Merge pull request #174 from lindemer/new_pmp

New PMP plugin optimized for FPGAs
This commit is contained in:
Dolu1990 2021-06-03 20:16:34 +02:00 committed by GitHub
commit 87f100dac1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 698 additions and 460 deletions

View File

@ -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.

View File

@ -41,6 +41,7 @@ object GenSecure extends App {
),
new PmpPlugin(
regions = 16,
granularity = 32,
ioRange = _(31 downto 28) === 0xf
),
new DecoderSimplePlugin(

View File

@ -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)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Samuel Lindemer <samuel.lindemer@ri.se>
* Copyright (c) 2021 Samuel Lindemer <samuel.lindemer@ri.se>
*
* 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)
}
}
}
}
}
}

View File

@ -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 <trap>
80000008: 30509073 csrw mtvec,ra
8000000c: 00c0006f j 80000018 <test0>
80000000: 00000493 li s1,0
80000004: 00000097 auipc ra,0x0
80000008: 01008093 addi ra,ra,16 # 80000014 <trap>
8000000c: 30509073 csrw mtvec,ra
80000010: 0140006f j 80000024 <test0>
80000010 <trap>:
80000010: 341f1073 csrw mepc,t5
80000014: 30200073 mret
80000014 <trap>:
80000014: 341f1073 csrw mepc,t5
80000018: 00049463 bnez s1,80000020 <trap_exit>
8000001c: 30200073 mret
80000018 <test0>:
80000018: 00000e13 li t3,0
8000001c: 00000f17 auipc t5,0x0
80000020: 27cf0f13 addi t5,t5,636 # 80000298 <fail>
80000024: 800000b7 lui ra,0x80000
80000028: 80008237 lui tp,0x80008
8000002c: deadc137 lui sp,0xdeadc
80000030: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc4b>
80000034: 0020a023 sw sp,0(ra) # 80000000 <pass+0xfffffd5c>
80000038: 00222023 sw sp,0(tp) # 80008000 <pass+0x7d5c>
8000003c: 0000a183 lw gp,0(ra)
80000040: 24311c63 bne sp,gp,80000298 <fail>
80000044: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
80000048: 24311863 bne sp,gp,80000298 <fail>
8000004c: 071202b7 lui t0,0x7120
80000050: 3a029073 csrw pmpcfg0,t0
80000054: 3a002373 csrr t1,pmpcfg0
80000058: 24629063 bne t0,t1,80000298 <fail>
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 <fail>
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 <fail>
80000134: 00000193 li gp,0
80000138: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
8000013c: 14311e63 bne sp,gp,80000298 <fail>
80000020 <trap_exit>:
80000020: 000f0067 jr t5
80000140 <test1>:
80000140: 00100e13 li t3,1
80000144: 00000f17 auipc t5,0x0
80000148: 154f0f13 addi t5,t5,340 # 80000298 <fail>
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 <fail>
80000160: 800080b7 lui ra,0x80008
80000164: deadc137 lui sp,0xdeadc
80000168: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc4b>
8000016c: 0020a023 sw sp,0(ra) # 80008000 <pass+0x7d5c>
80000170: 00000f17 auipc t5,0x0
80000174: 010f0f13 addi t5,t5,16 # 80000180 <test2>
80000178: 0000a183 lw gp,0(ra)
8000017c: 11c0006f j 80000298 <fail>
80000024 <test0>:
80000024: 00000e13 li t3,0
80000028: 00000f17 auipc t5,0x0
8000002c: 340f0f13 addi t5,t5,832 # 80000368 <fail>
80000030: 800000b7 lui ra,0x80000
80000034: 80008237 lui tp,0x80008
80000038: deadc137 lui sp,0xdeadc
8000003c: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb7b>
80000040: 0020a023 sw sp,0(ra) # 80000000 <pass+0xfffffc8c>
80000044: 00222023 sw sp,0(tp) # 80008000 <pass+0x7c8c>
80000048: 0000a183 lw gp,0(ra)
8000004c: 30311e63 bne sp,gp,80000368 <fail>
80000050: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
80000054: 30311a63 bne sp,gp,80000368 <fail>
80000058: 071a02b7 lui t0,0x71a0
8000005c: 3a029073 csrw pmpcfg0,t0
80000060: 3a002373 csrr t1,pmpcfg0
80000064: 30629263 bne t0,t1,80000368 <fail>
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 <fail>
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 <fail>
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 <fail>
80000148: 00000193 li gp,0
8000014c: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
80000150: 20311c63 bne sp,gp,80000368 <fail>
80000180 <test2>:
80000180: 00200e13 li t3,2
80000154 <test1>:
80000154: 00100e13 li t3,1
80000158: 00000f17 auipc t5,0x0
8000015c: 210f0f13 addi t5,t5,528 # 80000368 <fail>
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 <fail>
80000174: 808000b7 lui ra,0x80800
80000178: deadc137 lui sp,0xdeadc
8000017c: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb7b>
80000180: 0020a023 sw sp,0(ra) # 80800000 <pass+0x7ffc8c>
80000184: 00000f17 auipc t5,0x0
80000188: 114f0f13 addi t5,t5,276 # 80000298 <fail>
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 <fail>
800001a4: 0e628a63 beq t0,t1,80000298 <fail>
800001a8: 800080b7 lui ra,0x80008
800001ac: deadc137 lui sp,0xdeadc
800001b0: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc4b>
800001b4: 0020a023 sw sp,0(ra) # 80008000 <pass+0x7d5c>
800001b8: 00000f17 auipc t5,0x0
800001bc: 010f0f13 addi t5,t5,16 # 800001c8 <test3>
800001c0: 0000a183 lw gp,0(ra)
800001c4: 0d40006f j 80000298 <fail>
80000188: 010f0f13 addi t5,t5,16 # 80000194 <test2>
8000018c: 0000a183 lw gp,0(ra)
80000190: 1d80006f j 80000368 <fail>
800001c8 <test3>:
800001c8: 00300e13 li t3,3
800001cc: 00000f17 auipc t5,0x0
800001d0: 0ccf0f13 addi t5,t5,204 # 80000298 <fail>
800001d4: 00000117 auipc sp,0x0
800001d8: 01010113 addi sp,sp,16 # 800001e4 <test4>
800001dc: 34111073 csrw mepc,sp
800001e0: 30200073 mret
80000194 <test2>:
80000194: 00200e13 li t3,2
80000198: 00000f17 auipc t5,0x0
8000019c: 1d0f0f13 addi t5,t5,464 # 80000368 <fail>
800001a0: 071a02b7 lui t0,0x71a0
800001a4: 3a029073 csrw pmpcfg0,t0
800001a8: 3a002373 csrr t1,pmpcfg0
800001ac: 1a628e63 beq t0,t1,80000368 <fail>
800001b0: 3b305073 csrwi pmpaddr3,0
800001b4: 3b302373 csrr t1,pmpaddr3
800001b8: 1a031863 bnez t1,80000368 <fail>
800001bc: 3b205073 csrwi pmpaddr2,0
800001c0: 3b202373 csrr t1,pmpaddr2
800001c4: 1a030263 beqz t1,80000368 <fail>
800001c8: 808000b7 lui ra,0x80800
800001cc: deadc137 lui sp,0xdeadc
800001d0: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb7b>
800001d4: 0020a023 sw sp,0(ra) # 80800000 <pass+0x7ffc8c>
800001d8: 00000f17 auipc t5,0x0
800001dc: 010f0f13 addi t5,t5,16 # 800001e8 <test3>
800001e0: 0000a183 lw gp,0(ra)
800001e4: 1840006f j 80000368 <fail>
800001e4 <test4>:
800001e4: 00400e13 li t3,4
800001e8: 00000f17 auipc t5,0x0
800001ec: 0b0f0f13 addi t5,t5,176 # 80000298 <fail>
800001f0: deadc137 lui sp,0xdeadc
800001f4: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc4b>
800001f8: 800080b7 lui ra,0x80008
800001fc: 0020a023 sw sp,0(ra) # 80008000 <pass+0x7d5c>
80000200: 00000f17 auipc t5,0x0
80000204: 010f0f13 addi t5,t5,16 # 80000210 <test5>
80000208: 0000a183 lw gp,0(ra)
8000020c: 08c0006f j 80000298 <fail>
800001e8 <test3>:
800001e8: 00300e13 li t3,3
800001ec: 00000f17 auipc t5,0x0
800001f0: 17cf0f13 addi t5,t5,380 # 80000368 <fail>
800001f4: 00ff02b7 lui t0,0xff0
800001f8: 3b32a073 csrs pmpaddr3,t0
800001fc: 3b302373 csrr t1,pmpaddr3
80000200: 16629463 bne t0,t1,80000368 <fail>
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 <fail>
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 <fail>
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 <fail>
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 <fail>
80000210 <test5>:
80000210: 00500e13 li t3,5
80000214: deadc137 lui sp,0xdeadc
80000218: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc4b>
8000021c: 800000b7 lui ra,0x80000
80000220: 0020a023 sw sp,0(ra) # 80000000 <pass+0xfffffd5c>
80000224: 0000a183 lw gp,0(ra)
80000228: 06311863 bne sp,gp,80000298 <fail>
8000022c <test6>:
8000022c: 00600e13 li t3,6
80000230: 800100b7 lui ra,0x80010
80000234: 0000a183 lw gp,0(ra) # 80010000 <pass+0xfd5c>
80000238: 00000f17 auipc t5,0x0
8000023c: 06cf0f13 addi t5,t5,108 # 800002a4 <pass>
80000240: 0030a023 sw gp,0(ra)
80000244: 0540006f j 80000298 <fail>
80000248 <test7>:
80000248: 00700e13 li t3,7
8000024c: 00000f17 auipc t5,0x0
80000250: 04cf0f13 addi t5,t5,76 # 80000298 <fail>
80000254: deadc137 lui sp,0xdeadc
80000258: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc4b>
8000025c: 800300b7 lui ra,0x80030
80000260: ff808093 addi ra,ra,-8 # 8002fff8 <pass+0x2fd54>
80000264: 00222023 sw sp,0(tp) # 0 <_start-0x80000000>
80000264 <test4>:
80000264: 00400e13 li t3,4
80000268: 00000f17 auipc t5,0x0
8000026c: fa8f0f13 addi t5,t5,-88 # 80000210 <test5>
80000270: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
80000274: 0240006f j 80000298 <fail>
8000026c: 100f0f13 addi t5,t5,256 # 80000368 <fail>
80000270: 00000117 auipc sp,0x0
80000274: 01010113 addi sp,sp,16 # 80000280 <test5>
80000278: 34111073 csrw mepc,sp
8000027c: 30200073 mret
80000278 <test8>:
80000278: 00800e13 li t3,8
8000027c: 800400b7 lui ra,0x80040
80000280: ff808093 addi ra,ra,-8 # 8003fff8 <pass+0x3fd54>
80000284: 0000a183 lw gp,0(ra)
80000288: 00000f17 auipc t5,0x0
8000028c: 01cf0f13 addi t5,t5,28 # 800002a4 <pass>
80000290: 0030a023 sw gp,0(ra)
80000294: 0040006f j 80000298 <fail>
80000280 <test5>:
80000280: 00500e13 li t3,5
80000284: 00000f17 auipc t5,0x0
80000288: 0e4f0f13 addi t5,t5,228 # 80000368 <fail>
8000028c: deadc137 lui sp,0xdeadc
80000290: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb7b>
80000294: 808000b7 lui ra,0x80800
80000298: 0020a023 sw sp,0(ra) # 80800000 <pass+0x7ffc8c>
8000029c: 00000f17 auipc t5,0x0
800002a0: 010f0f13 addi t5,t5,16 # 800002ac <test6>
800002a4: 0000a183 lw gp,0(ra)
800002a8: 0c00006f j 80000368 <fail>
80000298 <fail>:
80000298: f0100137 lui sp,0xf0100
8000029c: f2410113 addi sp,sp,-220 # f00fff24 <pass+0x700ffc80>
800002a0: 01c12023 sw t3,0(sp)
800002ac <test6>:
800002ac: 00600e13 li t3,6
800002b0: 00000f17 auipc t5,0x0
800002b4: 0b8f0f13 addi t5,t5,184 # 80000368 <fail>
800002b8: deadc137 lui sp,0xdeadc
800002bc: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb7b>
800002c0: 880000b7 lui ra,0x88000
800002c4: 0020a023 sw sp,0(ra) # 88000000 <pass+0x7fffc8c>
800002c8: 0000a183 lw gp,0(ra)
800002a4 <pass>:
800002a4: f0100137 lui sp,0xf0100
800002a8: f2010113 addi sp,sp,-224 # f00fff20 <pass+0x700ffc7c>
800002ac: 00012023 sw zero,0(sp)
800002cc <test7>:
800002cc: 00700e13 li t3,7
800002d0: 00000f17 auipc t5,0x0
800002d4: 098f0f13 addi t5,t5,152 # 80000368 <fail>
800002d8: 890000b7 lui ra,0x89000
800002dc: ff008093 addi ra,ra,-16 # 88fffff0 <pass+0x8fffc7c>
800002e0: 0000a183 lw gp,0(ra)
800002e4: 00000f17 auipc t5,0x0
800002e8: 010f0f13 addi t5,t5,16 # 800002f4 <test8a>
800002ec: 0030a023 sw gp,0(ra)
800002f0: 0780006f j 80000368 <fail>
800002f4 <test8a>:
800002f4: 00800e13 li t3,8
800002f8: 00000f17 auipc t5,0x0
800002fc: 014f0f13 addi t5,t5,20 # 8000030c <test8b>
80000300: 00100493 li s1,1
80000304: 3a305073 csrwi pmpcfg3,0
80000308: 0600006f j 80000368 <fail>
8000030c <test8b>:
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 <fail>
80000320 <test9a>:
80000320: 00900e13 li t3,9
80000324: 00000f17 auipc t5,0x0
80000328: 044f0f13 addi t5,t5,68 # 80000368 <fail>
8000032c: 00000493 li s1,0
80000330: 00000117 auipc sp,0x0
80000334: 01010113 addi sp,sp,16 # 80000340 <test9b>
80000338: 34111073 csrw mepc,sp
8000033c: 30200073 mret
80000340 <test9b>:
80000340: 00900e13 li t3,9
80000344: 00000f17 auipc t5,0x0
80000348: 014f0f13 addi t5,t5,20 # 80000358 <test9c>
8000034c: 00100493 li s1,1
80000350: 3ba05073 csrwi pmpaddr10,0
80000354: 0140006f j 80000368 <fail>
80000358 <test9c>:
80000358: 00900e13 li t3,9
8000035c: fff00293 li t0,-1
80000360: 3ba02373 csrr t1,pmpaddr10
80000364: 00628863 beq t0,t1,80000374 <pass>
80000368 <fail>:
80000368: f0100137 lui sp,0xf0100
8000036c: f2410113 addi sp,sp,-220 # f00fff24 <pass+0x700ffbb0>
80000370: 01c12023 sw t3,0(sp)
80000374 <pass>:
80000374: f0100137 lui sp,0xf0100
80000378: f2010113 addi sp,sp,-224 # f00fff20 <pass+0x700ffbac>
8000037c: 00012023 sw zero,0(sp)

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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
)
}