From f88b259ebacb84624f2df3cfd14db56a5dd2ca4f Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 24 Feb 2020 12:43:35 +0100 Subject: [PATCH 01/30] emulator: Use external hw/common.h from LiteX Remove code copied from `hw/common.h` and use the header from the LiteX repository provided using `LITEX_BASE` environment variable. Content of `common.h` is now evolving (new functions are added, some are removed) and syncing it between repos would be cumbersome. --- src/main/c/emulator/makefile | 7 ++++--- src/main/c/emulator/src/hal.c | 32 -------------------------------- 2 files changed, 4 insertions(+), 35 deletions(-) diff --git a/src/main/c/emulator/makefile b/src/main/c/emulator/makefile index 7534d08..6f3c8fc 100755 --- a/src/main/c/emulator/makefile +++ b/src/main/c/emulator/makefile @@ -18,10 +18,11 @@ sim: all qemu: CFLAGS += -DQEMU qemu: all -litex: CFLAGS += -DLITEX -I${LITEX_BASE}/software/include -litex: | check_litex_base all -check_litex_base: +litex: CFLAGS += -DLITEX -I${LITEX_GENERATED} -I${LITEX_BASE}/litex/soc/software/include +litex: | check_litex all +check_litex: @[ "${LITEX_BASE}" ] || ( echo ">> LITEX_BASE is not set"; exit 1 ) + @[ "${LITEX_GENERATED}" ] || ( echo ">> LITEX_GENERATED is not set"; exit 1 ) include ${STANDALONE}/common/riscv64-unknown-elf.mk include ${STANDALONE}/common/standalone.mk diff --git a/src/main/c/emulator/src/hal.c b/src/main/c/emulator/src/hal.c index 5a151bb..aa6745b 100644 --- a/src/main/c/emulator/src/hal.c +++ b/src/main/c/emulator/src/hal.c @@ -146,38 +146,6 @@ void halInit(){ #ifdef LITEX -// this is copied from LiteX -#define CSR_ACCESSORS_DEFINED -static inline void csr_writeb(uint8_t value, unsigned long addr) -{ - *((volatile uint8_t *)addr) = value; -} - -static inline uint8_t csr_readb(unsigned long addr) -{ - return *(volatile uint8_t *)addr; -} - -static inline void csr_writew(uint16_t value, unsigned long addr) -{ - *((volatile uint16_t *)addr) = value; -} - -static inline uint16_t csr_readw(unsigned long addr) -{ - return *(volatile uint16_t *)addr; -} - -static inline void csr_writel(uint32_t value, unsigned long addr) -{ - *((volatile uint32_t *)addr) = value; -} - -static inline uint32_t csr_readl(unsigned long addr) -{ - return *(volatile uint32_t *)addr; -} - // this is a file generated by LiteX #include From 31667b18d8fb1acee198c141900f5dd874f1c8e3 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 20 Mar 2020 11:26:38 +0100 Subject: [PATCH 02/30] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22bfba8..84b811e 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ For commercial support, please contact spinalhdl@gmail.com. ## Area usage and maximal frequency -The following numbers were obtained by synthesizing the CPU as toplevel without any specific synthesis options to save area or to get better maximal frequency (neutral).
+The following numbers were obtained by synthesizing the CPU as toplevel on the fastest speed grade without any specific synthesis options to save area or to get better maximal frequency (neutral).
The clock constraint is set to an unattainable value, which tends to increase the design area.
The dhrystone benchmark was compiled with the `-O3 -fno-inline` option.
All the cached configurations have some cache trashing during the dhrystone benchmark except the `VexRiscv full max perf` one. This, of course, reduces the performance. It is possible to produce From 31d2aaa05bd3b353e8d2e4dba2448f17cca2f52b Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Sat, 28 Mar 2020 15:38:32 +0100 Subject: [PATCH 03/30] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 84b811e..bb37f03 100644 --- a/README.md +++ b/README.md @@ -824,6 +824,12 @@ This plugin implements the register file. This register file use a `don't care` read-during-write policy, so the bypassing/hazard plugin should take care of this. +If you get a `Missing inserts : INSTRUCTION_ANTICIPATE` error, that's because the RegFilePlugin is configured to use SYNC memory read ports to access the register file, but the IBus plugin configuration can't provide the instruction's register file read address one cycle before the decode stage. To workaround that you can : + +- Configure the RegFilePlugin to implement the register file read in a asyncronus manner (ASYNC), if your target device support such things +- If you use the IBusSimplePlugin, you need to enable the injectorStage configuration +- If you use the IBusCachedPlugin, you can either enable the injectorStage, or set twoCycleCache + twoCycleRam to false. + #### HazardSimplePlugin This plugin checks the pipeline instruction dependencies and, if necessary or possible, will stop the instruction in the decoding stage or bypass the instruction results From ddc59bc40417fd8cf23bdcee482330430ab172a2 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 7 Apr 2020 12:13:40 +0200 Subject: [PATCH 04/30] Fix DebugPlugin step by step --- src/main/scala/vexriscv/plugin/DebugPlugin.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/DebugPlugin.scala b/src/main/scala/vexriscv/plugin/DebugPlugin.scala index 93e65e3..c04d167 100644 --- a/src/main/scala/vexriscv/plugin/DebugPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DebugPlugin.scala @@ -213,18 +213,17 @@ class DebugPlugin(val debugClockDomain : ClockDomain, hardwareBreakpointCount : iBusFetcher.haltIt() } - when(stepIt) { - //Assume nothing will stop the CPU in the decode stage + when(stepIt && iBusFetcher.incoming()) { + iBusFetcher.haltIt() when(decode.arbitration.isValid) { haltIt := True - decode.arbitration.flushNext := True } } //Avoid having two C instruction executed in a single step if(pipeline(RVC_GEN)){ val cleanStep = RegNext(stepIt && decode.arbitration.isFiring) init(False) - decode.arbitration.removeIt setWhen(cleanStep) + execute.arbitration.flushNext setWhen(cleanStep) } io.resetOut := RegNext(resetIt) From c74b03b4de44a167f6d17f0713842916b54d22a9 Mon Sep 17 00:00:00 2001 From: Tom Verbeure Date: Tue, 19 May 2020 13:40:46 -0700 Subject: [PATCH 05/30] Add uinstret support. --- src/main/scala/vexriscv/Riscv.scala | 2 ++ src/main/scala/vexriscv/demo/Briey.scala | 3 ++- .../scala/vexriscv/demo/VexRiscvAhbLite3.scala | 3 ++- .../vexriscv/demo/VexRiscvAvalonForSim.scala | 3 ++- .../demo/VexRiscvAvalonWithIntegratedJtag.scala | 3 ++- .../demo/VexRiscvAxi4WithIntegratedJtag.scala | 3 ++- src/main/scala/vexriscv/plugin/CsrPlugin.scala | 17 +++++++++++++---- 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/main/scala/vexriscv/Riscv.scala b/src/main/scala/vexriscv/Riscv.scala index 91cf876..7874e02 100644 --- a/src/main/scala/vexriscv/Riscv.scala +++ b/src/main/scala/vexriscv/Riscv.scala @@ -159,5 +159,7 @@ object Riscv{ def UCYCLE = 0xC00 // UR Machine ucycle counter. def UCYCLEH = 0xC80 + def UINSTRET = 0xC02 // UR Machine instructions-retired counter. + def UINSTRETH = 0xC82 // UR Upper 32 bits of minstret, RV32I only. } } diff --git a/src/main/scala/vexriscv/demo/Briey.scala b/src/main/scala/vexriscv/demo/Briey.scala index 2bf5947..dd794a6 100644 --- a/src/main/scala/vexriscv/demo/Briey.scala +++ b/src/main/scala/vexriscv/demo/Briey.scala @@ -147,7 +147,8 @@ object BrieyConfig{ minstretAccess = CsrAccess.NONE, ecallGen = false, wfiGenAsWait = false, - ucycleAccess = CsrAccess.NONE + ucycleAccess = CsrAccess.NONE, + uinstretAccess = CsrAccess.NONE ) ), new YamlPlugin("cpu0.yaml") diff --git a/src/main/scala/vexriscv/demo/VexRiscvAhbLite3.scala b/src/main/scala/vexriscv/demo/VexRiscvAhbLite3.scala index 593d399..49f51ae 100644 --- a/src/main/scala/vexriscv/demo/VexRiscvAhbLite3.scala +++ b/src/main/scala/vexriscv/demo/VexRiscvAhbLite3.scala @@ -126,7 +126,8 @@ object VexRiscvAhbLite3{ minstretAccess = CsrAccess.NONE, ecallGen = false, wfiGenAsWait = false, - ucycleAccess = CsrAccess.NONE + ucycleAccess = CsrAccess.NONE, + uinstretAccess = CsrAccess.NONE ) ), new YamlPlugin("cpu0.yaml") diff --git a/src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala b/src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala index 4245cd1..b2c3f69 100644 --- a/src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala +++ b/src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala @@ -124,7 +124,8 @@ object VexRiscvAvalonForSim{ minstretAccess = CsrAccess.NONE, ecallGen = false, wfiGenAsWait = false, - ucycleAccess = CsrAccess.NONE + ucycleAccess = CsrAccess.NONE, + uinstretAccess = CsrAccess.NONE ) ), new YamlPlugin("cpu0.yaml") diff --git a/src/main/scala/vexriscv/demo/VexRiscvAvalonWithIntegratedJtag.scala b/src/main/scala/vexriscv/demo/VexRiscvAvalonWithIntegratedJtag.scala index bba065e..063d945 100644 --- a/src/main/scala/vexriscv/demo/VexRiscvAvalonWithIntegratedJtag.scala +++ b/src/main/scala/vexriscv/demo/VexRiscvAvalonWithIntegratedJtag.scala @@ -121,7 +121,8 @@ object VexRiscvAvalonWithIntegratedJtag{ minstretAccess = CsrAccess.NONE, ecallGen = false, wfiGenAsWait = false, - ucycleAccess = CsrAccess.NONE + ucycleAccess = CsrAccess.NONE, + uinstretAccess = CsrAccess.NONE ) ), new YamlPlugin("cpu0.yaml") diff --git a/src/main/scala/vexriscv/demo/VexRiscvAxi4WithIntegratedJtag.scala b/src/main/scala/vexriscv/demo/VexRiscvAxi4WithIntegratedJtag.scala index b002c06..67556e9 100644 --- a/src/main/scala/vexriscv/demo/VexRiscvAxi4WithIntegratedJtag.scala +++ b/src/main/scala/vexriscv/demo/VexRiscvAxi4WithIntegratedJtag.scala @@ -122,7 +122,8 @@ object VexRiscvAxi4WithIntegratedJtag{ minstretAccess = CsrAccess.NONE, ecallGen = false, wfiGenAsWait = false, - ucycleAccess = CsrAccess.NONE + ucycleAccess = CsrAccess.NONE, + uinstretAccess = CsrAccess.NONE ) ), new YamlPlugin("cpu0.yaml") diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 0cdc896..539e534 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -49,6 +49,7 @@ case class CsrPluginConfig( mcycleAccess : CsrAccess, minstretAccess : CsrAccess, ucycleAccess : CsrAccess, + uinstretAccess : CsrAccess, wfiGenAsWait : Boolean, ecallGen : Boolean, xtvecModeGen : Boolean = false, @@ -100,6 +101,7 @@ object CsrPluginConfig{ mcycleAccess = CsrAccess.NONE, minstretAccess = CsrAccess.NONE, ucycleAccess = CsrAccess.NONE, + uinstretAccess = CsrAccess.NONE, wfiGenAsWait = true, ecallGen = true, xtvecModeGen = false, @@ -140,6 +142,7 @@ object CsrPluginConfig{ mcycleAccess = CsrAccess.READ_WRITE, minstretAccess = CsrAccess.READ_WRITE, ucycleAccess = CsrAccess.READ_ONLY, + uinstretAccess = CsrAccess.READ_ONLY, wfiGenAsWait = true, ecallGen = true, xtvecModeGen = false, @@ -180,7 +183,8 @@ object CsrPluginConfig{ minstretAccess = CsrAccess.READ_WRITE, ecallGen = true, wfiGenAsWait = true, - ucycleAccess = CsrAccess.READ_ONLY + ucycleAccess = CsrAccess.READ_ONLY, + uinstretAccess = CsrAccess.READ_ONLY ) def all2(mtvecInit : BigInt) : CsrPluginConfig = CsrPluginConfig( @@ -202,6 +206,7 @@ object CsrPluginConfig{ ecallGen = true, wfiGenAsWait = true, ucycleAccess = CsrAccess.READ_ONLY, + uinstretAccess = CsrAccess.READ_ONLY, supervisorGen = true, sscratchGen = true, stvecAccess = CsrAccess.READ_WRITE, @@ -233,7 +238,8 @@ object CsrPluginConfig{ minstretAccess = CsrAccess.NONE, ecallGen = false, wfiGenAsWait = false, - ucycleAccess = CsrAccess.NONE + ucycleAccess = CsrAccess.NONE, + uinstretAccess = CsrAccess.NONE ) def smallest(mtvecInit : BigInt) = CsrPluginConfig( @@ -254,7 +260,8 @@ object CsrPluginConfig{ minstretAccess = CsrAccess.NONE, ecallGen = false, wfiGenAsWait = false, - ucycleAccess = CsrAccess.NONE + ucycleAccess = CsrAccess.NONE, + uinstretAccess = CsrAccess.NONE ) } @@ -586,6 +593,8 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep //User CSR ucycleAccess(CSR.UCYCLE, mcycle(31 downto 0)) ucycleAccess(CSR.UCYCLEH, mcycle(63 downto 32)) + uinstretAccess(CSR.UINSTRET, minstret(31 downto 0)) + uinstretAccess(CSR.UINSTRETH, minstret(63 downto 32)) pipeline(MPP) := mstatus.MPP } @@ -1148,4 +1157,4 @@ class UserInterruptPlugin(interruptName : String, code : Int, privilege : Int = csr.rw(csrAddress = CSR.MIE, bitOffset = code, interruptEnable) } override def build(pipeline: VexRiscv): Unit = {} -} \ No newline at end of file +} From b901651ab54174606d189498b8cdcbeb307dbd7b Mon Sep 17 00:00:00 2001 From: Tom Verbeure Date: Tue, 19 May 2020 14:48:35 -0700 Subject: [PATCH 06/30] Add default value of NONE to uinstret CSR. --- src/main/scala/vexriscv/plugin/CsrPlugin.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 539e534..668f1b7 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -38,7 +38,7 @@ case class CsrPluginConfig( marchid : BigInt, mimpid : BigInt, mhartid : BigInt, - misaExtensionsInit : Int, + misaExtensionsInit : Int, misaAccess : CsrAccess, mtvecAccess : CsrAccess, mtvecInit : BigInt, @@ -49,7 +49,7 @@ case class CsrPluginConfig( mcycleAccess : CsrAccess, minstretAccess : CsrAccess, ucycleAccess : CsrAccess, - uinstretAccess : CsrAccess, + uinstretAccess : CsrAccess = CsrAccess.NONE, wfiGenAsWait : Boolean, ecallGen : Boolean, xtvecModeGen : Boolean = false, From 2942d0652a89646c5225bee15dd55cc3b0871766 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 13 Apr 2020 13:01:12 +0200 Subject: [PATCH 07/30] fix Briey verilator --- src/test/cpp/briey/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/cpp/briey/main.cpp b/src/test/cpp/briey/main.cpp index 2243dce..0ee7c45 100644 --- a/src/test/cpp/briey/main.cpp +++ b/src/test/cpp/briey/main.cpp @@ -401,7 +401,7 @@ public: sdramIo->ADDR = &top->io_sdram_ADDR ; sdramIo->DQ_read = (CData*)&top->io_sdram_DQ_read ; sdramIo->DQ_write = (CData*)&top->io_sdram_DQ_write ; - sdramIo->DQ_writeEnable = &top->io_sdram_DQ_writeEnable; + sdramIo->DQ_writeEnable = (CData*)&top->io_sdram_DQ_writeEnable; Sdram *sdram = new Sdram(sdramConfig, sdramIo); axiClk->add(sdram); From c489143442d9ccc23790153cca6ad33c2736114a Mon Sep 17 00:00:00 2001 From: Marcus Comstedt Date: Sun, 30 Aug 2020 15:17:09 +0200 Subject: [PATCH 08/30] Add support for big endian byte ordering --- src/main/scala/vexriscv/demo/Murax.scala | 17 ++-- .../scala/vexriscv/demo/MuraxUtiles.scala | 20 ++-- .../vexriscv/plugin/DBusSimplePlugin.scala | 93 ++++++++++--------- .../vexriscv/plugin/IBusSimplePlugin.scala | 9 +- 4 files changed, 81 insertions(+), 58 deletions(-) diff --git a/src/main/scala/vexriscv/demo/Murax.scala b/src/main/scala/vexriscv/demo/Murax.scala index 6d98907..a0590ad 100644 --- a/src/main/scala/vexriscv/demo/Murax.scala +++ b/src/main/scala/vexriscv/demo/Murax.scala @@ -52,8 +52,8 @@ case class MuraxConfig(coreFrequency : HertzNumber, object MuraxConfig{ - def default : MuraxConfig = default(false) - def default(withXip : Boolean) = MuraxConfig( + def default : MuraxConfig = default(false, false) + def default(withXip : Boolean = false, bigEndian : Boolean = false) = MuraxConfig( coreFrequency = 12 MHz, onChipRamSize = 8 kB, onChipRamHexFile = null, @@ -75,12 +75,14 @@ object MuraxConfig{ cmdForkPersistence = withXip, //Required by the Xip controller prediction = NONE, catchAccessFault = false, - compressedGen = false + compressedGen = false, + bigEndian = bigEndian ), new DBusSimplePlugin( catchAddressMisaligned = false, catchAccessFault = false, - earlyInjection = false + earlyInjection = false, + bigEndian = bigEndian ), new CsrPlugin(CsrPluginConfig.smallest(mtvecInit = if(withXip) 0xE0040020l else 0x80000020l)), new DecoderSimplePlugin( @@ -214,9 +216,11 @@ case class Murax(config : MuraxConfig) extends Component{ dataWidth = 32 ) + val bigEndianDBus = config.cpuPlugins.exists(_ match{ case plugin : DBusSimplePlugin => plugin.bigEndian case _ => false}) + //Arbiter of the cpu dBus/iBus to drive the mainBus //Priority to dBus, !! cmd transactions can change on the fly !! - val mainBusArbiter = new MuraxMasterArbiter(pipelinedMemoryBusConfig) + val mainBusArbiter = new MuraxMasterArbiter(pipelinedMemoryBusConfig, bigEndianDBus) //Instanciate the CPU val cpu = new VexRiscv( @@ -258,7 +262,8 @@ case class Murax(config : MuraxConfig) extends Component{ val ram = new MuraxPipelinedMemoryBusRam( onChipRamSize = onChipRamSize, onChipRamHexFile = onChipRamHexFile, - pipelinedMemoryBusConfig = pipelinedMemoryBusConfig + pipelinedMemoryBusConfig = pipelinedMemoryBusConfig, + bigEndian = bigEndianDBus ) mainBusMapping += ram.io.bus -> (0x80000000l, onChipRamSize) diff --git a/src/main/scala/vexriscv/demo/MuraxUtiles.scala b/src/main/scala/vexriscv/demo/MuraxUtiles.scala index 1c45bc3..1e22157 100644 --- a/src/main/scala/vexriscv/demo/MuraxUtiles.scala +++ b/src/main/scala/vexriscv/demo/MuraxUtiles.scala @@ -10,10 +10,10 @@ import spinal.lib._ import spinal.lib.bus.simple._ import vexriscv.plugin.{DBusSimpleBus, IBusSimpleBus} -class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) extends Component{ +class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig, bigEndian : Boolean = false) extends Component{ val io = new Bundle{ val iBus = slave(IBusSimpleBus(null)) - val dBus = slave(DBusSimpleBus()) + val dBus = slave(DBusSimpleBus(bigEndian)) val masterBus = master(PipelinedMemoryBus(pipelinedMemoryBusConfig)) } @@ -21,11 +21,7 @@ class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) ex io.masterBus.cmd.write := io.dBus.cmd.valid && io.dBus.cmd.wr io.masterBus.cmd.address := io.dBus.cmd.valid ? io.dBus.cmd.address | io.iBus.cmd.pc io.masterBus.cmd.data := io.dBus.cmd.data - io.masterBus.cmd.mask := io.dBus.cmd.size.mux( - 0 -> B"0001", - 1 -> B"0011", - default -> B"1111" - ) |<< io.dBus.cmd.address(1 downto 0) + io.masterBus.cmd.mask := io.dBus.genMask(io.dBus.cmd) io.iBus.cmd.ready := io.masterBus.cmd.ready && !io.dBus.cmd.valid io.dBus.cmd.ready := io.masterBus.cmd.ready @@ -53,7 +49,7 @@ class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) ex } -case class MuraxPipelinedMemoryBusRam(onChipRamSize : BigInt, onChipRamHexFile : String, pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) extends Component{ +case class MuraxPipelinedMemoryBusRam(onChipRamSize : BigInt, onChipRamHexFile : String, pipelinedMemoryBusConfig : PipelinedMemoryBusConfig, bigEndian : Boolean = false) extends Component{ val io = new Bundle{ val bus = slave(PipelinedMemoryBus(pipelinedMemoryBusConfig)) } @@ -71,6 +67,14 @@ case class MuraxPipelinedMemoryBusRam(onChipRamSize : BigInt, onChipRamHexFile : if(onChipRamHexFile != null){ HexTools.initRam(ram, onChipRamHexFile, 0x80000000l) + if(bigEndian) + // HexTools.initRam (incorrectly) assumes little endian byte ordering + for((word, wordIndex) <- ram.initialContent.zipWithIndex) + ram.initialContent(wordIndex) = + ((word & 0xffl) << 24) | + ((word & 0xff00l) << 8) | + ((word & 0xff0000l) >> 8) | + ((word & 0xff000000l) >> 24) } } diff --git a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala index e08b640..c9fe212 100644 --- a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala @@ -90,7 +90,7 @@ object DBusSimpleBus{ ) } -case class DBusSimpleBus() extends Bundle with IMasterSlave{ +case class DBusSimpleBus(bigEndian : Boolean = false) extends Bundle with IMasterSlave{ val cmd = Stream(DBusSimpleCmd()) val rsp = DBusSimpleRsp() @@ -100,12 +100,27 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{ } def cmdS2mPipe() : DBusSimpleBus = { - val s = DBusSimpleBus() + val s = DBusSimpleBus(bigEndian) s.cmd << this.cmd.s2mPipe() this.rsp := s.rsp s } + def genMask(cmd : DBusSimpleCmd) = { + if(bigEndian) + cmd.size.mux( + U(0) -> B"1000", + U(1) -> B"1100", + default -> B"1111" + ) |>> cmd.address(1 downto 0) + else + cmd.size.mux( + U(0) -> B"0001", + U(1) -> B"0011", + default -> B"1111" + ) |<< cmd.address(1 downto 0) + } + def toAxi4Shared(stageCmd : Boolean = false, pendingWritesMax : Int = 7): Axi4Shared = { val axi = Axi4Shared(DBusSimpleBus.getAxi4Config()) @@ -130,11 +145,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{ axi.writeData.arbitrationFrom(dataStage) axi.writeData.last := True axi.writeData.data := dataStage.data - axi.writeData.strb := (dataStage.size.mux( - U(0) -> B"0001", - U(1) -> B"0011", - default -> B"1111" - ) << dataStage.address(1 downto 0)).resized + axi.writeData.strb := genMask(dataStage).resized rsp.ready := axi.r.valid @@ -158,11 +169,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{ mm.write := cmdStage.valid && cmdStage.wr mm.address := (cmdStage.address >> 2) @@ U"00" mm.writeData := cmdStage.data(31 downto 0) - mm.byteEnable := (cmdStage.size.mux ( - U(0) -> B"0001", - U(1) -> B"0011", - default -> B"1111" - ) << cmdStage.address(1 downto 0)).resized + mm.byteEnable := genMask(cmdStage).resized cmdStage.ready := mm.waitRequestn @@ -181,11 +188,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{ bus.ADR := cmdStage.address >> 2 bus.CTI :=B"000" bus.BTE := "00" - bus.SEL := (cmdStage.size.mux ( - U(0) -> B"0001", - U(1) -> B"0011", - default -> B"1111" - ) << cmdStage.address(1 downto 0)).resized + bus.SEL := genMask(cmdStage).resized when(!cmdStage.wr) { bus.SEL := "1111" } @@ -209,11 +212,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{ bus.cmd.write := cmd.wr bus.cmd.address := cmd.address.resized bus.cmd.data := cmd.data - bus.cmd.mask := cmd.size.mux( - 0 -> B"0001", - 1 -> B"0011", - default -> B"1111" - ) |<< cmd.address(1 downto 0) + bus.cmd.mask := genMask(cmd) cmd.ready := bus.cmd.ready rsp.ready := bus.rsp.valid @@ -265,11 +264,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{ 1 -> U"01", default -> U"11" ) - bus.cmd.mask := cmd.size.mux( - 0 -> B"0001", - 1 -> B"0011", - default -> B"1111" - ) |<< cmd.address(1 downto 0) + bus.cmd.mask := genMask(cmd) cmd.ready := bus.cmd.ready @@ -289,6 +284,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, emitCmdInMemoryStage : Boolean = false, onlyLoadWords : Boolean = false, withLrSc : Boolean = false, + val bigEndian : Boolean = false, memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] with DBusAccessService { var dBus : DBusSimpleBus = null @@ -393,7 +389,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, import pipeline._ import pipeline.config._ - dBus = master(DBusSimpleBus()).setName("dBus") + dBus = master(DBusSimpleBus(bigEndian)).setName("dBus") decode plug new Area { @@ -436,11 +432,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, insert(MEMORY_ADDRESS_LOW) := dBus.cmd.address(1 downto 0) //formal - val formalMask = dBus.cmd.size.mux( - U(0) -> B"0001", - U(1) -> B"0011", - default -> B"1111" - ) |<< dBus.cmd.address(1 downto 0) + val formalMask = dBus.genMask(dBus.cmd) insert(FORMAL_MEM_ADDR) := dBus.cmd.address & U"xFFFFFFFC" insert(FORMAL_MEM_WMASK) := (dBus.cmd.valid && dBus.cmd.wr) ? formalMask | B"0000" @@ -541,17 +533,32 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, val rspShifted = MEMORY_READ_DATA() rspShifted := input(MEMORY_READ_DATA) - switch(input(MEMORY_ADDRESS_LOW)){ - is(1){rspShifted(7 downto 0) := input(MEMORY_READ_DATA)(15 downto 8)} - is(2){rspShifted(15 downto 0) := input(MEMORY_READ_DATA)(31 downto 16)} - is(3){rspShifted(7 downto 0) := input(MEMORY_READ_DATA)(31 downto 24)} - } + if(bigEndian) + switch(input(MEMORY_ADDRESS_LOW)){ + is(1){rspShifted(31 downto 24) := input(MEMORY_READ_DATA)(23 downto 16)} + is(2){rspShifted(31 downto 16) := input(MEMORY_READ_DATA)(15 downto 0)} + is(3){rspShifted(31 downto 24) := input(MEMORY_READ_DATA)(7 downto 0)} + } + else + switch(input(MEMORY_ADDRESS_LOW)){ + is(1){rspShifted(7 downto 0) := input(MEMORY_READ_DATA)(15 downto 8)} + is(2){rspShifted(15 downto 0) := input(MEMORY_READ_DATA)(31 downto 16)} + is(3){rspShifted(7 downto 0) := input(MEMORY_READ_DATA)(31 downto 24)} + } - val rspFormated = input(INSTRUCTION)(13 downto 12).mux( - 0 -> B((31 downto 8) -> (rspShifted(7) && !input(INSTRUCTION)(14)),(7 downto 0) -> rspShifted(7 downto 0)), - 1 -> B((31 downto 16) -> (rspShifted(15) && ! input(INSTRUCTION)(14)),(15 downto 0) -> rspShifted(15 downto 0)), - default -> rspShifted //W - ) + val rspFormated = + if(bigEndian) + input(INSTRUCTION)(13 downto 12).mux( + 0 -> B((31 downto 8) -> (rspShifted(31) && !input(INSTRUCTION)(14)),(7 downto 0) -> rspShifted(31 downto 24)), + 1 -> B((31 downto 16) -> (rspShifted(31) && ! input(INSTRUCTION)(14)),(15 downto 0) -> rspShifted(31 downto 16)), + default -> rspShifted //W + ) + else + input(INSTRUCTION)(13 downto 12).mux( + 0 -> B((31 downto 8) -> (rspShifted(7) && !input(INSTRUCTION)(14)),(7 downto 0) -> rspShifted(7 downto 0)), + 1 -> B((31 downto 16) -> (rspShifted(15) && ! input(INSTRUCTION)(14)),(15 downto 0) -> rspShifted(15 downto 0)), + default -> rspShifted //W + ) when(arbitration.isValid && input(MEMORY_ENABLE)) { output(REGFILE_WRITE_DATA) := (if(!onlyLoadWords) rspFormated else input(MEMORY_READ_DATA)) diff --git a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala index b8bc978..22c3606 100644 --- a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala @@ -234,7 +234,8 @@ class IBusSimplePlugin( resetVector : BigInt, val singleInstructionPipeline : Boolean = false, val memoryTranslatorPortConfig : Any = null, relaxPredictorAddress : Boolean = true, - predictionBuffer : Boolean = true + predictionBuffer : Boolean = true, + bigEndian : Boolean = false ) extends IBusFetcherImpl( resetVector = resetVector, keepPcPlus4 = keepPcPlus4, @@ -371,6 +372,12 @@ class IBusSimplePlugin( resetVector : BigInt, fetchRsp.pc := stages.last.output.payload fetchRsp.rsp := rspBuffer.output.payload fetchRsp.rsp.error.clearWhen(!rspBuffer.output.valid) //Avoid interference with instruction injection from the debug plugin + if(bigEndian){ + // inst(15 downto 0) should contain lower addressed parcel, + // and inst(31 downto 16) the higher addressed parcel + fetchRsp.rsp.inst.allowOverride + fetchRsp.rsp.inst := rspBuffer.output.payload.inst.rotateLeft(16) + } val join = Stream(FetchRsp()) val exceptionDetected = False From 8e466dd13c8a4c35b7c40a57a8bf772137a39b84 Mon Sep 17 00:00:00 2001 From: Marcus Comstedt Date: Sun, 6 Sep 2020 17:05:31 +0200 Subject: [PATCH 09/30] Add support for RV32E in RegFilePlugin The RV32E extension removes registers x16-x31 from the ISA. This is useful when compiling with -mem2reg to save on BRAMs. On iCE40 HX8K this option saves 1285 LC:s, which also improves the routing situation, when using -mem2reg. Note that the illegal instruction exception required by the RV32E specification for accesses to registers x16-x31 is not implemented. --- .../scala/vexriscv/plugin/RegFilePlugin.scala | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/RegFilePlugin.scala b/src/main/scala/vexriscv/plugin/RegFilePlugin.scala index a34dc46..f2f7a4e 100644 --- a/src/main/scala/vexriscv/plugin/RegFilePlugin.scala +++ b/src/main/scala/vexriscv/plugin/RegFilePlugin.scala @@ -18,6 +18,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind, writeRfInMemoryStage : Boolean = false, readInExecute : Boolean = false, syncUpdateOnStall : Boolean = true, + rv32e : Boolean = false, withShadow : Boolean = false //shadow registers aren't transition hazard free ) extends Plugin[VexRiscv] with RegFileService{ import Riscv._ @@ -39,8 +40,11 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind, val readStage = if(readInExecute) execute else decode val writeStage = if(writeRfInMemoryStage) memory else stages.last + val numRegisters = if(rv32e) 16 else 32 + def clipRange(that : Range) = if(rv32e) that.tail else that + val global = pipeline plug new Area{ - val regFileSize = if(withShadow) 64 else 32 + val regFileSize = if(withShadow) numRegisters * 2 else numRegisters val regFile = Mem(Bits(32 bits),regFileSize) addAttribute(Verilator.public) if(zeroBoot) regFile.init(List.fill(regFileSize)(B(0, 32 bits))) @@ -59,6 +63,9 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind, when(decode.input(INSTRUCTION)(rdRange) === 0) { decode.input(REGFILE_WRITE_VALID) := False } + if(rv32e) when(decode.input(INSTRUCTION)(rdRange.head)) { + decode.input(REGFILE_WRITE_VALID) := False + } //Read register file readStage plug new Area{ @@ -72,8 +79,8 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind, } def shadowPrefix(that : Bits) = if(withShadow) global.shadow.read ## that else that - val regFileReadAddress1 = U(shadowPrefix(srcInstruction(Riscv.rs1Range))) - val regFileReadAddress2 = U(shadowPrefix(srcInstruction(Riscv.rs2Range))) + val regFileReadAddress1 = U(shadowPrefix(srcInstruction(clipRange(Riscv.rs1Range)))) + val regFileReadAddress2 = U(shadowPrefix(srcInstruction(clipRange(Riscv.rs2Range)))) val (rs1Data,rs2Data) = regFileReadyKind match{ case `ASYNC` => (global.regFile.readAsync(regFileReadAddress1),global.regFile.readAsync(regFileReadAddress2)) @@ -93,7 +100,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind, def shadowPrefix(that : Bits) = if(withShadow) global.shadow.write ## that else that val regFileWrite = global.regFile.writePort.addAttribute(Verilator.public).setName("lastStageRegFileWrite") regFileWrite.valid := output(REGFILE_WRITE_VALID) && arbitration.isFiring - regFileWrite.address := U(shadowPrefix(output(INSTRUCTION)(rdRange))) + regFileWrite.address := U(shadowPrefix(output(INSTRUCTION)(clipRange(rdRange)))) regFileWrite.data := output(REGFILE_WRITE_DATA) //Ensure no boot glitches modify X0 From 9d35e75fb5972af8b3f04fb7fc5dc8cf9d9ef6de Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 1 Oct 2020 16:41:24 +0200 Subject: [PATCH 10/30] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bb37f03..57372fc 100644 --- a/README.md +++ b/README.md @@ -283,7 +283,7 @@ Note that sometimes Eclipse needs to be restarted in order to be able to place n ## Briey SoC As a demonstration, a SoC named Briey is implemented in `src/main/scala/vexriscv/demo/Briey.scala`. This SoC is very similar to -the [Pinsec SoC](https://spinalhdl.github.io/SpinalDoc/spinal/lib/pinsec/hardware/): +the [Pinsec SoC](https://spinalhdl.github.io/SpinalDoc-RTD/SpinalHDL/Legacy/pinsec/hardware_toplevel.html#): ![Briey SoC](assets/brieySoc.png?raw=true "") From 6c8e97f825848ff0a1b3544845710f57199883f2 Mon Sep 17 00:00:00 2001 From: Marcus Comstedt Date: Tue, 20 Oct 2020 18:05:31 +0200 Subject: [PATCH 11/30] Update big endian instruction encoding Between draft-20181101-ebe1ca4 and draft-20190622-6993896 of the RISC-V Instruction Set Manual, the wording was changed from requiring "natural endianness" of instruction parcels to require them to be little endian. Update the big endian instruction pipe to reflect the newer requirement. --- src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala index 22c3606..195b7d1 100644 --- a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala @@ -373,10 +373,9 @@ class IBusSimplePlugin( resetVector : BigInt, fetchRsp.rsp := rspBuffer.output.payload fetchRsp.rsp.error.clearWhen(!rspBuffer.output.valid) //Avoid interference with instruction injection from the debug plugin if(bigEndian){ - // inst(15 downto 0) should contain lower addressed parcel, - // and inst(31 downto 16) the higher addressed parcel + // instructions are stored in little endian byteorder fetchRsp.rsp.inst.allowOverride - fetchRsp.rsp.inst := rspBuffer.output.payload.inst.rotateLeft(16) + fetchRsp.rsp.inst := EndiannessSwap(rspBuffer.output.payload.inst) } val join = Stream(FetchRsp()) From fc2c8a7c371db9ee6556c765ddf634fb31b78455 Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Tue, 20 Oct 2020 11:45:22 +0200 Subject: [PATCH 12/30] Initial commit of PMP plugin --- src/main/scala/vexriscv/demo/GenZephyr.scala | 85 ++++++++ .../scala/vexriscv/plugin/CsrPlugin.scala | 25 +++ .../scala/vexriscv/plugin/PmpPlugin.scala | 182 ++++++++++++++++++ 3 files changed, 292 insertions(+) create mode 100644 src/main/scala/vexriscv/demo/GenZephyr.scala create mode 100644 src/main/scala/vexriscv/plugin/PmpPlugin.scala diff --git a/src/main/scala/vexriscv/demo/GenZephyr.scala b/src/main/scala/vexriscv/demo/GenZephyr.scala new file mode 100644 index 0000000..69302e3 --- /dev/null +++ b/src/main/scala/vexriscv/demo/GenZephyr.scala @@ -0,0 +1,85 @@ +package vexriscv.demo + +import vexriscv.plugin._ +import vexriscv.ip.{DataCacheConfig, InstructionCacheConfig} +import vexriscv.{plugin, VexRiscv, VexRiscvConfig} +import spinal.core._ + +object GenZephyr extends App{ + def cpu() = new VexRiscv( + config = VexRiscvConfig( + plugins = List( + new IBusCachedPlugin( + prediction = STATIC, + config = InstructionCacheConfig( + cacheSize = 4096, + bytePerLine = 32, + wayCount = 1, + addressWidth = 32, + cpuDataWidth = 32, + memDataWidth = 32, + catchIllegalAccess = true, + catchAccessFault = true, + asyncTagMemory = false, + twoCycleRam = true, + twoCycleCache = true + ) + ), + new DBusCachedPlugin( + config = new DataCacheConfig( + cacheSize = 4096, + bytePerLine = 32, + wayCount = 1, + addressWidth = 32, + cpuDataWidth = 32, + memDataWidth = 32, + catchAccessError = true, + catchIllegal = true, + catchUnaligned = true + ) + ), + new PmpPlugin( + regions = 16, + ioRange = _(31 downto 28) === 0xF + ), + new DecoderSimplePlugin( + catchIllegalInstruction = true + ), + new RegFilePlugin( + regFileReadyKind = plugin.SYNC, + zeroBoot = false + ), + new IntAluPlugin, + new SrcPlugin( + separatedAddSub = false, + executeInsertion = true + ), + new FullBarrelShifterPlugin, + new HazardSimplePlugin( + bypassExecute = true, + bypassMemory = true, + bypassWriteBack = true, + bypassWriteBackBuffer = true, + pessimisticUseSrc = false, + pessimisticWriteRegFile = false, + pessimisticAddressMatch = false + ), + new MulDivIterativePlugin( + genMul = true, + genDiv = true, + mulUnrollFactor = 1, + divUnrollFactor = 1 + ), + new CsrPlugin(CsrPluginConfig.zephyr(0x00000020l)), + new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))), + new BranchPlugin( + earlyBranch = false, + catchAddressMisaligned = true + ), + new YamlPlugin("cpu0.yaml") + ) + ) + ) + + SpinalVerilog(cpu()) +} diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 668f1b7..224ee09 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -264,6 +264,31 @@ object CsrPluginConfig{ uinstretAccess = CsrAccess.NONE ) + def zephyr(mtvecInit : BigInt) = CsrPluginConfig( + catchIllegalAccess = true, + mvendorid = 1, + marchid = 2, + mimpid = 3, + mhartid = 0, + misaExtensionsInit = 0, + misaAccess = CsrAccess.NONE, + mtvecAccess = CsrAccess.READ_WRITE, + mtvecInit = mtvecInit, + mepcAccess = CsrAccess.READ_WRITE, + mscratchGen = true, + mcauseAccess = CsrAccess.READ_ONLY, + mbadaddrAccess = CsrAccess.READ_ONLY, + mcycleAccess = CsrAccess.NONE, + minstretAccess = CsrAccess.NONE, + ucycleAccess = CsrAccess.NONE, + uinstretAccess = CsrAccess.NONE, + wfiGenAsWait = true, + ecallGen = true, + userGen = true, + medelegAccess = CsrAccess.READ_WRITE, + midelegAccess = CsrAccess.READ_WRITE + ) + } case class CsrWrite(that : Data, bitOffset : Int) case class CsrRead(that : Data , bitOffset : Int) diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala new file mode 100644 index 0000000..839cb8b --- /dev/null +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2020 Samuel Lindemer + * + * SPDX-License-Identifier: MIT + */ + +package vexriscv.plugin + +import vexriscv.{VexRiscv, _} +import spinal.core._ +import spinal.lib._ +import scala.collection.mutable.ArrayBuffer + +/* Each 32-bit pmpcfg# register contains four 8-bit configuration sections. + * These section numbers contain flags which apply to region defined by the + * corresponding pmpaddr# register. + * + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | pmp3cfg | pmp2cfg | pmp1cfg | pmp0cfg | pmpcfg0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | pmp7cfg | pmp6cfg | pmp5cfg | pmp4cfg | pmpcfg2 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 7 6 5 4 3 2 1 0 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | L | 0 | A | X | W | R | pmp#cfg + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * + * L: locks configuration until system reset (including M-mode) + * 0: hardwired to zero + * A: 0 = OFF (null region / disabled) + * 1 = TOR (top of range) + * 2 = NA4 (naturally aligned four-byte region) + * 3 = NAPOT (naturally aligned power-of-two region, > 7 bytes) + * X: execute + * W: write + * R: read + * + * TOR: Each 32-bit pmpaddr# register defines the upper bound of the pmp region + * right-shifted by two bits. The lower bound of the region is the previous + * pmpaddr# register. In the case of pmpaddr0, the lower bound is address 0x0. + * + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | address[33:2] | pmpaddr# + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * NAPOT: Each 32-bit pmpaddr# register defines the regionStart address and the size + * of the pmp region. The number of concurrent 1s begging at the LSB indicates + * the size of the region as a power of two (e.g. 0x...0 = 8-byte, 0x...1 = + * 16-byte, 0x...11 = 32-byte, etc.). + * + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | address[33:2] |0|1|1|1|1| pmpaddr# + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * NA4: This is essentially an edge case of NAPOT where the entire pmpaddr# + * register defines a 4-byte wide region. + */ + +case class PmpRegister() extends Bundle { + + // CSR segments + val x, w, r = Reg(Bool) + val l = Reg(Bool) init(False) + val a = Reg(UInt(2 bits)) init(0) + val address = Reg(UInt(32 bits)) + + // Computed region bounds + val regionStart = UInt(32 bits) + val regionEnd = UInt(32 bits) + val valid = Bool + + // Addressing options + def NA4 = 2 + def NAPOT = 3 + + switch(a) { + is(NA4) { + regionStart := address |<< 2 + regionEnd := regionStart + 4 + valid := True + } + is(NAPOT) { + val mask = address & ~(address + 1) + regionStart := (address & ~mask) |<< 2 + regionEnd := regionStart + ((mask + 1) |<< 3) + valid := True + } + default { + regionStart := 0 + regionEnd := 0 + valid := False + } + } + +} + +case class ProtectedMemoryTranslatorPort(bus : MemoryTranslatorBus) + +class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] with MemoryTranslator { + + // Each pmpcfg# CSR configures four regions. + assert((regions % 4) == 0) + + val pmps = ArrayBuffer[PmpRegister]() + val portsInfo = ArrayBuffer[ProtectedMemoryTranslatorPort]() + + override def newTranslationPort(priority : Int, args : Any): MemoryTranslatorBus = { + val port = ProtectedMemoryTranslatorPort(MemoryTranslatorBus()) + portsInfo += port + port.bus + } + + override def build(pipeline: VexRiscv): Unit = { + import pipeline._ + import pipeline.config._ + import Riscv._ + + val csrService = pipeline.service(classOf[CsrInterface]) + val privilegeService = pipeline.service(classOf[PrivilegeService]) + + val core = pipeline plug new Area { + + // Instantiate pmpaddr0 ... pmpaddr# CSRs. + for (n <- 0 until regions) { + pmps += PmpRegister() + csrService.rw(0x3B0 + n, pmps(n).address) + } + + // Instantiate pmpcfg0 ... pmpcfg# CSRs. + for (n <- 0 until (regions / 4)) { + csrService.rw(0x3A0 + n, + 31 -> pmps((n * 4) + 3).l, 27 -> pmps((n * 4) + 3).a, + 26 -> pmps((n * 4) + 3).x, 25 -> pmps((n * 4) + 3).w, 24 -> pmps((n * 4) + 3).r, + 23 -> pmps((n * 4) + 2).l, 19 -> pmps((n * 4) + 2).a, + 18 -> pmps((n * 4) + 2).x, 17 -> pmps((n * 4) + 2).w, 16 -> pmps((n * 4) + 2).r, + 15 -> pmps((n * 4) + 1).l, 11 -> pmps((n * 4) + 1).a, + 10 -> pmps((n * 4) + 1).x, 9 -> pmps((n * 4) + 1).w, 8 -> pmps((n * 4) + 1).r, + 7 -> pmps((n * 4) ).l, 3 -> pmps((n * 4) ).a, + 2 -> pmps((n * 4) ).x, 1 -> pmps((n * 4) ).w, 0 -> pmps((n * 4) ).r + ) + } + + // Connect memory ports to PMP logic. + val ports = for ((port, portId) <- portsInfo.zipWithIndex) yield new Area { + + val address = port.bus.cmd.virtualAddress + port.bus.rsp.physicalAddress := address + + // Only the first matching PMP region is applied. + val hits = pmps.map(pmp => pmp.valid && + pmp.regionStart <= address && + pmp.regionEnd > address && + (pmp.l || ~privilegeService.isMachine())) + + // M-mode has full access by default. All others have none by default. + when(CountOne(hits) === 0) { + port.bus.rsp.allowRead := privilegeService.isMachine() + port.bus.rsp.allowWrite := privilegeService.isMachine() + port.bus.rsp.allowExecute := privilegeService.isMachine() + } otherwise { + port.bus.rsp.allowRead := MuxOH(OHMasking.first(hits), pmps).r + port.bus.rsp.allowWrite := MuxOH(OHMasking.first(hits), pmps).w + port.bus.rsp.allowExecute := MuxOH(OHMasking.first(hits), pmps).x + } + + port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) + port.bus.rsp.exception := False + port.bus.rsp.refilling := False + port.bus.busy := False + + } + } + } +} + From 4209dc27929da0c55f9e8dcdae2ca27269c0745a Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Wed, 28 Oct 2020 12:57:20 +0100 Subject: [PATCH 13/30] Fix CsrPlugin privilege crossing --- src/main/scala/vexriscv/plugin/CsrPlugin.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 668f1b7..0cb6a79 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -1136,7 +1136,11 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep } } - illegalAccess setWhen(privilege < csrAddress(9 downto 8).asUInt) + when(privilege < csrAddress(9 downto 8).asUInt){ + illegalAccess := True + readInstruction := False + writeInstruction := False + } illegalAccess clearWhen(!arbitration.isValid || !input(IS_CSR)) } } From dc9246715de9ef0618f979f2a9ce15e29677b0fd Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Wed, 28 Oct 2020 12:58:24 +0100 Subject: [PATCH 14/30] Do not allow jtag ebreak outside machine mode --- src/main/scala/vexriscv/plugin/DebugPlugin.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/vexriscv/plugin/DebugPlugin.scala b/src/main/scala/vexriscv/plugin/DebugPlugin.scala index c04d167..516571b 100644 --- a/src/main/scala/vexriscv/plugin/DebugPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DebugPlugin.scala @@ -195,8 +195,9 @@ class DebugPlugin(val debugClockDomain : ClockDomain, hardwareBreakpointCount : } } + val allowEBreak = if(!pipeline.serviceExist(classOf[PrivilegeService])) True else pipeline.service(classOf[PrivilegeService]).isMachine() - decode.insert(DO_EBREAK) := !haltIt && (decode.input(IS_EBREAK) || hardwareBreakpoints.map(hb => hb.valid && hb.pc === (decode.input(PC) >> 1)).foldLeft(False)(_ || _)) + decode.insert(DO_EBREAK) := !haltIt && (decode.input(IS_EBREAK) || hardwareBreakpoints.map(hb => hb.valid && hb.pc === (decode.input(PC) >> 1)).foldLeft(False)(_ || _)) && allowEBreak when(execute.arbitration.isValid && execute.input(DO_EBREAK)){ execute.arbitration.haltByOther := True busReadDataReg := execute.input(PC).asBits From 97fe279f7b0a6f2830fb2b5ff2c87e870216aeff Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Wed, 28 Oct 2020 14:21:47 +0100 Subject: [PATCH 15/30] Enable PMP register lock --- .../scala/vexriscv/plugin/CsrPlugin.scala | 16 +-- .../scala/vexriscv/plugin/PmpPlugin.scala | 107 ++++++++++-------- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 224ee09..d3c0eb6 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -270,18 +270,18 @@ object CsrPluginConfig{ marchid = 2, mimpid = 3, mhartid = 0, - misaExtensionsInit = 0, - misaAccess = CsrAccess.NONE, + misaExtensionsInit = 0x103124, // RV32CFIMNU + misaAccess = CsrAccess.READ_WRITE, mtvecAccess = CsrAccess.READ_WRITE, mtvecInit = mtvecInit, mepcAccess = CsrAccess.READ_WRITE, mscratchGen = true, - mcauseAccess = CsrAccess.READ_ONLY, - mbadaddrAccess = CsrAccess.READ_ONLY, - mcycleAccess = CsrAccess.NONE, - minstretAccess = CsrAccess.NONE, - ucycleAccess = CsrAccess.NONE, - uinstretAccess = CsrAccess.NONE, + mcauseAccess = CsrAccess.READ_WRITE, + mbadaddrAccess = CsrAccess.READ_WRITE, + mcycleAccess = CsrAccess.READ_WRITE, + minstretAccess = CsrAccess.READ_WRITE, + ucycleAccess = CsrAccess.READ_ONLY, + uinstretAccess = CsrAccess.READ_ONLY, wfiGenAsWait = true, ecallGen = true, userGen = true, diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index 839cb8b..ceb219b 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -12,7 +12,7 @@ import spinal.lib._ import scala.collection.mutable.ArrayBuffer /* Each 32-bit pmpcfg# register contains four 8-bit configuration sections. - * These section numbers contain flags which apply to region defined by the + * These section numbers contain flags which apply to regions defined by the * corresponding pmpaddr# register. * * 3 2 1 @@ -48,7 +48,7 @@ import scala.collection.mutable.ArrayBuffer * | address[33:2] | pmpaddr# * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * - * NAPOT: Each 32-bit pmpaddr# register defines the regionStart address and the size + * NAPOT: Each 32-bit pmpaddr# register defines the region address and the size * of the pmp region. The number of concurrent 1s begging at the LSB indicates * the size of the region as a power of two (e.g. 0x...0 = 8-byte, 0x...1 = * 16-byte, 0x...11 = 32-byte, etc.). @@ -63,39 +63,52 @@ import scala.collection.mutable.ArrayBuffer * register defines a 4-byte wide region. */ -case class PmpRegister() extends Bundle { - - // CSR segments - val x, w, r = Reg(Bool) - val l = Reg(Bool) init(False) - val a = Reg(UInt(2 bits)) init(0) - val address = Reg(UInt(32 bits)) - - // Computed region bounds - val regionStart = UInt(32 bits) - val regionEnd = UInt(32 bits) - val valid = Bool +case class PmpRegister() extends Area { // Addressing options def NA4 = 2 def NAPOT = 3 - switch(a) { - is(NA4) { - regionStart := address |<< 2 - regionEnd := regionStart + 4 - valid := True - } - is(NAPOT) { - val mask = address & ~(address + 1) - regionStart := (address & ~mask) |<< 2 - regionEnd := regionStart + ((mask + 1) |<< 3) - valid := True - } - default { - regionStart := 0 - regionEnd := 0 - valid := False + val csr = new Area { + val r, w, x, l = RegInit(False) + val a = Reg(UInt(2 bits)) init(0) + val addr = Reg(UInt(32 bits)) + } + + val region = new Area { + val r, w, x = Reg(Bool) + val l = RegInit(False) + val start = Reg(UInt(32 bits)) + val end = Reg(UInt(32 bits)) + val valid = RegInit(False) + } + + // Internal CSR state is locked until reset if L-bit set + when(~region.l) { + region.r := csr.r + region.w := csr.w + region.x := csr.x + region.l := csr.l + + switch(csr.a) { + is(NA4) { + val shifted = csr.addr |<< 2 + region.start := shifted + region.end := shifted + 4 + region.valid := True + } + is(NAPOT) { + val mask = csr.addr & ~(csr.addr + 1) + val shifted = (csr.addr & ~mask) |<< 2 + region.start := shifted + region.end := shifted + ((mask + 1) |<< 3) + region.valid := True + } + default { + region.start := 0 + region.end := 0 + region.valid := False + } } } @@ -130,20 +143,22 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] // Instantiate pmpaddr0 ... pmpaddr# CSRs. for (n <- 0 until regions) { pmps += PmpRegister() - csrService.rw(0x3B0 + n, pmps(n).address) + csrService.rw(0x3B0 + n, pmps(n).csr.addr) } // Instantiate pmpcfg0 ... pmpcfg# CSRs. for (n <- 0 until (regions / 4)) { csrService.rw(0x3A0 + n, - 31 -> pmps((n * 4) + 3).l, 27 -> pmps((n * 4) + 3).a, - 26 -> pmps((n * 4) + 3).x, 25 -> pmps((n * 4) + 3).w, 24 -> pmps((n * 4) + 3).r, - 23 -> pmps((n * 4) + 2).l, 19 -> pmps((n * 4) + 2).a, - 18 -> pmps((n * 4) + 2).x, 17 -> pmps((n * 4) + 2).w, 16 -> pmps((n * 4) + 2).r, - 15 -> pmps((n * 4) + 1).l, 11 -> pmps((n * 4) + 1).a, - 10 -> pmps((n * 4) + 1).x, 9 -> pmps((n * 4) + 1).w, 8 -> pmps((n * 4) + 1).r, - 7 -> pmps((n * 4) ).l, 3 -> pmps((n * 4) ).a, - 2 -> pmps((n * 4) ).x, 1 -> pmps((n * 4) ).w, 0 -> pmps((n * 4) ).r + 31 -> pmps((n * 4) + 3).csr.l, 23 -> pmps((n * 4) + 2).csr.l, + 15 -> pmps((n * 4) + 1).csr.l, 7 -> pmps((n * 4) ).csr.l, + 27 -> pmps((n * 4) + 3).csr.a, 26 -> pmps((n * 4) + 3).csr.x, + 25 -> pmps((n * 4) + 3).csr.w, 24 -> pmps((n * 4) + 3).csr.r, + 19 -> pmps((n * 4) + 2).csr.a, 18 -> pmps((n * 4) + 2).csr.x, + 17 -> pmps((n * 4) + 2).csr.w, 16 -> pmps((n * 4) + 2).csr.r, + 11 -> pmps((n * 4) + 1).csr.a, 10 -> pmps((n * 4) + 1).csr.x, + 9 -> pmps((n * 4) + 1).csr.w, 8 -> pmps((n * 4) + 1).csr.r, + 3 -> pmps((n * 4) ).csr.a, 2 -> pmps((n * 4) ).csr.x, + 1 -> pmps((n * 4) ).csr.w, 0 -> pmps((n * 4) ).csr.r ) } @@ -154,10 +169,10 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] port.bus.rsp.physicalAddress := address // Only the first matching PMP region is applied. - val hits = pmps.map(pmp => pmp.valid && - pmp.regionStart <= address && - pmp.regionEnd > address && - (pmp.l || ~privilegeService.isMachine())) + val hits = pmps.map(pmp => pmp.region.valid && + pmp.region.start <= address && + pmp.region.end > address && + (pmp.region.l || ~privilegeService.isMachine())) // M-mode has full access by default. All others have none by default. when(CountOne(hits) === 0) { @@ -165,9 +180,9 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] port.bus.rsp.allowWrite := privilegeService.isMachine() port.bus.rsp.allowExecute := privilegeService.isMachine() } otherwise { - port.bus.rsp.allowRead := MuxOH(OHMasking.first(hits), pmps).r - port.bus.rsp.allowWrite := MuxOH(OHMasking.first(hits), pmps).w - port.bus.rsp.allowExecute := MuxOH(OHMasking.first(hits), pmps).x + port.bus.rsp.allowRead := MuxOH(OHMasking.first(hits), pmps.map(_.region.r)) + port.bus.rsp.allowWrite := MuxOH(OHMasking.first(hits), pmps.map(_.region.w)) + port.bus.rsp.allowExecute := MuxOH(OHMasking.first(hits), pmps.map(_.region.x)) } port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) From d1691e94789950d583e2bb75ee7f26da16a128fa Mon Sep 17 00:00:00 2001 From: banahogg Date: Sat, 14 Nov 2020 17:31:50 -0800 Subject: [PATCH 16/30] Update GCC prebuild instructions for sifive.com reorg --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 57372fc..5d9c15e 100644 --- a/README.md +++ b/README.md @@ -412,7 +412,7 @@ Note that VexRiscv can run Linux on both cache full and cache less design. A prebuild GCC toolsuite can be found here: -- https://www.sifive.com/products/tools/ => SiFive GNU Embedded Toolchain +- https://www.sifive.com/software/ => Prebuilt RISC‑V GCC Toolchain and Emulator The VexRiscvSocSoftware makefiles are expecting to find this prebuild version in /opt/riscv/__contentOfThisPreBuild__ From e0ae46e79491383e1c7caa3e438b4b504d229f86 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 16 Nov 2020 12:37:48 +0100 Subject: [PATCH 17/30] Fix Csr ReadWrite interration with DBusCachedPlugin execute halt # Conflicts: # src/main/scala/vexriscv/plugin/CsrPlugin.scala --- src/main/scala/vexriscv/plugin/CsrPlugin.scala | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 0cb6a79..545c5fe 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -1010,18 +1010,8 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep val readData = Bits(32 bits) val writeInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_WRITE_OPCODE) val readInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_READ_OPCODE) - val writeEnable = writeInstruction && ! blockedBySideEffects && !arbitration.isStuckByOthers// && readDataRegValid - val readEnable = readInstruction && ! blockedBySideEffects && !arbitration.isStuckByOthers// && !readDataRegValid - //arbitration.isStuckByOthers, in case of the hazardPlugin is in the executeStage - - -// def readDataReg = memory.input(REGFILE_WRITE_DATA) //PIPE OPT -// val readDataRegValid = Reg(Bool) setWhen(arbitration.isValid) clearWhen(!arbitration.isStuck) -// val writeDataEnable = input(INSTRUCTION)(13) ? writeSrc | B"xFFFFFFFF" -// val writeData = if(noCsrAlu) writeSrc else input(INSTRUCTION)(13).mux( -// False -> writeSrc, -// True -> Mux(input(INSTRUCTION)(12), ~writeSrc, writeSrc) -// ) + val writeEnable = writeInstruction && !arbitration.isStuck + val readEnable = readInstruction && !arbitration.isStuck val readToWriteData = CombInit(readData) val writeData = if(noCsrAlu) writeSrc else input(INSTRUCTION)(13).mux( From 2d0ebf1ef55d12ce79deb42804d8543734ad2b82 Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Wed, 25 Nov 2020 12:28:16 +0100 Subject: [PATCH 18/30] Flush pipeline after PMP CSR writes --- src/main/scala/vexriscv/demo/GenZephyr.scala | 2 +- .../scala/vexriscv/plugin/PmpPlugin.scala | 81 ++++++++++++------- 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/main/scala/vexriscv/demo/GenZephyr.scala b/src/main/scala/vexriscv/demo/GenZephyr.scala index 69302e3..b9d0c7a 100644 --- a/src/main/scala/vexriscv/demo/GenZephyr.scala +++ b/src/main/scala/vexriscv/demo/GenZephyr.scala @@ -40,7 +40,7 @@ object GenZephyr extends App{ ), new PmpPlugin( regions = 16, - ioRange = _(31 downto 28) === 0xF + ioRange = _(31 downto 28) === 0xf ), new DecoderSimplePlugin( catchIllegalInstruction = true diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index ceb219b..fce48be 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -65,30 +65,32 @@ import scala.collection.mutable.ArrayBuffer case class PmpRegister() extends Area { - // Addressing options + // Addressing options (TOR not supported) + def TOR = 1 def NA4 = 2 def NAPOT = 3 + // Software-accessible CSR interface val csr = new Area { - val r, w, x, l = RegInit(False) + val r, w, x = Reg(Bool) + val l = RegInit(False) val a = Reg(UInt(2 bits)) init(0) val addr = Reg(UInt(32 bits)) } + // Active region bounds and permissions (internal) val region = new Area { val r, w, x = Reg(Bool) - val l = RegInit(False) - val start = Reg(UInt(32 bits)) - val end = Reg(UInt(32 bits)) - val valid = RegInit(False) + val lock, valid = RegInit(False) + val start, end = Reg(UInt(32 bits)) } - - // Internal CSR state is locked until reset if L-bit set - when(~region.l) { - region.r := csr.r - region.w := csr.w - region.x := csr.x - region.l := csr.l + + // Internal PMP state is locked until reset once the L-bit is set. + when(~region.lock) { + region.r := csr.r + region.w := csr.w + region.x := csr.x + region.lock := csr.l switch(csr.a) { is(NA4) { @@ -123,6 +125,7 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] val pmps = ArrayBuffer[PmpRegister]() val portsInfo = ArrayBuffer[ProtectedMemoryTranslatorPort]() + var redoInterface : Flow[UInt] = null override def newTranslationPort(priority : Int, args : Any): MemoryTranslatorBus = { val port = ProtectedMemoryTranslatorPort(MemoryTranslatorBus()) @@ -131,35 +134,51 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] } override def build(pipeline: VexRiscv): Unit = { - import pipeline._ import pipeline.config._ + import pipeline._ import Riscv._ val csrService = pipeline.service(classOf[CsrInterface]) val privilegeService = pipeline.service(classOf[PrivilegeService]) + var pcManagerService = pipeline.service(classOf[JumpService]) + + // Flush proceeding instructions and replay them after any CSR write. + redoInterface = pcManagerService.createJumpInterface(pipeline.execute, -1) + redoInterface.valid := False + redoInterface.payload := decode.input(PC) val core = pipeline plug new Area { + redoInterface.valid := False + // Instantiate pmpaddr0 ... pmpaddr# CSRs. - for (n <- 0 until regions) { + for (i <- 0 until regions) { pmps += PmpRegister() - csrService.rw(0x3B0 + n, pmps(n).csr.addr) + csrService.rw(0x3b0 + i, pmps(i).csr.addr) + csrService.onWrite(0x3b0 + i) { + execute.arbitration.flushNext := True + redoInterface.valid := True + } } // Instantiate pmpcfg0 ... pmpcfg# CSRs. - for (n <- 0 until (regions / 4)) { - csrService.rw(0x3A0 + n, - 31 -> pmps((n * 4) + 3).csr.l, 23 -> pmps((n * 4) + 2).csr.l, - 15 -> pmps((n * 4) + 1).csr.l, 7 -> pmps((n * 4) ).csr.l, - 27 -> pmps((n * 4) + 3).csr.a, 26 -> pmps((n * 4) + 3).csr.x, - 25 -> pmps((n * 4) + 3).csr.w, 24 -> pmps((n * 4) + 3).csr.r, - 19 -> pmps((n * 4) + 2).csr.a, 18 -> pmps((n * 4) + 2).csr.x, - 17 -> pmps((n * 4) + 2).csr.w, 16 -> pmps((n * 4) + 2).csr.r, - 11 -> pmps((n * 4) + 1).csr.a, 10 -> pmps((n * 4) + 1).csr.x, - 9 -> pmps((n * 4) + 1).csr.w, 8 -> pmps((n * 4) + 1).csr.r, - 3 -> pmps((n * 4) ).csr.a, 2 -> pmps((n * 4) ).csr.x, - 1 -> pmps((n * 4) ).csr.w, 0 -> pmps((n * 4) ).csr.r + for (i <- 0 until (regions / 4)) { + csrService.rw(0x3a0 + i, + 31 -> pmps((i * 4) + 3).csr.l, 23 -> pmps((i * 4) + 2).csr.l, + 15 -> pmps((i * 4) + 1).csr.l, 7 -> pmps((i * 4) ).csr.l, + 27 -> pmps((i * 4) + 3).csr.a, 26 -> pmps((i * 4) + 3).csr.x, + 25 -> pmps((i * 4) + 3).csr.w, 24 -> pmps((i * 4) + 3).csr.r, + 19 -> pmps((i * 4) + 2).csr.a, 18 -> pmps((i * 4) + 2).csr.x, + 17 -> pmps((i * 4) + 2).csr.w, 16 -> pmps((i * 4) + 2).csr.r, + 11 -> pmps((i * 4) + 1).csr.a, 10 -> pmps((i * 4) + 1).csr.x, + 9 -> pmps((i * 4) + 1).csr.w, 8 -> pmps((i * 4) + 1).csr.r, + 3 -> pmps((i * 4) ).csr.a, 2 -> pmps((i * 4) ).csr.x, + 1 -> pmps((i * 4) ).csr.w, 0 -> pmps((i * 4) ).csr.r ) + csrService.onWrite(0x3a0 + i) { + execute.arbitration.flushNext := True + redoInterface.valid := True + } } // Connect memory ports to PMP logic. @@ -168,13 +187,13 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] val address = port.bus.cmd.virtualAddress port.bus.rsp.physicalAddress := address - // Only the first matching PMP region is applied. + // Only the first matching PMP region applies. val hits = pmps.map(pmp => pmp.region.valid && pmp.region.start <= address && pmp.region.end > address && - (pmp.region.l || ~privilegeService.isMachine())) + (pmp.region.lock || ~privilegeService.isMachine())) - // M-mode has full access by default. All others have none by default. + // M-mode has full access by default, others have none. when(CountOne(hits) === 0) { port.bus.rsp.allowRead := privilegeService.isMachine() port.bus.rsp.allowWrite := privilegeService.isMachine() From 1b65a9e523341980de46b5b3f92b41bc7b6a1903 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 30 Nov 2020 16:11:00 +0100 Subject: [PATCH 19/30] remove libts-dev from readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d9c15e..32b2f8a 100644 --- a/README.md +++ b/README.md @@ -296,7 +296,7 @@ sbt "runMain vexriscv.demo.Briey" To run the verilator simulation of the Briey SoC, which can then be connected to OpenOCD/GDB, first get these dependencies: ```sh -sudo apt-get install build-essential xorg-dev libudev-dev libts-dev libgl1-mesa-dev libglu1-mesa-dev libasound2-dev libpulse-dev libopenal-dev libogg-dev libvorbis-dev libaudiofile-dev libpng12-dev libfreetype6-dev libusb-dev libdbus-1-dev zlib1g-dev libdirectfb-dev libsdl2-dev +sudo apt-get install build-essential xorg-dev libudev-dev libgl1-mesa-dev libglu1-mesa-dev libasound2-dev libpulse-dev libopenal-dev libogg-dev libvorbis-dev libaudiofile-dev libpng12-dev libfreetype6-dev libusb-dev libdbus-1-dev zlib1g-dev libdirectfb-dev libsdl2-dev ``` Then go in `src/test/cpp/briey` and run the simulation with (UART TX is printed in the terminal, VGA is displayed in a GUI): From c5023ad973f4d5532645473bb9f7484aca20385c Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Thu, 26 Nov 2020 15:08:08 +0100 Subject: [PATCH 20/30] Add PMP regression test --- .../scala/vexriscv/plugin/PmpPlugin.scala | 2 - src/test/cpp/raw/pmp/build/pmp.asm | 172 ++++++++++++++++++ src/test/cpp/raw/pmp/build/pmp.elf | Bin 0 -> 5324 bytes src/test/cpp/raw/pmp/build/pmp.hex | 39 ++++ src/test/cpp/raw/pmp/build/pmp.map | 35 ++++ src/test/cpp/raw/pmp/makefile | 3 + src/test/cpp/raw/pmp/src/crt.S | 172 ++++++++++++++++++ src/test/cpp/raw/pmp/src/ld | 16 ++ src/test/cpp/regression/main.cpp | 4 + 9 files changed, 441 insertions(+), 2 deletions(-) create mode 100644 src/test/cpp/raw/pmp/build/pmp.asm create mode 100755 src/test/cpp/raw/pmp/build/pmp.elf create mode 100644 src/test/cpp/raw/pmp/build/pmp.hex create mode 100644 src/test/cpp/raw/pmp/build/pmp.map create mode 100644 src/test/cpp/raw/pmp/makefile create mode 100644 src/test/cpp/raw/pmp/src/crt.S create mode 100644 src/test/cpp/raw/pmp/src/ld 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 0000000000000000000000000000000000000000..22660990f46b47cd5475119569be2e4e97454b49 GIT binary patch literal 5324 zcmeHLO=uHA6#gdLv|8=%+7+d>HVf&Ycu3YZx{wswD*habDR>n^5-SF3x9n^Sg4l)L zO(6%tO9juOH;-1lcq`sT4|>*U?~QNvC)uC{j~?d1%zNLPH}B1SGpDz8ZRt8=46&qe z0D-0ezd-tv5v~+ql7AY5NC)fC1HVtRKbHc;NDEi!7nT&sfMh^2AQ_MhNCqSWk^#wp zWI!??8ITM}2L2NU94w@`o+)scmVK3hTZ&~UFuAE%d`A!bPwA{JABTKr*=ni4Sq(5W zE%PP?-+n^l{majWa_~L-yoRi~hV2(A)X(sV?W~IWD4(!1<3onl^trATZEa%A(8|kH zvuJ2O<9fbm=O;DFx5M>$TBq8&Rx-49hhj>0Uf_JmF2gjm4*BL2b~#~Jg4i&|N%*%C zc9Ze~T;GlKt4P0%^nRqjMEXahJ0)9r2SfRK*muX%Tn+B1bG4=F5iiXVJM*k}-ArB=NZ7y&M8_wN&TfTh+&KjD}ghFr|1vH>(sNtP1eH~2tP_- z+Kbl-e3|fv1fC<@PT(tqtwjDCgsFy4irQQZw@42pFlrl()w_A_*7J4O%Q^6z$_8I? z;jM7b!o6x^H83v*^Gq<$26G{pFJZmPIV#+%x*j~Yx(?*{!v|iqM%r^jeLuFSMuo4` zy@s=fT<{FJs^__l+6L7VXZ%+=M}eZ}HyCd4MGsH(^J1Yp1~N^v0??^KnHvQrV?a9Y rA_|?@jyn|BCZEVN5@{-d<1{E=SC;4#-R`1ZKJgEdak~^({7c+#k7U~* literal 0 HcmV?d00001 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 From d5b1a8f565c44b5966f3378ff67756d8b43537bd Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Tue, 1 Dec 2020 18:35:51 +0100 Subject: [PATCH 21/30] Add PMP test to regression suite --- .../scala/vexriscv/plugin/PmpPlugin.scala | 5 +- src/test/cpp/raw/pmp/build/pmp.asm | 72 +++++++++--------- src/test/cpp/raw/pmp/build/pmp.elf | Bin 5324 -> 5324 bytes src/test/cpp/raw/pmp/build/pmp.hex | 22 +++--- src/test/cpp/raw/pmp/build/pmp.map | 5 +- src/test/cpp/raw/pmp/src/crt.S | 21 +++-- src/test/cpp/regression/main.cpp | 2 +- src/test/cpp/regression/makefile | 5 ++ .../vexriscv/TestIndividualFeatures.scala | 25 ++++-- 9 files changed, 89 insertions(+), 68 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index b2757b8..96599e0 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -140,13 +140,12 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] val privilegeService = pipeline.service(classOf[PrivilegeService]) var pcManagerService = pipeline.service(classOf[JumpService]) - // Flush proceeding instructions and replay them after any CSR write. redoInterface = pcManagerService.createJumpInterface(pipeline.execute, -1) - redoInterface.valid := False - redoInterface.payload := decode.input(PC) val core = pipeline plug new Area { + // Flush proceeding instructions and replay them after any CSR write. + redoInterface.payload := decode.input(PC) redoInterface.valid := False // Instantiate pmpaddr0 ... pmpaddr# CSRs. diff --git a/src/test/cpp/raw/pmp/build/pmp.asm b/src/test/cpp/raw/pmp/build/pmp.asm index 86da5ba..1a12556 100644 --- a/src/test/cpp/raw/pmp/build/pmp.asm +++ b/src/test/cpp/raw/pmp/build/pmp.asm @@ -4,28 +4,26 @@ build/pmp.elf: file format elf32-littleriscv Disassembly of section .crt_section: -80000000 : -80000000: 0240006f j 80000024 <_start> +80000000 <_start>: +80000000: 00000097 auipc ra,0x0 +80000004: 01008093 addi ra,ra,16 # 80000010 +80000008: 30509073 csrw mtvec,ra +8000000c: 0240006f j 80000030 -80000004 : -80000004: 341f1073 csrw mepc,t5 -80000008: 30200073 mret +80000010 : +80000010: 341f1073 csrw mepc,t5 +80000014: 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 +80000018 : +80000018: 00014337 lui t1,0x14 +8000001c: 30033073 csrc mstatus,t1 +80000020: 20000313 li t1,512 +80000024: 30032073 csrs mstatus,t1 +80000028: 34109073 csrw mepc,ra +8000002c: 30200073 mret 80000030 : -80000030: 00000e93 li t4,0 +80000030: 00000e13 li t3,0 80000034: 00000f17 auipc t5,0x0 80000038: 1f0f0f13 addi t5,t5,496 # 80000224 8000003c: 800002b7 lui t0,0x80000 @@ -39,15 +37,15 @@ Disassembly of section .crt_section: 8000005c: 000e2383 lw t2,0(t3) 80000060: 1c731263 bne t1,t2,80000224 80000064: 071a1f37 lui t5,0x71a1 -80000068: 808f0f13 addi t5,t5,-2040 # 71a0808 +80000068: 808f0f13 addi t5,t5,-2040 # 71a0808 <_start-0x78e5f7f8> 8000006c: 3a0f1073 csrw pmpcfg0,t5 80000070: 191c0f37 lui t5,0x191c0 -80000074: 504f0f13 addi t5,t5,1284 # 191c0504 +80000074: 504f0f13 addi t5,t5,1284 # 191c0504 <_start-0x66e3fafc> 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 +80000088: 900f0f13 addi t5,t5,-1792 # f1e1900 <_start-0x70e1e700> 8000008c: 3a3f1073 csrw pmpcfg3,t5 80000090: 20000f37 lui t5,0x20000 80000094: 3b0f1073 csrw pmpaddr0,t5 @@ -56,22 +54,22 @@ Disassembly of section .crt_section: 800000a0: 20002f37 lui t5,0x20002 800000a4: 3b2f1073 csrw pmpaddr2,t5 800000a8: 20004f37 lui t5,0x20004 -800000ac: ffff0f13 addi t5,t5,-1 # 20003fff +800000ac: ffff0f13 addi t5,t5,-1 # 20003fff <_start-0x5fffc001> 800000b0: 3b3f1073 csrw pmpaddr3,t5 800000b4: 20004f37 lui t5,0x20004 -800000b8: ffff0f13 addi t5,t5,-1 # 20003fff +800000b8: ffff0f13 addi t5,t5,-1 # 20003fff <_start-0x5fffc001> 800000bc: 3b4f1073 csrw pmpaddr4,t5 800000c0: 20004f37 lui t5,0x20004 -800000c4: ffff0f13 addi t5,t5,-1 # 20003fff +800000c4: ffff0f13 addi t5,t5,-1 # 20003fff <_start-0x5fffc001> 800000c8: 3b5f1073 csrw pmpaddr5,t5 800000cc: 20002f37 lui t5,0x20002 -800000d0: ffff0f13 addi t5,t5,-1 # 20001fff +800000d0: ffff0f13 addi t5,t5,-1 # 20001fff <_start-0x5fffe001> 800000d4: 3b6f1073 csrw pmpaddr6,t5 800000d8: 20004f37 lui t5,0x20004 -800000dc: ffff0f13 addi t5,t5,-1 # 20003fff +800000dc: ffff0f13 addi t5,t5,-1 # 20003fff <_start-0x5fffc001> 800000e0: 3b7f1073 csrw pmpaddr7,t5 800000e4: 20004f37 lui t5,0x20004 -800000e8: ffff0f13 addi t5,t5,-1 # 20003fff +800000e8: ffff0f13 addi t5,t5,-1 # 20003fff <_start-0x5fffc001> 800000ec: 3b8f1073 csrw pmpaddr8,t5 800000f0: 00000f13 li t5,0 800000f4: 3b9f1073 csrw pmpaddr9,t5 @@ -88,7 +86,7 @@ Disassembly of section .crt_section: 80000120: 00000f13 li t5,0 80000124: 3bff1073 csrw pmpaddr15,t5 80000128: 00c10337 lui t1,0xc10 -8000012c: fee30313 addi t1,t1,-18 # c0ffee +8000012c: fee30313 addi t1,t1,-18 # c0ffee <_start-0x7f3f0012> 80000130: 0062a023 sw t1,0(t0) 80000134: 006e2023 sw t1,0(t3) 80000138: 0002a383 lw t2,0(t0) @@ -97,11 +95,11 @@ Disassembly of section .crt_section: 80000144: 0e731063 bne t1,t2,80000224 80000148 : -80000148: 00100e93 li t4,1 +80000148: 00100e13 li t3,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 +80000158: 808f0f13 addi t5,t5,-2040 # 79a0808 <_start-0x7865f7f8> 8000015c: 3a0f1073 csrw pmpcfg0,t5 80000160: deadc337 lui t1,0xdeadc 80000164: eef30313 addi t1,t1,-273 # deadbeef @@ -112,11 +110,11 @@ Disassembly of section .crt_section: 80000178: 0ac0006f j 80000224 8000017c : -8000017c: 00200e93 li t4,2 +8000017c: 00200e13 li t3,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 +8000018c: 808f0f13 addi t5,t5,-2040 # 71a0808 <_start-0x78e5f7f8> 80000190: 3a0f1073 csrw pmpcfg0,t5 80000194: deadc337 lui t1,0xdeadc 80000198: eef30313 addi t1,t1,-273 # deadbeef @@ -127,15 +125,15 @@ Disassembly of section .crt_section: 800001ac: 0780006f j 80000224 800001b0 : -800001b0: 00300e93 li t4,3 +800001b0: 00300e13 li t3,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 +800001c4: e55ff06f j 80000018 800001c8 : -800001c8: 00400e93 li t4,4 +800001c8: 00400e13 li t3,4 800001cc: 00000f17 auipc t5,0x0 800001d0: 058f0f13 addi t5,t5,88 # 80000224 800001d4: deadc337 lui t1,0xdeadc @@ -147,7 +145,7 @@ Disassembly of section .crt_section: 800001ec: 0380006f j 80000224 800001f0 : -800001f0: 00500e93 li t4,5 +800001f0: 00500e13 li t3,5 800001f4: 00000f17 auipc t5,0x0 800001f8: 03cf0f13 addi t5,t5,60 # 80000230 800001fc: 80010e37 lui t3,0x80010 @@ -164,7 +162,7 @@ Disassembly of section .crt_section: 80000224 : 80000224: f0100137 lui sp,0xf0100 80000228: f2410113 addi sp,sp,-220 # f00fff24 -8000022c: 01d12023 sw t4,0(sp) +8000022c: 01c12023 sw t3,0(sp) 80000230 : 80000230: f0100137 lui sp,0xf0100 diff --git a/src/test/cpp/raw/pmp/build/pmp.elf b/src/test/cpp/raw/pmp/build/pmp.elf index 22660990f46b47cd5475119569be2e4e97454b49..c024632bf007112d3b165f866dd9b3b639d985e9 100755 GIT binary patch delta 262 zcmX@3c}8=B1S7*n$>;n$(-{~TCO0rJ7EcH;m?WUWD7@KFK%9|Lc(SLUF_5eUlN$v^ znd6@dPd+KA4ix(+Xv=tTvc6DZy#WJ515iH@Ffxb(NfjmpUk1qcU_|hhfczRHz6OxL z0g0~%;o&c?48=r!z1xOm1NKS3DuWVDe@|0dYpg$&)<=je%q>nA|8R z$~^zc + * + * SPDX-License-Identifier: MIT + */ + +#define TEST_ID x28 #define TRAP_RA x30 #define PMPCFG0 0x071a0808 @@ -24,15 +30,18 @@ #define PMPADDR14 0x00000000 // NAPOT WX #define PMPADDR15 0x00000000 // TOR RWX -.global trap .global _start +_start: + la x1, trap + csrw mtvec, x1 + j test0 - j _start - +.global trap trap: csrw mepc, TRAP_RA mret +.global to_user to_user: li t1, 0x14000 csrc mstatus, t1 @@ -41,10 +50,6 @@ to_user: csrw mepc, ra mret -_start: - la x1, trap - csrw mtvec, x1 - // configure PMP, attempt read/write from machine mode test0: li TEST_ID, 0 diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index a4d3a3b..e070353 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -3871,7 +3871,7 @@ int main(int argc, char **argv, char **env) { #endif #ifdef PMP - redo(REDO,WorkspaceRegression("pmp").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/lrsc/build/pmp.hex")->bootAt(0x00000000u)->run(10e3);); + redo(REDO,WorkspaceRegression("pmp").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/pmp/build/pmp.hex")->bootAt(0x00000000u)->run(10e3);); #endif #ifdef AMO diff --git a/src/test/cpp/regression/makefile b/src/test/cpp/regression/makefile index 61fe9d1..c71c880 100644 --- a/src/test/cpp/regression/makefile +++ b/src/test/cpp/regression/makefile @@ -15,6 +15,7 @@ CSR_SKIP_TEST?=no EBREAK?=no FENCEI?=no MMU?=yes +PMP?=yes SEED?=no LRSC?=no AMO?=no @@ -217,6 +218,10 @@ ifeq ($(MMU),yes) ADDCFLAGS += -CFLAGS -DMMU endif +ifeq ($(PMP),yes) + ADDCFLAGS += -CFLAGS -DPMP +endif + ifeq ($(MUL),yes) ADDCFLAGS += -CFLAGS -DMUL endif diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 047c719..6d07291 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -48,6 +48,7 @@ class VexRiscvUniverse extends ConfigUniverse object VexRiscvUniverse{ val CATCH_ALL = new VexRiscvUniverse val MMU = new VexRiscvUniverse + val PMP = new VexRiscvUniverse val FORCE_MULDIV = new VexRiscvUniverse val SUPERVISOR = new VexRiscvUniverse val NO_WRITEBACK = new VexRiscvUniverse @@ -468,12 +469,12 @@ class DBusDimension extends VexRiscvDimension("DBus") { } -class MmuDimension extends VexRiscvDimension("DBus") { +class MmuPmpDimension extends VexRiscvDimension("DBus") { override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = { if(universes.contains(VexRiscvUniverse.MMU)) { new VexRiscvPosition("WithMmu") { - override def testParam = "MMU=yes" + override def testParam = "MMU=yes PMP=no" override def applyOn(config: VexRiscvConfig): Unit = { config.plugins += new MmuPlugin( @@ -481,9 +482,20 @@ class MmuDimension extends VexRiscvDimension("DBus") { ) } } + } else if (universes.contains(VexRiscvUniverse.PMP)) { + new VexRiscvPosition("WithPmp") { + override def testParam = "MMU=no PMP=yes" + + override def applyOn(config: VexRiscvConfig): Unit = { + config.plugins += new PmpPlugin( + regions = 16, + ioRange = _ (31 downto 28) === 0xF + ) + } + } } else { - new VexRiscvPosition("NoMmu") { - override def testParam = "MMU=no" + new VexRiscvPosition("NoMemProtect") { + override def testParam = "MMU=no PMP=no" override def applyOn(config: VexRiscvConfig): Unit = { config.plugins += new StaticMemoryTranslatorPlugin( @@ -661,7 +673,7 @@ class TestIndividualFeatures extends MultithreadedFunSuite { new CsrDimension(/*sys.env.getOrElse("VEXRISCV_REGRESSION_FREERTOS_COUNT", "1")*/ "0", zephyrCount, linuxRegression), //Freertos old port software is broken new DecoderDimension, new DebugDimension, - new MmuDimension + new MmuPmpDimension ) var clockCounter = 0l @@ -749,6 +761,7 @@ class TestIndividualFeatures extends MultithreadedFunSuite { } else { if(machineOsRate > rand.nextDouble()) { universe += VexRiscvUniverse.CATCH_ALL + universe += VexRiscvUniverse.PMP if(demwRate < rand.nextDouble()){ universe += VexRiscvUniverse.NO_WRITEBACK } @@ -776,4 +789,4 @@ class TestIndividualFeatures extends MultithreadedFunSuite { val clockPerSecond = (clockCounter/time*1e-3).toLong println(s"Duration=${(time/60).toInt}mn clocks=${(clockCounter*1e-6).toLong}M clockPerSecond=${clockPerSecond}K") } -} \ No newline at end of file +} From 872aa19d83288e7fe781780f5be63024d2024b19 Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Wed, 2 Dec 2020 10:25:15 +0100 Subject: [PATCH 22/30] Add PMP to golden model --- src/test/cpp/raw/pmp/build/pmp.asm | 283 +++++++++++++++-------------- src/test/cpp/raw/pmp/build/pmp.elf | Bin 5324 -> 5328 bytes src/test/cpp/raw/pmp/build/pmp.hex | 70 +++---- src/test/cpp/raw/pmp/build/pmp.map | 12 +- src/test/cpp/raw/pmp/src/crt.S | 165 ++++++++--------- src/test/cpp/regression/main.cpp | 162 ++++++++++++++++- 6 files changed, 423 insertions(+), 269 deletions(-) diff --git a/src/test/cpp/raw/pmp/build/pmp.asm b/src/test/cpp/raw/pmp/build/pmp.asm index 1a12556..48395cf 100644 --- a/src/test/cpp/raw/pmp/build/pmp.asm +++ b/src/test/cpp/raw/pmp/build/pmp.asm @@ -15,156 +15,157 @@ Disassembly of section .crt_section: 80000014: 30200073 mret 80000018 : -80000018: 00014337 lui t1,0x14 -8000001c: 30033073 csrc mstatus,t1 -80000020: 20000313 li t1,512 -80000024: 30032073 csrs mstatus,t1 -80000028: 34109073 csrw mepc,ra +80000018: 00014137 lui sp,0x14 +8000001c: 30013073 csrc mstatus,sp +80000020: 20000113 li sp,512 +80000024: 30012073 csrs mstatus,sp +80000028: 341e9073 csrw mepc,t4 8000002c: 30200073 mret 80000030 : 80000030: 00000e13 li t3,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 <_start-0x78e5f7f8> -8000006c: 3a0f1073 csrw pmpcfg0,t5 -80000070: 191c0f37 lui t5,0x191c0 -80000074: 504f0f13 addi t5,t5,1284 # 191c0504 <_start-0x66e3fafc> -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 <_start-0x70e1e700> -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 <_start-0x5fffc001> -800000b0: 3b3f1073 csrw pmpaddr3,t5 -800000b4: 20004f37 lui t5,0x20004 -800000b8: ffff0f13 addi t5,t5,-1 # 20003fff <_start-0x5fffc001> -800000bc: 3b4f1073 csrw pmpaddr4,t5 -800000c0: 20004f37 lui t5,0x20004 -800000c4: ffff0f13 addi t5,t5,-1 # 20003fff <_start-0x5fffc001> -800000c8: 3b5f1073 csrw pmpaddr5,t5 -800000cc: 20002f37 lui t5,0x20002 -800000d0: ffff0f13 addi t5,t5,-1 # 20001fff <_start-0x5fffe001> -800000d4: 3b6f1073 csrw pmpaddr6,t5 -800000d8: 20004f37 lui t5,0x20004 -800000dc: ffff0f13 addi t5,t5,-1 # 20003fff <_start-0x5fffc001> -800000e0: 3b7f1073 csrw pmpaddr7,t5 -800000e4: 20004f37 lui t5,0x20004 -800000e8: ffff0f13 addi t5,t5,-1 # 20003fff <_start-0x5fffc001> -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 <_start-0x7f3f0012> -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 +80000038: 1f4f0f13 addi t5,t5,500 # 80000228 +8000003c: 800000b7 lui ra,0x80000 +80000040: 80008237 lui tp,0x80008 +80000044: deadc137 lui sp,0xdeadc +80000048: eef10113 addi sp,sp,-273 # deadbeef +8000004c: 0020a023 sw sp,0(ra) # 80000000 +80000050: 00222023 sw sp,0(tp) # 80008000 +80000054: 0000a183 lw gp,0(ra) +80000058: 1c311863 bne sp,gp,80000228 +8000005c: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000060: 1c311463 bne sp,gp,80000228 +80000064: 071a12b7 lui t0,0x71a1 +80000068: 80828293 addi t0,t0,-2040 # 71a0808 <_start-0x78e5f7f8> +8000006c: 3a029073 csrw pmpcfg0,t0 +80000070: 191c02b7 lui t0,0x191c0 +80000074: 50428293 addi t0,t0,1284 # 191c0504 <_start-0x66e3fafc> +80000078: 3a129073 csrw pmpcfg1,t0 +8000007c: 01800293 li t0,24 +80000080: 3a229073 csrw pmpcfg2,t0 +80000084: 0f1e22b7 lui t0,0xf1e2 +80000088: 90028293 addi t0,t0,-1792 # f1e1900 <_start-0x70e1e700> +8000008c: 3a329073 csrw pmpcfg3,t0 +80000090: 200002b7 lui t0,0x20000 +80000094: 3b029073 csrw pmpaddr0,t0 +80000098: fff00293 li t0,-1 +8000009c: 3b129073 csrw pmpaddr1,t0 +800000a0: 200022b7 lui t0,0x20002 +800000a4: 3b229073 csrw pmpaddr2,t0 +800000a8: 200042b7 lui t0,0x20004 +800000ac: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000b0: 3b329073 csrw pmpaddr3,t0 +800000b4: 200042b7 lui t0,0x20004 +800000b8: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000bc: 3b429073 csrw pmpaddr4,t0 +800000c0: 200042b7 lui t0,0x20004 +800000c4: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000c8: 3b529073 csrw pmpaddr5,t0 +800000cc: 200022b7 lui t0,0x20002 +800000d0: fff28293 addi t0,t0,-1 # 20001fff <_start-0x5fffe001> +800000d4: 3b629073 csrw pmpaddr6,t0 +800000d8: 200042b7 lui t0,0x20004 +800000dc: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000e0: 3b729073 csrw pmpaddr7,t0 +800000e4: 200042b7 lui t0,0x20004 +800000e8: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000ec: 3b829073 csrw pmpaddr8,t0 +800000f0: 00000293 li t0,0 +800000f4: 3b929073 csrw pmpaddr9,t0 +800000f8: 00000293 li t0,0 +800000fc: 3ba29073 csrw pmpaddr10,t0 +80000100: 00000293 li t0,0 +80000104: 3bb29073 csrw pmpaddr11,t0 +80000108: 00000293 li t0,0 +8000010c: 3bc29073 csrw pmpaddr12,t0 +80000110: 00000293 li t0,0 +80000114: 3bd29073 csrw pmpaddr13,t0 +80000118: 00000293 li t0,0 +8000011c: 3be29073 csrw pmpaddr14,t0 +80000120: 00000293 li t0,0 +80000124: 3bf29073 csrw pmpaddr15,t0 +80000128: 00c10137 lui sp,0xc10 +8000012c: fee10113 addi sp,sp,-18 # c0ffee <_start-0x7f3f0012> +80000130: 0020a023 sw sp,0(ra) +80000134: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +80000138: 0000a183 lw gp,0(ra) +8000013c: 0e311663 bne sp,gp,80000228 +80000140: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000144: 0e311263 bne sp,gp,80000228 +80000148: 06c0006f j 800001b4 -80000148 : -80000148: 00100e13 li t3,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 <_start-0x7865f7f8> -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 +8000014c : +8000014c: 00100e13 li t3,1 +80000150: 00000f17 auipc t5,0x0 +80000154: 0d8f0f13 addi t5,t5,216 # 80000228 +80000158: 079a12b7 lui t0,0x79a1 +8000015c: 80828293 addi t0,t0,-2040 # 79a0808 <_start-0x7865f7f8> +80000160: 3a029073 csrw pmpcfg0,t0 +80000164: deadc137 lui sp,0xdeadc +80000168: eef10113 addi sp,sp,-273 # deadbeef +8000016c: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +80000170: 00000f17 auipc t5,0x0 +80000174: 010f0f13 addi t5,t5,16 # 80000180 +80000178: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +8000017c: 0ac0006f j 80000228 -8000017c : -8000017c: 00200e13 li t3,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 <_start-0x78e5f7f8> -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 +80000180 : +80000180: 00200e13 li t3,2 +80000184: 00000f17 auipc t5,0x0 +80000188: 0a4f0f13 addi t5,t5,164 # 80000228 +8000018c: 071a12b7 lui t0,0x71a1 +80000190: 80828293 addi t0,t0,-2040 # 71a0808 <_start-0x78e5f7f8> +80000194: 3a029073 csrw pmpcfg0,t0 +80000198: deadc137 lui sp,0xdeadc +8000019c: eef10113 addi sp,sp,-273 # deadbeef +800001a0: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +800001a4: 00000f17 auipc t5,0x0 +800001a8: 010f0f13 addi t5,t5,16 # 800001b4 +800001ac: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +800001b0: 0780006f j 80000228 -800001b0 : -800001b0: 00300e13 li t3,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: e55ff06f j 80000018 +800001b4 : +800001b4: 00300e13 li t3,3 +800001b8: 00000f17 auipc t5,0x0 +800001bc: 070f0f13 addi t5,t5,112 # 80000228 +800001c0: 00000e97 auipc t4,0x0 +800001c4: 00ce8e93 addi t4,t4,12 # 800001cc +800001c8: e51ff06f j 80000018 -800001c8 : -800001c8: 00400e13 li t3,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 +800001cc : +800001cc: 00400e13 li t3,4 +800001d0: 00000f17 auipc t5,0x0 +800001d4: 058f0f13 addi t5,t5,88 # 80000228 +800001d8: deadc137 lui sp,0xdeadc +800001dc: eef10113 addi sp,sp,-273 # deadbeef +800001e0: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +800001e4: 00000f17 auipc t5,0x0 +800001e8: 010f0f13 addi t5,t5,16 # 800001f4 +800001ec: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +800001f0: 0380006f j 80000228 -800001f0 : -800001f0: 00500e13 li t3,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) +800001f4 : +800001f4: 00500e13 li t3,5 +800001f8: 00000f17 auipc t5,0x0 +800001fc: 03cf0f13 addi t5,t5,60 # 80000234 +80000200: 80010237 lui tp,0x80010 +80000204: deadc137 lui sp,0xdeadc +80000208: eef10113 addi sp,sp,-273 # deadbeef +8000020c: 0020a023 sw sp,0(ra) +80000210: 0000a183 lw gp,0(ra) +80000214: 00311a63 bne sp,gp,80000228 +80000218: 00022183 lw gp,0(tp) # 80010000 +8000021c: 00000f17 auipc t5,0x0 +80000220: 018f0f13 addi t5,t5,24 # 80000234 +80000224: 00322023 sw gp,0(tp) # 0 <_start-0x80000000> -80000224 : -80000224: f0100137 lui sp,0xf0100 -80000228: f2410113 addi sp,sp,-220 # f00fff24 -8000022c: 01c12023 sw t3,0(sp) +80000228 : +80000228: f0100137 lui sp,0xf0100 +8000022c: f2410113 addi sp,sp,-220 # f00fff24 +80000230: 01c12023 sw t3,0(sp) -80000230 : -80000230: f0100137 lui sp,0xf0100 -80000234: f2010113 addi sp,sp,-224 # f00fff20 -80000238: 00012023 sw zero,0(sp) +80000234 : +80000234: f0100137 lui sp,0xf0100 +80000238: f2010113 addi sp,sp,-224 # f00fff20 +8000023c: 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 index c024632bf007112d3b165f866dd9b3b639d985e9..9b21344a11a56286768e95efa12760ea87cc49c6 100755 GIT binary patch delta 710 zcmaJ;J4?hs5T0E*4+Im<245VyCWYEaavmHc2C->q(YIRuC!ZhAcwB<*sD)s&@3bIUd8b8Wz<4V-}6)e8= zJu$7+Xdv@XeG}6vN#1o+k&<64jMr!MxKQh`-t7jld0yGZ+Uy{O0OCU+hj>bUxP^Qo z#RriGDL#z+GQ|tX-&5Q}UQq39x^)DW7sRp~+q_y~yQHMLO&jf~IY4IA0@{jNGY2w< K48T)kCi?<-&$jpg literal 5324 zcmeHL&ubGw6#gdLv|4p{?TFPHo5gtODOuadLQ-gp_~TGa!K)CGSTRt$WoKIu#4hx1 z3LXS66+DaHJlf*LTmJ#kgLu_w@5VR#quC$@j~?d1%zNLPH}B1SGpDzCeenik42fiL zfEWd3a(?2`N*NaUr!b6cv~Gs}faYK}1IUq;uE;MfC5i#XfMP%~pcqgLC3xd|AMzv7Zpy!zvOAO) z5av#--^BWTtoLL6CDuP;-K#p<9=P`P_rM*`2tB-`DRi!zF)y7{PX0yzz6m$POUxUS zdtB^}a@~r3wb22Nj@%QBaNSPwj6`p@3%6VU#`XE6e)jM^{;C;hTwjXg_BBUm18*0; z+k}8TUv$KbPPf8Mjy;Un2ZCg{KI=P2nQpk0~ts zTiq0{5VlkK=LnyR>zj1Cn}kUMIZ1pw)P0QRdVA$wNqDVN%kzsa{AJ$iVRW4AV?D-8x8v@zGll{CzhGIkVsR4AVNM^@?$pny2x`plK-QrE diff --git a/src/test/cpp/raw/pmp/build/pmp.hex b/src/test/cpp/raw/pmp/build/pmp.hex index a0a342a..3f75e5d 100644 --- a/src/test/cpp/raw/pmp/build/pmp.hex +++ b/src/test/cpp/raw/pmp/build/pmp.hex @@ -1,39 +1,39 @@ :0200000480007A :100000009700000093800001739050306F00400211 -:1000100073101F34730020303743010073300330F6 -:1000200013030020732003307390103473002030CA -:10003000130E0000170F0000130F0F1FB7020080F0 -:10004000378E008037C3ADDE1303F3EE23A06200CA -:1000500023206E0083A302006316731C83230E000B -:100060006312731C371F1A07130F8F8073100F3A18 -:10007000370F1C19130F4F5073101F3A130F8001C5 -:1000800073102F3A372F1E0F130F0F9073103F3A34 -:10009000370F002073100F3B130FF0FF73101F3B3F -:1000A000372F002073102F3B374F0020130FFFFF17 -:1000B00073103F3B374F0020130FFFFF73104F3B70 -:1000C000374F0020130FFFFF73105F3B372F0020C7 -:1000D000130FFFFF73106F3B374F0020130FFFFF0D -:1000E00073107F3B374F0020130FFFFF73108F3BC0 -:1000F000130F000073109F3B130F00007310AF3BF2 -:10010000130F00007310BF3B130F00007310CF3BA1 -:10011000130F00007310DF3B130F00007310EF3B51 -:10012000130F00007310FF3B3703C1001303E3FEFE -:1001300023A0620023206E0083A302006314730EC9 -:1001400083230E006310730E130E1000170F0000B0 -:10015000130F8F0D371F9A07130F8F8073100F3AED -:1001600037C3ADDE1303F3EE23206E00170F00003C -:10017000130F0F0183230E006F00C00A130E20001F -:10018000170F0000130F4F0A371F1A07130F8F8026 -:1001900073100F3A37C3ADDE1303F3EE23206E0066 -:1001A000170F0000130F0F0183230E006F0080074D -:1001B000130E3000170F0000130F0F0797000000F9 -:1001C0009380C0006FF05FE5130E4000170F000032 -:1001D000130F8F0537C3ADDE1303F3EE23206E003C -:1001E000170F0000130F0F0183230E006F00800311 -:1001F000130E5000170F0000130FCF03370E0180AE -:1002000037C3ADDE1303F3EE23A0620083A3020025 -:10021000631A730083230E00170F0000130F8F0162 -:1002200023207E00370110F0130141F22320C10189 -:0C023000370110F0130101F2232001003F +:1000100073101F34730020303741010073300130FA +:10002000130100207320013073901E3473002030C0 +:10003000130E0000170F0000130F4F1FB7000080B2 +:100040003782008037C1ADDE1301F1EE23A020001E +:100050002320220083A100006318311C83210200A9 +:100060006314311CB7121A07938282807390023A8C +:10007000B7021C19938242507390123A9302800186 +:100080007390223AB7221E0F938202907390323AF5 +:10009000B70200207390023B9302F0FF7390123B73 +:1000A000B72200207390223BB74200209382F2FFD8 +:1000B0007390323BB74200209382F2FF7390423B31 +:1000C000B74200209382F2FF7390523BB722002088 +:1000D0009382F2FF7390623BB74200209382F2FF5B +:1000E0007390723BB74200209382F2FF7390823B81 +:1000F000930200007390923B930200007390A23B26 +:10010000930200007390B23B930200007390C23BD5 +:10011000930200007390D23B930200007390E23B85 +:10012000930200007390F23B3701C1001301E1FE1E +:1001300023A020002320220083A100006316310E9B +:10014000832102006312310E6F00C006130E1000EF +:10015000170F0000130F8F0DB7129A07938282803A +:100160007390023A37C1ADDE1301F1EE2320220075 +:10017000170F0000130F0F01832102006F00C00A48 +:10018000130E2000170F0000130F4F0AB7121A07A3 +:10019000938282807390023A37C1ADDE1301F1EE93 +:1001A00023202200170F0000130F0F0183210200EC +:1001B0006F008007130E3000170F0000130F0F079A +:1001C000970E0000938ECE006FF01FE5130E4000D7 +:1001D000170F0000130F8F0537C1ADDE1301F1EECD +:1001E00023202200170F0000130F0F0183210200AC +:1001F0006F008003130E5000170F0000130FCF0382 +:100200003702018037C1ADDE1301F1EE23A02000DB +:1002100083A10000631A310083210200170F000040 +:10022000130F8F0123203200370110F0130141F228 +:100230002320C101370110F0130101F22320010036 :040000058000000077 :00000001FF diff --git a/src/test/cpp/raw/pmp/build/pmp.map b/src/test/cpp/raw/pmp/build/pmp.map index ede4c4b..f2252f3 100644 --- a/src/test/cpp/raw/pmp/build/pmp.map +++ b/src/test/cpp/raw/pmp/build/pmp.map @@ -15,20 +15,20 @@ LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-e END GROUP LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/libgcc.a -.crt_section 0x0000000080000000 0x23c +.crt_section 0x0000000080000000 0x240 0x0000000080000000 . = ALIGN (0x4) *crt.o(.text) - .text 0x0000000080000000 0x23c build/src/crt.o + .text 0x0000000080000000 0x240 build/src/crt.o 0x0000000080000000 _start 0x0000000080000010 trap 0x0000000080000018 to_user OUTPUT(build/pmp.elf elf32-littleriscv) -.data 0x000000008000023c 0x0 - .data 0x000000008000023c 0x0 build/src/crt.o +.data 0x0000000080000240 0x0 + .data 0x0000000080000240 0x0 build/src/crt.o -.bss 0x000000008000023c 0x0 - .bss 0x000000008000023c 0x0 build/src/crt.o +.bss 0x0000000080000240 0x0 + .bss 0x0000000080000240 0x0 build/src/crt.o .riscv.attributes 0x0000000000000000 0x1e diff --git a/src/test/cpp/raw/pmp/src/crt.S b/src/test/cpp/raw/pmp/src/crt.S index 35a4e1e..6eacc08 100644 --- a/src/test/cpp/raw/pmp/src/crt.S +++ b/src/test/cpp/raw/pmp/src/crt.S @@ -5,6 +5,7 @@ */ #define TEST_ID x28 +#define USER_RA x29 #define TRAP_RA x30 #define PMPCFG0 0x071a0808 @@ -43,11 +44,11 @@ trap: .global to_user to_user: - li t1, 0x14000 - csrc mstatus, t1 - li t1, 0x200 - csrs mstatus, t1 - csrw mepc, ra + li x2, 0x14000 + csrc mstatus, x2 + li x2, 0x200 + csrs mstatus, x2 + csrw mepc, USER_RA mret // configure PMP, attempt read/write from machine mode @@ -55,118 +56,118 @@ 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 x1, 0x80000000 + li x4, 0x80008000 + li x2, 0xdeadbeef + sw x2, 0x0(x1) + sw x2, 0x0(x4) + lw x3, 0x0(x1) + bne x2, x3, fail + lw x3, 0x0(x4) + bne x2, x3, 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 x5, PMPCFG0 + csrw pmpcfg0, x5 + li x5, PMPCFG1 + csrw pmpcfg1, x5 + li x5, PMPCFG2 + csrw pmpcfg2, x5 + li x5, PMPCFG3 + csrw pmpcfg3, x5 + li x5, PMPADDR0 + csrw pmpaddr0, x5 + li x5, PMPADDR1 + csrw pmpaddr1, x5 + li x5, PMPADDR2 + csrw pmpaddr2, x5 + li x5, PMPADDR3 + csrw pmpaddr3, x5 + li x5, PMPADDR4 + csrw pmpaddr4, x5 + li x5, PMPADDR5 + csrw pmpaddr5, x5 + li x5, PMPADDR6 + csrw pmpaddr6, x5 + li x5, PMPADDR7 + csrw pmpaddr7, x5 + li x5, PMPADDR8 + csrw pmpaddr8, x5 + li x5, PMPADDR9 + csrw pmpaddr9, x5 + li x5, PMPADDR10 + csrw pmpaddr10, x5 + li x5, PMPADDR11 + csrw pmpaddr11, x5 + li x5, PMPADDR12 + csrw pmpaddr12, x5 + li x5, PMPADDR13 + csrw pmpaddr13, x5 + li x5, PMPADDR14 + csrw pmpaddr14, x5 + li x5, PMPADDR15 + csrw pmpaddr15, x5 - 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 + li x2, 0x00c0ffee + sw x2, 0x0(x1) + sw x2, 0x0(x4) + lw x3, 0x0(x1) + bne x2, x3, fail + lw x3, 0x0(x4) + bne x2, x3, 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) + li x5, PMPCFG0_ + csrw pmpcfg0, x5 // lock region 2 + li x2, 0xdeadbeef + sw x2, 0x0(x4) // should be OK (write 0x80008000) la TRAP_RA, test2 - lw t2, 0x0(t3) // should fault (read 0x80008000) + lw x3, 0x0(x4) // 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) + li x5, PMPCFG0 + csrw pmpcfg0, x5 // "unlock" region 2 + li x2, 0xdeadbeef + sw x2, 0x0(x4) // should still be OK (write 0x80008000) la TRAP_RA, test3 - lw t2, 0x0(t3) // should still fault (read 0x80008000) + lw x3, 0x0(x4) // should still fault (read 0x80008000) j fail // jump into user mode test3: li TEST_ID, 3 la TRAP_RA, fail - la ra, test4 + la USER_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) + li x2, 0xdeadbeef + sw x2, 0x0(x4) // should be OK (write 0x80008000) la TRAP_RA, test5 - lw t2, 0x0(t3) // should fault (read 0x80008000) + lw x3, 0x0(x4) // 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) + li x4, 0x80010000 + li x2, 0xdeadbeef + sw x2, 0x0(x1) + lw x3, 0x0(x1) + bne x2, x3, fail // should be OK + lw x3, 0x0(x4) // should be OK (read 0x80010000) la TRAP_RA, pass - sw t2, 0x0(t3) // should fault (write 0x80010000) + sw x3, 0x0(x4) // should fault (write 0x80010000) fail: li x2, 0xf00fff24 diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index e070353..dca31a7 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -211,6 +211,26 @@ class success : public std::exception { }; #define MCYCLEH 0xB80 // MRW Upper 32 bits of mcycle, RV32I only. #define MINSTRETH 0xB82 // MRW Upper 32 bits of minstret, RV32I only. +#define PMPCFG0 0x3a0 +#define PMPCFG1 0x3a1 +#define PMPCFG2 0x3a2 +#define PMPCFG3 0x3a3 +#define PMPADDR0 0x3b0 +#define PMPADDR1 0x3b1 +#define PMPADDR2 0x3b2 +#define PMPADDR3 0x3b3 +#define PMPADDR4 0x3b4 +#define PMPADDR5 0x3b5 +#define PMPADDR6 0x3b6 +#define PMPADDR7 0x3b7 +#define PMPADDR8 0x3b8 +#define PMPADDR9 0x3b9 +#define PMPADDR10 0x3ba +#define PMPADDR11 0x3bb +#define PMPADDR12 0x3bc +#define PMPADDR13 0x3bd +#define PMPADDR14 0x3be +#define PMPADDR15 0x3bf #define SSTATUS 0x100 #define SIE 0x104 @@ -373,10 +393,26 @@ public: uint32_t ppn1 : 12; }; }; - - + bool lrscReserved; + struct pmpcfg_s { + uint32_t r : 1; + uint32_t w : 1; + uint32_t x : 1; + uint32_t a : 2; + uint32_t _dummy : 2; + uint32_t l : 1; + } __attribute__((packed)); + + union pmpcfg_u { + uint32_t raw; + pmpcfg_s reg[4]; + }; + + pmpcfg_u pmpcfg[4]; + uint32_t pmpaddr[16]; + RiscvGolden() { pc = 0x80000000; regs[0] = 0; @@ -401,6 +437,10 @@ public: ipInput = 0; stepCounter = 0; lrscReserved = false; + for (int i = 0; i < 4; i++) + pmpcfg[i].raw = 0; + for (int i = 0; i < 16; i++) + pmpaddr[i] = 0; } virtual void rfWrite(int32_t address, int32_t data) { @@ -425,8 +465,55 @@ public: enum AccessKind {READ,WRITE,EXECUTE,READ_WRITE}; 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; + + bool pmpCheck(uint32_t p, AccessKind kind) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (privilege != 3 || pmpcfg[i].reg[3-j].l) { + uint32_t start, end; + bool valid = false; + + switch (pmpcfg[i].reg[3-j].a) { + case 0: // OFF + valid = false; + break; + + case 1: // TOR + valid = false; + break; + + case 2: // NA4 + valid = true; + start = pmpaddr[i*4+j] << 2; + end = start + 4; + break; + + case 3: // NAPOT + valid = true; + uint32_t mask = pmpaddr[i*4+j] & ~(pmpaddr[i*4+j] + 1); + start = (pmpaddr[i*4+j] & ~mask) << 2; + end = start + ((mask + 1) << 3); + break; + } + + if (valid && start <= p && end > p) { + if (kind == READ) return (bool)(!pmpcfg[i].reg[3-j].r); + if (kind == WRITE) return (bool)(!pmpcfg[i].reg[3-j].w); + if (kind == EXECUTE) return (bool)(!pmpcfg[i].reg[3-j].x); + return false; + } + } + } + } + return false; + } + + bool v2p(uint32_t v, uint32_t *p, AccessKind kind) { +#ifdef PMP + *p = v; + return pmpCheck(v, kind); +#else + uint32_t effectivePrivilege = status.mprv && kind != EXECUTE ? status.mpp : privilege; if(effectivePrivilege == 3 || satp.mode == 0 || !isMmuRegion(v)){ *p = v; } else { @@ -449,6 +536,7 @@ public: *p = (tlb.ppn1 << 22) | (superPage ? v & 0x3FF000 : tlb.ppn0 << 12) | (v & 0xFFF); } return false; +#endif } void trap(bool interrupt,int32_t cause) { @@ -528,7 +616,7 @@ public: virtual bool csrRead(int32_t csr, uint32_t *value){ if(((csr >> 8) & 0x3) > privilege) return true; - switch(csr){ + switch(csr) { case MSTATUS: *value = status.raw & MSTATUS_READ_MASK; break; case MIP: *value = getIp().raw; break; case MIE: *value = ie.raw; break; @@ -550,6 +638,28 @@ public: case SEPC: *value = sepc; break; case SSCRATCH: *value = sscratch; break; case SATP: *value = satp.raw; break; + + case PMPCFG0: *value = pmpcfg[0].raw; break; + case PMPCFG1: *value = pmpcfg[1].raw; break; + case PMPCFG2: *value = pmpcfg[2].raw; break; + case PMPCFG3: *value = pmpcfg[3].raw; break; + case PMPADDR0: *value = pmpaddr[0]; break; + case PMPADDR1: *value = pmpaddr[1]; break; + case PMPADDR2: *value = pmpaddr[2]; break; + case PMPADDR3: *value = pmpaddr[3]; break; + case PMPADDR4: *value = pmpaddr[4]; break; + case PMPADDR5: *value = pmpaddr[5]; break; + case PMPADDR6: *value = pmpaddr[6]; break; + case PMPADDR7: *value = pmpaddr[7]; break; + case PMPADDR8: *value = pmpaddr[8]; break; + case PMPADDR9: *value = pmpaddr[9]; break; + case PMPADDR10: *value = pmpaddr[10]; break; + case PMPADDR11: *value = pmpaddr[11]; break; + case PMPADDR12: *value = pmpaddr[12]; break; + case PMPADDR13: *value = pmpaddr[13]; break; + case PMPADDR14: *value = pmpaddr[14]; break; + case PMPADDR15: *value = pmpaddr[15]; break; + default: return true; break; } return false; @@ -591,6 +701,48 @@ public: case SSCRATCH: sscratch = value; break; case SATP: satp.raw = value; break; + case PMPCFG0: + if (!pmpcfg[0].reg[3].l) maskedWrite(pmpcfg[0].raw, value, 0xff); + if (!pmpcfg[0].reg[2].l) maskedWrite(pmpcfg[0].raw, value, 0xff00); + if (!pmpcfg[0].reg[1].l) maskedWrite(pmpcfg[0].raw, value, 0xff0000); + if (!pmpcfg[0].reg[0].l) maskedWrite(pmpcfg[0].raw, value, 0xff000000); + break; + case PMPCFG1: + if (!pmpcfg[1].reg[3].l) maskedWrite(pmpcfg[1].raw, value, 0xff); + if (!pmpcfg[1].reg[2].l) maskedWrite(pmpcfg[1].raw, value, 0xff00); + if (!pmpcfg[1].reg[1].l) maskedWrite(pmpcfg[1].raw, value, 0xff0000); + if (!pmpcfg[1].reg[0].l) maskedWrite(pmpcfg[1].raw, value, 0xff000000); + break; + case PMPCFG2: + if (!pmpcfg[2].reg[3].l) maskedWrite(pmpcfg[2].raw, value, 0xff); + if (!pmpcfg[2].reg[2].l) maskedWrite(pmpcfg[2].raw, value, 0xff00); + if (!pmpcfg[2].reg[1].l) maskedWrite(pmpcfg[2].raw, value, 0xff0000); + if (!pmpcfg[2].reg[0].l) maskedWrite(pmpcfg[2].raw, value, 0xff000000); + break; + case PMPCFG3: + if (!pmpcfg[3].reg[3].l) maskedWrite(pmpcfg[3].raw, value, 0xff); + if (!pmpcfg[3].reg[2].l) maskedWrite(pmpcfg[3].raw, value, 0xff00); + if (!pmpcfg[3].reg[1].l) maskedWrite(pmpcfg[3].raw, value, 0xff0000); + if (!pmpcfg[3].reg[0].l) maskedWrite(pmpcfg[3].raw, value, 0xff000000); + break; + + case PMPADDR0: pmpaddr[0] = value; break; + case PMPADDR1: pmpaddr[1] = value; break; + case PMPADDR2: pmpaddr[2] = value; break; + case PMPADDR3: pmpaddr[3] = value; break; + case PMPADDR4: pmpaddr[4] = value; break; + case PMPADDR5: pmpaddr[5] = value; break; + case PMPADDR6: pmpaddr[6] = value; break; + case PMPADDR7: pmpaddr[7] = value; break; + case PMPADDR8: pmpaddr[8] = value; break; + case PMPADDR9: pmpaddr[9] = value; break; + case PMPADDR10: pmpaddr[10] = value; break; + case PMPADDR11: pmpaddr[11] = value; break; + case PMPADDR12: pmpaddr[12] = value; break; + case PMPADDR13: pmpaddr[13] = value; break; + case PMPADDR14: pmpaddr[14] = value; break; + case PMPADDR15: pmpaddr[15] = value; break; + default: ilegalInstruction(); return true; break; } return false; From 987de8fb6a283a7a5d962d854eb7ab1201f7f22c Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Wed, 2 Dec 2020 14:18:17 +0100 Subject: [PATCH 23/30] Lock PMP address registers in golden model --- src/test/cpp/raw/pmp/build/pmp.asm | 153 ++++++++++++++--------------- src/test/cpp/raw/pmp/build/pmp.elf | Bin 5328 -> 5324 bytes src/test/cpp/raw/pmp/build/pmp.hex | 40 ++++---- src/test/cpp/raw/pmp/build/pmp.map | 12 +-- src/test/cpp/regression/main.cpp | 65 ++++++++---- 5 files changed, 150 insertions(+), 120 deletions(-) diff --git a/src/test/cpp/raw/pmp/build/pmp.asm b/src/test/cpp/raw/pmp/build/pmp.asm index 48395cf..9d5dddf 100644 --- a/src/test/cpp/raw/pmp/build/pmp.asm +++ b/src/test/cpp/raw/pmp/build/pmp.asm @@ -25,17 +25,17 @@ Disassembly of section .crt_section: 80000030 : 80000030: 00000e13 li t3,0 80000034: 00000f17 auipc t5,0x0 -80000038: 1f4f0f13 addi t5,t5,500 # 80000228 +80000038: 1f0f0f13 addi t5,t5,496 # 80000224 8000003c: 800000b7 lui ra,0x80000 80000040: 80008237 lui tp,0x80008 80000044: deadc137 lui sp,0xdeadc -80000048: eef10113 addi sp,sp,-273 # deadbeef -8000004c: 0020a023 sw sp,0(ra) # 80000000 -80000050: 00222023 sw sp,0(tp) # 80008000 +80000048: eef10113 addi sp,sp,-273 # deadbeef +8000004c: 0020a023 sw sp,0(ra) # 80000000 +80000050: 00222023 sw sp,0(tp) # 80008000 80000054: 0000a183 lw gp,0(ra) -80000058: 1c311863 bne sp,gp,80000228 +80000058: 1c311663 bne sp,gp,80000224 8000005c: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000060: 1c311463 bne sp,gp,80000228 +80000060: 1c311263 bne sp,gp,80000224 80000064: 071a12b7 lui t0,0x71a1 80000068: 80828293 addi t0,t0,-2040 # 71a0808 <_start-0x78e5f7f8> 8000006c: 3a029073 csrw pmpcfg0,t0 @@ -90,82 +90,81 @@ Disassembly of section .crt_section: 80000130: 0020a023 sw sp,0(ra) 80000134: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> 80000138: 0000a183 lw gp,0(ra) -8000013c: 0e311663 bne sp,gp,80000228 +8000013c: 0e311463 bne sp,gp,80000224 80000140: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000144: 0e311263 bne sp,gp,80000228 -80000148: 06c0006f j 800001b4 +80000144: 0e311063 bne sp,gp,80000224 -8000014c : -8000014c: 00100e13 li t3,1 -80000150: 00000f17 auipc t5,0x0 -80000154: 0d8f0f13 addi t5,t5,216 # 80000228 -80000158: 079a12b7 lui t0,0x79a1 -8000015c: 80828293 addi t0,t0,-2040 # 79a0808 <_start-0x7865f7f8> -80000160: 3a029073 csrw pmpcfg0,t0 -80000164: deadc137 lui sp,0xdeadc -80000168: eef10113 addi sp,sp,-273 # deadbeef -8000016c: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> -80000170: 00000f17 auipc t5,0x0 -80000174: 010f0f13 addi t5,t5,16 # 80000180 -80000178: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -8000017c: 0ac0006f j 80000228 +80000148 : +80000148: 00100e13 li t3,1 +8000014c: 00000f17 auipc t5,0x0 +80000150: 0d8f0f13 addi t5,t5,216 # 80000224 +80000154: 079a12b7 lui t0,0x79a1 +80000158: 80828293 addi t0,t0,-2040 # 79a0808 <_start-0x7865f7f8> +8000015c: 3a029073 csrw pmpcfg0,t0 +80000160: deadc137 lui sp,0xdeadc +80000164: eef10113 addi sp,sp,-273 # deadbeef +80000168: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +8000016c: 00000f17 auipc t5,0x0 +80000170: 010f0f13 addi t5,t5,16 # 8000017c +80000174: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000178: 0ac0006f j 80000224 -80000180 : -80000180: 00200e13 li t3,2 -80000184: 00000f17 auipc t5,0x0 -80000188: 0a4f0f13 addi t5,t5,164 # 80000228 -8000018c: 071a12b7 lui t0,0x71a1 -80000190: 80828293 addi t0,t0,-2040 # 71a0808 <_start-0x78e5f7f8> -80000194: 3a029073 csrw pmpcfg0,t0 -80000198: deadc137 lui sp,0xdeadc -8000019c: eef10113 addi sp,sp,-273 # deadbeef -800001a0: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> -800001a4: 00000f17 auipc t5,0x0 -800001a8: 010f0f13 addi t5,t5,16 # 800001b4 -800001ac: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -800001b0: 0780006f j 80000228 +8000017c : +8000017c: 00200e13 li t3,2 +80000180: 00000f17 auipc t5,0x0 +80000184: 0a4f0f13 addi t5,t5,164 # 80000224 +80000188: 071a12b7 lui t0,0x71a1 +8000018c: 80828293 addi t0,t0,-2040 # 71a0808 <_start-0x78e5f7f8> +80000190: 3a029073 csrw pmpcfg0,t0 +80000194: deadc137 lui sp,0xdeadc +80000198: eef10113 addi sp,sp,-273 # deadbeef +8000019c: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +800001a0: 00000f17 auipc t5,0x0 +800001a4: 010f0f13 addi t5,t5,16 # 800001b0 +800001a8: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +800001ac: 0780006f j 80000224 -800001b4 : -800001b4: 00300e13 li t3,3 -800001b8: 00000f17 auipc t5,0x0 -800001bc: 070f0f13 addi t5,t5,112 # 80000228 -800001c0: 00000e97 auipc t4,0x0 -800001c4: 00ce8e93 addi t4,t4,12 # 800001cc -800001c8: e51ff06f j 80000018 +800001b0 : +800001b0: 00300e13 li t3,3 +800001b4: 00000f17 auipc t5,0x0 +800001b8: 070f0f13 addi t5,t5,112 # 80000224 +800001bc: 00000e97 auipc t4,0x0 +800001c0: 00ce8e93 addi t4,t4,12 # 800001c8 +800001c4: e55ff06f j 80000018 -800001cc : -800001cc: 00400e13 li t3,4 -800001d0: 00000f17 auipc t5,0x0 -800001d4: 058f0f13 addi t5,t5,88 # 80000228 -800001d8: deadc137 lui sp,0xdeadc -800001dc: eef10113 addi sp,sp,-273 # deadbeef -800001e0: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> -800001e4: 00000f17 auipc t5,0x0 -800001e8: 010f0f13 addi t5,t5,16 # 800001f4 -800001ec: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -800001f0: 0380006f j 80000228 +800001c8 : +800001c8: 00400e13 li t3,4 +800001cc: 00000f17 auipc t5,0x0 +800001d0: 058f0f13 addi t5,t5,88 # 80000224 +800001d4: deadc137 lui sp,0xdeadc +800001d8: eef10113 addi sp,sp,-273 # deadbeef +800001dc: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +800001e0: 00000f17 auipc t5,0x0 +800001e4: 010f0f13 addi t5,t5,16 # 800001f0 +800001e8: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +800001ec: 0380006f j 80000224 -800001f4 : -800001f4: 00500e13 li t3,5 -800001f8: 00000f17 auipc t5,0x0 -800001fc: 03cf0f13 addi t5,t5,60 # 80000234 -80000200: 80010237 lui tp,0x80010 -80000204: deadc137 lui sp,0xdeadc -80000208: eef10113 addi sp,sp,-273 # deadbeef -8000020c: 0020a023 sw sp,0(ra) -80000210: 0000a183 lw gp,0(ra) -80000214: 00311a63 bne sp,gp,80000228 -80000218: 00022183 lw gp,0(tp) # 80010000 -8000021c: 00000f17 auipc t5,0x0 -80000220: 018f0f13 addi t5,t5,24 # 80000234 -80000224: 00322023 sw gp,0(tp) # 0 <_start-0x80000000> +800001f0 : +800001f0: 00500e13 li t3,5 +800001f4: 00000f17 auipc t5,0x0 +800001f8: 03cf0f13 addi t5,t5,60 # 80000230 +800001fc: 80010237 lui tp,0x80010 +80000200: deadc137 lui sp,0xdeadc +80000204: eef10113 addi sp,sp,-273 # deadbeef +80000208: 0020a023 sw sp,0(ra) +8000020c: 0000a183 lw gp,0(ra) +80000210: 00311a63 bne sp,gp,80000224 +80000214: 00022183 lw gp,0(tp) # 80010000 +80000218: 00000f17 auipc t5,0x0 +8000021c: 018f0f13 addi t5,t5,24 # 80000230 +80000220: 00322023 sw gp,0(tp) # 0 <_start-0x80000000> -80000228 : -80000228: f0100137 lui sp,0xf0100 -8000022c: f2410113 addi sp,sp,-220 # f00fff24 -80000230: 01c12023 sw t3,0(sp) +80000224 : +80000224: f0100137 lui sp,0xf0100 +80000228: f2410113 addi sp,sp,-220 # f00fff24 +8000022c: 01c12023 sw t3,0(sp) -80000234 : -80000234: f0100137 lui sp,0xf0100 -80000238: f2010113 addi sp,sp,-224 # f00fff20 -8000023c: 00012023 sw zero,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 index 9b21344a11a56286768e95efa12760ea87cc49c6..381eec7caefa49f471aad8f6fa86a7636b6069c3 100755 GIT binary patch delta 232 zcmcbhc}8=B0^^;Dips1uObiS*8$CbrGxATi7Lel Date: Thu, 3 Dec 2020 17:29:31 +0100 Subject: [PATCH 24/30] PMP passes test with GenZephyr, but pipeline flushes have been disabled --- src/main/scala/vexriscv/demo/GenZephyr.scala | 3 +- .../scala/vexriscv/plugin/PmpPlugin.scala | 8 +- src/test/cpp/raw/pmp/.gdbinit | 3 + src/test/cpp/raw/pmp/build/pmp.asm | 270 +++++++++--------- src/test/cpp/raw/pmp/build/pmp.elf | Bin 5324 -> 5304 bytes src/test/cpp/raw/pmp/build/pmp.hex | 71 +++-- src/test/cpp/raw/pmp/build/pmp.map | 13 +- src/test/cpp/raw/pmp/src/crt.S | 31 +- src/test/cpp/regression/main.cpp | 2 +- 9 files changed, 197 insertions(+), 204 deletions(-) create mode 100644 src/test/cpp/raw/pmp/.gdbinit diff --git a/src/main/scala/vexriscv/demo/GenZephyr.scala b/src/main/scala/vexriscv/demo/GenZephyr.scala index b9d0c7a..4666ec4 100644 --- a/src/main/scala/vexriscv/demo/GenZephyr.scala +++ b/src/main/scala/vexriscv/demo/GenZephyr.scala @@ -5,11 +5,12 @@ import vexriscv.ip.{DataCacheConfig, InstructionCacheConfig} import vexriscv.{plugin, VexRiscv, VexRiscvConfig} import spinal.core._ -object GenZephyr extends App{ +object GenZephyr extends App { def cpu() = new VexRiscv( config = VexRiscvConfig( plugins = List( new IBusCachedPlugin( + resetVector = 0x80000000l, prediction = STATIC, config = InstructionCacheConfig( cacheSize = 4096, diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index 96599e0..2d727fd 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -153,8 +153,8 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] pmps += PmpRegister() csrService.rw(0x3b0 + i, pmps(i).csr.addr) csrService.onWrite(0x3b0 + i) { - execute.arbitration.flushNext := True - redoInterface.valid := True + //execute.arbitration.flushNext := True + //redoInterface.valid := True } } @@ -173,8 +173,8 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] 1 -> pmps((i * 4) ).csr.w, 0 -> pmps((i * 4) ).csr.r ) csrService.onWrite(0x3a0 + i) { - execute.arbitration.flushNext := True - redoInterface.valid := True + //execute.arbitration.flushNext := True + //redoInterface.valid := True } } diff --git a/src/test/cpp/raw/pmp/.gdbinit b/src/test/cpp/raw/pmp/.gdbinit new file mode 100644 index 0000000..45fceb2 --- /dev/null +++ b/src/test/cpp/raw/pmp/.gdbinit @@ -0,0 +1,3 @@ +target remote localhost:3333 +monitor reset halt +load diff --git a/src/test/cpp/raw/pmp/build/pmp.asm b/src/test/cpp/raw/pmp/build/pmp.asm index 9d5dddf..d625d87 100644 --- a/src/test/cpp/raw/pmp/build/pmp.asm +++ b/src/test/cpp/raw/pmp/build/pmp.asm @@ -8,163 +8,159 @@ Disassembly of section .crt_section: 80000000: 00000097 auipc ra,0x0 80000004: 01008093 addi ra,ra,16 # 80000010 80000008: 30509073 csrw mtvec,ra -8000000c: 0240006f j 80000030 +8000000c: 00c0006f j 80000018 80000010 : 80000010: 341f1073 csrw mepc,t5 80000014: 30200073 mret -80000018 : -80000018: 00014137 lui sp,0x14 -8000001c: 30013073 csrc mstatus,sp -80000020: 20000113 li sp,512 -80000024: 30012073 csrs mstatus,sp -80000028: 341e9073 csrw mepc,t4 -8000002c: 30200073 mret - -80000030 : -80000030: 00000e13 li t3,0 -80000034: 00000f17 auipc t5,0x0 -80000038: 1f0f0f13 addi t5,t5,496 # 80000224 -8000003c: 800000b7 lui ra,0x80000 -80000040: 80008237 lui tp,0x80008 -80000044: deadc137 lui sp,0xdeadc -80000048: eef10113 addi sp,sp,-273 # deadbeef -8000004c: 0020a023 sw sp,0(ra) # 80000000 -80000050: 00222023 sw sp,0(tp) # 80008000 -80000054: 0000a183 lw gp,0(ra) -80000058: 1c311663 bne sp,gp,80000224 -8000005c: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000060: 1c311263 bne sp,gp,80000224 -80000064: 071a12b7 lui t0,0x71a1 -80000068: 80828293 addi t0,t0,-2040 # 71a0808 <_start-0x78e5f7f8> -8000006c: 3a029073 csrw pmpcfg0,t0 -80000070: 191c02b7 lui t0,0x191c0 -80000074: 50428293 addi t0,t0,1284 # 191c0504 <_start-0x66e3fafc> -80000078: 3a129073 csrw pmpcfg1,t0 -8000007c: 01800293 li t0,24 -80000080: 3a229073 csrw pmpcfg2,t0 -80000084: 0f1e22b7 lui t0,0xf1e2 -80000088: 90028293 addi t0,t0,-1792 # f1e1900 <_start-0x70e1e700> -8000008c: 3a329073 csrw pmpcfg3,t0 -80000090: 200002b7 lui t0,0x20000 -80000094: 3b029073 csrw pmpaddr0,t0 -80000098: fff00293 li t0,-1 -8000009c: 3b129073 csrw pmpaddr1,t0 -800000a0: 200022b7 lui t0,0x20002 -800000a4: 3b229073 csrw pmpaddr2,t0 +80000018 : +80000018: 00000e13 li t3,0 +8000001c: 00000f17 auipc t5,0x0 +80000020: 1f4f0f13 addi t5,t5,500 # 80000210 +80000024: 800000b7 lui ra,0x80000 +80000028: 80008237 lui tp,0x80008 +8000002c: deadc137 lui sp,0xdeadc +80000030: eef10113 addi sp,sp,-273 # deadbeef +80000034: 0020a023 sw sp,0(ra) # 80000000 +80000038: 00222023 sw sp,0(tp) # 80008000 +8000003c: 0000a183 lw gp,0(ra) +80000040: 1c311863 bne sp,gp,80000210 +80000044: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000048: 1c311463 bne sp,gp,80000210 +8000004c: 071212b7 lui t0,0x7121 +80000050: 80828293 addi t0,t0,-2040 # 7120808 <_start-0x78edf7f8> +80000054: 3a029073 csrw pmpcfg0,t0 +80000058: 191f02b7 lui t0,0x191f0 +8000005c: 30428293 addi t0,t0,772 # 191f0304 <_start-0x66e0fcfc> +80000060: 3a129073 csrw pmpcfg1,t0 +80000064: 01800293 li t0,24 +80000068: 3a229073 csrw pmpcfg2,t0 +8000006c: 0f1e22b7 lui t0,0xf1e2 +80000070: 90028293 addi t0,t0,-1792 # f1e1900 <_start-0x70e1e700> +80000074: 3a329073 csrw pmpcfg3,t0 +80000078: 200002b7 lui t0,0x20000 +8000007c: 3b029073 csrw pmpaddr0,t0 +80000080: fff00293 li t0,-1 +80000084: 3b129073 csrw pmpaddr1,t0 +80000088: 200022b7 lui t0,0x20002 +8000008c: 3b229073 csrw pmpaddr2,t0 +80000090: 200042b7 lui t0,0x20004 +80000094: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +80000098: 3b329073 csrw pmpaddr3,t0 +8000009c: 200042b7 lui t0,0x20004 +800000a0: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000a4: 3b429073 csrw pmpaddr4,t0 800000a8: 200042b7 lui t0,0x20004 800000ac: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> -800000b0: 3b329073 csrw pmpaddr3,t0 -800000b4: 200042b7 lui t0,0x20004 -800000b8: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> -800000bc: 3b429073 csrw pmpaddr4,t0 +800000b0: 3b529073 csrw pmpaddr5,t0 +800000b4: 200022b7 lui t0,0x20002 +800000b8: fff28293 addi t0,t0,-1 # 20001fff <_start-0x5fffe001> +800000bc: 3b629073 csrw pmpaddr6,t0 800000c0: 200042b7 lui t0,0x20004 800000c4: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> -800000c8: 3b529073 csrw pmpaddr5,t0 -800000cc: 200022b7 lui t0,0x20002 -800000d0: fff28293 addi t0,t0,-1 # 20001fff <_start-0x5fffe001> -800000d4: 3b629073 csrw pmpaddr6,t0 -800000d8: 200042b7 lui t0,0x20004 -800000dc: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> -800000e0: 3b729073 csrw pmpaddr7,t0 -800000e4: 200042b7 lui t0,0x20004 -800000e8: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> -800000ec: 3b829073 csrw pmpaddr8,t0 +800000c8: 3b729073 csrw pmpaddr7,t0 +800000cc: 200042b7 lui t0,0x20004 +800000d0: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000d4: 3b829073 csrw pmpaddr8,t0 +800000d8: 00000293 li t0,0 +800000dc: 3b929073 csrw pmpaddr9,t0 +800000e0: 00000293 li t0,0 +800000e4: 3ba29073 csrw pmpaddr10,t0 +800000e8: 00000293 li t0,0 +800000ec: 3bb29073 csrw pmpaddr11,t0 800000f0: 00000293 li t0,0 -800000f4: 3b929073 csrw pmpaddr9,t0 +800000f4: 3bc29073 csrw pmpaddr12,t0 800000f8: 00000293 li t0,0 -800000fc: 3ba29073 csrw pmpaddr10,t0 +800000fc: 3bd29073 csrw pmpaddr13,t0 80000100: 00000293 li t0,0 -80000104: 3bb29073 csrw pmpaddr11,t0 +80000104: 3be29073 csrw pmpaddr14,t0 80000108: 00000293 li t0,0 -8000010c: 3bc29073 csrw pmpaddr12,t0 -80000110: 00000293 li t0,0 -80000114: 3bd29073 csrw pmpaddr13,t0 -80000118: 00000293 li t0,0 -8000011c: 3be29073 csrw pmpaddr14,t0 -80000120: 00000293 li t0,0 -80000124: 3bf29073 csrw pmpaddr15,t0 -80000128: 00c10137 lui sp,0xc10 -8000012c: fee10113 addi sp,sp,-18 # c0ffee <_start-0x7f3f0012> -80000130: 0020a023 sw sp,0(ra) -80000134: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> -80000138: 0000a183 lw gp,0(ra) -8000013c: 0e311463 bne sp,gp,80000224 -80000140: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000144: 0e311063 bne sp,gp,80000224 +8000010c: 3bf29073 csrw pmpaddr15,t0 +80000110: 00c10137 lui sp,0xc10 +80000114: fee10113 addi sp,sp,-18 # c0ffee <_start-0x7f3f0012> +80000118: 0020a023 sw sp,0(ra) +8000011c: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +80000120: 0000a183 lw gp,0(ra) +80000124: 0e311663 bne sp,gp,80000210 +80000128: 00000193 li gp,0 +8000012c: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000130: 0e311063 bne sp,gp,80000210 -80000148 : -80000148: 00100e13 li t3,1 -8000014c: 00000f17 auipc t5,0x0 -80000150: 0d8f0f13 addi t5,t5,216 # 80000224 -80000154: 079a12b7 lui t0,0x79a1 -80000158: 80828293 addi t0,t0,-2040 # 79a0808 <_start-0x7865f7f8> -8000015c: 3a029073 csrw pmpcfg0,t0 -80000160: deadc137 lui sp,0xdeadc -80000164: eef10113 addi sp,sp,-273 # deadbeef -80000168: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +80000134 : +80000134: 00100e13 li t3,1 +80000138: 00000f17 auipc t5,0x0 +8000013c: 0d8f0f13 addi t5,t5,216 # 80000210 +80000140: 079212b7 lui t0,0x7921 +80000144: 80828293 addi t0,t0,-2040 # 7920808 <_start-0x786df7f8> +80000148: 3a029073 csrw pmpcfg0,t0 +8000014c: deadc137 lui sp,0xdeadc +80000150: eef10113 addi sp,sp,-273 # deadbeef +80000154: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +80000158: 00000f17 auipc t5,0x0 +8000015c: 010f0f13 addi t5,t5,16 # 80000168 +80000160: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000164: 0ac0006f j 80000210 + +80000168 : +80000168: 00200e13 li t3,2 8000016c: 00000f17 auipc t5,0x0 -80000170: 010f0f13 addi t5,t5,16 # 8000017c -80000174: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000178: 0ac0006f j 80000224 +80000170: 0a4f0f13 addi t5,t5,164 # 80000210 +80000174: 071212b7 lui t0,0x7121 +80000178: 80828293 addi t0,t0,-2040 # 7120808 <_start-0x78edf7f8> +8000017c: 3a029073 csrw pmpcfg0,t0 +80000180: deadc137 lui sp,0xdeadc +80000184: eef10113 addi sp,sp,-273 # deadbeef +80000188: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +8000018c: 00000f17 auipc t5,0x0 +80000190: 010f0f13 addi t5,t5,16 # 8000019c +80000194: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000198: 0780006f j 80000210 -8000017c : -8000017c: 00200e13 li t3,2 -80000180: 00000f17 auipc t5,0x0 -80000184: 0a4f0f13 addi t5,t5,164 # 80000224 -80000188: 071a12b7 lui t0,0x71a1 -8000018c: 80828293 addi t0,t0,-2040 # 71a0808 <_start-0x78e5f7f8> -80000190: 3a029073 csrw pmpcfg0,t0 -80000194: deadc137 lui sp,0xdeadc -80000198: eef10113 addi sp,sp,-273 # deadbeef -8000019c: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +8000019c : +8000019c: 00300e13 li t3,3 800001a0: 00000f17 auipc t5,0x0 -800001a4: 010f0f13 addi t5,t5,16 # 800001b0 -800001a8: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -800001ac: 0780006f j 80000224 +800001a4: 070f0f13 addi t5,t5,112 # 80000210 +800001a8: 00000117 auipc sp,0x0 +800001ac: 01010113 addi sp,sp,16 # 800001b8 +800001b0: 34111073 csrw mepc,sp +800001b4: 30200073 mret -800001b0 : -800001b0: 00300e13 li t3,3 -800001b4: 00000f17 auipc t5,0x0 -800001b8: 070f0f13 addi t5,t5,112 # 80000224 -800001bc: 00000e97 auipc t4,0x0 -800001c0: 00ce8e93 addi t4,t4,12 # 800001c8 -800001c4: e55ff06f j 80000018 +800001b8 : +800001b8: 00400e13 li t3,4 +800001bc: 00000f17 auipc t5,0x0 +800001c0: 054f0f13 addi t5,t5,84 # 80000210 +800001c4: deadc137 lui sp,0xdeadc +800001c8: eef10113 addi sp,sp,-273 # deadbeef +800001cc: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +800001d0: 00000f17 auipc t5,0x0 +800001d4: 010f0f13 addi t5,t5,16 # 800001e0 +800001d8: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +800001dc: 0340006f j 80000210 -800001c8 : -800001c8: 00400e13 li t3,4 -800001cc: 00000f17 auipc t5,0x0 -800001d0: 058f0f13 addi t5,t5,88 # 80000224 -800001d4: deadc137 lui sp,0xdeadc -800001d8: eef10113 addi sp,sp,-273 # deadbeef -800001dc: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> -800001e0: 00000f17 auipc t5,0x0 -800001e4: 010f0f13 addi t5,t5,16 # 800001f0 -800001e8: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -800001ec: 0380006f j 80000224 +800001e0 : +800001e0: 00500e13 li t3,5 +800001e4: deadc137 lui sp,0xdeadc +800001e8: eef10113 addi sp,sp,-273 # deadbeef +800001ec: 0020a023 sw sp,0(ra) +800001f0: 0000a183 lw gp,0(ra) +800001f4: 00311e63 bne sp,gp,80000210 -800001f0 : -800001f0: 00500e13 li t3,5 -800001f4: 00000f17 auipc t5,0x0 -800001f8: 03cf0f13 addi t5,t5,60 # 80000230 +800001f8 : +800001f8: 00600e13 li t3,6 800001fc: 80010237 lui tp,0x80010 -80000200: deadc137 lui sp,0xdeadc -80000204: eef10113 addi sp,sp,-273 # deadbeef -80000208: 0020a023 sw sp,0(ra) -8000020c: 0000a183 lw gp,0(ra) -80000210: 00311a63 bne sp,gp,80000224 -80000214: 00022183 lw gp,0(tp) # 80010000 -80000218: 00000f17 auipc t5,0x0 -8000021c: 018f0f13 addi t5,t5,24 # 80000230 -80000220: 00322023 sw gp,0(tp) # 0 <_start-0x80000000> +80000200: 00022183 lw gp,0(tp) # 80010000 +80000204: 00000f17 auipc t5,0x0 +80000208: 018f0f13 addi t5,t5,24 # 8000021c +8000020c: 00322023 sw gp,0(tp) # 0 <_start-0x80000000> -80000224 : -80000224: f0100137 lui sp,0xf0100 -80000228: f2410113 addi sp,sp,-220 # f00fff24 -8000022c: 01c12023 sw t3,0(sp) +80000210 : +80000210: f0100137 lui sp,0xf0100 +80000214: f2410113 addi sp,sp,-220 # f00fff24 +80000218: 01c12023 sw t3,0(sp) -80000230 : -80000230: f0100137 lui sp,0xf0100 -80000234: f2010113 addi sp,sp,-224 # f00fff20 -80000238: 00012023 sw zero,0(sp) +8000021c : +8000021c: 29a00e13 li t3,666 +80000220: f0100137 lui sp,0xf0100 +80000224: f2010113 addi sp,sp,-224 # f00fff20 +80000228: 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 index 381eec7caefa49f471aad8f6fa86a7636b6069c3..e5e89ac443042316240eb8b5347ecdc155167933 100755 GIT binary patch delta 447 zcmYk$%}N4M6bJDCnG_*#oS8fMQG<@nq67&iB*79?XdwvI8yFI_G^RzgNpu;JdbTa> z0a~=uWiEskJwx;aVXazr?E~k)J@@>$_nvcKGUH6orssaz31$@_`&gSsR-WK#sk{d} zCsZI70Yv10ceP|H?pocnf~M(OBf|)Br_=U&N^zv565Ofg_(Ge8qOQsWa9NMifUk9j zFLjL!S-DnB9ta}xH2trC`M-aV8~SRsyd=~^6ebU^fRy6<0l9)xogV8mUNyLUY9=gc~kn%=Pl{6&w1%L zpNrC8K9_+cEZ@L=c|k^do-`2ZToSeA^AqoU2d!hz#z%(h#3Dc3eWNw7(1~8Kk Z0&<1<%v=lZ3E+tPrW3r8Rgo*E_y#*BOd0?H delta 477 zcmY+8F-yZx5XbMO2A4KT^FmwG(58)|9h3wLg;KD(XhEdls#GaDxLACOi(*K3t-e8U z(S86yr?@&497Ml>xVe`44ZMa*U#rNV0(edY`ZtyC< zc!z^QloadHex(string(REGRESSION_PATH) + "../raw/pmp/build/pmp.hex")->bootAt(0x00000000u)->run(10e3);); + redo(REDO,WorkspaceRegression("pmp").loadHex(string(REGRESSION_PATH) + "../raw/pmp/build/pmp.hex")->bootAt(0x00000000u)->run(10e3);); #endif #ifdef AMO From 763eebeeba75d508351e81e77e48b675bdfe6c18 Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Fri, 4 Dec 2020 10:11:49 +0100 Subject: [PATCH 25/30] Add TOR support, tests pass on GenZephyr --- .../scala/vexriscv/plugin/PmpPlugin.scala | 71 +++--- src/test/cpp/raw/pmp/build/pmp.asm | 208 ++++++++++-------- src/test/cpp/raw/pmp/build/pmp.elf | Bin 5304 -> 5436 bytes src/test/cpp/raw/pmp/build/pmp.hex | 58 ++--- src/test/cpp/raw/pmp/build/pmp.map | 12 +- src/test/cpp/raw/pmp/src/crt.S | 62 ++++-- src/test/cpp/regression/main.cpp | 165 +------------- .../vexriscv/TestIndividualFeatures.scala | 4 +- 8 files changed, 237 insertions(+), 343 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index 2d727fd..f232ee4 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -63,9 +63,9 @@ import scala.collection.mutable.ArrayBuffer * register defines a 4-byte wide region. */ -case class PmpRegister() extends Area { +case class PmpRegister(previous : PmpRegister) extends Area { - // Addressing options (TOR not supported) + def OFF = 0 def TOR = 1 def NA4 = 2 def NAPOT = 3 @@ -81,37 +81,52 @@ case class PmpRegister() extends Area { // Active region bounds and permissions (internal) val region = new Area { val r, w, x = Reg(Bool) - val lock, valid = RegInit(False) + val l, valid = RegInit(False) val start, end = Reg(UInt(32 bits)) } - // Internal PMP state is locked until reset once the L-bit is set. - when(~region.lock) { - region.r := csr.r - region.w := csr.w - region.x := csr.x - region.lock := csr.l + when(~region.l) { + region.r := csr.r + region.w := csr.w + region.x := csr.x + region.l := csr.l + + val shifted = csr.addr |<< 2 + region.valid := True switch(csr.a) { + + is(TOR) { + if (previous == null) { + region.start := 0 + } else { + region.start := previous.region.end + } + if (csr.l == True) { + previous.region.l := True + } + region.end := shifted + } + is(NA4) { - val shifted = csr.addr |<< 2 region.start := shifted region.end := shifted + 4 - region.valid := True } + is(NAPOT) { val mask = csr.addr & ~(csr.addr + 1) - val shifted = (csr.addr & ~mask) |<< 2 - region.start := shifted - region.end := shifted + ((mask + 1) |<< 3) - region.valid := True + val masked = (csr.addr & ~mask) |<< 2 + region.start := masked + region.end := masked + ((mask + 1) |<< 3) } + default { + region.end := shifted region.valid := False } + } } - } case class ProtectedMemoryTranslatorPort(bus : MemoryTranslatorBus) @@ -123,7 +138,6 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] val pmps = ArrayBuffer[PmpRegister]() val portsInfo = ArrayBuffer[ProtectedMemoryTranslatorPort]() - var redoInterface : Flow[UInt] = null override def newTranslationPort(priority : Int, args : Any): MemoryTranslatorBus = { val port = ProtectedMemoryTranslatorPort(MemoryTranslatorBus()) @@ -138,24 +152,17 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] val csrService = pipeline.service(classOf[CsrInterface]) val privilegeService = pipeline.service(classOf[PrivilegeService]) - var pcManagerService = pipeline.service(classOf[JumpService]) - - redoInterface = pcManagerService.createJumpInterface(pipeline.execute, -1) val core = pipeline plug new Area { - // Flush proceeding instructions and replay them after any CSR write. - redoInterface.payload := decode.input(PC) - redoInterface.valid := False - // Instantiate pmpaddr0 ... pmpaddr# CSRs. for (i <- 0 until regions) { - pmps += PmpRegister() - csrService.rw(0x3b0 + i, pmps(i).csr.addr) - csrService.onWrite(0x3b0 + i) { - //execute.arbitration.flushNext := True - //redoInterface.valid := True + if (i == 0) { + pmps += PmpRegister(null) + } else { + pmps += PmpRegister(pmps.last) } + csrService.rw(0x3b0 + i, pmps(i).csr.addr) } // Instantiate pmpcfg0 ... pmpcfg# CSRs. @@ -172,10 +179,6 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] 3 -> pmps((i * 4) ).csr.a, 2 -> pmps((i * 4) ).csr.x, 1 -> pmps((i * 4) ).csr.w, 0 -> pmps((i * 4) ).csr.r ) - csrService.onWrite(0x3a0 + i) { - //execute.arbitration.flushNext := True - //redoInterface.valid := True - } } // Connect memory ports to PMP logic. @@ -188,7 +191,7 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] val hits = pmps.map(pmp => pmp.region.valid && pmp.region.start <= address && pmp.region.end > address && - (pmp.region.lock || ~privilegeService.isMachine())) + (pmp.region.l || ~privilegeService.isMachine())) // M-mode has full access by default, others have none. when(CountOne(hits) === 0) { diff --git a/src/test/cpp/raw/pmp/build/pmp.asm b/src/test/cpp/raw/pmp/build/pmp.asm index d625d87..294e964 100644 --- a/src/test/cpp/raw/pmp/build/pmp.asm +++ b/src/test/cpp/raw/pmp/build/pmp.asm @@ -17,24 +17,24 @@ Disassembly of section .crt_section: 80000018 : 80000018: 00000e13 li t3,0 8000001c: 00000f17 auipc t5,0x0 -80000020: 1f4f0f13 addi t5,t5,500 # 80000210 +80000020: 250f0f13 addi t5,t5,592 # 8000026c 80000024: 800000b7 lui ra,0x80000 80000028: 80008237 lui tp,0x80008 8000002c: deadc137 lui sp,0xdeadc -80000030: eef10113 addi sp,sp,-273 # deadbeef -80000034: 0020a023 sw sp,0(ra) # 80000000 -80000038: 00222023 sw sp,0(tp) # 80008000 +80000030: eef10113 addi sp,sp,-273 # deadbeef +80000034: 0020a023 sw sp,0(ra) # 80000000 +80000038: 00222023 sw sp,0(tp) # 80008000 8000003c: 0000a183 lw gp,0(ra) -80000040: 1c311863 bne sp,gp,80000210 +80000040: 22311663 bne sp,gp,8000026c 80000044: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000048: 1c311463 bne sp,gp,80000210 -8000004c: 071212b7 lui t0,0x7121 -80000050: 80828293 addi t0,t0,-2040 # 7120808 <_start-0x78edf7f8> -80000054: 3a029073 csrw pmpcfg0,t0 -80000058: 191f02b7 lui t0,0x191f0 -8000005c: 30428293 addi t0,t0,772 # 191f0304 <_start-0x66e0fcfc> -80000060: 3a129073 csrw pmpcfg1,t0 -80000064: 01800293 li t0,24 +80000048: 22311263 bne sp,gp,8000026c +8000004c: 071202b7 lui t0,0x7120 +80000050: 3a029073 csrw pmpcfg0,t0 +80000054: 191f02b7 lui t0,0x191f0 +80000058: 30428293 addi t0,t0,772 # 191f0304 <_start-0x66e0fcfc> +8000005c: 3a129073 csrw pmpcfg1,t0 +80000060: 000f02b7 lui t0,0xf0 +80000064: 50628293 addi t0,t0,1286 # f0506 <_start-0x7ff0fafa> 80000068: 3a229073 csrw pmpcfg2,t0 8000006c: 0f1e22b7 lui t0,0xf1e2 80000070: 90028293 addi t0,t0,-1792 # f1e1900 <_start-0x70e1e700> @@ -57,70 +57,70 @@ Disassembly of section .crt_section: 800000b4: 200022b7 lui t0,0x20002 800000b8: fff28293 addi t0,t0,-1 # 20001fff <_start-0x5fffe001> 800000bc: 3b629073 csrw pmpaddr6,t0 -800000c0: 200042b7 lui t0,0x20004 -800000c4: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000c0: 200062b7 lui t0,0x20006 +800000c4: fff28293 addi t0,t0,-1 # 20005fff <_start-0x5fffa001> 800000c8: 3b729073 csrw pmpaddr7,t0 -800000cc: 200042b7 lui t0,0x20004 -800000d0: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> -800000d4: 3b829073 csrw pmpaddr8,t0 -800000d8: 00000293 li t0,0 -800000dc: 3b929073 csrw pmpaddr9,t0 -800000e0: 00000293 li t0,0 -800000e4: 3ba29073 csrw pmpaddr10,t0 -800000e8: 00000293 li t0,0 -800000ec: 3bb29073 csrw pmpaddr11,t0 -800000f0: 00000293 li t0,0 -800000f4: 3bc29073 csrw pmpaddr12,t0 -800000f8: 00000293 li t0,0 -800000fc: 3bd29073 csrw pmpaddr13,t0 -80000100: 00000293 li t0,0 -80000104: 3be29073 csrw pmpaddr14,t0 -80000108: 00000293 li t0,0 -8000010c: 3bf29073 csrw pmpaddr15,t0 -80000110: 00c10137 lui sp,0xc10 -80000114: fee10113 addi sp,sp,-18 # c0ffee <_start-0x7f3f0012> -80000118: 0020a023 sw sp,0(ra) -8000011c: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> -80000120: 0000a183 lw gp,0(ra) -80000124: 0e311663 bne sp,gp,80000210 -80000128: 00000193 li gp,0 -8000012c: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000130: 0e311063 bne sp,gp,80000210 +800000cc: 2000c2b7 lui t0,0x2000c +800000d0: 3b829073 csrw pmpaddr8,t0 +800000d4: 2000d2b7 lui t0,0x2000d +800000d8: 3b929073 csrw pmpaddr9,t0 +800000dc: fff00293 li t0,-1 +800000e0: 3ba29073 csrw pmpaddr10,t0 +800000e4: 00000293 li t0,0 +800000e8: 3bb29073 csrw pmpaddr11,t0 +800000ec: 00000293 li t0,0 +800000f0: 3bc29073 csrw pmpaddr12,t0 +800000f4: 00000293 li t0,0 +800000f8: 3bd29073 csrw pmpaddr13,t0 +800000fc: 00000293 li t0,0 +80000100: 3be29073 csrw pmpaddr14,t0 +80000104: 00000293 li t0,0 +80000108: 3bf29073 csrw pmpaddr15,t0 +8000010c: 00c10137 lui sp,0xc10 +80000110: fee10113 addi sp,sp,-18 # c0ffee <_start-0x7f3f0012> +80000114: 0020a023 sw sp,0(ra) +80000118: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +8000011c: 0000a183 lw gp,0(ra) +80000120: 14311663 bne sp,gp,8000026c +80000124: 00000193 li gp,0 +80000128: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +8000012c: 14311063 bne sp,gp,8000026c -80000134 : -80000134: 00100e13 li t3,1 -80000138: 00000f17 auipc t5,0x0 -8000013c: 0d8f0f13 addi t5,t5,216 # 80000210 -80000140: 079212b7 lui t0,0x7921 -80000144: 80828293 addi t0,t0,-2040 # 7920808 <_start-0x786df7f8> -80000148: 3a029073 csrw pmpcfg0,t0 +80000130 : +80000130: 00100e13 li t3,1 +80000134: 00000f17 auipc t5,0x0 +80000138: 138f0f13 addi t5,t5,312 # 8000026c +8000013c: 079212b7 lui t0,0x7921 +80000140: 80828293 addi t0,t0,-2040 # 7920808 <_start-0x786df7f8> +80000144: 3a029073 csrw pmpcfg0,t0 +80000148: 800080b7 lui ra,0x80008 8000014c: deadc137 lui sp,0xdeadc -80000150: eef10113 addi sp,sp,-273 # deadbeef -80000154: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +80000150: eef10113 addi sp,sp,-273 # deadbeef +80000154: 0020a023 sw sp,0(ra) # 80008000 80000158: 00000f17 auipc t5,0x0 8000015c: 010f0f13 addi t5,t5,16 # 80000168 -80000160: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000164: 0ac0006f j 80000210 +80000160: 0000a183 lw gp,0(ra) +80000164: 1080006f j 8000026c 80000168 : 80000168: 00200e13 li t3,2 8000016c: 00000f17 auipc t5,0x0 -80000170: 0a4f0f13 addi t5,t5,164 # 80000210 -80000174: 071212b7 lui t0,0x7121 -80000178: 80828293 addi t0,t0,-2040 # 7120808 <_start-0x78edf7f8> -8000017c: 3a029073 csrw pmpcfg0,t0 +80000170: 100f0f13 addi t5,t5,256 # 8000026c +80000174: 071202b7 lui t0,0x7120 +80000178: 3a029073 csrw pmpcfg0,t0 +8000017c: 800080b7 lui ra,0x80008 80000180: deadc137 lui sp,0xdeadc -80000184: eef10113 addi sp,sp,-273 # deadbeef -80000188: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +80000184: eef10113 addi sp,sp,-273 # deadbeef +80000188: 0020a023 sw sp,0(ra) # 80008000 8000018c: 00000f17 auipc t5,0x0 80000190: 010f0f13 addi t5,t5,16 # 8000019c -80000194: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000198: 0780006f j 80000210 +80000194: 0000a183 lw gp,0(ra) +80000198: 0d40006f j 8000026c 8000019c : 8000019c: 00300e13 li t3,3 800001a0: 00000f17 auipc t5,0x0 -800001a4: 070f0f13 addi t5,t5,112 # 80000210 +800001a4: 0ccf0f13 addi t5,t5,204 # 8000026c 800001a8: 00000117 auipc sp,0x0 800001ac: 01010113 addi sp,sp,16 # 800001b8 800001b0: 34111073 csrw mepc,sp @@ -129,38 +129,64 @@ Disassembly of section .crt_section: 800001b8 : 800001b8: 00400e13 li t3,4 800001bc: 00000f17 auipc t5,0x0 -800001c0: 054f0f13 addi t5,t5,84 # 80000210 +800001c0: 0b0f0f13 addi t5,t5,176 # 8000026c 800001c4: deadc137 lui sp,0xdeadc -800001c8: eef10113 addi sp,sp,-273 # deadbeef -800001cc: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> -800001d0: 00000f17 auipc t5,0x0 -800001d4: 010f0f13 addi t5,t5,16 # 800001e0 -800001d8: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -800001dc: 0340006f j 80000210 +800001c8: eef10113 addi sp,sp,-273 # deadbeef +800001cc: 800080b7 lui ra,0x80008 +800001d0: 0020a023 sw sp,0(ra) # 80008000 +800001d4: 00000f17 auipc t5,0x0 +800001d8: 010f0f13 addi t5,t5,16 # 800001e4 +800001dc: 0000a183 lw gp,0(ra) +800001e0: 08c0006f j 8000026c -800001e0 : -800001e0: 00500e13 li t3,5 -800001e4: deadc137 lui sp,0xdeadc -800001e8: eef10113 addi sp,sp,-273 # deadbeef -800001ec: 0020a023 sw sp,0(ra) -800001f0: 0000a183 lw gp,0(ra) -800001f4: 00311e63 bne sp,gp,80000210 +800001e4 : +800001e4: 00500e13 li t3,5 +800001e8: deadc137 lui sp,0xdeadc +800001ec: eef10113 addi sp,sp,-273 # deadbeef +800001f0: 800000b7 lui ra,0x80000 +800001f4: 0020a023 sw sp,0(ra) # 80000000 +800001f8: 0000a183 lw gp,0(ra) +800001fc: 06311863 bne sp,gp,8000026c -800001f8 : -800001f8: 00600e13 li t3,6 -800001fc: 80010237 lui tp,0x80010 -80000200: 00022183 lw gp,0(tp) # 80010000 -80000204: 00000f17 auipc t5,0x0 -80000208: 018f0f13 addi t5,t5,24 # 8000021c -8000020c: 00322023 sw gp,0(tp) # 0 <_start-0x80000000> +80000200 : +80000200: 00600e13 li t3,6 +80000204: 800100b7 lui ra,0x80010 +80000208: 0000a183 lw gp,0(ra) # 80010000 +8000020c: 00000f17 auipc t5,0x0 +80000210: 06cf0f13 addi t5,t5,108 # 80000278 +80000214: 0030a023 sw gp,0(ra) +80000218: 0540006f j 8000026c -80000210 : -80000210: f0100137 lui sp,0xf0100 -80000214: f2410113 addi sp,sp,-220 # f00fff24 -80000218: 01c12023 sw t3,0(sp) +8000021c : +8000021c: 00700e13 li t3,7 +80000220: 00000f17 auipc t5,0x0 +80000224: 04cf0f13 addi t5,t5,76 # 8000026c +80000228: deadc137 lui sp,0xdeadc +8000022c: eef10113 addi sp,sp,-273 # deadbeef +80000230: 800300b7 lui ra,0x80030 +80000234: ff808093 addi ra,ra,-8 # 8002fff8 +80000238: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +8000023c: 00000f17 auipc t5,0x0 +80000240: fa8f0f13 addi t5,t5,-88 # 800001e4 +80000244: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000248: 0240006f j 8000026c -8000021c : -8000021c: 29a00e13 li t3,666 -80000220: f0100137 lui sp,0xf0100 -80000224: f2010113 addi sp,sp,-224 # f00fff20 -80000228: 00012023 sw zero,0(sp) +8000024c : +8000024c: 00800e13 li t3,8 +80000250: 800400b7 lui ra,0x80040 +80000254: ff808093 addi ra,ra,-8 # 8003fff8 +80000258: 0000a183 lw gp,0(ra) +8000025c: 00000f17 auipc t5,0x0 +80000260: 01cf0f13 addi t5,t5,28 # 80000278 +80000264: 0030a023 sw gp,0(ra) +80000268: 0040006f j 8000026c + +8000026c : +8000026c: f0100137 lui sp,0xf0100 +80000270: f2410113 addi sp,sp,-220 # f00fff24 +80000274: 01c12023 sw t3,0(sp) + +80000278 : +80000278: f0100137 lui sp,0xf0100 +8000027c: f2010113 addi sp,sp,-224 # f00fff20 +80000280: 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 index e5e89ac443042316240eb8b5347ecdc155167933..75d1010c91fc4338946e1dadf660f4690f889fa6 100755 GIT binary patch delta 682 zcmaJ-ze^lJ7=1IjQ$gLG+gWl-1Sh)$Q3&jTaKS4)6B3YEC`3DZ{Y*JZ^v9vkA+4INRhbA0euvVZ5{zCx%1?0g5-AJ>ANryT2EEy%dnAE$gK7hQ8EUTyn^0lA~7`O*=nx`1?d zW#;Ymn-;NqYY>w9d)B~#obo_)ij5t6Om@y4(kk6X$i>~i$!HRhKi)q zyfqxWjUgjL8^y!nzXznVh&v8NXE}LPBeg#1yhjG6E$-<$ec^sYOE=5X`HbpH{uxdxG67n+^%MbTpZj^811zyD>zai3`c*E<<(9jPi8l6Ng4#3}bXg=FppM zow56`GxoN?Y7*Qk;Mau53ivJIg#un8Or>oTU|2QJhj_CN+g}(h+pKNMen@@N kpBVn(5tGs`k-{}C|4I3$1X|{+AC6RfAm7N^Q4uY#YnVKmx&QzG delta 539 zcmZ`#KTE?<5WkCtVxcdud66mx`)mfObZDedNEK^EK`5x;;wE%)6U->mkWLO_?E31(XDOAqeP@9y2*@7>edV>aN*3%ko?)SLp4>+HX3dk5(d zz$^MvyX`lIpC49>gT*t@xCf{$*k)rzftq2Pp{~b-?|W{bIH8hW6n-V|2D&2@55*Zh zu`0lYKlpZoi&8j_{gRNo+@KkG(W5(cA`l>&N^Qajg_H)swA)0eH^&>sY$TK4x`xA^ zb9jz3!biD-_#~_8Jzk8F{HUj{#Zr<0LqwM*3oh_HBjvw=>hvMy8Ac9aT$g8xPPA+T zBd1VQ&>IpQeFiPQ4n?GWhT8*+caf1+Hp1dczf4jEJctCrl)fP5*w$tb|Fe$Feof%A z#O6fTuEbKjp`n0K6%XuKs73>G;@YsJZ5ykJst(YXFJ`4C#JjPiZZLo&f%BGnBO^z2 G4E6){C3wI9 diff --git a/src/test/cpp/raw/pmp/build/pmp.hex b/src/test/cpp/raw/pmp/build/pmp.hex index c87e1d4..e3fdeab 100644 --- a/src/test/cpp/raw/pmp/build/pmp.hex +++ b/src/test/cpp/raw/pmp/build/pmp.hex @@ -1,38 +1,44 @@ :0200000480007A :100000009700000093800001739050306F00C00093 :1000100073101F3473002030130E0000170F000000 -:10002000130F4F1FB70000803782008037C1ADDE4D +:10002000130F0F25B70000803782008037C1ADDE87 :100030001301F1EE23A020002320220083A1000061 -:100040006318311C832102006314311CB71212079C -:10005000938282807390023AB7021F1993824230D2 -:100060007390123A930280017390223AB7221E0FC6 +:10004000631631228321020063123122B7021207A4 +:100050007390023AB7021F19938242307390123A9A +:10006000B7020F00938262507390223AB7221E0F9C :10007000938202907390323AB70200207390023B51 :100080009302F0FF7390123BB72200207390223B43 :10009000B74200209382F2FF7390323BB7420020B8 :1000A0009382F2FF7390423BB74200209382F2FFAB :1000B0007390523BB72200209382F2FF7390623B11 -:1000C000B74200209382F2FF7390723BB742002048 -:1000D0009382F2FF7390823B930200007390923BF5 -:1000E000930200007390A23B930200007390B23B16 -:1000F000930200007390C23B930200007390D23BC6 -:10010000930200007390E23B930200007390F23B75 -:100110003701C1001301E1FE23A0200023202200AB -:1001200083A100006316310E9301000083210200B9 -:100130006310310E130E1000170F0000130F8F0DF8 -:10014000B7129207938282807390023A37C1ADDE74 -:100150001301F1EE23202200170F0000130F0F01EF -:10016000832102006F00C00A130E2000170F000049 -:10017000130F4F0AB7121207938282807390023ACC -:1001800037C1ADDE1301F1EE23202200170F00006E -:10019000130F0F01832102006F008007130E300040 -:1001A000170F0000130F0F071701000013010101C3 +:1000C000B76200209382F2FF7390723BB7C20020A8 +:1000D0007390823BB7D200207390923B9302F0FF63 +:1000E0007390A23B930200007390B23B9302000016 +:1000F0007390C23B930200007390D23B93020000C6 +:100100007390E23B930200007390F23B3701C10011 +:100110001301E1FE23A020002320220083A1000080 +:10012000631631149301000083210200631031141F +:10013000130E1000170F0000130F8F13B712920742 +:10014000938282807390023AB780008037C1ADDE1F +:100150001301F1EE23A02000170F0000130F0F0171 +:1001600083A100006F008010130E2000170F000005 +:10017000130F0F10B70212077390023AB780008076 +:1001800037C1ADDE1301F1EE23A02000170F0000F0 +:10019000130F0F0183A100006F00400D130E3000FC +:1001A000170F0000130FCF0C1701000013010101FE :1001B0007310113473002030130E4000170F00002D -:1001C000130F4F0537C1ADDE1301F1EE23202200DE -:1001D000170F0000130F0F01832102006F0040036F -:1001E000130E500037C1ADDE1301F1EE23A0200045 -:1001F00083A10000631E3100130E600037020180EE -:1002000083210200170F0000130F8F0123203200FB -:10021000370110F0130141F22320C101130EA02970 -:0C022000370110F0130101F2232001004F +:1001C000130F0F0B37C1ADDE1301F1EEB7800080C6 +:1001D00023A02000170F0000130F0F0183A10000C0 +:1001E0006F00C008130E500037C1ADDE1301F1EEF1 +:1001F000B700008023A0200083A10000631831060F +:10020000130E6000B700018083A10000170F0000EB +:10021000130FCF0623A030006F004005130E7000AF +:10022000170F0000130FCF0437C1ADDE1301F1EE3D +:10023000B7000380938080FF23202200170F000067 +:10024000130F8FFA832102006F004002130E80000B +:10025000B7000480938080FF83A10000170F000087 +:10026000130FCF0123A030006F004000370110F0C2 +:10027000130141F22320C101370110F0130101F2F3 +:040280002320010036 :040000058000000077 :00000001FF diff --git a/src/test/cpp/raw/pmp/build/pmp.map b/src/test/cpp/raw/pmp/build/pmp.map index f49f55e..1ba7c62 100644 --- a/src/test/cpp/raw/pmp/build/pmp.map +++ b/src/test/cpp/raw/pmp/build/pmp.map @@ -15,19 +15,19 @@ LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-e END GROUP LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/libgcc.a -.crt_section 0x0000000080000000 0x22c +.crt_section 0x0000000080000000 0x284 0x0000000080000000 . = ALIGN (0x4) *crt.o(.text) - .text 0x0000000080000000 0x22c build/src/crt.o + .text 0x0000000080000000 0x284 build/src/crt.o 0x0000000080000000 _start 0x0000000080000010 trap OUTPUT(build/pmp.elf elf32-littleriscv) -.data 0x000000008000022c 0x0 - .data 0x000000008000022c 0x0 build/src/crt.o +.data 0x0000000080000284 0x0 + .data 0x0000000080000284 0x0 build/src/crt.o -.bss 0x000000008000022c 0x0 - .bss 0x000000008000022c 0x0 build/src/crt.o +.bss 0x0000000080000284 0x0 + .bss 0x0000000080000284 0x0 build/src/crt.o .riscv.attributes 0x0000000000000000 0x1e diff --git a/src/test/cpp/raw/pmp/src/crt.S b/src/test/cpp/raw/pmp/src/crt.S index d7881ae..47d36b7 100644 --- a/src/test/cpp/raw/pmp/src/crt.S +++ b/src/test/cpp/raw/pmp/src/crt.S @@ -7,23 +7,23 @@ #define TEST_ID x28 #define TRAP_RA x30 -#define PMPCFG0 0x07120808 -#define PMPCFG0_ 0x07920808 // lock region 2 +#define PMPCFG0 0x07120000 +#define PMPCFG0_ 0x07920808 // locked #define PMPCFG1 0x191f0304 -#define PMPCFG2 0x00000018 +#define PMPCFG2 0x000f0506 #define PMPCFG3 0x0f1e1900 -#define PMPADDR0 0x20000000 // TOR -#define PMPADDR1 0xffffffff // TOR +#define PMPADDR0 0x20000000 // OFF +#define PMPADDR1 0xffffffff // OFF #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 PMPADDR7 0x20005fff // NAPOT R +#define PMPADDR8 0x2000c000 // TOR W +#define PMPADDR9 0x2000d000 // TOR R +#define PMPADDR10 0xffffffff // TOR RWX #define PMPADDR11 0x00000000 // OFF #define PMPADDR12 0x00000000 // OFF #define PMPADDR13 0x00000000 // NAPOT R @@ -97,7 +97,7 @@ test0: li x5, PMPADDR15 csrw pmpaddr15, x5 - li x2, 0x00c0ffee + li x2, 0xc0ffee sw x2, 0x0(x1) sw x2, 0x0(x4) lw x3, 0x0(x1) @@ -112,10 +112,11 @@ test1: la TRAP_RA, fail li x5, PMPCFG0_ csrw pmpcfg0, x5 // lock region 2 + li x1, 0x80008000 li x2, 0xdeadbeef - sw x2, 0x0(x4) // should be OK (write 0x80008000) + sw x2, 0x0(x1) // should be OK (write 0x80008000) la TRAP_RA, test2 - lw x3, 0x0(x4) // should fault (read 0x80008000) + lw x3, 0x0(x1) // should fault (read 0x80008000) j fail // "unlock" region 2, attempt read/write from machine mode @@ -124,10 +125,11 @@ test2: la TRAP_RA, fail li x5, PMPCFG0 csrw pmpcfg0, x5 // "unlock" region 2 + li x1, 0x80008000 li x2, 0xdeadbeef - sw x2, 0x0(x4) // should still be OK (write 0x80008000) + sw x2, 0x0(x1) // should still be OK (write 0x80008000) la TRAP_RA, test3 - lw x3, 0x0(x4) // should still fault (read 0x80008000) + lw x3, 0x0(x1) // should still fault (read 0x80008000) j fail // jump into user mode @@ -143,31 +145,51 @@ test4: li TEST_ID, 4 la TRAP_RA, fail li x2, 0xdeadbeef - sw x2, 0x0(x4) // should be OK (write 0x80008000) + li x1, 0x80008000 + sw x2, 0x0(x1) // should be OK (write 0x80008000) la TRAP_RA, test5 - lw x3, 0x0(x4) // should fault (read 0x80008000) + lw x3, 0x0(x1) // should fault (read 0x80008000) j fail // attempt to read/write other regions from user mode test5: li TEST_ID, 5 li x2, 0xdeadbeef + li x1, 0x80000000 sw x2, 0x0(x1) lw x3, 0x0(x1) bne x2, x3, fail // should be OK (read/write 0x80000000) test6: li TEST_ID, 6 - li x4, 0x80010000 - lw x3, 0x0(x4) // should be OK (read 0x80010000) + li x1, 0x80010000 + lw x3, 0x0(x1) // should be OK (read 0x80010000) la TRAP_RA, pass - sw x3, 0x0(x4) // should fault (write 0x80010000) + sw x3, 0x0(x1) // should fault (write 0x80010000) + j fail + +test7: + li TEST_ID, 7 + la TRAP_RA, fail + li x2, 0xdeadbeef + li x1, 0x8002fff8 + sw x2, 0x0(x4) // should be OK (write 0x8002fff8) + la TRAP_RA, test5 + lw x3, 0x0(x4) // should fault (read 0x8002fff8) + j fail + +test8: + li TEST_ID, 8 + li x1, 0x8003fff8 + lw x3, 0x0(x1) // should be OK (read 0x8003fff8) + la TRAP_RA, pass + sw x3, 0x0(x1) // should fault (write 0x8003fff8) + j fail fail: li x2, 0xf00fff24 sw TEST_ID, 0(x2) pass: - li TEST_ID, 666 li x2, 0xf00fff20 sw x0, 0(x2) diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 81eae4c..8b299de 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -211,27 +211,6 @@ class success : public std::exception { }; #define MCYCLEH 0xB80 // MRW Upper 32 bits of mcycle, RV32I only. #define MINSTRETH 0xB82 // MRW Upper 32 bits of minstret, RV32I only. -#define PMPCFG0 0x3a0 -#define PMPCFG1 0x3a1 -#define PMPCFG2 0x3a2 -#define PMPCFG3 0x3a3 -#define PMPADDR0 0x3b0 -#define PMPADDR1 0x3b1 -#define PMPADDR2 0x3b2 -#define PMPADDR3 0x3b3 -#define PMPADDR4 0x3b4 -#define PMPADDR5 0x3b5 -#define PMPADDR6 0x3b6 -#define PMPADDR7 0x3b7 -#define PMPADDR8 0x3b8 -#define PMPADDR9 0x3b9 -#define PMPADDR10 0x3ba -#define PMPADDR11 0x3bb -#define PMPADDR12 0x3bc -#define PMPADDR13 0x3bd -#define PMPADDR14 0x3be -#define PMPADDR15 0x3bf - #define SSTATUS 0x100 #define SIE 0x104 #define STVEC 0x105 @@ -466,53 +445,8 @@ public: enum AccessKind {READ,WRITE,EXECUTE,READ_WRITE}; virtual bool isMmuRegion(uint32_t v) = 0; - bool pmpCheck(uint32_t p, AccessKind kind) { - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - if (privilege != 3 || pmpcfg[i].reg[3-j].l) { - uint32_t start, end; - bool valid = false; - - switch (pmpcfg[i].reg[3-j].a) { - case 0: // OFF - valid = false; - break; - - case 1: // TOR - valid = false; - break; - - case 2: // NA4 - valid = true; - start = pmpaddr[i*4+j] << 2; - end = start + 4; - break; - - case 3: // NAPOT - valid = true; - uint32_t mask = pmpaddr[i*4+j] & ~(pmpaddr[i*4+j] + 1); - start = (pmpaddr[i*4+j] & ~mask) << 2; - end = start + ((mask + 1) << 3); - break; - } - - if (valid && start <= p && end > p) { - if (kind == READ) return (bool)(!pmpcfg[i].reg[3-j].r); - if (kind == WRITE) return (bool)(!pmpcfg[i].reg[3-j].w); - if (kind == EXECUTE) return (bool)(!pmpcfg[i].reg[3-j].x); - return false; - } - } - } - } - return false; - } bool v2p(uint32_t v, uint32_t *p, AccessKind kind) { -#ifdef PMP - *p = v; - return pmpCheck(v, kind); -#else uint32_t effectivePrivilege = status.mprv && kind != EXECUTE ? status.mpp : privilege; if(effectivePrivilege == 3 || satp.mode == 0 || !isMmuRegion(v)){ *p = v; @@ -536,7 +470,6 @@ public: *p = (tlb.ppn1 << 22) | (superPage ? v & 0x3FF000 : tlb.ppn0 << 12) | (v & 0xFFF); } return false; -#endif } void trap(bool interrupt,int32_t cause) { @@ -639,27 +572,6 @@ public: case SSCRATCH: *value = sscratch; break; case SATP: *value = satp.raw; break; - case PMPCFG0: *value = pmpcfg[0].raw; break; - case PMPCFG1: *value = pmpcfg[1].raw; break; - case PMPCFG2: *value = pmpcfg[2].raw; break; - case PMPCFG3: *value = pmpcfg[3].raw; break; - case PMPADDR0: *value = pmpaddr[0]; break; - case PMPADDR1: *value = pmpaddr[1]; break; - case PMPADDR2: *value = pmpaddr[2]; break; - case PMPADDR3: *value = pmpaddr[3]; break; - case PMPADDR4: *value = pmpaddr[4]; break; - case PMPADDR5: *value = pmpaddr[5]; break; - case PMPADDR6: *value = pmpaddr[6]; break; - case PMPADDR7: *value = pmpaddr[7]; break; - case PMPADDR8: *value = pmpaddr[8]; break; - case PMPADDR9: *value = pmpaddr[9]; break; - case PMPADDR10: *value = pmpaddr[10]; break; - case PMPADDR11: *value = pmpaddr[11]; break; - case PMPADDR12: *value = pmpaddr[12]; break; - case PMPADDR13: *value = pmpaddr[13]; break; - case PMPADDR14: *value = pmpaddr[14]; break; - case PMPADDR15: *value = pmpaddr[15]; break; - default: return true; break; } return false; @@ -698,81 +610,6 @@ public: case SCAUSE: scause.raw = value; break; case STVAL: sbadaddr = value; break; case SEPC: sepc = value; break; - case SSCRATCH: sscratch = value; break; - case SATP: satp.raw = value; break; - - case PMPCFG0: - if (!pmpcfg[0].reg[3].l) maskedWrite(pmpcfg[0].raw, value, 0xff); - if (!pmpcfg[0].reg[2].l) maskedWrite(pmpcfg[0].raw, value, 0xff00); - if (!pmpcfg[0].reg[1].l) maskedWrite(pmpcfg[0].raw, value, 0xff0000); - if (!pmpcfg[0].reg[0].l) maskedWrite(pmpcfg[0].raw, value, 0xff000000); - break; - case PMPCFG1: - if (!pmpcfg[1].reg[3].l) maskedWrite(pmpcfg[1].raw, value, 0xff); - if (!pmpcfg[1].reg[2].l) maskedWrite(pmpcfg[1].raw, value, 0xff00); - if (!pmpcfg[1].reg[1].l) maskedWrite(pmpcfg[1].raw, value, 0xff0000); - if (!pmpcfg[1].reg[0].l) maskedWrite(pmpcfg[1].raw, value, 0xff000000); - break; - case PMPCFG2: - if (!pmpcfg[2].reg[3].l) maskedWrite(pmpcfg[2].raw, value, 0xff); - if (!pmpcfg[2].reg[2].l) maskedWrite(pmpcfg[2].raw, value, 0xff00); - if (!pmpcfg[2].reg[1].l) maskedWrite(pmpcfg[2].raw, value, 0xff0000); - if (!pmpcfg[2].reg[0].l) maskedWrite(pmpcfg[2].raw, value, 0xff000000); - break; - case PMPCFG3: - if (!pmpcfg[3].reg[3].l) maskedWrite(pmpcfg[3].raw, value, 0xff); - if (!pmpcfg[3].reg[2].l) maskedWrite(pmpcfg[3].raw, value, 0xff00); - if (!pmpcfg[3].reg[1].l) maskedWrite(pmpcfg[3].raw, value, 0xff0000); - if (!pmpcfg[3].reg[0].l) maskedWrite(pmpcfg[3].raw, value, 0xff000000); - break; - case PMPADDR0: - if (!pmpcfg[0].reg[3].l) pmpaddr[0] = value; - break; - case PMPADDR1: - if (!pmpcfg[0].reg[2].l) pmpaddr[1] = value; - break; - case PMPADDR2: - if (!pmpcfg[0].reg[1].l) pmpaddr[2] = value; - break; - case PMPADDR3: - if (!pmpcfg[0].reg[0].l) pmpaddr[3] = value; - break; - case PMPADDR4: - if (!pmpcfg[1].reg[3].l) pmpaddr[4] = value; - break; - case PMPADDR5: - if (!pmpcfg[1].reg[2].l) pmpaddr[5] = value; - break; - case PMPADDR6: - if (!pmpcfg[1].reg[1].l) pmpaddr[6] = value; - break; - case PMPADDR7: - if (!pmpcfg[1].reg[0].l) pmpaddr[7] = value; - break; - case PMPADDR8: - if (!pmpcfg[2].reg[3].l) pmpaddr[8] = value; - break; - case PMPADDR9: - if (!pmpcfg[2].reg[2].l) pmpaddr[9] = value; - break; - case PMPADDR10: - if (!pmpcfg[2].reg[1].l) pmpaddr[10] = value; - break; - case PMPADDR11: - if (!pmpcfg[2].reg[0].l) pmpaddr[11] = value; - break; - case PMPADDR12: - if (!pmpcfg[3].reg[3].l) pmpaddr[12] = value; - break; - case PMPADDR13: - if (!pmpcfg[3].reg[2].l) pmpaddr[13] = value; - break; - case PMPADDR14: - if (!pmpcfg[3].reg[1].l) pmpaddr[14] = value; - break; - case PMPADDR15: - if (!pmpcfg[3].reg[0].l) pmpaddr[15] = value; - break; default: ilegalInstruction(); return true; break; } @@ -4054,7 +3891,7 @@ int main(int argc, char **argv, char **env) { #endif #ifdef PMP - redo(REDO,WorkspaceRegression("pmp").loadHex(string(REGRESSION_PATH) + "../raw/pmp/build/pmp.hex")->bootAt(0x00000000u)->run(10e3);); + redo(REDO,WorkspaceRegression("pmp").loadHex(string(REGRESSION_PATH) + "../raw/pmp/build/pmp.hex")->bootAt(0x80000000u)->run(10e3);); #endif #ifdef AMO diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 6d07291..64c8ad6 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -523,8 +523,8 @@ class CsrDimension(freertos : String, zephyr : String, linux : String) extends V } } else if(catchAll){ new VexRiscvPosition("MachineOs") with CatchAllPosition{ - override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.all(0x80000020l)) - override def testParam = s"CSR=yes FREERTOS=$freertos ZEPHYR=$zephyr" + override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.zephyr(0x80000020l)) + override def testParam = s"CSR=yes CSR_SKIP_TEST=yes FREERTOS=$freertos ZEPHYR=$zephyr" } } else if(r.nextDouble() < 0.3){ new VexRiscvPosition("AllNoException") with CatchAllPosition{ From f2ce2eab002b32aef0c56f49aa33eda89c2dd8a5 Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Mon, 7 Dec 2020 09:11:26 +0100 Subject: [PATCH 26/30] PMP plugin passes regression tests --- src/test/cpp/regression/main.cpp | 34 ++++--------------- src/test/cpp/regression/makefile | 2 +- .../vexriscv/TestIndividualFeatures.scala | 14 ++++---- 3 files changed, 15 insertions(+), 35 deletions(-) diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 8b299de..99393ac 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -211,6 +211,7 @@ class success : public std::exception { }; #define MCYCLEH 0xB80 // MRW Upper 32 bits of mcycle, RV32I only. #define MINSTRETH 0xB82 // MRW Upper 32 bits of minstret, RV32I only. + #define SSTATUS 0x100 #define SIE 0x104 #define STVEC 0x105 @@ -373,25 +374,9 @@ public: }; }; + bool lrscReserved; - struct pmpcfg_s { - uint32_t r : 1; - uint32_t w : 1; - uint32_t x : 1; - uint32_t a : 2; - uint32_t _dummy : 2; - uint32_t l : 1; - } __attribute__((packed)); - - union pmpcfg_u { - uint32_t raw; - pmpcfg_s reg[4]; - }; - - pmpcfg_u pmpcfg[4]; - uint32_t pmpaddr[16]; - RiscvGolden() { pc = 0x80000000; regs[0] = 0; @@ -416,10 +401,6 @@ public: ipInput = 0; stepCounter = 0; lrscReserved = false; - for (int i = 0; i < 4; i++) - pmpcfg[i].raw = 0; - for (int i = 0; i < 16; i++) - pmpaddr[i] = 0; } virtual void rfWrite(int32_t address, int32_t data) { @@ -444,10 +425,8 @@ public: enum AccessKind {READ,WRITE,EXECUTE,READ_WRITE}; 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; + 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 || !isMmuRegion(v)){ *p = v; } else { @@ -549,7 +528,7 @@ public: virtual bool csrRead(int32_t csr, uint32_t *value){ if(((csr >> 8) & 0x3) > privilege) return true; - switch(csr) { + switch(csr){ case MSTATUS: *value = status.raw & MSTATUS_READ_MASK; break; case MIP: *value = getIp().raw; break; case MIE: *value = ie.raw; break; @@ -571,7 +550,6 @@ public: case SEPC: *value = sepc; break; case SSCRATCH: *value = sscratch; break; case SATP: *value = satp.raw; break; - default: return true; break; } return false; @@ -610,6 +588,8 @@ public: case SCAUSE: scause.raw = value; break; case STVAL: sbadaddr = value; break; case SEPC: sepc = value; break; + case SSCRATCH: sscratch = value; break; + case SATP: satp.raw = value; break; default: ilegalInstruction(); return true; break; } diff --git a/src/test/cpp/regression/makefile b/src/test/cpp/regression/makefile index c71c880..5f64034 100644 --- a/src/test/cpp/regression/makefile +++ b/src/test/cpp/regression/makefile @@ -15,7 +15,7 @@ CSR_SKIP_TEST?=no EBREAK?=no FENCEI?=no MMU?=yes -PMP?=yes +PMP?=no SEED?=no LRSC?=no AMO?=no diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 64c8ad6..b2f35aa 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -46,6 +46,7 @@ abstract class VexRiscvPosition(name: String) extends ConfigPosition[VexRiscvCo class VexRiscvUniverse extends ConfigUniverse object VexRiscvUniverse{ + val CACHE_ALL = new VexRiscvUniverse val CATCH_ALL = new VexRiscvUniverse val MMU = new VexRiscvUniverse val PMP = new VexRiscvUniverse @@ -322,9 +323,10 @@ class IBusDimension(rvcRate : Double) extends VexRiscvDimension("IBus") { override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = { val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL) + val cacheAll = universes.contains(VexRiscvUniverse.CACHE_ALL) val mmuConfig = if(universes.contains(VexRiscvUniverse.MMU)) MmuPortConfig( portTlbSize = 4) else null - if(r.nextDouble() < 0.5){ + if(r.nextDouble() < 0.5 && !cacheAll){ val latency = r.nextInt(5) + 1 val compressed = r.nextDouble() < rvcRate val injectorStage = r.nextBoolean() || latency == 1 @@ -403,13 +405,14 @@ class DBusDimension extends VexRiscvDimension("DBus") { override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = { val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL) + val cacheAll = universes.contains(VexRiscvUniverse.CACHE_ALL) val mmuConfig = if(universes.contains(VexRiscvUniverse.MMU)) MmuPortConfig( portTlbSize = 4) else null val noMemory = universes.contains(VexRiscvUniverse.NO_MEMORY) val noWriteBack = universes.contains(VexRiscvUniverse.NO_WRITEBACK) - if(r.nextDouble() < 0.4 || noMemory){ + if((r.nextDouble() < 0.4 || noMemory) && !cacheAll){ val withLrSc = catchAll val earlyInjection = r.nextBoolean() && !universes.contains(VexRiscvUniverse.NO_WRITEBACK) new VexRiscvPosition("Simple" + (if(earlyInjection) "Early" else "Late")) { @@ -760,18 +763,15 @@ class TestIndividualFeatures extends MultithreadedFunSuite { } } else { if(machineOsRate > rand.nextDouble()) { + universe += VexRiscvUniverse.CACHE_ALL universe += VexRiscvUniverse.CATCH_ALL universe += VexRiscvUniverse.PMP if(demwRate < rand.nextDouble()){ universe += VexRiscvUniverse.NO_WRITEBACK } } - if(demwRate > rand.nextDouble()){ - }else if(demRate > rand.nextDouble()){ + if(demRate > rand.nextDouble()){ universe += VexRiscvUniverse.NO_WRITEBACK - } else { - universe += VexRiscvUniverse.NO_WRITEBACK - universe += VexRiscvUniverse.NO_MEMORY } } From 7d699dcc137573e570dc2f2e2588297da7cd6c87 Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Thu, 10 Dec 2020 09:39:56 +0100 Subject: [PATCH 27/30] Remove PMP from MachineOs test defaults --- .../demo/{GenZephyr.scala => GenSecure.scala} | 4 ++-- .../scala/vexriscv/plugin/CsrPlugin.scala | 4 ++-- src/test/cpp/raw/pmp/.gdbinit | 3 --- src/test/cpp/regression/main.cpp | 2 +- .../vexriscv/TestIndividualFeatures.scala | 24 +++++++++++++++---- 5 files changed, 25 insertions(+), 12 deletions(-) rename src/main/scala/vexriscv/demo/{GenZephyr.scala => GenSecure.scala} (96%) delete mode 100644 src/test/cpp/raw/pmp/.gdbinit diff --git a/src/main/scala/vexriscv/demo/GenZephyr.scala b/src/main/scala/vexriscv/demo/GenSecure.scala similarity index 96% rename from src/main/scala/vexriscv/demo/GenZephyr.scala rename to src/main/scala/vexriscv/demo/GenSecure.scala index 4666ec4..2835b44 100644 --- a/src/main/scala/vexriscv/demo/GenZephyr.scala +++ b/src/main/scala/vexriscv/demo/GenSecure.scala @@ -5,7 +5,7 @@ import vexriscv.ip.{DataCacheConfig, InstructionCacheConfig} import vexriscv.{plugin, VexRiscv, VexRiscvConfig} import spinal.core._ -object GenZephyr extends App { +object GenSecure extends App { def cpu() = new VexRiscv( config = VexRiscvConfig( plugins = List( @@ -71,7 +71,7 @@ object GenZephyr extends App { mulUnrollFactor = 1, divUnrollFactor = 1 ), - new CsrPlugin(CsrPluginConfig.zephyr(0x00000020l)), + new CsrPlugin(CsrPluginConfig.secure(0x00000020l)), new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))), new BranchPlugin( earlyBranch = false, diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index cabc262..315d3e5 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -264,13 +264,13 @@ object CsrPluginConfig{ uinstretAccess = CsrAccess.NONE ) - def zephyr(mtvecInit : BigInt) = CsrPluginConfig( + def secure(mtvecInit : BigInt) = CsrPluginConfig( catchIllegalAccess = true, mvendorid = 1, marchid = 2, mimpid = 3, mhartid = 0, - misaExtensionsInit = 0x103124, // RV32CFIMNU + misaExtensionsInit = 0x101064, // RV32GCFMU misaAccess = CsrAccess.READ_WRITE, mtvecAccess = CsrAccess.READ_WRITE, mtvecInit = mtvecInit, diff --git a/src/test/cpp/raw/pmp/.gdbinit b/src/test/cpp/raw/pmp/.gdbinit deleted file mode 100644 index 45fceb2..0000000 --- a/src/test/cpp/raw/pmp/.gdbinit +++ /dev/null @@ -1,3 +0,0 @@ -target remote localhost:3333 -monitor reset halt -load diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 99393ac..d5788f5 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -373,7 +373,7 @@ public: uint32_t ppn1 : 12; }; }; - + bool lrscReserved; diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index b2f35aa..75d3405 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -517,6 +517,7 @@ trait CatchAllPosition class CsrDimension(freertos : String, zephyr : String, linux : String) extends VexRiscvDimension("Csr") { override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = { + val pmp = universes.contains(VexRiscvUniverse.PMP) val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL) val supervisor = universes.contains(VexRiscvUniverse.SUPERVISOR) if(supervisor){ @@ -524,9 +525,14 @@ class CsrDimension(freertos : String, zephyr : String, linux : String) extends V override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.linuxFull(0x80000020l)) override def testParam = s"FREERTOS=$freertos ZEPHYR=$zephyr LINUX_REGRESSION=$linux SUPERVISOR=yes" } + } else if(pmp){ + new VexRiscvPosition("Secure") with CatchAllPosition{ + override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.secure(0x80000020l)) + override def testParam = s"CSR=yes CSR_SKIP_TEST=yes FREERTOS=$freertos ZEPHYR=$zephyr" + } } else if(catchAll){ new VexRiscvPosition("MachineOs") with CatchAllPosition{ - override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.zephyr(0x80000020l)) + override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.all(0x80000020l)) override def testParam = s"CSR=yes CSR_SKIP_TEST=yes FREERTOS=$freertos ZEPHYR=$zephyr" } } else if(r.nextDouble() < 0.3){ @@ -655,6 +661,7 @@ class TestIndividualFeatures extends MultithreadedFunSuite { val rvcRate = sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_RVC_RATE", "0.5").toDouble val linuxRate = sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_LINUX_RATE", "0.3").toDouble val machineOsRate = sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE", "0.5").toDouble + val secureRate = sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_SECURE_RATE", "0.5").toDouble val linuxRegression = sys.env.getOrElse("VEXRISCV_REGRESSION_LINUX_REGRESSION", "yes") val coremarkRegression = sys.env.getOrElse("VEXRISCV_REGRESSION_COREMARK", "yes") val zephyrCount = sys.env.getOrElse("VEXRISCV_REGRESSION_ZEPHYR_COUNT", "4") @@ -761,17 +768,26 @@ class TestIndividualFeatures extends MultithreadedFunSuite { if(demwRate < rand.nextDouble()){ universe += VexRiscvUniverse.NO_WRITEBACK } - } else { - if(machineOsRate > rand.nextDouble()) { + } else if (secureRate > rand.nextDouble()) { universe += VexRiscvUniverse.CACHE_ALL universe += VexRiscvUniverse.CATCH_ALL universe += VexRiscvUniverse.PMP if(demwRate < rand.nextDouble()){ universe += VexRiscvUniverse.NO_WRITEBACK } + } else { + if(machineOsRate > rand.nextDouble()) { + universe += VexRiscvUniverse.CATCH_ALL + if(demwRate < rand.nextDouble()){ + universe += VexRiscvUniverse.NO_WRITEBACK + } } - if(demRate > rand.nextDouble()){ + if(demwRate > rand.nextDouble()){ + }else if(demRate > rand.nextDouble()){ universe += VexRiscvUniverse.NO_WRITEBACK + } else { + universe += VexRiscvUniverse.NO_WRITEBACK + universe += VexRiscvUniverse.NO_MEMORY } } From 5e6c64546123fe0126ae5cb523af7b3648e608db Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Thu, 14 Jan 2021 08:34:54 +0100 Subject: [PATCH 28/30] Distinguish between page faults from MMU and access faults from PMP --- src/main/scala/vexriscv/Services.scala | 1 + src/main/scala/vexriscv/ip/DataCache.scala | 23 +++++++++++-------- .../scala/vexriscv/ip/InstructionCache.scala | 8 +++---- .../vexriscv/plugin/DBusCachedPlugin.scala | 9 ++++---- .../scala/vexriscv/plugin/MmuPlugin.scala | 2 ++ .../scala/vexriscv/plugin/PmpPlugin.scala | 1 + .../plugin/StaticMemoryTranslatorPlugin.scala | 1 + 7 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/main/scala/vexriscv/Services.scala b/src/main/scala/vexriscv/Services.scala index 4b0aeca..47a16d1 100644 --- a/src/main/scala/vexriscv/Services.scala +++ b/src/main/scala/vexriscv/Services.scala @@ -71,6 +71,7 @@ case class MemoryTranslatorCmd() extends Bundle{ case class MemoryTranslatorRsp() extends Bundle{ val physicalAddress = UInt(32 bits) val isIoAccess = Bool + val isPaging = Bool val allowRead, allowWrite, allowExecute = Bool val exception = Bool val refilling = Bool diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index 7cbe4ba..1c60690 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -551,9 +551,20 @@ class DataCache(p : DataCacheConfig) extends Component{ val memCmdSent = RegInit(False) setWhen (io.mem.cmd.ready) clearWhen (!io.cpu.writeBack.isStuck) - io.cpu.redo := False + val badPermissions = (!mmuRsp.allowWrite && request.wr) || (!mmuRsp.allowRead && (!request.wr || isAmo)) + val loadStoreFault = io.cpu.writeBack.isValid && (mmuRsp.exception || badPermissions) + io.cpu.writeBack.accessError := False - io.cpu.writeBack.mmuException := io.cpu.writeBack.isValid && (if(catchIllegal) mmuRsp.exception || (!mmuRsp.allowWrite && request.wr) || (!mmuRsp.allowRead && (!request.wr || isAmo)) else False) + when(mmuRsp.isIoAccess) { + io.cpu.writeBack.data := io.mem.rsp.data + if (catchAccessError) io.cpu.writeBack.accessError := io.mem.rsp.valid && io.mem.rsp.error + } otherwise { + io.cpu.writeBack.data := dataMux + if (catchAccessError) io.cpu.writeBack.accessError := (waysHits & B(tagsReadRsp.map(_.error))) =/= 0 || (loadStoreFault && !mmuRsp.isPaging) + } + + io.cpu.redo := False + io.cpu.writeBack.mmuException := loadStoreFault && (if(catchIllegal) mmuRsp.isPaging else False) io.cpu.writeBack.unalignedAccess := io.cpu.writeBack.isValid && (if(catchUnaligned) ((request.size === 2 && mmuRsp.physicalAddress(1 downto 0) =/= 0) || (request.size === 1 && mmuRsp.physicalAddress(0 downto 0) =/= 0)) else False) io.cpu.writeBack.isWrite := request.wr @@ -626,14 +637,6 @@ class DataCache(p : DataCacheConfig) extends Component{ } } - when(mmuRsp.isIoAccess){ - io.cpu.writeBack.data := io.mem.rsp.data - if(catchAccessError) io.cpu.writeBack.accessError := io.mem.rsp.valid && io.mem.rsp.error - } otherwise { - io.cpu.writeBack.data := dataMux - if(catchAccessError) io.cpu.writeBack.accessError := (waysHits & B(tagsReadRsp.map(_.error))) =/= 0 - } - //remove side effects on exceptions when(mmuRsp.refilling || io.cpu.writeBack.accessError || io.cpu.writeBack.mmuException || io.cpu.writeBack.unalignedAccess){ io.mem.cmd.valid := False diff --git a/src/main/scala/vexriscv/ip/InstructionCache.scala b/src/main/scala/vexriscv/ip/InstructionCache.scala index 4df0f79..380e6b3 100644 --- a/src/main/scala/vexriscv/ip/InstructionCache.scala +++ b/src/main/scala/vexriscv/ip/InstructionCache.scala @@ -438,9 +438,9 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ val mmuRsp = io.cpu.fetch.mmuBus.rsp io.cpu.fetch.cacheMiss := !hit.valid - io.cpu.fetch.error := hit.error + io.cpu.fetch.error := hit.error || (!mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute)) io.cpu.fetch.mmuRefilling := mmuRsp.refilling - io.cpu.fetch.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute) + io.cpu.fetch.mmuException := !mmuRsp.refilling && mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute) }) } @@ -468,9 +468,9 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ } io.cpu.decode.cacheMiss := !hit.valid - io.cpu.decode.error := hit.error + io.cpu.decode.error := hit.error || (!mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute)) io.cpu.decode.mmuRefilling := mmuRsp.refilling - io.cpu.decode.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute) + io.cpu.decode.mmuException := !mmuRsp.refilling && mmuRsp.isPaging && (mmuRsp.exception || !mmuRsp.allowExecute) io.cpu.decode.physicalAddress := mmuRsp.physicalAddress }) } diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index fd45dd8..1dedd79 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -273,15 +273,14 @@ class DBusCachedPlugin(val config : DataCacheConfig, exceptionBus.valid := True exceptionBus.code := (input(MEMORY_WR) ? U(7) | U(5)).resized } - - if (catchUnaligned) when(cache.io.cpu.writeBack.unalignedAccess) { - exceptionBus.valid := True - exceptionBus.code := (input(MEMORY_WR) ? U(6) | U(4)).resized - } if(catchIllegal) when (cache.io.cpu.writeBack.mmuException) { exceptionBus.valid := True exceptionBus.code := (input(MEMORY_WR) ? U(15) | U(13)).resized } + if (catchUnaligned) when(cache.io.cpu.writeBack.unalignedAccess) { + exceptionBus.valid := True + exceptionBus.code := (input(MEMORY_WR) ? U(6) | U(4)).resized + } when(cache.io.cpu.redo) { redoBranch.valid := True diff --git a/src/main/scala/vexriscv/plugin/MmuPlugin.scala b/src/main/scala/vexriscv/plugin/MmuPlugin.scala index 9dedde5..6d7f6a8 100644 --- a/src/main/scala/vexriscv/plugin/MmuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/MmuPlugin.scala @@ -127,6 +127,7 @@ class MmuPlugin(ioRange : UInt => Bool, port.bus.rsp.allowExecute := cacheLine.allowExecute port.bus.rsp.exception := cacheHit && (cacheLine.exception || cacheLine.allowUser && privilegeService.isSupervisor() && !csr.status.sum || !cacheLine.allowUser && privilegeService.isUser()) port.bus.rsp.refilling := !cacheHit + port.bus.rsp.isPaging := True } otherwise { port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress port.bus.rsp.allowRead := True @@ -134,6 +135,7 @@ class MmuPlugin(ioRange : UInt => Bool, port.bus.rsp.allowExecute := True port.bus.rsp.exception := False port.bus.rsp.refilling := False + port.bus.rsp.isPaging := False } port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index f232ee4..88be675 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -205,6 +205,7 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] } port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) + port.bus.rsp.isPaging := False port.bus.rsp.exception := False port.bus.rsp.refilling := False port.bus.busy := False diff --git a/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala b/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala index 351ebc5..7a31d18 100644 --- a/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala +++ b/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala @@ -32,6 +32,7 @@ class StaticMemoryTranslatorPlugin(ioRange : UInt => Bool) extends Plugin[VexRis port.bus.rsp.allowWrite := True port.bus.rsp.allowExecute := True port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) + port.bus.rsp.isPaging := False port.bus.rsp.exception := False port.bus.rsp.refilling := False port.bus.busy := False From 828ea960067076055294e24c9afe76aa597fa796 Mon Sep 17 00:00:00 2001 From: Samuel Lindemer Date: Wed, 20 Jan 2021 09:27:35 +0100 Subject: [PATCH 29/30] PMP registers are now WARL --- .../scala/vexriscv/plugin/PmpPlugin.scala | 126 ++++--- src/test/cpp/raw/pmp/build/pmp.asm | 314 +++++++++--------- src/test/cpp/raw/pmp/build/pmp.elf | Bin 5436 -> 5468 bytes src/test/cpp/raw/pmp/build/pmp.hex | 78 ++--- src/test/cpp/raw/pmp/build/pmp.map | 12 +- src/test/cpp/raw/pmp/src/crt.S | 8 + 6 files changed, 293 insertions(+), 245 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index 88be675..5f008b4 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -70,61 +70,78 @@ case class PmpRegister(previous : PmpRegister) extends Area { def NA4 = 2 def NAPOT = 3 - // Software-accessible CSR interface - val csr = new Area { + val state = new Area { val r, w, x = Reg(Bool) val l = RegInit(False) val a = Reg(UInt(2 bits)) init(0) val addr = Reg(UInt(32 bits)) } - // Active region bounds and permissions (internal) + // CSR writes connect to these signals rather than the internal state + // registers. This makes locking and WARL possible. + val csr = new Area { + val r, w, x = Bool + val l = Bool + val a = UInt(2 bits) + val addr = UInt(32 bits) + } + + // Last assignment wins; nothing happens if a user-initiated write did not + // occur on this clock cycle. + csr.r := state.r + csr.w := state.w + csr.x := state.x + csr.l := state.l + csr.a := state.a + csr.addr := state.addr + + // Computed PMP region bounds val region = new Area { - val r, w, x = Reg(Bool) - val l, valid = RegInit(False) + val valid = Bool val start, end = Reg(UInt(32 bits)) } - - when(~region.l) { - region.r := csr.r - region.w := csr.w - region.x := csr.x - region.l := csr.l - val shifted = csr.addr |<< 2 - region.valid := True + when(~state.l) { + state.r := csr.r + state.w := csr.w + state.x := csr.x + state.l := csr.l + state.a := csr.a + state.addr := csr.addr - switch(csr.a) { + if (csr.l == True & csr.a == TOR) { + previous.state.l := True + } + } - is(TOR) { - if (previous == null) { - region.start := 0 - } else { - region.start := previous.region.end - } - if (csr.l == True) { - previous.region.l := True - } - region.end := shifted + val shifted = csr.addr |<< 2 + region.valid := True + + switch(state.a) { + is(TOR) { + if (previous == null) { + region.start := 0 + } else { + region.start := previous.region.end } + region.end := shifted + } - is(NA4) { - region.start := shifted - region.end := shifted + 4 - } + is(NA4) { + region.start := shifted + region.end := shifted + 4 + } - is(NAPOT) { - val mask = csr.addr & ~(csr.addr + 1) - val masked = (csr.addr & ~mask) |<< 2 - region.start := masked - region.end := masked + ((mask + 1) |<< 3) - } - - default { - region.end := shifted - region.valid := False - } + is(NAPOT) { + val mask = state.addr & ~(state.addr + 1) + val masked = (state.addr & ~mask) |<< 2 + region.start := masked + region.end := masked + ((mask + 1) |<< 3) + } + default { + region.end := shifted + region.valid := False } } } @@ -162,12 +179,25 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] } else { pmps += PmpRegister(pmps.last) } - csrService.rw(0x3b0 + i, pmps(i).csr.addr) + csrService.r(0x3b0 + i, pmps(i).state.addr) + csrService.w(0x3b0 + i, pmps(i).csr.addr) } // Instantiate pmpcfg0 ... pmpcfg# CSRs. for (i <- 0 until (regions / 4)) { - csrService.rw(0x3a0 + i, + csrService.r(0x3a0 + i, + 31 -> pmps((i * 4) + 3).state.l, 23 -> pmps((i * 4) + 2).state.l, + 15 -> pmps((i * 4) + 1).state.l, 7 -> pmps((i * 4) ).state.l, + 27 -> pmps((i * 4) + 3).state.a, 26 -> pmps((i * 4) + 3).state.x, + 25 -> pmps((i * 4) + 3).state.w, 24 -> pmps((i * 4) + 3).state.r, + 19 -> pmps((i * 4) + 2).state.a, 18 -> pmps((i * 4) + 2).state.x, + 17 -> pmps((i * 4) + 2).state.w, 16 -> pmps((i * 4) + 2).state.r, + 11 -> pmps((i * 4) + 1).state.a, 10 -> pmps((i * 4) + 1).state.x, + 9 -> pmps((i * 4) + 1).state.w, 8 -> pmps((i * 4) + 1).state.r, + 3 -> pmps((i * 4) ).state.a, 2 -> pmps((i * 4) ).state.x, + 1 -> pmps((i * 4) ).state.w, 0 -> pmps((i * 4) ).state.r + ) + csrService.w(0x3a0 + i, 31 -> pmps((i * 4) + 3).csr.l, 23 -> pmps((i * 4) + 2).csr.l, 15 -> pmps((i * 4) + 1).csr.l, 7 -> pmps((i * 4) ).csr.l, 27 -> pmps((i * 4) + 3).csr.a, 26 -> pmps((i * 4) + 3).csr.x, @@ -188,10 +218,10 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] port.bus.rsp.physicalAddress := address // Only the first matching PMP region applies. - val hits = pmps.map(pmp => pmp.region.valid && - pmp.region.start <= address && - pmp.region.end > address && - (pmp.region.l || ~privilegeService.isMachine())) + val hits = pmps.map(pmp => pmp.region.valid & + pmp.region.start <= address & + pmp.region.end > address & + (pmp.state.l | ~privilegeService.isMachine())) // M-mode has full access by default, others have none. when(CountOne(hits) === 0) { @@ -199,9 +229,9 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] port.bus.rsp.allowWrite := privilegeService.isMachine() port.bus.rsp.allowExecute := privilegeService.isMachine() } otherwise { - port.bus.rsp.allowRead := MuxOH(OHMasking.first(hits), pmps.map(_.region.r)) - port.bus.rsp.allowWrite := MuxOH(OHMasking.first(hits), pmps.map(_.region.w)) - port.bus.rsp.allowExecute := MuxOH(OHMasking.first(hits), pmps.map(_.region.x)) + port.bus.rsp.allowRead := MuxOH(OHMasking.first(hits), pmps.map(_.state.r)) + port.bus.rsp.allowWrite := MuxOH(OHMasking.first(hits), pmps.map(_.state.w)) + port.bus.rsp.allowExecute := MuxOH(OHMasking.first(hits), pmps.map(_.state.x)) } port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) diff --git a/src/test/cpp/raw/pmp/build/pmp.asm b/src/test/cpp/raw/pmp/build/pmp.asm index 294e964..5c7605b 100644 --- a/src/test/cpp/raw/pmp/build/pmp.asm +++ b/src/test/cpp/raw/pmp/build/pmp.asm @@ -17,176 +17,184 @@ Disassembly of section .crt_section: 80000018 : 80000018: 00000e13 li t3,0 8000001c: 00000f17 auipc t5,0x0 -80000020: 250f0f13 addi t5,t5,592 # 8000026c +80000020: 270f0f13 addi t5,t5,624 # 8000028c 80000024: 800000b7 lui ra,0x80000 80000028: 80008237 lui tp,0x80008 8000002c: deadc137 lui sp,0xdeadc -80000030: eef10113 addi sp,sp,-273 # deadbeef -80000034: 0020a023 sw sp,0(ra) # 80000000 -80000038: 00222023 sw sp,0(tp) # 80008000 +80000030: eef10113 addi sp,sp,-273 # deadbeef +80000034: 0020a023 sw sp,0(ra) # 80000000 +80000038: 00222023 sw sp,0(tp) # 80008000 8000003c: 0000a183 lw gp,0(ra) -80000040: 22311663 bne sp,gp,8000026c +80000040: 24311663 bne sp,gp,8000028c 80000044: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000048: 22311263 bne sp,gp,8000026c +80000048: 24311263 bne sp,gp,8000028c 8000004c: 071202b7 lui t0,0x7120 80000050: 3a029073 csrw pmpcfg0,t0 -80000054: 191f02b7 lui t0,0x191f0 -80000058: 30428293 addi t0,t0,772 # 191f0304 <_start-0x66e0fcfc> -8000005c: 3a129073 csrw pmpcfg1,t0 -80000060: 000f02b7 lui t0,0xf0 -80000064: 50628293 addi t0,t0,1286 # f0506 <_start-0x7ff0fafa> -80000068: 3a229073 csrw pmpcfg2,t0 -8000006c: 0f1e22b7 lui t0,0xf1e2 -80000070: 90028293 addi t0,t0,-1792 # f1e1900 <_start-0x70e1e700> -80000074: 3a329073 csrw pmpcfg3,t0 -80000078: 200002b7 lui t0,0x20000 -8000007c: 3b029073 csrw pmpaddr0,t0 -80000080: fff00293 li t0,-1 -80000084: 3b129073 csrw pmpaddr1,t0 -80000088: 200022b7 lui t0,0x20002 -8000008c: 3b229073 csrw pmpaddr2,t0 -80000090: 200042b7 lui t0,0x20004 -80000094: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> -80000098: 3b329073 csrw pmpaddr3,t0 -8000009c: 200042b7 lui t0,0x20004 -800000a0: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> -800000a4: 3b429073 csrw pmpaddr4,t0 -800000a8: 200042b7 lui t0,0x20004 -800000ac: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> -800000b0: 3b529073 csrw pmpaddr5,t0 -800000b4: 200022b7 lui t0,0x20002 -800000b8: fff28293 addi t0,t0,-1 # 20001fff <_start-0x5fffe001> -800000bc: 3b629073 csrw pmpaddr6,t0 -800000c0: 200062b7 lui t0,0x20006 -800000c4: fff28293 addi t0,t0,-1 # 20005fff <_start-0x5fffa001> -800000c8: 3b729073 csrw pmpaddr7,t0 -800000cc: 2000c2b7 lui t0,0x2000c -800000d0: 3b829073 csrw pmpaddr8,t0 -800000d4: 2000d2b7 lui t0,0x2000d -800000d8: 3b929073 csrw pmpaddr9,t0 -800000dc: fff00293 li t0,-1 -800000e0: 3ba29073 csrw pmpaddr10,t0 -800000e4: 00000293 li t0,0 -800000e8: 3bb29073 csrw pmpaddr11,t0 -800000ec: 00000293 li t0,0 -800000f0: 3bc29073 csrw pmpaddr12,t0 +80000054: 3a002373 csrr t1,pmpcfg0 +80000058: 22629a63 bne t0,t1,8000028c +8000005c: 191f02b7 lui t0,0x191f0 +80000060: 30428293 addi t0,t0,772 # 191f0304 <_start-0x66e0fcfc> +80000064: 3a129073 csrw pmpcfg1,t0 +80000068: 000f02b7 lui t0,0xf0 +8000006c: 50628293 addi t0,t0,1286 # f0506 <_start-0x7ff0fafa> +80000070: 3a229073 csrw pmpcfg2,t0 +80000074: 0f1e22b7 lui t0,0xf1e2 +80000078: 90028293 addi t0,t0,-1792 # f1e1900 <_start-0x70e1e700> +8000007c: 3a329073 csrw pmpcfg3,t0 +80000080: 200002b7 lui t0,0x20000 +80000084: 3b029073 csrw pmpaddr0,t0 +80000088: 3b002373 csrr t1,pmpaddr0 +8000008c: 20629063 bne t0,t1,8000028c +80000090: fff00293 li t0,-1 +80000094: 3b129073 csrw pmpaddr1,t0 +80000098: 200022b7 lui t0,0x20002 +8000009c: 3b229073 csrw pmpaddr2,t0 +800000a0: 200042b7 lui t0,0x20004 +800000a4: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000a8: 3b329073 csrw pmpaddr3,t0 +800000ac: 200042b7 lui t0,0x20004 +800000b0: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000b4: 3b429073 csrw pmpaddr4,t0 +800000b8: 200042b7 lui t0,0x20004 +800000bc: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000c0: 3b529073 csrw pmpaddr5,t0 +800000c4: 200022b7 lui t0,0x20002 +800000c8: fff28293 addi t0,t0,-1 # 20001fff <_start-0x5fffe001> +800000cc: 3b629073 csrw pmpaddr6,t0 +800000d0: 200062b7 lui t0,0x20006 +800000d4: fff28293 addi t0,t0,-1 # 20005fff <_start-0x5fffa001> +800000d8: 3b729073 csrw pmpaddr7,t0 +800000dc: 2000c2b7 lui t0,0x2000c +800000e0: 3b829073 csrw pmpaddr8,t0 +800000e4: 2000d2b7 lui t0,0x2000d +800000e8: 3b929073 csrw pmpaddr9,t0 +800000ec: fff00293 li t0,-1 +800000f0: 3ba29073 csrw pmpaddr10,t0 800000f4: 00000293 li t0,0 -800000f8: 3bd29073 csrw pmpaddr13,t0 +800000f8: 3bb29073 csrw pmpaddr11,t0 800000fc: 00000293 li t0,0 -80000100: 3be29073 csrw pmpaddr14,t0 +80000100: 3bc29073 csrw pmpaddr12,t0 80000104: 00000293 li t0,0 -80000108: 3bf29073 csrw pmpaddr15,t0 -8000010c: 00c10137 lui sp,0xc10 -80000110: fee10113 addi sp,sp,-18 # c0ffee <_start-0x7f3f0012> -80000114: 0020a023 sw sp,0(ra) -80000118: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> -8000011c: 0000a183 lw gp,0(ra) -80000120: 14311663 bne sp,gp,8000026c -80000124: 00000193 li gp,0 -80000128: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -8000012c: 14311063 bne sp,gp,8000026c +80000108: 3bd29073 csrw pmpaddr13,t0 +8000010c: 00000293 li t0,0 +80000110: 3be29073 csrw pmpaddr14,t0 +80000114: 00000293 li t0,0 +80000118: 3bf29073 csrw pmpaddr15,t0 +8000011c: 00c10137 lui sp,0xc10 +80000120: fee10113 addi sp,sp,-18 # c0ffee <_start-0x7f3f0012> +80000124: 0020a023 sw sp,0(ra) +80000128: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +8000012c: 0000a183 lw gp,0(ra) +80000130: 14311e63 bne sp,gp,8000028c +80000134: 00000193 li gp,0 +80000138: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +8000013c: 14311863 bne sp,gp,8000028c -80000130 : -80000130: 00100e13 li t3,1 -80000134: 00000f17 auipc t5,0x0 -80000138: 138f0f13 addi t5,t5,312 # 8000026c -8000013c: 079212b7 lui t0,0x7921 -80000140: 80828293 addi t0,t0,-2040 # 7920808 <_start-0x786df7f8> -80000144: 3a029073 csrw pmpcfg0,t0 -80000148: 800080b7 lui ra,0x80008 -8000014c: deadc137 lui sp,0xdeadc -80000150: eef10113 addi sp,sp,-273 # deadbeef -80000154: 0020a023 sw sp,0(ra) # 80008000 -80000158: 00000f17 auipc t5,0x0 -8000015c: 010f0f13 addi t5,t5,16 # 80000168 -80000160: 0000a183 lw gp,0(ra) -80000164: 1080006f j 8000026c +80000140 : +80000140: 00100e13 li t3,1 +80000144: 00000f17 auipc t5,0x0 +80000148: 148f0f13 addi t5,t5,328 # 8000028c +8000014c: 079212b7 lui t0,0x7921 +80000150: 80828293 addi t0,t0,-2040 # 7920808 <_start-0x786df7f8> +80000154: 3a029073 csrw pmpcfg0,t0 +80000158: 3a002373 csrr t1,pmpcfg0 +8000015c: 12629863 bne t0,t1,8000028c +80000160: 800080b7 lui ra,0x80008 +80000164: deadc137 lui sp,0xdeadc +80000168: eef10113 addi sp,sp,-273 # deadbeef +8000016c: 0020a023 sw sp,0(ra) # 80008000 +80000170: 00000f17 auipc t5,0x0 +80000174: 010f0f13 addi t5,t5,16 # 80000180 +80000178: 0000a183 lw gp,0(ra) +8000017c: 1100006f j 8000028c -80000168 : -80000168: 00200e13 li t3,2 -8000016c: 00000f17 auipc t5,0x0 -80000170: 100f0f13 addi t5,t5,256 # 8000026c -80000174: 071202b7 lui t0,0x7120 -80000178: 3a029073 csrw pmpcfg0,t0 -8000017c: 800080b7 lui ra,0x80008 -80000180: deadc137 lui sp,0xdeadc -80000184: eef10113 addi sp,sp,-273 # deadbeef -80000188: 0020a023 sw sp,0(ra) # 80008000 -8000018c: 00000f17 auipc t5,0x0 -80000190: 010f0f13 addi t5,t5,16 # 8000019c -80000194: 0000a183 lw gp,0(ra) -80000198: 0d40006f j 8000026c +80000180 : +80000180: 00200e13 li t3,2 +80000184: 00000f17 auipc t5,0x0 +80000188: 108f0f13 addi t5,t5,264 # 8000028c +8000018c: 071202b7 lui t0,0x7120 +80000190: 3a029073 csrw pmpcfg0,t0 +80000194: 3a002373 csrr t1,pmpcfg0 +80000198: 0e628a63 beq t0,t1,8000028c +8000019c: 800080b7 lui ra,0x80008 +800001a0: deadc137 lui sp,0xdeadc +800001a4: eef10113 addi sp,sp,-273 # deadbeef +800001a8: 0020a023 sw sp,0(ra) # 80008000 +800001ac: 00000f17 auipc t5,0x0 +800001b0: 010f0f13 addi t5,t5,16 # 800001bc +800001b4: 0000a183 lw gp,0(ra) +800001b8: 0d40006f j 8000028c -8000019c : -8000019c: 00300e13 li t3,3 -800001a0: 00000f17 auipc t5,0x0 -800001a4: 0ccf0f13 addi t5,t5,204 # 8000026c -800001a8: 00000117 auipc sp,0x0 -800001ac: 01010113 addi sp,sp,16 # 800001b8 -800001b0: 34111073 csrw mepc,sp -800001b4: 30200073 mret +800001bc : +800001bc: 00300e13 li t3,3 +800001c0: 00000f17 auipc t5,0x0 +800001c4: 0ccf0f13 addi t5,t5,204 # 8000028c +800001c8: 00000117 auipc sp,0x0 +800001cc: 01010113 addi sp,sp,16 # 800001d8 +800001d0: 34111073 csrw mepc,sp +800001d4: 30200073 mret -800001b8 : -800001b8: 00400e13 li t3,4 -800001bc: 00000f17 auipc t5,0x0 -800001c0: 0b0f0f13 addi t5,t5,176 # 8000026c -800001c4: deadc137 lui sp,0xdeadc -800001c8: eef10113 addi sp,sp,-273 # deadbeef -800001cc: 800080b7 lui ra,0x80008 -800001d0: 0020a023 sw sp,0(ra) # 80008000 -800001d4: 00000f17 auipc t5,0x0 -800001d8: 010f0f13 addi t5,t5,16 # 800001e4 -800001dc: 0000a183 lw gp,0(ra) -800001e0: 08c0006f j 8000026c +800001d8 : +800001d8: 00400e13 li t3,4 +800001dc: 00000f17 auipc t5,0x0 +800001e0: 0b0f0f13 addi t5,t5,176 # 8000028c +800001e4: deadc137 lui sp,0xdeadc +800001e8: eef10113 addi sp,sp,-273 # deadbeef +800001ec: 800080b7 lui ra,0x80008 +800001f0: 0020a023 sw sp,0(ra) # 80008000 +800001f4: 00000f17 auipc t5,0x0 +800001f8: 010f0f13 addi t5,t5,16 # 80000204 +800001fc: 0000a183 lw gp,0(ra) +80000200: 08c0006f j 8000028c -800001e4 : -800001e4: 00500e13 li t3,5 -800001e8: deadc137 lui sp,0xdeadc -800001ec: eef10113 addi sp,sp,-273 # deadbeef -800001f0: 800000b7 lui ra,0x80000 -800001f4: 0020a023 sw sp,0(ra) # 80000000 -800001f8: 0000a183 lw gp,0(ra) -800001fc: 06311863 bne sp,gp,8000026c +80000204 : +80000204: 00500e13 li t3,5 +80000208: deadc137 lui sp,0xdeadc +8000020c: eef10113 addi sp,sp,-273 # deadbeef +80000210: 800000b7 lui ra,0x80000 +80000214: 0020a023 sw sp,0(ra) # 80000000 +80000218: 0000a183 lw gp,0(ra) +8000021c: 06311863 bne sp,gp,8000028c -80000200 : -80000200: 00600e13 li t3,6 -80000204: 800100b7 lui ra,0x80010 -80000208: 0000a183 lw gp,0(ra) # 80010000 -8000020c: 00000f17 auipc t5,0x0 -80000210: 06cf0f13 addi t5,t5,108 # 80000278 -80000214: 0030a023 sw gp,0(ra) -80000218: 0540006f j 8000026c +80000220 : +80000220: 00600e13 li t3,6 +80000224: 800100b7 lui ra,0x80010 +80000228: 0000a183 lw gp,0(ra) # 80010000 +8000022c: 00000f17 auipc t5,0x0 +80000230: 06cf0f13 addi t5,t5,108 # 80000298 +80000234: 0030a023 sw gp,0(ra) +80000238: 0540006f j 8000028c -8000021c : -8000021c: 00700e13 li t3,7 -80000220: 00000f17 auipc t5,0x0 -80000224: 04cf0f13 addi t5,t5,76 # 8000026c -80000228: deadc137 lui sp,0xdeadc -8000022c: eef10113 addi sp,sp,-273 # deadbeef -80000230: 800300b7 lui ra,0x80030 -80000234: ff808093 addi ra,ra,-8 # 8002fff8 -80000238: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> -8000023c: 00000f17 auipc t5,0x0 -80000240: fa8f0f13 addi t5,t5,-88 # 800001e4 -80000244: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000248: 0240006f j 8000026c - -8000024c : -8000024c: 00800e13 li t3,8 -80000250: 800400b7 lui ra,0x80040 -80000254: ff808093 addi ra,ra,-8 # 8003fff8 -80000258: 0000a183 lw gp,0(ra) +8000023c : +8000023c: 00700e13 li t3,7 +80000240: 00000f17 auipc t5,0x0 +80000244: 04cf0f13 addi t5,t5,76 # 8000028c +80000248: deadc137 lui sp,0xdeadc +8000024c: eef10113 addi sp,sp,-273 # deadbeef +80000250: 800300b7 lui ra,0x80030 +80000254: ff808093 addi ra,ra,-8 # 8002fff8 +80000258: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> 8000025c: 00000f17 auipc t5,0x0 -80000260: 01cf0f13 addi t5,t5,28 # 80000278 -80000264: 0030a023 sw gp,0(ra) -80000268: 0040006f j 8000026c +80000260: fa8f0f13 addi t5,t5,-88 # 80000204 +80000264: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000268: 0240006f j 8000028c -8000026c : -8000026c: f0100137 lui sp,0xf0100 -80000270: f2410113 addi sp,sp,-220 # f00fff24 -80000274: 01c12023 sw t3,0(sp) +8000026c : +8000026c: 00800e13 li t3,8 +80000270: 800400b7 lui ra,0x80040 +80000274: ff808093 addi ra,ra,-8 # 8003fff8 +80000278: 0000a183 lw gp,0(ra) +8000027c: 00000f17 auipc t5,0x0 +80000280: 01cf0f13 addi t5,t5,28 # 80000298 +80000284: 0030a023 sw gp,0(ra) +80000288: 0040006f j 8000028c -80000278 : -80000278: f0100137 lui sp,0xf0100 -8000027c: f2010113 addi sp,sp,-224 # f00fff20 -80000280: 00012023 sw zero,0(sp) +8000028c : +8000028c: f0100137 lui sp,0xf0100 +80000290: f2410113 addi sp,sp,-220 # f00fff24 +80000294: 01c12023 sw t3,0(sp) + +80000298 : +80000298: f0100137 lui sp,0xf0100 +8000029c: f2010113 addi sp,sp,-224 # f00fff20 +800002a0: 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 index 75d1010c91fc4338946e1dadf660f4690f889fa6..89007214ac506ba500d1b940ddf23ee6c5aba736 100755 GIT binary patch delta 369 zcmdm^bw_K00%OiZMP=3{ObiT5HhSLTw^ZNGz|dgc1jGl|-VGG8LX0LB`Hk~5zyfPa;%dlBq>a85Ll=$XDBk6 zk%0lMLBdc(m`{K~oS%U~n7?0SyU--|$xTfSa06x}2~DmMl#^o+6y{TaDHA}kqbrGT zbB$mPV|@=3LjwaCFfzyhX$M9GUkS)>K;mlv`FoJ~dO-dSB)$od&w^y06_Brh#CHJl zXCU!i85o2ZY>))JfeLaacMAV!Tr#;+L>Wk~6;WqAGWjZyyfXQ(h&rpG2m^!Fi?2rN_=GZdN3$iM)W7cdkN<`ZBL=VxFL z=IB5$Y($@-vP+2K;pYHFbFZoAPIN_75GeEDg2+Y jW%5c9WgvN0M4fTT Date: Wed, 20 Jan 2021 14:16:10 +0100 Subject: [PATCH 30/30] Remove registers storing PMP region bounds --- .../scala/vexriscv/plugin/PmpPlugin.scala | 33 ++-- src/test/cpp/raw/pmp/build/pmp.asm | 185 +++++++++--------- src/test/cpp/raw/pmp/build/pmp.elf | Bin 5468 -> 5480 bytes src/test/cpp/raw/pmp/build/pmp.hex | 54 ++--- src/test/cpp/raw/pmp/build/pmp.map | 12 +- src/test/cpp/raw/pmp/src/crt.S | 3 + 6 files changed, 146 insertions(+), 141 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index 5f008b4..73c15af 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -86,8 +86,8 @@ case class PmpRegister(previous : PmpRegister) extends Area { val addr = UInt(32 bits) } - // Last assignment wins; nothing happens if a user-initiated write did not - // occur on this clock cycle. + // Last valid assignment wins; nothing happens if a user-initiated write did + // not occur on this clock cycle. csr.r := state.r csr.w := state.w csr.x := state.x @@ -97,8 +97,8 @@ case class PmpRegister(previous : PmpRegister) extends Area { // Computed PMP region bounds val region = new Area { - val valid = Bool - val start, end = Reg(UInt(32 bits)) + val valid, locked = Bool + val start, end = UInt(32 bits) } when(~state.l) { @@ -114,32 +114,31 @@ case class PmpRegister(previous : PmpRegister) extends Area { } } - val shifted = csr.addr |<< 2 + val shifted = state.addr |<< 2 + val mask = state.addr & ~(state.addr + 1) + val masked = (state.addr & ~mask) |<< 2 + + // PMP changes take effect two clock cycles after the initial CSR write (i.e., + // settings propagate from csr -> state -> region). + region.locked := state.l region.valid := True - switch(state.a) { + switch(csr.a) { is(TOR) { - if (previous == null) { - region.start := 0 - } else { - region.start := previous.region.end - } + if (previous == null) region.start := 0 + else region.start := previous.region.end region.end := shifted } - is(NA4) { region.start := shifted region.end := shifted + 4 } - is(NAPOT) { - val mask = state.addr & ~(state.addr + 1) - val masked = (state.addr & ~mask) |<< 2 region.start := masked region.end := masked + ((mask + 1) |<< 3) } - default { + region.start := 0 region.end := shifted region.valid := False } @@ -221,7 +220,7 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] val hits = pmps.map(pmp => pmp.region.valid & pmp.region.start <= address & pmp.region.end > address & - (pmp.state.l | ~privilegeService.isMachine())) + (pmp.region.locked | ~privilegeService.isMachine())) // M-mode has full access by default, others have none. when(CountOne(hits) === 0) { diff --git a/src/test/cpp/raw/pmp/build/pmp.asm b/src/test/cpp/raw/pmp/build/pmp.asm index 5c7605b..4508ee6 100644 --- a/src/test/cpp/raw/pmp/build/pmp.asm +++ b/src/test/cpp/raw/pmp/build/pmp.asm @@ -17,21 +17,21 @@ Disassembly of section .crt_section: 80000018 : 80000018: 00000e13 li t3,0 8000001c: 00000f17 auipc t5,0x0 -80000020: 270f0f13 addi t5,t5,624 # 8000028c +80000020: 27cf0f13 addi t5,t5,636 # 80000298 80000024: 800000b7 lui ra,0x80000 80000028: 80008237 lui tp,0x80008 8000002c: deadc137 lui sp,0xdeadc -80000030: eef10113 addi sp,sp,-273 # deadbeef -80000034: 0020a023 sw sp,0(ra) # 80000000 -80000038: 00222023 sw sp,0(tp) # 80008000 +80000030: eef10113 addi sp,sp,-273 # deadbeef +80000034: 0020a023 sw sp,0(ra) # 80000000 +80000038: 00222023 sw sp,0(tp) # 80008000 8000003c: 0000a183 lw gp,0(ra) -80000040: 24311663 bne sp,gp,8000028c +80000040: 24311c63 bne sp,gp,80000298 80000044: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000048: 24311263 bne sp,gp,8000028c +80000048: 24311863 bne sp,gp,80000298 8000004c: 071202b7 lui t0,0x7120 80000050: 3a029073 csrw pmpcfg0,t0 80000054: 3a002373 csrr t1,pmpcfg0 -80000058: 22629a63 bne t0,t1,8000028c +80000058: 24629063 bne t0,t1,80000298 8000005c: 191f02b7 lui t0,0x191f0 80000060: 30428293 addi t0,t0,772 # 191f0304 <_start-0x66e0fcfc> 80000064: 3a129073 csrw pmpcfg1,t0 @@ -44,7 +44,7 @@ Disassembly of section .crt_section: 80000080: 200002b7 lui t0,0x20000 80000084: 3b029073 csrw pmpaddr0,t0 80000088: 3b002373 csrr t1,pmpaddr0 -8000008c: 20629063 bne t0,t1,8000028c +8000008c: 20629663 bne t0,t1,80000298 80000090: fff00293 li t0,-1 80000094: 3b129073 csrw pmpaddr1,t0 80000098: 200022b7 lui t0,0x20002 @@ -85,116 +85,119 @@ Disassembly of section .crt_section: 80000124: 0020a023 sw sp,0(ra) 80000128: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> 8000012c: 0000a183 lw gp,0(ra) -80000130: 14311e63 bne sp,gp,8000028c +80000130: 16311463 bne sp,gp,80000298 80000134: 00000193 li gp,0 80000138: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -8000013c: 14311863 bne sp,gp,8000028c +8000013c: 14311e63 bne sp,gp,80000298 80000140 : 80000140: 00100e13 li t3,1 80000144: 00000f17 auipc t5,0x0 -80000148: 148f0f13 addi t5,t5,328 # 8000028c +80000148: 154f0f13 addi t5,t5,340 # 80000298 8000014c: 079212b7 lui t0,0x7921 80000150: 80828293 addi t0,t0,-2040 # 7920808 <_start-0x786df7f8> 80000154: 3a029073 csrw pmpcfg0,t0 80000158: 3a002373 csrr t1,pmpcfg0 -8000015c: 12629863 bne t0,t1,8000028c +8000015c: 12629e63 bne t0,t1,80000298 80000160: 800080b7 lui ra,0x80008 80000164: deadc137 lui sp,0xdeadc -80000168: eef10113 addi sp,sp,-273 # deadbeef -8000016c: 0020a023 sw sp,0(ra) # 80008000 +80000168: eef10113 addi sp,sp,-273 # deadbeef +8000016c: 0020a023 sw sp,0(ra) # 80008000 80000170: 00000f17 auipc t5,0x0 80000174: 010f0f13 addi t5,t5,16 # 80000180 80000178: 0000a183 lw gp,0(ra) -8000017c: 1100006f j 8000028c +8000017c: 11c0006f j 80000298 80000180 : 80000180: 00200e13 li t3,2 80000184: 00000f17 auipc t5,0x0 -80000188: 108f0f13 addi t5,t5,264 # 8000028c +80000188: 114f0f13 addi t5,t5,276 # 80000298 8000018c: 071202b7 lui t0,0x7120 80000190: 3a029073 csrw pmpcfg0,t0 80000194: 3a002373 csrr t1,pmpcfg0 -80000198: 0e628a63 beq t0,t1,8000028c -8000019c: 800080b7 lui ra,0x80008 -800001a0: deadc137 lui sp,0xdeadc -800001a4: eef10113 addi sp,sp,-273 # deadbeef -800001a8: 0020a023 sw sp,0(ra) # 80008000 -800001ac: 00000f17 auipc t5,0x0 -800001b0: 010f0f13 addi t5,t5,16 # 800001bc -800001b4: 0000a183 lw gp,0(ra) -800001b8: 0d40006f j 8000028c +80000198: 3b205073 csrwi pmpaddr2,0 +8000019c: 3b202373 csrr t1,pmpaddr2 +800001a0: 0e030c63 beqz t1,80000298 +800001a4: 0e628a63 beq t0,t1,80000298 +800001a8: 800080b7 lui ra,0x80008 +800001ac: deadc137 lui sp,0xdeadc +800001b0: eef10113 addi sp,sp,-273 # deadbeef +800001b4: 0020a023 sw sp,0(ra) # 80008000 +800001b8: 00000f17 auipc t5,0x0 +800001bc: 010f0f13 addi t5,t5,16 # 800001c8 +800001c0: 0000a183 lw gp,0(ra) +800001c4: 0d40006f j 80000298 -800001bc : -800001bc: 00300e13 li t3,3 -800001c0: 00000f17 auipc t5,0x0 -800001c4: 0ccf0f13 addi t5,t5,204 # 8000028c -800001c8: 00000117 auipc sp,0x0 -800001cc: 01010113 addi sp,sp,16 # 800001d8 -800001d0: 34111073 csrw mepc,sp -800001d4: 30200073 mret +800001c8 : +800001c8: 00300e13 li t3,3 +800001cc: 00000f17 auipc t5,0x0 +800001d0: 0ccf0f13 addi t5,t5,204 # 80000298 +800001d4: 00000117 auipc sp,0x0 +800001d8: 01010113 addi sp,sp,16 # 800001e4 +800001dc: 34111073 csrw mepc,sp +800001e0: 30200073 mret -800001d8 : -800001d8: 00400e13 li t3,4 -800001dc: 00000f17 auipc t5,0x0 -800001e0: 0b0f0f13 addi t5,t5,176 # 8000028c -800001e4: deadc137 lui sp,0xdeadc -800001e8: eef10113 addi sp,sp,-273 # deadbeef -800001ec: 800080b7 lui ra,0x80008 -800001f0: 0020a023 sw sp,0(ra) # 80008000 -800001f4: 00000f17 auipc t5,0x0 -800001f8: 010f0f13 addi t5,t5,16 # 80000204 -800001fc: 0000a183 lw gp,0(ra) -80000200: 08c0006f j 8000028c +800001e4 : +800001e4: 00400e13 li t3,4 +800001e8: 00000f17 auipc t5,0x0 +800001ec: 0b0f0f13 addi t5,t5,176 # 80000298 +800001f0: deadc137 lui sp,0xdeadc +800001f4: eef10113 addi sp,sp,-273 # deadbeef +800001f8: 800080b7 lui ra,0x80008 +800001fc: 0020a023 sw sp,0(ra) # 80008000 +80000200: 00000f17 auipc t5,0x0 +80000204: 010f0f13 addi t5,t5,16 # 80000210 +80000208: 0000a183 lw gp,0(ra) +8000020c: 08c0006f j 80000298 -80000204 : -80000204: 00500e13 li t3,5 -80000208: deadc137 lui sp,0xdeadc -8000020c: eef10113 addi sp,sp,-273 # deadbeef -80000210: 800000b7 lui ra,0x80000 -80000214: 0020a023 sw sp,0(ra) # 80000000 -80000218: 0000a183 lw gp,0(ra) -8000021c: 06311863 bne sp,gp,8000028c +80000210 : +80000210: 00500e13 li t3,5 +80000214: deadc137 lui sp,0xdeadc +80000218: eef10113 addi sp,sp,-273 # deadbeef +8000021c: 800000b7 lui ra,0x80000 +80000220: 0020a023 sw sp,0(ra) # 80000000 +80000224: 0000a183 lw gp,0(ra) +80000228: 06311863 bne sp,gp,80000298 -80000220 : -80000220: 00600e13 li t3,6 -80000224: 800100b7 lui ra,0x80010 -80000228: 0000a183 lw gp,0(ra) # 80010000 -8000022c: 00000f17 auipc t5,0x0 -80000230: 06cf0f13 addi t5,t5,108 # 80000298 -80000234: 0030a023 sw gp,0(ra) -80000238: 0540006f j 8000028c +8000022c : +8000022c: 00600e13 li t3,6 +80000230: 800100b7 lui ra,0x80010 +80000234: 0000a183 lw gp,0(ra) # 80010000 +80000238: 00000f17 auipc t5,0x0 +8000023c: 06cf0f13 addi t5,t5,108 # 800002a4 +80000240: 0030a023 sw gp,0(ra) +80000244: 0540006f j 80000298 -8000023c : -8000023c: 00700e13 li t3,7 -80000240: 00000f17 auipc t5,0x0 -80000244: 04cf0f13 addi t5,t5,76 # 8000028c -80000248: deadc137 lui sp,0xdeadc -8000024c: eef10113 addi sp,sp,-273 # deadbeef -80000250: 800300b7 lui ra,0x80030 -80000254: ff808093 addi ra,ra,-8 # 8002fff8 -80000258: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> -8000025c: 00000f17 auipc t5,0x0 -80000260: fa8f0f13 addi t5,t5,-88 # 80000204 -80000264: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000268: 0240006f j 8000028c +80000248 : +80000248: 00700e13 li t3,7 +8000024c: 00000f17 auipc t5,0x0 +80000250: 04cf0f13 addi t5,t5,76 # 80000298 +80000254: deadc137 lui sp,0xdeadc +80000258: eef10113 addi sp,sp,-273 # deadbeef +8000025c: 800300b7 lui ra,0x80030 +80000260: ff808093 addi ra,ra,-8 # 8002fff8 +80000264: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +80000268: 00000f17 auipc t5,0x0 +8000026c: fa8f0f13 addi t5,t5,-88 # 80000210 +80000270: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000274: 0240006f j 80000298 -8000026c : -8000026c: 00800e13 li t3,8 -80000270: 800400b7 lui ra,0x80040 -80000274: ff808093 addi ra,ra,-8 # 8003fff8 -80000278: 0000a183 lw gp,0(ra) -8000027c: 00000f17 auipc t5,0x0 -80000280: 01cf0f13 addi t5,t5,28 # 80000298 -80000284: 0030a023 sw gp,0(ra) -80000288: 0040006f j 8000028c +80000278 : +80000278: 00800e13 li t3,8 +8000027c: 800400b7 lui ra,0x80040 +80000280: ff808093 addi ra,ra,-8 # 8003fff8 +80000284: 0000a183 lw gp,0(ra) +80000288: 00000f17 auipc t5,0x0 +8000028c: 01cf0f13 addi t5,t5,28 # 800002a4 +80000290: 0030a023 sw gp,0(ra) +80000294: 0040006f j 80000298 -8000028c : -8000028c: f0100137 lui sp,0xf0100 -80000290: f2410113 addi sp,sp,-220 # f00fff24 -80000294: 01c12023 sw t3,0(sp) - -80000298 : +80000298 : 80000298: f0100137 lui sp,0xf0100 -8000029c: f2010113 addi sp,sp,-224 # f00fff20 -800002a0: 00012023 sw zero,0(sp) +8000029c: f2410113 addi sp,sp,-220 # f00fff24 +800002a0: 01c12023 sw t3,0(sp) + +800002a4 : +800002a4: f0100137 lui sp,0xf0100 +800002a8: f2010113 addi sp,sp,-224 # f00fff20 +800002ac: 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 index 89007214ac506ba500d1b940ddf23ee6c5aba736..b844a20189743c473a3eeb6c94fa6b6976f7932d 100755 GIT binary patch delta 334 zcmcbk^+Icc0%OHQMP=3vObiSgHhSLVw>q!Boq?gjya|X8uDvJB`0<_c0tE(T1to^& zg$xYIGKMP6icAd25{4?GOnPe@Xk93x=JIBjyDz+znyL$S$>3=CkE za)u(pd;$#O{0t1j{Qjcbg(k62Zfa_P>zp?^PEbMXfS@p+0!)!0veCr>3f9HS3f9Ry z%zVjRNqmzN1m!mG5{zSHoH1EaSU>RuBSQlN7%(#E0qG}5d=nsFfC(XQ1?1}>@g0Et zB}jZ%Am0Ot?+xTvOkOGcpK-(Fl_JVO@~ntD8p~z%L1_rQ7 z2}2QKJ^==Ceg+0%{(h0|LX+4hH#IfDb^%qd<7)F1CT!hiSG*J+aU41f&84w kTZR8KE}6VlL>Wll6j5h9GMQ0So$<