ryu: Make kernel boot
BUG=chrome-os-partner:31356
BRANCH=None
TEST=With one more change required for relocation, we see kernel booting and crashing.
Change-Id: Id7a7c105e500516ba983ec277daa7c2352e4a6d0
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://chromium-review.googlesource.com/212575
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Commit-Queue: Furquan Shaikh <furquan@chromium.org>
Tested-by: Furquan Shaikh <furquan@chromium.org>
diff --git a/src/arch/arm/Makefile.inc b/src/arch/arm/Makefile.inc
index 7f9e3f3..bd391a2 100644
--- a/src/arch/arm/Makefile.inc
+++ b/src/arch/arm/Makefile.inc
@@ -15,11 +15,10 @@
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
##
-depthcharge-y += boot.c
ifeq ($(CONFIG_ARCH_ARM_V8),y)
-depthcharge-y += boot_asm64.S physmem_arm64.c
+depthcharge-y += boot_asm64.S physmem_arm64.c transition.S boot64.c
else
-depthcharge-y += boot_asm.S enter_trampoline.c physmem.c
+depthcharge-y += boot_asm.S enter_trampoline.c physmem.c boot.c
endif
readonly-y += commonparams.c
readwrite-y += commonparams.c
diff --git a/src/arch/arm/boot.c b/src/arch/arm/boot.c
index e35ff50..0178204 100644
--- a/src/arch/arm/boot.c
+++ b/src/arch/arm/boot.c
@@ -31,21 +31,13 @@
static inline uint32_t get_sctlr(void)
{
uint32_t val;
-#if CONFIG_ARCH_ARM_V8
- asm("mrs %0, sctlr_el2" : "=r" (val));
-#else
asm("mrc p15, 0, %0, c1, c0, 0" : "=r" (val));
-#endif
return val;
}
static inline void set_sctlr(uint32_t val)
{
-#if CONFIG_ARCH_ARM_V8
- asm volatile("msr sctlr_el2, %0" :: "r" (val));
-#else
asm volatile("mcr p15, 0, %0, c1, c0, 0" :: "r" (val));
-#endif
asm volatile("" ::: "memory");
}
diff --git a/src/arch/arm/boot64.c b/src/arch/arm/boot64.c
new file mode 100644
index 0000000..78ae7f5
--- /dev/null
+++ b/src/arch/arm/boot64.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <libpayload.h>
+
+#include "arch/arm/boot.h"
+#include "base/cleanup_funcs.h"
+#include "base/timestamp.h"
+#include "config.h"
+#include "vboot/boot.h"
+
+static inline uint32_t get_sctlr(void)
+{
+ uint32_t val;
+ asm("mrs %0, sctlr_el2" : "=r" (val));
+ return val;
+}
+
+static inline void set_sctlr(uint32_t val)
+{
+ asm volatile("msr sctlr_el2, %0" :: "r" (val));
+ asm volatile("" ::: "memory");
+}
+
+void boot_arm_linux_jump(void *entry, void *fdt)
+ __attribute__((noreturn));
+
+void switch_to_el2(void);
+
+int boot_arm_linux(uint32_t machine_type, void *fdt, void *entry)
+{
+ run_cleanup_funcs(CleanupOnHandoff);
+
+ static const uint32_t SctlrM = (0x1 << 0);
+ static const uint32_t SctlrC = (0x1 << 2);
+
+ uint32_t sctlr = get_sctlr();
+
+ timestamp_add_now(TS_START_KERNEL);
+
+ /* Flush dcache and icache to make loaded code visible. */
+ cache_sync_instructions();
+
+ /* Turn off the MMU. */
+ sctlr &= ~SctlrM;
+
+ /* Disable the data/unified cache. */
+ sctlr &= ~SctlrC;
+
+ set_sctlr(sctlr);
+
+ tlb_invalidate_all();
+
+ /* Switch to el2 before jump */
+ switch_to_el2();
+
+ printf("jumping to kernel\n");
+
+ boot_arm_linux_jump(entry, fdt);
+
+ return 0;
+}
diff --git a/src/arch/arm/boot_asm64.S b/src/arch/arm/boot_asm64.S
index 75eff48..c6f05fd 100644
--- a/src/arch/arm/boot_asm64.S
+++ b/src/arch/arm/boot_asm64.S
@@ -23,15 +23,21 @@
.global boot_arm_linux_jump
.type boot_arm_linux_jump, function
boot_arm_linux_jump:
- /* Entered with X0 = entry, X1 = machine_type, X2 = &fdt */
+ /* Entered with X0 = entry, X1 = &fdt */
/* Linux ABI expects masking of Debug, SError, IRQ and FIQ */
- mov x3, #0x3c0
- msr daif, x3
-
+ msr daifset, #0xf
mov x4, x0 /* save entry pointer */
- mov x0, x2 /* X0 = physical address of dtb */
+ mov x0, x1 /* X0 = physical address of dtb */
mov x1, #0 /* X1 = 0 */
mov x2, #0 /* X2 = 0 */
mov x3, #0 /* X3 = 0 */
+
+ mrs x5, sctlr_el2
+ /* turn off mmu and disable caching */
+ and x5, x5, #~1
+ and x5, x5, #~(1<<2)
+ and x5, x5, #~(1<<12)
+ msr sctlr_el2, x5
+
br x4 /* jump to entry pointer */
diff --git a/src/arch/arm/transition.S b/src/arch/arm/transition.S
new file mode 100644
index 0000000..1d360a1
--- /dev/null
+++ b/src/arch/arm/transition.S
@@ -0,0 +1,30 @@
+.section .text, "ax", %progbits
+ .global switch_to_el2
+ .align 4
+switch_to_el2:
+ mov x0, #0x531
+ msr scr_el3, x0
+ mrs x0, SCTLR_EL2
+ ldr x1, .SCTLR_MASK
+ and x0, x0, x1
+ msr SCTLR_EL2, x0
+ mrs x0, vbar_el3
+ msr vbar_el2, x0
+ mov x0, #0x3c8
+ msr spsr_el3, x0
+ mrs x0, mair_el3
+ msr mair_el2, x0
+ mrs x0, tcr_el3
+ msr tcr_el2, x0
+ mrs x0, ttbr0_el3
+ msr ttbr0_el2, x0
+ mrs x0, sctlr_el2
+ orr x0, x0, #1
+ orr x0, x0, #1 << 2
+ orr x0, x0, #1 << 12
+ msr sctlr_el2, x0
+ msr elr_el3, x30
+ eret
+ .align 4
+ .SCTLR_MASK:
+ .quad 0x0FFFFEFF0