diff mbox

[RFC,1/3] arm: boot: Add board specific setup code API

Message ID 2e804dcfc24ce25676517ae8b00e11368e904ab6.1443931379.git.crosthwaite.peter@gmail.com
State New
Headers show

Commit Message

Peter Crosthwaite Oct. 10, 2015, 3:13 a.m. UTC
Add an API for boards to inject their own preboot software (or
firmware) seqeuence.

The software then returns to bootloader via the link register. This
allows boards to do their own little bits of firmware setup without
needed to replace the bootloader completely (which is the requirement
for existing firmware support).

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 hw/arm/boot.c        | 11 +++++++++++
 include/hw/arm/arm.h |  7 +++++++
 2 files changed, 18 insertions(+)
diff mbox

Patch

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index bef451b..a0dd1df 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -31,6 +31,7 @@  typedef enum {
     FIXUP_NONE = 0,   /* do nothing */
     FIXUP_TERMINATOR, /* end of insns */
     FIXUP_BOARDID,    /* overwrite with board ID number */
+    FIXUP_BOARDSETUP, /* overwrite with board specific setup code address */
     FIXUP_ARGPTR,     /* overwrite with pointer to kernel args */
     FIXUP_ENTRYPOINT, /* overwrite with kernel entry point */
     FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
@@ -60,6 +61,11 @@  static const ARMInsnFixup bootloader_aarch64[] = {
 
 /* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
 static const ARMInsnFixup bootloader[] = {
+    { 0xe28fe008 }, /* add     lr, pc, #8 */
+    { 0xe59ff000 }, /* ldr     pc, [pc, #0] */
+    { 0 },
+    { 0, FIXUP_BOARDSETUP },
+#define BOOTLOADER_NO_BOARDSETUP_OFFSET 4
     { 0xe3a00000 }, /* mov     r0, #0 */
     { 0xe59f1004 }, /* ldr     r1, [pc, #4] */
     { 0xe59f2004 }, /* ldr     r2, [pc, #4] */
@@ -131,6 +137,7 @@  static void write_bootloader(const char *name, hwaddr addr,
         case FIXUP_NONE:
             break;
         case FIXUP_BOARDID:
+        case FIXUP_BOARDSETUP:
         case FIXUP_ARGPTR:
         case FIXUP_ENTRYPOINT:
         case FIXUP_GIC_CPU_IF:
@@ -640,6 +647,9 @@  static void arm_load_kernel_notify(Notifier *notifier, void *data)
         elf_machine = EM_AARCH64;
     } else {
         primary_loader = bootloader;
+        if (!info->board_setup_blob) {
+            primary_loader += BOOTLOADER_NO_BOARDSETUP_OFFSET;
+        }
         kernel_load_offset = KERNEL_LOAD_ADDR;
         elf_machine = EM_ARM;
     }
@@ -745,6 +755,7 @@  static void arm_load_kernel_notify(Notifier *notifier, void *data)
         info->initrd_size = initrd_size;
 
         fixupcontext[FIXUP_BOARDID] = info->board_id;
+        fixupcontext[FIXUP_BOARDSETUP] = info->board_setup_blob_addr;
 
         /* for device tree boot, we pass the DTB directly in r2. Otherwise
          * we point to the kernel args.
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 4dcd4f9..0e3a652 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -87,6 +87,13 @@  struct arm_boot_info {
      * -pflash. It also implies that fw_cfg_find() will succeed.
      */
     bool firmware_loaded;
+
+    /* Address as which board specific loader/setup code exists. If enabled,
+     * this code-blob will run before anything else. It must return to the
+     * caller via the link register. There is no stack setup.
+     */
+    bool board_setup_blob;
+    hwaddr board_setup_blob_addr;
 };
 
 /**