@@ -30,6 +30,7 @@ addons:
 | 
				
			|||||||
      - bison
 | 
					      - bison
 | 
				
			||||||
      - flex
 | 
					      - flex
 | 
				
			||||||
      - texinfo
 | 
					      - texinfo
 | 
				
			||||||
 | 
					      - device-tree-compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
env:
 | 
					env:
 | 
				
			||||||
  matrix:
 | 
					  matrix:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 $@
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
									
								
							
							
						
						
									
										
											BIN
										
									
								
								bootrom/bootrom.img
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -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) }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user