1
0
Fork 0

Allow reset vector to be set dynamically

A chip's power-up sequence, or awake-from-sleep sequence, may wish to
set the reset PC based upon dynamic properties, e.g., the settings of
external pins.  Support this by passing the reset vector to the Coreplex.
ExampleTop simply hard-wires the reset vector, as was the case before.

Additionally, allow MTVEC to *not* be reset.  In most cases, including
riscv-tests, pk, and bbl, overriding MTVEC is one of the first things
that the boot sequence does.  So the reset value is superfluous.
This commit is contained in:
Andrew Waterman 2016-09-19 16:45:57 -07:00
parent e6c1bcfedd
commit d0572d6aab
9 changed files with 27 additions and 17 deletions

View File

@ -131,8 +131,7 @@ class BaseCoreplexConfig extends Config (
case UseCompressed => true
case DMKey => new DefaultDebugModuleConfig(site(NTiles), site(XLen))
case NCustomMRWCSRs => 0
case ResetVector => BigInt(0x1000)
case MtvecInit => BigInt(0x1010)
case MtvecInit => None
case MtvecWritable => true
//Uncore Paramters
case LNEndpoints => site(TLKey(site(TLId))).nManagers + site(TLKey(site(TLId))).nClients

View File

@ -58,6 +58,7 @@ abstract class Coreplex(implicit val p: Parameters, implicit val c: CoreplexConf
val debug = new DebugBusIO()(p).flip
val clint = Vec(c.nTiles, new CoreplexLocalInterrupts).asInput
val success: Option[Bool] = hasSuccessFlag.option(Bool(OUTPUT))
val resetVector = UInt(INPUT, p(XLen))
}
def hasSuccessFlag: Boolean = false
@ -153,6 +154,7 @@ class DefaultCoreplex(tp: Parameters, tc: CoreplexConfig) extends Coreplex()(tp,
tile.io.interrupts.seip.foreach(_ := plic.io.harts(plic.cfg.context(i, 'S')))
tile.io.interrupts.debug := debugModule.io.debugInterrupts(i)
tile.io.hartid := i
tile.io.resetVector := io.resetVector
}
val tileSlavePorts = (0 until tc.nTiles) map (i => s"int:dmem$i") filter (ioAddrMap contains _)

View File

@ -227,7 +227,11 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
val reg_mcause = Reg(Bits(width = xLen))
val reg_mbadaddr = Reg(UInt(width = vaddrBitsExtended))
val reg_mscratch = Reg(Bits(width = xLen))
val reg_mtvec = Reg(init=UInt(p(MtvecInit), paddrBits min xLen))
val mtvecWidth = paddrBits min xLen
val reg_mtvec = p(MtvecInit) match {
case Some(addr) => Reg(init=UInt(addr, mtvecWidth))
case None => Reg(UInt(width = mtvecWidth))
}
val reg_mucounteren = Reg(UInt(width = 32))
val reg_mscounteren = Reg(UInt(width = 32))
val delegable_counters = (BigInt(1) << (nPerfCounters + CSR.firstHPM)) - 1

View File

@ -35,6 +35,7 @@ class Frontend(implicit p: Parameters) extends CoreModule()(p) with HasL1CachePa
val cpu = new FrontendIO().flip
val ptw = new TLBPTWIO()
val mem = new ClientUncachedTileLinkIO
val resetVector = UInt(INPUT, vaddrBitsExtended)
}
val icache = Module(new ICache(latency = 2))
@ -45,7 +46,7 @@ class Frontend(implicit p: Parameters) extends CoreModule()(p) with HasL1CachePa
val s1_speculative = Reg(Bool())
val s1_same_block = Reg(Bool())
val s2_valid = Reg(init=Bool(true))
val s2_pc = Reg(init=UInt(p(ResetVector)))
val s2_pc = Reg(init=io.resetVector)
val s2_btb_resp_valid = Reg(init=Bool(false))
val s2_btb_resp_bits = Reg(new BTBResp)
val s2_xcpt_if = Reg(init=Bool(false))

View File

@ -27,8 +27,7 @@ case object FastJAL extends Field[Boolean]
case object CoreInstBits extends Field[Int]
case object NCustomMRWCSRs extends Field[Int]
case object MtvecWritable extends Field[Boolean]
case object MtvecInit extends Field[BigInt]
case object ResetVector extends Field[BigInt]
case object MtvecInit extends Field[Option[BigInt]]
case object NBreakpoints extends Field[Int]
case object NPerfCounters extends Field[Int]
case object NPerfEvents extends Field[Int]

View File

@ -34,6 +34,7 @@ abstract class Tile(clockSignal: Clock = null, resetSignal: Bool = null)
val hartid = UInt(INPUT, p(XLen))
val interrupts = new TileInterrupts().asInput
val slave = (p(DataScratchpadSize) > 0).option(new ClientUncachedTileLinkIO().flip)
val resetVector = UInt(INPUT, p(XLen))
}
val io = new TileIO
@ -58,6 +59,7 @@ class RocketTile(clockSignal: Clock = null, resetSignal: Bool = null)
core.io.interrupts := io.interrupts
core.io.hartid := io.hartid
icache.io.cpu <> core.io.imem
icache.io.resetVector := io.resetVector
val fpuOpt = p(FPUKey).map(cfg => Module(new FPU(cfg)))
fpuOpt.foreach(fpu => core.io.fpu <> fpu.io)

View File

@ -311,7 +311,9 @@ trait PeripheryBootROM extends LazyModule {
implicit val p: Parameters
val peripheryBus: TLXbar
val rom = LazyModule(new TLROM(0x1000, 0x1000, GenerateBootROM(p)) { override def name = "bootrom" })
val address = 0x1000
val size = 0x1000
val rom = LazyModule(new TLROM(address, size, GenerateBootROM(p, address)) { override def name = "bootrom" })
rom.node := TLFragmenter(peripheryBus.node, 4, 256)
}
@ -365,3 +367,10 @@ trait PeripheryTestBusMasterModule {
implicit val p: Parameters
val outer: PeripheryTestBusMaster
}
/////
trait HardwiredResetVector {
val coreplex: Coreplex
coreplex.io.resetVector := UInt(0x1000) // boot ROM
}

View File

@ -103,6 +103,7 @@ class ExampleTopBundle(p: Parameters, c: Coreplex) extends BaseTopBundle(p, c)
class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle](p: Parameters, l: L, b: Coreplex => B) extends BaseTopModule(p, l, b)
with PeripheryBootROMModule with PeripheryDebugModule with PeripheryExtInterruptsModule with PeripheryCoreplexLocalInterrupterModule
with PeripheryMasterMemModule with PeripheryMasterMMIOModule with PeripherySlaveModule
with HardwiredResetVector
/** Example Top with TestRAM */
class ExampleTopWithTestRAM(q: Parameters) extends ExampleTop(q)

View File

@ -168,21 +168,14 @@ object GenerateConfigString {
}
object GenerateBootROM {
def apply(p: Parameters) = {
def apply(p: Parameters, address: BigInt) = {
val romdata = Files.readAllBytes(Paths.get(p(BootROMFile)))
val rom = ByteBuffer.wrap(romdata)
rom.order(ByteOrder.LITTLE_ENDIAN)
// for now, have the reset vector jump straight to memory
val memBase = (
if (p(GlobalAddrMap) contains "mem") p(GlobalAddrMap)("mem")
else p(GlobalAddrMap)("io:int:dmem0")
).start
val resetToMemDist = memBase - p(ResetVector)
require(resetToMemDist == (resetToMemDist.toInt >> 12 << 12))
val configStringAddr = p(ResetVector).toInt + rom.capacity
require(address == address.toInt)
val configStringAddr = address.toInt + rom.capacity
require(rom.getInt(12) == 0,
"Config string address position should not be occupied by code")
rom.putInt(12, configStringAddr)