]> xenbits.xensource.com Git - people/julieng/boot-wrapper-aarch64.git/commitdiff
boot-wrapper: arm64: add support for GICv3
authorMarc Zyngier <marc.zyngier@arm.com>
Thu, 24 Apr 2014 15:17:22 +0000 (16:17 +0100)
committerMark Rutland <mark.rutland@arm.com>
Fri, 9 May 2014 17:43:52 +0000 (18:43 +0100)
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>
Makefile.am
configure.ac
gic-v3.S [new file with mode: 0644]
model.lds.S

index 2f69061f7a1abdac00302cd4078904e1c2c2cb70..aa4e5729d75fc30e64432b980e73b51ed10534a6 100644 (file)
 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 $@ -
index 40d36a05cce622c328cd9d716302731b5b1c7338..b60f8697bf68dac9aa321a6cc41c10746882ce51 100644 (file)
@@ -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 (file)
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
index 401ea5f3df60f45ee2982dc7d6abb2d66e097b8f..6be474f8769a6773a8bab24dbc029e601e72c3fa 100644 (file)
@@ -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 }