From 21449fffd229ad10bdd86f19314c47d5c3f140d6 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 20 Jul 2015 22:46:17 +0100 Subject: [PATCH] 68hc11test: initial incomplete compile testing for HC11 --- Kernel/platform-68hc11test/68hc11.h | 5 + Kernel/platform-68hc11test/Makefile | 33 +++++ Kernel/platform-68hc11test/README | 17 +++ Kernel/platform-68hc11test/commonmem.s | 21 ++++ Kernel/platform-68hc11test/config.h | 47 +++++++ Kernel/platform-68hc11test/crt0.s | 53 ++++++++ Kernel/platform-68hc11test/devices.c | 38 ++++++ Kernel/platform-68hc11test/devrd.c | 69 ++++++++++ Kernel/platform-68hc11test/devrd.h | 13 ++ Kernel/platform-68hc11test/devtty.c | 81 ++++++++++++ Kernel/platform-68hc11test/devtty.h | 4 + Kernel/platform-68hc11test/kernel.def | 51 ++++++++ Kernel/platform-68hc11test/libc.c | 25 ++++ Kernel/platform-68hc11test/main.c | 32 +++++ Kernel/platform-68hc11test/p68hc11.s | 149 ++++++++++++++++++++++ Kernel/platform-68hc11test/target.mk | 1 + Kernel/platform-68hc11test/tricks.s | 166 +++++++++++++++++++++++++ 17 files changed, 805 insertions(+) create mode 100644 Kernel/platform-68hc11test/68hc11.h create mode 100644 Kernel/platform-68hc11test/Makefile create mode 100644 Kernel/platform-68hc11test/README create mode 100644 Kernel/platform-68hc11test/commonmem.s create mode 100644 Kernel/platform-68hc11test/config.h create mode 100644 Kernel/platform-68hc11test/crt0.s create mode 100644 Kernel/platform-68hc11test/devices.c create mode 100644 Kernel/platform-68hc11test/devrd.c create mode 100644 Kernel/platform-68hc11test/devrd.h create mode 100644 Kernel/platform-68hc11test/devtty.c create mode 100644 Kernel/platform-68hc11test/devtty.h create mode 100644 Kernel/platform-68hc11test/kernel.def create mode 100644 Kernel/platform-68hc11test/libc.c create mode 100644 Kernel/platform-68hc11test/main.c create mode 100644 Kernel/platform-68hc11test/p68hc11.s create mode 100644 Kernel/platform-68hc11test/target.mk create mode 100644 Kernel/platform-68hc11test/tricks.s diff --git a/Kernel/platform-68hc11test/68hc11.h b/Kernel/platform-68hc11test/68hc11.h new file mode 100644 index 00000000..697ea0e1 --- /dev/null +++ b/Kernel/platform-68hc11test/68hc11.h @@ -0,0 +1,5 @@ +extern volatile uint8_t *baud; +extern volatile uint8_t *sccr1; +extern volatile uint8_t *sccr2; +extern volatile uint8_t *scdr; +extern volatile uint8_t *scsr; diff --git a/Kernel/platform-68hc11test/Makefile b/Kernel/platform-68hc11test/Makefile new file mode 100644 index 00000000..dc3f59cb --- /dev/null +++ b/Kernel/platform-68hc11test/Makefile @@ -0,0 +1,33 @@ + +CSRCS = devtty.c devrd.c +CSRCS += devices.c main.c libc.c + +ASRCS = crt0.s p68hc11.s +ASRCS += tricks.s commonmem.s + +COBJS = $(CSRCS:.c=$(BINEXT)) +AOBJS = $(ASRCS:.s=$(BINEXT)) +OBJS = $(COBJS) $(AOBJS) + +JUNK = $(CSRCS:.c=.o) $(ASRCS:.s=.o) + +all: $(OBJS) + +$(COBJS): %$(BINEXT): %.c + $(CROSS_CC) $(CROSS_CCOPTS) -c $< + +$(AOBJS): %$(BINEXT): %.s + $(CROSS_AS) $(ASOPTS) $< -o $*.o + +clean: + rm -f $(OBJS) $(JUNK) core *~ + +image: + $(CROSS_LD) -o ../fuzix.bin -M >../fuzix.map \ + crt0.o commonmem.o \ + p68hc11.o ../start.o ../version.o ../lowlevel-68hc11.o \ + tricks.o main.o ../timer.o ../kdata.o devrd.o devices.o \ + ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \ + ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o ../bankfixed.o \ + ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o ../syscall_exec16.o \ + ../usermem_std-68hc11.o devtty.o libc.o diff --git a/Kernel/platform-68hc11test/README b/Kernel/platform-68hc11test/README new file mode 100644 index 00000000..439a84b0 --- /dev/null +++ b/Kernel/platform-68hc11test/README @@ -0,0 +1,17 @@ + +68HC811E Development board + +Memory map: +0000-00FF: internal RAM (unbanked) +0100-F7FF: externam RAM (banked) + but with hole +F000-F03F: I/O devices (unbanked) +F800-FFFF: 2K EEPROM (unbanked) + + +8 banks of 64K (minus 2.5K or so per bank unusable) + +Kernel in bank 0, user space in 1-7 + +Serial is the onchip port +SPI drives the SD card diff --git a/Kernel/platform-68hc11test/commonmem.s b/Kernel/platform-68hc11test/commonmem.s new file mode 100644 index 00000000..31962238 --- /dev/null +++ b/Kernel/platform-68hc11test/commonmem.s @@ -0,0 +1,21 @@ +; +; udata is a bit special we have to copy it on a task switch as we've +; got almost no common memory space on the simple board design +; + .file "commonmem" + .mode mshort + + ; exported symbols + .globl _ub + .globl udata + .globl kstack_top + .globl istack_top + .globl istack_switched_sp + + .sect .udata + + .comm udata,512,1 + .comm kstack_top,0,1 + .comm istack_base,254,1 + .comm istack_top,2,1 + .comm istack_switched_sp,2,1 diff --git a/Kernel/platform-68hc11test/config.h b/Kernel/platform-68hc11test/config.h new file mode 100644 index 00000000..e31e215f --- /dev/null +++ b/Kernel/platform-68hc11test/config.h @@ -0,0 +1,47 @@ +/* Enable to make ^Z dump the inode table for debug */ +#undef CONFIG_IDUMP +/* Enable to make ^A drop back into the monitor */ +#undef CONFIG_MONITOR +/* Profil syscall support (not yet complete) */ +#define CONFIG_PROFIL +/* Multiple processes in memory at once */ +#define CONFIG_MULTI +/* Single tasking - for now while we get it booting */ +#undef CONFIG_SINGLETASK +#undef CONFIG_USERMEM_C +/* We use big banks so use the helper */ +#define CONFIG_BANK_FIXED +#define CONFIG_BANKS 7 /* and one for the kernel */ +#define MAX_MAPS 7 +#define MAPBASE 0x200 +#define MAP_SIZE 0xEE00 +/* And swapping */ +#define SWAPDEV 6 /* FIXME */ +#define SWAP_SIZE 0x78 /* Almost a full 64K */ +/* FIXME: udata swap separately */ +#define SWAPBASE 0x0200 /* We swap the lot in one */ +#define SWAPTOP 0xF000 +#define MAX_SWAPS 32 + +/* Serial tty */ +#undef CONFIG_VT + +#define TICKSPERSEC 100 /* Ticks per second */ +#define PROGBASE 0x0200 /* also data base */ +#define PROGLOAD 0x0200 /* also data base */ +#define PROGTOP 0xF000 /* Top of program, base of I/O */ + +#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 7 /* Number of block buffers */ +#define NMOUNTS 2 /* Number of mounts at a time */ + +#define swap_map(x) ((uint8_t *)(x)) diff --git a/Kernel/platform-68hc11test/crt0.s b/Kernel/platform-68hc11test/crt0.s new file mode 100644 index 00000000..58fa1498 --- /dev/null +++ b/Kernel/platform-68hc11test/crt0.s @@ -0,0 +1,53 @@ + ; imported symbols + + .file "crt0.s" + .mode mshort + + .globl fuzix_main + .globl init_early + .globl init_hardware + .globl kstack_top + + ; startup code @0 + .sect .start + jmp start + + .sect .text +start: + sei + lds #kstack_top +; +; FIXME: any set up needed ? +; + + jsr init_early + jsr init_hardware + jsr fuzix_main + sei +stop: bra stop + +; +; Zeropage compiler goo +; + + .globl _.frame + .globl _.tmp + .globl _.d0 + .globl _.d1 + .globl _.d2 + .globl _.d3 + .globl _.d4 + .globl _.d5 + .globl _.xy + .globl _.z + +.equ _.frame,0x40 +.equ _.tmp,0x42 +.equ _.d0,0x44 +.equ _.d1,0x46 +.equ _.d2,0x48 +.equ _.d3,0x4A +.equ _.d4,0x4C +.equ _.d5,0x4E +.equ _.xy,0x50 +.equ _.z,0x52 \ No newline at end of file diff --git a/Kernel/platform-68hc11test/devices.c b/Kernel/platform-68hc11test/devices.c new file mode 100644 index 00000000..df1dcdd8 --- /dev/null +++ b/Kernel/platform-68hc11test/devices.c @@ -0,0 +1,38 @@ +#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 Hard disc block devices (SD card) */ + { rd_open, no_close, rd_read, rd_write, no_ioctl }, + /* 1: /dev/fd Floppy 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 (none) */ + { nxio_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) + 255) + return false; + else + return true; +} +void device_init(void) +{ +} + diff --git a/Kernel/platform-68hc11test/devrd.c b/Kernel/platform-68hc11test/devrd.c new file mode 100644 index 00000000..70f4fc35 --- /dev/null +++ b/Kernel/platform-68hc11test/devrd.c @@ -0,0 +1,69 @@ +/* + * NC100 RD PCMCIA driver + * + */ + +#include +#include +#include +#include + +static int rd_transfer(bool is_read, uint8_t rawflag) +{ + blkno_t block; + int block_xfer; + uint16_t dptr; + int dlen; + int ct = 0; + int map; + + /* FIXME: raw is broken unless nicely aligned */ + if(rawflag) { + dlen = udata.u_count; + dptr = (uint16_t)udata.u_base; + if (((uint16_t)dptr | dlen) & BLKMASK) { + udata.u_error = EIO; + return -1; + } + block = udata.u_offset >> 9; + block_xfer = dlen >> 9; + map = 1; + } else { /* rawflag == 0 */ + dlen = 512; + dptr = (uint16_t)udata.u_buf->bf_data; + block = udata.u_buf->bf_blk; + block_xfer = 1; + map = 0; + } + block += 2*320; /* ramdisc starts at 320K in */ + + while (ct < block_xfer) { +/* rd_memcpy(is_read, map, dptr, block); */ + block++; + ct++; + } + return ct; +} + +int rd_open(uint8_t minor, uint16_t flag) +{ + flag; + if(minor != 0) { + udata.u_error = ENODEV; + return -1; + } + return 0; +} + +int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag;minor; + return rd_transfer(true, rawflag); +} + +int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag;minor; + return rd_transfer(false, rawflag); +} + diff --git a/Kernel/platform-68hc11test/devrd.h b/Kernel/platform-68hc11test/devrd.h new file mode 100644 index 00000000..6320b269 --- /dev/null +++ b/Kernel/platform-68hc11test/devrd.h @@ -0,0 +1,13 @@ +#ifndef __DEVRD_DOT_H__ +#define __DEVRD_DOT_H__ + +/* public interface */ +int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag); +int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag); +int rd_open(uint8_t minor, uint16_t flag); + +/* asm banking helper */ +void rd_memcpy(uint8_t isread, uint8_t map, uint16_t dptr, uint16_t block); + +#endif /* __DEVRD_DOT_H__ */ + diff --git a/Kernel/platform-68hc11test/devtty.c b/Kernel/platform-68hc11test/devtty.c new file mode 100644 index 00000000..eb54dc25 --- /dev/null +++ b/Kernel/platform-68hc11test/devtty.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include +#include +#include +#include <68hc11.h> + +static 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}, +}; + +/* tty1 is the HC11 port B serial */ + +/* 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 = *scsr; + return (c & 0x80) ? TTY_READY_NOW : TTY_READY_SOON; +} + +void tty_putc(uint8_t minor, unsigned char c) +{ + *scdr = c; +} + +void tty_sleeping(uint8_t minor) +{ + used(minor); +} + +/* Assumes 8MHz crystal and SCPR set to 011 */ +void tty_setup(uint8_t minor) +{ + uint8_t b = ttydata[1].termios.c_cflag & CBAUD; + *sccr1 = 0; + *sccr2 = 0x2C; /* rx interrupt, rx/tx enabled */ + if (b < B75) + b = B75; /* Lowest with fixed divider.. we can do 50 + but its much mucking about */ + if (b > B9600) + b = B9600; + /* Only 8N1 */ + ttydata[1].termios.c_cflag &= ~(CBAUD|PARENB); + ttydata[1].termios.c_cflag |= b | CS8; + + b = B9600 - b; + + *baud = b | 0x3; + minor; +} + +/* Carrier etc are done via extra control lines. We don't have any spare! */ +int tty_carrier(uint8_t minor) +{ + minor; + return 1; +} + +void platform_interrupt(void) +{ + uint8_t c = *scsr; + if (c & 0x20) { + /* Character arrived */ + c = *scdr; /* This clears the irq as well */ + tty_inproc(1, c); + } + timer_interrupt(); +} + diff --git a/Kernel/platform-68hc11test/devtty.h b/Kernel/platform-68hc11test/devtty.h new file mode 100644 index 00000000..c387e904 --- /dev/null +++ b/Kernel/platform-68hc11test/devtty.h @@ -0,0 +1,4 @@ +#ifndef __DEVTTY_DOT_H__ +#define __DEVTTY_DOT_H__ + +#endif diff --git a/Kernel/platform-68hc11test/kernel.def b/Kernel/platform-68hc11test/kernel.def new file mode 100644 index 00000000..52867759 --- /dev/null +++ b/Kernel/platform-68hc11test/kernel.def @@ -0,0 +1,51 @@ +; +; Hide the udata above the I/O in the gap before the EEPROM +; +.equ U_DATA , 0xF200 ; (this is struct u_data from kernel.h) +.equ U_DATA__TOTALSIZE , 0x200 ; +.equ IRQ_STACK , 0xF400 +.equ EESTACK , 0xF600 ; used for eeprom stuff + +; +; EEPROM entry points +; +; A = srcbank, B = dstbank +; IX = src, returns value in D +.equ fargetb , 0xF840 +.equ fargetw , 0xF842 +; +; A = srcbank, B = dstbank +; IX = dst, IY = dstval +; +.equ farputb , 0xF844 +.equ farputw , 0xF846 +; +; A = srcbank, B = dstbank +; IX = dst, IY = src +; kernel:_tmp1 = length (in kernel bank) +; +.equ farcopy , 0xF848 +; +; A = bank, IX = function, IY = far stack +; +.equ farcall , 0xF84A +; +; A = bank, IX = function, IY = far stack +; +.equ farjump , 0xF84C +; +; A = bank +; +.equ setbank , 0xF84E +; +; D = 0 +; +.equ reboot , 0xF850 +; +; +; Low memory usage (not banked) +; +.equ tmp1 , 0xFE ; 16bits +.equ curbank , 0xFD +.equ usrbank , 0xFC ; we track this to emulate + ; usermode copy stuff \ No newline at end of file diff --git a/Kernel/platform-68hc11test/libc.c b/Kernel/platform-68hc11test/libc.c new file mode 100644 index 00000000..311e4117 --- /dev/null +++ b/Kernel/platform-68hc11test/libc.c @@ -0,0 +1,25 @@ +#include "cpu.h" + +void *memcpy(void *d, const void *s, size_t sz) +{ + unsigned char *dp, *sp; + 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; +} + diff --git a/Kernel/platform-68hc11test/main.c b/Kernel/platform-68hc11test/main.c new file mode 100644 index 00000000..2baa0c16 --- /dev/null +++ b/Kernel/platform-68hc11test/main.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include + +void platform_idle(void) +{ +} + +void do_beep(void) +{ +} + +/* + * Map handling: We have flexible paging. Each map table consists of a set of pages + * with the last page repeated to fill any holes. + */ + +void pagemap_init(void) +{ + int i; + for (i = 0x01; i < 0x08; i++) + pagemap_add(i); +} + +void map_init(void) +{ +} + + +uint8_t need_resched; diff --git a/Kernel/platform-68hc11test/p68hc11.s b/Kernel/platform-68hc11test/p68hc11.s new file mode 100644 index 00000000..e01800aa --- /dev/null +++ b/Kernel/platform-68hc11test/p68hc11.s @@ -0,0 +1,149 @@ +; +; 68HC11 Simulation Platform +; + + .file "p68hc11" + .mode mshort + + ; exported symbols + .globl init_early + .globl init_hardware + .globl interrupt_handler + .globl program_vectors + .globl map_kernel + .globl map_process + .globl map_process_always + .globl map_save + .globl map_restore + + ; exported debugging tools + .globl trap_monitor + .globl trap_reboot + + include "kernel.def" + include "../kernel-hc11.def" + +; +; TODO: hardware registers +; + + .globl baud +.equ baud,0xf000 + .globl sccr1 +.equ sccr1,0xf000 + .globl sccr2 +.equ sccr2,0xf000 + .globl scdr +.equ scdr,0xf000 + .globl scsr +.equ scsr,0xf000 + + .sect .data + +trapmsg: + .ascii "Trapdoor: SP=" + .byte 0 +trapmsg2: + .ascii ", PC=" + .byte 0 +tm_user_sp: + .word 0 + +savedbank: + .word 0 + + .sect .text +trap_monitor: + sei + bra trap_monitor + +trap_reboot: + jmp reboot + +init_early: + rts + +init_hardware: + ; set system RAM size + ldd #512 + std ramsize + ldd #512-64 + std procmem + + ; Our vectors are in high memory unlike Z80 but we still + ; need vectors + clra + clrb ; pass NULL + jsr program_vectors + rts + + +program_vectors: +; +; FIXME: figure out how this will interact with eeprom (eeprom should +; bank switch then call into some secondary vector) +; + rts ; rti will be in eeprom + +; +; Memory is fully banked, with no real common. We simply track the +; "correct" user bank for use by the copiers. +; +map_process_always: + psha + ldaa U_DATA__U_PAGE + staa usrbank + pula + rts + +map_kernel: + clr usrbank + rts + +map_restore: + psha + ldaa savedbank + pula + rts +map_save: + psha + ldaa curbank + staa savedbank + pula + rts + +map_process: + xgdx + ldaa P_TAB__P_PAGE_OFFSET,x + staa usrbank + xgdx + rts + +; +; Bank handling +; + .globl doexec + .globl sigdispatch + .globl _ugetc + .globl _ugetw + .globl _ugets + .globl _uget + .globl _uputc + .globl _uputw + .globl _uputs + .globl _uput + .globl _uzero + + +doexec: +sigdispatch: +_ugetc: +_ugetw: +_ugets: +_uget: +_uputc: +_uputw: +_uput: +_uzero: + /* FIXME */ + rts diff --git a/Kernel/platform-68hc11test/target.mk b/Kernel/platform-68hc11test/target.mk new file mode 100644 index 00000000..5858abdd --- /dev/null +++ b/Kernel/platform-68hc11test/target.mk @@ -0,0 +1 @@ +export CPU = 68hc11 diff --git a/Kernel/platform-68hc11test/tricks.s b/Kernel/platform-68hc11test/tricks.s new file mode 100644 index 00000000..122705f8 --- /dev/null +++ b/Kernel/platform-68hc11test/tricks.s @@ -0,0 +1,166 @@ +; +; 68HC11 fully banked (so no real 'common') +; + .file "tricks" + .mode mshort + + .globl newproc + .globl chksigs + .globl getproc + .globl trap_monitor + .globl inint + .globl switchout + .globl switchin + .globl dofork + .globl ramtop + + include "kernel.def" + include "../kernel-hc11.def" + + .sect .data + +; ramtop must be in common for single process swapping cases +; and its a constant for the others from before init forks so it'll be fine +; here + +ramtop: + .word 0 + + .sect .code + +; 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(). +; +; FIXME: make sure we optimise the switch to self case higher up the stack! +; +; This function can have no arguments or auto variables. +switchout: + sei + jsr chksigs + + ; save machine state + ldx #0 ; 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: + pshx + sts U_DATA__U_SP + + ; set inint to false + clr inint + + ; find another process to run (may select this one again) returns it + ; in X + jsr getproc + jsr switchin + ; we should never get here + jsr trap_monitor + +badswitchmsg: .ascii "switchin: FAIL" + .byte 13 + .byte 10 + .byte 0 + +; new process pointer is in D +switchin: + sei + + xgdx + + ; + ; FIXME: implement dragon-nx uarea copy logic for HC11 via + ; eeprom copy helpers + ; + + ; ------- No stack ------- + ; check u_data->u_ptab matches what we wanted + cmpx U_DATA__U_PTAB + bne switchinfail + + ; wants optimising up a bit + ldaa #P_RUNNING + staa P_TAB__P_STATUS_OFFSET,x + + clr runticks + + ; restore machine state -- note we may be returning from either + ; _switchout or _dofork + lds U_DATA__U_SP + + + ; enable interrupts, if the ISR isn't already running + ldaa inint + beq swtchdone ; in ISR, leave interrupts off + cli +swtchdone: + pulx ; return code + xgdx + rts + +switchinfail: + jsr outx + ldx #badswitchmsg + jsr outstring + ; something went wrong and we didn't switch in what we asked for + jmp trap_monitor + +fork_proc_ptr: .word 0 ; (C type is struct p_tab *) -- address of child process p_tab entry + +; +; Called from _fork. We are in a syscall, the uarea is live as the +; parent uarea. The kernel is the mapped object. +; +dofork: + sei + ; new process is in D, get parent pid into d and process into x + + xgdx + + stx fork_proc_ptr + ldd P_TAB__P_PID_OFFSET,x + + ; Save the stack pointer and critical registers. + ; When this process (the parent) is switched back in, it will be as if + ; it returns with the value of the child's pid. + xgdx + pshx ; x has p->p_pid from above, the return value in the parent + + ; save kernel stack pointer -- when it comes back in the parent we'll be in + ; _switchin which will immediately return (appearing to be _dofork() + ; returning) and with HL (ie return code) containing the child PID. + ; Hurray. + sts U_DATA__U_SP + + ; now we're in a safe state for _switchin to return in the parent + ; process. + + ; --------- we switch stack copies in this call ----------- + ; d is the process pointer + jsr fork_copy + + ; We are now in the kernel child context + + ; now the copy operation is complete we can get rid of the stuff + ; _switchin will be expecting from our copy of the stack. + pulx + + ldd fork_proc_ptr + jsr newproc + + ; any calls to map process will now map the childs memory + + ; runticks = 0; + clr runticks + ; in the child process, fork() returns zero. + ; + ; And we exit, with the kernel mapped, the child now being deemed + ; to be the live uarea. The parent is frozen in time and space as + ; if it had done a switchout(). + rts + +fork_copy: + ; FIXME + rts ; this stack is copied so safe to return on + + -- 2.34.1