68000: Basic 68010 support
authorAlan Cox <alan@linux.intel.com>
Mon, 4 Feb 2019 00:37:59 +0000 (00:37 +0000)
committerAlan Cox <alan@linux.intel.com>
Mon, 4 Feb 2019 00:37:59 +0000 (00:37 +0000)
Kernel/cpu-68000/cpu.h
Kernel/cpu-68000/rules.mk
Kernel/lib/68000exception.c
Kernel/lib/68000flat.S
Kernel/lowlevel-68000.S

index 5069f11..f7f8be7 100644 (file)
@@ -86,3 +86,6 @@ register struct u_data *udata_ptr asm ("a5");
 extern void copy_blocks(void *, void *, unsigned int);
 
 extern void *memcpy32(void *to, const void *from, size_t bytes);
+
+extern int probe_memory(void *p);
+extern int cpu_type(void);
index 3f9c861..0e26862 100644 (file)
@@ -2,7 +2,7 @@ export CROSS_LD=m68k-uclinux-ld
 export CROSS_CC = m68k-uclinux-gcc
 # Do not use the Fedora gcc 5.3.1. It miscompiles stuff badly.
 export CROSS_CCOPTS=-c -Os -fno-strict-aliasing -fomit-frame-pointer -fno-builtin -Wall -m68000 -I$(ROOT_DIR)/cpu-68000 -I$(ROOT_DIR)/platform-$(TARGET) -I$(ROOT_DIR)/include
-export CROSS_AS=$(CROSS_CC) $(CROSS_CCOPTS) #-Wa,-M
+export CROSS_AS=$(CROSS_CC) $(CROSS_CCOPTS) -m68060 #-Wa,-M
 export CROSS_CC_SEG1=
 export CROSS_CC_SEG2=
 export CROSS_CC_SEG3=
index 93a13d3..8448e2d 100644 (file)
@@ -25,6 +25,8 @@ struct trapdata {
 
 #define FRAME_A                1
 #define FRAME_B                2
+#define FRAME_C                3
+#define FRAME_D                4
 
 static void explode(struct trapdata *framedata, int type)
 {
@@ -68,7 +70,14 @@ static void explode(struct trapdata *framedata, int type)
        for (j = 0;j < 16; j++)
                kprintf("%d: %x\n", j, excp[j]);
 
-       /* For now we only do 68000 */
+       /* 68010 long frame */
+       if (type == FRAME_C) {
+               kputs((excp[4] & 0x100)?"R":"W");
+               kprintf(" FC %x", excp[4] & 7);
+               fv = (uint32_t *)(excp +5);
+               kprintf(" Addr %p SSW %x ", *fv, excp[4]);
+       }
+       /* 68000 long frame */
        if (type == FRAME_A) {
                kputs((excp[0] & 0x10)?"R":"W");
                kprintf(" FC %x", excp[0] & 7);
@@ -76,10 +85,9 @@ static void explode(struct trapdata *framedata, int type)
                kprintf(" Addr %p IR %x ", *fv, excp[3]);
                excp += 4;
        }
-       if (type == FRAME_A || type == FRAME_B) {
-               fv = (uint32_t *)(excp + 1);
-               kprintf("PC %p SR %x\n", *fv, *excp);
-       }
+       /* All frames */
+       fv = (uint32_t *)(excp + 1);
+       kprintf("PC %p SR %x\n", *fv, *excp);
 }
 
 /* Our caller did a movem of the registers to kstack then pushed an
@@ -127,22 +135,31 @@ int exception(struct trapdata *framedata)
 
        proc = udata.u_ptab;
 
-       /* Most synchronous exceptions are type B */
-       /* FIXME: sizes need to become chip aware */
-       frame = FRAME_B;
-       fsize = 3;              /* Three words on 68000 */
-       /* TODO: On the 68010 there are at least 4 words as word 4 always holds
-          the vector and format */
+       if (sysinfo.cpu[0] == 10) {
+               /* Long or short frame: the CPU tells us the frame format */
+               if (framedata->exception[3] & 0x8000) {
+                       fsize = 29;
+                       frame = FRAME_C;
+               } else  {
+                       fsize = 4;
+                       frame = FRAME_D;
+               }
+       } else {
+               frame = FRAME_B;
+               fsize = 3;
+       }
        if (trap == 0) {
                sig = udata.u_cursig;
                udata.u_cursig = 0;
        } else if (trap < 12) {
                if (trap < 4) {
-                       /* TODO: On a 68010 this frame is 29 words and the event is
+                       /* On a 68010 this frame is 29 words and the event is
                           restartable (although not always usefully). We need to
                           decide whether to set the restart flag case by case */
-                       frame = FRAME_A;
-                       fsize = 7;
+                       if (sysinfo.cpu[0] == 0) {
+                               frame = FRAME_A;
+                               fsize = 7;
+                       }
                }
                sig = trap_to_sig[trap];
        } else if (trap >= 32 && trap < 48)
index 9f1f0b3..38648f5 100644 (file)
@@ -127,17 +127,36 @@ loop:
        ;
        ; 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
+       ;               68000           68010
+       ;   1022        PC.L            VECTOR
+       ;   1020        PC.H            PC.L
+       ;   1018        STATUS          PC.H
+       ;   1016        A5              STATUS
+       ;   1014        A5              A5
+       ;   1012                        A5
+       ;
+       tst.b cpu_has_trapvec
+       beq cpu_3word
+
+       move.w 1022(a5),-(a1)   ; Copy the vector
+       move.l 1018(a5),-(a1)   ; Copy the PC
+       move.w 1016(a5),-(a1)   ; Copy the Status
+       move.l 1012(a5),-(a1)   ; Copy the A5 save of the parent
                                ; needed for PIC processes
+       bra pushret
+cpu_3word:
+       move.l 1020(a5),-(a1)   ; Copy the PC
+       move.w 1018(a5),-(a1)   ; Copy the Status
+       move.l 1014(a5),-(a1)   ; Copy A5
+pushret:
        ;
        ; Stack a return address
        ;
        move.l #forkreturn,-(a1)
+
+       move.l a1,-(sp)
+       jsr dumpshit
+       addq #4,sp
        ;
        ; USP has to be in a0
        ;
index af3bb75..50aa903 100644 (file)
@@ -385,6 +385,7 @@ SYM (__umodsi3):
                .globl trap0,trap1,trap2,trap3,trap4,trap5,trap6,trap7
                .globl trap8,trap9,trap10,trap11,trap12,trap13,trap14,trap15
                .globl spurious,unexpected,uninit
+               .globl cpu_type,probe_memory,cpu_has_trapvec
                .globl udata_shadow
                .globl trap_via_signal
                .globl dump_registers
@@ -448,13 +449,16 @@ vdso:     trap #12                ; syscall entry
 ;      switch modes as we switch address so that we don't fault if there
 ;      is memory protection.
 ;
-;      TODO: 68010 support needs adjusting here
-;
 doexec:
                move.l 4(sp),a1                 ; go address
                lea.l 1024(a5),a7               ; reset the supervisor stack
 
                and.w #$F8FF,sr                 ; IRQ on
+
+               tst.b cpu_has_trapvec
+               beq threeword
+               clr.w -(sp)                     ; push vector
+threeword:
                move.l a1,-(sp)                 ; return address
                clr.w -(sp)                     ; set up the status register
                move.l U_DATA__U_ISP(a5),a0
@@ -519,6 +523,57 @@ init_trap_loop:
                move.l #spurious,$60(a0)
                rts
 
+;
+;      Interrupts assumed to be off for these trap tricks
+;
+
+;
+;      Override the bus error trap and check if a memory address faults
+;      (Returns 1 if it errors)
+;
+probe_memory:
+               move.l 4(sp),a0
+               move.l #probe_error,8
+               move.l a7,a1
+               moveq #0,d0
+               move.w (a0),d1
+probe_out:     move.l #bus_error,8
+               rts
+probe_error:
+               moveq #1,d0
+               move.l a1,a7
+               bra probe_out
+;
+;      Check the cpu type and return 0,10,etc.
+;
+;      FIXME: doesn't tell 68020 from 68030
+;      One way we could do that would be to issue a CALLM with a bogus
+;      module descriptor and see if we get illegal (68030) or a format
+;      exception. We can fix that when we actually need to support anything
+;      bigger than a 68010 !
+;
+cpu_type:
+               move.l #cpu_ill_error,16
+               move.l a7,a1
+               moveq #0,d0
+               movec vbr,d1            ; faults on a 68000
+               moveq #10,d0
+               movec cacr,d1           ; faults on a 68000 and 010
+               moveq #20,d0
+               movec itt0,d1           ; faults on 68020/30
+               moveq #40,d0
+               movec pcr,d1            ; faults on all but 68060
+               moveq #60,d0
+cpu_type_exit:
+               move.l #illegal,16
+               move.b d0,cpu_has_trapvec
+               rts
+;
+;      We found the faulting instruction for this CPU type so bail
+;
+cpu_ill_error:
+               move.l a1,a7
+               bra cpu_type_exit
 
 bus_error:     move.w sr,-(sp)
                move.w #2,-(sp)
@@ -691,6 +746,9 @@ spurious:   movem.l a0-a6/d0-d7,-(sp)
 unexpected:    movem.l a0-a6/d0-d7,-(sp)
                move.l #strunexpected,a0
                bsr outstring
+               move.w 6(sp),d0
+               move.w d0,a0
+               bsr outa0hex
 unexpectedl:   bra unexpectedl
 
 uninit:                movem.l a0-a6/d0-d7,-(sp)
@@ -910,3 +968,5 @@ dump_registers:
 kernel_flag:   byte 0
 udata_shadow:  long 0
 trap_id:       word 0
+cpu_has_trapvec:
+               byte 0
\ No newline at end of file