From cae48c32456f7b2c7c203c93f7d9481e2ee2dd3f Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Tue, 12 Apr 2022 14:22:33 +0100 Subject: [PATCH] move flash-first-phase-initialisation to separate function attempting to execute directly from flash by jumping to it (after making it run a leeetle bit faster than 100 bytes/sec) --- coldboot/coldboot.c | 49 ++++++++++++++++++++++++++++------------- hello_world/powerpc.lds | 14 ------------ 2 files changed, 34 insertions(+), 29 deletions(-) delete mode 100644 hello_world/powerpc.lds diff --git a/coldboot/coldboot.c b/coldboot/coldboot.c index 1cb82d4..1eea544 100644 --- a/coldboot/coldboot.c +++ b/coldboot/coldboot.c @@ -93,22 +93,13 @@ static inline void write_tercel_register(uint8_t reg, uint32_t value) // TODO: need to use this // https://gitlab.raptorengineering.com/kestrel-collaboration/kestrel-firmware/bare-metal-firmware/-/blob/master/main.c#L2328 -static bool fl_read(void *dst, uint32_t offset, uint32_t size) -{ - uint8_t *d = dst; - memcpy(d, (void *)(unsigned long)(SPI_FLASH_BASE + offset), size); - return true; -} -static unsigned long copy_flash(unsigned int offset, unsigned int dst_offs) +/* this is a "level 1" speed-up, which gets an initial improvement of 10-50x + * over the default speed (which is a scant 100 bytes per second). + */ +static void crank_up_qspi_level1(void) { - Elf64_Ehdr ehdr; - Elf64_Phdr ph; - unsigned int i, poff, size, off; - void *addr; - - // WARNING - // KESTREL SPECIFIC + // WARNING: KESTREL SPECIFIC // Set SPI clock cycle divider to 1 uint32_t dword; dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1); @@ -122,6 +113,21 @@ static unsigned long copy_flash(unsigned int offset, unsigned int dst_offs) dword |= (TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK << TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT); write_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5, dword); +} + +static bool fl_read(void *dst, uint32_t offset, uint32_t size) +{ + uint8_t *d = dst; + memcpy(d, (void *)(unsigned long)(SPI_FLASH_BASE + offset), size); + return true; +} + +static unsigned long copy_flash(unsigned int offset, unsigned int dst_offs) +{ + Elf64_Ehdr ehdr; + Elf64_Phdr ph; + unsigned int i, poff, size, off; + void *addr; puts("Trying flash...\r\n"); if (!fl_read(&ehdr, offset, sizeof(ehdr))) @@ -241,6 +247,9 @@ int main(void) { puts("\r\n"); if (ftr & SYS_REG_INFO_HAS_SPI_FLASH) { + // speed up the QSPI to at least a sane level + crank_up_qspi_level1(); + puts("SPI Offset: "); spi_offs = readl(SYSCON_BASE + SYS_REG_SPI_INFO); uart_writeuint32(spi_offs); @@ -262,7 +271,7 @@ int main(void) { puts("\n"); } #endif - volatile uint32_t *qspi = (uint32_t*)SPI_FLASH_BASE+spi_offs; + volatile uint32_t *qspi = (uint32_t*)SPI_FLASH_BASE; //volatile uint8_t *qspi_bytes = (uint8_t*)spi_offs; // let's not, eh? writel(0xDEAF0123, (unsigned long)&(qspi[0])); // tmp = readl((unsigned long)&(qspi[0])); @@ -482,6 +491,16 @@ int main(void) { #endif puts("done\n"); + // temporary hard-hack: boot directly from QSPI. really + // should do something like detect at least... something + if ((ftr & SYS_REG_INFO_HAS_SPI_FLASH)) + { + // jump to absolute address + mtspr(8, spi_offs); // move address to LR + __asm__ volatile("blr"); + return 0; + } + // memcpy from SPI Flash then boot if ((ftr & SYS_REG_INFO_HAS_SPI_FLASH) && (failcnt == 0)) diff --git a/hello_world/powerpc.lds b/hello_world/powerpc.lds deleted file mode 100644 index f3901f4..0000000 --- a/hello_world/powerpc.lds +++ /dev/null @@ -1,14 +0,0 @@ -SECTIONS -{ - _start = .; - start = _start; - . = 0; - .head : { - KEEP(*(.head)) - } - . = 0x1000; - .text : { *(.text) } - . = 0x1800; - .data : { *(.data) } - .bss : { *(.bss) } -} -- 2.30.2