diff options
author | Freya Murphy <freya@freyacat.org> | 2025-03-27 11:39:12 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-03-27 11:39:12 -0400 |
commit | 0ff301cda68669c59351e5854ce98f2cf460543f (patch) | |
tree | cfe8f976261962420ada64b821559b9da0a56841 /kernel | |
parent | add compile_flags.txt for clangd lsp (diff) | |
download | comus-0ff301cda68669c59351e5854ce98f2cf460543f.tar.gz comus-0ff301cda68669c59351e5854ce98f2cf460543f.tar.bz2 comus-0ff301cda68669c59351e5854ce98f2cf460543f.zip |
pull upstream changes, add auto formatting
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cio.c | 809 | ||||
-rw-r--r-- | kernel/clock.c | 59 | ||||
-rw-r--r-- | kernel/isrs.S | 2 | ||||
-rw-r--r-- | kernel/kernel.c | 231 | ||||
-rw-r--r-- | kernel/kmem.c | 346 | ||||
-rw-r--r-- | kernel/list.c | 17 | ||||
-rw-r--r-- | kernel/procs.c | 514 | ||||
-rw-r--r-- | kernel/sio.c | 258 | ||||
-rw-r--r-- | kernel/startup.S | 8 | ||||
-rw-r--r-- | kernel/support.c | 122 | ||||
-rw-r--r-- | kernel/syscalls.c | 402 | ||||
-rw-r--r-- | kernel/user.c | 604 | ||||
-rw-r--r-- | kernel/vm.c | 463 | ||||
-rw-r--r-- | kernel/vmtables.c | 522 |
14 files changed, 2432 insertions, 1925 deletions
diff --git a/kernel/cio.c b/kernel/cio.c index cfff543..1e5cb3c 100644 --- a/kernel/cio.c +++ b/kernel/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,55 @@ static unsigned int max_x, max_y; // pointer to input notification function static void (*notify)(int); -#ifdef SA_DEBUG +#ifdef SA_DEBUG #include <stdio.h> -#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) ) ) +#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_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_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,38 +112,40 @@ 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; @@ -159,12 +160,13 @@ 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(); @@ -173,17 +175,19 @@ 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; /* @@ -191,43 +195,41 @@ 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; @@ -239,9 +241,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; } @@ -254,21 +256,23 @@ 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 @@ -276,38 +280,41 @@ 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; @@ -316,7 +323,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; @@ -327,85 +334,84 @@ 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); } - else { - cio_puts( str ); - } - if( extra > 0 && leftadjust ) { - x = mypad( x, y, extra, padchar ); + 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 ); - - while( (ch = *fmt++) != '\0' ) { + ap = (int *)(f + 1); + 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, @@ -418,17 +424,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++; @@ -437,55 +443,52 @@ 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 */ @@ -497,129 +500,352 @@ 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' - }, +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' - } -}; + { // 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; @@ -643,74 +869,76 @@ 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; } } @@ -718,10 +946,11 @@ 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; @@ -730,14 +959,15 @@ 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 @@ -762,34 +992,35 @@ 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/clock.c b/kernel/clock.c index 96f71c4..7af47b7 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -30,8 +30,8 @@ */ // pinwheel control variables -static uint32_t pinwheel; // pinwheel counter -static uint32_t pindex; // index into pinwheel string +static uint32_t pinwheel; // pinwheel counter +static uint32_t pindex; // index into pinwheel string /* ** PUBLIC GLOBAL VARIABLES @@ -52,15 +52,15 @@ uint32_t system_time; ** @param vector Vector number for the clock interrupt ** @param code Error code (0 for this interrupt) */ -static void clk_isr( int vector, int code ) { - +static void clk_isr(int vector, int code) +{ // spin the pinwheel ++pinwheel; - if( pinwheel == (CLOCK_FREQ / 10) ) { + if (pinwheel == (CLOCK_FREQ / 10)) { pinwheel = 0; ++pindex; - cio_putchar_at( 0, 0, "|/-\\"[ pindex & 3 ] ); + cio_putchar_at(0, 0, "|/-\\"[pindex & 3]); } #if defined(SYSTEM_STATUS) @@ -70,14 +70,11 @@ static void clk_isr( int vector, int code ) { // 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) - ); + 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 @@ -91,42 +88,42 @@ static void clk_isr( int vector, int code ) { do { // if there isn't anyone in the sleep queue, we're done - if( pcb_queue_empty(sleeping) ) { + if (pcb_queue_empty(sleeping)) { break; } // peek at the first member of the queue - pcb_t *tmp = pcb_queue_peek( sleeping ); - assert( tmp != NULL ); + 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 ) { + 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 ); + 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 ) { + if (current->ticks < 1) { // yes! reschedule it - schedule( current ); + schedule(current); current = NULL; // and pick a new process dispatch(); } // tell the PIC we're done - outb( PIC1_CMD, PIC_EOI ); + outb(PIC1_CMD, PIC_EOI); } /* @@ -139,10 +136,10 @@ static void clk_isr( int vector, int code ) { ** Initializes the clock module ** */ -void clk_init( void ) { - +void clk_init(void) +{ #if TRACING_INIT - cio_puts( " Clock" ); + cio_puts(" Clock"); #endif // start the pinwheel @@ -154,10 +151,10 @@ void clk_init( void ) { // 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 + 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 ); + install_isr(VEC_TIMER, clk_isr); } diff --git a/kernel/isrs.S b/kernel/isrs.S index 421e6d2..f6bd662 100644 --- a/kernel/isrs.S +++ b/kernel/isrs.S @@ -16,7 +16,7 @@ #define ASM_SRC - .arch i386 +# .arch i386 #include <bootstrap.h> diff --git a/kernel/kernel.c b/kernel/kernel.c index 53e50a7..4a1fd07 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -6,7 +6,7 @@ ** @brief Kernel support routines */ -#define KERNEL_SRC +#define KERNEL_SRC #include <common.h> #include <cio.h> @@ -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,116 +55,117 @@ 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_STACK - " STK" +#if TRACING_VM + " VM" #endif #if TRACING_QUEUE - " QUE" + " QUE" #endif #if TRACING_SCHED - " SCHED" + " SCHED" +#endif +#if TRACING_DISPATCH + " DISPATCH" #endif #if TRACING_SYSCALLS - " SCALL" + " SCALL" #endif #if TRACING_SYSRETS - " SRET" + " SRET" #endif #if TRACING_EXIT - " EXIT" -#endif -#if TRACING_DISPATCH - " DISPATCH" + " 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" #endif -#if TRACING_SPAWN - " SPAWN" +#if TRACING_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_puts( "\n-------------------------------\n" ); + cio_puts("\n-------------------------------\n"); } - #if defined(CONSOLE_STATS) /** ** stats - callback routine for console statistics @@ -176,53 +177,51 @@ 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 ); - pcb_queue_dump( "W", waiting ); - pcb_queue_dump( "S", sleeping ); - pcb_queue_dump( "Z", zombie ); - pcb_queue_dump( "I", sioread ); + 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; } } @@ -240,15 +239,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. @@ -258,13 +257,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 @@ -277,40 +276,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( "-------------------------------\n" ); + cio_puts("\nModule initialization complete.\n"); + cio_puts("-------------------------------\n"); // report our configuration options - kreport( true ); + kreport(true); - delay( DELAY_3_SEC ); + delay(DELAY_3_SEC); /* ** Other tasks typically performed here: @@ -327,7 +326,7 @@ int main( void ) { */ // 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; @@ -335,32 +334,36 @@ 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) == SUCCESS ); + assert(user_load(prog, init_pcb, args) == SUCCESS); // send it on its merry way - schedule( init_pcb ); + 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 @@ -372,10 +375,10 @@ int main( void ) { ** Finally, report that we're all done. */ - cio_puts( "System initialization complete.\n" ); - cio_puts( "-------------------------------\n" ); + cio_puts("System initialization complete.\n"); + cio_puts("-------------------------------\n"); - sio_enable( SIO_RX ); + sio_enable(SIO_RX); return 0; } diff --git a/kernel/kmem.c b/kernel/kmem.c index 8777f49..fe0c7de 100644 --- a/kernel/kmem.c +++ b/kernel/kmem.c @@ -17,6 +17,10 @@ ** (4KB, and aligned at 4KB boundaries); they are held in the free list ** in LIFO order, as all pages are created equal. ** +** By default, the addresses used are virtual addresses rather than +** physical addresses. Define the symbol USE_PADDRS when compiling to +** change this. +** ** Each allocator ("page" and "slice") allocates the first block from ** the appropriate free list. On deallocation, the block is added back ** to the free list. @@ -40,6 +44,8 @@ ** Compilation options: ** ** ALLOC_FAIL_PANIC if an internal slice allocation fails, panic +** USE_PADDRS build the free list using physical, not +** virtual, addresses */ #define KERNEL_SRC @@ -56,24 +62,29 @@ #include <x86/bios.h> #include <bootstrap.h> #include <cio.h> +#include <vm.h> /* ** PRIVATE DEFINITIONS */ +// combination tracing tests +#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 @@ -83,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 @@ -104,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 -} __attribute__((__packed__)) region_t; + 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 @@ -182,22 +193,22 @@ static int km_initialized; ** page-sized fragments which will each be added to the free_pages ** list; each of these will also be modified. ** -** @param[in] base Base address of the block +** @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 TRACING_KMEM | TRACING_KMEM_INIT - cio_printf( " add(%08x,%08x): ", base, length ); +#if ANY_KMEM + 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 @@ -207,37 +218,38 @@ 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; } - // split the block into pages and add them to the free list + // determine the starting and ending addresses for the block +#ifndef USE_PADDRS + // starting and ending addresses as virtual addresses + base = P2V(base); +#endif + // endpoint of the block + uint32_t blend = base + length; - void *block = (void *) base; - void *blend = (void *) (base + length); + // page count for this block int npages = 0; -#if TRACING_KMEM | TRACING_KMEM_INIT - cio_printf( "-> base %08x len %08x: ", base, length ); +#if ANY_KMEM + cio_printf("-> base %08x len %08x: ", base, length); #endif - while( block < blend ) { - - // just add to the front of the list - list_add( &free_pages, block ); + // iterate through the block page by page + while (base < blend) { + list_add(&free_pages, (void *)base); ++npages; - - // move to the next block base += SZ_PAGE; - block = (void *) base; } // add the count to our running total n_pages += npages; -#if TRACING_KMEM | TRACING_KMEM_INIT - cio_printf( " -> %d pages\n", npages ); +#if ANY_KMEM + cio_printf(" -> %d pages\n", npages); #endif } @@ -251,13 +263,14 @@ 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 @@ -266,39 +279,29 @@ void km_init( void ) { n_pages = n_slices = 0; km_initialized = 0; - /* - ** We ignore anything below our KM_LOW_CUTOFF address. In theory, - ** we should be able to re-use much of that space; in practice, - ** this is safer. - */ - // get the list length - entries = *((int32_t *) MMAP_ADDR); + entries = *((int32_t *)MMAP_ADDR); -#if TRACING_KMEM | TRACING_KMEM_INIT - cio_printf( "\nKmem: %d regions\n", entries ); +#if KMEM_OR_INIT + 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)); - - for( int i = 0; i < entries; ++i, ++region ) { + region = ((region_t *)(MMAP_ADDR + 4)); -#if TRACING_KMEM | TRACING_KMEM_INIT + 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 /* @@ -318,33 +321,36 @@ void km_init( void ) { // first, check the ACPI one-bit flags - if( ((region->acpi) & REGION_IGNORE) == 0 ) { -#if TRACING_KMEM | TRACING_KMEM_INIT - cio_puts( " IGN\n" ); + if (((region->acpi) & REGION_IGNORE) == 0) { +#if KMEM_OR_INIT + cio_puts(" IGN\n"); #endif continue; } - if( ((region->acpi) & REGION_NONVOL) != 0 ) { -#if TRACING_KMEM | TRACING_KMEM_INIT - cio_puts( " NVOL\n" ); + if (((region->acpi) & REGION_NONVOL) != 0) { +#if KMEM_OR_INIT + 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 TRACING_KMEM | TRACING_KMEM_INIT - cio_puts( " RCLM\n" ); + if ((region->type) != REGION_USABLE) { +#if KMEM_OR_INIT + 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) } /* ** We have a "normal" memory region. We need to verify - ** that it's within our constraints. We won't add anything - ** to the free list if it is: + ** that it's within our constraints. + ** + ** We ignore anything below our KM_LOW_CUTOFF address. (In theory, + ** we should be able to re-use much of that space; in practice, + ** this is safer.) We won't add anything to the free list if it is: ** ** * below our KM_LOW_CUTOFF value ** * above out KM_HIGH_CUTOFF value. @@ -355,18 +361,17 @@ 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 TRACING_KMEM | TRACING_KMEM_INIT - cio_puts( " HIGH\n" ); +#if KMEM_OR_INIT + cio_puts(" HIGH\n"); #endif continue; } @@ -376,13 +381,12 @@ 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 TRACING_KMEM | TRACING_KMEM_INIT - cio_puts( " LOW\n" ); +#if KMEM_OR_INIT + cio_puts(" LOW\n"); #endif continue; } @@ -400,21 +404,21 @@ void km_init( void ) { // we should recalculate the length length = endpt - base; -#if TRACING_KMEM | TRACING_KMEM_INIT - cio_puts( " OK\n" ); +#if KMEM_OR_INIT + 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 TRACING_KMEM | TRACING_KMEM_INIT - delay( DELAY_3_SEC ); +#if KMEM_OR_INIT + delay(DELAY_3_SEC); #endif } @@ -429,39 +433,38 @@ 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; } @@ -470,21 +473,20 @@ 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); } } @@ -500,35 +502,39 @@ 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"); +#else + return NULL; #endif - return( NULL ); } // fix the count of available pages --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); } /** @@ -538,22 +544,22 @@ 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); +#endif /* ** Don't do anything if the address is NULL. */ - if( page == NULL ){ + if (page == NULL) { return; } -#if TRACING_KMEM_FREELIST - cio_printf( "KM: pg_free(%08x)", (uint32_t) page ); -#endif - /* ** CRITICAL ASSUMPTION ** @@ -575,7 +581,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; @@ -599,15 +605,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); +#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; } @@ -622,38 +632,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); } /** @@ -666,16 +676,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/list.c b/kernel/list.c index 084000a..5492615 100644 --- a/kernel/list.c +++ b/kernel/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,16 +49,15 @@ 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/procs.c b/kernel/procs.c index 96bb3fd..64edb49 100644 --- a/kernel/procs.c +++ b/kernel/procs.c @@ -6,7 +6,7 @@ ** @brief Process-related implementations */ -#define KERNEL_SRC +#define KERNEL_SRC #include <common.h> @@ -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 @@ -75,32 +75,28 @@ pcb_t *init_pcb; // table of state name strings 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" + [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] = { - [ 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] = { - [ 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 @@ -125,16 +121,16 @@ const char *ord_str[N_PRIOS] = { ** @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; } @@ -142,16 +138,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; } @@ -159,16 +155,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; } @@ -181,10 +177,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); \ } /** @@ -192,22 +188,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 @@ -218,8 +214,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; } } @@ -233,14 +229,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; } @@ -255,20 +251,19 @@ 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); } } } @@ -282,15 +277,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 @@ -306,26 +301,24 @@ 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 @@ -333,7 +326,6 @@ void pcb_zombify( register pcb_t *victim ) { // collected when 'init' loops zchild = curr; } - } } @@ -353,20 +345,19 @@ void pcb_zombify( register pcb_t *victim ) { ** 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. @@ -379,8 +370,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); } /* @@ -394,14 +385,12 @@ 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); - - if( target == 0 || target == vicpid ) { + uint32_t target = ARG(parent, 1); + 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. @@ -409,9 +398,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. @@ -424,8 +413,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; } @@ -443,7 +432,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 @@ -459,23 +448,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); } /** @@ -487,18 +476,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; } } @@ -516,19 +505,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; } } @@ -548,13 +537,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; } @@ -575,10 +564,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); } @@ -592,16 +581,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; } @@ -619,41 +608,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? @@ -662,29 +651,25 @@ 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; @@ -700,14 +685,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; } @@ -719,7 +704,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; } @@ -744,14 +729,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; } @@ -759,7 +744,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; } @@ -773,15 +758,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; @@ -793,7 +778,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; @@ -806,10 +791,8 @@ 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; } @@ -824,13 +807,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; } @@ -849,13 +832,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; } @@ -864,8 +847,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"); } } @@ -874,16 +857,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 @@ -891,7 +874,6 @@ void dispatch( void ) { current->ticks = QUANTUM_STANDARD; } - /* ** Debugging/tracing routines */ @@ -904,32 +886,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); } /** @@ -939,19 +921,19 @@ 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); } } } @@ -965,47 +947,46 @@ 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", pcb->pid ); - cio_printf( " %s", - 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'); } /** @@ -1017,36 +998,36 @@ void pcb_dump( const char *msg, register pcb_t *pcb, 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) +{ // 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'); } } @@ -1058,50 +1039,48 @@ 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); } } @@ -1111,14 +1090,15 @@ 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]; @@ -1127,10 +1107,10 @@ void ptable_dump_counts( void ) { ++ptr; } - 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_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/sio.c b/kernel/sio.c index fc20435..8bcc8a1 100644 --- a/kernel/sio.c +++ b/kernel/sio.c @@ -76,28 +76,28 @@ ** PRIVATE DEFINITIONS */ -#define BUF_SIZE 2048 +#define BUF_SIZE 2048 /* ** PRIVATE GLOBALS */ - // input character buffer -static char inbuffer[ BUF_SIZE ]; +// 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 ]; +// output character buffer +static char outbuffer[BUF_SIZE]; static char *outlast; static char *outnext; static uint32_t outcount; - // output control flag +// output control flag static int sending; - // interrupt register status +// interrupt register status static uint8_t ier; /* @@ -122,41 +122,40 @@ extern QTYPE QNAME; ** @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 ) { +static void sio_isr(int vector, int ecode) +{ int ch; #if TRACING_SIO_ISR - cio_puts( "SIO: int:" ); + cio_puts("SIO: int:"); #endif // // Must process all pending events; loop until the IRR // says there's nothing else to do. // - for(;;) { - + for (;;) { // get the "pending event" indicator - int iir = inb( UA4_IIR ) & UA4_IIR_INT_PRI_MASK; + int iir = inb(UA4_IIR) & UA4_IIR_INT_PRI_MASK; // process this event - switch( iir ) { - + switch (iir) { case UA4_IIR_LINE_STATUS: // shouldn't happen, but just in case.... - cio_printf( "** SIO int, LSR = %02x\n", inb(UA4_LSR) ); + cio_printf("** SIO int, LSR = %02x\n", inb(UA4_LSR)); break; case UA4_IIR_RX: #if TRACING_SIO_ISR - cio_puts( " RX" ); + cio_puts(" RX"); #endif // get the character - ch = inb( UA4_RXD ); - if( ch == '\r' ) { // map CR to LF + ch = inb(UA4_RXD); + if (ch == '\r') { // map CR to LF ch = '\n'; } #if TRACING_SIO_ISR - cio_printf( " ch %02x", ch ); + cio_printf(" ch %02x", ch); #endif #ifdef QNAME @@ -166,18 +165,18 @@ static void sio_isr( int vector, int ecode ) { // process and awaken the process. // - if( !QEMPTY(QNAME) ) { + if (!QEMPTY(QNAME)) { PCBTYPE *pcb; - QDEQUE( QNAME, pcb ); + QDEQUE(QNAME, pcb); // make sure we got a non-NULL result - assert( pcb ); + assert(pcb); // return char via arg #2 and count in EAX - char *buf = (char *) ARG(pcb,2); + char *buf = (char *)ARG(pcb, 2); *buf = ch & 0xff; RET(pcb) = 1; - SCHED( pcb ); + SCHED(pcb); } else { #endif /* QNAME */ @@ -187,7 +186,7 @@ static void sio_isr( int vector, int ecode ) { // if there is room, otherwise just ignore it. // - if( incount < BUF_SIZE ) { + if (incount < BUF_SIZE) { *inlast++ = ch; ++incount; } @@ -199,65 +198,64 @@ static void sio_isr( int vector, int ecode ) { 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 ); + 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" ); + cio_puts(" TX"); #endif // if there is another character, send it - if( sending && outcount > 0 ) { + if (sending && outcount > 0) { #if TRACING_SIO_ISR - cio_printf( " ch %02x", *outnext ); + cio_printf(" ch %02x", *outnext); #endif - outb( UA4_TXD, *outnext ); + outb(UA4_TXD, *outnext); ++outnext; // wrap around if necessary - if( outnext >= (outbuffer + BUF_SIZE) ) { + if (outnext >= (outbuffer + BUF_SIZE)) { outnext = outbuffer; } --outcount; #if TRACING_SIO_ISR - cio_printf( " (outcount %d)", outcount ); + cio_printf(" (outcount %d)", outcount); #endif } else { #if TRACING_SIO_ISR - cio_puts( " EOS" ); + 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 ); + sio_disable(SIO_TX); } break; case UA4_IIR_NO_INT: #if TRACING_SIO_ISR - cio_puts( " EOI\n" ); + cio_puts(" EOI\n"); #endif // nothing to do - tell the PIC we're done - outb( PIC1_CMD, PIC_EOI ); + 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) ); + 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 ); + sprint(b256, "sio isr: IIR %02x\n", ((uint32_t)iir) & 0xff); + PANIC(0, b256); } - } // should never reach this point! - assert( false ); + assert(false); } /* @@ -269,27 +267,27 @@ static void sio_isr( int vector, int ecode ) { ** ** Initialize the UART chip. */ -void sio_init( void ) { - +void sio_init(void) +{ #if TRACING_INIT - cio_puts( " Sio" ); + cio_puts(" Sio"); #endif /* ** Initialize SIO variables. */ - memclr( (void *) inbuffer, sizeof(inbuffer) ); + memclr((void *)inbuffer, sizeof(inbuffer)); inlast = innext = inbuffer; incount = 0; - memclr( (void *) outbuffer, sizeof(outbuffer) ); + memclr((void *)outbuffer, sizeof(outbuffer)); outlast = outnext = outbuffer; outcount = 0; sending = 0; // queue of read-blocked processes - QCREATE( QNAME ); + QCREATE(QNAME); /* ** Next, initialize the UART. @@ -299,11 +297,11 @@ void sio_init( void ) { ** 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 + 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 @@ -312,36 +310,36 @@ void sio_init( void ) { ** called to switch them back on */ - outb( UA4_IER, 0 ); + 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 ) ); + 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 ); + 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 ); + outb(UA4_MCR, UA4_MCR_ISEN | UA4_MCR_DTR | UA4_MCR_RTS); /* ** Install our ISR */ - install_isr( VEC_COM1, sio_isr ); + install_isr(VEC_COM1, sio_isr); } /** @@ -355,7 +353,8 @@ void sio_init( void ) { ** ** @return the prior IER setting */ -uint8_t sio_enable( uint8_t which ) { +uint8_t sio_enable(uint8_t which) +{ uint8_t old; // remember the current status @@ -364,23 +363,23 @@ uint8_t sio_enable( uint8_t which ) { // figure out what to enable - if( which & SIO_TX ) { + if (which & SIO_TX) { ier |= UA4_IER_TX_IE; } - if( which & SIO_RX ) { + if (which & SIO_RX) { ier |= UA4_IER_RX_IE; } // if there was a change, make it - if( old != ier ) { - outb( UA4_IER, ier ); + if (old != ier) { + outb(UA4_IER, ier); } // return the prior settings - return( old ); + return (old); } /** @@ -394,7 +393,8 @@ 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) +{ uint8_t old; // remember the current status @@ -403,23 +403,23 @@ uint8_t sio_disable( uint8_t which ) { // figure out what to disable - if( which & SIO_TX ) { + if (which & SIO_TX) { ier &= ~UA4_IER_TX_IE; } - if( which & SIO_RX ) { + if (which & SIO_RX) { ier &= ~UA4_IER_RX_IE; } // if there was a change, make it - if( old != ier ) { - outb( UA4_IER, ier ); + if (old != ier) { + outb(UA4_IER, ier); } // return the prior settings - return( old ); + return (old); } /** @@ -431,8 +431,9 @@ uint8_t sio_disable( uint8_t which ) { ** ** @return the count of characters still in the input queue */ -int sio_inq_length( void ) { - return( incount ); +int sio_inq_length(void) +{ + return (incount); } /** @@ -444,7 +445,8 @@ int sio_inq_length( void ) { ** ** @return the next character, or -1 if no character is available */ -int sio_readc( void ) { +int sio_readc(void) +{ int ch; // assume there is no character available @@ -454,21 +456,18 @@ int sio_readc( void ) { // If there is a character, return it // - if( incount > 0 ) { - + 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 ) { + if (incount < 1) { inlast = innext = inbuffer; } - } - return( ch ); - + return (ch); } /** @@ -484,14 +483,15 @@ int sio_readc( void ) { ** @return the number of bytes copied, or 0 if no characters were available */ -int sio_read( char *buf, int length ) { +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 ); + if (incount < 1) { + return (0); } // @@ -499,9 +499,9 @@ int sio_read( char *buf, int length ) { // buffer as will fit. // - while( incount > 0 && copied < length ) { + while (incount > 0 && copied < length) { *ptr++ = *innext++ & 0xff; - if( innext > (inbuffer + BUF_SIZE) ) { + if (innext > (inbuffer + BUF_SIZE)) { innext = inbuffer; } --incount; @@ -510,16 +510,15 @@ int sio_read( char *buf, int length ) { // reset the input buffer if necessary - if( incount < 1 ) { + if (incount < 1) { inlast = innext = inbuffer; } // return the copy count - return( copied ); + return (copied); } - /** ** sio_writec( ch ) ** @@ -529,22 +528,21 @@ int sio_read( char *buf, int length ) { ** ** @param ch Character to be written (in the low-order 8 bits) */ -void sio_writec( int ch ){ - - +void sio_writec(int ch) +{ // // Must do LF -> CRLF mapping // - if( ch == '\n' ) { - sio_writec( '\r' ); + if (ch == '\n') { + sio_writec('\r'); } // // If we're currently transmitting, just add this to the buffer // - if( sending ) { + if (sending) { *outlast++ = ch; ++outcount; return; @@ -555,12 +553,11 @@ void sio_writec( int ch ){ // sending = 1; - outb( UA4_TXD, ch ); + outb(UA4_TXD, ch); // Also must enable transmitter interrupts - sio_enable( SIO_TX ); - + sio_enable(SIO_TX); } /** @@ -575,7 +572,8 @@ 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) +{ int first = *buffer; const char *ptr = buffer; int copied = 0; @@ -587,15 +585,15 @@ int sio_write( const char *buffer, int length ) { // sio_writec() to send the first one out. // - if( !sending ) { + if (!sending) { ptr += 1; copied++; } - while( copied < length && outcount < BUF_SIZE ) { + while (copied < length && outcount < BUF_SIZE) { *outlast++ = *ptr++; // wrap around if necessary - if( outlast >= (outbuffer + BUF_SIZE) ) { + if (outlast >= (outbuffer + BUF_SIZE)) { outlast = outbuffer; } ++outcount; @@ -608,15 +606,13 @@ int sio_write( const char *buffer, int length ) { // variables for us. // - if( !sending ) { - sio_writec( first ); + if (!sending) { + sio_writec(first); } // Return the transfer count - - return( copied ); - + return (copied); } /** @@ -630,13 +626,14 @@ int sio_write( const char *buffer, int length ) { ** ** @return the count of bytes transferred */ -int sio_puts( const char *buffer ) { - int n; // must be outside the loop so we can return it +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 ); + n = SLENGTH(buffer); + sio_write(buffer, n); - return( n ); + return (n); } /** @@ -651,44 +648,43 @@ int sio_puts( const char *buffer ) { ** of the queues) */ -void sio_dump( bool_t full ) { +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 ); + 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 ) { + if (!full) { return; } // also want the queue contents, but we'll // dump them into the scrolling region - if( incount ) { - cio_puts( "SIO input queue: \"" ); + if (incount) { + cio_puts("SIO input queue: \""); ptr = innext; - for( n = 0; n < incount; ++n ) { - put_char_or_code( *ptr++ ); + for (n = 0; n < incount; ++n) { + put_char_or_code(*ptr++); } - cio_puts( "\"\n" ); + cio_puts("\"\n"); } - if( outcount ) { - cio_puts( "SIO output queue: \"" ); - cio_puts( " ot: \"" ); + if (outcount) { + cio_puts("SIO output queue: \""); + cio_puts(" ot: \""); ptr = outnext; - for( n = 0; n < outcount; ++n ) { - put_char_or_code( *ptr++ ); + for (n = 0; n < outcount; ++n) { + put_char_or_code(*ptr++); } - cio_puts( "\"\n" ); + cio_puts("\"\n"); } } diff --git a/kernel/startup.S b/kernel/startup.S index 1cae13c..73a081e 100644 --- a/kernel/startup.S +++ b/kernel/startup.S @@ -15,7 +15,7 @@ #define KERNEL_SRC #define ASM_SRC - .arch i386 +# .arch i386 #include <common.h> #include <bootstrap.h> @@ -75,11 +75,11 @@ _start: */ .globl __bss_start, _end - movl $V2P(__bss_start), %edi + movl $V2PNC(__bss_start), %edi clearbss: movl $0, (%edi) addl $4, %edi - cmpl $V2P(_end), %edi + cmpl $V2PNC(_end), %edi jb clearbss #endif /* CLEAR_BSS */ @@ -96,7 +96,7 @@ clearbss: # set the page directory .globl firstpdir - movl $(V2P(firstpdir)+0x1000), %eax + movl $(V2PNC(firstpdir)), %eax movl %eax, %cr3 # turn on paging diff --git a/kernel/support.c b/kernel/support.c index d48ce59..89834ee 100644 --- a/kernel/support.c +++ b/kernel/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,11 +59,12 @@ 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"); } /** @@ -75,23 +76,24 @@ 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!"); } } @@ -106,12 +108,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); } /** @@ -119,37 +121,38 @@ 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); } /** @@ -163,7 +166,8 @@ 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; @@ -181,17 +185,18 @@ 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); } /* @@ -200,13 +205,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); } /* @@ -221,10 +226,11 @@ 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 (;;) { ; } } @@ -234,7 +240,8 @@ void panic( char *reason ) { ** ** (Re)initilizes the interrupt system. */ -void init_interrupts( void ) { +void init_interrupts(void) +{ init_idt(); init_pic(); } @@ -244,13 +251,12 @@ 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 (*install_isr(int vector, void (*handler)(int, int)))(int, int) +{ + void (*old_handler)(int vector, int code); - void ( *old_handler )( int vector, int code ); - - old_handler = isr_table[ vector ]; - isr_table[ vector ] = handler; + old_handler = isr_table[vector]; + isr_table[vector] = handler; return old_handler; } @@ -270,10 +276,10 @@ void (*install_isr( int vector, ** ** 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/syscalls.c b/kernel/syscalls.c index 7176cda..0653c93 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -6,7 +6,7 @@ ** @brief System call implementations */ -#define KERNEL_SRC +#define KERNEL_SRC #include <common.h> @@ -33,28 +33,30 @@ #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 @@ -71,7 +73,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 @@ -95,26 +97,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); } /** @@ -128,12 +130,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 @@ -151,47 +153,42 @@ 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 ); - - if( child != NULL ) { + child = pcb_find_pid(target); + 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 @@ -204,15 +201,13 @@ 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; @@ -220,12 +215,11 @@ 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); } - } /* @@ -241,25 +235,24 @@ 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. @@ -272,9 +265,9 @@ SYSIMPL(waitpid) { } // clean up the child - pcb_cleanup( child ); + pcb_cleanup(child); - SYSCALL_EXIT( RET(pcb) ); + SYSCALL_EXIT(RET(pcb)); } /** @@ -287,26 +280,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. @@ -322,9 +315,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); } /** @@ -341,30 +334,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 ); - if( status != SUCCESS ) { + int status = user_load(prog, pcb, args); + if (status != SUCCESS) { RET(pcb) = status; - SYSCALL_EXIT( status ); + SYSCALL_EXIT(status); } /* @@ -380,7 +373,7 @@ SYSIMPL(exec) ** an error status to it. */ - schedule( pcb ); + schedule(pcb); dispatch(); } @@ -394,52 +387,49 @@ SYSIMPL(exec) ** Reads up to 'length' bytes from 'chan' into 'buffer'. Returns the ** count of bytes actually transferred. */ -SYSIMPL(read) { - +SYSIMPL(read) +{ // sanity check - assert( pcb != NULL ); + assert(pcb != NULL); + + SYSCALL_ENTER(pcb->pid); - 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 ); - - } else if( chan == CHAN_SIO ) { + SYSCALL_EXIT(n); + } 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); } /** @@ -451,17 +441,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 @@ -470,27 +460,21 @@ 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); } /** @@ -499,12 +483,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; @@ -516,13 +500,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; @@ -534,12 +518,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; @@ -551,12 +535,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; @@ -568,18 +552,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; @@ -594,56 +578,55 @@ 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; @@ -653,7 +636,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(); @@ -663,8 +646,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; @@ -672,15 +655,14 @@ 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 ** @@ -690,35 +672,33 @@ 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 ); - - if( length == 0 ) { + uint_t length = ARG(pcb, 1); + 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 @@ -727,7 +707,7 @@ SYSIMPL(sleep) { } // only dispatch if the current process called us - if( pcb == current ) { + if (pcb == current) { current = NULL; dispatch(); } @@ -746,20 +726,14 @@ 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 }; /** @@ -770,40 +744,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); } /* @@ -818,12 +792,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/user.c b/kernel/user.c index 2d32157..a019430 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -6,7 +6,7 @@ ** @brief User-level code manipulation routines */ -#define KERNEL_SRC +#define KERNEL_SRC #include <common.h> @@ -39,12 +39,12 @@ ** ** 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,78 +65,117 @@ 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 ); +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 ); + 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); } /* @@ -144,45 +183,67 @@ 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'); } /* @@ -190,58 +251,95 @@ 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 -__attribute__((__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 ); +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); } #endif @@ -258,51 +356,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; } @@ -311,8 +409,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; } @@ -331,8 +429,8 @@ static int read_phdrs( elfhdr_t *hdr, pcb_t *pcb ) { ** ** @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 ) { - +static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args) +{ /* ** First, we need to count the space we'll need for the argument ** vector and strings. @@ -341,10 +439,10 @@ static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { int argbytes = 0; int argc = 0; - while( args[argc] != NULL ) { - int n = strlen( args[argc] ) + 1; + while (args[argc] != NULL) { + int n = strlen(args[argc]) + 1; // can't go over one page in size - if( (argbytes + n) > SZ_PAGE ) { + if ((argbytes + n) > SZ_PAGE) { // oops - ignore this and any others break; } @@ -376,20 +474,20 @@ static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { ** annoyance. */ - char argstrings[ argbytes ]; - char *argv[ argc + 1 ]; + char argstrings[argbytes]; + char *argv[argc + 1]; - CLEAR( argstrings ); - CLEAR( argv ); + CLEAR(argstrings); + CLEAR(argv); // Next, duplicate the argument strings, and create pointers to // each one in our argv. char *tmp = argstrings; - for( int i = 0; i < argc; ++i ) { + 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 + strcpy(tmp, args[i]); // add to our buffer + argv[i] = tmp; // remember where it was + tmp += nb; // move on } // trailing NULL pointer @@ -421,7 +519,7 @@ static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { ** see below for more information. */ - // Pointer to the last word in stack. We get this from the + // 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]; @@ -431,19 +529,18 @@ static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { // 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 *ptr = (uint32_t *)((uint32_t)(stack_pte & MOD4K_MASK) + SZ_PAGE); // Pointer to where the arg strings should be filled in. - char *strings = (char *) ( (uint32_t) ptr - argbytes ); + char *strings = (char *)((uint32_t)ptr - argbytes); // 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); + strings = (char *)((uint32_t)strings & MOD4_MASK); // Copy over the argv strings. - memcpy( (void *)strings, argstrings, argbytes ); + memcpy((void *)strings, argstrings, argbytes); /* ** Next, we need to copy over the argv pointers. Start by @@ -469,7 +566,7 @@ static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { */ int nwords = argc + 3; - uint32_t *acptr = ((uint32_t *) strings) - nwords; + uint32_t *acptr = ((uint32_t *)strings) - nwords; /* ** Next, back up until we're at a multiple-of-16 address. Because we @@ -478,7 +575,7 @@ static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { ** AND to just turn off the lower four bits. */ - acptr = (uint32_t *) ( ((uint32_t)acptr) & MOD16_MASK ); + acptr = (uint32_t *)(((uint32_t)acptr) & MOD16_MASK); // copy in 'argc' *acptr = argc; @@ -486,17 +583,17 @@ static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { // 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; + *(acptr + 1) = (uint32_t)avptr; /* ** Next, we copy in all argc+1 pointers. */ // Adjust and copy the string pointers. - for( int i = 0; i <= argc; ++i ) { - if( argv[i] != NULL ) { + for (int i = 0; i <= argc; ++i) { + if (argv[i] != NULL) { // an actual pointer - adjust it and copy it in - *avptr = (uint32_t) strings; + *avptr = (uint32_t)strings; // skip to the next entry in the array strings += strlen(argv[i]) + 1; } else { @@ -517,7 +614,7 @@ static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { */ // Locate the context save area on the stack. - context_t *ctx = ((context_t *) avptr) - 1; + context_t *ctx = ((context_t *)avptr) - 1; /* ** We cleared the entire stack earlier, so all the context @@ -525,9 +622,9 @@ static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { ** all the important fields. */ - ctx->eflags = DEFAULT_EFLAGS; // IE enabled, PPL 0 - ctx->eip = entry; // initial EIP - ctx->cs = GDT_CODE; // segment registers + 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; @@ -535,8 +632,8 @@ static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { ** Return the new context pointer to the caller. It will be our ** caller's responsibility to schedule this process. */ - - return( ctx ); + + return (ctx); } /* @@ -548,39 +645,36 @@ 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 *) 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 { @@ -588,7 +682,7 @@ void user_init( void ) { user_header = NULL; prog_table = NULL; #if TRACING_USER - cio_putchar( '\n' ); + cio_putchar('\n'); #endif } } @@ -602,15 +696,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 ) { - +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; } @@ -619,7 +713,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; } @@ -637,8 +731,8 @@ 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) +{ // We need to do a recursive duplication of the process address // space of the current process. First, we create a new user // page directory. Next, we'll duplicate the USER_PDE page @@ -647,39 +741,45 @@ 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 + // Next, add a USER_PDE page table that's a duplicate of the // current process' page table - if( !vm_uvmdup(old->pdir,new->pdir) ) { + if (!vm_uvmdup(old->pdir, new->pdir)) { // check for memory leak? return E_NO_MEMORY; } - // now, iterate through the entries, replacing the frame - // numbers with duplicate frames + // We don't do copy-on-write, so we must duplicate all the + // individual page frames. Iterate through all the user-level + // PDE entries, and replace the existing frames with duplicates. // // NOTE: we only deal with pdir[0] here, as we are limiting - // the user address space to the first 4MB - pte_t *pt = (pte_t *) (pdir[USER_PDE]); + // the user address space to the first 4MB. If the size of + // the address space goes up, this code will need to be + // 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); - 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(*pt) ) { + if (IS_PRESENT(entry)) { + // duplicate the frame pointed to by this PTE + void *tmp = vm_pagedup((void *)PTE_ADDR(entry)); - // duplicate the page - void *tmp = vm_pagedup( (void *) (*pt & FRAME_MASK) ); // replace the old frame number with the new one - *pt = (pte_t) (((uint32_t)tmp) | (*pt & PERM_MASK)); + *pt = (pte_t)(((uint32_t)tmp) | PERMS(entry)); } else { - *pt = 0; - } ++pt; } @@ -699,57 +799,57 @@ int user_duplicate( pcb_t *new, pcb_t *old ) { ** ** @return the status of the load attempt */ -int user_load( prog_t *ptab, pcb_t *pcb, const char **args ) { - +int user_load(prog_t *ptab, pcb_t *pcb, const char **args) +{ // NULL pointers are bad! - assert1( ptab != NULL ); - assert1( pcb != NULL ); - assert1( args != NULL ); + 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 ); - for( int i = 0; args[i] != NULL; ++i ) { - cio_printf( " [%d] %s", i, 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 ) { + 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" ); + 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 ) { + 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" ); + PANIC(0, "user_load: vm_add failed"); } // set up the command-line arguments - pcb->context = stack_setup( pcb, hdr->e_entry, args ); + pcb->context = stack_setup(pcb, hdr->e_entry, args); return SUCCESS; } @@ -762,13 +862,13 @@ int user_load( prog_t *ptab, pcb_t *pcb, const char **args ) { ** ** @param pcb The PCB of the program to be unloaded */ -void user_cleanup( pcb_t *pcb ) { - - 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/vm.c b/kernel/vm.c index 46c4eab..e630a0f 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -6,7 +6,7 @@ ** @brief Kernel VM support */ -#define KERNEL_SRC +#define KERNEL_SRC #include <common.h> @@ -19,18 +19,6 @@ #include <x86/ops.h> /* -** PRIVATE DEFINITIONS -*/ - -/* -** PRIVATE DATA TYPES -*/ - -/* -** PRIVATE GLOBAL VARIABLES -*/ - -/* ** PUBLIC GLOBAL VARIABLES */ @@ -49,62 +37,115 @@ 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: uva2kva ** -** Convert a user VA into a kernel address +** 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 pdir Pointer to the page directory to examine +** @param va Virtual address to check */ -__attribute__((__unused__)) -static void *uva2kva( pde_t *pdir, void *va ) { - +ATTR_UNUSED +static void *uva2kva(pde_t *pdir, void *va) +{ // find the PMT entry for this address - pte_t *pte = vm_getpte( pdir, va, false ); - if( pte == NULL ) { + 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(*pte) ) { - return 0; + if (IS_PRESENT(entry)) { + return NULL; } - if( IS_LARGE(*pte) ) { - return 0; + // is this a system-only page? + if (IS_SYSTEM(entry)) { + return NULL; } // get the physical address - uint32_t frame = *pte & FRAME_MASK; // keep the frame address - frame |= ((uint32_t) va) & PERM_MASK; // OR in the lower 12 bits + uint32_t frame = PTE_ADDR(*pte) | PERMS(va); - return (void *) frame; + return (void *)P2V(frame); } +/** +** Name: ptdump +** +** Dump the non-zero entries of a page table or directory +** +** @param pt The page table +** @param dir Is this a page directory? +*/ +static void ptdump(void *pt, bool_t dir) +{ + cio_printf("\n\nP% dump", dir ? 'D' : 'T'); + cio_printf(" of %08x\n", (uint32_t)pt); + + uint_t n = 0; + uint_t z = 0; + pte_t *ptr = pt; + + for (uint_t i = 0; i < N_PTE; ++i) { + pte_t entry = *ptr++; + // four entries per line + if (n && ((n & 0x3) == 0)) { + cio_putchar('\n'); + } + if (IS_PRESENT(entry)) { + cio_printf(" %03x", 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 @@ -115,18 +156,21 @@ static void *uva2kva( pde_t *pdir, void *va ) { ** ** 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 page directory + // set up the kernel's 4K-page directory kpdir = vm_mkkvm(); - assert( kpdir != NULL ); + assert(kpdir != NULL); + + // switch to it + vm_set_kvm(); // install the page fault handler - install_isr( VEC_PAGE_FAULT, vm_isr ); + install_isr(VEC_PAGE_FAULT, vm_isr); } /** @@ -138,16 +182,17 @@ void vm_init( void ) { ** ** @return a pointer to the new, duplicate page, or NULL */ -void *vm_pagedup( void *old ) { - void *new = (void *) km_page_alloc(); - if( new != NULL ) { - memcpy( 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; } /** -** Name: vm_ptdup +** Name: vm_pdedup ** ** Duplicate a page directory entry ** @@ -156,31 +201,39 @@ void *vm_pagedup( void *old ) { ** ** @return true on success, else false */ -bool_t vm_ptdup( pde_t *dst, pde_t *curr ) { +bool_t vm_pdedup(pde_t *dst, pde_t *curr) +{ + assert1(curr != NULL); + assert1(dst != NULL); #if TRACING_VM - cio_printf( "vm_ptdup dst %08x curr %08x\n", - (uint32_t) dst, (uint32_t) curr ); + cio_printf("vm_pdedup dst %08x curr %08x\n", (uint32_t)dst, (uint32_t)curr); #endif + pde_t entry = *curr; + // simplest case - if( *curr == 0 ) { + if (!IS_PRESENT(entry)) { *dst = 0; return true; } - // OK, we have an entry; allocate a page table - pte_t *pt = (pte_t *) km_page_alloc(); - if( pt == NULL ) { + // OK, we have an entry; allocate a page table for it + pte_t *newtbl = (pte_t *)km_page_alloc(); + if (newtbl == NULL) { return false; } - // pointer to the first PTE in the current table - pte_t *old = (pte_t *) (((uint32_t) *curr) & FRAME_MASK); + // we could clear the new table, but we'll be assigning to + // each entry anyway, so we'll save the execution time + + // 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 - pte_t *new = pt; + pte_t *new = newtbl; - for( int i = 0 ; i < N_PTE; ++i ) { - if( IS_PRESENT(*old) ) { + for (int i = 0; i < N_PTE; ++i) { + if (!IS_PRESENT(*old)) { *new = 0; } else { *new = *old; @@ -189,12 +242,9 @@ bool_t vm_ptdup( pde_t *dst, pde_t *curr ) { ++new; } - // assign the page table into the new page directory - // upper 22 bits from 'pt', lower 12 from '*curr' - *dst = (pde_t) ( - (((uint32_t)pt) & FRAME_MASK) | - (((uint32_t)(*curr)) & PERM_MASK ) - ); + // replace the page table address + // upper 22 bits from 'newtbl', lower 12 from '*curr' + *dst = (pde_t)(PTE_ADDR(newtbl) | PERMS(entry)); return true; } @@ -211,79 +261,98 @@ bool_t vm_ptdup( pde_t *dst, pde_t *curr ) { ** @param va The virtual address we're looking for ** @param alloc Should we allocate a page table if there isn't one? ** -** @return A pointer to the page table entry for this VA, or NULL +** @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 *ptab; +pte_t *vm_getpte(pde_t *pdir, const void *va, bool_t alloc) +{ + pte_t *ptbl; // sanity check - assert1( pdir != NULL ); + assert1(pdir != NULL); // get the PDIR entry for this virtual address - pde_t *pde = &pdir[ PDIX(va) ]; + uint32_t ix = PDIX(va); + pde_t *pde_ptr = &pdir[ix]; // is it already set up? - if( IS_PRESENT(*pde) ) { - + if (IS_PRESENT(*pde_ptr)) { // yes! - ptab = (pte_t*)P2V(PTE_ADDR(*pde)); + ptbl = (pte_t *)P2V(PTE_ADDR(*pde_ptr)); } else { - // no - should we create it? - if( !alloc ) { + if (!alloc) { // nope, so just return return NULL; } // yes - try to allocate a page table - ptab = (pte_t *) km_page_alloc(); - if( ptab == NULL ) { - WARNING( "can't allocate page table" ); + ptbl = (pte_t *)km_page_alloc(); + if (ptbl == NULL) { + WARNING("can't allocate page table"); return NULL; } // who knows what was left in this page.... - memclr( ptab, SZ_PAGE ); + memclr(ptbl, SZ_PAGE); // add this to the page directory // // we set this up to allow general access; this could be // controlled by setting access control in the page table // entries, if necessary. - *pde = V2P(ptab) | PDE_P | PDE_RW; + // + // 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; } // finally, return a pointer to the entry in the // page table for this VA - return &ptab[ PTIX(va) ]; + ix = PTIX(va); + return &ptbl[ix]; } // 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 TRACING_VM + cio_puts("\nEntering vm_mkkvm\n"); + ptdump(pdir, true); +#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"); + } // 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_end - k->pa_start, - 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_start, + k->pa_end - k->pa_start, k->perm); + if (stat != SUCCESS) { + vm_free(pdir); return 0; } } +#if TRACING_VM + cio_puts("\nvm_mkkvm() final PD:\n"); + ptdump(pdir, true); +#endif return pdir; } @@ -294,22 +363,21 @@ 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 kernel page directory pde_t *curr = kpdir; pde_t *dst = new; - for( int i = 0; i < N_PDE; ++i ) { - - if( *curr != 0 ) { + for (int i = 0; i < N_PDE; ++i) { + if (*curr != 0) { // found an active one - duplicate it - if( !vm_ptdup(dst,curr) ) { + if (!vm_pdedup(dst, curr)) { return NULL; } } @@ -319,7 +387,6 @@ pde_t *vm_mkuvm( void ) { } return new; - } /** @@ -327,8 +394,9 @@ pde_t *vm_mkuvm( void ) { ** ** Switch the page table register to the kernel's page directory. */ -void vm_set_kvm( void ) { - w_cr3( V2P(kpdir) ); // switch to the kernel page table +void vm_set_kvm(void) +{ + w_cr3(V2P(kpdir)); // switch to the kernel page table } /** @@ -338,11 +406,12 @@ void vm_set_kvm( void ) { ** ** @param p PCB of the process we're switching to */ -void vm_set_uvm( pcb_t *p ) { - 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 + w_cr3(V2P(p->pdir)); // switch to process's address space } /** @@ -361,35 +430,34 @@ 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? - uint_t npages = ((size & MOD4K_BITS) ? PGUP(size) : size) >> MOD4K_SHIFT; + uint32_t npages = ((size & MOD4K_BITS) ? PGUP(size) : size) >> MOD4K_SHIFT; // permission set for the PTEs - uint_t entrybase = PTE_P; - if( wr ) { + uint32_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 (%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 ); + 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 ) { + 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? @@ -398,27 +466,27 @@ int vm_add( pde_t *pdir, bool_t wr, bool_t sys, // allocate the frame void *page = km_page_alloc(); - if( page == NULL ) { + 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) (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 - uint_t num = bytes > SZ_PAGE ? SZ_PAGE : bytes; + uint32_t num = bytes > SZ_PAGE ? SZ_PAGE : bytes; // do it! - memcpy( (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 @@ -426,7 +494,6 @@ int vm_add( pde_t *pdir, bool_t wr, bool_t sys, } return SUCCESS; - } /** @@ -435,40 +502,46 @@ int vm_add( pde_t *pdir, bool_t wr, bool_t sys, ** Deallocate a page table hierarchy and all physical memory frames ** in the user portion. ** +** Works only for 4KB pages. +** ** @param pdir Pointer to the page directory */ -void vm_free( pde_t *pdir ) { - +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; - 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(*curr) ) { + if (IS_PRESENT(entry)) { + // yes - large pages make us unhappy + assert(!IS_LARGE(entry)); - // yes - get the PMT pointer - pte_t *pte = (pte_t *) PTE_ADDR(*curr); + // get the PMT pointer + pte_t *pmt = (pte_t *)PTE_ADDR(entry); // walk the PMT - for( int j = 0; j < N_PTE; ++j ) { + for (int j = 0; j < N_PTE; ++j) { // does this entry point to a frame? - if( IS_PRESENT(*pte) ) { + if (IS_PRESENT(*pmt)) { // yes - free the frame - km_page_free( (void *) PTE_ADDR(*pte) ); + km_page_free((void *)PTE_ADDR(*pmt)); // mark it so we don't get surprised - *pte = 0; + *pmt = 0; } // move on - ++pte; + ++pmt; } // now, free the PMT itself - km_page_free( (void *) PDE_ADDR(*curr) ); + km_page_free((void *)PDE_ADDR(entry)); *curr = 0; } @@ -477,7 +550,7 @@ void vm_free( pde_t *pdir ) { } // finally, free the PDIR itself - km_page_free( (void *) pdir ); + km_page_free((void *)pdir); } /* @@ -489,45 +562,67 @@ void vm_free( pde_t *pdir ) { ** ** @param pdir Page directory for this address space ** @param va The starting virtual address -** @param size Length of the range to be mapped ** @param pa The starting physical address +** @param size Length of the range to be mapped ** @param perm Permission bits for the PTEs +** +** @return the status of the mapping attempt */ -int vm_map( pde_t *pdir, void *va, uint_t size, uint_t pa, int perm ) { - pte_t *pte; - +int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm) +{ // round the VA down to its page boundary - char *addr = (char*)PGDOWN((uint_t)va); + char *addr = (char *)PGDOWN((uint32_t)va); // round the end of the range down to its page boundary - char *last = (char*)PGDOWN(((uint_t)va) + size - 1); + char *last = (char *)PGDOWN(((uint32_t)va) + size - 1); - for(;;) { +#if TRACING_VM + // keep this in case we need it + uint32_t startpa = pa; +#endif + while (addr <= last) { // get a pointer to the PTE for the current VA - if( (pte = vm_getpte(pdir, addr, 1)) == 0 ) { + pte_t *pte = vm_getpte(pdir, addr, true); + if (pte == NULL) { // couldn't find it return E_NO_PTE; } // if this entry has already been mapped, we're in trouble - if( IS_PRESENT(*pte) ) { - PANIC( 0, "mapping an already-mapped address" ); + if (IS_PRESENT(*pte)) { +#if TRACING_VM + // get some debugging help + cio_printf( + "\n\nvm_map pdir %08x va %08x pa %08x size %08x perm %03x\n", + (uint32_t)pdir, (uint32_t)va, startpa, size, perm); + cio_printf(" addr %08x pa %08x last %08x pte %08x *pte %08x\n", + (uint32_t)addr, pa, (uint32_t)last, (uint32_t)pte, *pte); + cio_printf(" PDIX 0x%x PTIX 0x%x\n", PDIX(addr), PTIX(addr)); + + // dump the directory + ptdump(pdir, true); + + // find the relevant PDE entry + uint32_t ix = PDIX(va); + pde_t entry = pdir[ix]; + if (!IS_LARGE(entry)) { + // dump the PMT for the relevant directory entry + ptdump((void *)P2V(PDE_ADDR(entry)), false); + } +#endif + + PANIC(0, "mapping an already-mapped address"); } // ok, set the PTE as requested *pte = pa | perm | PTE_P; - // are we done? - if( addr == last ) { - break; - } - // nope - move to the next page addr += SZ_PAGE; pa += SZ_PAGE; } - return 0; + return SUCCESS; } /** @@ -539,7 +634,7 @@ int vm_map( pde_t *pdir, void *va, uint_t size, uint_t pa, int perm ) { ** ** Note: we do not duplicate the frames in the hierarchy - we just ** create a duplicate of the hierarchy itself. This means that we -** now have two sets of page tables that refer to the same user-level +** now have two sets of page tables that refer to the same physical ** frames in memory. ** ** @param old Existing page directory @@ -547,36 +642,44 @@ int vm_map( pde_t *pdir, void *va, uint_t size, uint_t pa, int perm ) { ** ** @return status of the duplication attempt */ -int vm_uvmdup( pde_t *old, pde_t *new ) { - - if( old == NULL || new == NULL ) { +int vm_uvmdup(pde_t *old, pde_t *new) +{ + if (old == NULL || new == NULL) { return E_BAD_PARAM; } // 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(*old) ) { - + if (IS_PRESENT(entry)) { // yes. if it points to a 4MB page, we just copy it; // otherwise, we must duplicate the next level PMT - *new = *old; // copy the entry - - if( !IS_LARGE(*old) ) { - + if (!IS_LARGE(entry)) { // it's a 4KB page, so we need to duplicate the PMT - pte_t *newpmt = (pte_t *) vm_pagedup( (void *) (*old & FRAME_MASK) ); - if( newpmt == 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 # - *new = (pde_t) (((uint32_t)newpmt) | PERMS(*old)); + entry = ((uint32_t)newpt) | perms; } + + } else { + // not present, so create an empty entry + entry = 0; } + // send it on its way + *new = entry; + + // move on down the line ++old; ++new; } diff --git a/kernel/vmtables.c b/kernel/vmtables.c index 306b1f6..42bc1ef 100644 --- a/kernel/vmtables.c +++ b/kernel/vmtables.c @@ -11,7 +11,7 @@ ** 4MB of main memory. */ -#define KERNEL_SRC +#define KERNEL_SRC #include <common.h> @@ -35,80 +35,169 @@ extern char _data[]; ** memory. */ -// identity-map 4MB page #n -#define L(n) [n] = (pde_t) ( (TO_4MFRAME((n))) | (PDE_P|PDE_RW|PDE_PS) ) +// 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)) -ALIGN(SZ_PAGE) -pde_t firstpdir[N_PDE] = { +// 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)) + +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 [KERN_BASE, KERN_BASE+4MB] to PA range [0, 4MB] - [PDIX(KERN_BASE)] = (pde_t) (PDE_P | PDE_RW | PDE_PS) + // 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) }; #ifdef MAKE_IDENTITY_MAP @@ -123,148 +212,167 @@ L(0x1f8), L(0x1f9), L(0x1fa), L(0x1fb), L(0x1fc), L(0x1fd), L(0x1fe), L(0x1ff), */ // 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)) -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) +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) }; -#endif /* MAKE_IDENTITY_MAP */ +#endif /* MAKE_IDENTITY_MAP */ /* ** Kernel address mappings, present in every page table */ -mapping_t kmap[] = { +const mapping_t kmap[] = { // va pa_start pa_end perms - { 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 } + { 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]); |