Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: fallen/milkymist-mmu
base: 033c430
...
head fork: fallen/milkymist-mmu
compare: 3d8f348
  • 2 commits
  • 5 files changed
  • 0 commit comments
  • 1 contributor
2  software/include/base/mmu.h
View
@@ -3,7 +3,7 @@
#include <hal/mmu.h>
-unsigned int mmu_map(unsigned int vaddr, unsigned int paddr);
+unsigned int mmu_map(unsigned int vaddr, unsigned int paddr, char metadata);
unsigned int get_mmu_mapping_for(unsigned int vaddr);
unsigned char remove_mmu_mapping_for(unsigned int vaddr);
void panic(void);
17 software/include/hal/mmu.h
View
@@ -25,12 +25,25 @@
#define NULL (0)
#define get_pfn(x) (x & ~(PAGE_SIZE - 1))
+#define ITLB_MAPPING (1)
+#define DTLB_MAPPING (1 << 1)
+#define MAPPING_CAN_READ (1 << 2)
+#define MAPPING_CAN_WRITE (1 << 3)
+#define MAPPING_COPY_ON_WRITE (1 << 4)
+#define MAPPING_IS_VALID (1 << 5)
+
struct mmu_mapping {
unsigned int vaddr;
unsigned int paddr;
- char valid;
-
+ char metadata;
+ // x x x x x x x x
+ // | | | | | |-> ITLB mapping
+ // | | | | |-> DTLB mapping
+ // | | | |-> CAN_READ
+ // | | |-> CAN_WRITE
+ // | |-> COPY_ON_WRITE: Not Implemented Yet
+ // |-> MAPPING_IS_VALID
};
#define enable_dtlb() do { \
8 software/mmu-bios/dtlb_exception_handling_tests.c
View
@@ -9,10 +9,10 @@ void dtlb_exception_handling_tests() {
asm volatile("mv %0, sp" : "=r"(stack) :: );
- ret = mmu_map(stack, stack);
+ ret = mmu_map(stack, stack, DTLB_MAPPING | MAPPING_CAN_READ | MAPPING_CAN_WRITE);
check_for_error(ret);
- ret = mmu_map(stack-0x1000, stack-0x1000);
+ ret = mmu_map(stack-0x1000, stack-0x1000, DTLB_MAPPING | MAPPING_CAN_READ | MAPPING_CAN_WRITE);
check_for_error(ret);
printf("stack == 0x%08X\n", stack);
@@ -20,7 +20,7 @@ void dtlb_exception_handling_tests() {
addr = 0x44004004;
printf("\n=> Mapping 0x%08X to 0x%08X\n", addr, addr);
- ret = mmu_map(addr, addr);
+ ret = mmu_map(addr, addr, DTLB_MAPPING | MAPPING_CAN_READ | MAPPING_CAN_WRITE);
check_for_error(ret);
data = 42;
@@ -43,7 +43,7 @@ void dtlb_exception_handling_tests() {
printf("\n<= Reading %d from virtual address 0x%08X\n\n", data, addr);
printf("=> Mapping 0x%08X to 0%08X\n", addr, addr+0x1000);
- ret = mmu_map(addr, addr+0x1000); // Map to something else
+ ret = mmu_map(addr, addr+0x1000, DTLB_MAPPING | MAPPING_CAN_READ | MAPPING_CAN_WRITE); // Map to something else
check_for_error(ret);
printf("=> Invalidating the mapping of virtual address 0x%08X in the TLB\n", addr);
41 software/mmu-bios/main.c
View
@@ -1,5 +1,5 @@
#include "main.h"
-
+#include <base/mmu.h>
void uart_write(char c)
{
@@ -72,11 +72,48 @@ int printf(const char *fmt, ...)
return len;
}
+void f(void) {
+ CSR_UART_RXTX = '@';
+ asm volatile("bi f" ::: ); // We intinitely loop to f()
+ asm volatile("xor r0, r0, r0\n\t"
+ "xor r0, r0, r0" ::: );
+}
+
+void itlbtest(void) {
+ register unsigned int stack, f_addr;
+ unsigned int *p;
+ unsigned int *pdest;
+
+ asm volatile("mv %0, sp" : "=r"(stack) :: );
+ printf("stack == 0x%08X\n", stack);
+
+ printf("f() is located at 0x%p\n", f);
+
+ f_addr = 0x44004000;
+ printf("Mapping f() into virtual memory at 0x%08X [physical == 0x%08X]\n", f_addr, f_addr+0x1000);
+
+ mmu_map(f_addr, f_addr + 0x1000, ITLB_MAPPING | MAPPING_CAN_READ);
+ puts("Mapping DONE");
+
+ // We copy f's code to 0x44005000
+ for (p = f, pdest = 0x44005000 ; p < f + 0x1000 ; p++, pdest++)
+ *pdest = *p;
+ puts("Copy DONE");
+
+ asm volatile("wcsr DCC, r0");
+ asm volatile("wcsr ICC, r0");
+ puts("Instruction and Data caches have been invalidated");
+
+ call_function_with_itlb_enabled(f_addr);
+ puts("Call DONE");
+}
+
int main(int argc, char **argv)
{
asm volatile("wcsr IE, r0");
// dtlb_load_test();
- dtlb_exception_handling_tests();
+// dtlb_exception_handling_tests();
+ itlbtest();
while (1)
{
47 software/mmu-bios/mmu.c
View
@@ -59,7 +59,7 @@ struct mmu_mapping mappings[MAX_MMU_SLOTS];
* If there is no empty slot anymore then we fail
*/
-unsigned int mmu_map(unsigned int vaddr, unsigned int paddr) {
+unsigned int mmu_map(unsigned int vaddr, unsigned int paddr, char metadata) {
int i;
register unsigned int stack;
int empty_slot = NO_EMPTY_SLOT;
@@ -71,9 +71,9 @@ unsigned int mmu_map(unsigned int vaddr, unsigned int paddr) {
for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
{
- if (!mappings[i].valid)
+ if (!(mappings[i].metadata & MAPPING_IS_VALID))
empty_slot = i;
- if ((vaddr == mappings[i].vaddr) && (paddr == mappings[i].paddr) && mappings[i].valid)
+ if ((vaddr == mappings[i].vaddr) && (paddr == mappings[i].paddr) && (mappings[i].metadata & MAPPING_IS_VALID))
{
puts("Already mapped !");
return 1;
@@ -88,8 +88,14 @@ unsigned int mmu_map(unsigned int vaddr, unsigned int paddr) {
mappings[empty_slot].vaddr = vaddr;
mappings[empty_slot].paddr = paddr;
- mappings[empty_slot].valid = 1;
- mmu_dtlb_map(vaddr, paddr);
+ mappings[empty_slot].metadata = (metadata | MAPPING_IS_VALID);
+
+ if (metadata & ITLB_MAPPING)
+ mmu_itlb_map(vaddr, paddr);
+
+ if (metadata & DTLB_MAPPING)
+ mmu_dtlb_map(vaddr, paddr);
+
printf("mapping 0x%08X->0x%08X in slot %d [0x%p]\n", vaddr, paddr, empty_slot, &mappings[empty_slot]);
return 1;
@@ -100,7 +106,7 @@ unsigned int get_mmu_mapping_for(unsigned int vaddr) {
vaddr = get_pfn(vaddr);
for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
- if (mappings[i].valid && (vaddr == mappings[i].vaddr))
+ if ((mappings[i].metadata & MAPPING_IS_VALID) && (vaddr == mappings[i].vaddr))
return mappings[i].paddr;
return A_BAD_ADDR;
@@ -112,10 +118,10 @@ unsigned char remove_mmu_mapping_for(unsigned int vaddr) {
for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
{
- if (mappings[i].valid && (vaddr == mappings[i].vaddr))
+ if ((mappings[i].metadata & MAPPING_IS_VALID) && (vaddr == mappings[i].vaddr))
{
mmu_dtlb_invalidate(vaddr);
- mappings[i].valid = 0;
+ mappings[i].metadata &= ~MAPPING_IS_VALID;
return 1;
}
}
@@ -186,3 +192,28 @@ unsigned int write_word_with_mmu_enabled(register unsigned int vaddr, register u
"xor r0, r0, r0\n\t" :: "r"(vaddr), "r"(data) : "r11"
);
}
+
+void call_function_with_itlb_enabled(void (*f)(void))
+{
+ asm volatile(
+ "xor r11, r11, r11\n\t"
+ "ori r11, r11, 0x10\n\t"
+ "wcsr tlbctrl, r11\n\t" // Activates ITLB
+ "call %0\n\t"
+ "xor r11, r11, r11\n\t"
+ "ori r11, r11, 0x8\n\t"
+ "wcsr tlbctrl, r11" :: "r"(f) : "r11" // Disactivates ITLB
+ );
+}
+
+inline void mmu_itlb_map(unsigned int vpfn, unsigned int pfn)
+{
+
+ asm volatile ("wcsr tlbvaddr, %0" :: "r"(vpfn) : );
+
+ asm volatile ("wcsr tlbpaddr, %0" :: "r"(pfn) : );
+
+ asm volatile ("xor r11, r11, r11\n\t"
+ "ori r11, r11, 0x4\n\t"
+ "wcsr tlbctrl, r11" ::: "r11");
+}

No commit comments for this range

Something went wrong with that request. Please try again.