Skip to content

Commit

Permalink
Add new BIOS commands to play with MMU
Browse files Browse the repository at this point in the history
  • Loading branch information
fallen committed Jun 6, 2012
1 parent 2bcd496 commit 2f35de4
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 15 deletions.
4 changes: 2 additions & 2 deletions software/bios/dtlb_exception_handling_tests.c
Expand Up @@ -51,7 +51,7 @@ void dtlb_exception_handling_tests() {
printf("\n<= Reading %d from virtual address 0x%08X\n\n", data, addr);

printf("=> Invalidating the mapping of virtual address 0x%08X in the TLB\n", addr);
mmu_dtlb_invalidate(addr);
mmu_dtlb_invalidate_line(addr);

data = 43;
printf("=> Writing %d to physical address 0x%08X\n", data, addr);
Expand All @@ -67,7 +67,7 @@ void dtlb_exception_handling_tests() {
check_for_error(ret);

printf("=> Invalidating the mapping of virtual address 0x%08X in the TLB\n", addr);
mmu_dtlb_invalidate(addr); // AND invalidate the mapping
mmu_dtlb_invalidate_line(addr); // AND invalidate the mapping

data = 44;
printf("=> Writting %d to physical address 0x%08X\n", data, addr+0x1000);
Expand Down
86 changes: 85 additions & 1 deletion software/bios/main.c
Expand Up @@ -422,6 +422,14 @@ static void help()
puts("version - display version");
puts("reboot - system reset");
puts("reconf - reload FPGA configuration");
puts("dmap - adds a MMU DTLB mapping");
puts("dunmap - removes a MMU DTLB mapping");
puts("dtlbi - invalidates the whole DTLB");
puts("dmapi - invalidates a DTLB mapping");
puts("mmu - activates MMU");
puts("nommu - disactivates MMU");
puts("mmuread - reads from memory with MMU enabled");
puts("mmuwrite - writes to memory with MMU enabled");
puts("dtlbtest - runs DTLB MMU load store tests");
puts("detest - runs DTLB MMU exception handling tests");
}
Expand Down Expand Up @@ -506,6 +514,75 @@ static void dtlbtest(void)

}

void mmuread(char *vaddr_str)
{
unsigned int vaddr, data;
char *c;

vaddr = strtoul(vaddr_str, &c, 0);

data = read_word_with_mmu_enabled(vaddr);

printf("0x%08X contains 0x%08X\n", vaddr, data);
}

void mmuwrite(char *vaddr_str, char * data_str)
{
unsigned int vaddr, data;
char *c;

vaddr = strtoul(vaddr_str, &c, 0);
data = strtoul(data_str, &c, 0);

write_word_with_mmu_enabled(vaddr, data);
}

void dmap(char *vaddr_str, char *paddr_str)
{
unsigned int vaddr, paddr;
char *c;

vaddr = strtoul(vaddr_str, &c, 0);
paddr = strtoul(paddr_str, &c, 0);

mmu_map(vaddr, paddr);
}

void dunmap(char *vaddr_str)
{
unsigned int vaddr;
char *c;

vaddr = strtoul(vaddr_str, &c, 0);

remove_mmu_mapping_for(vaddr);
}

void dtlbi(void)
{
mmu_dtlb_invalidate();
}

void dmapi(char *vaddr_str)
{
unsigned int vaddr;
char *c;

vaddr = strtoul(vaddr_str, &c, 0);

mmu_dtlb_invalidate_line(vaddr);
}

void activate_mmu(void)
{
enable_dtlb();
}

void disactivate_mmu(void)
{
disable_dtlb();
}

static void do_command(char *c)
{
char *token;
Expand Down Expand Up @@ -540,7 +617,14 @@ static void do_command(char *c)
else if(strcmp(token, "wcsr") == 0) wcsr(get_token(&c), get_token(&c));
else if(strcmp(token, "dtlbtest") == 0) dtlbtest();
else if(strcmp(token, "detest") == 0) dtlb_exception_handling_tests();

else if(strcmp(token, "dmap") == 0) dmap(get_token(&c), get_token(&c));
else if(strcmp(token, "dunmap") == 0) dunmap(get_token(&c));
else if(strcmp(token, "dtlbi") == 0) dtlbi();
else if(strcmp(token, "mmu") == 0) activate_mmu();
else if(strcmp(token, "nommu") == 0) disactivate_mmu();
else if(strcmp(token, "mmuread") == 0) mmuread(get_token(&c));
else if(strcmp(token, "mmuwrite") == 0) mmuwrite(get_token(&c), get_token(&c));
else if(strcmp(token, "dmapi") == 0) dmapi(get_token(&c));
else if(strcmp(token, "") != 0)
printf("Command not found\n");
}
Expand Down
3 changes: 2 additions & 1 deletion software/include/hal/mmu.h
Expand Up @@ -50,6 +50,7 @@ struct mmu_mapping {

void mmu_dtlb_map(unsigned int vpfn, unsigned int pfn);
unsigned int read_word_with_mmu_enabled(unsigned int vaddr);
void mmu_dtlb_invalidate(unsigned int vaddr);
void mmu_dtlb_invalidate_line(unsigned int vaddr);
void mmu_dtlb_invalidate(void);

#endif
45 changes: 34 additions & 11 deletions software/libhal/mmu.c
Expand Up @@ -18,32 +18,43 @@
#include <hal/mmu.h>
#include <base/mmu.h>

#define DTLB_CTRL_FLUSH_CMD (0x3)
#define DTLB_CTRL_DISABLE_CMD (0x5)
#define DTLB_CTRL_ENABLE_CMD (0x9)

/* @vpfn : virtual page frame number
* @pfn : physical page frame number
*/
inline void mmu_dtlb_map(unsigned int vpfn, unsigned int pfn)
{

asm volatile ("ori %0, %0, 1\n\t"
"wcsr tlbvaddr, %0"::"r"(vpfn):);
"wcsr tlbvaddr, %0" :: "r"(vpfn) : );

asm volatile ("ori %0, %0, 1\n\t"
"wcsr tlbpaddr, %0"::"r"(pfn):);

asm volatile ("xor r11, r11, r11\n\t"
"ori r11, r11, 0x5\n\t"
"wcsr tlbctrl, r11":::"r11");
"wcsr tlbctrl, r11" ::: "r11");

}

inline void mmu_dtlb_invalidate(unsigned int vaddr)
inline void mmu_dtlb_invalidate_line(unsigned int vaddr)
{
asm volatile ("ori %0, %0, 1\n\t"
"wcsr tlbvaddr, %0"::"r"(vaddr):);

asm volatile ("xor r11, r11, r11\n\t"
"ori r11, r11, 0x21\n\t"
"wcsr tlbctrl, r11":::"r11");
"wcsr tlbctrl, r11" ::: "r11");
}

inline void mmu_dtlb_invalidate(void)
{
register unsigned int cmd = DTLB_CTRL_FLUSH_CMD;
asm volatile("wcsr tlbctrl, %0" :: "r"(cmd) : );

}

/* This function activates the MMU
Expand All @@ -55,20 +66,32 @@ inline void mmu_dtlb_invalidate(unsigned int vaddr)

unsigned int read_word_with_mmu_enabled(unsigned int vaddr)
{
register unsigned int data;
register unsigned int data, cmd1, cmd2;

cmd1 = DTLB_CTRL_ENABLE_CMD;
cmd2 = DTLB_CTRL_DISABLE_CMD;

asm volatile("wcsr tlbctrl, %2\n\t" // Activates the MMU
"xor r0, r0, r0\n\t"
"lw %0, (%1+0)\n\t" // Reads from virtual address "addr"
"wcsr tlbctrl, %3\n\t" // Disactivates the MMU
"xor r0, r0, r0\n\t" : "=&r"(data) : "r"(vaddr), "r"(cmd1), "r"(cmd2) :
);

return data;
}

unsigned int write_word_with_mmu_enabled(register unsigned int vaddr, register unsigned int data)
{
asm volatile(
"xor r11, r11, r11\n\t"
"ori r11, r11, 0x11\n\t"
"wcsr tlbctrl, r11\n\t" // Activates the MMU
"xor r0, r0, r0\n\t"
"xor r11, r11, r11\n\t"
"or r11, r11, %1\n\t"
"lw %0, (r11+0)\n\t" // Reads from virtual address "addr"
"sw (%0 + 0), %1\n\t" // Reads from virtual address "addr"
"xor r11, r11, r11\n\t"
"ori r11, r11, 0x9\n\t"
"wcsr tlbctrl, r11\n\t" // Disactivates the MMU
"xor r0, r0, r0\n\t" : "=&r"(data) : "r"(vaddr) : "r11"
"xor r0, r0, r0\n\t" :: "r"(vaddr), "r"(data) : "r11"
);

return data;
}

0 comments on commit 2f35de4

Please sign in to comment.