Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: fallen/milkymist-mmu
base: 033c430
...
head fork: fallen/milkymist-mmu
compare: 3d8f348
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 5 files changed
  • 0 commit comments
  • 1 contributor
View
2  software/include/base/mmu.h
@@ -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);
View
17 software/include/hal/mmu.h
@@ -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 { \
View
8 software/mmu-bios/dtlb_exception_handling_tests.c
@@ -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);
View
41 software/mmu-bios/main.c
@@ -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)
{
View
47 software/mmu-bios/mmu.c
@@ -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.