From 41c22e8330cd457485e726b060601687edf4f8f8 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 31 Jan 2015 23:17:59 +0000 Subject: [PATCH] 8086: initial preparatory work C bits all build under bcc --- Kernel/Makefile | 20 +++++++- Kernel/cpu-8086/cpu.h | 65 ++++++++++++++++++++++++++ Kernel/cpu-8086/stdbool.h | 8 ++++ Kernel/platform-8086test/Makefile | 32 +++++++++++++ Kernel/platform-8086test/README | 4 ++ Kernel/platform-8086test/config.h | 61 ++++++++++++++++++++++++ Kernel/platform-8086test/device.h | 6 +++ Kernel/platform-8086test/devices.c | 40 ++++++++++++++++ Kernel/platform-8086test/devlpr.c | 54 +++++++++++++++++++++ Kernel/platform-8086test/devlpr.h | 8 ++++ Kernel/platform-8086test/devrd.c | 69 +++++++++++++++++++++++++++ Kernel/platform-8086test/devrd.h | 13 ++++++ Kernel/platform-8086test/devtty.c | 75 ++++++++++++++++++++++++++++++ Kernel/platform-8086test/devtty.h | 15 ++++++ Kernel/platform-8086test/libc.c | 17 +++++++ Kernel/platform-8086test/main.c | 53 +++++++++++++++++++++ 16 files changed, 539 insertions(+), 1 deletion(-) create mode 100644 Kernel/cpu-8086/cpu.h create mode 100644 Kernel/cpu-8086/stdbool.h create mode 100644 Kernel/platform-8086test/Makefile create mode 100644 Kernel/platform-8086test/README create mode 100644 Kernel/platform-8086test/config.h create mode 100644 Kernel/platform-8086test/device.h create mode 100644 Kernel/platform-8086test/devices.c create mode 100644 Kernel/platform-8086test/devlpr.c create mode 100644 Kernel/platform-8086test/devlpr.h create mode 100644 Kernel/platform-8086test/devrd.c create mode 100644 Kernel/platform-8086test/devrd.h create mode 100644 Kernel/platform-8086test/devtty.c create mode 100644 Kernel/platform-8086test/devtty.h create mode 100644 Kernel/platform-8086test/libc.c create mode 100644 Kernel/platform-8086test/main.c diff --git a/Kernel/Makefile b/Kernel/Makefile index c232de33..dcea1596 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -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 index 00000000..b39729e3 --- /dev/null +++ b/Kernel/cpu-8086/cpu.h @@ -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 index 00000000..0172aefd --- /dev/null +++ b/Kernel/cpu-8086/stdbool.h @@ -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 index 00000000..0442c2a5 --- /dev/null +++ b/Kernel/platform-8086test/Makefile @@ -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 index 00000000..893a5163 --- /dev/null +++ b/Kernel/platform-8086test/README @@ -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 index 00000000..8dba4df2 --- /dev/null +++ b/Kernel/platform-8086test/config.h @@ -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 index 00000000..6f4c1e26 --- /dev/null +++ b/Kernel/platform-8086test/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-8086test/devices.c b/Kernel/platform-8086test/devices.c new file mode 100644 index 00000000..c4b52863 --- /dev/null +++ b/Kernel/platform-8086test/devices.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +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 index 00000000..a0110858 --- /dev/null +++ b/Kernel/platform-8086test/devlpr.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +/* 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 index 00000000..7765c187 --- /dev/null +++ b/Kernel/platform-8086test/devlpr.h @@ -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 index 00000000..ddbf8b3c --- /dev/null +++ b/Kernel/platform-8086test/devrd.c @@ -0,0 +1,69 @@ +/* + * NC100 RD PCMCIA driver + * + */ + +#include +#include +#include +#include + +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 index 00000000..6320b269 --- /dev/null +++ b/Kernel/platform-8086test/devrd.h @@ -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 index 00000000..2abb5146 --- /dev/null +++ b/Kernel/platform-8086test/devtty.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 00000000..421ba7f4 --- /dev/null +++ b/Kernel/platform-8086test/devtty.h @@ -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 index 00000000..8a972835 --- /dev/null +++ b/Kernel/platform-8086test/libc.c @@ -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 index 00000000..75ccedbc --- /dev/null +++ b/Kernel/platform-8086test/main.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include + +/* 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) +{ +} -- 2.34.1