Modified bootloader to access GUID partitions. SDC interrupt to PLIC.

Since writing an SD card image generation script, the bootloader
needed to be altered to access individual binaries from specific
partitions. A new file, gpt.c with it's header gpt.h, have been added
to the bootloader to facilitate this.

The SDC has been added to the device tree for the VCU108
board. Additionally the SDC interrupt signal was added to the PLIC
node in the device tree. The PLIC itself  was modified to accept the
SDC interrupt signal.
This commit is contained in:
Jacob Pease 2023-07-14 13:36:44 -05:00
parent 40f81d5da6
commit b3aaa87cba
14 changed files with 309 additions and 23 deletions

View File

@ -141,6 +141,7 @@
`define PLIC_NUM_SRC 53
`define PLIC_UART_ID 10
`define PLIC_GPIO_ID 3
`define PLIC_SDC_ID 20
`define BPRED_SUPPORTED 1
`define BPRED_TYPE "BPSPECULATIVEGSHARE" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE or BPSPECULATIVEGLOBAL or BPSPECULATIVEGSHARE or BPOLDGSHARE or BPOLDGSHARE2

78
fpga/proberange Executable file
View File

@ -0,0 +1,78 @@
#!/usr/bin/python3
import sys
def usage():
print("Usage: ./probes list_of_probes outfile")
def header():
return """create_debug_core u_ila_0 ila
set_property C_DATA_DEPTH 16384 [get_debug_cores u_ila_0]
set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0]
set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0]
set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_0]
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0]
set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_0]
startgroup
set_property C_EN_STRG_QUAL true [get_debug_cores u_ila_0 ]
set_property C_ADV_TRIGGER true [get_debug_cores u_ila_0 ]
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ]
set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ]
endgroup
connect_debug_port u_ila_0/clk [get_nets [list xlnx_ddr4_c0/inst/u_ddr4_infrastructure/addn_ui_clkout1 ]]"""
def convertLine(x):
temp = x.split()
temp[1] = int(temp[1])
temp[2] = int(temp[2])
return tuple(temp)
def probeBits( probe ):
str = ''
if (probe[1] > 1):
for i in range(probe[1]):
if i != (probe[1]-1):
str = str + f"{{{probe[0]}[{i}]}} "
else:
str = str + f"{{{probe[0]}[{i}]}} "
else:
str = f'{{{probe[0]}}}'
return str
def printProbe( probe,):
bits = probeBits(probe)
return (
f'create_debug_port u_ila_0 probe\n'
f'set_property port_width {probe[1]} [get_debug_ports u_ila_0/probe{probe[2]}]\n'
f'set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe{probe[2]}]\n'
f'connect_debug_port u_ila_0/probe{probe[2]} [get_nets [list {bits}]]\n\n'
)
def main(args):
if (len(args) != 2):
usage()
exit()
probeList = []
with open(args[0]) as probeListFile:
probeList = list(map(convertLine, probeListFile.readlines()))
with open(args[1], 'w') as outfile:
# outfile.write(header())
# outfile.write("\n\n")
for i in range(len(probeList)):
outfile.write(printProbe(probeList[i]))
if __name__ == '__main__':
main(sys.argv[1:])

76
fpga/probes Executable file
View File

@ -0,0 +1,76 @@
#!/usr/bin/python3
import sys
def usage():
print("Usage: ./probes list_of_probes outfile")
def header():
return """create_debug_core u_ila_0 ila
set_property C_DATA_DEPTH 16384 [get_debug_cores u_ila_0]
set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0]
set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0]
set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_0]
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0]
set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_0]
startgroup
set_property C_EN_STRG_QUAL true [get_debug_cores u_ila_0 ]
set_property C_ADV_TRIGGER true [get_debug_cores u_ila_0 ]
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ]
set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ]
endgroup
connect_debug_port u_ila_0/clk [get_nets [list xlnx_ddr4_c0/inst/u_ddr4_infrastructure/addn_ui_clkout1 ]]"""
def convertLine(x):
temp = x.split()
temp[1] = int(temp[1])
return tuple(temp)
def probeBits( probe ):
str = ''
if (probe[1] > 1):
for i in range(probe[1]):
if i != (probe[1]-1):
str = str + f"{{{probe[0]}[{i}]}} "
else:
str = str + f"{{{probe[0]}[{i}]}} "
else:
str = f'{{{probe[0]}}}'
return str
def printProbe( probe, i ):
bits = probeBits(probe)
return (
f'create_debug_port u_ila_0 probe\n'
f'set_property port_width {probe[1]} [get_debug_ports u_ila_0/probe{i}]\n'
f'set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe{i}]\n'
f'connect_debug_port u_ila_0/probe{i} [get_nets [list {bits}]]\n\n'
)
def main(args):
if (len(args) != 2):
usage()
exit()
probeList = []
with open(args[0]) as probeListFile:
probeList = list(map(convertLine, probeListFile.readlines()))
with open(args[1], 'w') as outfile:
outfile.write(header())
outfile.write("\n\n")
for i in range(len(probeList)):
outfile.write(printProbe(probeList[i], i))
if __name__ == '__main__':
main(sys.argv[1:])

View File

@ -41,7 +41,7 @@ module fpgaTop
inout [3:0] SDCDat,
output SDCCLK,
inout SDCCmd,
input SDCCD,
input SDCCD,
output calib,
output cpu_reset,
@ -415,6 +415,9 @@ module fpgaTop
wire sd_cmd_reg_o;
wire sd_cmd_reg_t;
// SD Card Interrupt signal
wire SDCintr;
// New SDC Data IOBUF connections
wire [3:0] sd_dat_i;
wire [3:0] sd_dat_reg_o;
@ -506,7 +509,8 @@ module fpgaTop
.GPIOPinsEn(GPIOPinsEn),
// UART
.UARTSin(UARTSin),
.UARTSout(UARTSout)
.UARTSout(UARTSout),
.SDCIntr(SDCIntr)
// SD Card
/*.SDCDatIn(SDCDatIn),
.SDCCmdIn(SDCCmdIn),
@ -864,7 +868,9 @@ module fpgaTop
.sd_cmd_i(sd_cmd_i),
.sdio_clk(SDCCLK),
.sdio_cd(SDCCD)
.sdio_cd(SDCCD),
.interrupt(SDCIntr)
);
xlnx_axi_dwidth_conv_32to64 axi_conv_up

View File

@ -9,6 +9,7 @@ all:
generate:
# generating device tree binary
dtc -I dts -O dtb ../devicetree/wally-virt.dts > ${IMAGES}/wally-virt.dtb
dtc -I dts -O dtb ../devicetree/wally-vcu108.dts > ${IMAGES}/wally-vcu108.dtb
disassemble:
mkdir -p ${DIS}

View File

@ -67,6 +67,20 @@
#address-cells = <0x00>;
};
mmc@13000 {
interrupts = <0x14>;
compatible = "riscv,axi-sd-card-1.0";
reg = <0x00 0x13000 0x00 0x7F>;
fifo-depth = <256>;
bus-width = <4>;
interrupt-parent = <0x03>;
clock = <0x14FB180>;
max-frequency = <0xA7D8C0>;
cap-sd-highspeed;
cap-mmc-highspeed;
no-sdio;
};
clint@2000000 {
interrupts-extended = <0x02 0x03 0x02 0x07>;
reg = <0x00 0x2000000 0x00 0x10000>;

View File

@ -43,17 +43,17 @@
// hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts
module plic_apb (
input logic PCLK, PRESETn,
input logic PSEL,
input logic [27:0] PADDR,
input logic [`XLEN-1:0] PWDATA,
input logic [`XLEN/8-1:0] PSTRB,
input logic PWRITE,
input logic PENABLE,
output logic [`XLEN-1:0] PRDATA,
output logic PREADY,
input logic UARTIntr,GPIOIntr,
output logic MExtInt, SExtInt
input logic PCLK, PRESETn,
input logic PSEL,
input logic [27:0] PADDR,
input logic [`XLEN-1:0] PWDATA,
input logic [`XLEN/8-1:0] PSTRB,
input logic PWRITE,
input logic PENABLE,
output logic [`XLEN-1:0] PRDATA,
output logic PREADY,
input logic UARTIntr,GPIOIntr,SDCIntr,
output logic MExtInt, SExtInt
);
logic memwrite, memread;
@ -167,6 +167,11 @@ module plic_apb (
`ifdef PLIC_UART_ID
requests[`PLIC_UART_ID] = UARTIntr;
`endif
// Jacob: July 8th 2023
`ifdef PLIC_SDC_ID
requests[`PLIC_SDC_ID] = SDCIntr;
`endif
end
// pending interrupt requests

View File

@ -57,7 +57,8 @@ module uncore (
input logic [31:0] GPIOPinsIn, // GPIO pin input value
output logic [31:0] GPIOPinsOut, GPIOPinsEn, // GPIO pin output value and enable
input logic UARTSin, // UART serial input
output logic UARTSout // UART serial output
output logic UARTSout, // UART serial output
input logic SDCIntr
/*output logic SDCCmdOut, // SD Card command output
output logic SDCCmdOE, // SD Card command output enable
input logic SDCCmdIn, // SD Card command input
@ -130,7 +131,7 @@ module uncore (
if (`PLIC_SUPPORTED == 1) begin : plic
plic_apb plic(.PCLK, .PRESETn, .PSEL(PSEL[2]), .PADDR(PADDR[27:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
.PRDATA(PRDATA[2]), .PREADY(PREADY[2]), .UARTIntr, .GPIOIntr, .MExtInt, .SExtInt);
.PRDATA(PRDATA[2]), .PREADY(PREADY[2]), .UARTIntr, .GPIOIntr, .SDCIntr, .MExtInt, .SExtInt);
end else begin : plic
assign MExtInt = 0;
assign SExtInt = 0;

View File

@ -56,7 +56,8 @@ module wallypipelinedsoc (
output logic [31:0] GPIOPinsOut, // output values for GPIO
output logic [31:0] GPIOPinsEn, // output enables for GPIO
input logic UARTSin, // UART serial data input
output logic UARTSout // UART serial data output
output logic UARTSout, // UART serial data output
input logic SDCIntr
/*input logic SDCCmdIn, // SDC Command input
output logic SDCCmdOut, // SDC Command output
output logic SDCCmdOE, // SDC Command output enable
@ -87,7 +88,7 @@ module wallypipelinedsoc (
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HSELEXT, .HSELEXTSDC,
.MTimerInt, .MSwInt, .MExtInt, .SExtInt, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin,
.UARTSout, .MTIME_CLINT
.UARTSout, .MTIME_CLINT, .SDCIntr
/*.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK*/);
end

View File

@ -28,7 +28,9 @@ LINKER :=$(ROOT)/linker1000.x
AFLAGS =$(MARCH) $(MABI) -W
CFLAGS =$(MARCH) $(MABI) -mcmodel=medany -O2
# Override directive allows us to prepend other options on the command line
# e.g. $ make CFLAGS=-g
override CFLAGS +=$(MARCH) $(MABI) -mcmodel=medany -O2
AS=riscv64-unknown-elf-as
CC=riscv64-unknown-elf-gcc
AR=riscv64-unknown-elf-ar
@ -104,7 +106,7 @@ $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CPPEXT)
# convert to hex
$(TARGET).memfile: $(TARGET)
@echo 'Making object dump file.'
@riscv64-unknown-elf-objdump -D $< > $<.objdump
riscv64-unknown-elf-objdump -DS $< > $<.objdump
@echo 'Making memory file'
riscv64-unknown-elf-elf2hex --bit-width 64 --input $^ --output $@
extractFunctionRadix.sh $<.objdump

View File

@ -1,5 +1,6 @@
#include <stddef.h>
#include "boot.h"
#include "gpt.h"
/* Card type flags (card_type) */
#define CT_MMC 0x01 /* MMC ver 3 */
@ -400,12 +401,15 @@ int disk_read(BYTE * buf, LBA_t sector, UINT count, BYTE card_type) {
void copyFlash(QWORD address, QWORD * Dst, DWORD numBlocks) {
BYTE card_type;
int ret = 0;
card_type = ini_sd();
BYTE * buf = (BYTE *)Dst;
// BYTE * buf = (BYTE *)Dst;
if (disk_read(buf, (LBA_t)address, (UINT)numBlocks, card_type) < 0) /* UART Print function?*/;
// if (disk_read(buf, (LBA_t)address, (UINT)numBlocks, card_type) < 0) /* UART Print function?*/;
ret = gpt_load_partitions(card_type);
}
/*

View File

@ -11,5 +11,16 @@ typedef WORD WCHAR;
typedef QWORD LBA_t;
// Define memory locations of boot images =====================
// These locations are copied from the generic configuration
// of OpenSBI. These addresses can be found in:
// buildroot/output/build/opensbi-0.9/platform/generic/config.mk
#define FDT_ADDRESS 0x80200000 // FW_JUMP_FDT_ADDR
#define OPENSBI_ADDRESS 0x80000000 // FW_TEXT_START
#define KERNEL_ADDRESS 0x82200000 // FW_JUMP_ADDR
// Export disk_read
int disk_read(BYTE * buf, LBA_t sector, UINT count, BYTE card_type);
#endif // WALLYBOOT

46
tests/custom/boot/gpt.c Normal file
View File

@ -0,0 +1,46 @@
#include "gpt.h"
#include "boot.h"
#include <stddef.h>
/* PSUEDOCODE
Need to load GPT LBA 1 and read through the partition entries.
I need to find each of the relevant partition entries, possibly
by their partition names.
*/
int gpt_load_partitions(BYTE card_type) {
// In this version of the GPT partition code
// I'm going to assume that the SD card is already initialized.
// size_t block_size = 512/8;
// long int lba1_buf[block_size];
BYTE lba1_buf[512];
int ret = 0;
//ret = disk_read(/* BYTE * buf, LBA_t sector, UINT count, BYTE card_type */);
ret = disk_read(lba1_buf, 1, 1, card_type);
/* Possible error handling with UART message
if ( ret != 0 ) {
}*/
gpt_pth_t *lba1 = (gpt_pth_t *)lba1_buf;
BYTE lba2_buf[512];
ret = disk_read(lba2_buf, (LBA_t)lba1->partition_entries_lba, 1, card_type);
// Load parition entries for the relevant boot partitions.
partition_entries_t *fdt = (partition_entries_t *)(lba2_buf);
partition_entries_t *opensbi = (partition_entries_t *)(lba2_buf + 128);
partition_entries_t *kernel = (partition_entries_t *)(lba2_buf + 256);
ret = disk_read((BYTE *)FDT_ADDRESS, fdt->first_lba, fdt->last_lba - fdt->first_lba + 1, card_type);
ret = disk_read((BYTE *)OPENSBI_ADDRESS, opensbi->first_lba, opensbi->last_lba - opensbi->first_lba + 1, card_type);
ret = disk_read((BYTE *)KERNEL_ADDRESS, kernel->first_lba,kernel->last_lba - kernel->first_lba + 1, card_type);
return 0;
}

40
tests/custom/boot/gpt.h Normal file
View File

@ -0,0 +1,40 @@
#pragma once
#include <stdint.h>
#include "boot.h"
// LBA 0: Protective MBR
// ignored here
// Partition Table Header (LBA 1)
typedef struct gpt_pth
{
uint64_t signature;
uint32_t revision;
uint32_t header_size; //! little endian, usually 0x5c = 92
uint32_t crc_header;
uint32_t reserved; //! must be 0
uint64_t current_lba;
uint64_t backup_lba;
uint64_t first_usable_lba;
uint64_t last_usable_lba;
uint8_t disk_guid[16];
uint64_t partition_entries_lba;
uint32_t nr_partition_entries;
uint32_t size_partition_entry; //! usually 0x80 = 128
uint32_t crc_partition_entry;
} gpt_pth_t;
// Partition Entries (LBA 2-33)
typedef struct partition_entries
{
uint8_t partition_type_guid[16];
uint8_t partition_guid[16];
uint64_t first_lba;
uint64_t last_lba; //! inclusive
uint64_t attributes;
uint8_t name[72]; //! utf16 encoded
} partition_entries_t;
// Find boot partition and load it to the destination
int gpt_load_partitions(BYTE card_type);