From 4eaac79ec25728cc76b161455cb1096589a5271c Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 2 Nov 2017 14:43:04 -0700 Subject: [PATCH 1/6] freedom: bump submodules to their respective masters --- common.mk | 23 +++++++++++++++---- fpga-shells | 2 +- rocket-chip | 2 +- sifive-blocks | 2 +- .../everywhere/e300artydevkit/Platform.scala | 16 ++++++------- .../unleashed/u500vc707devkit/Config.scala | 5 +++- .../unleashed/u500vc707devkit/FPGAChip.scala | 9 +++++--- 7 files changed, 40 insertions(+), 19 deletions(-) diff --git a/common.mk b/common.mk index db05483..e23cbb7 100644 --- a/common.mk +++ b/common.mk @@ -72,11 +72,26 @@ endif .PHONY: romgen romgen: $(romgen) +f := $(BUILD_DIR)/$(CONFIG_PROJECT).$(CONFIG).vsrcs.F +$(f): + echo $(VSRCS) > $@ + +bit := $(BUILD_DIR)/obj/$(MODEL).bit +$(bit): $(romgen) $(f) + cd $(BUILD_DIR); vivado \ + -nojournal -mode batch \ + -source $(fpga_common_script_dir)/vivado.tcl \ + -tclargs \ + -top-module "$(MODEL)" \ + -F "$(f)" \ + -ip-vivado-tcls "$(shell find '$(BUILD_DIR)' -name '*.vivado.tcl')" \ + -board "$(BOARD)" + + # Build .mcs -mcs := $(BUILD_DIR)/$(CONFIG_PROJECT).$(CONFIG).mcs -$(mcs): $(romgen) - VSRCS="$(VSRCS)" $(MAKE) -C $(FPGA_DIR) mcs - cp $(BUILD_DIR)/$(MODEL)/obj/system.mcs $@ +mcs := $(BUILD_DIR)/obj/$(MODEL).mcs +$(mcs): $(bit) + cd $(BUILD_DIR); vivado -nojournal -mode batch -source $(fpga_common_script_dir)/write_cfgmem.tcl -tclargs $(BOARD) $@ $< .PHONY: mcs mcs: $(mcs) diff --git a/fpga-shells b/fpga-shells index 2389e6e..ba7beb6 160000 --- a/fpga-shells +++ b/fpga-shells @@ -1 +1 @@ -Subproject commit 2389e6e95717caca782e7444422da16fef687188 +Subproject commit ba7beb676d55b73334bd4a85623e56c713a83773 diff --git a/rocket-chip b/rocket-chip index 82df766..7e75d63 160000 --- a/rocket-chip +++ b/rocket-chip @@ -1 +1 @@ -Subproject commit 82df766f4a5b1efb24b8659eb11c8b12c410a291 +Subproject commit 7e75d63ba6b4c1b50aaaf920e1c693ef6acf51d7 diff --git a/sifive-blocks b/sifive-blocks index f266b55..d1d2f47 160000 --- a/sifive-blocks +++ b/sifive-blocks @@ -1 +1 @@ -Subproject commit f266b55da92e42350be5704b4fe7d2a934e986ae +Subproject commit d1d2f47f609638c43546d4a9d0a4018c73dee4bb diff --git a/src/main/scala/everywhere/e300artydevkit/Platform.scala b/src/main/scala/everywhere/e300artydevkit/Platform.scala index a325333..be1789a 100644 --- a/src/main/scala/everywhere/e300artydevkit/Platform.scala +++ b/src/main/scala/everywhere/e300artydevkit/Platform.scala @@ -8,9 +8,9 @@ import freechips.rocketchip.coreplex._ import freechips.rocketchip.devices.debug._ import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.util.ResetCatchAndSync import freechips.rocketchip.system._ -import sifive.blocks.util.{ResetCatchAndSync} import sifive.blocks.devices.mockaon._ import sifive.blocks.devices.gpio._ import sifive.blocks.devices.jtag._ @@ -82,10 +82,10 @@ class E300ArtyDevKitPlatform(implicit val p: Parameters) extends Module { val spi_pins = sys.outer.spiParams.map { c => Wire(new SPIPins(() => PinGen(), c))} val i2c_pins = sys.outer.i2cParams.map { c => Wire(new I2CPins(() => PinGen()))} - (uart_pins zip sys_uart) map {case (p, r) => p.fromPort(r, clock = clock, reset = reset, syncStages = 0)} - (pwm_pins zip sys_pwm) map {case (p, r) => p.fromPort(r)} - (spi_pins zip sys_spi) map {case (p, r) => p.fromPort(r, clock = clock, reset = reset, syncStages = 0)} - (i2c_pins zip sys_i2c) map {case (p, r) => p.fromPort(r, clock = clock, reset = reset, syncStages = 0)} + (uart_pins zip sys_uart) map {case (p, r) => UARTPinsFromPort(p, r, clock = clock, reset = reset, syncStages = 0)} + (pwm_pins zip sys_pwm) map {case (p, r) => PWMPinsFromPort(p, r) } + (spi_pins zip sys_spi) map {case (p, r) => SPIPinsFromPort(p, r, clock = clock, reset = reset, syncStages = 0)} + (i2c_pins zip sys_i2c) map {case (p, r) => I2CPinsFromPort(p, r, clock = clock, reset = reset, syncStages = 0)} //----------------------------------------------------------------------- // Default Pin connections before attaching pinmux @@ -157,14 +157,14 @@ class E300ArtyDevKitPlatform(implicit val p: Parameters) extends Module { //----------------------------------------------------------------------- // Result of Pin Mux - io.pins.gpio.fromPort(sys.gpio(0)) + GPIOPinsFromPort(io.pins.gpio, sys.gpio(0)) // Dedicated SPI Pads - io.pins.qspi.fromPort(sys.qspi(0), clock = sys.clock, reset = sys.reset, syncStages = 3) + SPIPinsFromPort(io.pins.qspi, sys.qspi(0), clock = sys.clock, reset = sys.reset, syncStages = 3) // JTAG Debug Interface val sjtag = sys.debug.systemjtag.get - io.pins.jtag.fromPort(sjtag.jtag) + JTAGPinsFromPort(io.pins.jtag, sjtag.jtag) sjtag.reset := io.jtag_reset sjtag.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W) diff --git a/src/main/scala/unleashed/u500vc707devkit/Config.scala b/src/main/scala/unleashed/u500vc707devkit/Config.scala index a899e96..fd017bd 100644 --- a/src/main/scala/unleashed/u500vc707devkit/Config.scala +++ b/src/main/scala/unleashed/u500vc707devkit/Config.scala @@ -13,6 +13,8 @@ import sifive.blocks.devices.gpio._ import sifive.blocks.devices.spi._ import sifive.blocks.devices.uart._ +import sifive.fpgashells.devices.xilinx.xilinxvc707mig.{MemoryXilinxDDRKey,XilinxVC707MIGParams} + // Default FreedomUVC707Config class FreedomUVC707Config extends Config( new WithJtagDTM ++ @@ -40,7 +42,8 @@ class U500VC707DevKitConfig extends Config( new U500VC707DevKitPeripherals ++ new FreedomUVC707Config().alter((site,here,up) => { case ErrorParams => ErrorParams(Seq(AddressSet(0x3000, 0xfff))) - case PeripheryBusParams => up(PeripheryBusParams, site).copy(frequency = 50000000) // 50 MHz hperiphery + case PeripheryBusKey => up(PeripheryBusKey, site).copy(frequency = 50000000) // 50 MHz hperiphery + case MemoryXilinxDDRKey => XilinxVC707MIGParams(address = Seq(AddressSet(0x80000000L,0x40000000L-1))) //1GB case DTSTimebase => BigInt(1000000) case ExtMem => up(ExtMem).copy(size = 0x40000000L) case JtagDTMKey => new JtagDTMConfig ( diff --git a/src/main/scala/unleashed/u500vc707devkit/FPGAChip.scala b/src/main/scala/unleashed/u500vc707devkit/FPGAChip.scala index b281bb8..9ac7667 100644 --- a/src/main/scala/unleashed/u500vc707devkit/FPGAChip.scala +++ b/src/main/scala/unleashed/u500vc707devkit/FPGAChip.scala @@ -10,7 +10,7 @@ import freechips.rocketchip.diplomacy._ import sifive.blocks.devices.gpio._ import sifive.blocks.devices.pinctrl.{BasePin} -import sifive.fpgashells.shell.xilinx.vc707shell.{VC707Shell} +import sifive.fpgashells.shell.xilinx.vc707shell._ import sifive.fpgashells.ip.xilinx.{IOBUF} //------------------------------------------------------------------------- @@ -27,7 +27,10 @@ object PinGen { // U500VC707DevKitFPGAChip //------------------------------------------------------------------------- -class U500VC707DevKitFPGAChip(implicit override val p: Parameters) extends VC707Shell { +class U500VC707DevKitFPGAChip(implicit override val p: Parameters) + extends VC707Shell + with HasPCIe + with HasDDR3 { //----------------------------------------------------------------------- // DUT @@ -55,7 +58,7 @@ class U500VC707DevKitFPGAChip(implicit override val p: Parameters) extends VC707 val gpioParams = p(PeripheryGPIOKey) val gpio_pins = Wire(new GPIOPins(() => PinGen(), gpioParams(0))) - gpio_pins.fromPort(dut.gpio(0)) + GPIOPinsFromPort(gpio_pins, dut.gpio(0)) gpio_pins.pins.foreach { _.i.ival := Bool(false) } gpio_pins.pins.zipWithIndex.foreach { From 9cb03a3708d40576b6513da453dca4593371ecec Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 3 Nov 2017 11:20:08 -0700 Subject: [PATCH 2/6] README: update location of built files --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2498750..940b3d0 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ $ make -f Makefile.e300artydevkit verilog $ make -f Makefile.e300artydevkit mcs ``` -These will place the files under `builds/e300artydevkit`. +These will place the files under `builds/e300artydevkit/obj`. Note that in order to run the `mcs` target, you need to have the `vivado` executable on your `PATH`. @@ -77,7 +77,7 @@ $ make -f Makefile.u500vc707devkit verilog $ make -f Makefile.u500vc707devkit mcs ``` -These will place the files under `builds/u500vc707devkit`. +These will place the files under `builds/u500vc707devkit/obj`. Note that in order to run the `mcs` target, you need to have the `vivado` executable on your `PATH`. From c965442560d2fa820e0f835f1cd38acec7f2245b Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 2 Nov 2017 15:21:39 -0700 Subject: [PATCH 3/6] u500: enable FPU; needed by linux --- src/main/scala/unleashed/u500vc707devkit/Config.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/scala/unleashed/u500vc707devkit/Config.scala b/src/main/scala/unleashed/u500vc707devkit/Config.scala index fd017bd..f15c14e 100644 --- a/src/main/scala/unleashed/u500vc707devkit/Config.scala +++ b/src/main/scala/unleashed/u500vc707devkit/Config.scala @@ -37,7 +37,6 @@ class U500VC707DevKitPeripherals extends Config((site, here, up) => { // Freedom U500 VC707 Dev Kit class U500VC707DevKitConfig extends Config( - new WithoutFPU ++ new WithNExtTopInterrupts(0) ++ new U500VC707DevKitPeripherals ++ new FreedomUVC707Config().alter((site,here,up) => { From 9f0877fc85a299ad0c6d9c2e2eec411e3ce87d8c Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 3 Nov 2017 11:42:52 -0700 Subject: [PATCH 4/6] sdboot: support SMP boot --- bootrom/sdboot/head.S | 3 + bootrom/sdboot/include/smp.h | 142 +++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 bootrom/sdboot/include/smp.h diff --git a/bootrom/sdboot/head.S b/bootrom/sdboot/head.S index 88adfbb..14fa740 100644 --- a/bootrom/sdboot/head.S +++ b/bootrom/sdboot/head.S @@ -1,13 +1,16 @@ // See LICENSE for license details. #include +#include #include "common.h" .section .text.init .option norvc .globl _prog_start _prog_start: + smp_pause(s1, s2) li sp, (PAYLOAD_DEST + 0x7fff000) call main + smp_resume(s1, s2) csrr a0, mhartid la a1, dtb li s1, PAYLOAD_DEST diff --git a/bootrom/sdboot/include/smp.h b/bootrom/sdboot/include/smp.h new file mode 100644 index 0000000..145ceb3 --- /dev/null +++ b/bootrom/sdboot/include/smp.h @@ -0,0 +1,142 @@ +#ifndef SIFIVE_SMP +#define SIFIVE_SMP +#include "platform.h" + +// The maximum number of HARTs this code supports +#ifndef MAX_HARTS +#define MAX_HARTS 32 +#endif +#define CLINT_END_HART_IPI CLINT_CTRL_ADDR + (MAX_HARTS*4) +#define CLINT1_END_HART_IPI CLINT1_CTRL_ADDR + (MAX_HARTS*4) + +// The hart that non-SMP tests should run on +#ifndef NONSMP_HART +#define NONSMP_HART 0 +#endif + +/* If your test cannot handle multiple-threads, use this: + * smp_disable(reg1) + */ +#define smp_disable(reg1, reg2) \ + csrr reg1, mhartid ;\ + li reg2, NONSMP_HART ;\ + beq reg1, reg2, hart0_entry ;\ +42: ;\ + wfi ;\ + j 42b ;\ +hart0_entry: + +/* If your test needs to temporarily block multiple-threads, do this: + * smp_pause(reg1, reg2) + * ... single-threaded work ... + * smp_resume(reg1, reg2) + * ... multi-threaded work ... + */ + +#define smp_pause(reg1, reg2) \ + li reg2, 0x8 ;\ + csrw mie, reg2 ;\ + li reg1, NONSMP_HART ;\ + csrr reg2, mhartid ;\ + bne reg1, reg2, 42f + +#ifdef CLINT1_CTRL_ADDR +// If a second CLINT exists, then make sure we: +// 1) Trigger a software interrupt on all harts of both CLINTs. +// 2) Locate your own hart's software interrupt pending register and clear it. +// 3) Wait for all harts on both CLINTs to clear their software interrupt +// pending register. +// WARNING: This code makes these assumptions, which are only true for Fadu as +// of now: +// 1) hart0 uses CLINT0 at offset 0 +// 2) hart2 uses CLINT1 at offset 0 +// 3) hart3 uses CLINT1 at offset 1 +// 4) There are no other harts or CLINTs in the system. +#define smp_resume(reg1, reg2) \ + /* Trigger software interrupt on CLINT0 */ \ + li reg1, CLINT_CTRL_ADDR ;\ +41: ;\ + li reg2, 1 ;\ + sw reg2, 0(reg1) ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT_END_HART_IPI ;\ + blt reg1, reg2, 41b ;\ + /* Trigger software interrupt on CLINT1 */ \ + li reg1, CLINT1_CTRL_ADDR ;\ +41: ;\ + li reg2, 1 ;\ + sw reg2, 0(reg1) ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT1_END_HART_IPI ;\ + blt reg1, reg2, 41b ;\ + /* Wait to receive software interrupt */ \ +42: ;\ + wfi ;\ + csrr reg2, mip ;\ + andi reg2, reg2, 0x8 ;\ + beqz reg2, 42b ;\ + /* Clear own software interrupt bit */ \ + csrr reg2, mhartid ;\ + bnez reg2, 41f; \ + /* hart0 case: Use CLINT0 */ \ + li reg1, CLINT_CTRL_ADDR ;\ + slli reg2, reg2, 2 ;\ + add reg2, reg2, reg1 ;\ + sw zero, 0(reg2) ;\ + j 42f; \ +41: \ + /* hart 2, 3 case: Use CLINT1 and remap hart IDs to 0 and 1 */ \ + li reg1, CLINT1_CTRL_ADDR ;\ + addi reg2, reg2, -2; \ + slli reg2, reg2, 2 ;\ + add reg2, reg2, reg1 ;\ + sw zero, 0(reg2) ; \ +42: \ + /* Wait for all software interrupt bits to be cleared on CLINT0 */ \ + li reg1, CLINT_CTRL_ADDR ;\ +41: ;\ + lw reg2, 0(reg1) ;\ + bnez reg2, 41b ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT_END_HART_IPI ;\ + blt reg1, reg2, 41b; \ + /* Wait for all software interrupt bits to be cleared on CLINT1 */ \ + li reg1, CLINT1_CTRL_ADDR ;\ +41: ;\ + lw reg2, 0(reg1) ;\ + bnez reg2, 41b ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT1_END_HART_IPI ;\ + blt reg1, reg2, 41b; \ + /* End smp_resume() */ + +#else + +#define smp_resume(reg1, reg2) \ + li reg1, CLINT_CTRL_ADDR ;\ +41: ;\ + li reg2, 1 ;\ + sw reg2, 0(reg1) ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT_END_HART_IPI ;\ + blt reg1, reg2, 41b ;\ +42: ;\ + wfi ;\ + csrr reg2, mip ;\ + andi reg2, reg2, 0x8 ;\ + beqz reg2, 42b ;\ + li reg1, CLINT_CTRL_ADDR ;\ + csrr reg2, mhartid ;\ + slli reg2, reg2, 2 ;\ + add reg2, reg2, reg1 ;\ + sw zero, 0(reg2) ;\ +41: ;\ + lw reg2, 0(reg1) ;\ + bnez reg2, 41b ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT_END_HART_IPI ;\ + blt reg1, reg2, 41b + +#endif /* ifdef CLINT1_CTRL_ADDR */ + +#endif From 4297b224729d400468ac11cc19da2a20bd8a7dca Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 2 Nov 2017 15:32:31 -0700 Subject: [PATCH 5/6] unleashed: build quad-core instead Because there are boot loaders out there that disable core 0, let's make sure the open source design has >1 core to prevent these images from hanging. We should also change freedom-u-sdk to check using DTS to determine which cores to disable to properly fix this problem. --- src/main/scala/unleashed/u500vc707devkit/Config.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/unleashed/u500vc707devkit/Config.scala b/src/main/scala/unleashed/u500vc707devkit/Config.scala index f15c14e..4598f2f 100644 --- a/src/main/scala/unleashed/u500vc707devkit/Config.scala +++ b/src/main/scala/unleashed/u500vc707devkit/Config.scala @@ -19,7 +19,7 @@ import sifive.fpgashells.devices.xilinx.xilinxvc707mig.{MemoryXilinxDDRKey,Xilin class FreedomUVC707Config extends Config( new WithJtagDTM ++ new WithNMemoryChannels(1) ++ - new WithNBigCores(1) ++ + new WithNBigCores(4) ++ new BaseConfig ) From e1673b86705f0fc3f812a46bd08c4ae7ff054fa3 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 3 Nov 2017 12:53:00 -0700 Subject: [PATCH 6/6] README: note the vivado version requirements --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 940b3d0..3ba5011 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ $ make -f Makefile.e300artydevkit verilog $ make -f Makefile.e300artydevkit mcs ``` +Note: This flow requires vivado 2017.1. Old versions are known to fail. + These will place the files under `builds/e300artydevkit/obj`. Note that in order to run the `mcs` target, you need to have the `vivado` @@ -77,6 +79,8 @@ $ make -f Makefile.u500vc707devkit verilog $ make -f Makefile.u500vc707devkit mcs ``` +Note: This flow requires vivado 2016.1. Newer versions are known to fail. + These will place the files under `builds/u500vc707devkit/obj`. Note that in order to run the `mcs` target, you need to have the `vivado`