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