Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/software/bios/isr.c b/software/bios/isr.c
- index 80a6bda..22305f8 100644
- --- a/software/bios/isr.c
- +++ b/software/bios/isr.c
- @@ -30,10 +30,11 @@ void isr()
- if(irqs & IRQ_UART)
- uart_isr();
- -
- +/*
- if(irqs & IRQ_TMU)
- tmu_isr();
- if(irqs & IRQ_USB)
- usb_isr();
- +*/
- }
- diff --git a/software/bios/main.c b/software/bios/main.c
- index d7a3ff6..5c39a67 100644
- --- a/software/bios/main.c
- +++ b/software/bios/main.c
- @@ -33,19 +33,20 @@
- #include <hw/flash.h>
- #include <hw/minimac.h>
- -#include <hal/vga.h>
- -#include <hal/tmu.h>
- +//#include <hal/vga.h>
- +//#include <hal/tmu.h>
- #include <hal/brd.h>
- -#include <hal/usb.h>
- -#include <hal/ukb.h>
- +//#include <hal/usb.h>
- +//#include <hal/ukb.h>
- +#include <hal/mmu.h>
- #include "boot.h"
- -#include "splash.h"
- +//#include "splash.h"
- enum {
- CSR_IE = 1, CSR_IM, CSR_IP, CSR_ICC, CSR_DCC, CSR_CC, CSR_CFG, CSR_EBA,
- CSR_DC, CSR_DEBA, CSR_JTX, CSR_JRX, CSR_BP0, CSR_BP1, CSR_BP2, CSR_BP3,
- - CSR_WP0, CSR_WP1, CSR_WP2, CSR_WP3,
- + CSR_WP0, CSR_WP1, CSR_WP2, CSR_WP3, CSR_TLBCTRL, CSR_TLBVADDR, CSR_TLBPADDR
- };
- /* General address space functions */
- @@ -232,6 +233,9 @@ static int parse_csr(const char *csr)
- if(!strcmp(csr, "wp1")) return CSR_WP1;
- if(!strcmp(csr, "wp2")) return CSR_WP2;
- if(!strcmp(csr, "wp3")) return CSR_WP3;
- + if(!strcmp(csr, "tlbctrl")) return CSR_TLBCTRL;
- + if(!strcmp(csr, "tlbvaddr")) return CSR_TLBVADDR;
- + if(!strcmp(csr, "tlbpaddr")) return CSR_TLBPADDR;
- return 0;
- }
- @@ -308,6 +312,9 @@ static void wcsr(char *csr, char *value)
- case CSR_WP1: asm volatile ("wcsr wp1,%0"::"r"(value2)); break;
- case CSR_WP2: asm volatile ("wcsr wp2,%0"::"r"(value2)); break;
- case CSR_WP3: asm volatile ("wcsr wp3,%0"::"r"(value2)); break;
- + case CSR_TLBCTRL: asm volatile ("wcsr tlbctrl,%0"::"r"(value2)); break;
- + case CSR_TLBVADDR: asm volatile ("wcsr tlbvaddr,%0"::"r"(value2)); break;
- + case CSR_TLBPADDR: asm volatile ("wcsr tlbpaddr,%0"::"r"(value2)); break;
- default: printf("csr read only\n"); return;
- }
- }
- @@ -415,6 +422,7 @@ static void help()
- puts("version - display version");
- puts("reboot - system reset");
- puts("reconf - reload FPGA configuration");
- + puts("dtlbtest - runs DTLB MMU test");
- }
- static char *get_token(char **str)
- @@ -433,6 +441,70 @@ static char *get_token(char **str)
- return d;
- }
- +#define DTLB_CSR (1 << 31)
- +#define DTLB_CSR_CTRL_FLUSH DTLB_CSR || (1 << 0)
- +#define DTLB_CSR_CTRL_UPDATE DTLB_CSR || (1 << 1)
- +#define DTLB_CSR_CTRL_SWITCH_TO_KERNEL_MODE DTLB_CSR || (1 << 30)
- +#define DTLB_CSR_CTRL_SWITCH_TO_USER_MODE DTLB_CSR || (1 << 29)
- +
- +static void dtlbtest(void)
- +{
- +/* volatile unsigned int *addr;
- + register unsigned int value = 0x43;
- + puts("Starting DTLB tests...");
- +
- + printf("Data store test : ");
- +
- + //Let's try to map Virtual address 0x44001000 to Physical address 0x44000000
- + mmu_dtlb_map(0x44001000, 0x44000000);
- +
- + //Enable MMU DTLB
- + enable_dtlb();
- +
- + // Let's write to Virtual address 0x44001000
- + // addr = (unsigned int *)0x44001000;
- + // *addr = 0x42;
- +
- + asm volatile ("mvhi r11, 0x4400\n\t"
- + "ori r11, r11, 0x1000\n\t"
- + "xor r12, r12, r12\n\t"
- + "ori r12, r12, 0x42\n\t"
- + "sw (r11+0), r12":::"r11", "r12");
- +
- + // Disable DTLB -> going back into KERNEL MODE
- + disable_dtlb();
- +
- + //Let's read back from Physical address 0x44000000
- + addr = (unsigned int *)0x44000000;
- + if (*addr == 0x42)
- + puts("SUCCESS");
- + else
- + puts("FAILURE");
- +
- + printf("0x44000000 contains %08X\n", *addr);
- +
- + printf("Data load test : ");
- +
- + //Now let's try to read from Virtual address 0x44001000
- + enable_dtlb();
- + //Following code means : value = *(unsigned int *)0x44001000;
- + asm volatile ("mvhi r11, 0x4400\n\t"
- + "ori r11, r11, 0x1000\n\t"
- + "lw %0, (r11+0)":"=r"(value)::"r11");
- + disable_dtlb();
- +
- + if (value == 0x42)
- + puts("SUCCESS");
- + else
- + puts("FAILURE");
- +
- + printf("value contains %08X\n", value);
- +*/
- + //Running more dtlb load tests
- + dtlb_load_test();
- +
- +}
- +
- static void do_command(char *c)
- {
- char *token;
- @@ -465,6 +537,7 @@ static void do_command(char *c)
- else if(strcmp(token, "rcsr") == 0) rcsr(get_token(&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, "") != 0)
- printf("Command not found\n");
- @@ -612,6 +685,7 @@ static void ethreset()
- int main(int i, char **c)
- {
- char buffer[64];
- + unsigned short int k;
- /* lock gdbstub ROM */
- CSR_DBG_CTRL = DBG_CTRL_GDB_ROM_LOCK;
- @@ -625,27 +699,28 @@ int main(int i, char **c)
- irq_setmask(0);
- irq_enable(1);
- uart_init();
- - vga_init(!(rescue || (CSR_GPIO_IN & GPIO_BTN2)));
- putsnonl(banner);
- crcbios();
- brd_init();
- - tmu_init(); /* < for hardware-accelerated scrolling */
- - usb_init();
- - ukb_init();
- if(rescue)
- printf("I: Booting in rescue mode\n");
- - splash_display();
- - ethreset(); /* < that pesky ethernet PHY needs two resets at times... */
- - print_mac();
- boot_sequence();
- - vga_unblank();
- - vga_set_console(1);
- +
- + uart_force_sync(1);
- + irq_enable(0);
- +
- + for (k = 0 ; k < 65000 ; ++k)
- + asm volatile("nop");
- +
- + dtlb_load_test();
- +
- while(1) {
- - putsnonl("\e[1mBIOS>\e[0m ");
- - readstr(buffer, 64);
- - do_command(buffer);
- + if (++k == 0)
- + printf(".");
- + asm volatile("nop");
- }
- +
- return 0;
- }
- diff --git a/software/bios/mmu_test_gen.c b/software/bios/mmu_test_gen.c
- new file mode 100644
- index 0000000..75bb22d
- --- /dev/null
- +++ b/software/bios/mmu_test_gen.c
- @@ -0,0 +1,115 @@
- +/* MMU test generator
- + * Author : Yann Sionneau <yann.sionneau@gmail.com>
- + */
- +
- +#include <stdio.h>
- +
- +static inline void generate_test(int i, int j) {
- + int k;
- +
- + puts("asm volatile(");
- + puts("\t\"xor r11, r11, r11\\n\\t\"");
- + puts("\t\"ori r11, r11, 0x11\\n\\t\"");
- + puts("\t\"wcsr tlbctrl, r11\\n\\t\"");
- + puts("\t\"xor r0, r0, r0\\n\\t\"");
- + puts("\t\"xor r0, r0, r0\\n\\t\"");
- + puts("\t\"xor r0, r0, r0\\n\\t\"");
- + for (k = 0 ; k < 6 ; k++) {
- + if (k == i) {
- + printf("\t\"sw (%2+0), %1");
- + }
- + else if(k == j) {
- + printf("\t\"lw %0, (%2+0)");
- + }
- + else
- + printf("\t\"xor r0, r0, r0");
- + if (k != 5)
- + printf("\\n\\t");
- + puts("\"");
- + }
- +
- + puts(": \"=&r\"(value_verif) : \"r\"(value), \"r\"(addr) :\"r11\"\n);");
- +
- +}
- +
- +int main(void) {
- +
- + puts("#include <hal/mmu.h>\n");
- + puts("#include <base/console.h>\n");
- + puts("#include <stdio.h>\n");
- + puts("void dtlb_load_test(void) {\n");
- +
- + puts(
- + "char a, b, c, d;\n"
- + "// map vaddr 0x4400 2000 to paddr 0x4400 1000\n"
- + "register unsigned int value, addr, value_verif, stack, data;\n"
- + "int success, failure;\n"
- + "unsigned int count;\n"
- + "asm volatile(\"mv %0, sp\" : \"=r\"(stack) :: );\n"
- + "mmu_dtlb_map(0x44002000, 0x44001000);\n"
- + "mmu_dtlb_map(stack, stack);\n"
- + "mmu_dtlb_map(stack-0x1000, stack-0x1000);\n"
- + "printf(\"stack == 0x%08X\\n\", stack);"
- + "a = 0;\n"
- + "b = 1;\n"
- + "c = 2;\n"
- + "d = 3;\n"
- + "addr = 0x44002000;\n"
- + "success = 0;\n"
- + "failure = 0;"
- + );
- +
- + int test_num = 0;
- + int i, j;
- +
- + for (i = 0 ; i < 5 ; i++) {
- + for (j = i+1 ; j < 6 ; j++) {
- +
- + puts( "value = a << 24;\n"
- + "value |= b << 16;\n"
- + "value |= c << 8;\n"
- + "value |= d;\n"
- + "addr += 4;\n"
- + );
- +
- +
- + generate_test(i, j);
- +
- + puts("disable_dtlb();");
- + puts("printf(\"addr == 0x%08X\\n\", addr);");
- + puts("printf(\"[MMU OFF] *(0x%08X) == 0x%08X\\n\", addr, *(volatile unsigned int *)addr);");
- + puts("enable_dtlb();");
- + puts("asm volatile(\"lw %0, (%1+0)\" : \"=&r\"(data) : \"r\"(addr) : );");
- + puts("disable_dtlb();");
- + puts("printf(\"[MMU ON] *(0x%08X) == 0x%08X\\n\", addr, data);");
- + puts("printf(\"[MMU OFF] *(0x%08X) == 0x%08X\\n\", addr-0x1000, *(volatile unsigned int *)(addr - 0x1000));");
- + printf("printf(\"Test n° %02d : \");\n", test_num);
- + puts( "if (value == value_verif) {\n"
- + "\tputs(\"PASS\");\n"
- + "\tsuccess++;\n"
- + "} else {\n"
- + "\tputs(\"FAIL\");\n"
- + "\tfailure++;\n"
- + "}"
- + );
- +
- + puts( "a++;\n"
- + "b++;\n"
- + "c++;\n"
- + "d++;\n\n"
- + );
- + test_num++;
- +
- + puts("\
- + for (count = 0 ; count <= 10000000 ; ++count) {\n\
- + \t asm volatile(\"nop\");\n\
- + }");
- + }
- + }
- +
- + puts("printf(\"TOTAL : %d/%d successes | %d/%d failures\\n\", success, success + failure, failure, success + failure);");
- +
- + puts("}");
- +
- + return 0;
- +}
- diff --git a/software/include/fpvm/ast.h b/software/include/fpvm/ast.h
- index fa0159c..fa2b6eb 100644
- --- a/software/include/fpvm/ast.h
- +++ b/software/include/fpvm/ast.h
- @@ -48,8 +48,6 @@ enum ast_op {
- op_max,
- op_int,
- op_bnot,
- - op_band,
- - op_bor,
- };
- /* maximum supported arity is 3 */
- diff --git a/software/include/hal/mmu.h b/software/include/hal/mmu.h
- new file mode 100644
- index 0000000..f36641d
- --- /dev/null
- +++ b/software/include/hal/mmu.h
- @@ -0,0 +1,35 @@
- +/*
- + * Milkymist SoC (Software)
- + * Copyright (C) 2012 Yann Sionneau <yann.sionneau@gmail.com>
- + *
- + * This program is free software: you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation, version 3 of the License.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program. If not, see <http://www.gnu.org/licenses/>.
- + */
- +
- +
- +#define enable_dtlb() do { \
- + asm volatile ("xor r11, r11, r11\n\t" \
- + "ori r11, r11, 0x11\n\t" \
- + "wcsr tlbctrl, r11\n\t" \
- + "xor r0, r0, r0":::"r11"); \
- +} while(0);
- +
- +#define disable_dtlb() do { \
- + asm volatile ("xor r11, r11, r11\n\t" \
- + "ori r11, r11, 0x9\n\t" \
- + "wcsr tlbctrl, r11\n\t" \
- + "xor r0, r0, r0\n\t" \
- + "xor r0, r0, r0\n\t" \
- + "xor r0, r0, r0":::"r11"); \
- +} while(0);
- +
- +void mmu_dtlb_map(unsigned int vpfn, unsigned int pfn);
- diff --git a/software/libbase/uart.c b/software/libbase/uart.c
- index dabddfe..c751aee 100644
- --- a/software/libbase/uart.c
- +++ b/software/libbase/uart.c
- @@ -49,6 +49,15 @@ void uart_isr(void)
- {
- unsigned int stat = CSR_UART_STAT;
- + mmu_dtlb_map(uart_isr, uart_isr);
- + mmu_dtlb_map(rx_buf, rx_buf);
- + mmu_dtlb_map(tx_buf, tx_buf);
- + mmu_dtlb_map(&tx_produce, &tx_produce);
- + mmu_dtlb_map(&tx_consume, &tx_consume);
- + mmu_dtlb_map(&rx_produce, &rx_produce);
- + mmu_dtlb_map(&tx_cts, &tx_cts);
- + mmu_dtlb_map(irq_ack, irq_ack);
- +
- if(stat & UART_STAT_RX_EVT) {
- rx_buf[rx_produce] = CSR_UART_RXTX;
- rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
- diff --git a/software/libfpvm/fpvm.c b/software/libfpvm/fpvm.c
- index b76b13d..75c74f1 100644
- --- a/software/libfpvm/fpvm.c
- +++ b/software/libfpvm/fpvm.c
- @@ -395,11 +395,6 @@ static int compile(struct fpvm_fragment *fragment, int reg, struct ast_node *nod
- opb = COMPILE(FPVM_INVALID_REG, node->contents.branches.c);
- (void) COMPILE(FPVM_REG_IFB, node->contents.branches.a);
- break;
- - case op_band:
- - case op_bor:
- - opa = opb = 0;
- - (void) COMPILE(FPVM_REG_IFB, node->contents.branches.a);
- - break;
- case op_negate:
- if(node->contents.branches.a->op == op_constant) {
- /* Node is a negative constant */
- @@ -533,26 +528,6 @@ static int compile(struct fpvm_fragment *fragment, int reg, struct ast_node *nod
- return FPVM_INVALID_REG;
- ADD_ISN(FPVM_OPCODE_EQUAL, opa, opb, reg);
- break;
- - case op_band: {
- - int reg_zero = REG_CONST(0);
- - int reg_one = REG_CONST(1);
- - int reg_tmp = REG_ALLOC();
- -
- - ADD_ISN(FPVM_OPCODE_IF, reg_one, reg_zero, reg_tmp);
- - (void) COMPILE(FPVM_REG_IFB, node->contents.branches.b);
- - ADD_ISN(FPVM_OPCODE_IF, reg_tmp, reg_zero, reg);
- - break;
- - }
- - case op_bor: {
- - int reg_zero = REG_CONST(0);
- - int reg_one = REG_CONST(1);
- - int reg_tmp = REG_ALLOC();
- -
- - ADD_ISN(FPVM_OPCODE_IF, reg_one, reg_zero, reg_tmp);
- - (void) COMPILE(FPVM_REG_IFB, node->contents.branches.b);
- - ADD_ISN(FPVM_OPCODE_IF, reg_one, reg_tmp, reg);
- - break;
- - }
- default:
- /* Normal case */
- opcode = operator2opcode(node->op);
- diff --git a/software/libhal/Makefile b/software/libhal/Makefile
- index a33fb9c..3e3dcd0 100644
- --- a/software/libhal/Makefile
- +++ b/software/libhal/Makefile
- @@ -1,7 +1,7 @@
- MMDIR=../..
- include $(MMDIR)/software/include.mak
- -OBJECTS=brd.o dmx.o font8x16.o mem.o pfpu.o snd.o time.o tmu.o ukb.o usb.o vga.o vin.o
- +OBJECTS=brd.o dmx.o font8x16.o mem.o pfpu.o snd.o time.o tmu.o ukb.o usb.o vga.o vin.o mmu.o
- all: libhal.a
- diff --git a/software/libhal/mmu.c b/software/libhal/mmu.c
- new file mode 100644
- index 0000000..c82352b
- --- /dev/null
- +++ b/software/libhal/mmu.c
- @@ -0,0 +1,34 @@
- +/*
- + * Milkymist SoC (Software)
- + * Copyright (C) 2012 Yann Sionneau <yann.sionneau@gmail.com>
- + *
- + * This program is free software: you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation, version 3 of the License.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program. If not, see <http://www.gnu.org/licenses/>.
- + */
- +
- +/* @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):);
- +
- + 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");
- +
- +}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement