summary refs log tree commit diff stats
path: root/hw/arm/boot.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-02-04 11:06:35 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-02-04 11:06:35 +0000
commit071aacc9c9e15859500bbacf153e03b45008ee50 (patch)
tree1b0145834043ed90e4e051013c8229556bad65fc /hw/arm/boot.c
parent382d34ff9fcc534db32d54eb82590de7c04f9b33 (diff)
parent1df7d1f9303aef9a2b1f703e887553416b7c0586 (diff)
downloadfocaccia-qemu-071aacc9c9e15859500bbacf153e03b45008ee50.tar.gz
focaccia-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;