summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-03-27 11:39:12 -0400
committerFreya Murphy <freya@freyacat.org>2025-03-27 11:39:12 -0400
commit0ff301cda68669c59351e5854ce98f2cf460543f (patch)
treecfe8f976261962420ada64b821559b9da0a56841 /kernel
parentadd compile_flags.txt for clangd lsp (diff)
downloadcomus-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.c809
-rw-r--r--kernel/clock.c59
-rw-r--r--kernel/isrs.S2
-rw-r--r--kernel/kernel.c231
-rw-r--r--kernel/kmem.c346
-rw-r--r--kernel/list.c17
-rw-r--r--kernel/procs.c514
-rw-r--r--kernel/sio.c258
-rw-r--r--kernel/startup.S8
-rw-r--r--kernel/support.c122
-rw-r--r--kernel/syscalls.c402
-rw-r--r--kernel/user.c604
-rw-r--r--kernel/vm.c463
-rw-r--r--kernel/vmtables.c522
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, &current );
- if( status != SUCCESS ) {
- sprint( b256, "dispatch queue remove failed, code %d", status );
- PANIC( 0, b256 );
+ int status = pcb_queue_remove(ready, &current);
+ 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]);