Skip to content
This repository
Browse code

Add a test for DTLB exception handling in Milkymist BIOS

  • Loading branch information...
commit 23f37859ab13481b729d2ec291e44503af0e3b56 1 parent 43f6245
Yann Sionneau authored May 30, 2012
2  software/bios/Makefile
... ...
@@ -1,7 +1,7 @@
1 1
 MMDIR=../..
2 2
 include $(MMDIR)/software/include.mak
3 3
 
4  
-OBJECTS=crt0.o isr.o main.o unlzma.o boot.o boot-helper.o splash.o dtlb_load_test.o
  4
+OBJECTS=crt0.o isr.o main.o unlzma.o boot.o boot-helper.o splash.o dtlb_load_test.o dtlb_exception_handling_tests.o dtlb_miss_handler.o
5 5
 SEGMENTS=-j .text -j .data -j .rodata
6 6
 LIBS=$(MMDIR)/software/libhpdmc/libhpdmc.a $(MMDIR)/software/libbase/libbase-light.a \
7 7
      $(MMDIR)/software/libhal/libhal.a     $(MMDIR)/software/libnet/libnet.a
20  software/bios/crt0.S
@@ -97,6 +97,26 @@ _interrupt_handler:
97 97
 	nop
98 98
 	nop
99 99
 
  100
+_scall_handler:
  101
+	bi _scall_handler
  102
+	nop
  103
+	nop
  104
+	nop
  105
+	nop
  106
+	nop
  107
+	nop
  108
+	nop
  109
+
  110
+_dtlb_miss_exception_handler:
  111
+	sw	(sp+0), ra
  112
+	addi	ea, ea, -4
  113
+	calli	.save_all
  114
+	calli	dtlb_miss_handler
  115
+	bi	.restore_all_and_eret
  116
+	nop
  117
+	nop
  118
+	nop
  119
+
100 120
 macaddress:
101 121
 	.byte 0x10
102 122
 	.byte 0xe2
160  software/bios/dtlb_exception_handling_tests.c
... ...
@@ -0,0 +1,160 @@
  1
+#include <hal/mmu.h>
  2
+
  3
+#define PAGE_SIZE	(4096)
  4
+
  5
+#define MAX_MMU_SLOTS	10
  6
+#define NO_EMPTY_SLOT	(MAX_MMU_SLOTS + 1)
  7
+
  8
+#define A_BAD_ADDR	(0)
  9
+
  10
+#define NULL (0)
  11
+
  12
+#define get_pfn(x)	(x & ~(PAGE_SIZE - 1))
  13
+
  14
+struct mmu_mapping {
  15
+
  16
+	unsigned int vaddr;
  17
+	unsigned int paddr;
  18
+	char valid;
  19
+
  20
+} mappings[10];
  21
+
  22
+/*
  23
+ * This records in a global structure all MMU mappings
  24
+ * If such a mapping already exists the function returns immediately.
  25
+ * If such a mapping does not exist yet, vaddr is mapped to paddr and 
  26
+ * the mapping is recorded in the mappings[] global structure array in
  27
+ * an empty slot.
  28
+ * If there is no empty slot anymore then we fail
  29
+ */
  30
+
  31
+unsigned int mmu_map(unsigned int vaddr, unsigned int paddr) {
  32
+	int i;
  33
+	int empty_slot = NO_EMPTY_SLOT;
  34
+	vaddr = get_pfn(vaddr);
  35
+
  36
+	for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
  37
+	{
  38
+		if (!mappings[i].valid)
  39
+			empty_slot = i;
  40
+		if (vaddr == mappings[i].vaddr && paddr == mappings[i].paddr)
  41
+			return 1;
  42
+	}
  43
+	
  44
+	if (empty_slot == NO_EMPTY_SLOT)
  45
+		return empty_slot;
  46
+
  47
+	mappings[empty_slot].vaddr = vaddr;
  48
+	mappings[empty_slot].paddr = paddr;
  49
+	mappings[empty_slot].valid = 1;
  50
+	mmu_dtlb_map(vaddr, paddr);
  51
+
  52
+	return 1;
  53
+}
  54
+
  55
+unsigned int get_mmu_mapping_for(unsigned int vaddr) {
  56
+	int i;
  57
+	vaddr = get_pfn(vaddr);
  58
+
  59
+	for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
  60
+		if (mappings[i].valid && vaddr == mappings[i].vaddr)
  61
+			return mappings[i].paddr;
  62
+
  63
+	return A_BAD_ADDR;
  64
+}
  65
+
  66
+unsigned int invalidate_mmu_mapping(unsigned int vaddr) {
  67
+	int i;
  68
+	vaddr = get_pfn(vaddr);
  69
+	for (i = 0 ; i < MAX_MMU_SLOTS ; ++i)
  70
+	{
  71
+		if (mappings[i].valid && vaddr == mappings[i].vaddr) {
  72
+			mmu_dtlb_invalidate(vaddr);
  73
+			mappings[i].valid = 0;
  74
+			return 1;
  75
+		}
  76
+	}
  77
+	return 0;
  78
+}
  79
+
  80
+static void panic(void) {
  81
+	puts("PANIC !");
  82
+	while(1)
  83
+		asm volatile("nop");
  84
+}
  85
+
  86
+static void check_for_error(int ret) {
  87
+	if (ret)
  88
+		return;
  89
+
  90
+	if (ret == NO_EMPTY_SLOT) {
  91
+		puts("No empty slot in MMU mappings structure anymore");
  92
+		panic();
  93
+	}
  94
+
  95
+	if ( !ret ) {
  96
+		puts("Unknown issue");
  97
+		panic();
  98
+	}
  99
+}
  100
+
  101
+void dtlb_exception_handling_tests() {
  102
+
  103
+	register unsigned int stack, addr, data;
  104
+	int ret;
  105
+
  106
+	asm volatile("mv %0, sp" : "=r"(stack) :: );
  107
+
  108
+	ret = mmu_map(stack, stack);
  109
+	check_for_error(ret);
  110
+
  111
+	ret = mmu_map(stack-0x1000, stack-0x1000);
  112
+	check_for_error(ret);
  113
+
  114
+	printf("stack == 0x%08X\n", stack);
  115
+
  116
+	addr = 0x44002342; // Random address
  117
+	*(unsigned int *)addr = 42;
  118
+//	mmu_map(addr, addr);
  119
+
  120
+	printf("Address 0x%08X mapped to itself, value : ", addr);
  121
+
  122
+	asm volatile(
  123
+		"xor r11, r11, r11\n\t"
  124
+		"ori r11, r11, 0x11\n\t"
  125
+		"wcsr tlbctrl, r11\n\t" // this activates the mmu
  126
+		"xor r0, r0, r0\n\t"
  127
+		"xor r11, r11, r11\n\t"
  128
+		"or r11, r11, %1\n\t"
  129
+		"lw  %0, (r11+0)\n\t"
  130
+		"xor r11, r11, r11\n\t"
  131
+		"ori r11, r11, 0x9\n\t"
  132
+		"wcsr tlbctrl, r11\n\t" // this disactivates the mmu
  133
+		"xor r0, r0, r0" : "=&r"(data) : "r"(addr) : "r11"
  134
+	);
  135
+
  136
+	printf("%d\n", data);
  137
+
  138
+	invalidate_mmu_mapping(addr);
  139
+
  140
+	printf("DTLB has just been invalidated, next access to 0x%08X should trigger a DTLB exception\n", addr);
  141
+
  142
+	printf("Address 0x%08X not mapped, value : ", addr);
  143
+
  144
+	asm volatile(
  145
+		"xor r11, r11, r11\n\t"
  146
+		"ori r11, r11, 0x11\n\t"
  147
+		"wcsr tlbctrl, r11\n\t" // this activates the mmu
  148
+		"xor r0, r0, r0\n\t"
  149
+		"xor r11, r11, r11\n\t"
  150
+		"or r11, r11, %1\n\t"
  151
+		"lw  %0, (r11+0)\n\t"
  152
+		"xor r11, r11, r11\n\t"
  153
+		"ori r11, r11, 0x9\n\t"
  154
+		"wcsr tlbctrl, r11\n\t" // this disactivates the mmu
  155
+		"xor r0, r0, r0" : "=&r"(data) : "r"(addr) : "r11"
  156
+	);
  157
+
  158
+	printf("%d\n", data);
  159
+
  160
+}
8  software/bios/dtlb_miss_handler.c
... ...
@@ -0,0 +1,8 @@
  1
+#include <hal/mmu.h>
  2
+
  3
+void dtlb_miss_handler(void) {
  4
+
  5
+	disable_dtlb();
  6
+	printf("TOTO");
  7
+
  8
+}
4  software/bios/main.c
@@ -422,7 +422,8 @@ static void help()
422 422
 	puts("version    - display version");
423 423
 	puts("reboot     - system reset");
424 424
 	puts("reconf     - reload FPGA configuration");
425  
-	puts("dtlbtest   - runs DTLB MMU test");
  425
+	puts("dtlbtest   - runs DTLB MMU load store tests");
  426
+	puts("detest     - runs DTLB MMU exception handling tests");
426 427
 }
427 428
 
428 429
 static char *get_token(char **str)
@@ -538,6 +539,7 @@ static void do_command(char *c)
538 539
 	else if(strcmp(token, "rcsr") == 0) rcsr(get_token(&c));
539 540
 	else if(strcmp(token, "wcsr") == 0) wcsr(get_token(&c), get_token(&c));
540 541
 	else if(strcmp(token, "dtlbtest") == 0) dtlbtest();
  542
+	else if(strcmp(token, "detest") == 0) dtlb_exception_handling_tests();
541 543
 
542 544
 	else if(strcmp(token, "") != 0)
543 545
 		printf("Command not found\n");
10  software/libhal/mmu.c
@@ -32,3 +32,13 @@ inline void mmu_dtlb_map(unsigned int vpfn, unsigned int pfn)
32 32
 			 "wcsr tlbctrl, r11":::"r11");
33 33
 
34 34
 }
  35
+
  36
+inline void mmu_dtlb_invalidate(unsigned int vaddr)
  37
+{
  38
+	asm volatile ("ori %0, %0, 1\n\t"
  39
+		      "wcsr tlbvaddr, %0"::"r"(vaddr):);
  40
+
  41
+	asm volatile ("xor r11, r11, r11\n\t"
  42
+		      "ori r11, r11, 0x21\n\t"
  43
+		      "wcsr tlbctrl, r11":::"r11");
  44
+}

0 notes on commit 23f3785

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