[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 03/13] arm: boot: Add board specific setup code API
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 03/13] arm: boot: Add board specific setup code API |
Date: |
Tue, 3 Nov 2015 14:13:09 +0000 |
From: Peter Crosthwaite <address@hidden>
Add an API for boards to inject their own preboot software (or
firmware) sequence.
The software then returns to the 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).
The blob is loaded by a callback if and only if doing a linux boot
(similar to the existing write_secondary support).
Rewrite the comment for the primary boot blob.
Reviewed-by: Peter Maydell <address@hidden>
Signed-off-by: Peter Crosthwaite <address@hidden>
Message-id: address@hidden
Signed-off-by: Peter Maydell <address@hidden>
---
hw/arm/boot.c | 20 +++++++++++++++++++-
include/hw/arm/arm.h | 10 ++++++++++
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 2a151e2..b0879a5 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_BOARD_SETUP, /* 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 */
@@ -58,8 +59,17 @@ static const ARMInsnFixup bootloader_aarch64[] = {
{ 0, FIXUP_TERMINATOR }
};
-/* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
+/* A very small bootloader: call the board-setup code (if needed),
+ * set r0-r2, then jump to the kernel.
+ * If we're not calling boot setup code then we don't copy across
+ * the first BOOTLOADER_NO_BOARD_SETUP_OFFSET insns in this array.
+ */
+
static const ARMInsnFixup bootloader[] = {
+ { 0xe28fe008 }, /* add lr, pc, #8 */
+ { 0xe51ff004 }, /* ldr pc, [pc, #-4] */
+ { 0, FIXUP_BOARD_SETUP },
+#define BOOTLOADER_NO_BOARD_SETUP_OFFSET 3
{ 0xe3a00000 }, /* mov r0, #0 */
{ 0xe59f1004 }, /* ldr r1, [pc, #4] */
{ 0xe59f2004 }, /* ldr r2, [pc, #4] */
@@ -131,6 +141,7 @@ static void write_bootloader(const char *name, hwaddr addr,
case FIXUP_NONE:
break;
case FIXUP_BOARDID:
+ case FIXUP_BOARD_SETUP:
case FIXUP_ARGPTR:
case FIXUP_ENTRYPOINT:
case FIXUP_GIC_CPU_IF:
@@ -640,6 +651,9 @@ static void arm_load_kernel_notify(Notifier *notifier, void
*data)
elf_machine = EM_AARCH64;
} else {
primary_loader = bootloader;
+ if (!info->write_board_setup) {
+ primary_loader += BOOTLOADER_NO_BOARD_SETUP_OFFSET;
+ }
kernel_load_offset = KERNEL_LOAD_ADDR;
elf_machine = EM_ARM;
}
@@ -745,6 +759,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void
*data)
info->initrd_size = initrd_size;
fixupcontext[FIXUP_BOARDID] = info->board_id;
+ fixupcontext[FIXUP_BOARD_SETUP] = info->board_setup_addr;
/* for device tree boot, we pass the DTB directly in r2. Otherwise
* we point to the kernel args.
@@ -793,6 +808,9 @@ static void arm_load_kernel_notify(Notifier *notifier, void
*data)
if (info->nb_cpus > 1) {
info->write_secondary_boot(cpu, info);
}
+ if (info->write_board_setup) {
+ info->write_board_setup(cpu, info);
+ }
/* Notify devices which need to fake up firmware initialization
* that we're doing a direct kernel boot.
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 4dcd4f9..9217b70 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -87,6 +87,16 @@ struct arm_boot_info {
* -pflash. It also implies that fw_cfg_find() will succeed.
*/
bool firmware_loaded;
+
+ /* Address at 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 set up. Enabled by
+ * defining write_board_setup, which is responsible for loading the blob
+ * to the specified address.
+ */
+ hwaddr board_setup_addr;
+ void (*write_board_setup)(ARMCPU *cpu,
+ const struct arm_boot_info *info);
};
/**
--
1.9.1
- [Qemu-devel] [PULL 00/13] target-arm queue, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 11/13] hw/arm/virt-acpi-build: _CCA attribute is compulsory, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 09/13] target-arm: Bring AArch64 debug CPU display of PSTATE into line with AArch32, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 04/13] arm: xilinx_zynq: Add linux pre-boot, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 10/13] target-arm: Report S/NS status in the CPU debug logs, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 07/13] arm: stellaris: exit on external reset request, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 13/13] ARM: ACPI: Fix MPIDR value in ACPI table, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 03/13] arm: boot: Add board specific setup code API,
Peter Maydell <=
- [Qemu-devel] [PULL 08/13] MAINTAINERS: Add new qemu-arm mailing list to ARM related entries, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 05/13] armv7-m: Return DeviceState* from armv7m_init(), Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 12/13] hw/arm/virt-acpi-build: Add GICC ACPI subtable for GICv3, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 02/13] arm: boot: Adjust indentation of FIXUP comments, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 01/13] target-arm: Add and use symbolic names for register banks, Peter Maydell, 2015/11/03
- [Qemu-devel] [PULL 06/13] armv7-m: Implement SYSRESETREQ, Peter Maydell, 2015/11/03
- Re: [Qemu-devel] [PULL 00/13] target-arm queue, Peter Maydell, 2015/11/03