8086: initial preparatory work
authorAlan Cox <alan@linux.intel.com>
Sat, 31 Jan 2015 23:17:59 +0000 (23:17 +0000)
committerAlan Cox <alan@linux.intel.com>
Sat, 31 Jan 2015 23:17:59 +0000 (23:17 +0000)
C bits all build under bcc

16 files changed:
Kernel/Makefile
Kernel/cpu-8086/cpu.h [new file with mode: 0644]
Kernel/cpu-8086/stdbool.h [new file with mode: 0644]
Kernel/platform-8086test/Makefile [new file with mode: 0644]
Kernel/platform-8086test/README [new file with mode: 0644]
Kernel/platform-8086test/config.h [new file with mode: 0644]
Kernel/platform-8086test/device.h [new file with mode: 0644]
Kernel/platform-8086test/devices.c [new file with mode: 0644]
Kernel/platform-8086test/devlpr.c [new file with mode: 0644]
Kernel/platform-8086test/devlpr.h [new file with mode: 0644]
Kernel/platform-8086test/devrd.c [new file with mode: 0644]
Kernel/platform-8086test/devrd.h [new file with mode: 0644]
Kernel/platform-8086test/devtty.c [new file with mode: 0644]
Kernel/platform-8086test/devtty.h [new file with mode: 0644]
Kernel/platform-8086test/libc.c [new file with mode: 0644]
Kernel/platform-8086test/main.c [new file with mode: 0644]

index c232de3..dcea159 100644 (file)
@@ -8,6 +8,9 @@ export CPU = z80
 #export CPU = 6502
 #export TARGET=atarist
 #export CPU = 68000
+#export TARGET = 8086test
+#export CPU = 8086
+
 export VERSION = "0.1"
 export SUBVERSION = "ac1"
 
@@ -78,7 +81,7 @@ export ASOPTS=
 export ASMEXT = .s
 export BINEXT = .o
 export BITS=16
-else
+else ifeq ($(CPU),68000)
 export CROSS_LD=m68k-linux-gnu-ld
 export CROSS_CC = m68k-linux-gnu-gcc
 export CROSS_CCOPTS=-c -fno-builtin -Wall -Os -m68000 -mshort -I$(ROOT_DIR)/cpu-68000 -I$(ROOT_DIR)/platform-$(TARGET) -I$(ROOT_DIR)/include
@@ -93,6 +96,21 @@ export ASOPTS=
 export ASMEXT = .S
 export BINEXT = .o
 export BITS=32
+else
+export CROSS_LD=ld86
+export CROSS_CC = bcc
+export CROSS_CCOPTS=-c -ansi -0 -O -I$(ROOT_DIR)/cpu-8086 -I$(ROOT_DIR)/platform-$(TARGET) -I$(ROOT_DIR)/include
+export CROSS_AS=$(CROSS_CC) $(CROSS_CCOPTS)
+export CROSS_CC_SEG1=
+export CROSS_CC_SEG2=
+export CROSS_CC_SEG3=
+# Fixme: we should split discard off
+export CROSS_CC_SEGDISC=
+export CROSS_CC_VIDEO=
+export ASOPTS=
+export ASMEXT = .S
+export BINEXT = .o
+export BITS=16
 endif
 
 ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
diff --git a/Kernel/cpu-8086/cpu.h b/Kernel/cpu-8086/cpu.h
new file mode 100644 (file)
index 0000000..b39729e
--- /dev/null
@@ -0,0 +1,65 @@
+typedef unsigned long uint32_t;
+typedef signed long int32_t;
+typedef unsigned short uint16_t;
+typedef signed short int16_t;
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+typedef signed int size_t;
+
+typedef uint8_t irqflags_t;
+
+typedef int16_t arg_t;
+typedef uint16_t uarg_t;               /* Holds arguments */
+typedef uint16_t usize_t;              /* Largest value passed by userspace */
+typedef int16_t susize_t;
+typedef uint16_t uaddr_t;
+
+#define __fastcall__
+extern void ei(void);
+extern irqflags_t di(void);
+extern void irqrestore(irqflags_t f);
+
+extern void *  memcpy(void *, void *, size_t);
+extern void *  memset(void *, int, size_t);
+extern size_t  strlen(const char *);
+
+#define EMAGIC    0x4C    /* Header of executable (JMP) */
+#define EMAGIC_2  0x38   /* SEC BCS foo */
+/* We use SEC BCS not CLC BCC because CLC is 0x18 which is the Z80 JR header
+   so the two would be identical - not good! */
+
+
+/* High byte is saved, low byte is a mystery so take worst case. Also allow
+   a bit less as C stack is not return stack */
+#define brk_limit() ((((uint16_t)udata.u_syscall_sp) | 0xFF) - 384)
+
+#define staticfast     static
+
+/* User's structure for times() system call */
+typedef unsigned long clock_t;
+
+typedef struct {
+  uint32_t low;
+  uint32_t high;
+} time_t;
+
+typedef union {            /* this structure is endian dependent */
+    clock_t  full;         /* 32-bit count of ticks since boot */
+    struct {
+      uint16_t low;         /* 16-bit count of ticks since boot */
+      uint16_t high;
+    } h;
+} ticks_t;
+
+/* Sane behaviour for unused parameters */
+#define used(x)
+
+/* We don't yet have bank attributes and banking for 6502 */
+#define CODE1
+#define CODE2
+#define COMMON
+#define VIDEO
+#define DISCARD
+
+
+#define const
diff --git a/Kernel/cpu-8086/stdbool.h b/Kernel/cpu-8086/stdbool.h
new file mode 100644 (file)
index 0000000..0172aef
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __STDBOOL_H
+#define __STDBOOL_H
+
+typedef unsigned char bool;
+
+#define true 1
+#define false 0
+#endif
diff --git a/Kernel/platform-8086test/Makefile b/Kernel/platform-8086test/Makefile
new file mode 100644 (file)
index 0000000..0442c2a
--- /dev/null
@@ -0,0 +1,32 @@
+
+CSRCS = devlpr.c devtty.c devrd.c
+CSRCS += devices.c main.c libc.c
+
+#ASRCS = p8086.s crt0.s
+#ASRCS += tricks.s commonmem.s
+
+COBJS = $(CSRCS:.c=$(BINEXT))
+AOBJS = $(ASRCS:.s=$(BINEXT))
+OBJS  = $(COBJS) $(AOBJS)
+
+JUNK = $(CSRCS:.c=.o) $(CSRCS:.c=.s) $(ASRCS:.s=.o)
+
+all:   $(OBJS)
+
+$(COBJS): %$(BINEXT): %.c
+       $(CROSS_CC) $(CROSS_CCOPTS) $<
+
+$(AOBJS): %$(BINEXT): %.s
+       $(CROSS_AS) $(ASOPTS) $< -o $*$(BINEXT)
+
+clean:
+       rm -f $(OBJS) $(JUNK)  core *~ 
+
+image:
+       $(CROSS_LD) -o ../fuzix.bin -0 -i crt0.o commonmem.o \
+       p8086.o ../start.o ../version.o ../lowlevel-8086.o \
+       tricks.o main.o ../timer.o ../kdata.o devrd.o devices.o \
+       ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
+       ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o ../bank16k.o \
+       ../tty.o ../devsys.o ../syscall_fs2.o ../syscall_exec.o \
+       ../usermem.o devlpr.o devtty.o libc.o 
diff --git a/Kernel/platform-8086test/README b/Kernel/platform-8086test/README
new file mode 100644 (file)
index 0000000..893a516
--- /dev/null
@@ -0,0 +1,4 @@
+8086 test sketching out
+
+Getting the bcc compiler bits working. Ideally we'll switch to pcc once it
+works
diff --git a/Kernel/platform-8086test/config.h b/Kernel/platform-8086test/config.h
new file mode 100644 (file)
index 0000000..8dba4df
--- /dev/null
@@ -0,0 +1,61 @@
+/* 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) */
+#define CONFIG_PROFIL
+/* Acct syscall support */
+#define CONFIG_ACCT
+/* Multiple processes in memory at once */
+#define CONFIG_MULTI
+/* Single tasking - for now while we get it booting */
+#undef CONFIG_SINGLETASK
+/* Use the C language usermem helpers */
+#define CONFIG_USERMEM_C
+/* TODO: these need to be defined as the code to flip the banks over */
+#define BANK_PROCESS
+#define BANK_KERNEL
+#define CONFIG_BANKS   1
+
+/* We use flexible 16K banks so use the helper */
+#define CONFIG_BANK16
+#define MAX_MAPS 16
+/* And swapping */
+#define SWAPDEV 6      /* FIXME */
+#define SWAP_SIZE   0x80       /* 64K blocks */
+/* FIXME */
+#define SWAPBASE    0x0000     /* We swap the lot in one, include the */
+#define SWAPTOP            0xF000      /* vectors so its a round number of sectors */
+#define UDATA_BLOCKS   0       /* We swap the uarea in the data */
+#define UDATA_SWAPSIZE 0
+#define MAX_SWAPS      32
+
+/* Video terminal, not a serial tty */
+#define CONFIG_VT
+/* We want the 8x8 font */
+#define CONFIG_FONT_8X8
+/* Vt definitions */
+#define VT_WIDTH       64
+#define VT_HEIGHT      24
+#define VT_RIGHT       63
+#define VT_BOTTOM      23
+
+#define TICKSPERSEC 100   /* Ticks per second */
+#define PROGBASE    0x0200  /* also data base */
+#define PROGLOAD    0x0200
+#define PROGTOP     0xF000  /* Top of program, base of U_DATA */
+
+#define BOOT_TTY 513        /* 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 3
+#define NDEVS    1        /* Devices 0..NDEVS-1 are capable of being mounted */
+                          /*  (add new mountable devices to beginning area.) */
+#define TTYDEV   BOOT_TTY /* Device used by kernel for messages, panics */
+#define NBUFS    10       /* Number of block buffers */
+#define NMOUNTS         1        /* Number of mounts at a time - nothing mountable! */
diff --git a/Kernel/platform-8086test/device.h b/Kernel/platform-8086test/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-8086test/devices.c b/Kernel/platform-8086test/devices.c
new file mode 100644 (file)
index 0000000..c4b5286
--- /dev/null
@@ -0,0 +1,40 @@
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <devrd.h>
+#include <devsys.h>
+#include <devlpr.h>
+#include <tty.h>
+#include <devtty.h>
+
+struct devsw dev_tab[] =  /* The device driver switch table */
+{
+// minor    open         close        read      write       ioctl
+// -----------------------------------------------------------------
+  /* 0: /dev/fd                Floppy disc block devices  */
+  {  rd_open,     no_close,    rd_read,   rd_write,   no_ioctl },
+  /* 1: /dev/hd                Hard disc block devices (absent) */
+  {  nxio_open,     no_close,    no_rdwr,   no_rdwr,   no_ioctl },
+  /* 2: /dev/tty       TTY devices */
+  {  tty_open,     tty_close,   tty_read,  tty_write,  tty_ioctl },
+  /* 3: /dev/lpr       Printer devices */
+  {  lpr_open,     lpr_close,   no_rdwr,   lpr_write,  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) + 255)
+       return false;
+    else
+        return true;
+}
+
+void device_init(void)
+{
+}
+
diff --git a/Kernel/platform-8086test/devlpr.c b/Kernel/platform-8086test/devlpr.c
new file mode 100644 (file)
index 0000000..a011085
--- /dev/null
@@ -0,0 +1,54 @@
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <device.h>
+#include <devlpr.h>
+
+/* random test places */
+uint8_t *lpstat = (uint8_t *)0xFF00;
+uint8_t *lpdata = (uint8_t *)0xFF01;
+
+int lpr_open(uint8_t minor, uint16_t flag)
+{
+       minor;
+       flag;                   // shut up compiler
+       return 0;
+}
+
+int lpr_close(uint8_t minor)
+{
+       minor;                  // shut up compiler
+       return 0;
+}
+
+int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+       int c = udata.u_count;
+       char *p = udata.u_base;
+       uint16_t ct;
+
+       minor;
+       rawflag;
+       flag;                   // shut up compiler
+
+       while (c-- > 0) {
+               ct = 0;
+
+               /* Try and balance polling and sleeping */
+               while (*lpstat & 2) {
+                       ct++;
+                       if (ct == 10000) {
+                               udata.u_ptab->p_timeout = 3;
+                               if (psleep_flags(NULL, flag)) {
+                                       if (udata.u_count)
+                                               udata.u_error = 0;
+                                       return udata.u_count;
+                               }
+                               ct = 0;
+                       }
+               }
+               /* Data */
+               *lpdata = ugetc(p++);
+       }
+       return udata.u_count;
+}
diff --git a/Kernel/platform-8086test/devlpr.h b/Kernel/platform-8086test/devlpr.h
new file mode 100644 (file)
index 0000000..7765c18
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __DEVLPR_DOT_H__
+#define __DEVLPR_DOT_H__
+
+int lpr_open(uint8_t minor, uint16_t flag);
+int lpr_close(uint8_t minor);
+int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
+
+#endif
diff --git a/Kernel/platform-8086test/devrd.c b/Kernel/platform-8086test/devrd.c
new file mode 100644 (file)
index 0000000..ddbf8b3
--- /dev/null
@@ -0,0 +1,69 @@
+/* 
+ * NC100 RD PCMCIA driver
+ *
+ */
+
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devrd.h>
+
+static int rd_transfer(bool is_read, uint8_t rawflag)
+{
+    blkno_t block;
+    int block_xfer;
+    uint16_t dptr;
+    int dlen;
+    int ct = 0;
+    int map;
+
+    /* FIXME: raw is broken unless nicely aligned */
+    if(rawflag) {
+        dlen = udata.u_count;
+        dptr = (uint16_t)udata.u_base;
+        if (dptr & 0x1FF) {
+            udata.u_error = EIO;
+            return -1;
+        }
+        block = udata.u_offset >> 9;
+        block_xfer = dlen >> 9;
+        map = 1;
+    } else { /* rawflag == 0 */
+        dlen = 512;
+        dptr = (uint16_t)udata.u_buf->bf_data;
+        block = udata.u_buf->bf_blk;
+        block_xfer = 1;
+        map = 0;
+    }
+    block += 2*320;    /* ramdisc starts at 320K in */
+        
+    while (ct < block_xfer) {
+/*        rd_memcpy(is_read, map, dptr, block); */
+        block++;
+        ct++;
+    }
+    return ct;
+}
+
+int rd_open(uint8_t minor, uint16_t flag)
+{
+    flag;
+    if(minor != 0) {
+        udata.u_error = ENODEV;
+        return -1;
+    }
+    return 0;
+}
+
+int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+    flag;minor;
+    return rd_transfer(true, rawflag);
+}
+
+int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+    flag;minor;
+    return rd_transfer(false, rawflag);
+}
+
diff --git a/Kernel/platform-8086test/devrd.h b/Kernel/platform-8086test/devrd.h
new file mode 100644 (file)
index 0000000..6320b26
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __DEVRD_DOT_H__
+#define __DEVRD_DOT_H__
+
+/* public interface */
+int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag);
+int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
+int rd_open(uint8_t minor, uint16_t flag);
+
+/* asm banking helper */
+void rd_memcpy(uint8_t isread, uint8_t map, uint16_t dptr, uint16_t block);
+
+#endif /* __DEVRD_DOT_H__ */
+
diff --git a/Kernel/platform-8086test/devtty.c b/Kernel/platform-8086test/devtty.c
new file mode 100644 (file)
index 0000000..2abb514
--- /dev/null
@@ -0,0 +1,75 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <stdbool.h>
+#include <devtty.h>
+#include <device.h>
+#include <vt.h>
+#include <tty.h>
+
+#undef  DEBUG                  /* UNdefine to delete debug code sequences */
+
+uint8_t *uarta = (uint8_t *)0xFF04;
+uint8_t *uartb = (uint8_t *)0xFF05;
+
+static char tbuf1[TTYSIZ];
+static char tbuf2[TTYSIZ];
+PTY_BUFFERS;
+
+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},
+       {tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ / 2},
+       PTY_QUEUES
+};
+
+/* tty1 is the screen tty2 is the serial port */
+
+/* Output for the system console (kprintf etc) */
+void kputchar(char c)
+{
+       if (c == '\n')
+               tty_putc(1, '\r');
+       tty_putc(1, c);
+}
+
+bool tty_writeready(uint8_t minor)
+{
+       uint8_t c;
+       if (minor == 1)
+               return 1;
+       c = *uartb;
+       return c & 1;
+}
+
+void tty_putc(uint8_t minor, unsigned char c)
+{
+       minor;
+#if 0
+       if (minor == 1) {
+               vtoutput(&c, 1);
+               return;
+       }
+#endif 
+       *uarta = c;
+}
+
+void tty_setup(uint8_t minor)
+{
+    minor;
+}
+
+/* For the moment */
+int tty_carrier(uint8_t minor)
+{
+    minor;
+    return 1;
+}
+
+void platform_interrupt(void)
+{
+       timer_interrupt();
+}
+
+/* This is used by the vt asm code, but needs to live at the top of the kernel */
+uint16_t cursorpos;
diff --git a/Kernel/platform-8086test/devtty.h b/Kernel/platform-8086test/devtty.h
new file mode 100644 (file)
index 0000000..421ba7f
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __DEVTTY_DOT_H__
+#define __DEVTTY_DOT_H__
+
+extern void kbd_interrupt(void);
+extern void tty_interrupt(void);
+
+#define KEY_ROWS       8
+#define KEY_COLS       10
+
+extern uint16_t keymap[8];
+extern uint8_t keyboard[8][10];
+extern uint8_t shiftkeyboard[8][10];
+
+
+#endif
diff --git a/Kernel/platform-8086test/libc.c b/Kernel/platform-8086test/libc.c
new file mode 100644 (file)
index 0000000..8a97283
--- /dev/null
@@ -0,0 +1,17 @@
+#include "cpu.h"
+
+void *memcpy(void *d, void *s, size_t sz)
+{
+  unsigned char *dp, *sp;
+  while(sz--)
+    *dp++=*sp++;
+  return d;
+}
+
+size_t strlen(const char *p)
+{
+  const char *e = p;
+  while(*e++);
+  return e-p-1;
+}
+
diff --git a/Kernel/platform-8086test/main.c b/Kernel/platform-8086test/main.c
new file mode 100644 (file)
index 0000000..75ccedb
--- /dev/null
@@ -0,0 +1,53 @@
+#include <kernel.h>
+#include <timer.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devtty.h>
+
+/* The uarea is already synched to the stash which is written with the
+   process */
+uint8_t *swapout_prepare_uarea(ptptr p)
+{
+  p;
+  return NULL;
+}
+
+/* The switchin code will move the uarea into the process itself, we just
+   need to fix up the u_page pointer */
+uint8_t *swapin_prepare_uarea(ptptr p)
+{
+  p;
+  return NULL;
+}
+
+void platform_idle(void)
+{
+}
+
+void do_beep(void)
+{
+}
+
+/*
+ * Map handling: We have flexible paging. Each map table consists of a set of pages
+ * with the last page repeated to fill any holes.
+ */
+
+void pagemap_init(void)
+{
+    int i;
+    /* 0/1/2 image, 3/4/5 kernel 6-19 apps */
+    /* Don't add page 6 yet - it's the initial common at boot */
+    for (i = 0x80 + 7; i < 0x80 + 20; i++)
+        pagemap_add(i);
+    /*
+     * The kernel boots with 0x86 as the common, list it last here so it also
+     * gets given to init as the kernel kicks off the init stub. init will then
+     * exec preserving this common and all forks will be copies from it.
+     */
+    pagemap_add(0x86);
+}
+
+void map_init(void)
+{
+}