ibmpc: introduce a platform skeleton so we can test build 8086 core code
authorAlan Cox <alan@linux.intel.com>
Sun, 15 Oct 2017 17:47:59 +0000 (18:47 +0100)
committerAlan Cox <alan@linux.intel.com>
Sun, 15 Oct 2017 17:47:59 +0000 (18:47 +0100)
This is *miles* from being an actual port. It's just there to get the core
code comping.

17 files changed:
Kernel/platform-ibmpc/Makefile [new file with mode: 0644]
Kernel/platform-ibmpc/README [new file with mode: 0644]
Kernel/platform-ibmpc/bios.h [new file with mode: 0644]
Kernel/platform-ibmpc/biosdisk.c [new file with mode: 0644]
Kernel/platform-ibmpc/config.h [new file with mode: 0644]
Kernel/platform-ibmpc/crt0.S [new file with mode: 0644]
Kernel/platform-ibmpc/devhd.h [new file with mode: 0644]
Kernel/platform-ibmpc/device.h [new file with mode: 0644]
Kernel/platform-ibmpc/devices.c [new file with mode: 0644]
Kernel/platform-ibmpc/devtty.c [new file with mode: 0644]
Kernel/platform-ibmpc/devtty.h [new file with mode: 0644]
Kernel/platform-ibmpc/fuzix.ld [new file with mode: 0644]
Kernel/platform-ibmpc/ibmpc.S [new file with mode: 0644]
Kernel/platform-ibmpc/libc.c [new file with mode: 0644]
Kernel/platform-ibmpc/main.c [new file with mode: 0644]
Kernel/platform-ibmpc/target.mk [new file with mode: 0644]
Kernel/platform-ibmpc/tricks.S [new file with mode: 0644]

diff --git a/Kernel/platform-ibmpc/Makefile b/Kernel/platform-ibmpc/Makefile
new file mode 100644 (file)
index 0000000..dd57aed
--- /dev/null
@@ -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 (file)
index 0000000..413a210
--- /dev/null
@@ -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 (file)
index 0000000..f7d38cf
--- /dev/null
@@ -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 (file)
index 0000000..7736115
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ *     PC BIOS disk driver
+ */
+
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devhd.h>
+#include <bios.h>
+
+#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 (file)
index 0000000..10e8889
--- /dev/null
@@ -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 (file)
index 0000000..3cc219c
--- /dev/null
@@ -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 (file)
index 0000000..8c30a94
--- /dev/null
@@ -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 (file)
index 0000000..6f4c1e2
--- /dev/null
@@ -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 (file)
index 0000000..c8f55ca
--- /dev/null
@@ -0,0 +1,42 @@
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <devsys.h>
+#include <tty.h>
+#include <vt.h>
+#include <devhd.h>
+
+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 (file)
index 0000000..3954fa8
--- /dev/null
@@ -0,0 +1,65 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <stdbool.h>
+#include <devtty.h>
+#include <device.h>
+#include <tty.h>
+
+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 (file)
index 0000000..14c28c3
--- /dev/null
@@ -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 (file)
index 0000000..05784a3
--- /dev/null
@@ -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 (file)
index 0000000..94c1add
--- /dev/null
@@ -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 (file)
index 0000000..e718087
--- /dev/null
@@ -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 (file)
index 0000000..633168e
--- /dev/null
@@ -0,0 +1,44 @@
+#include <kernel.h>
+#include <timer.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devtty.h>
+#include <buddy.h>
+
+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 (file)
index 0000000..6361df6
--- /dev/null
@@ -0,0 +1 @@
+export CPU = 8086
diff --git a/Kernel/platform-ibmpc/tricks.S b/Kernel/platform-ibmpc/tricks.S
new file mode 100644 (file)
index 0000000..55be713
--- /dev/null
@@ -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