Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
3fc938b5
Commit
3fc938b5
authored
Jul 10, 2014
by
danh-arm
Browse files
Merge pull request #146 from danh-arm/dh/refactor-fvp-gic
Refactor fvp config and gic code
parents
06bd0262
1e8c5c4f
Changes
16
Hide whitespace changes
Inline
Side-by-side
bl32/tsp/tsp-fvp.mk
View file @
3fc938b5
...
...
@@ -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
docs/user-guide.md
View file @
3fc938b5
...
...
@@ -158,9 +158,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
...
...
plat/fvp/fvp
_gic.c
→
drivers/arm/gic/arm
_gic.c
View file @
3fc938b5
/*
* 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
();
/* commit
e
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_g
ic_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_g
ic_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_g
ic_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_g
ic_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_g
ic_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 */
include/drivers/arm/arm_gic.h
0 → 100644
View file @
3fc938b5
/*
* 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__ */
include/drivers/arm/gic_v2.h
View file @
3fc938b5
...
...
@@ -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
...
...
include/plat/common/plat_config.h
0 → 100644
View file @
3fc938b5
/*
* 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__ */
plat/common/plat_gic.c
0 → 100644
View file @
3fc938b5
/*
* 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
);
}
plat/fvp/aarch64/fvp_common.c
View file @
3fc938b5
...
...
@@ -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
...
...
@@ -142,16 +154,16 @@ 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:
ERROR
(
"Unsupported board build %x
\n
"
,
bld
);
...
...
@@ -164,12 +176,9 @@ 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
...
...
@@ -186,16 +195,14 @@ int fvp_config_setup(void)
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
;
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
;
plat_config
.
max_aff0
=
4
;
plat_config
.
max_aff1
=
2
;
plat_config
.
flags
|=
CONFIG_BASE_MMAP
|
CONFIG_HAS_CCI
|
CONFIG_HAS_TZC
;
/*
* Check for supported revisions
...
...
@@ -237,18 +244,24 @@ 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
);
}
/*******************************************************************************
* Gets SPSR for BL32 entry
...
...
plat/fvp/bl31_fvp_setup.c
View file @
3fc938b5
...
...
@@ -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>
...
...
@@ -183,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
...
...
plat/fvp/bl32_fvp_setup.c
View file @
3fc938b5
...
...
@@ -83,7 +83,7 @@ void bl32_early_platform_setup(void)
******************************************************************************/
void
bl32_platform_setup
(
void
)
{
fvp_gic_init
();
}
/*******************************************************************************
...
...
plat/fvp/fvp_def.h
View file @
3fc938b5
...
...
@@ -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
******************************************************************************/
...
...
plat/fvp/fvp_pm.c
View file @
3fc938b5
...
...
@@ -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
;
...
...
plat/fvp/fvp_private.h
View file @
3fc938b5
...
...
@@ -75,16 +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
);
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
);
...
...
plat/fvp/fvp_security.c
View file @
3fc938b5
...
...
@@ -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
;
/*
...
...
plat/fvp/include/plat_macros.S
View file @
3fc938b5
...
...
@@ -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
]
...
...
plat/fvp/platform.mk
View file @
3fc938b5
...
...
@@ -69,12 +69,13 @@ BL2_SOURCES += drivers/arm/tzc400/tzc400.c \
plat/fvp/aarch64/fvp_common.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/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
\
...
...
@@ -82,7 +83,7 @@ BL31_SOURCES += drivers/arm/cci400/cci400.c \
plat/fvp/aarch64/fvp_common.c
\
plat/fvp/drivers/pwrc/fvp_pwrc.c
# 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))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment