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)
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
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 $@ -
[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
echo " Embedded initrd: ${FILESYSTEM:-NONE}"
echo " Use PSCI? ${USE_PSCI}"
echo " CPU IDs: ${CPU_IDS}"
+echo " Use GICv3? ${USE_GICV3}"
echo ""
--- /dev/null
+/*
+ * 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