Merge "docs(security): update info on use of OpenSSL 3.0" into integration
diff --git a/changelog.yaml b/changelog.yaml
index 37a9c6d..c4028c4 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -563,6 +563,9 @@
- title: TRP
scope: trp
+ - title: RMMD
+ scope: rmmd
+
- title: SPM
scope: spm
@@ -1048,6 +1051,13 @@
deprecated:
- fdts stm32mp1
+ subsections:
+ - title: STM32MP13
+ scope: stm32mp13-fdts
+
+ - title: STM32MP15
+ scope: stm32mp15-fdts
+
- title: PIE
scope: pie
diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c
index b1d628c..1bad74f 100644
--- a/common/fdt_fixup.c
+++ b/common/fdt_fixup.c
@@ -583,3 +583,44 @@
(ac + sc + ac) * 4,
val, sc * 4);
}
+/**
+ * fdt_set_mac_address () - store MAC address in device tree
+ * @dtb: pointer to the device tree blob in memory
+ * @eth_idx: number of Ethernet interface in /aliases node
+ * @mac_addr: pointer to 6 byte MAC address to store
+ *
+ * Use the generic local-mac-address property in a network device DT node
+ * to define the MAC address this device should be using. Many platform
+ * network devices lack device-specific non-volatile storage to hold this
+ * address, and leave it up to firmware to find and store a unique MAC
+ * address in the DT.
+ * The MAC address could be read from some board or firmware defined storage,
+ * or could be derived from some other unique property like a serial number.
+ *
+ * Return: 0 on success, a negative libfdt error value otherwise.
+ */
+int fdt_set_mac_address(void *dtb, unsigned int ethernet_idx,
+ const uint8_t *mac_addr)
+{
+ char eth_alias[12];
+ const char *path;
+ int node;
+
+ if (ethernet_idx > 9U) {
+ return -FDT_ERR_BADVALUE;
+ }
+ snprintf(eth_alias, sizeof(eth_alias), "ethernet%d", ethernet_idx);
+
+ path = fdt_get_alias(dtb, eth_alias);
+ if (path == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ node = fdt_path_offset(dtb, path);
+ if (node < 0) {
+ ERROR("Path \"%s\" not found in DT: %d\n", path, node);
+ return node;
+ }
+
+ return fdt_setprop(dtb, node, "local-mac-address", mac_addr, 6);
+}
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 871afe3..d16b5dd 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -48,6 +48,8 @@
:|G|: `madhukar-Arm`_
:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
:|G|: `raghuncstate`_
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
.. _code owners:
@@ -111,14 +113,22 @@
:|G|: `ManishVB-Arm`_
:|F|: bl31/ehf.c
+Realm Management Monitor Dispatcher (RMMD)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
+:|G|: `javieralso-arm`_
+:|F|: services/std_svc/rmmd/\*
+:|F|: include/services/rmmd_svc.h
+:|F|: include/services/rmm_core_manifest.h
+
Realm Management Extension (RME)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Bipin Ravi <bipin.ravi@arm.com>
:|G|: `bipinravi-arm`_
:|M|: Mark Dykes <mark.dykes@arm.com>
:|G|: `mardyk01`_
-:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:|G|: `zelalem-aweke`_
+:|M|: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
+:|G|: `javieralso-arm`_
Drivers, Libraries and Framework Code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/components/index.rst b/docs/components/index.rst
index 2f81f23..192773f 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -24,4 +24,5 @@
xlat-tables-lib-v2-design
cot-binding
realm-management-extension
+ rmm-el3-comms-spec
granule-protection-tables-design
diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst
index 5fa5140..ea921fc 100644
--- a/docs/components/realm-management-extension.rst
+++ b/docs/components/realm-management-extension.rst
@@ -73,6 +73,14 @@
world. It initializes the RMM and handles Realm Management Interface (RMI)
SMC calls from Non-secure and Realm worlds.
+There is a contract between RMM and RMMD that defines the arguments that the
+former needs to take in order to initialize and also the possible return values.
+This contract is defined in the RMM Boot Interface, which can be found at
+:ref:`rmm_el3_boot_interface`.
+
+There is also a specification of the runtime services provided by TF-A
+to RMM. This can be found at :ref:`runtime_services_and_interface`.
+
Test Realm Payload (TRP)
*************************
TRP is a small test payload that runs at R-EL2 and implements a subset of
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
new file mode 100644
index 0000000..9140d54
--- /dev/null
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -0,0 +1,413 @@
+RMM-EL3 Communication interface
+*******************************
+
+This document defines the communication interface between RMM and EL3.
+There are two parts in this interface: the boot interface and the runtime
+interface.
+
+The Boot Interface defines the ABI between EL3 and RMM when the CPU enters
+R-EL2 for the first time after boot. The cold boot interface defines the ABI
+for the cold boot path and the warm boot interface defines the same for the
+warm path.
+
+The RMM-EL3 runtime interface defines the ABI for EL3 services which can be
+invoked by RMM as well as the register save-restore convention when handling an
+SMC call from NS.
+
+The below sections discuss these interfaces more in detail.
+
+.. _rmm_el3_ifc_versioning:
+
+RMM-EL3 Interface versioning
+____________________________
+
+The RMM Boot and Runtime Interface uses a version number to check
+compatibility with the register arguments passed as part of Boot Interface and
+RMM-EL3 runtime interface.
+
+The Boot Manifest, discussed later in section :ref:`rmm_el3_boot_manifest`,
+uses a separate version number but with the same scheme.
+
+The version number is a 32-bit type with the following fields:
+
+.. csv-table::
+ :header: "Bits", "Value"
+
+ [0:15],``VERSION_MINOR``
+ [16:30],``VERSION_MAJOR``
+ [31],RES0
+
+The version numbers are sequentially increased and the rules for updating them
+are explained below:
+
+ - ``VERSION_MAJOR``: This value is increased when changes break
+ compatibility with previous versions. If the changes
+ on the ABI are compatible with the previous one, ``VERSION_MAJOR``
+ remains unchanged.
+
+ - ``VERSION_MINOR``: This value is increased on any change that is backwards
+ compatible with the previous version. When ``VERSION_MAJOR`` is increased,
+ ``VERSION_MINOR`` must be set to 0.
+
+ - ``RES0``: Bit 31 of the version number is reserved 0 as to maintain
+ consistency with the versioning schemes used in other parts of RMM.
+
+This document specifies the 0.1 version of Boot Interface ABI and RMM-EL3
+services specification and the 0.1 version of the Boot Manifest.
+
+.. _rmm_el3_boot_interface:
+
+RMM Boot Interface
+__________________
+
+This section deals with the Boot Interface part of the specification.
+
+One of the goals of the Boot Interface is to allow EL3 firmware to pass
+down into RMM certain platform specific information dynamically. This allows
+RMM to be less platform dependent and be more generic across platform
+variations. It also allows RMM to be decoupled from the other boot loader
+images in the boot sequence and remain agnostic of any particular format used
+for configuration files.
+
+The Boot Interface ABI defines a set of register conventions and
+also a memory based manifest file to pass information from EL3 to RMM. The
+boot manifest and the associated platform data in it can be dynamically created
+by EL3 and there is no restriction on how the data can be obtained (e.g by DTB,
+hoblist or other).
+
+The register convention and the manifest are versioned separately to manage
+future enhancements and compatibility.
+
+RMM completes the boot by issuing the ``RMM_BOOT_COMPLETE`` SMC (0xC40001CF)
+back to EL3. After the RMM has finished the boot process, it can only be
+entered from EL3 as part of RMI handling.
+
+If RMM returns an error during boot (in any CPU), then RMM must not be entered
+from any CPU.
+
+.. _rmm_cold_boot_interface:
+
+Cold Boot Interface
+~~~~~~~~~~~~~~~~~~~
+
+During cold boot RMM expects the following register values:
+
+.. csv-table::
+ :header: "Register", "Value"
+ :widths: 1, 5
+
+ x0,Linear index of this PE. This index starts from 0 and must be less than the maximum number of CPUs to be supported at runtime (see x2).
+ x1,Version for this Boot Interface as defined in :ref:`rmm_el3_ifc_versioning`.
+ x2,Maximum number of CPUs to be supported at runtime. RMM should ensure that it can support this maximum number.
+ x3,Base address for the shared buffer used for communication between EL3 firmware and RMM. This buffer must be of 4KB size (1 page). The boot manifest must be present at the base of this shared buffer during cold boot.
+
+During cold boot, EL3 firmware needs to allocate a 4K page that will be
+passed to RMM in x3. This memory will be used as shared buffer for communication
+between EL3 and RMM. It must be assigned to Realm world and must be mapped with
+Normal memory attributes (IWB-OWB-ISH) at EL3. At boot, this memory will be
+used to populate the Boot Manifest. Since the Boot Manifest can be accessed by
+RMM prior to enabling its MMU, EL3 must ensure that proper cache maintenance
+operations are performed after the Boot Manifest is populated.
+
+EL3 should also ensure that this shared buffer is always available for use by RMM
+during the lifetime of the system and that it can be used for runtime
+communication between RMM and EL3. For example, when RMM invokes attestation
+service commands in EL3, this buffer can be used to exchange data between RMM
+and EL3. It is also allowed for RMM to invoke runtime services provided by EL3
+utilizing this buffer during the boot phase, prior to return back to EL3 via
+RMM_BOOT_COMPLETE SMC.
+
+RMM should map this memory page into its Stage 1 page-tables using Normal
+memory attributes.
+
+During runtime, it is the RMM which initiates any communication with EL3. If that
+communication requires the use of the shared area, it is expected that RMM needs
+to do the necessary concurrency protection to prevent the use of the same buffer
+by other PEs.
+
+The following sequence diagram shows how a generic EL3 Firmware would boot RMM.
+
+.. image:: ../resources/diagrams/rmm_cold_boot_generic.png
+
+Warm Boot Interface
+~~~~~~~~~~~~~~~~~~~
+
+At warm boot, RMM is already initialized and only some per-CPU initialization
+is still pending. The only argument that is required by RMM at this stage is
+the CPU Id, which will be passed through register x0 whilst x1 to x3 are RES0.
+This is summarized in the following table:
+
+.. csv-table::
+ :header: "Register", "Value"
+ :widths: 1, 5
+
+ x0,Linear index of this PE. This index starts from 0 and must be less than the maximum number of CPUs to be supported at runtime (see x2).
+ x1 - x3,RES0
+
+Boot error handling and return values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After boot up and initialization, RMM returns control back to EL3 through a
+``RMM_BOOT_COMPLETE`` SMC call. The only argument of this SMC call will
+be returned in x1 and it will encode a signed integer with the error reason
+as per the following table:
+
+.. csv-table::
+ :header: "Error code", "Description", "ID"
+ :widths: 2 4 1
+
+ ``E_RMM_BOOT_SUCCESS``,Boot successful,0
+ ``E_RMM_BOOT_ERR_UNKNOWN``,Unknown error,-1
+ ``E_RMM_BOOT_VERSION_NOT_VALID``,Boot Interface version reported by EL3 is not supported by RMM,-2
+ ``E_RMM_BOOT_CPUS_OUT_OF_RAGE``,Number of CPUs reported by EL3 larger than maximum supported by RMM,-3
+ ``E_RMM_BOOT_CPU_ID_OUT_OF_RAGE``,Current CPU Id is higher or equal than the number of CPUs supported by RMM,-4
+ ``E_RMM_BOOT_INVALID_SHARED_BUFFER``,Invalid pointer to shared memory area,-5
+ ``E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED``,Version reported by the boot manifest not supported by RMM,-6
+ ``E_RMM_BOOT_MANIFEST_DATA_ERROR``,Error parsing core boot manifest,-7
+
+For any error detected in RMM during cold or warm boot, RMM will return back to
+EL3 using ``RMM_BOOT_COMPLETE`` SMC with an appropriate error code. It is
+expected that EL3 will take necessary action to disable Realm world for further
+entry from NS Host on receiving an error. This will be done across all the PEs
+in the system so as to present a symmetric view to the NS Host. Any further
+warm boot by any PE should not enter RMM using the warm boot interface.
+
+.. _rmm_el3_boot_manifest:
+
+Boot Manifest
+~~~~~~~~~~~~~
+
+During cold boot, EL3 Firmware passes a memory boot manifest to RMM containing
+platform information.
+
+This boot manifest is versioned independently of the boot interface, to help
+evolve the boot manifest independent of the rest of Boot Manifest.
+The current version for the boot manifest is ``v0.1`` and the rules explained
+in :ref:`rmm_el3_ifc_versioning` apply on this version as well.
+
+The boot manifest is divided into two different components:
+
+ - Core Manifest: This is the generic parameters passed to RMM by EL3 common to all platforms.
+ - Platform data: This is defined by the platform owner and contains information specific to that platform.
+
+For the current version of the manifest, the core manifest contains a pointer
+to the platform data. EL3 must ensure that the whole boot manifest,
+including the platform data, if available, fits inside the RMM EL3 shared
+buffer.
+
+For the type specification of the RMM Boot Manifest v0.1, refer to
+:ref:`rmm_el3_manifest_struct`
+
+.. _runtime_services_and_interface:
+
+RMMM-EL3 Runtime Interface
+__________________________
+
+This section defines the RMM-EL3 runtime interface which specifies the ABI for
+EL3 services expected by RMM at runtime as well as the register save and
+restore convention between EL3 and RMM as part of RMI call handling. It is
+important to note that RMM is allowed to invoke EL3-RMM runtime interface
+services during the boot phase as well. The EL3 runtime service handling must
+not result in a world switch to another world unless specified. Both the RMM
+and EL3 are allowed to make suitable optimizations based on this assumption.
+
+If the interface requires the use of memory, then the memory references should
+be within the shared buffer communicated as part of the boot interface. See
+:ref:`rmm_cold_boot_interface` for properties of this shared buffer which both
+EL3 and RMM must adhere to.
+
+RMM-EL3 runtime service return codes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The return codes from EL3 to RMM is a 32 bit signed integer which encapsulates
+error condition as described in the following table:
+
+.. csv-table::
+ :header: "Error code", "Description", "ID"
+ :widths: 2 4 1
+
+ ``E_RMM_OK``,No errors detected,0
+ ``E_RMM_UNK``,Unknown/Generic error,-1
+ ``E_RMM_BAD_ADDR``,The value of an address used as argument was invalid,-2
+ ``E_RMM_BAD_PAS``,Incorrect PAS,-3
+ ``E_RMM_NOMEM``,Not enough memory to perform an operation,-4
+ ``E_RMM_INVAL``,The value of an argument was invalid,-5
+
+If multiple failure conditions are detected in an RMM to EL3 command, then EL3
+is allowed to return an error code corresponding to any of the failure
+conditions.
+
+RMM-EL3 runtime services
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following table summarizes the RMM runtime services that need to be
+implemented by EL3 Firmware.
+
+.. csv-table::
+ :header: "FID", "Command"
+ :widths: 2 5
+
+ 0xC40001B2,``RMM_ATTEST_GET_REALM_KEY``
+ 0xC40001B3,``RMM_ATTEST_GET_PLAT_TOKEN``
+
+RMM_ATTEST_GET_REALM_KEY command
+================================
+
+Retrieve the Realm Attestation Token Signing key from EL3.
+
+FID
+---
+
+``0xC40001B2``
+
+Input values
+------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ fid,x0,[63:0],UInt64,Command FID
+ buf_pa,x1,[63:0],Address,PA where the Realm Attestation Key must be stored by EL3. The PA must belong to the shared buffer
+ buf_size,x2,[63:0],Size,Size in bytes of the Realm Attestation Key buffer. ``bufPa + bufSize`` must lie within the shared buffer
+ ecc_curve,x3,[63:0],Enum,Type of the elliptic curve to which the requested attestation key belongs to. See :ref:`ecc_curves`
+
+Output values
+-------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ Result,x0,[63:0],Error Code,Command return status
+ keySize,x1,[63:0],Size,Size of the Realm Attestation Key
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table::
+ :header: "ID", "Condition"
+ :widths: 1 5
+
+ ``E_RMM_BAD_ADDR``,``PA`` is outside the shared buffer
+ ``E_RMM_INVAL``,``PA + BSize`` is outside the shared buffer
+ ``E_RMM_INVAL``,``Curve`` is not one of the listed in :ref:`ecc_curves`
+ ``E_RMM_UNK``,An unknown error occurred whilst processing the command
+ ``E_RMM_OK``,No errors detected
+
+.. _ecc_curves:
+
+Supported ECC Curves
+--------------------
+
+.. csv-table::
+ :header: "ID", "Curve"
+ :widths: 1 5
+
+ 0,ECC SECP384R1
+
+RMM_ATTEST_GET_PLAT_TOKEN command
+=================================
+
+Retrieve the Platform Token from EL3.
+
+FID
+---
+
+``0xC40001B3``
+
+Input values
+------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ fid,x0,[63:0],UInt64,Command FID
+ buf_pa,x1,[63:0],Address,PA of the platform attestation token. The challenge object is passed in this buffer. The PA must belong to the shared buffer
+ buf_size,x2,[63:0],Size,Size in bytes of the platform attestation token buffer. ``bufPa + bufSize`` must lie within the shared buffer
+ c_size,x3,[63:0],Size,Size in bytes of the challenge object. It corresponds to the size of one of the defined SHA algorithms
+
+Output values
+-------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ Result,x0,[63:0],Error Code,Command return status
+ tokenSize,x1,[63:0],Size,Size of the platform token
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table::
+ :header: "ID", "Condition"
+ :widths: 1 5
+
+ ``E_RMM_BAD_ADDR``,``PA`` is outside the shared buffer
+ ``E_RMM_INVAL``,``PA + BSize`` is outside the shared buffer
+ ``E_RMM_INVAL``,``CSize`` does not represent the size of a supported SHA algorithm
+ ``E_RMM_UNK``,An unknown error occurred whilst processing the command
+ ``E_RMM_OK``,No errors detected
+
+RMM-EL3 world switch register save restore convention
+_____________________________________________________
+
+As part of NS world switch, EL3 is expected to maintain a register context
+specific to each world and will save and restore the registers
+appropriately. This section captures the contract between EL3 and RMM on the
+register set to be saved and restored.
+
+EL3 must maintain a separate register context for the following:
+
+ #. General purpose registers (x0-x30) and ``sp_el0``, ``sp_el2`` stack pointers
+ #. EL2 system register context for all enabled features by EL3. These include system registers with the ``_EL2`` prefix. The EL2 physical and virtual timer registers must not be included in this.
+
+It is the responsibility of EL3 that the above registers will not be leaked to
+the NS Host and to maintain the confidentiality of the Realm World.
+
+EL3 will not save some registers as mentioned in the below list. It is the
+responsibility of RMM to ensure that these are appropriately saved if the
+Realm World makes use of them:
+
+ #. FP/SIMD registers
+ #. SVE registers
+ #. SME registers
+ #. EL1/0 registers
+
+SMCCC v1.3 allows NS world to specify whether SVE context is in use. In this
+case, RMM could choose to not save the incoming SVE context but must ensure
+to clear SVE registers if they have been used in Realm World. The same applies
+to SME registers.
+
+Types
+_____
+
+.. _rmm_el3_manifest_struct:
+
+RMM-EL3 Boot Manifest Version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The RMM-EL3 Boot Manifest structure contains platform boot information passed
+from EL3 to RMM. The width of the Boot Manifest is 128 bits
+
+.. image:: ../resources/diagrams/rmm_el3_manifest_struct.png
+
+The members of the RMM-EL3 Boot Manifest structure are shown in the following
+table:
+
+.. csv-table::
+ :header: "Name", "Range", "Type", Description
+ :widths: 2 1 1 4
+
+ ``Version Minor``,15:0,uint16_t,Version Minor part of the Boot Manifest Version.
+ ``Version Major``,30:16,uint16_t,Version Major part of the Boot Manifest Version.
+ ``RES0``,31,bit,Reserved. Set to 0.
+ ``Platform Data``,127:64,Address,Pointer to the Platform Data section of the Boot Manifest.
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 60313d5..2e3fe74 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -325,6 +325,12 @@
Cortex-A78 AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This
erratum is still open.
+For Cortex-A78C, the following errata build flags are defined :
+
+- ``ERRATA_A78C_2132064`` : This applies errata 2132064 workaround to
+ Cortex-A78C CPU. This needs to be enabled for revisions r0p1, r0p2 and
+ it is still open.
+
For Cortex-X1 CPU, the following errata build flags are defined:
- ``ERRATA_X1_1821534`` : This applies errata 1821534 workaround to Cortex-X1
@@ -498,6 +504,10 @@
- ``ERRATA_N2_2280757``: This applies errata 2280757 workaround to Neoverse-N2
CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+- ``ERRATA_N2_2388450``: This applies errata 2388450 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
+ r0p1.
+
For Cortex-X2, the following errata build flags are defined :
- ``ERRATA_X2_2002765``: This applies errata 2002765 workaround to Cortex-X2
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 2c6a005..77ee897 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -89,6 +89,8 @@
The following variables, functions and constants must be defined by the platform
for the firmware to work correctly.
+.. _platform_def_mandatory:
+
File : platform_def.h [mandatory]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1663,6 +1665,42 @@
must return 0, otherwise it must return 1. The default implementation
of this always returns 0.
+Function : bl2_plat_mboot_init() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+When the MEASURED_BOOT flag is enabled:
+
+- This function is used to initialize the backend driver(s) of measured boot.
+- On the Arm FVP port, this function is used to initialize the Event Log
+ backend driver with the Event Log buffer information (base address and
+ size) received from BL1. It results in panic on error.
+
+When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
+
+Function : bl2_plat_mboot_finish() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+When the MEASURED_BOOT flag is enabled:
+
+- This function is used to finalize the measured boot backend driver(s),
+ and also, set the information for the next bootloader component to extend
+ the measurement if needed.
+- On the Arm FVP port, this function is used to pass the Event Log buffer
+ information (base address and size) to non-secure(BL33) and trusted OS(BL32)
+ via nt_fw and tos_fw config respectively. It results in panic on error.
+
+When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
+
Boot Loader Stage 2 (BL2) at EL3
--------------------------------
@@ -1820,42 +1858,6 @@
This function returns 0 on success, a negative error code otherwise.
This function is included if SCP_BL2U_BASE is defined.
-Function : bl2_plat_mboot_init() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-When the MEASURED_BOOT flag is enabled:
-
-- This function is used to initialize the backend driver(s) of measured boot.
-- On the Arm FVP port, this function is used to initialize the Event Log
- backend driver with the Event Log buffer information (base address and
- size) received from BL1. It results in panic on error.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
-Function : bl2_plat_mboot_finish() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-When the MEASURED_BOOT flag is enabled:
-
-- This function is used to finalize the measured boot backend driver(s),
- and also, set the information for the next bootloader component to extend
- the measurement if needed.
-- On the Arm FVP port, this function is used to pass the Event Log buffer
- information (base address and size) to non-secure(BL33) and trusted OS(BL32)
- via nt_fw and tos_fw config respectively. It results in panic on error.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
Boot Loader Stage 3-1 (BL31)
----------------------------
@@ -2017,7 +2019,7 @@
(that was copied during ``bl31_early_platform_setup()``) if the image exists. It
should return NULL otherwise.
-Function : plat_get_cca_attest_token() [mandatory when ENABLE_RME == 1]
+Function : plat_rmmd_get_cca_attest_token() [mandatory when ENABLE_RME == 1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
@@ -2043,8 +2045,8 @@
The function returns 0 on success, -EINVAL on failure.
-Function : plat_get_cca_realm_attest_key() [mandatory when ENABLE_RME == 1]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Function : plat_rmmd_get_cca_realm_attest_key() [mandatory when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
@@ -2069,6 +2071,31 @@
The function returns 0 on success, -EINVAL on failure.
+Function : plat_rmmd_get_el3_rmm_shared_mem() [when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uintptr_t *
+ Return : size_t
+
+This function returns the size of the shared area between EL3 and RMM (or 0 on
+failure). A pointer to the shared area (or a NULL pointer on failure) is stored
+in the pointer passed as argument.
+
+Function : plat_rmmd_load_manifest() [when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments : rmm_manifest_t *manifest
+ Return : int
+
+When ENABLE_RME is enabled, this function populates a boot manifest for the
+RMM image and stores it in the area specified by manifest.
+
+When ENABLE_RME is disabled, this function is not used.
+
Function : bl31_plat_enable_mmu [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 5d575d8..81c55a5 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -7,6 +7,7 @@
It may possible to build |TF-A| with combinations of software packages that are
different from those listed below, however only the software described in this
document can be officially supported.
+
Build Host
----------
diff --git a/docs/resources/diagrams/Makefile b/docs/resources/diagrams/Makefile
index 7f583b5..4e65569 100644
--- a/docs/resources/diagrams/Makefile
+++ b/docs/resources/diagrams/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -61,7 +61,19 @@
xlat_align_layers = "bg,translations"
xlat_align_opts =
-all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG)
+RMM_DIA = rmm_cold_boot_generic.dia
+RMM_PNG = rmm_cold_boot_generic.png
+
+rmm_cold_boot_generic_layers = "background"
+rmm_cold_boot_generic_opts =
+
+RMM_EL3_MANIFEST_DIA = rmm_el3_manifest_struct.dia
+RMM_EL3_MANIFEST_PNG = rmm_el3_manifest_struct.png
+
+rmm_el3_manifest_struct_layers = "Background"
+rmm_el3_manifest_struct_opts =
+
+all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG) $(RMM_PNG) $(RMM_EL3_MANIFEST_PNG)
$(RESET_PNGS):$(RESET_DIA)
$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
@@ -72,3 +84,9 @@
$(XLAT_PNG):$(XLAT_DIA)
$(call generate_image,$($(patsubst %.png,%_layers,$@)),$(patsubst %.png,%.svg,$@),svg,$($(patsubst %.png,%_opts,$@)),$<)
inkscape -z $(patsubst %.png,%.svg,$@) -e $@ -d 45
+
+$(RMM_PNG):$(RMM_DIA)
+ $(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
+
+$(RMM_EL3_MANIFEST_PNG):$(RMM_EL3_MANIFEST_DIA)
+ $(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
diff --git a/docs/resources/diagrams/rmm_cold_boot_generic.dia b/docs/resources/diagrams/rmm_cold_boot_generic.dia
new file mode 100644
index 0000000..739a1df
--- /dev/null
+++ b/docs/resources/diagrams/rmm_cold_boot_generic.dia
Binary files differ
diff --git a/docs/resources/diagrams/rmm_cold_boot_generic.png b/docs/resources/diagrams/rmm_cold_boot_generic.png
new file mode 100644
index 0000000..df4c1ba
--- /dev/null
+++ b/docs/resources/diagrams/rmm_cold_boot_generic.png
Binary files differ
diff --git a/docs/resources/diagrams/rmm_el3_manifest_struct.dia b/docs/resources/diagrams/rmm_el3_manifest_struct.dia
new file mode 100644
index 0000000..7b7a9c2
--- /dev/null
+++ b/docs/resources/diagrams/rmm_el3_manifest_struct.dia
Binary files differ
diff --git a/docs/resources/diagrams/rmm_el3_manifest_struct.png b/docs/resources/diagrams/rmm_el3_manifest_struct.png
new file mode 100644
index 0000000..8b5776c
--- /dev/null
+++ b/docs/resources/diagrams/rmm_el3_manifest_struct.png
Binary files differ
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 7db6c0b..47ff26b 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -225,8 +225,7 @@
}
continue;
}
- while ((mmio_read_32(base + HCS) & HCS_DP) == 0)
- ;
+ assert((mmio_read_32(base + HCS) & HCS_DP) == 0);
data = mmio_read_32(base + IS);
if (data & UFS_INT_ULSS)
mmio_write_32(base + IS, UFS_INT_ULSS);
@@ -482,9 +481,7 @@
mmio_write_32(ufs_params.reg_base + IS, ~0);
mmio_write_32(ufs_params.reg_base + UTRLRSR, 1);
- do {
- data = mmio_read_32(ufs_params.reg_base + UTRLRSR);
- } while (data == 0);
+ assert(mmio_read_32(ufs_params.reg_base + UTRLRSR) == 1);
data = UTRIACR_IAEN | UTRIACR_CTR | UTRIACR_IACTH(0x1F) |
UTRIACR_IATOVAL(0xFF);
diff --git a/fdts/stm32mp131.dtsi b/fdts/stm32mp131.dtsi
index decd812..e4d9d3b 100644
--- a/fdts/stm32mp131.dtsi
+++ b/fdts/stm32mp131.dtsi
@@ -383,7 +383,7 @@
status = "disabled";
};
- ddr: ddr@5a003000{
+ ddr: ddr@5a003000 {
compatible = "st,stm32mp13-ddr";
reg = <0x5a003000 0x550>, <0x5a004000 0x234>;
clocks = <&rcc AXIDCG>,
diff --git a/fdts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi
new file mode 100644
index 0000000..ff184c2
--- /dev/null
+++ b/fdts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2020, DH electronics - All Rights Reserved
+ *
+ * STM32MP15xx DHSOM configuration
+ * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology.
+ * Reference used W634GU6NB15I from Winbond
+ *
+ * DDR type / Platform DDR3/3L
+ * freq 533MHz
+ * width 32
+ * datasheet 0 = W634GU6NB15I / DDR3-1333
+ * DDR density 8
+ * timing mode optimized
+ * address mapping : RBC
+ * Tc > + 85C : J
+ */
+
+#define DDR_MEM_NAME "DDR3L 32bits 2x4Gb 533MHz"
+#define DDR_MEM_SPEED 533000
+#define DDR_MEM_SIZE 0x40000000
+
+#define DDR_MSTR 0x00040401
+#define DDR_MRCTRL0 0x00000010
+#define DDR_MRCTRL1 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00800000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00400010
+#define DDR_HWLPCTL 0x00000000
+#define DDR_RFSHCTL0 0x00210000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x0040008B
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_DRAMTMG0 0x121B1214
+#define DDR_DRAMTMG1 0x000A041C
+#define DDR_DRAMTMG2 0x0608090F
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x08040608
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020002
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x00001005
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_ZQCTL0 0xC2000040
+#define DDR_DFITMG0 0x02060105
+#define DDR_DFITMG1 0x00000202
+#define DDR_DFILPCFG0 0x07000000
+#define DDR_DFIUPD0 0xC0400003
+#define DDR_DFIUPD1 0x00000000
+#define DDR_DFIUPD2 0x00000000
+#define DDR_DFIPHYMSTR 0x00000000
+#define DDR_ODTCFG 0x06000600
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x00000C01
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x01000001
+#define DDR_PERFLPR1 0x08000200
+#define DDR_PERFWR1 0x08000400
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000010
+#define DDR_PCFGR_0 0x00010000
+#define DDR_PCFGW_0 0x00000000
+#define DDR_PCFGQOS0_0 0x02100C03
+#define DDR_PCFGQOS1_0 0x00800100
+#define DDR_PCFGWQOS0_0 0x01100C03
+#define DDR_PCFGWQOS1_0 0x01000200
+#define DDR_PCFGR_1 0x00010000
+#define DDR_PCFGW_1 0x00000000
+#define DDR_PCFGQOS0_1 0x02100C03
+#define DDR_PCFGQOS1_1 0x00800040
+#define DDR_PCFGWQOS0_1 0x01100C03
+#define DDR_PCFGWQOS1_1 0x01000200
+#define DDR_ADDRMAP1 0x00080808
+#define DDR_ADDRMAP2 0x00000000
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x07070707
+#define DDR_ADDRMAP6 0x0F070707
+#define DDR_ADDRMAP9 0x00000000
+#define DDR_ADDRMAP10 0x00000000
+#define DDR_ADDRMAP11 0x00000000
+#define DDR_PGCR 0x01442E02
+#define DDR_PTR0 0x0022AA5B
+#define DDR_PTR1 0x04841104
+#define DDR_PTR2 0x042DA068
+#define DDR_ACIOCR 0x10400812
+#define DDR_DXCCR 0x00000C40
+#define DDR_DSGCR 0xF200011F
+#define DDR_DCR 0x0000000B
+#define DDR_DTPR0 0x38D488D0
+#define DDR_DTPR1 0x098B00D8
+#define DDR_DTPR2 0x10023600
+#define DDR_MR0 0x00000840
+#define DDR_MR1 0x00000000
+#define DDR_MR2 0x00000248
+#define DDR_MR3 0x00000000
+#define DDR_ODTCR 0x00010000
+#define DDR_ZQ0CR1 0x00000038
+#define DDR_DX0GCR 0x0000CE81
+#define DDR_DX1GCR 0x0000CE81
+#define DDR_DX2GCR 0x0000CE81
+#define DDR_DX3GCR 0x0000CE81
+
+#include "stm32mp15-ddr.dtsi"
diff --git a/fdts/stm32mp15-fw-config.dtsi b/fdts/stm32mp15-fw-config.dtsi
index 8aece28..d583672 100644
--- a/fdts/stm32mp15-fw-config.dtsi
+++ b/fdts/stm32mp15-fw-config.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
*/
#include <common/tbbr/tbbr_img_def.h>
@@ -14,7 +14,7 @@
#define DDR_NS_BASE STM32MP_DDR_BASE
#ifdef AARCH32_SP_OPTEE
-/* OP-TEE reserved shared memory: located at DDR top */
+/* OP-TEE reserved shared memory: located at DDR top or null size */
#define DDR_SHARE_SIZE STM32MP_DDR_SHMEM_SIZE
#define DDR_SHARE_BASE (STM32MP_DDR_BASE + (DDR_SIZE - DDR_SHARE_SIZE))
/* OP-TEE secure memory: located right below OP-TEE reserved shared memory */
@@ -70,8 +70,11 @@
memory-ranges = <
DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR
DDR_SEC_BASE DDR_SEC_SIZE TZC_REGION_S_RDWR 0
+#if STM32MP15_OPTEE_RSV_SHM
DDR_SHARE_BASE DDR_SHARE_SIZE TZC_REGION_S_NONE
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)>;
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)
+#endif
+ >;
#else
memory-ranges = <
DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR>;
diff --git a/fdts/stm32mp15-pinctrl.dtsi b/fdts/stm32mp15-pinctrl.dtsi
index d74dc2b..1b5fbc6 100644
--- a/fdts/stm32mp15-pinctrl.dtsi
+++ b/fdts/stm32mp15-pinctrl.dtsi
@@ -114,7 +114,7 @@
drive-push-pull;
bias-pull-up;
};
- pins2{
+ pins2 {
pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
bias-pull-up;
};
diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi
index 20071fe..575d61e 100644
--- a/fdts/stm32mp151.dtsi
+++ b/fdts/stm32mp151.dtsi
@@ -360,7 +360,7 @@
status = "disabled";
};
- ddr: ddr@5a003000{
+ ddr: ddr@5a003000 {
compatible = "st,stm32mp1-ddr";
reg = <0x5A003000 0x550 0x5A004000 0x234>;
clocks = <&rcc AXIDCG>,
diff --git a/fdts/stm32mp157c-dhcom-pdk2-fw-config.dts b/fdts/stm32mp157c-dhcom-pdk2-fw-config.dts
new file mode 100644
index 0000000..6a5a192
--- /dev/null
+++ b/fdts/stm32mp157c-dhcom-pdk2-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (c) 2022 DH electronics GmbH
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157c-dhcom-pdk2.dts b/fdts/stm32mp157c-dhcom-pdk2.dts
new file mode 100644
index 0000000..370a69a
--- /dev/null
+++ b/fdts/stm32mp157c-dhcom-pdk2.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2019-2020 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2022 DH electronics GmbH
+ *
+ * DHCOM STM32MP1 variant:
+ * DHCM-STM32MP157C-C065-R102-F0819-SPI-E2-CAN2-SDR104-RTC-WBT-T-DSI-I-01D2
+ * DHCOM PCB number: 587-200 or newer
+ * PDK2 PCB number: 516-400 or newer
+ */
+/dts-v1/;
+
+#include "stm32mp157.dtsi"
+#include "stm32mp15xc.dtsi"
+#include "stm32mp15xx-dhcom-som.dtsi"
+#include "stm32mp15xx-dhcom-pdk2.dtsi"
+
+/ {
+ model = "DH electronics STM32MP157C DHCOM Premium Developer Kit (2)";
+ compatible = "dh,stm32mp157c-dhcom-pdk2", "dh,stm32mp157c-dhcom-som",
+ "st,stm32mp157";
+};
+
+&cryp1 {
+ status = "okay";
+};
diff --git a/fdts/stm32mp15xx-dhcom-pdk2.dtsi b/fdts/stm32mp15xx-dhcom-pdk2.dtsi
new file mode 100644
index 0000000..1ffc60d
--- /dev/null
+++ b/fdts/stm32mp15xx-dhcom-pdk2.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2019-2020 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2022 DH electronics GmbH
+ */
+
+/ {
+ aliases {
+ serial0 = &uart4;
+ serial1 = &usart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&usart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usart3_pins_a>;
+ status = "okay";
+};
+
+&usbotg_hs {
+ dr_mode = "otg";
+ pinctrl-0 = <&usbotg_hs_pins_a>;
+ pinctrl-names = "default";
+ phy-names = "usb2-phy";
+ phys = <&usbphyc_port1 0>;
+ vbus-supply = <&vbus_otg>;
+ status = "okay";
+};
+
+&usbphyc {
+ status = "okay";
+};
+
+&usbphyc_port0 {
+ phy-supply = <&vdd_usb>;
+};
+
+&usbphyc_port1 {
+ phy-supply = <&vdd_usb>;
+};
diff --git a/fdts/stm32mp15xx-dhcom-som.dtsi b/fdts/stm32mp15xx-dhcom-som.dtsi
new file mode 100644
index 0000000..3021ef8
--- /dev/null
+++ b/fdts/stm32mp15xx-dhcom-som.dtsi
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2019-2020 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2022 DH electronics GmbH
+ */
+
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxaa-pinctrl.dtsi"
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include "stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi"
+
+/ {
+ memory@c0000000 {
+ device_type = "memory";
+ reg = <0xC0000000 0x40000000>;
+ };
+};
+
+&bsec {
+ board_id: board_id@ec {
+ reg = <0xec 0x4>;
+ st,non-secure-otp;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vddcore>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcore>;
+};
+
+&hash1 {
+ status = "okay";
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins_a>;
+ i2c-scl-rising-time-ns = <185>;
+ i2c-scl-falling-time-ns = <20>;
+ status = "okay";
+
+ pmic: stpmic@33 {
+ compatible = "st,stpmic1";
+ reg = <0x33>;
+ interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "okay";
+
+ regulators {
+ compatible = "st,stpmic1-regulators";
+ ldo1-supply = <&v3v3>;
+ ldo2-supply = <&v3v3>;
+ ldo3-supply = <&vdd_ddr>;
+ ldo5-supply = <&v3v3>;
+ ldo6-supply = <&v3v3>;
+ pwr_sw1-supply = <&bst_out>;
+ pwr_sw2-supply = <&bst_out>;
+
+ vddcore: buck1 {
+ regulator-name = "vddcore";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd_ddr: buck2 {
+ regulator-name = "vdd_ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd: buck3 {
+ regulator-name = "vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ st,mask-reset;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ v3v3: buck4 {
+ regulator-name = "v3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ regulator-initial-mode = <0>;
+ };
+
+ vdda: ldo1 {
+ regulator-name = "vdda";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-always-on;
+ };
+
+ v2v8: ldo2 {
+ regulator-name = "v2v8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vtt_ddr: ldo3 {
+ regulator-name = "vtt_ddr";
+ regulator-always-on;
+ regulator-over-current-protection;
+ st,regulator-sink-source;
+ };
+
+ vdd_usb: ldo4 {
+ regulator-name = "vdd_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_sd: ldo5 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ };
+
+ v1v8: ldo6 {
+ regulator-name = "v1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vref_ddr: vref_ddr {
+ regulator-name = "vref_ddr";
+ regulator-always-on;
+ };
+
+ bst_out: boost {
+ regulator-name = "bst_out";
+ };
+
+ vbus_otg: pwr_sw1 {
+ regulator-name = "vbus_otg";
+ };
+
+ vbus_sw: pwr_sw2 {
+ regulator-name = "vbus_sw";
+ regulator-active-discharge = <1>;
+ };
+ };
+ };
+};
+
+&iwdg2 {
+ timeout-sec = <32>;
+ status = "okay";
+ secure-status = "okay";
+};
+
+&pwr_regulators {
+ vdd-supply = <&vdd>;
+ vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>;
+ reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <108000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&rcc {
+ secure-status = "disabled";
+ st,clksrc = <
+ CLK_MPU_PLL1P
+ CLK_AXI_PLL2P
+ CLK_MCU_PLL3P
+ CLK_PLL12_HSE
+ CLK_PLL3_HSE
+ CLK_PLL4_HSE
+ CLK_RTC_LSE
+ CLK_MCO1_DISABLED
+ CLK_MCO2_PLL4P
+ >;
+
+ st,clkdiv = <
+ 1 /*MPU*/
+ 0 /*AXI*/
+ 0 /*MCU*/
+ 1 /*APB1*/
+ 1 /*APB2*/
+ 1 /*APB3*/
+ 1 /*APB4*/
+ 2 /*APB5*/
+ 23 /*RTC*/
+ 0 /*MCO1*/
+ 1 /*MCO2*/
+ >;
+
+ st,pkcs = <
+ CLK_CKPER_HSE
+ CLK_FMC_ACLK
+ CLK_QSPI_ACLK
+ CLK_ETH_PLL4P
+ CLK_SDMMC12_PLL4P
+ CLK_DSI_DSIPLL
+ CLK_STGEN_HSE
+ CLK_USBPHY_HSE
+ CLK_SPI2S1_PLL3Q
+ CLK_SPI2S23_PLL3Q
+ CLK_SPI45_HSI
+ CLK_SPI6_HSI
+ CLK_I2C46_HSI
+ CLK_SDMMC3_PLL4P
+ CLK_USBO_USBPHY
+ CLK_ADC_CKPER
+ CLK_CEC_LSE
+ CLK_I2C12_HSI
+ CLK_I2C35_HSI
+ CLK_UART1_HSI
+ CLK_UART24_HSI
+ CLK_UART35_HSI
+ CLK_UART6_HSI
+ CLK_UART78_HSI
+ CLK_SPDIF_PLL4P
+ CLK_FDCAN_PLL4R
+ CLK_SAI1_PLL3Q
+ CLK_SAI2_PLL3Q
+ CLK_SAI3_PLL3Q
+ CLK_SAI4_PLL3Q
+ CLK_RNG1_LSI
+ CLK_RNG2_LSI
+ CLK_LPTIM1_PCLK1
+ CLK_LPTIM23_PCLK3
+ CLK_LPTIM45_LSE
+ >;
+
+ /* VCO = 1300.0 MHz => P = 650 (CPU) */
+ pll1: st,pll@0 {
+ compatible = "st,stm32mp1-pll";
+ reg = <0>;
+ cfg = <2 80 0 0 0 PQR(1,0,0)>;
+ frac = <0x800>;
+ };
+
+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
+ pll2: st,pll@1 {
+ compatible = "st,stm32mp1-pll";
+ reg = <1>;
+ cfg = <2 65 1 0 0 PQR(1,1,1)>;
+ frac = <0x1400>;
+ };
+
+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
+ pll3: st,pll@2 {
+ compatible = "st,stm32mp1-pll";
+ reg = <2>;
+ cfg = <1 33 1 16 36 PQR(1,1,1)>;
+ frac = <0x1a04>;
+ };
+
+ /* VCO = 600.0 MHz => P = 50, Q = 50, R = 50 */
+ pll4: st,pll@3 {
+ compatible = "st,stm32mp1-pll";
+ reg = <3>;
+ cfg = <1 49 5 11 11 PQR(1,1,1)>;
+ };
+};
+
+&rng1 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sdmmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
+ disable-wp;
+ st,sig-dir;
+ st,neg-edge;
+ bus-width = <4>;
+ vmmc-supply = <&vdd_sd>;
+ status = "okay";
+};
+
+&sdmmc1_b4_pins_a {
+ /*
+ * SD bus pull-up resistors:
+ * - optional on SoMs with SD voltage translator
+ * - mandatory on SoMs without SD voltage translator
+ */
+ pins1 {
+ bias-pull-up;
+ };
+ pins2 {
+ bias-pull-up;
+ };
+};
+
+&sdmmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
+ non-removable;
+ no-sd;
+ no-sdio;
+ st,neg-edge;
+ bus-width = <8>;
+ vmmc-supply = <&v3v3>;
+ vqmmc-supply = <&v3v3>;
+ mmc-ddr-3_3v;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins_a>;
+ status = "okay";
+};
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index 05eb46a..74e529d 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -33,11 +33,11 @@
st,digbypass;
};
-&cpu0{
+&cpu0 {
cpu-supply = <&vddcore>;
};
-&cpu1{
+&cpu1 {
cpu-supply = <&vddcore>;
};
diff --git a/fdts/stm32mp15xx-osd32.dtsi b/fdts/stm32mp15xx-osd32.dtsi
index ca67235..c7ddc92 100644
--- a/fdts/stm32mp15xx-osd32.dtsi
+++ b/fdts/stm32mp15xx-osd32.dtsi
@@ -167,11 +167,11 @@
st,digbypass;
};
-&cpu0{
+&cpu0 {
cpu-supply = <&vddcore>;
};
-&cpu1{
+&cpu1 {
cpu-supply = <&vddcore>;
};
diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h
index c35e9be..9531bdb 100644
--- a/include/common/fdt_fixup.h
+++ b/include/common/fdt_fixup.h
@@ -32,5 +32,7 @@
int fdt_add_cpu_idle_states(void *dtb, const struct psci_cpu_idle_state *state);
int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, uintptr_t gicr_base,
unsigned int gicr_frame_size);
+int fdt_set_mac_address(void *dtb, unsigned int ethernet_idx,
+ const uint8_t *mac_addr);
#endif /* FDT_FIXUP_H */
diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h
index 0a19f8a..f4c4fb8 100644
--- a/include/drivers/measured_boot/event_log/event_log.h
+++ b/include/drivers/measured_boot/event_log/event_log.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -78,6 +78,14 @@
#define EVLOG_TB_FW_CONFIG_STRING "TB_FW_CONFIG"
#define EVLOG_TOS_FW_CONFIG_STRING "TOS_FW_CONFIG"
#define EVLOG_RMM_STRING "RMM"
+#define EVLOG_SP1_STRING "SP1"
+#define EVLOG_SP2_STRING "SP2"
+#define EVLOG_SP3_STRING "SP3"
+#define EVLOG_SP4_STRING "SP4"
+#define EVLOG_SP5_STRING "SP5"
+#define EVLOG_SP6_STRING "SP6"
+#define EVLOG_SP7_STRING "SP7"
+#define EVLOG_SP8_STRING "SP8"
typedef struct {
unsigned int id;
diff --git a/include/lib/cpus/aarch64/a64fx.h b/include/lib/cpus/aarch64/a64fx.h
new file mode 100644
index 0000000..b7342b0
--- /dev/null
+++ b/include/lib/cpus/aarch64/a64fx.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022, Fujitsu Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef A64FX_H
+#define A64FX_H
+
+#include <lib/utils_def.h>
+
+/* A64FX midr for revision 0 */
+#define A64FX_MIDR U(0x461f0010)
+
+#endif /* A64FX_H */
diff --git a/include/lib/cpus/aarch64/cortex_a78c.h b/include/lib/cpus/aarch64/cortex_a78c.h
index b1945ed..39e2adf 100644
--- a/include/lib/cpus/aarch64/cortex_a78c.h
+++ b/include/lib/cpus/aarch64/cortex_a78c.h
@@ -17,6 +17,8 @@
* CPU Extended Control register specific definitions.
******************************************************************************/
#define CORTEX_A78C_CPUECTLR_EL1 S3_0_C15_C1_4
+#define CORTEX_A78C_CPUECTLR_EL1_BIT6 (ULL(1) << 6)
+#define CORTEX_A78C_CPUECTLR_EL1_BIT7 (ULL(1) << 7)
/*******************************************************************************
* CPU Power Control register specific definitions
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index 0452b39..5d41a13 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -38,6 +38,7 @@
******************************************************************************/
#define NEOVERSE_N2_CPUACTLR2_EL1 S3_0_C15_C1_1
#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2)
+#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_40 (ULL(1) << 40)
/*******************************************************************************
* CPU Auxiliary Control register 5 specific definitions.
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index caab14e..ab0e4ff 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -79,6 +79,7 @@
* - SCP TZC DRAM: If present, DRAM reserved for SCP use
* - L1 GPT DRAM: Reserved for L1 GPT if RME is enabled
* - REALM DRAM: Reserved for Realm world if RME is enabled
+ * - TF-A <-> RMM SHARED: Area shared for communication between TF-A and RMM
* - AP TZC DRAM: The remaining TZC secured DRAM reserved for AP use
*
* RME enabled(64MB) RME not enabled(16MB)
@@ -87,11 +88,16 @@
* | AP TZC (~28MB) | | AP TZC (~14MB) |
* -------------------- -------------------
* | | | |
- * | REALM (32MB) | | EL3 TZC (2MB) |
- * -------------------- -------------------
- * | | | |
- * | EL3 TZC (3MB) | | SCP TZC |
- * -------------------- 0xFFFF_FFFF-------------------
+ * | REALM (RMM) | | EL3 TZC (2MB) |
+ * | (32MB - 4KB) | -------------------
+ * -------------------- | |
+ * | | | SCP TZC |
+ * | TF-A <-> RMM | 0xFFFF_FFFF-------------------
+ * | SHARED (4KB) |
+ * --------------------
+ * | |
+ * | EL3 TZC (3MB) |
+ * --------------------
* | L1 GPT + SCP TZC |
* | (~1MB) |
* 0xFFFF_FFFF --------------------
@@ -106,12 +112,17 @@
*/
#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00300000) /* 3MB */
#define ARM_L1_GPT_SIZE UL(0x00100000) /* 1MB */
-#define ARM_REALM_SIZE UL(0x02000000) /* 32MB */
+
+/* 32MB - ARM_EL3_RMM_SHARED_SIZE */
+#define ARM_REALM_SIZE (UL(0x02000000) - \
+ ARM_EL3_RMM_SHARED_SIZE)
+#define ARM_EL3_RMM_SHARED_SIZE (PAGE_SIZE) /* 4KB */
#else
#define ARM_TZC_DRAM1_SIZE UL(0x01000000) /* 16MB */
#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00200000) /* 2MB */
#define ARM_L1_GPT_SIZE UL(0)
#define ARM_REALM_SIZE UL(0)
+#define ARM_EL3_RMM_SHARED_SIZE UL(0)
#endif /* ENABLE_RME */
#define ARM_SCP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \
@@ -128,13 +139,20 @@
#define ARM_L1_GPT_END (ARM_L1_GPT_ADDR_BASE + \
ARM_L1_GPT_SIZE - 1U)
-#define ARM_REALM_BASE (ARM_DRAM1_BASE + \
- ARM_DRAM1_SIZE - \
- (ARM_SCP_TZC_DRAM1_SIZE + \
- ARM_EL3_TZC_DRAM1_SIZE + \
- ARM_REALM_SIZE + \
- ARM_L1_GPT_SIZE))
+#define ARM_REALM_BASE (ARM_EL3_RMM_SHARED_BASE - \
+ ARM_REALM_SIZE)
+
#define ARM_REALM_END (ARM_REALM_BASE + ARM_REALM_SIZE - 1U)
+
+#define ARM_EL3_RMM_SHARED_BASE (ARM_DRAM1_BASE + \
+ ARM_DRAM1_SIZE - \
+ (ARM_SCP_TZC_DRAM1_SIZE + \
+ ARM_L1_GPT_SIZE + \
+ ARM_EL3_RMM_SHARED_SIZE + \
+ ARM_EL3_TZC_DRAM1_SIZE))
+
+#define ARM_EL3_RMM_SHARED_END (ARM_EL3_RMM_SHARED_BASE + \
+ ARM_EL3_RMM_SHARED_SIZE - 1U)
#endif /* ENABLE_RME */
#define ARM_EL3_TZC_DRAM1_BASE (ARM_SCP_TZC_DRAM1_BASE - \
@@ -148,6 +166,7 @@
#define ARM_AP_TZC_DRAM1_SIZE (ARM_TZC_DRAM1_SIZE - \
(ARM_SCP_TZC_DRAM1_SIZE + \
ARM_EL3_TZC_DRAM1_SIZE + \
+ ARM_EL3_RMM_SHARED_SIZE + \
ARM_REALM_SIZE + \
ARM_L1_GPT_SIZE))
#define ARM_AP_TZC_DRAM1_END (ARM_AP_TZC_DRAM1_BASE + \
@@ -197,6 +216,7 @@
#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE
#define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \
ARM_TZC_DRAM1_SIZE)
+
#define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \
ARM_NS_DRAM1_SIZE - 1U)
#ifdef PLAT_ARM_DRAM1_BASE
@@ -290,9 +310,14 @@
MT_MEMORY | MT_RW | MT_SECURE)
#if ENABLE_RME
+/*
+ * We add the EL3_RMM_SHARED size to RMM mapping to map the region as a block.
+ * Else we end up requiring more pagetables in BL2 for ROMLIB build.
+ */
#define ARM_MAP_RMM_DRAM MAP_REGION_FLAT( \
PLAT_ARM_RMM_BASE, \
- PLAT_ARM_RMM_SIZE, \
+ (PLAT_ARM_RMM_SIZE + \
+ ARM_EL3_RMM_SHARED_SIZE), \
MT_MEMORY | MT_RW | MT_REALM)
@@ -301,6 +326,12 @@
ARM_L1_GPT_SIZE, \
MT_MEMORY | MT_RW | EL3_PAS)
+#define ARM_MAP_EL3_RMM_SHARED_MEM \
+ MAP_REGION_FLAT( \
+ ARM_EL3_RMM_SHARED_BASE, \
+ ARM_EL3_RMM_SHARED_SIZE, \
+ MT_MEMORY | MT_RW | MT_REALM)
+
#endif /* ENABLE_RME */
/*
@@ -595,6 +626,8 @@
#if ENABLE_RME
#define RMM_BASE (ARM_REALM_BASE)
#define RMM_LIMIT (RMM_BASE + ARM_REALM_SIZE)
+#define RMM_SHARED_BASE (ARM_EL3_RMM_SHARED_BASE)
+#define RMM_SHARED_SIZE (ARM_EL3_RMM_SHARED_SIZE)
#endif
#if !defined(__aarch64__) || JUNO_AARCH32_EL3_RUNTIME
diff --git a/include/plat/arm/common/arm_pas_def.h b/include/plat/arm/common/arm_pas_def.h
index 4fee41b..c199302 100644
--- a/include/plat/arm/common/arm_pas_def.h
+++ b/include/plat/arm/common/arm_pas_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -61,6 +61,10 @@
#define ARM_PAS_2_BASE (ARM_PAS_1_BASE + ARM_PAS_1_SIZE)
#define ARM_PAS_2_SIZE (ARM_NS_DRAM1_SIZE)
+/* Shared area between EL3 and RMM */
+#define ARM_PAS_SHARED_BASE (ARM_EL3_RMM_SHARED_BASE)
+#define ARM_PAS_SHARED_SIZE (ARM_EL3_RMM_SHARED_SIZE)
+
/* Secure TZC region */
#define ARM_PAS_3_BASE (ARM_AP_TZC_DRAM1_BASE)
#define ARM_PAS_3_SIZE (ARM_AP_TZC_DRAM1_SIZE)
@@ -76,8 +80,13 @@
ARM_PAS_3_SIZE, \
GPT_GPI_SECURE)
+/*
+ * REALM and Shared area share the same PAS, so consider them a single
+ * PAS region to configure in GPT.
+ */
#define ARM_PAS_REALM GPT_MAP_REGION_GRANULE(ARM_REALM_BASE, \
- ARM_REALM_SIZE, \
+ (ARM_PAS_SHARED_SIZE + \
+ ARM_REALM_SIZE), \
GPT_GPI_REALM)
#define ARM_PAS_EL3_DRAM GPT_MAP_REGION_GRANULE(ARM_EL3_TZC_DRAM1_BASE, \
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 9618700..d060332 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -57,7 +57,8 @@
{ARM_EL3_TZC_DRAM1_BASE, ARM_L1_GPT_END, TZC_REGION_S_RDWR, 0}, \
{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}, \
- {ARM_REALM_BASE, ARM_REALM_END, ARM_TZC_NS_DRAM_S_ACCESS, \
+ /* Realm and Shared area share the same PAS */ \
+ {ARM_REALM_BASE, ARM_EL3_RMM_SHARED_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}, \
{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index b62a631..184606a 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -13,6 +13,9 @@
#if defined(SPD_spmd)
#include <services/spm_core_manifest.h>
#endif
+#if ENABLE_RME
+#include <services/rmm_core_manifest.h>
+#endif
#if TRNG_SUPPORT
#include "plat_trng.h"
#endif
@@ -305,10 +308,14 @@
/*******************************************************************************
* Mandatory BL31 functions when ENABLE_RME=1
******************************************************************************/
-int plat_get_cca_attest_token(uintptr_t buf, size_t *len,
- uintptr_t hash, size_t hash_size);
-int plat_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
- unsigned int type);
+#if ENABLE_RME
+int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
+ uintptr_t hash, size_t hash_size);
+int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
+ unsigned int type);
+size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
+int plat_rmmd_load_manifest(rmm_manifest_t *manifest);
+#endif
/*******************************************************************************
* Optional BL31 functions (may be overridden)
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
new file mode 100644
index 0000000..2f25858
--- /dev/null
+++ b/include/services/rmm_core_manifest.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RMM_CORE_MANIFEST_H
+#define RMM_CORE_MANIFEST_H
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/cassert.h>
+
+#define RMMD_MANIFEST_VERSION_MAJOR U(0)
+#define RMMD_MANIFEST_VERSION_MINOR U(1)
+
+/*
+ * Manifest version encoding:
+ * - Bit[31] RES0
+ * - Bits [30:16] Major version
+ * - Bits [15:0] Minor version
+ */
+#define _RMMD_MANIFEST_VERSION(_major, _minor) \
+ ((((_major) & 0x7FFF) << 16) | ((_minor) & 0xFFFF))
+
+#define RMMD_MANIFEST_VERSION _RMMD_MANIFEST_VERSION( \
+ RMMD_MANIFEST_VERSION_MAJOR, \
+ RMMD_MANIFEST_VERSION_MINOR)
+
+#define RMMD_GET_MANIFEST_VERSION_MAJOR(_version) \
+ ((_version >> 16) & 0x7FFF)
+
+#define RMMD_GET_MANIFEST_VERSION_MINOR(_version) \
+ (_version & 0xFFFF)
+
+/* Boot manifest core structure as per v0.1 */
+typedef struct rmm_manifest {
+ uint32_t version; /* Manifest version */
+ uintptr_t plat_data; /* Manifest platform data */
+} rmm_manifest_t;
+
+CASSERT(offsetof(rmm_manifest_t, version) == 0,
+ rmm_manifest_t_version_unaligned);
+CASSERT(offsetof(rmm_manifest_t, plat_data) == 8,
+ rmm_manifest_t_plat_data_unaligned);
+
+#endif /* RMM_CORE_MANIFEST_H */
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index 156d89c..6adc5f3 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.h
@@ -40,7 +40,17 @@
/* 0x18F */
#define RMMD_RMI_REQ_COMPLETE SMC64_RMI_FID(U(0x3F))
-/* The SMC in the range 0x8400 0190 - 0x8400 01AF are reserved for RSIs.*/
+/* RMM_BOOT_COMPLETE arg0 error codes */
+#define E_RMM_BOOT_SUCCESS (0)
+#define E_RMM_BOOT_UNKNOWN (-1)
+#define E_RMM_BOOT_VERSION_MISMATCH (-2)
+#define E_RMM_BOOT_CPUS_OUT_OF_RANGE (-3)
+#define E_RMM_BOOT_CPU_ID_OUT_OF_RANGE (-4)
+#define E_RMM_BOOT_INVALID_SHARED_BUFFER (-5)
+#define E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED (-6)
+#define E_RMM_BOOT_MANIFEST_DATA_ERROR (-7)
+
+/* The SMC in the range 0x8400 0191 - 0x8400 01AF are reserved for RSIs.*/
/*
* EL3 - RMM SMCs used for requesting RMMD services. These SMCs originate in Realm
@@ -74,12 +84,12 @@
#define RMMD_GTSI_UNDELEGATE SMC64_RMMD_EL3_FID(U(1))
/* Return error codes from RMM-EL3 SMCs */
-#define RMMD_OK 0
-#define RMMD_ERR_BAD_ADDR -2
-#define RMMD_ERR_BAD_PAS -3
-#define RMMD_ERR_NOMEM -4
-#define RMMD_ERR_INVAL -5
-#define RMMD_ERR_UNK -6
+#define E_RMM_OK 0
+#define E_RMM_UNK -1
+#define E_RMM_BAD_ADDR -2
+#define E_RMM_BAD_PAS -3
+#define E_RMM_NOMEM -4
+#define E_RMM_INVAL -5
/* Acceptable SHA sizes for Challenge object */
#define SHA256_DIGEST_SIZE 32U
@@ -121,6 +131,36 @@
/* ECC Curve types for attest key generation */
#define ATTEST_KEY_CURVE_ECC_SECP384R1 0
+/*
+ * RMM_BOOT_COMPLETE originates on RMM when the boot finishes (either cold
+ * or warm boot). This is handled by the RMM-EL3 interface SMC handler.
+ *
+ * RMM_BOOT_COMPLETE FID is located at the end of the available range.
+ */
+ /* 0x1CF */
+#define RMM_BOOT_COMPLETE SMC64_RMMD_EL3_FID(U(0x1F))
+
+/*
+ * The major version number of the RMM Boot Interface implementation.
+ * Increase this whenever the semantics of the boot arguments change making it
+ * backwards incompatible.
+ */
+#define RMM_EL3_IFC_VERSION_MAJOR (U(0))
+
+/*
+ * The minor version number of the RMM Boot Interface implementation.
+ * Increase this when a bug is fixed, or a feature is added without
+ * breaking compatibility.
+ */
+#define RMM_EL3_IFC_VERSION_MINOR (U(1))
+
+#define RMM_EL3_INTERFACE_VERSION \
+ (((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) | \
+ RMM_EL3_IFC_VERSION_MINOR)
+
+#define RMM_EL3_IFC_VERSION_GET_MAJOR(_version) (((_version) >> 16) \
+ & 0x7FFF)
+#define RMM_EL3_IFC_VERSION_GET_MAJOR_MINOR(_version) ((_version) & 0xFFFF)
#ifndef __ASSEMBLER__
#include <stdint.h>
diff --git a/include/services/trp/platform_trp.h b/include/services/trp/platform_trp.h
index b34da85..1c963c8 100644
--- a/include/services/trp/platform_trp.h
+++ b/include/services/trp/platform_trp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,9 +7,11 @@
#ifndef PLATFORM_TRP_H
#define PLATFORM_TRP_H
+#include <services/rmm_core_manifest.h>
+
/*******************************************************************************
* Mandatory TRP functions (only if platform contains a TRP)
******************************************************************************/
-void trp_early_platform_setup(void);
+void trp_early_platform_setup(rmm_manifest_t *manifest);
#endif /* PLATFORM_TRP_H */
diff --git a/include/services/trp/trp_helpers.h b/include/services/trp/trp_helpers.h
new file mode 100644
index 0000000..8e786e2
--- /dev/null
+++ b/include/services/trp/trp_helpers.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRP_HELPERS_H
+#define TRP_HELPERS_H
+
+/* Definitions to help the assembler access the SMC/ERET args structure */
+#define TRP_ARGS_SIZE TRP_ARGS_END
+#define TRP_ARG0 0x0
+#define TRP_ARG1 0x8
+#define TRP_ARG2 0x10
+#define TRP_ARG3 0x18
+#define TRP_ARG4 0x20
+#define TRP_ARG5 0x28
+#define TRP_ARG6 0x30
+#define TRP_ARG7 0x38
+#define TRP_ARGS_END 0x40
+
+#ifndef __ASSEMBLER__
+
+#include <platform_def.h>
+
+/* Data structure to hold SMC arguments */
+typedef struct trp_args {
+ uint64_t regs[TRP_ARGS_END >> 3];
+} __aligned(CACHE_WRITEBACK_GRANULE) trp_args_t;
+
+trp_args_t *set_smc_args(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7);
+
+__dead2 void trp_boot_abort(uint64_t err);
+
+#endif /* __ASSEMBLER __ */
+#endif /* TRP_HELPERS_H */
diff --git a/lib/cpus/aarch64/a64fx.S b/lib/cpus/aarch64/a64fx.S
new file mode 100644
index 0000000..54c20c3
--- /dev/null
+++ b/lib/cpus/aarch64/a64fx.S
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022, Fujitsu Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <a64fx.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+func a64fx_core_pwr_dwn
+endfunc a64fx_core_pwr_dwn
+
+func a64fx_cluster_pwr_dwn
+endfunc a64fx_cluster_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for A64FX. Must follow AAPCS.
+ */
+func a64fx_errata_report
+ ret
+endfunc a64fx_errata_report
+#endif
+
+ /* ---------------------------------------------
+ * This function provides cpu specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ascii and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.a64fx_regs, "aS"
+a64fx_regs: /* The ascii list of register names to be reported */
+ .asciz ""
+
+func a64fx_cpu_reg_dump
+ adr x6, a64fx_regs
+ ret
+endfunc a64fx_cpu_reg_dump
+
+declare_cpu_ops a64fx, A64FX_MIDR, CPU_NO_RESET_FUNC \
+ a64fx_core_pwr_dwn, \
+ a64fx_cluster_pwr_dwn
+
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 0712109..f57ecaf 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -21,6 +21,43 @@
wa_cve_2022_23960_bhb_vector_table CORTEX_A78C_BHB_LOOP_COUNT, cortex_a78c
#endif /* WORKAROUND_CVE_2022_23960 */
+/* --------------------------------------------------
+ * Errata Workaround for A78C Erratum 2132064.
+ * This applies to revisions r0p1 and r0p2 of A78C
+ * and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78c_2132064_wa
+ /* Compare x0 against revisions r0p0 - r0p1 */
+ mov x17, x30
+ bl check_errata_2132064
+ cbz x0, 1f
+
+ /* --------------------------------------------------------
+ * Place the data prefetcher in the most conservative mode
+ * to reduce prefetches by writing the following bits to
+ * the value indicated: ecltr[7:6], PF_MODE = 2'b11
+ * --------------------------------------------------------
+ */
+ mrs x0, CORTEX_A78C_CPUECTLR_EL1
+ orr x0, x0, #CORTEX_A78C_CPUECTLR_EL1_BIT6
+ orr x0, x0, #CORTEX_A78C_CPUECTLR_EL1_BIT7
+ msr CORTEX_A78C_CPUECTLR_EL1, x0
+ isb
+1:
+ ret x17
+endfunc errata_a78c_2132064_wa
+
+func check_errata_2132064
+ /* Applies to revisions r0p1 and r0p2. */
+ mov x1, #CPU_REV(0, 1)
+ mov x2, #CPU_REV(0, 2)
+ b cpu_rev_var_range
+endfunc check_errata_2132064
+
func check_errata_cve_2022_23960
#if WORKAROUND_CVE_2022_23960
mov x0, #ERRATA_APPLIES
@@ -35,6 +72,15 @@
* -------------------------------------------------
*/
func cortex_a78c_reset_func
+ mov x19, x30
+ bl cpu_get_rev_var
+ mov x18, x0
+
+#if ERRATA_A78C_2132064
+ mov x0, x18
+ bl errata_a78c_2132064_wa
+#endif
+
#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
/*
* The Cortex-A78c generic vectors are overridden to apply errata
@@ -43,8 +89,9 @@
adr x0, wa_cve_vbar_cortex_a78c
msr vbar_el3, x0
#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
isb
- ret
+ ret x19
endfunc cortex_a78c_reset_func
/* ----------------------------------------------------
@@ -77,6 +124,7 @@
* Report all errata. The revision-variant information is passed to
* checking functions of each errata.
*/
+ report_errata ERRATA_A78C_2132064, cortex_a78c, 2132064
report_errata WORKAROUND_CVE_2022_23960, cortex_a78c, cve_2022_23960
ldp x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 5b796dc..fae3be2 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -338,6 +338,36 @@
b cpu_rev_var_ls
endfunc check_errata_2280757
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2388450.
+ * This applies to revision r0p0 of Neoverse N2,
+ * fixed in r0p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2388450_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2388450
+ cbz x0, 1f
+
+ /*Set bit 40 in ACTLR2_EL1 */
+ mrs x1, NEOVERSE_N2_CPUACTLR2_EL1
+ orr x1, x1, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_40
+ msr NEOVERSE_N2_CPUACTLR2_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_n2_2388450_wa
+
+func check_errata_2388450
+ /* Applies to r0p0, fixed in r0p1 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2388450
+
func check_errata_cve_2022_23960
#if WORKAROUND_CVE_2022_23960
mov x0, #ERRATA_APPLIES
@@ -417,6 +447,11 @@
bl errata_n2_2280757_wa
#endif
+#if ERRATA_N2_2388450
+ mov x0, x18
+ bl errata_n2_2388450_wa
+#endif
+
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, cptr_el3
@@ -496,6 +531,7 @@
report_errata ERRATA_N2_2138958, neoverse_n2, 2138958
report_errata ERRATA_N2_2242400, neoverse_n2, 2242400
report_errata ERRATA_N2_2280757, neoverse_n2, 2280757
+ report_errata ERRATA_N2_2388450, neoverse_n2, 2388450
report_errata WORKAROUND_CVE_2022_23960, neoverse_n2, cve_2022_23960
report_errata ERRATA_DSU_2313941, neoverse_n2, dsu_2313941
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 6d49dab..19e611c 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -361,6 +361,10 @@
# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
ERRATA_A78_AE_2395408 ?=0
+# Flag to apply erratum 2132064 workaround during reset. This erratum applies
+# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
+ERRATA_A78C_2132064 ?=0
+
# Flag to apply erratum 1821534 workaround during reset. This erratum applies
# to revisions r0p0 - r1p0 of the X1 cpu and fixed in r1p1.
ERRATA_X1_1821534 ?=0
@@ -556,6 +560,10 @@
# to revision r0p0 of the Neoverse N2 cpu and is still open.
ERRATA_N2_2280757 ?=0
+# Flag to apply erratum 2388450 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
+ERRATA_N2_2388450 ?=0
+
# Flag to apply erratum 2002765 workaround during reset. This erratum applies
# to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
ERRATA_X2_2002765 ?=0
@@ -911,6 +919,10 @@
$(eval $(call assert_boolean,ERRATA_A78_AE_2395408))
$(eval $(call add_define,ERRATA_A78_AE_2395408))
+# Process ERRATA_A78C_2132064 flag
+$(eval $(call assert_boolean,ERRATA_A78C_2132064))
+$(eval $(call add_define,ERRATA_A78C_2132064))
+
# Process ERRATA_X1_1821534 flag
$(eval $(call assert_boolean,ERRATA_X1_1821534))
$(eval $(call add_define,ERRATA_X1_1821534))
@@ -1103,6 +1115,10 @@
$(eval $(call assert_boolean,ERRATA_N2_2280757))
$(eval $(call add_define,ERRATA_N2_2280757))
+# Process ERRATA_N2_2388450 flag
+$(eval $(call assert_boolean,ERRATA_N2_2388450))
+$(eval $(call add_define,ERRATA_N2_2388450))
+
# Process ERRATA_X2_2002765 flag
$(eval $(call assert_boolean,ERRATA_X2_2002765))
$(eval $(call add_define,ERRATA_X2_2002765))
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index 1c2b984..958b623 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -37,6 +37,8 @@
/* Make sure SME is implemented in hardware before continuing. */
if (!feat_sme_supported()) {
+ /* Perhaps the hardware supports SVE only */
+ sve_enable(context);
return;
}
@@ -83,6 +85,8 @@
/* Make sure SME is implemented in hardware before continuing. */
if (!feat_sme_supported()) {
+ /* Perhaps the hardware supports SVE only */
+ sve_disable(context);
return;
}
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index 21a6073..4543671 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -82,4 +82,8 @@
device_type = "memory";
reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
};
+
+#if MEASURED_BOOT
+#include "event_log.dtsi"
+#endif
};
diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
index fd15b70..e938e24 100644
--- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
@@ -6,6 +6,7 @@
#include <stdint.h>
+#include <common/tbbr/tbbr_img_def.h>
#include <drivers/measured_boot/event_log/event_log.h>
#include <drivers/measured_boot/rss/rss_measured_boot.h>
#include <tools_share/tbbr_oid.h>
@@ -31,6 +32,17 @@
{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
{ RMM_IMAGE_ID, EVLOG_RMM_STRING, PCR_0},
+#if defined(SPD_spmd)
+ { SP_PKG1_ID, EVLOG_SP1_STRING, PCR_0 },
+ { SP_PKG2_ID, EVLOG_SP2_STRING, PCR_0 },
+ { SP_PKG3_ID, EVLOG_SP3_STRING, PCR_0 },
+ { SP_PKG4_ID, EVLOG_SP4_STRING, PCR_0 },
+ { SP_PKG5_ID, EVLOG_SP5_STRING, PCR_0 },
+ { SP_PKG6_ID, EVLOG_SP6_STRING, PCR_0 },
+ { SP_PKG7_ID, EVLOG_SP7_STRING, PCR_0 },
+ { SP_PKG8_ID, EVLOG_SP8_STRING, PCR_0 },
+#endif
+
{ CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 },
{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index a7028f6..f8463f1 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -17,6 +17,9 @@
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <platform_def.h>
#include <services/arm_arch_svc.h>
+#if ENABLE_RME
+#include <services/rmm_core_manifest.h>
+#endif
#if SPM_MM
#include <services/spm_mm_partition.h>
#endif
@@ -169,6 +172,7 @@
#endif
#if ENABLE_RME
ARM_MAP_GPT_L1_DRAM,
+ ARM_MAP_EL3_RMM_SHARED_MEM,
#endif
{0}
};
@@ -512,3 +516,29 @@
return (int32_t)(((sys_id >> V2M_SYS_ID_REV_SHIFT) &
V2M_SYS_ID_REV_MASK) & SOC_ID_REV_MASK);
}
+
+#if ENABLE_RME
+/*
+ * Get a pointer to the RMM-EL3 Shared buffer and return it
+ * through the pointer passed as parameter.
+ *
+ * This function returns the size of the shared buffer.
+ */
+size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
+{
+ *shared = (uintptr_t)RMM_SHARED_BASE;
+
+ return (size_t)RMM_SHARED_SIZE;
+}
+
+int plat_rmmd_load_manifest(rmm_manifest_t *manifest)
+{
+ assert(manifest != NULL);
+
+ manifest->version = RMMD_MANIFEST_VERSION;
+ manifest->plat_data = (uintptr_t)NULL;
+
+ return 0;
+}
+
+#endif
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
index 5463f33..1b0854b 100644
--- a/plat/arm/board/fvp/fvp_plat_attest_token.c
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -300,8 +300,8 @@
0xB0, 0x3A
};
-int plat_get_cca_attest_token(uintptr_t buf, size_t *len,
- uintptr_t hash, size_t hash_size)
+int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
+ uintptr_t hash, size_t hash_size)
{
(void)hash;
(void)hash_size;
diff --git a/plat/arm/board/fvp/fvp_realm_attest_key.c b/plat/arm/board/fvp/fvp_realm_attest_key.c
index b32f557..1af1f0d 100644
--- a/plat/arm/board/fvp/fvp_realm_attest_key.c
+++ b/plat/arm/board/fvp/fvp_realm_attest_key.c
@@ -19,7 +19,8 @@
0xEB, 0x1A, 0x41, 0x85, 0xBD, 0x11, 0x7F, 0x68
};
-int plat_get_cca_realm_attest_key(uintptr_t buf, size_t *len, unsigned int type)
+int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
+ unsigned int type)
{
assert(type == ATTEST_KEY_CURVE_ECC_SECP384R1);
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index c75aca7..d0f8aa9 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -127,11 +127,7 @@
#if defined(IMAGE_BL31)
# if SPM_MM
# define PLAT_ARM_MMAP_ENTRIES 10
-# if ENABLE_RME
-# define MAX_XLAT_TABLES 11
-# else
-# define MAX_XLAT_TABLES 9
-# endif
+# define MAX_XLAT_TABLES 9
# define PLAT_SP_IMAGE_MMAP_REGIONS 30
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# elif SPMC_AT_EL3
@@ -141,13 +137,13 @@
# define PLAT_ARM_MMAP_ENTRIES 9
# if USE_DEBUGFS
# if ENABLE_RME
-# define MAX_XLAT_TABLES 10
+# define MAX_XLAT_TABLES 9
# else
# define MAX_XLAT_TABLES 8
# endif
# else
# if ENABLE_RME
-# define MAX_XLAT_TABLES 9
+# define MAX_XLAT_TABLES 8
# else
# define MAX_XLAT_TABLES 7
# endif
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index f9053a8..a7e27e8 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -341,10 +341,6 @@
endif
endif
-ifeq (${ENABLE_RME},1)
- BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
-endif
-
ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
ifeq (${ARCH},aarch32)
BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
diff --git a/plat/arm/board/morello/morello_bl2_setup.c b/plat/arm/board/morello/morello_bl2_setup.c
index 0d4b6d0..da1f7ae 100644
--- a/plat/arm/board/morello/morello_bl2_setup.c
+++ b/plat/arm/board/morello/morello_bl2_setup.c
@@ -1,27 +1,226 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
+#include <drivers/arm/css/sds.h>
+#include <lib/mmio.h>
#include <lib/utils.h>
#include <plat/arm/common/plat_arm.h>
-void bl2_platform_setup(void)
-{
+#include "morello_def.h"
+#include <platform_def.h>
+
+#ifdef TARGET_PLATFORM_FVP
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size
+ * - Local DDR size in bytes, DDR memory in main board
+ */
+struct morello_plat_info {
+ uint64_t local_ddr_size;
+} __packed;
+#else
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size which is an information about multichip setup
+ * - Local DDR size in bytes, DDR memory in main board
+ * - Remote DDR size in bytes, DDR memory in remote board
+ * - remote_chip_count
+ * - multichip mode
+ * - scc configuration
+ */
+struct morello_plat_info {
+ uint64_t local_ddr_size;
+ uint64_t remote_ddr_size;
+ uint8_t remote_chip_count;
+ bool multichip_mode;
+ uint32_t scc_config;
+} __packed;
+#endif
+
+/* Compile time assertion to ensure the size of structure is 18 bytes */
+CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
+ assert_invalid_plat_info_size);
+
#ifdef TARGET_PLATFORM_SOC
- /*
- * Morello platform supports RDIMMs with ECC capability. To use the ECC
- * capability, the entire DDR memory space has to be zeroed out before
- * enabling the ECC bits in DMC-Bing.
- * Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF during BL2 stage,
- * as BL33 binary cannot be copied to DDR memory before enabling ECC.
- * Rest of the DDR memory space is zeroed out during BL31 stage.
- */
+/*
+ * Morello platform supports RDIMMs with ECC capability. To use the ECC
+ * capability, the entire DDR memory space has to be zeroed out before
+ * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
+ * memory from SCP is quite time consuming so the following function
+ * is added to zero out the DDR memory from application processor which is
+ * much faster compared to SCP.
+ */
+
+static void dmc_ecc_setup(struct morello_plat_info *plat_info)
+{
+ uint64_t dram2_size;
+ uint32_t val;
+ uint64_t tag_mem_base;
+ uint64_t usable_mem_size;
+
+ INFO("Total DIMM size: %uGB\n",
+ (uint32_t)(plat_info->local_ddr_size / 0x40000000));
+
+ assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
+ dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
+
INFO("Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF\n");
zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
+
+ INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
+ ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
+ zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
+ flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
+
+ /* Clear previous ECC errors while zeroing out the memory */
+ val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
+ mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
+
+ val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
+ mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
+
+ /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
+ mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
+ mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
+
+ while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
+ MORELLO_DMC_MEMC_STATUS_MASK) !=
+ MORELLO_DMC_MEMC_CMD_CONFIG) {
+ continue;
+ }
+
+ while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
+ MORELLO_DMC_MEMC_STATUS_MASK) !=
+ MORELLO_DMC_MEMC_CMD_CONFIG) {
+ continue;
+ }
+
+ /* Configure Bing client/server mode based on SCC configuration */
+ if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
+ INFO("Configuring DMC Bing in client mode\n");
+ usable_mem_size = plat_info->local_ddr_size -
+ (plat_info->local_ddr_size / 128ULL);
+
+ /* Linear DDR address */
+ tag_mem_base = usable_mem_size;
+ tag_mem_base = tag_mem_base / 4;
+
+ /* Reverse translation */
+ if (tag_mem_base < ARM_DRAM1_BASE) {
+ tag_mem_base += ARM_DRAM1_BASE;
+ } else {
+ tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
+ ARM_DRAM2_BASE;
+ }
+
+ mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
+ mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
+ mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
+ mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
+
+ if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
+ mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
+ mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
+ INFO("C1 Tag Cache Enabled\n");
+ }
+
+ if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
+ mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
+ mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
+ INFO("C2 Tag Cache Enabled\n");
+ }
+
+ mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
+ (uint32_t)tag_mem_base);
+ mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
+ (uint32_t)tag_mem_base);
+ mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
+ (uint32_t)(tag_mem_base >> 32));
+ mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
+ (uint32_t)(tag_mem_base >> 32));
+
+ mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
+ MORELLO_DMC_MEM_ACCESS_DIS);
+ mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
+ MORELLO_DMC_MEM_ACCESS_DIS);
+
+ INFO("Tag base set to 0x%lx\n", tag_mem_base);
+ plat_info->local_ddr_size = usable_mem_size;
+ } else {
+ INFO("Configuring DMC Bing in server mode\n");
+ mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
+ mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
+ }
+
+ INFO("Enabling ECC on DMCs\n");
+ /* Enable ECC in DMCs */
+ mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
+ MORELLO_DMC_ERR0CTLR0_ECC_EN);
+ mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
+ MORELLO_DMC_ERR0CTLR0_ECC_EN);
+
+ /* Set DMCs to READY state */
+ mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
+ mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
+
+ while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
+ MORELLO_DMC_MEMC_STATUS_MASK) !=
+ MORELLO_DMC_MEMC_CMD_READY) {
+ continue;
+ }
+
+ while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
+ MORELLO_DMC_MEMC_STATUS_MASK) !=
+ MORELLO_DMC_MEMC_CMD_READY) {
+ continue;
+ }
+}
+#endif
+
+void bl2_platform_setup(void)
+{
+ int ret;
+ struct morello_plat_info plat_info;
+
+ ret = sds_init();
+ if (ret != SDS_OK) {
+ ERROR("SDS initialization failed. ret:%d\n", ret);
+ panic();
+ }
+
+ ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
+ MORELLO_SDS_PLATFORM_INFO_OFFSET,
+ &plat_info,
+ MORELLO_SDS_PLATFORM_INFO_SIZE,
+ SDS_ACCESS_MODE_NON_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("Error getting platform info from SDS. ret:%d\n", ret);
+ panic();
+ }
+
+ /* Validate plat_info SDS */
+#ifdef TARGET_PLATFORM_FVP
+ if (plat_info.local_ddr_size == 0U) {
+#else
+ if ((plat_info.local_ddr_size == 0U)
+ || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
+ || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
+ || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
+ ) {
+#endif
+ ERROR("platform info SDS is corrupted\n");
+ panic();
+ }
+
+#ifdef TARGET_PLATFORM_SOC
+ dmc_ecc_setup(&plat_info);
#endif
arm_bl2_platform_setup();
}
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
index e418518..a044212 100644
--- a/plat/arm/board/morello/morello_bl31_setup.c
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -1,54 +1,16 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <common/debug.h>
#include <drivers/arm/css/css_mhu_doorbell.h>
#include <drivers/arm/css/scmi.h>
-#include <drivers/arm/css/sds.h>
-#include <lib/cassert.h>
-#include <lib/utils.h>
#include <plat/arm/common/plat_arm.h>
#include "morello_def.h"
#include <platform_def.h>
-#ifdef TARGET_PLATFORM_FVP
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size
- * - Local DDR size in bytes, DDR memory in main board
- */
-struct morello_plat_info {
- uint64_t local_ddr_size;
-} __packed;
-#else
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size which is an information about multichip setup
- * - Local DDR size in bytes, DDR memory in main board
- * - Remote DDR size in bytes, DDR memory in remote board
- * - remote_chip_count
- * - multichip mode
- * - scc configuration
- */
-struct morello_plat_info {
- uint64_t local_ddr_size;
- uint64_t remote_ddr_size;
- uint8_t remote_chip_count;
- bool multichip_mode;
- uint32_t scc_config;
-} __packed;
-#endif
-
-/* Compile time assertion to ensure the size of structure is 18 bytes */
-CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
- assert_invalid_plat_info_size);
-
static scmi_channel_plat_info_t morello_scmi_plat_info = {
.scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE,
.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
@@ -67,177 +29,7 @@
return css_scmi_override_pm_ops(ops);
}
-#ifdef TARGET_PLATFORM_SOC
-/*
- * Morello platform supports RDIMMs with ECC capability. To use the ECC
- * capability, the entire DDR memory space has to be zeroed out before
- * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
- * memory from SCP is quite time consuming so the following function
- * is added to zero out the DDR memory from application processor which is
- * much faster compared to SCP.
- */
-
-static void dmc_ecc_setup(struct morello_plat_info *plat_info)
-{
- uint64_t dram2_size;
- uint32_t val;
- uint64_t tag_mem_base;
- uint64_t usable_mem_size;
-
- INFO("Total DIMM size: %uGB\n",
- (uint32_t)(plat_info->local_ddr_size / 0x40000000));
-
- assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
- dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
-
- INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
- ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
- zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
- flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
-
- /* Clear previous ECC errors while zeroing out the memory */
- val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
- mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
-
- val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
- mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
-
- /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
- mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
- mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
-
- while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_CONFIG) {
- continue;
- }
-
- while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_CONFIG) {
- continue;
- }
-
- /* Configure Bing client/server mode based on SCC configuration */
- if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
- INFO("Configuring DMC Bing in client mode\n");
- usable_mem_size = plat_info->local_ddr_size -
- (plat_info->local_ddr_size / 128ULL);
-
- /* Linear DDR address */
- tag_mem_base = usable_mem_size;
- tag_mem_base = tag_mem_base / 4;
-
- /* Reverse translation */
- if (tag_mem_base < ARM_DRAM1_BASE) {
- tag_mem_base += ARM_DRAM1_BASE;
- } else {
- tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
- ARM_DRAM2_BASE;
- }
-
- mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
- mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
- mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
- mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
-
- if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
- mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
- mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
- INFO("C1 Tag Cache Enabled\n");
- }
-
- if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
- mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
- mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
- INFO("C2 Tag Cache Enabled\n");
- }
-
- mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
- (uint32_t)tag_mem_base);
- mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
- (uint32_t)tag_mem_base);
- mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
- (uint32_t)(tag_mem_base >> 32));
- mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
- (uint32_t)(tag_mem_base >> 32));
-
- mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
- MORELLO_DMC_MEM_ACCESS_DIS);
- mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
- MORELLO_DMC_MEM_ACCESS_DIS);
-
- INFO("Tag base set to 0x%lx\n", tag_mem_base);
- plat_info->local_ddr_size = usable_mem_size;
- } else {
- INFO("Configuring DMC Bing in server mode\n");
- mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
- mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
- }
-
- INFO("Enabling ECC on DMCs\n");
- /* Enable ECC in DMCs */
- mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
- MORELLO_DMC_ERR0CTLR0_ECC_EN);
- mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
- MORELLO_DMC_ERR0CTLR0_ECC_EN);
-
- /* Set DMCs to READY state */
- mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
- mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
-
- while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_READY) {
- continue;
- }
-
- while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_READY) {
- continue;
- }
-}
-#endif
-
void bl31_platform_setup(void)
{
- int ret;
- struct morello_plat_info plat_info;
-
- ret = sds_init();
- if (ret != SDS_OK) {
- ERROR("SDS initialization failed. ret:%d\n", ret);
- panic();
- }
-
- ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
- MORELLO_SDS_PLATFORM_INFO_OFFSET,
- &plat_info,
- MORELLO_SDS_PLATFORM_INFO_SIZE,
- SDS_ACCESS_MODE_NON_CACHED);
- if (ret != SDS_OK) {
- ERROR("Error getting platform info from SDS. ret:%d\n", ret);
- panic();
- }
-
- /* Validate plat_info SDS */
-#ifdef TARGET_PLATFORM_FVP
- if (plat_info.local_ddr_size == 0U) {
-#else
- if ((plat_info.local_ddr_size == 0U)
- || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
- || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
- || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
- ) {
-#endif
- ERROR("platform info SDS is corrupted\n");
- panic();
- }
-
arm_bl31_platform_setup();
-
-#ifdef TARGET_PLATFORM_SOC
- dmc_ecc_setup(&plat_info);
-#endif
}
diff --git a/plat/arm/board/morello/morello_plat.c b/plat/arm/board/morello/morello_plat.c
index 42e5171..1da0ff9 100644
--- a/plat/arm/board/morello/morello_plat.c
+++ b/plat/arm/board/morello/morello_plat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,7 +15,7 @@
* Table of regions to map using the MMU.
* Replace or extend the below regions as required
*/
-#if IMAGE_BL1 || IMAGE_BL31
+#if IMAGE_BL1
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
MORELLO_MAP_DEVICE,
@@ -25,12 +25,23 @@
{0}
};
#endif
+
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ MORELLO_MAP_DEVICE,
+ MORELLO_MAP_NS_SRAM,
+ {0}
+};
+#endif
+
#if IMAGE_BL2
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
MORELLO_MAP_DEVICE,
MORELLO_MAP_NS_SRAM,
ARM_MAP_DRAM1,
+ ARM_MAP_DRAM2,
#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
ARM_MAP_BL1_RW,
#endif
diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk
index 86047e3..156b7ea 100644
--- a/plat/arm/board/morello/platform.mk
+++ b/plat/arm/board/morello/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -83,6 +83,8 @@
override ARM_PLAT_MT := 1
+override ARM_BL31_IN_DRAM := 1
+
# Errata workarounds:
ERRATA_N1_1868343 := 1
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
index a9b30a4..69bfd7b 100644
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ b/plat/arm/board/rde1edge/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,12 +26,15 @@
#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL3
+/* Maximum number of address bits used per chip */
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(36)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
index a61b0d5..de01902 100644
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ b/plat/arm/board/rdn1edge/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,12 +30,17 @@
/* Virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
+/* Maximum number of address bits used per chip */
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(42)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43)
+#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
+ CSS_SGI_CHIP_COUNT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
+ CSS_SGI_CHIP_COUNT)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index e4015f7..464a157 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -69,15 +69,16 @@
*/
#ifdef __aarch64__
#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(46) /* 64TB */
+#else
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(42) /* 4TB */
+#endif
+
#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
CSS_SGI_CHIP_COUNT)
#define PLAT_VIRT_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
CSS_SGI_CHIP_COUNT)
#else
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42)
-#endif
-#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#endif
diff --git a/plat/arm/board/rdv1/include/platform_def.h b/plat/arm/board/rdv1/include/platform_def.h
index 5b98b4e..620fa3e 100644
--- a/plat/arm/board/rdv1/include/platform_def.h
+++ b/plat/arm/board/rdv1/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -46,12 +46,15 @@
(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \
(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
+/* Maximum number of address bits used per chip */
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(42)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
diff --git a/plat/arm/board/rdv1mc/include/platform_def.h b/plat/arm/board/rdv1mc/include/platform_def.h
index 12ce806..3670904 100644
--- a/plat/arm/board/rdv1mc/include/platform_def.h
+++ b/plat/arm/board/rdv1mc/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -46,6 +46,9 @@
/* Virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xC0000000)
+/* Remote chip address offset (4TB per chip) */
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(42)
+
/* Physical and virtual address space limits for MMU in AARCH64 mode */
#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
CSS_SGI_CHIP_COUNT)
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index 72d5f7c..82a38c5 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,12 +27,15 @@
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+/* Maximum number of address bits used per chip */
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(36)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 745d91c..6ca3261 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -177,7 +177,7 @@
#define PLAT_ARM_NSTIMER_FRAME_ID 0
-#define PLAT_ARM_TRUSTED_ROM_BASE 0x0
+#define PLAT_ARM_TRUSTED_ROM_BASE 0x1000
#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000 /* 512KB */
#define PLAT_ARM_NSRAM_BASE 0x06000000
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index a6f7df5..cf403b1 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -164,6 +164,14 @@
bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+#if ENABLE_RME
+ /*
+ * Populate entry point information for RMM.
+ * Only PC needs to be set as other fields are determined by RMMD.
+ */
+ rmm_image_ep_info.pc = RMM_BASE;
+#endif /* ENABLE_RME */
+
#else /* RESET_TO_BL31 */
/*
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 290b4ee..bd59ec0 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -73,6 +73,14 @@
$(eval $(call assert_boolean,ARM_BL31_IN_DRAM))
$(eval $(call add_define,ARM_BL31_IN_DRAM))
+# As per CCA security model, all root firmware must execute from on-chip secure
+# memory. This means we must not run BL31 from TZC-protected DRAM.
+ifeq (${ARM_BL31_IN_DRAM},1)
+ ifeq (${ENABLE_RME},1)
+ $(error "BL31 must not run from DRAM on RME-systems. Please set ARM_BL31_IN_DRAM to 0")
+ endif
+endif
+
# Process ARM_PLAT_MT flag
ARM_PLAT_MT := 0
$(eval $(call assert_boolean,ARM_PLAT_MT))
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 83e3f9a..a62693c 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -131,6 +131,7 @@
bl_mem_params_node_t *cfg_mem_params = NULL;
uintptr_t image_base;
uint32_t image_size;
+ unsigned int error_config_id = MAX_IMAGE_IDS;
const unsigned int config_ids[] = {
HW_CONFIG_ID,
SOC_FW_CONFIG_ID,
@@ -142,17 +143,17 @@
/* Iterate through all the fw config IDs */
for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
- /* Get the config load address and size from TB_FW_CONFIG */
+ /* Get the config load address and size */
cfg_mem_params = get_bl_mem_params_node(config_ids[i]);
if (cfg_mem_params == NULL) {
- VERBOSE("%sHW_CONFIG in bl_mem_params_node\n",
- "Couldn't find ");
+ VERBOSE("%sconfig_id = %d in bl_mem_params_node\n",
+ "Couldn't find ", config_ids[i]);
continue;
}
dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]);
if (dtb_info == NULL) {
- VERBOSE("%sconfig_id %d load info in TB_FW_CONFIG\n",
+ VERBOSE("%sconfig_id %d load info in FW_CONFIG\n",
"Couldn't find ", config_ids[i]);
continue;
}
@@ -168,17 +169,32 @@
if (config_ids[i] != HW_CONFIG_ID) {
if (check_uptr_overflow(image_base, image_size)) {
+ VERBOSE("%s=%d as its %s is overflowing uptr\n",
+ "skip loading of firmware config",
+ config_ids[i],
+ "load-address");
+ error_config_id = config_ids[i];
continue;
}
#ifdef BL31_BASE
/* Ensure the configs don't overlap with BL31 */
if ((image_base >= BL31_BASE) &&
(image_base <= BL31_LIMIT)) {
+ VERBOSE("%s=%d as its %s is overlapping BL31\n",
+ "skip loading of firmware config",
+ config_ids[i],
+ "load-address");
+ error_config_id = config_ids[i];
continue;
}
#endif
/* Ensure the configs are loaded in a valid address */
if (image_base < ARM_BL_RAM_BASE) {
+ VERBOSE("%s=%d as its %s is invalid\n",
+ "skip loading of firmware config",
+ config_ids[i],
+ "load-address");
+ error_config_id = config_ids[i];
continue;
}
#ifdef BL32_BASE
@@ -188,6 +204,11 @@
*/
if ((image_base >= BL32_BASE) &&
(image_base <= BL32_LIMIT)) {
+ VERBOSE("%s=%d as its %s is overlapping BL32\n",
+ "skip loading of firmware config",
+ config_ids[i],
+ "load-address");
+ error_config_id = config_ids[i];
continue;
}
#endif
@@ -202,4 +223,9 @@
*/
cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
}
+
+ if (error_config_id != MAX_IMAGE_IDS) {
+ ERROR("Invalid config file %u\n", error_config_id);
+ panic();
+ }
}
diff --git a/plat/arm/common/trp/arm_trp.mk b/plat/arm/common/trp/arm_trp.mk
index 997111f..204c14a 100644
--- a/plat/arm/common/trp/arm_trp.mk
+++ b/plat/arm/common/trp/arm_trp.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,3 +8,5 @@
RMM_SOURCES += plat/arm/common/trp/arm_trp_setup.c \
plat/arm/common/arm_topology.c \
plat/common/aarch64/platform_mp_stack.S
+
+INCLUDES += -Iinclude/services/trp
diff --git a/plat/arm/common/trp/arm_trp_setup.c b/plat/arm/common/trp/arm_trp_setup.c
index 8e48293..59b4c06 100644
--- a/plat/arm/common/trp/arm_trp_setup.c
+++ b/plat/arm/common/trp/arm_trp_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,33 +8,65 @@
#include <common/debug.h>
#include <drivers/arm/pl011.h>
#include <drivers/console.h>
+#include <services/rmm_core_manifest.h>
+#include <services/rmmd_svc.h>
+#include <services/trp/platform_trp.h>
+#include <trp_helpers.h>
+
#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>
/*******************************************************************************
+ * Received from boot manifest and populated here
+ ******************************************************************************/
+extern uint32_t trp_boot_manifest_version;
+
+/*******************************************************************************
* Initialize the UART
******************************************************************************/
static console_t arm_trp_runtime_console;
+static int arm_trp_process_manifest(rmm_manifest_t *manifest)
+{
+ /* Verify the Boot Manifest Version. Only the Major is considered */
+ if (RMMD_MANIFEST_VERSION_MAJOR !=
+ RMMD_GET_MANIFEST_VERSION_MAJOR(manifest->version)) {
+ return E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED;
+ }
+
-void arm_trp_early_platform_setup(void)
+ trp_boot_manifest_version = manifest->version;
+ flush_dcache_range((uintptr_t)manifest, sizeof(rmm_manifest_t));
+
+ return 0;
+}
+
+void arm_trp_early_platform_setup(rmm_manifest_t *manifest)
{
+ int rc;
+
+ rc = arm_trp_process_manifest(manifest);
+ if (rc != 0) {
+ trp_boot_abort(rc);
+ }
+
/*
* Initialize a different console than already in use to display
* messages from trp
*/
- int rc = console_pl011_register(PLAT_ARM_TRP_UART_BASE,
- PLAT_ARM_TRP_UART_CLK_IN_HZ,
- ARM_CONSOLE_BAUDRATE,
- &arm_trp_runtime_console);
+ rc = console_pl011_register(PLAT_ARM_TRP_UART_BASE,
+ PLAT_ARM_TRP_UART_CLK_IN_HZ,
+ ARM_CONSOLE_BAUDRATE,
+ &arm_trp_runtime_console);
if (rc == 0) {
panic();
}
console_set_scope(&arm_trp_runtime_console,
CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+
}
-void trp_early_platform_setup(void)
+void trp_early_platform_setup(rmm_manifest_t *manifest)
{
- arm_trp_early_platform_setup();
+ arm_trp_early_platform_setup(manifest);
}
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 58a153a..22870c4 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -21,8 +21,9 @@
#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */
-/* Remote chip address offset (4TB per chip) */
-#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) ((ULL(1) << 42) * (n))
+/* Remote chip address offset */
+#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) \
+ ((ULL(1) << CSS_SGI_ADDR_BITS_PER_CHIP) * (n))
/*
* PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
@@ -67,7 +68,7 @@
* PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
* plus a little space for growth.
*/
-#define PLAT_ARM_MAX_BL1_RW_SIZE 0xC000
+#define PLAT_ARM_MAX_BL1_RW_SIZE (64 * 1024) /* 64 KB */
/*
* PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index fd54820..fae9750 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -34,6 +34,13 @@
SMC_RET1(handle, imx_soc_info_handler(smc_fid, x1, x2, x3));
break;
#endif
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+ case IMX_SIP_DDR_DVFS:
+ return dram_dvfs_handler(smc_fid, handle, x1, x2, x3);
+ case IMX_SIP_GPC:
+ SMC_RET1(handle, imx_gpc_handler(smc_fid, x1, x2, x3));
+ break;
+#endif
#if (defined(PLAT_imx8qm) || defined(PLAT_imx8qx))
case IMX_SIP_SRTC:
return imx_srtc_handler(smc_fid, handle, x1, x2, x3, x4);
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 6c7a760..c6e9879 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,8 @@
#define __IMX_SIP_SVC_H__
/* SMC function IDs for SiP Service queries */
+#define IMX_SIP_GPC 0xC2000000
+
#define IMX_SIP_CPUFREQ 0xC2000001
#define IMX_SIP_SET_CPUFREQ 0x00
@@ -17,6 +19,8 @@
#define IMX_SIP_BUILDINFO 0xC2000003
#define IMX_SIP_BUILDINFO_GET_COMMITHASH 0x00
+#define IMX_SIP_DDR_DVFS 0xc2000004
+
#define IMX_SIP_SRC 0xC2000005
#define IMX_SIP_SRC_SET_SECONDARY_BOOT 0x10
#define IMX_SIP_SRC_IS_SECONDARY_BOOT 0x11
@@ -41,6 +45,13 @@
int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1,
u_register_t x2, u_register_t x3);
#endif
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+ u_register_t x1, u_register_t x2, u_register_t x3);
+
+int imx_gpc_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3);
+#endif
#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
int imx_src_handler(uint32_t smc_fid, u_register_t x1,
diff --git a/plat/imx/imx8m/ddr/clock.c b/plat/imx/imx8m/ddr/clock.c
new file mode 100644
index 0000000..7fb5730
--- /dev/null
+++ b/plat/imx/imx8m/ddr/clock.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#define IMX_CCM_IP_BASE (IMX_CCM_BASE + 0xa000)
+#define DRAM_SEL_CFG (IMX_CCM_BASE + 0x9800)
+#define CCM_IP_CLK_ROOT_GEN_TAGET(i) (IMX_CCM_IP_BASE + 0x80 * (i) + 0x00)
+#define CCM_IP_CLK_ROOT_GEN_TAGET_SET(i) (IMX_CCM_IP_BASE + 0x80 * (i) + 0x04)
+#define CCM_IP_CLK_ROOT_GEN_TAGET_CLR(i) (IMX_CCM_IP_BASE + 0x80 * (i) + 0x08)
+#define PLL_FREQ_800M U(0x00ece580)
+#define PLL_FREQ_400M U(0x00ec6984)
+#define PLL_FREQ_167M U(0x00f5a406)
+
+void ddr_pll_bypass_100mts(void)
+{
+ /* change the clock source of dram_alt_clk_root to source 2 --100MHz */
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(0), (0x7 << 24) | (0x7 << 16));
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(0), (0x2 << 24));
+
+ /* change the clock source of dram_apb_clk_root to source 2 --40MHz/2 */
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x2 << 24) | (0x1 << 16));
+
+ /* configure pll bypass mode */
+ mmio_write_32(DRAM_SEL_CFG + 0x4, BIT(24));
+}
+
+void ddr_pll_bypass_400mts(void)
+{
+ /* change the clock source of dram_alt_clk_root to source 1 --400MHz */
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(0), (0x7 << 24) | (0x7 << 16));
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(0), (0x1 << 24) | (0x1 << 16));
+
+ /* change the clock source of dram_apb_clk_root to source 3 --160MHz/2 */
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x3 << 24) | (0x1 << 16));
+
+ /* configure pll bypass mode */
+ mmio_write_32(DRAM_SEL_CFG + 0x4, BIT(24));
+}
+
+void ddr_pll_unbypass(void)
+{
+ mmio_write_32(DRAM_SEL_CFG + 0x8, BIT(24));
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
+ /* to source 4 --800MHz/5 */
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x4 << 24) | (0x4 << 16));
+}
+
+#if defined(PLAT_imx8mq)
+void dram_pll_init(unsigned int drate)
+{
+ /* bypass the PLL */
+ mmio_setbits_32(HW_DRAM_PLL_CFG0, 0x30);
+
+ switch (drate) {
+ case 3200:
+ mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_800M);
+ break;
+ case 1600:
+ mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_400M);
+ break;
+ case 667:
+ mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_167M);
+ break;
+ default:
+ break;
+ }
+
+ /* unbypass the PLL */
+ mmio_clrbits_32(HW_DRAM_PLL_CFG0, 0x30);
+ while (!(mmio_read_32(HW_DRAM_PLL_CFG0) & (1 << 31))) {
+ ;
+ }
+}
+#else
+void dram_pll_init(unsigned int drate)
+{
+ /* bypass the PLL */
+ mmio_setbits_32(DRAM_PLL_CTRL, (1 << 16));
+ mmio_clrbits_32(DRAM_PLL_CTRL, (1 << 9));
+
+ switch (drate) {
+ case 2400:
+ mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (3 << 4) | 2);
+ break;
+ case 1600:
+ mmio_write_32(DRAM_PLL_CTRL + 0x4, (400 << 12) | (3 << 4) | 3);
+ break;
+ case 1066:
+ mmio_write_32(DRAM_PLL_CTRL + 0x4, (266 << 12) | (3 << 4) | 3);
+ break;
+ case 667:
+ mmio_write_32(DRAM_PLL_CTRL + 0x4, (334 << 12) | (3 << 4) | 4);
+ break;
+ default:
+ break;
+ }
+
+ mmio_setbits_32(DRAM_PLL_CTRL, BIT(9));
+ /* wait for PLL locked */
+ while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) {
+ ;
+ }
+
+ /* unbypass the PLL */
+ mmio_clrbits_32(DRAM_PLL_CTRL, BIT(16));
+}
+#endif
+
+/* change the dram clock frequency */
+void dram_clock_switch(unsigned int target_drate, bool bypass_mode)
+{
+ if (bypass_mode) {
+ switch (target_drate) {
+ case 400:
+ ddr_pll_bypass_400mts();
+ break;
+ case 100:
+ ddr_pll_bypass_100mts();
+ break;
+ default:
+ ddr_pll_unbypass();
+ break;
+ }
+ } else {
+ dram_pll_init(target_drate);
+ }
+}
diff --git a/plat/imx/imx8m/ddr/ddr4_dvfs.c b/plat/imx/imx8m/ddr/ddr4_dvfs.c
new file mode 100644
index 0000000..cdc7dc2
--- /dev/null
+++ b/plat/imx/imx8m/ddr/ddr4_dvfs.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <dram.h>
+
+void ddr4_mr_write(uint32_t mr, uint32_t data, uint32_t mr_type, uint32_t rank)
+{
+ uint32_t val, mr_mirror, data_mirror;
+
+ /*
+ * 1. Poll MRSTAT.mr_wr_busy until it is 0 to make sure
+ * that there is no outstanding MR transAction.
+ */
+ while (mmio_read_32(DDRC_MRSTAT(0)) & 0x1) {
+ ;
+ }
+
+ /*
+ * 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr, MRCTRL0.mr_rank
+ * and (for MRWs) MRCTRL1.mr_data to define the MR transaction.
+ */
+ val = mmio_read_32(DDRC_DIMMCTL(0));
+ if ((val & 0x2) && (rank == 0x2)) {
+ mr_mirror = (mr & 0x4) | ((mr & 0x1) << 1) | ((mr & 0x2) >> 1); /* BA0, BA1 swap */
+ data_mirror = (data & 0x1607) | ((data & 0x8) << 1) | ((data & 0x10) >> 1) |
+ ((data & 0x20) << 1) | ((data & 0x40) >> 1) | ((data & 0x80) << 1) |
+ ((data & 0x100) >> 1) | ((data & 0x800) << 2) | ((data & 0x2000) >> 2) ;
+ } else {
+ mr_mirror = mr;
+ data_mirror = data;
+ }
+
+ mmio_write_32(DDRC_MRCTRL0(0), mr_type | (mr_mirror << 12) | (rank << 4));
+ mmio_write_32(DDRC_MRCTRL1(0), data_mirror);
+
+ /*
+ * 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1.
+ * This bit is self-clearing, and triggers the MR transaction.
+ * The uMCTL2 then asserts the MRSTAT.mr_wr_busy while it performs
+ * the MR transaction to SDRAM, and no further accesses can be
+ * initiated until it is deasserted.
+ */
+ mmio_setbits_32(DDRC_MRCTRL0(0), BIT(31));
+
+ while (mmio_read_32(DDRC_MRSTAT(0))) {
+ ;
+ }
+}
+
+void dram_cfg_all_mr(struct dram_info *info, uint32_t pstate)
+{
+ uint32_t num_rank = info->num_rank;
+ /*
+ * 15. Perform MRS commands as required to re-program
+ * timing registers in the SDRAM for the new frequency
+ * (in particular, CL, CWL and WR may need to be changed).
+ */
+
+ for (int i = 1; i <= num_rank; i++) {
+ for (int j = 0; j < 6; j++) {
+ ddr4_mr_write(j, info->mr_table[pstate][j], 0, i);
+ }
+ ddr4_mr_write(6, info->mr_table[pstate][7], 0, i);
+ }
+}
+
+void sw_pstate(uint32_t pstate, uint32_t drate)
+{
+ uint32_t val;
+
+ mmio_write_32(DDRC_SWCTL(0), 0x0);
+
+ /*
+ * Update any registers which may be required to
+ * change for the new frequency.
+ */
+ mmio_write_32(DDRC_MSTR2(0), pstate);
+ mmio_setbits_32(DDRC_MSTR(0), (0x1 << 29));
+
+ /*
+ * Toggle RFSHCTL3.refresh_update_level to allow the
+ * new refresh-related register values to propagate
+ * to the refresh logic.
+ */
+ val = mmio_read_32(DDRC_RFSHCTL3(0));
+ if (val & 0x2) {
+ mmio_write_32(DDRC_RFSHCTL3(0), val & 0xFFFFFFFD);
+ } else {
+ mmio_write_32(DDRC_RFSHCTL3(0), val | 0x2);
+ }
+
+ /*
+ * 19. If required, trigger the initialization in the PHY.
+ * If using the gen2 multiPHY, PLL initialization should
+ * be triggered at this point. See the PHY databook for
+ * details about the frequency change procedure.
+ */
+ mmio_write_32(DDRC_DFIMISC(0), 0x00000000 | (pstate << 8));
+ mmio_write_32(DDRC_DFIMISC(0), 0x00000020 | (pstate << 8));
+
+ /* wait DFISTAT.dfi_init_complete to 0 */
+ while (mmio_read_32(DDRC_DFISTAT(0)) & 0x1) {
+ ;
+ }
+
+ /* change the clock to the target frequency */
+ dram_clock_switch(drate, false);
+
+ mmio_write_32(DDRC_DFIMISC(0), 0x00000000 | (pstate << 8));
+
+ /* wait DFISTAT.dfi_init_complete to 1 */
+ while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
+ ;
+ }
+
+ /*
+ * When changing frequencies the controller may violate the JEDEC
+ * requirement that no more than 16 refreshes should be issued within
+ * 2*tREFI. These extra refreshes are not expected to cause a problem
+ * in the SDRAM. This issue can be avoided by waiting for at least 2*tREFI
+ * before exiting self-refresh in step 19.
+ */
+ udelay(14);
+
+ /* 14. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
+ mmio_clrbits_32(DDRC_PWRCTL(0), (1 << 5));
+
+ while ((mmio_read_32(DDRC_STAT(0)) & 0x3f) == 0x23) {
+ ;
+ }
+}
+
+void ddr4_swffc(struct dram_info *info, unsigned int pstate)
+{
+ uint32_t drate = info->timing_info->fsp_table[pstate];
+
+ /*
+ * 1. set SWCTL.sw_done to disable quasi-dynamic register
+ * programming outside reset.
+ */
+ mmio_write_32(DDRC_SWCTL(0), 0x0);
+
+ /*
+ * 2. Write 0 to PCTRL_n.port_en. This blocks AXI port(s)
+ * from taking any transaction (blocks traffic on AXI ports).
+ */
+ mmio_write_32(DDRC_PCTRL_0(0), 0x0);
+
+ /*
+ * 3. Poll PSTAT.rd_port_busy_n=0 and PSTAT.wr_port_busy_n=0.
+ * Wait until all AXI ports are idle (the uMCTL2 core has to
+ * be idle).
+ */
+ while (mmio_read_32(DDRC_PSTAT(0)) & 0x10001) {
+ ;
+ }
+
+ /*
+ * 4. Write 0 to SBRCTL.scrub_en. Disable SBR, required only if
+ * SBR instantiated.
+ * 5. Poll SBRSTAT.scrub_busy=0.
+ * 6. Set DERATEEN.derate_enable = 0, if DERATEEN.derate_eanble = 1
+ * and the read latency (RL) value needs to change after the frequency
+ * change (LPDDR2/3/4 only).
+ * 7. Set DBG1.dis_hif=1 so that no new commands will be accepted by the uMCTL2.
+ */
+ mmio_setbits_32(DDRC_DBG1(0), (0x1 << 1));
+
+ /*
+ * 8. Poll DBGCAM.dbg_wr_q_empty and DBGCAM.dbg_rd_q_empty to ensure
+ * that write and read data buffers are empty.
+ */
+ while ((mmio_read_32(DDRC_DBGCAM(0)) & 0x06000000) != 0x06000000) {
+ ;
+ }
+
+ /*
+ * 9. For DDR4, update MR6 with the new tDLLK value via the Mode
+ * Register Write signals
+ * 10. Set DFILPCFG0.dfi_lp_en_sr = 0, if DFILPCFG0.dfi_lp_en_sr = 1,
+ * and wait until DFISTAT.dfi_lp_ack
+ * 11. If DFI PHY Master interface is active in uMCTL2, then disable it
+ * 12. Wait until STAT.operating_mode[1:0]!=11 indicating that the
+ * controller is not in self-refresh mode.
+ */
+ while ((mmio_read_32(DDRC_STAT(0)) & 0x3) == 0x3) {
+ ;
+ }
+
+ /*
+ * 13. Assert PWRCTL.selfref_sw for the DWC_ddr_umctl2 core to enter
+ * the self-refresh mode.
+ */
+ mmio_setbits_32(DDRC_PWRCTL(0), (1 << 5));
+
+ /*
+ * 14. Wait until STAT.operating_mode[1:0]==11 indicating that the
+ * controller core is in self-refresh mode.
+ */
+ while ((mmio_read_32(DDRC_STAT(0)) & 0x3f) != 0x23) {
+ ;
+ }
+
+ sw_pstate(pstate, drate);
+ dram_cfg_all_mr(info, pstate);
+
+ /* 23. Enable HIF commands by setting DBG1.dis_hif=0. */
+ mmio_clrbits_32(DDRC_DBG1(0), (0x1 << 1));
+
+ /*
+ * 24. Reset DERATEEN.derate_enable = 1 if DERATEEN.derate_enable
+ * has been set to 0 in step 6.
+ * 25. If DFI PHY Master interface was active before step 11 then
+ * enable it back by programming DFIPHYMSTR.phymstr_en = 1'b1.
+ * 26. Write 1 to PCTRL_n.port_en. AXI port(s) are no longer blocked
+ * from taking transactions (Re-enable traffic on AXI ports)
+ */
+ mmio_write_32(DDRC_PCTRL_0(0), 0x1);
+
+ /*
+ * 27. Write 1 to SBRCTL.scrub_en. Enable SBR if desired, only
+ * required if SBR instantiated.
+ */
+
+ /*
+ * set SWCTL.sw_done to enable quasi-dynamic register programming
+ * outside reset.
+ */
+ mmio_write_32(DDRC_SWCTL(0), 0x1);
+
+ /* wait SWSTAT.sw_done_ack to 1 */
+ while (!(mmio_read_32(DDRC_SWSTAT(0)) & 0x1)) {
+ ;
+ }
+}
diff --git a/plat/imx/imx8m/ddr/dram.c b/plat/imx/imx8m/ddr/dram.c
new file mode 100644
index 0000000..6ccd6fd
--- /dev/null
+++ b/plat/imx/imx8m/ddr/dram.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2019-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl31/interrupt_mgmt.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+
+#include <dram.h>
+
+#define IMX_SIP_DDR_DVFS_GET_FREQ_COUNT 0x10
+#define IMX_SIP_DDR_DVFS_GET_FREQ_INFO 0x11
+
+struct dram_info dram_info;
+
+/* lock used for DDR DVFS */
+spinlock_t dfs_lock;
+
+static volatile uint32_t wfe_done;
+static volatile bool wait_ddrc_hwffc_done = true;
+static unsigned int dev_fsp = 0x1;
+
+static uint32_t fsp_init_reg[3][4] = {
+ { DDRC_INIT3(0), DDRC_INIT4(0), DDRC_INIT6(0), DDRC_INIT7(0) },
+ { DDRC_FREQ1_INIT3(0), DDRC_FREQ1_INIT4(0), DDRC_FREQ1_INIT6(0), DDRC_FREQ1_INIT7(0) },
+ { DDRC_FREQ2_INIT3(0), DDRC_FREQ2_INIT4(0), DDRC_FREQ2_INIT6(0), DDRC_FREQ2_INIT7(0) },
+};
+
+static void get_mr_values(uint32_t (*mr_value)[8])
+{
+ uint32_t init_val;
+ unsigned int i, fsp_index;
+
+ for (fsp_index = 0U; fsp_index < 3U; fsp_index++) {
+ for (i = 0U; i < 4U; i++) {
+ init_val = mmio_read_32(fsp_init_reg[fsp_index][i]);
+ mr_value[fsp_index][2*i] = init_val >> 16;
+ mr_value[fsp_index][2*i + 1] = init_val & 0xFFFF;
+ }
+ }
+}
+
+/* Restore the ddrc configs */
+void dram_umctl2_init(struct dram_timing_info *timing)
+{
+ struct dram_cfg_param *ddrc_cfg = timing->ddrc_cfg;
+ unsigned int i;
+
+ for (i = 0U; i < timing->ddrc_cfg_num; i++) {
+ mmio_write_32(ddrc_cfg->reg, ddrc_cfg->val);
+ ddrc_cfg++;
+ }
+
+ /* set the default fsp to P0 */
+ mmio_write_32(DDRC_MSTR2(0), 0x0);
+}
+
+/* Restore the dram PHY config */
+void dram_phy_init(struct dram_timing_info *timing)
+{
+ struct dram_cfg_param *cfg = timing->ddrphy_cfg;
+ unsigned int i;
+
+ /* Restore the PHY init config */
+ cfg = timing->ddrphy_cfg;
+ for (i = 0U; i < timing->ddrphy_cfg_num; i++) {
+ dwc_ddrphy_apb_wr(cfg->reg, cfg->val);
+ cfg++;
+ }
+
+ /* Restore the DDR PHY CSRs */
+ cfg = timing->ddrphy_trained_csr;
+ for (i = 0U; i < timing->ddrphy_trained_csr_num; i++) {
+ dwc_ddrphy_apb_wr(cfg->reg, cfg->val);
+ cfg++;
+ }
+
+ /* Load the PIE image */
+ cfg = timing->ddrphy_pie;
+ for (i = 0U; i < timing->ddrphy_pie_num; i++) {
+ dwc_ddrphy_apb_wr(cfg->reg, cfg->val);
+ cfg++;
+ }
+}
+
+/* EL3 SGI-8 IPI handler for DDR Dynamic frequency scaling */
+static uint64_t waiting_dvfs(uint32_t id, uint32_t flags,
+ void *handle, void *cookie)
+{
+ uint64_t mpidr = read_mpidr_el1();
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+ uint32_t irq;
+
+ irq = plat_ic_acknowledge_interrupt();
+ if (irq < 1022U) {
+ plat_ic_end_of_interrupt(irq);
+ }
+
+ /* set the WFE done status */
+ spin_lock(&dfs_lock);
+ wfe_done |= (1 << cpu_id * 8);
+ dsb();
+ spin_unlock(&dfs_lock);
+
+ while (1) {
+ /* ddr frequency change done */
+ if (!wait_ddrc_hwffc_done)
+ break;
+
+ wfe();
+ }
+
+ return 0;
+}
+
+void dram_info_init(unsigned long dram_timing_base)
+{
+ uint32_t ddrc_mstr, current_fsp;
+ uint32_t flags = 0;
+ uint32_t rc;
+ unsigned int i;
+
+ /* Get the dram type & rank */
+ ddrc_mstr = mmio_read_32(DDRC_MSTR(0));
+
+ dram_info.dram_type = ddrc_mstr & DDR_TYPE_MASK;
+ dram_info.num_rank = (ddrc_mstr >> 24) & ACTIVE_RANK_MASK;
+
+ /* Get current fsp info */
+ current_fsp = mmio_read_32(DDRC_DFIMISC(0)) & 0xf;
+ dram_info.boot_fsp = current_fsp;
+ dram_info.current_fsp = current_fsp;
+
+ get_mr_values(dram_info.mr_table);
+
+ dram_info.timing_info = (struct dram_timing_info *)dram_timing_base;
+
+ /* get the num of supported fsp */
+ for (i = 0U; i < 4U; ++i) {
+ if (!dram_info.timing_info->fsp_table[i]) {
+ break;
+ }
+ }
+ dram_info.num_fsp = i;
+
+ /* check if has bypass mode support */
+ if (dram_info.timing_info->fsp_table[i-1] < 666) {
+ dram_info.bypass_mode = true;
+ } else {
+ dram_info.bypass_mode = false;
+ }
+
+ /* Register the EL3 handler for DDR DVFS */
+ set_interrupt_rm_flag(flags, NON_SECURE);
+ rc = register_interrupt_type_handler(INTR_TYPE_EL3, waiting_dvfs, flags);
+ if (rc != 0) {
+ panic();
+ }
+}
+
+
+/*
+ * For each freq return the following info:
+ *
+ * r1: data rate
+ * r2: 1 + dram_core parent
+ * r3: 1 + dram_alt parent index
+ * r4: 1 + dram_apb parent index
+ *
+ * The parent indices can be used by an OS who manages source clocks to enabled
+ * them ahead of the switch.
+ *
+ * A parent value of "0" means "don't care".
+ *
+ * Current implementation of freq switch is hardcoded in
+ * plat/imx/common/imx8m/clock.c but in theory this can be enhanced to support
+ * a wide variety of rates.
+ */
+int dram_dvfs_get_freq_info(void *handle, u_register_t index)
+{
+ switch (index) {
+ case 0:
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[0],
+ 1, 0, 5);
+ case 1:
+ if (!dram_info.bypass_mode) {
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[1],
+ 1, 0, 0);
+ }
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[1],
+ 2, 2, 4);
+ case 2:
+ if (!dram_info.bypass_mode) {
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[2],
+ 1, 0, 0);
+ }
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[2],
+ 2, 3, 3);
+ case 3:
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[3],
+ 1, 0, 0);
+ default:
+ SMC_RET1(handle, -3);
+ }
+}
+
+int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+ u_register_t x1, u_register_t x2, u_register_t x3)
+{
+ uint64_t mpidr = read_mpidr_el1();
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+ unsigned int fsp_index = x1;
+ uint32_t online_cores = x2;
+
+ if (x1 == IMX_SIP_DDR_DVFS_GET_FREQ_COUNT) {
+ SMC_RET1(handle, dram_info.num_fsp);
+ } else if (x1 == IMX_SIP_DDR_DVFS_GET_FREQ_INFO) {
+ return dram_dvfs_get_freq_info(handle, x2);
+ } else if (x1 < 4) {
+ wait_ddrc_hwffc_done = true;
+ dsb();
+
+ /* trigger the SGI IPI to info other cores */
+ for (int i = 0; i < PLATFORM_CORE_COUNT; i++) {
+ if (cpu_id != i && (online_cores & (0x1 << (i * 8)))) {
+ plat_ic_raise_el3_sgi(0x8, i);
+ }
+ }
+
+ /* make sure all the core in WFE */
+ online_cores &= ~(0x1 << (cpu_id * 8));
+ while (1) {
+ if (online_cores == wfe_done) {
+ break;
+ }
+ }
+
+ /* flush the L1/L2 cache */
+ dcsw_op_all(DCCSW);
+
+ if (dram_info.dram_type == DDRC_LPDDR4) {
+ lpddr4_swffc(&dram_info, dev_fsp, fsp_index);
+ dev_fsp = (~dev_fsp) & 0x1;
+ } else if (dram_info.dram_type == DDRC_DDR4) {
+ ddr4_swffc(&dram_info, fsp_index);
+ }
+
+ dram_info.current_fsp = fsp_index;
+ wait_ddrc_hwffc_done = false;
+ wfe_done = 0;
+ dsb();
+ sev();
+ isb();
+ }
+
+ SMC_RET1(handle, 0);
+}
diff --git a/plat/imx/imx8m/ddr/dram_retention.c b/plat/imx/imx8m/ddr/dram_retention.c
new file mode 100644
index 0000000..7d4f823
--- /dev/null
+++ b/plat/imx/imx8m/ddr/dram_retention.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <lib/mmio.h>
+
+#include <dram.h>
+#include <platform_def.h>
+
+#define SRC_DDR1_RCR (IMX_SRC_BASE + 0x1000)
+#define SRC_DDR2_RCR (IMX_SRC_BASE + 0x1004)
+
+#define PU_PGC_UP_TRG 0xf8
+#define PU_PGC_DN_TRG 0x104
+#define GPC_PU_PWRHSK (IMX_GPC_BASE + 0x01FC)
+#define CCM_SRC_CTRL_OFFSET (IMX_CCM_BASE + 0x800)
+#define CCM_CCGR_OFFSET (IMX_CCM_BASE + 0x4000)
+#define CCM_SRC_CTRL(n) (CCM_SRC_CTRL_OFFSET + 0x10 * (n))
+#define CCM_CCGR(n) (CCM_CCGR_OFFSET + 0x10 * (n))
+
+#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50)
+
+#define DBGCAM_EMPTY 0x36000000
+
+void dram_enter_retention(void)
+{
+ /* Wait DBGCAM to be empty */
+ while (mmio_read_32(DDRC_DBGCAM(0)) != DBGCAM_EMPTY) {
+ ;
+ }
+
+ /* Block AXI ports from taking anymore transactions */
+ mmio_write_32(DDRC_PCTRL_0(0), 0x0);
+ /* Wait until all AXI ports are idle */
+ while (mmio_read_32(DDRC_PSTAT(0)) & 0x10001) {
+ ;
+ }
+
+ /* Enter self refresh */
+ mmio_write_32(DDRC_PWRCTL(0), 0xaa);
+
+ /* LPDDR4 & DDR4/DDR3L need to check different status */
+ if (dram_info.dram_type == DDRC_LPDDR4) {
+ while (0x223 != (mmio_read_32(DDRC_STAT(0)) & 0x33f)) {
+ ;
+ }
+ } else {
+ while (0x23 != (mmio_read_32(DDRC_STAT(0)) & 0x3f)) {
+ ;
+ }
+ }
+
+ mmio_write_32(DDRC_DFIMISC(0), 0x0);
+ mmio_write_32(DDRC_SWCTL(0), 0x0);
+ mmio_write_32(DDRC_DFIMISC(0), 0x1f00);
+ mmio_write_32(DDRC_DFIMISC(0), 0x1f20);
+
+ while (mmio_read_32(DDRC_DFISTAT(0)) & 0x1) {
+ ;
+ }
+
+ mmio_write_32(DDRC_DFIMISC(0), 0x1f00);
+ /* wait DFISTAT.dfi_init_complete to 1 */
+ while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
+ ;
+ }
+
+ mmio_write_32(DDRC_SWCTL(0), 0x1);
+
+ /* should check PhyInLP3 pub reg */
+ dwc_ddrphy_apb_wr(0xd0000, 0x0);
+ if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) {
+ INFO("PhyInLP3 = 1\n");
+ }
+ dwc_ddrphy_apb_wr(0xd0000, 0x1);
+
+#if defined(PLAT_imx8mq)
+ /* pwrdnreqn_async adbm/adbs of ddr */
+ mmio_clrbits_32(GPC_PU_PWRHSK, BIT(1));
+ while (mmio_read_32(GPC_PU_PWRHSK) & BIT(18)) {
+ ;
+ }
+ mmio_setbits_32(GPC_PU_PWRHSK, BIT(1));
+#else
+ /* pwrdnreqn_async adbm/adbs of ddr */
+ mmio_clrbits_32(GPC_PU_PWRHSK, BIT(2));
+ while (mmio_read_32(GPC_PU_PWRHSK) & BIT(20)) {
+ ;
+ }
+ mmio_setbits_32(GPC_PU_PWRHSK, BIT(2));
+#endif
+ /* remove PowerOk */
+ mmio_write_32(SRC_DDR1_RCR, 0x8F000008);
+
+ mmio_write_32(CCM_CCGR(5), 0);
+ mmio_write_32(CCM_SRC_CTRL(15), 2);
+
+ /* enable the phy iso */
+ mmio_setbits_32(IMX_GPC_BASE + 0xd40, 1);
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, BIT(5));
+
+ VERBOSE("dram enter retention\n");
+}
+
+void dram_exit_retention(void)
+{
+ VERBOSE("dram exit retention\n");
+ /* assert all reset */
+#if defined(PLAT_imx8mq)
+ mmio_write_32(SRC_DDR2_RCR, 0x8F000003);
+ mmio_write_32(SRC_DDR1_RCR, 0x8F00000F);
+ mmio_write_32(SRC_DDR2_RCR, 0x8F000000);
+#else
+ mmio_write_32(SRC_DDR1_RCR, 0x8F00001F);
+ mmio_write_32(SRC_DDR1_RCR, 0x8F00000F);
+#endif
+ mmio_write_32(CCM_CCGR(5), 2);
+ mmio_write_32(CCM_SRC_CTRL(15), 2);
+
+ /* disable iso */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, BIT(5));
+ mmio_write_32(SRC_DDR1_RCR, 0x8F000006);
+
+ /* wait dram pll locked */
+ while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) {
+ ;
+ }
+
+ /* ddrc re-init */
+ dram_umctl2_init(dram_info.timing_info);
+
+ /*
+ * Skips the DRAM init routine and starts up in selfrefresh mode
+ * Program INIT0.skip_dram_init = 2'b11
+ */
+ mmio_setbits_32(DDRC_INIT0(0), 0xc0000000);
+ /* Keeps the controller in self-refresh mode */
+ mmio_write_32(DDRC_PWRCTL(0), 0xaa);
+ mmio_write_32(DDRC_DBG1(0), 0x0);
+ mmio_write_32(SRC_DDR1_RCR, 0x8F000004);
+ mmio_write_32(SRC_DDR1_RCR, 0x8F000000);
+
+ /* before write Dynamic reg, sw_done should be 0 */
+ mmio_write_32(DDRC_SWCTL(0), 0x0);
+
+#if !PLAT_imx8mn
+ if (dram_info.dram_type == DDRC_LPDDR4) {
+ mmio_write_32(DDRC_DDR_SS_GPR0, 0x01); /*LPDDR4 mode */
+ }
+#endif /* !PLAT_imx8mn */
+
+ mmio_write_32(DDRC_DFIMISC(0), 0x0);
+
+ /* dram phy re-init */
+ dram_phy_init(dram_info.timing_info);
+
+ /* DWC_DDRPHYA_APBONLY0_MicroContMuxSel */
+ dwc_ddrphy_apb_wr(0xd0000, 0x0);
+ while (dwc_ddrphy_apb_rd(0x20097)) {
+ ;
+ }
+ dwc_ddrphy_apb_wr(0xd0000, 0x1);
+
+ /* before write Dynamic reg, sw_done should be 0 */
+ mmio_write_32(DDRC_SWCTL(0), 0x0);
+ mmio_write_32(DDRC_DFIMISC(0), 0x20);
+ /* wait DFISTAT.dfi_init_complete to 1 */
+ while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
+ ;
+ }
+
+ /* clear DFIMISC.dfi_init_start */
+ mmio_write_32(DDRC_DFIMISC(0), 0x0);
+ /* set DFIMISC.dfi_init_complete_en */
+ mmio_write_32(DDRC_DFIMISC(0), 0x1);
+
+ /* set SWCTL.sw_done to enable quasi-dynamic register programming */
+ mmio_write_32(DDRC_SWCTL(0), 0x1);
+ /* wait SWSTAT.sw_done_ack to 1 */
+ while (!(mmio_read_32(DDRC_SWSTAT(0)) & 0x1)) {
+ ;
+ }
+
+ mmio_write_32(DDRC_PWRCTL(0), 0x88);
+ /* wait STAT to normal state */
+ while (0x1 != (mmio_read_32(DDRC_STAT(0)) & 0x7)) {
+ ;
+ }
+
+ mmio_write_32(DDRC_PCTRL_0(0), 0x1);
+ /* dis_auto-refresh is set to 0 */
+ mmio_write_32(DDRC_RFSHCTL3(0), 0x0);
+
+ /* should check PhyInLP3 pub reg */
+ dwc_ddrphy_apb_wr(0xd0000, 0x0);
+ if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) {
+ VERBOSE("PHYInLP3 = 0\n");
+ }
+ dwc_ddrphy_apb_wr(0xd0000, 0x1);
+}
diff --git a/plat/imx/imx8m/ddr/lpddr4_dvfs.c b/plat/imx/imx8m/ddr/lpddr4_dvfs.c
new file mode 100644
index 0000000..2b4f300
--- /dev/null
+++ b/plat/imx/imx8m/ddr/lpddr4_dvfs.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+
+#include <dram.h>
+
+static void lpddr4_mr_write(uint32_t mr_rank, uint32_t mr_addr, uint32_t mr_data)
+{
+ /*
+ * 1. Poll MRSTAT.mr_wr_busy until it is 0. This checks that there
+ * is no outstanding MR transaction. No
+ * writes should be performed to MRCTRL0 and MRCTRL1 if MRSTAT.mr_wr_busy = 1.
+ */
+ while (mmio_read_32(DDRC_MRSTAT(0)) & 0x1)
+ ;
+
+ /*
+ * 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr,
+ * MRCTRL0.mr_rank and (for MRWs)
+ * MRCTRL1.mr_data to define the MR transaction.
+ */
+ mmio_write_32(DDRC_MRCTRL0(0), (mr_rank << 4));
+ mmio_write_32(DDRC_MRCTRL1(0), (mr_addr << 8) | mr_data);
+ mmio_setbits_32(DDRC_MRCTRL0(0), BIT(31));
+}
+
+void lpddr4_swffc(struct dram_info *info, unsigned int init_fsp,
+ unsigned int fsp_index)
+
+{
+ uint32_t mr, emr, emr2, emr3;
+ uint32_t mr11, mr12, mr22, mr14;
+ uint32_t val;
+ uint32_t derate_backup[3];
+ uint32_t (*mr_data)[8];
+
+ /* 1. program targetd UMCTL2_REGS_FREQ1/2/3,already done, skip it. */
+
+ /* 2. MR13.FSP-WR=1, MRW to update MR registers */
+ mr_data = info->mr_table;
+ mr = mr_data[fsp_index][0];
+ emr = mr_data[fsp_index][1];
+ emr2 = mr_data[fsp_index][2];
+ emr3 = mr_data[fsp_index][3];
+ mr11 = mr_data[fsp_index][4];
+ mr12 = mr_data[fsp_index][5];
+ mr22 = mr_data[fsp_index][6];
+ mr14 = mr_data[fsp_index][7];
+
+ val = (init_fsp == 1) ? 0x2 << 6 : 0x1 << 6;
+ emr3 = (emr3 & 0x003f) | val | 0x0d00;
+
+ /* 12. set PWRCTL.selfref_en=0 */
+ mmio_clrbits_32(DDRC_PWRCTL(0), 0xf);
+
+ /* It is more safe to config it here */
+ mmio_clrbits_32(DDRC_DFIPHYMSTR(0), 0x1);
+
+ lpddr4_mr_write(3, 13, emr3);
+ lpddr4_mr_write(3, 1, mr);
+ lpddr4_mr_write(3, 2, emr);
+ lpddr4_mr_write(3, 3, emr2);
+ lpddr4_mr_write(3, 11, mr11);
+ lpddr4_mr_write(3, 12, mr12);
+ lpddr4_mr_write(3, 14, mr14);
+ lpddr4_mr_write(3, 22, mr22);
+
+ do {
+ val = mmio_read_32(DDRC_MRSTAT(0));
+ } while (val & 0x1);
+
+ /* 3. disable AXI ports */
+ mmio_write_32(DDRC_PCTRL_0(0), 0x0);
+
+ /* 4.Poll PSTAT.rd_port_busy_n=0 and PSTAT.wr_port_busy_n=0. */
+ do {
+ val = mmio_read_32(DDRC_PSTAT(0));
+ } while (val != 0);
+
+ /* 6.disable SBRCTL.scrub_en, skip if never enable it */
+ /* 7.poll SBRSTAT.scrub_busy Q2: should skip phy master if never enable it */
+ /* Disable phy master */
+#ifdef DFILP_SPT
+ /* 8. disable DFI LP */
+ /* DFILPCFG0.dfi_lp_en_sr */
+ val = mmio_read_32(DDRC_DFILPCFG0(0));
+ if (val & 0x100) {
+ mmio_write_32(DDRC_DFILPCFG0(0), 0x0);
+ do {
+ val = mmio_read_32(DDRC_DFISTAT(0)); // dfi_lp_ack
+ val2 = mmio_read_32(DDRC_STAT(0)); // operating_mode
+ } while (((val & 0x2) == 0x2) && ((val2 & 0x7) == 3));
+ }
+#endif
+ /* 9. wait until in normal or power down states */
+ do {
+ /* operating_mode */
+ val = mmio_read_32(DDRC_STAT(0));
+ } while (((val & 0x7) != 1) && ((val & 0x7) != 2));
+
+ /* 10. Disable automatic derating: derate_enable */
+ val = mmio_read_32(DDRC_DERATEEN(0));
+ derate_backup[0] = val;
+ mmio_clrbits_32(DDRC_DERATEEN(0), 0x1);
+
+ val = mmio_read_32(DDRC_FREQ1_DERATEEN(0));
+ derate_backup[1] = val;
+ mmio_clrbits_32(DDRC_FREQ1_DERATEEN(0), 0x1);
+
+ val = mmio_read_32(DDRC_FREQ2_DERATEEN(0));
+ derate_backup[2] = val;
+ mmio_clrbits_32(DDRC_FREQ2_DERATEEN(0), 0x1);
+
+ /* 11. disable automatic ZQ calibration */
+ mmio_setbits_32(DDRC_ZQCTL0(0), BIT(31));
+ mmio_setbits_32(DDRC_FREQ1_ZQCTL0(0), BIT(31));
+ mmio_setbits_32(DDRC_FREQ2_ZQCTL0(0), BIT(31));
+
+ /* 12. set PWRCTL.selfref_en=0 */
+ mmio_clrbits_32(DDRC_PWRCTL(0), 0x1);
+
+ /* 13.Poll STAT.operating_mode is in "Normal" (001) or "Power-down" (010) */
+ do {
+ val = mmio_read_32(DDRC_STAT(0));
+ } while (((val & 0x7) != 1) && ((val & 0x7) != 2));
+
+ /* 14-15. trigger SW SR */
+ /* bit 5: selfref_sw, bit 6: stay_in_selfref */
+ mmio_setbits_32(DDRC_PWRCTL(0), 0x60);
+
+ /* 16. Poll STAT.selfref_state in "Self Refresh 1" */
+ do {
+ val = mmio_read_32(DDRC_STAT(0));
+ } while ((val & 0x300) != 0x100);
+
+ /* 17. disable dq */
+ mmio_setbits_32(DDRC_DBG1(0), 0x1);
+
+ /* 18. Poll DBGCAM.wr_data_pipeline_empty and DBGCAM.rd_data_pipeline_empty */
+ do {
+ val = mmio_read_32(DDRC_DBGCAM(0));
+ val &= 0x30000000;
+ } while (val != 0x30000000);
+
+ /* 19. change MR13.FSP-OP to new FSP and MR13.VRCG to high current */
+ emr3 = (((~init_fsp) & 0x1) << 7) | (0x1 << 3) | (emr3 & 0x0077) | 0x0d00;
+ lpddr4_mr_write(3, 13, emr3);
+
+ /* 20. enter SR Power Down */
+ mmio_clrsetbits_32(DDRC_PWRCTL(0), 0x60, 0x20);
+
+ /* 21. Poll STAT.selfref_state is in "SR Power down" */
+ do {
+ val = mmio_read_32(DDRC_STAT(0));
+ } while ((val & 0x300) != 0x200);
+
+ /* 22. set dfi_init_complete_en = 0 */
+
+ /* 23. switch clock */
+ /* set SWCTL.dw_done to 0 */
+ mmio_write_32(DDRC_SWCTL(0), 0x0000);
+
+ /* 24. program frequency mode=1(bit 29), target_frequency=target_freq (bit 29) */
+ mmio_write_32(DDRC_MSTR2(0), fsp_index);
+
+ /* 25. DBICTL for FSP-OP[1], skip it if never enable it */
+
+ /* 26.trigger initialization in the PHY */
+
+ /* Q3: if refresh level is updated, then should program */
+ /* as updating refresh, need to toggle refresh_update_level signal */
+ val = mmio_read_32(DDRC_RFSHCTL3(0));
+ val = val ^ 0x2;
+ mmio_write_32(DDRC_RFSHCTL3(0), val);
+
+ /* Q4: only for legacy PHY, so here can skipped */
+
+ /* dfi_frequency -> 0x1x */
+ val = mmio_read_32(DDRC_DFIMISC(0));
+ val &= 0xFE;
+ val |= (fsp_index << 8);
+ mmio_write_32(DDRC_DFIMISC(0), val);
+ /* dfi_init_start */
+ val |= 0x20;
+ mmio_write_32(DDRC_DFIMISC(0), val);
+
+ /* polling dfi_init_complete de-assert */
+ do {
+ val = mmio_read_32(DDRC_DFISTAT(0));
+ } while ((val & 0x1) == 0x1);
+
+ /* change the clock frequency */
+ dram_clock_switch(info->timing_info->fsp_table[fsp_index], info->bypass_mode);
+
+ /* dfi_init_start de-assert */
+ mmio_clrbits_32(DDRC_DFIMISC(0), 0x20);
+
+ /* polling dfi_init_complete re-assert */
+ do {
+ val = mmio_read_32(DDRC_DFISTAT(0));
+ } while ((val & 0x1) == 0x0);
+
+ /* 27. set ZQCTL0.dis_srx_zqcl = 1 */
+ if (fsp_index == 0) {
+ mmio_setbits_32(DDRC_ZQCTL0(0), BIT(30));
+ } else if (fsp_index == 1) {
+ mmio_setbits_32(DDRC_FREQ1_ZQCTL0(0), BIT(30));
+ } else {
+ mmio_setbits_32(DDRC_FREQ2_ZQCTL0(0), BIT(30));
+ }
+
+ /* 28,29. exit "self refresh power down" to stay "self refresh 2" */
+ /* exit SR power down */
+ mmio_clrsetbits_32(DDRC_PWRCTL(0), 0x60, 0x40);
+ /* 30. Poll STAT.selfref_state in "Self refresh 2" */
+ do {
+ val = mmio_read_32(DDRC_STAT(0));
+ } while ((val & 0x300) != 0x300);
+
+ /* 31. change MR13.VRCG to normal */
+ emr3 = (emr3 & 0x00f7) | 0x0d00;
+ lpddr4_mr_write(3, 13, emr3);
+
+ /* enable PHY master */
+ mmio_write_32(DDRC_DFIPHYMSTR(0), 0x1);
+
+ /* 32. issue ZQ if required: zq_calib_short, bit 4 */
+ /* polling zq_calib_short_busy */
+ mmio_setbits_32(DDRC_DBGCMD(0), 0x10);
+
+ do {
+ val = mmio_read_32(DDRC_DBGSTAT(0));
+ } while ((val & 0x10) != 0x0);
+
+ /* 33. Reset ZQCTL0.dis_srx_zqcl=0 */
+ if (fsp_index == 1)
+ mmio_clrbits_32(DDRC_FREQ1_ZQCTL0(0), BIT(30));
+ else if (fsp_index == 2)
+ mmio_clrbits_32(DDRC_FREQ2_ZQCTL0(0), BIT(30));
+ else
+ mmio_clrbits_32(DDRC_ZQCTL0(0), BIT(30));
+
+ /* set SWCTL.dw_done to 1 and poll SWSTAT.sw_done_ack=1 */
+ mmio_write_32(DDRC_SWCTL(0), 0x1);
+
+ /* wait SWSTAT.sw_done_ack to 1 */
+ do {
+ val = mmio_read_32(DDRC_SWSTAT(0));
+ } while ((val & 0x1) == 0x0);
+
+ /* 34. set PWRCTL.stay_in_selfreh=0, exit SR */
+ mmio_clrbits_32(DDRC_PWRCTL(0), 0x40);
+ /* wait tXSR */
+
+ /* 35. Poll STAT.selfref_state in "Idle" */
+ do {
+ val = mmio_read_32(DDRC_STAT(0));
+ } while ((val & 0x300) != 0x0);
+
+#ifdef DFILP_SPT
+ /* 36. restore dfi_lp.dfi_lp_en_sr */
+ mmio_setbits_32(DDRC_DFILPCFG0(0), BIT(8));
+#endif
+
+ /* 37. re-enable CAM: dis_dq */
+ mmio_clrbits_32(DDRC_DBG1(0), 0x1);
+
+ /* 38. re-enable automatic SR: selfref_en */
+ mmio_setbits_32(DDRC_PWRCTL(0), 0x1);
+
+ /* 39. re-enable automatic ZQ: dis_auto_zq=0 */
+ /* disable automatic ZQ calibration */
+ if (fsp_index == 1)
+ mmio_clrbits_32(DDRC_FREQ1_ZQCTL0(0), BIT(31));
+ else if (fsp_index == 2)
+ mmio_clrbits_32(DDRC_FREQ2_ZQCTL0(0), BIT(31));
+ else
+ mmio_clrbits_32(DDRC_ZQCTL0(0), BIT(31));
+ /* 40. re-emable automatic derating: derate_enable */
+ mmio_write_32(DDRC_DERATEEN(0), derate_backup[0]);
+ mmio_write_32(DDRC_FREQ1_DERATEEN(0), derate_backup[1]);
+ mmio_write_32(DDRC_FREQ2_DERATEEN(0), derate_backup[2]);
+
+ /* 41. write 1 to PCTRL.port_en */
+ mmio_write_32(DDRC_PCTRL_0(0), 0x1);
+
+ /* 42. enable SBRCTL.scrub_en, skip if never enable it */
+}
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c
index 1e55f05..e674d7a 100644
--- a/plat/imx/imx8m/gpc_common.c
+++ b/plat/imx/imx8m/gpc_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
+#include <common/runtime_svc.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
@@ -16,10 +17,14 @@
#include <imx8m_psci.h>
#include <plat_imx8.h>
+#define MAX_PLL_NUM U(10)
+
static uint32_t gpc_imr_offset[] = { IMR1_CORE0_A53, IMR1_CORE1_A53, IMR1_CORE2_A53, IMR1_CORE3_A53, };
DEFINE_BAKERY_LOCK(gpc_lock);
+#define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03
+
#pragma weak imx_set_cpu_pwr_off
#pragma weak imx_set_cpu_pwr_on
#pragma weak imx_set_cpu_lpm
@@ -250,3 +255,54 @@
mmio_clrbits_32(IMX_GPC_BASE + SLPCR, SLPCR_RBC_EN |
(0x3f << SLPCR_RBC_COUNT_SHIFT));
}
+
+struct pll_override {
+ uint32_t reg;
+ uint32_t override_mask;
+};
+
+struct pll_override pll[MAX_PLL_NUM] = {
+ {.reg = 0x0, .override_mask = (1 << 12) | (1 << 8), },
+ {.reg = 0x14, .override_mask = (1 << 12) | (1 << 8), },
+ {.reg = 0x28, .override_mask = (1 << 12) | (1 << 8), },
+ {.reg = 0x50, .override_mask = (1 << 12) | (1 << 8), },
+ {.reg = 0x64, .override_mask = (1 << 10) | (1 << 8), },
+ {.reg = 0x74, .override_mask = (1 << 10) | (1 << 8), },
+ {.reg = 0x84, .override_mask = (1 << 10) | (1 << 8), },
+ {.reg = 0x94, .override_mask = 0x5555500, },
+ {.reg = 0x104, .override_mask = 0x5555500, },
+ {.reg = 0x114, .override_mask = 0x500, },
+};
+
+#define PLL_BYPASS BIT(4)
+void imx_anamix_override(bool enter)
+{
+ unsigned int i;
+
+ /*
+ * bypass all the plls & enable the override bit before
+ * entering DSM mode.
+ */
+ for (i = 0U; i < MAX_PLL_NUM; i++) {
+ if (enter) {
+ mmio_setbits_32(IMX_ANAMIX_BASE + pll[i].reg, PLL_BYPASS);
+ mmio_setbits_32(IMX_ANAMIX_BASE + pll[i].reg, pll[i].override_mask);
+ } else {
+ mmio_clrbits_32(IMX_ANAMIX_BASE + pll[i].reg, PLL_BYPASS);
+ mmio_clrbits_32(IMX_ANAMIX_BASE + pll[i].reg, pll[i].override_mask);
+ }
+ }
+}
+
+int imx_gpc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3)
+{
+ switch (x1) {
+ case FSL_SIP_CONFIG_GPC_PM_DOMAIN:
+ imx_gpc_pm_domain_enable(x2, x3);
+ break;
+ default:
+ return SMC_UNK;
+ }
+
+ return 0;
+}
diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c
index 9dfd311..4df4f8e 100644
--- a/plat/imx/imx8m/imx8m_psci_common.c
+++ b/plat/imx/imx8m/imx8m_psci_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,7 @@
#include <lib/mmio.h>
#include <lib/psci/psci.h>
+#include <dram.h>
#include <gpc.h>
#include <imx8m_psci.h>
#include <plat_imx8.h>
@@ -118,8 +119,11 @@
if (!is_local_state_run(CLUSTER_PWR_STATE(target_state)))
imx_set_cluster_powerdown(core_id, CLUSTER_PWR_STATE(target_state));
- if (is_local_state_off(SYSTEM_PWR_STATE(target_state)))
+ if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
imx_set_sys_lpm(core_id, true);
+ dram_enter_retention();
+ imx_anamix_override(true);
+ }
}
void imx_domain_suspend_finish(const psci_power_state_t *target_state)
@@ -127,8 +131,11 @@
uint64_t mpidr = read_mpidr_el1();
unsigned int core_id = MPIDR_AFFLVL0_VAL(mpidr);
- if (is_local_state_off(SYSTEM_PWR_STATE(target_state)))
+ if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
+ imx_anamix_override(false);
+ dram_exit_retention();
imx_set_sys_lpm(core_id, false);
+ }
if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) {
imx_clear_rbc_count();
diff --git a/plat/imx/imx8m/imx8mm/gpc.c b/plat/imx/imx8m/imx8mm/gpc.c
index ab59292..cc1cb10 100644
--- a/plat/imx/imx8m/imx8mm/gpc.c
+++ b/plat/imx/imx8m/imx8mm/gpc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,6 +19,332 @@
#include <gpc.h>
#include <imx_sip_svc.h>
+#define MIPI_PWR_REQ BIT(0)
+#define PCIE_PWR_REQ BIT(1)
+#define OTG1_PWR_REQ BIT(2)
+#define OTG2_PWR_REQ BIT(3)
+#define HSIOMIX_PWR_REQ BIT(4)
+#define GPU2D_PWR_REQ BIT(6)
+#define GPUMIX_PWR_REQ BIT(7)
+#define VPUMIX_PWR_REQ BIT(8)
+#define GPU3D_PWR_REQ BIT(9)
+#define DISPMIX_PWR_REQ BIT(10)
+#define VPU_G1_PWR_REQ BIT(11)
+#define VPU_G2_PWR_REQ BIT(12)
+#define VPU_H1_PWR_REQ BIT(13)
+
+#define HSIOMIX_ADB400_SYNC (0x3 << 5)
+#define DISPMIX_ADB400_SYNC BIT(7)
+#define VPUMIX_ADB400_SYNC BIT(8)
+#define GPU3D_ADB400_SYNC BIT(9)
+#define GPU2D_ADB400_SYNC BIT(10)
+#define GPUMIX_ADB400_SYNC BIT(11)
+#define HSIOMIX_ADB400_ACK (0x3 << 23)
+#define DISPMIX_ADB400_ACK BIT(25)
+#define VPUMIX_ADB400_ACK BIT(26)
+#define GPU3D_ADB400_ACK BIT(27)
+#define GPU2D_ADB400_ACK BIT(28)
+#define GPUMIX_ADB400_ACK BIT(29)
+
+#define MIPI_PGC 0xc00
+#define PCIE_PGC 0xc40
+#define OTG1_PGC 0xc80
+#define OTG2_PGC 0xcc0
+#define HSIOMIX_PGC 0xd00
+#define GPU2D_PGC 0xd80
+#define GPUMIX_PGC 0xdc0
+#define VPUMIX_PGC 0xe00
+#define GPU3D_PGC 0xe40
+#define DISPMIX_PGC 0xe80
+#define VPU_G1_PGC 0xec0
+#define VPU_G2_PGC 0xf00
+#define VPU_H1_PGC 0xf40
+
+enum pu_domain_id {
+ HSIOMIX,
+ PCIE,
+ OTG1,
+ OTG2,
+ GPUMIX,
+ VPUMIX,
+ VPU_G1,
+ VPU_G2,
+ VPU_H1,
+ DISPMIX,
+ MIPI,
+ /* below two domain only for ATF internal use */
+ GPU2D,
+ GPU3D,
+ MAX_DOMAINS,
+};
+
+/* PU domain */
+static struct imx_pwr_domain pu_domains[] = {
+ IMX_MIX_DOMAIN(HSIOMIX, false),
+ IMX_PD_DOMAIN(PCIE, false),
+ IMX_PD_DOMAIN(OTG1, true),
+ IMX_PD_DOMAIN(OTG2, true),
+ IMX_MIX_DOMAIN(GPUMIX, false),
+ IMX_MIX_DOMAIN(VPUMIX, false),
+ IMX_PD_DOMAIN(VPU_G1, false),
+ IMX_PD_DOMAIN(VPU_G2, false),
+ IMX_PD_DOMAIN(VPU_H1, false),
+ IMX_MIX_DOMAIN(DISPMIX, false),
+ IMX_PD_DOMAIN(MIPI, false),
+ /* below two domain only for ATF internal use */
+ IMX_MIX_DOMAIN(GPU2D, false),
+ IMX_MIX_DOMAIN(GPU3D, false),
+};
+
+static unsigned int pu_domain_status;
+
+#define GPU_RCR 0x40
+#define VPU_RCR 0x44
+
+#define VPU_CTL_BASE 0x38330000
+#define BLK_SFT_RSTN_CSR 0x0
+#define H1_SFT_RSTN BIT(2)
+#define G1_SFT_RSTN BIT(1)
+#define G2_SFT_RSTN BIT(0)
+
+#define DISP_CTL_BASE 0x32e28000
+
+void vpu_sft_reset_assert(uint32_t domain_id)
+{
+ uint32_t val;
+
+ val = mmio_read_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR);
+
+ switch (domain_id) {
+ case VPU_G1:
+ val &= ~G1_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ case VPU_G2:
+ val &= ~G2_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ case VPU_H1:
+ val &= ~H1_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ default:
+ break;
+ }
+}
+
+void vpu_sft_reset_deassert(uint32_t domain_id)
+{
+ uint32_t val;
+
+ val = mmio_read_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR);
+
+ switch (domain_id) {
+ case VPU_G1:
+ val |= G1_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ case VPU_G2:
+ val |= G2_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ case VPU_H1:
+ val |= H1_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ default:
+ break;
+ }
+}
+
+void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
+{
+ if (domain_id >= MAX_DOMAINS) {
+ return;
+ }
+
+ struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id];
+
+ if (on) {
+ pu_domain_status |= (1 << domain_id);
+
+ if (domain_id == VPU_G1 || domain_id == VPU_G2 ||
+ domain_id == VPU_H1) {
+ vpu_sft_reset_assert(domain_id);
+ }
+
+ /* HSIOMIX has no PU bit, so skip for it */
+ if (domain_id != HSIOMIX) {
+ /* clear the PGC bit */
+ mmio_clrbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
+
+ /* power up the domain */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, pwr_domain->pwr_req);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & pwr_domain->pwr_req) {
+ ;
+ }
+ }
+
+ if (domain_id == VPU_G1 || domain_id == VPU_G2 ||
+ domain_id == VPU_H1) {
+ vpu_sft_reset_deassert(domain_id);
+ /* dealy for a while to make sure reset done */
+ udelay(100);
+ }
+
+ if (domain_id == GPUMIX) {
+ /* assert reset */
+ mmio_write_32(IMX_SRC_BASE + GPU_RCR, 0x1);
+
+ /* power up GPU2D */
+ mmio_clrbits_32(IMX_GPC_BASE + GPU2D_PGC, 0x1);
+
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, GPU2D_PWR_REQ);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & GPU2D_PWR_REQ) {
+ ;
+ }
+
+ udelay(1);
+
+ /* power up GPU3D */
+ mmio_clrbits_32(IMX_GPC_BASE + GPU3D_PGC, 0x1);
+
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, GPU3D_PWR_REQ);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & GPU3D_PWR_REQ) {
+ ;
+ }
+
+ udelay(10);
+ /* release the gpumix reset */
+ mmio_write_32(IMX_SRC_BASE + GPU_RCR, 0x0);
+ udelay(10);
+ }
+
+ /* vpu sft clock enable */
+ if (domain_id == VPUMIX) {
+ mmio_write_32(IMX_SRC_BASE + VPU_RCR, 0x1);
+ udelay(5);
+ mmio_write_32(IMX_SRC_BASE + VPU_RCR, 0x0);
+ udelay(5);
+
+ /* enable all clock */
+ mmio_write_32(VPU_CTL_BASE + 0x4, 0x7);
+ }
+
+ if (domain_id == DISPMIX) {
+ /* special setting for DISPMIX */
+ mmio_write_32(DISP_CTL_BASE + 0x4, 0x1fff);
+ mmio_write_32(DISP_CTL_BASE, 0x7f);
+ mmio_write_32(DISP_CTL_BASE + 0x8, 0x30000);
+ }
+
+ /* handle the ADB400 sync */
+ if (pwr_domain->need_sync) {
+ /* clear adb power down request */
+ mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
+
+ /* wait for adb power request ack */
+ while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
+ ;
+ }
+ }
+
+ if (domain_id == GPUMIX) {
+ /* power up GPU2D ADB */
+ mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU2D_ADB400_SYNC);
+
+ /* wait for adb power request ack */
+ while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU2D_ADB400_ACK)) {
+ ;
+ }
+
+ /* power up GPU3D ADB */
+ mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU3D_ADB400_SYNC);
+
+ /* wait for adb power request ack */
+ while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU3D_ADB400_ACK)) {
+ ;
+ }
+ }
+ } else {
+ pu_domain_status &= ~(1 << domain_id);
+
+ if (domain_id == OTG1 || domain_id == OTG2) {
+ return;
+ }
+
+ /* GPU2D & GPU3D ADB power down */
+ if (domain_id == GPUMIX) {
+ mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU2D_ADB400_SYNC);
+
+ /* wait for adb power request ack */
+ while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU2D_ADB400_ACK)) {
+ ;
+ }
+
+ mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU3D_ADB400_SYNC);
+
+ /* wait for adb power request ack */
+ while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU3D_ADB400_ACK)) {
+ ;
+ }
+ }
+
+ /* handle the ADB400 sync */
+ if (pwr_domain->need_sync) {
+ /* set adb power down request */
+ mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
+
+ /* wait for adb power request ack */
+ while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
+ ;
+ }
+ }
+
+ if (domain_id == GPUMIX) {
+ /* power down GPU2D */
+ mmio_setbits_32(IMX_GPC_BASE + GPU2D_PGC, 0x1);
+
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, GPU2D_PWR_REQ);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & GPU2D_PWR_REQ) {
+ ;
+ }
+
+ /* power down GPU3D */
+ mmio_setbits_32(IMX_GPC_BASE + GPU3D_PGC, 0x1);
+
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, GPU3D_PWR_REQ);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & GPU3D_PWR_REQ) {
+ ;
+ }
+ }
+
+ /* HSIOMIX has no PU bit, so skip for it */
+ if (domain_id != HSIOMIX) {
+ /* set the PGC bit */
+ mmio_setbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
+
+ /* power down the domain */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, pwr_domain->pwr_req);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & pwr_domain->pwr_req) {
+ ;
+ }
+ }
+ }
+}
+
void imx_gpc_init(void)
{
unsigned int val;
@@ -85,7 +411,4 @@
*/
mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1);
-
- /* enable all the power domain by default */
- mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x3fcf);
}
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index debede1..ba0db0c 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -21,6 +21,7 @@
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
+#include <dram.h>
#include <gpc.h>
#include <imx_aipstz.h>
#include <imx_uart.h>
@@ -34,6 +35,9 @@
static const mmap_region_t imx_mmap[] = {
MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW),
MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW), /* AIPS map */
+ MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_DEVICE | MT_RW), /* OCRAM_S */
+ MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW), /* DDRMIX */
+ MAP_REGION_FLAT(IMX_VPUMIX_BASE, IMX_VPUMIX_SIZE, MT_DEVICE | MT_RW), /* VPUMIX */
{0},
};
@@ -198,6 +202,9 @@
/* select the CKIL source to 32K OSC */
mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
+ /* Init the dram info */
+ dram_info_init(SAVED_DRAM_TIMING_BASE);
+
plat_gic_driver_init();
plat_gic_init();
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index ed693b9..84d86b9 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -6,6 +6,7 @@
#include <arch.h>
#include <common/tbbr/tbbr_img_def.h>
+#include <lib/utils_def.h>
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
@@ -85,7 +86,7 @@
#define IMX_AIPSTZ4 U(0x32df0000)
#define IMX_AIPS_BASE U(0x30000000)
-#define IMX_AIPS_SIZE U(0xC00000)
+#define IMX_AIPS_SIZE U(0x3000000)
#define IMX_GPV_BASE U(0x32000000)
#define IMX_GPV_SIZE U(0x800000)
#define IMX_AIPS1_BASE U(0x30200000)
@@ -105,7 +106,10 @@
#define IMX_DDRC_BASE U(0x3d400000)
#define IMX_DDRPHY_BASE U(0x3c000000)
#define IMX_DDR_IPS_BASE U(0x3d000000)
+#define IMX_DDR_IPS_SIZE U(0x1800000)
#define IMX_ROM_BASE U(0x0)
+#define IMX_VPUMIX_BASE U(0x38330000)
+#define IMX_VPUMIX_SIZE U(0x100000)
#define GPV_BASE U(0x32000000)
#define GPV_SIZE U(0x800000)
@@ -140,12 +144,14 @@
#define GPR_TZASC_EN_LOCK BIT(16)
#define ANAMIX_MISC_CTL U(0x124)
+#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50)
#define MAX_CSU_NUM U(64)
#define OCRAM_S_BASE U(0x00180000)
#define OCRAM_S_SIZE U(0x8000)
#define OCRAM_S_LIMIT (OCRAM_S_BASE + OCRAM_S_SIZE)
+#define SAVED_DRAM_TIMING_BASE OCRAM_S_BASE
#define COUNTER_FREQUENCY 8000000 /* 8MHz */
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index 60fa325..1c6c9f8 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -19,6 +19,12 @@
include lib/libfdt/libfdt.mk
+IMX_DRAM_SOURCES := plat/imx/imx8m/ddr/dram.c \
+ plat/imx/imx8m/ddr/clock.c \
+ plat/imx/imx8m/ddr/dram_retention.c \
+ plat/imx/imx8m/ddr/ddr4_dvfs.c \
+ plat/imx/imx8m/ddr/lpddr4_dvfs.c
+
IMX_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
@@ -43,6 +49,7 @@
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
${XLAT_TABLES_LIB_SRCS} \
+ ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES}
ifeq (${NEED_BL2},yes)
diff --git a/plat/imx/imx8m/imx8mn/gpc.c b/plat/imx/imx8m/imx8mn/gpc.c
index 37d4226..4e05297 100644
--- a/plat/imx/imx8m/imx8mn/gpc.c
+++ b/plat/imx/imx8m/imx8mn/gpc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 NXP
+ * Copyright 2019-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,6 +21,124 @@
#define CCGR(x) (0x4000 + (x) * 0x10)
+#define MIPI_PWR_REQ BIT(0)
+#define OTG1_PWR_REQ BIT(2)
+#define HSIOMIX_PWR_REQ BIT(4)
+#define GPUMIX_PWR_REQ BIT(7)
+#define DISPMIX_PWR_REQ BIT(10)
+
+#define HSIOMIX_ADB400_SYNC BIT(5)
+#define DISPMIX_ADB400_SYNC BIT(7)
+#define GPUMIX_ADB400_SYNC (0x5 << 9)
+#define HSIOMIX_ADB400_ACK BIT(23)
+#define DISPMIX_ADB400_ACK BIT(25)
+#define GPUMIX_ADB400_ACK (0x5 << 27)
+
+#define MIPI_PGC 0xc00
+#define OTG1_PGC 0xc80
+#define HSIOMIX_PGC 0xd00
+#define GPUMIX_PGC 0xdc0
+#define DISPMIX_PGC 0xe80
+
+enum pu_domain_id {
+ HSIOMIX,
+ OTG1 = 2,
+ GPUMIX = 4,
+ DISPMIX = 9,
+ MIPI,
+};
+
+/* PU domain, add some hole to minimize the uboot change */
+static struct imx_pwr_domain pu_domains[11] = {
+ [HSIOMIX] = IMX_MIX_DOMAIN(HSIOMIX, false),
+ [OTG1] = IMX_PD_DOMAIN(OTG1, true),
+ [GPUMIX] = IMX_MIX_DOMAIN(GPUMIX, false),
+ [DISPMIX] = IMX_MIX_DOMAIN(DISPMIX, false),
+ [MIPI] = IMX_PD_DOMAIN(MIPI, true),
+};
+
+static unsigned int pu_domain_status;
+
+void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
+{
+ if (domain_id > MIPI) {
+ return;
+ }
+
+ struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id];
+
+ if (on) {
+ if (pwr_domain->need_sync) {
+ pu_domain_status |= (1 << domain_id);
+ }
+
+ /* HSIOMIX has no PU bit, so skip for it */
+ if (domain_id != HSIOMIX) {
+ /* clear the PGC bit */
+ mmio_clrbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
+
+ /* power up the domain */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, pwr_domain->pwr_req);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & pwr_domain->pwr_req) {
+ ;
+ }
+ }
+
+ if (domain_id == DISPMIX) {
+ /* de-reset bus_blk clk and
+ * enable bus_blk clk
+ */
+ mmio_write_32(0x32e28000, 0x100);
+ mmio_write_32(0x32e28004, 0x100);
+ }
+
+ /* handle the ADB400 sync */
+ if (pwr_domain->need_sync) {
+ /* clear adb power down request */
+ mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
+
+ /* wait for adb power request ack */
+ while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
+ ;
+ }
+ }
+ } else {
+ pu_domain_status &= ~(1 << domain_id);
+
+ if (domain_id == OTG1) {
+ return;
+ }
+
+ /* handle the ADB400 sync */
+ if (pwr_domain->need_sync) {
+
+ /* set adb power down request */
+ mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
+
+ /* wait for adb power request ack */
+ while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
+ ;
+ }
+ }
+
+ /* HSIOMIX has no PU bit, so skip for it */
+ if (domain_id != HSIOMIX) {
+ /* set the PGC bit */
+ mmio_setbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
+
+ /* power down the domain */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, pwr_domain->pwr_req);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & pwr_domain->pwr_req) {
+ ;
+ }
+ }
+ }
+}
+
void imx_gpc_init(void)
{
unsigned int val;
@@ -86,9 +204,4 @@
* only need to do it once.
*/
mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
-
- /* enable all the power domain by default */
- for (i = 0; i < 103; i++)
- mmio_write_32(IMX_CCM_BASE + CCGR(i), 0x3);
- mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x485);
}
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index 8147792..5d2a64e 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -19,6 +19,7 @@
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
+#include <dram.h>
#include <gpc.h>
#include <imx_aipstz.h>
#include <imx_uart.h>
@@ -207,6 +208,9 @@
/* select the CKIL source to 32K OSC */
mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
+ /* Init the dram info */
+ dram_info_init(SAVED_DRAM_TIMING_BASE);
+
plat_gic_driver_init();
plat_gic_init();
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index 8d39ea6..dbb4416 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -9,6 +9,8 @@
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <lib/utils_def.h>
+
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
@@ -70,7 +72,7 @@
#define IMX_AIPSTZ4 U(0x32df0000)
#define IMX_AIPS_BASE U(0x30000000)
-#define IMX_AIPS_SIZE U(0xC00000)
+#define IMX_AIPS_SIZE U(0x3000000)
#define IMX_GPV_BASE U(0x32000000)
#define IMX_GPV_SIZE U(0x800000)
#define IMX_AIPS1_BASE U(0x30200000)
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
index 54be41b..0f3ad1a 100644
--- a/plat/imx/imx8m/imx8mn/platform.mk
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -13,6 +13,13 @@
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
+IMX_DRAM_SOURCES := plat/imx/imx8m/ddr/dram.c \
+ plat/imx/imx8m/ddr/clock.c \
+ plat/imx/imx8m/ddr/dram_retention.c \
+ plat/imx/imx8m/ddr/ddr4_dvfs.c \
+ plat/imx/imx8m/ddr/lpddr4_dvfs.c
+
+
IMX_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
@@ -36,6 +43,7 @@
drivers/arm/tzc/tzc380.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES} \
${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/imx/imx8m/imx8mp/gpc.c b/plat/imx/imx8m/imx8mp/gpc.c
index 3d68b94..452e788 100644
--- a/plat/imx/imx8m/imx8mp/gpc.c
+++ b/plat/imx/imx8m/imx8mp/gpc.c
@@ -170,7 +170,7 @@
}
}
-static void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
+void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
{
struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id];
unsigned int i;
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index 57e5c51..d443c3d 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -19,6 +19,7 @@
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
+#include <dram.h>
#include <gpc.h>
#include <imx_aipstz.h>
#include <imx_uart.h>
@@ -203,6 +204,9 @@
/* select the CKIL source to 32K OSC */
mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
+ /* Init the dram info */
+ dram_info_init(SAVED_DRAM_TIMING_BASE);
+
plat_gic_driver_init();
plat_gic_init();
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 73fbd87..45f2972 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -15,6 +15,12 @@
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
+IMX_DRAM_SOURCES := plat/imx/imx8m/ddr/dram.c \
+ plat/imx/imx8m/ddr/clock.c \
+ plat/imx/imx8m/ddr/dram_retention.c \
+ plat/imx/imx8m/ddr/ddr4_dvfs.c \
+ plat/imx/imx8m/ddr/lpddr4_dvfs.c
+
IMX_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
@@ -38,6 +44,7 @@
drivers/arm/tzc/tzc380.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES} \
${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/imx/imx8m/include/ddrc.h b/plat/imx/imx8m/include/ddrc.h
new file mode 100644
index 0000000..55af3ff
--- /dev/null
+++ b/plat/imx/imx8m/include/ddrc.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2019-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_DDRC_H
+#define IMX_DDRC_H
+
+#define DDRC_IPS_BASE_ADDR(X) (0x3d400000 + ((X) * 0x2000000))
+#define DDRC_DDR_SS_GPR0 0x3d000000
+
+/* DWC ddr umctl2 REGs offset*/
+/**********************/
+#define DDRC_MSTR(X) (DDRC_IPS_BASE_ADDR(X) + 0x00)
+#define DDRC_STAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x04)
+#define DDRC_MSTR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x08)
+#define DDRC_MRCTRL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x10)
+#define DDRC_MRCTRL1(X) (DDRC_IPS_BASE_ADDR(X) + 0x14)
+#define DDRC_MRSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x18)
+#define DDRC_MRCTRL2(X) (DDRC_IPS_BASE_ADDR(X) + 0x1c)
+#define DDRC_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x20)
+#define DDRC_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x24)
+#define DDRC_MSTR2(X) (DDRC_IPS_BASE_ADDR(X) + 0x28)
+#define DDRC_PWRCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x30)
+#define DDRC_PWRTMG(X) (DDRC_IPS_BASE_ADDR(X) + 0x34)
+#define DDRC_HWLPCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x38)
+#define DDRC_HWFFCCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x3c)
+#define DDRC_HWFFCSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x40)
+#define DDRC_RFSHCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x50)
+#define DDRC_RFSHCTL1(X) (DDRC_IPS_BASE_ADDR(X) + 0x54)
+#define DDRC_RFSHCTL2(X) (DDRC_IPS_BASE_ADDR(X) + 0x58)
+#define DDRC_RFSHCTL3(X) (DDRC_IPS_BASE_ADDR(X) + 0x60)
+#define DDRC_RFSHTMG(X) (DDRC_IPS_BASE_ADDR(X) + 0x64)
+#define DDRC_ECCCFG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x70)
+#define DDRC_ECCCFG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x74)
+#define DDRC_ECCSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x78)
+#define DDRC_ECCCLR(X) (DDRC_IPS_BASE_ADDR(X) + 0x7c)
+#define DDRC_ECCERRCNT(X) (DDRC_IPS_BASE_ADDR(X) + 0x80)
+#define DDRC_ECCCADDR0(X) (DDRC_IPS_BASE_ADDR(X) + 0x84)
+#define DDRC_ECCCADDR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x88)
+#define DDRC_ECCCSYN0(X) (DDRC_IPS_BASE_ADDR(X) + 0x8c)
+#define DDRC_ECCCSYN1(X) (DDRC_IPS_BASE_ADDR(X) + 0x90)
+#define DDRC_ECCCSYN2(X) (DDRC_IPS_BASE_ADDR(X) + 0x94)
+#define DDRC_ECCBITMASK0(X) (DDRC_IPS_BASE_ADDR(X) + 0x98)
+#define DDRC_ECCBITMASK1(X) (DDRC_IPS_BASE_ADDR(X) + 0x9c)
+#define DDRC_ECCBITMASK2(X) (DDRC_IPS_BASE_ADDR(X) + 0xa0)
+#define DDRC_ECCUADDR0(X) (DDRC_IPS_BASE_ADDR(X) + 0xa4)
+#define DDRC_ECCUADDR1(X) (DDRC_IPS_BASE_ADDR(X) + 0xa8)
+#define DDRC_ECCUSYN0(X) (DDRC_IPS_BASE_ADDR(X) + 0xac)
+#define DDRC_ECCUSYN1(X) (DDRC_IPS_BASE_ADDR(X) + 0xb0)
+#define DDRC_ECCUSYN2(X) (DDRC_IPS_BASE_ADDR(X) + 0xb4)
+#define DDRC_ECCPOISONADDR0(X) (DDRC_IPS_BASE_ADDR(X) + 0xb8)
+#define DDRC_ECCPOISONADDR1(X) (DDRC_IPS_BASE_ADDR(X) + 0xbc)
+#define DDRC_CRCPARCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0xc0)
+#define DDRC_CRCPARCTL1(X) (DDRC_IPS_BASE_ADDR(X) + 0xc4)
+#define DDRC_CRCPARCTL2(X) (DDRC_IPS_BASE_ADDR(X) + 0xc8)
+#define DDRC_CRCPARSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0xcc)
+#define DDRC_INIT0(X) (DDRC_IPS_BASE_ADDR(X) + 0xd0)
+#define DDRC_INIT1(X) (DDRC_IPS_BASE_ADDR(X) + 0xd4)
+#define DDRC_INIT2(X) (DDRC_IPS_BASE_ADDR(X) + 0xd8)
+#define DDRC_INIT3(X) (DDRC_IPS_BASE_ADDR(X) + 0xdc)
+#define DDRC_INIT4(X) (DDRC_IPS_BASE_ADDR(X) + 0xe0)
+#define DDRC_INIT5(X) (DDRC_IPS_BASE_ADDR(X) + 0xe4)
+#define DDRC_INIT6(X) (DDRC_IPS_BASE_ADDR(X) + 0xe8)
+#define DDRC_INIT7(X) (DDRC_IPS_BASE_ADDR(X) + 0xec)
+#define DDRC_DIMMCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0xf0)
+#define DDRC_RANKCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0xf4)
+#define DDRC_DRAMTMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x100)
+#define DDRC_DRAMTMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x104)
+#define DDRC_DRAMTMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x108)
+#define DDRC_DRAMTMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x10c)
+#define DDRC_DRAMTMG4(X) (DDRC_IPS_BASE_ADDR(X) + 0x110)
+#define DDRC_DRAMTMG5(X) (DDRC_IPS_BASE_ADDR(X) + 0x114)
+#define DDRC_DRAMTMG6(X) (DDRC_IPS_BASE_ADDR(X) + 0x118)
+#define DDRC_DRAMTMG7(X) (DDRC_IPS_BASE_ADDR(X) + 0x11c)
+#define DDRC_DRAMTMG8(X) (DDRC_IPS_BASE_ADDR(X) + 0x120)
+#define DDRC_DRAMTMG9(X) (DDRC_IPS_BASE_ADDR(X) + 0x124)
+#define DDRC_DRAMTMG10(X) (DDRC_IPS_BASE_ADDR(X) + 0x128)
+#define DDRC_DRAMTMG11(X) (DDRC_IPS_BASE_ADDR(X) + 0x12c)
+#define DDRC_DRAMTMG12(X) (DDRC_IPS_BASE_ADDR(X) + 0x130)
+#define DDRC_DRAMTMG13(X) (DDRC_IPS_BASE_ADDR(X) + 0x134)
+#define DDRC_DRAMTMG14(X) (DDRC_IPS_BASE_ADDR(X) + 0x138)
+#define DDRC_DRAMTMG15(X) (DDRC_IPS_BASE_ADDR(X) + 0x13C)
+#define DDRC_DRAMTMG16(X) (DDRC_IPS_BASE_ADDR(X) + 0x140)
+#define DDRC_DRAMTMG17(X) (DDRC_IPS_BASE_ADDR(X) + 0x144)
+
+#define DDRC_ZQCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x180)
+#define DDRC_ZQCTL1(X) (DDRC_IPS_BASE_ADDR(X) + 0x184)
+#define DDRC_ZQCTL2(X) (DDRC_IPS_BASE_ADDR(X) + 0x188)
+#define DDRC_ZQSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x18c)
+#define DDRC_DFITMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x190)
+#define DDRC_DFITMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x194)
+#define DDRC_DFILPCFG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x198)
+#define DDRC_DFILPCFG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x19c)
+#define DDRC_DFIUPD0(X) (DDRC_IPS_BASE_ADDR(X) + 0x1a0)
+#define DDRC_DFIUPD1(X) (DDRC_IPS_BASE_ADDR(X) + 0x1a4)
+#define DDRC_DFIUPD2(X) (DDRC_IPS_BASE_ADDR(X) + 0x1a8)
+#define DDRC_DFIMISC(X) (DDRC_IPS_BASE_ADDR(X) + 0x1b0)
+#define DDRC_DFITMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x1b4)
+#define DDRC_DFITMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x1b8)
+#define DDRC_DFISTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x1bc)
+
+#define DDRC_DBICTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x1c0)
+#define DDRC_DFIPHYMSTR(X) (DDRC_IPS_BASE_ADDR(X) + 0x1c4)
+#define DDRC_TRAINCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x1d0)
+#define DDRC_TRAINCTL1(X) (DDRC_IPS_BASE_ADDR(X) + 0x1d4)
+#define DDRC_TRAINCTL2(X) (DDRC_IPS_BASE_ADDR(X) + 0x1d8)
+#define DDRC_TRAINSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x1dc)
+#define DDRC_ADDRMAP0(X) (DDRC_IPS_BASE_ADDR(X) + 0x200)
+#define DDRC_ADDRMAP1(X) (DDRC_IPS_BASE_ADDR(X) + 0x204)
+#define DDRC_ADDRMAP2(X) (DDRC_IPS_BASE_ADDR(X) + 0x208)
+#define DDRC_ADDRMAP3(X) (DDRC_IPS_BASE_ADDR(X) + 0x20c)
+#define DDRC_ADDRMAP4(X) (DDRC_IPS_BASE_ADDR(X) + 0x210)
+#define DDRC_ADDRMAP5(X) (DDRC_IPS_BASE_ADDR(X) + 0x214)
+#define DDRC_ADDRMAP6(X) (DDRC_IPS_BASE_ADDR(X) + 0x218)
+#define DDRC_ADDRMAP7(X) (DDRC_IPS_BASE_ADDR(X) + 0x21c)
+#define DDRC_ADDRMAP8(X) (DDRC_IPS_BASE_ADDR(X) + 0x220)
+#define DDRC_ADDRMAP9(X) (DDRC_IPS_BASE_ADDR(X) + 0x224)
+#define DDRC_ADDRMAP10(X) (DDRC_IPS_BASE_ADDR(X) + 0x228)
+#define DDRC_ADDRMAP11(X) (DDRC_IPS_BASE_ADDR(X) + 0x22c)
+
+#define DDRC_ODTCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x240)
+#define DDRC_ODTMAP(X) (DDRC_IPS_BASE_ADDR(X) + 0x244)
+#define DDRC_SCHED(X) (DDRC_IPS_BASE_ADDR(X) + 0x250)
+#define DDRC_SCHED1(X) (DDRC_IPS_BASE_ADDR(X) + 0x254)
+#define DDRC_PERFHPR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x25c)
+#define DDRC_PERFLPR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x264)
+#define DDRC_PERFWR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x26c)
+#define DDRC_PERFVPR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x274)
+
+#define DDRC_PERFVPW1(X) (DDRC_IPS_BASE_ADDR(X) + 0x278)
+
+#define DDRC_DQMAP0(X) (DDRC_IPS_BASE_ADDR(X) + 0x280)
+#define DDRC_DQMAP1(X) (DDRC_IPS_BASE_ADDR(X) + 0x284)
+#define DDRC_DQMAP2(X) (DDRC_IPS_BASE_ADDR(X) + 0x288)
+#define DDRC_DQMAP3(X) (DDRC_IPS_BASE_ADDR(X) + 0x28c)
+#define DDRC_DQMAP4(X) (DDRC_IPS_BASE_ADDR(X) + 0x290)
+#define DDRC_DQMAP5(X) (DDRC_IPS_BASE_ADDR(X) + 0x294)
+#define DDRC_DBG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x300)
+#define DDRC_DBG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x304)
+#define DDRC_DBGCAM(X) (DDRC_IPS_BASE_ADDR(X) + 0x308)
+#define DDRC_DBGCMD(X) (DDRC_IPS_BASE_ADDR(X) + 0x30c)
+#define DDRC_DBGSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x310)
+
+#define DDRC_SWCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x320)
+#define DDRC_SWSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x324)
+#define DDRC_OCPARCFG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x330)
+#define DDRC_OCPARCFG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x334)
+#define DDRC_OCPARCFG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x338)
+#define DDRC_OCPARCFG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x33c)
+#define DDRC_OCPARSTAT0(X) (DDRC_IPS_BASE_ADDR(X) + 0x340)
+#define DDRC_OCPARSTAT1(X) (DDRC_IPS_BASE_ADDR(X) + 0x344)
+#define DDRC_OCPARWLOG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x348)
+#define DDRC_OCPARWLOG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x34c)
+#define DDRC_OCPARWLOG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x350)
+#define DDRC_OCPARAWLOG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x354)
+#define DDRC_OCPARAWLOG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x358)
+#define DDRC_OCPARRLOG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x35c)
+#define DDRC_OCPARRLOG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x360)
+#define DDRC_OCPARARLOG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x364)
+#define DDRC_OCPARARLOG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x368)
+#define DDRC_POISONCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x36C)
+#define DDRC_POISONSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x370)
+#define DDRC_ADVECCINDEX(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ADVECCSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ECCPOISONPAT0(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ECCPOISONPAT1(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ECCPOISONPAT2(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_HIFCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+
+#define DDRC_PSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x3fc)
+#define DDRC_PCCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x400)
+#define DDRC_PCFGR_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x404)
+#define DDRC_PCFGR_1(X) (DDRC_IPS_BASE_ADDR(X) + 1 * 0xb0 + 0x404)
+#define DDRC_PCFGR_2(X) (DDRC_IPS_BASE_ADDR(X) + 2 * 0xb0 + 0x404)
+#define DDRC_PCFGR_3(X) (DDRC_IPS_BASE_ADDR(X) + 3 * 0xb0 + 0x404)
+#define DDRC_PCFGW_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x408)
+#define DDRC_PCFGW_1(X) (DDRC_IPS_BASE_ADDR(X) + 1 * 0xb0 + 0x408)
+#define DDRC_PCFGW_2(X) (DDRC_IPS_BASE_ADDR(X) + 2 * 0xb0 + 0x408)
+#define DDRC_PCFGW_3(X) (DDRC_IPS_BASE_ADDR(X) + 3 * 0xb0 + 0x408)
+#define DDRC_PCFGC_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x40c)
+#define DDRC_PCFGIDMASKCH(X) (DDRC_IPS_BASE_ADDR(X) + 0x410)
+#define DDRC_PCFGIDVALUECH(X) (DDRC_IPS_BASE_ADDR(X) + 0x414)
+#define DDRC_PCTRL_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x490)
+#define DDRC_PCTRL_1(X) (DDRC_IPS_BASE_ADDR(X) + 0x490 + 1 * 0xb0)
+#define DDRC_PCTRL_2(X) (DDRC_IPS_BASE_ADDR(X) + 0x490 + 2 * 0xb0)
+#define DDRC_PCTRL_3(X) (DDRC_IPS_BASE_ADDR(X) + 0x490 + 3 * 0xb0)
+#define DDRC_PCFGQOS0_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x494)
+#define DDRC_PCFGQOS1_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x498)
+#define DDRC_PCFGWQOS0_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x49c)
+#define DDRC_PCFGWQOS1_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x4a0)
+#define DDRC_SARBASE0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf04)
+#define DDRC_SARSIZE0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf08)
+#define DDRC_SBRCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0xf24)
+#define DDRC_SBRSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0xf28)
+#define DDRC_SBRWDATA0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf2c)
+#define DDRC_SBRWDATA1(X) (DDRC_IPS_BASE_ADDR(X) + 0xf30)
+#define DDRC_PDCH(X) (DDRC_IPS_BASE_ADDR(X) + 0xf34)
+
+/* SHADOW registers */
+#define DDRC_FREQ1_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x2020)
+#define DDRC_FREQ1_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x2024)
+#define DDRC_FREQ1_RFSHCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x2050)
+#define DDRC_FREQ1_RFSHTMG(X) (DDRC_IPS_BASE_ADDR(X) + 0x2064)
+#define DDRC_FREQ1_INIT3(X) (DDRC_IPS_BASE_ADDR(X) + 0x20dc)
+#define DDRC_FREQ1_INIT4(X) (DDRC_IPS_BASE_ADDR(X) + 0x20e0)
+#define DDRC_FREQ1_INIT6(X) (DDRC_IPS_BASE_ADDR(X) + 0x20e8)
+#define DDRC_FREQ1_INIT7(X) (DDRC_IPS_BASE_ADDR(X) + 0x20ec)
+#define DDRC_FREQ1_DRAMTMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x2100)
+#define DDRC_FREQ1_DRAMTMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x2104)
+#define DDRC_FREQ1_DRAMTMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x2108)
+#define DDRC_FREQ1_DRAMTMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x210c)
+#define DDRC_FREQ1_DRAMTMG4(X) (DDRC_IPS_BASE_ADDR(X) + 0x2110)
+#define DDRC_FREQ1_DRAMTMG5(X) (DDRC_IPS_BASE_ADDR(X) + 0x2114)
+#define DDRC_FREQ1_DRAMTMG6(X) (DDRC_IPS_BASE_ADDR(X) + 0x2118)
+#define DDRC_FREQ1_DRAMTMG7(X) (DDRC_IPS_BASE_ADDR(X) + 0x211c)
+#define DDRC_FREQ1_DRAMTMG8(X) (DDRC_IPS_BASE_ADDR(X) + 0x2120)
+#define DDRC_FREQ1_DRAMTMG9(X) (DDRC_IPS_BASE_ADDR(X) + 0x2124)
+#define DDRC_FREQ1_DRAMTMG10(X) (DDRC_IPS_BASE_ADDR(X) + 0x2128)
+#define DDRC_FREQ1_DRAMTMG11(X) (DDRC_IPS_BASE_ADDR(X) + 0x212c)
+#define DDRC_FREQ1_DRAMTMG12(X) (DDRC_IPS_BASE_ADDR(X) + 0x2130)
+#define DDRC_FREQ1_DRAMTMG13(X) (DDRC_IPS_BASE_ADDR(X) + 0x2134)
+#define DDRC_FREQ1_DRAMTMG14(X) (DDRC_IPS_BASE_ADDR(X) + 0x2138)
+#define DDRC_FREQ1_DRAMTMG15(X) (DDRC_IPS_BASE_ADDR(X) + 0x213C)
+#define DDRC_FREQ1_DRAMTMG16(X) (DDRC_IPS_BASE_ADDR(X) + 0x2140)
+#define DDRC_FREQ1_DRAMTMG17(X) (DDRC_IPS_BASE_ADDR(X) + 0x2144)
+#define DDRC_FREQ1_ZQCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x2180)
+#define DDRC_FREQ1_DFITMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x2190)
+#define DDRC_FREQ1_DFITMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x2194)
+#define DDRC_FREQ1_DFITMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x21b4)
+#define DDRC_FREQ1_DFITMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x21b8)
+#define DDRC_FREQ1_ODTCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x2240)
+
+#define DDRC_FREQ2_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x3020)
+#define DDRC_FREQ2_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x3024)
+#define DDRC_FREQ2_RFSHCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x3050)
+#define DDRC_FREQ2_RFSHTMG(X) (DDRC_IPS_BASE_ADDR(X) + 0x3064)
+#define DDRC_FREQ2_INIT3(X) (DDRC_IPS_BASE_ADDR(X) + 0x30dc)
+#define DDRC_FREQ2_INIT4(X) (DDRC_IPS_BASE_ADDR(X) + 0x30e0)
+#define DDRC_FREQ2_INIT6(X) (DDRC_IPS_BASE_ADDR(X) + 0x30e8)
+#define DDRC_FREQ2_INIT7(X) (DDRC_IPS_BASE_ADDR(X) + 0x30ec)
+#define DDRC_FREQ2_DRAMTMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x3100)
+#define DDRC_FREQ2_DRAMTMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x3104)
+#define DDRC_FREQ2_DRAMTMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x3108)
+#define DDRC_FREQ2_DRAMTMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x310c)
+#define DDRC_FREQ2_DRAMTMG4(X) (DDRC_IPS_BASE_ADDR(X) + 0x3110)
+#define DDRC_FREQ2_DRAMTMG5(X) (DDRC_IPS_BASE_ADDR(X) + 0x3114)
+#define DDRC_FREQ2_DRAMTMG6(X) (DDRC_IPS_BASE_ADDR(X) + 0x3118)
+#define DDRC_FREQ2_DRAMTMG7(X) (DDRC_IPS_BASE_ADDR(X) + 0x311c)
+#define DDRC_FREQ2_DRAMTMG8(X) (DDRC_IPS_BASE_ADDR(X) + 0x3120)
+#define DDRC_FREQ2_DRAMTMG9(X) (DDRC_IPS_BASE_ADDR(X) + 0x3124)
+#define DDRC_FREQ2_DRAMTMG10(X) (DDRC_IPS_BASE_ADDR(X) + 0x3128)
+#define DDRC_FREQ2_DRAMTMG11(X) (DDRC_IPS_BASE_ADDR(X) + 0x312c)
+#define DDRC_FREQ2_DRAMTMG12(X) (DDRC_IPS_BASE_ADDR(X) + 0x3130)
+#define DDRC_FREQ2_DRAMTMG13(X) (DDRC_IPS_BASE_ADDR(X) + 0x3134)
+#define DDRC_FREQ2_DRAMTMG14(X) (DDRC_IPS_BASE_ADDR(X) + 0x3138)
+#define DDRC_FREQ2_DRAMTMG15(X) (DDRC_IPS_BASE_ADDR(X) + 0x313C)
+#define DDRC_FREQ2_DRAMTMG16(X) (DDRC_IPS_BASE_ADDR(X) + 0x3140)
+#define DDRC_FREQ2_DRAMTMG17(X) (DDRC_IPS_BASE_ADDR(X) + 0x3144)
+#define DDRC_FREQ2_ZQCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x3180)
+#define DDRC_FREQ2_DFITMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x3190)
+#define DDRC_FREQ2_DFITMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x3194)
+#define DDRC_FREQ2_DFITMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x31b4)
+#define DDRC_FREQ2_DFITMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x31b8)
+#define DDRC_FREQ2_ODTCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x3240)
+
+#define DDRC_FREQ3_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x4020)
+#define DDRC_FREQ3_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x4024)
+#define DDRC_FREQ3_RFSHCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x4050)
+#define DDRC_FREQ3_RFSHTMG(X) (DDRC_IPS_BASE_ADDR(X) + 0x4064)
+#define DDRC_FREQ3_INIT3(X) (DDRC_IPS_BASE_ADDR(X) + 0x40dc)
+#define DDRC_FREQ3_INIT4(X) (DDRC_IPS_BASE_ADDR(X) + 0x40e0)
+#define DDRC_FREQ3_INIT6(X) (DDRC_IPS_BASE_ADDR(X) + 0x40e8)
+#define DDRC_FREQ3_INIT7(X) (DDRC_IPS_BASE_ADDR(X) + 0x40ec)
+#define DDRC_FREQ3_DRAMTMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x4100)
+#define DDRC_FREQ3_DRAMTMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x4104)
+#define DDRC_FREQ3_DRAMTMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x4108)
+#define DDRC_FREQ3_DRAMTMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x410c)
+#define DDRC_FREQ3_DRAMTMG4(X) (DDRC_IPS_BASE_ADDR(X) + 0x4110)
+#define DDRC_FREQ3_DRAMTMG5(X) (DDRC_IPS_BASE_ADDR(X) + 0x4114)
+#define DDRC_FREQ3_DRAMTMG6(X) (DDRC_IPS_BASE_ADDR(X) + 0x4118)
+#define DDRC_FREQ3_DRAMTMG7(X) (DDRC_IPS_BASE_ADDR(X) + 0x411c)
+#define DDRC_FREQ3_DRAMTMG8(X) (DDRC_IPS_BASE_ADDR(X) + 0x4120)
+#define DDRC_FREQ3_DRAMTMG9(X) (DDRC_IPS_BASE_ADDR(X) + 0x4124)
+#define DDRC_FREQ3_DRAMTMG10(X) (DDRC_IPS_BASE_ADDR(X) + 0x4128)
+#define DDRC_FREQ3_DRAMTMG11(X) (DDRC_IPS_BASE_ADDR(X) + 0x412c)
+#define DDRC_FREQ3_DRAMTMG12(X) (DDRC_IPS_BASE_ADDR(X) + 0x4130)
+#define DDRC_FREQ3_DRAMTMG13(X) (DDRC_IPS_BASE_ADDR(X) + 0x4134)
+#define DDRC_FREQ3_DRAMTMG14(X) (DDRC_IPS_BASE_ADDR(X) + 0x4138)
+#define DDRC_FREQ3_DRAMTMG15(X) (DDRC_IPS_BASE_ADDR(X) + 0x413C)
+#define DDRC_FREQ3_DRAMTMG16(X) (DDRC_IPS_BASE_ADDR(X) + 0x4140)
+
+#define DDRC_FREQ3_ZQCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x4180)
+#define DDRC_FREQ3_DFITMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x4190)
+#define DDRC_FREQ3_DFITMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x4194)
+#define DDRC_FREQ3_DFITMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x41b4)
+#define DDRC_FREQ3_DFITMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x41b8)
+#define DDRC_FREQ3_ODTCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x4240)
+#define DDRC_DFITMG0_SHADOW(X) (DDRC_IPS_BASE_ADDR(X) + 0x2190)
+#define DDRC_DFITMG1_SHADOW(X) (DDRC_IPS_BASE_ADDR(X) + 0x2194)
+#define DDRC_DFITMG2_SHADOW(X) (DDRC_IPS_BASE_ADDR(X) + 0x21b4)
+#define DDRC_DFITMG3_SHADOW(X) (DDRC_IPS_BASE_ADDR(X) + 0x21b8)
+#define DDRC_ODTCFG_SHADOW(X) (DDRC_IPS_BASE_ADDR(X) + 0x2240)
+
+#define DRC_PERF_MON_BASE_ADDR(X) (0x3d800000 + ((X) * 0x2000000))
+#define DRC_PERF_MON_CNT0_CTL(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x0)
+#define DRC_PERF_MON_CNT1_CTL(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x4)
+#define DRC_PERF_MON_CNT2_CTL(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x8)
+#define DRC_PERF_MON_CNT3_CTL(X) (DRC_PERF_MON_BASE_ADDR(X) + 0xC)
+#define DRC_PERF_MON_CNT0_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x20)
+#define DRC_PERF_MON_CNT1_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x24)
+#define DRC_PERF_MON_CNT2_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x28)
+#define DRC_PERF_MON_CNT3_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x2C)
+#define DRC_PERF_MON_DPCR_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x30)
+#define DRC_PERF_MON_MRR0_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x40)
+#define DRC_PERF_MON_MRR1_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x44)
+#define DRC_PERF_MON_MRR2_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x48)
+#define DRC_PERF_MON_MRR3_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x4C)
+#define DRC_PERF_MON_MRR4_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x50)
+#define DRC_PERF_MON_MRR5_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x54)
+#define DRC_PERF_MON_MRR6_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x58)
+#define DRC_PERF_MON_MRR7_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x5C)
+#define DRC_PERF_MON_MRR8_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x60)
+#define DRC_PERF_MON_MRR9_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x64)
+#define DRC_PERF_MON_MRR10_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x68)
+#define DRC_PERF_MON_MRR11_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x6C)
+#define DRC_PERF_MON_MRR12_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x70)
+#define DRC_PERF_MON_MRR13_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x74)
+#define DRC_PERF_MON_MRR14_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x78)
+#define DRC_PERF_MON_MRR15_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x7C)
+
+#define dwc_ddrphy_apb_rd(addr) mmio_read_32(IMX_DDRPHY_BASE + 4 * (addr))
+#define dwc_ddrphy_apb_wr(addr, val) mmio_write_32(IMX_DDRPHY_BASE + 4 * (addr), val)
+
+#endif /*IMX_DDRC_H */
diff --git a/plat/imx/imx8m/include/dram.h b/plat/imx/imx8m/include/dram.h
new file mode 100644
index 0000000..ad11a27
--- /dev/null
+++ b/plat/imx/imx8m/include/dram.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRAM_H
+#define DRAM_H
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <lib/utils_def.h>
+
+#include <ddrc.h>
+#include <platform_def.h>
+
+#define DDRC_LPDDR4 BIT(5)
+#define DDRC_DDR4 BIT(4)
+#define DDRC_DDR3L BIT(0)
+#define DDR_TYPE_MASK U(0x3f)
+#define ACTIVE_RANK_MASK U(0x3)
+
+/* reg & config param */
+struct dram_cfg_param {
+ unsigned int reg;
+ unsigned int val;
+};
+
+struct dram_timing_info {
+ /* umctl2 config */
+ struct dram_cfg_param *ddrc_cfg;
+ unsigned int ddrc_cfg_num;
+ /* ddrphy config */
+ struct dram_cfg_param *ddrphy_cfg;
+ unsigned int ddrphy_cfg_num;
+ /* ddr fsp train info */
+ struct dram_fsp_msg *fsp_msg;
+ unsigned int fsp_msg_num;
+ /* ddr phy trained CSR */
+ struct dram_cfg_param *ddrphy_trained_csr;
+ unsigned int ddrphy_trained_csr_num;
+ /* ddr phy PIE */
+ struct dram_cfg_param *ddrphy_pie;
+ unsigned int ddrphy_pie_num;
+ /* initialized fsp table */
+ unsigned int fsp_table[4];
+};
+
+struct dram_info {
+ int dram_type;
+ unsigned int num_rank;
+ uint32_t num_fsp;
+ int current_fsp;
+ int boot_fsp;
+ bool bypass_mode;
+ struct dram_timing_info *timing_info;
+ /* mr, emr, emr2, emr3, mr11, mr12, mr22, mr14 */
+ uint32_t mr_table[3][8];
+};
+
+extern struct dram_info dram_info;
+
+void dram_info_init(unsigned long dram_timing_base);
+void dram_umctl2_init(struct dram_timing_info *timing);
+void dram_phy_init(struct dram_timing_info *timing);
+
+/* dram retention */
+void dram_enter_retention(void);
+void dram_exit_retention(void);
+
+void dram_clock_switch(unsigned int target_drate, bool bypass_mode);
+
+/* dram frequency change */
+void lpddr4_swffc(struct dram_info *info, unsigned int init_fsp, unsigned int fsp_index);
+void ddr4_swffc(struct dram_info *dram_info, unsigned int pstate);
+
+#endif /* DRAM_H */
diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h
index 29b8ecf..a41030e 100644
--- a/plat/imx/imx8m/include/gpc.h
+++ b/plat/imx/imx8m/include/gpc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -69,5 +69,7 @@
void imx_set_sys_lpm(unsigned last_core, bool retention);
void imx_set_rbc_count(void);
void imx_clear_rbc_count(void);
+void imx_anamix_override(bool enter);
+void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on);
#endif /*IMX8M_GPC_H */
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 127e318..a903a16 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -65,6 +65,10 @@
# STM32 image header version v1.0
STM32_HEADER_VERSION_MAJOR:= 1
STM32_HEADER_VERSION_MINOR:= 0
+
+# Add OP-TEE reserved shared memory area in mapping
+STM32MP15_OPTEE_RSV_SHM := 1
+$(eval $(call add_defines,STM32MP15_OPTEE_RSV_SHM))
endif
# STM32 image header binary type for BL2
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 7e0745a..8ca6123 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -182,7 +182,12 @@
#endif
#endif
+#if STM32MP13
+#define STM32MP_BL33_BASE STM32MP_DDR_BASE
+#endif
+#if STM32MP15
#define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x100000))
+#endif
#define STM32MP_BL33_MAX_SIZE U(0x400000)
/* Define maximum page size for NAND devices */
@@ -247,8 +252,14 @@
/*******************************************************************************
* STM32MP1 UART
******************************************************************************/
+#if STM32MP13
+#define USART1_BASE U(0x4C000000)
+#define USART2_BASE U(0x4C001000)
+#endif
+#if STM32MP15
#define USART1_BASE U(0x5C000000)
#define USART2_BASE U(0x4000E000)
+#endif
#define USART3_BASE U(0x4000F000)
#define UART4_BASE U(0x40010000)
#define UART5_BASE U(0x40011000)
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
index 2076175..82e53db 100644
--- a/plat/st/stm32mp1/stm32mp1_fip_def.h
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -7,8 +7,13 @@
#ifndef STM32MP1_FIP_DEF_H
#define STM32MP1_FIP_DEF_H
+#if STM32MP15_OPTEE_RSV_SHM
#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */
#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */
+#else
+#define STM32MP_DDR_S_SIZE U(0x02000000) /* 32 MB */
+#define STM32MP_DDR_SHMEM_SIZE U(0) /* empty */
+#endif
#if STM32MP13
#define STM32MP_BL2_RO_SIZE U(0x00015000) /* 84 KB */
diff --git a/plat/st/stm32mp1/stm32mp1_stm32image_def.h b/plat/st/stm32mp1/stm32mp1_stm32image_def.h
index 8efa342..6260cb9 100644
--- a/plat/st/stm32mp1/stm32mp1_stm32image_def.h
+++ b/plat/st/stm32mp1/stm32mp1_stm32image_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2021-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,9 +8,14 @@
#define STM32MP1_STM32IMAGE_DEF_H
#ifdef AARCH32_SP_OPTEE
+#if STM32MP15_OPTEE_RSV_SHM
#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */
#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */
#else
+#define STM32MP_DDR_S_SIZE U(0x02000000) /* 32 MB */
+#define STM32MP_DDR_SHMEM_SIZE U(0) /* empty */
+#endif
+#else
#define STM32MP_DDR_S_SIZE U(0)
#define STM32MP_DDR_SHMEM_SIZE U(0)
#endif
diff --git a/plat/xilinx/common/include/pm_client.h b/plat/xilinx/common/include/pm_client.h
index e91bb8f..dc012b7 100644
--- a/plat/xilinx/common/include/pm_client.h
+++ b/plat/xilinx/common/include/pm_client.h
@@ -16,7 +16,7 @@
#include "pm_defs.h"
/* Functions to be implemented by each PU */
-void pm_client_suspend(const struct pm_proc *proc, unsigned int state);
+void pm_client_suspend(const struct pm_proc *proc, uint32_t state);
void pm_client_abort_suspend(void);
void pm_client_wakeup(const struct pm_proc *proc);
@@ -24,7 +24,6 @@
extern const struct pm_proc *primary_proc;
#ifndef VERSAL_PLATFORM
-enum pm_ret_status set_ocm_retention(void);
enum pm_ret_status pm_set_suspend_mode(uint32_t mode);
const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
#endif
diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h
index 0c24a36..06efa4b 100644
--- a/plat/xilinx/common/include/pm_common.h
+++ b/plat/xilinx/common/include/pm_common.h
@@ -48,10 +48,10 @@
*/
struct pm_proc {
const uint32_t node_id;
- const unsigned int pwrdn_mask;
+ const uint32_t pwrdn_mask;
const struct pm_ipi *ipi;
};
-const struct pm_proc *pm_get_proc(unsigned int cpuid);
+const struct pm_proc *pm_get_proc(uint32_t cpuid);
#endif /* PM_COMMON_H */
diff --git a/plat/xilinx/common/include/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h
index 8c7738d..2d20b9f 100644
--- a/plat/xilinx/common/include/pm_ipi.h
+++ b/plat/xilinx/common/include/pm_ipi.h
@@ -13,7 +13,7 @@
#define IPI_BLOCKING 1
#define IPI_NON_BLOCKING 0
-int pm_ipi_init(const struct pm_proc *proc);
+int32_t pm_ipi_init(const struct pm_proc *proc);
enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
uint32_t payload[PAYLOAD_ARG_CNT]);
@@ -21,8 +21,8 @@
uint32_t payload[PAYLOAD_ARG_CNT]);
enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
uint32_t payload[PAYLOAD_ARG_CNT],
- unsigned int *value, size_t count);
-void pm_ipi_buff_read_callb(unsigned int *value, size_t count);
+ uint32_t *value, size_t count);
+void pm_ipi_buff_read_callb(uint32_t *value, size_t count);
void pm_ipi_irq_enable(const struct pm_proc *proc);
void pm_ipi_irq_clear(const struct pm_proc *proc);
uint32_t pm_ipi_irq_status(const struct pm_proc *proc);
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index a46ac80..cb6aaa5 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -67,10 +67,10 @@
uint64_t x3, uint64_t x4, const void *cookie,
void *handle, uint64_t flags)
{
- int ret;
+ int32_t ret;
uint32_t ipi_local_id;
uint32_t ipi_remote_id;
- unsigned int is_secure;
+ uint32_t is_secure;
ipi_local_id = x1 & UNSIGNED32_MASK;
ipi_remote_id = x2 & UNSIGNED32_MASK;
@@ -94,7 +94,7 @@
SMC_RET1(handle, 0);
case IPI_MAILBOX_STATUS_ENQUIRY:
{
- int disable_irq;
+ int32_t disable_irq;
disable_irq = (x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) ? 1 : 0;
ret = ipi_mb_enquire_status(ipi_local_id, ipi_remote_id);
@@ -112,7 +112,7 @@
}
case IPI_MAILBOX_ACK:
{
- int enable_irq;
+ int32_t enable_irq;
enable_irq = (x3 & IPI_SMC_ACK_EIRQ_MASK) ? 1 : 0;
ipi_mb_ack(ipi_local_id, ipi_remote_id);
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index b8f88c4..a0900c4 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -24,36 +24,36 @@
* CPU# 5:6 00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3
*/
-#define FSBL_FLAGS_ESTATE_SHIFT 0
-#define FSBL_FLAGS_ESTATE_MASK (1 << FSBL_FLAGS_ESTATE_SHIFT)
-#define FSBL_FLAGS_ESTATE_A64 0
-#define FSBL_FLAGS_ESTATE_A32 1
+#define FSBL_FLAGS_ESTATE_SHIFT 0U
+#define FSBL_FLAGS_ESTATE_MASK (1U << FSBL_FLAGS_ESTATE_SHIFT)
+#define FSBL_FLAGS_ESTATE_A64 0U
+#define FSBL_FLAGS_ESTATE_A32 1U
-#define FSBL_FLAGS_ENDIAN_SHIFT 1
-#define FSBL_FLAGS_ENDIAN_MASK (1 << FSBL_FLAGS_ENDIAN_SHIFT)
-#define FSBL_FLAGS_ENDIAN_LE 0
-#define FSBL_FLAGS_ENDIAN_BE 1
+#define FSBL_FLAGS_ENDIAN_SHIFT 1U
+#define FSBL_FLAGS_ENDIAN_MASK (1U << FSBL_FLAGS_ENDIAN_SHIFT)
+#define FSBL_FLAGS_ENDIAN_LE 0U
+#define FSBL_FLAGS_ENDIAN_BE 1U
-#define FSBL_FLAGS_TZ_SHIFT 2
-#define FSBL_FLAGS_TZ_MASK (1 << FSBL_FLAGS_TZ_SHIFT)
-#define FSBL_FLAGS_NON_SECURE 0
-#define FSBL_FLAGS_SECURE 1
+#define FSBL_FLAGS_TZ_SHIFT 2U
+#define FSBL_FLAGS_TZ_MASK (1U << FSBL_FLAGS_TZ_SHIFT)
+#define FSBL_FLAGS_NON_SECURE 0U
+#define FSBL_FLAGS_SECURE 1U
-#define FSBL_FLAGS_EL_SHIFT 3
-#define FSBL_FLAGS_EL_MASK (3 << FSBL_FLAGS_EL_SHIFT)
-#define FSBL_FLAGS_EL0 0
-#define FSBL_FLAGS_EL1 1
-#define FSBL_FLAGS_EL2 2
-#define FSBL_FLAGS_EL3 3
+#define FSBL_FLAGS_EL_SHIFT 3U
+#define FSBL_FLAGS_EL_MASK (3U << FSBL_FLAGS_EL_SHIFT)
+#define FSBL_FLAGS_EL0 0U
+#define FSBL_FLAGS_EL1 1U
+#define FSBL_FLAGS_EL2 2U
+#define FSBL_FLAGS_EL3 3U
-#define FSBL_FLAGS_CPU_SHIFT 5
-#define FSBL_FLAGS_CPU_MASK (3 << FSBL_FLAGS_CPU_SHIFT)
-#define FSBL_FLAGS_A53_0 0
-#define FSBL_FLAGS_A53_1 1
-#define FSBL_FLAGS_A53_2 2
-#define FSBL_FLAGS_A53_3 3
+#define FSBL_FLAGS_CPU_SHIFT 5U
+#define FSBL_FLAGS_CPU_MASK (3U << FSBL_FLAGS_CPU_SHIFT)
+#define FSBL_FLAGS_A53_0 0U
+#define FSBL_FLAGS_A53_1 1U
+#define FSBL_FLAGS_A53_2 2U
+#define FSBL_FLAGS_A53_3 3U
-#define FSBL_MAX_PARTITIONS 8
+#define FSBL_MAX_PARTITIONS 8U
/* Structure corresponding to each partition entry */
struct xfsbl_partition {
@@ -75,7 +75,7 @@
*
* Return: FSBL_FLAGS_A53_0, FSBL_FLAGS_A53_1, FSBL_FLAGS_A53_2 or FSBL_FLAGS_A53_3
*/
-static int get_fsbl_cpu(const struct xfsbl_partition *partition)
+static int32_t get_fsbl_cpu(const struct xfsbl_partition *partition)
{
uint64_t flags = partition->flags & FSBL_FLAGS_CPU_MASK;
@@ -89,7 +89,7 @@
*
* Return: FSBL_FLAGS_EL0, FSBL_FLAGS_EL1, FSBL_FLAGS_EL2 or FSBL_FLAGS_EL3
*/
-static int get_fsbl_el(const struct xfsbl_partition *partition)
+static int32_t get_fsbl_el(const struct xfsbl_partition *partition)
{
uint64_t flags = partition->flags & FSBL_FLAGS_EL_MASK;
@@ -103,7 +103,7 @@
*
* Return: FSBL_FLAGS_NON_SECURE or FSBL_FLAGS_SECURE
*/
-static int get_fsbl_ss(const struct xfsbl_partition *partition)
+static int32_t get_fsbl_ss(const struct xfsbl_partition *partition)
{
uint64_t flags = partition->flags & FSBL_FLAGS_TZ_MASK;
@@ -117,7 +117,7 @@
*
* Return: SPSR_E_LITTLE or SPSR_E_BIG
*/
-static int get_fsbl_endian(const struct xfsbl_partition *partition)
+static int32_t get_fsbl_endian(const struct xfsbl_partition *partition)
{
uint64_t flags = partition->flags & FSBL_FLAGS_ENDIAN_MASK;
@@ -137,7 +137,7 @@
*
* Return: FSBL_FLAGS_ESTATE_A32 or FSBL_FLAGS_ESTATE_A64
*/
-static int get_fsbl_estate(const struct xfsbl_partition *partition)
+static int32_t get_fsbl_estate(const struct xfsbl_partition *partition)
{
uint64_t flags = partition->flags & FSBL_FLAGS_ESTATE_MASK;
@@ -193,8 +193,8 @@
*/
for (size_t i = 0; i < ATFHandoffParams->num_entries; i++) {
entry_point_info_t *image;
- int target_estate, target_secure;
- int target_cpu, target_endianness, target_el;
+ int32_t target_estate, target_secure, target_cpu;
+ uint32_t target_endianness, target_el;
VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i,
ATFHandoffParams->partition[i].entry_point,
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 1d1ba85..12313f2 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -30,7 +30,7 @@
*
* Called from pm_setup initialization function
*/
-int pm_ipi_init(const struct pm_proc *proc)
+int32_t pm_ipi_init(const struct pm_proc *proc)
{
bakery_lock_init(&pm_secure_lock);
ipi_mb_open(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
@@ -131,12 +131,12 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
- unsigned int *value, size_t count)
+ uint32_t *value, size_t count)
{
size_t i;
#if IPI_CRC_CHECK
size_t j;
- unsigned int response_payload[PAYLOAD_ARG_CNT];
+ uint32_t response_payload[PAYLOAD_ARG_CNT];
#endif
uintptr_t buffer_base = proc->ipi->buffer_base +
IPI_BUFFER_TARGET_REMOTE_OFFSET +
@@ -177,7 +177,7 @@
*
* @return Returns status, either success or error+reason
*/
-void pm_ipi_buff_read_callb(unsigned int *value, size_t count)
+void pm_ipi_buff_read_callb(uint32_t *value, size_t count)
{
size_t i;
#if IPI_CRC_CHECK
@@ -224,7 +224,7 @@
*/
enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
uint32_t payload[PAYLOAD_ARG_CNT],
- unsigned int *value, size_t count)
+ uint32_t *value, size_t count)
{
enum pm_ret_status ret;
@@ -255,7 +255,7 @@
uint32_t pm_ipi_irq_status(const struct pm_proc *proc)
{
- int ret;
+ int32_t ret;
ret = ipi_mb_enquire_status(proc->ipi->local_ipi_id,
proc->ipi->remote_ipi_id);
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index dec686b..3946e9b 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -29,7 +29,7 @@
{0}
};
-static unsigned int zynqmp_get_silicon_ver(void)
+static uint32_t zynqmp_get_silicon_ver(void)
{
static unsigned int ver;
@@ -43,7 +43,7 @@
return ver;
}
-unsigned int zynqmp_get_uart_clk(void)
+uint32_t zynqmp_get_uart_clk(void)
{
unsigned int ver = zynqmp_get_silicon_ver();
@@ -56,8 +56,8 @@
#if LOG_LEVEL >= LOG_LEVEL_NOTICE
static const struct {
- unsigned int id;
- unsigned int ver;
+ uint32_t id;
+ uint32_t ver;
char *name;
bool evexists;
} zynqmp_devices[] = {
@@ -215,8 +215,8 @@
#define ZYNQMP_PL_STATUS_MASK BIT(ZYNQMP_PL_STATUS_BIT)
#define ZYNQMP_CSU_VERSION_MASK ~(ZYNQMP_PL_STATUS_MASK)
-#define SILICON_ID_XCK24 0x4714093
-#define SILICON_ID_XCK26 0x4724093
+#define SILICON_ID_XCK24 0x4714093U
+#define SILICON_ID_XCK26 0x4724093U
static char *zynqmp_get_silicon_idcode_name(void)
{
@@ -310,20 +310,20 @@
return zynqmp_get_silicon_idcode_name();
}
-static unsigned int zynqmp_get_ps_ver(void)
+static uint32_t zynqmp_get_ps_ver(void)
{
uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
ver &= ZYNQMP_PS_VER_MASK;
ver >>= ZYNQMP_PS_VER_SHIFT;
- return ver + 1;
+ return ver + 1U;
}
static void zynqmp_print_platform_name(void)
{
- unsigned int ver = zynqmp_get_silicon_ver();
- unsigned int rtl = zynqmp_get_rtl_ver();
+ uint32_t ver = zynqmp_get_silicon_ver();
+ uint32_t rtl = zynqmp_get_rtl_ver();
char *label = "Unknown";
switch (ver) {
@@ -347,7 +347,7 @@
static inline void zynqmp_print_platform_name(void) { }
#endif
-unsigned int zynqmp_get_bootmode(void)
+uint32_t zynqmp_get_bootmode(void)
{
uint32_t r;
unsigned int ret;
@@ -379,9 +379,9 @@
generic_delay_timer_init();
}
-unsigned int plat_get_syscnt_freq2(void)
+uint32_t plat_get_syscnt_freq2(void)
{
- unsigned int ver = zynqmp_get_silicon_ver();
+ uint32_t ver = zynqmp_get_silicon_ver();
if (ver == ZYNQMP_CSU_VERSION_QEMU) {
return 65000000;
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 6ded2e2..38ad32b 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -82,7 +82,7 @@
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
} else if (ZYNQMP_CONSOLE_IS(dcc)) {
/* Initialize the dcc console for debug */
- int rc = console_dcc_register();
+ int32_t rc = console_dcc_register();
if (rc == 0) {
panic();
}
diff --git a/plat/xilinx/zynqmp/include/plat_private.h b/plat/xilinx/zynqmp/include/plat_private.h
index 288cc53..534777b 100644
--- a/plat/xilinx/zynqmp/include/plat_private.h
+++ b/plat/xilinx/zynqmp/include/plat_private.h
@@ -15,11 +15,11 @@
void zynqmp_config_setup(void);
-unsigned int zynqmp_calc_core_pos(u_register_t mpidr);
+uint32_t zynqmp_calc_core_pos(u_register_t mpidr);
/* ZynqMP specific functions */
-unsigned int zynqmp_get_uart_clk(void);
-unsigned int zynqmp_get_bootmode(void);
+uint32_t zynqmp_get_uart_clk(void);
+uint32_t zynqmp_get_bootmode(void);
#if ZYNQMP_WDT_RESTART
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 19b6937..877127b 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -163,40 +163,40 @@
#define ZYNQMP_CSU_VERSION_SILICON 0
#define ZYNQMP_CSU_VERSION_QEMU 3
-#define ZYNQMP_RTL_VER_MASK 0xFF0
+#define ZYNQMP_RTL_VER_MASK 0xFF0U
#define ZYNQMP_RTL_VER_SHIFT 4
-#define ZYNQMP_PS_VER_MASK 0xF
+#define ZYNQMP_PS_VER_MASK 0xFU
#define ZYNQMP_PS_VER_SHIFT 0
#define ZYNQMP_CSU_BASEADDR U(0xFFCA0000)
-#define ZYNQMP_CSU_IDCODE_OFFSET 0x40
+#define ZYNQMP_CSU_IDCODE_OFFSET 0x40U
-#define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT 0
-#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK (0xFFF << \
+#define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT 0U
+#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK (0xFFFU << \
ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
#define ZYNQMP_CSU_IDCODE_XILINX_ID 0x093
-#define ZYNQMP_CSU_IDCODE_SVD_SHIFT 12
-#define ZYNQMP_CSU_IDCODE_SVD_MASK (0x7 << \
+#define ZYNQMP_CSU_IDCODE_SVD_SHIFT 12U
+#define ZYNQMP_CSU_IDCODE_SVD_MASK (0x7U << \
ZYNQMP_CSU_IDCODE_SVD_SHIFT)
-#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT 15
-#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK (0xF << \
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT 15U
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK (0xFU << \
ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
-#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT 19
-#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK (0x3 << \
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT 19U
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK (0x3U << \
ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
-#define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT 21
-#define ZYNQMP_CSU_IDCODE_FAMILY_MASK (0x7F << \
+#define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT 21U
+#define ZYNQMP_CSU_IDCODE_FAMILY_MASK (0x7FU << \
ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
#define ZYNQMP_CSU_IDCODE_FAMILY 0x23
-#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT 28
-#define ZYNQMP_CSU_IDCODE_REVISION_MASK (0xF << \
+#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT 28U
+#define ZYNQMP_CSU_IDCODE_REVISION_MASK (0xFU << \
ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
-#define ZYNQMP_CSU_IDCODE_REVISION 0
+#define ZYNQMP_CSU_IDCODE_REVISION 0U
-#define ZYNQMP_CSU_VERSION_OFFSET 0x44
+#define ZYNQMP_CSU_VERSION_OFFSET 0x44U
/* Efuse */
#define EFUSE_BASEADDR U(0xFFCC0000)
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index f337cf5..b7408b1 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -29,9 +29,9 @@
wfi();
}
-static int zynqmp_pwr_domain_on(u_register_t mpidr)
+static int32_t zynqmp_pwr_domain_on(u_register_t mpidr)
{
- unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
+ uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
const struct pm_proc *proc;
uint32_t buff[3];
enum pm_ret_status ret;
@@ -60,7 +60,7 @@
static void zynqmp_pwr_domain_off(const psci_power_state_t *target_state)
{
- unsigned int cpu_id = plat_my_core_pos();
+ uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -84,8 +84,8 @@
static void zynqmp_pwr_domain_suspend(const psci_power_state_t *target_state)
{
- unsigned int state;
- unsigned int cpu_id = plat_my_core_pos();
+ uint32_t state;
+ uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
@@ -117,7 +117,7 @@
static void zynqmp_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
{
- unsigned int cpu_id = plat_my_core_pos();
+ uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -171,12 +171,12 @@
}
}
-static int zynqmp_validate_power_state(unsigned int power_state,
+static int32_t zynqmp_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state)
{
VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
- int pstate = psci_get_pstate_type(power_state);
+ uint32_t pstate = psci_get_pstate_type(power_state);
assert(req_state);
diff --git a/plat/xilinx/zynqmp/plat_topology.c b/plat/xilinx/zynqmp/plat_topology.c
index aab24aa..41add9f 100644
--- a/plat/xilinx/zynqmp/plat_topology.c
+++ b/plat/xilinx/zynqmp/plat_topology.c
@@ -3,10 +3,11 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <stdint.h>
-static const unsigned char plat_power_domain_tree_desc[] = {1, 4};
+static const uint8_t plat_power_domain_tree_desc[] = {1, 4};
-const unsigned char *plat_get_power_domain_tree_desc(void)
+const uint8_t *plat_get_power_domain_tree_desc(void)
{
return plat_power_domain_tree_desc;
}
diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c
index 58a52a3..25ebac6 100644
--- a/plat/xilinx/zynqmp/plat_zynqmp.c
+++ b/plat/xilinx/zynqmp/plat_zynqmp.c
@@ -7,7 +7,7 @@
#include <plat_private.h>
#include <plat/common/platform.h>
-int plat_core_pos_by_mpidr(u_register_t mpidr)
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
{
if (mpidr & MPIDR_CLUSTER_MASK) {
return -1;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 1ea741c..c6bed7d 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -228,8 +228,8 @@
struct pm_clock {
char name[CLK_NAME_LEN];
uint8_t num_nodes;
- unsigned int control_reg;
- unsigned int status_reg;
+ uint32_t control_reg;
+ uint32_t status_reg;
int32_t (*parents)[];
struct pm_clock_node(*nodes)[];
};
@@ -2396,7 +2396,7 @@
*
* Return: Returns 1 if clock is valid else 0.
*/
-static bool pm_clock_valid(unsigned int clock_id)
+static bool pm_clock_valid(uint32_t clock_id)
{
unsigned int i;
@@ -2415,7 +2415,7 @@
*
* Return: Returns type of clock (OUTPUT/EXTERNAL).
*/
-static unsigned int pm_clock_type(unsigned int clock_id)
+static uint32_t pm_clock_type(uint32_t clock_id)
{
return (clock_id < CLK_MAX_OUTPUT_CLK) ?
CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL;
@@ -2429,7 +2429,7 @@
*
* @return Returns success.
*/
-enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks)
+enum pm_ret_status pm_api_clock_get_num_clocks(uint32_t *nclocks)
{
*nclocks = CLK_MAX;
@@ -2444,7 +2444,7 @@
* This function is used by master to get nmae of clock specified
* by given clock ID.
*/
-void pm_api_clock_get_name(unsigned int clock_id, char *name)
+void pm_api_clock_get_name(uint32_t clock_id, char *name)
{
if (clock_id == CLK_MAX) {
memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ?
@@ -2472,13 +2472,13 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
- unsigned int index,
+enum pm_ret_status pm_api_clock_get_topology(uint32_t clock_id,
+ uint32_t index,
uint32_t *topology)
{
struct pm_clock_node *clock_nodes;
uint8_t num_nodes;
- unsigned int i;
+ uint32_t i;
uint16_t typeflags;
if (!pm_clock_valid(clock_id)) {
@@ -2528,13 +2528,13 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
+enum pm_ret_status pm_api_clock_get_fixedfactor_params(uint32_t clock_id,
uint32_t *mul,
uint32_t *div)
{
struct pm_clock_node *clock_nodes;
uint8_t num_nodes;
- unsigned int type, i;
+ uint32_t type, i;
if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
@@ -2581,11 +2581,11 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
- unsigned int index,
+enum pm_ret_status pm_api_clock_get_parents(uint32_t clock_id,
+ uint32_t index,
uint32_t *parents)
{
- unsigned int i;
+ uint32_t i;
int32_t *clk_parents;
if (!pm_clock_valid(clock_id)) {
@@ -2610,7 +2610,7 @@
}
}
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < 3U; i++) {
parents[i] = clk_parents[index + i];
if (clk_parents[index + i] == CLK_NA_PARENT) {
break;
@@ -2630,7 +2630,7 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
+enum pm_ret_status pm_api_clock_get_attributes(uint32_t clock_id,
uint32_t *attr)
{
if (clock_id >= CLK_MAX) {
@@ -2857,7 +2857,7 @@
* returned state value is valid or an error if returned by PMU
*/
enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
- unsigned int *state)
+ uint32_t *state)
{
enum pm_ret_status status;
enum pm_pll_mode mode;
@@ -2894,7 +2894,7 @@
*/
enum pm_ret_status pm_clock_pll_set_parent(struct pm_pll *pll,
enum clock_id clock_id,
- unsigned int parent_index)
+ uint32_t parent_index)
{
if (!pll) {
return PM_RET_ERROR_ARGS;
@@ -2927,7 +2927,7 @@
*/
enum pm_ret_status pm_clock_pll_get_parent(struct pm_pll *pll,
enum clock_id clock_id,
- unsigned int *parent_index)
+ uint32_t *parent_index)
{
if (!pll) {
return PM_RET_ERROR_ARGS;
@@ -2962,7 +2962,7 @@
* @return Success if mode is buffered or error if an argument is invalid
*/
enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id,
- unsigned int mode)
+ uint32_t mode)
{
struct pm_pll *pll = pm_clock_get_pll(clock_id);
@@ -2984,7 +2984,7 @@
* @return Success if mode is stored or error if an argument is invalid
*/
enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
- unsigned int *mode)
+ uint32_t *mode)
{
struct pm_pll *pll = pm_clock_get_pll(clock_id);
@@ -3002,7 +3002,7 @@
*
* @return Returns success if clock_id is valid, otherwise an error
*/
-enum pm_ret_status pm_clock_id_is_valid(unsigned int clock_id)
+enum pm_ret_status pm_clock_id_is_valid(uint32_t clock_id)
{
if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
@@ -3022,7 +3022,7 @@
*
* @return True(1)=clock has the divider, false(0)=otherwise
*/
-uint8_t pm_clock_has_div(unsigned int clock_id, enum pm_clock_div_id div_id)
+uint8_t pm_clock_has_div(uint32_t clock_id, enum pm_clock_div_id div_id)
{
uint32_t i;
struct pm_clock_node *nodes;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index 5efd63f..bc15592 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -292,20 +292,20 @@
struct pm_pll;
struct pm_pll *pm_clock_get_pll(enum clock_id clock_id);
struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id);
-uint8_t pm_clock_has_div(unsigned int clock_id, enum pm_clock_div_id div_id);
+uint8_t pm_clock_has_div(uint32_t clock_id, enum pm_clock_div_id div_id);
-void pm_api_clock_get_name(unsigned int clock_id, char *name);
-enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks);
-enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
- unsigned int index,
+void pm_api_clock_get_name(uint32_t clock_id, char *name);
+enum pm_ret_status pm_api_clock_get_num_clocks(uint32_t *nclocks);
+enum pm_ret_status pm_api_clock_get_topology(uint32_t clock_id,
+ uint32_t index,
uint32_t *topology);
-enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
+enum pm_ret_status pm_api_clock_get_fixedfactor_params(uint32_t clock_id,
uint32_t *mul,
uint32_t *div);
-enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
- unsigned int index,
+enum pm_ret_status pm_api_clock_get_parents(uint32_t clock_id,
+ uint32_t index,
uint32_t *parents);
-enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
+enum pm_ret_status pm_api_clock_get_attributes(uint32_t clock_id,
uint32_t *attr);
enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id,
uint8_t div_type,
@@ -313,21 +313,21 @@
enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id,
enum pm_node_id *node_id);
-enum pm_ret_status pm_clock_id_is_valid(unsigned int clock_id);
+enum pm_ret_status pm_clock_id_is_valid(uint32_t clock_id);
enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll);
enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll);
enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
- unsigned int *state);
+ uint32_t *state);
enum pm_ret_status pm_clock_pll_set_parent(struct pm_pll *pll,
enum clock_id clock_id,
- unsigned int parent_index);
+ uint32_t parent_index);
enum pm_ret_status pm_clock_pll_get_parent(struct pm_pll *pll,
enum clock_id clock_id,
- unsigned int *parent_index);
+ uint32_t *parent_index);
enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id,
- unsigned int mode);
+ uint32_t mode);
enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
- unsigned int *mode);
+ uint32_t *mode);
#endif /* PM_API_CLOCK_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index f12143a..8a5a25a 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -29,13 +29,13 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(unsigned int *mode)
+static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(uint32_t *mode)
{
- unsigned int val;
+ uint32_t val;
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
val &= ZYNQMP_SLSPLIT_MASK;
- if (val == 0) {
+ if (val == 0U) {
*mode = PM_RPU_MODE_LOCKSTEP;
} else {
*mode = PM_RPU_MODE_SPLIT;
@@ -55,9 +55,9 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(unsigned int mode)
+static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
{
- unsigned int val;
+ uint32_t val;
if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) {
return PM_RET_ERROR_ACCESS;
@@ -92,9 +92,9 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
- unsigned int value)
+ uint32_t value)
{
- unsigned int rpu_cfg_addr, val;
+ uint32_t rpu_cfg_addr, val;
if (nid == NODE_RPU_0) {
rpu_cfg_addr = ZYNQMP_RPU0_CFG;
@@ -128,9 +128,9 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_config_tcm_comb(unsigned int value)
+static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
{
- unsigned int val;
+ uint32_t val;
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
@@ -156,8 +156,8 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(unsigned int type,
- unsigned int value)
+static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
+ uint32_t value)
{
if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX) {
@@ -179,9 +179,9 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
- unsigned int value)
+ uint32_t value)
{
- unsigned int val, mask, shift;
+ uint32_t val, mask, shift;
enum pm_ret_status ret;
if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE) {
@@ -237,9 +237,9 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
- unsigned int type)
+ uint32_t type)
{
- unsigned int mask, val;
+ uint32_t mask, val;
enum pm_ret_status ret;
if (nid == NODE_SD_0) {
@@ -288,11 +288,11 @@
*/
static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
enum tap_delay_type type,
- unsigned int value)
+ uint32_t value)
{
- unsigned int shift;
+ uint32_t shift;
enum pm_ret_status ret;
- unsigned int val, mask;
+ uint32_t val, mask;
if (nid == NODE_SD_0) {
shift = 0;
@@ -309,7 +309,7 @@
return ret;
}
- if ((val & mask) == 0) {
+ if ((val & mask) == 0U) {
ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
if (ret != PM_RET_SUCCESS) {
return ret;
@@ -325,7 +325,7 @@
goto reset_release;
}
- if (value == 0) {
+ if (value == 0U) {
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPDLYENA_MASK <<
shift), 0);
@@ -384,7 +384,7 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_set_pll_frac_mode
- (unsigned int pll, unsigned int mode)
+ (uint32_t pll, uint32_t mode)
{
return pm_clock_set_pll_mode(pll, mode);
}
@@ -400,7 +400,7 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_get_pll_frac_mode
- (unsigned int pll, unsigned int *mode)
+ (uint32_t pll, uint32_t *mode)
{
return pm_clock_get_pll_mode(pll, mode);
}
@@ -417,7 +417,7 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_set_pll_frac_data
- (unsigned int pll, unsigned int data)
+ (uint32_t pll, uint32_t data)
{
enum pm_node_id pll_nid;
enum pm_ret_status status;
@@ -442,7 +442,7 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_get_pll_frac_data
- (unsigned int pll, unsigned int *data)
+ (uint32_t pll, uint32_t *data)
{
enum pm_node_id pll_nid;
enum pm_ret_status status;
@@ -466,8 +466,8 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
- unsigned int value)
+static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
+ uint32_t value)
{
if (index >= GGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
@@ -487,8 +487,8 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
- unsigned int *value)
+static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
+ uint32_t *value)
{
if (index >= GGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
@@ -507,8 +507,8 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
- unsigned int value)
+static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
+ uint32_t value)
{
if (index >= PGGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
@@ -527,11 +527,11 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_afi(unsigned int index,
- unsigned int value)
+static enum pm_ret_status pm_ioctl_afi(uint32_t index,
+ uint32_t value)
{
- unsigned int mask;
- unsigned int regarr[] = {0xFD360000U,
+ uint32_t mask;
+ uint32_t regarr[] = {0xFD360000U,
0xFD360014U,
0xFD370000U,
0xFD370014U,
@@ -572,8 +572,8 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
- unsigned int *value)
+static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
+ uint32_t *value)
{
if (index >= PGGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
@@ -626,7 +626,7 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_set_boot_health_status(unsigned int value)
+static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value)
{
return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4,
PM_BOOT_HEALTH_STATUS_MASK, value);
@@ -645,10 +645,10 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
- unsigned int ioctl_id,
- unsigned int arg1,
- unsigned int arg2,
- unsigned int *value)
+ uint32_t ioctl_id,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t *value)
{
enum pm_ret_status ret;
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -750,7 +750,7 @@
IOCTL_AFI,
};
uint8_t i, ioctl_id;
- int ret;
+ int32_t ret;
for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
ioctl_id = supported_ids[i];
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
index 0c5f33f..3b0d6ee 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -88,9 +88,9 @@
#define PM_DLL_RESET_PULSE 2U
enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
- unsigned int ioctl_id,
- unsigned int arg1,
- unsigned int arg2,
- unsigned int *value);
+ uint32_t ioctl_id,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t *value);
enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask);
#endif /* PM_API_IOCTL_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 86cbb7e..0192f81 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -1952,7 +1952,7 @@
*
* @return Returns success.
*/
-enum pm_ret_status pm_api_pinctrl_get_num_pins(unsigned int *npins)
+enum pm_ret_status pm_api_pinctrl_get_num_pins(uint32_t *npins)
{
*npins = MAX_PIN;
@@ -1967,7 +1967,7 @@
*
* @return Returns success.
*/
-enum pm_ret_status pm_api_pinctrl_get_num_functions(unsigned int *nfuncs)
+enum pm_ret_status pm_api_pinctrl_get_num_functions(uint32_t *nfuncs)
{
*nfuncs = MAX_FUNCTION;
@@ -1984,8 +1984,8 @@
*
* @return Returns success.
*/
-enum pm_ret_status pm_api_pinctrl_get_num_func_groups(unsigned int fid,
- unsigned int *ngroups)
+enum pm_ret_status pm_api_pinctrl_get_num_func_groups(uint32_t fid,
+ uint32_t *ngroups)
{
if (fid >= MAX_FUNCTION) {
return PM_RET_ERROR_ARGS;
@@ -2004,7 +2004,7 @@
* This function is used by master to get name of function specified
* by given function ID.
*/
-void pm_api_pinctrl_get_function_name(unsigned int fid, char *name)
+void pm_api_pinctrl_get_function_name(uint32_t fid, char *name)
{
if (fid >= MAX_FUNCTION) {
memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
@@ -2031,8 +2031,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid,
- unsigned int index,
+enum pm_ret_status pm_api_pinctrl_get_function_groups(uint32_t fid,
+ uint32_t index,
uint16_t *groups)
{
uint16_t grps;
@@ -2076,11 +2076,11 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin,
- unsigned int index,
+enum pm_ret_status pm_api_pinctrl_get_pin_groups(uint32_t pin,
+ uint32_t index,
uint16_t *groups)
{
- unsigned int i;
+ uint32_t i;
uint16_t *grps;
if (pin >= MAX_PIN) {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
index 755c19a..b3159c2 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
@@ -709,15 +709,15 @@
#define PINCTRL_DRIVE_STRENGTH_8MA 2U
#define PINCTRL_DRIVE_STRENGTH_12MA 3U
-void pm_api_pinctrl_get_function_name(unsigned int fid, char *name);
-enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid,
- unsigned int index,
+void pm_api_pinctrl_get_function_name(uint32_t fid, char *name);
+enum pm_ret_status pm_api_pinctrl_get_function_groups(uint32_t fid,
+ uint32_t index,
uint16_t *groups);
-enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin,
- unsigned int index,
+enum pm_ret_status pm_api_pinctrl_get_pin_groups(uint32_t pin,
+ uint32_t index,
uint16_t *groups);
-enum pm_ret_status pm_api_pinctrl_get_num_pins(unsigned int *npins);
-enum pm_ret_status pm_api_pinctrl_get_num_functions(unsigned int *nfuncs);
-enum pm_ret_status pm_api_pinctrl_get_num_func_groups(unsigned int fid,
- unsigned int *ngroups);
+enum pm_ret_status pm_api_pinctrl_get_num_pins(uint32_t *npins);
+enum pm_ret_status pm_api_pinctrl_get_num_functions(uint32_t *nfuncs);
+enum pm_ret_status pm_api_pinctrl_get_num_func_groups(uint32_t fid,
+ uint32_t *ngroups);
#endif /* PM_API_PINCTRL_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index e524ba5..a17b6c5 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -240,14 +240,14 @@
};
/* default shutdown/reboot scope is system(2) */
-static unsigned int pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
+static uint32_t pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
/**
* pm_get_shutdown_scope() - Get the currently set shutdown scope
*
* @return Shutdown scope value
*/
-unsigned int pm_get_shutdown_scope(void)
+uint32_t pm_get_shutdown_scope(void)
{
return pm_shutdown_scope;
}
@@ -269,12 +269,12 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
- unsigned int latency,
- unsigned int state,
+ uint32_t latency,
+ uint32_t state,
uintptr_t address)
{
uint32_t payload[PAYLOAD_ARG_CNT];
- unsigned int cpuid = plat_my_core_pos();
+ uint32_t cpuid = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpuid);
/*
@@ -300,7 +300,7 @@
*/
enum pm_ret_status pm_req_suspend(enum pm_node_id target,
enum pm_request_ack ack,
- unsigned int latency, unsigned int state)
+ uint32_t latency, uint32_t state)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -330,7 +330,7 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
- unsigned int set_address,
+ uint32_t set_address,
uintptr_t address,
enum pm_request_ack ack)
{
@@ -412,7 +412,7 @@
*/
enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
enum pm_node_id wkup_node,
- unsigned int enable)
+ uint32_t enable)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -428,7 +428,7 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_system_shutdown(unsigned int type, unsigned int subtype)
+enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -454,8 +454,8 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_req_node(enum pm_node_id nid,
- unsigned int capabilities,
- unsigned int qos,
+ uint32_t capabilities,
+ uint32_t qos,
enum pm_request_ack ack)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -481,8 +481,8 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
- unsigned int capabilities,
- unsigned int qos,
+ uint32_t capabilities,
+ uint32_t qos,
enum pm_request_ack ack)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -505,7 +505,7 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_get_api_version(unsigned int *version)
+enum pm_ret_status pm_get_api_version(uint32_t *version)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -545,8 +545,8 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_mmio_write(uintptr_t address,
- unsigned int mask,
- unsigned int value)
+ uint32_t mask,
+ uint32_t value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -565,7 +565,7 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_mmio_read(uintptr_t address, unsigned int *value)
+enum pm_ret_status pm_mmio_read(uintptr_t address, uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -609,7 +609,7 @@
* the fpga status
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_fpga_get_status(unsigned int *value)
+enum pm_ret_status pm_fpga_get_status(uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -715,10 +715,10 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_ioctl(enum pm_node_id nid,
- unsigned int ioctl_id,
- unsigned int arg1,
- unsigned int arg2,
- unsigned int *value)
+ uint32_t ioctl_id,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t *value)
{
return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
}
@@ -947,7 +947,7 @@
*
* Return: Returns status, either success or error+reason.
*/
-static enum pm_ret_status pm_clock_get_max_divisor(unsigned int clock_id,
+static enum pm_ret_status pm_clock_get_max_divisor(uint32_t clock_id,
uint8_t div_type,
uint32_t *max_div)
{
@@ -975,7 +975,7 @@
* This function is used by master to get nmae of clock specified
* by given clock ID.
*/
-static void pm_clock_get_name(unsigned int clock_id, char *name)
+static void pm_clock_get_name(uint32_t clock_id, char *name)
{
pm_api_clock_get_name(clock_id, name);
}
@@ -993,8 +993,8 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_clock_get_topology(unsigned int clock_id,
- unsigned int index,
+static enum pm_ret_status pm_clock_get_topology(uint32_t clock_id,
+ uint32_t index,
uint32_t *topology)
{
return pm_api_clock_get_topology(clock_id, index, topology);
@@ -1012,7 +1012,7 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_clock_get_fixedfactor_params(unsigned int clock_id,
+static enum pm_ret_status pm_clock_get_fixedfactor_params(uint32_t clock_id,
uint32_t *mul,
uint32_t *div)
{
@@ -1036,8 +1036,8 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_clock_get_parents(unsigned int clock_id,
- unsigned int index,
+static enum pm_ret_status pm_clock_get_parents(uint32_t clock_id,
+ uint32_t index,
uint32_t *parents)
{
return pm_api_clock_get_parents(clock_id, index, parents);
@@ -1053,7 +1053,7 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
+static enum pm_ret_status pm_clock_get_attributes(uint32_t clock_id,
uint32_t *attr)
{
return pm_api_clock_get_attributes(clock_id, attr);
@@ -1067,8 +1067,8 @@
* @return Error if an argument is not valid or status as returned by the
* PM controller (PMU)
*/
-static enum pm_ret_status pm_clock_gate(unsigned int clock_id,
- unsigned char enable)
+static enum pm_ret_status pm_clock_gate(uint32_t clock_id,
+ uint8_t enable)
{
uint32_t payload[PAYLOAD_ARG_CNT];
enum pm_ret_status status;
@@ -1108,7 +1108,7 @@
* @return: Error if an argument is not valid or status as returned by the
* pm_clock_gate
*/
-enum pm_ret_status pm_clock_enable(unsigned int clock_id)
+enum pm_ret_status pm_clock_enable(uint32_t clock_id)
{
struct pm_pll *pll;
@@ -1132,7 +1132,7 @@
* @return: Error if an argument is not valid or status as returned by the
* pm_clock_gate
*/
-enum pm_ret_status pm_clock_disable(unsigned int clock_id)
+enum pm_ret_status pm_clock_disable(uint32_t clock_id)
{
struct pm_pll *pll;
@@ -1156,8 +1156,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
- unsigned int *state)
+enum pm_ret_status pm_clock_getstate(uint32_t clock_id,
+ uint32_t *state)
{
struct pm_pll *pll;
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1189,8 +1189,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
- unsigned int divider)
+enum pm_ret_status pm_clock_setdivider(uint32_t clock_id,
+ uint32_t divider)
{
enum pm_ret_status status;
enum pm_node_id nid;
@@ -1237,8 +1237,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
- unsigned int *divider)
+enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
+ uint32_t *divider)
{
enum pm_ret_status status;
enum pm_node_id nid;
@@ -1291,7 +1291,7 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
+enum pm_ret_status pm_clock_setrate(uint32_t clock_id,
uint64_t rate)
{
return PM_RET_ERROR_NOTSUPPORTED;
@@ -1307,7 +1307,7 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
+enum pm_ret_status pm_clock_getrate(uint32_t clock_id,
uint64_t *rate)
{
return PM_RET_ERROR_NOTSUPPORTED;
@@ -1322,8 +1322,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
- unsigned int parent_index)
+enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
+ uint32_t parent_index)
{
struct pm_pll *pll;
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1356,8 +1356,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
- unsigned int *parent_index)
+enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
+ uint32_t *parent_index)
{
struct pm_pll *pll;
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1417,7 +1417,7 @@
*
* Return: Returns status, either success or error+reason.
*/
-static enum pm_ret_status pm_pinctrl_get_num_function_groups(unsigned int fid,
+static enum pm_ret_status pm_pinctrl_get_num_function_groups(uint32_t fid,
uint32_t *ngroups)
{
return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
@@ -1431,7 +1431,7 @@
* This function is used by master to get name of function specified
* by given function Id
*/
-static void pm_pinctrl_get_function_name(unsigned int fid, char *name)
+static void pm_pinctrl_get_function_name(uint32_t fid, char *name)
{
pm_api_pinctrl_get_function_name(fid, name);
}
@@ -1453,8 +1453,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-static enum pm_ret_status pm_pinctrl_get_function_groups(unsigned int fid,
- unsigned int index,
+static enum pm_ret_status pm_pinctrl_get_function_groups(uint32_t fid,
+ uint32_t index,
uint16_t *groups)
{
return pm_api_pinctrl_get_function_groups(fid, index, groups);
@@ -1477,8 +1477,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-static enum pm_ret_status pm_pinctrl_get_pin_groups(unsigned int pin_id,
- unsigned int index,
+static enum pm_ret_status pm_pinctrl_get_pin_groups(uint32_t pin_id,
+ uint32_t index,
uint16_t *groups)
{
return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
@@ -1494,8 +1494,8 @@
*
* This function returns requested data.
*/
-void pm_query_data(enum pm_query_id qid, unsigned int arg1, unsigned int arg2,
- unsigned int arg3, unsigned int *data)
+void pm_query_data(enum pm_query_id qid, uint32_t arg1, uint32_t arg2,
+ uint32_t arg3, uint32_t *data)
{
switch (qid) {
case PM_QID_CLOCK_GET_NAME:
@@ -1632,7 +1632,7 @@
*/
enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
enum pm_pll_param param_id,
- unsigned int value)
+ uint32_t value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1662,7 +1662,7 @@
*/
enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
enum pm_pll_param param_id,
- unsigned int *value)
+ uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1752,11 +1752,11 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_register_access(unsigned int register_access_id,
- unsigned int address,
- unsigned int mask,
- unsigned int value,
- unsigned int *out)
+enum pm_ret_status pm_register_access(uint32_t register_access_id,
+ uint32_t address,
+ uint32_t mask,
+ uint32_t value,
+ uint32_t *out)
{
enum pm_ret_status ret;
@@ -1808,7 +1808,7 @@
return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
-enum pm_ret_status em_set_action(unsigned int *value)
+enum pm_ret_status em_set_action(uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1817,7 +1817,7 @@
return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
-enum pm_ret_status em_remove_action(unsigned int *value)
+enum pm_ret_status em_remove_action(uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1826,7 +1826,7 @@
return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
-enum pm_ret_status em_send_errors(unsigned int *value)
+enum pm_ret_status em_send_errors(uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index 84b239c..d3e9a34 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -70,12 +70,12 @@
**********************************************************/
enum pm_ret_status pm_req_suspend(enum pm_node_id target,
enum pm_request_ack ack,
- unsigned int latency,
- unsigned int state);
+ uint32_t latency,
+ uint32_t state);
enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
- unsigned int latency,
- unsigned int state,
+ uint32_t latency,
+ uint32_t state,
uintptr_t address);
enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
@@ -84,53 +84,42 @@
enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason);
enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
- unsigned int set_address,
+ uint32_t set_address,
uintptr_t address,
enum pm_request_ack ack);
enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
enum pm_node_id wkup_node,
- unsigned int enable);
+ uint32_t enable);
-enum pm_ret_status pm_system_shutdown(unsigned int type, unsigned int subtype);
-
-enum pm_ret_status pm_init_suspend_cb(enum pm_suspend_reason reason,
- unsigned int latency,
- unsigned int state,
- unsigned int timeout);
+enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype);
/* API functions for managing PM Slaves */
enum pm_ret_status pm_req_node(enum pm_node_id nid,
- unsigned int capabilities,
- unsigned int qos,
+ uint32_t capabilities,
+ uint32_t qos,
enum pm_request_ack ack);
enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
- unsigned int capabilities,
- unsigned int qos,
+ uint32_t capabilities,
+ uint32_t qos,
enum pm_request_ack ack);
/* Miscellaneous API functions */
-enum pm_ret_status pm_get_api_version(unsigned int *version);
+enum pm_ret_status pm_get_api_version(uint32_t *version);
enum pm_ret_status pm_get_node_status(enum pm_node_id nid,
uint32_t *ret_buff);
-enum pm_ret_status pm_acknowledge_cb(enum pm_node_id nid,
- enum pm_ret_status status,
- unsigned int oppoint);
-enum pm_ret_status pm_notify_cb(enum pm_node_id nid,
- unsigned int event,
- unsigned int oppoint);
/* Direct-Control API functions */
enum pm_ret_status pm_mmio_write(uintptr_t address,
- unsigned int mask,
- unsigned int value);
-enum pm_ret_status pm_mmio_read(uintptr_t address, unsigned int *value);
+ uint32_t mask,
+ uint32_t value);
+enum pm_ret_status pm_mmio_read(uintptr_t address, uint32_t *value);
enum pm_ret_status pm_fpga_load(uint32_t address_low,
uint32_t address_high,
uint32_t size,
uint32_t flags);
-enum pm_ret_status pm_fpga_get_status(unsigned int *value);
+enum pm_ret_status pm_fpga_get_status(uint32_t *value);
enum pm_ret_status pm_get_chipid(uint32_t *value);
enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
@@ -140,28 +129,28 @@
unsigned int pm_get_shutdown_scope(void);
void pm_get_callbackdata(uint32_t *data, size_t count);
enum pm_ret_status pm_ioctl(enum pm_node_id nid,
- unsigned int ioctl_id,
- unsigned int arg1,
- unsigned int arg2,
- unsigned int *value);
-enum pm_ret_status pm_clock_enable(unsigned int clock_id);
-enum pm_ret_status pm_clock_disable(unsigned int clock_id);
-enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
- unsigned int *state);
-enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
- unsigned int divider);
-enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
- unsigned int *divider);
-enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
+ uint32_t ioctl_id,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t *value);
+enum pm_ret_status pm_clock_enable(uint32_t clock_id);
+enum pm_ret_status pm_clock_disable(uint32_t clock_id);
+enum pm_ret_status pm_clock_getstate(uint32_t clock_id,
+ uint32_t *state);
+enum pm_ret_status pm_clock_setdivider(uint32_t clock_id,
+ uint32_t divider);
+enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
+ uint32_t *divider);
+enum pm_ret_status pm_clock_setrate(uint32_t clock_id,
uint64_t rate);
-enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
+enum pm_ret_status pm_clock_getrate(uint32_t clock_id,
uint64_t *rate);
-enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
- unsigned int parent_index);
-enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
- unsigned int *parent_index);
-void pm_query_data(enum pm_query_id qid, unsigned int arg1, unsigned int arg2,
- unsigned int arg3, unsigned int *data);
+enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
+ uint32_t parent_index);
+enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
+ uint32_t *parent_index);
+void pm_query_data(enum pm_query_id qid, uint32_t arg1, uint32_t arg2,
+ uint32_t arg3, uint32_t *data);
enum pm_ret_status pm_sha_hash(uint32_t address_high,
uint32_t address_low,
uint32_t size,
@@ -183,28 +172,24 @@
enum pm_ret_status pm_aes_engine(uint32_t address_high,
uint32_t address_low,
uint32_t *value);
-enum pm_ret_status pm_register_access(unsigned int register_access_id,
- unsigned int address,
- unsigned int mask,
- unsigned int value,
- unsigned int *out);
+enum pm_ret_status pm_register_access(uint32_t register_access_id,
+ uint32_t address,
+ uint32_t mask,
+ uint32_t value,
+ uint32_t *out);
enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
enum pm_pll_param param_id,
- unsigned int value);
+ uint32_t value);
enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
enum pm_pll_param param_id,
- unsigned int *value);
+ uint32_t *value);
enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode);
enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode);
enum pm_ret_status pm_efuse_access(uint32_t address_high,
uint32_t address_low, uint32_t *value);
-enum pm_ret_status em_set_action(unsigned int *value);
-enum pm_ret_status em_remove_action(unsigned int *value);
-enum pm_ret_status em_send_errors(unsigned int *value);
-enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
- unsigned int config_id,
- unsigned int value,
- unsigned int *response);
+enum pm_ret_status em_set_action(uint32_t *value);
+enum pm_ret_status em_remove_action(uint32_t *value);
+enum pm_ret_status em_send_errors(uint32_t *value);
enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
uint32_t *bit_mask, uint8_t len);
enum pm_ret_status check_api_dependency(uint8_t id);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 3cd48a7..34b931e 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -163,7 +163,7 @@
*
* Return: PM node ID corresponding to the specified interrupt
*/
-static enum pm_node_id irq_to_pm_node(unsigned int irq)
+static enum pm_node_id irq_to_pm_node(uint32_t irq)
{
assert(irq <= IRQ_MAX);
return irq_node_map[irq];
@@ -233,7 +233,7 @@
*
* Return: pointer to a proc structure if proc is found, otherwise NULL
*/
-const struct pm_proc *pm_get_proc(unsigned int cpuid)
+const struct pm_proc *pm_get_proc(uint32_t cpuid)
{
if (cpuid < ARRAY_SIZE(pm_procs_all)) {
return &pm_procs_all[cpuid];
@@ -264,7 +264,7 @@
*
* Return: the cpu ID (starting from 0) for the subsystem
*/
-static unsigned int pm_get_cpuid(enum pm_node_id nid)
+static uint32_t pm_get_cpuid(enum pm_node_id nid)
{
for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
if (pm_procs_all[i].node_id == nid) {
@@ -283,7 +283,7 @@
* required prior to sending suspend request to PMU
* Actions taken depend on the state system is suspending to.
*/
-void pm_client_suspend(const struct pm_proc *proc, unsigned int state)
+void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
{
bakery_lock_get(&pm_client_secure_lock);
@@ -326,7 +326,7 @@
*/
void pm_client_wakeup(const struct pm_proc *proc)
{
- unsigned int cpuid = pm_get_cpuid(proc->node_id);
+ uint32_t cpuid = pm_get_cpuid(proc->node_id);
if (cpuid == UNDEFINED_CPUID) {
return;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index 8eb197a..d48df55 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -17,10 +17,10 @@
* Version number is a 32bit value, like:
* (PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR
*/
-#define PM_VERSION_MAJOR 1
-#define PM_VERSION_MINOR 1
+#define PM_VERSION_MAJOR 1U
+#define PM_VERSION_MINOR 1U
-#define PM_VERSION ((PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR)
+#define PM_VERSION ((PM_VERSION_MAJOR << 16U) | PM_VERSION_MINOR)
/**
* PM API versions
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 493ff85..a136ebc 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -203,9 +203,9 @@
* Called from sip_svc_setup initialization function with the
* rt_svc_init signature.
*/
-int pm_setup(void)
+int32_t pm_setup(void)
{
- int status, ret;
+ int32_t status, ret;
status = pm_ipi_init(primary_proc);
@@ -214,7 +214,7 @@
ERROR("BL31: Platform Management API version error. Expected: "
"v%d.%d - Found: v%d.%d\n", PM_VERSION_MAJOR,
PM_VERSION_MINOR, pm_ctx.api_version >> 16,
- pm_ctx.api_version & 0xFFFF);
+ pm_ctx.api_version & 0xFFFFU);
return -EINVAL;
}
@@ -291,7 +291,7 @@
case PM_REQ_WAKEUP:
{
/* Use address flag is encoded in the 1st bit of the low-word */
- unsigned int set_addr = pm_arg[1] & 0x1;
+ uint32_t set_addr = pm_arg[1] & 0x1;
uint64_t address = (uint64_t)pm_arg[2] << 32;
address |= pm_arg[1] & (~0x1);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
index 9cff3cb..c1781f3 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
@@ -9,7 +9,7 @@
#include "pm_common.h"
-int pm_setup(void);
+int32_t pm_setup(void);
uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
uint64_t x4, const void *cookie, void *handle,
uint64_t flags);
diff --git a/services/std_svc/rmmd/rmmd_attest.c b/services/std_svc/rmmd/rmmd_attest.c
index 0432ec3..25adf50 100644
--- a/services/std_svc/rmmd/rmmd_attest.c
+++ b/services/std_svc/rmmd/rmmd_attest.c
@@ -5,6 +5,7 @@
*/
#include <stdint.h>
#include <string.h>
+
#include <common/debug.h>
#include <lib/spinlock.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
@@ -56,110 +57,96 @@
}
/*
- * TODO: Have different error codes for different errors so that the caller can
- * differentiate various error cases.
+ * Helper function to validate that the buffer base and length are
+ * within range.
*/
-int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_len, uint64_t challenge_hash_len)
+static int validate_buffer_params(uint64_t buf_pa, uint64_t buf_len)
{
- int err;
- uintptr_t va;
- uint8_t temp_buf[SHA512_DIGEST_SIZE];
+ unsigned long shared_buf_page;
+ uintptr_t shared_buf_base;
- /*
- * TODO: Currently we don't validate incoming buf_pa. This is a
- * prototype and we will need to allocate static buffer for EL3-RMM
- * communication.
- */
+ (void)plat_rmmd_get_el3_rmm_shared_mem(&shared_buf_base);
- /* We need a page of buffer to pass data */
- if (*buf_len != PAGE_SIZE) {
- ERROR("Invalid buffer length\n");
- return RMMD_ERR_INVAL;
+ shared_buf_page = shared_buf_base & ~PAGE_SIZE_MASK;
+
+ /* Validate the buffer pointer */
+ if ((buf_pa & ~PAGE_SIZE_MASK) != shared_buf_page) {
+ ERROR("Buffer PA out of range\n");
+ return E_RMM_BAD_ADDR;
}
- if ((challenge_hash_len != SHA256_DIGEST_SIZE) &&
- (challenge_hash_len != SHA384_DIGEST_SIZE) &&
- (challenge_hash_len != SHA512_DIGEST_SIZE)) {
- ERROR("Invalid hash size: %lu\n", challenge_hash_len);
- return RMMD_ERR_INVAL;
+ /* Validate the size of the shared area */
+ if (((buf_pa + buf_len - 1UL) & ~PAGE_SIZE_MASK) != shared_buf_page) {
+ ERROR("Invalid buffer length\n");
+ return E_RMM_INVAL;
}
- spin_lock(&lock);
+ return 0; /* No error */
+}
+
+int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t c_size)
+{
+ int err;
+ uint8_t temp_buf[SHA512_DIGEST_SIZE];
- /* Map the buffer that was provided by the RMM. */
- err = mmap_add_dynamic_region_alloc_va(buf_pa, &va, PAGE_SIZE,
- MT_RW_DATA | MT_REALM);
+ err = validate_buffer_params(buf_pa, *buf_size);
if (err != 0) {
- ERROR("mmap_add_dynamic_region_alloc_va failed: %d (%p).\n"
- , err, (void *)buf_pa);
- spin_unlock(&lock);
- return RMMD_ERR_NOMEM;
+ return err;
+ }
+
+ if ((c_size != SHA256_DIGEST_SIZE) &&
+ (c_size != SHA384_DIGEST_SIZE) &&
+ (c_size != SHA512_DIGEST_SIZE)) {
+ ERROR("Invalid hash size: %lu\n", c_size);
+ return E_RMM_INVAL;
}
- (void)memcpy(temp_buf, (void *)va, challenge_hash_len);
+ spin_lock(&lock);
- print_challenge((uint8_t *)temp_buf, challenge_hash_len);
+ (void)memcpy(temp_buf, (void *)buf_pa, c_size);
+
+ print_challenge((uint8_t *)temp_buf, c_size);
/* Get the platform token. */
- err = plat_get_cca_attest_token(va,
- buf_len, (uintptr_t)temp_buf, challenge_hash_len);
+ err = plat_rmmd_get_cca_attest_token((uintptr_t)buf_pa,
+ buf_size, (uintptr_t)temp_buf, c_size);
if (err != 0) {
ERROR("Failed to get platform token: %d.\n", err);
- err = RMMD_ERR_UNK;
+ err = E_RMM_UNK;
}
- /* Unmap RMM memory. */
- (void)mmap_remove_dynamic_region(va, PAGE_SIZE);
spin_unlock(&lock);
return err;
}
-int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_len,
+int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
uint64_t ecc_curve)
{
int err;
- uintptr_t va;
- /*
- * TODO: Currently we don't validate incoming buf_pa. This is a
- * prototype and we will need to allocate static buffer for EL3-RMM
- * communication.
- */
-
- /* We need a page of buffer to pass data */
- if (*buf_len != PAGE_SIZE) {
- ERROR("Invalid buffer length\n");
- return RMMD_ERR_INVAL;
+ err = validate_buffer_params(buf_pa, *buf_size);
+ if (err != 0) {
+ return err;
}
if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
ERROR("Invalid ECC curve specified\n");
- return RMMD_ERR_INVAL;
+ return E_RMM_INVAL;
}
spin_lock(&lock);
- /* Map the buffer that was provided by the RMM. */
- err = mmap_add_dynamic_region_alloc_va(buf_pa, &va, PAGE_SIZE,
- MT_RW_DATA | MT_REALM);
- if (err != 0) {
- ERROR("mmap_add_dynamic_region_alloc_va failed: %d (%p).\n"
- , err, (void *)buf_pa);
- spin_unlock(&lock);
- return RMMD_ERR_NOMEM;
- }
-
/* Get the Realm attestation key. */
- err = plat_get_cca_realm_attest_key(va, buf_len, (unsigned int)ecc_curve);
+ err = plat_rmmd_get_cca_realm_attest_key((uintptr_t)buf_pa, buf_size,
+ (unsigned int)ecc_curve);
if (err != 0) {
ERROR("Failed to get attestation key: %d.\n", err);
- err = RMMD_ERR_UNK;
+ err = E_RMM_UNK;
}
- /* Unmap RMM memory. */
- (void)mmap_remove_dynamic_region(va, PAGE_SIZE);
spin_unlock(&lock);
return err;
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 746419e..322d9f2 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -33,6 +33,11 @@
#include "rmmd_private.h"
/*******************************************************************************
+ * RMM boot failure flag
+ ******************************************************************************/
+static bool rmm_boot_failed;
+
+/*******************************************************************************
* RMM context information.
******************************************************************************/
rmmd_rmm_context_t rmm_context[PLATFORM_CORE_COUNT];
@@ -132,13 +137,10 @@
******************************************************************************/
static int32_t rmm_init(void)
{
-
- uint64_t rc;
-
+ long rc;
rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()];
INFO("RMM init start.\n");
- ctx->state = RMM_STATE_RESET;
/* Enable architecture extensions */
manage_extensions_realm(&ctx->cpu_ctx);
@@ -147,12 +149,13 @@
rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx);
rc = rmmd_rmm_sync_entry(ctx);
- if (rc != 0ULL) {
- ERROR("RMM initialisation failed 0x%" PRIx64 "\n", rc);
- panic();
+ if (rc != E_RMM_BOOT_SUCCESS) {
+ ERROR("RMM init failed: %ld\n", rc);
+ /* Mark the boot as failed for all the CPUs */
+ rmm_boot_failed = true;
+ return 0;
}
- ctx->state = RMM_STATE_IDLE;
INFO("RMM init end.\n");
return 1;
@@ -163,9 +166,13 @@
******************************************************************************/
int rmmd_setup(void)
{
+ size_t shared_buf_size __unused;
+ uintptr_t shared_buf_base;
uint32_t ep_attr;
unsigned int linear_id = plat_my_core_pos();
rmmd_rmm_context_t *rmm_ctx = &rmm_context[linear_id];
+ rmm_manifest_t *manifest;
+ int rc;
/* Make sure RME is supported. */
assert(get_armv9_2_feat_rme_support() != 0U);
@@ -192,6 +199,34 @@
MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
+ shared_buf_size =
+ plat_rmmd_get_el3_rmm_shared_mem(&shared_buf_base);
+
+ assert((shared_buf_size == SZ_4K) &&
+ ((void *)shared_buf_base != NULL));
+
+ /* Load the boot manifest at the beginning of the shared area */
+ manifest = (rmm_manifest_t *)shared_buf_base;
+ rc = plat_rmmd_load_manifest(manifest);
+ if (rc != 0) {
+ ERROR("Error loading RMM Boot Manifest (%i)\n", rc);
+ return rc;
+ }
+ flush_dcache_range((uintptr_t)shared_buf_base, shared_buf_size);
+
+ /*
+ * Prepare coldboot arguments for RMM:
+ * arg0: This CPUID (primary processor).
+ * arg1: Version for this Boot Interface.
+ * arg2: PLATFORM_CORE_COUNT.
+ * arg3: Base address for the EL3 <-> RMM shared area. The boot
+ * manifest will be stored at the beginning of this area.
+ */
+ rmm_ep_info->args.arg0 = linear_id;
+ rmm_ep_info->args.arg1 = RMM_EL3_INTERFACE_VERSION;
+ rmm_ep_info->args.arg2 = PLATFORM_CORE_COUNT;
+ rmm_ep_info->args.arg3 = shared_buf_base;
+
/* Initialise RMM context with this entry point information */
cm_setup_context(&rmm_ctx->cpu_ctx, rmm_ep_info);
@@ -244,9 +279,14 @@
uint64_t x3, uint64_t x4, void *cookie,
void *handle, uint64_t flags)
{
- rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()];
uint32_t src_sec_state;
+ /* If RMM failed to boot, treat any RMI SMC as unknown */
+ if (rmm_boot_failed) {
+ WARN("RMMD: Failed to boot up RMM. Ignoring RMI call\n");
+ SMC_RET1(handle, SMC_UNK);
+ }
+
/* Determine which security state this SMC originated from */
src_sec_state = caller_sec_state(flags);
@@ -272,11 +312,6 @@
switch (smc_fid) {
case RMMD_RMI_REQ_COMPLETE:
- if (ctx->state == RMM_STATE_RESET) {
- VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
- rmmd_rmm_sync_exit(x1);
- }
-
return rmmd_smc_forward(REALM, NON_SECURE, x1,
x2, x3, x4, 0, handle);
@@ -293,11 +328,26 @@
******************************************************************************/
static void *rmmd_cpu_on_finish_handler(const void *arg)
{
- int32_t rc;
+ long rc;
uint32_t linear_id = plat_my_core_pos();
rmmd_rmm_context_t *ctx = &rmm_context[linear_id];
- ctx->state = RMM_STATE_RESET;
+ if (rmm_boot_failed) {
+ /* RMM Boot failed on a previous CPU. Abort. */
+ ERROR("RMM Failed to initialize. Ignoring for CPU%d\n",
+ linear_id);
+ return NULL;
+ }
+
+ /*
+ * Prepare warmboot arguments for RMM:
+ * arg0: This CPUID.
+ * arg1 to arg3: Not used.
+ */
+ rmm_ep_info->args.arg0 = linear_id;
+ rmm_ep_info->args.arg1 = 0ULL;
+ rmm_ep_info->args.arg2 = 0ULL;
+ rmm_ep_info->args.arg3 = 0ULL;
/* Initialise RMM context with this entry point information */
cm_setup_context(&ctx->cpu_ctx, rmm_ep_info);
@@ -309,13 +359,13 @@
rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx);
rc = rmmd_rmm_sync_entry(ctx);
- if (rc != 0) {
- ERROR("RMM initialisation failed (%d) on CPU%d\n", rc,
- linear_id);
- panic();
+
+ if (rc != E_RMM_BOOT_SUCCESS) {
+ ERROR("RMM init failed on CPU%d: %ld\n", linear_id, rc);
+ /* Mark the boot as failed for any other booting CPU */
+ rmm_boot_failed = true;
}
- ctx->state = RMM_STATE_IDLE;
return NULL;
}
@@ -328,15 +378,15 @@
int ret;
if (error == 0) {
- return RMMD_OK;
+ return E_RMM_OK;
}
if (error == -EINVAL) {
- ret = RMMD_ERR_BAD_ADDR;
+ ret = E_RMM_BAD_ADDR;
} else {
/* This is the only other error code we expect */
assert(error == -EPERM);
- ret = RMMD_ERR_BAD_PAS;
+ ret = E_RMM_BAD_PAS;
}
ERROR("RMMD: PAS Transition failed. GPT ret = %d, PA: 0x%"PRIx64 ", FID = 0x%x\n",
@@ -354,6 +404,12 @@
uint32_t src_sec_state;
int ret;
+ /* If RMM failed to boot, treat any RMM-EL3 interface SMC as unknown */
+ if (rmm_boot_failed) {
+ WARN("RMMD: Failed to boot up RMM. Ignoring RMM-EL3 call\n");
+ SMC_RET1(handle, SMC_UNK);
+ }
+
/* Determine which security state this SMC originated from */
src_sec_state = caller_sec_state(flags);
@@ -375,6 +431,11 @@
case RMMD_ATTEST_GET_REALM_KEY:
ret = rmmd_attest_get_signing_key(x1, &x2, x3);
SMC_RET2(handle, ret, x2);
+
+ case RMM_BOOT_COMPLETE:
+ VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
+ rmmd_rmm_sync_exit(x1);
+
default:
WARN("RMMD: Unsupported RMM-EL3 call 0x%08x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
diff --git a/services/std_svc/rmmd/rmmd_private.h b/services/std_svc/rmmd/rmmd_private.h
index 73df2b8..4954a43 100644
--- a/services/std_svc/rmmd/rmmd_private.h
+++ b/services/std_svc/rmmd/rmmd_private.h
@@ -32,11 +32,6 @@
#ifndef __ASSEMBLER__
#include <stdint.h>
-typedef enum rmm_state {
- RMM_STATE_RESET = 0,
- RMM_STATE_IDLE
-} rmm_state_t;
-
/*
* Data structure used by the RMM dispatcher (RMMD) in EL3 to track context of
* the RMM at R-EL2.
@@ -44,7 +39,6 @@
typedef struct rmmd_rmm_context {
uint64_t c_rt_ctx;
cpu_context_t cpu_ctx;
- rmm_state_t state;
} rmmd_rmm_context_t;
/* Functions used to enter/exit the RMM synchronously */
@@ -52,10 +46,10 @@
__dead2 void rmmd_rmm_sync_exit(uint64_t rc);
/* Functions implementing attestation utilities for RMM */
-int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_len,
- uint64_t challenge_hash_len);
-int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_len,
- uint64_t ecc_curve);
+int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t c_size);
+int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t ecc_curve);
/* Assembly helpers */
uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);
diff --git a/services/std_svc/rmmd/trp/trp.mk b/services/std_svc/rmmd/trp/trp.mk
index a4f6e03..44bbf22 100644
--- a/services/std_svc/rmmd/trp/trp.mk
+++ b/services/std_svc/rmmd/trp/trp.mk
@@ -1,11 +1,12 @@
#
-# Copyright (c) 2021 Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022 Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
-RMM_SOURCES += services/std_svc/rmmd/trp/trp_entry.S \
- services/std_svc/rmmd/trp/trp_main.c
+RMM_SOURCES += services/std_svc/rmmd/trp/trp_entry.S \
+ services/std_svc/rmmd/trp/trp_main.c \
+ services/std_svc/rmmd/trp/trp_helpers.c
RMM_LINKERFILE := services/std_svc/rmmd/trp/linker.lds
diff --git a/services/std_svc/rmmd/trp/trp_entry.S b/services/std_svc/rmmd/trp/trp_entry.S
index 1b03c9f..47c1df1 100644
--- a/services/std_svc/rmmd/trp/trp_entry.S
+++ b/services/std_svc/rmmd/trp/trp_entry.S
@@ -6,6 +6,8 @@
#include <asm_macros.S>
#include <services/rmmd_svc.h>
+
+#include <platform_def.h>
#include "trp_private.h"
.global trp_head
@@ -31,6 +33,28 @@
* ---------------------------------------------
*/
trp_head:
+ /*
+ * Stash arguments from previous boot stage
+ */
+ mov x20, x0
+ mov x21, x1
+ mov x22, x2
+ mov x23, x3
+
+ /*
+ * Validate CPUId before allocating a stack.
+ */
+ cmp x20, #PLATFORM_CORE_COUNT
+ b.lo 1f
+
+ mov_imm x0, RMM_BOOT_COMPLETE
+ mov_imm x1, E_RMM_BOOT_CPU_ID_OUT_OF_RANGE
+ smc #0
+
+ /* EL3 should never return back here, so panic if it does */
+ b trp_panic
+
+1:
bl plat_set_my_stack
/*
@@ -45,7 +69,6 @@
adr x2, cold_boot_flag
str xzr, [x2]
-
/* ---------------------------------------------
* Zero out BSS section
* ---------------------------------------------
@@ -54,15 +77,21 @@
ldr x1, =__BSS_SIZE__
bl zeromem
+ mov x0, x20
+ mov x1, x21
+ mov x2, x22
+ mov x3, x23
bl trp_setup
-
bl trp_main
warm_boot:
- mov_imm x0, RMMD_RMI_REQ_COMPLETE
- mov x1, xzr
+ mov_imm x0, RMM_BOOT_COMPLETE
+ mov x1, xzr /* RMM_BOOT_SUCCESS */
smc #0
b trp_handler
+trp_panic:
+ no_ret plat_panic_handler
+
/*
* Flag to mark if it is a cold boot.
* 1: cold boot, 0: warmboot.
diff --git a/services/std_svc/rmmd/trp/trp_helpers.c b/services/std_svc/rmmd/trp/trp_helpers.c
new file mode 100644
index 0000000..159f3a5
--- /dev/null
+++ b/services/std_svc/rmmd/trp/trp_helpers.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <plat/common/platform.h>
+#include <services/rmmd_svc.h>
+#include "trp_private.h"
+
+/*
+ * Per cpu data structure to populate parameters for an SMC in C code and use
+ * a pointer to this structure in assembler code to populate x0-x7
+ */
+static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT];
+
+/*
+ * Set the arguments for SMC call
+ */
+trp_args_t *set_smc_args(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ uint32_t linear_id;
+ trp_args_t *pcpu_smc_args;
+
+ /*
+ * Return to Secure Monitor by raising an SMC. The results of the
+ * service are passed as an arguments to the SMC
+ */
+ linear_id = plat_my_core_pos();
+ pcpu_smc_args = &trp_smc_args[linear_id];
+ write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0);
+ write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1);
+ write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2);
+ write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3);
+ write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4);
+ write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5);
+ write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6);
+ write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7);
+
+ return pcpu_smc_args;
+}
+
+/*
+ * Abort the boot process with the reason given in err.
+ */
+__dead2 void trp_boot_abort(uint64_t err)
+{
+ (void)trp_smc(set_smc_args(RMM_BOOT_COMPLETE, err, 0, 0, 0, 0, 0, 0));
+ panic();
+}
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 2e3f076..cf6ec7b 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -7,58 +7,63 @@
#include <common/debug.h>
#include <plat/common/platform.h>
+#include <services/rmm_core_manifest.h>
#include <services/rmmd_svc.h>
#include <services/trp/platform_trp.h>
+#include <trp_helpers.h>
+#include "trp_private.h"
#include <platform_def.h>
-#include "trp_private.h"
-/*******************************************************************************
- * Per cpu data structure to populate parameters for an SMC in C code and use
- * a pointer to this structure in assembler code to populate x0-x7
- ******************************************************************************/
-static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT];
+/* Parameters received from the previous image */
+static unsigned int trp_boot_abi_version;
+static uintptr_t trp_shared_region_start;
+
+/* Parameters received from boot manifest */
+uint32_t trp_boot_manifest_version;
/*******************************************************************************
- * Set the arguments for SMC call
+ * Setup function for TRP.
******************************************************************************/
-static trp_args_t *set_smc_args(uint64_t arg0,
- uint64_t arg1,
- uint64_t arg2,
- uint64_t arg3,
- uint64_t arg4,
- uint64_t arg5,
- uint64_t arg6,
- uint64_t arg7)
+void trp_setup(uint64_t x0,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3)
{
- uint32_t linear_id;
- trp_args_t *pcpu_smc_args;
-
/*
- * Return to Secure Monitor by raising an SMC. The results of the
- * service are passed as an arguments to the SMC
+ * Validate boot parameters.
+ *
+ * According to the Boot Interface ABI v.0.1, the
+ * parameters recived from EL3 are:
+ * x0: CPUID (verified earlier so not used)
+ * x1: Boot Interface version
+ * x2: PLATFORM_CORE_COUNT
+ * x3: Pointer to the shared memory area.
*/
- linear_id = plat_my_core_pos();
- pcpu_smc_args = &trp_smc_args[linear_id];
- write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0);
- write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1);
- write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2);
- write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3);
- write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4);
- write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5);
- write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6);
- write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7);
- return pcpu_smc_args;
-}
+ (void)x0;
-/*******************************************************************************
- * Setup function for TRP.
- ******************************************************************************/
-void trp_setup(void)
-{
+ if (TRP_RMM_EL3_VERSION_GET_MAJOR(x1) != TRP_RMM_EL3_ABI_VERS_MAJOR) {
+ trp_boot_abort(E_RMM_BOOT_VERSION_MISMATCH);
+ }
+
+ if ((void *)x3 == NULL) {
+ trp_boot_abort(E_RMM_BOOT_INVALID_SHARED_BUFFER);
+ }
+
+ if (x2 > TRP_PLATFORM_CORE_COUNT) {
+ trp_boot_abort(E_RMM_BOOT_CPUS_OUT_OF_RANGE);
+ }
+
+ trp_boot_abi_version = x1;
+ trp_shared_region_start = x3;
+ flush_dcache_range((uintptr_t)&trp_boot_abi_version,
+ sizeof(trp_boot_abi_version));
+ flush_dcache_range((uintptr_t)&trp_shared_region_start,
+ sizeof(trp_shared_region_start));
+
/* Perform early platform-specific setup */
- trp_early_platform_setup();
+ trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start);
}
/* Main function for TRP */
@@ -66,9 +71,19 @@
{
NOTICE("TRP: %s\n", version_string);
NOTICE("TRP: %s\n", build_message);
+ NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
+ TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
+ NOTICE("TRP: Boot Manifest Version : v.%u.%u\n",
+ RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version),
+ RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version));
INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE);
+ INFO("TRP: Base address for the shared region : 0x%lx\n",
+ (unsigned long)trp_shared_region_start);
INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END
- RMM_BASE));
+ INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n",
+ TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version),
+ TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version));
}
/*******************************************************************************
diff --git a/services/std_svc/rmmd/trp/trp_private.h b/services/std_svc/rmmd/trp/trp_private.h
index 4c5222e..945ae1c 100644
--- a/services/std_svc/rmmd/trp/trp_private.h
+++ b/services/std_svc/rmmd/trp/trp_private.h
@@ -7,27 +7,21 @@
#ifndef TRP_PRIVATE_H
#define TRP_PRIVATE_H
-/* Definitions to help the assembler access the SMC/ERET args structure */
-#define TRP_ARGS_SIZE TRP_ARGS_END
-#define TRP_ARG0 0x0
-#define TRP_ARG1 0x8
-#define TRP_ARG2 0x10
-#define TRP_ARG3 0x18
-#define TRP_ARG4 0x20
-#define TRP_ARG5 0x28
-#define TRP_ARG6 0x30
-#define TRP_ARG7 0x38
-#define TRP_ARGS_END 0x40
+#include <services/rmmd_svc.h>
+#include <trp_helpers.h>
+
+/* Definitions for RMM-EL3 Interface ABI VERSION */
+#define TRP_RMM_EL3_ABI_VERS_MAJOR RMM_EL3_IFC_VERSION_MAJOR
+#define TRP_RMM_EL3_ABI_VERS_MINOR RMM_EL3_IFC_VERSION_MINOR
+#define TRP_RMM_EL3_ABI_VERS (((TRP_RMM_EL3_ABI_VERS_MAJOR & 0x7FFF) << 16) | \
+ (TRP_RMM_EL3_ABI_VERS_MINOR & 0xFFFF))
+
+#define TRP_PLATFORM_CORE_COUNT PLATFORM_CORE_COUNT
#ifndef __ASSEMBLER__
#include <stdint.h>
-/* Data structure to hold SMC arguments */
-typedef struct trp_args {
- uint64_t regs[TRP_ARGS_END >> 3];
-} __aligned(CACHE_WRITEBACK_GRANULE) trp_args_t;
-
#define write_trp_arg(args, offset, val) (((args)->regs[offset >> 3]) \
= val)
/* RMI SMC64 FIDs handled by the TRP */
@@ -38,8 +32,14 @@
/* Definitions for RMI VERSION */
#define RMI_ABI_VERSION_MAJOR U(0x0)
#define RMI_ABI_VERSION_MINOR U(0x0)
-#define RMI_ABI_VERSION ((RMI_ABI_VERSION_MAJOR << 16) | \
- RMI_ABI_VERSION_MINOR)
+#define RMI_ABI_VERSION (((RMI_ABI_VERSION_MAJOR & 0x7FFF) \
+ << 16) | \
+ (RMI_ABI_VERSION_MINOR & 0xFFFF))
+
+#define TRP_RMM_EL3_VERSION_GET_MAJOR(x) \
+ RMM_EL3_IFC_VERSION_GET_MAJOR((x))
+#define TRP_RMM_EL3_VERSION_GET_MINOR(x) \
+ RMM_EL3_IFC_VERSION_GET_MAJOR_MINOR((x))
/* Helper to issue SMC calls to BL31 */
uint64_t trp_smc(trp_args_t *);
@@ -48,7 +48,10 @@
void trp_main(void);
/* Setup TRP. Executed only by Primary CPU */
-void trp_setup(void);
+void trp_setup(uint64_t x0,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3);
#endif /* __ASSEMBLER__ */
#endif /* TRP_PRIVATE_H */
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index e388784..7e6c89d 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -803,6 +803,14 @@
break; /* not reached */
case FFA_MSG_SEND_DIRECT_REQ_SMC32:
+ case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+ if (!secure_origin) {
+ /* Validate source endpoint is non-secure for non-secure caller. */
+ if (ffa_is_secure_world_id(ffa_endpoint_source(x1))) {
+ return spmd_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+ }
if (secure_origin && spmd_is_spmc_message(x1)) {
ret = spmd_handle_spmc_message(x3, x4,
SMC_GET_GP(handle, CTX_GPREG_X5),
@@ -862,7 +870,6 @@
/* Fall through to forward the call to the other world */
case FFA_MSG_SEND:
- case FFA_MSG_SEND_DIRECT_REQ_SMC64:
case FFA_MSG_SEND_DIRECT_RESP_SMC64:
case FFA_MEM_DONATE_SMC32:
case FFA_MEM_DONATE_SMC64:
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index f4045d3..814d051 100644
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -145,7 +145,7 @@
sptool_args += f" --img-offset {image_offset}" if image_offset is not None else ""
sptool_args += f" -o {sp_pkg}"
sppkg_rule = f'''
-{sp_pkg}:
+{sp_pkg}: {sp_dtb}
\t$(Q)echo Generating {sp_pkg}
\t$(Q)$(PYTHON) $(SPTOOL) {sptool_args}
'''