tiny68K; just an initial commit
authorAlan Cox <alan@linux.intel.com>
Wed, 16 Jan 2019 22:19:01 +0000 (22:19 +0000)
committerAlan Cox <alan@linux.intel.com>
Wed, 16 Jan 2019 22:19:01 +0000 (22:19 +0000)
17 files changed:
Kernel/platform-tiny68k/Makefile [new file with mode: 0644]
Kernel/platform-tiny68k/README [new file with mode: 0644]
Kernel/platform-tiny68k/config.h [new file with mode: 0644]
Kernel/platform-tiny68k/crt0.S [new file with mode: 0644]
Kernel/platform-tiny68k/device.h [new file with mode: 0644]
Kernel/platform-tiny68k/devices.c [new file with mode: 0644]
Kernel/platform-tiny68k/devtty.c [new file with mode: 0644]
Kernel/platform-tiny68k/devtty.h [new file with mode: 0644]
Kernel/platform-tiny68k/fuzix.ld [new file with mode: 0644]
Kernel/platform-tiny68k/libc.c [new file with mode: 0644]
Kernel/platform-tiny68k/loader.S [new file with mode: 0644]
Kernel/platform-tiny68k/loader.ld [new file with mode: 0644]
Kernel/platform-tiny68k/main.c [new file with mode: 0644]
Kernel/platform-tiny68k/p68000.S [new file with mode: 0644]
Kernel/platform-tiny68k/platform_ide.h [new file with mode: 0644]
Kernel/platform-tiny68k/target.mk [new file with mode: 0644]
Kernel/platform-tiny68k/tricks.S [new file with mode: 0644]

diff --git a/Kernel/platform-tiny68k/Makefile b/Kernel/platform-tiny68k/Makefile
new file mode 100644 (file)
index 0000000..9f4a6e3
--- /dev/null
@@ -0,0 +1,46 @@
+
+CSRCS = devtty.c
+CSRCS += devices.c main.c libc.c
+
+ASRCS = p68000.S crt0.S
+ASRCS += tricks.S
+
+DSRCS = ../dev/devide.c ../dev/mbr.c ../dev/blkdev.c ../dev/devide_discard.c
+DOBJS = $(patsubst ../dev/%.c,%.o, $(DSRCS))
+
+COBJS = $(CSRCS:.c=$(BINEXT))
+AOBJS = $(ASRCS:.S=.o)
+OBJS  = $(COBJS) $(AOBJS) $(DOBJS)
+
+CROSS_CCOPTS += -I../dev/
+
+all:   $(OBJS)
+
+$(COBJS): %.o: %.c
+       $(CROSS_CC) $(CROSS_CCOPTS) -c $<
+
+$(AOBJS): %.o: %.S
+       $(CROSS_AS) $(ASOPTS) $< -o $*.o
+
+$(DOBJS): %.o: ../dev/%.c
+       $(CROSS_CC) $(CROSS_CCOPTS) -c $<
+
+clean:
+       rm -f *.o fuzix.elf loader.elf loader.map loader.bin core *~ 
+
+image:
+       $(CROSS_LD) -M -o fuzix.elf -T fuzix.ld \
+       crt0.o \
+       p68000.o ../start.o ../version.o ../lowlevel-68000.o \
+       tricks.o ../simple.o main.o ../timer.o ../kdata.o devices.o \
+       ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
+       ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o ../buddy.o \
+       ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o \
+       ../syscall_fs3.o ../syscall_exec32.o blkdev.o devide.o devide_discard.o mbr.o  \
+       ../usermem_std-68000.o devtty.o libc.o ../malloc.o \
+       ../level2.o ../syscall_level2.o ../select.o > ../fuzix.map
+       m68k-uclinux-objcopy fuzix.elf -O binary ../fuzix.bin
+
+       $(CROSS_CC) -c loader.S
+       $(CROSS_LD) -M -o loader.elf -T loader.ld loader.o >loader.map
+       m68k-uclinux-objcopy loader.elf -O binary loader.bin
diff --git a/Kernel/platform-tiny68k/README b/Kernel/platform-tiny68k/README
new file mode 100644 (file)
index 0000000..9857e90
--- /dev/null
@@ -0,0 +1,3 @@
+Just a test build to start the Tiny68K port
+
+Nothing interesting to see here yet
diff --git a/Kernel/platform-tiny68k/config.h b/Kernel/platform-tiny68k/config.h
new file mode 100644 (file)
index 0000000..c33dee7
--- /dev/null
@@ -0,0 +1,65 @@
+/* Enable to make ^Z dump the inode table for debug */
+#define 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_32BIT
+#define CONFIG_LEVEL_2
+
+/* To get us up and running then debug the flat model space */
+#undef 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     1024
+#define UDATA_BLKS     2
+
+#define PROGBASE       0x20000UL
+#define PROGTOP                0x30000UL
+#define SWAP_SIZE      (130 + 2)               /* 2 for the udata */
+#define SWAPBASE       PROGBASE
+#define SWAPTOP                0x30000UL
+#define MAX_SWAPS      PTABSIZE                /* Mandatory for swap only */
+#define swap_map(x)    ((uint8_t *)(x))
+
+#define CONFIG_DYNAMIC_SWAP
+#define SWAPDEV                (swap_dev)
+
+#define TICKSPERSEC 100   /* 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 2
+#define TTYDEV   BOOT_TTY /* Device used by kernel for messages, panics */
+
+/* Could be bigger but we need to add hashing first and it's not clearly
+   a win with a CF card anyway */
+#define NBUFS    16       /* Number of block buffers */
+#define NMOUNTS         8        /* Number of mounts at a time */
+
+#define MAX_BLKDEV 2
+
+#define CONFIG_IDE
+
+#define platform_copyright()
+
+/* Note: select() in the level 2 code will not work on this configuration
+   at the moment as select is limited to 16 processes. FIXME - support a
+   hash ELKS style for bigger systems where wakeup aliasing is cheaper */
+
+#define PTABSIZE       125
+#define UFTSIZE                16
+#define OFTSIZE                160
+#define ITABSIZE       176
+
diff --git a/Kernel/platform-tiny68k/crt0.S b/Kernel/platform-tiny68k/crt0.S
new file mode 100644 (file)
index 0000000..9b7796c
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *     Need to wipe BSS etc once we figure out our preferred boot method
+ *
+ *     On entry we are loaded at $2000 with the loader and the loaders
+ *     supervisor stack below us. We are in supervisor mode and the rest
+ *     is our problem.
+ */
+               .globl __end
+               .globl __bss_start
+
+.mri 1
+               byte $15
+               byte $05
+               byte $C0
+               byte $DE
+start:
+               or #$0700,sr
+               move.l #__bss_start,a0
+               move.l #__end,d0
+               sub.l a0,d0
+               lsr.l #2,d0
+wipebss:
+               clr.l (a0)+
+               dbra d0,wipebss
+
+               /* FIXME: hard coded ugly */
+               move.l #udata_block+1016,a7
+               /* udata global */
+               move.l #udata_block,a5
+               bsr init_early
+               bsr init_hardware
+               bsr fuzix_main
+               or #$0700,sr
+stop:          bra stop
diff --git a/Kernel/platform-tiny68k/device.h b/Kernel/platform-tiny68k/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-tiny68k/devices.c b/Kernel/platform-tiny68k/devices.c
new file mode 100644 (file)
index 0000000..46ccf83
--- /dev/null
@@ -0,0 +1,45 @@
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <devide.h>
+#include <blkdev.h>
+#include <devsys.h>
+#include <tty.h>
+#include <vt.h>
+
+struct devsw dev_tab[] =  /* The device driver switch table */
+{
+// minor    open         close        read      write       ioctl
+// -----------------------------------------------------------------
+  /* 0: /dev/hd                Disc block devices  */
+  {  blkdev_open,   no_close,    blkdev_read,   blkdev_write, blkdev_ioctl },
+  /* 1: /dev/fd                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 */
+  {  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;
+
+  devide_init();
+
+  for (i = 1; i <= MAX_SWAPS; i++)
+    swapmap_init(i);
+}
diff --git a/Kernel/platform-tiny68k/devtty.c b/Kernel/platform-tiny68k/devtty.c
new file mode 100644 (file)
index 0000000..21ca2d8
--- /dev/null
@@ -0,0 +1,138 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <stdbool.h>
+#include <devtty.h>
+#include <device.h>
+#include <tty.h>
+
+static unsigned char tbuf1[TTYSIZ];
+static unsigned char tbuf2[TTYSIZ];
+
+#define UART_MRA       0x01
+#define UART_SRA       0x03
+#define UART_CSRA      0x03
+#define UART_CRA       0x05
+#define UART_RHRA      0x07
+#define UART_THRA      0x07
+#define UART_IPCR      0x09
+#define UART_ACR       0x09
+#define UART_ISR       0x0B
+#define UART_IMR       0x0B
+#define UART_CTU       0x0D
+#define UART_CTUR      0x0D
+#define UART_CTL       0x0F
+#define UART_CTLR      0x0F
+#define UART_MRB       0x11
+#define UART_SRB       0x13
+#define UART_CSRB      0x13
+#define UART_CRB       0x15
+#define UART_RHRB      0x17
+#define UART_THRB      0x17
+#define UART_IVR       0x19
+#define UART_OPCR      0x1B
+#define UART_STARTCTR  0x1D
+#define UART_SETOPR    0x1D
+#define UART_STOPCTR   0x1F
+#define UART_CLROPR    0x1F
+
+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},
+};
+
+static uint8_t sleeping;
+
+/* For now */
+static tcflag_t console_mask[4] = {
+       _ISYS,
+       _OSYS,
+       _CSYS,
+       _LSYS
+};
+
+tcflag_t *termios_mask[NUM_DEV_TTY + 1] = {
+       NULL,
+       console_mask,
+       console_mask
+};
+
+/* Output for the system console (kprintf etc) */
+void kputchar(char c)
+{
+       if (c == '\n')
+               tty_putc(1, '\r');
+       tty_putc(1, c);
+}
+
+static volatile uint8_t *uart_base = (volatile uint8_t *)0xFFF000;
+
+#define GETB(x)                (uart_base[(x)])
+#define PUTB(x,y)      uart_base[(x)] = (y)
+
+ttyready_t tty_writeready(uint8_t minor)
+{
+       uint8_t c = GETB(0x10 * minor + UART_SRA);
+       return (c & 2) ? TTY_READY_NOW : TTY_READY_SOON; /* TX DATA empty */
+}
+
+void tty_putc(uint8_t minor, unsigned char c)
+{
+       PUTB(0x10 * minor + UART_THRA, c);
+}
+
+void tty_setup(uint8_t minor, uint8_t flags)
+{
+}
+
+int tty_carrier(uint8_t minor)
+{
+       return 1;
+}
+
+void tty_sleeping(uint8_t minor)
+{
+       sleeping |= 1 << minor;
+}
+
+void tty_data_consumed(uint8_t minor)
+{
+}
+
+/* Currently run off the timer */
+static void tty_interrupt(uint8_t r)
+{
+       if (r & 0x01) {
+               r = GETB(UART_RHRA);
+               tty_inproc(1,r);
+       }       
+       if (r & 0x02) {
+               if (sleeping & 2)
+                       tty_outproc(1);
+       }
+       if (r & 0x04) {
+               /* How to clear break int ? */
+       }
+       if (r & 0x10) {
+               r = GETB(UART_RHRB);
+               tty_inproc(2,r);
+       }       
+       if (r & 0x20) {
+               if (sleeping & 4)
+                       tty_outproc(2);
+       }
+       if (r & 0x40) {
+               /* How to clear break int ? */
+       }
+}
+
+void platform_interrupt(void)
+{
+       uint8_t r = GETB(UART_ISR);
+       tty_interrupt(r);
+       if (r & 0x08)
+               timer_interrupt();
+       /* and 0x80 is the GPIO */
+}
+
diff --git a/Kernel/platform-tiny68k/devtty.h b/Kernel/platform-tiny68k/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-tiny68k/fuzix.ld b/Kernel/platform-tiny68k/fuzix.ld
new file mode 100644 (file)
index 0000000..ea455a5
--- /dev/null
@@ -0,0 +1,87 @@
+STARTUP(crt0.o)
+OUTPUT_ARCH(m68k)
+
+SEARCH_DIR(.)
+
+MEMORY
+{
+  ram (rwx) : ORIGIN = 0x400, LENGTH = 0x80000-0x400
+}
+
+/*
+ * 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.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+
+    *(.rodata .rodata.*)
+
+    . = ALIGN(0x4);
+    *(.gcc_except_table)
+
+    . = ALIGN(0x4);
+    *(.eh_frame)
+
+    . = ALIGN(0x4);
+    __INIT_SECTION__ = . ;
+    LONG (0x4e560000)   /* linkw %fp,#0 */
+    *(.init)
+    SHORT (0x4e5e)      /* unlk %fp */
+    SHORT (0x4e75)      /* rts */
+
+    . = ALIGN(0x4);
+    __FINI_SECTION__ = . ;
+    LONG (0x4e560000)   /* linkw %fp,#0 */
+    *(.fini)
+    SHORT (0x4e5e)      /* unlk %fp */
+    SHORT (0x4e75)      /* rts */
+
+    . = 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-tiny68k/libc.c b/Kernel/platform-tiny68k/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-tiny68k/loader.S b/Kernel/platform-tiny68k/loader.S
new file mode 100644 (file)
index 0000000..e980dbf
--- /dev/null
@@ -0,0 +1,76 @@
+#define DATA   0
+#define ERR    3
+#define NSEC   5
+#define LBA0   7
+#define LBA1   9
+#define LBA2   11
+#define LBA3   13
+#define COMMAND 15
+#define STATUS  15
+
+#define READY  6
+#define DRQ    3
+
+#define READ   $20
+
+/*
+ *     Simple loader to get us going
+ */
+       .globl start
+       .globl loader
+
+.mri   1
+
+start:
+       jmp.l $15050
+       jmp.l $15050            ; any value will do
+       ; This bit fools the CP/M bootloader checking
+       ; 34 words of padding
+       .ds 34
+       ; should be where we end up from the bra
+loader:
+       lea $00FF0000,a0
+       lea $00FFF000,a2
+       move.b #13,(a2)
+       lea strap,a1
+       move.w #1024,d0
+reloc:
+       move.w (a1)+,(a0)+
+       dbra d0,reloc
+       jmp.l $00FF0000
+
+strap:
+       move.b #10,(a2)
+       lea $00FFE000,a1
+       lea $00000400,a0
+       move.b #2,d2                    ; Sector
+       move.b #$80,d1                  ; Count to load (64K for now)
+       move.b #0xE0,LBA3(a0)
+wait0:
+       btst #READY,STATUS(a1)
+       beq wait0
+
+       move.b #0,LBA2(a0)
+       move.b #0,LBA1(a0)
+load:
+       move.b d2,LBA0(a1)
+       move.b #1,NSEC(a1)
+       add.q #1,d2
+wait1:
+       btst #READY,STATUS(a1)
+       beq wait1
+       move.b #READ,COMMAND(a1)
+       nop
+wait2:
+       btst #DRQ,STATUS(a1)
+       beq wait2
+
+       move.b #'.',(a2)
+       move.w #255,d0
+sector:
+       move.w (a1),(a0)+
+       dbra d0,sector
+       dbra d1,load
+
+       move.b #13,(a2)
+       jmp.l $00000400
diff --git a/Kernel/platform-tiny68k/loader.ld b/Kernel/platform-tiny68k/loader.ld
new file mode 100644 (file)
index 0000000..81f17f6
--- /dev/null
@@ -0,0 +1,86 @@
+OUTPUT_ARCH(m68k)
+
+SEARCH_DIR(.)
+
+MEMORY
+{
+  ram (rwx) : ORIGIN = 0x15000, LENGTH = 0x200
+}
+
+/*
+ * 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.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+
+    *(.rodata .rodata.*)
+
+    . = ALIGN(0x4);
+    *(.gcc_except_table)
+
+    . = ALIGN(0x4);
+    *(.eh_frame)
+
+    . = ALIGN(0x4);
+    __INIT_SECTION__ = . ;
+    LONG (0x4e560000)   /* linkw %fp,#0 */
+    *(.init)
+    SHORT (0x4e5e)      /* unlk %fp */
+    SHORT (0x4e75)      /* rts */
+
+    . = ALIGN(0x4);
+    __FINI_SECTION__ = . ;
+    LONG (0x4e560000)   /* linkw %fp,#0 */
+    *(.fini)
+    SHORT (0x4e5e)      /* unlk %fp */
+    SHORT (0x4e75)      /* rts */
+
+    . = 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-tiny68k/main.c b/Kernel/platform-tiny68k/main.c
new file mode 100644 (file)
index 0000000..e91de50
--- /dev/null
@@ -0,0 +1,140 @@
+#include <kernel.h>
+#include <timer.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devtty.h>
+#include <blkdev.h>
+
+uint16_t swap_dev = 0xFFFF;
+
+void platform_idle(void)
+{
+       /* Use STOP ? */
+}
+
+void do_beep(void)
+{
+}
+
+/*
+ *     MMU initialize
+ */
+
+void map_init(void)
+{
+}
+
+uaddr_t ramtop;
+uint8_t need_resched;
+
+uaddr_t pagemap_base(void)
+{
+       return 0x20000UL;
+}
+
+uint8_t platform_param(char *p)
+{
+       return 0;
+}
+
+void platform_discard(void)
+{
+}
+
+void memzero(void *p, usize_t len)
+{
+       memset(p, 0, len);
+}
+
+arg_t _memalloc(void)
+{
+       udata.u_error = ENOSYS;
+       return -1;
+}
+
+arg_t _memfree(void)
+{
+       udata.u_error = ENOSYS;
+       return -1;
+}
+
+
+/*
+ *     This function is called for partitioned devices if a partition is found
+ *     and marked as swap type. The first one found will be used as swap. We
+ *     only support one swap device.
+ */
+void platform_swap_found(uint8_t letter, uint8_t m)
+{
+       blkdev_t *blk = blk_op.blkdev;
+       uint16_t n;
+       if (swap_dev != 0xFFFF)
+               return;
+       letter -= 'a';
+       kputs("(swap) ");
+       swap_dev = letter << 4 | m;
+       n = blk->lba_count[m - 1] / SWAP_SIZE;
+       if (n > MAX_SWAPS)
+               n = MAX_SWAPS;
+#ifdef SWAPDEV
+       while (n)
+               swapmap_init(n--);
+#endif
+}
+/* Live udata and kernel stack */
+u_block udata_block;
+uint16_t irqstack[128];        /* Used for swapping only */
+
+/* This will belong in the core 68K code once finalized */
+
+void install_vdso(void)
+{
+       extern uint8_t vdso[];
+       /* Should be uput etc */
+       memcpy((void *)udata.u_codebase, &vdso, 0x40);
+}
+
+
+extern void *get_usp(void);
+extern void set_usp(void *p);
+
+void signal_frame(uint8_t *trapframe, uint32_t d0, uint32_t d1, uint32_t a0,
+       uint32_t a1)
+{
+       extern void *udata_shadow;
+       uint8_t *usp = get_usp();
+       udata_ptr = udata_shadow;
+       uint16_t ccr = *(uint16_t *)trapframe;
+       uint32_t addr = *(uint32_t *)(trapframe + 2);
+       int err = 0;
+
+       /* Build the user stack frame */
+
+       /* FIXME: eventually we should put the trap frame details and trap
+          info into the frame */
+       usp -= 4;
+       err |= uputl(addr, usp);
+       usp -= 4;
+       err |= uputw(ccr, usp);
+       usp -= 2;
+       err |=uputl(a1, usp);
+       usp -= 4;
+       err |= uputl(a0, usp);
+       usp -= 4;
+       err |= uputl(d1, usp);
+       usp -= 4;
+       err |= uputl(d0, usp);
+       usp -= 4;
+       err |= uputl(udata.u_codebase + 4, usp);
+       set_usp(usp);
+
+       if (err) {
+               kprintf("%d: stack fault\n", udata.u_ptab->p_pid);
+               doexit(SIGKILL/* FIXME dump_core(SIGKILL)*/);
+       }
+       /* Now patch up the kernel frame */
+       *(uint16_t *)trapframe = 0;
+       *(uint32_t *)(trapframe + 2) = (uint32_t)udata.u_sigvec[udata.u_cursig];
+       udata.u_sigvec[udata.u_cursig] = SIG_DFL;
+       udata.u_cursig = 0;
+}
diff --git a/Kernel/platform-tiny68k/p68000.S b/Kernel/platform-tiny68k/p68000.S
new file mode 100644 (file)
index 0000000..8332482
--- /dev/null
@@ -0,0 +1,161 @@
+
+#include "../kernel-68000.def"
+/*
+ *     Lots left to fill in
+ */
+
+               .globl platform_reboot
+               .globl init_early
+               .globl init_hardware
+               .globl program_vectors
+               .globl outchar
+               .globl platform_monitor
+               .globl udata_block
+               .globl devide_read_data
+               .globl devide_write_data
+               .globl vdso
+.mri 1
+platform_reboot:
+platform_monitor:
+           or #0700,sr
+           bra platform_monitor
+
+init_early:
+           lea.l udata_block,a5        ; udata ptr
+           move.l a5,udata_shadow      ; shadow copy for entry/exit
+            rts
+
+;
+;      FIXME: could be in discard if we wanted
+;
+init_hardware:
+            ; set system RAM size(hardcode hacks for now)
+           move.w #16352,d0
+           move.w d0,ramsize
+           sub.w  #64,d0               ; Guess for kernel
+           move.w d0,procmem           ; guesses for now
+
+           move.l #8,a0
+           move.w #253,d0
+           move.l #unexpected,d1
+init_trap_loop:
+           move.l d1,(a0)+
+           dbra d0,init_trap_loop
+           ;
+           ; Now set the vectors we care about
+           ;
+           move.w #8,a0
+           move.l #bus_error,(a0)+
+           move.l #addr_error,(a0)+
+           move.l #illegal,(a0)+
+           move.l #divzero,(a0)+
+           move.l #chk,(a0)+
+           move.l #trapv,(a0)+
+           move.l #priv,(a0)+
+           move.l #trace,(a0)+
+           move.l #unimpa,(a0)+        ; A and F line traps
+           move.l #unimpf,(a0)+
+           move.w #$80,a0
+           move.w #13,d0
+trapset:
+           move.l #misctrap,(a0)+
+           dbra d0,trapset
+           move.l #trap14,(a0)+
+           move.l #trap15,(a0)+
+           move.w #$0,a0
+           move.l #uninit,$3c(a0)
+           move.l #spurious,$60(a0)
+           ; FIXME: vectored so actually vector 0x81 I think ?
+           move.l #timer_irq,$78(a0)
+
+            rts
+
+timer_irq:
+           ; C will save and restore a2+/d2+
+           movem.l a0-a1/a5/d0-d1,-(sp)
+           move.l udata_shadow,a5      ; set up the register global
+           move.b #1,U_DATA__U_ININTERRUPT(a5)
+           jsr platform_interrupt
+           clr.b U_DATA__U_ININTERRUPT(a5)
+
+           tst.b U_DATA__U_INSYS(a5)
+           bne no_preempt
+           tst.b need_resched
+           bne no_preempt
+           ;
+           ;   Vanish into the scheduler. Some other task will pop back out
+           ;   and eventually we'll re-appear here and continue.
+           ;
+           ;   FIXME: check IRQ masking
+           ;
+           move.l U_DATA__U_PTAB(a5),a0
+           move.b #P_READY,P_TAB__P_STATUS_OFFSET(a0)
+           bsr switchout
+no_preempt:
+           tst.b U_DATA__U_CURSIG(a5)
+           beq no_signal
+           bra trap_via_signal         ; a0/a1/d0/d1 already stacked
+
+no_signal:
+           movem.l (sp)+,a0-a1/a5/d0-d1
+           rte
+
+;
+;      Nothing to do in 68000 - all set up once at boot
+;
+program_vectors:
+       rts
+
+;
+;      We do no banking so we need to do nothing here.
+;
+map_process_always:
+map_process:
+map_kernel:
+map_restore:
+map_save:
+       rts
+
+; outchar: Wait for UART TX idle, then print the char in d0
+
+outchar:
+outcharw:
+       btst #2,$00FFF003
+       beq outcharw
+       move.b d0,$00FFF000
+       rts
+;
+;      IDE:
+;
+devide_read_data:
+       move.l blk_op,a0
+       move.l #$00FFE000,a1
+       move.w #255,d0
+devide_read_l:
+       move.w (a1),(a0)+
+       dbra d0,devide_read_l
+       rts
+
+devide_write_data:
+       move.l blk_op,a0
+       move.l #$00FFE000,a1
+       move.w #255,d0
+devide_write_l:
+       move.w (a0)+,(a1)
+       dbra d0,devide_write_l
+       rts
+
+;
+;      'VDSO'
+;
+vdso:  trap #14                ; syscall entry
+       rts
+       ; signal unwind
+       movem.l (sp)+,a0/a1/d0/d1
+       move.w (sp)+,ccr
+       rts
+       ; rest is spare for now
+
+.section data
+
+kernel_flag: byte 1
diff --git a/Kernel/platform-tiny68k/platform_ide.h b/Kernel/platform-tiny68k/platform_ide.h
new file mode 100644 (file)
index 0000000..076a062
--- /dev/null
@@ -0,0 +1,18 @@
+#define IDE_IS_MMIO  1         /* MMIO IDE */
+
+#define IDE_REG_DATA           0x00F01000
+#define IDE_REG_ERROR          0x00F01003
+#define IDE_REG_FEATURES       0x00F01003
+#define IDE_REG_SEC_COUNT      0x00F01005
+#define IDE_REG_LBA_0          0x00F01007
+#define IDE_REG_LBA_1          0x00F01009
+#define IDE_REG_LBA_2          0x00F0100B
+#define IDE_REG_LBA_3          0x00F0100D
+#define IDE_REG_DEVHEAD                0x00F0100D
+#define IDE_REG_STATUS         0x00F0100F
+#define IDE_REG_COMMAND                0x00F0100F
+
+/* FIXME: Check altstatus/control mapping */
+
+#define ide_select(x)
+#define ide_deselect()
diff --git a/Kernel/platform-tiny68k/target.mk b/Kernel/platform-tiny68k/target.mk
new file mode 100644 (file)
index 0000000..df1c235
--- /dev/null
@@ -0,0 +1 @@
+export CPU = 68000
diff --git a/Kernel/platform-tiny68k/tricks.S b/Kernel/platform-tiny68k/tricks.S
new file mode 100644 (file)
index 0000000..29b86f8
--- /dev/null
@@ -0,0 +1,169 @@
+#include "../kernel-68000.def"
+
+
+.globl platform_switchout,switchin,dofork,udata_shadow
+
+.mri 1
+
+; Switchout switches out the current process, finds another that is READY,
+; possibly the same process, and switches it in.  When a process is
+; restarted after calling switchout, it thinks it has just returned
+; from switchout().
+platform_switchout:
+        or #$0700,sr
+        ; save machine state
+
+        clr.w -(sp) ; return code set here is ignored, but switchin can
+        ; return from either switchout OR dofork, so they must both write
+        ; U_DATA__U_SP with the following on the stack:
+       move.l usp,a0
+       movem.l a0/a2-a4/a6/d2-d7,-(sp)
+       move.l sp,U_DATA__U_SP(a5)      ; this is where the SP is restored in switchin
+
+        ; find another process to run (may select this one again)
+        bsr getproc
+
+       move.l d0,-(sp)
+        bsr switchin
+
+        ; we should never get here
+        bra platform_monitor
+
+switchin:
+        or #$0700,sr
+       move.l 4(sp),a0         ; task to switch to
+       move.l P_TAB__P_UDATA_OFFSET(a0),a5
+       tst.w P_TAB__P_PAGE_OFFSET(a0)  ; swapped or existing process ?
+       bne not_swapped
+
+;
+;      If you have one udata and swap them then you need to stack switch
+;      for the swap in as you'll overwrite the kernel stack. You can use
+;      the IRQ stack but only if you leave IRQs off for a swap in (ugghh)
+;
+
+;
+;      FIXME: sort IRQ enables
+;
+
+;
+;      In simple mode the existing process always gets the boot here
+;      before we can swap the new one in
+;
+       move.l U_DATA__U_PTAB(a5),a1    ; old process
+       tst.w P_TAB__P_PAGE_OFFSET(a1)  ; swapped out/dead ?
+       beq its_dead_jim                ; corpses don't need swapping out
+
+       move.l a0,-(sp)
+       move.l a1,-(sp)
+       jsr swapout
+       addq #4,sp
+       move.l (sp)+,a0
+
+its_dead_jim:
+       move.l sp,a1
+       move.l #irqstack+256,sp
+       move.l a1,-(sp)
+       move.l a0,-(sp)
+       move.l a0,-(sp)
+       jsr swapper
+       addq #4,sp
+       move.l (sp)+,a0
+       move.w #1,P_TAB__P_PAGE_OFFSET(a0) ; swapped in
+       move.l (sp)+,a1                 ; straight into a7 fails
+       move.l a1,a7                    ; emulator bug or CPU funny ??
+
+        or #$0700,sr
+
+not_swapped:
+        ; check u_data->u_ptab matches what we wanted
+       cmp.l U_DATA__U_PTAB(a5),a0
+       bne switchinfail
+
+       move.b #P_RUNNING,P_TAB__P_STATUS_OFFSET(a0)
+
+        ; runticks = 0
+       clr.w runticks
+
+        ; restore machine state
+        move.l U_DATA__U_SP(a5),sp
+       movem.l (sp)+,a0/a2-a4/a6/d2-d7
+       move.l a0,usp
+       move.w (sp)+,d0                 ; FIXME: can we merge ?
+
+        tst.b U_DATA__U_ININTERRUPT(a5)
+        bne keepoff ; in ISR, leave interrupts off
+        and #$F8FF,sr
+keepoff:
+        rts ; return with interrupts on
+
+switchinfail:
+       bsr outa0hex
+        lea badswitchmsg,a0
+        bsr outstring
+       ; something went wrong and we didn't switch in what we asked for
+        bra platform_monitor
+
+       ;
+       ; this gets exciting on the 68000 because our udata is not in a
+       ; fixed location except for swap only platforms. That means any
+       ; udata relative pointers on the stack when we duplicate the kernel
+       ; stack point to the parent. For the simple case we have a single
+       ; swapped udata and stack so all is fairly easy. For the other
+       ; cases we have to return as the parent but set up a fake stack
+       ; frame for the child to exit the syscall. Simply being careful
+       ; about pointers doesn't work - the compiler will internally
+       ; use link/unlk and other stuff.
+       ;
+       ; Entry:
+       ; A5 = u_data pointer for parent
+       ; 4(sp) = child process table entry
+       ;
+       ; Exit:
+       ; We are running as the child, A5 = u_data pointer of child, on
+       ; child stack
+       ;
+dofork:
+       ;
+       ; simple edition for swap only
+       ;
+       move.l 4(sp),a0                 ;       child p_tab
+       ;
+       ; in the simple case we only have one udata. In the complex cases
+       ; we would have to compute the new one and load it into a5 and
+       ; offset
+       ;
+       move.l a5,P_TAB__P_UDATA_OFFSET(a0)
+       move.w P_TAB__P_PID_OFFSET(a0),-(sp)    ;       child pid (parent return)
+       move.l usp,a0
+       movem.l a0/a2-a4/a6/d2-d7,-(sp) ;       save state
+       move.l sp,U_DATA__U_SP(a5)      ;       save pointer
+       move.l U_DATA__U_PTAB(a5),-(sp) ;       parent p_tab
+
+       ; FIXME: for the single case with less swaps than processes the
+       ; out of swap case is one out (we must swap out to swap in so need
+       ; one swap free after the fork. Right now we deal with this in
+       ; Config by not setting it that way
+       jsr swapout
+       add.w #50,sp                    ;       throw the call frame and
+                                       ;       the frame we built for
+                                       ;       switchin
+       tst.w d0
+       bne forked_up
+
+       movel a5,-(sp)                  ;       U_DATA
+       move.l 4(sp),a0
+       move.l a0,-(sp)
+       jsr makeproc
+       addq #8,sp
+
+       moveq #0,d0                     ;       child, ok
+       clr.w runticks
+       rts
+forked_up:
+       moveq #-1,d0                    ;       parent, failed
+       rts
+
+badswitchmsg: ascii "_switchin: FAIL"
+            byte 13,10,0
+.even