// 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);
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)))
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);
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]));
#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))