Merge pull request #1046 from jeenu-arm/revc

Support for RevC FVP model
This commit is contained in:
danh-arm 2017-08-14 15:32:27 +01:00 committed by GitHub
commit a937d93e5c
23 changed files with 756 additions and 371 deletions

View File

@ -465,7 +465,6 @@ $(eval $(call assert_numeric,ARM_ARCH_MINOR))
# platform to overwrite the default options
################################################################################
$(eval $(call add_define,ARM_CCI_PRODUCT_ID))
$(eval $(call add_define,ARM_ARCH_MAJOR))
$(eval $(call add_define,ARM_ARCH_MINOR))
$(eval $(call add_define,ARM_GIC_ARCH))

View File

@ -213,10 +213,6 @@ Common build options
It can take either ``aarch64`` or ``aarch32`` as values. By default, it is
defined to ``aarch64``.
- ``ARM_CCI_PRODUCT_ID``: Choice of ARM CCI product used by the platform. This
is used to determine the number of valid slave interfaces available in the
ARM CCI driver. Default is 400 (that is, CCI-400).
- ``ARM_ARCH_MAJOR``: The major version of ARM Architecture to target when
compiling ARM Trusted Firmware. Its value must be numeric, and defaults to
8 . See also, *ARMv8 Architecture Extensions* in `Firmware Design`_.
@ -231,10 +227,10 @@ Common build options
This build option is deprecated.
- ``ARM_PLAT_MT``: This flag determines whether the ARM platform layer has to
cater for the multi-threading ``MT`` bit when accessing MPIDR. When this
flag is set, the functions which deal with MPIDR assume that the ``MT`` bit
in MPIDR is set and access the bit-fields in MPIDR accordingly. Default
value of this flag is 0.
cater for the multi-threading ``MT`` bit when accessing MPIDR. When this flag
is set, the functions which deal with MPIDR assume that the ``MT`` bit in
MPIDR is set and access the bit-fields in MPIDR accordingly. Default value of
this flag is 0. Note that this option is not used on FVP platforms.
- ``BL2``: This is an optional build option which specifies the path to BL2
image for the ``fip`` target. In this case, the BL2 in the ARM Trusted
@ -677,6 +673,10 @@ ARM FVP platform specific build options
- ``FVP_CCN`` : The CCN driver is selected. This is the default
if ``FVP_CLUSTER_COUNT`` > 2.
- ``FVP_MAX_PE_PER_CPU``: Sets the maximum number of PEs implemented on any CPU
in the system. This option defaults to 1. Note that the build option
``ARM_PLAT_MT`` doesn't have any effect on FVP platforms.
- ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
- ``FVP_GIC600`` : The GIC600 implementation of GICv3 is selected

View File

@ -11,11 +11,26 @@
#include <mmio.h>
#include <stdint.h>
static uintptr_t g_cci_base;
static unsigned int g_max_master_id;
static const int *g_cci_slave_if_map;
#define MAKE_CCI_PART_NUMBER(hi, lo) ((hi << 8) | lo)
#define CCI_PART_LO_MASK 0xff
#define CCI_PART_HI_MASK 0xf
/* CCI part number codes read from Peripheral ID registers 0 and 1 */
#define CCI400_PART_NUM 0x420
#define CCI500_PART_NUM 0x422
#define CCI550_PART_NUM 0x423
#define CCI400_SLAVE_PORTS 5
#define CCI500_SLAVE_PORTS 7
#define CCI550_SLAVE_PORTS 7
static uintptr_t cci_base;
static const int *cci_slave_if_map;
#if ENABLE_ASSERTIONS
static unsigned int max_master_id;
static int cci_num_slave_ports;
static int validate_cci_map(const int *map)
{
unsigned int valid_cci_map = 0;
@ -23,13 +38,13 @@ static int validate_cci_map(const int *map)
int i;
/* Validate the map */
for (i = 0; i <= g_max_master_id; i++) {
for (i = 0; i <= max_master_id; i++) {
slave_if_id = map[i];
if (slave_if_id < 0)
continue;
if (slave_if_id >= CCI_SLAVE_INTERFACE_COUNT) {
if (slave_if_id >= cci_num_slave_ports) {
ERROR("Slave interface ID is invalid\n");
return 0;
}
@ -48,70 +63,105 @@ static int validate_cci_map(const int *map)
return 1;
}
/*
* Read CCI part number from Peripheral ID registers
*/
static unsigned int read_cci_part_number(uintptr_t base)
{
unsigned int part_lo, part_hi;
part_lo = mmio_read_32(base + PERIPHERAL_ID0) & CCI_PART_LO_MASK;
part_hi = mmio_read_32(base + PERIPHERAL_ID1) & CCI_PART_HI_MASK;
return MAKE_CCI_PART_NUMBER(part_hi, part_lo);
}
/*
* Identify a CCI device, and return the number of slaves. Return -1 for an
* unidentified device.
*/
static int get_slave_ports(unsigned int part_num)
{
/* Macro to match CCI products */
#define RET_ON_MATCH(product) \
case CCI ## product ## _PART_NUM: \
return CCI ## product ## _SLAVE_PORTS
switch (part_num) {
RET_ON_MATCH(400);
RET_ON_MATCH(500);
RET_ON_MATCH(550);
default:
return -1;
}
#undef RET_ON_MATCH
}
#endif /* ENABLE_ASSERTIONS */
void cci_init(uintptr_t cci_base,
const int *map,
unsigned int num_cci_masters)
void cci_init(uintptr_t base, const int *map, unsigned int num_cci_masters)
{
assert(map);
assert(cci_base);
assert(base);
g_cci_base = cci_base;
cci_base = base;
cci_slave_if_map = map;
#if ENABLE_ASSERTIONS
/*
* Master Id's are assigned from zero, So in an array of size n
* the max master id is (n - 1).
*/
g_max_master_id = num_cci_masters - 1;
max_master_id = num_cci_masters - 1;
cci_num_slave_ports = get_slave_ports(read_cci_part_number(base));
#endif
assert(cci_num_slave_ports >= 0);
assert(validate_cci_map(map));
g_cci_slave_if_map = map;
}
void cci_enable_snoop_dvm_reqs(unsigned int master_id)
{
int slave_if_id;
int slave_if_id = cci_slave_if_map[master_id];
assert(g_cci_base);
assert(master_id <= g_max_master_id);
slave_if_id = g_cci_slave_if_map[master_id];
assert((slave_if_id < CCI_SLAVE_INTERFACE_COUNT) && (slave_if_id >= 0));
assert(master_id <= max_master_id);
assert((slave_if_id < cci_num_slave_ports) && (slave_if_id >= 0));
assert(cci_base);
/*
* Enable Snoops and DVM messages, no need for Read/Modify/Write as
* rest of bits are write ignore
*/
mmio_write_32(g_cci_base +
SLAVE_IFACE_OFFSET(slave_if_id) +
SNOOP_CTRL_REG, DVM_EN_BIT | SNOOP_EN_BIT);
mmio_write_32(cci_base +
SLAVE_IFACE_OFFSET(slave_if_id) + SNOOP_CTRL_REG,
DVM_EN_BIT | SNOOP_EN_BIT);
/* Wait for the dust to settle down */
while (mmio_read_32(g_cci_base + STATUS_REG) & CHANGE_PENDING_BIT)
while (mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT)
;
}
void cci_disable_snoop_dvm_reqs(unsigned int master_id)
{
int slave_if_id;
int slave_if_id = cci_slave_if_map[master_id];
assert(g_cci_base);
assert(master_id <= g_max_master_id);
slave_if_id = g_cci_slave_if_map[master_id];
assert((slave_if_id < CCI_SLAVE_INTERFACE_COUNT) && (slave_if_id >= 0));
assert(master_id <= max_master_id);
assert((slave_if_id < cci_num_slave_ports) && (slave_if_id >= 0));
assert(cci_base);
/*
* Disable Snoops and DVM messages, no need for Read/Modify/Write as
* rest of bits are write ignore.
*/
mmio_write_32(g_cci_base +
SLAVE_IFACE_OFFSET(slave_if_id) +
SNOOP_CTRL_REG, ~(DVM_EN_BIT | SNOOP_EN_BIT));
mmio_write_32(cci_base +
SLAVE_IFACE_OFFSET(slave_if_id) + SNOOP_CTRL_REG,
~(DVM_EN_BIT | SNOOP_EN_BIT));
/* Wait for the dust to settle down */
while (mmio_read_32(g_cci_base + STATUS_REG) & CHANGE_PENDING_BIT)
while (mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT)
;
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mmio.h>
#include <smmu_v3.h>
/* Test for pending invalidate */
#define INVAL_PENDING(base) \
smmuv3_read_s_init(base) & SMMU_S_INIT_INV_ALL_MASK
static inline uint32_t smmuv3_read_s_idr1(uintptr_t base)
{
return mmio_read_32(base + SMMU_S_IDR1);
}
static inline uint32_t smmuv3_read_s_init(uintptr_t base)
{
return mmio_read_32(base + SMMU_S_INIT);
}
static inline void smmuv3_write_s_init(uintptr_t base, uint32_t value)
{
mmio_write_32(base + SMMU_S_INIT, value);
}
/*
* Initialize the SMMU by invalidating all secure caches and TLBs.
*
* Returns 0 on success, and -1 on failure.
*/
int smmuv3_init(uintptr_t smmu_base)
{
uint32_t idr1_reg;
/*
* Invalidation of secure caches and TLBs is required only if the SMMU
* supports secure state. If not, it's implementation defined as to how
* SMMU_S_INIT register is accessed.
*/
idr1_reg = smmuv3_read_s_idr1(smmu_base);
if (!((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) &
SMMU_S_IDR1_SECURE_IMPL_MASK)) {
return -1;
}
/* Initiate invalidation, and wait for it to finish */
smmuv3_write_s_init(smmu_base, SMMU_S_INIT_INV_ALL_MASK);
while (INVAL_PENDING(smmu_base))
;
return 0;
}

Binary file not shown.

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/dts-v1/;
/include/ "fvp-base-gicv3-psci-common.dtsi"
&CPU0 {
reg = <0x0 0x0>;
};
&CPU1 {
reg = <0x0 0x100>;
};
&CPU2 {
reg = <0x0 0x200>;
};
&CPU3 {
reg = <0x0 0x300>;
};
&CPU4 {
reg = <0x0 0x10000>;
};
&CPU5 {
reg = <0x0 0x10100>;
};
&CPU6 {
reg = <0x0 0x10200>;
};
&CPU7 {
reg = <0x0 0x10300>;
};

View File

@ -0,0 +1,268 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/memreserve/ 0x80000000 0x00010000;
/ {
};
/ {
model = "FVP Base";
compatible = "arm,vfp-base", "arm,vexpress";
interrupt-parent = <&gic>;
#address-cells = <2>;
#size-cells = <2>;
chosen { };
aliases {
serial0 = &v2m_serial0;
serial1 = &v2m_serial1;
serial2 = &v2m_serial2;
serial3 = &v2m_serial3;
};
psci {
compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
method = "smc";
cpu_suspend = <0xc4000001>;
cpu_off = <0x84000002>;
cpu_on = <0xc4000003>;
sys_poweroff = <0x84000008>;
sys_reset = <0x84000009>;
};
cpus {
#address-cells = <2>;
#size-cells = <0>;
cpu-map {
cluster0 {
core0 {
cpu = <&CPU0>;
};
core1 {
cpu = <&CPU1>;
};
core2 {
cpu = <&CPU2>;
};
core3 {
cpu = <&CPU3>;
};
};
cluster1 {
core0 {
cpu = <&CPU4>;
};
core1 {
cpu = <&CPU5>;
};
core2 {
cpu = <&CPU6>;
};
core3 {
cpu = <&CPU7>;
};
};
};
idle-states {
entry-method = "arm,psci";
CPU_SLEEP_0: cpu-sleep-0 {
compatible = "arm,idle-state";
local-timer-stop;
arm,psci-suspend-param = <0x0010000>;
entry-latency-us = <40>;
exit-latency-us = <100>;
min-residency-us = <150>;
};
CLUSTER_SLEEP_0: cluster-sleep-0 {
compatible = "arm,idle-state";
local-timer-stop;
arm,psci-suspend-param = <0x1010000>;
entry-latency-us = <500>;
exit-latency-us = <1000>;
min-residency-us = <2500>;
};
};
CPU0:cpu@0 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x0>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU1:cpu@1 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x1>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU2:cpu@2 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x2>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU3:cpu@3 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x3>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU4:cpu@100 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x100>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU5:cpu@101 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x101>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU6:cpu@102 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x102>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU7:cpu@103 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x103>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
L2_0: l2-cache0 {
compatible = "cache";
};
};
memory@80000000 {
device_type = "memory";
reg = <0x00000000 0x80000000 0 0x7F000000>,
<0x00000008 0x80000000 0 0x80000000>;
};
gic: interrupt-controller@2f000000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
interrupt-controller;
reg = <0x0 0x2f000000 0 0x10000>, // GICD
<0x0 0x2f100000 0 0x200000>, // GICR
<0x0 0x2c000000 0 0x2000>, // GICC
<0x0 0x2c010000 0 0x2000>, // GICH
<0x0 0x2c02f000 0 0x2000>; // GICV
interrupts = <1 9 4>;
its: its@2f020000 {
compatible = "arm,gic-v3-its";
msi-controller;
reg = <0x0 0x2f020000 0x0 0x20000>; // GITS
};
};
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0xff01>,
<1 14 0xff01>,
<1 11 0xff01>,
<1 10 0xff01>;
clock-frequency = <100000000>;
};
timer@2a810000 {
compatible = "arm,armv7-timer-mem";
reg = <0x0 0x2a810000 0x0 0x10000>;
clock-frequency = <100000000>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
frame@2a830000 {
frame-number = <1>;
interrupts = <0 26 4>;
reg = <0x0 0x2a830000 0x0 0x10000>;
};
};
pmu {
compatible = "arm,armv8-pmuv3";
interrupts = <0 60 4>,
<0 61 4>,
<0 62 4>,
<0 63 4>;
};
smb {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0 0x08000000 0x04000000>,
<1 0 0 0x14000000 0x04000000>,
<2 0 0 0x18000000 0x04000000>,
<3 0 0 0x1c000000 0x04000000>,
<4 0 0 0x0c000000 0x04000000>,
<5 0 0 0x10000000 0x04000000>;
/include/ "rtsm_ve-motherboard.dtsi"
};
panels {
panel@0 {
compatible = "panel";
mode = "XVGA";
refresh = <60>;
xres = <1024>;
yres = <768>;
pixclock = <15748>;
left_margin = <152>;
right_margin = <48>;
upper_margin = <23>;
lower_margin = <3>;
hsync_len = <104>;
vsync_len = <4>;
sync = <0>;
vmode = "FB_VMODE_NONINTERLACED";
tim2 = "TIM2_BCD", "TIM2_IPC";
cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
bpp = <16>;
};
};
};

View File

@ -6,265 +6,4 @@
/dts-v1/;
/memreserve/ 0x80000000 0x00010000;
/ {
};
/ {
model = "FVP Base";
compatible = "arm,vfp-base", "arm,vexpress";
interrupt-parent = <&gic>;
#address-cells = <2>;
#size-cells = <2>;
chosen { };
aliases {
serial0 = &v2m_serial0;
serial1 = &v2m_serial1;
serial2 = &v2m_serial2;
serial3 = &v2m_serial3;
};
psci {
compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
method = "smc";
cpu_suspend = <0xc4000001>;
cpu_off = <0x84000002>;
cpu_on = <0xc4000003>;
sys_poweroff = <0x84000008>;
sys_reset = <0x84000009>;
};
cpus {
#address-cells = <2>;
#size-cells = <0>;
cpu-map {
cluster0 {
core0 {
cpu = <&CPU0>;
};
core1 {
cpu = <&CPU1>;
};
core2 {
cpu = <&CPU2>;
};
core3 {
cpu = <&CPU3>;
};
};
cluster1 {
core0 {
cpu = <&CPU4>;
};
core1 {
cpu = <&CPU5>;
};
core2 {
cpu = <&CPU6>;
};
core3 {
cpu = <&CPU7>;
};
};
};
idle-states {
entry-method = "arm,psci";
CPU_SLEEP_0: cpu-sleep-0 {
compatible = "arm,idle-state";
local-timer-stop;
arm,psci-suspend-param = <0x0010000>;
entry-latency-us = <40>;
exit-latency-us = <100>;
min-residency-us = <150>;
};
CLUSTER_SLEEP_0: cluster-sleep-0 {
compatible = "arm,idle-state";
local-timer-stop;
arm,psci-suspend-param = <0x1010000>;
entry-latency-us = <500>;
exit-latency-us = <1000>;
min-residency-us = <2500>;
};
};
CPU0:cpu@0 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x0>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU1:cpu@1 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x1>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU2:cpu@2 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x2>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU3:cpu@3 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x3>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU4:cpu@100 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x100>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU5:cpu@101 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x101>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU6:cpu@102 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x102>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
CPU7:cpu@103 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x103>;
enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
};
L2_0: l2-cache0 {
compatible = "cache";
};
};
memory@80000000 {
device_type = "memory";
reg = <0x00000000 0x80000000 0 0x7F000000>,
<0x00000008 0x80000000 0 0x80000000>;
};
gic: interrupt-controller@2f000000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
interrupt-controller;
reg = <0x0 0x2f000000 0 0x10000>, // GICD
<0x0 0x2f100000 0 0x200000>, // GICR
<0x0 0x2c000000 0 0x2000>, // GICC
<0x0 0x2c010000 0 0x2000>, // GICH
<0x0 0x2c02f000 0 0x2000>; // GICV
interrupts = <1 9 4>;
its: its@2f020000 {
compatible = "arm,gic-v3-its";
msi-controller;
reg = <0x0 0x2f020000 0x0 0x20000>; // GITS
};
};
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0xff01>,
<1 14 0xff01>,
<1 11 0xff01>,
<1 10 0xff01>;
clock-frequency = <100000000>;
};
timer@2a810000 {
compatible = "arm,armv7-timer-mem";
reg = <0x0 0x2a810000 0x0 0x10000>;
clock-frequency = <100000000>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
frame@2a830000 {
frame-number = <1>;
interrupts = <0 26 4>;
reg = <0x0 0x2a830000 0x0 0x10000>;
};
};
pmu {
compatible = "arm,armv8-pmuv3";
interrupts = <0 60 4>,
<0 61 4>,
<0 62 4>,
<0 63 4>;
};
smb {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0 0x08000000 0x04000000>,
<1 0 0 0x14000000 0x04000000>,
<2 0 0 0x18000000 0x04000000>,
<3 0 0 0x1c000000 0x04000000>,
<4 0 0 0x0c000000 0x04000000>,
<5 0 0 0x10000000 0x04000000>;
/include/ "rtsm_ve-motherboard.dtsi"
};
panels {
panel@0 {
compatible = "panel";
mode = "XVGA";
refresh = <60>;
xres = <1024>;
yres = <768>;
pixclock = <15748>;
left_margin = <152>;
right_margin = <48>;
upper_margin = <23>;
lower_margin = <3>;
hsync_len = <104>;
vsync_len = <4>;
sync = <0>;
vmode = "FB_VMODE_NONINTERLACED";
tim2 = "TIM2_BCD", "TIM2_IPC";
cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
bpp = <16>;
};
};
};
/include/ "fvp-base-gicv3-psci-common.dtsi"

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -98,14 +98,6 @@
#define SLAVE_IF_UNUSED -1
#if ARM_CCI_PRODUCT_ID == 400
#define CCI_SLAVE_INTERFACE_COUNT 5
#elif ARM_CCI_PRODUCT_ID == 500
#define CCI_SLAVE_INTERFACE_COUNT 7
#else
#error "Invalid CCI product or CCI not supported"
#endif
#ifndef __ASSEMBLY__
#include <stdint.h>
@ -114,7 +106,7 @@
/*
* The ARM CCI driver needs the following:
* 1. Base address of the CCI-500/CCI-400
* 1. Base address of the CCI product
* 2. An array of map between AMBA 4 master ids and ACE/ACE lite slave
* interfaces.
* 3. Size of the array.
@ -122,9 +114,7 @@
* SLAVE_IF_UNUSED should be used in the map to represent no AMBA 4 master exists
* for that interface.
*/
void cci_init(uintptr_t cci_base,
const int *map,
unsigned int num_cci_masters);
void cci_init(uintptr_t base, const int *map, unsigned int num_cci_masters);
void cci_enable_snoop_dvm_reqs(unsigned int master_id);
void cci_disable_snoop_dvm_reqs(unsigned int master_id);

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __SMMU_V3_H__
#define __SMMU_V3_H__
#include <stdint.h>
/* SMMUv3 register offsets from device base */
#define SMMU_S_IDR1 0x8004
#define SMMU_S_INIT 0x803c
/* SMMU_S_IDR1 register fields */
#define SMMU_S_IDR1_SECURE_IMPL_SHIFT 31
#define SMMU_S_IDR1_SECURE_IMPL_MASK 0x1
/* SMMU_S_INIT register fields */
#define SMMU_S_INIT_INV_ALL_MASK 0x1
int smmuv3_init(uintptr_t smmu_base);
#endif /* __SMMU_V3_H__ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,14 +7,20 @@
#define __ARM_CONFIG_H__
#include <stdint.h>
#include <utils_def.h>
enum arm_config_flags {
/* Whether Base memory map is in use */
ARM_CONFIG_BASE_MMAP = 0x1,
/* Whether interconnect should be enabled */
ARM_CONFIG_HAS_INTERCONNECT = 0x2,
ARM_CONFIG_BASE_MMAP = BIT(1),
/* Whether TZC should be configured */
ARM_CONFIG_HAS_TZC = 0x4
ARM_CONFIG_HAS_TZC = BIT(2),
/* FVP model has shifted affinity */
ARM_CONFIG_FVP_SHIFTED_AFF = BIT(3),
/* FVP model has SMMUv3 affinity */
ARM_CONFIG_FVP_HAS_SMMUV3 = BIT(4),
/* FVP model has CCI (400 or 500/550) devices */
ARM_CONFIG_FVP_HAS_CCI400 = BIT(5),
ARM_CONFIG_FVP_HAS_CCI5XX = BIT(6),
};
typedef struct arm_config {

View File

@ -16,10 +16,6 @@ AARCH32_SP := none
# The Target build architecture. Supported values are: aarch64, aarch32.
ARCH := aarch64
# Determine the version of ARM CCI product used in the platform. The platform
# port can change this value if needed.
ARM_CCI_PRODUCT_ID := 400
# ARM Architecture major and minor versions: 8.0 by default.
ARM_ARCH_MAJOR := 8
ARM_ARCH_MINOR := 0

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -13,6 +13,7 @@
.globl plat_secondary_cold_boot_setup
.globl plat_get_my_entrypoint
.globl plat_is_my_cpu_primary
.globl plat_arm_calc_core_pos
/* --------------------------------------------------------------------
* void plat_secondary_cold_boot_setup (void);
@ -95,10 +96,43 @@ endfunc plat_get_my_entrypoint
*/
func plat_is_my_cpu_primary
ldcopr r0, MPIDR
ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
ldr r1, =MPIDR_AFFINITY_MASK
and r0, r1
cmp r0, #FVP_PRIMARY_CPU
moveq r0, #1
movne r0, #0
bx lr
endfunc plat_is_my_cpu_primary
/* -----------------------------------------------------
* unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
*
* Function to calculate the core position on FVP.
*
* (ClusterId * FVP_MAX_CPUS_PER_CLUSTER) +
* (CPUId * FVP_MAX_PE_PER_CPU) +
* ThreadId
* -----------------------------------------------------
*/
func plat_arm_calc_core_pos
mov r3, r0
/*
* Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
* look as if in a multi-threaded implementation
*/
tst r0, #MPIDR_MT_MASK
lsleq r3, r0, #MPIDR_AFFINITY_BITS
/* Extract individual affinity fields from MPIDR */
mov r2, #FVP_MAX_PE_PER_CPU
ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
mla r0, r1, r2, r0
mov r1, #FVP_MAX_CPUS_PER_CLUSTER
ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
mla r0, r1, r2, r0
bx lr
endfunc plat_arm_calc_core_pos

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -16,6 +16,7 @@
.globl plat_secondary_cold_boot_setup
.globl plat_get_my_entrypoint
.globl plat_is_my_cpu_primary
.globl plat_arm_calc_core_pos
.macro fvp_choose_gicmmap param1, param2, x_tmp, w_tmp, res
ldr \x_tmp, =V2M_SYSREGS_BASE + V2M_SYS_ID
@ -170,8 +171,43 @@ endfunc plat_get_my_entrypoint
*/
func plat_is_my_cpu_primary
mrs x0, mpidr_el1
and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
ldr x1, =MPIDR_AFFINITY_MASK
and x0, x0, x1
cmp x0, #FVP_PRIMARY_CPU
cset w0, eq
ret
endfunc plat_is_my_cpu_primary
/* -----------------------------------------------------
* unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
*
* Function to calculate the core position on FVP.
*
* (ClusterId * FVP_MAX_CPUS_PER_CLUSTER) +
* (CPUId * FVP_MAX_PE_PER_CPU) +
* ThreadId
* -----------------------------------------------------
*/
func plat_arm_calc_core_pos
mov x3, x0
/*
* Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
* look as if in a multi-threaded implementation.
*/
tst x0, #MPIDR_MT_MASK
lsl x3, x0, #MPIDR_AFFINITY_BITS
csel x3, x3, x0, eq
/* Extract individual affinity fields from MPIDR */
ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
/* Compute linear position */
mov x4, #FVP_MAX_PE_PER_CPU
madd x0, x1, x4, x0
mov x5, #FVP_MAX_CPUS_PER_CLUSTER
madd x0, x2, x5, x0
ret
endfunc plat_arm_calc_core_pos

View File

@ -1,10 +1,12 @@
/*
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arm_config.h>
#include <plat_arm.h>
#include <smmu_v3.h>
#include "fvp_private.h"
#if LOAD_IMAGE_V2
@ -34,4 +36,8 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
* FVP PSCI code will enable coherency for other clusters.
*/
fvp_interconnect_enable();
/* On FVP RevC, intialize SMMUv3 */
if (arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3)
smmuv3_init(PLAT_FVP_SMMUV3_BASE);
}

View File

@ -1,11 +1,13 @@
/*
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arm_config.h>
#include <arm_def.h>
#include <assert.h>
#include <cci.h>
#include <ccn.h>
#include <debug.h>
#include <gicv2.h>
@ -118,6 +120,30 @@ const mmap_region_t plat_arm_mmap[] = {
ARM_CASSERT_MMAP
#if FVP_INTERCONNECT_DRIVER != FVP_CCN
static const int fvp_cci400_map[] = {
PLAT_FVP_CCI400_CLUS0_SL_PORT,
PLAT_FVP_CCI400_CLUS1_SL_PORT,
};
static const int fvp_cci5xx_map[] = {
PLAT_FVP_CCI5XX_CLUS0_SL_PORT,
PLAT_FVP_CCI5XX_CLUS1_SL_PORT,
};
static unsigned int get_interconnect_master(void)
{
unsigned int master;
u_register_t mpidr;
mpidr = read_mpidr_el1();
master = (arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) ?
MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);
assert(master < FVP_CLUSTER_COUNT);
return master;
}
#endif
/*******************************************************************************
* A single boot loader stack is expected to work on both the Foundation FVP
@ -182,8 +208,7 @@ void fvp_config_setup(void)
}
break;
case HBI_BASE_FVP:
arm_config.flags |= ARM_CONFIG_BASE_MMAP |
ARM_CONFIG_HAS_INTERCONNECT | ARM_CONFIG_HAS_TZC;
arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC);
/*
* Check for supported revisions
@ -191,6 +216,12 @@ void fvp_config_setup(void)
*/
switch (rev) {
case REV_BASE_FVP_V0:
arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400;
break;
case REV_BASE_FVP_REVC:
arm_config.flags |= (ARM_CONFIG_FVP_SHIFTED_AFF |
ARM_CONFIG_FVP_HAS_SMMUV3 |
ARM_CONFIG_FVP_HAS_CCI5XX);
break;
default:
WARN("Unrecognized Base FVP revision %x\n", rev);
@ -206,26 +237,67 @@ void fvp_config_setup(void)
void fvp_interconnect_init(void)
{
if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT) {
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
ERROR("Unrecognized CCN variant detected. Only CCN-502"
" is supported");
panic();
}
#endif
plat_arm_interconnect_init();
if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
ERROR("Unrecognized CCN variant detected. Only CCN-502"
" is supported");
panic();
}
plat_arm_interconnect_init();
#else
uintptr_t cci_base = 0;
const int *cci_map = 0;
unsigned int map_size = 0;
if (!(arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
ARM_CONFIG_FVP_HAS_CCI5XX))) {
return;
}
/* Initialize the right interconnect */
if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) {
cci_base = PLAT_FVP_CCI5XX_BASE;
cci_map = fvp_cci5xx_map;
map_size = ARRAY_SIZE(fvp_cci5xx_map);
} else if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) {
cci_base = PLAT_FVP_CCI400_BASE;
cci_map = fvp_cci400_map;
map_size = ARRAY_SIZE(fvp_cci400_map);
}
assert(cci_base);
assert(cci_map);
cci_init(cci_base, cci_map, map_size);
#endif
}
void fvp_interconnect_enable(void)
{
if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT)
plat_arm_interconnect_enter_coherency();
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
plat_arm_interconnect_enter_coherency();
#else
unsigned int master;
if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
ARM_CONFIG_FVP_HAS_CCI5XX)) {
master = get_interconnect_master();
cci_enable_snoop_dvm_reqs(master);
}
#endif
}
void fvp_interconnect_disable(void)
{
if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT)
plat_arm_interconnect_exit_coherency();
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
plat_arm_interconnect_exit_coherency();
#else
unsigned int master;
if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
ARM_CONFIG_FVP_HAS_CCI5XX)) {
master = get_interconnect_master();
cci_disable_snoop_dvm_reqs(master);
}
#endif
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -12,6 +12,10 @@
#endif
#define FVP_MAX_CPUS_PER_CLUSTER 4
#ifndef FVP_MAX_PE_PER_CPU
# define FVP_MAX_PE_PER_CPU 1
#endif
#define FVP_PRIMARY_CPU 0x0
/* Defines for the Interconnect build selection */
@ -74,6 +78,7 @@
/* Constants to distinguish FVP type */
#define HBI_BASE_FVP 0x020
#define REV_BASE_FVP_V0 0x0
#define REV_BASE_FVP_REVC 0x2
#define HBI_FOUNDATION_FVP 0x010
#define REV_FOUNDATION_FVP_V2_0 0x0

View File

@ -1,10 +1,11 @@
/*
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arm_config.h>
#include <cassert.h>
#include <plat_arm.h>
#include <platform_def.h>
@ -55,11 +56,38 @@ unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
******************************************************************************/
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
if (arm_check_mpidr(mpidr) == -1)
unsigned int clus_id, cpu_id, thread_id;
/* Validate affinity fields */
if (arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) {
thread_id = MPIDR_AFFLVL0_VAL(mpidr);
cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
clus_id = MPIDR_AFFLVL2_VAL(mpidr);
} else {
thread_id = 0;
cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
clus_id = MPIDR_AFFLVL1_VAL(mpidr);
}
if (clus_id >= FVP_CLUSTER_COUNT)
return -1;
if (cpu_id >= FVP_MAX_CPUS_PER_CLUSTER)
return -1;
if (thread_id >= FVP_MAX_PE_PER_CPU)
return -1;
if (fvp_pwrc_read_psysr(mpidr) == PSYSR_INVALID)
return -1;
/*
* Core position calculation for FVP platform depends on the MT bit in
* MPIDR. This function cannot assume that the supplied MPIDR has the MT
* bit set even if the implementation has. For example, PSCI clients
* might supply MPIDR values without the MT bit set. Therefore, we
* inject the current PE's MT bit so as to get the calculation correct.
* This of course assumes that none or all CPUs on the platform has MT
* bit set.
*/
mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
return plat_arm_calc_core_pos(mpidr);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,15 +7,13 @@
#define __PLAT_MACROS_S__
#include <arm_macros.S>
#include <cci_macros.S>
#include <v2m_def.h>
#include "../fvp_def.h"
/* ---------------------------------------------
* The below required platform porting macro
* prints out relevant GIC and CCI registers
* whenever an unhandled exception is taken in
* BL31.
* prints out relevant GIC registers whenever an
* unhandled exception is taken in BL31.
* Clobbers: x0 - x10, x16, x17, sp
* ---------------------------------------------
*/
@ -40,9 +38,6 @@ use_ve_mmap:
mov_imm x16, VE_GICD_BASE
print_gic_regs:
arm_print_gic_regs
#if FVP_INTERCONNECT_DRIVER == FVP_CCI
print_cci_regs
#endif
.endm
#endif /* __PLAT_MACROS_S__ */

View File

@ -16,10 +16,13 @@
#include "../fvp_def.h"
/* Required platform porting definitions */
#define PLATFORM_CORE_COUNT \
(FVP_CLUSTER_COUNT * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU)
#define PLAT_NUM_PWR_DOMAINS (FVP_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
#define PLATFORM_CORE_COUNT (FVP_CLUSTER_COUNT * FVP_MAX_CPUS_PER_CLUSTER)
/*
* Other platform porting definitions are provided by included headers
@ -65,10 +68,17 @@
#define PLAT_ARM_TSP_UART_BASE V2M_IOFPGA_UART2_BASE
#define PLAT_ARM_TSP_UART_CLK_IN_HZ V2M_IOFPGA_UART2_CLK_IN_HZ
#define PLAT_FVP_SMMUV3_BASE 0x2b400000
/* CCI related constants */
#define PLAT_ARM_CCI_BASE 0x2c090000
#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 3
#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 4
#define PLAT_FVP_CCI400_BASE 0x2c090000
#define PLAT_FVP_CCI400_CLUS0_SL_PORT 3
#define PLAT_FVP_CCI400_CLUS1_SL_PORT 4
/* CCI-500/CCI-550 on Base platform */
#define PLAT_FVP_CCI5XX_BASE 0x2a000000
#define PLAT_FVP_CCI5XX_CLUS0_SL_PORT 5
#define PLAT_FVP_CCI5XX_CLUS1_SL_PORT 6
/* CCN related constants. Only CCN 502 is currently supported */
#define PLAT_ARM_CCN_BASE 0x2e000000

View File

@ -6,19 +6,28 @@
# Use the GICv3 driver on the FVP by default
FVP_USE_GIC_DRIVER := FVP_GICV3
# Use the SP804 timer instead of the generic one
FVP_USE_SP804_TIMER := 0
# Default cluster count for FVP
FVP_CLUSTER_COUNT := 2
# Default number of threads per CPU on FVP
FVP_MAX_PE_PER_CPU := 1
$(eval $(call assert_boolean,FVP_USE_SP804_TIMER))
$(eval $(call add_define,FVP_USE_SP804_TIMER))
# The FVP platform depends on this macro to build with correct GIC driver.
$(eval $(call add_define,FVP_USE_GIC_DRIVER))
# Define default FVP_CLUSTER_COUNT to 2 and pass it into the build system.
FVP_CLUSTER_COUNT := 2
# Pass FVP_CLUSTER_COUNT to the build system.
$(eval $(call add_define,FVP_CLUSTER_COUNT))
# Pass FVP_MAX_PE_PER_CPU to the build system.
$(eval $(call add_define,FVP_MAX_PE_PER_CPU))
# Sanity check the cluster count and if FVP_CLUSTER_COUNT <= 2,
# choose the CCI driver , else the CCN driver
ifeq ($(FVP_CLUSTER_COUNT), 0)
@ -63,8 +72,7 @@ $(error "Incorrect GIC driver chosen on FVP port")
endif
ifeq (${FVP_INTERCONNECT_DRIVER}, FVP_CCI)
FVP_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c \
plat/arm/common/arm_cci.c
FVP_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c
else ifeq (${FVP_INTERCONNECT_DRIVER}, FVP_CCN)
FVP_INTERCONNECT_SOURCES := drivers/arm/ccn/ccn.c \
plat/arm/common/arm_ccn.c
@ -127,7 +135,8 @@ endif
BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \
${FVP_SECURITY_SOURCES}
BL31_SOURCES += plat/arm/board/fvp/fvp_bl31_setup.c \
BL31_SOURCES += drivers/arm/smmu/smmu_v3.c \
plat/arm/board/fvp/fvp_bl31_setup.c \
plat/arm/board/fvp/fvp_pm.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/aarch64/fvp_helpers.S \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -35,6 +35,26 @@ static const unsigned int g0_interrupt_array[] = {
PLAT_ARM_G0_IRQS
};
/*
* 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 arm_gicv3_mpidr_hash(u_register_t mpidr)
{
mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
return plat_arm_calc_core_pos(mpidr);
}
const gicv3_driver_data_t arm_gic_data = {
.gicd_base = PLAT_ARM_GICD_BASE,
.gicr_base = PLAT_ARM_GICR_BASE,
@ -44,7 +64,7 @@ const gicv3_driver_data_t arm_gic_data = {
.g1s_interrupt_array = g1s_interrupt_array,
.rdistif_num = PLATFORM_CORE_COUNT,
.rdistif_base_addrs = rdistif_base_addrs,
.mpidr_to_core_pos = plat_arm_calc_core_pos
.mpidr_to_core_pos = arm_gicv3_mpidr_hash
};
void plat_arm_gic_driver_init(void)

View File

@ -19,9 +19,9 @@
* -----------------------------------------------------
*/
func plat_get_my_stack
mov r3, lr
push {r4, lr}
get_my_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE
bx r3
pop {r4, pc}
endfunc plat_get_my_stack
/* -----------------------------------------------------
@ -32,10 +32,10 @@ endfunc plat_get_my_stack
* -----------------------------------------------------
*/
func plat_set_my_stack
mov r3, lr
mov r4, lr
get_my_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE
mov sp, r0
bx r3
bx r4
endfunc plat_set_my_stack
/* -----------------------------------------------------