Networking finally works stable, although not really clean. Something causes spurious interrupts and a handler for this fixed it for now.
This commit is contained in:
@@ -270,6 +270,15 @@ NIF nif1;
|
|||||||
NIF nif2;
|
NIF nif2;
|
||||||
#endif
|
#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
|
* 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 */
|
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
|
* register the FEC interrupt handler
|
||||||
*/
|
*/
|
||||||
if (!isr_register_handler(64 + INT_SOURCE_FEC0, 5, 1, fec0_interrupt_handler, NULL, (void *) &nif1))
|
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))
|
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
|
#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))
|
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))
|
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 */
|
#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))
|
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 */
|
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))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -442,7 +459,10 @@ void BaS(void)
|
|||||||
init_isr();
|
init_isr();
|
||||||
|
|
||||||
enable_coldfire_interrupts();
|
enable_coldfire_interrupts();
|
||||||
|
MCF_INTC_IMRH = 0;
|
||||||
|
MCF_INTC_IMRL = 0;
|
||||||
dma_irq_enable();
|
dma_irq_enable();
|
||||||
|
fec_irq_enable(0, 5, 1);
|
||||||
|
|
||||||
init_pci();
|
init_pci();
|
||||||
// video_init();
|
// video_init();
|
||||||
|
|||||||
@@ -27,108 +27,108 @@
|
|||||||
#include "m5484l.h"
|
#include "m5484l.h"
|
||||||
#endif /* MACHINE_FIREBEE */
|
#endif /* MACHINE_FIREBEE */
|
||||||
|
|
||||||
.extern __SUP_SP
|
.extern __SUP_SP
|
||||||
.extern _rom_entry
|
.extern _rom_entry
|
||||||
.extern __RAMBAR0
|
.extern __RAMBAR0
|
||||||
.extern _rt_mod
|
.extern _rt_mod
|
||||||
.extern _rt_ssp
|
.extern _rt_ssp
|
||||||
.extern _rt_usp
|
.extern _rt_usp
|
||||||
.extern _rt_vbr
|
.extern _rt_vbr
|
||||||
.extern _mmutr_miss
|
.extern _mmutr_miss
|
||||||
.extern __MBAR
|
.extern __MBAR
|
||||||
.extern __MMUBAR
|
.extern __MMUBAR
|
||||||
.extern _video_tlb
|
.extern _video_tlb
|
||||||
.extern _video_sbt
|
.extern _video_sbt
|
||||||
.extern _flush_and_invalidate_caches
|
.extern _flush_and_invalidate_caches
|
||||||
.extern _get_bas_drivers
|
.extern _get_bas_drivers
|
||||||
|
|
||||||
/* PCI interrupt handlers */
|
/* PCI interrupt handlers */
|
||||||
.extern _irq5_handler
|
.extern _irq5_handler
|
||||||
.extern _irq6_handler
|
.extern _irq6_handler
|
||||||
.extern _irq7_handler
|
.extern _irq7_handler
|
||||||
|
|
||||||
.global _vec_init
|
.global _vec_init
|
||||||
.global _std_exc_vec /* needed by driver_vec.c */
|
.global _std_exc_vec /* needed by driver_vec.c */
|
||||||
|
|
||||||
/* Register read/write equates */
|
/* Register read/write equates */
|
||||||
|
|
||||||
/* MMU */
|
/* MMU */
|
||||||
.equ MCF_MMU_MMUCR, __MMUBAR
|
.equ MCF_MMU_MMUCR, __MMUBAR
|
||||||
.equ MCF_MMU_MMUOR, __MMUBAR+0x04
|
.equ MCF_MMU_MMUOR, __MMUBAR+0x04
|
||||||
.equ MCF_MMU_MMUSR, __MMUBAR+0x08
|
.equ MCF_MMU_MMUSR, __MMUBAR+0x08
|
||||||
.equ MCF_MMU_MMUAR, __MMUBAR+0x10
|
.equ MCF_MMU_MMUAR, __MMUBAR+0x10
|
||||||
.equ MCF_MMU_MMUTR, __MMUBAR+0x14
|
.equ MCF_MMU_MMUTR, __MMUBAR+0x14
|
||||||
.equ MCF_MMU_MMUDR, __MMUBAR+0x18
|
.equ MCF_MMU_MMUDR, __MMUBAR+0x18
|
||||||
|
|
||||||
/* EPORT flag register */
|
/* EPORT flag register */
|
||||||
.equ MCF_EPORT_EPFR, __MBAR+0xf0c
|
.equ MCF_EPORT_EPFR, __MBAR+0xf0c
|
||||||
|
|
||||||
/* FEC1 port output data direction register */
|
/* FEC1 port output data direction register */
|
||||||
.equ MCF_GPIO_PODR_FEC1L, __MBAR+0xa07
|
.equ MCF_GPIO_PODR_FEC1L, __MBAR+0xa07
|
||||||
|
|
||||||
/* PSC0 transmit buffer register */
|
/* PSC0 transmit buffer register */
|
||||||
.equ MCF_PSC0_PSCTB_8BIT, __MBAR+0x860c
|
.equ MCF_PSC0_PSCTB_8BIT, __MBAR+0x860c
|
||||||
|
|
||||||
/* GPT mode select register */
|
/* GPT mode select register */
|
||||||
.equ MCF_GPT0_GMS, __MBAR+0x800
|
.equ MCF_GPT0_GMS, __MBAR+0x800
|
||||||
|
|
||||||
/* Slice timer 0 count register */
|
/* Slice timer 0 count register */
|
||||||
.equ MCF_SLT0_SCNT, __MBAR+0x908
|
.equ MCF_SLT0_SCNT, __MBAR+0x908
|
||||||
|
|
||||||
// interrupt sources
|
// interrupt sources
|
||||||
.equ INT_SOURCE_EPORT_EPF1,1 // edge port flag 1
|
.equ INT_SOURCE_EPORT_EPF1,1 // edge port flag 1
|
||||||
.equ INT_SOURCE_EPORT_EPF2,2 // edge port flag 2
|
.equ INT_SOURCE_EPORT_EPF2,2 // edge port flag 2
|
||||||
.equ INT_SOURCE_EPORT_EPF3,3 // edge port flag 3
|
.equ INT_SOURCE_EPORT_EPF3,3 // edge port flag 3
|
||||||
.equ INT_SOURCE_EPORT_EPF4,4 // edge port flag 4
|
.equ INT_SOURCE_EPORT_EPF4,4 // edge port flag 4
|
||||||
.equ INT_SOURCE_EPORT_EPF5,5 // edge port flag 5
|
.equ INT_SOURCE_EPORT_EPF5,5 // edge port flag 5
|
||||||
.equ INT_SOURCE_EPORT_EPF6,6 // edge port flag 6
|
.equ INT_SOURCE_EPORT_EPF6,6 // edge port flag 6
|
||||||
.equ INT_SOURCE_EPORT_EPF7,7 // edge port flag 7
|
.equ INT_SOURCE_EPORT_EPF7,7 // edge port flag 7
|
||||||
.equ INT_SOURCE_USB_EP0ISR,15 // USB endpoint 0 interrupt
|
.equ INT_SOURCE_USB_EP0ISR,15 // USB endpoint 0 interrupt
|
||||||
.equ INT_SOURCE_USB_EP1ISR,16 // USB endpoint 1 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_EP2ISR,17 // USB endpoint 2 interrupt
|
||||||
.equ INT_SOURCE_USB_EP3ISR,18 // USB endpoint 3 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_EP4ISR,19 // USB endpoint 4 interrupt
|
||||||
.equ INT_SOURCE_USB_EP5ISR,20 // USB endpoint 5 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_EP6ISR,21 // USB endpoint 6 interrupt
|
||||||
.equ INT_SOURCE_USB_USBISR,22 // USB general interrupt
|
.equ INT_SOURCE_USB_USBISR,22 // USB general interrupt
|
||||||
.equ INT_SOURCE_USB_USBAISR,23 // USB core 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_ANY,24 // OR of all USB interrupts
|
||||||
.equ INT_SOURCE_USB_DSPI_OVF,25 // DSPI overflow or underflow
|
.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_RFOF,26 // receive FIFO overflow interrupt
|
||||||
.equ INT_SOURCE_USB_DSPI_RFDF,27 // receive FIFO drain 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_TFUF,28 // transmit FIFO underflow interrupt
|
||||||
.equ INT_SOURCE_USB_DSPI_TCF,29 // transfer complete 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_TFFF,30 // transfer FIFO fill interrupt
|
||||||
.equ INT_SOURCE_USB_DSPI_EOQF,31 // end of queue interrupt
|
.equ INT_SOURCE_USB_DSPI_EOQF,31 // end of queue interrupt
|
||||||
.equ INT_SOURCE_PSC3,32 // PSC3 interrupt
|
.equ INT_SOURCE_PSC3,32 // PSC3 interrupt
|
||||||
.equ INT_SOURCE_PSC2,33 // PSC2 interrupt
|
.equ INT_SOURCE_PSC2,33 // PSC2 interrupt
|
||||||
.equ INT_SOURCE_PSC1,34 // PSC1 interrupt
|
.equ INT_SOURCE_PSC1,34 // PSC1 interrupt
|
||||||
.equ INT_SOURCE_PSC0,35 // PSC0 interrupt
|
.equ INT_SOURCE_PSC0,35 // PSC0 interrupt
|
||||||
.equ INT_SOURCE_CTIMERS,36 // combined source for comm timers
|
.equ INT_SOURCE_CTIMERS,36 // combined source for comm timers
|
||||||
.equ INT_SOURCE_SEC,37 // SEC interrupt
|
.equ INT_SOURCE_SEC,37 // SEC interrupt
|
||||||
.equ INT_SOURCE_FEC1,38 // FEC1 interrupt
|
.equ INT_SOURCE_FEC1,38 // FEC1 interrupt
|
||||||
.equ INT_SOURCE_FEC0,39 // FEC0 interrupt
|
.equ INT_SOURCE_FEC0,39 // FEC0 interrupt
|
||||||
.equ INT_SOURCE_I2C,40 // I2C interrupt
|
.equ INT_SOURCE_I2C,40 // I2C interrupt
|
||||||
.equ INT_SOURCE_PCIARB,41 // PCI arbiter interrupt
|
.equ INT_SOURCE_PCIARB,41 // PCI arbiter interrupt
|
||||||
.equ INT_SOURCE_CBPCI,42 // COMM bus PCI interrupt
|
.equ INT_SOURCE_CBPCI,42 // COMM bus PCI interrupt
|
||||||
.equ INT_SOURCE_XLBPCI,43 // XLB PCI interrupt
|
.equ INT_SOURCE_XLBPCI,43 // XLB PCI interrupt
|
||||||
.equ INT_SOURCE_XLBARB,47 // XLBARB to PCI interrupt
|
.equ INT_SOURCE_XLBARB,47 // XLBARB to PCI interrupt
|
||||||
.equ INT_SOURCE_DMA,48 // multichannel DMA interrupt
|
.equ INT_SOURCE_DMA,48 // multichannel DMA interrupt
|
||||||
.equ INT_SOURCE_CAN0_ERROR,49 // FlexCAN error interrupt
|
.equ INT_SOURCE_CAN0_ERROR,49 // FlexCAN error interrupt
|
||||||
.equ INT_SOURCE_CAN0_BUSOFF,50 // FlexCAN bus off interrupt
|
.equ INT_SOURCE_CAN0_BUSOFF,50 // FlexCAN bus off interrupt
|
||||||
.equ INT_SOURCE_CAN0_MBOR,51 // message buffer ORed interrupt
|
.equ INT_SOURCE_CAN0_MBOR,51 // message buffer ORed interrupt
|
||||||
.equ INT_SOURCE_SLT1,53 // slice timer 1 interrupt
|
.equ INT_SOURCE_SLT1,53 // slice timer 1 interrupt
|
||||||
.equ INT_SOURCE_SLT0,54 // slice timer 0 interrupt
|
.equ INT_SOURCE_SLT0,54 // slice timer 0 interrupt
|
||||||
.equ INT_SOURCE_CAN1_ERROR,55 // FlexCAN error interrupt
|
.equ INT_SOURCE_CAN1_ERROR,55 // FlexCAN error interrupt
|
||||||
.equ INT_SOURCE_CAN1_BUSOFF,56 // FlexCAN bus off interrupt
|
.equ INT_SOURCE_CAN1_BUSOFF,56 // FlexCAN bus off interrupt
|
||||||
.equ INT_SOURCE_CAN1_MBOR,57 // message buffer ORed interrupt
|
.equ INT_SOURCE_CAN1_MBOR,57 // message buffer ORed interrupt
|
||||||
.equ INT_SOURCE_GPT3,59 // GPT3 timer interrupt
|
.equ INT_SOURCE_GPT3,59 // GPT3 timer interrupt
|
||||||
.equ INT_SOURCE_GPT2,60 // GPT2 timer interrupt
|
.equ INT_SOURCE_GPT2,60 // GPT2 timer interrupt
|
||||||
.equ INT_SOURCE_GPT1,61 // GPT1 timer interrupt
|
.equ INT_SOURCE_GPT1,61 // GPT1 timer interrupt
|
||||||
.equ INT_SOURCE_GPT0,62 // GPT0 timer interrupt
|
.equ INT_SOURCE_GPT0,62 // GPT0 timer interrupt
|
||||||
|
|
||||||
// Atari register equates (provided by FPGA)
|
// Atari register equates (provided by FPGA)
|
||||||
.equ vbasehi, 0xffff8201
|
.equ vbasehi, 0xffff8201
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* macros
|
* macros
|
||||||
@@ -139,113 +139,119 @@
|
|||||||
* flag from the EDGE PORT flag register, set the status register to the appropriate interrupt
|
* flag from the EDGE PORT flag register, set the status register to the appropriate interrupt
|
||||||
* mask an jump through the corresponging vector
|
* mask an jump through the corresponging vector
|
||||||
*/
|
*/
|
||||||
.macro irq vector,int_mask,clr_int
|
.macro irq vector,int_mask,clr_int
|
||||||
move.w #0x2700,sr // disable interrupt
|
move.w #0x2700,sr // disable interrupt
|
||||||
subq.l #8,sp
|
subq.l #8,sp
|
||||||
movem.l d0/a5,(sp) // save registers
|
movem.l d0/a5,(sp) // save registers
|
||||||
|
|
||||||
lea MCF_EPORT_EPFR,a5
|
lea MCF_EPORT_EPFR,a5
|
||||||
move.b #\clr_int,(a5) // clear int pending
|
move.b #\clr_int,(a5) // clear int pending
|
||||||
|
|
||||||
movem.l (sp),d0/a5 // restore registers
|
movem.l (sp),d0/a5 // restore registers
|
||||||
addq.l #8,sp
|
addq.l #8,sp
|
||||||
move.l \vector,-(sp)
|
move.l \vector,-(sp)
|
||||||
move #0x2\int_mask\()00,sr
|
move #0x2\int_mask\()00,sr
|
||||||
rts
|
rts
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.text
|
.text
|
||||||
_vec_init:
|
_vec_init:
|
||||||
move.l a2,-(sp) // Backup registers
|
move.l a2,-(sp) // Backup registers
|
||||||
|
|
||||||
mov3q.l #-1,_rt_mod // rt_mod auf super
|
mov3q.l #-1,_rt_mod // rt_mod auf super
|
||||||
clr.l _rt_ssp
|
clr.l _rt_ssp
|
||||||
clr.l _rt_usp
|
clr.l _rt_usp
|
||||||
clr.l _rt_vbr
|
clr.l _rt_vbr
|
||||||
move.l #__RAMBAR0,d0 // exception vectors reside in rambar0
|
move.l #__RAMBAR0,d0 // exception vectors reside in rambar0
|
||||||
movec d0,VBR
|
movec d0,VBR
|
||||||
move.l d0,a0
|
move.l d0,a0
|
||||||
move.l a0,a2
|
move.l a0,a2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* first, set standard vector for all exceptions
|
* first, set standard vector for all exceptions
|
||||||
*/
|
*/
|
||||||
init_vec:
|
init_vec:
|
||||||
move.l #256,d0
|
move.l #256,d0
|
||||||
lea std_exc_vec(pc),a1 // standard vector
|
lea std_exc_vec(pc),a1 // standard vector
|
||||||
init_vec_loop:
|
init_vec_loop:
|
||||||
move.l a1,(a2)+ // set standard vector for all exceptions
|
move.l a1,(a2)+ // set standard vector for all exceptions
|
||||||
subq.l #1,d0
|
subq.l #1,d0
|
||||||
bne init_vec_loop
|
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 #__SUP_SP,(a0) // set initial stack pointer at start of exception vector table
|
||||||
move.l a1,0x04(a0)
|
|
||||||
|
|
||||||
lea access(pc),a1 // set illegal access exception handler
|
lea reset_vector(pc),a1 // set reset vector
|
||||||
move.l a1,0x08(a0)
|
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
|
// trap #0 (without any parameters for now) is used to provide BaS' driver addresses to the OS
|
||||||
lea _get_bas_drivers(pc),a1
|
lea _get_bas_drivers(pc),a1
|
||||||
move.l a1,0x80(a0) // trap #0 exception vector
|
move.l a1,0x80(a0) // trap #0 exception vector
|
||||||
|
|
||||||
// MFP non-autovector interrupt handlers. Those are just rerouted to their autovector counterparts
|
// MFP non-autovector interrupt handlers. Those are just rerouted to their autovector counterparts
|
||||||
|
|
||||||
lea irq1(pc),a1
|
lea irq1(pc),a1
|
||||||
move.l a1,0x104(a0)
|
move.l a1,0x104(a0)
|
||||||
|
|
||||||
lea irq2(pc),a1
|
lea irq2(pc),a1
|
||||||
move.l a1,0x108(a0)
|
move.l a1,0x108(a0)
|
||||||
|
|
||||||
lea irq3(pc),a1
|
lea irq3(pc),a1
|
||||||
move.l a1,0x10c(a0)
|
move.l a1,0x10c(a0)
|
||||||
|
|
||||||
lea irq4(pc),a1
|
lea irq4(pc),a1
|
||||||
move.l a1,0x110(a0)
|
move.l a1,0x110(a0)
|
||||||
|
|
||||||
lea irq5(pc),a1
|
lea irq5(pc),a1
|
||||||
move.l a1,0x114(a0)
|
move.l a1,0x114(a0)
|
||||||
|
|
||||||
lea irq6(pc),a1
|
lea irq6(pc),a1
|
||||||
move.l a1,0x118(a0)
|
move.l a1,0x118(a0)
|
||||||
|
|
||||||
lea irq7(pc),a1
|
lea irq7(pc),a1
|
||||||
move.l a1,0x11c(a0)
|
move.l a1,0x11c(a0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// install lowlevel_isr_handler for the three GPT timers
|
// install lowlevel_isr_handler for the three GPT timers
|
||||||
lea _lowlevel_isr_handler(pc),a1
|
lea _lowlevel_isr_handler(pc),a1
|
||||||
move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0)
|
move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0)
|
||||||
move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0)
|
move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0)
|
||||||
move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0)
|
move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0)
|
||||||
|
|
||||||
// install lowlevel_isr_handler for the PSC3 interrupt
|
// 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
|
// 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
|
// 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
|
// 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
|
#ifndef MACHINE_FIREBEE
|
||||||
// FEC1 not wired on the FireBee (used for FPGA as GPIO), but available on other machines
|
// 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
|
#endif
|
||||||
|
|
||||||
#ifdef MACHINE_FIREBEE
|
#ifdef MACHINE_FIREBEE
|
||||||
|
|
||||||
// timer vectors (triggers when vbashi gets changed, used for video page copy)
|
// 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 */
|
#endif /* MACHINE_FIREBEE */
|
||||||
|
|
||||||
move.l (sp)+,a2 // Restore registers
|
move.l (sp)+,a2 // Restore registers
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -254,144 +260,144 @@ init_vec_loop:
|
|||||||
vector_table_start:
|
vector_table_start:
|
||||||
std_exc_vec:
|
std_exc_vec:
|
||||||
_std_exc_vec:
|
_std_exc_vec:
|
||||||
//move.w #0x2700,sr // disable interrupt
|
//move.w #0x2700,sr // disable interrupt
|
||||||
subq.l #8,sp
|
subq.l #8,sp
|
||||||
movem.l d0/a5,(sp) // save registers
|
movem.l d0/a5,(sp) // save registers
|
||||||
move.w 8(sp),d0 // fetch vector
|
move.w 8(sp),d0 // fetch vector
|
||||||
and.l #0x3fc,d0 // mask out vector number
|
and.l #0x3fc,d0 // mask out vector number
|
||||||
#define DBG_EXC
|
//#define DBG_EXC
|
||||||
#ifdef DBG_EXC
|
#ifdef DBG_EXC
|
||||||
// printout vector number of exception
|
// printout vector number of exception
|
||||||
|
|
||||||
lea -4 * 4(sp),sp // reserve stack space
|
lea -4 * 4(sp),sp // reserve stack space
|
||||||
movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers
|
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
|
cmp.l #33,d0
|
||||||
beq noprint
|
beq noprint
|
||||||
cmp.l #34,d0
|
cmp.l #34,d0
|
||||||
beq noprint
|
beq noprint
|
||||||
cmp.l #45,d0
|
cmp.l #45,d0
|
||||||
beq noprint
|
beq noprint
|
||||||
cmp.l #46,d0
|
cmp.l #46,d0
|
||||||
beq noprint
|
beq noprint
|
||||||
move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception
|
move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception
|
||||||
move.l d0,-(sp) // provide it to xprintf()
|
move.l d0,-(sp) // provide it to xprintf()
|
||||||
pea exception_text
|
pea exception_text
|
||||||
jsr _xprintf // call xprintf()
|
jsr _xprintf // call xprintf()
|
||||||
add.l #3*4,sp // adjust stack
|
add.l #3*4,sp // adjust stack
|
||||||
noprint:
|
noprint:
|
||||||
|
|
||||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
lea 4 * 4(sp),sp
|
lea 4 * 4(sp),sp
|
||||||
#endif /* DBG_EXC */
|
#endif /* DBG_EXC */
|
||||||
|
|
||||||
add.l _rt_vbr,d0 // + VBR
|
add.l _rt_vbr,d0 // + VBR
|
||||||
move.l d0,a5
|
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 4(sp),a5 // restore a5
|
||||||
move.l d0,4(sp) // store exception routine address
|
move.l d0,4(sp) // store exception routine address
|
||||||
|
|
||||||
// FIXME: not clear why we would need the following?
|
// FIXME: not clear why we would need the following?
|
||||||
//move.w 10(sp),d0 // restore original SR
|
//move.w 10(sp),d0 // restore original SR
|
||||||
//bset #13,d0 // set supervisor bit
|
//bset #13,d0 // set supervisor bit
|
||||||
//move.w d0,sr //
|
//move.w d0,sr //
|
||||||
move.l (sp)+,d0 // restore d0
|
move.l (sp)+,d0 // restore d0
|
||||||
rts // jump to exception handler
|
rts // jump to exception handler
|
||||||
|
|
||||||
exception_text:
|
exception_text:
|
||||||
.ascii "DEBUG: EXCEPTION %d caught at %p"
|
.ascii "DEBUG: EXCEPTION %d caught at %p"
|
||||||
.byte 13, 10, 0
|
.byte 13, 10, 0
|
||||||
.align 4
|
.align 4
|
||||||
|
|
||||||
reset_vector:
|
reset_vector:
|
||||||
move.w #0x2700,sr // disable interrupts
|
move.w #0x2700,sr // disable interrupts
|
||||||
move.l #0x31415926,d0
|
move.l #0x31415926,d0
|
||||||
cmp.l 0x426,d0 // _resvalid: reset vector valid?
|
cmp.l 0x426,d0 // _resvalid: reset vector valid?
|
||||||
beq std_exc_vec // yes->
|
beq std_exc_vec // yes->
|
||||||
jmp _rom_entry // no, cold start machine
|
jmp _rom_entry // no, cold start machine
|
||||||
|
|
||||||
access:
|
access:
|
||||||
move.w #0x2700,sr // disable interrupts
|
move.w #0x2700,sr // disable interrupts
|
||||||
|
|
||||||
link a6,#-4 * 4 // make room for gcc scratch registers
|
link a6,#-4 * 4 // make room for gcc scratch registers
|
||||||
movem.l d0-d1/a0-a1,(sp) // save them
|
movem.l d0-d1/a0-a1,(sp) // save them
|
||||||
|
|
||||||
move.l 4(a6),-(sp) // push format_status
|
move.l 4(a6),-(sp) // push format_status
|
||||||
move.l 8(a6),-(sp) // pc at exception
|
move.l 8(a6),-(sp) // pc at exception
|
||||||
move.l MCF_MMU_MMUAR,-(sp) // MMU fault address
|
move.l MCF_MMU_MMUAR,-(sp) // MMU fault address
|
||||||
move.l MCF_MMU_MMUSR,-(sp) // MMU status regisrter
|
move.l MCF_MMU_MMUSR,-(sp) // MMU status regisrter
|
||||||
move.w #0x2300,sr // can lower interrupt mask now that MMU status is safe
|
move.w #0x2300,sr // can lower interrupt mask now that MMU status is safe
|
||||||
jsr _mmutr_miss // call C routine
|
jsr _mmutr_miss // call C routine
|
||||||
lea 4 * 4(sp),sp // adjust stack
|
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
|
bne bus_error
|
||||||
|
|
||||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
unlk a6
|
unlk a6
|
||||||
rte
|
rte
|
||||||
|
|
||||||
bus_error:
|
bus_error:
|
||||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
unlk a6
|
unlk a6
|
||||||
bra std_exc_vec // FIXME: this seems to be bogous...
|
bra std_exc_vec // FIXME: this seems to be bogous...
|
||||||
|
|
||||||
zero_divide:
|
zero_divide:
|
||||||
move.w #0x2700,sr // disable interrupt
|
move.w #0x2700,sr // disable interrupt
|
||||||
move.l a0,-(sp)
|
move.l a0,-(sp)
|
||||||
move.l d0,-(sp)
|
move.l d0,-(sp)
|
||||||
move.l 12(sp),a0 // pc
|
move.l 12(sp),a0 // pc
|
||||||
move.w (a0)+,d0 // command word
|
move.w (a0)+,d0 // command word
|
||||||
btst #7,d0 // long?
|
btst #7,d0 // long?
|
||||||
beq zd_word // nein->
|
beq zd_word // nein->
|
||||||
addq.l #2,a0
|
addq.l #2,a0
|
||||||
|
|
||||||
zd_word:
|
zd_word:
|
||||||
and.l 0x3f,d0 // mask out ea field
|
and.l 0x3f,d0 // mask out ea field
|
||||||
cmp.w #0x08,d0 // -(ax) or less?
|
cmp.w #0x08,d0 // -(ax) or less?
|
||||||
ble zd_end
|
ble zd_end
|
||||||
addq.l #2,a0
|
addq.l #2,a0
|
||||||
cmp.w #0x39,d0 // xxx.L
|
cmp.w #0x39,d0 // xxx.L
|
||||||
bne zd_nal
|
bne zd_nal
|
||||||
addq.l #2,a0
|
addq.l #2,a0
|
||||||
bra zd_end
|
bra zd_end
|
||||||
|
|
||||||
zd_nal: cmp.w #0x3c,d0 // immediate?
|
zd_nal: cmp.w #0x3c,d0 // immediate?
|
||||||
bne zd_end // no->
|
bne zd_end // no->
|
||||||
btst #7,d0 // long?
|
btst #7,d0 // long?
|
||||||
beq zd_end // no
|
beq zd_end // no
|
||||||
addq.l #2,a0
|
addq.l #2,a0
|
||||||
zd_end:
|
zd_end:
|
||||||
move.l a0,12(sp)
|
move.l a0,12(sp)
|
||||||
move.l (sp)+,d0
|
move.l (sp)+,d0
|
||||||
move.l (sp)+,a0
|
move.l (sp)+,a0
|
||||||
rte
|
rte
|
||||||
|
|
||||||
#ifdef _NOT_USED_
|
#ifdef _NOT_USED_
|
||||||
linea:
|
linea:
|
||||||
move.w #0x2700,sr // disable interrupt
|
move.w #0x2700,sr // disable interrupt
|
||||||
halt
|
halt
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
linef:
|
linef:
|
||||||
move.w #0x2700,sr // disable interrupt
|
move.w #0x2700,sr // disable interrupt
|
||||||
halt
|
halt
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
format:
|
format:
|
||||||
move.w #0x2700,sr // disable interrupt
|
move.w #0x2700,sr // disable interrupt
|
||||||
halt
|
halt
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
|
|
||||||
//floating point
|
//floating point
|
||||||
flpoow:
|
flpoow:
|
||||||
move.w #0x2700,sr // disable interrupt
|
move.w #0x2700,sr // disable interrupt
|
||||||
halt
|
halt
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
#endif /* _NOT_USED */
|
#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 */
|
#if defined(MACHINE_FIREBEE) /* these handlers are only meaningful for the Firebee */
|
||||||
irq5: //move.w #0x2700,sr // disable interrupts
|
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
|
link a6,#-4 * 4 // save gcc scratch registers
|
||||||
movem.l d0-d1/a0-a1,(sp)
|
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?
|
tst.b d0 // handled?
|
||||||
beq irq5_forward
|
beq irq5_forward
|
||||||
|
|
||||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
unlk a6
|
unlk a6
|
||||||
addq.l #4,sp
|
addq.l #4,sp
|
||||||
|
|
||||||
rte // return from exception
|
rte // return from exception
|
||||||
|
|
||||||
irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector
|
irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector
|
||||||
add.l _rt_vbr,a0 // add runtime vbr
|
add.l _rt_vbr,a0 // add runtime vbr
|
||||||
move.l a0,4(a6) // put on stack
|
move.l a0,4(a6) // put on stack
|
||||||
|
|
||||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
unlk a6 //
|
unlk a6 //
|
||||||
move.w #0x2500,sr // set interrupt level
|
move.w #0x2500,sr // set interrupt level
|
||||||
rts // jump through vector
|
rts // jump through vector
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* irq6 needs special treatment since - because the Coldfire only supports autovector interrupts
|
* irq6 needs special treatment since - because the Coldfire only supports autovector interrupts
|
||||||
* - the exception vector is provided by the simulated MFP from the FPGA
|
* - the exception vector is provided by the simulated MFP from the FPGA
|
||||||
*/
|
*/
|
||||||
irq6: //move.w #0x2700,sr // disable interrupt
|
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
|
link a6,#-4 * 4 // save gcc scratch registers
|
||||||
movem.l d0-d1/a0-a1,(sp)
|
movem.l d0-d1/a0-a1,(sp)
|
||||||
|
|
||||||
move.l 8(a6),-(sp) // format status word
|
move.l 8(a6),-(sp) // format status word
|
||||||
move.l 12(a6),-(sp) // pc at exception
|
move.l 12(a6),-(sp) // pc at exception
|
||||||
jsr _irq6_handler // call C handler
|
jsr _irq6_handler // call C handler
|
||||||
lea 8(sp),sp // fix stack
|
lea 8(sp),sp // fix stack
|
||||||
|
|
||||||
tst.b d0 // interrupt handled?
|
tst.b d0 // interrupt handled?
|
||||||
beq irq6_forward // no, forward to TOS
|
beq irq6_forward // no, forward to TOS
|
||||||
|
|
||||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
unlk a6
|
unlk a6
|
||||||
addq.l #4,sp // "extra space" not needed in this case
|
addq.l #4,sp // "extra space" not needed in this case
|
||||||
rte
|
rte
|
||||||
|
|
||||||
irq6_forward:
|
irq6_forward:
|
||||||
move.l 0xf0020000,a0 // fetch "MFP interrupt vector" from FPGA
|
move.l 0xf0020000,a0 // fetch "MFP interrupt vector" from FPGA
|
||||||
add.l _rt_vbr,a0 // add runtime VBR
|
add.l _rt_vbr,a0 // add runtime VBR
|
||||||
move.l (a0),4(a6) // fetch handler address and put it on "extra space"
|
move.l (a0),4(a6) // fetch handler address and put it on "extra space"
|
||||||
|
|
||||||
movem.l (sp),d0-d1/a0-a1
|
movem.l (sp),d0-d1/a0-a1
|
||||||
unlk a6
|
unlk a6
|
||||||
move.w #0x2600,sr // set interrupt mask to MFP level
|
move.w #0x2600,sr // set interrupt mask to MFP level
|
||||||
|
|
||||||
rts // jump through vector
|
rts // jump through vector
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* irq 7 = pseudo bus error
|
* irq 7 = pseudo bus error
|
||||||
*/
|
*/
|
||||||
irq7:
|
irq7:
|
||||||
lea -12(sp),sp
|
lea -12(sp),sp
|
||||||
movem.l d0/a0,(sp)
|
movem.l d0/a0,(sp)
|
||||||
|
|
||||||
move.l __RAMBAR0+0x008,a0 // real access error handler
|
move.l __RAMBAR0+0x008,a0 // real access error handler
|
||||||
move.l a0,8(sp) // this will be the return address for rts
|
move.l a0,8(sp) // this will be the return address for rts
|
||||||
|
|
||||||
move.w 12(sp),d0 // format/vector word
|
move.w 12(sp),d0 // format/vector word
|
||||||
andi.l #0xf000,d0 // keep only the format
|
andi.l #0xf000,d0 // keep only the format
|
||||||
ori.l #2*4,d0 // simulate vector #2, no fault
|
ori.l #2*4,d0 // simulate vector #2, no fault
|
||||||
move.w d0,12(sp)
|
move.w d0,12(sp)
|
||||||
|
|
||||||
// TODO: Inside an interrupt handler, 16(sp) is the return address.
|
// 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
|
// For an Access Error, it should be the address of the fault instruction instead
|
||||||
|
|
||||||
lea MCF_EPORT_EPFR,a0
|
lea MCF_EPORT_EPFR,a0
|
||||||
bset #7,(a0) // clear int 7
|
bset #7,(a0) // clear int 7
|
||||||
|
|
||||||
move.l (sp)+,d0 // restore registers
|
move.l (sp)+,d0 // restore registers
|
||||||
move.l (sp)+,a0
|
move.l (sp)+,a0
|
||||||
rts // Forward to the Access Error handler
|
rts // Forward to the Access Error handler
|
||||||
|
|
||||||
#else // handlers for M5484LITE
|
#else // handlers for M5484LITE
|
||||||
|
|
||||||
irq5: //move.w #0x2700,sr // disable interrupts
|
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
|
link a6,#-4 * 4 // save gcc scratch registers
|
||||||
movem.l d0-d1/a0-a1,(sp)
|
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?
|
tst.b d0 // handled?
|
||||||
beq irq5_forward
|
beq irq5_forward
|
||||||
|
|
||||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
unlk a6
|
unlk a6
|
||||||
addq.l #4,sp
|
addq.l #4,sp
|
||||||
|
|
||||||
rte // return from exception
|
rte // return from exception
|
||||||
|
|
||||||
irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector
|
irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector
|
||||||
add.l _rt_vbr,a0 // add runtime vbr
|
add.l _rt_vbr,a0 // add runtime vbr
|
||||||
move.l a0,4(a6) // put on stack
|
move.l a0,4(a6) // put on stack
|
||||||
|
|
||||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
unlk a6 //
|
unlk a6 //
|
||||||
move.w #0x2500,sr // set interrupt level
|
move.w #0x2500,sr // set interrupt level
|
||||||
rts // jump through vector
|
rts // jump through vector
|
||||||
|
|
||||||
irq6:
|
irq6:
|
||||||
irq 0x74,5,0x20
|
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
|
lea -4*4(sp),sp // save gcc scratch registers
|
||||||
movem.l d0-d1/a0-a1,(sp)
|
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
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
lea 4*4(sp),sp
|
lea 4*4(sp),sp
|
||||||
|
|
||||||
rte // return from exception
|
rte // return from exception
|
||||||
|
|
||||||
irq7text:
|
irq7text:
|
||||||
.data
|
.data
|
||||||
.ascii "IRQ7!"
|
.ascii "IRQ7!"
|
||||||
.dc.b 13,10,0
|
.dc.b 13,10,0
|
||||||
.text
|
.text
|
||||||
#endif /* MACHINE_FIREBEE */
|
#endif /* MACHINE_FIREBEE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -545,8 +551,8 @@ irq7text:
|
|||||||
* isr_register_handler(int vector). If the higlevel routine (isr_execute_handler())
|
* 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).
|
* returns != true, the call is forwarded to the OS (through its own vector base).
|
||||||
*/
|
*/
|
||||||
.global _lowlevel_isr_handler
|
.global _lowlevel_isr_handler
|
||||||
.extern _isr_execute_handler
|
.extern _isr_execute_handler
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -562,33 +568,33 @@ irq7text:
|
|||||||
* (sp) -> gcc scratch registers save area
|
* (sp) -> gcc scratch registers save area
|
||||||
*/
|
*/
|
||||||
_lowlevel_isr_handler:
|
_lowlevel_isr_handler:
|
||||||
subq.l #4,sp // extra space
|
subq.l #4,sp // extra space
|
||||||
link a6,#-4 * 4 // make room for
|
link a6,#-4 * 4 // make room for
|
||||||
movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them,
|
movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them,
|
||||||
// other registers will be taken care of by gcc itself
|
// other registers will be taken care of by gcc itself
|
||||||
|
|
||||||
move.w 8(a6),d0 // fetch vector number from stack
|
move.w 8(a6),d0 // fetch vector number from stack
|
||||||
lsr.l #2,d0 // move it in place
|
lsr.l #2,d0 // move it in place
|
||||||
andi.l #0xff,d0 // mask it out
|
andi.l #0xff,d0 // mask it out
|
||||||
move.l d0,-(sp) // push it
|
move.l d0,-(sp) // push it
|
||||||
jsr _isr_execute_handler // call the C handler
|
jsr _isr_execute_handler // call the C handler
|
||||||
addq.l #4,sp // adjust stack
|
addq.l #4,sp // adjust stack
|
||||||
tst.b d0 // handled?
|
tst.b d0 // handled?
|
||||||
beq lowlevel_forward // no, forward it to TOS
|
beq lowlevel_forward // no, forward it to TOS
|
||||||
|
|
||||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
unlk a6
|
unlk a6
|
||||||
addq.l #4,sp // eliminate extra space
|
addq.l #4,sp // eliminate extra space
|
||||||
|
|
||||||
rte
|
rte
|
||||||
|
|
||||||
lowlevel_forward:
|
lowlevel_forward:
|
||||||
move.l 8(a6),d0 // fetch OS irq vector
|
move.l 8(a6),d0 // fetch OS irq vector
|
||||||
lsr.l #2,d0 // move it in place
|
lsr.l #2,d0 // move it in place
|
||||||
andi.l #0xff,d0 // mask out vector number
|
andi.l #0xff,d0 // mask out vector number
|
||||||
add.l _rt_vbr,d0 // add runtime vbr
|
add.l _rt_vbr,d0 // add runtime vbr
|
||||||
move.l d0,4(a6) // put on stack as return address
|
move.l d0,4(a6) // put on stack as return address
|
||||||
|
|
||||||
movem.l (sp),d0-d1/a0-a1 // restore registers
|
movem.l (sp),d0-d1/a0-a1 // restore registers
|
||||||
unlk a6 //
|
unlk a6 //
|
||||||
rts // jump through vector
|
rts // jump through vector
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ bool isr_enable_int_source(int int_source)
|
|||||||
}
|
}
|
||||||
else
|
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;
|
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))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isr_set_prio_and_level(int_source, priority, level))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user