v68: do some updating on the in progress banked memory model
authorAlan Cox <alan@linux.intel.com>
Sat, 20 May 2017 18:14:56 +0000 (19:14 +0100)
committerAlan Cox <alan@linux.intel.com>
Sat, 20 May 2017 18:14:56 +0000 (19:14 +0100)
Kernel/platform-v68-banked/p68000.S
Kernel/platform-v68-banked/tricks.S

index 9a8d6fd..f12371a 100644 (file)
@@ -29,14 +29,14 @@ init_early:
 ;      FIXME: could be in discard if we wanted
 ;
 init_hardware:
-            ; set system RAM size(hadcode hacks for now) 
+            ; 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 #0,a0
-           move.w #256,d0
+           move.l #8,a0
+           move.w #253,d0
            move.l #unexpected,d1
 init_trap_loop:
            move.l d1,(a0)+
@@ -81,9 +81,6 @@ timer_irq:
            clr.b U_DATA__U_ININTERRUPT(a5)
            move.b $00F04000,d0         ; Re-enable
 
-           ; DEBUG FIXME
-           bra no_signal
-
            tst.b U_DATA__U_INSYS(a5)
            bne no_preempt
            tst.b need_resched
@@ -121,14 +118,24 @@ program_vectors:
            rts
 
 ;
-;      TODO
+;      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_kernel:
+       ; 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:
-           rts
+       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
 
@@ -143,7 +150,8 @@ outcharw:
            rts
 
 ;
-;      IDE
+;      IDE. This differs a tiny bit from the simple case because we must
+;      support bank switching while handling swap.
 ;
 devide_read_data:
        move.l blk_op,a0
@@ -189,3 +197,4 @@ vdso:       trap #14                ; syscall entry
 .section data
 
 kernel_flag: byte 1
+banksave:    byte 0
index 9c02a66..fcc0002 100644 (file)
@@ -1,10 +1,31 @@
 #include "../kernel-68000.def"
 #include "kernel.def"
 
-
 .globl 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
@@ -22,7 +43,8 @@ switchout:
        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
+       ; 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
@@ -138,8 +160,8 @@ switchinfail:
         bra trap_monitor
 
        ;
-       ; this gets exciting on the 68000 because our udata is not in a
-       ; fixed location except for swap only platforms. That means any
+       ; this gets exciting on the 68000 because our udata is not always in
+       ; 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
@@ -168,20 +190,43 @@ dofork:
        ; offset
 
        ;
-       ; Set up a switchin frame for the parent process
+       ; 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,a0
        movem.l a0/a2-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 #54,sp                    ;       toss the stack frames