summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bl1/aarch64/bl1_entrypoint.S10
-rw-r--r--bl31/aarch64/bl31_entrypoint.S4
-rw-r--r--bl32/tsp/tsp-fvp.mk7
-rw-r--r--docs/firmware-design.md165
-rw-r--r--docs/porting-guide.md11
-rw-r--r--docs/user-guide.md6
-rw-r--r--drivers/arm/gic/arm_gic.c (renamed from plat/fvp/fvp_gic.c)244
-rw-r--r--include/drivers/arm/arm_gic.h57
-rw-r--r--include/drivers/arm/gic_v2.h4
-rw-r--r--include/lib/aarch64/arch.h19
-rw-r--r--include/plat/common/plat_config.h80
-rw-r--r--lib/aarch64/xlat_tables.c53
-rw-r--r--plat/common/plat_gic.c73
-rw-r--r--plat/fvp/aarch64/fvp_common.c136
-rw-r--r--plat/fvp/bl2_fvp_setup.c6
-rw-r--r--plat/fvp/bl31_fvp_setup.c76
-rw-r--r--plat/fvp/bl32_fvp_setup.c2
-rw-r--r--plat/fvp/fvp_def.h22
-rw-r--r--plat/fvp/fvp_pm.c43
-rw-r--r--plat/fvp/fvp_private.h19
-rw-r--r--plat/fvp/fvp_security.c3
-rw-r--r--plat/fvp/include/plat_macros.S6
-rw-r--r--plat/fvp/platform.mk22
23 files changed, 654 insertions, 414 deletions
diff --git a/bl1/aarch64/bl1_entrypoint.S b/bl1/aarch64/bl1_entrypoint.S
index cbbaeadd..50cfae65 100644
--- a/bl1/aarch64/bl1_entrypoint.S
+++ b/bl1/aarch64/bl1_entrypoint.S
@@ -98,13 +98,9 @@ func bl1_entrypoint
bic w0, w0, #TFP_BIT
msr cptr_el3, x0
- /* ---------------------------------------------
- * Find the type of reset and jump to handler
- * if present. If the handler is null then it is
- * a cold boot. The primary cpu will set up the
- * platform while the secondaries wait for
- * their turn to be woken up
- * ---------------------------------------------
+ /* -------------------------------------------------------
+ * Will not return from this macro if it is a warm boot.
+ * -------------------------------------------------------
*/
wait_for_entrypoint
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index e4dfea43..6e48e313 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -104,6 +104,10 @@ func bl31_entrypoint
msr cptr_el3, x1
#if RESET_TO_BL31
+ /* -------------------------------------------------------
+ * Will not return from this macro if it is a warm boot.
+ * -------------------------------------------------------
+ */
wait_for_entrypoint
bl platform_mem_init
#else
diff --git a/bl32/tsp/tsp-fvp.mk b/bl32/tsp/tsp-fvp.mk
index 21864d68..3220c08f 100644
--- a/bl32/tsp/tsp-fvp.mk
+++ b/bl32/tsp/tsp-fvp.mk
@@ -29,9 +29,10 @@
#
# TSP source files specific to FVP platform
-BL32_SOURCES += drivers/arm/gic/gic_v2.c \
+BL32_SOURCES += drivers/arm/gic/arm_gic.c \
+ drivers/arm/gic/gic_v2.c \
plat/common/aarch64/platform_mp_stack.S \
+ plat/common/plat_gic.c \
plat/fvp/aarch64/fvp_common.c \
plat/fvp/aarch64/fvp_helpers.S \
- plat/fvp/bl32_fvp_setup.c \
- plat/fvp/fvp_gic.c
+ plat/fvp/bl32_fvp_setup.c
diff --git a/docs/firmware-design.md b/docs/firmware-design.md
index b20f06b3..9bdfefb5 100644
--- a/docs/firmware-design.md
+++ b/docs/firmware-design.md
@@ -934,46 +934,62 @@ The sample crash output is shown below.
7. Memory layout on FVP platforms
----------------------------------
+Each bootloader image can be divided in 2 parts:
+
+ * the static contents of the image. These are data actually stored in the
+ binary on the disk. In the ELF terminology, they are called `PROGBITS`
+ sections;
+
+ * the run-time contents of the image. These are data that don't occupy any
+ space in the binary on the disk. The ELF binary just contains some
+ metadata indicating where these data will be stored at run-time and the
+ corresponding sections need to be allocated and initialized at run-time.
+ In the ELF terminology, they are called `NOBITS` sections.
+
+All PROGBITS sections are grouped together at the beginning of the image,
+followed by all NOBITS sections. This is true for all Trusted Firmware images
+and it is governed by the linker scripts. This ensures that the raw binary
+images are as small as possible. If a NOBITS section would sneak in between
+PROGBITS sections then the resulting binary file would contain a bunch of zero
+bytes at the location of this NOBITS section, making the image unnecessarily
+bigger. Smaller images allow faster loading from the FIP to the main memory.
+
On FVP platforms, we use the Trusted ROM and Trusted SRAM to store the trusted
-firmware binaries. BL1 is originally sitting in the Trusted ROM at address
-`0x0`. Its read-write data are relocated at the base of the Trusted SRAM at
-runtime. BL1 loads BL2 image near the top of the trusted SRAM. BL2 loads BL3-1
-image between BL1 and BL2. Optionally, BL2 then loads the TSP as the BL3-2
-image. By default it is loaded in Trusted SRAM, in this case it sits between
-BL3-1 and BL2. This memory layout is illustrated by the following diagram.
-
- Trusted SRAM
- +----------+ 0x04040000
- | |
- |----------|
- | BL2 |
- |----------|
- | |
- |----------|
- | BL32 | (optional)
- |----------|
- | |
- |----------|
- | BL31 |
- |----------|
- | |
- |----------|
- | BL1 (rw) |
- +----------+ 0x04000000
-
- Trusted ROM
- +----------+ 0x04000000
- | BL1 (ro) |
- +----------+ 0x00000000
+firmware binaries.
+
+ * BL1 is originally sitting in the Trusted ROM at address `0x0`. Its
+ read-write data are relocated at the top of the Trusted SRAM at runtime.
+
+ * BL3-1 is loaded at the top of the Trusted SRAM, such that its NOBITS
+ sections will overwrite BL1 R/W data.
+
+ * BL2 is loaded below BL3-1.
+
+ * The TSP is loaded as the BL3-2 image at the base of the Trusted SRAM. Its
+ NOBITS sections are allowed to overlay BL2.
+
+This memory layout is designed to give the BL3-2 image as much memory as
+possible. It is illustrated by the following diagram.
+
+ Trusted SRAM
+ 0x04040000 +----------+ loaded by BL2 ------------------
+ | BL1 (rw) | <<<<<<<<<<<<< | BL3-1 NOBITS |
+ |----------| <<<<<<<<<<<<< |----------------|
+ | | <<<<<<<<<<<<< | BL3-1 PROGBITS |
+ |----------| ------------------
+ | BL2 | <<<<<<<<<<<<< | BL3-2 NOBITS |
+ |----------| <<<<<<<<<<<<< |----------------|
+ | | <<<<<<<<<<<<< | BL3-2 PROGBITS |
+ 0x04000000 +----------+ ------------------
+
+ Trusted ROM
+ 0x04000000 +----------+
+ | BL1 (ro) |
+ 0x00000000 +----------+
The TSP image may be loaded in Trusted DRAM instead. This doesn't change the
memory layout of the other boot loader images in Trusted SRAM.
-Although the goal at long term is to give complete flexibility over the memory
-layout, all platforms should conform to this layout at the moment. This is
-because of some limitations in the implementation of the image loader in the
-Trusted Firmware. Refer to the "Limitations of the image loader" section below.
-
Each bootloader stage image layout is described by its own linker script. The
linker scripts export some symbols into the program symbol table. Their values
correspond to particular addresses. The trusted firmware code can refer to these
@@ -1095,82 +1111,9 @@ happens, the linker will issue a message similar to the following:
aarch64-none-elf-ld: BLx has exceeded its limit.
-On FVP platforms, the base addresses have been chosen such that all images can
-reside concurrently in Trusted RAM without overlapping each other. Note that
-this is not a requirement, as not all images live in memory at the same time.
-For example, when the BL3-1 image takes over execution, BL1 and BL2 images are
-not needed anymore.
-
-### Limitations of the image loader
-
-The current implementation of the image loader can result in wasted space
-because of the simplified data structure used to represent the extents of free
-memory. For example, to load BL2 at address `0x0402D000`, the resulting memory
-layout should be as follows:
-
- ------------ 0x04040000
- | | <- Free space (1)
- |----------|
- | BL2 |
- |----------| BL2_BASE (0x0402D000)
- | | <- Free space (2)
- |----------|
- | BL1 |
- ------------ 0x04000000
-
-In the current implementation, we need to specify whether BL2 is loaded at the
-top or bottom of the free memory. BL2 is top-loaded so in the example above,
-the free space (1) above BL2 is hidden, resulting in the following view of
-memory:
-
- ------------ 0x04040000
- | |
- | |
- | BL2 |
- |----------| BL2_BASE (0x0402D000)
- | | <- Free space (2)
- |----------|
- | BL1 |
- ------------ 0x04000000
-
-BL3-1 is bottom-loaded above BL1. For example, if BL3-1 is bottom-loaded at
-`0x0400E000`, the memory layout should look like this:
-
- ------------ 0x04040000
- | |
- | |
- | BL2 |
- |----------| BL2_BASE (0x0402D000)
- | | <- Free space (2)
- | |
- |----------|
- | |
- | BL31 |
- |----------| BL31_BASE (0x0400E000)
- | | <- Free space (3)
- |----------|
- | BL1 |
- ------------ 0x04000000
-
-But the free space (3) between BL1 and BL3-1 is wasted, resulting in the
-following view:
-
- ------------ 0x04040000
- | |
- | |
- | BL2 |
- |----------| BL2_BASE (0x0402D000)
- | | <- Free space (2)
- | |
- |----------|
- | |
- | |
- | BL31 | BL31_BASE (0x0400E000)
- | |
- |----------|
- | BL1 |
- ------------ 0x04000000
-
+Additionally, if the platform memory layout implies some image overlaying like
+on FVP, BL3-1 and TSP need to know the limit address that their PROGBITS
+sections must not overstep. The platform code must provide those.
8. Firmware Image Package (FIP)
--------------------------------
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 2a98d0e9..813d0be6 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -253,6 +253,17 @@ be defined as well:
the secure memory identified by `TSP_SEC_MEM_BASE` and `TSP_SEC_MEM_SIZE`
constants.
+The following constants are optional. They should be defined when the platform
+memory layout implies some image overlaying like on FVP.
+
+* **#define : BL31_PROGBITS_LIMIT**
+
+ Defines the maximum address in secure RAM that the BL3-1's progbits sections
+ can occupy.
+
+* **#define : BL32_PROGBITS_LIMIT**
+
+ Defines the maximum address that the TSP's progbits sections can occupy.
### File : plat_macros.S [mandatory]
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 34e5ba1d..a4d7f464 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -162,9 +162,9 @@ performed.
* `V`: Verbose build. If assigned anything other than 0, the build commands
are printed. Default is 0
-* `FVP_GIC_ARCH`: Choice of ARM GIC architecture version used by the FVP port
- for implementing the platform GIC API. This API is used by the interrupt
- management framework. Default is 2 i.e. version 2.0
+* `ARM_GIC_ARCH`: Choice of ARM GIC architecture version used by the ARM GIC
+ driver for implementing the platform GIC API. This API is used
+ by the interrupt management framework. Default is 2 i.e. version 2.0.
* `IMF_READ_INTERRUPT_ID`: Boolean flag used by the interrupt management
framework to enable passing of the interrupt id to its handler. The id is
diff --git a/plat/fvp/fvp_gic.c b/drivers/arm/gic/arm_gic.c
index a48b29b9..636348ba 100644
--- a/plat/fvp/fvp_gic.c
+++ b/drivers/arm/gic/arm_gic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -28,7 +28,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <arch.h>
#include <arch_helpers.h>
+#include <arm_gic.h>
#include <assert.h>
#include <bl_common.h>
#include <debug.h>
@@ -37,8 +39,14 @@
#include <interrupt_mgmt.h>
#include <platform.h>
#include <stdint.h>
-#include "fvp_def.h"
-#include "fvp_private.h"
+
+
+static unsigned int g_gicc_base;
+static unsigned int g_gicd_base;
+static unsigned long g_gicr_base;
+static const unsigned int *g_irq_sec_ptr;
+static unsigned int g_num_irqs;
+
/*******************************************************************************
* This function does some minimal GICv3 configuration. The Firmware itself does
@@ -46,7 +54,7 @@
* provided by GICv3. This function allows software (like Linux) in later stages
* to use full GICv3 features.
******************************************************************************/
-void gicv3_cpuif_setup(void)
+static void gicv3_cpuif_setup(void)
{
unsigned int scr_val, val;
uintptr_t base;
@@ -59,7 +67,8 @@ void gicv3_cpuif_setup(void)
* GICR_WAKER is NOT banked per CPU, compute the correct base address
* per CPU.
*/
- base = gicv3_get_rdist(BASE_GICR_BASE, read_mpidr());
+ assert(g_gicr_base);
+ base = gicv3_get_rdist(g_gicr_base, read_mpidr());
if (base == (uintptr_t)NULL) {
/* No re-distributor base address. This interface cannot be
* configured.
@@ -75,9 +84,8 @@ void gicv3_cpuif_setup(void)
/* We need to wait for ChildrenAsleep to clear. */
val = gicr_read_waker(base);
- while (val & WAKER_CA) {
+ while (val & WAKER_CA)
val = gicr_read_waker(base);
- }
/*
* We need to set SCR_EL3.NS in order to see GICv3 non-secure state.
@@ -103,7 +111,7 @@ void gicv3_cpuif_setup(void)
write_icc_sre_el2(val | ICC_SRE_EN | ICC_SRE_SRE);
write_icc_pmr_el1(GIC_PRI_MASK);
- isb(); /* commite ICC_* changes before setting NS=0 */
+ isb(); /* commit ICC_* changes before setting NS=0 */
/* Restore SCR_EL3 */
write_scr(scr_val);
@@ -114,7 +122,7 @@ void gicv3_cpuif_setup(void)
* This function does some minimal GICv3 configuration when cores go
* down.
******************************************************************************/
-void gicv3_cpuif_deactivate(void)
+static void gicv3_cpuif_deactivate(void)
{
unsigned int val;
uintptr_t base;
@@ -126,7 +134,8 @@ void gicv3_cpuif_deactivate(void)
* GICR_WAKER is NOT banked per CPU, compute the correct base address
* per CPU.
*/
- base = gicv3_get_rdist(BASE_GICR_BASE, read_mpidr());
+ assert(g_gicr_base);
+ base = gicv3_get_rdist(g_gicr_base, read_mpidr());
if (base == (uintptr_t)NULL) {
/* No re-distributor base address. This interface cannot be
* configured.
@@ -141,9 +150,8 @@ void gicv3_cpuif_deactivate(void)
/* We need to wait for ChildrenAsleep to set. */
val = gicr_read_waker(base);
- while ((val & WAKER_CA) == 0) {
+ while ((val & WAKER_CA) == 0)
val = gicr_read_waker(base);
- }
}
@@ -151,91 +159,76 @@ void gicv3_cpuif_deactivate(void)
* Enable secure interrupts and use FIQs to route them. Disable legacy bypass
* and set the priority mask register to allow all interrupts to trickle in.
******************************************************************************/
-void gic_cpuif_setup(unsigned int gicc_base)
+void arm_gic_cpuif_setup(void)
{
unsigned int val;
- val = gicc_read_iidr(gicc_base);
+ assert(g_gicc_base);
+ val = gicc_read_iidr(g_gicc_base);
/*
* If GICv3 we need to do a bit of additional setup. We want to
* allow default GICv2 behaviour but allow the next stage to
* enable full gicv3 features.
*/
- if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3) {
+ if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3)
gicv3_cpuif_setup();
- }
val = ENABLE_GRP0 | FIQ_EN | FIQ_BYP_DIS_GRP0;
val |= IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1;
- gicc_write_pmr(gicc_base, GIC_PRI_MASK);
- gicc_write_ctlr(gicc_base, val);
+ gicc_write_pmr(g_gicc_base, GIC_PRI_MASK);
+ gicc_write_ctlr(g_gicc_base, val);
}
/*******************************************************************************
* Place the cpu interface in a state where it can never make a cpu exit wfi as
* as result of an asserted interrupt. This is critical for powering down a cpu
******************************************************************************/
-void gic_cpuif_deactivate(unsigned int gicc_base)
+void arm_gic_cpuif_deactivate(void)
{
unsigned int val;
/* Disable secure, non-secure interrupts and disable their bypass */
- val = gicc_read_ctlr(gicc_base);
+ assert(g_gicc_base);
+ val = gicc_read_ctlr(g_gicc_base);
val &= ~(ENABLE_GRP0 | ENABLE_GRP1);
val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0;
val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1;
- gicc_write_ctlr(gicc_base, val);
+ gicc_write_ctlr(g_gicc_base, val);
- val = gicc_read_iidr(gicc_base);
+ val = gicc_read_iidr(g_gicc_base);
/*
* If GICv3 we need to do a bit of additional setup. Make sure the
* RDIST is put to sleep.
*/
- if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3) {
+ if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3)
gicv3_cpuif_deactivate();
- }
}
/*******************************************************************************
* Per cpu gic distributor setup which will be done by all cpus after a cold
* boot/hotplug. This marks out the secure interrupts & enables them.
******************************************************************************/
-void gic_pcpu_distif_setup(unsigned int gicd_base)
+void arm_gic_pcpu_distif_setup(void)
{
- gicd_write_igroupr(gicd_base, 0, ~0);
-
- gicd_clr_igroupr(gicd_base, IRQ_SEC_PHY_TIMER);
- gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_0);
- gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_1);
- gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_2);
- gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_3);
- gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_4);
- gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_5);
- gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_6);
- gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_7);
-
- gicd_set_ipriorityr(gicd_base, IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY);
- gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY);
- gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY);
- gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY);
- gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY);
- gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY);
- gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY);
- gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY);
- gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY);
-
- gicd_set_isenabler(gicd_base, IRQ_SEC_PHY_TIMER);
- gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_0);
- gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_1);
- gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_2);
- gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_3);
- gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_4);
- gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_5);
- gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_6);
- gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_7);
+ unsigned int index, irq_num;
+
+ assert(g_gicd_base);
+ gicd_write_igroupr(g_gicd_base, 0, ~0);
+
+ assert(g_irq_sec_ptr);
+ for (index = 0; index < g_num_irqs; index++) {
+ irq_num = g_irq_sec_ptr[index];
+ if (irq_num < MIN_SPI_ID) {
+ /* We have an SGI or a PPI */
+ gicd_clr_igroupr(g_gicd_base, irq_num);
+ gicd_set_ipriorityr(g_gicd_base, irq_num,
+ GIC_HIGHEST_SEC_PRIORITY);
+ gicd_set_isenabler(g_gicd_base, irq_num);
+ }
+ }
}
/*******************************************************************************
@@ -243,63 +236,88 @@ void gic_pcpu_distif_setup(unsigned int gicd_base)
* cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It
* then enables the secure GIC distributor interface.
******************************************************************************/
-void gic_distif_setup(unsigned int gicd_base)
+static void arm_gic_distif_setup(void)
{
- unsigned int ctr, num_ints, ctlr;
+ unsigned int num_ints, ctlr, index, irq_num;
/* Disable the distributor before going further */
- ctlr = gicd_read_ctlr(gicd_base);
+ assert(g_gicd_base);
+ ctlr = gicd_read_ctlr(g_gicd_base);
ctlr &= ~(ENABLE_GRP0 | ENABLE_GRP1);
- gicd_write_ctlr(gicd_base, ctlr);
+ gicd_write_ctlr(g_gicd_base, ctlr);
/*
* Mark out non-secure interrupts. Calculate number of
* IGROUPR registers to consider. Will be equal to the
* number of IT_LINES
*/
- num_ints = gicd_read_typer(gicd_base) & IT_LINES_NO_MASK;
+ num_ints = gicd_read_typer(g_gicd_base) & IT_LINES_NO_MASK;
num_ints++;
- for (ctr = 0; ctr < num_ints; ctr++)
- gicd_write_igroupr(gicd_base, ctr << IGROUPR_SHIFT, ~0);
+ for (index = 0; index < num_ints; index++)
+ gicd_write_igroupr(g_gicd_base, index << IGROUPR_SHIFT, ~0);
/* Configure secure interrupts now */
- gicd_clr_igroupr(gicd_base, IRQ_TZ_WDOG);
- gicd_set_ipriorityr(gicd_base, IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY);
- gicd_set_itargetsr(gicd_base, IRQ_TZ_WDOG,
- platform_get_core_pos(read_mpidr()));
- gicd_set_isenabler(gicd_base, IRQ_TZ_WDOG);
- gic_pcpu_distif_setup(gicd_base);
-
- gicd_write_ctlr(gicd_base, ctlr | ENABLE_GRP0);
+ assert(g_irq_sec_ptr);
+ for (index = 0; index < g_num_irqs; index++) {
+ irq_num = g_irq_sec_ptr[index];
+ if (irq_num >= MIN_SPI_ID) {
+ /* We have an SPI */
+ gicd_clr_igroupr(g_gicd_base, irq_num);
+ gicd_set_ipriorityr(g_gicd_base, irq_num,
+ GIC_HIGHEST_SEC_PRIORITY);
+ gicd_set_itargetsr(g_gicd_base, irq_num,
+ platform_get_core_pos(read_mpidr()));
+ gicd_set_isenabler(g_gicd_base, irq_num);
+ }
+ }
+ arm_gic_pcpu_distif_setup();
+
+ gicd_write_ctlr(g_gicd_base, ctlr | ENABLE_GRP0);
}
-void gic_setup(void)
+/*******************************************************************************
+ * Initialize the ARM GIC driver with the provided platform inputs
+******************************************************************************/
+void arm_gic_init(unsigned int gicc_base,
+ unsigned int gicd_base,
+ unsigned long gicr_base,
+ const unsigned int *irq_sec_ptr,
+ unsigned int num_irqs
+ )
{
- unsigned int gicd_base, gicc_base;
-
- gicd_base = fvp_get_cfgvar(CONFIG_GICD_ADDR);
- gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR);
+ assert(gicc_base);
+ assert(gicd_base);
+ assert(gicr_base);
+ assert(irq_sec_ptr);
+ g_gicc_base = gicc_base;
+ g_gicd_base = gicd_base;
+ g_gicr_base = gicr_base;
+ g_irq_sec_ptr = irq_sec_ptr;
+ g_num_irqs = num_irqs;
+}
- gic_cpuif_setup(gicc_base);
- gic_distif_setup(gicd_base);
+/*******************************************************************************
+ * Setup the ARM GIC CPU and distributor interfaces.
+******************************************************************************/
+void arm_gic_setup(void)
+{
+ arm_gic_cpuif_setup();
+ arm_gic_distif_setup();
}
/*******************************************************************************
* An ARM processor signals interrupt exceptions through the IRQ and FIQ pins.
* The interrupt controller knows which pin/line it uses to signal a type of
- * interrupt. The platform knows which interrupt controller type is being used
- * in a particular security state e.g. with an ARM GIC, normal world could use
- * the GICv2 features while the secure world could use GICv3 features and vice
- * versa.
- * This function is exported by the platform to let the interrupt management
- * framework determine for a type of interrupt and security state, which line
- * should be used in the SCR_EL3 to control its routing to EL3. The interrupt
- * line is represented as the bit position of the IRQ or FIQ bit in the SCR_EL3.
+ * interrupt. This function provides a common implementation of
+ * plat_interrupt_type_to_line() in an ARM GIC environment for optional re-use
+ * across platforms. It lets the interrupt management framework determine
+ * for a type of interrupt and security state, which line should be used in the
+ * SCR_EL3 to control its routing to EL3. The interrupt line is represented as
+ * the bit position of the IRQ or FIQ bit in the SCR_EL3.
******************************************************************************/
-uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state)
+uint32_t arm_gic_interrupt_type_to_line(uint32_t type,
+ uint32_t security_state)
{
- uint32_t gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR);
-
assert(type == INTR_TYPE_S_EL1 ||
type == INTR_TYPE_EL3 ||
type == INTR_TYPE_NS);
@@ -311,25 +329,25 @@ uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state)
* both normal and secure worlds are using ARM GICv2. This parameter
* will be used when the secure world starts using GICv3.
*/
-#if FVP_GIC_ARCH == 2
- return gicv2_interrupt_type_to_line(gicc_base, type);
+#if ARM_GIC_ARCH == 2
+ return gicv2_interrupt_type_to_line(g_gicc_base, type);
#else
-#error "Invalid GIC architecture version specified for FVP port"
-#endif
+#error "Invalid ARM GIC architecture version specified for platform port"
+#endif /* ARM_GIC_ARCH */
}
-#if FVP_GIC_ARCH == 2
+#if ARM_GIC_ARCH == 2
/*******************************************************************************
* This function returns the type of the highest priority pending interrupt at
* the GIC cpu interface. INTR_TYPE_INVAL is returned when there is no
* interrupt pending.
******************************************************************************/
-uint32_t plat_ic_get_pending_interrupt_type(void)
+uint32_t arm_gic_get_pending_interrupt_type(void)
{
- uint32_t id, gicc_base;
+ uint32_t id;
- gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR);
- id = gicc_read_hppir(gicc_base);
+ assert(g_gicc_base);
+ id = gicc_read_hppir(g_gicc_base);
/* Assume that all secure interrupts are S-EL1 interrupts */
if (id < 1022)
@@ -346,12 +364,12 @@ uint32_t plat_ic_get_pending_interrupt_type(void)
* the GIC cpu interface. INTR_ID_UNAVAILABLE is returned when there is no
* interrupt pending.
******************************************************************************/
-uint32_t plat_ic_get_pending_interrupt_id(void)
+uint32_t arm_gic_get_pending_interrupt_id(void)
{
- uint32_t id, gicc_base;
+ uint32_t id;
- gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR);
- id = gicc_read_hppir(gicc_base);
+ assert(g_gicc_base);
+ id = gicc_read_hppir(g_gicc_base);
if (id < 1022)
return id;
@@ -363,26 +381,27 @@ uint32_t plat_ic_get_pending_interrupt_id(void)
* Find out which non-secure interrupt it is under the assumption that
* the GICC_CTLR.AckCtl bit is 0.
*/
- return gicc_read_ahppir(gicc_base);
+ return gicc_read_ahppir(g_gicc_base);
}
/*******************************************************************************
* This functions reads the GIC cpu interface Interrupt Acknowledge register
* to start handling the pending interrupt. It returns the contents of the IAR.
******************************************************************************/
-uint32_t plat_ic_acknowledge_interrupt(void)
+uint32_t arm_gic_acknowledge_interrupt(void)
{
- return gicc_read_IAR(fvp_get_cfgvar(CONFIG_GICC_ADDR));
+ assert(g_gicc_base);
+ return gicc_read_IAR(g_gicc_base);
}
/*******************************************************************************
* This functions writes the GIC cpu interface End Of Interrupt register with
* the passed value to finish handling the active interrupt
******************************************************************************/
-void plat_ic_end_of_interrupt(uint32_t id)
+void arm_gic_end_of_interrupt(uint32_t id)
{
- gicc_write_EOIR(fvp_get_cfgvar(CONFIG_GICC_ADDR), id);
- return;
+ assert(g_gicc_base);
+ gicc_write_EOIR(g_gicc_base, id);
}
/*******************************************************************************
@@ -390,11 +409,12 @@ void plat_ic_end_of_interrupt(uint32_t id)
* this interrupt has been configured under by the interrupt controller i.e.
* group0 or group1.
******************************************************************************/
-uint32_t plat_ic_get_interrupt_type(uint32_t id)
+uint32_t arm_gic_get_interrupt_type(uint32_t id)
{
uint32_t group;
- group = gicd_get_igroupr(fvp_get_cfgvar(CONFIG_GICD_ADDR), id);
+ assert(g_gicd_base);
+ group = gicd_get_igroupr(g_gicd_base, id);
/* Assume that all secure interrupts are S-EL1 interrupts */
if (group == GRP0)
@@ -404,5 +424,5 @@ uint32_t plat_ic_get_interrupt_type(uint32_t id)
}
#else
-#error "Invalid GIC architecture version specified for FVP port"
-#endif
+#error "Invalid ARM GIC architecture version specified for platform port"
+#endif /* ARM_GIC_ARCH */
diff --git a/include/drivers/arm/arm_gic.h b/include/drivers/arm/arm_gic.h
new file mode 100644
index 00000000..9ab1a959
--- /dev/null
+++ b/include/drivers/arm/arm_gic.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. 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.
+ */
+
+#ifndef __ARM_GIC_H__
+#define __ARM_GIC_H__
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * Function declarations
+ ******************************************************************************/
+void arm_gic_init(unsigned int gicc_base,
+ unsigned int gicd_base,
+ unsigned long gicr_base,
+ const unsigned int *irq_sec_ptr,
+ unsigned int num_irqs);
+void arm_gic_setup(void);
+void arm_gic_cpuif_deactivate(void);
+void arm_gic_cpuif_setup(void);
+void arm_gic_pcpu_distif_setup(void);
+
+uint32_t arm_gic_interrupt_type_to_line(uint32_t type,
+ uint32_t security_state);
+uint32_t arm_gic_get_pending_interrupt_type(void);
+uint32_t arm_gic_get_pending_interrupt_id(void);
+uint32_t arm_gic_acknowledge_interrupt(void);
+void arm_gic_end_of_interrupt(uint32_t id);
+uint32_t arm_gic_get_interrupt_type(uint32_t id);
+
+#endif /* __GIC_H__ */
diff --git a/include/drivers/arm/gic_v2.h b/include/drivers/arm/gic_v2.h
index 1859a8eb..4c6b0dcc 100644
--- a/include/drivers/arm/gic_v2.h
+++ b/include/drivers/arm/gic_v2.h
@@ -36,6 +36,10 @@
#define MAX_PPIS 14
#define MAX_SGIS 16
+#define MIN_SGI_ID 0
+#define MIN_PPI_ID 16
+#define MIN_SPI_ID 32
+
#define GRP0 0
#define GRP1 1
#define GIC_PRI_MASK 0xff
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 5dc488bb..ff91efc4 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -211,8 +211,23 @@
* TCR defintions
*/
#define TCR_EL3_RES1 ((1UL << 31) | (1UL << 23))
-
-#define TCR_T0SZ_4GB 32
+#define TCR_EL1_IPS_SHIFT 32
+#define TCR_EL3_PS_SHIFT 16
+
+/* (internal) physical address size bits in EL3/EL1 */
+#define TCR_PS_BITS_4GB (0x0)
+#define TCR_PS_BITS_64GB (0x1)
+#define TCR_PS_BITS_1TB (0x2)
+#define TCR_PS_BITS_4TB (0x3)
+#define TCR_PS_BITS_16TB (0x4)
+#define TCR_PS_BITS_256TB (0x5)
+
+#define ADDR_MASK_48_TO_63 0xFFFF000000000000UL
+#define ADDR_MASK_44_TO_47 0x0000F00000000000UL
+#define ADDR_MASK_42_TO_43 0x00000C0000000000UL
+#define ADDR_MASK_40_TO_41 0x0000030000000000UL
+#define ADDR_MASK_36_TO_39 0x000000F000000000UL
+#define ADDR_MASK_32_TO_35 0x0000000F00000000UL
#define TCR_RGN_INNER_NC (0x0 << 8)
#define TCR_RGN_INNER_WBA (0x1 << 8)
diff --git a/include/plat/common/plat_config.h b/include/plat/common/plat_config.h
new file mode 100644
index 00000000..826d01b7
--- /dev/null
+++ b/include/plat/common/plat_config.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. 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.
+ */
+#ifndef __PLAT_CONFIG_H__
+#define __PLAT_CONFIG_H__
+
+#define CONFIG_GICC_BASE_OFFSET 0x4
+
+
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+
+
+enum plat_config_flags {
+ /* Whether CPUECTLR SMP bit should be enabled */
+ CONFIG_CPUECTLR_SMP_BIT = 0x1,
+ /* Whether Base FVP memory map is in use */
+ CONFIG_BASE_MMAP = 0x2,
+ /* Whether CCI should be enabled */
+ CONFIG_HAS_CCI = 0x4,
+ /* Whether TZC should be configured */
+ CONFIG_HAS_TZC = 0x8
+};
+
+typedef struct plat_config {
+ unsigned int gicd_base;
+ unsigned int gicc_base;
+ unsigned int gich_base;
+ unsigned int gicv_base;
+ unsigned int max_aff0;
+ unsigned int max_aff1;
+ unsigned long flags;
+} plat_config_t;
+
+inline const plat_config_t *get_plat_config();
+
+
+CASSERT(CONFIG_GICC_BASE_OFFSET == __builtin_offsetof(
+ plat_config_t, gicc_base),
+ assert_gicc_base_offset_mismatch);
+
+/* If used, plat_config must be defined and populated in the platform port*/
+extern plat_config_t plat_config;
+
+inline const plat_config_t *get_plat_config()
+{
+ return &plat_config;
+}
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __PLAT_CONFIG_H__ */
diff --git a/lib/aarch64/xlat_tables.c b/lib/aarch64/xlat_tables.c
index 1b99cc85..f1d658d5 100644
--- a/lib/aarch64/xlat_tables.c
+++ b/lib/aarch64/xlat_tables.c
@@ -31,6 +31,7 @@
#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
+#include <cassert.h>
#include <platform_def.h>
#include <string.h>
#include <xlat_tables.h>
@@ -46,6 +47,7 @@
#define debug_print(...) ((void)0)
#endif
+CASSERT(ADDR_SPACE_SIZE > 0, assert_valid_addr_space_size);
#define UNSET_DESC ~0ul
@@ -58,6 +60,9 @@ static uint64_t xlat_tables[MAX_XLAT_TABLES][XLAT_TABLE_ENTRIES]
__aligned(XLAT_TABLE_SIZE) __attribute__((section("xlat_table")));
static unsigned next_xlat;
+static unsigned long max_pa;
+static unsigned long max_va;
+static unsigned long tcr_ps_bits;
/*
* Array of all memory regions stored in order of ascending base address.
@@ -85,6 +90,8 @@ void mmap_add_region(unsigned long base_pa, unsigned long base_va,
{
mmap_region_t *mm = mmap;
mmap_region_t *mm_last = mm + sizeof(mmap) / sizeof(mmap[0]) - 1;
+ unsigned long pa_end = base_pa + size - 1;
+ unsigned long va_end = base_va + size - 1;
assert(IS_PAGE_ALIGNED(base_pa));
assert(IS_PAGE_ALIGNED(base_va));
@@ -107,6 +114,11 @@ void mmap_add_region(unsigned long base_pa, unsigned long base_va,
mm->base_va = base_va;
mm->size = size;
mm->attr = attr;
+
+ if (pa_end > max_pa)
+ max_pa = pa_end;
+ if (va_end > max_va)
+ max_va = va_end;
}
void mmap_add(const mmap_region_t *mm)
@@ -233,10 +245,40 @@ static mmap_region_t *init_xlation_table(mmap_region_t *mm,
return mm;
}
+static unsigned int calc_physical_addr_size_bits(unsigned long max_addr)
+{
+ /* Physical address can't exceed 48 bits */
+ assert((max_addr & ADDR_MASK_48_TO_63) == 0);
+
+ /* 48 bits address */
+ if (max_addr & ADDR_MASK_44_TO_47)
+ return TCR_PS_BITS_256TB;
+
+ /* 44 bits address */
+ if (max_addr & ADDR_MASK_42_TO_43)
+ return TCR_PS_BITS_16TB;
+
+ /* 42 bits address */
+ if (max_addr & ADDR_MASK_40_TO_41)
+ return TCR_PS_BITS_4TB;
+
+ /* 40 bits address */
+ if (max_addr & ADDR_MASK_36_TO_39)
+ return TCR_PS_BITS_1TB;
+
+ /* 36 bits address */
+ if (max_addr & ADDR_MASK_32_TO_35)
+ return TCR_PS_BITS_64GB;
+
+ return TCR_PS_BITS_4GB;
+}
+
void init_xlat_tables(void)
{
print_mmap();
init_xlation_table(mmap, 0, l1_xlation_table, 1);
+ tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
+ assert(max_va < ADDR_SPACE_SIZE);
}
/*******************************************************************************
@@ -270,7 +312,8 @@ void init_xlat_tables(void)
/* Set TCR bits as well. */ \
/* Inner & outer WBWA & shareable + T0SZ = 32 */ \
tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA | \
- TCR_RGN_INNER_WBA | TCR_T0SZ_4GB; \
+ TCR_RGN_INNER_WBA | \
+ (64 - __builtin_ctzl(ADDR_SPACE_SIZE)); \
tcr |= _tcr_extra; \
write_tcr_el##_el(tcr); \
\
@@ -295,5 +338,9 @@ void init_xlat_tables(void)
}
/* Define EL1 and EL3 variants of the function enabling the MMU */
-DEFINE_ENABLE_MMU_EL(1, 0, tlbivmalle1)
-DEFINE_ENABLE_MMU_EL(3, TCR_EL3_RES1, tlbialle3)
+DEFINE_ENABLE_MMU_EL(1,
+ (tcr_ps_bits << TCR_EL1_IPS_SHIFT),
+ tlbivmalle1)
+DEFINE_ENABLE_MMU_EL(3,
+ TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT),
+ tlbialle3)
diff --git a/plat/common/plat_gic.c b/plat/common/plat_gic.c
new file mode 100644
index 00000000..f736e55a
--- /dev/null
+++ b/plat/common/plat_gic.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. 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.
+ */
+#include <arm_gic.h>
+
+/*
+ * The following platform GIC functions are weakly defined. They
+ * provide typical implementations that may be re-used by multiple
+ * platforms but may also be overridden by a platform if required.
+ */
+#pragma weak plat_ic_get_pending_interrupt_id
+#pragma weak plat_ic_get_pending_interrupt_type
+#pragma weak plat_ic_acknowledge_interrupt
+#pragma weak plat_ic_get_interrupt_type
+#pragma weak plat_ic_end_of_interrupt
+#pragma weak plat_interrupt_type_to_line
+
+uint32_t plat_ic_get_pending_interrupt_id(void)
+{
+ return arm_gic_get_pending_interrupt_id();
+}
+
+uint32_t plat_ic_get_pending_interrupt_type(void)
+{
+ return arm_gic_get_pending_interrupt_type();
+}
+
+uint32_t plat_ic_acknowledge_interrupt(void)
+{
+ return arm_gic_acknowledge_interrupt();
+}
+
+uint32_t plat_ic_get_interrupt_type(uint32_t id)
+{
+ return arm_gic_get_interrupt_type(id);
+}
+
+void plat_ic_end_of_interrupt(uint32_t id)
+{
+ arm_gic_end_of_interrupt(id);
+}
+
+uint32_t plat_interrupt_type_to_line(uint32_t type,
+ uint32_t security_state)
+{
+ return arm_gic_interrupt_type_to_line(type, security_state);
+}
diff --git a/plat/fvp/aarch64/fvp_common.c b/plat/fvp/aarch64/fvp_common.c
index 580c7936..3fe3a218 100644
--- a/plat/fvp/aarch64/fvp_common.c
+++ b/plat/fvp/aarch64/fvp_common.c
@@ -30,23 +30,25 @@
#include <arch.h>
#include <arch_helpers.h>
+#include <arm_gic.h>
#include <assert.h>
#include <bl_common.h>
#include <cci400.h>
#include <debug.h>
#include <mmio.h>
#include <platform.h>
+#include <plat_config.h>
#include <xlat_tables.h>
#include "../fvp_def.h"
/*******************************************************************************
- * This array holds the characteristics of the differences between the three
+ * plat_config holds the characteristics of the differences between the three
* FVP platforms (Base, A53_A57 & Foundation). It will be populated during cold
* boot at each boot stage by the primary before enabling the MMU (to allow cci
* configuration) & used thereafter. Each BL will have its own copy to allow
* independent operation.
******************************************************************************/
-static unsigned long fvp_config[CONFIG_LIMIT];
+plat_config_t plat_config;
/*
* Table of regions to map using the MMU.
@@ -76,6 +78,23 @@ const mmap_region_t fvp_mmap[] = {
{0}
};
+/* Array of secure interrupts to be configured by the gic driver */
+const unsigned int irq_sec_array[] = {
+ IRQ_TZ_WDOG,
+ IRQ_SEC_PHY_TIMER,
+ IRQ_SEC_SGI_0,
+ IRQ_SEC_SGI_1,
+ IRQ_SEC_SGI_2,
+ IRQ_SEC_SGI_3,
+ IRQ_SEC_SGI_4,
+ IRQ_SEC_SGI_5,
+ IRQ_SEC_SGI_6,
+ IRQ_SEC_SGI_7
+};
+
+const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
+ sizeof(irq_sec_array[0]);
+
/*******************************************************************************
* Macro generating the code for the function setting up the pagetables as per
* the platform memory map & initialize the mmu, for the given exception level
@@ -107,13 +126,6 @@ const mmap_region_t fvp_mmap[] = {
DEFINE_CONFIGURE_MMU_EL(1)
DEFINE_CONFIGURE_MMU_EL(3)
-/* Simple routine which returns a configuration variable value */
-unsigned long fvp_get_cfgvar(unsigned int var_id)
-{
- assert(var_id < CONFIG_LIMIT);
- return fvp_config[var_id];
-}
-
/*******************************************************************************
* A single boot loader stack is expected to work on both the Foundation FVP
* models and the two flavours of the Base FVP models (AEMv8 & Cortex). The
@@ -131,8 +143,10 @@ int fvp_config_setup(void)
bld = (sys_id >> SYS_ID_BLD_SHIFT) & SYS_ID_BLD_MASK;
arch = (sys_id >> SYS_ID_ARCH_SHIFT) & SYS_ID_ARCH_MASK;
- if ((rev != REV_FVP) || (arch != ARCH_MODEL))
+ if (arch != ARCH_MODEL) {
+ ERROR("This firmware is for FVP models\n");
panic();
+ }
/*
* The build field in the SYS_ID tells which variant of the GIC
@@ -140,19 +154,20 @@ int fvp_config_setup(void)
*/
switch (bld) {
case BLD_GIC_VE_MMAP:
- fvp_config[CONFIG_GICD_ADDR] = VE_GICD_BASE;
- fvp_config[CONFIG_GICC_ADDR] = VE_GICC_BASE;
- fvp_config[CONFIG_GICH_ADDR] = VE_GICH_BASE;
- fvp_config[CONFIG_GICV_ADDR] = VE_GICV_BASE;
+ plat_config.gicd_base = VE_GICD_BASE;
+ plat_config.gicc_base = VE_GICC_BASE;
+ plat_config.gich_base = VE_GICH_BASE;
+ plat_config.gicv_base = VE_GICV_BASE;
break;
case BLD_GIC_A53A57_MMAP:
- fvp_config[CONFIG_GICD_ADDR] = BASE_GICD_BASE;
- fvp_config[CONFIG_GICC_ADDR] = BASE_GICC_BASE;
- fvp_config[CONFIG_GICH_ADDR] = BASE_GICH_BASE;
- fvp_config[CONFIG_GICV_ADDR] = BASE_GICV_BASE;
+ plat_config.gicd_base = BASE_GICD_BASE;
+ plat_config.gicc_base = BASE_GICC_BASE;
+ plat_config.gich_base = BASE_GICH_BASE;
+ plat_config.gicv_base = BASE_GICV_BASE;
break;
default:
- assert(0);
+ ERROR("Unsupported board build %x\n", bld);
+ panic();
}
/*
@@ -161,28 +176,49 @@ int fvp_config_setup(void)
*/
switch (hbi) {
case HBI_FOUNDATION:
- fvp_config[CONFIG_MAX_AFF0] = 4;
- fvp_config[CONFIG_MAX_AFF1] = 1;
- fvp_config[CONFIG_CPU_SETUP] = 0;
- fvp_config[CONFIG_BASE_MMAP] = 0;
- fvp_config[CONFIG_HAS_CCI] = 0;
- fvp_config[CONFIG_HAS_TZC] = 0;
+ plat_config.max_aff0 = 4;
+ plat_config.max_aff1 = 1;
+ plat_config.flags = 0;
+
+ /*
+ * Check for supported revisions of Foundation FVP
+ * Allow future revisions to run but emit warning diagnostic
+ */
+ switch (rev) {
+ case REV_FOUNDATION_V2_0:
+ case REV_FOUNDATION_V2_1:
+ break;
+ default:
+ WARN("Unrecognized Foundation FVP revision %x\n", rev);
+ break;
+ }
break;
case HBI_FVP_BASE:
midr_pn = (read_midr() >> MIDR_PN_SHIFT) & MIDR_PN_MASK;
- if ((midr_pn == MIDR_PN_A57) || (midr_pn == MIDR_PN_A53))
- fvp_config[CONFIG_CPU_SETUP] = 1;
- else
- fvp_config[CONFIG_CPU_SETUP] = 0;
+ plat_config.flags =
+ ((midr_pn == MIDR_PN_A57) || (midr_pn == MIDR_PN_A53))
+ ? CONFIG_CPUECTLR_SMP_BIT : 0;
+
+ plat_config.max_aff0 = 4;
+ plat_config.max_aff1 = 2;
+ plat_config.flags |= CONFIG_BASE_MMAP | CONFIG_HAS_CCI |
+ CONFIG_HAS_TZC;
- fvp_config[CONFIG_MAX_AFF0] = 4;
- fvp_config[CONFIG_MAX_AFF1] = 2;
- fvp_config[CONFIG_BASE_MMAP] = 1;
- fvp_config[CONFIG_HAS_CCI] = 1;
- fvp_config[CONFIG_HAS_TZC] = 1;
+ /*
+ * Check for supported revisions
+ * Allow future revisions to run but emit warning diagnostic
+ */
+ switch (rev) {
+ case REV_FVP_BASE_V0:
+ break;
+ default:
+ WARN("Unrecognized Base FVP revision %x\n", rev);
+ break;
+ }
break;
default:
- assert(0);
+ ERROR("Unsupported board HBI number 0x%x\n", hbi);
+ panic();
}
return 0;
@@ -208,39 +244,45 @@ uint64_t plat_get_syscnt_freq(void)
void fvp_cci_setup(void)
{
- unsigned long cci_setup;
-
/*
* Enable CCI-400 for this cluster. No need
* for locks as no other cpu is active at the
* moment
*/
- cci_setup = fvp_get_cfgvar(CONFIG_HAS_CCI);
- if (cci_setup)
+ if (plat_config.flags & CONFIG_HAS_CCI)
cci_enable_coherency(read_mpidr());
}
+void fvp_gic_init(void)
+{
+ arm_gic_init(plat_config.gicc_base,
+ plat_config.gicd_base,
+ BASE_GICR_BASE,
+ irq_sec_array,
+ num_sec_irqs);
+}
+
/*******************************************************************************
- * Set SPSR and secure state for BL32 image
+ * Gets SPSR for BL32 entry
******************************************************************************/
-void fvp_set_bl32_ep_info(entry_point_info_t *bl32_ep_info)
+uint32_t fvp_get_spsr_for_bl32_entry(void)
{
- SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
/*
* The Secure Payload Dispatcher service is responsible for
* setting the SPSR prior to entry into the BL32 image.
*/
- bl32_ep_info->spsr = 0;
+ return 0;
}
/*******************************************************************************
- * Set SPSR and secure state for BL33 image
+ * Gets SPSR for BL33 entry
******************************************************************************/
-void fvp_set_bl33_ep_info(entry_point_info_t *bl33_ep_info)
+uint32_t fvp_get_spsr_for_bl33_entry(void)
{
unsigned long el_status;
unsigned int mode;
+ uint32_t spsr;
/* Figure out what mode we enter the non-secure world in */
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
@@ -256,6 +298,6 @@ void fvp_set_bl33_ep_info(entry_point_info_t *bl33_ep_info)
* the FIP ToC and allowing the platform to have a say as
* well.
*/
- bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
- SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
+ spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
}
diff --git a/plat/fvp/bl2_fvp_setup.c b/plat/fvp/bl2_fvp_setup.c
index 5a107339..beba804e 100644
--- a/plat/fvp/bl2_fvp_setup.c
+++ b/plat/fvp/bl2_fvp_setup.c
@@ -241,7 +241,8 @@ void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
entry_point_info_t *bl32_ep_info)
{
- fvp_set_bl32_ep_info(bl32_ep_info);
+ SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
+ bl32_ep_info->spsr = fvp_get_spsr_for_bl32_entry();
}
/*******************************************************************************
@@ -253,7 +254,8 @@ void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
void bl2_plat_set_bl33_ep_info(image_info_t *image,
entry_point_info_t *bl33_ep_info)
{
- fvp_set_bl33_ep_info(bl33_ep_info);
+ SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
+ bl33_ep_info->spsr = fvp_get_spsr_for_bl33_entry();
}
diff --git a/plat/fvp/bl31_fvp_setup.c b/plat/fvp/bl31_fvp_setup.c
index 50ed0b0b..96f4772a 100644
--- a/plat/fvp/bl31_fvp_setup.c
+++ b/plat/fvp/bl31_fvp_setup.c
@@ -30,6 +30,7 @@
#include <arch.h>
#include <arch_helpers.h>
+#include <arm_gic.h>
#include <assert.h>
#include <bl_common.h>
#include <bl31.h>
@@ -72,8 +73,7 @@ extern unsigned long __COHERENT_RAM_END__;
#if RESET_TO_BL31
-static entry_point_info_t bl32_entrypoint_info;
-static entry_point_info_t bl33_entrypoint_info;
+static entry_point_info_t next_image_ep_info;
#else
/*******************************************************************************
* Reference to structure which holds the arguments that have been passed to
@@ -90,30 +90,42 @@ static bl31_params_t *bl2_to_bl31_params;
******************************************************************************/
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
{
- entry_point_info_t *next_image_info;
-
#if RESET_TO_BL31
- if (type == NON_SECURE)
- fvp_get_entry_point_info(NON_SECURE, &bl33_entrypoint_info);
- else
- fvp_get_entry_point_info(SECURE, &bl32_entrypoint_info);
+ assert(type <= NON_SECURE);
+ SET_PARAM_HEAD(&next_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
- next_image_info = (type == NON_SECURE) ?
- &bl33_entrypoint_info :
- &bl32_entrypoint_info;
+ SET_SECURITY_STATE(next_image_ep_info.h.attr, type);
+
+ if (type == NON_SECURE) {
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+ next_image_ep_info.pc = plat_get_ns_image_entrypoint();
+ next_image_ep_info.spsr = fvp_get_spsr_for_bl33_entry();
+ } else {
+ next_image_ep_info.pc = BL32_BASE;
+ next_image_ep_info.spsr = fvp_get_spsr_for_bl32_entry();
+ }
+
+ return &next_image_ep_info;
#else
+ entry_point_info_t *next_image_info;
+
next_image_info = (type == NON_SECURE) ?
bl2_to_bl31_params->bl33_ep_info :
bl2_to_bl31_params->bl32_ep_info;
-#endif
-
/* None of the images on this platform can have 0x0 as the entrypoint */
if (next_image_info->pc)
return next_image_info;
else
return NULL;
+#endif
}
/*******************************************************************************
@@ -172,7 +184,8 @@ void bl31_platform_setup(void)
unsigned int reg_val;
/* Initialize the gic cpu and distributor interfaces */
- gic_setup();
+ fvp_gic_init();
+ arm_gic_setup();
/*
* TODO: Configure the CLCD before handing control to
@@ -220,38 +233,3 @@ void bl31_plat_arch_setup(void)
BL31_COHERENT_RAM_BASE,
BL31_COHERENT_RAM_LIMIT);
}
-
-#if RESET_TO_BL31
-/*******************************************************************************
- * Generate the entry point info for Non Secure and Secure images
- * for transferring control from BL31
- ******************************************************************************/
-void fvp_get_entry_point_info(unsigned long target_security,
- entry_point_info_t *target_entry_info)
-{
- if (target_security == NON_SECURE) {
- SET_PARAM_HEAD(target_entry_info,
- PARAM_EP,
- VERSION_1,
- 0);
- /*
- * Tell BL31 where the non-trusted software image
- * is located and the entry state information
- */
- target_entry_info->pc = plat_get_ns_image_entrypoint();
-
- fvp_set_bl33_ep_info(target_entry_info);
-
- } else {
- SET_PARAM_HEAD(target_entry_info,
- PARAM_EP,
- VERSION_1,
- 0);
- if (BL32_BASE != 0) {
- /* Hard coding entry point to the base of the BL32 */
- target_entry_info->pc = BL32_BASE;
- fvp_set_bl32_ep_info(target_entry_info);
- }
- }
-}
-#endif
diff --git a/plat/fvp/bl32_fvp_setup.c b/plat/fvp/bl32_fvp_setup.c
index 3c09ca2b..901c5857 100644
--- a/plat/fvp/bl32_fvp_setup.c
+++ b/plat/fvp/bl32_fvp_setup.c
@@ -83,7 +83,7 @@ void bl32_early_platform_setup(void)
******************************************************************************/
void bl32_platform_setup(void)
{
-
+ fvp_gic_init();
}
/*******************************************************************************
diff --git a/plat/fvp/fvp_def.h b/plat/fvp/fvp_def.h
index 59dcc90b..89c8b023 100644
--- a/plat/fvp/fvp_def.h
+++ b/plat/fvp/fvp_def.h
@@ -1,4 +1,4 @@
-/*
+#/*
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,21 +37,6 @@
/* Firmware Image Package */
#define FIP_IMAGE_NAME "fip.bin"
-/* Constants for accessing platform configuration */
-#define CONFIG_GICD_ADDR 0
-#define CONFIG_GICC_ADDR 1
-#define CONFIG_GICH_ADDR 2
-#define CONFIG_GICV_ADDR 3
-#define CONFIG_MAX_AFF0 4
-#define CONFIG_MAX_AFF1 5
-/* Indicate whether the CPUECTLR SMP bit should be enabled. */
-#define CONFIG_CPU_SETUP 6
-#define CONFIG_BASE_MMAP 7
-/* Indicates whether CCI should be enabled on the platform. */
-#define CONFIG_HAS_CCI 8
-#define CONFIG_HAS_TZC 9
-#define CONFIG_LIMIT 10
-
/*******************************************************************************
* FVP memory map related constants
******************************************************************************/
@@ -151,9 +136,12 @@
#define SYS_ID_BLD_LENGTH 4
-#define REV_FVP 0x0
#define HBI_FVP_BASE 0x020
+#define REV_FVP_BASE_V0 0x0
+
#define HBI_FOUNDATION 0x010
+#define REV_FOUNDATION_V2_0 0x0
+#define REV_FOUNDATION_V2_1 0x1
#define BLD_GIC_VE_MMAP 0x0
#define BLD_GIC_A53A57_MMAP 0x1
diff --git a/plat/fvp/fvp_pm.c b/plat/fvp/fvp_pm.c
index 03f06e7c..55f465ba 100644
--- a/plat/fvp/fvp_pm.c
+++ b/plat/fvp/fvp_pm.c
@@ -29,11 +29,13 @@
*/
#include <arch_helpers.h>
+#include <arm_gic.h>
#include <assert.h>
#include <bakery_lock.h>
#include <cci400.h>
#include <mmio.h>
#include <platform.h>
+#include <plat_config.h>
#include <platform_def.h>
#include <psci.h>
#include "drivers/pwrc/fvp_pwrc.h"
@@ -129,8 +131,7 @@ int fvp_affinst_off(unsigned long mpidr,
unsigned int state)
{
int rc = PSCI_E_SUCCESS;
- unsigned int gicc_base, ectlr;
- unsigned long cpu_setup, cci_setup;
+ unsigned int ectlr;
switch (afflvl) {
case MPIDR_AFFLVL1:
@@ -139,10 +140,8 @@ int fvp_affinst_off(unsigned long mpidr,
* Disable coherency if this cluster is to be
* turned off
*/
- cci_setup = fvp_get_cfgvar(CONFIG_HAS_CCI);
- if (cci_setup) {
+ if (get_plat_config()->flags & CONFIG_HAS_CCI)
cci_disable_coherency(mpidr);
- }
/*
* Program the power controller to turn the
@@ -160,8 +159,7 @@ int fvp_affinst_off(unsigned long mpidr,
* Take this cpu out of intra-cluster coherency if
* the FVP flavour supports the SMP bit.
*/
- cpu_setup = fvp_get_cfgvar(CONFIG_CPU_SETUP);
- if (cpu_setup) {
+ if (get_plat_config()->flags & CONFIG_CPUECTLR_SMP_BIT) {
ectlr = read_cpuectlr();
ectlr &= ~CPUECTLR_SMP_BIT;
write_cpuectlr(ectlr);
@@ -171,8 +169,7 @@ int fvp_affinst_off(unsigned long mpidr,
* Prevent interrupts from spuriously waking up
* this cpu
*/
- gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR);
- gic_cpuif_deactivate(gicc_base);
+ arm_gic_cpuif_deactivate();
/*
* Program the power controller to power this
@@ -208,8 +205,8 @@ int fvp_affinst_suspend(unsigned long mpidr,
unsigned int state)
{
int rc = PSCI_E_SUCCESS;
- unsigned int gicc_base, ectlr;
- unsigned long cpu_setup, cci_setup, linear_id;
+ unsigned int ectlr;
+ unsigned long linear_id;
mailbox_t *fvp_mboxes;
switch (afflvl) {
@@ -219,10 +216,8 @@ int fvp_affinst_suspend(unsigned long mpidr,
* Disable coherency if this cluster is to be
* turned off
*/
- cci_setup = fvp_get_cfgvar(CONFIG_HAS_CCI);
- if (cci_setup) {
+ if (get_plat_config()->flags & CONFIG_HAS_CCI)
cci_disable_coherency(mpidr);
- }
/*
* Program the power controller to turn the
@@ -239,8 +234,7 @@ int fvp_affinst_suspend(unsigned long mpidr,
* Take this cpu out of intra-cluster coherency if
* the FVP flavour supports the SMP bit.
*/
- cpu_setup = fvp_get_cfgvar(CONFIG_CPU_SETUP);
- if (cpu_setup) {
+ if (get_plat_config()->flags & CONFIG_CPUECTLR_SMP_BIT) {
ectlr = read_cpuectlr();
ectlr &= ~CPUECTLR_SMP_BIT;
write_cpuectlr(ectlr);
@@ -257,8 +251,7 @@ int fvp_affinst_suspend(unsigned long mpidr,
* Prevent interrupts from spuriously waking up
* this cpu
*/
- gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR);
- gic_cpuif_deactivate(gicc_base);
+ arm_gic_cpuif_deactivate();
/*
* Program the power controller to power this
@@ -288,9 +281,9 @@ int fvp_affinst_on_finish(unsigned long mpidr,
unsigned int state)
{
int rc = PSCI_E_SUCCESS;
- unsigned long linear_id, cpu_setup;
+ unsigned long linear_id;
mailbox_t *fvp_mboxes;
- unsigned int gicd_base, gicc_base, ectlr;
+ unsigned int ectlr;
switch (afflvl) {
@@ -325,8 +318,7 @@ int fvp_affinst_on_finish(unsigned long mpidr,
* Turn on intra-cluster coherency if the FVP flavour supports
* it.
*/
- cpu_setup = fvp_get_cfgvar(CONFIG_CPU_SETUP);
- if (cpu_setup) {
+ if (get_plat_config()->flags & CONFIG_CPUECTLR_SMP_BIT) {
ectlr = read_cpuectlr();
ectlr |= CPUECTLR_SMP_BIT;
write_cpuectlr(ectlr);
@@ -345,14 +337,11 @@ int fvp_affinst_on_finish(unsigned long mpidr,
flush_dcache_range((unsigned long) &fvp_mboxes[linear_id],
sizeof(unsigned long));
- gicd_base = fvp_get_cfgvar(CONFIG_GICD_ADDR);
- gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR);
-
/* Enable the gic cpu interface */
- gic_cpuif_setup(gicc_base);
+ arm_gic_cpuif_setup();
/* TODO: This setup is needed only after a cold boot */
- gic_pcpu_distif_setup(gicd_base);
+ arm_gic_pcpu_distif_setup();
break;
diff --git a/plat/fvp/fvp_private.h b/plat/fvp/fvp_private.h
index 2331bb7e..054baa88 100644
--- a/plat/fvp/fvp_private.h
+++ b/plat/fvp/fvp_private.h
@@ -75,20 +75,11 @@ void fvp_configure_mmu_el3(unsigned long total_base,
unsigned long,
unsigned long,
unsigned long);
-unsigned long fvp_get_cfgvar(unsigned int);
int fvp_config_setup(void);
-#if RESET_TO_BL31
-void fvp_get_entry_point_info(unsigned long target_security,
- struct entry_point_info *target_entry_info);
-#endif
void fvp_cci_setup(void);
-/* Declarations for fvp_gic.c */
-void gic_cpuif_deactivate(unsigned int);
-void gic_cpuif_setup(unsigned int);
-void gic_pcpu_distif_setup(unsigned int);
-void gic_setup(void);
+void fvp_gic_init(void);
/* Declarations for fvp_topology.c */
int fvp_setup_topology(void);
@@ -99,11 +90,11 @@ void fvp_io_setup(void);
/* Declarations for fvp_security.c */
void fvp_security_setup(void);
-/* Sets the entrypoint for BL32 */
-void fvp_set_bl32_ep_info(struct entry_point_info *bl32_ep);
+/* Gets the SPR for BL32 entry */
+uint32_t fvp_get_spsr_for_bl32_entry(void);
-/* Sets the entrypoint for BL33 */
-void fvp_set_bl33_ep_info(struct entry_point_info *bl33_ep);
+/* Gets the SPSR for BL33 entry */
+uint32_t fvp_get_spsr_for_bl33_entry(void);
#endif /* __FVP_PRIVATE_H__ */
diff --git a/plat/fvp/fvp_security.c b/plat/fvp/fvp_security.c
index 76c45413..0adbbc5d 100644
--- a/plat/fvp/fvp_security.c
+++ b/plat/fvp/fvp_security.c
@@ -30,6 +30,7 @@
#include <assert.h>
#include <debug.h>
+#include <plat_config.h>
#include <tzc400.h>
#include "fvp_def.h"
#include "fvp_private.h"
@@ -56,7 +57,7 @@ void fvp_security_setup(void)
* configurations, those would be configured here.
*/
- if (!fvp_get_cfgvar(CONFIG_HAS_TZC))
+ if (!(get_plat_config()->flags & CONFIG_HAS_TZC))
return;
/*
diff --git a/plat/fvp/include/plat_macros.S b/plat/fvp/include/plat_macros.S
index d2e7cbc2..602eaf1d 100644
--- a/plat/fvp/include/plat_macros.S
+++ b/plat/fvp/include/plat_macros.S
@@ -29,7 +29,7 @@
*/
#include <gic_v2.h>
-#include "../fvp_def.h"
+#include <plat_config.h>
.section .rodata.gic_reg_name, "aS"
gic_regs: .asciz "gic_iar", "gic_ctlr", ""
@@ -43,8 +43,8 @@ gic_regs: .asciz "gic_iar", "gic_ctlr", ""
* ---------------------------------------------
*/
.macro plat_print_gic_regs
- mov x0, #CONFIG_GICC_ADDR
- bl fvp_get_cfgvar
+ adr x0, plat_config;
+ ldr w0, [x0, #CONFIG_GICC_BASE_OFFSET]
/* gic base address is now in x0 */
ldr w1, [x0, #GICC_IAR]
ldr w2, [x0, #GICC_CTLR]
diff --git a/plat/fvp/platform.mk b/plat/fvp/platform.mk
index d2003583..21ac1e73 100644
--- a/plat/fvp/platform.mk
+++ b/plat/fvp/platform.mk
@@ -68,24 +68,22 @@ BL2_SOURCES += drivers/arm/tzc400/tzc400.c \
plat/fvp/fvp_security.c \
plat/fvp/aarch64/fvp_common.c
-BL31_SOURCES += drivers/arm/gic/gic_v2.c \
+BL31_SOURCES += drivers/arm/cci400/cci400.c \
+ drivers/arm/gic/arm_gic.c \
+ drivers/arm/gic/gic_v2.c \
drivers/arm/gic/gic_v3.c \
- drivers/arm/cci400/cci400.c \
+ drivers/arm/tzc400/tzc400.c \
+ plat/common/plat_gic.c \
plat/common/aarch64/platform_mp_stack.S \
plat/fvp/bl31_fvp_setup.c \
- plat/fvp/fvp_gic.c \
plat/fvp/fvp_pm.c \
+ plat/fvp/fvp_security.c \
plat/fvp/fvp_topology.c \
plat/fvp/aarch64/fvp_helpers.S \
plat/fvp/aarch64/fvp_common.c \
plat/fvp/drivers/pwrc/fvp_pwrc.c
-ifeq (${RESET_TO_BL31}, 1)
-BL31_SOURCES += drivers/arm/tzc400/tzc400.c \
- plat/fvp/fvp_security.c
-endif
-
-# Flag used by the FVP port to determine the version of ARM GIC architecture
-# to use for interrupt management in EL3.
-FVP_GIC_ARCH := 2
-$(eval $(call add_define,FVP_GIC_ARCH))
+# Flag used by the platform port to determine the version of ARM GIC
+# architecture to use for interrupt management in EL3.
+ARM_GIC_ARCH := 2
+$(eval $(call add_define,ARM_GIC_ARCH))