tiny68k: use the flat model
authorAlan Cox <alan@linux.intel.com>
Tue, 22 Jan 2019 23:48:26 +0000 (23:48 +0000)
committerAlan Cox <alan@linux.intel.com>
Tue, 22 Jan 2019 23:48:26 +0000 (23:48 +0000)
Kernel/platform-tiny68k/config.h
Kernel/platform-tiny68k/main.c
Kernel/platform-tiny68k/tricks.S

index c33dee7..b8cfdee 100644 (file)
@@ -8,28 +8,18 @@
 #define CONFIG_32BIT
 #define CONFIG_LEVEL_2
 
-/* To get us up and running then debug the flat model space */
-#undef CONFIG_MULTI
-#define CONFIG_SWAP_ONLY
+#define CONFIG_MULTI
+#define CONFIG_FLAT
+#define CONFIG_PARENT_FIRST
 #define CONFIG_USERMEM_DIRECT
 #define CONFIG_BANKS   1
-#define PROC_SIZE      128                     /* 64K, 128 * 512 */
+
+#define CONFIG_LARGE_IO_DIRECT(x)      1
 
 #define CONFIG_SPLIT_UDATA
 #define UDATA_SIZE     1024
 #define UDATA_BLKS     2
 
-#define PROGBASE       0x20000UL
-#define PROGTOP                0x30000UL
-#define SWAP_SIZE      (130 + 2)               /* 2 for the udata */
-#define SWAPBASE       PROGBASE
-#define SWAPTOP                0x30000UL
-#define MAX_SWAPS      PTABSIZE                /* Mandatory for swap only */
-#define swap_map(x)    ((uint8_t *)(x))
-
-#define CONFIG_DYNAMIC_SWAP
-#define SWAPDEV                (swap_dev)
-
 #define TICKSPERSEC 100   /* Ticks per second */
 
 #define BOOT_TTY (512 + 1)   /* Set this to default device for stdio, stderr */
index ac899db..f341d56 100644 (file)
@@ -27,11 +27,6 @@ void map_init(void)
 uaddr_t ramtop;
 uint8_t need_resched;
 
-uaddr_t pagemap_base(void)
-{
-       return 0x20000UL;
-}
-
 uint8_t platform_param(char *p)
 {
        return 0;
@@ -46,43 +41,18 @@ void memzero(void *p, usize_t len)
        memset(p, 0, len);
 }
 
-arg_t _memalloc(void)
+void pagemap_init(void)
 {
-       udata.u_error = ENOSYS;
-       return -1;
+       /* FIXME: base should be from _end of binary aligned
+          and size we want to probe early and deal with shifted monitor
+          etc */
+       kmemaddblk((void *)0x40000, 0xFF8000 - 0x40000);
 }
 
-arg_t _memfree(void)
-{
-       udata.u_error = ENOSYS;
-       return -1;
-}
-
-
-/*
- *     This function is called for partitioned devices if a partition is found
- *     and marked as swap type. The first one found will be used as swap. We
- *     only support one swap device.
- */
-void platform_swap_found(uint8_t letter, uint8_t m)
-{
-       blkdev_t *blk = blk_op.blkdev;
-       uint16_t n;
-       if (swap_dev != 0xFFFF)
-               return;
-       letter -= 'a';
-       kputs("(swap) ");
-       swap_dev = letter << 4 | m;
-       n = blk->lba_count[m - 1] / SWAP_SIZE;
-       if (n > MAX_SWAPS)
-               n = MAX_SWAPS;
-#ifdef SWAPDEV
-       while (n)
-               swapmap_init(n--);
-#endif
-}
-/* Live udata and kernel stack */
-u_block udata_block;
+/* Udata and kernel stacks */
+/* FIXME: dynamic allocation needed */
+u_block udata_block[PTABSIZE];
+/* FIXME: irqstack can go now I think */
 uint16_t irqstack[128];        /* Used for swapping only */
 
 /* This will belong in the core 68K code once finalized */
@@ -94,6 +64,10 @@ void install_vdso(void)
        memcpy((void *)udata.u_codebase, &vdso, 0x40);
 }
 
+void platform_udata_set(ptptr p)
+{
+       p->p_udata = &udata_block[p - ptab].u_d;
+}
 
 extern void *get_usp(void);
 extern void set_usp(void *p);
index fae8358..3740eca 100644 (file)
@@ -33,63 +33,34 @@ switchin:
         or #$0700,sr
        move.l 4(sp),a0         ; task to switch to
        move.l P_TAB__P_UDATA_OFFSET(a0),a5
-       tst.w P_TAB__P_PAGE_OFFSET(a0)  ; swapped or existing process ?
-       bne not_swapped
-
-;
-;      If you have one udata and swap them then you need to stack switch
-;      for the swap in as you'll overwrite the kernel stack. You can use
-;      the IRQ stack but only if you leave IRQs off for a swap in (ugghh)
-;
-
-;
-;      FIXME: sort IRQ enables
-;
-
-;
-;      In simple mode the existing process always gets the boot here
-;      before we can swap the new one in
-;
-       move.l U_DATA__U_PTAB(a5),a1    ; old process
-       tst.w P_TAB__P_PAGE_OFFSET(a1)  ; swapped out/dead ?
-       beq its_dead_jim                ; corpses don't need swapping out
-
-       move.l a0,-(sp)
-       move.l a1,-(sp)
-       jsr swapout
-       addq #4,sp
-       move.l (sp)+,a0
-
-its_dead_jim:
-       move.l sp,a1
-       move.l #irqstack+256,sp
-       move.l a1,-(sp)
-       move.l a0,-(sp)
-       move.l a0,-(sp)
-       jsr swapper
-       addq #4,sp
-       move.l (sp)+,a0
-       move.w #1,P_TAB__P_PAGE_OFFSET(a0) ; swapped in
-       move.l (sp)+,a1                 ; straight into a7 fails
-       move.l a1,a7                    ; emulator bug or CPU funny ??
-
-        or #$0700,sr
-
-not_swapped:
         ; check u_data->u_ptab matches what we wanted
        cmp.l U_DATA__U_PTAB(a5),a0
        bne switchinfail
 
+       ; Switch the stacks back
+       move.l a5,udata_shadow  ; For IRQs etc to recover A5 state
+       move.l U_DATA__U_SP(a5),a7
+
        move.b #P_RUNNING,P_TAB__P_STATUS_OFFSET(a0)
 
+       ;
+       ;       Get the user pages back. We can safely
+       ;       do this above the parent kernel stack I think
+       ;
+       clr.l -(sp)
+       move.l a0,-(sp)
+       jsr pagemap_switch
+       addq #8,sp
+
         ; runticks = 0
        clr.w runticks
 
-        ; restore machine state
-        move.l U_DATA__U_SP(a5),sp
+       ; recover the task switch state
        movem.l (sp)+,a0/a2-a4/a6/d2-d7
-       move.l a0,usp
-       move.w (sp)+,d0                 ; FIXME: can we merge ?
+       move.l a0,USP
+       ; and return code - FIXME: we have a different fork path so the d0
+       ; stacking can go
+       move.w (sp)+,d0
 
         tst.b U_DATA__U_ININTERRUPT(a5)
         bne keepoff ; in ISR, leave interrupts off
@@ -106,14 +77,8 @@ switchinfail:
 
        ;
        ; this gets exciting on the 68000 because our udata is not in a
-       ; 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
-       ; cases we have to return as the parent but set up a fake stack
-       ; frame for the child to exit the syscall. Simply being careful
-       ; about pointers doesn't work - the compiler will internally
-       ; use link/unlk and other stuff.
+       ; fixed location except for swap only platforms. To deal with this
+       ; we return parent first and create a new return frame for the child
        ;
        ; Entry:
        ; A5 = u_data pointer for parent
@@ -124,45 +89,102 @@ switchinfail:
        ; child stack
        ;
 dofork:
-       ;
-       ; simple edition for swap only
-       ;
        move.l 4(sp),a0                 ;       child p_tab
+       move.l a2,-(sp)
+
+       move.l P_TAB__P_UDATA_OFFSET(a0),a1     ; child udata
+
+       ; Copy the udata
+       ; FIXME: we don't need to copy the stack too!
+
+       move.l a5,a2
+       move.w #255,d0
+loop:
+       move.l (a2)+,(a1)+
+       dbra d0,loop
+
+
        ;
-       ; in the simple case we only have one udata. In the complex cases
-       ; we would have to compute the new one and load it into a5 and
-       ; offset
+       ; Save the child PID for later and the udata offset
        ;
-       move.l a5,P_TAB__P_UDATA_OFFSET(a0)
-       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
-       move.l U_DATA__U_PTAB(a5),-(sp) ;       parent p_tab
-
-       ; FIXME: for the single case with less swaps than processes the
-       ; out of swap case is one out (we must swap out to swap in so need
-       ; one swap free after the fork. Right now we deal with this in
-       ; Config by not setting it that way
-       jsr swapout
-       add.w #50,sp                    ;       throw the call frame and
-                                       ;       the frame we built for
-                                       ;       switchin
-       tst.w d0
-       bne forked_up
-
-       move.l 4(sp),a0
-       movel a5,-(sp)                  ;       U_DATA
+       move.w P_TAB__P_PID_OFFSET(a0),-(sp)
+       move.l P_TAB__P_UDATA_OFFSET(a0),-(sp)
+       ;
+       ; Configure the child udata now we copied it
+       ; BUG: child udata is NULL ????
+
+       move.l P_TAB__P_UDATA_OFFSET(a0),-(sp)
        move.l a0,-(sp)
        jsr makeproc
        addq #8,sp
+       ;
+       ;       The memory map is clone by ptab_alloc (we might want to
+       ;       adjust that bit)
+       ;
+       ;tst.l d0
+       ;bne forked_up
+
+       move.l (sp)+,a2         ; Get the udata pointer back
+       ;
+       ; Now build a custom return frame for the child
+       ;
+       lea.l 1024(a2),a1       ; End of stack
+       ;
+       ; Copy over the parent top of stack return info
+       ;
+       ; FIXME: This assumes 68000 trap format. For the 68010
+       ; there will be 4 words not 3
+       ;
+       move.l 1020(a5),-(a1)   ; Copy the PC
+       move.w 1018(a5),-(a1)   ; Copy the status word
+       move.l 1014(a5),-(a1)   ; Copy the A5 save of the parent
+                               ; needed for PIC processes
+       ;
+       ; Stack a return address
+       ;
+       move.l #forkreturn,-(a1)
+       ;
+       ; USP has to be in a0
+       ;
+       move.l usp,a0
+       ;
+       ; And a frame as if we did a switchout
+       ;
+       move.w #0,-(a1)
+       movem.l a0/a2-a4/a6/d2-d7,-(a1)
+       move.l a1,U_DATA__U_SP(a2)      ; Set the stack pointer
 
-       moveq #0,d0                     ;       child, ok
+       ; And carry on as the parent
+       move.w (sp)+,d0         ; child pid
+       move.l (sp)+,a2
        clr.w runticks
        rts
 forked_up:
        moveq #-1,d0                    ;       parent, failed
        rts
+;
+;      This code gets called when we resume the child
+;
+forkreturn:
+       ; Wipe any stray kernel data
+       moveq #0,d1
+       move.l d1,a0
+       move.l d1,a1
+       move.l d1,a2
+       move.l d1,a3
+       move.l d1,a4
+       move.l d1,a6
+       move.l d1,d2
+       move.l d1,d3
+       move.l d1,d4
+       move.l d1,d5
+       move.l d1,d6
+       move.l d1,d7
+       ; recover A5 to match the parent
+       move.l (sp)+,a5
+       ; and RTE to the same address (which is fine as the user memory
+       ; has already been juggled if needed).
+       rte
 
 badswitchmsg: ascii "_switchin: FAIL"
             byte 13,10,0