bios/boot: rework netboot/flashboot for VexRiscv in linux variant

Get rid of NETBOOT_LINUX_VEXRISCV/FLASHBOOT_LINUX_VEXRISCV defines
and use information about CPU_TYPE and CPU_VARIANT instead.

Use common kernel/rootfs/device tree/emulator images layout
when booting over network and from flash.
This commit is contained in:
Mateusz Holenko 2019-07-11 10:14:27 +02:00
parent a19bdd0e6a
commit 8335f13fb1

View file

@ -224,6 +224,48 @@ const char *filename, char *buffer)
static const unsigned char macadr[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00}; static const unsigned char macadr[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00};
#define ROOTFS_IMAGE_RAM_OFFSET 0x00800000
#define DEVICE_TREE_IMAGE_RAM_OFFSET 0x01000000
#define EMULATOR_IMAGE_RAM_OFFSET 0x02000000
#if defined(CONFIG_CPU_TYPE_VEXRISCV) && defined(CONFIG_CPU_VARIANT_LINUX)
static int try_get_kernel_rootfs_dtb_emulator(unsigned int ip, unsigned short tftp_port)
{
unsigned long tftp_dst_addr;
int size;
tftp_dst_addr = MAIN_RAM_BASE;
size = tftp_get_v(ip, tftp_port, "Image", (void *)tftp_dst_addr);
if (size <= 0) {
printf("Network boot failed\n");
return 0;
}
tftp_dst_addr = MAIN_RAM_BASE + ROOTFS_IMAGE_RAM_OFFSET;
size = tftp_get_v(ip, tftp_port, "rootfs.cpio", (void *)tftp_dst_addr);
if(size <= 0) {
printf("No rootfs.cpio found\n");
return 0;
}
tftp_dst_addr = MAIN_RAM_BASE + DEVICE_TREE_IMAGE_RAM_OFFSET;
size = tftp_get_v(ip, tftp_port, "rv32.dtb", (void *)tftp_dst_addr);
if(size <= 0) {
printf("No rv32.dtb found\n");
return 0;
}
tftp_dst_addr = MAIN_RAM_BASE + EMULATOR_IMAGE_RAM_OFFSET;
size = tftp_get_v(ip, tftp_port, "emulator.bin", (void *)tftp_dst_addr);
if(size <= 0) {
printf("No emulator.bin found\n");
return 0;
}
return 1;
}
#endif
void netboot(void) void netboot(void)
{ {
int size; int size;
@ -242,37 +284,13 @@ void netboot(void)
tftp_port = TFTP_SERVER_PORT; tftp_port = TFTP_SERVER_PORT;
printf("Fetching from: UDP/%d\n", tftp_port); printf("Fetching from: UDP/%d\n", tftp_port);
#ifdef NETBOOT_LINUX_VEXRISCV #if defined(CONFIG_CPU_TYPE_VEXRISCV) && defined(CONFIG_CPU_VARIANT_LINUX)
tftp_dst_addr = MAIN_RAM_BASE; if(try_get_kernel_rootfs_dtb_emulator(ip, tftp_port))
size = tftp_get_v(ip, tftp_port, "Image", (void *)tftp_dst_addr); {
if (size <= 0) { boot(0, 0, 0, MAIN_RAM_BASE + EMULATOR_IMAGE_RAM_OFFSET);
printf("Network boot failed\n");
return; return;
} }
#endif
tftp_dst_addr = MAIN_RAM_BASE + 0x00800000;
size = tftp_get_v(ip, tftp_port, "rootfs.cpio", (void *)tftp_dst_addr);
if(size <= 0) {
printf("No rootfs.cpio found\n");
return;
}
tftp_dst_addr = MAIN_RAM_BASE + 0x01000000;
size = tftp_get_v(ip, tftp_port, "rv32.dtb", (void *)tftp_dst_addr);
if(size <= 0) {
printf("No rv32.dtb found\n");
return;
}
tftp_dst_addr = EMULATOR_RAM_BASE;
size = tftp_get_v(ip, tftp_port, "emulator.bin", (void *)tftp_dst_addr);
if(size <= 0) {
printf("No emulator.bin found\n");
return;
}
boot(0, 0, 0, EMULATOR_RAM_BASE);
#else
tftp_dst_addr = MAIN_RAM_BASE; tftp_dst_addr = MAIN_RAM_BASE;
size = tftp_get_v(ip, tftp_port, "boot.bin", (void *)tftp_dst_addr); size = tftp_get_v(ip, tftp_port, "boot.bin", (void *)tftp_dst_addr);
if (size <= 0) { if (size <= 0) {
@ -281,34 +299,10 @@ void netboot(void)
} }
boot(0, 0, 0, MAIN_RAM_BASE); boot(0, 0, 0, MAIN_RAM_BASE);
#endif
} }
#endif #endif
#ifdef FLASHBOOT_LINUX_VEXRISCV
/* TODO: add configurable flash mapping, improve integration */
void flashboot(void)
{
printf("Loading Image from flash...\n");
memcpy((void *)MAIN_RAM_BASE + 0x00000000, (void *)0x50400000, 0x400000);
printf("Loading rootfs.cpio from flash...\n");
memcpy((void *)MAIN_RAM_BASE + 0x00800000, (void *)0x50800000, 0x700000);
printf("Loading rv32.dtb from flash...\n");
memcpy((void *)MAIN_RAM_BASE + 0x01000000, (void *)0x50f00000, 0x001000);
printf("Loading emulator.bin from flash...\n");
memcpy((void *)EMULATOR_RAM_BASE + 0x00000000, (void *)0x50f80000, 0x004000);
boot(0, 0, 0, EMULATOR_RAM_BASE);
}
#else
#ifdef FLASH_BOOT_ADDRESS #ifdef FLASH_BOOT_ADDRESS
/* On systems with exernal SDRAM we copy out of the SPI flash into the SDRAM /* On systems with exernal SDRAM we copy out of the SPI flash into the SDRAM
@ -321,38 +315,105 @@ void flashboot(void)
#define FIRMWARE_BASE_ADDRESS (FLASH_BOOT_ADDRESS + 2 * sizeof(unsigned int)) #define FIRMWARE_BASE_ADDRESS (FLASH_BOOT_ADDRESS + 2 * sizeof(unsigned int))
#endif #endif
void flashboot(void) static unsigned int check_image_in_flash(unsigned int *base_address)
{ {
unsigned int *flashbase;
unsigned int length; unsigned int length;
unsigned int crc; unsigned int crc;
unsigned int got_crc; unsigned int got_crc;
printf("Booting from flash...\n"); length = *base_address++;
flashbase = (unsigned int *)FLASH_BOOT_ADDRESS;
length = *flashbase++;
crc = *flashbase++;
if((length < 32) || (length > 4*1024*1024)) { if((length < 32) || (length > 4*1024*1024)) {
printf("Error: Invalid flash boot image length 0x%08x\n", length); printf("Error: Invalid image length 0x%08x\n", length);
return 0;
}
crc = *base_address++;
got_crc = crc32((unsigned char *)base_address, length);
if(crc != got_crc) {
printf("CRC failed (expected %08x, got %08x)\n", crc, got_crc);
return 0;
}
return length;
}
#if defined(MAIN_RAM_BASE) && defined(CONFIG_CPU_TYPE_VEXRISCV) && defined(CONFIG_CPU_VARIANT_LINUX)
static int copy_image_from_flash_to_ram(unsigned int *flash_address, unsigned int *ram_address)
{
unsigned int length;
length = check_image_in_flash(flash_address);
if(length > 0) {
// skip length and crc
memcpy((void *)ram_address, (void *)(flash_address + 2), length);
return 1;
}
return 0;
}
#endif
#define KERNEL_IMAGE_FLASH_OFFSET 0x00000000 // 0MB
#define ROOTFS_IMAGE_FLASH_OFFSET 0x00400000 // 4MB
#define DEVICE_TREE_IMAGE_FLASH_OFFSET 0x00B00000 // 11MB
#define EMULATOR_IMAGE_FLASH_OFFSET 0x00B01000 // 11MB + 4KB
void flashboot(void)
{
unsigned int length;
#if defined(MAIN_RAM_BASE) && defined(CONFIG_CPU_TYPE_VEXRISCV) && defined(CONFIG_CPU_VARIANT_LINUX)
unsigned int result;
printf("Loading emulator.bin from flash...\n");
result = copy_image_from_flash_to_ram(
(unsigned int *)(FLASH_BOOT_ADDRESS + EMULATOR_IMAGE_FLASH_OFFSET),
(unsigned int *)(MAIN_RAM_BASE + EMULATOR_IMAGE_RAM_OFFSET));
if(result) {
printf("Loading Image from flash...\n");
result &= copy_image_from_flash_to_ram(
(unsigned int *)FLASH_BOOT_ADDRESS + KERNEL_IMAGE_FLASH_OFFSET,
(unsigned int *)MAIN_RAM_BASE);
}
if(result) {
printf("Loading rootfs.cpio from flash...\n");
result &= copy_image_from_flash_to_ram(
(unsigned int *)(FLASH_BOOT_ADDRESS + ROOTFS_IMAGE_FLASH_OFFSET),
(unsigned int *)(MAIN_RAM_BASE + ROOTFS_IMAGE_RAM_OFFSET));
}
if(result) {
printf("Loading rv32.dtb from flash...\n");
result &= copy_image_from_flash_to_ram(
(unsigned int *)(FLASH_BOOT_ADDRESS + DEVICE_TREE_IMAGE_FLASH_OFFSET),
(unsigned int *)(MAIN_RAM_BASE + DEVICE_TREE_IMAGE_RAM_OFFSET));
}
if(result) {
boot(0, 0, 0, MAIN_RAM_BASE + EMULATOR_IMAGE_RAM_OFFSET);
return;
}
#endif
printf("Booting from flash...\n");
length = check_image_in_flash((unsigned int *)FLASH_BOOT_ADDRESS);
if(!length)
{
return; return;
} }
#ifdef MAIN_RAM_BASE #ifdef MAIN_RAM_BASE
printf("Loading %d bytes from flash...\n", length); printf("Loading %d bytes from flash...\n", length);
memcpy((void *)MAIN_RAM_BASE, flashbase, length); // skip length and crc
memcpy((void *)MAIN_RAM_BASE, (unsigned int *)(FLASH_BOOT_ADDRESS + 2 * sizeof(unsigned int)), length);
#endif #endif
got_crc = crc32((unsigned char *)FIRMWARE_BASE_ADDRESS, length);
if(crc != got_crc) {
printf("CRC failed (expected %08x, got %08x)\n", crc, got_crc);
return;
}
boot(0, 0, 0, FIRMWARE_BASE_ADDRESS); boot(0, 0, 0, FIRMWARE_BASE_ADDRESS);
} }
#endif #endif
#endif
#ifdef ROM_BOOT_ADDRESS #ifdef ROM_BOOT_ADDRESS
/* When firmware is small enough, it can be interesting to run code from an /* When firmware is small enough, it can be interesting to run code from an
embedded blockram memory (faster and not impacted by memory controller embedded blockram memory (faster and not impacted by memory controller