From 9a2f0d01a15653dbd6dba370f0d324d0fe0ee8c9 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 24 Mar 2017 14:35:11 -0700 Subject: [PATCH 1/5] GenerateBootROM: use compiled DTB --- src/main/scala/coreplex/RISCVPlatform.scala | 1 + src/main/scala/diplomacy/DeviceTree.scala | 16 ++++++++++++++++ src/main/scala/rocketchip/Periphery.scala | 2 +- src/main/scala/rocketchip/Utils.scala | 8 ++++---- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/scala/coreplex/RISCVPlatform.scala b/src/main/scala/coreplex/RISCVPlatform.scala index 4744ea85..e2e6d079 100644 --- a/src/main/scala/coreplex/RISCVPlatform.scala +++ b/src/main/scala/coreplex/RISCVPlatform.scala @@ -25,6 +25,7 @@ trait CoreplexRISCVPlatform extends CoreplexNetwork { plic.intnode := intBar.intnode lazy val dts = DTS(bindingTree) + lazy val dtb = DTB(dts) lazy val json = JSON(bindingTree) } diff --git a/src/main/scala/diplomacy/DeviceTree.scala b/src/main/scala/diplomacy/DeviceTree.scala index 8a26991a..04c468f2 100644 --- a/src/main/scala/diplomacy/DeviceTree.scala +++ b/src/main/scala/diplomacy/DeviceTree.scala @@ -4,6 +4,8 @@ package diplomacy import Chisel._ import config._ +import sys.process._ +import java.io.{ByteArrayInputStream, ByteArrayOutputStream} case object DTSModel extends Field[String] case object DTSCompat extends Field[Seq[String]] // -dev, -soc @@ -115,3 +117,17 @@ object DTS 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) + } +} diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 65b59033..4d091e80 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -307,7 +307,7 @@ trait PeripheryBootROM { private val bootrom_address = 0x1000 private val bootrom_size = 0x1000 - private lazy val bootrom_contents = GenerateBootROM(p, bootrom_address, coreplex.dts) + private lazy val bootrom_contents = GenerateBootROM(p, bootrom_address, coreplex.dtb) val bootrom = LazyModule(new TLROM(bootrom_address, bootrom_size, bootrom_contents, true, peripheryBusConfig.beatBytes)) bootrom.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) } diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index 31632741..c6910d69 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -53,17 +53,17 @@ class GlobalVariable[T] { } object GenerateBootROM { - def apply(p: Parameters, address: BigInt, dts: String) = { + def apply(p: Parameters, address: BigInt, dtb: DTB) = { val romdata = Files.readAllBytes(Paths.get(p(BootROMFile))) val rom = ByteBuffer.wrap(romdata) rom.order(ByteOrder.LITTLE_ENDIAN) require(address == address.toInt) - val dtsAddr = address.toInt + rom.capacity + val dtbAddr = 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) + rom.putInt(12, dtbAddr) + rom.array() ++ dtb.contents } } From 34f8ce653a4ab7aaf27d33b1c87fc638d2582009 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 24 Mar 2017 15:55:57 -0700 Subject: [PATCH 2/5] bootrom: follow SBI (a0=hartid, a1=dtb) --- bootrom/Makefile | 9 ++++-- bootrom/bootrom.S | 30 +++++++++++------- bootrom/bootrom.img | Bin 32 -> 128 bytes bootrom/linker.ld | 11 +++++-- src/main/scala/rocketchip/Periphery.scala | 2 +- src/main/scala/rocketchip/RISCVPlatform.scala | 2 +- src/main/scala/rocketchip/Utils.scala | 10 +----- 7 files changed, 36 insertions(+), 28 deletions(-) mode change 100755 => 100644 bootrom/bootrom.img diff --git a/bootrom/Makefile b/bootrom/Makefile index 3ea5f831..0580ba5a 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -5,8 +5,11 @@ OBJCOPY=riscv64-unknown-elf-objcopy all: $(bootrom_img) -%.img: %.elf - $(OBJCOPY) -O binary --change-addresses=-0x1000 --only-section .text $< $@ +%.img: %.bin + dd if=$< of=$@ bs=128 count=1 + +%.bin: %.elf + $(OBJCOPY) -O binary $< $@ %.elf: %.S linker.ld - $(GCC) -Tlinker.ld $< -nostdlib -static -o $@ + $(GCC) -Tlinker.ld $< -nostdlib -static -Wl,--no-gc-sections -o $@ diff --git a/bootrom/bootrom.S b/bootrom/bootrom.S index b35ee02a..384a4a37 100644 --- a/bootrom/bootrom.S +++ b/bootrom/bootrom.S @@ -1,13 +1,19 @@ -.text -.global _start +.section .text.start, "ax", @progbits +.globl _start _start: - // This boot ROM doesn't know about any boot devices, so it just spins, - // waiting for the debugger to load a program and change the PC. - j _start // reset vector - .word 0 // reserved - .word 0 // reserved - .word 0 // pointer to config string - .word 0 // default trap vector - .word 0 - .word 0 - .word 0 + la s0, DRAM_BASE + csrr a0, mhartid + la a1, _dtb + jr s0 + +.section .text.hang, "ax", @progbits +.globl _hang +_hang: + wfi + j _hang + +.section .rodata.dtb, "a", @progbits +.globl _dtb +.align 5, 0 +_dtb: +.ascii "DTB goes here" diff --git a/bootrom/bootrom.img b/bootrom/bootrom.img old mode 100755 new mode 100644 index 6d852f38bd3cd969a84d637805f29967f4d35926..c2016e2b9acdc66add405958d963c1e811ad0020 GIT binary patch literal 128 rcmWgt^1oh~g@vJ5)#2lGRtAR2t*-1$Eeu41Vuk>LultEsj-e0$(=rKr literal 32 Kcmd02zz+Zp003|R diff --git a/bootrom/linker.ld b/bootrom/linker.ld index 1b6ff96d..d209bc93 100644 --- a/bootrom/linker.ld +++ b/bootrom/linker.ld @@ -1,5 +1,12 @@ SECTIONS { - . = 0x1000; - .text : { *(.text) } + DRAM_BASE = 0x80000000; + ROM_BASE = 0x1000; + + . = ROM_BASE; + .text.start : { *(.text.start) } + . = ROM_BASE + 0x40; + .text.hang : { *(.text.hang) } + . = ROM_BASE + 0x80; + .rodata.dtb : { *(.rodata.dtb) } } diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 4d091e80..2a98f30f 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -307,7 +307,7 @@ trait PeripheryBootROM { private val bootrom_address = 0x1000 private val bootrom_size = 0x1000 - private lazy val bootrom_contents = GenerateBootROM(p, bootrom_address, coreplex.dtb) + private lazy val bootrom_contents = GenerateBootROM(coreplex.dtb) val bootrom = LazyModule(new TLROM(bootrom_address, bootrom_size, bootrom_contents, true, peripheryBusConfig.beatBytes)) bootrom.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) } diff --git a/src/main/scala/rocketchip/RISCVPlatform.scala b/src/main/scala/rocketchip/RISCVPlatform.scala index 7bc9779a..27f511d7 100644 --- a/src/main/scala/rocketchip/RISCVPlatform.scala +++ b/src/main/scala/rocketchip/RISCVPlatform.scala @@ -124,5 +124,5 @@ trait HardwiredResetVectorModule extends HasTopLevelNetworksModule { val outer: HardwiredResetVector val io: HardwiredResetVectorBundle - outer.coreplex.module.io.resetVector := UInt(0x1000) // boot ROM + outer.coreplex.module.io.resetVector := UInt(0x1040) // boot ROM: hang } diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index c6910d69..f6d039d8 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -53,17 +53,9 @@ class GlobalVariable[T] { } object GenerateBootROM { - def apply(p: Parameters, address: BigInt, dtb: DTB) = { + def apply(dtb: DTB)(implicit p: Parameters) = { val romdata = Files.readAllBytes(Paths.get(p(BootROMFile))) val rom = ByteBuffer.wrap(romdata) - - rom.order(ByteOrder.LITTLE_ENDIAN) - - require(address == address.toInt) - val dtbAddr = address.toInt + rom.capacity - require(rom.getInt(12) == 0, - "DTS address position should not be occupied by code") - rom.putInt(12, dtbAddr) rom.array() ++ dtb.contents } } From ac205ca10a51beec0b0ac53e24edf6fe2aa21f0c Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 24 Mar 2017 16:00:00 -0700 Subject: [PATCH 3/5] bootrom: move to 0x10000 for more space (DTB on multicore is big) --- bootrom/bootrom.img | Bin 128 -> 128 bytes bootrom/linker.ld | 2 +- src/main/scala/rocketchip/Periphery.scala | 4 ++-- src/main/scala/rocketchip/RISCVPlatform.scala | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bootrom/bootrom.img b/bootrom/bootrom.img index c2016e2b9acdc66add405958d963c1e811ad0020..bee192cfdbe45083f5f06502c80318c90379ef45 100644 GIT binary patch delta 10 RcmZo*Y+z&(XPL-U2LKD+0x val coreplex: CoreplexRISCVPlatform - private val bootrom_address = 0x1000 - private val bootrom_size = 0x1000 + private val bootrom_address = 0x10000 + private val bootrom_size = 0x10000 private lazy val bootrom_contents = GenerateBootROM(coreplex.dtb) val bootrom = LazyModule(new TLROM(bootrom_address, bootrom_size, bootrom_contents, true, peripheryBusConfig.beatBytes)) bootrom.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) diff --git a/src/main/scala/rocketchip/RISCVPlatform.scala b/src/main/scala/rocketchip/RISCVPlatform.scala index 27f511d7..b3cc4071 100644 --- a/src/main/scala/rocketchip/RISCVPlatform.scala +++ b/src/main/scala/rocketchip/RISCVPlatform.scala @@ -124,5 +124,5 @@ trait HardwiredResetVectorModule extends HasTopLevelNetworksModule { val outer: HardwiredResetVector val io: HardwiredResetVectorBundle - outer.coreplex.module.io.resetVector := UInt(0x1040) // boot ROM: hang + outer.coreplex.module.io.resetVector := UInt(0x10040) // boot ROM: hang } From f36b1766f8d68cf9cc33ca2b0d8c6156b2a8c038 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 24 Mar 2017 16:07:59 -0700 Subject: [PATCH 4/5] TLROM: use the smallest ROM implementation that works The contents everywhere else are still zero. --- src/main/scala/uncore/devices/Rom.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/scala/uncore/devices/Rom.scala b/src/main/scala/uncore/devices/Rom.scala index 8f5edc5a..2e686480 100644 --- a/src/main/scala/uncore/devices/Rom.scala +++ b/src/main/scala/uncore/devices/Rom.scala @@ -30,20 +30,22 @@ class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], exec } val contents = contentsDelayed - require (contents.size <= size) + val wrapSize = 1 << log2Ceil(contents.size) + require (wrapSize <= size) val in = io.in(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 rom = Vec(bigs.map(x => UInt(x, width = 8*beatBytes))) in.d.valid := in.a.valid in.a.ready := in.d.ready - val index = in.a.bits.address(log2Ceil(size)-1,log2Ceil(beatBytes)) - in.d.bits := edge.AccessAck(in.a.bits, UInt(0), rom(index)) + val index = in.a.bits.address(log2Ceil(wrapSize)-1,log2Ceil(beatBytes)) + 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 in.b.valid := Bool(false) From e74226564c64620c3ada0d801b293facd2a298c7 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 24 Mar 2017 20:59:33 -0700 Subject: [PATCH 5/5] travis: add dependency on device-tree-compiler --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 37a4eb52..aadb05c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,7 @@ addons: - bison - flex - texinfo + - device-tree-compiler env: matrix: