added interrupt controller initialization for PCI error interrupts

This commit is contained in:
Markus Fröschle
2014-10-09 18:59:35 +00:00
parent 1cbd86f7e9
commit 44a2234ed2
4 changed files with 345 additions and 322 deletions

View File

@@ -36,6 +36,7 @@ CFLAGS=-mcpu=5474 \
-fomit-frame-pointer \ -fomit-frame-pointer \
-ffreestanding \ -ffreestanding \
-fleading-underscore \ -fleading-underscore \
-mno-strict-align \
-Wa,--register-prefix-optional -Wa,--register-prefix-optional
CFLAGS_OPTIMIZED = -mcpu=5474 \ CFLAGS_OPTIMIZED = -mcpu=5474 \
-Wall \ -Wall \

456
sys/BaS.c
View File

@@ -78,10 +78,10 @@ extern uint8_t _EMUTOS_SIZE[];
*/ */
static inline bool pic_txready(void) static inline bool pic_txready(void)
{ {
if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY) if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY)
return true; return true;
return false; return false;
} }
/* /*
@@ -89,84 +89,84 @@ static inline bool pic_txready(void)
*/ */
static inline bool pic_rxready(void) static inline bool pic_rxready(void)
{ {
if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY) if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY)
return true; return true;
return false; return false;
} }
void write_pic_byte(uint8_t value) void write_pic_byte(uint8_t value)
{ {
/* Wait until the transmitter is ready or 1000us are passed */ /* Wait until the transmitter is ready or 1000us are passed */
waitfor(1000, pic_txready); waitfor(1000, pic_txready);
/* Transmit the byte */ /* Transmit the byte */
*(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit
} }
uint8_t read_pic_byte(void) uint8_t read_pic_byte(void)
{ {
/* Wait until a byte has been received or 1000us are passed */ /* Wait until a byte has been received or 1000us are passed */
waitfor(1000, pic_rxready); waitfor(1000, pic_rxready);
/* Return the received byte */ /* Return the received byte */
return * (volatile uint8_t *) (&MCF_PSC3_PSCTB_8BIT); // Really 8-bit return * (volatile uint8_t *) (&MCF_PSC3_PSCTB_8BIT); // Really 8-bit
} }
void pic_init(void) void pic_init(void)
{ {
char answer[4] = "OLD"; char answer[4] = "OLD";
xprintf("initialize the PIC: "); xprintf("initialize the PIC: ");
/* Send the PIC initialization string */ /* Send the PIC initialization string */
write_pic_byte('A'); write_pic_byte('A');
write_pic_byte('C'); write_pic_byte('C');
write_pic_byte('P'); write_pic_byte('P');
write_pic_byte('F'); write_pic_byte('F');
/* Read the 3-char answer string. Should be "OK!". */ /* Read the 3-char answer string. Should be "OK!". */
answer[0] = read_pic_byte(); answer[0] = read_pic_byte();
answer[1] = read_pic_byte(); answer[1] = read_pic_byte();
answer[2] = read_pic_byte(); answer[2] = read_pic_byte();
answer[3] = '\0'; answer[3] = '\0';
if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!') if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!')
{ {
dbg("PIC initialization failed. Already initialized?\r\n"); dbg("PIC initialization failed. Already initialized?\r\n");
} }
else else
{ {
xprintf("%s\r\n", answer); xprintf("%s\r\n", answer);
} }
} }
void nvram_init(void) void nvram_init(void)
{ {
int i; int i;
xprintf("Restore the NVRAM data: "); xprintf("Restore the NVRAM data: ");
/* Request for NVRAM backup data */ /* Request for NVRAM backup data */
write_pic_byte(0x01); write_pic_byte(0x01);
/* Check answer type */ /* Check answer type */
if (read_pic_byte() != 0x81) if (read_pic_byte() != 0x81)
{ {
// FIXME: PIC protocol error // FIXME: PIC protocol error
xprintf("FAILED\r\n"); xprintf("FAILED\r\n");
return; return;
} }
/* Restore the NVRAM backup to the FPGA */ /* Restore the NVRAM backup to the FPGA */
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
{ {
uint8_t data = read_pic_byte(); uint8_t data = read_pic_byte();
*(volatile uint8_t*)0xffff8961 = i; *(volatile uint8_t*)0xffff8961 = i;
*(volatile uint8_t*)0xffff8963 = data; *(volatile uint8_t*)0xffff8963 = data;
} }
xprintf("finished\r\n"); xprintf("finished\r\n");
} }
#define KBD_ACIA_CONTROL ((uint8_t *) 0xfffffc00) #define KBD_ACIA_CONTROL ((uint8_t *) 0xfffffc00)
@@ -176,77 +176,77 @@ void nvram_init(void)
void acia_init() void acia_init()
{ {
xprintf("init ACIA: "); xprintf("init ACIA: ");
/* init ACIA */ /* init ACIA */
* KBD_ACIA_CONTROL = 3; /* master reset */ * KBD_ACIA_CONTROL = 3; /* master reset */
NOP(); NOP();
* MIDI_ACIA_CONTROL = 3; /* master reset */ * MIDI_ACIA_CONTROL = 3; /* master reset */
NOP(); NOP();
* KBD_ACIA_CONTROL = 0x96; /* clock div = 64, 8N1, RTS low, TX int disable, RX int enable */ * KBD_ACIA_CONTROL = 0x96; /* clock div = 64, 8N1, RTS low, TX int disable, RX int enable */
NOP(); NOP();
* MFP_INTR_IN_SERVICE_A = -1; * MFP_INTR_IN_SERVICE_A = -1;
NOP(); NOP();
* MFP_INTR_IN_SERVICE_B = -1; * MFP_INTR_IN_SERVICE_B = -1;
NOP(); NOP();
xprintf("finished\r\n"); xprintf("finished\r\n");
} }
void enable_coldfire_interrupts() void enable_coldfire_interrupts()
{ {
xprintf("enable interrupts: "); xprintf("enable interrupts: ");
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
*FPGA_INTR_CONTROL = 0L; /* disable all interrupts */ *FPGA_INTR_CONTROL = 0L; /* disable all interrupts */
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */ MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
/* /*
* TIN0 on the Coldfire is connected to the FPGA. TIN0 triggers every write * TIN0 on the Coldfire is connected to the FPGA. TIN0 triggers every write
* access to 0xff8201 (vbasehi), i.e. everytime the video base address is written * access to 0xff8201 (vbasehi), i.e. everytime the video base address is written
*/ */
MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */ MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */
MCF_GPT_GMS_IEN | MCF_GPT_GMS_IEN |
MCF_GPT_GMS_TMS(1); MCF_GPT_GMS_TMS(1); /* route GPT0 interrupt on interrupt controller */
/* route GPT0 interrupt on interrupt controller */ MCF_INTC_ICR62 = MCF_INTC_ICR_IL(7) |
MCF_INTC_ICR62 = 0x3f; /* interrupt level 7, interrupt priority 7 */ MCF_INTC_ICR_IP(7); /* interrupt level 7, interrupt priority 7 */
MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */ MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */
MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */ MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */
MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */ MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */
MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */ MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */
*FPGA_INTR_ENABLE = FPGA_INTR_INT_IRQ7 | *FPGA_INTR_ENABLE = FPGA_INTR_INT_IRQ7 |
FPGA_INTR_INT_MFP_IRQ6 | FPGA_INTR_INT_MFP_IRQ6 |
FPGA_INTR_INT_FPGA_IRQ5 | FPGA_INTR_INT_FPGA_IRQ5 |
FPGA_INTR_INT_VSYNC_IRQ4 | FPGA_INTR_INT_VSYNC_IRQ4 |
FPGA_INTR_INT_CTR0_IRQ3 | FPGA_INTR_INT_CTR0_IRQ3 |
FPGA_INTR_INT_HSYNC_IRQ2 | FPGA_INTR_INT_HSYNC_IRQ2 |
FPGA_INTR_PCI_INTA | FPGA_INTR_PCI_INTA |
FPGA_INTR_PCI_INTB | FPGA_INTR_PCI_INTB |
FPGA_INTR_PCI_INTC | FPGA_INTR_PCI_INTC |
FPGA_INTR_PCI_INTD | FPGA_INTR_PCI_INTD |
FPGA_INTR_ETHERNET; FPGA_INTR_ETHERNET;
#endif #endif
xprintf("finished\r\n"); xprintf("finished\r\n");
} }
void disable_coldfire_interrupts() void disable_coldfire_interrupts()
{ {
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
*FPGA_INTR_ENABLE = 0; /* disable all interrupts */ *FPGA_INTR_ENABLE = 0; /* disable all interrupts */
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
MCF_EPORT_EPIER = 0x0; MCF_EPORT_EPIER = 0x0;
MCF_EPORT_EPFR = 0x0; MCF_EPORT_EPFR = 0x0;
MCF_INTC_IMRL = 0xfffffffe; MCF_INTC_IMRL = 0xfffffffe;
MCF_INTC_IMRH = 0xffffffff; MCF_INTC_IMRH = 0xffffffff;
} }
@@ -261,175 +261,181 @@ NIF nif2;
*/ */
void init_isr(void) 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 the FEC interrupt handler * register the FEC interrupt handler
*/ */
if (!isr_register_handler(64 + INT_SOURCE_FEC0, fec0_interrupt_handler, NULL, (void *) &nif1)) if (!isr_register_handler(64 + INT_SOURCE_FEC0, fec0_interrupt_handler, NULL, (void *) &nif1))
{ {
dbg("unable to register isr for FEC0\r\n"); dbg("unable to register isr for FEC0\r\n");
return; return;
} }
/* /*
* Register the DMA interrupt handler * Register the DMA interrupt handler
*/ */
if (!isr_register_handler(64 + INT_SOURCE_DMA, dma_interrupt_handler, NULL,NULL)) if (!isr_register_handler(64 + INT_SOURCE_DMA, dma_interrupt_handler, NULL,NULL))
{ {
dbg("Error: Unable to register isr for DMA\r\n"); dbg("Error: Unable to register isr for DMA\r\n");
return; return;
} }
dma_irq_enable(5, 3); /* TODO: need to match the FEC driver's specs in MiNT? */ dma_irq_enable(5, 3); /* TODO: need to match the FEC driver's specs in MiNT? */
/* /*
* register the PIC interrupt handler * register the PIC interrupt handler
*/ */
if (isr_register_handler(64 + INT_SOURCE_PSC3, pic_interrupt_handler, NULL, NULL)) if (isr_register_handler(64 + INT_SOURCE_PSC3, pic_interrupt_handler, NULL, NULL))
{ {
dbg("Error: unable to register ISR for PSC3\r\n"); dbg("Error: unable to register ISR for PSC3\r\n");
return; return;
} }
/* /*
* register the XLB PCI interrupt handler * register the XLB PCI interrupt handler
*/ */
if (!isr_register_handler(64 + INT_SOURCE_XLBPCI, xlbpci_interrupt_handler, NULL, NULL)) if (!isr_register_handler(64 + INT_SOURCE_XLBPCI, xlbpci_interrupt_handler, NULL, NULL))
{ {
dbg("Error: unable to register isr for XLB PIC interrupts\r\n"); dbg("Error: unable to register isr for XLB PCI interrupts\r\n");
return; return;
} }
MCF_XLB_XARB_IMR = MCF_XLB_XARB_IMR_SEAE | /* slave error acknowledge interrupt */ MCF_INTC_ICR43 = MCF_INTC_ICR_IL(5) | /* level 5, priority 1 */
MCF_XLB_XARB_IMR_MME | /* multiple master at prio 0 interrupt */ MCF_INTC_ICR_IP(1);
MCF_XLB_XARB_IMR_TTAE | /* TT address only interrupt */
MCF_XLB_XARB_IMR_TTRE | /* TT reserved interrupt enable */
MCF_XLB_XARB_IMR_ECWE | /* external control word interrupt */
MCF_XLB_XARB_IMR_TTME | /* TBST/TSIZ mismatch interrupt */
MCF_XLB_XARB_IMR_BAE; /* bus activity tenure timeout interrupt */
if (!isr_register_handler(64 + INT_SOURCE_PCIARB, pciarb_interrupt_handler, NULL, NULL)) MCF_XLB_XARB_IMR = MCF_XLB_XARB_IMR_SEAE | /* slave error acknowledge interrupt */
{ MCF_XLB_XARB_IMR_MME | /* multiple master at prio 0 interrupt */
dbg("Error: unable to register isr for PCIARB interrupts\r\n"); MCF_XLB_XARB_IMR_TTAE | /* TT address only interrupt */
MCF_XLB_XARB_IMR_TTRE | /* TT reserved interrupt enable */
MCF_XLB_XARB_IMR_ECWE | /* external control word interrupt */
MCF_XLB_XARB_IMR_TTME | /* TBST/TSIZ mismatch interrupt */
MCF_XLB_XARB_IMR_BAE; /* bus activity tenure timeout interrupt */
return; if (!isr_register_handler(64 + INT_SOURCE_PCIARB, pciarb_interrupt_handler, NULL, NULL))
} {
MCF_PCIARB_PACR = MCF_PCIARB_PACR_EXTMINTEN(0x1f) | /* external master broken interrupt */ dbg("Error: unable to register isr for PCIARB interrupts\r\n");
MCF_PCIARB_PACR_INTMINTEN; /* internal master broken interrupt */
return;
}
MCF_INTC_ICR41 = MCF_INTC_ICR_IL(5) | /* level 5, priority 0 */
MCF_INTC_ICR_IP(0);
MCF_PCIARB_PACR = MCF_PCIARB_PACR_EXTMINTEN(0x1f) | /* external master broken interrupt */
MCF_PCIARB_PACR_INTMINTEN; /* internal master broken interrupt */
} }
void BaS(void) void BaS(void)
{ {
uint8_t *src; uint8_t *src;
uint8_t *dst = (uint8_t *) TOS; uint8_t *dst = (uint8_t *) TOS;
#if defined(MACHINE_FIREBEE) /* LITE board has no pic and (currently) no nvram */ #if defined(MACHINE_FIREBEE) /* LITE board has no pic and (currently) no nvram */
pic_init(); pic_init();
nvram_init(); nvram_init();
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
xprintf("copy EmuTOS: "); xprintf("copy EmuTOS: ");
/* copy EMUTOS */ /* copy EMUTOS */
src = (uint8_t *) EMUTOS; src = (uint8_t *) EMUTOS;
dma_memcpy(dst, src, EMUTOS_SIZE); dma_memcpy(dst, src, EMUTOS_SIZE);
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("initialize MMU: "); xprintf("initialize MMU: ");
mmu_init(); mmu_init();
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("initialize exception vector table: "); xprintf("initialize exception vector table: ");
vec_init(); vec_init();
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("flush caches: "); xprintf("flush caches: ");
flush_and_invalidate_caches(); flush_and_invalidate_caches();
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("enable MMU: "); xprintf("enable MMU: ");
MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */ MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */
NOP(); /* force pipeline sync */ NOP(); /* force pipeline sync */
xprintf("finished\r\n"); xprintf("finished\r\n");
#ifdef MACHINE_FIREBEE #ifdef MACHINE_FIREBEE
xprintf("IDE reset: "); xprintf("IDE reset: ");
/* IDE reset */ /* IDE reset */
* (volatile uint8_t *) (0xffff8802 - 2) = 14; * (volatile uint8_t *) (0xffff8802 - 2) = 14;
* (volatile uint8_t *) (0xffff8802 - 0) = 0x80; * (volatile uint8_t *) (0xffff8802 - 0) = 0x80;
wait(1); wait(1);
* (volatile uint8_t *) (0xffff8802 - 0) = 0; * (volatile uint8_t *) (0xffff8802 - 0) = 0;
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("enable video: "); xprintf("enable video: ");
/* /*
* video setup (25MHz) * video setup (25MHz)
*/ */
* (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */ * (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */
* (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */ * (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */
* (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */ * (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */
* (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */ * (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */
/* fifo on, refresh on, ddrcs and cke on, video dac on */ /* fifo on, refresh on, ddrcs and cke on, video dac on */
* (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002; * (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002;
xprintf("finished\r\n"); xprintf("finished\r\n");
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
sd_card_init(); sd_card_init();
/* /*
* memory setup * memory setup
*/ */
memset((void *) 0x400, 0, 0x400); memset((void *) 0x400, 0, 0x400);
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
/* set Falcon bus control register */ /* set Falcon bus control register */
/* sets bit 3 and 6. Both are undefined on an original Falcon? */ /* sets bit 3 and 6. Both are undefined on an original Falcon? */
* (volatile uint8_t *) 0xffff8007 = 0x48; * (volatile uint8_t *) 0xffff8007 = 0x48;
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
/* ST RAM */ /* ST RAM */
* (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */ * (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */
* (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */ * (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */
* (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */ * (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */
* (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */ * (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */
/* TT-RAM */ /* TT-RAM */
* (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */ * (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */
* (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */ * (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */
#if defined(MACHINE_FIREBEE) /* m5484lite has no ACIA and no dip switch... */ #if defined(MACHINE_FIREBEE) /* m5484lite has no ACIA and no dip switch... */
acia_init(); acia_init();
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
srec_execute("BASFLASH.S19"); srec_execute("BASFLASH.S19");
/* Jump into the OS */ /* Jump into the OS */
typedef void void_func(void); typedef void void_func(void);
struct rom_header struct rom_header
{ {
void *initial_sp; void *initial_sp;
void_func *initial_pc; void_func *initial_pc;
}; };
xprintf("BaS initialization finished, enable interrupts\r\n"); xprintf("BaS initialization finished, enable interrupts\r\n");
init_isr(); init_isr();
enable_coldfire_interrupts(); enable_coldfire_interrupts();
init_pci(); init_pci();
video_init(); video_init();
set_ipl(0); /* enable interrupts */ set_ipl(0); /* enable interrupts */
/* initialize USB devices */ /* initialize USB devices */
init_usb(); init_usb();
//set_ipl(7); /* disable interrupts */ //set_ipl(7); /* disable interrupts */
xprintf("call EmuTOS\r\n"); xprintf("call EmuTOS\r\n");
struct rom_header *os_header = (struct rom_header *) TOS; struct rom_header *os_header = (struct rom_header *) TOS;
os_header->initial_pc(); os_header->initial_pc();
} }

View File

@@ -40,9 +40,11 @@
.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
/* PCI interrupt handlers */ /* PCI interrupt handlers */
.extern _irq5_handler .extern _irq5_handler
.extern _irq6_handler
.extern _irq7_handler .extern _irq7_handler
.global _vec_init .global _vec_init
@@ -133,7 +135,7 @@
*/ */
.altmacro .altmacro
.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
@@ -159,6 +161,10 @@ _vec_init:
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
*/
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
@@ -175,7 +181,6 @@ init_vec_loop:
lea access(pc),a1 // set illegal access exception handler lea access(pc),a1 // set illegal access exception handler
move.l a1,0x08(a0) move.l a1,0x08(a0)
.extern _get_bas_drivers
// 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
@@ -467,7 +472,7 @@ irq6: move.w #0x2700,sr // disable interrupt
move.l 4(a6),-(sp) // format status word move.l 4(a6),-(sp) // format status word
move.l 8(a6),-(sp) // pc at exception move.l 8(a6),-(sp) // pc at exception
jsr _irq6_interrupt_handler // call C handler jsr _irq6_handler // call C handler
lea 8(sp),sp // fix stack lea 8(sp),sp // fix stack
tst.l d0 // interrupt handled? tst.l d0 // interrupt handled?

View File

@@ -86,32 +86,34 @@ int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev,
if ((vector == 0) || (handler == NULL)) if ((vector == 0) || (handler == NULL))
{ {
dbg("illegal vector or handler!\r\n"); dbg("illegal vector or handler!\r\n");
return false;
return false;
} }
for (index = 0; index < MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
if (isrtab[index].vector == vector) if (isrtab[index].vector == vector)
{ {
/* one cross each, only! */ /* one cross each, only! */
dbg("already set handler with this vector (%d, %d)\r\n", vector); dbg("already set handler with this vector (%d, %d)\r\n", vector);
return false;
}
if (isrtab[index].vector == 0) return false;
{ }
isrtab[index].vector = vector;
isrtab[index].handler = handler;
isrtab[index].hdev = hdev;
isrtab[index].harg = harg;
return true; if (isrtab[index].vector == 0)
} {
} isrtab[index].vector = vector;
dbg("no available slots to register handler for vector %d\n\r", vector); isrtab[index].handler = handler;
isrtab[index].hdev = hdev;
isrtab[index].harg = harg;
return false; /* no available slots */ return true;
}
}
dbg("no available slots to register handler for vector %d\n\r", vector);
return false; /* no available slots */
} }
void isr_remove_handler(int (*handler)(void *, void *)) void isr_remove_handler(int (*handler)(void *, void *))
@@ -124,19 +126,19 @@ void isr_remove_handler(int (*handler)(void *, void *))
for (index = 0; index < MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
if (isrtab[index].handler == handler) if (isrtab[index].handler == handler)
{ {
memset(&isrtab[index], 0, sizeof(struct isrentry)); memset(&isrtab[index], 0, sizeof(struct isrentry));
return; return;
} }
} }
dbg("no such handler registered (handler=%p\r\n", handler); dbg("no such handler registered (handler=%p\r\n", handler);
} }
/* /*
* This routine searches the ISR table for an entry that matches * This routine searches the ISR table for an entry that matches
* 'vector'. If one is found, then 'handler' is executed. * 'vector'. If one is found, then 'handler' is executed.
*/ */
bool isr_execute_handler(int vector) bool isr_execute_handler(int vector)
{ {
@@ -144,19 +146,19 @@ bool isr_execute_handler(int vector)
bool retval = false; bool retval = false;
/* /*
* locate a BaS Interrupt Service Routine handler. * locate an Interrupt Service Routine handler.
*/ */
for (index = 0; index < MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
if (isrtab[index].vector == vector) if (isrtab[index].vector == vector)
{ {
retval = true; retval = true;
if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg)) if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg))
{ {
return retval; return retval;
} }
} }
} }
dbg("no isr handler for vector %d found\r\n", vector); dbg("no isr handler for vector %d found\r\n", vector);
@@ -176,18 +178,18 @@ int pic_interrupt_handler(void *arg1, void *arg2)
rcv_byte = MCF_PSC3_PSCRB_8BIT; rcv_byte = MCF_PSC3_PSCRB_8BIT;
if (rcv_byte == 2) // PIC requests RTC data if (rcv_byte == 2) // PIC requests RTC data
{ {
uint8_t *rtc_reg = (uint8_t *) 0xffff8961; uint8_t *rtc_reg = (uint8_t *) 0xffff8961;
uint8_t *rtc_data = (uint8_t *) 0xffff8963; uint8_t *rtc_data = (uint8_t *) 0xffff8963;
int index = 0; int index = 0;
xprintf("PIC interrupt: requesting RTC data\r\n"); xprintf("PIC interrupt: requesting RTC data\r\n");
MCF_PSC3_PSCTB_8BIT = 0x82; // header byte to PIC MCF_PSC3_PSCTB_8BIT = 0x82; // header byte to PIC
do do
{ {
*rtc_reg = 0; *rtc_reg = 0;
MCF_PSC3_PSCTB_8BIT = *rtc_data; MCF_PSC3_PSCTB_8BIT = *rtc_data;
} while (index++ < 64); } while (index++ < 64);
} }
return 1; return 1;
} }
@@ -206,6 +208,53 @@ int pciarb_interrupt_handler(void *arg1, void *arg2)
return 1; return 1;
} }
#if defined(MACHINE_FIREBEE)
/*
* This gets called from irq5 in exceptions.S
* Once we arrive here, the SR has been set to disable interrupts and the gcc scratch registers have been saved
*/
int irq5_handler(void *arg1, void *arg2)
{
int32_t handle;
int32_t value = 0;
int32_t newvalue;
err("FPGA_INTR_CONTROL = 0x%08x\r\n", * FPGA_INTR_CONTROL);
err("FPGA_INTR_ENABLE = 0x%08x\r\n", * FPGA_INTR_ENABLE);
err("FPGA_INTR_CLEAR = 0x%08x\r\n", * FPGA_INTR_CLEAR);
err("FPGA_INTR_PENDING = 0x%08x\r\n", * FPGA_INTR_PENDING);
* FPGA_INTR_CLEAR &= ~0x20000000UL; /* clear interrupt from FPGA */
err("\r\nFPGA_INTR_CLEAR = 0x%08x\r\n", * FPGA_INTR_CLEAR);
MCF_EPORT_EPFR |= (1 << 5); /* clear interrupt from edge port */
//xprintf("IRQ5!\r\n");
if ((handle = pci_get_interrupt_cause()) > 0)
{
newvalue = pci_call_interrupt_chain(handle, value);
if (newvalue == value)
{
dbg("interrupt not handled!\r\n");
return 1;
}
}
return 0;
}
int irq6_handler(void *arg1, void *arg2)
{
err("IRQ6!\r\n");
return 0;
}
#else
int irq5_handler(void *arg1, void *arg2)
{
return 0;
}
/* /*
* blink the Firebee's LED to show we are still alive * blink the Firebee's LED to show we are still alive
*/ */
@@ -215,11 +264,11 @@ void blink_led(void)
if ((blinker++ & 0x80) > 0) if ((blinker++ & 0x80) > 0)
{ {
MCF_GPIO_PODR_FEC1L |= (1 << 4); /* LED off */ MCF_GPIO_PODR_FEC1L |= (1 << 4); /* LED off */
} }
else else
{ {
MCF_GPIO_PODR_FEC1L &= ~(1 << 4); /* LED on */ MCF_GPIO_PODR_FEC1L &= ~(1 << 4); /* LED on */
} }
} }
@@ -247,7 +296,7 @@ bool irq6_acsi_dma_interrupt(void)
return false; return false;
} }
bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2) bool irq6_handler(uint32_t sf1, uint32_t sf2)
{ {
bool handled = false; bool handled = false;
@@ -256,51 +305,12 @@ bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2)
if (FALCON_MFP_IPRA || FALCON_MFP_IPRB) if (FALCON_MFP_IPRA || FALCON_MFP_IPRB)
{ {
blink_led(); blink_led();
} }
return handled; return handled;
} }
#if defined(MACHINE_FIREBEE)
/*
* This gets called from irq5 in exceptions.S
* Once we arrive here, the SR has been set to disable interrupts and the gcc scratch registers have been saved
*/
int irq5_handler(void *arg1, void *arg2)
{
int32_t handle;
int32_t value = 0;
int32_t newvalue;
err("FPGA_INTR_CONTROL = 0x%08x\r\n", * FPGA_INTR_CONTROL);
err("FPGA_INTR_ENABLE = 0x%08x\r\n", * FPGA_INTR_ENABLE);
err("FPGA_INTR_CLEAR = 0x%08x\r\n", * FPGA_INTR_CLEAR);
err("FPGA_INTR_PENDING = 0x%08x\r\n", * FPGA_INTR_PENDING);
* FPGA_INTR_CLEAR &= ~0x20000000UL; /* clear interrupt from FPGA */
err("\r\nFPGA_INTR_CLEAR = 0x%08x\r\n", * FPGA_INTR_CLEAR);
MCF_EPORT_EPFR |= (1 << 5); /* clear interrupt from edge port */
//xprintf("IRQ5!\r\n");
if ((handle = pci_get_interrupt_cause()) > 0)
{
newvalue = pci_call_interrupt_chain(handle, value);
if (newvalue == value)
{
dbg("interrupt not handled!\r\n");
return 1;
}
}
return 0;
}
#else
int irq5_handler(void *arg1, void *arg2)
{
;
}
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
#ifdef MACHINE_M5484LITE #ifdef MACHINE_M5484LITE
@@ -318,11 +328,11 @@ void irq7_handler(void)
dbg("IRQ7!\r\n"); dbg("IRQ7!\r\n");
if ((handle = pci_get_interrupt_cause()) > 0) if ((handle = pci_get_interrupt_cause()) > 0)
{ {
newvalue = pci_call_interrupt_chain(handle, value); newvalue = pci_call_interrupt_chain(handle, value);
if (newvalue == value) if (newvalue == value)
{ {
dbg("interrupt not handled!\r\n"); dbg("interrupt not handled!\r\n");
} }
} }
} }
#endif /* MACHINE_M548X */ #endif /* MACHINE_M548X */
@@ -333,8 +343,9 @@ void irq7_handler(void)
#define vbaselow (* (volatile uint8_t *) 0xffff820d) #define vbaselow (* (volatile uint8_t *) 0xffff820d)
#define vwrap (* (volatile uint16_t *) 0xffff8210) #define vwrap (* (volatile uint16_t *) 0xffff8210)
#define vde (* (volatile uint16_t *) 0xffff82aa) #define vde (* (volatile uint16_t *) 0xffff82aa)
#define vdb (* (volatile uint16_t *) 0xffff82a8) #define vdb (* (volatile uint16_t *) 0xffff82a8)
/* /*
* this is the higlevel interrupt service routine for gpt0 timer interrupts. * this is the higlevel interrupt service routine for gpt0 timer interrupts.
* *