From: Brett Gordon Date: Fri, 26 Jun 2015 06:35:27 +0000 (-0400) Subject: Fuzix: platform-coco3: no more stashing, progtop = 0xe000 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=6528aaf0f25e9093f83c87e19c0941b4829608fb;p=FUZIX.git Fuzix: platform-coco3: no more stashing, progtop = 0xe000 I fixed up the coco3 platform's udata/progtop/banking: * no more udata/stack stashing on switch-in/switch-out * Progtop now set at 0xe000, the last 8k mmu bank (could go higher) -- Brett M. Gordon, beretta42@gmail.com --- diff --git a/Kernel/platform-coco3/README b/Kernel/platform-coco3/README index f896405c..3c49fae6 100644 --- a/Kernel/platform-coco3/README +++ b/Kernel/platform-coco3/README @@ -105,6 +105,13 @@ cd Standalone/filesystem-src +************************* +DONE +************************* + +* Fix the underlying Banking layout to better handle UDATA + + ************************* TO DO ************************* @@ -114,9 +121,11 @@ upgrade is required. * IDE Drivers. -* Better and more DriveWire Virtual Serial Ports. +* SDC Drivers. -* Fix the underlying Banking layout to better handle UDATA +* SCSI Drivers. + +* Better and more DriveWire Virtual Serial Ports. * Better support of the GIME chip's video modes diff --git a/Kernel/platform-coco3/build b/Kernel/platform-coco3/build index da805f2b..1e4ad3a8 100755 --- a/Kernel/platform-coco3/build +++ b/Kernel/platform-coco3/build @@ -14,6 +14,10 @@ make TARGET=coco3 cd platform-coco3 rm fuzix.dsk ; make fuzix.dsk +if [ $1 = "kernel" ]; then + exit +fi + # make Libs cd ../../Library diff --git a/Kernel/platform-coco3/coco3.s b/Kernel/platform-coco3/coco3.s index 796bece7..a608d9eb 100644 --- a/Kernel/platform-coco3/coco3.s +++ b/Kernel/platform-coco3/coco3.s @@ -42,8 +42,14 @@ ; ----------------------------------------------------------------------------- .area .common + +saved_map + .db 0 ; which mapping state where we in? +init1_mirror + .db 0 ; a *mirror* of gimme $ff91, which is WriteOnly +_need_resched + .db 0 ; scheduler flag -tm_user_sp: .dw 0 _trap_monitor: orcc #0x10 @@ -65,8 +71,10 @@ loop@ lda ,u+ ;; low memory on reboot to bounce to the reset ;; vector. bounce@ - lda #0x84 ; reset GIME (map in roms) + lda #0x06 ; reset GIME (map in internal 32k rom) sta 0xff90 + clr 0xff91 + clr 0x72 jmp [0xfffe] ; jmp to reset vector bounce_end@ @@ -118,6 +126,13 @@ init_hardware: std _ramsize ldd #512-64 std _procmem + ;; set initial user mmu + ldd #8 + ldx #$ffa0 +b@ sta ,x+ + inca + decb + bne b@ ;; set temporary screen up ldb #%01000100 ; coco3 mode stb $ff90 @@ -165,19 +180,27 @@ a@ sta ,x+ .area .common -;;; Setup interrupt vectors in the cpu map state -;;; CoCo3's vectors are in common, so this doesn't need to do anything -;;; takes: nothing +;;; Platform specific userspace setup +;;; We're going to borrow this to copy the common bank +;;; into the userspace too. +;;; takes: X = page table pointer ;;; returns: nothing _program_vectors: - jsr map_process - ldb #0x7E - stb 0 - jsr map_kernel - rts - -;;; This clear the interrupt source before calling the -;; normal handler + ;; copy the common section into user-space + lda 0xffa8 ; save mmu reg on stack + pshs a,x,u + + ;; setup the null pointer / sentinal bytes in low process memory + lda [1,s] ; get process's blk address for address 0 + sta 0xffa8 ; put in our mmu ( at address 0 ) + lda #0x7E + sta 0 + puls a,x,u ; restore mmu reg + sta 0xffa8 ; + rts ; return + +;;; This clear the interrupt source before calling the +;;; normal handler ;;; takes: nothing ( it is an interrupt handler) ;;; returns: nothing ( it is an interrupt handler ) my_interrupt_handler @@ -232,14 +255,11 @@ map_process_2: pshs x,y,a ldy #0xffa0 ; MMU user map. We can fiddle with - ;; map in the common block lda ,x+ ; get byte from page table sta ,y+ ; put it in mmu inca ; increment to get next 8k block sta ,y+ ; put it in mmu - ;; map the rest of the block in order -* ldy #0xffa0 ; lda ,x+ sta ,y+ inca @@ -250,12 +270,10 @@ map_process_2: inca sta ,y+ -* lda ,x+ - lda #6 - sta ,y+ - inca + lda ,x+ ; bank all but common memory sta ,y + lda #0 sta 0xff91 ; new mapping goes live here sta init1_mirror ; and save INIT1 setting in mirror @@ -285,11 +303,6 @@ map_save: sta saved_map puls a,pc -saved_map: .db 0 ; which mapping state where we in? -init1_mirror: - .db 0 ; a *mirror* of gimme $ff91, which is WriteOnly -_need_resched .db 0 ; scheduler flag - ;;; Print a character to debugging ;;; takes: A = character @@ -303,3 +316,6 @@ outchar: .area .data scrPos .dw 0xb400 ; debugging screen buffer position + + + diff --git a/Kernel/platform-coco3/commonmem.s b/Kernel/platform-coco3/commonmem.s index 13050769..c4aed57d 100644 --- a/Kernel/platform-coco3/commonmem.s +++ b/Kernel/platform-coco3/commonmem.s @@ -11,7 +11,8 @@ .globl kstack_top .globl istack_top .globl istack_switched_sp - + .globl kcommon_start + .area .udata ;;; first 512 bytes: starts with struct u_block, @@ -27,3 +28,7 @@ istack_base: zmb 254 istack_top: istack_switched_sp: .dw 0 + +;;; This helps _program_vectors know where the kernel common code starts +;;; for copying into userspace. +kcommon_start \ No newline at end of file diff --git a/Kernel/platform-coco3/config.h b/Kernel/platform-coco3/config.h index a39f285f..bca552c9 100644 --- a/Kernel/platform-coco3/config.h +++ b/Kernel/platform-coco3/config.h @@ -51,7 +51,7 @@ extern unsigned char vt_map( unsigned char c ); #define TICKSPERSEC 60 /* Ticks per second */ #define PROGBASE 0x0100 /* also data base */ -#define PROGTOP 0xbd00 /* Top of program, base of U_DATA */ +#define PROGTOP 0xe000 /* Top of program, base of U_DATA */ #define PROGLOAD 0x0100 /* ??? */ #define BOOT_TTY (512 + 1) /* Set this to default device for stdio, stderr */ diff --git a/Kernel/platform-coco3/fuzix.link b/Kernel/platform-coco3/fuzix.link index bbe18249..6b9f5d28 100644 --- a/Kernel/platform-coco3/fuzix.link +++ b/Kernel/platform-coco3/fuzix.link @@ -5,10 +5,11 @@ section .text2 section .text section .text.hot section .test.unlikely -section .discard section .data section .bss +section .discard section .video load 0xa880 -section .udata load 0xc000 +section .udata load 0xe000 section .common +section .cpage load 0xfe00 entry start diff --git a/Kernel/platform-coco3/kernel.def b/Kernel/platform-coco3/kernel.def index 25ec3981..b5b150f1 100644 --- a/Kernel/platform-coco3/kernel.def +++ b/Kernel/platform-coco3/kernel.def @@ -1,10 +1,8 @@ ;;; UZI mnemonics for memory addresses etc -U_DATA equ 0xc000 ; (this is struct u_data from kernel.h) +U_DATA equ 0xe000 ; (this is struct u_data from kernel.h) U_DATA__TOTALSIZE equ 0x200 ; 256+256 bytes. -U_DATA_STASH equ 0xBd00 ; FC00-FEFF - ;;; We don't need these macros for we have no ;;; SAM shenanigans on a CoCo3 diff --git a/Kernel/platform-coco3/main.c b/Kernel/platform-coco3/main.c index fbe7d59d..577b1906 100644 --- a/Kernel/platform-coco3/main.c +++ b/Kernel/platform-coco3/main.c @@ -27,7 +27,7 @@ void pagemap_init(void) for (i = 8; i < 64; i+=2) pagemap_add(i); /* add common page last so init gets it */ - /* pagemap_add(6); */ + pagemap_add(6); } void map_init(void) diff --git a/Kernel/platform-coco3/tricks.s b/Kernel/platform-coco3/tricks.s index d3d72ed4..5f8edef4 100644 --- a/Kernel/platform-coco3/tricks.s +++ b/Kernel/platform-coco3/tricks.s @@ -25,7 +25,12 @@ _ramtop: .dw 0 +_swapstack + .dw 0 + .dw 0 +fork_proc_ptr: + .dw 0 ; (C type is struct p_tab *) -- address of child process p_tab entry .area .common @@ -49,27 +54,11 @@ _switchout: pshs d,y,u sts U_DATA__U_SP ; save SP - - ;; Stash the uarea into process memory bank - jsr map_process_always - ldx #U_DATA - ldy #U_DATA_STASH -stash ldd ,x++ - std ,y++ - cmpx #U_DATA+U_DATA__TOTALSIZE - bne stash - jsr map_kernel - - jsr _getproc ; X = next process ptr jsr _switchin ; and switch it in ; we should never get here jsr _trap_monitor -_swapstack - .dw 0 - .dw 0 - badswitchmsg: .ascii "_switchin: FAIL" @@ -83,52 +72,24 @@ badswitchmsg: _switchin: orcc #0x10 ; irq off - ;pshs x - stx _swapstack - - leax P_TAB__P_PAGE_OFFSET,x ; get address of page table - - - cmpx U_DATA__U_PAGE ; switching in ourselfs? - beq nostash ; yes then don't save UDATA - - jsr map_process ; map new process into memory + stx _swapstack ; save passed page table * - ; fetch uarea from process memory - sty _swapstack+2 - ldx #U_DATA_STASH - ldy #U_DATA -stashb ldd ,x++ - std ,y++ - cmpx #U_DATA_STASH+U_DATA__TOTALSIZE - bne stashb - - ; we have now new stacks so get new stack pointer before any jsr - lds U_DATA__U_SP - - ; get back kernel page so that we see process table - jsr map_kernel + ;; flip in the newly choosen task's common page + lda P_TAB__P_PAGE_OFFSET+3,x + inca + sta 0xffa7 + sta 0xffaf + + ;; --------- No Stack ! -------------- -nostash: - ;puls x - ldx _swapstack ; check u_data->u_ptab matches what we wanted + ldx _swapstack cmpx U_DATA__U_PTAB bne switchinfail lda #P_RUNNING sta P_TAB__P_STATUS_OFFSET,x - ;; fix-up page mappings (voodoo code?) - lda P_TAB__P_PAGE_OFFSET,x - sta U_DATA__U_PAGE - lda P_TAB__P_PAGE_OFFSET+1,x - sta U_DATA__U_PAGE+1 - lda P_TAB__P_PAGE_OFFSET+2,x - sta U_DATA__U_PAGE+2 - lda P_TAB__P_PAGE_OFFSET+3,x - sta U_DATA__U_PAGE+3 - ;; clear the 16 bit tick counter ldx #0 stx _runticks @@ -152,8 +113,6 @@ switchinfail: ;; something went wrong and we didn't switch in what we asked for jmp _trap_monitor -fork_proc_ptr: - .dw 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 @@ -211,35 +170,50 @@ _dofork: ;;; copy the process memory to the new process ;;; and stash parent uarea to old bank fork_copy: - ldx fork_proc_ptr - ldb P_TAB__P_PAGE_OFFSET,x ; new bank - lda U_DATA__U_PAGE ; old bank - jsr copybank - ldb P_TAB__P_PAGE_OFFSET+1,x ; new bank - lda U_DATA__U_PAGE+1 ; old bank - jsr copybank - ldb P_TAB__P_PAGE_OFFSET+2,x ; new bank - lda U_DATA__U_PAGE+2 ; old bank - jsr copybank - ;; stash parent urea (including kernel stack) - jsr map_process_always - ldx #U_DATA - ldu #U_DATA_STASH -stashf ldd ,x++ - std ,u++ - cmpx #U_DATA+U_DATA__TOTALSIZE - bne stashf - jsr map_kernel + ;; calculate how many regular pages we need to copy + ldd U_DATA__U_TOP ; get size of process + tfr d,y ; make copy of progtop + anda #$3f ; mask off remainder + pshs cc ; push onto stack ( remcc ) + tfr y,d ; get copy of progtop + rola ; make low bits = whole pages + rola ; + rola ; + anda #$3 ; bottom two bits are now whole pages + puls cc ; get remainder's cc ( ) + beq skip@ ; skip round-up if zero + inca ; round up + cmpa #4 ; is 4th bank copied? + pshs cc,a ; and put on stack ( 4th? no ) + ;; copy parent's whole pages to child's +skip@ ldx fork_proc_ptr + leax P_TAB__P_PAGE_OFFSET,x ; X = * new process page tables (dest) + ldu #U_DATA__U_PAGE ; parent process page tables (src) +loop@ ldb ,x+ ; B = child's next page + lda ,u+ ; A = parent's next page + jsr copybank ; copy bank + dec 1,s ; bump counter + bne loop@ + ;; copy UDATA + common (if needed) + ldx fork_proc_ptr ; X = new process ptr + ldb P_TAB__P_PAGE_OFFSET+3,x ; B = child's UDATA/common page + puls cc,a ; pull 4th? condition codes + beq skip2@ ; 4th bank already copied? + lda U_DATA__U_PAGE+3 ; A = parent's UDATA/common page + jsr copybank ; copy it + ;; remap common page in MMU to new process +skip2@ incb + stb 0xffaf + stb 0xffa7 ; --- we are now on the stack copy, parent stack is locked away --- rts ; this stack is copied so safe to return on ;;; Copy data from one bank to another ;;; takes: B = dest bank, A = src bank -;;; modifies: U copybank - pshs d,x - ;; copy first block in bank - ldd 0xffa8 ; save mmu state + pshs d,x,u + ;; save mmu state + ldd 0xffa8 pshs d ldd 0xffaa pshs d @@ -251,9 +225,10 @@ copybank sta 0xffaa inca sta 0xffab - ;; copy - ldx #0 - ldu #0x4000 + ;; loop setup + ldx #0 ; dest address + ldu #0x4000 ; src address + ;; unrolled: 16 bytes at a time a@ ldd ,u++ std ,x++ ldd ,u++ @@ -262,12 +237,20 @@ a@ ldd ,u++ std ,x++ ldd ,u++ std ,x++ - cmpx #0x4000 - bne a@ + ldd ,u++ + std ,x++ + ldd ,u++ + std ,x++ + ldd ,u++ + std ,x++ + ldd ,u++ + std ,x++ + cmpx #0x4000 ; end of copy? + bne a@ ; no repeat ;; restore mmu puls d std 0xffaa puls d std 0xffa8 ;; return - puls d,x,pc ; return + puls d,x,u,pc ; return