From 94fc2c3ecf51dabbf4aea6430d4cbefafc57f837 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 26 Mar 2019 01:25:18 +0100 Subject: [PATCH] Fix some models missmatch Add more SBI Add hardware LR/SC support in dbus cacheless --- src/main/c/emulator/build/emulator.asm | 693 +++++++++++------- src/main/c/emulator/build/emulator.hex | 162 ++-- src/main/c/emulator/src/config.h | 3 - src/main/c/emulator/src/hal.c | 25 + src/main/c/emulator/src/hal.h | 23 + src/main/c/emulator/src/main.c | 131 ++-- src/main/c/emulator/src/riscv.h | 18 +- src/main/c/emulator/src/start.S | 4 +- src/main/c/emulator/src/utils.S | 47 ++ src/main/scala/vexriscv/demo/Linux.scala | 12 +- .../scala/vexriscv/plugin/CsrPlugin.scala | 6 +- .../vexriscv/plugin/DBusSimplePlugin.scala | 89 ++- src/test/cpp/regression/main.cpp | 104 ++- src/test/cpp/regression/makefile | 2 +- 14 files changed, 886 insertions(+), 433 deletions(-) create mode 100644 src/main/c/emulator/src/hal.c create mode 100644 src/main/c/emulator/src/hal.h create mode 100644 src/main/c/emulator/src/utils.S diff --git a/src/main/c/emulator/build/emulator.asm b/src/main/c/emulator/build/emulator.asm index dffc8975..e1e89d06 100644 --- a/src/main/c/emulator/build/emulator.asm +++ b/src/main/c/emulator/build/emulator.asm @@ -12,19 +12,19 @@ Disassembly of section .init: #endif*/ la sp, _sp 80000000: 00001117 auipc sp,0x1 -80000004: dd810113 addi sp,sp,-552 # 80000dd8 <_sp> +80000004: f3810113 addi sp,sp,-200 # 80000f38 <_sp> /* Load data section */ la a0, _data_lma 80000008: 00000517 auipc a0,0x0 -8000000c: 55c50513 addi a0,a0,1372 # 80000564 <__init_array_end> +8000000c: 6b850513 addi a0,a0,1720 # 800006c0 <__init_array_end> la a1, _data 80000010: 00000597 auipc a1,0x0 -80000014: 55458593 addi a1,a1,1364 # 80000564 <__init_array_end> +80000014: 6b058593 addi a1,a1,1712 # 800006c0 <__init_array_end> la a2, _edata 80000018: 00000617 auipc a2,0x0 -8000001c: 5c060613 addi a2,a2,1472 # 800005d8 <__bss_start> +8000001c: 72060613 addi a2,a2,1824 # 80000738 <__bss_start> bgeu a1, a2, 2f 80000020: 00c5fc63 bleu a2,a1,80000038 <_start+0x38> 1: @@ -43,10 +43,10 @@ Disassembly of section .init: /* Clear bss section */ la a0, __bss_start 80000038: 00000517 auipc a0,0x0 -8000003c: 5a050513 addi a0,a0,1440 # 800005d8 <__bss_start> +8000003c: 70050513 addi a0,a0,1792 # 80000738 <__bss_start> la a1, _end 80000040: 00000597 auipc a1,0x0 -80000044: 59858593 addi a1,a1,1432 # 800005d8 <__bss_start> +80000044: 6f858593 addi a1,a1,1784 # 80000738 <__bss_start> bgeu a0, a1, 2f 80000048: 00b57863 bleu a1,a0,80000058 <_start+0x58> 1: @@ -59,16 +59,16 @@ Disassembly of section .init: 2: call __libc_init_array -80000058: 474000ef jal ra,800004cc <__libc_init_array> +80000058: 5d0000ef jal ra,80000628 <__libc_init_array> call init 8000005c: 128000ef jal ra,80000184 la ra, done 80000060: 00000097 auipc ra,0x0 80000064: 01408093 addi ra,ra,20 # 80000074 - li a0, DTB -80000068: 81000537 lui a0,0x81000 - li a1, 0 -8000006c: 00000593 li a1,0 + li a0, 0 +80000068: 00000513 li a0,0 + li a1, DTB +8000006c: 810005b7 lui a1,0x81000 mret 80000070: 30200073 mret @@ -156,7 +156,7 @@ trapEntry: sw x31, 31*4(sp) 800000f8: 07f12e23 sw t6,124(sp) call trap -800000fc: 1e8000ef jal ra,800002e4 +800000fc: 1ec000ef jal ra,800002e8 lw x0, 0*4(sp) 80000100: 00012003 lw zero,0(sp) lw x1, 1*4(sp) @@ -231,79 +231,70 @@ extern void trapEntry(); extern void emulationTrap(); void init() { - unsigned int sp = (unsigned int) (&_sp); + uint32_t sp = (uint32_t) (&_sp); csr_write(mtvec, trapEntry); 80000184: 800007b7 lui a5,0x80000 -80000188: 07c78793 addi a5,a5,124 # 8000007c <_sp+0xfffff2a4> +80000188: 07c78793 addi a5,a5,124 # 8000007c <_sp+0xfffff144> 8000018c: 30579073 csrw mtvec,a5 csr_write(mscratch, sp -32*4); 80000190: 800017b7 lui a5,0x80001 -80000194: dd878793 addi a5,a5,-552 # 80000dd8 <_sp+0x0> +80000194: f3878793 addi a5,a5,-200 # 80000f38 <_sp+0x0> 80000198: f8078793 addi a5,a5,-128 8000019c: 34079073 csrw mscratch,a5 - csr_write(mstatus, 0x0800); + csr_write(mstatus, 0x0800 | MSTATUS_MPIE); 800001a0: 000017b7 lui a5,0x1 -800001a4: 80078793 addi a5,a5,-2048 # 800 <__stack_size> +800001a4: 88078793 addi a5,a5,-1920 # 880 <__stack_size+0x80> 800001a8: 30079073 csrw mstatus,a5 + csr_write(mie, 0); +800001ac: 30405073 csrwi mie,0 csr_write(mepc, OS_CALL); -800001ac: c00007b7 lui a5,0xc0000 -800001b0: 34179073 csrw mepc,a5 - csr_write(medeleg, MDELEG_INSTRUCTION_PAGE_FAULT | MDELEG_LOAD_PAGE_FAULT | MDELEG_STORE_PAGE_FAULT); -800001b4: 0000b7b7 lui a5,0xb -800001b8: 30279073 csrw medeleg,a5 +800001b0: c00007b7 lui a5,0xc0000 +800001b4: 34179073 csrw mepc,a5 + csr_write(medeleg, MEDELEG_INSTRUCTION_PAGE_FAULT | MEDELEG_LOAD_PAGE_FAULT | MEDELEG_STORE_PAGE_FAULT); +800001b8: 0000b7b7 lui a5,0xb +800001bc: 30279073 csrw medeleg,a5 + csr_write(mideleg, MIDELEG_SUPERVISOR_TIMER); +800001c0: 02000793 li a5,32 +800001c4: 30379073 csrw mideleg,a5 + csr_write(sbadaddr, 0); //Used to avoid simulation missmatch +800001c8: 14305073 csrwi sbadaddr,0 } -800001bc: 00008067 ret +800001cc: 00008067 ret -800001c0 : +800001d0 : -int readRegister(int id){ +int readRegister(uint32_t id){ unsigned int sp = (unsigned int) (&_sp); return ((int*) sp)[id-32]; -800001c0: 00251513 slli a0,a0,0x2 -800001c4: 800017b7 lui a5,0x80001 -800001c8: dd878793 addi a5,a5,-552 # 80000dd8 <_sp+0x0> -800001cc: 00f50533 add a0,a0,a5 +800001d0: 00251513 slli a0,a0,0x2 +800001d4: 800017b7 lui a5,0x80001 +800001d8: f3878793 addi a5,a5,-200 # 80000f38 <_sp+0x0> +800001dc: 00f50533 add a0,a0,a5 } -800001d0: f8052503 lw a0,-128(a0) # 80ffff80 <_sp+0xfff1a8> -800001d4: 00008067 ret +800001e0: f8052503 lw a0,-128(a0) +800001e4: 00008067 ret -800001d8 : -void writeRegister(int id, int value){ - unsigned int sp = (unsigned int) (&_sp); - ((int*) sp)[id-32] = value; -800001d8: 00251513 slli a0,a0,0x2 -800001dc: 800017b7 lui a5,0x80001 -800001e0: dd878793 addi a5,a5,-552 # 80000dd8 <_sp+0x0> -800001e4: 00f50533 add a0,a0,a5 -800001e8: f8b52023 sw a1,-128(a0) -} -800001ec: 00008067 ret - -800001f0 : - - -void stopSim(){ - *((volatile int*) SIM_STOP) = 0; -800001f0: fe002e23 sw zero,-4(zero) # fffffffc <_sp+0x7ffff224> -} -800001f4: 00008067 ret - -800001f8 : - -void putC(char c){ - *((volatile int*) PUTC) = c; -800001f8: fea02c23 sw a0,-8(zero) # fffffff8 <_sp+0x7ffff220> +800001e8 : +void writeRegister(uint32_t id, int value){ + uint32_t sp = (uint32_t) (&_sp); + ((uint32_t*) sp)[id-32] = value; +800001e8: 00251513 slli a0,a0,0x2 +800001ec: 800017b7 lui a5,0x80001 +800001f0: f3878793 addi a5,a5,-200 # 80000f38 <_sp+0x0> +800001f4: 00f50533 add a0,a0,a5 +800001f8: f8b52023 sw a1,-128(a0) } 800001fc: 00008067 ret 80000200 : + void redirectTrap(){ 80000200: ff010113 addi sp,sp,-16 80000204: 00112623 sw ra,12(sp) stopSim(); -80000208: fe9ff0ef jal ra,800001f0 +80000208: 3e8000ef jal ra,800005f0 csr_write(sbadaddr, csr_read(mbadaddr)); 8000020c: 343027f3 csrr a5,mbadaddr 80000210: 14379073 csrw sbadaddr,a5 @@ -346,286 +337,436 @@ void emulationTrapToSupervisorTrap(uint32_t sepc, uint32_t mstatus){ 80000268: 000027b7 lui a5,0x2 8000026c: 80078793 addi a5,a5,-2048 # 1800 <__stack_size+0x1000> 80000270: 3007b073 csrc mstatus,a5 - csr_set(mstatus, 0x8000); + csr_set(mstatus, 0x8000 | MSTATUS_MPIE); 80000274: 000087b7 lui a5,0x8 -80000278: 3007a073 csrs mstatus,a5 +80000278: 08078793 addi a5,a5,128 # 8080 <__stack_size+0x7880> +8000027c: 3007a073 csrs mstatus,a5 } -8000027c: 00008067 ret +80000280: 00008067 ret -80000280 : +80000284 : //Will modify MEPC -int readWord(int address, int *data){ - int result, tmp; - int failed; +int32_t readWord(uint32_t address, int32_t *data){ + int32_t result, tmp; + int32_t failed; __asm__ __volatile__ ( -80000280: 00020737 lui a4,0x20 -80000284: 30072073 csrs mstatus,a4 -80000288: 00000717 auipc a4,0x0 -8000028c: 01870713 addi a4,a4,24 # 800002a0 -80000290: 34171073 csrw mepc,a4 -80000294: 00100693 li a3,1 -80000298: 00052783 lw a5,0(a0) -8000029c: 00000693 li a3,0 -800002a0: 00020737 lui a4,0x20 -800002a4: 30073073 csrc mstatus,a4 -800002a8: 00068513 mv a0,a3 +80000284: 00020737 lui a4,0x20 +80000288: 30072073 csrs mstatus,a4 +8000028c: 00000717 auipc a4,0x0 +80000290: 01870713 addi a4,a4,24 # 800002a4 +80000294: 34171073 csrw mepc,a4 +80000298: 00100693 li a3,1 +8000029c: 00052783 lw a5,0(a0) +800002a0: 00000693 li a3,0 +800002a4: 00020737 lui a4,0x20 +800002a8: 30073073 csrc mstatus,a4 +800002ac: 00068513 mv a0,a3 : [result]"=&r" (result), [failed]"=&r" (failed), [tmp]"=&r" (tmp) : [address]"r" (address) : "memory" ); *data = result; -800002ac: 00f5a023 sw a5,0(a1) +800002b0: 00f5a023 sw a5,0(a1) # 81000000 <_sp+0xfff0c8> return failed; } -800002b0: 00008067 ret +800002b4: 00008067 ret -800002b4 : +800002b8 : //Will modify MEPC -int writeWord(uint32_t address, uint32_t data){ - int result, tmp; - int failed; +int32_t writeWord(uint32_t address, int32_t data){ + int32_t result, tmp; + int32_t failed; __asm__ __volatile__ ( -800002b4: 00020737 lui a4,0x20 -800002b8: 30072073 csrs mstatus,a4 -800002bc: 00000717 auipc a4,0x0 -800002c0: 01870713 addi a4,a4,24 # 800002d4 -800002c4: 34171073 csrw mepc,a4 -800002c8: 00100793 li a5,1 -800002cc: 00b52023 sw a1,0(a0) -800002d0: 00000793 li a5,0 -800002d4: 00020737 lui a4,0x20 -800002d8: 30073073 csrc mstatus,a4 -800002dc: 00078513 mv a0,a5 +800002b8: 00020737 lui a4,0x20 +800002bc: 30072073 csrs mstatus,a4 +800002c0: 00000717 auipc a4,0x0 +800002c4: 01870713 addi a4,a4,24 # 800002d8 +800002c8: 34171073 csrw mepc,a4 +800002cc: 00100793 li a5,1 +800002d0: 00b52023 sw a1,0(a0) +800002d4: 00000793 li a5,0 +800002d8: 00020737 lui a4,0x20 +800002dc: 30073073 csrc mstatus,a4 +800002e0: 00078513 mv a0,a5 : [address]"r" (address), [data]"r" (data) : "memory" ); return failed; } -800002e0: 00008067 ret - -800002e4 : +800002e4: 00008067 ret +800002e8 : void trap(){ -800002e4: fd010113 addi sp,sp,-48 -800002e8: 02112623 sw ra,44(sp) -800002ec: 02812423 sw s0,40(sp) -800002f0: 02912223 sw s1,36(sp) -800002f4: 03212023 sw s2,32(sp) -800002f8: 01312e23 sw s3,28(sp) -800002fc: 01412c23 sw s4,24(sp) -80000300: 01512a23 sw s5,20(sp) - int cause = csr_read(mcause); -80000304: 342027f3 csrr a5,mcause - if(cause < 0){ -80000308: 0207ce63 bltz a5,80000344 - redirectTrap(); - } else { +800002e8: fd010113 addi sp,sp,-48 +800002ec: 02112623 sw ra,44(sp) +800002f0: 02812423 sw s0,40(sp) +800002f4: 02912223 sw s1,36(sp) +800002f8: 03212023 sw s2,32(sp) +800002fc: 01312e23 sw s3,28(sp) +80000300: 01412c23 sw s4,24(sp) +80000304: 01512a23 sw s5,20(sp) + int32_t cause = csr_read(mcause); +80000308: 342027f3 csrr a5,mcause + if(cause < 0){ //interrupt +8000030c: 0007ce63 bltz a5,80000328 + csr_clear(mie, MIE_MTIE); + }break; + default: redirectTrap(); break; + } + } else { //exception switch(cause){ -8000030c: 00200713 li a4,2 -80000310: 02e78e63 beq a5,a4,8000034c -80000314: 00900713 li a4,9 -80000318: 16e78e63 beq a5,a4,80000494 +80000310: 00200713 li a4,2 +80000314: 04e78e63 beq a5,a4,80000370 +80000318: 00900713 li a4,9 +8000031c: 24e78e63 beq a5,a4,80000578 csr_write(mepc, csr_read(mepc) + 4); }break; default: stopSim(); break; } }break; default: redirectTrap(); break; -8000031c: ee5ff0ef jal ra,80000200 +80000320: ee1ff0ef jal ra,80000200 +80000324: 0200006f j 80000344 + switch(cause & 0xFF){ +80000328: 0ff7f793 andi a5,a5,255 +8000032c: 00700713 li a4,7 +80000330: 02e79c63 bne a5,a4,80000368 + csr_set(sip, MIP_STIP); +80000334: 02000793 li a5,32 +80000338: 1447a073 csrs sip,a5 + csr_clear(mie, MIE_MTIE); +8000033c: 08000793 li a5,128 +80000340: 3047b073 csrc mie,a5 } } } -80000320: 02c12083 lw ra,44(sp) -80000324: 02812403 lw s0,40(sp) -80000328: 02412483 lw s1,36(sp) -8000032c: 02012903 lw s2,32(sp) -80000330: 01c12983 lw s3,28(sp) -80000334: 01812a03 lw s4,24(sp) -80000338: 01412a83 lw s5,20(sp) -8000033c: 03010113 addi sp,sp,48 -80000340: 00008067 ret - redirectTrap(); -80000344: ebdff0ef jal ra,80000200 -80000348: fd9ff06f j 80000320 - int mepc = csr_read(mepc); -8000034c: 341024f3 csrr s1,mepc - int mstatus = csr_read(mstatus); -80000350: 300029f3 csrr s3,mstatus - int instruction = csr_read(mbadaddr); -80000354: 34302473 csrr s0,mbadaddr - int opcode = instruction & 0x7F; -80000358: 07f47693 andi a3,s0,127 - int funct3 = (instruction >> 12) & 0x7; -8000035c: 40c45793 srai a5,s0,0xc -80000360: 0077f793 andi a5,a5,7 +80000344: 02c12083 lw ra,44(sp) +80000348: 02812403 lw s0,40(sp) +8000034c: 02412483 lw s1,36(sp) +80000350: 02012903 lw s2,32(sp) +80000354: 01c12983 lw s3,28(sp) +80000358: 01812a03 lw s4,24(sp) +8000035c: 01412a83 lw s5,20(sp) +80000360: 03010113 addi sp,sp,48 +80000364: 00008067 ret + default: redirectTrap(); break; +80000368: e99ff0ef jal ra,80000200 +8000036c: fd9ff06f j 80000344 + uint32_t mepc = csr_read(mepc); +80000370: 341024f3 csrr s1,mepc + uint32_t mstatus = csr_read(mstatus); +80000374: 30002a73 csrr s4,mstatus + uint32_t instruction = csr_read(mbadaddr); +80000378: 34302473 csrr s0,mbadaddr + uint32_t opcode = instruction & 0x7F; +8000037c: 07f47713 andi a4,s0,127 + uint32_t funct3 = (instruction >> 12) & 0x7; +80000380: 00c45793 srli a5,s0,0xc +80000384: 0077f613 andi a2,a5,7 switch(opcode){ -80000364: 02f00713 li a4,47 -80000368: fae69ce3 bne a3,a4,80000320 +80000388: 02f00693 li a3,47 +8000038c: 00d70a63 beq a4,a3,800003a0 +80000390: 07300693 li a3,115 +80000394: 12d70a63 beq a4,a3,800004c8 + default: redirectTrap(); break; +80000398: e69ff0ef jal ra,80000200 +8000039c: fa9ff06f j 80000344 switch(funct3){ -8000036c: 00200713 li a4,2 -80000370: 10e79e63 bne a5,a4,8000048c - int sel = instruction >> 27; -80000374: 41b45913 srai s2,s0,0x1b - int addr = readRegister((instruction >> 15) & 0x1F); -80000378: 40f45513 srai a0,s0,0xf -8000037c: 01f57513 andi a0,a0,31 -80000380: e41ff0ef jal ra,800001c0 -80000384: 00050a93 mv s5,a0 - int src = readRegister((instruction >> 20) & 0x1F); -80000388: 41445513 srai a0,s0,0x14 -8000038c: 01f57513 andi a0,a0,31 -80000390: e31ff0ef jal ra,800001c0 -80000394: 00050a13 mv s4,a0 - int rd = (instruction >> 7) & 0x1F; -80000398: 40745413 srai s0,s0,0x7 -8000039c: 01f47413 andi s0,s0,31 +800003a0: 00200793 li a5,2 +800003a4: 10f61e63 bne a2,a5,800004c0 + uint32_t sel = instruction >> 27; +800003a8: 01b45913 srli s2,s0,0x1b + uint32_t addr = readRegister((instruction >> 15) & 0x1F); +800003ac: 00f45513 srli a0,s0,0xf +800003b0: 01f57513 andi a0,a0,31 +800003b4: e1dff0ef jal ra,800001d0 +800003b8: 00050a93 mv s5,a0 + int32_t src = readRegister((instruction >> 20) & 0x1F); +800003bc: 01445513 srli a0,s0,0x14 +800003c0: 01f57513 andi a0,a0,31 +800003c4: e0dff0ef jal ra,800001d0 +800003c8: 00050993 mv s3,a0 + uint32_t rd = (instruction >> 7) & 0x1F; +800003cc: 00745413 srli s0,s0,0x7 +800003d0: 01f47413 andi s0,s0,31 if(readWord(addr, &readValue)){ -800003a0: 00c10593 addi a1,sp,12 -800003a4: 000a8513 mv a0,s5 -800003a8: ed9ff0ef jal ra,80000280 -800003ac: 02051263 bnez a0,800003d0 +800003d4: 00c10593 addi a1,sp,12 +800003d8: 000a8513 mv a0,s5 +800003dc: ea9ff0ef jal ra,80000284 +800003e0: 02051263 bnez a0,80000404 switch(sel){ -800003b0: 01c00793 li a5,28 -800003b4: 0d27e063 bltu a5,s2,80000474 -800003b8: 00291913 slli s2,s2,0x2 -800003bc: 800007b7 lui a5,0x80000 -800003c0: 56478793 addi a5,a5,1380 # 80000564 <_sp+0xfffff78c> -800003c4: 00f90933 add s2,s2,a5 -800003c8: 00092783 lw a5,0(s2) -800003cc: 00078067 jr a5 +800003e4: 01c00793 li a5,28 +800003e8: 0d27e063 bltu a5,s2,800004a8 +800003ec: 00291913 slli s2,s2,0x2 +800003f0: 800007b7 lui a5,0x80000 +800003f4: 6c078793 addi a5,a5,1728 # 800006c0 <_sp+0xfffff788> +800003f8: 00f90933 add s2,s2,a5 +800003fc: 00092783 lw a5,0(s2) +80000400: 00078067 jr a5 emulationTrapToSupervisorTrap(mepc, mstatus); -800003d0: 00098593 mv a1,s3 -800003d4: 00048513 mv a0,s1 -800003d8: e61ff0ef jal ra,80000238 +80000404: 000a0593 mv a1,s4 +80000408: 00048513 mv a0,s1 +8000040c: e2dff0ef jal ra,80000238 return; -800003dc: f45ff06f j 80000320 +80000410: f35ff06f j 80000344 case 0x0: writeValue = src + readValue; break; -800003e0: 00c12783 lw a5,12(sp) -800003e4: 00fa0a33 add s4,s4,a5 +80000414: 00c12783 lw a5,12(sp) +80000418: 00f989b3 add s3,s3,a5 writeRegister(rd, readValue); -800003e8: 00c12583 lw a1,12(sp) -800003ec: 00040513 mv a0,s0 -800003f0: de9ff0ef jal ra,800001d8 +8000041c: 00c12583 lw a1,12(sp) +80000420: 00040513 mv a0,s0 +80000424: dc5ff0ef jal ra,800001e8 if(writeWord(addr, writeValue)){ -800003f4: 000a0593 mv a1,s4 -800003f8: 000a8513 mv a0,s5 -800003fc: eb9ff0ef jal ra,800002b4 -80000400: 06051e63 bnez a0,8000047c +80000428: 00098593 mv a1,s3 +8000042c: 000a8513 mv a0,s5 +80000430: e89ff0ef jal ra,800002b8 +80000434: 06051e63 bnez a0,800004b0 csr_write(mepc, mepc + 4); -80000404: 00448493 addi s1,s1,4 -80000408: 34149073 csrw mepc,s1 +80000438: 00448493 addi s1,s1,4 +8000043c: 34149073 csrw mepc,s1 }break; -8000040c: f15ff06f j 80000320 +80000440: f05ff06f j 80000344 case 0x4: writeValue = src ^ readValue; break; -80000410: 00c12783 lw a5,12(sp) -80000414: 00fa4a33 xor s4,s4,a5 -80000418: fd1ff06f j 800003e8 - case 0xC: writeValue = src & readValue; break; -8000041c: 00c12783 lw a5,12(sp) -80000420: 00fa7a33 and s4,s4,a5 -80000424: fc5ff06f j 800003e8 - case 0x8: writeValue = src | readValue; break; -80000428: 00c12783 lw a5,12(sp) -8000042c: 00fa6a33 or s4,s4,a5 -80000430: fb9ff06f j 800003e8 - case 0x10: writeValue = min(src, readValue); break; -80000434: 00c12783 lw a5,12(sp) -80000438: fb47d8e3 ble s4,a5,800003e8 -8000043c: 00078a13 mv s4,a5 -80000440: fa9ff06f j 800003e8 - case 0x14: writeValue = max(src, readValue); break; 80000444: 00c12783 lw a5,12(sp) -80000448: fafa50e3 ble a5,s4,800003e8 -8000044c: 00078a13 mv s4,a5 -80000450: f99ff06f j 800003e8 +80000448: 00f9c9b3 xor s3,s3,a5 +8000044c: fd1ff06f j 8000041c + case 0xC: writeValue = src & readValue; break; +80000450: 00c12783 lw a5,12(sp) +80000454: 00f9f9b3 and s3,s3,a5 +80000458: fc5ff06f j 8000041c + case 0x8: writeValue = src | readValue; break; +8000045c: 00c12783 lw a5,12(sp) +80000460: 00f9e9b3 or s3,s3,a5 +80000464: fb9ff06f j 8000041c + case 0x10: writeValue = min(src, readValue); break; +80000468: 00c12783 lw a5,12(sp) +8000046c: fb37d8e3 ble s3,a5,8000041c +80000470: 00078993 mv s3,a5 +80000474: fa9ff06f j 8000041c + case 0x14: writeValue = max(src, readValue); break; +80000478: 00c12783 lw a5,12(sp) +8000047c: faf9d0e3 ble a5,s3,8000041c +80000480: 00078993 mv s3,a5 +80000484: f99ff06f j 8000041c case 0x18: writeValue = min((unsigned int)src, (unsigned int)readValue); break; -80000454: 00c12783 lw a5,12(sp) -80000458: f947f8e3 bleu s4,a5,800003e8 -8000045c: 00078a13 mv s4,a5 -80000460: f89ff06f j 800003e8 +80000488: 00c12783 lw a5,12(sp) +8000048c: f937f8e3 bleu s3,a5,8000041c +80000490: 00078993 mv s3,a5 +80000494: f89ff06f j 8000041c case 0x1C: writeValue = max((unsigned int)src, (unsigned int)readValue); break; -80000464: 00c12783 lw a5,12(sp) -80000468: f8fa70e3 bleu a5,s4,800003e8 -8000046c: 00078a13 mv s4,a5 -80000470: f79ff06f j 800003e8 +80000498: 00c12783 lw a5,12(sp) +8000049c: f8f9f0e3 bleu a5,s3,8000041c +800004a0: 00078993 mv s3,a5 +800004a4: f79ff06f j 8000041c default: redirectTrap(); return; break; -80000474: d8dff0ef jal ra,80000200 -80000478: ea9ff06f j 80000320 +800004a8: d59ff0ef jal ra,80000200 +800004ac: e99ff06f j 80000344 emulationTrapToSupervisorTrap(mepc, mstatus); -8000047c: 00098593 mv a1,s3 -80000480: 00048513 mv a0,s1 -80000484: db5ff0ef jal ra,80000238 +800004b0: 000a0593 mv a1,s4 +800004b4: 00048513 mv a0,s1 +800004b8: d81ff0ef jal ra,80000238 return; -80000488: e99ff06f j 80000320 +800004bc: e89ff06f j 80000344 default: redirectTrap(); break; -8000048c: d75ff0ef jal ra,80000200 -80000490: e91ff06f j 80000320 - int which = readRegister(17); -80000494: 01100513 li a0,17 -80000498: d29ff0ef jal ra,800001c0 +800004c0: d41ff0ef jal ra,80000200 +800004c4: e81ff06f j 80000344 + switch (funct3 & 0x3) { +800004c8: 0037f793 andi a5,a5,3 +800004cc: 00100713 li a4,1 +800004d0: 06e78263 beq a5,a4,80000534 +800004d4: 02078c63 beqz a5,8000050c +800004d8: 00200713 li a4,2 +800004dc: 02e78c63 beq a5,a4,80000514 +800004e0: 00300713 li a4,3 +800004e4: 04e78063 beq a5,a4,80000524 + uint32_t csrAddress = instruction >> 20; +800004e8: 01445713 srli a4,s0,0x14 + switch(csrAddress){ +800004ec: 000017b7 lui a5,0x1 +800004f0: c0178793 addi a5,a5,-1023 # c01 <__stack_size+0x401> +800004f4: 04f70463 beq a4,a5,8000053c +800004f8: 000017b7 lui a5,0x1 +800004fc: c8178793 addi a5,a5,-895 # c81 <__stack_size+0x481> +80000500: 06f70263 beq a4,a5,80000564 + default: redirectTrap(); break; +80000504: cfdff0ef jal ra,80000200 +80000508: 03c0006f j 80000544 + case 0: redirectTrap(); break; +8000050c: cf5ff0ef jal ra,80000200 +80000510: fd9ff06f j 800004e8 + case 2: clear = 0; set = input; write = ((instruction >> 15) & 0x1F) != 0; break; +80000514: 00f45993 srli s3,s0,0xf +80000518: 01f9f993 andi s3,s3,31 +8000051c: 013039b3 snez s3,s3 +80000520: fc9ff06f j 800004e8 + case 3: clear = input; set = 0; write = ((instruction >> 15) & 0x1F) != 0; break; +80000524: 00f45993 srli s3,s0,0xf +80000528: 01f9f993 andi s3,s3,31 +8000052c: 013039b3 snez s3,s3 +80000530: fb9ff06f j 800004e8 + case 1: clear = ~0; set = input; write = 1; break; +80000534: 00100993 li s3,1 +80000538: fb1ff06f j 800004e8 + case RDTIME : old = rdtime(); break; +8000053c: 0c4000ef jal ra,80000600 +80000540: 00050913 mv s2,a0 + if(write) { +80000544: 02099663 bnez s3,80000570 + writeRegister((instruction >> 7) & 0x1F, old); +80000548: 00745513 srli a0,s0,0x7 +8000054c: 00090593 mv a1,s2 +80000550: 01f57513 andi a0,a0,31 +80000554: c95ff0ef jal ra,800001e8 + csr_write(mepc, mepc + 4); +80000558: 00448493 addi s1,s1,4 +8000055c: 34149073 csrw mepc,s1 + }break; +80000560: de5ff06f j 80000344 + case RDTIMEH : old = rdtimeh(); break; +80000564: 0a4000ef jal ra,80000608 +80000568: 00050913 mv s2,a0 +8000056c: fd9ff06f j 80000544 + default: redirectTrap(); break; +80000570: c91ff0ef jal ra,80000200 +80000574: fd5ff06f j 80000548 + uint32_t which = readRegister(17); +80000578: 01100513 li a0,17 +8000057c: c55ff0ef jal ra,800001d0 +80000580: 00050413 mv s0,a0 + uint32_t a0 = readRegister(10); +80000584: 00a00513 li a0,10 +80000588: c49ff0ef jal ra,800001d0 +8000058c: 00050493 mv s1,a0 + uint32_t a1 = readRegister(11); +80000590: 00b00513 li a0,11 +80000594: c3dff0ef jal ra,800001d0 switch(which){ -8000049c: 00100793 li a5,1 -800004a0: 02f51263 bne a0,a5,800004c4 - putC(readRegister(10)); -800004a4: 00a00513 li a0,10 -800004a8: d19ff0ef jal ra,800001c0 -800004ac: 0ff57513 andi a0,a0,255 -800004b0: d49ff0ef jal ra,800001f8 +80000598: 02040263 beqz s0,800005bc +8000059c: 00100793 li a5,1 +800005a0: 04f41463 bne s0,a5,800005e8 + putC(a0); +800005a4: 0ff4f513 andi a0,s1,255 +800005a8: 050000ef jal ra,800005f8 csr_write(mepc, csr_read(mepc) + 4); -800004b4: 341027f3 csrr a5,mepc -800004b8: 00478793 addi a5,a5,4 -800004bc: 34179073 csrw mepc,a5 +800005ac: 341027f3 csrr a5,mepc +800005b0: 00478793 addi a5,a5,4 +800005b4: 34179073 csrw mepc,a5 }break; -800004c0: e61ff06f j 80000320 +800005b8: d8dff06f j 80000344 + setMachineTimerCmp(a0, a1); +800005bc: 00050593 mv a1,a0 +800005c0: 00048513 mv a0,s1 +800005c4: 04c000ef jal ra,80000610 + csr_set(mie, MIE_MTIE); +800005c8: 08000793 li a5,128 +800005cc: 3047a073 csrs mie,a5 + csr_clear(sip, MIP_STIP); +800005d0: 02000793 li a5,32 +800005d4: 1447b073 csrc sip,a5 + csr_write(mepc, csr_read(mepc) + 4); +800005d8: 341027f3 csrr a5,mepc +800005dc: 00478793 addi a5,a5,4 +800005e0: 34179073 csrw mepc,a5 + }break; +800005e4: d61ff06f j 80000344 default: stopSim(); break; -800004c4: d2dff0ef jal ra,800001f0 -800004c8: e59ff06f j 80000320 +800005e8: 008000ef jal ra,800005f0 +800005ec: d59ff06f j 80000344 -800004cc <__libc_init_array>: -800004cc: ff010113 addi sp,sp,-16 -800004d0: 00812423 sw s0,8(sp) -800004d4: 00912223 sw s1,4(sp) -800004d8: 00000417 auipc s0,0x0 -800004dc: 08c40413 addi s0,s0,140 # 80000564 <__init_array_end> -800004e0: 00000497 auipc s1,0x0 -800004e4: 08448493 addi s1,s1,132 # 80000564 <__init_array_end> -800004e8: 408484b3 sub s1,s1,s0 -800004ec: 01212023 sw s2,0(sp) -800004f0: 00112623 sw ra,12(sp) -800004f4: 4024d493 srai s1,s1,0x2 -800004f8: 00000913 li s2,0 -800004fc: 04991063 bne s2,s1,8000053c <__libc_init_array+0x70> -80000500: 00000417 auipc s0,0x0 -80000504: 06440413 addi s0,s0,100 # 80000564 <__init_array_end> -80000508: 00000497 auipc s1,0x0 -8000050c: 05c48493 addi s1,s1,92 # 80000564 <__init_array_end> -80000510: 408484b3 sub s1,s1,s0 -80000514: b65ff0ef jal ra,80000078 <_init> -80000518: 4024d493 srai s1,s1,0x2 -8000051c: 00000913 li s2,0 -80000520: 02991863 bne s2,s1,80000550 <__libc_init_array+0x84> -80000524: 00c12083 lw ra,12(sp) -80000528: 00812403 lw s0,8(sp) -8000052c: 00412483 lw s1,4(sp) -80000530: 00012903 lw s2,0(sp) -80000534: 01010113 addi sp,sp,16 -80000538: 00008067 ret -8000053c: 00042783 lw a5,0(s0) -80000540: 00190913 addi s2,s2,1 -80000544: 00440413 addi s0,s0,4 -80000548: 000780e7 jalr a5 -8000054c: fb1ff06f j 800004fc <__libc_init_array+0x30> -80000550: 00042783 lw a5,0(s0) -80000554: 00190913 addi s2,s2,1 -80000558: 00440413 addi s0,s0,4 -8000055c: 000780e7 jalr a5 -80000560: fc1ff06f j 80000520 <__libc_init_array+0x54> +800005f0 : +#include "hal.h" + +void stopSim(){ + *((volatile uint32_t*) 0xFFFFFFFC) = 0; +800005f0: fe002e23 sw zero,-4(zero) # fffffffc <_sp+0x7ffff0c4> +} +800005f4: 00008067 ret + +800005f8 : + +void putC(char c){ + *((volatile uint32_t*) 0xFFFFFFF8) = c; +800005f8: fea02c23 sw a0,-8(zero) # fffffff8 <_sp+0x7ffff0c0> +} +800005fc: 00008067 ret + +80000600 : + +uint32_t rdtime(){ + return *((volatile uint32_t*) 0xFFFFFFE0); +80000600: fe002503 lw a0,-32(zero) # ffffffe0 <_sp+0x7ffff0a8> +} +80000604: 00008067 ret + +80000608 : + +uint32_t rdtimeh(){ + return *((volatile uint32_t*) 0xFFFFFFE4); +80000608: fe402503 lw a0,-28(zero) # ffffffe4 <_sp+0x7ffff0ac> +} +8000060c: 00008067 ret + +80000610 : + + +void setMachineTimerCmp(uint32_t low, uint32_t high){ + volatile uint32_t* base = (volatile uint32_t*) 0xFFFFFFE8; + base[1] = 0xffffffff; +80000610: fec00793 li a5,-20 +80000614: fff00713 li a4,-1 +80000618: 00e7a023 sw a4,0(a5) + base[0] = low; +8000061c: fea02423 sw a0,-24(zero) # ffffffe8 <_sp+0x7ffff0b0> + base[1] = high; +80000620: 00b7a023 sw a1,0(a5) +} +80000624: 00008067 ret + +80000628 <__libc_init_array>: +80000628: ff010113 addi sp,sp,-16 +8000062c: 00812423 sw s0,8(sp) +80000630: 00912223 sw s1,4(sp) +80000634: 00000417 auipc s0,0x0 +80000638: 08c40413 addi s0,s0,140 # 800006c0 <__init_array_end> +8000063c: 00000497 auipc s1,0x0 +80000640: 08448493 addi s1,s1,132 # 800006c0 <__init_array_end> +80000644: 408484b3 sub s1,s1,s0 +80000648: 01212023 sw s2,0(sp) +8000064c: 00112623 sw ra,12(sp) +80000650: 4024d493 srai s1,s1,0x2 +80000654: 00000913 li s2,0 +80000658: 04991063 bne s2,s1,80000698 <__libc_init_array+0x70> +8000065c: 00000417 auipc s0,0x0 +80000660: 06440413 addi s0,s0,100 # 800006c0 <__init_array_end> +80000664: 00000497 auipc s1,0x0 +80000668: 05c48493 addi s1,s1,92 # 800006c0 <__init_array_end> +8000066c: 408484b3 sub s1,s1,s0 +80000670: a09ff0ef jal ra,80000078 <_init> +80000674: 4024d493 srai s1,s1,0x2 +80000678: 00000913 li s2,0 +8000067c: 02991863 bne s2,s1,800006ac <__libc_init_array+0x84> +80000680: 00c12083 lw ra,12(sp) +80000684: 00812403 lw s0,8(sp) +80000688: 00412483 lw s1,4(sp) +8000068c: 00012903 lw s2,0(sp) +80000690: 01010113 addi sp,sp,16 +80000694: 00008067 ret +80000698: 00042783 lw a5,0(s0) +8000069c: 00190913 addi s2,s2,1 +800006a0: 00440413 addi s0,s0,4 +800006a4: 000780e7 jalr a5 +800006a8: fb1ff06f j 80000658 <__libc_init_array+0x30> +800006ac: 00042783 lw a5,0(s0) +800006b0: 00190913 addi s2,s2,1 +800006b4: 00440413 addi s0,s0,4 +800006b8: 000780e7 jalr a5 +800006bc: fc1ff06f j 8000067c <__libc_init_array+0x54> diff --git a/src/main/c/emulator/build/emulator.hex b/src/main/c/emulator/build/emulator.hex index 7aba5679..4b5dcb75 100644 --- a/src/main/c/emulator/build/emulator.hex +++ b/src/main/c/emulator/build/emulator.hex @@ -1,11 +1,11 @@ :0200000480007A -:1000000017110000130181DD170500001305C55508 -:100010009705000093854555170600001306065CFA +:1000000017110000130181F3170500001305856B1C +:10001000970500009385056B17060000130606720E :1000200063FCC5008322050023A05500130545008D -:1000300093854500E3E8C5FE170500001305055A42 -:1000400097050000938585596378B5002320050046 -:1000500013054500E36CB5FEEF004047EF0080124A -:100060009700000093804001370500819305000050 +:1000300093854500E3E8C5FE17050000130505702C +:10004000970500009385856F6378B5002320050030 +:1000500013054500E36CB5FEEF00005DEF00801274 +:10006000970000009380400113050000B705008150 :10007000730020306F0000006780000073110134AE :1000800023200100232211002326310023284100D0 :10009000232A5100232C6100232E7100232081028A @@ -14,7 +14,7 @@ :1000C0002322110523242105232631052328410558 :1000D000232A5105232C6105232E71052320810736 :1000E000232291072324A1072326B1072328C10730 -:1000F000232AD107232CE107232EF107EF00801ECE +:1000F000232AD107232CE107232EF107EF00C01E8E :1001000003200100832041008321C100032201015B :1001100083224101032381018323C10103240102BE :1001200083244102032581028325C10203260103A2 @@ -25,74 +25,96 @@ :10017000832E4107032F8107832FC1077311013499 :0401800073002030B8 :10018400B70700809387C70773905730B71700806D -:10019400938787DD938707F873900734B7170000B8 -:1001A4009387078073900730B70700C073901734A4 -:1001B400B7B700007390273067800000131525003F -:1001C400B7170080938787DD3305F500032505F80D -:1001D4006780000013152500B7170080938787DD1B -:1001E4003305F5002320B5F867800000232E00FEB8 -:1001F40067800000232CA0FE67800000130101FF2C -:1002040023261100EFF09FFEF32730347390371448 +:10019400938787F3938707F873900734B7170000A2 +:1001A400938707887390073073504030B70700C0B7 +:1001B40073901734B7B70000739027309307000289 +:1001C4007390373073503014678000001315250086 +:1001D400B7170080938787F33305F500032505F8E7 +:1001E4006780000013152500B7170080938787F3F5 +:1001F4003305F5002320B5F867800000130101FFE3 +:1002040023261100EF00803EF32730347390371417 :10021400F327103473901714F327203473902714A2 :10022400F3275010739017348320C1001301010188 :1002340067800000F327303473903714F327203499 :100244007390271473101514F327501073901734F8 :100254009307001073B0071093D5350093F505107C :1002640073A00510B72700009387078073B0073089 -:10027400B787000073A007306780000037070200CB -:100284007320073017070000130787017310173412 -:100294009306100083270500930600003707020029 -:1002A400733007301385060023A0F5006780000033 -:1002B4003707020073200730170700001307870170 -:1002C40073101734930710002320B5009307000020 -:1002D400370702007330073013850700678000007A -:1002E400130101FD232611022324810223229102FA -:1002F40023202103232E3101232C4101232A5101E0 -:10030400F327203463CE070213072000638EE7022D -:1003140013079000638EE716EFF05FEE8320C102AF -:100324000324810283244102032901028329C10198 -:10033400032A8101832A410113010103678000001C -:10034400EFF0DFEB6FF09FFDF3241034F32900305E -:10035400732430349376F4079357C44093F77700AB -:100364001307F002E39CE6FA13072000639EE710EC -:100374001359B4411355F4401375F501EFF01FE41C -:10038400930A0500135544411375F501EFF01FE37B -:10039400130A0500135474401374F4019305C10047 -:1003A40013850A00EFF09FED631205029307C00165 -:1003B40063E0270D13192900B70700809387475678 -:1003C4003309F90083270900678007009385090032 -:1003D40013850400EFF01FE66FF05FF48327C1007C -:1003E400330AFA008325C10013050400EFF09FDEF1 -:1003F40093050A0013850A00EFF09FEB631E0506C0 -:1004040093844400739014346FF05FF18327C10028 -:10041400334AFA006FF01FFD8327C100337AFA00D4 -:100424006FF05FFC8327C100336AFA006FF09FFB13 -:100434008327C100E3D847FB138A07006FF09FFAB4 -:100444008327C100E350FAFA138A07006FF09FF97B -:100454008327C100E3F847F9138A07006FF09FF878 -:100464008327C100E370FAF8138A07006FF09FF73F -:10047400EFF0DFD86FF09FEA93850900138504003D -:10048400EFF05FDB6FF09FE9EFF05FD76FF01FE9EC -:1004940013051001EFF09FD2930710006312F502C9 -:1004A4001305A000EFF09FD11375F50FEFF09FD463 -:1004B400F327103493874700739017346FF01FE6C7 -:1004C400EFF0DFD26FF09FE5130101FF23248100D9 -:1004D40023229100170400001304C40897040000A9 -:1004E40093844408B38484402320210123261100EB -:1004F40093D42440130900006310990417040000E6 -:1005040013044406970400009384C405B384844010 -:10051400EFF05FB693D424401309000063189902E6 -:100524008320C100032481008324410003290100A6 -:1005340013010101678000008327040013091900D7 -:1005440013044400E78007006FF01FFB83270400B7 -:100554001309190013044400E78007006FF01FFC1F -:10056400E0030080E80300807404008074040080C9 -:1005740010040080740400807404008074040080FB -:1005840028040080740400807404008074040080D3 -:100594001C040080740400807404008074040080CF -:1005A40034040080740400807404008074040080A7 -:1005B4004404008074040080740400807404008087 -:1005C4005404008074040080740400807404008067 -:0405D400640400803B +:10027400B78700009387070873A0073067800000E2 +:1002840037070200732007301707000013078701A0 +:10029400731017349306100083270500930600009B +:1002A40037070200733007301385060023A0F500DA +:1002B400678000003707020073200730170700002B +:1002C4001307870173101734930710002320B50018 +:1002D40093070000370702007330073013850700C7 +:1002E40067800000130101FD2326110223248102EB +:1002F4002322910223202103232E3101232C4101A7 +:10030400232A5101F327203463CE0700130720006A +:10031400638EE70413079000638EE724EFF01FEE6B +:100324006F00000293F7F70F13077000639CE70256 +:100334009307000273A047149307000873B0473073 +:100344008320C10203248102832441020329010280 +:100354008329C101032A8101832A41011301010375 +:1003640067800000EFF09FE96FF09FFDF3241034E5 +:10037400732A0030732430341377F4079357C4007E +:1003840013F677009306F002630AD700930630074A +:10039400630AD712EFF09FE66FF09FFA93072000ED +:1003A400631EF6101359B4011355F4001375F501C7 +:1003B400EFF0DFE1930A0500135544011375F501CD +:1003C400EFF0DFE093090500135474001374F40193 +:1003D4009305C10013850A00EFF09FEA631205023A +:1003E4009307C00163E0270D13192900B7070080A4 +:1003F4009387076C3309F900832709006780070096 +:1004040093050A0013850400EFF0DFE26FF05FF359 +:100414008327C100B389F9008325C10013050400B3 +:10042400EFF05FDC9385090013850A00EFF09FE885 +:10043400631E050693844400739014346FF05FF0D8 +:100444008327C100B3C9F9006FF01FFD8327C100E2 +:10045400B3F9F9006FF05FFC8327C100B3E9F90039 +:100464006FF09FFB8327C100E3D837FB9389070014 +:100474006FF09FFA8327C100E3D0F9FA938907004C +:100484006FF09FF98327C100E3F837F993890700D8 +:100494006FF09FF88327C100E3F0F9F89389070010 +:1004A4006FF09FF7EFF09FD56FF09FE993050A0077 +:1004B40013850400EFF01FD86FF09FE8EFF01FD40E +:1004C4006FF01FE893F73700130710006382E70605 +:1004D400638C070213072000638CE70213073000C4 +:1004E4006380E70413574401B7170000938717C0CC +:1004F4006304F704B7170000938717C86302F7066D +:10050400EFF0DFCF6F00C003EFF05FCF6FF09FFD20 +:100514009359F40093F9F901B33930016FF09FFC5A +:100524009359F40093F9F901B33930016FF09FFB4B +:10053400930910006FF01FFBEF00400C1309050036 +:100544006396090213557400930509001375F501A8 +:10055400EFF05FC993844400739014346FF05FDE4E +:10056400EF00400A130905006FF09FFDEFF01FC96B +:100574006FF05FFD13051001EFF05FC51304050074 +:100584001305A000EFF09FC4930405001305B00009 +:10059400EFF0DFC363020402930710006314F40452 +:1005A40013F5F40FEF000005F32710349387470089 +:1005B400739017346FF0DFD893050500138504009A +:1005C400EF00C0049307000873A0473093070002AC +:1005D40073B04714F327103493874700739017348C +:1005E4006FF01FD6EF0080006FF09FD5232E00FE22 +:1005F40067800000232CA0FE67800000032500FE16 +:1006040067800000032540FE678000009307C0FE5A +:100614001307F0FF23A0E7002324A0FE23A0B700C4 +:1006240067800000130101FF23248100232291002D +:10063400170400001304C4089704000093844408BA +:10064400B3848440232021012326110093D4244021 +:1006540013090000631099041704000013044406EE +:10066400970400009384C405B3848440EFF09FA0F2 +:1006740093D4244013090000631899028320C10015 +:100684000324810083244100032901001301010193 +:100694006780000083270400130919001304440031 +:1006A400E78007006FF01FFB83270400130919007C +:0C06B40013044400E78007006FF01FFCF7 +:1006C000140400801C040080A8040080A80400809A +:1006D00044040080A8040080A8040080A8040080CE +:1006E0005C040080A8040080A8040080A8040080A6 +:1006F00050040080A8040080A8040080A8040080A2 +:1007000068040080A8040080A8040080A804008079 +:1007100078040080A8040080A8040080A804008059 +:1007200088040080A8040080A8040080A804008039 +:080730009804008000000000A5 :040000058000000077 :00000001FF diff --git a/src/main/c/emulator/src/config.h b/src/main/c/emulator/src/config.h index e39fa657..3c1f1aa3 100644 --- a/src/main/c/emulator/src/config.h +++ b/src/main/c/emulator/src/config.h @@ -3,8 +3,5 @@ #define OS_CALL 0xC0000000 #define DTB 0x81000000 -#define SIM_STOP 0xFFFFFFFC -#define PUTC 0xFFFFFFF8 - #endif diff --git a/src/main/c/emulator/src/hal.c b/src/main/c/emulator/src/hal.c new file mode 100644 index 00000000..cdb052df --- /dev/null +++ b/src/main/c/emulator/src/hal.c @@ -0,0 +1,25 @@ +#include "hal.h" + +void stopSim(){ + *((volatile uint32_t*) 0xFFFFFFFC) = 0; +} + +void putC(char c){ + *((volatile uint32_t*) 0xFFFFFFF8) = c; +} + +uint32_t rdtime(){ + return *((volatile uint32_t*) 0xFFFFFFE0); +} + +uint32_t rdtimeh(){ + return *((volatile uint32_t*) 0xFFFFFFE4); +} + + +void setMachineTimerCmp(uint32_t low, uint32_t high){ + volatile uint32_t* base = (volatile uint32_t*) 0xFFFFFFE8; + base[1] = 0xffffffff; + base[0] = low; + base[1] = high; +} diff --git a/src/main/c/emulator/src/hal.h b/src/main/c/emulator/src/hal.h new file mode 100644 index 00000000..c5cb70ae --- /dev/null +++ b/src/main/c/emulator/src/hal.h @@ -0,0 +1,23 @@ + +#ifndef HAL_H +#define HAL_H + +#include + +#define SBI_SET_TIMER 0 +#define SBI_CONSOLE_PUTCHAR 1 +#define SBI_CONSOLE_GETCHAR 2 +#define SBI_CLEAR_IPI 3 +#define SBI_SEND_IPI 4 +#define SBI_REMOTE_FENCE_I 5 +#define SBI_REMOTE_SFENCE_VMA 6 +#define SBI_REMOTE_SFENCE_VMA_ASID 7 +#define SBI_SHUTDOWN 8 + +void stopSim(); +void putC(char c); +uint32_t rdtime(); +uint32_t rdtimeh(); +void setMachineTimerCmp(uint32_t low, uint32_t high); + +#endif diff --git a/src/main/c/emulator/src/main.c b/src/main/c/emulator/src/main.c index aa058f71..a2171b83 100755 --- a/src/main/c/emulator/src/main.c +++ b/src/main/c/emulator/src/main.c @@ -1,38 +1,34 @@ #include #include "riscv.h" #include "config.h" +#include "hal.h" -extern const unsigned int _sp; +extern const uint32_t _sp; extern void trapEntry(); extern void emulationTrap(); void init() { - unsigned int sp = (unsigned int) (&_sp); + uint32_t sp = (uint32_t) (&_sp); csr_write(mtvec, trapEntry); csr_write(mscratch, sp -32*4); - csr_write(mstatus, 0x0800); + csr_write(mstatus, 0x0800 | MSTATUS_MPIE); + csr_write(mie, 0); csr_write(mepc, OS_CALL); - csr_write(medeleg, MDELEG_INSTRUCTION_PAGE_FAULT | MDELEG_LOAD_PAGE_FAULT | MDELEG_STORE_PAGE_FAULT); + csr_write(medeleg, MEDELEG_INSTRUCTION_PAGE_FAULT | MEDELEG_LOAD_PAGE_FAULT | MEDELEG_STORE_PAGE_FAULT); + csr_write(mideleg, MIDELEG_SUPERVISOR_TIMER); + csr_write(sbadaddr, 0); //Used to avoid simulation missmatch } -int readRegister(int id){ +int readRegister(uint32_t id){ unsigned int sp = (unsigned int) (&_sp); return ((int*) sp)[id-32]; } -void writeRegister(int id, int value){ - unsigned int sp = (unsigned int) (&_sp); - ((int*) sp)[id-32] = value; +void writeRegister(uint32_t id, int value){ + uint32_t sp = (uint32_t) (&_sp); + ((uint32_t*) sp)[id-32] = value; } -void stopSim(){ - *((volatile int*) SIM_STOP) = 0; -} - -void putC(char c){ - *((volatile int*) PUTC) = c; -} - void redirectTrap(){ stopSim(); @@ -50,7 +46,7 @@ void emulationTrapToSupervisorTrap(uint32_t sepc, uint32_t mstatus){ csr_clear(sstatus, MSTATUS_SPP); csr_set(sstatus, (mstatus >> 3) & MSTATUS_SPP); csr_clear(mstatus, MSTATUS_MPP); - csr_set(mstatus, 0x8000); + csr_set(mstatus, 0x8000 | MSTATUS_MPIE); } #define max(a,b) \ @@ -67,9 +63,9 @@ void emulationTrapToSupervisorTrap(uint32_t sepc, uint32_t mstatus){ //Will modify MEPC -int readWord(int address, int *data){ - int result, tmp; - int failed; +int32_t readWord(uint32_t address, int32_t *data){ + int32_t result, tmp; + int32_t failed; __asm__ __volatile__ ( " li %[tmp], 0x00020000\n" " csrs mstatus, %[tmp]\n" @@ -91,9 +87,9 @@ int readWord(int address, int *data){ } //Will modify MEPC -int writeWord(uint32_t address, uint32_t data){ - int result, tmp; - int failed; +int32_t writeWord(uint32_t address, int32_t data){ + int32_t result, tmp; + int32_t failed; __asm__ __volatile__ ( " li %[tmp], 0x00020000\n" " csrs mstatus, %[tmp]\n" @@ -116,30 +112,33 @@ int writeWord(uint32_t address, uint32_t data){ - - - void trap(){ - int cause = csr_read(mcause); - if(cause < 0){ - redirectTrap(); - } else { + int32_t cause = csr_read(mcause); + if(cause < 0){ //interrupt + switch(cause & 0xFF){ + case CAUSE_MACHINE_TIMER:{ + csr_set(sip, MIP_STIP); + csr_clear(mie, MIE_MTIE); + }break; + default: redirectTrap(); break; + } + } else { //exception switch(cause){ case CAUSE_ILLEGAL_INSTRUCTION:{ - int mepc = csr_read(mepc); - int mstatus = csr_read(mstatus); - int instruction = csr_read(mbadaddr); - int opcode = instruction & 0x7F; - int funct3 = (instruction >> 12) & 0x7; + uint32_t mepc = csr_read(mepc); + uint32_t mstatus = csr_read(mstatus); + uint32_t instruction = csr_read(mbadaddr); + uint32_t opcode = instruction & 0x7F; + uint32_t funct3 = (instruction >> 12) & 0x7; switch(opcode){ case 0x2F: //Atomic switch(funct3){ case 0x2:{ - int sel = instruction >> 27; - int addr = readRegister((instruction >> 15) & 0x1F); - int src = readRegister((instruction >> 20) & 0x1F); - int rd = (instruction >> 7) & 0x1F; - int readValue; + uint32_t sel = instruction >> 27; + uint32_t addr = readRegister((instruction >> 15) & 0x1F); + int32_t src = readRegister((instruction >> 20) & 0x1F); + uint32_t rd = (instruction >> 7) & 0x1F; + int32_t readValue; if(readWord(addr, &readValue)){ emulationTrapToSupervisorTrap(mepc, mstatus); return; @@ -148,6 +147,11 @@ void trap(){ switch(sel){ case 0x0: writeValue = src + readValue; break; case 0x1: writeValue = src; break; +//LR SC done in hardware (cheap), and require to keep track of context switches +// case 0x2:{ //LR +// }break; +// case 0x3:{ //SC +// }break; case 0x4: writeValue = src ^ readValue; break; case 0xC: writeValue = src & readValue; break; case 0x8: writeValue = src | readValue; break; @@ -165,14 +169,53 @@ void trap(){ csr_write(mepc, mepc + 4); }break; default: redirectTrap(); break; - } + } break; + case 0x73:{ + //CSR + uint32_t input = (instruction & 0x4000) ? ((instruction >> 15) & 0x1F) : readRegister((instruction >> 15) & 0x1F);; + uint32_t clear, set; + uint32_t write; + switch (funct3 & 0x3) { + case 0: redirectTrap(); break; + case 1: clear = ~0; set = input; write = 1; break; + case 2: clear = 0; set = input; write = ((instruction >> 15) & 0x1F) != 0; break; + case 3: clear = input; set = 0; write = ((instruction >> 15) & 0x1F) != 0; break; + } + uint32_t csrAddress = instruction >> 20; + uint32_t old; + switch(csrAddress){ + case RDTIME : old = rdtime(); break; + case RDTIMEH : old = rdtimeh(); break; + default: redirectTrap(); break; + } + if(write) { + uint32_t newValue = (old & ~clear) | set; + switch(csrAddress){ + default: redirectTrap(); break; + } + } + + writeRegister((instruction >> 7) & 0x1F, old); + csr_write(mepc, mepc + 4); + + }break; + default: redirectTrap(); break; } }break; case CAUSE_SCALL:{ - int which = readRegister(17); + uint32_t which = readRegister(17); + uint32_t a0 = readRegister(10); + uint32_t a1 = readRegister(11); + uint32_t a2 = readRegister(12); switch(which){ - case 1:{ - putC(readRegister(10)); + case SBI_CONSOLE_PUTCHAR:{ + putC(a0); + csr_write(mepc, csr_read(mepc) + 4); + }break; + case SBI_SET_TIMER:{ + setMachineTimerCmp(a0, a1); + csr_set(mie, MIE_MTIE); + csr_clear(sip, MIP_STIP); csr_write(mepc, csr_read(mepc) + 4); }break; default: stopSim(); break; diff --git a/src/main/c/emulator/src/riscv.h b/src/main/c/emulator/src/riscv.h index dcb125e5..06d2333c 100644 --- a/src/main/c/emulator/src/riscv.h +++ b/src/main/c/emulator/src/riscv.h @@ -2,11 +2,16 @@ #define RISCV_H #define CAUSE_ILLEGAL_INSTRUCTION 2 +#define CAUSE_MACHINE_TIMER 7 #define CAUSE_SCALL 9 -#define MDELEG_INSTRUCTION_PAGE_FAULT (1 << 12) -#define MDELEG_LOAD_PAGE_FAULT (1 << 13) -#define MDELEG_STORE_PAGE_FAULT (1 << 15) +#define MEDELEG_INSTRUCTION_PAGE_FAULT (1 << 12) +#define MEDELEG_LOAD_PAGE_FAULT (1 << 13) +#define MEDELEG_STORE_PAGE_FAULT (1 << 15) +#define MIDELEG_SUPERVISOR_TIMER (1 << 5) + +#define MIE_MTIE (1 << 7) +#define MIP_STIP (1 << 5) #define MSTATUS_UIE 0x00000001 #define MSTATUS_SIE 0x00000002 @@ -46,6 +51,13 @@ #define SSTATUS64_SD 0x8000000000000000 +#define RDCYCLE 0xC00 //Read-only cycle Cycle counter for RDCYCLE instruction. +#define RDTIME 0xC01 //Read-only time Timer for RDTIME instruction. +#define RDINSTRET 0xC02 //Read-only instret Instructions-retired counter for RDINSTRET instruction. +#define RDCYCLEH 0xC80 //Read-only cycleh Upper 32 bits of cycle, RV32I only. +#define RDTIMEH 0xC81 //Read-only timeh Upper 32 bits of time, RV32I only. +#define RDINSTRETH 0xC82 //Read-only instreth Upper 32 bits of instret, RV32I only. + #define csr_swap(csr, val) \ ({ \ diff --git a/src/main/c/emulator/src/start.S b/src/main/c/emulator/src/start.S index ef020e3c..af7fafe0 100755 --- a/src/main/c/emulator/src/start.S +++ b/src/main/c/emulator/src/start.S @@ -39,8 +39,8 @@ _start: call __libc_init_array call init la ra, done - li a0, DTB - li a1, 0 + li a0, 0 + li a1, DTB mret done: j done diff --git a/src/main/c/emulator/src/utils.S b/src/main/c/emulator/src/utils.S new file mode 100644 index 00000000..90c7b647 --- /dev/null +++ b/src/main/c/emulator/src/utils.S @@ -0,0 +1,47 @@ +#include "riscv.h" +/* + + .section .init + .globl readMemory + .type readMemory,@function +readWord: + csrr a4, mepc + li a2, MSTATUS_MPRV + csrs mstatus, a2 + li a3, emulationTrap + csrw mepc, a3 + lw a0, 0(a0) + li a3, trapEntry + csrw mepc, a3 + csrc mstatus, a2 + +writeWord: + csrr a4, mepc + li a2, MSTATUS_MPRV + csrs mstatus, a2 + li a3, emulationTrap + csrw mepc, a3 + sw a1, 0(a0) + li a3, trapEntry + csrw mepc, a3 + csrc mstatus, a2 +*/ +//Redirect trap to supervisor +/* + .section .init + .globl emulationTrap + .type emulationTrap,@function +emulationTrap: + li a0, MSTATUS_MPRV + csrc mstatus, a0 + + la sp, _sp + csrw sepc, a4 + csrr a0, mcause + csrw scause, a0 + csrr a0, mbadaddr + csrw sbadaddr, a0 + + call init + mret +*/ diff --git a/src/main/scala/vexriscv/demo/Linux.scala b/src/main/scala/vexriscv/demo/Linux.scala index f2a84e89..9a35bb9b 100644 --- a/src/main/scala/vexriscv/demo/Linux.scala +++ b/src/main/scala/vexriscv/demo/Linux.scala @@ -46,9 +46,8 @@ make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes LITEX=yes Other commands (Memo): cp litex_default_configuration .config -ARCH=riscv CROSS_COMPILE=riscv64-unknown-elf- make -j`nproc` -riscv64-unknown-elf-objcopy -O binary vmlinux vmlinux.bin -riscv64-unknown-elf-objdump -S -d vmlinux > vmlinux.asm +ARCH=riscv CROSS_COMPILE=riscv64-unknown-elf- make -j`nproc`; riscv64-unknown-elf-objcopy -O binary vmlinux vmlinux.bin +riscv64-unknown-elf-objdump -S -d vmlinux > vmlinux.asm; split -b 1M vmlinux.asm split -b 1M vmlinux.asm dtc -O dtb -o rv32.dtb rv32.dts @@ -56,10 +55,13 @@ make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes LITEX=yes */ + +//TODO have to check, look like supervisor can't get interrupt if the machine mod didn't delegated it, have to check exactly object LinuxGen { def configFull(litex : Boolean, withMmu : Boolean) = { val config = VexRiscvConfig( plugins = List( + new DummyFencePlugin(), //TODO should be removed for design with caches new IBusSimplePlugin( resetVector = 0x80000000l, cmdForkOnSecondStage = false, @@ -102,6 +104,7 @@ object LinuxGen { catchAddressMisaligned = true, catchAccessFault = true, earlyInjection = false, + atomicEntriesCount = 1, memoryTranslatorPortConfig = withMmu generate MmuPortConfig( portTlbSize = 4 ) @@ -200,7 +203,8 @@ object LinuxGen { ) ) if(withMmu) config.plugins += new MmuPlugin( - virtualRange = a => True, +// virtualRange = a => True, + virtualRange = x => x(31 downto 24) =/= 0x81, //TODO It fix the DTB kernel access (workaround) ioRange = (x => if(litex) x(31 downto 28) === 0xB || x(31 downto 28) === 0xE || x(31 downto 28) === 0xF else x(31 downto 28) === 0xF), allowUserIo = true ) diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index eeb7eb1a..b6e77877 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -781,7 +781,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception scause.interrupt := !hadException scause.exceptionCode := trapCause sepc := mepcCaptureStage.input(PC) - if (exceptionPortCtrl != null) { + if (exceptionPortCtrl != null) when(hadException){ stval := exceptionPortCtrl.exceptionContext.badAddr } } @@ -793,7 +793,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception mcause.interrupt := !hadException mcause.exceptionCode := trapCause mepc := mepcCaptureStage.input(PC) - if(exceptionPortCtrl != null) { + if(exceptionPortCtrl != null) when(hadException){ mtval := exceptionPortCtrl.exceptionContext.badAddr } } @@ -872,7 +872,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception if(selfException != null) { selfException.valid := False selfException.code.assignDontCare() - selfException.badAddr := 0 + selfException.badAddr := input(INSTRUCTION).asUInt if(catchIllegalAccess) when(illegalAccess || illegalInstruction){ selfException.valid := True selfException.code := 2 diff --git a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala index 3dc7ad34..3dde6dc8 100644 --- a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala @@ -205,17 +205,21 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, earlyInjection : Boolean = false, /*, idempotentRegions : (UInt) => Bool = (x) => False*/ emitCmdInMemoryStage : Boolean = false, onlyLoadWords : Boolean = false, + atomicEntriesCount : Int = 0, memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] with DBusAccessService { var dBus : DBusSimpleBus = null assert(!(emitCmdInMemoryStage && earlyInjection)) - + def genAtomic = atomicEntriesCount != 0 object MEMORY_ENABLE extends Stageable(Bool) object MEMORY_READ_DATA extends Stageable(Bits(32 bits)) object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits)) object ALIGNEMENT_FAULT extends Stageable(Bool) object MMU_FAULT extends Stageable(Bool) object MMU_RSP extends Stageable(MemoryTranslatorRsp()) + object MEMORY_ATOMIC extends Stageable(Bool) + object ATOMIC_HIT extends Stageable(Bool) + object MEMORY_STORE extends Stageable(Bool) var memoryExceptionPort : Flow[ExceptionCause] = null var rspStage : Stage = null @@ -248,12 +252,14 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> False, - BYPASSABLE_MEMORY_STAGE -> Bool(earlyInjection) + BYPASSABLE_MEMORY_STAGE -> Bool(earlyInjection), + MEMORY_STORE -> False ) ++ (if(catchAccessFault || catchAddressMisaligned) List(HAS_SIDE_EFFECT -> True) else Nil) val storeActions = stdActions ++ List( SRC2_CTRL -> Src2CtrlEnum.IMS, - RS2_USE -> True + RS2_USE -> True, + MEMORY_STORE -> True ) decoderService.addDefault(MEMORY_ENABLE, False) @@ -263,6 +269,29 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, ) + if(genAtomic){ + List(LB, LH, LW, LBU, LHU, LWU, SB, SH, SW).foreach(e => + decoderService.add(e, Seq(MEMORY_ATOMIC -> False)) + ) + decoderService.add( + key = LR, + values = loadActions.filter(_._1 != SRC2_CTRL) ++ Seq( + SRC2_CTRL -> Src2CtrlEnum.RS, + MEMORY_ATOMIC -> True + ) + ) + //TODO probably the cached implemention of SC is bugy (address calculation) + decoderService.add( + key = SC, + values = storeActions.filter(_._1 != SRC2_CTRL) ++ Seq( + REGFILE_WRITE_VALID -> True, + BYPASSABLE_EXECUTE_STAGE -> False, + BYPASSABLE_MEMORY_STAGE -> False, + MEMORY_ATOMIC -> True + ) + ) + } + rspStage = if(stages.last == execute) execute else (if(emitCmdInMemoryStage) writeBack else memory) if(catchSomething) { @@ -300,7 +329,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, skipCmd setWhen(input(ALIGNEMENT_FAULT)) dBus.cmd.valid := arbitration.isValid && input(MEMORY_ENABLE) && !arbitration.isStuckByOthers && !arbitration.isFlushed && !skipCmd && !cmdSent - dBus.cmd.wr := input(INSTRUCTION)(5) + dBus.cmd.wr := input(MEMORY_STORE) dBus.cmd.size := input(INSTRUCTION)(13 downto 12).asUInt dBus.cmd.payload.data := dBus.cmd.size.mux ( U(0) -> input(RS2)(7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0), @@ -332,7 +361,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, dBus.cmd.address := mmuBus.rsp.physicalAddress //do not emit memory request if MMU refilling - insert(MMU_FAULT) := input(MMU_RSP).exception || (!input(MMU_RSP).allowWrite && input(INSTRUCTION)(5)) || (!input(MMU_RSP).allowRead && !input(INSTRUCTION)(5)) || (!input(MMU_RSP).allowUser && privilegeService.isUser()) + insert(MMU_FAULT) := input(MMU_RSP).exception || (!input(MMU_RSP).allowWrite && input(MEMORY_STORE)) || (!input(MMU_RSP).allowRead && !input(MEMORY_STORE)) || (!input(MMU_RSP).allowUser && privilegeService.isUser()) skipCmd.setWhen(input(MMU_FAULT) || input(MMU_RSP).refilling) insert(MMU_RSP) := mmuBus.rsp @@ -341,6 +370,40 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, val mmuLess = (mmuBus == null) generate new Area{ dBus.cmd.address := input(SRC_ADD).asUInt } + + + val atomic = genAtomic generate new Area{ + val address = input(SRC1).asUInt //TODO could avoid 32 muxes if SRC_ADD can be disabled + case class AtomicEntry() extends Bundle{ + val valid = Bool() + val address = UInt(32 bits) + + def init: this.type ={ + valid init(False) + this + } + } + val entries = Vec(Reg(AtomicEntry()).init, atomicEntriesCount) + val entriesAllocCounter = Counter(atomicEntriesCount) + insert(ATOMIC_HIT) := entries.map(e => e.valid && e.address === address).orR + when(arbitration.isValid && input(MEMORY_ENABLE) && input(MEMORY_ATOMIC) && !input(MEMORY_STORE)){ + entries(entriesAllocCounter).valid := True + entries(entriesAllocCounter).address := address + when(!arbitration.isStuck){ + entriesAllocCounter.increment() + } + } + when(service(classOf[IContextSwitching]).isContextSwitching){ + entries.foreach(_.valid := False) + } + + when(input(MEMORY_STORE) && input(MEMORY_ATOMIC) && !input(ATOMIC_HIT)){ + skipCmd := True + } + when(input(MEMORY_ATOMIC)){ + mmuBus.cmd.virtualAddress := address + } + } } //Collect dBus.rsp read responses @@ -349,20 +412,21 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, insert(MEMORY_READ_DATA) := dBus.rsp.data - arbitration.haltItself setWhen(arbitration.isValid && input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && !dBus.rsp.ready) + + arbitration.haltItself setWhen(arbitration.isValid && input(MEMORY_ENABLE) && !input(MEMORY_STORE) && !dBus.rsp.ready) if(catchSomething) { memoryExceptionPort.valid := False memoryExceptionPort.code.assignDontCare() memoryExceptionPort.badAddr := input(REGFILE_WRITE_DATA).asUInt - if(catchAccessFault) when(dBus.rsp.ready && dBus.rsp.error && !input(INSTRUCTION)(5)) { + if(catchAccessFault) when(dBus.rsp.ready && dBus.rsp.error && !input(MEMORY_STORE)) { memoryExceptionPort.valid := True memoryExceptionPort.code := 5 } if(catchAddressMisaligned) when(input(ALIGNEMENT_FAULT)){ - memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(6) | U(4)).resized + memoryExceptionPort.code := (input(MEMORY_STORE) ? U(6) | U(4)).resized memoryExceptionPort.valid := True } @@ -375,7 +439,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, memoryExceptionPort.valid := False } elsewhen(input(MMU_FAULT)) { memoryExceptionPort.valid := True - memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(15) | U(13)).resized + memoryExceptionPort.code := (input(MEMORY_STORE) ? U(15) | U(13)).resized } arbitration.flushAll setWhen(redoBranch.valid) @@ -414,10 +478,15 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, when(arbitration.isValid && input(MEMORY_ENABLE)) { output(REGFILE_WRITE_DATA) := (if(!onlyLoadWords) rspFormated else input(MEMORY_READ_DATA)) + if(genAtomic){ + when(input(MEMORY_ATOMIC) && input(MEMORY_STORE)){ + output(REGFILE_WRITE_DATA) := (!input(ATOMIC_HIT)).asBits.resized + } + } } if(!earlyInjection && !emitCmdInMemoryStage && config.withWriteBackStage) - assert(!(arbitration.isValid && input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && arbitration.isStuck),"DBusSimplePlugin doesn't allow writeback stage stall when read happend") + assert(!(arbitration.isValid && input(MEMORY_ENABLE) && !input(MEMORY_STORE) && arbitration.isStuck),"DBusSimplePlugin doesn't allow writeback stage stall when read happend") //formal insert(FORMAL_MEM_RDATA) := input(MEMORY_READ_DATA) diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 3b4953b2..75d5fdad 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -365,7 +365,14 @@ public: }; }; +#define RESERVED_ENTRY_COUNT 1 + struct ReservedEntry{ + bool valid; + uint32_t address; + }; + ReservedEntry reservedEntries[RESERVED_ENTRY_COUNT]; + int reservedEntriesPtr = 0; RiscvGolden() { pc = 0x80000000; @@ -373,6 +380,9 @@ public: for (int i = 0; i < 32; i++) regs[i] = 0; + for(int i = 0;i < RESERVED_ENTRY_COUNT;i++) reservedEntries[i].valid = false; + + status.raw = 0; ie.raw = 0; mtvec.raw = 0x80000020; @@ -412,9 +422,10 @@ public: virtual void dWrite(int32_t address, int32_t size, uint32_t data) = 0; enum AccessKind {READ,WRITE,EXECUTE}; + virtual bool isMmuRegion(uint32_t v) = 0; bool v2p(uint32_t v, uint32_t *p, AccessKind kind){ uint32_t effectivePrivilege = status.mprv && kind != EXECUTE ? status.mpp : privilege; - if(effectivePrivilege == 3 || satp.mode == 0){ + if(effectivePrivilege == 3 || satp.mode == 0 || !isMmuRegion(v)){ *p = v; } else { Tlb tlb; @@ -440,7 +451,7 @@ public: } void trap(bool interrupt,int32_t cause) { - trap(interrupt, cause, true, 0); + trap(interrupt, cause, false, 0); } void trap(bool interrupt,int32_t cause, uint32_t value) { trap(interrupt, cause, true, value); @@ -452,6 +463,7 @@ public: cout << hex << " a7=0x" << regs[17] << " a0=0x" << regs[10] << " a1=0x" << regs[11] << " a2=0x" << regs[12] << dec << endl; } #endif + for(int i = 0;i < RESERVED_ENTRY_COUNT;i++) reservedEntries[i].valid = false; //Check leguality of the interrupt if(interrupt) { bool hit = false; @@ -673,7 +685,7 @@ public: if (pc & 2) { if(v2p(pc - 2, &pAddr, EXECUTE)){ trap(0, 12, pc - 2); return; } if(iRead(pAddr, &i)){ - trap(0, 1); + trap(0, 1, 0); return; } i >>= 16; @@ -681,7 +693,7 @@ public: uint32_t u32Buf; if(v2p(pc + 2, &pAddr, EXECUTE)){ trap(0, 12, pc + 2); return; } if(iRead(pAddr, &u32Buf)){ - trap(0, 1); + trap(0, 1, 0); return; } i |= u32Buf << 16; @@ -689,7 +701,7 @@ public: } else { if(v2p(pc, &pAddr, EXECUTE)){ trap(0, 12, pc); return; } if(iRead(pAddr, &i)){ - trap(0, 1); + trap(0, 1, 0); return; } } @@ -855,6 +867,56 @@ public: } break; } + case 0x2F: // Atomic stuff + switch(i32_func3){ + case 0x2: + switch(iBits(27,5)){ + case 0x2:{ //LR + uint32_t data; + uint32_t address = i32_rs1; + if(address & 3){ + trap(0, 4, address); + } else { + if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; } + if(dRead(pAddr, 4, &data)){ + trap(0, 5, address); + } else { + reservedEntries[reservedEntriesPtr].valid = true; + reservedEntries[reservedEntriesPtr].address = address; + reservedEntriesPtr = (reservedEntriesPtr + 1) % RESERVED_ENTRY_COUNT; + rfWrite(rd32, data); + pcWrite(pc + 4); + } + } + } break; + case 0x3:{ //SC + uint32_t address = i32_rs1; + if(address & 3){ + trap(0, 6, address); + } else { + if(v2p(address, &pAddr, WRITE)){ trap(0, 15, address); return; } + bool hit = false; + for(int i = 0;i < RESERVED_ENTRY_COUNT;i++) hit |= reservedEntries[i].valid && reservedEntries[i].address == address; + rfWrite(rd32, !hit); + if(hit){ + dWrite(pAddr, 4, i32_rs2); + } + pcWrite(pc + 4); + } + } break; + default: ilegalInstruction(); break; + } + break; + default: ilegalInstruction(); break; + } + break; + case 0x0f: + if(i == 0x100F || (i & 0xF00FFFFF) == 0x000F){ // FENCE FENCE.I + pcWrite(pc + 4); + } else{ + ilegalInstruction(); + } + break; default: ilegalInstruction(); break; } } else { @@ -868,7 +930,7 @@ public: } else { if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; } if(dRead(address, 4, &data)) { - trap(1, 5, address); + trap(0, 5, address); } else { rfWrite(i16_addr2, data); pcWrite(pc + 2); } @@ -917,7 +979,7 @@ public: } else { if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; } if(dRead(pAddr, 4, &data)){ - trap(1, 5, address); + trap(0, 5, address); } else { rfWrite(rd32, data); pcWrite(pc + 2); } @@ -1032,6 +1094,9 @@ public: virtual void fail() { ws->fail(); } + + virtual bool isMmuRegion(uint32_t v) {return ws->isMmuRegion(v);} + bool rfWriteValid; int32_t rfWriteAddress; int32_t rfWriteData; @@ -1172,7 +1237,7 @@ public: } virtual bool isPerifRegion(uint32_t addr) { return false; } - + virtual bool isMmuRegion(uint32_t addr) { return true;} virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error) { if(addr % 4 != 0) { cout << "Warning, unaligned IBusAccess : " << addr << endl; @@ -1186,7 +1251,7 @@ public: } - + virtual bool isDBusCheckedRegion(uint32_t address){ return isPerifRegion(address);} virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) { assertEq(addr % (1 << size), 0); if(isPerifRegion(addr)){ @@ -1448,7 +1513,7 @@ public: (rfWriteValid && (rfWriteAddress!= riscvRef.rfWriteAddress || rfWriteData!= riscvRef.rfWriteData))){ cout << "regFile write missmatch :" << endl; if(rfWriteValid) cout << " REF: RF[" << riscvRef.rfWriteAddress << "] = 0x" << hex << riscvRef.rfWriteData << dec << endl; - if(rfWriteValid) cout << " RTL: RF[" << rfWriteAddress << "] = 0x" << hex << rfWriteData << dec << endl; + if(rfWriteValid) cout << " DUT: RF[" << rfWriteAddress << "] = 0x" << hex << rfWriteData << dec << endl; fail(); } } @@ -1566,7 +1631,7 @@ public: break; #endif case 0xF00FFF48u: mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data;break; - case 0xF00FFF4Cu: mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); /*cout << "mTimeCmp <= " << mTimeCmp << endl; */break; + case 0xF00FFF4Cu: mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); break; } }else{ switch(addr){ @@ -2882,19 +2947,25 @@ public: } - virtual bool isPerifRegion(uint32_t addr) { return (addr & 0xF0000000) == 0xB0000000 || (addr & 0xF0000000) == 0xE0000000;} - + virtual bool isPerifRegion(uint32_t addr) { return (addr & 0xF0000000) == 0xB0000000 || (addr & 0xE0000000) == 0xE0000000;} + virtual bool isMmuRegion(uint32_t addr) { return (addr & 0xFF000000) != 0x81000000;} virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) { - switch(addr){ + if(isPerifRegion(addr)) switch(addr){ //TODO Emulate peripherals here - case 0xFFFFFFFC: fail(); break; //Simulation end + case 0xFFFFFFE0: if(wr) fail(); else *data = mTime; break; + case 0xFFFFFFE4: if(wr) fail(); else *data = mTime >> 32; break; + case 0xFFFFFFE8: if(wr) mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data; else *data = mTimeCmp; break; + case 0xFFFFFFEC: if(wr) mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); else *data = mTimeCmp >> 32; break; case 0xFFFFFFF8: if(wr){ cout << (char)*data; logTraces << (char)*data; - } + logTraces.flush(); + } else fail(); break; + case 0xFFFFFFFC: fail(); break; //Simulation end + default: cout << "Unmapped peripheral access : addr=0x" << hex << addr << " wr=" << wr << " mask=0x" << mask << " data=0x" << data << dec << endl; fail(); break; } Workspace::dBusAccess(addr,wr,size,mask,data,error); @@ -3180,7 +3251,6 @@ int main(int argc, char **argv, char **env) { ->setDStall(false) ->bootAt(0x80000000) ->run(0); - return 1; #endif // #ifdef MMU diff --git a/src/test/cpp/regression/makefile b/src/test/cpp/regression/makefile index 86d5d52e..f5c8d95e 100644 --- a/src/test/cpp/regression/makefile +++ b/src/test/cpp/regression/makefile @@ -1,4 +1,4 @@ -DEBUG?=yes +DEBUG?=no IBUS?=CACHED IBUS_TC?=no