Merge pull request #147 from lindemer/pmp
Physical Memory Protection (PMP) plugin
This commit is contained in:
commit
d2855fcfca
|
@ -0,0 +1,86 @@
|
|||
package vexriscv.demo
|
||||
|
||||
import vexriscv.plugin._
|
||||
import vexriscv.ip.{DataCacheConfig, InstructionCacheConfig}
|
||||
import vexriscv.{plugin, VexRiscv, VexRiscvConfig}
|
||||
import spinal.core._
|
||||
|
||||
object GenSecure extends App {
|
||||
def cpu() = new VexRiscv(
|
||||
config = VexRiscvConfig(
|
||||
plugins = List(
|
||||
new IBusCachedPlugin(
|
||||
resetVector = 0x80000000l,
|
||||
prediction = STATIC,
|
||||
config = InstructionCacheConfig(
|
||||
cacheSize = 4096,
|
||||
bytePerLine = 32,
|
||||
wayCount = 1,
|
||||
addressWidth = 32,
|
||||
cpuDataWidth = 32,
|
||||
memDataWidth = 32,
|
||||
catchIllegalAccess = true,
|
||||
catchAccessFault = true,
|
||||
asyncTagMemory = false,
|
||||
twoCycleRam = true,
|
||||
twoCycleCache = true
|
||||
)
|
||||
),
|
||||
new DBusCachedPlugin(
|
||||
config = new DataCacheConfig(
|
||||
cacheSize = 4096,
|
||||
bytePerLine = 32,
|
||||
wayCount = 1,
|
||||
addressWidth = 32,
|
||||
cpuDataWidth = 32,
|
||||
memDataWidth = 32,
|
||||
catchAccessError = true,
|
||||
catchIllegal = true,
|
||||
catchUnaligned = true
|
||||
)
|
||||
),
|
||||
new PmpPlugin(
|
||||
regions = 16,
|
||||
ioRange = _(31 downto 28) === 0xf
|
||||
),
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = true
|
||||
),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = plugin.SYNC,
|
||||
zeroBoot = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new SrcPlugin(
|
||||
separatedAddSub = false,
|
||||
executeInsertion = true
|
||||
),
|
||||
new FullBarrelShifterPlugin,
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = true,
|
||||
bypassMemory = true,
|
||||
bypassWriteBack = true,
|
||||
bypassWriteBackBuffer = true,
|
||||
pessimisticUseSrc = false,
|
||||
pessimisticWriteRegFile = false,
|
||||
pessimisticAddressMatch = false
|
||||
),
|
||||
new MulDivIterativePlugin(
|
||||
genMul = true,
|
||||
genDiv = true,
|
||||
mulUnrollFactor = 1,
|
||||
divUnrollFactor = 1
|
||||
),
|
||||
new CsrPlugin(CsrPluginConfig.secure(0x00000020l)),
|
||||
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
|
||||
new BranchPlugin(
|
||||
earlyBranch = false,
|
||||
catchAddressMisaligned = true
|
||||
),
|
||||
new YamlPlugin("cpu0.yaml")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
SpinalVerilog(cpu())
|
||||
}
|
|
@ -264,6 +264,31 @@ object CsrPluginConfig{
|
|||
uinstretAccess = CsrAccess.NONE
|
||||
)
|
||||
|
||||
def secure(mtvecInit : BigInt) = CsrPluginConfig(
|
||||
catchIllegalAccess = true,
|
||||
mvendorid = 1,
|
||||
marchid = 2,
|
||||
mimpid = 3,
|
||||
mhartid = 0,
|
||||
misaExtensionsInit = 0x101064, // RV32GCFMU
|
||||
misaAccess = CsrAccess.READ_WRITE,
|
||||
mtvecAccess = CsrAccess.READ_WRITE,
|
||||
mtvecInit = mtvecInit,
|
||||
mepcAccess = CsrAccess.READ_WRITE,
|
||||
mscratchGen = true,
|
||||
mcauseAccess = CsrAccess.READ_WRITE,
|
||||
mbadaddrAccess = CsrAccess.READ_WRITE,
|
||||
mcycleAccess = CsrAccess.READ_WRITE,
|
||||
minstretAccess = CsrAccess.READ_WRITE,
|
||||
ucycleAccess = CsrAccess.READ_ONLY,
|
||||
uinstretAccess = CsrAccess.READ_ONLY,
|
||||
wfiGenAsWait = true,
|
||||
ecallGen = true,
|
||||
userGen = true,
|
||||
medelegAccess = CsrAccess.READ_WRITE,
|
||||
midelegAccess = CsrAccess.READ_WRITE
|
||||
)
|
||||
|
||||
}
|
||||
case class CsrWrite(that : Data, bitOffset : Int)
|
||||
case class CsrRead(that : Data , bitOffset : Int)
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Samuel Lindemer <samuel.lindemer@ri.se>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
package vexriscv.plugin
|
||||
|
||||
import vexriscv.{VexRiscv, _}
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
/* Each 32-bit pmpcfg# register contains four 8-bit configuration sections.
|
||||
* These section numbers contain flags which apply to regions defined by the
|
||||
* corresponding pmpaddr# register.
|
||||
*
|
||||
* 3 2 1
|
||||
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | pmp3cfg | pmp2cfg | pmp1cfg | pmp0cfg | pmpcfg0
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | pmp7cfg | pmp6cfg | pmp5cfg | pmp4cfg | pmpcfg2
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
* 7 6 5 4 3 2 1 0
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* | L | 0 | A | X | W | R | pmp#cfg
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
*
|
||||
* L: locks configuration until system reset (including M-mode)
|
||||
* 0: hardwired to zero
|
||||
* A: 0 = OFF (null region / disabled)
|
||||
* 1 = TOR (top of range)
|
||||
* 2 = NA4 (naturally aligned four-byte region)
|
||||
* 3 = NAPOT (naturally aligned power-of-two region, > 7 bytes)
|
||||
* X: execute
|
||||
* W: write
|
||||
* R: read
|
||||
*
|
||||
* TOR: Each 32-bit pmpaddr# register defines the upper bound of the pmp region
|
||||
* right-shifted by two bits. The lower bound of the region is the previous
|
||||
* pmpaddr# register. In the case of pmpaddr0, the lower bound is address 0x0.
|
||||
*
|
||||
* 3 2 1
|
||||
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | address[33:2] | pmpaddr#
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
* NAPOT: Each 32-bit pmpaddr# register defines the region address and the size
|
||||
* of the pmp region. The number of concurrent 1s begging at the LSB indicates
|
||||
* the size of the region as a power of two (e.g. 0x...0 = 8-byte, 0x...1 =
|
||||
* 16-byte, 0x...11 = 32-byte, etc.).
|
||||
*
|
||||
* 3 2 1
|
||||
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | address[33:2] |0|1|1|1|1| pmpaddr#
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
* NA4: This is essentially an edge case of NAPOT where the entire pmpaddr#
|
||||
* register defines a 4-byte wide region.
|
||||
*/
|
||||
|
||||
case class PmpRegister(previous : PmpRegister) extends Area {
|
||||
|
||||
def OFF = 0
|
||||
def TOR = 1
|
||||
def NA4 = 2
|
||||
def NAPOT = 3
|
||||
|
||||
// Software-accessible CSR interface
|
||||
val csr = new Area {
|
||||
val r, w, x = Reg(Bool)
|
||||
val l = RegInit(False)
|
||||
val a = Reg(UInt(2 bits)) init(0)
|
||||
val addr = Reg(UInt(32 bits))
|
||||
}
|
||||
|
||||
// Active region bounds and permissions (internal)
|
||||
val region = new Area {
|
||||
val r, w, x = Reg(Bool)
|
||||
val l, valid = RegInit(False)
|
||||
val start, end = Reg(UInt(32 bits))
|
||||
}
|
||||
|
||||
when(~region.l) {
|
||||
region.r := csr.r
|
||||
region.w := csr.w
|
||||
region.x := csr.x
|
||||
region.l := csr.l
|
||||
|
||||
val shifted = csr.addr |<< 2
|
||||
region.valid := True
|
||||
|
||||
switch(csr.a) {
|
||||
|
||||
is(TOR) {
|
||||
if (previous == null) {
|
||||
region.start := 0
|
||||
} else {
|
||||
region.start := previous.region.end
|
||||
}
|
||||
if (csr.l == True) {
|
||||
previous.region.l := True
|
||||
}
|
||||
region.end := shifted
|
||||
}
|
||||
|
||||
is(NA4) {
|
||||
region.start := shifted
|
||||
region.end := shifted + 4
|
||||
}
|
||||
|
||||
is(NAPOT) {
|
||||
val mask = csr.addr & ~(csr.addr + 1)
|
||||
val masked = (csr.addr & ~mask) |<< 2
|
||||
region.start := masked
|
||||
region.end := masked + ((mask + 1) |<< 3)
|
||||
}
|
||||
|
||||
default {
|
||||
region.end := shifted
|
||||
region.valid := False
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case class ProtectedMemoryTranslatorPort(bus : MemoryTranslatorBus)
|
||||
|
||||
class PmpPlugin(regions : Int, ioRange : UInt => Bool) extends Plugin[VexRiscv] with MemoryTranslator {
|
||||
|
||||
// Each pmpcfg# CSR configures four regions.
|
||||
assert((regions % 4) == 0)
|
||||
|
||||
val pmps = ArrayBuffer[PmpRegister]()
|
||||
val portsInfo = ArrayBuffer[ProtectedMemoryTranslatorPort]()
|
||||
|
||||
override def newTranslationPort(priority : Int, args : Any): MemoryTranslatorBus = {
|
||||
val port = ProtectedMemoryTranslatorPort(MemoryTranslatorBus())
|
||||
portsInfo += port
|
||||
port.bus
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
import pipeline._
|
||||
import Riscv._
|
||||
|
||||
val csrService = pipeline.service(classOf[CsrInterface])
|
||||
val privilegeService = pipeline.service(classOf[PrivilegeService])
|
||||
|
||||
val core = pipeline plug new Area {
|
||||
|
||||
// Instantiate pmpaddr0 ... pmpaddr# CSRs.
|
||||
for (i <- 0 until regions) {
|
||||
if (i == 0) {
|
||||
pmps += PmpRegister(null)
|
||||
} else {
|
||||
pmps += PmpRegister(pmps.last)
|
||||
}
|
||||
csrService.rw(0x3b0 + i, pmps(i).csr.addr)
|
||||
}
|
||||
|
||||
// Instantiate pmpcfg0 ... pmpcfg# CSRs.
|
||||
for (i <- 0 until (regions / 4)) {
|
||||
csrService.rw(0x3a0 + i,
|
||||
31 -> pmps((i * 4) + 3).csr.l, 23 -> pmps((i * 4) + 2).csr.l,
|
||||
15 -> pmps((i * 4) + 1).csr.l, 7 -> pmps((i * 4) ).csr.l,
|
||||
27 -> pmps((i * 4) + 3).csr.a, 26 -> pmps((i * 4) + 3).csr.x,
|
||||
25 -> pmps((i * 4) + 3).csr.w, 24 -> pmps((i * 4) + 3).csr.r,
|
||||
19 -> pmps((i * 4) + 2).csr.a, 18 -> pmps((i * 4) + 2).csr.x,
|
||||
17 -> pmps((i * 4) + 2).csr.w, 16 -> pmps((i * 4) + 2).csr.r,
|
||||
11 -> pmps((i * 4) + 1).csr.a, 10 -> pmps((i * 4) + 1).csr.x,
|
||||
9 -> pmps((i * 4) + 1).csr.w, 8 -> pmps((i * 4) + 1).csr.r,
|
||||
3 -> pmps((i * 4) ).csr.a, 2 -> pmps((i * 4) ).csr.x,
|
||||
1 -> pmps((i * 4) ).csr.w, 0 -> pmps((i * 4) ).csr.r
|
||||
)
|
||||
}
|
||||
|
||||
// Connect memory ports to PMP logic.
|
||||
val ports = for ((port, portId) <- portsInfo.zipWithIndex) yield new Area {
|
||||
|
||||
val address = port.bus.cmd.virtualAddress
|
||||
port.bus.rsp.physicalAddress := address
|
||||
|
||||
// Only the first matching PMP region applies.
|
||||
val hits = pmps.map(pmp => pmp.region.valid &&
|
||||
pmp.region.start <= address &&
|
||||
pmp.region.end > address &&
|
||||
(pmp.region.l || ~privilegeService.isMachine()))
|
||||
|
||||
// M-mode has full access by default, 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()
|
||||
} otherwise {
|
||||
port.bus.rsp.allowRead := MuxOH(OHMasking.first(hits), pmps.map(_.region.r))
|
||||
port.bus.rsp.allowWrite := MuxOH(OHMasking.first(hits), pmps.map(_.region.w))
|
||||
port.bus.rsp.allowExecute := MuxOH(OHMasking.first(hits), pmps.map(_.region.x))
|
||||
}
|
||||
|
||||
port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress)
|
||||
port.bus.rsp.exception := False
|
||||
port.bus.rsp.refilling := False
|
||||
port.bus.busy := False
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
|
||||
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>
|
||||
|
||||
80000010 <trap>:
|
||||
80000010: 341f1073 csrw mepc,t5
|
||||
80000014: 30200073 mret
|
||||
|
||||
80000018 <test0>:
|
||||
80000018: 00000e13 li t3,0
|
||||
8000001c: 00000f17 auipc t5,0x0
|
||||
80000020: 250f0f13 addi t5,t5,592 # 8000026c <fail>
|
||||
80000024: 800000b7 lui ra,0x80000
|
||||
80000028: 80008237 lui tp,0x80008
|
||||
8000002c: deadc137 lui sp,0xdeadc
|
||||
80000030: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc77>
|
||||
80000034: 0020a023 sw sp,0(ra) # 80000000 <pass+0xfffffd88>
|
||||
80000038: 00222023 sw sp,0(tp) # 80008000 <pass+0x7d88>
|
||||
8000003c: 0000a183 lw gp,0(ra)
|
||||
80000040: 22311663 bne sp,gp,8000026c <fail>
|
||||
80000044: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
|
||||
80000048: 22311263 bne sp,gp,8000026c <fail>
|
||||
8000004c: 071202b7 lui t0,0x7120
|
||||
80000050: 3a029073 csrw pmpcfg0,t0
|
||||
80000054: 191f02b7 lui t0,0x191f0
|
||||
80000058: 30428293 addi t0,t0,772 # 191f0304 <_start-0x66e0fcfc>
|
||||
8000005c: 3a129073 csrw pmpcfg1,t0
|
||||
80000060: 000f02b7 lui t0,0xf0
|
||||
80000064: 50628293 addi t0,t0,1286 # f0506 <_start-0x7ff0fafa>
|
||||
80000068: 3a229073 csrw pmpcfg2,t0
|
||||
8000006c: 0f1e22b7 lui t0,0xf1e2
|
||||
80000070: 90028293 addi t0,t0,-1792 # f1e1900 <_start-0x70e1e700>
|
||||
80000074: 3a329073 csrw pmpcfg3,t0
|
||||
80000078: 200002b7 lui t0,0x20000
|
||||
8000007c: 3b029073 csrw pmpaddr0,t0
|
||||
80000080: fff00293 li t0,-1
|
||||
80000084: 3b129073 csrw pmpaddr1,t0
|
||||
80000088: 200022b7 lui t0,0x20002
|
||||
8000008c: 3b229073 csrw pmpaddr2,t0
|
||||
80000090: 200042b7 lui t0,0x20004
|
||||
80000094: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001>
|
||||
80000098: 3b329073 csrw pmpaddr3,t0
|
||||
8000009c: 200042b7 lui t0,0x20004
|
||||
800000a0: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001>
|
||||
800000a4: 3b429073 csrw pmpaddr4,t0
|
||||
800000a8: 200042b7 lui t0,0x20004
|
||||
800000ac: fff28293 addi t0,t0,-1 # 20003fff <_start-0x5fffc001>
|
||||
800000b0: 3b529073 csrw pmpaddr5,t0
|
||||
800000b4: 200022b7 lui t0,0x20002
|
||||
800000b8: fff28293 addi t0,t0,-1 # 20001fff <_start-0x5fffe001>
|
||||
800000bc: 3b629073 csrw pmpaddr6,t0
|
||||
800000c0: 200062b7 lui t0,0x20006
|
||||
800000c4: fff28293 addi t0,t0,-1 # 20005fff <_start-0x5fffa001>
|
||||
800000c8: 3b729073 csrw pmpaddr7,t0
|
||||
800000cc: 2000c2b7 lui t0,0x2000c
|
||||
800000d0: 3b829073 csrw pmpaddr8,t0
|
||||
800000d4: 2000d2b7 lui t0,0x2000d
|
||||
800000d8: 3b929073 csrw pmpaddr9,t0
|
||||
800000dc: fff00293 li t0,-1
|
||||
800000e0: 3ba29073 csrw pmpaddr10,t0
|
||||
800000e4: 00000293 li t0,0
|
||||
800000e8: 3bb29073 csrw pmpaddr11,t0
|
||||
800000ec: 00000293 li t0,0
|
||||
800000f0: 3bc29073 csrw pmpaddr12,t0
|
||||
800000f4: 00000293 li t0,0
|
||||
800000f8: 3bd29073 csrw pmpaddr13,t0
|
||||
800000fc: 00000293 li t0,0
|
||||
80000100: 3be29073 csrw pmpaddr14,t0
|
||||
80000104: 00000293 li t0,0
|
||||
80000108: 3bf29073 csrw pmpaddr15,t0
|
||||
8000010c: 00c10137 lui sp,0xc10
|
||||
80000110: fee10113 addi sp,sp,-18 # c0ffee <_start-0x7f3f0012>
|
||||
80000114: 0020a023 sw sp,0(ra)
|
||||
80000118: 00222023 sw sp,0(tp) # 0 <_start-0x80000000>
|
||||
8000011c: 0000a183 lw gp,0(ra)
|
||||
80000120: 14311663 bne sp,gp,8000026c <fail>
|
||||
80000124: 00000193 li gp,0
|
||||
80000128: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
|
||||
8000012c: 14311063 bne sp,gp,8000026c <fail>
|
||||
|
||||
80000130 <test1>:
|
||||
80000130: 00100e13 li t3,1
|
||||
80000134: 00000f17 auipc t5,0x0
|
||||
80000138: 138f0f13 addi t5,t5,312 # 8000026c <fail>
|
||||
8000013c: 079212b7 lui t0,0x7921
|
||||
80000140: 80828293 addi t0,t0,-2040 # 7920808 <_start-0x786df7f8>
|
||||
80000144: 3a029073 csrw pmpcfg0,t0
|
||||
80000148: 800080b7 lui ra,0x80008
|
||||
8000014c: deadc137 lui sp,0xdeadc
|
||||
80000150: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc77>
|
||||
80000154: 0020a023 sw sp,0(ra) # 80008000 <pass+0x7d88>
|
||||
80000158: 00000f17 auipc t5,0x0
|
||||
8000015c: 010f0f13 addi t5,t5,16 # 80000168 <test2>
|
||||
80000160: 0000a183 lw gp,0(ra)
|
||||
80000164: 1080006f j 8000026c <fail>
|
||||
|
||||
80000168 <test2>:
|
||||
80000168: 00200e13 li t3,2
|
||||
8000016c: 00000f17 auipc t5,0x0
|
||||
80000170: 100f0f13 addi t5,t5,256 # 8000026c <fail>
|
||||
80000174: 071202b7 lui t0,0x7120
|
||||
80000178: 3a029073 csrw pmpcfg0,t0
|
||||
8000017c: 800080b7 lui ra,0x80008
|
||||
80000180: deadc137 lui sp,0xdeadc
|
||||
80000184: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc77>
|
||||
80000188: 0020a023 sw sp,0(ra) # 80008000 <pass+0x7d88>
|
||||
8000018c: 00000f17 auipc t5,0x0
|
||||
80000190: 010f0f13 addi t5,t5,16 # 8000019c <test3>
|
||||
80000194: 0000a183 lw gp,0(ra)
|
||||
80000198: 0d40006f j 8000026c <fail>
|
||||
|
||||
8000019c <test3>:
|
||||
8000019c: 00300e13 li t3,3
|
||||
800001a0: 00000f17 auipc t5,0x0
|
||||
800001a4: 0ccf0f13 addi t5,t5,204 # 8000026c <fail>
|
||||
800001a8: 00000117 auipc sp,0x0
|
||||
800001ac: 01010113 addi sp,sp,16 # 800001b8 <test4>
|
||||
800001b0: 34111073 csrw mepc,sp
|
||||
800001b4: 30200073 mret
|
||||
|
||||
800001b8 <test4>:
|
||||
800001b8: 00400e13 li t3,4
|
||||
800001bc: 00000f17 auipc t5,0x0
|
||||
800001c0: 0b0f0f13 addi t5,t5,176 # 8000026c <fail>
|
||||
800001c4: deadc137 lui sp,0xdeadc
|
||||
800001c8: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc77>
|
||||
800001cc: 800080b7 lui ra,0x80008
|
||||
800001d0: 0020a023 sw sp,0(ra) # 80008000 <pass+0x7d88>
|
||||
800001d4: 00000f17 auipc t5,0x0
|
||||
800001d8: 010f0f13 addi t5,t5,16 # 800001e4 <test5>
|
||||
800001dc: 0000a183 lw gp,0(ra)
|
||||
800001e0: 08c0006f j 8000026c <fail>
|
||||
|
||||
800001e4 <test5>:
|
||||
800001e4: 00500e13 li t3,5
|
||||
800001e8: deadc137 lui sp,0xdeadc
|
||||
800001ec: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc77>
|
||||
800001f0: 800000b7 lui ra,0x80000
|
||||
800001f4: 0020a023 sw sp,0(ra) # 80000000 <pass+0xfffffd88>
|
||||
800001f8: 0000a183 lw gp,0(ra)
|
||||
800001fc: 06311863 bne sp,gp,8000026c <fail>
|
||||
|
||||
80000200 <test6>:
|
||||
80000200: 00600e13 li t3,6
|
||||
80000204: 800100b7 lui ra,0x80010
|
||||
80000208: 0000a183 lw gp,0(ra) # 80010000 <pass+0xfd88>
|
||||
8000020c: 00000f17 auipc t5,0x0
|
||||
80000210: 06cf0f13 addi t5,t5,108 # 80000278 <pass>
|
||||
80000214: 0030a023 sw gp,0(ra)
|
||||
80000218: 0540006f j 8000026c <fail>
|
||||
|
||||
8000021c <test7>:
|
||||
8000021c: 00700e13 li t3,7
|
||||
80000220: 00000f17 auipc t5,0x0
|
||||
80000224: 04cf0f13 addi t5,t5,76 # 8000026c <fail>
|
||||
80000228: deadc137 lui sp,0xdeadc
|
||||
8000022c: eef10113 addi sp,sp,-273 # deadbeef <pass+0x5eadbc77>
|
||||
80000230: 800300b7 lui ra,0x80030
|
||||
80000234: ff808093 addi ra,ra,-8 # 8002fff8 <pass+0x2fd80>
|
||||
80000238: 00222023 sw sp,0(tp) # 0 <_start-0x80000000>
|
||||
8000023c: 00000f17 auipc t5,0x0
|
||||
80000240: fa8f0f13 addi t5,t5,-88 # 800001e4 <test5>
|
||||
80000244: 00022183 lw gp,0(tp) # 0 <_start-0x80000000>
|
||||
80000248: 0240006f j 8000026c <fail>
|
||||
|
||||
8000024c <test8>:
|
||||
8000024c: 00800e13 li t3,8
|
||||
80000250: 800400b7 lui ra,0x80040
|
||||
80000254: ff808093 addi ra,ra,-8 # 8003fff8 <pass+0x3fd80>
|
||||
80000258: 0000a183 lw gp,0(ra)
|
||||
8000025c: 00000f17 auipc t5,0x0
|
||||
80000260: 01cf0f13 addi t5,t5,28 # 80000278 <pass>
|
||||
80000264: 0030a023 sw gp,0(ra)
|
||||
80000268: 0040006f j 8000026c <fail>
|
||||
|
||||
8000026c <fail>:
|
||||
8000026c: f0100137 lui sp,0xf0100
|
||||
80000270: f2410113 addi sp,sp,-220 # f00fff24 <pass+0x700ffcac>
|
||||
80000274: 01c12023 sw t3,0(sp)
|
||||
|
||||
80000278 <pass>:
|
||||
80000278: f0100137 lui sp,0xf0100
|
||||
8000027c: f2010113 addi sp,sp,-224 # f00fff20 <pass+0x700ffca8>
|
||||
80000280: 00012023 sw zero,0(sp)
|
Binary file not shown.
|
@ -0,0 +1,44 @@
|
|||
:0200000480007A
|
||||
:100000009700000093800001739050306F00C00093
|
||||
:1000100073101F3473002030130E0000170F000000
|
||||
:10002000130F0F25B70000803782008037C1ADDE87
|
||||
:100030001301F1EE23A020002320220083A1000061
|
||||
:10004000631631228321020063123122B7021207A4
|
||||
:100050007390023AB7021F19938242307390123A9A
|
||||
:10006000B7020F00938262507390223AB7221E0F9C
|
||||
:10007000938202907390323AB70200207390023B51
|
||||
:100080009302F0FF7390123BB72200207390223B43
|
||||
:10009000B74200209382F2FF7390323BB7420020B8
|
||||
:1000A0009382F2FF7390423BB74200209382F2FFAB
|
||||
:1000B0007390523BB72200209382F2FF7390623B11
|
||||
:1000C000B76200209382F2FF7390723BB7C20020A8
|
||||
:1000D0007390823BB7D200207390923B9302F0FF63
|
||||
:1000E0007390A23B930200007390B23B9302000016
|
||||
:1000F0007390C23B930200007390D23B93020000C6
|
||||
:100100007390E23B930200007390F23B3701C10011
|
||||
:100110001301E1FE23A020002320220083A1000080
|
||||
:10012000631631149301000083210200631031141F
|
||||
:10013000130E1000170F0000130F8F13B712920742
|
||||
:10014000938282807390023AB780008037C1ADDE1F
|
||||
:100150001301F1EE23A02000170F0000130F0F0171
|
||||
:1001600083A100006F008010130E2000170F000005
|
||||
:10017000130F0F10B70212077390023AB780008076
|
||||
:1001800037C1ADDE1301F1EE23A02000170F0000F0
|
||||
:10019000130F0F0183A100006F00400D130E3000FC
|
||||
:1001A000170F0000130FCF0C1701000013010101FE
|
||||
:1001B0007310113473002030130E4000170F00002D
|
||||
:1001C000130F0F0B37C1ADDE1301F1EEB7800080C6
|
||||
:1001D00023A02000170F0000130F0F0183A10000C0
|
||||
:1001E0006F00C008130E500037C1ADDE1301F1EEF1
|
||||
:1001F000B700008023A0200083A10000631831060F
|
||||
:10020000130E6000B700018083A10000170F0000EB
|
||||
:10021000130FCF0623A030006F004005130E7000AF
|
||||
:10022000170F0000130FCF0437C1ADDE1301F1EE3D
|
||||
:10023000B7000380938080FF23202200170F000067
|
||||
:10024000130F8FFA832102006F004002130E80000B
|
||||
:10025000B7000480938080FF83A10000170F000087
|
||||
:10026000130FCF0123A030006F004000370110F0C2
|
||||
:10027000130141F22320C101370110F0130101F2F3
|
||||
:040280002320010036
|
||||
:040000058000000077
|
||||
:00000001FF
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
Memory Configuration
|
||||
|
||||
Name Origin Length Attributes
|
||||
onChipRam 0x0000000080000000 0x0000000000020000 w !xr
|
||||
*default* 0x0000000000000000 0xffffffffffffffff
|
||||
|
||||
Linker script and memory map
|
||||
|
||||
LOAD build/src/crt.o
|
||||
LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/libgcc.a
|
||||
START GROUP
|
||||
LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a
|
||||
LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libgloss.a
|
||||
END GROUP
|
||||
LOAD /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/libgcc.a
|
||||
|
||||
.crt_section 0x0000000080000000 0x284
|
||||
0x0000000080000000 . = ALIGN (0x4)
|
||||
*crt.o(.text)
|
||||
.text 0x0000000080000000 0x284 build/src/crt.o
|
||||
0x0000000080000000 _start
|
||||
0x0000000080000010 trap
|
||||
OUTPUT(build/pmp.elf elf32-littleriscv)
|
||||
|
||||
.data 0x0000000080000284 0x0
|
||||
.data 0x0000000080000284 0x0 build/src/crt.o
|
||||
|
||||
.bss 0x0000000080000284 0x0
|
||||
.bss 0x0000000080000284 0x0 build/src/crt.o
|
||||
|
||||
.riscv.attributes
|
||||
0x0000000000000000 0x1e
|
||||
.riscv.attributes
|
||||
0x0000000000000000 0x1e build/src/crt.o
|
|
@ -0,0 +1,3 @@
|
|||
PROJ_NAME=pmp
|
||||
|
||||
include ../common/asm.mk
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Samuel Lindemer <samuel.lindemer@ri.se>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define TEST_ID x28
|
||||
#define TRAP_RA x30
|
||||
|
||||
#define PMPCFG0 0x07120000
|
||||
#define PMPCFG0_ 0x07920808 // locked
|
||||
#define PMPCFG1 0x191f0304
|
||||
#define PMPCFG2 0x000f0506
|
||||
#define PMPCFG3 0x0f1e1900
|
||||
|
||||
#define PMPADDR0 0x20000000 // OFF
|
||||
#define PMPADDR1 0xffffffff // OFF
|
||||
#define PMPADDR2 0x20002000 // NA4 W
|
||||
#define PMPADDR3 0x20003fff // OFF RWX
|
||||
#define PMPADDR4 0x20003fff // OFF X
|
||||
#define PMPADDR5 0x20003fff // OFF RW
|
||||
#define PMPADDR6 0x20001fff // NAPOT RWX
|
||||
#define PMPADDR7 0x20005fff // NAPOT R
|
||||
#define PMPADDR8 0x2000c000 // TOR W
|
||||
#define PMPADDR9 0x2000d000 // TOR R
|
||||
#define PMPADDR10 0xffffffff // TOR RWX
|
||||
#define PMPADDR11 0x00000000 // OFF
|
||||
#define PMPADDR12 0x00000000 // OFF
|
||||
#define PMPADDR13 0x00000000 // NAPOT R
|
||||
#define PMPADDR14 0x00000000 // NAPOT WX
|
||||
#define PMPADDR15 0x00000000 // TOR RWX
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
la x1, trap
|
||||
csrw mtvec, x1
|
||||
j test0
|
||||
|
||||
.global trap
|
||||
trap:
|
||||
csrw mepc, TRAP_RA
|
||||
mret
|
||||
|
||||
// configure PMP, attempt read/write from machine mode
|
||||
test0:
|
||||
li TEST_ID, 0
|
||||
la TRAP_RA, fail
|
||||
|
||||
li x1, 0x80000000
|
||||
li x4, 0x80008000
|
||||
li x2, 0xdeadbeef
|
||||
sw x2, 0x0(x1)
|
||||
sw x2, 0x0(x4)
|
||||
lw x3, 0x0(x1)
|
||||
bne x2, x3, fail
|
||||
lw x3, 0x0(x4)
|
||||
bne x2, x3, fail
|
||||
|
||||
li x5, PMPCFG0
|
||||
csrw pmpcfg0, x5
|
||||
li x5, PMPCFG1
|
||||
csrw pmpcfg1, x5
|
||||
li x5, PMPCFG2
|
||||
csrw pmpcfg2, x5
|
||||
li x5, PMPCFG3
|
||||
csrw pmpcfg3, x5
|
||||
li x5, PMPADDR0
|
||||
csrw pmpaddr0, x5
|
||||
li x5, PMPADDR1
|
||||
csrw pmpaddr1, x5
|
||||
li x5, PMPADDR2
|
||||
csrw pmpaddr2, x5
|
||||
li x5, PMPADDR3
|
||||
csrw pmpaddr3, x5
|
||||
li x5, PMPADDR4
|
||||
csrw pmpaddr4, x5
|
||||
li x5, PMPADDR5
|
||||
csrw pmpaddr5, x5
|
||||
li x5, PMPADDR6
|
||||
csrw pmpaddr6, x5
|
||||
li x5, PMPADDR7
|
||||
csrw pmpaddr7, x5
|
||||
li x5, PMPADDR8
|
||||
csrw pmpaddr8, x5
|
||||
li x5, PMPADDR9
|
||||
csrw pmpaddr9, x5
|
||||
li x5, PMPADDR10
|
||||
csrw pmpaddr10, x5
|
||||
li x5, PMPADDR11
|
||||
csrw pmpaddr11, x5
|
||||
li x5, PMPADDR12
|
||||
csrw pmpaddr12, x5
|
||||
li x5, PMPADDR13
|
||||
csrw pmpaddr13, x5
|
||||
li x5, PMPADDR14
|
||||
csrw pmpaddr14, x5
|
||||
li x5, PMPADDR15
|
||||
csrw pmpaddr15, x5
|
||||
|
||||
li x2, 0xc0ffee
|
||||
sw x2, 0x0(x1)
|
||||
sw x2, 0x0(x4)
|
||||
lw x3, 0x0(x1)
|
||||
bne x2, x3, fail
|
||||
li x3, 0x0
|
||||
lw x3, 0x0(x4)
|
||||
bne x2, x3, fail
|
||||
|
||||
// lock region 2, attempt read/write from machine mode
|
||||
test1:
|
||||
li TEST_ID, 1
|
||||
la TRAP_RA, fail
|
||||
li x5, PMPCFG0_
|
||||
csrw pmpcfg0, x5 // lock region 2
|
||||
li x1, 0x80008000
|
||||
li x2, 0xdeadbeef
|
||||
sw x2, 0x0(x1) // should be OK (write 0x80008000)
|
||||
la TRAP_RA, test2
|
||||
lw x3, 0x0(x1) // should fault (read 0x80008000)
|
||||
j fail
|
||||
|
||||
// "unlock" region 2, attempt read/write from machine mode
|
||||
test2:
|
||||
li TEST_ID, 2
|
||||
la TRAP_RA, fail
|
||||
li x5, PMPCFG0
|
||||
csrw pmpcfg0, x5 // "unlock" region 2
|
||||
li x1, 0x80008000
|
||||
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)
|
||||
j fail
|
||||
|
||||
// jump into user mode
|
||||
test3:
|
||||
li TEST_ID, 3
|
||||
la TRAP_RA, fail
|
||||
la x2, test4
|
||||
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
|
||||
test5:
|
||||
li TEST_ID, 5
|
||||
li x2, 0xdeadbeef
|
||||
li x1, 0x80000000
|
||||
sw x2, 0x0(x1)
|
||||
lw x3, 0x0(x1)
|
||||
bne x2, x3, fail // should be OK (read/write 0x80000000)
|
||||
|
||||
test6:
|
||||
li TEST_ID, 6
|
||||
li 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 x2, 0xdeadbeef
|
||||
li x1, 0x8002fff8
|
||||
sw x2, 0x0(x4) // should be OK (write 0x8002fff8)
|
||||
la TRAP_RA, test5
|
||||
lw x3, 0x0(x4) // should fault (read 0x8002fff8)
|
||||
j fail
|
||||
|
||||
test8:
|
||||
li TEST_ID, 8
|
||||
li x1, 0x8003fff8
|
||||
lw x3, 0x0(x1) // should be OK (read 0x8003fff8)
|
||||
la TRAP_RA, pass
|
||||
sw x3, 0x0(x1) // should fault (write 0x8003fff8)
|
||||
j fail
|
||||
|
||||
fail:
|
||||
li x2, 0xf00fff24
|
||||
sw TEST_ID, 0(x2)
|
||||
|
||||
pass:
|
||||
li x2, 0xf00fff20
|
||||
sw x0, 0(x2)
|
|
@ -0,0 +1,16 @@
|
|||
OUTPUT_ARCH( "riscv" )
|
||||
|
||||
MEMORY {
|
||||
onChipRam (W!RX)/*(RX)*/ : ORIGIN = 0x80000000, LENGTH = 128K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.crt_section :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*crt.o(.text)
|
||||
} > onChipRam
|
||||
|
||||
}
|
|
@ -3870,6 +3870,10 @@ int main(int argc, char **argv, char **env) {
|
|||
redo(REDO,WorkspaceRegression("lrsc").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/lrsc/build/lrsc.hex")->bootAt(0x00000000u)->run(10e3););
|
||||
#endif
|
||||
|
||||
#ifdef PMP
|
||||
redo(REDO,WorkspaceRegression("pmp").loadHex(string(REGRESSION_PATH) + "../raw/pmp/build/pmp.hex")->bootAt(0x80000000u)->run(10e3););
|
||||
#endif
|
||||
|
||||
#ifdef AMO
|
||||
redo(REDO,WorkspaceRegression("amo").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/amo/build/amo.hex")->bootAt(0x00000000u)->run(10e3););
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,7 @@ CSR_SKIP_TEST?=no
|
|||
EBREAK?=no
|
||||
FENCEI?=no
|
||||
MMU?=yes
|
||||
PMP?=no
|
||||
SEED?=no
|
||||
LRSC?=no
|
||||
AMO?=no
|
||||
|
@ -217,6 +218,10 @@ ifeq ($(MMU),yes)
|
|||
ADDCFLAGS += -CFLAGS -DMMU
|
||||
endif
|
||||
|
||||
ifeq ($(PMP),yes)
|
||||
ADDCFLAGS += -CFLAGS -DPMP
|
||||
endif
|
||||
|
||||
ifeq ($(MUL),yes)
|
||||
ADDCFLAGS += -CFLAGS -DMUL
|
||||
endif
|
||||
|
|
|
@ -46,8 +46,10 @@ abstract class VexRiscvPosition(name: String) extends ConfigPosition[VexRiscvCo
|
|||
class VexRiscvUniverse extends ConfigUniverse
|
||||
|
||||
object VexRiscvUniverse{
|
||||
val CACHE_ALL = new VexRiscvUniverse
|
||||
val CATCH_ALL = new VexRiscvUniverse
|
||||
val MMU = new VexRiscvUniverse
|
||||
val PMP = new VexRiscvUniverse
|
||||
val FORCE_MULDIV = new VexRiscvUniverse
|
||||
val SUPERVISOR = new VexRiscvUniverse
|
||||
val NO_WRITEBACK = new VexRiscvUniverse
|
||||
|
@ -321,9 +323,10 @@ class IBusDimension(rvcRate : Double) extends VexRiscvDimension("IBus") {
|
|||
|
||||
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
|
||||
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL)
|
||||
val cacheAll = universes.contains(VexRiscvUniverse.CACHE_ALL)
|
||||
val mmuConfig = if(universes.contains(VexRiscvUniverse.MMU)) MmuPortConfig( portTlbSize = 4) else null
|
||||
|
||||
if(r.nextDouble() < 0.5){
|
||||
if(r.nextDouble() < 0.5 && !cacheAll){
|
||||
val latency = r.nextInt(5) + 1
|
||||
val compressed = r.nextDouble() < rvcRate
|
||||
val injectorStage = r.nextBoolean() || latency == 1
|
||||
|
@ -402,13 +405,14 @@ class DBusDimension extends VexRiscvDimension("DBus") {
|
|||
|
||||
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
|
||||
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL)
|
||||
val cacheAll = universes.contains(VexRiscvUniverse.CACHE_ALL)
|
||||
val mmuConfig = if(universes.contains(VexRiscvUniverse.MMU)) MmuPortConfig( portTlbSize = 4) else null
|
||||
val noMemory = universes.contains(VexRiscvUniverse.NO_MEMORY)
|
||||
val noWriteBack = universes.contains(VexRiscvUniverse.NO_WRITEBACK)
|
||||
|
||||
|
||||
|
||||
if(r.nextDouble() < 0.4 || noMemory){
|
||||
if((r.nextDouble() < 0.4 || noMemory) && !cacheAll){
|
||||
val withLrSc = catchAll
|
||||
val earlyInjection = r.nextBoolean() && !universes.contains(VexRiscvUniverse.NO_WRITEBACK)
|
||||
new VexRiscvPosition("Simple" + (if(earlyInjection) "Early" else "Late")) {
|
||||
|
@ -468,12 +472,12 @@ class DBusDimension extends VexRiscvDimension("DBus") {
|
|||
}
|
||||
|
||||
|
||||
class MmuDimension extends VexRiscvDimension("DBus") {
|
||||
class MmuPmpDimension extends VexRiscvDimension("DBus") {
|
||||
|
||||
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
|
||||
if(universes.contains(VexRiscvUniverse.MMU)) {
|
||||
new VexRiscvPosition("WithMmu") {
|
||||
override def testParam = "MMU=yes"
|
||||
override def testParam = "MMU=yes PMP=no"
|
||||
|
||||
override def applyOn(config: VexRiscvConfig): Unit = {
|
||||
config.plugins += new MmuPlugin(
|
||||
|
@ -481,9 +485,20 @@ class MmuDimension extends VexRiscvDimension("DBus") {
|
|||
)
|
||||
}
|
||||
}
|
||||
} else if (universes.contains(VexRiscvUniverse.PMP)) {
|
||||
new VexRiscvPosition("WithPmp") {
|
||||
override def testParam = "MMU=no PMP=yes"
|
||||
|
||||
override def applyOn(config: VexRiscvConfig): Unit = {
|
||||
config.plugins += new PmpPlugin(
|
||||
regions = 16,
|
||||
ioRange = _ (31 downto 28) === 0xF
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
new VexRiscvPosition("NoMmu") {
|
||||
override def testParam = "MMU=no"
|
||||
new VexRiscvPosition("NoMemProtect") {
|
||||
override def testParam = "MMU=no PMP=no"
|
||||
|
||||
override def applyOn(config: VexRiscvConfig): Unit = {
|
||||
config.plugins += new StaticMemoryTranslatorPlugin(
|
||||
|
@ -502,6 +517,7 @@ trait CatchAllPosition
|
|||
|
||||
class CsrDimension(freertos : String, zephyr : String, linux : String) extends VexRiscvDimension("Csr") {
|
||||
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
|
||||
val pmp = universes.contains(VexRiscvUniverse.PMP)
|
||||
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL)
|
||||
val supervisor = universes.contains(VexRiscvUniverse.SUPERVISOR)
|
||||
if(supervisor){
|
||||
|
@ -509,10 +525,15 @@ class CsrDimension(freertos : String, zephyr : String, linux : String) extends V
|
|||
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.linuxFull(0x80000020l))
|
||||
override def testParam = s"FREERTOS=$freertos ZEPHYR=$zephyr LINUX_REGRESSION=$linux SUPERVISOR=yes"
|
||||
}
|
||||
} else if(pmp){
|
||||
new VexRiscvPosition("Secure") with CatchAllPosition{
|
||||
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.secure(0x80000020l))
|
||||
override def testParam = s"CSR=yes CSR_SKIP_TEST=yes FREERTOS=$freertos ZEPHYR=$zephyr"
|
||||
}
|
||||
} else if(catchAll){
|
||||
new VexRiscvPosition("MachineOs") with CatchAllPosition{
|
||||
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.all(0x80000020l))
|
||||
override def testParam = s"CSR=yes FREERTOS=$freertos ZEPHYR=$zephyr"
|
||||
override def testParam = s"CSR=yes CSR_SKIP_TEST=yes FREERTOS=$freertos ZEPHYR=$zephyr"
|
||||
}
|
||||
} else if(r.nextDouble() < 0.3){
|
||||
new VexRiscvPosition("AllNoException") with CatchAllPosition{
|
||||
|
@ -640,6 +661,7 @@ class TestIndividualFeatures extends MultithreadedFunSuite {
|
|||
val rvcRate = sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_RVC_RATE", "0.5").toDouble
|
||||
val linuxRate = sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_LINUX_RATE", "0.3").toDouble
|
||||
val machineOsRate = sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE", "0.5").toDouble
|
||||
val secureRate = sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_SECURE_RATE", "0.5").toDouble
|
||||
val linuxRegression = sys.env.getOrElse("VEXRISCV_REGRESSION_LINUX_REGRESSION", "yes")
|
||||
val coremarkRegression = sys.env.getOrElse("VEXRISCV_REGRESSION_COREMARK", "yes")
|
||||
val zephyrCount = sys.env.getOrElse("VEXRISCV_REGRESSION_ZEPHYR_COUNT", "4")
|
||||
|
@ -661,7 +683,7 @@ class TestIndividualFeatures extends MultithreadedFunSuite {
|
|||
new CsrDimension(/*sys.env.getOrElse("VEXRISCV_REGRESSION_FREERTOS_COUNT", "1")*/ "0", zephyrCount, linuxRegression), //Freertos old port software is broken
|
||||
new DecoderDimension,
|
||||
new DebugDimension,
|
||||
new MmuDimension
|
||||
new MmuPmpDimension
|
||||
)
|
||||
|
||||
var clockCounter = 0l
|
||||
|
@ -746,6 +768,13 @@ class TestIndividualFeatures extends MultithreadedFunSuite {
|
|||
if(demwRate < rand.nextDouble()){
|
||||
universe += VexRiscvUniverse.NO_WRITEBACK
|
||||
}
|
||||
} else if (secureRate > rand.nextDouble()) {
|
||||
universe += VexRiscvUniverse.CACHE_ALL
|
||||
universe += VexRiscvUniverse.CATCH_ALL
|
||||
universe += VexRiscvUniverse.PMP
|
||||
if(demwRate < rand.nextDouble()){
|
||||
universe += VexRiscvUniverse.NO_WRITEBACK
|
||||
}
|
||||
} else {
|
||||
if(machineOsRate > rand.nextDouble()) {
|
||||
universe += VexRiscvUniverse.CATCH_ALL
|
||||
|
@ -776,4 +805,4 @@ class TestIndividualFeatures extends MultithreadedFunSuite {
|
|||
val clockPerSecond = (clockCounter/time*1e-3).toLong
|
||||
println(s"Duration=${(time/60).toInt}mn clocks=${(clockCounter*1e-6).toLong}M clockPerSecond=${clockPerSecond}K")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue