mainly in the kernel and headers. This split based on work by Ingmar Alting <iaalting@cs.vu.nl> done for his Minix PowerPC architecture port. . kernel does not program the interrupt controller directly, do any other architecture-dependent operations, or contain assembly any more, but uses architecture-dependent functions in arch/$(ARCH)/. . architecture-dependent constants and types defined in arch/$(ARCH)/include. . <ibm/portio.h> moved to <minix/portio.h>, as they have become, for now, architecture-independent functions. . int86, sdevio, readbios, and iopenable are now i386-specific kernel calls and live in arch/i386/do_* now. . i386 arch now supports even less 86 code; e.g. mpx86.s and klib86.s have gone, and 'machine.protected' is gone (and always taken to be 1 in i386). If 86 support is to return, it should be a new architecture. . prototypes for the architecture-dependent functions defined in kernel/arch/$(ARCH)/*.c but used in kernel/ are in kernel/proto.h . /etc/make.conf included in makefiles and shell scripts that need to know the building architecture; it defines ARCH=<arch>, currently only i386. . some basic per-architecture build support outside of the kernel (lib) . in clock.c, only dequeue a process if it was ready . fixes for new include files files deleted: . mpx/klib.s - only for choosing between mpx/klib86 and -386 . klib86.s - only for 86 i386-specific files files moved (or arch-dependent stuff moved) to arch/i386/: . mpx386.s (entry point) . klib386.s . sconst.h . exception.c . protect.c . protect.h . i8269.c
250 lines
5 KiB
C
250 lines
5 KiB
C
/*
|
|
* kernel.c for mdb
|
|
*/
|
|
|
|
#include "mdb.h"
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#define ptrace mdbtrace
|
|
#include <sys/ptrace.h>
|
|
#include "proto.h"
|
|
|
|
#include <kernel/arch/i386/include/archtypes.h>
|
|
#include <kernel/const.h>
|
|
#include <kernel/type.h>
|
|
#include <kernel/proc.h>
|
|
|
|
/* Define these here */
|
|
/* buffer for proc and pointer to proc */
|
|
|
|
#define SIZ (1 + sizeof(struct proc)/sizeof(long))
|
|
|
|
struct proc *prc;
|
|
long lbuf[SIZ];
|
|
|
|
PRIVATE char segment_name[] = "TDS";
|
|
|
|
/*
|
|
* Display memory maps
|
|
*/
|
|
PUBLIC void disp_maps()
|
|
{
|
|
int i;
|
|
long int vir, phy, len;
|
|
|
|
Printf("\t Virtual\t Physical\tLength\n");
|
|
Printf("\t address\t address\n");
|
|
for (i = 0; i < strlen(segment_name); i++) {
|
|
vir = (long) prc->p_memmap[i].mem_vir << CLICK_SHIFT;
|
|
phy = (long) prc->p_memmap[i].mem_phys << CLICK_SHIFT;
|
|
len = (long) prc->p_memmap[i].mem_len << CLICK_SHIFT;
|
|
Printf("%c:\t0x%08.8lx\t0x%08.8lx\t%8ld (0x%08.8lx)\n",
|
|
segment_name[i], vir, phy, len, len);
|
|
}
|
|
}
|
|
|
|
PUBLIC void update()
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < (SIZ - 1); i++)
|
|
lbuf[i] = ptrace(T_GETUSER, curpid, (long) (i * sizeof(long)), 0L);
|
|
|
|
st_addr = (long) prc->p_memmap[T].mem_vir << CLICK_SHIFT;
|
|
et_addr = st_addr + ( (long) prc->p_memmap[T].mem_len << CLICK_SHIFT );
|
|
|
|
sd_addr = (long) prc->p_memmap[D].mem_vir << CLICK_SHIFT;
|
|
ed_addr = end_addr =
|
|
sd_addr + ( (long) prc->p_memmap[D].mem_len << CLICK_SHIFT );
|
|
|
|
sk_addr = (long) prc->p_memmap[S].mem_vir << CLICK_SHIFT;
|
|
sk_size = (long) prc->p_memmap[S].mem_len << CLICK_SHIFT;
|
|
|
|
#ifdef MINIX_PC
|
|
if ( end_addr < et_addr ) end_addr = et_addr;
|
|
#endif
|
|
|
|
}
|
|
|
|
PUBLIC int disp_regs()
|
|
{
|
|
int i;
|
|
|
|
if (curpid <= 0) {
|
|
Printf("No active process.\n");
|
|
return 1;
|
|
}
|
|
|
|
/* Look at kernel/type.h see how this data from the stackframe is laid out */
|
|
|
|
#if defined(MINIX_PC) && defined(__i86)
|
|
Printf("\
|
|
es ds di si bp bx dx cx ax ip cs psw sp ss\
|
|
\n");
|
|
for (i = 0; i < 16; i++)
|
|
if ( i != 5 && i != 10 ) Printf("%04x ", ((reg_t *) &prc->p_reg)[i]);
|
|
Printf("\n");
|
|
#endif
|
|
|
|
#if defined(MINIX_PC) && defined(__i386)
|
|
Printf("\n");
|
|
Printf("\
|
|
fs gs ds es edi esi ebp ebx edx\n");
|
|
for (i = 0; i < 8; i++)
|
|
if ( i != 6 ) Printf("%08lx ", ((reg_t *) &prc->p_reg)[i]);
|
|
Printf("\n\
|
|
ecx eax eip cs psw esp ss\n");
|
|
for (; i < 16; i++)
|
|
if ( i != 10 ) Printf("%08lx ", ((reg_t *) &prc->p_reg)[i]);
|
|
Printf("\n");
|
|
#endif
|
|
|
|
#ifdef MINIX_ST
|
|
Printf("\npc=%lx psw=%x\n\n",(long)PC_MEMBER(prc), PSW_MEMBER(prc));
|
|
Printf(
|
|
" 0 1 2 3 4 5 6 7\nD");
|
|
for (i = 0; i < 8; i++) Printf(" %08lx", ((reg_t *) &prc->p_reg)[i]);
|
|
Printf("\nA");
|
|
for (; i < NR_REGS; i++) Printf(" %08lx", ((reg_t *) &prc->p_reg)[i]);
|
|
Printf(" %08lx\n\n", (long)SP_MEMBER(prc));
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
/* System dependent core */
|
|
|
|
#ifdef MINIX_PC
|
|
|
|
#ifdef __i386
|
|
PRIVATE char regs[] = "fs gs ds es di si bp bx dx cx ax ip cs ps sp ss";
|
|
#else
|
|
PRIVATE char regs[] = "es ds di si bp bx dx cx ax ip cs ps sp ss";
|
|
#endif
|
|
|
|
/* Get register for pid at offset k */
|
|
PUBLIC long get_reg(pid, k)
|
|
int pid;
|
|
long k;
|
|
{
|
|
long off;
|
|
long val;
|
|
int reg_size;
|
|
|
|
/* Calculate size of register */
|
|
reg_size = (k < N_REG16 * 2) ? 2 : sizeof(reg_t);
|
|
|
|
/* Adjust offset */
|
|
off = k - (k & (sizeof(long) - 1));
|
|
|
|
val = ptrace(T_GETUSER, pid, off, 0L);
|
|
|
|
if (k & (sizeof(long) - 1))
|
|
val >>= BITSIZE(reg_size);
|
|
else
|
|
val &= MASK(reg_size);
|
|
return val;
|
|
}
|
|
|
|
|
|
/* Set register for pid at offset k */
|
|
PUBLIC void set_reg(pid, k, value)
|
|
int pid;
|
|
long k;
|
|
long value;
|
|
{
|
|
long off;
|
|
|
|
/* Adjust offset */
|
|
off = k - (k & (sizeof(long) - 1));
|
|
|
|
ptrace(T_SETUSER, pid, off, value);
|
|
|
|
}
|
|
|
|
|
|
PUBLIC long reg_addr(s)
|
|
char *s;
|
|
{
|
|
long val;
|
|
char *t;
|
|
char *send;
|
|
char q[3];
|
|
|
|
if (*s == ' ')
|
|
mdb_error("Invalid syntax\n");
|
|
q[0] = tolower(*s);
|
|
q[1] = tolower(*++s);
|
|
q[2] = '\0';
|
|
|
|
t = regs;
|
|
send = regs + sizeof(regs);
|
|
while (t < send) {
|
|
if (strncmp(q, t, 2) == 0) {
|
|
val = (long) (t - regs);
|
|
val /= 3L;
|
|
if (val < N_REG16 - 1)
|
|
val = val * 2;
|
|
else
|
|
val = (N_REG16 - 1) * 2 +
|
|
(val - N_REG16 + 1) * sizeof(reg_t);
|
|
return val;
|
|
}
|
|
t += 3;
|
|
}
|
|
Printf("Unknown register: %s", q);
|
|
mdb_error("\n");
|
|
}
|
|
|
|
|
|
PUBLIC int outsegreg(num)
|
|
off_t num;
|
|
{
|
|
/* print segment register */
|
|
|
|
if ((num % HCLICK_SIZE) != 0 || num >= 0x100000)
|
|
{
|
|
Printf("%08x",num);
|
|
return 8;
|
|
}
|
|
Printf("%04x", (u16_t) (num / HCLICK_SIZE) );
|
|
return 4;
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef MINIX_ST
|
|
|
|
/* Get register for pid at offset k */
|
|
PUBLIC long get_reg(pid, k)
|
|
int pid;
|
|
long k;
|
|
{
|
|
return ptrace(T_GETUSER, pid, k, 0L);
|
|
}
|
|
|
|
PUBLIC long reg_addr(s)
|
|
char *s;
|
|
{
|
|
long val;
|
|
|
|
switch (*s++) {
|
|
case 'a':
|
|
case 'A': val = 32; break;
|
|
case 'd':
|
|
case 'D': val = 0; break;
|
|
case 'P':
|
|
case 'p': if (*s != 'c' && *s != 'C') goto error;
|
|
return 64;
|
|
break;
|
|
default: goto error;
|
|
}
|
|
if (*s >= '0' && *s <= '7')
|
|
return val + 4 * (*s - '0');
|
|
error:
|
|
Printf("Unknown register: %2.2s", s);
|
|
mdb_error("\n");
|
|
}
|
|
|
|
#endif
|