summaryrefslogtreecommitdiffstats
path: root/hw/arm/boot.c
diff options
context:
space:
mode:
authorPeter Maydell2016-02-04 12:06:35 +0100
committerPeter Maydell2016-02-04 12:06:35 +0100
commit071aacc9c9e15859500bbacf153e03b45008ee50 (patch)
tree1b0145834043ed90e4e051013c8229556bad65fc /hw/arm/boot.c
parentMerge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' int... (diff)
parentraspi: add raspberry pi 2 machine (diff)
downloadqemu-071aacc9c9e15859500bbacf153e03b45008ee50.tar.gz
qemu-071aacc9c9e15859500bbacf153e03b45008ee50.tar.xz
qemu-071aacc9c9e15859500bbacf153e03b45008ee50.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160203' into staging
target-arm queue: * virt-acpi-build: add always-on property for timer * various fixes for EL2 and EL3 behaviour * arm: virt-acpi: each MADT.GICC entry as enabled unconditionally * target-arm: Don't report presence of EL2 if it doesn't exist * raspi: add raspberry pi 2 machine # gpg: Signature made Wed 03 Feb 2016 18:58:02 GMT using RSA key ID 14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" * remotes/pmaydell/tags/pull-target-arm-20160203: raspi: add raspberry pi 2 machine arm/boot: move highbank secure board setup code to common routine bcm2836: add bcm2836 SoC device bcm2836_control: add bcm2836 ARM control logic bcm2835_peripherals: add rollup device for bcm2835 peripherals bcm2835_ic: add bcm2835 interrupt controller bcm2835_property: add bcm2835 property channel bcm2835_mbox: add BCM2835 mailboxes target-arm: Don't report presence of EL2 if it doesn't exist libvixl: Avoid std::abs() of 64-bit type arm: virt-acpi: each MADT.GICC entry as enabled unconditionally target-arm: Implement the S2 MMU inputsize > pamax check target-arm: Rename check_s2_startlevel to check_s2_mmu_setup target-arm: Apply S2 MMU startlevel table size check to AArch64 hw/arm: Setup EL1 and EL2 in AArch64 mode for 64bit Linux boots target-arm: Make various system registers visible to EL3 virt-acpi-build: add always-on property for timer Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/arm/boot.c')
-rw-r--r--hw/arm/boot.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 7742dd3cb6..cce8c7cd1c 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -178,6 +178,57 @@ static void default_write_secondary(ARMCPU *cpu,
smpboot, fixupcontext);
}
+void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
+ const struct arm_boot_info *info,
+ hwaddr mvbar_addr)
+{
+ int n;
+ uint32_t mvbar_blob[] = {
+ /* mvbar_addr: secure monitor vectors
+ * Default unimplemented and unused vectors to spin. Makes it
+ * easier to debug (as opposed to the CPU running away).
+ */
+ 0xeafffffe, /* (spin) */
+ 0xeafffffe, /* (spin) */
+ 0xe1b0f00e, /* movs pc, lr ;SMC exception return */
+ 0xeafffffe, /* (spin) */
+ 0xeafffffe, /* (spin) */
+ 0xeafffffe, /* (spin) */
+ 0xeafffffe, /* (spin) */
+ 0xeafffffe, /* (spin) */
+ };
+ uint32_t board_setup_blob[] = {
+ /* board setup addr */
+ 0xe3a00e00 + (mvbar_addr >> 4), /* mov r0, #mvbar_addr */
+ 0xee0c0f30, /* mcr p15, 0, r0, c12, c0, 1 ;set MVBAR */
+ 0xee110f11, /* mrc p15, 0, r0, c1 , c1, 0 ;read SCR */
+ 0xe3800031, /* orr r0, #0x31 ;enable AW, FW, NS */
+ 0xee010f11, /* mcr p15, 0, r0, c1, c1, 0 ;write SCR */
+ 0xe1a0100e, /* mov r1, lr ;save LR across SMC */
+ 0xe1600070, /* smc #0 ;call monitor to flush SCR */
+ 0xe1a0f001, /* mov pc, r1 ;return */
+ };
+
+ /* check that mvbar_addr is correctly aligned and relocatable (using MOV) */
+ assert((mvbar_addr & 0x1f) == 0 && (mvbar_addr >> 4) < 0x100);
+
+ /* check that these blobs don't overlap */
+ assert((mvbar_addr + sizeof(mvbar_blob) <= info->board_setup_addr)
+ || (info->board_setup_addr + sizeof(board_setup_blob) <= mvbar_addr));
+
+ for (n = 0; n < ARRAY_SIZE(mvbar_blob); n++) {
+ mvbar_blob[n] = tswap32(mvbar_blob[n]);
+ }
+ rom_add_blob_fixed("board-setup-mvbar", mvbar_blob, sizeof(mvbar_blob),
+ mvbar_addr);
+
+ for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
+ board_setup_blob[n] = tswap32(board_setup_blob[n]);
+ }
+ rom_add_blob_fixed("board-setup", board_setup_blob,
+ sizeof(board_setup_blob), info->board_setup_addr);
+}
+
static void default_reset_secondary(ARMCPU *cpu,
const struct arm_boot_info *info)
{
@@ -488,7 +539,9 @@ static void do_cpu_reset(void *opaque)
* adjust.
*/
if (env->aarch64) {
+ env->cp15.scr_el3 |= SCR_RW;
if (arm_feature(env, ARM_FEATURE_EL2)) {
+ env->cp15.hcr_el2 |= HCR_RW;
env->pstate = PSTATE_MODE_EL2h;
} else {
env->pstate = PSTATE_MODE_EL1h;