Merge pull request #316 from ucb-bar/dynamic-reset-vector
Allow reset vector to be set dynamically
This commit is contained in:
commit
15e7041ccb
@ -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
|
||||||
|
}
|
||||||
|
@ -53,11 +53,11 @@ abstract class BaseTop(q: Parameters) extends LazyModule {
|
|||||||
peripheryBus.node := TLBuffer(TLWidthWidget(TLHintHandler(legacy.node), legacy.tlDataBytes))
|
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))
|
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 outer: L = l
|
||||||
|
|
||||||
val coreplex = p(BuildCoreplex)(p, outer.c)
|
val coreplex = p(BuildCoreplex)(p, outer.c)
|
||||||
@ -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