From 09d7031d5642ff1d81c0dede9b86822d67b6b52a Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 24 Apr 2014 16:17:22 +0100 Subject: [PATCH] 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 Signed-off-by: Will Deacon Signed-off-by: Mark Rutland --- Makefile.am | 24 +++++++++----- configure.ac | 9 ++++++ gic-v3.S | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++ model.lds.S | 4 +-- 4 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 gic-v3.S 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 } -- 2.39.5