From c8a1e0531d7ccdce5f76aec8a5b6147c686d3403 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 8 Apr 2025 10:49:18 -0400 Subject: fix old checkout --- kernel/old/Make.mk | 76 ++++ kernel/old/cio.c | 814 +++++++++++++++-------------------------- kernel/old/clock.c | 163 +++++++++ kernel/old/drivers/clock.c | 152 -------- kernel/old/drivers/serial.c | 629 ------------------------------- kernel/old/include/.vm.h.swp | Bin 0 -> 24576 bytes kernel/old/include/bindings.h | 73 ---- kernel/old/include/bootstrap.h | 105 +++--- kernel/old/include/cio.h | 40 +- kernel/old/include/clock.h | 12 +- kernel/old/include/common.h | 31 ++ kernel/old/include/compat.h | 27 +- kernel/old/include/debug.h | 245 ++++++------- kernel/old/include/defs.h | 89 +++-- kernel/old/include/elf.h | 235 ++++++++++++ kernel/old/include/kdefs.h | 125 +++---- kernel/old/include/klib.h | 8 +- kernel/old/include/kmem.h | 20 +- kernel/old/include/lib.h | 314 ++++++++++++++++ kernel/old/include/list.h | 6 +- kernel/old/include/offsets.h | 83 ----- kernel/old/include/params.h | 10 +- kernel/old/include/procs.h | 145 ++++---- kernel/old/include/serial.h | 3 - kernel/old/include/sio.h | 28 +- kernel/old/include/support.h | 27 +- kernel/old/include/syscalls.h | 38 +- kernel/old/include/types.h | 53 ++- kernel/old/include/udefs.h | 113 ++++++ kernel/old/include/ulib.h | 315 ++++++++++++++++ kernel/old/include/user.h | 25 +- kernel/old/include/userids.h | 33 ++ kernel/old/include/vm.h | 356 ++++++++---------- kernel/old/include/vmtables.h | 2 +- kernel/old/include/x86/arch.h | 350 +++++++++--------- kernel/old/include/x86/bios.h | 73 ++++ kernel/old/include/x86/ops.h | 266 ++++++++------ kernel/old/include/x86/pic.h | 131 +++---- kernel/old/include/x86/pit.h | 75 ++-- kernel/old/include/x86/uart.h | 389 ++++++++++---------- kernel/old/isrs.S | 18 +- kernel/old/kernel.c | 246 ++++++------- kernel/old/kernel.ld | 71 ++++ kernel/old/kmem.c | 272 +++++++------- kernel/old/list.c | 17 +- kernel/old/procs.c | 524 +++++++++++++------------- kernel/old/sio.c | 694 +++++++++++++++++++++++++++++++++++ kernel/old/startup.S | 153 ++++++++ kernel/old/support.c | 122 +++--- kernel/old/syscalls.c | 402 ++++++++++---------- kernel/old/user.c | 810 +++++++++++++++++----------------------- kernel/old/vm.c | 724 ++++++++++-------------------------- kernel/old/vmtables.c | 573 ++++++++++++++--------------- 53 files changed, 5463 insertions(+), 4842 deletions(-) create mode 100644 kernel/old/Make.mk create mode 100644 kernel/old/clock.c delete mode 100644 kernel/old/drivers/clock.c delete mode 100644 kernel/old/drivers/serial.c create mode 100644 kernel/old/include/.vm.h.swp delete mode 100644 kernel/old/include/bindings.h create mode 100644 kernel/old/include/common.h create mode 100644 kernel/old/include/elf.h create mode 100644 kernel/old/include/lib.h delete mode 100644 kernel/old/include/offsets.h delete mode 100644 kernel/old/include/serial.h create mode 100644 kernel/old/include/udefs.h create mode 100644 kernel/old/include/ulib.h create mode 100644 kernel/old/include/userids.h create mode 100644 kernel/old/include/x86/bios.h create mode 100644 kernel/old/kernel.ld create mode 100644 kernel/old/sio.c create mode 100644 kernel/old/startup.S diff --git a/kernel/old/Make.mk b/kernel/old/Make.mk new file mode 100644 index 0000000..ac8928d --- /dev/null +++ b/kernel/old/Make.mk @@ -0,0 +1,76 @@ +# +# Makefile fragment for the kernel components of the system. +# +# Makefile fragment for the kernel component of the system. +# +# THIS IS NOT A COMPLETE Makefile - run GNU make in the top-level +# directory, and this will be pulled in automatically. +# + +SUBDIRS += kernel + +################### +# FILES SECTION # +################### + +BOOT_OBJ := $(patsubst %.c, $(BUILDDIR)/%.o, $(BOOT_SRC)) + +KERN_SRC := kernel/startup.S kernel/isrs.S \ + kernel/cio.c kernel/clock.c kernel/kernel.c kernel/kmem.c \ + kernel/list.c kernel/procs.c kernel/sio.c kernel/support.c \ + kernel/syscalls.c kernel/user.c kernel/vm.c kernel/vmtables.c + +KERN_OBJ := $(patsubst %.c, $(BUILDDIR)/%.o, $(KERN_SRC)) +KERN_OBJ := $(patsubst %.S, $(BUILDDIR)/%.o, $(KERN_OBJ)) + +KCFLAGS := -ggdb +KLDFLAGS := -T kernel/kernel.ld +KLIBS := -lkernel -lcommon + +################### +# RULES SECTION # +################### + +kernel: $(BUILDDIR)/kernel/kernel.b + +$(BUILDDIR)/kernel/%.o: kernel/%.c $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CC) $(CFLAGS) $(KCFLAGS) -c -o $@ $< + +#$(BUILDDIR)/kernel/%.o: kernel/%.S $(BUILDDIR)/.vars.CFLAGS +# @mkdir -p $(@D) +# $(CPP) $(CPPFLAGS) -o $(@D)/$*.s $< +# $(AS) $(ASFLAGS) $(KCFLAGS) -o $@ $(@D)/$*.s -a=$(@D)/$*.lst +# $(RM) -f $(@D)/$*.s + +$(BUILDDIR)/kernel/%.o: kernel/%.S $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CC) $(CFLAGS) $(KCFLAGS) -c -o $@ $< + $(OBJDUMP) -S $@ > $(@D)/$*.asm + +$(BUILDDIR)/kernel/kernel: $(KERN_OBJ) + @mkdir -p $(@D) + $(LD) $(KLDFLAGS) $(LDFLAGS) -o $@ $(KERN_OBJ) $(KLIBS) + $(OBJDUMP) -S $@ > $@.asm + $(NM) -n $@ > $@.sym + $(READELF) -a $@ > $@.info + +$(BUILDDIR)/kernel/kernel.b: $(BUILDDIR)/kernel/kernel + $(LD) $(LDFLAGS) -o $(BUILDDIR)/kernel/kernel.b -s \ + --oformat binary -Ttext 0x10000 $(BUILDDIR)/kernel/kernel + +# some debugging assist rules +$(BUILDDIR)/kernel/%.i: kernel/%.c $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CC) $(CFLAGS) $(KCFLAGS) -E -c $< > $(@D)/$*.i + +$(BUILDDIR)/kernel/%.dat: $(BUILDDIR)/kernel/%.o + @mkdir -p $(@D) + $(OBJCOPY) -S -O binary -j .data $< $@ + hexdump -C $@ > $(@D)/$*.hex + +$(BUILDDIR)/kernel/%.rodat: $(BUILDDIR)/kernel/%.o + @mkdir -p $(@D) + $(OBJCOPY) -S -O binary -j .rodata $< $@ + hexdump -C $@ > $(@D)/$*.hex + diff --git a/kernel/old/cio.c b/kernel/old/cio.c index deb6b76..cfff543 100644 --- a/kernel/old/cio.c +++ b/kernel/old/cio.c @@ -30,18 +30,18 @@ /* ** Bit masks for the lower five and eight bits of a value */ -#define BMASK5 0x1f -#define BMASK8 0xff +#define BMASK5 0x1f +#define BMASK8 0xff /* ** Video parameters */ -#define SCREEN_MIN_X 0 -#define SCREEN_MIN_Y 0 -#define SCREEN_X_SIZE 80 -#define SCREEN_Y_SIZE 25 -#define SCREEN_MAX_X (SCREEN_X_SIZE - 1) -#define SCREEN_MAX_Y (SCREEN_Y_SIZE - 1) +#define SCREEN_MIN_X 0 +#define SCREEN_MIN_Y 0 +#define SCREEN_X_SIZE 80 +#define SCREEN_Y_SIZE 25 +#define SCREEN_MAX_X ( SCREEN_X_SIZE - 1 ) +#define SCREEN_MAX_Y ( SCREEN_Y_SIZE - 1 ) /* ** Video state @@ -55,56 +55,56 @@ static unsigned int max_x, max_y; // pointer to input notification function static void (*notify)(int); -#ifdef SA_DEBUG +#ifdef SA_DEBUG #include -#define cio_putchar putchar -#define cio_puts(x) fputs(x, stdout) +#define cio_putchar putchar +#define cio_puts(x) fputs( x, stdout ) #endif + /* ** VGA definitions. */ // calculate the memory address of a specific character position // within VGA memory -#define VIDEO_ADDR(x, y) \ - (unsigned short *)((VID_BASE_ADDR + 2 * ((y) * SCREEN_X_SIZE + (x))) | \ - 0x80000000) +#define VIDEO_ADDR(x,y) ( unsigned short * ) \ + ( VID_BASE_ADDR + 2 * ( (y) * SCREEN_X_SIZE + (x) ) ) // port addresses -#define VGA_CTRL_IX_ADDR 0x3d4 -#define VGA_CTRL_CUR_HIGH 0x0e // cursor location, high byte -#define VGA_CTRL_CUR_LOW 0x0f // cursor location, low byte -#define VGA_CTRL_IX_DATA 0x3d5 +#define VGA_CTRL_IX_ADDR 0x3d4 +# define VGA_CTRL_CUR_HIGH 0x0e // cursor location, high byte +# define VGA_CTRL_CUR_LOW 0x0f // cursor location, low byte +#define VGA_CTRL_IX_DATA 0x3d5 // attribute bits -#define VGA_ATT_BBI 0x80 // blink, or background intensity -#define VGA_ATT_BGC 0x70 // background color -#define VGA_ATT_FICS 0x80 // foreground intensity or char font select -#define VGA_ATT_FGC 0x70 // foreground color +#define VGA_ATT_BBI 0x80 // blink, or background intensity +#define VGA_ATT_BGC 0x70 // background color +#define VGA_ATT_FICS 0x80 // foreground intensity or char font select +#define VGA_ATT_FGC 0x70 // foreground color // color selections -#define VGA_BG_BLACK 0x0000 // background colors -#define VGA_BG_BLUE 0x1000 -#define VGA_BG_GREEN 0x2000 -#define VGA_BG_CYAN 0x3000 -#define VGA_BG_RED 0x4000 -#define VGA_BG_MAGENTA 0x5000 -#define VGA_BG_BROWN 0x6000 -#define VGA_BG_WHITE 0x7000 - -#define VGA_FG_BLACK 0x0000 // foreground colors -#define VGA_FG_BLUE 0x0100 -#define VGA_FG_GREEN 0x0200 -#define VGA_FG_CYAN 0x0300 -#define VGA_FG_RED 0x0400 -#define VGA_FG_MAGENTA 0x0500 -#define VGA_FG_BROWN 0x0600 -#define VGA_FG_WHITE 0x0700 +#define VGA_BG_BLACK 0x0000 // background colors +#define VGA_BG_BLUE 0x1000 +#define VGA_BG_GREEN 0x2000 +#define VGA_BG_CYAN 0x3000 +#define VGA_BG_RED 0x4000 +#define VGA_BG_MAGENTA 0x5000 +#define VGA_BG_BROWN 0x6000 +#define VGA_BG_WHITE 0x7000 + +#define VGA_FG_BLACK 0x0000 // foreground colors +#define VGA_FG_BLUE 0x0100 +#define VGA_FG_GREEN 0x0200 +#define VGA_FG_CYAN 0x0300 +#define VGA_FG_RED 0x0400 +#define VGA_FG_MAGENTA 0x0500 +#define VGA_FG_BROWN 0x0600 +#define VGA_FG_WHITE 0x0700 // color combinations -#define VGA_WHITE_ON_BLACK (VGA_FG_WHITE | VGA_BG_BLACK) -#define VGA_BLACK_ON_WHITE (VGA_FG_BLACK | VGA_BG_WHITE) +#define VGA_WHITE_ON_BLACK (VGA_FG_WHITE | VGA_BG_BLACK) +#define VGA_BLACK_ON_WHITE (VGA_FG_BLACK | VGA_BG_WHITE) /* ** Internal support routines. @@ -113,40 +113,38 @@ static void (*notify)(int); /* ** setcursor: set the cursor location (screen coordinates) */ -static void setcursor(void) -{ +static void setcursor( void ) { unsigned addr; unsigned int y = curr_y; - if (y > scroll_max_y) { + if( y > scroll_max_y ) { y = scroll_max_y; } - addr = (unsigned)(y * SCREEN_X_SIZE + curr_x); + addr = (unsigned)( y * SCREEN_X_SIZE + curr_x ); - outb(VGA_CTRL_IX_ADDR, VGA_CTRL_CUR_HIGH); - outb(VGA_CTRL_IX_DATA, (addr >> 8) & BMASK8); - outb(VGA_CTRL_IX_ADDR, VGA_CTRL_CUR_LOW); - outb(VGA_CTRL_IX_DATA, addr & BMASK8); + outb( VGA_CTRL_IX_ADDR, VGA_CTRL_CUR_HIGH ); + outb( VGA_CTRL_IX_DATA, ( addr >> 8 ) & BMASK8 ); + outb( VGA_CTRL_IX_ADDR, VGA_CTRL_CUR_LOW ); + outb( VGA_CTRL_IX_DATA, addr & BMASK8 ); } /* ** putchar_at: physical output to the video memory */ -static void putchar_at(unsigned int x, unsigned int y, unsigned int c) -{ +static void putchar_at( unsigned int x, unsigned int y, unsigned int c ) { /* ** If x or y is too big or small, don't do any output. */ - if (x <= max_x && y <= max_y) { - unsigned short *addr = VIDEO_ADDR(x, y); + if( x <= max_x && y <= max_y ) { + unsigned short *addr = VIDEO_ADDR( x, y ); /* ** The character may have attributes associated with it; if ** so, use those, otherwise use white on black. */ - c &= 0xffff; // keep only the lower bytes - if (c > BMASK8) { + c &= 0xffff; // keep only the lower bytes + if( c > BMASK8 ) { *addr = (unsigned short)c; } else { *addr = (unsigned short)c | VGA_WHITE_ON_BLACK; @@ -161,13 +159,12 @@ static void putchar_at(unsigned int x, unsigned int y, unsigned int c) /* ** Set the scrolling region */ -void cio_setscroll(unsigned int s_min_x, unsigned int s_min_y, - unsigned int s_max_x, unsigned int s_max_y) -{ - scroll_min_x = bound(min_x, s_min_x, max_x); - scroll_min_y = bound(min_y, s_min_y, max_y); - scroll_max_x = bound(scroll_min_x, s_max_x, max_x); - scroll_max_y = bound(scroll_min_y, s_max_y, max_y); +void cio_setscroll( unsigned int s_min_x, unsigned int s_min_y, + unsigned int s_max_x, unsigned int s_max_y ) { + scroll_min_x = bound( min_x, s_min_x, max_x ); + scroll_min_y = bound( min_y, s_min_y, max_y ); + scroll_max_x = bound( scroll_min_x, s_max_x, max_x ); + scroll_max_y = bound( scroll_min_y, s_max_y, max_y ); curr_x = scroll_min_x; curr_y = scroll_min_y; setcursor(); @@ -176,19 +173,17 @@ void cio_setscroll(unsigned int s_min_x, unsigned int s_min_y, /* ** Cursor movement in the scroll region */ -void cio_moveto(unsigned int x, unsigned int y) -{ - curr_x = bound(scroll_min_x, x + scroll_min_x, scroll_max_x); - curr_y = bound(scroll_min_y, y + scroll_min_y, scroll_max_y); +void cio_moveto( unsigned int x, unsigned int y ) { + curr_x = bound( scroll_min_x, x + scroll_min_x, scroll_max_x ); + curr_y = bound( scroll_min_y, y + scroll_min_y, scroll_max_y ); setcursor(); } /* ** The putchar family */ -void cio_putchar_at(unsigned int x, unsigned int y, unsigned int c) -{ - if ((c & 0x7f) == '\n') { +void cio_putchar_at( unsigned int x, unsigned int y, unsigned int c ) { + if( ( c & 0x7f ) == '\n' ) { unsigned int limit; /* @@ -196,41 +191,43 @@ void cio_putchar_at(unsigned int x, unsigned int y, unsigned int c) ** leave it. If we're not in the scroll region, don't ** let this loop enter it. */ - if (x > scroll_max_x) { + if( x > scroll_max_x ) { limit = max_x; - } else if (x >= scroll_min_x) { + } + else if( x >= scroll_min_x ) { limit = scroll_max_x; - } else { + } + else { limit = scroll_min_x - 1; } - while (x <= limit) { - putchar_at(x, y, ' '); + while( x <= limit ) { + putchar_at( x, y, ' ' ); x += 1; } - } else { - putchar_at(x, y, c); + } + else { + putchar_at( x, y, c ); } } #ifndef SA_DEBUG -void cio_putchar(unsigned int c) -{ +void cio_putchar( unsigned int c ) { /* ** If we're off the bottom of the screen, scroll the window. */ - if (curr_y > scroll_max_y) { - cio_scroll(curr_y - scroll_max_y); + if( curr_y > scroll_max_y ) { + cio_scroll( curr_y - scroll_max_y ); curr_y = scroll_max_y; } - switch (c & BMASK8) { + switch( c & BMASK8 ) { case '\n': /* ** Erase to the end of the line, then move to new line ** (actual scroll is delayed until next output appears). */ - while (curr_x <= scroll_max_x) { - putchar_at(curr_x, curr_y, ' '); + while( curr_x <= scroll_max_x ) { + putchar_at( curr_x, curr_y, ' ' ); curr_x += 1; } curr_x = scroll_min_x; @@ -242,9 +239,9 @@ void cio_putchar(unsigned int c) break; default: - putchar_at(curr_x, curr_y, c); + putchar_at( curr_x, curr_y, c ); curr_x += 1; - if (curr_x > scroll_max_x) { + if( curr_x > scroll_max_x ) { curr_x = scroll_min_x; curr_y += 1; } @@ -257,23 +254,21 @@ void cio_putchar(unsigned int c) /* ** The puts family */ -void cio_puts_at(unsigned int x, unsigned int y, const char *str) -{ +void cio_puts_at( unsigned int x, unsigned int y, const char *str ) { unsigned int ch; - while ((ch = *str++) != '\0' && x <= max_x) { - cio_putchar_at(x, y, ch); + while( (ch = *str++) != '\0' && x <= max_x ) { + cio_putchar_at( x, y, ch ); x += 1; } } #ifndef SA_DEBUG -void cio_puts(const char *str) -{ +void cio_puts( const char *str ) { unsigned int ch; - while ((ch = *str++) != '\0') { - cio_putchar(ch); + while( (ch = *str++) != '\0' ) { + cio_putchar( ch ); } } #endif @@ -281,41 +276,38 @@ void cio_puts(const char *str) /* ** Write a "sized" buffer (like cio_puts(), but no NUL) */ -void cio_write(const char *buf, int length) -{ - for (int i = 0; i < length; ++i) { - cio_putchar(buf[i]); +void cio_write( const char *buf, int length ) { + for( int i = 0; i < length; ++i ) { + cio_putchar( buf[i] ); } } -void cio_clearscroll(void) -{ +void cio_clearscroll( void ) { unsigned int nchars = scroll_max_x - scroll_min_x + 1; unsigned int l; unsigned int c; - for (l = scroll_min_y; l <= scroll_max_y; l += 1) { - unsigned short *to = VIDEO_ADDR(scroll_min_x, l); + for( l = scroll_min_y; l <= scroll_max_y; l += 1 ) { + unsigned short *to = VIDEO_ADDR( scroll_min_x, l ); - for (c = 0; c < nchars; c += 1) { + for( c = 0; c < nchars; c += 1 ) { *to++ = ' ' | 0x0700; } } } -void cio_clearscreen(void) -{ - unsigned short *to = VIDEO_ADDR(min_x, min_y); - unsigned int nchars = (max_y - min_y + 1) * (max_x - min_x + 1); +void cio_clearscreen( void ) { + unsigned short *to = VIDEO_ADDR( min_x, min_y ); + unsigned int nchars = ( max_y - min_y + 1 ) * ( max_x - min_x + 1 ); - while (nchars > 0) { + while( nchars > 0 ) { *to++ = ' ' | 0x0700; nchars -= 1; } } -void cio_scroll(unsigned int lines) -{ + +void cio_scroll( unsigned int lines ) { unsigned short *from; unsigned short *to; int nchars = scroll_max_x - scroll_min_x + 1; @@ -324,7 +316,7 @@ void cio_scroll(unsigned int lines) /* ** If # of lines is the whole scrolling region or more, just clear. */ - if (lines > scroll_max_y - scroll_min_y) { + if( lines > scroll_max_y - scroll_min_y ) { cio_clearscroll(); curr_x = scroll_min_x; curr_y = scroll_min_y; @@ -335,84 +327,85 @@ void cio_scroll(unsigned int lines) /* ** Must copy it line by line. */ - for (line = scroll_min_y; line <= scroll_max_y - lines; line += 1) { - from = VIDEO_ADDR(scroll_min_x, line + lines); - to = VIDEO_ADDR(scroll_min_x, line); - for (c = 0; c < nchars; c += 1) { + for( line = scroll_min_y; line <= scroll_max_y - lines; line += 1 ) { + from = VIDEO_ADDR( scroll_min_x, line + lines ); + to = VIDEO_ADDR( scroll_min_x, line ); + for( c = 0; c < nchars; c += 1 ) { *to++ = *from++; } } - for (; line <= scroll_max_y; line += 1) { - to = VIDEO_ADDR(scroll_min_x, line); - for (c = 0; c < nchars; c += 1) { + for( ; line <= scroll_max_y; line += 1 ) { + to = VIDEO_ADDR( scroll_min_x, line ); + for( c = 0; c < nchars; c += 1 ) { *to++ = ' ' | 0x0700; } } } -static int mypad(int x, int y, int extra, int padchar) -{ - while (extra > 0) { - if (x != -1 || y != -1) { - cio_putchar_at(x, y, padchar); +static int mypad( int x, int y, int extra, int padchar ) { + while( extra > 0 ) { + if( x != -1 || y != -1 ) { + cio_putchar_at( x, y, padchar ); x += 1; - } else { - cio_putchar(padchar); + } + else { + cio_putchar( padchar ); } extra -= 1; } return x; } -static int mypadstr(int x, int y, char *str, int len, int width, int leftadjust, - int padchar) -{ +static int mypadstr( int x, int y, char *str, int len, int width, + int leftadjust, int padchar ) { int extra; - if (len < 0) { - len = strlen(str); + if( len < 0 ) { + len = strlen( str ); } extra = width - len; - if (extra > 0 && !leftadjust) { - x = mypad(x, y, extra, padchar); + if( extra > 0 && !leftadjust ) { + x = mypad( x, y, extra, padchar ); } - if (x != -1 || y != -1) { - cio_puts_at(x, y, str); + if( x != -1 || y != -1 ) { + cio_puts_at( x, y, str ); x += len; - } else { - cio_puts(str); } - if (extra > 0 && leftadjust) { - x = mypad(x, y, extra, padchar); + else { + cio_puts( str ); + } + if( extra > 0 && leftadjust ) { + x = mypad( x, y, extra, padchar ); } return x; } -static void do_printf(int x, int y, char **f) -{ +static void do_printf( int x, int y, char **f ) { char *fmt = *f; - int *ap; - char buf[12]; + int *ap; + char buf[ 12 ]; char ch; char *str; - int leftadjust; - int width; - int len; - int padchar; + int leftadjust; + int width; + int len; + int padchar; /* ** Get characters from the format string and process them */ - ap = (int *)(f + 1); + ap = (int *)( f + 1 ); + + while( (ch = *fmt++) != '\0' ) { - while ((ch = *fmt++) != '\0') { /* ** Is it the start of a format code? */ - if (ch == '%') { + if( ch == '%' ) { + /* ** Yes, get the padding and width options (if there). ** Alignment must come at the beginning, then fill, @@ -425,17 +418,17 @@ static void do_printf(int x, int y, char **f) ch = *fmt++; - if (ch == '-') { + if( ch == '-' ) { leftadjust = 1; ch = *fmt++; } - if (ch == '0') { + if( ch == '0' ) { padchar = '0'; ch = *fmt++; } - while (ch >= '0' && ch <= '9') { + while( ch >= '0' && ch <= '9' ) { width *= 10; width += ch - '0'; ch = *fmt++; @@ -444,52 +437,55 @@ static void do_printf(int x, int y, char **f) /* ** What data type do we have? */ - switch (ch) { + switch( ch ) { + case 'c': // ch = *( (int *)ap )++; ch = *ap++; - buf[0] = ch; - buf[1] = '\0'; - x = mypadstr(x, y, buf, 1, width, leftadjust, padchar); + buf[ 0 ] = ch; + buf[ 1 ] = '\0'; + x = mypadstr( x, y, buf, 1, width, leftadjust, padchar ); break; case 'd': // len = cvtdec( buf, *( (int *)ap )++ ); - len = cvtdec(buf, *ap++); - x = mypadstr(x, y, buf, len, width, leftadjust, padchar); + len = cvtdec( buf, *ap++ ); + x = mypadstr( x, y, buf, len, width, leftadjust, padchar ); break; case 's': // str = *( (char **)ap )++; - str = (char *)(*ap++); - x = mypadstr(x, y, str, -1, width, leftadjust, padchar); + str = (char *) (*ap++); + x = mypadstr( x, y, str, -1, width, leftadjust, padchar ); break; case 'x': // len = cvthex( buf, *( (int *)ap )++ ); - len = cvthex(buf, *ap++); - x = mypadstr(x, y, buf, len, width, leftadjust, padchar); + len = cvthex( buf, *ap++ ); + x = mypadstr( x, y, buf, len, width, leftadjust, padchar ); break; case 'o': // len = cvtoct( buf, *( (int *)ap )++ ); - len = cvtoct(buf, *ap++); - x = mypadstr(x, y, buf, len, width, leftadjust, padchar); + len = cvtoct( buf, *ap++ ); + x = mypadstr( x, y, buf, len, width, leftadjust, padchar ); break; case 'u': - len = cvtuns(buf, *ap++); - x = mypadstr(x, y, buf, len, width, leftadjust, padchar); + len = cvtuns( buf, *ap++ ); + x = mypadstr( x, y, buf, len, width, leftadjust, padchar ); break; + } } else { + /* ** No - just print it normally. */ - if (x != -1 || y != -1) { - cio_putchar_at(x, y, ch); - switch (ch) { + if( x != -1 || y != -1 ) { + cio_putchar_at( x, y, ch ); + switch( ch ) { case '\n': y += 1; /* FALL THRU */ @@ -501,352 +497,129 @@ static void do_printf(int x, int y, char **f) default: x += 1; } - } else { - cio_putchar(ch); + } + else { + cio_putchar( ch ); } } } } -void cio_printf_at(unsigned int x, unsigned int y, char *fmt, ...) -{ - do_printf(x, y, &fmt); +void cio_printf_at( unsigned int x, unsigned int y, char *fmt, ... ) { + do_printf( x, y, &fmt ); } -void cio_printf(char *fmt, ...) -{ - do_printf(-1, -1, &fmt); +void cio_printf( char *fmt, ... ) { + do_printf( -1, -1, &fmt ); } /* ** These are the "standard" IBM AT "Set 1" keycodes. */ -static unsigned char scan_code[2][128] = { { // unshifted characters - /* 00-07 */ '\377', - '\033', - '1', - '2', - '3', - '4', - '5', - '6', - /* 08-0f */ '7', - '8', - '9', - '0', - '-', - '=', - '\b', - '\t', - /* 10-17 */ 'q', - 'w', - 'e', - 'r', - 't', - 'y', - 'u', - 'i', - /* 18-1f */ 'o', - 'p', - '[', - ']', - '\n', - '\377', - 'a', - 's', - /* 20-27 */ 'd', - 'f', - 'g', - 'h', - 'j', - 'k', - 'l', - ';', - /* 28-2f */ '\'', - '`', - '\377', - '\\', - 'z', - 'x', - 'c', - 'v', - /* 30-37 */ 'b', - 'n', - 'm', - ',', - '.', - '/', - '\377', - '*', - /* 38-3f */ '\377', - ' ', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - /* 40-47 */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '7', - /* 48-4f */ '8', - '9', - '-', - '4', - '5', - '6', - '+', - '1', - /* 50-57 */ '2', - '3', - '0', - '.', - '\377', - '\377', - '\377', - '\377', - /* 58-5f */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - /* 60-67 */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - /* 68-6f */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - /* 70-77 */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - /* 78-7f */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377' }, - - { // shifted characters - /* 00-07 */ '\377', - '\033', - '!', - '@', - '#', - '$', - '%', - '^', - /* 08-0f */ '&', - '*', - '(', - ')', - '_', - '+', - '\b', - '\t', - /* 10-17 */ 'Q', - 'W', - 'E', - 'R', - 'T', - 'Y', - 'U', - 'I', - /* 18-1f */ 'O', - 'P', - '{', - '}', - '\n', - '\377', - 'A', - 'S', - /* 20-27 */ 'D', - 'F', - 'G', - 'H', - 'J', - 'K', - 'L', - ':', - /* 28-2f */ '"', - '~', - '\377', - '|', - 'Z', - 'X', - 'C', - 'V', - /* 30-37 */ 'B', - 'N', - 'M', - '<', - '>', - '?', - '\377', - '*', - /* 38-3f */ '\377', - ' ', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - /* 40-47 */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '7', - /* 48-4f */ '8', - '9', - '-', - '4', - '5', - '6', - '+', - '1', - /* 50-57 */ '2', - '3', - '0', - '.', - '\377', - '\377', - '\377', - '\377', - /* 58-5f */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - /* 60-67 */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - /* 68-6f */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - /* 70-77 */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - /* 78-7f */ '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377', - '\377' } }; +static unsigned char scan_code[ 2 ][ 128 ] = { + { // unshifted characters +/* 00-07 */ '\377', '\033', '1', '2', '3', '4', '5', '6', +/* 08-0f */ '7', '8', '9', '0', '-', '=', '\b', '\t', +/* 10-17 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', +/* 18-1f */ 'o', 'p', '[', ']', '\n', '\377', 'a', 's', +/* 20-27 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', +/* 28-2f */ '\'', '`', '\377', '\\', 'z', 'x', 'c', 'v', +/* 30-37 */ 'b', 'n', 'm', ',', '.', '/', '\377', '*', +/* 38-3f */ '\377', ' ', '\377', '\377', '\377', '\377', '\377', '\377', +/* 40-47 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '7', +/* 48-4f */ '8', '9', '-', '4', '5', '6', '+', '1', +/* 50-57 */ '2', '3', '0', '.', '\377', '\377', '\377', '\377', +/* 58-5f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 60-67 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 68-6f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 70-77 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 78-7f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377' + }, + + { // shifted characters +/* 00-07 */ '\377', '\033', '!', '@', '#', '$', '%', '^', +/* 08-0f */ '&', '*', '(', ')', '_', '+', '\b', '\t', +/* 10-17 */ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', +/* 18-1f */ 'O', 'P', '{', '}', '\n', '\377', 'A', 'S', +/* 20-27 */ 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', +/* 28-2f */ '"', '~', '\377', '|', 'Z', 'X', 'C', 'V', +/* 30-37 */ 'B', 'N', 'M', '<', '>', '?', '\377', '*', +/* 38-3f */ '\377', ' ', '\377', '\377', '\377', '\377', '\377', '\377', +/* 40-47 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '7', +/* 48-4f */ '8', '9', '-', '4', '5', '6', '+', '1', +/* 50-57 */ '2', '3', '0', '.', '\377', '\377', '\377', '\377', +/* 58-5f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 60-67 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 68-6f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 70-77 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 78-7f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377' + } +}; /* ** Scan code masks */ // 'release' bit -#define REL_BIT 0x80 -#define CODE_BITS 0x7f +#define REL_BIT 0x80 +#define CODE_BITS 0x7f -#define IS_PRESS(c) (((c) & REL_BIT) == 0) -#define IS_RELEASE(c) (((c) & REL_BIT) != 0) +#define IS_PRESS(c) (((c) & REL_BIT) == 0) +#define IS_RELEASE(c) (((c) & REL_BIT) != 0) /* ** Scan codes for some special characters */ // escape code - followed by another code byte -#define SCAN_ESC 0xe0 +#define SCAN_ESC 0xe0 // shift keys: press, release -#define L_SHIFT_DN 0x2a -#define R_SHIFT_DN 0x36 -#define L_SHIFT_UP 0xaa -#define R_SHIFT_UP 0xb6 +#define L_SHIFT_DN 0x2a +#define R_SHIFT_DN 0x36 +#define L_SHIFT_UP 0xaa +#define R_SHIFT_UP 0xb6 // control keys -#define L_CTRL_DN 0x1d -#define L_CTRL_UP 0x9d +#define L_CTRL_DN 0x1d +#define L_CTRL_UP 0x9d /* ** I/O communication constants */ -#define KBD_DATA 0x60 -#define KBD_STATUS 0x64 -#define READY 0x1 +#define KBD_DATA 0x60 +#define KBD_STATUS 0x64 +#define READY 0x1 /* ** Circular buffer for input characters. Characters are inserted at ** next_space, and are removed at next_char. Buffer is empty if ** these are equal. */ -#define C_BUFSIZE 200 +#define C_BUFSIZE 200 -static char input_buffer[C_BUFSIZE]; +static char input_buffer[ C_BUFSIZE ]; static volatile char *next_char = input_buffer; static volatile char *next_space = input_buffer; -static volatile char *increment(volatile char *pointer) -{ - if (++pointer >= input_buffer + C_BUFSIZE) { +static volatile char *increment( volatile char *pointer ) { + if( ++pointer >= input_buffer + C_BUFSIZE ) { pointer = input_buffer; } return pointer; } -static int input_scan_code(int code) -{ - static int shift = 0; - static int ctrl_mask = BMASK8; +static int input_scan_code( int code ) { + static int shift = 0; + static int ctrl_mask = BMASK8; int rval = -1; /* ** Do the shift processing */ code &= BMASK8; - switch (code) { + switch( code ) { case L_SHIFT_DN: case R_SHIFT_DN: shift = 1; @@ -870,76 +643,74 @@ static int input_scan_code(int code) ** Process ordinary characters only on the press (to handle ** autorepeat). Ignore undefined scan codes. */ - if (IS_PRESS(code)) { - code = scan_code[shift][(int)code]; - if (code != '\377') { - volatile char *next = increment(next_space); + if( IS_PRESS(code) ) { + code = scan_code[ shift ][ (int)code ]; + if( code != '\377' ) { + volatile char *next = increment( next_space ); /* ** Store character only if there's room */ rval = code & ctrl_mask; - if (next != next_char) { + if( next != next_char ) { *next_space = code & ctrl_mask; next_space = next; } } } } - return (rval); + return( rval ); } -static void keyboard_isr(int vector, int code) -{ - int data = inb(KBD_DATA); - int val = input_scan_code(data); +static void keyboard_isr( int vector, int code ) { + + int data = inb( KBD_DATA ); + int val = input_scan_code( data ); // if there is a notification function, call it - if (val != -1 && notify) - notify(val); + if( val != -1 && notify ) + notify( val ); - outb(PIC1_CMD, PIC_EOI); + outb( PIC1_CMD, PIC_EOI ); } -int cio_getchar(void) -{ - char c; +int cio_getchar( void ) { + char c; int interrupts_enabled = r_eflags() & EFL_IF; - while (next_char == next_space) { - if (!interrupts_enabled) { + while( next_char == next_space ) { + if( !interrupts_enabled ) { /* ** Must read the next keystroke ourselves. */ - while ((inb(KBD_STATUS) & READY) == 0) { + while( ( inb( KBD_STATUS ) & READY ) == 0 ) { ; } - (void)input_scan_code(inb(KBD_DATA)); + (void) input_scan_code( inb( KBD_DATA ) ); } } c = *next_char & BMASK8; - next_char = increment(next_char); - if (c != EOT) { - cio_putchar(c); + next_char = increment( next_char ); + if( c != EOT ) { + cio_putchar( c ); } return c; } -int cio_gets(char *buffer, unsigned int size) -{ - char ch; +int cio_gets( char *buffer, unsigned int size ) { + char ch; int count = 0; - while (size > 1) { + while( size > 1 ) { ch = cio_getchar(); - if (ch == EOT) { + if( ch == EOT ) { break; } *buffer++ = ch; count += 1; size -= 1; - if (ch == '\n') { + if( ch == '\n' ) { break; } } @@ -947,11 +718,10 @@ int cio_gets(char *buffer, unsigned int size) return count; } -int cio_input_queue(void) -{ +int cio_input_queue( void ) { int n_chars = next_space - next_char; - if (n_chars < 0) { + if( n_chars < 0 ) { n_chars += C_BUFSIZE; } return n_chars; @@ -960,15 +730,14 @@ int cio_input_queue(void) /* ** Initialization routines */ -void cio_init(void (*fcn)(int)) -{ +void cio_init( void (*fcn)(int) ) { /* ** Screen dimensions */ - min_x = SCREEN_MIN_X; - min_y = SCREEN_MIN_Y; - max_x = SCREEN_MAX_X; - max_y = SCREEN_MAX_Y; + min_x = SCREEN_MIN_X; + min_y = SCREEN_MIN_Y; + max_x = SCREEN_MAX_X; + max_y = SCREEN_MAX_Y; /* ** Scrolling region @@ -993,35 +762,34 @@ void cio_init(void (*fcn)(int)) /* ** Set up the interrupt handler for the keyboard */ - install_isr(VEC_KBD, keyboard_isr); + install_isr( VEC_KBD, keyboard_isr ); } #ifdef SA_DEBUG -int main() -{ - cio_printf("%d\n", 123); - cio_printf("%d\n", -123); - cio_printf("%d\n", 0x7fffffff); - cio_printf("%d\n", 0x80000001); - cio_printf("%d\n", 0x80000000); - cio_printf("x%14dy\n", 0x80000000); - cio_printf("x%-14dy\n", 0x80000000); - cio_printf("x%014dy\n", 0x80000000); - cio_printf("x%-014dy\n", 0x80000000); - cio_printf("%s\n", "xyz"); - cio_printf("|%10s|\n", "xyz"); - cio_printf("|%-10s|\n", "xyz"); - cio_printf("%c\n", 'x'); - cio_printf("|%4c|\n", 'y'); - cio_printf("|%-4c|\n", 'y'); - cio_printf("|%04c|\n", 'y'); - cio_printf("|%-04c|\n", 'y'); - cio_printf("|%3d|\n", 5); - cio_printf("|%3d|\n", 54321); - cio_printf("%x\n", 0x123abc); - cio_printf("|%04x|\n", 20); - cio_printf("|%012x|\n", 0xfedcba98); - cio_printf("|%-012x|\n", 0x76543210); +int main() { + cio_printf( "%d\n", 123 ); + cio_printf( "%d\n", -123 ); + cio_printf( "%d\n", 0x7fffffff ); + cio_printf( "%d\n", 0x80000001 ); + cio_printf( "%d\n", 0x80000000 ); + cio_printf( "x%14dy\n", 0x80000000 ); + cio_printf( "x%-14dy\n", 0x80000000 ); + cio_printf( "x%014dy\n", 0x80000000 ); + cio_printf( "x%-014dy\n", 0x80000000 ); + cio_printf( "%s\n", "xyz" ); + cio_printf( "|%10s|\n", "xyz" ); + cio_printf( "|%-10s|\n", "xyz" ); + cio_printf( "%c\n", 'x' ); + cio_printf( "|%4c|\n", 'y' ); + cio_printf( "|%-4c|\n", 'y' ); + cio_printf( "|%04c|\n", 'y' ); + cio_printf( "|%-04c|\n", 'y' ); + cio_printf( "|%3d|\n", 5 ); + cio_printf( "|%3d|\n", 54321 ); + cio_printf( "%x\n", 0x123abc ); + cio_printf( "|%04x|\n", 20 ); + cio_printf( "|%012x|\n", 0xfedcba98 ); + cio_printf( "|%-012x|\n", 0x76543210 ); } int curr_x, curr_y, max_x, max_y; diff --git a/kernel/old/clock.c b/kernel/old/clock.c new file mode 100644 index 0000000..96f71c4 --- /dev/null +++ b/kernel/old/clock.c @@ -0,0 +1,163 @@ +/** +** @file clock.c +** +** @author CSCI-452 class of 20245 +** +** @brief Clock module implementation +*/ + +#define KERNEL_SRC + +#include + +#include +#include + +#include +#include +#include + +/* +** PRIVATE DEFINITIONS +*/ + +/* +** PRIVATE DATA TYPES +*/ + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +// pinwheel control variables +static uint32_t pinwheel; // pinwheel counter +static uint32_t pindex; // index into pinwheel string + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +// current system time +uint32_t system_time; + +/* +** PRIVATE FUNCTIONS +*/ + +/** +** Name: clk_isr +** +** The ISR for the clock +** +** @param vector Vector number for the clock interrupt +** @param code Error code (0 for this interrupt) +*/ +static void clk_isr( int vector, int code ) { + + // spin the pinwheel + + ++pinwheel; + if( pinwheel == (CLOCK_FREQ / 10) ) { + pinwheel = 0; + ++pindex; + cio_putchar_at( 0, 0, "|/-\\"[ pindex & 3 ] ); + } + +#if defined(SYSTEM_STATUS) + // Periodically, dump the queue lengths and the SIO status (along + // with the SIO buffers, if non-empty). + // + // Define the symbol SYSTEM_STATUS with a value equal to the desired + // reporting frequency, in seconds. + + if( (system_time % SEC_TO_TICKS(SYSTEM_STATUS)) == 0 ) { + cio_printf_at( 1, 0, " queues: R[%u] W[%u] S[%u] Z[%u] I[%u] ", + pcb_queue_length(ready), + pcb_queue_length(waiting), + pcb_queue_length(sleeping), + pcb_queue_length(zombie), + pcb_queue_length(sioread) + ); + } +#endif + + // time marches on! + ++system_time; + + // wake up any sleeping processes whose time has come + // + // we give them preference over the current process when + // it is scheduled again + + do { + // if there isn't anyone in the sleep queue, we're done + if( pcb_queue_empty(sleeping) ) { + break; + } + + // peek at the first member of the queue + pcb_t *tmp = pcb_queue_peek( sleeping ); + assert( tmp != NULL ); + + // the sleep queue is sorted in ascending order by wakeup + // time, so we know that the retrieved PCB's wakeup time is + // the earliest of any process on the sleep queue; if that + // time hasn't arrived yet, there's nobody left to awaken + + if( tmp->wakeup > system_time ) { + break; + } + + // OK, we need to wake this process up + assert( pcb_queue_remove(sleeping,&tmp) == SUCCESS ); + schedule( tmp ); + } while( 1 ); + + // next, we decrement the current process' remaining time + current->ticks -= 1; + + // has it expired? + if( current->ticks < 1 ) { + // yes! reschedule it + schedule( current ); + current = NULL; + // and pick a new process + dispatch(); + } + + // tell the PIC we're done + outb( PIC1_CMD, PIC_EOI ); +} + +/* +** PUBLIC FUNCTIONS +*/ + +/** +** Name: clk_init +** +** Initializes the clock module +** +*/ +void clk_init( void ) { + +#if TRACING_INIT + cio_puts( " Clock" ); +#endif + + // start the pinwheel + pinwheel = (CLOCK_FREQ / 10) - 1; + pindex = 0; + + // return to the dawn of time + system_time = 0; + + // configure the clock + uint32_t divisor = PIT_FREQ / CLOCK_FREQ; + outb( PIT_CONTROL_PORT, PIT_0_LOAD | PIT_0_SQUARE ); + outb( PIT_0_PORT, divisor & 0xff ); // LSB of divisor + outb( PIT_0_PORT, (divisor >> 8) & 0xff ); // MSB of divisor + + // register the second-stage ISR + install_isr( VEC_TIMER, clk_isr ); +} diff --git a/kernel/old/drivers/clock.c b/kernel/old/drivers/clock.c deleted file mode 100644 index 9f3d4be..0000000 --- a/kernel/old/drivers/clock.c +++ /dev/null @@ -1,152 +0,0 @@ -#define KERNEL_SRC - -#include - -#include -#include - -#include -#include -#include - -/* -** PRIVATE DEFINITIONS -*/ - -/* -** PRIVATE DATA TYPES -*/ - -/* -** PRIVATE GLOBAL VARIABLES -*/ - -// pinwheel control variables -static uint32_t pinwheel; // pinwheel counter -static uint32_t pindex; // index into pinwheel string - -/* -** PUBLIC GLOBAL VARIABLES -*/ - -// current system time -uint32_t system_time; - -/* -** PRIVATE FUNCTIONS -*/ - -/** -** Name: clk_isr -** -** The ISR for the clock -** -** @param vector Vector number for the clock interrupt -** @param code Error code (0 for this interrupt) -*/ -static void clk_isr(int vector, int code) -{ - // spin the pinwheel - - ++pinwheel; - if (pinwheel == (CLOCK_FREQ / 10)) { - pinwheel = 0; - ++pindex; - cio_putchar_at(0, 0, "|/-\\"[pindex & 3]); - } - -#if defined(SYSTEM_STATUS) - // Periodically, dump the queue lengths and the SIO status (along - // with the SIO buffers, if non-empty). - // - // Define the symbol SYSTEM_STATUS with a value equal to the desired - // reporting frequency, in seconds. - - if ((system_time % SEC_TO_TICKS(SYSTEM_STATUS)) == 0) { - cio_printf_at(1, 0, " queues: R[%u] W[%u] S[%u] Z[%u] I[%u] ", - pcb_queue_length(ready), pcb_queue_length(waiting), - pcb_queue_length(sleeping), pcb_queue_length(zombie), - pcb_queue_length(sioread)); - } -#endif - - // time marches on! - ++system_time; - - // wake up any sleeping processes whose time has come - // - // we give them preference over the current process when - // it is scheduled again - - do { - // if there isn't anyone in the sleep queue, we're done - if (pcb_queue_empty(sleeping)) { - break; - } - - // peek at the first member of the queue - pcb_t *tmp = pcb_queue_peek(sleeping); - assert(tmp != NULL); - - // the sleep queue is sorted in ascending order by wakeup - // time, so we know that the retrieved PCB's wakeup time is - // the earliest of any process on the sleep queue; if that - // time hasn't arrived yet, there's nobody left to awaken - - if (tmp->wakeup > system_time) { - break; - } - - // OK, we need to wake this process up - assert(pcb_queue_remove(sleeping, &tmp) == SUCCESS); - schedule(tmp); - } while (1); - - // next, we decrement the current process' remaining time - current->ticks -= 1; - - // has it expired? - if (current->ticks < 1) { - // yes! reschedule it - schedule(current); - current = NULL; - // and pick a new process - dispatch(); - } - - // tell the PIC we're done - outb(PIC1_CMD, PIC_EOI); -} - -/* -** PUBLIC FUNCTIONS -*/ - -/** -** Name: clk_init -** -** Initializes the clock module -** -*/ -void clk_init(void) -{ -#if TRACING_INIT - cio_puts(" Clock"); -#endif - - // start the pinwheel - pinwheel = (CLOCK_FREQ / 10) - 1; - pindex = 0; - - // return to the dawn of time - system_time = 0; - - // configure the clock - uint32_t divisor = PIT_FREQ / CLOCK_FREQ; - outb(PIT_CONTROL_PORT, PIT_0_LOAD | PIT_0_SQUARE); - outb(PIT_0_PORT, divisor & 0xff); // LSB of divisor - outb(PIT_0_PORT, (divisor >> 8) & 0xff); // MSB of divisor - - // register the second-stage ISR - install_isr(VEC_TIMER, clk_isr); -} diff --git a/kernel/old/drivers/serial.c b/kernel/old/drivers/serial.c deleted file mode 100644 index d6572e5..0000000 --- a/kernel/old/drivers/serial.c +++ /dev/null @@ -1,629 +0,0 @@ -#define KERNEL_SRC - -// this should do all includes required for this OS -#include - -// all other framework includes are next -#include -#include -#include - -#include -#include - -/* -** PRIVATE DEFINITIONS -*/ - -#define BUF_SIZE 2048 - -/* -** PRIVATE GLOBALS -*/ - -// input character buffer -static char inbuffer[BUF_SIZE]; -static char *inlast; -static char *innext; -static uint32_t incount; - -// output character buffer -static char outbuffer[BUF_SIZE]; -static char *outlast; -static char *outnext; -static uint32_t outcount; - -// output control flag -static int sending; - -// interrupt register status -static uint8_t ier; - -/* -** PUBLIC GLOBAL VARIABLES -*/ - -// queue for read-blocked processes -#ifdef QNAME -extern QTYPE QNAME; -#endif - -/* -** PRIVATE FUNCTIONS -*/ - -/** -** sio_isr(vector,ecode) -** -** Interrupt handler for the SIO module. Handles all pending -** events (as described by the SIO controller). -** -** @param vector The interrupt vector number for this interrupt -** @param ecode The error code associated with this interrupt -*/ -static void sio_isr(int vector, int ecode) -{ - int ch; - -#if TRACING_SIO_ISR - cio_puts("SIO: int:"); -#endif - // - // Must process all pending events; loop until the IRR - // says there's nothing else to do. - // - - for (;;) { - // get the "pending event" indicator - int iir = inb(UA4_IIR) & UA4_IIR_INT_PRI_MASK; - - // process this event - switch (iir) { - case UA4_IIR_LINE_STATUS: - // shouldn't happen, but just in case.... - cio_printf("** SIO int, LSR = %02x\n", inb(UA4_LSR)); - break; - - case UA4_IIR_RX: -#if TRACING_SIO_ISR - cio_puts(" RX"); -#endif - // get the character - ch = inb(UA4_RXD); - if (ch == '\r') { // map CR to LF - ch = '\n'; - } -#if TRACING_SIO_ISR - cio_printf(" ch %02x", ch); -#endif - -#ifdef QNAME - // - // If there is a waiting process, this must be - // the first input character; give it to that - // process and awaken the process. - // - - if (!QEMPTY(QNAME)) { - PCBTYPE *pcb; - - QDEQUE(QNAME, pcb); - // make sure we got a non-NULL result - assert(pcb); - - // return char via arg #2 and count in EAX - char *buf = (char *)ARG(pcb, 2); - *buf = ch & 0xff; - RET(pcb) = 1; - SCHED(pcb); - - } else { -#endif /* QNAME */ - - // - // Nobody waiting - add to the input buffer - // if there is room, otherwise just ignore it. - // - - if (incount < BUF_SIZE) { - *inlast++ = ch; - ++incount; - } - -#ifdef QNAME - } -#endif /* QNAME */ - break; - - case UA5_IIR_RX_FIFO: - // shouldn't happen, but just in case.... - ch = inb(UA4_RXD); - cio_printf("** SIO FIFO timeout, RXD = %02x\n", ch); - break; - - case UA4_IIR_TX: -#if TRACING_SIO_ISR - cio_puts(" TX"); -#endif - // if there is another character, send it - if (sending && outcount > 0) { -#if TRACING_SIO_ISR - cio_printf(" ch %02x", *outnext); -#endif - outb(UA4_TXD, *outnext); - ++outnext; - // wrap around if necessary - if (outnext >= (outbuffer + BUF_SIZE)) { - outnext = outbuffer; - } - --outcount; -#if TRACING_SIO_ISR - cio_printf(" (outcount %d)", outcount); -#endif - } else { -#if TRACING_SIO_ISR - cio_puts(" EOS"); -#endif - // no more data - reset the output vars - outcount = 0; - outlast = outnext = outbuffer; - sending = 0; - // disable TX interrupts - sio_disable(SIO_TX); - } - break; - - case UA4_IIR_NO_INT: -#if TRACING_SIO_ISR - cio_puts(" EOI\n"); -#endif - // nothing to do - tell the PIC we're done - outb(PIC1_CMD, PIC_EOI); - return; - - case UA4_IIR_MODEM_STATUS: - // shouldn't happen, but just in case.... - cio_printf("** SIO int, MSR = %02x\n", inb(UA4_MSR)); - break; - - default: - // uh-oh.... - sprint(b256, "sio isr: IIR %02x\n", ((uint32_t)iir) & 0xff); - PANIC(0, b256); - } - } - - // should never reach this point! - assert(false); -} - -/* -** PUBLIC FUNCTIONS -*/ - -/** -** sio_init() -** -** Initialize the UART chip. -*/ -void sio_init(void) -{ -#if TRACING_INIT - cio_puts(" Sio"); -#endif - - /* - ** Initialize SIO variables. - */ - - memclr((void *)inbuffer, sizeof(inbuffer)); - inlast = innext = inbuffer; - incount = 0; - - memclr((void *)outbuffer, sizeof(outbuffer)); - outlast = outnext = outbuffer; - outcount = 0; - sending = 0; - - // queue of read-blocked processes - QCREATE(QNAME); - - /* - ** Next, initialize the UART. - ** - ** Initialize the FIFOs - ** - ** this is a bizarre little sequence of operations - */ - - outb(UA5_FCR, 0x20); - outb(UA5_FCR, UA5_FCR_FIFO_RESET); // 0x00 - outb(UA5_FCR, UA5_FCR_FIFO_EN); // 0x01 - outb(UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR); // 0x03 - outb(UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR | UA5_FCR_TXSR); // 0x07 - - /* - ** disable interrupts - ** - ** note that we leave them disabled; sio_enable() must be - ** called to switch them back on - */ - - outb(UA4_IER, 0); - ier = 0; - - /* - ** select the divisor latch registers and set the data rate - */ - - outb(UA4_LCR, UA4_LCR_DLAB); - outb(UA4_DLL, BAUD_LOW_BYTE(DL_BAUD_9600)); - outb(UA4_DLM, BAUD_HIGH_BYTE(DL_BAUD_9600)); - - /* - ** deselect the latch registers, by setting the data - ** characteristics in the LCR - */ - - outb(UA4_LCR, UA4_LCR_WLS_8 | UA4_LCR_1_STOP_BIT | UA4_LCR_NO_PARITY); - - /* - ** Set the ISEN bit to enable the interrupt request signal, - ** and the DTR and RTS bits to enable two-way communication. - */ - - outb(UA4_MCR, UA4_MCR_ISEN | UA4_MCR_DTR | UA4_MCR_RTS); - - /* - ** Install our ISR - */ - - install_isr(VEC_COM1, sio_isr); -} - -/** -** sio_enable() -** -** Enable SIO interrupts -** -** usage: uint8_t old = sio_enable( uint8_t which ) -** -** @param which Bit mask indicating which interrupt(s) to enable -** -** @return the prior IER setting -*/ -uint8_t sio_enable(uint8_t which) -{ - uint8_t old; - - // remember the current status - - old = ier; - - // figure out what to enable - - if (which & SIO_TX) { - ier |= UA4_IER_TX_IE; - } - - if (which & SIO_RX) { - ier |= UA4_IER_RX_IE; - } - - // if there was a change, make it - - if (old != ier) { - outb(UA4_IER, ier); - } - - // return the prior settings - - return (old); -} - -/** -** sio_disable() -** -** Disable SIO interrupts -** -** usage: uint8_t old = sio_disable( uint8_t which ) -** -** @param which Bit mask indicating which interrupt(s) to disable -** -** @return the prior IER setting -*/ -uint8_t sio_disable(uint8_t which) -{ - uint8_t old; - - // remember the current status - - old = ier; - - // figure out what to disable - - if (which & SIO_TX) { - ier &= ~UA4_IER_TX_IE; - } - - if (which & SIO_RX) { - ier &= ~UA4_IER_RX_IE; - } - - // if there was a change, make it - - if (old != ier) { - outb(UA4_IER, ier); - } - - // return the prior settings - - return (old); -} - -/** -** sio_inq_length() -** -** Get the input queue length -** -** usage: int num = sio_inq_length() -** -** @return the count of characters still in the input queue -*/ -int sio_inq_length(void) -{ - return (incount); -} - -/** -** sio_readc() -** -** Get the next input character -** -** usage: int ch = sio_readc() -** -** @return the next character, or -1 if no character is available -*/ -int sio_readc(void) -{ - int ch; - - // assume there is no character available - ch = -1; - - // - // If there is a character, return it - // - - if (incount > 0) { - // take it out of the input buffer - ch = ((int)(*innext++)) & 0xff; - --incount; - - // reset the buffer variables if this was the last one - if (incount < 1) { - inlast = innext = inbuffer; - } - } - - return (ch); -} - -/** -** sio_read(buf,length) -** -** Read the entire input buffer into a user buffer of a specified size -** -** usage: int num = sio_read( char *buffer, int length ) -** -** @param buf The destination buffer -** @param length Length of the buffer -** -** @return the number of bytes copied, or 0 if no characters were available -*/ - -int sio_read(char *buf, int length) -{ - char *ptr = buf; - int copied = 0; - - // if there are no characters, just return 0 - - if (incount < 1) { - return (0); - } - - // - // We have characters. Copy as many of them into the user - // buffer as will fit. - // - - while (incount > 0 && copied < length) { - *ptr++ = *innext++ & 0xff; - if (innext > (inbuffer + BUF_SIZE)) { - innext = inbuffer; - } - --incount; - ++copied; - } - - // reset the input buffer if necessary - - if (incount < 1) { - inlast = innext = inbuffer; - } - - // return the copy count - - return (copied); -} - -/** -** sio_writec( ch ) -** -** Write a character to the serial output -** -** usage: sio_writec( int ch ) -** -** @param ch Character to be written (in the low-order 8 bits) -*/ -void sio_writec(int ch) -{ - // - // Must do LF -> CRLF mapping - // - - if (ch == '\n') { - sio_writec('\r'); - } - - // - // If we're currently transmitting, just add this to the buffer - // - - if (sending) { - *outlast++ = ch; - ++outcount; - return; - } - - // - // Not sending - must prime the pump - // - - sending = 1; - outb(UA4_TXD, ch); - - // Also must enable transmitter interrupts - - sio_enable(SIO_TX); -} - -/** -** sio_write( buffer, length ) -** -** Write a buffer of characters to the serial output -** -** usage: int num = sio_write( const char *buffer, int length ) -** -** @param buffer Buffer containing characters to write -** @param length Number of characters to write -** -** @return the number of characters copied into the SIO output buffer -*/ -int sio_write(const char *buffer, int length) -{ - int first = *buffer; - const char *ptr = buffer; - int copied = 0; - - // - // If we are currently sending, we want to append all - // the characters to the output buffer; else, we want - // to append all but the first character, and then use - // sio_writec() to send the first one out. - // - - if (!sending) { - ptr += 1; - copied++; - } - - while (copied < length && outcount < BUF_SIZE) { - *outlast++ = *ptr++; - // wrap around if necessary - if (outlast >= (outbuffer + BUF_SIZE)) { - outlast = outbuffer; - } - ++outcount; - ++copied; - } - - // - // We use sio_writec() to send out the first character, - // as it will correctly set all the other necessary - // variables for us. - // - - if (!sending) { - sio_writec(first); - } - - // Return the transfer count - - return (copied); -} - -/** -** sio_puts( buf ) -** -** Write a NUL-terminated buffer of characters to the serial output -** -** usage: int num = sio_puts( const char *buffer ) -** -** @param buffer The buffer containing a NUL-terminated string -** -** @return the count of bytes transferred -*/ -int sio_puts(const char *buffer) -{ - int n; // must be outside the loop so we can return it - - n = SLENGTH(buffer); - sio_write(buffer, n); - - return (n); -} - -/** -** sio_dump( full ) -** -** dump the contents of the SIO buffers to the console -** -** usage: sio_dump(true) or sio_dump(false) -** -** @param full Boolean indicating whether or not a "full" dump -** is being requested (which includes the contents -** of the queues) -*/ - -void sio_dump(bool_t full) -{ - int n; - char *ptr; - - // dump basic info into the status region - - cio_printf_at(48, 0, "SIO: IER %02x (%c%c%c) in %d ot %d", - ((uint32_t)ier) & 0xff, sending ? '*' : '.', - (ier & UA4_IER_TX_IE) ? 'T' : 't', - (ier & UA4_IER_RX_IE) ? 'R' : 'r', incount, outcount); - - // if we're not doing a full dump, stop now - - if (!full) { - return; - } - - // also want the queue contents, but we'll - // dump them into the scrolling region - - if (incount) { - cio_puts("SIO input queue: \""); - ptr = innext; - for (n = 0; n < incount; ++n) { - put_char_or_code(*ptr++); - } - cio_puts("\"\n"); - } - - if (outcount) { - cio_puts("SIO output queue: \""); - cio_puts(" ot: \""); - ptr = outnext; - for (n = 0; n < outcount; ++n) { - put_char_or_code(*ptr++); - } - cio_puts("\"\n"); - } -} diff --git a/kernel/old/include/.vm.h.swp b/kernel/old/include/.vm.h.swp new file mode 100644 index 0000000..eb334b9 Binary files /dev/null and b/kernel/old/include/.vm.h.swp differ diff --git a/kernel/old/include/bindings.h b/kernel/old/include/bindings.h deleted file mode 100644 index 365abc9..0000000 --- a/kernel/old/include/bindings.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file bindings.h - * @author Freya Murphy - * - * C-style function definitions binded to their named assembly instruction. - */ - -#ifndef _BINDINGS_H -#define _BINDINGS_H -#include - -static inline uint8_t inb(uint16_t port) -{ - uint8_t ret; - __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline void outb(uint16_t port, uint8_t val) -{ - __asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port)); -} - -static inline uint16_t inw(uint16_t port) -{ - uint16_t ret; - __asm__ volatile("inw %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline void outw(uint16_t port, uint16_t val) -{ - __asm__ volatile("outw %0, %1" : : "a"(val), "Nd"(port)); -} - -static inline uint32_t inl(uint16_t port) -{ - uint32_t ret; - __asm__ volatile("inl %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline void outl(uint16_t port, uint32_t val) -{ - __asm__ volatile("outl %0, %1" : : "a"(val), "Nd"(port)); -} - -static inline void io_wait(void) -{ - outb(0x80, 0); -} - -static inline void sti(void) -{ - __asm__ volatile("sti"); -} - -static inline void cli(void) -{ - __asm__ volatile("cli"); -} - -static inline void int_wait(void) -{ - __asm__ volatile("sti; hlt"); -} - -static inline void halt(void) -{ - __asm__ volatile("cli; hlt"); -} - -#endif /* bindings.h */ diff --git a/kernel/old/include/bootstrap.h b/kernel/old/include/bootstrap.h index 6c6dfcc..ade778a 100644 --- a/kernel/old/include/bootstrap.h +++ b/kernel/old/include/bootstrap.h @@ -9,89 +9,89 @@ ** Addresses where various stuff goes in memory. */ -#ifndef BOOTSTRAP_H_ -#define BOOTSTRAP_H_ +#ifndef BOOTSTRAP_H_ +#define BOOTSTRAP_H_ /* ** The boot device */ -#define BDEV_FLOPPY 0x00 -#define BDEV_USB 0x80 /* hard drive */ +#define BDEV_FLOPPY 0x00 +#define BDEV_USB 0x80 /* hard drive */ -#define BDEV BDEV_USB /* default */ +#define BDEV BDEV_USB /* default */ /* ** Bootstrap definitions */ -#define BOOT_SEG 0x07c0 /* 07c0:0000 */ -#define BOOT_DISP 0x0000 -#define BOOT_ADDR ((BOOT_SEG << 4) + BOOT_DISP) +#define BOOT_SEG 0x07c0 /* 07c0:0000 */ +#define BOOT_DISP 0x0000 +#define BOOT_ADDR ((BOOT_SEG << 4) + BOOT_DISP) -#define PART2_DISP 0x0200 /* 07c0:0200 */ -#define PART2_ADDR ((BOOT_SEG << 4) + PART2_DISP) +#define PART2_DISP 0x0200 /* 07c0:0200 */ +#define PART2_ADDR ((BOOT_SEG << 4) + PART2_DISP) -#define SECTOR_SIZE 0x200 /* 512 bytes */ +#define SECTOR_SIZE 0x200 /* 512 bytes */ /* Note: this assumes the bootstrap is two sectors long! */ -#define BOOT_SIZE (SECTOR_SIZE + SECTOR_SIZE) +#define BOOT_SIZE (SECTOR_SIZE + SECTOR_SIZE) -#define OFFSET_LIMIT (0x10000 - SECTOR_SIZE) +#define OFFSET_LIMIT (0x10000 - SECTOR_SIZE) -#define BOOT_SP_DISP 0x4000 /* stack pointer 07c0:4000, or 0xbc00 */ -#define BOOT_SP_ADDR ((BOOT_SEG << 4) + BOOT_SP_DISP) +#define BOOT_SP_DISP 0x4000 /* stack pointer 07c0:4000, or 0xbc00 */ +#define BOOT_SP_ADDR ((BOOT_SEG << 4) + BOOT_SP_DISP) -#define SECTOR1_END (BOOT_ADDR + SECTOR_SIZE) -#define SECTOR2_END (BOOT_ADDR + BOOT_SIZE) +#define SECTOR1_END (BOOT_ADDR + SECTOR_SIZE) +#define SECTOR2_END (BOOT_ADDR + BOOT_SIZE) // location of the user blob data // (three halfwords of data) -#define USER_BLOB_DATA (SECTOR2_END - 12) +#define USER_BLOB_DATA (SECTOR2_END - 12) /* ** The target program itself */ -#define TARGET_SEG 0x00001000 /* 1000:0000 */ -#define TARGET_ADDR 0x00010000 /* and upward */ -#define TARGET_STACK 0x00010000 /* and downward */ +#define TARGET_SEG 0x00001000 /* 1000:0000 */ +#define TARGET_ADDR 0x00010000 /* and upward */ +#define TARGET_STACK 0x00010000 /* and downward */ /* ** The Global Descriptor Table (0000:0500 - 0000:2500) */ -#define GDT_SEG 0x00000050 -#define GDT_ADDR 0x00000500 +#define GDT_SEG 0x00000050 +#define GDT_ADDR 0x00000500 -/* segment register values */ -#define GDT_LINEAR 0x0008 /* All of memory, R/W */ -#define GDT_CODE 0x0010 /* All of memory, R/E */ -#define GDT_DATA 0x0018 /* All of memory, R/W */ -#define GDT_STACK 0x0020 /* All of memory, R/W */ + /* segment register values */ +#define GDT_LINEAR 0x0008 /* All of memory, R/W */ +#define GDT_CODE 0x0010 /* All of memory, R/E */ +#define GDT_DATA 0x0018 /* All of memory, R/W */ +#define GDT_STACK 0x0020 /* All of memory, R/W */ /* ** The Interrupt Descriptor Table (0000:2500 - 0000:2D00) */ -#define IDT_SEG 0x00000250 -#define IDT_ADDR 0x00002500 +#define IDT_SEG 0x00000250 +#define IDT_ADDR 0x00002500 /* ** Additional I/O ports used by the bootstrap code */ // keyboard controller -#define KBD_DATA 0x60 -#define KBD_CMD 0x64 -#define KBD_STAT 0x64 +#define KBD_DATA 0x60 +#define KBD_CMD 0x64 +#define KBD_STAT 0x64 // status register bits -#define KBD_OBSTAT 0x01 -#define KBD_IBSTAT 0x02 -#define KBD_SYSFLAG 0x04 -#define KBD_CMDDAT 0x08 +#define KBD_OBSTAT 0x01 +#define KBD_IBSTAT 0x02 +#define KBD_SYSFLAG 0x04 +#define KBD_CMDDAT 0x08 // commands -#define KBD_P1_DISABLE 0xad -#define KBD_P1_ENABLE 0xae -#define KBD_RD_OPORT 0xd0 -#define KBD_WT_OPORT 0xd1 +#define KBD_P1_DISABLE 0xad +#define KBD_P1_ENABLE 0xae +#define KBD_RD_OPORT 0xd0 +#define KBD_WT_OPORT 0xd1 #ifdef ASM_SRC @@ -104,16 +104,17 @@ // .byte granularity byte // .byte upper 8 bits of base // we use 4K units, so we ignore the lower 12 bits of the limit -#define SEGNULL .word 0, 0, 0, 0 - -#define SEGMENT(base, limit, dpl, type) \ - .word(((limit) >> 12) & 0xffff); \ - .word((base) & 0xffff); \ - .byte(((base) >> 16) & 0xff); \ - .byte(SEG_PRESENT | (dpl) | SEG_NON_SYSTEM | (type)); \ - .byte(SEG_GRAN_4KBYTE | SEG_DB_32BIT | (((limit) >> 28) & 0xf)); \ - .byte(((base) >> 24) & 0xff) - -#endif /* ASM_SRC */ +#define SEGNULL \ + .word 0, 0, 0, 0 + +#define SEGMENT(base,limit,dpl,type) \ + .word (((limit) >> 12) & 0xffff); \ + .word ((base) & 0xffff) ; \ + .byte (((base) >> 16) & 0xff) ; \ + .byte (SEG_PRESENT | (dpl) | SEG_NON_SYSTEM | (type)) ; \ + .byte (SEG_GRAN_4KBYTE | SEG_DB_32BIT | (((limit) >> 28) & 0xf)) ; \ + .byte (((base) >> 24) & 0xff) + +#endif /* ASM_SRC */ #endif diff --git a/kernel/old/include/cio.h b/kernel/old/include/cio.h index 63bf827..1854f6e 100644 --- a/kernel/old/include/cio.h +++ b/kernel/old/include/cio.h @@ -11,7 +11,7 @@ ** Declarations and descriptions of console I/O routines ** ** These routines provide a rudimentary capability for printing to -** the screen and reading from the keyboard. +** the screen and reading from the keyboard. ** ** Screen output: ** There are two families of functions. The first provides a window @@ -50,7 +50,7 @@ ** Keyboard input: ** Two functions are provided: getting a single character and getting ** a newline-terminated line. A third function returns a count of -** the number of characters available for immediate reading. +** the number of characters available for immediate reading. ** No conversions are provided (yet). */ @@ -77,7 +77,7 @@ ** ** @param notify pointer to an input notification function, or NULL */ -void cio_init(void (*notify)(int)); +void cio_init( void (*notify)(int) ); /***************************************************************************** ** @@ -102,8 +102,8 @@ void cio_init(void (*notify)(int)); ** @param min_x,min_y upper-left corner of the region ** @param max_x,max_y lower-right corner of the region */ -void cio_setscroll(unsigned int min_x, unsigned int min_y, unsigned int max_x, - unsigned int max_y); +void cio_setscroll( unsigned int min_x, unsigned int min_y, + unsigned int max_x, unsigned int max_y ); /** ** cio_moveto @@ -114,7 +114,7 @@ void cio_setscroll(unsigned int min_x, unsigned int min_y, unsigned int max_x, ** ** @param x,y desired coordinate position */ -void cio_moveto(unsigned int x, unsigned int y); +void cio_moveto( unsigned int x, unsigned int y ); /** ** cio_putchar @@ -123,7 +123,7 @@ void cio_moveto(unsigned int x, unsigned int y); ** ** @param c the character to be printed */ -void cio_putchar(unsigned int c); +void cio_putchar( unsigned int c ); /** ** cio_puts @@ -133,7 +133,7 @@ void cio_putchar(unsigned int c); ** ** @param str pointer to a NUL-terminated string to be printed */ -void cio_puts(const char *str); +void cio_puts( const char *str ); /** ** cio_write @@ -143,7 +143,7 @@ void cio_puts(const char *str); ** @param buf the buffer of characters ** @param length the number of characters to print */ -void cio_write(const char *buf, int length); +void cio_write( const char *buf, int length ); /** ** cio_printf @@ -154,7 +154,7 @@ void cio_write(const char *buf, int length); ** @param fmt a printf-style format control string ** @param ... optional additional values to be printed */ -void cio_printf(char *fmt, ...); +void cio_printf( char *fmt, ... ); /** ** cio_scroll @@ -165,7 +165,7 @@ void cio_printf(char *fmt, ...); ** ** @param lines the number of lines to scroll */ -void cio_scroll(unsigned int lines); +void cio_scroll( unsigned int lines ); /** ** cio_clearscroll @@ -173,7 +173,7 @@ void cio_scroll(unsigned int lines); ** Clears the entire scrolling region to blank spaces, and ** moves the cursor to (0,0). */ -void cio_clearscroll(void); +void cio_clearscroll( void ); /***************************************************************************** ** @@ -196,7 +196,7 @@ void cio_clearscroll(void); ** @param x,y desired coordinate position ** @param c the character to be printed */ -void cio_putchar_at(unsigned int x, unsigned int y, unsigned int c); +void cio_putchar_at( unsigned int x, unsigned int y, unsigned int c ); /** ** cio_puts_at @@ -207,7 +207,7 @@ void cio_putchar_at(unsigned int x, unsigned int y, unsigned int c); ** @param x,y desired coordinate position ** @param str pointer to a NUL-terminated string to be printed */ -void cio_puts_at(unsigned int x, unsigned int y, const char *str); +void cio_puts_at( unsigned int x, unsigned int y, const char *str ); /** ** cio_printf_at @@ -219,14 +219,14 @@ void cio_puts_at(unsigned int x, unsigned int y, const char *str); ** @param fmt a printf-style format control string ** @param ... optional additional values to be printed */ -void cio_printf_at(unsigned int x, unsigned int y, char *fmt, ...); +void cio_printf_at( unsigned int x, unsigned int y, char *fmt, ... ); /** ** cio_clearscreen ** ** This function clears the entire screen, including the scrolling region. */ -void cio_clearscreen(void); +void cio_clearscreen( void ); /***************************************************************************** ** @@ -251,7 +251,7 @@ void cio_clearscreen(void); ** ** @return the next character from the keyboard input buffer */ -int cio_getchar(void); +int cio_getchar( void ); /** ** cio_gets @@ -270,7 +270,7 @@ int cio_getchar(void); ** ** @return count of the number of characters read into the buffer */ -int cio_gets(char *buffer, unsigned int size); +int cio_gets( char *buffer, unsigned int size ); /** ** cio_input_queue @@ -281,7 +281,7 @@ int cio_gets(char *buffer, unsigned int size); ** ** @return number of characters in the input queue */ -int cio_input_queue(void); -#endif /* !ASM_SRC */ +int cio_input_queue( void ); +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/clock.h b/kernel/old/include/clock.h index 674d799..6eae41f 100644 --- a/kernel/old/include/clock.h +++ b/kernel/old/include/clock.h @@ -17,10 +17,10 @@ // conversion functions for seconds, ms, and ticks // (SEC_TO_MS is defined in defs.h) -#define MS_TO_TICKS(n) ((n)) -#define SEC_TO_TICKS(n) (MS_TO_TICKS(SEC_TO_MS(n))) -#define TICKS_TO_SEC(n) ((n) / CLOCK_FREQ) -#define TICKS_TO_SEC_ROUNDED(n) (((n) + (CLOCK_FREQ - 1)) / CLOCK_FREQ) +#define MS_TO_TICKS(n) ((n)) +#define SEC_TO_TICKS(n) (MS_TO_TICKS(SEC_TO_MS(n))) +#define TICKS_TO_SEC(n) ((n) / CLOCK_FREQ) +#define TICKS_TO_SEC_ROUNDED(n) (((n)+(CLOCK_FREQ-1)) / CLOCK_FREQ) #ifndef ASM_SRC @@ -48,8 +48,8 @@ extern uint32_t system_time; ** ** Clock module initialization */ -void clk_init(void); +void clk_init( void ); -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/common.h b/kernel/old/include/common.h new file mode 100644 index 0000000..599c492 --- /dev/null +++ b/kernel/old/include/common.h @@ -0,0 +1,31 @@ +/** +** @file common.h +** +** @author Warren R. Carithers +** +** @brief Common definitions for the baseline system. +** +** This header file pulls in the standard header information needed +** by all parts of the system. It is purely for our convenience. +*/ + +#ifndef COMMON_H_ +#define COMMON_H_ + +// everything needs these; they also pull in +// the kernel- or user-level defs and lib headers +#include +#include +#include +#include + +#ifdef KERNEL_SRC + +// only kernel code needs these headers +#include +#include +#include + +#endif /* KERNEL_SRC */ + +#endif diff --git a/kernel/old/include/compat.h b/kernel/old/include/compat.h index f0c8c97..ee62090 100644 --- a/kernel/old/include/compat.h +++ b/kernel/old/include/compat.h @@ -60,10 +60,10 @@ */ // type name for the PCB -#define PCBTYPE pcb_t +#define PCBTYPE pcb_t // type name for our queue -#define QTYPE pcb_queue_t +#define QTYPE pcb_queue_t /* ** Section 3: interface and behavior @@ -77,13 +77,13 @@ */ // string functions -#define SLENGTH strlen +#define SLENGTH strlen // scheduler -#define SCHED schedule +#define SCHED schedule // dispatcher -#define DISPATCH dispatch +#define DISPATCH dispatch /* ** blocked queue for reading processes @@ -93,7 +93,7 @@ ** Its value should be the name of the globally-visible ** queue to be used. */ -#define QNAME sioread +#define QNAME sioread #ifdef QNAME @@ -105,27 +105,26 @@ // invoke the queue creation function // examples: // -// #define QCREATE(q) do { -// _que_create( &(q), NULL ); +// #define QCREATE(q) do { +// _que_create( &(q), NULL ); // } while(0) // // #define QCREATE(q) // do nothing -#define QCREATE(q) // handled elsewhere for us +#define QCREATE(q) // handled elsewhere for us // check to see if the queue is empty // examples: // // #define QEMPTY(q) queue_is_empty(q) // #define QEMPTY(q) (quene_length(q) > 0) -#define QEMPTY(q) pcb_queue_empty(q) +#define QEMPTY(q) pcb_queue_empty(q) // this macro expands into code that removes a value from // 'q' and places it into 'd' -#define QDEQUE(q, d) \ - do { \ - assert(pcb_queue_remove((q), (pcb_t **)&(d)) == SUCCESS); \ - } while (0) +#define QDEQUE(q,d) do { \ + assert(pcb_queue_remove( (q), (pcb_t **) &(d) ) == SUCCESS ); \ + } while(0) #endif /* QNAME */ diff --git a/kernel/old/include/debug.h b/kernel/old/include/debug.h index 41e38cb..487a592 100644 --- a/kernel/old/include/debug.h +++ b/kernel/old/include/debug.h @@ -35,17 +35,11 @@ // currently, these do not use the macro parameter, but could be // modified to do so; instead, we use the __func__ CPP pseudo-macro // to get the function name -#define ENTERING(n) \ - do { \ - cio_puts(" enter " __func__); \ - } while (0) -#define EXITING(n) \ - do { \ - cio_puts(" exit " __func__); \ - } while (0) +#define ENTERING(n) do { cio_puts( " enter " __func__ ); } while(0) +#define EXITING(n) do { cio_puts( " exit " __func__ ); } while(0) #else -#define ENTERING(m) // do nothing -#define EXITING(m) // do nothing +#define ENTERING(m) // do nothing +#define EXITING(m) // do nothing #endif /* @@ -54,22 +48,20 @@ // Warning messages to the console // m: message (condition, etc.) -#define WARNING(m) \ - do { \ - cio_printf("\n** %s (%s @ %d): ", __func__, __FILE__, __LINE__); \ - cio_puts(m); \ - cio_putchar('\n'); \ - } while (0) +#define WARNING(m) do { \ + cio_printf( "\n** %s (%s @ %d): ", __func__, __FILE__, __LINE__ ); \ + cio_puts( m ); \ + cio_putchar( '\n' ); \ + } while(0) // Panic messages to the console // n: severity level // m: message (condition, etc.) -#define PANIC(n, m) \ - do { \ - sprint(b512, "%s (%s @ %d), %d: %s\n", __func__, __FILE__, __LINE__, \ - n, #m); \ - kpanic(b512); \ - } while (0) +#define PANIC(n,m) do { \ + sprint( b512, "%s (%s @ %d), %d: %s\n", \ + __func__, __FILE__, __LINE__, n, # m ); \ + kpanic( b512 ); \ + } while(0) /* ** Assertions are categorized by the "sanity level" being used in this @@ -84,48 +76,30 @@ #ifndef SANITY // default sanity check level: check everything! -#define SANITY 9999 +#define SANITY 9999 #endif // Always-active assertions -#define assert(x) \ - if (!(x)) { \ - PANIC(0, x); \ - } +#define assert(x) if( !(x) ) { PANIC(0,x); } // only provide these macros if the sanity check level is positive #if SANITY > 0 -#define assert1(x) \ - if (SANITY >= 1 && !(x)) { \ - PANIC(1, x); \ - } -#define assert2(x) \ - if (SANITY >= 2 && !(x)) { \ - PANIC(2, x); \ - } -#define assert3(x) \ - if (SANITY >= 3 && !(x)) { \ - PANIC(3, x); \ - } -#define assert4(x) \ - if (SANITY >= 4 && !(x)) { \ - PANIC(4, x); \ - } +#define assert1(x) if( SANITY >= 1 && !(x) ) { PANIC(1,x); } +#define assert2(x) if( SANITY >= 2 && !(x) ) { PANIC(2,x); } +#define assert3(x) if( SANITY >= 3 && !(x) ) { PANIC(3,x); } +#define assert4(x) if( SANITY >= 4 && !(x) ) { PANIC(4,x); } // arbitrary sanity level -#define assertN(n, x) \ - if (SANITY >= (n) && !(x)) { \ - PANIC(n, x); \ - } +#define assertN(n,x) if( SANITY >= (n) && !(x) ) { PANIC(n,x); } #else -#define assert1(x) // do nothing -#define assert2(x) // do nothing -#define assert3(x) // do nothing -#define assert4(x) // do nothing -#define assertN(n, x) // do nothing +#define assert1(x) // do nothing +#define assert2(x) // do nothing +#define assert3(x) // do nothing +#define assert4(x) // do nothing +#define assertN(n,x) // do nothing #endif /* SANITY > 0 */ @@ -169,185 +143,182 @@ // 2^0 bit #ifdef T_PCB -#define TRPCB 0x00000001 +#define TRPCB 0x00000001 #else -#define TRPCB 0 +#define TRPCB 0 #endif #ifdef T_VM -#define TRVM 0x00000002 +#define TRVM 0x00000002 #else -#define TRVM 0 +#define TRVM 0 #endif #ifdef T_QUE -#define TRQUEUE 0x00000004 +#define TRQUEUE 0x00000004 #else -#define TRQUEUE 0 +#define TRQUEUE 0 #endif #ifdef T_SCH -#define TRSCHED 0x00000008 +#define TRSCHED 0x00000008 #else -#define TRSCHED 0 +#define TRSCHED 0 #endif // 2^4 bit #ifdef T_DSP -#define TRDISP 0x00000010 +#define TRDISP 0x00000010 #else -#define TRDISP 0 +#define TRDISP 0 #endif #ifdef T_SCALL -#define TRSYSCALLS 0x00000020 +#define TRSYSCALLS 0x00000020 #else -#define TRSYSCALLS 0 +#define TRSYSCALLS 0 #endif #ifdef T_SRET -#define TRSYSRETS 0x00000040 +#define TRSYSRETS 0x00000040 #else -#define TRSYSRETS 0 +#define TRSYSRETS 0 #endif #ifdef T_EXIT -#define TREXIT 0x00000080 +#define TREXIT 0x00000080 #else -#define TREXIT 0 +#define TREXIT 0 #endif // 2^8 bit #ifdef T_INIT -#define TRINIT 0x00000100 +#define TRINIT 0x00000100 #else -#define TRINIT 0 +#define TRINIT 0 #endif #ifdef T_KM -#define TRKMEM 0x00000200 +#define TRKMEM 0x00000200 #else -#define TRKMEM 0 +#define TRKMEM 0 #endif #ifdef T_KMFR -#define TRKMEM_F 0x00000400 +#define TRKMEM_F 0x00000400 #else -#define TRKMEM_F 0 +#define TRKMEM_F 0 #endif #ifdef T_KMIN -#define TRKMEM_I 0x00000800 +#define TRKMEM_I 0x00000800 #else -#define TRKMEM_I 0 +#define TRKMEM_I 0 #endif // 2^12 bit #ifdef T_FORK -#define TRFORK 0x00001000 +#define TRFORK 0x00001000 #else -#define TRFORK 0 +#define TRFORK 0 #endif #ifdef T_EXEC -#define TREXEC 0x00002000 +#define TREXEC 0x00002000 #else -#define TREXEC 0 +#define TREXEC 0 #endif #ifdef T_SIO -#define TRSIO_STAT 0x00004000 +#define TRSIO_STAT 0x00004000 #else -#define TRSIO_STAT 0 +#define TRSIO_STAT 0 #endif #ifdef T_SIOR -#define TRSIO_RD 0x00008000 +#define TRSIO_RD 0x00008000 #else -#define TRSIO_RD 0 +#define TRSIO_RD 0 #endif // 2^16 bit #ifdef T_SIOW -#define TRSIO_WR 0x00010000 +#define TRSIO_WR 0x00010000 #else -#define TRSIO_WR 0 +#define TRSIO_WR 0 #endif #ifdef T_USER -#define TRUSER 0x00020000 +#define TRUSER 0x00020000 #else -#define TRUSER 0 +#define TRUSER 0 #endif #ifdef T_ELF -#define TRELF 0x00040000 +#define TRELF 0x00040000 #else -#define TRELF 0 +#define TRELF 0 #endif // 13 bits remaining for tracing options // next available bit: 0x00080000 -#define TRACE \ - (TRDISP | TREXIT | TRINIT | TRKMEM | TRKMEM_F | TRKMEM_I | TRPCB | \ - TRQUEUE | TRSCHED | TREXEC | TRSIO_RD | TRSIO_STAT | TRSIO_WR | TRFORK | \ - TRVM | TRSYSCALLS | TRSYSRETS | TRUSER | TRELF) +#define TRACE (TRDISP | TREXIT | TRINIT | TRKMEM | TRKMEM_F | TRKMEM_I | TRPCB | TRQUEUE | TRSCHED | TREXEC | TRSIO_RD | TRSIO_STAT | TRSIO_WR | TRFORK | TRVM | TRSYSCALLS | TRSYSRETS | TRUSER | TRELF) #if TRACE > 0 // compile-time expressions for testing trace options // usage: #if TRACING_thing -#define TRACING_PCB ((TRACE & TRPCB) != 0) -#define TRACING_VM ((TRACE & TRVM) != 0) -#define TRACING_QUEUE ((TRACE & TRQUEUE) != 0) -#define TRACING_SCHED ((TRACE & TRSCHED) != 0) -#define TRACING_DISPATCH ((TRACE & TRDISPATCH) != 0) -#define TRACING_SYSCALLS ((TRACE & TRSYSCALLS) != 0) -#define TRACING_SYSRETS ((TRACE & TRSYSRETS) != 0) -#define TRACING_EXIT ((TRACE & TREXIT) != 0) -#define TRACING_INIT ((TRACE & TRINIT) != 0) -#define TRACING_KMEM ((TRACE & TRKMEM) != 0) -#define TRACING_KMEM_FREELIST ((TRACE & TRKMEM_F) != 0) -#define TRACING_KMEM_INIT ((TRACE & TRKMEM_I) != 0) -#define TRACING_FORK ((TRACE & TRFORK) != 0) -#define TRACING_EXEC ((TRACE & TREXEC) != 0) -#define TRACING_SIO_STAT ((TRACE & TRSIO_STAT) != 0) -#define TRACING_SIO_ISR ((TRACE & TRSIO_ISR) != 0) -#define TRACING_SIO_RD ((TRACE & TRSIO_RD) != 0) -#define TRACING_SIO_WR ((TRACE & TRSIO_WR) != 0) -#define TRACING_USER ((TRACE & TRUSER) != 0) -#define TRACING_ELF ((TRACE & TRELF) != 0) +#define TRACING_PCB ((TRACE & TRPCB) != 0) +#define TRACING_VM ((TRACE & TRVM) != 0) +#define TRACING_QUEUE ((TRACE & TRQUEUE) != 0) +#define TRACING_SCHED ((TRACE & TRSCHED) != 0) +#define TRACING_DISPATCH ((TRACE & TRDISPATCH) != 0) +#define TRACING_SYSCALLS ((TRACE & TRSYSCALLS) != 0) +#define TRACING_SYSRETS ((TRACE & TRSYSRETS) != 0) +#define TRACING_EXIT ((TRACE & TREXIT) != 0) +#define TRACING_INIT ((TRACE & TRINIT) != 0) +#define TRACING_KMEM ((TRACE & TRKMEM) != 0) +#define TRACING_KMEM_FREELIST ((TRACE & TRKMEM_F) != 0) +#define TRACING_KMEM_INIT ((TRACE & TRKMEM_I) != 0) +#define TRACING_FORK ((TRACE & TRFORK) != 0) +#define TRACING_EXEC ((TRACE & TREXEC) != 0) +#define TRACING_SIO_STAT ((TRACE & TRSIO_STAT) != 0) +#define TRACING_SIO_ISR ((TRACE & TRSIO_ISR) != 0) +#define TRACING_SIO_RD ((TRACE & TRSIO_RD) != 0) +#define TRACING_SIO_WR ((TRACE & TRSIO_WR) != 0) +#define TRACING_USER ((TRACE & TRUSER) != 0) +#define TRACING_ELF ((TRACE & TRELF) != 0) // more generic tests -#define TRACING_SOMETHING (TRACE != 0) +#define TRACING_SOMETHING (TRACE != 0) #else // TRACE == 0, so just define these all as "false" -#define TRACING_PCB 0 -#define TRACING_STACK 0 -#define TRACING_QUEUE 0 -#define TRACING_SCHED 0 -#define TRACING_DISPATCH 0 -#define TRACING_SYSCALLS 0 -#define TRACING_SYSRET 0 -#define TRACING_EXIT 0 -#define TRACING_INIT 0 -#define TRACING_KMEM 0 -#define TRACING_KMEM_FREELIST 0 -#define TRACING_KMEM_INIT 0 -#define TRACING_FORK 0 -#define TRACING_EXEC 0 -#define TRACING_SI_STAT 0 -#define TRACING_SIO_ISR 0 -#define TRACING_SIO_RD 0 -#define TRACING_SIO_WR 0 -#define TRACING_USER 0 -#define TRACING_ELF 0 - -#define TRACING_SOMETHING 0 +#define TRACING_PCB 0 +#define TRACING_STACK 0 +#define TRACING_QUEUE 0 +#define TRACING_SCHED 0 +#define TRACING_DISPATCH 0 +#define TRACING_SYSCALLS 0 +#define TRACING_SYSRET 0 +#define TRACING_EXIT 0 +#define TRACING_INIT 0 +#define TRACING_KMEM 0 +#define TRACING_KMEM_FREELIST 0 +#define TRACING_KMEM_INIT 0 +#define TRACING_FORK 0 +#define TRACING_EXEC 0 +#define TRACING_SI_STAT 0 +#define TRACING_SIO_ISR 0 +#define TRACING_SIO_RD 0 +#define TRACING_SIO_WR 0 +#define TRACING_USER 0 +#define TRACING_ELF 0 + +#define TRACING_SOMETHING 0 #endif /* TRACE */ diff --git a/kernel/old/include/defs.h b/kernel/old/include/defs.h index 018b14e..0280c47 100644 --- a/kernel/old/include/defs.h +++ b/kernel/old/include/defs.h @@ -29,21 +29,24 @@ // we define this the traditional way so that // it's usable from both C and assembly -#define NULL 0 +#define NULL 0 // predefined i/o channels -#define CHAN_CIO 0 -#define CHAN_SIO 1 +#define CHAN_CIO 0 +#define CHAN_SIO 1 + +// maximum allowable number of command-line arguments +#define MAX_ARGS 10 // sizes of various things -#define NUM_1KB 0x00000400 // 2^10 -#define NUM_4KB 0x00001000 // 2^12 -#define NUM_1MB 0x00100000 // 2^20 -#define NUM_4MB 0x00400000 // 2^22 -#define NUM_1GB 0x40000000 // 2^30 -#define NUM_2GB 0x80000000 // 2^31 -#define NUM_3GB 0xc0000000 // 1GB + 2GB +#define NUM_1KB 0x00000400 // 2^10 +#define NUM_4KB 0x00001000 // 2^12 +#define NUM_1MB 0x00100000 // 2^20 +#define NUM_4MB 0x00400000 // 2^22 +#define NUM_1GB 0x40000000 // 2^30 +#define NUM_2GB 0x80000000 // 2^31 +#define NUM_3GB 0xc0000000 #ifndef ASM_SRC @@ -60,63 +63,59 @@ ** These can be returned to both system functions ** and to user system calls. */ -// success! -#define SUCCESS (0) -#define E_SUCCESS SUCCESS -// generic "something went wrong" -#define E_FAILURE (-1) -// specific failure reasons -#define E_BAD_PARAM (-2) -#define E_BAD_CHAN (-3) -#define E_NO_CHILDREN (-4) -#define E_NO_MEMORY (-5) -#define E_NOT_FOUND (-6) -#define E_NO_PROCS (-7) + // success! +#define SUCCESS (0) +# define E_SUCCESS SUCCESS + // generic "something went wrong" +#define E_FAILURE (-1) + // specific failure reasons +#define E_BAD_PARAM (-2) +#define E_BAD_CHAN (-3) +#define E_NO_CHILDREN (-4) +#define E_NO_MEMORY (-5) +#define E_NOT_FOUND (-6) +#define E_NO_PROCS (-7) /* ** These error codes are internal to the OS. */ -#define E_EMPTY_QUEUE (-100) -#define E_NO_PCBS (-101) -#define E_NO_PTE (-102) -#define E_LOAD_LIMIT (-103) +#define E_EMPTY_QUEUE (-100) +#define E_NO_PCBS (-101) +#define E_NO_PTE (-102) +#define E_LOAD_LIMIT (-103) // exit status values -#define EXIT_SUCCESS (0) -#define EXIT_FAILURE (-1) -#define EXIT_KILLED (-101) -#define EXIT_BAD_SYSCALL (-102) +#define EXIT_SUCCESS (0) +#define EXIT_FAILURE (-1) +#define EXIT_KILLED (-101) +#define EXIT_BAD_SYSCALL (-102) /* ** Process priority values */ enum priority_e { - PRIO_HIGH, - PRIO_STD, - PRIO_LOW, - PRIO_DEFERRED + PRIO_HIGH, PRIO_STD, PRIO_LOW, PRIO_DEFERRED // sentinel - , - N_PRIOS + , N_PRIOS }; // halves of various data sizes -#define UI16_UPPER 0xff00 -#define UI16_LOWER 0x00ff +#define UI16_UPPER 0xff00 +#define UI16_LOWER 0x00ff -#define UI32_UPPER 0xffff0000 -#define UI32_LOWER 0x0000ffff +#define UI32_UPPER 0xffff0000 +#define UI32_LOWER 0x0000ffff -#define UI64_UPPER 0xffffffff00000000LL -#define UI64_LOWER 0x00000000ffffffffLL +#define UI64_UPPER 0xffffffff00000000LL +#define UI64_LOWER 0x00000000ffffffffLL // Simple conversion pseudo-functions usable by everyone // convert seconds to ms -#define SEC_TO_MS(n) ((n) * 1000) +#define SEC_TO_MS(n) ((n) * 1000) -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ /* ** Level-specific definitions @@ -125,6 +124,6 @@ enum priority_e { #include #else #include -#endif /* KERNEL_SRC */ +#endif /* KERNEL_SRC */ #endif diff --git a/kernel/old/include/elf.h b/kernel/old/include/elf.h new file mode 100644 index 0000000..a43e5c3 --- /dev/null +++ b/kernel/old/include/elf.h @@ -0,0 +1,235 @@ +/** +** @file elf.h +** +** @author Warren R. Carithers +** +** @brief ELF format declarations +*/ + +#ifndef ELF_H_ +#define ELF_H_ + +#include + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +// ELF data types (TIS ELF Spec v1.2, May 1995 +typedef uint32_t e32_a; // 32-bit unsigned address +typedef uint16_t e32_h; // 16-bit unsigned "medium" integer +typedef uint32_t e32_o; // 32-bit unsigned offset +typedef int32_t e32_sw; // 32-bit signed "large" integer +typedef uint32_t e32_w; // 32-bit unsigned "large" integer +typedef uint8_t e32_si; // 8-bit unsigned "small" integer + +// ELF magic number - first four bytes +#define ELF_MAGIC 0x464C457FU // "\x7FELF" in little-endian order +#define EI_NIDENT 16 + +union elfident_u { + uint8_t bytes[EI_NIDENT]; // array of 16 bytes + struct { + uint32_t magic; // magic number + uint8_t class; // file class + uint8_t data; // data encoding + uint8_t version; // file version + uint8_t osabi; // OS ABI identification + uint8_t abivers; // ABI version + uint8_t pad[7]; // padding to 16 bytes + } f; +}; + +// indices for byte fields in the ident array +#define EI_MAGIC 0 +# define EI_MAG0 EI_MAGIC +# define EI_MAG1 1 +# define EI_MAG2 2 +# define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_ABIVERSION 8 + +// ELF classes +#define ELF_CLASS_NONE 0 +#define ELF_CLASS_32 1 // 32-bit objects +#define ELF_CLASS_64 2 // 64-bit objects + +// ELF data encoding +#define ELF_DATA_NONE 0 // invalid data encoding +#define ELF_DATA_2LSB 1 // two's complement little-endian +#define ELF_DATA_2MSB 2 // two's complement big-endian + +// ELF versions +#define ELF_VERSION__NONE 0 // invalid version +# define EV_NONE ELF_VERSION_NONE +#define ELF_VERSION__CURRENT 1 // current version +# define EV_CURRENT ELF_VERSION_CURRENT + +// ELF header +// +// field names are from the TIS ELF Spec v1.2, May 1995 +typedef struct elfhdr_s { + union elfident_u e_ident; // file identification + e32_h e_type; // file type + e32_h e_machine; // required architecture + e32_w e_version; // object file version + e32_a e_entry; // entry point (VA) + e32_o e_phoff; // offset to program header table (PHT) + e32_o e_shoff; // offset to section header table (SHT) + e32_w e_flags; // processor-specific flags + e32_h e_ehsize; // ELF header size (bytes) + e32_h e_phentsize; // size of one PHT entry (bytes) + e32_h e_phnum; // number of PHT entries + e32_h e_shentsize; // size of one SHT entry (bytes) + e32_h e_shnum; // number of SHT entries + e32_h e_shstrndx; // SHT index of the sect. name string table +} elfhdr_t; + +#define SZ_ELFHDR sizeof(elfhdr_t) + +// field values +// e_type +#define ET_NONE 0 // no file type +#define ET_REL 1 // relocatable file +#define ET_EXEC 2 // executable file +#define ET_DYN 3 // shared object file +#define ET_CORE 4 // core file +#define ET_LO_OS 0xfe00 // processor-specific +#define ET_HI_OS 0xfeff // processor-specific +#define ET_LO_CP 0xff00 // processor-specific +#define ET_HI_CP 0xffff // processor-specific + +// e_machine +#define EM_NONE 0x00 // no machine type +#define EM_M32 0x01 // AT&T WE 32100 +#define EM_SPARC 0x02 // SUN SPARC +#define EM_386 0x03 // Intel Architecture +#define EM_68K 0x04 // Motorola 68000 +#define EM_88K 0x05 // Motorola 88000 +#define EM_IAMCU 0x06 // Intel MCU +#define EM_860 0x07 // Intel 80860 +#define EM_MIPS 0x08 // MIPS RS3000 Big-Endian +#define EM_S370 0x09 // IBM System/370 +#define EM_MIPS_RS3_LE 0x0a // MIPS RS3000 Big-Endian +#define EM_SPARC32PLLUS 0x12 // Sun "v8plus" +#define EM_PPC 0x14 // IBM PowerPC +#define EM_PPC64 0x15 // IBM PowerPC 64-bit +#define EM_S390 0x16 // IBM System/390 +#define EM_ARM 0x28 // ARM up to V7/AArch32 +#define EM_SPARCV9 0x2b // SPARC V9 64-bit +#define EM_IA_64 0x32 // Intel Itanium (Merced) +#define EM_MIPS_X 0x32 // Stanford MIPS-X +#define EM_X86_64 0x3E // AMD x86-64 (Intel64) +#define EM_PDP11 0x40 // DEC PDP-11 +#define EM_VAX 0x4b // DEC VAX +#define EM_AARCH64 0xb7 // ARM AArch64 +#define EM_Z80 0xec // Zilog Z-80 +#define EM_AMDGPU 0xf0 // AMD GPU +#define EM_RISCV 0xf3 // RISC-V +#define EM_BPF 0xf7 // Berkeley Packet Filter + +// ELF section header +// +// field names are from the TIS ELF Spec v1.2, May 1995 +typedef struct shdr_s { + e32_w sh_name; // section name (index into string table) + e32_w sh_type; // section contents/semantics + e32_w sh_flags; // attribute flag bits + e32_a sh_addr; // 0, or load point of this section in memory + e32_o sh_offset; // byte offset within the file + e32_w sh_size; // section size in bytes + e32_w sh_link; // section header index table link + e32_w sh_info; // "extra information" + e32_w sh_addralign; // required alignment + e32_w sh_entsize; // 0, or size of each entry in the section +} elfsecthdr_t; + +#define SZ_ELFSECTHDR sizeof(elfsecthdr_t) + +// sh_name +#define SHN_UNDEF 0 + +// sh_type +#define SHT_NULL 0x00 +#define SHT_PROGBITS 0x01 +#define SHT_SYMTAB 0x02 +#define SHT_STRTAB 0x03 +#define SHT_RELA 0x04 +#define SHT_HASH 0x05 +#define SHT_DYNAMIC 0x06 +#define SHT_NOTE 0x07 +#define SHT_NOBITS 0x08 +#define SHT_REL 0x09 +#define SHT_SHLIB 0x0a +#define SHT_DYNSYM 0x0b +#define SHT_LO_CP 0x70000000 +#define SHT_HI_CP 0x7fffffff +#define SHT_LO_US 0x80000000 +#define SHT_HI_US 0x8fffffff + +// sh_flags +#define SHF_WRITE 0x001 +#define SHF_ALLOC 0x002 +#define SHF_EXECINSTR 0x004 +#define SHF_MERGE 0x010 +#define SHF_STRINGS 0x020 +#define SHF_INFO_LINK 0x040 +#define SHF_LINK_ORDER 0x080 +#define SHF_OS_NONCON 0x100 +#define SHF_GROUP 0x200 +#define SHF_TLS 0x400 +#define SHF_MASKOS 0x0ff00000 +#define SHF_MASKPROC 0xf0000000 + +// ELF program header +// +// field names are from the TIS ELF Spec v1.2, May 1995 +typedef struct phdr_s { + e32_w p_type; // type of segment + e32_o p_offset; // byte offset in file + e32_a p_va; // load point in memory (virtual address) + e32_a p_pa; // load point in memory (physical address) + e32_w p_filesz; // number of bytes in this file + e32_w p_memsz; // number of bytes in memory + e32_w p_flags; // attribute flag bits + e32_w p_align; // required alignment +} elfproghdr_t; + +#define SZ_ELFPROGHDR sizeof(elfproghdr_t) + +// p_type +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_TLS 7 +#define PT_LO_OS 0x70000000 +#define PT_HI_OS 0x7fffffff +#define PT_LO_CP 0x70000000 +#define PT_HI_CP 0x7fffffff + +// p_flags +#define PF_E 0x1 +#define PF_W 0x2 +#define PF_R 0x4 +#define PF_MASKPROC 0xf0000000 + +/* +** Globals +*/ + +/* +** Prototypes +*/ + +#endif /* !ASM_SRC */ + +#endif diff --git a/kernel/old/include/kdefs.h b/kernel/old/include/kdefs.h index d26fa3d..794516b 100644 --- a/kernel/old/include/kdefs.h +++ b/kernel/old/include/kdefs.h @@ -17,58 +17,53 @@ */ // page sizes -#define SZ_PAGE NUM_4KB -#define SZ_BIGPAGE NUM_4MB +#define SZ_PAGE NUM_4KB +#define SZ_BIGPAGE NUM_4MB // kernel stack size (bytes) -#define N_KSTKPAGES 1 -#define SZ_KSTACK (N_KSTKPAGES * SZ_PAGE) +#define N_KSTKPAGES 1 +#define SZ_KSTACK (N_KSTKPAGES * SZ_PAGE) // user stack size -#define N_USTKPAGES 2 -#define SZ_USTACK (N_USTKPAGES * SZ_PAGE) +#define N_USTKPAGES 2 +#define SZ_USTACK (N_USTKPAGES * SZ_PAGE) // declarations for modulus checking of (e.g.) sizes and addresses -#define LOW_9_BITS 0x00000fff -#define LOW_22_BITS 0x003fffff -#define HIGH_20_BITS 0xfffff000 -#define HIGH_10_BITS 0xffc00000 - -#define MOD4_BITS 0x00000003 -#define MOD4_MASK 0xfffffffc -#define MOD4_INC 0x00000004 -#define MOD4_SHIFT 2 - -#define MOD16_BITS 0x0000000f -#define MOD16_MASK 0xfffffff0 -#define MOD16_INC 0x00000010 -#define MOD16_SHIFT 4 - -#define MOD1K_BITS 0x000003ff -#define MOD1K_MASK 0xfffffc00 -#define MOD1K_INC 0x00000400 -#define MOD1K_SHIFT 10 - -#define MOD4K_BITS 0x00000fff -#define MOD4K_MASK 0xfffff000 -#define MOD4K_INC 0x00001000 -#define MOD4K_SHIFT 12 - -#define MOD1M_BITS 0x000fffff -#define MOD1M_MASK 0xfff00000 -#define MOD1M_INC 0x00100000 -#define MOD1M_SHIFT 20 - -#define MOD4M_BITS 0x003fffff -#define MOD4M_MASK 0xffc00000 -#define MOD4M_INC 0x00400000 -#define MOD4M_SHIFT 22 - -#define MOD1G_BITS 0x3fffffff -#define MOD1G_MASK 0xc0000000 -#define MOD1G_INC 0x40000000 -#define MOD1G_SHIFT 30 +#define MOD4_BITS 0x00000003 +#define MOD4_MASK 0xfffffffc +#define MOD4_INC 0x00000004 +#define MOD4_SHIFT 2 + +#define MOD16_BITS 0x0000000f +#define MOD16_MASK 0xfffffff0 +#define MOD16_INC 0x00000010 +#define MOD16_SHIFT 4 + +#define MOD1K_BITS 0x000003ff +#define MOD1K_MASK 0xfffffc00 +#define MOD1K_INC 0x00000400 +#define MOD1K_SHIFT 10 + +#define MOD4K_BITS 0x00000fff +#define MOD4K_MASK 0xfffff000 +#define MOD4K_INC 0x00001000 +#define MOD4K_SHIFT 12 + +#define MOD1M_BITS 0x000fffff +#define MOD1M_MASK 0xfff00000 +#define MOD1M_INC 0x00100000 +#define MOD1M_SHIFT 20 + +#define MOD4M_BITS 0x003fffff +#define MOD4M_MASK 0xffc00000 +#define MOD4M_INC 0x00400000 +#define MOD4M_SHIFT 22 + +#define MOD1G_BITS 0x3fffffff +#define MOD1G_MASK 0xc0000000 +#define MOD1G_INC 0x40000000 +#define MOD1G_SHIFT 30 #ifndef ASM_SRC @@ -77,26 +72,26 @@ */ // unit conversion macros -#define B_TO_KB(x) (((uint_t)(x)) >> 10) -#define B_TO_MB(x) (((uint_t)(x)) >> 20) -#define B_TO_GB(x) (((uint_t)(x)) >> 30) +#define B_TO_KB(x) (((uint_t)(x))>>10) +#define B_TO_MB(x) (((uint_t)(x))>>20) +#define B_TO_GB(x) (((uint_t)(x))>>30) -#define KB_TO_B(x) (((uint_t)(x)) << 10) -#define KB_TO_MB(x) (((uint_t)(x)) >> 10) -#define KB_TO_GB(x) (((uint_t)(x)) >> 20) +#define KB_TO_B(x) (((uint_t)(x))<<10) +#define KB_TO_MB(x) (((uint_t)(x))>>10) +#define KB_TO_GB(x) (((uint_t)(x))>>20) -#define MB_TO_B(x) (((uint_t)(x)) << 20) -#define MB_TO_KB(x) (((uint_t)(x)) << 10) -#define MB_TO_GB(x) (((uint_t)(x)) >> 10) +#define MB_TO_B(x) (((uint_t)(x))<<20) +#define MB_TO_KB(x) (((uint_t)(x))<<10) +#define MB_TO_GB(x) (((uint_t)(x))>>10) -#define GB_TO_B(x) (((uint_t)(x)) << 30) -#define GB_TO_KB(x) (((uint_t)(x)) << 20) -#define GB_TO_MB(x) (((uint_t)(x)) << 10) +#define GB_TO_B(x) (((uint_t)(x))<<30) +#define GB_TO_KB(x) (((uint_t)(x))<<20) +#define GB_TO_MB(x) (((uint_t)(x))<<10) // potetially useful compiler attributes #define ATTR_ALIGNED(x) __attribute__((__aligned__(x))) -#define ATTR_PACKED __attribute__((__packed__)) -#define ATTR_UNUSED __attribute__((__unused__)) +#define ATTR_PACKED __attribute__((__packed__)) +#define ATTR_UNUSED __attribute__((__unused__)) /* ** Utility macros @@ -107,18 +102,18 @@ // // these are usable for clearing single-valued data items (e.g., // a PCB, etc.) -#define CLEAR(v) memclr(&v, sizeof(v)) -#define CLEAR_PTR(p) memclr(p, sizeof(*p)) +#define CLEAR(v) memclr( &v, sizeof(v) ) +#define CLEAR_PTR(p) memclr( p, sizeof(*p) ) // // macros for access registers and system call arguments // // REG(pcb,x) -- access a specific register in a process context -#define REG(pcb, x) ((pcb)->context->x) +#define REG(pcb,x) ((pcb)->context->x) // RET(pcb) -- access return value register in a process context -#define RET(pcb) ((pcb)->context->eax) +#define RET(pcb) ((pcb)->context->eax) // ARG(pcb,n) -- access argument #n from the indicated process // @@ -129,7 +124,7 @@ // // ASSUMES THE STANDARD 32-BIT ABI, WITH PARAMETERS PUSHED ONTO THE // STACK. IF THE PARAMETER PASSING MECHANISM CHANGES, SO MUST THIS! -#define ARG(pcb, n) (((uint32_t *)(((pcb)->context) + 1))[(n)]) +#define ARG(pcb,n) ( ( (uint32_t *) (((pcb)->context) + 1) ) [(n)] ) /* ** Types @@ -152,6 +147,6 @@ extern uint8_t kstack[SZ_KSTACK]; ** Prototypes */ -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/klib.h b/kernel/old/include/klib.h index 60f59da..c1d270c 100644 --- a/kernel/old/include/klib.h +++ b/kernel/old/include/klib.h @@ -24,7 +24,7 @@ ** ** @param ch The character to be printed */ -void put_char_or_code(int ch); +void put_char_or_code( int ch ); /** ** Name: backtrace @@ -35,7 +35,7 @@ void put_char_or_code(int ch); ** @param ebp Initial EBP to use ** @param args Number of function argument values to print */ -void backtrace(uint32_t *ebp, uint_t args); +void backtrace( uint32_t *ebp, uint_t args ); /** ** Name: kpanic @@ -50,8 +50,8 @@ void backtrace(uint32_t *ebp, uint_t args); ** @param msg[in] String containing a relevant message to be printed, ** or NULL */ -void kpanic(const char *msg); +void kpanic( const char *msg ); -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/kmem.h b/kernel/old/include/kmem.h index 631f7ab..5a98765 100644 --- a/kernel/old/include/kmem.h +++ b/kernel/old/include/kmem.h @@ -28,8 +28,8 @@ // Slab and slice sizes, in bytes -#define SZ_SLAB SZ_PAGE -#define SZ_SLICE (SZ_SLAB >> 2) +#define SZ_SLAB SZ_PAGE +#define SZ_SLICE (SZ_SLAB >> 2) // memory limits // @@ -37,8 +37,8 @@ // module will manage // // we won't map any memory below 1MB or above 1GB -#define KM_LOW_CUTOFF NUM_1MB -#define KM_HIGH_CUTOFF NUM_1GB +#define KM_LOW_CUTOFF NUM_1MB +#define KM_HIGH_CUTOFF NUM_1GB #ifndef ASM_SRC @@ -68,7 +68,7 @@ ** Must be called before any other init routine that uses ** dynamic storage is called. */ -void km_init(void); +void km_init( void ); /** ** Name: km_dump @@ -81,7 +81,7 @@ void km_init(void); ** @param addrs Also dump page addresses ** @param both Also dump slice addresses */ -void km_dump(bool_t addrs, bool_t both); +void km_dump( bool_t addrs, bool_t both ); /* ** Functions that manipulate free memory blocks. @@ -95,7 +95,7 @@ void km_dump(bool_t addrs, bool_t both); ** @return a pointer to the beginning of the allocated page, ** or NULL if no memory is available */ -void *km_page_alloc(void); +void *km_page_alloc( void ); /** ** Name: km_page_free @@ -108,7 +108,7 @@ void *km_page_alloc(void); ** ** @param[in] block Pointer to the page to be returned to the free list */ -void km_page_free(void *block); +void km_page_free( void *block ); /** ** Name: km_slice_alloc @@ -119,7 +119,7 @@ void km_page_free(void *block); ** ** @return a pointer to the allocated slice */ -void *km_slice_alloc(void); +void *km_slice_alloc( void ); /** ** Name: km_slice_free @@ -131,7 +131,7 @@ void *km_slice_alloc(void); ** ** @param[in] block Pointer to the slice (1/4 page) to be freed */ -void km_slice_free(void *block); +void km_slice_free( void *block ); #endif /* !ASM_SRC */ diff --git a/kernel/old/include/lib.h b/kernel/old/include/lib.h new file mode 100644 index 0000000..bde0554 --- /dev/null +++ b/kernel/old/include/lib.h @@ -0,0 +1,314 @@ +/** +** @file lib.h +** +** @author Numerous CSCI-452 classes +** +** @brief C declarations of common library functions +** +** These are callable from either kernel or user code. Care should be taken +** that user code is linked against these separately from kernel code, to +** ensure separation of the address spaces. +*/ + +#ifndef LIB_H_ +#define LIB_H_ + +#ifndef ASM_SRC + +#include + +/* +********************************************** +** MEMORY MANIPULATION FUNCTIONS +********************************************** +*/ + +/** +** blkmov(dst,src,len) +** +** Copy a word-aligned block from src to dst. Deals with overlapping +** buffers. +** +** If the buffer addresses aren't word-aligned or the length is not a +** multiple of four, calls memmove(). +** +** @param dst Destination buffer +** @param src Source buffer +** @param len Buffer size (in bytes) +*/ +void blkmov( void *dst, const void *src, register uint32_t len ); + +/** +** memset(buf,len,value) +** +** initialize all bytes of a block of memory to a specific value +** +** @param buf The buffer to initialize +** @param len Buffer size (in bytes) +** @param value Initialization value +*/ +void memset( void *buf, register uint32_t len, register uint32_t value ); + +/** +** memclr(buf,len) +** +** Initialize all bytes of a block of memory to zero +** +** @param buf The buffer to initialize +** @param len Buffer size (in bytes) +*/ +void memclr( void *buf, register uint32_t len ); + +/** +** memcpy(dst,src,len) +** +** Copy a block from one place to another +** +** May not correctly deal with overlapping buffers +** +** @param dst Destination buffer +** @param src Source buffer +** @param len Buffer size (in bytes) +*/ +void memcpy( void *dst, register const void *src, register uint32_t len ); + +/** +** memmove(dst,src,len) +** +** Copy a block from one place to another. Deals with overlapping +** buffers +** +** @param dst Destination buffer +** @param src Source buffer +** @param len Buffer size (in bytes) +*/ +void memmove( void *dst, register const void *src, register uint32_t len ); + +/* +********************************************** +** STRING MANIPULATION FUNCTIONS +********************************************** +*/ + +/** +** str2int(str,base) - convert a string to a number in the specified base +** +** @param str The string to examine +** @param base The radix to use in the conversion +** +** @return The converted integer +*/ +int str2int( register const char *str, register int base ); + +/** +** strlen(str) - return length of a NUL-terminated string +** +** @param str The string to examine +** +** @return The length of the string, or 0 +*/ +uint32_t strlen( register const char *str ); + +/** +** strcmp(s1,s2) - compare two NUL-terminated strings +** +** @param s1 The first source string +** @param s2 The second source string +** +** @return negative if s1 < s2, zero if equal, and positive if s1 > s2 +*/ +int strcmp( register const char *s1, register const char *s2 ); + +/** +** strcpy(dst,src) - copy a NUL-terminated string +** +** @param dst The destination buffer +** @param src The source buffer +** +** @return The dst parameter +** +** NOTE: assumes dst is large enough to hold the copied string +*/ +char *strcpy( register char *dst, register const char *src ); + +/** +** strcat(dst,src) - append one string to another +** +** @param dst The destination buffer +** @param src The source buffer +** +** @return The dst parameter +** +** NOTE: assumes dst is large enough to hold the resulting string +*/ +char *strcat( register char *dst, register const char *src ); + +/** +** pad(dst,extra,padchar) - generate a padding string +** +** @param dst Pointer to where the padding should begin +** @param extra How many padding bytes to add +** @param padchar What character to pad with +** +** @return Pointer to the first byte after the padding +** +** NOTE: does NOT NUL-terminate the buffer +*/ +char *pad( char *dst, int extra, int padchar ); + +/** +** padstr(dst,str,len,width,leftadjust,padchar - add padding characters +** to a string +** +** @param dst The destination buffer +** @param str The string to be padded +** @param len The string length, or -1 +** @param width The desired final length of the string +** @param leftadjust Should the string be left-justified? +** @param padchar What character to pad with +** +** @return Pointer to the first byte after the padded string +** +** NOTE: does NOT NUL-terminate the buffer +*/ +char *padstr( char *dst, char *str, int len, int width, + int leftadjust, int padchar ); + +/** +** sprint(dst,fmt,...) - formatted output into a string buffer +** +** @param dst The string buffer +** @param fmt Format string +** +** The format string parameter is followed by zero or more additional +** parameters which are interpreted according to the format string. +** +** NOTE: assumes the buffer is large enough to hold the result string +** +** NOTE: relies heavily on the x86 parameter passing convention +** (parameters are pushed onto the stack in reverse order as +** 32-bit values). +*/ +void sprint( char *dst, char *fmt, ... ); + +/* +********************************************** +** CONVERSION FUNCTIONS +********************************************** +*/ + +/** +** cvtuns0(buf,value) - local support routine for cvtuns() +** +** Convert a 32-bit unsigned value into a NUL-terminated character string +** +** @param buf Result buffer +** @param value Value to be converted +** +** @return Pointer to the first unused byte in the buffer +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +char *cvtuns0( char *buf, uint32_t value ); + +/** +** cvtuns(buf,value) +** +** Convert a 32-bit unsigned value into a NUL-terminated character string +** +** @param buf Result buffer +** @param value Value to be converted +** +** @return Length of the resulting buffer +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvtuns( char *buf, uint32_t value ); + +/** +** cvtdec0(buf,value) - local support routine for cvtdec() +** +** convert a 32-bit unsigned integer into a NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +char *cvtdec0( char *buf, int value ); + +/** +** cvtdec(buf,value) +** +** convert a 32-bit signed value into a NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvtdec( char *buf, int32_t value ); + +/** +** cvthex(buf,value) +** +** convert a 32-bit unsigned value into a mininal-length (up to +** 8-character) NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvthex( char *buf, uint32_t value ); + +/** +** cvtoct(buf,value) +** +** convert a 32-bit unsigned value into a mininal-length (up to +** 11-character) NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvtoct( char *buf, uint32_t value ); + +/** +** bound(min,value,max) +** +** This function confines an argument within specified bounds. +** +** @param min Lower bound +** @param value Value to be constrained +** @param max Upper bound +** +** @return The constrained value +*/ +uint32_t bound( uint32_t min, uint32_t value, uint32_t max ); + +#endif /* !ASM_SRC */ + +/* +** Finally, pull in the level-specific library headers +*/ +#ifdef KERNEL_SRC +#include +#else +#include +#endif /* KERNEL_SRC */ + +#endif diff --git a/kernel/old/include/list.h b/kernel/old/include/list.h index 0be11e9..28c2377 100644 --- a/kernel/old/include/list.h +++ b/kernel/old/include/list.h @@ -35,7 +35,7 @@ // The list structure typedef struct list_s { - struct list_s *next; // link to the successor + struct list_s *next; // link to the successor } list_t; /* @@ -50,7 +50,7 @@ typedef struct list_s { ** @param[in,out] list The address of a list_t variable ** @param[in] data The data to prepend to the list */ -void list_add(list_t *list, void *data); +void list_add( list_t *list, void *data ); /** ** Name: list_remove @@ -61,7 +61,7 @@ void list_add(list_t *list, void *data); ** ** @return a pointer to the removed data, or NULL if the list was empty */ -void *list_remove(list_t *list); +void *list_remove( list_t *list ); #endif /* !ASM_SRC */ diff --git a/kernel/old/include/offsets.h b/kernel/old/include/offsets.h deleted file mode 100644 index bf19776..0000000 --- a/kernel/old/include/offsets.h +++ /dev/null @@ -1,83 +0,0 @@ -/** -** @file offsets.h -** -** GENERATED AUTOMATICALLY - DO NOT EDIT -** -** This header file contains C Preprocessor macros which expand -** into the byte offsets needed to reach fields within structs -** used in the baseline system. Should those struct declarations -** change, the Offsets program should be modified (if needed), -** recompiled, and re-run to recreate this file. -*/ - -#ifndef OFFSETS_H_ -#define OFFSETS_H_ - -// Sizes of basic types - -#define SZ_char 1 -#define SZ_short 2 -#define SZ_int 4 -#define SZ_long 4 -#define SZ_long_long 8 -#define SZ_pointer 4 - -// Sizes of our types - -#define SZ_int8_t 1 -#define SZ_uint8_t 1 -#define SZ_int16_t 2 -#define SZ_uint16_t 2 -#define SZ_int32_t 4 -#define SZ_uint32_t 4 -#define SZ_int64_t 8 -#define SZ_uint64_t 8 -#define SZ_bool_t 1 - -// context_t structure - -#define SZ_CTX 72 - -#define CTX_ss 0 -#define CTX_gs 4 -#define CTX_fs 8 -#define CTX_es 12 -#define CTX_ds 16 -#define CTX_edi 20 -#define CTX_esi 24 -#define CTX_ebp 28 -#define CTX_esp 32 -#define CTX_ebx 36 -#define CTX_edx 40 -#define CTX_ecx 44 -#define CTX_eax 48 -#define CTX_vector 52 -#define CTX_code 56 -#define CTX_eip 60 -#define CTX_cs 64 -#define CTX_eflags 68 - -// section_t structure - -#define SZ_SCT 8 - -#define SCT_length 0 -#define SCT_addr 4 - -// pcb_t structure - -#define SZ_PCB 72 - -#define PCB_context 0 -#define PCB_pdir 4 -#define PCB_sects 8 -#define PCB_next 40 -#define PCB_parent 44 -#define PCB_wakeup 48 -#define PCB_exit_status 52 -#define PCB_pid 56 -#define PCB_state 60 -#define PCB_priority 64 -#define PCB_ticks 68 - -#endif diff --git a/kernel/old/include/params.h b/kernel/old/include/params.h index 7a41e02..52eb81d 100644 --- a/kernel/old/include/params.h +++ b/kernel/old/include/params.h @@ -20,14 +20,12 @@ // Upper bound on the number of simultaneous user-level // processes in the system (completely arbitrary) -#define N_PROCS 25 -// Limit on the number of entries in argv[], INCLUDING -// the trailing NULL pointer (also completely arbitrary) -#define N_ARGS 10 +#define N_PROCS 25 // Clock frequency (Hz) -#define CLOCK_FREQ 1000 -#define TICKS_PER_MS 1 + +#define CLOCK_FREQ 1000 +#define TICKS_PER_MS 1 #endif diff --git a/kernel/old/include/procs.h b/kernel/old/include/procs.h index bc5b705..9db4ac8 100644 --- a/kernel/old/include/procs.h +++ b/kernel/old/include/procs.h @@ -30,28 +30,22 @@ */ enum state_e { // pre-viable - STATE_UNUSED = 0, - STATE_NEW, + STATE_UNUSED = 0, STATE_NEW, // runnable - STATE_READY, - STATE_RUNNING, + STATE_READY, STATE_RUNNING, // runnable, but waiting for some event - STATE_SLEEPING, - STATE_BLOCKED, - STATE_WAITING, + STATE_SLEEPING, STATE_BLOCKED, STATE_WAITING, // no longer runnable - STATE_KILLED, - STATE_ZOMBIE + STATE_KILLED, STATE_ZOMBIE // sentinel value - , - N_STATES + , N_STATES }; // these may be handy for checking general conditions of processes // they depend on the order of the state names in the enum! -#define FIRST_VIABLE STATE_READY -#define FIRST_BLOCKED STATE_SLEEPING -#define LAST_VIABLE STATE_WAITING +#define FIRST_VIABLE STATE_READY +#define FIRST_BLOCKED STATE_SLEEPING +#define LAST_VIABLE STATE_WAITING /* ** Process priorities are defined in @@ -60,13 +54,17 @@ enum state_e { /* ** Quantum lengths - values are number of clock ticks */ -enum quantum_e { QUANTUM_SHORT = 1, QUANTUM_STANDARD = 3, QUANTUM_LONG = 5 }; +enum quantum_e { + QUANTUM_SHORT = 1, + QUANTUM_STANDARD = 3, + QUANTUM_LONG = 5 +}; /* ** PID-related definitions */ -#define PID_INIT 1 -#define FIRST_USER_PID 2 +#define PID_INIT 1 +#define FIRST_USER_PID 2 /* ** Process context structure @@ -80,7 +78,7 @@ enum quantum_e { QUANTUM_SHORT = 1, QUANTUM_STANDARD = 3, QUANTUM_LONG = 5 }; */ typedef struct context_s { - uint32_t ss; // pushed by isr_save + uint32_t ss; // pushed by isr_save uint32_t gs; uint32_t fs; uint32_t es; @@ -94,34 +92,34 @@ typedef struct context_s { uint32_t ecx; uint32_t eax; uint32_t vector; - uint32_t code; // pushed by isr_save or the hardware - uint32_t eip; // pushed by the hardware + uint32_t code; // pushed by isr_save or the hardware + uint32_t eip; // pushed by the hardware uint32_t cs; uint32_t eflags; } context_t; -#define SZ_CONTEXT sizeof(context_t) +#define SZ_CONTEXT sizeof(context_t) /* ** program section information for user processes */ typedef struct section_s { - uint_t length; // length, in some units - uint_t addr; // location, in some units + uint_t length; // length, in some units + uint_t addr; // location, in some units } section_t; // note: these correspond to the PT_LOAD sections found in // an ELF file, not necessarily to text/data/bss -#define SECT_L1 0 -#define SECT_L2 1 -#define SECT_L3 2 -#define SECT_STACK 3 +#define SECT_L1 0 +#define SECT_L2 1 +#define SECT_L3 2 +#define SECT_STACK 3 // total number of section table entries in our PCB -#define N_SECTS 4 +#define N_SECTS 4 // number of those that can be loaded from an ELF module -#define N_LOADABLE 3 +#define N_LOADABLE 3 /* ** The process control block @@ -134,31 +132,32 @@ typedef struct section_s { */ typedef struct pcb_s { + // four-byte fields // start with these four bytes, for easy access in assembly - context_t *context; // pointer to context save area on stack + context_t *context; // pointer to context save area on stack // VM information - pde_t *pdir; // page directory for this process - section_t sects[N_SECTS]; // per-section memory information + pde_t *pdir; // page directory for this process + section_t sects[N_SECTS]; // per-section memory information // queue linkage - struct pcb_s *next; // next PCB in queue + struct pcb_s *next; // next PCB in queue // process state information - struct pcb_s *parent; // pointer to PCB of our parent process - uint32_t wakeup; // wakeup time, for sleeping processes - int32_t exit_status; // termination status, for parent's use + struct pcb_s *parent; // pointer to PCB of our parent process + uint32_t wakeup; // wakeup time, for sleeping processes + int32_t exit_status; // termination status, for parent's use // these things may not need to be four bytes - uint_t pid; // PID of this process - enum state_e state; // process' current state - enum priority_e priority; // process priority level - uint_t ticks; // remaining ticks in this time slice + uint_t pid; // PID of this process + enum state_e state; // process' current state + enum priority_e priority; // process priority level + uint_t ticks; // remaining ticks in this time slice } pcb_t; -#define SZ_PCB sizeof(pcb_t) +#define SZ_PCB sizeof(pcb_t) /* ** PCB queue structure (opaque to the rest of the kernel) @@ -169,16 +168,12 @@ typedef struct pcb_queue_s *pcb_queue_t; ** Queue ordering methods */ enum pcb_queue_order_e { - O_FIFO, - O_PRIO, - O_PID, - O_WAKEUP + O_FIFO, O_PRIO, O_PID, O_WAKEUP // sentinel - , - N_ORDERINGS + , N_ORDERINGS }; -#define O_FIRST_STYLE O_FIFO -#define O_LAST_STYLE O_WAKEUP +#define O_FIRST_STYLE O_FIFO +#define O_LAST_STYLE O_WAKEUP /* ** Globals @@ -205,13 +200,13 @@ extern uint_t next_pid; extern pcb_t *init_pcb; // table of state name strings -extern const char state_str[N_STATES][4]; +extern const char *state_str[N_STATES]; // table of priority name strings -extern const char prio_str[N_PRIOS][5]; +extern const char *prio_str[N_PRIOS]; // table of queue ordering name strings -extern const char ord_str[N_ORDERINGS][5]; +extern const char *ord_str[N_ORDERINGS]; /* ** Prototypes @@ -222,7 +217,7 @@ extern const char ord_str[N_ORDERINGS][5]; ** ** Initialization for the Process module. */ -void pcb_init(void); +void pcb_init( void ); /** ** Name: pcb_alloc @@ -233,7 +228,7 @@ void pcb_init(void); ** ** @return status of the allocation attempt */ -int pcb_alloc(pcb_t **pcb); +int pcb_alloc( pcb_t **pcb ); /** ** Name: pcb_free @@ -242,7 +237,7 @@ int pcb_alloc(pcb_t **pcb); ** ** @param pcb Pointer to the PCB to be deallocated. */ -void pcb_free(pcb_t *pcb); +void pcb_free( pcb_t *pcb ); /** ** Name: pcb_zombify @@ -253,7 +248,7 @@ void pcb_free(pcb_t *pcb); ** ** @param pcb Pointer to the newly-undead PCB */ -void pcb_zombify(register pcb_t *victim); +void pcb_zombify( register pcb_t *victim ); /** ** Name: pcb_cleanup @@ -262,7 +257,7 @@ void pcb_zombify(register pcb_t *victim); ** ** @param pcb The PCB to reclaim */ -void pcb_cleanup(pcb_t *pcb); +void pcb_cleanup( pcb_t *pcb ); /** ** Name: pcb_find_pid @@ -273,7 +268,7 @@ void pcb_cleanup(pcb_t *pcb); ** ** @return Pointer to the PCB, or NULL */ -pcb_t *pcb_find_pid(uint_t pid); +pcb_t *pcb_find_pid( uint_t pid ); /** ** Name: pcb_find_ppid @@ -284,7 +279,7 @@ pcb_t *pcb_find_pid(uint_t pid); ** ** @return Pointer to the PCB, or NULL */ -pcb_t *pcb_find_ppid(uint_t pid); +pcb_t *pcb_find_ppid( uint_t pid ); /** ** Name: pcb_queue_reset @@ -296,7 +291,7 @@ pcb_t *pcb_find_ppid(uint_t pid); ** ** @return status of the init request */ -int pcb_queue_reset(pcb_queue_t queue, enum pcb_queue_order_e style); +int pcb_queue_reset( pcb_queue_t queue, enum pcb_queue_order_e style ); /** ** Name: pcb_queue_empty @@ -308,7 +303,7 @@ int pcb_queue_reset(pcb_queue_t queue, enum pcb_queue_order_e style); ** ** @return true if the queue is empty, else false */ -bool_t pcb_queue_empty(pcb_queue_t queue); +bool_t pcb_queue_empty( pcb_queue_t queue ); /** ** Name: pcb_queue_length @@ -319,7 +314,7 @@ bool_t pcb_queue_empty(pcb_queue_t queue); ** ** @return the count (0 if the queue is empty) */ -uint_t pcb_queue_length(const pcb_queue_t queue); +uint_t pcb_queue_length( const pcb_queue_t queue ); /** ** Name: pcb_queue_insert @@ -331,7 +326,7 @@ uint_t pcb_queue_length(const pcb_queue_t queue); ** ** @return status of the insertion request */ -int pcb_queue_insert(pcb_queue_t queue, pcb_t *pcb); +int pcb_queue_insert( pcb_queue_t queue, pcb_t *pcb ); /** ** Name: pcb_queue_peek @@ -343,7 +338,7 @@ int pcb_queue_insert(pcb_queue_t queue, pcb_t *pcb); ** ** @return the PCB pointer, or NULL if the queue is empty */ -pcb_t *pcb_queue_peek(const pcb_queue_t queue); +pcb_t *pcb_queue_peek( const pcb_queue_t queue ); /** ** Name: pcb_queue_remove @@ -355,7 +350,7 @@ pcb_t *pcb_queue_peek(const pcb_queue_t queue); ** ** @return status of the removal request */ -int pcb_queue_remove(pcb_queue_t queue, pcb_t **pcb); +int pcb_queue_remove( pcb_queue_t queue, pcb_t **pcb ); /** ** Name: pcb_queue_remove_this @@ -367,7 +362,7 @@ int pcb_queue_remove(pcb_queue_t queue, pcb_t **pcb); ** ** @return status of the removal request */ -int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb); +int pcb_queue_remove_this( pcb_queue_t queue, pcb_t *pcb ); /* ** Scheduler routines @@ -380,14 +375,14 @@ int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb); ** ** @param pcb Pointer to the PCB of the process to be scheduled */ -void schedule(pcb_t *pcb); +void schedule( pcb_t *pcb ); /** ** dispatch() ** ** Select the next process to receive the CPU */ -void dispatch(void); +void dispatch( void ); /* ** Debugging/tracing routines @@ -401,7 +396,7 @@ void dispatch(void); ** @param msg[in] An optional message to print before the dump ** @param c[in] The context to dump out */ -void ctx_dump(const char *msg, register context_t *c); +void ctx_dump( const char *msg, register context_t *c ); /** ** Name: ctx_dump_all @@ -410,7 +405,7 @@ void ctx_dump(const char *msg, register context_t *c); ** ** @param msg[in] Optional message to print */ -void ctx_dump_all(const char *msg); +void ctx_dump_all( const char *msg ); /** ** Name: pcb_dump @@ -421,7 +416,7 @@ void ctx_dump_all(const char *msg); ** @param p[in] The PCB to dump ** @param all[in] Dump all the contents? */ -void pcb_dump(const char *msg, register pcb_t *p, bool_t all); +void pcb_dump( const char *msg, register pcb_t *p, bool_t all ); /** ** Name: pcb_queue_dump @@ -432,7 +427,7 @@ void pcb_dump(const char *msg, register pcb_t *p, bool_t all); ** @param queue[in] The queue to dump ** @param contents[in] Also dump (some) contents? */ -void pcb_queue_dump(const char *msg, pcb_queue_t queue, bool_t contents); +void pcb_queue_dump( const char *msg, pcb_queue_t queue, bool_t contents ); /** ** Name: ptable_dump @@ -442,7 +437,7 @@ void pcb_queue_dump(const char *msg, pcb_queue_t queue, bool_t contents); ** @param msg[in] Optional message to print ** @param all[in] Dump all or only part of the relevant data */ -void ptable_dump(const char *msg, bool_t all); +void ptable_dump( const char *msg, bool_t all ); /** ** Name: ptable_dump_counts @@ -450,8 +445,8 @@ void ptable_dump(const char *msg, bool_t all); ** Prints basic information about the process table (number of ** entries, number with each process state, etc.). */ -void ptable_dump_counts(void); +void ptable_dump_counts( void ); -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/serial.h b/kernel/old/include/serial.h deleted file mode 100644 index 20bf192..0000000 --- a/kernel/old/include/serial.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#include diff --git a/kernel/old/include/sio.h b/kernel/old/include/sio.h index 629fda2..dca80ed 100644 --- a/kernel/old/include/sio.h +++ b/kernel/old/include/sio.h @@ -18,9 +18,9 @@ // sio interrupt settings -#define SIO_TX 0x01 -#define SIO_RX 0x02 -#define SIO_BOTH (SIO_TX | SIO_RX) +#define SIO_TX 0x01 +#define SIO_RX 0x02 +#define SIO_BOTH (SIO_TX | SIO_RX) #ifndef ASM_SRC @@ -48,7 +48,7 @@ extern QTYPE QNAME; ** ** Initialize the UART chip. */ -void sio_init(void); +void sio_init( void ); /** ** sio_enable() @@ -61,7 +61,7 @@ void sio_init(void); ** ** @return the prior IER setting */ -uint8_t sio_enable(uint8_t which); +uint8_t sio_enable( uint8_t which ); /** ** sio_disable() @@ -74,7 +74,7 @@ uint8_t sio_enable(uint8_t which); ** ** @return the prior IER setting */ -uint8_t sio_disable(uint8_t which); +uint8_t sio_disable( uint8_t which ); /** ** sio_inq_length() @@ -85,7 +85,7 @@ uint8_t sio_disable(uint8_t which); ** ** @return the count of characters still in the input queue */ -int sio_inq_length(void); +int sio_inq_length( void ); /** ** sio_readc() @@ -96,7 +96,7 @@ int sio_inq_length(void); ** ** @return the next character, or -1 if no character is available */ -int sio_readc(void); +int sio_readc( void ); /** ** sio_read() @@ -110,7 +110,7 @@ int sio_readc(void); ** ** @return the number of bytes copied, or 0 if no characters were available */ -int sio_read(char *buffer, int length); +int sio_read( char *buffer, int length ); /** ** sio_writec( ch ) @@ -121,7 +121,7 @@ int sio_read(char *buffer, int length); ** ** @param ch Character to be written (in the low-order 8 bits) */ -void sio_writec(int ch); +void sio_writec( int ch ); /** ** sio_write( ch ) @@ -135,7 +135,7 @@ void sio_writec(int ch); ** ** @return the number of characters copied into the SIO output buffer */ -int sio_write(const char *buffer, int length); +int sio_write( const char *buffer, int length ); /** ** sio_puts( buf ) @@ -148,7 +148,7 @@ int sio_write(const char *buffer, int length); ** ** @return the count of bytes transferred */ -int sio_puts(const char *buffer); +int sio_puts( const char *buffer ); /** ** sio_dump( full ) @@ -161,8 +161,8 @@ int sio_puts(const char *buffer); ** is being requested (which includes the contents ** of the queues) */ -void sio_dump(bool_t full); +void sio_dump( bool_t full ); -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/support.h b/kernel/old/include/support.h index ac75a64..bdc5dc6 100644 --- a/kernel/old/include/support.h +++ b/kernel/old/include/support.h @@ -30,14 +30,14 @@ ** ** Ultimately, just remember that THESE VALUES ARE APPROXIMATE AT BEST. */ -#define DELAY_1_SEC 40 -#define DELAY_1_25_SEC 50 -#define DELAY_2_SEC 80 -#define DELAY_2_5_SEC 100 -#define DELAY_3_SEC 120 -#define DELAY_5_SEC 200 -#define DELAY_7_SEC 280 -#define DELAY_10_SEC 400 +#define DELAY_1_SEC 40 +#define DELAY_1_25_SEC 50 +#define DELAY_2_SEC 80 +#define DELAY_2_5_SEC 100 +#define DELAY_3_SEC 120 +#define DELAY_5_SEC 200 +#define DELAY_7_SEC 280 +#define DELAY_10_SEC 400 #ifndef ASM_SRC /** @@ -49,7 +49,7 @@ ** ** @param reason NUL-terminated message to be printed. */ -void panic(char *reason); +void panic( char *reason ); /** ** init_interrupts @@ -58,7 +58,7 @@ void panic(char *reason); ** IDT and the PIC. It is up to the user to enable processor interrupts ** when they're ready. */ -void init_interrupts(void); +void init_interrupts( void ); /* ** install_isr @@ -71,7 +71,8 @@ void init_interrupts(void); ** ** @return a pointer to the previously-registered ISR */ -void (*install_isr(int vector, void (*handler)(int, int)))(int, int); +void (*install_isr( int vector, + void ( *handler )(int,int) ) )( int, int ); /* ** Name: delay @@ -79,8 +80,8 @@ void (*install_isr(int vector, void (*handler)(int, int)))(int, int); ** See the comment above about the relative accuracy of the 'length' ** parameter. */ -void delay(int length); +void delay( int length ); -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/syscalls.h b/kernel/old/include/syscalls.h index 27392a1..e66f6c0 100644 --- a/kernel/old/include/syscalls.h +++ b/kernel/old/include/syscalls.h @@ -23,28 +23,28 @@ ** so that they can be used from assembly */ -#define SYS_exit 0 -#define SYS_waitpid 1 -#define SYS_fork 2 -#define SYS_exec 3 -#define SYS_read 4 -#define SYS_write 5 -#define SYS_getpid 6 -#define SYS_getppid 7 -#define SYS_gettime 8 -#define SYS_getprio 9 -#define SYS_setprio 10 -#define SYS_kill 11 -#define SYS_sleep 12 +#define SYS_exit 0 +#define SYS_waitpid 1 +#define SYS_fork 2 +#define SYS_exec 3 +#define SYS_read 4 +#define SYS_write 5 +#define SYS_getpid 6 +#define SYS_getppid 7 +#define SYS_gettime 8 +#define SYS_getprio 9 +#define SYS_setprio 10 +#define SYS_kill 11 +#define SYS_sleep 12 // UPDATE THIS DEFINITION IF MORE SYSCALLS ARE ADDED! -#define N_SYSCALLS 13 +#define N_SYSCALLS 13 // dummy system call code for testing our ISR -#define SYS_bogus 0xbad +#define SYS_bogus 0xbad // interrupt vector entry for system calls -#define VEC_SYSCALL 0x80 +#define VEC_SYSCALL 0x80 #ifndef ASM_SRC @@ -71,10 +71,10 @@ ** ** Syscall module initialization routine */ -void sys_init(void); +void sys_init( void ); -#endif /* KERNEL_SRC */ +#endif /* KERNEL_SRC */ -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/types.h b/kernel/old/include/types.h index 9435954..2f934f1 100644 --- a/kernel/old/include/types.h +++ b/kernel/old/include/types.h @@ -1,13 +1,58 @@ +/** +** @file types.h +** +** @author Warren R. Carithers +** +** @brief Common type declarations. +** +** This header file contains type declarations used throughout +** the kernel and user code. +*/ + #ifndef TYPES_H_ #define TYPES_H_ + #ifndef ASM_SRC +/* +** Start of C-only definitions +** +** Anything that should not be visible to something other than +** the C compiler should be put here. +*/ + +/* +** Types +*/ + +// standard integer sized types +typedef char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; + +// other integer types +typedef unsigned char uchar_t; +typedef unsigned int uint_t; +typedef unsigned long int ulong_t; + +// Boolean values +typedef uint8_t bool_t; + +#define true 1 +#define false 0 + #ifdef KERNEL_SRC // we define these here instead of in vm.h in order to get around a // nasty chick/egg dependency between procs.h and vm.h -typedef uint32_t pde_t; // page directory entry -typedef uint32_t pte_t; // page table entry -#endif /* KERNEL_SRC */ +typedef uint32_t pde_t; // page directory entry +typedef uint32_t pte_t; // page table entry +#endif /* KERNEL_SRC */ + +#endif /* !ASM_SRC */ -#endif #endif diff --git a/kernel/old/include/udefs.h b/kernel/old/include/udefs.h new file mode 100644 index 0000000..50b6952 --- /dev/null +++ b/kernel/old/include/udefs.h @@ -0,0 +1,113 @@ +/** +** @file udefs.h +** +** @author CSCI-452 class of 20245 +** +** @brief "Userland" configuration information +*/ + +#ifndef UDEFS_H_ +#define UDEFS_H_ + +#include + +/* +** General (C and/or assembly) definitions +** +** This section of the header file contains definitions that can be +** used in either C or assembly-language source code. +*/ + +// delay loop counts + +#define DELAY_LONG 100000000 +#define DELAY_MED 4500000 +#define DELAY_SHORT 2500000 + +#define DELAY_STD DELAY_SHORT + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +// convenience macros + +// a delay loop - kind of ugly, but it works + +#define DELAY(n) do { \ + for(int _dlc = 0; _dlc < (DELAY_##n); ++_dlc) continue; \ + } while(0) + +/* +** We need the list of program IDs so that we can request +** their execution +*/ + +#include + +/* +** All user main() functions have the following prototype: +** +** int name( int argc, char *argv[] ); +** +** To simplify declaring them, we define a macro that expands into +** that header. This can be used both in the implementation (followed +** by the function body) and in places where we just need the prototype +** (following it with a semicolon). +*/ + +#define USERMAIN(f) int f( int argc, char *argv[] ) + +/* +** User process controls. +** +** To enable a specific test, define the symbol SPAWN_name here, and +** guard the places in other code that use or refer to that test. For +** example, test 'A' is enabled by definining SPAWN_A here, and all +** places that refer to test 'A' are guarded with: +** +** #ifdef SPAWN_A +** ... conditionally-compiled code +** #endif +** +** Generally, most of these will exit with a status of 0. If a process +** returns from its main function when it shouldn't (e.g., if it had +** called exit() but continued to run), it will usually return a status +** of ?. +*/ + +/* +** The standard set of test programs, start by the shell (which is started +** automatically from the initial user process) +** +** There is no user 'O' program, and programs 'W' through 'Z' are spawned +** from other processes and are never spawned directly. +*/ + +#define SPAWN_A +#define SPAWN_B +#define SPAWN_C +#define SPAWN_D +#define SPAWN_E +#define SPAWN_F +#define SPAWN_G +#define SPAWN_H +#define SPAWN_I +#define SPAWN_J +#define SPAWN_K +#define SPAWN_L +#define SPAWN_M +#define SPAWN_N +#define SPAWN_P +#define SPAWN_Q +#define SPAWN_R +#define SPAWN_S +#define SPAWN_T +#define SPAWN_U +#define SPAWN_V + +#endif /* !ASM_SRC */ + +#endif diff --git a/kernel/old/include/ulib.h b/kernel/old/include/ulib.h new file mode 100644 index 0000000..d254d6a --- /dev/null +++ b/kernel/old/include/ulib.h @@ -0,0 +1,315 @@ +/** +** @file ulib.h +** +** @author CSCI-452 class of 20245 +** +** @brief Declarations for user-level library functions +** +** This module implements a simple collection of support functions +** similar to the standard C library. +*/ + +#ifndef ULIB_H_ +#define ULIB_H_ + +#include + +/* +** General (C and/or assembly) definitions +*/ + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** Types +*/ + +/* +** Globals +*/ + +/* +** Prototypes +*/ + +/* +************************************************* +** SYSTEM CALLS ********************************* +************************************************* +*/ + +/** +** exit - terminate the calling process +** +** usage: exit(status); +** +** @param status Termination status of this process +** +** Does not return. +*/ +void exit( int32_t status ); + +/** +** waitpid - wait for a child process to terminate +** +** usage: pid = waitpid(pid,&status); +** +** @param pid PID of the desired child, or 0 for any child +** @param status Pointer to int32_t into which the child's status is placed, +** or NULL +** +** @return The PID of the terminated child, or an error code +** +** If there are no children in the system, returns an error code (*status +** is unchanged). +** +** If there are one or more children in the system and at least one has +** terminated but hasn't yet been cleaned up, cleans up that process and +** returns its information; otherwise, blocks until a child terminates. +*/ +int waitpid( uint_t pid, int32_t *status ); + +/** +** fork - create a duplicate of the calling process +** +** usage: pid = fork(); +** +** @return parent - the pid of the new child, or an error code +** child - 0 +*/ +int fork( void ); + +/** +** exec - replace the memory image of the calling process +** +** usage: exec( what, args ) +** +** @param what program table index of the program to exec +** @param args the command-line argument vector +** +** Does not return if it succeeds; if it returns, something has +** gone wrong. +*/ +void exec( uint_t what, char **args ); + +/** +** read - read into a buffer from a stream +** +** usage: n = read(channel,buf,length) +** +** @param chan I/O stream to read from +** @param buf Buffer to read into +** @param length Maximum capacity of the buffer +** +** @return The count of bytes transferred, or an error code +*/ +int read( uint_t chan, void *buffer, uint_t length ); + +/** +** write - write from a buffer to a stream +** +** usage: n = write(channel,buf,length) +** +** @param chan I/O stream to write to +** @param buf Buffer to write from +** @param length Maximum capacity of the buffer +** +** @return The count of bytes transferred, or an error code +*/ +int write( uint_t chan, const void *buffer, uint_t length ); + +/** +** getpid - get the PID of the calling process +** +** usage: pid = getpid() +** +** @return the PID of this process +*/ +uint_t getpid( void ); + +/** +** getppid - get the PID of the calling process' parent +** +** usage: pid = getppid() +** +** @return the PID of this process' parent +*/ +uint_t getppid( void ); + +/** +** gettime - get the current system time +** +** usage: pid = gettime() +** +** @return the system time +*/ +uint32_t gettime( void ); + +/** +** getprio - get the scheduling priority of the calling process +** +** usage: prio = getprio() +** +** @return the process' priority +*/ +int getprio( void ); + +/** +** setprio - set the scheduling priority of the calling process +** +** usage: oldprio = setprio(newprio) +** +** @param new the desired new priority +** +** @return the old priority value +*/ +int setprio( int new ); + +/** +** kill - terminate a process with extreme prejudice +** +** usage: n = kill( pid ) +** +** @param pid the intended victim +** +** @return 0 on success, else an error code +*/ +int32_t kill( uint_t pid ); + +/** +** sleep - put the current process to sleep for some length of time +** +** usage: sleep(n); +** +** @param ms Desired sleep time (in ms), or 0 to yield the CPU +** +** @return the time the process spent sleeping (in ms) +*/ +int sleep( uint32_t ms ); + +/** +** bogus - a nonexistent system call, to test our syscall ISR +** +** usage: bogus() +** +** Does not return. +*/ +void bogus( void ); + +/* +************************************************* +** CONVENIENT "SHORTHAND" VERSIONS OF SYSCALLS ** +************************************************* +** +** These are library functions that perform specific common +** variants of system calls. This helps reduce the total number +** of system calls, keeping our baseline OS as lean and mean +** as we can make it. :-) +*/ + +/** +** wait - wait for any child to exit +** +** usage: pid = wait(&status) +** +** Calls waitpid(0,status) +** +** @param status Pointer to int32_t into which the child's status is placed, +** or NULL +** +** @return The PID of the terminated child, or an error code +*/ +int wait( int32_t *status ); + +/** +** spawn - create a new process running a different program +** +** usage: n = spawn(what,args) +** +** Creates a new process and then execs 'what' +** +** @param what Program table index of the program to spawn +** @param args The command-line argument vector for the process +** +** @return The PID of the child, or an error code +*/ +int spawn( uint_t what, char **args ); + +/** +** cwritech(ch) - write a single character to the console +** +** @param ch The character to write +** +** @return The return value from calling write() +*/ +int cwritech( char ch ); + +/** +** cwrites(str) - write a NUL-terminated string to the console +** +** @param str The string to write +** +*/ +int cwrites( const char *str ); + +/** +** cwrite(buf,leng) - write a sized buffer to the console +** +** @param buf The buffer to write +** @param leng The number of bytes to write +** +** @return The return value from calling write() +*/ +int cwrite( const char *buf, uint32_t leng ); + +/** +** swritech(ch) - write a single character to the SIO +** +** @param ch The character to write +** +** @return The return value from calling write() +*/ +int swritech( char ch ); + +/** +** swrites(str) - write a NUL-terminated string to the SIO +** +** @param str The string to write +** +** @return The return value from calling write() +*/ +int swrites( const char *str ); + +/** +** swrite(buf,leng) - write a sized buffer to the SIO +** +** @param buf The buffer to write +** @param leng The number of bytes to write +** +** @return The return value from calling write() +*/ +int swrite( const char *buf, uint32_t leng ); + +/* +************************************************* +** MISCELLANEOUS USEFUL SUPPORT FUNCTIONS ******* +************************************************* +*/ + +/** +** fake_exit() +** +** dummy "startup" function +** +** calls exit(%eax) - serves as the "return to" code for +** main() functions, in case they don't call exit() themselves +*/ +void fake_exit( void ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/kernel/old/include/user.h b/kernel/old/include/user.h index 672f916..4d9402f 100644 --- a/kernel/old/include/user.h +++ b/kernel/old/include/user.h @@ -15,7 +15,7 @@ #include // default value for EFLAGS in new processes -#define DEFAULT_EFLAGS (EFL_MB1 | EFL_IF) +#define DEFAULT_EFLAGS (EFL_MB1 | EFL_IF) /* ** General (C and/or assembly) definitions @@ -61,14 +61,14 @@ typedef struct header_s { } header_t; // length of the file name field -#define NAMELEN 20 +#define NAMELEN 20 // program descriptor typedef struct prog_s { - char name[NAMELEN]; // truncated name (15 chars) - uint32_t offset; // offset from the beginning of the blob - uint32_t size; // size of this ELF module - uint32_t flags; // miscellaneous flags + char name[NAMELEN]; // truncated name (15 chars) + uint32_t offset; // offset from the beginning of the blob + uint32_t size; // size of this ELF module + uint32_t flags; // miscellaneous flags } prog_t; /* @@ -84,7 +84,7 @@ typedef struct prog_s { ** ** Initializes the user support module. */ -void user_init(void); +void user_init( void ); /** ** Name: user_locate @@ -95,7 +95,7 @@ void user_init(void); ** ** @return pointer to the program table entry in the code archive, or NULL */ -prog_t *user_locate(uint_t what); +prog_t *user_locate( uint_t what ); /** ** Name: user_duplicate @@ -107,7 +107,7 @@ prog_t *user_locate(uint_t what); ** ** @return the status of the duplicate attempt */ -int user_duplicate(pcb_t *new, pcb_t *old); +int user_duplicate( pcb_t *new, pcb_t *old ); /** ** Name: user_load @@ -118,11 +118,10 @@ int user_duplicate(pcb_t *new, pcb_t *old); ** @param prog A pointer to the program table entry to be loaded ** @param pcb The PCB for the program being loaded ** @param args The argument vector for the program -** @param sys Is the argument vector from kernel code? ** ** @return the status of the load attempt */ -int user_load(prog_t *prog, pcb_t *pcb, const char **args, bool_t sys); +int user_load( prog_t *prog, pcb_t *pcb, const char **args ); /** ** Name: user_cleanup @@ -132,8 +131,8 @@ int user_load(prog_t *prog, pcb_t *pcb, const char **args, bool_t sys); ** ** @param pcb The PCB of the program to be cleaned up */ -void user_cleanup(pcb_t *pcb); +void user_cleanup( pcb_t *pcb ); -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/userids.h b/kernel/old/include/userids.h new file mode 100644 index 0000000..284f3ee --- /dev/null +++ b/kernel/old/include/userids.h @@ -0,0 +1,33 @@ +/** +** @file userids.h +** +** @author Warren R. Carithers +** +** @brief IDs for user-level programs +** +** NOTE: this file is automatically generated when the user.img file +** is created. Do not edit this manually! +*/ + +#ifndef USERIDS_H_ +#define USERIDS_H_ + +#ifndef ASM_SRC +/* +** These IDs are used to identify the various user programs. +** Each call to exec() will provide one of these as the first +** argument. +** +** This list should be updated if/when the collection of +** user processes changes. +*/ +enum users_e { + Init, Idle, Shell, ProgABC, ProgDE, ProgFG, ProgH, ProgI, + ProgJ, ProgKL, ProgMN, ProgP, ProgQ, ProgR, ProgS, ProgTUV, + ProgW, ProgX, ProgY, ProgZ + // sentinel + , N_USERS +}; +#endif /* !ASM_SRC */ + +#endif diff --git a/kernel/old/include/vm.h b/kernel/old/include/vm.h index dc12568..6e3935e 100644 --- a/kernel/old/include/vm.h +++ b/kernel/old/include/vm.h @@ -64,91 +64,87 @@ */ // user virtual addresses -#define USER_BASE 0x00000000 -#define USER_MAX 0x003fffff -#define USER_TEXT 0x00001000 -#define USER_STACK 0x003fe000 -#define USER_STACK_P1 USER_STACK -#define USER_STACK_P2 0x003ff000 -#define USER_STK_END 0x00400000 +#define USER_TEXT 0x00001000 +#define USER_STACK 0x003fe000 +#define USER_STK_END 0x00400000 // how to find the addresses of the stack pages in the VM hierarchy // user address space is the first 4MB of virtual memory -#define USER_PDE 0 -// the stack occupies this range of pages in the user address space -#define USER_STK_FIRST_PTE 1022 -#define USER_STK_LAST_PTE 1023 +#define USER_PDE 0 +// the stack occupies the last two pages of the address space +#define USER_STK_PTE1 1022 +#define USER_STK_PTE2 1023 // some important memory addresses -#define KERN_BASE 0x80000000 // start of "kernel" memory -#define EXT_BASE 0x00100000 // start of "extended" memory (1MB) -#define DEV_BASE 0xfe000000 // "device" memory -#define PHYS_TOP 0x3fffffff // last usable physical address (1GB - 1) +#define KERN_BASE 0x80000000 // start of "kernel" memory +#define EXT_BASE 0x00100000 // start of "extended" memory (1MB) +#define DEV_BASE 0xfe000000 // "device" memory +#define PHYS_TOP 0x3fffffff // last usable physical address (1GB - 1) // where the kernel actually lives -#define KERN_PLINK 0x00010000 -#define KERN_VLINK (KERN_BASE + KERN_PLINK) +#define KERN_PLINK 0x00010000 +#define KERN_VLINK (KERN_BASE + KERN_PLINK) // number of entries in a page directory or page table -#define N_PDE 1024 -#define N_PTE 1024 +#define N_PDE 1024 +#define N_PTE 1024 // index field shift counts and masks -#define PDIX_SHIFT 22 -#define PTIX_SHIFT 12 -#define PIX2I_MASK 0x3ff +#define PDIX_SHIFT 22 +#define PTIX_SHIFT 12 +#define PIX2I_MASK 0x3ff // physical/virtual converters that don't use casting // (usable from anywhere) -#define V2PNC(a) ((a) - KERN_BASE) -#define P2VNC(a) ((a) + KERN_BASE) +#define V2PNC(a) ((a) - KERN_BASE) +#define P2VNC(a) ((a) + KERN_BASE) // page-size address rounding macros -#define SZ_PG_M1 MOD4K_BITS -#define SZ_PG_MASK MOD4K_MASK -#define PGUP(a) (((a) + SZ_PG_M1) & SZ_PG_MASK) -#define PGDOWN(a) ((a) & SZ_PG_MASK) +#define SZ_PG_M1 MOD4K_BITS +#define SZ_PG_MASK MOD4K_MASK +#define PGUP(a) (((a)+SZ_PG_M1) & SZ_PG_MASK) +#define PGDOWN(a) ((a) & SZ_PG_MASK) // page directory entry bit fields -#define PDE_P 0x00000001 // 1 = present -#define PDE_RW 0x00000002 // 1 = writable -#define PDE_US 0x00000004 // 1 = user and system usable -#define PDE_PWT 0x00000008 // cache: 1 = write-through -#define PDE_PCD 0x00000010 // cache: 1 = disabled -#define PDE_A 0x00000020 // accessed -#define PDE_D 0x00000040 // dirty (4MB pages) -#define PDE_AVL1 0x00000040 // ignored (4KB pages) -#define PDE_PS 0x00000080 // 1 = 4MB page size -#define PDE_G 0x00000100 // global -#define PDE_AVL2 0x00000e00 // ignored -#define PDE_PAT 0x00001000 // (4MB pages) use page attribute table -#define PDE_PTA 0xfffff000 // page table address field (4KB pages) -#define PDE_FA 0xffc00000 // frame address field (4MB pages) +#define PDE_P 0x00000001 // 1 = present +#define PDE_RW 0x00000002 // 1 = writable +#define PDE_US 0x00000004 // 1 = user and system usable +#define PDE_PWT 0x00000008 // cache: 1 = write-through +#define PDE_PCD 0x00000010 // cache: 1 = disabled +#define PDE_A 0x00000020 // accessed +#define PDE_D 0x00000040 // dirty (4MB pages) +#define PDE_AVL1 0x00000040 // ignored (4KB pages) +#define PDE_PS 0x00000080 // 1 = 4MB page size +#define PDE_G 0x00000100 // global +#define PDE_AVL2 0x00000e00 // ignored +#define PDE_PAT 0x00001000 // (4MB pages) use page attribute table +#define PDE_PTA 0xfffff000 // page table address field (4KB pages) +#define PDE_FA 0xffc00000 // frame address field (4MB pages) // page table entry bit fields -#define PTE_P 0x00000001 // present -#define PTE_RW 0x00000002 // 1 = writable -#define PTE_US 0x00000004 // 1 = user and system usable -#define PTE_PWT 0x00000008 // cache: 1 = write-through -#define PTE_PCD 0x00000010 // cache: 1 = disabled -#define PTE_A 0x00000020 // accessed -#define PTE_D 0x00000040 // dirty -#define PTE_PAT 0x00000080 // use page attribute table -#define PTE_G 0x00000100 // global -#define PTE_AVL2 0x00000e00 // ignored -#define PTE_FA 0xfffff000 // frame address field +#define PTE_P 0x00000001 // present +#define PTE_RW 0x00000002 // 1 = writable +#define PTE_US 0x00000004 // 1 = user and system usable +#define PTE_PWT 0x00000008 // cache: 1 = write-through +#define PTE_PCD 0x00000010 // cache: 1 = disabled +#define PTE_A 0x00000020 // accessed +#define PTE_D 0x00000040 // dirty +#define PTE_PAT 0x00000080 // use page attribute table +#define PTE_G 0x00000100 // global +#define PTE_AVL2 0x00000e00 // ignored +#define PTE_FA 0xfffff000 // frame address field // error code bit assignments for page faults -#define PFLT_P 0x00000001 -#define PFLT_W 0x00000002 -#define PFLT_US 0x00000004 -#define PFLT_RSVD 0x00000008 -#define PFLT_ID 0x00000010 -#define PFLT_PK 0x00000020 -#define PFLT_SS 0x00000040 -#define PFLT_HLAT 0x00000080 -#define PFLT_SGX 0x00008000 -#define PFLT_UNUSED 0xffff7f00 +#define PFLT_P 0x00000001 +#define PFLT_W 0x00000002 +#define PFLT_US 0x00000004 +#define PFLT_RSVD 0x00000008 +#define PFLT_ID 0x00000010 +#define PFLT_PK 0x00000020 +#define PFLT_SS 0x00000040 +#define PFLT_HLAT 0x00000080 +#define PFLT_SGX 0x00008000 +#define PFLT_UNUSED 0xffff7f00 #ifndef ASM_SRC @@ -158,59 +154,54 @@ // physical/virtual converters that do use casting // (not usable from assembly) -#define V2P(a) (((uint32_t)(a)) - KERN_BASE) -#define P2V(a) (((uint32_t)(a)) + KERN_BASE) +#define V2P(a) (((uint32_t)(a)) - KERN_BASE) +#define P2V(a) (((uint32_t)(a)) + KERN_BASE) // create a pde/pte from an integer frame number and permission bits -#define MKPDE(f, p) ((pde_t)(TO_FRAME((f)) | (p))) -#define MKPTE(f, p) ((pte_t)(TO_FRAME((f)) | (p))) +#define MKPDE(f,p) ((pde_t)( TO_FRAME((f)) | (p) )) +#define MKPTE(f,p) ((pte_t)( TO_FRAME((f)) | (p) )) // is a PDE/PTE present? // (P bit is in the same place in both) -#define IS_PRESENT(entry) (((entry) & PDE_P) != 0) +#define IS_PRESENT(entry) (((entry) & PDE_P) != 0 ) // is a PDE a 4MB page entry? -#define IS_LARGE(pde) (((pde) & PDE_PS) != 0) +#define IS_LARGE(pde) (((pde) & PDE_PS) != 0 ) // is this entry "system only" or "system and user"? -#define IS_SYSTEM(entry) (((entry) & PDE_US) == 0) -#define IS_USER(entry) (((entry) & PDE_US) != 0) +#define IS_SYSTEM(entry) (((entry) & PDE_US) == 0 ) +#define IS_USER(entry) (((entry) & PDE_US) != 0 ) // low-order nine bits of PDEs and PTEs hold "permission" flag bits -#define PERMS_MASK MOD4K_BITS +#define PERMS_MASK MOD4K_MASK // 4KB frame numbers are 20 bits wide -#define FRAME_4K_SHIFT 12 -#define FRAME2I_4K_MASK 0x000fffff -#define TO_4KFRAME(n) (((n) & FRAME2I_4K_MASK) << FRAME_4K_SHIFT) -#define GET_4KFRAME(n) (((n) >> FRAME_4K_SHIFT) & FRAME2I_4K_MASK) -#define PDE_4K_ADDR(n) ((n) & MOD4K_MASK) -#define PTE_4K_ADDR(n) ((n) & MOD4K_MASK) +#define FRAME_4K_SHIFT 12 +#define FRAME2I_4K_MASK 0x000fffff +#define TO_4KFRAME(n) (((n)&FRAME2I_4K_MASK) << FRAME_4K_SHIFT) +#define GET_4KFRAME(n) (((n) >> FRAME_4K_SHIFT)&F2I_4K_MASK) +#define PDE_4K_ADDR(n) ((n) & MOD4K_MASK) +#define PTE_4K_ADDR(n) ((n) & MOD4K_MASK) // 4MB frame numbers are 10 bits wide -#define FRAME_4M_SHIFT 22 -#define FRAME2I_4M_MASK 0x000003ff -#define TO_4MFRAME(n) (((n) & FRAME2I_4M_MASK) << FRAME_4M_SHIFT) -#define GET_4MFRAME(n) (((n) >> FRAME_4M_SHIFT) & FRAME2I_4M_MASK) -#define PDE_4M_ADDR(n) ((n) & MOD4M_MASK) -#define PTE_4M_ADDR(n) ((n) & MOD4M_MASK) +#define FRAME_4M_SHIFT 22 +#define FRAME2I_4M_MASK 0x000003ff +#define TO_4MFRAME(n) (((n)&FRAME2I_4M_MASK) << FRAME_4M_SHIFT) +#define GET_4MFRAME(n) (((n) >> FRAME_4M_SHIFT)&F2I_4M_MASK) +#define PDE_4M_ADDR(n) ((n) & MOD4M_MASK) +#define PTE_4M_ADDR(n) ((n) & MOD4M_MASK) // extract the PMT address or frame address from a table entry // PDEs could point to 4MB pages, or 4KB PMTs -#define PDE_ADDR(p) \ - (IS_LARGE(p) ? (((uint32_t)p) & PDE_FA) : (((uint32_t)p) & PDE_PTA)) +#define PDE_ADDR(p) (IS_LARGE(p)?(((uint32_t)p)&PDE_FA):(((uint32_t)p)&PDE_PTA)) // PTEs always point to 4KB pages -#define PTE_ADDR(p) (((uint32_t)(p)) & PTE_FA) +#define PTE_ADDR(p) (((uint32_t)(p))&PTE_FA) // everything has nine bits of permission flags -#define PERMS(p) (((uint32_t)(p)) & PERMS_MASK) +#define PERMS(p) (((uint32_t)(p))&PERMS_MASK) -// extract the table indices from a 32-bit VA -#define PDIX(v) ((((uint32_t)(v)) >> PDIX_SHIFT) & PIX2I_MASK) -#define PTIX(v) ((((uint32_t)(v)) >> PTIX_SHIFT) & PIX2I_MASK) - -// extract the byte offset from a 32-bit VA -#define OFFSET_4K(v) (((uint32_t)(v)) & MOD4K_BITS) -#define OFFSET_4M(v) (((uint32_t)(v)) & MOD4M_BITS) +// extract the table indices from a 32-bit address +#define PDIX(v) ((((uint32_t)(v)) >> PDIX_SHIFT) & PIX2I_MASK) +#define PTIX(v) ((((uint32_t)(v)) >> PTIX_SHIFT) & PIX2I_MASK) /* ** Types @@ -223,34 +214,31 @@ // PDE for 4KB pages typedef struct pdek_s { - uint_t p : 1; // 0: present - uint_t rw : 1; // 1: writable - uint_t us : 1; // 2: user/supervisor - uint_t pwt : 1; // 3: cache write-through - uint_t pcd : 1; // 4: cache disable - uint_t a : 1; // 5: accessed - uint_t avl1 : 1; // 6: ignored (available) - uint_t ps : 1; // 7: page size (must be 0) - uint_t avl2 : 4; // 11-8: ignored (available) - uint_t fa : 20; // 31-12: frame address + uint_t p :1; // present + uint_t rw :1; // writable + uint_t us :1; // user/supervisor + uint_t pwt :1; // cache write-through + uint_t pcd :1; // cache disable + uint_t a :1; // accessed + uint_t avl1 :1; // ignored (available) + uint_t ps :1; // page size (must be 0) + uint_t avl2 :4; // ignored (available) + uint_t fa :20; // frame address } pdek_f_t; // PDE for 4MB pages typedef struct pdem_s { - uint_t p : 1; // 0: present - uint_t rw : 1; // 1: writable - uint_t us : 1; // 2: user/supervisor - uint_t pwt : 1; // 3: cache write-through - uint_t pcd : 1; // 4: cache disable - uint_t a : 1; // 5: accessed - uint_t d : 1; // 6: dirty - uint_t ps : 1; // 7: page size (must be 1) - uint_t g : 1; // 8: global - uint_t avl : 3; // 11-9: ignored (available) - uint_t pat : 1; // 12: page attribute table in use - uint_t fa2 : 4; // 16-13: bits 35-32 of frame address (36-bit addrs) - uint_t rsv : 5; // 21-17: reserved - must be zero - uint_t fa : 10; // 31-22: bits 31-22 of frame address + uint_t p :1; // present + uint_t rw :1; // writable + uint_t us :1; // user/supervisor + uint_t pwt :1; // cache write-through + uint_t pcd :1; // cache disable + uint_t a :1; // accessed + uint_t d :1; // dirty + uint_t ps :1; // page size (must be 1) + uint_t g :1; // global + uint_t avl :3; // ignored (available) + uint_t fa :20; // frame address } pdem_f_t; // page table entries @@ -260,33 +248,33 @@ typedef struct pdem_s { // broken out into fields typedef struct pte_s { - uint_t p : 1; // 0: present - uint_t rw : 1; // 1: writable - uint_t us : 1; // 2: user/supervisor - uint_t pwt : 1; // 3: cache write-through - uint_t pcd : 1; // 4: cache disable - uint_t a : 1; // 5: accessed - uint_t d : 1; // 6: dirty - uint_t pat : 1; // 7: page attribute table in use - uint_t g : 1; // 8: global - uint_t avl : 3; // 11-9: ignored (available) - uint_t fa : 20; // 31-12: frame address + uint_t p :1; // present + uint_t rw :1; // writable + uint_t us :1; // user/supervisor + uint_t pwt :1; // cache write-through + uint_t pcd :1; // cache disable + uint_t a :1; // accessed + uint_t d :1; // dirty + uint_t pat :1; // page attribute table in use + uint_t g :1; // global + uint_t avl :3; // ignored (available) + uint_t fa :20; // frame address } ptef_t; // page fault error code bits // comment: meaning when 1 / meaning when 0 struct pfec_s { - uint_t p : 1; // page-level protection violation / !present - uint_t w : 1; // write / read - uint_t us : 1; // user-mode access / supervisor-mode access - uint_t rsvd : 1; // reserved bit violation / not - uint_t id : 1; // instruction fetch / data fetch - uint_t pk : 1; // protection-key violation / !pk - uint_t ss : 1; // shadow stack access / !ss - uint_t hlat : 1; // HLAT paging / ordinary paging or access rights - uint_t xtr1 : 7; // unused - uint_t sgz : 1; // SGX-specific access control violation / !SGX - uint_t xtr2 : 16; // more unused + uint_t p :1; // page-level protection violation / !present + uint_t w :1; // write / read + uint_t us :1; // user-mode access / supervisor-mode access + uint_t rsvd :1; // reserved bit violation / not + uint_t id :1; // instruction fetch / data fetch + uint_t pk :1; // protection-key violation / !pk + uint_t ss :1; // shadow stack access / !ss + uint_t hlat :1; // HLAT paging / ordinary paging or access rights + uint_t xtr1 :7; // unused + uint_t sgz :1; // SGX-specific access control violation / !SGX + uint_t xtr2 :16; // more unused }; typedef union pfec_u { @@ -296,23 +284,12 @@ typedef union pfec_u { // Mapping descriptor for VA::PA mappings typedef struct mapping_t { - uint32_t va_start; // starting virtual address for this range - uint32_t pa_start; // first physical address in the range - uint32_t pa_end; // last physical address in the range - uint32_t perm; // access control + uint32_t va_start; // starting virtual address for this range + uint32_t pa_start; // first physical address in the range + uint32_t pa_end; // last physical address in the range + uint32_t perm; // access control } mapping_t; -// Modes for dumping out page hierarchies -enum vmmode_e { - Simple = 0, // just count 'present' entries at each level - OneLevel, // top-level only: count entries, decode 'present' - TwoLevel, // count entries & decode at each level - Full // ??? in case we need more? - // sentinel - , - N_VMMODES -}; - /* ** Globals */ @@ -332,20 +309,7 @@ extern pde_t *kpdir; ** Note: should not be called until after the memory free list has ** been set up. */ -void vm_init(void); - -/** -** Name: vm_uva2kva -** -** Convert a user VA into a kernel address. Works for all addresses - -** if the address is a page address, the low-order nine bits will be -** zeroes; otherwise, they is the offset into the page, which is -** unchanged within the address spaces. -** -** @param pdir Pointer to the page directory to examine -** @param va Virtual address to check -*/ -void *vm_uva2kva(pde_t *pdir, void *va); +void vm_init( void ); /** ** Name: vm_pagedup @@ -356,18 +320,7 @@ void *vm_uva2kva(pde_t *pdir, void *va); ** ** @return a pointer to the new, duplicate page, or NULL */ -void *vm_pagedup(void *old); - -/** -** Name: vm_pdedup -** -** Duplicate a page directory entry -** -** @param entry The entry to be duplicated -** -** @return the new entry, or -1 on error. -*/ -pde_t vm_pdedup(pde_t entry); +void *vm_pagedup( void *old ); /** ** Name: vm_ptdup @@ -379,7 +332,7 @@ pde_t vm_pdedup(pde_t entry); ** ** @return true on success, else false */ -bool_t vm_ptdup(pde_t *dst, pde_t *curr); +bool_t vm_ptdup( pde_t *dst, pde_t *curr ); /** ** Name: vm_getpte @@ -395,28 +348,28 @@ bool_t vm_ptdup(pde_t *dst, pde_t *curr); ** ** @return A pointer to the page table entry for this VA, or NULL */ -pte_t *vm_getpte(pde_t *pdir, const void *va, bool_t alloc); +pte_t *vm_getpte( pde_t *pdir, const void *va, bool_t alloc ); /** ** Name: vm_mkkvm ** ** Create the kernel's page table hierarchy */ -pde_t *vm_mkkvm(void); +pde_t *vm_mkkvm( void ); /** ** Name: vm_mkuvm ** ** Create the page table hierarchy for a user process */ -pde_t *vm_mkuvm(void); +pde_t *vm_mkuvm( void ); /** ** Name: vm_set_kvm ** ** Switch the page table register to the kernel's page directory */ -void vm_set_kvm(void); +void vm_set_kvm( void ); /** ** Name: vm_set_uvm @@ -425,7 +378,7 @@ void vm_set_kvm(void); ** ** @param p The PCB of the user process */ -void vm_set_uvm(pcb_t *p); +void vm_set_uvm( pcb_t *p ); /** ** Name: vm_add @@ -443,8 +396,8 @@ void vm_set_uvm(pcb_t *p); ** ** @return status of the allocation attempt */ -int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size, - char *data, uint32_t bytes); +int vm_add( pde_t *pdir, bool_t wr, bool_t sys, + void *va, uint32_t size, char *data, uint32_t bytes ); /** ** Name: vm_free @@ -454,7 +407,7 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size, ** ** @param pdir Pointer to the page directory */ -void vm_free(pde_t *pdir); +void vm_free( pde_t *pdir ); /* ** Name: vm_map @@ -465,11 +418,11 @@ void vm_free(pde_t *pdir); ** ** @param pdir Page directory for this address space ** @param va The starting virtual address -** @param pa The starting physical address ** @param size Length of the range to be mapped +** @param pa The starting physical address ** @param perm Permission bits for the PTEs */ -int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm); +int vm_map( pde_t *pdir, void *va, uint_t size, uint_t pa, int perm ); /** ** Name: vm_uvmdup @@ -478,24 +431,13 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm); ** hierarchy. We assume that the "new" page directory exists and ** the system portions of it should not be touched. ** -** @param new New page directory ** @param old Existing page directory +** @param new New page directory ** ** @return status of the duplication attempt */ -int vm_uvmdup(pde_t *new, pde_t *old); - -/** -** Name: vm_print -** -** Print out a paging hierarchy. -** -** @param pt Page table to display -** @param dir Is it a page directory (vs. a page table)? -** @param mode How to display the entries -*/ -void vm_print(void *pt, bool_t dir, enum vmmode_e mode); +int vm_uvmdup( pde_t *old, pde_t *new ); -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/vmtables.h b/kernel/old/include/vmtables.h index 83c0881..17f6e0a 100644 --- a/kernel/old/include/vmtables.h +++ b/kernel/old/include/vmtables.h @@ -38,6 +38,6 @@ extern pte_t id_map[]; extern mapping_t kmap[]; extern const uint32_t n_kmap; -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/x86/arch.h b/kernel/old/include/x86/arch.h index df0b2e2..113c76b 100644 --- a/kernel/old/include/x86/arch.h +++ b/kernel/old/include/x86/arch.h @@ -15,25 +15,25 @@ /* ** Video stuff */ -#define VID_BASE_ADDR 0xB8000 +#define VID_BASE_ADDR 0xB8000 /* ** Memory management */ -#define SEG_PRESENT 0x80 -#define SEG_PL_0 0x00 -#define SEG_PL_1 0x20 -#define SEG_PL_2 0x40 -#define SEG_PL_3 0x50 -#define SEG_SYSTEM 0x00 -#define SEG_NON_SYSTEM 0x10 -#define SEG_32BIT 0x04 -#define DESC_IGATE 0x06 +#define SEG_PRESENT 0x80 +#define SEG_PL_0 0x00 +#define SEG_PL_1 0x20 +#define SEG_PL_2 0x40 +#define SEG_PL_3 0x50 +#define SEG_SYSTEM 0x00 +#define SEG_NON_SYSTEM 0x10 +#define SEG_32BIT 0x04 +#define DESC_IGATE 0x06 /* ** Exceptions */ -#define N_EXCEPTIONS 256 +#define N_EXCEPTIONS 256 /* ** Bit definitions in registers @@ -41,94 +41,95 @@ ** See IA-32 Intel Architecture SW Dev. Manual, Volume 3: System ** Programming Guide, page 2-8. */ + /* ** EFLAGS */ -#define EFL_RSVD 0xffc00000 /* reserved */ -#define EFL_MB0 0x00008020 /* must be zero */ -#define EFL_MB1 0x00000002 /* must be 1 */ +#define EFL_RSVD 0xffc00000 /* reserved */ +#define EFL_MB0 0x00008020 /* must be zero */ +#define EFL_MB1 0x00000002 /* must be 1 */ -#define EFL_ID 0x00200000 -#define EFL_VIP 0x00100000 -#define EFL_VIF 0x00080000 -#define EFL_AC 0x00040000 -#define EFL_VM 0x00020000 -#define EFL_RF 0x00010000 -#define EFL_NT 0x00004000 +#define EFL_ID 0x00200000 +#define EFL_VIP 0x00100000 +#define EFL_VIF 0x00080000 +#define EFL_AC 0x00040000 +#define EFL_VM 0x00020000 +#define EFL_RF 0x00010000 +#define EFL_NT 0x00004000 #define EFL_IOPL 0x00003000 -#define EFL_OF 0x00000800 -#define EFL_DF 0x00000400 -#define EFL_IF 0x00000200 -#define EFL_TF 0x00000100 -#define EFL_SF 0x00000080 -#define EFL_ZF 0x00000040 -#define EFL_AF 0x00000010 -#define EFL_PF 0x00000004 -#define EFL_CF 0x00000001 +#define EFL_OF 0x00000800 +#define EFL_DF 0x00000400 +#define EFL_IF 0x00000200 +#define EFL_TF 0x00000100 +#define EFL_SF 0x00000080 +#define EFL_ZF 0x00000040 +#define EFL_AF 0x00000010 +#define EFL_PF 0x00000004 +#define EFL_CF 0x00000001 /* ** CR0, CR1, CR2, CR3, CR4 ** ** IA-32 V3, page 2-12. */ -#define CR0_RSVD 0x1ffaffc0 -#define CR0_PG 0x80000000 -#define CR0_CD 0x40000000 -#define CR0_NW 0x20000000 -#define CR0_AM 0x00040000 -#define CR0_WP 0x00010000 -#define CR0_NE 0x00000020 -#define CR0_ET 0x00000010 -#define CR0_TS 0x00000008 -#define CR0_EM 0x00000004 -#define CR0_MP 0x00000002 -#define CR0_PE 0x00000001 +#define CR0_RSVD 0x1ffaffc0 +#define CR0_PG 0x80000000 +#define CR0_CD 0x40000000 +#define CR0_NW 0x20000000 +#define CR0_AM 0x00040000 +#define CR0_WP 0x00010000 +#define CR0_NE 0x00000020 +#define CR0_ET 0x00000010 +#define CR0_TS 0x00000008 +#define CR0_EM 0x00000004 +#define CR0_MP 0x00000002 +#define CR0_PE 0x00000001 -#define CR1_RSVD 0xffffffff +#define CR1_RSVD 0xffffffff -#define CR2_RSVD 0x00000000 +#define CR2_RSVD 0x00000000 #define CR2_PF_LIN_ADDR 0xffffffff -#define CR3_RSVD 0x00000fe7 -#define CR3_PD_BASE 0xfffff000 -#define CR3_PCD 0x00000010 -#define CR3_PWT 0x00000008 +#define CR3_RSVD 0x00000fe7 +#define CR3_PD_BASE 0xfffff000 +#define CR3_PCD 0x00000010 +#define CR3_PWT 0x00000008 -#define CR4_RSVD 0xfd001000 -#define CR4_UINT 0x02000000 -#define CR4_PKS 0x01000000 -#define CR4_CET 0x00800000 -#define CR4_PKE 0x00400000 -#define CR4_SMAP 0x00200000 -#define CR4_SMEP 0x00100000 -#define CR4_KL 0x00080000 -#define CR4_OSXS 0x00040000 -#define CR4_PCID 0x00020000 -#define CR4_FSGS 0x00010000 -#define CR4_SMXE 0x00004000 -#define CR4_VMXE 0x00002000 -#define CR4_LA57 0x00001000 -#define CR4_UMIP 0x00000800 -#define CR4_OSXMMEXCPT 0x00000400 -#define CR4_OSFXSR 0x00000200 -#define CR4_PCE 0x00000100 -#define CR4_PGE 0x00000080 -#define CR4_MCE 0x00000040 -#define CR4_PAE 0x00000020 -#define CR4_PSE 0x00000010 -#define CR4_DE 0x00000008 -#define CR4_TSD 0x00000004 -#define CR4_PVI 0x00000002 -#define CR4_VME 0x00000001 +#define CR4_RSVD 0xfd001000 +#define CR4_UINT 0x02000000 +#define CR4_PKS 0x01000000 +#define CR4_CET 0x00800000 +#define CR4_PKE 0x00400000 +#define CR4_SMAP 0x00200000 +#define CR4_SMEP 0x00100000 +#define CR4_KL 0x00080000 +#define CR4_OSXS 0x00040000 +#define CR4_PCID 0x00020000 +#define CR4_FSGS 0x00010000 +#define CR4_SMXE 0x00004000 +#define CR4_VMXE 0x00002000 +#define CR4_LA57 0x00001000 +#define CR4_UMIP 0x00000800 +#define CR4_OSXMMEXCPT 0x00000400 +#define CR4_OSFXSR 0x00000200 +#define CR4_PCE 0x00000100 +#define CR4_PGE 0x00000080 +#define CR4_MCE 0x00000040 +#define CR4_PAE 0x00000020 +#define CR4_PSE 0x00000010 +#define CR4_DE 0x00000008 +#define CR4_TSD 0x00000004 +#define CR4_PVI 0x00000002 +#define CR4_VME 0x00000001 /* ** PMode segment selector field masks ** ** IA-32 V3, page 3-8. */ -#define SEG_SEL_IX_MASK 0xfff8 -#define SEG_SEL_TI_MASK 0x0004 -#define SEG_SEL_RPL_MASK 0x0003 +#define SEG_SEL_IX_MASK 0xfff8 +#define SEG_SEL_TI_MASK 0x0004 +#define SEG_SEL_RPL_MASK 0x0003 /* ** Segment descriptor bytes @@ -141,6 +142,7 @@ ** 4: base address 23:16 ** 7: base address 31:24 */ + /* ** Byte 5: access control bits ** 7: present @@ -148,43 +150,43 @@ ** 4: system/user ** 3-0: type */ -#define SEG_ACCESS_P_MASK 0x80 -#define SEG_PRESENT 0x80 -#define SEG_NOT_PRESENT 0x00 +#define SEG_ACCESS_P_MASK 0x80 +# define SEG_PRESENT 0x80 +# define SEG_NOT_PRESENT 0x00 -#define SEG_ACCESS_DPL_MASK 0x60 -#define SEG_DPL_0 0x00 -#define SEG_DPL_1 0x20 -#define SEG_DPL_2 0x40 -#define SEG_DPL_3 0x60 +#define SEG_ACCESS_DPL_MASK 0x60 +# define SEG_DPL_0 0x00 +# define SEG_DPL_1 0x20 +# define SEG_DPL_2 0x40 +# define SEG_DPL_3 0x60 -#define SEG_ACCESS_S_MASK 0x10 -#define SEG_SYSTEM 0x00 -#define SEG_NON_SYSTEM 0x10 +#define SEG_ACCESS_S_MASK 0x10 +# define SEG_SYSTEM 0x00 +# define SEG_NON_SYSTEM 0x10 -#define SEG_TYPE_MASK 0x0f -#define SEG_DATA_A_BIT 0x1 -#define SEG_DATA_W_BIT 0x2 -#define SEG_DATA_E_BIT 0x4 -#define SEG_CODE_A_BIT 0x1 -#define SEG_CODE_R_BIT 0x2 -#define SEG_CODE_C_BIT 0x4 -#define SEG_DATA_RO 0x0 -#define SEG_DATA_ROA 0x1 -#define SEG_DATA_RW 0x2 -#define SEG_DATA_RWA 0x3 -#define SEG_DATA_RO_XD 0x4 -#define SEG_DATA_RO_XDA 0x5 -#define SEG_DATA_RW_XW 0x6 -#define SEG_DATA_RW_XWA 0x7 -#define SEG_CODE_XO 0x8 -#define SEG_CODE_XOA 0x9 -#define SEG_CODE_XR 0xa -#define SEG_CODE_XRA 0xb -#define SEG_CODE_XO_C 0xc -#define SEG_CODE_XO_CA 0xd -#define SEG_CODE_XR_C 0xe -#define SEG_CODE_XR_CA 0xf +#define SEG_TYPE_MASK 0x0f +# define SEG_DATA_A_BIT 0x1 +# define SEG_DATA_W_BIT 0x2 +# define SEG_DATA_E_BIT 0x4 +# define SEG_CODE_A_BIT 0x1 +# define SEG_CODE_R_BIT 0x2 +# define SEG_CODE_C_BIT 0x4 +# define SEG_DATA_RO 0x0 +# define SEG_DATA_ROA 0x1 +# define SEG_DATA_RW 0x2 +# define SEG_DATA_RWA 0x3 +# define SEG_DATA_RO_XD 0x4 +# define SEG_DATA_RO_XDA 0x5 +# define SEG_DATA_RW_XW 0x6 +# define SEG_DATA_RW_XWA 0x7 +# define SEG_CODE_XO 0x8 +# define SEG_CODE_XOA 0x9 +# define SEG_CODE_XR 0xa +# define SEG_CODE_XRA 0xb +# define SEG_CODE_XO_C 0xc +# define SEG_CODE_XO_CA 0xd +# define SEG_CODE_XR_C 0xe +# define SEG_CODE_XR_CA 0xf /* ** Byte 6: sizes @@ -195,47 +197,48 @@ ** 3-0: upper 4 bits of limit ** 7: base address 31:24 */ -#define SEG_SIZE_G_MASK 0x80 -#define SEG_GRAN_BYTE 0x00 -#define SEG_GRAN_4KBYTE 0x80 +#define SEG_SIZE_G_MASK 0x80 +# define SEG_GRAN_BYTE 0x00 +# define SEG_GRAN_4KBYTE 0x80 -#define SEG_SIZE_D_B_MASK 0x40 -#define SEG_DB_16BIT 0x00 -#define SEG_DB_32BIT 0x40 +#define SEG_SIZE_D_B_MASK 0x40 +# define SEG_DB_16BIT 0x00 +# define SEG_DB_32BIT 0x40 -#define SEG_SIZE_L_MASK 0x20 -#define SEG_L_64BIT 0x20 -#define SEG_L_32BIT 0x00 +#define SEG_SIZE_L_MASK 0x20 +# define SEG_L_64BIT 0x20 +# define SEG_L_32BIT 0x00 -#define SEG_SIZE_AVL_MASK 0x10 +#define SEG_SIZE_AVL_MASK 0x10 #define SEG_SIZE_LIM_19_16_MASK 0x0f + /* ** System-segment and gate-descriptor types ** ** IA-32 V3, page 3-15. */ -// type 0: reserved + // type 0: reserved #define SEG_SYS_16BIT_TSS_AVAIL 0x1 -#define SEG_SYS_LDT 0x2 -#define SEG_SYS_16BIT_TSS_BUSY 0x3 +#define SEG_SYS_LDT 0x2 +#define SEG_SYS_16BIT_TSS_BUSY 0x3 #define SEG_SYS_16BIT_CALL_GATE 0x4 -#define SEG_SYS_TASK_GATE 0x5 -#define SEG_SYS_16BIT_INT_GATE 0x6 +#define SEG_SYS_TASK_GATE 0x5 +#define SEG_SYS_16BIT_INT_GATE 0x6 #define SEG_SYS_16BIT_TRAP_GATE 0x7 -// type 8: reserved + // type 8: reserved #define SEG_SYS_32BIT_TSS_AVAIL 0x9 -// type A: reserved -#define SEG_SYS_32BIT_TSS_BUSY 0xb + // type A: reserved +#define SEG_SYS_32BIT_TSS_BUSY 0xb #define SEG_SYS_32BIT_CALL_GATE 0xc -// type D: reserved -#define SEG_SYS_32BIT_INT_GATE 0xe + // type D: reserved +#define SEG_SYS_32BIT_INT_GATE 0xe #define SEG_SYS_32BIT_TRAP_GATE 0xf /* ** IDT Descriptors -** +** ** IA-32 V3, page 5-13. ** ** All have a segment selector in bytes 2 and 3; Task Gate descriptors @@ -243,57 +246,58 @@ ** and 7 devoted to the 16 bits of the Offset, with the low nybble of ** byte 4 reserved. */ -#define IDT_PRESENT 0x8000 -#define IDT_DPL_MASK 0x6000 -#define IDT_DPL_0 0x0000 -#define IDT_DPL_1 0x2000 -#define IDT_DPL_2 0x4000 -#define IDT_DPL_3 0x6000 -#define IDT_GATE_TYPE 0x0f00 -#define IDT_TASK_GATE 0x0500 -#define IDT_INT16_GATE 0x0600 -#define IDT_INT32_GATE 0x0e00 -#define IDT_TRAP16_GATE 0x0700 -#define IDT_TRAP32_GATE 0x0f00 +#define IDT_PRESENT 0x8000 +#define IDT_DPL_MASK 0x6000 +# define IDT_DPL_0 0x0000 +# define IDT_DPL_1 0x2000 +# define IDT_DPL_2 0x4000 +# define IDT_DPL_3 0x6000 +#define IDT_GATE_TYPE 0x0f00 +# define IDT_TASK_GATE 0x0500 +# define IDT_INT16_GATE 0x0600 +# define IDT_INT32_GATE 0x0e00 +# define IDT_TRAP16_GATE 0x0700 +# define IDT_TRAP32_GATE 0x0f00 /* ** Interrupt vectors */ + // predefined by the architecture -#define VEC_DIVIDE_ERROR 0x00 -#define VEC_DEBUG_EXCEPTION 0x01 -#define VEC_NMI_INTERRUPT 0x02 -#define VEC_BREAKPOINT 0x03 -#define VEC_OVERFLOW 0x04 -#define VEC_BOUND_RANGE_EXCEEDED 0x05 -#define VEC_INVALID_OPCODE 0x06 -#define VEC_DEVICE_NOT_AVAILABLE 0x07 -#define VEC_DOUBLE_FAULT 0x08 -#define VEC_COPROCESSOR_OVERRUN 0x09 -#define VEC_INVALID_TSS 0x0a -#define VEC_SEGMENT_NOT_PRESENT 0x0b -#define VEC_STACK_FAULT 0x0c -#define VEC_GENERAL_PROTECTION 0x0d -#define VEC_PAGE_FAULT 0x0e +#define VEC_DIVIDE_ERROR 0x00 +#define VEC_DEBUG_EXCEPTION 0x01 +#define VEC_NMI_INTERRUPT 0x02 +#define VEC_BREAKPOINT 0x03 +#define VEC_OVERFLOW 0x04 +#define VEC_BOUND_RANGE_EXCEEDED 0x05 +#define VEC_INVALID_OPCODE 0x06 +#define VEC_DEVICE_NOT_AVAILABLE 0x07 +#define VEC_DOUBLE_FAULT 0x08 +#define VEC_COPROCESSOR_OVERRUN 0x09 +#define VEC_INVALID_TSS 0x0a +#define VEC_SEGMENT_NOT_PRESENT 0x0b +#define VEC_STACK_FAULT 0x0c +#define VEC_GENERAL_PROTECTION 0x0d +#define VEC_PAGE_FAULT 0x0e // 0x0f is reserved - unused -#define VEC_FPU_ERROR 0x10 -#define VEC_ALIGNMENT_CHECK 0x11 -#define VEC_MACHINE_CHECK 0x12 -#define VEC_SIMD_FP_EXCEPTION 0x13 -#define VEC_VIRT_EXCEPTION 0x14 -#define VEC_CTRL_PROT_EXCEPTION 0x15 +#define VEC_FPU_ERROR 0x10 +#define VEC_ALIGNMENT_CHECK 0x11 +#define VEC_MACHINE_CHECK 0x12 +#define VEC_SIMD_FP_EXCEPTION 0x13 +#define VEC_VIRT_EXCEPTION 0x14 +#define VEC_CTRL_PROT_EXCEPTION 0x15 // 0x16 through 0x1f are reserved // 0x20 through 0xff are user-defined, non-reserved // IRQ0 through IRQ15 will use vectors 0x20 through 0x2f -#define VEC_TIMER 0x20 -#define VEC_KBD 0x21 -#define VEC_COM2 0x23 -#define VEC_COM1 0x24 -#define VEC_PARALLEL 0x25 -#define VEC_FLOPPY 0x26 -#define VEC_MYSTERY 0x27 -#define VEC_MOUSE 0x2c +#define VEC_TIMER 0x20 +#define VEC_KBD 0x21 +#define VEC_COM2 0x23 +#define VEC_COM1 0x24 +#define VEC_PARALLEL 0x25 +#define VEC_FLOPPY 0x26 +#define VEC_MYSTERY 0x27 +#define VEC_MOUSE 0x2c #endif diff --git a/kernel/old/include/x86/bios.h b/kernel/old/include/x86/bios.h new file mode 100644 index 0000000..a19e570 --- /dev/null +++ b/kernel/old/include/x86/bios.h @@ -0,0 +1,73 @@ +/* +** @file bios.h +** +** @author Warren R. Carithers +** +** BIOS-related declarations +*/ + +#ifndef BIOS_H_ +#define BIOS_H_ + +/* +** BIOS-related memory addresses +*/ + +#define BIOS_BDA 0x0400 + +/* +** Selected BIOS interrupt numbers +*/ + +#define BIOS_TIMER 0x08 +#define BIOS_KBD 0x09 +#define BIOS_VIDEO 0x10 +#define BIOS_EQUIP 0x11 +#define BIOS_MSIZ 0x12 +#define BIOS_DISK 0x13 +#define BIOS_SERIAL 0x14 +#define BIOS_MISC 0x15 +#define BIOS_KBDSVC 0x16 +#define BIOS_PRTSVC 0x17 +#define BIOS_BOOT 0x19 +#define BIOS_RTCPCI 0x1a + +// BIOS video commands (AH) +#define BV_W_ADV 0x0e + +// BIOS disk commands (AH) +#define BD_RESET 0x00 +#define BD_CHECK 0x01 +#define BD_RDSECT 0x02 +#define BD_WRSECT 0x03 +#define BD_PARAMS 0x08 + +// BIOS disk commands with parameters (AX) +#define BD_READ(n) ((BD_RDSECT << 8) | (n)) +#define BD_READ1 0x0201 + +// CMOS ports (used for masking NMIs) +#define CMOS_ADDR 0x70 +#define CMOS_DATA 0x71 + +// important related commands +#define NMI_ENABLE 0x00 +#define NMI_DISABLE 0x80 + +/* +** Physical Memory Map Table (0000:2D00 - 0000:7c00) +** +** Primarily used with the BIOS_MISC interrupt +*/ +#define MMAP_SEG 0x02D0 +#define MMAP_DISP 0x0000 +#define MMAP_ADDR ((MMAP_SEG << 4) + MMAP_DISP) +#define MMAP_SECTORS 0x0a + +#define MMAP_ENT 24 /* bytes per entry */ +#define MMAP_MAX_ENTS (BOOT_ADDR - MMAP_ADDR - 4) / 24 + +#define MMAP_CODE 0xE820 /* int 0x15 code */ +#define MMAP_MAGIC_NUM 0x534D4150 /* for 0xE820 interrupt */ + +#endif diff --git a/kernel/old/include/x86/ops.h b/kernel/old/include/x86/ops.h index 81167a1..ad795b9 100644 --- a/kernel/old/include/x86/ops.h +++ b/kernel/old/include/x86/ops.h @@ -10,7 +10,7 @@ ** MIT's xv6, https://github.com/mit-pdos/xv6-public ** ** Note: normally, GCC doesn't inline unless the optimization level is -** over 1. This can be forced by adding +** over 1. This can be forced by adding ** ** __attribute__((always_inline)) ** @@ -27,10 +27,10 @@ // control "forced" inlining #ifdef FORCE_INLINING -#define OPSINLINED __attribute__((always_inline)) +#define OPSINLINED __attribute__((always_inline)) #else -#define OPSINLINED /* no-op */ -#endif /* FORCE_INLINING */ +#define OPSINLINED /* no-op */ +#endif /* FORCE_INLINING */ /**************************** ** Data movement @@ -47,33 +47,36 @@ ** @param src Source buffer ** @param len Byte count */ -static inline void movsb(void *dst, const void *src, uint32_t len) OPSINLINED +static inline void +movsb( void* dst, const void* src, uint32_t len ) OPSINLINED { - __asm__ __volatile__("cld; rep movsb" - : "+D"(dst), "+S"(src), "+c"(len) - : - : "memory"); + __asm__ __volatile__( "cld; rep movsb" + : "+D"(dst), "+S"(src), "+c"(len) + : : "memory" ); } -static inline void movsw(void *dst, const void *src, uint32_t len) OPSINLINED + +static inline void +movsw( void* dst, const void* src, uint32_t len ) OPSINLINED { - __asm__ __volatile__("cld; rep movsw" - : "+D"(dst), "+S"(src), "+c"(len) - : - : "memory"); + __asm__ __volatile__( "cld; rep movsw" + : "+D"(dst), "+S"(src), "+c"(len) + : : "memory" ); } -static inline void movsl(void *dst, const void *src, uint32_t len) OPSINLINED + +static inline void +movsl( void* dst, const void* src, uint32_t len ) OPSINLINED { - __asm__ __volatile__("cld; rep movsl" - : "+D"(dst), "+S"(src), "+c"(len) - : - : "memory"); + __asm__ __volatile__( "cld; rep movsl" + : "+D"(dst), "+S"(src), "+c"(len) + : : "memory" ); } -static inline void movsq(void *dst, const void *src, uint32_t len) OPSINLINED + +static inline void +movsq( void* dst, const void* src, uint32_t len ) OPSINLINED { - __asm__ __volatile__("cld; rep movsq" - : "+D"(dst), "+S"(src), "+c"(len) - : - : "memory"); + __asm__ __volatile__( "cld; rep movsq" + : "+D"(dst), "+S"(src), "+c"(len) + : : "memory" ); } /** @@ -87,26 +90,31 @@ static inline void movsq(void *dst, const void *src, uint32_t len) OPSINLINED ** @param val Data to copy ** @param len Byte count */ -static inline void stosb(void *dst, uint8_t val, uint32_t len) OPSINLINED +static inline void +stosb( void *dst, uint8_t val, uint32_t len ) OPSINLINED { - __asm__ __volatile__("cld; rep stosb" - : "=D"(dst), "=c"(len) - : "0"(dst), "1"(len), "a"(val) - : "memory", "cc"); + __asm__ __volatile__( "cld; rep stosb" + : "=D" (dst), "=c" (len) + : "0" (dst), "1" (len), "a" (val) + : "memory", "cc" ); } -static inline void stosw(void *dst, uint16_t val, uint32_t len) OPSINLINED + +static inline void +stosw( void *dst, uint16_t val, uint32_t len ) OPSINLINED { - __asm__ __volatile__("cld; rep stos2" - : "=D"(dst), "=c"(len) - : "0"(dst), "1"(len), "a"(val) - : "memory", "cc"); + __asm__ __volatile__( "cld; rep stos2" + : "=D" (dst), "=c" (len) + : "0" (dst), "1" (len), "a" (val) + : "memory", "cc" ); } -static inline void stosl(void *dst, uint32_t val, uint32_t len) OPSINLINED + +static inline void +stosl( void *dst, uint32_t val, uint32_t len ) OPSINLINED { - __asm__ __volatile__("cld; rep stosl" - : "=D"(dst), "=c"(len) - : "0"(dst), "1"(len), "a"(val) - : "memory", "cc"); + __asm__ __volatile__( "cld; rep stosl" + : "=D" (dst), "=c" (len) + : "0" (dst), "1" (len), "a" (val) + : "memory", "cc" ); } /**************************** @@ -123,46 +131,59 @@ static inline void stosl(void *dst, uint32_t val, uint32_t len) OPSINLINED ** ** @return Contents of the register */ -static inline uint32_t r_cr0(void) OPSINLINED +static inline uint32_t +r_cr0( void ) OPSINLINED { uint32_t val; - __asm__ __volatile__("movl %%cr0,%0" : "=r"(val)); + __asm__ __volatile__( "movl %%cr0,%0" : "=r" (val) ); return val; } -static inline uint32_t r_cr2(void) OPSINLINED + +static inline uint32_t +r_cr2( void ) OPSINLINED { uint32_t val; - __asm__ __volatile__("movl %%cr2,%0" : "=r"(val)); + __asm__ __volatile__( "movl %%cr2,%0" : "=r" (val) ); return val; } -static inline uint32_t r_cr3(void) OPSINLINED + +static inline uint32_t +r_cr3( void ) OPSINLINED { uint32_t val; - __asm__ __volatile__("movl %%cr3,%0" : "=r"(val)); + __asm__ __volatile__( "movl %%cr3,%0" : "=r" (val) ); return val; } -static inline uint32_t r_cr4(void) OPSINLINED + +static inline uint32_t +r_cr4( void ) OPSINLINED { uint32_t val; - __asm__ __volatile__("movl %%cr4,%0" : "=r"(val)); + __asm__ __volatile__( "movl %%cr4,%0" : "=r" (val) ); return val; } -static inline uint32_t r_eflags(void) OPSINLINED + +static inline uint32_t +r_eflags(void) OPSINLINED { uint32_t val; - __asm__ __volatile__("pushfl; popl %0" : "=r"(val)); + __asm__ __volatile__( "pushfl; popl %0" : "=r" (val) ); return val; } -static inline uint32_t r_ebp(void) OPSINLINED + +static inline uint32_t +r_ebp(void) OPSINLINED { uint32_t val; - __asm__ __volatile__("movl %%ebp,%0" : "=r"(val)); + __asm__ __volatile__( "movl %%ebp,%0" : "=r" (val) ); return val; } -static inline uint32_t r_esp(void) OPSINLINED + +static inline uint32_t +r_esp(void) OPSINLINED { uint32_t val; - __asm__ __volatile__("movl %%esp,%0" : "=r"(val)); + __asm__ __volatile__( "movl %%esp,%0" : "=r" (val) ); return val; } @@ -173,25 +194,34 @@ static inline uint32_t r_esp(void) OPSINLINED ** ** Description: Writes a value into the CR indicated by its name */ -static inline void w_cr0(uint32_t val) OPSINLINED +static inline void +w_cr0( uint32_t val ) OPSINLINED { - __asm__ __volatile__("movl %0,%%cr0" : : "r"(val)); + __asm__ __volatile__( "movl %0,%%cr0" : : "r" (val) ); } -static inline void w_cr2(uint32_t val) OPSINLINED + +static inline void +w_cr2( uint32_t val ) OPSINLINED { - __asm__ __volatile__("movl %0,%%cr2" : : "r"(val)); + __asm__ __volatile__( "movl %0,%%cr2" : : "r" (val) ); } -static inline void w_cr3(uint32_t val) OPSINLINED + +static inline void +w_cr3( uint32_t val ) OPSINLINED { - __asm__ __volatile__("movl %0,%%cr3" : : "r"(val)); + __asm__ __volatile__( "movl %0,%%cr3" : : "r" (val) ); } -static inline void w_cr4(uint32_t val) OPSINLINED + +static inline void +w_cr4( uint32_t val ) OPSINLINED { - __asm__ __volatile__("movl %0,%%cr4" : : "r"(val)); + __asm__ __volatile__( "movl %0,%%cr4" : : "r" (val) ); } -static inline void w_eflags(uint32_t eflags) OPSINLINED + +static inline void +w_eflags(uint32_t eflags) OPSINLINED { - __asm__ __volatile__("pushl %0; popfl" : : "r"(eflags)); + __asm__ __volatile__( "pushl %0; popfl" : : "r" (eflags) ); } /** @@ -203,13 +233,16 @@ static inline void w_eflags(uint32_t eflags) OPSINLINED ** ** @param addr The value to be loaded into the register */ -static inline void w_gdt(void *addr) OPSINLINED +static inline void +w_gdt( void *addr ) OPSINLINED { - __asm__ __volatile__("lgdt (%0)" : : "r"(addr)); + __asm__ __volatile__( "lgdt (%0)" : : "r" (addr) ); } -static inline void w_idt(void *addr) OPSINLINED + +static inline void +w_idt( void *addr ) OPSINLINED { - __asm__ __volatile__("lidt (%0)" : : "r"(addr)); + __asm__ __volatile__( "lidt (%0)" : : "r" (addr) ); } /** @@ -223,21 +256,19 @@ static inline void w_idt(void *addr) OPSINLINED ** @param cp Pointer to where %ecx contents should be saved, or NULL ** @param dp Pointer to where %edx contents should be saved, or NULL */ -static inline void cpuid(uint32_t op, uint32_t *ap, uint32_t *bp, uint32_t *cp, - uint32_t *dp) OPSINLINED +static inline void +cpuid( uint32_t op, uint32_t *ap, uint32_t *bp, + uint32_t *cp, uint32_t *dp ) OPSINLINED { uint32_t eax, ebx, ecx, edx; - __asm__ __volatile__("cpuid" - : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) - : "a"(op)); - if (ap) - *ap = eax; - if (bp) - *bp = ebx; - if (cp) - *cp = ecx; - if (dp) - *dp = edx; + __asm__ __volatile__( "cpuid" + : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) + : "a" (op) ); + + if( ap ) *ap = eax; + if( bp ) *bp = ebx; + if( cp ) *cp = ecx; + if( dp ) *dp = edx; } /**************************** @@ -251,9 +282,10 @@ static inline void cpuid(uint32_t op, uint32_t *ap, uint32_t *bp, uint32_t *cp, ** ** @param addr An address within the page to be flushed */ -static inline void invlpg(uint32_t addr) OPSINLINED +static inline void +invlpg( uint32_t addr ) OPSINLINED { - __asm__ __volatile__("invlpg (%0)" : : "r"(addr) : "memory"); + __asm__ __volatile__( "invlpg (%0)" : : "r" (addr) : "memory" ); } /** @@ -263,11 +295,12 @@ static inline void invlpg(uint32_t addr) OPSINLINED ** ** We do this by changing CR3. */ -static inline void flushtlb(void) OPSINLINED +static inline void +flushtlb( void ) OPSINLINED { uint32_t cr3; - __asm__ __volatile__("movl %%cr3,%0" : "=r"(cr3)); - __asm__ __volatile__("movl %0,%%cr2" : : "r"(cr3)); + __asm__ __volatile__( "movl %%cr3,%0" : "=r" (cr3) ); + __asm__ __volatile__( "movl %0,%%cr2" : : "r" (cr3) ); } /**************************** @@ -285,22 +318,27 @@ static inline void flushtlb(void) OPSINLINED ** ** @return The data read from the specified port */ -static inline uint8_t inb(int port) OPSINLINED +static inline uint8_t +inb( int port ) OPSINLINED { uint8_t data; - __asm__ __volatile__("inb %w1,%0" : "=a"(data) : "d"(port)); + __asm__ __volatile__( "inb %w1,%0" : "=a" (data) : "d" (port) ); return data; } -static inline uint16_t inw(int port) OPSINLINED + +static inline uint16_t +inw( int port ) OPSINLINED { uint16_t data; - __asm__ __volatile__("inw %w1,%0" : "=a"(data) : "d"(port)); + __asm__ __volatile__( "inw %w1,%0" : "=a" (data) : "d" (port) ); return data; } -static inline uint32_t inl(int port) OPSINLINED + +static inline uint32_t +inl( int port ) OPSINLINED { uint32_t data; - __asm__ __volatile__("inl %w1,%0" : "=a"(data) : "d"(port)); + __asm__ __volatile__( "inl %w1,%0" : "=a" (data) : "d" (port) ); return data; } @@ -316,17 +354,22 @@ static inline uint32_t inl(int port) OPSINLINED ** ** @return The data read from the specified port */ -static inline void outb(int port, uint8_t data) OPSINLINED +static inline void +outb( int port, uint8_t data ) OPSINLINED { - __asm__ __volatile__("outb %0,%w1" : : "a"(data), "d"(port)); + __asm__ __volatile__( "outb %0,%w1" : : "a" (data), "d" (port) ); } -static inline void outw(int port, uint16_t data) OPSINLINED + +static inline void +outw( int port, uint16_t data ) OPSINLINED { - __asm__ __volatile__("outw %0,%w1" : : "a"(data), "d"(port)); + __asm__ __volatile__( "outw %0,%w1" : : "a" (data), "d" (port) ); } -static inline void outl(int port, uint32_t data) OPSINLINED + +static inline void +outl( int port, uint32_t data ) OPSINLINED { - __asm__ __volatile__("outl %0,%w1" : : "a"(data), "d"(port)); + __asm__ __volatile__( "outl %0,%w1" : : "a" (data), "d" (port) ); } /**************************** @@ -338,9 +381,10 @@ static inline void outl(int port, uint32_t data) OPSINLINED ** ** Description: Cause a breakpoint interrupt for debugging purposes */ -static inline void breakpoint(void) OPSINLINED +static inline void +breakpoint( void ) OPSINLINED { - __asm__ __volatile__("int3"); + __asm__ __volatile__( "int3" ); } /** @@ -351,10 +395,11 @@ static inline void breakpoint(void) OPSINLINED ** ** @return The address the calling routine will return to as a uint32_t */ -static inline uint32_t get_ra(void) OPSINLINED +static inline uint32_t +get_ra( void ) OPSINLINED { uint32_t val; - __asm__ __volatile__("movl 4(%%ebp),%0" : "=r"(val)); + __asm__ __volatile__( "movl 4(%%ebp),%0" : "=r" (val) ); return val; } @@ -363,11 +408,13 @@ static inline uint32_t get_ra(void) OPSINLINED ** ** Description: Pause until something happens */ -static inline void ev_wait(void) OPSINLINED +static inline void +ev_wait( void ) OPSINLINED { - __asm__ __volatile__("sti ; hlt"); + __asm__ __volatile__( "sti ; hlt" ); } + /** ** Name: xchgl ** @@ -378,18 +425,19 @@ static inline void ev_wait(void) OPSINLINED ** ** @return The old contents of the memory location */ -static inline uint32_t xchgl(volatile uint32_t *addr, uint32_t data) OPSINLINED +static inline uint32_t +xchgl( volatile uint32_t *addr, uint32_t data ) OPSINLINED { uint32_t old; // + indicates a read-modify-write operand - __asm__ __volatile__("lock; xchgl %0, %1" - : "+m"(*addr), "=a"(old) - : "1"(data) - : "cc"); + __asm__ __volatile__( "lock; xchgl %0, %1" + : "+m" (*addr), "=a" (old) + : "1" (data) + : "cc"); return old; } -#endif /* !ASM_SRC */ +#endif /* !ASM_SRC */ #endif diff --git a/kernel/old/include/x86/pic.h b/kernel/old/include/x86/pic.h index ae3fe6c..d4fa93b 100644 --- a/kernel/old/include/x86/pic.h +++ b/kernel/old/include/x86/pic.h @@ -16,14 +16,15 @@ ** Our expected configuration is two PICs, with the secondary connected ** through the IRQ2 pin of the primary. */ + /* ** Port addresses for the command port and interrupt mask register port ** for both the primary and secondary PICs. */ -#define PIC1_CMD 0x20 // primary command -#define PIC1_DATA (PIC1_CMD + 1) // primary data / int mask register -#define PIC2_CMD 0xA0 // secondary command -#define PIC2_DATA (PIC2_CMD + 1) // secondary data / int mask register +#define PIC1_CMD 0x20 // primary command +#define PIC1_DATA (PIC1_CMD + 1) // primary data / int mask register +#define PIC2_CMD 0xA0 // secondary command +#define PIC2_DATA (PIC2_CMD + 1) // secondary data / int mask register /* ** Initialization Command Word (ICW) definitions @@ -41,96 +42,98 @@ ** PIC2_* defines are intended for the secondary PIC ** PIC_* defines are sent to both PICs */ + /* ** ICW1: initialization, send to command port */ -#define PIC_CW1_INIT 0x10 // start initialization sequence -#define PIC_CW1_NEED4 0x01 // ICW4 will also be set -#define PIC_CW1_SINGLE 0x02 // select single (vs. cascade) mode -#define PIC_CW1_INTVAL 0x04 // set call interval to 4 (vs. 8) -#define PIC_CW1_LEVEL 0x08 // use level-triggered mode (vs. edge) +#define PIC_CW1_INIT 0x10 // start initialization sequence +#define PIC_CW1_NEED4 0x01 // ICW4 will also be set +#define PIC_CW1_SINGLE 0x02 // select single (vs. cascade) mode +#define PIC_CW1_INTVAL 0x04 // set call interval to 4 (vs. 8) +#define PIC_CW1_LEVEL 0x08 // use level-triggered mode (vs. edge) /* ** ICW2: interrupt vector base offsets, send to data port */ -#define PIC1_CW2_VECBASE 0x20 // IRQ0 int vector number -#define PIC2_CW2_VECBASE 0x28 // IRQ8 int vector number +#define PIC1_CW2_VECBASE 0x20 // IRQ0 int vector number +#define PIC2_CW2_VECBASE 0x28 // IRQ8 int vector number /* ** ICW3: secondary::primary attachment, send to data port */ -#define PIC1_CW3_SEC_IRQ2 0x04 // bit mask: secondary is on pin 2 -#define PIC2_CW3_SEC_ID 0x02 // integer: secondary id +#define PIC1_CW3_SEC_IRQ2 0x04 // bit mask: secondary is on pin 2 +#define PIC2_CW3_SEC_ID 0x02 // integer: secondary id /* ** ICW4: operating mode, send to data port */ -#define PIC_CW4_PM86 0x01 // 8086 mode (vs. 8080/8085) -#define PIC_CW4_AUTOEOI 0x02 // do auto eoi's -#define PIC_CW4_UNBUF 0x00 // unbuffered mode -#define PIC_CW4_SEC_BUF 0x08 // put secondary in buffered mode -#define PIC_CW4_PRI_BUF 0x0C // put primary in buffered mode -#define PIC_CW4_SFNMODE 0x10 // "special fully nested" mode +#define PIC_CW4_PM86 0x01 // 8086 mode (vs. 8080/8085) +#define PIC_CW4_AUTOEOI 0x02 // do auto eoi's +#define PIC_CW4_UNBUF 0x00 // unbuffered mode +#define PIC_CW4_SEC_BUF 0x08 // put secondary in buffered mode +#define PIC_CW4_PRI_BUF 0x0C // put primary in buffered mode +#define PIC_CW4_SFNMODE 0x10 // "special fully nested" mode /* ** Operation Control Words (OCWs) ** ** After the init sequence, can send these */ + /* ** OCW1: interrupt mask; send to data port */ -#define PIC_MASK_NONE 0x00 // allow all interrupts -#define PIC_MASK_NO_IRQ0 0x01 // prevent IRQ0 interrupts -#define PIC_MASK_NO_IRQ1 0x02 // prevent IRQ1 interrupts -#define PIC_MASK_NO_IRQ2 0x04 // prevent IRQ2 interrupts -#define PIC_MASK_NO_IRQ3 0x08 // prevent IRQ3 interrupts -#define PIC_MASK_NO_IRQ4 0x10 // prevent IRQ4 interrupts -#define PIC_MASK_NO_IRQ5 0x20 // prevent IRQ5 interrupts -#define PIC_MASK_NO_IRQ6 0x40 // prevent IRQ6 interrupts -#define PIC_MASK_NO_IRQ7 0x80 // prevent IRQ7 interrupts -#define PIC_MASK_ALL 0xff // prevent all interrupts +#define PIC_MASK_NONE 0x00 // allow all interrupts +#define PIC_MASK_NO_IRQ0 0x01 // prevent IRQ0 interrupts +#define PIC_MASK_NO_IRQ1 0x02 // prevent IRQ1 interrupts +#define PIC_MASK_NO_IRQ2 0x04 // prevent IRQ2 interrupts +#define PIC_MASK_NO_IRQ3 0x08 // prevent IRQ3 interrupts +#define PIC_MASK_NO_IRQ4 0x10 // prevent IRQ4 interrupts +#define PIC_MASK_NO_IRQ5 0x20 // prevent IRQ5 interrupts +#define PIC_MASK_NO_IRQ6 0x40 // prevent IRQ6 interrupts +#define PIC_MASK_NO_IRQ7 0x80 // prevent IRQ7 interrupts +#define PIC_MASK_ALL 0xff // prevent all interrupts /* ** OCW2: EOI control, interrupt level; send to command port */ -#define PIC_LVL_0 0x00 // act on IRQ level 0 -#define PIC_LVL_1 0x01 // act on IRQ level 1 -#define PIC_LVL_2 0x02 // act on IRQ level 2 -#define PIC_LVL_3 0x03 // act on IRQ level 3 -#define PIC_LVL_4 0x04 // act on IRQ level 4 -#define PIC_LVL_5 0x05 // act on IRQ level 5 -#define PIC_LVL_6 0x06 // act on IRQ level 6 -#define PIC_LVL_7 0x07 // act on IRQ level 7 - -#define PIC_EOI_NON_SPEC 0x20 // non-specific EOI command -#define PIC_EOI PIC_EOI_NON_SPEC - -#define PIC_EOI_SPEC 0x60 // specific EOI command -#define PIC_SEOI PIC_EOI_SPEC -#define PIC_SEOI_LVL0 (PIC_EOI_SPEC | PIC_LVL_0) -#define PIC_SEOI_LVL1 (PIC_EOI_SPEC | PIC_LVL_1) -#define PIC_SEOI_LVL2 (PIC_EOI_SPEC | PIC_LVL_2) -#define PIC_SEOI_LVL3 (PIC_EOI_SPEC | PIC_LVL_3) -#define PIC_SEOI_LVL4 (PIC_EOI_SPEC | PIC_LVL_4) -#define PIC_SEOI_LVL5 (PIC_EOI_SPEC | PIC_LVL_5) -#define PIC_SEOI_LVL6 (PIC_EOI_SPEC | PIC_LVL_6) -#define PIC_SEOI_LVL7 (PIC_EOI_SPEC | PIC_LVL_7) - -#define PIC_EOI_ROT_NONSP 0xa0 // rotate on non-spec EOI cmd -#define PIC_EOI_SET_ROT_AUTO 0x80 // set "rotate in auto EOI mode" -#define PIC_EOI_CLR_ROT_AUTO 0x00 // clear "rotate in auto EOI mode" -#define PIC_EOI_ROT_SPEC 0xe0 // rotate on spec EOI cmd (+ level) -#define PIC_EOI_SET_PRIO 0xc0 // set priority (+ level) -#define PIC_EOI_NOP 0x40 // no operation +#define PIC_LVL_0 0x00 // act on IRQ level 0 +#define PIC_LVL_1 0x01 // act on IRQ level 1 +#define PIC_LVL_2 0x02 // act on IRQ level 2 +#define PIC_LVL_3 0x03 // act on IRQ level 3 +#define PIC_LVL_4 0x04 // act on IRQ level 4 +#define PIC_LVL_5 0x05 // act on IRQ level 5 +#define PIC_LVL_6 0x06 // act on IRQ level 6 +#define PIC_LVL_7 0x07 // act on IRQ level 7 + +#define PIC_EOI_NON_SPEC 0x20 // non-specific EOI command +# define PIC_EOI PIC_EOI_NON_SPEC + +#define PIC_EOI_SPEC 0x60 // specific EOI command +# define PIC_SEOI PIC_EOI_SPEC +# define PIC_SEOI_LVL0 (PIC_EOI_SPEC | PIC_LVL_0) +# define PIC_SEOI_LVL1 (PIC_EOI_SPEC | PIC_LVL_1) +# define PIC_SEOI_LVL2 (PIC_EOI_SPEC | PIC_LVL_2) +# define PIC_SEOI_LVL3 (PIC_EOI_SPEC | PIC_LVL_3) +# define PIC_SEOI_LVL4 (PIC_EOI_SPEC | PIC_LVL_4) +# define PIC_SEOI_LVL5 (PIC_EOI_SPEC | PIC_LVL_5) +# define PIC_SEOI_LVL6 (PIC_EOI_SPEC | PIC_LVL_6) +# define PIC_SEOI_LVL7 (PIC_EOI_SPEC | PIC_LVL_7) + +#define PIC_EOI_ROT_NONSP 0xa0 // rotate on non-spec EOI cmd +#define PIC_EOI_SET_ROT_AUTO 0x80 // set "rotate in auto EOI mode" +#define PIC_EOI_CLR_ROT_AUTO 0x00 // clear "rotate in auto EOI mode" +#define PIC_EOI_ROT_SPEC 0xe0 // rotate on spec EOI cmd (+ level) +#define PIC_EOI_SET_PRIO 0xc0 // set priority (+ level) +#define PIC_EOI_NOP 0x40 // no operation /* -** OCW3: read requests, special mask mode; send to command port +** OCW3: read requests, special mask mode; send to command port */ -#define PIC_READIRR 0x0a // read the IR register -#define PIC_READISR 0x0b // read the IS register -#define PIC_POLL 0x0c // poll -#define PIC_MASK_RESET 0x48 // reset special mask mode -#define PIC_MASK_SET 0x68 // set special mask mode +#define PIC_READIRR 0x0a // read the IR register +#define PIC_READISR 0x0b // read the IS register +#define PIC_POLL 0x0c // poll +#define PIC_MASK_RESET 0x48 // reset special mask mode +#define PIC_MASK_SET 0x68 // set special mask mode #endif diff --git a/kernel/old/include/x86/pit.h b/kernel/old/include/x86/pit.h index 0c54539..269fcec 100644 --- a/kernel/old/include/x86/pit.h +++ b/kernel/old/include/x86/pit.h @@ -12,6 +12,7 @@ #ifndef X86PIT_H_ #define X86PIT_H_ + /* ** Hardware timer (Intel 8254 Programmable Interval Timer) ** @@ -25,57 +26,57 @@ ** M - mode ** BCD - binary or BCD counter */ + /* Frequency settings */ -#define PIT_DEFAULT_TICKS_PER_SECOND 18 // actually 18.2065Hz -#define PIT_DEFAULT_MS_PER_TICK (1000 / PIT_DEFAULT_TICKS_PER_SECOND) -#define PIT_FREQ 1193182 // clock cycles/sec +#define PIT_DEFAULT_TICKS_PER_SECOND 18 // actually 18.2065Hz +#define PIT_DEFAULT_MS_PER_TICK (1000/PIT_DEFAULT_TICKS_PER_SECOND) +#define PIT_FREQ 1193182 // clock cycles/sec /* Port assignments */ -#define PIT_BASE_PORT 0x40 // I/O port for the timer -#define PIT_0_PORT (PIT_BASE_PORT) -#define PIT_1_PORT (PIT_BASE_PORT + 1) -#define PIT_2_PORT (PIT_BASE_PORT + 2) -#define PIT_CONTROL_PORT (PIT_BASE_PORT + 3) +#define PIT_BASE_PORT 0x40 // I/O port for the timer +# define PIT_0_PORT (PIT_BASE_PORT) +# define PIT_1_PORT (PIT_BASE_PORT+1) +# define PIT_2_PORT (PIT_BASE_PORT+2) +# define PIT_CONTROL_PORT (PIT_BASE_PORT+3) /* BCD field */ -#define PIT_USE_DECIMAL 0x00 // 16-bit binary counter (default) -#define PIT_USE_BCD 0x01 // BCD counter +#define PIT_USE_DECIMAL 0x00 // 16-bit binary counter (default) +#define PIT_USE_BCD 0x01 // BCD counter /* Timer modes */ -#define PIT_MODE_0 0x00 // int on terminal count -#define PIT_MODE_1 0x02 // one-shot -#define PIT_MODE_2 0x04 // divide-by-N -#define PIT_MODE_3 0x06 // square-wave -#define PIT_MODE_4 0x08 // software strobe -#define PIT_MODE_5 0x0a // hardware strobe +#define PIT_MODE_0 0x00 // int on terminal count +#define PIT_MODE_1 0x02 // one-shot +#define PIT_MODE_2 0x04 // divide-by-N +#define PIT_MODE_3 0x06 // square-wave +#define PIT_MODE_4 0x08 // software strobe +#define PIT_MODE_5 0x0a // hardware strobe /* Timer 0 settings */ -#define PIT_0_SELECT 0x00 // select timer 0 -#define PIT_0_LOAD 0x30 // load LSB, then MSB -#define PIT_0_NDIV PIT_MODE_2 // divide-by-N counter -#define PIT_0_SQUARE PIT_MODE_3 // square-wave mode -#define PIT_0_ENDSIGNAL 0x00 // assert OUT at end of count +#define PIT_0_SELECT 0x00 // select timer 0 +#define PIT_0_LOAD 0x30 // load LSB, then MSB +#define PIT_0_NDIV PIT_MODE_2 // divide-by-N counter +#define PIT_0_SQUARE PIT_MODE_3 // square-wave mode +#define PIT_0_ENDSIGNAL 0x00 // assert OUT at end of count /* Timer 1 settings */ -#define PIT_1_SELECT 0x40 // select timer 1 -#define PIT_1_READ 0x30 // read/load LSB then MSB -#define PIT_1_RATE 0x06 // square-wave, for USART +#define PIT_1_SELECT 0x40 // select timer 1 +#define PIT_1_READ 0x30 // read/load LSB then MSB +#define PIT_1_RATE 0x06 // square-wave, for USART /* Timer 2 settings */ -#define PIT_2_SELECT 0x80 // select timer 1 -#define PIT_2_READ 0x30 // read/load LSB then MSB -#define PIT_2_RATE 0x06 // square-wave, for USART +#define PIT_2_SELECT 0x80 // select timer 1 +#define PIT_2_READ 0x30 // read/load LSB then MSB +#define PIT_2_RATE 0x06 // square-wave, for USART /* Timer read-back */ - -#define PIT_READBACK 0xc0 // perform a read-back -#define PIT_RB_NOT_COUNT 0x20 // don't latch the count -#define PIT_RB_NOT_STATUS 0x10 // don't latch the status -#define PIT_RB_CHAN_2 0x08 // read back channel 2 -#define PIT_RB_CHAN_1 0x04 // read back channel 1 -#define PIT_RB_CHAN_0 0x02 // read back channel 0 -#define PIT_RB_ACCESS_MASK 0x30 // access mode field -#define PIT_RB_OP_MASK 0x0e // oper mode field -#define PIT_RB_BCD_MASK 0x01 // BCD mode field +#define PIT_READBACK 0xc0 // perform a read-back +#define PIT_RB_NOT_COUNT 0x20 // don't latch the count +#define PIT_RB_NOT_STATUS 0x10 // don't latch the status +#define PIT_RB_CHAN_2 0x08 // read back channel 2 +#define PIT_RB_CHAN_1 0x04 // read back channel 1 +#define PIT_RB_CHAN_0 0x02 // read back channel 0 +#define PIT_RB_ACCESS_MASK 0x30 // access mode field +#define PIT_RB_OP_MASK 0x0e // oper mode field +#define PIT_RB_BCD_MASK 0x01 // BCD mode field #endif diff --git a/kernel/old/include/x86/uart.h b/kernel/old/include/x86/uart.h index 293b7b7..0c6194b 100644 --- a/kernel/old/include/x86/uart.h +++ b/kernel/old/include/x86/uart.h @@ -20,7 +20,7 @@ */ #ifndef UART_H -#define UART_H +#define UART_H /********************************************************************* ***************************** I/O PORTS ****************************** @@ -29,14 +29,14 @@ /* ** Base port number assigned to the device */ -#define UA4_COM1_PORT 0x3f8 -#define UA4_COM2_PORT 0x2f8 -#define UA4_COM3_PORT 0x3e8 -#define UA4_COM4_PORT 0x2e8 +#define UA4_COM1_PORT 0x3f8 +#define UA4_COM2_PORT 0x2f8 +#define UA4_COM3_PORT 0x3e8 +#define UA4_COM4_PORT 0x2e8 // short name for the one we'll use -#define UA4_PORT UA4_COM1_PORT -#define UA5_PORT UA4_COM1_PORT +#define UA4_PORT UA4_COM1_PORT +#define UA5_PORT UA4_COM1_PORT /* ** Registers @@ -47,7 +47,7 @@ ** Index Register(s) ** ===== ========================================= ** 0 Receiver Data (RO), Transmitter Data (WO) -** 1 Interrupt Enable +** 1 Interrupt Enable ** 2 Interrupt ID (RO), FIFO Control (WO) ** 3 Line Control, Divisor Latch ** 4 Modem Control @@ -66,156 +66,157 @@ ** accessed (0 selects Line Control, 1 selects Divisor Latch), with the ** remaining bits selecting fields within the indicated register. */ + /* ** Receiver Data Register (read-only) */ -#define UA4_RXD (UA4_PORT + 0) -#define UA4_RX_DATA UA4_RXD +#define UA4_RXD (UA4_PORT+0) +# define UA4_RX_DATA UA4_RXD /* ** Transmitter Data Register (write-only) */ -#define UA4_TXD (UA4_PORT + 0) -#define UA4_TX_DATA UA4_TXD +#define UA4_TXD (UA4_PORT+0) +# define UA4_TX_DATA UA4_TXD /* ** Interrupt Enable Register */ -#define UA4_IER (UA4_PORT + 1) -#define UA4_INT_ENABLE_REG UA4_IER +#define UA4_IER (UA4_PORT+1) +# define UA4_INT_ENABLE_REG UA4_IER // fields -#define UA4_IER_RX_IE 0x01 // Rcvr High-Data-Level Int Enable -#define UA4_IER_TX_IE 0x02 // Xmitter Low-data-level Int Enable -#define UA4_IER_LS_IE 0x04 // Line Status Int Enable -#define UA4_IER_MS_IE 0x08 // Modem Status Int Enable +#define UA4_IER_RX_IE 0x01 // Rcvr High-Data-Level Int Enable +#define UA4_IER_TX_IE 0x02 // Xmitter Low-data-level Int Enable +#define UA4_IER_LS_IE 0x04 // Line Status Int Enable +#define UA4_IER_MS_IE 0x08 // Modem Status Int Enable // aliases -#define UA4_IER_RX_INT_ENABLE UA4_IER_RX_IE -#define UA4_IER_TX_INT_ENABLE UA4_IER_TX_IE -#define UA4_IER_LINE_STATUS_INT_ENABLE UA4_IER_LS_IE -#define UA4_IER_MODEM_STATUS_INT_ENABLE UA4_IER_MS_IE +#define UA4_IER_RX_INT_ENABLE UA4_IER_RX_IE +#define UA4_IER_TX_INT_ENABLE UA4_IER_TX_IE +#define UA4_IER_LINE_STATUS_INT_ENABLE UA4_IER_LS_IE +#define UA4_IER_MODEM_STATUS_INT_ENABLE UA4_IER_MS_IE /* ** Interrupt Identification Register (read-only) ** ** a.k.a. Event Identification Register */ -#define UA4_IIR (UA4_PORT + 2) -#define UA4_EVENT_ID UA4_IIR +#define UA4_IIR (UA4_PORT+2) +# define UA4_EVENT_ID UA4_IIR // fields -#define UA4_IIR_IPF 0x01 // Interrupt Pending flag +#define UA4_IIR_IPF 0x01 // Interrupt Pending flag -#define UA4_IIR_IPR_MASK 0x06 // Interrupt Priority mask -#define UA4_IIR_IPR0_MASK 0x02 // IPR bit 0 mask -#define UA4_IIR_IPR1_MASK 0x04 // IPR bit 1 mask +#define UA4_IIR_IPR_MASK 0x06 // Interrupt Priority mask +# define UA4_IIR_IPR0_MASK 0x02 // IPR bit 0 mask +# define UA4_IIR_IPR1_MASK 0x04 // IPR bit 1 mask -#define UA5_IIR_RXFT 0x08 // RX_FIFO Timeout -#define UA5_IIR_FEN0 0x40 // FIFOs Enabled -#define UA5_IIR_FEN1 0x80 // FIFOs Enabled +#define UA5_IIR_RXFT 0x08 // RX_FIFO Timeout +#define UA5_IIR_FEN0 0x40 // FIFOs Enabled +#define UA5_IIR_FEN1 0x80 // FIFOs Enabled // aliases -#define UA4_IIR_INT_PENDING UA4_IIR_IPF -#define UA4_IIR_INT_PRIORITY UA4_IIR_IPR -#define UA5_IIR_RX_FIFO_TIMEOUT UA5_IIR_RXFT -#define UA5_IIR_FIFO_ENABLED_0 UA5_IIR_FEN0 -#define UA5_IIR_FIFO_ENABLED_1 UA5_IIR_FEN1 +#define UA4_IIR_INT_PENDING UA4_IIR_IPF +#define UA4_IIR_INT_PRIORITY UA4_IIR_IPR +#define UA5_IIR_RX_FIFO_TIMEOUT UA5_IIR_RXFT +#define UA5_IIR_FIFO_ENABLED_0 UA5_IIR_FEN0 +#define UA5_IIR_FIFO_ENABLED_1 UA5_IIR_FEN1 // IIR interrupt priorities (four-bit values) -#define UA4_IIR_INT_PRI_MASK 0x0f // Mask for extracting int priority -#define UA4_IIR_NO_INT 0x01 // no interrupt -#define UA4_IIR_LINE_STATUS 0x06 // line status interrupt -#define UA4_IIR_RX 0x04 // Receiver High Data Level -#define UA5_IIR_RX_FIFO 0x0c // Receiver FIFO timeout (16550) -#define UA4_IIR_TX 0x02 // Transmitter Low Data level -#define UA4_IIR_MODEM_STATUS 0x00 // Modem Status +#define UA4_IIR_INT_PRI_MASK 0x0f // Mask for extracting int priority +# define UA4_IIR_NO_INT 0x01 // no interrupt +# define UA4_IIR_LINE_STATUS 0x06 // line status interrupt +# define UA4_IIR_RX 0x04 // Receiver High Data Level +# define UA5_IIR_RX_FIFO 0x0c // Receiver FIFO timeout (16550) +# define UA4_IIR_TX 0x02 // Transmitter Low Data level +# define UA4_IIR_MODEM_STATUS 0x00 // Modem Status // aliases -#define UA4_IIR_NO_INT_PENDING UA4_IIR_NO_INT -#define UA4_IIR_LINE_STATUS_INT_PENDING UA4_IIR_LINE_STATUS -#define UA4_IIR_RX_INT_PENDING UA4_IIR_RX -#define UA5_IIR_RX_FIFO_TIMEOUT_INT_PENDING UA5_IIR_RX_FIFO -#define UA4_IIR_TX_INT_PENDING UA4_IIR_TX -#define UA4_IIR_MODEM_STATUS_INT_PENDING UA4_IIR_MODEM_STATUS +#define UA4_IIR_NO_INT_PENDING UA4_IIR_NO_INT +#define UA4_IIR_LINE_STATUS_INT_PENDING UA4_IIR_LINE_STATUS +#define UA4_IIR_RX_INT_PENDING UA4_IIR_RX +#define UA5_IIR_RX_FIFO_TIMEOUT_INT_PENDING UA5_IIR_RX_FIFO +#define UA4_IIR_TX_INT_PENDING UA4_IIR_TX +#define UA4_IIR_MODEM_STATUS_INT_PENDING UA4_IIR_MODEM_STATUS /* ** FIFO Control Register (16550 only, write-only) */ -#define UA5_FCR (UA5_PORT + 2) -#define UA5_FIFO_CTL UA5_FCR - -#define UA5_FCR_FIFO_RESET 0x00 // Reset the FIFO -#define UA5_FCR_FIFO_EN 0x01 // FIFO Enable -#define UA5_FCR_RXSR 0x02 // Receiver Soft Reset -#define UA5_FCR_TXSR 0x04 // Transmitter Soft Reset - -#define UA5_FCR_TXFT_MASK 0x30 // TX_FIFO threshold level mask -#define UA5_FCR_TXFT0_MASK 0x10 // TXFT bit 0 mask -#define UA5_FCR_TXFT1_MASK 0x20 // TXFT bit 1 mask -#define UA5_FCR_TX_FIFO_1 0x00 // 1 char -#define UA5_FCR_TX_FIFO_3 0x10 // 3 char -#define UA5_FCR_TX_FIFO_9 0x20 // 9 char -#define UA5_FCR_TX_FIFO_13 0x30 // 13 char - -#define UA5_FCR_RXFT_MASK 0xc0 // RX_FIFO threshold level mask -#define UA5_FCR_RXFT0_MASK 0x40 // RXFT bit 0 mask -#define UA5_FCR_RXFT1_MASK 0x80 // RXFT bit 1 mask -#define UA5_FCR_RX_FIFO_1 0x00 // 1 char -#define UA5_FCR_RX_FIFO_4 0x40 // 4 char -#define UA5_FCR_RX_FIFO_8 0x80 // 8 char -#define UA5_FCR_RX_FIFO_14 0xc0 // 14 char +#define UA5_FCR (UA5_PORT+2) +# define UA5_FIFO_CTL UA5_FCR + +#define UA5_FCR_FIFO_RESET 0x00 // Reset the FIFO +#define UA5_FCR_FIFO_EN 0x01 // FIFO Enable +#define UA5_FCR_RXSR 0x02 // Receiver Soft Reset +#define UA5_FCR_TXSR 0x04 // Transmitter Soft Reset + +#define UA5_FCR_TXFT_MASK 0x30 // TX_FIFO threshold level mask +# define UA5_FCR_TXFT0_MASK 0x10 // TXFT bit 0 mask +# define UA5_FCR_TXFT1_MASK 0x20 // TXFT bit 1 mask +# define UA5_FCR_TX_FIFO_1 0x00 // 1 char +# define UA5_FCR_TX_FIFO_3 0x10 // 3 char +# define UA5_FCR_TX_FIFO_9 0x20 // 9 char +# define UA5_FCR_TX_FIFO_13 0x30 // 13 char + +#define UA5_FCR_RXFT_MASK 0xc0 // RX_FIFO threshold level mask +# define UA5_FCR_RXFT0_MASK 0x40 // RXFT bit 0 mask +# define UA5_FCR_RXFT1_MASK 0x80 // RXFT bit 1 mask +# define UA5_FCR_RX_FIFO_1 0x00 // 1 char +# define UA5_FCR_RX_FIFO_4 0x40 // 4 char +# define UA5_FCR_RX_FIFO_8 0x80 // 8 char +# define UA5_FCR_RX_FIFO_14 0xc0 // 14 char // aliases -#define UA5_FCR_FIFO_ENABLED UA5_FCR_FIFO_EN -#define UA5_FCR_RX_SOFT_RESET UA5_FCR_RXSR -#define UA5_FCR_TX_SOFT_RESET UA5_FCR_TXSR -#define UA5_FCR_TX_FIFO_1_CHAR UA5_FCR_TX_FIFO_1 -#define UA5_FCR_TX_FIFO_3_CHAR UA5_FCR_TX_FIFO_3 -#define UA5_FCR_TX_FIFO_9_CHAR UA5_FCR_TX_FIFO_9 -#define UA5_FCR_TX_FIFO_13_CHAR UA5_FCR_TX_FIFO_13 -#define UA5_FCR_RX_FIFO_1_CHAR UA5_FCR_RX_FIFO_1 -#define UA5_FCR_RX_FIFO_4_CHAR UA5_FCR_RX_FIFO_4 -#define UA5_FCR_RX_FIFO_8_CHAR UA5_FCR_RX_FIFO_8 -#define UA5_FCR_RX_FIFO_14_CHAR UA5_FCR_RX_FIFO_14 +#define UA5_FCR_FIFO_ENABLED UA5_FCR_FIFO_EN +#define UA5_FCR_RX_SOFT_RESET UA5_FCR_RXSR +#define UA5_FCR_TX_SOFT_RESET UA5_FCR_TXSR +#define UA5_FCR_TX_FIFO_1_CHAR UA5_FCR_TX_FIFO_1 +#define UA5_FCR_TX_FIFO_3_CHAR UA5_FCR_TX_FIFO_3 +#define UA5_FCR_TX_FIFO_9_CHAR UA5_FCR_TX_FIFO_9 +#define UA5_FCR_TX_FIFO_13_CHAR UA5_FCR_TX_FIFO_13 +#define UA5_FCR_RX_FIFO_1_CHAR UA5_FCR_RX_FIFO_1 +#define UA5_FCR_RX_FIFO_4_CHAR UA5_FCR_RX_FIFO_4 +#define UA5_FCR_RX_FIFO_8_CHAR UA5_FCR_RX_FIFO_8 +#define UA5_FCR_RX_FIFO_14_CHAR UA5_FCR_RX_FIFO_14 /* ** Line Control Register (available in all banks) ** ** Selected when bit 7 of the value written to the port is a 0. */ -#define UA4_LCR (UA4_PORT + 3) -#define UA4_LINE_CTL UA4_LCR - -#define UA4_LCR_WLS_MASK 0x03 // Word Length Select mask -#define UA4_LCR_WLS0_MASK 0x01 // WLS bit 0 mask -#define UA4_LCR_WLS1_MASK 0x02 // WLS bit 1 mask -#define UA4_LCR_WLS_5 0x00 // 5 bits per char -#define UA4_LCR_WLS_6 0x01 // 6 bits per char -#define UA4_LCR_WLS_7 0x02 // 7 bits per char -#define UA4_LCR_WLS_8 0x03 // 8 bits per char - -#define UA4_LCR_STB 0x04 // Stop Bits -#define UA4_LCR_1_STOP_BIT 0x00 -#define UA4_LCR_2_STOP_BIT 0x04 - -#define UA4_LCR_PEN 0x08 // Parity Enable -#define UA4_LCR_EPS 0x10 // Even Parity Select -#define UA4_LCR_STKP 0x20 // Sticky Parity -#define UA4_LCR_NO_PARITY 0x00 -#define UA4_LCR_ODD_PARITY UA4_LCR_PEN -#define UA4_LCR_EVEN_PARITY (UA4_LCR_PEN | UA4_LCR_EPS) -#define UA4_LCR_PARITY_LOGIC_1 (UA4_LCR_PEN | UA4_LCR_STKP) -#define UA4_LCR_PARITY_LOGIC_0 (UA4_LCR_PEN | UA4_LCR_EPS | UA4_LCR_STKP) - -#define UA4_LCR_SBRK 0x40 // Set Break -#define UA4_LCR_DLAB 0x80 // Divisor Latch select bit +#define UA4_LCR (UA4_PORT+3) +# define UA4_LINE_CTL UA4_LCR + +#define UA4_LCR_WLS_MASK 0x03 // Word Length Select mask +# define UA4_LCR_WLS0_MASK 0x01 // WLS bit 0 mask +# define UA4_LCR_WLS1_MASK 0x02 // WLS bit 1 mask +# define UA4_LCR_WLS_5 0x00 // 5 bits per char +# define UA4_LCR_WLS_6 0x01 // 6 bits per char +# define UA4_LCR_WLS_7 0x02 // 7 bits per char +# define UA4_LCR_WLS_8 0x03 // 8 bits per char + +#define UA4_LCR_STB 0x04 // Stop Bits +# define UA4_LCR_1_STOP_BIT 0x00 +# define UA4_LCR_2_STOP_BIT 0x04 + +#define UA4_LCR_PEN 0x08 // Parity Enable +#define UA4_LCR_EPS 0x10 // Even Parity Select +#define UA4_LCR_STKP 0x20 // Sticky Parity +# define UA4_LCR_NO_PARITY 0x00 +# define UA4_LCR_ODD_PARITY UA4_LCR_PEN +# define UA4_LCR_EVEN_PARITY (UA4_LCR_PEN|UA4_LCR_EPS) +# define UA4_LCR_PARITY_LOGIC_1 (UA4_LCR_PEN|UA4_LCR_STKP) +# define UA4_LCR_PARITY_LOGIC_0 (UA4_LCR_PEN|UA4_LCR_EPS|UA4_LCR_STKP) + +#define UA4_LCR_SBRK 0x40 // Set Break +#define UA4_LCR_DLAB 0x80 // Divisor Latch select bit // aliases -#define UA4_LCR_STOP_BITS UA4_LCR_STB -#define UA4_LCR_PARITY_ENABLE UA4_LCR_PEN -#define UA4_LCR_SET_BREAK UA4_LCR_SBRK -#define UA4_LCR_BANK_SELECT_ENABLE UA4_LCR_BKSE +# define UA4_LCR_STOP_BITS UA4_LCR_STB +# define UA4_LCR_PARITY_ENABLE UA4_LCR_PEN +# define UA4_LCR_SET_BREAK UA4_LCR_SBRK +# define UA4_LCR_BANK_SELECT_ENABLE UA4_LCR_BKSE /* ** Divisor Latch Registers @@ -232,109 +233,109 @@ ** "re-lock" the Divisor Latch registers, write a command byte to ** LCR with 0 in the DLAB bit. */ -#define UA4_DLL (UA4_PORT + 0) // Divisor Latch (least sig.) -#define UA4_DLM (UA4_PORT + 1) // Divisor Latch (most sig.) +#define UA4_DLL (UA4_PORT+0) // Divisor Latch (least sig.) +#define UA4_DLM (UA4_PORT+1) // Divisor Latch (most sig.) // aliases -#define UA4_DIVISOR_LATCH_LS UA4_DLL -#define UA4_DIVISOR_LATCH_MS UA4_DLM +#define UA4_DIVISOR_LATCH_LS UA4_DLL +#define UA4_DIVISOR_LATCH_MS UA4_DLM // Baud rate divisor high and low bytes -#define BAUD_HIGH_BYTE(x) (((x) >> 8) & 0xff) -#define BAUD_LOW_BYTE(x) ((x) & 0xff) +#define BAUD_HIGH_BYTE(x) (((x) >> 8) & 0xff) +#define BAUD_LOW_BYTE(x) ((x) & 0xff) // Baud rate divisors -#define DL_BAUD_50 2304 -#define DL_BAUD_75 1536 -#define DL_BAUD_110 1047 -#define DL_BAUD_150 768 -#define DL_BAUD_300 384 -#define DL_BAUD_600 192 -#define DL_BAUD_1200 96 -#define DL_BAUD_1800 64 -#define DL_BAUD_2000 58 -#define DL_BAUD_2400 48 -#define DL_BAUD_3600 32 -#define DL_BAUD_4800 24 -#define DL_BAUD_7200 16 -#define DL_BAUD_9600 12 -#define DL_BAUD_14400 8 -#define DL_BAUD_19200 6 -#define DL_BAUD_28800 4 -#define DL_BAUD_38400 3 -#define DL_BAUD_57600 2 -#define DL_BAUD_115200 1 +#define DL_BAUD_50 2304 +#define DL_BAUD_75 1536 +#define DL_BAUD_110 1047 +#define DL_BAUD_150 768 +#define DL_BAUD_300 384 +#define DL_BAUD_600 192 +#define DL_BAUD_1200 96 +#define DL_BAUD_1800 64 +#define DL_BAUD_2000 58 +#define DL_BAUD_2400 48 +#define DL_BAUD_3600 32 +#define DL_BAUD_4800 24 +#define DL_BAUD_7200 16 +#define DL_BAUD_9600 12 +#define DL_BAUD_14400 8 +#define DL_BAUD_19200 6 +#define DL_BAUD_28800 4 +#define DL_BAUD_38400 3 +#define DL_BAUD_57600 2 +#define DL_BAUD_115200 1 /* ** Modem Control Register */ -#define UA4_MCR (UA4_PORT + 4) -#define UA4_MODEM_CTL UA4_MCR +#define UA4_MCR (UA4_PORT+4) +# define UA4_MODEM_CTL UA4_MCR -#define UA4_MCR_DTR 0x01 // Data Terminal Ready -#define UA4_MCR_RTS 0x02 // Ready to Send -#define UA4_MCR_RILP 0x04 // Loopback Interrupt Request -#define UA4_MCR_ISEN 0x08 // Interrupt Signal Enable -#define UA4_MCR_DCDLP 0x08 // DCD Loopback -#define UA4_MCR_LOOP 0x10 // Loopback Enable +#define UA4_MCR_DTR 0x01 // Data Terminal Ready +#define UA4_MCR_RTS 0x02 // Ready to Send +#define UA4_MCR_RILP 0x04 // Loopback Interrupt Request +#define UA4_MCR_ISEN 0x08 // Interrupt Signal Enable +#define UA4_MCR_DCDLP 0x08 // DCD Loopback +#define UA4_MCR_LOOP 0x10 // Loopback Enable // aliases -#define UA4_MCR_DATA_TERMINAL_READY UA4_MCR_DTR -#define UA4_MCR_READY_TO_SEND UA4_MCR_RTS -#define UA4_MCR_LOOPBACK_INT_REQ UA4_MCR_RILP -#define UA4_MCR_INT_SIGNAL_ENABLE UA4_MCR_ISEN -#define UA4_MCR_LOOPBACK_DCD UA4_MCR_DCDLP -#define UA4_MCR_LOOPBACK_ENABLE UA4_MCR_LOOP +#define UA4_MCR_DATA_TERMINAL_READY UA4_MCR_DTR +#define UA4_MCR_READY_TO_SEND UA4_MCR_RTS +#define UA4_MCR_LOOPBACK_INT_REQ UA4_MCR_RILP +#define UA4_MCR_INT_SIGNAL_ENABLE UA4_MCR_ISEN +#define UA4_MCR_LOOPBACK_DCD UA4_MCR_DCDLP +#define UA4_MCR_LOOPBACK_ENABLE UA4_MCR_LOOP /* ** Line Status Register */ -#define UA4_LSR (UA4_PORT + 5) -#define UA4_LINE_STATUS UA4_LSR - -#define UA4_LSR_RXDA 0x01 // Receiver Data Available -#define UA4_LSR_OE 0x02 // Overrun Error -#define UA4_LSR_PE 0x04 // Parity Error -#define UA4_LSR_FE 0x08 // Framing Error -#define UA4_LSR_BRK 0x10 // Break Event Detected -#define UA4_LSR_TXRDY 0x20 // Transmitter Ready -#define UA4_LSR_TXEMP 0x40 // Transmitter Empty -#define UA4_LSR_ER_INF 0x80 // Error in RX_FIFO +#define UA4_LSR (UA4_PORT+5) +# define UA4_LINE_STATUS UA4_LSR + +#define UA4_LSR_RXDA 0x01 // Receiver Data Available +#define UA4_LSR_OE 0x02 // Overrun Error +#define UA4_LSR_PE 0x04 // Parity Error +#define UA4_LSR_FE 0x08 // Framing Error +#define UA4_LSR_BRK 0x10 // Break Event Detected +#define UA4_LSR_TXRDY 0x20 // Transmitter Ready +#define UA4_LSR_TXEMP 0x40 // Transmitter Empty +#define UA4_LSR_ER_INF 0x80 // Error in RX_FIFO // aliases -#define UA4_LSR_RX_DATA_AVAILABLE UA4_LSR_RXDA -#define UA4_LSR_OVERRUN_ERROR UA4_LSR_OE -#define UA4_LSR_PARITY_ERROR UA4_LSR_PE -#define UA4_LSR_FRAMING_ERROR UA4_LSR_FE -#define UA4_LSR_BREAK_DETECTED UA4_LSR_BRK -#define UA4_LSR_TX_READY UA4_LSR_TXRDY -#define UA4_LSR_TX_EMPTY UA4_LSR_TXEMP -#define UA4_LSR_RX_FIFO_ERROR UA4_LSR_ER_INF +#define UA4_LSR_RX_DATA_AVAILABLE UA4_LSR_RXDA +#define UA4_LSR_OVERRUN_ERROR UA4_LSR_OE +#define UA4_LSR_PARITY_ERROR UA4_LSR_PE +#define UA4_LSR_FRAMING_ERROR UA4_LSR_FE +#define UA4_LSR_BREAK_DETECTED UA4_LSR_BRK +#define UA4_LSR_TX_READY UA4_LSR_TXRDY +#define UA4_LSR_TX_EMPTY UA4_LSR_TXEMP +#define UA4_LSR_RX_FIFO_ERROR UA4_LSR_ER_INF /* ** Modem Status Register */ -#define UA4_MSR (UA4_PORT + 6) -#define UA4_MODEM_STATUS UA4_MSR - -#define UA4_MSR_DCTS 0x01 // Delta Clear to Send -#define UA4_MSR_DDSR 0x02 // Delta Data Set Ready -#define UA4_MSR_TERI 0x04 // Trailing Edge Ring Indicate -#define UA4_MSR_DDCD 0x08 // Delta Data Carrier Detect -#define UA4_MSR_CTS 0x10 // Clear to Send -#define UA4_MSR_DSR 0x20 // Data Set Ready -#define UA4_MSR_RI 0x40 // Ring Indicate -#define UA4_MSR_DCD 0x80 // Data Carrier Detect +#define UA4_MSR (UA4_PORT+6) +# define UA4_MODEM_STATUS UA4_MSR + +#define UA4_MSR_DCTS 0x01 // Delta Clear to Send +#define UA4_MSR_DDSR 0x02 // Delta Data Set Ready +#define UA4_MSR_TERI 0x04 // Trailing Edge Ring Indicate +#define UA4_MSR_DDCD 0x08 // Delta Data Carrier Detect +#define UA4_MSR_CTS 0x10 // Clear to Send +#define UA4_MSR_DSR 0x20 // Data Set Ready +#define UA4_MSR_RI 0x40 // Ring Indicate +#define UA4_MSR_DCD 0x80 // Data Carrier Detect // aliases -#define UA4_MSR_DELTA_CLEAR_TO_SEND UA4_MSR_DCTS -#define UA4_MSR_DELTA_DATA_SET_READY UA4_MSR_DDSR -#define UA4_MSR_TRAILING_EDGE_RING UA4_MSR_TERI -#define UA4_MSR_DELTA_DATA_CARRIER_DETECT UA4_MSR_DDCD -#define UA4_MSR_CLEAR_TO_SEND UA4_MSR_CTS -#define UA4_MSR_DATA_SET_READY UA4_MSR_DSR -#define UA4_MSR_RING_INDICATE UA4_MSR_RI -#define UA4_MSR_DATA_CARRIER_DETECT UA4_MSR_DCD +#define UA4_MSR_DELTA_CLEAR_TO_SEND UA4_MSR_DCTS +#define UA4_MSR_DELTA_DATA_SET_READY UA4_MSR_DDSR +#define UA4_MSR_TRAILING_EDGE_RING UA4_MSR_TERI +#define UA4_MSR_DELTA_DATA_CARRIER_DETECT UA4_MSR_DDCD +#define UA4_MSR_CLEAR_TO_SEND UA4_MSR_CTS +#define UA4_MSR_DATA_SET_READY UA4_MSR_DSR +#define UA4_MSR_RING_INDICATE UA4_MSR_RI +#define UA4_MSR_DATA_CARRIER_DETECT UA4_MSR_DCD /* ** Scratch Register @@ -342,7 +343,7 @@ ** Not used by the UART; usable as a "scratchpad" register for ** temporary storage. */ -#define UA4_SCR (UA4_PORT + 7) -#define UA4_SCRATCH UA4_UA5_SCR +#define UA4_SCR (UA4_PORT+7) +# define UA4_SCRATCH UA4_UA5_SCR -#endif /* uart.h */ +#endif /* uart.h */ diff --git a/kernel/old/isrs.S b/kernel/old/isrs.S index f5fdbca..f6bd662 100644 --- a/kernel/old/isrs.S +++ b/kernel/old/isrs.S @@ -19,8 +19,6 @@ # .arch i386 #include -#include -#include /* ** Configuration options - define in Makefile @@ -102,8 +100,8 @@ isr_save: ** ** Set up parameters for the ISR call. */ - movl CTX_vector(%esp),%eax // get vector number and error code - movl CTX_code(%esp),%ebx + movl 52(%esp),%eax // get vector number and error code + movl 56(%esp),%ebx /* *********************** @@ -122,12 +120,11 @@ isr_save: // save the context pointer movl current, %edx - movl %esp, PCB_context(%edx) + movl %esp, (%edx) // also save the page directory pointer movl %cr3, %ecx - addl $KERN_BASE, %ecx // convert to a virtual address - movl %ecx, PCB_pdir(%edx) + movl %ecx, 4(%edx) // switch to the system stack // @@ -169,9 +166,8 @@ isr_restore: *********************** */ movl current, %ebx // return to the user stack - movl PCB_context(%ebx), %esp // ESP --> context save area - movl PCB_pdir(%ebx), %ecx // page directory pointer - subl $KERN_BASE, %ecx // convert to a physical address + movl (%ebx), %esp // ESP --> context save area + movl 4(%ebx), %ecx // page directory pointer movl %ecx, %cr3 // now we're operating with the user process' @@ -187,7 +183,7 @@ isr_restore: /* ** DEBUGGING CODE PART 1 ** -** This code will execute during each context restore, and +** This code will execute during each context restore, and ** should be modified to print out whatever debugging information ** is desired. ** diff --git a/kernel/old/kernel.c b/kernel/old/kernel.c index ce2e9dd..14e8b02 100644 --- a/kernel/old/kernel.c +++ b/kernel/old/kernel.c @@ -6,7 +6,7 @@ ** @brief Kernel support routines */ -#define KERNEL_SRC +#define KERNEL_SRC #include #include @@ -37,8 +37,8 @@ // character buffers, usable throughout the OS // nto guaranteed to retain their contents across an exception return -char b256[256]; // primarily used for message creation -char b512[512]; // used by PANIC macro +char b256[256]; // primarily used for message creation +char b512[512]; // used by PANIC macro /* ** PRIVATE FUNCTIONS @@ -55,117 +55,119 @@ char b512[512]; // used by PANIC macro ** ** @param dtrace Decode the TRACE options */ -static void kreport(bool_t dtrace) -{ - cio_puts("\n-------------------------------\n"); - cio_printf("Config: N_PROCS = %d", N_PROCS); - cio_printf(" N_PRIOS = %d", N_PRIOS); - cio_printf(" N_STATES = %d", N_STATES); - cio_printf(" CLOCK = %dHz\n", CLOCK_FREQ); +static void kreport( bool_t dtrace ) { + + cio_puts( "\n-------------------------------\n" ); + cio_printf( "Config: N_PROCS = %d", N_PROCS ); + cio_printf( " N_PRIOS = %d", N_PRIOS ); + cio_printf( " N_STATES = %d", N_STATES ); + cio_printf( " CLOCK = %dHz\n", CLOCK_FREQ ); // This code is ugly, but it's the simplest way to // print out the values of compile-time options // without spending a lot of execution time at it. - cio_puts("Options: " + cio_puts( "Options: " #ifdef RPT_INT_UNEXP - " R-uint" + " R-uint" #endif #ifdef RPT_INT_MYSTERY - " R-mint" + " R-mint" #endif #ifdef TRACE_CX - " CX" + " CX" #endif #ifdef CONSOLE_STATS - " Cstats" + " Cstats" #endif - ); // end of cio_puts() call + ); // end of cio_puts() call #ifdef SANITY - cio_printf(" SANITY = %d", SANITY); + cio_printf( " SANITY = %d", SANITY ); #endif #ifdef STATUS - cio_printf(" STATUS = %d", STATUS); + cio_printf( " STATUS = %d", STATUS ); #endif #if TRACE > 0 - cio_printf(" TRACE = 0x%04x\n", TRACE); + cio_printf( " TRACE = 0x%04x\n", TRACE ); // decode the trace settings if that was requested - if (TRACING_SOMETHING && dtrace) { + if( TRACING_SOMETHING && dtrace ) { + // this one is simpler - we rely on string literal // concatenation in the C compiler to create one // long string to print out - cio_puts("Tracing:" + cio_puts( "Tracing:" #if TRACING_PCB - " PCB" + " PCB" #endif #if TRACING_VM - " VM" + " VM" #endif #if TRACING_QUEUE - " QUE" + " QUE" #endif #if TRACING_SCHED - " SCHED" + " SCHED" #endif #if TRACING_DISPATCH - " DISPATCH" + " DISPATCH" #endif #if TRACING_SYSCALLS - " SCALL" + " SCALL" #endif #if TRACING_SYSRETS - " SRET" + " SRET" #endif #if TRACING_EXIT - " EXIT" + " EXIT" #endif #if TRACING_INIT - " INIT" + " INIT" #endif #if TRACING_KMEM - " KM" + " KM" #endif #if TRACING_KMEM_FREELIST - " KMFL" + " KMFL" #endif #if TRACING_KMEM_INIT - " KMIN" + " KMIN" #endif #if TRACING_FORK - " FORK" + " FORK" #endif #if TRACING_EXEC - " EXEC" + " EXEC" #endif #if TRACING_SIO_STAT - " S_STAT" + " S_STAT" #endif #if TRACING_SIO_ISR - " S_ISR" + " S_ISR" #endif #if TRACING_SIO_RD - " S_RD" + " S_RD" #endif #if TRACING_SIO_WR - " S_WR" + " S_WR" #endif #if TRACING_USER - " USER" + " USER" #endif #if TRACING_ELF - " ELF" + " ELF" #endif - ); // end of cio_puts() call + ); // end of cio_puts() call } -#endif /* TRACE > 0 */ +#endif /* TRACE > 0 */ - cio_putchar('\n'); + cio_puts( "\n-------------------------------\n" ); } + #if defined(CONSOLE_STATS) /** ** stats - callback routine for console statistics @@ -177,51 +179,53 @@ static void kreport(bool_t dtrace) ** ** This code runs as part of the CIO ISR. */ -static void stats(int code) -{ - switch (code) { - case 'a': // dump the active table - ptable_dump("\nActive processes", false); +static void stats( int code ) { + + switch( code ) { + + case 'a': // dump the active table + ptable_dump( "\nActive processes", false ); break; - case 'c': // dump context info for all active PCBs - ctx_dump_all("\nContext dump"); + case 'c': // dump context info for all active PCBs + ctx_dump_all( "\nContext dump" ); break; - case 'p': // dump the active table and all PCBs - ptable_dump("\nActive processes", true); + case 'p': // dump the active table and all PCBs + ptable_dump( "\nActive processes", true ); break; - case 'q': // dump the queues + case 'q': // dump the queues // code to dump out any/all queues - pcb_queue_dump("R", ready, true); - pcb_queue_dump("W", waiting, true); - pcb_queue_dump("S", sleeping, true); - pcb_queue_dump("Z", zombie, true); - pcb_queue_dump("I", sioread, true); + pcb_queue_dump( "R", ready ); + pcb_queue_dump( "W", waiting ); + pcb_queue_dump( "S", sleeping ); + pcb_queue_dump( "Z", zombie ); + pcb_queue_dump( "I", sioread ); break; - case 'r': // print system configuration information - report(true); + case 'r': // print system configuration information + report( true ); break; // ignore CR and LF case '\r': // FALL THROUGH case '\n': break; - + default: - cio_printf("console: unknown request '0x%02x'\n", code); + cio_printf( "console: unknown request '0x%02x'\n", code ); // FALL THROUGH - case 'h': // help message - cio_puts("\nCommands:\n" - " a -- dump the active table\n" - " c -- dump contexts for active processes\n" - " h -- this message\n" - " p -- dump the active table and all PCBs\n" - " q -- dump the queues\n" - " r -- print system configuration\n"); + case 'h': // help message + cio_puts( "\nCommands:\n" + " a -- dump the active table\n" + " c -- dump contexts for active processes\n" + " h -- this message\n" + " p -- dump the active table and all PCBs\n" + " q -- dump the queues\n" + " r -- print system configuration\n" + ); break; } } @@ -239,15 +243,15 @@ static void stats(int code) ** ** Making this type 'int' keeps the compiler happy. */ -int main(void) -{ +int main( void ) { + /* ** BOILERPLATE CODE - taken from basic framework ** ** Initialize interrupt stuff. */ - init_interrupts(); // IDT and PIC initialization + init_interrupts(); // IDT and PIC initialization /* ** Console I/O system. @@ -257,13 +261,13 @@ int main(void) ** and queue modules. */ -#if defined(CONSOLE_STATS) - cio_init(stats); +#if defined(CONSOLE_STATS) + cio_init( stats ); #else - cio_init(NULL); // no console callback routine + cio_init( NULL ); // no console callback routine #endif - cio_clearscreen(); // wipe out whatever is there + cio_clearscreen(); // wipe out whatever is there /* ** TERM-SPECIFIC CODE STARTS HERE @@ -276,40 +280,40 @@ int main(void) ** install their own ISRs in their initialization routines. */ - cio_puts("System initialization starting.\n"); - cio_puts("-------------------------------\n"); + cio_puts( "System initialization starting.\n" ); + cio_puts( "-------------------------------\n" ); - cio_puts("Modules:"); + cio_puts( "Modules:" ); // call the module initialization functions, being // careful to follow any module precedence requirements - km_init(); // MUST BE FIRST + km_init(); // MUST BE FIRST #if TRACING_KMEM || TRACING_KMEM_FREE - delay(DELAY_2_SEC); // approximately + delay( DELAY_2_SEC ); // approximately #endif // other module initialization calls here - clk_init(); // clock - pcb_init(); // process (PCBs, queues, scheduler) + clk_init(); // clock + pcb_init(); // process (PCBs, queues, scheduler) #if TRACING_PCB - delay(DELAY_2_SEC); + delay( DELAY_2_SEC ); #endif - sio_init(); // serial i/o - sys_init(); // system call + sio_init(); // serial i/o + sys_init(); // system call #if TRACING_SYSCALLS || TRACING_SYSRETS - delay(DELAY_2_SEC); + delay( DELAY_2_SEC ); #endif - vm_init(); // virtual memory - user_init(); // user code handling + vm_init(); // virtual memory + user_init(); // user code handling - cio_puts("\nModule initialization complete.\n"); + cio_puts( "\nModule initialization complete.\n" ); + cio_puts( "-------------------------------\n" ); // report our configuration options - kreport(true); - cio_puts("-------------------------------\n"); + kreport( true ); - delay(DELAY_2_SEC); + delay( DELAY_3_SEC ); /* ** Other tasks typically performed here: @@ -319,14 +323,14 @@ int main(void) /* ** Create the initial user process - ** + ** ** This code is largely stolen from the fork() and exec() ** implementations in syscalls.c; if those change, this must ** also change. */ // if we can't get a PCB, there's no use continuing! - assert(pcb_alloc(&init_pcb) == SUCCESS); + assert( pcb_alloc(&init_pcb) == SUCCESS ); // fill in the necessary details init_pcb->pid = PID_INIT; @@ -334,67 +338,47 @@ int main(void) init_pcb->priority = PRIO_HIGH; // find the 'init' program - prog_t *prog = user_locate(Init); - assert(prog != NULL); + prog_t *prog = user_locate( Init ); + assert( prog != NULL ); // command-line arguments for 'init' const char *args[2] = { "init", NULL }; // load it - assert(user_load(prog, init_pcb, args, true) == SUCCESS); + assert( user_load(prog,init_pcb,args) == SUCCESS ); // send it on its merry way - schedule(init_pcb); - dispatch(); + schedule( init_pcb ); #ifdef TRACE_CX // if we're using a scrolling region, wait a bit more and then set it up - delay(DELAY_7_SEC); + delay( DELAY_7_SEC ); // define a scrolling region in the top 7 lines of the screen - cio_setscroll(0, 7, 99, 99); + cio_setscroll( 0, 7, 99, 99 ); // clear it cio_clearscroll(); // clear the top line - cio_puts_at( - 0, 0, - "* "); + cio_puts_at( 0, 0, "* " ); // separator - cio_puts_at( - 0, 6, - "================================================================================"); + cio_puts_at( 0, 6, "================================================================================" ); #endif + // switch to the "real" kernel page directory + vm_set_kvm(); + /* ** END OF TERM-SPECIFIC CODE ** ** Finally, report that we're all done. */ - cio_puts("System initialization complete.\n"); - cio_puts("-------------------------------\n"); - - sio_enable(SIO_RX); - -#if 0 - // produce a "system state" report - cio_puts( "System status: Queues " ); - pcb_queue_dump( "R", ready, true ); - pcb_queue_dump( "W", waiting, true ); - pcb_queue_dump( "S", sleeping, true ); - pcb_queue_dump( "Z", zombie, true ); - pcb_queue_dump( "I", sioread, true ); - ptable_dump_counts(); - pcb_dump( "Current: ", current, true ); + cio_puts( "System initialization complete.\n" ); + cio_puts( "-------------------------------\n" ); - delay( DELAY_3_SEC ); - - vm_print( current->pdir, true, TwoLevel ); - - delay( DELAY_3_SEC ); -#endif + sio_enable( SIO_RX ); return 0; } diff --git a/kernel/old/kernel.ld b/kernel/old/kernel.ld new file mode 100644 index 0000000..1534aad --- /dev/null +++ b/kernel/old/kernel.ld @@ -0,0 +1,71 @@ +/* +** Simple linker script for the 20245 kernel. +*/ + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +SECTIONS +{ + /* Link the kernel at this address. */ + /* Must match what is defined in vm.h! */ + . = 0x80010000; + + .text : AT(0x10000) { + *(.text .stub .text.* .gnu.linkonce.t.*) + } + + /* standard symbols */ + PROVIDE(etext = .); + PROVIDE(_etext = .); + + /* put read-only data next */ + .rodata : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + } + + /* Could put STABs here */ + .stab : { + PROVIDE(__STAB_BEGIN__ = .); + *(.stab); + PROVIDE(__STAB_END__ = .); + } + .stabstr : { + PROVIDE(__STABSTR_BEGIN__ = .); + *(.stabstr); + PROVIDE(__STABSTR_END__ = .); + } + + /* Align the data segment at the next page boundary */ + . = ALIGN(0x1000); + + PROVIDE(data = .); + PROVIDE(_data = .); + + /* The data segment */ + .data : { + *(.data .data.*) + } + + PROVIDE(edata = .); + PROVIDE(_edata = .); + + /* page-align the BSS */ + . = ALIGN(0x1000); + + PROVIDE(__bss_start = .); + + .bss : { + *(.bss .bss.*) + *(COMMON) + } + + PROVIDE(end = .); + PROVIDE(_end = .); + + /DISCARD/ : { + /* *(.stab .stab_info .stabstr) */ + *(.eh_frame .note.GNU-stack .note.gnu.property .comment) + } +} diff --git a/kernel/old/kmem.c b/kernel/old/kmem.c index fe0c7de..febc6b9 100644 --- a/kernel/old/kmem.c +++ b/kernel/old/kmem.c @@ -69,22 +69,22 @@ */ // combination tracing tests -#define ANY_KMEM (TRACING_KMEM | TRACING_KMEM_INIT | TRACING_KMEM_FREELIST) -#define KMEM_OR_INIT (TRACING_KMEM | TRACING_KMEM_INIT) +#define ANY_KMEM (TRACING_KMEM|TRACING_KMEM_INIT|TRACING_KMEM_FREELIST) +#define KMEM_OR_INIT (TRACING_KMEM|TRACING_KMEM_INIT) // parameters related to word and block sizes -#define WORD_SIZE sizeof(int) -#define LOG2_OF_WORD_SIZE 2 +#define WORD_SIZE sizeof(int) +#define LOG2_OF_WORD_SIZE 2 -#define LOG2_OF_PAGE_SIZE 12 +#define LOG2_OF_PAGE_SIZE 12 -#define LOG2_OF_SLICE_SIZE 10 +#define LOG2_OF_SLICE_SIZE 10 // converters: pages to bytes, bytes to pages -#define P2B(x) ((x) << LOG2_OF_PAGE_SIZE) -#define B2P(x) ((x) >> LOG2_OF_PAGE_SIZE) +#define P2B(x) ((x) << LOG2_OF_PAGE_SIZE) +#define B2P(x) ((x) >> LOG2_OF_PAGE_SIZE) /* ** Name: adjacent @@ -94,8 +94,8 @@ ** Description: Determines whether the second block immediately ** follows the first one. */ -#define adjacent(first, second) \ - ((void *)(first) + P2B((first)->pages) == (void *)(second)) +#define adjacent(first,second) \ + ( (void *) (first) + P2B((first)->pages) == (void *) (second) ) /* ** PRIVATE DATA TYPES @@ -115,44 +115,44 @@ typedef union b64_u { } b64_t; // the halves of a 64-bit address -#define LOW part[0] -#define HIGH part[1] +#define LOW part[0] +#define HIGH part[1] // memory region descriptor typedef struct memregion_s { - b64_t base; // base address - b64_t length; // region length - uint32_t type; // type of region - uint32_t acpi; // ACPI 3.0 info + b64_t base; // base address + b64_t length; // region length + uint32_t type; // type of region + uint32_t acpi; // ACPI 3.0 info } ATTR_PACKED region_t; /* ** Region types */ -#define REGION_USABLE 1 -#define REGION_RESERVED 2 -#define REGION_ACPI_RECL 3 -#define REGION_ACPI_NVS 4 -#define REGION_BAD 5 +#define REGION_USABLE 1 +#define REGION_RESERVED 2 +#define REGION_ACPI_RECL 3 +#define REGION_ACPI_NVS 4 +#define REGION_BAD 5 /* ** ACPI 3.0 bit fields */ -#define REGION_IGNORE 0x01 -#define REGION_NONVOL 0x02 +#define REGION_IGNORE 0x01 +#define REGION_NONVOL 0x02 /* ** 32-bit and 64-bit address values as 64-bit literals */ -#define ADDR_BIT_32 0x0000000100000000LL -#define ADDR_LOW_HALF 0x00000000ffffffffLL -#define ADDR_HIGH_HALR 0xffffffff00000000LL +#define ADDR_BIT_32 0x0000000100000000LL +#define ADDR_LOW_HALF 0x00000000ffffffffLL +#define ADDR_HIGH_HALR 0xffffffff00000000LL -#define ADDR_32_MAX ADDR_LOW_HALF -#define ADDR_64_FIRST ADDR_BIT_32 +#define ADDR_32_MAX ADDR_LOW_HALF +#define ADDR_64_FIRST ADDR_BIT_32 /* ** PRIVATE GLOBAL VARIABLES @@ -196,19 +196,19 @@ static int km_initialized; ** @param[in] base Base physical address of the block ** @param[in] length Block length, in bytes */ -static void add_block(uint32_t base, uint32_t length) -{ +static void add_block( uint32_t base, uint32_t length ) { + // don't add it if it isn't at least 4K - if (length < SZ_PAGE) { + if( length < SZ_PAGE ) { return; } #if ANY_KMEM - cio_printf(" add(%08x,%08x): ", base, length); + cio_printf( " add(%08x,%08x): ", base, length ); #endif // verify that the base address is a 4K boundary - if ((base & MOD4K_BITS) != 0) { + if( (base & MOD4K_BITS) != 0 ) { // nope - how many bytes will we lose from the beginning uint_t loss = base & MOD4K_BITS; // adjust the starting address: (n + 4K - 1) / 4K @@ -218,7 +218,7 @@ static void add_block(uint32_t base, uint32_t length) } // only want to add multiples of 4K; check the lower bits - if ((length & MOD4K_BITS) != 0) { + if( (length & MOD4K_BITS) != 0 ) { // round it down to 4K length &= MOD4K_MASK; } @@ -235,21 +235,21 @@ static void add_block(uint32_t base, uint32_t length) int npages = 0; #if ANY_KMEM - cio_printf("-> base %08x len %08x: ", base, length); + cio_printf( "-> base %08x len %08x: ", base, length ); #endif // iterate through the block page by page - while (base < blend) { - list_add(&free_pages, (void *)base); + while( base < blend ) { + list_add( &free_pages, (void *) base ); ++npages; - base += SZ_PAGE; + base += SZ_PAGE; } // add the count to our running total n_pages += npages; #if ANY_KMEM - cio_printf(" -> %d pages\n", npages); + cio_printf( " -> %d pages\n", npages ); #endif } @@ -263,14 +263,13 @@ static void add_block(uint32_t base, uint32_t length) ** Must be called before any other init routine that uses ** dynamic storage is called. */ -void km_init(void) -{ +void km_init( void ) { int32_t entries; region_t *region; #if TRACING_INIT // announce that we're starting initialization - cio_puts(" Kmem"); + cio_puts( " Kmem" ); #endif // initially, nothing in the free lists @@ -280,28 +279,32 @@ void km_init(void) km_initialized = 0; // get the list length - entries = *((int32_t *)MMAP_ADDR); + entries = *((int32_t *) MMAP_ADDR); #if KMEM_OR_INIT - cio_printf("\nKmem: %d regions\n", entries); + cio_printf( "\nKmem: %d regions\n", entries ); #endif // if there are no entries, we have nothing to do! - if (entries < 1) { // note: entries == -1 could occur! + if( entries < 1 ) { // note: entries == -1 could occur! return; } // iterate through the entries, adding things to the freelist - region = ((region_t *)(MMAP_ADDR + 4)); + region = ((region_t *) (MMAP_ADDR + 4)); + + for( int i = 0; i < entries; ++i, ++region ) { - for (int i = 0; i < entries; ++i, ++region) { #if KMEM_OR_INIT // report this region - cio_printf("%3d: ", i); - cio_printf(" B %08x%08x", region->base.HIGH, region->base.LOW); - cio_printf(" L %08x%08x", region->length.HIGH, region->length.LOW); - cio_printf(" T %08x A %08x", region->type, region->acpi); + cio_printf( "%3d: ", i ); + cio_printf( " B %08x%08x", + region->base.HIGH, region->base.LOW ); + cio_printf( " L %08x%08x", + region->length.HIGH, region->length.LOW ); + cio_printf( " T %08x A %08x", + region->type, region->acpi ); #endif /* @@ -321,27 +324,27 @@ void km_init(void) // first, check the ACPI one-bit flags - if (((region->acpi) & REGION_IGNORE) == 0) { + if( ((region->acpi) & REGION_IGNORE) == 0 ) { #if KMEM_OR_INIT - cio_puts(" IGN\n"); + cio_puts( " IGN\n" ); #endif continue; } - if (((region->acpi) & REGION_NONVOL) != 0) { + if( ((region->acpi) & REGION_NONVOL) != 0 ) { #if KMEM_OR_INIT - cio_puts(" NVOL\n"); + cio_puts( " NVOL\n" ); #endif - continue; // we'll ignore this, too + continue; // we'll ignore this, too } // next, the region type - if ((region->type) != REGION_USABLE) { + if( (region->type) != REGION_USABLE ) { #if KMEM_OR_INIT - cio_puts(" RCLM\n"); + cio_puts( " RCLM\n" ); #endif - continue; // we won't attempt to reclaim ACPI memory (yet) + continue; // we won't attempt to reclaim ACPI memory (yet) } /* @@ -361,17 +364,18 @@ void km_init(void) */ // grab the two 64-bit values to simplify things - uint64_t base = region->base.all; + uint64_t base = region->base.all; uint64_t length = region->length.all; - uint64_t endpt = base + length; + uint64_t endpt = base + length; // ignore it if it's above our high cutoff point - if (base >= KM_HIGH_CUTOFF || endpt >= KM_HIGH_CUTOFF) { + if( base >= KM_HIGH_CUTOFF || endpt >= KM_HIGH_CUTOFF ) { + // is the whole thing too high, or just part? - if (base >= KM_HIGH_CUTOFF) { + if( base >= KM_HIGH_CUTOFF ) { // it's all too high! #if KMEM_OR_INIT - cio_puts(" HIGH\n"); + cio_puts( " HIGH\n" ); #endif continue; } @@ -381,12 +385,13 @@ void km_init(void) } // see if it's below our low cutoff point - if (base < KM_LOW_CUTOFF || endpt < KM_LOW_CUTOFF) { + if( base < KM_LOW_CUTOFF || endpt < KM_LOW_CUTOFF ) { + // is the whole thing too low, or just part? - if (endpt < KM_LOW_CUTOFF) { + if( endpt < KM_LOW_CUTOFF ) { // it's all below the cutoff! #if KMEM_OR_INIT - cio_puts(" LOW\n"); + cio_puts( " LOW\n" ); #endif continue; } @@ -405,20 +410,20 @@ void km_init(void) length = endpt - base; #if KMEM_OR_INIT - cio_puts(" OK\n"); + cio_puts( " OK\n" ); #endif - uint32_t b32 = base & ADDR_LOW_HALF; + uint32_t b32 = base & ADDR_LOW_HALF; uint32_t l32 = length & ADDR_LOW_HALF; - add_block(b32, l32); + add_block( b32, l32 ); } // record the initialization km_initialized = 1; #if KMEM_OR_INIT - delay(DELAY_3_SEC); + delay( DELAY_3_SEC ); #endif } @@ -433,38 +438,39 @@ void km_init(void) ** @param addrs Also dump page addresses ** @param both Also dump slice addresses */ -void km_dump(bool_t addrs, bool_t both) -{ +void km_dump( bool_t addrs, bool_t both ) { + // report the sizes - cio_printf("&free_pages %08x, &free_slices %08x, %u pages, %u slices\n", - (uint32_t)&free_pages, (uint32_t)&free_slices, n_pages, - n_slices); + cio_printf( "&free_pages %08x, &free_slices %08x, %u pages, %u slices\n", + (uint32_t) &free_pages, (uint32_t) &free_slices, + n_pages, n_slices ); // was that all? - if (!addrs) { + if( !addrs ) { return; } // dump the addresses of the pages in the free list uint32_t n = 0; list_t *block = free_pages.next; - while (block != NULL) { - if (n && !(n & MOD4_BITS)) { + while( block != NULL ) { + if( n && !(n & MOD4_BITS) ) { // four per line - cio_putchar('\n'); + cio_putchar( '\n' ); } - cio_printf(" page @ 0x%08x", (uint32_t)block); + cio_printf( " page @ 0x%08x", (uint32_t) block ); block = block->next; ++n; } // sanity check - verify that the counts match - if (n != n_pages) { - sprint(b256, "km_dump: n_pages %u, counted %u!!!\n", n_pages, n); - WARNING(b256); + if( n != n_pages ) { + sprint( b256, "km_dump: n_pages %u, counted %u!!!\n", + n_pages, n ); + WARNING( b256); } - if (!both) { + if( !both ) { return; } @@ -473,20 +479,21 @@ void km_dump(bool_t addrs, bool_t both) // also dump the addresses of slices in the slice free list n = 0; block = free_slices.next; - while (block != NULL) { - if (n && !(n & MOD4_BITS)) { + while( block != NULL ) { + if( n && !(n & MOD4_BITS) ) { // four per line - cio_putchar('\n'); + cio_putchar( '\n' ); } - cio_printf(" slc @ 0x%08x", (uint32_t)block); + cio_printf( " slc @ 0x%08x", (uint32_t) block ); block = block->next; ++n; } // sanity check - verify that the counts match - if (n != n_slices) { - sprint(b256, "km_dump: n_slices %u, counted %u!!!\n", n_slices, n); - WARNING(b256); + if( n != n_slices ) { + sprint( b256, "km_dump: n_slices %u, counted %u!!!\n", + n_slices, n ); + WARNING( b256); } } @@ -502,26 +509,26 @@ void km_dump(bool_t addrs, bool_t both) ** @return a pointer to the beginning of the allocated page, ** or NULL if no memory is available */ -void *km_page_alloc(void) -{ +void *km_page_alloc( void ) { + // if km_init() wasn't called first, stop us in our tracks - assert(km_initialized); + assert( km_initialized ); #if TRACING_KMEM_FREELIST - cio_puts("KM: pg_alloc()"); + cio_puts( "KM: pg_alloc()" ); #endif // pointer to the first block - void *page = list_remove(&free_pages); + void *page = list_remove( &free_pages ); // was a page available? - if (page == NULL) { + if( page == NULL ){ // nope! #if TRACING_KMEM_FREELIST - cio_puts(" FAIL\n"); + cio_puts( " FAIL\n" ); #endif #if ALLOC_FAIL_PANIC - PANIC(0, "page alloc failed"); + PANIC( 0, "page alloc failed" ); #else return NULL; #endif @@ -531,10 +538,10 @@ void *km_page_alloc(void) --n_pages; #if TRACING_KMEM_FREELIST - cio_printf(" -> %08x\n", (uint32_t)page); + cio_printf( " -> %08x\n", (uint32_t) page ); #endif - return (page); + return( page ); } /** @@ -544,22 +551,23 @@ void *km_page_alloc(void) ** ** @param[in] page Pointer to the page to be returned to the free list */ -void km_page_free(void *page) -{ +void km_page_free( void *page ){ + // verify that km_init() was called first - assert(km_initialized); + assert( km_initialized ); #if TRACING_KMEM_FREELIST - cio_printf("KM: pg_free(%08x)\n", (uint32_t)page); + cio_printf( "KM: pg_free(%08x)\n", (uint32_t) page ); #endif /* ** Don't do anything if the address is NULL. */ - if (page == NULL) { + if( page == NULL ){ return; } + /* ** CRITICAL ASSUMPTION ** @@ -581,7 +589,7 @@ void km_page_free(void *page) */ // link this into the free list - list_add(&free_pages, page); + list_add( &free_pages, page ); // one more in the pool ++n_pages; @@ -605,19 +613,19 @@ void km_page_free(void *page) ** ** @param page Pointer to the page to be carved up */ -static void carve_slices(void *page) -{ +static void carve_slices( void *page ) { + // sanity check - assert1(page != NULL); + assert1( page != NULL ); #if TRACING_KMEM_FREELIST - cio_printf("KM: carve_slices(%08x)\n", (uint32_t)page); + cio_printf( "KM: carve_slices(%08x)\n", (uint32_t) page ); #endif // create the four slices from it - uint8_t *ptr = (uint8_t *)page; - for (int i = 0; i < 4; ++i) { - km_slice_free((void *)ptr); + uint8_t *ptr = (uint8_t *) page; + for( int i = 0; i < 4; ++i ) { + km_slice_free( (void *) ptr ); ptr += SZ_SLICE; ++n_slices; } @@ -632,38 +640,38 @@ static void carve_slices(void *page) ** ** @return a pointer to the allocated slice */ -void *km_slice_alloc(void) -{ +void *km_slice_alloc( void ) { + // verify that km_init() was called first - assert(km_initialized); + assert( km_initialized ); #if TRACING_KMEM_FREELIST - cio_printf("KM: sl_alloc()\n"); + cio_printf( "KM: sl_alloc()\n" ); #endif // if we are out of slices, create a few more - if (free_slices.next == NULL) { + if( free_slices.next == NULL ) { void *new = km_page_alloc(); - if (new == NULL) { + if( new == NULL ) { // can't get any more space #if ALLOC_FAIL_PANIC - PANIC(0, "slice new alloc failed"); + PANIC( 0, "slice new alloc failed" ); #else return NULL; #endif } - carve_slices(new); + carve_slices( new ); } // take the first one from the free list - void *slice = list_remove(&free_slices); - assert(slice != NULL); + void *slice = list_remove( &free_slices ); + assert( slice != NULL ); --n_slices; // make it nice and shiny for the caller - memclr((void *)slice, SZ_SLICE); + memclr( (void *) slice, SZ_SLICE ); - return (slice); + return( slice ); } /** @@ -676,16 +684,16 @@ void *km_slice_alloc(void) ** ** @param[in] block Pointer to the slice (1/4 page) to be freed */ -void km_slice_free(void *block) -{ +void km_slice_free( void *block ) { + // verify that km_init() was called first - assert(km_initialized); + assert( km_initialized ); #if TRACING_KMEM_FREELIST - cio_printf("KM: sl_free(%08x)\n", (uint32_t)block); + cio_printf( "KM: sl_free(%08x)\n", (uint32_t) block ); #endif // just add it to the front of the free list - list_add(&free_slices, block); + list_add( &free_slices, block ); --n_slices; } diff --git a/kernel/old/list.c b/kernel/old/list.c index 5492615..084000a 100644 --- a/kernel/old/list.c +++ b/kernel/old/list.c @@ -29,11 +29,11 @@ ** @param[in,out] list The address of a list_t variable ** @param[in] data The data to prepend to the list */ -void list_add(list_t *list, void *data) -{ +void list_add( list_t *list, void *data ) { + // sanity checks - assert1(list != NULL); - assert1(data != NULL); + assert1( list != NULL ); + assert1( data != NULL ); list_t *tmp = (list_t *)data; tmp->next = list->next; @@ -49,15 +49,16 @@ void list_add(list_t *list, void *data) ** ** @return a pointer to the removed data, or NULL if the list was empty */ -void *list_remove(list_t *list) -{ - assert1(list != NULL); +void *list_remove( list_t *list ) { + + assert1( list != NULL ); list_t *data = list->next; - if (data != NULL) { + if( data != NULL ) { list->next = data->next; data->next = NULL; } return (void *)data; } + diff --git a/kernel/old/procs.c b/kernel/old/procs.c index 82c4c98..96bb3fd 100644 --- a/kernel/old/procs.c +++ b/kernel/old/procs.c @@ -6,7 +6,7 @@ ** @brief Process-related implementations */ -#define KERNEL_SRC +#define KERNEL_SRC #include @@ -18,7 +18,7 @@ */ // determine if a queue is empty; assumes 'q' is a valid pointer -#define PCB_QUEUE_EMPTY(q) ((q)->head == NULL) +#define PCB_QUEUE_EMPTY(q) ((q)->head == NULL) /* ** PRIVATE DATA TYPES @@ -74,29 +74,33 @@ uint_t next_pid; pcb_t *init_pcb; // table of state name strings -const char state_str[N_STATES][4] = { - [STATE_UNUSED] = "Unu", // "Unused" - [STATE_NEW] = "New", - [STATE_READY] = "Rdy", // "Ready" - [STATE_RUNNING] = "Run", // "Running" - [STATE_SLEEPING] = "Slp", // "Sleeping" - [STATE_BLOCKED] = "Blk", // "Blocked" - [STATE_WAITING] = "Wat", // "Waiting" - [STATE_KILLED] = "Kil", // "Killed" - [STATE_ZOMBIE] = "Zom" // "Zombie" +const char *state_str[N_STATES] = { + [ STATE_UNUSED ] = "Unu", // "Unused" + [ STATE_NEW ] = "New", + [ STATE_READY ] = "Rdy", // "Ready" + [ STATE_RUNNING ] = "Run", // "Running" + [ STATE_SLEEPING ] = "Slp", // "Sleeping" + [ STATE_BLOCKED ] = "Blk", // "Blocked" + [ STATE_WAITING ] = "Wat", // "Waiting" + [ STATE_KILLED ] = "Kil", // "Killed" + [ STATE_ZOMBIE ] = "Zom" // "Zombie" }; // table of priority name strings -const char prio_str[N_PRIOS][5] = { [PRIO_HIGH] = "High", - [PRIO_STD] = "User", - [PRIO_LOW] = "Low ", - [PRIO_DEFERRED] = "Def " }; +const char *prio_str[N_PRIOS] = { + [ PRIO_HIGH ] = "High", + [ PRIO_STD ] = "User", + [ PRIO_LOW ] = "Low ", + [ PRIO_DEFERRED ] = "Def " +}; // table of queue ordering name strings -const char ord_str[N_PRIOS][5] = { [O_FIFO] = "FIFO", - [O_PRIO] = "PRIO", - [O_PID] = "PID ", - [O_WAKEUP] = "WAKE" }; +const char *ord_str[N_PRIOS] = { + [ O_FIFO ] = "FIFO", + [ O_PRIO ] = "PRIO", + [ O_PID ] = "PID ", + [ O_WAKEUP ] = "WAKE" +}; /* ** PRIVATE FUNCTIONS @@ -121,16 +125,16 @@ const char ord_str[N_PRIOS][5] = { [O_FIFO] = "FIFO", ** @return a pointer to the predecessor in the queue, or NULL if ** this PCB would be at the beginning of the queue. */ -static pcb_t *find_prev_wakeup(pcb_queue_t queue, pcb_t *pcb) -{ +static pcb_t *find_prev_wakeup( pcb_queue_t queue, pcb_t *pcb ) { + // sanity checks! - assert1(queue != NULL); - assert1(pcb != NULL); + assert1( queue != NULL ); + assert1( pcb != NULL ); pcb_t *prev = NULL; pcb_t *curr = queue->head; - while (curr != NULL && curr->wakeup <= pcb->wakeup) { + while( curr != NULL && curr->wakeup <= pcb->wakeup ) { prev = curr; curr = curr->next; } @@ -138,16 +142,16 @@ static pcb_t *find_prev_wakeup(pcb_queue_t queue, pcb_t *pcb) return prev; } -static pcb_t *find_prev_priority(pcb_queue_t queue, pcb_t *pcb) -{ +static pcb_t *find_prev_priority( pcb_queue_t queue, pcb_t *pcb ) { + // sanity checks! - assert1(queue != NULL); - assert1(pcb != NULL); + assert1( queue != NULL ); + assert1( pcb != NULL ); pcb_t *prev = NULL; pcb_t *curr = queue->head; - while (curr != NULL && curr->priority <= pcb->priority) { + while( curr != NULL && curr->priority <= pcb->priority ) { prev = curr; curr = curr->next; } @@ -155,16 +159,16 @@ static pcb_t *find_prev_priority(pcb_queue_t queue, pcb_t *pcb) return prev; } -static pcb_t *find_prev_pid(pcb_queue_t queue, pcb_t *pcb) -{ +static pcb_t *find_prev_pid( pcb_queue_t queue, pcb_t *pcb ) { + // sanity checks! - assert1(queue != NULL); - assert1(pcb != NULL); + assert1( queue != NULL ); + assert1( pcb != NULL ); pcb_t *prev = NULL; pcb_t *curr = queue->head; - while (curr != NULL && curr->pid <= pcb->pid) { + while( curr != NULL && curr->pid <= pcb->pid ) { prev = curr; curr = curr->next; } @@ -177,10 +181,10 @@ static pcb_t *find_prev_pid(pcb_queue_t queue, pcb_t *pcb) */ // a macro to simplify queue setup -#define QINIT(q, s) \ - q = &q##_queue; \ - if (pcb_queue_reset(q, s) != SUCCESS) { \ - PANIC(0, "pcb_init can't reset " #q); \ +#define QINIT(q,s) \ + q = &q##_queue; \ + if( pcb_queue_reset(q,s) != SUCCESS ) { \ + PANIC( 0, "pcb_init can't reset " # q ); \ } /** @@ -188,22 +192,22 @@ static pcb_t *find_prev_pid(pcb_queue_t queue, pcb_t *pcb) ** ** Initialization for the Process module. */ -void pcb_init(void) -{ +void pcb_init( void ) { + #if TRACING_INIT - cio_puts(" Procs"); + cio_puts( " Procs" ); #endif // there is no current process current = NULL; // set up the external links to the queues - QINIT(pcb_freelist, O_FIFO); - QINIT(ready, O_PRIO); - QINIT(waiting, O_PID); - QINIT(sleeping, O_WAKEUP); - QINIT(zombie, O_PID); - QINIT(sioread, O_FIFO); + QINIT( pcb_freelist, O_FIFO ); + QINIT( ready, O_PRIO ); + QINIT( waiting, O_PID ); + QINIT( sleeping, O_WAKEUP ); + QINIT( zombie, O_PID ); + QINIT( sioread, O_FIFO ); /* ** We statically allocate our PCBs, so we need to add them @@ -214,8 +218,8 @@ void pcb_init(void) */ pcb_t *ptr = ptable; - for (int i = 0; i < N_PROCS; ++i) { - pcb_free(ptr); + for( int i = 0; i < N_PROCS; ++i ) { + pcb_free( ptr ); ++ptr; } } @@ -229,14 +233,14 @@ void pcb_init(void) ** ** @return status of the allocation attempt */ -int pcb_alloc(pcb_t **pcb) -{ +int pcb_alloc( pcb_t **pcb ) { + // sanity check! - assert1(pcb != NULL); + assert1( pcb != NULL ); // remove the first PCB from the free list pcb_t *tmp; - if (pcb_queue_remove(pcb_freelist, &tmp) != SUCCESS) { + if( pcb_queue_remove(pcb_freelist,&tmp) != SUCCESS ) { return E_NO_PCBS; } @@ -251,19 +255,20 @@ int pcb_alloc(pcb_t **pcb) ** ** @param pcb Pointer to the PCB to be deallocated. */ -void pcb_free(pcb_t *pcb) -{ - if (pcb != NULL) { +void pcb_free( pcb_t *pcb ) { + + if( pcb != NULL ) { // mark the PCB as available pcb->state = STATE_UNUSED; // add it to the free list - int status = pcb_queue_insert(pcb_freelist, pcb); + int status = pcb_queue_insert( pcb_freelist, pcb ); // if that failed, we're in trouble - if (status != SUCCESS) { - sprint(b256, "pcb_free(0x%08x) status %d", (uint32_t)pcb, status); - PANIC(0, b256); + if( status != SUCCESS ) { + sprint( b256, "pcb_free(0x%08x) status %d", (uint32_t) pcb, + status ); + PANIC( 0, b256 ); } } } @@ -277,15 +282,15 @@ void pcb_free(pcb_t *pcb) ** ** @param pcb Pointer to the newly-undead PCB */ -void pcb_zombify(register pcb_t *victim) -{ +void pcb_zombify( register pcb_t *victim ) { + // should this be an error? - if (victim == NULL) { + if( victim == NULL ) { return; } // every process must have a parent, even if it's 'init' - assert(victim->parent != NULL); + assert( victim->parent != NULL ); /* ** We need to locate the parent of this process. We also need @@ -301,24 +306,26 @@ void pcb_zombify(register pcb_t *victim) // speed up access to the process table entries register pcb_t *curr = ptable; - for (int i = 0; i < N_PROCS; ++i, ++curr) { + for( int i = 0; i < N_PROCS; ++i, ++curr ) { + // make sure this is a valid entry - if (curr->state == STATE_UNUSED) { + if( curr->state == STATE_UNUSED ) { continue; } // if this is our parent, just keep going - we continue // iterating to find all the children of this process. - if (curr == parent) { + if( curr == parent ) { continue; } - if (curr->parent == victim) { + if( curr->parent == victim ) { + // found a child - reparent it curr->parent = init_pcb; // see if this child is already undead - if (curr->state == STATE_ZOMBIE) { + if( curr->state == STATE_ZOMBIE ) { // if it's already a zombie, remember it, so we // can pass it on to 'init'; also, if there are // two or more zombie children, it doesn't matter @@ -326,6 +333,7 @@ void pcb_zombify(register pcb_t *victim) // collected when 'init' loops zchild = curr; } + } } @@ -339,25 +347,26 @@ void pcb_zombify(register pcb_t *victim) ** ** Also note: it's possible that the exiting process' parent is ** also init, which means we're letting one of zombie children - ** of the exiting process be cleaned up by init before the + ** of the exiting process be cleaned up by init before the ** existing process itself is cleaned up by init. This will work, ** because after init cleans up the zombie, it will loop and ** call waitpid() again, by which time this exiting process will ** be marked as a zombie. */ - if (zchild != NULL && init_pcb->state == STATE_WAITING) { + if( zchild != NULL && init_pcb->state == STATE_WAITING ) { + // dequeue the zombie - assert(pcb_queue_remove_this(zombie, zchild) == SUCCESS); + assert( pcb_queue_remove_this(zombie,zchild) == SUCCESS ); - assert(pcb_queue_remove_this(waiting, init_pcb) == SUCCESS); + assert( pcb_queue_remove_this(waiting,init_pcb) == SUCCESS ); // intrinsic return value is the PID RET(init_pcb) = zchild->pid; // may also want to return the exit status - int32_t *ptr = (int32_t *)ARG(init_pcb, 2); + int32_t *ptr = (int32_t *) ARG(init_pcb,2); - if (ptr != NULL) { + if( ptr != NULL ) { // ******************************************************** // ** Potential VM issue here! This code assigns the exit // ** status into a variable in the parent's address space. @@ -370,8 +379,8 @@ void pcb_zombify(register pcb_t *victim) } // all done - schedule 'init', and clean up the zombie - schedule(init_pcb); - pcb_cleanup(zchild); + schedule( init_pcb ); + pcb_cleanup( zchild ); } /* @@ -385,12 +394,14 @@ void pcb_zombify(register pcb_t *victim) ** worry about it being scheduled twice. */ - if (parent->state == STATE_WAITING) { + if( parent->state == STATE_WAITING ) { + // verify that the parent is either waiting for this process // or is waiting for any of its children - uint32_t target = ARG(parent, 1); + uint32_t target = ARG(parent,1); + + if( target == 0 || target == vicpid ) { - if (target == 0 || target == vicpid) { // the parent is waiting for this child or is waiting // for any of its children, so we can wake it up. @@ -398,9 +409,9 @@ void pcb_zombify(register pcb_t *victim) RET(parent) = vicpid; // may also want to return the exit status - int32_t *ptr = (int32_t *)ARG(parent, 2); + int32_t *ptr = (int32_t *) ARG(parent,2); - if (ptr != NULL) { + if( ptr != NULL ) { // ******************************************************** // ** Potential VM issue here! This code assigns the exit // ** status into a variable in the parent's address space. @@ -413,8 +424,8 @@ void pcb_zombify(register pcb_t *victim) } // all done - schedule the parent, and clean up the zombie - schedule(parent); - pcb_cleanup(victim); + schedule( parent ); + pcb_cleanup( victim ); return; } @@ -432,7 +443,7 @@ void pcb_zombify(register pcb_t *victim) */ victim->state = STATE_ZOMBIE; - assert(pcb_queue_insert(zombie, victim) == SUCCESS); + assert( pcb_queue_insert(zombie,victim) == SUCCESS ); /* ** Note: we don't call _dispatch() here - we leave that for @@ -448,23 +459,23 @@ void pcb_zombify(register pcb_t *victim) ** ** @param pcb The PCB to reclaim */ -void pcb_cleanup(pcb_t *pcb) -{ +void pcb_cleanup( pcb_t *pcb ) { + #if TRACING_PCB - cio_printf("** pcb_cleanup(0x%08x)\n", (uint32_t)pcb); + cio_printf( "** pcb_cleanup(0x%08x)\n", (uint32_t) pcb ); #endif // avoid deallocating a NULL pointer - if (pcb == NULL) { + if( pcb == NULL ) { // should this be an error? return; } // we need to release all the VM data structures and frames - user_cleanup(pcb); + user_cleanup( pcb ); // release the PCB itself - pcb_free(pcb); + pcb_free( pcb ); } /** @@ -476,18 +487,18 @@ void pcb_cleanup(pcb_t *pcb) ** ** @return Pointer to the PCB, or NULL */ -pcb_t *pcb_find_pid(uint_t pid) -{ +pcb_t *pcb_find_pid( uint_t pid ) { + // must be a valid PID - if (pid < 1) { + if( pid < 1 ) { return NULL; } // scan the process table pcb_t *p = ptable; - for (int i = 0; i < N_PROCS; ++i, ++p) { - if (p->pid == pid && p->state != STATE_UNUSED) { + for( int i = 0; i < N_PROCS; ++i, ++p ) { + if( p->pid == pid && p->state != STATE_UNUSED ) { return p; } } @@ -505,19 +516,19 @@ pcb_t *pcb_find_pid(uint_t pid) ** ** @return Pointer to the PCB, or NULL */ -pcb_t *pcb_find_ppid(uint_t pid) -{ +pcb_t *pcb_find_ppid( uint_t pid ) { + // must be a valid PID - if (pid < 1) { + if( pid < 1 ) { return NULL; } // scan the process table pcb_t *p = ptable; - for (int i = 0; i < N_PROCS; ++i, ++p) { - assert1(p->parent != NULL); - if (p->parent->pid == pid && p->parent->state != STATE_UNUSED) { + for( int i = 0; i < N_PROCS; ++i, ++p ) { + assert1( p->parent != NULL ); + if( p->parent->pid == pid && p->parent->state != STATE_UNUSED ) { return p; } } @@ -537,13 +548,13 @@ pcb_t *pcb_find_ppid(uint_t pid) ** ** @return status of the init request */ -int pcb_queue_reset(pcb_queue_t queue, enum pcb_queue_order_e style) -{ +int pcb_queue_reset( pcb_queue_t queue, enum pcb_queue_order_e style ) { + // sanity check - assert1(queue != NULL); + assert1( queue != NULL ); // make sure the style is valid - if (style < O_FIRST_STYLE || style > O_LAST_STYLE) { + if( style < O_FIRST_STYLE || style > O_LAST_STYLE ) { return E_BAD_PARAM; } @@ -564,10 +575,10 @@ int pcb_queue_reset(pcb_queue_t queue, enum pcb_queue_order_e style) ** ** @return true if the queue is empty, else false */ -bool_t pcb_queue_empty(pcb_queue_t queue) -{ +bool_t pcb_queue_empty( pcb_queue_t queue ) { + // if there is no queue, blow up - assert1(queue != NULL); + assert1( queue != NULL ); return PCB_QUEUE_EMPTY(queue); } @@ -581,16 +592,16 @@ bool_t pcb_queue_empty(pcb_queue_t queue) ** ** @return the count (0 if the queue is empty) */ -uint_t pcb_queue_length(const pcb_queue_t queue) -{ +uint_t pcb_queue_length( const pcb_queue_t queue ) { + // sanity check - assert1(queue != NULL); + assert1( queue != NULL ); // this is pretty simple register pcb_t *tmp = queue->head; register int num = 0; - - while (tmp != NULL) { + + while( tmp != NULL ) { ++num; tmp = tmp->next; } @@ -608,41 +619,41 @@ uint_t pcb_queue_length(const pcb_queue_t queue) ** ** @return status of the insertion request */ -int pcb_queue_insert(pcb_queue_t queue, pcb_t *pcb) -{ +int pcb_queue_insert( pcb_queue_t queue, pcb_t *pcb ) { + // sanity checks - assert1(queue != NULL); - assert1(pcb != NULL); + assert1( queue != NULL ); + assert1( pcb != NULL ); // if this PCB is already in a queue, we won't touch it - if (pcb->next != NULL) { + if( pcb->next != NULL ) { // what to do? we let the caller decide return E_BAD_PARAM; } // is the queue empty? - if (queue->head == NULL) { + if( queue->head == NULL ) { queue->head = queue->tail = pcb; return SUCCESS; } - assert1(queue->tail != NULL); + assert1( queue->tail != NULL ); // no, so we need to search it pcb_t *prev = NULL; // find the predecessor node - switch (queue->order) { + switch( queue->order ) { case O_FIFO: prev = queue->tail; break; case O_PRIO: - prev = find_prev_priority(queue, pcb); + prev = find_prev_priority(queue,pcb); break; case O_PID: - prev = find_prev_pid(queue, pcb); + prev = find_prev_pid(queue,pcb); break; case O_WAKEUP: - prev = find_prev_wakeup(queue, pcb); + prev = find_prev_wakeup(queue,pcb); break; default: // do we need something more specific here? @@ -651,25 +662,29 @@ int pcb_queue_insert(pcb_queue_t queue, pcb_t *pcb) // OK, we found the predecessor node; time to do the insertion - if (prev == NULL) { + if( prev == NULL ) { + // there is no predecessor, so we're // inserting at the front of the queue pcb->next = queue->head; - if (queue->head == NULL) { + if( queue->head == NULL ) { // empty queue!?! - should we panic? queue->tail = pcb; } queue->head = pcb; - } else if (prev->next == NULL) { + } else if( prev->next == NULL ) { + // append at end prev->next = pcb; queue->tail = pcb; } else { + // insert between prev & prev->next pcb->next = prev->next; prev->next = pcb; + } return SUCCESS; @@ -685,14 +700,14 @@ int pcb_queue_insert(pcb_queue_t queue, pcb_t *pcb) ** ** @return status of the removal request */ -int pcb_queue_remove(pcb_queue_t queue, pcb_t **pcb) -{ +int pcb_queue_remove( pcb_queue_t queue, pcb_t **pcb ) { + //sanity checks - assert1(queue != NULL); - assert1(pcb != NULL); + assert1( queue != NULL ); + assert1( pcb != NULL ); // can't get anything if there's nothing to get! - if (PCB_QUEUE_EMPTY(queue)) { + if( PCB_QUEUE_EMPTY(queue) ) { return E_EMPTY_QUEUE; } @@ -704,7 +719,7 @@ int pcb_queue_remove(pcb_queue_t queue, pcb_t **pcb) tmp->next = NULL; // was this the last thing in the queue? - if (queue->head == NULL) { + if( queue->head == NULL ) { // yes, so clear the tail pointer for consistency queue->tail = NULL; } @@ -729,14 +744,14 @@ int pcb_queue_remove(pcb_queue_t queue, pcb_t **pcb) ** ** @return status of the removal request */ -int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb) -{ +int pcb_queue_remove_this( pcb_queue_t queue, pcb_t *pcb ) { + //sanity checks - assert1(queue != NULL); - assert1(pcb != NULL); + assert1( queue != NULL ); + assert1( pcb != NULL ); // can't get anything if there's nothing to get! - if (PCB_QUEUE_EMPTY(queue)) { + if( PCB_QUEUE_EMPTY(queue) ) { return E_EMPTY_QUEUE; } @@ -744,7 +759,7 @@ int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb) pcb_t *prev = NULL; pcb_t *curr = queue->head; - while (curr != NULL && curr != pcb) { + while( curr != NULL && curr != pcb ) { prev = curr; curr = curr->next; } @@ -758,15 +773,15 @@ int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb) // 5. !0 !0 0 removing from end // 6. !0 !0 !0 removing from middle - if (curr == NULL) { + if( curr == NULL ) { // case 1 - assert(prev != NULL); + assert( prev != NULL ); // case 4 return E_NOT_FOUND; } // connect predecessor to successor - if (prev != NULL) { + if( prev != NULL ) { // not the first element // cases 5 and 6 prev->next = curr->next; @@ -778,7 +793,7 @@ int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb) // if this was the last node (cases 2 and 5), // also need to reset the tail pointer - if (curr->next == NULL) { + if( curr->next == NULL ) { // if this was the only entry (2), prev is NULL, // so this works for that case, too queue->tail = prev; @@ -791,8 +806,10 @@ int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb) // one of the queue pointers is NULL and the other one // is not NULL - assert1((queue->head == NULL && queue->tail == NULL) || - (queue->head != NULL && queue->tail != NULL)); + assert1( + (queue->head == NULL && queue->tail == NULL) || + (queue->head != NULL && queue->tail != NULL) + ); return SUCCESS; } @@ -807,13 +824,13 @@ int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb) ** ** @return the PCB poiner, or NULL if the queue is empty */ -pcb_t *pcb_queue_peek(const pcb_queue_t queue) -{ +pcb_t *pcb_queue_peek( const pcb_queue_t queue ) { + //sanity check - assert1(queue != NULL); + assert1( queue != NULL ); // can't get anything if there's nothing to get! - if (PCB_QUEUE_EMPTY(queue)) { + if( PCB_QUEUE_EMPTY(queue) ) { return NULL; } @@ -832,13 +849,13 @@ pcb_t *pcb_queue_peek(const pcb_queue_t queue) ** ** @param pcb Pointer to the PCB of the process to be scheduled */ -void schedule(pcb_t *pcb) -{ +void schedule( pcb_t *pcb ) { + // sanity check - assert1(pcb != NULL); + assert1( pcb != NULL ); // check for a killed process - if (pcb->state == STATE_KILLED) { + if( pcb->state == STATE_KILLED ) { // TODO figure out what to do now return; } @@ -847,8 +864,8 @@ void schedule(pcb_t *pcb) pcb->state = STATE_READY; // add it to the ready queue - if (pcb_queue_insert(ready, pcb) != SUCCESS) { - PANIC(0, "schedule insert fail"); + if( pcb_queue_insert(ready,pcb) != SUCCESS ) { + PANIC( 0, "schedule insert fail" ); } } @@ -857,16 +874,16 @@ void schedule(pcb_t *pcb) ** ** Select the next process to receive the CPU */ -void dispatch(void) -{ +void dispatch( void ) { + // verify that there is no current process - assert(current == NULL); + assert( current == NULL ); // grab whoever is at the head of the queue - int status = pcb_queue_remove(ready, ¤t); - if (status != SUCCESS) { - sprint(b256, "dispatch queue remove failed, code %d", status); - PANIC(0, b256); + int status = pcb_queue_remove( ready, ¤t ); + if( status != SUCCESS ) { + sprint( b256, "dispatch queue remove failed, code %d", status ); + PANIC( 0, b256 ); } // set the process up for success @@ -874,6 +891,7 @@ void dispatch(void) current->ticks = QUANTUM_STANDARD; } + /* ** Debugging/tracing routines */ @@ -886,32 +904,32 @@ void dispatch(void) ** @param msg[in] An optional message to print before the dump ** @param c[in] The context to dump out */ -void ctx_dump(const char *msg, register context_t *c) -{ +void ctx_dump( const char *msg, register context_t *c ) { + // first, the message (if there is one) - if (msg) { - cio_puts(msg); + if( msg ) { + cio_puts( msg ); } // the pointer - cio_printf(" @ %08x: ", (uint32_t)c); + cio_printf( " @ %08x: ", (uint32_t) c ); // if it's NULL, why did you bother calling me? - if (c == NULL) { - cio_puts(" NULL???\n"); + if( c == NULL ) { + cio_puts( " NULL???\n" ); return; } // now, the contents - cio_printf("ss %04x gs %04x fs %04x es %04x ds %04x cs %04x\n", - c->ss & 0xff, c->gs & 0xff, c->fs & 0xff, c->es & 0xff, - c->ds & 0xff, c->cs & 0xff); - cio_printf(" edi %08x esi %08x ebp %08x esp %08x\n", c->edi, c->esi, - c->ebp, c->esp); - cio_printf(" ebx %08x edx %08x ecx %08x eax %08x\n", c->ebx, c->edx, - c->ecx, c->eax); - cio_printf(" vec %08x cod %08x eip %08x eflags %08x\n", c->vector, c->code, - c->eip, c->eflags); + cio_printf( "ss %04x gs %04x fs %04x es %04x ds %04x cs %04x\n", + c->ss & 0xff, c->gs & 0xff, c->fs & 0xff, + c->es & 0xff, c->ds & 0xff, c->cs & 0xff ); + cio_printf( " edi %08x esi %08x ebp %08x esp %08x\n", + c->edi, c->esi, c->ebp, c->esp ); + cio_printf( " ebx %08x edx %08x ecx %08x eax %08x\n", + c->ebx, c->edx, c->ecx, c->eax ); + cio_printf( " vec %08x cod %08x eip %08x eflags %08x\n", + c->vector, c->code, c->eip, c->eflags ); } /** @@ -921,25 +939,25 @@ void ctx_dump(const char *msg, register context_t *c) ** ** @param msg[in] Optional message to print */ -void ctx_dump_all(const char *msg) -{ - if (msg != NULL) { - cio_puts(msg); +void ctx_dump_all( const char *msg ) { + + if( msg != NULL ) { + cio_puts( msg ); } int n = 0; register pcb_t *pcb = ptable; - for (int i = 0; i < N_PROCS; ++i, ++pcb) { - if (pcb->state != STATE_UNUSED) { + for( int i = 0; i < N_PROCS; ++i, ++pcb ) { + if( pcb->state != STATE_UNUSED ) { ++n; - cio_printf("%2d(%d): ", n, pcb->pid); - ctx_dump(NULL, pcb->context); + cio_printf( "%2d(%d): ", n, pcb->pid ); + ctx_dump( NULL, pcb->context ); } } } /** -** pcb_dump(msg,pcb,all) +** _pcb_dump(msg,pcb) ** ** Dumps the contents of this PCB to the console ** @@ -947,85 +965,88 @@ void ctx_dump_all(const char *msg) ** @param pcb[in] The PCB to dump ** @param all[in] Dump all the contents? */ -void pcb_dump(const char *msg, register pcb_t *pcb, bool_t all) -{ +void pcb_dump( const char *msg, register pcb_t *pcb, bool_t all ) { + // first, the message (if there is one) - if (msg) { - cio_puts(msg); + if( msg ) { + cio_puts( msg ); } // the pointer - cio_printf(" @ %08x:", (uint32_t)pcb); + cio_printf( " @ %08x:", (uint32_t) pcb ); // if it's NULL, why did you bother calling me? - if (pcb == NULL) { - cio_puts(" NULL???\n"); + if( pcb == NULL ) { + cio_puts( " NULL???\n" ); return; } - cio_printf(" %d %s", pcb->pid, - pcb->state >= N_STATES ? "???" : state_str[pcb->state]); + cio_printf( " %d", pcb->pid ); + cio_printf( " %s", + pcb->state >= N_STATES ? "???" : state_str[pcb->state] ); - if (!all) { + if( !all ) { // just printing IDs and states on one line return; } // now, the rest of the contents - cio_printf(" %s", - pcb->priority >= N_PRIOS ? "???" : prio_str[pcb->priority]); + cio_printf( " %s", + pcb->priority >= N_PRIOS ? "???" : prio_str[pcb->priority] ); - cio_printf(" ticks %u xit %d wake %08x\n", pcb->ticks, pcb->exit_status, - pcb->wakeup); + cio_printf( " ticks %u xit %d wake %08x\n", + pcb->ticks, pcb->exit_status, pcb->wakeup ); - cio_printf(" parent %08x", (uint32_t)pcb->parent); - if (pcb->parent != NULL) { - cio_printf(" (%u)", pcb->parent->pid); + cio_printf( " parent %08x", (uint32_t)pcb->parent ); + if( pcb->parent != NULL ) { + cio_printf( " (%u)", pcb->parent->pid ); } - cio_printf(" next %08x context %08x pde %08x", (uint32_t)pcb->next, - (uint32_t)pcb->context, (uint32_t)pcb->pdir); + cio_printf( " next %08x context %08x pde %08x", (uint32_t) pcb->next, + (uint32_t) pcb->context, (uint32_t) pcb->pdir ); - cio_putchar('\n'); + cio_putchar( '\n' ); } /** ** pcb_queue_dump(msg,queue,contents) ** +** Dump the contents of the specified queue to the console +** ** @param msg[in] Optional message to print ** @param queue[in] The queue to dump ** @param contents[in] Also dump (some) contents? */ -void pcb_queue_dump(const char *msg, pcb_queue_t queue, bool_t contents) -{ +void pcb_queue_dump( const char *msg, pcb_queue_t queue, bool_t contents ) { + // report on this queue - cio_printf("%s: ", msg); - if (queue == NULL) { - cio_puts("NULL???\n"); + cio_printf( "%s: ", msg ); + if( queue == NULL ) { + cio_puts( "NULL???\n" ); return; } // first, the basic data - cio_printf("head %08x tail %08x", (uint32_t)queue->head, - (uint32_t)queue->tail); + cio_printf( "head %08x tail %08x", + (uint32_t) queue->head, (uint32_t) queue->tail ); // next, how the queue is ordered - cio_printf(" order %s\n", - queue->order >= N_ORDERINGS ? "????" : ord_str[queue->order]); + cio_printf( " order %s\n", + queue->order >= N_ORDERINGS ? "????" : ord_str[queue->order] ); // if there are members in the queue, dump the first few PIDs - if (contents && queue->head != NULL) { - cio_puts(" PIDs: "); + if( contents && queue->head != NULL ) { + cio_puts( " PIDs: " ); pcb_t *tmp = queue->head; - for (int i = 0; i < 5 && tmp != NULL; ++i, tmp = tmp->next) { - cio_printf(" [%u]", tmp->pid); + for( int i = 0; i < 5 && tmp != NULL; ++i, tmp = tmp->next ) { + cio_printf( " [%u]", tmp->pid ); } - if (tmp != NULL) { - cio_puts(" ..."); + if( tmp != NULL ) { + cio_puts( " ..." ); } - cio_putchar('\n'); + cio_putchar( '\n' ); } } @@ -1037,48 +1058,50 @@ void pcb_queue_dump(const char *msg, pcb_queue_t queue, bool_t contents) ** @param msg[in] Optional message to print ** @param all[in] Dump all or only part of the relevant data */ -void ptable_dump(const char *msg, bool_t all) -{ - if (msg) { - cio_puts(msg); +void ptable_dump( const char *msg, bool_t all ) { + + if( msg ) { + cio_puts( msg ); } - cio_putchar(' '); + cio_putchar( ' ' ); int used = 0; int empty = 0; register pcb_t *pcb = ptable; - for (int i = 0; i < N_PROCS; ++i) { - if (pcb->state == STATE_UNUSED) { + for( int i = 0; i < N_PROCS; ++i ) { + if( pcb->state == STATE_UNUSED ) { + // an empty slot ++empty; } else { + // a non-empty slot ++used; // if not dumping everything, add commas if needed - if (!all && used) { - cio_putchar(','); + if( !all && used ) { + cio_putchar( ',' ); } // report the table slot # - cio_printf(" #%d:", i); + cio_printf( " #%d:", i ); // and dump the contents - pcb_dump(NULL, pcb, all); + pcb_dump( NULL, pcb, all ); } } // only need this if we're doing one-line output - if (!all) { - cio_putchar('\n'); + if( !all ) { + cio_putchar( '\n' ); } // sanity check - make sure we saw the correct number of table slots - if ((used + empty) != N_PROCS) { - cio_printf("Table size %d, used %d + empty %d = %d???\n", N_PROCS, used, - empty, used + empty); + if( (used + empty) != N_PROCS ) { + cio_printf( "Table size %d, used %d + empty %d = %d???\n", + N_PROCS, used, empty, used + empty ); } } @@ -1088,15 +1111,14 @@ void ptable_dump(const char *msg, bool_t all) ** Prints basic information about the process table (number of ** entries, number with each process state, etc.). */ -void ptable_dump_counts(void) -{ +void ptable_dump_counts( void ) { uint_t nstate[N_STATES] = { 0 }; uint_t unknown = 0; int n = 0; pcb_t *ptr = ptable; - while (n < N_PROCS) { - if (ptr->state < 0 || ptr->state >= N_STATES) { + while( n < N_PROCS ) { + if( ptr->state < 0 || ptr->state >= N_STATES ) { ++unknown; } else { ++nstate[ptr->state]; @@ -1105,12 +1127,10 @@ void ptable_dump_counts(void) ++ptr; } - cio_printf("Ptable: %u ***", unknown); - for (n = 0; n < N_STATES; ++n) { - if (nstate[n]) { - cio_printf(" %u %s", nstate[n], - state_str[n] != NULL ? state_str[n] : "???"); - } + cio_printf( "Ptable: %u ***", unknown ); + for( n = 0; n < N_STATES; ++n ) { + cio_printf( " %u %s", nstate[n], + state_str[n] != NULL ? state_str[n] : "???" ); } - cio_putchar('\n'); + cio_putchar( '\n' ); } diff --git a/kernel/old/sio.c b/kernel/old/sio.c new file mode 100644 index 0000000..a5c7b75 --- /dev/null +++ b/kernel/old/sio.c @@ -0,0 +1,694 @@ +/** +** @file sio.c +** +** @author Warren R. Carithers +** +** @brief SIO module +** +** For maximum compatibility from semester to semester, this code uses +** several "stand-in" type names and macros which should be defined +** in the accompanying "compat.h" header file if they're not part of +** the baseline system: +** +** standard-sized integer types: intN_t, uintN_t +** other types: PCBTYPE, QTYPE +** scheduler functions: SCHED, DISPATCH +** queue functions: QCREATE, QLENGTH, QDEQUE +** other functions: SLENGTH +** sio read queue: QNAME +** +** Our SIO scheme is very simple: +** +** Input: We maintain a buffer of incoming characters that haven't +** yet been read by processes. When a character comes in, if +** there is no process waiting for it, it goes in the buffer; +** otherwise, the first waiting process is awakeneda and it +** gets the character. +** +** When a process invokes readch(), if there is a character in +** the input buffer, the process gets it; otherwise, it is +** blocked until input appears +** +** Communication with system calls is via two routines. +** sio_readc() returns the first available character (if +** there is one), resetting the input variables if this was +** the last character in the buffer. If there are no +** characters in the buffer, sio_read() returns a -1 +** (presumably so the requesting process can be blocked). +** +** sio_read() copies the contents of the input buffer into +** a user-supplied buffer. It returns the number of characters +** copied. If there are no characters available, return a -1. +** +** Output: We maintain a buffer of outgoing characters that haven't +** yet been sent to the device, and an indication of whether +** or not we are in the middle of a transmit sequence. When +** an interrupt comes in, if there is another character to +** send we copy it to the transmitter buffer; otherwise, we +** end the transmit sequence. +** +** Communication with user processes is via three functions. +** sio_writec() writes a single character; sio_write() +** writes a sized buffer full of characters; sio_puts() +** prints a NUL-terminated string. If we are in the middle +** of a transmit sequence, all characters will be added +** to the output buffer (from where they will be sent +** automatically); otherwise, we send the first character +** directly, add the rest of the characters (if there are +** any) to the output buffer, and set the "sending" flag +** to indicate that we're expecting a transmitter interrupt. +*/ + +#define KERNEL_SRC + +// this should do all includes required for this OS +#include + +// all other framework includes are next +#include +#include +#include + +#include +#include + +/* +** PRIVATE DEFINITIONS +*/ + +#define BUF_SIZE 2048 + +/* +** PRIVATE GLOBALS +*/ + + // input character buffer +static char inbuffer[ BUF_SIZE ]; +static char *inlast; +static char *innext; +static uint32_t incount; + + // output character buffer +static char outbuffer[ BUF_SIZE ]; +static char *outlast; +static char *outnext; +static uint32_t outcount; + + // output control flag +static int sending; + + // interrupt register status +static uint8_t ier; + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +// queue for read-blocked processes +#ifdef QNAME +QTYPE QNAME; +#endif + +/* +** PRIVATE FUNCTIONS +*/ + +/** +** sio_isr(vector,ecode) +** +** Interrupt handler for the SIO module. Handles all pending +** events (as described by the SIO controller). +** +** @param vector The interrupt vector number for this interrupt +** @param ecode The error code associated with this interrupt +*/ +static void sio_isr( int vector, int ecode ) { + int ch; + +#if TRACING_SIO_ISR + cio_puts( "SIO: int:" ); +#endif + // + // Must process all pending events; loop until the IRR + // says there's nothing else to do. + // + + for(;;) { + + // get the "pending event" indicator + int iir = inb( UA4_IIR ) & UA4_IIR_INT_PRI_MASK; + + // process this event + switch( iir ) { + + case UA4_IIR_LINE_STATUS: + // shouldn't happen, but just in case.... + cio_printf( "** SIO int, LSR = %02x\n", inb(UA4_LSR) ); + break; + + case UA4_IIR_RX: +#if TRACING_SIO_ISR + cio_puts( " RX" ); +#endif + // get the character + ch = inb( UA4_RXD ); + if( ch == '\r' ) { // map CR to LF + ch = '\n'; + } +#if TRACING_SIO_ISR + cio_printf( " ch %02x", ch ); +#endif + +#ifdef QNAME + // + // If there is a waiting process, this must be + // the first input character; give it to that + // process and awaken the process. + // + + if( !QEMPTY(QNAME) ) { + PCBTYPE *pcb; + + QDEQUE( QNAME, pcb ); + // make sure we got a non-NULL result + assert( pcb ); + + // return char via arg #2 and count in EAX + char *buf = (char *) ARG(pcb,2); + *buf = ch & 0xff; + RET(pcb) = 1; + SCHED( pcb ); + + } else { +#endif /* QNAME */ + + // + // Nobody waiting - add to the input buffer + // if there is room, otherwise just ignore it. + // + + if( incount < BUF_SIZE ) { + *inlast++ = ch; + ++incount; + } + +#ifdef QNAME + } +#endif /* QNAME */ + break; + + case UA5_IIR_RX_FIFO: + // shouldn't happen, but just in case.... + ch = inb( UA4_RXD ); + cio_printf( "** SIO FIFO timeout, RXD = %02x\n", ch ); + break; + + case UA4_IIR_TX: +#if TRACING_SIO_ISR + cio_puts( " TX" ); +#endif + // if there is another character, send it + if( sending && outcount > 0 ) { +#if TRACING_SIO_ISR + cio_printf( " ch %02x", *outnext ); +#endif + outb( UA4_TXD, *outnext ); + ++outnext; + // wrap around if necessary + if( outnext >= (outbuffer + BUF_SIZE) ) { + outnext = outbuffer; + } + --outcount; +#if TRACING_SIO_ISR + cio_printf( " (outcount %d)", outcount ); +#endif + } else { +#if TRACING_SIO_ISR + cio_puts( " EOS" ); +#endif + // no more data - reset the output vars + outcount = 0; + outlast = outnext = outbuffer; + sending = 0; + // disable TX interrupts + sio_disable( SIO_TX ); + } + break; + + case UA4_IIR_NO_INT: +#if TRACING_SIO_ISR + cio_puts( " EOI\n" ); +#endif + // nothing to do - tell the PIC we're done + outb( PIC1_CMD, PIC_EOI ); + return; + + case UA4_IIR_MODEM_STATUS: + // shouldn't happen, but just in case.... + cio_printf( "** SIO int, MSR = %02x\n", inb(UA4_MSR) ); + break; + + default: + // uh-oh.... + sprint( b256, "sio isr: IIR %02x\n", ((uint32_t) iir) & 0xff ); + PANIC( 0, b256 ); + } + + } + + // should never reach this point! + assert( false ); +} + +/* +** PUBLIC FUNCTIONS +*/ + +/** +** sio_init() +** +** Initialize the UART chip. +*/ +void sio_init( void ) { + +#if TRACING_INIT + cio_puts( " Sio" ); +#endif + + /* + ** Initialize SIO variables. + */ + + memclr( (void *) inbuffer, sizeof(inbuffer) ); + inlast = innext = inbuffer; + incount = 0; + + memclr( (void *) outbuffer, sizeof(outbuffer) ); + outlast = outnext = outbuffer; + outcount = 0; + sending = 0; + + // queue of read-blocked processes + QCREATE( QNAME ); + + /* + ** Next, initialize the UART. + ** + ** Initialize the FIFOs + ** + ** this is a bizarre little sequence of operations + */ + + outb( UA5_FCR, 0x20 ); + outb( UA5_FCR, UA5_FCR_FIFO_RESET ); // 0x00 + outb( UA5_FCR, UA5_FCR_FIFO_EN ); // 0x01 + outb( UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR ); // 0x03 + outb( UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR | UA5_FCR_TXSR ); // 0x07 + + /* + ** disable interrupts + ** + ** note that we leave them disabled; sio_enable() must be + ** called to switch them back on + */ + + outb( UA4_IER, 0 ); + ier = 0; + + /* + ** select the divisor latch registers and set the data rate + */ + + outb( UA4_LCR, UA4_LCR_DLAB ); + outb( UA4_DLL, BAUD_LOW_BYTE( DL_BAUD_9600 ) ); + outb( UA4_DLM, BAUD_HIGH_BYTE( DL_BAUD_9600 ) ); + + /* + ** deselect the latch registers, by setting the data + ** characteristics in the LCR + */ + + outb( UA4_LCR, UA4_LCR_WLS_8 | UA4_LCR_1_STOP_BIT | UA4_LCR_NO_PARITY ); + + /* + ** Set the ISEN bit to enable the interrupt request signal, + ** and the DTR and RTS bits to enable two-way communication. + */ + + outb( UA4_MCR, UA4_MCR_ISEN | UA4_MCR_DTR | UA4_MCR_RTS ); + + /* + ** Install our ISR + */ + + install_isr( VEC_COM1, sio_isr ); +} + +/** +** sio_enable() +** +** Enable SIO interrupts +** +** usage: uint8_t old = sio_enable( uint8_t which ) +** +** @param which Bit mask indicating which interrupt(s) to enable +** +** @return the prior IER setting +*/ +uint8_t sio_enable( uint8_t which ) { + uint8_t old; + + // remember the current status + + old = ier; + + // figure out what to enable + + if( which & SIO_TX ) { + ier |= UA4_IER_TX_IE; + } + + if( which & SIO_RX ) { + ier |= UA4_IER_RX_IE; + } + + // if there was a change, make it + + if( old != ier ) { + outb( UA4_IER, ier ); + } + + // return the prior settings + + return( old ); +} + +/** +** sio_disable() +** +** Disable SIO interrupts +** +** usage: uint8_t old = sio_disable( uint8_t which ) +** +** @param which Bit mask indicating which interrupt(s) to disable +** +** @return the prior IER setting +*/ +uint8_t sio_disable( uint8_t which ) { + uint8_t old; + + // remember the current status + + old = ier; + + // figure out what to disable + + if( which & SIO_TX ) { + ier &= ~UA4_IER_TX_IE; + } + + if( which & SIO_RX ) { + ier &= ~UA4_IER_RX_IE; + } + + // if there was a change, make it + + if( old != ier ) { + outb( UA4_IER, ier ); + } + + // return the prior settings + + return( old ); +} + +/** +** sio_inq_length() +** +** Get the input queue length +** +** usage: int num = sio_inq_length() +** +** @return the count of characters still in the input queue +*/ +int sio_inq_length( void ) { + return( incount ); +} + +/** +** sio_readc() +** +** Get the next input character +** +** usage: int ch = sio_readc() +** +** @return the next character, or -1 if no character is available +*/ +int sio_readc( void ) { + int ch; + + // assume there is no character available + ch = -1; + + // + // If there is a character, return it + // + + if( incount > 0 ) { + + // take it out of the input buffer + ch = ((int)(*innext++)) & 0xff; + --incount; + + // reset the buffer variables if this was the last one + if( incount < 1 ) { + inlast = innext = inbuffer; + } + + } + + return( ch ); + +} + +/** +** sio_read(buf,length) +** +** Read the entire input buffer into a user buffer of a specified size +** +** usage: int num = sio_read( char *buffer, int length ) +** +** @param buf The destination buffer +** @param length Length of the buffer +** +** @return the number of bytes copied, or 0 if no characters were available +*/ + +int sio_read( char *buf, int length ) { + char *ptr = buf; + int copied = 0; + + // if there are no characters, just return 0 + + if( incount < 1 ) { + return( 0 ); + } + + // + // We have characters. Copy as many of them into the user + // buffer as will fit. + // + + while( incount > 0 && copied < length ) { + *ptr++ = *innext++ & 0xff; + if( innext > (inbuffer + BUF_SIZE) ) { + innext = inbuffer; + } + --incount; + ++copied; + } + + // reset the input buffer if necessary + + if( incount < 1 ) { + inlast = innext = inbuffer; + } + + // return the copy count + + return( copied ); +} + + +/** +** sio_writec( ch ) +** +** Write a character to the serial output +** +** usage: sio_writec( int ch ) +** +** @param ch Character to be written (in the low-order 8 bits) +*/ +void sio_writec( int ch ){ + + + // + // Must do LF -> CRLF mapping + // + + if( ch == '\n' ) { + sio_writec( '\r' ); + } + + // + // If we're currently transmitting, just add this to the buffer + // + + if( sending ) { + *outlast++ = ch; + ++outcount; + return; + } + + // + // Not sending - must prime the pump + // + + sending = 1; + outb( UA4_TXD, ch ); + + // Also must enable transmitter interrupts + + sio_enable( SIO_TX ); + +} + +/** +** sio_write( buffer, length ) +** +** Write a buffer of characters to the serial output +** +** usage: int num = sio_write( const char *buffer, int length ) +** +** @param buffer Buffer containing characters to write +** @param length Number of characters to write +** +** @return the number of characters copied into the SIO output buffer +*/ +int sio_write( const char *buffer, int length ) { + int first = *buffer; + const char *ptr = buffer; + int copied = 0; + + // + // If we are currently sending, we want to append all + // the characters to the output buffer; else, we want + // to append all but the first character, and then use + // sio_writec() to send the first one out. + // + + if( !sending ) { + ptr += 1; + copied++; + } + + while( copied < length && outcount < BUF_SIZE ) { + *outlast++ = *ptr++; + // wrap around if necessary + if( outlast >= (outbuffer + BUF_SIZE) ) { + outlast = outbuffer; + } + ++outcount; + ++copied; + } + + // + // We use sio_writec() to send out the first character, + // as it will correctly set all the other necessary + // variables for us. + // + + if( !sending ) { + sio_writec( first ); + } + + // Return the transfer count + + + return( copied ); + +} + +/** +** sio_puts( buf ) +** +** Write a NUL-terminated buffer of characters to the serial output +** +** usage: int num = sio_puts( const char *buffer ) +** +** @param buffer The buffer containing a NUL-terminated string +** +** @return the count of bytes transferred +*/ +int sio_puts( const char *buffer ) { + int n; // must be outside the loop so we can return it + + n = SLENGTH( buffer ); + sio_write( buffer, n ); + + return( n ); +} + +/** +** sio_dump( full ) +** +** dump the contents of the SIO buffers to the console +** +** usage: sio_dump(true) or sio_dump(false) +** +** @param full Boolean indicating whether or not a "full" dump +** is being requested (which includes the contents +** of the queues) +*/ + +void sio_dump( bool_t full ) { + int n; + char *ptr; + + // dump basic info into the status region + + cio_printf_at( 48, 0, + "SIO: IER %02x (%c%c%c) in %d ot %d", + ((uint32_t)ier) & 0xff, sending ? '*' : '.', + (ier & UA4_IER_TX_IE) ? 'T' : 't', + (ier & UA4_IER_RX_IE) ? 'R' : 'r', + incount, outcount ); + + // if we're not doing a full dump, stop now + + if( !full ) { + return; + } + + // also want the queue contents, but we'll + // dump them into the scrolling region + + if( incount ) { + cio_puts( "SIO input queue: \"" ); + ptr = innext; + for( n = 0; n < incount; ++n ) { + put_char_or_code( *ptr++ ); + } + cio_puts( "\"\n" ); + } + + if( outcount ) { + cio_puts( "SIO output queue: \"" ); + cio_puts( " ot: \"" ); + ptr = outnext; + for( n = 0; n < outcount; ++n ) { + put_char_or_code( *ptr++ ); + } + cio_puts( "\"\n" ); + } +} diff --git a/kernel/old/startup.S b/kernel/old/startup.S new file mode 100644 index 0000000..73a081e --- /dev/null +++ b/kernel/old/startup.S @@ -0,0 +1,153 @@ +/* +** @file startup.S +** +** @author Jon Coles +** @authors Warren R. Carithers, K. Reek +** +** SP startup code. +** +** This code prepares the various registers for execution of +** the program. It sets up all the segment registers and the +** runtime stack. By the time this code is running, we're in +** protected mode already. +*/ + +#define KERNEL_SRC +#define ASM_SRC + +# .arch i386 + +#include +#include +#include +#include +#include + +/* +** Configuration options - define in Makefile +** +** CLEAR_BSS include code to clear all BSS space +** OS_CONFIG OS-related (vs. just standalone) variations +*/ + +/* +** A symbol for locating the beginning of the code. +*/ + .globl begtext + + .text +begtext: + +/* +** The entry point. When we get here, we have just entered protected +** mode, so all the segment registers are incorrect except for CS. +*/ + .globl _start + +_start: + cli /* seems to be reset on entry to p. mode */ + movb $NMI_ENABLE, %al /* re-enable NMIs (bootstrap */ + outb $CMOS_ADDR /* turned them off) */ + +/* +** Set the data and stack segment registers (code segment register +** was set by the long jump that switched us into protected mode). +*/ + xorl %eax, %eax /* clear EAX */ + movw $GDT_DATA, %ax /* GDT entry #3 - data segment */ + movw %ax, %ds /* for all four data segment registers */ + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + movw $GDT_STACK, %ax /* entry #4 is the stack segment */ + movw %ax, %ss + + movl $TARGET_STACK, %esp /* set up the system stack pointer */ + +#ifdef CLEAR_BSS +/* +** Zero the BSS segment +** +** These symbols are defined automatically by the linker, but they're +** defined at their virtual addresses rather than their physical addresses, +** and we haven't enabled paging yet. +*/ + .globl __bss_start, _end + + movl $V2PNC(__bss_start), %edi +clearbss: + movl $0, (%edi) + addl $4, %edi + cmpl $V2PNC(_end), %edi + jb clearbss +#endif /* CLEAR_BSS */ + +/* +** Enable paging. We use "large" pages for the initial page directory +** so that a one-level hierarchy will work for us. Once we have set +** up our memory freelist, we'll create a two-level hierarchy using +** "normal" 4KB pages. +*/ + # enable large pages + movl %cr4, %eax + orl $(CR4_PSE), %eax + movl %eax, %cr4 + + # set the page directory + .globl firstpdir + movl $(V2PNC(firstpdir)), %eax + movl %eax, %cr3 + + # turn on paging + movl %cr0, %eax + orl $(CR0_PG), %eax + movl %eax, %cr0 + + # reset our stack pointer + movl $(kstack + SZ_KSTACK), %esp + + # set the initial frame pointer + xorl %ebp, %ebp + +/* +** Call the system initialization routine, and switch to +** executing at high addresses. We use an indirect jump +** here to avoid getting a PC-relative 'jmp' instruction. +** +** Alternate idea: push the address of isr_restore +** and just do an indirect jump? +*/ + .globl main + + movl $main, %eax + call *%eax + +/* +** At this point, main() must have created the first user +** process, and we're ready to shift into user mode. The user +** stack for that process must have the initial context in it; +** we treat this as a "return from interrupt" event, and just +** transfer to the code that restores the user context. +*/ + + .globl isr_restore + jmp isr_restore + + .data + +/* +** Define the kernel stack here, at a multiple-of-16 address +*/ + .p2align 4 + .globl kstack +kstack: .space SZ_KSTACK, 0 + +/* +** Define the initial kernel ESP here, as well. It should point +** to the first byte after the stack. +*/ + + .globl kernel_esp +kernel_esp: + .long kstack + SZ_KSTACK diff --git a/kernel/old/support.c b/kernel/old/support.c index 89834ee..d48ce59 100644 --- a/kernel/old/support.c +++ b/kernel/old/support.c @@ -29,16 +29,16 @@ ** each interrupt. These functions are called from the isr stub based ** on the interrupt number. */ -void (*isr_table[256])(int vector, int code); +void ( *isr_table[ 256 ] )( int vector, int code ); /* ** Format of an IDT entry. */ -typedef struct { - short offset_15_0; - short segment_selector; - short flags; - short offset_31_16; +typedef struct { + short offset_15_0; + short segment_selector; + short flags; + short offset_31_16; } IDT_Gate; /* @@ -59,12 +59,11 @@ typedef struct { #ifdef RPT_INT_UNEXP /* add any header includes you need here */ #endif -static void unexpected_handler(int vector, int code) -{ +static void unexpected_handler( int vector, int code ) { #ifdef RPT_INT_UNEXP - cio_printf("\n** UNEXPECTED vector %d code %d\n", vector, code); + cio_printf( "\n** UNEXPECTED vector %d code %d\n", vector, code ); #endif - panic("Unexpected interrupt"); + panic( "Unexpected interrupt" ); } /** @@ -76,24 +75,23 @@ static void unexpected_handler(int vector, int code) ** @param vector vector number for the interrupt that occurred ** @param code error code, or a dummy value */ -static void default_handler(int vector, int code) -{ +static void default_handler( int vector, int code ) { #ifdef RPT_INT_UNEXP - cio_printf("\n** vector %d code %d\n", vector, code); + cio_printf( "\n** vector %d code %d\n", vector, code ); #endif - if (vector >= 0x20 && vector < 0x30) { - if (vector > 0x27) { + if( vector >= 0x20 && vector < 0x30 ) { + if( vector > 0x27 ) { // must also ACK the secondary PIC - outb(PIC2_CMD, PIC_EOI); + outb( PIC2_CMD, PIC_EOI ); } - outb(PIC1_CMD, PIC_EOI); + outb( PIC1_CMD, PIC_EOI ); } else { /* ** All the "expected" interrupts will be handled by the ** code above. If we get down here, the isr table may ** have been corrupted. Print a message and don't return. */ - panic("Unexpected \"expected\" interrupt!"); + panic( "Unexpected \"expected\" interrupt!" ); } } @@ -108,12 +106,12 @@ static void default_handler(int vector, int code) ** @param vector vector number for the interrupt that occurred ** @param code error code, or a dummy value */ -static void mystery_handler(int vector, int code) -{ +static void mystery_handler( int vector, int code ) { #if defined(RPT_INT_MYSTERY) || defined(RPT_INT_UNEXP) - cio_printf("\nMystery interrupt!\nVector=0x%02x, code=%d\n", vector, code); + cio_printf( "\nMystery interrupt!\nVector=0x%02x, code=%d\n", + vector, code ); #endif - outb(PIC1_CMD, PIC_EOI); + outb( PIC1_CMD, PIC_EOI ); } /** @@ -121,38 +119,37 @@ static void mystery_handler(int vector, int code) ** ** Initialize the 8259 Programmable Interrupt Controller. */ -static void init_pic(void) -{ +static void init_pic( void ) { /* ** ICW1: start the init sequence, update ICW4 */ - outb(PIC1_CMD, PIC_CW1_INIT | PIC_CW1_NEED4); - outb(PIC2_CMD, PIC_CW1_INIT | PIC_CW1_NEED4); + outb( PIC1_CMD, PIC_CW1_INIT | PIC_CW1_NEED4 ); + outb( PIC2_CMD, PIC_CW1_INIT | PIC_CW1_NEED4 ); /* ** ICW2: primary offset of 0x20 in the IDT, secondary offset of 0x28 */ - outb(PIC1_DATA, PIC1_CW2_VECBASE); - outb(PIC2_DATA, PIC2_CW2_VECBASE); + outb( PIC1_DATA, PIC1_CW2_VECBASE ); + outb( PIC2_DATA, PIC2_CW2_VECBASE ); /* ** ICW3: secondary attached to line 2 of primary, bit mask is 00000100 ** secondary id is 2 */ - outb(PIC1_DATA, PIC1_CW3_SEC_IRQ2); - outb(PIC2_DATA, PIC2_CW3_SEC_ID); + outb( PIC1_DATA, PIC1_CW3_SEC_IRQ2 ); + outb( PIC2_DATA, PIC2_CW3_SEC_ID ); /* ** ICW4: want 8086 mode, not 8080/8085 mode */ - outb(PIC1_DATA, PIC_CW4_PM86); - outb(PIC2_DATA, PIC_CW4_PM86); + outb( PIC1_DATA, PIC_CW4_PM86 ); + outb( PIC2_DATA, PIC_CW4_PM86 ); /* ** OCW1: allow interrupts on all lines */ - outb(PIC1_DATA, PIC_MASK_NONE); - outb(PIC2_DATA, PIC_MASK_NONE); + outb( PIC1_DATA, PIC_MASK_NONE ); + outb( PIC2_DATA, PIC_MASK_NONE ); } /** @@ -166,8 +163,7 @@ static void init_pic(void) ** Note: generally, the handler invoked from the IDT will be a "stub" ** that calls the second-level C handler via the isr_table array. */ -static void set_idt_entry(int entry, void (*handler)(void)) -{ +static void set_idt_entry( int entry, void ( *handler )( void ) ) { IDT_Gate *g = (IDT_Gate *)IDT_ADDR + entry; g->offset_15_0 = (int)handler & 0xffff; @@ -185,18 +181,17 @@ static void set_idt_entry(int entry, void (*handler)(void)) ** are then installed for those interrupts we may get before a real ** handler is set up. */ -static void init_idt(void) -{ +static void init_idt( void ) { int i; - extern void (*isr_stub_table[256])(void); + extern void ( *isr_stub_table[ 256 ] )( void ); /* ** Make each IDT entry point to the stub for that vector. Also ** make each entry in the ISR table point to the default handler. */ - for (i = 0; i < 256; i++) { - set_idt_entry(i, isr_stub_table[i]); - install_isr(i, unexpected_handler); + for ( i=0; i < 256; i++ ) { + set_idt_entry( i, isr_stub_table[ i ] ); + install_isr( i, unexpected_handler ); } /* @@ -205,13 +200,13 @@ static void init_idt(void) ** will eventually install the "real" handler. */ - install_isr(VEC_KBD, default_handler); // cio_init() - install_isr(VEC_COM1, default_handler); // sio_init() - install_isr(VEC_TIMER, default_handler); // clk_init() - install_isr(VEC_SYSCALL, default_handler); // sys_init() - install_isr(VEC_PAGE_FAULT, default_handler); // vm_init() + install_isr( VEC_KBD, default_handler ); // cio_init() + install_isr( VEC_COM1, default_handler ); // sio_init() + install_isr( VEC_TIMER, default_handler ); // clk_init() + install_isr( VEC_SYSCALL, default_handler ); // sys_init() + install_isr( VEC_PAGE_FAULT, default_handler ); // vm_init() - install_isr(VEC_MYSTERY, mystery_handler); + install_isr( VEC_MYSTERY, mystery_handler ); } /* @@ -226,11 +221,10 @@ static void init_idt(void) ** ** Called when we find an unrecoverable error. */ -void panic(char *reason) -{ - __asm__("cli"); - cio_printf("\nPANIC: %s\nHalting...", reason); - for (;;) { +void panic( char *reason ) { + __asm__( "cli" ); + cio_printf( "\nPANIC: %s\nHalting...", reason ); + for(;;) { ; } } @@ -240,8 +234,7 @@ void panic(char *reason) ** ** (Re)initilizes the interrupt system. */ -void init_interrupts(void) -{ +void init_interrupts( void ) { init_idt(); init_pic(); } @@ -251,12 +244,13 @@ void init_interrupts(void) ** ** Installs a second-level handler for a specific interrupt. */ -void (*install_isr(int vector, void (*handler)(int, int)))(int, int) -{ - void (*old_handler)(int vector, int code); +void (*install_isr( int vector, + void (*handler)(int,int) ) ) ( int, int ) { - old_handler = isr_table[vector]; - isr_table[vector] = handler; + void ( *old_handler )( int vector, int code ); + + old_handler = isr_table[ vector ]; + isr_table[ vector ] = handler; return old_handler; } @@ -276,10 +270,10 @@ void (*install_isr(int vector, void (*handler)(int, int)))(int, int) ** ** Ultimately, just remember that DELAY VALUES ARE APPROXIMATE AT BEST. */ -void delay(int length) -{ - while (--length >= 0) { - for (int i = 0; i < 10000000; ++i) +void delay( int length ) { + + while( --length >= 0 ) { + for( int i = 0; i < 10000000; ++i ) ; } } diff --git a/kernel/old/syscalls.c b/kernel/old/syscalls.c index 92a0a23..7176cda 100644 --- a/kernel/old/syscalls.c +++ b/kernel/old/syscalls.c @@ -6,7 +6,7 @@ ** @brief System call implementations */ -#define KERNEL_SRC +#define KERNEL_SRC #include @@ -33,30 +33,28 @@ #if TRACING_SYSCALLS -#define SYSCALL_ENTER(x) \ - do { \ - cio_printf("--> %s, pid %08x", __func__, (uint32_t)(x)); \ - } while (0) +#define SYSCALL_ENTER(x) do { \ + cio_printf( "--> %s, pid %08x", __func__, (uint32_t) (x) ); \ + } while(0) #else -#define SYSCALL_ENTER(x) /* */ +#define SYSCALL_ENTER(x) /* */ -#endif /* TRACING_SYSCALLS */ +#endif /* TRACING_SYSCALLS */ #if TRACING_SYSRETS -#define SYSCALL_EXIT(x) \ - do { \ - cio_printf("<-- %s %08x\n", __func__, (uint32_t)(x)); \ - return; \ - } while (0) +#define SYSCALL_EXIT(x) do { \ + cio_printf( "<-- %s %08x\n", __func__, (uint32_t) (x) ); \ + return; \ + } while(0) #else #define SYSCALL_EXIT(x) return -#endif /* TRACING_SYSRETS */ +#endif /* TRACING_SYSRETS */ /* ** PRIVATE DATA TYPES @@ -73,7 +71,7 @@ // a macro to simplify syscall entry point specification // we don't declare these static because we may want to call // some of them from other parts of the kernel -#define SYSIMPL(x) void sys_##x(pcb_t *pcb) +#define SYSIMPL(x) void sys_##x( pcb_t * pcb ) /* ** Second-level syscall handlers @@ -97,26 +95,26 @@ ** ** Does not return */ -SYSIMPL(exit) -{ +SYSIMPL(exit) { + // sanity check - assert(pcb != NULL); + assert( pcb != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // retrieve the exit status of this process - pcb->exit_status = (int32_t)ARG(pcb, 1); + pcb->exit_status = (int32_t) ARG(pcb,1); // now, we need to do the following: // reparent any children of this process and wake up init if need be // find this process' parent and wake it up if it's waiting - - pcb_zombify(pcb); + + pcb_zombify( pcb ); // pick a new winner dispatch(); - SYSCALL_EXIT(0); + SYSCALL_EXIT( 0 ); } /** @@ -130,12 +128,12 @@ SYSIMPL(exit) ** terminated, or an error code; on success, returns the child's termination ** status via 'status' if that pointer is non-NULL. */ -SYSIMPL(waitpid) -{ +SYSIMPL(waitpid) { + // sanity check - assert(pcb != NULL); + assert( pcb != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); /* ** We need to do two things here: (1) find out whether or @@ -153,42 +151,47 @@ SYSIMPL(waitpid) */ // verify that we aren't looking for ourselves! - uint_t target = ARG(pcb, 1); + uint_t target = ARG(pcb,1); - if (target == pcb->pid) { + if( target == pcb->pid ) { RET(pcb) = E_BAD_PARAM; - SYSCALL_EXIT(E_BAD_PARAM); + SYSCALL_EXIT( E_BAD_PARAM ); } // Good. Now, figure out what we're looking for. pcb_t *child = NULL; - if (target != 0) { + if( target != 0 ) { + // we're looking for a specific child - child = pcb_find_pid(target); + child = pcb_find_pid( target ); + + if( child != NULL ) { - if (child != NULL) { // found the process; is it one of our children: - if (child->parent != pcb) { + if( child->parent != pcb ) { // NO, so we can't wait for it RET(pcb) = E_BAD_PARAM; - SYSCALL_EXIT(E_BAD_PARAM); + SYSCALL_EXIT( E_BAD_PARAM ); } // yes! is this one ready to be collected? - if (child->state != STATE_ZOMBIE) { + if( child->state != STATE_ZOMBIE ) { // no, so we'll have to block for now child = NULL; } } else { + // no such child RET(pcb) = E_BAD_PARAM; - SYSCALL_EXIT(E_BAD_PARAM); + SYSCALL_EXIT( E_BAD_PARAM ); + } } else { + // looking for any child // we need to find a process that is our child @@ -201,13 +204,15 @@ SYSIMPL(waitpid) // so we need to do the iteration ourselves register pcb_t *curr = ptable; - for (int i = 0; i < N_PROCS; ++i, ++curr) { - if (curr->parent == pcb) { + for( int i = 0; i < N_PROCS; ++i, ++curr ) { + + if( curr->parent == pcb ) { + // found one! found = true; // has it already exited? - if (curr->state == STATE_ZOMBIE) { + if( curr->state == STATE_ZOMBIE ) { // yes, so we're done here child = curr; break; @@ -215,11 +220,12 @@ SYSIMPL(waitpid) } } - if (!found) { + if( !found ) { // got through the loop without finding a child! RET(pcb) = E_NO_CHILDREN; - SYSCALL_EXIT(E_NO_CHILDREN); + SYSCALL_EXIT( E_NO_CHILDREN ); } + } /* @@ -235,24 +241,25 @@ SYSIMPL(waitpid) */ // did we find one to collect? - if (child == NULL) { + if( child == NULL ) { + // no - mark the parent as "Waiting" pcb->state = STATE_WAITING; - assert(pcb_queue_insert(waiting, pcb) == SUCCESS); + assert( pcb_queue_insert(waiting,pcb) == SUCCESS ); // select a new current process dispatch(); - SYSCALL_EXIT((uint32_t)current); + SYSCALL_EXIT( (uint32_t) current ); } // found a Zombie; collect its information and clean it up RET(pcb) = child->pid; // get "status" pointer from parent - int32_t *stat = (int32_t *)ARG(pcb, 2); + int32_t *stat = (int32_t *) ARG(pcb,2); // if stat is NULL, the parent doesn't want the status - if (stat != NULL) { + if( stat != NULL ) { // ******************************************************** // ** Potential VM issue here! This code assigns the exit // ** status into a variable in the parent's address space. @@ -265,9 +272,9 @@ SYSIMPL(waitpid) } // clean up the child - pcb_cleanup(child); + pcb_cleanup( child ); - SYSCALL_EXIT(RET(pcb)); + SYSCALL_EXIT( RET(pcb) ); } /** @@ -280,26 +287,26 @@ SYSIMPL(waitpid) ** Returns the child's PID to the parent, and 0 to the child, on success; ** else, returns an error code to the parent. */ -SYSIMPL(fork) -{ +SYSIMPL(fork) { + // sanity check - assert(pcb != NULL); + assert( pcb != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // Make sure there's room for another process! pcb_t *new; - if (pcb_alloc(&new) != SUCCESS || new == NULL) { + if( pcb_alloc(&new) != SUCCESS || new == NULL ) { RET(pcb) = E_NO_PROCS; - SYSCALL_EXIT(RET(pcb)); + SYSCALL_EXIT( RET(pcb) ); } // duplicate the memory image of the parent - int status = user_duplicate(new, pcb); - if (status != SUCCESS) { - pcb_free(new); + int status = user_duplicate( new, pcb ); + if( status != SUCCESS ) { + pcb_free( new ); RET(pcb) = status; - SYSCALL_EXIT(status); + SYSCALL_EXIT( status ); } // Set the child's identity. @@ -315,9 +322,9 @@ SYSIMPL(fork) RET(new) = 0; // Schedule the child, and let the parent continue. - schedule(new); + schedule( new ); - SYSCALL_EXIT(new->pid); + SYSCALL_EXIT( new->pid ); } /** @@ -334,30 +341,30 @@ SYSIMPL(fork) SYSIMPL(exec) { // sanity check - assert(pcb != NULL); + assert( pcb != NULL ); - uint_t what = ARG(pcb, 1); - const char **args = (const char **)ARG(pcb, 2); + uint_t what = ARG(pcb,1); + const char **args = (const char **) ARG(pcb,2); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // locate the requested program - prog_t *prog = user_locate(what); - if (prog == NULL) { + prog_t *prog = user_locate( what ); + if( prog == NULL ) { RET(pcb) = E_NOT_FOUND; - SYSCALL_EXIT(E_NOT_FOUND); + SYSCALL_EXIT( E_NOT_FOUND ); } // we have located the program, but before we can load it, // we need to clean up the existing VM hierarchy - vm_free(pcb->pdir); + vm_free( pcb->pdir ); pcb->pdir = NULL; // "load" it and set up the VM tables for this process - int status = user_load(prog, pcb, args, false); - if (status != SUCCESS) { + int status = user_load( prog, pcb, args ); + if( status != SUCCESS ) { RET(pcb) = status; - SYSCALL_EXIT(status); + SYSCALL_EXIT( status ); } /* @@ -373,7 +380,7 @@ SYSIMPL(exec) ** an error status to it. */ - schedule(pcb); + schedule( pcb ); dispatch(); } @@ -387,49 +394,52 @@ SYSIMPL(exec) ** Reads up to 'length' bytes from 'chan' into 'buffer'. Returns the ** count of bytes actually transferred. */ -SYSIMPL(read) -{ - // sanity check - assert(pcb != NULL); +SYSIMPL(read) { - SYSCALL_ENTER(pcb->pid); + // sanity check + assert( pcb != NULL ); + SYSCALL_ENTER( pcb->pid ); + // grab the arguments - uint_t chan = ARG(pcb, 1); - char *buf = (char *)ARG(pcb, 2); - uint_t len = ARG(pcb, 3); + uint_t chan = ARG(pcb,1); + char *buf = (char *) ARG(pcb,2); + uint_t len = ARG(pcb,3); // if the buffer is of length 0, we're done! - if (len == 0) { + if( len == 0 ) { RET(pcb) = 0; - SYSCALL_EXIT(0); + SYSCALL_EXIT( 0 ); } // try to get the next character(s) int n = 0; - if (chan == CHAN_CIO) { + if( chan == CHAN_CIO ) { + // console input is non-blocking - if (cio_input_queue() < 1) { + if( cio_input_queue() < 1 ) { RET(pcb) = 0; - SYSCALL_EXIT(0); + SYSCALL_EXIT( 0 ); } // at least one character - n = cio_gets(buf, len); + n = cio_gets( buf, len ); RET(pcb) = n; - SYSCALL_EXIT(n); + SYSCALL_EXIT( n ); + + } else if( chan == CHAN_SIO ) { - } else if (chan == CHAN_SIO) { // SIO input is blocking, so if there are no characters // available, we'll block this process - n = sio_read(buf, len); + n = sio_read( buf, len ); RET(pcb) = n; - SYSCALL_EXIT(n); + SYSCALL_EXIT( n ); + } // bad channel code RET(pcb) = E_BAD_PARAM; - SYSCALL_EXIT(E_BAD_PARAM); + SYSCALL_EXIT( E_BAD_PARAM ); } /** @@ -441,17 +451,17 @@ SYSIMPL(read) ** Writes 'length' bytes from 'buffer' to 'chan'. Returns the ** count of bytes actually transferred. */ -SYSIMPL(write) -{ +SYSIMPL(write) { + // sanity check - assert(pcb != NULL); + assert( pcb != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // grab the parameters - uint_t chan = ARG(pcb, 1); - char *buf = (char *)ARG(pcb, 2); - uint_t length = ARG(pcb, 3); + uint_t chan = ARG(pcb,1); + char *buf = (char *) ARG(pcb,2); + uint_t length = ARG(pcb,3); // this is almost insanely simple, but it does separate the // low-level device access fromm the higher-level syscall implementation @@ -460,21 +470,27 @@ SYSIMPL(write) int rval = length; // simplest case - if (length >= 0) { - if (chan == CHAN_CIO) { - cio_write(buf, length); + if( length >= 0 ) { + + if( chan == CHAN_CIO ) { + + cio_write( buf, length ); - } else if (chan == CHAN_SIO) { - sio_write(buf, length); + } else if( chan == CHAN_SIO ) { + + sio_write( buf, length ); } else { + rval = E_BAD_CHAN; + } + } RET(pcb) = rval; - SYSCALL_EXIT(rval); + SYSCALL_EXIT( rval ); } /** @@ -483,12 +499,12 @@ SYSIMPL(write) ** Implements: ** uint_t getpid( void ); */ -SYSIMPL(getpid) -{ +SYSIMPL(getpid) { + // sanity check! - assert(pcb != NULL); + assert( pcb != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // return the time RET(pcb) = pcb->pid; @@ -500,13 +516,13 @@ SYSIMPL(getpid) ** Implements: ** uint_t getppid( void ); */ -SYSIMPL(getppid) -{ +SYSIMPL(getppid) { + // sanity check! - assert(pcb != NULL); - assert(pcb->parent != NULL); + assert( pcb != NULL ); + assert( pcb->parent != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // return the time RET(pcb) = pcb->parent->pid; @@ -518,12 +534,12 @@ SYSIMPL(getppid) ** Implements: ** uint32_t gettime( void ); */ -SYSIMPL(gettime) -{ +SYSIMPL(gettime) { + // sanity check! - assert(pcb != NULL); + assert( pcb != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // return the time RET(pcb) = system_time; @@ -535,12 +551,12 @@ SYSIMPL(gettime) ** Implements: ** int getprio( void ); */ -SYSIMPL(getprio) -{ +SYSIMPL(getprio) { + // sanity check! - assert(pcb != NULL); + assert( pcb != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // return the time RET(pcb) = pcb->priority; @@ -552,18 +568,18 @@ SYSIMPL(getprio) ** Implements: ** int setprio( int new ); */ -SYSIMPL(setprio) -{ +SYSIMPL(setprio) { + // sanity check! - assert(pcb != NULL); + assert( pcb != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // remember the old priority int old = pcb->priority; // set the priority - pcb->priority = ARG(pcb, 1); + pcb->priority = ARG(pcb,1); // return the old value RET(pcb) = old; @@ -578,55 +594,56 @@ SYSIMPL(setprio) ** Marks the specified process (or the calling process, if PID is 0) ** as "killed". Returns 0 on success, else an error code. */ -SYSIMPL(kill) -{ +SYSIMPL(kill) { + // sanity check - assert(pcb != NULL); + assert( pcb != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // who is the victim? - uint_t pid = ARG(pcb, 1); + uint_t pid = ARG(pcb,1); // if it's this process, convert this into a call to exit() - if (pid == pcb->pid) { + if( pid == pcb->pid ) { pcb->exit_status = EXIT_KILLED; - pcb_zombify(pcb); + pcb_zombify( pcb ); dispatch(); - SYSCALL_EXIT(EXIT_KILLED); + SYSCALL_EXIT( EXIT_KILLED ); } // must be a valid "ordinary user" PID // QUESTION: what if it's the idle process? - if (pid < FIRST_USER_PID) { + if( pid < FIRST_USER_PID ) { RET(pcb) = E_FAILURE; - SYSCALL_EXIT(E_FAILURE); + SYSCALL_EXIT( E_FAILURE ); } // OK, this is an acceptable victim; see if it exists - pcb_t *victim = pcb_find_pid(pid); - if (victim == NULL) { + pcb_t *victim = pcb_find_pid( pid ); + if( victim == NULL ) { // nope! RET(pcb) = E_NOT_FOUND; - SYSCALL_EXIT(E_NOT_FOUND); + SYSCALL_EXIT( E_NOT_FOUND ); } // must have a state that is possible - assert(victim->state >= FIRST_VIABLE && victim->state < N_STATES); + assert( victim->state >= FIRST_VIABLE && victim->state < N_STATES ); // how we perform the kill depends on the victim's state int32_t status = SUCCESS; - switch (victim->state) { - case STATE_KILLED: // FALL THROUGH + switch( victim->state ) { + + case STATE_KILLED: // FALL THROUGH case STATE_ZOMBIE: // you can't kill it if it's already dead RET(pcb) = SUCCESS; break; - case STATE_READY: // FALL THROUGH - case STATE_SLEEPING: // FALL THROUGH - case STATE_BLOCKED: // FALL THROUGH + case STATE_READY: // FALL THROUGH + case STATE_SLEEPING: // FALL THROUGH + case STATE_BLOCKED: // FALL THROUGH // here, the process is on a queue somewhere; mark // it as "killed", and let the scheduler deal with it victim->state = STATE_KILLED; @@ -636,7 +653,7 @@ SYSIMPL(kill) case STATE_RUNNING: // we have met the enemy, and it is us! pcb->exit_status = EXIT_KILLED; - pcb_zombify(pcb); + pcb_zombify( pcb ); status = EXIT_KILLED; // we need a new current process dispatch(); @@ -646,8 +663,8 @@ SYSIMPL(kill) // similar to the 'running' state, but we don't need // to dispatch a new process victim->exit_status = EXIT_KILLED; - status = pcb_queue_remove_this(waiting, victim); - pcb_zombify(victim); + status = pcb_queue_remove_this( waiting, victim ); + pcb_zombify( victim ); RET(pcb) = status; break; @@ -655,14 +672,15 @@ SYSIMPL(kill) // this is a really bad potential problem - we have an // unexpected or bogus process state, but we didn't // catch that earlier. - sprint(b256, "*** kill(): victim %d, odd state %d\n", victim->pid, - victim->state); - PANIC(0, b256); + sprint( b256, "*** kill(): victim %d, odd state %d\n", + victim->pid, victim->state ); + PANIC( 0, b256 ); } - SYSCALL_EXIT(status); + SYSCALL_EXIT( status ); } + /** ** sys_sleep - put the calling process to sleep for some length of time ** @@ -672,33 +690,35 @@ SYSIMPL(kill) ** Puts the calling process to sleep for 'ms' milliseconds (or just yields ** the CPU if 'ms' is 0). ** Returns the time the process spent sleeping. */ -SYSIMPL(sleep) -{ +SYSIMPL(sleep) { + // sanity check - assert(pcb != NULL); + assert( pcb != NULL ); - SYSCALL_ENTER(pcb->pid); + SYSCALL_ENTER( pcb->pid ); // get the desired duration - uint_t length = ARG(pcb, 1); + uint_t length = ARG( pcb, 1 ); + + if( length == 0 ) { - if (length == 0) { // just yield the CPU // sleep duration is 0 RET(pcb) = 0; // back on the ready queue - schedule(pcb); + schedule( pcb ); } else { + // sleep for a while pcb->wakeup = system_time + length; - if (pcb_queue_insert(sleeping, pcb) != SUCCESS) { + if( pcb_queue_insert(sleeping,pcb) != SUCCESS ) { // something strange is happening - WARNING("sleep pcb insert failed"); + WARNING( "sleep pcb insert failed" ); // if this is the current process, report an error - if (current == pcb) { + if( current == pcb ) { RET(pcb) = -1; } // return without dispatching a new process @@ -707,7 +727,7 @@ SYSIMPL(sleep) } // only dispatch if the current process called us - if (pcb == current) { + if( pcb == current ) { current = NULL; dispatch(); } @@ -726,14 +746,20 @@ SYSIMPL(sleep) ** position in the initialization list is irrelevant. */ -static void (*const syscalls[N_SYSCALLS])(pcb_t *) = { - [SYS_exit] = sys_exit, [SYS_waitpid] = sys_waitpid, - [SYS_fork] = sys_fork, [SYS_exec] = sys_exec, - [SYS_read] = sys_read, [SYS_write] = sys_write, - [SYS_getpid] = sys_getpid, [SYS_getppid] = sys_getppid, - [SYS_gettime] = sys_gettime, [SYS_getprio] = sys_getprio, - [SYS_setprio] = sys_setprio, [SYS_kill] = sys_kill, - [SYS_sleep] = sys_sleep +static void (* const syscalls[N_SYSCALLS])( pcb_t * ) = { + [ SYS_exit ] = sys_exit, + [ SYS_waitpid ] = sys_waitpid, + [ SYS_fork ] = sys_fork, + [ SYS_exec ] = sys_exec, + [ SYS_read ] = sys_read, + [ SYS_write ] = sys_write, + [ SYS_getpid ] = sys_getpid, + [ SYS_getppid ] = sys_getppid, + [ SYS_gettime ] = sys_gettime, + [ SYS_getprio ] = sys_getprio, + [ SYS_setprio ] = sys_setprio, + [ SYS_kill ] = sys_kill, + [ SYS_sleep ] = sys_sleep }; /** @@ -744,40 +770,40 @@ static void (*const syscalls[N_SYSCALLS])(pcb_t *) = { ** @param vector Vector number for this interrupt ** @param code Error code (0 for this interrupt) */ -static void sys_isr(int vector, int code) -{ +static void sys_isr( int vector, int code ) { + // keep the compiler happy - (void)vector; - (void)code; + (void) vector; + (void) code; // sanity check! - assert(current != NULL); - assert(current->context != NULL); + assert( current != NULL ); + assert( current->context != NULL ); // retrieve the syscall code - int num = REG(current, eax); + int num = REG( current, eax ); #if TRACING_SYSCALLS - cio_printf("** --> SYS pid %u code %u\n", current->pid, num); + cio_printf( "** --> SYS pid %u code %u\n", current->pid, num ); #endif // validate it - if (num < 0 || num >= N_SYSCALLS) { + if( num < 0 || num >= N_SYSCALLS ) { // bad syscall number // could kill it, but we'll just force it to exit num = SYS_exit; - ARG(current, 1) = EXIT_BAD_SYSCALL; + ARG(current,1) = EXIT_BAD_SYSCALL; } // call the handler - syscalls[num](current); + syscalls[num]( current ); #if TRACING_SYSCALLS - cio_printf("** <-- SYS pid %u ret %u\n", current->pid, RET(current)); + cio_printf( "** <-- SYS pid %u ret %u\n", current->pid, RET(current) ); #endif // tell the PIC we're done - outb(PIC1_CMD, PIC_EOI); + outb( PIC1_CMD, PIC_EOI ); } /* @@ -792,12 +818,12 @@ static void sys_isr(int vector, int code) ** Dependencies: ** Must be called after cio_init() */ -void sys_init(void) -{ +void sys_init( void ) { + #if TRACING_INIT - cio_puts(" Sys"); + cio_puts( " Sys" ); #endif // install the second-stage ISR - install_isr(VEC_SYSCALL, sys_isr); + install_isr( VEC_SYSCALL, sys_isr ); } diff --git a/kernel/old/user.c b/kernel/old/user.c index 5759534..c41867e 100644 --- a/kernel/old/user.c +++ b/kernel/old/user.c @@ -6,7 +6,7 @@ ** @brief User-level code manipulation routines */ -#define KERNEL_SRC +#define KERNEL_SRC #include @@ -35,16 +35,16 @@ ** Location of the "user blob" in memory. ** ** These variables are filled in by the code in startup.S using values -** passed to it from the bootstrap. +** passed to it from the bootstrap. ** ** These are visible so that the startup code can find them. */ -uint16_t user_offset; // byte offset from the segment base -uint16_t user_segment; // segment base address -uint16_t user_sectors; // number of 512-byte sectors it occupies +uint16_t user_offset; // byte offset from the segment base +uint16_t user_segment; // segment base address +uint16_t user_sectors; // number of 512-byte sectors it occupies -header_t *user_header; // filled in by the user_init routine -prog_t *prog_table; // filled in by the user_init routine +header_t *user_header; // filled in by the user_init routine +prog_t *prog_table; // filled in by the user_init routine /* ** PRIVATE FUNCTIONS @@ -65,117 +65,78 @@ static char ebuf[16]; */ // interpret the file class -static const char *fh_eclass(e32_si class) -{ - switch (class) { - case ELF_CLASS_NONE: - return ("None"); - break; - case ELF_CLASS_32: - return ("EC32"); - break; - case ELF_CLASS_64: - return ("EC64"); - break; +static const char *fh_eclass( e32_si class ) { + switch( class ) { + case ELF_CLASS_NONE: return( "None" ); break; + case ELF_CLASS_32: return( "EC32" ); break; + case ELF_CLASS_64: return( "EC64" ); break; } - return ("????"); + return( "????" ); } // interpret the data encoding -static const char *fh_edata(e32_si data) -{ - switch (data) { - case ELF_DATA_NONE: - return ("Invd"); - break; - case ELF_DATA_2LSB: - return ("2CLE"); - break; - case ELF_DATA_2MSB: - return ("2CBE"); - break; +static const char *fh_edata( e32_si data ) { + switch( data ) { + case ELF_DATA_NONE: return( "Invd" ); break; + case ELF_DATA_2LSB: return( "2CLE" ); break; + case ELF_DATA_2MSB: return( "2CBE" ); break; } - return ("????"); + return( "????" ); } // interpret the file type -static const char *fh_htype(e32_h type) -{ - switch (type) { - case ET_NONE: - return ("none"); - break; - case ET_REL: - return ("rel"); - break; - case ET_EXEC: - return ("exec"); - break; - case ET_DYN: - return ("dyn"); - break; - case ET_CORE: - return ("core"); - break; +static const char *fh_htype( e32_h type ) { + switch( type ) { + case ET_NONE: return( "none" ); break; + case ET_REL: return( "rel" ); break; + case ET_EXEC: return( "exec" ); break; + case ET_DYN: return( "dyn" ); break; + case ET_CORE: return( "core" ); break; default: - if (type >= ET_LO_OS && type <= ET_HI_OS) - return ("OSsp"); - else if (type >= ET_LO_CP && type <= ET_HI_CP) - return ("CPsp"); + if( type >= ET_LO_OS && type <= ET_HI_OS ) + return( "OSsp" ); + else if( type >= ET_LO_CP && type <= ET_HI_CP ) + return( "CPsp" ); } - sprint(ebuf, "0x%04x", type); - return ((const char *)ebuf); + sprint( ebuf, "0x%04x", type ); + return( (const char *) ebuf ); } // interpret the machine type -static const char *fh_mtype(e32_h machine) -{ - switch (machine) { - case EM_NONE: - return ("None"); - break; - case EM_386: - return ("386"); - break; - case EM_ARM: - return ("ARM"); - break; - case EM_X86_64: - return ("AMD64"); - break; - case EM_AARCH64: - return ("AARCH64"); - break; - case EM_RISCV: - return ("RISC-V"); - break; +static const char *fh_mtype( e32_h machine ) { + switch( machine ) { + case EM_NONE: return( "None" ); break; + case EM_386: return( "386" ); break; + case EM_ARM: return( "ARM" ); break; + case EM_X86_64: return( "AMD64" ); break; + case EM_AARCH64: return( "AARCH64" ); break; + case EM_RISCV: return( "RISC-V" ); break; } - return ("Other"); + return( "Other" ); } // dump the program header -static void dump_fhdr(elfhdr_t *hdr) -{ - cio_puts("File header: magic "); - for (int i = EI_MAG0; i <= EI_MAG3; ++i) - put_char_or_code(hdr->e_ident.bytes[i]); - cio_printf(" class %s", fh_eclass(hdr->e_ident.f.class)); - cio_printf(" enc %s", fh_edata(hdr->e_ident.f.data)); - cio_printf(" ver %u\n", hdr->e_ident.f.version); - cio_printf(" type %s", fh_htype(hdr->e_type)); - cio_printf(" mach %s", fh_mtype(hdr->e_machine)); - cio_printf(" vers %d", hdr->e_version); - cio_printf(" entr %08x\n", hdr->e_entry); - - cio_printf(" phoff %08x", hdr->e_phoff); - cio_printf(" shoff %08x", hdr->e_shoff); - cio_printf(" flags %08x", (uint32_t)hdr->e_flags); - cio_printf(" ehsize %u\n", hdr->e_ehsize); - cio_printf(" phentsize %u", hdr->e_phentsize); - cio_printf(" phnum %u", hdr->e_phnum); - cio_printf(" shentsize %u", hdr->e_shentsize); - cio_printf(" shnum %u", hdr->e_shnum); - cio_printf(" shstrndx %u\n", hdr->e_shstrndx); +static void dump_fhdr( elfhdr_t *hdr ) { + cio_puts( "File header: magic " ); + for( int i = EI_MAG0; i <= EI_MAG3; ++i ) + put_char_or_code( hdr->e_ident.bytes[i] ); + cio_printf( " class %s", fh_eclass(hdr->e_ident.f.class) ); + cio_printf( " enc %s", fh_edata(hdr->e_ident.f.data) ); + cio_printf( " ver %u\n", hdr->e_ident.f.version ); + cio_printf( " type %s", fh_htype(hdr->e_type) ); + cio_printf( " mach %s", fh_mtype(hdr->e_machine) ); + cio_printf( " vers %d", hdr->e_version ); + cio_printf( " entr %08x\n", hdr->e_entry ); + + cio_printf( " phoff %08x", hdr->e_phoff ); + cio_printf( " shoff %08x", hdr->e_shoff ); + cio_printf( " flags %08x", (uint32_t) hdr->e_flags ); + cio_printf( " ehsize %u\n", hdr->e_ehsize ); + cio_printf( " phentsize %u", hdr->e_phentsize ); + cio_printf( " phnum %u", hdr->e_phnum ); + cio_printf( " shentsize %u", hdr->e_shentsize ); + cio_printf( " shnum %u", hdr->e_shnum ); + cio_printf( " shstrndx %u\n", hdr->e_shstrndx ); } /* @@ -183,67 +144,45 @@ static void dump_fhdr(elfhdr_t *hdr) */ // categorize the header type -static const char *ph_type(e32_w type) -{ - switch (type) { - case PT_NULL: - return ("Unused"); - break; - case PT_LOAD: - return ("Load"); - break; - case PT_DYNAMIC: - return ("DLI"); - break; - case PT_INTERP: - return ("Interp"); - break; - case PT_NOTE: - return ("Aux"); - break; - case PT_SHLIB: - return ("RSVD"); - break; - case PT_PHDR: - return ("PTentry"); - break; - case PT_TLS: - return ("TLS"); - break; +static const char *ph_type( e32_w type ) { + switch( type ) { + case PT_NULL: return( "Unused" ); break; + case PT_LOAD: return( "Load" ); break; + case PT_DYNAMIC: return( "DLI" ); break; + case PT_INTERP: return( "Interp" ); break; + case PT_NOTE: return( "Aux" ); break; + case PT_SHLIB: return( "RSVD" ); break; + case PT_PHDR: return( "PTentry" ); break; + case PT_TLS: return( "TLS" ); break; default: - if (type >= PT_LO_OS && type <= PT_HI_OS) - return ("OSsp"); - else if (type >= PT_LO_CP && type <= PT_HI_CP) - return ("CPsp"); + if( type >= PT_LO_OS && type <= PT_HI_OS ) + return( "OSsp" ); + else if( type >= PT_LO_CP && type <= PT_HI_CP ) + return( "CPsp" ); } - sprint(ebuf, "0x%08x", type); - return ((const char *)ebuf); + sprint( ebuf, "0x%08x", type ); + return( (const char *) ebuf ); } // report the individual flags -static void ph_flags(e32_w flags) -{ - if ((flags & PF_R) != 0) - cio_putchar('R'); - if ((flags & PF_W) != 0) - cio_putchar('W'); - if ((flags & PF_E) != 0) - cio_putchar('X'); +static void ph_flags( e32_w flags ) { + if( (flags & PF_R) != 0 ) cio_putchar( 'R' ); + if( (flags & PF_W) != 0 ) cio_putchar( 'W' ); + if( (flags & PF_E) != 0 ) cio_putchar( 'X' ); } // dump a program header -static void dump_phdr(elfproghdr_t *hdr, int n) -{ - cio_printf("Prog header %d, type %s\n", n, ph_type(hdr->p_type)); - cio_printf(" offset %08x", hdr->p_offset); - cio_printf(" va %08x", hdr->p_va); - cio_printf(" pa %08x\n", hdr->p_pa); - cio_printf(" filesz %08x", hdr->p_filesz); - cio_printf(" memsz %08x", hdr->p_memsz); - cio_puts(" flags "); - ph_flags(hdr->p_flags); - cio_printf(" align %08x", hdr->p_align); - cio_putchar('\n'); +static void dump_phdr( elfproghdr_t *hdr, int n ) { + cio_printf( "Prog header %d, type %s\n", n, ph_type(hdr->p_type) ); + cio_printf( " offset %08x", hdr->p_offset ); + cio_printf( " va %08x", hdr->p_va ); + cio_printf( " pa %08x\n", hdr->p_pa ); + cio_printf( " filesz %08x", hdr->p_filesz ); + cio_printf( " memsz %08x", hdr->p_memsz ); + cio_puts( " flags " ); + ph_flags( hdr->p_flags ); + cio_printf( " align %08x", hdr->p_align ); + cio_putchar( '\n' ); } /* @@ -251,95 +190,58 @@ static void dump_phdr(elfproghdr_t *hdr, int n) */ // interpret the header type -static const char *sh_type(e32_w type) -{ - switch (type) { - case SHT_NULL: - return ("Unused"); - break; - case SHT_PROGBITS: - return ("Progbits"); - break; - case SHT_SYMTAB: - return ("Symtab"); - break; - case SHT_STRTAB: - return ("Strtab"); - break; - case SHT_RELA: - return ("Rela"); - break; - case SHT_HASH: - return ("Hash"); - break; - case SHT_DYNAMIC: - return ("Dynamic"); - break; - case SHT_NOTE: - return ("Note"); - break; - case SHT_NOBITS: - return ("Nobits"); - break; - case SHT_REL: - return ("Rel"); - break; - case SHT_SHLIB: - return ("Shlib"); - break; - case SHT_DYNSYM: - return ("Dynsym"); - break; +static const char *sh_type( e32_w type ) { + switch( type ) { + case SHT_NULL: return( "Unused" ); break; + case SHT_PROGBITS: return( "Progbits" ); break; + case SHT_SYMTAB: return( "Symtab" ); break; + case SHT_STRTAB: return( "Strtab" ); break; + case SHT_RELA: return( "Rela" ); break; + case SHT_HASH: return( "Hash" ); break; + case SHT_DYNAMIC: return( "Dynamic" ); break; + case SHT_NOTE: return( "Note" ); break; + case SHT_NOBITS: return( "Nobits" ); break; + case SHT_REL: return( "Rel" ); break; + case SHT_SHLIB: return( "Shlib" ); break; + case SHT_DYNSYM: return( "Dynsym" ); break; default: - if (type >= SHT_LO_CP && type <= SHT_HI_CP) - return ("CCsp"); - else if (type >= SHT_LO_US && type <= SHT_HI_US) - return ("User"); + if( type >= SHT_LO_CP && type <= SHT_HI_CP ) + return( "CCsp" ); + else if( type >= SHT_LO_US && type <= SHT_HI_US ) + return( "User" ); } - sprint(ebuf, "0x%08x", type); - return ((const char *)ebuf); + sprint( ebuf, "0x%08x", type ); + return( (const char *) ebuf ); } // report the various flags -static void sh_flags(unsigned int flags) -{ - if ((flags & SHF_WRITE) != 0) - cio_putchar('W'); - if ((flags & SHF_ALLOC) != 0) - cio_putchar('A'); - if ((flags & SHF_EXECINSTR) != 0) - cio_putchar('X'); - if ((flags & SHF_MERGE) != 0) - cio_putchar('M'); - if ((flags & SHF_STRINGS) != 0) - cio_putchar('S'); - if ((flags & SHF_INFO_LINK) != 0) - cio_putchar('L'); - if ((flags & SHF_LINK_ORDER) != 0) - cio_putchar('o'); - if ((flags & SHF_OS_NONCON) != 0) - cio_putchar('n'); - if ((flags & SHF_GROUP) != 0) - cio_putchar('g'); - if ((flags & SHF_TLS) != 0) - cio_putchar('t'); +static void sh_flags( unsigned int flags ) { + if( (flags & SHF_WRITE) != 0 ) cio_putchar( 'W' ); + if( (flags & SHF_ALLOC) != 0 ) cio_putchar( 'A' ); + if( (flags & SHF_EXECINSTR) != 0 ) cio_putchar( 'X' ); + if( (flags & SHF_MERGE) != 0 ) cio_putchar( 'M' ); + if( (flags & SHF_STRINGS) != 0 ) cio_putchar( 'S' ); + if( (flags & SHF_INFO_LINK) != 0 ) cio_putchar( 'L' ); + if( (flags & SHF_LINK_ORDER) != 0 ) cio_putchar( 'o' ); + if( (flags & SHF_OS_NONCON) != 0 ) cio_putchar( 'n' ); + if( (flags & SHF_GROUP) != 0 ) cio_putchar( 'g' ); + if( (flags & SHF_TLS) != 0 ) cio_putchar( 't' ); } // dump a section header ATTR_UNUSED -static void dump_shdr(elfsecthdr_t *hdr, int n) -{ - cio_printf("Sect header %d, type %d (%s), name %s\n", n, hdr->sh_type, - sh_type(hdr->sh_type)); - cio_printf(" flags %08x ", (uint32_t)hdr->sh_flags); - sh_flags(hdr->sh_flags); - cio_printf(" addr %08x", hdr->sh_addr); - cio_printf(" offset %08x", hdr->sh_offset); - cio_printf(" size %08x\n", hdr->sh_size); - cio_printf(" link %08x", hdr->sh_link); - cio_printf(" info %08x", hdr->sh_info); - cio_printf(" align %08x", hdr->sh_addralign); - cio_printf(" entsz %08x\n", hdr->sh_entsize); +static void dump_shdr( elfsecthdr_t *hdr, int n ) { + cio_printf( "Sect header %d, type %d (%s), name %s\n", + n, hdr->sh_type, sh_type(hdr->sh_type) ); + cio_printf( " flags %08x ", (uint32_t) hdr->sh_flags ); + sh_flags( hdr->sh_flags ); + cio_printf( " addr %08x", hdr->sh_addr ); + cio_printf( " offset %08x", hdr->sh_offset ); + cio_printf( " size %08x\n", hdr->sh_size ); + cio_printf( " link %08x", hdr->sh_link ); + cio_printf( " info %08x", hdr->sh_info ); + cio_printf( " align %08x", hdr->sh_addralign ); + cio_printf( " entsz %08x\n", hdr->sh_entsize ); } #endif @@ -356,51 +258,51 @@ static void dump_shdr(elfsecthdr_t *hdr, int n) ** E_LOAD_LIMIT more than N_LOADABLE PT_LOAD sections ** other status returned from vm_add() */ -static int read_phdrs(elfhdr_t *hdr, pcb_t *pcb) -{ +static int read_phdrs( elfhdr_t *hdr, pcb_t *pcb ) { + // sanity check - assert1(hdr != NULL); - assert2(pcb != NULL); + assert1( hdr != NULL ); + assert2( pcb != NULL ); #if TRACING_USER - cio_printf("read_phdrs(%08x,%08x)\n", (uint32_t)hdr, (uint32_t)pcb); + cio_printf( "read_phdrs(%08x,%08x)\n", (uint32_t) hdr, (uint32_t) pcb ); #endif // iterate through the program headers uint_t nhdrs = hdr->e_phnum; // pointer to the first header table entry - elfproghdr_t *curr = (elfproghdr_t *)((uint32_t)hdr + hdr->e_phoff); + elfproghdr_t *curr = (elfproghdr_t *) ((uint32_t) hdr + hdr->e_phoff); // process them all int loaded = 0; - for (uint_t i = 0; i < nhdrs; ++i, ++curr) { + for( uint_t i = 0; i < nhdrs; ++i, ++curr ) { + #if TRACING_ELF - dump_phdr(curr, i); + dump_phdr( curr, i ); #endif - if (curr->p_type != PT_LOAD) { + if( curr->p_type != PT_LOAD ) { // not loadable --> we'll skip it continue; } - if (loaded >= N_LOADABLE) { + if( loaded >= N_LOADABLE ) { #if TRACING_USER - cio_puts(" LIMIT\n"); + cio_puts( " LIMIT\n" ); #endif return E_LOAD_LIMIT; } // set a pointer to the bytes within the object file - char *data = (char *)(((uint32_t)hdr) + curr->p_offset); + char *data = (char *) (((uint32_t)hdr) + curr->p_offset); #if TRACING_USER - cio_printf(" data @ %08x", (uint32_t)data); + cio_printf( " data @ %08x", (uint32_t) data ); #endif // copy the pages into memory - int stat = vm_add(pcb->pdir, curr->p_flags & PF_W, false, - (char *)curr->p_va, curr->p_memsz, data, - curr->p_filesz); - if (stat != SUCCESS) { + int stat = vm_add( pcb->pdir, curr->p_flags & PF_W, false, + (char *) curr->p_va, curr->p_memsz, data, curr->p_filesz ); + if( stat != SUCCESS ) { // TODO what else should we do here? check for memory leak? return stat; } @@ -409,8 +311,8 @@ static int read_phdrs(elfhdr_t *hdr, pcb_t *pcb) pcb->sects[loaded].length = curr->p_memsz; pcb->sects[loaded].addr = curr->p_va; #if TRACING_USER - cio_printf(" loaded %u @ %08x\n", pcb->sects[loaded].length, - pcb->sects[loaded].addr); + cio_printf( " loaded %u @ %08x\n", + pcb->sects[loaded].length, pcb->sects[loaded].addr ); #endif ++loaded; } @@ -426,27 +328,39 @@ static int read_phdrs(elfhdr_t *hdr, pcb_t *pcb) ** @param pcb Pointer to the PCB for the process ** @param entry Entry point for the new process ** @param args Argument vector to be put in place -** @param sys Is the argument vector from kernel code? ** -** @return A (user VA) pointer to the context_t on the stack, or NULL +** @return A pointer to the context_t on the stack, or NULL */ -static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args, - bool_t sys) -{ -#if TRACING_USER - cio_printf("stksetup: pcb %08x, entry %08x, args %08x\n", (uint32_t)pcb, - entry, (uint32_t)args); -#endif +static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { /* - ** First, we need to calculate the space we'll need for the argument + ** First, we need to count the space we'll need for the argument ** vector and strings. + */ + + int argbytes = 0; + int argc = 0; + + while( args[argc] != NULL ) { + int n = strlen( args[argc] ) + 1; + // can't go over one page in size + if( (argbytes + n) > SZ_PAGE ) { + // oops - ignore this and any others + break; + } + argbytes += n; + ++argc; + } + + // Round up the byte count to the next multiple of four. + argbytes = (argbytes + 3) & MOD4_MASK; + + /* + ** Allocate the arrays. We are safe using dynamic arrays here + ** because we're using the OS stack, not the user stack. ** - ** Keeping track of kernel vs. user VAs is tricky, so we'll use - ** a prefix on variable names: kv_* is a kernel virtual address; - ** uv_* is a user virtual address. - ** - ** We rely on the C standard, section 6.7.8, to clear these arrays: + ** We want the argstrings and argv arrays to contain all zeroes. + ** The C standard states, in section 6.7.8, that ** ** "21 If there are fewer initializers in a brace-enclosed list ** than there are elements or members of an aggregate, or @@ -455,36 +369,31 @@ static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args, ** the remainder of the aggregate shall be initialized ** implicitly the same as objects that have static storage ** duration." + ** + ** Sadly, because we're using variable-sized arrays, we can't + ** rely on this, so we have to call memclr() instead. :-( In + ** truth, it doesn't really cost us much more time, but it's an + ** annoyance. */ - int argbytes = 0; // total length of arg strings - int argc = 0; // number of argv entries - const char *kv_strs[N_ARGS] = { 0 }; // converted user arg string pointers - int strlengths[N_ARGS] = { 0 }; // length of each string - const char *uv_argv[N_ARGS] = { 0 }; // argv pointers + char argstrings[ argbytes ]; + char *argv[ argc + 1 ]; - /* - ** IF the argument list given to us came from user code, we need - ** to convert its address and the addresses it contains to kernel - ** VAs; otherwise, we can use them directly. - */ - char **kv_args = sys ? args : vm_uva2kva(pcb->pdir, (void *)args); + CLEAR( argstrings ); + CLEAR( argv ); - while (kv_args[argc] != NULL) { - kv_strs[argc] = sys ? args[argc] : - vm_uva2kva(pcb->pdir, (void *)(kv_args[argc])); - strlengths[argc] = strlen(kv_strs[argc]) + 1; - // can't go over one page in size - if ((argbytes + strlengths[argc]) > SZ_PAGE) { - // oops - ignore this and any others - break; - } - argbytes += strlengths[argc]; - ++argc; + // Next, duplicate the argument strings, and create pointers to + // each one in our argv. + char *tmp = argstrings; + for( int i = 0; i < argc; ++i ) { + int nb = strlen(args[i]) + 1; // bytes (incl. NUL) in this string + strcpy( tmp, args[i] ); // add to our buffer + argv[i] = tmp; // remember where it was + tmp += nb; // move on } - // Round up the byte count to the next multiple of four. - argbytes = (argbytes + 3) & MOD4_MASK; + // trailing NULL pointer + argv[argc] = NULL; /* ** The pages for the stack were cleared when they were allocated, @@ -496,7 +405,7 @@ static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args, ** The user code was linked with a startup function that defines ** the entry point (_start), calls main(), and then calls exit() ** if main() returns. We need to set up the stack this way: - ** + ** ** esp -> context <- context save area ** ... <- context save area ** context <- context save area @@ -510,73 +419,35 @@ static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args, ** Stack alignment rules for the SysV ABI i386 supplement dictate that ** the 'argc' parameter must be at an address that is a multiple of 16; ** see below for more information. - ** - ** Ultimately, this is what the bottom end of the stack will look like: - ** - ** kvavptr - ** kvacptr | - ** | | - ** v v - ** argc argv av[0] av[1] etc NULL str0 str1 etc. - ** [....][....][....][....] ... [0000] ... [......0......0.........] - ** | ^ | | ^ ^ - ** | | | | | | - ** ------ | ---------------------|------- - ** --------------------------- - */ - - /* - ** We need to find the last page of the user stack. Find the page - ** table for the 4MB user address space. The physical address of its - ** frame is in the first page directory entry. Extract that from the - ** entry and convert it into a virtual address for the kernel to use. - */ - pde_t *kv_userpt = (pde_t *)P2V(PTE_ADDR(pcb->pdir[USER_PDE])); - assert(kv_userpt != NULL); - - /* - ** The final entries in that PMT are for the pages of the user stack. - ** Grab the physical address of the frame for the last one. (Again, - ** we need to convert it to a virtual address we can use.) */ - // the PMT entry for that page - pte_t pmt_entry = kv_userpt[USER_STK_LAST_PTE]; - assert(IS_PRESENT(pmt_entry)); - - // user VA for the first byte of that page - uint32_t *uvptr = (uint32_t *)USER_STACK_P2; + // Pointer to the last word in stack. We get this from the + // VM hierarchy. Get the PDE entry for the user address space. + pde_t stack_pde = pcb->pdir[USER_PDE]; - // convert that address to a kernel VA - uint32_t *kvptr = (uint32_t *)vm_uva2kva(pcb->pdir, (void *)uvptr); + // The PDE entry points to the PT, which is an array of PTE. The last + // two entries are for the stack; pull out the last one. + pte_t stack_pte = ((pte_t *)(stack_pde & MOD4K_MASK))[USER_STK_PTE2]; - /* - ** Move these pointers to where the string area will begin. We - ** will then back up to the next lower multiple-of-four address. - */ + // OK, now we have the PTE. The frame address of the last page is + // in this PTE. Find the address immediately after that. + uint32_t *ptr = (uint32_t *) + ((uint32_t)(stack_pte & MOD4K_MASK) + SZ_PAGE); - uint32_t uvstrptr = ((uint32_t)uvptr) + SZ_PAGE - argbytes; - uvstrptr &= MOD4_MASK; + // Pointer to where the arg strings should be filled in. + char *strings = (char *) ( (uint32_t) ptr - argbytes ); - uint32_t kvstrptr = ((uint32_t)kvptr) + SZ_PAGE - argbytes; - kvstrptr &= MOD4_MASK; + // back the pointer up to the nearest word boundary; because we're + // moving toward location 0, the nearest word boundary is just the + // next smaller address whose low-order two bits are zeroes + strings = (char *) ((uint32_t) strings & MOD4_MASK); - // Copy over the argv strings, remembering where each string begins - for (int i = 0; i < argc; ++i) { - // copy the string using kernel addresses - strcpy((char *)kvstrptr, kv_args[i]); - - // remember the user address where this string went - uv_argv[i] = (char *)uvstrptr; - - // adjust both string addresses - kvstrptr += strlengths[i]; - uvstrptr += strlengths[i]; - } + // Copy over the argv strings. + memcpy( (void *)strings, argstrings, argbytes ); /* - ** Next, we need to copy over the other data. Start by determining - ** where 'argc' should go. + ** Next, we need to copy over the argv pointers. Start by + ** determining where 'argc' should go. ** ** Stack alignment is controlled by the SysV ABI i386 supplement, ** version 1.2 (June 23, 2016), which states in section 2.2.2: @@ -590,43 +461,53 @@ static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args, ** ** Isn't technical documentation fun? Ultimately, this means that ** the first parameter to main() should be on the stack at an address - ** that is a multiple of 16. In our case, that is 'argc'. - */ - - /* + ** that is a multiple of 16. + ** ** The space needed for argc, argv, and the argv array itself is ** argc + 3 words (argc+1 for the argv entries, plus one word each - ** for argc and argv). We back up that much from the string area. + ** for argc and argv). We back up that much from 'strings'. */ int nwords = argc + 3; - uint32_t *kvacptr = ((uint32_t *)kvstrptr) - nwords; - uint32_t *uvacptr = ((uint32_t *)uvstrptr) - nwords; + uint32_t *acptr = ((uint32_t *) strings) - nwords; + + /* + ** Next, back up until we're at a multiple-of-16 address. Because we + ** are moving to a lower address, its upper 28 bits are identical to + ** the address we currently have, so we can do this with a bitwise + ** AND to just turn off the lower four bits. + */ - // back these up to multiple-of-16 addresses for stack alignment - kvacptr = (uint32_t *)(((uint32_t)kvacptr) & MOD16_MASK); - uvacptr = (uint32_t *)(((uint32_t)uvacptr) & MOD16_MASK); + acptr = (uint32_t *) ( ((uint32_t)acptr) & MOD16_MASK ); // copy in 'argc' - *kvacptr = argc; + *acptr = argc; - // 'argv' immediately follows 'argc', and 'argv[0]' immediately - // follows 'argv' - uint32_t *kvavptr = kvacptr + 2; - *(kvavptr - 1) = (uint32_t)kvavptr; + // next, 'argv', which follows 'argc'; 'argv' points to the + // word that follows it in the stack + uint32_t *avptr = acptr + 2; + *(acptr+1) = (uint32_t) avptr; - // now, the argv entries themselves - for (int i = 0; i < argc; ++i) { - *kvavptr++ = (uint32_t)uv_argv[i]; - } + /* + ** Next, we copy in all argc+1 pointers. + */ - // and the trailing NULL - *kvavptr = NULL; + // Adjust and copy the string pointers. + for( int i = 0; i <= argc; ++i ) { + if( argv[i] != NULL ) { + // an actual pointer - adjust it and copy it in + *avptr = (uint32_t) strings; + // skip to the next entry in the array + strings += strlen(argv[i]) + 1; + } else { + // end of the line! + *avptr = NULL; + } + ++avptr; + } /* - ** Almost done! - ** - ** Now we need to set up the initial context for the executing + ** Now, we need to set up the initial context for the executing ** process. ** ** When this process is dispatched, the context restore code will @@ -635,34 +516,27 @@ static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args, ** the interrupt "returns" to the entry point of the process. */ - // Locate the context save area on the stack by backup up one - // "context" from where the argc value is saved - context_t *kvctx = ((context_t *)kvacptr) - 1; - uint32_t uvctx = (uint32_t)(((context_t *)uvacptr) - 1); + // Locate the context save area on the stack. + context_t *ctx = ((context_t *) avptr) - 1; /* ** We cleared the entire stack earlier, so all the context ** fields currently contain zeroes. We now need to fill in ** all the important fields. - ** - ** Note: we don't need to set the ESP value for the process, - ** as the 'popa' that restores the general registers doesn't - ** actually restore ESP from the context area - it leaves it - ** where it winds up. */ - kvctx->eflags = DEFAULT_EFLAGS; // IF enabled, IOPL 0 - kvctx->eip = entry; // initial EIP - kvctx->cs = GDT_CODE; // segment registers - kvctx->ss = GDT_STACK; - kvctx->ds = kvctx->es = kvctx->fs = kvctx->gs = GDT_DATA; + ctx->eflags = DEFAULT_EFLAGS; // IE enabled, PPL 0 + ctx->eip = entry; // initial EIP + ctx->cs = GDT_CODE; // segment registers + ctx->ss = GDT_STACK; + ctx->ds = ctx->es = ctx->fs = ctx->gs = GDT_DATA; /* - ** Return the new context pointer to the caller as a user - ** space virtual address. + ** Return the new context pointer to the caller. It will be our + ** caller's responsibility to schedule this process. */ - - return ((context_t *)uvctx); + + return( ctx ); } /* @@ -674,36 +548,39 @@ static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args, ** ** Initializes the user support module. */ -void user_init(void) -{ +void user_init( void ) { + #if TRACING_INIT - cio_puts(" User"); -#endif + cio_puts( " User" ); +#endif // This is gross, but we need to get this information somehow. // Access the "user blob" data in the second bootstrap sector - uint16_t *blobdata = (uint16_t *)P2V(USER_BLOB_DATA); - user_offset = *blobdata++; + uint16_t *blobdata = (uint16_t *) USER_BLOB_DATA; + user_offset = *blobdata++; user_segment = *blobdata++; user_sectors = *blobdata++; #if TRACING_USER - cio_printf("\nUser blob: %u sectors @ %04x:%04x", user_sectors, - user_segment, user_offset); + cio_printf( "\nUser blob: %u sectors @ %04x:%04x", user_sectors, + user_segment, user_offset ); #endif // calculate the location of the user blob - if (user_sectors > 0) { + if( user_sectors > 0 ) { + // calculate the address of the header - user_header = (header_t *)(KERN_BASE + ((((uint_t)user_segment) << 4) + - ((uint_t)user_offset))); + user_header = (header_t *) + ( KERN_BASE + + ( (((uint_t)user_segment) << 4) + ((uint_t)user_offset) ) + ); // the program table immediate follows the blob header - prog_table = (prog_t *)(user_header + 1); + prog_table = (prog_t *) (user_header + 1); #if TRACING_USER - cio_printf(", hdr %08x, %u progs, tbl %08x\n", (uint32_t)user_header, - user_header->num, (uint32_t)prog_table); + cio_printf( ", hdr %08x, %u progs, tbl %08x\n", (uint32_t) user_header, + user_header->num, (uint32_t) prog_table ); #endif } else { @@ -711,7 +588,7 @@ void user_init(void) user_header = NULL; prog_table = NULL; #if TRACING_USER - cio_putchar('\n'); + cio_putchar( '\n' ); #endif } } @@ -725,19 +602,15 @@ void user_init(void) ** ** @return pointer to the program table entry in the code archive, or NULL */ -prog_t *user_locate(uint_t what) -{ -#if TRACING_USER - cio_printf("ulocate: %u\n", what); -#endif - +prog_t *user_locate( uint_t what ) { + // no programs if there is no blob! - if (user_header == NULL) { + if( user_header == NULL ) { return NULL; } // make sure this is a reasonable program to request - if (what >= user_header->num) { + if( what >= user_header->num ) { // no such program! return NULL; } @@ -746,7 +619,7 @@ prog_t *user_locate(uint_t what) prog_t *prog = &prog_table[what]; // if there are no bytes, it's useless - if (prog->size < 1) { + if( prog->size < 1 ) { return NULL; } @@ -764,11 +637,7 @@ prog_t *user_locate(uint_t what) ** ** @return the status of the duplicate attempt */ -int user_duplicate(pcb_t *new, pcb_t *old) -{ -#if TRACING_USER - cio_printf("udup: old %08x new %08x\n", (uint32_t)old, (uint32_t)new); -#endif +int user_duplicate( pcb_t *new, pcb_t *old ) { // We need to do a recursive duplication of the process address // space of the current process. First, we create a new user @@ -778,14 +647,14 @@ int user_duplicate(pcb_t *new, pcb_t *old) // create the initial VM hierarchy pde_t *pdir = vm_mkuvm(); - if (pdir == NULL) { + if( pdir == NULL ) { return E_NO_MEMORY; } new->pdir = pdir; // Next, add a USER_PDE page table that's a duplicate of the // current process' page table - if (!vm_uvmdup(new->pdir, old->pdir)) { + if( !vm_uvmdup(old->pdir,new->pdir) ) { // check for memory leak? return E_NO_MEMORY; } @@ -800,23 +669,26 @@ int user_duplicate(pcb_t *new, pcb_t *old) // modified to loop over the larger space. // pointer to the PMT for the user - pte_t *pt = (pte_t *)(pdir[USER_PDE]); - assert(pt != NULL); + pte_t *pt = (pte_t *) (pdir[USER_PDE]); + assert( pt != NULL ); - for (int i = 0; i < N_PTE; ++i) { + for( int i = 0; i < N_PTE; ++i ) { // get the current entry from the PMT pte_t entry = *pt; // if this entry is present, - if (IS_PRESENT(entry)) { + if( IS_PRESENT(entry) ) { + // duplicate the frame pointed to by this PTE - void *tmp = vm_pagedup((void *)PTE_ADDR(entry)); + void *tmp = vm_pagedup( (void *) PTE_ADDR(entry) ); // replace the old frame number with the new one - *pt = (pte_t)(((uint32_t)tmp) | PERMS(entry)); + *pt = (pte_t) (((uint32_t)tmp) | PERMS(entry) ); } else { + *pt = 0; + } ++pt; } @@ -833,74 +705,60 @@ int user_duplicate(pcb_t *new, pcb_t *old) ** @param ptab A pointer to the program table entry to be loaded ** @param pcb The PCB for the program being loaded ** @param args The argument vector for the program -** @param sys Is the argument vector from kernel code? ** ** @return the status of the load attempt */ -int user_load(prog_t *ptab, pcb_t *pcb, const char **args, bool_t sys) -{ - // NULL pointers are bad! - assert1(ptab != NULL); - assert1(pcb != NULL); - assert1(args != NULL); +int user_load( prog_t *ptab, pcb_t *pcb, const char **args ) { -#if TRACING_USER - cio_printf("Uload: prog '%s' pcb %08x args %08x\n", - ptab->name[0] ? ptab->name : "?", (uint32_t)pcb, (uint32_t)args); -#endif + // NULL pointers are bad! + assert1( ptab != NULL ); + assert1( pcb != NULL ); + assert1( args != NULL ); // locate the ELF binary - elfhdr_t *hdr = (elfhdr_t *)((uint32_t)user_header + ptab->offset); + elfhdr_t *hdr = (elfhdr_t *) ((uint32_t)user_header + ptab->offset); #if TRACING_ELF - cio_printf("Load: ptab %08x: '%s', off %08x, size %08x, flags %08x\n", - (uint32_t)ptab, ptab->name, ptab->offset, ptab->size, - ptab->flags); - cio_printf(" args %08x:", (uint32_t)args); - if (sys) { - for (int i = 0; args[i] != NULL; ++i) { - cio_printf(" [%d] %s", i, args[i]); - } - } else { - char **kv_args = vm_uva2kva(pcb->pdir, args); - for (int i = 0; kv_args[i] != NULL; ++i) { - cio_printf(" [%d] %s", i, - (char *)vm_uva2kva(pcb->pdir, kv_args[i])); - } + cio_printf( "Load: ptab %08x: '%s', off %08x, size %08x, flags %08x\n", + (uint32_t) ptab, ptab->name, ptab->offset, ptab->size, + ptab->flags ); + cio_printf( " args %08x:", (uint32_t) args ); + for( int i = 0; args[i] != NULL; ++i ) { + cio_printf( " [%d] %s", i, args[i] ); } - cio_printf("\n pcb %08x (pid %u)\n", (uint32_t)pcb, pcb->pid); - dump_fhdr(hdr); + cio_printf( "\n pcb %08x (pid %u)\n", (uint32_t) pcb, pcb->pid ); + dump_fhdr( hdr ); #endif // verify the ELF header - if (hdr->e_ident.f.magic != ELF_MAGIC) { + if( hdr->e_ident.f.magic != ELF_MAGIC ) { return E_BAD_PARAM; } // allocate a page directory pcb->pdir = vm_mkuvm(); - if (pcb->pdir == NULL) { + if( pcb->pdir == NULL ) { return E_NO_MEMORY; } // read all the program headers - int stat = read_phdrs(hdr, pcb); - if (stat != SUCCESS) { - cio_printf("Uload: read_phdrs('%s') returned %d\n", ptab->name, stat); - PANIC(0, "User_load: phdr read failed"); + int stat = read_phdrs( hdr, pcb ); + if( stat != SUCCESS ) { + // TODO figure out a better way to deal with this + PANIC( 0, "user_load: phdr read failed" ); } // next, set up the runtime stack - just like setting up loadable // sections, except nothing to copy - stat = - vm_add(pcb->pdir, true, false, (void *)USER_STACK, SZ_USTACK, NULL, 0); - if (stat != SUCCESS) { - cio_printf("Uload: vm_add('%s') stack returned %d\n", ptab->name, stat); - PANIC(0, "user_load: vm_add stack failed"); + stat = vm_add( pcb->pdir, true, false, (void *) USER_STACK, + SZ_USTACK, NULL, 0 ); + if( stat != SUCCESS ) { + // TODO yadda yadda... + PANIC( 0, "user_load: vm_add failed" ); } // set up the command-line arguments - pcb->context = stack_setup(pcb, hdr->e_entry, args, sys); + pcb->context = stack_setup( pcb, hdr->e_entry, args ); return SUCCESS; } @@ -913,17 +771,13 @@ int user_load(prog_t *ptab, pcb_t *pcb, const char **args, bool_t sys) ** ** @param pcb The PCB of the program to be unloaded */ -void user_cleanup(pcb_t *pcb) -{ -#if TRACING_USER - cio_printf("Uclean: %08x\n", (uint32_t)pcb); -#endif - - if (pcb == NULL) { +void user_cleanup( pcb_t *pcb ) { + + if( pcb == NULL ) { // should this be an error? return; } - vm_free(pcb->pdir); + vm_free( pcb->pdir ); pcb->pdir = NULL; } diff --git a/kernel/old/vm.c b/kernel/old/vm.c index 814ff12..749bed3 100644 --- a/kernel/old/vm.c +++ b/kernel/old/vm.c @@ -6,7 +6,7 @@ ** @brief Kernel VM support */ -#define KERNEL_SRC +#define KERNEL_SRC #include @@ -37,244 +37,70 @@ pde_t *kpdir; ** @param vector Interrupt vector number ** @param code Error code pushed onto the stack */ -static void vm_isr(int vector, int code) -{ +static void vm_isr( int vector, int code ) { + // get whatever information we can from the fault pfec_t fault; - fault.u = (uint32_t)code; + fault.u = (uint32_t) code; uint32_t addr = r_cr2(); // report what we found - sprint(b256, - "** page fault @ 0x%08x %cP %c %cM %cRSV %c %cPK %cSS %cHLAT %cSGZ", - addr, fault.s.p ? ' ' : '!', fault.s.w ? 'W' : 'R', - fault.s.us ? 'U' : 'S', fault.s.rsvd ? ' ' : '!', - fault.s.id ? 'I' : 'D', fault.s.pk ? ' ' : '!', - fault.s.ss ? ' ' : '!', fault.s.hlat ? ' ' : '!', - fault.s.sgz ? ' ' : '!'); + sprint( b256, + "** page fault @ 0x%08x %cP %c %cM %cRSV %c %cPK %cSS %cHLAT %cSGZ", + addr, + fault.s.p ? ' ' : '!', + fault.s.w ? 'W' : 'R', + fault.s.us ? 'U' : 'S', + fault.s.rsvd ? ' ' : '!', + fault.s.id ? 'I' : 'D', + fault.s.pk ? ' ' : '!', + fault.s.ss ? ' ' : '!', + fault.s.hlat ? ' ' : '!', + fault.s.sgz ? ' ' : '!' + ); // and give up - PANIC(0, b256); + PANIC( 0, b256 ); } /** -** Name: ptcount -** -** Count the number of each type of entry in a page table. -** Returns a 32-bit result containing two 16-bit counts: +** Name: uva2kva ** -** Upper half Lower half -** PDIR: # of 4MB entries # of 'present' entries -** PMT: zero # of 'present' entries -** -** The number of "not present" can be calculated from these. +** Convert a user VA into a kernel address. Works for all addresses - +** if the address is a page address, the PERMS(va) value will be 0; +** otherwise, it is the offset into the page. ** -** @param pt Pointer to the page table -** @param dir Is it a page directory (vs. a page table)? +** @param pdir Pointer to the page directory to examine +** @param va Virtual address to check */ ATTR_UNUSED -static uint32_t ptcount(pte_t *ptr, bool_t dir) -{ - uint16_t n_np = 0, n_p = 0, n_lg = 0; +static void *uva2kva( pde_t *pdir, void *va ) { - for (int i = 0; i < N_PTE; ++i) { - pde_t entry = *ptr++; - if (!IS_PRESENT(entry)) { - ++n_np; - continue; - } - if (dir && IS_LARGE(entry)) { - ++n_lg; - } else { - ++n_p; - } + // find the PMT entry for this address + pte_t *pte = vm_getpte( pdir, va, false ); + if( pte == NULL ) { + return NULL; } - // n_lg will be 0 for PMTs - return (n_lg << 16) | n_p; -} - -// decode a PDE -static void pde_prt(uint32_t level, uint32_t i, uint32_t entry, bool_t all) -{ - if (!IS_PRESENT(entry) && !all) { - return; - } + // get the entry + pte_t entry = *pte; - // indent - for (int n = 0; n <= level; ++n) - cio_puts(" "); - - // line header - cio_printf("[%03x] %08x", i, entry); - - // perms - if (IS_LARGE(entry)) { // PS is 1 - if ((entry & PDE_PAT) != 0) - cio_puts(" PAT"); - if ((entry & PDE_G) != 0) - cio_puts(" G"); - cio_puts(" PS"); - if ((entry & PDE_D) != 0) - cio_puts(" D"); + // is this a valid address for the user? + if( IS_PRESENT(entry) ) { + return NULL; } - if ((entry & PDE_A) != 0) - cio_puts(" A"); - if ((entry & PDE_PCD) != 0) - cio_puts(" CD"); - if ((entry & PDE_PWT) != 0) - cio_puts(" WT"); - if ((entry & PDE_US) != 0) - cio_puts(" U"); - if ((entry & PDE_RW) != 0) - cio_puts(" W"); - - // frame address - cio_printf(" P --> %s %08x\n", IS_LARGE(entry) ? "Pg" : "PT", - PDE_ADDR(entry)); -} -// decode a PTE -static void pte_prt(uint32_t level, uint32_t i, uint32_t entry, bool_t all) -{ - if (!IS_PRESENT(entry) && !all) { - return; + // is this a system-only page? + if( IS_SYSTEM(entry) ) { + return NULL; } - // indent - for (int n = 0; n <= level; ++n) - cio_puts(" "); - - // line header - cio_printf("[%03x] %08x", i, entry); - - // perms - if ((entry & PTE_G) != 0) - cio_puts(" G"); - if ((entry & PTE_PAT) != 0) - cio_puts(" PAT"); - if ((entry & PTE_D) != 0) - cio_puts(" D"); - if ((entry & PTE_A) != 0) - cio_puts(" A"); - if ((entry & PTE_PCD) != 0) - cio_puts(" CD"); - if ((entry & PTE_PWT) != 0) - cio_puts(" WT"); - if ((entry & PTE_US) != 0) - cio_puts(" U"); - if ((entry & PTE_RW) != 0) - cio_puts(" W"); - - cio_printf(" P --> Pg %08x\n", PTE_ADDR(entry)); -} - -/** -** Name: ptdump -** -** Recursive helper for table hierarchy dump. -** -** @param level Current hierarchy level -** @param pt Page table to display -** @param dir Is it a page directory (vs. a page table)? -** @param mode How to display the entries -*/ -ATTR_UNUSED -static void ptdump(uint_t level, void *pt, bool_t dir, enum vmmode_e mode) -{ - pte_t *ptr = (pte_t *)pt; - - // indent two spaces per level - for (int n = 0; n < level; ++n) - cio_puts(" "); + // get the physical address + uint32_t frame = PTE_ADDR(*pte) | PERMS(va); - cio_printf("%s at 0x%08x:", dir ? "PDir" : "PTbl", (uint32_t)pt); - uint32_t nums = ptcount(ptr, dir); - if (dir) { - cio_printf(" 4MB=%u", (nums >> 16)); - } - cio_printf(" P=%u !P=%u\n", nums & 0xffff, - N_PTE - ((nums >> 16) + (nums & 0xffff))); - - for (uint32_t i = 0; i < (uint32_t)N_PTE; ++i) { - pte_t entry = *ptr++; - - // only process this entry if it's not empty - if (entry) { - if (dir) { - // this is a PDIR entry; could be either a 4MB - // page, or a PMT pointer - if (mode > Simple) { - pde_prt(level, i, entry, false); - if (!IS_LARGE(entry) && mode > OneLevel) { - ptdump(level + 1, (void *)P2V(PTE_ADDR(entry)), false, - mode); - } - } - } else { - // just a PMT entry - if (mode > Simple) { - pte_prt(level, i, entry, false); - } - } - } - } + return (void *) P2V(frame); } -/** -** Name: pmt_dump -** -** Dump the non-zero entries of a page table or directory -** -** @param pt The page table -** @param dir Is this a page directory? -** @param start First entry to process -** @param num Number of entries to process -*/ -ATTR_UNUSED -static void pmt_dump(pte_t *pt, bool_t dir, uint32_t start, uint32_t num) -{ - cio_printf("\n\nP%c dump", dir ? 'D' : 'T'); - cio_printf(" of %08x", (uint32_t)pt); - cio_printf(" [%03x] through [%03x]\n", start, start + num - 1); - - uint_t n = 0; - uint_t z = 0; - - for (uint_t i = 0; i < num; ++i) { - pte_t entry = pt[start + i]; - // four entries per line - if (n && ((n & 0x3) == 0)) { - cio_putchar('\n'); - } - if (IS_PRESENT(entry)) { - cio_printf(" %03x", start + i); - if (IS_LARGE(entry)) { - cio_printf(" 8 %05x", GET_4MFRAME(entry) << 10); - } else { - cio_printf(" 4 %05x", GET_4KFRAME(entry)); - } - ++n; - } else { - ++z; - } - // pause after every four lines of output - if (n && ((n & 0xf) == 0)) { - delay(DELAY_2_SEC); - } - } - - // partial line? - if ((n & 0x3) != 0) { - cio_putchar('\n'); - } - - if (z > 0) { - cio_printf(" %u entries were !P\n", z); - } - - delay(DELAY_2_SEC); -} /* ** PUBLIC FUNCTIONS @@ -285,83 +111,21 @@ static void pmt_dump(pte_t *pt, bool_t dir, uint32_t start, uint32_t num) ** ** Description: Initialize the VM module */ -void vm_init(void) -{ +void vm_init( void ) { + #if TRACING_INIT - cio_puts(" VM"); + cio_puts( " VM" ); #endif // set up the kernel's 4K-page directory kpdir = vm_mkkvm(); - assert(kpdir != NULL); - -#if TRACING_VM - cio_printf("vm_init: kpdir %08x, adding user pages\n", kpdir); -#endif - - // add the entries for the user address space - for (uint32_t addr = 0; addr < NUM_4MB; addr += SZ_PAGE) { - int stat = vm_map(kpdir, (void *)addr, addr, SZ_PAGE, PTE_US | PTE_RW); - if (stat != SUCCESS) { - cio_printf("vm_init, map %08x->%08x failed, status %d\n", addr, - addr, stat); - PANIC(0, "vm_init user range map failed"); - } -#if TRACING_VM - cio_putchar('.'); -#endif - } -#if TRACING_VM - cio_puts(" done\n"); -#endif + assert( kpdir != NULL ); // switch to it vm_set_kvm(); -#if TRACING_VM - cio_puts("vm_init: running on new kpdir\n"); -#endif - // install the page fault handler - install_isr(VEC_PAGE_FAULT, vm_isr); -} - -/** -** Name: vm_uva2kva -** -** Convert a user VA into a kernel address. Works for all addresses - -** if the address is a page address, the low-order nine bits will be -** zeroes; otherwise, they are the offset into the page, which is -** unchanged between the address spaces. -** -** @param pdir Pointer to the page directory to examine -** @param va Virtual address to check -*/ -void *vm_uva2kva(pde_t *pdir, void *va) -{ - // find the PMT entry for this address - pte_t *pte = vm_getpte(pdir, va, false); - if (pte == NULL) { - return NULL; - } - - // get the entry - pte_t entry = *pte; - - // is this a valid address for the user? - if (!IS_PRESENT(entry)) { - return NULL; - } - - // is this a system-only page? - if (IS_SYSTEM(entry)) { - return NULL; - } - - // get the physical address - uint32_t frame = PTE_ADDR(*pte) | PERMS(va); - - return (void *)P2V(frame); + install_isr( VEC_PAGE_FAULT, vm_isr ); } /** @@ -373,11 +137,10 @@ void *vm_uva2kva(pde_t *pdir, void *va) ** ** @return a pointer to the new, duplicate page, or NULL */ -void *vm_pagedup(void *old) -{ - void *new = (void *)km_page_alloc(); - if (new != NULL) { - blkmov(new, old, SZ_PAGE); +void *vm_pagedup( void *old ) { + void *new = (void *) km_page_alloc(); + if( new != NULL ) { + blkmov( new, old, SZ_PAGE ); } return new; } @@ -387,54 +150,58 @@ void *vm_pagedup(void *old) ** ** Duplicate a page directory entry ** -** @param entry The entry to be duplicated +** @param dst Pointer to where the duplicate should go +** @param curr Pointer to the entry to be duplicated ** -** @return the new entry, or -1 on error +** @return true on success, else false */ -pde_t vm_pdedup(pde_t entry) -{ +bool_t vm_pdedup( pde_t *dst, pde_t *curr ) { + + assert1( curr != NULL ); + assert1( dst != NULL ); + #if TRACING_VM - cio_printf("vm_pdedup curr %08x\n", (uint32_t)entry); + cio_printf( "vm_pdedup dst %08x curr %08x\n", + (uint32_t) dst, (uint32_t) curr ); #endif + pde_t entry = *curr; // simplest case - if (!IS_PRESENT(entry)) { - return 0; - } - - // is this a large page? - if (IS_LARGE(entry)) { - // just copy it - return entry; + if( !IS_PRESENT(entry) ) { + *dst = 0; + return true; } - // OK, we have a 4KB entry; allocate a page table for it - pte_t *tblva = (pte_t *)km_page_alloc(); - if (tblva == NULL) { - return (uint32_t)-1; + // OK, we have an entry; allocate a page table for it + pte_t *newtbl = (pte_t *) km_page_alloc(); + if( newtbl == NULL ) { + return false; } - // make sure the entries are all initially 'not present' - memclr(tblva, SZ_PAGE); + // we could clear the new table, but we'll be assigning to + // each entry anyway, so we'll save the execution time - // VA of the page table for this directory entry - pte_t *old = (pte_t *)P2V(PDE_ADDR(entry)); + // address of the page table for this directory entry + pte_t *old = (pte_t *) PDE_ADDR(entry); - // pointer to the first PTE in the new table (already a VA) - pte_t *new = tblva; + // pointer to the first PTE in the new table + pte_t *new = newtbl; - for (int i = 0; i < N_PTE; ++i) { - // only need to copy 'present' entries - if (IS_PRESENT(*old)) { + for( int i = 0 ; i < N_PTE; ++i ) { + if( !IS_PRESENT(*old) ) { + *new = 0; + } else { *new = *old; } ++old; ++new; } - // replace the page table address - // (PA of page table, lower 12 bits from '*curr') - return (pde_t)(V2P(PTE_ADDR(tblva)) | PERMS(entry)); + // replace the page table address + // upper 22 bits from 'newtbl', lower 12 from '*curr' + *dst = (pde_t) ( PTE_ADDR(newtbl) | PERMS(entry) ); + + return true; } /** @@ -452,37 +219,38 @@ pde_t vm_pdedup(pde_t entry) ** @return A pointer to the page table entry for this VA, or NULL if ** there isn't one and we're not allocating */ -pte_t *vm_getpte(pde_t *pdir, const void *va, bool_t alloc) -{ - pte_t *ptbl; +pte_t *vm_getpte( pde_t *pdir, const void *va, bool_t alloc ) { + pte_t *ptab; // sanity check - assert1(pdir != NULL); + assert1( pdir != NULL ); // get the PDIR entry for this virtual address - pde_t *pde_ptr = &pdir[PDIX(va)]; + pde_t *pde = &pdir[ PDIX(va) ]; // is it already set up? - if (IS_PRESENT(*pde_ptr)) { + if( IS_PRESENT(*pde) ) { + // yes! - ptbl = (pte_t *)P2V(PTE_ADDR(*pde_ptr)); + ptab = (pte_t*)P2V(PTE_ADDR(*pde)); } else { + // no - should we create it? - if (!alloc) { + if( !alloc ) { // nope, so just return return NULL; } // yes - try to allocate a page table - ptbl = (pte_t *)km_page_alloc(); - if (ptbl == NULL) { - WARNING("can't allocate page table"); + ptab = (pte_t *) km_page_alloc(); + if( ptab == NULL ) { + WARNING( "can't allocate page table" ); return NULL; } // who knows what was left in this page.... - memclr(ptbl, SZ_PAGE); + memclr( ptab, SZ_PAGE ); // add this to the page directory // @@ -491,54 +259,46 @@ pte_t *vm_getpte(pde_t *pdir, const void *va, bool_t alloc) // entries, if necessary. // // NOTE: the allocator is serving us virtual page addresses, - // so we must convert them to physical addresses for the - // table entries - *pde_ptr = V2P(ptbl) | PDE_P | PDE_RW | PDE_US; + // so we must convert them to physical addresses + *pde = ((uint32_t) V2P(ptab)) | PDE_P | PDE_RW; } - // finally, return a pointer to the entry in the page table for this VA - return &ptbl[PTIX(va)]; + // finally, return a pointer to the entry in the + // page table for this VA + return &ptab[ PTIX(va) ]; } // Set up kernel part of a page table. -pde_t *vm_mkkvm(void) +pde_t *vm_mkkvm( void ) { mapping_t *k; // allocate the page directory pde_t *pdir = km_page_alloc(); - if (pdir == NULL) { + if( pdir == NULL ) { return NULL; } -#if 0 && TRACING_VM - cio_puts( "\nEntering vm_mkkvm\n" ); - pmt_dump( pdir, true, 0, N_PDE ); -#endif // clear it out to disable all the entries - memclr(pdir, SZ_PAGE); + memclr( pdir, SZ_PAGE ); - if (P2V(PHYS_TOP) > DEV_BASE) { - cio_printf("PHYS_TOP (%08x -> %08x) > DEV_BASE(%08x)\n", PHYS_TOP, - P2V(PHYS_TOP), DEV_BASE); - PANIC(0, "PHYS_TOP too large"); + if( P2V(PHYS_TOP) > DEV_BASE ) { + cio_printf( "PHYS_TOP (%08x -> %08x) > DEV_BASE(%08x)\n", + PHYS_TOP, P2V(PHYS_TOP), DEV_BASE ); + PANIC( 0, "PHYS_TOP too large" ); } // map in all the page ranges k = kmap; - for (int i = 0; i < n_kmap; ++i, ++k) { - int stat = vm_map(pdir, ((void *)k->va_start), k->pa_start, - k->pa_end - k->pa_start, k->perm); - if (stat != SUCCESS) { - vm_free(pdir); + for( int i = 0; i < n_kmap; ++i, ++k ) { + int stat = vm_map( pdir, ((void *)k->va_start), + k->pa_end - k->pa_start, + k->pa_start, k->perm ); + if( stat != SUCCESS ) { + vm_free( pdir ); return 0; } } -#if 0 && TRACING_VM - cio_puts( "\nvm_mkkvm() final PD:\n" ); - pmt_dump( pdir, true, 0, 16 ); - pmt_dump( pdir, true, 0x200, 16 ); -#endif return pdir; } @@ -549,37 +309,32 @@ pde_t *vm_mkkvm(void) ** ** @return a pointer to the new page directory, or NULL */ -pde_t *vm_mkuvm(void) -{ +pde_t *vm_mkuvm( void ) { + // allocate the directory - pde_t *new = (pde_t *)km_page_alloc(); - if (new == NULL) { + pde_t *new = (pde_t *) km_page_alloc(); + if( new == NULL ) { return NULL; } - // iterate through the 'system' portions of the kernel - // page directory - int i = PDIX(KERN_BASE); - pde_t *curr = &kpdir[i]; - pde_t *dst = &new[i]; - while (i < N_PDE) { - if (*curr != 0) { + // iterate through the kernel page directory + pde_t *curr = kpdir; + pde_t *dst = new; + for( int i = 0; i < N_PDE; ++i ) { + + if( *curr != 0 ) { // found an active one - duplicate it - pde_t entry = vm_pdedup(*curr); - if (entry == (uint32_t)-1) { + if( !vm_pdedup(dst,curr) ) { return NULL; } - *dst = entry; - } else { - *dst = 0; } ++curr; ++dst; - ++i; } return new; + } /** @@ -587,15 +342,8 @@ pde_t *vm_mkuvm(void) ** ** Switch the page table register to the kernel's page directory. */ -void vm_set_kvm(void) -{ -#if TRACING_VM - cio_puts("Entering vm_set_kvm()\n"); -#endif - w_cr3(V2P(kpdir)); // switch to the kernel page table -#if TRACING_VM - cio_puts("Exiting vm_set_kvm()\n"); -#endif +void vm_set_kvm( void ) { + w_cr3( V2P(kpdir) ); // switch to the kernel page table } /** @@ -605,18 +353,11 @@ void vm_set_kvm(void) ** ** @param p PCB of the process we're switching to */ -void vm_set_uvm(pcb_t *p) -{ -#if TRACING_VM - cio_puts("Entering vm_set_uvm()\n"); -#endif - assert(p != NULL); - assert(p->pdir != NULL); +void vm_set_uvm( pcb_t *p ) { + assert( p != NULL ); + assert( p->pdir != NULL ); - w_cr3(V2P(p->pdir)); // switch to process's address space -#if TRACING_VM - cio_puts("Entering vm_set_uvm()\n"); -#endif + w_cr3( V2P(p->pdir) ); // switch to process's address space } /** @@ -635,35 +376,36 @@ void vm_set_uvm(pcb_t *p) ** ** @return status of the allocation attempt */ -int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size, - char *data, uint32_t bytes) -{ +int vm_add( pde_t *pdir, bool_t wr, bool_t sys, + void *va, uint32_t size, char *data, uint32_t bytes ) { + // how many pages do we need? - uint32_t npages = ((size & MOD4K_BITS) ? PGUP(size) : size) >> MOD4K_SHIFT; + uint_t npages = ((size & MOD4K_BITS) ? PGUP(size) : size) >> MOD4K_SHIFT; // permission set for the PTEs - uint32_t entrybase = PTE_P; - if (wr) { + uint_t entrybase = PTE_P; + if( wr ) { entrybase |= PTE_RW; } - if (!sys) { + if( sys ) { entrybase |= PTE_US; } #if TRACING_VM - cio_printf("vm_add: pdir %08x, %s, va %08x size %u (%u pgs)\n", - (uint32_t)pdir, wr ? "W" : "!W", (uint32_t)va, size, npages); - cio_printf(" from %08x, %u bytes, perms %08x\n", (uint32_t)data, - bytes, entrybase); + cio_printf( "vm_add: pdir %08x, %s, va %08x (%u, %u pgs)\n", + (uint32_t) pdir, wr ? "W" : "!W", (uint32_t) va, size ); + cio_printf( " from %08x, %u bytes, perms %08x\n", + (uint32_t) data, bytes, entrybase ); #endif // iterate through the pages - for (int i = 0; i < npages; ++i) { + for( int i = 0; i < npages; ++i ) { + // figure out where this page will go in the hierarchy - pte_t *pte = vm_getpte(pdir, va, true); - if (pte == NULL) { - // if i > 0, this isn't the first frame - is + pte_t *pte = vm_getpte( pdir, va, true ); + if( pte == NULL ) { + // TODO if i > 0, this isn't the first frame - is // there anything to do about other frames? // POSSIBLE MEMORY LEAK? return E_NO_MEMORY; @@ -671,27 +413,27 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size, // allocate the frame void *page = km_page_alloc(); - if (page == NULL) { - // same question here + if( page == NULL ) { + // TODO same question here return E_NO_MEMORY; } // clear it all out - memclr(page, SZ_PAGE); + memclr( page, SZ_PAGE ); // create the PTE for this frame - uint32_t entry = (uint32_t)(V2P(PTE_ADDR(page)) | entrybase); + uint32_t entry = (uint32_t) (PTE_ADDR(page) | entrybase); *pte = entry; // copy data if we need to - if (data != NULL && bytes > 0) { + if( data != NULL && bytes > 0 ) { // how much to copy - uint32_t num = bytes > SZ_PAGE ? SZ_PAGE : bytes; + uint_t num = bytes > SZ_PAGE ? SZ_PAGE : bytes; // do it! - memmove((void *)page, (void *)data, num); + memcpy( (void *)page, (void *)data, num ); // adjust all the pointers - data += num; // where to continue - bytes -= num; // what's left to copy + data += num; // where to continue + bytes -= num; // what's left to copy } // bump the virtual address @@ -699,6 +441,7 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size, } return SUCCESS; + } /** @@ -711,43 +454,36 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size, ** ** @param pdir Pointer to the page directory */ -void vm_free(pde_t *pdir) -{ -#if TRACING_VM - cio_printf("vm_free(%08x)\n", (uint32_t)pdir); -#endif +void vm_free( pde_t *pdir ) { // do we have anything to do? - if (pdir == NULL) { + if( pdir == NULL ) { return; } // iterate through the page directory entries, freeing the // PMTS and the frames they point to pde_t *curr = pdir; - int nf = 0; - int nt = 0; + for( int i = 0; i < N_PDE; ++i ) { - for (int i = 0; i < N_PDE; ++i) { // the entry itself pde_t entry = *curr; // does this entry point to anything useful? - if (IS_PRESENT(entry)) { + if( IS_PRESENT(entry) ) { + // yes - large pages make us unhappy - assert(!IS_LARGE(entry)); + assert( !IS_LARGE(entry) ); // get the PMT pointer - pte_t *pmt = (pte_t *)P2V(PTE_ADDR(entry)); + pte_t *pmt = (pte_t *) PTE_ADDR(entry); // walk the PMT - for (int j = 0; j < N_PTE; ++j) { - pte_t tmp = *pmt; + for( int j = 0; j < N_PTE; ++j ) { // does this entry point to a frame? - if (IS_PRESENT(tmp)) { + if( IS_PRESENT(*pmt) ) { // yes - free the frame - km_page_free((void *)P2V(PTE_ADDR(tmp))); - ++nf; + km_page_free( (void *) PTE_ADDR(*pmt) ); // mark it so we don't get surprised *pmt = 0; } @@ -755,8 +491,7 @@ void vm_free(pde_t *pdir) ++pmt; } // now, free the PMT itself - km_page_free((void *)P2V(PDE_ADDR(entry))); - ++nt; + km_page_free( (void *) PDE_ADDR(entry) ); *curr = 0; } @@ -765,12 +500,7 @@ void vm_free(pde_t *pdir) } // finally, free the PDIR itself - km_page_free((void *)pdir); - ++nt; - -#if TRACING_VM - cio_printf("vm_free: %d pages, %d tables\n", nf, nt); -#endif + km_page_free( (void *) pdir ); } /* @@ -782,74 +512,47 @@ void vm_free(pde_t *pdir) ** ** @param pdir Page directory for this address space ** @param va The starting virtual address -** @param pa The starting physical address ** @param size Length of the range to be mapped +** @param pa The starting physical address ** @param perm Permission bits for the PTEs ** ** @return the status of the mapping attempt */ -int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm) -{ +int vm_map( pde_t *pdir, void *va, uint_t size, uint_t pa, int perm ) { + // round the VA down to its page boundary - char *addr = (char *)PGDOWN((uint32_t)va); + char *addr = (char*)PGDOWN((uint_t)va); // round the end of the range down to its page boundary - char *last = (char *)PGDOWN(((uint32_t)va) + size - 1); + char *last = (char*)PGDOWN(((uint_t)va) + size - 1); -#if TRACING_VM - cio_printf("vm_map pdir %08x va %08x pa %08x size %08x perm %03x\n", - (uint32_t)pdir, (uint32_t)va, pa, size, perm); -#endif + while( addr < last ) { - while (addr <= last) { // get a pointer to the PTE for the current VA - pte_t *pte = vm_getpte(pdir, addr, true); - if (pte == NULL) { + pte_t *pte = vm_getpte( pdir, addr, true ); + if( pte == NULL ) { // couldn't find it return E_NO_PTE; } -#if 0 && TRACING_VM - cio_printf( " addr %08x pa %08x last %08x pte %08x *pte %08x\n", - (uint32_t) addr, pa, (uint32_t) last, (uint32_t) pte, *pte - ); -#endif - - // create the new entry for the page table - pde_t newpte = pa | perm | PTE_P; // if this entry has already been mapped, we're in trouble - if (IS_PRESENT(*pte)) { - if (*pte != newpte) { -#if TRACING_VM - cio_printf( - "vm_map: va %08x pa %08x pte %08x *pte %08x entry %08x\n", - (uint32_t)va, pa, (uint32_t)pte, (uint32_t)*pte, newpte); - cio_printf(" addr %08x PDIX 0x%x PTIX 0x%x\n", (uint32_t)addr, - PDIX(addr), PTIX(addr)); - - // dump the directory - pmt_dump(pdir, true, PDIX(addr), 4); - - // find the relevant PDE entry - uint32_t ix = PDIX(va); - pde_t entry = pdir[ix]; - if (!IS_LARGE(entry)) { - // round the PMT index down - uint32_t ix2 = PTIX(va) & MOD4_MASK; - // dump the PMT for the relevant directory entry - pmt_dump((void *)P2V(PDE_ADDR(entry)), false, ix2, 4); - } -#endif - PANIC(0, "mapping an already-mapped address"); - } + if( IS_PRESENT(*pte) ) { + cio_printf( "vm_map(%08x,%08x,%u,%08x,%03x)\n", + (uint32_t) pdir, (uint32_t) va, size, pa, perm ); + cio_printf( " addr %08x last %08x pte %08x *pte %08x\n", + (uint32_t) addr, (uint32_t) last, + (uint32_t) pte, *pte ); + + PANIC( 0, "mapping an already-mapped address" ); } // ok, set the PTE as requested - *pte = newpte; + *pte = pa | perm | PTE_P; // nope - move to the next page addr += SZ_PAGE; pa += SZ_PAGE; + } return SUCCESS; } @@ -866,48 +569,48 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm) ** now have two sets of page tables that refer to the same physical ** frames in memory. ** -** @param new New page directory ** @param old Existing page directory +** @param new New page directory ** ** @return status of the duplication attempt */ -int vm_uvmdup(pde_t *new, pde_t *old) -{ - if (old == NULL || new == NULL) { +int vm_uvmdup( pde_t *old, pde_t *new ) { + + if( old == NULL || new == NULL ) { return E_BAD_PARAM; } -#if TRACING_VM - cio_printf("vmdup: old %08x new %08x\n", (uint32_t)old, (uint32_t)new); -#endif - // we only want to deal with the "user" half of the address space - for (int i = 0; i < (N_PDE >> 1); ++i) { + for( int i = 0; i < (N_PDE >> 1); ++i ) { + // the entry to copy pde_t entry = *old; // is this entry in use? - if (IS_PRESENT(entry)) { + if( IS_PRESENT(entry) ) { + // yes. if it points to a 4MB page, we just copy it; // otherwise, we must duplicate the next level PMT - if (!IS_LARGE(entry)) { + if( !IS_LARGE(entry) ) { + // it's a 4KB page, so we need to duplicate the PMT - pte_t *newpt = - (pte_t *)vm_pagedup((void *)P2V(PTE_ADDR(entry))); - if (newpt == NULL) { + pte_t *newpt = (pte_t *) vm_pagedup( (void *)PTE_ADDR(entry) ); + if( newpt == NULL ) { return E_NO_MEMORY; } uint32_t perms = PERMS(entry); // create the new PDE entry by replacing the frame # - entry = ((uint32_t)V2P(PTE_ADDR(newpt))) | perms; + entry = ((uint32_t) newpt) | perms; } } else { + // not present, so create an empty entry entry = 0; + } // send it on its way @@ -920,26 +623,3 @@ int vm_uvmdup(pde_t *new, pde_t *old) return SUCCESS; } - -/** -** Name: vm_print -** -** Print out a paging hierarchy. -** -** @param pt Page table to display -** @param dir Is it a page directory (vs. a page table)? -** @param mode How to display the entries -*/ -void vm_print(void *pt, bool_t dir, enum vmmode_e mode) -{ - cio_puts("\nVM hierarchy"); - if (pt == NULL) { - cio_puts(" (NULL pointer)\n"); - return; - } - - cio_printf(", starting at 0x%08x (%s):\n", (uint32_t)pt, - dir ? "PDIR" : "PMT"); - - ptdump(1, pt, dir, mode); -} diff --git a/kernel/old/vmtables.c b/kernel/old/vmtables.c index 113fd8b..a50315d 100644 --- a/kernel/old/vmtables.c +++ b/kernel/old/vmtables.c @@ -11,7 +11,7 @@ ** 4MB of main memory. */ -#define KERNEL_SRC +#define KERNEL_SRC #include @@ -37,167 +37,146 @@ extern char _data[]; // identity-map 4MB virtual address #n to physical 4MB address #n // used for addresses 0 to 2GB -#define L(n) [n] = (pde_t)((TO_4MFRAME((n))) | (PDE_P | PDE_RW | PDE_PS)) +#define L(n) [n] = (pde_t) ( (TO_4MFRAME((n))) | (PDE_P|PDE_RW|PDE_PS) ) // ditto, but adds 512 (0x200) to the index // used for addresses 2GB to 4GB -#define M(n) \ - [n | 0x200] = (pde_t)((TO_4MFRAME((n))) | (PDE_P | PDE_RW | PDE_PS)) +#define M(n) [n|0x200] = (pde_t) ( (TO_4MFRAME((n))) | (PDE_P|PDE_RW|PDE_PS) ) ATTR_ALIGNED(SZ_PAGE) const pde_t firstpdir[N_PDE] = { // Map VA range [0, 2GB] to PA range [0, 2GB] - L(0x000), L(0x001), L(0x002), L(0x003), L(0x004), L(0x005), L(0x006), - L(0x007), L(0x008), L(0x009), L(0x00a), L(0x00b), L(0x00c), L(0x00d), - L(0x00e), L(0x00f), L(0x010), L(0x011), L(0x012), L(0x013), L(0x014), - L(0x015), L(0x016), L(0x017), L(0x018), L(0x019), L(0x01a), L(0x01b), - L(0x01c), L(0x01d), L(0x01e), L(0x01f), L(0x020), L(0x021), L(0x022), - L(0x023), L(0x024), L(0x025), L(0x026), L(0x027), L(0x028), L(0x029), - L(0x02a), L(0x02b), L(0x02c), L(0x02d), L(0x02e), L(0x02f), L(0x030), - L(0x031), L(0x032), L(0x033), L(0x034), L(0x035), L(0x036), L(0x037), - L(0x038), L(0x039), L(0x03a), L(0x03b), L(0x03c), L(0x03d), L(0x03e), - L(0x03f), L(0x040), L(0x041), L(0x042), L(0x043), L(0x044), L(0x045), - L(0x046), L(0x047), L(0x048), L(0x049), L(0x04a), L(0x04b), L(0x04c), - L(0x04d), L(0x04e), L(0x04f), L(0x050), L(0x051), L(0x052), L(0x053), - L(0x054), L(0x055), L(0x056), L(0x057), L(0x058), L(0x059), L(0x05a), - L(0x05b), L(0x05c), L(0x05d), L(0x05e), L(0x05f), L(0x060), L(0x061), - L(0x062), L(0x063), L(0x064), L(0x065), L(0x066), L(0x067), L(0x068), - L(0x069), L(0x06a), L(0x06b), L(0x06c), L(0x06d), L(0x06e), L(0x06f), - L(0x070), L(0x071), L(0x072), L(0x073), L(0x074), L(0x075), L(0x076), - L(0x077), L(0x078), L(0x079), L(0x07a), L(0x07b), L(0x07c), L(0x07d), - L(0x07e), L(0x07f), L(0x080), L(0x081), L(0x082), L(0x083), L(0x084), - L(0x085), L(0x086), L(0x087), L(0x088), L(0x089), L(0x08a), L(0x08b), - L(0x08c), L(0x08d), L(0x08e), L(0x08f), L(0x090), L(0x091), L(0x092), - L(0x093), L(0x094), L(0x095), L(0x096), L(0x097), L(0x098), L(0x099), - L(0x09a), L(0x09b), L(0x09c), L(0x09d), L(0x09e), L(0x09f), L(0x0a0), - L(0x0a1), L(0x0a2), L(0x0a3), L(0x0a4), L(0x0a5), L(0x0a6), L(0x0a7), - L(0x0a8), L(0x0a9), L(0x0aa), L(0x0ab), L(0x0ac), L(0x0ad), L(0x0ae), - L(0x0af), L(0x0b0), L(0x0b1), L(0x0b2), L(0x0b3), L(0x0b4), L(0x0b5), - L(0x0b6), L(0x0b7), L(0x0b8), L(0x0b9), L(0x0ba), L(0x0bb), L(0x0bc), - L(0x0bd), L(0x0be), L(0x0bf), L(0x0c0), L(0x0c1), L(0x0c2), L(0x0c3), - L(0x0c4), L(0x0c5), L(0x0c6), L(0x0c7), L(0x0c8), L(0x0c9), L(0x0ca), - L(0x0cb), L(0x0cc), L(0x0cd), L(0x0ce), L(0x0cf), L(0x0d0), L(0x0d1), - L(0x0d2), L(0x0d3), L(0x0d4), L(0x0d5), L(0x0d6), L(0x0d7), L(0x0d8), - L(0x0d9), L(0x0da), L(0x0db), L(0x0dc), L(0x0dd), L(0x0de), L(0x0df), - L(0x0e0), L(0x0e1), L(0x0e2), L(0x0e3), L(0x0e4), L(0x0e5), L(0x0e6), - L(0x0e7), L(0x0e8), L(0x0e9), L(0x0ea), L(0x0eb), L(0x0ec), L(0x0ed), - L(0x0ee), L(0x0ef), L(0x0f0), L(0x0f1), L(0x0f2), L(0x0f3), L(0x0f4), - L(0x0f5), L(0x0f6), L(0x0f7), L(0x0f8), L(0x0f9), L(0x0fa), L(0x0fb), - L(0x0fc), L(0x0fd), L(0x0fe), L(0x0ff), L(0x100), L(0x101), L(0x102), - L(0x103), L(0x104), L(0x105), L(0x106), L(0x107), L(0x108), L(0x109), - L(0x10a), L(0x10b), L(0x10c), L(0x10d), L(0x10e), L(0x10f), L(0x110), - L(0x111), L(0x112), L(0x113), L(0x114), L(0x115), L(0x116), L(0x117), - L(0x118), L(0x119), L(0x11a), L(0x11b), L(0x11c), L(0x11d), L(0x11e), - L(0x11f), L(0x120), L(0x121), L(0x122), L(0x123), L(0x124), L(0x125), - L(0x126), L(0x127), L(0x128), L(0x129), L(0x12a), L(0x12b), L(0x12c), - L(0x12d), L(0x12e), L(0x12f), L(0x130), L(0x131), L(0x132), L(0x133), - L(0x134), L(0x135), L(0x136), L(0x137), L(0x138), L(0x139), L(0x13a), - L(0x13b), L(0x13c), L(0x13d), L(0x13e), L(0x13f), L(0x140), L(0x141), - L(0x142), L(0x143), L(0x144), L(0x145), L(0x146), L(0x147), L(0x148), - L(0x149), L(0x14a), L(0x14b), L(0x14c), L(0x14d), L(0x14e), L(0x14f), - L(0x150), L(0x151), L(0x152), L(0x153), L(0x154), L(0x155), L(0x156), - L(0x157), L(0x158), L(0x159), L(0x15a), L(0x15b), L(0x15c), L(0x15d), - L(0x15e), L(0x15f), L(0x160), L(0x161), L(0x162), L(0x163), L(0x164), - L(0x165), L(0x166), L(0x167), L(0x168), L(0x169), L(0x16a), L(0x16b), - L(0x16c), L(0x16d), L(0x16e), L(0x16f), L(0x170), L(0x171), L(0x172), - L(0x173), L(0x174), L(0x175), L(0x176), L(0x177), L(0x178), L(0x179), - L(0x17a), L(0x17b), L(0x17c), L(0x17d), L(0x17e), L(0x17f), L(0x180), - L(0x181), L(0x182), L(0x183), L(0x184), L(0x185), L(0x186), L(0x187), - L(0x188), L(0x189), L(0x18a), L(0x18b), L(0x18c), L(0x18d), L(0x18e), - L(0x18f), L(0x190), L(0x191), L(0x192), L(0x193), L(0x194), L(0x195), - L(0x196), L(0x197), L(0x198), L(0x199), L(0x19a), L(0x19b), L(0x19c), - L(0x19d), L(0x19e), L(0x19f), L(0x1a0), L(0x1a1), L(0x1a2), L(0x1a3), - L(0x1a4), L(0x1a5), L(0x1a6), L(0x1a7), L(0x1a8), L(0x1a9), L(0x1aa), - L(0x1ab), L(0x1ac), L(0x1ad), L(0x1ae), L(0x1af), L(0x1b0), L(0x1b1), - L(0x1b2), L(0x1b3), L(0x1b4), L(0x1b5), L(0x1b6), L(0x1b7), L(0x1b8), - L(0x1b9), L(0x1ba), L(0x1bb), L(0x1bc), L(0x1bd), L(0x1be), L(0x1bf), - L(0x1c0), L(0x1c1), L(0x1c2), L(0x1c3), L(0x1c4), L(0x1c5), L(0x1c6), - L(0x1c7), L(0x1c8), L(0x1c9), L(0x1ca), L(0x1cb), L(0x1cc), L(0x1cd), - L(0x1ce), L(0x1cf), L(0x1d0), L(0x1d1), L(0x1d2), L(0x1d3), L(0x1d4), - L(0x1d5), L(0x1d6), L(0x1d7), L(0x1d8), L(0x1d9), L(0x1da), L(0x1db), - L(0x1dc), L(0x1dd), L(0x1de), L(0x1df), L(0x1e0), L(0x1e1), L(0x1e2), - L(0x1e3), L(0x1e4), L(0x1e5), L(0x1e6), L(0x1e7), L(0x1e8), L(0x1e9), - L(0x1ea), L(0x1eb), L(0x1ec), L(0x1ed), L(0x1ee), L(0x1ef), L(0x1f0), - L(0x1f1), L(0x1f2), L(0x1f3), L(0x1f4), L(0x1f5), L(0x1f6), L(0x1f7), - L(0x1f8), L(0x1f9), L(0x1fa), L(0x1fb), L(0x1fc), L(0x1fd), L(0x1fe), - L(0x1ff), +L(0x000), L(0x001), L(0x002), L(0x003), L(0x004), L(0x005), L(0x006), L(0x007), +L(0x008), L(0x009), L(0x00a), L(0x00b), L(0x00c), L(0x00d), L(0x00e), L(0x00f), +L(0x010), L(0x011), L(0x012), L(0x013), L(0x014), L(0x015), L(0x016), L(0x017), +L(0x018), L(0x019), L(0x01a), L(0x01b), L(0x01c), L(0x01d), L(0x01e), L(0x01f), +L(0x020), L(0x021), L(0x022), L(0x023), L(0x024), L(0x025), L(0x026), L(0x027), +L(0x028), L(0x029), L(0x02a), L(0x02b), L(0x02c), L(0x02d), L(0x02e), L(0x02f), +L(0x030), L(0x031), L(0x032), L(0x033), L(0x034), L(0x035), L(0x036), L(0x037), +L(0x038), L(0x039), L(0x03a), L(0x03b), L(0x03c), L(0x03d), L(0x03e), L(0x03f), +L(0x040), L(0x041), L(0x042), L(0x043), L(0x044), L(0x045), L(0x046), L(0x047), +L(0x048), L(0x049), L(0x04a), L(0x04b), L(0x04c), L(0x04d), L(0x04e), L(0x04f), +L(0x050), L(0x051), L(0x052), L(0x053), L(0x054), L(0x055), L(0x056), L(0x057), +L(0x058), L(0x059), L(0x05a), L(0x05b), L(0x05c), L(0x05d), L(0x05e), L(0x05f), +L(0x060), L(0x061), L(0x062), L(0x063), L(0x064), L(0x065), L(0x066), L(0x067), +L(0x068), L(0x069), L(0x06a), L(0x06b), L(0x06c), L(0x06d), L(0x06e), L(0x06f), +L(0x070), L(0x071), L(0x072), L(0x073), L(0x074), L(0x075), L(0x076), L(0x077), +L(0x078), L(0x079), L(0x07a), L(0x07b), L(0x07c), L(0x07d), L(0x07e), L(0x07f), +L(0x080), L(0x081), L(0x082), L(0x083), L(0x084), L(0x085), L(0x086), L(0x087), +L(0x088), L(0x089), L(0x08a), L(0x08b), L(0x08c), L(0x08d), L(0x08e), L(0x08f), +L(0x090), L(0x091), L(0x092), L(0x093), L(0x094), L(0x095), L(0x096), L(0x097), +L(0x098), L(0x099), L(0x09a), L(0x09b), L(0x09c), L(0x09d), L(0x09e), L(0x09f), +L(0x0a0), L(0x0a1), L(0x0a2), L(0x0a3), L(0x0a4), L(0x0a5), L(0x0a6), L(0x0a7), +L(0x0a8), L(0x0a9), L(0x0aa), L(0x0ab), L(0x0ac), L(0x0ad), L(0x0ae), L(0x0af), +L(0x0b0), L(0x0b1), L(0x0b2), L(0x0b3), L(0x0b4), L(0x0b5), L(0x0b6), L(0x0b7), +L(0x0b8), L(0x0b9), L(0x0ba), L(0x0bb), L(0x0bc), L(0x0bd), L(0x0be), L(0x0bf), +L(0x0c0), L(0x0c1), L(0x0c2), L(0x0c3), L(0x0c4), L(0x0c5), L(0x0c6), L(0x0c7), +L(0x0c8), L(0x0c9), L(0x0ca), L(0x0cb), L(0x0cc), L(0x0cd), L(0x0ce), L(0x0cf), +L(0x0d0), L(0x0d1), L(0x0d2), L(0x0d3), L(0x0d4), L(0x0d5), L(0x0d6), L(0x0d7), +L(0x0d8), L(0x0d9), L(0x0da), L(0x0db), L(0x0dc), L(0x0dd), L(0x0de), L(0x0df), +L(0x0e0), L(0x0e1), L(0x0e2), L(0x0e3), L(0x0e4), L(0x0e5), L(0x0e6), L(0x0e7), +L(0x0e8), L(0x0e9), L(0x0ea), L(0x0eb), L(0x0ec), L(0x0ed), L(0x0ee), L(0x0ef), +L(0x0f0), L(0x0f1), L(0x0f2), L(0x0f3), L(0x0f4), L(0x0f5), L(0x0f6), L(0x0f7), +L(0x0f8), L(0x0f9), L(0x0fa), L(0x0fb), L(0x0fc), L(0x0fd), L(0x0fe), L(0x0ff), +L(0x100), L(0x101), L(0x102), L(0x103), L(0x104), L(0x105), L(0x106), L(0x107), +L(0x108), L(0x109), L(0x10a), L(0x10b), L(0x10c), L(0x10d), L(0x10e), L(0x10f), +L(0x110), L(0x111), L(0x112), L(0x113), L(0x114), L(0x115), L(0x116), L(0x117), +L(0x118), L(0x119), L(0x11a), L(0x11b), L(0x11c), L(0x11d), L(0x11e), L(0x11f), +L(0x120), L(0x121), L(0x122), L(0x123), L(0x124), L(0x125), L(0x126), L(0x127), +L(0x128), L(0x129), L(0x12a), L(0x12b), L(0x12c), L(0x12d), L(0x12e), L(0x12f), +L(0x130), L(0x131), L(0x132), L(0x133), L(0x134), L(0x135), L(0x136), L(0x137), +L(0x138), L(0x139), L(0x13a), L(0x13b), L(0x13c), L(0x13d), L(0x13e), L(0x13f), +L(0x140), L(0x141), L(0x142), L(0x143), L(0x144), L(0x145), L(0x146), L(0x147), +L(0x148), L(0x149), L(0x14a), L(0x14b), L(0x14c), L(0x14d), L(0x14e), L(0x14f), +L(0x150), L(0x151), L(0x152), L(0x153), L(0x154), L(0x155), L(0x156), L(0x157), +L(0x158), L(0x159), L(0x15a), L(0x15b), L(0x15c), L(0x15d), L(0x15e), L(0x15f), +L(0x160), L(0x161), L(0x162), L(0x163), L(0x164), L(0x165), L(0x166), L(0x167), +L(0x168), L(0x169), L(0x16a), L(0x16b), L(0x16c), L(0x16d), L(0x16e), L(0x16f), +L(0x170), L(0x171), L(0x172), L(0x173), L(0x174), L(0x175), L(0x176), L(0x177), +L(0x178), L(0x179), L(0x17a), L(0x17b), L(0x17c), L(0x17d), L(0x17e), L(0x17f), +L(0x180), L(0x181), L(0x182), L(0x183), L(0x184), L(0x185), L(0x186), L(0x187), +L(0x188), L(0x189), L(0x18a), L(0x18b), L(0x18c), L(0x18d), L(0x18e), L(0x18f), +L(0x190), L(0x191), L(0x192), L(0x193), L(0x194), L(0x195), L(0x196), L(0x197), +L(0x198), L(0x199), L(0x19a), L(0x19b), L(0x19c), L(0x19d), L(0x19e), L(0x19f), +L(0x1a0), L(0x1a1), L(0x1a2), L(0x1a3), L(0x1a4), L(0x1a5), L(0x1a6), L(0x1a7), +L(0x1a8), L(0x1a9), L(0x1aa), L(0x1ab), L(0x1ac), L(0x1ad), L(0x1ae), L(0x1af), +L(0x1b0), L(0x1b1), L(0x1b2), L(0x1b3), L(0x1b4), L(0x1b5), L(0x1b6), L(0x1b7), +L(0x1b8), L(0x1b9), L(0x1ba), L(0x1bb), L(0x1bc), L(0x1bd), L(0x1be), L(0x1bf), +L(0x1c0), L(0x1c1), L(0x1c2), L(0x1c3), L(0x1c4), L(0x1c5), L(0x1c6), L(0x1c7), +L(0x1c8), L(0x1c9), L(0x1ca), L(0x1cb), L(0x1cc), L(0x1cd), L(0x1ce), L(0x1cf), +L(0x1d0), L(0x1d1), L(0x1d2), L(0x1d3), L(0x1d4), L(0x1d5), L(0x1d6), L(0x1d7), +L(0x1d8), L(0x1d9), L(0x1da), L(0x1db), L(0x1dc), L(0x1dd), L(0x1de), L(0x1df), +L(0x1e0), L(0x1e1), L(0x1e2), L(0x1e3), L(0x1e4), L(0x1e5), L(0x1e6), L(0x1e7), +L(0x1e8), L(0x1e9), L(0x1ea), L(0x1eb), L(0x1ec), L(0x1ed), L(0x1ee), L(0x1ef), +L(0x1f0), L(0x1f1), L(0x1f2), L(0x1f3), L(0x1f4), L(0x1f5), L(0x1f6), L(0x1f7), +L(0x1f8), L(0x1f9), L(0x1fa), L(0x1fb), L(0x1fc), L(0x1fd), L(0x1fe), L(0x1ff), // Map VA range [2GB, 4GB] to PA range [0, 2MB] - M(0x000), M(0x001), M(0x002), M(0x003), M(0x004), M(0x005), M(0x006), - M(0x007), M(0x008), M(0x009), M(0x00a), M(0x00b), M(0x00c), M(0x00d), - M(0x00e), M(0x00f), M(0x010), M(0x011), M(0x012), M(0x013), M(0x014), - M(0x015), M(0x016), M(0x017), M(0x018), M(0x019), M(0x01a), M(0x01b), - M(0x01c), M(0x01d), M(0x01e), M(0x01f), M(0x020), M(0x021), M(0x022), - M(0x023), M(0x024), M(0x025), M(0x026), M(0x027), M(0x028), M(0x029), - M(0x02a), M(0x02b), M(0x02c), M(0x02d), M(0x02e), M(0x02f), M(0x030), - M(0x031), M(0x032), M(0x033), M(0x034), M(0x035), M(0x036), M(0x037), - M(0x038), M(0x039), M(0x03a), M(0x03b), M(0x03c), M(0x03d), M(0x03e), - M(0x03f), M(0x040), M(0x041), M(0x042), M(0x043), M(0x044), M(0x045), - M(0x046), M(0x047), M(0x048), M(0x049), M(0x04a), M(0x04b), M(0x04c), - M(0x04d), M(0x04e), M(0x04f), M(0x050), M(0x051), M(0x052), M(0x053), - M(0x054), M(0x055), M(0x056), M(0x057), M(0x058), M(0x059), M(0x05a), - M(0x05b), M(0x05c), M(0x05d), M(0x05e), M(0x05f), M(0x060), M(0x061), - M(0x062), M(0x063), M(0x064), M(0x065), M(0x066), M(0x067), M(0x068), - M(0x069), M(0x06a), M(0x06b), M(0x06c), M(0x06d), M(0x06e), M(0x06f), - M(0x070), M(0x071), M(0x072), M(0x073), M(0x074), M(0x075), M(0x076), - M(0x077), M(0x078), M(0x079), M(0x07a), M(0x07b), M(0x07c), M(0x07d), - M(0x07e), M(0x07f), M(0x080), M(0x081), M(0x082), M(0x083), M(0x084), - M(0x085), M(0x086), M(0x087), M(0x088), M(0x089), M(0x08a), M(0x08b), - M(0x08c), M(0x08d), M(0x08e), M(0x08f), M(0x090), M(0x091), M(0x092), - M(0x093), M(0x094), M(0x095), M(0x096), M(0x097), M(0x098), M(0x099), - M(0x09a), M(0x09b), M(0x09c), M(0x09d), M(0x09e), M(0x09f), M(0x0a0), - M(0x0a1), M(0x0a2), M(0x0a3), M(0x0a4), M(0x0a5), M(0x0a6), M(0x0a7), - M(0x0a8), M(0x0a9), M(0x0aa), M(0x0ab), M(0x0ac), M(0x0ad), M(0x0ae), - M(0x0af), M(0x0b0), M(0x0b1), M(0x0b2), M(0x0b3), M(0x0b4), M(0x0b5), - M(0x0b6), M(0x0b7), M(0x0b8), M(0x0b9), M(0x0ba), M(0x0bb), M(0x0bc), - M(0x0bd), M(0x0be), M(0x0bf), M(0x0c0), M(0x0c1), M(0x0c2), M(0x0c3), - M(0x0c4), M(0x0c5), M(0x0c6), M(0x0c7), M(0x0c8), M(0x0c9), M(0x0ca), - M(0x0cb), M(0x0cc), M(0x0cd), M(0x0ce), M(0x0cf), M(0x0d0), M(0x0d1), - M(0x0d2), M(0x0d3), M(0x0d4), M(0x0d5), M(0x0d6), M(0x0d7), M(0x0d8), - M(0x0d9), M(0x0da), M(0x0db), M(0x0dc), M(0x0dd), M(0x0de), M(0x0df), - M(0x0e0), M(0x0e1), M(0x0e2), M(0x0e3), M(0x0e4), M(0x0e5), M(0x0e6), - M(0x0e7), M(0x0e8), M(0x0e9), M(0x0ea), M(0x0eb), M(0x0ec), M(0x0ed), - M(0x0ee), M(0x0ef), M(0x0f0), M(0x0f1), M(0x0f2), M(0x0f3), M(0x0f4), - M(0x0f5), M(0x0f6), M(0x0f7), M(0x0f8), M(0x0f9), M(0x0fa), M(0x0fb), - M(0x0fc), M(0x0fd), M(0x0fe), M(0x0ff), M(0x100), M(0x101), M(0x102), - M(0x103), M(0x104), M(0x105), M(0x106), M(0x107), M(0x108), M(0x109), - M(0x10a), M(0x10b), M(0x10c), M(0x10d), M(0x10e), M(0x10f), M(0x110), - M(0x111), M(0x112), M(0x113), M(0x114), M(0x115), M(0x116), M(0x117), - M(0x118), M(0x119), M(0x11a), M(0x11b), M(0x11c), M(0x11d), M(0x11e), - M(0x11f), M(0x120), M(0x121), M(0x122), M(0x123), M(0x124), M(0x125), - M(0x126), M(0x127), M(0x128), M(0x129), M(0x12a), M(0x12b), M(0x12c), - M(0x12d), M(0x12e), M(0x12f), M(0x130), M(0x131), M(0x132), M(0x133), - M(0x134), M(0x135), M(0x136), M(0x137), M(0x138), M(0x139), M(0x13a), - M(0x13b), M(0x13c), M(0x13d), M(0x13e), M(0x13f), M(0x140), M(0x141), - M(0x142), M(0x143), M(0x144), M(0x145), M(0x146), M(0x147), M(0x148), - M(0x149), M(0x14a), M(0x14b), M(0x14c), M(0x14d), M(0x14e), M(0x14f), - M(0x150), M(0x151), M(0x152), M(0x153), M(0x154), M(0x155), M(0x156), - M(0x157), M(0x158), M(0x159), M(0x15a), M(0x15b), M(0x15c), M(0x15d), - M(0x15e), M(0x15f), M(0x160), M(0x161), M(0x162), M(0x163), M(0x164), - M(0x165), M(0x166), M(0x167), M(0x168), M(0x169), M(0x16a), M(0x16b), - M(0x16c), M(0x16d), M(0x16e), M(0x16f), M(0x170), M(0x171), M(0x172), - M(0x173), M(0x174), M(0x175), M(0x176), M(0x177), M(0x178), M(0x179), - M(0x17a), M(0x17b), M(0x17c), M(0x17d), M(0x17e), M(0x17f), M(0x180), - M(0x181), M(0x182), M(0x183), M(0x184), M(0x185), M(0x186), M(0x187), - M(0x188), M(0x189), M(0x18a), M(0x18b), M(0x18c), M(0x18d), M(0x18e), - M(0x18f), M(0x190), M(0x191), M(0x192), M(0x193), M(0x194), M(0x195), - M(0x196), M(0x197), M(0x198), M(0x199), M(0x19a), M(0x19b), M(0x19c), - M(0x19d), M(0x19e), M(0x19f), M(0x1a0), M(0x1a1), M(0x1a2), M(0x1a3), - M(0x1a4), M(0x1a5), M(0x1a6), M(0x1a7), M(0x1a8), M(0x1a9), M(0x1aa), - M(0x1ab), M(0x1ac), M(0x1ad), M(0x1ae), M(0x1af), M(0x1b0), M(0x1b1), - M(0x1b2), M(0x1b3), M(0x1b4), M(0x1b5), M(0x1b6), M(0x1b7), M(0x1b8), - M(0x1b9), M(0x1ba), M(0x1bb), M(0x1bc), M(0x1bd), M(0x1be), M(0x1bf), - M(0x1c0), M(0x1c1), M(0x1c2), M(0x1c3), M(0x1c4), M(0x1c5), M(0x1c6), - M(0x1c7), M(0x1c8), M(0x1c9), M(0x1ca), M(0x1cb), M(0x1cc), M(0x1cd), - M(0x1ce), M(0x1cf), M(0x1d0), M(0x1d1), M(0x1d2), M(0x1d3), M(0x1d4), - M(0x1d5), M(0x1d6), M(0x1d7), M(0x1d8), M(0x1d9), M(0x1da), M(0x1db), - M(0x1dc), M(0x1dd), M(0x1de), M(0x1df), M(0x1e0), M(0x1e1), M(0x1e2), - M(0x1e3), M(0x1e4), M(0x1e5), M(0x1e6), M(0x1e7), M(0x1e8), M(0x1e9), - M(0x1ea), M(0x1eb), M(0x1ec), M(0x1ed), M(0x1ee), M(0x1ef), M(0x1f0), - M(0x1f1), M(0x1f2), M(0x1f3), M(0x1f4), M(0x1f5), M(0x1f6), M(0x1f7), - M(0x1f8), M(0x1f9), M(0x1fa), M(0x1fb), M(0x1fc), M(0x1fd), M(0x1fe), - M(0x1ff) +M(0x000), M(0x001), M(0x002), M(0x003), M(0x004), M(0x005), M(0x006), M(0x007), +M(0x008), M(0x009), M(0x00a), M(0x00b), M(0x00c), M(0x00d), M(0x00e), M(0x00f), +M(0x010), M(0x011), M(0x012), M(0x013), M(0x014), M(0x015), M(0x016), M(0x017), +M(0x018), M(0x019), M(0x01a), M(0x01b), M(0x01c), M(0x01d), M(0x01e), M(0x01f), +M(0x020), M(0x021), M(0x022), M(0x023), M(0x024), M(0x025), M(0x026), M(0x027), +M(0x028), M(0x029), M(0x02a), M(0x02b), M(0x02c), M(0x02d), M(0x02e), M(0x02f), +M(0x030), M(0x031), M(0x032), M(0x033), M(0x034), M(0x035), M(0x036), M(0x037), +M(0x038), M(0x039), M(0x03a), M(0x03b), M(0x03c), M(0x03d), M(0x03e), M(0x03f), +M(0x040), M(0x041), M(0x042), M(0x043), M(0x044), M(0x045), M(0x046), M(0x047), +M(0x048), M(0x049), M(0x04a), M(0x04b), M(0x04c), M(0x04d), M(0x04e), M(0x04f), +M(0x050), M(0x051), M(0x052), M(0x053), M(0x054), M(0x055), M(0x056), M(0x057), +M(0x058), M(0x059), M(0x05a), M(0x05b), M(0x05c), M(0x05d), M(0x05e), M(0x05f), +M(0x060), M(0x061), M(0x062), M(0x063), M(0x064), M(0x065), M(0x066), M(0x067), +M(0x068), M(0x069), M(0x06a), M(0x06b), M(0x06c), M(0x06d), M(0x06e), M(0x06f), +M(0x070), M(0x071), M(0x072), M(0x073), M(0x074), M(0x075), M(0x076), M(0x077), +M(0x078), M(0x079), M(0x07a), M(0x07b), M(0x07c), M(0x07d), M(0x07e), M(0x07f), +M(0x080), M(0x081), M(0x082), M(0x083), M(0x084), M(0x085), M(0x086), M(0x087), +M(0x088), M(0x089), M(0x08a), M(0x08b), M(0x08c), M(0x08d), M(0x08e), M(0x08f), +M(0x090), M(0x091), M(0x092), M(0x093), M(0x094), M(0x095), M(0x096), M(0x097), +M(0x098), M(0x099), M(0x09a), M(0x09b), M(0x09c), M(0x09d), M(0x09e), M(0x09f), +M(0x0a0), M(0x0a1), M(0x0a2), M(0x0a3), M(0x0a4), M(0x0a5), M(0x0a6), M(0x0a7), +M(0x0a8), M(0x0a9), M(0x0aa), M(0x0ab), M(0x0ac), M(0x0ad), M(0x0ae), M(0x0af), +M(0x0b0), M(0x0b1), M(0x0b2), M(0x0b3), M(0x0b4), M(0x0b5), M(0x0b6), M(0x0b7), +M(0x0b8), M(0x0b9), M(0x0ba), M(0x0bb), M(0x0bc), M(0x0bd), M(0x0be), M(0x0bf), +M(0x0c0), M(0x0c1), M(0x0c2), M(0x0c3), M(0x0c4), M(0x0c5), M(0x0c6), M(0x0c7), +M(0x0c8), M(0x0c9), M(0x0ca), M(0x0cb), M(0x0cc), M(0x0cd), M(0x0ce), M(0x0cf), +M(0x0d0), M(0x0d1), M(0x0d2), M(0x0d3), M(0x0d4), M(0x0d5), M(0x0d6), M(0x0d7), +M(0x0d8), M(0x0d9), M(0x0da), M(0x0db), M(0x0dc), M(0x0dd), M(0x0de), M(0x0df), +M(0x0e0), M(0x0e1), M(0x0e2), M(0x0e3), M(0x0e4), M(0x0e5), M(0x0e6), M(0x0e7), +M(0x0e8), M(0x0e9), M(0x0ea), M(0x0eb), M(0x0ec), M(0x0ed), M(0x0ee), M(0x0ef), +M(0x0f0), M(0x0f1), M(0x0f2), M(0x0f3), M(0x0f4), M(0x0f5), M(0x0f6), M(0x0f7), +M(0x0f8), M(0x0f9), M(0x0fa), M(0x0fb), M(0x0fc), M(0x0fd), M(0x0fe), M(0x0ff), +M(0x100), M(0x101), M(0x102), M(0x103), M(0x104), M(0x105), M(0x106), M(0x107), +M(0x108), M(0x109), M(0x10a), M(0x10b), M(0x10c), M(0x10d), M(0x10e), M(0x10f), +M(0x110), M(0x111), M(0x112), M(0x113), M(0x114), M(0x115), M(0x116), M(0x117), +M(0x118), M(0x119), M(0x11a), M(0x11b), M(0x11c), M(0x11d), M(0x11e), M(0x11f), +M(0x120), M(0x121), M(0x122), M(0x123), M(0x124), M(0x125), M(0x126), M(0x127), +M(0x128), M(0x129), M(0x12a), M(0x12b), M(0x12c), M(0x12d), M(0x12e), M(0x12f), +M(0x130), M(0x131), M(0x132), M(0x133), M(0x134), M(0x135), M(0x136), M(0x137), +M(0x138), M(0x139), M(0x13a), M(0x13b), M(0x13c), M(0x13d), M(0x13e), M(0x13f), +M(0x140), M(0x141), M(0x142), M(0x143), M(0x144), M(0x145), M(0x146), M(0x147), +M(0x148), M(0x149), M(0x14a), M(0x14b), M(0x14c), M(0x14d), M(0x14e), M(0x14f), +M(0x150), M(0x151), M(0x152), M(0x153), M(0x154), M(0x155), M(0x156), M(0x157), +M(0x158), M(0x159), M(0x15a), M(0x15b), M(0x15c), M(0x15d), M(0x15e), M(0x15f), +M(0x160), M(0x161), M(0x162), M(0x163), M(0x164), M(0x165), M(0x166), M(0x167), +M(0x168), M(0x169), M(0x16a), M(0x16b), M(0x16c), M(0x16d), M(0x16e), M(0x16f), +M(0x170), M(0x171), M(0x172), M(0x173), M(0x174), M(0x175), M(0x176), M(0x177), +M(0x178), M(0x179), M(0x17a), M(0x17b), M(0x17c), M(0x17d), M(0x17e), M(0x17f), +M(0x180), M(0x181), M(0x182), M(0x183), M(0x184), M(0x185), M(0x186), M(0x187), +M(0x188), M(0x189), M(0x18a), M(0x18b), M(0x18c), M(0x18d), M(0x18e), M(0x18f), +M(0x190), M(0x191), M(0x192), M(0x193), M(0x194), M(0x195), M(0x196), M(0x197), +M(0x198), M(0x199), M(0x19a), M(0x19b), M(0x19c), M(0x19d), M(0x19e), M(0x19f), +M(0x1a0), M(0x1a1), M(0x1a2), M(0x1a3), M(0x1a4), M(0x1a5), M(0x1a6), M(0x1a7), +M(0x1a8), M(0x1a9), M(0x1aa), M(0x1ab), M(0x1ac), M(0x1ad), M(0x1ae), M(0x1af), +M(0x1b0), M(0x1b1), M(0x1b2), M(0x1b3), M(0x1b4), M(0x1b5), M(0x1b6), M(0x1b7), +M(0x1b8), M(0x1b9), M(0x1ba), M(0x1bb), M(0x1bc), M(0x1bd), M(0x1be), M(0x1bf), +M(0x1c0), M(0x1c1), M(0x1c2), M(0x1c3), M(0x1c4), M(0x1c5), M(0x1c6), M(0x1c7), +M(0x1c8), M(0x1c9), M(0x1ca), M(0x1cb), M(0x1cc), M(0x1cd), M(0x1ce), M(0x1cf), +M(0x1d0), M(0x1d1), M(0x1d2), M(0x1d3), M(0x1d4), M(0x1d5), M(0x1d6), M(0x1d7), +M(0x1d8), M(0x1d9), M(0x1da), M(0x1db), M(0x1dc), M(0x1dd), M(0x1de), M(0x1df), +M(0x1e0), M(0x1e1), M(0x1e2), M(0x1e3), M(0x1e4), M(0x1e5), M(0x1e6), M(0x1e7), +M(0x1e8), M(0x1e9), M(0x1ea), M(0x1eb), M(0x1ec), M(0x1ed), M(0x1ee), M(0x1ef), +M(0x1f0), M(0x1f1), M(0x1f2), M(0x1f3), M(0x1f4), M(0x1f5), M(0x1f6), M(0x1f7), +M(0x1f8), M(0x1f9), M(0x1fa), M(0x1fb), M(0x1fc), M(0x1fd), M(0x1fe), M(0x1ff) }; #ifdef MAKE_IDENTITY_MAP @@ -212,170 +191,148 @@ const pde_t firstpdir[N_PDE] = { */ // identity-map 4KB page #n -#define S(n) [n] = (pte_t)((TO_4KFRAME((n))) | (PTE_P | PTE_RW)) +#define S(n) [n] = (pte_t) ( (TO_4KFRAME((n))) | (PTE_P|PTE_RW) ) const pte_t id_map[N_PTE] = { - S(0x000), S(0x001), S(0x002), S(0x003), S(0x004), S(0x005), S(0x006), - S(0x007), S(0x008), S(0x009), S(0x00a), S(0x00b), S(0x00c), S(0x00d), - S(0x00e), S(0x00f), S(0x010), S(0x011), S(0x012), S(0x013), S(0x014), - S(0x015), S(0x016), S(0x017), S(0x018), S(0x019), S(0x01a), S(0x01b), - S(0x01c), S(0x01d), S(0x01e), S(0x01f), S(0x020), S(0x021), S(0x022), - S(0x023), S(0x024), S(0x025), S(0x026), S(0x027), S(0x028), S(0x029), - S(0x02a), S(0x02b), S(0x02c), S(0x02d), S(0x02e), S(0x02f), S(0x030), - S(0x031), S(0x032), S(0x033), S(0x034), S(0x035), S(0x036), S(0x037), - S(0x038), S(0x039), S(0x03a), S(0x03b), S(0x03c), S(0x03d), S(0x03e), - S(0x03f), S(0x040), S(0x041), S(0x042), S(0x043), S(0x044), S(0x045), - S(0x046), S(0x047), S(0x048), S(0x049), S(0x04a), S(0x04b), S(0x04c), - S(0x04d), S(0x04e), S(0x04f), S(0x050), S(0x051), S(0x052), S(0x053), - S(0x054), S(0x055), S(0x056), S(0x057), S(0x058), S(0x059), S(0x05a), - S(0x05b), S(0x05c), S(0x05d), S(0x05e), S(0x05f), S(0x060), S(0x061), - S(0x062), S(0x063), S(0x064), S(0x065), S(0x066), S(0x067), S(0x068), - S(0x069), S(0x06a), S(0x06b), S(0x06c), S(0x06d), S(0x06e), S(0x06f), - S(0x070), S(0x071), S(0x072), S(0x073), S(0x074), S(0x075), S(0x076), - S(0x077), S(0x078), S(0x079), S(0x07a), S(0x07b), S(0x07c), S(0x07d), - S(0x07e), S(0x07f), S(0x080), S(0x081), S(0x082), S(0x083), S(0x084), - S(0x085), S(0x086), S(0x087), S(0x088), S(0x089), S(0x08a), S(0x08b), - S(0x08c), S(0x08d), S(0x08e), S(0x08f), S(0x090), S(0x091), S(0x092), - S(0x093), S(0x094), S(0x095), S(0x096), S(0x097), S(0x098), S(0x099), - S(0x09a), S(0x09b), S(0x09c), S(0x09d), S(0x09e), S(0x09f), S(0x0a0), - S(0x0a1), S(0x0a2), S(0x0a3), S(0x0a4), S(0x0a5), S(0x0a6), S(0x0a7), - S(0x0a8), S(0x0a9), S(0x0aa), S(0x0ab), S(0x0ac), S(0x0ad), S(0x0ae), - S(0x0af), S(0x0b0), S(0x0b1), S(0x0b2), S(0x0b3), S(0x0b4), S(0x0b5), - S(0x0b6), S(0x0b7), S(0x0b8), S(0x0b9), S(0x0ba), S(0x0bb), S(0x0bc), - S(0x0bd), S(0x0be), S(0x0bf), S(0x0c0), S(0x0c1), S(0x0c2), S(0x0c3), - S(0x0c4), S(0x0c5), S(0x0c6), S(0x0c7), S(0x0c8), S(0x0c9), S(0x0ca), - S(0x0cb), S(0x0cc), S(0x0cd), S(0x0ce), S(0x0cf), S(0x0d0), S(0x0d1), - S(0x0d2), S(0x0d3), S(0x0d4), S(0x0d5), S(0x0d6), S(0x0d7), S(0x0d8), - S(0x0d9), S(0x0da), S(0x0db), S(0x0dc), S(0x0dd), S(0x0de), S(0x0df), - S(0x0e0), S(0x0e1), S(0x0e2), S(0x0e3), S(0x0e4), S(0x0e5), S(0x0e6), - S(0x0e7), S(0x0e8), S(0x0e9), S(0x0ea), S(0x0eb), S(0x0ec), S(0x0ed), - S(0x0ee), S(0x0ef), S(0x0f0), S(0x0f1), S(0x0f2), S(0x0f3), S(0x0f4), - S(0x0f5), S(0x0f6), S(0x0f7), S(0x0f8), S(0x0f9), S(0x0fa), S(0x0fb), - S(0x0fc), S(0x0fd), S(0x0fe), S(0x0ff), S(0x100), S(0x101), S(0x102), - S(0x103), S(0x104), S(0x105), S(0x106), S(0x107), S(0x108), S(0x109), - S(0x10a), S(0x10b), S(0x10c), S(0x10d), S(0x10e), S(0x10f), S(0x110), - S(0x111), S(0x112), S(0x113), S(0x114), S(0x115), S(0x116), S(0x117), - S(0x118), S(0x119), S(0x11a), S(0x11b), S(0x11c), S(0x11d), S(0x11e), - S(0x11f), S(0x120), S(0x121), S(0x122), S(0x123), S(0x124), S(0x125), - S(0x126), S(0x127), S(0x128), S(0x129), S(0x12a), S(0x12b), S(0x12c), - S(0x12d), S(0x12e), S(0x12f), S(0x130), S(0x131), S(0x132), S(0x133), - S(0x134), S(0x135), S(0x136), S(0x137), S(0x138), S(0x139), S(0x13a), - S(0x13b), S(0x13c), S(0x13d), S(0x13e), S(0x13f), S(0x140), S(0x141), - S(0x142), S(0x143), S(0x144), S(0x145), S(0x146), S(0x147), S(0x148), - S(0x149), S(0x14a), S(0x14b), S(0x14c), S(0x14d), S(0x14e), S(0x14f), - S(0x150), S(0x151), S(0x152), S(0x153), S(0x154), S(0x155), S(0x156), - S(0x157), S(0x158), S(0x159), S(0x15a), S(0x15b), S(0x15c), S(0x15d), - S(0x15e), S(0x15f), S(0x160), S(0x161), S(0x162), S(0x163), S(0x164), - S(0x165), S(0x166), S(0x167), S(0x168), S(0x169), S(0x16a), S(0x16b), - S(0x16c), S(0x16d), S(0x16e), S(0x16f), S(0x170), S(0x171), S(0x172), - S(0x173), S(0x174), S(0x175), S(0x176), S(0x177), S(0x178), S(0x179), - S(0x17a), S(0x17b), S(0x17c), S(0x17d), S(0x17e), S(0x17f), S(0x180), - S(0x181), S(0x182), S(0x183), S(0x184), S(0x185), S(0x186), S(0x187), - S(0x188), S(0x189), S(0x18a), S(0x18b), S(0x18c), S(0x18d), S(0x18e), - S(0x18f), S(0x190), S(0x191), S(0x192), S(0x193), S(0x194), S(0x195), - S(0x196), S(0x197), S(0x198), S(0x199), S(0x19a), S(0x19b), S(0x19c), - S(0x19d), S(0x19e), S(0x19f), S(0x1a0), S(0x1a1), S(0x1a2), S(0x1a3), - S(0x1a4), S(0x1a5), S(0x1a6), S(0x1a7), S(0x1a8), S(0x1a9), S(0x1aa), - S(0x1ab), S(0x1ac), S(0x1ad), S(0x1ae), S(0x1af), S(0x1b0), S(0x1b1), - S(0x1b2), S(0x1b3), S(0x1b4), S(0x1b5), S(0x1b6), S(0x1b7), S(0x1b8), - S(0x1b9), S(0x1ba), S(0x1bb), S(0x1bc), S(0x1bd), S(0x1be), S(0x1bf), - S(0x1c0), S(0x1c1), S(0x1c2), S(0x1c3), S(0x1c4), S(0x1c5), S(0x1c6), - S(0x1c7), S(0x1c8), S(0x1c9), S(0x1ca), S(0x1cb), S(0x1cc), S(0x1cd), - S(0x1ce), S(0x1cf), S(0x1d0), S(0x1d1), S(0x1d2), S(0x1d3), S(0x1d4), - S(0x1d5), S(0x1d6), S(0x1d7), S(0x1d8), S(0x1d9), S(0x1da), S(0x1db), - S(0x1dc), S(0x1dd), S(0x1de), S(0x1df), S(0x1e0), S(0x1e1), S(0x1e2), - S(0x1e3), S(0x1e4), S(0x1e5), S(0x1e6), S(0x1e7), S(0x1e8), S(0x1e9), - S(0x1ea), S(0x1eb), S(0x1ec), S(0x1ed), S(0x1ee), S(0x1ef), S(0x1f0), - S(0x1f1), S(0x1f2), S(0x1f3), S(0x1f4), S(0x1f5), S(0x1f6), S(0x1f7), - S(0x1f8), S(0x1f9), S(0x1fa), S(0x1fb), S(0x1fc), S(0x1fd), S(0x1fe), - S(0x1ff), S(0x200), S(0x201), S(0x202), S(0x203), S(0x204), S(0x205), - S(0x206), S(0x207), S(0x208), S(0x209), S(0x20a), S(0x20b), S(0x20c), - S(0x20d), S(0x20e), S(0x20f), S(0x210), S(0x211), S(0x212), S(0x213), - S(0x214), S(0x215), S(0x216), S(0x217), S(0x218), S(0x219), S(0x21a), - S(0x21b), S(0x21c), S(0x21d), S(0x21e), S(0x21f), S(0x220), S(0x221), - S(0x222), S(0x223), S(0x224), S(0x225), S(0x226), S(0x227), S(0x228), - S(0x229), S(0x22a), S(0x22b), S(0x22c), S(0x22d), S(0x22e), S(0x22f), - S(0x230), S(0x231), S(0x232), S(0x233), S(0x234), S(0x235), S(0x236), - S(0x237), S(0x238), S(0x239), S(0x23a), S(0x23b), S(0x23c), S(0x23d), - S(0x23e), S(0x23f), S(0x240), S(0x241), S(0x242), S(0x243), S(0x244), - S(0x245), S(0x246), S(0x247), S(0x248), S(0x249), S(0x24a), S(0x24b), - S(0x24c), S(0x24d), S(0x24e), S(0x24f), S(0x250), S(0x251), S(0x252), - S(0x253), S(0x254), S(0x255), S(0x256), S(0x257), S(0x258), S(0x259), - S(0x25a), S(0x25b), S(0x25c), S(0x25d), S(0x25e), S(0x25f), S(0x260), - S(0x261), S(0x262), S(0x263), S(0x264), S(0x265), S(0x266), S(0x267), - S(0x268), S(0x269), S(0x26a), S(0x26b), S(0x26c), S(0x26d), S(0x26e), - S(0x26f), S(0x270), S(0x271), S(0x272), S(0x273), S(0x274), S(0x275), - S(0x276), S(0x277), S(0x278), S(0x279), S(0x27a), S(0x27b), S(0x27c), - S(0x27d), S(0x27e), S(0x27f), S(0x280), S(0x281), S(0x282), S(0x283), - S(0x284), S(0x285), S(0x286), S(0x287), S(0x288), S(0x289), S(0x28a), - S(0x28b), S(0x28c), S(0x28d), S(0x28e), S(0x28f), S(0x290), S(0x291), - S(0x292), S(0x293), S(0x294), S(0x295), S(0x296), S(0x297), S(0x298), - S(0x299), S(0x29a), S(0x29b), S(0x29c), S(0x29d), S(0x29e), S(0x29f), - S(0x2a0), S(0x2a1), S(0x2a2), S(0x2a3), S(0x2a4), S(0x2a5), S(0x2a6), - S(0x2a7), S(0x2a8), S(0x2a9), S(0x2aa), S(0x2ab), S(0x2ac), S(0x2ad), - S(0x2ae), S(0x2af), S(0x2b0), S(0x2b1), S(0x2b2), S(0x2b3), S(0x2b4), - S(0x2b5), S(0x2b6), S(0x2b7), S(0x2b8), S(0x2b9), S(0x2ba), S(0x2bb), - S(0x2bc), S(0x2bd), S(0x2be), S(0x2bf), S(0x2c0), S(0x2c1), S(0x2c2), - S(0x2c3), S(0x2c4), S(0x2c5), S(0x2c6), S(0x2c7), S(0x2c8), S(0x2c9), - S(0x2ca), S(0x2cb), S(0x2cc), S(0x2cd), S(0x2ce), S(0x2cf), S(0x2d0), - S(0x2d1), S(0x2d2), S(0x2d3), S(0x2d4), S(0x2d5), S(0x2d6), S(0x2d7), - S(0x2d8), S(0x2d9), S(0x2da), S(0x2db), S(0x2dc), S(0x2dd), S(0x2de), - S(0x2df), S(0x2e0), S(0x2e1), S(0x2e2), S(0x2e3), S(0x2e4), S(0x2e5), - S(0x2e6), S(0x2e7), S(0x2e8), S(0x2e9), S(0x2ea), S(0x2eb), S(0x2ec), - S(0x2ed), S(0x2ee), S(0x2ef), S(0x2f0), S(0x2f1), S(0x2f2), S(0x2f3), - S(0x2f4), S(0x2f5), S(0x2f6), S(0x2f7), S(0x2f8), S(0x2f9), S(0x2fa), - S(0x2fb), S(0x2fc), S(0x2fd), S(0x2fe), S(0x2ff), S(0x300), S(0x301), - S(0x302), S(0x303), S(0x304), S(0x305), S(0x306), S(0x307), S(0x308), - S(0x309), S(0x30a), S(0x30b), S(0x30c), S(0x30d), S(0x30e), S(0x30f), - S(0x310), S(0x311), S(0x312), S(0x313), S(0x314), S(0x315), S(0x316), - S(0x317), S(0x318), S(0x319), S(0x31a), S(0x31b), S(0x31c), S(0x31d), - S(0x31e), S(0x31f), S(0x320), S(0x321), S(0x322), S(0x323), S(0x324), - S(0x325), S(0x326), S(0x327), S(0x328), S(0x329), S(0x32a), S(0x32b), - S(0x32c), S(0x32d), S(0x32e), S(0x32f), S(0x330), S(0x331), S(0x332), - S(0x333), S(0x334), S(0x335), S(0x336), S(0x337), S(0x338), S(0x339), - S(0x33a), S(0x33b), S(0x33c), S(0x33d), S(0x33e), S(0x33f), S(0x340), - S(0x341), S(0x342), S(0x343), S(0x344), S(0x345), S(0x346), S(0x347), - S(0x348), S(0x349), S(0x34a), S(0x34b), S(0x34c), S(0x34d), S(0x34e), - S(0x34f), S(0x350), S(0x351), S(0x352), S(0x353), S(0x354), S(0x355), - S(0x356), S(0x357), S(0x358), S(0x359), S(0x35a), S(0x35b), S(0x35c), - S(0x35d), S(0x35e), S(0x35f), S(0x360), S(0x361), S(0x362), S(0x363), - S(0x364), S(0x365), S(0x366), S(0x367), S(0x368), S(0x369), S(0x36a), - S(0x36b), S(0x36c), S(0x36d), S(0x36e), S(0x36f), S(0x370), S(0x371), - S(0x372), S(0x373), S(0x374), S(0x375), S(0x376), S(0x377), S(0x378), - S(0x379), S(0x37a), S(0x37b), S(0x37c), S(0x37d), S(0x37e), S(0x37f), - S(0x380), S(0x381), S(0x382), S(0x383), S(0x384), S(0x385), S(0x386), - S(0x387), S(0x388), S(0x389), S(0x38a), S(0x38b), S(0x38c), S(0x38d), - S(0x38e), S(0x38f), S(0x390), S(0x391), S(0x392), S(0x393), S(0x394), - S(0x395), S(0x396), S(0x397), S(0x398), S(0x399), S(0x39a), S(0x39b), - S(0x39c), S(0x39d), S(0x39e), S(0x39f), S(0x3a0), S(0x3a1), S(0x3a2), - S(0x3a3), S(0x3a4), S(0x3a5), S(0x3a6), S(0x3a7), S(0x3a8), S(0x3a9), - S(0x3aa), S(0x3ab), S(0x3ac), S(0x3ad), S(0x3ae), S(0x3af), S(0x3b0), - S(0x3b1), S(0x3b2), S(0x3b3), S(0x3b4), S(0x3b5), S(0x3b6), S(0x3b7), - S(0x3b8), S(0x3b9), S(0x3ba), S(0x3bb), S(0x3bc), S(0x3bd), S(0x3be), - S(0x3bf), S(0x3c0), S(0x3c1), S(0x3c2), S(0x3c3), S(0x3c4), S(0x3c5), - S(0x3c6), S(0x3c7), S(0x3c8), S(0x3c9), S(0x3ca), S(0x3cb), S(0x3cc), - S(0x3cd), S(0x3ce), S(0x3cf), S(0x3d0), S(0x3d1), S(0x3d2), S(0x3d3), - S(0x3d4), S(0x3d5), S(0x3d6), S(0x3d7), S(0x3d8), S(0x3d9), S(0x3da), - S(0x3db), S(0x3dc), S(0x3dd), S(0x3de), S(0x3df), S(0x3e0), S(0x3e1), - S(0x3e2), S(0x3e3), S(0x3e4), S(0x3e5), S(0x3e6), S(0x3e7), S(0x3e8), - S(0x3e9), S(0x3ea), S(0x3eb), S(0x3ec), S(0x3ed), S(0x3ee), S(0x3ef), - S(0x3f0), S(0x3f1), S(0x3f2), S(0x3f3), S(0x3f4), S(0x3f5), S(0x3f6), - S(0x3f7), S(0x3f8), S(0x3f9), S(0x3fa), S(0x3fb), S(0x3fc), S(0x3fd), - S(0x3fe), S(0x3ff) +S(0x000), S(0x001), S(0x002), S(0x003), S(0x004), S(0x005), S(0x006), S(0x007), +S(0x008), S(0x009), S(0x00a), S(0x00b), S(0x00c), S(0x00d), S(0x00e), S(0x00f), +S(0x010), S(0x011), S(0x012), S(0x013), S(0x014), S(0x015), S(0x016), S(0x017), +S(0x018), S(0x019), S(0x01a), S(0x01b), S(0x01c), S(0x01d), S(0x01e), S(0x01f), +S(0x020), S(0x021), S(0x022), S(0x023), S(0x024), S(0x025), S(0x026), S(0x027), +S(0x028), S(0x029), S(0x02a), S(0x02b), S(0x02c), S(0x02d), S(0x02e), S(0x02f), +S(0x030), S(0x031), S(0x032), S(0x033), S(0x034), S(0x035), S(0x036), S(0x037), +S(0x038), S(0x039), S(0x03a), S(0x03b), S(0x03c), S(0x03d), S(0x03e), S(0x03f), +S(0x040), S(0x041), S(0x042), S(0x043), S(0x044), S(0x045), S(0x046), S(0x047), +S(0x048), S(0x049), S(0x04a), S(0x04b), S(0x04c), S(0x04d), S(0x04e), S(0x04f), +S(0x050), S(0x051), S(0x052), S(0x053), S(0x054), S(0x055), S(0x056), S(0x057), +S(0x058), S(0x059), S(0x05a), S(0x05b), S(0x05c), S(0x05d), S(0x05e), S(0x05f), +S(0x060), S(0x061), S(0x062), S(0x063), S(0x064), S(0x065), S(0x066), S(0x067), +S(0x068), S(0x069), S(0x06a), S(0x06b), S(0x06c), S(0x06d), S(0x06e), S(0x06f), +S(0x070), S(0x071), S(0x072), S(0x073), S(0x074), S(0x075), S(0x076), S(0x077), +S(0x078), S(0x079), S(0x07a), S(0x07b), S(0x07c), S(0x07d), S(0x07e), S(0x07f), +S(0x080), S(0x081), S(0x082), S(0x083), S(0x084), S(0x085), S(0x086), S(0x087), +S(0x088), S(0x089), S(0x08a), S(0x08b), S(0x08c), S(0x08d), S(0x08e), S(0x08f), +S(0x090), S(0x091), S(0x092), S(0x093), S(0x094), S(0x095), S(0x096), S(0x097), +S(0x098), S(0x099), S(0x09a), S(0x09b), S(0x09c), S(0x09d), S(0x09e), S(0x09f), +S(0x0a0), S(0x0a1), S(0x0a2), S(0x0a3), S(0x0a4), S(0x0a5), S(0x0a6), S(0x0a7), +S(0x0a8), S(0x0a9), S(0x0aa), S(0x0ab), S(0x0ac), S(0x0ad), S(0x0ae), S(0x0af), +S(0x0b0), S(0x0b1), S(0x0b2), S(0x0b3), S(0x0b4), S(0x0b5), S(0x0b6), S(0x0b7), +S(0x0b8), S(0x0b9), S(0x0ba), S(0x0bb), S(0x0bc), S(0x0bd), S(0x0be), S(0x0bf), +S(0x0c0), S(0x0c1), S(0x0c2), S(0x0c3), S(0x0c4), S(0x0c5), S(0x0c6), S(0x0c7), +S(0x0c8), S(0x0c9), S(0x0ca), S(0x0cb), S(0x0cc), S(0x0cd), S(0x0ce), S(0x0cf), +S(0x0d0), S(0x0d1), S(0x0d2), S(0x0d3), S(0x0d4), S(0x0d5), S(0x0d6), S(0x0d7), +S(0x0d8), S(0x0d9), S(0x0da), S(0x0db), S(0x0dc), S(0x0dd), S(0x0de), S(0x0df), +S(0x0e0), S(0x0e1), S(0x0e2), S(0x0e3), S(0x0e4), S(0x0e5), S(0x0e6), S(0x0e7), +S(0x0e8), S(0x0e9), S(0x0ea), S(0x0eb), S(0x0ec), S(0x0ed), S(0x0ee), S(0x0ef), +S(0x0f0), S(0x0f1), S(0x0f2), S(0x0f3), S(0x0f4), S(0x0f5), S(0x0f6), S(0x0f7), +S(0x0f8), S(0x0f9), S(0x0fa), S(0x0fb), S(0x0fc), S(0x0fd), S(0x0fe), S(0x0ff), +S(0x100), S(0x101), S(0x102), S(0x103), S(0x104), S(0x105), S(0x106), S(0x107), +S(0x108), S(0x109), S(0x10a), S(0x10b), S(0x10c), S(0x10d), S(0x10e), S(0x10f), +S(0x110), S(0x111), S(0x112), S(0x113), S(0x114), S(0x115), S(0x116), S(0x117), +S(0x118), S(0x119), S(0x11a), S(0x11b), S(0x11c), S(0x11d), S(0x11e), S(0x11f), +S(0x120), S(0x121), S(0x122), S(0x123), S(0x124), S(0x125), S(0x126), S(0x127), +S(0x128), S(0x129), S(0x12a), S(0x12b), S(0x12c), S(0x12d), S(0x12e), S(0x12f), +S(0x130), S(0x131), S(0x132), S(0x133), S(0x134), S(0x135), S(0x136), S(0x137), +S(0x138), S(0x139), S(0x13a), S(0x13b), S(0x13c), S(0x13d), S(0x13e), S(0x13f), +S(0x140), S(0x141), S(0x142), S(0x143), S(0x144), S(0x145), S(0x146), S(0x147), +S(0x148), S(0x149), S(0x14a), S(0x14b), S(0x14c), S(0x14d), S(0x14e), S(0x14f), +S(0x150), S(0x151), S(0x152), S(0x153), S(0x154), S(0x155), S(0x156), S(0x157), +S(0x158), S(0x159), S(0x15a), S(0x15b), S(0x15c), S(0x15d), S(0x15e), S(0x15f), +S(0x160), S(0x161), S(0x162), S(0x163), S(0x164), S(0x165), S(0x166), S(0x167), +S(0x168), S(0x169), S(0x16a), S(0x16b), S(0x16c), S(0x16d), S(0x16e), S(0x16f), +S(0x170), S(0x171), S(0x172), S(0x173), S(0x174), S(0x175), S(0x176), S(0x177), +S(0x178), S(0x179), S(0x17a), S(0x17b), S(0x17c), S(0x17d), S(0x17e), S(0x17f), +S(0x180), S(0x181), S(0x182), S(0x183), S(0x184), S(0x185), S(0x186), S(0x187), +S(0x188), S(0x189), S(0x18a), S(0x18b), S(0x18c), S(0x18d), S(0x18e), S(0x18f), +S(0x190), S(0x191), S(0x192), S(0x193), S(0x194), S(0x195), S(0x196), S(0x197), +S(0x198), S(0x199), S(0x19a), S(0x19b), S(0x19c), S(0x19d), S(0x19e), S(0x19f), +S(0x1a0), S(0x1a1), S(0x1a2), S(0x1a3), S(0x1a4), S(0x1a5), S(0x1a6), S(0x1a7), +S(0x1a8), S(0x1a9), S(0x1aa), S(0x1ab), S(0x1ac), S(0x1ad), S(0x1ae), S(0x1af), +S(0x1b0), S(0x1b1), S(0x1b2), S(0x1b3), S(0x1b4), S(0x1b5), S(0x1b6), S(0x1b7), +S(0x1b8), S(0x1b9), S(0x1ba), S(0x1bb), S(0x1bc), S(0x1bd), S(0x1be), S(0x1bf), +S(0x1c0), S(0x1c1), S(0x1c2), S(0x1c3), S(0x1c4), S(0x1c5), S(0x1c6), S(0x1c7), +S(0x1c8), S(0x1c9), S(0x1ca), S(0x1cb), S(0x1cc), S(0x1cd), S(0x1ce), S(0x1cf), +S(0x1d0), S(0x1d1), S(0x1d2), S(0x1d3), S(0x1d4), S(0x1d5), S(0x1d6), S(0x1d7), +S(0x1d8), S(0x1d9), S(0x1da), S(0x1db), S(0x1dc), S(0x1dd), S(0x1de), S(0x1df), +S(0x1e0), S(0x1e1), S(0x1e2), S(0x1e3), S(0x1e4), S(0x1e5), S(0x1e6), S(0x1e7), +S(0x1e8), S(0x1e9), S(0x1ea), S(0x1eb), S(0x1ec), S(0x1ed), S(0x1ee), S(0x1ef), +S(0x1f0), S(0x1f1), S(0x1f2), S(0x1f3), S(0x1f4), S(0x1f5), S(0x1f6), S(0x1f7), +S(0x1f8), S(0x1f9), S(0x1fa), S(0x1fb), S(0x1fc), S(0x1fd), S(0x1fe), S(0x1ff), +S(0x200), S(0x201), S(0x202), S(0x203), S(0x204), S(0x205), S(0x206), S(0x207), +S(0x208), S(0x209), S(0x20a), S(0x20b), S(0x20c), S(0x20d), S(0x20e), S(0x20f), +S(0x210), S(0x211), S(0x212), S(0x213), S(0x214), S(0x215), S(0x216), S(0x217), +S(0x218), S(0x219), S(0x21a), S(0x21b), S(0x21c), S(0x21d), S(0x21e), S(0x21f), +S(0x220), S(0x221), S(0x222), S(0x223), S(0x224), S(0x225), S(0x226), S(0x227), +S(0x228), S(0x229), S(0x22a), S(0x22b), S(0x22c), S(0x22d), S(0x22e), S(0x22f), +S(0x230), S(0x231), S(0x232), S(0x233), S(0x234), S(0x235), S(0x236), S(0x237), +S(0x238), S(0x239), S(0x23a), S(0x23b), S(0x23c), S(0x23d), S(0x23e), S(0x23f), +S(0x240), S(0x241), S(0x242), S(0x243), S(0x244), S(0x245), S(0x246), S(0x247), +S(0x248), S(0x249), S(0x24a), S(0x24b), S(0x24c), S(0x24d), S(0x24e), S(0x24f), +S(0x250), S(0x251), S(0x252), S(0x253), S(0x254), S(0x255), S(0x256), S(0x257), +S(0x258), S(0x259), S(0x25a), S(0x25b), S(0x25c), S(0x25d), S(0x25e), S(0x25f), +S(0x260), S(0x261), S(0x262), S(0x263), S(0x264), S(0x265), S(0x266), S(0x267), +S(0x268), S(0x269), S(0x26a), S(0x26b), S(0x26c), S(0x26d), S(0x26e), S(0x26f), +S(0x270), S(0x271), S(0x272), S(0x273), S(0x274), S(0x275), S(0x276), S(0x277), +S(0x278), S(0x279), S(0x27a), S(0x27b), S(0x27c), S(0x27d), S(0x27e), S(0x27f), +S(0x280), S(0x281), S(0x282), S(0x283), S(0x284), S(0x285), S(0x286), S(0x287), +S(0x288), S(0x289), S(0x28a), S(0x28b), S(0x28c), S(0x28d), S(0x28e), S(0x28f), +S(0x290), S(0x291), S(0x292), S(0x293), S(0x294), S(0x295), S(0x296), S(0x297), +S(0x298), S(0x299), S(0x29a), S(0x29b), S(0x29c), S(0x29d), S(0x29e), S(0x29f), +S(0x2a0), S(0x2a1), S(0x2a2), S(0x2a3), S(0x2a4), S(0x2a5), S(0x2a6), S(0x2a7), +S(0x2a8), S(0x2a9), S(0x2aa), S(0x2ab), S(0x2ac), S(0x2ad), S(0x2ae), S(0x2af), +S(0x2b0), S(0x2b1), S(0x2b2), S(0x2b3), S(0x2b4), S(0x2b5), S(0x2b6), S(0x2b7), +S(0x2b8), S(0x2b9), S(0x2ba), S(0x2bb), S(0x2bc), S(0x2bd), S(0x2be), S(0x2bf), +S(0x2c0), S(0x2c1), S(0x2c2), S(0x2c3), S(0x2c4), S(0x2c5), S(0x2c6), S(0x2c7), +S(0x2c8), S(0x2c9), S(0x2ca), S(0x2cb), S(0x2cc), S(0x2cd), S(0x2ce), S(0x2cf), +S(0x2d0), S(0x2d1), S(0x2d2), S(0x2d3), S(0x2d4), S(0x2d5), S(0x2d6), S(0x2d7), +S(0x2d8), S(0x2d9), S(0x2da), S(0x2db), S(0x2dc), S(0x2dd), S(0x2de), S(0x2df), +S(0x2e0), S(0x2e1), S(0x2e2), S(0x2e3), S(0x2e4), S(0x2e5), S(0x2e6), S(0x2e7), +S(0x2e8), S(0x2e9), S(0x2ea), S(0x2eb), S(0x2ec), S(0x2ed), S(0x2ee), S(0x2ef), +S(0x2f0), S(0x2f1), S(0x2f2), S(0x2f3), S(0x2f4), S(0x2f5), S(0x2f6), S(0x2f7), +S(0x2f8), S(0x2f9), S(0x2fa), S(0x2fb), S(0x2fc), S(0x2fd), S(0x2fe), S(0x2ff), +S(0x300), S(0x301), S(0x302), S(0x303), S(0x304), S(0x305), S(0x306), S(0x307), +S(0x308), S(0x309), S(0x30a), S(0x30b), S(0x30c), S(0x30d), S(0x30e), S(0x30f), +S(0x310), S(0x311), S(0x312), S(0x313), S(0x314), S(0x315), S(0x316), S(0x317), +S(0x318), S(0x319), S(0x31a), S(0x31b), S(0x31c), S(0x31d), S(0x31e), S(0x31f), +S(0x320), S(0x321), S(0x322), S(0x323), S(0x324), S(0x325), S(0x326), S(0x327), +S(0x328), S(0x329), S(0x32a), S(0x32b), S(0x32c), S(0x32d), S(0x32e), S(0x32f), +S(0x330), S(0x331), S(0x332), S(0x333), S(0x334), S(0x335), S(0x336), S(0x337), +S(0x338), S(0x339), S(0x33a), S(0x33b), S(0x33c), S(0x33d), S(0x33e), S(0x33f), +S(0x340), S(0x341), S(0x342), S(0x343), S(0x344), S(0x345), S(0x346), S(0x347), +S(0x348), S(0x349), S(0x34a), S(0x34b), S(0x34c), S(0x34d), S(0x34e), S(0x34f), +S(0x350), S(0x351), S(0x352), S(0x353), S(0x354), S(0x355), S(0x356), S(0x357), +S(0x358), S(0x359), S(0x35a), S(0x35b), S(0x35c), S(0x35d), S(0x35e), S(0x35f), +S(0x360), S(0x361), S(0x362), S(0x363), S(0x364), S(0x365), S(0x366), S(0x367), +S(0x368), S(0x369), S(0x36a), S(0x36b), S(0x36c), S(0x36d), S(0x36e), S(0x36f), +S(0x370), S(0x371), S(0x372), S(0x373), S(0x374), S(0x375), S(0x376), S(0x377), +S(0x378), S(0x379), S(0x37a), S(0x37b), S(0x37c), S(0x37d), S(0x37e), S(0x37f), +S(0x380), S(0x381), S(0x382), S(0x383), S(0x384), S(0x385), S(0x386), S(0x387), +S(0x388), S(0x389), S(0x38a), S(0x38b), S(0x38c), S(0x38d), S(0x38e), S(0x38f), +S(0x390), S(0x391), S(0x392), S(0x393), S(0x394), S(0x395), S(0x396), S(0x397), +S(0x398), S(0x399), S(0x39a), S(0x39b), S(0x39c), S(0x39d), S(0x39e), S(0x39f), +S(0x3a0), S(0x3a1), S(0x3a2), S(0x3a3), S(0x3a4), S(0x3a5), S(0x3a6), S(0x3a7), +S(0x3a8), S(0x3a9), S(0x3aa), S(0x3ab), S(0x3ac), S(0x3ad), S(0x3ae), S(0x3af), +S(0x3b0), S(0x3b1), S(0x3b2), S(0x3b3), S(0x3b4), S(0x3b5), S(0x3b6), S(0x3b7), +S(0x3b8), S(0x3b9), S(0x3ba), S(0x3bb), S(0x3bc), S(0x3bd), S(0x3be), S(0x3bf), +S(0x3c0), S(0x3c1), S(0x3c2), S(0x3c3), S(0x3c4), S(0x3c5), S(0x3c6), S(0x3c7), +S(0x3c8), S(0x3c9), S(0x3ca), S(0x3cb), S(0x3cc), S(0x3cd), S(0x3ce), S(0x3cf), +S(0x3d0), S(0x3d1), S(0x3d2), S(0x3d3), S(0x3d4), S(0x3d5), S(0x3d6), S(0x3d7), +S(0x3d8), S(0x3d9), S(0x3da), S(0x3db), S(0x3dc), S(0x3dd), S(0x3de), S(0x3df), +S(0x3e0), S(0x3e1), S(0x3e2), S(0x3e3), S(0x3e4), S(0x3e5), S(0x3e6), S(0x3e7), +S(0x3e8), S(0x3e9), S(0x3ea), S(0x3eb), S(0x3ec), S(0x3ed), S(0x3ee), S(0x3ef), +S(0x3f0), S(0x3f1), S(0x3f2), S(0x3f3), S(0x3f4), S(0x3f5), S(0x3f6), S(0x3f7), +S(0x3f8), S(0x3f9), S(0x3fa), S(0x3fb), S(0x3fc), S(0x3fd), S(0x3fe), S(0x3ff) }; -#endif /* MAKE_IDENTITY_MAP */ - -extern char _end[]; +#endif /* MAKE_IDENTITY_MAP */ /* ** Kernel address mappings, present in every page table */ const mapping_t kmap[] = { // va pa_start pa_end perms - { KERN_BASE, 0, EXT_BASE, PDE_RW }, - { KERN_VLINK, KERN_PLINK, V2P(_data), PDE_RW }, - // { (uint32_t) _data, V2P(_data), V2P(_end), PDE_RW }, - { (uint32_t)_data, V2P(_data), PHYS_TOP, PDE_RW } - // { DEV_BASE, DEV_BASE, 0, PDE_RW } + { KERN_BASE, 0, EXT_BASE, PDE_RW }, + { KERN_VLINK, KERN_PLINK, V2P(_data), 0 }, + { (uint32_t) _data, V2P(_data), KERN_BASE, PDE_RW }, + { DEV_BASE, DEV_BASE, 0, PDE_RW } }; const uint_t n_kmap = sizeof(kmap) / sizeof(kmap[0]); -- cgit v1.2.3-freya