Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add BIOS support for ITLB page fault handling

  • Loading branch information...
commit 4225524cf018b905f50db00ac01f00d20544f135 1 parent 3d8f348
@fallen authored
View
16 software/include/hal/mmu.h
@@ -62,6 +62,22 @@ struct mmu_mapping {
"xor r0, r0, r0":::"r11"); \
} while(0);
+#define enable_itlb() do { \
+ asm volatile ("xor r11, r11, r11\n\t" \
+ "ori r11, r11, 0x10\n\t" \
+ "wcsr tlbctrl, r11\n\t" \
+ "xor r0, r0, r0":::"r11"); \
+} while(0);
+
+#define disable_itlb() do { \
+ asm volatile ("xor r11, r11, r11\n\t" \
+ "ori r11, r11, 0x8\n\t" \
+ "wcsr tlbctrl, r11\n\t" \
+ "xor r0, r0, r0\n\t" \
+ "xor r0, r0, r0\n\t" \
+ "xor r0, r0, r0":::"r11"); \
+} while(0);
+
void mmu_dtlb_map(unsigned int vpfn, unsigned int pfn);
#endif
View
2  software/mmu-bios/Makefile
@@ -1,7 +1,7 @@
MMDIR=../..
include $(MMDIR)/software/include.mak
-OBJECTS=crt0.o main.o dtlb_load_test.o mmu.o isr.o vsnprintf-nofloat.o dtlb_miss_handler.o dtlb_exception_handling_tests.o
+OBJECTS=crt0.o main.o dtlb_load_test.o mmu.o isr.o vsnprintf-nofloat.o tlb_miss_handler.o dtlb_exception_handling_tests.o
SEGMENTS=-j .text -j .data -j .rodata
all: bios.bin
View
9 software/mmu-bios/crt0.S
@@ -119,6 +119,15 @@ _dtlb_miss_exception_handler:
nop
nop
+_itlb_miss_exception_handler:
+ sw (sp+0), ra
+ calli .save_all
+ calli itlb_miss_handler
+ bi .restore_all_and_eret
+ nop
+ nop
+ nop
+
macaddress:
.byte 0x10
.byte 0xe2
View
26 software/mmu-bios/dtlb_miss_handler.c
@@ -1,26 +0,0 @@
-#include <hal/mmu.h>
-#include <base/mmu.h>
-
-void dtlb_miss_handler(void)
-{
- unsigned int vaddr, paddr;
-
- // retrieve virtual address which caused the page fault
- asm volatile("rcsr %0, dtlbma" : "=r"(vaddr) :: );
-
- /*
- * check if there is an existing mapping for that virtual address
- * if yes: refill the DTLB with it
- * if not: we panic() !
- */
- paddr = get_mmu_mapping_for(vaddr);
- if (paddr == A_BAD_ADDR)
- {
- puts("Unrecoverable page fault !");
- panic();
- }
-
- printf("Refilling DTLB with mapping 0x%08X->0x%08X\n", vaddr, paddr);
- mmu_dtlb_map(vaddr, paddr);
-
-}
View
14 software/mmu-bios/main.c
@@ -1,6 +1,8 @@
#include "main.h"
#include <base/mmu.h>
+extern void call_function_with_itlb_enabled(void (*f)(void));
+
void uart_write(char c)
{
unsigned int oldmask;
@@ -74,7 +76,7 @@ int printf(const char *fmt, ...)
void f(void) {
CSR_UART_RXTX = '@';
- asm volatile("bi f" ::: ); // We intinitely loop to f()
+// asm volatile("bi f" ::: ); // We intinitely loop to f()
asm volatile("xor r0, r0, r0\n\t"
"xor r0, r0, r0" ::: );
}
@@ -92,9 +94,15 @@ void itlbtest(void) {
f_addr = 0x44004000;
printf("Mapping f() into virtual memory at 0x%08X [physical == 0x%08X]\n", f_addr, f_addr+0x1000);
+ mmu_map(0x44003000, 0x44003000, DTLB_MAPPING | MAPPING_CAN_READ | MAPPING_CAN_WRITE);
+ mmu_map(stack, stack, DTLB_MAPPING | MAPPING_CAN_READ | MAPPING_CAN_WRITE);
mmu_map(f_addr, f_addr + 0x1000, ITLB_MAPPING | MAPPING_CAN_READ);
+ mmu_map(itlbtest, itlbtest, ITLB_MAPPING | MAPPING_CAN_READ);
+ mmu_map(call_function_with_itlb_enabled, call_function_with_itlb_enabled, ITLB_MAPPING | MAPPING_CAN_READ);
puts("Mapping DONE");
+ mmu_itlb_invalidate(f_addr);
+
// We copy f's code to 0x44005000
for (p = f, pdest = 0x44005000 ; p < f + 0x1000 ; p++, pdest++)
*pdest = *p;
@@ -105,7 +113,11 @@ void itlbtest(void) {
puts("Instruction and Data caches have been invalidated");
call_function_with_itlb_enabled(f_addr);
+ disable_dtlb();
+ disable_itlb();
puts("Call DONE");
+ while(1)
+ asm volatile("xor r0, r0, r0");
}
int main(int argc, char **argv)
View
37 software/mmu-bios/mmu.c
@@ -47,6 +47,16 @@ inline void mmu_dtlb_invalidate(unsigned int vaddr)
"wcsr tlbctrl, r11":::"r11");
}
+inline void mmu_itlb_invalidate(unsigned int vaddr)
+{
+ asm volatile ("ori %0, %0, 0\n\t"
+ "wcsr tlbvaddr, %0"::"r"(vaddr):);
+
+ asm volatile ("xor r11, r11, r11\n\t"
+ "ori r11, r11, 0x20\n\t"
+ "wcsr tlbctrl, r11":::"r11");
+}
+
struct mmu_mapping mappings[MAX_MMU_SLOTS];
@@ -102,7 +112,7 @@ unsigned int mmu_map(unsigned int vaddr, unsigned int paddr, char metadata) {
}
unsigned int get_mmu_mapping_for(unsigned int vaddr) {
- int i;
+ unsigned int i;
vaddr = get_pfn(vaddr);
for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
@@ -112,6 +122,28 @@ unsigned int get_mmu_mapping_for(unsigned int vaddr) {
return A_BAD_ADDR;
}
+unsigned char is_dtlb_mapping(unsigned int vaddr) {
+ unsigned int i;
+ vaddr = get_pfn(vaddr);
+
+ for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
+ if ((mappings[i].vaddr == vaddr) && (mappings[i].metadata & (MAPPING_IS_VALID)) && (mappings[i].metadata & (DTLB_MAPPING)))
+ return 1;
+
+ return 0;
+}
+
+unsigned char is_itlb_mapping(unsigned int vaddr) {
+ unsigned int i;
+ vaddr = get_pfn(vaddr);
+
+ for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
+ if ((mappings[i].vaddr == vaddr) && (mappings[i].metadata & (MAPPING_IS_VALID)) && (mappings[i].metadata & (ITLB_MAPPING)))
+ return 1;
+
+ return 0;
+}
+
unsigned char remove_mmu_mapping_for(unsigned int vaddr) {
int i;
vaddr = get_pfn(vaddr);
@@ -195,6 +227,9 @@ unsigned int write_word_with_mmu_enabled(register unsigned int vaddr, register u
void call_function_with_itlb_enabled(void (*f)(void))
{
+ register unsigned int stack;
+ asm volatile("mv %0, sp" : "=r"(stack) :: );
+ printf("call stack == 0x%08x\n", stack);
asm volatile(
"xor r11, r11, r11\n\t"
"ori r11, r11, 0x10\n\t"
View
50 software/mmu-bios/tlb_miss_handler.c
@@ -0,0 +1,50 @@
+#include <hal/mmu.h>
+#include <base/mmu.h>
+
+void dtlb_miss_handler(void)
+{
+ unsigned int vaddr, paddr;
+
+ // retrieve virtual address which caused the page fault
+ asm volatile("rcsr %0, dtlbma" : "=r"(vaddr) :: );
+
+ /*
+ * check if there is an existing mapping for that virtual address
+ * if yes: refill the DTLB with it
+ * if not: we panic() !
+ */
+ paddr = get_mmu_mapping_for(vaddr);
+ if (paddr == A_BAD_ADDR || !is_dtlb_mapping(vaddr))
+ {
+ puts("Unrecoverable DTLB page fault !");
+ panic();
+ }
+
+ printf("Refilling DTLB with mapping 0x%08X->0x%08X\n", vaddr, paddr);
+ mmu_dtlb_map(vaddr, paddr);
+}
+
+void itlb_miss_handler(void)
+{
+ unsigned int vaddr, paddr;
+
+ asm volatile("rcsr %0, itlbma" : "=r"(vaddr) :: );
+ printf("Address 0x%08X caused an ITLB page fault\n", vaddr);
+
+ paddr = get_mmu_mapping_for(vaddr);
+ if (paddr == A_BAD_ADDR)
+ {
+ puts("No such mapping !");
+ puts("Unrecoverable ITLB page fault !");
+ panic();
+ }
+
+ if (!is_itlb_mapping(vaddr))
+ {
+ puts("Mapping not in ITLB");
+ panic();
+ }
+
+ printf("Refilling ITLB with mapping 0x%08X->0x%08X\n", vaddr, paddr);
+ mmu_itlb_map(vaddr, paddr);
+}

0 comments on commit 4225524

Please sign in to comment.
Something went wrong with that request. Please try again.