From patchwork Tue Nov 3 14:13:09 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 55938 Delivered-To: patch@linaro.org Received: by 10.112.61.134 with SMTP id p6csp1865422lbr; Tue, 3 Nov 2015 06:27:18 -0800 (PST) X-Received: by 10.140.89.147 with SMTP id v19mr18817564qgd.11.1446560838647; Tue, 03 Nov 2015 06:27:18 -0800 (PST) Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id m18si22506450qgd.31.2015.11.03.06.27.18 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 03 Nov 2015 06:27:18 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:48884 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZtcYQ-0006u0-4o for patch@linaro.org; Tue, 03 Nov 2015 09:27:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55001) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZtcL5-0001hs-Q3 for qemu-devel@nongnu.org; Tue, 03 Nov 2015 09:13:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZtcL4-0007w0-J0 for qemu-devel@nongnu.org; Tue, 03 Nov 2015 09:13:31 -0500 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:35243) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZtcL4-0007sB-Bi for qemu-devel@nongnu.org; Tue, 03 Nov 2015 09:13:30 -0500 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1ZtcKt-0003Et-BB for qemu-devel@nongnu.org; Tue, 03 Nov 2015 14:13:19 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Tue, 3 Nov 2015 14:13:09 +0000 Message-Id: <1446559999-12413-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1446559999-12413-1-git-send-email-peter.maydell@linaro.org> References: <1446559999-12413-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Subject: [Qemu-devel] [PULL 03/13] arm: boot: Add board specific setup code API X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org From: Peter Crosthwaite 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 Signed-off-by: Peter Crosthwaite Message-id: 070295644c6ac84696d743913296e8cfefb48c15.1446182614.git.crosthwaite.peter@gmail.com Signed-off-by: Peter Maydell --- hw/arm/boot.c | 20 +++++++++++++++++++- include/hw/arm/arm.h | 10 ++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) -- 1.9.1 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); }; /**