From 391b6a37b1fea4a22368551e48f0521f33b82df1 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 23 Jan 2019 19:21:59 +0000 Subject: [PATCH] v68: resync with moves of code to core --- Kernel/platform-v68/Makefile | 10 +- Kernel/platform-v68/README | 8 +- Kernel/platform-v68/main.c | 233 ----------------------------------- Kernel/platform-v68/p68000.S | 53 +------- 4 files changed, 10 insertions(+), 294 deletions(-) diff --git a/Kernel/platform-v68/Makefile b/Kernel/platform-v68/Makefile index a71ca314..b764a205 100644 --- a/Kernel/platform-v68/Makefile +++ b/Kernel/platform-v68/Makefile @@ -8,9 +8,12 @@ ASRCS += tricks.S DSRCS = ../dev/devide.c ../dev/mbr.c ../dev/blkdev.c ../dev/devide_discard.c DOBJS = $(patsubst ../dev/%.c,%.o, $(DSRCS)) +LSRCS = ../lib/68000exception.c +LOBJS = $(patsubst ../lib/%.c,%.o, $(LSRCS)) + COBJS = $(CSRCS:.c=$(BINEXT)) AOBJS = $(ASRCS:.S=.o) -OBJS = $(COBJS) $(AOBJS) $(DOBJS) +OBJS = $(COBJS) $(AOBJS) $(DOBJS) $(LOBJS) CROSS_CCOPTS += -I../dev/ @@ -27,6 +30,9 @@ $(AOBJS): %.o: %.S $(DOBJS): %.o: ../dev/%.c $(CROSS_CC) $(CROSS_CCOPTS) -c $< +$(LOBJS): %.o: ../lib/%.c + $(CROSS_CC) $(CROSS_CCOPTS) -c $< + clean: rm -f $(OBJS) $(JUNK) core *~ @@ -37,7 +43,7 @@ image: 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 \ + ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o 68000exception.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 diff --git a/Kernel/platform-v68/README b/Kernel/platform-v68/README index 10627923..309958e5 100644 --- a/Kernel/platform-v68/README +++ b/Kernel/platform-v68/README @@ -18,17 +18,11 @@ to start user space straight after the kernel or if need be just above the protection boundary. TODO: -- bourne shell crashes on exit with MMU enforcement with an access to 0. This - appears to be a bug in the v7 version of sh in 32bit. It would make more - sense to use the heritage sh which is sys5 ish and a bit bigger. -- signal handling needs further testing (disabled on IRQ path currently) -- copy exception/trap frames onto user stack along with trap identifiers - so we can support stuff like CP/M 68K and TOS emulators. -- pre-emption needs more testing (also disabled on IRQ path currently) - support multiple IRQ sources and IRQ priority nesting when appropriate - enable IRQ during swap on context switch - optimize swap out/in. With bigger amounts of RAM we want to be smarter where it doesn't matter on 8bit. +- parent first mode Possible optimizations: diff --git a/Kernel/platform-v68/main.c b/Kernel/platform-v68/main.c index b1ac02cd..7dc895fb 100644 --- a/Kernel/platform-v68/main.c +++ b/Kernel/platform-v68/main.c @@ -60,8 +60,6 @@ arg_t _memfree(void) 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[]; @@ -69,234 +67,3 @@ void install_vdso(void) memcpy((void *)udata.u_codebase, &vdso, 0x40); } -extern void *get_usp(void); -extern void set_usp(void *p); - -/* We do as much exception processing in software as we can. This code - is called from the asm trap hooks on the supervisor stack and expected - to sort the mess out */ - -/* The stackframe we work with looks like this when exception is called */ - -struct trapdata { - /* MOVEM.L with predecrement stores A7 to A0 then D7 to D0. In other - words viewed in memory order it is D0-D7 then A0-A7 (A6 for us - as we don't store A7) */ - uint32_t d[8]; - uint32_t a[7]; - uint16_t trap; /* Pushed second */ - uint16_t sr; /* Condition codes */ - /* The CPU pushed the frame which sits above the MOVEM */ - uint16_t exception[0]; /* CPU exception frame */ -}; - -#define FRAME_A 1 -#define FRAME_B 2 - -static void explode(struct trapdata *framedata, int type) -{ - uint16_t *excp = framedata->exception; - uint32_t *fv; - unsigned int i = framedata->trap; - unsigned int j; - - if (i > 12) - i = 12; - - for (j = 0; j < i; j++) - kputs(" '* "); - kputchar('\n'); - for (j = 0; j < i; j++) - kputs(" | "); - kputchar('\n'); - for (j = 0; j < i; j++) - kputs(".###. "); - kputchar('\n'); - for (j = 0; j < i; j++) - kputs("##### "); - kputchar('\n'); - for (j = 0; j < i; j++) - kputs("##### "); - kputchar('\n'); - for (j = 0; j < i; j++) - kputs("`###' "); - kputchar('\n'); - - kprintf("Trap: %d\n", framedata->trap); - kprintf("Register Dump\nA: "); - for (i = 0; i < 7; i++) - kprintf("%p ", framedata->a[i]); - kprintf("%p\nD: ", get_usp()); - for (i = 0; i < 8; i++) - kprintf("%p ", framedata->d[i]); - kprintf("\nSR: %x\n", framedata->sr); - - kprintf("Exception frame:\n"); - for (j = 0;j < 16; j++) - kprintf("%d: %x\n", j, excp[j]); - - /* For now we only do 68000 */ - if (type == FRAME_A) { - kputs((excp[0] & 0x10)?"R":"W"); - kprintf(" FC %x", excp[0] & 7); - fv = (uint32_t *)(excp + 1); - kprintf(" Addr %p IR %x ", *fv, excp[3]); - excp += 4; - } - if (type == FRAME_A || type == FRAME_B) { - fv = (uint32_t *)(excp + 1); - kprintf("PC %p SR %x\n", *fv, *excp); - } -} - -/* Our caller did a movem of the registers to kstack then pushed an - exception and other info. This all sits on the kstack but pass - a pointer to it for flexibility. - - On return it will pull the state back and rte. We can thus adjust - what happens according to need. - - To keep common code we push the same frame for all cases */ - -static uint8_t pushw(uint16_t **usp, uint16_t v) -{ - (*usp)--; - return uputw(v, *usp); -} - -static uint8_t pushl(uint16_t **usp, uint32_t v) -{ - (*usp) -= 2; - return uputl(v, *usp); -} - -extern uint8_t kernel_flag; - -int exception(struct trapdata *framedata) -{ - ptptr proc; - unsigned int frame, fsize; - uint8_t trap = framedata->trap; - unsigned int sig = 0; - uint16_t m; - uint16_t *sp = (uint16_t *)framedata; - uint16_t *usp = get_usp(); - uint16_t *unwind, *context; - uint8_t err = 0; - int i; - - /* We translate debug to SIGIOT and A and F line to SIGILL - We will need to fix up 68000 v 68010 move to/from SR */ - static const uint8_t trap_to_sig[] = { - 0, 0, SIGSEGV, SIGBUS, SIGILL, SIGFPE, - SIGABRT/*CHK*/, SIGTRAP/*TRAPV */, - SIGILL, SIGIOT, SIGILL, SIGFPE }; - - proc = udata.u_ptab; - - /* Most synchronous exceptions are type B */ - /* FIXME: sizes need to become chip aware */ - frame = FRAME_B; - fsize = 3; /* Three words on 68000 */ - /* TODO: On the 68010 there are at least 4 words as word 4 always holds - the vector and format */ - if (trap == 0) { - sig = udata.u_cursig; - udata.u_cursig = 0; - } else if (trap < 12) { - if (trap < 4) { - /* TODO: On a 68010 this frame is 29 words and the event is - restartable (although not always usefully). We need to - decide whether to set the restart flag case by case */ - frame = FRAME_A; - fsize = 7; - } - sig = trap_to_sig[trap]; - } else if (trap >= 32 && trap < 48) - sig = SIGTRAP; - /* This processing only applies to synchronous hardware exceptions */ - if (trap) { - /* Went boom in kernel space or without a user recovery */ - if (kernel_flag || sig == 0) { - explode(framedata, frame); - panic("trap"); - } - - /* Cheating here .. all our exceptions are low 16 signal */ - m = 1 << sig; - /* - * The caller is ignoring our signal. In some cases this is fine - * but in others it's less clear (eg division by zero) and we - * may need to take different action. - */ - if (proc->p_sig[0].s_ignored & m) - return 0; - /* Weird case - we took a sync signal and the caller wants us to - report it later. */ - if (proc->p_sig[0].s_held & m) { - /* TODO: if it's not meaningfully restartable we should - probably treat this as a kill */ - ssig(proc, sig); - return 0; - } - recalc_cursig(); /* Put any async signal back */ - } - if (udata.u_sigvec[sig] == SIG_DFL) { - /* Default action for our signal ? */ - doexit(dump_core(sig)); - /* This will never return. We will go schedule new work */ - panic("exret"); - } - /* build signal frame - - Our unwinder code does - move.l 8(sp),sp - movem.l a0-a1/d0-d1,(sp)+ - move.w (sp)+,ccr - rts */ - - /* Push the recovery PC */ - - /* Now update the user stack */ - err |= pushw(&usp, sp[31 + fsize]); - err |= pushw(&usp, sp[30 + fsize]); - - /* Patch the kernel exception frame */ - *(uint32_t *)(&sp[30 + fsize]) = (uint32_t)udata.u_sigvec[sig]; - - /* FIXME: when we do ptrace we will need to support adding the T - flag back here as the exception cleared it */ - err |= pushw(&usp, framedata->sr); - /* Push A1 A0 D1 D0 to match MOVEM.L */ - err |= pushl(&usp, framedata->a[1]); - err |= pushl(&usp, framedata->a[0]); - err |= pushl(&usp, framedata->d[1]); - err |= pushl(&usp, framedata->d[0]); - - /* Remember the target for undoing the frame */ - unwind = usp; - - /* Copy in the signal context itself. 30 words of registers, 2 of - trap code and then the hardware exception */ - for (i = 0; i < 30 + 2 + fsize; i++) - err |= pushw(&usp, *sp++); - context = usp; - err |= pushl(&usp, (uint32_t)unwind); - /* Signal context is a secret extra non portable argument */ - err |= pushl(&usp, (uint32_t)context); - /* We end it with the call frame as seen from the signal handler, a - single argument and a return address */ - err |= pushl(&usp, sig); - err |= pushl(&usp, udata.u_codebase + 0x04); - - set_usp(usp); - - if (err) { - doexit(dump_core(SIGSTKFLT)); - panic("exret2"); - } - /* Once built clear the restart state */ - udata.u_sigvec[sig] = SIG_DFL; - /* Return, RTE and end up on the signal frame */ - return 1; -} diff --git a/Kernel/platform-v68/p68000.S b/Kernel/platform-v68/p68000.S index d0f81f67..4f4d861e 100644 --- a/Kernel/platform-v68/p68000.S +++ b/Kernel/platform-v68/p68000.S @@ -13,7 +13,6 @@ .globl udata_block .globl devide_read_data .globl devide_write_data - .globl vdso .mri 1 platform_reboot: platform_monitor: @@ -35,47 +34,9 @@ init_hardware: 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 + bsr install_vectors -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.l #trap0,(a0)+ - move.l #trap1,(a0)+ - move.l #trap2,(a0)+ - move.l #trap3,(a0)+ - move.l #trap4,(a0)+ - move.l #trap5,(a0)+ - move.l #trap6,(a0)+ - move.l #trap7,(a0)+ - move.l #trap8,(a0)+ - move.l #trap9,(a0)+ - move.l #trap10,(a0)+ - move.l #trap11,(a0)+ - move.l #trap12,(a0)+ - move.l #trap13,(a0)+ - 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) @@ -185,15 +146,3 @@ devide_write_l: dbra d0,devide_write_l rts -; -; 'VDSO' -; -vdso: trap #12 ; syscall entry - rts - ; signal unwind - move.l 8(sp),sp ; blow away stack frame - movem.l (sp)+,a0/a1/d0/d1 - move.w (sp)+,ccr - rts - ; rest is spare for now - -- 2.34.1