did more changes to interrupt code, but still crashes in networking

This commit is contained in:
Markus Fröschle
2015-01-10 17:19:56 +00:00
parent cb5bd09713
commit b56f40fc98
13 changed files with 884 additions and 796 deletions

View File

@@ -63,10 +63,6 @@ write 0xFF000104 0x710D0F00 4 # SDCR (lock SDMR and enable refresh)
sleep 100 sleep 100
load -v firebee/ram.elf load -v firebee/ram.elf
write-ctrl 0x80e 0x2700
write-ctrl 0x2 0xa50c8120
dump-register SR
dump-register CACR
dump-register MBAR
execute execute
wait wait

View File

@@ -665,6 +665,7 @@ void *dma_memcpy(void *dst, void *src, size_t n)
int dma_init(void) int dma_init(void)
{ {
int i;
int res; int res;
dbg("MCD DMA API initialization: "); dbg("MCD DMA API initialization: ");
@@ -675,6 +676,15 @@ int dma_init(void)
return 0; return 0;
} }
/*
* make sure dma_channel array is properly initialized
*/
for (i = 0; i < NCHANNELS; i++)
{
dma_channel[i].req = -1;
dma_channel[i].handler = NULL;
}
// test // test
dma_memcpy((void *) 0x10000, (void *) 0x03e00000, 0x00100000); /* copy one megabyte of flash to RAM */ dma_memcpy((void *) 0x10000, (void *) 0x03e00000, 0x00100000); /* copy one megabyte of flash to RAM */

View File

@@ -12,8 +12,9 @@
/* /*
* Turn Execution Unit tasks ON (#define) or OFF (#undef) * Turn Execution Unit tasks ON (#define) or OFF (#undef)
*/ */
#undef MCD_INCLUDE_EU
//#define MCD_INCLUDE_EU //#define MCD_INCLUDE_EU
#undef MCD_INCLUDE_EU
/* /*
* Number of DMA channels * Number of DMA channels

View File

@@ -107,7 +107,6 @@
#define MCF_INTC_LIACK(x) (*(volatile uint8_t *)(&_MBAR[0x7E4 + ((x-1)*0x4)])) #define MCF_INTC_LIACK(x) (*(volatile uint8_t *)(&_MBAR[0x7E4 + ((x-1)*0x4)]))
/* Bit definitions and macros for MCF_INTC_IPRH */ /* Bit definitions and macros for MCF_INTC_IPRH */
#define MCF_INTC_IPRH_INT32 (0x1) #define MCF_INTC_IPRH_INT32 (0x1)
#define MCF_INTC_IPRH_INT33 (0x2) #define MCF_INTC_IPRH_INT33 (0x2)

View File

@@ -26,10 +26,6 @@
#include "MCD_dma.h" #include "MCD_dma.h"
#include "bas_string.h" #include "bas_string.h"
#define DMA_INTC_LVL 5
#define DMA_INTC_PRI 3
void *dma_memcpy(void *dst, void *src, size_t n); void *dma_memcpy(void *dst, void *src, size_t n);
extern int dma_init(void); extern int dma_init(void);
extern int dma_get_channel(int requestor); extern int dma_get_channel(int requestor);

View File

@@ -80,7 +80,8 @@ struct xhdi_driver_interface
uint32_t (*xhdivec)(); uint32_t (*xhdivec)();
}; };
/* Interpretation of offset for color fields: All offsets are from the right, /*
* Interpretation of offset for color fields: All offsets are from the right,
* inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
* can use the offset as right argument to <<). A pixel afterwards is a bit * can use the offset as right argument to <<). A pixel afterwards is a bit
* stream and is written to video memory as that unmodified. This implies * stream and is written to video memory as that unmodified. This implies
@@ -207,11 +208,12 @@ struct framebuffer_driver_interface
struct fb_info **framebuffer_info; /* pointer to an fb_info struct (defined in include/fb.h) */ struct fb_info **framebuffer_info; /* pointer to an fb_info struct (defined in include/fb.h) */
}; };
struct pci_bios_interface { struct pci_bios_interface
{
uint32_t subjar; uint32_t subjar;
uint32_t version; uint32_t version;
/* Although we declare this functions as standard gcc functions (cdecl), /* Although we declare this functions as standard gcc functions (cdecl),
* they expect paramenters inside registers (fastcall) unsupported by gcc m68k. * they expect parameters inside registers (fastcall) unsupported by gcc m68k.
* Caller will take care of parameters passing convention. * Caller will take care of parameters passing convention.
*/ */
int32_t (*find_pci_device)(uint32_t id, uint16_t index); int32_t (*find_pci_device)(uint32_t id, uint16_t index);

View File

@@ -145,7 +145,9 @@
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
extern void isr_init(void); extern void isr_init(void);
extern int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg); extern bool isr_set_prio_and_level(int int_source, int priority, int level);
extern bool isr_enable_int_source(int int_source);
extern bool isr_register_handler(int vector, int level, int priority, int (*handler)(void *, void *), void *hdev, void *harg);
extern void isr_remove_handler(int (*handler)(void *, void *)); extern void isr_remove_handler(int (*handler)(void *, void *));
extern bool isr_execute_handler(int vector); extern bool isr_execute_handler(int vector);
extern int pic_interrupt_handler(void *arg1, void *arg2); extern int pic_interrupt_handler(void *arg1, void *arg2);

View File

@@ -158,7 +158,7 @@ bool timer_init(uint8_t ch, uint8_t lvl, uint8_t pri)
/* /*
* Register the timer interrupt handler * Register the timer interrupt handler
*/ */
if (!isr_register_handler(TIMER_VECTOR(ch), if (!isr_register_handler(TIMER_VECTOR(ch), 3, 0,
(int (*)(void *,void *)) timer_default_isr, (int (*)(void *,void *)) timer_default_isr,
NULL, NULL,
(void *) &net_timer[ch]) (void *) &net_timer[ch])

View File

@@ -186,28 +186,28 @@ void nvram_init(void)
xprintf("finished\r\n"); xprintf("finished\r\n");
} }
#define KBD_ACIA_CONTROL ((uint8_t *) 0xfffffc00) #define KBD_ACIA_CONTROL * ((uint8_t *) 0xfffffc00)
#define MIDI_ACIA_CONTROL ((uint8_t *) 0xfffffc04) #define MIDI_ACIA_CONTROL * ((uint8_t *) 0xfffffc04)
#define MFP_INTR_IN_SERVICE_A ((uint8_t *) 0xfffffa0f) #define MFP_INTR_IN_SERVICE_A * ((uint8_t *) 0xfffffa0f)
#define MFP_INTR_IN_SERVICE_B ((uint8_t *) 0xfffffa11) #define MFP_INTR_IN_SERVICE_B * ((uint8_t *) 0xfffffa11)
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 = 0xff;
NOP(); NOP();
* MFP_INTR_IN_SERVICE_B = -1; MFP_INTR_IN_SERVICE_B = 0xff;
NOP(); NOP();
xprintf("finished\r\n"); xprintf("finished\r\n");
@@ -280,7 +280,7 @@ void init_isr(void)
/* /*
* 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, 7, 6, fec0_interrupt_handler, NULL, (void *) &nif1))
{ {
err("unable to register isr for FEC0\r\n"); err("unable to register isr for FEC0\r\n");
} }
@@ -289,13 +289,11 @@ void init_isr(void)
* 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, 7, 7, dma_interrupt_handler, NULL, NULL))
{ {
err("Error: Unable to register isr for DMA\r\n"); err("Error: Unable to register isr for DMA\r\n");
} }
dma_irq_enable(7, 7); /* TODO: need to match the FEC driver's specs in MiNT? */
#ifdef _NOT_USED_ #ifdef _NOT_USED_
/* /*
* register the PIC interrupt handler * register the PIC interrupt handler
@@ -356,6 +354,8 @@ void BaS(void)
xprintf("copy EmuTOS: "); xprintf("copy EmuTOS: ");
dma_init();
/* copy EMUTOS */ /* copy EMUTOS */
src = (uint8_t *) EMUTOS; src = (uint8_t *) EMUTOS;
dma_memcpy(dst, src, EMUTOS_SIZE); dma_memcpy(dst, src, EMUTOS_SIZE);
@@ -441,7 +441,7 @@ void BaS(void)
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();
/* initialize USB devices */ /* initialize USB devices */

View File

@@ -238,7 +238,7 @@ init_vec_loop:
move.l a1,(INT_SOURCE_XLBPCI + 64) * 4(a0) move.l a1,(INT_SOURCE_XLBPCI + 64) * 4(a0)
#ifndef MACHINE_FIREBEE #ifndef MACHINE_FIREBEE
// FEC1 not wired on the FireBee (used for FPGA as GPIO), but used 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
@@ -430,15 +430,18 @@ irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector
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
* - 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 4(a6),-(sp) // format status word move.l 8(a6),-(sp) // format status word
move.l 8(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
@@ -563,25 +566,53 @@ irq7text:
/* /*
* low-level interrupt service routine for routines registered with * low-level interrupt service routine for routines registered with
* isr_register_handler() * isr_register_handler(int vector). If the higlevel routine (isr_execute_handler())
* returns != 0, 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
/*
* stack format (after link instruction) is like this:
*
* +12 program counter (return address)
* +8 format_status
* +4 save area for rts (if we need to jump through the OS vector)
* (a6) -> saved a6 (from link)
* -4
* -8
* -12
* (sp) -> gcc scratch registers save area
*/
_lowlevel_isr_handler: _lowlevel_isr_handler:
move.w #0x2700,sr // do not disturb 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 handled by gcc itself // other registers will be taken care of by gcc itself
move.w 4(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.l d0 // handled?
bne lowlevel_forward // no, we 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
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
movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 //
rts // jump through vector

View File

@@ -37,9 +37,6 @@
#include "dma.h" #include "dma.h"
#include "pci.h" #include "pci.h"
extern void (*rt_vbr[])(void);
#define VBR rt_vbr
#define IRQ_DEBUG #define IRQ_DEBUG
#if defined(IRQ_DEBUG) #if defined(IRQ_DEBUG)
#define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0)
@@ -72,6 +69,51 @@ void isr_init(void)
memset(isrtab, 0, sizeof(isrtab)); memset(isrtab, 0, sizeof(isrtab));
} }
bool isr_set_prio_and_level(int int_source, int priority, int level)
{
if (int_source > 8 && int_source <= 62)
{
/*
* preset interrupt control registers with level and priority
*/
MCF_INTC_ICR(int_source) = MCF_INTC_ICR_IP(priority) |
MCF_INTC_ICR_IL(level);
}
else if (int_source >= 1 && int_source <= 8)
{
dbg("interrrupt control register for vector %d is read only!\r\n");
}
else
{
err("invalid vector - interrupt control register not set.\r\n");
return false;
}
return true;
}
/*
* enable internal int source in DMA controller
*/
bool isr_enable_int_source(int int_source)
{
if (int_source < 32 && int_source > 0)
{
MCF_INTC_IMRL &= ~(1 << int_source);
}
else if (int_source >= 32 && int_source <= 62)
{
MCF_INTC_IMRH &= ~(1 << (int_source - 32));
}
else
{
err("vector %d does not correspond to an internal interrupt source\r\n");
return false;
}
return true;
}
/* /*
* This function places an interrupt handler in the ISR table, * This function places an interrupt handler in the ISR table,
* thereby registering it so that the low-level handler may call it. * thereby registering it so that the low-level handler may call it.
@@ -80,9 +122,10 @@ void isr_init(void)
* pointer to the device itself, and the second a pointer to a data * pointer to the device itself, and the second a pointer to a data
* structure used by the device driver for that particular device. * structure used by the device driver for that particular device.
*/ */
int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg) bool isr_register_handler(int vector, int level, int priority, int (*handler)(void *, void *), void *hdev, void *harg)
{ {
int index; int index;
int int_source;
if ((vector == 0) || (handler == NULL)) if ((vector == 0) || (handler == NULL))
{ {
@@ -108,6 +151,20 @@ int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev,
isrtab[index].hdev = hdev; isrtab[index].hdev = hdev;
isrtab[index].harg = harg; isrtab[index].harg = harg;
int_source = vector - 64;
if (!isr_enable_int_source(int_source))
{
err("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);
return false;
}
return true; return true;
} }
} }
@@ -145,24 +202,19 @@ bool isr_execute_handler(int vector)
int index; int index;
bool retval = false; bool retval = false;
dbg("vector = 0x%x\r\n", vector); dbg("vector = %d\r\n", vector);
/* /*
* locate an 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; return isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg);
if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg))
{
return retval;
} }
} }
} err("no isr handler for vector %d found. Spurious?\r\n", vector);
dbg("no isr handler for vector %d found\r\n", vector);
return retval; return retval;
} }

View File

@@ -1117,7 +1117,6 @@ void initialize_hardware(void)
#if MACHINE_FIREBEE #if MACHINE_FIREBEE
init_ac97(); init_ac97();
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
dma_init();
/* jump into the BaS */ /* jump into the BaS */
extern void BaS(void); extern void BaS(void);