]> xenbits.xensource.com Git - people/vhanquez/xen-unstable.git/commitdiff
arm: Move hyp-mode entry code out of line.
authorTim Deegan <tim@xen.org>
Fri, 1 Jun 2012 09:20:37 +0000 (10:20 +0100)
committerTim Deegan <tim@xen.org>
Fri, 1 Jun 2012 09:20:37 +0000 (10:20 +0100)
This code is grottier than the rest of the start-of-day code and
very specific to the software model we're developing on.
Segregate it accordingly, by putting it in its own file.

Signed-off-by: Tim Deegan <tim@xen.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/arm/Makefile
xen/arch/arm/head.S
xen/arch/arm/mode_switch.S [new file with mode: 0644]

index d5afb6ba9e997a9bda8894fde39e1add9842fddc..9440a218192072bd0c2084150f1c4f7076688011 100644 (file)
@@ -12,6 +12,7 @@ obj-y += io.o
 obj-y += irq.o
 obj-y += kernel.o
 obj-y += mm.o
+obj-y += mode_switch.o
 obj-y += p2m.o
 obj-y += percpu.o
 obj-y += guestcopy.o
index 1858eb35c8d7ff73a237d04304b77b623a24bfe6..9a7714a6127d601d8de4b855910d7ab35b291763 100644 (file)
@@ -122,50 +122,9 @@ boot_cpu:
 1:
        /* OK, we're in Secure state. */
        PRINT("- Started in Secure state -\r\n- Entering Hyp mode -\r\n")
-
-       /* Dance into Hyp mode */
-       cpsid aif, #0x16             /* Enter Monitor mode */
-       mrc   CP32(r0, SCR)
-       orr   r0, r0, #0x100         /* Set HCE */
-       orr   r0, r0, #0xb1          /* Set SCD, AW, FW and NS */
-       bic   r0, r0, #0xe           /* Clear EA, FIQ and IRQ */
-       mcr   CP32(r0, SCR)
-       /* Ugly: the system timer's frequency register is only
-        * programmable in Secure state.  Since we don't know where its
-        * memory-mapped control registers live, we can't find out the
-        * right frequency.  Use the VE model's default frequency here. */
-       ldr   r0, =0x5f5e100         /* 100 MHz */
-       mcr   CP32(r0, CNTFRQ)
-       ldr   r0, =0x40c00           /* SMP, c11, c10 in non-secure mode */
-       mcr   CP32(r0, NSACR)
-       /* Continuing ugliness: Set up the GIC so NS state owns interrupts */
-       mov   r0, #GIC_BASE_ADDRESS
-       add   r0, r0, #GIC_DR_OFFSET
-       mov   r1, #0
-       str   r1, [r0]               /* Disable delivery in the distributor */
-       add   r0, r0, #0x80          /* GICD_IGROUP0 */
-       mov   r2, #0xffffffff        /* All interrupts to group 1 */
-       str   r2, [r0]
-       str   r2, [r0, #4]
-       str   r2, [r0, #8]
-       /* Must drop priority mask below 0x80 before entering NS state */
-       mov   r0, #GIC_BASE_ADDRESS
-       add   r0, r0, #GIC_CR_OFFSET
-       ldr   r1, =0xff
-       str   r1, [r0, #0x4]         /* -> GICC_PMR */
-       /* Reset a few config registers */
-       mov   r0, #0
-       mcr   CP32(r0, FCSEIDR)
-       mcr   CP32(r0, CONTEXTIDR)
-       /* FIXME: ought to reset some other NS control regs here */
-       adr   r1, 1f
-       adr   r0, hyp                /* Store paddr (hyp entry point) */
-       str   r0, [r1]               /* where we can use it for RFE */
-       isb                          /* Ensure we see the stored target address */
-       rfeia r1                     /* Enter Hyp mode */
-
-1:     .word 0                      /* PC to enter Hyp mode at */
-       .word 0x000001da             /* CPSR: LE, Abort/IRQ/FIQ off, Hyp */
+       ldr   r0, =enter_hyp_mode    /* VA of function */
+       adr   lr, hyp                /* Set return address for call */
+       add   pc, r0, r10            /* Call PA of function */
 
 hyp:
        PRINT("- Setting up control registers -\r\n")
diff --git a/xen/arch/arm/mode_switch.S b/xen/arch/arm/mode_switch.S
new file mode 100644 (file)
index 0000000..71a21e7
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * xen/arch/arm/mode_switch.S
+ *
+ * Start-of day code to take a CPU from Secure mode to Hyp mode.
+ *
+ * Tim Deegan <tim@xen.org>
+ * Copyright (c) 2011-2012 Citrix Systems.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/config.h>
+#include <asm/page.h>
+#include <asm/asm_defns.h>
+
+/* Get up a CPU into Hyp mode.  Clobbers r0-r3.
+ *
+ * This code is specific to the VE model, and not intended to be used
+ * on production systems.  As such it's a bit hackier than the main
+ * boot code in head.S.  In future it will be replaced by better
+ * integration with the bootloader/firmware so that Xen always starts
+ * in Hyp mode. */
+
+.globl enter_hyp_mode
+enter_hyp_mode:
+       mov   r3, lr                 /* Put return address in non-banked reg */
+       cpsid aif, #0x16             /* Enter Monitor mode */
+       mrc   CP32(r0, SCR)
+       orr   r0, r0, #0x100         /* Set HCE */
+       orr   r0, r0, #0xb1          /* Set SCD, AW, FW and NS */
+       bic   r0, r0, #0xe           /* Clear EA, FIQ and IRQ */
+       mcr   CP32(r0, SCR)
+       /* Ugly: the system timer's frequency register is only
+        * programmable in Secure state.  Since we don't know where its
+        * memory-mapped control registers live, we can't find out the
+        * right frequency.  Use the VE model's default frequency here. */
+       ldr   r0, =0x5f5e100         /* 100 MHz */
+       mcr   CP32(r0, CNTFRQ)
+       ldr   r0, =0x40c00           /* SMP, c11, c10 in non-secure mode */
+       mcr   CP32(r0, NSACR)
+       /* Continuing ugliness: Set up the GIC so NS state owns interrupts */
+       mov   r0, #GIC_BASE_ADDRESS
+       add   r0, r0, #GIC_DR_OFFSET
+       mov   r1, #0
+       str   r1, [r0]               /* Disable delivery in the distributor */
+       add   r0, r0, #0x80          /* GICD_IGROUP0 */
+       mov   r2, #0xffffffff        /* All interrupts to group 1 */
+       str   r2, [r0]
+       str   r2, [r0, #4]
+       str   r2, [r0, #8]
+       /* Must drop priority mask below 0x80 before entering NS state */
+       mov   r0, #GIC_BASE_ADDRESS
+       add   r0, r0, #GIC_CR_OFFSET
+       ldr   r1, =0xff
+       str   r1, [r0, #0x4]         /* -> GICC_PMR */
+       /* Reset a few config registers */
+       mov   r0, #0
+       mcr   CP32(r0, FCSEIDR)
+       mcr   CP32(r0, CONTEXTIDR)
+       /* FIXME: ought to reset some other NS control regs here */
+       adr   r1, 1f                 /* Store return address */
+       str   r3, [r1]               /* where we can use it for RFE */
+       isb                          /* Ensure we see the stored address */
+       rfeia r1                     /* Enter Hyp mode */
+
+1:     .word 0                      /* PC to enter Hyp mode at */
+       .word 0x000001da             /* CPSR: LE, Abort/IRQ/FIQ off, Hyp */
+