diff --git a/README.md b/README.md index 739ca08..4fdeec2 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ - [CPU generation](#cpu-generation) - [Regression tests](#regression-tests) - [Interactive debug of the simulated CPU via GDB OpenOCD and Verilator](#interactive-debug-of-the-simulated-cpu-via-gdb-openocd-and-verilator) -- [Using Eclipse to run and debug the software](#using-Eclipse-to-run-and-debug-the-software) - * [By using gnu-mcu-eclipse](#by-using-gnu-mcu-eclipse) - * [By using Zylin plugin (old)](#by-using-zylin-plugin-old) +- [Using Eclipse to run and debug the software](#using-eclipse-to-run-and-debug-the-software) + - [By using gnu-mcu-eclipse](#by-using-gnu-mcu-eclipse) + - [By using Zylin plugin (old)](#by-using-zylin-plugin-old) - [Briey SoC](#briey-soc) - [Murax SoC](#murax-soc) - [Running Linux](#running-linux) @@ -19,8 +19,35 @@ - [Adding a new CSR via the plugin system](#adding-a-new-csr-via-the-plugin-system) - [CPU clock and resets](#cpu-clock-and-resets) - [VexRiscv Architecture](#vexriscv-architecture) - * [FPU](#fpu) - * [Plugins](#plugins) + - [FPU](#fpu) + - [Plugins](#plugins) + - [IBusSimplePlugin](#ibussimpleplugin) + - [IBusCachedPlugin](#ibuscachedplugin) + - [DecoderSimplePlugin](#decodersimpleplugin) + - [RegFilePlugin](#regfileplugin) + - [HazardSimplePlugin](#hazardsimpleplugin) + - [SrcPlugin](#srcplugin) + - [IntAluPlugin](#intaluplugin) + - [LightShifterPlugin](#lightshifterplugin) + - [FullBarrelShifterPlugin](#fullbarrelshifterplugin) + - [BranchPlugin](#branchplugin) + - [Prediction NONE](#prediction-none) + - [Prediction STATIC](#prediction-static) + - [Prediction DYNAMIC](#prediction-dynamic) + - [Prediction DYNAMIC_TARGET](#prediction-dynamic_target) + - [DBusSimplePlugin](#dbussimpleplugin) + - [DBusCachedPlugin](#dbuscachedplugin) + - [MulPlugin](#mulplugin) + - [DivPlugin](#divplugin) + - [MulDivIterativePlugin](#muldiviterativeplugin) + - [CsrPlugin](#csrplugin) + - [StaticMemoryTranslatorPlugin](#staticmemorytranslatorplugin) + - [MmuPlugin](#mmuplugin) + - [PmpPlugin](#pmpplugin) + - [DebugPlugin](#debugplugin) + - [YamlPlugin](#yamlplugin) + - [FpuPlugin](#fpuplugin) + - [AesPlugin](#aesplugin) @@ -1082,6 +1109,10 @@ Static memory translator plugin which allows to specify which range of the memor Hardware refilled MMU implementation. Allows other plugins such as DBusCachedPlugin/IBusCachedPlugin to instanciate memory address translation ports. Each port has a small dedicated fully associative TLB cache which is refilled automaticaly via a dbus access sharing. +#### PmpPlugin + +This is a physical memory protection (PMP) plugin which conforms to the latest RISC-V privilege specification. PMP is configured by writing two special CSRs: `pmpcfg#` and `pmpaddr#`. The former contains the permissions and addressing modes for four protection regions, and the latter contains the encoded start address for a single region. Since the actual region bounds must be computed from the values written to these registers, writing them takes a few CPU cylces. This delay is necessary in order to centralize all of the decoding logic into a single component. Otherwise, it would have to be duplicated for each region, even though the decoding operation happens only when PMP is reprogrammed (e.g., on some context switches). + #### DebugPlugin This plugin implements enough CPU debug features to allow comfortable GDB/Eclipse debugging. To access those debug features, it provides a simple memory bus interface. diff --git a/src/main/scala/vexriscv/demo/GenSecure.scala b/src/main/scala/vexriscv/demo/GenSecure.scala index 2835b44..8b2cd55 100644 --- a/src/main/scala/vexriscv/demo/GenSecure.scala +++ b/src/main/scala/vexriscv/demo/GenSecure.scala @@ -41,6 +41,7 @@ object GenSecure extends App { ), new PmpPlugin( regions = 16, + granularity = 32, ioRange = _(31 downto 28) === 0xf ), new DecoderSimplePlugin( diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index db30cdd..ea60f64 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -364,8 +364,10 @@ case class CsrMapping() extends Area with CsrInterface { override def during(csrAddress: Int)(body: => Unit): Unit = addMappingAt(csrAddress, CsrDuring(() => body)) override def onRead(csrAddress: Int)(body: => Unit): Unit = addMappingAt(csrAddress, CsrOnRead(() => {body})) override def duringAny(): Bool = ??? - override def durringWrite(body: => Unit) : Unit = always += CsrDuringRead(() => body) - override def durringRead(body: => Unit) : Unit = always += CsrDuringWrite(() => body) + override def duringAnyRead(body: => Unit) : Unit = always += CsrDuringRead(() => body) + override def duringAnyWrite(body: => Unit) : Unit = always += CsrDuringWrite(() => body) + override def onAnyRead(body: => Unit) : Unit = always += CsrOnRead(() => body) + override def onAnyWrite(body: => Unit) : Unit = always += CsrOnWrite(() => body) override def readData() = readDataSignal override def writeData() = writeDataSignal override def allowCsr() = allowCsrSignal := True @@ -386,8 +388,10 @@ trait CsrInterface{ r(csrAddress,bitOffset,that) w(csrAddress,bitOffset,that) } - def durringWrite(body: => Unit) : Unit //Called all the durration of a Csr write instruction in the execute stage - def durringRead(body: => Unit) : Unit //same than above for read + def duringAnyRead(body: => Unit) : Unit //Called all the durration of a Csr write instruction in the execute stage + def duringAnyWrite(body: => Unit) : Unit //same than above for read + def onAnyRead(body: => Unit) : Unit + def onAnyWrite(body: => Unit) : Unit def allowCsr() : Unit //In case your csr do not use the regular API with csrAddress but is implemented using "side channels", you can call that if the current csr is implemented def isHazardFree() : Bool // You should not have any side effect nor use readData() until this return True @@ -516,8 +520,10 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep override def duringRead(csrAddress: Int)(body: => Unit): Unit = csrMapping.duringRead(csrAddress)(body) override def during(csrAddress: Int)(body: => Unit): Unit = csrMapping.during(csrAddress)(body) override def duringAny(): Bool = pipeline.execute.arbitration.isValid && pipeline.execute.input(IS_CSR) - override def durringWrite(body: => Unit) = csrMapping.durringWrite(body) - override def durringRead(body: => Unit) = csrMapping.durringRead(body) + override def duringAnyRead(body: => Unit) = csrMapping.duringAnyRead(body) + override def duringAnyWrite(body: => Unit) = csrMapping.duringAnyWrite(body) + override def onAnyRead(body: => Unit) = csrMapping.onAnyRead(body) + override def onAnyWrite(body: => Unit) = csrMapping.onAnyWrite(body) override def allowCsr() = csrMapping.allowCsr() override def readData() = csrMapping.readData() override def writeData() = csrMapping.writeData() @@ -1279,6 +1285,8 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep csrMapping.always.foreach { case element : CsrDuringWrite => when(writeInstruction){element.doThat()} case element : CsrDuringRead => when(readInstruction){element.doThat()} + case element : CsrOnWrite => when(writeEnable){element.doThat()} + case element : CsrOnRead => when(readEnable){element.doThat()} } illegalAccess clearWhen(csrMapping.allowCsrSignal) diff --git a/src/main/scala/vexriscv/plugin/PmpPlugin.scala b/src/main/scala/vexriscv/plugin/PmpPlugin.scala index e6cb396..7c1330b 100644 --- a/src/main/scala/vexriscv/plugin/PmpPlugin.scala +++ b/src/main/scala/vexriscv/plugin/PmpPlugin.scala @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samuel Lindemer + * Copyright (c) 2021 Samuel Lindemer * * SPDX-License-Identifier: MIT */ @@ -7,9 +7,10 @@ package vexriscv.plugin import vexriscv.{VexRiscv, _} +import vexriscv.plugin.MemoryTranslatorPort.{_} import spinal.core._ import spinal.lib._ -import scala.collection.mutable.ArrayBuffer +import spinal.lib.fsm._ /* Each 32-bit pmpcfg# register contains four 8-bit configuration sections. * These section numbers contain flags which apply to regions defined by the @@ -61,106 +62,60 @@ import scala.collection.mutable.ArrayBuffer * * NA4: This is essentially an edge case of NAPOT where the entire pmpaddr# * register defines a 4-byte wide region. + * + * N.B. THIS IMPLEMENTATION ONLY SUPPORTS NAPOT ADDRESSING. REGIONS ARE NOT + * ORDERED BY PRIORITY. A PERMISSION IS GRANTED TO AN ACCESS IF ANY MATCHING + * PMP REGION HAS THAT PERMISSION ENABLED. */ -case class PmpRegister(previous : PmpRegister) extends Area { - +trait Pmp { def OFF = 0 def TOR = 1 def NA4 = 2 def NAPOT = 3 - 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)) + def xlen = 32 + def rBit = 0 + def wBit = 1 + def xBit = 2 + def aBits = 4 downto 3 + def lBit = 7 +} + +class PmpSetter(cutoff : Int) extends Component with Pmp { + val io = new Bundle { + val addr = in UInt(xlen bits) + val base, mask = out UInt(xlen - cutoff bits) } - // 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 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 - csr.l := state.l - csr.a := state.a - csr.addr := state.addr - - // Computed PMP region bounds - val region = new Area { - val valid, locked = Bool - val start, end = UInt(32 bits) - } - - 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 - - if (csr.l == True & csr.a == TOR) { - previous.state.l := True - } - } - - 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(csr.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(NAPOT) { - region.start := masked - region.end := masked + ((mask + 1) |<< 3) - } - default { - region.start := 0 - region.end := shifted - region.valid := False - } - } + val ones = io.addr & ~(io.addr + 1) + io.base := io.addr(xlen - 3 downto cutoff - 2) ^ ones(xlen - 3 downto cutoff - 2) + io.mask := ~ones(xlen - 2 downto cutoff - 1) } 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]() +class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] with MemoryTranslator with Pmp { + assert(regions % 4 == 0 & regions <= 16) + assert(granularity >= 8) + var setter : PmpSetter = null + var dPort, iPort : ProtectedMemoryTranslatorPort = null + val cutoff = log2Up(granularity) - 1 + override def newTranslationPort(priority : Int, args : Any): MemoryTranslatorBus = { val port = ProtectedMemoryTranslatorPort(MemoryTranslatorBus(new MemoryTranslatorBusParameter(0, 0))) - portsInfo += port + priority match { + case PRIORITY_INSTRUCTION => iPort = port + case PRIORITY_DATA => dPort = port + } port.bus } + override def setup(pipeline: VexRiscv): Unit = { + setter = new PmpSetter(cutoff) + } + override def build(pipeline: VexRiscv): Unit = { import pipeline.config._ import pipeline._ @@ -169,78 +124,182 @@ class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] val csrService = pipeline.service(classOf[CsrInterface]) val privilegeService = pipeline.service(classOf[PrivilegeService]) - val core = pipeline plug new Area { + val pmpaddr = Mem(UInt(xlen bits), regions) + val pmpcfg = Vector.fill(regions)(Reg(Bits(8 bits)) init(0)) + val base, mask = Vector.fill(regions)(Reg(UInt(xlen - cutoff bits))) - // Instantiate pmpaddr0 ... pmpaddr# CSRs. - for (i <- 0 until regions) { - if (i == 0) { - pmps += PmpRegister(null) - } else { - pmps += PmpRegister(pmps.last) + def machineMode : Bool = privilegeService.isMachine() + + execute plug new Area { + import execute._ + + val fsmPending = RegInit(False) clearWhen(!arbitration.isStuck) + val fsmComplete = False + val hazardFree = csrService.isHazardFree() + + val csrAddress = input(INSTRUCTION)(csrRange) + val pmpNcfg = csrAddress(log2Up(regions) - 1 downto 0).asUInt + val pmpcfgN = pmpNcfg(log2Up(regions) - 3 downto 0) + val pmpcfgCsr = input(INSTRUCTION)(31 downto 24) === 0x3a + val pmpaddrCsr = input(INSTRUCTION)(31 downto 24) === 0x3b + + val pmpNcfg_ = Reg(UInt(log2Up(regions) bits)) + val pmpcfgN_ = Reg(UInt(log2Up(regions) - 2 bits)) + val pmpcfgCsr_ = RegInit(False) + val pmpaddrCsr_ = RegInit(False) + val writeData_ = Reg(Bits(xlen bits)) + + csrService.duringAnyRead { + when (machineMode) { + when (pmpcfgCsr) { + csrService.allowCsr() + csrService.readData() := + pmpcfg(pmpcfgN @@ U(3, 2 bits)) ## + pmpcfg(pmpcfgN @@ U(2, 2 bits)) ## + pmpcfg(pmpcfgN @@ U(1, 2 bits)) ## + pmpcfg(pmpcfgN @@ U(0, 2 bits)) + } + when (pmpaddrCsr) { + csrService.allowCsr() + csrService.readData() := pmpaddr(pmpNcfg).asBits + } } - 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.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, - 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.duringAnyWrite { + when ((pmpcfgCsr | pmpaddrCsr) & machineMode) { + csrService.allowCsr() + arbitration.haltItself := !fsmComplete + when (!fsmPending) { + fsmPending := True + writeData_ := csrService.writeData() + pmpNcfg_ := pmpNcfg + pmpcfgN_ := pmpcfgN + pmpcfgCsr_ := pmpcfgCsr + pmpaddrCsr_ := pmpaddrCsr + } + } } - // Connect memory ports to PMP logic. - val ports = for ((port, portId) <- portsInfo.zipWithIndex) yield new Area { + val fsm = new StateMachine { + val fsmEnable = RegInit(False) + val fsmCounter = Reg(UInt(log2Up(regions) bits)) init(0) - val address = port.bus.cmd(0).virtualAddress - port.bus.rsp.physicalAddress := address + val stateIdle : State = new State with EntryPoint { + onEntry { + fsmPending := False + fsmEnable := False + fsmComplete := True + fsmCounter := 0 + } + whenIsActive { + when (fsmPending & hazardFree) { + goto(stateWrite) + } + } + } - // 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.locked | ~privilegeService.isMachine())) + val stateWrite : State = new State { + whenIsActive { + when (pmpcfgCsr_) { + val overwrite = writeData_.subdivideIn(8 bits) + for (i <- 0 until 4) { + when (~pmpcfg(pmpcfgN_ @@ U(i, 2 bits))(lBit)) { + pmpcfg(pmpcfgN_ @@ U(i, 2 bits)).assignFromBits(overwrite(i)) + } + } + goto(stateCfg) + } + when (pmpaddrCsr_) { + when (~pmpcfg(pmpNcfg_)(lBit)) { + pmpaddr(pmpNcfg_) := writeData_.asUInt + } + goto(stateAddr) + } + } + onExit (fsmEnable := True) + } - // 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() - port.bus.rsp.allowExecute := privilegeService.isMachine() + val stateCfg : State = new State { + onEntry (fsmCounter := pmpcfgN_ @@ U(0, 2 bits)) + whenIsActive { + fsmCounter := fsmCounter + 1 + when (fsmCounter(1 downto 0) === 3) { + goto(stateIdle) + } + } + } + + val stateAddr : State = new State { + onEntry (fsmCounter := pmpNcfg_) + whenIsActive (goto(stateIdle)) + } + + when (pmpaddrCsr_) { + setter.io.addr := writeData_.asUInt } otherwise { - 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)) + setter.io.addr := pmpaddr(fsmCounter) } + + when (fsmEnable & ~pmpcfg(fsmCounter)(lBit)) { + base(fsmCounter) := setter.io.base + mask(fsmCounter) := setter.io.mask + } + } + } - 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 + pipeline plug new Area { + def getHits(address : UInt) = { + (0 until regions).map(i => + ((address & mask(U(i, log2Up(regions) bits))) === base(U(i, log2Up(regions) bits))) & + (pmpcfg(i)(lBit) | ~machineMode) & (pmpcfg(i)(aBits) === NAPOT) + ) + } + def getPermission(hits : IndexedSeq[Bool], bit : Int) = { + (hits zip pmpcfg).map({ case (i, cfg) => i & cfg(bit) }).orR + } + + val dGuard = new Area { + val address = dPort.bus.cmd(0).virtualAddress + dPort.bus.rsp.physicalAddress := address + dPort.bus.rsp.isIoAccess := ioRange(address) + dPort.bus.rsp.isPaging := False + dPort.bus.rsp.exception := False + dPort.bus.rsp.refilling := False + dPort.bus.rsp.allowExecute := False + dPort.bus.busy := False + + val hits = getHits(address(31 downto cutoff)) + + when(~hits.orR) { + dPort.bus.rsp.allowRead := machineMode + dPort.bus.rsp.allowWrite := machineMode + } otherwise { + dPort.bus.rsp.allowRead := getPermission(hits, rBit) + dPort.bus.rsp.allowWrite := getPermission(hits, wBit) + } + } + + val iGuard = new Area { + val address = iPort.bus.cmd(0).virtualAddress + iPort.bus.rsp.physicalAddress := address + iPort.bus.rsp.isIoAccess := ioRange(address) + iPort.bus.rsp.isPaging := False + iPort.bus.rsp.exception := False + iPort.bus.rsp.refilling := False + iPort.bus.rsp.allowRead := False + iPort.bus.rsp.allowWrite := False + iPort.bus.busy := False + + val hits = getHits(address(31 downto cutoff)) + + when(~hits.orR) { + iPort.bus.rsp.allowExecute := machineMode + } otherwise { + iPort.bus.rsp.allowExecute := getPermission(hits, xBit) + } } } } -} - +} \ No newline at end of file diff --git a/src/test/cpp/raw/pmp/build/pmp.asm b/src/test/cpp/raw/pmp/build/pmp.asm index 4508ee6..34ddcbf 100644 --- a/src/test/cpp/raw/pmp/build/pmp.asm +++ b/src/test/cpp/raw/pmp/build/pmp.asm @@ -5,199 +5,261 @@ build/pmp.elf: file format elf32-littleriscv Disassembly of section .crt_section: 80000000 <_start>: -80000000: 00000097 auipc ra,0x0 -80000004: 01008093 addi ra,ra,16 # 80000010 -80000008: 30509073 csrw mtvec,ra -8000000c: 00c0006f j 80000018 +80000000: 00000493 li s1,0 +80000004: 00000097 auipc ra,0x0 +80000008: 01008093 addi ra,ra,16 # 80000014 +8000000c: 30509073 csrw mtvec,ra +80000010: 0140006f j 80000024 -80000010 : -80000010: 341f1073 csrw mepc,t5 -80000014: 30200073 mret +80000014 : +80000014: 341f1073 csrw mepc,t5 +80000018: 00049463 bnez s1,80000020 +8000001c: 30200073 mret -80000018 : -80000018: 00000e13 li t3,0 -8000001c: 00000f17 auipc t5,0x0 -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 -8000003c: 0000a183 lw gp,0(ra) -80000040: 24311c63 bne sp,gp,80000298 -80000044: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -80000048: 24311863 bne sp,gp,80000298 -8000004c: 071202b7 lui t0,0x7120 -80000050: 3a029073 csrw pmpcfg0,t0 -80000054: 3a002373 csrr t1,pmpcfg0 -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 -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: 20629663 bne t0,t1,80000298 -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: 3bb29073 csrw pmpaddr11,t0 -800000fc: 00000293 li t0,0 -80000100: 3bc29073 csrw pmpaddr12,t0 -80000104: 00000293 li t0,0 -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: 16311463 bne sp,gp,80000298 -80000134: 00000193 li gp,0 -80000138: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> -8000013c: 14311e63 bne sp,gp,80000298 +80000020 : +80000020: 000f0067 jr t5 -80000140 : -80000140: 00100e13 li t3,1 -80000144: 00000f17 auipc t5,0x0 -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: 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 -80000170: 00000f17 auipc t5,0x0 -80000174: 010f0f13 addi t5,t5,16 # 80000180 -80000178: 0000a183 lw gp,0(ra) -8000017c: 11c0006f j 80000298 +80000024 : +80000024: 00000e13 li t3,0 +80000028: 00000f17 auipc t5,0x0 +8000002c: 340f0f13 addi t5,t5,832 # 80000368 +80000030: 800000b7 lui ra,0x80000 +80000034: 80008237 lui tp,0x80008 +80000038: deadc137 lui sp,0xdeadc +8000003c: eef10113 addi sp,sp,-273 # deadbeef +80000040: 0020a023 sw sp,0(ra) # 80000000 +80000044: 00222023 sw sp,0(tp) # 80008000 +80000048: 0000a183 lw gp,0(ra) +8000004c: 30311e63 bne sp,gp,80000368 +80000050: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000054: 30311a63 bne sp,gp,80000368 +80000058: 071a02b7 lui t0,0x71a0 +8000005c: 3a029073 csrw pmpcfg0,t0 +80000060: 3a002373 csrr t1,pmpcfg0 +80000064: 30629263 bne t0,t1,80000368 +80000068: 1a1902b7 lui t0,0x1a190 +8000006c: 30428293 addi t0,t0,772 # 1a190304 <_start-0x65e6fcfc> +80000070: 3a129073 csrw pmpcfg1,t0 +80000074: 000f12b7 lui t0,0xf1 +80000078: 90a28293 addi t0,t0,-1782 # f090a <_start-0x7ff0f6f6> +8000007c: 3a229073 csrw pmpcfg2,t0 +80000080: 3a202373 csrr t1,pmpcfg2 +80000084: 2e629263 bne t0,t1,80000368 +80000088: 1c1e22b7 lui t0,0x1c1e2 +8000008c: 90028293 addi t0,t0,-1792 # 1c1e1900 <_start-0x63e1e700> +80000090: 3a329073 csrw pmpcfg3,t0 +80000094: 200002b7 lui t0,0x20000 +80000098: 3b029073 csrw pmpaddr0,t0 +8000009c: 3b002373 csrr t1,pmpaddr0 +800000a0: 2c629463 bne t0,t1,80000368 +800000a4: fff00293 li t0,-1 +800000a8: 3b129073 csrw pmpaddr1,t0 +800000ac: 202002b7 lui t0,0x20200 +800000b0: 3b229073 csrw pmpaddr2,t0 +800000b4: 200042b7 lui t0,0x20004 +800000b8: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000bc: 3b329073 csrw pmpaddr3,t0 +800000c0: 200042b7 lui t0,0x20004 +800000c4: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000c8: 3b429073 csrw pmpaddr4,t0 +800000cc: 200042b7 lui t0,0x20004 +800000d0: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001> +800000d4: 3b529073 csrw pmpaddr5,t0 +800000d8: 230002b7 lui t0,0x23000 +800000dc: fff28293 addi t0,t0,-1 # 22ffffff <_start-0x5d000001> +800000e0: 3b629073 csrw pmpaddr6,t0 +800000e4: 220402b7 lui t0,0x22040 +800000e8: fff28293 addi t0,t0,-1 # 2203ffff <_start-0x5dfc0001> +800000ec: 3b729073 csrw pmpaddr7,t0 +800000f0: 200d02b7 lui t0,0x200d0 +800000f4: 3b829073 csrw pmpaddr8,t0 +800000f8: 200e02b7 lui t0,0x200e0 +800000fc: 3b929073 csrw pmpaddr9,t0 +80000100: fff00293 li t0,-1 +80000104: 3ba29073 csrw pmpaddr10,t0 +80000108: 00000293 li t0,0 +8000010c: 3bb29073 csrw pmpaddr11,t0 +80000110: 00000293 li t0,0 +80000114: 3bc29073 csrw pmpaddr12,t0 +80000118: 00000293 li t0,0 +8000011c: 3bd29073 csrw pmpaddr13,t0 +80000120: 00000293 li t0,0 +80000124: 3be29073 csrw pmpaddr14,t0 +80000128: fff00293 li t0,-1 +8000012c: 3bf29073 csrw pmpaddr15,t0 +80000130: 00c10137 lui sp,0xc10 +80000134: fee10113 addi sp,sp,-18 # c0ffee <_start-0x7f3f0012> +80000138: 0020a023 sw sp,0(ra) +8000013c: 00222023 sw sp,0(tp) # 0 <_start-0x80000000> +80000140: 0000a183 lw gp,0(ra) +80000144: 22311263 bne sp,gp,80000368 +80000148: 00000193 li gp,0 +8000014c: 00022183 lw gp,0(tp) # 0 <_start-0x80000000> +80000150: 20311c63 bne sp,gp,80000368 -80000180 : -80000180: 00200e13 li t3,2 +80000154 : +80000154: 00100e13 li t3,1 +80000158: 00000f17 auipc t5,0x0 +8000015c: 210f0f13 addi t5,t5,528 # 80000368 +80000160: 079a12b7 lui t0,0x79a1 +80000164: 80828293 addi t0,t0,-2040 # 79a0808 <_start-0x7865f7f8> +80000168: 3a029073 csrw pmpcfg0,t0 +8000016c: 3a002373 csrr t1,pmpcfg0 +80000170: 1e629c63 bne t0,t1,80000368 +80000174: 808000b7 lui ra,0x80800 +80000178: deadc137 lui sp,0xdeadc +8000017c: eef10113 addi sp,sp,-273 # deadbeef +80000180: 0020a023 sw sp,0(ra) # 80800000 80000184: 00000f17 auipc t5,0x0 -80000188: 114f0f13 addi t5,t5,276 # 80000298 -8000018c: 071202b7 lui t0,0x7120 -80000190: 3a029073 csrw pmpcfg0,t0 -80000194: 3a002373 csrr t1,pmpcfg0 -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 +80000188: 010f0f13 addi t5,t5,16 # 80000194 +8000018c: 0000a183 lw gp,0(ra) +80000190: 1d80006f j 80000368 -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 +80000194 : +80000194: 00200e13 li t3,2 +80000198: 00000f17 auipc t5,0x0 +8000019c: 1d0f0f13 addi t5,t5,464 # 80000368 +800001a0: 071a02b7 lui t0,0x71a0 +800001a4: 3a029073 csrw pmpcfg0,t0 +800001a8: 3a002373 csrr t1,pmpcfg0 +800001ac: 1a628e63 beq t0,t1,80000368 +800001b0: 3b305073 csrwi pmpaddr3,0 +800001b4: 3b302373 csrr t1,pmpaddr3 +800001b8: 1a031863 bnez t1,80000368 +800001bc: 3b205073 csrwi pmpaddr2,0 +800001c0: 3b202373 csrr t1,pmpaddr2 +800001c4: 1a030263 beqz t1,80000368 +800001c8: 808000b7 lui ra,0x80800 +800001cc: deadc137 lui sp,0xdeadc +800001d0: eef10113 addi sp,sp,-273 # deadbeef +800001d4: 0020a023 sw sp,0(ra) # 80800000 +800001d8: 00000f17 auipc t5,0x0 +800001dc: 010f0f13 addi t5,t5,16 # 800001e8 +800001e0: 0000a183 lw gp,0(ra) +800001e4: 1840006f j 80000368 -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 +800001e8 : +800001e8: 00300e13 li t3,3 +800001ec: 00000f17 auipc t5,0x0 +800001f0: 17cf0f13 addi t5,t5,380 # 80000368 +800001f4: 00ff02b7 lui t0,0xff0 +800001f8: 3b32a073 csrs pmpaddr3,t0 +800001fc: 3b302373 csrr t1,pmpaddr3 +80000200: 16629463 bne t0,t1,80000368 +80000204: 0ff00293 li t0,255 +80000208: 3b32a073 csrs pmpaddr3,t0 +8000020c: 3b302373 csrr t1,pmpaddr3 +80000210: 00ff02b7 lui t0,0xff0 +80000214: 0ff28293 addi t0,t0,255 # ff00ff <_start-0x7f00ff01> +80000218: 14629863 bne t0,t1,80000368 +8000021c: 00ff02b7 lui t0,0xff0 +80000220: 3b32b073 csrc pmpaddr3,t0 +80000224: 3b302373 csrr t1,pmpaddr3 +80000228: 0ff00293 li t0,255 +8000022c: 12629e63 bne t0,t1,80000368 +80000230: 00ff02b7 lui t0,0xff0 +80000234: 0ff28293 addi t0,t0,255 # ff00ff <_start-0x7f00ff01> +80000238: 3a02b073 csrc pmpcfg0,t0 +8000023c: 3a002373 csrr t1,pmpcfg0 +80000240: 079a02b7 lui t0,0x79a0 +80000244: 12629263 bne t0,t1,80000368 +80000248: 00ff02b7 lui t0,0xff0 +8000024c: 70728293 addi t0,t0,1799 # ff0707 <_start-0x7f00f8f9> +80000250: 3a02a073 csrs pmpcfg0,t0 +80000254: 3a002373 csrr t1,pmpcfg0 +80000258: 079a02b7 lui t0,0x79a0 +8000025c: 70728293 addi t0,t0,1799 # 79a0707 <_start-0x7865f8f9> +80000260: 10629463 bne t0,t1,80000368 -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 - -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 - -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> +80000264 : +80000264: 00400e13 li t3,4 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: 100f0f13 addi t5,t5,256 # 80000368 +80000270: 00000117 auipc sp,0x0 +80000274: 01010113 addi sp,sp,16 # 80000280 +80000278: 34111073 csrw mepc,sp +8000027c: 30200073 mret -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 +80000280 : +80000280: 00500e13 li t3,5 +80000284: 00000f17 auipc t5,0x0 +80000288: 0e4f0f13 addi t5,t5,228 # 80000368 +8000028c: deadc137 lui sp,0xdeadc +80000290: eef10113 addi sp,sp,-273 # deadbeef +80000294: 808000b7 lui ra,0x80800 +80000298: 0020a023 sw sp,0(ra) # 80800000 +8000029c: 00000f17 auipc t5,0x0 +800002a0: 010f0f13 addi t5,t5,16 # 800002ac +800002a4: 0000a183 lw gp,0(ra) +800002a8: 0c00006f j 80000368 -80000298 : -80000298: f0100137 lui sp,0xf0100 -8000029c: f2410113 addi sp,sp,-220 # f00fff24 -800002a0: 01c12023 sw t3,0(sp) +800002ac : +800002ac: 00600e13 li t3,6 +800002b0: 00000f17 auipc t5,0x0 +800002b4: 0b8f0f13 addi t5,t5,184 # 80000368 +800002b8: deadc137 lui sp,0xdeadc +800002bc: eef10113 addi sp,sp,-273 # deadbeef +800002c0: 880000b7 lui ra,0x88000 +800002c4: 0020a023 sw sp,0(ra) # 88000000 +800002c8: 0000a183 lw gp,0(ra) -800002a4 : -800002a4: f0100137 lui sp,0xf0100 -800002a8: f2010113 addi sp,sp,-224 # f00fff20 -800002ac: 00012023 sw zero,0(sp) +800002cc : +800002cc: 00700e13 li t3,7 +800002d0: 00000f17 auipc t5,0x0 +800002d4: 098f0f13 addi t5,t5,152 # 80000368 +800002d8: 890000b7 lui ra,0x89000 +800002dc: ff008093 addi ra,ra,-16 # 88fffff0 +800002e0: 0000a183 lw gp,0(ra) +800002e4: 00000f17 auipc t5,0x0 +800002e8: 010f0f13 addi t5,t5,16 # 800002f4 +800002ec: 0030a023 sw gp,0(ra) +800002f0: 0780006f j 80000368 + +800002f4 : +800002f4: 00800e13 li t3,8 +800002f8: 00000f17 auipc t5,0x0 +800002fc: 014f0f13 addi t5,t5,20 # 8000030c +80000300: 00100493 li s1,1 +80000304: 3a305073 csrwi pmpcfg3,0 +80000308: 0600006f j 80000368 + +8000030c : +8000030c: 00800e13 li t3,8 +80000310: 1c1e22b7 lui t0,0x1c1e2 +80000314: 90028293 addi t0,t0,-1792 # 1c1e1900 <_start-0x63e1e700> +80000318: 3a302373 csrr t1,pmpcfg3 +8000031c: 04629663 bne t0,t1,80000368 + +80000320 : +80000320: 00900e13 li t3,9 +80000324: 00000f17 auipc t5,0x0 +80000328: 044f0f13 addi t5,t5,68 # 80000368 +8000032c: 00000493 li s1,0 +80000330: 00000117 auipc sp,0x0 +80000334: 01010113 addi sp,sp,16 # 80000340 +80000338: 34111073 csrw mepc,sp +8000033c: 30200073 mret + +80000340 : +80000340: 00900e13 li t3,9 +80000344: 00000f17 auipc t5,0x0 +80000348: 014f0f13 addi t5,t5,20 # 80000358 +8000034c: 00100493 li s1,1 +80000350: 3ba05073 csrwi pmpaddr10,0 +80000354: 0140006f j 80000368 + +80000358 : +80000358: 00900e13 li t3,9 +8000035c: fff00293 li t0,-1 +80000360: 3ba02373 csrr t1,pmpaddr10 +80000364: 00628863 beq t0,t1,80000374 + +80000368 : +80000368: f0100137 lui sp,0xf0100 +8000036c: f2410113 addi sp,sp,-220 # f00fff24 +80000370: 01c12023 sw t3,0(sp) + +80000374 : +80000374: f0100137 lui sp,0xf0100 +80000378: f2010113 addi sp,sp,-224 # f00fff20 +8000037c: 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 b844a20..c28d2cd 100755 Binary files a/src/test/cpp/raw/pmp/build/pmp.elf and b/src/test/cpp/raw/pmp/build/pmp.elf differ diff --git a/src/test/cpp/raw/pmp/build/pmp.hex b/src/test/cpp/raw/pmp/build/pmp.hex index 8197935..805692b 100644 --- a/src/test/cpp/raw/pmp/build/pmp.hex +++ b/src/test/cpp/raw/pmp/build/pmp.hex @@ -1,46 +1,59 @@ :0200000480007A -:100000009700000093800001739050306F00C00093 -:1000100073101F3473002030130E0000170F000000 -:10002000130FCF27B70000803782008037C1ADDEC5 -:100030001301F1EE23A020002320220083A1000061 -:10004000631C31248321020063183124B702120794 -:100050007390023A7323003A63906224B7021F1927 -:10006000938242307390123AB7020F00938262502B -:100070007390223AB7221E0F938202907390323A05 -:10008000B70200207390023B7323003B639662200B -:100090009302F0FF7390123BB72200207390223B33 -:1000A000B74200209382F2FF7390323BB7420020A8 -:1000B0009382F2FF7390423BB74200209382F2FF9B -:1000C0007390523BB72200209382F2FF7390623B01 -:1000D000B76200209382F2FF7390723BB7C2002098 -:1000E0007390823BB7D200207390923B9302F0FF53 -:1000F0007390A23B930200007390B23B9302000006 -:100100007390C23B930200007390D23B93020000B5 -:100110007390E23B930200007390F23B3701C10001 -:100120001301E1FE23A020002320220083A1000070 -:10013000631431169301000083210200631E311401 -:10014000130E1000170F0000130F4F15B712920770 -:10015000938282807390023A7323003A639E621204 -:10016000B780008037C1ADDE1301F1EE23A020007F -:10017000170F0000130F0F0183A100006F00C011C3 -:10018000130E2000170F0000130F4F11B7021207B4 -:100190007390023A7323003A7350203B7323203B41 -:1001A000630C030E638A620EB780008037C1ADDE38 -:1001B0001301F1EE23A02000170F0000130F0F0111 -:1001C00083A100006F00400D130E3000170F0000D8 -:1001D000130FCF0C1701000013010101731011342C -:1001E00073002030130E4000170F0000130F0F0B89 -:1001F00037C1ADDE1301F1EEB780008023A02000EF -:10020000170F0000130F0F0183A100006F00C0083B -:10021000130E500037C1ADDE1301F1EEB7000080C0 -:1002200023A0200083A1000063183106130E600094 -:10023000B700018083A10000170F0000130FCF0645 -:1002400023A030006F004005130E7000170F000050 -:10025000130FCF0437C1ADDE1301F1EEB7000380F9 -:10026000938080FF23202200170F0000130F8FFAC6 -:10027000832102006F004002130E8000B70004804B -:10028000938080FF83A10000170F0000130FCF01A0 -:1002900023A030006F004000370110F0130141F23D -:1002A0002320C101370110F0130101F223200100C6 +:10000000930400009700000093800001739050302B +:100010006F00400173101F3463940400730020309C +:1000200067000F00130E0000170F0000130F0F34AE +:10003000B70000803782008037C1ADDE1301F1EEDA +:1000400023A020002320220083A10000631E313062 +:1000500083210200631A3130B7021A077390023A03 +:100060007323003A63926230B702191A93824230C6 +:100070007390123AB7120F009382A2907390223AB3 +:100080007323203A6392622EB7221E1C9382029041 +:100090007390323AB70200207390023B7323003B07 +:1000A0006394622C9302F0FF7390123BB7022020FE +:1000B0007390223BB74200209382F2FF7390323B51 +:1000C000B74200209382F2FF7390423BB742002078 +:1000D0009382F2FF7390523BB70200239382F2FFA8 +:1000E0007390623BB70204229382F2FF7390723BDB +:1000F000B7020D207390823BB7020E207390923BA3 +:100100009302F0FF7390A23B930200007390B23B06 +:10011000930200007390C23B930200007390D23BA5 +:10012000930200007390E23B9302F0FF7390F23B66 +:100130003701C1001301E1FE23A02000232022008B +:1001400083A1000063123122930100008321020089 +:10015000631C3120130E1000170F0000130F0F2126 +:10016000B7129A07938282807390023A7323003AFF +:10017000639C621EB700808037C1ADDE1301F1EED3 +:1001800023A02000170F0000130F0F0183A1000010 +:100190006F00801D130E2000170F0000130F0F1D9E +:1001A000B7021A077390023A7323003A638E621AF9 +:1001B0007350303B7323303B6318031A7350203B5A +:1001C0007323203B6302031AB700808037C1ADDE82 +:1001D0001301F1EE23A02000170F0000130F0F01F1 +:1001E00083A100006F004018130E3000170F0000AD +:1001F000130FCF17B702FF0073A0323B7323303BBE +:10020000639462169302F00F73A0323B7323303B6A +:10021000B702FF009382F20F63986214B702FF00E7 +:1002200073B0323B7323303B9302F00F639E621234 +:10023000B702FF009382F20F73B0023A7323003AC1 +:10024000B7029A0763926212B702FF00938272703C +:1002500073A0023A7323003AB7029A07938272702E +:1002600063946210130E4000170F0000130F0F105D +:1002700017010000130101017310113473002030C5 +:10028000130E5000170F0000130F4F0E37C1ADDED5 +:100290001301F1EEB700808023A02000170F0000AB +:1002A000130F0F0183A100006F00000C130E6000FC +:1002B000170F0000130F8F0B37C1ADDE1301F1EEE6 +:1002C000B700008823A0200083A10000130E700057 +:1002D000170F0000130F8F09B7000089938000FFEC +:1002E00083A10000170F0000130F0F0123A030009F +:1002F0006F008007130E8000170F0000130F4F01CF +:10030000930410007350303A6F000006130E800003 +:10031000B7221E1C938202907323303A63966204C4 +:10032000130E9000170F0000130F4F0493040000EA +:100330001701000013010101731011347300203004 +:10034000130E9000170F0000130F4F0193041000BD +:100350007350A03B6F004001130E90009302F0FF1A +:100360007323A03B63886200370110F0130141F250 +:100370002320C101370110F0130101F223200100F5 :040000058000000077 :00000001FF diff --git a/src/test/cpp/raw/pmp/build/pmp.map b/src/test/cpp/raw/pmp/build/pmp.map index 2a01820..0a074b1 100644 --- a/src/test/cpp/raw/pmp/build/pmp.map +++ b/src/test/cpp/raw/pmp/build/pmp.map @@ -8,28 +8,28 @@ onChipRam 0x0000000080000000 0x0000000000020000 w !xr Linker script and memory map LOAD build/src/crt.o -LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/libgcc.a +LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/8.3.0/rv32i/ilp32/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 +LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/8.3.0/../../../../riscv64-unknown-elf/lib/rv32i/ilp32/libc.a +LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/8.3.0/../../../../riscv64-unknown-elf/lib/rv32i/ilp32/libgloss.a END GROUP -LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/libgcc.a +LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/8.3.0/rv32i/ilp32/libgcc.a -.crt_section 0x0000000080000000 0x2b0 +.crt_section 0x0000000080000000 0x380 0x0000000080000000 . = ALIGN (0x4) *crt.o(.text) - .text 0x0000000080000000 0x2b0 build/src/crt.o + .text 0x0000000080000000 0x380 build/src/crt.o 0x0000000080000000 _start - 0x0000000080000010 trap + 0x0000000080000014 trap OUTPUT(build/pmp.elf elf32-littleriscv) -.data 0x00000000800002b0 0x0 - .data 0x00000000800002b0 0x0 build/src/crt.o +.data 0x0000000080000380 0x0 + .data 0x0000000080000380 0x0 build/src/crt.o -.bss 0x00000000800002b0 0x0 - .bss 0x00000000800002b0 0x0 build/src/crt.o +.bss 0x0000000080000380 0x0 + .bss 0x0000000080000380 0x0 build/src/crt.o .riscv.attributes - 0x0000000000000000 0x1e + 0x0000000000000000 0x1a .riscv.attributes - 0x0000000000000000 0x1e build/src/crt.o + 0x0000000000000000 0x1a build/src/crt.o diff --git a/src/test/cpp/raw/pmp/src/crt.S b/src/test/cpp/raw/pmp/src/crt.S index 76ee02f..5c74beb 100644 --- a/src/test/cpp/raw/pmp/src/crt.S +++ b/src/test/cpp/raw/pmp/src/crt.S @@ -4,47 +4,54 @@ * SPDX-License-Identifier: MIT */ -#define TEST_ID x28 -#define TRAP_RA x30 +#define TEST_ID x28 +#define TRAP_RETURN x30 +#define TRAP_EXIT x9 -#define PMPCFG0 0x07120000 -#define PMPCFG0_ 0x07920808 // locked -#define PMPCFG1 0x191f0304 -#define PMPCFG2 0x000f0506 -#define PMPCFG3 0x0f1e1900 +#define PMPCFG0 0x071a0000 +#define PMPCFG0_ 0x079a0808 +#define PMPCFG1 0x1a190304 +#define PMPCFG2 0x000f090a +#define PMPCFG3 0x1c1e1900 -#define PMPADDR0 0x20000000 // OFF -#define PMPADDR1 0xffffffff // OFF -#define PMPADDR2 0x20002000 // NA4 W -#define PMPADDR3 0x20003fff // OFF RWX +#define PMPADDR0 0x20000000 // OFF (test0) -> TOR (test1) -> OFF (test2) +#define PMPADDR1 0xffffffff // OFF (test0) -> TOR (test1) -> OFF (test2) +#define PMPADDR2 0x20200000 // NAPOT W +#define PMPADDR3 0x20003fff // OFF RWX -> 0x00000000 OFF RWX (test2) #define PMPADDR4 0x20003fff // OFF X #define PMPADDR5 0x20003fff // OFF RW -#define PMPADDR6 0x20001fff // NAPOT RWX -#define PMPADDR7 0x20005fff // NAPOT R -#define PMPADDR8 0x2000c000 // TOR W -#define PMPADDR9 0x2000d000 // TOR R +#define PMPADDR6 0x22ffffff // NAPOT R +#define PMPADDR7 0x2203ffff // NAPOT W +#define PMPADDR8 0x200d0000 // TOR W +#define PMPADDR9 0x200e0000 // TOR R #define PMPADDR10 0xffffffff // TOR RWX #define PMPADDR11 0x00000000 // OFF #define PMPADDR12 0x00000000 // OFF #define PMPADDR13 0x00000000 // NAPOT R #define PMPADDR14 0x00000000 // NAPOT WX -#define PMPADDR15 0x00000000 // TOR RWX +#define PMPADDR15 0xffffffff // NAPOT X .global _start _start: + li TRAP_EXIT, 0x0 la x1, trap csrw mtvec, x1 j test0 .global trap trap: - csrw mepc, TRAP_RA + csrw mepc, TRAP_RETURN + bnez TRAP_EXIT, trap_exit mret +// return from trap, but stay in M-mode +trap_exit: + jr TRAP_RETURN + // configure PMP, attempt read/write from machine mode test0: li TEST_ID, 0 - la TRAP_RA, fail + la TRAP_RETURN, fail li x1, 0x80000000 li x4, 0x80008000 @@ -64,6 +71,8 @@ test0: csrw pmpcfg1, x5 li x5, PMPCFG2 csrw pmpcfg2, x5 + csrr x6, pmpcfg2 + bne x5, x6, fail li x5, PMPCFG3 csrw pmpcfg3, x5 li x5, PMPADDR0 @@ -113,94 +122,148 @@ test0: // lock region 2, attempt read/write from machine mode test1: li TEST_ID, 1 - la TRAP_RA, fail + la TRAP_RETURN, fail li x5, PMPCFG0_ csrw pmpcfg0, x5 // lock region 2 csrr x6, pmpcfg0 bne x5, x6, fail - li x1, 0x80008000 + li x1, 0x80800000 li x2, 0xdeadbeef - sw x2, 0x0(x1) // should be OK (write 0x80008000) - la TRAP_RA, test2 - lw x3, 0x0(x1) // should fault (read 0x80008000) + sw x2, 0x0(x1) // should be OK (write region 2) + la TRAP_RETURN, test2 + lw x3, 0x0(x1) // should fault (read region 2) j fail // "unlock" region 2, attempt read/write from machine mode test2: li TEST_ID, 2 - la TRAP_RA, fail + la TRAP_RETURN, fail li x5, PMPCFG0 csrw pmpcfg0, x5 // "unlock" region 2 csrr x6, pmpcfg0 + beq x5, x6, fail + csrwi pmpaddr3, 0x0 + csrr x6, pmpaddr3 + bnez x6, fail csrwi pmpaddr2, 0x0 csrr x6, pmpaddr2 beqz x6, fail - beq x5, x6, fail - li x1, 0x80008000 + li x1, 0x80800000 li x2, 0xdeadbeef - sw x2, 0x0(x1) // should still be OK (write 0x80008000) - la TRAP_RA, test3 - lw x3, 0x0(x1) // should still fault (read 0x80008000) + sw x2, 0x0(x1) // should still be OK (write region 2) + la TRAP_RETURN, test3 + lw x3, 0x0(x1) // should still fault (read region 2) j fail -// jump into user mode +// verify masked CSR read/write operations test3: li TEST_ID, 3 - la TRAP_RA, fail - la x2, test4 + la TRAP_RETURN, fail + li x5, 0x00ff0000 + csrs pmpaddr3, x5 + csrr x6, pmpaddr3 + bne x5, x6, fail + li x5, 0x000000ff + csrs pmpaddr3, x5 + csrr x6, pmpaddr3 + li x5, 0x00ff00ff + bne x5, x6, fail + li x5, 0x00ff0000 + csrc pmpaddr3, x5 + csrr x6, pmpaddr3 + li x5, 0x000000ff + bne x5, x6, fail + li x5, 0x00ff00ff + csrc pmpcfg0, x5 + csrr x6, pmpcfg0 + li x5, 0x079a0000 + bne x5, x6, fail + li x5, 0x00ff0707 + csrs pmpcfg0, x5 + csrr x6, pmpcfg0 + li x5, 0x079a0707 + bne x5, x6, fail + +// jump into U-mode +test4: + li TEST_ID, 4 + la TRAP_RETURN, fail + la x2, test5 csrw mepc, x2 mret -// attempt to read/write region 2 from user mode -test4: - li TEST_ID, 4 - la TRAP_RA, fail - li x2, 0xdeadbeef - li x1, 0x80008000 - sw x2, 0x0(x1) // should be OK (write 0x80008000) - la TRAP_RA, test5 - lw x3, 0x0(x1) // should fault (read 0x80008000) - j fail - -// attempt to read/write other regions from user mode +// attempt to read/write the locked region from U-mode test5: li TEST_ID, 5 + la TRAP_RETURN, fail li x2, 0xdeadbeef - li x1, 0x80000000 - sw x2, 0x0(x1) - lw x3, 0x0(x1) - bne x2, x3, fail // should be OK (read/write 0x80000000) + li x1, 0x80800000 + sw x2, 0x0(x1) // should be OK (write region 2) + la TRAP_RETURN, test6 + lw x3, 0x0(x1) // should fault (read region 2) + j fail +// attempt to read/write overlapping regions from U-mode test6: li TEST_ID, 6 - li x1, 0x80010000 - lw x3, 0x0(x1) // should be OK (read 0x80010000) - la TRAP_RA, pass - sw x3, 0x0(x1) // should fault (write 0x80010000) - j fail - + la TRAP_RETURN, fail + li x2, 0xdeadbeef + li x1, 0x88000000 + sw x2, 0x0(x1) // should be OK (write region 6/7) + lw x3, 0x0(x1) // should be OK (write region 6/7) + 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) + la TRAP_RETURN, fail + li x1, 0x88fffff0 + lw x3, 0x0(x1) // should be OK (read region 6) + la TRAP_RETURN, test8a + sw x3, 0x0(x1) // should fault (write region 6) j fail -test8: +// attempt to write a pmpcfg# register from U-mode +test8a: 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) + la TRAP_RETURN, test8b + li TRAP_EXIT, 0x1 + csrwi pmpcfg3, 0x0 j fail - + +// check the result from M-mode +test8b: + li TEST_ID, 8 + li x5, PMPCFG3 + csrr x6, pmpcfg3 + bne x5, x6, fail + +// jump back into U-mode +test9a: + li TEST_ID, 9 + la TRAP_RETURN, fail + li TRAP_EXIT, 0x0 + la x2, test9b + csrw mepc, x2 + mret + +// attempt to write a pmpaddr# register from U-mode +test9b: + li TEST_ID, 9 + la TRAP_RETURN, test9c + li TRAP_EXIT, 0x1 + csrwi pmpaddr10, 0x0 + j fail + +// check the result from M-mode +test9c: + li TEST_ID, 9 + li x5, PMPADDR10 + csrr x6, pmpaddr10 + beq x5, x6, pass + fail: li x2, 0xf00fff24 sw TEST_ID, 0(x2) pass: li x2, 0xf00fff20 - sw x0, 0(x2) + sw x0, 0(x2) \ No newline at end of file diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 8141448..71c6697 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -520,6 +520,7 @@ class MmuPmpDimension extends VexRiscvDimension("DBus") { override def applyOn(config: VexRiscvConfig): Unit = { config.plugins += new PmpPlugin( regions = 16, + granularity = 32, ioRange = _ (31 downto 28) === 0xF ) }