From: Alan Cox Date: Wed, 16 Jan 2019 22:19:01 +0000 (+0000) Subject: tiny68K; just an initial commit X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=432df6abd61b07916bcaee43788360330a682d2b;p=FUZIX.git tiny68K; just an initial commit --- diff --git a/Kernel/platform-tiny68k/Makefile b/Kernel/platform-tiny68k/Makefile new file mode 100644 index 00000000..9f4a6e3c --- /dev/null +++ b/Kernel/platform-tiny68k/Makefile @@ -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 index 00000000..9857e901 --- /dev/null +++ b/Kernel/platform-tiny68k/README @@ -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 index 00000000..c33dee77 --- /dev/null +++ b/Kernel/platform-tiny68k/config.h @@ -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 index 00000000..9b7796cb --- /dev/null +++ b/Kernel/platform-tiny68k/crt0.S @@ -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 index 00000000..6f4c1e26 --- /dev/null +++ b/Kernel/platform-tiny68k/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-tiny68k/devices.c b/Kernel/platform-tiny68k/devices.c new file mode 100644 index 00000000..46ccf83d --- /dev/null +++ b/Kernel/platform-tiny68k/devices.c @@ -0,0 +1,45 @@ +#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/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 index 00000000..21ca2d82 --- /dev/null +++ b/Kernel/platform-tiny68k/devtty.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#include +#include + +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 index 00000000..14c28c31 --- /dev/null +++ b/Kernel/platform-tiny68k/devtty.h @@ -0,0 +1,10 @@ +#ifndef __DEVTTY_DOT_H__ +#define __DEVTTY_DOT_H__ + +#define KEY_ROWS 8 +#define KEY_COLS 7 +extern uint8_t keymap[8]; +extern uint8_t keyboard[8][7]; +extern uint8_t shiftkeyboard[8][7]; + +#endif diff --git a/Kernel/platform-tiny68k/fuzix.ld b/Kernel/platform-tiny68k/fuzix.ld new file mode 100644 index 00000000..ea455a5f --- /dev/null +++ b/Kernel/platform-tiny68k/fuzix.ld @@ -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 index 00000000..e718087e --- /dev/null +++ b/Kernel/platform-tiny68k/libc.c @@ -0,0 +1,40 @@ +#include "cpu.h" + +void *memcpy(void *d, const void *s, size_t sz) +{ + unsigned char *dp = d; + const unsigned char *sp = s; + while(sz--) + *dp++=*sp++; + return d; +} + +void *memset(void *d, int c, size_t sz) +{ + unsigned char *p = d; + while(sz--) + *p++ = c; + return d; +} + +size_t strlen(const char *p) +{ + const char *e = p; + while(*e++); + return e-p-1; +} + +int memcmp(const void *a, const void *b, size_t n) +{ + const uint8_t *ap = a; + const uint8_t *bp = b; + while(n--) { + if (*ap < *bp) + return -1; + if (*ap != *bp) + return 1; + ap++; + bp++; + } + return 0; +} diff --git a/Kernel/platform-tiny68k/loader.S b/Kernel/platform-tiny68k/loader.S new file mode 100644 index 00000000..e980dbf9 --- /dev/null +++ b/Kernel/platform-tiny68k/loader.S @@ -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 index 00000000..81f17f6a --- /dev/null +++ b/Kernel/platform-tiny68k/loader.ld @@ -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 index 00000000..e91de50c --- /dev/null +++ b/Kernel/platform-tiny68k/main.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include +#include + +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 index 00000000..83324826 --- /dev/null +++ b/Kernel/platform-tiny68k/p68000.S @@ -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 index 00000000..076a0626 --- /dev/null +++ b/Kernel/platform-tiny68k/platform_ide.h @@ -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 index 00000000..df1c235f --- /dev/null +++ b/Kernel/platform-tiny68k/target.mk @@ -0,0 +1 @@ +export CPU = 68000 diff --git a/Kernel/platform-tiny68k/tricks.S b/Kernel/platform-tiny68k/tricks.S new file mode 100644 index 00000000..29b86f82 --- /dev/null +++ b/Kernel/platform-tiny68k/tricks.S @@ -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