diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index fce48be..b2757b8 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -107,8 +107,6 @@ case class PmpRegister() extends Area { region.valid := True } default { - region.start := 0 - region.end := 0 region.valid := False } } diff --git a/src/test/cpp/raw/pmp/build/pmp.asm b/src/test/cpp/raw/pmp/build/pmp.asm new file mode 100644 index 0000000..86da5ba --- /dev/null +++ b/src/test/cpp/raw/pmp/build/pmp.asm @@ -0,0 +1,172 @@ + +build/pmp.elf: file format elf32-littleriscv + + +Disassembly of section .crt_section: + +80000000 : +80000000: 0240006f j 80000024 <_start> + +80000004 : +80000004: 341f1073 csrw mepc,t5 +80000008: 30200073 mret + +8000000c : +8000000c: 00014337 lui t1,0x14 +80000010: 30033073 csrc mstatus,t1 +80000014: 20000313 li t1,512 +80000018: 30032073 csrs mstatus,t1 +8000001c: 34109073 csrw mepc,ra +80000020: 30200073 mret + +80000024 <_start>: +80000024: 00000097 auipc ra,0x0 +80000028: fe008093 addi ra,ra,-32 # 80000004 +8000002c: 30509073 csrw mtvec,ra + +80000030 : +80000030: 00000e93 li t4,0 +80000034: 00000f17 auipc t5,0x0 +80000038: 1f0f0f13 addi t5,t5,496 # 80000224 +8000003c: 800002b7 lui t0,0x80000 +80000040: 80008e37 lui t3,0x80008 +80000044: deadc337 lui t1,0xdeadc +80000048: eef30313 addi t1,t1,-273 # deadbeef +8000004c: 0062a023 sw t1,0(t0) # 80000000 +80000050: 006e2023 sw t1,0(t3) # 80008000 +80000054: 0002a383 lw t2,0(t0) +80000058: 1c731663 bne t1,t2,80000224 +8000005c: 000e2383 lw t2,0(t3) +80000060: 1c731263 bne t1,t2,80000224 +80000064: 071a1f37 lui t5,0x71a1 +80000068: 808f0f13 addi t5,t5,-2040 # 71a0808 +8000006c: 3a0f1073 csrw pmpcfg0,t5 +80000070: 191c0f37 lui t5,0x191c0 +80000074: 504f0f13 addi t5,t5,1284 # 191c0504 +80000078: 3a1f1073 csrw pmpcfg1,t5 +8000007c: 01800f13 li t5,24 +80000080: 3a2f1073 csrw pmpcfg2,t5 +80000084: 0f1e2f37 lui t5,0xf1e2 +80000088: 900f0f13 addi t5,t5,-1792 # f1e1900 +8000008c: 3a3f1073 csrw pmpcfg3,t5 +80000090: 20000f37 lui t5,0x20000 +80000094: 3b0f1073 csrw pmpaddr0,t5 +80000098: fff00f13 li t5,-1 +8000009c: 3b1f1073 csrw pmpaddr1,t5 +800000a0: 20002f37 lui t5,0x20002 +800000a4: 3b2f1073 csrw pmpaddr2,t5 +800000a8: 20004f37 lui t5,0x20004 +800000ac: ffff0f13 addi t5,t5,-1 # 20003fff +800000b0: 3b3f1073 csrw pmpaddr3,t5 +800000b4: 20004f37 lui t5,0x20004 +800000b8: ffff0f13 addi t5,t5,-1 # 20003fff +800000bc: 3b4f1073 csrw pmpaddr4,t5 +800000c0: 20004f37 lui t5,0x20004 +800000c4: ffff0f13 addi t5,t5,-1 # 20003fff +800000c8: 3b5f1073 csrw pmpaddr5,t5 +800000cc: 20002f37 lui t5,0x20002 +800000d0: ffff0f13 addi t5,t5,-1 # 20001fff +800000d4: 3b6f1073 csrw pmpaddr6,t5 +800000d8: 20004f37 lui t5,0x20004 +800000dc: ffff0f13 addi t5,t5,-1 # 20003fff +800000e0: 3b7f1073 csrw pmpaddr7,t5 +800000e4: 20004f37 lui t5,0x20004 +800000e8: ffff0f13 addi t5,t5,-1 # 20003fff +800000ec: 3b8f1073 csrw pmpaddr8,t5 +800000f0: 00000f13 li t5,0 +800000f4: 3b9f1073 csrw pmpaddr9,t5 +800000f8: 00000f13 li t5,0 +800000fc: 3baf1073 csrw pmpaddr10,t5 +80000100: 00000f13 li t5,0 +80000104: 3bbf1073 csrw pmpaddr11,t5 +80000108: 00000f13 li t5,0 +8000010c: 3bcf1073 csrw pmpaddr12,t5 +80000110: 00000f13 li t5,0 +80000114: 3bdf1073 csrw pmpaddr13,t5 +80000118: 00000f13 li t5,0 +8000011c: 3bef1073 csrw pmpaddr14,t5 +80000120: 00000f13 li t5,0 +80000124: 3bff1073 csrw pmpaddr15,t5 +80000128: 00c10337 lui t1,0xc10 +8000012c: fee30313 addi t1,t1,-18 # c0ffee +80000130: 0062a023 sw t1,0(t0) +80000134: 006e2023 sw t1,0(t3) +80000138: 0002a383 lw t2,0(t0) +8000013c: 0e731463 bne t1,t2,80000224 +80000140: 000e2383 lw t2,0(t3) +80000144: 0e731063 bne t1,t2,80000224 + +80000148 : +80000148: 00100e93 li t4,1 +8000014c: 00000f17 auipc t5,0x0 +80000150: 0d8f0f13 addi t5,t5,216 # 80000224 +80000154: 079a1f37 lui t5,0x79a1 +80000158: 808f0f13 addi t5,t5,-2040 # 79a0808 +8000015c: 3a0f1073 csrw pmpcfg0,t5 +80000160: deadc337 lui t1,0xdeadc +80000164: eef30313 addi t1,t1,-273 # deadbeef +80000168: 006e2023 sw t1,0(t3) +8000016c: 00000f17 auipc t5,0x0 +80000170: 010f0f13 addi t5,t5,16 # 8000017c +80000174: 000e2383 lw t2,0(t3) +80000178: 0ac0006f j 80000224 + +8000017c : +8000017c: 00200e93 li t4,2 +80000180: 00000f17 auipc t5,0x0 +80000184: 0a4f0f13 addi t5,t5,164 # 80000224 +80000188: 071a1f37 lui t5,0x71a1 +8000018c: 808f0f13 addi t5,t5,-2040 # 71a0808 +80000190: 3a0f1073 csrw pmpcfg0,t5 +80000194: deadc337 lui t1,0xdeadc +80000198: eef30313 addi t1,t1,-273 # deadbeef +8000019c: 006e2023 sw t1,0(t3) +800001a0: 00000f17 auipc t5,0x0 +800001a4: 010f0f13 addi t5,t5,16 # 800001b0 +800001a8: 000e2383 lw t2,0(t3) +800001ac: 0780006f j 80000224 + +800001b0 : +800001b0: 00300e93 li t4,3 +800001b4: 00000f17 auipc t5,0x0 +800001b8: 070f0f13 addi t5,t5,112 # 80000224 +800001bc: 00000097 auipc ra,0x0 +800001c0: 00c08093 addi ra,ra,12 # 800001c8 +800001c4: e49ff06f j 8000000c + +800001c8 : +800001c8: 00400e93 li t4,4 +800001cc: 00000f17 auipc t5,0x0 +800001d0: 058f0f13 addi t5,t5,88 # 80000224 +800001d4: deadc337 lui t1,0xdeadc +800001d8: eef30313 addi t1,t1,-273 # deadbeef +800001dc: 006e2023 sw t1,0(t3) +800001e0: 00000f17 auipc t5,0x0 +800001e4: 010f0f13 addi t5,t5,16 # 800001f0 +800001e8: 000e2383 lw t2,0(t3) +800001ec: 0380006f j 80000224 + +800001f0 : +800001f0: 00500e93 li t4,5 +800001f4: 00000f17 auipc t5,0x0 +800001f8: 03cf0f13 addi t5,t5,60 # 80000230 +800001fc: 80010e37 lui t3,0x80010 +80000200: deadc337 lui t1,0xdeadc +80000204: eef30313 addi t1,t1,-273 # deadbeef +80000208: 0062a023 sw t1,0(t0) +8000020c: 0002a383 lw t2,0(t0) +80000210: 00731a63 bne t1,t2,80000224 +80000214: 000e2383 lw t2,0(t3) # 80010000 +80000218: 00000f17 auipc t5,0x0 +8000021c: 018f0f13 addi t5,t5,24 # 80000230 +80000220: 007e2023 sw t2,0(t3) + +80000224 : +80000224: f0100137 lui sp,0xf0100 +80000228: f2410113 addi sp,sp,-220 # f00fff24 +8000022c: 01d12023 sw t4,0(sp) + +80000230 : +80000230: f0100137 lui sp,0xf0100 +80000234: f2010113 addi sp,sp,-224 # f00fff20 +80000238: 00012023 sw zero,0(sp) diff --git a/src/test/cpp/raw/pmp/build/pmp.elf b/src/test/cpp/raw/pmp/build/pmp.elf new file mode 100755 index 0000000..2266099 Binary files /dev/null and b/src/test/cpp/raw/pmp/build/pmp.elf differ diff --git a/src/test/cpp/raw/pmp/build/pmp.hex b/src/test/cpp/raw/pmp/build/pmp.hex new file mode 100644 index 0000000..885cf04 --- /dev/null +++ b/src/test/cpp/raw/pmp/build/pmp.hex @@ -0,0 +1,39 @@ +:0200000480007A +:100000006F00400273101F3473002030374301002B +:1000100073300330130300207320033073901034C7 +:100020007300203097000000938000FE73905030E2 +:10003000930E0000170F0000130F0F1FB702008070 +:10004000378E008037C3ADDE1303F3EE23A06200CA +:1000500023206E0083A302006316731C83230E000B +:100060006312731C371F1A07130F8F8073100F3A18 +:10007000370F1C19130F4F5073101F3A130F8001C5 +:1000800073102F3A372F1E0F130F0F9073103F3A34 +:10009000370F002073100F3B130FF0FF73101F3B3F +:1000A000372F002073102F3B374F0020130FFFFF17 +:1000B00073103F3B374F0020130FFFFF73104F3B70 +:1000C000374F0020130FFFFF73105F3B372F0020C7 +:1000D000130FFFFF73106F3B374F0020130FFFFF0D +:1000E00073107F3B374F0020130FFFFF73108F3BC0 +:1000F000130F000073109F3B130F00007310AF3BF2 +:10010000130F00007310BF3B130F00007310CF3BA1 +:10011000130F00007310DF3B130F00007310EF3B51 +:10012000130F00007310FF3B3703C1001303E3FEFE +:1001300023A0620023206E0083A302006314730EC9 +:1001400083230E006310730E930E1000170F000030 +:10015000130F8F0D371F9A07130F8F8073100F3AED +:1001600037C3ADDE1303F3EE23206E00170F00003C +:10017000130F0F0183230E006F00C00A930E20009F +:10018000170F0000130F4F0A371F1A07130F8F8026 +:1001900073100F3A37C3ADDE1303F3EE23206E0066 +:1001A000170F0000130F0F0183230E006F0080074D +:1001B000930E3000170F0000130F0F079700000079 +:1001C0009380C0006FF09FE4930E4000170F000073 +:1001D000130F8F0537C3ADDE1303F3EE23206E003C +:1001E000170F0000130F0F0183230E006F00800311 +:1001F000930E5000170F0000130FCF03370E01802E +:1002000037C3ADDE1303F3EE23A0620083A3020025 +:10021000631A730083230E00170F0000130F8F0162 +:1002200023207E00370110F0130141F22320D10179 +:0C023000370110F0130101F2232001003F +:040000058000002453 +:00000001FF diff --git a/src/test/cpp/raw/pmp/build/pmp.map b/src/test/cpp/raw/pmp/build/pmp.map new file mode 100644 index 0000000..66d99f2 --- /dev/null +++ b/src/test/cpp/raw/pmp/build/pmp.map @@ -0,0 +1,35 @@ + +Memory Configuration + +Name Origin Length Attributes +onChipRam 0x0000000080000000 0x0000000000020000 w !xr +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +LOAD build/src/crt.o +LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/libgcc.a +START GROUP +LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a +LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libgloss.a +END GROUP +LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/libgcc.a + +.crt_section 0x0000000080000000 0x23c + 0x0000000080000000 . = ALIGN (0x4) + *crt.o(.text) + .text 0x0000000080000000 0x23c build/src/crt.o + 0x0000000080000004 trap + 0x0000000080000024 _start +OUTPUT(build/pmp.elf elf32-littleriscv) + +.data 0x000000008000023c 0x0 + .data 0x000000008000023c 0x0 build/src/crt.o + +.bss 0x000000008000023c 0x0 + .bss 0x000000008000023c 0x0 build/src/crt.o + +.riscv.attributes + 0x0000000000000000 0x1e + .riscv.attributes + 0x0000000000000000 0x1e build/src/crt.o diff --git a/src/test/cpp/raw/pmp/makefile b/src/test/cpp/raw/pmp/makefile new file mode 100644 index 0000000..0069df4 --- /dev/null +++ b/src/test/cpp/raw/pmp/makefile @@ -0,0 +1,3 @@ +PROJ_NAME=pmp + +include ../common/asm.mk diff --git a/src/test/cpp/raw/pmp/src/crt.S b/src/test/cpp/raw/pmp/src/crt.S new file mode 100644 index 0000000..e9c8546 --- /dev/null +++ b/src/test/cpp/raw/pmp/src/crt.S @@ -0,0 +1,172 @@ +#define TEST_ID x29 +#define TRAP_RA x30 + +#define PMPCFG0 0x071a0808 +#define PMPCFG0_ 0x079a0808 // lock region 2 +#define PMPCFG1 0x191c0504 +#define PMPCFG2 0x00000018 +#define PMPCFG3 0x0f1e1900 + +#define PMPADDR0 0x20000000 // TOR +#define PMPADDR1 0xffffffff // TOR +#define PMPADDR2 0x20002000 // NA4 W +#define PMPADDR3 0x20003fff // OFF RWX +#define PMPADDR4 0x20003fff // OFF X +#define PMPADDR5 0x20003fff // OFF RW +#define PMPADDR6 0x20001fff // NAPOT RWX +#define PMPADDR7 0x20003fff // NAPOT R +#define PMPADDR8 0x20003fff // NAPOT +#define PMPADDR9 0x00000000 // OFF +#define PMPADDR10 0x00000000 // OFF +#define PMPADDR11 0x00000000 // OFF +#define PMPADDR12 0x00000000 // OFF +#define PMPADDR13 0x00000000 // NAPOT R +#define PMPADDR14 0x00000000 // NAPOT WX +#define PMPADDR15 0x00000000 // TOR RWX + +.global trap +.global _start + + j _start + +trap: + csrw mepc, TRAP_RA + mret + +to_user: + li t1, 0x14000 + csrc mstatus, t1 + li t1, 0x200 + csrs mstatus, t1 + csrw mepc, ra + mret + +_start: + la x1, trap + csrw mtvec, x1 + +// configure PMP, attempt read/write from machine mode +test0: + li TEST_ID, 0 + la TRAP_RA, fail + + li t0, 0x80000000 + li t3, 0x80008000 + li t1, 0xdeadbeef + sw t1, 0x0(t0) + sw t1, 0x0(t3) + lw t2, 0x0(t0) + bne t1, t2, fail + lw t2, 0x0(t3) + bne t1, t2, fail + + li t5, PMPCFG0 + csrw pmpcfg0, t5 + li t5, PMPCFG1 + csrw pmpcfg1, t5 + li t5, PMPCFG2 + csrw pmpcfg2, t5 + li t5, PMPCFG3 + csrw pmpcfg3, t5 + li t5, PMPADDR0 + csrw pmpaddr0, t5 + li t5, PMPADDR1 + csrw pmpaddr1, t5 + li t5, PMPADDR2 + csrw pmpaddr2, t5 + li t5, PMPADDR3 + csrw pmpaddr3, t5 + li t5, PMPADDR4 + csrw pmpaddr4, t5 + li t5, PMPADDR5 + csrw pmpaddr5, t5 + li t5, PMPADDR6 + csrw pmpaddr6, t5 + li t5, PMPADDR7 + csrw pmpaddr7, t5 + li t5, PMPADDR8 + csrw pmpaddr8, t5 + li t5, PMPADDR9 + csrw pmpaddr9, t5 + li t5, PMPADDR10 + csrw pmpaddr10, t5 + li t5, PMPADDR11 + csrw pmpaddr11, t5 + li t5, PMPADDR12 + csrw pmpaddr12, t5 + li t5, PMPADDR13 + csrw pmpaddr13, t5 + li t5, PMPADDR14 + csrw pmpaddr14, t5 + li t5, PMPADDR15 + csrw pmpaddr15, t5 + + li t1, 0x00c0ffee + sw t1, 0x0(t0) + sw t1, 0x0(t3) + lw t2, 0x0(t0) + bne t1, t2, fail + lw t2, 0x0(t3) + bne t1, t2, fail + +// lock region 2, attempt read/write from machine mode +test1: + li TEST_ID, 1 + la TRAP_RA, fail + li t5, PMPCFG0_ + csrw pmpcfg0, t5 // lock region 2 + li t1, 0xdeadbeef + sw t1, 0x0(t3) // should be OK (write 0x80008000) + la TRAP_RA, test2 + lw t2, 0x0(t3) // should fault (read 0x80008000) + j fail + +// "unlock" region 2, attempt read/write from machine mode +test2: + li TEST_ID, 2 + la TRAP_RA, fail + li t5, PMPCFG0 + csrw pmpcfg0, t5 // "unlock" region 2 + li t1, 0xdeadbeef + sw t1, 0x0(t3) // should still be OK (write 0x80008000) + la TRAP_RA, test3 + lw t2, 0x0(t3) // should still fault (read 0x80008000) + j fail + +// jump into user mode +test3: + li TEST_ID, 3 + la TRAP_RA, fail + la ra, test4 + j to_user + +// attempt to read/write region 2 from user mode +test4: + li TEST_ID, 4 + la TRAP_RA, fail + li t1, 0xdeadbeef + sw t1, 0x0(t3) // should be OK (write 0x80008000) + la TRAP_RA, test5 + lw t2, 0x0(t3) // should fault (read 0x80008000) + j fail + +// attempt to read/write other regions from user mode +test5: + li TEST_ID, 5 + la TRAP_RA, pass + li t3, 0x80010000 + li t1, 0xdeadbeef + sw t1, 0x0(t0) + lw t2, 0x0(t0) + bne t1, t2, fail // should be OK + lw t2, 0x0(t3) // should be OK (read 0x80010000) + la TRAP_RA, pass + sw t2, 0x0(t3) // should fault (write 0x80010000) + +fail: + li x2, 0xf00fff24 + sw TEST_ID, 0(x2) + +pass: + li x2, 0xf00fff20 + sw x0, 0(x2) diff --git a/src/test/cpp/raw/pmp/src/ld b/src/test/cpp/raw/pmp/src/ld new file mode 100644 index 0000000..93d8de8 --- /dev/null +++ b/src/test/cpp/raw/pmp/src/ld @@ -0,0 +1,16 @@ +OUTPUT_ARCH( "riscv" ) + +MEMORY { + onChipRam (W!RX)/*(RX)*/ : ORIGIN = 0x80000000, LENGTH = 128K +} + +SECTIONS +{ + + .crt_section : + { + . = ALIGN(4); + *crt.o(.text) + } > onChipRam + +} diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index d983e8e..a4d3a3b 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -3870,6 +3870,10 @@ int main(int argc, char **argv, char **env) { redo(REDO,WorkspaceRegression("lrsc").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/lrsc/build/lrsc.hex")->bootAt(0x00000000u)->run(10e3);); #endif + #ifdef PMP + redo(REDO,WorkspaceRegression("pmp").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/lrsc/build/pmp.hex")->bootAt(0x00000000u)->run(10e3);); + #endif + #ifdef AMO redo(REDO,WorkspaceRegression("amo").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/amo/build/amo.hex")->bootAt(0x00000000u)->run(10e3);); #endif