65c816: Fixes for non bank 0
authorAlan Cox <alan@linux.intel.com>
Tue, 2 Jan 2018 21:03:23 +0000 (21:03 +0000)
committerAlan Cox <alan@linux.intel.com>
Tue, 2 Jan 2018 21:03:23 +0000 (21:03 +0000)
With this fixed the large mode seems to work (not heavily tested) and
an 8MB boot works to a shell prompt and some test commands at least.

Kernel/lib/65c816.s
Kernel/platform-v65c816-big/README
Kernel/platform-v65c816-big/commonmem.s
Kernel/platform-v65c816-big/config.h
Kernel/platform-v65c816-big/kernel.def
Kernel/platform-v65c816/README

index e11d394..4f12020 100644 (file)
@@ -21,6 +21,7 @@
        .import _runticks
        .import outcharhex
        .import outstring
+       .import kstack_base
 
 
        .code
@@ -80,6 +81,9 @@ slow_path:
        .a8
        lda     U_DATA__U_PAGE
        sta     f:KERNEL_CODE_FAR+switch_patch_1+1              ; target bank of save
+.if ( KERNEL_BANK )
+       sta     f:KERNEL_CODE_FAR+switch_patch_2+1              ; target bank of save
+.endif
        rep     #$30
        .i16
        .a16
@@ -89,6 +93,20 @@ slow_path:
        phb
 switch_patch_1:
        mvn     0,KERNEL_BANK           ; save stack and udata
+
+.if ( KERNEL_BANK )
+       ;
+       ;       Big (non bank 0) kernels by necessity split off the
+       ;       kstack into bank 0.
+       ;
+       ;       FIXME: some day split the user ZP to be half ZP half Kstack
+       ;
+       lda     #$FF
+       ldx     #kstack_base
+switch_patch_2:
+       mvn     0,0
+
+.endif
        plb
        sep #$30
        stz     _inint
@@ -115,7 +133,10 @@ _switchin:
        ; If this is zero we need swapping so the swapper checks go here
        ; FIXME
 
-       sta     f:KERNEL_CODE_FAR+switch_patch_2+2      ; source bank of retrieve
+       sta     f:KERNEL_CODE_FAR+switch_patch_3+2      ; source bank of retrieve
+.if ( KERNEL_BANK )
+       sta     f:KERNEL_CODE_FAR+switch_patch_4+2      ; source bank of retrieve
+.endif
        rep     #$30
        .i16
        .a16
@@ -125,19 +146,41 @@ _switchin:
        ldx     #U_DATA_STASH
        ldy     #U_DATA
        lda     #U_DATA__TOTALSIZE-1
-switch_patch_2:
+switch_patch_3:
        mvn     KERNEL_BANK,0
-       ;       after the MVN our data bank is KERNEL_DATA
+
+.if ( KERNEL_BANK )
+       ;
+       ;       Big kernel - recover kstack into bank 0
+       ;
+       ldy     #kstack_base
+       lda     #$FF
+switch_patch_4:
+       mvn     0,0
+
+.endif
+
+       ;       Bank may be invalid but we don't have a stack we can use
+       ;       so force a far access
+       ;       after this our data bank is KERNEL_DATA
        ;       Our stack is now valid and we may use it again, our UDATA
        ;       is for the new process
-       ldx     U_DATA__U_SP                    ; correct stack pointer
+       lda     f:KERNEL_FAR+U_DATA__U_SP       ; correct stack pointer
+       tax
        txs
+       ;       Now our stack is valid fix the bank register
+
+       sep     #$20
+       .a8
+       lda     #KERNEL_BANK
+       pha
+       plb
+
        ldx     U_DATA__U_PTAB
        cpx     ptr1
        bne     switchinfail    ;       wrong process !!
        stz     _runticks
-       sep     #$20
-       .a8
+
        lda     #P_RUNNING
        sta     a:P_TAB__P_STATUS_OFFSET,x
        ;       This will only be needed once we swap, and we will need to
@@ -181,6 +224,9 @@ _dofork:
        lda     U_DATA__U_PAGE
        sta     f:KERNEL_CODE_FAR+fork_patch+2   ; source bank (parent)
        sta     f:KERNEL_CODE_FAR+fork_patch_2+1 ; destination udata stash
+.if ( KERNEL_BANK )
+       sta     f:KERNEL_CODE_FAR+fork_patch_3+1 ; destination udata stash
+.endif
        asl     a
        adc     #STACK_BANKOFF
        sta     ptr2+1                  ; source for S and DP
@@ -210,7 +256,7 @@ _dofork:
        ; Our context is now a valid stack frame so we can save stuff
        ldx     #0
        txy
-       lda     #MAP_SIZE       ; 64K - udata shadow
+       lda     #MAP_SIZE-1     ; 64K - udata shadow
        phb
 fork_patch:
        mvn     0,0             ; copy the entire bank below the save
@@ -219,12 +265,25 @@ fork_patch:
        lda     #U_DATA__TOTALSIZE-1
 fork_patch_2:
        mvn     0,KERNEL_BANK
-       plb                     ; back to kernel bank
-
-       ldx     ptr2
-       ldy     ptr3
+.if ( KERNEL_BANK )
+       ;
+       ;       For big kernels copy the kstack separately as it's in
+       ;       bank 0 but the C stack and udata are in kernel data.
+       ;
+       ldx     #kstack_base
+       lda     #$FF
+fork_patch_3:
+       mvn     0,0
+.endif
+       ;
+       ;       Clone DP and stack between parent and child
+       ;
+       ldx     ptr2            ; in DP
+       ldy     ptr3            ; in DP
        lda     #$01FF          ; DP and stack
+
        mvn     0,0
+       plb                     ; back to corect bank register
 
        ;
        ;       Final hairy detail - the child S value needs to be shifted
index cecbb9a..2bfbee1 100644 (file)
@@ -49,13 +49,6 @@ make
 
 TODO
 ----
-- Fix task switching: on big model our udata is in bank 2 and our kstack
-  ring 0 so we can't save them as single 512 byte xfer but as we know we
-  won't be using nearly all the 512 bytes of C stack we can save udata and
-  most of C stack just fine.
 - See 65c816 port for general notes
 - Save jmpvec+1/2 in seg 2 on IRQ entry and restore on exit
 
-Optimisations We Need To Do
---------------------------------------------------------------
-- Only copy the needed memory when forking, not 64K ?
index 1fcdcb4..1f25fc4 100644 (file)
@@ -6,6 +6,7 @@
         .export _ub
         .export _udata
         .export kstack_top
+       .export kstack_base
        .export kstackc_top
         .export istack_top
        .export istackc_top
@@ -23,8 +24,8 @@
 ;      stack and a small CPU stack in the banking
 ;
 ;      Our current layout is
-;      [udata][C stack]                256 bytes
-;      [C stack]                       256 
+;      [udata]                         ~256 bytes (279 with L2)
+;      [C stack]                       256  (or thereabouts)
 ;
 ;      There is a separate IRQ DP, stack and C stack.
 ;
@@ -33,6 +34,7 @@ _udata:
 kstackc_base:
        .res 512,0
 kstackc_top:
+       ; and our saved area follows this by a copy of kstack
 
 ;
 ;      We have a single istack so we can stuff that anywhere we like
index e64dde5..48e2c00 100644 (file)
@@ -26,8 +26,8 @@
  */
 #define CONFIG_BANK_65C816
 #define KERNEL_BANK    2
-#define MAX_MAPS       125
-#define MAP_SIZE    0xFC00  /* 0-FBFF */
+#define MAX_MAPS       125
+#define MAP_SIZE    0xFB00  /* 0-FAFF */
 
 /* 0xEE because our first bank is 1 and 0xEE + 2 * 1 = 0xF0 */
 #define STACK_BANKOFF  0x00    /* 0400-FDFF */
@@ -36,7 +36,7 @@
 #define MAPBASE            0x0000  /* We map from 0 */
 #define PROGBASE    0x0100  /* also data base */
 #define PROGLOAD    0x0100
-#define PROGTOP     0xFC00  /* Top of program. If we fixed a few things we
+#define PROGTOP     0xFB00  /* Top of program. If we fixed a few things we
                                could go to FE00 */
 
 #define BOOT_TTY 513        /* Set this to default device for stdio, stderr */
index 338eaa2..b657e53 100644 (file)
@@ -4,7 +4,7 @@
 U_DATA                  .set $0100     ; avoid ZP
 ; 256+256              (U, kstack copy, k C stack copy)
 U_DATA__TOTALSIZE       .set $0200
-U_DATA_STASH           .set $FC00      ; leaves FFxx for vectors and stubs
+U_DATA_STASH           .set $FB00      ; leaves FFxx for vectors and stubs
 
 PROGLOAD               .set $0100
 ZPBASE                 .set $0
@@ -21,6 +21,6 @@ STACK_BANKOFF         .set $FE        ; 0400-FDFF
 IRQ_DP                 .set $FF80      ; FF80-FFBF
 KERNEL_DP              .set $00        ; We use the real ZP for kernel DP
 
-MAP_SIZE               .set $FC00
+MAP_SIZE               .set $FB00
 
 PROGBASE               .set $0100
index 2ba03d8..3be44e5 100644 (file)
@@ -36,7 +36,6 @@ the emulator.
 
 TODO
 ----
-- Test revized brk() checking
 - Add swap logic
 - Relocatable binaries
 - cc65 stubs optimized for 65c816
@@ -48,3 +47,10 @@ TODO
 Optimisations We Need To Do
 --------------------------------------------------------------
 - Only copy the needed memory when forking, not 64K ?
+- Can we keep udata in kernel ZP (at least for level 1). Would need to
+  audit that we don't take pointers to ZP but might be faster and we
+  need to do the same audit for some cases with 68K etc anyway
+- Can we put the kernel per process CPU stack (kstack) into the upper half
+  of ZP for each process. We don't need 256 bytes of ZP per process
+- Can we trim down to say 64 bytes ZP + 256 stack per process so we can go
+  above 8MB - do we care ??