+++ /dev/null
-
-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/
-
-JUNK = $(CSRCS:.c=.o) $(ASRCS:.S=.o)
-
-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 $(OBJS) $(JUNK) core *~
-
-image:
- $(CROSS_LD) -M -o fuzix.elf -T fuzix.ld \
- crt0.o \
- p68000.o ../start.o ../version.o ../lowlevel-68000.o \
- tricks.o ../bankfixed.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 > ../fuzix.map
- m68k-uclinux-objcopy fuzix.elf -O binary ../fuzix.bin
+++ /dev/null
-See platform-v68
-
-This is a test tree for a configuration using banked memory (N8VEM 680x0
-style). In this configuration we place the kernel in the low 64K of the
-emulator space (protected), and we put the applications and the udata stash
-in each bank. This allows us to keep the kernel protected. We'd have far
-faster task switch if we kept udata banks all in the kernel and moved a5
-(plus did fork differently) but would then lose the 64K protection.
-
-We simulate 4 banks of 128K plus swap.
-
-The current model this uses only makes sense for small memory sizes. If you
-have lots of memory then we need a much smarter swap algorithm that does real
-allocation and we also need to avoid copying empty zones we can zero.
-
-TODO
-
-- Make bankfixed support only writing out used areas of memory
-
-- Make fork copy only the needed bits
-
-Look at a bankfixed/bankfixed32 split - put the smarts in bankfixed32 and then
-look at a proper swap allocator so we don't waste tons of memory with big
-banks.
-
-- Write optimised udata copier ? (movem based and reverse ?)
-
-- Save restore bank on interrupt entry/exit
+++ /dev/null
-/* 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_MULTI
-/* This works for banks as kernel is not banked, but won't work when we go
- real MMU */
-#define CONFIG_USERMEM_DIRECT
-#define CONFIG_BANK_FIXED
-#define MAX_MAPS 4
-#define MAPBASE 0x00200000
-#define MAP_SIZE 0x0001FC00
-
-#define CONFIG_LARGE_IO_DIRECT(x) 1
-
-#define CONFIG_BANKS 1
-#define PROC_SIZE MAP_SIZE /* 128K minus udata */
-
-#define PROGBASE MAPBASE
-#define PROGTOP (MAPBASE + MAP_SIZE)
-#define SWAP_SIZE 256 /* 128K including udata */
-#define SWAPBASE PROGBASE
-#define SWAPTOP (PROGTOP + 0x400)
-#define MAX_SWAPS 16
-
-#define swap_map(x) ((uint8_t *)(x))
-
-#define SWAPDEV (1)
-
-#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 1
-#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */
-#define NBUFS 10 /* Number of block buffers */
-#define NMOUNTS 4 /* Number of mounts at a time */
-
-#define MAX_BLKDEV 4
-
-#define CONFIG_IDE
-
-#define platform_copyright()
-
-#define BOOTDEVICENAMES "hd#"
+++ /dev/null
-/*
- * 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
- /* ensure we have bank 0 mapped */
- clr.b $00F05000
- /* Launch the OS */
- bsr init_early
- bsr init_hardware
- bsr fuzix_main
- or #$0700,sr
-stop: bra stop
+++ /dev/null
-#ifndef __DEVICE_DOT_H__
-#define __DEVICE_DOT_H__
-
-extern void mod_control(uint8_t set, uint8_t clr);
-
-#endif /* __DEVICE_DOT_H__ */
+++ /dev/null
-#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);
-}
+++ /dev/null
-#include <kernel.h>
-#include <kdata.h>
-#include <printf.h>
-#include <stdbool.h>
-#include <devtty.h>
-#include <device.h>
-#include <tty.h>
-
-volatile uint8_t *uart_data = (volatile uint8_t *)0xF03000; /* UART data */
-volatile uint8_t *uart_status = (volatile uint8_t *)0xF03010; /* UART status */
-
-static unsigned char tbuf1[TTYSIZ];
-
-struct s_queue ttyinq[NUM_DEV_TTY + 1] = { /* ttyinq[0] is never used */
- {NULL, NULL, NULL, 0, 0, 0},
- {tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2},
-};
-
-static tcflag_t console_mask[4] = {
- _ISYS,
- _OSYS,
- _CSYS,
- _LSYS
-};
-
-tcflag_t *termios_mask[NUM_DEV_TTY + 1] = {
- NULL,
- console_mask
-};
-
-/* Output for the system console (kprintf etc) */
-void kputchar(char c)
-{
- if (c == '\n')
- tty_putc(1, '\r');
- tty_putc(1, c);
-}
-
-ttyready_t tty_writeready(uint8_t minor)
-{
- uint8_t c = *uart_status;
- return (c & 2) ? TTY_READY_NOW : TTY_READY_SOON; /* TX DATA empty */
-}
-
-void tty_putc(uint8_t minor, unsigned char c)
-{
- *uart_data = c; /* Data */
-}
-
-void tty_setup(uint8_t minor, uint8_t flags)
-{
-}
-
-int tty_carrier(uint8_t minor)
-{
- return 1;
-}
-
-void tty_sleeping(uint8_t minor)
-{
-}
-
-void tty_data_consumed(uint8_t minor)
-{
-}
-
-/* Currently run off the timer */
-void tty_interrupt(void)
-{
- uint8_t r = *uart_status;
- if (r & 1) {
- r = *uart_data;
- tty_inproc(1,r);
- }
-}
-
-void platform_interrupt(void)
-{
- timer_interrupt();
- tty_interrupt();
-}
+++ /dev/null
-#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
+++ /dev/null
-STARTUP(crt0.o)
-OUTPUT_ARCH(m68k)
-
-SEARCH_DIR(.)
-
-MEMORY
-{
- ram (rwx) : ORIGIN = 0x2000, LENGTH = 0x80000-0x2000
-}
-
-/*
- * 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)
- }
-}
+++ /dev/null
-#define UDATA_STASH $02FFFC00
\ No newline at end of file
+++ /dev/null
-#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;
-}
+++ /dev/null
-#include <kernel.h>
-#include <timer.h>
-#include <kdata.h>
-#include <printf.h>
-#include <devtty.h>
-#include <buddy.h>
-
-void platform_idle(void)
-{
- /* FIXME: disable IRQ, run tty interrupt, re-enable ? */
-}
-
-void do_beep(void)
-{
-}
-
-/*
- * MMU initialize
- */
-
-void map_init(void)
-{
-}
-
-void pagemap_init(void)
-{
- /* 0 means swapped */
- /* We number 1-4 and reply on the hardware wrapping to 0,3,2,1...
- in the more general case if you use 0 then you need to invent
- it */
- pagemap_add(3);
- pagemap_add(2);
- pagemap_add(1);
- pagemap_add(4);
-}
-
-uaddr_t ramtop;
-uint8_t need_resched;
-
-/* Each process is mapped into the same banked address */
-uaddr_t pagemap_base(void)
-{
- return MAPBASE;
-}
-
-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;
-}
-
-/* Live udata and kernel stack for each process */
-/* FIXME: we need to find a way to make these smaller or bank them out but
- that has a material cost */
-
-u_block udata_block[PTABSIZE];
-uint16_t irqstack[128];
-
-/* 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(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;
-}
+++ /dev/null
-
-#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 #512,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)
- move.l #timer_irq,$78(a0)
- move.l #mmu_fault,$7C(a0)
-
- moveq #1,d0 ;
- move.b d0,$00F04000
- 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)
- move.b $00F04000,d0 ; Re-enable
-
- 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
-
-mmu_fault:
- tst.w $00F02020 ; clear the MMU flag
- move.l d0,-(sp)
- move.b #'M',d0
- jsr outchar
- move.l (sp)+,d0
- bra addr_error ; treat as an address error
-
-;
-; Nothing to do in 68000 - all set up once at boot
-;
-program_vectors:
- rts
-
-;
-; Switch the banking hardware.
-;
-map_process_always:
- ; make sure the current process is mapped.
- move.b U_DATA__U_PAGEB(a5),$00F05000
- rts
-map_process:
- ; map a specific process (not actually used)
- move.b P_TAB__P_PAGE_OFFSETB(a5),$00F05000
- rts
-map_restore:
- move.b $00F05000,banksave
- rts
-map_save:
- move.b banksave,$00F05000
- rts
-map_kernel: ; we never bank out the kernel
- rts
-
-; outchar: Wait for UART TX idle, then print the char in d0
-
-outchar:
- move.w d0,-(sp)
-outcharw:
- move.b $00F03010,d0
- btst #1,d0
- beq outcharw
- move.w (sp)+,d0
- move.b d0,$00F03000
- rts
-
-;
-; IDE. This differs a tiny bit from the simple case because we must
-; support bank switching while handling swap.
-;
-devide_read_data:
- lea.l blk_op,a0
- move.b 4(a0),d0
- move.b $00F05000,d1
- cmp.b #2,d0
- bne notswap
- move.b 5(a0),$00F05000
-notswap:
- move.w #255,d0
- move.l (a0),a0
-devide_read_l:
- move.w $00F01000,(a0)+
- dbra d0,devide_read_l
- move.b d1,$00F05000
- rts
-
-devide_write_data:
- lea.l blk_op,a0
- move.b 4(a0),d0
- move.b $00F05000,d1
- cmp.b #2,d0
- bne notswapw
- move.b 5(a0),$00F05000
-notswapw:
- move.w #255,d0
- move.l (a0),a0
-devide_write_l:
- move.w (a0)+,$00F01000
- dbra d0,devide_write_l
- move.b d1,$00F05000
- 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
-banksave: byte 0
+++ /dev/null
-#define IDE_IS_MMIO 1 /* MMIO IDE */
-
-#define IDE_REG_DATA 0x00F01000
-#define IDE_REG_ERROR 0x00F01002
-#define IDE_REG_FEATURES 0x00F01002
-#define IDE_REG_SEC_COUNT 0x00F01004
-#define IDE_REG_LBA_0 0x00F01006
-#define IDE_REG_LBA_1 0x00F01008
-#define IDE_REG_LBA_2 0x00F0100A
-#define IDE_REG_LBA_3 0x00F0100C
-#define IDE_REG_DEVHEAD 0x00F0100C
-#define IDE_REG_STATUS 0x00F0100E
-#define IDE_REG_COMMAND 0x00F0100E
-#define IDE_REG_ALTSTATUS 0x00F01010
-#define IDE_REG_CONTROL 0x00F01010
-
-#define ide_select(x)
-#define ide_deselect()
+++ /dev/null
-export CPU = 68000
+++ /dev/null
-#include "../kernel-68000.def"
-#include "kernel.def"
-
-.globl platform_switchout,switchin,dofork,udata_shadow,udata_stash
-
-
-.mri 1
-;
-; There are two ways a banked 68K system can handle the udata pointer.
-; The first is to keep an array of udata objects in the kernel space
-; and flip a5, the other is to copy the udata to and from a save area
-; in the banks as we do on 8bit. The former is far faster but the
-; latter is useful if you have a limited area of protected memory for
-; the kernel.
-;
-; For the virtual platform we use the stash because of the limited
-; protected area. In the multiple udata case dofork instead needs to
-; - push a switchin frame
-; - save the state in its udata as it would with a switchout
-; - copy the udata state to the child
-; - call newproc(child) with udata ptr pointing to the child
-; - clear runticks
-; - mark itself running
-; - build a top of supervisor frame to return to userspace
-; - move stack up to it
-; - clear registers
-; - restore user a5
-; - rte
-
-; 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
- ;
- ; keep a fast path for wakeup of the last executed process. We don't
- ; need the fastpaths if not copying udata buffers.
- ;
- tst.b nready
- bne slow_path
-idling:
- and #$F8FF,sr
- jsr platform_idle
- or #$0700,sr
- move.b nready,d0
- beq idling
- cmp.b #1,d0
- bne slow_path
- move.l U_DATA__U_PTAB(a5),a0
- cmp.b #P_READY,P_TAB__P_STATUS_OFFSET(a0)
- bne slow_path
- mov.b #P_RUNNING,P_TAB__P_STATUS_OFFSET(a0)
- movem.l (sp)+,a0/a2-a4/a6/d2-d7
- addq #2,sp
-;
-; FIXME: check if in interrupt and if so don't restore IRQ ?
-;
- and #$F8FF,sr
- rts
-
-slow_path:
- lea.l udata_stash,a0
- move.l a5,a1
- move.w #255,d0
- ; FIXME - optimise 1K copy
-copyi: move.l (a1)+,(a0)+
- dbra d0,copyi
-
- ; 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
-
- ;
- ; We are going to copy over the process stack so use the
- ; other stack for this
- ;
- lea.l irqstack+256,sp ; switch stack to copy the udata/stack
-
- ;
- ; Now switch task context
- ;
- move.l P_TAB__P_UDATA_OFFSET(a0),a5
- tst.w P_TAB__P_PAGE_OFFSET(a0) ; swapped or existing process ?
- bne not_swapped
-
-;
-; FIXME: sort IRQ enables
-;
-
- move.l a0,-(sp)
- move.l a0,-(sp)
- jsr swapper
- addq #4,sp
- move.l (sp)+,a0
-
- or #$0700,sr
- bra copyud
-
-not_swapped:
- move.w P_TAB__P_PAGE_OFFSET(a0),d0
- ; switch memory bank
- move.b d0,$FFF05000
- ; is the cached udata still valid ?
- move.l P_TAB__P_UDATA_OFFSET(a0),a5
- cmp.l U_DATA__U_PTAB(a5),a0
- beq skip_copyback
-copyud:
- ;
- ; Recover the udata block
- ;
- lea.l udata_stash,a1
- move.w #255,d0
-copyo:
- move.l (a1)+,(a5)+
- dbra d0,copyo
-
-skip_copyback:
- move.l P_TAB__P_UDATA_OFFSET(a0),a5
- ; 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)
- move.w P_TAB__P_PAGE_OFFSET(a0),U_DATA__U_PAGE(a5)
-
- ; 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 always 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 and leap directly back to user mode
- ;
-dofork:
- ;
- ; We need the child to return off its own stack so this is very
- ; different to other platforms.
- ;
- 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
-
- ;
- ; Set up a switchin frame for the parent process and ensure the
- ; parent state is valid
- ;
- move.w P_TAB__P_PID_OFFSET(a0),-(sp) ; child pid (parent return)
- move.l usp,a1
- movem.l a1-a4/a6/d2-d7,-(sp) ; save state
- move.l sp,U_DATA__U_SP(a5) ; save pointer
- ;
- ; At this point we can make a copy of the parent udata into the
- ; stash and it will be valid
-
- move.l a0,-(sp) ; argument to newproc
-
- ;
- ; Save the parent into the udata stash
- ;
- lea.l udata_stash,a0
- move.l a5,a1
- move.w #255,d0
- ; FIXME - optimise 1K copy
-copyif: move.l (a1)+,(a0)+
- dbra d0,copyif
-
- move.l (sp),a0
- move.w P_TAB__P_PAGE_OFFSET(a0),d0 ; page
-
- ;
- ; Copy the banks over
- ;
-
- jsr bankfork ; copy the memory
-
- move.l (sp),a0
-
- ;
- ; We enter this on the child's mappings with its udata
- ;
- jsr newproc ; Called with the child udata
- add.w #50,sp ; toss the stack frames
-
- clr.w runticks
- moveq #0,d0 ; child
- rts
-
-bankfork:
- ; copy the memory banks over (we copy the lot we should fast copy
- ; the actual used low/high chunks and then zero the middle
- ;
- ; FIXME: write it to run at proper speed etc
- ;
- ; Caution we are copying our own stack here
- ;
- ;
- move.l d2,-(sp)
- move.l #$00200000,a0 ; process base
- move.b $FFF05000,d1 ; parent page
-
-copyloop:
- move.b d1,$FFF05000 ; parent bank
- move.l (a0),d2
- move.b d0,$FFF05000 ; child bank
- move.l d2,(a0)+
- cmp.l #$00220000,a0
- bne copyloop
- ; Return with child bank paged as we want it
- move.l (sp)+,d2 ; we swapped stack but copied d2
- rts ; so popping off the other bank
- ; is fine
-
-badswitchmsg: ascii "_switchin: FAIL"
- byte 13,10,0
-.even
-
-
-udata_stash equ UDATA_STASH
+++ /dev/null
-
-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/
-
-JUNK = $(CSRCS:.c=.o) $(ASRCS:.S=.o)
-
-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 $(OBJS) $(JUNK) core *~
-
-image:
- $(CROSS_LD) -M -o fuzix.elf -T fuzix.ld \
- crt0.o \
- p68000.o ../start.o ../version.o ../lowlevel-68000.o \
- tricks.o ../bankfixed.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 ../flat_mem.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 > ../fuzix.map
- m68k-uclinux-objcopy fuzix.elf -O binary ../fuzix.bin
+++ /dev/null
-See platform-v68
-
-This is a test tree for a configuration developing the software MMU mode. It's
-not yet functional and will crash when fork() is hit.
-
+++ /dev/null
-/* 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_MULTI
-#define CONFIG_USERMEM_DIRECT
-#define CONFIG_VMMU
-
-#define CONFIG_LARGE_IO_DIRECT(x) 1
-
-#define MMU_BLKSIZE 8192
-
-#define CONFIG_BANKS 1
-
-#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 1
-#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */
-#define NBUFS 10 /* Number of block buffers */
-#define NMOUNTS 4 /* Number of mounts at a time */
-
-#define MAX_BLKDEV 4
-
-#define platform_copyright()
-
-#definbe BOOTDEVICENAMES "hd#"
+++ /dev/null
-/*
- * 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
- /* ensure we have bank 0 mapped */
- clr.b $00F05000
- /* Launch the OS */
- bsr init_early
- bsr init_hardware
- bsr fuzix_main
- or #$0700,sr
-stop: bra stop
+++ /dev/null
-#ifndef __DEVICE_DOT_H__
-#define __DEVICE_DOT_H__
-
-extern void mod_control(uint8_t set, uint8_t clr);
-
-#endif /* __DEVICE_DOT_H__ */
+++ /dev/null
-#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();
-}
+++ /dev/null
-#include <kernel.h>
-#include <kdata.h>
-#include <printf.h>
-#include <stdbool.h>
-#include <devtty.h>
-#include <device.h>
-#include <tty.h>
-
-volatile uint8_t *uart_data = (volatile uint8_t *)0xF03000; /* UART data */
-volatile uint8_t *uart_status = (volatile uint8_t *)0xF03010; /* UART status */
-
-static unsigned char tbuf1[TTYSIZ];
-
-struct s_queue ttyinq[NUM_DEV_TTY + 1] = { /* ttyinq[0] is never used */
- {NULL, NULL, NULL, 0, 0, 0},
- {tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2},
-};
-
-static tcflag_t console_mask[4] = {
- _ISYS,
- _OSYS,
- _CSYS,
- _LSYS
-};
-
-tcflag_t *termios_mask[NUM_DEV_TTY + 1] = {
- NULL,
- console_mask
-};
-
-/* Output for the system console (kprintf etc) */
-void kputchar(char c)
-{
- if (c == '\n')
- tty_putc(1, '\r');
- tty_putc(1, c);
-}
-
-ttyready_t tty_writeready(uint8_t minor)
-{
- uint8_t c = *uart_status;
- return (c & 2) ? TTY_READY_NOW : TTY_READY_SOON; /* TX DATA empty */
-}
-
-void tty_putc(uint8_t minor, unsigned char c)
-{
- *uart_data = c; /* Data */
-}
-
-void tty_setup(uint8_t minor, uint8_t flags)
-{
-}
-
-int tty_carrier(uint8_t minor)
-{
- return 1;
-}
-
-void tty_sleeping(uint8_t minor)
-{
-}
-
-void tty_data_consumed(uint8_t minor)
-{
-}
-
-/* Currently run off the timer */
-void tty_interrupt(void)
-{
- uint8_t r = *uart_status;
- if (r & 1) {
- r = *uart_data;
- tty_inproc(1,r);
- }
-}
-
-void platform_interrupt(void)
-{
- timer_interrupt();
- tty_interrupt();
-}
+++ /dev/null
-#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
+++ /dev/null
-#define UDATA_STASH $02FFFC00
\ No newline at end of file
+++ /dev/null
-#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;
-}
+++ /dev/null
-#include <kernel.h>
-#include <timer.h>
-#include <kdata.h>
-#include <printf.h>
-#include <devtty.h>
-#include <flat_mem.h>
-
-/* FIXME don't hard code! */
-uint8_t *memtop = (uint8_t *)0x100000;
-uint8_t *membase = (uint8_t *)0x018000;
-
-void platform_idle(void)
-{
- /* FIXME: disable IRQ, run tty interrupt, re-enable ? */
-}
-
-void do_beep(void)
-{
-}
-
-/*
- * MMU initialize
- */
-
-void map_init(void)
-{
-}
-
-void pagemap_init(void)
-{
- vmmu_init();
-}
-
-uaddr_t ramtop;
-uint8_t need_resched;
-
-uint8_t platform_param(char *p)
-{
- return 0;
-}
-
-void platform_discard(void)
-{
-}
-
-void platform_mmu_setup(struct mmu_context *m)
-{
- /* Allocate an initial space for the init task that will hold
- the execve arguments and be freed when init loads */
- m->base = vmmu_alloc(&m->mmu, MMU_BLKSIZE, 0, 0, 1);
- if (m->base == NULL)
- panic("initmmu");
- kprintf("init boot at %p\n", m->base);
-}
-
-void fast_zero_block(void *p)
-{
- memset(p, 0, MMU_BLKSIZE);
-}
-
-void fast_swap_block(void *ap, void *bp)
-{
- /* TODO */
- uint32_t *a = ap, *b = bp;
- int n = 0;
- while(n++ < MMU_BLKSIZE/4) {
- uint32_t t = *a;
- *a++ = *b;
- *b++ = t;
- }
-}
-
-void fast_copy_block(void *a, void *b)
-{
- /* TODO */
- memcpy(a, b, MMU_BLKSIZE);
-}
-
-void fast_op_complete(void)
-{
-}
-
-
-/* Live udata and kernel stack for each process */
-/* FIXME: we need to find a way to make these smaller or bank them out but
- that has a material cost */
-
-u_block udata_block[PTABSIZE];
-uint16_t irqstack[128];
-
-/* 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(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;
-}
-
+++ /dev/null
-
-#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(hadcode hacks for now)
- move.w #512,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)
- move.l #timer_irq,$78(a0)
- move.l #mmu_fault,$7C(a0)
-
- moveq #1,d0 ;
- move.b d0,$00F04000
- 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)
- move.b $00F04000,d0 ; Re-enable
-
- 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
-
-mmu_fault:
- tst.w $00F02020 ; clear the MMU flag
- move.l d0,-(sp)
- move.b #'M',d0
- jsr outchar
- move.l (sp)+,d0
- bra addr_error ; treat as an address error
-
-;
-; Nothing to do in 68000 - all set up once at boot
-;
-program_vectors:
- rts
-
-;
-; TODO
-;
-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:
- move.w d0,-(sp)
-outcharw:
- move.b $00F03010,d0
- btst #1,d0
- beq outcharw
- move.w (sp)+,d0
- move.b d0,$00F03000
- rts
-
-;
-; IDE
-;
-devide_read_data:
- move.l blk_op,a0
- move.b 4(a0),d0
- move.b $00F05000,d1
- cmp.b #2,d0
- bne notswap
- move.b 5(a0),$00F05000
-notswap:
- move.w #255,d0
-devide_read_l:
- move.w $00F01000,(a0)+
- dbra d0,devide_read_l
- move.b d1,$00F05000
- rts
-
-devide_write_data:
- move.l blk_op,a0
- move.b 4(a0),d0
- move.b $00F05000,d1
- cmp.b #2,d0
- bne notswapw
- move.b 5(a0),$00F05000
-notswapw:
- move.w #255,d0
-devide_write_l:
- move.w (a0)+,$00F01000
- dbra d0,devide_write_l
- move.b d1,$00F05000
- 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
+++ /dev/null
-#define IDE_IS_MMIO 1 /* MMIO IDE */
-
-#define IDE_REG_DATA 0x00F01000
-#define IDE_REG_ERROR 0x00F01002
-#define IDE_REG_FEATURES 0x00F01002
-#define IDE_REG_SEC_COUNT 0x00F01004
-#define IDE_REG_LBA_0 0x00F01006
-#define IDE_REG_LBA_1 0x00F01008
-#define IDE_REG_LBA_2 0x00F0100A
-#define IDE_REG_LBA_3 0x00F0100C
-#define IDE_REG_DEVHEAD 0x00F0100C
-#define IDE_REG_STATUS 0x00F0100E
-#define IDE_REG_COMMAND 0x00F0100E
-#define IDE_REG_ALTSTATUS 0x00F01010
-#define IDE_REG_CONTROL 0x00F01010
-
-#define ide_select(x)
-#define ide_deselect()
+++ /dev/null
-export CPU = 68000
+++ /dev/null
-#include "../kernel-68000.def"
-#include "kernel.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
-
- ;
- ; Now switch task context
- ;
- move.l P_TAB__P_UDATA_OFFSET(a0),a5
- move.l a5,udata_shadow
-
- ; Swap support needs to go here once we have the software
- ; MMU stable ?
-
- move.l P_TAB__P_UDATA_OFFSET(a0),a5
- move.l a0,-(sp)
- move.l a0,-(sp)
- jsr pagemap_switch
- addq #4,sp
- move.l (sp)+,a0
-
- move.l P_TAB__P_UDATA_OFFSET(a0),a5
- ; 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)
- move.w P_TAB__P_PAGE_OFFSET(a0),U_DATA__U_PAGE(a5)
-
- ; 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 parent, A5 = u_data pointer of parent.
- ;
-dofork:
- ;
- ; On a flat_mem system the software MMU already cloned the memory
- ; map except that the child is not currently identity mapped. The
- ; parent will return via its copy of the udata, but the child udata
- ; is not mapped at the same address so we must build the child a
- ; fake task switch frame that returns to user space.
- ;
- move.l 4(sp),a0 ; child p_tab
-
- move.l P_TAB__P_UDATA_OFFSET(a0),a1 ; child udata
-
- ;
- ; Copy the parent udata into the child. Only copy the struct data.
- ; Probably not worth saving registers and using movem to speed up.
- ;
-
- movem.l a1/a5,-(sp)
- moveq #U_DATA_COPYSIZE-1,d0
-cplp:
- move.l (a5)+,(a1)+
- dbra d0,cplp
-
- movem.l (sp)+,a1/a5
-
-
- lea.l 512(a1),a0 ; top of child kernel stack
-
- ;
- ; Stack a task switch frame into a1
- ;
-
- move.l 508(a5),-(a0) ; trap frame
- move.l 504(a5),-(a0) ; "" ""
- move.l 500(a5),-(a0) ; A5
- move.l #child_rte,-(a0) ; under the 3 copied words
- movem.l a0/a2-a4/a6/d2-d7,-(a0) ; the faked switchin frame
- move.l a0,U_DATA__U_SP(a1) ; set child frame pointer
-
- ;
- ; Now finish up the process creation
- ;
- move.l a5,-(sp) ; save true udata
- move.l P_TAB__P_UDATA_OFFSET(a1),a5 ; child
- move.l a5,udata_shadow ; paranoia
-
- jsr newproc ; Called with the child udata
-
- move.l U_DATA__U_PTAB(a5),a1 ; reload child pptr
- move.w P_TAB__P_PID_OFFSET(a1),d0 ; pid of child
- ext.l d0
- move.l (sp)+,a5 ; recover parent udata
- move.l a5,udata_shadow ; paranoia
- rts ; return as parent
-
-;
-; This is called with the faked stack frame from dofork. All we have
-; on the stack is the A5 to restore and the fake stack frame. All the
-; other register restores will be done via the fork() syscall code in
-; userspace. The child returns this way not via syscall paths.
-;
-child_rte:
- move.l (sp)+,a5
- moveq #0,d0
- move.l d0,d1
- move.l d1,d2
- move.l d2,d3
- move.l d3,d4
- move.l d4,d5
- move.l d5,d6
- move.l d6,d7
- move.l d7,a0
- move.l a0,a1
- move.l a1,a2
- move.l a2,a3
- move.l a3,a4
- move.l a4,a6
- rte
-
-
-badswitchmsg: ascii "_switchin: FAIL"
- byte 13,10,0
-.even