From d0572d6aabedaab924d5282df8e98a44eb85be38 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 19 Sep 2016 16:45:57 -0700 Subject: [PATCH 1/2] 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. --- src/main/scala/coreplex/Configs.scala | 3 +-- src/main/scala/coreplex/Coreplex.scala | 2 ++ src/main/scala/rocket/csr.scala | 6 +++++- src/main/scala/rocket/frontend.scala | 3 ++- src/main/scala/rocket/rocket.scala | 3 +-- src/main/scala/rocket/tile.scala | 2 ++ src/main/scala/rocketchip/Periphery.scala | 11 ++++++++++- src/main/scala/rocketchip/Top.scala | 1 + src/main/scala/rocketchip/Utils.scala | 13 +++---------- 9 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 2e124a9c..c75ae487 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -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 diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index fe1d5bf0..341f4977 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -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 _) diff --git a/src/main/scala/rocket/csr.scala b/src/main/scala/rocket/csr.scala index 8b3ecff0..e542d233 100644 --- a/src/main/scala/rocket/csr.scala +++ b/src/main/scala/rocket/csr.scala @@ -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 diff --git a/src/main/scala/rocket/frontend.scala b/src/main/scala/rocket/frontend.scala index 25c47b80..7fdc37a5 100644 --- a/src/main/scala/rocket/frontend.scala +++ b/src/main/scala/rocket/frontend.scala @@ -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)) diff --git a/src/main/scala/rocket/rocket.scala b/src/main/scala/rocket/rocket.scala index 61b013b2..4939412d 100644 --- a/src/main/scala/rocket/rocket.scala +++ b/src/main/scala/rocket/rocket.scala @@ -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] diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index 1a868fa8..9280bae2 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -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) diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index c69ef131..f7d6d5bb 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -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 +} diff --git a/src/main/scala/rocketchip/Top.scala b/src/main/scala/rocketchip/Top.scala index ef4a98b4..dc36acb3 100644 --- a/src/main/scala/rocketchip/Top.scala +++ b/src/main/scala/rocketchip/Top.scala @@ -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) diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index 1436050a..387e23bb 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -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) From 3b38736a8e9a45be7ccd5a43c24cd958c16bc575 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 19 Sep 2016 16:50:04 -0700 Subject: [PATCH 2/2] Make BaseTopModule and BaseTopModule abstract They aren't meant to be directly instantiated. --- src/main/scala/rocketchip/Top.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/rocketchip/Top.scala b/src/main/scala/rocketchip/Top.scala index dc36acb3..8dc579aa 100644 --- a/src/main/scala/rocketchip/Top.scala +++ b/src/main/scala/rocketchip/Top.scala @@ -53,11 +53,11 @@ abstract class BaseTop(q: Parameters) extends LazyModule { peripheryBus.node := TLBuffer(TLWidthWidget(TLHintHandler(legacy.node), legacy.tlDataBytes)) } -class BaseTopBundle(val p: Parameters, val c: Coreplex) extends ParameterizedBundle()(p) { +abstract class BaseTopBundle(val p: Parameters, val c: Coreplex) extends ParameterizedBundle()(p) { val success = c.hasSuccessFlag.option(Bool(OUTPUT)) } -class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle](val p: Parameters, l: L, b: Coreplex => B) extends LazyModuleImp(l) { +abstract class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle](val p: Parameters, l: L, b: Coreplex => B) extends LazyModuleImp(l) { val outer: L = l val coreplex = p(BuildCoreplex)(p, outer.c)