1. diff --git a/software/bios/isr.c b/software/bios/isr.c
  2. index 80a6bda..22305f8 100644
  3. --- a/software/bios/isr.c
  4. +++ b/software/bios/isr.c
  5. @@ -30,10 +30,11 @@ void isr()
  6.  
  7.     if(irqs & IRQ_UART)
  8.         uart_isr();
  9. -      
  10. +/*    
  11.     if(irqs & IRQ_TMU)
  12.         tmu_isr();
  13.  
  14.     if(irqs & IRQ_USB)
  15.         usb_isr();
  16. +*/
  17.  }
  18. diff --git a/software/bios/main.c b/software/bios/main.c
  19. index d7a3ff6..5c39a67 100644
  20. --- a/software/bios/main.c
  21. +++ b/software/bios/main.c
  22. @@ -33,19 +33,20 @@
  23.  #include <hw/flash.h>
  24.  #include <hw/minimac.h>
  25.  
  26. -#include <hal/vga.h>
  27. -#include <hal/tmu.h>
  28. +//#include <hal/vga.h>
  29. +//#include <hal/tmu.h>
  30.  #include <hal/brd.h>
  31. -#include <hal/usb.h>
  32. -#include <hal/ukb.h>
  33. +//#include <hal/usb.h>
  34. +//#include <hal/ukb.h>
  35. +#include <hal/mmu.h>
  36.  
  37.  #include "boot.h"
  38. -#include "splash.h"
  39. +//#include "splash.h"
  40.  
  41.  enum {
  42.     CSR_IE = 1, CSR_IM, CSR_IP, CSR_ICC, CSR_DCC, CSR_CC, CSR_CFG, CSR_EBA,
  43.     CSR_DC, CSR_DEBA, CSR_JTX, CSR_JRX, CSR_BP0, CSR_BP1, CSR_BP2, CSR_BP3,
  44. -   CSR_WP0, CSR_WP1, CSR_WP2, CSR_WP3,
  45. +   CSR_WP0, CSR_WP1, CSR_WP2, CSR_WP3, CSR_TLBCTRL, CSR_TLBVADDR, CSR_TLBPADDR
  46.  };
  47.  
  48.  /* General address space functions */
  49. @@ -232,6 +233,9 @@ static int parse_csr(const char *csr)
  50.     if(!strcmp(csr, "wp1"))  return CSR_WP1;
  51.     if(!strcmp(csr, "wp2"))  return CSR_WP2;
  52.     if(!strcmp(csr, "wp3"))  return CSR_WP3;
  53. +   if(!strcmp(csr, "tlbctrl"))   return CSR_TLBCTRL;
  54. +   if(!strcmp(csr, "tlbvaddr"))  return CSR_TLBVADDR;
  55. +   if(!strcmp(csr, "tlbpaddr"))  return CSR_TLBPADDR;
  56.  
  57.     return 0;
  58.  }
  59. @@ -308,6 +312,9 @@ static void wcsr(char *csr, char *value)
  60.         case CSR_WP1:  asm volatile ("wcsr wp1,%0"::"r"(value2)); break;
  61.         case CSR_WP2:  asm volatile ("wcsr wp2,%0"::"r"(value2)); break;
  62.         case CSR_WP3:  asm volatile ("wcsr wp3,%0"::"r"(value2)); break;
  63. +       case CSR_TLBCTRL:   asm volatile ("wcsr tlbctrl,%0"::"r"(value2));  break;
  64. +       case CSR_TLBVADDR:  asm volatile ("wcsr tlbvaddr,%0"::"r"(value2)); break;
  65. +       case CSR_TLBPADDR:  asm volatile ("wcsr tlbpaddr,%0"::"r"(value2)); break;
  66.         default: printf("csr read only\n"); return;
  67.     }
  68.  }
  69. @@ -415,6 +422,7 @@ static void help()
  70.     puts("version    - display version");
  71.     puts("reboot     - system reset");
  72.     puts("reconf     - reload FPGA configuration");
  73. +   puts("dtlbtest   - runs DTLB MMU test");
  74.  }
  75.  
  76.  static char *get_token(char **str)
  77. @@ -433,6 +441,70 @@ static char *get_token(char **str)
  78.     return d;
  79.  }
  80.  
  81. +#define DTLB_CSR                   (1 << 31)
  82. +#define DTLB_CSR_CTRL_FLUSH                DTLB_CSR || (1 << 0)
  83. +#define DTLB_CSR_CTRL_UPDATE               DTLB_CSR || (1 << 1)
  84. +#define DTLB_CSR_CTRL_SWITCH_TO_KERNEL_MODE        DTLB_CSR || (1 << 30)
  85. +#define DTLB_CSR_CTRL_SWITCH_TO_USER_MODE      DTLB_CSR || (1 << 29)
  86. +
  87. +static void dtlbtest(void)
  88. +{
  89. +/* volatile unsigned int *addr;
  90. +   register unsigned int value = 0x43;
  91. +   puts("Starting DTLB tests...");
  92. +
  93. +   printf("Data store test : ");
  94. +
  95. +   //Let's try to map Virtual address 0x44001000 to Physical address 0x44000000
  96. +   mmu_dtlb_map(0x44001000, 0x44000000);
  97. +
  98. +   //Enable MMU DTLB
  99. +   enable_dtlb();
  100. +
  101. +   // Let's write to Virtual address 0x44001000
  102. +   // addr = (unsigned int *)0x44001000;
  103. +   // *addr = 0x42;
  104. +
  105. +   asm volatile    ("mvhi r11, 0x4400\n\t"
  106. +            "ori r11, r11, 0x1000\n\t"
  107. +            "xor r12, r12, r12\n\t"
  108. +            "ori r12, r12, 0x42\n\t"
  109. +            "sw (r11+0), r12":::"r11", "r12");
  110. +
  111. +   // Disable DTLB -> going back into KERNEL MODE
  112. +   disable_dtlb();
  113. +
  114. +   //Let's read back from Physical address 0x44000000
  115. +   addr = (unsigned int *)0x44000000;
  116. +   if (*addr == 0x42)
  117. +       puts("SUCCESS");
  118. +   else
  119. +       puts("FAILURE");
  120. +
  121. +   printf("0x44000000 contains %08X\n", *addr);
  122. +
  123. +   printf("Data load test : ");
  124. +
  125. +   //Now let's try to read from Virtual address 0x44001000
  126. +   enable_dtlb();
  127. +   //Following code means : value = *(unsigned int *)0x44001000;
  128. +   asm volatile    ("mvhi r11, 0x4400\n\t"
  129. +            "ori r11, r11, 0x1000\n\t"
  130. +            "lw %0, (r11+0)":"=r"(value)::"r11");
  131. +   disable_dtlb();
  132. +
  133. +   if (value == 0x42)
  134. +       puts("SUCCESS");
  135. +   else
  136. +       puts("FAILURE");
  137. +
  138. +   printf("value contains %08X\n", value);
  139. +*/
  140. +   //Running more dtlb load tests
  141. +   dtlb_load_test();
  142. +
  143. +}
  144. +
  145.  static void do_command(char *c)
  146.  {
  147.     char *token;
  148. @@ -465,6 +537,7 @@ static void do_command(char *c)
  149.  
  150.     else if(strcmp(token, "rcsr") == 0) rcsr(get_token(&c));
  151.     else if(strcmp(token, "wcsr") == 0) wcsr(get_token(&c), get_token(&c));
  152. +   else if(strcmp(token, "dtlbtest") == 0) dtlbtest();
  153.  
  154.     else if(strcmp(token, "") != 0)
  155.         printf("Command not found\n");
  156. @@ -612,6 +685,7 @@ static void ethreset()
  157.  int main(int i, char **c)
  158.  {
  159.     char buffer[64];
  160. +   unsigned short int k;
  161.  
  162.     /* lock gdbstub ROM */
  163.     CSR_DBG_CTRL = DBG_CTRL_GDB_ROM_LOCK;
  164. @@ -625,27 +699,28 @@ int main(int i, char **c)
  165.     irq_setmask(0);
  166.     irq_enable(1);
  167.     uart_init();
  168. -   vga_init(!(rescue || (CSR_GPIO_IN & GPIO_BTN2)));
  169.     putsnonl(banner);
  170.     crcbios();
  171.     brd_init();
  172. -   tmu_init(); /* < for hardware-accelerated scrolling */
  173. -   usb_init();
  174. -   ukb_init();
  175.  
  176.     if(rescue)
  177.         printf("I: Booting in rescue mode\n");
  178.  
  179. -   splash_display();
  180. -   ethreset(); /* < that pesky ethernet PHY needs two resets at times... */
  181. -   print_mac();
  182.     boot_sequence();
  183. -   vga_unblank();
  184. -   vga_set_console(1);
  185. +
  186. +   uart_force_sync(1);
  187. +   irq_enable(0);
  188. +
  189. +   for (k = 0 ; k < 65000 ; ++k)
  190. +       asm volatile("nop");
  191. +
  192. +   dtlb_load_test();
  193. +
  194.     while(1) {
  195. -       putsnonl("\e[1mBIOS>\e[0m ");
  196. -       readstr(buffer, 64);
  197. -       do_command(buffer);
  198. +       if (++k == 0)
  199. +           printf(".");
  200. +       asm volatile("nop");
  201.     }
  202. +
  203.     return 0;
  204.  }
  205. diff --git a/software/bios/mmu_test_gen.c b/software/bios/mmu_test_gen.c
  206. new file mode 100644
  207. index 0000000..75bb22d
  208. --- /dev/null
  209. +++ b/software/bios/mmu_test_gen.c
  210. @@ -0,0 +1,115 @@
  211. +/* MMU test generator
  212. + * Author : Yann Sionneau <yann.sionneau@gmail.com>
  213. + */
  214. +
  215. +#include <stdio.h>
  216. +
  217. +static inline void generate_test(int i, int j) {
  218. +   int k;
  219. +
  220. +   puts("asm volatile(");
  221. +   puts("\t\"xor r11, r11, r11\\n\\t\"");
  222. +   puts("\t\"ori r11, r11, 0x11\\n\\t\"");
  223. +   puts("\t\"wcsr tlbctrl, r11\\n\\t\"");
  224. +   puts("\t\"xor r0, r0, r0\\n\\t\"");
  225. +   puts("\t\"xor r0, r0, r0\\n\\t\"");
  226. +   puts("\t\"xor r0, r0, r0\\n\\t\"");
  227. +   for (k = 0 ; k < 6 ; k++) {
  228. +       if (k == i) {
  229. +           printf("\t\"sw (%2+0), %1");
  230. +       }
  231. +       else if(k == j) {
  232. +           printf("\t\"lw %0, (%2+0)");
  233. +       }
  234. +       else
  235. +           printf("\t\"xor r0, r0, r0");
  236. +       if (k != 5)
  237. +           printf("\\n\\t");
  238. +       puts("\"");
  239. +   }
  240. +
  241. +   puts(": \"=&r\"(value_verif) : \"r\"(value), \"r\"(addr) :\"r11\"\n);");
  242. +
  243. +}
  244. +
  245. +int main(void) {
  246. +
  247. +   puts("#include <hal/mmu.h>\n");
  248. +   puts("#include <base/console.h>\n");
  249. +   puts("#include <stdio.h>\n");
  250. +   puts("void dtlb_load_test(void) {\n");
  251. +
  252. +   puts(  
  253. +       "char a, b, c, d;\n"
  254. +       "// map vaddr 0x4400 2000 to paddr 0x4400 1000\n"
  255. +       "register unsigned int value, addr, value_verif, stack, data;\n"
  256. +       "int success, failure;\n"
  257. +       "unsigned int count;\n"
  258. +       "asm volatile(\"mv %0, sp\" : \"=r\"(stack) :: );\n"
  259. +       "mmu_dtlb_map(0x44002000, 0x44001000);\n"
  260. +       "mmu_dtlb_map(stack, stack);\n"
  261. +       "mmu_dtlb_map(stack-0x1000, stack-0x1000);\n"
  262. +       "printf(\"stack == 0x%08X\\n\", stack);"
  263. +       "a = 0;\n"
  264. +       "b = 1;\n"
  265. +       "c = 2;\n"
  266. +       "d = 3;\n"
  267. +       "addr = 0x44002000;\n"
  268. +       "success = 0;\n"
  269. +       "failure = 0;"
  270. +   );
  271. +
  272. +   int test_num = 0;
  273. +   int i, j;
  274. +
  275. +   for (i = 0 ; i < 5 ; i++) {
  276. +       for (j = i+1 ; j < 6 ; j++) {
  277. +
  278. +           puts(   "value = a << 24;\n"
  279. +               "value |= b << 16;\n"
  280. +               "value |= c << 8;\n"
  281. +               "value |= d;\n"
  282. +               "addr += 4;\n"
  283. +           );
  284. +
  285. +
  286. +           generate_test(i, j);
  287. +
  288. +           puts("disable_dtlb();");
  289. +           puts("printf(\"addr == 0x%08X\\n\", addr);");
  290. +           puts("printf(\"[MMU OFF] *(0x%08X) == 0x%08X\\n\", addr, *(volatile unsigned int *)addr);");
  291. +           puts("enable_dtlb();");
  292. +           puts("asm volatile(\"lw %0, (%1+0)\" : \"=&r\"(data) : \"r\"(addr) : );");
  293. +           puts("disable_dtlb();");
  294. +           puts("printf(\"[MMU ON] *(0x%08X) == 0x%08X\\n\", addr, data);");
  295. +           puts("printf(\"[MMU OFF] *(0x%08X) == 0x%08X\\n\", addr-0x1000, *(volatile unsigned int *)(addr - 0x1000));");
  296. +           printf("printf(\"Test n° %02d : \");\n", test_num);
  297. +           puts(   "if (value == value_verif) {\n"
  298. +                   "\tputs(\"PASS\");\n"
  299. +                   "\tsuccess++;\n"
  300. +               "} else {\n"
  301. +                   "\tputs(\"FAIL\");\n"
  302. +                   "\tfailure++;\n"
  303. +               "}"
  304. +           );
  305. +
  306. +           puts(   "a++;\n"
  307. +               "b++;\n"
  308. +               "c++;\n"
  309. +               "d++;\n\n"
  310. +           );
  311. +           test_num++;
  312. +
  313. +           puts("\
  314. +           for (count = 0 ; count <= 10000000 ; ++count) {\n\
  315. +           \t  asm volatile(\"nop\");\n\
  316. +           }");
  317. +       }
  318. +   }
  319. +
  320. +   puts("printf(\"TOTAL : %d/%d successes | %d/%d failures\\n\", success, success + failure, failure, success + failure);");
  321. +
  322. +   puts("}");
  323. +
  324. +   return 0;
  325. +}
  326. diff --git a/software/include/fpvm/ast.h b/software/include/fpvm/ast.h
  327. index fa0159c..fa2b6eb 100644
  328. --- a/software/include/fpvm/ast.h
  329. +++ b/software/include/fpvm/ast.h
  330. @@ -48,8 +48,6 @@ enum ast_op {
  331.     op_max,
  332.     op_int,
  333.     op_bnot,
  334. -   op_band,
  335. -   op_bor,
  336.  };
  337.  
  338.  /* maximum supported arity is 3 */
  339. diff --git a/software/include/hal/mmu.h b/software/include/hal/mmu.h
  340. new file mode 100644
  341. index 0000000..f36641d
  342. --- /dev/null
  343. +++ b/software/include/hal/mmu.h
  344. @@ -0,0 +1,35 @@
  345. +/*
  346. + * Milkymist SoC (Software)
  347. + * Copyright (C) 2012 Yann Sionneau <yann.sionneau@gmail.com>
  348. + *
  349. + * This program is free software: you can redistribute it and/or modify
  350. + * it under the terms of the GNU General Public License as published by
  351. + * the Free Software Foundation, version 3 of the License.
  352. + *
  353. + * This program is distributed in the hope that it will be useful,
  354. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  355. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  356. + * GNU General Public License for more details.
  357. + *
  358. + * You should have received a copy of the GNU General Public License
  359. + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  360. + */
  361. +
  362. +
  363. +#define enable_dtlb() do { \
  364. +   asm volatile    ("xor r11, r11, r11\n\t" \
  365. +            "ori r11, r11, 0x11\n\t" \
  366. +            "wcsr tlbctrl, r11\n\t" \
  367. +            "xor r0, r0, r0":::"r11"); \
  368. +} while(0);
  369. +
  370. +#define disable_dtlb() do { \
  371. +   asm volatile    ("xor r11, r11, r11\n\t" \
  372. +            "ori r11, r11, 0x9\n\t" \
  373. +            "wcsr tlbctrl, r11\n\t" \
  374. +            "xor r0, r0, r0\n\t" \
  375. +            "xor r0, r0, r0\n\t" \
  376. +            "xor r0, r0, r0":::"r11"); \
  377. +} while(0);
  378. +
  379. +void mmu_dtlb_map(unsigned int vpfn, unsigned int pfn);
  380. diff --git a/software/libbase/uart.c b/software/libbase/uart.c
  381. index dabddfe..c751aee 100644
  382. --- a/software/libbase/uart.c
  383. +++ b/software/libbase/uart.c
  384. @@ -49,6 +49,15 @@ void uart_isr(void)
  385.  {
  386.     unsigned int stat = CSR_UART_STAT;
  387.  
  388. +   mmu_dtlb_map(uart_isr, uart_isr);
  389. +   mmu_dtlb_map(rx_buf, rx_buf);
  390. +   mmu_dtlb_map(tx_buf, tx_buf);
  391. +   mmu_dtlb_map(&tx_produce, &tx_produce);
  392. +   mmu_dtlb_map(&tx_consume, &tx_consume);
  393. +   mmu_dtlb_map(&rx_produce, &rx_produce);
  394. +   mmu_dtlb_map(&tx_cts, &tx_cts);
  395. +   mmu_dtlb_map(irq_ack, irq_ack);
  396. +
  397.     if(stat & UART_STAT_RX_EVT) {
  398.         rx_buf[rx_produce] = CSR_UART_RXTX;
  399.         rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
  400. diff --git a/software/libfpvm/fpvm.c b/software/libfpvm/fpvm.c
  401. index b76b13d..75c74f1 100644
  402. --- a/software/libfpvm/fpvm.c
  403. +++ b/software/libfpvm/fpvm.c
  404. @@ -395,11 +395,6 @@ static int compile(struct fpvm_fragment *fragment, int reg, struct ast_node *nod
  405.         opb = COMPILE(FPVM_INVALID_REG, node->contents.branches.c);
  406.         (void) COMPILE(FPVM_REG_IFB, node->contents.branches.a);
  407.         break;
  408. -   case op_band:
  409. -   case op_bor:
  410. -       opa = opb = 0;
  411. -       (void) COMPILE(FPVM_REG_IFB, node->contents.branches.a);
  412. -       break;
  413.     case op_negate:
  414.         if(node->contents.branches.a->op == op_constant) {
  415.             /* Node is a negative constant */
  416. @@ -533,26 +528,6 @@ static int compile(struct fpvm_fragment *fragment, int reg, struct ast_node *nod
  417.             return FPVM_INVALID_REG;
  418.         ADD_ISN(FPVM_OPCODE_EQUAL, opa, opb, reg);
  419.         break;
  420. -   case op_band: {
  421. -       int reg_zero = REG_CONST(0);
  422. -       int reg_one = REG_CONST(1);
  423. -       int reg_tmp = REG_ALLOC();
  424. -
  425. -       ADD_ISN(FPVM_OPCODE_IF, reg_one, reg_zero, reg_tmp);
  426. -       (void) COMPILE(FPVM_REG_IFB, node->contents.branches.b);
  427. -       ADD_ISN(FPVM_OPCODE_IF, reg_tmp, reg_zero, reg);
  428. -       break;
  429. -   }
  430. -   case op_bor: {
  431. -       int reg_zero = REG_CONST(0);
  432. -       int reg_one = REG_CONST(1);
  433. -       int reg_tmp = REG_ALLOC();
  434. -
  435. -       ADD_ISN(FPVM_OPCODE_IF, reg_one, reg_zero, reg_tmp);
  436. -       (void) COMPILE(FPVM_REG_IFB, node->contents.branches.b);
  437. -       ADD_ISN(FPVM_OPCODE_IF, reg_one, reg_tmp, reg);
  438. -       break;
  439. -   }
  440.     default:
  441.         /* Normal case */
  442.         opcode = operator2opcode(node->op);
  443. diff --git a/software/libhal/Makefile b/software/libhal/Makefile
  444. index a33fb9c..3e3dcd0 100644
  445. --- a/software/libhal/Makefile
  446. +++ b/software/libhal/Makefile
  447. @@ -1,7 +1,7 @@
  448.  MMDIR=../..
  449.  include $(MMDIR)/software/include.mak
  450.  
  451. -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
  452. +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
  453.  
  454.  all: libhal.a
  455.  
  456. diff --git a/software/libhal/mmu.c b/software/libhal/mmu.c
  457. new file mode 100644
  458. index 0000000..c82352b
  459. --- /dev/null
  460. +++ b/software/libhal/mmu.c
  461. @@ -0,0 +1,34 @@
  462. +/*
  463. + * Milkymist SoC (Software)
  464. + * Copyright (C) 2012 Yann Sionneau <yann.sionneau@gmail.com>
  465. + *
  466. + * This program is free software: you can redistribute it and/or modify
  467. + * it under the terms of the GNU General Public License as published by
  468. + * the Free Software Foundation, version 3 of the License.
  469. + *
  470. + * This program is distributed in the hope that it will be useful,
  471. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  472. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  473. + * GNU General Public License for more details.
  474. + *
  475. + * You should have received a copy of the GNU General Public License
  476. + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  477. + */
  478. +
  479. +/* @vpfn : virtual page frame number
  480. + * @pfn  : physical page frame number
  481. + */
  482. +inline void mmu_dtlb_map(unsigned int vpfn, unsigned int pfn)
  483. +{
  484. +
  485. +   asm volatile    ("ori %0, %0, 1\n\t"
  486. +            "wcsr tlbvaddr, %0"::"r"(vpfn):);
  487. +
  488. +   asm volatile    ("ori %0, %0, 1\n\t"
  489. +            "wcsr tlbpaddr, %0"::"r"(pfn):);
  490. +
  491. +   asm volatile    ("xor r11, r11, r11\n\t"
  492. +            "ori r11, r11, 0x5\n\t"
  493. +            "wcsr tlbctrl, r11":::"r11");
  494. +
  495. +}