1
0

Merge pull request #609 from ucb-bar/dtb-rom

DTB in the bootrom
This commit is contained in:
Wesley W. Terpstra 2017-03-24 21:54:13 -07:00 committed by GitHub
commit 19485a9861
11 changed files with 63 additions and 35 deletions

View File

@ -30,6 +30,7 @@ addons:
- bison - bison
- flex - flex
- texinfo - texinfo
- device-tree-compiler
env: env:
matrix: matrix:

View File

@ -5,8 +5,11 @@ OBJCOPY=riscv64-unknown-elf-objcopy
all: $(bootrom_img) all: $(bootrom_img)
%.img: %.elf %.img: %.bin
$(OBJCOPY) -O binary --change-addresses=-0x1000 --only-section .text $< $@ dd if=$< of=$@ bs=128 count=1
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
%.elf: %.S linker.ld %.elf: %.S linker.ld
$(GCC) -Tlinker.ld $< -nostdlib -static -o $@ $(GCC) -Tlinker.ld $< -nostdlib -static -Wl,--no-gc-sections -o $@

View File

@ -1,13 +1,19 @@
.text .section .text.start, "ax", @progbits
.global _start .globl _start
_start: _start:
// This boot ROM doesn't know about any boot devices, so it just spins, la s0, DRAM_BASE
// waiting for the debugger to load a program and change the PC. csrr a0, mhartid
j _start // reset vector la a1, _dtb
.word 0 // reserved jr s0
.word 0 // reserved
.word 0 // pointer to config string .section .text.hang, "ax", @progbits
.word 0 // default trap vector .globl _hang
.word 0 _hang:
.word 0 wfi
.word 0 j _hang
.section .rodata.dtb, "a", @progbits
.globl _dtb
.align 5, 0
_dtb:
.ascii "DTB goes here"

BIN
bootrom/bootrom.img Executable file → Normal file

Binary file not shown.

View File

@ -1,5 +1,12 @@
SECTIONS SECTIONS
{ {
. = 0x1000; DRAM_BASE = 0x80000000;
.text : { *(.text) } ROM_BASE = 0x10000;
. = ROM_BASE;
.text.start : { *(.text.start) }
. = ROM_BASE + 0x40;
.text.hang : { *(.text.hang) }
. = ROM_BASE + 0x80;
.rodata.dtb : { *(.rodata.dtb) }
} }

View File

@ -25,6 +25,7 @@ trait CoreplexRISCVPlatform extends CoreplexNetwork {
plic.intnode := intBar.intnode plic.intnode := intBar.intnode
lazy val dts = DTS(bindingTree) lazy val dts = DTS(bindingTree)
lazy val dtb = DTB(dts)
lazy val json = JSON(bindingTree) lazy val json = JSON(bindingTree)
} }

View File

@ -4,6 +4,8 @@ package diplomacy
import Chisel._ import Chisel._
import config._ import config._
import sys.process._
import java.io.{ByteArrayInputStream, ByteArrayOutputStream}
case object DTSModel extends Field[String] case object DTSModel extends Field[String]
case object DTSCompat extends Field[Seq[String]] // -dev, -soc case object DTSCompat extends Field[Seq[String]] // -dev, -soc
@ -115,3 +117,17 @@ object DTS
case x: ResourceMap => fmtMap(x, indent, cells) case x: ResourceMap => fmtMap(x, indent, cells)
} }
} }
case class DTB(contents: Seq[Byte])
object DTB
{
def apply(dts: String): DTB = {
val instream = new ByteArrayInputStream(dts.getBytes("UTF-8"))
val outstream = new ByteArrayOutputStream
val proc = "dtc -O dtb" #< instream #> outstream
require (proc.! == 0, "Failed to run dtc; is it in your path?")
instream.close
outstream.close
DTB(outstream.toByteArray)
}
}

View File

@ -305,9 +305,9 @@ trait PeripheryBootROM {
this: HasTopLevelNetworks => this: HasTopLevelNetworks =>
val coreplex: CoreplexRISCVPlatform val coreplex: CoreplexRISCVPlatform
private val bootrom_address = 0x1000 private val bootrom_address = 0x10000
private val bootrom_size = 0x1000 private val bootrom_size = 0x10000
private lazy val bootrom_contents = GenerateBootROM(p, bootrom_address, coreplex.dts) private lazy val bootrom_contents = GenerateBootROM(coreplex.dtb)
val bootrom = LazyModule(new TLROM(bootrom_address, bootrom_size, bootrom_contents, true, peripheryBusConfig.beatBytes)) val bootrom = LazyModule(new TLROM(bootrom_address, bootrom_size, bootrom_contents, true, peripheryBusConfig.beatBytes))
bootrom.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) bootrom.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
} }

View File

@ -124,5 +124,5 @@ trait HardwiredResetVectorModule extends HasTopLevelNetworksModule {
val outer: HardwiredResetVector val outer: HardwiredResetVector
val io: HardwiredResetVectorBundle val io: HardwiredResetVectorBundle
outer.coreplex.module.io.resetVector := UInt(0x1000) // boot ROM outer.coreplex.module.io.resetVector := UInt(0x10040) // boot ROM: hang
} }

View File

@ -53,17 +53,9 @@ class GlobalVariable[T] {
} }
object GenerateBootROM { object GenerateBootROM {
def apply(p: Parameters, address: BigInt, dts: String) = { def apply(dtb: DTB)(implicit p: Parameters) = {
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.array() ++ dtb.contents
rom.order(ByteOrder.LITTLE_ENDIAN)
require(address == address.toInt)
val dtsAddr = address.toInt + rom.capacity
require(rom.getInt(12) == 0,
"DTS address position should not be occupied by code")
rom.putInt(12, dtsAddr)
rom.array() ++ (dts.getBytes.toSeq)
} }
} }

View File

@ -30,20 +30,22 @@ class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], exec
} }
val contents = contentsDelayed val contents = contentsDelayed
require (contents.size <= size) val wrapSize = 1 << log2Ceil(contents.size)
require (wrapSize <= size)
val in = io.in(0) val in = io.in(0)
val edge = node.edgesIn(0) val edge = node.edgesIn(0)
val words = (contents ++ Seq.fill(size-contents.size)(0.toByte)).grouped(beatBytes).toSeq val words = (contents ++ Seq.fill(wrapSize-contents.size)(0.toByte)).grouped(beatBytes).toSeq
val bigs = words.map(_.foldRight(BigInt(0)){ case (x,y) => (x.toInt & 0xff) | y << 8}) val bigs = words.map(_.foldRight(BigInt(0)){ case (x,y) => (x.toInt & 0xff) | y << 8})
val rom = Vec(bigs.map(x => UInt(x, width = 8*beatBytes))) val rom = Vec(bigs.map(x => UInt(x, width = 8*beatBytes)))
in.d.valid := in.a.valid in.d.valid := in.a.valid
in.a.ready := in.d.ready in.a.ready := in.d.ready
val index = in.a.bits.address(log2Ceil(size)-1,log2Ceil(beatBytes)) val index = in.a.bits.address(log2Ceil(wrapSize)-1,log2Ceil(beatBytes))
in.d.bits := edge.AccessAck(in.a.bits, UInt(0), rom(index)) val high = if (wrapSize == size) UInt(0) else in.a.bits.address(log2Ceil(size)-1, log2Ceil(wrapSize))
in.d.bits := edge.AccessAck(in.a.bits, UInt(0), Mux(high.orR, UInt(0), rom(index)))
// Tie off unused channels // Tie off unused channels
in.b.valid := Bool(false) in.b.valid := Bool(false)