Skip to content
This repository
  • 2 commits
  • 5 files changed
  • 0 comments
  • 1 contributor
2  software/include/base/mmu.h
@@ -3,7 +3,7 @@
3 3
 
4 4
 #include <hal/mmu.h>
5 5
 
6  
-unsigned int mmu_map(unsigned int vaddr, unsigned int paddr);
  6
+unsigned int mmu_map(unsigned int vaddr, unsigned int paddr, char metadata);
7 7
 unsigned int get_mmu_mapping_for(unsigned int vaddr);
8 8
 unsigned char remove_mmu_mapping_for(unsigned int vaddr);
9 9
 void panic(void);
17  software/include/hal/mmu.h
@@ -25,12 +25,25 @@
25 25
 #define NULL 		(0)
26 26
 #define get_pfn(x)	(x & ~(PAGE_SIZE - 1))
27 27
 
  28
+#define ITLB_MAPPING		(1)
  29
+#define DTLB_MAPPING		(1 << 1)
  30
+#define MAPPING_CAN_READ	(1 << 2)
  31
+#define MAPPING_CAN_WRITE	(1 << 3)
  32
+#define MAPPING_COPY_ON_WRITE	(1 << 4)
  33
+#define MAPPING_IS_VALID	(1 << 5)
  34
+
28 35
 struct mmu_mapping {
29 36
 
30 37
 	unsigned int vaddr;
31 38
 	unsigned int paddr;
32  
-	char valid;
33  
-
  39
+	char metadata;
  40
+	// x  x  x  x    x  x  x  x
  41
+	//       |  |    |  |  |  |-> ITLB mapping
  42
+	//       |  |    |  |  |-> DTLB mapping
  43
+	//       |  |    |  |->  CAN_READ
  44
+	//       |  |    |-> CAN_WRITE
  45
+	//       |  |-> COPY_ON_WRITE: Not Implemented Yet
  46
+	//       |-> MAPPING_IS_VALID
34 47
 };
35 48
 
36 49
 #define enable_dtlb() do { \
8  software/mmu-bios/dtlb_exception_handling_tests.c
@@ -9,10 +9,10 @@ void dtlb_exception_handling_tests() {
9 9
 
10 10
 	asm volatile("mv %0, sp" : "=r"(stack) :: );
11 11
 
12  
-	ret = mmu_map(stack, stack);
  12
+	ret = mmu_map(stack, stack, DTLB_MAPPING | MAPPING_CAN_READ | MAPPING_CAN_WRITE);
13 13
 	check_for_error(ret);
14 14
 
15  
-	ret = mmu_map(stack-0x1000, stack-0x1000);
  15
+	ret = mmu_map(stack-0x1000, stack-0x1000, DTLB_MAPPING | MAPPING_CAN_READ | MAPPING_CAN_WRITE);
16 16
 	check_for_error(ret);
17 17
 
18 18
 	printf("stack == 0x%08X\n", stack);
@@ -20,7 +20,7 @@ void dtlb_exception_handling_tests() {
20 20
 	addr = 0x44004004;
21 21
 
22 22
 	printf("\n=> Mapping 0x%08X to 0x%08X\n", addr, addr);
23  
-	ret = mmu_map(addr, addr);
  23
+	ret = mmu_map(addr, addr, DTLB_MAPPING | MAPPING_CAN_READ | MAPPING_CAN_WRITE);
24 24
 	check_for_error(ret);
25 25
 
26 26
 	data = 42;
@@ -43,7 +43,7 @@ void dtlb_exception_handling_tests() {
43 43
 	printf("\n<= Reading %d from virtual address 0x%08X\n\n", data, addr);
44 44
 
45 45
 	printf("=> Mapping 0x%08X to 0%08X\n", addr, addr+0x1000);
46  
-	ret = mmu_map(addr, addr+0x1000); // Map to something else
  46
+	ret = mmu_map(addr, addr+0x1000, DTLB_MAPPING | MAPPING_CAN_READ | MAPPING_CAN_WRITE); // Map to something else
47 47
 	check_for_error(ret);
48 48
 
49 49
 	printf("=> Invalidating the mapping of virtual address 0x%08X in the TLB\n", addr);
41  software/mmu-bios/main.c
... ...
@@ -1,5 +1,5 @@
1 1
 #include "main.h"
2  
-
  2
+#include <base/mmu.h>
3 3
 
4 4
 void uart_write(char c)
5 5
 {
@@ -72,11 +72,48 @@ int printf(const char *fmt, ...)
72 72
 	return len;
73 73
 }
74 74
 
  75
+void f(void) {
  76
+	CSR_UART_RXTX = '@';
  77
+	asm volatile("bi f" ::: ); // We intinitely loop to f()
  78
+	asm volatile("xor r0, r0, r0\n\t"
  79
+		     "xor r0, r0, r0" ::: );
  80
+}
  81
+
  82
+void itlbtest(void) {
  83
+	register unsigned int stack, f_addr;
  84
+	unsigned int *p;
  85
+	unsigned int *pdest;
  86
+
  87
+	asm volatile("mv %0, sp" : "=r"(stack) :: );
  88
+	printf("stack == 0x%08X\n", stack);
  89
+
  90
+	printf("f() is located at 0x%p\n", f);
  91
+
  92
+	f_addr = 0x44004000;
  93
+	printf("Mapping f() into virtual memory at 0x%08X [physical == 0x%08X]\n", f_addr, f_addr+0x1000);
  94
+
  95
+	mmu_map(f_addr, f_addr + 0x1000, ITLB_MAPPING | MAPPING_CAN_READ);
  96
+	puts("Mapping DONE");
  97
+
  98
+	// We copy f's code to 0x44005000
  99
+	for (p = f, pdest = 0x44005000 ; p < f + 0x1000 ; p++, pdest++)
  100
+		*pdest = *p;
  101
+	puts("Copy DONE");
  102
+
  103
+	asm volatile("wcsr DCC, r0");
  104
+	asm volatile("wcsr ICC, r0");
  105
+	puts("Instruction and Data caches have been invalidated");
  106
+
  107
+	call_function_with_itlb_enabled(f_addr);
  108
+	puts("Call DONE");
  109
+}
  110
+
75 111
 int main(int argc, char **argv)
76 112
 {
77 113
 	asm volatile("wcsr IE, r0");
78 114
 //	dtlb_load_test();
79  
-	dtlb_exception_handling_tests();
  115
+//	dtlb_exception_handling_tests();
  116
+	itlbtest();
80 117
 
81 118
 	while (1)
82 119
 	{
47  software/mmu-bios/mmu.c
@@ -59,7 +59,7 @@ struct mmu_mapping mappings[MAX_MMU_SLOTS];
59 59
  * If there is no empty slot anymore then we fail
60 60
  */
61 61
 
62  
-unsigned int mmu_map(unsigned int vaddr, unsigned int paddr) {
  62
+unsigned int mmu_map(unsigned int vaddr, unsigned int paddr, char metadata) {
63 63
 	int i;
64 64
 	register unsigned int stack;
65 65
 	int empty_slot = NO_EMPTY_SLOT;
@@ -71,9 +71,9 @@ unsigned int mmu_map(unsigned int vaddr, unsigned int paddr) {
71 71
 
72 72
 	for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
73 73
 	{
74  
-		if (!mappings[i].valid)
  74
+		if (!(mappings[i].metadata & MAPPING_IS_VALID))
75 75
 			empty_slot = i;
76  
-		if ((vaddr == mappings[i].vaddr) && (paddr == mappings[i].paddr) && mappings[i].valid)
  76
+		if ((vaddr == mappings[i].vaddr) && (paddr == mappings[i].paddr) && (mappings[i].metadata & MAPPING_IS_VALID))
77 77
 		{
78 78
 			puts("Already mapped !");
79 79
 			return 1;
@@ -88,8 +88,14 @@ unsigned int mmu_map(unsigned int vaddr, unsigned int paddr) {
88 88
 
89 89
 	mappings[empty_slot].vaddr = vaddr;
90 90
 	mappings[empty_slot].paddr = paddr;
91  
-	mappings[empty_slot].valid = 1;
92  
-	mmu_dtlb_map(vaddr, paddr);
  91
+	mappings[empty_slot].metadata = (metadata | MAPPING_IS_VALID);
  92
+
  93
+	if (metadata & ITLB_MAPPING)
  94
+		mmu_itlb_map(vaddr, paddr);
  95
+
  96
+	if (metadata & DTLB_MAPPING)
  97
+		mmu_dtlb_map(vaddr, paddr);
  98
+
93 99
 	printf("mapping 0x%08X->0x%08X in slot %d [0x%p]\n", vaddr, paddr, empty_slot, &mappings[empty_slot]);
94 100
 
95 101
 	return 1;
@@ -100,7 +106,7 @@ unsigned int get_mmu_mapping_for(unsigned int vaddr) {
100 106
 	vaddr = get_pfn(vaddr);
101 107
 
102 108
 	for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
103  
-		if (mappings[i].valid && (vaddr == mappings[i].vaddr))
  109
+		if ((mappings[i].metadata & MAPPING_IS_VALID) && (vaddr == mappings[i].vaddr))
104 110
 			return mappings[i].paddr;
105 111
 
106 112
 	return A_BAD_ADDR;
@@ -112,10 +118,10 @@ unsigned char remove_mmu_mapping_for(unsigned int vaddr) {
112 118
 
113 119
 	for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
114 120
 	{
115  
-		if (mappings[i].valid && (vaddr == mappings[i].vaddr))
  121
+		if ((mappings[i].metadata & MAPPING_IS_VALID) && (vaddr == mappings[i].vaddr))
116 122
 		{
117 123
 			mmu_dtlb_invalidate(vaddr);
118  
-			mappings[i].valid = 0;
  124
+			mappings[i].metadata &= ~MAPPING_IS_VALID;
119 125
 			return 1;
120 126
 		}
121 127
 	}
@@ -186,3 +192,28 @@ unsigned int write_word_with_mmu_enabled(register unsigned int vaddr, register u
186 192
 		"xor r0, r0, r0\n\t" :: "r"(vaddr), "r"(data) : "r11"
187 193
 	);
188 194
 }
  195
+
  196
+void call_function_with_itlb_enabled(void (*f)(void))
  197
+{
  198
+	asm volatile(
  199
+		"xor r11, r11, r11\n\t"
  200
+		"ori r11, r11, 0x10\n\t"
  201
+		"wcsr tlbctrl, r11\n\t" // Activates ITLB
  202
+		"call %0\n\t"
  203
+		"xor r11, r11, r11\n\t"
  204
+		"ori r11, r11, 0x8\n\t"
  205
+		"wcsr tlbctrl, r11" :: "r"(f) : "r11" // Disactivates ITLB
  206
+	);
  207
+}
  208
+
  209
+inline void mmu_itlb_map(unsigned int vpfn, unsigned int pfn)
  210
+{
  211
+
  212
+	asm volatile	("wcsr tlbvaddr, %0" :: "r"(vpfn) : );
  213
+
  214
+	asm volatile	("wcsr tlbpaddr, %0" :: "r"(pfn) : );
  215
+
  216
+	asm volatile	("xor r11, r11, r11\n\t"
  217
+			 "ori r11, r11, 0x4\n\t"
  218
+			 "wcsr tlbctrl, r11" ::: "r11");
  219
+}

No commit comments for this range

Something went wrong with that request. Please try again.