mirror of
https://github.com/kenshineto/kern.git
synced 2025-04-21 20:57:25 +00:00
fix old checkout
This commit is contained in:
parent
5372fc3bfd
commit
c8a1e0531d
51 changed files with 4847 additions and 4226 deletions
kernel/old
Make.mkcio.cclock.c
include
.vm.h.swpbindings.hbootstrap.hcio.hclock.hcommon.hcompat.hdebug.hdefs.helf.hkdefs.hklib.hkmem.hlib.hlist.hoffsets.hparams.hprocs.hserial.hsio.hsupport.hsyscalls.htypes.hudefs.hulib.huser.huserids.hvm.hvmtables.h
isrs.Skernel.ckernel.ldkmem.clist.cprocs.csio.cstartup.Ssupport.csyscalls.cuser.cvm.cvmtables.cx86
76
kernel/old/Make.mk
Normal file
76
kernel/old/Make.mk
Normal 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
|
||||
|
810
kernel/old/cio.c
810
kernel/old/cio.c
File diff suppressed because it is too large
Load diff
|
@ -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 );
|
||||
}
|
BIN
kernel/old/include/.vm.h.swp
Normal file
BIN
kernel/old/include/.vm.h.swp
Normal file
Binary file not shown.
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
31
kernel/old/include/common.h
Normal file
31
kernel/old/include/common.h
Normal 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
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
235
kernel/old/include/elf.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
314
kernel/old/include/lib.h
Normal 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
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
|
@ -18,9 +18,9 @@
|
|||
|
||||
// sio interrupt settings
|
||||
|
||||
#define SIO_TX 0x01
|
||||
#define SIO_RX 0x02
|
||||
#define SIO_BOTH (SIO_TX | SIO_RX)
|
||||
#define SIO_TX 0x01
|
||||
#define SIO_RX 0x02
|
||||
#define SIO_BOTH (SIO_TX | SIO_RX)
|
||||
|
||||
#ifndef ASM_SRC
|
||||
|
||||
|
@ -48,7 +48,7 @@ extern QTYPE QNAME;
|
|||
**
|
||||
** Initialize the UART chip.
|
||||
*/
|
||||
void sio_init(void);
|
||||
void sio_init( void );
|
||||
|
||||
/**
|
||||
** sio_enable()
|
||||
|
@ -61,7 +61,7 @@ void sio_init(void);
|
|||
**
|
||||
** @return the prior IER setting
|
||||
*/
|
||||
uint8_t sio_enable(uint8_t which);
|
||||
uint8_t sio_enable( uint8_t which );
|
||||
|
||||
/**
|
||||
** sio_disable()
|
||||
|
@ -74,7 +74,7 @@ uint8_t sio_enable(uint8_t which);
|
|||
**
|
||||
** @return the prior IER setting
|
||||
*/
|
||||
uint8_t sio_disable(uint8_t which);
|
||||
uint8_t sio_disable( uint8_t which );
|
||||
|
||||
/**
|
||||
** sio_inq_length()
|
||||
|
@ -85,7 +85,7 @@ uint8_t sio_disable(uint8_t which);
|
|||
**
|
||||
** @return the count of characters still in the input queue
|
||||
*/
|
||||
int sio_inq_length(void);
|
||||
int sio_inq_length( void );
|
||||
|
||||
/**
|
||||
** sio_readc()
|
||||
|
@ -96,7 +96,7 @@ int sio_inq_length(void);
|
|||
**
|
||||
** @return the next character, or -1 if no character is available
|
||||
*/
|
||||
int sio_readc(void);
|
||||
int sio_readc( void );
|
||||
|
||||
/**
|
||||
** sio_read()
|
||||
|
@ -110,7 +110,7 @@ int sio_readc(void);
|
|||
**
|
||||
** @return the number of bytes copied, or 0 if no characters were available
|
||||
*/
|
||||
int sio_read(char *buffer, int length);
|
||||
int sio_read( char *buffer, int length );
|
||||
|
||||
/**
|
||||
** sio_writec( ch )
|
||||
|
@ -121,7 +121,7 @@ int sio_read(char *buffer, int length);
|
|||
**
|
||||
** @param ch Character to be written (in the low-order 8 bits)
|
||||
*/
|
||||
void sio_writec(int ch);
|
||||
void sio_writec( int ch );
|
||||
|
||||
/**
|
||||
** sio_write( ch )
|
||||
|
@ -135,7 +135,7 @@ void sio_writec(int ch);
|
|||
**
|
||||
** @return the number of characters copied into the SIO output buffer
|
||||
*/
|
||||
int sio_write(const char *buffer, int length);
|
||||
int sio_write( const char *buffer, int length );
|
||||
|
||||
/**
|
||||
** sio_puts( buf )
|
||||
|
@ -148,7 +148,7 @@ int sio_write(const char *buffer, int length);
|
|||
**
|
||||
** @return the count of bytes transferred
|
||||
*/
|
||||
int sio_puts(const char *buffer);
|
||||
int sio_puts( const char *buffer );
|
||||
|
||||
/**
|
||||
** sio_dump( full )
|
||||
|
@ -161,8 +161,8 @@ int sio_puts(const char *buffer);
|
|||
** is being requested (which includes the contents
|
||||
** of the queues)
|
||||
*/
|
||||
void sio_dump(bool_t full);
|
||||
void sio_dump( bool_t full );
|
||||
|
||||
#endif /* !ASM_SRC */
|
||||
#endif /* !ASM_SRC */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
113
kernel/old/include/udefs.h
Normal 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
315
kernel/old/include/ulib.h
Normal 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
|
|
@ -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
|
||||
|
|
33
kernel/old/include/userids.h
Normal file
33
kernel/old/include/userids.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
73
kernel/old/include/x86/bios.h
Normal file
73
kernel/old/include/x86/bios.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
**
|
||||
|
|
|
@ -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
71
kernel/old/kernel.ld
Normal 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)
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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
153
kernel/old/startup.S
Normal 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
|
|
@ -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 )
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
734
kernel/old/vm.c
734
kernel/old/vm.c
File diff suppressed because it is too large
Load diff
|
@ -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]);
|
||||
|
|
Loading…
Add table
Reference in a new issue