fixed wrong stack address offset for "magic number"
This commit is contained in:
@@ -223,8 +223,10 @@ void __attribute__((interrupt)) get_bas_drivers(void)
|
|||||||
* The trap itself is 2 bytes, the four bytes before that must
|
* The trap itself is 2 bytes, the four bytes before that must
|
||||||
* read '_BAS' or we are not meant by this call
|
* read '_BAS' or we are not meant by this call
|
||||||
*/
|
*/
|
||||||
" move.l d0,-(sp) \n\t" // save register
|
" move.l a0,-(sp) \n\t" // save registers
|
||||||
" move.l 10(sp),d0 \n\t" // get "magic word"
|
" 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'?
|
" cmp.l #0x5f424153,d0 \n\t" // is it '_BAS'?
|
||||||
" beq fetch_drivers \n\t" // yes
|
" beq fetch_drivers \n\t" // yes
|
||||||
/*
|
/*
|
||||||
@@ -232,13 +234,15 @@ void __attribute__((interrupt)) get_bas_drivers(void)
|
|||||||
* If trap #0 isn't set to something sensible, we'll probably crash here, but this must be
|
* If trap #0 isn't set to something sensible, we'll probably crash here, but this must be
|
||||||
* prevented on the caller side.
|
* prevented on the caller side.
|
||||||
*/
|
*/
|
||||||
" move.l (sp)+,d0 \n\t" // restore register
|
" move.l (sp)+,d0 \n\t" // restore registers
|
||||||
|
" move.l (sp)+,a0 \n\t"
|
||||||
" move.l 0x80,-(sp) \n\t" // fetch vector
|
" move.l 0x80,-(sp) \n\t" // fetch vector
|
||||||
" rts \n\t" // and jump through it
|
" rts \n\t" // and jump through it
|
||||||
|
|
||||||
"fetch_drivers: \n\t"
|
"fetch_drivers: \n\t"
|
||||||
" move.l #%[drivers],d0 \n\t" // return driver struct in d0
|
" move.l #%[drivers],d0 \n\t" // return driver struct in d0
|
||||||
" addq.l #4,sp \n\t" // adjust stack
|
" addq.l #4,sp \n\t" // adjust stack
|
||||||
|
" move.l (sp)+,a0 \n\t" // restore register
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: [drivers] "o" (bas_drivers) /* input */
|
: [drivers] "o" (bas_drivers) /* input */
|
||||||
: /* clobber */
|
: /* clobber */
|
||||||
|
|||||||
@@ -236,98 +236,10 @@ int pic_interrupt_handler(void *arg1, void *arg2)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int32_t video_sbt;
|
|
||||||
extern int32_t video_tlb;
|
|
||||||
|
|
||||||
void video_addr_timeout(void)
|
void video_addr_timeout(void)
|
||||||
{
|
{
|
||||||
uint32_t addr = 0x0L;
|
|
||||||
uint32_t *src;
|
|
||||||
uint32_t *dst;
|
|
||||||
uint32_t asid;
|
|
||||||
|
|
||||||
dbg("video address timeout\r\n");
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -378,26 +290,6 @@ bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2)
|
|||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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)
|
if (FALCON_MFP_IPRA || FALCON_MFP_IPRB)
|
||||||
{
|
{
|
||||||
blink_led();
|
blink_led();
|
||||||
@@ -430,110 +322,8 @@ bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2)
|
|||||||
*/
|
*/
|
||||||
void gpt0_interrupt_handler(void)
|
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 */
|
MCF_GPT0_GMS &= ~1; /* rearm trigger */
|
||||||
NOP();
|
NOP();
|
||||||
MCF_GPT0_GMS |= 1;
|
MCF_GPT0_GMS |= 1;
|
||||||
|
|||||||
@@ -70,16 +70,16 @@
|
|||||||
#elif defined(MACHINE_M54455)
|
#elif defined(MACHINE_M54455)
|
||||||
#include "m54455.h"
|
#include "m54455.h"
|
||||||
#else
|
#else
|
||||||
#error "unknown machine!"
|
#error "unknown machine!"x
|
||||||
#endif /* MACHINE_FIREBEE */
|
#endif /* MACHINE_FIREBEE */
|
||||||
|
|
||||||
//#define DBG_MMU
|
#define DBG_MMU
|
||||||
#ifdef DBG_MMU
|
#ifdef DBG_MMU
|
||||||
#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)
|
||||||
#else
|
#else
|
||||||
#define dbg(format, arg...) do {;} while (0)
|
#define dbg(format, arg...) do {;} while (0)
|
||||||
#endif /* DBG_MMU */
|
#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
|
* set ASID register
|
||||||
@@ -582,8 +582,6 @@ void mmu_init(void)
|
|||||||
flags.locked = true;
|
flags.locked = true;
|
||||||
mmu_map_page(0x00d00000, 0x60d00000, MMU_PAGE_SIZE_1M, SCA_PAGE_ID, &flags);
|
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 */
|
#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",
|
"PC = 0x%08x\r\n",
|
||||||
fault_address, format_status, mmu_sr, pc);
|
fault_address, format_status, mmu_sr, pc);
|
||||||
dbg("fault = 0x%08x\r\n", fault);
|
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 */
|
/* due to prefetch, it makes sense to map the next adjacent page also for ITLBs */
|
||||||
if (pc + DEFAULT_PAGE_SIZE < TARGET_ADDRESS)
|
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
|
* 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;
|
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",
|
"PC = 0x%08x\r\n",
|
||||||
fault_address, format_status, mmu_sr, pc);
|
fault_address, format_status, mmu_sr, pc);
|
||||||
dbg("fault = 0x%08x\r\n", fault);
|
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;
|
break;
|
||||||
|
|
||||||
/* else issue an bus error */
|
/* else issue an bus error */
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ void setcookie(uint32_t cookie, uint32_t value)
|
|||||||
* work from TSRs)
|
* work from TSRs)
|
||||||
*/
|
*/
|
||||||
if (cookiejar[-1])
|
if (cookiejar[-1])
|
||||||
|
{
|
||||||
max_slots = cookiejar[-1];
|
max_slots = cookiejar[-1];
|
||||||
|
}
|
||||||
|
|
||||||
if (max_slots > num_slots)
|
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");
|
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)
|
static char *dt_to_str(enum driver_type dt)
|
||||||
{
|
{
|
||||||
@@ -118,7 +120,7 @@ int main(int argc, char *argv[])
|
|||||||
if (sig == 0x45544f53)
|
if (sig == 0x45544f53)
|
||||||
{
|
{
|
||||||
old_vector = Setexc(0x20, my_own_trap0_handler); /* set our own temporarily */
|
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 */
|
(void) Setexc(0x20, old_vector); /* restore original vector */
|
||||||
|
|
||||||
if (dt)
|
if (dt)
|
||||||
@@ -143,17 +145,20 @@ int main(int argc, char *argv[])
|
|||||||
ifc++;
|
ifc++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("driver table not found.\r\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
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);
|
(uint32_t) sig, 0x45544f53);
|
||||||
}
|
}
|
||||||
Super(ssp);
|
Super(ssp);
|
||||||
|
|
||||||
while (Cconis()) Cconin(); /* eat keys */
|
while (Cconis()) Cconin(); /* eat keys */
|
||||||
// printf("press any key to continue\n\r");
|
|
||||||
// while (! Cconis());
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user