From: Alan Cox Date: Sun, 15 Oct 2017 17:47:59 +0000 (+0100) Subject: ibmpc: introduce a platform skeleton so we can test build 8086 core code X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=56c0e862bfc41a82ce0ff32a6bf9c2dfc496a9a2;p=FUZIX.git ibmpc: introduce a platform skeleton so we can test build 8086 core code This is *miles* from being an actual port. It's just there to get the core code comping. --- diff --git a/Kernel/platform-ibmpc/Makefile b/Kernel/platform-ibmpc/Makefile new file mode 100644 index 00000000..dd57aedd --- /dev/null +++ b/Kernel/platform-ibmpc/Makefile @@ -0,0 +1,34 @@ + +CSRCS = devtty.c +CSRCS += devices.c main.c libc.c biosdisk.c + +ASRCS = ibmpc.S crt0.S +ASRCS += tricks.S + +COBJS = $(CSRCS:.c=$(BINEXT)) +AOBJS = $(ASRCS:.S=.o) +OBJS = $(COBJS) $(AOBJS) $(DOBJS) + +JUNK = $(CSRCS:.c=.o) $(ASRCS:.S=.o) + +all: $(OBJS) + +$(COBJS): %.o: %.c + $(CROSS_CC) $(CROSS_CCOPTS) -c $< + +$(AOBJS): %.o: %.S + $(CROSS_AS) $(ASOPTS) -c $< + +clean: + rm -f $(OBJS) $(JUNK) core *~ + +image: + $(CROSS_LD) -M -o fuzix.elf -T fuzix.ld \ + crt0.o \ + ../start.o ../version.o ../lowlevel-8086.o \ + main.o ../swap.o ../timer.o ../simple.o ../kdata.o devices.o \ + ../tty.o ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \ + ibmpc.o ../syscall_proc.o ../syscall_other.o ../mm.o \ + ../devsys.o ../usermem.o ../syscall_exec16.o ../syscall_fs2.o \ + tricks.o ../syscall_fs3.o biosdisk.o \ + ../usermem_std-8086.o devtty.o libc.o > ../fuzix.map diff --git a/Kernel/platform-ibmpc/README b/Kernel/platform-ibmpc/README new file mode 100644 index 00000000..413a210b --- /dev/null +++ b/Kernel/platform-ibmpc/README @@ -0,0 +1,4 @@ +At the moment this is just build testing the core code and totally incomplete +(no usable drivers, no loader, no task switching, no __ashldi/rdi stubs and +tons more) + diff --git a/Kernel/platform-ibmpc/bios.h b/Kernel/platform-ibmpc/bios.h new file mode 100644 index 00000000..f7d38cfc --- /dev/null +++ b/Kernel/platform-ibmpc/bios.h @@ -0,0 +1,12 @@ + +extern uint8_t biosdata_read(uint16_t offset); + +extern uint16_t bioshd_reset(uint16_t drive); +extern uint32_t bioshd_param(uint16_t drive); +extern uint32_t bioshd_read(uint16_t cylsec, uint8_t dev, uint8_t head, + uint16_t page, uint16_t dptr, uint16_t len); +extern uint32_t bioshd_write(uint16_t cylsec, uint8_t dev, uint8_t head, + uint16_t page, uint16_t dptr, uint16_t len); + +extern uint16_t kernel_ds; +extern uint16_t equipment_word; diff --git a/Kernel/platform-ibmpc/biosdisk.c b/Kernel/platform-ibmpc/biosdisk.c new file mode 100644 index 00000000..7736115e --- /dev/null +++ b/Kernel/platform-ibmpc/biosdisk.c @@ -0,0 +1,189 @@ +/* + * PC BIOS disk driver + */ + +#include +#include +#include +#include +#include + +#define MAX_HD 4 + +struct disk_geom { + uint8_t secs; + uint8_t heads; + uint16_t cyls; + uint8_t max; + uint8_t dev; +}; + +static uint8_t floppies; +static uint8_t nfloppy; +static uint8_t nhd; + +static struct disk_geom floppy[4]; +static struct disk_geom harddisk[MAX_HD]; + +static int bios_transfer(bool is_read, uint8_t rawflag, + struct disk_geom *g); + +int fd_read(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag; + return bios_transfer(true, rawflag, &floppy[minor]); +} + +int fd_write(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag; + return bios_transfer(false, rawflag, &floppy[minor]); +} + +int hd_read(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag; + return bios_transfer(true, rawflag, &harddisk[minor]); +} + +int hd_write(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag; + return bios_transfer(false, rawflag, &harddisk[minor]); +} + +static int bios_transfer(bool is_read, uint8_t rawflag, struct disk_geom *g) +{ + uint16_t dptr; + uint16_t ct = 0; + uint32_t st; + int map = 0; + uint16_t page = kernel_ds; + uint16_t left; + uint16_t cylsec; + uint8_t tries; + + /* Sort the actual request out */ + if(rawflag == 1) { + if (d_blkoff(9)) + return -1; + map = 1; + page = udata.u_page; +#ifdef SWAPDEV + } else if (rawflag == 2) { /* Swap device special */ + page = swappage; /* Acting on this page */ + map = 1; +#endif + } + + dptr = (uint16_t)udata.u_dptr; + left = udata.u_nblock; + + /* Try and read as much as we can in one go */ + while (ct < udata.u_nblock) { + uint16_t n = left; + uint8_t sec = udata.u_block % g->secs + 1; + uint16_t cyl = udata.u_block / g->secs; + uint8_t head = cyl / g->cyls; + cyl %= g->cyls; + cylsec = (cyl << 8) | sec; + cylsec |= (cyl & 0x300) >> 10; + + if (n > g->max) + n = g->max; + + /* Try the I/O multiple times if it fails */ + for (tries = 0; tries < 3; tries ++) { + if (is_read) + st = bioshd_read(cylsec, g->dev, head, page, dptr, n); + else + st = bioshd_write(cylsec, g->dev, head, page, dptr, n); + /* st will be 00:secs, or 00:random, depending upon the BIOS + if we succeeded. If CF is set and it's unknown we'll return + 0xFFxxxx */ + if (st <= 0xFF) + break; + /* Try and do partial writes, also try and deal with any crap + BIOS that can't handle multi-track */ + if (tries == 2) { + bioshd_reset(g->dev); + n = 1; + } + } + if (tries == 3) { + kprintf("bios disk %d: block %d, error %d\n", g->dev, udata.u_block, st); + break; + } + /* Adjust all our status */ + udata.u_block += n; + ct += n; + left -= n; + dptr += n << 9; + } + return ct << 9; +} + +int fd_open(uint8_t minor, uint16_t flag) +{ + if (!(floppies & (1 << minor))) { + udata.u_error = ENODEV; + return -1; + } + return 0; +} + +int hd_open(uint8_t minor, uint16_t flag) +{ + if (minor >= nhd) { + udata.u_error = ENODEV; + return -1; + } + return 0; +} + +void biosdisk_init(void) +{ + struct disk_geom *p = harddisk; + uint32_t bits; + uint16_t dx,cx; + int i; + + /* How many disks do we have and what sort ? */ + nfloppy = equipment_word & 0x01; + if (nfloppy) + nfloppy = 1 + (equipment_word >> 6) & 3; + for (i = 0; i < nfloppy; i++) { + bits = bioshd_param(i); + if (bits == 0xFFFF) + continue; + dx = bits >> 16; + cx = bits; + floppy[i].heads = dx >> 8; + floppy[i].cyls = cx >> 8; + floppy[i].secs = cx & 0x3F; + floppy[i].cyls |= ((cx & 0xC0) << 2); + floppy[i].dev = i; + /* Keep to sectors/track or less */ + floppy[i].max = cx & 0x3F; + } + /* Now the hard disks.. This is so much more fun. We need to be careful + not to read further once we have all the disks we should as the BIOS + may make up imaginary drives! */ + nhd = biosdata_read(0x75); /* Because we can't trust anything else */ + for (i = 0; i < 0x7f && nhd; i++) { + bits = bioshd_param(0x80 + i); + if (bits == 0xFFFF) + continue; + nhd--; + p->heads = dx >> 8; + p->cyls = cx >> 8; + p->secs = cx & 0x3F; + p->cyls |= ((cx & 0xC0) << 2); + /* Assume the BIOS can multitrack.. we may want to be cautious about + this for old 8086 boxes */ + p->max = 255; + p->dev = 0x80 + i; + p++; + } + nhd = i; +} diff --git a/Kernel/platform-ibmpc/config.h b/Kernel/platform-ibmpc/config.h new file mode 100644 index 00000000..10e8889c --- /dev/null +++ b/Kernel/platform-ibmpc/config.h @@ -0,0 +1,42 @@ +/* Enable to make ^Z dump the inode table for debug */ +#undef CONFIG_IDUMP +/* Enable to make ^A drop back into the monitor */ +#undef CONFIG_MONITOR +/* Profil syscall support (not yet complete) */ +#undef CONFIG_PROFIL + +#define CONFIG_MULTI +#define CONFIG_SWAP_ONLY +#define CONFIG_USERMEM_DIRECT +#define CONFIG_BANKS 1 +#define PROC_SIZE 128 /* 64K, 128 * 512 */ + +#define CONFIG_SPLIT_UDATA +#define UDATA_SIZE 512 +#define UDATA_BLKS 1 + +#define PROGBASE 0x8000UL +#define PROGLOAD PROGBASE +#define PROGTOP 0xE000UL +#define SWAP_SIZE (130 + 2) /* 2 for the udata */ +#define SWAPBASE PROGBASE +#define SWAPTOP 0xE000UL +#define MAX_SWAPS PTABSIZE /* Mandatory for swap only */ +#define swap_map(x) ((uint8_t *)(x)) + +#define SWAPDEV (1) + +#define TICKSPERSEC 50 /* Ticks per second */ + +#define BOOT_TTY (512 + 1) /* Set this to default device for stdio, stderr */ + /* In this case, the default is the first TTY device */ + /* Temp FIXME set to serial port for debug ease */ + +/* We need a tidier way to do this from the loader */ +#define CMDLINE NULL /* Location of root dev name */ + +/* Device parameters */ +#define NUM_DEV_TTY 1 +#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ +#define NBUFS 6 /* Number of block buffers */ +#define NMOUNTS 2 /* Number of mounts at a time */ diff --git a/Kernel/platform-ibmpc/crt0.S b/Kernel/platform-ibmpc/crt0.S new file mode 100644 index 00000000..3cc219ce --- /dev/null +++ b/Kernel/platform-ibmpc/crt0.S @@ -0,0 +1,29 @@ + .arch i8086,jumps + .code16 + .att_syntax prefix + + .text + + .global kstack_top + .global init_early + .global init_hardware + .global fuzix_main + .global __bss_start + .global __end + +start: + movw $kstack_top,%sp /* Set the stack */ + movw $__bss_start,%si /* Wipe the BSS */ + movw $__bss_start+1,%di + movw $__end,%cx + subw $__bss_start+1,%cx + movb $0,(%si) + rep + movsb + + call init_early + call init_hardware + call fuzix_main +1: + jmp 1b + diff --git a/Kernel/platform-ibmpc/devhd.h b/Kernel/platform-ibmpc/devhd.h new file mode 100644 index 00000000..8c30a94e --- /dev/null +++ b/Kernel/platform-ibmpc/devhd.h @@ -0,0 +1,7 @@ +extern int fd_read(uint8_t minor, uint8_t rawflag, uint8_t flag); +extern int fd_write(uint8_t minor, uint8_t rawflag, uint8_t flag); +extern int hd_read(uint8_t minor, uint8_t rawflag, uint8_t flag); +extern int hd_write(uint8_t minor, uint8_t rawflag, uint8_t flag); + +extern int fd_open(uint8_t minor, uint16_t flag); +extern int hd_open(uint8_t minor, uint16_t flag); diff --git a/Kernel/platform-ibmpc/device.h b/Kernel/platform-ibmpc/device.h new file mode 100644 index 00000000..6f4c1e26 --- /dev/null +++ b/Kernel/platform-ibmpc/device.h @@ -0,0 +1,6 @@ +#ifndef __DEVICE_DOT_H__ +#define __DEVICE_DOT_H__ + +extern void mod_control(uint8_t set, uint8_t clr); + +#endif /* __DEVICE_DOT_H__ */ diff --git a/Kernel/platform-ibmpc/devices.c b/Kernel/platform-ibmpc/devices.c new file mode 100644 index 00000000..c8f55ca5 --- /dev/null +++ b/Kernel/platform-ibmpc/devices.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include + +struct devsw dev_tab[] = /* The device driver switch table */ +{ +// minor open close read write ioctl +// ----------------------------------------------------------------- + /* 0: /dev/hd Disc block devices */ + { hd_open, no_close, hd_read, hd_write, no_ioctl }, + /* 1: /dev/fd Hard disc block devices (absent) */ + { fd_open, no_close, fd_read, fd_write, no_ioctl }, + /* 2: /dev/tty TTY devices */ + { tty_open, tty_close, tty_read, tty_write, tty_ioctl }, + /* 3: /dev/lpr Printer devices */ + { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 4: /dev/mem etc System devices (one offs) */ + { no_open, no_close, sys_read, sys_write, sys_ioctl }, + /* Pack to 7 with nxio if adding private devices and start at 8 */ +}; + +bool validdev(uint16_t dev) +{ + /* This is a bit uglier than needed but the right hand side is + a constant this way */ + if(dev > ((sizeof(dev_tab)/sizeof(struct devsw)) << 8) - 1) + return false; + else + return true; +} + +void device_init(void) +{ + int i; + + for (i = 1; i <= MAX_SWAPS; i++) + swapmap_init(i); +} diff --git a/Kernel/platform-ibmpc/devtty.c b/Kernel/platform-ibmpc/devtty.c new file mode 100644 index 00000000..3954fa8c --- /dev/null +++ b/Kernel/platform-ibmpc/devtty.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include + +volatile uint8_t *uart_data = (volatile uint8_t *)0xF03000; /* UART data */ +volatile uint8_t *uart_status = (volatile uint8_t *)0xF03010; /* UART status */ + +unsigned char tbuf1[TTYSIZ]; + +struct s_queue ttyinq[NUM_DEV_TTY + 1] = { /* ttyinq[0] is never used */ + {NULL, NULL, NULL, 0, 0, 0}, + {tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2}, +}; + +/* Output for the system console (kprintf etc) */ +void kputchar(char c) +{ + if (c == '\n') + tty_putc(1, '\r'); + tty_putc(1, c); +} + +ttyready_t tty_writeready(uint8_t minor) +{ + uint8_t c = *uart_status; + return (c & 2) ? TTY_READY_NOW : TTY_READY_SOON; /* TX DATA empty */ +} + +void tty_putc(uint8_t minor, unsigned char c) +{ + *uart_data = c; /* Data */ +} + +void tty_setup(uint8_t minor) +{ +} + +int tty_carrier(uint8_t minor) +{ + return 1; +} + +void tty_sleeping(uint8_t minor) +{ +} + +/* Currently run off the timer */ +void tty_interrupt(void) +{ + uint8_t r = *uart_status; + if (r & 1) { + r = *uart_data; + tty_inproc(1,r); + } +} + +void platform_interrupt(void) +{ + timer_interrupt(); + tty_interrupt(); +} diff --git a/Kernel/platform-ibmpc/devtty.h b/Kernel/platform-ibmpc/devtty.h new file mode 100644 index 00000000..14c28c31 --- /dev/null +++ b/Kernel/platform-ibmpc/devtty.h @@ -0,0 +1,10 @@ +#ifndef __DEVTTY_DOT_H__ +#define __DEVTTY_DOT_H__ + +#define KEY_ROWS 8 +#define KEY_COLS 7 +extern uint8_t keymap[8]; +extern uint8_t keyboard[8][7]; +extern uint8_t shiftkeyboard[8][7]; + +#endif diff --git a/Kernel/platform-ibmpc/fuzix.ld b/Kernel/platform-ibmpc/fuzix.ld new file mode 100644 index 00000000..05784a33 --- /dev/null +++ b/Kernel/platform-ibmpc/fuzix.ld @@ -0,0 +1,66 @@ +STARTUP(crt0.o) +OUTPUT_ARCH(i8086) + + +SEARCH_DIR(.) + +MEMORY +{ + ram (rwx) : ORIGIN = 0x1000, LENGTH = 0xE000 +} + +/* + * stick everything in ram (of course) + */ +SECTIONS +{ + .text : + { + CREATE_OBJECT_SYMBOLS + *(.text .text.*) + + . = ALIGN(0x4); + /* These are for running static constructors and destructors under ELF. */ + + *(.rodata .rodata.*) + + . = ALIGN(0x4); + *(.gcc_except_table) + + . = ALIGN(0x4); + *(.eh_frame) + + . = ALIGN(0x4); + _etext = .; + *(.lit) + } > ram + + .data : + { + *(.got.plt) *(.got) + *(.shdata) + *(.data .data.*) + _edata = .; + } > ram + + .bss : + { + . = ALIGN(0x4); + __bss_start = . ; + *(.shbss) + *(.bss .bss.*) + *(COMMON) + _end = ALIGN (0x8); + __end = _end; + } > ram + + .stab 0 (NOLOAD) : + { + *(.stab) + } + + .stabstr 0 (NOLOAD) : + { + *(.stabstr) + } +} diff --git a/Kernel/platform-ibmpc/ibmpc.S b/Kernel/platform-ibmpc/ibmpc.S new file mode 100644 index 00000000..94c1add7 --- /dev/null +++ b/Kernel/platform-ibmpc/ibmpc.S @@ -0,0 +1,196 @@ + .arch i8086,jumps + .code16 + .att_syntax prefix + .data + + .global udata + .global kstack_top + .global istack_top + +udata: + .bss 512 +kstack_top: + .bss 256 +istack_top: + + .text + + .global init_early + .global init_hardware + .global program_vectors + .global trap_monitor + .global trap_reboot + .global kernel_ds + + .global bioshd_param + .global bioshd_read + .global bioshd_write + .global bioshd_reset + .global biosdata_read + .global equipment_word + + +init_early: + /* Dig useful information out of the BIOS */ + int $11 + mov %ax,equipment_word + int $12 + mov %ax,ramsize + ret +init_hardware: + ret +program_vectors: + ret +trap_monitor: +trap_reboot: + jmp trap_monitor + +/* Returns the BIOS parameter data CX:DX as a long DX:AX to the C code or + FFFF if we don't get the right answer + + Things to note this being PC BIOS land + - bl return is not reliable for floppies (nor sometimes %cx) + - es:di is not reliably set by the BIOS + - you must do an int 13 ah=0x01 after this call on PS/2 model 30 + - some junk leaves interrupts disabled after this call + - Leading Edge BIOSes may trash di/si/bp/ds/es ! + - Some Compaq BIOSes will make stuff up for drive numbers above + the last one we use + + long bioshd_param(int drive) +*/ +bioshd_param: + pushw %bp + movw %sp,%bp + movw $0x0800,%ax /* get drive parameters */ + movw 4(%bp),%dx + pushf + stc + pushw %di + pushw %si + pushw %bp + pushw %ds + int $13 + popw %ds + movw %ds,%ax + movw %ax,%es + popw %bp + popw %si + popw %di + jc bioshd_fail + popf + pushw %cx + pushw %dx + movw 4(%bp),%dx /* drive number */ + movb $1,%ah + int $13 + popw %dx + popw %ax + popw %bp + ret +bioshd_fail: + popf + popw %bp + mov $0xFF,%ax + mov %ax,%dx + ret + +bioshd_status: + pushw %bp + movw %sp,%bp + movw 4(%bp),%dx + movb $1,%ah + int $13 + popw %bp + ret + +bioshd_reset: + xorb %ah,%ah + pushw %bp + movw %sp,%bp + movw 4(%bp),%dx + int $13 + popw %bp + ret + +/* + * Attempt a block read + * + * Guess what this is also horribly buggy on lots of systems too + * Buffer must be even on some AMI BIOSen (1990/1) so we need to + * handle direct I/O with care and also FIXME align buffer cache + * + * Some bioses destroy dx, and don't always handle carry right so we + * must call with stc first + * + * The original IBM PC-AT BIOS doesn't correctly handle interrupt + * disables. For now we just treat that as busted - use a newer BIOS, + * you've had 30 years to upgrade it! + * + * bioshd_read(uint16_t cylsec, uint8_t drive, uint8_t head, + * uint16_t seg, uint16_t addr, uint16_t secs) + */ +bioshd_read: + pushw %bp + movw %sp,%bp + pushw %es + movw 4(%bp),%cx + movw 6(%bp),%dx + movw 8(%bp),%ax + movw %ax,%es + movw 10(%bp),%bx + movw 12(%bp),%ax + movb $2,%ah + stc + int $13 + jc read_fail + movw $0,%dx +read_end: + popw %es + popw %bp + ret +read_fail: + movw $0xff,%dx + jmp read_end + + +bioshd_write: + pushw %bp + movw %sp,%bp + pushw %es + movw 4(%bp),%cx + movw 6(%bp),%dx + movw 8(%bp),%ax + movw %ax,%es + movw 10(%bp),%bx + movw 12(%bp),%ax + movb $3,%ah + stc + int $13 + jc read_fail + movw $0,%dx + popw %es + popw %bp + ret + +biosdata_read: + pushw %bp + movw %sp,%bp + pushw %di + movw $0x40,%ax + movw %ax,%es + movw 4(%bp),%di + movb (%di),%al + cbw + movw %ds,%bx + movw %bx,%es + popw %di + popw %bp + ret + +kernel_ds: + .word 0 + + .data +equipment_word: + .word 0 diff --git a/Kernel/platform-ibmpc/libc.c b/Kernel/platform-ibmpc/libc.c new file mode 100644 index 00000000..e718087e --- /dev/null +++ b/Kernel/platform-ibmpc/libc.c @@ -0,0 +1,40 @@ +#include "cpu.h" + +void *memcpy(void *d, const void *s, size_t sz) +{ + unsigned char *dp = d; + const unsigned char *sp = s; + while(sz--) + *dp++=*sp++; + return d; +} + +void *memset(void *d, int c, size_t sz) +{ + unsigned char *p = d; + while(sz--) + *p++ = c; + return d; +} + +size_t strlen(const char *p) +{ + const char *e = p; + while(*e++); + return e-p-1; +} + +int memcmp(const void *a, const void *b, size_t n) +{ + const uint8_t *ap = a; + const uint8_t *bp = b; + while(n--) { + if (*ap < *bp) + return -1; + if (*ap != *bp) + return 1; + ap++; + bp++; + } + return 0; +} diff --git a/Kernel/platform-ibmpc/main.c b/Kernel/platform-ibmpc/main.c new file mode 100644 index 00000000..633168e3 --- /dev/null +++ b/Kernel/platform-ibmpc/main.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include + +uint8_t kernel_flag = 1; + +void platform_idle(void) +{ + /* FIXME: disable IRQ, run tty interrupt, re-enable ? */ +} + +void do_beep(void) +{ +} + +/* + * MMU initialize + */ + +void map_init(void) +{ +} + +uaddr_t ramtop; +uint8_t need_resched; + +uint8_t platform_param(char *p) +{ + return 0; +} + +void platform_discard(void) +{ +} + +void memzero(void *p, usize_t len) +{ + memset(p, 0, len); +} + +uint16_t irqstack[128]; /* Used for swapping only */ diff --git a/Kernel/platform-ibmpc/target.mk b/Kernel/platform-ibmpc/target.mk new file mode 100644 index 00000000..6361df69 --- /dev/null +++ b/Kernel/platform-ibmpc/target.mk @@ -0,0 +1 @@ +export CPU = 8086 diff --git a/Kernel/platform-ibmpc/tricks.S b/Kernel/platform-ibmpc/tricks.S new file mode 100644 index 00000000..55be713a --- /dev/null +++ b/Kernel/platform-ibmpc/tricks.S @@ -0,0 +1,52 @@ +#include "../kernel-8086.def" + + .arch i8086,jumps + .code16 + .att_syntax prefix + + .text + + .globl switchin + .globl switchout + .globl dofork + +switchout: + cli + call chksigs + pushw %ax /* Figure out what we actually need to save */ + pushw %bx + pushw %cx + pushw %dx + pushw %es + pushw %di + pushw %bp + movw %sp,udata+U_DATA__U_SP + call getproc + push %ax + call switchin + jmp trap_monitor + +switchin: + push %bp + mov %sp,%bp + cli + movw 4(%bp),%si + cmpb $0,P_TAB__P_PAGE_OFFSET(%si) + /* + jne not_swapped + TODO */ + ret +switchfail: +/* call outaxhex + mov $badswitchmsg,ax + calloutstring + jmp _trap_monitor */ + +dofork: + /* TODO */ + movw $-1,%ax + ret + + .data +swapstack: + .bss 256