diff --git a/include/mmu.h b/include/mmu.h index 0e74440..3a45c7f 100644 --- a/include/mmu.h +++ b/include/mmu.h @@ -58,19 +58,22 @@ enum mmu_page_size { - MMU_PAGE_SIZE_1M = 0, - MMU_PAGE_SIZE_4K = 1, - MMU_PAGE_SIZE_8K = 2, - MMU_PAGE_SIZE_1K = 3 + MMU_PAGE_SIZE_1M = 0, + MMU_PAGE_SIZE_4K = 1, + MMU_PAGE_SIZE_8K = 2, + MMU_PAGE_SIZE_1K = 3 }; /* * cache modes */ -#define CACHE_WRITETHROUGH 0 -#define CACHE_COPYBACK 1 -#define CACHE_NOCACHE_PRECISE 2 -#define CACHE_NOCACHE_IMPRECISE 3 +enum mmu_cache_modes +{ + CACHE_WRITETHROUGH = 0, + CACHE_COPYBACK = 1, + CACHE_NOCACHE_PRECISE = 2, + CACHE_NOCACHE_IMPRECISE = 3 +}; /* diff --git a/sys/BaS.c b/sys/BaS.c index 8e520a3..4d0098e 100644 --- a/sys/BaS.c +++ b/sys/BaS.c @@ -76,10 +76,10 @@ extern uint8_t _EMUTOS_SIZE[]; */ static inline bool pic_txready(void) { - if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY) - return true; + if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY) + return true; - return false; + return false; } /* @@ -87,84 +87,84 @@ static inline bool pic_txready(void) */ static inline bool pic_rxready(void) { - if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY) - return true; + if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY) + return true; - return false; + return false; } void write_pic_byte(uint8_t value) { - /* Wait until the transmitter is ready or 1000us are passed */ - waitfor(1000, pic_txready); + /* Wait until the transmitter is ready or 1000us are passed */ + waitfor(1000, pic_txready); - /* Transmit the byte */ - *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit + /* Transmit the byte */ + *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit } uint8_t read_pic_byte(void) { - /* Wait until a byte has been received or 1000us are passed */ - waitfor(1000, pic_rxready); + /* Wait until a byte has been received or 1000us are passed */ + waitfor(1000, pic_rxready); - /* Return the received byte */ - return * (volatile uint8_t *) (&MCF_PSC3_PSCTB_8BIT); // Really 8-bit + /* Return the received byte */ + return * (volatile uint8_t *) (&MCF_PSC3_PSCTB_8BIT); // Really 8-bit } void pic_init(void) { - char answer[4] = "OLD"; + char answer[4] = "OLD"; - xprintf("initialize the PIC: "); + xprintf("initialize the PIC: "); - /* Send the PIC initialization string */ - write_pic_byte('A'); - write_pic_byte('C'); - write_pic_byte('P'); - write_pic_byte('F'); + /* Send the PIC initialization string */ + write_pic_byte('A'); + write_pic_byte('C'); + write_pic_byte('P'); + write_pic_byte('F'); - /* Read the 3-char answer string. Should be "OK!". */ - answer[0] = read_pic_byte(); - answer[1] = read_pic_byte(); - answer[2] = read_pic_byte(); - answer[3] = '\0'; + /* Read the 3-char answer string. Should be "OK!". */ + answer[0] = read_pic_byte(); + answer[1] = read_pic_byte(); + answer[2] = read_pic_byte(); + answer[3] = '\0'; - if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!') - { - dbg("PIC initialization failed. Already initialized?\r\n"); - } - else - { - xprintf("%s\r\n", answer); - } + if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!') + { + dbg("PIC initialization failed. Already initialized?\r\n"); + } + else + { + xprintf("%s\r\n", answer); + } } void nvram_init(void) { - int i; + int i; - xprintf("Restore the NVRAM data: "); + xprintf("Restore the NVRAM data: "); - /* Request for NVRAM backup data */ - write_pic_byte(0x01); + /* Request for NVRAM backup data */ + write_pic_byte(0x01); - /* Check answer type */ - if (read_pic_byte() != 0x81) - { - // FIXME: PIC protocol error - xprintf("FAILED\r\n"); - return; - } + /* Check answer type */ + if (read_pic_byte() != 0x81) + { + // FIXME: PIC protocol error + xprintf("FAILED\r\n"); + return; + } - /* Restore the NVRAM backup to the FPGA */ - for (i = 0; i < 64; i++) - { - uint8_t data = read_pic_byte(); - *(volatile uint8_t*)0xffff8961 = i; - *(volatile uint8_t*)0xffff8963 = data; - } + /* Restore the NVRAM backup to the FPGA */ + for (i = 0; i < 64; i++) + { + uint8_t data = read_pic_byte(); + *(volatile uint8_t*)0xffff8961 = i; + *(volatile uint8_t*)0xffff8963 = data; + } - xprintf("finished\r\n"); + xprintf("finished\r\n"); } #define KBD_ACIA_CONTROL ((uint8_t *) 0xfffffc00) @@ -174,24 +174,24 @@ void nvram_init(void) void acia_init() { - xprintf("init ACIA: "); - /* init ACIA */ - * KBD_ACIA_CONTROL = 3; /* master reset */ - NOP(); + xprintf("init ACIA: "); + /* init ACIA */ + * KBD_ACIA_CONTROL = 3; /* master reset */ + NOP(); - * MIDI_ACIA_CONTROL = 3; /* master reset */ - NOP(); + * MIDI_ACIA_CONTROL = 3; /* master reset */ + NOP(); - * KBD_ACIA_CONTROL = 0x96; /* clock div = 64, 8N1, RTS low, TX int disable, RX int enable */ - NOP(); + * KBD_ACIA_CONTROL = 0x96; /* clock div = 64, 8N1, RTS low, TX int disable, RX int enable */ + NOP(); - * MFP_INTR_IN_SERVICE_A = -1; - NOP(); + * MFP_INTR_IN_SERVICE_A = -1; + NOP(); - * MFP_INTR_IN_SERVICE_B = -1; - NOP(); + * MFP_INTR_IN_SERVICE_B = -1; + NOP(); - xprintf("finished\r\n"); + xprintf("finished\r\n"); } /* ACP interrupt controller */ @@ -201,43 +201,43 @@ void acia_init() void enable_coldfire_interrupts() { - xprintf("enable interrupts: "); + xprintf("enable interrupts: "); #if defined(MACHINE_FIREBEE) - *FPGA_INTR_CONTRL = 0L; /* disable all interrupts */ + *FPGA_INTR_CONTRL = 0L; /* disable all interrupts */ #endif /* MACHINE_FIREBEE */ - MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */ + MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */ #if defined(MACHINE_FIREBEE) - /* - * TIN0 on the Coldfire is connected to the FPGA. TIN0 triggers every write - * access to 0xff8201 (vbasehi), i.e. everytime the video base address is written - */ - MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */ - MCF_GPT_GMS_IEN | - MCF_GPT_GMS_TMS(1); - /* route GPT0 interrupt on interrupt controller */ - MCF_INTC_ICR62 = 0x3f; /* interrupt level 7, interrupt priority 7 */ + /* + * TIN0 on the Coldfire is connected to the FPGA. TIN0 triggers every write + * access to 0xff8201 (vbasehi), i.e. everytime the video base address is written + */ + MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */ + MCF_GPT_GMS_IEN | + MCF_GPT_GMS_TMS(1); + /* route GPT0 interrupt on interrupt controller */ + MCF_INTC_ICR62 = 0x3f; /* interrupt level 7, interrupt priority 7 */ - *FPGA_INTR_ENABLE = 0xfe; /* enable int 1-7 */ - MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */ - MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */ - MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */ - MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */ + *FPGA_INTR_ENABLE = 0xfe; /* enable int 1-7 */ + MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */ + MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */ + MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */ + MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */ #endif - xprintf("finished\r\n"); + xprintf("finished\r\n"); } void disable_coldfire_interrupts() { #if defined(MACHINE_FIREBEE) - *FPGA_INTR_ENABLE = 0; /* disable all interrupts */ + *FPGA_INTR_ENABLE = 0; /* disable all interrupts */ #endif /* MACHINE_FIREBEE */ - MCF_EPORT_EPIER = 0x0; - MCF_EPORT_EPFR = 0x0; - MCF_INTC_IMRL = 0xfffffffe; - MCF_INTC_IMRH = 0xffffffff; + MCF_EPORT_EPIER = 0x0; + MCF_EPORT_EPFR = 0x0; + MCF_INTC_IMRL = 0xfffffffe; + MCF_INTC_IMRH = 0xffffffff; } @@ -252,178 +252,179 @@ NIF nif2; */ void init_isr(void) { - isr_init(); /* need to call that explicitely, otherwise isr table might be full */ + isr_init(); /* need to call that explicitely, otherwise isr table might be full */ - /* - * register the FEC interrupt handler - */ - if (!isr_register_handler(64 + INT_SOURCE_FEC0, fec0_interrupt_handler, NULL, (void *) &nif1)) - { - dbg("unable to register isr for FEC0\r\n"); - return; - } + /* + * register the FEC interrupt handler + */ + if (!isr_register_handler(64 + INT_SOURCE_FEC0, fec0_interrupt_handler, NULL, (void *) &nif1)) + { + dbg("unable to register isr for FEC0\r\n"); + return; + } - /* - * Register the DMA interrupt handler - */ + /* + * Register the DMA interrupt handler + */ - if (!isr_register_handler(64 + INT_SOURCE_DMA, dma_interrupt_handler, NULL,NULL)) - { - dbg("Error: Unable to register isr for DMA\r\n"); - return; - } + if (!isr_register_handler(64 + INT_SOURCE_DMA, dma_interrupt_handler, NULL,NULL)) + { + dbg("Error: Unable to register isr for DMA\r\n"); + return; + } - dma_irq_enable(5, 3); /* TODO: need to match the FEC driver's specs in MiNT? */ + dma_irq_enable(5, 3); /* TODO: need to match the FEC driver's specs in MiNT? */ - /* - * register the PIC interrupt handler - */ - if (isr_register_handler(64 + INT_SOURCE_PSC3, pic_interrupt_handler, NULL, NULL)) - { - dbg("Error: unable to register ISR for PSC3\r\n"); - return; - } + /* + * register the PIC interrupt handler + */ + if (isr_register_handler(64 + INT_SOURCE_PSC3, pic_interrupt_handler, NULL, NULL)) + { + dbg("Error: unable to register ISR for PSC3\r\n"); + return; + } } void BaS(void) { - uint8_t *src; - uint8_t *dst = (uint8_t *) TOS; + uint8_t *src; + uint8_t *dst = (uint8_t *) TOS; #if defined(MACHINE_FIREBEE) /* LITE board has no pic and (currently) no nvram */ - pic_init(); - nvram_init(); + pic_init(); + nvram_init(); #endif /* MACHINE_FIREBEE */ - xprintf("copy EmuTOS: "); + xprintf("copy EmuTOS: "); - /* copy EMUTOS */ - src = (uint8_t *) EMUTOS; - dma_memcpy(dst, src, EMUTOS_SIZE); - xprintf("finished\r\n"); + /* copy EMUTOS */ + src = (uint8_t *) EMUTOS; + dma_memcpy(dst, src, EMUTOS_SIZE); + xprintf("finished\r\n"); - xprintf("initialize MMU: "); - mmu_init(); - xprintf("finished\r\n"); + xprintf("initialize MMU: "); + mmu_init(); + xprintf("finished\r\n"); - xprintf("initialize exception vector table: "); - vec_init(); - xprintf("finished\r\n"); + xprintf("enable MMU: "); + MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */ + NOP(); /* force pipeline sync */ + xprintf("finished\r\n"); - xprintf("flush caches: "); - flush_and_invalidate_caches(); - xprintf("finished\r\n"); - xprintf("enable MMU: "); - MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */ - NOP(); /* force pipeline sync */ - xprintf("finished\r\n"); + xprintf("initialize exception vector table: "); + vec_init(); + xprintf("finished\r\n"); - #ifdef MACHINE_FIREBEE - xprintf("IDE reset: "); - /* IDE reset */ - * (volatile uint8_t *) (0xffff8802 - 2) = 14; - * (volatile uint8_t *) (0xffff8802 - 0) = 0x80; - wait(1); + xprintf("flush caches: "); + flush_and_invalidate_caches(); + xprintf("finished\r\n"); - * (volatile uint8_t *) (0xffff8802 - 0) = 0; + #ifdef MACHINE_FIREBEE + xprintf("IDE reset: "); + /* IDE reset */ + * (volatile uint8_t *) (0xffff8802 - 2) = 14; + * (volatile uint8_t *) (0xffff8802 - 0) = 0x80; + wait(1); - xprintf("finished\r\n"); - xprintf("enable video: "); - /* - * video setup (25MHz) - */ - * (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */ - * (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */ - * (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */ - * (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */ + * (volatile uint8_t *) (0xffff8802 - 0) = 0; + + xprintf("finished\r\n"); + xprintf("enable video: "); + /* + * video setup (25MHz) + */ + * (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */ + * (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */ + * (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */ + * (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */ #ifdef _NOT_USED_ // 32MHz - * (volatile uint32_t *) (0xf0000410 + 0) = 0x037002ba; /* horizontal 640x480 */ - * (volatile uint32_t *) (0xf0000410 + 4) = 0x020d020a; /* vertical 640x480 */ - * (volatile uint32_t *) (0xf0000410 + 8) = 0x02a001e0; /* horizontal 320x240 */ - * (volatile uint32_t *) (0xf0000410 + 12) = 0x05a00160; /* vertical 320x230 */ + * (volatile uint32_t *) (0xf0000410 + 0) = 0x037002ba; /* horizontal 640x480 */ + * (volatile uint32_t *) (0xf0000410 + 4) = 0x020d020a; /* vertical 640x480 */ + * (volatile uint32_t *) (0xf0000410 + 8) = 0x02a001e0; /* horizontal 320x240 */ + * (volatile uint32_t *) (0xf0000410 + 12) = 0x05a00160; /* vertical 320x230 */ #endif /* _NOT_USED_ */ - /* fifo on, refresh on, ddrcs and cke on, video dac on */ - * (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002; + /* fifo on, refresh on, ddrcs and cke on, video dac on */ + * (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002; - xprintf("finished\r\n"); + xprintf("finished\r\n"); - enable_coldfire_interrupts(); + enable_coldfire_interrupts(); #ifdef _NOT_USED_ - screen_init(); + screen_init(); - /* experimental */ - { - int i; - uint32_t *scradr = 0xd00000; + /* experimental */ + { + int i; + uint32_t *scradr = 0xd00000; - for (i = 0; i < 100; i++) - { - uint32_t *p = scradr; + for (i = 0; i < 100; i++) + { + uint32_t *p = scradr; - for (p = scradr; p < scradr + 1024 * 150L; p++) - { - *p = 0xffffffff; - } + for (p = scradr; p < scradr + 1024 * 150L; p++) + { + *p = 0xffffffff; + } - for (p = scradr; p < scradr + 1024 * 150L; p++) - { - *p = 0x0; - } - } - } + for (p = scradr; p < scradr + 1024 * 150L; p++) + { + *p = 0x0; + } + } + } #endif /* _NOT_USED_ */ #endif /* MACHINE_FIREBEE */ - sd_card_init(); + sd_card_init(); - /* - * memory setup - */ - memset((void *) 0x400, 0, 0x400); + /* + * memory setup + */ + memset((void *) 0x400, 0, 0x400); #if defined(MACHINE_FIREBEE) - /* set Falcon bus control register */ - /* sets bit 3 and 6. Both are undefined on an original Falcon? */ + /* set Falcon bus control register */ + /* sets bit 3 and 6. Both are undefined on an original Falcon? */ - * (volatile uint8_t *) 0xffff8007 = 0x48; + * (volatile uint8_t *) 0xffff8007 = 0x48; #endif /* MACHINE_FIREBEE */ - /* ST RAM */ + /* ST RAM */ - * (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */ - * (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */ - * (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */ - * (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */ + * (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */ + * (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */ + * (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */ + * (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */ - /* TT-RAM */ + /* TT-RAM */ - * (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */ - * (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */ + * (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */ + * (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */ #if defined(MACHINE_FIREBEE) /* m5484lite has no ACIA and no dip switch... */ - acia_init(); + acia_init(); #endif /* MACHINE_FIREBEE */ - srec_execute("BASFLASH.S19"); + srec_execute("BASFLASH.S19"); - /* Jump into the OS */ - typedef void void_func(void); - struct rom_header - { - void *initial_sp; - void_func *initial_pc; - }; + /* Jump into the OS */ + typedef void void_func(void); + struct rom_header + { + void *initial_sp; + void_func *initial_pc; + }; - xprintf("BaS initialization finished, enable interrupts\r\n"); - enable_coldfire_interrupts(); - init_isr(); + xprintf("BaS initialization finished, enable interrupts\r\n"); + enable_coldfire_interrupts(); + init_isr(); - xprintf("call EmuTOS\r\n"); - struct rom_header *os_header = (struct rom_header *) TOS; - os_header->initial_pc(); + xprintf("call EmuTOS\r\n"); + struct rom_header *os_header = (struct rom_header *) TOS; + os_header->initial_pc(); } diff --git a/sys/exceptions.S b/sys/exceptions.S index c980e6c..9c5e88b 100644 --- a/sys/exceptions.S +++ b/sys/exceptions.S @@ -310,12 +310,12 @@ init_vec_loop: */ vector_table_start: std_exc_vec: - //move.w #0x2700,sr // disable interrupt + move.w #0x2700,sr // disable interrupt subq.l #8,sp movem.l d0/a5,(sp) // save registers move.w 8(sp),d0 // fetch vector and.l #0x3fc,d0 // mask out vector number - +#define DBG_EXC #ifdef DBG_EXC // printout vector number of exception @@ -388,12 +388,6 @@ access_mmu: move.l MCF_MMU_MMUSR,d0 // did the last fault hit in TLB? btst #1,d0 // yes, it did. So we already mapped that page bne bus_error // and this must be a real bus error - btst #5,d0 // supervisor protection fault? - bne bus_error - btst #4,d0 // read access fault? - bne bus_error - btst #3,d0 // write access fault? - bne bus_error move.l MCF_MMU_MMUAR,d0 cmp.l #__FASTRAM_END,d0 // above max User RAM area? @@ -690,11 +684,13 @@ handler_gpt0: link a6,#-4 * 4 // make room for movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them, // other registers will be handled by gcc itself - move.w 4(a6),d0 // fetch vector number from stack move.l d0,-(sp) // push it jsr _gpt0_interrupt_handler // call C handler addq.l #4,sp // adjust stack + + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 rte #endif /* MACHINE_FIREBEE */ diff --git a/sys/interrupts.c b/sys/interrupts.c index 3d109fa..25ed996 100644 --- a/sys/interrupts.c +++ b/sys/interrupts.c @@ -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,25 +215,25 @@ 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; @@ -241,93 +241,93 @@ 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("video address timeout\r\n"); - 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; + /* + * 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(); + /* + * 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 */ - } + 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; - } + /* 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_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++; - } + 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; + addr += 0x100000; + } while (addr < 0xd00000); + video_tlb = 0x2000; + video_sbt = 0; } @@ -336,16 +336,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 +363,47 @@ 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 (video_sbt != 0 && (video_sbt - 0x70000000) > MCF_SLT0_SCNT) + { + video_addr_timeout(); + handled = true; + } - /* - * check if ACSI DMA interrupt - */ + /* + * 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_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(); - } + if (FALCON_MFP_IPRA || FALCON_MFP_IPRB) + { + blink_led(); + } - return handled; + return handled; } #if defined(MACHINE_FIREBEE) @@ -430,112 +430,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 */ diff --git a/sys/mmu.c b/sys/mmu.c index 0317752..c2b3582 100644 --- a/sys/mmu.c +++ b/sys/mmu.c @@ -62,7 +62,7 @@ #error "unknown machine!" #endif /* MACHINE_FIREBEE */ -#define DEBUG_MMU +//#define DEBUG_MMU #ifdef DEBUG_MMU #define dbg(format, arg...) do { xprintf("DEBUG (%s()): " format, __FUNCTION__, ##arg);} while(0) #else @@ -199,14 +199,14 @@ struct virt_to_phys { uint32_t start_address; uint32_t length; - uint32_t physical_offset; + uint32_t physical_offset; }; static struct virt_to_phys translation[] = { - /* virtual , length , offset */ - { 0x00000000, 0x00e00000, 0x60000000 }, /* map first 14 MByte to first 14 Mb of video ram */ - { 0x00e00000, 0x00100000, 0x00000000 }, /* map TOS to SDRAM */ + /* virtual , length , offset */ + { 0x00000000, 0x00e00000, 0x60000000 }, /* map first 14 MByte to first 14 Mb of video ram */ + //{ 0x00e00000, 0x00100000, 0x00000000 }, /* map TOS to SDRAM */ { 0x00f00000, 0x00100000, 0xff000000 }, /* map Falcon I/O area to FPGA */ { 0x01000000, 0x10000000, 0x00000000 }, /* map rest of ram virt = phys */ { 0x1fd00000, 0x01000000, 0x00000000 }, /* accessed by EmuTOS? */ @@ -219,12 +219,12 @@ static inline uint32_t lookup_phys(uint32_t virt) for (i = 0; i < num_translations; i++) { - if (virt >= translation[i].start_address && virt < translation[i].start_address + translation[i].length) + if (virt >= translation[i].start_address && virt < translation[i].start_address + translation[i].length) { - return virt + translation[i].physical_offset; + return virt + translation[i].physical_offset; } } - err("virtual address 0x%lx not found in translation table!\r\n", virt); + err("virtual address 0x%lx not found in translation table!\r\n", virt); } struct page_descriptor @@ -254,11 +254,11 @@ static struct page_descriptor pages[65536]; /* 512 Mb RAM */ */ int mmu_map_8k_page(uint32_t virt) { - const int size_mask = 0xffffe000; /* 8k pagesize */ - int page_index = (virt & size_mask) / 4096; /* index into page_descriptor array */ - struct page_descriptor *page = &pages[page_index]; /* attributes of page to map */ + const int size_mask = 0xffffe000; /* 8k pagesize */ + int page_index = (virt & size_mask) / DEFAULT_PAGE_SIZE; /* index into page_descriptor array */ + struct page_descriptor *page = &pages[page_index]; /* attributes of page to map */ - uint32_t addr = lookup_phys(virt); /* virtual to physical translation of page */ + uint32_t phys = lookup_phys(virt); /* virtual to physical translation of page */ /* * add page to TLB @@ -269,7 +269,7 @@ int mmu_map_8k_page(uint32_t virt) MCF_MMU_MMUTR_V; /* valid */ NOP(); - MCF_MMU_MMUDR = (addr & size_mask) | /* physical address */ + MCF_MMU_MMUDR = (phys & size_mask) | /* physical address */ MCF_MMU_MMUDR_SZ(MMU_PAGE_SIZE_8K) | /* page size */ MCF_MMU_MMUDR_CM(page->cache_mode) | (page->read ? MCF_MMU_MMUDR_R : 0) | /* read access enable */ @@ -282,24 +282,19 @@ int mmu_map_8k_page(uint32_t virt) MCF_MMU_MMUOR_UAA; /* update allocation address field */ NOP(); + dbg("mapped virt=0x%08x to phys=0x%08x\r\n", virt & size_mask, phys & size_mask); + + dbg("DTLB: MCF_MMU_MMUOR = %08x\r\n", MCF_MMU_MMUOR); + 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=0x%08x to phys=0x%08x\r\n", virt, addr); + dbg("ITLB: MCF_MMU_MMUOR = %08x\r\n\r\n", MCF_MMU_MMUOR); + return 1; } -struct mmu_map_flags -{ - unsigned cache_mode:2; - unsigned protection:1; - unsigned page_id:8; - unsigned access:3; - unsigned locked:1; - unsigned unused:17; -}; - /* * map a page of memory using virt and phys as addresses with the Coldfire MMU. * @@ -312,7 +307,7 @@ struct mmu_map_flags * * */ -int mmu_map_page(uint32_t virt, uint32_t phys, enum mmu_page_size sz, const struct mmu_map_flags *flags) +int mmu_map_page(uint32_t virt, uint32_t phys, enum mmu_page_size sz, uint8_t page_id, const struct page_descriptor *flags) { int size_mask; @@ -335,24 +330,24 @@ int mmu_map_page(uint32_t virt, uint32_t phys, enum mmu_page_size sz, const stru break; default: - err("illegal map size %d\r\n", sz); + err("illegal map size %d\r\n", sz); } /* * add page to TLB */ - MCF_MMU_MMUTR = ((int) virt & size_mask) | /* virtual address */ - MCF_MMU_MMUTR_ID(flags->page_id) | /* address space id (ASID) */ - MCF_MMU_MMUTR_SG | /* shared global */ + MCF_MMU_MMUTR = ((uint32_t) virt & size_mask) | /* virtual address */ + MCF_MMU_MMUTR_ID(page_id) | /* address space id (ASID) */ + (flags->global ? MCF_MMU_MMUTR_SG : 0) | /* shared global */ MCF_MMU_MMUTR_V; /* valid */ NOP(); - MCF_MMU_MMUDR = ((int) phys & size_mask) | /* physical address */ + MCF_MMU_MMUDR = ((uint32_t) phys & size_mask) | /* physical address */ MCF_MMU_MMUDR_SZ(sz) | /* 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 */ + (flags->read ? MCF_MMU_MMUDR_R : 0) | /* read access enable */ + (flags->write ? MCF_MMU_MMUDR_W : 0) | /* write access enable */ + (flags->execute ? MCF_MMU_MMUDR_X : 0) | /* execute access enable */ (flags->locked ? MCF_MMU_MMUDR_LK : 0); NOP(); @@ -372,38 +367,52 @@ void mmu_init(void) { extern uint8_t _MMUBAR[]; uint32_t MMUBAR = (uint32_t) &_MMUBAR[0]; - struct mmu_map_flags flags; + struct page_descriptor flags; int i; /* - * prelaminary initialization of page descriptor 0 (root) table + * clear all MMU TLB entries first + */ + MCF_MMU_MMUOR = MCF_MMU_MMUOR_CA; + NOP(); + + /* + * prelaminary initialization of page descriptor 0 (root) table */ for (i = 0; i < sizeof(pages); i++) { - uint32_t addr = i * DEFAULT_PAGE_SIZE; + uint32_t addr = i * DEFAULT_PAGE_SIZE; - if (addr >= 0x00f00000 && addr < 0x00ffffff) + if (addr >= 0x00f00000 && addr < 0x00ffffff) { pages[i].cache_mode = CACHE_NOCACHE_PRECISE; + pages[i].execute = 0; + pages[i].supervisor_protect = 1; + } + else if (addr >= 0x0 && addr < 0x00f00000) /* ST-RAM, potential video memory */ + { + pages[i].cache_mode = CACHE_WRITETHROUGH; + pages[i].execute = 1; + pages[i].supervisor_protect = 0; } else { pages[i].cache_mode = CACHE_COPYBACK; + pages[i].execute = 1; + pages[i].supervisor_protect = 0; } - pages[i].global = 1; /* all pages global by default */ - pages[i].locked = 0; /* not locked */ - pages[i].read = 1; /* readable, writable, executable */ + pages[i].global = 1; /* all pages global by default */ + pages[i].locked = 0; /* not locked */ + pages[i].read = 1; /* readable, writable, executable */ pages[i].write = 1; - pages[i].execute = 1; - pages[i].supervisor_protect = 0; /* not supervisor protected */ } - set_asid(0); /* do not use address extension (ASID provides virtual 48 bit addresses) yet */ + set_asid(0); /* do not use address extension (ASID provides virtual 48 bit addresses) yet */ /* set data access attributes in ACR0 and ACR1 */ set_acr0(ACR_W(0) | /* read and write accesses permitted */ ACR_SP(0) | /* supervisor and user mode access permitted */ - ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* cache inhibit, precise (i/o area!) */ + ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* cache inhibit, precise (i/o area!) */ ACR_AMM(0) | /* control region > 16 MB */ ACR_S(ACR_S_ALL) | /* match addresses in user and supervisor mode */ ACR_E(1) | /* enable ACR */ @@ -425,7 +434,7 @@ void mmu_init(void) ACR_SP(0) | ACR_CM(0) | #if defined(MACHINE_FIREBEE) - ACR_CM(ACR_CM_CACHEABLE_WT) | /* ST RAM on the Firebee */ + ACR_CM(ACR_CM_CACHEABLE_WT) | /* ST RAM on the Firebee */ #elif defined(MACHINE_M5484LITE) ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* Compact Flash on the M548xLITE */ #elif defined(MACHINE_M54455) @@ -441,7 +450,7 @@ void mmu_init(void) /* set instruction access attributes in ACR2 and ACR3 */ - //set_acr2(0xe007c400); /* flash area */ + //set_acr2(0xe007c400); /* flash area */ set_acr2(ACR_W(0) | ACR_SP(0) | ACR_CM(0) | @@ -467,18 +476,33 @@ void mmu_init(void) * virtual address. This is also used (completely) when BaS is in RAM */ flags.cache_mode = CACHE_COPYBACK; - flags.access = ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE; - flags.protection = SV_PROTECT; /* supervisor access only */ - mmu_map_page(SDRAM_START + SDRAM_SIZE - 0X00200000, SDRAM_START + SDRAM_SIZE - 0X00200000, MMU_PAGE_SIZE_1M, &flags); + flags.read = 1; + flags.write = 1; + flags.execute = 1; + flags.supervisor_protect = 1; /* supervisor access only */ + flags.locked = 1; + mmu_map_page(SDRAM_START + SDRAM_SIZE - 0x00200000, SDRAM_START + SDRAM_SIZE - 0x00200000, 0, MMU_PAGE_SIZE_1M, &flags); + + /* + * map EmuTOS (locked for now) + */ + flags.read = 1; + flags.write = 1; + flags.execute = 1; + flags.locked = 1; + mmu_map_page(0xe00000, 0xe00000, MMU_PAGE_SIZE_1M, 0, &flags); /* * Map (locked) the very last MB of physical SDRAM (this is where the driver buffers reside) to the same * virtual address. Used uncached for drivers. */ flags.cache_mode = CACHE_NOCACHE_PRECISE; - flags.access = ACCESS_READ | ACCESS_WRITE; - flags.protection = SV_PROTECT; - mmu_map_page(SDRAM_START + SDRAM_SIZE - 0x00100000, SDRAM_START + SDRAM_SIZE - 0x00100000, MMU_PAGE_SIZE_1M, &flags); + flags.read = 1; + flags.write = 1; + flags.execute = 0; + flags.supervisor_protect = 1; + flags.locked = 1; + mmu_map_page(SDRAM_START + SDRAM_SIZE - 0x00100000, SDRAM_START + SDRAM_SIZE - 0x00100000, 0, MMU_PAGE_SIZE_1M, &flags); } @@ -489,12 +513,16 @@ void mmutr_miss(uint32_t address, uint32_t pc, uint32_t format_status) #ifdef _NOT_USED_ // experimental; try to ensure that supervisor stack area stays in mmu TLBs - // guess what: doesn't work... + // guess what: doesn't work... register uint32_t sp asm("sp"); + dbg("stack is at %p\r\n", sp); if (sp < 0x02000000) + { + dbg("mapped stack at 0x%08x\r\n"); mmu_map_8k_page(sp); - flush_and_invalidate_caches(); -#endif /* _NOT_USED_ */ + //flush_and_invalidate_caches(); + } +#endif /* _NOT_USED */ switch (address) { @@ -513,9 +541,6 @@ void mmutr_miss(uint32_t address, uint32_t pc, uint32_t format_status) default: /* add missed page to TLB */ mmu_map_8k_page(address); - - dbg("DTLB: MCF_MMU_MMUOR = %08x\r\n", MCF_MMU_MMUOR); - dbg("ITLB: MCF_MMU_MMUOR = %08x\r\n\r\n", MCF_MMU_MMUOR); } } diff --git a/sys/startcf.S b/sys/startcf.S index c2eb53f..547d237 100644 --- a/sys/startcf.S +++ b/sys/startcf.S @@ -49,6 +49,8 @@ _rom_entry: /* set stack pointer to end of SRAM */ lea __SUP_SP,a7 move.l #0,(sp) + subq.l #4,sp + move.l #0,(sp) /* * Initialize the processor caches.