aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-04-24 16:17:22 +0100
committerMark Rutland <mark.rutland@arm.com>2014-05-09 18:43:52 +0100
commit09d7031d5642ff1d81c0dede9b86822d67b6b52a (patch)
tree3e2df770dca9c7ee67f167930f81d80789e94e45
parent1a5cc50778aadad8f7cde86940dc7ab6a54395f3 (diff)
downloadboot-wrapper-aarch64-09d7031d5642ff1d81c0dede9b86822d67b6b52a.tar.gz
boot-wrapper: arm64: add support for GICv3
Performs the minimal initialization required for GICv3 support. Support can be enabled with --enable-gicv3. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
-rw-r--r--Makefile.am24
-rw-r--r--configure.ac9
-rw-r--r--gic-v3.S89
-rw-r--r--model.lds.S4
4 files changed, 117 insertions, 9 deletions
diff --git a/Makefile.am b/Makefile.am
index 2f69061..aa4e572 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,14 +11,10 @@
PHYS_OFFSET := $(shell $(top_srcdir)/findmem.pl $(KERNEL_DTB))
UART_BASE := $(shell $(top_srcdir)/findbase.pl $(KERNEL_DTB) 0 'arm,pl011')
SYSREGS_BASE := $(shell $(top_srcdir)/findbase.pl $(KERNEL_DTB) 0 'arm,vexpress-sysreg')
-GIC_DIST_BASE := $(shell $(top_srcdir)/findbase.pl $(KERNEL_DTB) 0 'arm,cortex-a15-gic')
-GIC_CPU_BASE := $(shell $(top_srcdir)/findbase.pl $(KERNEL_DTB) 1 'arm,cortex-a15-gic')
CNTFRQ := 0x01800000 # 24Mhz
DEFINES = -DCNTFRQ=$(CNTFRQ)
DEFINES += -DCPU_IDS=$(CPU_IDS)
-DEFINES += -DGIC_CPU_BASE=$(GIC_CPU_BASE)
-DEFINES += -DGIC_DIST_BASE=$(GIC_DIST_BASE)
DEFINES += -DSYSREGS_BASE=$(SYSREGS_BASE)
DEFINES += -DUART_BASE=$(UART_BASE)
@@ -42,6 +38,20 @@ PSCI_NODE :=
CPUS_NODE :=
endif
+if GICV3
+GIC_DIST_BASE := $(shell $(top_srcdir)/findbase.pl $(KERNEL_DTB) 0 'arm,gic-v3')
+GIC_RDIST_BASE := $(shell $(top_srcdir)/findbase.pl $(KERNEL_DTB) 1 'arm,gic-v3')
+DEFINES += -DGIC_DIST_BASE=$(GIC_DIST_BASE)
+DEFINES += -DGIC_RDIST_BASE=$(GIC_RDIST_BASE)
+GIC := gic-v3.o
+else
+GIC_DIST_BASE := $(shell $(top_srcdir)/findbase.pl $(KERNEL_DTB) 0 'arm,cortex-a15-gic')
+GIC_CPU_BASE := $(shell $(top_srcdir)/findbase.pl $(KERNEL_DTB) 1 'arm,cortex-a15-gic')
+DEFINES += -DGIC_CPU_BASE=$(GIC_CPU_BASE)
+DEFINES += -DGIC_DIST_BASE=$(GIC_DIST_BASE)
+GIC := gic.o
+endif
+
MBOX_OFFSET := 0xfff8
KERNEL_OFFSET := 0x80000
LD_SCRIPT := model.lds.S
@@ -72,16 +82,16 @@ CPPFLAGS += $(INITRD_FLAGS)
all: $(IMAGE)
-CLEANFILES = $(IMAGE) boot.o cache.o gic.o mmu.o ns.o $(BOOTMETHOD) model.lds fdt.dtb
+CLEANFILES = $(IMAGE) boot.o cache.o $(GIC) mmu.o ns.o $(BOOTMETHOD) model.lds fdt.dtb
-$(IMAGE): boot.o cache.o gic.o mmu.o ns.o $(BOOTMETHOD) model.lds fdt.dtb $(KERNEL_IMAGE) $(FILESYSTEM)
+$(IMAGE): boot.o cache.o $(GIC) mmu.o ns.o $(BOOTMETHOD) model.lds fdt.dtb $(KERNEL_IMAGE) $(FILESYSTEM)
$(LD) -o $@ --script=model.lds
%.o: %.S Makefile
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $<
model.lds: $(LD_SCRIPT) Makefile
- $(CPP) $(CPPFLAGS) -ansi -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) -DKERNEL=$(KERNEL_IMAGE) -DFILESYSTEM=$(FILESYSTEM) -DBOOTMETHOD=$(BOOTMETHOD) -P -C -o $@ $<
+ $(CPP) $(CPPFLAGS) -ansi -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) -DKERNEL=$(KERNEL_IMAGE) -DFILESYSTEM=$(FILESYSTEM) -DBOOTMETHOD=$(BOOTMETHOD) -DGIC=$(GIC) -P -C -o $@ $<
fdt.dtb: $(KERNEL_DTB) Makefile gen-cpu-nodes.sh
( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) $(CPUS_NODE) };" ) | $(DTC) -O dtb -o $@ -
diff --git a/configure.ac b/configure.ac
index 40d36a0..b60f869 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,6 +68,14 @@ AC_ARG_WITH([cmdline],
[C_CMDLINE=$withval])
AC_SUBST([CMDLINE], [$C_CMDLINE])
+# Allow a user to pass --enable-gicv3
+USE_GICV3=no
+AC_ARG_ENABLE([gicv3],
+ AS_HELP_STRING([--enable-gicv3], [enable GICv3 instead of GICv2]),
+ [USE_GICV3=yes],
+ [USE_GICV3=no])
+AM_CONDITIONAL([GICV3], [test "x$USE_GICV3" = "xyes"])
+
# Ensure that we have all the needed programs
AC_PROG_CC
AC_PROG_CPP
@@ -95,4 +103,5 @@ echo " Linux kernel command line: ${CMDLINE}"
echo " Embedded initrd: ${FILESYSTEM:-NONE}"
echo " Use PSCI? ${USE_PSCI}"
echo " CPU IDs: ${CPU_IDS}"
+echo " Use GICv3? ${USE_GICV3}"
echo ""
diff --git a/gic-v3.S b/gic-v3.S
new file mode 100644
index 0000000..7bf3c54
--- /dev/null
+++ b/gic-v3.S
@@ -0,0 +1,89 @@
+/*
+ * gic.S - Secure gic initialisation for stand-alone Linux booting
+ *
+ * Copyright (C) 2013 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.
+ */
+
+#include "common.S"
+
+ .text
+
+ .global gic_secure_init
+
+gic_secure_init:
+ /*
+ * Only the primary CPU setups the (re)distributors.
+ */
+ mrs x0, mpidr_el1
+ ldr x1, =MPIDR_ID_BITS
+ tst x0, x1
+ b.ne setup_cpu_if // secondary CPU
+
+ ldr x1, =GIC_DIST_BASE // GICD_CTLR
+ mov w0, #7 // EnableGrp0 | EnableGrp1ns | EnableGrp1s
+ orr w0, w0, #(3 << 4) // ARE_S | ARE_NS
+ str w0, [x1]
+
+ ldr x2, =GIC_RDIST_BASE
+
+ mvn w5, wzr
+
+next_rdist:
+ movn w6, #(1 << 1) // ProcessorSleep
+ ldr w4, [x2, #0x014] // GICR_WAKER
+ and w4, w4, w6 // Clear ProcessorSleep
+ str w4, [x2, #0x014] // GICR_WAKER
+ dsb st
+ isb
+
+1: ldr w4, [x2, #0x014] // GICR_WAKER
+ ands wzr, w4, #(1 << 2) // Test ChildrenAsleep
+ b.ne 1b
+
+ add x3, x2, #(1 << 16) // SGI_base
+
+ str w5, [x3, #0x80] // GICR_IGROUP0
+ str wzr, [x3, #0xD00] // GICR_IGRPMOD0
+
+ ldr w4, [x2, #8] // GICR_TYPER
+ add x3, x3, #(1 << 16) // Next redist
+ tbz w4, #1, 2f // if VLPIS is set,
+ add x3, x3, #(2 << 16) // it is two page further away
+2: mov x2, x3
+ tbz w4, #4, next_rdist
+
+ ldr w2, [x1, #4] // GICD_TYPER
+ and w2, w2, #0x1f // ITLinesNumber
+ cbz w2, setup_cpu_if
+
+ add x3, x1, #0x84 // GICD_IGROUP1
+ add x4, x1, #0xD04 // GICD_IGRPMOD1
+
+1: str w5, [x3], #4
+ str wzr, [x4], #4
+ sub w2, w2, #1
+ cbnz w2, 1b
+
+setup_cpu_if:
+
+#define ICC_SRE_EL2 S3_4_C12_C9_5
+#define ICC_SRE_EL3 S3_6_C12_C12_5
+#define ICC_CTLR_EL1 S3_0_C12_C12_4
+#define ICC_CTLR_EL3 S3_6_C12_C12_4
+#define ICC_PMR_EL1 S3_0_C4_C6_0
+
+ // Enable SRE at EL3 and ICC_SRE_EL2 access
+ mov x0, #((1 << 3) | (1 << 0)) // Enable | SRE
+ mrs x1, ICC_SRE_EL3
+ orr x1, x1, x0
+ msr ICC_SRE_EL3, x1
+ isb
+
+ // Configure CPU interface
+ msr ICC_CTLR_EL3, xzr
+ isb
+
+ ret
diff --git a/model.lds.S b/model.lds.S
index 401ea5f..6be474f 100644
--- a/model.lds.S
+++ b/model.lds.S
@@ -13,7 +13,7 @@ TARGET(binary)
INPUT(./boot.o)
INPUT(./cache.o)
-INPUT(./gic.o)
+INPUT(./GIC)
INPUT(./mmu.o)
INPUT(./ns.o)
INPUT(./BOOTMETHOD)
@@ -29,7 +29,7 @@ SECTIONS
. = PHYS_OFFSET;
.text : { boot.o }
.text : { cache.o }
- .text : { gic.o }
+ .text : { GIC }
.text : { mmu.o }
.text : { ns.o }
.text : { BOOTMETHOD }