Merge changes from topic "provencore-spd" into integration
* changes:
feat(zynqmp): add support for ProvenCore
feat(services): add a SPD for ProvenCore
feat(gic): add APIs to raise NS and S-EL1 SGIs
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index 339ebbe..afe89b9 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -152,6 +152,11 @@
to select the appropriate platform variant for the build. The range of
valid values is platform specific.
+- ``CSS_SYSTEM_GRACEFUL_RESET``: Build option to enable graceful powerdown of
+ CPU core on reset. This build option can be used on CSS platforms that
+ require all the CPUs to execute the CPU specific power down sequence to
+ complete a warm reboot sequence in which only the CPUs are power cycled.
+
--------------
.. |FIP in a GPT image| image:: ../../resources/diagrams/FIP_in_a_GPT_image.png
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index 5de2604..9fe8b37 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,7 @@
#include <common/debug.h>
#include <drivers/arm/css/css_scp.h>
#include <drivers/arm/css/scmi.h>
+#include <lib/mmio.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/arm/css/common/css_pm.h>
#include <plat/common/platform.h>
@@ -286,15 +287,42 @@
return HW_OFF;
}
+/*
+ * Callback function to raise a SGI designated to trigger the CPU power down
+ * sequence on all the online secondary cores.
+ */
+static void css_raise_pwr_down_interrupt(u_register_t mpidr)
+{
+#if CSS_SYSTEM_GRACEFUL_RESET
+ plat_ic_raise_el3_sgi(CSS_CPU_PWR_DOWN_REQ_INTR, mpidr);
+#endif
+}
+
void __dead2 css_scp_system_off(int state)
{
int ret;
/*
+ * Before issuing the system power down command, set the trusted mailbox
+ * to 0. This will ensure that in the case of a warm/cold reset, the
+ * primary CPU executes from the cold boot sequence.
+ */
+ mmio_write_64(PLAT_ARM_TRUSTED_MAILBOX_BASE, 0U);
+
+ /*
+ * Send powerdown request to online secondary core(s)
+ */
+ ret = psci_stop_other_cores(0, css_raise_pwr_down_interrupt);
+ if (ret != PSCI_E_SUCCESS) {
+ ERROR("Failed to powerdown secondary core(s)\n");
+ }
+
+ /*
* Disable GIC CPU interface to prevent pending interrupt from waking
* up the AP from WFI.
*/
plat_arm_gic_cpuif_disable();
+ plat_arm_gic_redistif_off();
/*
* Issue SCMI command. First issue a graceful
@@ -309,6 +337,9 @@
state, ret);
panic();
}
+
+ /* Powerdown of primary core */
+ psci_pwrdown_cpu(PLAT_MAX_PWR_LVL);
wfi();
ERROR("CSS set power state: operation not handled.\n");
panic();
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
index 5f42ad9..e85dbc1 100644
--- a/drivers/arm/gic/v3/gic600_multichip.c
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -97,16 +98,28 @@
spi_id_max = GIC600_SPI_ID_MIN;
}
- spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
- spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
-
switch ((gicd_iidr_val & IIDR_MODEL_MASK)) {
case IIDR_MODEL_ARM_GIC_600:
+ spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
+ spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
+
chipr_n_val = GICD_CHIPR_VALUE_GIC_600(chip_addr,
spi_block_min,
spi_blocks);
break;
case IIDR_MODEL_ARM_GIC_700:
+ /* Calculate the SPI_ID_MIN value for ESPI */
+ if (spi_id_min >= GIC700_ESPI_ID_MIN) {
+ spi_block_min = ESPI_BLOCK_MIN_VALUE(spi_id_min);
+ spi_block_min += SPI_BLOCKS_VALUE(GIC700_SPI_ID_MIN,
+ GIC700_SPI_ID_MAX);
+ } else {
+ spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
+ }
+
+ /* Calculate the total number of blocks */
+ spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
+
chipr_n_val = GICD_CHIPR_VALUE_GIC_700(chip_addr,
spi_block_min,
spi_blocks);
@@ -202,13 +215,104 @@
}
/*******************************************************************************
- * Intialize GIC-600 Multichip operation.
+ * Validates the GIC-700 Multichip data structure passed by the platform.
+ ******************************************************************************/
+static void gic700_multichip_validate_data(
+ struct gic600_multichip_data *multichip_data)
+{
+ unsigned int i, spi_id_min, spi_id_max, blocks_of_32;
+ unsigned int multichip_spi_blocks = 0U, multichip_espi_blocks = 0U;
+
+ assert(multichip_data != NULL);
+
+ if (multichip_data->chip_count > GIC600_MAX_MULTICHIP) {
+ ERROR("GIC-700 Multichip count (%u) should not exceed %u\n",
+ multichip_data->chip_count, GIC600_MAX_MULTICHIP);
+ panic();
+ }
+
+ for (i = 0U; i < multichip_data->chip_count; i++) {
+ spi_id_min = multichip_data->spi_ids[i][SPI_MIN_INDEX];
+ spi_id_max = multichip_data->spi_ids[i][SPI_MAX_INDEX];
+
+ if ((spi_id_min == 0U) || (spi_id_max == 0U)) {
+ continue;
+ }
+
+ /* MIN SPI ID check */
+ if ((spi_id_min < GIC700_SPI_ID_MIN) ||
+ ((spi_id_min >= GIC700_SPI_ID_MAX) &&
+ (spi_id_min < GIC700_ESPI_ID_MIN))) {
+ ERROR("Invalid MIN SPI ID {%u} passed for "
+ "Chip %u\n", spi_id_min, i);
+ panic();
+ }
+
+ if ((spi_id_min > spi_id_max) ||
+ ((spi_id_max - spi_id_min + 1) % 32 != 0)) {
+ ERROR("Unaligned SPI IDs {%u, %u} passed for "
+ "Chip %u\n", spi_id_min,
+ spi_id_max, i);
+ panic();
+ }
+
+ /* ESPI IDs range check */
+ if ((spi_id_min >= GIC700_ESPI_ID_MIN) &&
+ (spi_id_max > GIC700_ESPI_ID_MAX)) {
+ ERROR("Invalid ESPI IDs {%u, %u} passed for "
+ "Chip %u\n", spi_id_min,
+ spi_id_max, i);
+ panic();
+
+ }
+
+ /* SPI IDs range check */
+ if (((spi_id_min < GIC700_SPI_ID_MAX) &&
+ (spi_id_max > GIC700_SPI_ID_MAX))) {
+ ERROR("Invalid SPI IDs {%u, %u} passed for "
+ "Chip %u\n", spi_id_min,
+ spi_id_max, i);
+ panic();
+ }
+
+ /* SPI IDs overlap check */
+ if (spi_id_max < GIC700_SPI_ID_MAX) {
+ blocks_of_32 = BLOCKS_OF_32(spi_id_min, spi_id_max);
+ if ((multichip_spi_blocks & blocks_of_32) != 0) {
+ ERROR("SPI IDs of Chip %u overlapping\n", i);
+ panic();
+ }
+ multichip_spi_blocks |= blocks_of_32;
+ }
+
+ /* ESPI IDs overlap check */
+ if (spi_id_max > GIC700_ESPI_ID_MIN) {
+ blocks_of_32 = BLOCKS_OF_32(spi_id_min - GIC700_ESPI_ID_MIN,
+ spi_id_max - GIC700_ESPI_ID_MIN);
+ if ((multichip_espi_blocks & blocks_of_32) != 0) {
+ ERROR("SPI IDs of Chip %u overlapping\n", i);
+ panic();
+ }
+ multichip_espi_blocks |= blocks_of_32;
+ }
+ }
+}
+
+/*******************************************************************************
+ * Intialize GIC-600 and GIC-700 Multichip operation.
******************************************************************************/
void gic600_multichip_init(struct gic600_multichip_data *multichip_data)
{
unsigned int i;
+ uint32_t gicd_iidr_val = gicd_read_iidr(multichip_data->rt_owner_base);
- gic600_multichip_validate_data(multichip_data);
+ if ((gicd_iidr_val & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) {
+ gic600_multichip_validate_data(multichip_data);
+ }
+
+ if ((gicd_iidr_val & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700) {
+ gic700_multichip_validate_data(multichip_data);
+ }
/*
* Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures
diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h
index 5d1ff6a..c7b15c1 100644
--- a/drivers/arm/gic/v3/gic600_multichip_private.h
+++ b/drivers/arm/gic/v3/gic600_multichip_private.h
@@ -41,6 +41,11 @@
#define GIC600_SPI_ID_MIN 32
#define GIC600_SPI_ID_MAX 960
+#define GIC700_SPI_ID_MIN 32
+#define GIC700_SPI_ID_MAX 991
+#define GIC700_ESPI_ID_MIN 4096
+#define GIC700_ESPI_ID_MAX 5119
+
/* Number of retries for PUP update */
#define GICD_PUP_UPDATE_RETRIES 10000
@@ -53,6 +58,9 @@
#define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
(((spi_id_max) - (spi_id_min) + 1) / \
GIC600_SPI_ID_MIN)
+#define ESPI_BLOCK_MIN_VALUE(spi_id_min) \
+ (((spi_id_min) - GIC700_ESPI_ID_MIN + 1) / \
+ GIC700_SPI_ID_MIN)
#define GICD_CHIPR_VALUE_GIC_700(chip_addr, spi_block_min, spi_blocks) \
(((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
((spi_block_min) << GIC_700_SPI_BLOCK_MIN_SHIFT) | \
diff --git a/fdts/morello-fvp.dts b/fdts/morello-fvp.dts
index 55c87bf..dc3df41 100644
--- a/fdts/morello-fvp.dts
+++ b/fdts/morello-fvp.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,7 @@
#include "morello.dtsi"
/ {
+ model = "Arm Morello Fixed Virtual Platform";
chosen {
stdout-path = "serial0:115200n8";
@@ -78,16 +79,12 @@
/* The first bank of memory, memory map is actually provided by UEFI. */
memory@80000000 {
- #address-cells = <2>;
- #size-cells = <2>;
device_type = "memory";
/* [0x80000000-0xffffffff] */
reg = <0x00000000 0x80000000 0x0 0x80000000>;
};
memory@8080000000 {
- #address-cells = <2>;
- #size-cells = <2>;
device_type = "memory";
/* [0x8080000000-0x83ffffffff] */
reg = <0x00000080 0x80000000 0x1 0x80000000>;
@@ -143,8 +140,8 @@
scmi {
compatible = "arm,scmi";
mbox-names = "tx", "rx";
- mboxes = <&mailbox 1 0 &mailbox 1 1>;
- shmem = <&cpu_scp_hpri0 &cpu_scp_hpri1>;
+ mboxes = <&mailbox 1 0>, <&mailbox 1 1>;
+ shmem = <&cpu_scp_hpri0>, <&cpu_scp_hpri1>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/fdts/morello-soc.dts b/fdts/morello-soc.dts
index 8464634..5f147b7 100644
--- a/fdts/morello-soc.dts
+++ b/fdts/morello-soc.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,9 +8,10 @@
#include "morello.dtsi"
/ {
+ model = "Arm Morello System Development Platform";
chosen {
- stdout-path = "soc_uart0:115200n8";
+ stdout-path = "serial0:115200n8";
};
reserved-memory {
@@ -59,16 +60,12 @@
/* The first bank of memory, memory map is actually provided by UEFI. */
memory@80000000 {
- #address-cells = <2>;
- #size-cells = <2>;
device_type = "memory";
/* [0x80000000-0xffffffff] */
reg = <0x00000000 0x80000000 0x0 0x7F000000>;
};
memory@8080000000 {
- #address-cells = <2>;
- #size-cells = <2>;
device_type = "memory";
/* [0x8080000000-0x83f7ffffff] */
reg = <0x00000080 0x80000000 0x3 0x78000000>;
@@ -78,10 +75,10 @@
compatible = "arm,smmu-v3";
reg = <0 0x4f400000 0 0x40000>;
interrupts = <GIC_SPI 235 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 237 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 40 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 236 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 237 IRQ_TYPE_EDGE_RISING>;
- interrupt-names = "eventq", "priq", "cmdq-sync", "gerror";
+ <GIC_SPI 236 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
msi-parent = <&its2 0>;
#iommu-cells = <1>;
dma-coherent;
@@ -114,10 +111,10 @@
compatible = "arm,smmu-v3";
reg = <0 0x4f000000 0 0x40000>;
interrupts = <GIC_SPI 228 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 230 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 41 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 229 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 230 IRQ_TYPE_EDGE_RISING>;
- interrupt-names = "eventq", "priq", "cmdq-sync", "gerror";
+ <GIC_SPI 229 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
msi-parent = <&its1 0>;
#iommu-cells = <1>;
dma-coherent;
@@ -150,16 +147,16 @@
compatible = "arm,smmu-v3";
reg = <0 0x2ce00000 0 0x40000>;
interrupts = <GIC_SPI 76 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 78 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 80 IRQ_TYPE_EDGE_RISING>;
- interrupt-names = "eventq", "cmdq-sync", "gerror";
+ <GIC_SPI 80 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 78 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "eventq", "gerror", "cmdq-sync";
#iommu-cells = <1>;
};
dp0: display@2cc00000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "arm,mali-d32";
+ compatible = "arm,mali-d32", "arm,mali-d71";
reg = <0 0x2cc00000 0 0x20000>;
interrupts = <0 69 4>;
interrupt-names = "DPU";
@@ -220,8 +217,8 @@
scmi {
compatible = "arm,scmi";
mbox-names = "tx", "rx";
- mboxes = <&mailbox 1 0 &mailbox 1 1>;
- shmem = <&cpu_scp_hpri0 &cpu_scp_hpri1>;
+ mboxes = <&mailbox 1 0>, <&mailbox 1 1>;
+ shmem = <&cpu_scp_hpri0>, <&cpu_scp_hpri1>;
#address-cells = <1>;
#size-cells = <0>;
scmi_dvfs: protocol@13 {
@@ -241,28 +238,28 @@
<0x0 0x300c0000 0 0x80000>; /* GICR */
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
- its1: its@30040000 {
+ its1: msi-controller@30040000 {
compatible = "arm,gic-v3-its";
msi-controller;
#msi-cells = <1>;
reg = <0x0 0x30040000 0x0 0x20000>;
};
- its2: its@30060000 {
+ its2: msi-controller@30060000 {
compatible = "arm,gic-v3-its";
msi-controller;
#msi-cells = <1>;
reg = <0x0 0x30060000 0x0 0x20000>;
};
- its_ccix: its@30080000 {
+ its_ccix: msi-controller@30080000 {
compatible = "arm,gic-v3-its";
msi-controller;
#msi-cells = <1>;
reg = <0x0 0x30080000 0x0 0x20000>;
};
- its_pcie: its@300a0000 {
+ its_pcie: msi-controller@300a0000 {
compatible = "arm,gic-v3-its";
msi-controller;
#msi-cells = <1>;
diff --git a/fdts/morello.dtsi b/fdts/morello.dtsi
index f119820..20640c5 100644
--- a/fdts/morello.dtsi
+++ b/fdts/morello.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,7 +18,7 @@
};
gic: interrupt-controller@2c010000 {
- compatible = "arm,gic-600", "arm,gic-v3";
+ compatible = "arm,gic-v3";
#address-cells = <2>;
#interrupt-cells = <3>;
#size-cells = <2>;
@@ -70,12 +70,12 @@
#size-cells = <1>;
ranges = <0 0x0 0x06000000 0x8000>;
- cpu_scp_hpri0: scp-shmem@0 {
+ cpu_scp_hpri0: scp-sram@0 {
compatible = "arm,scmi-shmem";
reg = <0x0 0x80>;
};
- cpu_scp_hpri1: scp-shmem@80 {
+ cpu_scp_hpri1: scp-sram@80 {
compatible = "arm,scmi-shmem";
reg = <0x80 0x80>;
};
@@ -95,7 +95,7 @@
clock-output-names = "uartclk";
};
- soc_uart0: uart@2a400000 {
+ soc_uart0: serial@2a400000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0 0x2a400000 0x0 0x1000>;
interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 1c71149..5bb22fd 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -315,7 +315,7 @@
#define SGIR_IRM_SHIFT 40
#define SGIR_IRM_MASK ULL(0x1)
#define SGIR_AFF3_SHIFT 48
-#define SGIR_AFF_MASK ULL(0xf)
+#define SGIR_AFF_MASK ULL(0xff)
#define SGIR_IRM_TO_AFF U(0)
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index 43e2f96..3edc50b 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -92,6 +92,7 @@
int psci_stop_other_cores(unsigned int wait_ms,
void (*stop_func)(u_register_t mpidr));
bool psci_is_last_on_cpu_safe(void);
+void psci_pwrdown_cpu(unsigned int power_level);
#endif /* __ASSEMBLER__ */
diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h
index e5357f5..84e6b38 100644
--- a/include/plat/arm/css/common/css_pm.h
+++ b/include/plat/arm/css/common/css_pm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,9 @@
#include <lib/psci/psci.h>
+/* SGI used to trigger per-core power down request */
+#define CSS_CPU_PWR_DOWN_REQ_INTR ARM_IRQ_SEC_SGI_7
+
/* Macros to read the CSS power domain state */
#define CSS_CORE_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL0]
#define CSS_CLUSTER_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL1]
@@ -37,6 +40,9 @@
void css_cpu_standby(plat_local_state_t cpu_state);
void css_get_sys_suspend_power_state(psci_power_state_t *req_state);
int css_node_hw_state(u_register_t mpidr, unsigned int power_level);
+void css_setup_cpu_pwr_down_intr(void);
+int css_reboot_interrupt_handler(uint32_t intr_raw, uint32_t flags,
+ void *handle, void *cookie);
/*
* This mapping array has to be exported by the platform. Each element at
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 68aacc1..4355b12 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -229,14 +230,11 @@
sctlr_el2);
/*
- * The GICv3 driver initializes the ICC_SRE_EL2 register during
- * platform setup. Use the same setting for the corresponding
- * context register to make sure the correct bits are set when
- * restoring NS context.
+ * Program the ICC_SRE_EL2 to make sure the correct bits are set
+ * when restoring NS context.
*/
- u_register_t icc_sre_el2 = read_icc_sre_el2();
- icc_sre_el2 |= (ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT);
- icc_sre_el2 |= (ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT);
+ u_register_t icc_sre_el2 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
+ ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_ICC_SRE_EL2,
icc_sre_el2);
#endif /* CTX_INCLUDE_EL2_REGS */
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index b60ddbb..efcfed8 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -954,7 +954,7 @@
* Initiate power down sequence, by calling power down operations registered for
* this CPU.
******************************************************************************/
-void psci_do_pwrdown_sequence(unsigned int power_level)
+void psci_pwrdown_cpu(unsigned int power_level)
{
#if HW_ASSISTED_COHERENCY
/*
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index 5447045..637adb9 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -109,7 +109,7 @@
/*
* Arch. management. Initiate power down sequence.
*/
- psci_do_pwrdown_sequence(psci_find_max_off_lvl(&state_info));
+ psci_pwrdown_cpu(psci_find_max_off_lvl(&state_info));
#if ENABLE_RUNTIME_INSTRUMENTATION
PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 61bd966..caade9c 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -296,7 +296,6 @@
void psci_print_power_domain_map(void);
unsigned int psci_is_last_on_cpu(void);
int psci_spd_migrate_info(u_register_t *mpidr);
-void psci_do_pwrdown_sequence(unsigned int power_level);
/*
* CPU power down is directly called only when HW_ASSISTED_COHERENCY is
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index ffe3a91..f71994d 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -124,7 +124,7 @@
* TODO : Introduce a mechanism to query the cache level to flush
* and the cpu-ops power down to perform from the platform.
*/
- psci_do_pwrdown_sequence(max_off_lvl);
+ psci_pwrdown_cpu(max_off_lvl);
#if ENABLE_RUNTIME_INSTRUMENTATION
PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index 464a157..3474016 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -96,4 +96,8 @@
#define PLAT_ARM_GICR_BASE UL(0x301C0000)
#endif
+/* Interrupt priority level for shutdown/reboot */
+#define PLAT_REBOOT_PRI GIC_HIGHEST_SEC_PRIORITY
+#define PLAT_EHF_DESC EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_REBOOT_PRI)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index b882dc8..cfe4e28 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -24,6 +24,9 @@
GICV3_IMPL_GIC600_MULTICHIP := 1
endif
+override CSS_SYSTEM_GRACEFUL_RESET := 1
+override EL3_EXCEPTION_HANDLING := 1
+
include plat/arm/css/sgi/sgi-common.mk
RDN2_BASE = plat/arm/board/rdn2
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index 2fbbe45..1e4851c 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -35,6 +35,7 @@
drivers/arm/css/scmi/scmi_common.c \
drivers/arm/css/scmi/scmi_pwr_dmn_proto.c \
drivers/arm/css/scmi/scmi_sys_pwr_proto.c \
+ drivers/delay_timer/delay_timer.c \
drivers/arm/css/scp/css_pm_scmi.c
endif
@@ -88,3 +89,9 @@
$(eval $(call assert_boolean,CSS_NON_SECURE_UART))
$(eval $(call add_define,CSS_NON_SECURE_UART))
+# Process CSS_SYSTEM_GRACEFUL_RESET flag
+# This build option can be used on CSS platforms that require all the CPUs
+# to execute the CPU specific power down sequence to complete a warm reboot
+# sequence in which only the CPUs are power cycled.
+CSS_SYSTEM_GRACEFUL_RESET := 0
+$(eval $(call add_define,CSS_SYSTEM_GRACEFUL_RESET))
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 926b8ec..9b2639c 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,10 +9,14 @@
#include <platform_def.h>
#include <arch_helpers.h>
+#include <bl31/interrupt_mgmt.h>
#include <common/debug.h>
#include <drivers/arm/css/css_scp.h>
#include <lib/cassert.h>
#include <plat/arm/common/plat_arm.h>
+
+#include <plat/common/platform.h>
+
#include <plat/arm/css/common/css_pm.h>
/* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
@@ -110,6 +114,9 @@
/* Enable the gic cpu interface */
plat_arm_gic_cpuif_enable();
+
+ /* Setup the CPU power down request interrupt for secondary core(s) */
+ css_setup_cpu_pwr_down_intr();
}
/*******************************************************************************
@@ -331,6 +338,52 @@
return arm_validate_power_state(power_state, output_state);
}
+/*
+ * Setup the SGI interrupt that will be used trigger the execution of power
+ * down sequence for all the secondary cores. This interrupt is setup to be
+ * handled in EL3 context at a priority defined by the platform.
+ */
+void css_setup_cpu_pwr_down_intr(void)
+{
+#if CSS_SYSTEM_GRACEFUL_RESET
+ plat_ic_set_interrupt_type(CSS_CPU_PWR_DOWN_REQ_INTR, INTR_TYPE_EL3);
+ plat_ic_set_interrupt_priority(CSS_CPU_PWR_DOWN_REQ_INTR,
+ PLAT_REBOOT_PRI);
+ plat_ic_enable_interrupt(CSS_CPU_PWR_DOWN_REQ_INTR);
+#endif
+}
+
+/*
+ * For a graceful shutdown/reboot, each CPU in the system should do their power
+ * down sequence. On a PSCI shutdown/reboot request, only one CPU gets an
+ * opportunity to do the powerdown sequence. To achieve graceful reset, of all
+ * cores in the system, the CPU gets the opportunity raise warm reboot SGI to
+ * rest of the CPUs which are online. Add handler for the reboot SGI where the
+ * rest of the CPU execute the powerdown sequence.
+ */
+int css_reboot_interrupt_handler(uint32_t intr_raw, uint32_t flags,
+ void *handle, void *cookie)
+{
+ assert(intr_raw == CSS_CPU_PWR_DOWN_REQ_INTR);
+
+ /* Deactivate warm reboot SGI */
+ plat_ic_end_of_interrupt(CSS_CPU_PWR_DOWN_REQ_INTR);
+
+ /*
+ * Disable GIC CPU interface to prevent pending interrupt from waking
+ * up the AP from WFI.
+ */
+ plat_arm_gic_cpuif_disable();
+ plat_arm_gic_redistif_off();
+
+ psci_pwrdown_cpu(PLAT_MAX_PWR_LVL);
+
+ dmbsy();
+
+ wfi();
+ return 0;
+}
+
/*******************************************************************************
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
* platform will take care of registering the handlers with PSCI.
diff --git a/plat/arm/css/common/sp_min/css_sp_min.mk b/plat/arm/css/common/sp_min/css_sp_min.mk
index 6523a16..ae489fd 100644
--- a/plat/arm/css/common/sp_min/css_sp_min.mk
+++ b/plat/arm/css/common/sp_min/css_sp_min.mk
@@ -15,6 +15,7 @@
else
BL32_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \
drivers/arm/css/scp/css_pm_scmi.c \
+ drivers/delay_timer/delay_timer.c \
drivers/arm/css/scmi/scmi_common.c \
drivers/arm/css/scmi/scmi_pwr_dmn_proto.c \
drivers/arm/css/scmi/scmi_sys_pwr_proto.c
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 99f2f20..7ef7e6f 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,8 +13,11 @@
#include <drivers/arm/css/css_mhu_doorbell.h>
#include <drivers/arm/css/scmi.h>
#include <plat/arm/common/plat_arm.h>
+
#include <plat/common/platform.h>
+#include <plat/arm/css/common/css_pm.h>
+
#include <sgi_ras.h>
#include <sgi_variant.h>
@@ -105,6 +108,15 @@
#if RAS_EXTENSION
sgi_ras_intr_handler_setup();
#endif
+
+ /* Configure the warm reboot SGI for primary core */
+ css_setup_cpu_pwr_down_intr();
+
+#if CSS_SYSTEM_GRACEFUL_RESET
+ /* Register priority level handlers for reboot */
+ ehf_register_priority_handler(PLAT_REBOOT_PRI,
+ css_reboot_interrupt_handler);
+#endif
}
const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
diff --git a/plat/xilinx/common/include/pm_client.h b/plat/xilinx/common/include/pm_client.h
index dc012b7..eae1d98 100644
--- a/plat/xilinx/common/include/pm_client.h
+++ b/plat/xilinx/common/include/pm_client.h
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,9 +25,9 @@
/* Global variables to be set in pm_client.c */
extern const struct pm_proc *primary_proc;
-#ifndef VERSAL_PLATFORM
+#if defined(PLAT_zynqmp)
enum pm_ret_status pm_set_suspend_mode(uint32_t mode);
const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
-#endif
+#endif /* PLAT_zynqmp */
#endif /* PM_CLIENT_H */
diff --git a/plat/xilinx/common/include/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h
index 2d20b9f..8a15668 100644
--- a/plat/xilinx/common/include/pm_ipi.h
+++ b/plat/xilinx/common/include/pm_ipi.h
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +10,7 @@
#define PM_IPI_H
#include <plat_ipi.h>
+#include <stddef.h>
#include "pm_common.h"
#define IPI_BLOCKING 1
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 2f52f38..318079b 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,7 +18,6 @@
#include <lib/mmio.h>
#include <ipi.h>
-#include <plat_ipi.h>
#include <plat_private.h>
/*********************************************************************
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 12313f2..9c9fd62 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +15,7 @@
#include <plat_private.h>
#include <plat/common/platform.h>
+#include "pm_defs.h"
#include "pm_ipi.h"
#define ERROR_CODE_MASK 0xFFFFU
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 349b856..9b36208 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -184,8 +184,9 @@
}
}
- if (handler != NULL)
- handler(intr_id, flags, handle, cookie);
+ if (handler != NULL) {
+ return handler(intr_id, flags, handle, cookie);
+ }
return 0;
}
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index ecd8d08..db9fae4 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -17,7 +17,6 @@
#include "pm_client.h"
#include "pm_defs.h"
#include "pm_svc_main.h"
-#include "../drivers/arm/gic/v3/gicv3_private.h"
/* default shutdown/reboot scope is system(2) */
static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
@@ -466,8 +465,6 @@
if (ret != 0) {
return PM_RET_ERROR_ARGS;
}
- gicd_write_irouter(gicv3_driver_data->gicd_base,
- (uint32_t)PLAT_VERSAL_IPI_IRQ, MODE);
ret = PM_RET_SUCCESS;
break;
default:
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index e2a3cf8..c539aa7 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -17,7 +17,6 @@
#define LIBPM_MODULE_ID 0x2U
#define LOADER_MODULE_ID 0x7U
-#define MODE 0x80000000U
#define MODULE_ID_MASK 0x0000ff00U
/**********************************************************
* PM API function declarations
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index 4e26d87..929008a 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -19,6 +19,9 @@
#include "pm_client.h"
#include "pm_ipi.h"
#include <drivers/arm/gicv3.h>
+#include "../drivers/arm/gic/v3/gicv3_private.h"
+
+#define MODE 0x80000000U
#define XSCUGIC_SGIR_EL1_INITID_SHIFT 24U
#define INVALID_SGI 0xFFU
@@ -139,6 +142,8 @@
if (ret != 0) {
WARN("BL31: registering IPI interrupt failed\n");
}
+
+ gicd_write_irouter(gicv3_driver_data->gicd_base, PLAT_VERSAL_IPI_IRQ, MODE);
return ret;
}
@@ -253,7 +258,7 @@
*
* These EEMI calls performs functionality that does not require
* IPI transaction. The handler ends in TF-A and returns requested data to
- * kernel from TF-A
+ * kernel from TF-A.
*/
static uintptr_t TF_A_specific_handler(uint32_t api_id, uint32_t *pm_arg,
void *handle, uint32_t security_flag)
@@ -355,7 +360,7 @@
uint32_t api_id;
/* Handle case where PM wasn't initialized properly */
- if (!pm_up) {
+ if (pm_up == false) {
SMC_RET1(handle, SMC_UNK);
}
@@ -363,7 +368,7 @@
* Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
* if smc called is non secure
*/
- if (is_caller_non_secure(flags)) {
+ if (is_caller_non_secure(flags) != 0) {
security_flag = NON_SECURE_FLAG;
}
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 38ad32b..1d59537 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -176,7 +176,7 @@
/* Return if no device tree is detected */
if (fdt_check_header(dtb) != 0) {
- NOTICE("Can't read DT at 0x%p\n", dtb);
+ NOTICE("Can't read DT at %p\n", dtb);
return;
}
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 66bbf30..c2d22c2 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -40,7 +40,7 @@
# define BL31_BASE U(0xfffea000)
# define BL31_LIMIT U(0x100000000)
#else
-# define BL31_BASE U(0xfff5a000)
+# define BL31_BASE U(0xfffe5000)
# define BL31_LIMIT U(0x100000000)
#endif
#else
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 877127b..428bed5 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -352,7 +352,7 @@
#define RESTART_SCOPE_SHIFT (3)
#define RESTART_SCOPE_MASK (0x3U << RESTART_SCOPE_SHIFT)
-/*AFI registers */
+/* AFI registers */
#define AFIFM6_WRCTRL U(13)
#define FABRIC_WIDTH U(3)
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index 814d051..c0beb65 100644
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -196,7 +196,7 @@
''' Generate arguments for the FIP Tool. '''
if "uuid" in sp_layout[sp]:
# Extract the UUID from the JSON file if the SP entry has a 'uuid' field
- uuid_std = uuid.UUID(data[key]['uuid'])
+ uuid_std = uuid.UUID(sp_layout[sp]['uuid'])
else:
with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
uuid_lines = [l for l in pm_f if 'uuid' in l]