Xiang Wang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/35119 )
Change subject: soc/sifive/fu540: add support boot from sdcard ......................................................................
soc/sifive/fu540: add support boot from sdcard
Change-Id: I18948d31c0bf0bf9d641480a35fc710b9ee8ae84 Signed-off-by: Xiang Wang merle@hardenedlinux.org --- M src/mainboard/sifive/hifive-unleashed/Kconfig M src/mainboard/sifive/hifive-unleashed/media.c M src/soc/sifive/fu540/include/soc/memlayout.ld 3 files changed, 98 insertions(+), 7 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/19/35119/1
diff --git a/src/mainboard/sifive/hifive-unleashed/Kconfig b/src/mainboard/sifive/hifive-unleashed/Kconfig index 2453178..fc9bc1e 100644 --- a/src/mainboard/sifive/hifive-unleashed/Kconfig +++ b/src/mainboard/sifive/hifive-unleashed/Kconfig @@ -19,6 +19,7 @@ select BOARD_ROMSIZE_KB_32768 select MISSING_BOARD_RESET select FLATTENED_DEVICE_TREE + select SPI_SDCARD
config HEAP_SIZE default 0x10000 diff --git a/src/mainboard/sifive/hifive-unleashed/media.c b/src/mainboard/sifive/hifive-unleashed/media.c index b0198a7..29cca08 100644 --- a/src/mainboard/sifive/hifive-unleashed/media.c +++ b/src/mainboard/sifive/hifive-unleashed/media.c @@ -15,15 +15,91 @@ */
#include <boot_device.h> +#include <symbols.h> +#include <cbfs.h> +#include <arch/mmio.h> +#include <soc/addressmap.h> #include <soc/spi.h> +#include <soc/clock.h> +#include <console/console.h> +#include <string.h> +#include <spi_sdcard.h> + +static struct spi_sdcard card;
/* At 0x20000000: A 256MiB long memory-mapped view of the flash at QSPI0 */ -static struct mem_region_device mdev = +static struct mem_region_device spi_mdev = MEM_REGION_DEV_RO_INIT((void *)0x20000000, CONFIG_ROM_SIZE);
+static ssize_t unleashed_sd_readat(const struct region_device *rdev, void *dest, + size_t offset, size_t count) +{ + size_t start_block_address = offset / 512; + size_t end_block_address = (offset + count - 1) / 512; + size_t has_begin = !!(offset % 512); + size_t has_end = !!((offset + count) % 512); + + if (start_block_address == end_block_address) { + uint8_t tmp[512]; + size_t o = offset % 512; + size_t l = count; + spi_sdcard_single_read(&card, start_block_address, tmp); + memcpy(dest, tmp + o, l); + return count; + } + + if (has_begin) { + uint8_t tmp[512]; + size_t o = offset % 512; + size_t l = 512 - o; + spi_sdcard_single_read(&card, start_block_address, tmp); + memcpy(dest, tmp + o, l); + } + + if (start_block_address + has_begin <= end_block_address - has_end) { + size_t start_lba = start_block_address + has_begin; + size_t end_lba = end_block_address - has_end; + size_t o = has_begin ? 512 - offset % 512 : 0; + if (start_lba < end_lba) + spi_sdcard_multiple_read(&card, + start_lba, end_lba, dest + o); + else + spi_sdcard_single_read(&card, start_lba, dest + o); + } + + if (has_end) { + uint8_t tmp[512]; + size_t o = 0; + size_t l = (offset + count) % 512; + spi_sdcard_single_read(&card, end_block_address, tmp); + memcpy(dest + count - l, tmp + o, l); + } + + return count; +} + +static const struct region_device_ops unleashed_sd_ops = { + .mmap = mmap_helper_rdev_mmap, + .munmap = mmap_helper_rdev_munmap, + .readat = unleashed_sd_readat, +}; + + +static struct mmap_helper_region_device sd_mdev = + MMAP_HELPER_REGION_INIT(&unleashed_sd_ops, 0, CONFIG_ROM_SIZE); + const struct region_device *boot_device_ro(void) { - return &mdev.rdev; + + switch (read32((uint32_t *)FU540_MSEL)) { + case 6: + case 10: + case 15: + return &spi_mdev.rdev; + case 11: + return &sd_mdev.rdev; + } + return NULL; }
const static struct fu540_spi_mmap_config spi_mmap_config = { @@ -40,10 +116,22 @@ void boot_device_init(void) { struct spi_slave slave; + switch (read32((uint32_t *)FU540_MSEL)) { + case 6: + case 10: + case 15: + /* initialize spi controller */ + spi_setup_slave(0, 0, &slave);
- /* initialize spi controller */ - spi_setup_slave(0, 0, &slave); - - /* map flash to memory space */ - fu540_spi_mmap(&slave, &spi_mmap_config); + /* map flash to memory space */ + fu540_spi_mmap(&slave, &spi_mmap_config); + break; + case 11: + spi_sdcard_init(&card, 2, 0); + mmap_helper_device_init(&sd_mdev, + _cbfs_cache, REGION_SIZE(cbfs_cache)); + break; + default: + die("Wrong configuration of MSEL"); + } } diff --git a/src/soc/sifive/fu540/include/soc/memlayout.ld b/src/soc/sifive/fu540/include/soc/memlayout.ld index b9b9c47..81a7f9b 100644 --- a/src/soc/sifive/fu540/include/soc/memlayout.ld +++ b/src/soc/sifive/fu540/include/soc/memlayout.ld @@ -28,9 +28,11 @@ CAR_STACK(FU540_L2LIM + 64K, 20K) PRERAM_CBMEM_CONSOLE(FU540_L2LIM + 84K, 8K) ROMSTAGE(FU540_L2LIM + 128K, 128K) + PRERAM_CBFS_CACHE(FU540_L2LIM + 256K, 128K) L2LIM_END(FU540_L2LIM + 2M)
DRAM_START(FU540_DRAM) RAMSTAGE(FU540_DRAM, 256K) MEM_STACK(FU540_DRAM + 256K, 20K) + POSTRAM_CBFS_CACHE(FU540_DRAM + 512K, 32M - 512K) }