Merge "Cleanup the code for TBBR CoT descriptors" into integration
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 1901a20..5aad14e 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -341,3 +341,199 @@
return fdt_path_offset(dtb, path);
}
+
+
+/*******************************************************************************
+ * Only devices which are direct children of root node use CPU address domain.
+ * All other devices use addresses that are local to the device node and cannot
+ * directly used by CPU. Device tree provides an address translation mechanism
+ * through "ranges" property which provides mappings from local address space to
+ * parent address space. Since a device could be a child of a child node to the
+ * root node, there can be more than one level of address translation needed to
+ * map the device local address space to CPU address space.
+ * fdtw_translate_address() API performs address translation of a local address
+ * to a global address with help of various helper functions.
+ ******************************************************************************/
+
+static bool fdtw_xlat_hit(const uint32_t *value, int child_addr_size,
+ int parent_addr_size, int range_size, uint64_t base_address,
+ uint64_t *translated_addr)
+{
+ uint64_t local_address, parent_address, addr_range;
+
+ local_address = fdt_read_prop_cells(value, child_addr_size);
+ parent_address = fdt_read_prop_cells(value + child_addr_size,
+ parent_addr_size);
+ addr_range = fdt_read_prop_cells(value + child_addr_size +
+ parent_addr_size,
+ range_size);
+ VERBOSE("DT: Address %llx mapped to %llx with range %llx\n",
+ local_address, parent_address, addr_range);
+
+ /* Perform range check */
+ if ((base_address < local_address) ||
+ (base_address >= local_address + addr_range)) {
+ return false;
+ }
+
+ /* Found hit for the addr range that needs to be translated */
+ *translated_addr = parent_address + (base_address - local_address);
+ VERBOSE("DT: child address %llx mapped to %llx in parent bus\n",
+ local_address, parent_address);
+ return true;
+}
+
+#define ILLEGAL_ADDR ULL(~0)
+
+static uint64_t fdtw_search_all_xlat_entries(const void *dtb,
+ const struct fdt_property *ranges_prop,
+ int local_bus, uint64_t base_address)
+{
+ uint64_t translated_addr;
+ const uint32_t *next_entry;
+ int parent_bus_node, nxlat_entries, length;
+ int self_addr_cells, parent_addr_cells, self_size_cells, ncells_xlat;
+
+ /*
+ * The number of cells in one translation entry in ranges is the sum of
+ * the following values:
+ * self#address-cells + parent#address-cells + self#size-cells
+ * Ex: the iofpga ranges property has one translation entry with 4 cells
+ * They represent iofpga#addr-cells + motherboard#addr-cells + iofpga#size-cells
+ * = 1 + 2 + 1
+ */
+
+ parent_bus_node = fdt_parent_offset(dtb, local_bus);
+ self_addr_cells = fdt_address_cells(dtb, local_bus);
+ self_size_cells = fdt_size_cells(dtb, local_bus);
+ parent_addr_cells = fdt_address_cells(dtb, parent_bus_node);
+
+ /* Number of cells per translation entry i.e., mapping */
+ ncells_xlat = self_addr_cells + parent_addr_cells + self_size_cells;
+
+ assert(ncells_xlat > 0);
+
+ /*
+ * Find the number of translations(mappings) specified in the current
+ * `ranges` property. Note that length represents number of bytes and
+ * is stored in big endian mode.
+ */
+ length = fdt32_to_cpu(ranges_prop->len);
+ nxlat_entries = (length/sizeof(uint32_t))/ncells_xlat;
+
+ assert(nxlat_entries > 0);
+
+ next_entry = (const uint32_t *)ranges_prop->data;
+
+ /* Iterate over the entries in the "ranges" */
+ for (int i = 0; i < nxlat_entries; i++) {
+ if (fdtw_xlat_hit(next_entry, self_addr_cells,
+ parent_addr_cells, self_size_cells, base_address,
+ &translated_addr)){
+ return translated_addr;
+ }
+ next_entry = next_entry + ncells_xlat;
+ }
+
+ INFO("DT: No translation found for address %llx in node %s\n",
+ base_address, fdt_get_name(dtb, local_bus, NULL));
+ return ILLEGAL_ADDR;
+}
+
+
+/*******************************************************************************
+ * address mapping needs to be done recursively starting from current node to
+ * root node through all intermediate parent nodes.
+ * Sample device tree is shown here:
+
+smb@0,0 {
+ 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>;
+
+ motherboard {
+ arm,v2m-memory-map = "rs1";
+ compatible = "arm,vexpress,v2m-p1", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges;
+
+ iofpga@3,00000000 {
+ compatible = "arm,amba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 3 0 0x200000>;
+ v2m_serial1: uart@a0000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0a0000 0x1000>;
+ interrupts = <0 6 4>;
+ clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+ };
+};
+
+ * As seen above, there are 3 levels of address translations needed. An empty
+ * `ranges` property denotes identity mapping (as seen in `motherboard` node).
+ * Each ranges property can map a set of child addresses to parent bus. Hence
+ * there can be more than 1 (translation) entry in the ranges property as seen
+ * in the `smb` node which has 6 translation entries.
+ ******************************************************************************/
+
+/* Recursive implementation */
+uint64_t fdtw_translate_address(const void *dtb, int node,
+ uint64_t base_address)
+{
+ int length, local_bus_node;
+ const char *node_name;
+ uint64_t global_address;
+
+ local_bus_node = fdt_parent_offset(dtb, node);
+ node_name = fdt_get_name(dtb, local_bus_node, NULL);
+
+ /*
+ * In the example given above, starting from the leaf node:
+ * uart@a000 represents the current node
+ * iofpga@3,00000000 represents the local bus
+ * motherboard represents the parent bus
+ */
+
+ /* Read the ranges property */
+ const struct fdt_property *property = fdt_get_property(dtb,
+ local_bus_node, "ranges", &length);
+
+ if (property == NULL) {
+ if (local_bus_node == 0) {
+ /*
+ * root node doesn't have range property as addresses
+ * are in CPU address space.
+ */
+ return base_address;
+ }
+ INFO("DT: Couldn't find ranges property in node %s\n",
+ node_name);
+ return ILLEGAL_ADDR;
+ } else if (length == 0) {
+ /* empty ranges indicates identity map to parent bus */
+ return fdtw_translate_address(dtb, local_bus_node, base_address);
+ }
+
+ VERBOSE("DT: Translation lookup in node %s at offset %d\n", node_name,
+ local_bus_node);
+ global_address = fdtw_search_all_xlat_entries(dtb, property,
+ local_bus_node, base_address);
+
+ if (global_address == ILLEGAL_ADDR) {
+ return ILLEGAL_ADDR;
+ }
+
+ /* Translate the local device address recursively */
+ return fdtw_translate_address(dtb, local_bus_node, global_address);
+}
diff --git a/docs/about/features.rst b/docs/about/features.rst
index 7c73952..964cb25 100644
--- a/docs/about/features.rst
+++ b/docs/about/features.rst
@@ -108,8 +108,8 @@
- Refinements to Position Independent Executable (PIE) support.
-- Continued support for the draft SPCI specification, to enable the use of
- secure partition management in the secure world.
+- Continued support for the PSA FF-A v1.0 (formally known as SPCI) specification, to enable the
+ use of secure partition management in the secure world.
- Documentation enhancements.
diff --git a/docs/components/index.rst b/docs/components/index.rst
index e3ce614..c5f6264 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -17,5 +17,5 @@
romlib-design
sdei
secure-partition-manager-design
- spci-manifest-binding
+ psa-ffa-manifest-binding
xlat-tables-lib-v2-design
diff --git a/docs/components/spci-manifest-binding.rst b/docs/components/psa-ffa-manifest-binding.rst
similarity index 83%
rename from docs/components/spci-manifest-binding.rst
rename to docs/components/psa-ffa-manifest-binding.rst
index 5848169..09894ae 100644
--- a/docs/components/spci-manifest-binding.rst
+++ b/docs/components/psa-ffa-manifest-binding.rst
@@ -1,49 +1,39 @@
-SPCI manifest binding to device tree
-====================================
+PSA FF-A manifest binding to device tree
+========================================
This document defines the nodes and properties used to define a partition,
-according to the SPCI specification.
+according to the PSA FF-A specification.
Version 1.0
-----------
-spci-manifest-partition
-^^^^^^^^^^^^^^^^^^^^^^^
+Partition Properties
+^^^^^^^^^^^^^^^^^^^^
- compatible [mandatory]
- value type: <string>
- - Must be the string "arm,spci-manifest-X.Y" which specifies the major and
- minor versions fo the device tree binding for the SPCI manifest represented
+ - Must be the string "arm,ffa-manifest-X.Y" which specifies the major and
+ minor versions fo the device tree binding for the FFA manifest represented
by this node. The minor number is incremented if the binding changes in a
backwards compatible manner.
- X is an integer representing the major version number of this document.
- Y is an integer representing the minor version number of this document.
-- spci-version [mandatory]
+- ffa-version [mandatory]
- value type: <u32>
- Must be two 16 bits values (X, Y), concatenated as 31:16 -> X,
15:0 -> Y, where:
- - X is the major version of PSA-FF-A expected by the partition at the SPCI
+ - X is the major version of PSA-FF-A expected by the partition at the FFA
instance it will execute.
- - Y is the minor version of PSA-FF-A expected by the partition at the SPCI
+ - Y is the minor version of PSA-FF-A expected by the partition at the FFA
instance it will execute.
- uuid [mandatory]
- value type: <prop-encoded-array>
- An array consisting of 4 <u32> values, identifying the UUID of the service
implemented by this partition. The UUID format is described in RFC 4122.
- UUID can be shared by multiple instances of partitions that offer the same
- service For example:
-
- - If there are multiple instances of a Trusted OS, then the UUID can be
- shared by all instances.
- - The TEE driver in the HLOS can use the UUID with the
- SPCI_PARTITION_INFO_GET interface to determine the:
-
- - Number of Trusted OSs
- - The partition ID of each instance of the Trusted OS
- id
- value type: <u32>
@@ -75,9 +65,6 @@
- 0x0: EL1
- 0x1: S_EL0
- 0x2: S_EL1
- - 0x3: EL2
- - 0x4: Supervisor mode
- - 0x5: Secure User mode
- execution-state [mandatory]
- value type: <u32>
@@ -104,7 +91,7 @@
- 0x0: 4k
- 0x1: 16k
- - 0x2: 32k
+ - 0x2: 64k
- boot-order
- value type: <u32>
@@ -116,7 +103,7 @@
- value type: "memory-regions" node
- Specific "memory-regions" nodes that describe the RX/TX buffers expected
by the partition.
- The "compatible" must be the string "arm,spci-manifest-rx_tx-buffer".
+ The "compatible" must be the string "arm,ffa-manifest-rx_tx-buffer".
- messaging-method [mandatory]
- value type: <u32>
@@ -146,7 +133,7 @@
- gp-register-num
- value type: <u32>
- Presence of this field indicates that the partition expects the
- spci_init_info structure to be passed in via the specified general purpose
+ ffa_init_info structure to be passed in via the specified general purpose
register.
The field specifies the general purpose register number but not its width.
The width is derived from the partition's execution state, as specified in
@@ -159,12 +146,12 @@
- List of <u32> tuples, identifying the IDs this partition is acting as
proxy for.
-memory-regions
+Memory Regions
--------------
- compatible [mandatory]
- value type: <string>
- - Must be the string "arm,spci-manifest-memory-regions".
+ - Must be the string "arm,ffa-manifest-memory-regions".
- description
- value type: <string>
@@ -177,26 +164,30 @@
- attributes [mandatory]
- value type: <u32>
- - ?? TO DEFINE
+ - Mapping modes: ORed to get required permission
+
+ - 0x1: Read
+ - 0x2: Write
+ - 0x4: Execute
- base-address
- value type: <u64>
- Base address of the region. The address must be aligned to the translation
granule size.
The address given may be a Physical Address (PA), Virtual Address (VA), or
- Intermediate Physical Address (IPA). Refer to the SPCI specification for
+ Intermediate Physical Address (IPA). Refer to the FFA specification for
more information on the restrictions around the address type.
If the base address is omitted then the partition manager must map a memory
region of the specified size into the partition's translation regime and
then communicate the region properties (including the base address chosen
by the partition manager) to the partition.
-device-regions
+Device Regions
--------------
- compatible [mandatory]
- value type: <string>
- - Must be the string "arm,spci-manifest-device-regions".
+ - Must be the string "arm,ffa-manifest-device-regions".
- description
- value type: <string>
@@ -213,7 +204,11 @@
- attributes [mandatory]
- value type: <u32>
- - ?? TO DEFINE
+ - Mapping modes: ORed to get required permission
+
+ - 0x1: Read
+ - 0x2: Write
+ - 0x4: Execute
- smmu-id
- value type: <u32>
@@ -222,19 +217,18 @@
upstream of. If the field is omitted then it is assumed that the device is
not upstream of any SMMU.
-- stream-ids [mandatory]
+- stream-ids
- value type: <prop-encoded-array>
- A list of (id, mem-manage) pair, where:
- id: A unique <u32> value amongst all devices assigned to the partition.
- - mem-manage: A <u32> value used in memory management operations.
- interrupts [mandatory]
- value type: <prop-encoded-array>
- A list of (id, attributes) pair describing the device interrupts, where:
- id: The <u32> interrupt IDs.
- - attributes: A ?? TO DEFINE value,
+ - attributes: A <u32> value,
containing the attributes for each interrupt ID:
- Interrupt type: SPI, PPI, SGI
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 2d17f12..b7a93e4 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -1890,6 +1890,21 @@
of the system counter, which is retrieved from the first entry in the frequency
modes table.
+Function : plat_arm_set_twedel_scr_el3() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : uint32_t
+
+This function is used in v8.6+ systems to set the WFE trap delay value in
+SCR_EL3. If this function returns TWED_DISABLED or is left unimplemented, this
+feature is not enabled. The only hook provided is to set the TWED fields in
+SCR_EL3, there are similar fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 to adjust
+the WFE trap delays in lower ELs and these fields should be set by the
+appropriate EL2 or EL1 code depending on the platform configuration.
+
#define : PLAT_PERCPU_BAKERY_LOCK_SIZE [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1941,23 +1956,27 @@
Functions
.........
-Function: int plat_sdei_validate_entry_point(uintptr_t ep) [optional]
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Function: int plat_sdei_validate_entry_point() [optional]
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- Argument: uintptr_t
+ Argument: uintptr_t ep, unsigned int client_mode
Return: int
-This function validates the address of client entry points provided for both
-event registration and *Complete and Resume* |SDEI| calls. The function
-takes one argument, which is the address of the handler the |SDEI| client
-requested to register. The function must return ``0`` for successful validation,
-or ``-1`` upon failure.
+This function validates the entry point address of the event handler provided by
+the client for both event registration and *Complete and Resume* |SDEI| calls.
+The function ensures that the address is valid in the client translation regime.
+
+The second argument is the exception level that the client is executing in. It
+can be Non-Secure EL1 or Non-Secure EL2.
+
+The function must return ``0`` for successful validation, or ``-1`` upon failure.
The default implementation always returns ``0``. On Arm platforms, this function
-is implemented to translate the entry point to physical address, and further to
-ensure that the address is located in Non-secure DRAM.
+translates the entry point address within the client translation regime and
+further ensures that the resulting physical address is located in Non-secure
+DRAM.
Function: void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr) [optional]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index 4dda1dc..d33155b 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -14,6 +14,7 @@
.. |EHF| replace:: :term:`EHF`
.. |FCONF| replace:: :term:`FCONF`
.. |FDT| replace:: :term:`FDT`
+.. |FFA| replace:: :term:`FFA`
.. |FIP| replace:: :term:`FIP`
.. |FVP| replace:: :term:`FVP`
.. |FWU| replace:: :term:`FWU`
@@ -44,7 +45,6 @@
.. |SMCCC| replace:: :term:`SMCCC`
.. |SoC| replace:: :term:`SoC`
.. |SP| replace:: :term:`SP`
-.. |SPCI| replace:: :term:`SPCI`
.. |SPD| replace:: :term:`SPD`
.. |SPM| replace:: :term:`SPM`
.. |SSBS| replace:: :term:`SSBS`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 3da30b0..e087079 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -57,6 +57,9 @@
FDT
Flattened Device Tree
+ FFA
+ Firmware Framework for A-class processors
+
FIP
Firmware Image Package
@@ -107,6 +110,9 @@
PMF
Performance Measurement Framework
+ PSA
+ Platform Security Architecture
+
PSCI
Power State Coordination Interface
@@ -149,9 +155,6 @@
SP
Secure Partition
- SPCI
- Secure Partition Client Interface
-
SPD
Secure Payload Dispatcher
diff --git a/fdts/fvp-base-gicv2-psci-aarch32.dts b/fdts/fvp-base-gicv2-psci-aarch32.dts
index fcef927..591ec58 100644
--- a/fdts/fvp-base-gicv2-psci-aarch32.dts
+++ b/fdts/fvp-base-gicv2-psci-aarch32.dts
@@ -4,8 +4,15 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/* Configuration: max 4 clusters with up to 4 CPUs */
+
/dts-v1/;
+#define AFF
+#define REG_32
+
+#include "fvp-defs.dtsi"
+
/memreserve/ 0x80000000 0x00010000;
/ {
@@ -42,37 +49,7 @@
#address-cells = <1>;
#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>;
- };
- };
- };
+ CPU_MAP
idle-states {
entry-method = "arm,psci";
@@ -96,77 +73,7 @@
};
};
- CPU0:cpu@0 {
- device_type = "cpu";
- compatible = "arm,armv8";
- reg = <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 = <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 = <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 = <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 = <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 = <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 = <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 = <0x103>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
- next-level-cache = <&L2_0>;
- };
+ CPUS
L2_0: l2-cache0 {
compatible = "cache";
diff --git a/fdts/fvp-base-gicv2-psci.dts b/fdts/fvp-base-gicv2-psci.dts
index 1e0a81c..4b3942e 100644
--- a/fdts/fvp-base-gicv2-psci.dts
+++ b/fdts/fvp-base-gicv2-psci.dts
@@ -4,8 +4,14 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/* Configuration: max 4 clusters with up to 4 CPUs */
+
/dts-v1/;
+#define AFF
+
+#include "fvp-defs.dtsi"
+
/memreserve/ 0x80000000 0x00010000;
/ {
@@ -42,37 +48,7 @@
#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>;
- };
- };
- };
+ CPU_MAP
idle-states {
entry-method = "arm,psci";
@@ -96,77 +72,7 @@
};
};
- 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>;
- };
+ CPUS
L2_0: l2-cache0 {
compatible = "cache";
diff --git a/fdts/fvp-base-gicv3-psci-1t.dts b/fdts/fvp-base-gicv3-psci-1t.dts
index 3c82f7b..c5e0424 100644
--- a/fdts/fvp-base-gicv3-psci-1t.dts
+++ b/fdts/fvp-base-gicv3-psci-1t.dts
@@ -4,38 +4,11 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/* Configuration: max 4 clusters with up to 4 CPUs with 1 thread per each */
+
/dts-v1/;
+#define AFF 00
+
+#include "fvp-defs.dtsi"
#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>;
-};
diff --git a/fdts/fvp-base-gicv3-psci-aarch32-1t.dts b/fdts/fvp-base-gicv3-psci-aarch32-1t.dts
index d1d3348..a31c703 100644
--- a/fdts/fvp-base-gicv3-psci-aarch32-1t.dts
+++ b/fdts/fvp-base-gicv3-psci-aarch32-1t.dts
@@ -4,38 +4,12 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/* Configuration: max 4 clusters with up to 4 CPUs with 1 thread per each */
+
/dts-v1/;
+#define AFF 00
+#define REG_32
+
+#include "fvp-defs.dtsi"
#include "fvp-base-gicv3-psci-aarch32-common.dtsi"
-
-&CPU0 {
- reg = <0x0>;
-};
-
-&CPU1 {
- reg = <0x100>;
-};
-
-&CPU2 {
- reg = <0x200>;
-};
-
-&CPU3 {
- reg = <0x300>;
-};
-
-&CPU4 {
- reg = <0x10000>;
-};
-
-&CPU5 {
- reg = <0x10100>;
-};
-
-&CPU6 {
- reg = <0x10200>;
-};
-
-&CPU7 {
- reg = <0x10300>;
-};
diff --git a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi
index a28a4a5..1a1bd12 100644
--- a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi
+++ b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi
@@ -40,37 +40,7 @@
#address-cells = <1>;
#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>;
- };
- };
- };
+ CPU_MAP
idle-states {
entry-method = "arm,psci";
@@ -94,77 +64,7 @@
};
};
- CPU0:cpu@0 {
- device_type = "cpu";
- compatible = "arm,armv8";
- reg = <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 = <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 = <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 = <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 = <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 = <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 = <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 = <0x103>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
- next-level-cache = <&L2_0>;
- };
+ CPUS
L2_0: l2-cache0 {
compatible = "cache";
diff --git a/fdts/fvp-base-gicv3-psci-aarch32.dts b/fdts/fvp-base-gicv3-psci-aarch32.dts
index 513014b..971b2e4 100644
--- a/fdts/fvp-base-gicv3-psci-aarch32.dts
+++ b/fdts/fvp-base-gicv3-psci-aarch32.dts
@@ -4,6 +4,12 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/* Configuration: max 4 clusters with up to 4 CPUs */
+
/dts-v1/;
+#define REG_32
+#define AFF
+
+#include "fvp-defs.dtsi"
#include "fvp-base-gicv3-psci-aarch32-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi
index 4a7b656..0deb8a2 100644
--- a/fdts/fvp-base-gicv3-psci-common.dtsi
+++ b/fdts/fvp-base-gicv3-psci-common.dtsi
@@ -66,37 +66,7 @@
#address-cells = <2>;
#size-cells = <0>;
- CPU_MAP: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>;
- };
- };
- };
+ CPU_MAP
idle-states {
entry-method = "arm,psci";
@@ -120,77 +90,7 @@
};
};
- 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>;
- };
+ CPUS
L2_0: l2-cache0 {
compatible = "cache";
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
index 6e63b43..bda4b8d 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
+++ b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
@@ -4,185 +4,15 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/* DynamIQ configuration: 1 cluster with up to 8 CPUs with 2 threads per each */
+
+/* Set default value if not passed from platform's makefile */
+#ifdef FVP_MAX_PE_PER_CPU
+#define PE_PER_CPU FVP_MAX_PE_PER_CPU
+#else
+#define PE_PER_CPU 2
+#endif
+
/dts-v1/;
#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
-
-&CPU_MAP {
- /delete-node/ cluster0;
-
- cluster0 {
- core0 {
- thread0 {
- cpu = <&CPU0>;
- };
- thread1 {
- cpu = <&CPU1>;
- };
- };
- core1 {
- thread0 {
- cpu = <&CPU2>;
- };
- thread1 {
- cpu = <&CPU3>;
- };
- };
- core2 {
- thread0 {
- cpu = <&CPU4>;
- };
- thread1 {
- cpu = <&CPU5>;
- };
- };
- core3 {
- thread0 {
- cpu = <&CPU6>;
- };
- thread1 {
- cpu = <&CPU7>;
- };
- };
- core4 {
- thread0 {
- cpu = <&CPU8>;
- };
- thread1 {
- cpu = <&CPU9>;
- };
- };
- core5 {
- thread0 {
- cpu = <&CPU10>;
- };
- thread1 {
- cpu = <&CPU11>;
- };
- };
- core6 {
- thread0 {
- cpu = <&CPU12>;
- };
- thread1 {
- cpu = <&CPU13>;
- };
- };
- core7 {
- thread0 {
- cpu = <&CPU14>;
- };
- thread1 {
- cpu = <&CPU15>;
- };
- };
- };
-};
-
-/ {
- cpus {
- CPU0:cpu@0 {
- reg = <0x0 0x0>;
- };
-
- CPU1:cpu@1 {
- reg = <0x0 0x1>;
- };
-
- CPU2:cpu@2 {
- reg = <0x0 0x100>;
- };
-
- CPU3:cpu@3 {
- reg = <0x0 0x101>;
- };
-
- CPU4:cpu@100 {
- reg = <0x0 0x200>;
- };
-
- CPU5:cpu@101 {
- reg = <0x0 0x201>;
- };
-
- CPU6:cpu@102 {
- reg = <0x0 0x300>;
- };
-
- CPU7:cpu@103 {
- reg = <0x0 0x301>;
- };
-
- CPU8:cpu@200 {
- device_type = "cpu";
- compatible = "arm,armv8";
- reg = <0x0 0x400>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
- next-level-cache = <&L2_0>;
- };
-
- CPU9:cpu@201 {
- device_type = "cpu";
- compatible = "arm,armv8";
- reg = <0x0 0x401>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
- next-level-cache = <&L2_0>;
- };
-
- CPU10:cpu@202 {
- device_type = "cpu";
- compatible = "arm,armv8";
- reg = <0x0 0x500>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
- next-level-cache = <&L2_0>;
- };
-
- CPU11:cpu@203 {
- device_type = "cpu";
- compatible = "arm,armv8";
- reg = <0x0 0x501>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
- next-level-cache = <&L2_0>;
- };
-
- CPU12:cpu@300 {
- device_type = "cpu";
- compatible = "arm,armv8";
- reg = <0x0 0x600>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
- next-level-cache = <&L2_0>;
- };
-
- CPU13:cpu@301 {
- device_type = "cpu";
- compatible = "arm,armv8";
- reg = <0x0 0x601>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
- next-level-cache = <&L2_0>;
- };
-
- CPU14:cpu@302 {
- device_type = "cpu";
- compatible = "arm,armv8";
- reg = <0x0 0x700>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
- next-level-cache = <&L2_0>;
- };
-
- CPU15:cpu@303 {
- device_type = "cpu";
- compatible = "arm,armv8";
- reg = <0x0 0x701>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
- next-level-cache = <&L2_0>;
- };
- };
-};
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi
index 4bed36f..42a439f 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi
+++ b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi
@@ -6,38 +6,5 @@
/dts-v1/;
+#include "fvp-defs-dynamiq.dtsi"
#include "fvp-base-gicv3-psci-common.dtsi"
-
-/* DynamIQ based designs have upto 8 CPUs in each cluster */
-
-&CPU_MAP {
- /delete-node/ cluster0;
- /delete-node/ cluster1;
-
- cluster0 {
- core0 {
- cpu = <&CPU0>;
- };
- core1 {
- cpu = <&CPU1>;
- };
- core2 {
- cpu = <&CPU2>;
- };
- core3 {
- cpu = <&CPU3>;
- };
- core4 {
- cpu = <&CPU4>;
- };
- core5 {
- cpu = <&CPU5>;
- };
- core6 {
- cpu = <&CPU6>;
- };
- core7 {
- cpu = <&CPU7>;
- };
- };
-};
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq.dts b/fdts/fvp-base-gicv3-psci-dynamiq.dts
index b8b0445..b693f75 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq.dts
+++ b/fdts/fvp-base-gicv3-psci-dynamiq.dts
@@ -4,38 +4,15 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/* DynamIQ configuration: 1 cluster with up to 8 CPUs */
+
+/* Set default value if not passed from platform's makefile */
+#ifdef FVP_MAX_PE_PER_CPU
+#define PE_PER_CPU FVP_MAX_PE_PER_CPU
+#else
+#define PE_PER_CPU 1
+#endif
+
/dts-v1/;
#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
-
-&CPU0 {
- reg = <0x0 0x0>;
-};
-
-&CPU1 {
- reg = <0x0 0x100>;
-};
-
-&CPU2 {
- reg = <0x0 0x200>;
-};
-
-&CPU3 {
- reg = <0x0 0x300>;
-};
-
-&CPU4 {
- reg = <0x0 0x400>;
-};
-
-&CPU5 {
- reg = <0x0 0x500>;
-};
-
-&CPU6 {
- reg = <0x0 0x600>;
-};
-
-&CPU7 {
- reg = <0x0 0x700>;
-};
diff --git a/fdts/fvp-base-gicv3-psci.dts b/fdts/fvp-base-gicv3-psci.dts
index 65fa4b0..eb99472 100644
--- a/fdts/fvp-base-gicv3-psci.dts
+++ b/fdts/fvp-base-gicv3-psci.dts
@@ -4,6 +4,11 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/* Configuration: max 4 clusters with up to 4 CPUs */
+
/dts-v1/;
+#define AFF
+
+#include "fvp-defs.dtsi"
#include "fvp-base-gicv3-psci-common.dtsi"
diff --git a/fdts/fvp-defs-dynamiq.dtsi b/fdts/fvp-defs-dynamiq.dtsi
new file mode 100644
index 0000000..3659cd3
--- /dev/null
+++ b/fdts/fvp-defs-dynamiq.dtsi
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_DEFS_DYNAMIQ_DTSI
+#define FVP_DEFS_DYNAMIQ_DTSI
+
+/* Set default topology values if not passed from platform's makefile */
+#ifdef FVP_CLUSTER_COUNT
+#define CLUSTER_COUNT FVP_CLUSTER_COUNT
+#else
+#define CLUSTER_COUNT 1
+#endif
+
+#ifdef FVP_MAX_CPUS_PER_CLUSTER
+#define CPUS_PER_CLUSTER FVP_MAX_CPUS_PER_CLUSTER
+#else
+#define CPUS_PER_CLUSTER 8
+#endif
+
+#define CONCAT(x, y) x##y
+#define CONC(x, y) CONCAT(x, y)
+
+/*
+ * n - CPU number
+ * r - MPID
+ */
+#define CPU(n, r) \
+ CPU##n:cpu@r## { \
+ device_type = "cpu"; \
+ compatible = "arm,armv8"; \
+ reg = <0x0 0x##r>; \
+ enable-method = "psci"; \
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; \
+ next-level-cache = <&L2_0>; \
+ };
+
+#if (PE_PER_CPU == 2)
+#define THREAD(n) \
+ thread##n { \
+ cpu = <&CONC(CPU, __COUNTER__)>; \
+ };
+
+#define CORE(n) \
+ core##n { \
+ THREAD(0) \
+ THREAD(1) \
+ };
+
+#else /* PE_PER_CPU == 1 */
+#define CORE(n) \
+ core##n { \
+ cpu = <&CPU##n>;\
+ };
+#endif /* PE_PER_CORE */
+
+#if (CPUS_PER_CLUSTER == 1)
+#if (PE_PER_CPU == 1)
+#define CPUS \
+ CPU(0, 0)
+#else
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 1)
+#endif
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ };
+
+#elif (CPUS_PER_CLUSTER == 2)
+#if (PE_PER_CPU == 1)
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 100)
+#else
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 1) \
+ CPU(2, 100) \
+ CPU(3, 101)
+#endif
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ CORE(1) \
+ };
+
+#elif (CPUS_PER_CLUSTER == 3)
+#if (PE_PER_CPU == 1)
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 100) \
+ CPU(2, 200)
+#else
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 1) \
+ CPU(2, 100) \
+ CPU(3, 101) \
+ CPU(4, 200) \
+ CPU(5, 201)
+#endif
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ CORE(1) \
+ CORE(2) \
+ };
+
+#elif (CPUS_PER_CLUSTER == 4)
+#if (PE_PER_CPU == 1)
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 100) \
+ CPU(2, 200) \
+ CPU(3, 300)
+#else
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 1) \
+ CPU(2, 100) \
+ CPU(3, 101) \
+ CPU(4, 200) \
+ CPU(5, 201) \
+ CPU(6, 300) \
+ CPU(7, 301)
+#endif
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ CORE(1) \
+ CORE(2) \
+ CORE(3) \
+ };
+
+#elif (CPUS_PER_CLUSTER == 5)
+#if (PE_PER_CPU == 1)
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 100) \
+ CPU(2, 200) \
+ CPU(3, 300) \
+ CPU(4, 400)
+#else
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 1) \
+ CPU(2, 100) \
+ CPU(3, 101) \
+ CPU(4, 200) \
+ CPU(5, 201) \
+ CPU(6, 300) \
+ CPU(7, 301) \
+ CPU(8, 400) \
+ CPU(9, 401)
+#endif
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ CORE(1) \
+ CORE(2) \
+ CORE(3) \
+ CORE(4) \
+ };
+
+#elif (CPUS_PER_CLUSTER == 6)
+#if (PE_PER_CPU == 1)
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 100) \
+ CPU(2, 200) \
+ CPU(3, 300) \
+ CPU(4, 400) \
+ CPU(5, 500)
+#else
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 1) \
+ CPU(2, 100) \
+ CPU(3, 101) \
+ CPU(4, 200) \
+ CPU(5, 201) \
+ CPU(6, 300) \
+ CPU(7, 301) \
+ CPU(8, 400) \
+ CPU(9, 401) \
+ CPU(10, 500) \
+ CPU(11, 501)
+#endif
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ CORE(1) \
+ CORE(2) \
+ CORE(3) \
+ CORE(4) \
+ CORE(5) \
+ };
+
+#elif (CPUS_PER_CLUSTER == 7)
+#if (PE_PER_CPU == 1)
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 100) \
+ CPU(2, 200) \
+ CPU(3, 300) \
+ CPU(4, 400) \
+ CPU(5, 500) \
+ CPU(6, 600)
+#else
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 1) \
+ CPU(2, 100) \
+ CPU(3, 101) \
+ CPU(4, 200) \
+ CPU(5, 201) \
+ CPU(6, 300) \
+ CPU(7, 301) \
+ CPU(8, 400) \
+ CPU(9, 401) \
+ CPU(10, 500) \
+ CPU(11, 501) \
+ CPU(12, 600) \
+ CPU(13, 601)
+#endif
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ CORE(1) \
+ CORE(2) \
+ CORE(3) \
+ CORE(4) \
+ CORE(5) \
+ CORE(6) \
+ };
+
+#else
+#if (PE_PER_CPU == 1)
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 100) \
+ CPU(2, 200) \
+ CPU(3, 300) \
+ CPU(4, 400) \
+ CPU(5, 500) \
+ CPU(6, 600) \
+ CPU(7, 700)
+#else
+#define CPUS \
+ CPU(0, 0) \
+ CPU(1, 1) \
+ CPU(2, 100) \
+ CPU(3, 101) \
+ CPU(4, 200) \
+ CPU(5, 201) \
+ CPU(6, 300) \
+ CPU(7, 301) \
+ CPU(8, 400) \
+ CPU(9, 401) \
+ CPU(10, 500) \
+ CPU(11, 501) \
+ CPU(12, 600) \
+ CPU(13, 601) \
+ CPU(14, 700) \
+ CPU(15, 701)
+#endif
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ CORE(1) \
+ CORE(2) \
+ CORE(3) \
+ CORE(4) \
+ CORE(5) \
+ CORE(6) \
+ CORE(7) \
+ };
+#endif /* CPUS_PER_CLUSTER */
+
+#define CPU_MAP \
+ cpu-map { \
+ CLUSTER(0) \
+ };
+
+#endif /* FVP_DEFS_DYNAMIQ_DTSI */
diff --git a/fdts/fvp-defs.dtsi b/fdts/fvp-defs.dtsi
new file mode 100644
index 0000000..1ffe65a
--- /dev/null
+++ b/fdts/fvp-defs.dtsi
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_DEFS_DTSI
+#define FVP_DEFS_DTSI
+
+/* Set default topology values if not passed from platform's makefile */
+#ifndef CLUSTER_COUNT
+#ifdef FVP_CLUSTER_COUNT
+#define CLUSTER_COUNT FVP_CLUSTER_COUNT
+#else
+#define CLUSTER_COUNT 2
+#endif
+#endif /* CLUSTER_COUNT */
+
+#ifndef CPUS_PER_CLUSTER
+#ifdef FVP_MAX_CPUS_PER_CLUSTER
+#define CPUS_PER_CLUSTER FVP_MAX_CPUS_PER_CLUSTER
+#else
+#define CPUS_PER_CLUSTER 4
+#endif
+#endif /* CPUS_PER_CLUSTER */
+
+/* Get platform's topology */
+#define CPUS_COUNT (CLUSTER_COUNT * CPUS_PER_CLUSTER)
+
+#define CONCAT(x, y) x##y
+#define CONC(x, y) CONCAT(x, y)
+
+/* CPU's cluster */
+#define CLS(n) (n / CPUS_PER_CLUSTER)
+
+/* CPU's position in cluster */
+#define POS(n) (n % CPUS_PER_CLUSTER)
+
+#define ADR(n, c, p) \
+ CPU##n:cpu@CONC(c, CONC(p, AFF)) {
+
+#define PRE \
+ device_type = "cpu"; \
+ compatible = "arm,armv8";
+
+#ifdef REG_32
+/* 32-bit address */
+#define REG(c, p) \
+ reg = <CONC(0x, CONC(c, CONC(p, AFF)))>;
+#else
+/* 64-bit address */
+#define REG(c, p) \
+ reg = <0x0 CONC(0x, CONC(c, CONC(p, AFF)))>;
+#endif /* REG_32 */
+
+#define POST \
+ enable-method = "psci"; \
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; \
+ next-level-cache = <&L2_0>; \
+ };
+
+#ifdef REG_32
+#define CPU_0 \
+ CPU0:cpu@0 { \
+ PRE \
+ reg = <0x0>; \
+ POST
+#else
+#define CPU_0 \
+ CPU0:cpu@0 { \
+ PRE \
+ reg = <0x0 0x0>;\
+ POST
+#endif /* REG_32 */
+
+/*
+ * n - CPU number
+ */
+#define CPU(n, c, p) \
+ ADR(n, c, p) \
+ PRE \
+ REG(c, p) \
+ POST
+
+/* 2 CPUs */
+#if (CPUS_COUNT > 1)
+#if (CLS(1) == 0)
+#define c1
+#define p1 1
+#else
+#define c1 10
+#define p1 0
+#endif
+
+#define CPU_1 CPU(1, c1, p1) /* CPU1: 0.1; 1.0 */
+
+/* 3 CPUs */
+#if (CPUS_COUNT > 2)
+#if (CLS(2) == 0)
+#define c2
+#define p2 2
+#elif (CLS(2) == 1)
+#define c2 10
+#define p2 0
+#else
+#define c2 20
+#define p2 0
+#endif
+
+#define CPU_2 CPU(2, c2, p2) /* CPU2: 0.2; 1.0; 2.0 */
+
+/* 4 CPUs */
+#if (CPUS_COUNT > 3)
+#if (CLS(3) == 0)
+#define c3
+#elif (CLS(3) == 1)
+#define c3 10
+#else
+#define c3 30
+#endif
+
+#if (POS(3) == 0)
+#define p3 0
+#elif (POS(3) == 1)
+#define p3 1
+#else
+#define p3 3
+#endif
+
+#define CPU_3 CPU(3, c3, p3) /* CPU3: 0.3; 1.0; 1.1; 3.0 */
+
+/* 6 CPUs */
+#if (CPUS_COUNT > 4)
+#if (CLS(4) == 1)
+#define c4 10
+#else
+#define c4 20
+#endif
+
+#if (POS(4) == 0)
+#define p4 0
+#else
+#define p4 1
+#endif
+
+#if (CLS(5) == 1)
+#define c5 10
+#else
+#define c5 20
+#endif
+
+#if (POS(5) == 1)
+#define p5 1
+#else
+#define p5 2
+#endif
+
+#define CPU_4 CPU(4, c4, p4) /* CPU4: 1.0; 1.1; 2.0 */
+#define CPU_5 CPU(5, c5, p5) /* CPU5: 1.1; 1.2; 2.1 */
+
+/* 8 CPUs */
+#if (CPUS_COUNT > 6)
+#if (CLS(6) == 1)
+#define c6 10
+#define p6 2
+#elif (CLS(6) == 2)
+#define c6 20
+#define p6 0
+#else
+#define c6 30
+#define p6 0
+#endif
+
+#if (CLS(7) == 1)
+#define c7 10
+#define p7 3
+#elif (CLS(7) == 2)
+#define c7 20
+#define p7 1
+#else
+#define c7 30
+#define p7 1
+#endif
+
+#define CPU_6 CPU(6, c6, p6) /* CPU6: 1.2; 2.0; 3.0 */
+#define CPU_7 CPU(7, c7, p7) /* CPU7: 1.3; 2.1; 3.1 */
+
+/* 9 CPUs */
+#if (CPUS_COUNT > 8)
+#if (POS(8) == 0)
+#define p8 0
+#else
+#define p8 2
+#endif
+
+#define CPU_8 CPU(8, 20, p8) /* CPU8: 2.0; 2.2 */
+
+/* 12 CPUs */
+#if (CPUS_COUNT > 9)
+#if (CLS(9) == 2)
+#define c9 20
+#define p9 1
+#else
+#define c9 30
+#define p9 0
+#endif
+
+#if (CLS(10) == 2)
+#define c10 20
+#define p10 2
+#else
+#define c10 30
+#define p10 1
+#endif
+
+#if (CLS(11) == 2)
+#define c11 20
+#define p11 3
+#else
+#define c11 30
+#define p11 2
+#endif
+
+#define CPU_9 CPU(9, c9, p9) /* CPU9: 2.1; 3.0 */
+#define CPU_10 CPU(10, c10, p10) /* CPU10: 2.2; 3.1 */
+#define CPU_11 CPU(11, c11, p11) /* CPU11: 2.3; 3.2 */
+
+/* 16 CPUs */
+#if (CPUS_COUNT > 12)
+#define CPU_12 CPU(12, 30, 0) /* CPU12: 3.0 */
+#define CPU_13 CPU(13, 30, 1) /* CPU13: 3.1 */
+#define CPU_14 CPU(14, 30, 2) /* CPU14: 3.2 */
+#define CPU_15 CPU(15, 30, 3) /* CPU15: 3.3 */
+#endif /* > 12 */
+#endif /* > 9 */
+#endif /* > 8 */
+#endif /* > 6 */
+#endif /* > 4 */
+#endif /* > 3 */
+#endif /* > 2 */
+#endif /* > 1 */
+
+#if (CPUS_COUNT == 1)
+#define CPUS \
+ CPU_0
+
+#elif (CPUS_COUNT == 2)
+#define CPUS \
+ CPU_0 \
+ CPU_1
+
+#elif (CPUS_COUNT == 3)
+#define CPUS \
+ CPU_0 \
+ CPU_1 \
+ CPU_2
+
+#elif (CPUS_COUNT == 4)
+#define CPUS \
+ CPU_0 \
+ CPU_1 \
+ CPU_2 \
+ CPU_3
+
+#elif (CPUS_COUNT == 6)
+#define CPUS \
+ CPU_0 \
+ CPU_1 \
+ CPU_2 \
+ CPU_3 \
+ CPU_4 \
+ CPU_5
+
+#elif (CPUS_COUNT == 8)
+#define CPUS \
+ CPU_0 \
+ CPU_1 \
+ CPU_2 \
+ CPU_3 \
+ CPU_4 \
+ CPU_5 \
+ CPU_6 \
+ CPU_7
+
+#elif (CPUS_COUNT == 9)
+#define CPUS \
+ CPU_0 \
+ CPU_1 \
+ CPU_2 \
+ CPU_3 \
+ CPU_4 \
+ CPU_5 \
+ CPU_6 \
+ CPU_7 \
+ CPU_8
+
+#elif (CPUS_COUNT == 12)
+#define CPUS \
+ CPU_0 \
+ CPU_1 \
+ CPU_2 \
+ CPU_3 \
+ CPU_4 \
+ CPU_5 \
+ CPU_6 \
+ CPU_7 \
+ CPU_8 \
+ CPU_9 \
+ CPU_10 \
+ CPU_11
+
+#else
+#define CPUS \
+ CPU_0 \
+ CPU_1 \
+ CPU_2 \
+ CPU_3 \
+ CPU_4 \
+ CPU_5 \
+ CPU_6 \
+ CPU_7 \
+ CPU_8 \
+ CPU_9 \
+ CPU_10 \
+ CPU_11 \
+ CPU_12 \
+ CPU_13 \
+ CPU_14 \
+ CPU_15
+#endif /* CPUS_COUNT */
+
+#define CORE(n) \
+ core##n { \
+ cpu = <&CONC(CPU, __COUNTER__)>; \
+ };
+
+/* Max 4 CPUs per cluster */
+#if (CPUS_PER_CLUSTER == 1)
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ };
+#elif (CPUS_PER_CLUSTER == 2)
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ CORE(1) \
+ };
+
+#elif (CPUS_PER_CLUSTER == 3)
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ CORE(1) \
+ CORE(2) \
+ };
+
+#else
+#define CLUSTER(n) \
+ cluster##n { \
+ CORE(0) \
+ CORE(1) \
+ CORE(2) \
+ CORE(3) \
+ };
+#endif /* CPUS_PER_CLUSTER */
+
+/* Max 4 clusters */
+#if (CLUSTER_COUNT == 1)
+#define CPU_MAP \
+ cpu-map { \
+ CLUSTER(0) \
+ };
+
+#elif (CLUSTER_COUNT == 2)
+#define CPU_MAP \
+ cpu-map { \
+ CLUSTER(0) \
+ CLUSTER(1) \
+ };
+
+#elif (CLUSTER_COUNT == 3)
+#define CPU_MAP \
+ cpu-map { \
+ CLUSTER(0) \
+ CLUSTER(1) \
+ CLUSTER(2) \
+ };
+
+#else
+#define CPU_MAP \
+ cpu-map { \
+ CLUSTER(0) \
+ CLUSTER(1) \
+ CLUSTER(2) \
+ CLUSTER(3) \
+ };
+#endif /* CLUSTER_COUNT */
+
+#endif /* FVP_DEFS_DTSI */
diff --git a/fdts/fvp-foundation-gicv2-psci.dts b/fdts/fvp-foundation-gicv2-psci.dts
index 3a204cb..95a800e 100644
--- a/fdts/fvp-foundation-gicv2-psci.dts
+++ b/fdts/fvp-foundation-gicv2-psci.dts
@@ -4,8 +4,15 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/* Configuration: 1 cluster with up to 4 CPUs */
+
/dts-v1/;
+#define AFF
+#define CLUSTER_COUNT 1
+
+#include "fvp-defs.dtsi"
+
/memreserve/ 0x80000000 0x00010000;
/ {
@@ -42,22 +49,7 @@
#address-cells = <2>;
#size-cells = <0>;
- cpu-map {
- cluster0 {
- core0 {
- cpu = <&CPU0>;
- };
- core1 {
- cpu = <&CPU1>;
- };
- core2 {
- cpu = <&CPU2>;
- };
- core3 {
- cpu = <&CPU3>;
- };
- };
- };
+ CPU_MAP
idle-states {
entry-method = "arm,psci";
@@ -81,41 +73,7 @@
};
};
- 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>;
- };
+ CPUS
L2_0: l2-cache0 {
compatible = "cache";
diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts
index d85305a..c295dc1 100644
--- a/fdts/fvp-foundation-gicv3-psci.dts
+++ b/fdts/fvp-foundation-gicv3-psci.dts
@@ -4,8 +4,15 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+/* Configuration: 1 cluster with up to 4 CPUs */
+
/dts-v1/;
+#define AFF
+#define CLUSTER_COUNT 1
+
+#include "fvp-defs.dtsi"
+
/memreserve/ 0x80000000 0x00010000;
/ {
@@ -42,22 +49,7 @@
#address-cells = <2>;
#size-cells = <0>;
- cpu-map {
- cluster0 {
- core0 {
- cpu = <&CPU0>;
- };
- core1 {
- cpu = <&CPU1>;
- };
- core2 {
- cpu = <&CPU2>;
- };
- core3 {
- cpu = <&CPU3>;
- };
- };
- };
+ CPU_MAP
idle-states {
entry-method = "arm,psci";
@@ -81,41 +73,7 @@
};
};
- 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>;
- };
+ CPUS
L2_0: l2-cache0 {
compatible = "cache";
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 81e0f27..92e6737 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -226,6 +226,12 @@
#define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED ULL(0x1)
#define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED ULL(0x0)
+/* ID_AA64MMFR1_EL1 definitions */
+#define ID_AA64MMFR1_EL1_TWED_SHIFT U(32)
+#define ID_AA64MMFR1_EL1_TWED_MASK ULL(0xf)
+#define ID_AA64MMFR1_EL1_TWED_SUPPORTED ULL(0x1)
+#define ID_AA64MMFR1_EL1_TWED_NOT_SUPPORTED ULL(0x0)
+
/* ID_AA64MMFR2_EL1 definitions */
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
@@ -312,6 +318,9 @@
/* SCR definitions */
#define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5))
+#define SCR_TWEDEL_SHIFT U(30)
+#define SCR_TWEDEL_MASK ULL(0xf)
+#define SCR_TWEDEn_BIT (UL(1) << 29)
#define SCR_ATA_BIT (U(1) << 26)
#define SCR_FIEN_BIT (U(1) << 21)
#define SCR_EEL2_BIT (U(1) << 18)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 9513e97..49d827d 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -58,4 +58,10 @@
ID_AA64PFR0_SEL2_MASK) == 1ULL;
}
+static inline bool is_armv8_6_twed_present(void)
+{
+ return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_TWED_SHIFT) &
+ ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED);
+}
+
#endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 9cd1ae5..09059ca 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -358,6 +358,7 @@
DEFINE_SYSREG_READ_FUNC(midr_el1)
DEFINE_SYSREG_READ_FUNC(mpidr_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1)
+DEFINE_SYSREG_READ_FUNC(id_aa64mmfr1_el1)
DEFINE_SYSREG_RW_FUNCS(scr_el3)
DEFINE_SYSREG_RW_FUNCS(hcr_el2)
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 156b18a..0708de6 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <arch.h>
#include <asm_macros.S>
+#include <lib/xlat_tables/xlat_tables_defs.h>
/*
* Helper macro to initialise EL3 registers we care about.
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index 382651e..1d8da18 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -34,4 +34,7 @@
uintptr_t *base, size_t *size);
int fdt_get_stdout_node_offset(const void *dtb);
+uint64_t fdtw_translate_address(const void *dtb, int bus_node,
+ uint64_t base_address);
+
#endif /* FDT_WRAPPERS_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 0029658..90807ce 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -168,76 +168,75 @@
#define CTX_ELR_EL2 U(0x58)
#define CTX_ESR_EL2 U(0x60)
#define CTX_FAR_EL2 U(0x68)
-#define CTX_FPEXC32_EL2 U(0x70)
-#define CTX_HACR_EL2 U(0x78)
-#define CTX_HCR_EL2 U(0x80)
-#define CTX_HPFAR_EL2 U(0x88)
-#define CTX_HSTR_EL2 U(0x90)
-#define CTX_ICC_SRE_EL2 U(0x98)
-#define CTX_ICH_HCR_EL2 U(0xa0)
-#define CTX_ICH_VMCR_EL2 U(0xa8)
-#define CTX_MAIR_EL2 U(0xb0)
-#define CTX_MDCR_EL2 U(0xb8)
-#define CTX_PMSCR_EL2 U(0xc0)
-#define CTX_SCTLR_EL2 U(0xc8)
-#define CTX_SPSR_EL2 U(0xd0)
-#define CTX_SP_EL2 U(0xd8)
-#define CTX_TCR_EL2 U(0xe0)
-#define CTX_TPIDR_EL2 U(0xe8)
-#define CTX_TTBR0_EL2 U(0xf0)
-#define CTX_VBAR_EL2 U(0xf8)
-#define CTX_VMPIDR_EL2 U(0x100)
-#define CTX_VPIDR_EL2 U(0x108)
-#define CTX_VTCR_EL2 U(0x110)
-#define CTX_VTTBR_EL2 U(0x118)
+#define CTX_HACR_EL2 U(0x70)
+#define CTX_HCR_EL2 U(0x78)
+#define CTX_HPFAR_EL2 U(0x80)
+#define CTX_HSTR_EL2 U(0x88)
+#define CTX_ICC_SRE_EL2 U(0x90)
+#define CTX_ICH_HCR_EL2 U(0x98)
+#define CTX_ICH_VMCR_EL2 U(0xa0)
+#define CTX_MAIR_EL2 U(0xa8)
+#define CTX_MDCR_EL2 U(0xb0)
+#define CTX_PMSCR_EL2 U(0xb8)
+#define CTX_SCTLR_EL2 U(0xc0)
+#define CTX_SPSR_EL2 U(0xc8)
+#define CTX_SP_EL2 U(0xd0)
+#define CTX_TCR_EL2 U(0xd8)
+#define CTX_TPIDR_EL2 U(0xe0)
+#define CTX_TTBR0_EL2 U(0xe8)
+#define CTX_VBAR_EL2 U(0xf0)
+#define CTX_VMPIDR_EL2 U(0xf8)
+#define CTX_VPIDR_EL2 U(0x100)
+#define CTX_VTCR_EL2 U(0x108)
+#define CTX_VTTBR_EL2 U(0x110)
// Only if MTE registers in use
-#define CTX_TFSR_EL2 U(0x120)
+#define CTX_TFSR_EL2 U(0x118)
// Only if ENABLE_MPAM_FOR_LOWER_ELS==1
-#define CTX_MPAM2_EL2 U(0x128)
-#define CTX_MPAMHCR_EL2 U(0x130)
-#define CTX_MPAMVPM0_EL2 U(0x138)
-#define CTX_MPAMVPM1_EL2 U(0x140)
-#define CTX_MPAMVPM2_EL2 U(0x148)
-#define CTX_MPAMVPM3_EL2 U(0x150)
-#define CTX_MPAMVPM4_EL2 U(0x158)
-#define CTX_MPAMVPM5_EL2 U(0x160)
-#define CTX_MPAMVPM6_EL2 U(0x168)
-#define CTX_MPAMVPM7_EL2 U(0x170)
-#define CTX_MPAMVPMV_EL2 U(0x178)
+#define CTX_MPAM2_EL2 U(0x120)
+#define CTX_MPAMHCR_EL2 U(0x128)
+#define CTX_MPAMVPM0_EL2 U(0x130)
+#define CTX_MPAMVPM1_EL2 U(0x138)
+#define CTX_MPAMVPM2_EL2 U(0x140)
+#define CTX_MPAMVPM3_EL2 U(0x148)
+#define CTX_MPAMVPM4_EL2 U(0x150)
+#define CTX_MPAMVPM5_EL2 U(0x158)
+#define CTX_MPAMVPM6_EL2 U(0x160)
+#define CTX_MPAMVPM7_EL2 U(0x168)
+#define CTX_MPAMVPMV_EL2 U(0x170)
// Starting with Armv8.6
-#define CTX_HAFGRTR_EL2 U(0x180)
-#define CTX_HDFGRTR_EL2 U(0x188)
-#define CTX_HDFGWTR_EL2 U(0x190)
-#define CTX_HFGITR_EL2 U(0x198)
-#define CTX_HFGRTR_EL2 U(0x1a0)
-#define CTX_HFGWTR_EL2 U(0x1a8)
-#define CTX_CNTPOFF_EL2 U(0x1b0)
+#define CTX_HAFGRTR_EL2 U(0x178)
+#define CTX_HDFGRTR_EL2 U(0x180)
+#define CTX_HDFGWTR_EL2 U(0x188)
+#define CTX_HFGITR_EL2 U(0x190)
+#define CTX_HFGRTR_EL2 U(0x198)
+#define CTX_HFGWTR_EL2 U(0x1a0)
+#define CTX_CNTPOFF_EL2 U(0x1a8)
// Starting with Armv8.4
-#define CTX_CNTHPS_CTL_EL2 U(0x1b8)
-#define CTX_CNTHPS_CVAL_EL2 U(0x1c0)
-#define CTX_CNTHPS_TVAL_EL2 U(0x1c8)
-#define CTX_CNTHVS_CTL_EL2 U(0x1d0)
-#define CTX_CNTHVS_CVAL_EL2 U(0x1d8)
-#define CTX_CNTHVS_TVAL_EL2 U(0x1e0)
-#define CTX_CNTHV_CTL_EL2 U(0x1e8)
-#define CTX_CNTHV_CVAL_EL2 U(0x1f0)
-#define CTX_CNTHV_TVAL_EL2 U(0x1f8)
-#define CTX_CONTEXTIDR_EL2 U(0x200)
-#define CTX_SDER32_EL2 U(0x208)
-#define CTX_TTBR1_EL2 U(0x210)
-#define CTX_VDISR_EL2 U(0x218)
-#define CTX_VNCR_EL2 U(0x220)
-#define CTX_VSESR_EL2 U(0x228)
-#define CTX_VSTCR_EL2 U(0x230)
-#define CTX_VSTTBR_EL2 U(0x238)
-#define CTX_TRFCR_EL2 U(0x240)
+#define CTX_CNTHPS_CTL_EL2 U(0x1b0)
+#define CTX_CNTHPS_CVAL_EL2 U(0x1b8)
+#define CTX_CNTHPS_TVAL_EL2 U(0x1c0)
+#define CTX_CNTHVS_CTL_EL2 U(0x1c8)
+#define CTX_CNTHVS_CVAL_EL2 U(0x1d0)
+#define CTX_CNTHVS_TVAL_EL2 U(0x1d8)
+#define CTX_CNTHV_CTL_EL2 U(0x1e0)
+#define CTX_CNTHV_CVAL_EL2 U(0x1e8)
+#define CTX_CNTHV_TVAL_EL2 U(0x1f0)
+#define CTX_CONTEXTIDR_EL2 U(0x1f8)
+#define CTX_SDER32_EL2 U(0x200)
+#define CTX_TTBR1_EL2 U(0x208)
+#define CTX_VDISR_EL2 U(0x210)
+#define CTX_VNCR_EL2 U(0x218)
+#define CTX_VSESR_EL2 U(0x220)
+#define CTX_VSTCR_EL2 U(0x228)
+#define CTX_VSTTBR_EL2 U(0x230)
+#define CTX_TRFCR_EL2 U(0x238)
// Starting with Armv8.5
-#define CTX_SCXTNUM_EL2 U(0x248)
+#define CTX_SCXTNUM_EL2 U(0x240)
/* Align to the next 16 byte boundary */
#define CTX_EL2_SYSREGS_END U(0x250)
diff --git a/include/lib/extensions/twed.h b/include/lib/extensions/twed.h
new file mode 100644
index 0000000..eac4aa3
--- /dev/null
+++ b/include/lib/extensions/twed.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TWED_H
+#define TWED_H
+
+#include <stdint.h>
+
+#define TWED_DISABLED U(0xFFFFFFFF)
+
+uint32_t plat_arm_set_twedel_scr_el3(void);
+
+#endif /* TWEDE_H */
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
new file mode 100644
index 0000000..fe32175
--- /dev/null
+++ b/include/services/ffa_svc.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FFA_SVC_H
+#define FFA_SVC_H
+
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+#include <tools_share/uuid.h>
+
+/* FFA error codes. */
+#define FFA_ERROR_NOT_SUPPORTED -1
+#define FFA_ERROR_INVALID_PARAMETER -2
+#define FFA_ERROR_NO_MEMORY -3
+#define FFA_ERROR_BUSY -4
+#define FFA_ERROR_INTERRUPTED -5
+#define FFA_ERROR_DENIED -6
+#define FFA_ERROR_RETRY -7
+
+/* The macros below are used to identify FFA calls from the SMC function ID */
+#define FFA_FNUM_MIN_VALUE U(0x60)
+#define FFA_FNUM_MAX_VALUE U(0x7f)
+#define is_ffa_fid(fid) __extension__ ({ \
+ __typeof__(fid) _fid = (fid); \
+ ((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) && \
+ (GET_SMC_NUM(_fid) <= FFA_FNUM_MAX_VALUE)); })
+
+/* FFA_VERSION helpers */
+#define FFA_VERSION_MAJOR U(1)
+#define FFA_VERSION_MAJOR_SHIFT 16
+#define FFA_VERSION_MAJOR_MASK U(0x7FFF)
+#define FFA_VERSION_MINOR U(0)
+#define FFA_VERSION_MINOR_SHIFT 0
+#define FFA_VERSION_MINOR_MASK U(0xFFFF)
+
+#define MAKE_FFA_VERSION(major, minor) \
+ ((((major) & FFA_VERSION_MAJOR_MASK) << FFA_VERSION_MAJOR_SHIFT) | \
+ (((minor) & FFA_VERSION_MINOR_MASK) << FFA_VERSION_MINOR_SHIFT))
+#define FFA_VERSION_COMPILED MAKE_FFA_VERSION(FFA_VERSION_MAJOR, \
+ FFA_VERSION_MINOR)
+
+/* FFA_MSG_SEND helpers */
+#define FFA_MSG_SEND_ATTRS_BLK_SHIFT U(0)
+#define FFA_MSG_SEND_ATTRS_BLK_MASK U(0x1)
+#define FFA_MSG_SEND_ATTRS_BLK U(0)
+#define FFA_MSG_SEND_ATTRS_BLK_NOT U(1)
+#define FFA_MSG_SEND_ATTRS(blk) \
+ (((blk) & FFA_MSG_SEND_ATTRS_BLK_MASK) \
+ << FFA_MSG_SEND_ATTRS_BLK_SHIFT)
+
+/* Get FFA fastcall std FID from function number */
+#define FFA_FID(smc_cc, func_num) \
+ ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+ ((smc_cc) << FUNCID_CC_SHIFT) | \
+ (OEN_STD_START << FUNCID_OEN_SHIFT) | \
+ ((func_num) << FUNCID_NUM_SHIFT))
+
+/* FFA function numbers */
+#define FFA_FNUM_ERROR U(0x60)
+#define FFA_FNUM_SUCCESS U(0x61)
+#define FFA_FNUM_INTERRUPT U(0x62)
+#define FFA_FNUM_VERSION U(0x63)
+#define FFA_FNUM_FEATURES U(0x64)
+#define FFA_FNUM_RX_RELEASE U(0x65)
+#define FFA_FNUM_RXTX_MAP U(0x66)
+#define FFA_FNUM_RXTX_UNMAP U(0x67)
+#define FFA_FNUM_PARTITION_INFO_GET U(0x68)
+#define FFA_FNUM_ID_GET U(0x69)
+#define FFA_FNUM_MSG_POLL U(0x6A)
+#define FFA_FNUM_MSG_WAIT U(0x6B)
+#define FFA_FNUM_MSG_YIELD U(0x6C)
+#define FFA_FNUM_MSG_RUN U(0x6D)
+#define FFA_FNUM_MSG_SEND U(0x6E)
+#define FFA_FNUM_MSG_SEND_DIRECT_REQ U(0x6F)
+#define FFA_FNUM_MSG_SEND_DIRECT_RESP U(0x70)
+#define FFA_FNUM_MEM_DONATE U(0x71)
+#define FFA_FNUM_MEM_LEND U(0x72)
+#define FFA_FNUM_MEM_SHARE U(0x73)
+#define FFA_FNUM_MEM_RETRIEVE_REQ U(0x74)
+#define FFA_FNUM_MEM_RETRIEVE_RESP U(0x75)
+#define FFA_FNUM_MEM_RELINQUISH U(0x76)
+#define FFA_FNUM_MEM_RECLAIM U(0x77)
+
+/* FFA SMC32 FIDs */
+#define FFA_ERROR FFA_FID(SMC_32, FFA_FNUM_ERROR)
+#define FFA_SUCCESS_SMC32 FFA_FID(SMC_32, FFA_FNUM_SUCCESS)
+#define FFA_INTERRUPT FFA_FID(SMC_32, FFA_FNUM_INTERRUPT)
+#define FFA_VERSION FFA_FID(SMC_32, FFA_FNUM_VERSION)
+#define FFA_FEATURES FFA_FID(SMC_32, FFA_FNUM_FEATURES)
+#define FFA_RX_RELEASE FFA_FID(SMC_32, FFA_FNUM_RX_RELEASE)
+#define FFA_RXTX_MAP_SMC32 FFA_FID(SMC_32, FFA_FNUM_RXTX_MAP)
+#define FFA_RXTX_UNMAP FFA_FID(SMC_32, FFA_FNUM_RXTX_UNMAP)
+#define FFA_PARTITION_INFO_GET FFA_FID(SMC_32, FFA_FNUM_PARTITION_INFO_GET)
+#define FFA_ID_GET FFA_FID(SMC_32, FFA_FNUM_ID_GET)
+#define FFA_MSG_POLL FFA_FID(SMC_32, FFA_FNUM_MSG_POLL)
+#define FFA_MSG_WAIT FFA_FID(SMC_32, FFA_FNUM_MSG_WAIT)
+#define FFA_MSG_YIELD FFA_FID(SMC_32, FFA_FNUM_MSG_YIELD)
+#define FFA_MSG_RUN FFA_FID(SMC_32, FFA_FNUM_MSG_RUN)
+#define FFA_MSG_SEND FFA_FID(SMC_32, FFA_FNUM_MSG_SEND)
+#define FFA_MSG_SEND_DIRECT_REQ_SMC32 \
+ FFA_FID(SMC_32, FFA_FNUM_MSG_SEND_DIRECT_REQ)
+#define FFA_MSG_SEND_DIRECT_RESP_SMC32 \
+ FFA_FID(SMC_32, FFA_FNUM_MSG_SEND_DIRECT_RESP)
+#define FFA_MEM_DONATE_SMC32 FFA_FID(SMC_32, FFA_FNUM_MEM_DONATE)
+#define FFA_MEM_LEND_SMC32 FFA_FID(SMC_32, FFA_FNUM_MEM_LEND)
+#define FFA_MEM_SHARE_SMC32 FFA_FID(SMC_32, FFA_FNUM_MEM_SHARE)
+#define FFA_MEM_RETRIEVE_REQ_SMC32 \
+ FFA_FID(SMC_32, FFA_FNUM_MEM_RETRIEVE_REQ)
+#define FFA_MEM_RETRIEVE_RESP FFA_FID(SMC_32, FFA_FNUM_MEM_RETRIEVE_RESP)
+#define FFA_MEM_RELINQUISH FFA_FID(SMC_32, FFA_FNUM_MEM_RELINQUISH)
+#define FFA_MEM_RECLAIM FFA_FID(SMC_32, FFA_FNUM_MEM_RECLAIM)
+
+/* FFA SMC64 FIDs */
+#define FFA_SUCCESS_SMC64 FFA_FID(SMC_64, FFA_FNUM_SUCCESS)
+#define FFA_RXTX_MAP_SMC64 FFA_FID(SMC_64, FFA_FNUM_RXTX_MAP)
+#define FFA_MSG_SEND_DIRECT_REQ_SMC64 \
+ FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_REQ)
+#define FFA_MSG_SEND_DIRECT_RESP_SMC64 \
+ FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_RESP)
+#define FFA_MEM_DONATE_SMC64 FFA_FID(SMC_64, FFA_FNUM_MEM_DONATE)
+#define FFA_MEM_LEND_SMC64 FFA_FID(SMC_64, FFA_FNUM_MEM_LEND)
+#define FFA_MEM_SHARE_SMC64 FFA_FID(SMC_64, FFA_FNUM_MEM_SHARE)
+#define FFA_MEM_RETRIEVE_REQ_SMC64 \
+ FFA_FID(SMC_64, FFA_FNUM_MEM_RETRIEVE_REQ)
+
+/*
+ * Reserve a special value for traffic targeted to the Hypervisor or SPM.
+ */
+#define FFA_TARGET_INFO_MBZ U(0x0)
+
+/*
+ * Reserve a special value for MBZ parameters.
+ */
+#define FFA_PARAM_MBZ U(0x0)
+
+#endif /* FFA_SVC_H */
diff --git a/include/services/spci_svc.h b/include/services/spci_svc.h
deleted file mode 100644
index 49ba408..0000000
--- a/include/services/spci_svc.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPCI_SVC_H
-#define SPCI_SVC_H
-
-#include <lib/smccc.h>
-#include <lib/utils_def.h>
-#include <tools_share/uuid.h>
-
-/* SPCI error codes. */
-#define SPCI_ERROR_NOT_SUPPORTED -1
-#define SPCI_ERROR_INVALID_PARAMETER -2
-#define SPCI_ERROR_NO_MEMORY -3
-#define SPCI_ERROR_BUSY -4
-#define SPCI_ERROR_INTERRUPTED -5
-#define SPCI_ERROR_DENIED -6
-#define SPCI_ERROR_RETRY -7
-
-/* The macros below are used to identify SPCI calls from the SMC function ID */
-#define SPCI_FNUM_MIN_VALUE U(0x60)
-#define SPCI_FNUM_MAX_VALUE U(0x7f)
-#define is_spci_fid(fid) __extension__ ({ \
- __typeof__(fid) _fid = (fid); \
- ((GET_SMC_NUM(_fid) >= SPCI_FNUM_MIN_VALUE) && \
- (GET_SMC_NUM(_fid) <= SPCI_FNUM_MAX_VALUE)); })
-
-/* SPCI_VERSION helpers */
-#define SPCI_VERSION_MAJOR U(0)
-#define SPCI_VERSION_MAJOR_SHIFT 16
-#define SPCI_VERSION_MAJOR_MASK U(0x7FFF)
-#define SPCI_VERSION_MINOR U(9)
-#define SPCI_VERSION_MINOR_SHIFT 0
-#define SPCI_VERSION_MINOR_MASK U(0xFFFF)
-
-#define MAKE_SPCI_VERSION(major, minor) \
- ((((major) & SPCI_VERSION_MAJOR_MASK) << SPCI_VERSION_MAJOR_SHIFT) | \
- (((minor) & SPCI_VERSION_MINOR_MASK) << SPCI_VERSION_MINOR_SHIFT))
-#define SPCI_VERSION_COMPILED MAKE_SPCI_VERSION(SPCI_VERSION_MAJOR, \
- SPCI_VERSION_MINOR)
-
-/* SPCI_MSG_SEND helpers */
-#define SPCI_MSG_SEND_ATTRS_BLK_SHIFT U(0)
-#define SPCI_MSG_SEND_ATTRS_BLK_MASK U(0x1)
-#define SPCI_MSG_SEND_ATTRS_BLK U(0)
-#define SPCI_MSG_SEND_ATTRS_BLK_NOT U(1)
-#define SPCI_MSG_SEND_ATTRS(blk) \
- (((blk) & SPCI_MSG_SEND_ATTRS_BLK_MASK) \
- << SPCI_MSG_SEND_ATTRS_BLK_SHIFT)
-
-/* Get SPCI fastcall std FID from function number */
-#define SPCI_FID(smc_cc, func_num) \
- ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
- ((smc_cc) << FUNCID_CC_SHIFT) | \
- (OEN_STD_START << FUNCID_OEN_SHIFT) | \
- ((func_num) << FUNCID_NUM_SHIFT))
-
-/* SPCI function numbers */
-#define SPCI_FNUM_ERROR U(0x60)
-#define SPCI_FNUM_SUCCESS U(0x61)
-#define SPCI_FNUM_INTERRUPT U(0x62)
-#define SPCI_FNUM_VERSION U(0x63)
-#define SPCI_FNUM_FEATURES U(0x64)
-#define SPCI_FNUM_RX_RELEASE U(0x65)
-#define SPCI_FNUM_RXTX_MAP U(0x66)
-#define SPCI_FNUM_RXTX_UNMAP U(0x67)
-#define SPCI_FNUM_PARTITION_INFO_GET U(0x68)
-#define SPCI_FNUM_ID_GET U(0x69)
-#define SPCI_FNUM_MSG_POLL U(0x6A)
-#define SPCI_FNUM_MSG_WAIT U(0x6B)
-#define SPCI_FNUM_MSG_YIELD U(0x6C)
-#define SPCI_FNUM_MSG_RUN U(0x6D)
-#define SPCI_FNUM_MSG_SEND U(0x6E)
-#define SPCI_FNUM_MSG_SEND_DIRECT_REQ U(0x6F)
-#define SPCI_FNUM_MSG_SEND_DIRECT_RESP U(0x70)
-#define SPCI_FNUM_MEM_DONATE U(0x71)
-#define SPCI_FNUM_MEM_LEND U(0x72)
-#define SPCI_FNUM_MEM_SHARE U(0x73)
-#define SPCI_FNUM_MEM_RETRIEVE_REQ U(0x74)
-#define SPCI_FNUM_MEM_RETRIEVE_RESP U(0x75)
-#define SPCI_FNUM_MEM_RELINQUISH U(0x76)
-#define SPCI_FNUM_MEM_RECLAIM U(0x77)
-
-/* SPCI SMC32 FIDs */
-#define SPCI_ERROR SPCI_FID(SMC_32, SPCI_FNUM_ERROR)
-#define SPCI_SUCCESS_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_SUCCESS)
-#define SPCI_INTERRUPT SPCI_FID(SMC_32, SPCI_FNUM_INTERRUPT)
-#define SPCI_VERSION SPCI_FID(SMC_32, SPCI_FNUM_VERSION)
-#define SPCI_FEATURES SPCI_FID(SMC_32, SPCI_FNUM_FEATURES)
-#define SPCI_RX_RELEASE SPCI_FID(SMC_32, SPCI_FNUM_RX_RELEASE)
-#define SPCI_RXTX_MAP_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_RXTX_MAP)
-#define SPCI_RXTX_UNMAP SPCI_FID(SMC_32, SPCI_FNUM_RXTX_UNMAP)
-#define SPCI_PARTITION_INFO_GET SPCI_FID(SMC_32, SPCI_FNUM_PARTITION_INFO_GET)
-#define SPCI_ID_GET SPCI_FID(SMC_32, SPCI_FNUM_ID_GET)
-#define SPCI_MSG_POLL SPCI_FID(SMC_32, SPCI_FNUM_MSG_POLL)
-#define SPCI_MSG_WAIT SPCI_FID(SMC_32, SPCI_FNUM_MSG_WAIT)
-#define SPCI_MSG_YIELD SPCI_FID(SMC_32, SPCI_FNUM_MSG_YIELD)
-#define SPCI_MSG_RUN SPCI_FID(SMC_32, SPCI_FNUM_MSG_RUN)
-#define SPCI_MSG_SEND SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND)
-#define SPCI_MSG_SEND_DIRECT_REQ_SMC32 \
- SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_REQ)
-#define SPCI_MSG_SEND_DIRECT_RESP_SMC32 \
- SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_RESP)
-#define SPCI_MEM_DONATE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_DONATE)
-#define SPCI_MEM_LEND_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_LEND)
-#define SPCI_MEM_SHARE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_SHARE)
-#define SPCI_MEM_RETRIEVE_REQ_SMC32 \
- SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_REQ)
-#define SPCI_MEM_RETRIEVE_RESP SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_RESP)
-#define SPCI_MEM_RELINQUISH SPCI_FID(SMC_32, SPCI_FNUM_MEM_RELINQUISH)
-#define SPCI_MEM_RECLAIM SPCI_FID(SMC_32, SPCI_FNUM_MEM_RECLAIM)
-
-/* SPCI SMC64 FIDs */
-#define SPCI_SUCCESS_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_SUCCESS)
-#define SPCI_RXTX_MAP_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_RXTX_MAP)
-#define SPCI_MSG_SEND_DIRECT_REQ_SMC64 \
- SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_REQ)
-#define SPCI_MSG_SEND_DIRECT_RESP_SMC64 \
- SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_RESP)
-#define SPCI_MEM_DONATE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_DONATE)
-#define SPCI_MEM_LEND_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_LEND)
-#define SPCI_MEM_SHARE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_SHARE)
-#define SPCI_MEM_RETRIEVE_REQ_SMC64 \
- SPCI_FID(SMC_64, SPCI_FNUM_MEM_RETRIEVE_REQ)
-
-/*
- * Reserve a special value for traffic targeted to the Hypervisor or SPM.
- */
-#define SPCI_TARGET_INFO_MBZ U(0x0)
-
-/*
- * Reserve a special value for MBZ parameters.
- */
-#define SPCI_PARAM_MBZ U(0x0)
-
-#endif /* SPCI_SVC_H */
diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h
index 0c43636..64ecce0 100644
--- a/include/services/spm_core_manifest.h
+++ b/include/services/spm_core_manifest.h
@@ -15,7 +15,7 @@
typedef struct spm_core_manifest_sect_attribute {
/*
- * SPCI version (mandatory).
+ * FFA version (mandatory).
*/
uint32_t major_version;
uint32_t minor_version;
diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h
index a766dcf..1e7e6aa 100644
--- a/include/services/spmd_svc.h
+++ b/include/services/spmd_svc.h
@@ -8,7 +8,7 @@
#define SPMD_SVC_H
#ifndef __ASSEMBLER__
-#include <services/spci_svc.h>
+#include <services/ffa_svc.h>
#include <stdint.h>
int spmd_setup(void);
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 984468a..1568ef0 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -71,53 +71,52 @@
mrs x15, far_el2
stp x14, x15, [x0, #CTX_ESR_EL2]
- mrs x16, fpexc32_el2
- mrs x17, hacr_el2
- stp x16, x17, [x0, #CTX_FPEXC32_EL2]
+ mrs x16, hacr_el2
+ mrs x17, hcr_el2
+ stp x16, x17, [x0, #CTX_HACR_EL2]
- mrs x9, hcr_el2
- mrs x10, hpfar_el2
- stp x9, x10, [x0, #CTX_HCR_EL2]
+ mrs x9, hpfar_el2
+ mrs x10, hstr_el2
+ stp x9, x10, [x0, #CTX_HPFAR_EL2]
- mrs x11, hstr_el2
- mrs x12, ICC_SRE_EL2
- stp x11, x12, [x0, #CTX_HSTR_EL2]
+ mrs x11, ICC_SRE_EL2
+ mrs x12, ICH_HCR_EL2
+ stp x11, x12, [x0, #CTX_ICC_SRE_EL2]
- mrs x13, ICH_HCR_EL2
- mrs x14, ICH_VMCR_EL2
- stp x13, x14, [x0, #CTX_ICH_HCR_EL2]
+ mrs x13, ICH_VMCR_EL2
+ mrs x14, mair_el2
+ stp x13, x14, [x0, #CTX_ICH_VMCR_EL2]
- mrs x15, mair_el2
- mrs x16, mdcr_el2
- stp x15, x16, [x0, #CTX_MAIR_EL2]
+ mrs x15, mdcr_el2
+ mrs x16, PMSCR_EL2
+ stp x15, x16, [x0, #CTX_MDCR_EL2]
- mrs x17, PMSCR_EL2
- mrs x9, sctlr_el2
- stp x17, x9, [x0, #CTX_PMSCR_EL2]
+ mrs x17, sctlr_el2
+ mrs x9, spsr_el2
+ stp x17, x9, [x0, #CTX_SCTLR_EL2]
- mrs x10, spsr_el2
- mrs x11, sp_el2
- stp x10, x11, [x0, #CTX_SPSR_EL2]
+ mrs x10, sp_el2
+ mrs x11, tcr_el2
+ stp x10, x11, [x0, #CTX_SP_EL2]
- mrs x12, tcr_el2
- mrs x13, tpidr_el2
- stp x12, x13, [x0, #CTX_TCR_EL2]
+ mrs x12, tpidr_el2
+ mrs x13, ttbr0_el2
+ stp x12, x13, [x0, #CTX_TPIDR_EL2]
- mrs x14, ttbr0_el2
- mrs x15, vbar_el2
- stp x14, x15, [x0, #CTX_TTBR0_EL2]
+ mrs x14, vbar_el2
+ mrs x15, vmpidr_el2
+ stp x14, x15, [x0, #CTX_VBAR_EL2]
- mrs x16, vmpidr_el2
- mrs x17, vpidr_el2
- stp x16, x17, [x0, #CTX_VMPIDR_EL2]
+ mrs x16, vpidr_el2
+ mrs x17, vtcr_el2
+ stp x16, x17, [x0, #CTX_VPIDR_EL2]
- mrs x9, vtcr_el2
- mrs x10, vttbr_el2
- stp x9, x10, [x0, #CTX_VTCR_EL2]
+ mrs x9, vttbr_el2
+ str x9, [x0, #CTX_VTTBR_EL2]
#if CTX_INCLUDE_MTE_REGS
- mrs x11, TFSR_EL2
- str x11, [x0, #CTX_TFSR_EL2]
+ mrs x10, TFSR_EL2
+ str x10, [x0, #CTX_TFSR_EL2]
#endif
#if ENABLE_MPAM_FOR_LOWER_ELS
@@ -277,51 +276,48 @@
msr esr_el2, x14
msr far_el2, x15
- ldp x16, x17, [x0, #CTX_FPEXC32_EL2]
- msr fpexc32_el2, x16
- msr hacr_el2, x17
+ ldp x16, x17, [x0, #CTX_HACR_EL2]
+ msr hacr_el2, x16
+ msr hcr_el2, x17
- ldp x9, x10, [x0, #CTX_HCR_EL2]
- msr hcr_el2, x9
- msr hpfar_el2, x10
+ ldp x9, x10, [x0, #CTX_HPFAR_EL2]
+ msr hpfar_el2, x9
+ msr hstr_el2, x10
- ldp x11, x12, [x0, #CTX_HSTR_EL2]
- msr hstr_el2, x11
- msr ICC_SRE_EL2, x12
+ ldp x11, x12, [x0, #CTX_ICC_SRE_EL2]
+ msr ICC_SRE_EL2, x11
+ msr ICH_HCR_EL2, x12
- ldp x13, x14, [x0, #CTX_ICH_HCR_EL2]
- msr ICH_HCR_EL2, x13
- msr ICH_VMCR_EL2, x14
+ ldp x13, x14, [x0, #CTX_ICH_VMCR_EL2]
+ msr ICH_VMCR_EL2, x13
+ msr mair_el2, x14
- ldp x15, x16, [x0, #CTX_MAIR_EL2]
- msr mair_el2, x15
- msr mdcr_el2, x16
+ ldp x15, x16, [x0, #CTX_MDCR_EL2]
+ msr mdcr_el2, x15
+ msr PMSCR_EL2, x16
- ldr x17, [x0, #CTX_PMSCR_EL2]
- msr PMSCR_EL2, x17
+ ldp x17, x9, [x0, #CTX_SPSR_EL2]
+ msr spsr_el2, x17
+ msr sp_el2, x9
- ldp x10, x11, [x0, #CTX_SPSR_EL2]
- msr spsr_el2, x10
- msr sp_el2, x11
+ ldp x10, x11, [x0, #CTX_TPIDR_EL2]
+ msr tpidr_el2, x10
+ msr ttbr0_el2, x11
- ldr x12, [x0, #CTX_TPIDR_EL2]
- msr tpidr_el2, x12
+ ldp x12, x13, [x0, #CTX_VBAR_EL2]
+ msr vbar_el2, x12
+ msr vmpidr_el2, x13
- ldp x14, x15, [x0, #CTX_TTBR0_EL2]
- msr ttbr0_el2, x14
- msr vbar_el2, x15
+ ldp x14, x15, [x0, #CTX_VPIDR_EL2]
+ msr vpidr_el2, x14
+ msr vtcr_el2, x15
- ldp x16, x17, [x0, #CTX_VMPIDR_EL2]
- msr vmpidr_el2, x16
- msr vpidr_el2, x17
-
- ldp x9, x10, [x0, #CTX_VTCR_EL2]
- msr vtcr_el2, x9
- msr vttbr_el2, x10
+ ldr x16, [x0, #CTX_VTTBR_EL2]
+ msr vttbr_el2, x16
#if CTX_INCLUDE_MTE_REGS
- ldr x11, [x0, #CTX_TFSR_EL2]
- msr TFSR_EL2, x11
+ ldr x17, [x0, #CTX_TFSR_EL2]
+ msr TFSR_EL2, x17
#endif
#if ENABLE_MPAM_FOR_LOWER_ELS
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 0314a85..64a2d7b 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -22,6 +22,7 @@
#include <lib/extensions/mpam.h>
#include <lib/extensions/spe.h>
#include <lib/extensions/sve.h>
+#include <lib/extensions/twed.h>
#include <lib/utils.h>
@@ -229,6 +230,24 @@
sctlr_elx |= SCTLR_IESB_BIT;
#endif
+ /* Enable WFE trap delay in SCR_EL3 if supported and configured */
+ if (is_armv8_6_twed_present()) {
+ uint32_t delay = plat_arm_set_twedel_scr_el3();
+
+ if (delay != TWED_DISABLED) {
+ /* Make sure delay value fits */
+ assert((delay & ~SCR_TWEDEL_MASK) == 0U);
+
+ /* Set delay in SCR_EL3 */
+ scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
+ scr_el3 |= ((delay & SCR_TWEDEL_MASK)
+ << SCR_TWEDEL_SHIFT);
+
+ /* Enable WFE delay */
+ scr_el3 |= SCR_TWEDEn_BIT;
+ }
+ }
+
/*
* Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
* and other EL2 registers are set up by cm_prepare_ns_entry() as they
diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
index f1d9b93..8172a6e 100644
--- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -13,6 +13,9 @@
struct gicv3_config_t gicv3_config;
struct hw_topology_t soc_topology;
+struct uart_serial_config_t uart_serial_config;
+
+#define ILLEGAL_ADDR ULL(~0)
int fconf_populate_gicv3_config(uintptr_t config)
{
@@ -147,7 +150,8 @@
return -1;
}
- INFO("CLUSTER ID: %d cpu-count: %d\n", cluster_count, cpus_per_cluster[cluster_count]);
+ VERBOSE("CLUSTER ID: %d cpu-count: %d\n", cluster_count,
+ cpus_per_cluster[cluster_count]);
/* Find the maximum number of cpus in any cluster */
max_cpu_per_cluster = MAX(max_cpu_per_cluster, cpus_per_cluster[cluster_count]);
@@ -170,5 +174,95 @@
return 0;
}
+int fconf_populate_uart_config(uintptr_t config)
+{
+ int uart_node, node, err;
+ uintptr_t addr;
+ const char *path;
+ uint32_t phandle;
+ uint64_t translated_addr;
+
+ /* Necessary to work with libfdt APIs */
+ const void *hw_config_dtb = (const void *)config;
+
+ /*
+ * uart child node is indirectly referenced through its path which is
+ * specified in the `serial1` property of the "aliases" node.
+ * Note that TF-A boot console is mapped to serial0 while runtime
+ * console is mapped to serial1.
+ */
+
+ path = fdt_get_alias(hw_config_dtb, "serial1");
+ if (path == NULL) {
+ ERROR("FCONF: Could not read serial1 property in aliases node\n");
+ return -1;
+ }
+
+ /* Find the offset of the uart serial node */
+ uart_node = fdt_path_offset(hw_config_dtb, path);
+ if (uart_node < 0) {
+ ERROR("FCONF: Failed to locate uart serial node using its path\n");
+ return -1;
+ }
+
+ /* uart serial node has its offset and size of address in reg property */
+ err = fdt_get_reg_props_by_index(hw_config_dtb, uart_node, 0, &addr,
+ NULL);
+ if (err < 0) {
+ ERROR("FCONF: Failed to read reg property of '%s' node\n",
+ "uart serial");
+ return err;
+ }
+ VERBOSE("FCONF: UART node address: %lx\n", addr);
+
+ /*
+ * Perform address translation of local device address to CPU address
+ * domain.
+ */
+ translated_addr = fdtw_translate_address(hw_config_dtb,
+ uart_node, (uint64_t)addr);
+ if (translated_addr == ILLEGAL_ADDR) {
+ ERROR("FCONF: failed to translate UART node base address");
+ return -1;
+ }
+
+ uart_serial_config.uart_base = translated_addr;
+
+ VERBOSE("FCONF: UART serial device base address: %llx\n",
+ uart_serial_config.uart_base);
+
+ /*
+ * The phandle of the DT node which captures the clock info of uart
+ * serial node is specified in the "clocks" property.
+ */
+ err = fdt_read_uint32(hw_config_dtb, uart_node, "clocks", &phandle);
+ if (err < 0) {
+ ERROR("FCONF: Could not read clocks property in uart serial node\n");
+ return err;
+ }
+
+ node = fdt_node_offset_by_phandle(hw_config_dtb, phandle);
+ if (node < 0) {
+ ERROR("FCONF: Failed to locate clk node using its path\n");
+ return node;
+ }
+
+ /*
+ * Retrieve clock frequency. We assume clock provider generates a fixed
+ * clock.
+ */
+ err = fdt_read_uint32(hw_config_dtb, node, "clock-frequency",
+ &uart_serial_config.uart_clk);
+ if (err < 0) {
+ ERROR("FCONF: Could not read clock-frequency property in clk node\n");
+ return err;
+ }
+
+ VERBOSE("FCONF: UART serial device clk frequency: %x\n",
+ uart_serial_config.uart_clk);
+ return 0;
+}
+
FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config);
FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
+FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config);
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index ebfbe17..a1c9094 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -6,12 +6,14 @@
/dts-v1/;
/ {
- compatible = "arm,spci-core-manifest-1.0";
+ compatible = "arm,ffa-core-manifest-1.0";
+ #address-cells = <2>;
+ #size-cells = <1>;
attribute {
spmc_id = <0x8000>;
- maj_ver = <0x0>;
- min_ver = <0x9>;
+ maj_ver = <0x1>;
+ min_ver = <0x0>;
exec_state = <0x0>;
load_address = <0x0 0x6000000>;
entrypoint = <0x0 0x6000000>;
@@ -25,12 +27,12 @@
hypervisor {
compatible = "hafnium,hafnium";
vm1 {
- is_spci_partition;
+ is_ffa_partition;
debug_name = "cactus-primary";
load_address = <0x7000000>;
};
vm2 {
- is_spci_partition;
+ is_ffa_partition;
debug_name = "cactus-secondary";
load_address = <0x7100000>;
vcpu_count = <2>;
@@ -62,6 +64,6 @@
memory@60000000 {
device_type = "memory";
- reg = <0x6000000 0x2000000>; /* Trusted DRAM */
+ reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
};
};
diff --git a/plat/arm/board/fvp/fvp_console.c b/plat/arm/board/fvp/fvp_console.c
new file mode 100644
index 0000000..928b47b
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_console.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <fconf_hw_config_getter.h>
+#include <plat/arm/common/plat_arm.h>
+
+static console_t fvp_runtime_console;
+
+/* Initialize the runtime console */
+void arm_console_runtime_init(void)
+{
+ uintptr_t uart_base;
+ uint32_t uart_clk;
+
+ /*
+ * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and
+ * BL2_AT_EL3 systems.
+ */
+#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3
+ uart_base = PLAT_ARM_RUN_UART_BASE;
+ uart_clk = PLAT_ARM_RUN_UART_CLK_IN_HZ;
+#else
+ uart_base = FCONF_GET_PROPERTY(hw_config, uart_serial_config,
+ uart_base);
+ uart_clk = FCONF_GET_PROPERTY(hw_config, uart_serial_config,
+ uart_clk);
+#endif
+
+ int rc = console_pl011_register(uart_base, uart_clk,
+ ARM_CONSOLE_BAUDRATE,
+ &fvp_runtime_console);
+
+ if (rc == 0) {
+ panic();
+ }
+
+ console_set_scope(&fvp_runtime_console, CONSOLE_FLAG_RUNTIME);
+}
+
+void arm_console_runtime_end(void)
+{
+ (void)console_flush();
+ (void)console_unregister(&fvp_runtime_console);
+}
diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c
new file mode 100644
index 0000000..a3ee8ef
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_gicv3.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <platform_def.h>
+
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv3.h>
+#include <fconf_hw_config_getter.h>
+#include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t fvp_rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+/* Default GICR base address to be used for GICR probe. */
+static uint64_t fvp_gicr_base_addrs[2] = { 0U };
+
+/* List of zero terminated GICR frame addresses which CPUs will probe */
+static uint64_t *fvp_gicr_frames = fvp_gicr_base_addrs;
+
+static const interrupt_prop_t fvp_interrupt_props[] = {
+ PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
+ PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
+};
+
+/*
+ * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
+ * to core position.
+ *
+ * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
+ * values read from GICR_TYPER don't have an MT field. To reuse the same
+ * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
+ * that read from GICR_TYPER.
+ *
+ * Assumptions:
+ *
+ * - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
+ * - No CPUs implemented in the system use affinity level 3.
+ */
+static unsigned int fvp_gicv3_mpidr_hash(u_register_t mpidr)
+{
+ u_register_t temp_mpidr = mpidr;
+
+ temp_mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
+ return plat_arm_calc_core_pos(temp_mpidr);
+}
+
+
+static gicv3_driver_data_t fvp_gic_data = {
+ .interrupt_props = fvp_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props),
+ .rdistif_num = PLATFORM_CORE_COUNT,
+ .rdistif_base_addrs = fvp_rdistif_base_addrs,
+ .mpidr_to_core_pos = fvp_gicv3_mpidr_hash
+};
+
+void plat_arm_gic_driver_init(void)
+{
+ /* Get GICD and GICR base addressed through FCONF APIs */
+#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
+ (defined(__aarch64__) && defined(IMAGE_BL31))
+ fvp_gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config,
+ gicv3_config,
+ gicd_base);
+ fvp_gicr_base_addrs[0] = FCONF_GET_PROPERTY(hw_config, gicv3_config,
+ gicr_base);
+#else
+ fvp_gic_data.gicd_base = PLAT_ARM_GICD_BASE;
+ fvp_gicr_base_addrs[0] = PLAT_ARM_GICR_BASE;
+#endif
+
+ /*
+ * The GICv3 driver is initialized in EL3 and does not need
+ * to be initialized again in SEL1. This is because the S-EL1
+ * can use GIC system registers to manage interrupts and does
+ * not need GIC interface base addresses to be configured.
+ */
+
+#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
+ (defined(__aarch64__) && defined(IMAGE_BL31))
+ gicv3_driver_init(&fvp_gic_data);
+ if (gicv3_rdistif_probe((uintptr_t)fvp_gicr_base_addrs[0]) == -1) {
+ ERROR("No GICR base frame found for Primary CPU\n");
+ panic();
+ }
+#endif
+}
+
+/******************************************************************************
+ * Function to iterate over all GICR frames and discover the corresponding
+ * per-cpu redistributor frame as well as initialize the corresponding
+ * interface in GICv3.
+ *****************************************************************************/
+void plat_arm_gic_pcpu_init(void)
+{
+ int result;
+ const uint64_t *plat_gicr_frames = fvp_gicr_frames;
+
+ do {
+ result = gicv3_rdistif_probe(*plat_gicr_frames);
+
+ /* If the probe is successful, no need to proceed further */
+ if (result == 0)
+ break;
+
+ plat_gicr_frames++;
+ } while (*plat_gicr_frames != 0U);
+
+ if (result == -1) {
+ ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
+ panic();
+ }
+ gicv3_rdistif_init(plat_my_core_pos());
+}
diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
index a9e569e..b53e00a 100644
--- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h
+++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
@@ -14,9 +14,11 @@
#define hw_config__topology_getter(prop) soc_topology.prop
+#define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop
+
struct gicv3_config_t {
- uintptr_t gicd_base;
- uintptr_t gicr_base;
+ uint64_t gicd_base;
+ uint64_t gicr_base;
};
struct hw_topology_t {
@@ -26,10 +28,17 @@
uint32_t plat_max_pwr_level;
};
+struct uart_serial_config_t {
+ uint64_t uart_base;
+ uint32_t uart_clk;
+};
+
int fconf_populate_gicv3_config(uintptr_t config);
int fconf_populate_topology(uintptr_t config);
+int fconf_populate_uart_config(uintptr_t config);
extern struct gicv3_config_t gicv3_config;
extern struct hw_topology_t soc_topology;
+extern struct uart_serial_config_t uart_serial_config;
#endif /* FCONF_HW_CONFIG_GETTER_H */
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index 213a974..b72bdab 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -16,6 +16,7 @@
rom rom_lib_init
fdt fdt_getprop
+fdt fdt_get_property
fdt fdt_getprop_namelen
fdt fdt_setprop_inplace
fdt fdt_check_header
@@ -31,6 +32,9 @@
fdt fdt_parent_offset
fdt fdt_stringlist_search
fdt fdt_get_alias_namelen
+fdt fdt_get_name
+fdt fdt_get_alias
+fdt fdt_node_offset_by_phandle
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 04cebca..33531f3 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -65,6 +65,10 @@
plat/common/plat_gicv3.c \
plat/arm/common/arm_gicv3.c
+ ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31} ${RESET_TO_SP_MIN}),)
+ FVP_GIC_SOURCES += plat/arm/board/fvp/fvp_gicv3.c
+ endif
+
else ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV2)
# No GICv4 extension
@@ -201,6 +205,7 @@
drivers/cfi/v2m/v2m_flash.c \
lib/utils/mem_region.c \
plat/arm/board/fvp/fvp_bl31_setup.c \
+ plat/arm/board/fvp/fvp_console.c \
plat/arm/board/fvp/fvp_pm.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/aarch64/fvp_helpers.S \
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 36bf441..ba6ceec 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -10,6 +10,7 @@
lib/utils/mem_region.c \
plat/arm/board/fvp/aarch32/fvp_helpers.S \
plat/arm/board/fvp/fvp_pm.c \
+ plat/arm/board/fvp/fvp_console.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c \
plat/arm/common/arm_nor_psci_mem_protect.c \
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index 09017ac..20ed2c7 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -16,6 +16,7 @@
rom rom_lib_init
fdt fdt_getprop
+fdt fdt_get_property
fdt fdt_getprop_namelen
fdt fdt_setprop_inplace
fdt fdt_check_header
@@ -28,6 +29,9 @@
fdt fdt_get_alias_namelen
fdt fdt_path_offset
fdt fdt_path_offset_namelen
+fdt fdt_get_name
+fdt fdt_get_alias
+fdt fdt_node_offset_by_phandle
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c
index 0cac5d9..c2281c4 100644
--- a/plat/arm/common/arm_console.c
+++ b/plat/arm/common/arm_console.c
@@ -13,6 +13,9 @@
#include <drivers/console.h>
#include <plat/arm/common/plat_arm.h>
+#pragma weak arm_console_runtime_init
+#pragma weak arm_console_runtime_end
+
/*******************************************************************************
* Functions that set up the console
******************************************************************************/
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 63871d9..b8a4d01 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -11,6 +11,7 @@
#if RAS_EXTENSION
#include <lib/extensions/ras.h>
#endif
+#include <lib/extensions/twed.h>
#include <lib/xlat_tables/xlat_mmu_helpers.h>
#include <plat/common/platform.h>
@@ -20,6 +21,7 @@
* platforms but may also be overridden by a platform if required.
*/
#pragma weak bl31_plat_runtime_setup
+#pragma weak plat_arm_set_twedel_scr_el3
#if SDEI_SUPPORT
#pragma weak plat_sdei_handle_masked_trigger
@@ -100,3 +102,16 @@
#endif
panic();
}
+
+/*******************************************************************************
+ * In v8.6+ platforms with delayed trapping of WFE this hook sets the delay. It
+ * is a weak function definition so can be overridden depending on the
+ * requirements of a platform. The only hook provided is for the TWED fields
+ * in SCR_EL3, the TWED fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 should be
+ * configured as needed in lower exception levels.
+ ******************************************************************************/
+
+uint32_t plat_arm_set_twedel_scr_el3(void)
+{
+ return TWED_DISABLED;
+}
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index 109b001..455b980 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.c
@@ -31,14 +31,14 @@
rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version);
if (rc != 0) {
- ERROR("Missing SPCI %s version in SPM Core manifest.\n",
+ ERROR("Missing FFA %s version in SPM Core manifest.\n",
"major");
return rc;
}
rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version);
if (rc != 0) {
- ERROR("Missing SPCI %s version in SPM Core manifest.\n",
+ ERROR("Missing FFA %s version in SPM Core manifest.\n",
"minor");
return rc;
}
@@ -163,7 +163,7 @@
VERBOSE("Reading SPM Core manifest at address %p\n", pm_addr);
rc = fdt_node_offset_by_compatible(pm_addr, -1,
- "arm,spci-core-manifest-1.0");
+ "arm,ffa-core-manifest-1.0");
if (rc < 0) {
ERROR("Unrecognized SPM Core manifest\n");
goto exit_unmap;
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index c946a75..a86a315 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -1,5 +1,6 @@
#
# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -27,8 +28,14 @@
${COMMON_DIR}/lib/debug/profiler.c \
${COMMON_DIR}/tegra_bl31_setup.c \
${COMMON_DIR}/tegra_delay_timer.c \
+ ${COMMON_DIR}/tegra_ehf.c \
${COMMON_DIR}/tegra_fiq_glue.c \
${COMMON_DIR}/tegra_io_storage.c \
${COMMON_DIR}/tegra_platform.c \
${COMMON_DIR}/tegra_pm.c \
- ${COMMON_DIR}/tegra_sip_calls.c
+ ${COMMON_DIR}/tegra_sip_calls.c \
+ ${COMMON_DIR}/tegra_sdei.c
+
+ifneq ($(ENABLE_STACK_PROTECTOR), 0)
+BL31_SOURCES += ${COMMON_DIR}/tegra_stack_protector.c
+endif
diff --git a/plat/nvidia/tegra/common/tegra_ehf.c b/plat/nvidia/tegra/common/tegra_ehf.c
new file mode 100644
index 0000000..ea6e443
--- /dev/null
+++ b/plat/nvidia/tegra/common/tegra_ehf.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <bl31/ehf.h>
+
+/*
+ * Enumeration of priority levels on Tegra platforms.
+ */
+ehf_pri_desc_t tegra_exceptions[] = {
+ /* Watchdog priority */
+ EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_TEGRA_WDT_PRIO),
+
+#if SDEI_SUPPORT
+ /* Critical priority SDEI */
+ EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_CRITICAL_PRI),
+
+ /* Normal priority SDEI */
+ EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
+#endif
+};
+
+/* Plug in Tegra exceptions to Exception Handling Framework. */
+EHF_REGISTER_PRIORITIES(tegra_exceptions, ARRAY_SIZE(tegra_exceptions), PLAT_PRI_BITS);
diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c
index bb5add8..5309d98 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -26,15 +26,6 @@
/* Legacy FIQ used by earlier Tegra platforms */
#define LEGACY_FIQ_PPI_WDT 28U
-/* Install priority level descriptors for each dispatcher */
-ehf_pri_desc_t plat_exceptions[] = {
- EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_TEGRA_WDT_PRIO),
-};
-
-/* Expose priority descriptors to Exception Handling Framework */
-EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions),
- PLAT_PRI_BITS);
-
/*******************************************************************************
* Static variables
******************************************************************************/
diff --git a/plat/nvidia/tegra/common/tegra_sdei.c b/plat/nvidia/tegra/common/tegra_sdei.c
new file mode 100644
index 0000000..9241b81
--- /dev/null
+++ b/plat/nvidia/tegra/common/tegra_sdei.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* SDEI configuration for Tegra platforms */
+
+#include <platform_def.h>
+
+#include <bl31/ehf.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <lib/utils_def.h>
+#include <services/sdei.h>
+
+/* Private event mappings */
+static sdei_ev_map_t tegra_sdei_private[] = {
+ /* Event 0 definition */
+ SDEI_DEFINE_EVENT_0(TEGRA_SDEI_SGI_PRIVATE),
+
+ /* Dynamic private events */
+ SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+
+ /* General purpose explicit events */
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_0, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_1, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_2, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_3, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_4, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_5, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_6, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_7, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_8, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_9, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_10, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_11, SDEI_MAPF_CRITICAL)
+};
+
+/* Shared event mappings */
+static sdei_ev_map_t tegra_sdei_shared[] = {
+ /* Dynamic shared events */
+ SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+};
+
+void plat_sdei_setup(void)
+{
+ INFO("SDEI platform setup\n");
+}
+
+/* Export Tegra SDEI events */
+REGISTER_SDEI_MAP(tegra_sdei_private, tegra_sdei_shared);
diff --git a/plat/nvidia/tegra/common/tegra_stack_protector.c b/plat/nvidia/tegra/common/tegra_stack_protector.c
new file mode 100644
index 0000000..f6c459a
--- /dev/null
+++ b/plat/nvidia/tegra/common/tegra_stack_protector.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ u_register_t seed;
+
+ /*
+ * Ideally, a random number should be returned instead. As the
+ * platform does not have any random number generator, this is
+ * better than nothing, but not really secure.
+ */
+ seed = mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET);
+ seed <<= 32;
+ seed |= mmio_read_32(TEGRA_TMRUS_BASE);
+
+ return seed ^ read_cntpct_el0();
+}
diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h
index 6bfad23..678b15c 100644
--- a/plat/nvidia/tegra/include/platform_def.h
+++ b/plat/nvidia/tegra/include/platform_def.h
@@ -87,9 +87,43 @@
#define MAX_IO_HANDLES U(0)
/*******************************************************************************
+ * Platforms macros to support SDEI
+ ******************************************************************************/
+#define TEGRA_SDEI_SGI_PRIVATE U(8)
+
+/*******************************************************************************
* Platform macros to support exception handling framework
******************************************************************************/
#define PLAT_PRI_BITS U(3)
+#define PLAT_SDEI_CRITICAL_PRI U(0x20)
+#define PLAT_SDEI_NORMAL_PRI U(0x30)
#define PLAT_TEGRA_WDT_PRIO U(0x40)
+/*******************************************************************************
+ * SDEI events
+ ******************************************************************************/
+/* SDEI dynamic private event numbers */
+#define TEGRA_SDEI_DP_EVENT_0 U(100)
+#define TEGRA_SDEI_DP_EVENT_1 U(101)
+#define TEGRA_SDEI_DP_EVENT_2 U(102)
+
+/* SDEI dynamic shared event numbers */
+#define TEGRA_SDEI_DS_EVENT_0 U(200)
+#define TEGRA_SDEI_DS_EVENT_1 U(201)
+#define TEGRA_SDEI_DS_EVENT_2 U(202)
+
+/* SDEI explicit events */
+#define TEGRA_SDEI_EP_EVENT_0 U(300)
+#define TEGRA_SDEI_EP_EVENT_1 U(301)
+#define TEGRA_SDEI_EP_EVENT_2 U(302)
+#define TEGRA_SDEI_EP_EVENT_3 U(303)
+#define TEGRA_SDEI_EP_EVENT_4 U(304)
+#define TEGRA_SDEI_EP_EVENT_5 U(305)
+#define TEGRA_SDEI_EP_EVENT_6 U(306)
+#define TEGRA_SDEI_EP_EVENT_7 U(307)
+#define TEGRA_SDEI_EP_EVENT_8 U(308)
+#define TEGRA_SDEI_EP_EVENT_9 U(309)
+#define TEGRA_SDEI_EP_EVENT_10 U(310)
+#define TEGRA_SDEI_EP_EVENT_11 U(311)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index e03e1f3..3d61f06 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -49,6 +49,12 @@
# Flag to allow relocation of BL32 image to TZDRAM during boot
RELOCATE_BL32_IMAGE ?= 0
+# Enable stack protection
+ENABLE_STACK_PROTECTOR := strong
+
+# Enable SDEI
+SDEI_SUPPORT := 1
+
include plat/nvidia/tegra/common/tegra_common.mk
include ${SOC_DIR}/platform_${TARGET_SOC}.mk
@@ -63,6 +69,7 @@
# override with necessary libc files for the Tegra platform
override LIBC_SRCS := $(addprefix lib/libc/, \
+ aarch64/setjmp.S \
assert.c \
memcpy.c \
memmove.c \
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index 1c7c25d..c216b5d 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -214,6 +214,8 @@
/* Secure IRQs for Tegra186 */
static const interrupt_prop_t tegra186_interrupt_props[] = {
+ INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(TEGRA186_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index ce5815b..e226372 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -73,19 +73,16 @@
switch (state_id) {
case PSTATE_ID_CORE_IDLE:
+ if (psci_get_pstate_type(power_state) != PSTATE_TYPE_STANDBY) {
+ ret = PSCI_E_INVALID_PARAMS;
+ break;
+ }
+
/* Core idle request */
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
req_state->pwr_domain_state[MPIDR_AFFLVL1] = PSCI_LOCAL_STATE_RUN;
break;
- case PSTATE_ID_CORE_POWERDN:
-
- /* Core powerdown request */
- req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
- req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
-
- break;
-
default:
ERROR("%s: unsupported state id (%d)\n", __func__, state_id);
ret = PSCI_E_INVALID_PARAMS;
@@ -117,7 +114,7 @@
int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
const plat_local_state_t *pwr_domain_state;
- uint8_t stateid_afflvl0, stateid_afflvl2;
+ uint8_t stateid_afflvl2;
plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
uint64_t mc_ctx_base;
uint32_t val;
@@ -128,25 +125,14 @@
.system_state_force = 1U,
.update_wake_mask = 1U,
};
- uint32_t cpu = plat_my_core_pos();
int32_t ret = 0;
/* get the state ID */
pwr_domain_state = target_state->pwr_domain_state;
- stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] &
- TEGRA194_STATE_ID_MASK;
stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
TEGRA194_STATE_ID_MASK;
- if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) {
-
- /* Enter CPU powerdown */
- (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
- (uint64_t)TEGRA_NVG_CORE_C7,
- t19x_percpu_data[cpu].wake_time,
- 0U);
-
- } else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+ if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
/* save 'Secure Boot' Processor Feature Config Register */
val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
@@ -187,8 +173,6 @@
/* set system suspend state for house-keeping */
tegra194_set_system_suspend_entry();
- } else {
- ; /* do nothing */
}
return PSCI_E_SUCCESS;
@@ -226,15 +210,6 @@
plat_local_state_t target = states[core_pos];
mce_cstate_info_t cstate_info = { 0 };
- /* CPU suspend */
- if (target == PSTATE_ID_CORE_POWERDN) {
-
- /* Program default wake mask */
- cstate_info.wake_mask = TEGRA194_CORE_WAKE_MASK;
- cstate_info.update_wake_mask = 1;
- mce_update_cstate_info(&cstate_info);
- }
-
/* CPU off */
if (target == PLAT_MAX_OFF_STATE) {
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
index f90a69e..5d6c60b 100644
--- a/plat/nvidia/tegra/soc/t194/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -275,6 +275,8 @@
/* Secure IRQs for Tegra194 */
static const interrupt_prop_t tegra194_interrupt_props[] = {
+ INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(TEGRA194_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index 930eeac..f2b267b 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -179,6 +179,8 @@
/* Secure IRQs for Tegra186 */
static const interrupt_prop_t tegra210_interrupt_props[] = {
+ INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(TEGRA210_TIMER1_IRQ, PLAT_TEGRA_WDT_PRIO,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, PLAT_TEGRA_WDT_PRIO,
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 501782f..a818037 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -20,7 +20,7 @@
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <services/spci_svc.h>
+#include <services/ffa_svc.h>
#include <services/spmd_svc.h>
#include <smccc_helpers.h>
#include "spmd_private.h"
@@ -56,7 +56,7 @@
******************************************************************************/
static int32_t spmd_init(void);
static int spmd_spmc_init(void *pm_addr);
-static uint64_t spmd_spci_error_return(void *handle,
+static uint64_t spmd_ffa_error_return(void *handle,
int error_code);
static uint64_t spmd_smc_forward(uint32_t smc_fid,
bool secure_origin,
@@ -161,14 +161,14 @@
* Ensure that the SPM Core version is compatible with the SPM
* Dispatcher version.
*/
- if ((spmc_attrs.major_version != SPCI_VERSION_MAJOR) ||
- (spmc_attrs.minor_version > SPCI_VERSION_MINOR)) {
- WARN("Unsupported SPCI version (%u.%u)\n",
+ if ((spmc_attrs.major_version != FFA_VERSION_MAJOR) ||
+ (spmc_attrs.minor_version > FFA_VERSION_MINOR)) {
+ WARN("Unsupported FFA version (%u.%u)\n",
spmc_attrs.major_version, spmc_attrs.minor_version);
return -EINVAL;
}
- VERBOSE("SPCI version (%u.%u)\n", spmc_attrs.major_version,
+ VERBOSE("FFA version (%u.%u)\n", spmc_attrs.major_version,
spmc_attrs.minor_version);
VERBOSE("SPM Core run time EL%x.\n",
@@ -324,18 +324,18 @@
}
/*******************************************************************************
- * Return SPCI_ERROR with specified error code
+ * Return FFA_ERROR with specified error code
******************************************************************************/
-static uint64_t spmd_spci_error_return(void *handle, int error_code)
+static uint64_t spmd_ffa_error_return(void *handle, int error_code)
{
- SMC_RET8(handle, SPCI_ERROR,
- SPCI_TARGET_INFO_MBZ, error_code,
- SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
- SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+ SMC_RET8(handle, FFA_ERROR,
+ FFA_TARGET_INFO_MBZ, error_code,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ);
}
/*******************************************************************************
- * This function handles all SMCs in the range reserved for SPCI. Each call is
+ * This function handles all SMCs in the range reserved for FFA. Each call is
* either forwarded to the other security state or handled by the SPM dispatcher
******************************************************************************/
uint64_t spmd_smc_handler(uint32_t smc_fid,
@@ -360,7 +360,7 @@
SMC_GET_GP(handle, CTX_GPREG_X7));
switch (smc_fid) {
- case SPCI_ERROR:
+ case FFA_ERROR:
/*
* Check if this is the first invocation of this interface on
* this CPU. If so, then indicate that the SPM Core initialised
@@ -374,33 +374,33 @@
x1, x2, x3, x4, handle);
break; /* not reached */
- case SPCI_VERSION:
+ case FFA_VERSION:
/*
* TODO: This is an optimization that the version information
* provided by the SPM Core manifest is returned by the SPM
* dispatcher. It might be a better idea to simply forward this
* call to the SPM Core and wash our hands completely.
*/
- ret = MAKE_SPCI_VERSION(spmc_attrs.major_version,
+ ret = MAKE_FFA_VERSION(spmc_attrs.major_version,
spmc_attrs.minor_version);
- SMC_RET8(handle, SPCI_SUCCESS_SMC32, SPCI_TARGET_INFO_MBZ, ret,
- SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
- SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+ SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_TARGET_INFO_MBZ, ret,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ);
break; /* not reached */
- case SPCI_FEATURES:
+ case FFA_FEATURES:
/*
* This is an optional interface. Do the minimal checks and
* forward to SPM Core which will handle it if implemented.
*/
/*
- * Check if x1 holds a valid SPCI fid. This is an
+ * Check if x1 holds a valid FFA fid. This is an
* optimization.
*/
- if (!is_spci_fid(x1)) {
- return spmd_spci_error_return(handle,
- SPCI_ERROR_NOT_SUPPORTED);
+ if (!is_ffa_fid(x1)) {
+ return spmd_ffa_error_return(handle,
+ FFA_ERROR_NOT_SUPPORTED);
}
/* Forward SMC from Normal world to the SPM Core */
@@ -411,68 +411,68 @@
/*
* Return success if call was from secure world i.e. all
- * SPCI functions are supported. This is essentially a
+ * FFA functions are supported. This is essentially a
* nop.
*/
- SMC_RET8(handle, SPCI_SUCCESS_SMC32, x1, x2, x3, x4,
+ SMC_RET8(handle, FFA_SUCCESS_SMC32, x1, x2, x3, x4,
SMC_GET_GP(handle, CTX_GPREG_X5),
SMC_GET_GP(handle, CTX_GPREG_X6),
SMC_GET_GP(handle, CTX_GPREG_X7));
break; /* not reached */
- case SPCI_ID_GET:
+ case FFA_ID_GET:
/*
- * Returns the ID of the calling SPCI component.
+ * Returns the ID of the calling FFA component.
*/
if (!secure_origin) {
- SMC_RET8(handle, SPCI_SUCCESS_SMC32,
- SPCI_TARGET_INFO_MBZ, SPCI_NS_ENDPOINT_ID,
- SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
- SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
- SPCI_PARAM_MBZ);
+ SMC_RET8(handle, FFA_SUCCESS_SMC32,
+ FFA_TARGET_INFO_MBZ, FFA_NS_ENDPOINT_ID,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ);
}
- SMC_RET8(handle, SPCI_SUCCESS_SMC32,
- SPCI_TARGET_INFO_MBZ, spmc_attrs.spmc_id,
- SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
- SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
- SPCI_PARAM_MBZ);
+ SMC_RET8(handle, FFA_SUCCESS_SMC32,
+ FFA_TARGET_INFO_MBZ, spmc_attrs.spmc_id,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ);
break; /* not reached */
- case SPCI_RX_RELEASE:
- case SPCI_RXTX_MAP_SMC32:
- case SPCI_RXTX_MAP_SMC64:
- case SPCI_RXTX_UNMAP:
- case SPCI_MSG_RUN:
+ case FFA_RX_RELEASE:
+ case FFA_RXTX_MAP_SMC32:
+ case FFA_RXTX_MAP_SMC64:
+ case FFA_RXTX_UNMAP:
+ case FFA_MSG_RUN:
/* This interface must be invoked only by the Normal world */
if (secure_origin) {
- return spmd_spci_error_return(handle,
- SPCI_ERROR_NOT_SUPPORTED);
+ return spmd_ffa_error_return(handle,
+ FFA_ERROR_NOT_SUPPORTED);
}
/* Fall through to forward the call to the other world */
- case SPCI_PARTITION_INFO_GET:
- case SPCI_MSG_SEND:
- case SPCI_MSG_SEND_DIRECT_REQ_SMC32:
- case SPCI_MSG_SEND_DIRECT_REQ_SMC64:
- case SPCI_MSG_SEND_DIRECT_RESP_SMC32:
- case SPCI_MSG_SEND_DIRECT_RESP_SMC64:
- case SPCI_MEM_DONATE_SMC32:
- case SPCI_MEM_DONATE_SMC64:
- case SPCI_MEM_LEND_SMC32:
- case SPCI_MEM_LEND_SMC64:
- case SPCI_MEM_SHARE_SMC32:
- case SPCI_MEM_SHARE_SMC64:
- case SPCI_MEM_RETRIEVE_REQ_SMC32:
- case SPCI_MEM_RETRIEVE_REQ_SMC64:
- case SPCI_MEM_RETRIEVE_RESP:
- case SPCI_MEM_RELINQUISH:
- case SPCI_MEM_RECLAIM:
- case SPCI_SUCCESS_SMC32:
- case SPCI_SUCCESS_SMC64:
+ case FFA_PARTITION_INFO_GET:
+ case FFA_MSG_SEND:
+ case FFA_MSG_SEND_DIRECT_REQ_SMC32:
+ case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+ case FFA_MSG_SEND_DIRECT_RESP_SMC32:
+ case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+ case FFA_MEM_DONATE_SMC32:
+ case FFA_MEM_DONATE_SMC64:
+ case FFA_MEM_LEND_SMC32:
+ case FFA_MEM_LEND_SMC64:
+ case FFA_MEM_SHARE_SMC32:
+ case FFA_MEM_SHARE_SMC64:
+ case FFA_MEM_RETRIEVE_REQ_SMC32:
+ case FFA_MEM_RETRIEVE_REQ_SMC64:
+ case FFA_MEM_RETRIEVE_RESP:
+ case FFA_MEM_RELINQUISH:
+ case FFA_MEM_RECLAIM:
+ case FFA_SUCCESS_SMC32:
+ case FFA_SUCCESS_SMC64:
/*
* TODO: Assume that no requests originate from EL3 at the
* moment. This will change if a SP service is required in
@@ -484,7 +484,7 @@
x1, x2, x3, x4, handle);
break; /* not reached */
- case SPCI_MSG_WAIT:
+ case FFA_MSG_WAIT:
/*
* Check if this is the first invocation of this interface on
* this CPU from the Secure world. If so, then indicate that the
@@ -496,11 +496,11 @@
/* Fall through to forward the call to the other world */
- case SPCI_MSG_YIELD:
+ case FFA_MSG_YIELD:
/* This interface must be invoked only by the Secure world */
if (!secure_origin) {
- return spmd_spci_error_return(handle,
- SPCI_ERROR_NOT_SUPPORTED);
+ return spmd_ffa_error_return(handle,
+ FFA_ERROR_NOT_SUPPORTED);
}
return spmd_smc_forward(smc_fid, secure_origin,
@@ -509,6 +509,6 @@
default:
WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
- return spmd_spci_error_return(handle, SPCI_ERROR_NOT_SUPPORTED);
+ return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
}
}
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 232031b..4946309 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -30,7 +30,7 @@
#define SPMD_C_RT_CTX_ENTRIES (SPMD_C_RT_CTX_SIZE >> DWORD_SHIFT)
#ifndef __ASSEMBLER__
-#include <services/spci_svc.h>
+#include <services/ffa_svc.h>
#include <stdint.h>
typedef enum spmc_state {
@@ -49,11 +49,11 @@
} spmd_spm_core_context_t;
/*
- * Reserve ID for NS physical SPCI Endpoint.
+ * Reserve ID for NS physical FFA Endpoint.
*/
-#define SPCI_NS_ENDPOINT_ID U(0)
+#define FFA_NS_ENDPOINT_ID U(0)
-/* Mask and shift to check valid secure SPCI Endpoint ID. */
+/* Mask and shift to check valid secure FFA Endpoint ID. */
#define SPMC_SECURE_ID_MASK U(1)
#define SPMC_SECURE_ID_SHIFT U(15)
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 895fd29..cdd17bc 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -123,10 +123,10 @@
#if defined(SPD_spmd)
/*
- * Dispatch SPCI calls to the SPCI SMC handler implemented by the SPM
+ * Dispatch FFA calls to the FFA SMC handler implemented by the SPM
* dispatcher and return its return value
*/
- if (is_spci_fid(smc_fid)) {
+ if (is_ffa_fid(smc_fid)) {
return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
handle, flags);
}