Merge "fix(arm_fpga): Change PL011 UART IRQ" into integration
diff --git a/Makefile b/Makefile
index e5ab324..2a1d4d8 100644
--- a/Makefile
+++ b/Makefile
@@ -1318,7 +1318,8 @@
echo " with ${CHECKPATCH_OPTS} option(s)"; \
fi
${Q}COMMON_COMMIT=$$(git merge-base HEAD ${BASE_COMMIT}); \
- for commit in `git rev-list $$COMMON_COMMIT..HEAD`; do \
+ for commit in `git rev-list --no-merges $$COMMON_COMMIT..HEAD`; \
+ do \
printf "\n[*] Checking style of '$$commit'\n\n"; \
git log --format=email "$$commit~..$$commit" \
-- ${CHECK_PATHS} | \
diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c
index 46606fb..de02b46 100644
--- a/common/fdt_fixup.c
+++ b/common/fdt_fixup.c
@@ -398,6 +398,7 @@
* fdt_adjust_gic_redist() - Adjust GICv3 redistributor size
* @dtb: Pointer to the DT blob in memory
* @nr_cores: Number of CPU cores on this system.
+ * @gicr_base: Base address of the first GICR frame, or ~0 if unchanged
* @gicr_frame_size: Size of the GICR frame per core
*
* On a GICv3 compatible interrupt controller, the redistributor provides
@@ -410,17 +411,19 @@
* A GICv4 compatible redistributor uses four 64K pages per core, whereas GICs
* without support for direct injection of virtual interrupts use two 64K pages.
* The @gicr_frame_size parameter should be 262144 and 131072, respectively.
+ * Also optionally allow adjusting the GICR frame base address, when this is
+ * different due to ITS frames between distributor and redistributor.
*
* Return: 0 on success, negative error value otherwise.
*/
int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores,
- unsigned int gicr_frame_size)
+ uintptr_t gicr_base, unsigned int gicr_frame_size)
{
int offset = fdt_node_offset_by_compatible(dtb, 0, "arm,gic-v3");
- uint64_t redist_size_64;
- uint32_t redist_size_32;
+ uint64_t reg_64;
+ uint32_t reg_32;
void *val;
- int parent;
+ int parent, ret;
int ac, sc;
if (offset < 0) {
@@ -437,13 +440,34 @@
return -EINVAL;
}
+ if (gicr_base != INVALID_BASE_ADDR) {
+ if (ac == 1) {
+ reg_32 = cpu_to_fdt32(gicr_base);
+ val = ®_32;
+ } else {
+ reg_64 = cpu_to_fdt64(gicr_base);
+ val = ®_64;
+ }
+ /*
+ * The redistributor base address is the second address in
+ * the "reg" entry, so we have to skip one address and one
+ * size cell.
+ */
+ ret = fdt_setprop_inplace_namelen_partial(dtb, offset,
+ "reg", 3,
+ (ac + sc) * 4,
+ val, ac * 4);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
if (sc == 1) {
- redist_size_32 = cpu_to_fdt32(nr_cores * gicr_frame_size);
- val = &redist_size_32;
+ reg_32 = cpu_to_fdt32(nr_cores * gicr_frame_size);
+ val = ®_32;
} else {
- redist_size_64 = cpu_to_fdt64(nr_cores *
- (uint64_t)gicr_frame_size);
- val = &redist_size_64;
+ reg_64 = cpu_to_fdt64(nr_cores * (uint64_t)gicr_frame_size);
+ val = ®_64;
}
/*
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 64e01ea..cfa1342 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -35,7 +35,7 @@
/* Access property and obtain its length (in bytes) */
prop = fdt_getprop(dtb, node, prop_name, &value_len);
if (prop == NULL) {
- WARN("Couldn't find property %s in dtb\n", prop_name);
+ VERBOSE("Couldn't find property %s in dtb\n", prop_name);
return -FDT_ERR_NOTFOUND;
}
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index eebeaa2..9d0dd5e 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -288,6 +288,10 @@
CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2. It
is still open.
+- ``ERRATA_A78_2242635``: This applies errata 2242635 workaround to Cortex-A78
+ CPU. This needs to be enabled for revisions r1p0, r1p1, and r1p2. The issue
+ is present in r0p0 but there is no workaround. It is still open.
+
For Cortex-A78 AE, the following errata build flags are defined :
- ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to Cortex-A78
@@ -340,11 +344,6 @@
CPU. This needs to be enabled for revisions r3p0, r3p1, r4p0, and r4p1, for
revisions r0p0, r1p0, and r2p0 there is no workaround.
-For Neoverse N2, the following errata build flags are defined :
-
-- ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
- CPU. This needs to be enabled for revision r0p0 of the CPU, it is still open.
-
For Neoverse V1, the following errata build flags are defined :
- ``ERRATA_V1_1774420``: This applies errata 1774420 workaround to Neoverse-V1
@@ -379,6 +378,11 @@
CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU.
It is still open.
+- ``ERRATA_V1_2216392``: This applies errata 2216392 workaround to Neoverse-V1
+ CPU. This needs to be enabled for revisions r1p0 and r1p1 of the CPU, the
+ issue is present in r0p0 as well but there is no workaround for that
+ revision. It is still open.
+
For Cortex-A710, the following errata build flags are defined :
- ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -407,6 +411,9 @@
For Neoverse N2, the following errata build flags are defined :
+- ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU, it is still open.
+
- ``ERRATA_N2_2067956``: This applies errata 2067956 workaround to Neoverse-N2
CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
@@ -422,6 +429,18 @@
- ``ERRATA_N2_2138953``: This applies errata 2138953 workaround to Neoverse-N2
CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+- ``ERRATA_N2_2242415``: This applies errata 2242415 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+- ``ERRATA_N2_2138958``: This applies errata 2138958 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+- ``ERRATA_N2_2242400``: This applies errata 2242400 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+- ``ERRATA_N2_2280757``: This applies errata 2280757 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
DSU Errata Workarounds
----------------------
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index d41982f..2aaf195 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -12,51 +12,50 @@
(64-bit host machine only).
.. note::
- The FVP models used are Version 11.15 Build 14, unless otherwise stated.
+ The FVP models used are Version 11.16 Build 16, unless otherwise stated.
-- ``FVP_Base_AEMvA``
-- ``FVP_Base_AEMv8A-AEMv8A``
+- ``Foundation_Platform``
- ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502``
-- ``FVP_Base_RevC-2xAEMvA``
-- ``FVP_Base_Cortex-A32x4`` (Version 11.12 build 38)
+- ``FVP_Base_AEMv8A-AEMv8A`` (For certain configurations also uses 11.14/21)
+- ``FVP_Base_AEMv8A-GIC600AE``
+- ``FVP_Base_AEMvA`` (For certain configurations also uses 0.0/6684)
+- ``FVP_Base_Cortex-A32x4`` (Version 11.12/38)
- ``FVP_Base_Cortex-A35x4``
- ``FVP_Base_Cortex-A53x4``
-- ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
- ``FVP_Base_Cortex-A55x4``
+- ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
- ``FVP_Base_Cortex-A57x1-A53x1``
- ``FVP_Base_Cortex-A57x2-A53x4``
- ``FVP_Base_Cortex-A57x4-A53x4``
- ``FVP_Base_Cortex-A57x4``
-- ``FVP_Base_Cortex-A65x4``
- ``FVP_Base_Cortex-A65AEx8``
+- ``FVP_Base_Cortex-A65x4``
+- ``FVP_Base_Cortex-A710x4``
- ``FVP_Base_Cortex-A72x4-A53x4``
- ``FVP_Base_Cortex-A72x4``
- ``FVP_Base_Cortex-A73x4-A53x4``
- ``FVP_Base_Cortex-A73x4``
- ``FVP_Base_Cortex-A75x4``
-- ``FVP_Base_Cortex-A76x4``
- ``FVP_Base_Cortex-A76AEx4``
- ``FVP_Base_Cortex-A76AEx8``
+- ``FVP_Base_Cortex-A76x4``
- ``FVP_Base_Cortex-A77x4``
- ``FVP_Base_Cortex-A78x4``
-- ``FVP_Base_Cortex-A710x4``
-- ``FVP_Morello`` (Version 0.10 build 542)
- ``FVP_Base_Neoverse-E1x1``
- ``FVP_Base_Neoverse-E1x2``
- ``FVP_Base_Neoverse-E1x4``
- ``FVP_Base_Neoverse-N1x4``
- ``FVP_Base_Neoverse-N2x4`` (Version 11.12 build 38)
- ``FVP_Base_Neoverse-V1x4``
-- ``FVP_CSS_SGI-575`` (Version 11.10 build 36)
-- ``FVP_CSS_SGM-775``
-- ``FVP_RD_E1_edge`` (Version 11.9 build 41)
-- ``FVP_RD_N1_edge`` (Version 11.10 build 36)
-- ``FVP_RD_N1_edge_dual`` (Version 11.10 build 36)
-- ``FVP_RD_Daniel`` (Version 11.13 build 10)
-- ``FVP_RD_N2`` (Version 11.13 build 10)
-- ``FVP_TC0`` (Version 0.0 build 6509)
-- ``FVP_Base_AEMv8A-GIC600AE`` (Version 0.0 build 6415)
-- ``Foundation_Platform``
+- ``FVP_Base_RevC-2xAEMvA`` (For certain configurations also uses 0.0/6557)
+- ``FVP_CSS_SGI-575`` (Version 11.15/26)
+- ``FVP_Morello`` (Version 0.11/19)
+- ``FVP_RD_E1_edge`` (Version 11.15/26)
+- ``FVP_RD_N1_edge_dual`` (Version 11.15/26)
+- ``FVP_RD_N1_edge`` (Version 11.15/26)
+- ``FVP_RD_V1`` (Version 11.15/26)
+- ``FVP_TC0``
+- ``FVP_TC1``
The latest version of the AArch32 build of TF-A has been tested on the
following Arm FVPs without shifted affinities, and that do not support threaded
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index d752013..753d995 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -393,3 +393,18 @@
return count;
}
+
+unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame)
+{
+ unsigned int part_id;
+
+ /*
+ * The lower 8 bits of PIDR0, complemented by the lower 4 bits of
+ * PIDR1 contain a part number identifying the GIC component at a
+ * particular base address.
+ */
+ part_id = mmio_read_32(gic_frame + GICD_PIDR0_GICV3) & 0xff;
+ part_id |= (mmio_read_32(gic_frame + GICD_PIDR1_GICV3) << 8) & 0xf00;
+
+ return part_id;
+}
diff --git a/drivers/usb/usb_device.c b/drivers/usb/usb_device.c
index ce02d4f..8f73a6b 100644
--- a/drivers/usb/usb_device.c
+++ b/drivers/usb/usb_device.c
@@ -174,7 +174,7 @@
pdev->dev_config = cfgidx;
pdev->class->de_init(pdev, cfgidx);
} else if (cfgidx != pdev->dev_config) {
- if (pdev->class != NULL) {
+ if (pdev->class == NULL) {
usb_core_ctl_error(pdev);
return;
}
@@ -611,6 +611,17 @@
return USBD_OK;
}
+static void usb_core_start_xfer(struct usb_handle *pdev,
+ void *handle,
+ struct usbd_ep *ep)
+{
+ if (ep->num == 0U) {
+ pdev->driver->ep0_start_xfer(handle, ep);
+ } else {
+ pdev->driver->ep_start_xfer(handle, ep);
+ }
+}
+
/*
* usb_core_receive
* Receive an amount of data
@@ -640,11 +651,7 @@
ep->is_in = false;
ep->num = num;
- if (num == 0U) {
- pdev->driver->ep0_start_xfer(hpcd->instance, ep);
- } else {
- pdev->driver->ep_start_xfer(hpcd->instance, ep);
- }
+ usb_core_start_xfer(pdev, hpcd->instance, ep);
return USBD_OK;
}
@@ -678,11 +685,7 @@
ep->is_in = true;
ep->num = num;
- if (num == 0U) {
- pdev->driver->ep0_start_xfer(hpcd->instance, ep);
- } else {
- pdev->driver->ep_start_xfer(hpcd->instance, ep);
- }
+ usb_core_start_xfer(pdev, hpcd->instance, ep);
return USBD_OK;
}
diff --git a/fdts/arm_fpga.dts b/fdts/arm_fpga.dts
index 0fca30c..c0efd09 100644
--- a/fdts/arm_fpga.dts
+++ b/fdts/arm_fpga.dts
@@ -40,7 +40,6 @@
timer {
compatible = "arm,armv8-timer";
- clock-frequency = <10000000>;
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
@@ -98,5 +97,12 @@
/* The GICR size will be adjusted at runtime to match the cores. */
<0x0 0x30040000 0x0 0x00020000>; /* GICR for one core */
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+ its: msi-controller@30040000 {
+ compatible = "arm,gic-v3-its";
+ reg = <0x0 0x30040000 0x0 0x40000>;
+ #msi-cells = <1>;
+ msi-controller;
+ };
};
};
diff --git a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi
index 6ca6293..c6d6434 100644
--- a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi
+++ b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2021, STMicroelectronics - All Rights Reserved
*/
/*
diff --git a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
index 548f69a..9614ab4 100644
--- a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
+++ b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2021, STMicroelectronics - All Rights Reserved
*/
/*
diff --git a/fdts/stm32mp15-pinctrl.dtsi b/fdts/stm32mp15-pinctrl.dtsi
index e8e6b9f..d74dc2b 100644
--- a/fdts/stm32mp15-pinctrl.dtsi
+++ b/fdts/stm32mp15-pinctrl.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi
index 3beabbb..ca93f0c 100644
--- a/fdts/stm32mp151.dtsi
+++ b/fdts/stm32mp151.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index a09c66a..11e0a61 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved
+ * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
/dts-v1/;
diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts
index 4937514..02840a2 100644
--- a/fdts/stm32mp157c-ev1.dts
+++ b/fdts/stm32mp157c-ev1.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved
+ * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
/dts-v1/;
diff --git a/fdts/stm32mp157c-lxa-mc1.dts b/fdts/stm32mp157c-lxa-mc1.dts
index 31f1382..6f67712 100644
--- a/fdts/stm32mp157c-lxa-mc1.dts
+++ b/fdts/stm32mp157c-lxa-mc1.dts
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) */
/*
- * Copyright (C) 2020 STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
* Copyright (C) 2020 Ahmad Fatoum, Pengutronix
*/
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index 69b4828..9cc5368 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
*/
diff --git a/fdts/stm32mp15xxaa-pinctrl.dtsi b/fdts/stm32mp15xxaa-pinctrl.dtsi
index 04f7a43..f1d540a 100644
--- a/fdts/stm32mp15xxaa-pinctrl.dtsi
+++ b/fdts/stm32mp15xxaa-pinctrl.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
*/
diff --git a/fdts/stm32mp15xxab-pinctrl.dtsi b/fdts/stm32mp15xxab-pinctrl.dtsi
index 328dad1..b58c7e2 100644
--- a/fdts/stm32mp15xxab-pinctrl.dtsi
+++ b/fdts/stm32mp15xxab-pinctrl.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
*/
diff --git a/fdts/stm32mp15xxac-pinctrl.dtsi b/fdts/stm32mp15xxac-pinctrl.dtsi
index 7eaa245..11e7e03 100644
--- a/fdts/stm32mp15xxac-pinctrl.dtsi
+++ b/fdts/stm32mp15xxac-pinctrl.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
*/
diff --git a/fdts/stm32mp15xxad-pinctrl.dtsi b/fdts/stm32mp15xxad-pinctrl.dtsi
index b63e207..52806d6 100644
--- a/fdts/stm32mp15xxad-pinctrl.dtsi
+++ b/fdts/stm32mp15xxad-pinctrl.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
*/
diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h
index 2e9d49d..7a590b2 100644
--- a/include/common/fdt_fixup.h
+++ b/include/common/fdt_fixup.h
@@ -7,13 +7,15 @@
#ifndef FDT_FIXUP_H
#define FDT_FIXUP_H
+#define INVALID_BASE_ADDR ((uintptr_t)~0UL)
+
int dt_add_psci_node(void *fdt);
int dt_add_psci_cpu_enable_methods(void *fdt);
int fdt_add_reserved_memory(void *dtb, const char *node_name,
uintptr_t base, size_t size);
int fdt_add_cpus_node(void *dtb, unsigned int afflv0,
unsigned int afflv1, unsigned int afflv2);
-int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores,
+int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, uintptr_t gicr_base,
unsigned int gicr_frame_size);
#endif /* FDT_FIXUP_H */
diff --git a/include/drivers/arm/arm_gicv3_common.h b/include/drivers/arm/arm_gicv3_common.h
index e5df311..d1e93be 100644
--- a/include/drivers/arm/arm_gicv3_common.h
+++ b/include/drivers/arm/arm_gicv3_common.h
@@ -21,4 +21,8 @@
#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b)
#define IIDR_MODEL_ARM_GIC_700 U(0x0400043b)
+#define PIDR_COMPONENT_ARM_DIST U(0x492)
+#define PIDR_COMPONENT_ARM_REDIST U(0x493)
+#define PIDR_COMPONENT_ARM_ITS U(0x494)
+
#endif /* ARM_GICV3_COMMON_H */
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index fa8946b..5efefb6 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -104,6 +104,8 @@
#define GICD_IROUTER U(0x6000)
#define GICD_IROUTERE U(0x8000)
+#define GICD_PIDR0_GICV3 U(0xffe0)
+#define GICD_PIDR1_GICV3 U(0xffe4)
#define GICD_PIDR2_GICV3 U(0xffe8)
#define IGRPMODR_SHIFT 5
@@ -301,6 +303,8 @@
#define GITS_CTLR_ENABLED_BIT BIT_32(0)
#define GITS_CTLR_QUIESCENT_BIT BIT_32(1)
+#define GITS_TYPER_VSGI BIT_64(39)
+
#ifndef __ASSEMBLER__
#include <stdbool.h>
@@ -324,6 +328,8 @@
#endif
}
+unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame);
+
static inline bool gicv3_is_intr_id_special_identifier(unsigned int id)
{
return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT);
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index f414cb5..a1e676e 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -28,6 +28,7 @@
******************************************************************************/
#define NEOVERSE_N2_CPUACTLR_EL1 S3_0_C15_C1_0
#define NEOVERSE_N2_CPUACTLR_EL1_BIT_46 (ULL(1) << 46)
+#define NEOVERSE_N2_CPUACTLR_EL1_BIT_22 (ULL(1) << 22)
/*******************************************************************************
* CPU Auxiliary Control register 2 specific definitions.
@@ -40,6 +41,8 @@
******************************************************************************/
#define NEOVERSE_N2_CPUACTLR5_EL1 S3_0_C15_C8_0
#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_44 (ULL(1) << 44)
+#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_13 (ULL(1) << 13)
+#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_17 (ULL(1) << 17)
/*******************************************************************************
* CPU Auxiliary Control register specific definitions.
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 4e8a228..a1288ba 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -227,6 +227,42 @@
b cpu_rev_var_ls
endfunc check_errata_2132060
+/* --------------------------------------------------------------------
+ * Errata Workaround for A78 Erratum 2242635.
+ * This applies to revisions r1p0, r1p1, and r1p2 of the Cortex A78
+ * processor and is still open.
+ * The issue also exists in r0p0 but there is no fix in that revision.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------------------------
+ */
+func errata_a78_2242635_wa
+ /* Compare x0 against revisions r1p0 - r1p2 */
+ mov x17, x30
+ bl check_errata_2242635
+ cbz x0, 1f
+
+ ldr x0, =0x5
+ msr S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
+ ldr x0, =0x10F600E000
+ msr S3_6_c15_c8_2, x0 /* CPUPOR_EL3 */
+ ldr x0, =0x10FF80E000
+ msr S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */
+ ldr x0, =0x80000000003FF
+ msr S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */
+
+ isb
+1:
+ ret x17
+endfunc errata_a78_2242635_wa
+
+func check_errata_2242635
+ /* Applies to revisions r1p0 through r1p2. */
+ mov x1, #CPU_REV(1, 0)
+ mov x2, #CPU_REV(1, 2)
+ b cpu_rev_var_range
+endfunc check_errata_2242635
+
/* -------------------------------------------------
* The CPU Ops reset function for Cortex-A78
* -------------------------------------------------
@@ -266,6 +302,11 @@
bl errata_a78_2132060_wa
#endif
+#if ERRATA_A78_2242635
+ mov x0, x18
+ bl errata_a78_2242635_wa
+#endif
+
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, actlr_el3
@@ -326,6 +367,7 @@
report_errata ERRATA_A78_1821534, cortex_a78, 1821534
report_errata ERRATA_A78_1952683, cortex_a78, 1952683
report_errata ERRATA_A78_2132060, cortex_a78, 2132060
+ report_errata ERRATA_A78_2242635, cortex_a78, 2242635
ldp x8, x30, [sp], #16
ret
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 330cc59..621aded 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -184,6 +184,34 @@
endfunc check_errata_2138956
/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2242415.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2242415_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2242415
+ cbz x0, 1f
+
+ /* Apply instruction patching sequence */
+ mrs x1, NEOVERSE_N2_CPUACTLR_EL1
+ orr x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_22
+ msr NEOVERSE_N2_CPUACTLR_EL1, x1
+1:
+ ret x17
+endfunc errata_n2_2242415_wa
+
+func check_errata_2242415
+ /* Applies to r0p0 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2242415
+
+/* --------------------------------------------------
* Errata Workaround for Neoverse N2 Erratum 2138953.
* This applies to revision r0p0 of Neoverse N2. it is still open.
* Inputs:
@@ -212,6 +240,99 @@
b cpu_rev_var_ls
endfunc check_errata_2138953
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2138958.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2138958_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2138958
+ cbz x0, 1f
+
+ /* Apply instruction patching sequence */
+ mrs x1, NEOVERSE_N2_CPUACTLR5_EL1
+ orr x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_13
+ msr NEOVERSE_N2_CPUACTLR5_EL1, x1
+1:
+ ret x17
+endfunc errata_n2_2138958_wa
+
+func check_errata_2138958
+ /* Applies to r0p0 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2138958
+
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2242400.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2242400_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2242400
+ cbz x0, 1f
+
+ /* Apply instruction patching sequence */
+ mrs x1, NEOVERSE_N2_CPUACTLR5_EL1
+ orr x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_17
+ msr NEOVERSE_N2_CPUACTLR5_EL1, x1
+ ldr x0, =0x2
+ msr S3_6_c15_c8_0, x0
+ ldr x0, =0x10F600E000
+ msr S3_6_c15_c8_2, x0
+ ldr x0, =0x10FF80E000
+ msr S3_6_c15_c8_3, x0
+ ldr x0, =0x80000000003FF
+ msr S3_6_c15_c8_1, x0
+ isb
+1:
+ ret x17
+endfunc errata_n2_2242400_wa
+
+func check_errata_2242400
+ /* Applies to r0p0 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2242400
+
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2280757.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2280757_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2280757
+ cbz x0, 1f
+
+ /* Apply instruction patching sequence */
+ mrs x1, NEOVERSE_N2_CPUACTLR_EL1
+ orr x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_22
+ msr NEOVERSE_N2_CPUACTLR_EL1, x1
+1:
+ ret x17
+endfunc errata_n2_2280757_wa
+
+func check_errata_2280757
+ /* Applies to r0p0 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2280757
+
/* -------------------------------------------
* The CPU Ops reset function for Neoverse N2.
* -------------------------------------------
@@ -238,13 +359,13 @@
#endif
#if ERRATA_N2_2025414
- mov x0, x18
- bl errata_n2_2025414_wa
+ mov x0, x18
+ bl errata_n2_2025414_wa
#endif
#if ERRATA_N2_2189731
- mov x0, x18
- bl errata_n2_2189731_wa
+ mov x0, x18
+ bl errata_n2_2189731_wa
#endif
@@ -258,6 +379,26 @@
bl errata_n2_2138953_wa
#endif
+#if ERRATA_N2_2242415
+ mov x0, x18
+ bl errata_n2_2242415_wa
+#endif
+
+#if ERRATA_N2_2138958
+ mov x0, x18
+ bl errata_n2_2138958_wa
+#endif
+
+#if ERRATA_N2_2242400
+ mov x0, x18
+ bl errata_n2_2242400_wa
+#endif
+
+#if ERRATA_N2_2280757
+ mov x0, x18
+ bl errata_n2_2280757_wa
+#endif
+
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, cptr_el3
@@ -324,6 +465,10 @@
report_errata ERRATA_N2_2189731, neoverse_n2, 2189731
report_errata ERRATA_N2_2138956, neoverse_n2, 2138956
report_errata ERRATA_N2_2138953, neoverse_n2, 2138953
+ report_errata ERRATA_N2_2242415, neoverse_n2, 2242415
+ report_errata ERRATA_N2_2138958, neoverse_n2, 2138958
+ report_errata ERRATA_N2_2242400, neoverse_n2, 2242400
+ report_errata ERRATA_N2_2280757, neoverse_n2, 2280757
ldp x8, x30, [sp], #16
ret
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 200f67d..62a7a30 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -288,6 +288,43 @@
b cpu_rev_var_ls
endfunc check_errata_2108267
+ /* --------------------------------------------------
+ * Errata Workaround for Neoverse V1 Errata #2216392.
+ * This applies to revisions r1p0 and r1p1 and is
+ * still open.
+ * This issue is also present in r0p0 but there is no
+ * workaround in that revision.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_neoverse_v1_2216392_wa
+ /* Check workaround compatibility. */
+ mov x17, x30
+ bl check_errata_2216392
+ cbz x0, 1f
+
+ ldr x0, =0x5
+ msr S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
+ ldr x0, =0x10F600E000
+ msr S3_6_c15_c8_2, x0 /* CPUPOR_EL3 */
+ ldr x0, =0x10FF80E000
+ msr S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */
+ ldr x0, =0x80000000003FF
+ msr S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */
+
+ isb
+1:
+ ret x17
+endfunc errata_neoverse_v1_2216392_wa
+
+func check_errata_2216392
+ /* Applies to revisions r1p0 and r1p1. */
+ mov x1, #CPU_REV(1, 0)
+ mov x2, #CPU_REV(1, 1)
+ b cpu_rev_var_range
+endfunc check_errata_2216392
+
/* ---------------------------------------------
* HW will do the cache maintenance while powering down
* ---------------------------------------------
@@ -326,6 +363,7 @@
report_errata ERRATA_V1_1966096, neoverse_v1, 1966096
report_errata ERRATA_V1_2139242, neoverse_v1, 2139242
report_errata ERRATA_V1_2108267, neoverse_v1, 2108267
+ report_errata ERRATA_V1_2216392, neoverse_v1, 2216392
ldp x8, x30, [sp], #16
ret
@@ -379,6 +417,11 @@
bl errata_neoverse_v1_2108267_wa
#endif
+#if ERRATA_V1_2216392
+ mov x0, x18
+ bl errata_neoverse_v1_2216392_wa
+#endif
+
ret x19
endfunc neoverse_v1_reset_func
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 138f7a5..a5b8aae 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -311,6 +311,23 @@
# well but there is no workaround for that revision.
ERRATA_A78_1951500 ?=0
+# Flag to apply erratum 1821534 workaround during reset. This erratum applies
+# to revisions r0p0 and r1p0 of the A78 cpu.
+ERRATA_A78_1821534 ?=0
+
+# Flag to apply erratum 1952683 workaround during reset. This erratum applies
+# to revision r0p0 of the A78 cpu and was fixed in the revision r1p0.
+ERRATA_A78_1952683 ?=0
+
+# Flag to apply erratum 2132060 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
+ERRATA_A78_2132060 ?=0
+
+# Flag to apply erratum 2242635 workaround during reset. This erratum applies
+# to revisions r1p0, r1p1, and r1p2 of the A78 cpu and is open. The issue is
+# present in r0p0 as well but there is no workaround for that revision.
+ERRATA_A78_2242635 ?=0
+
# Flag to apply erratum 1941500 workaround during reset. This erratum applies
# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
ERRATA_A78_AE_1941500 ?=0
@@ -319,18 +336,6 @@
# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
ERRATA_A78_AE_1951502 ?=0
-# Flag to apply erratum 1821534 workaround during reset. This erratum applies
-# to revisions r0p0 and r1p0 of the A78 cpu.
-ERRATA_A78_1821534 ?=0
-
-# Flag to apply erratum 1952683 workaround during reset. This erratum applies
-# to revision r0p0 of the A78 cpu and was fixed in the revision r1p0.
-ERRATA_A78_1952683 ?=0
-
-# Flag to apply erratum 2132060 workaround during reset. This erratum applies
-# to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
-ERRATA_A78_2132060 ?=0
-
# Flag to apply T32 CLREX workaround during reset. This erratum applies
# only to r0p0 and r1p0 of the Neoverse N1 cpu.
ERRATA_N1_1043202 ?=0
@@ -425,6 +430,11 @@
# to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
ERRATA_V1_2108267 ?=0
+# Flag to apply erratum 2216392 workaround during reset. This erratum applies
+# to revisions r1p0 and r1p1 of the Neoverse V1 cpu and is still open. This
+# issue exists in r0p0 as well but there is no workaround for that revision.
+ERRATA_V1_2216392 ?=0
+
# Flag to apply erratum 1987031 workaround during reset. This erratum applies
# to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
ERRATA_A710_1987031 ?=0
@@ -461,6 +471,22 @@
# to revision r0p0 of the Neoverse N2 cpu and is still open.
ERRATA_N2_2138953 ?=0
+# Flag to apply erratum 2242415 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2242415 ?=0
+
+# Flag to apply erratum 2138958 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2138958 ?=0
+
+# Flag to apply erratum 2242400 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2242400 ?=0
+
+# Flag to apply erratum 2280757 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2280757 ?=0
+
# Flag to apply erratum 2055002 workaround during reset. This erratum applies
# to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open.
ERRATA_A710_2055002 ?=0
@@ -714,14 +740,6 @@
$(eval $(call assert_boolean,ERRATA_A78_1951500))
$(eval $(call add_define,ERRATA_A78_1951500))
-# Process ERRATA_A78_AE_1941500 flag
-$(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
-$(eval $(call add_define,ERRATA_A78_AE_1941500))
-
-# Process ERRATA_A78_AE_1951502 flag
-$(eval $(call assert_boolean,ERRATA_A78_AE_1951502))
-$(eval $(call add_define,ERRATA_A78_AE_1951502))
-
# Process ERRATA_A78_1821534 flag
$(eval $(call assert_boolean,ERRATA_A78_1821534))
$(eval $(call add_define,ERRATA_A78_1821534))
@@ -734,6 +752,18 @@
$(eval $(call assert_boolean,ERRATA_A78_2132060))
$(eval $(call add_define,ERRATA_A78_2132060))
+# Process ERRATA_A78_2242635 flag
+$(eval $(call assert_boolean,ERRATA_A78_2242635))
+$(eval $(call add_define,ERRATA_A78_2242635))
+
+# Process ERRATA_A78_AE_1941500 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
+$(eval $(call add_define,ERRATA_A78_AE_1941500))
+
+# Process ERRATA_A78_AE_1951502 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_1951502))
+$(eval $(call add_define,ERRATA_A78_AE_1951502))
+
# Process ERRATA_N1_1043202 flag
$(eval $(call assert_boolean,ERRATA_N1_1043202))
$(eval $(call add_define,ERRATA_N1_1043202))
@@ -826,6 +856,10 @@
$(eval $(call assert_boolean,ERRATA_V1_2108267))
$(eval $(call add_define,ERRATA_V1_2108267))
+# Process ERRATA_V1_2216392 flag
+$(eval $(call assert_boolean,ERRATA_V1_2216392))
+$(eval $(call add_define,ERRATA_V1_2216392))
+
# Process ERRATA_A710_1987031 flag
$(eval $(call assert_boolean,ERRATA_A710_1987031))
$(eval $(call add_define,ERRATA_A710_1987031))
@@ -862,6 +896,22 @@
$(eval $(call assert_boolean,ERRATA_N2_2138953))
$(eval $(call add_define,ERRATA_N2_2138953))
+# Process ERRATA_N2_2242415 flag
+$(eval $(call assert_boolean,ERRATA_N2_2242415))
+$(eval $(call add_define,ERRATA_N2_2242415))
+
+# Process ERRATA_N2_2138958 flag
+$(eval $(call assert_boolean,ERRATA_N2_2138958))
+$(eval $(call add_define,ERRATA_N2_2138958))
+
+# Process ERRATA_N2_2242400 flag
+$(eval $(call assert_boolean,ERRATA_N2_2242400))
+$(eval $(call add_define,ERRATA_N2_2242400))
+
+# Process ERRATA_N2_2280757 flag
+$(eval $(call assert_boolean,ERRATA_N2_2280757))
+$(eval $(call add_define,ERRATA_N2_2280757))
+
# Process ERRATA_A710_2055002 flag
$(eval $(call assert_boolean,ERRATA_A710_2055002))
$(eval $(call add_define,ERRATA_A710_2055002))
diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c
index 1f90e64..6d1ff4d 100644
--- a/lib/gpt_rme/gpt_rme.c
+++ b/lib/gpt_rme/gpt_rme.c
@@ -708,8 +708,12 @@
/* GPCCR_EL3.PGS */
gpccr_el3 |= SET_GPCCR_PGS(gpt_config.pgs);
- /* Set shareability attribute to Outher Shareable */
- gpccr_el3 |= SET_GPCCR_SH(GPCCR_SH_OS);
+ /*
+ * Since EL3 maps the L1 region as Inner shareable, use the same
+ * shareability attribute for GPC as well so that
+ * GPC fetches are visible to PEs
+ */
+ gpccr_el3 |= SET_GPCCR_SH(GPCCR_SH_IS);
/* Outer and Inner cacheability set to Normal memory, WB, RA, WA. */
gpccr_el3 |= SET_GPCCR_ORGN(GPCCR_ORGN_WB_RA_WA);
@@ -720,6 +724,7 @@
/* TODO: Configure GPCCR_EL3_GPCP for Fault control. */
write_gpccr_el3(gpccr_el3);
+ isb();
tlbipaallos();
dsb();
isb();
@@ -759,7 +764,7 @@
int ret;
uint64_t gpt_desc;
- /* Ensure that MMU and caches are enabled. */
+ /* Ensure that MMU and Data caches are enabled. */
assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
/* Validate other parameters. */
@@ -814,7 +819,7 @@
int ret;
int l1_gpt_cnt;
- /* Ensure that MMU and caches are enabled. */
+ /* Ensure that MMU and Data caches are enabled. */
assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
/* PGS is needed for gpt_validate_pas_mappings so check it now. */
@@ -888,6 +893,9 @@
/* Make sure that all the entries are written to the memory. */
dsbishst();
+ tlbipaallos();
+ dsb();
+ isb();
return 0;
}
@@ -907,7 +915,7 @@
{
u_register_t reg;
- /* Ensure that MMU and caches are enabled. */
+ /* Ensure that MMU and Data caches are enabled. */
assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
/* Ensure GPC are already enabled. */
@@ -1028,6 +1036,9 @@
/* Ensure that the tables have been set up before taking requests. */
assert(gpt_config.plat_gpt_l0_base != 0U);
+ /* Ensure that MMU and data caches are enabled. */
+ assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
+
/* Check for address range overflow. */
if ((ULONG_MAX - base) < size) {
VERBOSE("[GPT] Transition request address overflow!\n");
@@ -1093,18 +1104,18 @@
gpt_l1_desc |= ((uint64_t)target_pas << gpi_shift);
gpt_l1_addr[idx] = gpt_l1_desc;
- /* Ensure that the write operation happens before the unlock. */
- dmbishst();
+ /* Ensure that the write operation will be observed by GPC */
+ dsbishst();
/* Unlock access to the L1 tables. */
spin_unlock(&gpt_lock);
- /* Cache maintenance. */
- clean_dcache_range((uintptr_t)&gpt_l1_addr[idx],
- sizeof(uint64_t));
gpt_tlbi_by_pa(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p));
dsbishst();
-
+ /*
+ * The isb() will be done as part of context
+ * synchronization when returning to lower EL
+ */
VERBOSE("[GPT] Granule 0x%llx, GPI 0x%x->0x%x\n", base, gpi,
target_pas);
diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S
index b4bc7d8..d8254e5 100644
--- a/plat/arm/board/arm_fpga/build_axf.ld.S
+++ b/plat/arm/board/arm_fpga/build_axf.ld.S
@@ -15,11 +15,11 @@
OUTPUT_FORMAT("elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
-INPUT(./bl31/bl31.elf)
INPUT(./rom_trampoline.o)
INPUT(./kernel_trampoline.o)
TARGET(binary)
+INPUT(./bl31.bin)
INPUT(./fdts/arm_fpga.dtb)
ENTRY(_start)
@@ -33,7 +33,7 @@
.bl31 (BL31_BASE): {
ASSERT(. == ALIGN(PAGE_SIZE), "BL31_BASE is not page aligned");
- *bl31.elf(.text* .data* .rodata* ro* .bss*)
+ *bl31.bin
}
.dtb (FPGA_PRELOADED_DTB_BASE): {
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index 2b5ca4a..e1b3abb 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -13,6 +13,7 @@
#include <drivers/delay_timer.h>
#include <drivers/generic_delay_timer.h>
#include <lib/extensions/spe.h>
+#include <lib/mmio.h>
#include <libfdt.h>
#include "fpga_private.h"
@@ -20,6 +21,7 @@
#include <platform_def.h>
static entry_point_info_t bl33_image_ep_info;
+static unsigned int system_freq;
volatile uint32_t secondary_core_spinlock;
uintptr_t plat_get_ns_image_entrypoint(void)
@@ -118,18 +120,187 @@
}
}
-unsigned int plat_get_syscnt_freq2(void)
-{
- const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
- int node;
+/*
+ * Even though we sell the FPGA UART as an SBSA variant, it is actually
+ * a full fledged PL011. So the baudrate divider registers exist.
+ */
+#ifndef UARTIBRD
+#define UARTIBRD 0x024
+#define UARTFBRD 0x028
+#endif
- node = fdt_node_offset_by_compatible(fdt, 0, "arm,armv8-timer");
- if (node < 0) {
- return FPGA_DEFAULT_TIMER_FREQUENCY;
+/* Round an integer to the closest multiple of a value. */
+static unsigned int round_multiple(unsigned int x, unsigned int multiple)
+{
+ if (multiple < 2) {
+ return x;
}
- return fdt_read_uint32_default(fdt, node, "clock-frequency",
- FPGA_DEFAULT_TIMER_FREQUENCY);
+ return ((x + (multiple / 2 - 1)) / multiple) * multiple;
+}
+
+#define PL011_FRAC_SHIFT 6
+#define FPGA_DEFAULT_BAUDRATE 38400
+#define PL011_OVERSAMPLING 16
+static unsigned int pl011_freq_from_divider(unsigned int divider)
+{
+ unsigned int freq;
+
+ freq = divider * FPGA_DEFAULT_BAUDRATE * PL011_OVERSAMPLING;
+
+ return freq >> PL011_FRAC_SHIFT;
+}
+
+/*
+ * The FPGAs run most peripherals from one main clock, among them the CPUs,
+ * the arch timer, and the UART baud base clock.
+ * The SCP knows this frequency and programs the UART clock divider for a
+ * 38400 bps baudrate. Recalculate the base input clock from there.
+ */
+static unsigned int fpga_get_system_frequency(void)
+{
+ const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
+ int node, err;
+
+ /*
+ * If the arch timer DT node has an explicit clock-frequency property
+ * set, use that, to allow people overriding auto-detection.
+ */
+ node = fdt_node_offset_by_compatible(fdt, 0, "arm,armv8-timer");
+ if (node >= 0) {
+ uint32_t freq;
+
+ err = fdt_read_uint32(fdt, node, "clock-frequency", &freq);
+ if (err >= 0) {
+ return freq;
+ }
+ }
+
+ node = fdt_node_offset_by_compatible(fdt, 0, "arm,pl011");
+ if (node >= 0) {
+ uintptr_t pl011_base;
+ unsigned int divider;
+
+ err = fdt_get_reg_props_by_index(fdt, node, 0,
+ &pl011_base, NULL);
+ if (err >= 0) {
+ divider = mmio_read_32(pl011_base + UARTIBRD);
+ divider <<= PL011_FRAC_SHIFT;
+ divider += mmio_read_32(pl011_base + UARTFBRD);
+
+ /*
+ * The result won't be exact, due to rounding errors,
+ * but the input frequency was a multiple of 250 KHz.
+ */
+ return round_multiple(pl011_freq_from_divider(divider),
+ 250000);
+ } else {
+ WARN("Cannot read PL011 MMIO base\n");
+ }
+ } else {
+ WARN("No PL011 DT node\n");
+ }
+
+ /* No PL011 DT node or calculation failed. */
+ return FPGA_DEFAULT_TIMER_FREQUENCY;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ if (system_freq == 0U) {
+ system_freq = fpga_get_system_frequency();
+ }
+
+ return system_freq;
+}
+
+static void fpga_dtb_update_clock(void *fdt, unsigned int freq)
+{
+ uint32_t freq_dtb = fdt32_to_cpu(freq);
+ uint32_t phandle;
+ int node, err;
+
+ node = fdt_node_offset_by_compatible(fdt, 0, "arm,pl011");
+ if (node < 0) {
+ WARN("%s(): No PL011 DT node found\n", __func__);
+
+ return;
+ }
+
+ err = fdt_read_uint32(fdt, node, "clocks", &phandle);
+ if (err != 0) {
+ WARN("Cannot find clocks property\n");
+
+ return;
+ }
+
+ node = fdt_node_offset_by_phandle(fdt, phandle);
+ if (node < 0) {
+ WARN("Cannot get phandle\n");
+
+ return;
+ }
+
+ err = fdt_setprop_inplace(fdt, node,
+ "clock-frequency",
+ &freq_dtb,
+ sizeof(freq_dtb));
+ if (err < 0) {
+ WARN("Could not update DT baud clock frequency\n");
+
+ return;
+ }
+}
+
+#define CMDLINE_SIGNATURE "CMD:"
+
+static int fpga_dtb_set_commandline(void *fdt, const char *cmdline)
+{
+ int chosen;
+ const char *eol;
+ char nul = 0;
+ int slen, err;
+
+ chosen = fdt_add_subnode(fdt, 0, "chosen");
+ if (chosen == -FDT_ERR_EXISTS) {
+ chosen = fdt_path_offset(fdt, "/chosen");
+ }
+
+ if (chosen < 0) {
+ return chosen;
+ }
+
+ /*
+ * There is most likely an EOL at the end of the
+ * command line, make sure we terminate the line there.
+ * We can't replace the EOL with a NUL byte in the
+ * source, as this is in read-only memory. So we first
+ * create the property without any termination, then
+ * append a single NUL byte.
+ */
+ eol = strchr(cmdline, '\n');
+ if (eol == NULL) {
+ eol = strchr(cmdline, 0);
+ }
+ /* Skip the signature and omit the EOL/NUL byte. */
+ slen = eol - (cmdline + strlen(CMDLINE_SIGNATURE));
+ /*
+ * Let's limit the size of the property, just in case
+ * we find the signature by accident. The Linux kernel
+ * limits to 4096 characters at most (in fact 2048 for
+ * arm64), so that sounds like a reasonable number.
+ */
+ if (slen > 4095) {
+ slen = 4095;
+ }
+
+ err = fdt_setprop(fdt, chosen, "bootargs",
+ cmdline + strlen(CMDLINE_SIGNATURE), slen);
+ if (err != 0) {
+ return err;
+ }
+
+ return fdt_appendprop(fdt, chosen, "bootargs", &nul, 1);
}
static void fpga_prepare_dtb(void)
@@ -151,55 +322,13 @@
}
/* Check for the command line signature. */
- if (!strncmp(cmdline, "CMD:", 4)) {
- int chosen;
-
- INFO("using command line at 0x%x\n", FPGA_PRELOADED_CMD_LINE);
-
- chosen = fdt_add_subnode(fdt, 0, "chosen");
- if (chosen == -FDT_ERR_EXISTS) {
- chosen = fdt_path_offset(fdt, "/chosen");
- }
- if (chosen < 0) {
- ERROR("cannot find /chosen node: %d\n", chosen);
+ if (!strncmp(cmdline, CMDLINE_SIGNATURE, strlen(CMDLINE_SIGNATURE))) {
+ err = fpga_dtb_set_commandline(fdt, cmdline);
+ if (err == 0) {
+ INFO("using command line at 0x%x\n",
+ FPGA_PRELOADED_CMD_LINE);
} else {
- const char *eol;
- char nul = 0;
- int slen;
-
- /*
- * There is most likely an EOL at the end of the
- * command line, make sure we terminate the line there.
- * We can't replace the EOL with a NUL byte in the
- * source, as this is in read-only memory. So we first
- * create the property without any termination, then
- * append a single NUL byte.
- */
- eol = strchr(cmdline, '\n');
- if (!eol) {
- eol = strchr(cmdline, 0);
- }
- /* Skip the signature and omit the EOL/NUL byte. */
- slen = eol - (cmdline + 4);
-
- /*
- * Let's limit the size of the property, just in case
- * we find the signature by accident. The Linux kernel
- * limits to 4096 characters at most (in fact 2048 for
- * arm64), so that sounds like a reasonable number.
- */
- if (slen > 4095) {
- slen = 4095;
- }
- err = fdt_setprop(fdt, chosen, "bootargs",
- cmdline + 4, slen);
- if (!err) {
- err = fdt_appendprop(fdt, chosen, "bootargs",
- &nul, 1);
- }
- if (err) {
- ERROR("Could not set command line: %d\n", err);
- }
+ ERROR("failed to put command line into DTB: %d\n", err);
}
}
@@ -224,6 +353,7 @@
INFO("Adjusting GICR DT region to cover %u cores\n",
nr_cores);
err = fdt_adjust_gic_redist(fdt, nr_cores,
+ fpga_get_redist_base(),
fpga_get_redist_size());
if (err < 0) {
ERROR("Error %d fixing up GIC DT node\n", err);
@@ -231,6 +361,8 @@
}
}
+ fpga_dtb_update_clock(fdt, system_freq);
+
/* Check whether we support the SPE PMU. Remove the DT node if not. */
if (!spe_supported()) {
int node = fdt_node_offset_by_compatible(fdt, 0,
@@ -241,6 +373,16 @@
}
}
+ /* Check whether we have an ITS. Remove the DT node if not. */
+ if (!fpga_has_its()) {
+ int node = fdt_node_offset_by_compatible(fdt, 0,
+ "arm,gic-v3-its");
+
+ if (node >= 0) {
+ fdt_del_node(fdt, node);
+ }
+ }
+
err = fdt_pack(fdt);
if (err < 0) {
ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, err);
diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c
index 4a97beb..e06a9da 100644
--- a/plat/arm/board/arm_fpga/fpga_gicv3.c
+++ b/plat/arm/board/arm_fpga/fpga_gicv3.c
@@ -1,13 +1,14 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <common/fdt_wrappers.h>
-#include <drivers/arm/gicv3.h>
+#include <drivers/arm/arm_gicv3_common.h>
#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
#include <lib/mmio.h>
#include <libfdt.h>
@@ -21,6 +22,7 @@
};
static uintptr_t fpga_rdistif_base_addrs[PLATFORM_CORE_COUNT];
+static int nr_itses;
static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr)
{
@@ -38,6 +40,8 @@
void plat_fpga_gic_init(void)
{
const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
+ uintptr_t gicr_base = 0U;
+ uint32_t iidr;
int node, ret;
node = fdt_node_offset_by_compatible(fdt, 0, "arm,gic-v3");
@@ -54,11 +58,66 @@
return;
}
- ret = fdt_get_reg_props_by_index(fdt, node, 1,
- &fpga_gicv3_driver_data.gicr_base, NULL);
- if (ret < 0) {
- WARN("Could not read GIC redistributor address from DT.\n");
- return;
+ iidr = mmio_read_32(fpga_gicv3_driver_data.gicd_base + GICD_IIDR);
+ if (((iidr & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) ||
+ ((iidr & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700)) {
+ unsigned int frame_id;
+
+ /*
+ * According to the GIC TRMs, if there are any ITSes, they
+ * start four 64K pages after the distributor. After all
+ * the ITSes then follow the redistributors.
+ */
+ gicr_base = fpga_gicv3_driver_data.gicd_base + (4U << 16);
+
+ do {
+ uint64_t its_typer;
+
+ /* Each GIC component can be identified by its ID. */
+ frame_id = gicv3_get_component_partnum(gicr_base);
+
+ if (frame_id == PIDR_COMPONENT_ARM_REDIST) {
+ INFO("Found %d ITSes, redistributors start at 0x%llx\n",
+ nr_itses, (unsigned long long)gicr_base);
+ break;
+ }
+
+ if (frame_id != PIDR_COMPONENT_ARM_ITS) {
+ WARN("GICv3: found unexpected frame 0x%x\n",
+ frame_id);
+ gicr_base = 0U;
+ break;
+ }
+
+ /*
+ * Found an ITS, now work out if it supports virtual
+ * SGIs (for direct guest injection). If yes, each
+ * ITS occupies four 64K pages, otherwise just two.
+ */
+ its_typer = mmio_read_64(gicr_base + GITS_TYPER);
+ if ((its_typer & GITS_TYPER_VSGI) != 0U) {
+ gicr_base += 4U << 16;
+ } else {
+ gicr_base += 2U << 16;
+ }
+ nr_itses++;
+ } while (true);
+ }
+
+ /*
+ * If this is not a GIC-600 or -700, or the autodetection above failed,
+ * use the base address from the device tree.
+ */
+ if (gicr_base == 0U) {
+ ret = fdt_get_reg_props_by_index(fdt, node, 1,
+ &fpga_gicv3_driver_data.gicr_base,
+ NULL);
+ if (ret < 0) {
+ WARN("Could not read GIC redistributor address from DT.\n");
+ return;
+ }
+ } else {
+ fpga_gicv3_driver_data.gicr_base = gicr_base;
}
gicv3_driver_init(&fpga_gicv3_driver_data);
@@ -91,3 +150,13 @@
return gicv3_redist_size(typer_val);
}
+
+uintptr_t fpga_get_redist_base(void)
+{
+ return fpga_gicv3_driver_data.gicr_base;
+}
+
+bool fpga_has_its(void)
+{
+ return nr_itses > 0;
+}
diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h
index cc809c4..84d651c 100644
--- a/plat/arm/board/arm_fpga/fpga_private.h
+++ b/plat/arm/board/arm_fpga/fpga_private.h
@@ -26,6 +26,8 @@
unsigned int plat_fpga_calc_core_pos(uint32_t mpid);
unsigned int fpga_get_nr_gic_cores(void);
uintptr_t fpga_get_redist_size(void);
+uintptr_t fpga_get_redist_base(void);
+bool fpga_has_its(void);
#endif /* __ASSEMBLER__ */
diff --git a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
index a8592f6..d3a5e1a 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
+++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
@@ -43,6 +43,13 @@
vcpu_count = <1>;
mem_size = <1048576>;
};
+ vm4 {
+ is_ffa_partition;
+ debug_name = "ivy";
+ load_address = <0xfe600000>;
+ vcpu_count = <1>;
+ mem_size = <1048576>;
+ };
};
cpus {
diff --git a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
index af80550..4c6ccef 100644
--- a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
+++ b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
@@ -64,6 +64,12 @@
uuid = "79b55c73-1d8c-44b9-8593-61e1770ad8d2";
load-address = <0xfe200000>;
};
+
+ ivy {
+ uuid = "eaba83d8-baaf-4eaf-8144-f7fdcbe544a7";
+ load-address = <0xfe600000>;
+ owner = "Plat";
+ };
#endif
#endif /* ARM_BL2_SP_LIST_DTS */
};
diff --git a/plat/st/common/stm32cubeprogrammer_usb.c b/plat/st/common/stm32cubeprogrammer_usb.c
index 4cd210e..19a6bba 100644
--- a/plat/st/common/stm32cubeprogrammer_usb.c
+++ b/plat/st/common/stm32cubeprogrammer_usb.c
@@ -116,7 +116,7 @@
dfu->address += *len;
if (dfu->address - dfu->base > dfu->len) {
- return -EIO;
+ return -EIO;
}
return 0;
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index c8c2e5f..badc926 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -159,15 +159,17 @@
PLAT_INCLUDES := -Iplat/st/common/include/
PLAT_INCLUDES += -Iplat/st/stm32mp1/include/
+ifeq (${STM32MP_USE_STM32IMAGE},1)
include common/fdt_wrappers.mk
+else
+include lib/fconf/fconf.mk
+endif
include lib/libfdt/libfdt.mk
PLAT_BL_COMMON_SOURCES := common/uuid.c \
plat/st/common/stm32mp_common.c \
plat/st/stm32mp1/stm32mp1_private.c
-PLAT_BL_COMMON_SOURCES += ${FDT_WRAPPERS_SOURCES}
-
PLAT_BL_COMMON_SOURCES += drivers/st/uart/aarch32/stm32_console.S
ifneq (${ENABLE_STACK_PROTECTOR},0)
@@ -199,14 +201,16 @@
plat/st/stm32mp1/stm32mp1_syscfg.c
ifneq (${STM32MP_USE_STM32IMAGE},1)
+BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES}
+
BL2_SOURCES += drivers/io/io_fip.c \
- lib/fconf/fconf.c \
- lib/fconf/fconf_dyn_cfg_getter.c \
plat/st/common/bl2_io_storage.c \
plat/st/common/stm32mp_fconf_io.c \
plat/st/stm32mp1/plat_bl2_mem_params_desc.c \
plat/st/stm32mp1/stm32mp1_fconf_firewall.c
else
+BL2_SOURCES += ${FDT_WRAPPERS_SOURCES}
+
BL2_SOURCES += drivers/io/io_dummy.c \
drivers/st/io/io_stm32image.c \
plat/st/common/bl2_stm32_io_storage.c \
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index 4d4820a..239b60a 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -15,6 +15,10 @@
plat/st/stm32mp1/stm32mp1_shared_resources.c \
plat/st/stm32mp1/stm32mp1_topology.c
+# FDT wrappers
+include common/fdt_wrappers.mk
+BL32_SOURCES += ${FDT_WRAPPERS_SOURCES}
+
# Generic GIC v2
include drivers/arm/gic/v2/gicv2.mk
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 6de5feb..a9ff459 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -489,15 +489,6 @@
* forward to SPM Core which will handle it if implemented.
*/
- /*
- * Check if x1 holds a valid FFA fid. This is an
- * optimization.
- */
- if (!is_ffa_fid(x1)) {
- return spmd_ffa_error_return(handle,
- FFA_ERROR_NOT_SUPPORTED);
- }
-
/* Forward SMC from Normal world to the SPM Core */
if (!secure_origin) {
return spmd_smc_forward(smc_fid, secure_origin,