fix old checkout

This commit is contained in:
Murphy 2025-04-08 10:49:18 -04:00
parent 5372fc3bfd
commit c8a1e0531d
Signed by: freya
GPG key ID: 9FBC6FFD6D2DBF17
51 changed files with 4847 additions and 4226 deletions

76
kernel/old/Make.mk Normal file
View file

@ -0,0 +1,76 @@
#
# Makefile fragment for the kernel components of the system.
#
# Makefile fragment for the kernel component of the system.
#
# THIS IS NOT A COMPLETE Makefile - run GNU make in the top-level
# directory, and this will be pulled in automatically.
#
SUBDIRS += kernel
###################
# FILES SECTION #
###################
BOOT_OBJ := $(patsubst %.c, $(BUILDDIR)/%.o, $(BOOT_SRC))
KERN_SRC := kernel/startup.S kernel/isrs.S \
kernel/cio.c kernel/clock.c kernel/kernel.c kernel/kmem.c \
kernel/list.c kernel/procs.c kernel/sio.c kernel/support.c \
kernel/syscalls.c kernel/user.c kernel/vm.c kernel/vmtables.c
KERN_OBJ := $(patsubst %.c, $(BUILDDIR)/%.o, $(KERN_SRC))
KERN_OBJ := $(patsubst %.S, $(BUILDDIR)/%.o, $(KERN_OBJ))
KCFLAGS := -ggdb
KLDFLAGS := -T kernel/kernel.ld
KLIBS := -lkernel -lcommon
###################
# RULES SECTION #
###################
kernel: $(BUILDDIR)/kernel/kernel.b
$(BUILDDIR)/kernel/%.o: kernel/%.c $(BUILDDIR)/.vars.CFLAGS
@mkdir -p $(@D)
$(CC) $(CFLAGS) $(KCFLAGS) -c -o $@ $<
#$(BUILDDIR)/kernel/%.o: kernel/%.S $(BUILDDIR)/.vars.CFLAGS
# @mkdir -p $(@D)
# $(CPP) $(CPPFLAGS) -o $(@D)/$*.s $<
# $(AS) $(ASFLAGS) $(KCFLAGS) -o $@ $(@D)/$*.s -a=$(@D)/$*.lst
# $(RM) -f $(@D)/$*.s
$(BUILDDIR)/kernel/%.o: kernel/%.S $(BUILDDIR)/.vars.CFLAGS
@mkdir -p $(@D)
$(CC) $(CFLAGS) $(KCFLAGS) -c -o $@ $<
$(OBJDUMP) -S $@ > $(@D)/$*.asm
$(BUILDDIR)/kernel/kernel: $(KERN_OBJ)
@mkdir -p $(@D)
$(LD) $(KLDFLAGS) $(LDFLAGS) -o $@ $(KERN_OBJ) $(KLIBS)
$(OBJDUMP) -S $@ > $@.asm
$(NM) -n $@ > $@.sym
$(READELF) -a $@ > $@.info
$(BUILDDIR)/kernel/kernel.b: $(BUILDDIR)/kernel/kernel
$(LD) $(LDFLAGS) -o $(BUILDDIR)/kernel/kernel.b -s \
--oformat binary -Ttext 0x10000 $(BUILDDIR)/kernel/kernel
# some debugging assist rules
$(BUILDDIR)/kernel/%.i: kernel/%.c $(BUILDDIR)/.vars.CFLAGS
@mkdir -p $(@D)
$(CC) $(CFLAGS) $(KCFLAGS) -E -c $< > $(@D)/$*.i
$(BUILDDIR)/kernel/%.dat: $(BUILDDIR)/kernel/%.o
@mkdir -p $(@D)
$(OBJCOPY) -S -O binary -j .data $< $@
hexdump -C $@ > $(@D)/$*.hex
$(BUILDDIR)/kernel/%.rodat: $(BUILDDIR)/kernel/%.o
@mkdir -p $(@D)
$(OBJCOPY) -S -O binary -j .rodata $< $@
hexdump -C $@ > $(@D)/$*.hex

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,11 @@
/**
** @file clock.c
**
** @author CSCI-452 class of 20245
**
** @brief Clock module implementation
*/
#define KERNEL_SRC
#include <common.h>
@ -22,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
@ -44,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)
@ -62,11 +70,14 @@ 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
@ -80,42 +91,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 );
}
/*
@ -128,10 +139,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
@ -143,10 +154,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 );
}

Binary file not shown.

View file

@ -1,73 +0,0 @@
/**
* @file bindings.h
* @author Freya Murphy <freya@freyacat.org>
*
* C-style function definitions binded to their named assembly instruction.
*/
#ifndef _BINDINGS_H
#define _BINDINGS_H
#include <types.h>
static inline uint8_t inb(uint16_t port)
{
uint8_t ret;
__asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
static inline void outb(uint16_t port, uint8_t val)
{
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
}
static inline uint16_t inw(uint16_t port)
{
uint16_t ret;
__asm__ volatile("inw %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
static inline void outw(uint16_t port, uint16_t val)
{
__asm__ volatile("outw %0, %1" : : "a"(val), "Nd"(port));
}
static inline uint32_t inl(uint16_t port)
{
uint32_t ret;
__asm__ volatile("inl %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
static inline void outl(uint16_t port, uint32_t val)
{
__asm__ volatile("outl %0, %1" : : "a"(val), "Nd"(port));
}
static inline void io_wait(void)
{
outb(0x80, 0);
}
static inline void sti(void)
{
__asm__ volatile("sti");
}
static inline void cli(void)
{
__asm__ volatile("cli");
}
static inline void int_wait(void)
{
__asm__ volatile("sti; hlt");
}
static inline void halt(void)
{
__asm__ volatile("cli; hlt");
}
#endif /* bindings.h */

View file

@ -9,89 +9,89 @@
** Addresses where various stuff goes in memory.
*/
#ifndef BOOTSTRAP_H_
#define BOOTSTRAP_H_
#ifndef BOOTSTRAP_H_
#define BOOTSTRAP_H_
/*
** The boot device
*/
#define BDEV_FLOPPY 0x00
#define BDEV_USB 0x80 /* hard drive */
#define BDEV_FLOPPY 0x00
#define BDEV_USB 0x80 /* hard drive */
#define BDEV BDEV_USB /* default */
#define BDEV BDEV_USB /* default */
/*
** Bootstrap definitions
*/
#define BOOT_SEG 0x07c0 /* 07c0:0000 */
#define BOOT_DISP 0x0000
#define BOOT_ADDR ((BOOT_SEG << 4) + BOOT_DISP)
#define BOOT_SEG 0x07c0 /* 07c0:0000 */
#define BOOT_DISP 0x0000
#define BOOT_ADDR ((BOOT_SEG << 4) + BOOT_DISP)
#define PART2_DISP 0x0200 /* 07c0:0200 */
#define PART2_ADDR ((BOOT_SEG << 4) + PART2_DISP)
#define PART2_DISP 0x0200 /* 07c0:0200 */
#define PART2_ADDR ((BOOT_SEG << 4) + PART2_DISP)
#define SECTOR_SIZE 0x200 /* 512 bytes */
#define SECTOR_SIZE 0x200 /* 512 bytes */
/* Note: this assumes the bootstrap is two sectors long! */
#define BOOT_SIZE (SECTOR_SIZE + SECTOR_SIZE)
#define BOOT_SIZE (SECTOR_SIZE + SECTOR_SIZE)
#define OFFSET_LIMIT (0x10000 - SECTOR_SIZE)
#define OFFSET_LIMIT (0x10000 - SECTOR_SIZE)
#define BOOT_SP_DISP 0x4000 /* stack pointer 07c0:4000, or 0xbc00 */
#define BOOT_SP_ADDR ((BOOT_SEG << 4) + BOOT_SP_DISP)
#define BOOT_SP_DISP 0x4000 /* stack pointer 07c0:4000, or 0xbc00 */
#define BOOT_SP_ADDR ((BOOT_SEG << 4) + BOOT_SP_DISP)
#define SECTOR1_END (BOOT_ADDR + SECTOR_SIZE)
#define SECTOR2_END (BOOT_ADDR + BOOT_SIZE)
#define SECTOR1_END (BOOT_ADDR + SECTOR_SIZE)
#define SECTOR2_END (BOOT_ADDR + BOOT_SIZE)
// location of the user blob data
// (three halfwords of data)
#define USER_BLOB_DATA (SECTOR2_END - 12)
#define USER_BLOB_DATA (SECTOR2_END - 12)
/*
** The target program itself
*/
#define TARGET_SEG 0x00001000 /* 1000:0000 */
#define TARGET_ADDR 0x00010000 /* and upward */
#define TARGET_STACK 0x00010000 /* and downward */
#define TARGET_SEG 0x00001000 /* 1000:0000 */
#define TARGET_ADDR 0x00010000 /* and upward */
#define TARGET_STACK 0x00010000 /* and downward */
/*
** The Global Descriptor Table (0000:0500 - 0000:2500)
*/
#define GDT_SEG 0x00000050
#define GDT_ADDR 0x00000500
#define GDT_SEG 0x00000050
#define GDT_ADDR 0x00000500
/* segment register values */
#define GDT_LINEAR 0x0008 /* All of memory, R/W */
#define GDT_CODE 0x0010 /* All of memory, R/E */
#define GDT_DATA 0x0018 /* All of memory, R/W */
#define GDT_STACK 0x0020 /* All of memory, R/W */
/* segment register values */
#define GDT_LINEAR 0x0008 /* All of memory, R/W */
#define GDT_CODE 0x0010 /* All of memory, R/E */
#define GDT_DATA 0x0018 /* All of memory, R/W */
#define GDT_STACK 0x0020 /* All of memory, R/W */
/*
** The Interrupt Descriptor Table (0000:2500 - 0000:2D00)
*/
#define IDT_SEG 0x00000250
#define IDT_ADDR 0x00002500
#define IDT_SEG 0x00000250
#define IDT_ADDR 0x00002500
/*
** Additional I/O ports used by the bootstrap code
*/
// keyboard controller
#define KBD_DATA 0x60
#define KBD_CMD 0x64
#define KBD_STAT 0x64
#define KBD_DATA 0x60
#define KBD_CMD 0x64
#define KBD_STAT 0x64
// status register bits
#define KBD_OBSTAT 0x01
#define KBD_IBSTAT 0x02
#define KBD_SYSFLAG 0x04
#define KBD_CMDDAT 0x08
#define KBD_OBSTAT 0x01
#define KBD_IBSTAT 0x02
#define KBD_SYSFLAG 0x04
#define KBD_CMDDAT 0x08
// commands
#define KBD_P1_DISABLE 0xad
#define KBD_P1_ENABLE 0xae
#define KBD_RD_OPORT 0xd0
#define KBD_WT_OPORT 0xd1
#define KBD_P1_DISABLE 0xad
#define KBD_P1_ENABLE 0xae
#define KBD_RD_OPORT 0xd0
#define KBD_WT_OPORT 0xd1
#ifdef ASM_SRC
@ -104,16 +104,17 @@
// .byte granularity byte
// .byte upper 8 bits of base
// we use 4K units, so we ignore the lower 12 bits of the limit
#define SEGNULL .word 0, 0, 0, 0
#define SEGNULL \
.word 0, 0, 0, 0
#define SEGMENT(base, limit, dpl, type) \
.word(((limit) >> 12) & 0xffff); \
.word((base) & 0xffff); \
.byte(((base) >> 16) & 0xff); \
.byte(SEG_PRESENT | (dpl) | SEG_NON_SYSTEM | (type)); \
.byte(SEG_GRAN_4KBYTE | SEG_DB_32BIT | (((limit) >> 28) & 0xf)); \
.byte(((base) >> 24) & 0xff)
#define SEGMENT(base,limit,dpl,type) \
.word (((limit) >> 12) & 0xffff); \
.word ((base) & 0xffff) ; \
.byte (((base) >> 16) & 0xff) ; \
.byte (SEG_PRESENT | (dpl) | SEG_NON_SYSTEM | (type)) ; \
.byte (SEG_GRAN_4KBYTE | SEG_DB_32BIT | (((limit) >> 28) & 0xf)) ; \
.byte (((base) >> 24) & 0xff)
#endif /* ASM_SRC */
#endif /* ASM_SRC */
#endif

View file

@ -11,7 +11,7 @@
** Declarations and descriptions of console I/O routines
**
** These routines provide a rudimentary capability for printing to
** the screen and reading from the keyboard.
** the screen and reading from the keyboard.
**
** Screen output:
** There are two families of functions. The first provides a window
@ -50,7 +50,7 @@
** Keyboard input:
** Two functions are provided: getting a single character and getting
** a newline-terminated line. A third function returns a count of
** the number of characters available for immediate reading.
** the number of characters available for immediate reading.
** No conversions are provided (yet).
*/
@ -77,7 +77,7 @@
**
** @param notify pointer to an input notification function, or NULL
*/
void cio_init(void (*notify)(int));
void cio_init( void (*notify)(int) );
/*****************************************************************************
**
@ -102,8 +102,8 @@ void cio_init(void (*notify)(int));
** @param min_x,min_y upper-left corner of the region
** @param max_x,max_y lower-right corner of the region
*/
void cio_setscroll(unsigned int min_x, unsigned int min_y, unsigned int max_x,
unsigned int max_y);
void cio_setscroll( unsigned int min_x, unsigned int min_y,
unsigned int max_x, unsigned int max_y );
/**
** cio_moveto
@ -114,7 +114,7 @@ void cio_setscroll(unsigned int min_x, unsigned int min_y, unsigned int max_x,
**
** @param x,y desired coordinate position
*/
void cio_moveto(unsigned int x, unsigned int y);
void cio_moveto( unsigned int x, unsigned int y );
/**
** cio_putchar
@ -123,7 +123,7 @@ void cio_moveto(unsigned int x, unsigned int y);
**
** @param c the character to be printed
*/
void cio_putchar(unsigned int c);
void cio_putchar( unsigned int c );
/**
** cio_puts
@ -133,7 +133,7 @@ void cio_putchar(unsigned int c);
**
** @param str pointer to a NUL-terminated string to be printed
*/
void cio_puts(const char *str);
void cio_puts( const char *str );
/**
** cio_write
@ -143,7 +143,7 @@ void cio_puts(const char *str);
** @param buf the buffer of characters
** @param length the number of characters to print
*/
void cio_write(const char *buf, int length);
void cio_write( const char *buf, int length );
/**
** cio_printf
@ -154,7 +154,7 @@ void cio_write(const char *buf, int length);
** @param fmt a printf-style format control string
** @param ... optional additional values to be printed
*/
void cio_printf(char *fmt, ...);
void cio_printf( char *fmt, ... );
/**
** cio_scroll
@ -165,7 +165,7 @@ void cio_printf(char *fmt, ...);
**
** @param lines the number of lines to scroll
*/
void cio_scroll(unsigned int lines);
void cio_scroll( unsigned int lines );
/**
** cio_clearscroll
@ -173,7 +173,7 @@ void cio_scroll(unsigned int lines);
** Clears the entire scrolling region to blank spaces, and
** moves the cursor to (0,0).
*/
void cio_clearscroll(void);
void cio_clearscroll( void );
/*****************************************************************************
**
@ -196,7 +196,7 @@ void cio_clearscroll(void);
** @param x,y desired coordinate position
** @param c the character to be printed
*/
void cio_putchar_at(unsigned int x, unsigned int y, unsigned int c);
void cio_putchar_at( unsigned int x, unsigned int y, unsigned int c );
/**
** cio_puts_at
@ -207,7 +207,7 @@ void cio_putchar_at(unsigned int x, unsigned int y, unsigned int c);
** @param x,y desired coordinate position
** @param str pointer to a NUL-terminated string to be printed
*/
void cio_puts_at(unsigned int x, unsigned int y, const char *str);
void cio_puts_at( unsigned int x, unsigned int y, const char *str );
/**
** cio_printf_at
@ -219,14 +219,14 @@ void cio_puts_at(unsigned int x, unsigned int y, const char *str);
** @param fmt a printf-style format control string
** @param ... optional additional values to be printed
*/
void cio_printf_at(unsigned int x, unsigned int y, char *fmt, ...);
void cio_printf_at( unsigned int x, unsigned int y, char *fmt, ... );
/**
** cio_clearscreen
**
** This function clears the entire screen, including the scrolling region.
*/
void cio_clearscreen(void);
void cio_clearscreen( void );
/*****************************************************************************
**
@ -251,7 +251,7 @@ void cio_clearscreen(void);
**
** @return the next character from the keyboard input buffer
*/
int cio_getchar(void);
int cio_getchar( void );
/**
** cio_gets
@ -270,7 +270,7 @@ int cio_getchar(void);
**
** @return count of the number of characters read into the buffer
*/
int cio_gets(char *buffer, unsigned int size);
int cio_gets( char *buffer, unsigned int size );
/**
** cio_input_queue
@ -281,7 +281,7 @@ int cio_gets(char *buffer, unsigned int size);
**
** @return number of characters in the input queue
*/
int cio_input_queue(void);
#endif /* !ASM_SRC */
int cio_input_queue( void );
#endif /* !ASM_SRC */
#endif

View file

@ -17,10 +17,10 @@
// conversion functions for seconds, ms, and ticks
// (SEC_TO_MS is defined in defs.h)
#define MS_TO_TICKS(n) ((n))
#define SEC_TO_TICKS(n) (MS_TO_TICKS(SEC_TO_MS(n)))
#define TICKS_TO_SEC(n) ((n) / CLOCK_FREQ)
#define TICKS_TO_SEC_ROUNDED(n) (((n) + (CLOCK_FREQ - 1)) / CLOCK_FREQ)
#define MS_TO_TICKS(n) ((n))
#define SEC_TO_TICKS(n) (MS_TO_TICKS(SEC_TO_MS(n)))
#define TICKS_TO_SEC(n) ((n) / CLOCK_FREQ)
#define TICKS_TO_SEC_ROUNDED(n) (((n)+(CLOCK_FREQ-1)) / CLOCK_FREQ)
#ifndef ASM_SRC
@ -48,8 +48,8 @@ extern uint32_t system_time;
**
** Clock module initialization
*/
void clk_init(void);
void clk_init( void );
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -0,0 +1,31 @@
/**
** @file common.h
**
** @author Warren R. Carithers
**
** @brief Common definitions for the baseline system.
**
** This header file pulls in the standard header information needed
** by all parts of the system. It is purely for our convenience.
*/
#ifndef COMMON_H_
#define COMMON_H_
// everything needs these; they also pull in
// the kernel- or user-level defs and lib headers
#include <types.h>
#include <params.h>
#include <defs.h>
#include <lib.h>
#ifdef KERNEL_SRC
// only kernel code needs these headers
#include <common.h>
#include <cio.h>
#include <debug.h>
#endif /* KERNEL_SRC */
#endif

View file

@ -60,10 +60,10 @@
*/
// type name for the PCB
#define PCBTYPE pcb_t
#define PCBTYPE pcb_t
// type name for our queue
#define QTYPE pcb_queue_t
#define QTYPE pcb_queue_t
/*
** Section 3: interface and behavior
@ -77,13 +77,13 @@
*/
// string functions
#define SLENGTH strlen
#define SLENGTH strlen
// scheduler
#define SCHED schedule
#define SCHED schedule
// dispatcher
#define DISPATCH dispatch
#define DISPATCH dispatch
/*
** blocked queue for reading processes
@ -93,7 +93,7 @@
** Its value should be the name of the globally-visible
** queue to be used.
*/
#define QNAME sioread
#define QNAME sioread
#ifdef QNAME
@ -105,27 +105,26 @@
// invoke the queue creation function
// examples:
//
// #define QCREATE(q) do {
// _que_create( &(q), NULL );
// #define QCREATE(q) do {
// _que_create( &(q), NULL );
// } while(0)
//
// #define QCREATE(q) // do nothing
#define QCREATE(q) // handled elsewhere for us
#define QCREATE(q) // handled elsewhere for us
// check to see if the queue is empty
// examples:
//
// #define QEMPTY(q) queue_is_empty(q)
// #define QEMPTY(q) (quene_length(q) > 0)
#define QEMPTY(q) pcb_queue_empty(q)
#define QEMPTY(q) pcb_queue_empty(q)
// this macro expands into code that removes a value from
// 'q' and places it into 'd'
#define QDEQUE(q, d) \
do { \
assert(pcb_queue_remove((q), (pcb_t **)&(d)) == SUCCESS); \
} while (0)
#define QDEQUE(q,d) do { \
assert(pcb_queue_remove( (q), (pcb_t **) &(d) ) == SUCCESS ); \
} while(0)
#endif /* QNAME */

View file

@ -35,17 +35,11 @@
// currently, these do not use the macro parameter, but could be
// modified to do so; instead, we use the __func__ CPP pseudo-macro
// to get the function name
#define ENTERING(n) \
do { \
cio_puts(" enter " __func__); \
} while (0)
#define EXITING(n) \
do { \
cio_puts(" exit " __func__); \
} while (0)
#define ENTERING(n) do { cio_puts( " enter " __func__ ); } while(0)
#define EXITING(n) do { cio_puts( " exit " __func__ ); } while(0)
#else
#define ENTERING(m) // do nothing
#define EXITING(m) // do nothing
#define ENTERING(m) // do nothing
#define EXITING(m) // do nothing
#endif
/*
@ -54,22 +48,20 @@
// Warning messages to the console
// m: message (condition, etc.)
#define WARNING(m) \
do { \
cio_printf("\n** %s (%s @ %d): ", __func__, __FILE__, __LINE__); \
cio_puts(m); \
cio_putchar('\n'); \
} while (0)
#define WARNING(m) do { \
cio_printf( "\n** %s (%s @ %d): ", __func__, __FILE__, __LINE__ ); \
cio_puts( m ); \
cio_putchar( '\n' ); \
} while(0)
// Panic messages to the console
// n: severity level
// m: message (condition, etc.)
#define PANIC(n, m) \
do { \
sprint(b512, "%s (%s @ %d), %d: %s\n", __func__, __FILE__, __LINE__, \
n, #m); \
kpanic(b512); \
} while (0)
#define PANIC(n,m) do { \
sprint( b512, "%s (%s @ %d), %d: %s\n", \
__func__, __FILE__, __LINE__, n, # m ); \
kpanic( b512 ); \
} while(0)
/*
** Assertions are categorized by the "sanity level" being used in this
@ -84,48 +76,30 @@
#ifndef SANITY
// default sanity check level: check everything!
#define SANITY 9999
#define SANITY 9999
#endif
// Always-active assertions
#define assert(x) \
if (!(x)) { \
PANIC(0, x); \
}
#define assert(x) if( !(x) ) { PANIC(0,x); }
// only provide these macros if the sanity check level is positive
#if SANITY > 0
#define assert1(x) \
if (SANITY >= 1 && !(x)) { \
PANIC(1, x); \
}
#define assert2(x) \
if (SANITY >= 2 && !(x)) { \
PANIC(2, x); \
}
#define assert3(x) \
if (SANITY >= 3 && !(x)) { \
PANIC(3, x); \
}
#define assert4(x) \
if (SANITY >= 4 && !(x)) { \
PANIC(4, x); \
}
#define assert1(x) if( SANITY >= 1 && !(x) ) { PANIC(1,x); }
#define assert2(x) if( SANITY >= 2 && !(x) ) { PANIC(2,x); }
#define assert3(x) if( SANITY >= 3 && !(x) ) { PANIC(3,x); }
#define assert4(x) if( SANITY >= 4 && !(x) ) { PANIC(4,x); }
// arbitrary sanity level
#define assertN(n, x) \
if (SANITY >= (n) && !(x)) { \
PANIC(n, x); \
}
#define assertN(n,x) if( SANITY >= (n) && !(x) ) { PANIC(n,x); }
#else
#define assert1(x) // do nothing
#define assert2(x) // do nothing
#define assert3(x) // do nothing
#define assert4(x) // do nothing
#define assertN(n, x) // do nothing
#define assert1(x) // do nothing
#define assert2(x) // do nothing
#define assert3(x) // do nothing
#define assert4(x) // do nothing
#define assertN(n,x) // do nothing
#endif /* SANITY > 0 */
@ -169,185 +143,182 @@
// 2^0 bit
#ifdef T_PCB
#define TRPCB 0x00000001
#define TRPCB 0x00000001
#else
#define TRPCB 0
#define TRPCB 0
#endif
#ifdef T_VM
#define TRVM 0x00000002
#define TRVM 0x00000002
#else
#define TRVM 0
#define TRVM 0
#endif
#ifdef T_QUE
#define TRQUEUE 0x00000004
#define TRQUEUE 0x00000004
#else
#define TRQUEUE 0
#define TRQUEUE 0
#endif
#ifdef T_SCH
#define TRSCHED 0x00000008
#define TRSCHED 0x00000008
#else
#define TRSCHED 0
#define TRSCHED 0
#endif
// 2^4 bit
#ifdef T_DSP
#define TRDISP 0x00000010
#define TRDISP 0x00000010
#else
#define TRDISP 0
#define TRDISP 0
#endif
#ifdef T_SCALL
#define TRSYSCALLS 0x00000020
#define TRSYSCALLS 0x00000020
#else
#define TRSYSCALLS 0
#define TRSYSCALLS 0
#endif
#ifdef T_SRET
#define TRSYSRETS 0x00000040
#define TRSYSRETS 0x00000040
#else
#define TRSYSRETS 0
#define TRSYSRETS 0
#endif
#ifdef T_EXIT
#define TREXIT 0x00000080
#define TREXIT 0x00000080
#else
#define TREXIT 0
#define TREXIT 0
#endif
// 2^8 bit
#ifdef T_INIT
#define TRINIT 0x00000100
#define TRINIT 0x00000100
#else
#define TRINIT 0
#define TRINIT 0
#endif
#ifdef T_KM
#define TRKMEM 0x00000200
#define TRKMEM 0x00000200
#else
#define TRKMEM 0
#define TRKMEM 0
#endif
#ifdef T_KMFR
#define TRKMEM_F 0x00000400
#define TRKMEM_F 0x00000400
#else
#define TRKMEM_F 0
#define TRKMEM_F 0
#endif
#ifdef T_KMIN
#define TRKMEM_I 0x00000800
#define TRKMEM_I 0x00000800
#else
#define TRKMEM_I 0
#define TRKMEM_I 0
#endif
// 2^12 bit
#ifdef T_FORK
#define TRFORK 0x00001000
#define TRFORK 0x00001000
#else
#define TRFORK 0
#define TRFORK 0
#endif
#ifdef T_EXEC
#define TREXEC 0x00002000
#define TREXEC 0x00002000
#else
#define TREXEC 0
#define TREXEC 0
#endif
#ifdef T_SIO
#define TRSIO_STAT 0x00004000
#define TRSIO_STAT 0x00004000
#else
#define TRSIO_STAT 0
#define TRSIO_STAT 0
#endif
#ifdef T_SIOR
#define TRSIO_RD 0x00008000
#define TRSIO_RD 0x00008000
#else
#define TRSIO_RD 0
#define TRSIO_RD 0
#endif
// 2^16 bit
#ifdef T_SIOW
#define TRSIO_WR 0x00010000
#define TRSIO_WR 0x00010000
#else
#define TRSIO_WR 0
#define TRSIO_WR 0
#endif
#ifdef T_USER
#define TRUSER 0x00020000
#define TRUSER 0x00020000
#else
#define TRUSER 0
#define TRUSER 0
#endif
#ifdef T_ELF
#define TRELF 0x00040000
#define TRELF 0x00040000
#else
#define TRELF 0
#define TRELF 0
#endif
// 13 bits remaining for tracing options
// next available bit: 0x00080000
#define TRACE \
(TRDISP | TREXIT | TRINIT | TRKMEM | TRKMEM_F | TRKMEM_I | TRPCB | \
TRQUEUE | TRSCHED | TREXEC | TRSIO_RD | TRSIO_STAT | TRSIO_WR | TRFORK | \
TRVM | TRSYSCALLS | TRSYSRETS | TRUSER | TRELF)
#define TRACE (TRDISP | TREXIT | TRINIT | TRKMEM | TRKMEM_F | TRKMEM_I | TRPCB | TRQUEUE | TRSCHED | TREXEC | TRSIO_RD | TRSIO_STAT | TRSIO_WR | TRFORK | TRVM | TRSYSCALLS | TRSYSRETS | TRUSER | TRELF)
#if TRACE > 0
// compile-time expressions for testing trace options
// usage: #if TRACING_thing
#define TRACING_PCB ((TRACE & TRPCB) != 0)
#define TRACING_VM ((TRACE & TRVM) != 0)
#define TRACING_QUEUE ((TRACE & TRQUEUE) != 0)
#define TRACING_SCHED ((TRACE & TRSCHED) != 0)
#define TRACING_DISPATCH ((TRACE & TRDISPATCH) != 0)
#define TRACING_SYSCALLS ((TRACE & TRSYSCALLS) != 0)
#define TRACING_SYSRETS ((TRACE & TRSYSRETS) != 0)
#define TRACING_EXIT ((TRACE & TREXIT) != 0)
#define TRACING_INIT ((TRACE & TRINIT) != 0)
#define TRACING_KMEM ((TRACE & TRKMEM) != 0)
#define TRACING_KMEM_FREELIST ((TRACE & TRKMEM_F) != 0)
#define TRACING_KMEM_INIT ((TRACE & TRKMEM_I) != 0)
#define TRACING_FORK ((TRACE & TRFORK) != 0)
#define TRACING_EXEC ((TRACE & TREXEC) != 0)
#define TRACING_SIO_STAT ((TRACE & TRSIO_STAT) != 0)
#define TRACING_SIO_ISR ((TRACE & TRSIO_ISR) != 0)
#define TRACING_SIO_RD ((TRACE & TRSIO_RD) != 0)
#define TRACING_SIO_WR ((TRACE & TRSIO_WR) != 0)
#define TRACING_USER ((TRACE & TRUSER) != 0)
#define TRACING_ELF ((TRACE & TRELF) != 0)
#define TRACING_PCB ((TRACE & TRPCB) != 0)
#define TRACING_VM ((TRACE & TRVM) != 0)
#define TRACING_QUEUE ((TRACE & TRQUEUE) != 0)
#define TRACING_SCHED ((TRACE & TRSCHED) != 0)
#define TRACING_DISPATCH ((TRACE & TRDISPATCH) != 0)
#define TRACING_SYSCALLS ((TRACE & TRSYSCALLS) != 0)
#define TRACING_SYSRETS ((TRACE & TRSYSRETS) != 0)
#define TRACING_EXIT ((TRACE & TREXIT) != 0)
#define TRACING_INIT ((TRACE & TRINIT) != 0)
#define TRACING_KMEM ((TRACE & TRKMEM) != 0)
#define TRACING_KMEM_FREELIST ((TRACE & TRKMEM_F) != 0)
#define TRACING_KMEM_INIT ((TRACE & TRKMEM_I) != 0)
#define TRACING_FORK ((TRACE & TRFORK) != 0)
#define TRACING_EXEC ((TRACE & TREXEC) != 0)
#define TRACING_SIO_STAT ((TRACE & TRSIO_STAT) != 0)
#define TRACING_SIO_ISR ((TRACE & TRSIO_ISR) != 0)
#define TRACING_SIO_RD ((TRACE & TRSIO_RD) != 0)
#define TRACING_SIO_WR ((TRACE & TRSIO_WR) != 0)
#define TRACING_USER ((TRACE & TRUSER) != 0)
#define TRACING_ELF ((TRACE & TRELF) != 0)
// more generic tests
#define TRACING_SOMETHING (TRACE != 0)
#define TRACING_SOMETHING (TRACE != 0)
#else
// TRACE == 0, so just define these all as "false"
#define TRACING_PCB 0
#define TRACING_STACK 0
#define TRACING_QUEUE 0
#define TRACING_SCHED 0
#define TRACING_DISPATCH 0
#define TRACING_SYSCALLS 0
#define TRACING_SYSRET 0
#define TRACING_EXIT 0
#define TRACING_INIT 0
#define TRACING_KMEM 0
#define TRACING_KMEM_FREELIST 0
#define TRACING_KMEM_INIT 0
#define TRACING_FORK 0
#define TRACING_EXEC 0
#define TRACING_SI_STAT 0
#define TRACING_SIO_ISR 0
#define TRACING_SIO_RD 0
#define TRACING_SIO_WR 0
#define TRACING_USER 0
#define TRACING_ELF 0
#define TRACING_PCB 0
#define TRACING_STACK 0
#define TRACING_QUEUE 0
#define TRACING_SCHED 0
#define TRACING_DISPATCH 0
#define TRACING_SYSCALLS 0
#define TRACING_SYSRET 0
#define TRACING_EXIT 0
#define TRACING_INIT 0
#define TRACING_KMEM 0
#define TRACING_KMEM_FREELIST 0
#define TRACING_KMEM_INIT 0
#define TRACING_FORK 0
#define TRACING_EXEC 0
#define TRACING_SI_STAT 0
#define TRACING_SIO_ISR 0
#define TRACING_SIO_RD 0
#define TRACING_SIO_WR 0
#define TRACING_USER 0
#define TRACING_ELF 0
#define TRACING_SOMETHING 0
#define TRACING_SOMETHING 0
#endif /* TRACE */

View file

@ -29,21 +29,24 @@
// we define this the traditional way so that
// it's usable from both C and assembly
#define NULL 0
#define NULL 0
// predefined i/o channels
#define CHAN_CIO 0
#define CHAN_SIO 1
#define CHAN_CIO 0
#define CHAN_SIO 1
// maximum allowable number of command-line arguments
#define MAX_ARGS 10
// sizes of various things
#define NUM_1KB 0x00000400 // 2^10
#define NUM_4KB 0x00001000 // 2^12
#define NUM_1MB 0x00100000 // 2^20
#define NUM_4MB 0x00400000 // 2^22
#define NUM_1GB 0x40000000 // 2^30
#define NUM_2GB 0x80000000 // 2^31
#define NUM_3GB 0xc0000000 // 1GB + 2GB
#define NUM_1KB 0x00000400 // 2^10
#define NUM_4KB 0x00001000 // 2^12
#define NUM_1MB 0x00100000 // 2^20
#define NUM_4MB 0x00400000 // 2^22
#define NUM_1GB 0x40000000 // 2^30
#define NUM_2GB 0x80000000 // 2^31
#define NUM_3GB 0xc0000000
#ifndef ASM_SRC
@ -60,63 +63,59 @@
** These can be returned to both system functions
** and to user system calls.
*/
// success!
#define SUCCESS (0)
#define E_SUCCESS SUCCESS
// generic "something went wrong"
#define E_FAILURE (-1)
// specific failure reasons
#define E_BAD_PARAM (-2)
#define E_BAD_CHAN (-3)
#define E_NO_CHILDREN (-4)
#define E_NO_MEMORY (-5)
#define E_NOT_FOUND (-6)
#define E_NO_PROCS (-7)
// success!
#define SUCCESS (0)
# define E_SUCCESS SUCCESS
// generic "something went wrong"
#define E_FAILURE (-1)
// specific failure reasons
#define E_BAD_PARAM (-2)
#define E_BAD_CHAN (-3)
#define E_NO_CHILDREN (-4)
#define E_NO_MEMORY (-5)
#define E_NOT_FOUND (-6)
#define E_NO_PROCS (-7)
/*
** These error codes are internal to the OS.
*/
#define E_EMPTY_QUEUE (-100)
#define E_NO_PCBS (-101)
#define E_NO_PTE (-102)
#define E_LOAD_LIMIT (-103)
#define E_EMPTY_QUEUE (-100)
#define E_NO_PCBS (-101)
#define E_NO_PTE (-102)
#define E_LOAD_LIMIT (-103)
// exit status values
#define EXIT_SUCCESS (0)
#define EXIT_FAILURE (-1)
#define EXIT_KILLED (-101)
#define EXIT_BAD_SYSCALL (-102)
#define EXIT_SUCCESS (0)
#define EXIT_FAILURE (-1)
#define EXIT_KILLED (-101)
#define EXIT_BAD_SYSCALL (-102)
/*
** Process priority values
*/
enum priority_e {
PRIO_HIGH,
PRIO_STD,
PRIO_LOW,
PRIO_DEFERRED
PRIO_HIGH, PRIO_STD, PRIO_LOW, PRIO_DEFERRED
// sentinel
,
N_PRIOS
, N_PRIOS
};
// halves of various data sizes
#define UI16_UPPER 0xff00
#define UI16_LOWER 0x00ff
#define UI16_UPPER 0xff00
#define UI16_LOWER 0x00ff
#define UI32_UPPER 0xffff0000
#define UI32_LOWER 0x0000ffff
#define UI32_UPPER 0xffff0000
#define UI32_LOWER 0x0000ffff
#define UI64_UPPER 0xffffffff00000000LL
#define UI64_LOWER 0x00000000ffffffffLL
#define UI64_UPPER 0xffffffff00000000LL
#define UI64_LOWER 0x00000000ffffffffLL
// Simple conversion pseudo-functions usable by everyone
// convert seconds to ms
#define SEC_TO_MS(n) ((n) * 1000)
#define SEC_TO_MS(n) ((n) * 1000)
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
/*
** Level-specific definitions
@ -125,6 +124,6 @@ enum priority_e {
#include <kdefs.h>
#else
#include <udefs.h>
#endif /* KERNEL_SRC */
#endif /* KERNEL_SRC */
#endif

235
kernel/old/include/elf.h Normal file
View file

@ -0,0 +1,235 @@
/**
** @file elf.h
**
** @author Warren R. Carithers
**
** @brief ELF format declarations
*/
#ifndef ELF_H_
#define ELF_H_
#include <common.h>
#ifndef ASM_SRC
/*
** Start of C-only definitions
*/
// ELF data types (TIS ELF Spec v1.2, May 1995
typedef uint32_t e32_a; // 32-bit unsigned address
typedef uint16_t e32_h; // 16-bit unsigned "medium" integer
typedef uint32_t e32_o; // 32-bit unsigned offset
typedef int32_t e32_sw; // 32-bit signed "large" integer
typedef uint32_t e32_w; // 32-bit unsigned "large" integer
typedef uint8_t e32_si; // 8-bit unsigned "small" integer
// ELF magic number - first four bytes
#define ELF_MAGIC 0x464C457FU // "\x7FELF" in little-endian order
#define EI_NIDENT 16
union elfident_u {
uint8_t bytes[EI_NIDENT]; // array of 16 bytes
struct {
uint32_t magic; // magic number
uint8_t class; // file class
uint8_t data; // data encoding
uint8_t version; // file version
uint8_t osabi; // OS ABI identification
uint8_t abivers; // ABI version
uint8_t pad[7]; // padding to 16 bytes
} f;
};
// indices for byte fields in the ident array
#define EI_MAGIC 0
# define EI_MAG0 EI_MAGIC
# define EI_MAG1 1
# define EI_MAG2 2
# define EI_MAG3 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
#define EI_OSABI 7
#define EI_ABIVERSION 8
// ELF classes
#define ELF_CLASS_NONE 0
#define ELF_CLASS_32 1 // 32-bit objects
#define ELF_CLASS_64 2 // 64-bit objects
// ELF data encoding
#define ELF_DATA_NONE 0 // invalid data encoding
#define ELF_DATA_2LSB 1 // two's complement little-endian
#define ELF_DATA_2MSB 2 // two's complement big-endian
// ELF versions
#define ELF_VERSION__NONE 0 // invalid version
# define EV_NONE ELF_VERSION_NONE
#define ELF_VERSION__CURRENT 1 // current version
# define EV_CURRENT ELF_VERSION_CURRENT
// ELF header
//
// field names are from the TIS ELF Spec v1.2, May 1995
typedef struct elfhdr_s {
union elfident_u e_ident; // file identification
e32_h e_type; // file type
e32_h e_machine; // required architecture
e32_w e_version; // object file version
e32_a e_entry; // entry point (VA)
e32_o e_phoff; // offset to program header table (PHT)
e32_o e_shoff; // offset to section header table (SHT)
e32_w e_flags; // processor-specific flags
e32_h e_ehsize; // ELF header size (bytes)
e32_h e_phentsize; // size of one PHT entry (bytes)
e32_h e_phnum; // number of PHT entries
e32_h e_shentsize; // size of one SHT entry (bytes)
e32_h e_shnum; // number of SHT entries
e32_h e_shstrndx; // SHT index of the sect. name string table
} elfhdr_t;
#define SZ_ELFHDR sizeof(elfhdr_t)
// field values
// e_type
#define ET_NONE 0 // no file type
#define ET_REL 1 // relocatable file
#define ET_EXEC 2 // executable file
#define ET_DYN 3 // shared object file
#define ET_CORE 4 // core file
#define ET_LO_OS 0xfe00 // processor-specific
#define ET_HI_OS 0xfeff // processor-specific
#define ET_LO_CP 0xff00 // processor-specific
#define ET_HI_CP 0xffff // processor-specific
// e_machine
#define EM_NONE 0x00 // no machine type
#define EM_M32 0x01 // AT&T WE 32100
#define EM_SPARC 0x02 // SUN SPARC
#define EM_386 0x03 // Intel Architecture
#define EM_68K 0x04 // Motorola 68000
#define EM_88K 0x05 // Motorola 88000
#define EM_IAMCU 0x06 // Intel MCU
#define EM_860 0x07 // Intel 80860
#define EM_MIPS 0x08 // MIPS RS3000 Big-Endian
#define EM_S370 0x09 // IBM System/370
#define EM_MIPS_RS3_LE 0x0a // MIPS RS3000 Big-Endian
#define EM_SPARC32PLLUS 0x12 // Sun "v8plus"
#define EM_PPC 0x14 // IBM PowerPC
#define EM_PPC64 0x15 // IBM PowerPC 64-bit
#define EM_S390 0x16 // IBM System/390
#define EM_ARM 0x28 // ARM up to V7/AArch32
#define EM_SPARCV9 0x2b // SPARC V9 64-bit
#define EM_IA_64 0x32 // Intel Itanium (Merced)
#define EM_MIPS_X 0x32 // Stanford MIPS-X
#define EM_X86_64 0x3E // AMD x86-64 (Intel64)
#define EM_PDP11 0x40 // DEC PDP-11
#define EM_VAX 0x4b // DEC VAX
#define EM_AARCH64 0xb7 // ARM AArch64
#define EM_Z80 0xec // Zilog Z-80
#define EM_AMDGPU 0xf0 // AMD GPU
#define EM_RISCV 0xf3 // RISC-V
#define EM_BPF 0xf7 // Berkeley Packet Filter
// ELF section header
//
// field names are from the TIS ELF Spec v1.2, May 1995
typedef struct shdr_s {
e32_w sh_name; // section name (index into string table)
e32_w sh_type; // section contents/semantics
e32_w sh_flags; // attribute flag bits
e32_a sh_addr; // 0, or load point of this section in memory
e32_o sh_offset; // byte offset within the file
e32_w sh_size; // section size in bytes
e32_w sh_link; // section header index table link
e32_w sh_info; // "extra information"
e32_w sh_addralign; // required alignment
e32_w sh_entsize; // 0, or size of each entry in the section
} elfsecthdr_t;
#define SZ_ELFSECTHDR sizeof(elfsecthdr_t)
// sh_name
#define SHN_UNDEF 0
// sh_type
#define SHT_NULL 0x00
#define SHT_PROGBITS 0x01
#define SHT_SYMTAB 0x02
#define SHT_STRTAB 0x03
#define SHT_RELA 0x04
#define SHT_HASH 0x05
#define SHT_DYNAMIC 0x06
#define SHT_NOTE 0x07
#define SHT_NOBITS 0x08
#define SHT_REL 0x09
#define SHT_SHLIB 0x0a
#define SHT_DYNSYM 0x0b
#define SHT_LO_CP 0x70000000
#define SHT_HI_CP 0x7fffffff
#define SHT_LO_US 0x80000000
#define SHT_HI_US 0x8fffffff
// sh_flags
#define SHF_WRITE 0x001
#define SHF_ALLOC 0x002
#define SHF_EXECINSTR 0x004
#define SHF_MERGE 0x010
#define SHF_STRINGS 0x020
#define SHF_INFO_LINK 0x040
#define SHF_LINK_ORDER 0x080
#define SHF_OS_NONCON 0x100
#define SHF_GROUP 0x200
#define SHF_TLS 0x400
#define SHF_MASKOS 0x0ff00000
#define SHF_MASKPROC 0xf0000000
// ELF program header
//
// field names are from the TIS ELF Spec v1.2, May 1995
typedef struct phdr_s {
e32_w p_type; // type of segment
e32_o p_offset; // byte offset in file
e32_a p_va; // load point in memory (virtual address)
e32_a p_pa; // load point in memory (physical address)
e32_w p_filesz; // number of bytes in this file
e32_w p_memsz; // number of bytes in memory
e32_w p_flags; // attribute flag bits
e32_w p_align; // required alignment
} elfproghdr_t;
#define SZ_ELFPROGHDR sizeof(elfproghdr_t)
// p_type
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_TLS 7
#define PT_LO_OS 0x70000000
#define PT_HI_OS 0x7fffffff
#define PT_LO_CP 0x70000000
#define PT_HI_CP 0x7fffffff
// p_flags
#define PF_E 0x1
#define PF_W 0x2
#define PF_R 0x4
#define PF_MASKPROC 0xf0000000
/*
** Globals
*/
/*
** Prototypes
*/
#endif /* !ASM_SRC */
#endif

View file

@ -17,58 +17,53 @@
*/
// page sizes
#define SZ_PAGE NUM_4KB
#define SZ_BIGPAGE NUM_4MB
#define SZ_PAGE NUM_4KB
#define SZ_BIGPAGE NUM_4MB
// kernel stack size (bytes)
#define N_KSTKPAGES 1
#define SZ_KSTACK (N_KSTKPAGES * SZ_PAGE)
#define N_KSTKPAGES 1
#define SZ_KSTACK (N_KSTKPAGES * SZ_PAGE)
// user stack size
#define N_USTKPAGES 2
#define SZ_USTACK (N_USTKPAGES * SZ_PAGE)
#define N_USTKPAGES 2
#define SZ_USTACK (N_USTKPAGES * SZ_PAGE)
// declarations for modulus checking of (e.g.) sizes and addresses
#define LOW_9_BITS 0x00000fff
#define LOW_22_BITS 0x003fffff
#define HIGH_20_BITS 0xfffff000
#define HIGH_10_BITS 0xffc00000
#define MOD4_BITS 0x00000003
#define MOD4_MASK 0xfffffffc
#define MOD4_INC 0x00000004
#define MOD4_SHIFT 2
#define MOD4_BITS 0x00000003
#define MOD4_MASK 0xfffffffc
#define MOD4_INC 0x00000004
#define MOD4_SHIFT 2
#define MOD16_BITS 0x0000000f
#define MOD16_MASK 0xfffffff0
#define MOD16_INC 0x00000010
#define MOD16_SHIFT 4
#define MOD16_BITS 0x0000000f
#define MOD16_MASK 0xfffffff0
#define MOD16_INC 0x00000010
#define MOD16_SHIFT 4
#define MOD1K_BITS 0x000003ff
#define MOD1K_MASK 0xfffffc00
#define MOD1K_INC 0x00000400
#define MOD1K_SHIFT 10
#define MOD1K_BITS 0x000003ff
#define MOD1K_MASK 0xfffffc00
#define MOD1K_INC 0x00000400
#define MOD1K_SHIFT 10
#define MOD4K_BITS 0x00000fff
#define MOD4K_MASK 0xfffff000
#define MOD4K_INC 0x00001000
#define MOD4K_SHIFT 12
#define MOD4K_BITS 0x00000fff
#define MOD4K_MASK 0xfffff000
#define MOD4K_INC 0x00001000
#define MOD4K_SHIFT 12
#define MOD1M_BITS 0x000fffff
#define MOD1M_MASK 0xfff00000
#define MOD1M_INC 0x00100000
#define MOD1M_SHIFT 20
#define MOD1M_BITS 0x000fffff
#define MOD1M_MASK 0xfff00000
#define MOD1M_INC 0x00100000
#define MOD1M_SHIFT 20
#define MOD4M_BITS 0x003fffff
#define MOD4M_MASK 0xffc00000
#define MOD4M_INC 0x00400000
#define MOD4M_SHIFT 22
#define MOD4M_BITS 0x003fffff
#define MOD4M_MASK 0xffc00000
#define MOD4M_INC 0x00400000
#define MOD4M_SHIFT 22
#define MOD1G_BITS 0x3fffffff
#define MOD1G_MASK 0xc0000000
#define MOD1G_INC 0x40000000
#define MOD1G_SHIFT 30
#define MOD1G_BITS 0x3fffffff
#define MOD1G_MASK 0xc0000000
#define MOD1G_INC 0x40000000
#define MOD1G_SHIFT 30
#ifndef ASM_SRC
@ -77,26 +72,26 @@
*/
// unit conversion macros
#define B_TO_KB(x) (((uint_t)(x)) >> 10)
#define B_TO_MB(x) (((uint_t)(x)) >> 20)
#define B_TO_GB(x) (((uint_t)(x)) >> 30)
#define B_TO_KB(x) (((uint_t)(x))>>10)
#define B_TO_MB(x) (((uint_t)(x))>>20)
#define B_TO_GB(x) (((uint_t)(x))>>30)
#define KB_TO_B(x) (((uint_t)(x)) << 10)
#define KB_TO_MB(x) (((uint_t)(x)) >> 10)
#define KB_TO_GB(x) (((uint_t)(x)) >> 20)
#define KB_TO_B(x) (((uint_t)(x))<<10)
#define KB_TO_MB(x) (((uint_t)(x))>>10)
#define KB_TO_GB(x) (((uint_t)(x))>>20)
#define MB_TO_B(x) (((uint_t)(x)) << 20)
#define MB_TO_KB(x) (((uint_t)(x)) << 10)
#define MB_TO_GB(x) (((uint_t)(x)) >> 10)
#define MB_TO_B(x) (((uint_t)(x))<<20)
#define MB_TO_KB(x) (((uint_t)(x))<<10)
#define MB_TO_GB(x) (((uint_t)(x))>>10)
#define GB_TO_B(x) (((uint_t)(x)) << 30)
#define GB_TO_KB(x) (((uint_t)(x)) << 20)
#define GB_TO_MB(x) (((uint_t)(x)) << 10)
#define GB_TO_B(x) (((uint_t)(x))<<30)
#define GB_TO_KB(x) (((uint_t)(x))<<20)
#define GB_TO_MB(x) (((uint_t)(x))<<10)
// potetially useful compiler attributes
#define ATTR_ALIGNED(x) __attribute__((__aligned__(x)))
#define ATTR_PACKED __attribute__((__packed__))
#define ATTR_UNUSED __attribute__((__unused__))
#define ATTR_PACKED __attribute__((__packed__))
#define ATTR_UNUSED __attribute__((__unused__))
/*
** Utility macros
@ -107,18 +102,18 @@
//
// these are usable for clearing single-valued data items (e.g.,
// a PCB, etc.)
#define CLEAR(v) memclr(&v, sizeof(v))
#define CLEAR_PTR(p) memclr(p, sizeof(*p))
#define CLEAR(v) memclr( &v, sizeof(v) )
#define CLEAR_PTR(p) memclr( p, sizeof(*p) )
//
// macros for access registers and system call arguments
//
// REG(pcb,x) -- access a specific register in a process context
#define REG(pcb, x) ((pcb)->context->x)
#define REG(pcb,x) ((pcb)->context->x)
// RET(pcb) -- access return value register in a process context
#define RET(pcb) ((pcb)->context->eax)
#define RET(pcb) ((pcb)->context->eax)
// ARG(pcb,n) -- access argument #n from the indicated process
//
@ -129,7 +124,7 @@
//
// ASSUMES THE STANDARD 32-BIT ABI, WITH PARAMETERS PUSHED ONTO THE
// STACK. IF THE PARAMETER PASSING MECHANISM CHANGES, SO MUST THIS!
#define ARG(pcb, n) (((uint32_t *)(((pcb)->context) + 1))[(n)])
#define ARG(pcb,n) ( ( (uint32_t *) (((pcb)->context) + 1) ) [(n)] )
/*
** Types
@ -152,6 +147,6 @@ extern uint8_t kstack[SZ_KSTACK];
** Prototypes
*/
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -24,7 +24,7 @@
**
** @param ch The character to be printed
*/
void put_char_or_code(int ch);
void put_char_or_code( int ch );
/**
** Name: backtrace
@ -35,7 +35,7 @@ void put_char_or_code(int ch);
** @param ebp Initial EBP to use
** @param args Number of function argument values to print
*/
void backtrace(uint32_t *ebp, uint_t args);
void backtrace( uint32_t *ebp, uint_t args );
/**
** Name: kpanic
@ -50,8 +50,8 @@ void backtrace(uint32_t *ebp, uint_t args);
** @param msg[in] String containing a relevant message to be printed,
** or NULL
*/
void kpanic(const char *msg);
void kpanic( const char *msg );
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -28,8 +28,8 @@
// Slab and slice sizes, in bytes
#define SZ_SLAB SZ_PAGE
#define SZ_SLICE (SZ_SLAB >> 2)
#define SZ_SLAB SZ_PAGE
#define SZ_SLICE (SZ_SLAB >> 2)
// memory limits
//
@ -37,8 +37,8 @@
// module will manage
//
// we won't map any memory below 1MB or above 1GB
#define KM_LOW_CUTOFF NUM_1MB
#define KM_HIGH_CUTOFF NUM_1GB
#define KM_LOW_CUTOFF NUM_1MB
#define KM_HIGH_CUTOFF NUM_1GB
#ifndef ASM_SRC
@ -68,7 +68,7 @@
** Must be called before any other init routine that uses
** dynamic storage is called.
*/
void km_init(void);
void km_init( void );
/**
** Name: km_dump
@ -81,7 +81,7 @@ void km_init(void);
** @param addrs Also dump page addresses
** @param both Also dump slice addresses
*/
void km_dump(bool_t addrs, bool_t both);
void km_dump( bool_t addrs, bool_t both );
/*
** Functions that manipulate free memory blocks.
@ -95,7 +95,7 @@ void km_dump(bool_t addrs, bool_t both);
** @return a pointer to the beginning of the allocated page,
** or NULL if no memory is available
*/
void *km_page_alloc(void);
void *km_page_alloc( void );
/**
** Name: km_page_free
@ -108,7 +108,7 @@ void *km_page_alloc(void);
**
** @param[in] block Pointer to the page to be returned to the free list
*/
void km_page_free(void *block);
void km_page_free( void *block );
/**
** Name: km_slice_alloc
@ -119,7 +119,7 @@ void km_page_free(void *block);
**
** @return a pointer to the allocated slice
*/
void *km_slice_alloc(void);
void *km_slice_alloc( void );
/**
** Name: km_slice_free
@ -131,7 +131,7 @@ void *km_slice_alloc(void);
**
** @param[in] block Pointer to the slice (1/4 page) to be freed
*/
void km_slice_free(void *block);
void km_slice_free( void *block );
#endif /* !ASM_SRC */

314
kernel/old/include/lib.h Normal file
View file

@ -0,0 +1,314 @@
/**
** @file lib.h
**
** @author Numerous CSCI-452 classes
**
** @brief C declarations of common library functions
**
** These are callable from either kernel or user code. Care should be taken
** that user code is linked against these separately from kernel code, to
** ensure separation of the address spaces.
*/
#ifndef LIB_H_
#define LIB_H_
#ifndef ASM_SRC
#include <common.h>
/*
**********************************************
** MEMORY MANIPULATION FUNCTIONS
**********************************************
*/
/**
** blkmov(dst,src,len)
**
** Copy a word-aligned block from src to dst. Deals with overlapping
** buffers.
**
** If the buffer addresses aren't word-aligned or the length is not a
** multiple of four, calls memmove().
**
** @param dst Destination buffer
** @param src Source buffer
** @param len Buffer size (in bytes)
*/
void blkmov( void *dst, const void *src, register uint32_t len );
/**
** memset(buf,len,value)
**
** initialize all bytes of a block of memory to a specific value
**
** @param buf The buffer to initialize
** @param len Buffer size (in bytes)
** @param value Initialization value
*/
void memset( void *buf, register uint32_t len, register uint32_t value );
/**
** memclr(buf,len)
**
** Initialize all bytes of a block of memory to zero
**
** @param buf The buffer to initialize
** @param len Buffer size (in bytes)
*/
void memclr( void *buf, register uint32_t len );
/**
** memcpy(dst,src,len)
**
** Copy a block from one place to another
**
** May not correctly deal with overlapping buffers
**
** @param dst Destination buffer
** @param src Source buffer
** @param len Buffer size (in bytes)
*/
void memcpy( void *dst, register const void *src, register uint32_t len );
/**
** memmove(dst,src,len)
**
** Copy a block from one place to another. Deals with overlapping
** buffers
**
** @param dst Destination buffer
** @param src Source buffer
** @param len Buffer size (in bytes)
*/
void memmove( void *dst, register const void *src, register uint32_t len );
/*
**********************************************
** STRING MANIPULATION FUNCTIONS
**********************************************
*/
/**
** str2int(str,base) - convert a string to a number in the specified base
**
** @param str The string to examine
** @param base The radix to use in the conversion
**
** @return The converted integer
*/
int str2int( register const char *str, register int base );
/**
** strlen(str) - return length of a NUL-terminated string
**
** @param str The string to examine
**
** @return The length of the string, or 0
*/
uint32_t strlen( register const char *str );
/**
** strcmp(s1,s2) - compare two NUL-terminated strings
**
** @param s1 The first source string
** @param s2 The second source string
**
** @return negative if s1 < s2, zero if equal, and positive if s1 > s2
*/
int strcmp( register const char *s1, register const char *s2 );
/**
** strcpy(dst,src) - copy a NUL-terminated string
**
** @param dst The destination buffer
** @param src The source buffer
**
** @return The dst parameter
**
** NOTE: assumes dst is large enough to hold the copied string
*/
char *strcpy( register char *dst, register const char *src );
/**
** strcat(dst,src) - append one string to another
**
** @param dst The destination buffer
** @param src The source buffer
**
** @return The dst parameter
**
** NOTE: assumes dst is large enough to hold the resulting string
*/
char *strcat( register char *dst, register const char *src );
/**
** pad(dst,extra,padchar) - generate a padding string
**
** @param dst Pointer to where the padding should begin
** @param extra How many padding bytes to add
** @param padchar What character to pad with
**
** @return Pointer to the first byte after the padding
**
** NOTE: does NOT NUL-terminate the buffer
*/
char *pad( char *dst, int extra, int padchar );
/**
** padstr(dst,str,len,width,leftadjust,padchar - add padding characters
** to a string
**
** @param dst The destination buffer
** @param str The string to be padded
** @param len The string length, or -1
** @param width The desired final length of the string
** @param leftadjust Should the string be left-justified?
** @param padchar What character to pad with
**
** @return Pointer to the first byte after the padded string
**
** NOTE: does NOT NUL-terminate the buffer
*/
char *padstr( char *dst, char *str, int len, int width,
int leftadjust, int padchar );
/**
** sprint(dst,fmt,...) - formatted output into a string buffer
**
** @param dst The string buffer
** @param fmt Format string
**
** The format string parameter is followed by zero or more additional
** parameters which are interpreted according to the format string.
**
** NOTE: assumes the buffer is large enough to hold the result string
**
** NOTE: relies heavily on the x86 parameter passing convention
** (parameters are pushed onto the stack in reverse order as
** 32-bit values).
*/
void sprint( char *dst, char *fmt, ... );
/*
**********************************************
** CONVERSION FUNCTIONS
**********************************************
*/
/**
** cvtuns0(buf,value) - local support routine for cvtuns()
**
** Convert a 32-bit unsigned value into a NUL-terminated character string
**
** @param buf Result buffer
** @param value Value to be converted
**
** @return Pointer to the first unused byte in the buffer
**
** NOTE: assumes buf is large enough to hold the resulting string
*/
char *cvtuns0( char *buf, uint32_t value );
/**
** cvtuns(buf,value)
**
** Convert a 32-bit unsigned value into a NUL-terminated character string
**
** @param buf Result buffer
** @param value Value to be converted
**
** @return Length of the resulting buffer
**
** NOTE: assumes buf is large enough to hold the resulting string
*/
int cvtuns( char *buf, uint32_t value );
/**
** cvtdec0(buf,value) - local support routine for cvtdec()
**
** convert a 32-bit unsigned integer into a NUL-terminated character string
**
** @param buf Destination buffer
** @param value Value to convert
**
** @return The number of characters placed into the buffer
** (not including the NUL)
**
** NOTE: assumes buf is large enough to hold the resulting string
*/
char *cvtdec0( char *buf, int value );
/**
** cvtdec(buf,value)
**
** convert a 32-bit signed value into a NUL-terminated character string
**
** @param buf Destination buffer
** @param value Value to convert
**
** @return The number of characters placed into the buffer
** (not including the NUL)
**
** NOTE: assumes buf is large enough to hold the resulting string
*/
int cvtdec( char *buf, int32_t value );
/**
** cvthex(buf,value)
**
** convert a 32-bit unsigned value into a mininal-length (up to
** 8-character) NUL-terminated character string
**
** @param buf Destination buffer
** @param value Value to convert
**
** @return The number of characters placed into the buffer
** (not including the NUL)
**
** NOTE: assumes buf is large enough to hold the resulting string
*/
int cvthex( char *buf, uint32_t value );
/**
** cvtoct(buf,value)
**
** convert a 32-bit unsigned value into a mininal-length (up to
** 11-character) NUL-terminated character string
**
** @param buf Destination buffer
** @param value Value to convert
**
** @return The number of characters placed into the buffer
** (not including the NUL)
**
** NOTE: assumes buf is large enough to hold the resulting string
*/
int cvtoct( char *buf, uint32_t value );
/**
** bound(min,value,max)
**
** This function confines an argument within specified bounds.
**
** @param min Lower bound
** @param value Value to be constrained
** @param max Upper bound
**
** @return The constrained value
*/
uint32_t bound( uint32_t min, uint32_t value, uint32_t max );
#endif /* !ASM_SRC */
/*
** Finally, pull in the level-specific library headers
*/
#ifdef KERNEL_SRC
#include <klib.h>
#else
#include <ulib.h>
#endif /* KERNEL_SRC */
#endif

View file

@ -35,7 +35,7 @@
// The list structure
typedef struct list_s {
struct list_s *next; // link to the successor
struct list_s *next; // link to the successor
} list_t;
/*
@ -50,7 +50,7 @@ typedef struct list_s {
** @param[in,out] list The address of a list_t variable
** @param[in] data The data to prepend to the list
*/
void list_add(list_t *list, void *data);
void list_add( list_t *list, void *data );
/**
** Name: list_remove
@ -61,7 +61,7 @@ void list_add(list_t *list, void *data);
**
** @return a pointer to the removed data, or NULL if the list was empty
*/
void *list_remove(list_t *list);
void *list_remove( list_t *list );
#endif /* !ASM_SRC */

View file

@ -1,83 +0,0 @@
/**
** @file offsets.h
**
** GENERATED AUTOMATICALLY - DO NOT EDIT
**
** This header file contains C Preprocessor macros which expand
** into the byte offsets needed to reach fields within structs
** used in the baseline system. Should those struct declarations
** change, the Offsets program should be modified (if needed),
** recompiled, and re-run to recreate this file.
*/
#ifndef OFFSETS_H_
#define OFFSETS_H_
// Sizes of basic types
#define SZ_char 1
#define SZ_short 2
#define SZ_int 4
#define SZ_long 4
#define SZ_long_long 8
#define SZ_pointer 4
// Sizes of our types
#define SZ_int8_t 1
#define SZ_uint8_t 1
#define SZ_int16_t 2
#define SZ_uint16_t 2
#define SZ_int32_t 4
#define SZ_uint32_t 4
#define SZ_int64_t 8
#define SZ_uint64_t 8
#define SZ_bool_t 1
// context_t structure
#define SZ_CTX 72
#define CTX_ss 0
#define CTX_gs 4
#define CTX_fs 8
#define CTX_es 12
#define CTX_ds 16
#define CTX_edi 20
#define CTX_esi 24
#define CTX_ebp 28
#define CTX_esp 32
#define CTX_ebx 36
#define CTX_edx 40
#define CTX_ecx 44
#define CTX_eax 48
#define CTX_vector 52
#define CTX_code 56
#define CTX_eip 60
#define CTX_cs 64
#define CTX_eflags 68
// section_t structure
#define SZ_SCT 8
#define SCT_length 0
#define SCT_addr 4
// pcb_t structure
#define SZ_PCB 72
#define PCB_context 0
#define PCB_pdir 4
#define PCB_sects 8
#define PCB_next 40
#define PCB_parent 44
#define PCB_wakeup 48
#define PCB_exit_status 52
#define PCB_pid 56
#define PCB_state 60
#define PCB_priority 64
#define PCB_ticks 68
#endif

View file

@ -20,14 +20,12 @@
// Upper bound on the number of simultaneous user-level
// processes in the system (completely arbitrary)
#define N_PROCS 25
// Limit on the number of entries in argv[], INCLUDING
// the trailing NULL pointer (also completely arbitrary)
#define N_ARGS 10
#define N_PROCS 25
// Clock frequency (Hz)
#define CLOCK_FREQ 1000
#define TICKS_PER_MS 1
#define CLOCK_FREQ 1000
#define TICKS_PER_MS 1
#endif

View file

@ -30,28 +30,22 @@
*/
enum state_e {
// pre-viable
STATE_UNUSED = 0,
STATE_NEW,
STATE_UNUSED = 0, STATE_NEW,
// runnable
STATE_READY,
STATE_RUNNING,
STATE_READY, STATE_RUNNING,
// runnable, but waiting for some event
STATE_SLEEPING,
STATE_BLOCKED,
STATE_WAITING,
STATE_SLEEPING, STATE_BLOCKED, STATE_WAITING,
// no longer runnable
STATE_KILLED,
STATE_ZOMBIE
STATE_KILLED, STATE_ZOMBIE
// sentinel value
,
N_STATES
, N_STATES
};
// these may be handy for checking general conditions of processes
// they depend on the order of the state names in the enum!
#define FIRST_VIABLE STATE_READY
#define FIRST_BLOCKED STATE_SLEEPING
#define LAST_VIABLE STATE_WAITING
#define FIRST_VIABLE STATE_READY
#define FIRST_BLOCKED STATE_SLEEPING
#define LAST_VIABLE STATE_WAITING
/*
** Process priorities are defined in <defs.h>
@ -60,13 +54,17 @@ enum state_e {
/*
** Quantum lengths - values are number of clock ticks
*/
enum quantum_e { QUANTUM_SHORT = 1, QUANTUM_STANDARD = 3, QUANTUM_LONG = 5 };
enum quantum_e {
QUANTUM_SHORT = 1,
QUANTUM_STANDARD = 3,
QUANTUM_LONG = 5
};
/*
** PID-related definitions
*/
#define PID_INIT 1
#define FIRST_USER_PID 2
#define PID_INIT 1
#define FIRST_USER_PID 2
/*
** Process context structure
@ -80,7 +78,7 @@ enum quantum_e { QUANTUM_SHORT = 1, QUANTUM_STANDARD = 3, QUANTUM_LONG = 5 };
*/
typedef struct context_s {
uint32_t ss; // pushed by isr_save
uint32_t ss; // pushed by isr_save
uint32_t gs;
uint32_t fs;
uint32_t es;
@ -94,34 +92,34 @@ typedef struct context_s {
uint32_t ecx;
uint32_t eax;
uint32_t vector;
uint32_t code; // pushed by isr_save or the hardware
uint32_t eip; // pushed by the hardware
uint32_t code; // pushed by isr_save or the hardware
uint32_t eip; // pushed by the hardware
uint32_t cs;
uint32_t eflags;
} context_t;
#define SZ_CONTEXT sizeof(context_t)
#define SZ_CONTEXT sizeof(context_t)
/*
** program section information for user processes
*/
typedef struct section_s {
uint_t length; // length, in some units
uint_t addr; // location, in some units
uint_t length; // length, in some units
uint_t addr; // location, in some units
} section_t;
// note: these correspond to the PT_LOAD sections found in
// an ELF file, not necessarily to text/data/bss
#define SECT_L1 0
#define SECT_L2 1
#define SECT_L3 2
#define SECT_STACK 3
#define SECT_L1 0
#define SECT_L2 1
#define SECT_L3 2
#define SECT_STACK 3
// total number of section table entries in our PCB
#define N_SECTS 4
#define N_SECTS 4
// number of those that can be loaded from an ELF module
#define N_LOADABLE 3
#define N_LOADABLE 3
/*
** The process control block
@ -134,31 +132,32 @@ typedef struct section_s {
*/
typedef struct pcb_s {
// four-byte fields
// start with these four bytes, for easy access in assembly
context_t *context; // pointer to context save area on stack
context_t *context; // pointer to context save area on stack
// VM information
pde_t *pdir; // page directory for this process
section_t sects[N_SECTS]; // per-section memory information
pde_t *pdir; // page directory for this process
section_t sects[N_SECTS]; // per-section memory information
// queue linkage
struct pcb_s *next; // next PCB in queue
struct pcb_s *next; // next PCB in queue
// process state information
struct pcb_s *parent; // pointer to PCB of our parent process
uint32_t wakeup; // wakeup time, for sleeping processes
int32_t exit_status; // termination status, for parent's use
struct pcb_s *parent; // pointer to PCB of our parent process
uint32_t wakeup; // wakeup time, for sleeping processes
int32_t exit_status; // termination status, for parent's use
// these things may not need to be four bytes
uint_t pid; // PID of this process
enum state_e state; // process' current state
enum priority_e priority; // process priority level
uint_t ticks; // remaining ticks in this time slice
uint_t pid; // PID of this process
enum state_e state; // process' current state
enum priority_e priority; // process priority level
uint_t ticks; // remaining ticks in this time slice
} pcb_t;
#define SZ_PCB sizeof(pcb_t)
#define SZ_PCB sizeof(pcb_t)
/*
** PCB queue structure (opaque to the rest of the kernel)
@ -169,16 +168,12 @@ typedef struct pcb_queue_s *pcb_queue_t;
** Queue ordering methods
*/
enum pcb_queue_order_e {
O_FIFO,
O_PRIO,
O_PID,
O_WAKEUP
O_FIFO, O_PRIO, O_PID, O_WAKEUP
// sentinel
,
N_ORDERINGS
, N_ORDERINGS
};
#define O_FIRST_STYLE O_FIFO
#define O_LAST_STYLE O_WAKEUP
#define O_FIRST_STYLE O_FIFO
#define O_LAST_STYLE O_WAKEUP
/*
** Globals
@ -205,13 +200,13 @@ extern uint_t next_pid;
extern pcb_t *init_pcb;
// table of state name strings
extern const char state_str[N_STATES][4];
extern const char *state_str[N_STATES];
// table of priority name strings
extern const char prio_str[N_PRIOS][5];
extern const char *prio_str[N_PRIOS];
// table of queue ordering name strings
extern const char ord_str[N_ORDERINGS][5];
extern const char *ord_str[N_ORDERINGS];
/*
** Prototypes
@ -222,7 +217,7 @@ extern const char ord_str[N_ORDERINGS][5];
**
** Initialization for the Process module.
*/
void pcb_init(void);
void pcb_init( void );
/**
** Name: pcb_alloc
@ -233,7 +228,7 @@ void pcb_init(void);
**
** @return status of the allocation attempt
*/
int pcb_alloc(pcb_t **pcb);
int pcb_alloc( pcb_t **pcb );
/**
** Name: pcb_free
@ -242,7 +237,7 @@ int pcb_alloc(pcb_t **pcb);
**
** @param pcb Pointer to the PCB to be deallocated.
*/
void pcb_free(pcb_t *pcb);
void pcb_free( pcb_t *pcb );
/**
** Name: pcb_zombify
@ -253,7 +248,7 @@ void pcb_free(pcb_t *pcb);
**
** @param pcb Pointer to the newly-undead PCB
*/
void pcb_zombify(register pcb_t *victim);
void pcb_zombify( register pcb_t *victim );
/**
** Name: pcb_cleanup
@ -262,7 +257,7 @@ void pcb_zombify(register pcb_t *victim);
**
** @param pcb The PCB to reclaim
*/
void pcb_cleanup(pcb_t *pcb);
void pcb_cleanup( pcb_t *pcb );
/**
** Name: pcb_find_pid
@ -273,7 +268,7 @@ void pcb_cleanup(pcb_t *pcb);
**
** @return Pointer to the PCB, or NULL
*/
pcb_t *pcb_find_pid(uint_t pid);
pcb_t *pcb_find_pid( uint_t pid );
/**
** Name: pcb_find_ppid
@ -284,7 +279,7 @@ pcb_t *pcb_find_pid(uint_t pid);
**
** @return Pointer to the PCB, or NULL
*/
pcb_t *pcb_find_ppid(uint_t pid);
pcb_t *pcb_find_ppid( uint_t pid );
/**
** Name: pcb_queue_reset
@ -296,7 +291,7 @@ pcb_t *pcb_find_ppid(uint_t pid);
**
** @return status of the init request
*/
int pcb_queue_reset(pcb_queue_t queue, enum pcb_queue_order_e style);
int pcb_queue_reset( pcb_queue_t queue, enum pcb_queue_order_e style );
/**
** Name: pcb_queue_empty
@ -308,7 +303,7 @@ int pcb_queue_reset(pcb_queue_t queue, enum pcb_queue_order_e style);
**
** @return true if the queue is empty, else false
*/
bool_t pcb_queue_empty(pcb_queue_t queue);
bool_t pcb_queue_empty( pcb_queue_t queue );
/**
** Name: pcb_queue_length
@ -319,7 +314,7 @@ bool_t pcb_queue_empty(pcb_queue_t queue);
**
** @return the count (0 if the queue is empty)
*/
uint_t pcb_queue_length(const pcb_queue_t queue);
uint_t pcb_queue_length( const pcb_queue_t queue );
/**
** Name: pcb_queue_insert
@ -331,7 +326,7 @@ uint_t pcb_queue_length(const pcb_queue_t queue);
**
** @return status of the insertion request
*/
int pcb_queue_insert(pcb_queue_t queue, pcb_t *pcb);
int pcb_queue_insert( pcb_queue_t queue, pcb_t *pcb );
/**
** Name: pcb_queue_peek
@ -343,7 +338,7 @@ int pcb_queue_insert(pcb_queue_t queue, pcb_t *pcb);
**
** @return the PCB pointer, or NULL if the queue is empty
*/
pcb_t *pcb_queue_peek(const pcb_queue_t queue);
pcb_t *pcb_queue_peek( const pcb_queue_t queue );
/**
** Name: pcb_queue_remove
@ -355,7 +350,7 @@ pcb_t *pcb_queue_peek(const pcb_queue_t queue);
**
** @return status of the removal request
*/
int pcb_queue_remove(pcb_queue_t queue, pcb_t **pcb);
int pcb_queue_remove( pcb_queue_t queue, pcb_t **pcb );
/**
** Name: pcb_queue_remove_this
@ -367,7 +362,7 @@ int pcb_queue_remove(pcb_queue_t queue, pcb_t **pcb);
**
** @return status of the removal request
*/
int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb);
int pcb_queue_remove_this( pcb_queue_t queue, pcb_t *pcb );
/*
** Scheduler routines
@ -380,14 +375,14 @@ int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb);
**
** @param pcb Pointer to the PCB of the process to be scheduled
*/
void schedule(pcb_t *pcb);
void schedule( pcb_t *pcb );
/**
** dispatch()
**
** Select the next process to receive the CPU
*/
void dispatch(void);
void dispatch( void );
/*
** Debugging/tracing routines
@ -401,7 +396,7 @@ void dispatch(void);
** @param msg[in] An optional message to print before the dump
** @param c[in] The context to dump out
*/
void ctx_dump(const char *msg, register context_t *c);
void ctx_dump( const char *msg, register context_t *c );
/**
** Name: ctx_dump_all
@ -410,7 +405,7 @@ void ctx_dump(const char *msg, register context_t *c);
**
** @param msg[in] Optional message to print
*/
void ctx_dump_all(const char *msg);
void ctx_dump_all( const char *msg );
/**
** Name: pcb_dump
@ -421,7 +416,7 @@ void ctx_dump_all(const char *msg);
** @param p[in] The PCB to dump
** @param all[in] Dump all the contents?
*/
void pcb_dump(const char *msg, register pcb_t *p, bool_t all);
void pcb_dump( const char *msg, register pcb_t *p, bool_t all );
/**
** Name: pcb_queue_dump
@ -432,7 +427,7 @@ void pcb_dump(const char *msg, register pcb_t *p, bool_t all);
** @param queue[in] The queue to dump
** @param contents[in] Also dump (some) contents?
*/
void pcb_queue_dump(const char *msg, pcb_queue_t queue, bool_t contents);
void pcb_queue_dump( const char *msg, pcb_queue_t queue, bool_t contents );
/**
** Name: ptable_dump
@ -442,7 +437,7 @@ void pcb_queue_dump(const char *msg, pcb_queue_t queue, bool_t contents);
** @param msg[in] Optional message to print
** @param all[in] Dump all or only part of the relevant data
*/
void ptable_dump(const char *msg, bool_t all);
void ptable_dump( const char *msg, bool_t all );
/**
** Name: ptable_dump_counts
@ -450,8 +445,8 @@ void ptable_dump(const char *msg, bool_t all);
** Prints basic information about the process table (number of
** entries, number with each process state, etc.).
*/
void ptable_dump_counts(void);
void ptable_dump_counts( void );
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -1,3 +0,0 @@
#pragma once
#include <stdint.h>

View file

@ -18,9 +18,9 @@
// sio interrupt settings
#define SIO_TX 0x01
#define SIO_RX 0x02
#define SIO_BOTH (SIO_TX | SIO_RX)
#define SIO_TX 0x01
#define SIO_RX 0x02
#define SIO_BOTH (SIO_TX | SIO_RX)
#ifndef ASM_SRC
@ -48,7 +48,7 @@ extern QTYPE QNAME;
**
** Initialize the UART chip.
*/
void sio_init(void);
void sio_init( void );
/**
** sio_enable()
@ -61,7 +61,7 @@ void sio_init(void);
**
** @return the prior IER setting
*/
uint8_t sio_enable(uint8_t which);
uint8_t sio_enable( uint8_t which );
/**
** sio_disable()
@ -74,7 +74,7 @@ uint8_t sio_enable(uint8_t which);
**
** @return the prior IER setting
*/
uint8_t sio_disable(uint8_t which);
uint8_t sio_disable( uint8_t which );
/**
** sio_inq_length()
@ -85,7 +85,7 @@ uint8_t sio_disable(uint8_t which);
**
** @return the count of characters still in the input queue
*/
int sio_inq_length(void);
int sio_inq_length( void );
/**
** sio_readc()
@ -96,7 +96,7 @@ int sio_inq_length(void);
**
** @return the next character, or -1 if no character is available
*/
int sio_readc(void);
int sio_readc( void );
/**
** sio_read()
@ -110,7 +110,7 @@ int sio_readc(void);
**
** @return the number of bytes copied, or 0 if no characters were available
*/
int sio_read(char *buffer, int length);
int sio_read( char *buffer, int length );
/**
** sio_writec( ch )
@ -121,7 +121,7 @@ int sio_read(char *buffer, int length);
**
** @param ch Character to be written (in the low-order 8 bits)
*/
void sio_writec(int ch);
void sio_writec( int ch );
/**
** sio_write( ch )
@ -135,7 +135,7 @@ void sio_writec(int ch);
**
** @return the number of characters copied into the SIO output buffer
*/
int sio_write(const char *buffer, int length);
int sio_write( const char *buffer, int length );
/**
** sio_puts( buf )
@ -148,7 +148,7 @@ int sio_write(const char *buffer, int length);
**
** @return the count of bytes transferred
*/
int sio_puts(const char *buffer);
int sio_puts( const char *buffer );
/**
** sio_dump( full )
@ -161,8 +161,8 @@ int sio_puts(const char *buffer);
** is being requested (which includes the contents
** of the queues)
*/
void sio_dump(bool_t full);
void sio_dump( bool_t full );
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -30,14 +30,14 @@
**
** Ultimately, just remember that THESE VALUES ARE APPROXIMATE AT BEST.
*/
#define DELAY_1_SEC 40
#define DELAY_1_25_SEC 50
#define DELAY_2_SEC 80
#define DELAY_2_5_SEC 100
#define DELAY_3_SEC 120
#define DELAY_5_SEC 200
#define DELAY_7_SEC 280
#define DELAY_10_SEC 400
#define DELAY_1_SEC 40
#define DELAY_1_25_SEC 50
#define DELAY_2_SEC 80
#define DELAY_2_5_SEC 100
#define DELAY_3_SEC 120
#define DELAY_5_SEC 200
#define DELAY_7_SEC 280
#define DELAY_10_SEC 400
#ifndef ASM_SRC
/**
@ -49,7 +49,7 @@
**
** @param reason NUL-terminated message to be printed.
*/
void panic(char *reason);
void panic( char *reason );
/**
** init_interrupts
@ -58,7 +58,7 @@ void panic(char *reason);
** IDT and the PIC. It is up to the user to enable processor interrupts
** when they're ready.
*/
void init_interrupts(void);
void init_interrupts( void );
/*
** install_isr
@ -71,7 +71,8 @@ void init_interrupts(void);
**
** @return a pointer to the previously-registered ISR
*/
void (*install_isr(int vector, void (*handler)(int, int)))(int, int);
void (*install_isr( int vector,
void ( *handler )(int,int) ) )( int, int );
/*
** Name: delay
@ -79,8 +80,8 @@ void (*install_isr(int vector, void (*handler)(int, int)))(int, int);
** See the comment above about the relative accuracy of the 'length'
** parameter.
*/
void delay(int length);
void delay( int length );
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -23,28 +23,28 @@
** so that they can be used from assembly
*/
#define SYS_exit 0
#define SYS_waitpid 1
#define SYS_fork 2
#define SYS_exec 3
#define SYS_read 4
#define SYS_write 5
#define SYS_getpid 6
#define SYS_getppid 7
#define SYS_gettime 8
#define SYS_getprio 9
#define SYS_setprio 10
#define SYS_kill 11
#define SYS_sleep 12
#define SYS_exit 0
#define SYS_waitpid 1
#define SYS_fork 2
#define SYS_exec 3
#define SYS_read 4
#define SYS_write 5
#define SYS_getpid 6
#define SYS_getppid 7
#define SYS_gettime 8
#define SYS_getprio 9
#define SYS_setprio 10
#define SYS_kill 11
#define SYS_sleep 12
// UPDATE THIS DEFINITION IF MORE SYSCALLS ARE ADDED!
#define N_SYSCALLS 13
#define N_SYSCALLS 13
// dummy system call code for testing our ISR
#define SYS_bogus 0xbad
#define SYS_bogus 0xbad
// interrupt vector entry for system calls
#define VEC_SYSCALL 0x80
#define VEC_SYSCALL 0x80
#ifndef ASM_SRC
@ -71,10 +71,10 @@
**
** Syscall module initialization routine
*/
void sys_init(void);
void sys_init( void );
#endif /* KERNEL_SRC */
#endif /* KERNEL_SRC */
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -1,13 +1,58 @@
/**
** @file types.h
**
** @author Warren R. Carithers
**
** @brief Common type declarations.
**
** This header file contains type declarations used throughout
** the kernel and user code.
*/
#ifndef TYPES_H_
#define TYPES_H_
#ifndef ASM_SRC
/*
** Start of C-only definitions
**
** Anything that should not be visible to something other than
** the C compiler should be put here.
*/
/*
** Types
*/
// standard integer sized types
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
// other integer types
typedef unsigned char uchar_t;
typedef unsigned int uint_t;
typedef unsigned long int ulong_t;
// Boolean values
typedef uint8_t bool_t;
#define true 1
#define false 0
#ifdef KERNEL_SRC
// we define these here instead of in vm.h in order to get around a
// nasty chick/egg dependency between procs.h and vm.h
typedef uint32_t pde_t; // page directory entry
typedef uint32_t pte_t; // page table entry
#endif /* KERNEL_SRC */
typedef uint32_t pde_t; // page directory entry
typedef uint32_t pte_t; // page table entry
#endif /* KERNEL_SRC */
#endif /* !ASM_SRC */
#endif
#endif

113
kernel/old/include/udefs.h Normal file
View file

@ -0,0 +1,113 @@
/**
** @file udefs.h
**
** @author CSCI-452 class of 20245
**
** @brief "Userland" configuration information
*/
#ifndef UDEFS_H_
#define UDEFS_H_
#include <common.h>
/*
** General (C and/or assembly) definitions
**
** This section of the header file contains definitions that can be
** used in either C or assembly-language source code.
*/
// delay loop counts
#define DELAY_LONG 100000000
#define DELAY_MED 4500000
#define DELAY_SHORT 2500000
#define DELAY_STD DELAY_SHORT
#ifndef ASM_SRC
/*
** Start of C-only definitions
*/
// convenience macros
// a delay loop - kind of ugly, but it works
#define DELAY(n) do { \
for(int _dlc = 0; _dlc < (DELAY_##n); ++_dlc) continue; \
} while(0)
/*
** We need the list of program IDs so that we can request
** their execution
*/
#include <userids.h>
/*
** All user main() functions have the following prototype:
**
** int name( int argc, char *argv[] );
**
** To simplify declaring them, we define a macro that expands into
** that header. This can be used both in the implementation (followed
** by the function body) and in places where we just need the prototype
** (following it with a semicolon).
*/
#define USERMAIN(f) int f( int argc, char *argv[] )
/*
** User process controls.
**
** To enable a specific test, define the symbol SPAWN_name here, and
** guard the places in other code that use or refer to that test. For
** example, test 'A' is enabled by definining SPAWN_A here, and all
** places that refer to test 'A' are guarded with:
**
** #ifdef SPAWN_A
** ... conditionally-compiled code
** #endif
**
** Generally, most of these will exit with a status of 0. If a process
** returns from its main function when it shouldn't (e.g., if it had
** called exit() but continued to run), it will usually return a status
** of ?.
*/
/*
** The standard set of test programs, start by the shell (which is started
** automatically from the initial user process)
**
** There is no user 'O' program, and programs 'W' through 'Z' are spawned
** from other processes and are never spawned directly.
*/
#define SPAWN_A
#define SPAWN_B
#define SPAWN_C
#define SPAWN_D
#define SPAWN_E
#define SPAWN_F
#define SPAWN_G
#define SPAWN_H
#define SPAWN_I
#define SPAWN_J
#define SPAWN_K
#define SPAWN_L
#define SPAWN_M
#define SPAWN_N
#define SPAWN_P
#define SPAWN_Q
#define SPAWN_R
#define SPAWN_S
#define SPAWN_T
#define SPAWN_U
#define SPAWN_V
#endif /* !ASM_SRC */
#endif

315
kernel/old/include/ulib.h Normal file
View file

@ -0,0 +1,315 @@
/**
** @file ulib.h
**
** @author CSCI-452 class of 20245
**
** @brief Declarations for user-level library functions
**
** This module implements a simple collection of support functions
** similar to the standard C library.
*/
#ifndef ULIB_H_
#define ULIB_H_
#include <common.h>
/*
** General (C and/or assembly) definitions
*/
#ifndef ASM_SRC
/*
** Start of C-only definitions
*/
/*
** Types
*/
/*
** Globals
*/
/*
** Prototypes
*/
/*
*************************************************
** SYSTEM CALLS *********************************
*************************************************
*/
/**
** exit - terminate the calling process
**
** usage: exit(status);
**
** @param status Termination status of this process
**
** Does not return.
*/
void exit( int32_t status );
/**
** waitpid - wait for a child process to terminate
**
** usage: pid = waitpid(pid,&status);
**
** @param pid PID of the desired child, or 0 for any child
** @param status Pointer to int32_t into which the child's status is placed,
** or NULL
**
** @return The PID of the terminated child, or an error code
**
** If there are no children in the system, returns an error code (*status
** is unchanged).
**
** If there are one or more children in the system and at least one has
** terminated but hasn't yet been cleaned up, cleans up that process and
** returns its information; otherwise, blocks until a child terminates.
*/
int waitpid( uint_t pid, int32_t *status );
/**
** fork - create a duplicate of the calling process
**
** usage: pid = fork();
**
** @return parent - the pid of the new child, or an error code
** child - 0
*/
int fork( void );
/**
** exec - replace the memory image of the calling process
**
** usage: exec( what, args )
**
** @param what program table index of the program to exec
** @param args the command-line argument vector
**
** Does not return if it succeeds; if it returns, something has
** gone wrong.
*/
void exec( uint_t what, char **args );
/**
** read - read into a buffer from a stream
**
** usage: n = read(channel,buf,length)
**
** @param chan I/O stream to read from
** @param buf Buffer to read into
** @param length Maximum capacity of the buffer
**
** @return The count of bytes transferred, or an error code
*/
int read( uint_t chan, void *buffer, uint_t length );
/**
** write - write from a buffer to a stream
**
** usage: n = write(channel,buf,length)
**
** @param chan I/O stream to write to
** @param buf Buffer to write from
** @param length Maximum capacity of the buffer
**
** @return The count of bytes transferred, or an error code
*/
int write( uint_t chan, const void *buffer, uint_t length );
/**
** getpid - get the PID of the calling process
**
** usage: pid = getpid()
**
** @return the PID of this process
*/
uint_t getpid( void );
/**
** getppid - get the PID of the calling process' parent
**
** usage: pid = getppid()
**
** @return the PID of this process' parent
*/
uint_t getppid( void );
/**
** gettime - get the current system time
**
** usage: pid = gettime()
**
** @return the system time
*/
uint32_t gettime( void );
/**
** getprio - get the scheduling priority of the calling process
**
** usage: prio = getprio()
**
** @return the process' priority
*/
int getprio( void );
/**
** setprio - set the scheduling priority of the calling process
**
** usage: oldprio = setprio(newprio)
**
** @param new the desired new priority
**
** @return the old priority value
*/
int setprio( int new );
/**
** kill - terminate a process with extreme prejudice
**
** usage: n = kill( pid )
**
** @param pid the intended victim
**
** @return 0 on success, else an error code
*/
int32_t kill( uint_t pid );
/**
** sleep - put the current process to sleep for some length of time
**
** usage: sleep(n);
**
** @param ms Desired sleep time (in ms), or 0 to yield the CPU
**
** @return the time the process spent sleeping (in ms)
*/
int sleep( uint32_t ms );
/**
** bogus - a nonexistent system call, to test our syscall ISR
**
** usage: bogus()
**
** Does not return.
*/
void bogus( void );
/*
*************************************************
** CONVENIENT "SHORTHAND" VERSIONS OF SYSCALLS **
*************************************************
**
** These are library functions that perform specific common
** variants of system calls. This helps reduce the total number
** of system calls, keeping our baseline OS as lean and mean
** as we can make it. :-)
*/
/**
** wait - wait for any child to exit
**
** usage: pid = wait(&status)
**
** Calls waitpid(0,status)
**
** @param status Pointer to int32_t into which the child's status is placed,
** or NULL
**
** @return The PID of the terminated child, or an error code
*/
int wait( int32_t *status );
/**
** spawn - create a new process running a different program
**
** usage: n = spawn(what,args)
**
** Creates a new process and then execs 'what'
**
** @param what Program table index of the program to spawn
** @param args The command-line argument vector for the process
**
** @return The PID of the child, or an error code
*/
int spawn( uint_t what, char **args );
/**
** cwritech(ch) - write a single character to the console
**
** @param ch The character to write
**
** @return The return value from calling write()
*/
int cwritech( char ch );
/**
** cwrites(str) - write a NUL-terminated string to the console
**
** @param str The string to write
**
*/
int cwrites( const char *str );
/**
** cwrite(buf,leng) - write a sized buffer to the console
**
** @param buf The buffer to write
** @param leng The number of bytes to write
**
** @return The return value from calling write()
*/
int cwrite( const char *buf, uint32_t leng );
/**
** swritech(ch) - write a single character to the SIO
**
** @param ch The character to write
**
** @return The return value from calling write()
*/
int swritech( char ch );
/**
** swrites(str) - write a NUL-terminated string to the SIO
**
** @param str The string to write
**
** @return The return value from calling write()
*/
int swrites( const char *str );
/**
** swrite(buf,leng) - write a sized buffer to the SIO
**
** @param buf The buffer to write
** @param leng The number of bytes to write
**
** @return The return value from calling write()
*/
int swrite( const char *buf, uint32_t leng );
/*
*************************************************
** MISCELLANEOUS USEFUL SUPPORT FUNCTIONS *******
*************************************************
*/
/**
** fake_exit()
**
** dummy "startup" function
**
** calls exit(%eax) - serves as the "return to" code for
** main() functions, in case they don't call exit() themselves
*/
void fake_exit( void );
#endif /* !ASM_SRC */
#endif

View file

@ -15,7 +15,7 @@
#include <x86/arch.h>
// default value for EFLAGS in new processes
#define DEFAULT_EFLAGS (EFL_MB1 | EFL_IF)
#define DEFAULT_EFLAGS (EFL_MB1 | EFL_IF)
/*
** General (C and/or assembly) definitions
@ -61,14 +61,14 @@ typedef struct header_s {
} header_t;
// length of the file name field
#define NAMELEN 20
#define NAMELEN 20
// program descriptor
typedef struct prog_s {
char name[NAMELEN]; // truncated name (15 chars)
uint32_t offset; // offset from the beginning of the blob
uint32_t size; // size of this ELF module
uint32_t flags; // miscellaneous flags
char name[NAMELEN]; // truncated name (15 chars)
uint32_t offset; // offset from the beginning of the blob
uint32_t size; // size of this ELF module
uint32_t flags; // miscellaneous flags
} prog_t;
/*
@ -84,7 +84,7 @@ typedef struct prog_s {
**
** Initializes the user support module.
*/
void user_init(void);
void user_init( void );
/**
** Name: user_locate
@ -95,7 +95,7 @@ void user_init(void);
**
** @return pointer to the program table entry in the code archive, or NULL
*/
prog_t *user_locate(uint_t what);
prog_t *user_locate( uint_t what );
/**
** Name: user_duplicate
@ -107,7 +107,7 @@ prog_t *user_locate(uint_t what);
**
** @return the status of the duplicate attempt
*/
int user_duplicate(pcb_t *new, pcb_t *old);
int user_duplicate( pcb_t *new, pcb_t *old );
/**
** Name: user_load
@ -118,11 +118,10 @@ int user_duplicate(pcb_t *new, pcb_t *old);
** @param prog A pointer to the program table entry to be loaded
** @param pcb The PCB for the program being loaded
** @param args The argument vector for the program
** @param sys Is the argument vector from kernel code?
**
** @return the status of the load attempt
*/
int user_load(prog_t *prog, pcb_t *pcb, const char **args, bool_t sys);
int user_load( prog_t *prog, pcb_t *pcb, const char **args );
/**
** Name: user_cleanup
@ -132,8 +131,8 @@ int user_load(prog_t *prog, pcb_t *pcb, const char **args, bool_t sys);
**
** @param pcb The PCB of the program to be cleaned up
*/
void user_cleanup(pcb_t *pcb);
void user_cleanup( pcb_t *pcb );
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -0,0 +1,33 @@
/**
** @file userids.h
**
** @author Warren R. Carithers
**
** @brief IDs for user-level programs
**
** NOTE: this file is automatically generated when the user.img file
** is created. Do not edit this manually!
*/
#ifndef USERIDS_H_
#define USERIDS_H_
#ifndef ASM_SRC
/*
** These IDs are used to identify the various user programs.
** Each call to exec() will provide one of these as the first
** argument.
**
** This list should be updated if/when the collection of
** user processes changes.
*/
enum users_e {
Init, Idle, Shell, ProgABC, ProgDE, ProgFG, ProgH, ProgI,
ProgJ, ProgKL, ProgMN, ProgP, ProgQ, ProgR, ProgS, ProgTUV,
ProgW, ProgX, ProgY, ProgZ
// sentinel
, N_USERS
};
#endif /* !ASM_SRC */
#endif

View file

@ -64,91 +64,87 @@
*/
// user virtual addresses
#define USER_BASE 0x00000000
#define USER_MAX 0x003fffff
#define USER_TEXT 0x00001000
#define USER_STACK 0x003fe000
#define USER_STACK_P1 USER_STACK
#define USER_STACK_P2 0x003ff000
#define USER_STK_END 0x00400000
#define USER_TEXT 0x00001000
#define USER_STACK 0x003fe000
#define USER_STK_END 0x00400000
// how to find the addresses of the stack pages in the VM hierarchy
// user address space is the first 4MB of virtual memory
#define USER_PDE 0
// the stack occupies this range of pages in the user address space
#define USER_STK_FIRST_PTE 1022
#define USER_STK_LAST_PTE 1023
#define USER_PDE 0
// the stack occupies the last two pages of the address space
#define USER_STK_PTE1 1022
#define USER_STK_PTE2 1023
// some important memory addresses
#define KERN_BASE 0x80000000 // start of "kernel" memory
#define EXT_BASE 0x00100000 // start of "extended" memory (1MB)
#define DEV_BASE 0xfe000000 // "device" memory
#define PHYS_TOP 0x3fffffff // last usable physical address (1GB - 1)
#define KERN_BASE 0x80000000 // start of "kernel" memory
#define EXT_BASE 0x00100000 // start of "extended" memory (1MB)
#define DEV_BASE 0xfe000000 // "device" memory
#define PHYS_TOP 0x3fffffff // last usable physical address (1GB - 1)
// where the kernel actually lives
#define KERN_PLINK 0x00010000
#define KERN_VLINK (KERN_BASE + KERN_PLINK)
#define KERN_PLINK 0x00010000
#define KERN_VLINK (KERN_BASE + KERN_PLINK)
// number of entries in a page directory or page table
#define N_PDE 1024
#define N_PTE 1024
#define N_PDE 1024
#define N_PTE 1024
// index field shift counts and masks
#define PDIX_SHIFT 22
#define PTIX_SHIFT 12
#define PIX2I_MASK 0x3ff
#define PDIX_SHIFT 22
#define PTIX_SHIFT 12
#define PIX2I_MASK 0x3ff
// physical/virtual converters that don't use casting
// (usable from anywhere)
#define V2PNC(a) ((a) - KERN_BASE)
#define P2VNC(a) ((a) + KERN_BASE)
#define V2PNC(a) ((a) - KERN_BASE)
#define P2VNC(a) ((a) + KERN_BASE)
// page-size address rounding macros
#define SZ_PG_M1 MOD4K_BITS
#define SZ_PG_MASK MOD4K_MASK
#define PGUP(a) (((a) + SZ_PG_M1) & SZ_PG_MASK)
#define PGDOWN(a) ((a) & SZ_PG_MASK)
#define SZ_PG_M1 MOD4K_BITS
#define SZ_PG_MASK MOD4K_MASK
#define PGUP(a) (((a)+SZ_PG_M1) & SZ_PG_MASK)
#define PGDOWN(a) ((a) & SZ_PG_MASK)
// page directory entry bit fields
#define PDE_P 0x00000001 // 1 = present
#define PDE_RW 0x00000002 // 1 = writable
#define PDE_US 0x00000004 // 1 = user and system usable
#define PDE_PWT 0x00000008 // cache: 1 = write-through
#define PDE_PCD 0x00000010 // cache: 1 = disabled
#define PDE_A 0x00000020 // accessed
#define PDE_D 0x00000040 // dirty (4MB pages)
#define PDE_AVL1 0x00000040 // ignored (4KB pages)
#define PDE_PS 0x00000080 // 1 = 4MB page size
#define PDE_G 0x00000100 // global
#define PDE_AVL2 0x00000e00 // ignored
#define PDE_PAT 0x00001000 // (4MB pages) use page attribute table
#define PDE_PTA 0xfffff000 // page table address field (4KB pages)
#define PDE_FA 0xffc00000 // frame address field (4MB pages)
#define PDE_P 0x00000001 // 1 = present
#define PDE_RW 0x00000002 // 1 = writable
#define PDE_US 0x00000004 // 1 = user and system usable
#define PDE_PWT 0x00000008 // cache: 1 = write-through
#define PDE_PCD 0x00000010 // cache: 1 = disabled
#define PDE_A 0x00000020 // accessed
#define PDE_D 0x00000040 // dirty (4MB pages)
#define PDE_AVL1 0x00000040 // ignored (4KB pages)
#define PDE_PS 0x00000080 // 1 = 4MB page size
#define PDE_G 0x00000100 // global
#define PDE_AVL2 0x00000e00 // ignored
#define PDE_PAT 0x00001000 // (4MB pages) use page attribute table
#define PDE_PTA 0xfffff000 // page table address field (4KB pages)
#define PDE_FA 0xffc00000 // frame address field (4MB pages)
// page table entry bit fields
#define PTE_P 0x00000001 // present
#define PTE_RW 0x00000002 // 1 = writable
#define PTE_US 0x00000004 // 1 = user and system usable
#define PTE_PWT 0x00000008 // cache: 1 = write-through
#define PTE_PCD 0x00000010 // cache: 1 = disabled
#define PTE_A 0x00000020 // accessed
#define PTE_D 0x00000040 // dirty
#define PTE_PAT 0x00000080 // use page attribute table
#define PTE_G 0x00000100 // global
#define PTE_AVL2 0x00000e00 // ignored
#define PTE_FA 0xfffff000 // frame address field
#define PTE_P 0x00000001 // present
#define PTE_RW 0x00000002 // 1 = writable
#define PTE_US 0x00000004 // 1 = user and system usable
#define PTE_PWT 0x00000008 // cache: 1 = write-through
#define PTE_PCD 0x00000010 // cache: 1 = disabled
#define PTE_A 0x00000020 // accessed
#define PTE_D 0x00000040 // dirty
#define PTE_PAT 0x00000080 // use page attribute table
#define PTE_G 0x00000100 // global
#define PTE_AVL2 0x00000e00 // ignored
#define PTE_FA 0xfffff000 // frame address field
// error code bit assignments for page faults
#define PFLT_P 0x00000001
#define PFLT_W 0x00000002
#define PFLT_US 0x00000004
#define PFLT_RSVD 0x00000008
#define PFLT_ID 0x00000010
#define PFLT_PK 0x00000020
#define PFLT_SS 0x00000040
#define PFLT_HLAT 0x00000080
#define PFLT_SGX 0x00008000
#define PFLT_UNUSED 0xffff7f00
#define PFLT_P 0x00000001
#define PFLT_W 0x00000002
#define PFLT_US 0x00000004
#define PFLT_RSVD 0x00000008
#define PFLT_ID 0x00000010
#define PFLT_PK 0x00000020
#define PFLT_SS 0x00000040
#define PFLT_HLAT 0x00000080
#define PFLT_SGX 0x00008000
#define PFLT_UNUSED 0xffff7f00
#ifndef ASM_SRC
@ -158,59 +154,54 @@
// physical/virtual converters that do use casting
// (not usable from assembly)
#define V2P(a) (((uint32_t)(a)) - KERN_BASE)
#define P2V(a) (((uint32_t)(a)) + KERN_BASE)
#define V2P(a) (((uint32_t)(a)) - KERN_BASE)
#define P2V(a) (((uint32_t)(a)) + KERN_BASE)
// create a pde/pte from an integer frame number and permission bits
#define MKPDE(f, p) ((pde_t)(TO_FRAME((f)) | (p)))
#define MKPTE(f, p) ((pte_t)(TO_FRAME((f)) | (p)))
#define MKPDE(f,p) ((pde_t)( TO_FRAME((f)) | (p) ))
#define MKPTE(f,p) ((pte_t)( TO_FRAME((f)) | (p) ))
// is a PDE/PTE present?
// (P bit is in the same place in both)
#define IS_PRESENT(entry) (((entry) & PDE_P) != 0)
#define IS_PRESENT(entry) (((entry) & PDE_P) != 0 )
// is a PDE a 4MB page entry?
#define IS_LARGE(pde) (((pde) & PDE_PS) != 0)
#define IS_LARGE(pde) (((pde) & PDE_PS) != 0 )
// is this entry "system only" or "system and user"?
#define IS_SYSTEM(entry) (((entry) & PDE_US) == 0)
#define IS_USER(entry) (((entry) & PDE_US) != 0)
#define IS_SYSTEM(entry) (((entry) & PDE_US) == 0 )
#define IS_USER(entry) (((entry) & PDE_US) != 0 )
// low-order nine bits of PDEs and PTEs hold "permission" flag bits
#define PERMS_MASK MOD4K_BITS
#define PERMS_MASK MOD4K_MASK
// 4KB frame numbers are 20 bits wide
#define FRAME_4K_SHIFT 12
#define FRAME2I_4K_MASK 0x000fffff
#define TO_4KFRAME(n) (((n) & FRAME2I_4K_MASK) << FRAME_4K_SHIFT)
#define GET_4KFRAME(n) (((n) >> FRAME_4K_SHIFT) & FRAME2I_4K_MASK)
#define PDE_4K_ADDR(n) ((n) & MOD4K_MASK)
#define PTE_4K_ADDR(n) ((n) & MOD4K_MASK)
#define FRAME_4K_SHIFT 12
#define FRAME2I_4K_MASK 0x000fffff
#define TO_4KFRAME(n) (((n)&FRAME2I_4K_MASK) << FRAME_4K_SHIFT)
#define GET_4KFRAME(n) (((n) >> FRAME_4K_SHIFT)&F2I_4K_MASK)
#define PDE_4K_ADDR(n) ((n) & MOD4K_MASK)
#define PTE_4K_ADDR(n) ((n) & MOD4K_MASK)
// 4MB frame numbers are 10 bits wide
#define FRAME_4M_SHIFT 22
#define FRAME2I_4M_MASK 0x000003ff
#define TO_4MFRAME(n) (((n) & FRAME2I_4M_MASK) << FRAME_4M_SHIFT)
#define GET_4MFRAME(n) (((n) >> FRAME_4M_SHIFT) & FRAME2I_4M_MASK)
#define PDE_4M_ADDR(n) ((n) & MOD4M_MASK)
#define PTE_4M_ADDR(n) ((n) & MOD4M_MASK)
#define FRAME_4M_SHIFT 22
#define FRAME2I_4M_MASK 0x000003ff
#define TO_4MFRAME(n) (((n)&FRAME2I_4M_MASK) << FRAME_4M_SHIFT)
#define GET_4MFRAME(n) (((n) >> FRAME_4M_SHIFT)&F2I_4M_MASK)
#define PDE_4M_ADDR(n) ((n) & MOD4M_MASK)
#define PTE_4M_ADDR(n) ((n) & MOD4M_MASK)
// extract the PMT address or frame address from a table entry
// PDEs could point to 4MB pages, or 4KB PMTs
#define PDE_ADDR(p) \
(IS_LARGE(p) ? (((uint32_t)p) & PDE_FA) : (((uint32_t)p) & PDE_PTA))
#define PDE_ADDR(p) (IS_LARGE(p)?(((uint32_t)p)&PDE_FA):(((uint32_t)p)&PDE_PTA))
// PTEs always point to 4KB pages
#define PTE_ADDR(p) (((uint32_t)(p)) & PTE_FA)
#define PTE_ADDR(p) (((uint32_t)(p))&PTE_FA)
// everything has nine bits of permission flags
#define PERMS(p) (((uint32_t)(p)) & PERMS_MASK)
#define PERMS(p) (((uint32_t)(p))&PERMS_MASK)
// extract the table indices from a 32-bit VA
#define PDIX(v) ((((uint32_t)(v)) >> PDIX_SHIFT) & PIX2I_MASK)
#define PTIX(v) ((((uint32_t)(v)) >> PTIX_SHIFT) & PIX2I_MASK)
// extract the byte offset from a 32-bit VA
#define OFFSET_4K(v) (((uint32_t)(v)) & MOD4K_BITS)
#define OFFSET_4M(v) (((uint32_t)(v)) & MOD4M_BITS)
// extract the table indices from a 32-bit address
#define PDIX(v) ((((uint32_t)(v)) >> PDIX_SHIFT) & PIX2I_MASK)
#define PTIX(v) ((((uint32_t)(v)) >> PTIX_SHIFT) & PIX2I_MASK)
/*
** Types
@ -223,34 +214,31 @@
// PDE for 4KB pages
typedef struct pdek_s {
uint_t p : 1; // 0: present
uint_t rw : 1; // 1: writable
uint_t us : 1; // 2: user/supervisor
uint_t pwt : 1; // 3: cache write-through
uint_t pcd : 1; // 4: cache disable
uint_t a : 1; // 5: accessed
uint_t avl1 : 1; // 6: ignored (available)
uint_t ps : 1; // 7: page size (must be 0)
uint_t avl2 : 4; // 11-8: ignored (available)
uint_t fa : 20; // 31-12: frame address
uint_t p :1; // present
uint_t rw :1; // writable
uint_t us :1; // user/supervisor
uint_t pwt :1; // cache write-through
uint_t pcd :1; // cache disable
uint_t a :1; // accessed
uint_t avl1 :1; // ignored (available)
uint_t ps :1; // page size (must be 0)
uint_t avl2 :4; // ignored (available)
uint_t fa :20; // frame address
} pdek_f_t;
// PDE for 4MB pages
typedef struct pdem_s {
uint_t p : 1; // 0: present
uint_t rw : 1; // 1: writable
uint_t us : 1; // 2: user/supervisor
uint_t pwt : 1; // 3: cache write-through
uint_t pcd : 1; // 4: cache disable
uint_t a : 1; // 5: accessed
uint_t d : 1; // 6: dirty
uint_t ps : 1; // 7: page size (must be 1)
uint_t g : 1; // 8: global
uint_t avl : 3; // 11-9: ignored (available)
uint_t pat : 1; // 12: page attribute table in use
uint_t fa2 : 4; // 16-13: bits 35-32 of frame address (36-bit addrs)
uint_t rsv : 5; // 21-17: reserved - must be zero
uint_t fa : 10; // 31-22: bits 31-22 of frame address
uint_t p :1; // present
uint_t rw :1; // writable
uint_t us :1; // user/supervisor
uint_t pwt :1; // cache write-through
uint_t pcd :1; // cache disable
uint_t a :1; // accessed
uint_t d :1; // dirty
uint_t ps :1; // page size (must be 1)
uint_t g :1; // global
uint_t avl :3; // ignored (available)
uint_t fa :20; // frame address
} pdem_f_t;
// page table entries
@ -260,33 +248,33 @@ typedef struct pdem_s {
// broken out into fields
typedef struct pte_s {
uint_t p : 1; // 0: present
uint_t rw : 1; // 1: writable
uint_t us : 1; // 2: user/supervisor
uint_t pwt : 1; // 3: cache write-through
uint_t pcd : 1; // 4: cache disable
uint_t a : 1; // 5: accessed
uint_t d : 1; // 6: dirty
uint_t pat : 1; // 7: page attribute table in use
uint_t g : 1; // 8: global
uint_t avl : 3; // 11-9: ignored (available)
uint_t fa : 20; // 31-12: frame address
uint_t p :1; // present
uint_t rw :1; // writable
uint_t us :1; // user/supervisor
uint_t pwt :1; // cache write-through
uint_t pcd :1; // cache disable
uint_t a :1; // accessed
uint_t d :1; // dirty
uint_t pat :1; // page attribute table in use
uint_t g :1; // global
uint_t avl :3; // ignored (available)
uint_t fa :20; // frame address
} ptef_t;
// page fault error code bits
// comment: meaning when 1 / meaning when 0
struct pfec_s {
uint_t p : 1; // page-level protection violation / !present
uint_t w : 1; // write / read
uint_t us : 1; // user-mode access / supervisor-mode access
uint_t rsvd : 1; // reserved bit violation / not
uint_t id : 1; // instruction fetch / data fetch
uint_t pk : 1; // protection-key violation / !pk
uint_t ss : 1; // shadow stack access / !ss
uint_t hlat : 1; // HLAT paging / ordinary paging or access rights
uint_t xtr1 : 7; // unused
uint_t sgz : 1; // SGX-specific access control violation / !SGX
uint_t xtr2 : 16; // more unused
uint_t p :1; // page-level protection violation / !present
uint_t w :1; // write / read
uint_t us :1; // user-mode access / supervisor-mode access
uint_t rsvd :1; // reserved bit violation / not
uint_t id :1; // instruction fetch / data fetch
uint_t pk :1; // protection-key violation / !pk
uint_t ss :1; // shadow stack access / !ss
uint_t hlat :1; // HLAT paging / ordinary paging or access rights
uint_t xtr1 :7; // unused
uint_t sgz :1; // SGX-specific access control violation / !SGX
uint_t xtr2 :16; // more unused
};
typedef union pfec_u {
@ -296,23 +284,12 @@ typedef union pfec_u {
// Mapping descriptor for VA::PA mappings
typedef struct mapping_t {
uint32_t va_start; // starting virtual address for this range
uint32_t pa_start; // first physical address in the range
uint32_t pa_end; // last physical address in the range
uint32_t perm; // access control
uint32_t va_start; // starting virtual address for this range
uint32_t pa_start; // first physical address in the range
uint32_t pa_end; // last physical address in the range
uint32_t perm; // access control
} mapping_t;
// Modes for dumping out page hierarchies
enum vmmode_e {
Simple = 0, // just count 'present' entries at each level
OneLevel, // top-level only: count entries, decode 'present'
TwoLevel, // count entries & decode at each level
Full // ??? in case we need more?
// sentinel
,
N_VMMODES
};
/*
** Globals
*/
@ -332,20 +309,7 @@ extern pde_t *kpdir;
** Note: should not be called until after the memory free list has
** been set up.
*/
void vm_init(void);
/**
** Name: vm_uva2kva
**
** Convert a user VA into a kernel address. Works for all addresses -
** if the address is a page address, the low-order nine bits will be
** zeroes; otherwise, they is the offset into the page, which is
** unchanged within the address spaces.
**
** @param pdir Pointer to the page directory to examine
** @param va Virtual address to check
*/
void *vm_uva2kva(pde_t *pdir, void *va);
void vm_init( void );
/**
** Name: vm_pagedup
@ -356,18 +320,7 @@ void *vm_uva2kva(pde_t *pdir, void *va);
**
** @return a pointer to the new, duplicate page, or NULL
*/
void *vm_pagedup(void *old);
/**
** Name: vm_pdedup
**
** Duplicate a page directory entry
**
** @param entry The entry to be duplicated
**
** @return the new entry, or -1 on error.
*/
pde_t vm_pdedup(pde_t entry);
void *vm_pagedup( void *old );
/**
** Name: vm_ptdup
@ -379,7 +332,7 @@ pde_t vm_pdedup(pde_t entry);
**
** @return true on success, else false
*/
bool_t vm_ptdup(pde_t *dst, pde_t *curr);
bool_t vm_ptdup( pde_t *dst, pde_t *curr );
/**
** Name: vm_getpte
@ -395,28 +348,28 @@ bool_t vm_ptdup(pde_t *dst, pde_t *curr);
**
** @return A pointer to the page table entry for this VA, or NULL
*/
pte_t *vm_getpte(pde_t *pdir, const void *va, bool_t alloc);
pte_t *vm_getpte( pde_t *pdir, const void *va, bool_t alloc );
/**
** Name: vm_mkkvm
**
** Create the kernel's page table hierarchy
*/
pde_t *vm_mkkvm(void);
pde_t *vm_mkkvm( void );
/**
** Name: vm_mkuvm
**
** Create the page table hierarchy for a user process
*/
pde_t *vm_mkuvm(void);
pde_t *vm_mkuvm( void );
/**
** Name: vm_set_kvm
**
** Switch the page table register to the kernel's page directory
*/
void vm_set_kvm(void);
void vm_set_kvm( void );
/**
** Name: vm_set_uvm
@ -425,7 +378,7 @@ void vm_set_kvm(void);
**
** @param p The PCB of the user process
*/
void vm_set_uvm(pcb_t *p);
void vm_set_uvm( pcb_t *p );
/**
** Name: vm_add
@ -443,8 +396,8 @@ void vm_set_uvm(pcb_t *p);
**
** @return status of the allocation attempt
*/
int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size,
char *data, uint32_t bytes);
int vm_add( pde_t *pdir, bool_t wr, bool_t sys,
void *va, uint32_t size, char *data, uint32_t bytes );
/**
** Name: vm_free
@ -454,7 +407,7 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size,
**
** @param pdir Pointer to the page directory
*/
void vm_free(pde_t *pdir);
void vm_free( pde_t *pdir );
/*
** Name: vm_map
@ -465,11 +418,11 @@ void vm_free(pde_t *pdir);
**
** @param pdir Page directory for this address space
** @param va The starting virtual address
** @param pa The starting physical address
** @param size Length of the range to be mapped
** @param pa The starting physical address
** @param perm Permission bits for the PTEs
*/
int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm);
int vm_map( pde_t *pdir, void *va, uint_t size, uint_t pa, int perm );
/**
** Name: vm_uvmdup
@ -478,24 +431,13 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm);
** hierarchy. We assume that the "new" page directory exists and
** the system portions of it should not be touched.
**
** @param new New page directory
** @param old Existing page directory
** @param new New page directory
**
** @return status of the duplication attempt
*/
int vm_uvmdup(pde_t *new, pde_t *old);
int vm_uvmdup( pde_t *old, pde_t *new );
/**
** Name: vm_print
**
** Print out a paging hierarchy.
**
** @param pt Page table to display
** @param dir Is it a page directory (vs. a page table)?
** @param mode How to display the entries
*/
void vm_print(void *pt, bool_t dir, enum vmmode_e mode);
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -38,6 +38,6 @@ extern pte_t id_map[];
extern mapping_t kmap[];
extern const uint32_t n_kmap;
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -15,25 +15,25 @@
/*
** Video stuff
*/
#define VID_BASE_ADDR 0xB8000
#define VID_BASE_ADDR 0xB8000
/*
** Memory management
*/
#define SEG_PRESENT 0x80
#define SEG_PL_0 0x00
#define SEG_PL_1 0x20
#define SEG_PL_2 0x40
#define SEG_PL_3 0x50
#define SEG_SYSTEM 0x00
#define SEG_NON_SYSTEM 0x10
#define SEG_32BIT 0x04
#define DESC_IGATE 0x06
#define SEG_PRESENT 0x80
#define SEG_PL_0 0x00
#define SEG_PL_1 0x20
#define SEG_PL_2 0x40
#define SEG_PL_3 0x50
#define SEG_SYSTEM 0x00
#define SEG_NON_SYSTEM 0x10
#define SEG_32BIT 0x04
#define DESC_IGATE 0x06
/*
** Exceptions
*/
#define N_EXCEPTIONS 256
#define N_EXCEPTIONS 256
/*
** Bit definitions in registers
@ -41,94 +41,95 @@
** See IA-32 Intel Architecture SW Dev. Manual, Volume 3: System
** Programming Guide, page 2-8.
*/
/*
** EFLAGS
*/
#define EFL_RSVD 0xffc00000 /* reserved */
#define EFL_MB0 0x00008020 /* must be zero */
#define EFL_MB1 0x00000002 /* must be 1 */
#define EFL_RSVD 0xffc00000 /* reserved */
#define EFL_MB0 0x00008020 /* must be zero */
#define EFL_MB1 0x00000002 /* must be 1 */
#define EFL_ID 0x00200000
#define EFL_VIP 0x00100000
#define EFL_VIF 0x00080000
#define EFL_AC 0x00040000
#define EFL_VM 0x00020000
#define EFL_RF 0x00010000
#define EFL_NT 0x00004000
#define EFL_ID 0x00200000
#define EFL_VIP 0x00100000
#define EFL_VIF 0x00080000
#define EFL_AC 0x00040000
#define EFL_VM 0x00020000
#define EFL_RF 0x00010000
#define EFL_NT 0x00004000
#define EFL_IOPL 0x00003000
#define EFL_OF 0x00000800
#define EFL_DF 0x00000400
#define EFL_IF 0x00000200
#define EFL_TF 0x00000100
#define EFL_SF 0x00000080
#define EFL_ZF 0x00000040
#define EFL_AF 0x00000010
#define EFL_PF 0x00000004
#define EFL_CF 0x00000001
#define EFL_OF 0x00000800
#define EFL_DF 0x00000400
#define EFL_IF 0x00000200
#define EFL_TF 0x00000100
#define EFL_SF 0x00000080
#define EFL_ZF 0x00000040
#define EFL_AF 0x00000010
#define EFL_PF 0x00000004
#define EFL_CF 0x00000001
/*
** CR0, CR1, CR2, CR3, CR4
**
** IA-32 V3, page 2-12.
*/
#define CR0_RSVD 0x1ffaffc0
#define CR0_PG 0x80000000
#define CR0_CD 0x40000000
#define CR0_NW 0x20000000
#define CR0_AM 0x00040000
#define CR0_WP 0x00010000
#define CR0_NE 0x00000020
#define CR0_ET 0x00000010
#define CR0_TS 0x00000008
#define CR0_EM 0x00000004
#define CR0_MP 0x00000002
#define CR0_PE 0x00000001
#define CR0_RSVD 0x1ffaffc0
#define CR0_PG 0x80000000
#define CR0_CD 0x40000000
#define CR0_NW 0x20000000
#define CR0_AM 0x00040000
#define CR0_WP 0x00010000
#define CR0_NE 0x00000020
#define CR0_ET 0x00000010
#define CR0_TS 0x00000008
#define CR0_EM 0x00000004
#define CR0_MP 0x00000002
#define CR0_PE 0x00000001
#define CR1_RSVD 0xffffffff
#define CR1_RSVD 0xffffffff
#define CR2_RSVD 0x00000000
#define CR2_RSVD 0x00000000
#define CR2_PF_LIN_ADDR 0xffffffff
#define CR3_RSVD 0x00000fe7
#define CR3_PD_BASE 0xfffff000
#define CR3_PCD 0x00000010
#define CR3_PWT 0x00000008
#define CR3_RSVD 0x00000fe7
#define CR3_PD_BASE 0xfffff000
#define CR3_PCD 0x00000010
#define CR3_PWT 0x00000008
#define CR4_RSVD 0xfd001000
#define CR4_UINT 0x02000000
#define CR4_PKS 0x01000000
#define CR4_CET 0x00800000
#define CR4_PKE 0x00400000
#define CR4_SMAP 0x00200000
#define CR4_SMEP 0x00100000
#define CR4_KL 0x00080000
#define CR4_OSXS 0x00040000
#define CR4_PCID 0x00020000
#define CR4_FSGS 0x00010000
#define CR4_SMXE 0x00004000
#define CR4_VMXE 0x00002000
#define CR4_LA57 0x00001000
#define CR4_UMIP 0x00000800
#define CR4_OSXMMEXCPT 0x00000400
#define CR4_OSFXSR 0x00000200
#define CR4_PCE 0x00000100
#define CR4_PGE 0x00000080
#define CR4_MCE 0x00000040
#define CR4_PAE 0x00000020
#define CR4_PSE 0x00000010
#define CR4_DE 0x00000008
#define CR4_TSD 0x00000004
#define CR4_PVI 0x00000002
#define CR4_VME 0x00000001
#define CR4_RSVD 0xfd001000
#define CR4_UINT 0x02000000
#define CR4_PKS 0x01000000
#define CR4_CET 0x00800000
#define CR4_PKE 0x00400000
#define CR4_SMAP 0x00200000
#define CR4_SMEP 0x00100000
#define CR4_KL 0x00080000
#define CR4_OSXS 0x00040000
#define CR4_PCID 0x00020000
#define CR4_FSGS 0x00010000
#define CR4_SMXE 0x00004000
#define CR4_VMXE 0x00002000
#define CR4_LA57 0x00001000
#define CR4_UMIP 0x00000800
#define CR4_OSXMMEXCPT 0x00000400
#define CR4_OSFXSR 0x00000200
#define CR4_PCE 0x00000100
#define CR4_PGE 0x00000080
#define CR4_MCE 0x00000040
#define CR4_PAE 0x00000020
#define CR4_PSE 0x00000010
#define CR4_DE 0x00000008
#define CR4_TSD 0x00000004
#define CR4_PVI 0x00000002
#define CR4_VME 0x00000001
/*
** PMode segment selector field masks
**
** IA-32 V3, page 3-8.
*/
#define SEG_SEL_IX_MASK 0xfff8
#define SEG_SEL_TI_MASK 0x0004
#define SEG_SEL_RPL_MASK 0x0003
#define SEG_SEL_IX_MASK 0xfff8
#define SEG_SEL_TI_MASK 0x0004
#define SEG_SEL_RPL_MASK 0x0003
/*
** Segment descriptor bytes
@ -141,6 +142,7 @@
** 4: base address 23:16
** 7: base address 31:24
*/
/*
** Byte 5: access control bits
** 7: present
@ -148,43 +150,43 @@
** 4: system/user
** 3-0: type
*/
#define SEG_ACCESS_P_MASK 0x80
#define SEG_PRESENT 0x80
#define SEG_NOT_PRESENT 0x00
#define SEG_ACCESS_P_MASK 0x80
# define SEG_PRESENT 0x80
# define SEG_NOT_PRESENT 0x00
#define SEG_ACCESS_DPL_MASK 0x60
#define SEG_DPL_0 0x00
#define SEG_DPL_1 0x20
#define SEG_DPL_2 0x40
#define SEG_DPL_3 0x60
#define SEG_ACCESS_DPL_MASK 0x60
# define SEG_DPL_0 0x00
# define SEG_DPL_1 0x20
# define SEG_DPL_2 0x40
# define SEG_DPL_3 0x60
#define SEG_ACCESS_S_MASK 0x10
#define SEG_SYSTEM 0x00
#define SEG_NON_SYSTEM 0x10
#define SEG_ACCESS_S_MASK 0x10
# define SEG_SYSTEM 0x00
# define SEG_NON_SYSTEM 0x10
#define SEG_TYPE_MASK 0x0f
#define SEG_DATA_A_BIT 0x1
#define SEG_DATA_W_BIT 0x2
#define SEG_DATA_E_BIT 0x4
#define SEG_CODE_A_BIT 0x1
#define SEG_CODE_R_BIT 0x2
#define SEG_CODE_C_BIT 0x4
#define SEG_DATA_RO 0x0
#define SEG_DATA_ROA 0x1
#define SEG_DATA_RW 0x2
#define SEG_DATA_RWA 0x3
#define SEG_DATA_RO_XD 0x4
#define SEG_DATA_RO_XDA 0x5
#define SEG_DATA_RW_XW 0x6
#define SEG_DATA_RW_XWA 0x7
#define SEG_CODE_XO 0x8
#define SEG_CODE_XOA 0x9
#define SEG_CODE_XR 0xa
#define SEG_CODE_XRA 0xb
#define SEG_CODE_XO_C 0xc
#define SEG_CODE_XO_CA 0xd
#define SEG_CODE_XR_C 0xe
#define SEG_CODE_XR_CA 0xf
#define SEG_TYPE_MASK 0x0f
# define SEG_DATA_A_BIT 0x1
# define SEG_DATA_W_BIT 0x2
# define SEG_DATA_E_BIT 0x4
# define SEG_CODE_A_BIT 0x1
# define SEG_CODE_R_BIT 0x2
# define SEG_CODE_C_BIT 0x4
# define SEG_DATA_RO 0x0
# define SEG_DATA_ROA 0x1
# define SEG_DATA_RW 0x2
# define SEG_DATA_RWA 0x3
# define SEG_DATA_RO_XD 0x4
# define SEG_DATA_RO_XDA 0x5
# define SEG_DATA_RW_XW 0x6
# define SEG_DATA_RW_XWA 0x7
# define SEG_CODE_XO 0x8
# define SEG_CODE_XOA 0x9
# define SEG_CODE_XR 0xa
# define SEG_CODE_XRA 0xb
# define SEG_CODE_XO_C 0xc
# define SEG_CODE_XO_CA 0xd
# define SEG_CODE_XR_C 0xe
# define SEG_CODE_XR_CA 0xf
/*
** Byte 6: sizes
@ -195,47 +197,48 @@
** 3-0: upper 4 bits of limit
** 7: base address 31:24
*/
#define SEG_SIZE_G_MASK 0x80
#define SEG_GRAN_BYTE 0x00
#define SEG_GRAN_4KBYTE 0x80
#define SEG_SIZE_G_MASK 0x80
# define SEG_GRAN_BYTE 0x00
# define SEG_GRAN_4KBYTE 0x80
#define SEG_SIZE_D_B_MASK 0x40
#define SEG_DB_16BIT 0x00
#define SEG_DB_32BIT 0x40
#define SEG_SIZE_D_B_MASK 0x40
# define SEG_DB_16BIT 0x00
# define SEG_DB_32BIT 0x40
#define SEG_SIZE_L_MASK 0x20
#define SEG_L_64BIT 0x20
#define SEG_L_32BIT 0x00
#define SEG_SIZE_L_MASK 0x20
# define SEG_L_64BIT 0x20
# define SEG_L_32BIT 0x00
#define SEG_SIZE_AVL_MASK 0x10
#define SEG_SIZE_AVL_MASK 0x10
#define SEG_SIZE_LIM_19_16_MASK 0x0f
/*
** System-segment and gate-descriptor types
**
** IA-32 V3, page 3-15.
*/
// type 0: reserved
// type 0: reserved
#define SEG_SYS_16BIT_TSS_AVAIL 0x1
#define SEG_SYS_LDT 0x2
#define SEG_SYS_16BIT_TSS_BUSY 0x3
#define SEG_SYS_LDT 0x2
#define SEG_SYS_16BIT_TSS_BUSY 0x3
#define SEG_SYS_16BIT_CALL_GATE 0x4
#define SEG_SYS_TASK_GATE 0x5
#define SEG_SYS_16BIT_INT_GATE 0x6
#define SEG_SYS_TASK_GATE 0x5
#define SEG_SYS_16BIT_INT_GATE 0x6
#define SEG_SYS_16BIT_TRAP_GATE 0x7
// type 8: reserved
// type 8: reserved
#define SEG_SYS_32BIT_TSS_AVAIL 0x9
// type A: reserved
#define SEG_SYS_32BIT_TSS_BUSY 0xb
// type A: reserved
#define SEG_SYS_32BIT_TSS_BUSY 0xb
#define SEG_SYS_32BIT_CALL_GATE 0xc
// type D: reserved
#define SEG_SYS_32BIT_INT_GATE 0xe
// type D: reserved
#define SEG_SYS_32BIT_INT_GATE 0xe
#define SEG_SYS_32BIT_TRAP_GATE 0xf
/*
** IDT Descriptors
**
**
** IA-32 V3, page 5-13.
**
** All have a segment selector in bytes 2 and 3; Task Gate descriptors
@ -243,57 +246,58 @@
** and 7 devoted to the 16 bits of the Offset, with the low nybble of
** byte 4 reserved.
*/
#define IDT_PRESENT 0x8000
#define IDT_DPL_MASK 0x6000
#define IDT_DPL_0 0x0000
#define IDT_DPL_1 0x2000
#define IDT_DPL_2 0x4000
#define IDT_DPL_3 0x6000
#define IDT_GATE_TYPE 0x0f00
#define IDT_TASK_GATE 0x0500
#define IDT_INT16_GATE 0x0600
#define IDT_INT32_GATE 0x0e00
#define IDT_TRAP16_GATE 0x0700
#define IDT_TRAP32_GATE 0x0f00
#define IDT_PRESENT 0x8000
#define IDT_DPL_MASK 0x6000
# define IDT_DPL_0 0x0000
# define IDT_DPL_1 0x2000
# define IDT_DPL_2 0x4000
# define IDT_DPL_3 0x6000
#define IDT_GATE_TYPE 0x0f00
# define IDT_TASK_GATE 0x0500
# define IDT_INT16_GATE 0x0600
# define IDT_INT32_GATE 0x0e00
# define IDT_TRAP16_GATE 0x0700
# define IDT_TRAP32_GATE 0x0f00
/*
** Interrupt vectors
*/
// predefined by the architecture
#define VEC_DIVIDE_ERROR 0x00
#define VEC_DEBUG_EXCEPTION 0x01
#define VEC_NMI_INTERRUPT 0x02
#define VEC_BREAKPOINT 0x03
#define VEC_OVERFLOW 0x04
#define VEC_BOUND_RANGE_EXCEEDED 0x05
#define VEC_INVALID_OPCODE 0x06
#define VEC_DEVICE_NOT_AVAILABLE 0x07
#define VEC_DOUBLE_FAULT 0x08
#define VEC_COPROCESSOR_OVERRUN 0x09
#define VEC_INVALID_TSS 0x0a
#define VEC_SEGMENT_NOT_PRESENT 0x0b
#define VEC_STACK_FAULT 0x0c
#define VEC_GENERAL_PROTECTION 0x0d
#define VEC_PAGE_FAULT 0x0e
#define VEC_DIVIDE_ERROR 0x00
#define VEC_DEBUG_EXCEPTION 0x01
#define VEC_NMI_INTERRUPT 0x02
#define VEC_BREAKPOINT 0x03
#define VEC_OVERFLOW 0x04
#define VEC_BOUND_RANGE_EXCEEDED 0x05
#define VEC_INVALID_OPCODE 0x06
#define VEC_DEVICE_NOT_AVAILABLE 0x07
#define VEC_DOUBLE_FAULT 0x08
#define VEC_COPROCESSOR_OVERRUN 0x09
#define VEC_INVALID_TSS 0x0a
#define VEC_SEGMENT_NOT_PRESENT 0x0b
#define VEC_STACK_FAULT 0x0c
#define VEC_GENERAL_PROTECTION 0x0d
#define VEC_PAGE_FAULT 0x0e
// 0x0f is reserved - unused
#define VEC_FPU_ERROR 0x10
#define VEC_ALIGNMENT_CHECK 0x11
#define VEC_MACHINE_CHECK 0x12
#define VEC_SIMD_FP_EXCEPTION 0x13
#define VEC_VIRT_EXCEPTION 0x14
#define VEC_CTRL_PROT_EXCEPTION 0x15
#define VEC_FPU_ERROR 0x10
#define VEC_ALIGNMENT_CHECK 0x11
#define VEC_MACHINE_CHECK 0x12
#define VEC_SIMD_FP_EXCEPTION 0x13
#define VEC_VIRT_EXCEPTION 0x14
#define VEC_CTRL_PROT_EXCEPTION 0x15
// 0x16 through 0x1f are reserved
// 0x20 through 0xff are user-defined, non-reserved
// IRQ0 through IRQ15 will use vectors 0x20 through 0x2f
#define VEC_TIMER 0x20
#define VEC_KBD 0x21
#define VEC_COM2 0x23
#define VEC_COM1 0x24
#define VEC_PARALLEL 0x25
#define VEC_FLOPPY 0x26
#define VEC_MYSTERY 0x27
#define VEC_MOUSE 0x2c
#define VEC_TIMER 0x20
#define VEC_KBD 0x21
#define VEC_COM2 0x23
#define VEC_COM1 0x24
#define VEC_PARALLEL 0x25
#define VEC_FLOPPY 0x26
#define VEC_MYSTERY 0x27
#define VEC_MOUSE 0x2c
#endif

View file

@ -0,0 +1,73 @@
/*
** @file bios.h
**
** @author Warren R. Carithers
**
** BIOS-related declarations
*/
#ifndef BIOS_H_
#define BIOS_H_
/*
** BIOS-related memory addresses
*/
#define BIOS_BDA 0x0400
/*
** Selected BIOS interrupt numbers
*/
#define BIOS_TIMER 0x08
#define BIOS_KBD 0x09
#define BIOS_VIDEO 0x10
#define BIOS_EQUIP 0x11
#define BIOS_MSIZ 0x12
#define BIOS_DISK 0x13
#define BIOS_SERIAL 0x14
#define BIOS_MISC 0x15
#define BIOS_KBDSVC 0x16
#define BIOS_PRTSVC 0x17
#define BIOS_BOOT 0x19
#define BIOS_RTCPCI 0x1a
// BIOS video commands (AH)
#define BV_W_ADV 0x0e
// BIOS disk commands (AH)
#define BD_RESET 0x00
#define BD_CHECK 0x01
#define BD_RDSECT 0x02
#define BD_WRSECT 0x03
#define BD_PARAMS 0x08
// BIOS disk commands with parameters (AX)
#define BD_READ(n) ((BD_RDSECT << 8) | (n))
#define BD_READ1 0x0201
// CMOS ports (used for masking NMIs)
#define CMOS_ADDR 0x70
#define CMOS_DATA 0x71
// important related commands
#define NMI_ENABLE 0x00
#define NMI_DISABLE 0x80
/*
** Physical Memory Map Table (0000:2D00 - 0000:7c00)
**
** Primarily used with the BIOS_MISC interrupt
*/
#define MMAP_SEG 0x02D0
#define MMAP_DISP 0x0000
#define MMAP_ADDR ((MMAP_SEG << 4) + MMAP_DISP)
#define MMAP_SECTORS 0x0a
#define MMAP_ENT 24 /* bytes per entry */
#define MMAP_MAX_ENTS (BOOT_ADDR - MMAP_ADDR - 4) / 24
#define MMAP_CODE 0xE820 /* int 0x15 code */
#define MMAP_MAGIC_NUM 0x534D4150 /* for 0xE820 interrupt */
#endif

View file

@ -10,7 +10,7 @@
** MIT's xv6, https://github.com/mit-pdos/xv6-public
**
** Note: normally, GCC doesn't inline unless the optimization level is
** over 1. This can be forced by adding
** over 1. This can be forced by adding
**
** __attribute__((always_inline))
**
@ -27,10 +27,10 @@
// control "forced" inlining
#ifdef FORCE_INLINING
#define OPSINLINED __attribute__((always_inline))
#define OPSINLINED __attribute__((always_inline))
#else
#define OPSINLINED /* no-op */
#endif /* FORCE_INLINING */
#define OPSINLINED /* no-op */
#endif /* FORCE_INLINING */
/****************************
** Data movement
@ -47,33 +47,36 @@
** @param src Source buffer
** @param len Byte count
*/
static inline void movsb(void *dst, const void *src, uint32_t len) OPSINLINED
static inline void
movsb( void* dst, const void* src, uint32_t len ) OPSINLINED
{
__asm__ __volatile__("cld; rep movsb"
: "+D"(dst), "+S"(src), "+c"(len)
:
: "memory");
__asm__ __volatile__( "cld; rep movsb"
: "+D"(dst), "+S"(src), "+c"(len)
: : "memory" );
}
static inline void movsw(void *dst, const void *src, uint32_t len) OPSINLINED
static inline void
movsw( void* dst, const void* src, uint32_t len ) OPSINLINED
{
__asm__ __volatile__("cld; rep movsw"
: "+D"(dst), "+S"(src), "+c"(len)
:
: "memory");
__asm__ __volatile__( "cld; rep movsw"
: "+D"(dst), "+S"(src), "+c"(len)
: : "memory" );
}
static inline void movsl(void *dst, const void *src, uint32_t len) OPSINLINED
static inline void
movsl( void* dst, const void* src, uint32_t len ) OPSINLINED
{
__asm__ __volatile__("cld; rep movsl"
: "+D"(dst), "+S"(src), "+c"(len)
:
: "memory");
__asm__ __volatile__( "cld; rep movsl"
: "+D"(dst), "+S"(src), "+c"(len)
: : "memory" );
}
static inline void movsq(void *dst, const void *src, uint32_t len) OPSINLINED
static inline void
movsq( void* dst, const void* src, uint32_t len ) OPSINLINED
{
__asm__ __volatile__("cld; rep movsq"
: "+D"(dst), "+S"(src), "+c"(len)
:
: "memory");
__asm__ __volatile__( "cld; rep movsq"
: "+D"(dst), "+S"(src), "+c"(len)
: : "memory" );
}
/**
@ -87,26 +90,31 @@ static inline void movsq(void *dst, const void *src, uint32_t len) OPSINLINED
** @param val Data to copy
** @param len Byte count
*/
static inline void stosb(void *dst, uint8_t val, uint32_t len) OPSINLINED
static inline void
stosb( void *dst, uint8_t val, uint32_t len ) OPSINLINED
{
__asm__ __volatile__("cld; rep stosb"
: "=D"(dst), "=c"(len)
: "0"(dst), "1"(len), "a"(val)
: "memory", "cc");
__asm__ __volatile__( "cld; rep stosb"
: "=D" (dst), "=c" (len)
: "0" (dst), "1" (len), "a" (val)
: "memory", "cc" );
}
static inline void stosw(void *dst, uint16_t val, uint32_t len) OPSINLINED
static inline void
stosw( void *dst, uint16_t val, uint32_t len ) OPSINLINED
{
__asm__ __volatile__("cld; rep stos2"
: "=D"(dst), "=c"(len)
: "0"(dst), "1"(len), "a"(val)
: "memory", "cc");
__asm__ __volatile__( "cld; rep stos2"
: "=D" (dst), "=c" (len)
: "0" (dst), "1" (len), "a" (val)
: "memory", "cc" );
}
static inline void stosl(void *dst, uint32_t val, uint32_t len) OPSINLINED
static inline void
stosl( void *dst, uint32_t val, uint32_t len ) OPSINLINED
{
__asm__ __volatile__("cld; rep stosl"
: "=D"(dst), "=c"(len)
: "0"(dst), "1"(len), "a"(val)
: "memory", "cc");
__asm__ __volatile__( "cld; rep stosl"
: "=D" (dst), "=c" (len)
: "0" (dst), "1" (len), "a" (val)
: "memory", "cc" );
}
/****************************
@ -123,46 +131,59 @@ static inline void stosl(void *dst, uint32_t val, uint32_t len) OPSINLINED
**
** @return Contents of the register
*/
static inline uint32_t r_cr0(void) OPSINLINED
static inline uint32_t
r_cr0( void ) OPSINLINED
{
uint32_t val;
__asm__ __volatile__("movl %%cr0,%0" : "=r"(val));
__asm__ __volatile__( "movl %%cr0,%0" : "=r" (val) );
return val;
}
static inline uint32_t r_cr2(void) OPSINLINED
static inline uint32_t
r_cr2( void ) OPSINLINED
{
uint32_t val;
__asm__ __volatile__("movl %%cr2,%0" : "=r"(val));
__asm__ __volatile__( "movl %%cr2,%0" : "=r" (val) );
return val;
}
static inline uint32_t r_cr3(void) OPSINLINED
static inline uint32_t
r_cr3( void ) OPSINLINED
{
uint32_t val;
__asm__ __volatile__("movl %%cr3,%0" : "=r"(val));
__asm__ __volatile__( "movl %%cr3,%0" : "=r" (val) );
return val;
}
static inline uint32_t r_cr4(void) OPSINLINED
static inline uint32_t
r_cr4( void ) OPSINLINED
{
uint32_t val;
__asm__ __volatile__("movl %%cr4,%0" : "=r"(val));
__asm__ __volatile__( "movl %%cr4,%0" : "=r" (val) );
return val;
}
static inline uint32_t r_eflags(void) OPSINLINED
static inline uint32_t
r_eflags(void) OPSINLINED
{
uint32_t val;
__asm__ __volatile__("pushfl; popl %0" : "=r"(val));
__asm__ __volatile__( "pushfl; popl %0" : "=r" (val) );
return val;
}
static inline uint32_t r_ebp(void) OPSINLINED
static inline uint32_t
r_ebp(void) OPSINLINED
{
uint32_t val;
__asm__ __volatile__("movl %%ebp,%0" : "=r"(val));
__asm__ __volatile__( "movl %%ebp,%0" : "=r" (val) );
return val;
}
static inline uint32_t r_esp(void) OPSINLINED
static inline uint32_t
r_esp(void) OPSINLINED
{
uint32_t val;
__asm__ __volatile__("movl %%esp,%0" : "=r"(val));
__asm__ __volatile__( "movl %%esp,%0" : "=r" (val) );
return val;
}
@ -173,25 +194,34 @@ static inline uint32_t r_esp(void) OPSINLINED
**
** Description: Writes a value into the CR indicated by its name
*/
static inline void w_cr0(uint32_t val) OPSINLINED
static inline void
w_cr0( uint32_t val ) OPSINLINED
{
__asm__ __volatile__("movl %0,%%cr0" : : "r"(val));
__asm__ __volatile__( "movl %0,%%cr0" : : "r" (val) );
}
static inline void w_cr2(uint32_t val) OPSINLINED
static inline void
w_cr2( uint32_t val ) OPSINLINED
{
__asm__ __volatile__("movl %0,%%cr2" : : "r"(val));
__asm__ __volatile__( "movl %0,%%cr2" : : "r" (val) );
}
static inline void w_cr3(uint32_t val) OPSINLINED
static inline void
w_cr3( uint32_t val ) OPSINLINED
{
__asm__ __volatile__("movl %0,%%cr3" : : "r"(val));
__asm__ __volatile__( "movl %0,%%cr3" : : "r" (val) );
}
static inline void w_cr4(uint32_t val) OPSINLINED
static inline void
w_cr4( uint32_t val ) OPSINLINED
{
__asm__ __volatile__("movl %0,%%cr4" : : "r"(val));
__asm__ __volatile__( "movl %0,%%cr4" : : "r" (val) );
}
static inline void w_eflags(uint32_t eflags) OPSINLINED
static inline void
w_eflags(uint32_t eflags) OPSINLINED
{
__asm__ __volatile__("pushl %0; popfl" : : "r"(eflags));
__asm__ __volatile__( "pushl %0; popfl" : : "r" (eflags) );
}
/**
@ -203,13 +233,16 @@ static inline void w_eflags(uint32_t eflags) OPSINLINED
**
** @param addr The value to be loaded into the register
*/
static inline void w_gdt(void *addr) OPSINLINED
static inline void
w_gdt( void *addr ) OPSINLINED
{
__asm__ __volatile__("lgdt (%0)" : : "r"(addr));
__asm__ __volatile__( "lgdt (%0)" : : "r" (addr) );
}
static inline void w_idt(void *addr) OPSINLINED
static inline void
w_idt( void *addr ) OPSINLINED
{
__asm__ __volatile__("lidt (%0)" : : "r"(addr));
__asm__ __volatile__( "lidt (%0)" : : "r" (addr) );
}
/**
@ -223,21 +256,19 @@ static inline void w_idt(void *addr) OPSINLINED
** @param cp Pointer to where %ecx contents should be saved, or NULL
** @param dp Pointer to where %edx contents should be saved, or NULL
*/
static inline void cpuid(uint32_t op, uint32_t *ap, uint32_t *bp, uint32_t *cp,
uint32_t *dp) OPSINLINED
static inline void
cpuid( uint32_t op, uint32_t *ap, uint32_t *bp,
uint32_t *cp, uint32_t *dp ) OPSINLINED
{
uint32_t eax, ebx, ecx, edx;
__asm__ __volatile__("cpuid"
: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
: "a"(op));
if (ap)
*ap = eax;
if (bp)
*bp = ebx;
if (cp)
*cp = ecx;
if (dp)
*dp = edx;
__asm__ __volatile__( "cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "a" (op) );
if( ap ) *ap = eax;
if( bp ) *bp = ebx;
if( cp ) *cp = ecx;
if( dp ) *dp = edx;
}
/****************************
@ -251,9 +282,10 @@ static inline void cpuid(uint32_t op, uint32_t *ap, uint32_t *bp, uint32_t *cp,
**
** @param addr An address within the page to be flushed
*/
static inline void invlpg(uint32_t addr) OPSINLINED
static inline void
invlpg( uint32_t addr ) OPSINLINED
{
__asm__ __volatile__("invlpg (%0)" : : "r"(addr) : "memory");
__asm__ __volatile__( "invlpg (%0)" : : "r" (addr) : "memory" );
}
/**
@ -263,11 +295,12 @@ static inline void invlpg(uint32_t addr) OPSINLINED
**
** We do this by changing CR3.
*/
static inline void flushtlb(void) OPSINLINED
static inline void
flushtlb( void ) OPSINLINED
{
uint32_t cr3;
__asm__ __volatile__("movl %%cr3,%0" : "=r"(cr3));
__asm__ __volatile__("movl %0,%%cr2" : : "r"(cr3));
__asm__ __volatile__( "movl %%cr3,%0" : "=r" (cr3) );
__asm__ __volatile__( "movl %0,%%cr2" : : "r" (cr3) );
}
/****************************
@ -285,22 +318,27 @@ static inline void flushtlb(void) OPSINLINED
**
** @return The data read from the specified port
*/
static inline uint8_t inb(int port) OPSINLINED
static inline uint8_t
inb( int port ) OPSINLINED
{
uint8_t data;
__asm__ __volatile__("inb %w1,%0" : "=a"(data) : "d"(port));
__asm__ __volatile__( "inb %w1,%0" : "=a" (data) : "d" (port) );
return data;
}
static inline uint16_t inw(int port) OPSINLINED
static inline uint16_t
inw( int port ) OPSINLINED
{
uint16_t data;
__asm__ __volatile__("inw %w1,%0" : "=a"(data) : "d"(port));
__asm__ __volatile__( "inw %w1,%0" : "=a" (data) : "d" (port) );
return data;
}
static inline uint32_t inl(int port) OPSINLINED
static inline uint32_t
inl( int port ) OPSINLINED
{
uint32_t data;
__asm__ __volatile__("inl %w1,%0" : "=a"(data) : "d"(port));
__asm__ __volatile__( "inl %w1,%0" : "=a" (data) : "d" (port) );
return data;
}
@ -316,17 +354,22 @@ static inline uint32_t inl(int port) OPSINLINED
**
** @return The data read from the specified port
*/
static inline void outb(int port, uint8_t data) OPSINLINED
static inline void
outb( int port, uint8_t data ) OPSINLINED
{
__asm__ __volatile__("outb %0,%w1" : : "a"(data), "d"(port));
__asm__ __volatile__( "outb %0,%w1" : : "a" (data), "d" (port) );
}
static inline void outw(int port, uint16_t data) OPSINLINED
static inline void
outw( int port, uint16_t data ) OPSINLINED
{
__asm__ __volatile__("outw %0,%w1" : : "a"(data), "d"(port));
__asm__ __volatile__( "outw %0,%w1" : : "a" (data), "d" (port) );
}
static inline void outl(int port, uint32_t data) OPSINLINED
static inline void
outl( int port, uint32_t data ) OPSINLINED
{
__asm__ __volatile__("outl %0,%w1" : : "a"(data), "d"(port));
__asm__ __volatile__( "outl %0,%w1" : : "a" (data), "d" (port) );
}
/****************************
@ -338,9 +381,10 @@ static inline void outl(int port, uint32_t data) OPSINLINED
**
** Description: Cause a breakpoint interrupt for debugging purposes
*/
static inline void breakpoint(void) OPSINLINED
static inline void
breakpoint( void ) OPSINLINED
{
__asm__ __volatile__("int3");
__asm__ __volatile__( "int3" );
}
/**
@ -351,10 +395,11 @@ static inline void breakpoint(void) OPSINLINED
**
** @return The address the calling routine will return to as a uint32_t
*/
static inline uint32_t get_ra(void) OPSINLINED
static inline uint32_t
get_ra( void ) OPSINLINED
{
uint32_t val;
__asm__ __volatile__("movl 4(%%ebp),%0" : "=r"(val));
__asm__ __volatile__( "movl 4(%%ebp),%0" : "=r" (val) );
return val;
}
@ -363,11 +408,13 @@ static inline uint32_t get_ra(void) OPSINLINED
**
** Description: Pause until something happens
*/
static inline void ev_wait(void) OPSINLINED
static inline void
ev_wait( void ) OPSINLINED
{
__asm__ __volatile__("sti ; hlt");
__asm__ __volatile__( "sti ; hlt" );
}
/**
** Name: xchgl
**
@ -378,18 +425,19 @@ static inline void ev_wait(void) OPSINLINED
**
** @return The old contents of the memory location
*/
static inline uint32_t xchgl(volatile uint32_t *addr, uint32_t data) OPSINLINED
static inline uint32_t
xchgl( volatile uint32_t *addr, uint32_t data ) OPSINLINED
{
uint32_t old;
// + indicates a read-modify-write operand
__asm__ __volatile__("lock; xchgl %0, %1"
: "+m"(*addr), "=a"(old)
: "1"(data)
: "cc");
__asm__ __volatile__( "lock; xchgl %0, %1"
: "+m" (*addr), "=a" (old)
: "1" (data)
: "cc");
return old;
}
#endif /* !ASM_SRC */
#endif /* !ASM_SRC */
#endif

View file

@ -16,14 +16,15 @@
** Our expected configuration is two PICs, with the secondary connected
** through the IRQ2 pin of the primary.
*/
/*
** Port addresses for the command port and interrupt mask register port
** for both the primary and secondary PICs.
*/
#define PIC1_CMD 0x20 // primary command
#define PIC1_DATA (PIC1_CMD + 1) // primary data / int mask register
#define PIC2_CMD 0xA0 // secondary command
#define PIC2_DATA (PIC2_CMD + 1) // secondary data / int mask register
#define PIC1_CMD 0x20 // primary command
#define PIC1_DATA (PIC1_CMD + 1) // primary data / int mask register
#define PIC2_CMD 0xA0 // secondary command
#define PIC2_DATA (PIC2_CMD + 1) // secondary data / int mask register
/*
** Initialization Command Word (ICW) definitions
@ -41,96 +42,98 @@
** PIC2_* defines are intended for the secondary PIC
** PIC_* defines are sent to both PICs
*/
/*
** ICW1: initialization, send to command port
*/
#define PIC_CW1_INIT 0x10 // start initialization sequence
#define PIC_CW1_NEED4 0x01 // ICW4 will also be set
#define PIC_CW1_SINGLE 0x02 // select single (vs. cascade) mode
#define PIC_CW1_INTVAL 0x04 // set call interval to 4 (vs. 8)
#define PIC_CW1_LEVEL 0x08 // use level-triggered mode (vs. edge)
#define PIC_CW1_INIT 0x10 // start initialization sequence
#define PIC_CW1_NEED4 0x01 // ICW4 will also be set
#define PIC_CW1_SINGLE 0x02 // select single (vs. cascade) mode
#define PIC_CW1_INTVAL 0x04 // set call interval to 4 (vs. 8)
#define PIC_CW1_LEVEL 0x08 // use level-triggered mode (vs. edge)
/*
** ICW2: interrupt vector base offsets, send to data port
*/
#define PIC1_CW2_VECBASE 0x20 // IRQ0 int vector number
#define PIC2_CW2_VECBASE 0x28 // IRQ8 int vector number
#define PIC1_CW2_VECBASE 0x20 // IRQ0 int vector number
#define PIC2_CW2_VECBASE 0x28 // IRQ8 int vector number
/*
** ICW3: secondary::primary attachment, send to data port
*/
#define PIC1_CW3_SEC_IRQ2 0x04 // bit mask: secondary is on pin 2
#define PIC2_CW3_SEC_ID 0x02 // integer: secondary id
#define PIC1_CW3_SEC_IRQ2 0x04 // bit mask: secondary is on pin 2
#define PIC2_CW3_SEC_ID 0x02 // integer: secondary id
/*
** ICW4: operating mode, send to data port
*/
#define PIC_CW4_PM86 0x01 // 8086 mode (vs. 8080/8085)
#define PIC_CW4_AUTOEOI 0x02 // do auto eoi's
#define PIC_CW4_UNBUF 0x00 // unbuffered mode
#define PIC_CW4_SEC_BUF 0x08 // put secondary in buffered mode
#define PIC_CW4_PRI_BUF 0x0C // put primary in buffered mode
#define PIC_CW4_SFNMODE 0x10 // "special fully nested" mode
#define PIC_CW4_PM86 0x01 // 8086 mode (vs. 8080/8085)
#define PIC_CW4_AUTOEOI 0x02 // do auto eoi's
#define PIC_CW4_UNBUF 0x00 // unbuffered mode
#define PIC_CW4_SEC_BUF 0x08 // put secondary in buffered mode
#define PIC_CW4_PRI_BUF 0x0C // put primary in buffered mode
#define PIC_CW4_SFNMODE 0x10 // "special fully nested" mode
/*
** Operation Control Words (OCWs)
**
** After the init sequence, can send these
*/
/*
** OCW1: interrupt mask; send to data port
*/
#define PIC_MASK_NONE 0x00 // allow all interrupts
#define PIC_MASK_NO_IRQ0 0x01 // prevent IRQ0 interrupts
#define PIC_MASK_NO_IRQ1 0x02 // prevent IRQ1 interrupts
#define PIC_MASK_NO_IRQ2 0x04 // prevent IRQ2 interrupts
#define PIC_MASK_NO_IRQ3 0x08 // prevent IRQ3 interrupts
#define PIC_MASK_NO_IRQ4 0x10 // prevent IRQ4 interrupts
#define PIC_MASK_NO_IRQ5 0x20 // prevent IRQ5 interrupts
#define PIC_MASK_NO_IRQ6 0x40 // prevent IRQ6 interrupts
#define PIC_MASK_NO_IRQ7 0x80 // prevent IRQ7 interrupts
#define PIC_MASK_ALL 0xff // prevent all interrupts
#define PIC_MASK_NONE 0x00 // allow all interrupts
#define PIC_MASK_NO_IRQ0 0x01 // prevent IRQ0 interrupts
#define PIC_MASK_NO_IRQ1 0x02 // prevent IRQ1 interrupts
#define PIC_MASK_NO_IRQ2 0x04 // prevent IRQ2 interrupts
#define PIC_MASK_NO_IRQ3 0x08 // prevent IRQ3 interrupts
#define PIC_MASK_NO_IRQ4 0x10 // prevent IRQ4 interrupts
#define PIC_MASK_NO_IRQ5 0x20 // prevent IRQ5 interrupts
#define PIC_MASK_NO_IRQ6 0x40 // prevent IRQ6 interrupts
#define PIC_MASK_NO_IRQ7 0x80 // prevent IRQ7 interrupts
#define PIC_MASK_ALL 0xff // prevent all interrupts
/*
** OCW2: EOI control, interrupt level; send to command port
*/
#define PIC_LVL_0 0x00 // act on IRQ level 0
#define PIC_LVL_1 0x01 // act on IRQ level 1
#define PIC_LVL_2 0x02 // act on IRQ level 2
#define PIC_LVL_3 0x03 // act on IRQ level 3
#define PIC_LVL_4 0x04 // act on IRQ level 4
#define PIC_LVL_5 0x05 // act on IRQ level 5
#define PIC_LVL_6 0x06 // act on IRQ level 6
#define PIC_LVL_7 0x07 // act on IRQ level 7
#define PIC_LVL_0 0x00 // act on IRQ level 0
#define PIC_LVL_1 0x01 // act on IRQ level 1
#define PIC_LVL_2 0x02 // act on IRQ level 2
#define PIC_LVL_3 0x03 // act on IRQ level 3
#define PIC_LVL_4 0x04 // act on IRQ level 4
#define PIC_LVL_5 0x05 // act on IRQ level 5
#define PIC_LVL_6 0x06 // act on IRQ level 6
#define PIC_LVL_7 0x07 // act on IRQ level 7
#define PIC_EOI_NON_SPEC 0x20 // non-specific EOI command
#define PIC_EOI PIC_EOI_NON_SPEC
#define PIC_EOI_NON_SPEC 0x20 // non-specific EOI command
# define PIC_EOI PIC_EOI_NON_SPEC
#define PIC_EOI_SPEC 0x60 // specific EOI command
#define PIC_SEOI PIC_EOI_SPEC
#define PIC_SEOI_LVL0 (PIC_EOI_SPEC | PIC_LVL_0)
#define PIC_SEOI_LVL1 (PIC_EOI_SPEC | PIC_LVL_1)
#define PIC_SEOI_LVL2 (PIC_EOI_SPEC | PIC_LVL_2)
#define PIC_SEOI_LVL3 (PIC_EOI_SPEC | PIC_LVL_3)
#define PIC_SEOI_LVL4 (PIC_EOI_SPEC | PIC_LVL_4)
#define PIC_SEOI_LVL5 (PIC_EOI_SPEC | PIC_LVL_5)
#define PIC_SEOI_LVL6 (PIC_EOI_SPEC | PIC_LVL_6)
#define PIC_SEOI_LVL7 (PIC_EOI_SPEC | PIC_LVL_7)
#define PIC_EOI_SPEC 0x60 // specific EOI command
# define PIC_SEOI PIC_EOI_SPEC
# define PIC_SEOI_LVL0 (PIC_EOI_SPEC | PIC_LVL_0)
# define PIC_SEOI_LVL1 (PIC_EOI_SPEC | PIC_LVL_1)
# define PIC_SEOI_LVL2 (PIC_EOI_SPEC | PIC_LVL_2)
# define PIC_SEOI_LVL3 (PIC_EOI_SPEC | PIC_LVL_3)
# define PIC_SEOI_LVL4 (PIC_EOI_SPEC | PIC_LVL_4)
# define PIC_SEOI_LVL5 (PIC_EOI_SPEC | PIC_LVL_5)
# define PIC_SEOI_LVL6 (PIC_EOI_SPEC | PIC_LVL_6)
# define PIC_SEOI_LVL7 (PIC_EOI_SPEC | PIC_LVL_7)
#define PIC_EOI_ROT_NONSP 0xa0 // rotate on non-spec EOI cmd
#define PIC_EOI_SET_ROT_AUTO 0x80 // set "rotate in auto EOI mode"
#define PIC_EOI_CLR_ROT_AUTO 0x00 // clear "rotate in auto EOI mode"
#define PIC_EOI_ROT_SPEC 0xe0 // rotate on spec EOI cmd (+ level)
#define PIC_EOI_SET_PRIO 0xc0 // set priority (+ level)
#define PIC_EOI_NOP 0x40 // no operation
#define PIC_EOI_ROT_NONSP 0xa0 // rotate on non-spec EOI cmd
#define PIC_EOI_SET_ROT_AUTO 0x80 // set "rotate in auto EOI mode"
#define PIC_EOI_CLR_ROT_AUTO 0x00 // clear "rotate in auto EOI mode"
#define PIC_EOI_ROT_SPEC 0xe0 // rotate on spec EOI cmd (+ level)
#define PIC_EOI_SET_PRIO 0xc0 // set priority (+ level)
#define PIC_EOI_NOP 0x40 // no operation
/*
** OCW3: read requests, special mask mode; send to command port
** OCW3: read requests, special mask mode; send to command port
*/
#define PIC_READIRR 0x0a // read the IR register
#define PIC_READISR 0x0b // read the IS register
#define PIC_POLL 0x0c // poll
#define PIC_MASK_RESET 0x48 // reset special mask mode
#define PIC_MASK_SET 0x68 // set special mask mode
#define PIC_READIRR 0x0a // read the IR register
#define PIC_READISR 0x0b // read the IS register
#define PIC_POLL 0x0c // poll
#define PIC_MASK_RESET 0x48 // reset special mask mode
#define PIC_MASK_SET 0x68 // set special mask mode
#endif

View file

@ -12,6 +12,7 @@
#ifndef X86PIT_H_
#define X86PIT_H_
/*
** Hardware timer (Intel 8254 Programmable Interval Timer)
**
@ -25,57 +26,57 @@
** M - mode
** BCD - binary or BCD counter
*/
/* Frequency settings */
#define PIT_DEFAULT_TICKS_PER_SECOND 18 // actually 18.2065Hz
#define PIT_DEFAULT_MS_PER_TICK (1000 / PIT_DEFAULT_TICKS_PER_SECOND)
#define PIT_FREQ 1193182 // clock cycles/sec
#define PIT_DEFAULT_TICKS_PER_SECOND 18 // actually 18.2065Hz
#define PIT_DEFAULT_MS_PER_TICK (1000/PIT_DEFAULT_TICKS_PER_SECOND)
#define PIT_FREQ 1193182 // clock cycles/sec
/* Port assignments */
#define PIT_BASE_PORT 0x40 // I/O port for the timer
#define PIT_0_PORT (PIT_BASE_PORT)
#define PIT_1_PORT (PIT_BASE_PORT + 1)
#define PIT_2_PORT (PIT_BASE_PORT + 2)
#define PIT_CONTROL_PORT (PIT_BASE_PORT + 3)
#define PIT_BASE_PORT 0x40 // I/O port for the timer
# define PIT_0_PORT (PIT_BASE_PORT)
# define PIT_1_PORT (PIT_BASE_PORT+1)
# define PIT_2_PORT (PIT_BASE_PORT+2)
# define PIT_CONTROL_PORT (PIT_BASE_PORT+3)
/* BCD field */
#define PIT_USE_DECIMAL 0x00 // 16-bit binary counter (default)
#define PIT_USE_BCD 0x01 // BCD counter
#define PIT_USE_DECIMAL 0x00 // 16-bit binary counter (default)
#define PIT_USE_BCD 0x01 // BCD counter
/* Timer modes */
#define PIT_MODE_0 0x00 // int on terminal count
#define PIT_MODE_1 0x02 // one-shot
#define PIT_MODE_2 0x04 // divide-by-N
#define PIT_MODE_3 0x06 // square-wave
#define PIT_MODE_4 0x08 // software strobe
#define PIT_MODE_5 0x0a // hardware strobe
#define PIT_MODE_0 0x00 // int on terminal count
#define PIT_MODE_1 0x02 // one-shot
#define PIT_MODE_2 0x04 // divide-by-N
#define PIT_MODE_3 0x06 // square-wave
#define PIT_MODE_4 0x08 // software strobe
#define PIT_MODE_5 0x0a // hardware strobe
/* Timer 0 settings */
#define PIT_0_SELECT 0x00 // select timer 0
#define PIT_0_LOAD 0x30 // load LSB, then MSB
#define PIT_0_NDIV PIT_MODE_2 // divide-by-N counter
#define PIT_0_SQUARE PIT_MODE_3 // square-wave mode
#define PIT_0_ENDSIGNAL 0x00 // assert OUT at end of count
#define PIT_0_SELECT 0x00 // select timer 0
#define PIT_0_LOAD 0x30 // load LSB, then MSB
#define PIT_0_NDIV PIT_MODE_2 // divide-by-N counter
#define PIT_0_SQUARE PIT_MODE_3 // square-wave mode
#define PIT_0_ENDSIGNAL 0x00 // assert OUT at end of count
/* Timer 1 settings */
#define PIT_1_SELECT 0x40 // select timer 1
#define PIT_1_READ 0x30 // read/load LSB then MSB
#define PIT_1_RATE 0x06 // square-wave, for USART
#define PIT_1_SELECT 0x40 // select timer 1
#define PIT_1_READ 0x30 // read/load LSB then MSB
#define PIT_1_RATE 0x06 // square-wave, for USART
/* Timer 2 settings */
#define PIT_2_SELECT 0x80 // select timer 1
#define PIT_2_READ 0x30 // read/load LSB then MSB
#define PIT_2_RATE 0x06 // square-wave, for USART
#define PIT_2_SELECT 0x80 // select timer 1
#define PIT_2_READ 0x30 // read/load LSB then MSB
#define PIT_2_RATE 0x06 // square-wave, for USART
/* Timer read-back */
#define PIT_READBACK 0xc0 // perform a read-back
#define PIT_RB_NOT_COUNT 0x20 // don't latch the count
#define PIT_RB_NOT_STATUS 0x10 // don't latch the status
#define PIT_RB_CHAN_2 0x08 // read back channel 2
#define PIT_RB_CHAN_1 0x04 // read back channel 1
#define PIT_RB_CHAN_0 0x02 // read back channel 0
#define PIT_RB_ACCESS_MASK 0x30 // access mode field
#define PIT_RB_OP_MASK 0x0e // oper mode field
#define PIT_RB_BCD_MASK 0x01 // BCD mode field
#define PIT_READBACK 0xc0 // perform a read-back
#define PIT_RB_NOT_COUNT 0x20 // don't latch the count
#define PIT_RB_NOT_STATUS 0x10 // don't latch the status
#define PIT_RB_CHAN_2 0x08 // read back channel 2
#define PIT_RB_CHAN_1 0x04 // read back channel 1
#define PIT_RB_CHAN_0 0x02 // read back channel 0
#define PIT_RB_ACCESS_MASK 0x30 // access mode field
#define PIT_RB_OP_MASK 0x0e // oper mode field
#define PIT_RB_BCD_MASK 0x01 // BCD mode field
#endif

View file

@ -20,7 +20,7 @@
*/
#ifndef UART_H
#define UART_H
#define UART_H
/*********************************************************************
***************************** I/O PORTS ******************************
@ -29,14 +29,14 @@
/*
** Base port number assigned to the device
*/
#define UA4_COM1_PORT 0x3f8
#define UA4_COM2_PORT 0x2f8
#define UA4_COM3_PORT 0x3e8
#define UA4_COM4_PORT 0x2e8
#define UA4_COM1_PORT 0x3f8
#define UA4_COM2_PORT 0x2f8
#define UA4_COM3_PORT 0x3e8
#define UA4_COM4_PORT 0x2e8
// short name for the one we'll use
#define UA4_PORT UA4_COM1_PORT
#define UA5_PORT UA4_COM1_PORT
#define UA4_PORT UA4_COM1_PORT
#define UA5_PORT UA4_COM1_PORT
/*
** Registers
@ -47,7 +47,7 @@
** Index Register(s)
** ===== =========================================
** 0 Receiver Data (RO), Transmitter Data (WO)
** 1 Interrupt Enable
** 1 Interrupt Enable
** 2 Interrupt ID (RO), FIFO Control (WO)
** 3 Line Control, Divisor Latch
** 4 Modem Control
@ -66,156 +66,157 @@
** accessed (0 selects Line Control, 1 selects Divisor Latch), with the
** remaining bits selecting fields within the indicated register.
*/
/*
** Receiver Data Register (read-only)
*/
#define UA4_RXD (UA4_PORT + 0)
#define UA4_RX_DATA UA4_RXD
#define UA4_RXD (UA4_PORT+0)
# define UA4_RX_DATA UA4_RXD
/*
** Transmitter Data Register (write-only)
*/
#define UA4_TXD (UA4_PORT + 0)
#define UA4_TX_DATA UA4_TXD
#define UA4_TXD (UA4_PORT+0)
# define UA4_TX_DATA UA4_TXD
/*
** Interrupt Enable Register
*/
#define UA4_IER (UA4_PORT + 1)
#define UA4_INT_ENABLE_REG UA4_IER
#define UA4_IER (UA4_PORT+1)
# define UA4_INT_ENABLE_REG UA4_IER
// fields
#define UA4_IER_RX_IE 0x01 // Rcvr High-Data-Level Int Enable
#define UA4_IER_TX_IE 0x02 // Xmitter Low-data-level Int Enable
#define UA4_IER_LS_IE 0x04 // Line Status Int Enable
#define UA4_IER_MS_IE 0x08 // Modem Status Int Enable
#define UA4_IER_RX_IE 0x01 // Rcvr High-Data-Level Int Enable
#define UA4_IER_TX_IE 0x02 // Xmitter Low-data-level Int Enable
#define UA4_IER_LS_IE 0x04 // Line Status Int Enable
#define UA4_IER_MS_IE 0x08 // Modem Status Int Enable
// aliases
#define UA4_IER_RX_INT_ENABLE UA4_IER_RX_IE
#define UA4_IER_TX_INT_ENABLE UA4_IER_TX_IE
#define UA4_IER_LINE_STATUS_INT_ENABLE UA4_IER_LS_IE
#define UA4_IER_MODEM_STATUS_INT_ENABLE UA4_IER_MS_IE
#define UA4_IER_RX_INT_ENABLE UA4_IER_RX_IE
#define UA4_IER_TX_INT_ENABLE UA4_IER_TX_IE
#define UA4_IER_LINE_STATUS_INT_ENABLE UA4_IER_LS_IE
#define UA4_IER_MODEM_STATUS_INT_ENABLE UA4_IER_MS_IE
/*
** Interrupt Identification Register (read-only)
**
** a.k.a. Event Identification Register
*/
#define UA4_IIR (UA4_PORT + 2)
#define UA4_EVENT_ID UA4_IIR
#define UA4_IIR (UA4_PORT+2)
# define UA4_EVENT_ID UA4_IIR
// fields
#define UA4_IIR_IPF 0x01 // Interrupt Pending flag
#define UA4_IIR_IPF 0x01 // Interrupt Pending flag
#define UA4_IIR_IPR_MASK 0x06 // Interrupt Priority mask
#define UA4_IIR_IPR0_MASK 0x02 // IPR bit 0 mask
#define UA4_IIR_IPR1_MASK 0x04 // IPR bit 1 mask
#define UA4_IIR_IPR_MASK 0x06 // Interrupt Priority mask
# define UA4_IIR_IPR0_MASK 0x02 // IPR bit 0 mask
# define UA4_IIR_IPR1_MASK 0x04 // IPR bit 1 mask
#define UA5_IIR_RXFT 0x08 // RX_FIFO Timeout
#define UA5_IIR_FEN0 0x40 // FIFOs Enabled
#define UA5_IIR_FEN1 0x80 // FIFOs Enabled
#define UA5_IIR_RXFT 0x08 // RX_FIFO Timeout
#define UA5_IIR_FEN0 0x40 // FIFOs Enabled
#define UA5_IIR_FEN1 0x80 // FIFOs Enabled
// aliases
#define UA4_IIR_INT_PENDING UA4_IIR_IPF
#define UA4_IIR_INT_PRIORITY UA4_IIR_IPR
#define UA5_IIR_RX_FIFO_TIMEOUT UA5_IIR_RXFT
#define UA5_IIR_FIFO_ENABLED_0 UA5_IIR_FEN0
#define UA5_IIR_FIFO_ENABLED_1 UA5_IIR_FEN1
#define UA4_IIR_INT_PENDING UA4_IIR_IPF
#define UA4_IIR_INT_PRIORITY UA4_IIR_IPR
#define UA5_IIR_RX_FIFO_TIMEOUT UA5_IIR_RXFT
#define UA5_IIR_FIFO_ENABLED_0 UA5_IIR_FEN0
#define UA5_IIR_FIFO_ENABLED_1 UA5_IIR_FEN1
// IIR interrupt priorities (four-bit values)
#define UA4_IIR_INT_PRI_MASK 0x0f // Mask for extracting int priority
#define UA4_IIR_NO_INT 0x01 // no interrupt
#define UA4_IIR_LINE_STATUS 0x06 // line status interrupt
#define UA4_IIR_RX 0x04 // Receiver High Data Level
#define UA5_IIR_RX_FIFO 0x0c // Receiver FIFO timeout (16550)
#define UA4_IIR_TX 0x02 // Transmitter Low Data level
#define UA4_IIR_MODEM_STATUS 0x00 // Modem Status
#define UA4_IIR_INT_PRI_MASK 0x0f // Mask for extracting int priority
# define UA4_IIR_NO_INT 0x01 // no interrupt
# define UA4_IIR_LINE_STATUS 0x06 // line status interrupt
# define UA4_IIR_RX 0x04 // Receiver High Data Level
# define UA5_IIR_RX_FIFO 0x0c // Receiver FIFO timeout (16550)
# define UA4_IIR_TX 0x02 // Transmitter Low Data level
# define UA4_IIR_MODEM_STATUS 0x00 // Modem Status
// aliases
#define UA4_IIR_NO_INT_PENDING UA4_IIR_NO_INT
#define UA4_IIR_LINE_STATUS_INT_PENDING UA4_IIR_LINE_STATUS
#define UA4_IIR_RX_INT_PENDING UA4_IIR_RX
#define UA5_IIR_RX_FIFO_TIMEOUT_INT_PENDING UA5_IIR_RX_FIFO
#define UA4_IIR_TX_INT_PENDING UA4_IIR_TX
#define UA4_IIR_MODEM_STATUS_INT_PENDING UA4_IIR_MODEM_STATUS
#define UA4_IIR_NO_INT_PENDING UA4_IIR_NO_INT
#define UA4_IIR_LINE_STATUS_INT_PENDING UA4_IIR_LINE_STATUS
#define UA4_IIR_RX_INT_PENDING UA4_IIR_RX
#define UA5_IIR_RX_FIFO_TIMEOUT_INT_PENDING UA5_IIR_RX_FIFO
#define UA4_IIR_TX_INT_PENDING UA4_IIR_TX
#define UA4_IIR_MODEM_STATUS_INT_PENDING UA4_IIR_MODEM_STATUS
/*
** FIFO Control Register (16550 only, write-only)
*/
#define UA5_FCR (UA5_PORT + 2)
#define UA5_FIFO_CTL UA5_FCR
#define UA5_FCR (UA5_PORT+2)
# define UA5_FIFO_CTL UA5_FCR
#define UA5_FCR_FIFO_RESET 0x00 // Reset the FIFO
#define UA5_FCR_FIFO_EN 0x01 // FIFO Enable
#define UA5_FCR_RXSR 0x02 // Receiver Soft Reset
#define UA5_FCR_TXSR 0x04 // Transmitter Soft Reset
#define UA5_FCR_FIFO_RESET 0x00 // Reset the FIFO
#define UA5_FCR_FIFO_EN 0x01 // FIFO Enable
#define UA5_FCR_RXSR 0x02 // Receiver Soft Reset
#define UA5_FCR_TXSR 0x04 // Transmitter Soft Reset
#define UA5_FCR_TXFT_MASK 0x30 // TX_FIFO threshold level mask
#define UA5_FCR_TXFT0_MASK 0x10 // TXFT bit 0 mask
#define UA5_FCR_TXFT1_MASK 0x20 // TXFT bit 1 mask
#define UA5_FCR_TX_FIFO_1 0x00 // 1 char
#define UA5_FCR_TX_FIFO_3 0x10 // 3 char
#define UA5_FCR_TX_FIFO_9 0x20 // 9 char
#define UA5_FCR_TX_FIFO_13 0x30 // 13 char
#define UA5_FCR_TXFT_MASK 0x30 // TX_FIFO threshold level mask
# define UA5_FCR_TXFT0_MASK 0x10 // TXFT bit 0 mask
# define UA5_FCR_TXFT1_MASK 0x20 // TXFT bit 1 mask
# define UA5_FCR_TX_FIFO_1 0x00 // 1 char
# define UA5_FCR_TX_FIFO_3 0x10 // 3 char
# define UA5_FCR_TX_FIFO_9 0x20 // 9 char
# define UA5_FCR_TX_FIFO_13 0x30 // 13 char
#define UA5_FCR_RXFT_MASK 0xc0 // RX_FIFO threshold level mask
#define UA5_FCR_RXFT0_MASK 0x40 // RXFT bit 0 mask
#define UA5_FCR_RXFT1_MASK 0x80 // RXFT bit 1 mask
#define UA5_FCR_RX_FIFO_1 0x00 // 1 char
#define UA5_FCR_RX_FIFO_4 0x40 // 4 char
#define UA5_FCR_RX_FIFO_8 0x80 // 8 char
#define UA5_FCR_RX_FIFO_14 0xc0 // 14 char
#define UA5_FCR_RXFT_MASK 0xc0 // RX_FIFO threshold level mask
# define UA5_FCR_RXFT0_MASK 0x40 // RXFT bit 0 mask
# define UA5_FCR_RXFT1_MASK 0x80 // RXFT bit 1 mask
# define UA5_FCR_RX_FIFO_1 0x00 // 1 char
# define UA5_FCR_RX_FIFO_4 0x40 // 4 char
# define UA5_FCR_RX_FIFO_8 0x80 // 8 char
# define UA5_FCR_RX_FIFO_14 0xc0 // 14 char
// aliases
#define UA5_FCR_FIFO_ENABLED UA5_FCR_FIFO_EN
#define UA5_FCR_RX_SOFT_RESET UA5_FCR_RXSR
#define UA5_FCR_TX_SOFT_RESET UA5_FCR_TXSR
#define UA5_FCR_TX_FIFO_1_CHAR UA5_FCR_TX_FIFO_1
#define UA5_FCR_TX_FIFO_3_CHAR UA5_FCR_TX_FIFO_3
#define UA5_FCR_TX_FIFO_9_CHAR UA5_FCR_TX_FIFO_9
#define UA5_FCR_TX_FIFO_13_CHAR UA5_FCR_TX_FIFO_13
#define UA5_FCR_RX_FIFO_1_CHAR UA5_FCR_RX_FIFO_1
#define UA5_FCR_RX_FIFO_4_CHAR UA5_FCR_RX_FIFO_4
#define UA5_FCR_RX_FIFO_8_CHAR UA5_FCR_RX_FIFO_8
#define UA5_FCR_RX_FIFO_14_CHAR UA5_FCR_RX_FIFO_14
#define UA5_FCR_FIFO_ENABLED UA5_FCR_FIFO_EN
#define UA5_FCR_RX_SOFT_RESET UA5_FCR_RXSR
#define UA5_FCR_TX_SOFT_RESET UA5_FCR_TXSR
#define UA5_FCR_TX_FIFO_1_CHAR UA5_FCR_TX_FIFO_1
#define UA5_FCR_TX_FIFO_3_CHAR UA5_FCR_TX_FIFO_3
#define UA5_FCR_TX_FIFO_9_CHAR UA5_FCR_TX_FIFO_9
#define UA5_FCR_TX_FIFO_13_CHAR UA5_FCR_TX_FIFO_13
#define UA5_FCR_RX_FIFO_1_CHAR UA5_FCR_RX_FIFO_1
#define UA5_FCR_RX_FIFO_4_CHAR UA5_FCR_RX_FIFO_4
#define UA5_FCR_RX_FIFO_8_CHAR UA5_FCR_RX_FIFO_8
#define UA5_FCR_RX_FIFO_14_CHAR UA5_FCR_RX_FIFO_14
/*
** Line Control Register (available in all banks)
**
** Selected when bit 7 of the value written to the port is a 0.
*/
#define UA4_LCR (UA4_PORT + 3)
#define UA4_LINE_CTL UA4_LCR
#define UA4_LCR (UA4_PORT+3)
# define UA4_LINE_CTL UA4_LCR
#define UA4_LCR_WLS_MASK 0x03 // Word Length Select mask
#define UA4_LCR_WLS0_MASK 0x01 // WLS bit 0 mask
#define UA4_LCR_WLS1_MASK 0x02 // WLS bit 1 mask
#define UA4_LCR_WLS_5 0x00 // 5 bits per char
#define UA4_LCR_WLS_6 0x01 // 6 bits per char
#define UA4_LCR_WLS_7 0x02 // 7 bits per char
#define UA4_LCR_WLS_8 0x03 // 8 bits per char
#define UA4_LCR_WLS_MASK 0x03 // Word Length Select mask
# define UA4_LCR_WLS0_MASK 0x01 // WLS bit 0 mask
# define UA4_LCR_WLS1_MASK 0x02 // WLS bit 1 mask
# define UA4_LCR_WLS_5 0x00 // 5 bits per char
# define UA4_LCR_WLS_6 0x01 // 6 bits per char
# define UA4_LCR_WLS_7 0x02 // 7 bits per char
# define UA4_LCR_WLS_8 0x03 // 8 bits per char
#define UA4_LCR_STB 0x04 // Stop Bits
#define UA4_LCR_1_STOP_BIT 0x00
#define UA4_LCR_2_STOP_BIT 0x04
#define UA4_LCR_STB 0x04 // Stop Bits
# define UA4_LCR_1_STOP_BIT 0x00
# define UA4_LCR_2_STOP_BIT 0x04
#define UA4_LCR_PEN 0x08 // Parity Enable
#define UA4_LCR_EPS 0x10 // Even Parity Select
#define UA4_LCR_STKP 0x20 // Sticky Parity
#define UA4_LCR_NO_PARITY 0x00
#define UA4_LCR_ODD_PARITY UA4_LCR_PEN
#define UA4_LCR_EVEN_PARITY (UA4_LCR_PEN | UA4_LCR_EPS)
#define UA4_LCR_PARITY_LOGIC_1 (UA4_LCR_PEN | UA4_LCR_STKP)
#define UA4_LCR_PARITY_LOGIC_0 (UA4_LCR_PEN | UA4_LCR_EPS | UA4_LCR_STKP)
#define UA4_LCR_PEN 0x08 // Parity Enable
#define UA4_LCR_EPS 0x10 // Even Parity Select
#define UA4_LCR_STKP 0x20 // Sticky Parity
# define UA4_LCR_NO_PARITY 0x00
# define UA4_LCR_ODD_PARITY UA4_LCR_PEN
# define UA4_LCR_EVEN_PARITY (UA4_LCR_PEN|UA4_LCR_EPS)
# define UA4_LCR_PARITY_LOGIC_1 (UA4_LCR_PEN|UA4_LCR_STKP)
# define UA4_LCR_PARITY_LOGIC_0 (UA4_LCR_PEN|UA4_LCR_EPS|UA4_LCR_STKP)
#define UA4_LCR_SBRK 0x40 // Set Break
#define UA4_LCR_DLAB 0x80 // Divisor Latch select bit
#define UA4_LCR_SBRK 0x40 // Set Break
#define UA4_LCR_DLAB 0x80 // Divisor Latch select bit
// aliases
#define UA4_LCR_STOP_BITS UA4_LCR_STB
#define UA4_LCR_PARITY_ENABLE UA4_LCR_PEN
#define UA4_LCR_SET_BREAK UA4_LCR_SBRK
#define UA4_LCR_BANK_SELECT_ENABLE UA4_LCR_BKSE
# define UA4_LCR_STOP_BITS UA4_LCR_STB
# define UA4_LCR_PARITY_ENABLE UA4_LCR_PEN
# define UA4_LCR_SET_BREAK UA4_LCR_SBRK
# define UA4_LCR_BANK_SELECT_ENABLE UA4_LCR_BKSE
/*
** Divisor Latch Registers
@ -232,109 +233,109 @@
** "re-lock" the Divisor Latch registers, write a command byte to
** LCR with 0 in the DLAB bit.
*/
#define UA4_DLL (UA4_PORT + 0) // Divisor Latch (least sig.)
#define UA4_DLM (UA4_PORT + 1) // Divisor Latch (most sig.)
#define UA4_DLL (UA4_PORT+0) // Divisor Latch (least sig.)
#define UA4_DLM (UA4_PORT+1) // Divisor Latch (most sig.)
// aliases
#define UA4_DIVISOR_LATCH_LS UA4_DLL
#define UA4_DIVISOR_LATCH_MS UA4_DLM
#define UA4_DIVISOR_LATCH_LS UA4_DLL
#define UA4_DIVISOR_LATCH_MS UA4_DLM
// Baud rate divisor high and low bytes
#define BAUD_HIGH_BYTE(x) (((x) >> 8) & 0xff)
#define BAUD_LOW_BYTE(x) ((x) & 0xff)
#define BAUD_HIGH_BYTE(x) (((x) >> 8) & 0xff)
#define BAUD_LOW_BYTE(x) ((x) & 0xff)
// Baud rate divisors
#define DL_BAUD_50 2304
#define DL_BAUD_75 1536
#define DL_BAUD_110 1047
#define DL_BAUD_150 768
#define DL_BAUD_300 384
#define DL_BAUD_600 192
#define DL_BAUD_1200 96
#define DL_BAUD_1800 64
#define DL_BAUD_2000 58
#define DL_BAUD_2400 48
#define DL_BAUD_3600 32
#define DL_BAUD_4800 24
#define DL_BAUD_7200 16
#define DL_BAUD_9600 12
#define DL_BAUD_14400 8
#define DL_BAUD_19200 6
#define DL_BAUD_28800 4
#define DL_BAUD_38400 3
#define DL_BAUD_57600 2
#define DL_BAUD_115200 1
#define DL_BAUD_50 2304
#define DL_BAUD_75 1536
#define DL_BAUD_110 1047
#define DL_BAUD_150 768
#define DL_BAUD_300 384
#define DL_BAUD_600 192
#define DL_BAUD_1200 96
#define DL_BAUD_1800 64
#define DL_BAUD_2000 58
#define DL_BAUD_2400 48
#define DL_BAUD_3600 32
#define DL_BAUD_4800 24
#define DL_BAUD_7200 16
#define DL_BAUD_9600 12
#define DL_BAUD_14400 8
#define DL_BAUD_19200 6
#define DL_BAUD_28800 4
#define DL_BAUD_38400 3
#define DL_BAUD_57600 2
#define DL_BAUD_115200 1
/*
** Modem Control Register
*/
#define UA4_MCR (UA4_PORT + 4)
#define UA4_MODEM_CTL UA4_MCR
#define UA4_MCR (UA4_PORT+4)
# define UA4_MODEM_CTL UA4_MCR
#define UA4_MCR_DTR 0x01 // Data Terminal Ready
#define UA4_MCR_RTS 0x02 // Ready to Send
#define UA4_MCR_RILP 0x04 // Loopback Interrupt Request
#define UA4_MCR_ISEN 0x08 // Interrupt Signal Enable
#define UA4_MCR_DCDLP 0x08 // DCD Loopback
#define UA4_MCR_LOOP 0x10 // Loopback Enable
#define UA4_MCR_DTR 0x01 // Data Terminal Ready
#define UA4_MCR_RTS 0x02 // Ready to Send
#define UA4_MCR_RILP 0x04 // Loopback Interrupt Request
#define UA4_MCR_ISEN 0x08 // Interrupt Signal Enable
#define UA4_MCR_DCDLP 0x08 // DCD Loopback
#define UA4_MCR_LOOP 0x10 // Loopback Enable
// aliases
#define UA4_MCR_DATA_TERMINAL_READY UA4_MCR_DTR
#define UA4_MCR_READY_TO_SEND UA4_MCR_RTS
#define UA4_MCR_LOOPBACK_INT_REQ UA4_MCR_RILP
#define UA4_MCR_INT_SIGNAL_ENABLE UA4_MCR_ISEN
#define UA4_MCR_LOOPBACK_DCD UA4_MCR_DCDLP
#define UA4_MCR_LOOPBACK_ENABLE UA4_MCR_LOOP
#define UA4_MCR_DATA_TERMINAL_READY UA4_MCR_DTR
#define UA4_MCR_READY_TO_SEND UA4_MCR_RTS
#define UA4_MCR_LOOPBACK_INT_REQ UA4_MCR_RILP
#define UA4_MCR_INT_SIGNAL_ENABLE UA4_MCR_ISEN
#define UA4_MCR_LOOPBACK_DCD UA4_MCR_DCDLP
#define UA4_MCR_LOOPBACK_ENABLE UA4_MCR_LOOP
/*
** Line Status Register
*/
#define UA4_LSR (UA4_PORT + 5)
#define UA4_LINE_STATUS UA4_LSR
#define UA4_LSR (UA4_PORT+5)
# define UA4_LINE_STATUS UA4_LSR
#define UA4_LSR_RXDA 0x01 // Receiver Data Available
#define UA4_LSR_OE 0x02 // Overrun Error
#define UA4_LSR_PE 0x04 // Parity Error
#define UA4_LSR_FE 0x08 // Framing Error
#define UA4_LSR_BRK 0x10 // Break Event Detected
#define UA4_LSR_TXRDY 0x20 // Transmitter Ready
#define UA4_LSR_TXEMP 0x40 // Transmitter Empty
#define UA4_LSR_ER_INF 0x80 // Error in RX_FIFO
#define UA4_LSR_RXDA 0x01 // Receiver Data Available
#define UA4_LSR_OE 0x02 // Overrun Error
#define UA4_LSR_PE 0x04 // Parity Error
#define UA4_LSR_FE 0x08 // Framing Error
#define UA4_LSR_BRK 0x10 // Break Event Detected
#define UA4_LSR_TXRDY 0x20 // Transmitter Ready
#define UA4_LSR_TXEMP 0x40 // Transmitter Empty
#define UA4_LSR_ER_INF 0x80 // Error in RX_FIFO
// aliases
#define UA4_LSR_RX_DATA_AVAILABLE UA4_LSR_RXDA
#define UA4_LSR_OVERRUN_ERROR UA4_LSR_OE
#define UA4_LSR_PARITY_ERROR UA4_LSR_PE
#define UA4_LSR_FRAMING_ERROR UA4_LSR_FE
#define UA4_LSR_BREAK_DETECTED UA4_LSR_BRK
#define UA4_LSR_TX_READY UA4_LSR_TXRDY
#define UA4_LSR_TX_EMPTY UA4_LSR_TXEMP
#define UA4_LSR_RX_FIFO_ERROR UA4_LSR_ER_INF
#define UA4_LSR_RX_DATA_AVAILABLE UA4_LSR_RXDA
#define UA4_LSR_OVERRUN_ERROR UA4_LSR_OE
#define UA4_LSR_PARITY_ERROR UA4_LSR_PE
#define UA4_LSR_FRAMING_ERROR UA4_LSR_FE
#define UA4_LSR_BREAK_DETECTED UA4_LSR_BRK
#define UA4_LSR_TX_READY UA4_LSR_TXRDY
#define UA4_LSR_TX_EMPTY UA4_LSR_TXEMP
#define UA4_LSR_RX_FIFO_ERROR UA4_LSR_ER_INF
/*
** Modem Status Register
*/
#define UA4_MSR (UA4_PORT + 6)
#define UA4_MODEM_STATUS UA4_MSR
#define UA4_MSR (UA4_PORT+6)
# define UA4_MODEM_STATUS UA4_MSR
#define UA4_MSR_DCTS 0x01 // Delta Clear to Send
#define UA4_MSR_DDSR 0x02 // Delta Data Set Ready
#define UA4_MSR_TERI 0x04 // Trailing Edge Ring Indicate
#define UA4_MSR_DDCD 0x08 // Delta Data Carrier Detect
#define UA4_MSR_CTS 0x10 // Clear to Send
#define UA4_MSR_DSR 0x20 // Data Set Ready
#define UA4_MSR_RI 0x40 // Ring Indicate
#define UA4_MSR_DCD 0x80 // Data Carrier Detect
#define UA4_MSR_DCTS 0x01 // Delta Clear to Send
#define UA4_MSR_DDSR 0x02 // Delta Data Set Ready
#define UA4_MSR_TERI 0x04 // Trailing Edge Ring Indicate
#define UA4_MSR_DDCD 0x08 // Delta Data Carrier Detect
#define UA4_MSR_CTS 0x10 // Clear to Send
#define UA4_MSR_DSR 0x20 // Data Set Ready
#define UA4_MSR_RI 0x40 // Ring Indicate
#define UA4_MSR_DCD 0x80 // Data Carrier Detect
// aliases
#define UA4_MSR_DELTA_CLEAR_TO_SEND UA4_MSR_DCTS
#define UA4_MSR_DELTA_DATA_SET_READY UA4_MSR_DDSR
#define UA4_MSR_TRAILING_EDGE_RING UA4_MSR_TERI
#define UA4_MSR_DELTA_DATA_CARRIER_DETECT UA4_MSR_DDCD
#define UA4_MSR_CLEAR_TO_SEND UA4_MSR_CTS
#define UA4_MSR_DATA_SET_READY UA4_MSR_DSR
#define UA4_MSR_RING_INDICATE UA4_MSR_RI
#define UA4_MSR_DATA_CARRIER_DETECT UA4_MSR_DCD
#define UA4_MSR_DELTA_CLEAR_TO_SEND UA4_MSR_DCTS
#define UA4_MSR_DELTA_DATA_SET_READY UA4_MSR_DDSR
#define UA4_MSR_TRAILING_EDGE_RING UA4_MSR_TERI
#define UA4_MSR_DELTA_DATA_CARRIER_DETECT UA4_MSR_DDCD
#define UA4_MSR_CLEAR_TO_SEND UA4_MSR_CTS
#define UA4_MSR_DATA_SET_READY UA4_MSR_DSR
#define UA4_MSR_RING_INDICATE UA4_MSR_RI
#define UA4_MSR_DATA_CARRIER_DETECT UA4_MSR_DCD
/*
** Scratch Register
@ -342,7 +343,7 @@
** Not used by the UART; usable as a "scratchpad" register for
** temporary storage.
*/
#define UA4_SCR (UA4_PORT + 7)
#define UA4_SCRATCH UA4_UA5_SCR
#define UA4_SCR (UA4_PORT+7)
# define UA4_SCRATCH UA4_UA5_SCR
#endif /* uart.h */
#endif /* uart.h */

View file

@ -19,8 +19,6 @@
# .arch i386
#include <bootstrap.h>
#include <offsets.h>
#include <vm.h>
/*
** Configuration options - define in Makefile
@ -102,8 +100,8 @@ isr_save:
**
** Set up parameters for the ISR call.
*/
movl CTX_vector(%esp),%eax // get vector number and error code
movl CTX_code(%esp),%ebx
movl 52(%esp),%eax // get vector number and error code
movl 56(%esp),%ebx
/*
***********************
@ -122,12 +120,11 @@ isr_save:
// save the context pointer
movl current, %edx
movl %esp, PCB_context(%edx)
movl %esp, (%edx)
// also save the page directory pointer
movl %cr3, %ecx
addl $KERN_BASE, %ecx // convert to a virtual address
movl %ecx, PCB_pdir(%edx)
movl %ecx, 4(%edx)
// switch to the system stack
//
@ -169,9 +166,8 @@ isr_restore:
***********************
*/
movl current, %ebx // return to the user stack
movl PCB_context(%ebx), %esp // ESP --> context save area
movl PCB_pdir(%ebx), %ecx // page directory pointer
subl $KERN_BASE, %ecx // convert to a physical address
movl (%ebx), %esp // ESP --> context save area
movl 4(%ebx), %ecx // page directory pointer
movl %ecx, %cr3
// now we're operating with the user process'
@ -187,7 +183,7 @@ isr_restore:
/*
** DEBUGGING CODE PART 1
**
** This code will execute during each context restore, and
** This code will execute during each context restore, and
** should be modified to print out whatever debugging information
** is desired.
**

View file

@ -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,117 +55,119 @@ char b512[512]; // used by PANIC macro
**
** @param dtrace Decode the TRACE options
*/
static void kreport(bool_t dtrace)
{
cio_puts("\n-------------------------------\n");
cio_printf("Config: N_PROCS = %d", N_PROCS);
cio_printf(" N_PRIOS = %d", N_PRIOS);
cio_printf(" N_STATES = %d", N_STATES);
cio_printf(" CLOCK = %dHz\n", CLOCK_FREQ);
static void kreport( bool_t dtrace ) {
cio_puts( "\n-------------------------------\n" );
cio_printf( "Config: N_PROCS = %d", N_PROCS );
cio_printf( " N_PRIOS = %d", N_PRIOS );
cio_printf( " N_STATES = %d", N_STATES );
cio_printf( " CLOCK = %dHz\n", CLOCK_FREQ );
// This code is ugly, but it's the simplest way to
// print out the values of compile-time options
// without spending a lot of execution time at it.
cio_puts("Options: "
cio_puts( "Options: "
#ifdef RPT_INT_UNEXP
" R-uint"
" R-uint"
#endif
#ifdef RPT_INT_MYSTERY
" R-mint"
" R-mint"
#endif
#ifdef TRACE_CX
" CX"
" CX"
#endif
#ifdef CONSOLE_STATS
" Cstats"
" Cstats"
#endif
); // end of cio_puts() call
); // end of cio_puts() call
#ifdef SANITY
cio_printf(" SANITY = %d", SANITY);
cio_printf( " SANITY = %d", SANITY );
#endif
#ifdef STATUS
cio_printf(" STATUS = %d", STATUS);
cio_printf( " STATUS = %d", STATUS );
#endif
#if TRACE > 0
cio_printf(" TRACE = 0x%04x\n", TRACE);
cio_printf( " TRACE = 0x%04x\n", TRACE );
// decode the trace settings if that was requested
if (TRACING_SOMETHING && dtrace) {
if( TRACING_SOMETHING && dtrace ) {
// this one is simpler - we rely on string literal
// concatenation in the C compiler to create one
// long string to print out
cio_puts("Tracing:"
cio_puts( "Tracing:"
#if TRACING_PCB
" PCB"
" PCB"
#endif
#if TRACING_VM
" VM"
" VM"
#endif
#if TRACING_QUEUE
" QUE"
" QUE"
#endif
#if TRACING_SCHED
" SCHED"
" SCHED"
#endif
#if TRACING_DISPATCH
" DISPATCH"
" DISPATCH"
#endif
#if TRACING_SYSCALLS
" SCALL"
" SCALL"
#endif
#if TRACING_SYSRETS
" SRET"
" SRET"
#endif
#if TRACING_EXIT
" EXIT"
" EXIT"
#endif
#if TRACING_INIT
" INIT"
" INIT"
#endif
#if TRACING_KMEM
" KM"
" KM"
#endif
#if TRACING_KMEM_FREELIST
" KMFL"
" KMFL"
#endif
#if TRACING_KMEM_INIT
" KMIN"
" KMIN"
#endif
#if TRACING_FORK
" FORK"
" FORK"
#endif
#if TRACING_EXEC
" EXEC"
" EXEC"
#endif
#if TRACING_SIO_STAT
" S_STAT"
" S_STAT"
#endif
#if TRACING_SIO_ISR
" S_ISR"
" S_ISR"
#endif
#if TRACING_SIO_RD
" S_RD"
" S_RD"
#endif
#if TRACING_SIO_WR
" S_WR"
" S_WR"
#endif
#if TRACING_USER
" USER"
" USER"
#endif
#if TRACING_ELF
" ELF"
" ELF"
#endif
); // end of cio_puts() call
); // end of cio_puts() call
}
#endif /* TRACE > 0 */
#endif /* TRACE > 0 */
cio_putchar('\n');
cio_puts( "\n-------------------------------\n" );
}
#if defined(CONSOLE_STATS)
/**
** stats - callback routine for console statistics
@ -177,51 +179,53 @@ static void kreport(bool_t dtrace)
**
** This code runs as part of the CIO ISR.
*/
static void stats(int code)
{
switch (code) {
case 'a': // dump the active table
ptable_dump("\nActive processes", false);
static void stats( int code ) {
switch( code ) {
case 'a': // dump the active table
ptable_dump( "\nActive processes", false );
break;
case 'c': // dump context info for all active PCBs
ctx_dump_all("\nContext dump");
case 'c': // dump context info for all active PCBs
ctx_dump_all( "\nContext dump" );
break;
case 'p': // dump the active table and all PCBs
ptable_dump("\nActive processes", true);
case 'p': // dump the active table and all PCBs
ptable_dump( "\nActive processes", true );
break;
case 'q': // dump the queues
case 'q': // dump the queues
// code to dump out any/all queues
pcb_queue_dump("R", ready, true);
pcb_queue_dump("W", waiting, true);
pcb_queue_dump("S", sleeping, true);
pcb_queue_dump("Z", zombie, true);
pcb_queue_dump("I", sioread, true);
pcb_queue_dump( "R", ready );
pcb_queue_dump( "W", waiting );
pcb_queue_dump( "S", sleeping );
pcb_queue_dump( "Z", zombie );
pcb_queue_dump( "I", sioread );
break;
case 'r': // print system configuration information
report(true);
case 'r': // print system configuration information
report( true );
break;
// ignore CR and LF
case '\r': // FALL THROUGH
case '\n':
break;
default:
cio_printf("console: unknown request '0x%02x'\n", code);
cio_printf( "console: unknown request '0x%02x'\n", code );
// FALL THROUGH
case 'h': // help message
cio_puts("\nCommands:\n"
" a -- dump the active table\n"
" c -- dump contexts for active processes\n"
" h -- this message\n"
" p -- dump the active table and all PCBs\n"
" q -- dump the queues\n"
" r -- print system configuration\n");
case 'h': // help message
cio_puts( "\nCommands:\n"
" a -- dump the active table\n"
" c -- dump contexts for active processes\n"
" h -- this message\n"
" p -- dump the active table and all PCBs\n"
" q -- dump the queues\n"
" r -- print system configuration\n"
);
break;
}
}
@ -239,15 +243,15 @@ static void stats(int code)
**
** Making this type 'int' keeps the compiler happy.
*/
int main(void)
{
int main( void ) {
/*
** BOILERPLATE CODE - taken from basic framework
**
** Initialize interrupt stuff.
*/
init_interrupts(); // IDT and PIC initialization
init_interrupts(); // IDT and PIC initialization
/*
** Console I/O system.
@ -257,13 +261,13 @@ int main(void)
** and queue modules.
*/
#if defined(CONSOLE_STATS)
cio_init(stats);
#if defined(CONSOLE_STATS)
cio_init( stats );
#else
cio_init(NULL); // no console callback routine
cio_init( NULL ); // no console callback routine
#endif
cio_clearscreen(); // wipe out whatever is there
cio_clearscreen(); // wipe out whatever is there
/*
** TERM-SPECIFIC CODE STARTS HERE
@ -276,40 +280,40 @@ int main(void)
** install their own ISRs in their initialization routines.
*/
cio_puts("System initialization starting.\n");
cio_puts("-------------------------------\n");
cio_puts( "System initialization starting.\n" );
cio_puts( "-------------------------------\n" );
cio_puts("Modules:");
cio_puts( "Modules:" );
// call the module initialization functions, being
// careful to follow any module precedence requirements
km_init(); // MUST BE FIRST
km_init(); // MUST BE FIRST
#if TRACING_KMEM || TRACING_KMEM_FREE
delay(DELAY_2_SEC); // approximately
delay( DELAY_2_SEC ); // approximately
#endif
// other module initialization calls here
clk_init(); // clock
pcb_init(); // process (PCBs, queues, scheduler)
clk_init(); // clock
pcb_init(); // process (PCBs, queues, scheduler)
#if TRACING_PCB
delay(DELAY_2_SEC);
delay( DELAY_2_SEC );
#endif
sio_init(); // serial i/o
sys_init(); // system call
sio_init(); // serial i/o
sys_init(); // system call
#if TRACING_SYSCALLS || TRACING_SYSRETS
delay(DELAY_2_SEC);
delay( DELAY_2_SEC );
#endif
vm_init(); // virtual memory
user_init(); // user code handling
vm_init(); // virtual memory
user_init(); // user code handling
cio_puts("\nModule initialization complete.\n");
cio_puts( "\nModule initialization complete.\n" );
cio_puts( "-------------------------------\n" );
// report our configuration options
kreport(true);
cio_puts("-------------------------------\n");
kreport( true );
delay(DELAY_2_SEC);
delay( DELAY_3_SEC );
/*
** Other tasks typically performed here:
@ -319,14 +323,14 @@ int main(void)
/*
** Create the initial user process
**
**
** This code is largely stolen from the fork() and exec()
** implementations in syscalls.c; if those change, this must
** also change.
*/
// if we can't get a PCB, there's no use continuing!
assert(pcb_alloc(&init_pcb) == SUCCESS);
assert( pcb_alloc(&init_pcb) == SUCCESS );
// fill in the necessary details
init_pcb->pid = PID_INIT;
@ -334,67 +338,47 @@ int main(void)
init_pcb->priority = PRIO_HIGH;
// find the 'init' program
prog_t *prog = user_locate(Init);
assert(prog != NULL);
prog_t *prog = user_locate( Init );
assert( prog != NULL );
// command-line arguments for 'init'
const char *args[2] = { "init", NULL };
// load it
assert(user_load(prog, init_pcb, args, true) == SUCCESS);
assert( user_load(prog,init_pcb,args) == SUCCESS );
// send it on its merry way
schedule(init_pcb);
dispatch();
schedule( init_pcb );
#ifdef TRACE_CX
// if we're using a scrolling region, wait a bit more and then set it up
delay(DELAY_7_SEC);
delay( DELAY_7_SEC );
// define a scrolling region in the top 7 lines of the screen
cio_setscroll(0, 7, 99, 99);
cio_setscroll( 0, 7, 99, 99 );
// clear it
cio_clearscroll();
// clear the top line
cio_puts_at(
0, 0,
"* ");
cio_puts_at( 0, 0, "* " );
// separator
cio_puts_at(
0, 6,
"================================================================================");
cio_puts_at( 0, 6, "================================================================================" );
#endif
// switch to the "real" kernel page directory
vm_set_kvm();
/*
** END OF TERM-SPECIFIC CODE
**
** Finally, report that we're all done.
*/
cio_puts("System initialization complete.\n");
cio_puts("-------------------------------\n");
cio_puts( "System initialization complete.\n" );
cio_puts( "-------------------------------\n" );
sio_enable(SIO_RX);
#if 0
// produce a "system state" report
cio_puts( "System status: Queues " );
pcb_queue_dump( "R", ready, true );
pcb_queue_dump( "W", waiting, true );
pcb_queue_dump( "S", sleeping, true );
pcb_queue_dump( "Z", zombie, true );
pcb_queue_dump( "I", sioread, true );
ptable_dump_counts();
pcb_dump( "Current: ", current, true );
delay( DELAY_3_SEC );
vm_print( current->pdir, true, TwoLevel );
delay( DELAY_3_SEC );
#endif
sio_enable( SIO_RX );
return 0;
}

71
kernel/old/kernel.ld Normal file
View file

@ -0,0 +1,71 @@
/*
** Simple linker script for the 20245 kernel.
*/
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
/* Link the kernel at this address. */
/* Must match what is defined in vm.h! */
. = 0x80010000;
.text : AT(0x10000) {
*(.text .stub .text.* .gnu.linkonce.t.*)
}
/* standard symbols */
PROVIDE(etext = .);
PROVIDE(_etext = .);
/* put read-only data next */
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
}
/* Could put STABs here */
.stab : {
PROVIDE(__STAB_BEGIN__ = .);
*(.stab);
PROVIDE(__STAB_END__ = .);
}
.stabstr : {
PROVIDE(__STABSTR_BEGIN__ = .);
*(.stabstr);
PROVIDE(__STABSTR_END__ = .);
}
/* Align the data segment at the next page boundary */
. = ALIGN(0x1000);
PROVIDE(data = .);
PROVIDE(_data = .);
/* The data segment */
.data : {
*(.data .data.*)
}
PROVIDE(edata = .);
PROVIDE(_edata = .);
/* page-align the BSS */
. = ALIGN(0x1000);
PROVIDE(__bss_start = .);
.bss : {
*(.bss .bss.*)
*(COMMON)
}
PROVIDE(end = .);
PROVIDE(_end = .);
/DISCARD/ : {
/* *(.stab .stab_info .stabstr) */
*(.eh_frame .note.GNU-stack .note.gnu.property .comment)
}
}

View file

@ -69,22 +69,22 @@
*/
// combination tracing tests
#define ANY_KMEM (TRACING_KMEM | TRACING_KMEM_INIT | TRACING_KMEM_FREELIST)
#define KMEM_OR_INIT (TRACING_KMEM | TRACING_KMEM_INIT)
#define ANY_KMEM (TRACING_KMEM|TRACING_KMEM_INIT|TRACING_KMEM_FREELIST)
#define KMEM_OR_INIT (TRACING_KMEM|TRACING_KMEM_INIT)
// parameters related to word and block sizes
#define WORD_SIZE sizeof(int)
#define LOG2_OF_WORD_SIZE 2
#define WORD_SIZE sizeof(int)
#define LOG2_OF_WORD_SIZE 2
#define LOG2_OF_PAGE_SIZE 12
#define LOG2_OF_PAGE_SIZE 12
#define LOG2_OF_SLICE_SIZE 10
#define LOG2_OF_SLICE_SIZE 10
// converters: pages to bytes, bytes to pages
#define P2B(x) ((x) << LOG2_OF_PAGE_SIZE)
#define B2P(x) ((x) >> LOG2_OF_PAGE_SIZE)
#define P2B(x) ((x) << LOG2_OF_PAGE_SIZE)
#define B2P(x) ((x) >> LOG2_OF_PAGE_SIZE)
/*
** Name: adjacent
@ -94,8 +94,8 @@
** Description: Determines whether the second block immediately
** follows the first one.
*/
#define adjacent(first, second) \
((void *)(first) + P2B((first)->pages) == (void *)(second))
#define adjacent(first,second) \
( (void *) (first) + P2B((first)->pages) == (void *) (second) )
/*
** PRIVATE DATA TYPES
@ -115,44 +115,44 @@ typedef union b64_u {
} b64_t;
// the halves of a 64-bit address
#define LOW part[0]
#define HIGH part[1]
#define LOW part[0]
#define HIGH part[1]
// memory region descriptor
typedef struct memregion_s {
b64_t base; // base address
b64_t length; // region length
uint32_t type; // type of region
uint32_t acpi; // ACPI 3.0 info
b64_t base; // base address
b64_t length; // region length
uint32_t type; // type of region
uint32_t acpi; // ACPI 3.0 info
} ATTR_PACKED region_t;
/*
** Region types
*/
#define REGION_USABLE 1
#define REGION_RESERVED 2
#define REGION_ACPI_RECL 3
#define REGION_ACPI_NVS 4
#define REGION_BAD 5
#define REGION_USABLE 1
#define REGION_RESERVED 2
#define REGION_ACPI_RECL 3
#define REGION_ACPI_NVS 4
#define REGION_BAD 5
/*
** ACPI 3.0 bit fields
*/
#define REGION_IGNORE 0x01
#define REGION_NONVOL 0x02
#define REGION_IGNORE 0x01
#define REGION_NONVOL 0x02
/*
** 32-bit and 64-bit address values as 64-bit literals
*/
#define ADDR_BIT_32 0x0000000100000000LL
#define ADDR_LOW_HALF 0x00000000ffffffffLL
#define ADDR_HIGH_HALR 0xffffffff00000000LL
#define ADDR_BIT_32 0x0000000100000000LL
#define ADDR_LOW_HALF 0x00000000ffffffffLL
#define ADDR_HIGH_HALR 0xffffffff00000000LL
#define ADDR_32_MAX ADDR_LOW_HALF
#define ADDR_64_FIRST ADDR_BIT_32
#define ADDR_32_MAX ADDR_LOW_HALF
#define ADDR_64_FIRST ADDR_BIT_32
/*
** PRIVATE GLOBAL VARIABLES
@ -196,19 +196,19 @@ static int km_initialized;
** @param[in] base Base physical address of the block
** @param[in] length Block length, in bytes
*/
static void add_block(uint32_t base, uint32_t length)
{
static void add_block( uint32_t base, uint32_t length ) {
// don't add it if it isn't at least 4K
if (length < SZ_PAGE) {
if( length < SZ_PAGE ) {
return;
}
#if ANY_KMEM
cio_printf(" add(%08x,%08x): ", base, length);
cio_printf( " add(%08x,%08x): ", base, length );
#endif
// verify that the base address is a 4K boundary
if ((base & MOD4K_BITS) != 0) {
if( (base & MOD4K_BITS) != 0 ) {
// nope - how many bytes will we lose from the beginning
uint_t loss = base & MOD4K_BITS;
// adjust the starting address: (n + 4K - 1) / 4K
@ -218,7 +218,7 @@ static void add_block(uint32_t base, uint32_t length)
}
// only want to add multiples of 4K; check the lower bits
if ((length & MOD4K_BITS) != 0) {
if( (length & MOD4K_BITS) != 0 ) {
// round it down to 4K
length &= MOD4K_MASK;
}
@ -235,21 +235,21 @@ static void add_block(uint32_t base, uint32_t length)
int npages = 0;
#if ANY_KMEM
cio_printf("-> base %08x len %08x: ", base, length);
cio_printf( "-> base %08x len %08x: ", base, length );
#endif
// iterate through the block page by page
while (base < blend) {
list_add(&free_pages, (void *)base);
while( base < blend ) {
list_add( &free_pages, (void *) base );
++npages;
base += SZ_PAGE;
base += SZ_PAGE;
}
// add the count to our running total
n_pages += npages;
#if ANY_KMEM
cio_printf(" -> %d pages\n", npages);
cio_printf( " -> %d pages\n", npages );
#endif
}
@ -263,14 +263,13 @@ static void add_block(uint32_t base, uint32_t length)
** Must be called before any other init routine that uses
** dynamic storage is called.
*/
void km_init(void)
{
void km_init( void ) {
int32_t entries;
region_t *region;
#if TRACING_INIT
// announce that we're starting initialization
cio_puts(" Kmem");
cio_puts( " Kmem" );
#endif
// initially, nothing in the free lists
@ -280,28 +279,32 @@ void km_init(void)
km_initialized = 0;
// get the list length
entries = *((int32_t *)MMAP_ADDR);
entries = *((int32_t *) MMAP_ADDR);
#if KMEM_OR_INIT
cio_printf("\nKmem: %d regions\n", entries);
cio_printf( "\nKmem: %d regions\n", entries );
#endif
// if there are no entries, we have nothing to do!
if (entries < 1) { // note: entries == -1 could occur!
if( entries < 1 ) { // note: entries == -1 could occur!
return;
}
// iterate through the entries, adding things to the freelist
region = ((region_t *)(MMAP_ADDR + 4));
region = ((region_t *) (MMAP_ADDR + 4));
for( int i = 0; i < entries; ++i, ++region ) {
for (int i = 0; i < entries; ++i, ++region) {
#if KMEM_OR_INIT
// report this region
cio_printf("%3d: ", i);
cio_printf(" B %08x%08x", region->base.HIGH, region->base.LOW);
cio_printf(" L %08x%08x", region->length.HIGH, region->length.LOW);
cio_printf(" T %08x A %08x", region->type, region->acpi);
cio_printf( "%3d: ", i );
cio_printf( " B %08x%08x",
region->base.HIGH, region->base.LOW );
cio_printf( " L %08x%08x",
region->length.HIGH, region->length.LOW );
cio_printf( " T %08x A %08x",
region->type, region->acpi );
#endif
/*
@ -321,27 +324,27 @@ void km_init(void)
// first, check the ACPI one-bit flags
if (((region->acpi) & REGION_IGNORE) == 0) {
if( ((region->acpi) & REGION_IGNORE) == 0 ) {
#if KMEM_OR_INIT
cio_puts(" IGN\n");
cio_puts( " IGN\n" );
#endif
continue;
}
if (((region->acpi) & REGION_NONVOL) != 0) {
if( ((region->acpi) & REGION_NONVOL) != 0 ) {
#if KMEM_OR_INIT
cio_puts(" NVOL\n");
cio_puts( " NVOL\n" );
#endif
continue; // we'll ignore this, too
continue; // we'll ignore this, too
}
// next, the region type
if ((region->type) != REGION_USABLE) {
if( (region->type) != REGION_USABLE ) {
#if KMEM_OR_INIT
cio_puts(" RCLM\n");
cio_puts( " RCLM\n" );
#endif
continue; // we won't attempt to reclaim ACPI memory (yet)
continue; // we won't attempt to reclaim ACPI memory (yet)
}
/*
@ -361,17 +364,18 @@ void km_init(void)
*/
// grab the two 64-bit values to simplify things
uint64_t base = region->base.all;
uint64_t base = region->base.all;
uint64_t length = region->length.all;
uint64_t endpt = base + length;
uint64_t endpt = base + length;
// ignore it if it's above our high cutoff point
if (base >= KM_HIGH_CUTOFF || endpt >= KM_HIGH_CUTOFF) {
if( base >= KM_HIGH_CUTOFF || endpt >= KM_HIGH_CUTOFF ) {
// is the whole thing too high, or just part?
if (base >= KM_HIGH_CUTOFF) {
if( base >= KM_HIGH_CUTOFF ) {
// it's all too high!
#if KMEM_OR_INIT
cio_puts(" HIGH\n");
cio_puts( " HIGH\n" );
#endif
continue;
}
@ -381,12 +385,13 @@ void km_init(void)
}
// see if it's below our low cutoff point
if (base < KM_LOW_CUTOFF || endpt < KM_LOW_CUTOFF) {
if( base < KM_LOW_CUTOFF || endpt < KM_LOW_CUTOFF ) {
// is the whole thing too low, or just part?
if (endpt < KM_LOW_CUTOFF) {
if( endpt < KM_LOW_CUTOFF ) {
// it's all below the cutoff!
#if KMEM_OR_INIT
cio_puts(" LOW\n");
cio_puts( " LOW\n" );
#endif
continue;
}
@ -405,20 +410,20 @@ void km_init(void)
length = endpt - base;
#if KMEM_OR_INIT
cio_puts(" OK\n");
cio_puts( " OK\n" );
#endif
uint32_t b32 = base & ADDR_LOW_HALF;
uint32_t b32 = base & ADDR_LOW_HALF;
uint32_t l32 = length & ADDR_LOW_HALF;
add_block(b32, l32);
add_block( b32, l32 );
}
// record the initialization
km_initialized = 1;
#if KMEM_OR_INIT
delay(DELAY_3_SEC);
delay( DELAY_3_SEC );
#endif
}
@ -433,38 +438,39 @@ void km_init(void)
** @param addrs Also dump page addresses
** @param both Also dump slice addresses
*/
void km_dump(bool_t addrs, bool_t both)
{
void km_dump( bool_t addrs, bool_t both ) {
// report the sizes
cio_printf("&free_pages %08x, &free_slices %08x, %u pages, %u slices\n",
(uint32_t)&free_pages, (uint32_t)&free_slices, n_pages,
n_slices);
cio_printf( "&free_pages %08x, &free_slices %08x, %u pages, %u slices\n",
(uint32_t) &free_pages, (uint32_t) &free_slices,
n_pages, n_slices );
// was that all?
if (!addrs) {
if( !addrs ) {
return;
}
// dump the addresses of the pages in the free list
uint32_t n = 0;
list_t *block = free_pages.next;
while (block != NULL) {
if (n && !(n & MOD4_BITS)) {
while( block != NULL ) {
if( n && !(n & MOD4_BITS) ) {
// four per line
cio_putchar('\n');
cio_putchar( '\n' );
}
cio_printf(" page @ 0x%08x", (uint32_t)block);
cio_printf( " page @ 0x%08x", (uint32_t) block );
block = block->next;
++n;
}
// sanity check - verify that the counts match
if (n != n_pages) {
sprint(b256, "km_dump: n_pages %u, counted %u!!!\n", n_pages, n);
WARNING(b256);
if( n != n_pages ) {
sprint( b256, "km_dump: n_pages %u, counted %u!!!\n",
n_pages, n );
WARNING( b256);
}
if (!both) {
if( !both ) {
return;
}
@ -473,20 +479,21 @@ void km_dump(bool_t addrs, bool_t both)
// also dump the addresses of slices in the slice free list
n = 0;
block = free_slices.next;
while (block != NULL) {
if (n && !(n & MOD4_BITS)) {
while( block != NULL ) {
if( n && !(n & MOD4_BITS) ) {
// four per line
cio_putchar('\n');
cio_putchar( '\n' );
}
cio_printf(" slc @ 0x%08x", (uint32_t)block);
cio_printf( " slc @ 0x%08x", (uint32_t) block );
block = block->next;
++n;
}
// sanity check - verify that the counts match
if (n != n_slices) {
sprint(b256, "km_dump: n_slices %u, counted %u!!!\n", n_slices, n);
WARNING(b256);
if( n != n_slices ) {
sprint( b256, "km_dump: n_slices %u, counted %u!!!\n",
n_slices, n );
WARNING( b256);
}
}
@ -502,26 +509,26 @@ void km_dump(bool_t addrs, bool_t both)
** @return a pointer to the beginning of the allocated page,
** or NULL if no memory is available
*/
void *km_page_alloc(void)
{
void *km_page_alloc( void ) {
// if km_init() wasn't called first, stop us in our tracks
assert(km_initialized);
assert( km_initialized );
#if TRACING_KMEM_FREELIST
cio_puts("KM: pg_alloc()");
cio_puts( "KM: pg_alloc()" );
#endif
// pointer to the first block
void *page = list_remove(&free_pages);
void *page = list_remove( &free_pages );
// was a page available?
if (page == NULL) {
if( page == NULL ){
// nope!
#if TRACING_KMEM_FREELIST
cio_puts(" FAIL\n");
cio_puts( " FAIL\n" );
#endif
#if ALLOC_FAIL_PANIC
PANIC(0, "page alloc failed");
PANIC( 0, "page alloc failed" );
#else
return NULL;
#endif
@ -531,10 +538,10 @@ void *km_page_alloc(void)
--n_pages;
#if TRACING_KMEM_FREELIST
cio_printf(" -> %08x\n", (uint32_t)page);
cio_printf( " -> %08x\n", (uint32_t) page );
#endif
return (page);
return( page );
}
/**
@ -544,22 +551,23 @@ void *km_page_alloc(void)
**
** @param[in] page Pointer to the page to be returned to the free list
*/
void km_page_free(void *page)
{
void km_page_free( void *page ){
// verify that km_init() was called first
assert(km_initialized);
assert( km_initialized );
#if TRACING_KMEM_FREELIST
cio_printf("KM: pg_free(%08x)\n", (uint32_t)page);
cio_printf( "KM: pg_free(%08x)\n", (uint32_t) page );
#endif
/*
** Don't do anything if the address is NULL.
*/
if (page == NULL) {
if( page == NULL ){
return;
}
/*
** CRITICAL ASSUMPTION
**
@ -581,7 +589,7 @@ void km_page_free(void *page)
*/
// link this into the free list
list_add(&free_pages, page);
list_add( &free_pages, page );
// one more in the pool
++n_pages;
@ -605,19 +613,19 @@ void km_page_free(void *page)
**
** @param page Pointer to the page to be carved up
*/
static void carve_slices(void *page)
{
static void carve_slices( void *page ) {
// sanity check
assert1(page != NULL);
assert1( page != NULL );
#if TRACING_KMEM_FREELIST
cio_printf("KM: carve_slices(%08x)\n", (uint32_t)page);
cio_printf( "KM: carve_slices(%08x)\n", (uint32_t) page );
#endif
// create the four slices from it
uint8_t *ptr = (uint8_t *)page;
for (int i = 0; i < 4; ++i) {
km_slice_free((void *)ptr);
uint8_t *ptr = (uint8_t *) page;
for( int i = 0; i < 4; ++i ) {
km_slice_free( (void *) ptr );
ptr += SZ_SLICE;
++n_slices;
}
@ -632,38 +640,38 @@ static void carve_slices(void *page)
**
** @return a pointer to the allocated slice
*/
void *km_slice_alloc(void)
{
void *km_slice_alloc( void ) {
// verify that km_init() was called first
assert(km_initialized);
assert( km_initialized );
#if TRACING_KMEM_FREELIST
cio_printf("KM: sl_alloc()\n");
cio_printf( "KM: sl_alloc()\n" );
#endif
// if we are out of slices, create a few more
if (free_slices.next == NULL) {
if( free_slices.next == NULL ) {
void *new = km_page_alloc();
if (new == NULL) {
if( new == NULL ) {
// can't get any more space
#if ALLOC_FAIL_PANIC
PANIC(0, "slice new alloc failed");
PANIC( 0, "slice new alloc failed" );
#else
return NULL;
#endif
}
carve_slices(new);
carve_slices( new );
}
// take the first one from the free list
void *slice = list_remove(&free_slices);
assert(slice != NULL);
void *slice = list_remove( &free_slices );
assert( slice != NULL );
--n_slices;
// make it nice and shiny for the caller
memclr((void *)slice, SZ_SLICE);
memclr( (void *) slice, SZ_SLICE );
return (slice);
return( slice );
}
/**
@ -676,16 +684,16 @@ void *km_slice_alloc(void)
**
** @param[in] block Pointer to the slice (1/4 page) to be freed
*/
void km_slice_free(void *block)
{
void km_slice_free( void *block ) {
// verify that km_init() was called first
assert(km_initialized);
assert( km_initialized );
#if TRACING_KMEM_FREELIST
cio_printf("KM: sl_free(%08x)\n", (uint32_t)block);
cio_printf( "KM: sl_free(%08x)\n", (uint32_t) block );
#endif
// just add it to the front of the free list
list_add(&free_slices, block);
list_add( &free_slices, block );
--n_slices;
}

View file

@ -29,11 +29,11 @@
** @param[in,out] list The address of a list_t variable
** @param[in] data The data to prepend to the list
*/
void list_add(list_t *list, void *data)
{
void list_add( list_t *list, void *data ) {
// sanity checks
assert1(list != NULL);
assert1(data != NULL);
assert1( list != NULL );
assert1( data != NULL );
list_t *tmp = (list_t *)data;
tmp->next = list->next;
@ -49,15 +49,16 @@ void list_add(list_t *list, void *data)
**
** @return a pointer to the removed data, or NULL if the list was empty
*/
void *list_remove(list_t *list)
{
assert1(list != NULL);
void *list_remove( list_t *list ) {
assert1( list != NULL );
list_t *data = list->next;
if (data != NULL) {
if( data != NULL ) {
list->next = data->next;
data->next = NULL;
}
return (void *)data;
}

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,64 @@
/**
** @file sio.c
**
** @author Warren R. Carithers
**
** @brief SIO module
**
** For maximum compatibility from semester to semester, this code uses
** several "stand-in" type names and macros which should be defined
** in the accompanying "compat.h" header file if they're not part of
** the baseline system:
**
** standard-sized integer types: intN_t, uintN_t
** other types: PCBTYPE, QTYPE
** scheduler functions: SCHED, DISPATCH
** queue functions: QCREATE, QLENGTH, QDEQUE
** other functions: SLENGTH
** sio read queue: QNAME
**
** Our SIO scheme is very simple:
**
** Input: We maintain a buffer of incoming characters that haven't
** yet been read by processes. When a character comes in, if
** there is no process waiting for it, it goes in the buffer;
** otherwise, the first waiting process is awakeneda and it
** gets the character.
**
** When a process invokes readch(), if there is a character in
** the input buffer, the process gets it; otherwise, it is
** blocked until input appears
**
** Communication with system calls is via two routines.
** sio_readc() returns the first available character (if
** there is one), resetting the input variables if this was
** the last character in the buffer. If there are no
** characters in the buffer, sio_read() returns a -1
** (presumably so the requesting process can be blocked).
**
** sio_read() copies the contents of the input buffer into
** a user-supplied buffer. It returns the number of characters
** copied. If there are no characters available, return a -1.
**
** Output: We maintain a buffer of outgoing characters that haven't
** yet been sent to the device, and an indication of whether
** or not we are in the middle of a transmit sequence. When
** an interrupt comes in, if there is another character to
** send we copy it to the transmitter buffer; otherwise, we
** end the transmit sequence.
**
** Communication with user processes is via three functions.
** sio_writec() writes a single character; sio_write()
** writes a sized buffer full of characters; sio_puts()
** prints a NUL-terminated string. If we are in the middle
** of a transmit sequence, all characters will be added
** to the output buffer (from where they will be sent
** automatically); otherwise, we send the first character
** directly, add the rest of the characters (if there are
** any) to the output buffer, and set the "sending" flag
** to indicate that we're expecting a transmitter interrupt.
*/
#define KERNEL_SRC
// this should do all includes required for this OS
@ -15,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;
/*
@ -45,7 +106,7 @@ static uint8_t ier;
// queue for read-blocked processes
#ifdef QNAME
extern QTYPE QNAME;
QTYPE QNAME;
#endif
/*
@ -61,40 +122,41 @@ 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
@ -104,18 +166,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 */
@ -125,7 +187,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;
}
@ -137,64 +199,65 @@ 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 );
}
/*
@ -206,27 +269,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.
@ -236,11 +299,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
@ -249,36 +312,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 );
}
/**
@ -292,8 +355,7 @@ 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
@ -302,23 +364,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 );
}
/**
@ -332,8 +394,7 @@ uint8_t sio_enable(uint8_t which)
**
** @return the prior IER setting
*/
uint8_t sio_disable(uint8_t which)
{
uint8_t sio_disable( uint8_t which ) {
uint8_t old;
// remember the current status
@ -342,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 );
}
/**
@ -370,9 +431,8 @@ 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 );
}
/**
@ -384,29 +444,31 @@ 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
ch = -1;
//
//
// 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 );
}
/**
@ -422,15 +484,14 @@ 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 );
}
//
@ -438,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;
@ -449,15 +510,16 @@ 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 )
**
@ -467,21 +529,22 @@ 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;
@ -492,11 +555,12 @@ 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 );
}
/**
@ -511,8 +575,7 @@ void sio_writec(int ch)
**
** @return the number of characters copied into the SIO output buffer
*/
int sio_write(const char *buffer, int length)
{
int sio_write( const char *buffer, int length ) {
int first = *buffer;
const char *ptr = buffer;
int copied = 0;
@ -524,15 +587,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;
@ -545,13 +608,15 @@ 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 );
}
/**
@ -565,14 +630,13 @@ 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 );
}
/**
@ -587,43 +651,44 @@ 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: \"");
ptr = innext;
for (n = 0; n < incount; ++n) {
put_char_or_code(*ptr++);
if( incount ) {
cio_puts( "SIO input queue: \"" );
ptr = innext;
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: \"");
ptr = outnext;
for (n = 0; n < outcount; ++n) {
put_char_or_code(*ptr++);
if( outcount ) {
cio_puts( "SIO output queue: \"" );
cio_puts( " ot: \"" );
ptr = outnext;
for( n = 0; n < outcount; ++n ) {
put_char_or_code( *ptr++ );
}
cio_puts("\"\n");
cio_puts( "\"\n" );
}
}

153
kernel/old/startup.S Normal file
View file

@ -0,0 +1,153 @@
/*
** @file startup.S
**
** @author Jon Coles
** @authors Warren R. Carithers, K. Reek
**
** SP startup code.
**
** This code prepares the various registers for execution of
** the program. It sets up all the segment registers and the
** runtime stack. By the time this code is running, we're in
** protected mode already.
*/
#define KERNEL_SRC
#define ASM_SRC
# .arch i386
#include <common.h>
#include <bootstrap.h>
#include <x86/arch.h>
#include <x86/bios.h>
#include <vm.h>
/*
** Configuration options - define in Makefile
**
** CLEAR_BSS include code to clear all BSS space
** OS_CONFIG OS-related (vs. just standalone) variations
*/
/*
** A symbol for locating the beginning of the code.
*/
.globl begtext
.text
begtext:
/*
** The entry point. When we get here, we have just entered protected
** mode, so all the segment registers are incorrect except for CS.
*/
.globl _start
_start:
cli /* seems to be reset on entry to p. mode */
movb $NMI_ENABLE, %al /* re-enable NMIs (bootstrap */
outb $CMOS_ADDR /* turned them off) */
/*
** Set the data and stack segment registers (code segment register
** was set by the long jump that switched us into protected mode).
*/
xorl %eax, %eax /* clear EAX */
movw $GDT_DATA, %ax /* GDT entry #3 - data segment */
movw %ax, %ds /* for all four data segment registers */
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw $GDT_STACK, %ax /* entry #4 is the stack segment */
movw %ax, %ss
movl $TARGET_STACK, %esp /* set up the system stack pointer */
#ifdef CLEAR_BSS
/*
** Zero the BSS segment
**
** These symbols are defined automatically by the linker, but they're
** defined at their virtual addresses rather than their physical addresses,
** and we haven't enabled paging yet.
*/
.globl __bss_start, _end
movl $V2PNC(__bss_start), %edi
clearbss:
movl $0, (%edi)
addl $4, %edi
cmpl $V2PNC(_end), %edi
jb clearbss
#endif /* CLEAR_BSS */
/*
** Enable paging. We use "large" pages for the initial page directory
** so that a one-level hierarchy will work for us. Once we have set
** up our memory freelist, we'll create a two-level hierarchy using
** "normal" 4KB pages.
*/
# enable large pages
movl %cr4, %eax
orl $(CR4_PSE), %eax
movl %eax, %cr4
# set the page directory
.globl firstpdir
movl $(V2PNC(firstpdir)), %eax
movl %eax, %cr3
# turn on paging
movl %cr0, %eax
orl $(CR0_PG), %eax
movl %eax, %cr0
# reset our stack pointer
movl $(kstack + SZ_KSTACK), %esp
# set the initial frame pointer
xorl %ebp, %ebp
/*
** Call the system initialization routine, and switch to
** executing at high addresses. We use an indirect jump
** here to avoid getting a PC-relative 'jmp' instruction.
**
** Alternate idea: push the address of isr_restore
** and just do an indirect jump?
*/
.globl main
movl $main, %eax
call *%eax
/*
** At this point, main() must have created the first user
** process, and we're ready to shift into user mode. The user
** stack for that process must have the initial context in it;
** we treat this as a "return from interrupt" event, and just
** transfer to the code that restores the user context.
*/
.globl isr_restore
jmp isr_restore
.data
/*
** Define the kernel stack here, at a multiple-of-16 address
*/
.p2align 4
.globl kstack
kstack: .space SZ_KSTACK, 0
/*
** Define the initial kernel ESP here, as well. It should point
** to the first byte after the stack.
*/
.globl kernel_esp
kernel_esp:
.long kstack + SZ_KSTACK

View file

@ -29,16 +29,16 @@
** each interrupt. These functions are called from the isr stub based
** on the interrupt number.
*/
void (*isr_table[256])(int vector, int code);
void ( *isr_table[ 256 ] )( int vector, int code );
/*
** Format of an IDT entry.
*/
typedef struct {
short offset_15_0;
short segment_selector;
short flags;
short offset_31_16;
typedef struct {
short offset_15_0;
short segment_selector;
short flags;
short offset_31_16;
} IDT_Gate;
/*
@ -59,12 +59,11 @@ typedef struct {
#ifdef RPT_INT_UNEXP
/* add any header includes you need here */
#endif
static void unexpected_handler(int vector, int code)
{
static void unexpected_handler( int vector, int code ) {
#ifdef RPT_INT_UNEXP
cio_printf("\n** UNEXPECTED vector %d code %d\n", vector, code);
cio_printf( "\n** UNEXPECTED vector %d code %d\n", vector, code );
#endif
panic("Unexpected interrupt");
panic( "Unexpected interrupt" );
}
/**
@ -76,24 +75,23 @@ static void unexpected_handler(int vector, int code)
** @param vector vector number for the interrupt that occurred
** @param code error code, or a dummy value
*/
static void default_handler(int vector, int code)
{
static void default_handler( int vector, int code ) {
#ifdef RPT_INT_UNEXP
cio_printf("\n** vector %d code %d\n", vector, code);
cio_printf( "\n** vector %d code %d\n", vector, code );
#endif
if (vector >= 0x20 && vector < 0x30) {
if (vector > 0x27) {
if( vector >= 0x20 && vector < 0x30 ) {
if( vector > 0x27 ) {
// must also ACK the secondary PIC
outb(PIC2_CMD, PIC_EOI);
outb( PIC2_CMD, PIC_EOI );
}
outb(PIC1_CMD, PIC_EOI);
outb( PIC1_CMD, PIC_EOI );
} else {
/*
** All the "expected" interrupts will be handled by the
** code above. If we get down here, the isr table may
** have been corrupted. Print a message and don't return.
*/
panic("Unexpected \"expected\" interrupt!");
panic( "Unexpected \"expected\" interrupt!" );
}
}
@ -108,12 +106,12 @@ static void default_handler(int vector, int code)
** @param vector vector number for the interrupt that occurred
** @param code error code, or a dummy value
*/
static void mystery_handler(int vector, int code)
{
static void mystery_handler( int vector, int code ) {
#if defined(RPT_INT_MYSTERY) || defined(RPT_INT_UNEXP)
cio_printf("\nMystery interrupt!\nVector=0x%02x, code=%d\n", vector, code);
cio_printf( "\nMystery interrupt!\nVector=0x%02x, code=%d\n",
vector, code );
#endif
outb(PIC1_CMD, PIC_EOI);
outb( PIC1_CMD, PIC_EOI );
}
/**
@ -121,38 +119,37 @@ static void mystery_handler(int vector, int code)
**
** Initialize the 8259 Programmable Interrupt Controller.
*/
static void init_pic(void)
{
static void init_pic( void ) {
/*
** ICW1: start the init sequence, update ICW4
*/
outb(PIC1_CMD, PIC_CW1_INIT | PIC_CW1_NEED4);
outb(PIC2_CMD, PIC_CW1_INIT | PIC_CW1_NEED4);
outb( PIC1_CMD, PIC_CW1_INIT | PIC_CW1_NEED4 );
outb( PIC2_CMD, PIC_CW1_INIT | PIC_CW1_NEED4 );
/*
** ICW2: primary offset of 0x20 in the IDT, secondary offset of 0x28
*/
outb(PIC1_DATA, PIC1_CW2_VECBASE);
outb(PIC2_DATA, PIC2_CW2_VECBASE);
outb( PIC1_DATA, PIC1_CW2_VECBASE );
outb( PIC2_DATA, PIC2_CW2_VECBASE );
/*
** ICW3: secondary attached to line 2 of primary, bit mask is 00000100
** secondary id is 2
*/
outb(PIC1_DATA, PIC1_CW3_SEC_IRQ2);
outb(PIC2_DATA, PIC2_CW3_SEC_ID);
outb( PIC1_DATA, PIC1_CW3_SEC_IRQ2 );
outb( PIC2_DATA, PIC2_CW3_SEC_ID );
/*
** ICW4: want 8086 mode, not 8080/8085 mode
*/
outb(PIC1_DATA, PIC_CW4_PM86);
outb(PIC2_DATA, PIC_CW4_PM86);
outb( PIC1_DATA, PIC_CW4_PM86 );
outb( PIC2_DATA, PIC_CW4_PM86 );
/*
** OCW1: allow interrupts on all lines
*/
outb(PIC1_DATA, PIC_MASK_NONE);
outb(PIC2_DATA, PIC_MASK_NONE);
outb( PIC1_DATA, PIC_MASK_NONE );
outb( PIC2_DATA, PIC_MASK_NONE );
}
/**
@ -166,8 +163,7 @@ static void init_pic(void)
** Note: generally, the handler invoked from the IDT will be a "stub"
** that calls the second-level C handler via the isr_table array.
*/
static void set_idt_entry(int entry, void (*handler)(void))
{
static void set_idt_entry( int entry, void ( *handler )( void ) ) {
IDT_Gate *g = (IDT_Gate *)IDT_ADDR + entry;
g->offset_15_0 = (int)handler & 0xffff;
@ -185,18 +181,17 @@ static void set_idt_entry(int entry, void (*handler)(void))
** are then installed for those interrupts we may get before a real
** handler is set up.
*/
static void init_idt(void)
{
static void init_idt( void ) {
int i;
extern void (*isr_stub_table[256])(void);
extern void ( *isr_stub_table[ 256 ] )( void );
/*
** Make each IDT entry point to the stub for that vector. Also
** make each entry in the ISR table point to the default handler.
*/
for (i = 0; i < 256; i++) {
set_idt_entry(i, isr_stub_table[i]);
install_isr(i, unexpected_handler);
for ( i=0; i < 256; i++ ) {
set_idt_entry( i, isr_stub_table[ i ] );
install_isr( i, unexpected_handler );
}
/*
@ -205,13 +200,13 @@ static void init_idt(void)
** will eventually install the "real" handler.
*/
install_isr(VEC_KBD, default_handler); // cio_init()
install_isr(VEC_COM1, default_handler); // sio_init()
install_isr(VEC_TIMER, default_handler); // clk_init()
install_isr(VEC_SYSCALL, default_handler); // sys_init()
install_isr(VEC_PAGE_FAULT, default_handler); // vm_init()
install_isr( VEC_KBD, default_handler ); // cio_init()
install_isr( VEC_COM1, default_handler ); // sio_init()
install_isr( VEC_TIMER, default_handler ); // clk_init()
install_isr( VEC_SYSCALL, default_handler ); // sys_init()
install_isr( VEC_PAGE_FAULT, default_handler ); // vm_init()
install_isr(VEC_MYSTERY, mystery_handler);
install_isr( VEC_MYSTERY, mystery_handler );
}
/*
@ -226,11 +221,10 @@ static void init_idt(void)
**
** Called when we find an unrecoverable error.
*/
void panic(char *reason)
{
__asm__("cli");
cio_printf("\nPANIC: %s\nHalting...", reason);
for (;;) {
void panic( char *reason ) {
__asm__( "cli" );
cio_printf( "\nPANIC: %s\nHalting...", reason );
for(;;) {
;
}
}
@ -240,8 +234,7 @@ void panic(char *reason)
**
** (Re)initilizes the interrupt system.
*/
void init_interrupts(void)
{
void init_interrupts( void ) {
init_idt();
init_pic();
}
@ -251,12 +244,13 @@ void init_interrupts(void)
**
** Installs a second-level handler for a specific interrupt.
*/
void (*install_isr(int vector, void (*handler)(int, int)))(int, int)
{
void (*old_handler)(int vector, int code);
void (*install_isr( int vector,
void (*handler)(int,int) ) ) ( int, int ) {
old_handler = isr_table[vector];
isr_table[vector] = handler;
void ( *old_handler )( int vector, int code );
old_handler = isr_table[ vector ];
isr_table[ vector ] = handler;
return old_handler;
}
@ -276,10 +270,10 @@ void (*install_isr(int vector, void (*handler)(int, int)))(int, int)
**
** Ultimately, just remember that DELAY VALUES ARE APPROXIMATE AT BEST.
*/
void delay(int length)
{
while (--length >= 0) {
for (int i = 0; i < 10000000; ++i)
void delay( int length ) {
while( --length >= 0 ) {
for( int i = 0; i < 10000000; ++i )
;
}
}

View file

@ -6,7 +6,7 @@
** @brief System call implementations
*/
#define KERNEL_SRC
#define KERNEL_SRC
#include <common.h>
@ -33,30 +33,28 @@
#if TRACING_SYSCALLS
#define SYSCALL_ENTER(x) \
do { \
cio_printf("--> %s, pid %08x", __func__, (uint32_t)(x)); \
} while (0)
#define SYSCALL_ENTER(x) do { \
cio_printf( "--> %s, pid %08x", __func__, (uint32_t) (x) ); \
} while(0)
#else
#define SYSCALL_ENTER(x) /* */
#define SYSCALL_ENTER(x) /* */
#endif /* TRACING_SYSCALLS */
#endif /* TRACING_SYSCALLS */
#if TRACING_SYSRETS
#define SYSCALL_EXIT(x) \
do { \
cio_printf("<-- %s %08x\n", __func__, (uint32_t)(x)); \
return; \
} while (0)
#define SYSCALL_EXIT(x) do { \
cio_printf( "<-- %s %08x\n", __func__, (uint32_t) (x) ); \
return; \
} while(0)
#else
#define SYSCALL_EXIT(x) return
#endif /* TRACING_SYSRETS */
#endif /* TRACING_SYSRETS */
/*
** PRIVATE DATA TYPES
@ -73,7 +71,7 @@
// a macro to simplify syscall entry point specification
// we don't declare these static because we may want to call
// some of them from other parts of the kernel
#define SYSIMPL(x) void sys_##x(pcb_t *pcb)
#define SYSIMPL(x) void sys_##x( pcb_t * pcb )
/*
** Second-level syscall handlers
@ -97,26 +95,26 @@
**
** Does not return
*/
SYSIMPL(exit)
{
// sanity check
assert(pcb != NULL);
SYSIMPL(exit) {
SYSCALL_ENTER(pcb->pid);
// sanity check
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
// retrieve the exit status of this process
pcb->exit_status = (int32_t)ARG(pcb, 1);
pcb->exit_status = (int32_t) ARG(pcb,1);
// now, we need to do the following:
// reparent any children of this process and wake up init if need be
// find this process' parent and wake it up if it's waiting
pcb_zombify(pcb);
pcb_zombify( pcb );
// pick a new winner
dispatch();
SYSCALL_EXIT(0);
SYSCALL_EXIT( 0 );
}
/**
@ -130,12 +128,12 @@ SYSIMPL(exit)
** terminated, or an error code; on success, returns the child's termination
** status via 'status' if that pointer is non-NULL.
*/
SYSIMPL(waitpid)
{
// sanity check
assert(pcb != NULL);
SYSIMPL(waitpid) {
SYSCALL_ENTER(pcb->pid);
// sanity check
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
/*
** We need to do two things here: (1) find out whether or
@ -153,42 +151,47 @@ SYSIMPL(waitpid)
*/
// verify that we aren't looking for ourselves!
uint_t target = ARG(pcb, 1);
uint_t target = ARG(pcb,1);
if (target == pcb->pid) {
if( target == pcb->pid ) {
RET(pcb) = E_BAD_PARAM;
SYSCALL_EXIT(E_BAD_PARAM);
SYSCALL_EXIT( E_BAD_PARAM );
}
// Good. Now, figure out what we're looking for.
pcb_t *child = NULL;
if (target != 0) {
// we're looking for a specific child
child = pcb_find_pid(target);
if( target != 0 ) {
// we're looking for a specific child
child = pcb_find_pid( target );
if( child != NULL ) {
if (child != NULL) {
// found the process; is it one of our children:
if (child->parent != pcb) {
if( child->parent != pcb ) {
// NO, so we can't wait for it
RET(pcb) = E_BAD_PARAM;
SYSCALL_EXIT(E_BAD_PARAM);
SYSCALL_EXIT( E_BAD_PARAM );
}
// yes! is this one ready to be collected?
if (child->state != STATE_ZOMBIE) {
if( child->state != STATE_ZOMBIE ) {
// no, so we'll have to block for now
child = NULL;
}
} else {
// no such child
RET(pcb) = E_BAD_PARAM;
SYSCALL_EXIT(E_BAD_PARAM);
SYSCALL_EXIT( E_BAD_PARAM );
}
} else {
// looking for any child
// we need to find a process that is our child
@ -201,13 +204,15 @@ SYSIMPL(waitpid)
// so we need to do the iteration ourselves
register pcb_t *curr = ptable;
for (int i = 0; i < N_PROCS; ++i, ++curr) {
if (curr->parent == pcb) {
for( int i = 0; i < N_PROCS; ++i, ++curr ) {
if( curr->parent == pcb ) {
// found one!
found = true;
// has it already exited?
if (curr->state == STATE_ZOMBIE) {
if( curr->state == STATE_ZOMBIE ) {
// yes, so we're done here
child = curr;
break;
@ -215,11 +220,12 @@ SYSIMPL(waitpid)
}
}
if (!found) {
if( !found ) {
// got through the loop without finding a child!
RET(pcb) = E_NO_CHILDREN;
SYSCALL_EXIT(E_NO_CHILDREN);
SYSCALL_EXIT( E_NO_CHILDREN );
}
}
/*
@ -235,24 +241,25 @@ SYSIMPL(waitpid)
*/
// did we find one to collect?
if (child == NULL) {
if( child == NULL ) {
// no - mark the parent as "Waiting"
pcb->state = STATE_WAITING;
assert(pcb_queue_insert(waiting, pcb) == SUCCESS);
assert( pcb_queue_insert(waiting,pcb) == SUCCESS );
// select a new current process
dispatch();
SYSCALL_EXIT((uint32_t)current);
SYSCALL_EXIT( (uint32_t) current );
}
// found a Zombie; collect its information and clean it up
RET(pcb) = child->pid;
// get "status" pointer from parent
int32_t *stat = (int32_t *)ARG(pcb, 2);
int32_t *stat = (int32_t *) ARG(pcb,2);
// if stat is NULL, the parent doesn't want the status
if (stat != NULL) {
if( stat != NULL ) {
// ********************************************************
// ** Potential VM issue here! This code assigns the exit
// ** status into a variable in the parent's address space.
@ -265,9 +272,9 @@ SYSIMPL(waitpid)
}
// clean up the child
pcb_cleanup(child);
pcb_cleanup( child );
SYSCALL_EXIT(RET(pcb));
SYSCALL_EXIT( RET(pcb) );
}
/**
@ -280,26 +287,26 @@ SYSIMPL(waitpid)
** Returns the child's PID to the parent, and 0 to the child, on success;
** else, returns an error code to the parent.
*/
SYSIMPL(fork)
{
// sanity check
assert(pcb != NULL);
SYSIMPL(fork) {
SYSCALL_ENTER(pcb->pid);
// sanity check
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
// Make sure there's room for another process!
pcb_t *new;
if (pcb_alloc(&new) != SUCCESS || new == NULL) {
if( pcb_alloc(&new) != SUCCESS || new == NULL ) {
RET(pcb) = E_NO_PROCS;
SYSCALL_EXIT(RET(pcb));
SYSCALL_EXIT( RET(pcb) );
}
// duplicate the memory image of the parent
int status = user_duplicate(new, pcb);
if (status != SUCCESS) {
pcb_free(new);
int status = user_duplicate( new, pcb );
if( status != SUCCESS ) {
pcb_free( new );
RET(pcb) = status;
SYSCALL_EXIT(status);
SYSCALL_EXIT( status );
}
// Set the child's identity.
@ -315,9 +322,9 @@ SYSIMPL(fork)
RET(new) = 0;
// Schedule the child, and let the parent continue.
schedule(new);
schedule( new );
SYSCALL_EXIT(new->pid);
SYSCALL_EXIT( new->pid );
}
/**
@ -334,30 +341,30 @@ SYSIMPL(fork)
SYSIMPL(exec)
{
// sanity check
assert(pcb != NULL);
assert( pcb != NULL );
uint_t what = ARG(pcb, 1);
const char **args = (const char **)ARG(pcb, 2);
uint_t what = ARG(pcb,1);
const char **args = (const char **) ARG(pcb,2);
SYSCALL_ENTER(pcb->pid);
SYSCALL_ENTER( pcb->pid );
// locate the requested program
prog_t *prog = user_locate(what);
if (prog == NULL) {
prog_t *prog = user_locate( what );
if( prog == NULL ) {
RET(pcb) = E_NOT_FOUND;
SYSCALL_EXIT(E_NOT_FOUND);
SYSCALL_EXIT( E_NOT_FOUND );
}
// we have located the program, but before we can load it,
// we need to clean up the existing VM hierarchy
vm_free(pcb->pdir);
vm_free( pcb->pdir );
pcb->pdir = NULL;
// "load" it and set up the VM tables for this process
int status = user_load(prog, pcb, args, false);
if (status != SUCCESS) {
int status = user_load( prog, pcb, args );
if( status != SUCCESS ) {
RET(pcb) = status;
SYSCALL_EXIT(status);
SYSCALL_EXIT( status );
}
/*
@ -373,7 +380,7 @@ SYSIMPL(exec)
** an error status to it.
*/
schedule(pcb);
schedule( pcb );
dispatch();
}
@ -387,49 +394,52 @@ SYSIMPL(exec)
** Reads up to 'length' bytes from 'chan' into 'buffer'. Returns the
** count of bytes actually transferred.
*/
SYSIMPL(read)
{
SYSIMPL(read) {
// sanity check
assert(pcb != NULL);
SYSCALL_ENTER(pcb->pid);
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
// grab the arguments
uint_t chan = ARG(pcb, 1);
char *buf = (char *)ARG(pcb, 2);
uint_t len = ARG(pcb, 3);
uint_t chan = ARG(pcb,1);
char *buf = (char *) ARG(pcb,2);
uint_t len = ARG(pcb,3);
// if the buffer is of length 0, we're done!
if (len == 0) {
if( len == 0 ) {
RET(pcb) = 0;
SYSCALL_EXIT(0);
SYSCALL_EXIT( 0 );
}
// try to get the next character(s)
int n = 0;
if (chan == CHAN_CIO) {
if( chan == CHAN_CIO ) {
// console input is non-blocking
if (cio_input_queue() < 1) {
if( cio_input_queue() < 1 ) {
RET(pcb) = 0;
SYSCALL_EXIT(0);
SYSCALL_EXIT( 0 );
}
// at least one character
n = cio_gets(buf, len);
n = cio_gets( buf, len );
RET(pcb) = n;
SYSCALL_EXIT(n);
SYSCALL_EXIT( n );
} else if( chan == CHAN_SIO ) {
} else if (chan == CHAN_SIO) {
// SIO input is blocking, so if there are no characters
// available, we'll block this process
n = sio_read(buf, len);
n = sio_read( buf, len );
RET(pcb) = n;
SYSCALL_EXIT(n);
SYSCALL_EXIT( n );
}
// bad channel code
RET(pcb) = E_BAD_PARAM;
SYSCALL_EXIT(E_BAD_PARAM);
SYSCALL_EXIT( E_BAD_PARAM );
}
/**
@ -441,17 +451,17 @@ SYSIMPL(read)
** Writes 'length' bytes from 'buffer' to 'chan'. Returns the
** count of bytes actually transferred.
*/
SYSIMPL(write)
{
// sanity check
assert(pcb != NULL);
SYSIMPL(write) {
SYSCALL_ENTER(pcb->pid);
// sanity check
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
// grab the parameters
uint_t chan = ARG(pcb, 1);
char *buf = (char *)ARG(pcb, 2);
uint_t length = ARG(pcb, 3);
uint_t chan = ARG(pcb,1);
char *buf = (char *) ARG(pcb,2);
uint_t length = ARG(pcb,3);
// this is almost insanely simple, but it does separate the
// low-level device access fromm the higher-level syscall implementation
@ -460,21 +470,27 @@ SYSIMPL(write)
int rval = length;
// simplest case
if (length >= 0) {
if (chan == CHAN_CIO) {
cio_write(buf, length);
if( length >= 0 ) {
} else if (chan == CHAN_SIO) {
sio_write(buf, length);
if( chan == CHAN_CIO ) {
cio_write( buf, length );
} else if( chan == CHAN_SIO ) {
sio_write( buf, length );
} else {
rval = E_BAD_CHAN;
}
}
RET(pcb) = rval;
SYSCALL_EXIT(rval);
SYSCALL_EXIT( rval );
}
/**
@ -483,12 +499,12 @@ SYSIMPL(write)
** Implements:
** uint_t getpid( void );
*/
SYSIMPL(getpid)
{
// sanity check!
assert(pcb != NULL);
SYSIMPL(getpid) {
SYSCALL_ENTER(pcb->pid);
// sanity check!
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
// return the time
RET(pcb) = pcb->pid;
@ -500,13 +516,13 @@ SYSIMPL(getpid)
** Implements:
** uint_t getppid( void );
*/
SYSIMPL(getppid)
{
// sanity check!
assert(pcb != NULL);
assert(pcb->parent != NULL);
SYSIMPL(getppid) {
SYSCALL_ENTER(pcb->pid);
// sanity check!
assert( pcb != NULL );
assert( pcb->parent != NULL );
SYSCALL_ENTER( pcb->pid );
// return the time
RET(pcb) = pcb->parent->pid;
@ -518,12 +534,12 @@ SYSIMPL(getppid)
** Implements:
** uint32_t gettime( void );
*/
SYSIMPL(gettime)
{
// sanity check!
assert(pcb != NULL);
SYSIMPL(gettime) {
SYSCALL_ENTER(pcb->pid);
// sanity check!
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
// return the time
RET(pcb) = system_time;
@ -535,12 +551,12 @@ SYSIMPL(gettime)
** Implements:
** int getprio( void );
*/
SYSIMPL(getprio)
{
// sanity check!
assert(pcb != NULL);
SYSIMPL(getprio) {
SYSCALL_ENTER(pcb->pid);
// sanity check!
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
// return the time
RET(pcb) = pcb->priority;
@ -552,18 +568,18 @@ SYSIMPL(getprio)
** Implements:
** int setprio( int new );
*/
SYSIMPL(setprio)
{
// sanity check!
assert(pcb != NULL);
SYSIMPL(setprio) {
SYSCALL_ENTER(pcb->pid);
// sanity check!
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
// remember the old priority
int old = pcb->priority;
// set the priority
pcb->priority = ARG(pcb, 1);
pcb->priority = ARG(pcb,1);
// return the old value
RET(pcb) = old;
@ -578,55 +594,56 @@ SYSIMPL(setprio)
** Marks the specified process (or the calling process, if PID is 0)
** as "killed". Returns 0 on success, else an error code.
*/
SYSIMPL(kill)
{
// sanity check
assert(pcb != NULL);
SYSIMPL(kill) {
SYSCALL_ENTER(pcb->pid);
// sanity check
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
// who is the victim?
uint_t pid = ARG(pcb, 1);
uint_t pid = ARG(pcb,1);
// if it's this process, convert this into a call to exit()
if (pid == pcb->pid) {
if( pid == pcb->pid ) {
pcb->exit_status = EXIT_KILLED;
pcb_zombify(pcb);
pcb_zombify( pcb );
dispatch();
SYSCALL_EXIT(EXIT_KILLED);
SYSCALL_EXIT( EXIT_KILLED );
}
// must be a valid "ordinary user" PID
// QUESTION: what if it's the idle process?
if (pid < FIRST_USER_PID) {
if( pid < FIRST_USER_PID ) {
RET(pcb) = E_FAILURE;
SYSCALL_EXIT(E_FAILURE);
SYSCALL_EXIT( E_FAILURE );
}
// OK, this is an acceptable victim; see if it exists
pcb_t *victim = pcb_find_pid(pid);
if (victim == NULL) {
pcb_t *victim = pcb_find_pid( pid );
if( victim == NULL ) {
// nope!
RET(pcb) = E_NOT_FOUND;
SYSCALL_EXIT(E_NOT_FOUND);
SYSCALL_EXIT( E_NOT_FOUND );
}
// must have a state that is possible
assert(victim->state >= FIRST_VIABLE && victim->state < N_STATES);
assert( victim->state >= FIRST_VIABLE && victim->state < N_STATES );
// how we perform the kill depends on the victim's state
int32_t status = SUCCESS;
switch (victim->state) {
case STATE_KILLED: // FALL THROUGH
switch( victim->state ) {
case STATE_KILLED: // FALL THROUGH
case STATE_ZOMBIE:
// you can't kill it if it's already dead
RET(pcb) = SUCCESS;
break;
case STATE_READY: // FALL THROUGH
case STATE_SLEEPING: // FALL THROUGH
case STATE_BLOCKED: // FALL THROUGH
case STATE_READY: // FALL THROUGH
case STATE_SLEEPING: // FALL THROUGH
case STATE_BLOCKED: // FALL THROUGH
// here, the process is on a queue somewhere; mark
// it as "killed", and let the scheduler deal with it
victim->state = STATE_KILLED;
@ -636,7 +653,7 @@ SYSIMPL(kill)
case STATE_RUNNING:
// we have met the enemy, and it is us!
pcb->exit_status = EXIT_KILLED;
pcb_zombify(pcb);
pcb_zombify( pcb );
status = EXIT_KILLED;
// we need a new current process
dispatch();
@ -646,8 +663,8 @@ SYSIMPL(kill)
// similar to the 'running' state, but we don't need
// to dispatch a new process
victim->exit_status = EXIT_KILLED;
status = pcb_queue_remove_this(waiting, victim);
pcb_zombify(victim);
status = pcb_queue_remove_this( waiting, victim );
pcb_zombify( victim );
RET(pcb) = status;
break;
@ -655,14 +672,15 @@ SYSIMPL(kill)
// this is a really bad potential problem - we have an
// unexpected or bogus process state, but we didn't
// catch that earlier.
sprint(b256, "*** kill(): victim %d, odd state %d\n", victim->pid,
victim->state);
PANIC(0, b256);
sprint( b256, "*** kill(): victim %d, odd state %d\n",
victim->pid, victim->state );
PANIC( 0, b256 );
}
SYSCALL_EXIT(status);
SYSCALL_EXIT( status );
}
/**
** sys_sleep - put the calling process to sleep for some length of time
**
@ -672,33 +690,35 @@ SYSIMPL(kill)
** Puts the calling process to sleep for 'ms' milliseconds (or just yields
** the CPU if 'ms' is 0). ** Returns the time the process spent sleeping.
*/
SYSIMPL(sleep)
{
// sanity check
assert(pcb != NULL);
SYSIMPL(sleep) {
SYSCALL_ENTER(pcb->pid);
// sanity check
assert( pcb != NULL );
SYSCALL_ENTER( pcb->pid );
// get the desired duration
uint_t length = ARG(pcb, 1);
uint_t length = ARG( pcb, 1 );
if( length == 0 ) {
if (length == 0) {
// just yield the CPU
// sleep duration is 0
RET(pcb) = 0;
// back on the ready queue
schedule(pcb);
schedule( pcb );
} else {
// sleep for a while
pcb->wakeup = system_time + length;
if (pcb_queue_insert(sleeping, pcb) != SUCCESS) {
if( pcb_queue_insert(sleeping,pcb) != SUCCESS ) {
// something strange is happening
WARNING("sleep pcb insert failed");
WARNING( "sleep pcb insert failed" );
// if this is the current process, report an error
if (current == pcb) {
if( current == pcb ) {
RET(pcb) = -1;
}
// return without dispatching a new process
@ -707,7 +727,7 @@ SYSIMPL(sleep)
}
// only dispatch if the current process called us
if (pcb == current) {
if( pcb == current ) {
current = NULL;
dispatch();
}
@ -726,14 +746,20 @@ SYSIMPL(sleep)
** position in the initialization list is irrelevant.
*/
static void (*const syscalls[N_SYSCALLS])(pcb_t *) = {
[SYS_exit] = sys_exit, [SYS_waitpid] = sys_waitpid,
[SYS_fork] = sys_fork, [SYS_exec] = sys_exec,
[SYS_read] = sys_read, [SYS_write] = sys_write,
[SYS_getpid] = sys_getpid, [SYS_getppid] = sys_getppid,
[SYS_gettime] = sys_gettime, [SYS_getprio] = sys_getprio,
[SYS_setprio] = sys_setprio, [SYS_kill] = sys_kill,
[SYS_sleep] = sys_sleep
static void (* const syscalls[N_SYSCALLS])( pcb_t * ) = {
[ SYS_exit ] = sys_exit,
[ SYS_waitpid ] = sys_waitpid,
[ SYS_fork ] = sys_fork,
[ SYS_exec ] = sys_exec,
[ SYS_read ] = sys_read,
[ SYS_write ] = sys_write,
[ SYS_getpid ] = sys_getpid,
[ SYS_getppid ] = sys_getppid,
[ SYS_gettime ] = sys_gettime,
[ SYS_getprio ] = sys_getprio,
[ SYS_setprio ] = sys_setprio,
[ SYS_kill ] = sys_kill,
[ SYS_sleep ] = sys_sleep
};
/**
@ -744,40 +770,40 @@ static void (*const syscalls[N_SYSCALLS])(pcb_t *) = {
** @param vector Vector number for this interrupt
** @param code Error code (0 for this interrupt)
*/
static void sys_isr(int vector, int code)
{
static void sys_isr( int vector, int code ) {
// keep the compiler happy
(void)vector;
(void)code;
(void) vector;
(void) code;
// sanity check!
assert(current != NULL);
assert(current->context != NULL);
assert( current != NULL );
assert( current->context != NULL );
// retrieve the syscall code
int num = REG(current, eax);
int num = REG( current, eax );
#if TRACING_SYSCALLS
cio_printf("** --> SYS pid %u code %u\n", current->pid, num);
cio_printf( "** --> SYS pid %u code %u\n", current->pid, num );
#endif
// validate it
if (num < 0 || num >= N_SYSCALLS) {
if( num < 0 || num >= N_SYSCALLS ) {
// bad syscall number
// could kill it, but we'll just force it to exit
num = SYS_exit;
ARG(current, 1) = EXIT_BAD_SYSCALL;
ARG(current,1) = EXIT_BAD_SYSCALL;
}
// call the handler
syscalls[num](current);
syscalls[num]( current );
#if TRACING_SYSCALLS
cio_printf("** <-- SYS pid %u ret %u\n", current->pid, RET(current));
cio_printf( "** <-- SYS pid %u ret %u\n", current->pid, RET(current) );
#endif
// tell the PIC we're done
outb(PIC1_CMD, PIC_EOI);
outb( PIC1_CMD, PIC_EOI );
}
/*
@ -792,12 +818,12 @@ static void sys_isr(int vector, int code)
** Dependencies:
** Must be called after cio_init()
*/
void sys_init(void)
{
void sys_init( void ) {
#if TRACING_INIT
cio_puts(" Sys");
cio_puts( " Sys" );
#endif
// install the second-stage ISR
install_isr(VEC_SYSCALL, sys_isr);
install_isr( VEC_SYSCALL, sys_isr );
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -11,7 +11,7 @@
** 4MB of main memory.
*/
#define KERNEL_SRC
#define KERNEL_SRC
#include <common.h>
@ -37,167 +37,146 @@ extern char _data[];
// identity-map 4MB virtual address #n to physical 4MB address #n
// used for addresses 0 to 2GB
#define L(n) [n] = (pde_t)((TO_4MFRAME((n))) | (PDE_P | PDE_RW | PDE_PS))
#define L(n) [n] = (pde_t) ( (TO_4MFRAME((n))) | (PDE_P|PDE_RW|PDE_PS) )
// ditto, but adds 512 (0x200) to the index
// used for addresses 2GB to 4GB
#define M(n) \
[n | 0x200] = (pde_t)((TO_4MFRAME((n))) | (PDE_P | PDE_RW | PDE_PS))
#define M(n) [n|0x200] = (pde_t) ( (TO_4MFRAME((n))) | (PDE_P|PDE_RW|PDE_PS) )
ATTR_ALIGNED(SZ_PAGE)
const pde_t firstpdir[N_PDE] = {
// Map VA range [0, 2GB] to PA range [0, 2GB]
L(0x000), L(0x001), L(0x002), L(0x003), L(0x004), L(0x005), L(0x006),
L(0x007), L(0x008), L(0x009), L(0x00a), L(0x00b), L(0x00c), L(0x00d),
L(0x00e), L(0x00f), L(0x010), L(0x011), L(0x012), L(0x013), L(0x014),
L(0x015), L(0x016), L(0x017), L(0x018), L(0x019), L(0x01a), L(0x01b),
L(0x01c), L(0x01d), L(0x01e), L(0x01f), L(0x020), L(0x021), L(0x022),
L(0x023), L(0x024), L(0x025), L(0x026), L(0x027), L(0x028), L(0x029),
L(0x02a), L(0x02b), L(0x02c), L(0x02d), L(0x02e), L(0x02f), L(0x030),
L(0x031), L(0x032), L(0x033), L(0x034), L(0x035), L(0x036), L(0x037),
L(0x038), L(0x039), L(0x03a), L(0x03b), L(0x03c), L(0x03d), L(0x03e),
L(0x03f), L(0x040), L(0x041), L(0x042), L(0x043), L(0x044), L(0x045),
L(0x046), L(0x047), L(0x048), L(0x049), L(0x04a), L(0x04b), L(0x04c),
L(0x04d), L(0x04e), L(0x04f), L(0x050), L(0x051), L(0x052), L(0x053),
L(0x054), L(0x055), L(0x056), L(0x057), L(0x058), L(0x059), L(0x05a),
L(0x05b), L(0x05c), L(0x05d), L(0x05e), L(0x05f), L(0x060), L(0x061),
L(0x062), L(0x063), L(0x064), L(0x065), L(0x066), L(0x067), L(0x068),
L(0x069), L(0x06a), L(0x06b), L(0x06c), L(0x06d), L(0x06e), L(0x06f),
L(0x070), L(0x071), L(0x072), L(0x073), L(0x074), L(0x075), L(0x076),
L(0x077), L(0x078), L(0x079), L(0x07a), L(0x07b), L(0x07c), L(0x07d),
L(0x07e), L(0x07f), L(0x080), L(0x081), L(0x082), L(0x083), L(0x084),
L(0x085), L(0x086), L(0x087), L(0x088), L(0x089), L(0x08a), L(0x08b),
L(0x08c), L(0x08d), L(0x08e), L(0x08f), L(0x090), L(0x091), L(0x092),
L(0x093), L(0x094), L(0x095), L(0x096), L(0x097), L(0x098), L(0x099),
L(0x09a), L(0x09b), L(0x09c), L(0x09d), L(0x09e), L(0x09f), L(0x0a0),
L(0x0a1), L(0x0a2), L(0x0a3), L(0x0a4), L(0x0a5), L(0x0a6), L(0x0a7),
L(0x0a8), L(0x0a9), L(0x0aa), L(0x0ab), L(0x0ac), L(0x0ad), L(0x0ae),
L(0x0af), L(0x0b0), L(0x0b1), L(0x0b2), L(0x0b3), L(0x0b4), L(0x0b5),
L(0x0b6), L(0x0b7), L(0x0b8), L(0x0b9), L(0x0ba), L(0x0bb), L(0x0bc),
L(0x0bd), L(0x0be), L(0x0bf), L(0x0c0), L(0x0c1), L(0x0c2), L(0x0c3),
L(0x0c4), L(0x0c5), L(0x0c6), L(0x0c7), L(0x0c8), L(0x0c9), L(0x0ca),
L(0x0cb), L(0x0cc), L(0x0cd), L(0x0ce), L(0x0cf), L(0x0d0), L(0x0d1),
L(0x0d2), L(0x0d3), L(0x0d4), L(0x0d5), L(0x0d6), L(0x0d7), L(0x0d8),
L(0x0d9), L(0x0da), L(0x0db), L(0x0dc), L(0x0dd), L(0x0de), L(0x0df),
L(0x0e0), L(0x0e1), L(0x0e2), L(0x0e3), L(0x0e4), L(0x0e5), L(0x0e6),
L(0x0e7), L(0x0e8), L(0x0e9), L(0x0ea), L(0x0eb), L(0x0ec), L(0x0ed),
L(0x0ee), L(0x0ef), L(0x0f0), L(0x0f1), L(0x0f2), L(0x0f3), L(0x0f4),
L(0x0f5), L(0x0f6), L(0x0f7), L(0x0f8), L(0x0f9), L(0x0fa), L(0x0fb),
L(0x0fc), L(0x0fd), L(0x0fe), L(0x0ff), L(0x100), L(0x101), L(0x102),
L(0x103), L(0x104), L(0x105), L(0x106), L(0x107), L(0x108), L(0x109),
L(0x10a), L(0x10b), L(0x10c), L(0x10d), L(0x10e), L(0x10f), L(0x110),
L(0x111), L(0x112), L(0x113), L(0x114), L(0x115), L(0x116), L(0x117),
L(0x118), L(0x119), L(0x11a), L(0x11b), L(0x11c), L(0x11d), L(0x11e),
L(0x11f), L(0x120), L(0x121), L(0x122), L(0x123), L(0x124), L(0x125),
L(0x126), L(0x127), L(0x128), L(0x129), L(0x12a), L(0x12b), L(0x12c),
L(0x12d), L(0x12e), L(0x12f), L(0x130), L(0x131), L(0x132), L(0x133),
L(0x134), L(0x135), L(0x136), L(0x137), L(0x138), L(0x139), L(0x13a),
L(0x13b), L(0x13c), L(0x13d), L(0x13e), L(0x13f), L(0x140), L(0x141),
L(0x142), L(0x143), L(0x144), L(0x145), L(0x146), L(0x147), L(0x148),
L(0x149), L(0x14a), L(0x14b), L(0x14c), L(0x14d), L(0x14e), L(0x14f),
L(0x150), L(0x151), L(0x152), L(0x153), L(0x154), L(0x155), L(0x156),
L(0x157), L(0x158), L(0x159), L(0x15a), L(0x15b), L(0x15c), L(0x15d),
L(0x15e), L(0x15f), L(0x160), L(0x161), L(0x162), L(0x163), L(0x164),
L(0x165), L(0x166), L(0x167), L(0x168), L(0x169), L(0x16a), L(0x16b),
L(0x16c), L(0x16d), L(0x16e), L(0x16f), L(0x170), L(0x171), L(0x172),
L(0x173), L(0x174), L(0x175), L(0x176), L(0x177), L(0x178), L(0x179),
L(0x17a), L(0x17b), L(0x17c), L(0x17d), L(0x17e), L(0x17f), L(0x180),
L(0x181), L(0x182), L(0x183), L(0x184), L(0x185), L(0x186), L(0x187),
L(0x188), L(0x189), L(0x18a), L(0x18b), L(0x18c), L(0x18d), L(0x18e),
L(0x18f), L(0x190), L(0x191), L(0x192), L(0x193), L(0x194), L(0x195),
L(0x196), L(0x197), L(0x198), L(0x199), L(0x19a), L(0x19b), L(0x19c),
L(0x19d), L(0x19e), L(0x19f), L(0x1a0), L(0x1a1), L(0x1a2), L(0x1a3),
L(0x1a4), L(0x1a5), L(0x1a6), L(0x1a7), L(0x1a8), L(0x1a9), L(0x1aa),
L(0x1ab), L(0x1ac), L(0x1ad), L(0x1ae), L(0x1af), L(0x1b0), L(0x1b1),
L(0x1b2), L(0x1b3), L(0x1b4), L(0x1b5), L(0x1b6), L(0x1b7), L(0x1b8),
L(0x1b9), L(0x1ba), L(0x1bb), L(0x1bc), L(0x1bd), L(0x1be), L(0x1bf),
L(0x1c0), L(0x1c1), L(0x1c2), L(0x1c3), L(0x1c4), L(0x1c5), L(0x1c6),
L(0x1c7), L(0x1c8), L(0x1c9), L(0x1ca), L(0x1cb), L(0x1cc), L(0x1cd),
L(0x1ce), L(0x1cf), L(0x1d0), L(0x1d1), L(0x1d2), L(0x1d3), L(0x1d4),
L(0x1d5), L(0x1d6), L(0x1d7), L(0x1d8), L(0x1d9), L(0x1da), L(0x1db),
L(0x1dc), L(0x1dd), L(0x1de), L(0x1df), L(0x1e0), L(0x1e1), L(0x1e2),
L(0x1e3), L(0x1e4), L(0x1e5), L(0x1e6), L(0x1e7), L(0x1e8), L(0x1e9),
L(0x1ea), L(0x1eb), L(0x1ec), L(0x1ed), L(0x1ee), L(0x1ef), L(0x1f0),
L(0x1f1), L(0x1f2), L(0x1f3), L(0x1f4), L(0x1f5), L(0x1f6), L(0x1f7),
L(0x1f8), L(0x1f9), L(0x1fa), L(0x1fb), L(0x1fc), L(0x1fd), L(0x1fe),
L(0x1ff),
L(0x000), L(0x001), L(0x002), L(0x003), L(0x004), L(0x005), L(0x006), L(0x007),
L(0x008), L(0x009), L(0x00a), L(0x00b), L(0x00c), L(0x00d), L(0x00e), L(0x00f),
L(0x010), L(0x011), L(0x012), L(0x013), L(0x014), L(0x015), L(0x016), L(0x017),
L(0x018), L(0x019), L(0x01a), L(0x01b), L(0x01c), L(0x01d), L(0x01e), L(0x01f),
L(0x020), L(0x021), L(0x022), L(0x023), L(0x024), L(0x025), L(0x026), L(0x027),
L(0x028), L(0x029), L(0x02a), L(0x02b), L(0x02c), L(0x02d), L(0x02e), L(0x02f),
L(0x030), L(0x031), L(0x032), L(0x033), L(0x034), L(0x035), L(0x036), L(0x037),
L(0x038), L(0x039), L(0x03a), L(0x03b), L(0x03c), L(0x03d), L(0x03e), L(0x03f),
L(0x040), L(0x041), L(0x042), L(0x043), L(0x044), L(0x045), L(0x046), L(0x047),
L(0x048), L(0x049), L(0x04a), L(0x04b), L(0x04c), L(0x04d), L(0x04e), L(0x04f),
L(0x050), L(0x051), L(0x052), L(0x053), L(0x054), L(0x055), L(0x056), L(0x057),
L(0x058), L(0x059), L(0x05a), L(0x05b), L(0x05c), L(0x05d), L(0x05e), L(0x05f),
L(0x060), L(0x061), L(0x062), L(0x063), L(0x064), L(0x065), L(0x066), L(0x067),
L(0x068), L(0x069), L(0x06a), L(0x06b), L(0x06c), L(0x06d), L(0x06e), L(0x06f),
L(0x070), L(0x071), L(0x072), L(0x073), L(0x074), L(0x075), L(0x076), L(0x077),
L(0x078), L(0x079), L(0x07a), L(0x07b), L(0x07c), L(0x07d), L(0x07e), L(0x07f),
L(0x080), L(0x081), L(0x082), L(0x083), L(0x084), L(0x085), L(0x086), L(0x087),
L(0x088), L(0x089), L(0x08a), L(0x08b), L(0x08c), L(0x08d), L(0x08e), L(0x08f),
L(0x090), L(0x091), L(0x092), L(0x093), L(0x094), L(0x095), L(0x096), L(0x097),
L(0x098), L(0x099), L(0x09a), L(0x09b), L(0x09c), L(0x09d), L(0x09e), L(0x09f),
L(0x0a0), L(0x0a1), L(0x0a2), L(0x0a3), L(0x0a4), L(0x0a5), L(0x0a6), L(0x0a7),
L(0x0a8), L(0x0a9), L(0x0aa), L(0x0ab), L(0x0ac), L(0x0ad), L(0x0ae), L(0x0af),
L(0x0b0), L(0x0b1), L(0x0b2), L(0x0b3), L(0x0b4), L(0x0b5), L(0x0b6), L(0x0b7),
L(0x0b8), L(0x0b9), L(0x0ba), L(0x0bb), L(0x0bc), L(0x0bd), L(0x0be), L(0x0bf),
L(0x0c0), L(0x0c1), L(0x0c2), L(0x0c3), L(0x0c4), L(0x0c5), L(0x0c6), L(0x0c7),
L(0x0c8), L(0x0c9), L(0x0ca), L(0x0cb), L(0x0cc), L(0x0cd), L(0x0ce), L(0x0cf),
L(0x0d0), L(0x0d1), L(0x0d2), L(0x0d3), L(0x0d4), L(0x0d5), L(0x0d6), L(0x0d7),
L(0x0d8), L(0x0d9), L(0x0da), L(0x0db), L(0x0dc), L(0x0dd), L(0x0de), L(0x0df),
L(0x0e0), L(0x0e1), L(0x0e2), L(0x0e3), L(0x0e4), L(0x0e5), L(0x0e6), L(0x0e7),
L(0x0e8), L(0x0e9), L(0x0ea), L(0x0eb), L(0x0ec), L(0x0ed), L(0x0ee), L(0x0ef),
L(0x0f0), L(0x0f1), L(0x0f2), L(0x0f3), L(0x0f4), L(0x0f5), L(0x0f6), L(0x0f7),
L(0x0f8), L(0x0f9), L(0x0fa), L(0x0fb), L(0x0fc), L(0x0fd), L(0x0fe), L(0x0ff),
L(0x100), L(0x101), L(0x102), L(0x103), L(0x104), L(0x105), L(0x106), L(0x107),
L(0x108), L(0x109), L(0x10a), L(0x10b), L(0x10c), L(0x10d), L(0x10e), L(0x10f),
L(0x110), L(0x111), L(0x112), L(0x113), L(0x114), L(0x115), L(0x116), L(0x117),
L(0x118), L(0x119), L(0x11a), L(0x11b), L(0x11c), L(0x11d), L(0x11e), L(0x11f),
L(0x120), L(0x121), L(0x122), L(0x123), L(0x124), L(0x125), L(0x126), L(0x127),
L(0x128), L(0x129), L(0x12a), L(0x12b), L(0x12c), L(0x12d), L(0x12e), L(0x12f),
L(0x130), L(0x131), L(0x132), L(0x133), L(0x134), L(0x135), L(0x136), L(0x137),
L(0x138), L(0x139), L(0x13a), L(0x13b), L(0x13c), L(0x13d), L(0x13e), L(0x13f),
L(0x140), L(0x141), L(0x142), L(0x143), L(0x144), L(0x145), L(0x146), L(0x147),
L(0x148), L(0x149), L(0x14a), L(0x14b), L(0x14c), L(0x14d), L(0x14e), L(0x14f),
L(0x150), L(0x151), L(0x152), L(0x153), L(0x154), L(0x155), L(0x156), L(0x157),
L(0x158), L(0x159), L(0x15a), L(0x15b), L(0x15c), L(0x15d), L(0x15e), L(0x15f),
L(0x160), L(0x161), L(0x162), L(0x163), L(0x164), L(0x165), L(0x166), L(0x167),
L(0x168), L(0x169), L(0x16a), L(0x16b), L(0x16c), L(0x16d), L(0x16e), L(0x16f),
L(0x170), L(0x171), L(0x172), L(0x173), L(0x174), L(0x175), L(0x176), L(0x177),
L(0x178), L(0x179), L(0x17a), L(0x17b), L(0x17c), L(0x17d), L(0x17e), L(0x17f),
L(0x180), L(0x181), L(0x182), L(0x183), L(0x184), L(0x185), L(0x186), L(0x187),
L(0x188), L(0x189), L(0x18a), L(0x18b), L(0x18c), L(0x18d), L(0x18e), L(0x18f),
L(0x190), L(0x191), L(0x192), L(0x193), L(0x194), L(0x195), L(0x196), L(0x197),
L(0x198), L(0x199), L(0x19a), L(0x19b), L(0x19c), L(0x19d), L(0x19e), L(0x19f),
L(0x1a0), L(0x1a1), L(0x1a2), L(0x1a3), L(0x1a4), L(0x1a5), L(0x1a6), L(0x1a7),
L(0x1a8), L(0x1a9), L(0x1aa), L(0x1ab), L(0x1ac), L(0x1ad), L(0x1ae), L(0x1af),
L(0x1b0), L(0x1b1), L(0x1b2), L(0x1b3), L(0x1b4), L(0x1b5), L(0x1b6), L(0x1b7),
L(0x1b8), L(0x1b9), L(0x1ba), L(0x1bb), L(0x1bc), L(0x1bd), L(0x1be), L(0x1bf),
L(0x1c0), L(0x1c1), L(0x1c2), L(0x1c3), L(0x1c4), L(0x1c5), L(0x1c6), L(0x1c7),
L(0x1c8), L(0x1c9), L(0x1ca), L(0x1cb), L(0x1cc), L(0x1cd), L(0x1ce), L(0x1cf),
L(0x1d0), L(0x1d1), L(0x1d2), L(0x1d3), L(0x1d4), L(0x1d5), L(0x1d6), L(0x1d7),
L(0x1d8), L(0x1d9), L(0x1da), L(0x1db), L(0x1dc), L(0x1dd), L(0x1de), L(0x1df),
L(0x1e0), L(0x1e1), L(0x1e2), L(0x1e3), L(0x1e4), L(0x1e5), L(0x1e6), L(0x1e7),
L(0x1e8), L(0x1e9), L(0x1ea), L(0x1eb), L(0x1ec), L(0x1ed), L(0x1ee), L(0x1ef),
L(0x1f0), L(0x1f1), L(0x1f2), L(0x1f3), L(0x1f4), L(0x1f5), L(0x1f6), L(0x1f7),
L(0x1f8), L(0x1f9), L(0x1fa), L(0x1fb), L(0x1fc), L(0x1fd), L(0x1fe), L(0x1ff),
// Map VA range [2GB, 4GB] to PA range [0, 2MB]
M(0x000), M(0x001), M(0x002), M(0x003), M(0x004), M(0x005), M(0x006),
M(0x007), M(0x008), M(0x009), M(0x00a), M(0x00b), M(0x00c), M(0x00d),
M(0x00e), M(0x00f), M(0x010), M(0x011), M(0x012), M(0x013), M(0x014),
M(0x015), M(0x016), M(0x017), M(0x018), M(0x019), M(0x01a), M(0x01b),
M(0x01c), M(0x01d), M(0x01e), M(0x01f), M(0x020), M(0x021), M(0x022),
M(0x023), M(0x024), M(0x025), M(0x026), M(0x027), M(0x028), M(0x029),
M(0x02a), M(0x02b), M(0x02c), M(0x02d), M(0x02e), M(0x02f), M(0x030),
M(0x031), M(0x032), M(0x033), M(0x034), M(0x035), M(0x036), M(0x037),
M(0x038), M(0x039), M(0x03a), M(0x03b), M(0x03c), M(0x03d), M(0x03e),
M(0x03f), M(0x040), M(0x041), M(0x042), M(0x043), M(0x044), M(0x045),
M(0x046), M(0x047), M(0x048), M(0x049), M(0x04a), M(0x04b), M(0x04c),
M(0x04d), M(0x04e), M(0x04f), M(0x050), M(0x051), M(0x052), M(0x053),
M(0x054), M(0x055), M(0x056), M(0x057), M(0x058), M(0x059), M(0x05a),
M(0x05b), M(0x05c), M(0x05d), M(0x05e), M(0x05f), M(0x060), M(0x061),
M(0x062), M(0x063), M(0x064), M(0x065), M(0x066), M(0x067), M(0x068),
M(0x069), M(0x06a), M(0x06b), M(0x06c), M(0x06d), M(0x06e), M(0x06f),
M(0x070), M(0x071), M(0x072), M(0x073), M(0x074), M(0x075), M(0x076),
M(0x077), M(0x078), M(0x079), M(0x07a), M(0x07b), M(0x07c), M(0x07d),
M(0x07e), M(0x07f), M(0x080), M(0x081), M(0x082), M(0x083), M(0x084),
M(0x085), M(0x086), M(0x087), M(0x088), M(0x089), M(0x08a), M(0x08b),
M(0x08c), M(0x08d), M(0x08e), M(0x08f), M(0x090), M(0x091), M(0x092),
M(0x093), M(0x094), M(0x095), M(0x096), M(0x097), M(0x098), M(0x099),
M(0x09a), M(0x09b), M(0x09c), M(0x09d), M(0x09e), M(0x09f), M(0x0a0),
M(0x0a1), M(0x0a2), M(0x0a3), M(0x0a4), M(0x0a5), M(0x0a6), M(0x0a7),
M(0x0a8), M(0x0a9), M(0x0aa), M(0x0ab), M(0x0ac), M(0x0ad), M(0x0ae),
M(0x0af), M(0x0b0), M(0x0b1), M(0x0b2), M(0x0b3), M(0x0b4), M(0x0b5),
M(0x0b6), M(0x0b7), M(0x0b8), M(0x0b9), M(0x0ba), M(0x0bb), M(0x0bc),
M(0x0bd), M(0x0be), M(0x0bf), M(0x0c0), M(0x0c1), M(0x0c2), M(0x0c3),
M(0x0c4), M(0x0c5), M(0x0c6), M(0x0c7), M(0x0c8), M(0x0c9), M(0x0ca),
M(0x0cb), M(0x0cc), M(0x0cd), M(0x0ce), M(0x0cf), M(0x0d0), M(0x0d1),
M(0x0d2), M(0x0d3), M(0x0d4), M(0x0d5), M(0x0d6), M(0x0d7), M(0x0d8),
M(0x0d9), M(0x0da), M(0x0db), M(0x0dc), M(0x0dd), M(0x0de), M(0x0df),
M(0x0e0), M(0x0e1), M(0x0e2), M(0x0e3), M(0x0e4), M(0x0e5), M(0x0e6),
M(0x0e7), M(0x0e8), M(0x0e9), M(0x0ea), M(0x0eb), M(0x0ec), M(0x0ed),
M(0x0ee), M(0x0ef), M(0x0f0), M(0x0f1), M(0x0f2), M(0x0f3), M(0x0f4),
M(0x0f5), M(0x0f6), M(0x0f7), M(0x0f8), M(0x0f9), M(0x0fa), M(0x0fb),
M(0x0fc), M(0x0fd), M(0x0fe), M(0x0ff), M(0x100), M(0x101), M(0x102),
M(0x103), M(0x104), M(0x105), M(0x106), M(0x107), M(0x108), M(0x109),
M(0x10a), M(0x10b), M(0x10c), M(0x10d), M(0x10e), M(0x10f), M(0x110),
M(0x111), M(0x112), M(0x113), M(0x114), M(0x115), M(0x116), M(0x117),
M(0x118), M(0x119), M(0x11a), M(0x11b), M(0x11c), M(0x11d), M(0x11e),
M(0x11f), M(0x120), M(0x121), M(0x122), M(0x123), M(0x124), M(0x125),
M(0x126), M(0x127), M(0x128), M(0x129), M(0x12a), M(0x12b), M(0x12c),
M(0x12d), M(0x12e), M(0x12f), M(0x130), M(0x131), M(0x132), M(0x133),
M(0x134), M(0x135), M(0x136), M(0x137), M(0x138), M(0x139), M(0x13a),
M(0x13b), M(0x13c), M(0x13d), M(0x13e), M(0x13f), M(0x140), M(0x141),
M(0x142), M(0x143), M(0x144), M(0x145), M(0x146), M(0x147), M(0x148),
M(0x149), M(0x14a), M(0x14b), M(0x14c), M(0x14d), M(0x14e), M(0x14f),
M(0x150), M(0x151), M(0x152), M(0x153), M(0x154), M(0x155), M(0x156),
M(0x157), M(0x158), M(0x159), M(0x15a), M(0x15b), M(0x15c), M(0x15d),
M(0x15e), M(0x15f), M(0x160), M(0x161), M(0x162), M(0x163), M(0x164),
M(0x165), M(0x166), M(0x167), M(0x168), M(0x169), M(0x16a), M(0x16b),
M(0x16c), M(0x16d), M(0x16e), M(0x16f), M(0x170), M(0x171), M(0x172),
M(0x173), M(0x174), M(0x175), M(0x176), M(0x177), M(0x178), M(0x179),
M(0x17a), M(0x17b), M(0x17c), M(0x17d), M(0x17e), M(0x17f), M(0x180),
M(0x181), M(0x182), M(0x183), M(0x184), M(0x185), M(0x186), M(0x187),
M(0x188), M(0x189), M(0x18a), M(0x18b), M(0x18c), M(0x18d), M(0x18e),
M(0x18f), M(0x190), M(0x191), M(0x192), M(0x193), M(0x194), M(0x195),
M(0x196), M(0x197), M(0x198), M(0x199), M(0x19a), M(0x19b), M(0x19c),
M(0x19d), M(0x19e), M(0x19f), M(0x1a0), M(0x1a1), M(0x1a2), M(0x1a3),
M(0x1a4), M(0x1a5), M(0x1a6), M(0x1a7), M(0x1a8), M(0x1a9), M(0x1aa),
M(0x1ab), M(0x1ac), M(0x1ad), M(0x1ae), M(0x1af), M(0x1b0), M(0x1b1),
M(0x1b2), M(0x1b3), M(0x1b4), M(0x1b5), M(0x1b6), M(0x1b7), M(0x1b8),
M(0x1b9), M(0x1ba), M(0x1bb), M(0x1bc), M(0x1bd), M(0x1be), M(0x1bf),
M(0x1c0), M(0x1c1), M(0x1c2), M(0x1c3), M(0x1c4), M(0x1c5), M(0x1c6),
M(0x1c7), M(0x1c8), M(0x1c9), M(0x1ca), M(0x1cb), M(0x1cc), M(0x1cd),
M(0x1ce), M(0x1cf), M(0x1d0), M(0x1d1), M(0x1d2), M(0x1d3), M(0x1d4),
M(0x1d5), M(0x1d6), M(0x1d7), M(0x1d8), M(0x1d9), M(0x1da), M(0x1db),
M(0x1dc), M(0x1dd), M(0x1de), M(0x1df), M(0x1e0), M(0x1e1), M(0x1e2),
M(0x1e3), M(0x1e4), M(0x1e5), M(0x1e6), M(0x1e7), M(0x1e8), M(0x1e9),
M(0x1ea), M(0x1eb), M(0x1ec), M(0x1ed), M(0x1ee), M(0x1ef), M(0x1f0),
M(0x1f1), M(0x1f2), M(0x1f3), M(0x1f4), M(0x1f5), M(0x1f6), M(0x1f7),
M(0x1f8), M(0x1f9), M(0x1fa), M(0x1fb), M(0x1fc), M(0x1fd), M(0x1fe),
M(0x1ff)
M(0x000), M(0x001), M(0x002), M(0x003), M(0x004), M(0x005), M(0x006), M(0x007),
M(0x008), M(0x009), M(0x00a), M(0x00b), M(0x00c), M(0x00d), M(0x00e), M(0x00f),
M(0x010), M(0x011), M(0x012), M(0x013), M(0x014), M(0x015), M(0x016), M(0x017),
M(0x018), M(0x019), M(0x01a), M(0x01b), M(0x01c), M(0x01d), M(0x01e), M(0x01f),
M(0x020), M(0x021), M(0x022), M(0x023), M(0x024), M(0x025), M(0x026), M(0x027),
M(0x028), M(0x029), M(0x02a), M(0x02b), M(0x02c), M(0x02d), M(0x02e), M(0x02f),
M(0x030), M(0x031), M(0x032), M(0x033), M(0x034), M(0x035), M(0x036), M(0x037),
M(0x038), M(0x039), M(0x03a), M(0x03b), M(0x03c), M(0x03d), M(0x03e), M(0x03f),
M(0x040), M(0x041), M(0x042), M(0x043), M(0x044), M(0x045), M(0x046), M(0x047),
M(0x048), M(0x049), M(0x04a), M(0x04b), M(0x04c), M(0x04d), M(0x04e), M(0x04f),
M(0x050), M(0x051), M(0x052), M(0x053), M(0x054), M(0x055), M(0x056), M(0x057),
M(0x058), M(0x059), M(0x05a), M(0x05b), M(0x05c), M(0x05d), M(0x05e), M(0x05f),
M(0x060), M(0x061), M(0x062), M(0x063), M(0x064), M(0x065), M(0x066), M(0x067),
M(0x068), M(0x069), M(0x06a), M(0x06b), M(0x06c), M(0x06d), M(0x06e), M(0x06f),
M(0x070), M(0x071), M(0x072), M(0x073), M(0x074), M(0x075), M(0x076), M(0x077),
M(0x078), M(0x079), M(0x07a), M(0x07b), M(0x07c), M(0x07d), M(0x07e), M(0x07f),
M(0x080), M(0x081), M(0x082), M(0x083), M(0x084), M(0x085), M(0x086), M(0x087),
M(0x088), M(0x089), M(0x08a), M(0x08b), M(0x08c), M(0x08d), M(0x08e), M(0x08f),
M(0x090), M(0x091), M(0x092), M(0x093), M(0x094), M(0x095), M(0x096), M(0x097),
M(0x098), M(0x099), M(0x09a), M(0x09b), M(0x09c), M(0x09d), M(0x09e), M(0x09f),
M(0x0a0), M(0x0a1), M(0x0a2), M(0x0a3), M(0x0a4), M(0x0a5), M(0x0a6), M(0x0a7),
M(0x0a8), M(0x0a9), M(0x0aa), M(0x0ab), M(0x0ac), M(0x0ad), M(0x0ae), M(0x0af),
M(0x0b0), M(0x0b1), M(0x0b2), M(0x0b3), M(0x0b4), M(0x0b5), M(0x0b6), M(0x0b7),
M(0x0b8), M(0x0b9), M(0x0ba), M(0x0bb), M(0x0bc), M(0x0bd), M(0x0be), M(0x0bf),
M(0x0c0), M(0x0c1), M(0x0c2), M(0x0c3), M(0x0c4), M(0x0c5), M(0x0c6), M(0x0c7),
M(0x0c8), M(0x0c9), M(0x0ca), M(0x0cb), M(0x0cc), M(0x0cd), M(0x0ce), M(0x0cf),
M(0x0d0), M(0x0d1), M(0x0d2), M(0x0d3), M(0x0d4), M(0x0d5), M(0x0d6), M(0x0d7),
M(0x0d8), M(0x0d9), M(0x0da), M(0x0db), M(0x0dc), M(0x0dd), M(0x0de), M(0x0df),
M(0x0e0), M(0x0e1), M(0x0e2), M(0x0e3), M(0x0e4), M(0x0e5), M(0x0e6), M(0x0e7),
M(0x0e8), M(0x0e9), M(0x0ea), M(0x0eb), M(0x0ec), M(0x0ed), M(0x0ee), M(0x0ef),
M(0x0f0), M(0x0f1), M(0x0f2), M(0x0f3), M(0x0f4), M(0x0f5), M(0x0f6), M(0x0f7),
M(0x0f8), M(0x0f9), M(0x0fa), M(0x0fb), M(0x0fc), M(0x0fd), M(0x0fe), M(0x0ff),
M(0x100), M(0x101), M(0x102), M(0x103), M(0x104), M(0x105), M(0x106), M(0x107),
M(0x108), M(0x109), M(0x10a), M(0x10b), M(0x10c), M(0x10d), M(0x10e), M(0x10f),
M(0x110), M(0x111), M(0x112), M(0x113), M(0x114), M(0x115), M(0x116), M(0x117),
M(0x118), M(0x119), M(0x11a), M(0x11b), M(0x11c), M(0x11d), M(0x11e), M(0x11f),
M(0x120), M(0x121), M(0x122), M(0x123), M(0x124), M(0x125), M(0x126), M(0x127),
M(0x128), M(0x129), M(0x12a), M(0x12b), M(0x12c), M(0x12d), M(0x12e), M(0x12f),
M(0x130), M(0x131), M(0x132), M(0x133), M(0x134), M(0x135), M(0x136), M(0x137),
M(0x138), M(0x139), M(0x13a), M(0x13b), M(0x13c), M(0x13d), M(0x13e), M(0x13f),
M(0x140), M(0x141), M(0x142), M(0x143), M(0x144), M(0x145), M(0x146), M(0x147),
M(0x148), M(0x149), M(0x14a), M(0x14b), M(0x14c), M(0x14d), M(0x14e), M(0x14f),
M(0x150), M(0x151), M(0x152), M(0x153), M(0x154), M(0x155), M(0x156), M(0x157),
M(0x158), M(0x159), M(0x15a), M(0x15b), M(0x15c), M(0x15d), M(0x15e), M(0x15f),
M(0x160), M(0x161), M(0x162), M(0x163), M(0x164), M(0x165), M(0x166), M(0x167),
M(0x168), M(0x169), M(0x16a), M(0x16b), M(0x16c), M(0x16d), M(0x16e), M(0x16f),
M(0x170), M(0x171), M(0x172), M(0x173), M(0x174), M(0x175), M(0x176), M(0x177),
M(0x178), M(0x179), M(0x17a), M(0x17b), M(0x17c), M(0x17d), M(0x17e), M(0x17f),
M(0x180), M(0x181), M(0x182), M(0x183), M(0x184), M(0x185), M(0x186), M(0x187),
M(0x188), M(0x189), M(0x18a), M(0x18b), M(0x18c), M(0x18d), M(0x18e), M(0x18f),
M(0x190), M(0x191), M(0x192), M(0x193), M(0x194), M(0x195), M(0x196), M(0x197),
M(0x198), M(0x199), M(0x19a), M(0x19b), M(0x19c), M(0x19d), M(0x19e), M(0x19f),
M(0x1a0), M(0x1a1), M(0x1a2), M(0x1a3), M(0x1a4), M(0x1a5), M(0x1a6), M(0x1a7),
M(0x1a8), M(0x1a9), M(0x1aa), M(0x1ab), M(0x1ac), M(0x1ad), M(0x1ae), M(0x1af),
M(0x1b0), M(0x1b1), M(0x1b2), M(0x1b3), M(0x1b4), M(0x1b5), M(0x1b6), M(0x1b7),
M(0x1b8), M(0x1b9), M(0x1ba), M(0x1bb), M(0x1bc), M(0x1bd), M(0x1be), M(0x1bf),
M(0x1c0), M(0x1c1), M(0x1c2), M(0x1c3), M(0x1c4), M(0x1c5), M(0x1c6), M(0x1c7),
M(0x1c8), M(0x1c9), M(0x1ca), M(0x1cb), M(0x1cc), M(0x1cd), M(0x1ce), M(0x1cf),
M(0x1d0), M(0x1d1), M(0x1d2), M(0x1d3), M(0x1d4), M(0x1d5), M(0x1d6), M(0x1d7),
M(0x1d8), M(0x1d9), M(0x1da), M(0x1db), M(0x1dc), M(0x1dd), M(0x1de), M(0x1df),
M(0x1e0), M(0x1e1), M(0x1e2), M(0x1e3), M(0x1e4), M(0x1e5), M(0x1e6), M(0x1e7),
M(0x1e8), M(0x1e9), M(0x1ea), M(0x1eb), M(0x1ec), M(0x1ed), M(0x1ee), M(0x1ef),
M(0x1f0), M(0x1f1), M(0x1f2), M(0x1f3), M(0x1f4), M(0x1f5), M(0x1f6), M(0x1f7),
M(0x1f8), M(0x1f9), M(0x1fa), M(0x1fb), M(0x1fc), M(0x1fd), M(0x1fe), M(0x1ff)
};
#ifdef MAKE_IDENTITY_MAP
@ -212,170 +191,148 @@ const pde_t firstpdir[N_PDE] = {
*/
// identity-map 4KB page #n
#define S(n) [n] = (pte_t)((TO_4KFRAME((n))) | (PTE_P | PTE_RW))
#define S(n) [n] = (pte_t) ( (TO_4KFRAME((n))) | (PTE_P|PTE_RW) )
const pte_t id_map[N_PTE] = {
S(0x000), S(0x001), S(0x002), S(0x003), S(0x004), S(0x005), S(0x006),
S(0x007), S(0x008), S(0x009), S(0x00a), S(0x00b), S(0x00c), S(0x00d),
S(0x00e), S(0x00f), S(0x010), S(0x011), S(0x012), S(0x013), S(0x014),
S(0x015), S(0x016), S(0x017), S(0x018), S(0x019), S(0x01a), S(0x01b),
S(0x01c), S(0x01d), S(0x01e), S(0x01f), S(0x020), S(0x021), S(0x022),
S(0x023), S(0x024), S(0x025), S(0x026), S(0x027), S(0x028), S(0x029),
S(0x02a), S(0x02b), S(0x02c), S(0x02d), S(0x02e), S(0x02f), S(0x030),
S(0x031), S(0x032), S(0x033), S(0x034), S(0x035), S(0x036), S(0x037),
S(0x038), S(0x039), S(0x03a), S(0x03b), S(0x03c), S(0x03d), S(0x03e),
S(0x03f), S(0x040), S(0x041), S(0x042), S(0x043), S(0x044), S(0x045),
S(0x046), S(0x047), S(0x048), S(0x049), S(0x04a), S(0x04b), S(0x04c),
S(0x04d), S(0x04e), S(0x04f), S(0x050), S(0x051), S(0x052), S(0x053),
S(0x054), S(0x055), S(0x056), S(0x057), S(0x058), S(0x059), S(0x05a),
S(0x05b), S(0x05c), S(0x05d), S(0x05e), S(0x05f), S(0x060), S(0x061),
S(0x062), S(0x063), S(0x064), S(0x065), S(0x066), S(0x067), S(0x068),
S(0x069), S(0x06a), S(0x06b), S(0x06c), S(0x06d), S(0x06e), S(0x06f),
S(0x070), S(0x071), S(0x072), S(0x073), S(0x074), S(0x075), S(0x076),
S(0x077), S(0x078), S(0x079), S(0x07a), S(0x07b), S(0x07c), S(0x07d),
S(0x07e), S(0x07f), S(0x080), S(0x081), S(0x082), S(0x083), S(0x084),
S(0x085), S(0x086), S(0x087), S(0x088), S(0x089), S(0x08a), S(0x08b),
S(0x08c), S(0x08d), S(0x08e), S(0x08f), S(0x090), S(0x091), S(0x092),
S(0x093), S(0x094), S(0x095), S(0x096), S(0x097), S(0x098), S(0x099),
S(0x09a), S(0x09b), S(0x09c), S(0x09d), S(0x09e), S(0x09f), S(0x0a0),
S(0x0a1), S(0x0a2), S(0x0a3), S(0x0a4), S(0x0a5), S(0x0a6), S(0x0a7),
S(0x0a8), S(0x0a9), S(0x0aa), S(0x0ab), S(0x0ac), S(0x0ad), S(0x0ae),
S(0x0af), S(0x0b0), S(0x0b1), S(0x0b2), S(0x0b3), S(0x0b4), S(0x0b5),
S(0x0b6), S(0x0b7), S(0x0b8), S(0x0b9), S(0x0ba), S(0x0bb), S(0x0bc),
S(0x0bd), S(0x0be), S(0x0bf), S(0x0c0), S(0x0c1), S(0x0c2), S(0x0c3),
S(0x0c4), S(0x0c5), S(0x0c6), S(0x0c7), S(0x0c8), S(0x0c9), S(0x0ca),
S(0x0cb), S(0x0cc), S(0x0cd), S(0x0ce), S(0x0cf), S(0x0d0), S(0x0d1),
S(0x0d2), S(0x0d3), S(0x0d4), S(0x0d5), S(0x0d6), S(0x0d7), S(0x0d8),
S(0x0d9), S(0x0da), S(0x0db), S(0x0dc), S(0x0dd), S(0x0de), S(0x0df),
S(0x0e0), S(0x0e1), S(0x0e2), S(0x0e3), S(0x0e4), S(0x0e5), S(0x0e6),
S(0x0e7), S(0x0e8), S(0x0e9), S(0x0ea), S(0x0eb), S(0x0ec), S(0x0ed),
S(0x0ee), S(0x0ef), S(0x0f0), S(0x0f1), S(0x0f2), S(0x0f3), S(0x0f4),
S(0x0f5), S(0x0f6), S(0x0f7), S(0x0f8), S(0x0f9), S(0x0fa), S(0x0fb),
S(0x0fc), S(0x0fd), S(0x0fe), S(0x0ff), S(0x100), S(0x101), S(0x102),
S(0x103), S(0x104), S(0x105), S(0x106), S(0x107), S(0x108), S(0x109),
S(0x10a), S(0x10b), S(0x10c), S(0x10d), S(0x10e), S(0x10f), S(0x110),
S(0x111), S(0x112), S(0x113), S(0x114), S(0x115), S(0x116), S(0x117),
S(0x118), S(0x119), S(0x11a), S(0x11b), S(0x11c), S(0x11d), S(0x11e),
S(0x11f), S(0x120), S(0x121), S(0x122), S(0x123), S(0x124), S(0x125),
S(0x126), S(0x127), S(0x128), S(0x129), S(0x12a), S(0x12b), S(0x12c),
S(0x12d), S(0x12e), S(0x12f), S(0x130), S(0x131), S(0x132), S(0x133),
S(0x134), S(0x135), S(0x136), S(0x137), S(0x138), S(0x139), S(0x13a),
S(0x13b), S(0x13c), S(0x13d), S(0x13e), S(0x13f), S(0x140), S(0x141),
S(0x142), S(0x143), S(0x144), S(0x145), S(0x146), S(0x147), S(0x148),
S(0x149), S(0x14a), S(0x14b), S(0x14c), S(0x14d), S(0x14e), S(0x14f),
S(0x150), S(0x151), S(0x152), S(0x153), S(0x154), S(0x155), S(0x156),
S(0x157), S(0x158), S(0x159), S(0x15a), S(0x15b), S(0x15c), S(0x15d),
S(0x15e), S(0x15f), S(0x160), S(0x161), S(0x162), S(0x163), S(0x164),
S(0x165), S(0x166), S(0x167), S(0x168), S(0x169), S(0x16a), S(0x16b),
S(0x16c), S(0x16d), S(0x16e), S(0x16f), S(0x170), S(0x171), S(0x172),
S(0x173), S(0x174), S(0x175), S(0x176), S(0x177), S(0x178), S(0x179),
S(0x17a), S(0x17b), S(0x17c), S(0x17d), S(0x17e), S(0x17f), S(0x180),
S(0x181), S(0x182), S(0x183), S(0x184), S(0x185), S(0x186), S(0x187),
S(0x188), S(0x189), S(0x18a), S(0x18b), S(0x18c), S(0x18d), S(0x18e),
S(0x18f), S(0x190), S(0x191), S(0x192), S(0x193), S(0x194), S(0x195),
S(0x196), S(0x197), S(0x198), S(0x199), S(0x19a), S(0x19b), S(0x19c),
S(0x19d), S(0x19e), S(0x19f), S(0x1a0), S(0x1a1), S(0x1a2), S(0x1a3),
S(0x1a4), S(0x1a5), S(0x1a6), S(0x1a7), S(0x1a8), S(0x1a9), S(0x1aa),
S(0x1ab), S(0x1ac), S(0x1ad), S(0x1ae), S(0x1af), S(0x1b0), S(0x1b1),
S(0x1b2), S(0x1b3), S(0x1b4), S(0x1b5), S(0x1b6), S(0x1b7), S(0x1b8),
S(0x1b9), S(0x1ba), S(0x1bb), S(0x1bc), S(0x1bd), S(0x1be), S(0x1bf),
S(0x1c0), S(0x1c1), S(0x1c2), S(0x1c3), S(0x1c4), S(0x1c5), S(0x1c6),
S(0x1c7), S(0x1c8), S(0x1c9), S(0x1ca), S(0x1cb), S(0x1cc), S(0x1cd),
S(0x1ce), S(0x1cf), S(0x1d0), S(0x1d1), S(0x1d2), S(0x1d3), S(0x1d4),
S(0x1d5), S(0x1d6), S(0x1d7), S(0x1d8), S(0x1d9), S(0x1da), S(0x1db),
S(0x1dc), S(0x1dd), S(0x1de), S(0x1df), S(0x1e0), S(0x1e1), S(0x1e2),
S(0x1e3), S(0x1e4), S(0x1e5), S(0x1e6), S(0x1e7), S(0x1e8), S(0x1e9),
S(0x1ea), S(0x1eb), S(0x1ec), S(0x1ed), S(0x1ee), S(0x1ef), S(0x1f0),
S(0x1f1), S(0x1f2), S(0x1f3), S(0x1f4), S(0x1f5), S(0x1f6), S(0x1f7),
S(0x1f8), S(0x1f9), S(0x1fa), S(0x1fb), S(0x1fc), S(0x1fd), S(0x1fe),
S(0x1ff), S(0x200), S(0x201), S(0x202), S(0x203), S(0x204), S(0x205),
S(0x206), S(0x207), S(0x208), S(0x209), S(0x20a), S(0x20b), S(0x20c),
S(0x20d), S(0x20e), S(0x20f), S(0x210), S(0x211), S(0x212), S(0x213),
S(0x214), S(0x215), S(0x216), S(0x217), S(0x218), S(0x219), S(0x21a),
S(0x21b), S(0x21c), S(0x21d), S(0x21e), S(0x21f), S(0x220), S(0x221),
S(0x222), S(0x223), S(0x224), S(0x225), S(0x226), S(0x227), S(0x228),
S(0x229), S(0x22a), S(0x22b), S(0x22c), S(0x22d), S(0x22e), S(0x22f),
S(0x230), S(0x231), S(0x232), S(0x233), S(0x234), S(0x235), S(0x236),
S(0x237), S(0x238), S(0x239), S(0x23a), S(0x23b), S(0x23c), S(0x23d),
S(0x23e), S(0x23f), S(0x240), S(0x241), S(0x242), S(0x243), S(0x244),
S(0x245), S(0x246), S(0x247), S(0x248), S(0x249), S(0x24a), S(0x24b),
S(0x24c), S(0x24d), S(0x24e), S(0x24f), S(0x250), S(0x251), S(0x252),
S(0x253), S(0x254), S(0x255), S(0x256), S(0x257), S(0x258), S(0x259),
S(0x25a), S(0x25b), S(0x25c), S(0x25d), S(0x25e), S(0x25f), S(0x260),
S(0x261), S(0x262), S(0x263), S(0x264), S(0x265), S(0x266), S(0x267),
S(0x268), S(0x269), S(0x26a), S(0x26b), S(0x26c), S(0x26d), S(0x26e),
S(0x26f), S(0x270), S(0x271), S(0x272), S(0x273), S(0x274), S(0x275),
S(0x276), S(0x277), S(0x278), S(0x279), S(0x27a), S(0x27b), S(0x27c),
S(0x27d), S(0x27e), S(0x27f), S(0x280), S(0x281), S(0x282), S(0x283),
S(0x284), S(0x285), S(0x286), S(0x287), S(0x288), S(0x289), S(0x28a),
S(0x28b), S(0x28c), S(0x28d), S(0x28e), S(0x28f), S(0x290), S(0x291),
S(0x292), S(0x293), S(0x294), S(0x295), S(0x296), S(0x297), S(0x298),
S(0x299), S(0x29a), S(0x29b), S(0x29c), S(0x29d), S(0x29e), S(0x29f),
S(0x2a0), S(0x2a1), S(0x2a2), S(0x2a3), S(0x2a4), S(0x2a5), S(0x2a6),
S(0x2a7), S(0x2a8), S(0x2a9), S(0x2aa), S(0x2ab), S(0x2ac), S(0x2ad),
S(0x2ae), S(0x2af), S(0x2b0), S(0x2b1), S(0x2b2), S(0x2b3), S(0x2b4),
S(0x2b5), S(0x2b6), S(0x2b7), S(0x2b8), S(0x2b9), S(0x2ba), S(0x2bb),
S(0x2bc), S(0x2bd), S(0x2be), S(0x2bf), S(0x2c0), S(0x2c1), S(0x2c2),
S(0x2c3), S(0x2c4), S(0x2c5), S(0x2c6), S(0x2c7), S(0x2c8), S(0x2c9),
S(0x2ca), S(0x2cb), S(0x2cc), S(0x2cd), S(0x2ce), S(0x2cf), S(0x2d0),
S(0x2d1), S(0x2d2), S(0x2d3), S(0x2d4), S(0x2d5), S(0x2d6), S(0x2d7),
S(0x2d8), S(0x2d9), S(0x2da), S(0x2db), S(0x2dc), S(0x2dd), S(0x2de),
S(0x2df), S(0x2e0), S(0x2e1), S(0x2e2), S(0x2e3), S(0x2e4), S(0x2e5),
S(0x2e6), S(0x2e7), S(0x2e8), S(0x2e9), S(0x2ea), S(0x2eb), S(0x2ec),
S(0x2ed), S(0x2ee), S(0x2ef), S(0x2f0), S(0x2f1), S(0x2f2), S(0x2f3),
S(0x2f4), S(0x2f5), S(0x2f6), S(0x2f7), S(0x2f8), S(0x2f9), S(0x2fa),
S(0x2fb), S(0x2fc), S(0x2fd), S(0x2fe), S(0x2ff), S(0x300), S(0x301),
S(0x302), S(0x303), S(0x304), S(0x305), S(0x306), S(0x307), S(0x308),
S(0x309), S(0x30a), S(0x30b), S(0x30c), S(0x30d), S(0x30e), S(0x30f),
S(0x310), S(0x311), S(0x312), S(0x313), S(0x314), S(0x315), S(0x316),
S(0x317), S(0x318), S(0x319), S(0x31a), S(0x31b), S(0x31c), S(0x31d),
S(0x31e), S(0x31f), S(0x320), S(0x321), S(0x322), S(0x323), S(0x324),
S(0x325), S(0x326), S(0x327), S(0x328), S(0x329), S(0x32a), S(0x32b),
S(0x32c), S(0x32d), S(0x32e), S(0x32f), S(0x330), S(0x331), S(0x332),
S(0x333), S(0x334), S(0x335), S(0x336), S(0x337), S(0x338), S(0x339),
S(0x33a), S(0x33b), S(0x33c), S(0x33d), S(0x33e), S(0x33f), S(0x340),
S(0x341), S(0x342), S(0x343), S(0x344), S(0x345), S(0x346), S(0x347),
S(0x348), S(0x349), S(0x34a), S(0x34b), S(0x34c), S(0x34d), S(0x34e),
S(0x34f), S(0x350), S(0x351), S(0x352), S(0x353), S(0x354), S(0x355),
S(0x356), S(0x357), S(0x358), S(0x359), S(0x35a), S(0x35b), S(0x35c),
S(0x35d), S(0x35e), S(0x35f), S(0x360), S(0x361), S(0x362), S(0x363),
S(0x364), S(0x365), S(0x366), S(0x367), S(0x368), S(0x369), S(0x36a),
S(0x36b), S(0x36c), S(0x36d), S(0x36e), S(0x36f), S(0x370), S(0x371),
S(0x372), S(0x373), S(0x374), S(0x375), S(0x376), S(0x377), S(0x378),
S(0x379), S(0x37a), S(0x37b), S(0x37c), S(0x37d), S(0x37e), S(0x37f),
S(0x380), S(0x381), S(0x382), S(0x383), S(0x384), S(0x385), S(0x386),
S(0x387), S(0x388), S(0x389), S(0x38a), S(0x38b), S(0x38c), S(0x38d),
S(0x38e), S(0x38f), S(0x390), S(0x391), S(0x392), S(0x393), S(0x394),
S(0x395), S(0x396), S(0x397), S(0x398), S(0x399), S(0x39a), S(0x39b),
S(0x39c), S(0x39d), S(0x39e), S(0x39f), S(0x3a0), S(0x3a1), S(0x3a2),
S(0x3a3), S(0x3a4), S(0x3a5), S(0x3a6), S(0x3a7), S(0x3a8), S(0x3a9),
S(0x3aa), S(0x3ab), S(0x3ac), S(0x3ad), S(0x3ae), S(0x3af), S(0x3b0),
S(0x3b1), S(0x3b2), S(0x3b3), S(0x3b4), S(0x3b5), S(0x3b6), S(0x3b7),
S(0x3b8), S(0x3b9), S(0x3ba), S(0x3bb), S(0x3bc), S(0x3bd), S(0x3be),
S(0x3bf), S(0x3c0), S(0x3c1), S(0x3c2), S(0x3c3), S(0x3c4), S(0x3c5),
S(0x3c6), S(0x3c7), S(0x3c8), S(0x3c9), S(0x3ca), S(0x3cb), S(0x3cc),
S(0x3cd), S(0x3ce), S(0x3cf), S(0x3d0), S(0x3d1), S(0x3d2), S(0x3d3),
S(0x3d4), S(0x3d5), S(0x3d6), S(0x3d7), S(0x3d8), S(0x3d9), S(0x3da),
S(0x3db), S(0x3dc), S(0x3dd), S(0x3de), S(0x3df), S(0x3e0), S(0x3e1),
S(0x3e2), S(0x3e3), S(0x3e4), S(0x3e5), S(0x3e6), S(0x3e7), S(0x3e8),
S(0x3e9), S(0x3ea), S(0x3eb), S(0x3ec), S(0x3ed), S(0x3ee), S(0x3ef),
S(0x3f0), S(0x3f1), S(0x3f2), S(0x3f3), S(0x3f4), S(0x3f5), S(0x3f6),
S(0x3f7), S(0x3f8), S(0x3f9), S(0x3fa), S(0x3fb), S(0x3fc), S(0x3fd),
S(0x3fe), S(0x3ff)
S(0x000), S(0x001), S(0x002), S(0x003), S(0x004), S(0x005), S(0x006), S(0x007),
S(0x008), S(0x009), S(0x00a), S(0x00b), S(0x00c), S(0x00d), S(0x00e), S(0x00f),
S(0x010), S(0x011), S(0x012), S(0x013), S(0x014), S(0x015), S(0x016), S(0x017),
S(0x018), S(0x019), S(0x01a), S(0x01b), S(0x01c), S(0x01d), S(0x01e), S(0x01f),
S(0x020), S(0x021), S(0x022), S(0x023), S(0x024), S(0x025), S(0x026), S(0x027),
S(0x028), S(0x029), S(0x02a), S(0x02b), S(0x02c), S(0x02d), S(0x02e), S(0x02f),
S(0x030), S(0x031), S(0x032), S(0x033), S(0x034), S(0x035), S(0x036), S(0x037),
S(0x038), S(0x039), S(0x03a), S(0x03b), S(0x03c), S(0x03d), S(0x03e), S(0x03f),
S(0x040), S(0x041), S(0x042), S(0x043), S(0x044), S(0x045), S(0x046), S(0x047),
S(0x048), S(0x049), S(0x04a), S(0x04b), S(0x04c), S(0x04d), S(0x04e), S(0x04f),
S(0x050), S(0x051), S(0x052), S(0x053), S(0x054), S(0x055), S(0x056), S(0x057),
S(0x058), S(0x059), S(0x05a), S(0x05b), S(0x05c), S(0x05d), S(0x05e), S(0x05f),
S(0x060), S(0x061), S(0x062), S(0x063), S(0x064), S(0x065), S(0x066), S(0x067),
S(0x068), S(0x069), S(0x06a), S(0x06b), S(0x06c), S(0x06d), S(0x06e), S(0x06f),
S(0x070), S(0x071), S(0x072), S(0x073), S(0x074), S(0x075), S(0x076), S(0x077),
S(0x078), S(0x079), S(0x07a), S(0x07b), S(0x07c), S(0x07d), S(0x07e), S(0x07f),
S(0x080), S(0x081), S(0x082), S(0x083), S(0x084), S(0x085), S(0x086), S(0x087),
S(0x088), S(0x089), S(0x08a), S(0x08b), S(0x08c), S(0x08d), S(0x08e), S(0x08f),
S(0x090), S(0x091), S(0x092), S(0x093), S(0x094), S(0x095), S(0x096), S(0x097),
S(0x098), S(0x099), S(0x09a), S(0x09b), S(0x09c), S(0x09d), S(0x09e), S(0x09f),
S(0x0a0), S(0x0a1), S(0x0a2), S(0x0a3), S(0x0a4), S(0x0a5), S(0x0a6), S(0x0a7),
S(0x0a8), S(0x0a9), S(0x0aa), S(0x0ab), S(0x0ac), S(0x0ad), S(0x0ae), S(0x0af),
S(0x0b0), S(0x0b1), S(0x0b2), S(0x0b3), S(0x0b4), S(0x0b5), S(0x0b6), S(0x0b7),
S(0x0b8), S(0x0b9), S(0x0ba), S(0x0bb), S(0x0bc), S(0x0bd), S(0x0be), S(0x0bf),
S(0x0c0), S(0x0c1), S(0x0c2), S(0x0c3), S(0x0c4), S(0x0c5), S(0x0c6), S(0x0c7),
S(0x0c8), S(0x0c9), S(0x0ca), S(0x0cb), S(0x0cc), S(0x0cd), S(0x0ce), S(0x0cf),
S(0x0d0), S(0x0d1), S(0x0d2), S(0x0d3), S(0x0d4), S(0x0d5), S(0x0d6), S(0x0d7),
S(0x0d8), S(0x0d9), S(0x0da), S(0x0db), S(0x0dc), S(0x0dd), S(0x0de), S(0x0df),
S(0x0e0), S(0x0e1), S(0x0e2), S(0x0e3), S(0x0e4), S(0x0e5), S(0x0e6), S(0x0e7),
S(0x0e8), S(0x0e9), S(0x0ea), S(0x0eb), S(0x0ec), S(0x0ed), S(0x0ee), S(0x0ef),
S(0x0f0), S(0x0f1), S(0x0f2), S(0x0f3), S(0x0f4), S(0x0f5), S(0x0f6), S(0x0f7),
S(0x0f8), S(0x0f9), S(0x0fa), S(0x0fb), S(0x0fc), S(0x0fd), S(0x0fe), S(0x0ff),
S(0x100), S(0x101), S(0x102), S(0x103), S(0x104), S(0x105), S(0x106), S(0x107),
S(0x108), S(0x109), S(0x10a), S(0x10b), S(0x10c), S(0x10d), S(0x10e), S(0x10f),
S(0x110), S(0x111), S(0x112), S(0x113), S(0x114), S(0x115), S(0x116), S(0x117),
S(0x118), S(0x119), S(0x11a), S(0x11b), S(0x11c), S(0x11d), S(0x11e), S(0x11f),
S(0x120), S(0x121), S(0x122), S(0x123), S(0x124), S(0x125), S(0x126), S(0x127),
S(0x128), S(0x129), S(0x12a), S(0x12b), S(0x12c), S(0x12d), S(0x12e), S(0x12f),
S(0x130), S(0x131), S(0x132), S(0x133), S(0x134), S(0x135), S(0x136), S(0x137),
S(0x138), S(0x139), S(0x13a), S(0x13b), S(0x13c), S(0x13d), S(0x13e), S(0x13f),
S(0x140), S(0x141), S(0x142), S(0x143), S(0x144), S(0x145), S(0x146), S(0x147),
S(0x148), S(0x149), S(0x14a), S(0x14b), S(0x14c), S(0x14d), S(0x14e), S(0x14f),
S(0x150), S(0x151), S(0x152), S(0x153), S(0x154), S(0x155), S(0x156), S(0x157),
S(0x158), S(0x159), S(0x15a), S(0x15b), S(0x15c), S(0x15d), S(0x15e), S(0x15f),
S(0x160), S(0x161), S(0x162), S(0x163), S(0x164), S(0x165), S(0x166), S(0x167),
S(0x168), S(0x169), S(0x16a), S(0x16b), S(0x16c), S(0x16d), S(0x16e), S(0x16f),
S(0x170), S(0x171), S(0x172), S(0x173), S(0x174), S(0x175), S(0x176), S(0x177),
S(0x178), S(0x179), S(0x17a), S(0x17b), S(0x17c), S(0x17d), S(0x17e), S(0x17f),
S(0x180), S(0x181), S(0x182), S(0x183), S(0x184), S(0x185), S(0x186), S(0x187),
S(0x188), S(0x189), S(0x18a), S(0x18b), S(0x18c), S(0x18d), S(0x18e), S(0x18f),
S(0x190), S(0x191), S(0x192), S(0x193), S(0x194), S(0x195), S(0x196), S(0x197),
S(0x198), S(0x199), S(0x19a), S(0x19b), S(0x19c), S(0x19d), S(0x19e), S(0x19f),
S(0x1a0), S(0x1a1), S(0x1a2), S(0x1a3), S(0x1a4), S(0x1a5), S(0x1a6), S(0x1a7),
S(0x1a8), S(0x1a9), S(0x1aa), S(0x1ab), S(0x1ac), S(0x1ad), S(0x1ae), S(0x1af),
S(0x1b0), S(0x1b1), S(0x1b2), S(0x1b3), S(0x1b4), S(0x1b5), S(0x1b6), S(0x1b7),
S(0x1b8), S(0x1b9), S(0x1ba), S(0x1bb), S(0x1bc), S(0x1bd), S(0x1be), S(0x1bf),
S(0x1c0), S(0x1c1), S(0x1c2), S(0x1c3), S(0x1c4), S(0x1c5), S(0x1c6), S(0x1c7),
S(0x1c8), S(0x1c9), S(0x1ca), S(0x1cb), S(0x1cc), S(0x1cd), S(0x1ce), S(0x1cf),
S(0x1d0), S(0x1d1), S(0x1d2), S(0x1d3), S(0x1d4), S(0x1d5), S(0x1d6), S(0x1d7),
S(0x1d8), S(0x1d9), S(0x1da), S(0x1db), S(0x1dc), S(0x1dd), S(0x1de), S(0x1df),
S(0x1e0), S(0x1e1), S(0x1e2), S(0x1e3), S(0x1e4), S(0x1e5), S(0x1e6), S(0x1e7),
S(0x1e8), S(0x1e9), S(0x1ea), S(0x1eb), S(0x1ec), S(0x1ed), S(0x1ee), S(0x1ef),
S(0x1f0), S(0x1f1), S(0x1f2), S(0x1f3), S(0x1f4), S(0x1f5), S(0x1f6), S(0x1f7),
S(0x1f8), S(0x1f9), S(0x1fa), S(0x1fb), S(0x1fc), S(0x1fd), S(0x1fe), S(0x1ff),
S(0x200), S(0x201), S(0x202), S(0x203), S(0x204), S(0x205), S(0x206), S(0x207),
S(0x208), S(0x209), S(0x20a), S(0x20b), S(0x20c), S(0x20d), S(0x20e), S(0x20f),
S(0x210), S(0x211), S(0x212), S(0x213), S(0x214), S(0x215), S(0x216), S(0x217),
S(0x218), S(0x219), S(0x21a), S(0x21b), S(0x21c), S(0x21d), S(0x21e), S(0x21f),
S(0x220), S(0x221), S(0x222), S(0x223), S(0x224), S(0x225), S(0x226), S(0x227),
S(0x228), S(0x229), S(0x22a), S(0x22b), S(0x22c), S(0x22d), S(0x22e), S(0x22f),
S(0x230), S(0x231), S(0x232), S(0x233), S(0x234), S(0x235), S(0x236), S(0x237),
S(0x238), S(0x239), S(0x23a), S(0x23b), S(0x23c), S(0x23d), S(0x23e), S(0x23f),
S(0x240), S(0x241), S(0x242), S(0x243), S(0x244), S(0x245), S(0x246), S(0x247),
S(0x248), S(0x249), S(0x24a), S(0x24b), S(0x24c), S(0x24d), S(0x24e), S(0x24f),
S(0x250), S(0x251), S(0x252), S(0x253), S(0x254), S(0x255), S(0x256), S(0x257),
S(0x258), S(0x259), S(0x25a), S(0x25b), S(0x25c), S(0x25d), S(0x25e), S(0x25f),
S(0x260), S(0x261), S(0x262), S(0x263), S(0x264), S(0x265), S(0x266), S(0x267),
S(0x268), S(0x269), S(0x26a), S(0x26b), S(0x26c), S(0x26d), S(0x26e), S(0x26f),
S(0x270), S(0x271), S(0x272), S(0x273), S(0x274), S(0x275), S(0x276), S(0x277),
S(0x278), S(0x279), S(0x27a), S(0x27b), S(0x27c), S(0x27d), S(0x27e), S(0x27f),
S(0x280), S(0x281), S(0x282), S(0x283), S(0x284), S(0x285), S(0x286), S(0x287),
S(0x288), S(0x289), S(0x28a), S(0x28b), S(0x28c), S(0x28d), S(0x28e), S(0x28f),
S(0x290), S(0x291), S(0x292), S(0x293), S(0x294), S(0x295), S(0x296), S(0x297),
S(0x298), S(0x299), S(0x29a), S(0x29b), S(0x29c), S(0x29d), S(0x29e), S(0x29f),
S(0x2a0), S(0x2a1), S(0x2a2), S(0x2a3), S(0x2a4), S(0x2a5), S(0x2a6), S(0x2a7),
S(0x2a8), S(0x2a9), S(0x2aa), S(0x2ab), S(0x2ac), S(0x2ad), S(0x2ae), S(0x2af),
S(0x2b0), S(0x2b1), S(0x2b2), S(0x2b3), S(0x2b4), S(0x2b5), S(0x2b6), S(0x2b7),
S(0x2b8), S(0x2b9), S(0x2ba), S(0x2bb), S(0x2bc), S(0x2bd), S(0x2be), S(0x2bf),
S(0x2c0), S(0x2c1), S(0x2c2), S(0x2c3), S(0x2c4), S(0x2c5), S(0x2c6), S(0x2c7),
S(0x2c8), S(0x2c9), S(0x2ca), S(0x2cb), S(0x2cc), S(0x2cd), S(0x2ce), S(0x2cf),
S(0x2d0), S(0x2d1), S(0x2d2), S(0x2d3), S(0x2d4), S(0x2d5), S(0x2d6), S(0x2d7),
S(0x2d8), S(0x2d9), S(0x2da), S(0x2db), S(0x2dc), S(0x2dd), S(0x2de), S(0x2df),
S(0x2e0), S(0x2e1), S(0x2e2), S(0x2e3), S(0x2e4), S(0x2e5), S(0x2e6), S(0x2e7),
S(0x2e8), S(0x2e9), S(0x2ea), S(0x2eb), S(0x2ec), S(0x2ed), S(0x2ee), S(0x2ef),
S(0x2f0), S(0x2f1), S(0x2f2), S(0x2f3), S(0x2f4), S(0x2f5), S(0x2f6), S(0x2f7),
S(0x2f8), S(0x2f9), S(0x2fa), S(0x2fb), S(0x2fc), S(0x2fd), S(0x2fe), S(0x2ff),
S(0x300), S(0x301), S(0x302), S(0x303), S(0x304), S(0x305), S(0x306), S(0x307),
S(0x308), S(0x309), S(0x30a), S(0x30b), S(0x30c), S(0x30d), S(0x30e), S(0x30f),
S(0x310), S(0x311), S(0x312), S(0x313), S(0x314), S(0x315), S(0x316), S(0x317),
S(0x318), S(0x319), S(0x31a), S(0x31b), S(0x31c), S(0x31d), S(0x31e), S(0x31f),
S(0x320), S(0x321), S(0x322), S(0x323), S(0x324), S(0x325), S(0x326), S(0x327),
S(0x328), S(0x329), S(0x32a), S(0x32b), S(0x32c), S(0x32d), S(0x32e), S(0x32f),
S(0x330), S(0x331), S(0x332), S(0x333), S(0x334), S(0x335), S(0x336), S(0x337),
S(0x338), S(0x339), S(0x33a), S(0x33b), S(0x33c), S(0x33d), S(0x33e), S(0x33f),
S(0x340), S(0x341), S(0x342), S(0x343), S(0x344), S(0x345), S(0x346), S(0x347),
S(0x348), S(0x349), S(0x34a), S(0x34b), S(0x34c), S(0x34d), S(0x34e), S(0x34f),
S(0x350), S(0x351), S(0x352), S(0x353), S(0x354), S(0x355), S(0x356), S(0x357),
S(0x358), S(0x359), S(0x35a), S(0x35b), S(0x35c), S(0x35d), S(0x35e), S(0x35f),
S(0x360), S(0x361), S(0x362), S(0x363), S(0x364), S(0x365), S(0x366), S(0x367),
S(0x368), S(0x369), S(0x36a), S(0x36b), S(0x36c), S(0x36d), S(0x36e), S(0x36f),
S(0x370), S(0x371), S(0x372), S(0x373), S(0x374), S(0x375), S(0x376), S(0x377),
S(0x378), S(0x379), S(0x37a), S(0x37b), S(0x37c), S(0x37d), S(0x37e), S(0x37f),
S(0x380), S(0x381), S(0x382), S(0x383), S(0x384), S(0x385), S(0x386), S(0x387),
S(0x388), S(0x389), S(0x38a), S(0x38b), S(0x38c), S(0x38d), S(0x38e), S(0x38f),
S(0x390), S(0x391), S(0x392), S(0x393), S(0x394), S(0x395), S(0x396), S(0x397),
S(0x398), S(0x399), S(0x39a), S(0x39b), S(0x39c), S(0x39d), S(0x39e), S(0x39f),
S(0x3a0), S(0x3a1), S(0x3a2), S(0x3a3), S(0x3a4), S(0x3a5), S(0x3a6), S(0x3a7),
S(0x3a8), S(0x3a9), S(0x3aa), S(0x3ab), S(0x3ac), S(0x3ad), S(0x3ae), S(0x3af),
S(0x3b0), S(0x3b1), S(0x3b2), S(0x3b3), S(0x3b4), S(0x3b5), S(0x3b6), S(0x3b7),
S(0x3b8), S(0x3b9), S(0x3ba), S(0x3bb), S(0x3bc), S(0x3bd), S(0x3be), S(0x3bf),
S(0x3c0), S(0x3c1), S(0x3c2), S(0x3c3), S(0x3c4), S(0x3c5), S(0x3c6), S(0x3c7),
S(0x3c8), S(0x3c9), S(0x3ca), S(0x3cb), S(0x3cc), S(0x3cd), S(0x3ce), S(0x3cf),
S(0x3d0), S(0x3d1), S(0x3d2), S(0x3d3), S(0x3d4), S(0x3d5), S(0x3d6), S(0x3d7),
S(0x3d8), S(0x3d9), S(0x3da), S(0x3db), S(0x3dc), S(0x3dd), S(0x3de), S(0x3df),
S(0x3e0), S(0x3e1), S(0x3e2), S(0x3e3), S(0x3e4), S(0x3e5), S(0x3e6), S(0x3e7),
S(0x3e8), S(0x3e9), S(0x3ea), S(0x3eb), S(0x3ec), S(0x3ed), S(0x3ee), S(0x3ef),
S(0x3f0), S(0x3f1), S(0x3f2), S(0x3f3), S(0x3f4), S(0x3f5), S(0x3f6), S(0x3f7),
S(0x3f8), S(0x3f9), S(0x3fa), S(0x3fb), S(0x3fc), S(0x3fd), S(0x3fe), S(0x3ff)
};
#endif /* MAKE_IDENTITY_MAP */
extern char _end[];
#endif /* MAKE_IDENTITY_MAP */
/*
** Kernel address mappings, present in every page table
*/
const mapping_t kmap[] = {
// va pa_start pa_end perms
{ KERN_BASE, 0, EXT_BASE, PDE_RW },
{ KERN_VLINK, KERN_PLINK, V2P(_data), PDE_RW },
// { (uint32_t) _data, V2P(_data), V2P(_end), PDE_RW },
{ (uint32_t)_data, V2P(_data), PHYS_TOP, PDE_RW }
// { DEV_BASE, DEV_BASE, 0, PDE_RW }
{ KERN_BASE, 0, EXT_BASE, PDE_RW },
{ KERN_VLINK, KERN_PLINK, V2P(_data), 0 },
{ (uint32_t) _data, V2P(_data), KERN_BASE, PDE_RW },
{ DEV_BASE, DEV_BASE, 0, PDE_RW }
};
const uint_t n_kmap = sizeof(kmap) / sizeof(kmap[0]);