Initial commit of optimized PMP plugin
This commit is contained in:
parent
98eaeaabc8
commit
bf399cc927
|
@ -32,6 +32,14 @@ object CsrAccess {
|
|||
object NONE extends CsrAccess
|
||||
}
|
||||
|
||||
object CsrPlugin {
|
||||
object IS_CSR extends Stageable(Bool)
|
||||
object CSR_WRITE_OPCODE extends Stageable(Bool)
|
||||
object CSR_READ_OPCODE extends Stageable(Bool)
|
||||
object IS_PMP_CFG extends Stageable(Bool)
|
||||
object IS_PMP_ADDR extends Stageable(Bool)
|
||||
}
|
||||
|
||||
case class ExceptionPortInfo(port : Flow[ExceptionCause],stage : Stage, priority : Int)
|
||||
case class CsrPluginConfig(
|
||||
catchIllegalAccess : Boolean,
|
||||
|
@ -399,6 +407,7 @@ trait IWake{
|
|||
class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with ExceptionService with PrivilegeService with InterruptionInhibitor with ExceptionInhibitor with IContextSwitching with CsrInterface with IWake{
|
||||
import config._
|
||||
import CsrAccess._
|
||||
import CsrPlugin._
|
||||
|
||||
assert(!(wfiGenAsNop && wfiGenAsWait))
|
||||
|
||||
|
@ -440,9 +449,6 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
|
|||
}
|
||||
|
||||
object ENV_CTRL extends Stageable(EnvCtrlEnum())
|
||||
object IS_CSR extends Stageable(Bool)
|
||||
object CSR_WRITE_OPCODE extends Stageable(Bool)
|
||||
object CSR_READ_OPCODE extends Stageable(Bool)
|
||||
object PIPELINED_CSR_READ extends Stageable(Bits(32 bits))
|
||||
|
||||
var allowInterrupts : Bool = null
|
||||
|
@ -1029,9 +1035,13 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
|
|||
|| (input(INSTRUCTION)(14 downto 13) === B"11" && imm.z === 0)
|
||||
)
|
||||
insert(CSR_READ_OPCODE) := input(INSTRUCTION)(13 downto 7) =/= B"0100000"
|
||||
|
||||
if (pipeline.serviceExist(classOf[PmpPlugin])) {
|
||||
insert(IS_PMP_CFG) := input(INSTRUCTION)(31 downto 24) === 0x3a
|
||||
insert(IS_PMP_ADDR) := input(INSTRUCTION)(31 downto 24) === 0x3b
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
execute plug new Area{
|
||||
import execute._
|
||||
//Manage WFI instructions
|
||||
|
@ -1103,25 +1113,27 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
|
|||
True -> Mux(input(INSTRUCTION)(12), readToWriteData & ~writeSrc, readToWriteData | writeSrc)
|
||||
)
|
||||
|
||||
when(arbitration.isValid && input(IS_CSR)) {
|
||||
if(!pipelineCsrRead) output(REGFILE_WRITE_DATA) := readData
|
||||
arbitration.haltItself setWhen(blockedBySideEffects)
|
||||
}
|
||||
if(pipelineCsrRead){
|
||||
insert(PIPELINED_CSR_READ) := readData
|
||||
when(memory.arbitration.isValid && memory.input(IS_CSR)) {
|
||||
memory.output(REGFILE_WRITE_DATA) := memory.input(PIPELINED_CSR_READ)
|
||||
val csrAddress = input(INSTRUCTION)(csrRange)
|
||||
val pmpAccess = if (pipeline.serviceExist(classOf[PmpPlugin])) {
|
||||
input(IS_PMP_CFG) | input(IS_PMP_ADDR)
|
||||
} else False
|
||||
|
||||
when (~pmpAccess) {
|
||||
when(arbitration.isValid && input(IS_CSR)) {
|
||||
if(!pipelineCsrRead) output(REGFILE_WRITE_DATA) := readData
|
||||
arbitration.haltItself setWhen(blockedBySideEffects)
|
||||
}
|
||||
if(pipelineCsrRead){
|
||||
insert(PIPELINED_CSR_READ) := readData
|
||||
when(memory.arbitration.isValid && memory.input(IS_CSR)) {
|
||||
memory.output(REGFILE_WRITE_DATA) := memory.input(PIPELINED_CSR_READ)
|
||||
}
|
||||
}
|
||||
}.elsewhen(arbitration.isValid && input(IS_CSR)) {
|
||||
illegalAccess := False
|
||||
}
|
||||
//
|
||||
// Component.current.rework{
|
||||
// when(arbitration.isFiring && input(IS_CSR)) {
|
||||
// memory.input(REGFILE_WRITE_DATA).getDrivingReg := readData
|
||||
// }
|
||||
// }
|
||||
|
||||
//Translation of the csrMapping into real logic
|
||||
val csrAddress = input(INSTRUCTION)(csrRange)
|
||||
Component.current.afterElaboration{
|
||||
def doJobs(jobs : ArrayBuffer[Any]): Unit ={
|
||||
val withWrite = jobs.exists(j => j.isInstanceOf[CsrWrite] || j.isInstanceOf[CsrOnWrite] || j.isInstanceOf[CsrDuringWrite])
|
||||
|
|
|
@ -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,11 @@
|
|||
package vexriscv.plugin
|
||||
|
||||
import vexriscv.{VexRiscv, _}
|
||||
import vexriscv.plugin.CsrPlugin.{_}
|
||||
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
|
||||
|
@ -63,104 +65,70 @@ import scala.collection.mutable.ArrayBuffer
|
|||
* register defines a 4-byte wide region.
|
||||
*/
|
||||
|
||||
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() extends Component with Pmp {
|
||||
val io = new Bundle {
|
||||
val a = in Bits(2 bits)
|
||||
val addr = in UInt(xlen bits)
|
||||
val prevHi = in UInt(30 bits)
|
||||
val boundLo, boundHi = out UInt(30 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)
|
||||
}
|
||||
val shifted = io.addr(29 downto 0)
|
||||
io.boundLo := shifted
|
||||
io.boundHi := shifted
|
||||
|
||||
// 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
|
||||
switch (io.a) {
|
||||
is (TOR) {
|
||||
io.boundLo := io.prevHi
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
io.boundHi := shifted + 1
|
||||
}
|
||||
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
|
||||
is (NAPOT) {
|
||||
val mask = io.addr & ~(io.addr + 1)
|
||||
val boundLo = (io.addr ^ mask)(29 downto 0)
|
||||
io.boundLo := boundLo
|
||||
io.boundHi := boundLo + ((mask + 1) |<< 3)(29 downto 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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, ioRange : UInt => Bool) extends Plugin[VexRiscv] with MemoryTranslator with Pmp {
|
||||
assert(regions % 4 == 0)
|
||||
assert(regions <= 16)
|
||||
|
||||
var setter : PmpSetter = null
|
||||
var dPort, iPort : ProtectedMemoryTranslatorPort = null
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
import pipeline._
|
||||
|
@ -169,78 +137,201 @@ 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 = Reg(Bits(8 * regions bits)) init(0)
|
||||
val boundLo, boundHi = Mem(UInt(30 bits), regions)
|
||||
val cfgRegion = pmpcfg.subdivideIn(8 bits)
|
||||
val cfgRegister = pmpcfg.subdivideIn(xlen bits)
|
||||
val lockMask = Reg(Bits(4 bits)) init(B"4'0")
|
||||
|
||||
// Instantiate pmpaddr0 ... pmpaddr# CSRs.
|
||||
for (i <- 0 until regions) {
|
||||
if (i == 0) {
|
||||
pmps += PmpRegister(null)
|
||||
} else {
|
||||
pmps += PmpRegister(pmps.last)
|
||||
execute plug new Area {
|
||||
import execute._
|
||||
|
||||
val csrAddress = input(INSTRUCTION)(csrRange)
|
||||
val accessAddr = input(IS_PMP_ADDR)
|
||||
val accessCfg = input(IS_PMP_CFG)
|
||||
val pmpWrite = arbitration.isValid && input(IS_CSR) && input(CSR_WRITE_OPCODE) & (accessAddr | accessCfg)
|
||||
val pmpRead = arbitration.isValid && input(IS_CSR) && input(CSR_READ_OPCODE) & (accessAddr | accessCfg)
|
||||
val pmpIndex = csrAddress(log2Up(regions) - 1 downto 0).asUInt
|
||||
val pmpSelect = pmpIndex(log2Up(regions) - 3 downto 0)
|
||||
|
||||
val readAddr = pmpaddr.readAsync(pmpIndex).asBits
|
||||
val readCfg = cfgRegister(pmpSelect)
|
||||
val readToWrite = Mux(accessCfg, readCfg, readAddr)
|
||||
val writeSrc = input(SRC1)
|
||||
val writeData = input(INSTRUCTION)(13).mux(
|
||||
False -> writeSrc,
|
||||
True -> Mux(
|
||||
input(INSTRUCTION)(12),
|
||||
readToWrite & ~writeSrc,
|
||||
readToWrite | writeSrc
|
||||
)
|
||||
)
|
||||
|
||||
val writer = new Area {
|
||||
when (accessCfg) {
|
||||
when (pmpRead) {
|
||||
output(REGFILE_WRITE_DATA).assignFromBits(readCfg)
|
||||
}
|
||||
when (pmpWrite) {
|
||||
switch(pmpSelect) {
|
||||
for (i <- 0 until (regions / 4)) {
|
||||
is(i) {
|
||||
for (j <- Range(0, xlen, 8)) {
|
||||
val bitRange = j + xlen * i + lBit downto j + xlen * i
|
||||
val overwrite = writeData.subdivideIn(8 bits)(j / 8)
|
||||
val locked = cfgRegister(i).subdivideIn(8 bits)(j / 8)(lBit)
|
||||
lockMask(j / 8) := locked
|
||||
when (~locked) {
|
||||
pmpcfg(bitRange).assignFromBits(overwrite)
|
||||
if (j != 0 || i != 0) {
|
||||
when (overwrite(lBit) & overwrite(aBits) === TOR) {
|
||||
pmpcfg(j + xlen * i - 1) := True
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.elsewhen (accessAddr) {
|
||||
when (pmpRead) {
|
||||
output(REGFILE_WRITE_DATA) := readAddr
|
||||
}
|
||||
}
|
||||
csrService.r(0x3b0 + i, pmps(i).state.addr)
|
||||
csrService.w(0x3b0 + i, pmps(i).csr.addr)
|
||||
val locked = cfgRegion(pmpIndex)(lBit)
|
||||
pmpaddr.write(pmpIndex, writeData.asUInt, ~locked & pmpWrite & accessAddr)
|
||||
}
|
||||
|
||||
// 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
|
||||
)
|
||||
}
|
||||
val controller = new StateMachine {
|
||||
val counter = Reg(UInt(log2Up(regions) bits)) init(0)
|
||||
val enable = RegInit(False)
|
||||
|
||||
// Connect memory ports to PMP logic.
|
||||
val ports = for ((port, portId) <- portsInfo.zipWithIndex) yield new Area {
|
||||
val stateIdle : State = new State with EntryPoint {
|
||||
onEntry {
|
||||
lockMask := B"4'x0"
|
||||
enable := False
|
||||
counter := 0
|
||||
}
|
||||
onExit {
|
||||
enable := True
|
||||
arbitration.haltItself := True
|
||||
}
|
||||
whenIsActive {
|
||||
when (pmpWrite) {
|
||||
when (accessCfg) {
|
||||
goto(stateCfg)
|
||||
}.elsewhen (accessAddr) {
|
||||
goto(stateAddr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val address = port.bus.cmd(0).virtualAddress
|
||||
port.bus.rsp.physicalAddress := address
|
||||
val stateCfg : State = new State {
|
||||
onEntry (counter := pmpIndex(log2Up(regions) - 3 downto 0) @@ U"2'00")
|
||||
whenIsActive {
|
||||
counter := counter + 1
|
||||
when (counter(1 downto 0) === 3) {
|
||||
goto(stateIdle)
|
||||
} otherwise {
|
||||
arbitration.haltItself := True
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 stateAddr : State = new State {
|
||||
onEntry (counter := pmpIndex)
|
||||
whenIsActive {
|
||||
counter := counter + 1
|
||||
when (counter === (pmpIndex + 1) | counter === 0) {
|
||||
goto(stateIdle)
|
||||
} otherwise {
|
||||
arbitration.haltItself := 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()
|
||||
when (accessCfg) {
|
||||
setter.io.a := writeData.subdivideIn(8 bits)(counter(1 downto 0))(aBits)
|
||||
setter.io.addr := pmpaddr(counter)
|
||||
} 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.a := cfgRegion(counter)(aBits)
|
||||
when (counter === pmpIndex) {
|
||||
setter.io.addr := writeData.asUInt
|
||||
} otherwise {
|
||||
setter.io.addr := pmpaddr(counter)
|
||||
}
|
||||
}
|
||||
|
||||
when (counter === 0) {
|
||||
setter.io.prevHi := 0
|
||||
} otherwise {
|
||||
setter.io.prevHi := boundHi(counter - 1)
|
||||
}
|
||||
|
||||
when (enable &
|
||||
((accessCfg & ~lockMask(counter(1 downto 0))) |
|
||||
(accessAddr & ~cfgRegion(counter)(lBit)))) {
|
||||
boundLo(counter) := setter.io.boundLo
|
||||
boundHi(counter) := setter.io.boundHi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 >= boundLo(U(i, log2Up(regions) bits)) &
|
||||
address < boundHi(U(i, log2Up(regions) bits)) &
|
||||
(cfgRegion(i)(lBit) | ~privilegeService.isMachine()) &
|
||||
cfgRegion(i)(aBits) =/= 0
|
||||
)
|
||||
}
|
||||
|
||||
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 2))
|
||||
|
||||
when(~hits.orR) {
|
||||
dPort.bus.rsp.allowRead := privilegeService.isMachine()
|
||||
dPort.bus.rsp.allowWrite := privilegeService.isMachine()
|
||||
} otherwise {
|
||||
val oneHot = OHMasking.first(hits)
|
||||
dPort.bus.rsp.allowRead := MuxOH(oneHot, cfgRegion.map(cfg => cfg(rBit)))
|
||||
dPort.bus.rsp.allowWrite := MuxOH(oneHot, cfgRegion.map(cfg => cfg(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 2))
|
||||
|
||||
when(~hits.orR) {
|
||||
iPort.bus.rsp.allowExecute := privilegeService.isMachine()
|
||||
} otherwise {
|
||||
val oneHot = OHMasking.first(hits)
|
||||
iPort.bus.rsp.allowExecute := MuxOH(oneHot, cfgRegion.map(cfg => cfg(xBit)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -17,26 +17,26 @@ Disassembly of section .crt_section:
|
|||
80000018 <test0>:
|
||||
80000018: 00000e13 li t3,0
|
||||
8000001c: 00000f17 auipc t5,0x0
|
||||
80000020: 27cf0f13 addi t5,t5,636 # 80000298 <fail>
|
||||
80000020: 330f0f13 addi t5,t5,816 # 8000034c <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>
|
||||
80000030: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb97>
|
||||
80000034: 0020a023 sw sp,0(ra) # 80000000 <pass+0xfffffca8>
|
||||
80000038: 00222023 sw sp,0(tp) # 80008000 <pass+0x7ca8>
|
||||
8000003c: 0000a183 lw gp,0(ra)
|
||||
80000040: 24311c63 bne sp,gp,80000298 <fail>
|
||||
80000040: 30311663 bne sp,gp,8000034c <fail>
|
||||
80000044: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
|
||||
80000048: 24311863 bne sp,gp,80000298 <fail>
|
||||
80000048: 30311263 bne sp,gp,8000034c <fail>
|
||||
8000004c: 071202b7 lui t0,0x7120
|
||||
80000050: 3a029073 csrw pmpcfg0,t0
|
||||
80000054: 3a002373 csrr t1,pmpcfg0
|
||||
80000058: 24629063 bne t0,t1,80000298 <fail>
|
||||
80000058: 2e629a63 bne t0,t1,8000034c <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>
|
||||
80000068: 000f12b7 lui t0,0xf1
|
||||
8000006c: 90a28293 addi t0,t0,-1782 # f090a <_start-0x7ff0f6f6>
|
||||
80000070: 3a229073 csrw pmpcfg2,t0
|
||||
80000074: 0f1e22b7 lui t0,0xf1e2
|
||||
80000078: 90028293 addi t0,t0,-1792 # f1e1900 <_start-0x70e1e700>
|
||||
|
@ -44,7 +44,7 @@ Disassembly of section .crt_section:
|
|||
80000080: 200002b7 lui t0,0x20000
|
||||
80000084: 3b029073 csrw pmpaddr0,t0
|
||||
80000088: 3b002373 csrr t1,pmpaddr0
|
||||
8000008c: 20629663 bne t0,t1,80000298 <fail>
|
||||
8000008c: 2c629063 bne t0,t1,8000034c <fail>
|
||||
80000090: fff00293 li t0,-1
|
||||
80000094: 3b129073 csrw pmpaddr1,t0
|
||||
80000098: 200022b7 lui t0,0x20002
|
||||
|
@ -85,119 +85,166 @@ Disassembly of section .crt_section:
|
|||
80000124: 0020a023 sw sp,0(ra)
|
||||
80000128: 00222023 sw sp,0(tp) # 0 <_start-0x80000000>
|
||||
8000012c: 0000a183 lw gp,0(ra)
|
||||
80000130: 16311463 bne sp,gp,80000298 <fail>
|
||||
80000130: 20311e63 bne sp,gp,8000034c <fail>
|
||||
80000134: 00000193 li gp,0
|
||||
80000138: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
|
||||
8000013c: 14311e63 bne sp,gp,80000298 <fail>
|
||||
8000013c: 20311863 bne sp,gp,8000034c <fail>
|
||||
|
||||
80000140 <test1>:
|
||||
80000140: 00100e13 li t3,1
|
||||
80000144: 00000f17 auipc t5,0x0
|
||||
80000148: 154f0f13 addi t5,t5,340 # 80000298 <fail>
|
||||
80000148: 208f0f13 addi t5,t5,520 # 8000034c <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>
|
||||
8000015c: 1e629863 bne t0,t1,8000034c <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>
|
||||
80000168: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb97>
|
||||
8000016c: 0020a023 sw sp,0(ra) # 80008000 <pass+0x7ca8>
|
||||
80000170: 00000f17 auipc t5,0x0
|
||||
80000174: 010f0f13 addi t5,t5,16 # 80000180 <test2>
|
||||
80000178: 0000a183 lw gp,0(ra)
|
||||
8000017c: 11c0006f j 80000298 <fail>
|
||||
8000017c: 1d00006f j 8000034c <fail>
|
||||
|
||||
80000180 <test2>:
|
||||
80000180: 00200e13 li t3,2
|
||||
80000184: 00000f17 auipc t5,0x0
|
||||
80000188: 114f0f13 addi t5,t5,276 # 80000298 <fail>
|
||||
80000188: 1c8f0f13 addi t5,t5,456 # 8000034c <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>
|
||||
80000198: 1a628a63 beq t0,t1,8000034c <fail>
|
||||
8000019c: 200042b7 lui t0,0x20004
|
||||
800001a0: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001>
|
||||
800001a4: 3b305073 csrwi pmpaddr3,0
|
||||
800001a8: 3b302373 csrr t1,pmpaddr3
|
||||
800001ac: 1a031063 bnez t1,8000034c <fail>
|
||||
800001b0: 18628e63 beq t0,t1,8000034c <fail>
|
||||
800001b4: 200022b7 lui t0,0x20002
|
||||
800001b8: 3b205073 csrwi pmpaddr2,0
|
||||
800001bc: 3b202373 csrr t1,pmpaddr2
|
||||
800001c0: 18030663 beqz t1,8000034c <fail>
|
||||
800001c4: 18629463 bne t0,t1,8000034c <fail>
|
||||
800001c8: 800080b7 lui ra,0x80008
|
||||
800001cc: deadc137 lui sp,0xdeadc
|
||||
800001d0: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb97>
|
||||
800001d4: 0020a023 sw sp,0(ra) # 80008000 <pass+0x7ca8>
|
||||
800001d8: 00000f17 auipc t5,0x0
|
||||
800001dc: 010f0f13 addi t5,t5,16 # 800001e8 <test3>
|
||||
800001e0: 0000a183 lw gp,0(ra)
|
||||
800001e4: 1680006f j 8000034c <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
|
||||
800001e8 <test3>:
|
||||
800001e8: 00300e13 li t3,3
|
||||
800001ec: 00000f17 auipc t5,0x0
|
||||
800001f0: 160f0f13 addi t5,t5,352 # 8000034c <fail>
|
||||
800001f4: 00ff02b7 lui t0,0xff0
|
||||
800001f8: 3b32a073 csrs pmpaddr3,t0
|
||||
800001fc: 3b302373 csrr t1,pmpaddr3
|
||||
80000200: 14629663 bne t0,t1,8000034c <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: 12629a63 bne t0,t1,8000034c <fail>
|
||||
8000021c: 00ff02b7 lui t0,0xff0
|
||||
80000220: 3b32b073 csrc pmpaddr3,t0
|
||||
80000224: 3b302373 csrr t1,pmpaddr3
|
||||
80000228: 0ff00293 li t0,255
|
||||
8000022c: 12629063 bne t0,t1,8000034c <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: 079202b7 lui t0,0x7920
|
||||
80000244: 10629463 bne t0,t1,8000034c <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: 079202b7 lui t0,0x7920
|
||||
8000025c: 70728293 addi t0,t0,1799 # 7920707 <_start-0x786df8f9>
|
||||
80000260: 0e629663 bne t0,t1,8000034c <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>
|
||||
|
||||
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: 0e4f0f13 addi t5,t5,228 # 8000034c <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: 0c8f0f13 addi t5,t5,200 # 8000034c <fail>
|
||||
8000028c: deadc137 lui sp,0xdeadc
|
||||
80000290: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb97>
|
||||
80000294: 800080b7 lui ra,0x80008
|
||||
80000298: 0020a023 sw sp,0(ra) # 80008000 <pass+0x7ca8>
|
||||
8000029c: 00000f17 auipc t5,0x0
|
||||
800002a0: 010f0f13 addi t5,t5,16 # 800002ac <test6>
|
||||
800002a4: 0000a183 lw gp,0(ra)
|
||||
800002a8: 0a40006f j 8000034c <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: 09cf0f13 addi t5,t5,156 # 8000034c <fail>
|
||||
800002b8: deadc137 lui sp,0xdeadc
|
||||
800002bc: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb97>
|
||||
800002c0: 800000b7 lui ra,0x80000
|
||||
800002c4: 0020a023 sw sp,0(ra) # 80000000 <pass+0xfffffca8>
|
||||
800002c8: 0000a183 lw gp,0(ra)
|
||||
800002cc: 08311063 bne sp,gp,8000034c <fail>
|
||||
|
||||
800002a4 <pass>:
|
||||
800002a4: f0100137 lui sp,0xf0100
|
||||
800002a8: f2010113 addi sp,sp,-224 # f00fff20 <pass+0x700ffc7c>
|
||||
800002ac: 00012023 sw zero,0(sp)
|
||||
800002d0 <test7>:
|
||||
800002d0: 00700e13 li t3,7
|
||||
800002d4: 00000f17 auipc t5,0x0
|
||||
800002d8: 078f0f13 addi t5,t5,120 # 8000034c <fail>
|
||||
800002dc: 800400b7 lui ra,0x80040
|
||||
800002e0: 0000a183 lw gp,0(ra) # 80040000 <pass+0x3fca8>
|
||||
800002e4: 00000f17 auipc t5,0x0
|
||||
800002e8: 074f0f13 addi t5,t5,116 # 80000358 <pass>
|
||||
800002ec: 0030a023 sw gp,0(ra)
|
||||
800002f0: 05c0006f j 8000034c <fail>
|
||||
|
||||
800002f4 <test8>:
|
||||
800002f4: 00800e13 li t3,8
|
||||
800002f8: 00000f17 auipc t5,0x0
|
||||
800002fc: 054f0f13 addi t5,t5,84 # 8000034c <fail>
|
||||
80000300: deadc137 lui sp,0xdeadc
|
||||
80000304: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbb97>
|
||||
80000308: 800300b7 lui ra,0x80030
|
||||
8000030c: ff808093 addi ra,ra,-8 # 8002fff8 <pass+0x2fca0>
|
||||
80000310: 00222023 sw sp,0(tp) # 0 <_start-0x80000000>
|
||||
80000314: 00000f17 auipc t5,0x0
|
||||
80000318: 010f0f13 addi t5,t5,16 # 80000324 <test9>
|
||||
8000031c: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
|
||||
80000320: 02c0006f j 8000034c <fail>
|
||||
|
||||
80000324 <test9>:
|
||||
80000324: 00900e13 li t3,9
|
||||
80000328: 00000f17 auipc t5,0x0
|
||||
8000032c: 024f0f13 addi t5,t5,36 # 8000034c <fail>
|
||||
80000330: 800400b7 lui ra,0x80040
|
||||
80000334: ff808093 addi ra,ra,-8 # 8003fff8 <pass+0x3fca0>
|
||||
80000338: 0000a183 lw gp,0(ra)
|
||||
8000033c: 00000f17 auipc t5,0x0
|
||||
80000340: 01cf0f13 addi t5,t5,28 # 80000358 <pass>
|
||||
80000344: 0030a023 sw gp,0(ra)
|
||||
80000348: 0040006f j 8000034c <fail>
|
||||
|
||||
8000034c <fail>:
|
||||
8000034c: f0100137 lui sp,0xf0100
|
||||
80000350: f2410113 addi sp,sp,-220 # f00fff24 <pass+0x700ffbcc>
|
||||
80000354: 01c12023 sw t3,0(sp)
|
||||
|
||||
80000358 <pass>:
|
||||
80000358: f0100137 lui sp,0xf0100
|
||||
8000035c: f2010113 addi sp,sp,-224 # f00fff20 <pass+0x700ffbc8>
|
||||
80000360: 00012023 sw zero,0(sp)
|
||||
|
|
Binary file not shown.
|
@ -1,13 +1,13 @@
|
|||
:0200000480007A
|
||||
:100000009700000093800001739050306F00C00093
|
||||
:1000100073101F3473002030130E0000170F000000
|
||||
:10002000130FCF27B70000803782008037C1ADDEC5
|
||||
:10002000130F0F33B70000803782008037C1ADDE79
|
||||
:100030001301F1EE23A020002320220083A1000061
|
||||
:10004000631C31248321020063183124B702120794
|
||||
:100050007390023A7323003A63906224B7021F1927
|
||||
:10006000938242307390123AB7020F00938262502B
|
||||
:10004000631631308321020063123130B702120788
|
||||
:100050007390023A7323003A639A622EB7021F1913
|
||||
:10006000938242307390123AB7120F009382A2909B
|
||||
:100070007390223AB7221E0F938202907390323A05
|
||||
:10008000B70200207390023B7323003B639662200B
|
||||
:10008000B70200207390023B7323003B6390622C05
|
||||
:100090009302F0FF7390123BB72200207390223B33
|
||||
:1000A000B74200209382F2FF7390323BB7420020A8
|
||||
:1000B0009382F2FF7390423BB74200209382F2FF9B
|
||||
|
@ -18,29 +18,41 @@
|
|||
:100100007390C23B930200007390D23B93020000B5
|
||||
:100110007390E23B930200007390F23B3701C10001
|
||||
:100120001301E1FE23A020002320220083A1000070
|
||||
:10013000631431169301000083210200631E311401
|
||||
:10014000130E1000170F0000130F4F15B712920770
|
||||
:10015000938282807390023A7323003A639E621204
|
||||
:10013000631E3120930100008321020063183120E7
|
||||
:10014000130E1000170F0000130F8F20B712920725
|
||||
:10015000938282807390023A7323003A6398621EFE
|
||||
:10016000B780008037C1ADDE1301F1EE23A020007F
|
||||
:10017000170F0000130F0F0183A100006F00C011C3
|
||||
:10018000130E2000170F0000130F4F11B7021207B4
|
||||
:100190007390023A7323003A7350203B7323203B41
|
||||
:1001A000630C030E638A620EB780008037C1ADDE38
|
||||
:1001B0001301F1EE23A02000170F0000130F0F0111
|
||||
:1001C00083A100006F00400D130E3000170F0000D8
|
||||
:1001D000130FCF0C1701000013010101731011342C
|
||||
:1001E00073002030130E4000170F0000130F0F0B89
|
||||
:1001F00037C1ADDE1301F1EEB780008023A02000EF
|
||||
:10020000170F0000130F0F0183A100006F00C0083B
|
||||
:10021000130E500037C1ADDE1301F1EEB7000080C0
|
||||
:1002200023A0200083A1000063183106130E600094
|
||||
:10023000B700018083A10000170F0000130FCF0645
|
||||
:1002400023A030006F004005130E7000170F000050
|
||||
:10025000130FCF0437C1ADDE1301F1EEB7000380F9
|
||||
:10026000938080FF23202200170F0000130F8FFAC6
|
||||
:10027000832102006F004002130E8000B70004804B
|
||||
:10028000938080FF83A10000170F0000130FCF01A0
|
||||
:1002900023A030006F004000370110F0130141F23D
|
||||
:1002A0002320C101370110F0130101F223200100C6
|
||||
:10017000170F0000130F0F0183A100006F00001D77
|
||||
:10018000130E2000170F0000130F8F1CB702120769
|
||||
:100190007390023A7323003A638A621AB7420020CE
|
||||
:1001A0009382F2FF7350303B7323303B6310031A8A
|
||||
:1001B000638E6218B72200207350203B7323203BCC
|
||||
:1001C0006306031863946218B780008037C1ADDE00
|
||||
:1001D0001301F1EE23A02000170F0000130F0F01F1
|
||||
:1001E00083A100006F008016130E3000170F00006F
|
||||
:1001F000130F0F16B702FF0073A0323B7323303B7F
|
||||
:10020000639662149302F00F73A0323B7323303B6A
|
||||
:10021000B702FF009382F20F639A6212B702FF00E7
|
||||
:1002200073B0323B7323303B9302F00F6390621242
|
||||
:10023000B702FF009382F20F73B0023A7323003AC1
|
||||
:10024000B702920763946210B702FF009382727044
|
||||
:1002500073A0023A7323003AB70292079382727036
|
||||
:100260006396620E130E4000170F0000130F4F0E1F
|
||||
:1002700017010000130101017310113473002030C5
|
||||
:10028000130E5000170F0000130F8F0C37C1ADDE97
|
||||
:100290001301F1EEB780008023A02000170F0000AB
|
||||
:1002A000130F0F0183A100006F00400A130E6000BE
|
||||
:1002B000170F0000130FCF0937C1ADDE1301F1EEA8
|
||||
:1002C000B700008023A0200083A100006310310844
|
||||
:1002D000130E7000170F0000130F8F07B700048074
|
||||
:1002E00083A10000170F0000130F4F0723A0300059
|
||||
:1002F0006F00C005130E8000170F0000130F4F058D
|
||||
:1003000037C1ADDE1301F1EEB7000380938080FFAB
|
||||
:1003100023202200170F0000130F0F01832102007A
|
||||
:100320006F00C002130E9000170F0000130F4F0252
|
||||
:10033000B7000480938080FF83A10000170F0000A6
|
||||
:10034000130FCF0123A030006F004000370110F0E1
|
||||
:10035000130141F22320C101370110F0130101F212
|
||||
:040360002320010055
|
||||
:040000058000000077
|
||||
:00000001FF
|
||||
|
|
|
@ -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 0x364
|
||||
0x0000000080000000 . = ALIGN (0x4)
|
||||
*crt.o(.text)
|
||||
.text 0x0000000080000000 0x2b0 build/src/crt.o
|
||||
.text 0x0000000080000000 0x364 build/src/crt.o
|
||||
0x0000000080000000 _start
|
||||
0x0000000080000010 trap
|
||||
OUTPUT(build/pmp.elf elf32-littleriscv)
|
||||
|
||||
.data 0x00000000800002b0 0x0
|
||||
.data 0x00000000800002b0 0x0 build/src/crt.o
|
||||
.data 0x0000000080000364 0x0
|
||||
.data 0x0000000080000364 0x0 build/src/crt.o
|
||||
|
||||
.bss 0x00000000800002b0 0x0
|
||||
.bss 0x00000000800002b0 0x0 build/src/crt.o
|
||||
.bss 0x0000000080000364 0x0
|
||||
.bss 0x0000000080000364 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
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
#define TRAP_RA x30
|
||||
|
||||
#define PMPCFG0 0x07120000
|
||||
#define PMPCFG0_ 0x07920808 // locked
|
||||
#define PMPCFG0_ 0x07920808
|
||||
#define PMPCFG1 0x191f0304
|
||||
#define PMPCFG2 0x000f0506
|
||||
#define PMPCFG2 0x000f090a
|
||||
#define PMPCFG3 0x0f1e1900
|
||||
|
||||
#define PMPADDR0 0x20000000 // OFF
|
||||
#define PMPADDR1 0xffffffff // OFF
|
||||
#define PMPADDR0 0x20000000 // OFF (test0) -> TOR (test1) -> OFF (test2)
|
||||
#define PMPADDR1 0xffffffff // OFF (test0) -> TOR (test1) -> OFF (test2)
|
||||
#define PMPADDR2 0x20002000 // NA4 W
|
||||
#define PMPADDR3 0x20003fff // OFF RWX
|
||||
#define PMPADDR3 0x20003fff // OFF RWX -> 0x00000000 OFF RWX (test2)
|
||||
#define PMPADDR4 0x20003fff // OFF X
|
||||
#define PMPADDR5 0x20003fff // OFF RW
|
||||
#define PMPADDR6 0x20001fff // NAPOT RWX
|
||||
|
@ -132,10 +132,17 @@ test2:
|
|||
li x5, PMPCFG0
|
||||
csrw pmpcfg0, x5 // "unlock" region 2
|
||||
csrr x6, pmpcfg0
|
||||
beq x5, x6, fail
|
||||
li x5, PMPADDR3
|
||||
csrwi pmpaddr3, 0x0
|
||||
csrr x6, pmpaddr3
|
||||
bnez x6, fail
|
||||
beq x5, x6, fail
|
||||
li x5, PMPADDR2
|
||||
csrwi pmpaddr2, 0x0
|
||||
csrr x6, pmpaddr2
|
||||
beqz x6, fail
|
||||
beq x5, x6, fail
|
||||
beqz x6, fail
|
||||
bne x5, x6, fail
|
||||
li x1, 0x80008000
|
||||
li x2, 0xdeadbeef
|
||||
sw x2, 0x0(x1) // should still be OK (write 0x80008000)
|
||||
|
@ -143,54 +150,86 @@ test2:
|
|||
lw x3, 0x0(x1) // should still fault (read 0x80008000)
|
||||
j fail
|
||||
|
||||
// jump into user mode
|
||||
// verify masked CSR read/write operations
|
||||
test3:
|
||||
li TEST_ID, 3
|
||||
la TRAP_RA, fail
|
||||
la x2, test4
|
||||
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, 0x07920000
|
||||
bne x5, x6, fail
|
||||
li x5, 0x00ff0707
|
||||
csrs pmpcfg0, x5
|
||||
csrr x6, pmpcfg0
|
||||
li x5, 0x07920707
|
||||
bne x5, x6, fail
|
||||
|
||||
// jump into user mode
|
||||
test4:
|
||||
li TEST_ID, 4
|
||||
la TRAP_RA, fail
|
||||
la x2, test5
|
||||
csrw mepc, x2
|
||||
mret
|
||||
|
||||
// attempt to read/write region 2 from user mode
|
||||
test4:
|
||||
li TEST_ID, 4
|
||||
test5:
|
||||
li TEST_ID, 5
|
||||
la TRAP_RA, fail
|
||||
li x2, 0xdeadbeef
|
||||
li x1, 0x80008000
|
||||
sw x2, 0x0(x1) // should be OK (write 0x80008000)
|
||||
la TRAP_RA, test5
|
||||
la TRAP_RA, test6
|
||||
lw x3, 0x0(x1) // should fault (read 0x80008000)
|
||||
j fail
|
||||
|
||||
// attempt to read/write other regions from user mode
|
||||
test5:
|
||||
li TEST_ID, 5
|
||||
test6:
|
||||
li TEST_ID, 6
|
||||
la TRAP_RA, 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)
|
||||
|
||||
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
|
||||
|
||||
test7:
|
||||
li TEST_ID, 7
|
||||
la TRAP_RA, fail
|
||||
li x1, 0x80040000
|
||||
lw x3, 0x0(x1) // should be OK (read 0x80040000)
|
||||
la TRAP_RA, pass
|
||||
sw x3, 0x0(x1) // should fault (write 0x80040000)
|
||||
j fail
|
||||
|
||||
test8:
|
||||
li TEST_ID, 8
|
||||
la TRAP_RA, fail
|
||||
li x2, 0xdeadbeef
|
||||
li x1, 0x8002fff8
|
||||
sw x2, 0x0(x4) // should be OK (write 0x8002fff8)
|
||||
la TRAP_RA, test5
|
||||
la TRAP_RA, test9
|
||||
lw x3, 0x0(x4) // should fault (read 0x8002fff8)
|
||||
j fail
|
||||
|
||||
test8:
|
||||
li TEST_ID, 8
|
||||
test9:
|
||||
li TEST_ID, 9
|
||||
la TRAP_RA, fail
|
||||
li x1, 0x8003fff8
|
||||
lw x3, 0x0(x1) // should be OK (read 0x8003fff8)
|
||||
la TRAP_RA, pass
|
||||
|
|
Loading…
Reference in New Issue