From bef7fdbc2e1401491308af4b2946b9a9ca741ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Sun, 18 Jan 2015 19:47:31 +0000 Subject: [PATCH] Networking finally works stable, although not really clean. Something causes spurious interrupts and a handler for this fixed it for now. --- BaS_gcc/sys/BaS.c | 32 +- BaS_gcc/sys/exceptions.S | 718 ++++++++++++++++++++------------------- BaS_gcc/sys/interrupts.c | 6 +- 3 files changed, 391 insertions(+), 365 deletions(-) diff --git a/BaS_gcc/sys/BaS.c b/BaS_gcc/sys/BaS.c index eaed504..032faa9 100644 --- a/BaS_gcc/sys/BaS.c +++ b/BaS_gcc/sys/BaS.c @@ -270,6 +270,15 @@ NIF nif1; NIF nif2; #endif +bool spurious_interrupt_handler(void *arg1, void *arg2) +{ + dbg("IMRH=%lx, IMRL=%lx\r\n", MCF_INTC_IMRH, MCF_INTC_IMRL); + dbg("IPRH=%lx, IPRL=%lx\r\n", MCF_INTC_IPRH, MCF_INTC_IPRL); + dbg("IRLR=%x\r\n", MCF_INTC_IRLR); + + return true; +} + /* * initialize the interrupt handler tables to dispatch interrupt requests from Coldfire devices */ @@ -277,12 +286,20 @@ void init_isr(void) { isr_init(); /* need to call that explicitely, otherwise isr table might be full */ + /* + * register spurious interrupt handler + */ + if (!isr_register_handler(24, 6, 6, spurious_interrupt_handler, NULL, NULL)) + { + dbg("unable to register spurious interrupt handler\r\n"); + } + /* * register the FEC interrupt handler */ if (!isr_register_handler(64 + INT_SOURCE_FEC0, 5, 1, fec0_interrupt_handler, NULL, (void *) &nif1)) { - err("unable to register isr for FEC0\r\n"); + dbg("unable to register isr for FEC0\r\n"); } /* @@ -291,7 +308,7 @@ void init_isr(void) if (!isr_register_handler(64 + INT_SOURCE_DMA, 5, 3, dma_interrupt_handler, NULL, NULL)) { - err("unable to register isr for DMA\r\n"); + dbg("unable to register isr for DMA\r\n"); } #ifdef MACHINE_FIREBEE @@ -300,7 +317,7 @@ void init_isr(void) */ if (!isr_register_handler(64 + INT_SOURCE_GPT0, 5, 2, gpt0_interrupt_handler, NULL, NULL)) { - err("unable to register isr for GPT0 timer\r\n"); + dbg("unable to register isr for GPT0 timer\r\n"); } /* @@ -308,7 +325,7 @@ void init_isr(void) */ if (!isr_register_handler(64 + INT_SOURCE_PSC3, 5, 5, pic_interrupt_handler, NULL, NULL)) { - err("Error: unable to register ISR for PSC3\r\n"); + dbg("Error: unable to register ISR for PSC3\r\n"); } #endif /* MACHINE_FIREBEE */ @@ -317,7 +334,7 @@ void init_isr(void) */ if (!isr_register_handler(64 + INT_SOURCE_XLBPCI, 7, 0, xlbpci_interrupt_handler, NULL, NULL)) { - err("Error: unable to register isr for XLB PCI interrupts\r\n"); + dbg("Error: unable to register isr for XLB PCI interrupts\r\n"); } MCF_XLB_XARB_IMR = MCF_XLB_XARB_IMR_SEAE | /* slave error acknowledge interrupt */ @@ -330,7 +347,7 @@ void init_isr(void) if (!isr_register_handler(64 + INT_SOURCE_PCIARB, 7, 1, pciarb_interrupt_handler, NULL, NULL)) { - err("Error: unable to register isr for PCIARB interrupts\r\n"); + dbg("Error: unable to register isr for PCIARB interrupts\r\n"); return; } @@ -442,7 +459,10 @@ void BaS(void) init_isr(); enable_coldfire_interrupts(); + MCF_INTC_IMRH = 0; + MCF_INTC_IMRL = 0; dma_irq_enable(); + fec_irq_enable(0, 5, 1); init_pci(); // video_init(); diff --git a/BaS_gcc/sys/exceptions.S b/BaS_gcc/sys/exceptions.S index 7ef8f74..a9f5af6 100644 --- a/BaS_gcc/sys/exceptions.S +++ b/BaS_gcc/sys/exceptions.S @@ -27,108 +27,108 @@ #include "m5484l.h" #endif /* MACHINE_FIREBEE */ - .extern __SUP_SP - .extern _rom_entry - .extern __RAMBAR0 - .extern _rt_mod - .extern _rt_ssp - .extern _rt_usp - .extern _rt_vbr - .extern _mmutr_miss - .extern __MBAR - .extern __MMUBAR - .extern _video_tlb - .extern _video_sbt - .extern _flush_and_invalidate_caches - .extern _get_bas_drivers + .extern __SUP_SP + .extern _rom_entry + .extern __RAMBAR0 + .extern _rt_mod + .extern _rt_ssp + .extern _rt_usp + .extern _rt_vbr + .extern _mmutr_miss + .extern __MBAR + .extern __MMUBAR + .extern _video_tlb + .extern _video_sbt + .extern _flush_and_invalidate_caches + .extern _get_bas_drivers - /* PCI interrupt handlers */ - .extern _irq5_handler - .extern _irq6_handler - .extern _irq7_handler + /* PCI interrupt handlers */ + .extern _irq5_handler + .extern _irq6_handler + .extern _irq7_handler - .global _vec_init - .global _std_exc_vec /* needed by driver_vec.c */ + .global _vec_init + .global _std_exc_vec /* needed by driver_vec.c */ /* Register read/write equates */ - /* MMU */ - .equ MCF_MMU_MMUCR, __MMUBAR - .equ MCF_MMU_MMUOR, __MMUBAR+0x04 - .equ MCF_MMU_MMUSR, __MMUBAR+0x08 - .equ MCF_MMU_MMUAR, __MMUBAR+0x10 - .equ MCF_MMU_MMUTR, __MMUBAR+0x14 - .equ MCF_MMU_MMUDR, __MMUBAR+0x18 + /* MMU */ + .equ MCF_MMU_MMUCR, __MMUBAR + .equ MCF_MMU_MMUOR, __MMUBAR+0x04 + .equ MCF_MMU_MMUSR, __MMUBAR+0x08 + .equ MCF_MMU_MMUAR, __MMUBAR+0x10 + .equ MCF_MMU_MMUTR, __MMUBAR+0x14 + .equ MCF_MMU_MMUDR, __MMUBAR+0x18 - /* EPORT flag register */ - .equ MCF_EPORT_EPFR, __MBAR+0xf0c + /* EPORT flag register */ + .equ MCF_EPORT_EPFR, __MBAR+0xf0c - /* FEC1 port output data direction register */ - .equ MCF_GPIO_PODR_FEC1L, __MBAR+0xa07 + /* FEC1 port output data direction register */ + .equ MCF_GPIO_PODR_FEC1L, __MBAR+0xa07 - /* PSC0 transmit buffer register */ - .equ MCF_PSC0_PSCTB_8BIT, __MBAR+0x860c + /* PSC0 transmit buffer register */ + .equ MCF_PSC0_PSCTB_8BIT, __MBAR+0x860c - /* GPT mode select register */ - .equ MCF_GPT0_GMS, __MBAR+0x800 + /* GPT mode select register */ + .equ MCF_GPT0_GMS, __MBAR+0x800 - /* Slice timer 0 count register */ - .equ MCF_SLT0_SCNT, __MBAR+0x908 + /* Slice timer 0 count register */ + .equ MCF_SLT0_SCNT, __MBAR+0x908 - // interrupt sources - .equ INT_SOURCE_EPORT_EPF1,1 // edge port flag 1 - .equ INT_SOURCE_EPORT_EPF2,2 // edge port flag 2 - .equ INT_SOURCE_EPORT_EPF3,3 // edge port flag 3 - .equ INT_SOURCE_EPORT_EPF4,4 // edge port flag 4 - .equ INT_SOURCE_EPORT_EPF5,5 // edge port flag 5 - .equ INT_SOURCE_EPORT_EPF6,6 // edge port flag 6 - .equ INT_SOURCE_EPORT_EPF7,7 // edge port flag 7 - .equ INT_SOURCE_USB_EP0ISR,15 // USB endpoint 0 interrupt - .equ INT_SOURCE_USB_EP1ISR,16 // USB endpoint 1 interrupt - .equ INT_SOURCE_USB_EP2ISR,17 // USB endpoint 2 interrupt - .equ INT_SOURCE_USB_EP3ISR,18 // USB endpoint 3 interrupt - .equ INT_SOURCE_USB_EP4ISR,19 // USB endpoint 4 interrupt - .equ INT_SOURCE_USB_EP5ISR,20 // USB endpoint 5 interrupt - .equ INT_SOURCE_USB_EP6ISR,21 // USB endpoint 6 interrupt - .equ INT_SOURCE_USB_USBISR,22 // USB general interrupt - .equ INT_SOURCE_USB_USBAISR,23 // USB core interrupt - .equ INT_SOURCE_USB_ANY,24 // OR of all USB interrupts - .equ INT_SOURCE_USB_DSPI_OVF,25 // DSPI overflow or underflow - .equ INT_SOURCE_USB_DSPI_RFOF,26 // receive FIFO overflow interrupt - .equ INT_SOURCE_USB_DSPI_RFDF,27 // receive FIFO drain interrupt - .equ INT_SOURCE_USB_DSPI_TFUF,28 // transmit FIFO underflow interrupt - .equ INT_SOURCE_USB_DSPI_TCF,29 // transfer complete interrupt - .equ INT_SOURCE_USB_DSPI_TFFF,30 // transfer FIFO fill interrupt - .equ INT_SOURCE_USB_DSPI_EOQF,31 // end of queue interrupt - .equ INT_SOURCE_PSC3,32 // PSC3 interrupt - .equ INT_SOURCE_PSC2,33 // PSC2 interrupt - .equ INT_SOURCE_PSC1,34 // PSC1 interrupt - .equ INT_SOURCE_PSC0,35 // PSC0 interrupt - .equ INT_SOURCE_CTIMERS,36 // combined source for comm timers - .equ INT_SOURCE_SEC,37 // SEC interrupt - .equ INT_SOURCE_FEC1,38 // FEC1 interrupt - .equ INT_SOURCE_FEC0,39 // FEC0 interrupt - .equ INT_SOURCE_I2C,40 // I2C interrupt - .equ INT_SOURCE_PCIARB,41 // PCI arbiter interrupt - .equ INT_SOURCE_CBPCI,42 // COMM bus PCI interrupt - .equ INT_SOURCE_XLBPCI,43 // XLB PCI interrupt - .equ INT_SOURCE_XLBARB,47 // XLBARB to PCI interrupt - .equ INT_SOURCE_DMA,48 // multichannel DMA interrupt - .equ INT_SOURCE_CAN0_ERROR,49 // FlexCAN error interrupt - .equ INT_SOURCE_CAN0_BUSOFF,50 // FlexCAN bus off interrupt - .equ INT_SOURCE_CAN0_MBOR,51 // message buffer ORed interrupt - .equ INT_SOURCE_SLT1,53 // slice timer 1 interrupt - .equ INT_SOURCE_SLT0,54 // slice timer 0 interrupt - .equ INT_SOURCE_CAN1_ERROR,55 // FlexCAN error interrupt - .equ INT_SOURCE_CAN1_BUSOFF,56 // FlexCAN bus off interrupt - .equ INT_SOURCE_CAN1_MBOR,57 // message buffer ORed interrupt - .equ INT_SOURCE_GPT3,59 // GPT3 timer interrupt - .equ INT_SOURCE_GPT2,60 // GPT2 timer interrupt - .equ INT_SOURCE_GPT1,61 // GPT1 timer interrupt - .equ INT_SOURCE_GPT0,62 // GPT0 timer interrupt + // interrupt sources + .equ INT_SOURCE_EPORT_EPF1,1 // edge port flag 1 + .equ INT_SOURCE_EPORT_EPF2,2 // edge port flag 2 + .equ INT_SOURCE_EPORT_EPF3,3 // edge port flag 3 + .equ INT_SOURCE_EPORT_EPF4,4 // edge port flag 4 + .equ INT_SOURCE_EPORT_EPF5,5 // edge port flag 5 + .equ INT_SOURCE_EPORT_EPF6,6 // edge port flag 6 + .equ INT_SOURCE_EPORT_EPF7,7 // edge port flag 7 + .equ INT_SOURCE_USB_EP0ISR,15 // USB endpoint 0 interrupt + .equ INT_SOURCE_USB_EP1ISR,16 // USB endpoint 1 interrupt + .equ INT_SOURCE_USB_EP2ISR,17 // USB endpoint 2 interrupt + .equ INT_SOURCE_USB_EP3ISR,18 // USB endpoint 3 interrupt + .equ INT_SOURCE_USB_EP4ISR,19 // USB endpoint 4 interrupt + .equ INT_SOURCE_USB_EP5ISR,20 // USB endpoint 5 interrupt + .equ INT_SOURCE_USB_EP6ISR,21 // USB endpoint 6 interrupt + .equ INT_SOURCE_USB_USBISR,22 // USB general interrupt + .equ INT_SOURCE_USB_USBAISR,23 // USB core interrupt + .equ INT_SOURCE_USB_ANY,24 // OR of all USB interrupts + .equ INT_SOURCE_USB_DSPI_OVF,25 // DSPI overflow or underflow + .equ INT_SOURCE_USB_DSPI_RFOF,26 // receive FIFO overflow interrupt + .equ INT_SOURCE_USB_DSPI_RFDF,27 // receive FIFO drain interrupt + .equ INT_SOURCE_USB_DSPI_TFUF,28 // transmit FIFO underflow interrupt + .equ INT_SOURCE_USB_DSPI_TCF,29 // transfer complete interrupt + .equ INT_SOURCE_USB_DSPI_TFFF,30 // transfer FIFO fill interrupt + .equ INT_SOURCE_USB_DSPI_EOQF,31 // end of queue interrupt + .equ INT_SOURCE_PSC3,32 // PSC3 interrupt + .equ INT_SOURCE_PSC2,33 // PSC2 interrupt + .equ INT_SOURCE_PSC1,34 // PSC1 interrupt + .equ INT_SOURCE_PSC0,35 // PSC0 interrupt + .equ INT_SOURCE_CTIMERS,36 // combined source for comm timers + .equ INT_SOURCE_SEC,37 // SEC interrupt + .equ INT_SOURCE_FEC1,38 // FEC1 interrupt + .equ INT_SOURCE_FEC0,39 // FEC0 interrupt + .equ INT_SOURCE_I2C,40 // I2C interrupt + .equ INT_SOURCE_PCIARB,41 // PCI arbiter interrupt + .equ INT_SOURCE_CBPCI,42 // COMM bus PCI interrupt + .equ INT_SOURCE_XLBPCI,43 // XLB PCI interrupt + .equ INT_SOURCE_XLBARB,47 // XLBARB to PCI interrupt + .equ INT_SOURCE_DMA,48 // multichannel DMA interrupt + .equ INT_SOURCE_CAN0_ERROR,49 // FlexCAN error interrupt + .equ INT_SOURCE_CAN0_BUSOFF,50 // FlexCAN bus off interrupt + .equ INT_SOURCE_CAN0_MBOR,51 // message buffer ORed interrupt + .equ INT_SOURCE_SLT1,53 // slice timer 1 interrupt + .equ INT_SOURCE_SLT0,54 // slice timer 0 interrupt + .equ INT_SOURCE_CAN1_ERROR,55 // FlexCAN error interrupt + .equ INT_SOURCE_CAN1_BUSOFF,56 // FlexCAN bus off interrupt + .equ INT_SOURCE_CAN1_MBOR,57 // message buffer ORed interrupt + .equ INT_SOURCE_GPT3,59 // GPT3 timer interrupt + .equ INT_SOURCE_GPT2,60 // GPT2 timer interrupt + .equ INT_SOURCE_GPT1,61 // GPT1 timer interrupt + .equ INT_SOURCE_GPT0,62 // GPT0 timer interrupt // Atari register equates (provided by FPGA) - .equ vbasehi, 0xffff8201 + .equ vbasehi, 0xffff8201 /* * macros @@ -139,113 +139,119 @@ * flag from the EDGE PORT flag register, set the status register to the appropriate interrupt * mask an jump through the corresponging vector */ - .macro irq vector,int_mask,clr_int - move.w #0x2700,sr // disable interrupt - subq.l #8,sp - movem.l d0/a5,(sp) // save registers + .macro irq vector,int_mask,clr_int + move.w #0x2700,sr // disable interrupt + subq.l #8,sp + movem.l d0/a5,(sp) // save registers - lea MCF_EPORT_EPFR,a5 - move.b #\clr_int,(a5) // clear int pending + lea MCF_EPORT_EPFR,a5 + move.b #\clr_int,(a5) // clear int pending - movem.l (sp),d0/a5 // restore registers - addq.l #8,sp - move.l \vector,-(sp) - move #0x2\int_mask\()00,sr - rts - .endm + movem.l (sp),d0/a5 // restore registers + addq.l #8,sp + move.l \vector,-(sp) + move #0x2\int_mask\()00,sr + rts + .endm - .text + .text _vec_init: - move.l a2,-(sp) // Backup registers + move.l a2,-(sp) // Backup registers - mov3q.l #-1,_rt_mod // rt_mod auf super - clr.l _rt_ssp - clr.l _rt_usp - clr.l _rt_vbr - move.l #__RAMBAR0,d0 // exception vectors reside in rambar0 - movec d0,VBR - move.l d0,a0 - move.l a0,a2 + mov3q.l #-1,_rt_mod // rt_mod auf super + clr.l _rt_ssp + clr.l _rt_usp + clr.l _rt_vbr + move.l #__RAMBAR0,d0 // exception vectors reside in rambar0 + movec d0,VBR + move.l d0,a0 + move.l a0,a2 /* * first, set standard vector for all exceptions */ init_vec: - move.l #256,d0 - lea std_exc_vec(pc),a1 // standard vector + move.l #256,d0 + lea std_exc_vec(pc),a1 // standard vector init_vec_loop: - move.l a1,(a2)+ // set standard vector for all exceptions - subq.l #1,d0 - bne init_vec_loop + move.l a1,(a2)+ // set standard vector for all exceptions + subq.l #1,d0 + bne init_vec_loop - move.l #__SUP_SP,(a0) // set initial stack pointer at start of exception vector table +// set individual interrupt handler assignments - lea reset_vector(pc),a1 // set reset vector - move.l a1,0x04(a0) + move.l #__SUP_SP,(a0) // set initial stack pointer at start of exception vector table - lea access(pc),a1 // set illegal access exception handler - move.l a1,0x08(a0) + lea reset_vector(pc),a1 // set reset vector + move.l a1,0x04(a0) + + lea access(pc),a1 // set illegal access exception handler + move.l a1,0x08(a0) + +// install spurious interrupt handler + lea _lowlevel_isr_handler,a1 + move.l a1,0x60(a0) // trap #0 (without any parameters for now) is used to provide BaS' driver addresses to the OS - lea _get_bas_drivers(pc),a1 - move.l a1,0x80(a0) // trap #0 exception vector + lea _get_bas_drivers(pc),a1 + move.l a1,0x80(a0) // trap #0 exception vector // MFP non-autovector interrupt handlers. Those are just rerouted to their autovector counterparts - lea irq1(pc),a1 - move.l a1,0x104(a0) + lea irq1(pc),a1 + move.l a1,0x104(a0) - lea irq2(pc),a1 - move.l a1,0x108(a0) + lea irq2(pc),a1 + move.l a1,0x108(a0) - lea irq3(pc),a1 - move.l a1,0x10c(a0) + lea irq3(pc),a1 + move.l a1,0x10c(a0) - lea irq4(pc),a1 - move.l a1,0x110(a0) + lea irq4(pc),a1 + move.l a1,0x110(a0) - lea irq5(pc),a1 - move.l a1,0x114(a0) + lea irq5(pc),a1 + move.l a1,0x114(a0) - lea irq6(pc),a1 - move.l a1,0x118(a0) + lea irq6(pc),a1 + move.l a1,0x118(a0) - lea irq7(pc),a1 - move.l a1,0x11c(a0) + lea irq7(pc),a1 + move.l a1,0x11c(a0) // install lowlevel_isr_handler for the three GPT timers - lea _lowlevel_isr_handler(pc),a1 - move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0) - move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0) - move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0) + lea _lowlevel_isr_handler(pc),a1 + move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0) + move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0) + move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0) // install lowlevel_isr_handler for the PSC3 interrupt - move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0) + move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0) // install lowlevel_isr_handler for Coldfire DMA interrupts - move.l a1,(INT_SOURCE_DMA + 64) * 4(a0) + move.l a1,(INT_SOURCE_DMA + 64) * 4(a0) // install lowlevel_isr_handler for the XLBPCI interrupt - move.l a1,(INT_SOURCE_XLBPCI + 64) * 4(a0) + move.l a1,(INT_SOURCE_XLBPCI + 64) * 4(a0) // install lowlevel_isr_handler for the FEC0 interrupt - move.l a1,(INT_SOURCE_FEC0 + 64) * 4(a0) + move.l a1,(INT_SOURCE_FEC0 + 64) * 4(a0) #ifndef MACHINE_FIREBEE // FEC1 not wired on the FireBee (used for FPGA as GPIO), but available on other machines - move.l a1,(INT_SOURCE_FEC1 + 64) * 4(a0) + move.l a1,(INT_SOURCE_FEC1 + 64) * 4(a0) #endif #ifdef MACHINE_FIREBEE // timer vectors (triggers when vbashi gets changed, used for video page copy) - move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0) + move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0) #endif /* MACHINE_FIREBEE */ - move.l (sp)+,a2 // Restore registers - rts + move.l (sp)+,a2 // Restore registers + rts /* @@ -254,144 +260,144 @@ init_vec_loop: vector_table_start: std_exc_vec: _std_exc_vec: - //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 -#define DBG_EXC + //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 +//#define DBG_EXC #ifdef DBG_EXC - // printout vector number of exception + // 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 - cmp.l #33,d0 - beq noprint - cmp.l #34,d0 - beq noprint - cmp.l #45,d0 - 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() - pea exception_text - jsr _xprintf // call xprintf() - add.l #3*4,sp // adjust stack + lsr.l #2,d0 // shift vector number in place + cmp.l #33,d0 + beq noprint + cmp.l #34,d0 + beq noprint + cmp.l #45,d0 + 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() + pea exception_text + jsr _xprintf // call xprintf() + add.l #3*4,sp // adjust stack noprint: - 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 #endif /* DBG_EXC */ - add.l _rt_vbr,d0 // + VBR - move.l d0,a5 - move.l (a5),d0 // fetch exception routine address + add.l _rt_vbr,d0 // + VBR + move.l d0,a5 + 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 + // 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 exception_text: - .ascii "DEBUG: EXCEPTION %d caught at %p" - .byte 13, 10, 0 - .align 4 + .ascii "DEBUG: EXCEPTION %d caught at %p" + .byte 13, 10, 0 + .align 4 reset_vector: - 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 + 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 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 - bne bus_error + tst.l d0 // exception handler signals bus error + bne bus_error - movem.l (sp),d0-d1/a0-a1 // restore registers - unlk a6 - rte + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 + rte bus_error: - movem.l (sp),d0-d1/a0-a1 // restore registers - unlk a6 - bra std_exc_vec // FIXME: this seems to be bogous... + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 + bra std_exc_vec // FIXME: this seems to be bogous... zero_divide: - 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-> - addq.l #2,a0 + 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-> + addq.l #2,a0 zd_word: - 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 - bne zd_nal - addq.l #2,a0 - bra zd_end + 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 + 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 - addq.l #2,a0 + bne zd_end // no-> + btst #7,d0 // long? + beq zd_end // no + addq.l #2,a0 zd_end: - move.l a0,12(sp) - move.l (sp)+,d0 - move.l (sp)+,a0 - rte + move.l a0,12(sp) + move.l (sp)+,d0 + move.l (sp)+,a0 + rte #ifdef _NOT_USED_ linea: - move.w #0x2700,sr // disable interrupt - halt - nop - nop + move.w #0x2700,sr // disable interrupt + halt + nop + nop linef: - move.w #0x2700,sr // disable interrupt - halt - nop - nop + move.w #0x2700,sr // disable interrupt + halt + nop + nop format: - move.w #0x2700,sr // disable interrupt - halt - nop - nop + move.w #0x2700,sr // disable interrupt + halt + nop + nop //floating point flpoow: - move.w #0x2700,sr // disable interrupt - halt - nop - nop + move.w #0x2700,sr // disable interrupt + halt + nop + nop #endif /* _NOT_USED */ @@ -404,140 +410,140 @@ irq4: irq 0x70, 4, 0x10 // Level 4 autovector interr #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 + 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 + 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 + 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) - 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 - rte + 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 + movem.l (sp),d0-d1/a0-a1 + 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 - movem.l d0/a0,(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 + // 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 irq5: //move.w #0x2700,sr // disable interrupts - subq.l #4,sp // extra space + 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 + 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 + irq 0x74,5,0x20 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 - .text + .data + .ascii "IRQ7!" + .dc.b 13,10,0 + .text #endif /* MACHINE_FIREBEE */ /* @@ -545,8 +551,8 @@ irq7text: * isr_register_handler(int vector). If the higlevel routine (isr_execute_handler()) * returns != true, the call is forwarded to the OS (through its own vector base). */ - .global _lowlevel_isr_handler - .extern _isr_execute_handler + .global _lowlevel_isr_handler + .extern _isr_execute_handler /* @@ -562,33 +568,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 + 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 diff --git a/BaS_gcc/sys/interrupts.c b/BaS_gcc/sys/interrupts.c index 31b7cd2..26f87f5 100644 --- a/BaS_gcc/sys/interrupts.c +++ b/BaS_gcc/sys/interrupts.c @@ -117,7 +117,7 @@ bool isr_enable_int_source(int int_source) } else { - err("vector %d does not correspond to an internal interrupt source\r\n"); + dbg("vector %d does not correspond to an internal interrupt source\r\n"); return false; } @@ -165,13 +165,13 @@ bool isr_register_handler(int vector, int level, int priority, bool (*handler)(v if (!isr_enable_int_source(int_source)) { - err("failed to enable internal interrupt souce %d in IMRL/IMRH\r\n", int_source); + dbg("failed to enable internal interrupt souce %d in IMRL/IMRH\r\n", int_source); return false; } if (!isr_set_prio_and_level(int_source, priority, level)) { - err("failed to set priority and level for interrupt source %d\r\n", int_source); + dbg("failed to set priority and level for interrupt source %d\r\n", int_source); return false; }