fixed wrong stack address offset for "magic number"

This commit is contained in:
Markus Fröschle
2014-09-30 19:29:46 +00:00
parent 66dff57624
commit b857519ea5
4 changed files with 311 additions and 500 deletions

View File

@@ -37,7 +37,7 @@
*/
static struct xhdi_driver_interface xhdi_call_interface =
{
xhdi_call
xhdi_call
};
/*
@@ -47,27 +47,27 @@ static struct xhdi_driver_interface xhdi_call_interface =
*/
static struct dma_driver_interface dma_interface =
{
.version = 0x0101,
.magic = 0x444d4143, /* 'DMAC' */
.dma_set_initiator = dma_set_initiator,
.dma_get_initiator = dma_get_initiator,
.dma_free_initiator = dma_free_initiator,
.dma_set_channel = dma_set_channel,
.dma_get_channel = dma_get_channel,
.dma_free_channel = dma_free_channel,
.dma_clear_channel = dma_clear_channel,
.MCD_startDma = (int (*)(long, int8_t *, unsigned int, int8_t *, unsigned int,
unsigned int, unsigned int, unsigned int, int,
unsigned int, unsigned int)) MCD_startDma,
.MCD_dmaStatus = (int32_t (*)(int32_t)) MCD_dmaStatus,
.MCD_XferProgrQuery = (int32_t (*)(int32_t, MCD_XferProg *)) MCD_XferProgrQuery,
.MCD_killDma = (int32_t (*)(int32_t)) MCD_killDma,
.MCD_continDma = (int32_t (*)(int32_t)) MCD_continDma,
.MCD_pauseDma = (int32_t (*)(int32_t)) MCD_pauseDma,
.MCD_resumeDma = (int32_t (*)(int32_t)) MCD_resumeDma,
.MCD_csumQuery = (int32_t (*)(int32_t, uint32_t *)) MCD_csumQuery,
.dma_malloc = driver_mem_alloc,
.dma_free = driver_mem_free
.version = 0x0101,
.magic = 0x444d4143, /* 'DMAC' */
.dma_set_initiator = dma_set_initiator,
.dma_get_initiator = dma_get_initiator,
.dma_free_initiator = dma_free_initiator,
.dma_set_channel = dma_set_channel,
.dma_get_channel = dma_get_channel,
.dma_free_channel = dma_free_channel,
.dma_clear_channel = dma_clear_channel,
.MCD_startDma = (int (*)(long, int8_t *, unsigned int, int8_t *, unsigned int,
unsigned int, unsigned int, unsigned int, int,
unsigned int, unsigned int)) MCD_startDma,
.MCD_dmaStatus = (int32_t (*)(int32_t)) MCD_dmaStatus,
.MCD_XferProgrQuery = (int32_t (*)(int32_t, MCD_XferProg *)) MCD_XferProgrQuery,
.MCD_killDma = (int32_t (*)(int32_t)) MCD_killDma,
.MCD_continDma = (int32_t (*)(int32_t)) MCD_continDma,
.MCD_pauseDma = (int32_t (*)(int32_t)) MCD_pauseDma,
.MCD_resumeDma = (int32_t (*)(int32_t)) MCD_resumeDma,
.MCD_csumQuery = (int32_t (*)(int32_t, uint32_t *)) MCD_csumQuery,
.dma_malloc = driver_mem_alloc,
.dma_free = driver_mem_free
};
extern struct fb_info *info_fb;
@@ -77,51 +77,51 @@ extern struct fb_info *info_fb;
*/
static struct pci_bios_interface pci_interface =
{
.subjar = 0,
.version = 0x00010000,
.find_pci_device = wrapper_find_pci_device,
.find_pci_classcode = wrapper_find_pci_classcode,
.read_config_byte = wrapper_read_config_byte,
.read_config_word = wrapper_read_config_word,
.read_config_longword = wrapper_read_config_longword,
.fast_read_config_byte = wrapper_fast_read_config_byte,
.fast_read_config_word = wrapper_fast_read_config_word,
.fast_read_config_longword = wrapper_fast_read_config_longword,
.write_config_byte = wrapper_write_config_byte,
.write_config_word = wrapper_write_config_word,
.write_config_longword = wrapper_write_config_longword,
.hook_interrupt = wrapper_hook_interrupt,
.unhook_interrupt = wrapper_unhook_interrupt,
.special_cycle = wrapper_special_cycle,
.get_routing = wrapper_get_routing,
.set_interrupt = wrapper_set_interrupt,
.get_resource = wrapper_get_resource,
.get_card_used = wrapper_get_card_used,
.set_card_used = wrapper_set_card_used,
.read_mem_byte = wrapper_read_mem_byte,
.read_mem_word = wrapper_read_mem_word,
.read_mem_longword = wrapper_read_mem_longword,
.fast_read_mem_byte = wrapper_fast_read_mem_byte,
.fast_read_mem_word = wrapper_fast_read_mem_word,
.fast_read_mem_longword = wrapper_fast_read_mem_longword,
.write_mem_byte = wrapper_write_mem_byte,
.write_mem_word = wrapper_write_mem_word,
.write_mem_longword = wrapper_write_mem_longword,
.read_io_byte = wrapper_read_io_byte,
.read_io_word = wrapper_read_io_word,
.read_io_longword = wrapper_read_io_longword,
.fast_read_io_byte = wrapper_fast_read_io_byte,
.fast_read_io_word = wrapper_fast_read_io_word,
.fast_read_io_longword = wrapper_fast_read_io_longword,
.write_io_byte = wrapper_write_io_byte,
.write_io_word = wrapper_write_io_word,
.write_io_longword = wrapper_write_io_longword,
.get_machine_id = wrapper_get_machine_id,
.get_pagesize = wrapper_get_pagesize,
.virt_to_bus = wrapper_virt_to_bus,
.bus_to_virt = wrapper_bus_to_virt,
.virt_to_phys = wrapper_virt_to_phys,
.phys_to_virt = wrapper_phys_to_virt,
.subjar = 0,
.version = 0x00010000,
.find_pci_device = wrapper_find_pci_device,
.find_pci_classcode = wrapper_find_pci_classcode,
.read_config_byte = wrapper_read_config_byte,
.read_config_word = wrapper_read_config_word,
.read_config_longword = wrapper_read_config_longword,
.fast_read_config_byte = wrapper_fast_read_config_byte,
.fast_read_config_word = wrapper_fast_read_config_word,
.fast_read_config_longword = wrapper_fast_read_config_longword,
.write_config_byte = wrapper_write_config_byte,
.write_config_word = wrapper_write_config_word,
.write_config_longword = wrapper_write_config_longword,
.hook_interrupt = wrapper_hook_interrupt,
.unhook_interrupt = wrapper_unhook_interrupt,
.special_cycle = wrapper_special_cycle,
.get_routing = wrapper_get_routing,
.set_interrupt = wrapper_set_interrupt,
.get_resource = wrapper_get_resource,
.get_card_used = wrapper_get_card_used,
.set_card_used = wrapper_set_card_used,
.read_mem_byte = wrapper_read_mem_byte,
.read_mem_word = wrapper_read_mem_word,
.read_mem_longword = wrapper_read_mem_longword,
.fast_read_mem_byte = wrapper_fast_read_mem_byte,
.fast_read_mem_word = wrapper_fast_read_mem_word,
.fast_read_mem_longword = wrapper_fast_read_mem_longword,
.write_mem_byte = wrapper_write_mem_byte,
.write_mem_word = wrapper_write_mem_word,
.write_mem_longword = wrapper_write_mem_longword,
.read_io_byte = wrapper_read_io_byte,
.read_io_word = wrapper_read_io_word,
.read_io_longword = wrapper_read_io_longword,
.fast_read_io_byte = wrapper_fast_read_io_byte,
.fast_read_io_word = wrapper_fast_read_io_word,
.fast_read_io_longword = wrapper_fast_read_io_longword,
.write_io_byte = wrapper_write_io_byte,
.write_io_word = wrapper_write_io_word,
.write_io_longword = wrapper_write_io_longword,
.get_machine_id = wrapper_get_machine_id,
.get_pagesize = wrapper_get_pagesize,
.virt_to_bus = wrapper_virt_to_bus,
.bus_to_virt = wrapper_bus_to_virt,
.virt_to_phys = wrapper_virt_to_phys,
.phys_to_virt = wrapper_phys_to_virt,
};
/*
@@ -129,7 +129,7 @@ static struct pci_bios_interface pci_interface =
*/
static struct framebuffer_driver_interface framebuffer_interface =
{
.framebuffer_info = &info_fb
.framebuffer_info = &info_fb
};
/*
@@ -137,61 +137,61 @@ static struct framebuffer_driver_interface framebuffer_interface =
*/
static struct mmu_driver_interface mmu_interface =
{
.map_page_locked = &mmu_map_data_page_locked,
.unlock_page = &mmu_unlock_data_page,
.map_page_locked = &mmu_map_data_page_locked,
.unlock_page = &mmu_unlock_data_page,
.report_locked_pages = &mmu_report_locked_pages,
.report_pagesize = &mmu_report_pagesize
};
static struct generic_interface interfaces[] =
{
{
/* BaS SD-card driver interface */
{
/* BaS SD-card driver interface */
.type = XHDI_DRIVER,
.name = "SDCARD",
.description = "BaS SD Card driver",
.version = 0,
.revision = 1,
.interface.xhdi = &xhdi_call_interface
},
{
.type = MCD_DRIVER,
.name = "MCDDMA",
.description = "BaS Multichannel DMA driver",
.version = 0,
.revision = 1,
.interface.dma = &dma_interface,
},
{
.type = VIDEO_DRIVER,
.name = "RADEON",
.description = "BaS RADEON framebuffer driver",
.version = 0,
.revision = 1,
.interface.fb = &framebuffer_interface,
},
{
.type = PCI_DRIVER,
.name = "PCI",
.description = "BaS PCI_BIOS driver",
.version = 0,
.revision = 1,
.interface.pci = &pci_interface,
},
{
.type = MMU_DRIVER,
.name = "MMU",
.description = "BaS MMU driver",
.version = 0,
.revision = 1,
.interface.mmu = &mmu_interface,
},
/* insert new drivers here */
.type = XHDI_DRIVER,
.name = "SDCARD",
.description = "BaS SD Card driver",
.version = 0,
.revision = 1,
.interface.xhdi = &xhdi_call_interface
},
{
.type = MCD_DRIVER,
.name = "MCDDMA",
.description = "BaS Multichannel DMA driver",
.version = 0,
.revision = 1,
.interface.dma = &dma_interface,
},
{
.type = VIDEO_DRIVER,
.name = "RADEON",
.description = "BaS RADEON framebuffer driver",
.version = 0,
.revision = 1,
.interface.fb = &framebuffer_interface,
},
{
.type = PCI_DRIVER,
.name = "PCI",
.description = "BaS PCI_BIOS driver",
.version = 0,
.revision = 1,
.interface.pci = &pci_interface,
},
{
.type = MMU_DRIVER,
.name = "MMU",
.description = "BaS MMU driver",
.version = 0,
.revision = 1,
.interface.mmu = &mmu_interface,
},
/* insert new drivers here */
{
.type = END_OF_DRIVERS
}
{
.type = END_OF_DRIVERS
}
};
extern void remove_handler(void); /* forward declaration */
@@ -201,10 +201,10 @@ extern void remove_handler(void); /* forward declaration */
*/
static struct driver_table bas_drivers =
{
.bas_version = MAJOR_VERSION,
.bas_revision = MINOR_VERSION,
.bas_version = MAJOR_VERSION,
.bas_revision = MINOR_VERSION,
.remove_handler = remove_handler,
.interfaces = interfaces
.interfaces = interfaces
};
void remove_handler(void)
@@ -217,30 +217,34 @@ void remove_handler(void)
void __attribute__((interrupt)) get_bas_drivers(void)
{
__asm__ __volatile(
/*
* sp should now point to the next instruction after the trap
* The trap itself is 2 bytes, the four bytes before that must
* read '_BAS' or we are not meant by this call
*/
" move.l d0,-(sp) \n\t" // save register
" move.l 10(sp),d0 \n\t" // get "magic word"
" cmp.l #0x5f424153,d0 \n\t" // is it '_BAS'?
" beq fetch_drivers \n\t" // yes
/*
* This seems indeed a "normal" trap #0. Better pass control to "normal" trap #0 processing
* If trap #0 isn't set to something sensible, we'll probably crash here, but this must be
* prevented on the caller side.
*/
" move.l (sp)+,d0 \n\t" // restore register
" move.l 0x80,-(sp) \n\t" // fetch vector
" rts \n\t" // and jump through it
__asm__ __volatile(
/*
* sp should now point to the next instruction after the trap
* The trap itself is 2 bytes, the four bytes before that must
* read '_BAS' or we are not meant by this call
*/
" move.l a0,-(sp) \n\t" // save registers
" move.l d0,-(sp) \n\t"
" move.l 12(sp),a0 \n\t" // get return address
" move.l -6(a0),d0 \n\t" //
" cmp.l #0x5f424153,d0 \n\t" // is it '_BAS'?
" beq fetch_drivers \n\t" // yes
/*
* This seems indeed a "normal" trap #0. Better pass control to "normal" trap #0 processing
* If trap #0 isn't set to something sensible, we'll probably crash here, but this must be
* prevented on the caller side.
*/
" move.l (sp)+,d0 \n\t" // restore registers
" move.l (sp)+,a0 \n\t"
" move.l 0x80,-(sp) \n\t" // fetch vector
" rts \n\t" // and jump through it
"fetch_drivers: \n\t"
" move.l #%[drivers],d0 \n\t" // return driver struct in d0
" addq.l #4,sp \n\t" // adjust stack
: /* no output */
: [drivers] "o" (bas_drivers) /* input */
: /* clobber */
);
"fetch_drivers: \n\t"
" move.l #%[drivers],d0 \n\t" // return driver struct in d0
" addq.l #4,sp \n\t" // adjust stack
" move.l (sp)+,a0 \n\t" // restore register
: /* no output */
: [drivers] "o" (bas_drivers) /* input */
: /* clobber */
);
}

View File

@@ -52,45 +52,45 @@ extern void (*rt_vbr[])(void);
*/
int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority, uint8_t intr, void (*handler)(void))
{
int ipl;
int i;
volatile uint8_t *ICR = &MCF_INTC_ICR01 - 1;
uint8_t lp;
int ipl;
int i;
volatile uint8_t *ICR = &MCF_INTC_ICR01 - 1;
uint8_t lp;
source &= 63;
priority &= 7;
source &= 63;
priority &= 7;
if (source < 1 || source > 63)
{
dbg("interrupt source %d not defined\r\n", source);
return -1;
}
if (source < 1 || source > 63)
{
dbg("interrupt source %d not defined\r\n", source);
return -1;
}
lp = MCF_INTC_ICR_IL(level) | MCF_INTC_ICR_IP(priority);
lp = MCF_INTC_ICR_IL(level) | MCF_INTC_ICR_IP(priority);
/* check if this combination is already set somewhere */
for (i = 1; i < 64; i++)
{
if (ICR[i] == lp)
{
dbg("level %d and priority %d already used for interrupt source %d!\r\n",
level, priority, i);
return -1;
}
}
/* check if this combination is already set somewhere */
for (i = 1; i < 64; i++)
{
if (ICR[i] == lp)
{
dbg("level %d and priority %d already used for interrupt source %d!\r\n",
level, priority, i);
return -1;
}
}
/* disable interrupts */
ipl = set_ipl(7);
/* disable interrupts */
ipl = set_ipl(7);
VBR[64 + source] = handler; /* first 64 vectors are system exceptions */
VBR[64 + source] = handler; /* first 64 vectors are system exceptions */
/* set level and priority in interrupt controller */
ICR[source] = lp;
/* set level and priority in interrupt controller */
ICR[source] = lp;
/* set interrupt mask to where it was before */
set_ipl(ipl);
/* set interrupt mask to where it was before */
set_ipl(ipl);
return 0;
return 0;
}
#ifndef MAX_ISR_ENTRY
@@ -100,10 +100,10 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
struct isrentry
{
int vector;
int (*handler)(void *, void *);
void *hdev;
void *harg;
int vector;
int (*handler)(void *, void *);
void *hdev;
void *harg;
};
static struct isrentry isrtab[MAX_ISR_ENTRY]; /* list of interrupt service routines */
@@ -113,7 +113,7 @@ static struct isrentry isrtab[MAX_ISR_ENTRY]; /* list of interrupt service
*/
void isr_init(void)
{
memset(isrtab, 0, sizeof(isrtab));
memset(isrtab, 0, sizeof(isrtab));
}
/*
@@ -126,56 +126,56 @@ void isr_init(void)
*/
int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg)
{
int index;
int index;
if ((vector == 0) || (handler == NULL))
{
dbg("illegal vector or handler!\r\n");
return false;
}
if ((vector == 0) || (handler == NULL))
{
dbg("illegal vector or handler!\r\n");
return false;
}
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if (isrtab[index].vector == vector)
{
/* one cross each, only! */
dbg("already set handler with this vector (%d, %d)\r\n", vector);
return false;
}
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if (isrtab[index].vector == vector)
{
/* one cross each, only! */
dbg("already set handler with this vector (%d, %d)\r\n", vector);
return false;
}
if (isrtab[index].vector == 0)
{
isrtab[index].vector = vector;
isrtab[index].handler = handler;
isrtab[index].hdev = hdev;
isrtab[index].harg = harg;
if (isrtab[index].vector == 0)
{
isrtab[index].vector = vector;
isrtab[index].handler = handler;
isrtab[index].hdev = hdev;
isrtab[index].harg = harg;
return true;
}
}
dbg("no available slots to register handler for vector %d\n\r", vector);
return true;
}
}
dbg("no available slots to register handler for vector %d\n\r", vector);
return false; /* no available slots */
return false; /* no available slots */
}
void isr_remove_handler(int (*handler)(void *, void *))
{
/*
* This routine removes from the ISR table all
* entries that matches 'handler'.
*/
int index;
/*
* This routine removes from the ISR table all
* entries that matches 'handler'.
*/
int index;
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if (isrtab[index].handler == handler)
{
memset(&isrtab[index], 0, sizeof(struct isrentry));
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if (isrtab[index].handler == handler)
{
memset(&isrtab[index], 0, sizeof(struct isrentry));
return;
}
}
dbg("no such handler registered (handler=%p\r\n", handler);
return;
}
}
dbg("no such handler registered (handler=%p\r\n", handler);
}
/*
@@ -184,27 +184,27 @@ void isr_remove_handler(int (*handler)(void *, void *))
*/
bool isr_execute_handler(int vector)
{
int index;
bool retval = false;
int index;
bool retval = false;
/*
* locate a BaS Interrupt Service Routine handler.
*/
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if (isrtab[index].vector == vector)
{
retval = true;
/*
* locate a BaS Interrupt Service Routine handler.
*/
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if (isrtab[index].vector == vector)
{
retval = true;
if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg))
{
return retval;
}
}
}
dbg("no BaS isr handler for vector %d found\r\n", vector);
if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg))
{
return retval;
}
}
}
dbg("no BaS isr handler for vector %d found\r\n", vector);
return retval;
return retval;
}
/*
@@ -215,119 +215,31 @@ bool isr_execute_handler(int vector)
*/
int pic_interrupt_handler(void *arg1, void *arg2)
{
uint8_t rcv_byte;
uint8_t rcv_byte;
rcv_byte = MCF_PSC3_PSCRB_8BIT;
if (rcv_byte == 2) // PIC requests RTC data
{
uint8_t *rtc_reg = (uint8_t *) 0xffff8961;
uint8_t *rtc_data = (uint8_t *) 0xffff8963;
int index = 0;
rcv_byte = MCF_PSC3_PSCRB_8BIT;
if (rcv_byte == 2) // PIC requests RTC data
{
uint8_t *rtc_reg = (uint8_t *) 0xffff8961;
uint8_t *rtc_data = (uint8_t *) 0xffff8963;
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
do
{
*rtc_reg = 0;
MCF_PSC3_PSCTB_8BIT = *rtc_data;
} while (index++ < 64);
}
return 1;
MCF_PSC3_PSCTB_8BIT = 0x82; // header byte to PIC
do
{
*rtc_reg = 0;
MCF_PSC3_PSCTB_8BIT = *rtc_data;
} while (index++ < 64);
}
return 1;
}
extern int32_t video_sbt;
extern int32_t video_tlb;
void video_addr_timeout(void)
{
uint32_t addr = 0x0L;
uint32_t *src;
uint32_t *dst;
uint32_t asid;
dbg("video address timeout\r\n");
flush_and_invalidate_caches();
do
{
uint32_t tlb;
uint32_t page_attr;
/*
* search tlb entry id for addr (if not available, the MMU
* will provide a new one based on its LRU algorithm)
*/
MCF_MMU_MMUAR = addr;
MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_RW |
MCF_MMU_MMUOR_ACC;
NOP();
tlb = (MCF_MMU_MMUOR >> 16) & 0xffff;
/*
* retrieve tlb entry with the found TLB entry id
*/
MCF_MMU_MMUAR = tlb;
MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_ADR |
MCF_MMU_MMUOR_RW |
MCF_MMU_MMUOR_ACC;
NOP();
asid = (MCF_MMU_MMUTR >> 2) & 0x1fff; /* fetch ASID of page */;
if (asid != sca_page_ID) /* check if screen area */
{
addr += 0x100000;
continue; /* next page */
}
/* modify found TLB entry */
if (addr == 0x0)
{
page_attr =
MCF_MMU_MMUDR_LK |
MCF_MMU_MMUDR_SZ(0) |
MCF_MMU_MMUDR_CM(0) |
MCF_MMU_MMUDR_R |
MCF_MMU_MMUDR_W |
MCF_MMU_MMUDR_X;
}
else
{
page_attr =
MCF_MMU_MMUTR_SG |
MCF_MMU_MMUTR_V;
}
MCF_MMU_MMUTR = addr;
MCF_MMU_MMUDR = page_attr;
MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_ADR |
MCF_MMU_MMUOR_ACC |
MCF_MMU_MMUOR_UAA;
NOP();
dst = (uint32_t *) 0x60000000 + addr;
src = (uint32_t *) addr;
while (dst < (uint32_t *) 0x60000000 + addr + 0x10000)
{
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
}
addr += 0x100000;
} while (addr < 0xd00000);
video_tlb = 0x2000;
video_sbt = 0;
dbg("video address timeout\r\n");
}
@@ -336,16 +248,16 @@ void video_addr_timeout(void)
*/
void blink_led(void)
{
static uint16_t blinker = 0;
static uint16_t blinker = 0;
if ((blinker++ & 0x80) > 0)
{
MCF_GPIO_PODR_FEC1L |= (1 << 4); /* LED off */
}
else
{
MCF_GPIO_PODR_FEC1L &= ~(1 << 4); /* LED on */
}
if ((blinker++ & 0x80) > 0)
{
MCF_GPIO_PODR_FEC1L |= (1 << 4); /* LED off */
}
else
{
MCF_GPIO_PODR_FEC1L &= ~(1 << 4); /* LED on */
}
}
/*
@@ -363,47 +275,27 @@ void blink_led(void)
bool irq6_acsi_dma_interrupt(void)
{
dbg("ACSI DMA interrupt\r\n");
dbg("ACSI DMA interrupt\r\n");
/*
* TODO: implement handler
*/
/*
* TODO: implement handler
*/
return false;
return false;
}
bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2)
{
bool handled = false;
bool handled = false;
MCF_EPORT_EPFR |= (1 << 6); /* clear int6 from edge port */
MCF_EPORT_EPFR |= (1 << 6); /* clear int6 from edge port */
if (video_sbt != 0 && (video_sbt - 0x70000000) > MCF_SLT0_SCNT)
{
video_addr_timeout();
handled = true;
}
if (FALCON_MFP_IPRA || FALCON_MFP_IPRB)
{
blink_led();
}
/*
* check if ACSI DMA interrupt
*/
if (FALCON_MFP_IERA & (1 << 7))
{
/* ACSI interrupt is enabled */
if (FALCON_MFP_IPRA & (1 << 7))
{
irq6_acsi_dma_interrupt();
handled = true;
}
}
if (FALCON_MFP_IPRA || FALCON_MFP_IPRB)
{
blink_led();
}
return handled;
return handled;
}
#if defined(MACHINE_FIREBEE)
@@ -430,112 +322,10 @@ bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2)
*/
void gpt0_interrupt_handler(void)
{
uint32_t video_address;
uint32_t video_end_address;
int page_number;
bool already_set;
extern uint32_t _STRAM_END;
dbg("screen base = 0x%x\r\n", vbasehi);
dbg("screen base = 0x%x\r\n", vbasehi);
if (vbasehi < 2) /* screen base lower than 0x20000? */
{
goto rearm_trigger; /* do nothing */
}
else if (vbasehi >= 0xd0) /* higher than 0xd00000 (normal Falcon address)? */
{
video_sbt = MCF_SLT0_SCNT; /* FIXME: no idea why we need to save the time here */
}
video_address = (vbasehi << 16) | (vbasemid << 8) | vbaselow;
page_number = video_address >> 20; /* calculate a page number */
already_set = (video_tlb & (1 << page_number)); /* already in bitset? */
video_tlb |= page_number; /* set it */
if (! already_set) /* newly set page, need to copy contents */
{
flush_and_invalidate_caches();
dma_memcpy((uint8_t *) video_address + 0x60000000, (uint8_t *) video_address, 0x100000);
/*
* create an MMU TLB entry for the new video page
*/
/*
* first search for an existing entry with our address. If none is found,
* the MMU will propose a new one
*/
MCF_MMU_MMUAR = video_address;
MCF_MMU_MMUOR = 0x106;
NOP();
/*
* take this MMU TLB entry and set it to our video address and page mapping
*/
MCF_MMU_MMUAR = (MCF_MMU_MMUOR >> 16) & 0xffff; /* set TLB id */
MCF_MMU_MMUTR = video_address |
MCF_MMU_MMUTR_ID(sca_page_ID) | /* set video page ID */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = (video_address + 0x60000000) | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0) | /* writethrough */
MCF_MMU_MMUDR_R | /* readable */
MCF_MMU_MMUDR_W | /* writeable */
MCF_MMU_MMUDR_X; /* executable */
MCF_MMU_MMUOR = 0x10b; /* update TLB entry */
}
/*
* Calculate the effective screen memory size to see if we need to map another page
* in case the new screen spans more than one single page
*/
video_end_address = video_address + (vde - vdb) * vwrap;
if (video_end_address < _STRAM_END)
{
page_number = video_end_address >> 20; /* calculate a page number */
already_set = (video_tlb & (1 << page_number)); /* already in bitset? */
video_tlb |= page_number; /* set it */
if (! already_set) /* newly set page, need to copy contents */
{
flush_and_invalidate_caches();
dma_memcpy((uint8_t *) video_end_address + 0x60000000, (uint8_t *) video_end_address, 0x100000);
/*
* create an MMU TLB entry for the new video page
*/
/*
* first search for an existing entry with our address. If none is found,
* the MMU will propose a new one
*/
MCF_MMU_MMUAR = video_end_address;
MCF_MMU_MMUOR = 0x106;
NOP();
/*
* take this MMU TLB entry and set it to our video address and page mapping
*/
MCF_MMU_MMUAR = (MCF_MMU_MMUOR >> 16) & 0xffff; /* set TLB id */
MCF_MMU_MMUTR = video_end_address |
MCF_MMU_MMUTR_ID(sca_page_ID) | /* set video page ID */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = (video_end_address + 0x60000000) | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0) | /* writethrough */
MCF_MMU_MMUDR_R | /* readable */
MCF_MMU_MMUDR_W | /* writeable */
MCF_MMU_MMUDR_X; /* executable */
MCF_MMU_MMUOR = 0x10b; /* update TLB entry */
}
}
rearm_trigger:
MCF_GPT0_GMS &= ~1; /* rearm trigger */
NOP();
MCF_GPT0_GMS |= 1;
MCF_GPT0_GMS &= ~1; /* rearm trigger */
NOP();
MCF_GPT0_GMS |= 1;
}
#endif /* MACHINE_FIREBEE */

View File

@@ -70,16 +70,16 @@
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#error "unknown machine!"x
#endif /* MACHINE_FIREBEE */
//#define DBG_MMU
#define DBG_MMU
#ifdef DBG_MMU
#define dbg(format, arg...) do { xprintf("DEBUG (%s()): " format, __FUNCTION__, ##arg);} while(0)
#else
#define dbg(format, arg...) do {;} while (0)
#endif /* DBG_MMU */
#define err(format, arg...) do { xprintf("ERROR (%s()): " format, __FUNCTION__, ##arg); xprintf("system halted\r\n"); } while(0); while(1)
#define err(format, arg...) do { xprintf("ERROR (%s()): " format, __FUNCTION__, ##arg); } while(0);
/*
* set ASID register
@@ -582,8 +582,6 @@ void mmu_init(void)
flags.locked = true;
mmu_map_page(0x00d00000, 0x60d00000, MMU_PAGE_SIZE_1M, SCA_PAGE_ID, &flags);
video_tlb = 0x2000; /* set page as video page */
video_sbt = 0x0; /* clear time */
#endif /* MACHINE_FIREBEE */
/*
@@ -658,7 +656,12 @@ uint32_t mmutr_miss(uint32_t mmu_sr, uint32_t fault_address, uint32_t pc,
"PC = 0x%08x\r\n",
fault_address, format_status, mmu_sr, pc);
dbg("fault = 0x%08x\r\n", fault);
mmu_map_instruction_page(pc, 0);
if (!mmu_map_instruction_page(pc, 0))
{
dbg("bus error\r\n");
return 1; /* bus error */
}
/* due to prefetch, it makes sense to map the next adjacent page also for ITLBs */
if (pc + DEFAULT_PAGE_SIZE < TARGET_ADDRESS)
@@ -666,7 +669,11 @@ uint32_t mmutr_miss(uint32_t mmu_sr, uint32_t fault_address, uint32_t pc,
/*
* only do this if the next page is still valid RAM
*/
mmu_map_instruction_page(pc + DEFAULT_PAGE_SIZE, 0);
if (!mmu_map_instruction_page(pc + DEFAULT_PAGE_SIZE, 0))
{
dbg("bus error\r\n");
return 1; /* bus error */
}
}
break;
@@ -678,7 +685,12 @@ uint32_t mmutr_miss(uint32_t mmu_sr, uint32_t fault_address, uint32_t pc,
"PC = 0x%08x\r\n",
fault_address, format_status, mmu_sr, pc);
dbg("fault = 0x%08x\r\n", fault);
mmu_map_data_page(fault_address, 0);
if (!mmu_map_data_page(fault_address, 0))
{
dbg("bus error\r\n");
return 1; /* bus error */
}
break;
/* else issue an bus error */

View File

@@ -68,7 +68,9 @@ void setcookie(uint32_t cookie, uint32_t value)
* work from TSRs)
*/
if (cookiejar[-1])
{
max_slots = cookiejar[-1];
}
if (max_slots > num_slots)
{
@@ -83,7 +85,7 @@ void setcookie(uint32_t cookie, uint32_t value)
printf("cannot set cookie, cookie jar is full!\r\n");
}
# define COOKIE_DMAC 0x444D4143L /* FireTOS DMA API */
#define COOKIE_DMAC 0x444d4143L /* FireTOS DMA API */
static char *dt_to_str(enum driver_type dt)
{
@@ -118,7 +120,7 @@ int main(int argc, char *argv[])
if (sig == 0x45544f53)
{
old_vector = Setexc(0x20, my_own_trap0_handler); /* set our own temporarily */
dt = get_bas_drivers(); /* trap #1 */
dt = get_bas_drivers(); /* trap #0 */
(void) Setexc(0x20, old_vector); /* restore original vector */
if (dt)
@@ -143,17 +145,20 @@ int main(int argc, char *argv[])
ifc++;
}
}
else
{
printf("driver table not found.\r\n");
}
}
else
{
printf("not running on EmuTOS,\r\n(signature 0x%04x instead of 0x%04x),\r\n\r\nexiting\r\n",
printf("not running on EmuTOS,\r\n(signature 0x%04x instead of 0x%04x\r\n",
(uint32_t) sig, 0x45544f53);
}
Super(ssp);
while (Cconis()) Cconin(); /* eat keys */
// printf("press any key to continue\n\r");
// while (! Cconis());
return 0;
}