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);
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=
#define FRAME_A 1
#define FRAME_B 2
+#define FRAME_C 3
+#define FRAME_D 4
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);
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
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)
;
; 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
;
.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
; 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
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)
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)
kernel_flag: byte 0
udata_shadow: long 0
trap_id: word 0
+cpu_has_trapvec:
+ byte 0
\ No newline at end of file