diff --git a/fpga/zsbl/Makefile b/fpga/zsbl/Makefile index bd30033fc..37323b813 100644 --- a/fpga/zsbl/Makefile +++ b/fpga/zsbl/Makefile @@ -16,7 +16,7 @@ OBJECTS := $(OBJECTS:.$(CPPEXT)=.$(OBJEXT)) OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(OBJECTS)) TARGETDIR := bin -TARGET := $(TARGETDIR)/fpga-test-sdc +TARGET := $(TARGETDIR)/boot ROOT := .. LIBRARY_DIRS := LIBRARY_FILES := @@ -24,11 +24,13 @@ LIBRARY_FILES := MARCH :=-march=rv64imfdc_zifencei MABI :=-mabi=lp64d LINK_FLAGS :=$(MARCH) $(MABI) -nostartfiles -LINKER :=linker.x +LINKER :=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 -g 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 diff --git a/fpga/zsbl/bios.s b/fpga/zsbl/bios.s index 7954eab7a..9a5d6e21f 100644 --- a/fpga/zsbl/bios.s +++ b/fpga/zsbl/bios.s @@ -49,7 +49,12 @@ _start: # set the stack pointer to the top of memory - 8 bytes (pointer size) li sp, 0x87FFFFF8 - jal ra, main + li a0, 0x00000000 + li a1, 0x80000000 + #li a2, 128*1024*1024/512 # copy 128MB + li a2, 127*1024*1024/512 # copy 127MB upper 1MB contains the return address (ra) + #li a2, 800 # copy 400KB + jal ra, copyFlash fence.i # now toggle led so we know the copy completed. @@ -81,18 +86,16 @@ delay2: # now that the card is copied and the led toggled we # jump to the copied contents of the sd card. -jumpToLinux: - csrr a0, mhartid - li s0, 0x80000000 - la a1, _dtb - jr s0 +jumpToLinux: + csrrs a0, 0xF14, x0 # copy hart ID to a0 + li a1, 0x87000000 # end of memory? not 100% sure on this but it's 112MB + la a2, end_of_bios + li t0, 0x80000000 # start of code + + jalr x0, t0, 0 + end_of_bios: + -.section .rodata -.globl _dtb -.align 4, 0 -_dtb: -#.incbin "wally-vcu118.dtb" - diff --git a/fpga/zsbl/boot.c b/fpga/zsbl/boot.c new file mode 100644 index 000000000..6e4780f55 --- /dev/null +++ b/fpga/zsbl/boot.c @@ -0,0 +1,422 @@ +#include +#include "boot.h" +#include "gpt.h" + +/* Card type flags (card_type) */ +#define CT_MMC 0x01 /* MMC ver 3 */ +#define CT_SD1 0x02 /* SD ver 1 */ +#define CT_SD2 0x04 /* SD ver 2 */ +#define CT_SDC (CT_SD1|CT_SD2) /* SD */ +#define CT_BLOCK 0x08 /* Block addressing */ + +#define CMD0 (0) /* GO_IDLE_STATE */ +#define CMD1 (1) /* SEND_OP_COND */ +#define CMD2 (2) /* SEND_CID */ +#define CMD3 (3) /* RELATIVE_ADDR */ +#define CMD4 (4) +#define CMD5 (5) /* SLEEP_WAKE (SDC) */ +#define CMD6 (6) /* SWITCH_FUNC */ +#define CMD7 (7) /* SELECT */ +#define CMD8 (8) /* SEND_IF_COND */ +#define CMD9 (9) /* SEND_CSD */ +#define CMD10 (10) /* SEND_CID */ +#define CMD11 (11) +#define CMD12 (12) /* STOP_TRANSMISSION */ +#define CMD13 (13) +#define CMD15 (15) +#define CMD16 (16) /* SET_BLOCKLEN */ +#define CMD17 (17) /* READ_SINGLE_BLOCK */ +#define CMD18 (18) /* READ_MULTIPLE_BLOCK */ +#define CMD19 (19) +#define CMD20 (20) +#define CMD23 (23) +#define CMD24 (24) +#define CMD25 (25) +#define CMD27 (27) +#define CMD28 (28) +#define CMD29 (29) +#define CMD30 (30) +#define CMD32 (32) +#define CMD33 (33) +#define CMD38 (38) +#define CMD42 (42) +#define CMD55 (55) /* APP_CMD */ +#define CMD56 (56) +#define ACMD6 (0x80+6) /* define the data bus width */ +#define ACMD41 (0x80+41) /* SEND_OP_COND (ACMD) */ + +// Capability bits +#define SDC_CAPABILITY_SD_4BIT 0x0001 +#define SDC_CAPABILITY_SD_RESET 0x0002 +#define SDC_CAPABILITY_ADDR 0xff00 + +// Control bits +#define SDC_CONTROL_SD_4BIT 0x0001 +#define SDC_CONTROL_SD_RESET 0x0002 + +// Card detect bits +#define SDC_CARD_INSERT_INT_EN 0x0001 +#define SDC_CARD_INSERT_INT_REQ 0x0002 +#define SDC_CARD_REMOVE_INT_EN 0x0004 +#define SDC_CARD_REMOVE_INT_REQ 0x0008 + +// Command status bits +#define SDC_CMD_INT_STATUS_CC 0x0001 // Command complete +#define SDC_CMD_INT_STATUS_EI 0x0002 // Any error +#define SDC_CMD_INT_STATUS_CTE 0x0004 // Timeout +#define SDC_CMD_INT_STATUS_CCRC 0x0008 // CRC error +#define SDC_CMD_INT_STATUS_CIE 0x0010 // Command code check error + +// Data status bits +#define SDC_DAT_INT_STATUS_TRS 0x0001 // Transfer complete +#define SDC_DAT_INT_STATUS_ERR 0x0002 // Any error +#define SDC_DAT_INT_STATUS_CTE 0x0004 // Timeout +#define SDC_DAT_INT_STATUS_CRC 0x0008 // CRC error +#define SDC_DAT_INT_STATUS_CFE 0x0010 // Data FIFO underrun or overrun + + +#define ERR_EOF 30 +#define ERR_NOT_ELF 31 +#define ERR_ELF_BITS 32 +#define ERR_ELF_ENDIANNESS 33 +#define ERR_CMD_CRC 34 +#define ERR_CMD_CHECK 35 +#define ERR_DATA_CRC 36 +#define ERR_DATA_FIFO 37 +#define ERR_BUF_ALIGNMENT 38 +#define FR_DISK_ERR 39 +#define FR_TIMEOUT 40 + +struct sdc_regs { + volatile uint32_t argument; + volatile uint32_t command; + volatile uint32_t response1; + volatile uint32_t response2; + volatile uint32_t response3; + volatile uint32_t response4; + volatile uint32_t data_timeout; + volatile uint32_t control; + volatile uint32_t cmd_timeout; + volatile uint32_t clock_divider; + volatile uint32_t software_reset; + volatile uint32_t power_control; + volatile uint32_t capability; + volatile uint32_t cmd_int_status; + volatile uint32_t cmd_int_enable; + volatile uint32_t dat_int_status; + volatile uint32_t dat_int_enable; + volatile uint32_t block_size; + volatile uint32_t block_count; + volatile uint32_t card_detect; + volatile uint32_t res_50; + volatile uint32_t res_54; + volatile uint32_t res_58; + volatile uint32_t res_5c; + volatile uint64_t dma_addres; +}; + +#define MAX_BLOCK_CNT 0x1000 + +#define SDC 0x00013000; + +// static struct sdc_regs * const regs __attribute__((section(".rodata"))) = (struct sdc_regs *)0x00013000; + +// static int errno __attribute__((section(".bss"))); +// static DSTATUS drv_status __attribute__((section(".bss"))); +// static BYTE card_type __attribute__((section(".bss"))); +// static uint32_t response[4] __attribute__((section(".bss"))); +// static int alt_mem __attribute__((section(".bss"))); + +/*static const char * errno_to_str(void) { + switch (errno) { + case ERR_EOF: return "Unexpected EOF"; + case ERR_NOT_ELF: return "Not an ELF file"; + case ERR_ELF_BITS: return "Wrong ELF word size"; + case ERR_ELF_ENDIANNESS: return "Wrong ELF endianness"; + case ERR_CMD_CRC: return "Command CRC error"; + case ERR_CMD_CHECK: return "Command code check error"; + case ERR_DATA_CRC: return "Data CRC error"; + case ERR_DATA_FIFO: return "Data FIFO error"; + case ERR_BUF_ALIGNMENT: return "Bad buffer alignment"; + case FR_DISK_ERR: return "Disk error"; + case FR_TIMEOUT: return "Timeout"; + } + return "Unknown error code"; + }*/ + +static void usleep(unsigned us) { + uintptr_t cycles0; + uintptr_t cycles1; + asm volatile ("csrr %0, 0xB00" : "=r" (cycles0)); + for (;;) { + asm volatile ("csrr %0, 0xB00" : "=r" (cycles1)); + if (cycles1 - cycles0 >= us * 100) break; + } +} + +static int sdc_cmd_finish(unsigned cmd, uint32_t * response) { + struct sdc_regs * regs = (struct sdc_regs *)SDC; + + while (1) { + unsigned status = regs->cmd_int_status; + if (status) { + // clear interrupts + regs->cmd_int_status = 0; + while (regs->software_reset != 0) {} + if (status == SDC_CMD_INT_STATUS_CC) { + // get response + response[0] = regs->response1; + response[1] = regs->response2; + response[2] = regs->response3; + response[3] = regs->response4; + return 0; + } + /* errno = FR_DISK_ERR; + if (status & SDC_CMD_INT_STATUS_CTE) errno = FR_TIMEOUT; + if (status & SDC_CMD_INT_STATUS_CCRC) errno = ERR_CMD_CRC; + if (status & SDC_CMD_INT_STATUS_CIE) errno = ERR_CMD_CHECK;*/ + break; + } + } + return -1; +} + +static int sdc_data_finish(void) { + int status; + struct sdc_regs * regs = (struct sdc_regs *)SDC; + + while ((status = regs->dat_int_status) == 0) {} + regs->dat_int_status = 0; + while (regs->software_reset != 0) {} + + if (status == SDC_DAT_INT_STATUS_TRS) return 0; + /* errno = FR_DISK_ERR; + if (status & SDC_DAT_INT_STATUS_CTE) errno = FR_TIMEOUT; + if (status & SDC_DAT_INT_STATUS_CRC) errno = ERR_DATA_CRC; + if (status & SDC_DAT_INT_STATUS_CFE) errno = ERR_DATA_FIFO;*/ + return -1; +} + +static int send_data_cmd(unsigned cmd, unsigned arg, void * buf, unsigned blocks, uint32_t * response) { + struct sdc_regs * regs = (struct sdc_regs *)SDC; + + unsigned command = (cmd & 0x3f) << 8; + switch (cmd) { + case CMD0: + case CMD4: + case CMD15: + // No responce + break; + case CMD11: + case CMD13: + case CMD16: + case CMD17: + case CMD18: + case CMD19: + case CMD23: + case CMD24: + case CMD25: + case CMD27: + case CMD30: + case CMD32: + case CMD33: + case CMD42: + case CMD55: + case CMD56: + case ACMD6: + // R1 + command |= 1; // 48 bits + command |= 1 << 3; // resp CRC + command |= 1 << 4; // resp OPCODE + break; + case CMD7: + case CMD12: + case CMD20: + case CMD28: + case CMD29: + case CMD38: + // R1b + command |= 1; // 48 bits + command |= 1 << 2; // busy + command |= 1 << 3; // resp CRC + command |= 1 << 4; // resp OPCODE + break; + case CMD2: + case CMD9: + case CMD10: + // R2 + command |= 2; // 136 bits + command |= 1 << 3; // resp CRC + break; + case ACMD41: + // R3 + command |= 1; // 48 bits + break; + case CMD3: + // R6 + command |= 1; // 48 bits + command |= 1 << 2; // busy + command |= 1 << 3; // resp CRC + command |= 1 << 4; // resp OPCODE + break; + case CMD8: + // R7 + command |= 1; // 48 bits + command |= 1 << 3; // resp CRC + command |= 1 << 4; // resp OPCODE + break; + } + + if (blocks) { + command |= 1 << 5; + if ((intptr_t)buf & 3) { + // errno = ERR_BUF_ALIGNMENT; + return -1; + } + regs->dma_addres = (uint64_t)(intptr_t)buf; + regs->block_size = 511; + regs->block_count = blocks - 1; + regs->data_timeout = 0x1FFFFFF; + } + + regs->command = command; + regs->cmd_timeout = 0xFFFFF; + regs->argument = arg; + + if (sdc_cmd_finish(cmd, response) < 0) return -1; + if (blocks) return sdc_data_finish(); + + return 0; +} + +#define send_cmd(cmd, arg, response) send_data_cmd(cmd, arg, NULL, 0, response) + +static BYTE ini_sd(void) { + struct sdc_regs * regs = (struct sdc_regs *)SDC; + unsigned rca; + BYTE card_type; + uint32_t response[4]; + + /* Reset controller */ + regs->software_reset = 1; + while ((regs->software_reset & 1) == 0) {} + + // This clock divider is meant to initialize the card at + // 400kHz + + // 22MHz/400kHz = 55 (base 10) = 0x37 - 0x01 = 0x36 + regs->clock_divider = 0x36; + regs->software_reset = 0; + while (regs->software_reset) {} + usleep(5000); + + card_type = 0; + // drv_status = STA_NOINIT; + + if (regs->capability & SDC_CAPABILITY_SD_RESET) { + /* Power cycle SD card */ + regs->control |= SDC_CONTROL_SD_RESET; + usleep(1000000); + regs->control &= ~SDC_CONTROL_SD_RESET; + usleep(100000); + } + + /* Enter Idle state */ + send_cmd(CMD0, 0, response); + + card_type = CT_SD1; + if (send_cmd(CMD8, 0x1AA, response) == 0) { + if ((response[0] & 0xfff) != 0x1AA) { + // errno = ERR_CMD_CHECK; + return -1; + } + card_type = CT_SD2; + } + + /* Wait for leaving idle state (ACMD41 with HCS bit) */ + while (1) { + /* ACMD41, Set Operating Conditions: Host High Capacity & 3.3V */ + if (send_cmd(CMD55, 0, response) < 0 || send_cmd(ACMD41, 0x40300000, response) < 0) return -1; + if (response[0] & (1 << 31)) { + if (response[0] & (1 << 30)) card_type |= CT_BLOCK; + break; + } + } + + /* Enter Identification state */ + if (send_cmd(CMD2, 0, response) < 0) return -1; + + /* Get RCA (Relative Card Address) */ + rca = 0x1234; + if (send_cmd(CMD3, rca << 16, response) < 0) return -1; + rca = response[0] >> 16; + + /* Select card */ + if (send_cmd(CMD7, rca << 16, response) < 0) return -1; + + /* Clock 25MHz */ + // 22Mhz/2 = 11Mhz + regs->clock_divider = 1; + usleep(10000); + + /* Bus width 1-bit */ + regs->control = 0; + if (send_cmd(CMD55, rca << 16, response) < 0 || send_cmd(ACMD6, 0, response) < 0) return -1; + + /* Set R/W block length to 512 */ + if (send_cmd(CMD16, 512, response) < 0) return -1; + + // drv_status &= ~STA_NOINIT; + return card_type; +} + +int disk_read(BYTE * buf, LBA_t sector, UINT count, BYTE card_type) { + + /* This is not needed. This has everything to do with the FAT + filesystem stuff that I'm not including. All I need to do is + initialize the SD card and read from it. Anything in here that is + checking for potential errors, I'm going to have to temporarily + do without. + */ + // if (!count) return RES_PARERR; + /* if (drv_status & STA_NOINIT) return RES_NOTRDY; */ + + uint32_t response[4]; + struct sdc_regs * regs = (struct sdc_regs *)SDC; + + /* Convert LBA to byte address if needed */ + if (!(card_type & CT_BLOCK)) sector *= 512; + while (count > 0) { + UINT bcnt = count > MAX_BLOCK_CNT ? MAX_BLOCK_CNT : count; + unsigned bytes = bcnt * 512; + if (send_data_cmd(bcnt == 1 ? CMD17 : CMD18, sector, buf, bcnt, response) < 0) return 1; + if (bcnt > 1 && send_cmd(CMD12, 0, response) < 0) return 1; + sector += (card_type & CT_BLOCK) ? bcnt : bytes; + count -= bcnt; + buf += bytes; + } + + return 0;; +} + +void copyFlash(QWORD address, QWORD * Dst, DWORD numBlocks) { + BYTE card_type; + int ret = 0; + + card_type = ini_sd(); + + // BYTE * buf = (BYTE *)Dst; + + // if (disk_read(buf, (LBA_t)address, (UINT)numBlocks, card_type) < 0) /* UART Print function?*/; + + ret = gpt_load_partitions(card_type); +} + +/* +int main() { + ini_sd(); + + + return 0; +} +*/ diff --git a/fpga/zsbl/boot.h b/fpga/zsbl/boot.h new file mode 100644 index 000000000..77d403145 --- /dev/null +++ b/fpga/zsbl/boot.h @@ -0,0 +1,26 @@ +#ifndef WALLYBOOT +#define WALLYBOOT 10000 + +#include +typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ +typedef unsigned char BYTE; /* char must be 8-bit */ +typedef uint16_t WORD; /* 16-bit unsigned integer */ +typedef uint32_t DWORD; /* 32-bit unsigned integer */ +typedef uint64_t QWORD; /* 64-bit unsigned integer */ +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 0x87000000 // FW_JUMP_FDT_ADDR +#define OPENSBI_ADDRESS 0x80000000 // FW_TEXT_START +#define KERNEL_ADDRESS 0x80200000 // FW_JUMP_ADDR + +// Export disk_read +int disk_read(BYTE * buf, LBA_t sector, UINT count, BYTE card_type); + +#endif // WALLYBOOT + diff --git a/fpga/zsbl/copyFlash.c b/fpga/zsbl/copyFlash.c deleted file mode 100644 index 4165fe21c..000000000 --- a/fpga/zsbl/copyFlash.c +++ /dev/null @@ -1,40 +0,0 @@ -/////////////////////////////////////////// -// copyFlash.sv -// -// Written: Ross Thompson September 25, 2021 -// Modified: -// -// Purpose: copies flash card into memory -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -/////////////////////////////////////////// - -#include "sdcDriver.h" - -void copyFlash(long int blockAddr, long int * Dst, int numBlocks) { - - setSDCCLK(4); // must be even, 1 gives no division. - waitInitSDC(); - - int index; - - for(index = 0; index < numBlocks; index++) { - copySDC512(blockAddr+(index*512), Dst+(index*512/8)); - } - - -} diff --git a/fpga/zsbl/gpt.c b/fpga/zsbl/gpt.c index 0c645d70e..97e3e4e46 100644 --- a/fpga/zsbl/gpt.c +++ b/fpga/zsbl/gpt.c @@ -1,119 +1,46 @@ #include "gpt.h" - -#include "sdcDriver.h" - -#include "uart.h" +#include "boot.h" #include -int gpt_find_boot_partition(long int* dest, uint32_t size) -{ - //int ret = init_sd(); - int ret; - setSDCCLK(4); // must be even, 1 gives no division. - waitInitSDC(); - ret = 0; - if (ret != 0) { - print_uart("could not initialize sd... exiting\r\n"); - return -1; - } +/* PSUEDOCODE - print_uart("sd initialized!\r\n"); + 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. + +*/ - // load LBA1 - size_t block_size = 512/8; - long int lba1_buf[block_size]; +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. - //int res = sd_copy(lba1_buf, 1, 1); - int res; - copySDC512(1, lba1_buf); - res = 0; + // size_t block_size = 512/8; + // long int lba1_buf[block_size]; - if (res != 0) - { - print_uart("SD card failed!\r\n"); - print_uart("sd copy return value: "); - print_uart_addr(res); - print_uart("\r\n"); - return -2; - } + 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); - gpt_pth_t *lba1 = (gpt_pth_t *)lba1_buf; + /* Possible error handling with UART message + if ( ret != 0 ) { + + }*/ - print_uart("gpt partition table header:"); - print_uart("\r\n\tsignature:\t"); - print_uart_addr(lba1->signature); - print_uart("\r\n\trevision:\t"); - print_uart_int(lba1->revision); - print_uart("\r\n\tsize:\t\t"); - print_uart_int(lba1->header_size); - print_uart("\r\n\tcrc_header:\t"); - print_uart_int(lba1->crc_header); - print_uart("\r\n\treserved:\t"); - print_uart_int(lba1->reserved); - print_uart("\r\n\tcurrent lba:\t"); - print_uart_addr(lba1->current_lba); - print_uart("\r\n\tbackup lda:\t"); - print_uart_addr(lba1->backup_lba); - print_uart("\r\n\tpartition entries lba: \t"); - print_uart_addr(lba1->partition_entries_lba); - print_uart("\r\n\tnumber partition entries:\t"); - print_uart_int(lba1->nr_partition_entries); - print_uart("\r\n\tsize partition entries: \t"); - print_uart_int(lba1->size_partition_entry); - print_uart("\r\n"); + gpt_pth_t *lba1 = (gpt_pth_t *)lba1_buf; - long int lba2_buf[block_size]; + BYTE lba2_buf[512]; + ret = disk_read(lba2_buf, (LBA_t)lba1->partition_entries_lba, 1, card_type); - //res = sd_copy(lba2_buf, lba1->partition_entries_lba, 1); - copySDC512(lba1->partition_entries_lba, lba2_buf); - res = 0; + // 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); - if (res != 0) - { - print_uart("SD card failed!\r\n"); - print_uart("sd copy return value: "); - print_uart_addr(res); - print_uart("\r\n"); - return -2; - } + 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); - for (int i = 0; i < 4; i++) - { - partition_entries_t *part_entry = (partition_entries_t *)(lba2_buf + (i * 128)); - print_uart("gpt partition entry "); - print_uart_byte(i); - print_uart("\r\n\tpartition type guid:\t"); - for (int j = 0; j < 16; j++) - print_uart_byte(part_entry->partition_type_guid[j]); - print_uart("\r\n\tpartition guid: \t"); - for (int j = 0; j < 16; j++) - print_uart_byte(part_entry->partition_guid[j]); - print_uart("\r\n\tfirst lba:\t"); - print_uart_addr(part_entry->first_lba); - print_uart("\r\n\tlast lba:\t"); - print_uart_addr(part_entry->last_lba); - print_uart("\r\n\tattributes:\t"); - print_uart_addr(part_entry->attributes); - print_uart("\r\n\tname:\t"); - for (int j = 0; j < 72; j++) - print_uart_byte(part_entry->name[j]); - print_uart("\r\n"); - } - - partition_entries_t *boot = (partition_entries_t *)(lba2_buf); - print_uart("copying boot image "); - //res = sd_copy(dest, boot->first_lba, boot->last_lba - boot->first_lba + 1); - copyFlash(boot->first_lba, dest, boot->last_lba - boot->first_lba + 1); - - if (res != 0) - { - print_uart("SD card failed!\r\n"); - print_uart("sd copy return value: "); - print_uart_addr(res); - print_uart("\r\n"); - return -2; - } - - print_uart(" done!\r\n"); - return 0; + return 0; } diff --git a/fpga/zsbl/gpt.h b/fpga/zsbl/gpt.h index dcc27ae8a..4aefae229 100644 --- a/fpga/zsbl/gpt.h +++ b/fpga/zsbl/gpt.h @@ -1,6 +1,7 @@ #pragma once #include +#include "boot.h" // LBA 0: Protective MBR // ignored here @@ -36,4 +37,4 @@ typedef struct partition_entries } partition_entries_t; // Find boot partition and load it to the destination -int gpt_find_boot_partition(long int* dest, uint32_t size); +int gpt_load_partitions(BYTE card_type); diff --git a/fpga/zsbl/linker.x b/fpga/zsbl/linker1000.x similarity index 99% rename from fpga/zsbl/linker.x rename to fpga/zsbl/linker1000.x index f448109cc..6d9e948a6 100644 --- a/fpga/zsbl/linker.x +++ b/fpga/zsbl/linker1000.x @@ -7,7 +7,7 @@ SECTIONS { /* Read-only sections, merged into text segment: */ /* init segment to ensure we get a consistent start routine*/ - . = 0x0000000000000000; + . = 0x0000000000001000; . = ALIGN(0x0); .init : { *(.init) @@ -72,6 +72,7 @@ SECTIONS PROVIDE (__etext = .); PROVIDE (_etext = .); PROVIDE (etext = .); + . = 0x0000000000002000; .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } .sdata2 : diff --git a/fpga/zsbl/main.c b/fpga/zsbl/main.c deleted file mode 100644 index 898025c30..000000000 --- a/fpga/zsbl/main.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "uart.h" -#include "sdcDriver.h" -#include "gpt.h" - -int main() -{ - init_uart(30000000, 115200); - print_uart("Hello World!\r\n"); - - int res = gpt_find_boot_partition((long int *)0x80000000UL, 2 * 16384); - - if (res == 0) - { - return 0; - } - - while (1) - { - // do nothing - } -} - -void handle_trap(void) -{ - // print_uart("trap\r\n"); -} diff --git a/fpga/zsbl/sdcDriver.c b/fpga/zsbl/sdcDriver.c deleted file mode 100644 index 45caa42fa..000000000 --- a/fpga/zsbl/sdcDriver.c +++ /dev/null @@ -1,69 +0,0 @@ -/////////////////////////////////////////// -// SDC.sv -// -// Written: Rose Thompson September 25, 2021 -// Modified: -// -// Purpose: driver for sdc reader. -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -/////////////////////////////////////////// - - -#include "sdcDriver.h" - -#define SDC_MAIL_BOX 0x12100 - -void copySDC512(long int blockAddr, long int * Dst) { - - waitInitSDC(); - - volatile long int * mailBoxAddr; - volatile int * mailBoxCmd; - volatile int * mailBoxStatus; - volatile long int * mailBoxReadData; - mailBoxStatus = (int *) (SDC_MAIL_BOX + 0x4); - mailBoxCmd = (int *) (SDC_MAIL_BOX + 0x8); - mailBoxAddr = (long int *) (SDC_MAIL_BOX + 0x10); - mailBoxReadData = (long int *) (SDC_MAIL_BOX + 0x18); - - // write the SDC address register with the blockAddr - *mailBoxAddr = blockAddr; - *mailBoxCmd = 0x4; - - // wait until the mailbox has valid data - // this occurs when status[1] = 0 - while((*mailBoxStatus & 0x2) == 0x2); - - int index; - for(index = 0; index < 512/8; index++) { - Dst[index] = *mailBoxReadData; - } -} - -volatile void waitInitSDC(){ - volatile int * mailBoxStatus; - mailBoxStatus = (int *) (SDC_MAIL_BOX + 0x4); - while((*mailBoxStatus & 0x1) != 0x1); -} - -void setSDCCLK(int divider){ - divider = (1 - (divider >> 1)); - volatile int * mailBoxCLK; - mailBoxCLK = (int *) (SDC_MAIL_BOX + 0x0); - *mailBoxCLK = divider; -} diff --git a/fpga/zsbl/sdcDriver.h b/fpga/zsbl/sdcDriver.h deleted file mode 100644 index 3e7381837..000000000 --- a/fpga/zsbl/sdcDriver.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __SDCDRIVER_H -#define __SDCDRIVER_H - - -void copySDC512(long int, long int *); -volatile void waitInitSDC(); -void setSDCCLK(int); -void copyFlash(long int, long int *, int); - -#endif diff --git a/fpga/zsbl/smp.h b/fpga/zsbl/smp.h deleted file mode 100644 index bb037755d..000000000 --- a/fpga/zsbl/smp.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -// The hart that non-SMP tests should run on -#ifndef NONSMP_HART -#define NONSMP_HART 0 -#endif - -// The maximum number of HARTs this code supports -#define CLINT_CTRL_ADDR 0x2000000 -#ifndef MAX_HARTS -#define MAX_HARTS 256 -#endif -#define CLINT_END_HART_IPI CLINT_CTRL_ADDR + (MAX_HARTS * 4) - -/* 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 - -#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 diff --git a/fpga/zsbl/uart.c b/fpga/zsbl/uart.c deleted file mode 100644 index a8084ee5e..000000000 --- a/fpga/zsbl/uart.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "uart.h" - -void write_reg_u8(uintptr_t addr, uint8_t value) -{ - volatile uint8_t *loc_addr = (volatile uint8_t *)addr; - *loc_addr = value; -} - -uint8_t read_reg_u8(uintptr_t addr) -{ - return *(volatile uint8_t *)addr; -} - -int is_transmit_empty() -{ - return read_reg_u8(UART_LINE_STATUS) & 0x20; -} - -void write_serial(char a) -{ - while (is_transmit_empty() == 0) {}; - - write_reg_u8(UART_THR, a); -} - -void init_uart(uint32_t freq, uint32_t baud) -{ - uint32_t divisor = freq / (baud << 4); - - write_reg_u8(UART_INTERRUPT_ENABLE, 0x00); // Disable all interrupts - write_reg_u8(UART_LINE_CONTROL, 0x80); // Enable DLAB (set baud rate divisor) - write_reg_u8(UART_DLAB_LSB, divisor); // divisor (lo byte) - write_reg_u8(UART_DLAB_MSB, (divisor >> 8) & 0xFF); // divisor (hi byte) - write_reg_u8(UART_LINE_CONTROL, 0x03); // 8 bits, no parity, one stop bit - write_reg_u8(UART_FIFO_CONTROL, 0xC7); // Enable FIFO, clear them, with 14-byte threshold - write_reg_u8(UART_MODEM_CONTROL, 0x20); // Autoflow mode -} - -void print_uart(const char *str) -{ - const char *cur = &str[0]; - while (*cur != '\0') - { - write_serial((uint8_t)*cur); - ++cur; - } -} - -uint8_t bin_to_hex_table[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - -void bin_to_hex(uint8_t inp, uint8_t res[2]) -{ - res[1] = bin_to_hex_table[inp & 0xf]; - res[0] = bin_to_hex_table[(inp >> 4) & 0xf]; - return; -} - -void print_uart_int(uint32_t addr) -{ - int i; - for (i = 3; i > -1; i--) - { - uint8_t cur = (addr >> (i * 8)) & 0xff; - uint8_t hex[2]; - bin_to_hex(cur, hex); - write_serial(hex[0]); - write_serial(hex[1]); - } -} - -void print_uart_addr(uint64_t addr) -{ - int i; - for (i = 7; i > -1; i--) - { - uint8_t cur = (addr >> (i * 8)) & 0xff; - uint8_t hex[2]; - bin_to_hex(cur, hex); - write_serial(hex[0]); - write_serial(hex[1]); - } -} - -void print_uart_byte(uint8_t byte) -{ - uint8_t hex[2]; - bin_to_hex(byte, hex); - write_serial(hex[0]); - write_serial(hex[1]); -} diff --git a/fpga/zsbl/uart.h b/fpga/zsbl/uart.h deleted file mode 100644 index df3aef9c8..000000000 --- a/fpga/zsbl/uart.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -#define UART_BASE 0x10000000 - -#define UART_RBR UART_BASE + 0 -#define UART_THR UART_BASE + 0 -#define UART_INTERRUPT_ENABLE UART_BASE + 4 -#define UART_INTERRUPT_IDENT UART_BASE + 8 -#define UART_FIFO_CONTROL UART_BASE + 8 -#define UART_LINE_CONTROL UART_BASE + 12 -#define UART_MODEM_CONTROL UART_BASE + 16 -#define UART_LINE_STATUS UART_BASE + 20 -#define UART_MODEM_STATUS UART_BASE + 24 -#define UART_DLAB_LSB UART_BASE + 0 -#define UART_DLAB_MSB UART_BASE + 4 - -void init_uart(); - -void print_uart(const char* str); - -void print_uart_int(uint32_t addr); - -void print_uart_addr(uint64_t addr); - -void print_uart_byte(uint8_t byte);