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
a773abb6
Commit
a773abb6
authored
May 20, 2020
by
Mark Dykes
Committed by
TrustedFirmware Code Review
May 20, 2020
Browse files
Merge "plat/fvp: Populate GICv3 parameters dynamically" into integration
parents
c6ef55c5
8370c8ce
Changes
3
Hide whitespace changes
Inline
Side-by-side
plat/arm/board/fvp/fvp_gicv3.c
0 → 100644
View file @
a773abb6
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <platform_def.h>
#include <common/interrupt_props.h>
#include <drivers/arm/gicv3.h>
#include <fconf_hw_config_getter.h>
#include <lib/utils.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
/* The GICv3 driver only needs to be initialized in EL3 */
static
uintptr_t
fvp_rdistif_base_addrs
[
PLATFORM_CORE_COUNT
];
/* Default GICR base address to be used for GICR probe. */
static
uint64_t
fvp_gicr_base_addrs
[
2
]
=
{
0U
};
/* List of zero terminated GICR frame addresses which CPUs will probe */
static
uint64_t
*
fvp_gicr_frames
=
fvp_gicr_base_addrs
;
static
const
interrupt_prop_t
fvp_interrupt_props
[]
=
{
PLAT_ARM_G1S_IRQ_PROPS
(
INTR_GROUP1S
),
PLAT_ARM_G0_IRQ_PROPS
(
INTR_GROUP0
)
};
/*
* MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
* to core position.
*
* Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
* values read from GICR_TYPER don't have an MT field. To reuse the same
* translation used for CPUs, we insert MT bit read from the PE's MPIDR into
* that read from GICR_TYPER.
*
* Assumptions:
*
* - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
* - No CPUs implemented in the system use affinity level 3.
*/
static
unsigned
int
fvp_gicv3_mpidr_hash
(
u_register_t
mpidr
)
{
u_register_t
temp_mpidr
=
mpidr
;
temp_mpidr
|=
(
read_mpidr_el1
()
&
MPIDR_MT_MASK
);
return
plat_arm_calc_core_pos
(
temp_mpidr
);
}
static
gicv3_driver_data_t
fvp_gic_data
=
{
.
interrupt_props
=
fvp_interrupt_props
,
.
interrupt_props_num
=
ARRAY_SIZE
(
fvp_interrupt_props
),
.
rdistif_num
=
PLATFORM_CORE_COUNT
,
.
rdistif_base_addrs
=
fvp_rdistif_base_addrs
,
.
mpidr_to_core_pos
=
fvp_gicv3_mpidr_hash
};
void
plat_arm_gic_driver_init
(
void
)
{
/* Get GICD and GICR base addressed through FCONF APIs */
#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
(defined(__aarch64__) && defined(IMAGE_BL31))
fvp_gic_data
.
gicd_base
=
(
uintptr_t
)
FCONF_GET_PROPERTY
(
hw_config
,
gicv3_config
,
gicd_base
);
fvp_gicr_base_addrs
[
0
]
=
FCONF_GET_PROPERTY
(
hw_config
,
gicv3_config
,
gicr_base
);
#else
fvp_gic_data
.
gicd_base
=
PLAT_ARM_GICD_BASE
;
fvp_gicr_base_addrs
[
0
]
=
PLAT_ARM_GICR_BASE
;
#endif
/*
* The GICv3 driver is initialized in EL3 and does not need
* to be initialized again in SEL1. This is because the S-EL1
* can use GIC system registers to manage interrupts and does
* not need GIC interface base addresses to be configured.
*/
#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
(defined(__aarch64__) && defined(IMAGE_BL31))
gicv3_driver_init
(
&
fvp_gic_data
);
if
(
gicv3_rdistif_probe
((
uintptr_t
)
fvp_gicr_base_addrs
[
0
])
==
-
1
)
{
ERROR
(
"No GICR base frame found for Primary CPU
\n
"
);
panic
();
}
#endif
}
/******************************************************************************
* Function to iterate over all GICR frames and discover the corresponding
* per-cpu redistributor frame as well as initialize the corresponding
* interface in GICv3.
*****************************************************************************/
void
plat_arm_gic_pcpu_init
(
void
)
{
int
result
;
const
uint64_t
*
plat_gicr_frames
=
fvp_gicr_frames
;
do
{
result
=
gicv3_rdistif_probe
(
*
plat_gicr_frames
);
/* If the probe is successful, no need to proceed further */
if
(
result
==
0
)
break
;
plat_gicr_frames
++
;
}
while
(
*
plat_gicr_frames
!=
0U
);
if
(
result
==
-
1
)
{
ERROR
(
"No GICR base frame found for CPU 0x%lx
\n
"
,
read_mpidr
());
panic
();
}
gicv3_rdistif_init
(
plat_my_core_pos
());
}
plat/arm/board/fvp/include/fconf_hw_config_getter.h
View file @
a773abb6
...
...
@@ -15,8 +15,8 @@
#define hw_config__topology_getter(prop) soc_topology.prop
struct
gicv3_config_t
{
uint
ptr
_t
gicd_base
;
uint
ptr
_t
gicr_base
;
uint
64
_t
gicd_base
;
uint
64
_t
gicr_base
;
};
struct
hw_topology_t
{
...
...
plat/arm/board/fvp/platform.mk
View file @
a773abb6
...
...
@@ -65,6 +65,10 @@ FVP_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c
\
plat/arm/common/arm_gicv3.c
ifeq
($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31} ${RESET_TO_SP_MIN}),)
FVP_GIC_SOURCES
+=
plat/arm/board/fvp/fvp_gicv3.c
endif
else
ifeq
(${FVP_USE_GIC_DRIVER}, FVP_GICV2)
# No GICv4 extension
...
...
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