Initial version of the AArch64 Linux boot wrapper

This boot wrapper contains the code for initialising the ARMv8 software
model before the Linux kernel can run (see
Documentation/arm64/booting.txt in the kernel tree for the Linux booting
requirements).

Running "make" creates a "linux-system.axf" ELF file that can be loaded
by the software model.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..20026d8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+linux-system.axf
+Image
+model.lds
+boot.o
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d68a74e
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,28 @@
+Copyright (c) 2012, ARM Limited
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of ARM nor the names of its contributors may be
+      used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5e8b154
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,79 @@
+#
+# Makefile - build a kernel+filesystem image for stand-alone Linux booting
+#
+# Copyright (C) 2012 ARM Limited. All rights reserved.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE.txt file.
+
+# VE
+PHYS_OFFSET	:= 0x80000000
+UART_BASE	:= 0x1c090000
+GIC_DIST_BASE	:= 0x2c001000
+GIC_CPU_BASE	:= 0x2c002000
+CNTFRQ		:= 0x01800000	# 24Mhz
+
+#INITRD_FLAGS	:= -DUSE_INITRD
+CPPFLAGS	+= $(INITRD_FLAGS)
+
+BOOTLOADER	:= boot.S
+MBOX_OFFSET	:= 0xfff8
+KERNEL		:= Image
+KERNEL_OFFSET	:= 0x80000
+LD_SCRIPT	:= model.lds.S
+IMAGE		:= linux-system.axf
+
+FILESYSTEM	:= filesystem.cpio.gz
+FS_OFFSET	:= 0x10000000
+FILESYSTEM_START:= $(shell echo $$(($(PHYS_OFFSET) + $(FS_OFFSET))))
+FILESYSTEM_SIZE	:= $(shell stat -Lc %s $(FILESYSTEM) 2>/dev/null || echo 0)
+FILESYSTEM_END	:= $(shell echo $$(($(FILESYSTEM_START) + $(FILESYSTEM_SIZE))))
+
+FDT_SRC		:= vexpress-v2p-aarch64.dts
+FDT_INCL_REGEX	:= \(/include/[[:space:]]*"\)\([^"]\+\)\(".*\)
+FDT_DEPS	:= $(FDT_SRC) $(addprefix $(dir $(FDT_SRC)), $(shell sed -ne 'sq$(strip $(FDT_INCL_REGEX)q\2q p' < $(FDT_SRC))))
+FDT_OFFSET	:= 0x08000000
+
+ifneq (,$(findstring USE_INITRD,$(CPPFLAGS)))
+BOOTARGS	:= "console=ttyAMA0 $(BOOTARGS_EXTRA)"
+CHOSEN_NODE	:= chosen {						\
+			bootargs = $(BOOTARGS);				\
+			linux,initrd-start = <$(FILESYSTEM_START)>;	\
+			linux,initrd-end = <$(FILESYSTEM_END)>;		\
+		   };
+else
+BOOTARGS	:= "console=ttyAMA0 root=/dev/nfs nfsroot=10.1.69.68:/work/debootstrap/aarch64,tcp rw ip=dhcp $(BOOTARGS_EXTRA)"
+CHOSEN_NODE	:= chosen {						\
+			bootargs = $(BOOTARGS);				\
+		   };
+endif
+
+CROSS_COMPILE	:= aarch64-none-linux-gnu-
+CC		:= $(CROSS_COMPILE)gcc
+LD		:= $(CROSS_COMPILE)ld
+DTC		:= $(if $(wildcard ./dtc), ./dtc, $(shell which dtc))
+
+all: $(IMAGE)
+
+clean:
+	rm -f $(IMAGE) boot.o model.lds fdt.dtb
+
+$(IMAGE): boot.o model.lds fdt.dtb $(KERNEL) $(FILESYSTEM)
+	$(LD) -o $@ --script=model.lds
+
+boot.o: $(BOOTLOADER) Makefile
+	$(CC) $(CPPFLAGS) -DCNTFRQ=$(CNTFRQ) -DUART_BASE=$(UART_BASE) -DSYS_FLAGS=$(SYS_FLAGS) -DGIC_DIST_BASE=$(GIC_DIST_BASE) -DGIC_CPU_BASE=$(GIC_CPU_BASE) -c -o $@ $(BOOTLOADER)
+
+model.lds: $(LD_SCRIPT) Makefile
+	$(CC) $(CPPFLAGS) -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) -DKERNEL=$(KERNEL) -DFILESYSTEM=$(FILESYSTEM) -E -P -C -o $@ $<
+
+ifeq ($(DTC),)
+	$(error No dtc found! You can git clone from git://git.jdl.com/software/dtc.git)
+endif
+
+fdt.dtb: $(FDT_DEPS) Makefile
+	@sed -e 's%/\* chosen \*/%$(CHOSEN_NODE)%' -e 's%$(strip $(FDT_INCL_REGEX))%\1$(dir $(FDT_SRC))\2\3%' $< | \
+	$(DTC) -O dtb -o $@ -
+
+# The filesystem archive might not exist if INITRD is not being used
+.PHONY: all clean $(FILESYSTEM)
diff --git a/README b/README
new file mode 100644
index 0000000..d1e15c4
--- /dev/null
+++ b/README
@@ -0,0 +1,14 @@
+Linux boot wrapper with FDT support
+===================================
+
+The following files need to be linked into the boot wrapper directory:
+
+dtc			 - point to <linux-build-dir>/scripts/dtc/dtc
+vexpress-v2p-aarch64.dts - point to <linux-src-dir>/arch/arm64/boot/dts/vexpress-v2p-aarch64.dts
+vexpress-v2m-rs1.dtsi	 - point to <linux-src-dir>/arch/arm64/boot/dts/vexpress-v2m-rs1.dtsi
+skeleton.dtsi		 - point to <linux-src-dir>/arch/arm64/boot/dts/skeleton.dtsi
+
+Alternatively, you may specify the paths for dtc and the main dts file
+on the make command-line. For example:
+
+make DTC=<path-to-dtc> FDT_SRC=<linux-src-dir>/arch/arm64/boot/dts/vexpress-v2p-aarch64.dtsi
diff --git a/boot.S b/boot.S
new file mode 100644
index 0000000..27367d8
--- /dev/null
+++ b/boot.S
@@ -0,0 +1,110 @@
+/*
+ * boot.S - simple register setup code for stand-alone Linux booting
+ *
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+
+	.text
+
+	.globl	_start
+_start:
+	/*
+	 * EL3 initialisation
+	 */
+	mrs	x0, CurrentEL
+	cmp	x0, #0xc			// EL3?
+	b.ne	start_ns			// skip EL3 initialisation
+
+	mov	x0, #0x30			// RES1
+	orr	x0, x0, #(1 << 0)		// Non-secure EL1
+	orr	x0, x0, #(1 << 8)		// HVC enable
+	orr	x0, x0, #(1 << 10)		// 64-bit EL2
+	msr	scr_el3, x0
+
+	msr	cptr_el3, xzr			// Disable copro. traps to EL3
+
+	ldr	x0, =CNTFRQ
+	msr	cntfrq_el0, x0
+
+	/*
+	 * Check for the primary CPU to avoid a race on the distributor
+	 * registers.
+	 */
+	mrs	x0, mpidr_el1
+	tst	x0, #15
+	b.ne	1f				// secondary CPU
+
+	ldr	x1, =GIC_DIST_BASE		// GICD_CTLR
+	mov	w0, #3				// EnableGrp0 | EnableGrp1
+	str	w0, [x1]
+
+1:	ldr	x1, =GIC_DIST_BASE + 0x80	// GICD_IGROUPR
+	mov	w0, #~0				// Grp1 interrupts
+	str	w0, [x1], #4
+	b.ne	2f				// Only local interrupts for secondary CPUs
+	str	w0, [x1], #4
+	str	w0, [x1], #4
+
+2:	ldr	x1, =GIC_CPU_BASE		// GICC_CTLR
+	ldr	w0, [x1]
+	mov	w0, #3				// EnableGrp0 | EnableGrp1
+	str	w0, [x1]
+
+	mov	w0, #1 << 7			// allow NS access to GICC_PMR
+	str	w0, [x1, #4]			// GICC_PMR
+
+	msr	sctlr_el2, xzr
+
+	/*
+	 * Prepare the switch to the EL2_SP1 mode from EL3
+	 */
+	ldr	x0, =start_ns			// Return after mode switch
+	mov	x1, #0x3c9			// EL2_SP1 | D | A | I | F
+	msr	elr_el3, x0
+	msr	spsr_el3, x1
+	eret
+
+start_ns:
+	/*
+	 * Kernel parameters
+	 */
+	mov	x0, xzr
+	mov	x1, xzr
+	mov	x2, xzr
+	mov	x3, xzr
+
+	mrs	x4, mpidr_el1
+	tst	x4, #15
+	b.eq	2f
+
+	/*
+	 * Secondary CPUs
+	 */
+1:	wfe
+	ldr	x4, mbox
+	cbz	x4, 1b
+	br	x4				// branch to the given address
+
+2:
+	/*
+	 * UART initialisation (38400 8N1)
+	 */
+	ldr	x4, =UART_BASE			// UART base
+	mov	w5, #0x10			// ibrd
+	str	w5, [x4, #0x24]
+	mov	w5, #0xc300
+	orr	w5, w5, #0x0001			// cr
+	str	w5, [x4, #0x30]
+
+	/*
+	 * Primary CPU
+	 */
+	ldr	x0, =dtb			// device tree blob
+	b	kernel
+
+	.ltorg
+
+	.org	0x200
diff --git a/model.lds.S b/model.lds.S
new file mode 100644
index 0000000..ec27433
--- /dev/null
+++ b/model.lds.S
@@ -0,0 +1,45 @@
+/*
+ * model.lds.S - simple linker script for stand-alone Linux booting
+ *
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+
+OUTPUT_FORMAT("elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+TARGET(binary)
+
+INPUT(./boot.o)
+INPUT(KERNEL)
+INPUT(./fdt.dtb)
+
+#ifdef USE_INITRD
+INPUT(FILESYSTEM)
+#endif
+
+SECTIONS
+{
+	. = PHYS_OFFSET;
+	.text : { boot.o }
+	. = PHYS_OFFSET + MBOX_OFFSET;
+	mbox = .;
+	.mbox : { QUAD(0x0) }
+	. = PHYS_OFFSET + KERNEL_OFFSET;
+	kernel = .;
+	.kernel : { KERNEL }
+
+	. = PHYS_OFFSET + FDT_OFFSET;
+	dtb = .;
+	.dtb : { ./fdt.dtb }
+	. = PHYS_OFFSET + FS_OFFSET;
+	filesystem = .;
+#ifdef USE_INITRD
+	.filesystem : { FILESYSTEM }
+	fs_size = . - filesystem;
+#endif
+
+	.data : { *(.data) }
+	.bss : { *(.bss) }
+}