diff --git a/sys/exceptions.S b/sys/exceptions.S index 1844d59..a335ee3 100644 --- a/sys/exceptions.S +++ b/sys/exceptions.S @@ -223,22 +223,22 @@ * If anybody knows of any better way on how to do this - please do! * */ - .macro mchar st,a,b,c,d,tgt - \st #\a << 24|\b<<16|\c<<8|\d,\tgt - .endm + .macro mchar st,a,b,c,d,tgt + \st #\a << 24|\b<<16|\c<<8|\d,\tgt + .endm - .text + .text _vec_init: - move.l a2,-(sp) // Backup registers + move.l a2,-(sp) // Backup registers - mov3q.l #-1,_rt_mod // rt_mod auf super - clr.l _rt_ssp - clr.l _rt_usp - clr.l _rt_vbr - move.l #__RAMBAR0,d0 // exception vectors reside in rambar0 - movec d0,VBR - move.l d0,a0 - move.l a0,a2 + mov3q.l #-1,_rt_mod // rt_mod auf super + clr.l _rt_ssp + clr.l _rt_usp + clr.l _rt_vbr + move.l #__RAMBAR0,d0 // exception vectors reside in rambar0 + movec d0,VBR + move.l d0,a0 + move.l a0,a2 init_vec: move.l #256,d0 @@ -255,7 +255,7 @@ init_vec_loop: lea access_exception(pc),a1 // set illegal access exception handler 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 lea _get_bas_drivers(pc),a1 @@ -336,17 +336,17 @@ std_exc_vec: beq noprint move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception move.l d0,-(sp) // provide it to xprintf() - pea exception_text + pea exception_text jsr _xprintf // call xprintf() add.l #3*4,sp // adjust stack noprint: - + movem.l (sp),d0-d1/a0-a1 // restore registers lea 4 * 4(sp),sp #endif /* DBG_EXC */ add.l _rt_vbr,d0 // + VBR - move.l d0,a5 + move.l d0,a5 move.l (a5),d0 // fetch exception routine address move.l 4(sp),a5 // restore a5 @@ -382,7 +382,7 @@ access_exception: lea -4*4(sp),sp movem.l d0-d1/a0-a1,(sp) - + lea 4*4(sp),a0 // original stack pointer move.l (a0),-(sp) // format status word @@ -402,7 +402,7 @@ access_exception: bus_error: bra std_exc_vec - + zero_divide: move.l a0,-(a7) move.l d0,-(a7) @@ -430,9 +430,9 @@ zd_nal: cmp.w #0x3c,d0 // immediate? zd_end: move.l a0,12(a7) move.l (a7)+,d0 - move.l (a7)+,a0 + move.l (a7)+,a0 rte - + irq1: irq 0x64,1,0x02 @@ -458,7 +458,7 @@ irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE jsr _irq5_handler // call C handler routine movem.l (sp),d0-d1/a0-a1 // restore registers - lea 4*4(sp),sp + lea 4*4(sp),sp rte // return from exception @@ -466,7 +466,7 @@ irq5text: .ascii "IRQ5!" .dc.b 13,10,0 -irq6: +irq6: irq 0x74,5,0x20 irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE @@ -479,7 +479,7 @@ irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE jsr _irq7_handler // call C handler routine movem.l (sp),d0-d1/a0-a1 // restore registers - lea 4*4(sp),sp + lea 4*4(sp),sp rte // return from exception @@ -495,7 +495,7 @@ irq5: irq6: // MFP interrupt from FPGA move.w #0x2700,sr // disable interrupts - + lea -4 * 4(sp),sp // save gcc scratch registers movem.l d0-d1/a0-a1,(sp) @@ -509,7 +509,7 @@ irq6: // MFP interrupt from FPGA movem.l (sp),d0-d1/a0-a1 // restore registers saved above lea 4 * 4(sp),sp // adjust stack - beq irq6_os // call OS handler + bra irq6_os // call OS handler rte irq6_os: // call native OS irq6 handler @@ -535,36 +535,36 @@ irq6_os: // call native OS irq6 handler // move.b #0x40,(a5) // clear int6 from edge port // screen adr change timed out? - move.l _video_sbt,d0 - beq irq6_non_sca // nothing to do if 0 - sub.l #0x70000000,d0 // substract 14 seconds - lea MCF_SLT0_SCNT,a5 - cmp.l (a5),d0 // time reached? - ble irq6_non_sca // not yet + move.l _video_sbt,d0 + beq irq6_non_sca // nothing to do if 0 + sub.l #0x70000000,d0 // substract 14 seconds + lea MCF_SLT0_SCNT,a5 + cmp.l (a5),d0 // time reached? + ble irq6_non_sca // not yet - lea -28(a7),a7 // save more registers - movem.l d0-d4/a0-a1,(a7) // - clr.l d3 // beginn mit 0 - jsr _flush_and_invalidate_caches + lea -28(a7),a7 // save more registers + movem.l d0-d4/a0-a1,(a7) // + clr.l d3 // beginn mit 0 + jsr _flush_and_invalidate_caches // eintrag suchen irq6_next_sca: - move.l d3,d0 - move.l d0,MCF_MMU_MMUAR // addresse - move.l #0x106,d4 - move.l d4,MCF_MMU_MMUOR // suchen -> - nop - move.l MCF_MMU_MMUOR,d4 - clr.w d4 - swap d4 - move.l d4,MCF_MMU_MMUAR - mvz.w #0x10e,d4 - move.l d4,MCF_MMU_MMUOR // einträge holen aus mmu - nop - move.l MCF_MMU_MMUTR,d4 // ID holen - lsr.l #2,d4 // bit 9 bis 2 - cmp.w #sca_page_ID,d4 // ist screen change ID? - bne irq6_sca_pn // nein -> page keine screen area next + move.l d3,d0 + move.l d0,MCF_MMU_MMUAR // addresse + move.l #0x106,d4 + move.l d4,MCF_MMU_MMUOR // suchen -> + nop + move.l MCF_MMU_MMUOR,d4 + clr.w d4 + swap d4 + move.l d4,MCF_MMU_MMUAR + mvz.w #0x10e,d4 + move.l d4,MCF_MMU_MMUOR // einträge holen aus mmu + nop + move.l MCF_MMU_MMUTR,d4 // ID holen + lsr.l #2,d4 // bit 9 bis 2 + cmp.w #sca_page_ID,d4 // ist screen change ID? + bne irq6_sca_pn // nein -> page keine screen area next // eintrag �ndern add.l #std_mmutr,d0 move.l d3,d1 // page 0? @@ -574,10 +574,10 @@ irq6_os: // call native OS irq6 handler irq6_sca_pn0: add.l #writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 // page wt and locked irq6_sca_pn1c: - mvz.w #0x10b,d2 // MMU update - move.l d0,MCF_MMU_MMUTR + mvz.w #0x10b,d2 // MMU update + move.l d0,MCF_MMU_MMUTR move.l d1,MCF_MMU_MMUDR - move.l d2,MCF_MMU_MMUOR // setze tlb data only + move.l d2,MCF_MMU_MMUOR // setze tlb data only nop // page copy move.l d3,a0 @@ -616,7 +616,7 @@ wait_dma_finished: cmp.l #6,d0 bne wait_dma_finished #else -irq6_vcd0_loop: +irq6_vcd0_loop: move.l (a0)+,(a1)+ // page copy move.l (a0)+,(a1)+ move.l (a0)+,(a1)+ @@ -632,18 +632,18 @@ irq6_sca_pn: move.l #0x2000,d0 move.l d0,_video_tlb // anfangszustand wieder herstellen - clr.l _video_sbt // zeit löschen + clr.l _video_sbt // zeit löschen - movem.l (sp),d0-d4/a0-a1 // restore registers - lea 7 * 4(sp),sp + movem.l (sp),d0-d4/a0-a1 // restore registers + lea 7 * 4(sp),sp irq6_non_sca: // test auf acsi dma ----------------------------------------------------------------- - lea 0xfffffa0b,a5 - bset #7,-4(a5) // int ena - btst.b #7,(a5) // acsi dma int? - beq non_acsi_dma - bsr acsi_dma + lea 0xfffffa0b,a5 + bset #7,-4(a5) // int ena + btst.b #7,(a5) // acsi dma int? + beq non_acsi_dma + bsr acsi_dma non_acsi_dma: // ---------------------------------------------------------------------------------- tst.b (a5) @@ -652,7 +652,7 @@ non_acsi_dma: bne irq6_1 movem.l (a7),d0/a5 addq.l #8,a7 - rte + rte irq6_1: lea MCF_GPIO_PODR_FEC1L,a5 bclr.b #4,(a5) // led on @@ -677,7 +677,7 @@ irq6_2: blinker:.long 0 - .text + .text /* * pseudo dma @@ -685,7 +685,7 @@ blinker:.long 0 acsi_dma: // atari dma move.l a1,-(a7) move.l d1,-(a7) - + lea MCF_PSC0_PSCTB_8BIT,a1 // ++ vr mchar move.l, 'D,'M','A,'\ ,(a1) //move.l #"DMA ",(a1) @@ -696,33 +696,33 @@ acsi_dma: // atari dma acsi_dma_start: move.l -12(a5),a1 // dma adresse move.l -8(a5),d0 // byt counter - ble acsi_dma_end - btst.b #0,-16(a5) // write? (dma modus reg) + ble acsi_dma_end + btst.b #0,-16(a5) // write? (dma modus reg) bne acsi_dma_wl // ja-> acsi_dma_rl: - tst.b -4(a5) // dma req? - bpl acsi_dma_finished // nein-> - move.l (a5),(a1)+ // read 4 bytes - move.l (a5),(a1)+ // read 4 bytes - move.l (a5),(a1)+ // read 4 bytes - move.l (a5),(a1)+ // read 4 bytes - - moveq #'.',d1 - move.b d1,MCF_PSC0_PSCTB_8BIT + tst.b -4(a5) // dma req? + bpl acsi_dma_finished // nein-> + move.l (a5),(a1)+ // read 4 bytes + move.l (a5),(a1)+ // read 4 bytes + move.l (a5),(a1)+ // read 4 bytes + move.l (a5),(a1)+ // read 4 bytes - sub.l #16,d0 // byt counter -16 - bpl acsi_dma_rl - bra acsi_dma_finished + moveq #'.',d1 + move.b d1,MCF_PSC0_PSCTB_8BIT + + sub.l #16,d0 // byt counter -16 + bpl acsi_dma_rl + bra acsi_dma_finished acsi_dma_wl: - tst.b -4(a5) // dma req? - bpl acsi_dma_finished // nein-> - move.l (a1)+,(a5) // write 4 byts - move.l (a1)+,(a5) // write 4 byts - move.l (a1)+,(a5) // write 4 byts - move.l (a1)+,(a5) // write 4 byts - - moveq #'.',d1 - move.b d1,MCF_PSC0_PSCTB_8BIT + tst.b -4(a5) // dma req? + bpl acsi_dma_finished // nein-> + move.l (a1)+,(a5) // write 4 byts + move.l (a1)+,(a5) // write 4 byts + move.l (a1)+,(a5) // write 4 byts + move.l (a1)+,(a5) // write 4 byts + + moveq #'.',d1 + move.b d1,MCF_PSC0_PSCTB_8BIT sub.l #16,d0 // byt counter -16 bpl acsi_dma_wl @@ -730,15 +730,15 @@ acsi_dma_finished: move.l a1,-12(a5) // adresse zur�ck move.l d0,-8(a5) // byt counter zur�ck acsi_dma_end: - tst.b -4(a5) // dma req? - bmi acsi_dma_start // ja-> - lea 0xfffffa0b,a5 - bclr.b #7,4(a5) // clear int in service mfp - bclr.b #7,(a5) // clear int pending mfp 0xfffffa0b - + tst.b -4(a5) // dma req? + bmi acsi_dma_start // ja-> + lea 0xfffffa0b,a5 + bclr.b #7,4(a5) // clear int in service mfp + bclr.b #7,(a5) // clear int pending mfp 0xfffffa0b + move.w #0x0d0a,d1 move.w d1,MCF_PSC0_PSCTB_8BIT - + move.l (a7)+,d1 move.l (a7)+,a1 rts @@ -773,7 +773,7 @@ irq7: * psc3 com PIC MCF */ handler_psc3: - .extern _pic_interrupt_handler + .extern _pic_interrupt_handler move.w #0x2700,sr // disable interrupt lea -4 * 4(sp),sp // save gcc scratch registers @@ -790,7 +790,7 @@ handler_psc3: * vbasehi is written to, i.e. when the video base address gets changed */ handler_gpt0: - move #0x2700,sr // disable interrupts + move #0x2700,sr // disable interrupts lea -28(a7),a7 // save registers movem.l d0-d4/a0-a1,(a7) @@ -802,8 +802,8 @@ handler_gpt0: // to 60d00000 (FPGA video memory) blt sca_other // - lea MCF_SLT0_SCNT,a0 - move.l (a0),_video_sbt // save time + lea MCF_SLT0_SCNT,a0 + move.l (a0),_video_sbt // save time bra video_chg_end // FIXME: don't we need to get out here? @@ -878,22 +878,22 @@ video_copy_data_loop: #endif // eintrag suchen - move.l d0,MCF_MMU_MMUAR // adress - move.l #0x106,d4 - move.l d4,MCF_MMU_MMUOR // search -> new one will be offered if not found - nop - move.l MCF_MMU_MMUOR,d4 - clr.w d4 - swap d4 - move.l d4,MCF_MMU_MMUAR - move.l d0,d1 - add.l #MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0 - add.l #0x60000000|writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 - mvz.w #0x10b,d2 // MMU update - move.l d0,MCF_MMU_MMUTR - move.l d1,MCF_MMU_MMUDR - move.l d2,MCF_MMU_MMUOR // setzen vidoe maped to 60xxx only data - nop + move.l d0,MCF_MMU_MMUAR // adress + move.l #0x106,d4 + move.l d4,MCF_MMU_MMUOR // search -> new one will be offered if not found + nop + move.l MCF_MMU_MMUOR,d4 + clr.w d4 + swap d4 + move.l d4,MCF_MMU_MMUAR + move.l d0,d1 + add.l #MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0 + add.l #0x60000000|writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 + mvz.w #0x10b,d2 // MMU update + move.l d0,MCF_MMU_MMUTR + move.l d1,MCF_MMU_MMUDR + move.l d2,MCF_MMU_MMUOR // setzen vidoe maped to 60xxx only data + nop video_chg_2page: // test of adjacent page is needed also @@ -927,8 +927,8 @@ video_chg_end: * low-level interrupt service routine for routines registered with * isr_register_handler() */ - .global _lowlevel_isr_handler - .extern _isr_execute_handler + .global _lowlevel_isr_handler + .extern _isr_execute_handler _lowlevel_isr_handler: move.w #0x2700,sr // disable interrupts diff --git a/sys/interrupts.c b/sys/interrupts.c index 31f7b44..bcd4a27 100644 --- a/sys/interrupts.c +++ b/sys/interrupts.c @@ -39,7 +39,7 @@ extern void (*rt_vbr[])(void); #define IRQ_DEBUG #if defined(IRQ_DEBUG) -#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) +#define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0) #else #define dbg(format, arg...) do { ; } while (0) #endif @@ -50,45 +50,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("%s: interrupt source %d not defined\r\n", __FUNCTION__, 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("%s: level %d and priority %d already used for interrupt source %d!\r\n", __FUNCTION__, - 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 @@ -98,10 +98,10 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority, typedef struct { - int vector; - int (*handler)(void *, void *); - void *hdev; - void *harg; + int vector; + int (*handler)(void *, void *); + void *hdev; + void *harg; } ISRENTRY; ISRENTRY isrtab[MAX_ISR_ENTRY]; @@ -109,132 +109,136 @@ ISRENTRY isrtab[MAX_ISR_ENTRY]; void isr_init(void) { - int index; + int index; - for (index = 0; index < MAX_ISR_ENTRY; index++) - { - isrtab[index].vector = 0; - isrtab[index].handler = 0; - isrtab[index].hdev = 0; - isrtab[index].harg = 0; - } + for (index = 0; index < MAX_ISR_ENTRY; index++) + { + isrtab[index].vector = 0; + isrtab[index].handler = 0; + isrtab[index].hdev = 0; + isrtab[index].harg = 0; + } } int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg) { - /* - * This function places an interrupt handler in the ISR table, - * thereby registering it so that the low-level handler may call it. - * - * The two parameters are intended for the first arg to be a - * pointer to the device itself, and the second a pointer to a data - * structure used by the device driver for that particular device. - */ - int index; + /* + * This function places an interrupt handler in the ISR table, + * thereby registering it so that the low-level handler may call it. + * + * The two parameters are intended for the first arg to be a + * pointer to the device itself, and the second a pointer to a data + * structure used by the device driver for that particular device. + */ + int index; - if ((vector == 0) || (handler == NULL)) - { - dbg("%s: illegal vector or handler!\r\n", __FUNCTION__); - 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("%s: already set handler with this vector (%d, %d)\r\n", __FUNCTION__, 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("%s: no available slots to register handler for vector %d\n\r", __FUNCTION__, 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) - { - isrtab[index].vector = 0; - isrtab[index].handler = 0; - isrtab[index].hdev = 0; - isrtab[index].harg = 0; + for (index = 0; index < MAX_ISR_ENTRY; index++) + { + if (isrtab[index].handler == handler) + { + isrtab[index].vector = 0; + isrtab[index].handler = 0; + isrtab[index].hdev = 0; + isrtab[index].harg = 0; - return; - } - } - dbg("%s: no such handler registered (handler=%p\r\n", __FUNCTION__, handler); + return; + } + } + dbg("no such handler registered (handler=%p\r\n", handler); } bool isr_execute_handler(int vector) { - /* - * This routine searches the ISR table for an entry that matches - * 'vector'. If one is found, then 'handler' is executed. - */ - int index; - bool retval = false; + /* + * This routine searches the ISR table for an entry that matches + * 'vector'. If one is found, then 'handler' is executed. + */ + int index; + bool retval = false; - /* - * First 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("%s: no BaS isr handler for vector %d found\r\n", __FUNCTION__, vector); - return retval; + /* + * 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); + + return retval; } +/* + * PIC interrupt handler for Firebee + */ void pic_interrupt_handler(void) { - 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); - } + MCF_PSC3_PSCTB_8BIT = 0x82; // header byte to PIC + do + { + *rtc_reg = 0; + MCF_PSC3_PSCTB_8BIT = *rtc_data; + } while (index++ < 64); + } } extern int32_t video_sbt; @@ -242,106 +246,166 @@ extern int32_t video_tlb; void video_addr_timeout(void) { - uint32_t addr = 0x0L; - uint32_t *src; - uint32_t *dst; - uint32_t asid; + uint32_t addr = 0x0L; + uint32_t *src; + uint32_t *dst; + uint32_t asid; - dbg("%s:\r\n", __FUNCTION__); - flush_and_invalidate_caches(); + dbg("video address timeout\r\n"); + flush_and_invalidate_caches(); - do - { - uint32_t tlb; - uint32_t page_attr; + 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 = + /* + * 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_ADR | MCF_MMU_MMUOR_RW | MCF_MMU_MMUOR_ACC; - NOP(); + NOP(); + tlb = (MCF_MMU_MMUOR >> 16) & 0xffff; - 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 = + /* + * 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_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(); + 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++; - } + { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + } - addr += 0x100000; - } while (addr < 0xd00000); - video_tlb = 0x2000; - video_sbt = 0; + addr += 0x100000; + } while (addr < 0xd00000); + video_tlb = 0x2000; + video_sbt = 0; } +static uint32_t blinker = 0; + +/* + * blink the Firebee's LED to show we are still alive + */ +void blink_led(void) +{ + if ((blinker++ & 0x80) > 0) + { + MCF_GPIO_PODR_FEC1L |= (1 << 4); /* LED off */ + } + else + { + MCF_GPIO_PODR_FEC1L &= ~(1 << 4); /* LED on */ + } +} + +/* + * Atari MFP interrupt registers. + * + * TODO: should go into a header file + */ + +#define FALCON_MFP_IERA *((volatile uint8_t *) 0xfffffa07) +#define FALCON_MFP_IERB *((volatile uint8_t *) 0xfffffa09) +#define FALCON_MFP_IPRA *((volatile uint8_t *) 0xfffffa0b) +#define FALCON_MFP_IPRB *((volatile uint8_t *) 0xfffffa0d) +#define FALCON_MFP_IMRA *((volatile uint8_t *) 0xfffffa13) +#define FALCON_MFP_IMRB *((volatile uint8_t *) 0xfffffa15) + +bool irq6_acsi_dma_interrupt(void) +{ + dbg("ACSI DMA interrupt\r\n"); + + /* + * TODO: implement handler + */ + + return false; +} bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2) { - MCF_EPORT_EPFR = 0x40; /* clear int6 from edge port */ + bool handled = false; - dbg("%s: irq6!\r\n", __FUNCTION__); + MCF_EPORT_EPFR &= (1 << 6); /* clear int6 from edge port */ - if (video_sbt != 0 && (video_sbt - 0x70000000) > MCF_SLT0_SCNT) - { - video_addr_timeout(); - } + if (video_sbt != 0 && (video_sbt - 0x70000000) > MCF_SLT0_SCNT) + { + video_addr_timeout(); + handled = true; + } - return false; + /* + * 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; } diff --git a/sys/mmu.c b/sys/mmu.c index 4801a4d..02ec821 100644 --- a/sys/mmu.c +++ b/sys/mmu.c @@ -44,7 +44,7 @@ #define DBG_MMU #ifdef DBG_MMU -#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg);} while(0) +#define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg);} while(0) #else #define dbg(format, arg...) do {;} while (0) #endif /* DBG_MMU */ @@ -55,19 +55,19 @@ */ inline uint32_t set_asid(uint32_t value) { - extern long rt_asid; - uint32_t ret = rt_asid; + extern long rt_asid; + uint32_t ret = rt_asid; - __asm__ __volatile__( - "movec %[value],ASID\n\t" - : /* no output */ - : [value] "r" (value) - : - ); + __asm__ __volatile__( + "movec %[value],ASID\n\t" + : /* no output */ + : [value] "r" (value) + : + ); - rt_asid = value; + rt_asid = value; - return ret; + return ret; } @@ -77,18 +77,18 @@ inline uint32_t set_asid(uint32_t value) */ inline uint32_t set_acr0(uint32_t value) { - extern uint32_t rt_acr0; - uint32_t ret = rt_acr0; + extern uint32_t rt_acr0; + uint32_t ret = rt_acr0; - __asm__ __volatile__( - "movec %[value],ACR0\n\t" - : /* not output */ - : [value] "r" (value) - : - ); - rt_acr0 = value; + __asm__ __volatile__( + "movec %[value],ACR0\n\t" + : /* not output */ + : [value] "r" (value) + : + ); + rt_acr0 = value; - return ret; + return ret; } /* @@ -97,18 +97,18 @@ inline uint32_t set_acr0(uint32_t value) */ inline uint32_t set_acr1(uint32_t value) { - extern uint32_t rt_acr1; - uint32_t ret = rt_acr1; + extern uint32_t rt_acr1; + uint32_t ret = rt_acr1; - __asm__ __volatile__( - "movec %[value],ACR1\n\t" - : /* not output */ - : [value] "r" (value) - : - ); - rt_acr1 = value; + __asm__ __volatile__( + "movec %[value],ACR1\n\t" + : /* not output */ + : [value] "r" (value) + : + ); + rt_acr1 = value; - return ret; + return ret; } @@ -118,18 +118,18 @@ inline uint32_t set_acr1(uint32_t value) */ inline uint32_t set_acr2(uint32_t value) { - extern uint32_t rt_acr2; - uint32_t ret = rt_acr2; + extern uint32_t rt_acr2; + uint32_t ret = rt_acr2; - __asm__ __volatile__( - "movec %[value],ACR2\n\t" - : /* not output */ - : [value] "r" (value) - : - ); - rt_acr2 = value; + __asm__ __volatile__( + "movec %[value],ACR2\n\t" + : /* not output */ + : [value] "r" (value) + : + ); + rt_acr2 = value; - return ret; + return ret; } /* @@ -138,35 +138,35 @@ inline uint32_t set_acr2(uint32_t value) */ inline uint32_t set_acr3(uint32_t value) { - extern uint32_t rt_acr3; - uint32_t ret = rt_acr3; + extern uint32_t rt_acr3; + uint32_t ret = rt_acr3; - __asm__ __volatile__( - "movec %[value],ACR3\n\t" - : /* not output */ - : [value] "r" (value) - : - ); - rt_acr3 = value; + __asm__ __volatile__( + "movec %[value],ACR3\n\t" + : /* not output */ + : [value] "r" (value) + : + ); + rt_acr3 = value; - return ret; + return ret; } inline uint32_t set_mmubar(uint32_t value) { - extern uint32_t rt_mmubar; - uint32_t ret = rt_mmubar; + extern uint32_t rt_mmubar; + uint32_t ret = rt_mmubar; - __asm__ __volatile__( - "movec %[value],MMUBAR\n\t" - : /* no output */ - : [value] "r" (value) - : /* no clobber */ - ); - rt_mmubar = value; - NOP(); + __asm__ __volatile__( + "movec %[value],MMUBAR\n\t" + : /* no output */ + : [value] "r" (value) + : /* no clobber */ + ); + rt_mmubar = value; + NOP(); - return ret; + return ret; } @@ -181,332 +181,332 @@ extern uint8_t _FASTRAM_END[]; struct mmu_mapping { - uint32_t phys; - uint32_t virt; - uint32_t length; - uint32_t pagesize; - struct map_flags flags; + uint32_t phys; + uint32_t virt; + uint32_t length; + uint32_t pagesize; + struct map_flags flags; }; static struct mmu_mapping locked_map[] = { - { - /* Falcon video memory. Needs special care */ - 0xd00000, - 0x60d00000, - 0x100000, - MMU_PAGE_SIZE_1M, - { CACHE_WRITETHROUGH, SV_USER, SCA_PAGE_ID, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, - }, + { + /* Falcon video memory. Needs special care */ + 0xd00000, + 0x60d00000, + 0x100000, + MMU_PAGE_SIZE_1M, + { CACHE_WRITETHROUGH, SV_USER, SCA_PAGE_ID, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, + }, }; static int num_locked_mmu_maps = sizeof(locked_map) / sizeof(struct mmu_mapping); static struct mmu_mapping memory_map[] = { - /* map system vectors supervisor-protected */ - { - 0, - 0, - 0x800, - MMU_PAGE_SIZE_1K, - { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, - }, - { - 0x800, - 0x800, - 0x800, - MMU_PAGE_SIZE_1K, - { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, - }, - { - /* when the first 4k are filled with 1k pages, we can switch to 8k pages */ - 0x1000, - 0x1000, - 0xff000, - MMU_PAGE_SIZE_8K, - { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, - }, - { - /* arrived at a 1Meg border, we can switch to 1Meg pages */ - 0x100000, - 0x100000, - 0xc00000, - MMU_PAGE_SIZE_1M, - { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, - }, - /* Falcon video ram left out intentionally here (see above) */ - { - /* ROM */ - 0xe00000, - 0xe00000, - 0x100000, - MMU_PAGE_SIZE_1M, - { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_EXECUTE }, - }, - { - /* FASTRAM */ - 0x1000000, - 0x1000000, - _FASTRAM_END - 0x1000000, - MMU_PAGE_SIZE_1M, - { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, - }, - { - /* MBAR */ - MBAR_ADDRESS, - MBAR_ADDRESS, - 0x100000, - MMU_PAGE_SIZE_1M, - { CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE }, - }, - { - /* RAMBAR0 */ - RAMBAR0_ADDRESS, - RAMBAR0_ADDRESS, - (uint32_t) _RAMBAR0_SIZE, - MMU_PAGE_SIZE_1K, - { CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, - }, - { - /* RAMBAR1 */ - RAMBAR1_ADDRESS, - RAMBAR1_ADDRESS, - (uint32_t) _RAMBAR1_SIZE, - MMU_PAGE_SIZE_1K, - { CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, - }, - { - /* SYSTEM SRAM */ - SYS_SRAM_ADDRESS, - SYS_SRAM_ADDRESS, - (uint32_t) _SYS_SRAM_SIZE, - MMU_PAGE_SIZE_8K, - { CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, - }, - { - /* Firebee FPGA registers */ - (uint32_t) 0xf0000000, - (uint32_t) 0xf0000000, - (uint32_t) 0x08000000, - MMU_PAGE_SIZE_1M, - { CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE }, - }, - { - /* Falcon I/O registers */ - (uint32_t) 0xfff00000, - (uint32_t) 0xfff00000, - (uint32_t) 0x100000, - MMU_PAGE_SIZE_1M, - { CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE }, - }, - { - /* the same, but different virtual address */ - (uint32_t) 0x00f00000, - (uint32_t) 0xfff00000, - (uint32_t) 0x100000, - MMU_PAGE_SIZE_1M, - { CACHE_NOCACHE_PRECISE, SV_PROTECT, ACCESS_READ | ACCESS_WRITE }, - } + /* map system vectors supervisor-protected */ + { + 0, + 0, + 0x800, + MMU_PAGE_SIZE_1K, + { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, + }, + { + 0x800, + 0x800, + 0x800, + MMU_PAGE_SIZE_1K, + { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, + }, + { + /* when the first 4k are filled with 1k pages, we can switch to 8k pages */ + 0x1000, + 0x1000, + 0xff000, + MMU_PAGE_SIZE_8K, + { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, + }, + { + /* arrived at a 1Meg border, we can switch to 1Meg pages */ + 0x100000, + 0x100000, + 0xc00000, + MMU_PAGE_SIZE_1M, + { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, + }, + /* Falcon video ram left out intentionally here (see above) */ + { + /* ROM */ + 0xe00000, + 0xe00000, + 0x100000, + MMU_PAGE_SIZE_1M, + { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_EXECUTE }, + }, + { + /* FASTRAM */ + 0x1000000, + 0x1000000, + (uint32_t) _FASTRAM_END - 0x1000000, + MMU_PAGE_SIZE_1M, + { CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, + }, + { + /* MBAR */ + MBAR_ADDRESS, + MBAR_ADDRESS, + 0x100000, + MMU_PAGE_SIZE_1M, + { CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE }, + }, + { + /* RAMBAR0 */ + RAMBAR0_ADDRESS, + RAMBAR0_ADDRESS, + (uint32_t) _RAMBAR0_SIZE, + MMU_PAGE_SIZE_1K, + { CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, + }, + { + /* RAMBAR1 */ + RAMBAR1_ADDRESS, + RAMBAR1_ADDRESS, + (uint32_t) _RAMBAR1_SIZE, + MMU_PAGE_SIZE_1K, + { CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, + }, + { + /* SYSTEM SRAM */ + SYS_SRAM_ADDRESS, + SYS_SRAM_ADDRESS, + (uint32_t) _SYS_SRAM_SIZE, + MMU_PAGE_SIZE_8K, + { CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE }, + }, + { + /* Firebee FPGA registers */ + (uint32_t) 0xf0000000, + (uint32_t) 0xf0000000, + (uint32_t) 0x08000000, + MMU_PAGE_SIZE_1M, + { CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE }, + }, + { + /* Falcon I/O registers */ + (uint32_t) 0xfff00000, + (uint32_t) 0xfff00000, + (uint32_t) 0x100000, + MMU_PAGE_SIZE_1M, + { CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE }, + }, + { + /* the same, but different virtual address */ + (uint32_t) 0x00f00000, + (uint32_t) 0xfff00000, + (uint32_t) 0x100000, + MMU_PAGE_SIZE_1M, + { CACHE_NOCACHE_PRECISE, SV_PROTECT, ACCESS_READ | ACCESS_WRITE }, + } }; static int num_mmu_maps = sizeof(memory_map) / sizeof(struct mmu_mapping); static struct mmu_mapping *lookup_mapping(uint32_t virt) { - int i; + int i; - /* - * dumb, for now - */ + /* + * dumb, for now + */ - for (i = 0; i < num_mmu_maps; i++) - { - if (virt >= memory_map[i].virt && virt <= memory_map[i].virt + memory_map[i].length - 1) - return &memory_map[i]; - } - return NULL; + for (i = 0; i < num_mmu_maps; i++) + { + if (virt >= memory_map[i].virt && virt <= memory_map[i].virt + memory_map[i].length - 1) + return &memory_map[i]; + } + return NULL; } void mmu_init(void) { - extern uint8_t _MMUBAR[]; - uint32_t MMUBAR = (uint32_t) &_MMUBAR[0]; - int i; + extern uint8_t _MMUBAR[]; + uint32_t MMUBAR = (uint32_t) &_MMUBAR[0]; + int i; - set_asid(0); /* do not use address extension (ASID provides virtual 48 bit addresses */ + set_asid(0); /* do not use address extension (ASID provides virtual 48 bit addresses */ - /* - * need to set data ACRs in a way that supervisor access to all memory regions - * becomes possible. Otherways it might be that the supervisor stack ends up in an unmapped - * region when further MMU TLB entries force a page steal. This would lead to a double - * fault since the CPU wouldn't be able to push its exception stack frame during an access - * exception - */ + /* + * need to set data ACRs in a way that supervisor access to all memory regions + * becomes possible. Otherways it might be that the supervisor stack ends up in an unmapped + * region when further MMU TLB entries force a page steal. This would lead to a double + * fault since the CPU wouldn't be able to push its exception stack frame during an access + * exception + */ - /* set data access attributes in ACR0 and ACR1 */ + /* set data access attributes in ACR0 and ACR1 */ - set_acr0(ACR_WRITE_PROTECT(0) | /* read and write accesses permitted */ - ACR_SUPERVISOR_PROTECT(0) | /* supervisor and user mode access permitted */ - ACR_CACHE_MODE(CACHE_WRITETHROUGH) | /* cacheable, write through */ - ACR_ADDRESS_MASK_MODE(1) | /* region 13 MByte */ - ACR_S(ACR_S_SUPERVISOR_MODE) | /* memory only visible from supervisor mode */ - ACR_E(1) | /* enable ACR */ - ACR_ADMSK(0x0a) | /* cover 12 MByte from 0x0 */ - ACR_BA(0)); /* start from 0x0 */ + set_acr0(ACR_WRITE_PROTECT(0) | /* read and write accesses permitted */ + ACR_SUPERVISOR_PROTECT(0) | /* supervisor and user mode access permitted */ + ACR_CACHE_MODE(CACHE_WRITETHROUGH) | /* cacheable, write through */ + ACR_ADDRESS_MASK_MODE(1) | /* region 13 MByte */ + ACR_S(ACR_S_SUPERVISOR_MODE) | /* memory only visible from supervisor mode */ + ACR_E(1) | /* enable ACR */ + ACR_ADMSK(0x0a) | /* cover 12 MByte from 0x0 */ + ACR_BA(0)); /* start from 0x0 */ - set_acr1(ACR_WRITE_PROTECT(0) | /* read and write accesses permitted */ - ACR_SUPERVISOR_PROTECT(0) | /* supervisor and user mode access permitted */ - ACR_CACHE_MODE(CACHE_WRITETHROUGH) | /* cacheable, write through */ - ACR_ADDRESS_MASK_MODE(0) | /* region > 16 MByte */ - ACR_S(ACR_S_SUPERVISOR_MODE) | /* memory only visible from supervisor mode */ - ACR_E(1) | /* enable ACR */ - ACR_ADMSK(0x1f) | /* cover 495 MByte from 0x1000000 */ - ACR_BA(0x01000000)); /* all Fast RAM */ + set_acr1(ACR_WRITE_PROTECT(0) | /* read and write accesses permitted */ + ACR_SUPERVISOR_PROTECT(0) | /* supervisor and user mode access permitted */ + ACR_CACHE_MODE(CACHE_WRITETHROUGH) | /* cacheable, write through */ + ACR_ADDRESS_MASK_MODE(0) | /* region > 16 MByte */ + ACR_S(ACR_S_SUPERVISOR_MODE) | /* memory only visible from supervisor mode */ + ACR_E(1) | /* enable ACR */ + ACR_ADMSK(0x1f) | /* cover 495 MByte from 0x1000000 */ + ACR_BA(0x01000000)); /* all Fast RAM */ - /* - * set instruction access attributes in ACR2 and ACR3. This is the same as above, basically: - * enable supervisor access to all SDRAM - */ + /* + * set instruction access attributes in ACR2 and ACR3. This is the same as above, basically: + * enable supervisor access to all SDRAM + */ - set_acr2(ACR_WRITE_PROTECT(0) | - ACR_SUPERVISOR_PROTECT(0) | - ACR_CACHE_MODE(CACHE_WRITETHROUGH) | - ACR_ADDRESS_MASK_MODE(1) | - ACR_S(ACR_S_SUPERVISOR_MODE) | - ACR_E(1) | - ACR_ADMSK(0x0c) | - ACR_BA(0x0)); + set_acr2(ACR_WRITE_PROTECT(0) | + ACR_SUPERVISOR_PROTECT(0) | + ACR_CACHE_MODE(CACHE_WRITETHROUGH) | + ACR_ADDRESS_MASK_MODE(1) | + ACR_S(ACR_S_SUPERVISOR_MODE) | + ACR_E(1) | + ACR_ADMSK(0x0c) | + ACR_BA(0x0)); - set_acr3(ACR_WRITE_PROTECT(0) | - ACR_SUPERVISOR_PROTECT(0) | - ACR_CACHE_MODE(CACHE_WRITETHROUGH) | - ACR_ADDRESS_MASK_MODE(0) | - ACR_S(ACR_S_SUPERVISOR_MODE) | - ACR_E(1) | - ACR_ADMSK(0x1f) | - ACR_BA(0x0f)); + set_acr3(ACR_WRITE_PROTECT(0) | + ACR_SUPERVISOR_PROTECT(0) | + ACR_CACHE_MODE(CACHE_WRITETHROUGH) | + ACR_ADDRESS_MASK_MODE(0) | + ACR_S(ACR_S_SUPERVISOR_MODE) | + ACR_E(1) | + ACR_ADMSK(0x1f) | + ACR_BA(0x0f)); - set_mmubar(MMUBAR + 1); /* set and enable MMUBAR */ + set_mmubar(MMUBAR + 1); /* set and enable MMUBAR */ - /* clear all MMU TLB entries */ - MCF_MMU_MMUOR = MCF_MMU_MMUOR_CA; + /* clear all MMU TLB entries */ + MCF_MMU_MMUOR = MCF_MMU_MMUOR_CA; - /* map locked TLB entries */ - for (i = 0; i < num_locked_mmu_maps; i++) - { - mmu_map_page(locked_map[i].virt, locked_map[i].phys, locked_map->pagesize, locked_map->flags); + /* map locked TLB entries */ + for (i = 0; i < num_locked_mmu_maps; i++) + { + mmu_map_page(locked_map[i].virt, locked_map[i].phys, locked_map->pagesize, locked_map->flags); - if (locked_map[i].flags.page_id == SCA_PAGE_ID) - { - video_tlb = 0x2000; - video_sbt = 0x0; - } - } + if (locked_map[i].flags.page_id == SCA_PAGE_ID) + { + video_tlb = 0x2000; + video_sbt = 0x0; + } + } } /* - * handle an access error + * handle an access error * upper level routine called from access_exception inside exceptions.S */ bool access_exception(uint32_t pc, uint32_t format_status) { - int fault_status; - uint32_t fault_address; - uint32_t mmu_status; + int fault_status; + uint32_t fault_address; + uint32_t mmu_status; - /* - * extract fault status from format_status exception stack field - */ - fault_status = format_status & 0xc030000; - mmu_status = MCF_MMU_MMUSR; + /* + * extract fault status from format_status exception stack field + */ + fault_status = format_status & 0xc030000; + mmu_status = MCF_MMU_MMUSR; - /* - * determine if access fault was caused by a TLB miss - */ - switch (fault_status) - { - case 0x4010000: /* TLB miss on opword of instruction fetch */ - case 0x4020000: /* TLB miss on extension word of instruction fetch */ - fault_address = pc; - break; - case 0x8020000: /* TLB miss on data write */ - case 0xc020000: /* TLB miss on data read or read-modify-write */ - fault_address = MCF_MMU_MMUAR; - //dbg("%s: access fault - TLB miss at %p. Fault status = 0x0%x\r\n", __FUNCTION__, pc, fault_status); - break; + /* + * determine if access fault was caused by a TLB miss + */ + switch (fault_status) + { + case 0x4010000: /* TLB miss on opword of instruction fetch */ + case 0x4020000: /* TLB miss on extension word of instruction fetch */ + fault_address = pc; + break; + case 0x8020000: /* TLB miss on data write */ + case 0xc020000: /* TLB miss on data read or read-modify-write */ + fault_address = MCF_MMU_MMUAR; + dbg("access fault - TLB miss at %p. Fault status = 0x0%x\r\n", pc, fault_status); + break; - default: - return false; - } + default: + return false; + } - if (mmu_status & MCF_MMU_MMUSR_HIT) /* did the last fault hit in TLB? */ - { - /* - * if yes, then we already mapped that page during a previous turn and this is in fact a bus error - */ - return false; - } - else - { - struct mmu_mapping *map; + if (mmu_status & MCF_MMU_MMUSR_HIT) /* did the last fault hit in TLB? */ + { + /* + * if yes, then we already mapped that page during a previous turn and this is in fact a bus error + */ + return false; + } + else + { + struct mmu_mapping *map; - if ((map = lookup_mapping(fault_address)) != NULL) - { - uint32_t mask; + if ((map = lookup_mapping(fault_address)) != NULL) + { + uint32_t mask; - switch (map->pagesize) - { - case MMU_PAGE_SIZE_1M: - mask = ~(0x100000 - 1); - break; - case MMU_PAGE_SIZE_4K: - mask = ~(0x1000 - 1); - break; - case MMU_PAGE_SIZE_8K: - mask = ~(0x2000 - 1); - break; - case MMU_PAGE_SIZE_1K: - mask = ~(0x400 - 1); - break; - } + switch (map->pagesize) + { + case MMU_PAGE_SIZE_1M: + mask = ~(0x100000 - 1); + break; + case MMU_PAGE_SIZE_4K: + mask = ~(0x1000 - 1); + break; + case MMU_PAGE_SIZE_8K: + mask = ~(0x2000 - 1); + break; + case MMU_PAGE_SIZE_1K: + mask = ~(0x400 - 1); + break; + } - mmu_map_page(fault_address & mask, fault_address & mask, map->pagesize, map->flags); - return true; - } - } - return false; + mmu_map_page(fault_address & mask, fault_address & mask, map->pagesize, map->flags); + return true; + } + } + return false; } void mmu_map_page(uint32_t virt, uint32_t phys, uint32_t map_size, struct map_flags flags) { - /* - * add page to TLB - */ - MCF_MMU_MMUTR = virt | /* virtual address */ - MCF_MMU_MMUTR_ID(flags.page_id) | - MCF_MMU_MMUTR_SG | /* shared global */ - MCF_MMU_MMUTR_V; /* valid */ + /* + * add page to TLB + */ + MCF_MMU_MMUTR = virt | /* virtual address */ + MCF_MMU_MMUTR_ID(flags.page_id) | + MCF_MMU_MMUTR_SG | /* shared global */ + MCF_MMU_MMUTR_V; /* valid */ - MCF_MMU_MMUDR = phys | /* physical address */ - MCF_MMU_MMUDR_SZ(map_size) | /* 1 MB page size */ - MCF_MMU_MMUDR_CM(flags.cache_mode) | - (flags.access & ACCESS_READ ? MCF_MMU_MMUDR_R : 0) | /* read access enable */ - (flags.access & ACCESS_WRITE ? MCF_MMU_MMUDR_W : 0) | /* write access enable */ - (flags.access & ACCESS_EXECUTE ? MCF_MMU_MMUDR_X : 0); /* execute access enable */ + MCF_MMU_MMUDR = phys | /* physical address */ + MCF_MMU_MMUDR_SZ(map_size) | /* 1 MB page size */ + MCF_MMU_MMUDR_CM(flags.cache_mode) | + (flags.access & ACCESS_READ ? MCF_MMU_MMUDR_R : 0) | /* read access enable */ + (flags.access & ACCESS_WRITE ? MCF_MMU_MMUDR_W : 0) | /* write access enable */ + (flags.access & ACCESS_EXECUTE ? MCF_MMU_MMUDR_X : 0); /* execute access enable */ - MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */ - MCF_MMU_MMUOR_UAA; /* update allocation address field */ + MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */ + MCF_MMU_MMUOR_UAA; /* update allocation address field */ - MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */ - MCF_MMU_MMUOR_ACC | /* access TLB */ - MCF_MMU_MMUOR_UAA; /* update allocation address field */ - dbg("%s: mapped virt=%p to phys=%p\r\n", __FUNCTION__, virt, phys); + MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */ + MCF_MMU_MMUOR_ACC | /* access TLB */ + MCF_MMU_MMUOR_UAA; /* update allocation address field */ + dbg("mapped virt=%p to phys=%p\r\n", virt, phys); } diff --git a/sys/sysinit.c b/sys/sysinit.c index 7235d99..1c90567 100644 --- a/sys/sysinit.c +++ b/sys/sysinit.c @@ -95,10 +95,10 @@ void init_gpio(void) * * for DMA operation */ - MCF_PAD_PAR_DMA = MCF_PAD_PAR_DMA_PAR_DACK0(0b11) | - MCF_PAD_PAR_DMA_PAR_DACK1(0b11) | - MCF_PAD_PAR_DMA_PAR_DREQ1(0b11) | - MCF_PAD_PAR_DMA_PAR_DREQ0(0b11); + MCF_PAD_PAR_DMA = MCF_PAD_PAR_DMA_PAR_DACK0(0x3) | + MCF_PAD_PAR_DMA_PAR_DACK1(0x3) | + MCF_PAD_PAR_DMA_PAR_DREQ1(0x3) | + MCF_PAD_PAR_DMA_PAR_DREQ0(0x3); /* * configure FEC0 pin assignment on GPIO module as FEC0