DEFINES += -DUART_BASE=$(UART_BASE)
DEFINES += -DSTACK_SIZE=256
+if KERNEL_32
+DEFINES += -DKERNEL_32
+PSCI_CPU_ON := 0x84000003
+else
+PSCI_CPU_ON := 0xc4000003
+endif
+PSCI_CPU_OFF := 0x84000002
+
OFILES =
CFLAGS += -mgeneral-regs-only -mstrict-align
PSCI_NODE := psci { \
compatible = \"arm,psci\"; \
method = \"smc\"; \
- cpu_on = <0xc4000003>; \
- cpu_off = <0x84000002>; \
+ cpu_on = <$(PSCI_CPU_ON)>; \
+ cpu_off = <$(PSCI_CPU_OFF)>; \
};
CPU_NODES := $(shell $(top_srcdir)/gen-cpu-nodes.sh $(CPU_IDS))
CPUS_NODE := cpus { \
GIC := gic.o
endif
+if KERNEL_32
+MBOX_OFFSET := 0x7ff8
+KERNEL_OFFSET := 0x8000
+else
MBOX_OFFSET := 0xfff8
KERNEL_OFFSET := 0x80000
+endif
+
LD_SCRIPT := model.lds.S
IMAGE := linux-system.axf
1: mov x0, #0x30 // RES1
orr x0, x0, #(1 << 0) // Non-secure EL1
orr x0, x0, #(1 << 8) // HVC enable
+#ifndef KERNEL_32
orr x0, x0, #(1 << 10) // 64-bit EL2
+#endif
msr scr_el3, x0
msr cptr_el3, xzr // Disable copro. traps to EL3
mov x22, x3
mov x23, x4
+ ldr x0, =SCTLR_EL1_RESET
+ msr sctlr_el1, x0
+
ldr x0, =SCTLR_EL2_RESET
msr sctlr_el2, x0
br x19 // No EL3
1: mov x4, #SPSR_KERNEL
+
+ /*
+ * If bit 0 of the kernel address is set, we're entering in AArch32
+ * thumb mode. Set SPSR.T accordingly.
+ */
+ bfi x4, x19, #5, #1
+
msr elr_el3, x19
msr spsr_el3, x4
eret
#define SPSR_F (1 << 6) /* FIQ masked */
#define SPSR_T (1 << 5) /* Thumb */
#define SPSR_EL2H (9 << 0) /* EL2 Handler mode */
+#define SPSR_HYP (0x1a << 0) /* M[3:0] = hyp, M[4] = AArch32 */
+#define SCTLR_EL1_CP15BEN (1 << 5)
+#define SCTLR_EL1_RES1 (3 << 28 | 3 << 22 | 1 << 11)
+
+#ifdef KERNEL_32
+/* 32-bit kernel decompressor uses CP15 barriers */
+#define SCTLR_EL1_RESET (SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)
+#define SPSR_KERNEL (SPSR_A | SPSR_I | SPSR_F | SPSR_HYP)
+#else
+#define SCTLR_EL1_RESET SCTLR_EL1_RES1
#define SPSR_KERNEL (SPSR_A | SPSR_D | SPSR_I | SPSR_F | SPSR_EL2H)
+#endif
#ifndef __ASSEMBLY__
.endm
smc_entry32:
- mov w0, PSCI_RET_NOT_SUPPORTED
- eret
+ /* Clear upper bits */
+ mov w0, w0
+ /* Pass through */
smc_entry64:
/* SMC entry uses 112 bytes of stack */
stp x30, xzr, [sp, #-16]!
/* If function ID matches, do_call with procedure address in x7 */
+ branch_if PSCI_CPU_ON_32, psci_cpu_on
branch_if PSCI_CPU_ON_64, psci_cpu_on
branch_if PSCI_CPU_OFF, psci_cpu_off
}
if (is_entry)
+#ifdef KERNEL_32
+ jump_kernel(addr, 0, ~0, (unsigned long)&dtb, 0);
+#else
jump_kernel(addr, (unsigned long)&dtb, 0, 0, 0);
+#endif
jump_kernel(addr, 0, 0, 0, 0);
AM_INIT_AUTOMAKE([foreign])
+AC_ARG_ENABLE([aarch32-kernel],
+ AC_HELP_STRING([--enable-aarch32-kernel],
+ [start kernel in AArch32 instead of AArch64]),
+ [KERNEL_ES=32 USE_PSCI=yes AC_SUBST([KERNEL_32], [1]) AC_DEFINE([KERNEL_32])],
+ [KERNEL_ES=64])
+AM_CONDITIONAL([KERNEL_32], [test "x$KERNEL_ES" = x32])
+
# Allow a user to pass --with-kernel-dir
AC_ARG_WITH([kernel-dir],
AS_HELP_STRING([--with-kernel-dir], [specify the root Linux kernel build directory (required)]),
AC_SUBST([KERN_DIR], [$withval]),
AC_MSG_ERROR([No kernel directory specified. Use --with-kernel-dir]))
-KERN_IMAGE=$KERN_DIR/arch/arm64/boot/Image
+AS_IF([test "x$KERNEL_ES" = x32],
+ [KERN_IMAGE=$KERN_DIR/arch/arm/boot/zImage],
+ [KERN_IMAGE=$KERN_DIR/arch/arm64/boot/Image])
KERN_DTB=$KERN_DIR/arch/arm64/boot/dts/rtsm_ve-aemv8a.dtb
# Allow the user to override the default DTB
AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes"])
AS_IF([test "x$USE_PSCI" = "xyes"], [], [USE_PSCI=no])
+AS_IF([test "x$USE_PSCI" != "xyes" -a "x$KERNEL_ES" = "x32"],
+ [AC_MSG_ERROR([With an AArch32 kernel, boot method must be PSCI.])]
+)
+
# Allow a user to pass --with-cpu-ids
C_CPU_IDS="0x0,0x1,0x2,0x3"
AC_ARG_WITH(cpu-ids,
echo " Use PSCI? ${USE_PSCI}"
echo " CPU IDs: ${CPU_IDS}"
echo " Use GICv3? ${USE_GICV3}"
+echo " Kernel execution state: AArch${KERNEL_ES}"
echo ""
#define __PSCI_H
#define PSCI_CPU_OFF 0x84000002
+#define PSCI_CPU_ON_32 0x84000003
#define PSCI_CPU_ON_64 0xc4000003
#define PSCI_RET_SUCCESS 0