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:
parent
e6c1bcfedd
commit
d0572d6aab
@ -131,8 +131,7 @@ class BaseCoreplexConfig extends Config (
|
|||||||
case UseCompressed => true
|
case UseCompressed => true
|
||||||
case DMKey => new DefaultDebugModuleConfig(site(NTiles), site(XLen))
|
case DMKey => new DefaultDebugModuleConfig(site(NTiles), site(XLen))
|
||||||
case NCustomMRWCSRs => 0
|
case NCustomMRWCSRs => 0
|
||||||
case ResetVector => BigInt(0x1000)
|
case MtvecInit => None
|
||||||
case MtvecInit => BigInt(0x1010)
|
|
||||||
case MtvecWritable => true
|
case MtvecWritable => true
|
||||||
//Uncore Paramters
|
//Uncore Paramters
|
||||||
case LNEndpoints => site(TLKey(site(TLId))).nManagers + site(TLKey(site(TLId))).nClients
|
case LNEndpoints => site(TLKey(site(TLId))).nManagers + site(TLKey(site(TLId))).nClients
|
||||||
|
@ -58,6 +58,7 @@ abstract class Coreplex(implicit val p: Parameters, implicit val c: CoreplexConf
|
|||||||
val debug = new DebugBusIO()(p).flip
|
val debug = new DebugBusIO()(p).flip
|
||||||
val clint = Vec(c.nTiles, new CoreplexLocalInterrupts).asInput
|
val clint = Vec(c.nTiles, new CoreplexLocalInterrupts).asInput
|
||||||
val success: Option[Bool] = hasSuccessFlag.option(Bool(OUTPUT))
|
val success: Option[Bool] = hasSuccessFlag.option(Bool(OUTPUT))
|
||||||
|
val resetVector = UInt(INPUT, p(XLen))
|
||||||
}
|
}
|
||||||
|
|
||||||
def hasSuccessFlag: Boolean = false
|
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.seip.foreach(_ := plic.io.harts(plic.cfg.context(i, 'S')))
|
||||||
tile.io.interrupts.debug := debugModule.io.debugInterrupts(i)
|
tile.io.interrupts.debug := debugModule.io.debugInterrupts(i)
|
||||||
tile.io.hartid := 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 _)
|
val tileSlavePorts = (0 until tc.nTiles) map (i => s"int:dmem$i") filter (ioAddrMap contains _)
|
||||||
|
@ -227,7 +227,11 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
val reg_mcause = Reg(Bits(width = xLen))
|
val reg_mcause = Reg(Bits(width = xLen))
|
||||||
val reg_mbadaddr = Reg(UInt(width = vaddrBitsExtended))
|
val reg_mbadaddr = Reg(UInt(width = vaddrBitsExtended))
|
||||||
val reg_mscratch = Reg(Bits(width = xLen))
|
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_mucounteren = Reg(UInt(width = 32))
|
||||||
val reg_mscounteren = Reg(UInt(width = 32))
|
val reg_mscounteren = Reg(UInt(width = 32))
|
||||||
val delegable_counters = (BigInt(1) << (nPerfCounters + CSR.firstHPM)) - 1
|
val delegable_counters = (BigInt(1) << (nPerfCounters + CSR.firstHPM)) - 1
|
||||||
|
@ -35,6 +35,7 @@ class Frontend(implicit p: Parameters) extends CoreModule()(p) with HasL1CachePa
|
|||||||
val cpu = new FrontendIO().flip
|
val cpu = new FrontendIO().flip
|
||||||
val ptw = new TLBPTWIO()
|
val ptw = new TLBPTWIO()
|
||||||
val mem = new ClientUncachedTileLinkIO
|
val mem = new ClientUncachedTileLinkIO
|
||||||
|
val resetVector = UInt(INPUT, vaddrBitsExtended)
|
||||||
}
|
}
|
||||||
|
|
||||||
val icache = Module(new ICache(latency = 2))
|
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_speculative = Reg(Bool())
|
||||||
val s1_same_block = Reg(Bool())
|
val s1_same_block = Reg(Bool())
|
||||||
val s2_valid = Reg(init=Bool(true))
|
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_valid = Reg(init=Bool(false))
|
||||||
val s2_btb_resp_bits = Reg(new BTBResp)
|
val s2_btb_resp_bits = Reg(new BTBResp)
|
||||||
val s2_xcpt_if = Reg(init=Bool(false))
|
val s2_xcpt_if = Reg(init=Bool(false))
|
||||||
|
@ -27,8 +27,7 @@ case object FastJAL extends Field[Boolean]
|
|||||||
case object CoreInstBits extends Field[Int]
|
case object CoreInstBits extends Field[Int]
|
||||||
case object NCustomMRWCSRs extends Field[Int]
|
case object NCustomMRWCSRs extends Field[Int]
|
||||||
case object MtvecWritable extends Field[Boolean]
|
case object MtvecWritable extends Field[Boolean]
|
||||||
case object MtvecInit extends Field[BigInt]
|
case object MtvecInit extends Field[Option[BigInt]]
|
||||||
case object ResetVector extends Field[BigInt]
|
|
||||||
case object NBreakpoints extends Field[Int]
|
case object NBreakpoints extends Field[Int]
|
||||||
case object NPerfCounters extends Field[Int]
|
case object NPerfCounters extends Field[Int]
|
||||||
case object NPerfEvents extends Field[Int]
|
case object NPerfEvents extends Field[Int]
|
||||||
|
@ -34,6 +34,7 @@ abstract class Tile(clockSignal: Clock = null, resetSignal: Bool = null)
|
|||||||
val hartid = UInt(INPUT, p(XLen))
|
val hartid = UInt(INPUT, p(XLen))
|
||||||
val interrupts = new TileInterrupts().asInput
|
val interrupts = new TileInterrupts().asInput
|
||||||
val slave = (p(DataScratchpadSize) > 0).option(new ClientUncachedTileLinkIO().flip)
|
val slave = (p(DataScratchpadSize) > 0).option(new ClientUncachedTileLinkIO().flip)
|
||||||
|
val resetVector = UInt(INPUT, p(XLen))
|
||||||
}
|
}
|
||||||
|
|
||||||
val io = new TileIO
|
val io = new TileIO
|
||||||
@ -58,6 +59,7 @@ class RocketTile(clockSignal: Clock = null, resetSignal: Bool = null)
|
|||||||
core.io.interrupts := io.interrupts
|
core.io.interrupts := io.interrupts
|
||||||
core.io.hartid := io.hartid
|
core.io.hartid := io.hartid
|
||||||
icache.io.cpu <> core.io.imem
|
icache.io.cpu <> core.io.imem
|
||||||
|
icache.io.resetVector := io.resetVector
|
||||||
|
|
||||||
val fpuOpt = p(FPUKey).map(cfg => Module(new FPU(cfg)))
|
val fpuOpt = p(FPUKey).map(cfg => Module(new FPU(cfg)))
|
||||||
fpuOpt.foreach(fpu => core.io.fpu <> fpu.io)
|
fpuOpt.foreach(fpu => core.io.fpu <> fpu.io)
|
||||||
|
@ -311,7 +311,9 @@ trait PeripheryBootROM extends LazyModule {
|
|||||||
implicit val p: Parameters
|
implicit val p: Parameters
|
||||||
val peripheryBus: TLXbar
|
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)
|
rom.node := TLFragmenter(peripheryBus.node, 4, 256)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,3 +367,10 @@ trait PeripheryTestBusMasterModule {
|
|||||||
implicit val p: Parameters
|
implicit val p: Parameters
|
||||||
val outer: PeripheryTestBusMaster
|
val outer: PeripheryTestBusMaster
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////
|
||||||
|
|
||||||
|
trait HardwiredResetVector {
|
||||||
|
val coreplex: Coreplex
|
||||||
|
coreplex.io.resetVector := UInt(0x1000) // boot ROM
|
||||||
|
}
|
||||||
|
@ -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)
|
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 PeripheryBootROMModule with PeripheryDebugModule with PeripheryExtInterruptsModule with PeripheryCoreplexLocalInterrupterModule
|
||||||
with PeripheryMasterMemModule with PeripheryMasterMMIOModule with PeripherySlaveModule
|
with PeripheryMasterMemModule with PeripheryMasterMMIOModule with PeripherySlaveModule
|
||||||
|
with HardwiredResetVector
|
||||||
|
|
||||||
/** Example Top with TestRAM */
|
/** Example Top with TestRAM */
|
||||||
class ExampleTopWithTestRAM(q: Parameters) extends ExampleTop(q)
|
class ExampleTopWithTestRAM(q: Parameters) extends ExampleTop(q)
|
||||||
|
@ -168,21 +168,14 @@ object GenerateConfigString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object GenerateBootROM {
|
object GenerateBootROM {
|
||||||
def apply(p: Parameters) = {
|
def apply(p: Parameters, address: BigInt) = {
|
||||||
val romdata = Files.readAllBytes(Paths.get(p(BootROMFile)))
|
val romdata = Files.readAllBytes(Paths.get(p(BootROMFile)))
|
||||||
val rom = ByteBuffer.wrap(romdata)
|
val rom = ByteBuffer.wrap(romdata)
|
||||||
|
|
||||||
rom.order(ByteOrder.LITTLE_ENDIAN)
|
rom.order(ByteOrder.LITTLE_ENDIAN)
|
||||||
|
|
||||||
// for now, have the reset vector jump straight to memory
|
require(address == address.toInt)
|
||||||
val memBase = (
|
val configStringAddr = address.toInt + rom.capacity
|
||||||
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(rom.getInt(12) == 0,
|
require(rom.getInt(12) == 0,
|
||||||
"Config string address position should not be occupied by code")
|
"Config string address position should not be occupied by code")
|
||||||
rom.putInt(12, configStringAddr)
|
rom.putInt(12, configStringAddr)
|
||||||
|
Loading…
Reference in New Issue
Block a user