move flash-first-phase-initialisation to separate function
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 12 Apr 2022 13:22:33 +0000 (14:22 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 12 Apr 2022 13:22:33 +0000 (14:22 +0100)
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
hello_world/powerpc.lds [deleted file]

index 1cb82d4b3233a8d91915c381ab9dbdf4c05d5715..1eea544898f2ef666b1054c032e9f7040d6facde 100644 (file)
@@ -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 (file)
index f3901f4..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-SECTIONS
-{
-       _start = .;
-       start = _start;
-       . = 0;
-       .head : {
-               KEEP(*(.head))
-       }
-       . = 0x1000;
-       .text : { *(.text) }
-       . = 0x1800;
-       .data : { *(.data) }
-       .bss : { *(.bss) }
-}