still target aborts

This commit is contained in:
Markus Fröschle
2013-11-10 18:11:33 +00:00
parent 7995c466b0
commit 0c1ea5b610
5 changed files with 97 additions and 45 deletions

View File

@@ -36,6 +36,7 @@ SECTIONS
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
OBJDIR/wait.o(.text) OBJDIR/wait.o(.text)
OBJDIR/exceptions.o(.text) OBJDIR/exceptions.o(.text)
OBJDIR/interrupts.o(.text)
OBJDIR/illegal_instruction.o(.text) OBJDIR/illegal_instruction.o(.text)
OBJDIR/supervisor.o(.text) OBJDIR/supervisor.o(.text)
OBJDIR/mmu.o(.text) OBJDIR/mmu.o(.text)

View File

@@ -77,4 +77,5 @@
#define INT_SOURCE_GPT0 62 // GPT0 timer interrupt #define INT_SOURCE_GPT0 62 // GPT0 timer interrupt
extern int register_interrupt_handler(uint8_t priority, uint8_t intr, void (*func)());
#endif /* _INTERRUPTS_H_ */ #endif /* _INTERRUPTS_H_ */

View File

@@ -27,36 +27,39 @@
#include "bas_utils.h" #include "bas_utils.h"
#include "interrupts.h" #include "interrupts.h"
extern uint8_t _rtl_vbr[]; extern uint32_t rt_vbr[];
#define VBR ((uint32_t **) &_rtl_vbr[0]) #define VBR rt_vbr
/* /*
* register an interrupt handler at the Coldfire interrupt controller and add the handler to the interrupt vector table * register an interrupt handler at the Coldfire interrupt controller and add the handler to
* the interrupt vector table
*/ */
int register_handler(uint8_t priority, uint8_t intr, void (*func)()) int register_interrupt_handler(uint8_t priority, uint8_t source, void (*func)())
{ {
int i; int i;
uint8_t level = 0b01111111; uint8_t level = 0b01111111;
uint32_t **adr = VBR; uint32_t **adr = &VBR[0];
intr &= 63; source &= 63;
priority &= 7; priority &= 7;
if (intr <= 0) if (source <= 0)
return -1; return -1;
for (i = 1; i < 64; i++) for (i = 1; i < 64; i++)
if (i != intr) {
if (i != source)
{ {
if ((MCF_INTC_ICR(i) & 7) == priority) if ((MCF_INTC_ICR(i) & 7) == priority)
CLEAR_BIT_NO(level, (MCF_INTC_ICR(i) >> 3) & 7); CLEAR_BIT_NO(level, (MCF_INTC_ICR(i) >> 3) & 7);
} }
}
for (i = 0; 1 < 7; i++) for (i = 0; i <= 7; i++)
if (level & (1 << i)) if (level & (1 << i))
break; break;
if (i >= 7) if (i > 7)
return -1; return -1;
/* /*
@@ -64,39 +67,35 @@ int register_handler(uint8_t priority, uint8_t intr, void (*func)())
*/ */
__asm__ volatile ( __asm__ volatile (
"move.w sr,d0\n\t" "move.w sr,d0\n\t"
"move.w d0,-(sp) \n\t" "move.w d0,srsave \n\t"
"move.w #0x2700,sr\n\t" "move.w #0x2700,sr\n\t"
" .data\n\t"
"srsave: ds.w 1\n\t"
" .text\n\t"
: :
: :
: "sp","d0","memory" : "d0","memory"
); );
if (intr < 32) if (source < 32)
CLEAR_BIT(MCF_INTC_IMRL, (1 << intr)); CLEAR_BIT(MCF_INTC_IMRL, (1 << source));
else else
CLEAR_BIT(MCF_INTC_IMRH, (1 << (intr - 32))); CLEAR_BIT(MCF_INTC_IMRH, (1 << (source - 32)));
MCF_INTC_ICR(intr) = MCF_INTC_ICR_IP(priority) | MCF_INTC_ICR_IL(i); MCF_INTC_ICR(source) = MCF_INTC_ICR_IP(priority) | MCF_INTC_ICR_IL(i);
adr[64 + intr] = (uint32_t *) func; /* first 64 vectors are system exceptions */ adr[64 + source] = (uint32_t *) func; /* first 64 vectors are system exceptions */
/* /*
* Return the saved priority level * Return the saved priority level
*/ */
__asm__ volatile ( __asm__ volatile (
"move.w (sp)+,d2\n\t" "move.w srsave,d2\n\t"
"move.w d2,sr\n\t" "move.w d2,sr\n\t"
: :
: :
: "sp","d2","memory" : "d2","memory"
); );
return 0; return 0;
} }
__attribute__((interrupt)) void pci_arb_interrupt(void)
{
xprintf("XLBARB slave error interrupt\r\n");
MCF_XLB_XARB_SR |= ~MCF_XLB_XARB_SR_SEA;
}

View File

@@ -30,6 +30,7 @@
#include "bas_printf.h" #include "bas_printf.h"
#include "bas_string.h" #include "bas_string.h"
#include "util.h" #include "util.h"
#include "interrupts.h"
#include "wait.h" #include "wait.h"
#define pci_config_wait() wait(10000); /* FireBee USB not properly detected otherwise */ #define pci_config_wait() wait(10000); /* FireBee USB not properly detected otherwise */
@@ -173,7 +174,7 @@ uint32_t pci_read_config_longword(int32_t handle, int offset)
value = * (volatile uint32_t *) PCI_IO_OFFSET; /* access device */ value = * (volatile uint32_t *) PCI_IO_OFFSET; /* access device */
/* finish PCI configuration access special cycle (allow regular PCI accesses) */ /* finish PCI configuration access special cycle (allow regular PCI accesses) */
MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; //MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E;
pci_config_wait(); pci_config_wait();
@@ -222,7 +223,7 @@ int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t value)
pci_config_wait(); pci_config_wait();
/* finish configuration space access cycle */ /* finish configuration space access cycle */
MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; //MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E;
pci_config_wait(); pci_config_wait();
return PCI_SUCCESSFUL; return PCI_SUCCESSFUL;
@@ -345,8 +346,8 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
struct pci_rd *descriptors; struct pci_rd *descriptors;
int i; int i;
uint32_t value; uint32_t value;
static uint32_t mem_address = 0; static uint32_t mem_address = PCI_MEMORY_OFFSET;
static uint32_t io_address = 0; static uint32_t io_address = PCI_IO_OFFSET;
/* determine pci handle from bus, device + function number */ /* determine pci handle from bus, device + function number */
handle = PCI_HANDLE(bus, device, function); handle = PCI_HANDLE(bus, device, function);
@@ -372,7 +373,7 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
/* /*
* write all bits of BAR[i] * write all bits of BAR[i]
*/ */
pci_write_config_longword(handle, 0x10 + i, 0xffffffff); pci_write_config_longword(handle, PCIBAR0 + i, 0xffffffff);
/* /*
* read back value to see which bits have been set * read back value to see which bits have been set
@@ -390,7 +391,7 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
{ {
/* adjust base address to card's alignment requirements */ /* adjust base address to card's alignment requirements */
int size = ~(address & 0xfffffff0) + 1; int size = ~(address & 0xfffffff0) + 1;
xprintf("device 0x%x: BAR[%d] requests %d kBytes of memory\r\n", handle, i, size / 1024); xprintf("device 0x%x: BAR[%d] requests %d bytes of memory\r\n", handle, i, size);
/* calculate a valid map adress with alignment requirements */ /* calculate a valid map adress with alignment requirements */
address = (mem_address + size - 1) & ~(size - 1); address = (mem_address + size - 1) & ~(size - 1);
@@ -399,17 +400,17 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
pci_write_config_longword(handle, PCIBAR0 + i, swpl(address)); pci_write_config_longword(handle, PCIBAR0 + i, swpl(address));
/* read it back, just to be sure */ /* read it back, just to be sure */
value = swpl(pci_read_config_longword(handle, PCIBAR0 + i)); value = swpl(pci_read_config_longword(handle, PCIBAR0 + i)) & ~1;
xprintf("set PCIBAR%d on device 0x%02x to 0x%08x\r\n", xprintf("set PCIBAR%d on device 0x%02x to 0x%08x\r\n",
i, handle, value); i, handle, value);
/* fill resource descriptor */ /* fill resource descriptor */
rd->next = sizeof(struct pci_rd); rd->next = sizeof(struct pci_rd);
rd->flags = 0 | FLG_8BIT | FLG_16BIT | FLG_32BIT; rd->flags = 0 | FLG_32BIT | FLG_16BIT | FLG_8BIT | 2; /* little endian, lane swapped */
rd->start = address; rd->start = address;
rd->length = size; rd->length = size;
rd->offset = PCI_MEMORY_OFFSET; rd->offset = 0;
rd->dmaoffset = 0; rd->dmaoffset = 0;
/* adjust memory adress for next turn */ /* adjust memory adress for next turn */
@@ -421,7 +422,7 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
else if (IS_PCI_IO_BAR(value)) /* same as above for I/O resources */ else if (IS_PCI_IO_BAR(value)) /* same as above for I/O resources */
{ {
int size = ~(address & 0xfffffffc) + 1; int size = ~(address & 0xfffffffc) + 1;
xprintf("device 0x%x: BAR[%d] requests %d bytes of memory\r\n", handle, i, size); xprintf("device 0x%x: BAR[%d] requests %d bytes of I/O space\r\n", handle, i, size);
address = (io_address + size - 1) & ~(size - 1); address = (io_address + size - 1) & ~(size - 1);
pci_write_config_longword(handle, PCIBAR0 + i, swpl(address)); pci_write_config_longword(handle, PCIBAR0 + i, swpl(address));
@@ -431,9 +432,9 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
i, handle, value); i, handle, value);
rd->next = sizeof(struct pci_rd); rd->next = sizeof(struct pci_rd);
rd->flags = FLG_IO | FLG_8BIT | FLG_16BIT | FLG_32BIT | 1; rd->flags = FLG_IO | FLG_8BIT | FLG_16BIT | FLG_32BIT | 2;
rd->start = address; rd->start = address;
rd->offset = PCI_IO_OFFSET; rd->offset = 0;
rd->length = size; rd->length = size;
rd->dmaoffset = 0; rd->dmaoffset = 0;
@@ -451,13 +452,29 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
* enable device finally * enable device finally
*/ */
value = swpl(pci_read_config_longword(handle, PCICSR)); value = swpl(pci_read_config_longword(handle, PCICSR));
value |= 0xffff035f; xprintf("device 0x%02x PCICSR = 0x%08x\r\n", handle, value);
value = 0xffff0146;
pci_write_config_longword(handle, PCICSR, swpl(value)); pci_write_config_longword(handle, PCICSR, swpl(value));
value = swpl(pci_read_config_longword(handle, PCICSR)); value = swpl(pci_read_config_longword(handle, PCICSR));
xprintf("device 0x%02x PCICSR = 0x%08x\r\n", handle, value); xprintf("device 0x%02x PCICSR = 0x%08x\r\n", handle, value);
} }
static void pci_bridge_config(uint16_t bus, uint16_t device, uint16_t function)
{
int32_t handle;
if (function != 0)
{
xprintf("trying to configure a multi-function bridge. Cancelled\r\n");
return;
}
handle = PCI_HANDLE(bus, device, function);
pci_write_config_longword(handle, PCIBAR0, 0x40000000);
pci_write_config_longword(handle, PCIBAR1, 0x0);
pci_write_config_longword(handle, PCICSR, 0x146);
}
/* /*
* scan PCI bus and display devices found. Create a handle for each device and call pci_device_config() for it * scan PCI bus and display devices found. Create a handle for each device and call pci_device_config() for it
*/ */
@@ -494,6 +511,12 @@ void pci_scan(void)
PCI_DEVICE_FROM_HANDLE(handle), PCI_DEVICE_FROM_HANDLE(handle),
PCI_FUNCTION_FROM_HANDLE(handle)); PCI_FUNCTION_FROM_HANDLE(handle));
} }
else
{
pci_bridge_config(PCI_BUS_FROM_HANDLE(handle),
PCI_DEVICE_FROM_HANDLE(handle),
PCI_FUNCTION_FROM_HANDLE(handle));
}
handle = pci_find_device(0x0, 0xFFFF, ++index); handle = pci_find_device(0x0, 0xFFFF, ++index);
} }
@@ -545,9 +568,30 @@ void init_xlbus_arbiter(void)
MCF_XLB_XARB_BUSTO = 0xffffff; MCF_XLB_XARB_BUSTO = 0xffffff;
} }
__attribute__((interrupt)) void pci_arb_interrupt(void)
{
xprintf("XLBARB slave error interrupt\r\n");
MCF_XLB_XARB_SR |= ~MCF_XLB_XARB_SR_SEA;
}
__attribute__((interrupt)) void xlb_pci_interrupt(void)
{
xprintf("XLBPCI interrupt\r\n");
}
void init_pci(void) void init_pci(void)
{ {
xprintf("initializing PCI bridge:"); int res;
xprintf("initializing PCI bridge:\r\n");
res = register_interrupt_handler(0, INT_SOURCE_PCIARB, pci_arb_interrupt);
xprintf("registered interrupt handler for PCI arbiter: %s\r\n",
(res < 0 ? "failed" : "succeeded"));
register_interrupt_handler(0, INT_SOURCE_XLBPCI, xlb_pci_interrupt);
xprintf("registered interrupt handler for XLB PCI: %s\r\n",
(res < 0 ? "failed" : "succeeded"));
init_eport(); init_eport();
init_xlbus_arbiter(); init_xlbus_arbiter();
@@ -556,7 +600,7 @@ void init_pci(void)
* setup the PCI arbiter * setup the PCI arbiter
*/ */
MCF_PCIARB_PACR = MCF_PCIARB_PACR_INTMPRI /* internal master priority: high */ MCF_PCIARB_PACR = MCF_PCIARB_PACR_INTMPRI /* internal master priority: high */
| MCF_PCIARB_PACR_EXTMPRI(0x1F) /* external master priority: high */ | MCF_PCIARB_PACR_EXTMPRI(0x4) /* external master priority: high */
| MCF_PCIARB_PACR_INTMINTEN /* enable "internal master broken" interrupt */ | MCF_PCIARB_PACR_INTMINTEN /* enable "internal master broken" interrupt */
| MCF_PCIARB_PACR_EXTMINTEN(0x1F); /* enable "external master broken" interrupt */ | MCF_PCIARB_PACR_EXTMINTEN(0x1F); /* enable "external master broken" interrupt */
@@ -591,7 +635,9 @@ void init_pci(void)
/* initiator window 0 base / translation adress register */ /* initiator window 0 base / translation adress register */
MCF_PCI_PCIIW0BTAR = (PCI_MEMORY_OFFSET | (((PCI_MEMORY_SIZE - 1) >> 8) & 0xffff0000)) MCF_PCI_PCIIW0BTAR = (PCI_MEMORY_OFFSET | (((PCI_MEMORY_SIZE - 1) >> 8) & 0xffff0000))
| PCI_MEMORY_OFFSET >> 16; | ((PCI_MEMORY_OFFSET >> 16) & 0xff00);
xprintf("PCIIW0BTAR=0x%08x\r\n", MCF_PCI_PCIIW0BTAR);
/* initiator window 1 base / translation adress register */ /* initiator window 1 base / translation adress register */
MCF_PCI_PCIIW1BTAR = (PCI_IO_OFFSET | ((PCI_IO_SIZE - 1) >> 8)) & 0xffff0000; MCF_PCI_PCIIW1BTAR = (PCI_IO_OFFSET | ((PCI_IO_SIZE - 1) >> 8)) & 0xffff0000;
@@ -600,11 +646,14 @@ void init_pci(void)
MCF_PCI_PCIIW2BTAR = 0L; /* not used */ MCF_PCI_PCIIW2BTAR = 0L; /* not used */
/* initiator window configuration register */ /* initiator window configuration register */
MCF_PCI_PCIIWCR = MCF_PCI_PCIIWCR_WINCTRL0_MEMRDLINE | MCF_PCI_PCIIWCR_WINCTRL1_IO; MCF_PCI_PCIIWCR = MCF_PCI_PCIIWCR_WINCTRL0_MEMRDLINE |
MCF_PCI_PCIIWCR_WINCTRL1_IO |
MCF_PCI_PCIIWCR_WINCTRL0_E |
MCF_PCI_PCIIWCR_WINCTRL1_E;
/* initialize target control register */ /* initialize target control register */
MCF_PCI_PCIBAR0 = 0x40000000; /* 256 kB window */ MCF_PCI_PCIBAR0 = 0x40000000; /* 256 kB window */
MCF_PCI_PCITBATR0 = (uint32_t) &_MBAR[0] + MCF_PCI_PCITBATR0_EN; /* target base address translation register 0 */ MCF_PCI_PCITBATR0 = (uint32_t) &_MBAR[0] | MCF_PCI_PCITBATR0_EN; /* target base address translation register 0 */
MCF_PCI_PCIBAR1 = 0; /* 1GB window */ MCF_PCI_PCIBAR1 = 0; /* 1GB window */
MCF_PCI_PCITBATR1 = MCF_PCI_PCITBATR1_EN; MCF_PCI_PCITBATR1 = MCF_PCI_PCITBATR1_EN;
@@ -627,4 +676,6 @@ void init_pci(void)
xprintf("PCIGSCR=0x%08x, PCISCR=0x%08x\r\n", MCF_PCI_PCIGSCR, MCF_PCI_PCISCR); xprintf("PCIGSCR=0x%08x, PCISCR=0x%08x\r\n", MCF_PCI_PCIGSCR, MCF_PCI_PCISCR);
MCF_PCI_PCISCR |= 0xffff035f; /* clear all error flags */ MCF_PCI_PCISCR |= 0xffff035f; /* clear all error flags */
xprintf("PCIGSCR=0x%08x, PCISCR=0x%08x\r\n", MCF_PCI_PCIGSCR, MCF_PCI_PCISCR); xprintf("PCIGSCR=0x%08x, PCISCR=0x%08x\r\n", MCF_PCI_PCIGSCR, MCF_PCI_PCISCR);
xprintf("XARB_SR=0x%08x\r\n", MCF_XLB_XARB_SR);
} }

View File

@@ -260,7 +260,7 @@ void init_serial(void)
MCF_PSC3_PSCCR = 0x05; MCF_PSC3_PSCCR = 0x05;
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
MCF_INTC_ICR32 = 0x3F; //MAXIMALE PRIORITY/**********/ //MCF_INTC_ICR32 = 0x3F; //MAXIMALE PRIORITY/**********/
xprintf("\r\nserial interfaces initialization: finished\r\n"); xprintf("\r\nserial interfaces initialization: finished\r\n");
} }