fix a problem where nested interrupts caused networking to hang
This commit is contained in:
@@ -140,7 +140,7 @@
|
||||
* mask an jump through the corresponging vector
|
||||
*/
|
||||
.macro irq vector,int_mask,clr_int
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
move.w #0x2700,sr // disable interrupts
|
||||
subq.l #8,sp
|
||||
movem.l d0/a5,(sp) // save registers
|
||||
|
||||
@@ -260,19 +260,19 @@ init_vec_loop:
|
||||
vector_table_start:
|
||||
std_exc_vec:
|
||||
_std_exc_vec:
|
||||
//move.w #0x2700,sr // disable interrupt
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
subq.l #8,sp
|
||||
movem.l d0/a5,(sp) // save registers
|
||||
move.w 8(sp),d0 // fetch vector
|
||||
and.l #0x3fc,d0 // mask out vector number
|
||||
movem.l d0/a5,(sp) // save registers
|
||||
move.w 8(sp),d0 // fetch vector
|
||||
and.l #0x3fc,d0 // mask out vector number
|
||||
//#define DBG_EXC
|
||||
#ifdef DBG_EXC
|
||||
// printout vector number of exception
|
||||
|
||||
lea -4 * 4(sp),sp // reserve stack space
|
||||
movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers
|
||||
lea -4 * 4(sp),sp // reserve stack space
|
||||
movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers
|
||||
|
||||
lsr.l #2,d0 // shift vector number in place
|
||||
lsr.l #2,d0 // shift vector number in place
|
||||
cmp.l #33,d0
|
||||
beq noprint
|
||||
cmp.l #34,d0
|
||||
@@ -281,30 +281,29 @@ _std_exc_vec:
|
||||
beq noprint
|
||||
cmp.l #46,d0
|
||||
beq noprint
|
||||
move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception
|
||||
move.l d0,-(sp) // provide it to xprintf()
|
||||
move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception
|
||||
move.l d0,-(sp) // provide it to xprintf()
|
||||
pea exception_text
|
||||
jsr _xprintf // call xprintf()
|
||||
add.l #3*4,sp // adjust stack
|
||||
jsr _xprintf // call xprintf()
|
||||
add.l #3*4,sp // adjust stack
|
||||
noprint:
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
lea 4 * 4(sp),sp
|
||||
#endif /* DBG_EXC */
|
||||
|
||||
add.l _rt_vbr,d0 // + VBR
|
||||
add.l _rt_vbr,d0 // + VBR
|
||||
move.l d0,a5
|
||||
move.l (a5),d0 // fetch exception routine address
|
||||
move.l (a5),d0 // fetch exception routine address
|
||||
|
||||
move.l 4(sp),a5 // restore a5
|
||||
move.l d0,4(sp) // store exception routine address
|
||||
move.l 4(sp),a5 // restore a5
|
||||
move.l d0,4(sp) // store exception routine address
|
||||
|
||||
// FIXME: not clear why we would need the following?
|
||||
//move.w 10(sp),d0 // restore original SR
|
||||
//bset #13,d0 // set supervisor bit
|
||||
//move.w d0,sr //
|
||||
move.l (sp)+,d0 // restore d0
|
||||
rts // jump to exception handler
|
||||
move.w 10(sp),d0 // restore original SR (irq mask)
|
||||
bset #13,d0 // set supervisor bit
|
||||
move.w d0,sr //
|
||||
move.l (sp)+,d0 // restore d0
|
||||
rts // jump to exception handler
|
||||
|
||||
exception_text:
|
||||
.ascii "DEBUG: EXCEPTION %d caught at %p"
|
||||
@@ -312,62 +311,62 @@ exception_text:
|
||||
.align 4
|
||||
|
||||
reset_vector:
|
||||
move.w #0x2700,sr // disable interrupts
|
||||
move.w #0x2700,sr // disable interrupts
|
||||
move.l #0x31415926,d0
|
||||
cmp.l 0x426,d0 // _resvalid: reset vector valid?
|
||||
beq std_exc_vec // yes->
|
||||
jmp _rom_entry // no, cold start machine
|
||||
cmp.l 0x426,d0 // _resvalid: reset vector valid?
|
||||
beq std_exc_vec // yes->
|
||||
jmp _rom_entry // no, cold start machine
|
||||
|
||||
access:
|
||||
move.w #0x2700,sr // disable interrupts
|
||||
move.w #0x2700,sr // disable interrupts
|
||||
|
||||
link a6,#-4 * 4 // make room for gcc scratch registers
|
||||
movem.l d0-d1/a0-a1,(sp) // save them
|
||||
link a6,#-4 * 4 // make room for gcc scratch registers
|
||||
movem.l d0-d1/a0-a1,(sp) // save them
|
||||
|
||||
move.l 4(a6),-(sp) // push format_status
|
||||
move.l 8(a6),-(sp) // pc at exception
|
||||
move.l MCF_MMU_MMUAR,-(sp) // MMU fault address
|
||||
move.l MCF_MMU_MMUSR,-(sp) // MMU status regisrter
|
||||
move.w #0x2300,sr // can lower interrupt mask now that MMU status is safe
|
||||
jsr _mmutr_miss // call C routine
|
||||
lea 4 * 4(sp),sp // adjust stack
|
||||
move.l 4(a6),-(sp) // push format_status
|
||||
move.l 8(a6),-(sp) // pc at exception
|
||||
move.l MCF_MMU_MMUAR,-(sp) // MMU fault address
|
||||
move.l MCF_MMU_MMUSR,-(sp) // MMU status regisrter
|
||||
move.w #0x2300,sr // can lower interrupt mask now that MMU status is safe
|
||||
jsr _mmutr_miss // call C routine
|
||||
lea 4 * 4(sp),sp // adjust stack
|
||||
|
||||
tst.l d0 // exception handler signals bus error
|
||||
tst.l d0 // exception handler signals bus error
|
||||
bne bus_error
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6
|
||||
rte
|
||||
|
||||
bus_error:
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6
|
||||
bra std_exc_vec // FIXME: this seems to be bogous...
|
||||
bra std_exc_vec // FIXME: this seems to be bogous...
|
||||
|
||||
zero_divide:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
move.l a0,-(sp)
|
||||
move.l d0,-(sp)
|
||||
move.l 12(sp),a0 // pc
|
||||
move.w (a0)+,d0 // command word
|
||||
btst #7,d0 // long?
|
||||
beq zd_word // nein->
|
||||
move.l 12(sp),a0 // pc
|
||||
move.w (a0)+,d0 // command word
|
||||
btst #7,d0 // long?
|
||||
beq zd_word // no->
|
||||
addq.l #2,a0
|
||||
|
||||
zd_word:
|
||||
and.l 0x3f,d0 // mask out ea field
|
||||
cmp.w #0x08,d0 // -(ax) or less?
|
||||
and.l 0x3f,d0 // mask out ea field
|
||||
cmp.w #0x08,d0 // -(ax) or less?
|
||||
ble zd_end
|
||||
addq.l #2,a0
|
||||
cmp.w #0x39,d0 // xxx.L
|
||||
cmp.w #0x39,d0 // xxx.L
|
||||
bne zd_nal
|
||||
addq.l #2,a0
|
||||
bra zd_end
|
||||
|
||||
zd_nal: cmp.w #0x3c,d0 // immediate?
|
||||
bne zd_end // no->
|
||||
btst #7,d0 // long?
|
||||
beq zd_end // no
|
||||
zd_nal: cmp.w #0x3c,d0 // immediate?
|
||||
bne zd_end // no->
|
||||
btst #7,d0 // long?
|
||||
beq zd_end // no
|
||||
addq.l #2,a0
|
||||
zd_end:
|
||||
move.l a0,12(sp)
|
||||
@@ -377,172 +376,172 @@ zd_end:
|
||||
|
||||
#ifdef _NOT_USED_
|
||||
linea:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
halt
|
||||
nop
|
||||
nop
|
||||
linef:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
halt
|
||||
nop
|
||||
nop
|
||||
format:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
halt
|
||||
nop
|
||||
nop
|
||||
|
||||
//floating point
|
||||
flpoow:
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
move.w #0x2700,sr // disable interrupt
|
||||
halt
|
||||
nop
|
||||
nop
|
||||
#endif /* _NOT_USED */
|
||||
|
||||
|
||||
irq1: irq 0x64, 1, 0x02 // Level 1 autovector interrupt (unused)
|
||||
irq2: irq 0x68, 2, 0x04 // Level 2 autovector interrupt (horizontal blank)
|
||||
irq3: irq 0x6c, 3, 0x08 // Level 3 autovector interrupt (unused)
|
||||
irq4: irq 0x70, 4, 0x10 // Level 4 autovector interrupt (vertical blank)
|
||||
irq1: irq 0x64, 1, 0x02 // Level 1 autovector interrupt (unused)
|
||||
irq2: irq 0x68, 2, 0x04 // Level 2 autovector interrupt (horizontal blank)
|
||||
irq3: irq 0x6c, 3, 0x08 // Level 3 autovector interrupt (unused)
|
||||
irq4: irq 0x70, 4, 0x10 // Level 4 autovector interrupt (vertical blank)
|
||||
|
||||
|
||||
|
||||
#if defined(MACHINE_FIREBEE) /* these handlers are only meaningful for the Firebee */
|
||||
irq5: //move.w #0x2700,sr // disable interrupts
|
||||
subq.l #4,sp // extra space
|
||||
#if defined(MACHINE_FIREBEE) /* these handlers are only meaningful for the Firebee */
|
||||
irq5: //move.w #0x2700,sr // disable interrupts
|
||||
subq.l #4,sp // extra space
|
||||
|
||||
link a6,#-4 * 4 // save gcc scratch registers
|
||||
movem.l d0-d1/a0-a1,(sp)
|
||||
link a6,#-4 * 4 // save gcc scratch registers
|
||||
movem.l d0-d1/a0-a1,(sp)
|
||||
|
||||
jsr _irq5_handler // call C handler routine
|
||||
jsr _irq5_handler // call C handler routine
|
||||
|
||||
tst.b d0 // handled?
|
||||
beq irq5_forward
|
||||
tst.b d0 // handled?
|
||||
beq irq5_forward
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6
|
||||
addq.l #4,sp
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6
|
||||
addq.l #4,sp
|
||||
|
||||
rte // return from exception
|
||||
rte // return from exception
|
||||
|
||||
irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector
|
||||
add.l _rt_vbr,a0 // add runtime vbr
|
||||
move.l a0,4(a6) // put on stack
|
||||
irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector
|
||||
add.l _rt_vbr,a0 // add runtime vbr
|
||||
move.l a0,4(a6) // put on stack
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6 //
|
||||
move.w #0x2500,sr // set interrupt level
|
||||
rts // jump through vector
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6 //
|
||||
move.w #0x2500,sr // set interrupt level
|
||||
rts // jump through vector
|
||||
|
||||
/*
|
||||
* irq6 needs special treatment since - because the Coldfire only supports autovector interrupts
|
||||
* - the exception vector is provided by the simulated MFP from the FPGA
|
||||
*/
|
||||
irq6: //move.w #0x2700,sr // disable interrupt
|
||||
subq.l #4,sp // extra space
|
||||
irq6: move.w #0x2700,sr // disable interrupt
|
||||
subq.l #4,sp // extra space
|
||||
|
||||
link a6,#-4 * 4 // save gcc scratch registers
|
||||
link a6,#-4 * 4 // save gcc scratch registers
|
||||
movem.l d0-d1/a0-a1,(sp)
|
||||
|
||||
move.l 8(a6),-(sp) // format status word
|
||||
move.l 12(a6),-(sp) // pc at exception
|
||||
jsr _irq6_handler // call C handler
|
||||
lea 8(sp),sp // fix stack
|
||||
move.l 8(a6),-(sp) // format status word
|
||||
move.l 12(a6),-(sp) // pc at exception
|
||||
jsr _irq6_handler // call C handler
|
||||
lea 8(sp),sp // fix stack
|
||||
|
||||
tst.b d0 // interrupt handled?
|
||||
beq irq6_forward // no, forward to TOS
|
||||
tst.b d0 // interrupt handled?
|
||||
beq irq6_forward // no, forward to TOS
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6
|
||||
addq.l #4,sp // "extra space" not needed in this case
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6
|
||||
addq.l #4,sp // "extra space" not needed in this case
|
||||
rte
|
||||
|
||||
irq6_forward:
|
||||
move.l 0xf0020000,a0 // fetch "MFP interrupt vector" from FPGA
|
||||
add.l _rt_vbr,a0 // add runtime VBR
|
||||
move.l (a0),4(a6) // fetch handler address and put it on "extra space"
|
||||
move.l 0xf0020000,a0 // fetch "MFP interrupt vector" from FPGA
|
||||
add.l _rt_vbr,a0 // add runtime VBR
|
||||
move.l (a0),4(a6) // fetch handler address and put it on "extra space"
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1
|
||||
unlk a6
|
||||
move.w #0x2600,sr // set interrupt mask to MFP level
|
||||
unlk a6
|
||||
move.w #0x2600,sr // set interrupt mask to MFP level
|
||||
|
||||
rts // jump through vector
|
||||
rts // jump through vector
|
||||
|
||||
/*
|
||||
* irq 7 = pseudo bus error
|
||||
*/
|
||||
irq7:
|
||||
lea -12(sp),sp
|
||||
lea -12(sp),sp
|
||||
movem.l d0/a0,(sp)
|
||||
|
||||
move.l __RAMBAR0+0x008,a0 // real access error handler
|
||||
move.l a0,8(sp) // this will be the return address for rts
|
||||
move.l __RAMBAR0+0x008,a0 // real access error handler
|
||||
move.l a0,8(sp) // this will be the return address for rts
|
||||
|
||||
move.w 12(sp),d0 // format/vector word
|
||||
andi.l #0xf000,d0 // keep only the format
|
||||
ori.l #2*4,d0 // simulate vector #2, no fault
|
||||
move.w d0,12(sp)
|
||||
move.w 12(sp),d0 // format/vector word
|
||||
andi.l #0xf000,d0 // keep only the format
|
||||
ori.l #2*4,d0 // simulate vector #2, no fault
|
||||
move.w d0,12(sp)
|
||||
|
||||
// TODO: Inside an interrupt handler, 16(sp) is the return address.
|
||||
// For an Access Error, it should be the address of the fault instruction instead
|
||||
|
||||
lea MCF_EPORT_EPFR,a0
|
||||
bset #7,(a0) // clear int 7
|
||||
lea MCF_EPORT_EPFR,a0
|
||||
bset #7,(a0) // clear int 7
|
||||
|
||||
move.l (sp)+,d0 // restore registers
|
||||
move.l (sp)+,a0
|
||||
rts // Forward to the Access Error handler
|
||||
move.l (sp)+,d0 // restore registers
|
||||
move.l (sp)+,a0
|
||||
rts // Forward to the Access Error handler
|
||||
|
||||
#else // handlers for M5484LITE
|
||||
#else // handlers for M5484LITE
|
||||
|
||||
irq5: //move.w #0x2700,sr // disable interrupts
|
||||
subq.l #4,sp // extra space
|
||||
irq5: move.w #0x2700,sr // disable interrupts
|
||||
subq.l #4,sp // extra space
|
||||
|
||||
link a6,#-4 * 4 // save gcc scratch registers
|
||||
movem.l d0-d1/a0-a1,(sp)
|
||||
link a6,#-4 * 4 // save gcc scratch registers
|
||||
movem.l d0-d1/a0-a1,(sp)
|
||||
|
||||
jsr _irq5_handler // call C handler routine
|
||||
jsr _irq5_handler // call C handler routine
|
||||
|
||||
tst.b d0 // handled?
|
||||
beq irq5_forward
|
||||
tst.b d0 // handled?
|
||||
beq irq5_forward
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6
|
||||
addq.l #4,sp
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6
|
||||
addq.l #4,sp
|
||||
|
||||
rte // return from exception
|
||||
rte // return from exception
|
||||
|
||||
irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector
|
||||
add.l _rt_vbr,a0 // add runtime vbr
|
||||
move.l a0,4(a6) // put on stack
|
||||
irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector
|
||||
add.l _rt_vbr,a0 // add runtime vbr
|
||||
move.l a0,4(a6) // put on stack
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6 //
|
||||
move.w #0x2500,sr // set interrupt level
|
||||
rts // jump through vector
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6 //
|
||||
move.w #0x2500,sr // set interrupt level
|
||||
rts // jump through vector
|
||||
|
||||
irq6:
|
||||
irq 0x74,5,0x20
|
||||
|
||||
irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE
|
||||
irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE
|
||||
|
||||
//move.w #0x2700,sr // disable interrupts
|
||||
move.w #0x2700,sr // disable interrupts
|
||||
|
||||
lea -4*4(sp),sp // save gcc scratch registers
|
||||
movem.l d0-d1/a0-a1,(sp)
|
||||
lea -4*4(sp),sp // save gcc scratch registers
|
||||
movem.l d0-d1/a0-a1,(sp)
|
||||
|
||||
jsr _irq7_handler // call C handler routine
|
||||
jsr _irq7_handler // call C handler routine
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
lea 4*4(sp),sp
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
lea 4 * 4(sp),sp
|
||||
|
||||
rte // return from exception
|
||||
rte // return from exception
|
||||
|
||||
irq7text:
|
||||
.data
|
||||
.ascii "IRQ7!"
|
||||
.dc.b 13,10,0
|
||||
.ascii "IRQ7!"
|
||||
.dc.b 13,10,0
|
||||
.text
|
||||
#endif /* MACHINE_FIREBEE */
|
||||
|
||||
@@ -568,33 +567,33 @@ irq7text:
|
||||
* (sp) -> gcc scratch registers save area
|
||||
*/
|
||||
_lowlevel_isr_handler:
|
||||
subq.l #4,sp // extra space
|
||||
link a6,#-4 * 4 // make room for
|
||||
movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them,
|
||||
// other registers will be taken care of by gcc itself
|
||||
subq.l #4,sp // extra space
|
||||
link a6,#-4 * 4 // make room for
|
||||
movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them,
|
||||
// other registers will be taken care of by gcc itself
|
||||
|
||||
move.w 8(a6),d0 // fetch vector number from stack
|
||||
lsr.l #2,d0 // move it in place
|
||||
andi.l #0xff,d0 // mask it out
|
||||
move.l d0,-(sp) // push it
|
||||
jsr _isr_execute_handler // call the C handler
|
||||
addq.l #4,sp // adjust stack
|
||||
tst.b d0 // handled?
|
||||
beq lowlevel_forward // no, forward it to TOS
|
||||
move.w 8(a6),d0 // fetch vector number from stack
|
||||
lsr.l #2,d0 // move it in place
|
||||
andi.l #0xff,d0 // mask it out
|
||||
move.l d0,-(sp) // push it
|
||||
jsr _isr_execute_handler // call the C handler
|
||||
addq.l #4,sp // adjust stack
|
||||
tst.b d0 // handled?
|
||||
beq lowlevel_forward // no, forward it to TOS
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6
|
||||
addq.l #4,sp // eliminate extra space
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6
|
||||
addq.l #4,sp // eliminate extra space
|
||||
|
||||
rte
|
||||
|
||||
lowlevel_forward:
|
||||
move.l 8(a6),d0 // fetch OS irq vector
|
||||
lsr.l #2,d0 // move it in place
|
||||
andi.l #0xff,d0 // mask out vector number
|
||||
add.l _rt_vbr,d0 // add runtime vbr
|
||||
move.l d0,4(a6) // put on stack as return address
|
||||
move.l 8(a6),d0 // fetch OS irq vector
|
||||
lsr.l #2,d0 // move it in place
|
||||
andi.l #0xff,d0 // mask out vector number
|
||||
add.l _rt_vbr,d0 // add runtime vbr
|
||||
move.l d0,4(a6) // put on stack as return address
|
||||
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6 //
|
||||
rts // jump through vector
|
||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||
unlk a6 //
|
||||
rts // jump through vector
|
||||
|
||||
Reference in New Issue
Block a user