Merge "fix(spmd): fix build failure due to redefinition" into integration
diff --git a/Makefile b/Makefile
index 8e99259..51c7b2e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -23,7 +23,6 @@
MAKE_HELPERS_DIRECTORY := make_helpers/
include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
include ${MAKE_HELPERS_DIRECTORY}build-rules.mk
include ${MAKE_HELPERS_DIRECTORY}common.mk
@@ -99,15 +98,15 @@
# Variables for use with Certificate Generation Tool
CRTTOOLPATH ?= tools/cert_create
-CRTTOOL ?= ${CRTTOOLPATH}/cert_create${BIN_EXT}
+CRTTOOL ?= ${CRTTOOLPATH}/cert_create$(.exe)
# Variables for use with Firmware Encryption Tool
ENCTOOLPATH ?= tools/encrypt_fw
-ENCTOOL ?= ${ENCTOOLPATH}/encrypt_fw${BIN_EXT}
+ENCTOOL ?= ${ENCTOOLPATH}/encrypt_fw$(.exe)
# Variables for use with Firmware Image Package
FIPTOOLPATH ?= tools/fiptool
-FIPTOOL ?= ${FIPTOOLPATH}/fiptool${BIN_EXT}
+FIPTOOL ?= ${FIPTOOLPATH}/fiptool$(.exe)
# Variables for use with sptool
SPTOOLPATH ?= tools/sptool
@@ -283,7 +282,7 @@
-ffreestanding -Wa,--fatal-warnings
TF_CFLAGS += $(CPPFLAGS) $(TF_CFLAGS_$(ARCH)) \
-ffunction-sections -fdata-sections \
- -ffreestanding -fno-builtin -fno-common \
+ -ffreestanding -fno-common \
-Os -std=gnu99
ifeq (${SANITIZE_UB},on)
@@ -514,6 +513,12 @@
endif
################################################################################
+# Include the platform specific Makefile after the SPD Makefile (the platform
+# makefile may use all previous definitions in this file)
+################################################################################
+include ${PLAT_MAKEFILE_FULL}
+
+################################################################################
# Process BRANCH_PROTECTION value and set
# Pointer Authentication and Branch Target Identification flags
################################################################################
@@ -558,12 +563,6 @@
endif
################################################################################
-# Include the platform specific Makefile after the SPD Makefile (the platform
-# makefile may use all previous definitions in this file)
-################################################################################
-include ${PLAT_MAKEFILE_FULL}
-
-################################################################################
# Setup arch_features based on ARM_ARCH_MAJOR, ARM_ARCH_MINOR provided from
# platform.
################################################################################
@@ -599,11 +598,6 @@
################################################################################
# FEAT_RME
ifeq (${ENABLE_RME},1)
- # RME doesn't support PIE
- ifneq (${ENABLE_PIE},0)
- $(error ENABLE_RME does not support PIE)
- endif
-
# RME requires AARCH64
ifneq (${ARCH},aarch64)
$(error ENABLE_RME requires AArch64)
@@ -882,6 +876,10 @@
CRYPTO_SUPPORT := 0
endif #($(MEASURED_BOOT)-$(TRUSTED_BOARD_BOOT))
+ifneq ($(filter 1 2 3,$(CRYPTO_SUPPORT)),)
+CRYPTO_LIB := $(BUILD_PLAT)/lib/libmbedtls.a
+endif
+
# SDEI_IN_FCONF is only supported when SDEI_SUPPORT is enabled.
ifeq ($(SDEI_SUPPORT)-$(SDEI_IN_FCONF),0-1)
$(error "SDEI_IN_FCONF is only supported when SDEI_SUPPORT is enabled")
@@ -951,8 +949,29 @@
ifeq (${ENABLE_FEAT_RNG_TRAP},1)
$(error "ENABLE_FEAT_RNG_TRAP cannot be used with ARCH=aarch32")
endif
+
+ ifneq (${ENABLE_FEAT_FPMR},0)
+ $(error "ENABLE_FEAT_FPMR cannot be used with ARCH=aarch32")
+ endif
+
+ ifeq (${ARCH_FEATURE_AVAILABILITY},1)
+ $(error "ARCH_FEATURE_AVAILABILITY cannot be used with ARCH=aarch32")
+ endif
+ # FEAT_MOPS is only supported on AArch64
+ ifneq (${ENABLE_FEAT_MOPS},0)
+ $(error "ENABLE_FEAT_MOPS cannot be used with ARCH=aarch32")
+ endif
endif #(ARCH=aarch32)
+ifneq (${ENABLE_FEAT_FPMR},0)
+ ifeq (${ENABLE_FEAT_FGT},0)
+ $(error "ENABLE_FEAT_FPMR requires ENABLE_FEAT_FGT")
+ endif
+ ifeq (${ENABLE_FEAT_HCX},0)
+ $(error "ENABLE_FEAT_FPMR requires ENABLE_FEAT_HCX")
+ endif
+endif #(ENABLE_FEAT_FPMR)
+
ifneq (${ENABLE_SME_FOR_NS},0)
ifeq (${ENABLE_SVE_FOR_NS},0)
$(error "ENABLE_SME_FOR_NS requires ENABLE_SVE_FOR_NS")
@@ -1021,6 +1040,10 @@
$(info DRTM_SUPPORT is an experimental feature)
endif
+ifeq (${HOB_LIST},1)
+ $(warning HOB_LIST is an experimental feature)
+endif
+
ifeq (${TRANSFER_LIST},1)
$(info TRANSFER_LIST is an experimental feature)
endif
@@ -1186,6 +1209,7 @@
PROGRAMMABLE_RESET_ADDRESS \
PSCI_EXTENDED_STATE_ID \
PSCI_OS_INIT_MODE \
+ ARCH_FEATURE_AVAILABILITY \
RESET_TO_BL31 \
SAVE_KEYS \
SEPARATE_CODE_AND_RODATA \
@@ -1234,6 +1258,7 @@
PLATFORM_REPORT_CTX_MEM_USE \
EARLY_CONSOLE \
PRESERVE_DSU_PMU_REGS \
+ HOB_LIST \
)))
# Numeric_Flags
@@ -1259,8 +1284,10 @@
ENABLE_FEAT_ECV \
ENABLE_FEAT_FGT \
ENABLE_FEAT_FGT2 \
+ ENABLE_FEAT_FPMR \
ENABLE_FEAT_HCX \
ENABLE_FEAT_LS64_ACCDATA \
+ ENABLE_FEAT_MOPS \
ENABLE_FEAT_MTE2 \
ENABLE_FEAT_PAN \
ENABLE_FEAT_RNG \
@@ -1365,6 +1392,7 @@
PROGRAMMABLE_RESET_ADDRESS \
PSCI_EXTENDED_STATE_ID \
PSCI_OS_INIT_MODE \
+ ARCH_FEATURE_AVAILABILITY \
RESET_TO_BL31 \
RME_GPT_BITLOCK_BLOCK \
RME_GPT_MAX_BLOCK \
@@ -1420,6 +1448,7 @@
ENABLE_MPMM_FCONF \
ENABLE_FEAT_FGT \
ENABLE_FEAT_FGT2 \
+ ENABLE_FEAT_FPMR \
ENABLE_FEAT_ECV \
ENABLE_FEAT_AMUv1p1 \
ENABLE_FEAT_SEL2 \
@@ -1437,6 +1466,7 @@
ENABLE_FEAT_SCTLR2 \
ENABLE_FEAT_D128 \
ENABLE_FEAT_GCS \
+ ENABLE_FEAT_MOPS \
ENABLE_FEAT_MTE2 \
FEATURE_DETECTION \
TWED_DELAY \
@@ -1451,6 +1481,7 @@
PLATFORM_REPORT_CTX_MEM_USE \
EARLY_CONSOLE \
PRESERVE_DSU_PMU_REGS \
+ HOB_LIST \
)))
ifeq (${PLATFORM_REPORT_CTX_MEM_USE}, 1)
@@ -1620,29 +1651,17 @@
clean:
$(s)echo " CLEAN"
- $(call SHELL_REMOVE_DIR,${BUILD_PLAT})
-ifdef UNIX_MK
+ $(q)rm -rf $(BUILD_PLAT)
$(q)${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
-else
-# Clear the MAKEFLAGS as we do not want
-# to pass the gnumake flags to nmake.
- $(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) clean
-endif #(UNIX_MK)
$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} clean
$(q)${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
realclean distclean:
$(s)echo " REALCLEAN"
- $(call SHELL_REMOVE_DIR,${BUILD_BASE})
- $(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*)
-ifdef UNIX_MK
+ $(q)rm -rf $(BUILD_BASE)
+ $(q)rm -rf $(CURDIR)/cscope.*
$(q)${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
-else
-# Clear the MAKEFLAGS as we do not want
-# to pass the gnumake flags to nmake.
- $(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean
-endif #(UNIX_MK)
$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} realclean
$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean
$(q)${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
@@ -1727,25 +1746,14 @@
fwu_fip: ${BUILD_PLAT}/${FWU_FIP_NAME}
${FIPTOOL}: FORCE
-ifdef UNIX_MK
$(q)${MAKE} PLAT=${PLAT} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} DEBUG=${DEBUG} --no-print-directory -C ${FIPTOOLPATH} all
-else
-# Clear the MAKEFLAGS as we do not want
-# to pass the gnumake flags to nmake.
- $(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
-endif #(UNIX_MK)
-$(BUILD_PLAT)/romlib/romlib.bin $(BUILD_PLAT)/lib/libwrappers.a $&: $(BUILD_PLAT)/lib/libmbedtls.a $(BUILD_PLAT)/lib/libfdt.a $(BUILD_PLAT)/lib/libc.a
- $(q)${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES=$(call escape-shell,$(INCLUDES)) DEFINES=$(call escape-shell,$(DEFINES)) --no-print-directory -C ${ROMLIBPATH} all
+$(BUILD_PLAT)/romlib/romlib.bin $(BUILD_PLAT)/lib/libwrappers.a $&: $(BUILD_PLAT)/lib/libfdt.a $(BUILD_PLAT)/lib/libc.a $(CRYPTO_LIB)
+ $(q)${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} CRYPTO_SUPPORT=${CRYPTO_SUPPORT} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES=$(call escape-shell,$(INCLUDES)) DEFINES=$(call escape-shell,$(DEFINES)) --no-print-directory -C ${ROMLIBPATH} all
memmap: all
-ifdef UNIX_MK
$(q)PYTHONPATH=${CURDIR}/tools/memory \
${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
-else
- $(q)set PYTHONPATH=${CURDIR}/tools/memory && \
- ${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
-endif
tl: ${BUILD_PLAT}/tl.bin
${BUILD_PLAT}/tl.bin: ${HW_CONFIG}
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 336ad2b..2f9dc65 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -150,6 +150,10 @@
BL31_SOURCES += lib/extensions/trf/aarch64/trf.c
endif
+ifneq (${ENABLE_FEAT_FPMR},0)
+BL31_SOURCES += lib/extensions/fpmr/fpmr.c
+endif
+
ifeq (${WORKAROUND_CVE_2017_5715},1)
BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \
lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 8c03ab8..821ccb8 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -280,6 +280,18 @@
ID_AA64MMFR3_EL1_D128_MASK);
}
+static unsigned int read_feat_fpmr_id_field(void)
+{
+ return ISOLATE_FIELD(read_id_aa64pfr2_el1(), ID_AA64PFR2_EL1_FPMR_SHIFT,
+ ID_AA64PFR2_EL1_FPMR_MASK);
+}
+
+static unsigned int read_feat_mops_id_field(void)
+{
+ return ISOLATE_FIELD(read_id_aa64isar2_el1(), ID_AA64ISAR2_EL1_MOPS_SHIFT,
+ ID_AA64ISAR2_EL1_MOPS_MASK);
+}
+
/***********************************************************************************
* TF-A supports many Arm architectural features starting from arch version
* (8.0 till 8.7+). These features are mostly enabled through build flags. This
@@ -337,6 +349,8 @@
check_feature(ENABLE_FEAT_DIT, read_feat_dit_id_field(), "DIT", 1, 1);
check_feature(ENABLE_FEAT_AMU, read_feat_amu_id_field(),
"AMUv1", 1, 2);
+ check_feature(ENABLE_FEAT_MOPS, read_feat_mops_id_field(),
+ "MOPS", 1, 1);
check_feature(ENABLE_FEAT_MPAM, read_feat_mpam_version(),
"MPAM", 1, 17);
check_feature(CTX_INCLUDE_NEVE_REGS, read_feat_nv_id_field(),
@@ -405,6 +419,8 @@
"SME", 1, 2);
check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(),
"SME2", 2, 2);
+ check_feature(ENABLE_FEAT_FPMR, read_feat_fpmr_id_field(),
+ "FPMR", 1, 1);
/* v9.3 features */
check_feature(ENABLE_FEAT_D128, read_feat_d128_id_field(),
diff --git a/docs/about/index.rst b/docs/about/index.rst
index 06973ef..7cf2a68 100644
--- a/docs/about/index.rst
+++ b/docs/about/index.rst
@@ -7,6 +7,7 @@
features
release-information
+ lts
maintainers
contact
acknowledgements
diff --git a/docs/about/lts.rst b/docs/about/lts.rst
new file mode 100644
index 0000000..f5e5f8e
--- /dev/null
+++ b/docs/about/lts.rst
@@ -0,0 +1,364 @@
+LTS - Long-Term Support
+=======================
+
+.. table:: Table 1: Document History
+
+ +-------------+--------------------+-------------------------------------------------------+
+ | Date | Author | Description |
+ +=============+====================+=======================================================+
+ | 2022-07-20 | Okash Khawaja, | Initial draft. |
+ | | Varun Wadekar | |
+ +-------------+--------------------+-------------------------------------------------------+
+ | 2022-07-21 | Varun Wadekar | Refine the Maintainership guidelines and planning |
+ | | | sections. Introduce a new section documenting a day |
+ | | | in the life of a LTS branch maintainer |
+ +-------------+--------------------+-------------------------------------------------------+
+ | 2022-08-05 | Okash Khawaja, | Merge two drafts (draft 1 and 2), address comments |
+ | | Varun Wadekar | made by both authors, cosmetic changes to the content |
+ | | | all over the document |
+ +-------------+--------------------+-------------------------------------------------------+
+ | 2022-08-05 | Okash Khawaja | Add note about testing support available from TF.org |
+ +-------------+--------------------+-------------------------------------------------------+
+ | 2022-08-05 | Varun Wadekar | Changed the “Future plans” section to “FAQ” and |
+ | | | answered some of the questions with feedback from |
+ | | | the community. |
+ +-------------+--------------------+-------------------------------------------------------+
+ | 2025-01-07 | Govindraj Raja | Convert from pdf to rst. |
+ +-------------+--------------------+-------------------------------------------------------+
+ | 2025-01-07 | Govindraj Raja | Updates based on learnings and suggestions. |
+ +-------------+--------------------+-------------------------------------------------------+
+
+This document proposes a plan for long-term support (LTS) of the |TF-A| project.
+
+Why is LTS required?
+--------------------
+LTS is needed for commercial reasons. More specifically, on the device side,
+when a product is released, the companies have to support that in-market product
+such that the amount of changes to the firmware are kept to a minimum to avoid
+the risk of regression. At the same time the companies don't want to exclude
+critical patches such as those for security advisories. Similarly on the server side,
+companies want to minimize the churn when deploying fixes during incident
+response, e.g. due to critical security bugs.
+
+Also, the European Cyber Resilience Act (CRA) is a new EU legislation that mandates
+cybersecurity standards for products containing digital elements, aiming to
+protect consumers and businesses by ensuring manufacturers build security into
+their hardware and software throughout their lifecycle, including automatic
+updates and incident reporting; essentially requiring all digital products
+sold in the EU to meet specific cybersecurity requirements.
+
+This means that companies have to maintain and backport critical updates to
+old branches internally. As this effort is duplicated across different companies
+using TF-A, it makes sense to factor out this effort into a community-wide LTS.
+
+What does LTS mean for TF-A?
+----------------------------
+In this section we will define exactly what constitutes LTS for TF-A.
+Specifically, we will define the following characteristics:
+
+- criteria for selecting patches which will be backported to LTS branches
+- lifetime and frequency of LTS branches
+
+**Criteria**
+
+We must have an objective criterion for selecting patches to be backported to
+LTS branches. This will make maintenance easy because:
+
+a. there will be less -- ideally no -- discussion when selecting patches to backport
+b. large parts of the process can be automated
+
+Below is the criteria
+
+#. No features will be backported.
+#. Security advisories: Any patch that makes it into :ref:`Security Advisories`
+ is automatically selected for back porting. This includes patches to external
+ components too, e.g. libfdt.
+#. Workarounds for CPU and other ARM IP errata
+#. Workarounds for non-ARM IP errata, e.g. TI UART
+#. Fixes for platform bugs. These patches must not modify any code outside of
+ the specific platform that the fix applies to.
+#. Patches can only be backported from the master branch. In other words, the
+ master branch will be a superset of all the changes in any LTS branch.
+
+**Lifetime and frequency**
+
+This section approaches three questions: for how long should an LTS release be
+supported, how frequently should LTS releases be made and at which time(s) of
+the year should the releases be made.
+
+1. For how long should an LTS release be supported?
+
+The Linux kernel maintainers supports an LTS branch for 2 years. Since firmware
+tends to have less churn and longer lifetime than a HLOS, TF-A is trying to
+support at-least 7 years for its LTS. Initially it was intended to support
+5 years but there has been no objections to extend LTS support to 7 years.
+There are many challenges that may influence the 7 year support from CI
+infrastructure to availability of maintainers.
+
+2. How frequently should LTS releases be made?
+
+Given that many products that have a release cycle, have a yearly release
+cycle, it would make sense to have yearly TF-A releases.
+
+3. Which time(s) of the year should the releases be made?
+
+TF-A releases are cut twice a year: May and November. Basing LTS release
+on the November TF-A release has a few benefits. First, it aligns with Linux
+LTS releases which happen towards the end of each year. Second, it aligns
+with Android releases which tend to fall in Q3 each year. Since product
+releases are timed with Android release, this gives enough time to harden
+the TF-A LTS release during development so that it's ready for launch in
+Q3 following year. On the other hand, if the May release of TF-A is chosen as
+the basis for LTS then developers will have little time -- about a month,
+taking into account the test-and-debug phase before LTS is cut (see below) --
+before Android release.
+
+To summarize, there will be one LTS release per year. It will be supported for
+5 years and we can discuss extending it to 7 years later on. The LTS release
+will be based on the November release of TF-A.
+
+**Testing Criteria**
+
+Every patch merged to the LTS branch will complete the following tests before
+getting approved.
+
+#. TFTF tests currently running in the testing farm
+#. CI/CD static analysis scans
+#. Coverity scans
+#. Platform tests
+
+Platforms that are not maintained upstream will undergo testing downstream in a
+pre-defined window. The platform maintainer will complete the testing and provide
+a verified score on the patch once testing is completed.
+
+** A note about test coverage from TF.org **
+
+Currently TF.org maintains a CI system to run TF-A automated tests on a
+selection of HW boards donated by TF.org members (a benefit reserved to project
+members, see the project charter for more details). This automated test coverage
+will be extended to cover testing for LTS as well for boards that are part of
+the CI system.
+
+**TFTF Branching**
+
+A note about testing here. After a patch is backported to an LTS branch, that
+branch will need to be regression tested. Since TFTF moves forward with latest
+TF-A changes, newer TFTF tests may not apply to old LTS branches. Therefore
+TFTF will also need to be branched, in-sync with TF-A LTS branches. In other
+words, there will be one TFTF LTS branch corresponding to each TF-A LTS branch.
+The TFTF LTS branch will be used to regression test the corresponding TF-A LTS
+branch.
+
+As we work with the LTS branch of TFTF, we might also need fixes for TFTF
+itself to be ported to LTS. However, decision-making about those patches need
+not be as stringent as for TF-A.
+
+**CI Scripts**
+
+CI Scripts moves forward with TF-A changes, since we need to checkout the
+corresponding release version of CI scripts for LTS.
+
+Though we are unlikely to update CI scripts, but time to time migrating a newer
+FVP version or deprecating certain tests due to unavailability of platforms may
+influence updates to CI Scripts.
+
+**Hafnium / OP-TEE**
+
+Both Hafnium and OP-TEE move forward with TF-A changes so we need to freeze their
+corresponding version from TF-A release for a LTS.
+
+**MbedTLS**
+
+Updates to the version of MbedTLS used with LTS will happen time to time based on
+maintainers call to update them or not.
+
+Release details
+---------------
+This section goes into details of what the LTS release process will look like.
+
+
+**Test-and-debug period**
+
+Since the LTS branch will be used in product releases, it is expected that more
+testing and debugging will be done on the November release of TF-A. Therefore
+it would make sense to leave at least a month after the November release and
+then cut the LTS branch. We recommend two months, given that one of the months
+is December which tends to be slower due to holidays. So, an end-of-November
+TF-A release would result in a beginning-of-February LTS release. Note that
+the LTS branch will be created at the same time as the TF-A November release,
+but it will be officially released at the end of January or early February.
+Going forward we should strive to make the period smaller and smaller until
+ideally it coincides with TF-A November release which means that our test
+and CI/CD infra is good enough to allow that to happen.
+
+**Example timeline**
+
+Below is an example timeline starting from the November 2022 release of TF-A.
+
+.. image:: ../resources/diagrams/lts-timeline-example.png
+
+- Nov 2022: TF-A 2.8 is released towards the end of Nov, 2022. Not shown in the
+ diagram, at the same time LTS release candidate branch is made which is based
+ on TF-A 2.8. This means new features going in 2.8 won’t go in the LTS branch.
+ We can call it `LTS 2.8-rc`.
+- Feb 2023: After testing and debugging LTS 2.8-rc for a couple of months,
+ LTS 2.8.0 is officially released in early Feb 2023.
+- May 2023: TF-A 2.9 is released but since this is not an LTS branch it doesn’t
+ affect LTS.
+- Somewhere between May and Nov of 2023: A security advisory comes up and the
+ related patches go into TF-A master branch. Since these patches fall under
+ LTS criteria, they are backported to LTS 2.8.0 which results in LTS 2.8.1
+ being released. Note that here we don’t allow the extra testing and debugging
+ time that we had between Nov 2022 and early Feb 2023. This is because there
+ isn’t as much to test and debug as an annual LTS release has. Also companies
+ might want to deploy critical patches soon.
+- Nov 2023: TF-A 2.10 is released. Not shown in the diagram, at the same time
+ LTS 2.10-rc is made. It’s tested by partners for a couple of months.
+- Feb 2024: LTS 2.10.1 is released in early Feb. Now there are two LTS
+ branches: 2.8.1 and 2.10.1.
+
+Note that TFTF will follow similar branching model as TF-A LTS, i.e. there will
+be TFTF LTS 2.8.0 in Feb 2023, 2.8.1 (if new TFTF tests need to be added for
+the security advisory) when there is TF-A LTS 2.8.1 and so on.
+
+Maintainership
+--------------
+
+**Guidelines & Responsibilities**
+
+#. Maintainers shall be impartial and strive to work for the benefit of
+ the community
+#. Objective and well-defined merge criteria to avoid confusion and discussions
+ at random points in time when there is a "candidate" patch
+#. The maintainers shall explain the lifecycle of a patch to the community,
+ with a detailed description of the maximum time spent in each step
+#. Automate, automate, automate
+#. Reviewers should not focus too much on "what" and instead focus on "how"
+#. Constantly refine the merge criteria to include more partner use cases
+#. Ensure that all candidate patches flow from the main branch to all LTS branches
+#. Maintainers collaborate in the following discord channel -
+ https://discord.com/channels/1106321706588577904/1162029539761852436
+#. Maintainers discuss and provide updates about upcoming LTS releases in the above
+ mentioned discord channel.
+
+**Options**
+
+These are some options in the order of preference.
+
+#. Current set of :ref:`lts maintainers` from tf.org(or hired contractor) take care of the LTS
+#. From the community, create a set of maintainers focused solely on the LTS branches
+
+A day in the life of a maintainer
+*********************************
+This section documents the daily tasks that a maintainer might perform to
+support the LTS program. It is expected that a maintainer follows clearly laid
+down steps and does not have to make policy level decisions for merge, testing,
+or candidate patch selection.
+
+#. Monitor the main branch to identify candidate patches for the LTS branches
+#. Monitor emails from LTS triage report to choose patches that should be
+ cherry-picked for LTS branches.
+#. Cherry-pick agreed patches to LTS branches co-ordinate review process and Monitor
+ CI results.
+#. Monitor the mailing list for any LTS related issues
+#. Propose or solicit patches to the main branch and tag them as candidates for LTS
+
+Execution Plan
+**************
+This section lists the steps needed to put the LTS system in place. However,
+to kick start LTS in Nov ‘22, only a few steps are needed. The rest can follow
+in the background.
+
+Initial release steps
+*********************
+
+The following steps are necessary to kickstart the project and potentially
+create the first LTS from the Nov’22 release.
+
+#. Create a TF-A LTS release-candidate branch and a TFTF LTS branch immediately
+ after the Nov’22 release
+#. Request all platform-owners to test and debug the RC branch
+#. Gather feedback from the test and debug cycle
+#. Mark the TF-A LTS branch ready by the end of January
+#. Announce the official LTS release availability on the mailing lists
+
+Long term release plan
+**********************
+Above will buy us time to then work on the rest of the execution plan which
+is given below.
+
+#. The review criteria for LTS patches must be the same as TF-A patches
+#. The maintainers shall publish the well-defined merge criteria to allow
+ the community to choose candidate patches
+#. The maintainers shall publish a well-defined test specification for any
+ patch entering the LTS branch
+
+ a. Tests required to pass in the CI/CD flow
+ b. Static analysis scans
+ c. Coverity scans
+
+#. The maintainers shall publish a mechanism to choose candidate patches for
+ the LTS branch
+#. The maintainers shall publish a mechanism to report bugs `[1]`_ seen with
+ an LTS branch
+#. The maintainers shall publish a versioning mechanism for the LTS branch
+
+ a. Bump minor version for any “logical” `[2]`_ fix(es) that gets merged
+
+#. The CI/CD infrastructure shall provide test support for all “live” LTS
+ branches at any given point in time
+#. The CI/CD infrastructure shall provide means to
+
+ a. notify all maintainers that a patch is ready for review
+ b. automatically cherry-pick a patch to a given LTS branch
+ c. get it through the CI/CD testing flow
+ d. gentle ping in LTS discord channel asking for reviews to ensure
+ cherry-picks are merged.
+
+FAQ
+***
+
+In our discussions, in addition to the above points we also considered some
+questions. They have been discussed on the mailing list too.
+
+| Q. What happens when a bug fix applies just to a LTS branch and not to the
+ master branch?
+| A. This will be treated as a special case and the bug, and the fix will be
+ discussed
+
+| Q. When testing a backported patch, what if one of the partners needs more
+ time while the patch fix is time-critical and, hence slowing other
+ partners?
+| A. The maintainers will add more detail to the review and merge process to
+ handle this scenario.
+
+| Q. How do we handle the increasing version numbers for errata fixes?
+| A. Too many CPU errata workarounds resulting in too many LTS releases.
+ We propose bumping the version number for each logical fix as
+ described in the section “Long term release plan” above because
+ that will help accurately track what changes have been deployed in-field.
+
+| Q. What if LTS support duration needs to be extended to longer than 5 years?
+| A. Still under discussion.
+
+These are uncharted waters, and we will face some unseen problems. When they
+become real problems, then we will have concrete data and be better able to
+address them. This means that our LTS definition as presented in this document
+is not the final one. We will constantly be discussing it and deciding how to
+adapt it as we see practical problems.
+
+.. _[1]:
+
+[1] The plan is to create a system where reviewers can tag a patch on mainline which
+gets automatically rebased on LTS and pushed to Gerrit. On seeing this patch,
+the CI/CD starts tests and provides a score. In parallel, the system also sends
+an email to the maintainers announcing the arrival of a candidate patch for the
+LTS branch.
+
+.. _[2]:
+
+[2] Logical will be a patch or patches implementing a certain fix. For example, if a
+security mitigation is fixed with the help of three patches, then all of them are
+considered as one "logical" fix. The version is incremented only after all these
+patches are merged. with the maintainers. If agreed unanimously, the bug fix
+will be merged to the affected LTS branches after completing the review process.
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index a8f1676..210ae7e 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -58,6 +58,8 @@
:|M|: Govindraj Raja <govindraj.raja@arm.com>
:|G|: `govindraj-arm`_
+.. _lts maintainers:
+
LTS Maintainers
---------------
@@ -71,6 +73,10 @@
:|G|: `vwadekar`_
:|M|: Yann Gautier <yann.gautier@st.com>
:|G|: `Yann-lms`_
+:|M|: Chris Palmer <palmer@google.com>
+:|G|: `noncombatant`_
+:|M|: Govindraj Raja <govindraj.raja@arm.com>
+:|G|: `govindraj-arm`_
.. _code owners:
@@ -653,8 +659,8 @@
Marvell platform ports and SoC drivers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Konstantin Porotchkin <kostap@marvell.com>
-:|G|: `kostapr`_
+:|M|: Jaiprakash Singh <jaiprakashs@marvell.com>
+:|G|: `sjaypee208`_
:|F|: docs/plat/marvell/
:|F|: plat/marvell/
:|F|: drivers/marvell/
@@ -1098,6 +1104,7 @@
.. _MrVan: https://github.com/MrVan
.. _Neal-liu: https://github.com/neal-liu
.. _niej: https://github.com/niej
+.. _noncombatant: https://github.com/noncombatant
.. _nmenon: https://github.com/nmenon
.. _npoushin: https://github.com/npoushin
.. _odeprez: https://github.com/odeprez
@@ -1128,6 +1135,7 @@
.. _vishnu-banavath: https://github.com/vishnu-banavath
.. _vwadekar: https://github.com/vwadekar
.. _Yann-lms: https://github.com/Yann-lms
+.. _sjaypee208: https://github.com/sjaypee208
--------------
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index 9d6bbf6..dc2b2fd 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -35,7 +35,7 @@
For example, TF-A v2.10 has VERSION_MAJOR=2, VERSION_MINOR=10 and VERSION_PATCH=0.
-This VERSION_PATCH macro is only increased for LTS releases.
+This VERSION_PATCH macro is only increased for :ref:`LTS - Long-Term Support` releases.
Upcoming Releases
~~~~~~~~~~~~~~~~~
@@ -120,4 +120,4 @@
--------------
-*Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design/auth-framework.rst b/docs/design/auth-framework.rst
index 6dc2245..9c04a8b 100644
--- a/docs/design/auth-framework.rst
+++ b/docs/design/auth-framework.rst
@@ -232,22 +232,42 @@
.. code:: c
void (*init)(void);
- int (*verify_signature)(void *data_ptr, unsigned int data_len,
+ int (*verify_signature)(
+ /* Data to verify. */
+ void *data_ptr, unsigned int data_len,
+ /* Bit string of the signature in DER format. */
void *sig_ptr, unsigned int sig_len,
+ /* ASN1 SignatureAlgorithm struct. */
void *sig_alg, unsigned int sig_alg_len,
+ /* ASN1 SubjectPublicKeyInfo struct. */
void *pk_ptr, unsigned int pk_len);
- int (*calc_hash)(enum crypto_md_algo alg, void *data_ptr,
- unsigned int data_len,
- unsigned char output[CRYPTO_MD_MAX_SIZE])
- int (*verify_hash)(void *data_ptr, unsigned int data_len,
- void *digest_info_ptr, unsigned int digest_info_len);
- int (*auth_decrypt)(enum crypto_dec_algo dec_algo, void *data_ptr,
- size_t len, const void *key, unsigned int key_len,
- unsigned int key_flags, const void *iv,
- unsigned int iv_len, const void *tag,
- unsigned int tag_len);
+ int (*calc_hash)(
+ /* SHA256, SHA384 and SHA512 can be used. */
+ enum crypto_md_algo alg
+ /* Data to hash. */
+ void *data_ptr, unsigned int data_len,
+ /* Buffer to store the output. */
+ unsigned char output[CRYPTO_MD_MAX_SIZE]);
+ int (*verify_hash)(
+ /* Data to verify. */
+ void *data_ptr, unsigned int data_len,
+ /* ASN1 DigestInfo struct. */
+ void *digest_info_ptr, unsigned int digest_info_len);
+ int (*auth_decrypt)(
+ /* Currently AES-GCM is the only supported alg. */
+ enum crypto_dec_algo dec_algo,
+ /* Data to decrypt. */
+ void *data_ptr, size_t len,
+ /* Decryption key. */
+ const void *key, unsigned int key_len,
+ unsigned int key_flags,
+ /* Initialization vector. */
+ const void *iv, unsigned int iv_len,
+ /* Authentication tag. */
+ const void *tag, unsigned int tag_len);
-These functions are registered in the CM using the macro:
+The above functions return values from the enum ``crypto_ret_value``.
+The functions are registered in the CM using the macro:
.. code:: c
@@ -262,10 +282,21 @@
``_name`` must be a string containing the name of the CL. This name is used for
debugging purposes.
-Crypto module provides a function ``_calc_hash`` to calculate and
-return the hash of the given data using the provided hash algorithm.
-This function is mainly used in the ``MEASURED_BOOT`` and ``DRTM_SUPPORT``
-features to calculate the hashes of various images/data.
+The ``_init`` function is used to perform any initialization required for
+the specific CM and CL.
+
+The ``_verify_signature`` function is used to verify certificates,
+and ``_verify_hash`` is used to verify raw images.
+
+The ``_calc_hash`` function is mainly used in the ``MEASURED_BOOT``
+and ``DRTM_SUPPORT`` features to calculate the hashes of various images/data.
+
+The ``_auth_decrypt`` function uses an authentication tag to perform
+authenticated decryption, providing guarantees on the authenticity
+of encrypted data. This function is used when the optional encrypted
+firmware feature is enabled, that is when ``ENCRYPT_BL31`` or
+``ENCRYPT_BL32`` are set to ``1`` and ``DECRYPTION_SUPPORT`` is
+set to ``aes_gcm``.
Optionally, a platform function can be provided to convert public key
(_convert_pk). It is only used if the platform saves a hash of the ROTPK.
@@ -970,30 +1001,44 @@
The cryptographic library
~~~~~~~~~~~~~~~~~~~~~~~~~
-The cryptographic module relies on a library to perform the required operations,
-i.e. verify a hash or a digital signature. Arm platforms will use a library
-based on mbed TLS, which can be found in
-``drivers/auth/mbedtls/mbedtls_crypto.c``. This library is registered in the
-authentication framework using the macro ``REGISTER_CRYPTO_LIB()`` and exports
-below functions:
+The cryptographic module relies on a library to perform essential operations
+such as verifying a hash or a digital signature.
+Arm platforms use a library based on mbedTLS located at
+``drivers/auth/mbedtls/mbedtls_crypto.c``.
+Additionally, an experimental alternative library based on PSA Crypto
+is available at ``drivers/auth/mbedtls/mbedtls_psa_crypto.c``. In future,
+``mbedtls_psa_crypto.c`` will replace ``mbedtls_crypto.c`` as the default Arm
+CM. Both libraries are registered in the authentication framework using
+the macro ``REGISTER_CRYPTO_LIB()``. These libraries implement the following
+exported functions, their implementations are compared side-by-side below:
-.. code:: c
+.. list-table:: Comparison of exported CM function implementations
+ :widths: 20 40 40
+ :header-rows: 1
- void init(void);
- int verify_signature(void *data_ptr, unsigned int data_len,
- void *sig_ptr, unsigned int sig_len,
- void *sig_alg, unsigned int sig_alg_len,
- void *pk_ptr, unsigned int pk_len);
- int crypto_mod_calc_hash(enum crypto_md_algo alg, void *data_ptr,
- unsigned int data_len,
- unsigned char output[CRYPTO_MD_MAX_SIZE])
- int verify_hash(void *data_ptr, unsigned int data_len,
- void *digest_info_ptr, unsigned int digest_info_len);
- int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
- size_t len, const void *key, unsigned int key_len,
- unsigned int key_flags, const void *iv,
- unsigned int iv_len, const void *tag,
- unsigned int tag_len)
+ * - CM function
+ - ``mbedtls_crypto.c``
+ - ``mbedtls_psa_crypto.c``
+ * - ``init``
+ - Initialize the heap for mbedTLS.
+ - Initialize the heap for mbedTLS and call ``psa_crypto_init``.
+ * - ``verify_signature``
+ - Use mbedTLS to parse the ASN1 inputs, and then use the mbedTLS pk module to verify the signature.
+ - Use mbedTLS to parse the ASN1 inputs, use the mbedTLS pk module to parse the key,
+ import it into the PSA key system and then use ``psa_verify_message`` to verify the signature.
+ * - ``calc_hash``
+ - Use the ``mbedtls_md`` API to calculate the hash of the given data.
+ - Use ``psa_hash_compute`` to calculate the hash of the given data.
+ * - ``verify_hash``
+ - Use the ``mbedtls_md`` API to calculate the hash of the given data,
+ and then compare it against the data which is to be verified.
+ - Call ``psa_hash_compare``, which both calculates the hash of the given data and
+ compares this hash against the data to be verified.
+ * - ``auth_decrypt``
+ - Use the ``mbedtls_gcm`` API to decrypt the data, and then verify the returned
+ tag by comparing it to the inputted tag.
+ - Load the key into the PSA key store, and then use ``psa_aead_verify`` to
+ decrypt and verify the tag.
The mbedTLS library algorithm support is configured by both the
``TF_MBEDTLS_KEY_ALG`` and ``TF_MBEDTLS_KEY_SIZE`` variables.
@@ -1017,6 +1062,6 @@
--------------
-*Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.*
.. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index fda43dc..369ec6f 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -33,6 +33,11 @@
This build option should be set to 1 if the target platform contains at
least 1 CPU that requires this mitigation. Defaults to 1.
+- ``WORKAROUND_CVE_2024_5660``: Enables mitigation for `CVE-2024-5660`.
+ The fix is to disable hardware page aggregation by setting CPUECTLR_EL1[46]
+ in EL3 FW. This build option should be set to 1 if the target platform contains
+ at least 1 CPU that requires this mitigation. Defaults to 1.
+
.. _arm_cpu_macros_errata_workarounds:
CPU Errata Workarounds
@@ -843,6 +848,9 @@
- ``ERRATA_X4_2897503``: This applies errata 2897503 workaround to Cortex-X4
CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+- ``ERRATA_X4_2923985``: This applies errata 2923985 workaround to Cortex-X4
+ CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
- ``ERRATA_X4_3076789``: This applies errata 3076789 workaround to Cortex-X4
CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst
index caf367b..1cc1ba6 100644
--- a/docs/design/trusted-board-boot-build.rst
+++ b/docs/design/trusted-board-boot-build.rst
@@ -54,16 +54,34 @@
On Juno board, the default value corresponds to an ECDSA-SECP256R1 public
key hash, whose private part is not currently available.
- - ``ARM_ROTPK_LOCATION=devel_rsa``: use the default hash located in
- ``plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin``. Enforce
- generation of the new hash if ``ROT_KEY`` is specified.
+ - ``ARM_ROTPK_LOCATION=devel_rsa``: the ROTPK is a hash of the
+ RSA public key corresponding to the private key specified by
+ ``ROT_KEY``. If ``ROT_KEY`` is not specified, the private key is
+ the development key ``plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem``.
+ There are also 3k and 4k RSA development keys in ``plat/arm/board/common/rotpk/``.
+ The hashing algorithm is selected by ``HASH_ALG``; sha256 is used if
+ ``HASH_ALG`` is not specified.
- - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the default hash located in
- ``plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin``. Enforce
- generation of the new hash if ``ROT_KEY`` is specified.
+ - ``ARM_ROTPK_LOCATION=devel_ecdsa``: the ROTPK is a hash of the
+ ECDSA public key corresponding to the private key specified by
+ ``ROT_KEY``. If ``ROT_KEY`` is not specified, the private key is
+ the development key ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem`` by default,
+ a 384 bit key ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa_secp384r1.pem`` also exists,
+ and can be specified by ``ROT_KEY``. The hashing algorithm is selected by ``HASH_ALG``;
+ sha256 is used if ``HASH_ALG`` is not specified.
- - ``ARM_ROTPK_LOCATION=devel_full_dev_rsa_key``: use the key located in
- ``plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S``.
+ - ``ARM_ROTPK_LOCATION=devel_full_dev_rsa_key``: the ROTPK is an unhashed
+ RSA public key corresponding to the private key specified by ``ROT_KEY``.
+ If ``ROT_KEY`` is not specified, the private key is the development key
+ ``plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem``. There are also
+ 3k and 4k RSA development keys in ``plat/arm/board/common/rotpk/``.
+
+ - ``ARM_ROTPK_LOCATION=devel_full_dev_ecdsa_key``: the ROTPK is an unhashed
+ RSA public key corresponding to the private key specified by ``ROT_KEY``.
+ If ``ROT_KEY`` is not specified, the private key is the development key
+ ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem``, a 384 bit key
+ ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa_secp384r1.pem`` also exists,
+ and can be specified by ``ROT_KEY``.
Example of command line using RSA development keys:
@@ -119,7 +137,7 @@
--------------
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
.. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git
.. _mbed TLS Security Center: https://tls.mbed.org/security
diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst
index f10d2e7..f3e094c 100644
--- a/docs/design/trusted-board-boot.rst
+++ b/docs/design/trusted-board-boot.rst
@@ -39,7 +39,8 @@
- A Root of Trust Public Key (ROTPK), or a hash of it.
- On Arm development platforms, a SHA-256 hash of the ROTPK is stored in the
+ On Arm development platforms, a hash of the ROTPK (hash algorithm selected by
+ the ``HASH_ALG`` build option, with sha256 as default) is stored in the
trusted root-key storage registers. Alternatively, a development ROTPK might
be used and its hash embedded into the BL1 and BL2 images (only for
development purposes).
@@ -330,7 +331,7 @@
--------------
-*Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.*
.. _X.509 v3: https://tools.ietf.org/rfc/rfc5280.txt
.. _Trusted Board Boot Requirements (TBBR): https://developer.arm.com/docs/den0006/latest
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index ab0b94d..58321e7 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -351,6 +351,12 @@
This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
mechanism. Default value is ``0``.
+- ``ENABLE_FEAT_FPMR``: Numerical value to enable support for Floating Point
+ Mode Register feature, allowing access to the FPMR register. FPMR register
+ controls the behaviors of FP8 instructions. It is an optional architectural
+ feature from v9.2 and upwards. This flag can take value of 0 to 2, to align
+ with the ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
+
- ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps)
feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained
Read Trap Register) during EL2 to EL3 context save/restore operations.
@@ -372,6 +378,16 @@
flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
mechanism. Default value is ``0``.
+- ``ENABLE_FEAT_MOPS``: Numeric value to enable FEAT_MOPS (Standardization
+ of memory operations) when INIT_UNUSED_NS_EL2=1.
+ This feature is mandatory from v8.8 and enabling of FEAT_MOPS does not
+ require any settings from EL3 as the controls are present in EL2 registers
+ (HCRX_EL2.{MSCEn,MCE2} and SCTLR_EL2.MSCEn) and in most configurations
+ we expect EL2 to be present. But in case of INIT_UNUSED_NS_EL2=1 ,
+ EL3 should configure the EL2 registers. This flag
+ can take values 0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
+ Default value is ``0``.
+
- ``ENABLE_FEAT_MTE2``: Numeric value to enable Memory Tagging Extension2
if the platform wants to use this feature and MTE2 is enabled at ELX.
This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
@@ -708,6 +724,10 @@
invert this behavior. Lower addresses will be printed at the top and higher
addresses at the bottom.
+- ``INIT_UNUSED_NS_EL2``: This build flag guards code that disables EL2
+ safely in scenario where NS-EL2 is present but unused. This flag is set to 0
+ by default. Platforms without NS-EL2 in use must enable this flag.
+
- ``KEY_ALG``: This build flag enables the user to select the algorithm to be
used for generating the PKCS keys and subsequent signing of the certificate.
It accepts 5 values: ``rsa``, ``rsa_1_5``, ``ecdsa``, ``ecdsa-brainpool-regular``
@@ -727,9 +747,9 @@
+---------------------------+------------------------------------+
| ecdsa | 256 (default), 384 |
+---------------------------+------------------------------------+
- | ecdsa-brainpool-regular | unavailable |
+ | ecdsa-brainpool-regular | 256 (default) |
+---------------------------+------------------------------------+
- | ecdsa-brainpool-twisted | unavailable |
+ | ecdsa-brainpool-twisted | 256 (default) |
+---------------------------+------------------------------------+
- ``HASH_ALG``: This build flag enables the user to select the secure hash
@@ -848,6 +868,11 @@
- ``PSCI_OS_INIT_MODE``: Boolean flag to enable support for optional PSCI
OS-initiated mode. This option defaults to 0.
+- ``ARCH_FEATURE_AVAILABILITY``: Boolean flag to enable support for the
+ optional SMCCC_ARCH_FEATURE_AVAILABILITY call. This option implicitly
+ interacts with IMPDEF_SYSREG_TRAP and software emulation. This option
+ defaults to 0.
+
- ``ENABLE_FEAT_RAS``: Boolean flag to enable Armv8.2 RAS features. RAS features
are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
or later CPUs. This flag can take the values 0 or 1. The default value is 0.
@@ -1411,6 +1436,10 @@
interface through BL31 as a SiP SMC function.
Default is disabled (0).
+- ``HOB_LIST``: Setting this to ``1`` enables support for passing boot
+ information using HOB defined in `Platform Initialization specification`_.
+ This defaults to ``0``.
+
Firmware update options
~~~~~~~~~~~~~~~~~~~~~~~
@@ -1454,3 +1483,4 @@
.. _Clang: https://clang.llvm.org/docs/DiagnosticsReference.html
.. _Firmware Handoff specification: https://github.com/FirmwareHandoff/firmware_handoff/releases/tag/v0.9
.. _PSA Crypto API specification: https://armmbed.github.io/mbed-crypto/html/
+.. _Platform Initialization specification: https://uefi.org/specs/PI/1.8/index.html
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index c414b1f..32c2b39 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -31,7 +31,7 @@
Clang/LLVM 18.1.8
Device Tree Compiler 1.6.1
GNU make 3.81
-mbed TLS\ [#f1]_ 3.6.1
+mbed TLS\ [#f1]_ 3.6.2
Node.js [#f2]_ 16
OpenSSL 1.0.0
Poetry 1.3.2
diff --git a/docs/glossary.rst b/docs/glossary.rst
index f19897c..20ad21c 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -130,6 +130,9 @@
Memory Tagging Extension. An optional Armv8.5 extension that enables
hardware-assisted memory tagging.
+ LTS
+ Long-Term Support
+
OEN
Owning Entity Number
diff --git a/docs/license.rst b/docs/license.rst
index 9e0298b..e35b9bb 100644
--- a/docs/license.rst
+++ b/docs/license.rst
@@ -110,6 +110,14 @@
- ``tools/cot_dt2c/cot_dt2c/pydevicetree/source/parser.py``
- ``tools/cot_dt2c/cot_dt2c/pydevicetree/__init__.py``
+- Some source files originating from the `edk2`_ project.
+ These files are licensed under the BSD-2-Clause. Any contributions to this
+ code must also be made under the terms of BSD-2-Clause.
+ These files are:
+
+ - ``lib/hob/hob.c``
+ - ``include/lib/hob/mmram.h``
+ - ``include/lib/hob/mpinfo.h``
.. _FreeBSD: http://www.freebsd.org
.. _Linux MIT license: https://raw.githubusercontent.com/torvalds/linux/master/LICENSES/preferred/MIT
@@ -117,3 +125,4 @@
.. _Open Profile for DICE: https://pigweed.googlesource.com/open-dice/
.. _Apache License 2.0: https://www.apache.org/licenses/LICENSE-2.0.txt
.. _pydevicetree: https://pypi.org/project/pydevicetree/
+.. _edk2: https://github.com/tianocore/edk2
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index afbb157..a086a98 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -65,25 +65,26 @@
- ``regs`` : return the ROTPK hash stored in the Trusted root-key storage
registers.
- ``devel_rsa`` : return a development public key hash embedded in the BL1
- and BL2 binaries. This hash has been obtained from the RSA public key
- ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use
- this option, ``arm_rotprivk_rsa.pem`` must be specified as ``ROT_KEY``
- when creating the certificates.
+ and BL2 binaries. This hash corresponds to the development private key
+ ``plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem``.
+ The hashing algorithm is selected by ``HASH_ALG``; sha256 is used if
+ ``HASH_ALG`` is not specified. A different RSA key can be specified by setting
+ ``ROT_KEY``, there are 3k and 4k RSA keys in ``plat/arm/board/common/rotpk/``.
- ``devel_ecdsa`` : return a development public key hash embedded in the BL1
- and BL2 binaries. This hash has been obtained from the ECDSA public key
- ``arm_rotpk_ecdsa.der``, located in ``plat/arm/board/common/rotpk``. To
- use this option, ``arm_rotprivk_ecdsa.pem`` must be specified as
- ``ROT_KEY`` when creating the certificates.
- - ``devel_full_dev_rsa_key`` : returns a development public key embedded in
- the BL1 and BL2 binaries. This key has been obtained from the RSA public
- key ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``.
-
-- ``ARM_ROTPK_HASH``: used when ``ARM_ROTPK_LOCATION=devel_*``, excluding
- ``devel_full_dev_rsa_key``. Specifies the location of the ROTPK hash. Not
- expected to be a build option. This defaults to
- ``plat/arm/board/common/rotpk/*_sha256.bin`` depending on the specified
- algorithm. Providing ``ROT_KEY`` enforces generation of the hash from the
- ``ROT_KEY`` and overwrites the default hash file.
+ and BL2 binaries. This hash corresponds to the development private key
+ ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem`` unless a different key
+ is specified with ``ROT_KEY``, such as the 384 bit key in the same directory.
+ he hashing algorithm is selected by ``HASH_ALG``; sha256 is used if ``HASH_ALG``
+ is not specified.
+ - ``devel_full_dev_rsa_key`` : return a development public key embedded in
+ the BL1 and BL2 binaries. This key corresponds to the RSA private
+ key ``plat/arm/board/common/rotpk/arm_rotprivk.pem`` by default, but can
+ be changed by setting ``ROT_KEY``, there are 3k and 4k RSA keys in
+ ``plat/arm/board/common/rotpk/``.
+ - ``devel_full_dev_ecdsa_key`` : return a development public key embedded in
+ the BL1 and BL2 binaries. This key corresponds to the EC private key
+ ``plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem``, unless a different
+ ECDSA key is specified by ``ROT_KEY``, such as the 384 bit key in the same directory.
- ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options:
diff --git a/docs/plat/meson-gxl.rst b/docs/plat/meson-gxl.rst
index 0751f1d..df64505 100644
--- a/docs/plat/meson-gxl.rst
+++ b/docs/plat/meson-gxl.rst
@@ -19,6 +19,12 @@
CROSS_COMPILE=aarch64-linux-gnu- make DEBUG=1 PLAT=gxl
+Or, if willing to boot from U-Boot SPL (using standard params handling):
+
+.. code:: shell
+
+ CROSS_COMPILE=aarch64-linux-gnu- make DEBUG=1 PLAT=gxl AML_STDPARAMS=1
+
This port has been tested on a Lepotato. After building it, follow the
instructions in the `gxlimg repository`_ or `U-Boot repository`_, replacing the
mentioned **bl31.img** by the one built from this port.
diff --git a/docs/plat/qti.rst b/docs/plat/qti.rst
index 1d483e7..0f89500 100644
--- a/docs/plat/qti.rst
+++ b/docs/plat/qti.rst
@@ -2,7 +2,7 @@
===========================
Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QTI SC7180,
-SC7280.
+SC7280 and QCS615.
Boot Trace
-------------
@@ -30,7 +30,8 @@
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sc7180 COREBOOT=1
-update value of CROSS_COMPILE argument with your cross-compilation toolchain.
+Update value of CROSS_COMPILE argument with your cross-compilation toolchain.
+Update the value of PLAT to be either of sc7180, sc7280 or qcs615
Additional QTISECLIB_PATH=<path to qtiseclib> can be added in build command.
if QTISECLIB_PATH is not added in build command stub implementation of qtiseclib
@@ -41,3 +42,4 @@
`link <https://github.com/coreboot/qc_blobs/blob/master/sc7180/qtiseclib/libqtisec.a?raw=true>`__
QTISELIB for SC7280 is available at
`link <https://github.com/coreboot/qc_blobs/blob/master/sc7280/qtiseclib/libqtisec.a?raw=true>`__
+QTISECLIB for QCS615 is not available yet and currently compile with stubs only.
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 5cb20fd..6d03f44 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2454,7 +2454,7 @@
The value should be obtained from a reliable source of randomness.
This function is only needed if ARMv8.3 pointer authentication is used in the
-Trusted Firmware by building with ``BRANCH_PROTECTION`` option set to non-zero.
+Trusted Firmware by building with ``BRANCH_PROTECTION`` option set to 1, 2 or 3.
Function : plat_get_syscnt_freq2() [mandatory]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -3553,7 +3553,10 @@
This function is invoked by BL31's exception handler when there is a synchronous
system register trap caused by access to the implementation defined registers.
It allows platforms enabling ``IMPDEF_SYSREG_TRAP`` to emulate those system
-registers choosing to program bits of their choice.
+registers choosing to program bits of their choice. If using in combination with
+``ARCH_FEATURE_AVAILABILITY``, the macros
+{SCR,MDCR,CPTR}_PLAT_{BITS,IGNORED,FLIPPED} should be defined to report correct
+results.
The first parameter (``uint64_t esr_el3``) contains the content of the ESR_EL3
syndrome register, which encodes the instruction that was trapped.
diff --git a/docs/resources/diagrams/lts-timeline-example.png b/docs/resources/diagrams/lts-timeline-example.png
new file mode 100644
index 0000000..edb1145
--- /dev/null
+++ b/docs/resources/diagrams/lts-timeline-example.png
Binary files differ
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index 9fe8b37..fbcbdc7 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -312,7 +312,7 @@
/*
* Send powerdown request to online secondary core(s)
*/
- ret = psci_stop_other_cores(0, css_raise_pwr_down_interrupt);
+ ret = psci_stop_other_cores(plat_my_core_pos(), 0, css_raise_pwr_down_interrupt);
if (ret != PSCI_E_SUCCESS) {
ERROR("Failed to powerdown secondary core(s)\n");
}
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index ef04c4d..adca4fd 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -124,22 +124,35 @@
gptbr_el3 << 12);
/*
- * ACCESSEN=1: SMMU- and client-originated accesses are
- * not terminated by this mechanism.
* GPCEN=1: All clients and SMMU-originated accesses,
* except GPT-walks, are subject to GPC.
+ *
+ * It is recommended to set GPCEN and wait for completion
+ * prior to setting ACCESSEN.
+ */
+ mmio_setbits_32(smmu_base + SMMU_ROOT_CR0,
+ SMMU_ROOT_CR0_GPCEN);
+
+ /* Poll for GPCEN ack bit. */
+ if (smmuv3_poll(smmu_base + SMMU_ROOT_CR0ACK,
+ SMMU_ROOT_CR0_GPCEN,
+ SMMU_ROOT_CR0_GPCEN) != 0) {
+ WARN("Failed enabling SMMU GPC.\n");
+ }
+
+ /*
+ * ACCESSEN=1: SMMU- and client-originated accesses are
+ * not terminated by this mechanism.
*/
mmio_setbits_32(smmu_base + SMMU_ROOT_CR0,
SMMU_ROOT_CR0_GPCEN |
SMMU_ROOT_CR0_ACCESSEN);
- /* Poll for ACCESSEN and GPCEN ack bits. */
+ /* Poll for ACCESSEN ack bit. */
if (smmuv3_poll(smmu_base + SMMU_ROOT_CR0ACK,
- SMMU_ROOT_CR0_GPCEN |
SMMU_ROOT_CR0_ACCESSEN,
- SMMU_ROOT_CR0_GPCEN |
SMMU_ROOT_CR0_ACCESSEN) != 0) {
- WARN("Failed enabling SMMU GPC.\n");
+ WARN("Failed enabling SMMU ACCESS.\n");
/*
* Do not return in error, but fall back to
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 765491e..b3c4c91 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -25,9 +25,9 @@
# Specify mbed TLS configuration file
ifeq (${PSA_CRYPTO},1)
- MBEDTLS_CONFIG_FILE ?= "<drivers/auth/mbedtls/psa_mbedtls_config.h>"
+ MBEDTLS_CONFIG_FILE ?= "<drivers/auth/mbedtls/default_psa_mbedtls_config.h>"
else
- MBEDTLS_CONFIG_FILE ?= "<drivers/auth/mbedtls/mbedtls_config-3.h>"
+ MBEDTLS_CONFIG_FILE ?= "<drivers/auth/mbedtls/default_mbedtls_config.h>"
endif
$(eval $(call add_define,MBEDTLS_CONFIG_FILE))
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
index 9b57607..235b988 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
@@ -7,6 +7,7 @@
#include <common/debug.h>
#include <drivers/clk.h>
#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
#include <s32cc-clk-ids.h>
#include <s32cc-clk-modules.h>
#include <s32cc-clk-regs.h>
@@ -1464,7 +1465,39 @@
return 0;
}
-void s32cc_clk_register_drv(void)
+static int s32cc_clk_mmap_regs(const struct s32cc_clk_drv *drv)
+{
+ const uintptr_t base_addrs[11] = {
+ drv->fxosc_base,
+ drv->armpll_base,
+ drv->periphpll_base,
+ drv->armdfs_base,
+ drv->cgm0_base,
+ drv->cgm1_base,
+ drv->cgm5_base,
+ drv->ddrpll_base,
+ drv->mc_me,
+ drv->mc_rgm,
+ drv->rdc,
+ };
+ size_t i;
+ int ret;
+
+ for (i = 0U; i < ARRAY_SIZE(base_addrs); i++) {
+ ret = mmap_add_dynamic_region(base_addrs[i], base_addrs[i],
+ PAGE_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE);
+ if (ret != 0) {
+ ERROR("Failed to map clock module 0x%" PRIuPTR "\n",
+ base_addrs[i]);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int s32cc_clk_register_drv(bool mmap_regs)
{
static const struct clk_ops s32cc_clk_ops = {
.enable = s32cc_clk_enable,
@@ -1475,7 +1508,19 @@
.get_parent = s32cc_clk_get_parent,
.set_parent = s32cc_clk_set_parent,
};
+ const struct s32cc_clk_drv *drv;
clk_register(&s32cc_clk_ops);
+
+ drv = get_drv();
+ if (drv == NULL) {
+ return -EINVAL;
+ }
+
+ if (mmap_regs) {
+ return s32cc_clk_mmap_regs(drv);
+ }
+
+ return 0;
}
diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
index 02b9df9..f001568 100644
--- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -180,11 +180,14 @@
return ret;
}
-int s32cc_init_early_clks(void)
+int s32cc_init_core_clocks(void)
{
int ret;
- s32cc_clk_register_drv();
+ ret = s32cc_clk_register_drv(false);
+ if (ret != 0) {
+ return ret;
+ }
ret = setup_fxosc();
if (ret != 0) {
@@ -206,6 +209,18 @@
return ret;
}
+ return ret;
+}
+
+int s32cc_init_early_clks(void)
+{
+ int ret;
+
+ ret = s32cc_clk_register_drv(true);
+ if (ret != 0) {
+ return ret;
+ }
+
ret = setup_periph_pll();
if (ret != 0) {
return ret;
diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c
index 66662c1..1529dc0 100644
--- a/drivers/renesas/common/io/io_rcar.c
+++ b/drivers/renesas/common/io/io_rcar.c
@@ -149,6 +149,9 @@
static uint64_t rcar_image_header_prttn[RCAR_MAX_BL3X_IMAGE + 2U] = { 0U };
static uint64_t rcar_image_number = { 0U };
static uint32_t rcar_cert_load = { 0U };
+#if (RCAR_RPC_HYPERFLASH_ABLOADER == 1)
+static uint32_t rcar_image_offset = 0U;
+#endif
static io_type_t device_type_rcar(void)
{
@@ -196,8 +199,10 @@
*offset = rcar_image_header[addr];
- if (mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION)
- *offset += 0x800000;
+#if (RCAR_RPC_HYPERFLASH_ABLOADER == 1)
+ *offset += rcar_image_offset;
+#endif
+
*cert = RCAR_CERT_SIZE;
*cert *= RCAR_ATTR_GET_CERTOFF(name_offset[i].attr);
*cert += RCAR_SDRAM_certESS;
@@ -499,6 +504,15 @@
*/
offset = name == EMMC_DEV_ID ? RCAR_EMMC_CERT_HEADER :
RCAR_FLASH_CERT_HEADER;
+
+#if (RCAR_RPC_HYPERFLASH_ABLOADER == 1)
+ rcar_image_offset = 0;
+ if ((name == FLASH_DEV_ID) &&
+ (mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION)) {
+ rcar_image_offset = 0x800000;
+ }
+#endif
+
rc = io_seek(handle, IO_SEEK_SET, offset);
if (rc != IO_SUCCESS) {
WARN("Firmware Image Package header failed to seek\n");
diff --git a/fdts/rd1ae.dts b/fdts/rd1ae.dts
index 6e821ae..26eaa65 100644
--- a/fdts/rd1ae.dts
+++ b/fdts/rd1ae.dts
@@ -273,7 +273,7 @@
gic: interrupt-controller@30000000 {
compatible = "arm,gic-v3";
reg = <0x0 0x30000000 0 0x10000>, // GICD
- <0x0 0x301c0000 0 0x8000000>; // GICR
+ <0x0 0x301c0000 0 0x400000>; // GICR
#interrupt-cells = <3>;
#address-cells = <2>;
#size-cells = <2>;
@@ -425,7 +425,7 @@
method = "smc";
cpu_suspend = <0xc4000001>;
cpu_off = <0x84000002>;
- cpu_on = <0x84000003>;
+ cpu_on = <0xc4000003>;
};
};
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index d85221b..fe5f464 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -194,6 +194,7 @@
CLK_MPU_PLL1P
CLK_AXI_PLL2P
CLK_MCU_PLL3P
+ CLK_RTC_LSE
CLK_MCO1_DISABLED
CLK_MCO2_DISABLED
CLK_CKPER_HSE
@@ -242,6 +243,7 @@
DIV(DIV_APB3, 1)
DIV(DIV_APB4, 1)
DIV(DIV_APB5, 2)
+ DIV(DIV_RTC, 23)
DIV(DIV_MCO1, 0)
DIV(DIV_MCO2, 0)
>;
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index bac9e05..3115a00 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -198,6 +198,7 @@
CLK_MPU_PLL1P
CLK_AXI_PLL2P
CLK_MCU_PLL3P
+ CLK_RTC_LSE
CLK_MCO1_DISABLED
CLK_MCO2_DISABLED
CLK_CKPER_HSE
@@ -246,6 +247,7 @@
DIV(DIV_APB3, 1)
DIV(DIV_APB4, 1)
DIV(DIV_APB5, 2)
+ DIV(DIV_RTC, 23)
DIV(DIV_MCO1, 0)
DIV(DIV_MCO2, 0)
>;
diff --git a/fdts/stm32mp25-lpddr4-1x16Gbits-1x32bits-1200MHz.dtsi b/fdts/stm32mp25-lpddr4-1x16Gbits-1x32bits-1200MHz.dtsi
new file mode 100644
index 0000000..3917dc6
--- /dev/null
+++ b/fdts/stm32mp25-lpddr4-1x16Gbits-1x32bits-1200MHz.dtsi
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 LPDDR4 board configuration
+ * LPDDR4 1x16Gbits 1x32bits 1200MHz
+ *
+ * version 1
+ * memclk 1200MHz (2x DFI clock)
+ * width 32 32: full width / 16: half width
+ * ranks 1 Single or Dual rank
+ * density 8Gbits (per 16bit channel)
+ * Addressing RBC row/bank interleaving
+ * DBI-RD No Read DBI
+ * DBI-WR No Write DBI
+ * RPST 1.5 Read postamble (ck)
+ * Per_bank_ref Yes
+ */
+
+#define DDR_MEM_NAME "LPDDR4 1x16Gbits 1x32bits 1200MHz"
+#define DDR_MEM_SPEED 1200000
+#define DDR_MEM_SIZE 0x80000000
+
+#define DDR_MSTR 0x01080020
+#define DDR_MRCTRL0 0x00000030
+#define DDR_MRCTRL1 0x00000000
+#define DDR_MRCTRL2 0x00000000
+#define DDR_DERATEEN 0x00000203
+#define DDR_DERATEINT 0x0124F800
+#define DDR_DERATECTL 0x00000000
+#define DDR_PWRCTL 0x00000100
+#define DDR_PWRTMG 0x00130001
+#define DDR_HWLPCTL 0x00000002
+#define DDR_RFSHCTL0 0x00210014
+#define DDR_RFSHCTL1 0x00000000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x81240054
+#define DDR_RFSHTMG1 0x00360000
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_CRCPARCTL1 0x00001000
+#define DDR_INIT0 0xC0020002
+#define DDR_INIT1 0x00010002
+#define DDR_INIT2 0x00000D00
+#define DDR_INIT3 0x00C40024
+#define DDR_INIT4 0x00310008
+#define DDR_INIT5 0x00100004
+#define DDR_INIT6 0x00660050
+#define DDR_INIT7 0x00050019
+#define DDR_DIMMCTL 0x00000000
+#define DDR_RANKCTL 0x0000066F
+#define DDR_DRAMTMG0 0x1718141A
+#define DDR_DRAMTMG1 0x00050524
+#define DDR_DRAMTMG2 0x060C1111
+#define DDR_DRAMTMG3 0x0090900C
+#define DDR_DRAMTMG4 0x0B04060B
+#define DDR_DRAMTMG5 0x02030909
+#define DDR_DRAMTMG6 0x02020007
+#define DDR_DRAMTMG7 0x00000302
+#define DDR_DRAMTMG8 0x03034405
+#define DDR_DRAMTMG9 0x0004040D
+#define DDR_DRAMTMG10 0x001C180A
+#define DDR_DRAMTMG11 0x440C021C
+#define DDR_DRAMTMG12 0x1A020010
+#define DDR_DRAMTMG13 0x0B100002
+#define DDR_DRAMTMG14 0x000000AD
+#define DDR_DRAMTMG15 0x00000000
+#define DDR_ZQCTL0 0x02580012
+#define DDR_ZQCTL1 0x01E0493E
+#define DDR_ZQCTL2 0x00000000
+#define DDR_DFITMG0 0x0395820A
+#define DDR_DFITMG1 0x000A0303
+#define DDR_DFILPCFG0 0x07F04111
+#define DDR_DFILPCFG1 0x000000F0
+#define DDR_DFIUPD0 0x4040000C
+#define DDR_DFIUPD1 0x0040007F
+#define DDR_DFIUPD2 0x00000000
+#define DDR_DFIMISC 0x00000041
+#define DDR_DFITMG2 0x0000150A
+#define DDR_DFITMG3 0x00000000
+#define DDR_DBICTL 0x00000001
+#define DDR_DFIPHYMSTR 0x80000001
+#define DDR_ADDRMAP0 0x0000001F
+#define DDR_ADDRMAP1 0x00080808
+#define DDR_ADDRMAP2 0x00000000
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x070F0707
+#define DDR_ADDRMAP6 0x07070707
+#define DDR_ADDRMAP7 0x00000F0F
+#define DDR_ADDRMAP8 0x00003F3F
+#define DDR_ADDRMAP9 0x07070707
+#define DDR_ADDRMAP10 0x07070707
+#define DDR_ADDRMAP11 0x00000007
+#define DDR_ODTCFG 0x04000400
+#define DDR_ODTMAP 0x00000000
+#define DDR_SCHED 0x00001B00
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x04000200
+#define DDR_PERFLPR1 0x08000080
+#define DDR_PERFWR1 0x08000400
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_SWCTL 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000000
+#define DDR_PCFGR_0 0x00004100
+#define DDR_PCFGW_0 0x00004100
+#define DDR_PCTRL_0 0x00000000
+#define DDR_PCFGQOS0_0 0x0021000C
+#define DDR_PCFGQOS1_0 0x01000080
+#define DDR_PCFGWQOS0_0 0x01100C07
+#define DDR_PCFGWQOS1_0 0x04000200
+#define DDR_PCFGR_1 0x00004100
+#define DDR_PCFGW_1 0x00004100
+#define DDR_PCTRL_1 0x00000000
+#define DDR_PCFGQOS0_1 0x00100007
+#define DDR_PCFGQOS1_1 0x01000080
+#define DDR_PCFGWQOS0_1 0x01100C07
+#define DDR_PCFGWQOS1_1 0x04000200
+
+#define DDR_UIB_DRAMTYPE 0x00000002
+#define DDR_UIB_DIMMTYPE 0x00000004
+#define DDR_UIB_LP4XMODE 0x00000000
+#define DDR_UIB_NUMDBYTE 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI0 0x00000002
+#define DDR_UIB_NUMACTIVEDBYTEDFI1 0x00000002
+#define DDR_UIB_NUMANIB 0x00000008
+#define DDR_UIB_NUMRANK_DFI0 0x00000001
+#define DDR_UIB_NUMRANK_DFI1 0x00000001
+#define DDR_UIB_DRAMDATAWIDTH 0x00000010
+#define DDR_UIB_NUMPSTATES 0x00000001
+#define DDR_UIB_FREQUENCY_0 0x000004B0
+#define DDR_UIB_PLLBYPASS_0 0x00000000
+#define DDR_UIB_DFIFREQRATIO_0 0x00000001
+#define DDR_UIB_DFI1EXISTS 0x00000001
+#define DDR_UIB_TRAIN2D 0x00000000
+#define DDR_UIB_HARDMACROVER 0x00000003
+#define DDR_UIB_READDBIENABLE_0 0x00000000
+#define DDR_UIB_DFIMODE 0x00000000
+
+#define DDR_UIA_LP4RXPREAMBLEMODE_0 0x00000000
+#define DDR_UIA_LP4POSTAMBLEEXT_0 0x00000001
+#define DDR_UIA_D4RXPREAMBLELENGTH_0 0x00000001
+#define DDR_UIA_D4TXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_EXTCALRESVAL 0x00000000
+#define DDR_UIA_IS2TTIMING_0 0x00000000
+#define DDR_UIA_ODTIMPEDANCE_0 0x00000035
+#define DDR_UIA_TXIMPEDANCE_0 0x0000003C
+#define DDR_UIA_ATXIMPEDANCE 0x0000001E
+#define DDR_UIA_MEMALERTEN 0x00000000
+#define DDR_UIA_MEMALERTPUIMP 0x00000000
+#define DDR_UIA_MEMALERTVREFLEVEL 0x00000000
+#define DDR_UIA_MEMALERTSYNCBYPASS 0x00000000
+#define DDR_UIA_DISDYNADRTRI_0 0x00000001
+#define DDR_UIA_PHYMSTRTRAININTERVAL_0 0x0000000A
+#define DDR_UIA_PHYMSTRMAXREQTOACK_0 0x00000005
+#define DDR_UIA_WDQSEXT 0x00000000
+#define DDR_UIA_CALINTERVAL 0x00000009
+#define DDR_UIA_CALONCE 0x00000000
+#define DDR_UIA_LP4RL_0 0x00000004
+#define DDR_UIA_LP4WL_0 0x00000004
+#define DDR_UIA_LP4WLS_0 0x00000000
+#define DDR_UIA_LP4DBIRD_0 0x00000000
+#define DDR_UIA_LP4DBIWR_0 0x00000000
+#define DDR_UIA_LP4NWR_0 0x00000004
+#define DDR_UIA_LP4LOWPOWERDRV 0x00000000
+#define DDR_UIA_DRAMBYTESWAP 0x00000000
+#define DDR_UIA_RXENBACKOFF 0x00000000
+#define DDR_UIA_TRAINSEQUENCECTRL 0x00000000
+#define DDR_UIA_SNPSUMCTLOPT 0x00000000
+#define DDR_UIA_SNPSUMCTLF0RC5X_0 0x00000000
+#define DDR_UIA_TXSLEWRISEDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWFALLDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWRISEAC 0x0000000F
+#define DDR_UIA_TXSLEWFALLAC 0x0000000F
+#define DDR_UIA_DISABLERETRAINING 0x00000000
+#define DDR_UIA_DISABLEPHYUPDATE 0x00000001
+#define DDR_UIA_ENABLEHIGHCLKSKEWFIX 0x00000000
+#define DDR_UIA_DISABLEUNUSEDADDRLNS 0x00000001
+#define DDR_UIA_PHYINITSEQUENCENUM 0x00000000
+#define DDR_UIA_ENABLEDFICSPOLARITYFIX 0x00000000
+#define DDR_UIA_PHYVREF 0x00000014
+#define DDR_UIA_SEQUENCECTRL_0 0x0000131F
+
+#define DDR_UIM_MR0_0 0x00000000
+#define DDR_UIM_MR1_0 0x000000C4
+#define DDR_UIM_MR2_0 0x00000024
+#define DDR_UIM_MR3_0 0x00000031
+#define DDR_UIM_MR4_0 0x00000000
+#define DDR_UIM_MR5_0 0x00000000
+#define DDR_UIM_MR6_0 0x00000000
+#define DDR_UIM_MR11_0 0x00000066
+#define DDR_UIM_MR12_0 0x00000050
+#define DDR_UIM_MR13_0 0x00000008
+#define DDR_UIM_MR14_0 0x00000019
+#define DDR_UIM_MR22_0 0x00000005
+
+#define DDR_UIS_SWIZZLE_0 0x00000003
+#define DDR_UIS_SWIZZLE_1 0x00000002
+#define DDR_UIS_SWIZZLE_2 0x00000000
+#define DDR_UIS_SWIZZLE_3 0x00000001
+#define DDR_UIS_SWIZZLE_4 0x00000006
+#define DDR_UIS_SWIZZLE_5 0x00000007
+#define DDR_UIS_SWIZZLE_6 0x00000005
+#define DDR_UIS_SWIZZLE_7 0x00000004
+#define DDR_UIS_SWIZZLE_8 0x00000005
+#define DDR_UIS_SWIZZLE_9 0x00000004
+#define DDR_UIS_SWIZZLE_10 0x00000007
+#define DDR_UIS_SWIZZLE_11 0x00000006
+#define DDR_UIS_SWIZZLE_12 0x00000000
+#define DDR_UIS_SWIZZLE_13 0x00000003
+#define DDR_UIS_SWIZZLE_14 0x00000002
+#define DDR_UIS_SWIZZLE_15 0x00000001
+#define DDR_UIS_SWIZZLE_16 0x00000005
+#define DDR_UIS_SWIZZLE_17 0x00000007
+#define DDR_UIS_SWIZZLE_18 0x00000006
+#define DDR_UIS_SWIZZLE_19 0x00000004
+#define DDR_UIS_SWIZZLE_20 0x00000000
+#define DDR_UIS_SWIZZLE_21 0x00000001
+#define DDR_UIS_SWIZZLE_22 0x00000003
+#define DDR_UIS_SWIZZLE_23 0x00000002
+#define DDR_UIS_SWIZZLE_24 0x00000007
+#define DDR_UIS_SWIZZLE_25 0x00000004
+#define DDR_UIS_SWIZZLE_26 0x00000005
+#define DDR_UIS_SWIZZLE_27 0x00000006
+#define DDR_UIS_SWIZZLE_28 0x00000002
+#define DDR_UIS_SWIZZLE_29 0x00000003
+#define DDR_UIS_SWIZZLE_30 0x00000001
+#define DDR_UIS_SWIZZLE_31 0x00000000
+#define DDR_UIS_SWIZZLE_32 0x00000000
+#define DDR_UIS_SWIZZLE_33 0x00000001
+#define DDR_UIS_SWIZZLE_34 0x00000002
+#define DDR_UIS_SWIZZLE_35 0x00000003
+#define DDR_UIS_SWIZZLE_36 0x00000004
+#define DDR_UIS_SWIZZLE_37 0x00000005
+#define DDR_UIS_SWIZZLE_38 0x00000000
+#define DDR_UIS_SWIZZLE_39 0x00000001
+#define DDR_UIS_SWIZZLE_40 0x00000002
+#define DDR_UIS_SWIZZLE_41 0x00000003
+#define DDR_UIS_SWIZZLE_42 0x00000004
+#define DDR_UIS_SWIZZLE_43 0x00000005
+
+#include "stm32mp25-ddr.dtsi"
diff --git a/fdts/stm32mp25-lpddr4-1x32Gbits-1x32bits-1200MHz.dtsi b/fdts/stm32mp25-lpddr4-1x32Gbits-1x32bits-1200MHz.dtsi
new file mode 100644
index 0000000..53d6b7d
--- /dev/null
+++ b/fdts/stm32mp25-lpddr4-1x32Gbits-1x32bits-1200MHz.dtsi
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 LPDDR4 board configuration
+ * LPDDR4 1x32Gbits 1x32bits 1200MHz
+ *
+ * version 2
+ * memclk 1200MHz (2x DFI clock)
+ * width 32 32: full width / 16: half width
+ * ranks 1 Single or Dual rank
+ * density 16Gbits (per 16bit channel)
+ * Addressing RBC row/bank interleaving
+ * DBI-RD No Read DBI
+ * DBI-WR No Write DBI
+ * RPST 1.5 Read postamble (ck)
+ * Per_bank_ref Yes
+ */
+
+#define DDR_MEM_NAME "LPDDR4 1x32Gbits 1x32bits 1200MHz"
+#define DDR_MEM_SPEED 1200000
+#define DDR_MEM_SIZE 0x100000000
+
+#define DDR_MSTR 0x01080020
+#define DDR_MRCTRL0 0x00000030
+#define DDR_MRCTRL1 0x00000000
+#define DDR_MRCTRL2 0x00000000
+#define DDR_DERATEEN 0x00000203
+#define DDR_DERATEINT 0x0124F800
+#define DDR_DERATECTL 0x00000000
+#define DDR_PWRCTL 0x00000100
+#define DDR_PWRTMG 0x00130001
+#define DDR_HWLPCTL 0x00000002
+#define DDR_RFSHCTL0 0x00210014
+#define DDR_RFSHCTL1 0x00000000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x81240072
+#define DDR_RFSHTMG1 0x00360000
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_CRCPARCTL1 0x00001000
+#define DDR_INIT0 0xC0020002
+#define DDR_INIT1 0x00010002
+#define DDR_INIT2 0x00000D00
+#define DDR_INIT3 0x00C40024
+#define DDR_INIT4 0x00310008
+#define DDR_INIT5 0x00100004
+#define DDR_INIT6 0x00660047
+#define DDR_INIT7 0x00050047
+#define DDR_DIMMCTL 0x00000000
+#define DDR_RANKCTL 0x0000066F
+#define DDR_RANKCTL1 0x00000011
+#define DDR_DRAMTMG0 0x1718141A
+#define DDR_DRAMTMG1 0x00050524
+#define DDR_DRAMTMG2 0x060C1111
+#define DDR_DRAMTMG3 0x0090900C
+#define DDR_DRAMTMG4 0x0B04060B
+#define DDR_DRAMTMG5 0x02030909
+#define DDR_DRAMTMG6 0x02020007
+#define DDR_DRAMTMG7 0x00000302
+#define DDR_DRAMTMG8 0x03034405
+#define DDR_DRAMTMG9 0x0004040D
+#define DDR_DRAMTMG10 0x001C180A
+#define DDR_DRAMTMG11 0x440C021C
+#define DDR_DRAMTMG12 0x1A020010
+#define DDR_DRAMTMG13 0x0B100002
+#define DDR_DRAMTMG14 0x000000E9
+#define DDR_DRAMTMG15 0x00000000
+#define DDR_ZQCTL0 0x02580012
+#define DDR_ZQCTL1 0x01E0493E
+#define DDR_ZQCTL2 0x00000000
+#define DDR_DFITMG0 0x0395820A
+#define DDR_DFITMG1 0x000A0303
+#define DDR_DFILPCFG0 0x07F04111
+#define DDR_DFILPCFG1 0x000000F0
+#define DDR_DFIUPD0 0x4040000C
+#define DDR_DFIUPD1 0x0040007F
+#define DDR_DFIUPD2 0x00000000
+#define DDR_DFIMISC 0x00000041
+#define DDR_DFITMG2 0x0000150A
+#define DDR_DFITMG3 0x00000000
+#define DDR_DBICTL 0x00000001
+#define DDR_DFIPHYMSTR 0x80000001
+#define DDR_ADDRMAP0 0x0000001F
+#define DDR_ADDRMAP1 0x00080808
+#define DDR_ADDRMAP2 0x00000000
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x070F0707
+#define DDR_ADDRMAP6 0x07070707
+#define DDR_ADDRMAP7 0x00000F07
+#define DDR_ADDRMAP8 0x00003F3F
+#define DDR_ADDRMAP9 0x07070707
+#define DDR_ADDRMAP10 0x07070707
+#define DDR_ADDRMAP11 0x00000007
+#define DDR_ODTCFG 0x04000400
+#define DDR_ODTMAP 0x00000000
+#define DDR_SCHED 0x80001B00
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x04000200
+#define DDR_PERFLPR1 0x08000080
+#define DDR_PERFWR1 0x08000400
+#define DDR_SCHED3 0x04040208
+#define DDR_SCHED4 0x08400810
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_SWCTL 0x00000000
+#define DDR_SWCTLSTATIC 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000000
+#define DDR_PCFGR_0 0x00704100
+#define DDR_PCFGW_0 0x00004100
+#define DDR_PCTRL_0 0x00000000
+#define DDR_PCFGQOS0_0 0x0021000C
+#define DDR_PCFGQOS1_0 0x01000080
+#define DDR_PCFGWQOS0_0 0x01100C07
+#define DDR_PCFGWQOS1_0 0x04000200
+#define DDR_PCFGR_1 0x00704100
+#define DDR_PCFGW_1 0x00004100
+#define DDR_PCTRL_1 0x00000000
+#define DDR_PCFGQOS0_1 0x00100007
+#define DDR_PCFGQOS1_1 0x01000080
+#define DDR_PCFGWQOS0_1 0x01100C07
+#define DDR_PCFGWQOS1_1 0x04000200
+
+#define DDR_UIB_DRAMTYPE 0x00000002
+#define DDR_UIB_DIMMTYPE 0x00000004
+#define DDR_UIB_LP4XMODE 0x00000000
+#define DDR_UIB_NUMDBYTE 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI0 0x00000002
+#define DDR_UIB_NUMACTIVEDBYTEDFI1 0x00000002
+#define DDR_UIB_NUMANIB 0x00000008
+#define DDR_UIB_NUMRANK_DFI0 0x00000001
+#define DDR_UIB_NUMRANK_DFI1 0x00000001
+#define DDR_UIB_DRAMDATAWIDTH 0x00000010
+#define DDR_UIB_NUMPSTATES 0x00000001
+#define DDR_UIB_FREQUENCY_0 0x000004B0
+#define DDR_UIB_PLLBYPASS_0 0x00000000
+#define DDR_UIB_DFIFREQRATIO_0 0x00000001
+#define DDR_UIB_DFI1EXISTS 0x00000001
+#define DDR_UIB_TRAIN2D 0x00000000
+#define DDR_UIB_HARDMACROVER 0x00000003
+#define DDR_UIB_READDBIENABLE_0 0x00000000
+#define DDR_UIB_DFIMODE 0x00000000
+
+#define DDR_UIA_LP4RXPREAMBLEMODE_0 0x00000000
+#define DDR_UIA_LP4POSTAMBLEEXT_0 0x00000001
+#define DDR_UIA_D4RXPREAMBLELENGTH_0 0x00000001
+#define DDR_UIA_D4TXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_EXTCALRESVAL 0x00000000
+#define DDR_UIA_IS2TTIMING_0 0x00000000
+#define DDR_UIA_ODTIMPEDANCE_0 0x00000035
+#define DDR_UIA_TXIMPEDANCE_0 0x00000028
+#define DDR_UIA_ATXIMPEDANCE 0x00000028
+#define DDR_UIA_MEMALERTEN 0x00000000
+#define DDR_UIA_MEMALERTPUIMP 0x00000000
+#define DDR_UIA_MEMALERTVREFLEVEL 0x00000000
+#define DDR_UIA_MEMALERTSYNCBYPASS 0x00000000
+#define DDR_UIA_DISDYNADRTRI_0 0x00000001
+#define DDR_UIA_PHYMSTRTRAININTERVAL_0 0x0000000A
+#define DDR_UIA_PHYMSTRMAXREQTOACK_0 0x00000005
+#define DDR_UIA_WDQSEXT 0x00000000
+#define DDR_UIA_CALINTERVAL 0x00000009
+#define DDR_UIA_CALONCE 0x00000000
+#define DDR_UIA_LP4RL_0 0x00000004
+#define DDR_UIA_LP4WL_0 0x00000004
+#define DDR_UIA_LP4WLS_0 0x00000000
+#define DDR_UIA_LP4DBIRD_0 0x00000000
+#define DDR_UIA_LP4DBIWR_0 0x00000000
+#define DDR_UIA_LP4NWR_0 0x00000004
+#define DDR_UIA_LP4LOWPOWERDRV 0x00000000
+#define DDR_UIA_DRAMBYTESWAP 0x00000000
+#define DDR_UIA_RXENBACKOFF 0x00000000
+#define DDR_UIA_TRAINSEQUENCECTRL 0x00000000
+#define DDR_UIA_SNPSUMCTLOPT 0x00000000
+#define DDR_UIA_SNPSUMCTLF0RC5X_0 0x00000000
+#define DDR_UIA_TXSLEWRISEDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWFALLDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWRISEAC 0x0000000F
+#define DDR_UIA_TXSLEWFALLAC 0x0000000F
+#define DDR_UIA_DISABLERETRAINING 0x00000000
+#define DDR_UIA_DISABLEPHYUPDATE 0x00000001
+#define DDR_UIA_ENABLEHIGHCLKSKEWFIX 0x00000000
+#define DDR_UIA_DISABLEUNUSEDADDRLNS 0x00000001
+#define DDR_UIA_PHYINITSEQUENCENUM 0x00000000
+#define DDR_UIA_ENABLEDFICSPOLARITYFIX 0x00000000
+#define DDR_UIA_PHYVREF 0x00000014
+#define DDR_UIA_SEQUENCECTRL_0 0x0000131F
+
+#define DDR_UIM_MR0_0 0x00000000
+#define DDR_UIM_MR1_0 0x000000C4
+#define DDR_UIM_MR2_0 0x00000024
+#define DDR_UIM_MR3_0 0x00000031
+#define DDR_UIM_MR4_0 0x00000000
+#define DDR_UIM_MR5_0 0x00000000
+#define DDR_UIM_MR6_0 0x00000000
+#define DDR_UIM_MR11_0 0x00000066
+#define DDR_UIM_MR12_0 0x00000047
+#define DDR_UIM_MR13_0 0x00000008
+#define DDR_UIM_MR14_0 0x00000047
+#define DDR_UIM_MR22_0 0x00000005
+
+#define DDR_UIS_SWIZZLE_0 0x00000003
+#define DDR_UIS_SWIZZLE_1 0x00000002
+#define DDR_UIS_SWIZZLE_2 0x00000000
+#define DDR_UIS_SWIZZLE_3 0x00000001
+#define DDR_UIS_SWIZZLE_4 0x00000006
+#define DDR_UIS_SWIZZLE_5 0x00000007
+#define DDR_UIS_SWIZZLE_6 0x00000005
+#define DDR_UIS_SWIZZLE_7 0x00000004
+#define DDR_UIS_SWIZZLE_8 0x00000005
+#define DDR_UIS_SWIZZLE_9 0x00000004
+#define DDR_UIS_SWIZZLE_10 0x00000007
+#define DDR_UIS_SWIZZLE_11 0x00000006
+#define DDR_UIS_SWIZZLE_12 0x00000000
+#define DDR_UIS_SWIZZLE_13 0x00000003
+#define DDR_UIS_SWIZZLE_14 0x00000002
+#define DDR_UIS_SWIZZLE_15 0x00000001
+#define DDR_UIS_SWIZZLE_16 0x00000005
+#define DDR_UIS_SWIZZLE_17 0x00000007
+#define DDR_UIS_SWIZZLE_18 0x00000006
+#define DDR_UIS_SWIZZLE_19 0x00000004
+#define DDR_UIS_SWIZZLE_20 0x00000000
+#define DDR_UIS_SWIZZLE_21 0x00000001
+#define DDR_UIS_SWIZZLE_22 0x00000003
+#define DDR_UIS_SWIZZLE_23 0x00000002
+#define DDR_UIS_SWIZZLE_24 0x00000007
+#define DDR_UIS_SWIZZLE_25 0x00000004
+#define DDR_UIS_SWIZZLE_26 0x00000005
+#define DDR_UIS_SWIZZLE_27 0x00000006
+#define DDR_UIS_SWIZZLE_28 0x00000002
+#define DDR_UIS_SWIZZLE_29 0x00000003
+#define DDR_UIS_SWIZZLE_30 0x00000001
+#define DDR_UIS_SWIZZLE_31 0x00000000
+#define DDR_UIS_SWIZZLE_32 0x00000000
+#define DDR_UIS_SWIZZLE_33 0x00000001
+#define DDR_UIS_SWIZZLE_34 0x00000002
+#define DDR_UIS_SWIZZLE_35 0x00000003
+#define DDR_UIS_SWIZZLE_36 0x00000004
+#define DDR_UIS_SWIZZLE_37 0x00000005
+#define DDR_UIS_SWIZZLE_38 0x00000000
+#define DDR_UIS_SWIZZLE_39 0x00000001
+#define DDR_UIS_SWIZZLE_40 0x00000002
+#define DDR_UIS_SWIZZLE_41 0x00000003
+#define DDR_UIS_SWIZZLE_42 0x00000004
+#define DDR_UIS_SWIZZLE_43 0x00000005
+
+#include "stm32mp25-ddr.dtsi"
diff --git a/fdts/stm32mp25-pinctrl.dtsi b/fdts/stm32mp25-pinctrl.dtsi
index a22c823..b2ca962 100644
--- a/fdts/stm32mp25-pinctrl.dtsi
+++ b/fdts/stm32mp25-pinctrl.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
/*
- * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2025, STMicroelectronics - All Rights Reserved
* Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
*/
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
@@ -38,6 +38,26 @@
};
/omit-if-no-ref/
+ sdmmc1_b4_pins_b: sdmmc1-b4-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
+ <STM32_PINMUX('E', 5, AF10)>, /* SDMMC1_D1 */
+ <STM32_PINMUX('E', 0, AF10)>, /* SDMMC1_D2 */
+ <STM32_PINMUX('E', 1, AF10)>, /* SDMMC1_D3 */
+ <STM32_PINMUX('E', 2, AF10)>; /* SDMMC1_CMD */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-disable;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('E', 3, AF10)>; /* SDMMC1_CK */
+ slew-rate = <2>;
+ drive-push-pull;
+ bias-disable;
+ };
+ };
+
+ /omit-if-no-ref/
sdmmc2_b4_pins_a: sdmmc2-b4-0 {
pins1 {
pinmux = <STM32_PINMUX('E', 13, AF12)>, /* SDMMC2_D0 */
@@ -45,13 +65,13 @@
<STM32_PINMUX('E', 8, AF12)>, /* SDMMC2_D2 */
<STM32_PINMUX('E', 12, AF12)>, /* SDMMC2_D3 */
<STM32_PINMUX('E', 15, AF12)>; /* SDMMC2_CMD */
- slew-rate = <2>;
+ slew-rate = <1>;
drive-push-pull;
bias-pull-up;
};
pins2 {
pinmux = <STM32_PINMUX('E', 14, AF12)>; /* SDMMC2_CK */
- slew-rate = <3>;
+ slew-rate = <2>;
drive-push-pull;
bias-pull-up;
};
@@ -64,7 +84,7 @@
<STM32_PINMUX('E', 9, AF12)>, /* SDMMC2_D5 */
<STM32_PINMUX('E', 6, AF12)>, /* SDMMC2_D6 */
<STM32_PINMUX('E', 7, AF12)>; /* SDMMC2_D7 */
- slew-rate = <2>;
+ slew-rate = <1>;
drive-push-pull;
bias-pull-up;
};
diff --git a/fdts/stm32mp257f-dk-ca35tdcid-fw-config.dtsi b/fdts/stm32mp257f-dk-ca35tdcid-fw-config.dtsi
new file mode 100644
index 0000000..9637e1a
--- /dev/null
+++ b/fdts/stm32mp257f-dk-ca35tdcid-fw-config.dtsi
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2025 - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 tf-a firmware config
+ * Project : open
+ * Generated by XLmx tool version 2.2 - 3/6/2024 11:20:07 AM
+ */
+
+/ {
+ dtb-registry {
+ soc_fw-config {
+ load-address = <0x0 0x81fc0000>;
+ max-size = <0x40000>;
+ };
+ tos_fw {
+ load-address = <0x0 0x82000000>;
+ max-size = <0x2000000>;
+ };
+ };
+};
diff --git a/fdts/stm32mp257f-dk-ca35tdcid-rcc.dtsi b/fdts/stm32mp257f-dk-ca35tdcid-rcc.dtsi
new file mode 100644
index 0000000..dd38a52
--- /dev/null
+++ b/fdts/stm32mp257f-dk-ca35tdcid-rcc.dtsi
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2025 - All Rights Reserved
+ * Author: Loic Pallardy loic.pallardy@foss.st.com for STMicroelectronics.
+ */
+
+/*
+ * STM32MP25 Clock tree device tree configuration
+ * Project : open
+ * Generated by XLmx tool version 2.2 - 3/6/2024 11:20:07 AM
+ */
+
+&clk_hse {
+ clock-frequency = <40000000>;
+};
+
+&clk_hsi {
+ clock-frequency = <64000000>;
+};
+
+&clk_lse {
+ clock-frequency = <32768>;
+};
+
+&clk_lsi {
+ clock-frequency = <32000>;
+};
+
+&clk_msi {
+ clock-frequency = <16000000>;
+};
+
+&rcc {
+ st,busclk = <
+ DIV_CFG(DIV_LSMCU, 1)
+ DIV_CFG(DIV_APB1, 0)
+ DIV_CFG(DIV_APB2, 0)
+ DIV_CFG(DIV_APB3, 0)
+ DIV_CFG(DIV_APB4, 0)
+ DIV_CFG(DIV_APBDBG, 0)
+ >;
+
+ st,flexgen = <
+ FLEXGEN_CFG(0, XBAR_SRC_PLL4, 0, 2)
+ FLEXGEN_CFG(1, XBAR_SRC_PLL4, 0, 5)
+ FLEXGEN_CFG(2, XBAR_SRC_PLL4, 0, 1)
+ FLEXGEN_CFG(4, XBAR_SRC_PLL4, 0, 3)
+ FLEXGEN_CFG(5, XBAR_SRC_PLL4, 0, 2)
+ FLEXGEN_CFG(8, XBAR_SRC_HSI_KER, 0, 0)
+ FLEXGEN_CFG(48, XBAR_SRC_PLL5, 0, 3)
+ FLEXGEN_CFG(51, XBAR_SRC_PLL4, 0, 5)
+ FLEXGEN_CFG(52, XBAR_SRC_PLL4, 0, 5)
+ FLEXGEN_CFG(58, XBAR_SRC_HSE_KER, 0, 1)
+ FLEXGEN_CFG(63, XBAR_SRC_PLL4, 0, 2)
+ >;
+
+ st,kerclk = <
+ MUX_CFG(MUX_USB2PHY1, MUX_USB2PHY1_FLEX57)
+ MUX_CFG(MUX_USB2PHY2, MUX_USB2PHY2_FLEX58)
+ >;
+
+ pll1: st,pll-1 {
+ st,pll = <&pll1_cfg_1200Mhz>;
+
+ pll1_cfg_1200Mhz: pll1-cfg-1200Mhz {
+ cfg = <30 1 1 1>;
+ src = <MUX_CFG(MUX_MUXSEL5, MUXSEL_HSE)>;
+ };
+ };
+
+ pll2: st,pll-2 {
+ st,pll = <&pll2_cfg_600Mhz>;
+
+ pll2_cfg_600Mhz: pll2-cfg-600Mhz {
+ cfg = <30 1 1 2>;
+ src = <MUX_CFG(MUX_MUXSEL6, MUXSEL_HSE)>;
+ };
+ };
+
+ pll4: st,pll-4 {
+ st,pll = <&pll4_cfg_1200Mhz>;
+
+ pll4_cfg_1200Mhz: pll4-cfg-1200Mhz {
+ cfg = <30 1 1 1>;
+ src = <MUX_CFG(MUX_MUXSEL0, MUXSEL_HSE)>;
+ };
+ };
+
+ pll5: st,pll-5 {
+ st,pll = <&pll5_cfg_532Mhz>;
+
+ pll5_cfg_532Mhz: pll5-cfg-532Mhz {
+ cfg = <133 5 1 2>;
+ src = <MUX_CFG(MUX_MUXSEL1, MUXSEL_HSE)>;
+ };
+ };
+};
diff --git a/fdts/stm32mp257f-dk-fw-config.dts b/fdts/stm32mp257f-dk-fw-config.dts
new file mode 100644
index 0000000..67f8e30
--- /dev/null
+++ b/fdts/stm32mp257f-dk-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+#include "stm32mp25-fw-config.dtsi"
+#include "stm32mp257f-dk-ca35tdcid-fw-config.dtsi"
diff --git a/fdts/stm32mp257f-dk.dts b/fdts/stm32mp257f-dk.dts
new file mode 100644
index 0000000..ae18d6a
--- /dev/null
+++ b/fdts/stm32mp257f-dk.dts
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2025 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/clock/stm32mp25-clksrc.h>
+#include "stm32mp257.dtsi"
+#include "stm32mp25xf.dtsi"
+#include "stm32mp257f-dk-ca35tdcid-rcc.dtsi"
+#include "stm32mp25-lpddr4-1x32Gbits-1x32bits-1200MHz.dtsi"
+#include "stm32mp25-pinctrl.dtsi"
+#include "stm32mp25xxal-pinctrl.dtsi"
+
+/ {
+ model = "STMicroelectronics STM32MP257F-DK Discovery Board";
+ compatible = "st,stm32mp257f-dk", "st,stm32mp257";
+
+ aliases {
+ serial0 = &usart2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x1 0x00000000>;
+ };
+
+ shadow-prov {
+ compatible = "st,provisioning";
+
+ hconf1_prov {
+ nvmem-cells = <&hconf1_otp>;
+ st,shadow-value = <0x00018000>;
+ };
+ };
+};
+
+&bsec {
+ board_id: board-id@3d8 {
+ reg = <0x3d8 0x4>;
+ };
+};
+
+&ddr {
+ vdd1-supply = <&vdd1_ddr>;
+ vdd2-supply = <&vdd2_ddr>;
+ vddq-supply = <&vdd2_ddr>;
+};
+
+&i2c7 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c7_pins_a>;
+ i2c-scl-rising-time-ns = <185>;
+ i2c-scl-falling-time-ns = <20>;
+ clock-frequency = <400000>;
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic2: stpmic@33 {
+ compatible = "st,stpmic2";
+ reg = <0x33>;
+ status = "okay";
+
+ regulators {
+ compatible = "st,stpmic2-regulators";
+
+ vddcpu: buck1 {
+ regulator-name = "vddcpu";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <910000>;
+ regulator-always-on;
+ };
+ vddcore: buck2 {
+ regulator-name = "vddcore";
+ regulator-min-microvolt = <820000>;
+ regulator-max-microvolt = <820000>;
+ regulator-always-on;
+ };
+ vddgpu: buck3 {
+ regulator-name = "vddgpu";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <900000>;
+ regulator-always-on;
+ };
+ vddio_pmic: buck4 {
+ regulator-name = "vddio_pmic";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ v1v8: buck5 {
+ regulator-name = "v1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ vdd2_ddr: buck6 {
+ regulator-name = "vdd2_ddr";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+ v3v3: buck7 {
+ regulator-name = "v3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ vdda1v8_aon: ldo1 {
+ regulator-name = "vdda1v8_aon";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ vdd_emmc: ldo2 {
+ regulator-name = "vdd_emmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ vdd1_ddr: ldo3 {
+ regulator-name = "vdd1_ddr";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <1000>;
+ };
+ vdd3v3_usb: ldo4 {
+ regulator-name = "vdd3v3_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ v5v_hdmi: ldo5 {
+ regulator-name = "v5v_hdmi";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ };
+ vdd_sdcard: ldo7 {
+ regulator-name = "vdd_sdcard";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ vddio_sdcard: ldo8 {
+ regulator-name = "vddio_sdcard";
+ st,regulator-bypass-microvolt = <3300000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&pwr {
+ vddio1: vddio1 {
+ vddio1-supply = <&vddio_sdcard>;
+ };
+ vddio2: vddio2 {
+ vddio2-supply = <&v1v8>;
+ };
+ vddio3: vddio3 {
+ vddio3-supply = <&vddio_pmic>;
+ };
+ vddio4: vddio4 {
+ vddio4-supply = <&vddio_pmic>;
+ };
+ vddio: vddio {
+ vdd-supply = <&vddio_pmic>;
+ };
+};
+
+&sdmmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_b4_pins_b>;
+ st,neg-edge;
+ bus-width = <4>;
+ vmmc-supply = <&vdd_sdcard>;
+ vqmmc-supply = <&vddio1>;
+ status = "okay";
+};
+
+&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 = <&vdd_emmc>;
+ vqmmc-supply = <&vddio2>;
+ status = "okay";
+};
+
+&usart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usart2_pins_a>;
+ status = "okay";
+};
diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi
index 735d429..691a3b8 100644
--- a/fdts/tc-base.dtsi
+++ b/fdts/tc-base.dtsi
@@ -387,7 +387,7 @@
soc_uartclk: uartclk {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <UARTCLK_FREQ>;
+ clock-frequency = <TC_UARTCLK>;
clock-output-names = "uartclk";
};
@@ -405,34 +405,50 @@
dpu_aclk: dpu_aclk {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <VENCODER_TIMING_CLK>;
+ clock-frequency = <LCD_TIMING_CLK>;
clock-output-names = "fpga:dpu_aclk";
};
dpu_pixel_clk: dpu-pixel-clk {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <VENCODER_TIMING_CLK>;
+ clock-frequency = <LCD_TIMING_CLK>;
clock-output-names = "pxclk";
};
#endif /* !TC_DPU_USE_SCMI_CLK */
+#if TC_DPU_USE_SIMPLE_PANEL
+ vpanel {
+ compatible = "panel-dpi";
+ post-init-providers = <&pl0>;
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dp_pl0_out0>;
+ };
+ };
+
+ panel-timing {
+ LCD_TIMING;
+ };
+ };
+
+#else
vencoder {
compatible = "drm,virtual-encoder";
port {
- vencoder_in: endpoint {
+ lcd_in: endpoint {
remote-endpoint = <&dp_pl0_out0>;
};
};
display-timings {
timing-panel {
- VENCODER_TIMING;
+ LCD_TIMING;
};
};
};
-
+#endif
ethernet: ethernet@ETHERNET_ADDR {
reg = <0x0 ADDRESSIFY(ETHERNET_ADDR) 0x0 0x10000>;
interrupts = <GIC_SPI ETHERNET_INT IRQ_TYPE_LEVEL_HIGH 0>;
@@ -575,7 +591,7 @@
port@0 {
reg = <0>;
dp_pl0_out0: endpoint {
- remote-endpoint = <&vencoder_in>;
+ remote-endpoint = <&lcd_in>;
};
};
};
diff --git a/fdts/tc-fpga.dtsi b/fdts/tc-fpga.dtsi
index 08b9ae5..a3feacc 100644
--- a/fdts/tc-fpga.dtsi
+++ b/fdts/tc-fpga.dtsi
@@ -8,9 +8,9 @@
#define GIC_GICR_OFFSET 0x1000000
#define UART_OFFSET 0x10000
/* 1440x3200@120 framebuffer */
-#define VENCODER_TIMING_CLK 836000000
-#define VENCODER_TIMING \
- clock-frequency = <VENCODER_TIMING_CLK>; \
+#define LCD_TIMING_CLK 836000000
+#define LCD_TIMING \
+ clock-frequency = <LCD_TIMING_CLK>; \
hactive = <1440>; \
vactive = <3200>; \
hfront-porch = <136>; \
@@ -25,6 +25,19 @@
stdout-path = "serial0:38400n8";
};
+#if TC_FPGA_FS_IMG_IN_RAM
+ reserved-memory {
+ phram@0x880000000 {
+ /*
+ * starting from 0x8_8000_0000 reserve some memory
+ * android image will be side loaded to this location
+ */
+ reg = <0x8 0x80000000 HI(ANDROID_FS_SIZE) LO(ANDROID_FS_SIZE)>
+ no-map;
+ };
+ };
+#endif /* TC_FPGA_FS_IMG_IN_RAM */
+
ethernet: ethernet@ETHERNET_ADDR {
compatible = "smsc,lan9115";
phy-mode = "mii";
diff --git a/fdts/tc-fvp.dtsi b/fdts/tc-fvp.dtsi
index f57e21d..960730c 100644
--- a/fdts/tc-fvp.dtsi
+++ b/fdts/tc-fvp.dtsi
@@ -10,9 +10,9 @@
#ifdef TC_RESOLUTION_1920X1080P60
-#define VENCODER_TIMING_CLK 148500000
-#define VENCODER_TIMING \
- clock-frequency = <VENCODER_TIMING_CLK>; \
+#define LCD_TIMING_CLK 148500000
+#define LCD_TIMING \
+ clock-frequency = <LCD_TIMING_CLK>; \
hactive = <1920>; \
vactive = <1080>; \
hfront-porch = <88>; \
@@ -24,9 +24,9 @@
#else /* TC_RESOLUTION_640X480P60 */
-#define VENCODER_TIMING_CLK 25175000
-#define VENCODER_TIMING \
- clock-frequency = <VENCODER_TIMING_CLK>; \
+#define LCD_TIMING_CLK 25175000
+#define LCD_TIMING \
+ clock-frequency = <LCD_TIMING_CLK>; \
hactive = <640>; \
vactive = <480>; \
hfront-porch = <16>; \
diff --git a/fdts/tc2.dts b/fdts/tc2.dts
index c492274..003efdc 100644
--- a/fdts/tc2.dts
+++ b/fdts/tc2.dts
@@ -36,7 +36,6 @@
#define BIG_CPU_PMU_COMPATIBLE "arm,cortex-x4-pmu"
#define MPAM_ADDR 0x1 0x00010000 /* 0x1_0001_0000 */
-#define UARTCLK_FREQ 5000000
#define DPU_ADDR 2cc00000
#define DPU_IRQ 69
diff --git a/fdts/tc3-4-base.dtsi b/fdts/tc3-4-base.dtsi
index 2de5fd3..049a4c6 100644
--- a/fdts/tc3-4-base.dtsi
+++ b/fdts/tc3-4-base.dtsi
@@ -18,15 +18,12 @@
#define MHU_RX_INT_NAME "combined"
#define MPAM_ADDR 0x0 0x5f010000 /* 0x5f01_0000 */
-#define UARTCLK_FREQ 3750000
#if TARGET_FLAVOUR_FVP
#define DPU_ADDR 4000000000
#define DPU_IRQ 579
-#elif TARGET_FLAVOUR_FPGA
-#define DPU_ADDR 2cc00000
-#define DPU_IRQ 69
#endif
+
#include "tc-base.dtsi"
/ {
@@ -52,6 +49,31 @@
};
};
+ rse_mbox_db_rx: mhu@RSE_MHU_RX_ADDR {
+ compatible = MHU_RX_COMPAT;
+ reg = <0x0 ADDRESSIFY(RSE_MHU_RX_ADDR) 0x0 MHU_OFFSET>;
+ clocks = <&soc_refclk>;
+ clock-names = "apb_pclk";
+ #mbox-cells = <MHU_MBOX_CELLS>;
+ interrupts = <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = MHU_RX_INT_NAME;
+#if TARGET_FLAVOUR_FPGA
+ status = "disabled";
+#endif
+ };
+
+ rse_mbox_db_tx: mhu@RSE_MHU_TX_ADDR {
+ compatible = MHU_TX_COMPAT;
+ reg = <0x0 ADDRESSIFY(RSE_MHU_TX_ADDR) 0x0 MHU_OFFSET>;
+ clocks = <&soc_refclk>;
+ clock-names = "apb_pclk";
+ #mbox-cells = <MHU_MBOX_CELLS>;
+ interrupt-names = MHU_TX_INT_NAME;
+#if TARGET_FLAVOUR_FPGA
+ status = "disabled";
+#endif
+ };
+
gic: interrupt-controller@GIC_CTRL_ADDR {
ppi-partitions {
ppi_partition_little: interrupt-partition-0 {
@@ -80,5 +102,39 @@
mboxes = <&mbox_db_tx 0 0 0 &mbox_db_rx 0 0 0 &mbox_db_rx 0 0 1>;
shmem = <&cpu_scp_scmi_a2p &cpu_scp_scmi_p2a>;
};
+
+ rse {
+ compatible = "arm,rse";
+ mbox-names = "tx", "rx";
+ mboxes = <&rse_mbox_db_tx 0 0 0>, <&rse_mbox_db_rx 0 0 0>;
+#if TARGET_FLAVOUR_FPGA
+ status = "disabled";
+#endif
+ };
+ };
+
+ dsu-pmu {
+ compatible = "arm,dsu-pmu";
+ cpus = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
+ };
+
+ cs-pmu@0 {
+ compatible = "arm,coresight-pmu";
+ reg = <0x0 MCN_PMU_ADDR(0) 0x0 0xffc>;
+ };
+
+ cs-pmu@1 {
+ compatible = "arm,coresight-pmu";
+ reg = <0x0 MCN_PMU_ADDR(1) 0x0 0xffc>;
+ };
+
+ cs-pmu@2 {
+ compatible = "arm,coresight-pmu";
+ reg = <0x0 MCN_PMU_ADDR(2) 0x0 0xffc>;
+ };
+
+ cs-pmu@3 {
+ compatible = "arm,coresight-pmu";
+ reg = <0x0 MCN_PMU_ADDR(3) 0x0 0xffc>;
};
};
diff --git a/fdts/tc3.dts b/fdts/tc3.dts
index ffe3b6d..22d4d10 100644
--- a/fdts/tc3.dts
+++ b/fdts/tc3.dts
@@ -13,6 +13,9 @@
#define MHU_TX_ADDR 46040000 /* hex */
#define MHU_RX_ADDR 46140000 /* hex */
+#define RSE_MHU_TX_ADDR 49010000 /* hex */
+#define RSE_MHU_RX_ADDR 49110000 /* hex */
+
#define LIT_CPU_PMU_COMPATIBLE "arm,cortex-a520-pmu"
#define MID_CPU_PMU_COMPATIBLE "arm,cortex-a725-pmu"
#define BIG_CPU_PMU_COMPATIBLE "arm,cortex-x925-pmu"
@@ -37,6 +40,11 @@
#define VIRTIO_BLOCK_ADDR 1c130000
#define VIRTIO_BLOCK_INT 204
+#if TARGET_FLAVOUR_FPGA
+#define DPU_ADDR 2cc00000
+#define DPU_IRQ 69
+#endif
+
#include "tc-common.dtsi"
#if TARGET_FLAVOUR_FVP
#include "tc-fvp.dtsi"
@@ -46,24 +54,13 @@
#include "tc3-4-base.dtsi"
/ {
- cs-pmu@0 {
- compatible = "arm,coresight-pmu";
- reg = <0x0 MCN_PMU_ADDR(0) 0x0 0xffc>;
- };
-
- cs-pmu@1 {
- compatible = "arm,coresight-pmu";
- reg = <0x0 MCN_PMU_ADDR(1) 0x0 0xffc>;
- };
-
- cs-pmu@2 {
- compatible = "arm,coresight-pmu";
- reg = <0x0 MCN_PMU_ADDR(2) 0x0 0xffc>;
- };
-
- cs-pmu@3 {
- compatible = "arm,coresight-pmu";
- reg = <0x0 MCN_PMU_ADDR(3) 0x0 0xffc>;
+ /*
+ * The kaslr-seed node is a placeholder in DT. In the booting
+ * sequence, it will be initialized in U-Boot and then later
+ * used by Linux kernel.
+ */
+ chosen {
+ kaslr-seed = <0x0 0x0>;
};
spe-pmu-mid {
@@ -74,11 +71,6 @@
status = "okay";
};
- dsu-pmu {
- compatible = "arm,dsu-pmu";
- cpus = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
- };
-
ni-pmu {
compatible = "arm,ni-tower";
reg = <0x0 0x4f000000 0x0 0x4000000>;
diff --git a/fdts/tc4.dts b/fdts/tc4.dts
index 135d30a..98cfea1 100644
--- a/fdts/tc4.dts
+++ b/fdts/tc4.dts
@@ -17,14 +17,24 @@
#define MID_CPU_PMU_COMPATIBLE "arm,armv8-pmuv3"
#define BIG_CPU_PMU_COMPATIBLE "arm,armv8-pmuv3"
+#define RSE_MHU_TX_ADDR 49020000 /* hex */
+#define RSE_MHU_RX_ADDR 49030000 /* hex */
+
+#if TARGET_FLAVOUR_FVP
#define ETHERNET_ADDR 64000000
#define ETHERNET_INT 799
-
#define SYS_REGS_ADDR 60080000
-
#define MMC_ADDR 600b0000
#define MMC_INT_0 778
#define MMC_INT_1 779
+#else /* TARGET_FLAVOUR_FPGA */
+#define ETHERNET_ADDR 18000000
+#define ETHERNET_INT 109
+#define SYS_REGS_ADDR 1c010000
+#define MMC_ADDR 1c050000
+#define MMC_INT_0 107
+#define MMC_INT_1 108
+#endif /* TARGET_FLAVOUR_FVP */
#define RTC_ADDR 600a0000
#define RTC_INT 777
@@ -37,6 +47,11 @@
#define VIRTIO_BLOCK_ADDR 60020000
#define VIRTIO_BLOCK_INT 769
+#if TARGET_FLAVOUR_FPGA
+#define DPU_ADDR 4000000000
+#define DPU_IRQ 579
+#endif
+
#include "tc-common.dtsi"
#if TARGET_FLAVOUR_FVP
#include "tc-fvp.dtsi"
@@ -62,6 +77,31 @@
gpu: gpu@2d000000 {
interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "IRQAW";
- iommus = <&smmu_700 0x200>;
+ iommus = <&smmu_700 0x0>;
+ system-coherency = <0x0>;
+ };
+
+ dsu-pmu {
+ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH 0>;
+ };
+
+ cs-pmu@4 {
+ compatible = "arm,coresight-pmu";
+ reg = <0x0 MCN_PMU_ADDR(4) 0x0 0xffc>;
+ };
+
+ cs-pmu@5 {
+ compatible = "arm,coresight-pmu";
+ reg = <0x0 MCN_PMU_ADDR(5) 0x0 0xffc>;
+ };
+
+ cs-pmu@6 {
+ compatible = "arm,coresight-pmu";
+ reg = <0x0 MCN_PMU_ADDR(6) 0x0 0xffc>;
+ };
+
+ cs-pmu@7 {
+ compatible = "arm,coresight-pmu";
+ reg = <0x0 MCN_PMU_ADDR(7) 0x0 0xffc>;
};
};
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 737d07a..4d26153 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -317,6 +317,10 @@
/* ID_AA64ISAR2_EL1 definitions */
#define ID_AA64ISAR2_EL1 S3_0_C0_C6_2
+#define ID_AA64ISAR2_EL1_MOPS_SHIFT U(16)
+#define ID_AA64ISAR2_EL1_MOPS_MASK ULL(0xf)
+
+#define MOPS_IMPLEMENTED ULL(0x1)
/* ID_AA64PFR2_EL1 definitions */
#define ID_AA64PFR2_EL1 S3_0_C0_C4_2
@@ -465,6 +469,11 @@
#define ID_AA64PFR2_EL1_MTEFAR_SHIFT U(8)
#define ID_AA64PFR2_EL1_MTEFAR_MASK ULL(0xf)
+#define ID_AA64PFR2_EL1_FPMR_SHIFT U(32)
+#define ID_AA64PFR2_EL1_FPMR_MASK ULL(0xf)
+
+#define FPMR_IMPLEMENTED ULL(0x1)
+
#define VDISR_EL2 S3_4_C12_C1_1
#define VSESR_EL2 S3_4_C5_C2_3
@@ -605,6 +614,7 @@
#define SCR_NSE_SHIFT U(62)
#define SCR_FGTEN2_BIT (UL(1) << 59)
#define SCR_NSE_BIT (ULL(1) << SCR_NSE_SHIFT)
+#define SCR_EnFPM_BIT (ULL(1) << 50)
#define SCR_GPF_BIT (UL(1) << 48)
#define SCR_D128En_BIT (UL(1) << 47)
#define SCR_TWEDEL_SHIFT U(30)
@@ -648,15 +658,18 @@
/* MDCR_EL3 definitions */
#define MDCR_EBWE_BIT (ULL(1) << 43)
-#define MDCR_E3BREC (ULL(1) << 38)
-#define MDCR_E3BREW (ULL(1) << 37)
+#define MDCR_E3BREC_BIT (ULL(1) << 38)
+#define MDCR_E3BREW_BIT (ULL(1) << 37)
#define MDCR_EnPMSN_BIT (ULL(1) << 36)
#define MDCR_MPMX_BIT (ULL(1) << 35)
#define MDCR_MCCD_BIT (ULL(1) << 34)
#define MDCR_SBRBE_SHIFT U(32)
-#define MDCR_SBRBE_MASK ULL(0x3)
+#define MDCR_SBRBE(x) ((x) << MDCR_SBRBE_SHIFT)
+#define MDCR_SBRBE_ALL ULL(0x3)
+#define MDCR_SBRBE_NS ULL(0x1)
#define MDCR_NSTB(x) ((x) << 24)
#define MDCR_NSTB_EL1 ULL(0x3)
+#define MDCR_NSTB_EL3 ULL(0x2)
#define MDCR_NSTBE_BIT (ULL(1) << 26)
#define MDCR_MTPME_BIT (ULL(1) << 28)
#define MDCR_TDCC_BIT (ULL(1) << 27)
@@ -673,6 +686,7 @@
#define MDCR_SPD32_ENABLE ULL(0x3)
#define MDCR_NSPB(x) ((x) << 12)
#define MDCR_NSPB_EL1 ULL(0x3)
+#define MDCR_NSPB_EL3 ULL(0x2)
#define MDCR_NSPBE_BIT (ULL(1) << 11)
#define MDCR_TDOSA_BIT (ULL(1) << 10)
#define MDCR_TDA_BIT (ULL(1) << 9)
@@ -1522,6 +1536,11 @@
******************************************************************************/
#define CLUSTERPWRDN_EL1 S3_0_c15_c3_6
+/*******************************************************************************
+ * FEAT_FPMR - Floating point Mode Register
+ ******************************************************************************/
+#define FPMR S3_3_C4_C4_2
+
/* CLUSTERPWRDN_EL1 register definitions */
#define DSU_CLUSTER_PWR_OFF 0
#define DSU_CLUSTER_PWR_ON 1
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 59188da..1d0a2e0 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -142,6 +142,10 @@
* +----------------------------+
* | FEAT_LS64_ACCDATA |
* +----------------------------+
+ * | FEAT_FPMR |
+ * +----------------------------+
+ * | FEAT_MOPS |
+ * +----------------------------+
*/
__attribute__((always_inline))
@@ -284,6 +288,15 @@
ID_AA64MMFR3_EL1_D128_MASK, D128_IMPLEMENTED,
ENABLE_FEAT_D128)
+/* FEAT_FPMR */
+CREATE_FEATURE_FUNCS(feat_fpmr, id_aa64pfr2_el1, ID_AA64PFR2_EL1_FPMR_SHIFT,
+ ID_AA64PFR2_EL1_FPMR_MASK, FPMR_IMPLEMENTED,
+ ENABLE_FEAT_FPMR)
+/* FEAT_MOPS */
+CREATE_FEATURE_FUNCS(feat_mops, id_aa64isar2_el1, ID_AA64ISAR2_EL1_MOPS_SHIFT,
+ ID_AA64ISAR2_EL1_MOPS_MASK, MOPS_IMPLEMENTED,
+ ENABLE_FEAT_MOPS)
+
__attribute__((always_inline))
static inline bool is_feat_sxpie_supported(void)
{
@@ -345,8 +358,8 @@
ID_AA64MMFR1_EL1_HCX_MASK, 1U, ENABLE_FEAT_HCX)
/* FEAT_RNG_TRAP: Trapping support */
-CREATE_FEATURE_PRESENT(feat_rng_trap, id_aa64pfr1_el1, ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT,
- ID_AA64PFR1_EL1_RNDR_TRAP_MASK, RNG_TRAP_IMPLEMENTED)
+CREATE_FEATURE_FUNCS(feat_rng_trap, id_aa64pfr1_el1, ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT,
+ ID_AA64PFR1_EL1_RNDR_TRAP_MASK, RNG_TRAP_IMPLEMENTED, ENABLE_FEAT_RNG_TRAP)
/* Return the RME version, zero if not supported. */
CREATE_FEATURE_FUNCS(feat_rme, id_aa64pfr0_el1, ID_AA64PFR0_FEAT_RME_SHIFT,
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 119c428..8b92f19 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -295,6 +295,7 @@
DEFINE_SYSREG_RW_FUNCS(dbgdtrtx_el0)
DEFINE_SYSREG_RW_FUNCS(sp_el1)
DEFINE_SYSREG_RW_FUNCS(sp_el2)
+DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1)
DEFINE_SYSOP_FUNC(wfi)
DEFINE_SYSOP_FUNC(wfe)
@@ -718,6 +719,8 @@
DEFINE_RENAME_SYSREG_RW_FUNCS(gptbr_el3, GPTBR_EL3)
DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3)
+DEFINE_RENAME_SYSREG_RW_FUNCS(fpmr, FPMR)
+
#define IS_IN_EL(x) \
(GET_EL(read_CurrentEl()) == MODE_EL##x)
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index ec2acd5..197ea06 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -225,13 +225,6 @@
.endm
/*
- * With RAS extension executes esb instruction, else NOP
- */
- .macro esb
- .inst 0xd503221f
- .endm
-
- /*
* Helper macro to read system register value into x0
*/
.macro read reg:req
@@ -265,6 +258,14 @@
msr SYSREG_SB, xzr
.endm
+ .macro psb_csync
+ hint #17 /* use the hint synonym for compatibility */
+ .endm
+
+ .macro tsb_csync
+ hint #18 /* use the hint synonym for compatibility */
+ .endm
+
/*
* Macro for using speculation barrier instruction introduced by
* FEAT_SB, if it's enabled.
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 647ae85..2f065ec 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -168,6 +168,15 @@
} meminfo_t;
/*******************************************************************************
+ * Structure used for conveying the location and size of the heap allocated for
+ * use by the cryptography library.
+ * *****************************************************************************/
+struct crypto_heap_info {
+ void *addr;
+ size_t size;
+};
+
+/*******************************************************************************
* Function & variable prototypes
******************************************************************************/
int load_auth_image(unsigned int image_id, image_info_t *image_data);
diff --git a/include/drivers/auth/mbedtls/mbedtls_config-3.h b/include/drivers/auth/mbedtls/default_mbedtls_config.h
similarity index 89%
rename from include/drivers/auth/mbedtls/mbedtls_config-3.h
rename to include/drivers/auth/mbedtls/default_mbedtls_config.h
index 6ed9397..23daf24 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config-3.h
+++ b/include/drivers/auth/mbedtls/default_mbedtls_config.h
@@ -11,6 +11,11 @@
*/
/*
+ * This file is compatible with versions >= 3.6.2
+ */
+#define MBEDTLS_CONFIG_VERSION 0x03060200
+
+/*
* Key algorithms currently supported on mbed TLS libraries
*/
#define TF_MBEDTLS_RSA 1
@@ -127,18 +132,15 @@
#endif
/*
- * Determine Mbed TLS heap size
- * 13312 = 13*1024
- * 11264 = 11*1024
- * 7168 = 7*1024
+ * Determine Mbed TLS heap size.
*/
#if TF_MBEDTLS_USE_ECDSA
-#define TF_MBEDTLS_HEAP_SIZE U(13312)
+#define TF_MBEDTLS_HEAP_SIZE U(13 * 1024)
#elif TF_MBEDTLS_USE_RSA
#if TF_MBEDTLS_KEY_SIZE <= 2048
-#define TF_MBEDTLS_HEAP_SIZE U(7168)
+#define TF_MBEDTLS_HEAP_SIZE U(7 * 1024)
#else
-#define TF_MBEDTLS_HEAP_SIZE U(11264)
+#define TF_MBEDTLS_HEAP_SIZE U(11 * 1024)
#endif
#endif
@@ -150,3 +152,9 @@
* the warnings to more functions.
*/
#define MBEDTLS_CHECK_RETURN_WARNING
+
+/*
+ * Use an implementation of SHA-256 with a smaller memory footprint but reduced
+ * speed.
+ */
+#define MBEDTLS_SHA256_SMALLER
diff --git a/include/drivers/auth/mbedtls/psa_mbedtls_config.h b/include/drivers/auth/mbedtls/default_psa_mbedtls_config.h
similarity index 78%
rename from include/drivers/auth/mbedtls/psa_mbedtls_config.h
rename to include/drivers/auth/mbedtls/default_psa_mbedtls_config.h
index 1001d89..00b1f34 100644
--- a/include/drivers/auth/mbedtls/psa_mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/default_psa_mbedtls_config.h
@@ -7,7 +7,7 @@
#ifndef PSA_MBEDTLS_CONFIG_H
#define PSA_MBEDTLS_CONFIG_H
-#include "mbedtls_config-3.h"
+#include "default_mbedtls_config.h"
#define MBEDTLS_PSA_CRYPTO_C
#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
@@ -26,4 +26,12 @@
*/
#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+/*
+ * Override heap size for PSA Crypto when RSA key size > 2048.
+ */
+#if TF_MBEDTLS_USE_RSA && TF_MBEDTLS_KEY_SIZE > 2048
+#undef TF_MBEDTLS_HEAP_SIZE
+#define TF_MBEDTLS_HEAP_SIZE U(12 * 1024)
+#endif
+
#endif /* PSA_MBEDTLS_CONFIG_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
index d879f5b..632b82f 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
@@ -6,6 +6,7 @@
#ifndef S32CC_CLK_DRV_H
#define S32CC_CLK_DRV_H
+int s32cc_init_core_clocks(void);
int s32cc_init_early_clks(void);
#endif
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
index e6adecc..c6e90f0 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
@@ -5,6 +5,7 @@
#ifndef S32CC_CLK_UTILS_H
#define S32CC_CLK_UTILS_H
+#include <stdbool.h>
#include <s32cc-clk-modules.h>
struct s32cc_clk *s32cc_get_clk_from_table(const struct s32cc_clk_array *const *clk_arr,
@@ -18,6 +19,6 @@
struct s32cc_clk *s32cc_get_arch_clk(unsigned long id);
int s32cc_get_clk_id(const struct s32cc_clk *clk, unsigned long *id);
-void s32cc_clk_register_drv(void);
+int s32cc_clk_register_drv(bool mmap_regs);
#endif /* S32CC_CLK_UTILS_H */
diff --git a/include/lib/cpus/aarch64/cortex_alto.h b/include/lib/cpus/aarch64/cortex_alto.h
new file mode 100644
index 0000000..1c8786a
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_alto.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_ALTO_H
+#define CORTEX_ALTO_H
+
+#define CORTEX_ALTO_MIDR U(0x411FD900)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_ALTO_IMP_CPUECTLR_EL1 S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_ALTO_IMP_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CORTEX_ALTO_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT U(1)
+
+/*******************************************************************************
+ * SME Control registers
+ ******************************************************************************/
+#define CORTEX_ALTO_SVCRSM S0_3_C4_C2_3
+#define CORTEX_ALTO_SVCRZA S0_3_C4_C4_3
+
+#endif /* CORTEX_ALTO_H */
diff --git a/include/lib/el3_runtime/context_el1.h b/include/lib/el3_runtime/context_el1.h
index 7bc0235..7fe43c7 100644
--- a/include/lib/el3_runtime/context_el1.h
+++ b/include/lib/el3_runtime/context_el1.h
@@ -194,6 +194,9 @@
#define write_el1_ctx_common(ctx, reg, val) ((((ctx)->common).reg) \
= (uint64_t) (val))
+#define write_el1_ctx_common_sysreg128(ctx, reg, val) ((((ctx)->common).reg) \
+ = (sysreg_t) (val))
+
#if NS_TIMER_SWITCH
#define read_el1_ctx_arch_timer(ctx, reg) (((ctx)->arch_timer).reg)
#define write_el1_ctx_arch_timer(ctx, reg, val) ((((ctx)->arch_timer).reg) \
@@ -295,11 +298,11 @@
#if ENABLE_FEAT_THE
#define read_el1_ctx_the(ctx, reg) (((ctx)->the).reg)
-#define write_el1_ctx_the(ctx, reg, val) ((((ctx)->the).reg) \
- = (uint64_t) (val))
+#define write_el1_ctx_the_sysreg128(ctx, reg, val) ((((ctx)->the).reg) \
+ = (sysreg_t) (val))
#else
#define read_el1_ctx_the(ctx, reg) ULL(0)
-#define write_el1_ctx_the(ctx, reg, val)
+#define write_el1_ctx_the_sysreg128(ctx, reg, val)
#endif /* ENABLE_FEAT_THE */
#if ENABLE_FEAT_SCTLR2
diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h
index 7374e39..f35a091 100644
--- a/include/lib/el3_runtime/context_el2.h
+++ b/include/lib/el3_runtime/context_el2.h
@@ -225,7 +225,7 @@
#define write_el2_ctx_common(ctx, reg, val) ((((ctx)->common).reg) \
= (uint64_t) (val))
-#define write_el2_ctx_sysreg128(ctx, reg, val) ((((ctx)->common).reg) \
+#define write_el2_ctx_common_sysreg128(ctx, reg, val) ((((ctx)->common).reg) \
= (sysreg_t) (val))
#if ENABLE_FEAT_MTE2
@@ -268,12 +268,12 @@
#define read_el2_ctx_vhe(ctx, reg) (((ctx)->vhe).reg)
#define write_el2_ctx_vhe(ctx, reg, val) ((((ctx)->vhe).reg) \
= (uint64_t) (val))
-
#define write_el2_ctx_vhe_sysreg128(ctx, reg, val) ((((ctx)->vhe).reg) \
- = (sysreg_t) (val))
+ = (sysreg_t) (val))
#else
#define read_el2_ctx_vhe(ctx, reg) ULL(0)
#define write_el2_ctx_vhe(ctx, reg, val)
+#define write_el2_ctx_vhe_sysreg128(ctx, reg, val)
#endif /* ENABLE_FEAT_VHE */
#if ENABLE_FEAT_RAS
diff --git a/include/lib/el3_runtime/pubsub.h b/include/lib/el3_runtime/pubsub.h
index cbd8ecc..4419f15 100644
--- a/include/lib/el3_runtime/pubsub.h
+++ b/include/lib/el3_runtime/pubsub.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -73,7 +73,7 @@
*/
#define SUBSCRIBE_TO_EVENT(event, func) \
extern pubsub_cb_t __cb_func_##func##event __pubsub_section(event); \
- pubsub_cb_t __cb_func_##func##event __pubsub_section(event) = (func)
+ pubsub_cb_t __cb_func_##func##event __used __pubsub_section(event) = (func)
/*
* Iterate over subscribed handlers for a defined event. 'event' is the name of
diff --git a/include/lib/extensions/fpmr.h b/include/lib/extensions/fpmr.h
new file mode 100644
index 0000000..bc3ee9e
--- /dev/null
+++ b/include/lib/extensions/fpmr.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FPMR_H
+#define FPMR_H
+
+#include <context.h>
+
+#if ENABLE_FEAT_FPMR
+void fpmr_enable_per_world(per_world_context_t *per_world_ctx);
+#else
+static inline void fpmr_enable_per_world(per_world_context_t *per_world_ctx)
+{
+}
+#endif /* ENABLE_FEAT_FPMR */
+
+#endif /* FPMR_H */
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
index 4801a22..0a41e1e 100644
--- a/include/lib/extensions/spe.h
+++ b/include/lib/extensions/spe.h
@@ -14,7 +14,6 @@
void spe_enable(cpu_context_t *ctx);
void spe_disable(cpu_context_t *ctx);
void spe_init_el2_unused(void);
-void spe_stop(void);
#else
static inline void spe_enable(cpu_context_t *ctx)
{
@@ -25,9 +24,6 @@
static inline void spe_init_el2_unused(void)
{
}
-static inline void spe_stop(void)
-{
-}
#endif /* ENABLE_SPE_FOR_NS */
#endif /* SPE_H */
diff --git a/include/lib/hob/efi_types.h b/include/lib/hob/efi_types.h
new file mode 100644
index 0000000..071d012
--- /dev/null
+++ b/include/lib/hob/efi_types.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EFI_TYPES_H
+#define EFI_TYPES_H
+
+#include <stdint.h>
+#include <tools_share/uuid.h>
+
+typedef uint64_t efi_physical_address_t;
+
+/*****************************************************************************
+ * EFI_BOOT_MODE *
+ *****************************************************************************/
+
+typedef uint32_t efi_boot_mode_t;
+/**
+ * EFI boot mode.
+ */
+#define EFI_BOOT_WITH_FULL_CONFIGURATION U(0x00)
+#define EFI_BOOT_WITH_MINIMAL_CONFIGURATION U(0x01)
+#define EFI_BOOT_ASSUMING_NO_CONFIGURATION_CHANGES U(0x02)
+#define EFI_BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS U(0x03)
+#define EFI_BOOT_WITH_DEFAULT_SETTINGS U(0x04)
+#define EFI_BOOT_ON_S4_RESUME U(0x05)
+#define EFI_BOOT_ON_S5_RESUME U(0x06)
+#define EFI_BOOT_WITH_MFG_MODE_SETTINGS U(0x07)
+#define EFI_BOOT_ON_S2_RESUME U(0x10)
+#define EFI_BOOT_ON_S3_RESUME U(0x11)
+#define EFI_BOOT_ON_FLASH_UPDATE U(0x12)
+#define EFI_BOOT_IN_RECOVERY_MODE U(0x20)
+
+/*****************************************************************************
+ * EFI_RESOURCE_TYPE *
+ *****************************************************************************/
+
+typedef uint32_t efi_resource_type_t;
+
+/**
+ * Value of EFI_RESOURCE_TYPE used in EFI_HOB_RESOURCE_DESCRIPTOR.
+ */
+#define EFI_RESOURCE_SYSTEM_MEMORY U(0x00000000)
+#define EFI_RESOURCE_MEMORY_MAPPED_IO U(0x00000001)
+#define EFI_RESOURCE_IO U(0x00000002)
+#define EFI_RESOURCE_FIRMWARE_DEVICE U(0x00000003)
+#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT U(0x00000004)
+#define EFI_RESOURCE_MEMORY_RESERVED U(0x00000005)
+#define EFI_RESOURCE_IO_RESERVED U(0x00000006)
+
+/*****************************************************************************
+ * EFI_RESOURCE_ATTRIBUTE_TYPE *
+ *****************************************************************************/
+
+typedef uint32_t efi_resource_attribute_type_t;
+
+#define EFI_RESOURCE_ATTRIBUTE_PRESENT U(0x00000001)
+#define EFI_RESOURCE_ATTRIBUTE_INITIALIZED U(0x00000002)
+#define EFI_RESOURCE_ATTRIBUTE_TESTED U(0x00000004)
+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED U(0x00000080)
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED U(0x00000100)
+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED U(0x00000200)
+#define EFI_RESOURCE_ATTRIBUTE_PERSISTENT U(0x00800000)
+#define EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC U(0x00000008)
+#define EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC U(0x00000010)
+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 U(0x00000020)
+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 U(0x00000040)
+#define EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE U(0x00000400)
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE U(0x00000800)
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE U(0x00001000)
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE U(0x00002000)
+#define EFI_RESOURCE_ATTRIBUTE_16_BIT_IO U(0x00004000)
+#define EFI_RESOURCE_ATTRIBUTE_32_BIT_IO U(0x00008000)
+#define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO U(0x00010000)
+#define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED U(0x00020000)
+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE U(0x00100000)
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE U(0x00200000)
+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE U(0x00400000)
+#define EFI_RESOURCE_ATTRIBUTE_PERSISTABLE U(0x01000000)
+#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED U(0x00040000)
+#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE U(0x00080000)
+#define EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE U(0x02000000)
+
+#endif /* EFI_TYPES_H */
diff --git a/include/lib/hob/hob.h b/include/lib/hob/hob.h
new file mode 100644
index 0000000..120f5da
--- /dev/null
+++ b/include/lib/hob/hob.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef HOB_H
+#define HOB_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <lib/hob/efi_types.h>
+#include <lib/utils_def.h>
+#include <tools_share/uuid.h>
+
+/*****************************************************************************
+ * Hob Generic Header *
+ *****************************************************************************/
+
+/**
+ * HobType values of EFI_HOB_GENERIC_HEADER.
+ */
+#define EFI_HOB_TYPE_HANDOFF U(0x0001)
+#define EFI_HOB_TYPE_MEMORY_ALLOCATION U(0x0002)
+#define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR U(0x0003)
+#define EFI_HOB_TYPE_GUID_EXTENSION U(0x0004)
+#define EFI_HOB_TYPE_FV U(0x0005)
+#define EFI_HOB_TYPE_CPU U(0x0006)
+#define EFI_HOB_TYPE_MEMORY_POOL U(0x0007)
+#define EFI_HOB_TYPE_FV2 U(0x0009)
+#define EFI_HOB_TYPE_LOAD_PEIM_UNUSED U(0x000A)
+#define EFI_HOB_TYPE_UEFI_CAPSULE U(0x000B)
+#define EFI_HOB_TYPE_FV3 U(0x000C)
+#define EFI_HOB_TYPE_UNUSED U(0xFFFE)
+#define EFI_HOB_TYPE_END_OF_HOB_LIST U(0xFFFF)
+
+struct efi_hob_generic_header {
+ uint16_t hob_type;
+ uint16_t hob_length;
+ uint32_t reserved;
+};
+
+/*****************************************************************************
+ * PHIT Hob. *
+ *****************************************************************************/
+
+#define EFI_HOB_HANDOFF_TABLE_VERSION U(0x000a)
+
+struct efi_hob_handoff_info_table {
+ struct efi_hob_generic_header header;
+ uint32_t version;
+ efi_boot_mode_t boot_mode;
+ efi_physical_address_t efi_memory_top;
+ efi_physical_address_t efi_memory_bottom;
+ efi_physical_address_t efi_free_memory_top;
+ efi_physical_address_t efi_free_memory_bottom;
+ efi_physical_address_t efi_end_of_hob_list;
+};
+
+/*****************************************************************************
+ * Resource Descriptor Hob. *
+ *****************************************************************************/
+
+struct efi_hob_resource_descriptor {
+ struct efi_hob_generic_header header;
+ struct efi_guid owner;
+ efi_resource_type_t resource_type;
+ efi_resource_attribute_type_t resource_attribute;
+ efi_physical_address_t physical_start;
+ uint64_t resource_length;
+};
+
+/*****************************************************************************
+ * Guid Extension Hob. *
+ *****************************************************************************/
+struct efi_hob_guid_type {
+ struct efi_hob_generic_header header;
+ struct efi_guid name;
+ /**
+ * Guid specific data goes here.
+ */
+};
+
+/*****************************************************************************
+ * Firmware Volume Hob. *
+ *****************************************************************************/
+struct efi_hob_firmware_volume {
+ struct efi_hob_generic_header header;
+ efi_physical_address_t base_address;
+ uint64_t length;
+ /**
+ * Guid specific data goes here.
+ */
+};
+
+/*****************************************************************************
+ * Interfaces. *
+ *****************************************************************************/
+
+struct efi_hob_handoff_info_table *
+create_hob_list(
+ efi_physical_address_t efi_memory_begin, size_t efi_memory_length,
+ efi_physical_address_t efi_free_memory_bottom, size_t efi_free_memory_length);
+
+int create_resource_descriptor_hob(
+ struct efi_hob_handoff_info_table *hob_table,
+ efi_resource_type_t resource_type,
+ efi_resource_attribute_type_t resource_attribute,
+ efi_physical_address_t phy_addr_start,
+ uint64_t resource_length);
+
+int create_guid_hob(struct efi_hob_handoff_info_table *hob_table,
+ struct efi_guid *guid, uint16_t data_length, void **data);
+
+int create_fv_hob(struct efi_hob_handoff_info_table *hob_table,
+ efi_physical_address_t base_addr, uint64_t size);
+
+#endif /* HOB_H */
diff --git a/include/lib/hob/hob_guid.h b/include/lib/hob/hob_guid.h
new file mode 100644
index 0000000..65d3dbf
--- /dev/null
+++ b/include/lib/hob/hob_guid.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef HOB_GUID_H
+#define HOB_GUID_H
+
+#include <lib/hob/efi_types.h>
+
+/**
+ * Guid used for creating StandaloneMm related information.
+ */
+
+#define MM_PEI_MMRAM_MEMORY_RESERVE_GUID \
+{ \
+ 0x0703f912, 0xbf8d, 0x4e2a, {0xbe, 0x07, 0xab, 0x27, 0x25, 0x25, 0xc5, 0x92 } \
+}
+
+#define MM_NS_BUFFER_GUID \
+{ \
+ 0xf00497e3, 0xbfa2, 0x41a1, {0x9d, 0x29, 0x54, 0xc2, 0xe9, 0x37, 0x21, 0xc5 } \
+}
+
+#define MM_MP_INFORMATION_GUID \
+{ \
+ 0xba33f15d, 0x4000, 0x45c1, {0x8e, 0x88, 0xf9, 0x16, 0x92, 0xd4, 0x57, 0xe3} \
+}
+
+#endif /* HOB_GUID_H */
diff --git a/include/lib/hob/mmram.h b/include/lib/hob/mmram.h
new file mode 100644
index 0000000..b269c64
--- /dev/null
+++ b/include/lib/hob/mmram.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef MMRAM_H
+#define MMRAM_H
+
+#include <lib/hob/efi_types.h>
+
+/**
+ * MMRAM states and capabilities
+ * See UEFI Platform Initialization Specification Version 1.8, IV-5.3.5
+ */
+#define EFI_MMRAM_OPEN U(0x00000001)
+#define EFI_MMRAM_CLOSED U(0x00000002)
+#define EFI_MMRAM_LOCKED U(0x00000004)
+#define EFI_CACHEABLE U(0x00000008)
+#define EFI_ALLOCATED U(0x00000010)
+#define EFI_NEEDS_TESTING U(0x00000020)
+#define EFI_NEEDS_ECC_INITIALIZATION U(0x00000040)
+
+#define EFI_SMRAM_OPEN EFI_MMRAM_OPEN
+#define EFI_SMRAM_CLOSED EFI_MMRAM_CLOSED
+#define EFI_SMRAM_LOCKED EFI_MMRAM_LOCKED
+
+struct efi_mmram_descriptor {
+ efi_physical_address_t physical_start;
+ efi_physical_address_t cpu_start;
+ uint64_t physical_size;
+ uint64_t region_state;
+};
+
+/**
+ * MMRAM block descriptor
+ * This definition comes from
+ * https://github.com/tianocore/edk2/blob/master/StandaloneMmPkg/Include/Guid/MmramMemoryReserve.h
+ */
+struct efi_mmram_hob_descriptor_block {
+ uint32_t number_of_mm_reserved_regions;
+ struct efi_mmram_descriptor descriptor[];
+};
+
+#endif /* MMRAM_H */
diff --git a/include/lib/hob/mpinfo.h b/include/lib/hob/mpinfo.h
new file mode 100644
index 0000000..b80d8f1
--- /dev/null
+++ b/include/lib/hob/mpinfo.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#ifndef MPINFO_H
+#define MPINFO_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <lib/utils_def.h>
+
+/*
+ * Value used in the NumberProcessors parameter of the GetProcessorInfo function
+ */
+#define CPU_V2_EXTENDED_TOPOLOGY UL(1 << 24)
+
+/*
+ * This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+ * indicates whether the processor is playing the role of BSP. If the bit is 1,
+ * then the processor is BSP. Otherwise, it is AP.
+ */
+#define PROCESSOR_AS_BSP_BIT UL(1 << 0)
+
+/*
+ * This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+ * indicates whether the processor is enabled. If the bit is 1, then the
+ * processor is enabled. Otherwise, it is disabled.
+ */
+#define PROCESSOR_ENABLED_BIT UL(1 << 1)
+
+/*
+ * This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+ * indicates whether the processor is healthy. If the bit is 1, then the
+ * processor is healthy. Otherwise, some fault has been detected for the processor.
+ */
+#define PROCESSOR_HEALTH_STATUS_BIT UL(1 << 2)
+
+/*
+ * Structure that describes the physical location of a logical CPU.
+ */
+struct efi_cpu_physical_location {
+ uint32_t package;
+ uint32_t core;
+ uint32_t thread;
+};
+
+/*
+ * Structure that defines the 6-level physical location of the processor
+ */
+struct efi_cpu_physical_location2 {
+ uint32_t package;
+ uint32_t module;
+ uint32_t tile;
+ uint32_t die;
+ uint32_t core;
+ uint32_t thread;
+};
+
+union extended_processor_information {
+ /*
+ * The 6-level physical location of the processor, including the
+ * physical package number that identifies the cartridge, the physical
+ * module number within package, the physical tile number within the module,
+ * the physical die number within the tile, the physical core number within
+ * package, and logical thread number within core.
+ */
+ struct efi_cpu_physical_location2 location2;
+};
+
+/*
+ * Structure that describes information about a logical CPU.
+ */
+struct efi_processor_information {
+ /*
+ * The unique processor ID determined by system hardware.
+ */
+ uint64_t processor_id;
+
+ /*
+ * Flags indicating if the processor is BSP or AP, if the processor is enabled
+ * or disabled, and if the processor is healthy. Bits 3..31 are reserved and
+ * must be 0.
+ *
+ * <pre>
+ * BSP ENABLED HEALTH Description
+ * === ======= ====== ===================================================
+ * 0 0 0 Unhealthy Disabled AP.
+ * 0 0 1 Healthy Disabled AP.
+ * 0 1 0 Unhealthy Enabled AP.
+ * 0 1 1 Healthy Enabled AP.
+ * 1 0 0 Invalid. The BSP can never be in the disabled state.
+ * 1 0 1 Invalid. The BSP can never be in the disabled state.
+ * 1 1 0 Unhealthy Enabled BSP.
+ * 1 1 1 Healthy Enabled BSP.
+ * </pre>
+ */
+ uint32_t status_flags;
+
+ /*
+ * The physical location of the processor, including the physical package number
+ * that identifies the cartridge, the physical core number within package, and
+ * logical thread number within core.
+ */
+ struct efi_cpu_physical_location location;
+
+ /*
+ * The extended information of the processor. This field is filled only when
+ * CPU_V2_EXTENDED_TOPOLOGY is set in parameter ProcessorNumber.
+ */
+ union extended_processor_information extended_information;
+};
+
+struct efi_mp_information_hob_data {
+ uint64_t number_of_processors;
+ uint64_t number_of_enabled_processors;
+ struct efi_processor_information processor_info[];
+};
+
+#endif /* MPINFO_H */
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index c40f955..f12a4d6 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -302,7 +302,7 @@
/*
* Highest power level which takes part in a power management
- * operation.
+ * operation. May be lower while the core is in suspend state.
*/
unsigned int target_pwrlvl;
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index c50f8cb..9950a6e 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -89,10 +89,10 @@
void psci_register_spd_pm_hook(const spd_pm_ops_t *pm);
void psci_prepare_next_non_secure_ctx(
entry_point_info_t *next_image_info);
-int psci_stop_other_cores(unsigned int wait_ms,
+int psci_stop_other_cores(unsigned int this_cpu_idx, unsigned int wait_ms,
void (*stop_func)(u_register_t mpidr));
-bool psci_is_last_on_cpu_safe(void);
-bool psci_are_all_cpus_on_safe(void);
+bool psci_is_last_on_cpu_safe(unsigned int this_core);
+bool psci_are_all_cpus_on_safe(unsigned int this_core);
void psci_pwrdown_cpu(unsigned int power_level);
void psci_do_manage_extensions(void);
diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h
index 1b5ec2d..bcf9fc9 100644
--- a/include/lib/transfer_list.h
+++ b/include/lib/transfer_list.h
@@ -56,11 +56,12 @@
TL_TAG_HOB_BLOCK = 2,
TL_TAG_HOB_LIST = 3,
TL_TAG_ACPI_TABLE_AGGREGATE = 4,
+ TL_TAG_TPM_EVLOG = 5,
TL_TAG_OPTEE_PAGABLE_PART = 0x100,
TL_TAG_DT_SPMC_MANIFEST = 0x101,
TL_TAG_EXEC_EP_INFO64 = 0x102,
- TL_TAG_TB_FW_CONFIG = 0x103,
TL_TAG_SRAM_LAYOUT64 = 0x104,
+ TL_TAG_MBEDTLS_HEAP_INFO = 0x105,
};
enum transfer_list_ops {
@@ -110,6 +111,7 @@
CASSERT(sizeof(struct transfer_list_entry) == U(0x8), assert_transfer_list_entry_size);
void transfer_list_dump(struct transfer_list_header *tl);
+struct transfer_list_header *transfer_list_ensure(void *addr, size_t size);
entry_point_info_t *
transfer_list_set_handoff_args(struct transfer_list_header *tl,
entry_point_info_t *ep_info);
diff --git a/include/plat/arm/board/common/rotpk/rotpk_def.h b/include/plat/arm/board/common/rotpk/rotpk_def.h
index 685c21a..9ad9e4e 100644
--- a/include/plat/arm/board/common/rotpk/rotpk_def.h
+++ b/include/plat/arm/board/common/rotpk/rotpk_def.h
@@ -13,12 +13,9 @@
*/
/*
- * Root of trust key lengths
+ * Length of the header for a hashed DER ROTPK.
*/
-#ifndef ARM_ROTPK_HEADER_LEN
-#define ARM_ROTPK_HEADER_LEN 19
-#endif
-#ifndef ARM_ROTPK_HASH_LEN
-#define ARM_ROTPK_HASH_LEN 32
+#ifndef ARM_ROTPK_HASH_DER_HEADER_LEN
+#define ARM_ROTPK_HASH_DER_HEADER_LEN 19
#endif
#endif /* ROTPK_DEF_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index c3756bf..1d7a59d 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -288,6 +288,11 @@
void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl);
void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node,
struct transfer_list_header *secure_tl);
+void arm_transfer_list_copy_hw_config(struct transfer_list_header *secure_tl,
+ struct transfer_list_header *ns_tl);
+struct transfer_list_entry *
+arm_transfer_list_set_heap_info(struct transfer_list_header *tl);
+void arm_transfer_list_get_heap_info(void **heap_addr, size_t *heap_size);
/* TSP utility functions */
void arm_tsp_early_platform_setup(void);
@@ -427,6 +432,7 @@
extern plat_psci_ops_t plat_arm_psci_pm_ops;
extern const mmap_region_t plat_arm_mmap[];
extern const unsigned int arm_pm_idle_states[];
+extern struct transfer_list_header *secure_tl;
/* secure watchdog */
void plat_arm_secure_wdt_start(void);
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 118b537..b43f131 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -299,6 +299,16 @@
#if (MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT)
void bl2_plat_mboot_init(void);
void bl2_plat_mboot_finish(void);
+#if TRANSFER_LIST
+int plat_handoff_mboot(const void *data, uint32_t data_size, void *tl_base);
+#else
+static inline int
+plat_handoff_mboot(__unused const void *data, __unused uint32_t data_size,
+ __unused void *tl_base)
+{
+ return -1;
+}
+#endif
#else
static inline void bl2_plat_mboot_init(void)
{
diff --git a/include/plat/nuvoton/common/npcm845x_arm_def.h b/include/plat/nuvoton/common/npcm845x_arm_def.h
index df3ad24..9e921b8 100644
--- a/include/plat/nuvoton/common/npcm845x_arm_def.h
+++ b/include/plat/nuvoton/common/npcm845x_arm_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
*
* Copyright (C) 2017-2023 Nuvoton Ltd.
*
@@ -30,10 +30,9 @@
*****************************************************************************/
/*
- * Root of trust key hash lengths
+ * Length of the header for a hashed DER ROTPK.
*/
-#define ARM_ROTPK_HEADER_LEN 19
-#define ARM_ROTPK_HASH_LEN 32
+#define ARM_ROTPK_HASH_DER_HEADER_LEN 19
/* Special value used to verify platform parameters from BL2 to BL31 */
#define ARM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978)
diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h
index 645b388..c2b1f41 100644
--- a/include/services/arm_arch_svc.h
+++ b/include/services/arm_arch_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,8 +13,310 @@
#define SMCCC_ARCH_WORKAROUND_1 U(0x80008000)
#define SMCCC_ARCH_WORKAROUND_2 U(0x80007FFF)
#define SMCCC_ARCH_WORKAROUND_3 U(0x80003FFF)
+#define SMCCC_ARCH_FEATURE_AVAILABILITY U(0x80000003)
#define SMCCC_GET_SOC_VERSION U(0)
#define SMCCC_GET_SOC_REVISION U(1)
+#ifndef __ASSEMBLER__
+#if ARCH_FEATURE_AVAILABILITY
+#include <lib/cassert.h>
+
+#if ENABLE_FEAT_FGT2
+#define SCR_FEAT_FGT2 SCR_FGTEN2_BIT
+#else
+#define SCR_FEAT_FGT2 (0)
+#endif
+
+#if ENABLE_FEAT_FPMR
+#define SCR_FEAT_FPMR SCR_EnFPM_BIT
+#else
+#define SCR_FEAT_FPMR
+#endif
+
+#if ENABLE_FEAT_D128
+#define SCR_FEAT_D128 SCR_D128En_BIT
+#else
+#define SCR_FEAT_D128 (0)
+#endif
+
+#if ENABLE_FEAT_S1PIE
+#define SCR_FEAT_S1PIE SCR_PIEN_BIT
+#else
+#define SCR_FEAT_S1PIE (0)
+#endif
+
+#if ENABLE_FEAT_SCTLR2
+#define SCR_FEAT_SCTLR2 SCR_SCTLR2En_BIT
+#else
+#define SCR_FEAT_SCTLR2 (0)
+#endif
+
+#if ENABLE_FEAT_TCR2
+#define SCR_FEAT_TCR2 SCR_TCR2EN_BIT
+#else
+#define SCR_FEAT_TCR2 (0)
+#endif
+
+#if ENABLE_FEAT_THE
+#define SCR_FEAT_THE SCR_RCWMASKEn_BIT
+#else
+#define SCR_FEAT_THE (0)
+#endif
+
+#if ENABLE_SME_FOR_NS
+#define SCR_FEAT_SME SCR_ENTP2_BIT
+#else
+#define SCR_FEAT_SME (0)
+#endif
+
+#if ENABLE_FEAT_GCS
+#define SCR_FEAT_GCS SCR_GCSEn_BIT
+#else
+#define SCR_FEAT_GCS (0)
+#endif
+
+#if ENABLE_FEAT_HCX
+#define SCR_FEAT_HCX SCR_HXEn_BIT
+#else
+#define SCR_FEAT_HCX (0)
+#endif
+
+#if ENABLE_FEAT_LS64_ACCDATA
+#define SCR_FEAT_LS64_ACCDATA (SCR_ADEn_BIT | SCR_EnAS0_BIT)
+#else
+#define SCR_FEAT_LS64_ACCDATA (0)
+#endif
+
+#if ENABLE_FEAT_AMUv1p1
+#define SCR_FEAT_AMUv1p1 SCR_AMVOFFEN_BIT
+#else
+#define SCR_FEAT_AMUv1p1 (0)
+#endif
+
+#if ENABLE_FEAT_ECV
+#define SCR_FEAT_ECV SCR_ECVEN_BIT
+#else
+#define SCR_FEAT_ECV (0)
+#endif
+
+#if ENABLE_FEAT_FGT
+#define SCR_FEAT_FGT SCR_FGTEN_BIT
+#else
+#define SCR_FEAT_FGT (0)
+#endif
+
+#if ENABLE_FEAT_MTE2
+#define SCR_FEAT_MTE2 SCR_ATA_BIT
+#else
+#define SCR_FEAT_MTE2 (0)
+#endif
+
+#if ENABLE_FEAT_CSV2_2
+#define SCR_FEAT_CSV2_2 SCR_EnSCXT_BIT
+#else
+#define SCR_FEAT_CSV2_2 (0)
+#endif
+
+#if ENABLE_FEAT_RAS
+#define SCR_FEAT_RAS SCR_TERR_BIT
+#else
+#define SCR_FEAT_RAS (0)
+#endif
+
+#ifndef SCR_PLAT_FEATS
+#define SCR_PLAT_FEATS (0)
+#endif
+#ifndef SCR_PLAT_FLIPPED
+#define SCR_PLAT_FLIPPED (0)
+#endif
+#ifndef SCR_PLAT_IGNORED
+#define SCR_PLAT_IGNORED (0)
+#endif
+
+#ifndef CPTR_PLAT_FEATS
+#define CPTR_PLAT_FEATS (0)
+#endif
+#ifndef CPTR_PLAT_FLIPPED
+#define CPTR_PLAT_FLIPPED (0)
+#endif
+
+#ifndef MDCR_PLAT_FEATS
+#define MDCR_PLAT_FEATS (0)
+#endif
+#ifndef MDCR_PLAT_FLIPPED
+#define MDCR_PLAT_FLIPPED (0)
+#endif
+#ifndef MDCR_PLAT_IGNORED
+#define MDCR_PLAT_IGNORED (0)
+#endif
+/*
+ * XYZ_EL3_FEATS - list all bits that are relevant for feature enablement. It's
+ * a constant list based on what features are expected. This relies on the fact
+ * that if the feature is in any way disabled, then the relevant bit will not be
+ * written by context management.
+ *
+ * XYZ_EL3_FLIPPED - bits with an active 0, rather than the usual active 1. The
+ * spec always uses active 1 to mean that the feature will not trap.
+ *
+ * XYZ_EL3_IGNORED - list of all bits that are not relevant for feature
+ * enablement and should not be reported to lower ELs
+ */
+#define SCR_EL3_FEATS ( \
+ SCR_FEAT_FGT2 | \
+ SCR_FEAT_FPMR | \
+ SCR_FEAT_D128 | \
+ SCR_FEAT_S1PIE | \
+ SCR_FEAT_SCTLR2 | \
+ SCR_FEAT_TCR2 | \
+ SCR_FEAT_THE | \
+ SCR_FEAT_SME | \
+ SCR_FEAT_GCS | \
+ SCR_FEAT_HCX | \
+ SCR_FEAT_LS64_ACCDATA | \
+ SCR_FEAT_AMUv1p1 | \
+ SCR_FEAT_ECV | \
+ SCR_FEAT_FGT | \
+ SCR_FEAT_MTE2 | \
+ SCR_FEAT_CSV2_2 | \
+ SCR_APK_BIT | /* FEAT_Pauth */ \
+ SCR_FEAT_RAS | \
+ SCR_PLAT_FEATS)
+#define SCR_EL3_FLIPPED ( \
+ SCR_FEAT_RAS | \
+ SCR_PLAT_FLIPPED)
+#define SCR_EL3_IGNORED ( \
+ SCR_API_BIT | \
+ SCR_RW_BIT | \
+ SCR_SIF_BIT | \
+ SCR_HCE_BIT | \
+ SCR_FIQ_BIT | \
+ SCR_IRQ_BIT | \
+ SCR_NS_BIT | \
+ SCR_RES1_BITS | \
+ SCR_PLAT_IGNORED)
+CASSERT((SCR_EL3_FEATS & SCR_EL3_IGNORED) == 0, scr_feat_is_ignored);
+CASSERT((SCR_EL3_FLIPPED & SCR_EL3_FEATS) == SCR_EL3_FLIPPED, scr_flipped_not_a_feat);
+
+#if ENABLE_SYS_REG_TRACE_FOR_NS
+#define CPTR_SYS_REG_TRACE (TCPAC_BIT | TTA_BIT)
+#else
+#define CPTR_SYS_REG_TRACE (0)
+#endif
+
+#if ENABLE_FEAT_AMU
+#define CPTR_FEAT_AMU TAM_BIT
+#else
+#define CPTR_FEAT_AMU (0)
+#endif
+
+#if ENABLE_SME_FOR_NS
+#define CPTR_FEAT_SME ESM_BIT
+#else
+#define CPTR_FEAT_SME (0)
+#endif
+
+#if ENABLE_SVE_FOR_NS
+#define CPTR_FEAT_SVE CPTR_EZ_BIT
+#else
+#define CPTR_FEAT_SVE (0)
+#endif
+
+#define CPTR_EL3_FEATS ( \
+ CPTR_SYS_REG_TRACE | \
+ CPTR_FEAT_AMU | \
+ CPTR_FEAT_SME | \
+ TFP_BIT | \
+ CPTR_FEAT_SVE | \
+ CPTR_PLAT_FEATS)
+#define CPTR_EL3_FLIPPED ( \
+ CPTR_SYS_REG_TRACE | \
+ CPTR_FEAT_AMU | \
+ TFP_BIT | \
+ CPTR_PLAT_FLIPPED)
+CASSERT((CPTR_EL3_FLIPPED & CPTR_EL3_FEATS) == CPTR_EL3_FLIPPED, cptr_flipped_not_a_feat);
+
+/*
+ * Some features enables are expressed with more than 1 bit in order to cater
+ * for multi world enablement. In those cases (BRB, TRB, SPE) only the last bit
+ * is used and reported. This (ab)uses the convenient fact that the last bit
+ * always means "enabled for this world" when context switched correctly.
+ * The per-world values have been adjusted such that this is always true.
+ */
+#if ENABLE_BRBE_FOR_NS
+#define MDCR_FEAT_BRBE MDCR_SBRBE(1UL)
+#else
+#define MDCR_FEAT_BRBE (0)
+#endif
+
+#if ENABLE_FEAT_FGT
+#define MDCR_FEAT_FGT MDCR_TDCC_BIT
+#else
+#define MDCR_FEAT_FGT (0)
+#endif
+
+#if ENABLE_TRBE_FOR_NS
+#define MDCR_FEAT_TRBE MDCR_NSTB(1UL)
+#else
+#define MDCR_FEAT_TRBE (0)
+#endif
+
+#if ENABLE_TRF_FOR_NS
+#define MDCR_FEAT_TRF MDCR_TTRF_BIT
+#else
+#define MDCR_FEAT_TRF (0)
+#endif
+
+#if ENABLE_SPE_FOR_NS
+#define MDCR_FEAT_SPE MDCR_NSPB(1UL)
+#else
+#define MDCR_FEAT_SPE (0)
+#endif
+
+#define MDCR_EL3_FEATS ( \
+ MDCR_FEAT_BRBE | \
+ MDCR_FEAT_FGT | \
+ MDCR_FEAT_TRBE | \
+ MDCR_FEAT_TRF | \
+ MDCR_FEAT_SPE | \
+ MDCR_TDOSA_BIT | \
+ MDCR_TDA_BIT | \
+ MDCR_TPM_BIT | /* FEAT_PMUv3 */ \
+ MDCR_PLAT_FEATS)
+#define MDCR_EL3_FLIPPED ( \
+ MDCR_FEAT_FGT | \
+ MDCR_FEAT_TRF | \
+ MDCR_TDOSA_BIT | \
+ MDCR_TDA_BIT | \
+ MDCR_TPM_BIT | \
+ MDCR_PLAT_FLIPPED)
+#define MDCR_EL3_IGNORED ( \
+ MDCR_EBWE_BIT | \
+ MDCR_EnPMSN_BIT | \
+ MDCR_SBRBE(2UL) | \
+ MDCR_MTPME_BIT | \
+ MDCR_NSTBE_BIT | \
+ MDCR_NSTB(2UL) | \
+ MDCR_SDD_BIT | \
+ MDCR_SPD32(3UL) | \
+ MDCR_NSPB(2UL) | \
+ MDCR_NSPBE_BIT | \
+ MDCR_PLAT_IGNORED)
+CASSERT((MDCR_EL3_FEATS & MDCR_EL3_IGNORED) == 0, mdcr_feat_is_ignored);
+CASSERT((MDCR_EL3_FLIPPED & MDCR_EL3_FEATS) == MDCR_EL3_FLIPPED, mdcr_flipped_not_a_feat);
+
+#define MPAM3_EL3_FEATS (MPAM3_EL3_TRAPLOWER_BIT)
+#define MPAM3_EL3_FLIPPED (MPAM3_EL3_TRAPLOWER_BIT)
+#define MPAM3_EL3_IGNORED (MPAM3_EL3_MPAMEN_BIT)
+CASSERT((MPAM3_EL3_FEATS & MPAM3_EL3_IGNORED) == 0, mpam3_feat_is_ignored);
+CASSERT((MPAM3_EL3_FLIPPED & MPAM3_EL3_FEATS) == MPAM3_EL3_FLIPPED, mpam3_flipped_not_a_feat);
+
+/* The hex representations of these registers' S3 encoding */
+#define SCR_EL3_OPCODE U(0x1E1100)
+#define CPTR_EL3_OPCODE U(0x1E1140)
+#define MDCR_EL3_OPCODE U(0x1E1320)
+#define MPAM3_EL3_OPCODE U(0x1EA500)
+
+#endif /* ARCH_FEATURE_AVAILABILITY */
+#endif /* __ASSEMBLER__ */
#endif /* ARM_ARCH_SVC_H */
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 01dbea9..f5a9a2d 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -173,8 +173,8 @@
#define FFA_SPM_ID_GET FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
#define FFA_NORMAL_WORLD_RESUME FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME)
#define FFA_EL3_INTR_HANDLE FFA_FID(SMC_32, FFA_FNUM_EL3_INTR_HANDLE)
-#define FFA_MEM_PERM_GET FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_GET)
-#define FFA_MEM_PERM_SET FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_SET)
+#define FFA_MEM_PERM_GET_SMC32 FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_GET)
+#define FFA_MEM_PERM_SET_SMC32 FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_SET)
#define FFA_CONSOLE_LOG_SMC32 FFA_FID(SMC_32, FFA_FNUM_CONSOLE_LOG)
/* FFA SMC64 FIDs */
@@ -201,6 +201,8 @@
FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_REQ2)
#define FFA_MSG_SEND_DIRECT_RESP2_SMC64 \
FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_RESP2)
+#define FFA_MEM_PERM_GET_SMC64 FFA_FID(SMC_64, FFA_FNUM_MEM_PERM_GET)
+#define FFA_MEM_PERM_SET_SMC64 FFA_FID(SMC_64, FFA_FNUM_MEM_PERM_SET)
/*
* FF-A partition properties values.
@@ -208,6 +210,8 @@
#define FFA_PARTITION_DIRECT_REQ_RECV U(1 << 0)
#define FFA_PARTITION_DIRECT_REQ_SEND U(1 << 1)
#define FFA_PARTITION_INDIRECT_MSG U(1 << 2)
+#define FFA_PARTITION_DIRECT_REQ2_RECV U(1 << 9)
+#define FFA_PARTITION_DIRECT_REQ2_SEND U(1 << 10)
/*
* Reserve a special value for traffic targeted to the Hypervisor or SPM.
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index b9f6081..dce9c73 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -26,6 +26,13 @@
wa_cve_2022_23960_bhb_vector_table CORTEX_A710_BHB_LOOP_COUNT, cortex_a710
#endif /* WORKAROUND_CVE_2022_23960 */
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a710, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set CORTEX_A710_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a710, CVE(2024, 5660)
+
+check_erratum_ls cortex_a710, CVE(2024, 5660), CPU_REV(2, 1)
+
workaround_reset_start cortex_a710, ERRATUM(1987031), ERRATA_A710_1987031
ldr x0,=0x6
msr S3_6_c15_c8_0,x0
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index f53b646..766bdc0 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -26,6 +26,13 @@
wa_cve_2022_23960_bhb_vector_table CORTEX_A77_BHB_LOOP_COUNT, cortex_a77
#endif /* WORKAROUND_CVE_2022_23960 */
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a77, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set CORTEX_A77_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a77, CVE(2024, 5660)
+
+check_erratum_ls cortex_a77, CVE(2024, 5660), CPU_REV(1, 1)
+
workaround_reset_start cortex_a77, ERRATUM(1508412), ERRATA_A77_1508412
/* move cpu revision in again and compare against r0p0 */
mov x0, x7
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 1de570a..9f2ffdf 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -24,6 +24,13 @@
wa_cve_2022_23960_bhb_vector_table CORTEX_A78_BHB_LOOP_COUNT, cortex_a78
#endif /* WORKAROUND_CVE_2022_23960 */
+/* Disable hardware page aggregation.Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a78, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set CORTEX_A78_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a78, CVE(2024, 5660)
+
+check_erratum_ls cortex_a78, CVE(2024, 5660), CPU_REV(1, 2)
+
workaround_reset_start cortex_a78, ERRATUM(1688305), ERRATA_A78_1688305
sysreg_bit_set CORTEX_A78_ACTLR2_EL1, CORTEX_A78_ACTLR2_EL1_BIT_1
workaround_reset_end cortex_a78, ERRATUM(1688305)
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index bc10186..7fa1f9b 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -22,6 +22,13 @@
wa_cve_2022_23960_bhb_vector_table CORTEX_A78_AE_BHB_LOOP_COUNT, cortex_a78_ae
#endif /* WORKAROUND_CVE_2022_23960 */
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a78_ae, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set CORTEX_A78_AE_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a78_ae, CVE(2024, 5660)
+
+check_erratum_ls cortex_a78_ae, CVE(2024, 5660), CPU_REV(0, 3)
+
workaround_reset_start cortex_a78_ae, ERRATUM(1941500), ERRATA_A78_AE_1941500
sysreg_bit_set CORTEX_A78_AE_CPUECTLR_EL1, CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
workaround_reset_end cortex_a78_ae, ERRATUM(1941500)
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 260cc73..3f6944a 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -21,6 +21,13 @@
wa_cve_2022_23960_bhb_vector_table CORTEX_A78C_BHB_LOOP_COUNT, cortex_a78c
#endif /* WORKAROUND_CVE_2022_23960 */
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a78c, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set CORTEX_A78C_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a78c, CVE(2024, 5660)
+
+check_erratum_ls cortex_a78c, CVE(2024, 5660), CPU_REV(0, 2)
+
workaround_reset_start cortex_a78c, ERRATUM(1827430), ERRATA_A78C_1827430
/* Disable allocation of splintered pages in the L2 TLB */
sysreg_bit_set CORTEX_A78C_CPUECTLR_EL1, CORTEX_A78C_CPUECTLR_EL1_MM_ASP_EN
diff --git a/lib/cpus/aarch64/cortex_alto.S b/lib/cpus/aarch64/cortex_alto.S
new file mode 100644
index 0000000..c0815f9
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_alto.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_alto.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Alto must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Alto supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_alto
+ /* Disable speculative loads */
+ msr SSBS, xzr
+cpu_reset_func_end cortex_alto
+
+func cortex_alto_core_pwr_dwn
+#if ENABLE_SME_FOR_NS
+ /* ---------------------------------------------------
+ * Disable SME if enabled and supported
+ * ---------------------------------------------------
+ */
+ mrs x0, ID_AA64PFR1_EL1
+ ubfx x0, x0, #ID_AA64PFR1_EL1_SME_SHIFT, \
+ #ID_AA64PFR1_EL1_SME_WIDTH
+ cmp x0, #SME_NOT_IMPLEMENTED
+ b.eq 1f
+ msr CORTEX_ALTO_SVCRSM, xzr
+ msr CORTEX_ALTO_SVCRZA, xzr
+1:
+#endif
+ /* ---------------------------------------------------
+ * Enable CPU power down bit in power control register
+ * ---------------------------------------------------
+ */
+ sysreg_bit_set CORTEX_ALTO_IMP_CPUPWRCTLR_EL1, \
+ CORTEX_ALTO_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
+ isb
+ ret
+endfunc cortex_alto_core_pwr_dwn
+
+.section .rodata.cortex_alto_regs, "aS"
+cortex_alto_regs: /* The ASCII list of register names to be reported */
+ .asciz "cpuectlr_el1", ""
+
+func cortex_alto_cpu_reg_dump
+ adr x6, cortex_alto_regs
+ mrs x8, CORTEX_ALTO_IMP_CPUECTLR_EL1
+ ret
+endfunc cortex_alto_cpu_reg_dump
+
+declare_cpu_ops cortex_alto, CORTEX_ALTO_MIDR, \
+ cortex_alto_reset_func, \
+ cortex_alto_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x1.S b/lib/cpus/aarch64/cortex_x1.S
index ca6cac9..5bd020c 100644
--- a/lib/cpus/aarch64/cortex_x1.S
+++ b/lib/cpus/aarch64/cortex_x1.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023, Google LLC. All rights reserved.
+ * Copyright (c) 2022-2024, Google LLC. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,6 +23,13 @@
wa_cve_2022_23960_bhb_vector_table CORTEX_X1_BHB_LOOP_COUNT, cortex_x1
#endif /* WORKAROUND_CVE_2022_23960 */
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x1, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set CORTEX_X1_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x1, CVE(2024, 5660)
+
+check_erratum_ls cortex_x1, CVE(2024, 5660), CPU_REV(1, 2)
+
workaround_reset_start cortex_x1, ERRATUM(1688305), ERRATA_X1_1688305
sysreg_bit_set CORTEX_X1_ACTLR2_EL1, BIT(1)
workaround_reset_end cortex_x1, ERRATUM(1688305)
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index ac60903..2fc357a 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -26,6 +26,13 @@
wa_cve_2022_23960_bhb_vector_table CORTEX_X2_BHB_LOOP_COUNT, cortex_x2
#endif /* WORKAROUND_CVE_2022_23960 */
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set CORTEX_X2_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x2, CVE(2024, 5660)
+
+check_erratum_ls cortex_x2, CVE(2024, 5660), CPU_REV(2, 1)
+
workaround_reset_start cortex_x2, ERRATUM(2002765), ERRATA_X2_2002765
ldr x0, =0x6
msr S3_6_C15_C8_0, x0 /* CPUPSELR_EL3 */
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index a81c4cf..6becf7b 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -26,6 +26,13 @@
wa_cve_2022_23960_bhb_vector_table CORTEX_X3_BHB_LOOP_COUNT, cortex_x3
#endif /* WORKAROUND_CVE_2022_23960 */
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x3, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set CORTEX_X3_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x3, CVE(2024, 5660)
+
+check_erratum_ls cortex_x3, CVE(2024, 5660), CPU_REV(1, 2)
+
workaround_reset_start cortex_x3, ERRATUM(2070301), ERRATA_X3_2070301
sysreg_bitfield_insert CORTEX_X3_CPUECTLR2_EL1, CORTEX_X3_CPUECTLR2_EL1_PF_MODE_CNSRV, \
CORTEX_X3_CPUECTLR2_EL1_PF_MODE_LSB, CORTEX_X3_CPUECTLR2_EL1_PF_MODE_WIDTH
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index 320fd90..81704da 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -46,6 +46,13 @@
ret
check_erratum_custom_end cortex_x4, ERRATUM(2726228)
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x4, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set CORTEX_X4_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x4, CVE(2024, 5660)
+
+check_erratum_ls cortex_x4, CVE(2024, 5660), CPU_REV(0, 2)
+
workaround_runtime_start cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089
/* dsb before isb of power down sequence */
dsb sy
@@ -75,6 +82,12 @@
check_erratum_ls cortex_x4, ERRATUM(2897503), CPU_REV(0, 1)
+workaround_reset_start cortex_x4, ERRATUM(2923985), ERRATA_X4_2923985
+ sysreg_bit_set CORTEX_X4_CPUACTLR4_EL1, (BIT(11) | BIT(10))
+workaround_reset_end cortex_x4, ERRATUM(2923985)
+
+check_erratum_ls cortex_x4, ERRATUM(2923985), CPU_REV(0, 1)
+
workaround_reset_start cortex_x4, ERRATUM(3076789), ERRATA_X4_3076789
sysreg_bit_set CORTEX_X4_CPUACTLR3_EL1, BIT(14)
sysreg_bit_set CORTEX_X4_CPUACTLR3_EL1, BIT(13)
diff --git a/lib/cpus/aarch64/cortex_x925.S b/lib/cpus/aarch64/cortex_x925.S
index 8109ffb..3a31664 100644
--- a/lib/cpus/aarch64/cortex_x925.S
+++ b/lib/cpus/aarch64/cortex_x925.S
@@ -21,6 +21,13 @@
#error "Cortex-X925 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x925, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set CORTEX_X925_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x925, CVE(2024, 5660)
+
+check_erratum_ls cortex_x925, CVE(2024, 5660), CPU_REV(0, 1)
+
cpu_reset_func_start cortex_x925
/* Disable speculative loads */
msr SSBS, xzr
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index d2237f1..69aa8ab 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -34,6 +34,13 @@
.equ erratum_neoverse_n2_2313941_wa, errata_dsu_2313941_wa
add_erratum_entry neoverse_n2, ERRATUM(2313941), ERRATA_DSU_2313941, APPLY_AT_RESET
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_n2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set NEOVERSE_N2_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_n2, CVE(2024, 5660)
+
+check_erratum_ls neoverse_n2, CVE(2024, 5660), CPU_REV(0, 3)
+
workaround_reset_start neoverse_n2, ERRATUM(2002655), ERRATA_N2_2002655
/* Apply instruction patching sequence */
ldr x0,=0x6
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 1ec3e94..d1a2c24 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -26,6 +26,13 @@
wa_cve_2022_23960_bhb_vector_table NEOVERSE_V1_BHB_LOOP_COUNT, neoverse_v1
#endif /* WORKAROUND_CVE_2022_23960 */
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_v1, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set NEOVERSE_V1_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_v1, CVE(2024, 5660)
+
+check_erratum_ls neoverse_v1, CVE(2024, 5660), CPU_REV(1, 2)
+
workaround_reset_start neoverse_v1, ERRATUM(1618635), ERRATA_V1_1618635
/* Inserts a DMB SY before and after MRS PAR_EL1 */
ldr x0, =0x0
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index ca66f8d..f56a5e8 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -22,6 +22,13 @@
#error "Neoverse V2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_v2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set NEOVERSE_V2_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_v2, CVE(2024, 5660)
+
+check_erratum_ls neoverse_v2, CVE(2024, 5660), CPU_REV(0, 2)
+
workaround_reset_start neoverse_v2, ERRATUM(2331132), ERRATA_V2_2331132
sysreg_bitfield_insert NEOVERSE_V2_CPUECTLR2_EL1, NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_CNSRV, \
NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_LSB, NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_WIDTH
diff --git a/lib/cpus/aarch64/neoverse_v3.S b/lib/cpus/aarch64/neoverse_v3.S
index 01ac38f..4346d7d 100644
--- a/lib/cpus/aarch64/neoverse_v3.S
+++ b/lib/cpus/aarch64/neoverse_v3.S
@@ -26,6 +26,13 @@
wa_cve_2022_23960_bhb_vector_table NEOVERSE_V3_BHB_LOOP_COUNT, neoverse_v3
#endif /* WORKAROUND_CVE_2022_23960 */
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_v3, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+ sysreg_bit_set NEOVERSE_V3_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_v3, CVE(2024, 5660)
+
+check_erratum_ls neoverse_v3, CVE(2024, 5660), CPU_REV(0, 1)
+
workaround_reset_start neoverse_v3, CVE(2022,23960), WORKAROUND_CVE_2022_23960
#if IMAGE_BL31
/*
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 4c20785..d532460 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -33,6 +33,12 @@
WORKAROUND_CVE_2022_23960 ?=1
CPU_FLAG_LIST += WORKAROUND_CVE_2022_23960
+# Flag to disable Hardware page aggregation(HPA).
+# This flag is enabled by default.
+WORKAROUND_CVE_2024_5660 ?=1
+CPU_FLAG_LIST += WORKAROUND_CVE_2024_5660
+
+
# Flags to indicate internal or external Last level cache
# By default internal
CPU_FLAG_LIST += NEOVERSE_Nx_EXTERNAL_LLC
@@ -843,6 +849,10 @@
# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
CPU_FLAG_LIST += ERRATA_X4_2897503
+# Flag to apply erratum 2923985 workaround on reset. This erratum applies
+# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2923985
+
# Flag to apply erratum 3076789 workaround on reset. This erratum applies
# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
CPU_FLAG_LIST += ERRATA_X4_3076789
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index a353a87..fed24f0 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -400,7 +400,6 @@
/* PMUv3 is presumed to be always present */
mrs x9, pmcr_el0
str x9, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0]
- isb
#if CTX_INCLUDE_PAUTH_REGS
/* ----------------------------------------------------------
* Save the ARMv8.3-PAuth keys as they are not banked
@@ -440,6 +439,18 @@
* -----------------------------------------------------------------
*/
func prepare_el3_entry
+ /*
+ * context is about to mutate, so make sure we don't affect any still
+ * in-flight profiling operations. We don't care that they actually
+ * finish, that can still be later. NOP if not present
+ */
+#if ENABLE_SPE_FOR_NS
+ psb_csync
+#endif
+#if ENABLE_TRBE_FOR_NS
+ tsb_csync
+#endif
+ isb
save_gp_pmcr_pauth_regs
setup_el3_execution_context
ret
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 4ae1306..473190c 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -28,6 +28,7 @@
#include <lib/extensions/brbe.h>
#include <lib/extensions/debug_v8p9.h>
#include <lib/extensions/fgt2.h>
+#include <lib/extensions/fpmr.h>
#include <lib/extensions/mpam.h>
#include <lib/extensions/pmuv3.h>
#include <lib/extensions/sme.h>
@@ -48,7 +49,6 @@
per_world_context_t per_world_context[CPU_DATA_CONTEXT_NUM];
static bool has_secure_perworld_init;
-static void manage_extensions_common(cpu_context_t *ctx);
static void manage_extensions_nonsecure(cpu_context_t *ctx);
static void manage_extensions_secure(cpu_context_t *ctx);
static void manage_extensions_secure_per_world(void);
@@ -235,8 +235,9 @@
* SCR_EL3.APK: Set to one to not trap any PAuth key values at ELs other
* than EL3
*/
- scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
-
+ if (is_armv8_3_pauth_present()) {
+ scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
+ }
#endif /* CTX_INCLUDE_PAUTH_REGS */
#if HANDLE_EA_EL3_FIRST_NS
@@ -250,7 +251,6 @@
* and RAS ERX registers from EL1 and EL2(from any security state)
* are trapped to EL3.
* Set here to trap only for NS EL1/EL2
- *
*/
scr_el3 |= SCR_TERR_BIT;
#endif
@@ -291,6 +291,13 @@
scr_el3 |= SCR_D128En_BIT;
}
+ if (is_feat_fpmr_supported()) {
+ /* Set the EnFPM bit in SCR_EL3 to enable access to FPMR
+ * register.
+ */
+ scr_el3 |= SCR_EnFPM_BIT;
+ }
+
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
/* Initialize EL2 context registers */
@@ -439,9 +446,9 @@
* If FEAT_RNG_TRAP is enabled, all reads of the RNDR and RNDRRS
* registers are trapped to EL3.
*/
-#if ENABLE_FEAT_RNG_TRAP
- scr_el3 |= SCR_TRNDR_BIT;
-#endif
+ if (is_feat_rng_trap_supported()) {
+ scr_el3 |= SCR_TRNDR_BIT;
+ }
#if FAULT_INJECTION_SUPPORT
/* Enable fault injection from lower ELs */
@@ -458,7 +465,9 @@
* SCR_EL3.APK: Set to one to not trap any PAuth key values at ELs other
* than EL3
*/
- scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
+ if (is_armv8_3_pauth_present()) {
+ scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
+ }
#endif /* CTX_INCLUDE_PAUTH_REGS */
/*
@@ -559,11 +568,14 @@
& ~(MDCR_TDA_BIT | MDCR_TDOSA_BIT)) ;
write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3);
- /*
- * Configure MDCR_EL3 register as applicable for each world
- * (NS/Secure/Realm) context.
- */
- manage_extensions_common(ctx);
+#if IMAGE_BL31
+ /* Enable FEAT_TRF for Non-Secure and prohibit for Secure state. */
+ if (is_feat_trf_supported()) {
+ trf_enable(ctx);
+ }
+
+ pmuv3_enable(ctx);
+#endif /* IMAGE_BL31 */
/*
* Store the X0-X7 value from the entrypoint into the context
@@ -714,6 +726,10 @@
if (is_feat_mpam_supported()) {
mpam_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
}
+
+ if (is_feat_fpmr_supported()) {
+ fpmr_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
+ }
}
#endif /* IMAGE_BL31 */
@@ -769,41 +785,6 @@
}
/*******************************************************************************
- * Enable architecture extensions on first entry to Non-secure world only
- * and disable for secure world.
- *
- * NOTE: Arch features which have been provided with the capability of getting
- * enabled only for non-secure world and being disabled for secure world are
- * grouped here, as the MDCR_EL3 context value remains same across the worlds.
- ******************************************************************************/
-static void manage_extensions_common(cpu_context_t *ctx)
-{
-#if IMAGE_BL31
- if (is_feat_spe_supported()) {
- /*
- * Enable FEAT_SPE for Non-Secure and prohibit for Secure state.
- */
- spe_enable(ctx);
- }
-
- if (is_feat_trbe_supported()) {
- /*
- * Enable FEAT_TRBE for Non-Secure and prohibit for Secure and
- * Realm state.
- */
- trbe_enable(ctx);
- }
-
- if (is_feat_trf_supported()) {
- /*
- * Enable FEAT_TRF for Non-Secure and prohibit for Secure state.
- */
- trf_enable(ctx);
- }
-#endif /* IMAGE_BL31 */
-}
-
-/*******************************************************************************
* Enable architecture extensions on first entry to Non-secure world.
******************************************************************************/
static void manage_extensions_nonsecure(cpu_context_t *ctx)
@@ -825,11 +806,24 @@
debugv8p9_extended_bp_wp_enable(ctx);
}
+ /*
+ * SPE, TRBE, and BRBE have multi-field enables that affect which world
+ * they apply to. Despite this, it is useful to ignore these for
+ * simplicity in determining the feature's per world enablement status.
+ * This is only possible when context is written per-world. Relied on
+ * by SMCCC_ARCH_FEATURE_AVAILABILITY
+ */
+ if (is_feat_spe_supported()) {
+ spe_enable(ctx);
+ }
+
+ if (is_feat_trbe_supported()) {
+ trbe_enable(ctx);
+ }
+
if (is_feat_brbe_supported()) {
brbe_enable(ctx);
}
-
- pmuv3_enable(ctx);
#endif /* IMAGE_BL31 */
}
@@ -889,6 +883,10 @@
sme_init_el2_unused();
}
+ if (is_feat_mops_supported()) {
+ write_hcrx_el2(read_hcrx_el2() | HCRX_EL2_MSCEn_BIT);
+ }
+
#if ENABLE_PAUTH
enable_pauth_el2();
#endif /* ENABLE_PAUTH */
@@ -918,6 +916,20 @@
sme_disable(ctx);
}
}
+
+ /*
+ * SPE and TRBE cannot be fully disabled from EL3 registers alone, only
+ * sysreg access can. In case the EL1 controls leave them active on
+ * context switch, we want the owning security state to be NS so Secure
+ * can't be DOSed.
+ */
+ if (is_feat_spe_supported()) {
+ spe_disable(ctx);
+ }
+
+ if (is_feat_trbe_supported()) {
+ trbe_disable(ctx);
+ }
#endif /* IMAGE_BL31 */
}
@@ -1352,8 +1364,8 @@
write_el2_ctx_common(ctx, vpidr_el2, read_vpidr_el2());
write_el2_ctx_common(ctx, vtcr_el2, read_vtcr_el2());
- write_el2_ctx_sysreg128(ctx, ttbr0_el2, read_ttbr0_el2());
- write_el2_ctx_sysreg128(ctx, vttbr_el2, read_vttbr_el2());
+ write_el2_ctx_common_sysreg128(ctx, ttbr0_el2, read_ttbr0_el2());
+ write_el2_ctx_common_sysreg128(ctx, vttbr_el2, read_vttbr_el2());
}
static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx)
@@ -1679,15 +1691,12 @@
write_el1_ctx_common(ctx, csselr_el1, read_csselr_el1());
write_el1_ctx_common(ctx, sp_el1, read_sp_el1());
write_el1_ctx_common(ctx, esr_el1, read_esr_el1());
- write_el1_ctx_common(ctx, ttbr0_el1, read_ttbr0_el1());
- write_el1_ctx_common(ctx, ttbr1_el1, read_ttbr1_el1());
write_el1_ctx_common(ctx, mair_el1, read_mair_el1());
write_el1_ctx_common(ctx, amair_el1, read_amair_el1());
write_el1_ctx_common(ctx, actlr_el1, read_actlr_el1());
write_el1_ctx_common(ctx, tpidr_el1, read_tpidr_el1());
write_el1_ctx_common(ctx, tpidr_el0, read_tpidr_el0());
write_el1_ctx_common(ctx, tpidrro_el0, read_tpidrro_el0());
- write_el1_ctx_common(ctx, par_el1, read_par_el1());
write_el1_ctx_common(ctx, far_el1, read_far_el1());
write_el1_ctx_common(ctx, afsr0_el1, read_afsr0_el1());
write_el1_ctx_common(ctx, afsr1_el1, read_afsr1_el1());
@@ -1696,6 +1705,10 @@
write_el1_ctx_common(ctx, mdccint_el1, read_mdccint_el1());
write_el1_ctx_common(ctx, mdscr_el1, read_mdscr_el1());
+ write_el1_ctx_common_sysreg128(ctx, par_el1, read_par_el1());
+ write_el1_ctx_common_sysreg128(ctx, ttbr0_el1, read_ttbr0_el1());
+ write_el1_ctx_common_sysreg128(ctx, ttbr1_el1, read_ttbr1_el1());
+
if (CTX_INCLUDE_AARCH32_REGS) {
/* Save Aarch32 registers */
write_el1_ctx_aarch32(ctx, spsr_abt, read_spsr_abt());
@@ -1760,8 +1773,8 @@
}
if (is_feat_the_supported()) {
- write_el1_ctx_the(ctx, rcwmask_el1, read_rcwmask_el1());
- write_el1_ctx_the(ctx, rcwsmask_el1, read_rcwsmask_el1());
+ write_el1_ctx_the_sysreg128(ctx, rcwmask_el1, read_rcwmask_el1());
+ write_el1_ctx_the_sysreg128(ctx, rcwsmask_el1, read_rcwsmask_el1());
}
if (is_feat_sctlr2_supported()) {
diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c
index fef6647..f951654 100644
--- a/lib/extensions/brbe/brbe.c
+++ b/lib/extensions/brbe/brbe.c
@@ -22,7 +22,7 @@
* MDCR_EL3.{E3BREW, E3BREC} = 0b00
* Branch recording at EL3 is disabled
*/
- mdcr_el3_val &= ~((MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT) | MDCR_E3BREW | MDCR_E3BREC);
- mdcr_el3_val |= (0x1UL << MDCR_SBRBE_SHIFT);
+ mdcr_el3_val &= ~((MDCR_SBRBE(MDCR_SBRBE_ALL)) | MDCR_E3BREW_BIT | MDCR_E3BREC_BIT);
+ mdcr_el3_val |= (MDCR_SBRBE(MDCR_SBRBE_NS));
write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
}
diff --git a/lib/extensions/fpmr/fpmr.c b/lib/extensions/fpmr/fpmr.c
new file mode 100644
index 0000000..8e37e7a
--- /dev/null
+++ b/lib/extensions/fpmr/fpmr.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <lib/extensions/fpmr.h>
+
+void fpmr_enable_per_world(per_world_context_t *per_world_ctx)
+{
+ u_register_t reg;
+
+ /* Disable Floating point Trap in CPTR_EL3. */
+ reg = per_world_ctx->ctx_cptr_el3;
+ reg &= ~TFP_BIT;
+ per_world_ctx->ctx_cptr_el3 = reg;
+}
diff --git a/lib/extensions/pmuv3/aarch64/pmuv3.c b/lib/extensions/pmuv3/aarch64/pmuv3.c
index f9e32ca..61d1258 100644
--- a/lib/extensions/pmuv3/aarch64/pmuv3.c
+++ b/lib/extensions/pmuv3/aarch64/pmuv3.c
@@ -21,17 +21,6 @@
return mdcr_el2;
}
-void pmuv3_enable(cpu_context_t *ctx)
-{
-#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
- u_register_t mdcr_el2_val;
-
- mdcr_el2_val = read_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2);
- mdcr_el2_val = init_mdcr_el2_hpmn(mdcr_el2_val);
- write_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2, mdcr_el2_val);
-#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
-}
-
static u_register_t mtpmu_disable_el3(u_register_t mdcr_el3)
{
if (!is_feat_mtpmu_supported()) {
@@ -48,14 +37,20 @@
return mdcr_el3;
}
-void pmuv3_init_el3(void)
+void pmuv3_enable(cpu_context_t *ctx)
{
- u_register_t mdcr_el3 = read_mdcr_el3();
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
+ u_register_t mdcr_el2_val;
+
+ mdcr_el2_val = read_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2);
+ mdcr_el2_val = init_mdcr_el2_hpmn(mdcr_el2_val);
+ write_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2, mdcr_el2_val);
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
+
+ el3_state_t *state = get_el3state_ctx(ctx);
+ u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
/* ---------------------------------------------------------------------
- * Initialise MDCR_EL3, setting all fields rather than relying on hw.
- * Some fields are architecturally UNKNOWN on reset.
- *
* MDCR_EL3.MPMX: Set to zero to not affect event counters (when
* SPME = 0).
*
@@ -86,11 +81,15 @@
* MDCR_EL3.TPM: Set to zero so that EL0, EL1, and EL2 System register
* accesses to all Performance Monitors registers do not trap to EL3.
*/
- mdcr_el3 = (mdcr_el3 | MDCR_SCCD_BIT | MDCR_MCCD_BIT) &
+ mdcr_el3_val = (mdcr_el3_val | MDCR_SCCD_BIT | MDCR_MCCD_BIT) &
~(MDCR_MPMX_BIT | MDCR_SPME_BIT | MDCR_TPM_BIT);
- mdcr_el3 = mtpmu_disable_el3(mdcr_el3);
- write_mdcr_el3(mdcr_el3);
+ mdcr_el3_val = mtpmu_disable_el3(mdcr_el3_val);
+ write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
+}
+
+void pmuv3_init_el3(void)
+{
/* ---------------------------------------------------------------------
* Initialise PMCR_EL0 setting all fields rather than relying
* on hw. Some fields are architecturally UNKNOWN on reset.
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index d653222..d7df267 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,26 +9,10 @@
#include <arch.h>
#include <arch_features.h>
#include <arch_helpers.h>
-#include <lib/el3_runtime/pubsub.h>
#include <lib/extensions/spe.h>
#include <plat/common/platform.h>
-typedef struct spe_ctx {
- u_register_t pmblimitr_el1;
-} spe_ctx_t;
-
-static struct spe_ctx spe_ctxs[PLATFORM_CORE_COUNT];
-
-static inline void psb_csync(void)
-{
- /*
- * The assembler does not yet understand the psb csync mnemonic
- * so use the equivalent hint instruction.
- */
- __asm__ volatile("hint #17");
-}
-
void spe_enable(cpu_context_t *ctx)
{
el3_state_t *state = get_el3state_ctx(ctx);
@@ -58,18 +42,14 @@
u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
/*
- * MDCR_EL3.NSPB: Clear these bits to disable SPE feature, as it was enabled
- * for Non-secure state only. After clearing these bits Secure state owns
- * the Profiling Buffer and accesses to Statistical Profiling and Profiling
- * Buffer control registers at EL2 and EL1 generate Trap exceptions to EL3
- *
- * MDCR_EL3.NSPBE: Don't care as it was cleared during spe_enable and setting
- * this to 1 does not make sense as NSPBE{1} and NSPB{0b0x} is RESERVED.
+ * MDCR_EL3.{NSPB,NSPBE} = 0b00, 0b0
+ * Disable access of profiling buffer control registers from lower ELs
+ * in any security state. Secure state owns the buffer.
*
* MDCR_EL3.EnPMSN (ARM v8.7): Clear the bit to trap access of PMSNEVFR_EL1
* from EL2/EL1 to EL3.
*/
- mdcr_el3_val &= ~(MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT);
+ mdcr_el3_val &= ~(MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_NSPBE_BIT | MDCR_EnPMSN_BIT);
write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
}
@@ -90,63 +70,3 @@
v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
write_mdcr_el2(v);
}
-
-void spe_stop(void)
-{
- uint64_t v;
-
- /* Drain buffered data */
- psb_csync();
- dsbnsh();
-
- /* Disable profiling buffer */
- v = read_pmblimitr_el1();
- v &= ~(1ULL << 0);
- write_pmblimitr_el1(v);
- isb();
-}
-
-static void *spe_drain_buffers_hook(const void *arg)
-{
- if (!is_feat_spe_supported())
- return (void *)-1;
-
- /* Drain buffered data */
- psb_csync();
- dsbnsh();
-
- return (void *)0;
-}
-
-static void *spe_context_save(const void *arg)
-{
- unsigned int core_pos;
- struct spe_ctx *ctx;
-
- if (is_feat_spe_supported()) {
- core_pos = plat_my_core_pos();
- ctx = &spe_ctxs[core_pos];
- ctx->pmblimitr_el1 = read_pmblimitr_el1();
- }
-
- return NULL;
-}
-
-static void *spe_context_restore(const void *arg)
-{
- unsigned int core_pos;
- struct spe_ctx *ctx;
-
- if (is_feat_spe_supported()) {
- core_pos = plat_my_core_pos();
- ctx = &spe_ctxs[core_pos];
- write_pmblimitr_el1(ctx->pmblimitr_el1);
- }
-
- return NULL;
-}
-
-SUBSCRIBE_TO_EVENT(cm_entering_secure_world, spe_drain_buffers_hook);
-
-SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, spe_context_save);
-SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_finish, spe_context_restore);
diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
index 8c1c421..24d88ae 100644
--- a/lib/extensions/trbe/trbe.c
+++ b/lib/extensions/trbe/trbe.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,18 +7,8 @@
#include <arch.h>
#include <arch_features.h>
#include <arch_helpers.h>
-#include <lib/el3_runtime/pubsub.h>
#include <lib/extensions/trbe.h>
-static void tsb_csync(void)
-{
- /*
- * The assembler does not yet understand the tsb csync mnemonic
- * so use the equivalent hint instruction.
- */
- __asm__ volatile("hint #18");
-}
-
void trbe_enable(cpu_context_t *ctx)
{
el3_state_t *state = get_el3state_ctx(ctx);
@@ -45,13 +35,9 @@
u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
/*
- * MDCR_EL3.NSTBE = 0b0
- * Trace Buffer owning Security state is secure state. If FEAT_RME
- * is not implemented, this field is RES0.
- *
- * MDCR_EL3.NSTB = 0b00
- * Clear these bits to disable access of trace buffer control registers
- * from lower ELs in any security state.
+ * MDCR_EL3.{NSTBE,NSTB} = 0b0, 0b00
+ * Disable access of trace buffer control registers from lower ELs in
+ * any security state. Secure state owns the buffer.
*/
mdcr_el3_val &= ~(MDCR_NSTB(MDCR_NSTB_EL1));
mdcr_el3_val &= ~(MDCR_NSTBE_BIT);
@@ -68,21 +54,3 @@
*/
write_mdcr_el2(read_mdcr_el2() & ~MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1));
}
-
-static void *trbe_drain_trace_buffers_hook(const void *arg __unused)
-{
- if (is_feat_trbe_supported()) {
- /*
- * Before switching from normal world to secure world
- * the trace buffers need to be drained out to memory. This is
- * required to avoid an invalid memory access when TTBR is switched
- * for entry to S-EL1.
- */
- tsb_csync();
- dsbnsh();
- }
-
- return (void *)0;
-}
-
-SUBSCRIBE_TO_EVENT(cm_entering_secure_world, trbe_drain_trace_buffers_hook);
diff --git a/lib/hob/hob.c b/lib/hob/hob.c
new file mode 100644
index 0000000..60d8571
--- /dev/null
+++ b/lib/hob/hob.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2006-2014, Intel Corporation. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <arch.h>
+#include <common/debug.h>
+#include <lib/hob/hob.h>
+#include <lib/hob/hob_guid.h>
+#include <lib/hob/mmram.h>
+#include <lib/utils_def.h>
+
+#define ALIGN_UP(x, a) ((x + (a - 1)) & ~(a - 1))
+
+static void *_create_hob(struct efi_hob_handoff_info_table *hob_table,
+ uint16_t hob_type, uint16_t hob_length)
+{
+ size_t free_mem_size;
+ struct efi_hob_generic_header *new_hob;
+ struct efi_hob_generic_header *hob_end;
+
+ if ((hob_table == NULL) || (hob_length == 0)) {
+ return NULL;
+ }
+
+ hob_length = ALIGN_UP(hob_length, 8);
+ free_mem_size = hob_table->efi_free_memory_top - hob_table->efi_free_memory_bottom;
+
+ /**
+ * hob_length already including sizeof(efi_hob_generic_header).
+ * See the each export interface create_xxx_hob.
+ */
+ if ((size_t) hob_length > free_mem_size) {
+ return NULL;
+ }
+
+ new_hob = (struct efi_hob_generic_header *) hob_table->efi_end_of_hob_list;
+ new_hob->hob_type = hob_type;
+ new_hob->hob_length = hob_length;
+ new_hob->reserved = 0x00;
+
+ hob_end = (struct efi_hob_generic_header *) (hob_table->efi_end_of_hob_list + hob_length);
+ hob_end->hob_type = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ hob_end->hob_length = sizeof(struct efi_hob_generic_header);
+ hob_end->reserved = 0x00;
+
+ hob_table->efi_end_of_hob_list = (efi_physical_address_t) hob_end;
+ hob_table->efi_free_memory_bottom = (efi_physical_address_t) (hob_end + 1);
+
+ return new_hob;
+}
+
+/*
+ * Create PHIT HOB list.
+ *
+ * On success, return the address PHIT HOB list
+ * On error, return NULL.
+ *
+ * efi_memory_begin
+ * Base address for partition.
+ * efi_memory_length
+ * Size of memory for patition.
+ * efi_free_memory_bottom
+ * Base address PHIT HOB list can be allocated
+ * efi_free_memory_length.
+ * Maximum size of PHIT HOB list can have
+ */
+struct efi_hob_handoff_info_table *create_hob_list(
+ efi_physical_address_t efi_memory_begin, size_t efi_memory_length,
+ efi_physical_address_t efi_free_memory_bottom, size_t efi_free_memory_length)
+{
+ struct efi_hob_handoff_info_table *hob_table;
+ struct efi_hob_generic_header *hob_end;
+
+ if ((efi_memory_begin == 0) || (efi_free_memory_bottom == 0) ||
+ (efi_memory_length == 0) || (efi_free_memory_length == 0)) {
+ return NULL;
+ }
+
+ hob_table = (struct efi_hob_handoff_info_table *) efi_free_memory_bottom;
+ hob_end = (struct efi_hob_generic_header *) (hob_table + 1);
+
+ hob_table->header.hob_type = EFI_HOB_TYPE_HANDOFF;
+ hob_table->header.hob_length = sizeof(struct efi_hob_handoff_info_table);
+ hob_table->header.reserved = 0;
+
+ hob_end->hob_type = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ hob_end->hob_length = sizeof(struct efi_hob_generic_header);
+ hob_end->reserved = 0;
+
+ hob_table->version = EFI_HOB_HANDOFF_TABLE_VERSION;
+ hob_table->boot_mode = EFI_BOOT_WITH_FULL_CONFIGURATION;
+
+ hob_table->efi_memory_top = efi_memory_begin + efi_memory_length;
+ hob_table->efi_memory_bottom = efi_memory_begin;
+ hob_table->efi_free_memory_top = efi_memory_begin + efi_free_memory_length;
+ hob_table->efi_free_memory_bottom = (efi_physical_address_t) (hob_end + 1);
+ hob_table->efi_end_of_hob_list = (efi_physical_address_t) hob_end;
+
+ return hob_table;
+}
+
+/*
+ * Create resource description HOB in PHIT HOB list.
+ *
+ * On success, return 0.
+ * On error, return error code.
+ *
+ * hob_table
+ * Address of PHIT HOB list
+ * resource_type
+ * Resource type see EFI_RESOURCE_* in the include/lib/hob/efi_types.h
+ * resource_attribute
+ * Resource attribute see EFI_RESOURCE_ATTRIBUTES_*
+ * in the include/lib/hob/efi_types.h
+ * phy_addr_start
+ * Physical base address of resource
+ * resource_length
+ * Size of resource
+ */
+int create_resource_descriptor_hob(
+ struct efi_hob_handoff_info_table *hob_table,
+ efi_resource_type_t resource_type,
+ efi_resource_attribute_type_t resource_attribute,
+ efi_physical_address_t phy_addr_start,
+ uint64_t resource_length)
+{
+ struct efi_hob_resource_descriptor *rd_hop;
+
+ rd_hop = _create_hob(hob_table, EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
+ sizeof(struct efi_hob_resource_descriptor));
+
+ if (rd_hop == NULL) {
+ ERROR("No space for creating resource descriptor type hob...\n");
+ return -ENOMEM;
+ }
+
+ rd_hop->resource_type = resource_type;
+ rd_hop->resource_attribute = resource_attribute;
+ rd_hop->physical_start = phy_addr_start;
+ rd_hop->resource_length = resource_length;
+ memset(&rd_hop->owner, 0, sizeof(struct efi_guid));
+
+ return 0;
+}
+
+/*
+ * Create GUID HOB in PHIT HOB list.
+ *
+ * On success, return 0.
+ * On error, return error code.
+ *
+ * hob_table
+ * Address of PHIT HOB list
+ * guid
+ * guid.
+ * data length
+ * Size of data
+ * data
+ * Data
+ */
+int create_guid_hob(struct efi_hob_handoff_info_table *hob_table,
+ struct efi_guid *guid, uint16_t data_length, void **data)
+{
+ struct efi_hob_guid_type *guid_hob;
+ uint16_t hob_length;
+
+ hob_length = data_length + sizeof(struct efi_hob_guid_type);
+
+ if ((guid == NULL) || (data == NULL) || (hob_length < data_length)) {
+ return -EINVAL;
+ }
+
+ guid_hob = _create_hob(hob_table, EFI_HOB_TYPE_GUID_EXTENSION, hob_length);
+ if (guid_hob == NULL) {
+ ERROR("No space for creating guid type hob...\n");
+ return -ENOMEM;
+ }
+
+ memcpy(&guid_hob->name, guid, sizeof(struct efi_guid));
+
+ *data = (void *) (guid_hob + 1);
+
+ return 0;
+}
+
+/*
+ * Create Firmware Volume HOB in PHIT HOB list.
+ *
+ * On success, return 0.
+ * On error, return error code.
+ *
+ * hob_table
+ * Address of PHIT HOB list
+ * base_addr
+ * Base address of firmware volume
+ * size
+ * Size of Firmware Volume
+ */
+int create_fv_hob(struct efi_hob_handoff_info_table *hob_table,
+ efi_physical_address_t base_addr, uint64_t size)
+{
+ struct efi_hob_firmware_volume *fv_hob;
+
+ fv_hob = _create_hob(hob_table, EFI_HOB_TYPE_FV,
+ sizeof(struct efi_hob_firmware_volume));
+ if (fv_hob == NULL) {
+ ERROR("No space for creating fv type hob...\n");
+ return -ENOMEM;
+ }
+
+ fv_hob->base_address = base_addr;
+ fv_hob->length = size;
+
+ return 0;
+}
diff --git a/lib/hob/hob.mk b/lib/hob/hob.mk
new file mode 100644
index 0000000..332738b
--- /dev/null
+++ b/lib/hob/hob.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+HOB_LIST_SOURCES += $(addprefix lib/hob/, \
+ hob.c)
+
+INCLUDES += -Iinclude/lib/hob
+
+BL31_SOURCES += $(HOB_LIST_SOURCES)
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 375cdba..93d71b8 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,8 @@
#include <drivers/delay_timer.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/extensions/spe.h>
+#include <lib/pmf/pmf.h>
+#include <lib/runtime_instr.h>
#include <lib/utils.h>
#include <plat/common/platform.h>
@@ -170,9 +172,9 @@
* Returns 1 (true) if the current CPU is the last ON CPU or 0 (false)
* otherwise.
******************************************************************************/
-static bool psci_is_last_cpu_to_idle_at_pwrlvl(unsigned int end_pwrlvl)
+static bool psci_is_last_cpu_to_idle_at_pwrlvl(unsigned int my_idx, unsigned int end_pwrlvl)
{
- unsigned int my_idx, lvl;
+ unsigned int lvl;
unsigned int parent_idx = 0;
unsigned int cpu_start_idx, ncpus, cpu_idx;
plat_local_state_t local_state;
@@ -181,7 +183,6 @@
return true;
}
- my_idx = plat_my_core_pos();
parent_idx = psci_cpu_pd_nodes[my_idx].parent_node;
for (lvl = PSCI_CPU_PWR_LVL + U(1); lvl < end_pwrlvl; lvl++) {
parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
@@ -212,11 +213,9 @@
* turned OFF and the current CPU is the last running CPU in the system.
* Returns true, if the current CPU is the last ON CPU or false otherwise.
******************************************************************************/
-bool psci_is_last_on_cpu(void)
+bool psci_is_last_on_cpu(unsigned int my_idx)
{
- unsigned int cpu_idx, my_idx = plat_my_core_pos();
-
- for (cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
+ for (unsigned int cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
if (cpu_idx == my_idx) {
assert(psci_get_aff_info_state() == AFF_STATE_ON);
continue;
@@ -260,13 +259,9 @@
/*
* Assume that this cpu was suspended and retrieve its target power
- * level. If it is invalid then it could only have been turned off
- * earlier. PLAT_MAX_PWR_LVL will be the highest power level a
- * cpu can be turned off to.
+ * level. If it wasn't, the cpu is off so this will be PLAT_MAX_PWR_LVL.
*/
pwrlvl = psci_get_suspend_pwrlvl();
- if (pwrlvl == PSCI_INVALID_PWR_LVL)
- pwrlvl = PLAT_MAX_PWR_LVL;
assert(pwrlvl < PSCI_INVALID_PWR_LVL);
return pwrlvl;
}
@@ -428,14 +423,14 @@
* function will be called after a cpu is powered on to find the local state
* each power domain has emerged from.
*****************************************************************************/
-void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
+void psci_get_target_local_pwr_states(unsigned int cpu_idx, unsigned int end_pwrlvl,
psci_power_state_t *target_state)
{
unsigned int parent_idx, lvl;
plat_local_state_t *pd_state = target_state->pwr_domain_state;
pd_state[PSCI_CPU_PWR_LVL] = psci_get_cpu_local_state();
- parent_idx = psci_cpu_pd_nodes[plat_my_core_pos()].parent_node;
+ parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
/* Copy the local power state from node to state_info */
for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
@@ -454,7 +449,7 @@
* enter. This function will be called after coordination of requested power
* states has been done for each power level.
*****************************************************************************/
-void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
+void psci_set_target_local_pwr_states(unsigned int cpu_idx, unsigned int end_pwrlvl,
const psci_power_state_t *target_state)
{
unsigned int parent_idx, lvl;
@@ -468,7 +463,7 @@
*/
psci_flush_cpu_data(psci_svc_cpu_data.local_state);
- parent_idx = psci_cpu_pd_nodes[plat_my_core_pos()].parent_node;
+ parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
/* Copy the local_state from state_info */
for (lvl = 1U; lvl <= end_pwrlvl; lvl++) {
@@ -500,9 +495,9 @@
* affinity info state, target power state and requested power state for the
* current CPU and all its ancestor power domains to RUN.
*****************************************************************************/
-void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl)
+void psci_set_pwr_domains_to_run(unsigned int cpu_idx, unsigned int end_pwrlvl)
{
- unsigned int parent_idx, cpu_idx = plat_my_core_pos(), lvl;
+ unsigned int parent_idx, lvl;
parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
/* Reset the local_state to RUN for the non cpu power domains. */
@@ -544,10 +539,10 @@
* This function will only be invoked with data cache enabled and while
* powering down a core.
*****************************************************************************/
-void psci_do_state_coordination(unsigned int end_pwrlvl,
+void psci_do_state_coordination(unsigned int cpu_idx, unsigned int end_pwrlvl,
psci_power_state_t *state_info)
{
- unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
+ unsigned int lvl, parent_idx;
unsigned int start_idx;
unsigned int ncpus;
plat_local_state_t target_state, *req_states;
@@ -620,11 +615,11 @@
* This function will only be invoked with data cache enabled and while
* powering down a core.
*****************************************************************************/
-int psci_validate_state_coordination(unsigned int end_pwrlvl,
+int psci_validate_state_coordination(unsigned int cpu_idx, unsigned int end_pwrlvl,
psci_power_state_t *state_info)
{
int rc = PSCI_E_SUCCESS;
- unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
+ unsigned int lvl, parent_idx;
unsigned int start_idx;
unsigned int ncpus;
plat_local_state_t target_state, *req_states;
@@ -674,7 +669,7 @@
* specified power level.
*/
lvl = state_info->last_at_pwrlvl;
- if (!psci_is_last_cpu_to_idle_at_pwrlvl(lvl)) {
+ if (!psci_is_last_cpu_to_idle_at_pwrlvl(cpu_idx, lvl)) {
rc = PSCI_E_DENIED;
}
@@ -1004,7 +999,7 @@
*/
psci_acquire_pwr_domain_locks(end_pwrlvl, parent_nodes);
- psci_get_target_local_pwr_states(end_pwrlvl, &state_info);
+ psci_get_target_local_pwr_states(cpu_idx, end_pwrlvl, &state_info);
#if ENABLE_PSCI_STAT
plat_psci_stat_accounting_stop(&state_info);
@@ -1025,7 +1020,7 @@
if (psci_get_aff_info_state() == AFF_STATE_ON_PENDING)
psci_cpu_on_finish(cpu_idx, &state_info);
else
- psci_cpu_suspend_finish(cpu_idx, &state_info);
+ psci_cpu_suspend_to_powerdown_finish(cpu_idx, &state_info);
/*
* Generic management: Now we just need to retrieve the
@@ -1038,16 +1033,10 @@
* Set the requested and target state of this CPU and all the higher
* power domains which are ancestors of this CPU to run.
*/
- psci_set_pwr_domains_to_run(end_pwrlvl);
+ psci_set_pwr_domains_to_run(cpu_idx, end_pwrlvl);
#if ENABLE_PSCI_STAT
- /*
- * Update PSCI stats.
- * Caches are off when writing stats data on the power down path.
- * Since caches are now enabled, it's necessary to do cache
- * maintenance before reading that same data.
- */
- psci_stats_update_pwr_up(end_pwrlvl, &state_info);
+ psci_stats_update_pwr_up(cpu_idx, end_pwrlvl, &state_info);
#endif
/*
@@ -1169,7 +1158,16 @@
******************************************************************************/
void psci_pwrdown_cpu(unsigned int power_level)
{
- psci_do_manage_extensions();
+#if ENABLE_RUNTIME_INSTRUMENTATION
+
+ /*
+ * Flush cache line so that even if CPU power down happens
+ * the timestamp update is reflected in memory.
+ */
+ PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+ RT_INSTR_ENTER_CFLUSH,
+ PMF_CACHE_MAINT);
+#endif
#if HW_ASSISTED_COHERENCY
/*
@@ -1190,6 +1188,12 @@
*/
psci_do_pwrdown_cache_maintenance(power_level);
#endif
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+ PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+ RT_INSTR_EXIT_CFLUSH,
+ PMF_NO_CACHE_MAINT);
+#endif
}
/*******************************************************************************
@@ -1202,15 +1206,11 @@
* The function returns 'PSCI_E_DENIED' if some cores failed to stop within the
* given timeout.
******************************************************************************/
-int psci_stop_other_cores(unsigned int wait_ms,
+int psci_stop_other_cores(unsigned int this_cpu_idx, unsigned int wait_ms,
void (*stop_func)(u_register_t mpidr))
{
- unsigned int idx, this_cpu_idx;
-
- this_cpu_idx = plat_my_core_pos();
-
/* Invoke stop_func for each core */
- for (idx = 0U; idx < psci_plat_core_count; idx++) {
+ for (unsigned int idx = 0U; idx < psci_plat_core_count; idx++) {
/* skip current CPU */
if (idx == this_cpu_idx) {
continue;
@@ -1224,11 +1224,11 @@
/* Need to wait for other cores to shutdown */
if (wait_ms != 0U) {
- while ((wait_ms-- != 0U) && (!psci_is_last_on_cpu())) {
+ while ((wait_ms-- != 0U) && (!psci_is_last_on_cpu(this_cpu_idx))) {
mdelay(1U);
}
- if (!psci_is_last_on_cpu()) {
+ if (!psci_is_last_on_cpu(this_cpu_idx)) {
WARN("Failed to stop all cores!\n");
psci_print_power_domain_map();
return PSCI_E_DENIED;
@@ -1246,16 +1246,15 @@
* This API has following differences with psci_is_last_on_cpu
* 1. PSCI states are locked
******************************************************************************/
-bool psci_is_last_on_cpu_safe(void)
+bool psci_is_last_on_cpu_safe(unsigned int this_core)
{
- unsigned int this_core = plat_my_core_pos();
unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
psci_get_parent_pwr_domain_nodes(this_core, PLAT_MAX_PWR_LVL, parent_nodes);
psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
- if (!psci_is_last_on_cpu()) {
+ if (!psci_is_last_on_cpu(this_core)) {
psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
return false;
}
@@ -1272,9 +1271,8 @@
* This API has following differences with psci_are_all_cpus_on
* 1. PSCI states are locked
******************************************************************************/
-bool psci_are_all_cpus_on_safe(void)
+bool psci_are_all_cpus_on_safe(unsigned int this_core)
{
- unsigned int this_core = plat_my_core_pos();
unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
psci_get_parent_pwr_domain_nodes(this_core, PLAT_MAX_PWR_LVL, parent_nodes);
@@ -1290,20 +1288,3 @@
return true;
}
-
-/*******************************************************************************
- * This function performs architectural feature specific management.
- * It ensures the architectural features are disabled during cpu
- * power off/suspend operations.
- ******************************************************************************/
-void psci_do_manage_extensions(void)
-{
- /*
- * On power down we need to disable statistical profiling extensions
- * before exiting coherency.
- */
- if (is_feat_spe_supported()) {
- spe_stop();
- }
-
-}
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index a015531..7ac0e02 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -59,8 +59,8 @@
entry_point_info_t ep;
psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
plat_local_state_t cpu_pd_state;
-#if PSCI_OS_INIT_MODE
unsigned int cpu_idx = plat_my_core_pos();
+#if PSCI_OS_INIT_MODE
plat_local_state_t prev[PLAT_MAX_PWR_LVL];
#endif
@@ -145,7 +145,7 @@
plat_psci_stat_accounting_stop(&state_info);
/* Update PSCI stats */
- psci_stats_update_pwr_up(PSCI_CPU_PWR_LVL, &state_info);
+ psci_stats_update_pwr_up(cpu_idx, PSCI_CPU_PWR_LVL, &state_info);
#endif
return PSCI_E_SUCCESS;
@@ -167,7 +167,8 @@
* might return if the power down was abandoned for any reason, e.g.
* arrival of an interrupt
*/
- rc = psci_cpu_suspend_start(&ep,
+ rc = psci_cpu_suspend_start(cpu_idx,
+ &ep,
target_pwrlvl,
&state_info,
is_power_down_state);
@@ -181,9 +182,10 @@
int rc;
psci_power_state_t state_info;
entry_point_info_t ep;
+ unsigned int cpu_idx = plat_my_core_pos();
/* Check if the current CPU is the last ON CPU in the system */
- if (!psci_is_last_on_cpu())
+ if (!psci_is_last_on_cpu(cpu_idx))
return PSCI_E_DENIED;
/* Validate the entry point and get the entry_point_info */
@@ -212,7 +214,8 @@
* might return if the power down was abandoned for any reason, e.g.
* arrival of an interrupt
*/
- rc = psci_cpu_suspend_start(&ep,
+ rc = psci_cpu_suspend_start(cpu_idx,
+ &ep,
PLAT_MAX_PWR_LVL,
&state_info,
PSTATE_TYPE_POWERDOWN);
@@ -399,9 +402,11 @@
return PSCI_E_SUCCESS;
}
+ unsigned int this_core = plat_my_core_pos();
+
if (mode == PLAT_COORD) {
/* Check if the current CPU is the last ON CPU in the system */
- if (!psci_is_last_on_cpu_safe()) {
+ if (!psci_is_last_on_cpu_safe(this_core)) {
return PSCI_E_DENIED;
}
}
@@ -411,8 +416,8 @@
* Check if all CPUs in the system are ON or if the current
* CPU is the last ON CPU in the system.
*/
- if (!(psci_are_all_cpus_on_safe() ||
- psci_is_last_on_cpu_safe())) {
+ if (!(psci_are_all_cpus_on_safe(this_core) ||
+ psci_is_last_on_cpu_safe(this_core))) {
return PSCI_E_DENIED;
}
}
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index f83753f..d40ee3f 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -102,25 +102,14 @@
* it returns the negotiated state info for each power level upto
* the end level specified.
*/
- psci_do_state_coordination(end_pwrlvl, &state_info);
+ psci_do_state_coordination(idx, end_pwrlvl, &state_info);
/* Update the target state in the power domain nodes */
- psci_set_target_local_pwr_states(end_pwrlvl, &state_info);
+ psci_set_target_local_pwr_states(idx, end_pwrlvl, &state_info);
#if ENABLE_PSCI_STAT
/* Update the last cpu for each level till end_pwrlvl */
- psci_stats_update_pwr_down(end_pwrlvl, &state_info);
-#endif
-
-#if ENABLE_RUNTIME_INSTRUMENTATION
-
- /*
- * Flush cache line so that even if CPU power down happens
- * the timestamp update is reflected in memory.
- */
- PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
- RT_INSTR_ENTER_CFLUSH,
- PMF_CACHE_MAINT);
+ psci_stats_update_pwr_down(idx, end_pwrlvl, &state_info);
#endif
/*
@@ -128,12 +117,6 @@
*/
psci_pwrdown_cpu(psci_find_max_off_lvl(&state_info));
-#if ENABLE_RUNTIME_INSTRUMENTATION
- PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
- RT_INSTR_EXIT_CFLUSH,
- PMF_NO_CACHE_MAINT);
-#endif
-
/*
* Plat. management: Perform platform specific actions to turn this
* cpu off e.g. exit cpu coherency, program the power controller etc.
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 2eb4a9b..6622755 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -295,19 +295,19 @@
void psci_restore_req_local_pwr_states(unsigned int cpu_idx,
plat_local_state_t *prev);
#endif
-void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
+void psci_get_target_local_pwr_states(unsigned int cpu_idx, unsigned int end_pwrlvl,
psci_power_state_t *target_state);
-void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
+void psci_set_target_local_pwr_states(unsigned int cpu_idx, unsigned int end_pwrlvl,
const psci_power_state_t *target_state);
int psci_validate_entry_point(entry_point_info_t *ep,
uintptr_t entrypoint, u_register_t context_id);
void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
unsigned int end_lvl,
unsigned int *node_index);
-void psci_do_state_coordination(unsigned int end_pwrlvl,
+void psci_do_state_coordination(unsigned int cpu_idx, unsigned int end_pwrlvl,
psci_power_state_t *state_info);
#if PSCI_OS_INIT_MODE
-int psci_validate_state_coordination(unsigned int end_pwrlvl,
+int psci_validate_state_coordination(unsigned int cpu_idx, unsigned int end_pwrlvl,
psci_power_state_t *state_info);
#endif
void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl,
@@ -318,9 +318,9 @@
unsigned int is_power_down_state);
unsigned int psci_find_max_off_lvl(const psci_power_state_t *state_info);
unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info);
-void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl);
+void psci_set_pwr_domains_to_run(unsigned int cpu_idx, unsigned int end_pwrlvl);
void psci_print_power_domain_map(void);
-bool psci_is_last_on_cpu(void);
+bool psci_is_last_on_cpu(unsigned int my_idx);
int psci_spd_migrate_info(u_register_t *mpidr);
/*
@@ -343,12 +343,13 @@
int psci_do_cpu_off(unsigned int end_pwrlvl);
/* Private exported functions from psci_suspend.c */
-int psci_cpu_suspend_start(const entry_point_info_t *ep,
+int psci_cpu_suspend_start(unsigned int idx,
+ const entry_point_info_t *ep,
unsigned int end_pwrlvl,
psci_power_state_t *state_info,
unsigned int is_power_down_state);
-void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info);
+void psci_cpu_suspend_to_powerdown_finish(unsigned int cpu_idx, const psci_power_state_t *state_info);
/* Private exported functions from psci_helpers.S */
void psci_do_pwrdown_cache_maintenance(unsigned int pwr_level);
@@ -360,9 +361,9 @@
u_register_t psci_system_reset2(uint32_t reset_type, u_register_t cookie);
/* Private exported functions from psci_stat.c */
-void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
+void psci_stats_update_pwr_down(unsigned int cpu_idx, unsigned int end_pwrlvl,
const psci_power_state_t *state_info);
-void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
+void psci_stats_update_pwr_up(unsigned int cpu_idx, unsigned int end_pwrlvl,
const psci_power_state_t *state_info);
u_register_t psci_stat_residency(u_register_t target_cpu,
unsigned int power_state);
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index 6bf1ff4..a81ba4a 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -68,8 +68,8 @@
/* Set the Affinity Info for the cores as OFF */
svc_cpu_data->aff_info_state = AFF_STATE_OFF;
- /* Invalidate the suspend level for the cpu */
- svc_cpu_data->target_pwrlvl = PSCI_INVALID_PWR_LVL;
+ /* Default to the highest power level when the cpu is not suspending */
+ svc_cpu_data->target_pwrlvl = PLAT_MAX_PWR_LVL;
/* Set the power state to OFF state */
svc_cpu_data->local_state = PLAT_MAX_OFF_STATE;
@@ -202,6 +202,7 @@
int __init psci_setup(const psci_lib_args_t *lib_args)
{
const unsigned char *topology_tree;
+ unsigned int cpu_idx = plat_my_core_pos();
assert(VERIFY_PSCI_LIB_ARGS_V1(lib_args));
@@ -218,7 +219,7 @@
psci_update_pwrlvl_limits();
/* Populate the mpidr field of cpu node for this CPU */
- psci_cpu_pd_nodes[plat_my_core_pos()].mpidr =
+ psci_cpu_pd_nodes[cpu_idx].mpidr =
read_mpidr() & MPIDR_AFFINITY_MASK;
psci_init_req_local_pwr_states();
@@ -227,7 +228,7 @@
* Set the requested and target state of this CPU and all the higher
* power domain levels for this CPU to run.
*/
- psci_set_pwr_domains_to_run(PLAT_MAX_PWR_LVL);
+ psci_set_pwr_domains_to_run(cpu_idx, PLAT_MAX_PWR_LVL);
(void) plat_setup_psci_ops((uintptr_t)lib_args->mailbox_ep,
&psci_plat_pm_ops);
diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c
index bedb816..1225557 100644
--- a/lib/psci/psci_stat.c
+++ b/lib/psci/psci_stat.c
@@ -73,11 +73,10 @@
* This function will only be invoked with data cache enabled and while
* powering down a core.
******************************************************************************/
-void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
+void psci_stats_update_pwr_down(unsigned int cpu_idx, unsigned int end_pwrlvl,
const psci_power_state_t *state_info)
{
unsigned int lvl, parent_idx;
- unsigned int cpu_idx = plat_my_core_pos();
assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
assert(state_info != NULL);
@@ -106,11 +105,10 @@
* and NON-CPU power domains.
* It is called with caches enabled and locks acquired(for NON-CPU domain)
******************************************************************************/
-void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
+void psci_stats_update_pwr_up(unsigned int cpu_idx, unsigned int end_pwrlvl,
const psci_power_state_t *state_info)
{
unsigned int lvl, parent_idx;
- unsigned int cpu_idx = plat_my_core_pos();
int stat_idx;
plat_local_state_t local_state;
u_register_t residency;
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index cb12b83..2aadbfd 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,42 +25,18 @@
* This function does generic and platform specific operations after a wake-up
* from standby/retention states at multiple power levels.
******************************************************************************/
-static void psci_suspend_to_standby_finisher(unsigned int cpu_idx,
- unsigned int end_pwrlvl)
+static void psci_cpu_suspend_to_standby_finish(unsigned int cpu_idx,
+ unsigned int end_pwrlvl,
+ psci_power_state_t *state_info)
{
- unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
- psci_power_state_t state_info;
-
- /* Get the parent nodes */
- psci_get_parent_pwr_domain_nodes(cpu_idx, end_pwrlvl, parent_nodes);
-
- psci_acquire_pwr_domain_locks(end_pwrlvl, parent_nodes);
-
- /*
- * Find out which retention states this CPU has exited from until the
- * 'end_pwrlvl'. The exit retention state could be deeper than the entry
- * state as a result of state coordination amongst other CPUs post wfi.
- */
- psci_get_target_local_pwr_states(end_pwrlvl, &state_info);
-
-#if ENABLE_PSCI_STAT
- plat_psci_stat_accounting_stop(&state_info);
- psci_stats_update_pwr_up(end_pwrlvl, &state_info);
-#endif
-
/*
* Plat. management: Allow the platform to do operations
* on waking up from retention.
*/
- psci_plat_pm_ops->pwr_domain_suspend_finish(&state_info);
+ psci_plat_pm_ops->pwr_domain_suspend_finish(state_info);
- /*
- * Set the requested and target state of this CPU and all the higher
- * power domain levels for this CPU to run.
- */
- psci_set_pwr_domains_to_run(end_pwrlvl);
-
- psci_release_pwr_domain_locks(end_pwrlvl, parent_nodes);
+ /* This loses its meaning when not suspending, reset so it's correct for OFF */
+ psci_set_suspend_pwrlvl(PLAT_MAX_PWR_LVL);
}
/*******************************************************************************
@@ -116,29 +92,12 @@
*/
cm_init_my_context(ep);
-#if ENABLE_RUNTIME_INSTRUMENTATION
-
- /*
- * Flush cache line so that even if CPU power down happens
- * the timestamp update is reflected in memory.
- */
- PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
- RT_INSTR_ENTER_CFLUSH,
- PMF_CACHE_MAINT);
-#endif
-
/*
* Arch. management. Initiate power down sequence.
* TODO : Introduce a mechanism to query the cache level to flush
* and the cpu-ops power down to perform from the platform.
*/
psci_pwrdown_cpu(max_off_lvl);
-
-#if ENABLE_RUNTIME_INSTRUMENTATION
- PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
- RT_INSTR_EXIT_CFLUSH,
- PMF_NO_CACHE_MAINT);
-#endif
}
/*******************************************************************************
@@ -159,14 +118,14 @@
* the state transition has been done, no further error is expected and it is
* not possible to undo any of the actions taken beyond that point.
******************************************************************************/
-int psci_cpu_suspend_start(const entry_point_info_t *ep,
+int psci_cpu_suspend_start(unsigned int idx,
+ const entry_point_info_t *ep,
unsigned int end_pwrlvl,
psci_power_state_t *state_info,
unsigned int is_power_down_state)
{
int rc = PSCI_E_SUCCESS;
bool skip_wfi = false;
- unsigned int idx = plat_my_core_pos();
unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
/*
@@ -202,7 +161,7 @@
* This function validates the requested state info for
* OS-initiated mode.
*/
- rc = psci_validate_state_coordination(end_pwrlvl, state_info);
+ rc = psci_validate_state_coordination(idx, end_pwrlvl, state_info);
if (rc != PSCI_E_SUCCESS) {
skip_wfi = true;
goto exit;
@@ -214,7 +173,7 @@
* it returns the negotiated state info for each power level upto
* the end level specified.
*/
- psci_do_state_coordination(end_pwrlvl, state_info);
+ psci_do_state_coordination(idx, end_pwrlvl, state_info);
#if PSCI_OS_INIT_MODE
}
#endif
@@ -230,11 +189,11 @@
#endif
/* Update the target state in the power domain nodes */
- psci_set_target_local_pwr_states(end_pwrlvl, state_info);
+ psci_set_target_local_pwr_states(idx, end_pwrlvl, state_info);
#if ENABLE_PSCI_STAT
/* Update the last cpu for each level till end_pwrlvl */
- psci_stats_update_pwr_down(end_pwrlvl, state_info);
+ psci_stats_update_pwr_down(idx, end_pwrlvl, state_info);
#endif
if (is_power_down_state != 0U)
@@ -304,11 +263,32 @@
PMF_NO_CACHE_MAINT);
#endif
+ psci_acquire_pwr_domain_locks(end_pwrlvl, parent_nodes);
+ /*
+ * Find out which retention states this CPU has exited from until the
+ * 'end_pwrlvl'. The exit retention state could be deeper than the entry
+ * state as a result of state coordination amongst other CPUs post wfi.
+ */
+ psci_get_target_local_pwr_states(idx, end_pwrlvl, state_info);
+
+#if ENABLE_PSCI_STAT
+ plat_psci_stat_accounting_stop(state_info);
+ psci_stats_update_pwr_up(idx, end_pwrlvl, state_info);
+#endif
+
/*
* After we wake up from context retaining suspend, call the
* context retaining suspend finisher.
*/
- psci_suspend_to_standby_finisher(idx, end_pwrlvl);
+ psci_cpu_suspend_to_standby_finish(idx, end_pwrlvl, state_info);
+
+ /*
+ * Set the requested and target state of this CPU and all the higher
+ * power domain levels for this CPU to run.
+ */
+ psci_set_pwr_domains_to_run(idx, end_pwrlvl);
+
+ psci_release_pwr_domain_locks(end_pwrlvl, parent_nodes);
return rc;
}
@@ -318,7 +298,7 @@
* are called by the common finisher routine in psci_common.c. The `state_info`
* is the psci_power_state from which this CPU has woken up from.
******************************************************************************/
-void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info)
+void psci_cpu_suspend_to_powerdown_finish(unsigned int cpu_idx, const psci_power_state_t *state_info)
{
unsigned int counter_freq;
unsigned int max_off_lvl;
@@ -363,8 +343,8 @@
psci_spd_pm->svc_suspend_finish(max_off_lvl);
}
- /* Invalidate the suspend level for the cpu */
- psci_set_suspend_pwrlvl(PSCI_INVALID_PWR_LVL);
+ /* This loses its meaning when not suspending, reset so it's correct for OFF */
+ psci_set_suspend_pwrlvl(PLAT_MAX_PWR_LVL);
PUBLISH_EVENT(psci_suspend_pwrdown_finish);
}
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index bc31a2f..01a0395 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -12,17 +12,26 @@
BUILD_DIR = $(BUILD_PLAT)/romlib
LIB_DIR = $(BUILD_PLAT)/lib
WRAPPER_DIR = $(BUILD_PLAT)/libwrapper
-LIBS = $(LIB_DIR)/libmbedtls.a $(LIB_DIR)/libfdt.a $(LIB_DIR)/libc.a
+LIBS = $(LIB_DIR)/libfdt.a $(LIB_DIR)/libc.a
INC = $(INCLUDES:-I%=-I../../%)
PPFLAGS = $(INC) $(DEFINES) -P -x assembler-with-cpp -D__LINKER__ -MD -MP -MT $(BUILD_DIR)/romlib.ld
OBJS = $(BUILD_DIR)/jmptbl.o $(BUILD_DIR)/init.o
MAPFILE = $(BUILD_PLAT)/romlib/romlib.map
-ifneq ($(PLAT_DIR),)
- WRAPPER_SOURCES = $(sort $(shell $(ROMLIB_GEN) genwrappers -b $\
- $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i))
+PROCESSED_JMPTBL = ../../$(PLAT_DIR)/jmptbl.i
- WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
+# Determine if mbedtls is needed
+ifneq ($(filter $(CRYPTO_SUPPORT),1 2 3),)
+ PROCESSED_JMPTBL = $(BUILD_DIR)/jmptbl_processed.i
+ $(shell mkdir -p $(BUILD_DIR) && cat ../../$(PLAT_DIR)/jmptbl.i ../../$(PLAT_DIR)/jmptbl_mbedtls.i > $(BUILD_DIR)/jmptbl_processed.i)
+ LIBS += $(LIB_DIR)/libmbedtls.a
+endif
+
+ifneq ($(PLAT_DIR),)
+ # Generate wrapper sources and objects
+ WRAPPER_SOURCES = $(sort $(shell $(ROMLIB_GEN) genwrappers -b $\
+ $(WRAPPER_DIR) --list $(PROCESSED_JMPTBL)))
+ WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
endif
LDFLAGS := -Wl,--gc-sections -nostdlib
@@ -69,21 +78,21 @@
$(s)echo " AR $@"
$(q)$(aarch64-ar) -rc $@ $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
-$(BUILD_DIR)/jmptbl.i: ../../$(PLAT_DIR)/jmptbl.i | $$(@D)/
+$(BUILD_DIR)/jmptbl.i: $(PROCESSED_JMPTBL) | $$(@D)/
$(s)echo " PRE $@"
$(q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
-$(WRAPPER_SOURCES) $&: $(BUILD_DIR)/jmptbl.i | $$(@D)/
+$(WRAPPER_SOURCES) $&: $(PROCESSED_JMPTBL) | $$(@D)/
$(s)echo " WRP $<"
$(q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
$(WRAPPER_OBJS): $(WRAPPER_DIR)/%.o: $(WRAPPER_DIR)/%.s | $$(@D)/
-$(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i | $$(@D)/
+$(BUILD_DIR)/jmptbl.s: $(PROCESSED_JMPTBL) | $$(@D)/
$(s)echo " TBL $@"
$(q)$(ROMLIB_GEN) gentbl --output $@ --bti=$(ENABLE_BTI) $<
-$(BUILD_DIR)/romlib.ldflags: ../../$(PLAT_DIR)/jmptbl.i | $$(@D)/
+$(BUILD_DIR)/romlib.ldflags: $(PROCESSED_JMPTBL) | $$(@D)/
$(s)echo " LDFLAGS $@"
$(q)$(ROMLIB_GEN) link-flags $< > $@
diff --git a/lib/romlib/jmptbl.i b/lib/romlib/jmptbl.i
deleted file mode 100644
index 44751a2..0000000
--- a/lib/romlib/jmptbl.i
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-# Format:
-# lib function [patch]
-# Add "patch" at the end of the line to patch a function. For example:
-# mbedtls mbedtls_memory_buffer_alloc_init patch
-# Holes can be introduced in the table by using a special keyword "reserved".
-# Example:
-# reserved reserved
-# The jump table will contain an invalid instruction instead of branch
-
-rom rom_lib_init
-fdt fdt_getprop_namelen
-fdt fdt_setprop_inplace
-fdt fdt_check_header
-fdt fdt_node_offset_by_compatible
-fdt fdt_setprop_inplace_namelen_partial
-mbedtls mbedtls_asn1_get_alg
-mbedtls mbedtls_asn1_get_alg_null
-mbedtls mbedtls_asn1_get_bitstring_null
-mbedtls mbedtls_asn1_get_bool
-mbedtls mbedtls_asn1_get_int
-mbedtls mbedtls_asn1_get_tag
-mbedtls mbedtls_free
-mbedtls mbedtls_md
-mbedtls mbedtls_md_get_size
-mbedtls mbedtls_memory_buffer_alloc_init
-mbedtls mbedtls_oid_get_md_alg
-mbedtls mbedtls_oid_get_numeric_string
-mbedtls mbedtls_oid_get_pk_alg
-mbedtls mbedtls_oid_get_sig_alg
-mbedtls mbedtls_pk_free
-mbedtls mbedtls_pk_init
-mbedtls mbedtls_pk_parse_subpubkey
-mbedtls mbedtls_pk_verify_ext
-mbedtls mbedtls_platform_set_snprintf
-mbedtls mbedtls_x509_get_rsassa_pss_params
-mbedtls mbedtls_x509_get_sig_alg
-mbedtls mbedtls_md_info_from_type
-c exit
-c atexit
diff --git a/lib/transfer_list/transfer_list.c b/lib/transfer_list/transfer_list.c
index 8d82d25..07614a6 100644
--- a/lib/transfer_list/transfer_list.c
+++ b/lib/transfer_list/transfer_list.c
@@ -168,30 +168,29 @@
}
if (tl->signature != TRANSFER_LIST_SIGNATURE) {
- ERROR("Bad transfer list signature %#" PRIx32 "\n",
- tl->signature);
+ ERROR("Bad transfer list signature 0x%x\n", tl->signature);
return TL_OPS_NON;
}
if (!tl->max_size) {
- ERROR("Bad transfer list max size %#" PRIx32 "\n",
+ ERROR("Bad transfer list max size 0x%x\n",
tl->max_size);
return TL_OPS_NON;
}
if (tl->size > tl->max_size) {
- ERROR("Bad transfer list size %#" PRIx32 "\n", tl->size);
+ ERROR("Bad transfer list size 0x%x\n", tl->size);
return TL_OPS_NON;
}
if (tl->hdr_size != sizeof(struct transfer_list_header)) {
- ERROR("Bad transfer list header size %#" PRIx32 "\n",
+ ERROR("Bad transfer list header size 0x%x\n",
tl->hdr_size);
return TL_OPS_NON;
}
if (!transfer_list_verify_checksum(tl)) {
- ERROR("Bad transfer list checksum %#" PRIx32 "\n",
+ ERROR("Bad transfer list checksum 0x%x\n",
tl->checksum);
return TL_OPS_NON;
}
@@ -521,3 +520,22 @@
}
return (uint8_t *)entry + entry->hdr_size;
}
+
+/*******************************************************************************
+ * Verifies that the transfer list has not already been initialized, then
+ * initializes it at the specified memory location.
+ *
+ * Return pointer to the transfer list or NULL on error
+ * *****************************************************************************/
+struct transfer_list_header *transfer_list_ensure(void *addr, size_t size)
+{
+ struct transfer_list_header *tl = NULL;
+
+ if (transfer_list_check_header(addr) == TL_OPS_ALL) {
+ return (struct transfer_list_header *)addr;
+ }
+
+ tl = transfer_list_init((void *)addr, size);
+
+ return tl;
+}
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 57609d5..3c9e136 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -83,6 +83,7 @@
# Enable the features which are mandatory from ARCH version 8.8 and upwards.
ifeq "8.8" "$(word 1, $(sort 8.8 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+armv8-8-a-feats := ENABLE_FEAT_MOPS
# 8.7 Compliant
armv8-8-a-feats += ${armv8-7-a-feats}
FEAT_LIST := ${armv8-8-a-feats}
@@ -213,6 +214,14 @@
ENABLE_FEAT_HCX ?= 0
#----
+# 8.8
+#----
+
+# Flag to enable FEAT_MOPS (Standardization of Memory operations)
+# when INIT_UNUSED_NS_EL2 = 1
+ENABLE_FEAT_MOPS ?= 0
+
+#----
# 8.9
#----
@@ -408,6 +417,9 @@
# if FEAT_BRBE is implemented.
ENABLE_BRBE_FOR_NS ?= 0
+# Flag to enable Floating point exception Mode Register Feature (FEAT_FPMR)
+ENABLE_FEAT_FPMR ?= 0
+
#----
# 9.3
#----
diff --git a/make_helpers/build_env.mk b/make_helpers/build_env.mk
deleted file mode 100644
index 13acaae..0000000
--- a/make_helpers/build_env.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# This file contains the logic to identify and include any relevant
-# build environment specific make include files.
-
-ifndef BUILD_ENV_MK
- BUILD_ENV_MK := $(lastword $(MAKEFILE_LIST))
-
- # Block possible built-in command definitions that are not fully portable.
- # This traps occurences that need replacing with our OS portable macros
- COPY := $$(error "Replace COPY with call to SHELL_COPY or SHELL_COPY_TREE.")
- CP := $$(error "Replace CP with call to SHELL_COPY or SHELL_COPY_TREE.")
- DEL := $$(error "Replace DEL with call to SHELL_DELETE.")
- RD := $$(error "Replace RD with call to SHELL_REMOVE_DIR.")
- RM := $$(error "Replace RM with call to SHELL_DELETE.")
- RMDIR := $$(error "Replace RMDIR with call to SHELL_REMOVE_DIR.")
-
- ENV_FILE_TO_INCLUDE := unix.mk
- ifdef OSTYPE
- ifneq ($(findstring ${OSTYPE}, cygwin),)
- ENV_FILE_TO_INCLUDE := cygwin.mk
- else
- ifneq ($(findstring ${OSTYPE}, MINGW32 mingw msys),)
- ENV_FILE_TO_INCLUDE := msys.mk
- endif
- endif
- else
- ifdef MSYSTEM
- # Although the MINGW MSYS shell sets OSTYPE as msys in its environment,
- # it does not appear in the GNU make view of environment variables.
- # We use MSYSTEM as an alternative, as that is seen by make
- ifneq ($(findstring ${MSYSTEM}, MINGW32 mingw msys),)
- OSTYPE ?= msys
- ENV_FILE_TO_INCLUDE := msys.mk
- endif
- else
- ifdef OS
- ifneq ($(findstring ${OS}, Windows_NT),)
- ENV_FILE_TO_INCLUDE := windows.mk
- endif
- endif
- endif
- endif
- include $(dir $(lastword $(MAKEFILE_LIST)))${ENV_FILE_TO_INCLUDE}
- ENV_FILE_TO_INCLUDE :=
-
- ifndef SHELL_COPY
- $(error "SHELL_COPY not defined for build environment.")
- endif
- ifndef SHELL_COPY_TREE
- $(error "SHELL_COPY_TREE not defined for build environment.")
- endif
- ifndef SHELL_DELETE_ALL
- $(error "SHELL_DELETE_ALL not defined for build environment.")
- endif
- ifndef SHELL_DELETE
- $(error "SHELL_DELETE not defined for build environment.")
- endif
- ifndef SHELL_REMOVE_DIR
- $(error "SHELL_REMOVE_DIR not defined for build environment.")
- endif
-
-endif
diff --git a/make_helpers/common.mk b/make_helpers/common.mk
index 848e4e9..a4b69c7 100644
--- a/make_helpers/common.mk
+++ b/make_helpers/common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -14,4 +14,6 @@
s := @$(if $(or $(verbose),$(silent)),: )
q := $(if $(verbose),,@)
+
+ .exe := $(if $(filter Windows_NT,$(OS)),.exe)
endif
diff --git a/make_helpers/cygwin.mk b/make_helpers/cygwin.mk
deleted file mode 100644
index 04a963f..0000000
--- a/make_helpers/cygwin.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#
-
-# OS specific definitions for builds in a Cygwin environment.
-# Cygwin allows us to use unix style commands on a windows platform.
-
-ifndef CYGWIN_MK
- CYGWIN_MK := $(lastword $(MAKEFILE_LIST))
-
- include ${MAKE_HELPERS_DIRECTORY}unix.mk
-
- # In cygwin executable files have the Windows .exe extension type.
- BIN_EXT := .exe
-
-endif
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index d6c09de..4985c0c 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -159,6 +159,9 @@
# Enable Handoff protocol using transfer lists
TRANSFER_LIST := 0
+# Enable HOB list to generate boot information
+HOB_LIST := 0
+
# Enables support for the gcc compiler option "-mharden-sls=all".
# By default, disables all SLS hardening.
HARDEN_SLS := 0
@@ -207,6 +210,9 @@
# Enable PSCI OS-initiated mode support
PSCI_OS_INIT_MODE := 0
+# SMCCC_ARCH_FEATURE_AVAILABILITY support
+ARCH_FEATURE_AVAILABILITY := 0
+
# By default, BL1 acts as the reset handler, not BL31
RESET_TO_BL31 := 0
diff --git a/make_helpers/msys.mk b/make_helpers/msys.mk
deleted file mode 100644
index 7e60d57..0000000
--- a/make_helpers/msys.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#
-
-# OS specific definitions for builds in a Mingw32 MSYS environment.
-# Mingw32 allows us to use some unix style commands on a windows platform.
-
-ifndef MSYS_MK
- MSYS_MK := $(lastword $(MAKEFILE_LIST))
-
- include ${MAKE_HELPERS_DIRECTORY}unix.mk
-
- # In MSYS executable files have the Windows .exe extension type.
- BIN_EXT := .exe
-
-endif
-
diff --git a/make_helpers/toolchain.mk b/make_helpers/toolchain.mk
index 2ab577c..3b9d984 100644
--- a/make_helpers/toolchain.mk
+++ b/make_helpers/toolchain.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -18,7 +18,6 @@
ifndef toolchain-mk
toolchain-mk := $(lastword $(MAKEFILE_LIST))
- include $(dir $(toolchain-mk))build_env.mk
include $(dir $(toolchain-mk))utilities.mk
#
@@ -242,28 +241,28 @@
#
# Arm Compiler for Embedded
- toolchain-guess-tool-arm-clang = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armclang")
- toolchain-guess-tool-arm-link = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: armlink")
- toolchain-guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: fromelf")
- toolchain-guess-tool-arm-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armar")
+ toolchain-guess-tool-arm-clang = $(shell $(1) --version 2>&1 </dev/null | grep -o "Tool: armclang")
+ toolchain-guess-tool-arm-link = $(shell $(1) --help 2>&1 </dev/null | grep -o "Tool: armlink")
+ toolchain-guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 </dev/null | grep -o "Tool: fromelf")
+ toolchain-guess-tool-arm-ar = $(shell $(1) --version 2>&1 </dev/null | grep -o "Tool: armar")
# LLVM Project
- toolchain-guess-tool-llvm-clang = $(shell $(1) -v 2>&1 <$(nul) | grep -o "clang version")
- toolchain-guess-tool-llvm-lld = $(shell $(1) --help 2>&1 <$(nul) | grep -o "OVERVIEW: lld")
- toolchain-guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm-objcopy tool")
- toolchain-guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm object file dumper")
- toolchain-guess-tool-llvm-ar = $(shell $(1) --help 2>&1 <$(nul) | grep -o "LLVM Archiver")
+ toolchain-guess-tool-llvm-clang = $(shell $(1) -v 2>&1 </dev/null | grep -o "clang version")
+ toolchain-guess-tool-llvm-lld = $(shell $(1) --help 2>&1 </dev/null | grep -o "OVERVIEW: lld")
+ toolchain-guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 </dev/null | grep -o "llvm-objcopy tool")
+ toolchain-guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 </dev/null | grep -o "llvm object file dumper")
+ toolchain-guess-tool-llvm-ar = $(shell $(1) --help 2>&1 </dev/null | grep -o "LLVM Archiver")
# GNU Compiler Collection & GNU Binary Utilities
- toolchain-guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 <$(nul) | grep -o "gcc version")
- toolchain-guess-tool-gnu-ld = $(shell $(1) -v 2>&1 <$(nul) | grep -o "GNU ld")
- toolchain-guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objcopy")
- toolchain-guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objdump")
- toolchain-guess-tool-gnu-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU ar")
+ toolchain-guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 </dev/null | grep -o "gcc version")
+ toolchain-guess-tool-gnu-ld = $(shell $(1) -v 2>&1 </dev/null | grep -o "GNU ld")
+ toolchain-guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 </dev/null | grep -o "GNU objcopy")
+ toolchain-guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 </dev/null | grep -o "GNU objdump")
+ toolchain-guess-tool-gnu-ar = $(shell $(1) --version 2>&1 </dev/null | grep -o "GNU ar")
# Other tools
- toolchain-guess-tool-generic-dtc = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Version: DTC")
- toolchain-guess-tool-generic-poetry = $(shell $(1) --version 2>&1 <$(nul))
+ toolchain-guess-tool-generic-dtc = $(shell $(1) --version 2>&1 </dev/null | grep -o "Version: DTC")
+ toolchain-guess-tool-generic-poetry = $(shell $(1) --version 2>&1 </dev/null)
toolchain-guess-tool = $(if $(2),$(firstword $(foreach candidate,$(1),$\
$(if $(call toolchain-guess-tool-$(candidate),$(2)),$(candidate)))))
@@ -330,17 +329,17 @@
toolchain-derive-llvm-clang-cpp = $(1)
toolchain-derive-llvm-clang-as = $(1)
- toolchain-derive-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>$(nul))
- toolchain-derive-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>$(nul))
- toolchain-derive-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>$(nul))
- toolchain-derive-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>$(nul))
+ toolchain-derive-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>/dev/null)
+ toolchain-derive-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>/dev/null)
+ toolchain-derive-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>/dev/null)
+ toolchain-derive-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>/dev/null)
toolchain-derive-gnu-gcc-cpp = $(1)
toolchain-derive-gnu-gcc-as = $(1)
toolchain-derive-gnu-gcc-ld = $(1)
- toolchain-derive-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>$(nul))
- toolchain-derive-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>$(nul))
- toolchain-derive-gnu-gcc-ar = $(shell $(1) --print-prog-name ar 2>$(nul))
+ toolchain-derive-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>/dev/null)
+ toolchain-derive-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>/dev/null)
+ toolchain-derive-gnu-gcc-ar = $(shell $(1) --print-prog-name ar 2>/dev/null)
toolchain-derive = $(if $3,$(call toolchain-derive-$1-$2,$3))
diff --git a/make_helpers/unix.mk b/make_helpers/unix.mk
deleted file mode 100644
index fa7722a..0000000
--- a/make_helpers/unix.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# Trusted Firmware shell command definitions for a Unix style environment.
-
-ifndef UNIX_MK
- UNIX_MK := $(lastword $(MAKEFILE_LIST))
-
- DIR_DELIM := /
- PATH_SEP := :
-
- # These defines provide Unix style equivalents of the shell commands
- # required by the Trusted Firmware build environment.
-
- # ${1} is the file to be copied.
- # ${2} is the destination file name.
- define SHELL_COPY
- $(q)cp -f "${1}" "${2}"
- endef
-
- # ${1} is the directory to be copied.
- # ${2} is the destination directory path.
- define SHELL_COPY_TREE
- $(q)cp -rf "${1}" "${2}"
- endef
-
- # ${1} is the file to be deleted.
- define SHELL_DELETE
- -$(q)rm -f "${1}"
- endef
-
- # ${1} is a space delimited list of files to be deleted.
- # Note that we do not quote ${1}, as multiple parameters may be passed.
- define SHELL_DELETE_ALL
- -$(q)rm -rf ${1}
- endef
-
- define SHELL_REMOVE_DIR
- -$(q)rm -rf "${1}"
- endef
-
- nul := /dev/null
-
- which = $(shell command -v $(call escape-shell,$(1)) 2>$(nul))
-endif
diff --git a/make_helpers/utilities.mk b/make_helpers/utilities.mk
index fcccd24..10645bf 100644
--- a/make_helpers/utilities.mk
+++ b/make_helpers/utilities.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -127,3 +127,17 @@
#
defined = $(call bool,$(filter-out undefined,$(origin $(1))))
+
+#
+# Determine the path to a program.
+#
+# Parameters:
+#
+# - $(1): The program to search for.
+#
+# Example usage:
+#
+# path-to-gcc := $(call which,gcc) # "/usr/bin/gcc"
+#
+
+which = $(shell command -v $(call escape-shell,$(1)) 2>/dev/null)
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
deleted file mode 100644
index c24aa08..0000000
--- a/make_helpers/windows.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# OS specific parts for builds in a Windows_NT environment. The
-# environment variable OS is set to Windows_NT on all modern Windows platforms
-
-# Include generic windows command definitions.
-
-ifndef WINDOWS_MK
- WINDOWS_MK := $(lastword $(MAKEFILE_LIST))
-
- DIR_DELIM := $(strip \)
- BIN_EXT := .exe
- PATH_SEP := ;
-
- # For some Windows native commands there is a problem with the directory delimiter.
- # Make uses / (slash) and the commands expect \ (backslash)
- # We have to provide a means of translating these, so we define local functions.
-
- # ${1} is the file to be copied.
- # ${2} is the destination file name.
- define SHELL_COPY
- $(eval tmp_from_file:=$(subst /,\,${1}))
- $(eval tmp_to_file:=$(subst /,\,${2}))
- copy "${tmp_from_file}" "${tmp_to_file}"
- endef
-
- # ${1} is the directory to be copied.
- # ${2} is the destination directory path.
- define SHELL_COPY_TREE
- $(eval tmp_from_dir:=$(subst /,\,${1}))
- $(eval tmp_to_dir:=$(subst /,\,${2}))
- xcopy /HIVE "${tmp_from_dir}" "${tmp_to_dir}"
- endef
-
- # ${1} is the file to be deleted.
- define SHELL_DELETE
- $(eval tmp_del_file:=$(subst /,\,${*}))
- -@if exist $(tmp_del_file) del /Q $(tmp_del_file)
- endef
-
- # ${1} is a space delimited list of files to be deleted.
- define SHELL_DELETE_ALL
- $(eval $(foreach filename,$(wildcard ${1}),$(call DELETE_IF_THERE,${filename})))
- endef
-
- # ${1} is the directory to be removed.
- define SHELL_REMOVE_DIR
- $(eval tmp_dir:=$(subst /,\,${1}))
- -@if exist "$(tmp_dir)" rd /Q /S "$(tmp_dir)"
- endef
-
- nul := nul
-
- which = $(shell where "$(1)" 2>$(nul))
-endif
-
-# Because git is not available from CMD.EXE, we need to avoid
-# the BUILD_STRING generation which uses git.
-# For now we use "development build".
-# This can be overridden from the command line or environment.
-BUILD_STRING ?= development build
-
-MSVC_NMAKE := nmake.exe
diff --git a/package-lock.json b/package-lock.json
index a039bc5..61d05bd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1963,9 +1963,9 @@
}
},
"node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"dependencies": {
"path-key": "^3.1.0",
diff --git a/plat/amd/versal2/aarch64/common.c b/plat/amd/versal2/aarch64/common.c
index 0e46edc..c78d711 100644
--- a/plat/amd/versal2/aarch64/common.c
+++ b/plat/amd/versal2/aarch64/common.c
@@ -75,8 +75,8 @@
uint32_t version_type;
version_type = mmio_read_32(PMC_TAP_VERSION);
- platform_id = FIELD_GET(PLATFORM_MASK, version_type);
- platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version_type);
+ platform_id = FIELD_GET((uint32_t)PLATFORM_MASK, version_type);
+ platform_version = FIELD_GET((uint32_t)PLATFORM_VERSION_MASK, version_type);
if (platform_id == QEMU_COSIM) {
platform_id = QEMU;
diff --git a/plat/amd/versal2/bl31_setup.c b/plat/amd/versal2/bl31_setup.c
index 47d4c2c..05e4c96 100644
--- a/plat/amd/versal2/bl31_setup.c
+++ b/plat/amd/versal2/bl31_setup.c
@@ -63,7 +63,7 @@
bl32_image_ep_info.args.arg3 = XILINX_OF_BOARD_DTB_ADDR;
#endif
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
- bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+ bl33_image_ep_info.spsr = (uint32_t)SPSR_64(MODE_EL2, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
}
@@ -127,14 +127,14 @@
uart_clock = get_uart_clk();
+ /* Initialize the platform config for future decision making */
+ config_setup();
+
setup_console();
NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
platform_version / 10U, platform_version % 10U);
- /* Initialize the platform config for future decision making */
- config_setup();
-
/*
* Do initial security configuration to allow DRAM/device access. On
* Base only DRAM security is programmable (via TrustZone), but
@@ -170,16 +170,19 @@
{
static uint32_t index;
uint32_t i;
+ int32_t ret = 0;
/* Validate 'handler' and 'id' parameters */
if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit_label;
}
/* Check if a handler has already been registered */
for (i = 0; i < index; i++) {
if (id == type_el3_interrupt_table[i].id) {
- return -EALREADY;
+ ret = -EALREADY;
+ goto exit_label;
}
}
@@ -188,7 +191,8 @@
index++;
- return 0;
+exit_label:
+ return ret;
}
static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
@@ -229,7 +233,7 @@
void bl31_plat_runtime_setup(void)
{
- uint64_t flags = 0;
+ uint32_t flags = 0;
int32_t rc;
set_interrupt_rm_flag(flags, NON_SECURE);
diff --git a/plat/amd/versal2/include/def.h b/plat/amd/versal2/include/def.h
index f3a7907..0c43d1b 100644
--- a/plat/amd/versal2/include/def.h
+++ b/plat/amd/versal2/include/def.h
@@ -12,7 +12,7 @@
#include <plat/arm/common/smccc_def.h>
#include <plat/common/common_def.h>
-#define MAX_INTR_EL3 2
+#define MAX_INTR_EL3 2U
/* List all consoles */
#define VERSAL2_CONSOLE_ID_none 0
diff --git a/plat/amd/versal2/include/platform_def.h b/plat/amd/versal2/include/platform_def.h
index 42c9b08..be1e351 100644
--- a/plat/amd/versal2/include/platform_def.h
+++ b/plat/amd/versal2/include/platform_def.h
@@ -24,6 +24,9 @@
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * PLATFORM_CORE_COUNT_PER_CLUSTER)
+#define E_INVALID_CORE_COUNT -1
+#define E_INVALID_CLUSTER_COUNT -3
+
#define PLAT_MAX_PWR_LVL U(2)
#define PLAT_MAX_RET_STATE U(1)
#define PLAT_MAX_OFF_STATE U(2)
diff --git a/plat/amd/versal2/include/versal2-scmi.h b/plat/amd/versal2/include/versal2-scmi.h
index c08b4b1..218fbf6 100644
--- a/plat/amd/versal2/include/versal2-scmi.h
+++ b/plat/amd/versal2/include/versal2-scmi.h
@@ -10,96 +10,96 @@
#ifndef _VERSAL2_SCMI_H
#define _VERSAL2_SCMI_H
-#define CLK_GEM0_0 0
-#define CLK_GEM0_1 1
-#define CLK_GEM0_2 2
-#define CLK_GEM0_3 3
-#define CLK_GEM0_4 4
-#define CLK_GEM1_0 5
-#define CLK_GEM1_1 6
-#define CLK_GEM1_2 7
-#define CLK_GEM1_3 8
-#define CLK_GEM1_4 9
-#define CLK_SERIAL0_0 10
-#define CLK_SERIAL0_1 11
-#define CLK_SERIAL1_0 12
-#define CLK_SERIAL1_1 13
-#define CLK_UFS0_0 14
-#define CLK_UFS0_1 15
-#define CLK_UFS0_2 16
-#define CLK_USB0_0 17
-#define CLK_USB0_1 18
-#define CLK_USB0_2 19
-#define CLK_USB1_0 20
-#define CLK_USB1_1 21
-#define CLK_USB1_2 22
-#define CLK_MMC0_0 23
-#define CLK_MMC0_1 24
-#define CLK_MMC0_2 25
-#define CLK_MMC1_0 26
-#define CLK_MMC1_1 27
-#define CLK_MMC1_2 28
-#define CLK_TTC0_0 29
-#define CLK_TTC1_0 30
-#define CLK_TTC2_0 31
-#define CLK_TTC3_0 32
-#define CLK_TTC4_0 33
-#define CLK_TTC5_0 34
-#define CLK_TTC6_0 35
-#define CLK_TTC7_0 36
-#define CLK_I2C0_0 37
-#define CLK_I2C1_0 38
-#define CLK_I2C2_0 39
-#define CLK_I2C3_0 40
-#define CLK_I2C4_0 41
-#define CLK_I2C5_0 42
-#define CLK_I2C6_0 43
-#define CLK_I2C7_0 44
-#define CLK_OSPI0_0 45
-#define CLK_QSPI0_0 46
-#define CLK_QSPI0_1 47
-#define CLK_WWDT0_0 48
-#define CLK_WWDT1_0 49
-#define CLK_WWDT2_0 50
-#define CLK_WWDT3_0 51
-#define CLK_ADMA0_0 52
-#define CLK_ADMA0_1 53
-#define CLK_ADMA1_0 54
-#define CLK_ADMA1_1 55
-#define CLK_ADMA2_0 56
-#define CLK_ADMA2_1 57
-#define CLK_ADMA3_0 58
-#define CLK_ADMA3_1 59
-#define CLK_ADMA4_0 60
-#define CLK_ADMA4_1 61
-#define CLK_ADMA5_0 62
-#define CLK_ADMA5_1 63
-#define CLK_ADMA6_0 64
-#define CLK_ADMA6_1 65
-#define CLK_ADMA7_0 66
-#define CLK_ADMA7_1 67
-#define CLK_CAN0_0 68
-#define CLK_CAN0_1 69
-#define CLK_CAN1_0 70
-#define CLK_CAN1_1 71
-#define CLK_CAN2_0 72
-#define CLK_CAN2_1 73
-#define CLK_CAN3_0 74
-#define CLK_CAN3_1 75
-#define CLK_PS_GPIO_0 76
-#define CLK_PMC_GPIO_0 77
-#define CLK_SPI0_0 78
-#define CLK_SPI0_1 79
-#define CLK_SPI1_0 80
-#define CLK_SPI1_1 81
-#define CLK_I3C0_0 82
-#define CLK_I3C1_0 83
-#define CLK_I3C2_0 84
-#define CLK_I3C3_0 85
-#define CLK_I3C4_0 86
-#define CLK_I3C5_0 87
-#define CLK_I3C6_0 88
-#define CLK_I3C7_0 89
+#define CLK_GEM0_0 0U
+#define CLK_GEM0_1 1U
+#define CLK_GEM0_2 2U
+#define CLK_GEM0_3 3U
+#define CLK_GEM0_4 4U
+#define CLK_GEM1_0 5U
+#define CLK_GEM1_1 6U
+#define CLK_GEM1_2 7U
+#define CLK_GEM1_3 8U
+#define CLK_GEM1_4 9U
+#define CLK_SERIAL0_0 10U
+#define CLK_SERIAL0_1 11U
+#define CLK_SERIAL1_0 12U
+#define CLK_SERIAL1_1 13U
+#define CLK_UFS0_0 14U
+#define CLK_UFS0_1 15U
+#define CLK_UFS0_2 16U
+#define CLK_USB0_0 17U
+#define CLK_USB0_1 18U
+#define CLK_USB0_2 19U
+#define CLK_USB1_0 20U
+#define CLK_USB1_1 21U
+#define CLK_USB1_2 22U
+#define CLK_MMC0_0 23U
+#define CLK_MMC0_1 24U
+#define CLK_MMC0_2 25U
+#define CLK_MMC1_0 26U
+#define CLK_MMC1_1 27U
+#define CLK_MMC1_2 28U
+#define CLK_TTC0_0 29U
+#define CLK_TTC1_0 30U
+#define CLK_TTC2_0 31U
+#define CLK_TTC3_0 32U
+#define CLK_TTC4_0 33U
+#define CLK_TTC5_0 34U
+#define CLK_TTC6_0 35U
+#define CLK_TTC7_0 36U
+#define CLK_I2C0_0 37U
+#define CLK_I2C1_0 38U
+#define CLK_I2C2_0 39U
+#define CLK_I2C3_0 40U
+#define CLK_I2C4_0 41U
+#define CLK_I2C5_0 42U
+#define CLK_I2C6_0 43U
+#define CLK_I2C7_0 44U
+#define CLK_OSPI0_0 45U
+#define CLK_QSPI0_0 46U
+#define CLK_QSPI0_1 47U
+#define CLK_WWDT0_0 48U
+#define CLK_WWDT1_0 49U
+#define CLK_WWDT2_0 50U
+#define CLK_WWDT3_0 51U
+#define CLK_ADMA0_0 52U
+#define CLK_ADMA0_1 53U
+#define CLK_ADMA1_0 54U
+#define CLK_ADMA1_1 55U
+#define CLK_ADMA2_0 56U
+#define CLK_ADMA2_1 57U
+#define CLK_ADMA3_0 58U
+#define CLK_ADMA3_1 59U
+#define CLK_ADMA4_0 60U
+#define CLK_ADMA4_1 61U
+#define CLK_ADMA5_0 62U
+#define CLK_ADMA5_1 63U
+#define CLK_ADMA6_0 64U
+#define CLK_ADMA6_1 65U
+#define CLK_ADMA7_0 66U
+#define CLK_ADMA7_1 67U
+#define CLK_CAN0_0 68U
+#define CLK_CAN0_1 69U
+#define CLK_CAN1_0 70U
+#define CLK_CAN1_1 71U
+#define CLK_CAN2_0 72U
+#define CLK_CAN2_1 73U
+#define CLK_CAN3_0 74U
+#define CLK_CAN3_1 75U
+#define CLK_PS_GPIO_0 76U
+#define CLK_PMC_GPIO_0 77U
+#define CLK_SPI0_0 78U
+#define CLK_SPI0_1 79U
+#define CLK_SPI1_0 80U
+#define CLK_SPI1_1 81U
+#define CLK_I3C0_0 82U
+#define CLK_I3C1_0 83U
+#define CLK_I3C2_0 84U
+#define CLK_I3C3_0 85U
+#define CLK_I3C4_0 86U
+#define CLK_I3C5_0 87U
+#define CLK_I3C6_0 88U
+#define CLK_I3C7_0 89U
#define RESET_GEM0_0 0
#define RESET_GEM1_0 1
diff --git a/plat/amd/versal2/plat_psci.c b/plat/amd/versal2/plat_psci.c
index eab032d..55842cc 100644
--- a/plat/amd/versal2/plat_psci.c
+++ b/plat/amd/versal2/plat_psci.c
@@ -35,20 +35,22 @@
static int32_t zynqmp_nopmu_pwr_domain_on(u_register_t mpidr)
{
- uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr) & ~BIT(MPIDR_MT_BIT);
- uint32_t cpu = cpu_id % PLATFORM_CORE_COUNT_PER_CLUSTER;
- uint32_t cluster = cpu_id / PLATFORM_CORE_COUNT_PER_CLUSTER;
+ int32_t cpu_id = plat_core_pos_by_mpidr(mpidr) & ~BIT(MPIDR_MT_BIT);
+ int32_t cpu = cpu_id % PLATFORM_CORE_COUNT_PER_CLUSTER;
+ int32_t cluster = cpu_id / PLATFORM_CORE_COUNT_PER_CLUSTER;
uintptr_t apu_cluster_base = 0, apu_pcli_base, apu_pcli_cluster = 0;
uintptr_t rst_apu_cluster = PSX_CRF + RST_APU0_OFFSET + ((uint64_t)cluster * 0x4U);
+ int32_t ret = PSCI_E_SUCCESS;
VERBOSE("%s: mpidr: 0x%lx, cpuid: %x, cpu: %x, cluster: %x\n",
__func__, mpidr, cpu_id, cpu, cluster);
if (cpu_id == -1) {
- return PSCI_E_INTERN_FAIL;
+ ret = PSCI_E_INTERN_FAIL;
+ goto exit_label;
}
- if (cluster > 3) {
+ if (cluster > 3U) {
panic();
}
@@ -69,7 +71,7 @@
mmio_write_32(apu_cluster_base + APU_RVBAR_L_0 + (cpu << 3),
(uint32_t)_sec_entry);
mmio_write_32(apu_cluster_base + APU_RVBAR_H_0 + (cpu << 3),
- _sec_entry >> 32);
+ (uint32_t)(_sec_entry >> 32));
/* de-assert core reset */
mmio_clrbits_32(rst_apu_cluster, ((RST_APU_COLD_RESET|RST_APU_WARN_RESET) << cpu));
@@ -84,7 +86,8 @@
mmio_write_32(apu_pcli_base + PCLI_PSTATE_OFFSET, PCLI_PSTATE_VAL_CLEAR);
mmio_write_32(apu_pcli_base + PCLI_PREQ_OFFSET, PREQ_CHANGE_REQUEST);
- return PSCI_E_SUCCESS;
+exit_label:
+ return ret;
}
static void zynqmp_nopmu_pwr_domain_off(const psci_power_state_t *target_state)
@@ -101,13 +104,15 @@
static int32_t zynqmp_validate_ns_entrypoint(uint64_t ns_entrypoint)
{
+ int32_t ret = PSCI_E_INVALID_ADDRESS;
+
VERBOSE("Validate ns_entry point %lx\n", ns_entrypoint);
if ((ns_entrypoint) != 0U) {
- return PSCI_E_SUCCESS;
- } else {
- return PSCI_E_INVALID_ADDRESS;
+ ret = PSCI_E_SUCCESS;
}
+
+ return ret;
}
static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
@@ -178,9 +183,9 @@
ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_TX_RX_CONFIG_RDY);
break;
case IOCTL_UFS_SRAM_CSR_SEL:
- if (arg1 == 1) {
+ if (arg1 == 1U) {
ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_SRAM_CSR);
- } else if (arg1 == 0) {
+ } else if (arg1 == 0U) {
mmio_write_32(PMXC_IOU_SLCR_SRAM_CSR, arg2);
}
break;
diff --git a/plat/amd/versal2/plat_topology.c b/plat/amd/versal2/plat_topology.c
index 0763139..434e08a 100644
--- a/plat/amd/versal2/plat_topology.c
+++ b/plat/amd/versal2/plat_topology.c
@@ -41,6 +41,7 @@
int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
{
uint32_t cluster_id, cpu_id;
+ int32_t ret = 0;
mpidr &= MPIDR_AFFINITY_MASK;
@@ -48,7 +49,8 @@
cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
- return -3;
+ ret = E_INVALID_CLUSTER_COUNT;
+ goto exit_label;
}
/*
@@ -56,8 +58,11 @@
* one of the two clusters present on the platform.
*/
if (cpu_id >= PLATFORM_CORE_COUNT_PER_CLUSTER) {
- return -1;
+ ret = E_INVALID_CORE_COUNT;
+ } else {
+ ret = (cpu_id + (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER));
}
- return (cpu_id + (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER));
+exit_label:
+ return ret;
}
diff --git a/plat/amd/versal2/scmi.c b/plat/amd/versal2/scmi.c
index 6375df3..0d384a5 100644
--- a/plat/amd/versal2/scmi.c
+++ b/plat/amd/versal2/scmi.c
@@ -288,13 +288,16 @@
uint32_t start_idx)
{
const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+ int32_t ret = SCMI_SUCCESS;
if (clock == NULL) {
- return SCMI_NOT_FOUND;
+ ret = SCMI_NOT_FOUND;
+ goto exit_label;
}
- if (start_idx > 0) {
- return SCMI_OUT_OF_RANGE;
+ if (start_idx > 0U) {
+ ret = SCMI_OUT_OF_RANGE;
+ goto exit_label;
}
if (array == NULL) {
@@ -304,10 +307,11 @@
VERBOSE("SCMI: CLK: id: %d, clk_name: %s, get_rate %lu\n",
scmi_id, clock->name, *array);
} else {
- return SCMI_GENERIC_ERROR;
+ ret = SCMI_GENERIC_ERROR;
}
- return SCMI_SUCCESS;
+exit_label:
+ return ret;
}
unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, unsigned int scmi_id)
@@ -328,7 +332,7 @@
unsigned long rate)
{
struct scmi_clk *clock = clk_find(agent_id, scmi_id);
- unsigned long ret = UL(SCMI_SUCCESS);
+ int32_t ret = SCMI_SUCCESS;
if ((clock == NULL)) {
ret = SCMI_NOT_FOUND;
@@ -529,12 +533,13 @@
const char *plat_scmi_pd_get_name(unsigned int agent_id, unsigned int pd_id)
{
const struct scmi_pd *pd = find_pd(agent_id, pd_id);
+ const char *ret = NULL;
- if (pd == NULL) {
- return NULL;
+ if (pd != NULL) {
+ ret = pd->name;
}
- return pd->name;
+ return ret;
}
unsigned int plat_scmi_pd_statistics(unsigned int agent_id, unsigned long *pd_id)
@@ -550,31 +555,35 @@
unsigned int plat_scmi_pd_get_state(unsigned int agent_id, unsigned int pd_id)
{
const struct scmi_pd *pd = find_pd(agent_id, pd_id);
+ uint32_t ret = SCMI_NOT_SUPPORTED;
- if (pd == NULL) {
- return SCMI_NOT_SUPPORTED;
+ if (pd != NULL) {
+ NOTICE("SCMI: PD: get id: %d, state: %x\n", pd_id, pd->state);
+
+ ret = pd->state;
}
- NOTICE("SCMI: PD: get id: %d, state: %x\n", pd_id, pd->state);
-
- return pd->state;
+ return ret;
}
int32_t plat_scmi_pd_set_state(unsigned int agent_id, unsigned int flags, unsigned int pd_id,
unsigned int state)
{
struct scmi_pd *pd = find_pd(agent_id, pd_id);
+ int32_t ret = SCMI_SUCCESS;
if (pd == NULL) {
- return SCMI_NOT_SUPPORTED;
+ ret = SCMI_NOT_SUPPORTED;
+ goto exit_label;
}
NOTICE("SCMI: PD: set id: %d, orig state: %x, new state: %x, flags: %x\n",
- pd_id, pd->state, state, flags);
+ pd_id, pd->state, state, flags);
pd->state = state;
- return 0U;
+exit_label:
+ return ret;
}
@@ -636,8 +645,9 @@
size_t i;
int32_t ret;
- for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++)
+ for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++) {
scmi_smt_init_agent_channel(&scmi_channel[i]);
+ }
INFO("SCMI: Server initialized\n");
@@ -647,12 +657,14 @@
for (i = 0U; i < ARRAY_SIZE(scmi0_clock); i++) {
/* Keep i2c on 100MHz to calculate rates properly */
- if ((i >= CLK_I2C0_0) && (i <= CLK_I2C7_0))
+ if ((i >= CLK_I2C0_0) && (i <= CLK_I2C7_0)) {
continue;
+ }
/* Keep UFS clocks to default values to get the expected rates */
- if (i >= CLK_UFS0_0 && i <= CLK_UFS0_2)
+ if ((i >= CLK_UFS0_0) && (i <= CLK_UFS0_2)) {
continue;
+ }
/*
* SPP supports multiple versions.
diff --git a/plat/amd/versal2/sip_svc_setup.c b/plat/amd/versal2/sip_svc_setup.c
index 6850030..4a1be3e 100644
--- a/plat/amd/versal2/sip_svc_setup.c
+++ b/plat/amd/versal2/sip_svc_setup.c
@@ -71,7 +71,7 @@
VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
smc_fid, x1, x2, x3, x4);
- if ((smc_fid & SIP_FID_MASK) != 0) {
+ if ((smc_fid & SIP_FID_MASK) != 0U) {
WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
}
diff --git a/plat/amlogic/gxl/gxl_bl31_setup.c b/plat/amlogic/gxl/gxl_bl31_setup.c
index f581dd1..46c2dc2 100644
--- a/plat/amlogic/gxl/gxl_bl31_setup.c
+++ b/plat/amlogic/gxl/gxl_bl31_setup.c
@@ -1,11 +1,13 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2025, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-
#include <assert.h>
#include <common/bl_common.h>
+#ifdef AML_STDPARAMS
+#include <common/desc_image_load.h>
+#endif
#include <common/interrupt_props.h>
#include <drivers/arm/gicv2.h>
#include <lib/mmio.h>
@@ -60,17 +62,26 @@
image_info_t *bl32_image_info;
entry_point_info_t *bl33_ep_info;
image_info_t *bl33_image_info;
+#ifndef AML_STDPARAMS
image_info_t *scp_image_info[];
+#endif
};
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
+#ifndef AML_STDPARAMS
struct gxl_bl31_param *from_bl2;
+#endif
/* Initialize the console to provide early debug support */
aml_console_init();
+#ifdef AML_STDPARAMS
+ /* Parse arguments passed to BL31 from U-Boot SPL */
+ bl31_params_parse_helper(arg0, &bl33_image_ep_info,
+ &bl33_image_ep_info);
+#else
/* Check that params passed from BL2 are not NULL. */
from_bl2 = (struct gxl_bl31_param *) arg0;
@@ -84,14 +95,23 @@
* BL2's address space.
*/
bl33_image_ep_info = *from_bl2->bl33_ep_info;
+#endif
if (bl33_image_ep_info.pc == 0U) {
ERROR("BL31: BL33 entrypoint not obtained from BL2\n");
panic();
}
+#ifdef AML_STDPARAMS
+ /* Hardcode SCP_BL2 image info */
+ bl30_image_info.image_base = 0x13c0000;
+ bl30_image_info.image_size = 0xa000;
+ bl301_image_info.image_base = 0x13ca000;
+ bl301_image_info.image_size = 0x3400;
+#else
bl30_image_info = *from_bl2->scp_image_info[0];
bl301_image_info = *from_bl2->scp_image_info[1];
+#endif
}
void bl31_plat_arch_setup(void)
diff --git a/plat/amlogic/gxl/platform.mk b/plat/amlogic/gxl/platform.mk
index 31063a9..8aaa032 100644
--- a/plat/amlogic/gxl/platform.mk
+++ b/plat/amlogic/gxl/platform.mk
@@ -40,6 +40,12 @@
${XLAT_TABLES_LIB_SRCS} \
${GIC_SOURCES}
+ifeq (${AML_STDPARAMS}, 1)
+ BL31_SOURCES += common/desc_image_load.c
+ $(eval $(call add_define_val,AML_STDPARAMS,'$(AML_STDPARAMS)'))
+ $(info "Building with standard params")
+endif
+
# Tune compiler for Cortex-A53
ifeq ($($(ARCH)-cc-id),arm-clang)
TF_CFLAGS_aarch64 += -mcpu=cortex-a53
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index dd82a10..6d60cbe 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2025, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -75,9 +75,7 @@
${DYN_CFG_SOURCES} \
${A5DS_SECURITY_SOURCES}
-# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
-ifdef UNIX_MK
-
+# Add the FDT_SOURCES and options for Dynamic Config
FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb
@@ -94,7 +92,6 @@
FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \
plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \
${FVP_HW_CONFIG_DTS}
-endif
NEED_BL32 := yes
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 4a2572f..b1f7b11 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -44,11 +44,11 @@
#pragma weak plat_get_nv_ctr
#pragma weak plat_set_nv_ctr
-extern unsigned char arm_rotpk_header[], arm_rotpk_key[], arm_rotpk_hash_end[],
+extern unsigned char arm_rotpk_hash_der_header[], arm_rotpk_key[], arm_rotpk_hash_end[],
arm_rotpk_key_end[];
#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
-static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
+static unsigned char rotpk_hash_der[ARM_ROTPK_HASH_DER_HEADER_LEN + ARM_ROTPK_HASH_LEN];
#endif
#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
@@ -68,8 +68,8 @@
/* Copy the DER header */
- memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
- dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+ memcpy(rotpk_hash_der, arm_rotpk_hash_der_header, ARM_ROTPK_HASH_DER_HEADER_LEN);
+ dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HASH_DER_HEADER_LEN];
words = ARM_ROTPK_HASH_LEN >> 2;
@@ -95,8 +95,8 @@
int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
unsigned int *flags)
{
- *key_ptr = arm_rotpk_header;
- *key_len = arm_rotpk_hash_end - arm_rotpk_header;
+ *key_ptr = arm_rotpk_hash_der_header;
+ *key_len = arm_rotpk_hash_end - arm_rotpk_hash_der_header;
*flags = ROTPK_IS_HASH;
return 0;
}
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 365a960..124a44b 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -13,63 +13,70 @@
ifneq (${TRUSTED_BOARD_BOOT},0)
ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_dev_rotpk.S
+ARM_ROTPK = $(BUILD_PLAT)/arm_rotpk.bin
+ARM_ROTPK_IS_HASH := 1
+$(eval $(call add_define_val,ARM_ROTPK,'"$(ARM_ROTPK)"'))
# ROTPK hash location
ifeq (${ARM_ROTPK_LOCATION}, regs)
ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
-else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
+else
+# The ROTPK is a development key
+ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
CRYPTO_ALG=rsa
ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
- ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
-$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
-$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+ ROT_KEY ?= plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem
$(warning Development keys support for FVP is deprecated. Use `regs` \
option instead)
else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
CRYPTO_ALG=ec
ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
- ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
-$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
-$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+ ROT_KEY ?= plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem
$(warning Development keys support for FVP is deprecated. Use `regs` \
option instead)
else ifeq (${ARM_ROTPK_LOCATION}, devel_full_dev_rsa_key)
CRYPTO_ALG=rsa
ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID
- ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
+ ROT_KEY ?= plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem
+ ARM_ROTPK_IS_HASH = 0
$(warning Development keys support for FVP is deprecated. Use `regs` \
option instead)
else ifeq (${ARM_ROTPK_LOCATION}, devel_full_dev_ecdsa_key)
CRYPTO_ALG=ec
ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID
-ifeq (${KEY_SIZE},384)
- ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
-else
- ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
-endif
+ ROT_KEY ?= plat/arm/board/common/rotpk/arm_rotprivk_ecdsa.pem
+ ARM_ROTPK_IS_HASH = 0
$(warning Development keys support for FVP is deprecated. Use `regs` \
option instead)
else
$(error "Unsupported ARM_ROTPK_LOCATION value")
endif
+$(BUILD_PLAT)/bl1/arm_dev_rotpk.o : $(ARM_ROTPK)
+$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK)
+endif
$(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
+$(eval $(call add_define,ARM_ROTPK_IS_HASH))
ifeq (${ENABLE_RME}, 1)
COT := cca
endif
-# Force generation of the new hash if ROT_KEY is specified
+# Force generation of the ROT public key if ROT_KEY is specified
ifdef ROT_KEY
- HASH_PREREQUISITES = $(ROT_KEY) FORCE
+ PK_PREREQUISITES = $(ROT_KEY) FORCE
endif
-$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES)
+$(ARM_ROTPK) : $(PK_PREREQUISITES)
ifndef ROT_KEY
- $(error Cannot generate hash: no ROT_KEY defined)
+ $(error Cannot generate public key: no ROT_KEY defined)
endif
+ifeq ($(ARM_ROTPK_IS_HASH), 1)
${OPENSSL_BIN_PATH}/openssl ${CRYPTO_ALG} -in $< -pubout -outform DER | \
- ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@
+ ${OPENSSL_BIN_PATH}/openssl dgst -${HASH_ALG} -binary -out $@
+else
+ ${OPENSSL_BIN_PATH}/openssl ${CRYPTO_ALG} -in $< -pubout -outform DER -out $@
+endif
# Certificate NV-Counters. Use values corresponding to tied off values in
# ARM development platforms
@@ -85,50 +92,73 @@
BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \
${ARM_ROTPK_S}
+ifeq ($(CRYPTO_ALG), ec)
+ifeq ($(KEY_SIZE), 384)
+ARM_PROT_KEY := plat/arm/board/common/protpk/arm_protprivk_ecdsa_secp384r1.pem
+ARM_SWD_ROT_KEY := plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa_secp384r1.pem
+else
+ARM_PROT_KEY := plat/arm/board/common/protpk/arm_protprivk_ecdsa.pem
+ARM_SWD_ROT_KEY := plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa.pem
+endif
+else
+ARM_PROT_KEY := plat/arm/board/common/protpk/arm_protprivk_rsa.pem
+ARM_SWD_ROT_KEY := plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem
+endif
+
# Allows platform code to provide implementation variants depending on the
# selected chain of trust.
$(eval $(call add_define,ARM_COT_${COT}))
ifeq (${COT},dualroot)
# Platform Root of Trust key files.
-ARM_PROT_KEY := plat/arm/board/common/protpk/arm_protprivk_rsa.pem
-ARM_PROTPK_HASH := plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
+ARM_PROTPK := $(BUILD_PLAT)/arm_protpk.bin
# Provide the private key to cert_create tool. It needs it to sign the images.
PROT_KEY := ${ARM_PROT_KEY}
-$(eval $(call add_define_val,ARM_PROTPK_HASH,'"$(ARM_PROTPK_HASH)"'))
+$(eval $(call add_define_val,ARM_PROTPK,'"$(ARM_PROTPK)"'))
BL1_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S
BL2_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S
-$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
-$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK)
+$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK)
endif
ifeq (${COT},cca)
# Platform and Secure World Root of Trust key files.
-ARM_PROT_KEY := plat/arm/board/common/protpk/arm_protprivk_rsa.pem
-ARM_PROTPK_HASH := plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
-ARM_SWD_ROT_KEY := plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem
-ARM_SWD_ROTPK_HASH := plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
+ARM_PROTPK := $(BUILD_PLAT)/arm_protpk.bin
+ARM_SWD_ROTPK := $(BUILD_PLAT)/arm_swd_rotpk.bin
# Provide the private keys to cert_create tool. It needs them to sign the images.
PROT_KEY := ${ARM_PROT_KEY}
SWD_ROT_KEY := ${ARM_SWD_ROT_KEY}
-$(eval $(call add_define_val,ARM_PROTPK_HASH,'"$(ARM_PROTPK_HASH)"'))
-$(eval $(call add_define_val,ARM_SWD_ROTPK_HASH,'"$(ARM_SWD_ROTPK_HASH)"'))
+$(eval $(call add_define_val,ARM_PROTPK,'"$(ARM_PROTPK)"'))
+$(eval $(call add_define_val,ARM_SWD_ROTPK,'"$(ARM_SWD_ROTPK)"'))
BL1_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S \
plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
BL2_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S \
plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
-$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
-$(BUILD_PLAT)/bl1/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK_HASH)
-$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
-$(BUILD_PLAT)/bl2/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK_HASH)
+$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK)
+$(BUILD_PLAT)/bl1/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK)
+$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK)
+$(BUILD_PLAT)/bl2/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK)
endif
+$(ARM_PROTPK): $(ARM_PROT_KEY)
+ifndef ARM_PROT_KEY
+ $(error Cannot generate hash: no PROT_KEY defined)
+endif
+ ${OPENSSL_BIN_PATH}/openssl ${CRYPTO_ALG} -in ${ARM_PROT_KEY} -pubout -outform DER | \
+ ${OPENSSL_BIN_PATH}/openssl dgst -${HASH_ALG} -binary -out $@
+
+$(ARM_SWD_ROTPK): $(ARM_SWD_ROT_KEY)
+ifndef ARM_SWD_ROT_KEY
+ $(error Cannot generate hash: no SWD_KEY defined)
+endif
+ ${OPENSSL_BIN_PATH}/openssl ${CRYPTO_ALG} -in ${ARM_SWD_ROT_KEY} -pubout -outform DER | \
+ ${OPENSSL_BIN_PATH}/openssl dgst -${HASH_ALG} -binary -out $@
endif
diff --git a/plat/arm/board/common/protpk/README b/plat/arm/board/common/protpk/README
index 3aca180..15a0a9a 100644
--- a/plat/arm/board/common/protpk/README
+++ b/plat/arm/board/common/protpk/README
@@ -6,9 +6,12 @@
openssl genrsa 2048 > arm_protprivk_rsa.pem
-* arm_protpk_rsa_sha256.bin is the SHA-256 hash of the DER-encoded public key
- associated with the above private key. It has been generated using the openssl
- command line tool:
+* arm_protprivk_ecdsa.pem is a P-256 ECSA private key in PEM format. It has been
+ generated using the openssl command line tool:
- openssl rsa -in arm_protprivk_rsa.pem -pubout -outform DER | \
- openssl dgst -sha256 -binary > arm_protpk_rsa_sha256.bin
+ openssl ecparam -name prime256v1 -genkey -outform PEM -noout -out arm_protprivk_ecdsa.pem
+
+* arm_protprivk_ecdsa_secp384r1.pem is a P-384 ECSA private key in PEM format. It has been
+ generated using the openssl command line tool:
+
+ openssl ecparam -name secp384r1 -genkey -outform PEM -noout -out arm_protprivk_ecdsa_secp384r1.pem
\ No newline at end of file
diff --git a/plat/arm/board/common/protpk/arm_dev_protpk.S b/plat/arm/board/common/protpk/arm_dev_protpk.S
index 2688cbb..79b8c36 100644
--- a/plat/arm/board/common/protpk/arm_dev_protpk.S
+++ b/plat/arm/board/common/protpk/arm_dev_protpk.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,10 +9,31 @@
.section .rodata.arm_protpk_hash, "a"
+/*
+* The protpk header is dependent only on the algorithm used to
+* generate the hash.
+* ASN1_HASH_ALG is the last byte used to encode the OID for
+* the hash algorithm into the header,
+* this byte distinguishes between SHA256, SHA384 and SHA512.
+*/
+.equ HASH_ASN1_LEN, ARM_ROTPK_HASH_LEN
+#if ARM_ROTPK_HASH_LEN == 48
+ .equ ASN1_HASH_ALG, 0x02
+ .equ TOTAL_ASN1_LEN, 0x41
+#elif ARM_ROTPK_HASH_LEN == 64
+ .equ ASN1_HASH_ALG, 0x03
+ .equ TOTAL_ASN1_LEN, 0x51
+#elif ARM_ROTPK_HASH_LEN == 32
+ .equ ASN1_HASH_ALG, 0x01
+ .equ TOTAL_ASN1_LEN, 0x31
+#else
+ .error "Invalid PROTPK hash length."
+#endif
+
arm_protpk_hash:
/* DER header. */
- .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
- .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ .byte 0x30, TOTAL_ASN1_LEN, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, ASN1_HASH_ALG, 0x05, 0x00, 0x04, HASH_ASN1_LEN
/* Key hash. */
- .incbin ARM_PROTPK_HASH
+ .incbin ARM_PROTPK
arm_protpk_hash_end:
diff --git a/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin b/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
deleted file mode 100644
index 587da66..0000000
--- a/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
+++ /dev/null
@@ -1 +0,0 @@
-ó6{W*
`tíve×·§è£ ¾PÆK{9
\ No newline at end of file
diff --git a/plat/arm/board/common/protpk/arm_protprivk_ecdsa.pem b/plat/arm/board/common/protpk/arm_protprivk_ecdsa.pem
new file mode 100644
index 0000000..5888e10
--- /dev/null
+++ b/plat/arm/board/common/protpk/arm_protprivk_ecdsa.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEILviumKhnibRT6+73/WOURk8lCxu/AHRQVcbCn/nGAr8oAoGCCqGSM49
+AwEHoUQDQgAE2HPZeAd+P8kZKHcCMfNUE+MlZSKJV360gYYC1JEdogyYztJ/QbKj
+26CZijUU/He2b9kkCOpZoJp3UuMRlsQE4Q==
+-----END EC PRIVATE KEY-----
diff --git a/plat/arm/board/common/protpk/arm_protprivk_ecdsa_secp384r1.pem b/plat/arm/board/common/protpk/arm_protprivk_ecdsa_secp384r1.pem
new file mode 100644
index 0000000..d9db645
--- /dev/null
+++ b/plat/arm/board/common/protpk/arm_protprivk_ecdsa_secp384r1.pem
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCn+L3kRlvrZKnemt8aDOH+ujwuhpdwAM2ZxacxudJPy5qrWCjXGIh1
+gOAMHlGESySgBwYFK4EEACKhZANiAASM5exqdUZi0msFLGi42bIMW7FPqWsJ8YmL
+scDkI6BUYRoP0V4XZWB7NOjP6y/tm5Uwid9q25QTlhNKUo5qki1YH3T6unHuylWN
+63KRHQLOaXCXZqhMhT0wccg0gG3hs+0=
+-----END EC PRIVATE KEY-----
diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
index 22ae9d3..f4a1875 100644
--- a/plat/arm/board/common/rotpk/arm_dev_rotpk.S
+++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
@@ -6,20 +6,64 @@
#include <plat/arm/board/common/rotpk/rotpk_def.h>
- .global arm_rotpk_header
+#if ARM_ROTPK_IS_HASH == 1
+ .global arm_rotpk_hash_der_header
+ .global arm_rotpk_hash_end
.section .rodata.arm_rotpk_hash, "a"
-arm_rotpk_header:
- .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
- .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
-arm_rotpk_header_len:
+ #ifndef ARM_ROTPK_HASH_LEN
+ .error "ROTPK hash not defined."
+ #endif
-#ifdef ARM_ROTPK_HASH
- .global arm_rotpk_hash_end
- .incbin ARM_ROTPK_HASH
+ /*
+ * The rotpk header is dependent only on the algorithm used to
+ * generate the hash.
+ * ASN1_HASH_ALG is the last byte used to encode the OID for
+ * the hash algorithm into the header,
+ * this byte distinguishes between SHA256, SHA384 and SHA512.
+ */
+ .equ HASH_ASN1_LEN, ARM_ROTPK_HASH_LEN
+ #if ARM_ROTPK_HASH_LEN == 48
+ .equ ASN1_HASH_ALG, 0x02
+ .equ TOTAL_ASN1_LEN, 0x41
+ #elif ARM_ROTPK_HASH_LEN == 64
+ .equ ASN1_HASH_ALG, 0x03
+ .equ TOTAL_ASN1_LEN, 0x51
+ #elif ARM_ROTPK_HASH_LEN == 32
+ .equ ASN1_HASH_ALG, 0x01
+ .equ TOTAL_ASN1_LEN, 0x31
+ #else
+ .error "Invalid ROTPK hash length."
+ #endif
+
+arm_rotpk_hash_der_header:
+ .byte 0x30, TOTAL_ASN1_LEN, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, ASN1_HASH_ALG, 0x05, 0x00, 0x04, HASH_ASN1_LEN
+arm_rotpk_hash_der_header_len:
+
+#ifdef ARM_ROTPK
+ .incbin ARM_ROTPK
arm_rotpk_hash_end:
#endif
-.if ARM_ROTPK_HEADER_LEN != arm_rotpk_header_len - arm_rotpk_header
-.error "Invalid ROTPK header length."
-.endif
+ .if ARM_ROTPK_HASH_DER_HEADER_LEN != arm_rotpk_hash_der_header_len - arm_rotpk_hash_der_header
+ .error "Invalid ROTPK header length."
+ .endif
+
+#else
+ /*
+ * The rotpk is an unhashed public key in DER format.
+ * We do not need a header in this case.
+ */
+ .global arm_rotpk_key
+ .section .rodata.arm_rotpk_key, "a"
+
+arm_rotpk_key:
+ #ifdef ARM_ROTPK
+ .global arm_rotpk_key_end
+ .incbin ARM_ROTPK
+arm_rotpk_key_end:
+ #else
+ .error "ROTPK not found."
+ #endif
+#endif
\ No newline at end of file
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
deleted file mode 100644
index 690bdbc..0000000
--- a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
- .global arm_rotpk_key
- .global arm_rotpk_key_end
-
- .section .rodata.arm_rotpk_key, "a"
-
-/* Derived from arm_rotprivk_ecdsa.pem private key file. */
-arm_rotpk_key:
- .byte 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D
- .byte 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01
- .byte 0x07, 0x03, 0x42, 0x00, 0x04, 0x9B, 0xE6, 0x48, 0xBD, 0x34, 0x38
- .byte 0xE1, 0xA2, 0xA4, 0xF3, 0x70, 0xE1, 0x54, 0xBB, 0x2F, 0xB0, 0x5A
- .byte 0x4A, 0x0C, 0xFF, 0xC2, 0x87, 0xDB, 0xC0, 0xFB, 0x81, 0xE9, 0xF9
- .byte 0xF9, 0x95, 0x7D, 0x7E, 0xA0, 0x0C, 0x7F, 0x0A, 0xD4, 0xE0, 0x62
- .byte 0x4A, 0x94, 0x5F, 0xEC, 0x52, 0x7D, 0x44, 0x63, 0xC8, 0x9F, 0x61
- .byte 0xFA, 0xC6, 0xCB, 0x7E, 0x6B, 0x53, 0xAD, 0x2C, 0xC5, 0x94, 0x0D
- .byte 0x1A, 0x86, 0x91
-arm_rotpk_key_end:
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
deleted file mode 100644
index eaf2de4..0000000
--- a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
- .global arm_rotpk_key
- .global arm_rotpk_key_end
-
- .section .rodata.arm_rotpk_key, "a"
-
-/* Derived from arm_rotprivk_ecdsa_secp384r1.pem private key file. */
-arm_rotpk_key:
- .byte 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D
- .byte 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62
- .byte 0x00, 0x04, 0xB8, 0xB0, 0xC7, 0xC4, 0x57, 0x19, 0xB7, 0x5A, 0x06
- .byte 0x36, 0xC5, 0xD8, 0x3C, 0x4E, 0xC3, 0xB5, 0xE1, 0x15, 0x60, 0x0E
- .byte 0x63, 0xD8, 0xAF, 0x22, 0x2C, 0x6D, 0x79, 0x29, 0xDF, 0x46, 0xA9
- .byte 0x30, 0x12, 0x16, 0x2D, 0x4F, 0x0F, 0x96, 0x6B, 0x1F, 0x87, 0x06
- .byte 0xDB, 0x8F, 0xD7, 0x08, 0x46, 0xE4, 0x4C, 0x22, 0xF3, 0xDE, 0xCE
- .byte 0x0F, 0x72, 0x27, 0x00, 0xAA, 0xD8, 0xC3, 0x79, 0x80, 0x5E, 0xF1
- .byte 0x35, 0x1B, 0x33, 0xB6, 0x31, 0xC4, 0x59, 0xD4, 0xE9, 0x65, 0x91
- .byte 0x22, 0x58, 0x2F, 0x87, 0xF1, 0x6C, 0x27, 0xBE, 0x99, 0x6F, 0x5F
- .byte 0x6C, 0x14, 0xC5, 0x37, 0x0C, 0x73, 0xB4, 0xE4, 0x8A, 0x63
-arm_rotpk_key_end:
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
deleted file mode 100644
index 4532e53..0000000
--- a/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
- .global arm_rotpk_key
- .global arm_rotpk_key_end
-
- .section .rodata.arm_rotpk_key, "a"
-
-arm_rotpk_key:
- .byte 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48
- .byte 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01
- .byte 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00
- .byte 0xCB, 0x2C, 0x60, 0xD5, 0x8D, 0x63, 0xD4, 0x07, 0x79, 0x7E, 0xC7
- .byte 0x16, 0x96, 0xBD, 0x4D, 0x24, 0x4E, 0xAC, 0x86, 0xE6, 0xB7, 0x71
- .byte 0xE3, 0xC5, 0x54, 0x0B, 0xE7, 0x14, 0x1C, 0xBD, 0x29, 0x1A, 0xC1
- .byte 0x3F, 0x7A, 0xB6, 0x02, 0xAA, 0xAB, 0x36, 0xC4, 0xD9, 0x36, 0x69
- .byte 0x6C, 0xE2, 0x65, 0xC3, 0x9B, 0xB1, 0xBF, 0x3D, 0xA8, 0x56, 0x26
- .byte 0xCB, 0xFD, 0x04, 0x01, 0xBA, 0xAC, 0x3E, 0x54, 0x32, 0xCA, 0x79
- .byte 0x5E, 0xBB, 0xB2, 0x05, 0xEA, 0x06, 0x58, 0xF2, 0x74, 0xBA, 0xE1
- .byte 0xF4, 0x87, 0xC0, 0x19, 0x0A, 0x1F, 0x66, 0x07, 0x77, 0x84, 0x83
- .byte 0xA1, 0x1C, 0xEF, 0xFF, 0x28, 0x59, 0xE7, 0xC3, 0x68, 0x7D, 0x26
- .byte 0x20, 0x43, 0xEB, 0x56, 0x63, 0xF3, 0x39, 0x31, 0xD8, 0x2B, 0x51
- .byte 0xA9, 0xBC, 0x4F, 0xD0, 0xF6, 0xDE, 0x95, 0xDC, 0x5F, 0x5B, 0xC1
- .byte 0xED, 0x90, 0x6F, 0xEC, 0x28, 0x91, 0x7E, 0x17, 0xED, 0x78, 0x90
- .byte 0xF4, 0x60, 0xA7, 0xC4, 0xC7, 0x4F, 0x50, 0xED, 0x5D, 0x13, 0x3A
- .byte 0x21, 0x2B, 0x70, 0xC5, 0x61, 0x7B, 0x08, 0x21, 0x65, 0x3A, 0xCD
- .byte 0x82, 0x56, 0x8C, 0x7A, 0x47, 0xAC, 0x89, 0xE8, 0xA5, 0x48, 0x48
- .byte 0x31, 0xD9, 0x1D, 0x46, 0xE5, 0x85, 0x86, 0x98, 0xA0, 0xE5, 0xC0
- .byte 0xA6, 0x6A, 0xBD, 0x07, 0xE4, 0x92, 0x57, 0x61, 0x07, 0x8F, 0x7D
- .byte 0x5A, 0x4D, 0xCA, 0xAE, 0x36, 0xB9, 0x56, 0x04, 0x10, 0xF2, 0x6C
- .byte 0xBE, 0xF6, 0x3B, 0x6C, 0x80, 0x3E, 0xBE, 0x0E, 0xA3, 0x4D, 0xC7
- .byte 0xD4, 0x7E, 0xA7, 0x49, 0xD4, 0xF2, 0xD2, 0xBC, 0xCF, 0x30, 0xA8
- .byte 0xE7, 0x74, 0x8F, 0x64, 0xDF, 0xBC, 0x5C, 0x47, 0x68, 0xCC, 0x40
- .byte 0x4C, 0xF8, 0x83, 0xCC, 0xCB, 0x40, 0x35, 0x04, 0x60, 0xCA, 0xB3
- .byte 0xA4, 0x17, 0x9F, 0x03, 0xCA, 0x1D, 0x5A, 0xFA, 0xD1, 0xAF, 0x21
- .byte 0x57, 0x10, 0xD3, 0x02, 0x03, 0x01, 0x00, 0x01
-arm_rotpk_key_end:
diff --git a/plat/arm/board/common/rotpk/arm_rotpk_ecdsa.der b/plat/arm/board/common/rotpk/arm_rotpk_ecdsa.der
deleted file mode 100644
index 2547877..0000000
--- a/plat/arm/board/common/rotpk/arm_rotpk_ecdsa.der
+++ /dev/null
Binary files differ
diff --git a/plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin b/plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
deleted file mode 100644
index c5e123a..0000000
--- a/plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
+++ /dev/null
@@ -1 +0,0 @@
-.@¿nù»1q =ýÑÌiJë ° Nl
\ No newline at end of file
diff --git a/plat/arm/board/common/rotpk/arm_rotpk_rsa.der b/plat/arm/board/common/rotpk/arm_rotpk_rsa.der
deleted file mode 100644
index 661f899..0000000
--- a/plat/arm/board/common/rotpk/arm_rotpk_rsa.der
+++ /dev/null
Binary files differ
diff --git a/plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin b/plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
deleted file mode 100644
index 7653f7e..0000000
--- a/plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
+++ /dev/null
@@ -1 +0,0 @@
-°ó Ø:7zrGì2sé2âIYö^JJFØ"Ú
\ No newline at end of file
diff --git a/plat/arm/board/common/rotpk/arm_rotprivk_rsa_3k.pem b/plat/arm/board/common/rotpk/arm_rotprivk_rsa_3k.pem
new file mode 100644
index 0000000..842979d
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_rotprivk_rsa_3k.pem
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+MIIG/QIBADANBgkqhkiG9w0BAQEFAASCBucwggbjAgEAAoIBgQCi82DxdQ1Z88RT
+DBoK8nBZ3SF4YSnOSV3KXODZHtEJq/D1HihLpCITsB1GkR17qGX5XzjcIvrS7tGC
+1Y/ELC+wL1DNoNlLsgwfZdQ3+MGGlkymnK37/b5Q1bvkuthAHg415skvdzX+6tpM
+y3bbGn55oW+hjynGo9lhixZiOA22sKhHFM6TBgpyNyXt/EpxGHcL4HM59LSWgB3I
+UX6l0Fb5MLb3XRzOkPcf6tQwnupDRS8rcRKHlkq8m0kIZ619zDkj4DZVW7VSU3hj
+vnzMMTEqbJ9uBnGFLdTqw2O822jOtKJ8pDqcN1xEe60a0CN0abN5uNzr9WPgLw5d
+ZjWqTx2kFVbjIr5nAiY6KTUoas/radidv/r5BY4wXvbi/SVNHip4oLoKCgu6T+Un
+pIc5DG0osXKO/xtT5gsQUZ/AXEztCsEeuwkueEZ8c1AG+ceoOul/zH4y0YrFGzxV
+apwwRuXZQtjU0lXpFlD1Yy83QzkrxWgEfE5mUm402TRF92oLsY8CAwEAAQKCAYA5
+QBwLyW3G8FPGP8a4mOQrVntncW/AN9uZeRdQgTi9VqkiXZWXudN1Klemzt5Wb1xg
+iHmQMkQArwJyHrlTmZippH4VuNEPfL8wmtS8U4wezpigowSnt8dRXD6XBqRqpoSk
+oHCH2jDg3r+S4ptgMIdGEZeIYiWx0ihSUo0rNflvedKtopxPYHx0E3cijZTT9l4B
+ELs7HgQCqoGMO0GtXSzpgRmPgCnaU2lXz+f8KyEwQFLpxuDVPVMFv+Mhblewjnrn
+IpDUAocRPI1n0cOrObHHnnpVzkKpz4usxBfsvc+9Qg37hS/1ccbOWKPjA/LS9dOC
+w29J6pa3Az9AGQ6OdZlhbaOH7hMj4gmreC/4omtgV+IhOL65TeMeBwIY0Vb4gtCQ
+yHhu2eT99MeL+G/Zw+00RRqzKl898tnYTvBkFG1llIFyT9LRqPY8lRHAQzzgNTRq
+ZpwTAijCRxmBAIDdBkXQai/En2PP3LMuORZ9+2zYu5uIJeZnBoHKONtDlpOpKpkC
+gcEA2HkeVlfmFgiBen4QMRKCseB9II9s+xiPjk8VpWT2TRmsVPEmKRrIKkXER2YO
+yYG97vBocECQXOHB0dNNUTMtbnFvY9B0FAswcUwtWPdjafrqmPe6iIZkynTaFqCG
+nY52P4EYZsSF3YthXkkzZuwzaQ/zyVA5W2HXp/XL8SKj9uPA3dEMP114Of9jNlmH
++gfpNY49tiXomR1DX/k6nmyJyeG9eUVBGlmxERK72g/7OynYLK8o/7T3m8SUW5lq
+R5hZAoHBAMC0ZI36iq2m18xtEx84nrlipbRRRahIeb2bXziPBL3yEbomotwrabDl
+GExl3PpfAEUlNnqseZ3GS2EpESsEbOBnLuWmviF528pX/H/pw87AVjuseUZQOjzI
+GzuJu+Of0DNlt7FJsaWrOJeNqT0t1w0JiII3uEekmIC59740lyUJ2sVZlDq6Gf7i
+etV+7oqGn+aAmXgug0wszezMaYH8ZNjLgrxkxIsLSONQ8tUX3CYXglkqty0/JRVA
+ZCluTQ/cJwKBwHzESlz/qoi2fFIqiJCQF64IMnZq1ChhPpSKNnKun1tO2cnXd+Qn
+IIlkzr1MMGeqFNu7yqYwQESYhgq23BBaC+xlCwufoNfQnyod+uEVLUJvMXnbBrMb
+qsoZ0X1LJmt3KeZuNK8+w90uMX+Td0HyD6uVWzCDwZtO6GpRPCuOiKyLFqWCkKmQ
+6POcpAU2Uy4kEyEgC6eJb+eYOzX8wvF+o2gtaPSVmvFiErFBd+42Wdn+wy72Ag5n
+snMgOVYWNXBweQKBwQCcsBEzAIzSNd8x8V6i/D7TLkreG1cwRf33FeaO7ntElxei
+7Ndvfj0qAJ2JQSo0yhpGHsP1a1hX2WxhTCsRdz+wFzYitTnTrmnwVSqSN1lnOyzi
+yJKzgXhZA7xg5NVJeCCqKgL6vJkdw+L4F8+MV0GM8Dt25ieI2WTHBm9S0SA0lZa0
+8Ol99uQ8Q5rtDZCYQm6x1c7z0Z4gyi2GZY9EihzVymQ7GxRUmpBhhOhuLEBtGKB8
+MCdROw7EAN9wcKdoRfECgcB5zqNzKu2kbpa0oeHLLDpcOK1w9e7khN3/j3dTrpRw
+em8+HoCF54PoyfkPWANTHfg+Bs2gktgvUsxfLy0/DDBIRUBQXo6AyztfB34D5/3L
+QIPyPjSgQKxOCnUCcDAkvVRY+6J7W6J/pW385ZhzikCUrRSKrbc3UYEu3UZwypSC
+mJGKLUzhDhPYvIginpIugE9Pv3WXfKas3HRrk7UdqjIMpJxIRF5CULsEaZua6tje
+1oA5miNwoiXHcxPoo2qMtz8=
+-----END PRIVATE KEY-----
diff --git a/plat/arm/board/common/rotpk/arm_rotprivk_rsa_4k.pem b/plat/arm/board/common/rotpk/arm_rotprivk_rsa_4k.pem
new file mode 100644
index 0000000..2309ee6
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_rotprivk_rsa_4k.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDGeG6dmMX7DHdx
+LJ5vi3HpqSLVfyiGzYmjN14bcOORf1efCXy+0KfZ4M/N1rw/fVzIH6LP6iKm8rrH
+HQleKMb2rklbu8Azchr9fAJCbbbhENjhbp+lnh5W+bMWlhz4ePoSft/VNDssK/30
+tedSX7AEqs8nXOcqIjcOTnkB1UocNSAd98WP+m7oeqcwrJZGFj2HKHPkZiveX4c6
+5pN7xsdeuJ00FbOau7R3tX+0hInbTCxuA9UfPR9O+TrElMETPBCwvYUDo8SO0Oj9
+Vn3VsMYLuYfOQuHY65pgepBytgu6MTL8mKGxMTZ3HeaBfD2cDzf1tOe3PoN2eeBA
+eGHt/L9R7z0/84kfWDJg8zG9eSfCofXJy3HNlYAWo7fIdRaidNc75vU3DWRYrCE2
+OLwR+3pIRUoP+Pa1Xhaal/mXH9MHKNvK2aBz2QPgjaujMNlh9yLLtBjnBAcO9IXh
+ktS2pnEYwf+Rh2Nepy2sJa4Q88ZD7Uz8MZl7z/zNUjNpehDIe7oM8NXMt/i1DWqe
+XZoLfTdb7C77hgNfporBxkeqduhGGcu+RUgdAOMEJvFA4022iiZIJDkWeaiFZWI4
+iy9bmFd+VOXabCIAjb0Nl6F5TAROJ/mH9UjyT8hKlXYhnRu912+yEaFAlqiXk2rz
+kYbGGzj9zUMzClM52wJ7Btj50dz0eQIDAQABAoICAB62uHePEuRc84cCHqqoa8J7
+ODbN7NmfqTMm+FtKxwzXJhoof7OP2snu7nmuR4eTwO3/Z1TBqQco/RqfNbnqmY/H
+PPcDQSU0/VRJApiBHhIKZ2XLls0sgQl4ruxJ4sXZAuol1EHMSXP2guCB3gBzamvu
+ewxeZi+xB9Ag+Lz94vAmkIfStjIn0U4M3R69Nqw1+OOXsQehgBxzsBu/XweCpYvV
+Cg7rZNYHQlBcOB0ZfbQAP8fus+aXsOapzxxo4NA3NWYEjjcX+u0XC1dZMTQGnT9n
+QMr8srK9EzDnBr+ZyIrR3lAU1sDzGrioWemj7mzeNgzCKDHFbNbC2Z9ggdcwi/K+
+SX3ckR8phNkhGyIWImt5ChY19d/yh53A/FwFEJU4R/HiM0GFj8bxWMRr01R1TJV6
+UUb6c4L/T95URqe05bTAWz/BUUWirGs8F03NUp/8PvXquUJiKs3eEMHeyHDIt2Rj
+mB0bi+nr0qe4C7Y5yU9+Giw9RnV7slBkQvohA7mHXRlneenQx+Lh1v2fNk+Z+eVF
+Y7HBdTiNeavW8ZReoVgicqA8w2KZgbiDAhhJ2pzefpREjVAnY2endbMX4faqfEMF
+y6StIsg4rplrxojVIYftQ+nenSV0H+5I6+YsIk4XTirGYuBhccoko0ApRJx9VdX2
++UJU49UPHK2fTdqqouc5AoIBAQDmEqfyXQdf+5njZ3zx9cJFKRXB8SiFIDNZeSDL
+b8ph7py1YfinM163Xyb2/5oTB19tcNcfAaPoFOHJ8FDzXmSW3aUHKrB+sh8Q+aOH
+/3u6y2+dBEBNGPbtSxmMswVYK2z0K6NzzeZSZnqus0J61RPuG8EnO25PdMx9xOg/
+cPWTrxYNUYIBqSdhjm8K5BaTrkOf49Wur/0MZlcULVoatFzc3H/L3qyePvptKAwT
+V68bZeM2mXWhC3X953kxX5haClWZPJhf9sLESIeoOleaMi5yBvX6r7JKiFJy3Fwk
+dV7lPWr9fEkVtVoveHklCW8Ra6JbMizV7i1S5fmUcaUmgbbTAoIBAQDc1hTMI98o
+7hDEqh1cHtPmh1u9rLgJEMYLirUn/u4QDV6SUpT1Bpu55usLn+NFDyKfpEh1IU4r
+4CjfrjP15e2WLs+IOU+LvbDqbps7mEnq/TFWwr1YcjUVpur4SphJkqFHU/ztV6RC
+FbTA8656kb34YrILDnjgM7G1TKvWRHxzqdDCasPnlv7ch2/vtwv5zcVfTSNjixFb
+b8FCPy8WI6/LIFjKmSliLaeRb0NaUAWwMQ2qMEuP+rsGaq4Lr/6zf/UjSUcTgKzQ
+GSVm5cdJqjcqULFQzFZaOoG7Dht+ZJXumwc0G+k1eTuDAnYRs5CkEggtrnK9WfGm
+nBvGOAdeBvADAoIBAAPayCmNWXRIONnQgA1luq2B9LVdHvqsAXA8UUpXQyLE5qc7
+TvkuKSYVWAfHXIN5GiYxP8lrM53Ny8KgXhrVuAW3DO7DzlUxEsgsBotewmnswp/0
+1Eb2Zhyvp2vuC+bgQ2EL4h8skfFLej63DiQUsdLJcEECA+Uc5dgtll6Ju/OPeWUb
+unvgo6JEyqN6Es7CmqtxG8FjfW/Zvxe9cscDwpKItzNpNacpEvUFOL6SN4LUACyI
+AaqDEKUCXctv+JN5nNmGZF8nOTgkpvEwmQsiUBjk+PYMP4Z0Jj16Z6jMtpxMnSBG
+FstgUHR/JjhyogO+s+enPY0QAn5jD/1msgelILUCggEBAMV5emeBvFBxcfUq2c5C
+kuIWMGdQR9FzemVfx9bYFDGugt79kc359s8qOwzOEQD0I9X1pgV3ntuFO4ep0zUU
+QnyFp3b9KLChE87O0WldKNxFRRV8Vqz8k5OlC4Cz07IWuLl71TS3pl6h4lyYi3F3
+WhT+zI8uhdCW6VZiFVcpLtCPDeqMZlp1n7m8MtB9MuxSoSgzZm3hMcg+CucecRCv
+IMfXSQ8CHwt4H9vhTq032Z5QfxOs1CUP5KY8Rx6UZoJE7gR7xl8eNWpw0g1NdAPf
+fi0Ms0K5No7Aurl2SAeiEqCnaK2kN8plel4QmVwC4liU91NCJ8BC6eA+wGdkOtJO
+CdkCggEAG6v3cc6mw/kA3l+z21NzAXFUnYy7Q9xxl6noNBdNtT+vBQJ2jbEISSqi
+RM48KKtky2pgFWB980XUS1ZI8SiZ9GveM9bCSgpN+zupSdKNBaxT7+AKO/MPKMeO
+hukkWqtNCwFs6opByhLMRMC2UAKRSvTZBlrCUyIBY2EB6IzsqqQGdoAHOw2fDWay
+7C79JxtEl/XH10Et7zeWEI2uz6JK4TmSd2ZZu6m/X1UU6BHZJTHpItZlTnp14QYc
+hpHcRHU5d5i+ARQ+kUUynfEyAabY6sBIn3lxXqa9FplR0vqbtxyZPtQh1ZP11drD
+ihQEUR+haaYi8LFFpxe3Lja8D5eclg==
+-----END PRIVATE KEY-----
diff --git a/plat/arm/board/common/swd_rotpk/README b/plat/arm/board/common/swd_rotpk/README
index b628a5f..18fea4c 100644
--- a/plat/arm/board/common/swd_rotpk/README
+++ b/plat/arm/board/common/swd_rotpk/README
@@ -6,9 +6,12 @@
openssl genrsa 2048 > arm_swd_rotprivk_rsa.pem
-* swd_rotpk_rsa_sha256.bin is the SHA-256 hash of the DER-encoded public key
- associated with the above private key. It has been generated using the openssl
- command line tool:
+* arm_swd_rotprivk_ecdsa.pem is a P-256 ECSA private key in PEM format. It has been
+ generated using the openssl command line tool:
- openssl rsa -in arm_swd_rotprivk_rsa.pem -pubout -outform DER | \
- openssl dgst -sha256 -binary > arm_swd_rotpk_rsa_sha256.bin
+ openssl ecparam -name prime256v1 -genkey -outform PEM -noout -out arm_swd_rotprivk_ecdsa.pem
+
+* arm_swd_rotprivk_ecdsa_secp384r1.pem is a P-384 ECSA private key in PEM format. It has been
+ generated using the openssl command line tool:
+
+ openssl ecparam -name secp384r1 -genkey -outform PEM -noout -out arm_swd_rotprivk_ecdsa_secp384r1.pem
diff --git a/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S b/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
index ae4f9d2..2056bbe 100644
--- a/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
+++ b/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,10 +9,31 @@
.section .rodata.arm_swd_rotpk_hash, "a"
+/*
+* The swd_roptpk header is dependent only on the algorithm used to
+* generate the hash.
+* ASN1_HASH_ALG is the last byte used to encode the OID for
+* the hash algorithm into the header,
+* this byte distinguishes between SHA256, SHA384 and SHA512.
+*/
+.equ HASH_ASN1_LEN, ARM_ROTPK_HASH_LEN
+#if ARM_ROTPK_HASH_LEN == 48
+ .equ ASN1_HASH_ALG, 0x02
+ .equ TOTAL_ASN1_LEN, 0x41
+#elif ARM_ROTPK_HASH_LEN == 64
+ .equ ASN1_HASH_ALG, 0x03
+ .equ TOTAL_ASN1_LEN, 0x51
+#elif ARM_ROTPK_HASH_LEN == 32
+ .equ ASN1_HASH_ALG, 0x01
+ .equ TOTAL_ASN1_LEN, 0x31
+#else
+ .error "Invalid SWD_ROTPK hash length."
+#endif
+
arm_swd_rotpk_hash:
/* DER header. */
- .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
- .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ .byte 0x30, TOTAL_ASN1_LEN, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, ASN1_HASH_ALG, 0x05, 0x00, 0x04, HASH_ASN1_LEN
/* Key hash. */
- .incbin ARM_SWD_ROTPK_HASH
+ .incbin ARM_SWD_ROTPK
arm_swd_rotpk_hash_end:
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin b/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
deleted file mode 100644
index b2f3e60..0000000
--- a/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
+++ /dev/null
@@ -1 +0,0 @@
-0¾âÃæÈË(ì¨0wIÓÕéã¡gk
\ No newline at end of file
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa.pem b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa.pem
new file mode 100644
index 0000000..be40565
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIFmIjAPUmyqDfKXT+kKRMvyFzQfaZekczIzSPfLeQUGyoAoGCCqGSM49
+AwEHoUQDQgAEtZB8OrBV7hPl+lBrc5ypKetwGsUi+SpTK8OoMw0GwA17rGDYdBTV
+JK2ttZNtCsGzlDrXeHu6bcTmrleMdW9NdQ==
+-----END EC PRIVATE KEY-----
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa_secp384r1.pem b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa_secp384r1.pem
new file mode 100644
index 0000000..14ad7f7
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_ecdsa_secp384r1.pem
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDC348NhWsLI30vzJnWofKae6t3S6YIb5rdLEJSUyI9XwKj8FyJO8N3G
+DNgvVBwk4NigBwYFK4EEACKhZANiAARodLWP/EGH7/SrImvwDJr1zACOrh8acVH/
+eymfvZW2af4DPRMPyUC5Ftzv6NwGz6yPzBbAg9+qDgLgO7cqwXOwVON+hAU+ECEZ
+3AIQ7zLDfnXcfNz8dv1kwkwhfDJeQCs=
+-----END EC PRIVATE KEY-----
diff --git a/plat/arm/board/fvp/fdts/fvp_stmm_manifest.dts b/plat/arm/board/fvp/fdts/fvp_stmm_manifest.dts
new file mode 100644
index 0000000..df6810f
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_stmm_manifest.dts
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include <platform_def.h>
+
+/ {
+#define MODE_SEL0 (0x1)
+#define MODE_SEL1 (0x2)
+
+#define SECURE_RO 0x1
+#define SECURE_RW 0x3
+#define SECURE_EXECUTE_RO 0x5
+#define SECURE_EXECUTE_RW 0x7
+#define NON_SECURE_RO 0x9
+#define NON_SECURE_RW 0xB
+#define NON_SECURE_EXECUTE_RO 0xD
+#define NON_SECURE_EXECUTE_RW 0xF
+ /*
+ * FF-A compatible Secure Partition Manager parses the
+ * config file and fetch the following booting arguments to
+ * pass on to the StandAloneMM(StMM) Secure Partition.
+ */
+ compatible = "arm,ffa-manifest-1.0";
+
+ description = "FVP Base StandaloneMm";
+ ffa-version = <0x00010002>; /* 31:16 - Major, 15:0 - Minor */
+ uuid = <0xdcae8d37 0x46446bf0 0xab401483 0xa3873c93>;
+ id = <0x8001>;
+ execution-ctx-count = <PLATFORM_CORE_COUNT>;
+ exception-level = <MODE_SEL0>; /* SEL0*/
+ execution-state = <0>; /* AArch64*/
+ load-address = <0x0 0xff200000>;
+ image-size = <0x0 0x00300000>;
+ xlat-granule = <0>; /* 4KiB */
+ boot-order = <0>;
+ messaging-method = <0x603>; /* Direct req/resp/req2/resp2 supported. */
+ gp-register-num = <0>;
+
+ device-regions {
+ compatible = "arm,ffa-manifest-device-regions";
+
+ /**
+ * System registers, rtc, uart and etc regions for access from S-EL0.
+ */
+ io_fpga {
+ base-address = <0x0 0x1C000000>;
+ pages-count = <0x3000>;
+ attributes = <SECURE_RW>;
+ };
+
+ system_reg_el0 {
+ base-address = <0x0 0x1C010000>;
+ pages-count = <0x10>;
+ attributes = <SECURE_RW>;
+ };
+
+ /**
+ * ARM CSS SoC Peripherals area.
+ * Similar to SOC_CSS_MAP_DEVICE.
+ */
+ soc_components {
+ base-address = <0x0 0x20000000>;
+ pages-count = <0xc200>;
+ attributes = <SECURE_RO>;
+ };
+
+ /**
+ * NOR0 Flash region, used for Firmware Image Update.
+ */
+ nor_flash0 {
+ base-address = <0x0 0x08000000>;
+ pages-count = <0x4000>;
+ attributes = <SECURE_RW>;
+ };
+
+ /**
+ * NOR1 Flash region, used for Secure booting.
+ */
+ nor_flash1 {
+ base-address = <0x0 0x0c000000>;
+ pages-count = <0x4000>;
+ attributes = <SECURE_RW>;
+ };
+ };
+
+ memory-regions {
+ compatible = "arm,ffa-manifest-memory-regions";
+
+ /*
+ * SPM Payload memory. Mapped as code region for S-EL0
+ * Similar to ARM_SP_IMAGE_MMAP.
+ */
+ stmm_region {
+ description = "image";
+ base-address = <0x0 0xff200000>;
+ pages-count = <0x300>;
+ /* StMM will remap the regions during runtime */
+ attributes = <SECURE_EXECUTE_RO>;
+ };
+
+ /*
+ * Memory shared between EL3 and S-EL0.
+ * Similar to ARM_SPM_BUF_EL0_MMAP.
+ */
+ rx-tx-buffers {
+ description = "shared-buff";
+ base-address = <0x0 0xff500000>;
+ pages-count = <0x100>;
+ attributes = <SECURE_RW>;
+ };
+
+ /*
+ * Memory shared between Normal world and S-EL0.
+ * Similar to ARM_SP_IMAGE_NS_BUF_MMAP.
+ */
+ ns_comm_buffer {
+ /*
+ * Description is needed for StMM to identify
+ * ns-communication buffer.
+ */
+ description = "ns-comm";
+ base-address = <0x0 0xff600000>;
+ pages-count = <0x10>;
+ attributes = <NON_SECURE_RW>;
+ };
+
+ /*
+ * Heap used by SP to allocate memory for DMA.
+ */
+ heap {
+ /*
+ * Description is needed for StMM to identify
+ * heap buffer.
+ */
+ description = "heap";
+ base-address = <0x0 0xFF610000>;
+ pages-count = <0x7F0>;
+ attributes = <SECURE_RW>;
+ };
+ };
+};
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index ebdd80d..8dcdd62 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -48,8 +48,6 @@
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
{
- struct transfer_list_entry *te __unused;
-
#if TRANSFER_LIST
arg0 = arg3;
#endif
diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c
index 573d92e..5b97034 100644
--- a/plat/arm/board/fvp/fvp_security.c
+++ b/plat/arm/board/fvp/fvp_security.c
@@ -24,7 +24,7 @@
const arm_tzc_regions_info_t fvp_tzc_regions[] = {
ARM_TZC_REGIONS_DEF,
-#if !SPM_MM && !ENABLE_RME
+#if !SPM_MM && !ENABLE_RME && !(SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
{FVP_DRAM3_BASE, FVP_DRAM3_END,
ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS},
{FVP_DRAM4_BASE, FVP_DRAM4_END,
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index e0c9725..df4be8f 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -170,6 +170,8 @@
# elif SPMC_AT_EL3
# define PLAT_ARM_MMAP_ENTRIES 13
# define MAX_XLAT_TABLES 11
+# define PLAT_SP_IMAGE_MMAP_REGIONS 30
+# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else
# define PLAT_ARM_MMAP_ENTRIES 9
# if USE_DEBUGFS
@@ -220,7 +222,8 @@
* In case of PSA Crypto API, few algorithms like ECDSA needs bigger BL1 RW
* area.
*/
-#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA || PSA_CRYPTO
+#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA || PSA_CRYPTO || \
+FVP_TRUSTED_SRAM_SIZE == 512
#define PLAT_ARM_MAX_BL1_RW_SIZE UL(0xC000)
#else
#define PLAT_ARM_MAX_BL1_RW_SIZE UL(0xB000)
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index 077283e..a23de73 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -37,28 +37,5 @@
fdt fdt_get_alias
fdt fdt_node_offset_by_phandle
fdt fdt_add_subnode
-mbedtls mbedtls_asn1_get_alg
-mbedtls mbedtls_asn1_get_alg_null
-mbedtls mbedtls_asn1_get_bitstring_null
-mbedtls mbedtls_asn1_get_bool
-mbedtls mbedtls_asn1_get_int
-mbedtls mbedtls_asn1_get_len
-mbedtls mbedtls_asn1_get_tag
-mbedtls mbedtls_free
-mbedtls mbedtls_md
-mbedtls mbedtls_md_get_size
-mbedtls mbedtls_memory_buffer_alloc_init
-mbedtls mbedtls_oid_get_md_alg
-mbedtls mbedtls_oid_get_numeric_string
-mbedtls mbedtls_oid_get_pk_alg
-mbedtls mbedtls_oid_get_sig_alg
-mbedtls mbedtls_pk_free
-mbedtls mbedtls_pk_init
-mbedtls mbedtls_pk_parse_subpubkey
-mbedtls mbedtls_pk_verify_ext
-mbedtls mbedtls_platform_set_snprintf
-mbedtls mbedtls_x509_get_rsassa_pss_params
-mbedtls mbedtls_x509_get_sig_alg
-mbedtls mbedtls_md_info_from_type
c exit
c atexit
diff --git a/plat/arm/board/fvp/jmptbl_mbedtls.i b/plat/arm/board/fvp/jmptbl_mbedtls.i
new file mode 100644
index 0000000..6e1f017
--- /dev/null
+++ b/plat/arm/board/fvp/jmptbl_mbedtls.i
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform-specific ROMLIB MbedTLS functions can be added here.
+# During the build process, this file is appended to jmptbl.i
+# if MbedTLS support is required.
+#
+# Format:
+# lib function [patch]
+# Example:
+# mbedtls mbedtls_asn1_get_alg
+# mbedtls mbedtls_asn1_get_alg_null patch
+
+mbedtls mbedtls_asn1_get_alg
+mbedtls mbedtls_asn1_get_alg_null
+mbedtls mbedtls_asn1_get_bitstring_null
+mbedtls mbedtls_asn1_get_bool
+mbedtls mbedtls_asn1_get_int
+mbedtls mbedtls_asn1_get_len
+mbedtls mbedtls_asn1_get_tag
+mbedtls mbedtls_free
+mbedtls mbedtls_md
+mbedtls mbedtls_md_get_size
+mbedtls mbedtls_memory_buffer_alloc_init
+mbedtls mbedtls_oid_get_md_alg
+mbedtls mbedtls_oid_get_numeric_string
+mbedtls mbedtls_oid_get_pk_alg
+mbedtls mbedtls_oid_get_sig_alg
+mbedtls mbedtls_pk_free
+mbedtls mbedtls_pk_init
+mbedtls mbedtls_pk_parse_subpubkey
+mbedtls mbedtls_pk_verify_ext
+mbedtls mbedtls_platform_set_snprintf
+mbedtls mbedtls_x509_get_rsassa_pss_params
+mbedtls mbedtls_x509_get_sig_alg
+mbedtls mbedtls_md_info_from_type
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 0156b31..8793840 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -22,7 +22,12 @@
# only; enable redistributor frames of all CPU cores by default.
FVP_GICR_REGION_PROTECTION := 0
+ifeq (${HW_ASSISTED_COHERENCY}, 0)
FVP_DT_PREFIX := fvp-base-gicv3-psci
+else
+FVP_DT_PREFIX := fvp-base-gicv3-psci-dynamiq
+endif
+# fdts is wrong otherwise
# Size (in kilobytes) of the Trusted SRAM region to utilize when building for
# the FVP platform. This option defaults to 256.
@@ -57,6 +62,8 @@
ENABLE_BRBE_FOR_NS := 2
ENABLE_TRBE_FOR_NS := 2
ENABLE_FEAT_D128 := 2
+ ENABLE_FEAT_FPMR := 2
+ ENABLE_FEAT_MOPS := 2
endif
ENABLE_SYS_REG_TRACE_FOR_NS := 2
@@ -218,7 +225,8 @@
lib/cpus/aarch64/cortex_gelas.S \
lib/cpus/aarch64/nevis.S \
lib/cpus/aarch64/travis.S \
- lib/cpus/aarch64/cortex_arcadia.S
+ lib/cpus/aarch64/cortex_arcadia.S \
+ lib/cpus/aarch64/cortex_alto.S
endif
else
@@ -336,18 +344,12 @@
endif
# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
-ifdef UNIX_MK
-FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts
FDT_SOURCES += ${FVP_HW_CONFIG_DTS}
$(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS)))
-ifeq (${TRANSFER_LIST}, 1)
-FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \
- ${PLAT}_tb_fw_config.dts \
- )
-else
+ifeq (${TRANSFER_LIST}, 0)
FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \
${PLAT}_fw_config.dts \
${PLAT}_tb_fw_config.dts \
@@ -355,6 +357,7 @@
${PLAT}_nt_fw_config.dts \
)
+FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb
FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
@@ -386,13 +389,12 @@
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config,${FVP_SOC_FW_CONFIG}))
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG}))
-endif
-
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG}))
+endif
+
# Add the HW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
-endif
ifeq (${TRANSFER_LIST}, 1)
include lib/transfer_list/transfer_list.mk
@@ -406,6 +408,10 @@
endif
endif
+ifeq (${HOB_LIST}, 1)
+include lib/hob/hob.mk
+endif
+
# Enable dynamic mitigation support by default
DYNAMIC_WORKAROUND_CVE_2018_3639 := 1
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index 327a345..a62661d 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -36,28 +36,5 @@
fdt fdt_node_offset_by_phandle
fdt fdt_subnode_offset
fdt fdt_add_subnode
-mbedtls mbedtls_asn1_get_alg
-mbedtls mbedtls_asn1_get_alg_null
-mbedtls mbedtls_asn1_get_bitstring_null
-mbedtls mbedtls_asn1_get_bool
-mbedtls mbedtls_asn1_get_int
-mbedtls mbedtls_asn1_get_len
-mbedtls mbedtls_asn1_get_tag
-mbedtls mbedtls_free
-mbedtls mbedtls_md
-mbedtls mbedtls_md_get_size
-mbedtls mbedtls_memory_buffer_alloc_init
-mbedtls mbedtls_oid_get_md_alg
-mbedtls mbedtls_oid_get_numeric_string
-mbedtls mbedtls_oid_get_pk_alg
-mbedtls mbedtls_oid_get_sig_alg
-mbedtls mbedtls_pk_free
-mbedtls mbedtls_pk_init
-mbedtls mbedtls_pk_parse_subpubkey
-mbedtls mbedtls_pk_verify_ext
-mbedtls mbedtls_platform_set_snprintf
-mbedtls mbedtls_x509_get_rsassa_pss_params
-mbedtls mbedtls_x509_get_sig_alg
-mbedtls mbedtls_md_info_from_type
c exit
c atexit
diff --git a/plat/arm/board/juno/jmptbl_mbedtls.i b/plat/arm/board/juno/jmptbl_mbedtls.i
new file mode 100644
index 0000000..6e1f017
--- /dev/null
+++ b/plat/arm/board/juno/jmptbl_mbedtls.i
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform-specific ROMLIB MbedTLS functions can be added here.
+# During the build process, this file is appended to jmptbl.i
+# if MbedTLS support is required.
+#
+# Format:
+# lib function [patch]
+# Example:
+# mbedtls mbedtls_asn1_get_alg
+# mbedtls mbedtls_asn1_get_alg_null patch
+
+mbedtls mbedtls_asn1_get_alg
+mbedtls mbedtls_asn1_get_alg_null
+mbedtls mbedtls_asn1_get_bitstring_null
+mbedtls mbedtls_asn1_get_bool
+mbedtls mbedtls_asn1_get_int
+mbedtls mbedtls_asn1_get_len
+mbedtls mbedtls_asn1_get_tag
+mbedtls mbedtls_free
+mbedtls mbedtls_md
+mbedtls mbedtls_md_get_size
+mbedtls mbedtls_memory_buffer_alloc_init
+mbedtls mbedtls_oid_get_md_alg
+mbedtls mbedtls_oid_get_numeric_string
+mbedtls mbedtls_oid_get_pk_alg
+mbedtls mbedtls_oid_get_sig_alg
+mbedtls mbedtls_pk_free
+mbedtls mbedtls_pk_init
+mbedtls mbedtls_pk_parse_subpubkey
+mbedtls mbedtls_pk_verify_ext
+mbedtls mbedtls_platform_set_snprintf
+mbedtls mbedtls_x509_get_rsassa_pss_params
+mbedtls mbedtls_x509_get_sig_alg
+mbedtls mbedtls_md_info_from_type
diff --git a/plat/arm/board/juno/juno_trusted_boot.c b/plat/arm/board/juno/juno_trusted_boot.c
index c730406..2ead454 100644
--- a/plat/arm/board/juno/juno_trusted_boot.c
+++ b/plat/arm/board/juno/juno_trusted_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2024, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,9 +14,9 @@
#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
-static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
+static unsigned char rotpk_hash_der[ARM_ROTPK_HASH_DER_HEADER_LEN + ARM_ROTPK_HASH_LEN];
-extern unsigned char arm_rotpk_header[];
+extern unsigned char arm_rotpk_hash_der_header[];
/*
* Return the ROTPK hash stored in the registers of Juno board.
@@ -33,8 +33,8 @@
assert(flags != NULL);
/* Copy the DER header */
- memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
- dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+ memcpy(rotpk_hash_der, arm_rotpk_hash_der_header, ARM_ROTPK_HASH_DER_HEADER_LEN);
+ dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HASH_DER_HEADER_LEN];
/*
diff --git a/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
index bce8834..39a86b1 100644
--- a/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
@@ -152,6 +152,9 @@
nrd_plat_info.config_id = plat_arm_nrd_get_config_id();
nrd_plat_info.multi_chip_mode = plat_arm_nrd_get_multi_chip_mode();
+ /* Initialize generic timer */
+ generic_delay_timer_init();
+
arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
}
@@ -216,7 +219,6 @@
void nrd_bl31_common_platform_setup(void)
{
- generic_delay_timer_init();
arm_bl31_platform_setup();
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 86fce0e..71f7bb3 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -207,7 +207,21 @@
#if defined(TARGET_FLAVOUR_FPGA)
#undef V2M_FLASH0_BASE
#undef V2M_FLASH0_SIZE
+#if TC_FPGA_FIP_IMG_IN_RAM
+/*
+ * Note that this is just used for the FIP, which is not required
+ * anymore once Linux has commenced booting. So we are safe allowing
+ * Linux to also make use of this memory and it doesn't need to be
+ * carved out of the devicetree.
+ *
+ * This only needs to match the RAM load address that we give the FIP
+ * on either the FPGA or FVP command line so there is no need to link
+ * it to say halfway through the RAM or anything like that.
+ */
+#define V2M_FLASH0_BASE UL(0xB0000000)
+#else
#define V2M_FLASH0_BASE UL(0x0C000000)
+#endif
#define V2M_FLASH0_SIZE UL(0x02000000)
#endif
@@ -242,10 +256,28 @@
#if TARGET_PLATFORM <= 2
#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
#elif TARGET_PLATFORM >= 3
-#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
-#endif /* TARGET_PLATFORM >= 3 */
-#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+
+#if TC_FPGA_FS_IMG_IN_RAM
+/* 10GB reserved for system+userdata+vendor images */
+#define SYSTEM_IMAGE_SIZE 0xC0000000 /* 3GB */
+#define USERDATA_IMAGE_SIZE 0x140000000 /* 5GB */
+#define VENDOR_IMAGE_SIZE 0x20000000 /* 512MB */
+#define RESERVE_IMAGE_SIZE 0x60000000 /* 1.5GB */
+#define ANDROID_FS_SIZE (SYSTEM_IMAGE_SIZE + \
+ USERDATA_IMAGE_SIZE + \
+ VENDOR_IMAGE_SIZE + RESERVE_IMAGE_SIZE)
+
+#define PLAT_ARM_DRAM2_BASE ULL(0x880000000) + ANDROID_FS_SIZE
+#define PLAT_ARM_DRAM2_SIZE ULL(0x380000000) - ANDROID_FS_SIZE
+#else
+#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+#endif /* TC_FPGA_FS_IMG_IN_RAM */
+
+#endif /* TARGET_VERSION >= 3 */
+
#define PLAT_ARM_DRAM2_END (PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL)
#define TC_NS_MTE_SIZE (256 * SZ_1M)
@@ -341,13 +373,13 @@
* PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
* SCP_BL2 size plus a little space for growth.
*/
-#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x20000
+#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x30000
/*
* PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
* SCP_BL2U size plus a little space for growth.
*/
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x20000
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x30000
#if TARGET_PLATFORM <= 2
/* TZC Related Constants */
@@ -411,18 +443,22 @@
#undef PLAT_ARM_BOOT_UART_CLK_IN_HZ
#undef PLAT_ARM_RUN_UART_CLK_IN_HZ
-#if TARGET_FLAVOUR_FVP
-#define PLAT_ARM_BOOT_UART_BASE TC_UART1
-#define TC_UARTCLK 7372800
-#else /* TARGET_FLAVOUR_FPGA */
-#define PLAT_ARM_BOOT_UART_BASE TC_UART0
-#if TARGET_PLATFORM <= 2
-#define TC_UARTCLK 5000000
-#elif TARGET_PLATFORM >= 3
-#define TC_UARTCLK 3750000
-#endif /* TARGET_PLATFORM >= 3 */
#undef ARM_CONSOLE_BAUDRATE
#define ARM_CONSOLE_BAUDRATE 38400
+
+#if TARGET_PLATFORM <= 2
+#define TC_UARTCLK 5000000
+#elif TARGET_PLATFORM == 3
+#define TC_UARTCLK 3750000
+#elif TARGET_PLATFORM == 4
+#define TC_UARTCLK 4000000
+#endif /* TARGET_PLATFORM <=2 */
+
+
+#if TARGET_FLAVOUR_FVP
+#define PLAT_ARM_BOOT_UART_BASE TC_UART1
+#else /* TARGET_FLAVOUR_FPGA */
+#define PLAT_ARM_BOOT_UART_BASE TC_UART0
#endif /* TARGET_FLAVOUR_FPGA */
#define PLAT_ARM_RUN_UART_BASE TC_UART0
@@ -431,28 +467,41 @@
#define PLAT_ARM_BOOT_UART_CLK_IN_HZ TC_UARTCLK
#define PLAT_ARM_RUN_UART_CLK_IN_HZ TC_UARTCLK
-#if TARGET_PLATFORM == 3
+#if (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4)
#define NCI_BASE_ADDR UL(0x4F000000)
-#ifdef TARGET_FLAVOUR_FPGA
+#if (TARGET_PLATFORM == 3) && defined(TARGET_FLAVOUR_FPGA)
#define MCN_ADDRESS_SPACE_SIZE 0x00120000
#else
#define MCN_ADDRESS_SPACE_SIZE 0x00130000
-#endif /* TARGET_FLAVOUR_FPGA */
+#endif /* (TARGET_PLATFORM == 3) && defined(TARGET_FLAVOUR_FPGA) */
+#if TARGET_PLATFORM == 3
#define MCN_OFFSET_IN_NCI 0x00C90000
-#define MCN_BASE_ADDR (NCI_BASE_ADDR + MCN_OFFSET_IN_NCI)
+#else /* TARGET_PLATFORM == 4 */
+#ifdef TARGET_FLAVOUR_FPGA
+#define MCN_OFFSET_IN_NCI 0x00420000
+#else
+#define MCN_OFFSET_IN_NCI 0x00D80000
+#endif /* TARGET_FLAVOUR_FPGA */
+#endif /* TARGET_PLATFORM == 3 */
+#define MCN_BASE_ADDR(n) (NCI_BASE_ADDR + MCN_OFFSET_IN_NCI + \
+ ((n) * MCN_ADDRESS_SPACE_SIZE))
#define MCN_PMU_OFFSET 0x000C4000
#define MCN_MICROARCH_OFFSET 0x000E4000
-#define MCN_MICROARCH_BASE_ADDR (MCN_BASE_ADDR + MCN_MICROARCH_OFFSET)
+#define MCN_MICROARCH_BASE_ADDR(n) (MCN_BASE_ADDR(n) + \
+ MCN_MICROARCH_OFFSET)
#define MCN_SCR_OFFSET 0x4
#define MCN_SCR_PMU_BIT 10
+#if TARGET_PLATFORM == 3
#define MCN_INSTANCES 4
-#define MCN_PMU_ADDR(n) (MCN_BASE_ADDR + \
- (n * MCN_ADDRESS_SPACE_SIZE) + \
- MCN_PMU_OFFSET)
+#else /* TARGET_PLATFORM == 4 */
+#define MCN_INSTANCES 8
+#endif /* TARGET_PLATFORM == 3 */
+#define MCN_PMU_ADDR(n) (MCN_BASE_ADDR(n) + \
+ MCN_PMU_OFFSET)
#define MCN_MPAM_NS_OFFSET 0x000D0000
-#define MCN_MPAM_NS_BASE_ADDR (MCN_BASE_ADDR + MCN_MPAM_NS_OFFSET)
+#define MCN_MPAM_NS_BASE_ADDR(n) (MCN_BASE_ADDR(n) + MCN_MPAM_NS_OFFSET)
#define MCN_MPAM_S_OFFSET 0x000D4000
-#define MCN_MPAM_S_BASE_ADDR (MCN_BASE_ADDR + MCN_MPAM_S_OFFSET)
+#define MCN_MPAM_S_BASE_ADDR(n) (MCN_BASE_ADDR(n) + MCN_MPAM_S_OFFSET)
#define MPAM_SLCCFG_CTL_OFFSET 0x00003018
#define SLC_RDALLOCMODE_SHIFT 8
#define SLC_RDALLOCMODE_MASK (3 << SLC_RDALLOCMODE_SHIFT)
@@ -464,7 +513,7 @@
#define SLC_ALLOC_BUS_SIGNAL_ATTR 2
#define MCN_CONFIG_OFFSET 0x204
-#define MCN_CONFIG_ADDR (MCN_BASE_ADDR + MCN_CONFIG_OFFSET)
+#define MCN_CONFIG_ADDR(n) (MCN_BASE_ADDR(n) + MCN_CONFIG_OFFSET)
#define MCN_CONFIG_SLC_PRESENT_BIT 3
/*
@@ -475,7 +524,7 @@
*/
#define CPUECTLR_EL1 CORTEX_A520_CPUECTLR_EL1
#define CPUECTLR_EL1_EXTLLC_BIT CORTEX_A520_CPUECTLR_EL1_EXTLLC_BIT
-#endif /* TARGET_PLATFORM == 3 */
+#endif /* (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4) */
#define CPUACTLR_CLUSTERPMUEN (ULL(1) << 12)
diff --git a/plat/arm/board/tc/include/tc_helpers.S b/plat/arm/board/tc/include/tc_helpers.S
index 9adf09a..1fde9e9 100644
--- a/plat/arm/board/tc/include/tc_helpers.S
+++ b/plat/arm/board/tc/include/tc_helpers.S
@@ -54,7 +54,7 @@
func mark_extllc_presence
#ifdef MCN_CONFIG_ADDR
- mov_imm x0, (MCN_CONFIG_ADDR)
+ mov_imm x0, (MCN_CONFIG_ADDR(0))
ldr w1, [x0]
ubfx x1, x1, #MCN_CONFIG_SLC_PRESENT_BIT, #1
sysreg_bitfield_insert_from_gpr CPUECTLR_EL1, x1, \
@@ -82,6 +82,9 @@
endfunc TC_HANDLER(3)
func TC_HANDLER(4)
+ mov x9, lr
+ bl enable_dsu_pmu_el1_access
+ mov lr, x9
ret
endfunc TC_HANDLER(4)
diff --git a/plat/arm/board/tc/plat_tc_mbedtls_config.h b/plat/arm/board/tc/plat_tc_mbedtls_config.h
index 4fd8b6b..9118b0b 100644
--- a/plat/arm/board/tc/plat_tc_mbedtls_config.h
+++ b/plat/arm/board/tc/plat_tc_mbedtls_config.h
@@ -8,7 +8,7 @@
#define PLAT_TC_MBEDTLS_CONFIG_H
#include <export/lib/utils_def_exp.h>
-#include <mbedtls_config-3.h>
+#include <default_mbedtls_config.h>
#ifndef TF_MBEDTLS_HEAP_SIZE
#error TF_MBEDTLS_HEAP_SIZE is not defined
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 9cd3011..1ec7c44 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -77,12 +77,24 @@
$(error TARGET_FLAVOUR must be fvp or fpga)
endif
+# Support for loading FS Image to DRAM
+TC_FPGA_FS_IMG_IN_RAM := 0
+
+# Support Loading of FIP image to DRAM
+TC_FPGA_FIP_IMG_IN_RAM := 0
+
+# Use simple panel instead of vencoder with DPU
+TC_DPU_USE_SIMPLE_PANEL := 0
+
$(eval $(call add_defines, \
TARGET_PLATFORM \
TARGET_FLAVOUR_$(call uppercase,${TARGET_FLAVOUR}) \
TC_RESOLUTION_$(call uppercase,${TC_RESOLUTION}) \
TC_DPU_USE_SCMI_CLK \
TC_SCMI_PD_CTRL_EN \
+ TC_FPGA_FS_IMG_IN_RAM \
+ TC_FPGA_FIP_IMG_IN_RAM \
+ TC_DPU_USE_SIMPLE_PANEL \
))
CSS_LOAD_SCP_IMAGES := 1
@@ -218,18 +230,17 @@
# Add the HW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${TC_HW_CONFIG},--hw-config,${TC_HW_CONFIG}))
+$(info Including rse_comms.mk)
+include drivers/arm/rse/rse_comms.mk
+
+BL1_SOURCES += ${RSE_COMMS_SOURCES}
+BL2_SOURCES += ${RSE_COMMS_SOURCES}
+BL31_SOURCES += ${RSE_COMMS_SOURCES}
+
# Include Measured Boot makefile before any Crypto library makefile.
# Crypto library makefile may need default definitions of Measured Boot build
# flags present in Measured Boot makefile.
-$(info Including rse_comms.mk)
ifeq (${MEASURED_BOOT},1)
- $(info Including rse_comms.mk)
- include drivers/arm/rse/rse_comms.mk
-
- BL1_SOURCES += ${RSE_COMMS_SOURCES}
- BL2_SOURCES += ${RSE_COMMS_SOURCES}
- PLAT_INCLUDES += -Iinclude/lib/psa
-
ifeq (${DICE_PROTECTION_ENVIRONMENT},1)
$(info Including qcbor.mk)
include drivers/measured_boot/rse/qcbor.mk
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 801872a..bc8f5ec 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -25,6 +25,10 @@
#include <psa/crypto_types.h>
#include <psa/crypto_values.h>
#endif /* PLATFORM_TEST_TFM_TESTSUITE */
+#include <psa/error.h>
+
+#include <drivers/arm/rse_comms.h>
+#include <plat/common/platform.h>
#ifdef PLATFORM_TEST_TFM_TESTSUITE
/*
@@ -68,19 +72,21 @@
};
#endif
-#if TARGET_PLATFORM == 3
+#if (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4)
static void enable_ns_mcn_pmu(void)
{
/*
* Enable non-secure access to MCN PMU registers
*/
for (int i = 0; i < MCN_INSTANCES; i++) {
- uintptr_t mcn_scr = MCN_MICROARCH_BASE_ADDR + MCN_SCR_OFFSET +
- (i * MCN_ADDRESS_SPACE_SIZE);
+ uintptr_t mcn_scr = MCN_MICROARCH_BASE_ADDR(i) +
+ MCN_SCR_OFFSET;
mmio_setbits_32(mcn_scr, 1 << MCN_SCR_PMU_BIT);
}
}
+#endif /* (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4) */
+#if TARGET_PLATFORM == 3
static void set_mcn_slc_alloc_mode(void)
{
/*
@@ -89,10 +95,10 @@
* attribute from interface).
*/
for (int i = 0; i < MCN_INSTANCES; i++) {
- uintptr_t slccfg_ctl_ns = MCN_MPAM_NS_BASE_ADDR +
- (i * MCN_ADDRESS_SPACE_SIZE) + MPAM_SLCCFG_CTL_OFFSET;
- uintptr_t slccfg_ctl_s = MCN_MPAM_S_BASE_ADDR +
- (i * MCN_ADDRESS_SPACE_SIZE) + MPAM_SLCCFG_CTL_OFFSET;
+ uintptr_t slccfg_ctl_ns = MCN_MPAM_NS_BASE_ADDR(i) +
+ MPAM_SLCCFG_CTL_OFFSET;
+ uintptr_t slccfg_ctl_s = MCN_MPAM_S_BASE_ADDR(i) +
+ MPAM_SLCCFG_CTL_OFFSET;
mmio_clrsetbits_32(slccfg_ctl_ns,
(SLC_RDALLOCMODE_MASK | SLC_WRALLOCMODE_MASK),
@@ -109,8 +115,10 @@
void bl31_platform_setup(void)
{
tc_bl31_common_platform_setup();
-#if TARGET_PLATFORM == 3
+#if (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4)
enable_ns_mcn_pmu();
+#endif /* (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4) */
+#if TARGET_PLATFORM == 3
set_mcn_slc_alloc_mode();
plat_arm_ni_setup(NCI_BASE_ADDR);
#endif
@@ -186,10 +194,18 @@
#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
void tc_bl31_plat_runtime_setup(void)
{
+ psa_status_t status;
+
/* Start secure watchdog timer. */
plat_arm_secure_wdt_start();
arm_bl31_plat_runtime_setup();
+
+ /* Initialise RSE communication channel */
+ status = rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE, PLAT_RSE_AP_RCV_MHU_BASE);
+ if (status != PSA_SUCCESS) {
+ ERROR("Failed to initialize RSE communication channel - psa_status = %d\n", status);
+ }
}
void bl31_plat_runtime_setup(void)
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index fed14f7..1ecfdb9 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -40,6 +40,7 @@
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
TC_FLASH0_RO,
+ ARM_V2M_MAP_MEM_PROTECT,
TC_MAP_DEVICE,
TC_MAP_NS_DRAM1,
#if defined(SPD_spmd)
@@ -65,6 +66,7 @@
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
V2M_MAP_IOFPGA,
+ ARM_V2M_MAP_MEM_PROTECT,
TC_MAP_DEVICE,
PLAT_DTB_DRAM_NS,
#if SPM_MM
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index f043f59..b8e5027 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -64,9 +64,7 @@
/* Boolean variable to hold condition whether firmware update needed or not */
static bool is_fwu_needed;
-#if TRANSFER_LIST
-static struct transfer_list_header *secure_tl;
-#endif
+struct transfer_list_header *secure_tl;
struct meminfo *bl1_plat_sec_mem_layout(void)
{
@@ -90,6 +88,12 @@
/* Allow BL1 to see the whole Trusted RAM */
bl1_tzram_layout.total_base = ARM_BL_RAM_BASE;
bl1_tzram_layout.total_size = ARM_BL_RAM_SIZE;
+
+#if TRANSFER_LIST
+ secure_tl = transfer_list_ensure((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
+ PLAT_ARM_FW_HANDOFF_SIZE);
+ assert(secure_tl != NULL);
+#endif
}
void bl1_early_platform_setup(void)
@@ -158,7 +162,7 @@
image_desc_t *desc;
- int err = -1;
+ int err __unused = 1;
/* Initialise the IO layer and register platform IO devices */
plat_arm_io_setup();
@@ -171,35 +175,24 @@
}
#if TRANSFER_LIST
- secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
- PLAT_ARM_FW_HANDOFF_SIZE);
-
- if (secure_tl == NULL) {
- ERROR("Secure transfer list initialisation failed!\n");
- panic();
- }
-
- te = transfer_list_add(secure_tl, TL_TAG_TB_FW_CONFIG,
- ARM_TB_FW_CONFIG_MAX_SIZE, NULL);
+#if CRYPTO_SUPPORT
+ te = transfer_list_add(secure_tl, TL_TAG_MBEDTLS_HEAP_INFO,
+ sizeof(struct crypto_heap_info), NULL);
assert(te != NULL);
+ struct crypto_heap_info *heap_info =
+ (struct crypto_heap_info *)transfer_list_entry_data(te);
+ arm_get_mbedtls_heap(&heap_info->addr, &heap_info->size);
+#endif /* CRYPTO_SUPPORT */
+
+ desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+
/*
- * Set the load address of TB_FW_CONFIG in the data section of the TE just
- * allocated in the secure transfer list.
+ * The event log might have been updated prior to this, make sure we have an
+ * up to date tl before setting the handoff arguments.
*/
- SET_PARAM_HEAD(&config_image_info, PARAM_IMAGE_BINARY, VERSION_2, 0);
- config_image_info.image_base = (uintptr_t)transfer_list_entry_data(te);
- config_image_info.image_max_size = te->data_size;
-
- VERBOSE("FCONF: Loading config with image ID: %u\n", TB_FW_CONFIG_ID);
- err = load_auth_image(TB_FW_CONFIG_ID, &config_image_info);
- if (err != 0) {
- VERBOSE("Failed to load config %u\n", TB_FW_CONFIG_ID);
- plat_error_handler(err);
- }
-
transfer_list_update_checksum(secure_tl);
- fconf_populate("TB_FW", (uintptr_t)transfer_list_entry_data(te));
+ transfer_list_set_handoff_args(secure_tl, &desc->ep_info);
#else
/* Set global DTB info for fixed fw_config information */
fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
@@ -234,22 +227,18 @@
ERROR("Invalid FW_CONFIG address\n");
plat_error_handler(err);
}
-#endif /* TRANSFER_LIST */
desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
-#if TRANSFER_LIST
- transfer_list_set_handoff_args(secure_tl, &desc->ep_info);
-#else
/* The BL2 ep_info arg0 is modified to point to FW_CONFIG */
assert(desc != NULL);
desc->ep_info.args.arg0 = config_info->config_addr;
-#endif /* TRANSFER_LIST */
#if CRYPTO_SUPPORT
/* Share the Mbed TLS heap info with other images */
arm_bl1_set_mbedtls_heap();
#endif /* CRYPTO_SUPPORT */
+#endif /* TRANSFER_LIST */
/*
* Allow access to the System counter timer module and program
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 90ee70c..17dc0ed 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -52,22 +52,14 @@
#pragma weak bl2_plat_arch_setup
#pragma weak bl2_plat_sec_mem_layout
-#if ENABLE_RME
#define MAP_BL2_TOTAL MAP_REGION_FLAT( \
bl2_tzram_layout.total_base, \
bl2_tzram_layout.total_size, \
- MT_MEMORY | MT_RW | MT_ROOT)
-#else
-#define MAP_BL2_TOTAL MAP_REGION_FLAT( \
- bl2_tzram_layout.total_base, \
- bl2_tzram_layout.total_size, \
- MT_MEMORY | MT_RW | MT_SECURE)
-#endif /* ENABLE_RME */
+ MT_MEMORY | MT_RW | EL3_PAS)
#pragma weak arm_bl2_plat_handle_post_image_load
-static struct transfer_list_header *secure_tl __unused;
-static struct transfer_list_header *ns_tl __unused;
+struct transfer_list_header *secure_tl __unused;
/*******************************************************************************
* BL1 has passed the extents of the trusted SRAM that should be visible to BL2
@@ -129,15 +121,14 @@
#if TRANSFER_LIST
/* Assume the secure TL hasn't been initialised if BL2 is running at EL3. */
#if RESET_TO_BL2
- secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
- PLAT_ARM_FW_HANDOFF_SIZE);
+ secure_tl = transfer_list_ensure((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
+ PLAT_ARM_FW_HANDOFF_SIZE);
if (secure_tl == NULL) {
ERROR("Secure transfer list initialisation failed!\n");
panic();
}
#endif
-
arm_transfer_list_dyn_cfg_init(secure_tl);
#else
#if ARM_FW_CONFIG_LOAD_ENABLE
@@ -232,11 +223,10 @@
arm_bl2_plat_arch_setup();
#if TRANSFER_LIST
- te = transfer_list_find(secure_tl, TL_TAG_TB_FW_CONFIG);
- assert(te != NULL);
-
- fconf_populate("TB_FW", (uintptr_t)transfer_list_entry_data(te));
+#if CRYPTO_SUPPORT
+ te = arm_transfer_list_set_heap_info(secure_tl);
transfer_list_rem(secure_tl, te);
+#endif /* CRYPTO_SUPPORT */
#else
/* Fill the properties struct with the info from the config dtb */
fconf_populate("FW_CONFIG", config_base);
@@ -246,7 +236,7 @@
assert(tb_fw_config_info != NULL);
fconf_populate("TB_FW", tb_fw_config_info->config_addr);
-#endif
+#endif /* TRANSFER_LIST */
}
int arm_bl2_handle_post_image_load(unsigned int image_id)
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 0a8dd37..4787995 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -25,8 +25,8 @@
#include <plat/common/platform.h>
#include <platform_def.h>
-static struct transfer_list_header *secure_tl __unused;
-static struct transfer_list_header *ns_tl __unused;
+struct transfer_list_header *secure_tl;
+struct transfer_list_header *ns_tl __unused;
/*
* Placeholder variables for copying the arguments that have been passed to
@@ -367,14 +367,13 @@
struct transfer_list_entry *te __unused;
#if TRANSFER_LIST && !RESET_TO_BL31
- ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE,
- PLAT_ARM_FW_HANDOFF_SIZE);
-
+ ns_tl = transfer_list_ensure((void *)FW_NS_HANDOFF_BASE,
+ PLAT_ARM_FW_HANDOFF_SIZE);
if (ns_tl == NULL) {
- ERROR("Non-secure transfer list initialisation failed!");
+ ERROR("Non-secure transfer list initialisation failed!\n");
panic();
}
-
+ /* BL31 may modify the HW_CONFIG so defer copying it until later. */
te = transfer_list_find(secure_tl, TL_TAG_FDT);
assert(te != NULL);
@@ -392,7 +391,7 @@
te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size,
transfer_list_entry_data(te));
assert(te != NULL);
-#endif /* TRANSFER_LIST */
+#endif /* TRANSFER_LIST && !RESET_TO_BL31 */
/* Initialize the GIC driver, cpu and distributor interfaces */
plat_arm_gic_driver_init();
@@ -447,7 +446,7 @@
* they can access the updated data even if caching is not enabled.
*/
flush_dcache_range((uintptr_t)ns_tl, ns_tl->size);
-#endif /* TRANSFER_LIST && !(RESET_TO_BL2 || RESET_TO_BL31) */
+#endif /* TRANSFER_LIST && !RESET_TO_BL31 */
#if RECLAIM_INIT_CODE
arm_free_init_memory();
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 2fd993c..580ef5f 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -363,7 +363,7 @@
endif
# Pointer Authentication sources
-ifeq (${ENABLE_PAUTH}, 1)
+ifeq ($(BRANCH_PROTECTION),$(filter $(BRANCH_PROTECTION),1 2 3))
PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c
endif
@@ -382,12 +382,14 @@
ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT} ${DRTM_SUPPORT}),)
PLAT_INCLUDES += -Iplat/arm/common \
-Iinclude/drivers/auth/mbedtls
- # Specify mbed TLS configuration file
- ifeq (${PSA_CRYPTO},1)
- MBEDTLS_CONFIG_FILE ?= "<plat_arm_psa_mbedtls_config.h>"
+ ifeq (${HASH_ALG}, sha512)
+ ARM_ROTPK_HASH_LEN := 64
+ else ifeq (${HASH_ALG}, sha384)
+ ARM_ROTPK_HASH_LEN := 48
else
- MBEDTLS_CONFIG_FILE ?= "<plat_arm_mbedtls_config.h>"
+ ARM_ROTPK_HASH_LEN := 32
endif
+ $(eval $(call add_define,ARM_ROTPK_HASH_LEN))
endif
ifneq (${TRUSTED_BOARD_BOOT},0)
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 18ab5be..a827f05 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -23,7 +23,7 @@
#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>
-#if CRYPTO_SUPPORT
+#if CRYPTO_SUPPORT && !TRANSFER_LIST
static void *mbedtls_heap_addr;
static size_t mbedtls_heap_size;
@@ -118,7 +118,7 @@
#endif /* !MEASURED_BOOT */
}
}
-#endif /* CRYPTO_SUPPORT */
+#endif /* CRYPTO_SUPPORT && !TRANSFER_LIST */
#if IMAGE_BL2
/*
diff --git a/plat/arm/common/arm_ni.c b/plat/arm/common/arm_ni.c
index b3ad8b3..9c105f7 100644
--- a/plat/arm/common/arm_ni.c
+++ b/plat/arm/common/arm_ni.c
@@ -144,19 +144,33 @@
for (uint32_t i = 0U; i < vd_count; i++) {
vd_addr = global_cfg + mmio_read_32(global_cfg + NI_CHILD_POINTER(i));
+
+ VERBOSE("Voltage domain %u at 0x%lx node info: 0x%x\n",
+ i, vd_addr, mmio_read_32(vd_addr));
+
pd_count = mmio_read_32(vd_addr + NI_CHILD_NODE_COUNT);
for (uint32_t j = 0U; j < pd_count; j++) {
pd_addr = global_cfg + mmio_read_32(vd_addr + NI_CHILD_POINTER(j));
cd_count = mmio_read_32(pd_addr + NI_CHILD_NODE_COUNT);
+ VERBOSE("Power domain %u at 0x%lx node info: 0x%x\n",
+ j, pd_addr, mmio_read_32(pd_addr));
+
for (uint32_t k = 0U; k < cd_count; k++) {
cd_addr = global_cfg + mmio_read_32(pd_addr + NI_CHILD_POINTER(k));
comp_count = mmio_read_32(cd_addr + NI_CHILD_NODE_COUNT);
+ VERBOSE("Clock domain %u at 0x%lx node info: 0x%x\n",
+ k, cd_addr, mmio_read_32(cd_addr));
+
for (uint32_t l = 0U; l < comp_count; l++) {
comp_addr = global_cfg +
mmio_read_32(cd_addr + NI_CHILD_POINTER(l));
+
+ VERBOSE("Component %u at 0x%lx node info: 0x%x\n",
+ l, comp_addr, mmio_read_32(comp_addr));
+
ni_setup_component(comp_addr);
}
}
diff --git a/plat/arm/common/arm_transfer_list.c b/plat/arm/common/arm_transfer_list.c
index 59fb039..6847591 100644
--- a/plat/arm/common/arm_transfer_list.c
+++ b/plat/arm/common/arm_transfer_list.c
@@ -4,10 +4,49 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#if CRYPTO_SUPPORT
+#include <mbedtls/version.h>
+#endif /* CRYPTO_SUPPORT */
+
#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>
-void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl)
+#if CRYPTO_SUPPORT
+#if defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31)
+static unsigned char heap[TF_MBEDTLS_HEAP_SIZE];
+
+#define MBEDTLS_HEAP_ADDR heap
+#define MBEDTLS_HEAP_SIZE sizeof(heap)
+#else
+static struct crypto_heap_info heap_info;
+
+#define MBEDTLS_HEAP_ADDR heap_info.addr
+#define MBEDTLS_HEAP_SIZE heap_info.size
+
+struct transfer_list_entry *
+arm_transfer_list_set_heap_info(struct transfer_list_header *tl)
+{
+ struct transfer_list_entry *te =
+ transfer_list_find(tl, TL_TAG_MBEDTLS_HEAP_INFO);
+ assert(te != NULL);
+
+ heap_info = *(struct crypto_heap_info *)transfer_list_entry_data(te);
+ return te;
+}
+#endif /* defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31) */
+
+int __init arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ assert(heap_addr != NULL);
+ assert(heap_size != NULL);
+ *heap_addr = MBEDTLS_HEAP_ADDR;
+ *heap_size = MBEDTLS_HEAP_SIZE;
+
+ return 0;
+}
+#endif /* CRYPTO_SUPPORT */
+
+void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *tl)
{
struct transfer_list_entry *te;
bl_mem_params_node_t *next_param_node =
@@ -19,8 +58,7 @@
* mechanism. Pre-allocate a TE for the configuration and update the
* load information so the configuration is loaded directly into the TE.
*/
- te = transfer_list_add(secure_tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE,
- NULL);
+ te = transfer_list_add(tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE, NULL);
assert(te != NULL);
next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
@@ -30,7 +68,7 @@
}
void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node,
- struct transfer_list_header *secure_tl)
+ struct transfer_list_header *tl)
{
uint32_t next_exe_img_id;
entry_point_info_t *ep;
@@ -45,7 +83,7 @@
next_exe_img_id)];
assert(next_param_node != NULL);
- te = transfer_list_add(secure_tl, TL_TAG_EXEC_EP_INFO64,
+ te = transfer_list_add(tl, TL_TAG_EXEC_EP_INFO64,
sizeof(entry_point_info_t),
&next_param_node->ep_info);
assert(te != NULL);
@@ -72,5 +110,5 @@
next_exe_img_id = next_param_node->next_handoff_image_id;
}
- flush_dcache_range((uintptr_t)secure_tl, secure_tl->size);
+ flush_dcache_range((uintptr_t)tl, tl->size);
}
diff --git a/plat/arm/common/plat_arm_mbedtls_config.h b/plat/arm/common/plat_arm_mbedtls_config.h
deleted file mode 100644
index a5d0ec4..0000000
--- a/plat/arm/common/plat_arm_mbedtls_config.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Ltd. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_ARM_MBEDTLS_CONFIG_H
-#define PLAT_ARM_MBEDTLS_CONFIG_H
-
-#include <mbedtls_config-3.h>
-
-/**
- * On Arm platforms, the ROTPK is always hashed using the SHA-256
- * algorithm.
- * TODO: Update to hash the ROTPK with the selected HASH_ALG to avoid
- * the need for explicitly enabling the SHA-256 configuration in mbedTLS.
- */
-#define MBEDTLS_SHA256_C
-
-/*
- * Use an implementation of SHA-256 with a smaller memory footprint
- * but reduced speed.
- */
-#define MBEDTLS_SHA256_SMALLER
-
-#endif /* PLAT_ARM_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/common/plat_arm_psa_mbedtls_config.h b/plat/arm/common/plat_arm_psa_mbedtls_config.h
deleted file mode 100644
index fd434c9..0000000
--- a/plat/arm/common/plat_arm_psa_mbedtls_config.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Ltd. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_ARM_PSA_MBEDTLS_CONFIG_H
-#define PLAT_ARM_PSA_MBEDTLS_CONFIG_H
-
-#include "plat_arm_mbedtls_config.h"
-
-#define MBEDTLS_PSA_CRYPTO_C
-#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
-
-/*
- * Using PSA crypto API requires an RNG right now. If we don't define the macro
- * below then we get build errors.
- *
- * This is a functionality gap in mbedTLS. The technical limitation is that
- * psa_crypto_init() is all-or-nothing, and fixing that would require separate
- * initialization of the keystore, the RNG, etc.
- *
- * By defining MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG, we pretend using an external
- * RNG. As a result, the PSA crypto init code does nothing when it comes to
- * initializing the RNG, as we are supposed to take care of that ourselves.
- */
-#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
-
-#endif /* PLAT_ARM_PSA_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index db4a169..bfb6906 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -152,6 +152,8 @@
{
assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF);
css_power_down_common(target_state);
+ /* ask the GIC not to wake us up */
+ plat_arm_gic_redistif_off();
css_scp_off(target_state);
}
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index a603f2b..dbb6f81 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -9,6 +9,7 @@
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
+#include <lib/transfer_list.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/common/platform.h>
#include <services/arm_arch_svc.h>
@@ -129,3 +130,13 @@
/* Create the page tables to reflect the above mappings */
init_xlat_tables();
}
+
+#if ((MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT) && TRANSFER_LIST)
+int plat_handoff_mboot(const void *data, uint32_t data_size, void *tl_base)
+{
+ if (!transfer_list_add(tl_base, TL_TAG_TPM_EVLOG, data_size, data))
+ return -1;
+
+ return 0;
+}
+#endif
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
index c090117..ab03928 100644
--- a/plat/intel/soc/agilex5/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -196,6 +196,9 @@
NOTICE("BL31: CPU ID = %x\n", cpuid);
INFO("BL31: Invalidate Data cache\n");
invalidate_dcache_all();
+
+ /* Invalidate for NS EL2 and EL1 */
+ invalidate_cache_low_el();
}
/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
diff --git a/plat/intel/soc/agilex5/soc/agilex5_cache.S b/plat/intel/soc/agilex5/soc/agilex5_cache.S
index 52ed5d3..f8c6a2d 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_cache.S
+++ b/plat/intel/soc/agilex5/soc/agilex5_cache.S
@@ -15,14 +15,16 @@
* --------------------------------------------------------
*/
func invalidate_cache_low_el
- mrs x0,SCR_EL3
- orr x1,x0,#SCR_NS_BIT
+ mrs x0, SCR_EL3
+ orr x1, x0, #SCR_NS_BIT
msr SCR_EL3, x1
isb
tlbi ALLE2
dsb sy
tlbi ALLE1
dsb sy
+ msr SCR_EL3, x0
+ isb
endfunc invalidate_cache_low_el
.pushsection .text.asm_dcache_level, "ax"
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index dfa409f..e27af21 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -243,7 +243,8 @@
void mailbox_reset_warm(uint32_t reset_type);
void mailbox_clear_response(void);
-int intel_mailbox_get_config_status(uint32_t cmd, bool init_done);
+int intel_mailbox_get_config_status(uint32_t cmd, bool init_done,
+ uint32_t *err_states);
int intel_mailbox_is_fpga_not_ready(void);
#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 94895ba..69f0008 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -638,7 +638,8 @@
return MBOX_RET_OK;
}
-int intel_mailbox_get_config_status(uint32_t cmd, bool init_done)
+int intel_mailbox_get_config_status(uint32_t cmd, bool init_done,
+ uint32_t *err_states)
{
int status;
uint32_t res, response[6];
@@ -653,6 +654,9 @@
res = response[RECONFIG_STATUS_STATE];
+ if (err_states != NULL)
+ *err_states = res;
+
if (res == MBOX_CFGSTAT_VAB_BS_PREAUTH) {
return MBOX_CFGSTAT_STATE_CONFIG;
}
@@ -684,11 +688,11 @@
int intel_mailbox_is_fpga_not_ready(void)
{
- int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true);
+ int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true, NULL);
if ((ret != MBOX_RET_OK) && (ret != MBOX_CFGSTAT_STATE_CONFIG)) {
ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS,
- false);
+ false, NULL);
}
return ret;
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 68deab9..71a626d 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -94,22 +94,25 @@
return 0;
}
-static uint32_t intel_mailbox_fpga_config_isdone(void)
+static uint32_t intel_mailbox_fpga_config_isdone(uint32_t *err_states)
{
uint32_t ret;
+ if (err_states == NULL)
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+
switch (request_type) {
case RECONFIGURATION:
ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS,
- true);
+ true, err_states);
break;
case BITSTREAM_AUTH:
ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS,
- false);
+ false, err_states);
break;
default:
ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS,
- false);
+ false, err_states);
break;
}
@@ -814,6 +817,7 @@
uint32_t retval = 0, completed_addr[3];
uint32_t retval2 = 0;
uint32_t mbox_error = 0;
+ uint32_t err_states = 0;
uint64_t retval64, rsu_respbuf[9];
uint32_t seu_respbuf[3];
int status = INTEL_SIP_SMC_STATUS_OK;
@@ -827,8 +831,8 @@
SMC_UUID_RET(handle, intl_svc_uid);
case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
- status = intel_mailbox_fpga_config_isdone();
- SMC_RET4(handle, status, 0, 0, 0);
+ status = intel_mailbox_fpga_config_isdone(&err_states);
+ SMC_RET4(handle, status, err_states, 0, 0);
case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
index 0cb2014..a095ba9 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -71,8 +71,9 @@
$(eval SOURCES := $(2))
$(eval OBJS_TEMP := $(addprefix $(BUILD_DIR)/$(MODULE)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
$(eval MODULE_OBJS += $(OBJS_TEMP))
+ $(eval BL := $(call uppercase,$(3)))
-$(eval $(call MAKE_OBJS,$(BUILD_DIR)/$(MODULE),$(SOURCES),${3}))
+$(eval $(call MAKE_OBJS,$(BUILD_DIR)/$(MODULE),$(SOURCES),${3},$(BL)))
libraries: $(OBJS_TEMP)
endef
diff --git a/plat/mediatek/drivers/apusys/apusys.c b/plat/mediatek/drivers/apusys/apusys.c
index dfe1dcf..87e8960 100644
--- a/plat/mediatek/drivers/apusys/apusys.c
+++ b/plat/mediatek/drivers/apusys/apusys.c
@@ -30,10 +30,10 @@
switch (request_ops) {
case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON:
- ret = apusys_kernel_apusys_pwr_top_on();
+ ret = apusys_kernel_apusys_rv_pwr_ctrl(APU_PWR_ON);
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF:
- ret = apusys_kernel_apusys_pwr_top_off();
+ ret = apusys_kernel_apusys_rv_pwr_ctrl(APU_PWR_OFF);
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER:
ret = apusys_kernel_apusys_rv_setup_reviser();
@@ -68,6 +68,27 @@
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING:
ret = apusys_kernel_apusys_rv_cg_ungating();
break;
+ case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU:
+ ret = apusys_kernel_apusys_rv_setup_apummu();
+ break;
+#ifdef CONFIG_MTK_APUSYS_LOGTOP_SUPPORT
+ case MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_DUMP:
+ ret = apusys_kernel_apusys_logtop_reg_dump((uint32_t)x2, smccc_ret);
+ break;
+ case MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_WRITE:
+ ret = apusys_kernel_apusys_logtop_reg_write((uint32_t)x2, (uint32_t)x3,
+ smccc_ret);
+ break;
+ case MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_W1C:
+ ret = apusys_kernel_apusys_logtop_reg_w1c((uint32_t)x2, smccc_ret);
+ break;
+#endif
+ case MTK_APUSYS_KERNEL_OP_APUSYS_COLD_BOOT_CLR_MBOX_DUMMY:
+ ret = apusys_rv_cold_boot_clr_mbox_dummy();
+ break;
+ case MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN:
+ ret = apusys_rv_setup_ce_bin();
+ break;
default:
ERROR(MODULE_TAG "%s unknown request_ops = %x\n", MODULE_TAG, request_ops);
break;
diff --git a/plat/mediatek/drivers/apusys/apusys.h b/plat/mediatek/drivers/apusys/apusys.h
index ed4e195..709379e 100644
--- a/plat/mediatek/drivers/apusys/apusys.h
+++ b/plat/mediatek/drivers/apusys/apusys.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,19 +10,25 @@
#define MODULE_TAG "[APUSYS]"
enum MTK_APUSYS_KERNEL_OP {
- MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON, /* 0 */
- MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF, /* 1 */
- MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER, /* 2 */
- MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP, /* 3 */
- MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT, /* 4 */
- MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP, /* 5 */
- MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP, /* 6 */
- MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX, /* 7 */
- MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM, /* 8 */
- MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR, /* 9 */
- MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR, /* 10 */
- MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING, /* 11 */
- MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING, /* 12 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON, /* 0 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF, /* 1 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER, /* 2 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP, /* 3 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT, /* 4 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP, /* 5 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP, /* 6 */
+ MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX, /* 7 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM, /* 8 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR, /* 9 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR, /* 10 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING, /* 11 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING, /* 12 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU, /* 13 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_DUMP, /* 14 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_WRITE, /* 15 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_W1C, /* 16 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_COLD_BOOT_CLR_MBOX_DUMMY, /* 17 */
+ MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN, /* 18 */
MTK_APUSYS_KERNEL_OP_NUM,
};
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
index cb57668..a9eebb5 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
@@ -1,9 +1,11 @@
/*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <errno.h>
+
/* TF-A system header */
#include <common/debug.h>
#include <drivers/delay_timer.h>
@@ -14,7 +16,19 @@
#include "apusys.h"
#include "apusys_rv.h"
#include "apusys_rv_mbox_mpu.h"
-#include "emi_mpu.h"
+#include "apusys_rv_pwr_ctrl.h"
+#include "apusys_rv_sec_info.h"
+#ifdef CONFIG_MTK_APUSYS_SEC_CTRL
+#include "apusys_security_ctrl_perm.h"
+#endif
+#include "apusys_security_ctrl_plat.h"
+#include <drivers/apusys_rv_public.h>
+#include <mtk_mmap_pool.h>
+#include <mtk_sip_svc.h>
+
+#ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
+#include "apusys_ammu.h"
+#endif
static spinlock_t apusys_rv_lock;
@@ -94,6 +108,8 @@
(PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) |
(PREDEFINE_CACHE << PREDEF_4G_OFS));
+ apusys_infra_dcm_setup();
+
spin_unlock(&apusys_rv_lock);
return 0;
}
@@ -107,25 +123,64 @@
return 0;
}
+static int hw_sema2_release(uint32_t timeout)
+{
+#ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT
+ int ret;
+
+ ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 0, timeout, 0);
+ if (ret) {
+ ERROR("%s: HW semaphore release timeout\n", __func__);
+ }
+
+ return ret;
+#else
+ return 0;
+#endif
+}
+
+static int hw_sema2_acquire(uint32_t timeout)
+{
+#ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT
+ int ret;
+
+ ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 1, timeout, 0);
+ if (ret) {
+ ERROR("%s: HW semaphore acquire timeout\n", __func__);
+ }
+
+ return ret;
+#else
+ return 0;
+#endif
+}
+
int apusys_kernel_apusys_rv_stop_mp(void)
{
+ int ret;
+
+ ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
+ if (ret)
+ return ret;
+
spin_lock(&apusys_rv_lock);
mmio_write_32(MD32_RUNSTALL, MD32_STALL);
spin_unlock(&apusys_rv_lock);
- return 0;
+ ret = hw_sema2_release(HW_SEM_TIMEOUT);
+
+ return ret;
}
int apusys_kernel_apusys_rv_setup_sec_mem(void)
{
- int ret;
+ int ret = 0;
spin_lock(&apusys_rv_lock);
- ret = set_apu_emi_mpu_region();
- if (ret != 0) {
+ ret = apusys_plat_setup_sec_mem();
+ if (ret != 0)
ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__);
- }
spin_unlock(&apusys_rv_lock);
return ret;
@@ -133,37 +188,312 @@
int apusys_kernel_apusys_rv_disable_wdt_isr(void)
{
+ int ret;
+
+ ret = hw_sema2_acquire(0);
+ if (ret)
+ return ret;
+
spin_lock(&apusys_rv_lock);
mmio_clrbits_32(WDT_CTRL0, WDT_EN);
spin_unlock(&apusys_rv_lock);
- return 0;
+ ret = hw_sema2_release(0);
+
+ return ret;
}
int apusys_kernel_apusys_rv_clear_wdt_isr(void)
{
+ int ret;
+
+ ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
+ if (ret)
+ return ret;
+
spin_lock(&apusys_rv_lock);
mmio_clrbits_32(UP_INT_EN2, DBG_APB_EN);
mmio_write_32(WDT_INT, WDT_INT_W1C);
spin_unlock(&apusys_rv_lock);
- return 0;
+ ret = hw_sema2_release(HW_SEM_TIMEOUT);
+
+ return ret;
}
int apusys_kernel_apusys_rv_cg_gating(void)
{
+ int ret;
+
+ ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
+ if (ret)
+ return ret;
+
spin_lock(&apusys_rv_lock);
mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS);
spin_unlock(&apusys_rv_lock);
- return 0;
+ ret = hw_sema2_release(HW_SEM_TIMEOUT);
+
+ return ret;
}
int apusys_kernel_apusys_rv_cg_ungating(void)
{
+ int ret;
+
+ ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
+ if (ret)
+ return ret;
+
spin_lock(&apusys_rv_lock);
mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
spin_unlock(&apusys_rv_lock);
+ ret = hw_sema2_release(HW_SEM_TIMEOUT);
+
+ return ret;
+}
+
+int apusys_kernel_apusys_rv_setup_apummu(void)
+{
+ spin_lock(&apusys_rv_lock);
+
+#ifdef CONFIG_MTK_APUSYS_SEC_CTRL
+ sec_set_rv_dns();
+#endif
+
+#ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
+ uint32_t apummu_tcm_sz_select = 0;
+
+ if (APU_MD32_TCM_SZ <= 0x20000)
+ apummu_tcm_sz_select = APUMMU_PAGE_LEN_128KB;
+ else if (APU_MD32_TCM_SZ <= 0x40000)
+ apummu_tcm_sz_select = APUMMU_PAGE_LEN_256KB;
+ else if (APU_MD32_TCM_SZ <= 0x80000)
+ apummu_tcm_sz_select = APUMMU_PAGE_LEN_512KB;
+ else if (APU_MD32_TCM_SZ <= 0x100000)
+ apummu_tcm_sz_select = APUMMU_PAGE_LEN_1MB;
+ else {
+ ERROR("%s: APU_MD32_TCM_SZ = 0x%x > 1MB", __func__, APU_MD32_TCM_SZ);
+ spin_unlock(&apusys_rv_lock);
+ return -EINVAL;
+ }
+
+ INFO("%s: apummu_tcm_sz_select = %u\n", __func__, apummu_tcm_sz_select);
+ rv_boot(APU_SEC_FW_IOVA, 0, APUMMU_PAGE_LEN_1MB,
+ APU_MD32_TCM, apummu_tcm_sz_select);
+#endif
+
+ spin_unlock(&apusys_rv_lock);
+ return 0;
+}
+
+int apusys_kernel_apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
+{
+ return apusys_rv_pwr_ctrl(op);
+}
+
+#ifdef CONFIG_MTK_APUSYS_LOGTOP_SUPPORT
+int apusys_kernel_apusys_logtop_reg_dump(uint32_t op, struct smccc_res *smccc_ret)
+{
+ int ret = 0;
+ uint8_t smc_op;
+ uint32_t reg_addr[MAX_SMC_OP_NUM];
+ uint32_t i;
+
+ if (op == 0) {
+ ERROR("%s empty op = 0x%08x\n", MODULE_TAG, op);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < MAX_SMC_OP_NUM; i++) {
+ smc_op = (op >> (LOGTOP_OP_SHIFT * i)) & LOGTOP_OP_MASK;
+ switch (smc_op) {
+ case SMC_OP_APU_LOG_BUF_NULL:
+ reg_addr[i] = 0x0;
+ break;
+ case SMC_OP_APU_LOG_BUF_T_SIZE:
+ reg_addr[i] = APU_LOG_BUF_T_SIZE;
+ break;
+ case SMC_OP_APU_LOG_BUF_W_PTR:
+ reg_addr[i] = APU_LOG_BUF_W_PTR;
+ break;
+ case SMC_OP_APU_LOG_BUF_R_PTR:
+ reg_addr[i] = APU_LOG_BUF_R_PTR;
+ break;
+ case SMC_OP_APU_LOG_BUF_CON:
+ reg_addr[i] = APU_LOGTOP_CON;
+ break;
+ default:
+ ERROR("%s unknown op = 0x%08x\n", MODULE_TAG, smc_op);
+ return -EINVAL;
+ }
+ }
+
+ ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < MAX_SMC_OP_NUM; i++) {
+ if (reg_addr[i] == 0)
+ continue;
+
+ switch (i) {
+ case 0:
+ smccc_ret->a1 = mmio_read_32(reg_addr[i]);
+ break;
+ case 1:
+ smccc_ret->a2 = mmio_read_32(reg_addr[i]);
+ break;
+ case 2:
+ smccc_ret->a3 = mmio_read_32(reg_addr[i]);
+ break;
+ }
+ }
+
+ ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0);
+ if (ret)
+ ERROR("%s(%d): sem release timeout\n", __func__, op);
+
+ return ret;
+}
+
+static int apusys_kernel_apusys_logtop_reg_rw(uint32_t op, uint32_t write_val,
+ bool w1c, struct smccc_res *smccc_ret)
+{
+ int ret = 0;
+ uint32_t reg_addr = 0, reg_val = 0;
+
+ switch (op) {
+ case SMC_OP_APU_LOG_BUF_R_PTR:
+ reg_addr = APU_LOG_BUF_R_PTR;
+ break;
+ case SMC_OP_APU_LOG_BUF_CON:
+ reg_addr = APU_LOGTOP_CON;
+ break;
+ default:
+ ERROR("%s unknown or not support op = %x\n", MODULE_TAG, op);
+ return -EINVAL;
+ }
+
+ ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0);
+ if (ret)
+ return ret;
+
+ if (w1c) {
+ reg_val = mmio_read_32(reg_addr);
+ mmio_write_32(reg_addr, reg_val);
+ smccc_ret->a1 = reg_val;
+ } else {
+ mmio_write_32(reg_addr, write_val);
+ }
+
+ ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0);
+ if (ret)
+ ERROR("%s(%d): sem release timeout\n", __func__, op);
+
+ return ret;
+}
+
+int apusys_kernel_apusys_logtop_reg_write(uint32_t op, uint32_t write_val,
+ struct smccc_res *smccc_ret)
+{
+ return apusys_kernel_apusys_logtop_reg_rw(op, write_val, false, smccc_ret);
+}
+
+int apusys_kernel_apusys_logtop_reg_w1c(uint32_t op, struct smccc_res *smccc_ret)
+{
+ return apusys_kernel_apusys_logtop_reg_rw(op, 0, true, smccc_ret);
+}
+
+#endif /* CONFIG_MTK_APUSYS_LOGTOP_SUPPORT */
+
+int apusys_rv_cold_boot_clr_mbox_dummy(void)
+{
+#ifdef SUPPORT_APU_CLEAR_MBOX_DUMMY
+ mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, 0);
+#else
+ WARN("Not support clear mbox dummy on this platform\n");
+#endif
+ return 0;
+}
+
+#ifdef CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT
+int apusys_rv_iommu_hw_sem_trylock(void)
+{
+ return rv_iommu_hw_sem_trylock();
+}
+
+int apusys_rv_iommu_hw_sem_unlock(void)
+{
+ return rv_iommu_hw_sem_unlock();
+}
+#endif /* CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT */
+
+int apusys_rv_setup_ce_bin(void)
+{
+#ifdef CONFIG_MTK_APUSYS_CE_SUPPORT
+ uintptr_t apusys_rv_sec_buf_pa;
+ struct apusys_secure_info_t *apusys_secure_info;
+ struct ce_main_hdr_t *ce_main_hdr;
+ struct ce_sub_hdr_t *ce_sub_hdr;
+ unsigned int cnt, i, reg_val;
+ uint64_t ce_sub_hdr_bin;
+ int ret;
+
+ apusys_rv_sec_buf_pa = APU_RESERVE_MEMORY;
+ /* create mapping */
+ ret = mmap_add_dynamic_region(apusys_rv_sec_buf_pa, apusys_rv_sec_buf_pa,
+ round_up(APU_RESERVE_SIZE, PAGE_SIZE),
+ MT_MEMORY | MT_RW | MT_NS);
+ if (ret) {
+ ERROR("%s: mmap_add_dynamic_region() fail, ret=0x%x\n", __func__, ret);
+ return ret;
+ }
+
+ apusys_secure_info = (struct apusys_secure_info_t *)
+ (apusys_rv_sec_buf_pa + APU_SEC_INFO_OFFSET);
+
+ ce_main_hdr = (struct ce_main_hdr_t *)(apusys_rv_sec_buf_pa +
+ apusys_secure_info->ce_bin_ofs);
+ ce_sub_hdr = (struct ce_sub_hdr_t *)((uintptr_t)ce_main_hdr + ce_main_hdr->hdr_size);
+
+ if (ce_main_hdr->magic != CE_MAIN_MAGIC) {
+ ERROR("%s: invalid header\n", __func__);
+ return -EINVAL;
+ }
+
+ cnt = 0;
+
+ while (ce_sub_hdr->magic == CE_SUB_MAGIC && cnt < ce_main_hdr->bin_count) {
+ VERBOSE("%s: job (%d), magic (0x%x)\n", __func__,
+ ce_sub_hdr->ce_enum, ce_sub_hdr->magic);
+
+ ce_sub_hdr_bin = (uint64_t)ce_sub_hdr + ce_sub_hdr->bin_offset;
+
+ for (i = 0; i < ce_sub_hdr->bin_size; i += sizeof(uint32_t)) {
+ reg_val = *(uint32_t *)(ce_sub_hdr_bin + i);
+ mmio_write_32(ce_sub_hdr->mem_st + i, reg_val);
+ }
+
+ if (ce_sub_hdr->hw_entry) {
+ mmio_clrsetbits_32(ce_sub_hdr->hw_entry,
+ ce_sub_hdr->hw_entry_mask << ce_sub_hdr->hw_entry_bit,
+ (ce_sub_hdr->hw_entry_val & ce_sub_hdr->hw_entry_mask)
+ << ce_sub_hdr->hw_entry_bit);
+ }
+
+ ce_sub_hdr = (struct ce_sub_hdr_t *)(ce_sub_hdr_bin + ce_sub_hdr->bin_size);
+ cnt++;
+ }
+
+ mmap_remove_dynamic_region(apusys_rv_sec_buf_pa,
+ round_up(APU_RESERVE_SIZE, PAGE_SIZE));
+
+ INFO("%s: setup CE binary done\n", __func__);
+#else
+ WARN("Not support CE on this platform\n");
+#endif
return 0;
}
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
index 8a43890..506fcee 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -88,24 +88,35 @@
#define WDT_INT_W1C (1)
#define WDT_EN BIT(31)
-/* APU MBOX */
-#define MBOX_FUNC_CFG (0xb0)
-#define MBOX_DOMAIN_CFG (0xe0)
-#define MBOX_CTRL_LOCK BIT(0)
-#define MBOX_NO_MPU_SHIFT (16)
-#define MBOX_RX_NS_SHIFT (16)
-#define MBOX_RX_DOMAIN_SHIFT (17)
-#define MBOX_TX_NS_SHIFT (24)
-#define MBOX_TX_DOMAIN_SHIFT (25)
-#define MBOX_SIZE (0x100)
-#define MBOX_NUM (8)
+enum APU_PWR_OP {
+ APU_PWR_OFF = 0,
+ APU_PWR_ON = 1,
+};
-#define APU_MBOX(i) (((i) < MBOX_NUM) ? (APU_MBOX0 + MBOX_SIZE * (i)) : \
- (APU_MBOX1 + MBOX_SIZE * ((i) - MBOX_NUM)))
-#define APU_MBOX_FUNC_CFG(i) (APU_MBOX(i) + MBOX_FUNC_CFG)
-#define APU_MBOX_DOMAIN_CFG(i) (APU_MBOX(i) + MBOX_DOMAIN_CFG)
+/* APU_LOGTOP */
+#define APU_LOGTOP_CON (APU_LOGTOP + 0x0)
+#define APU_LOG_BUF_T_SIZE (APU_LOGTOP + 0x78)
+#define APU_LOG_BUF_W_PTR (APU_LOGTOP + 0x80)
+#define APU_LOG_BUF_R_PTR (APU_LOGTOP + 0x84)
+#define HW_SEMA2 (APU_ARE_REG_BASE + 0x0E08)
+#define HW_SEMA_USER (0x2)
+#define HW_SEMA_LOGGER_USER (0x3)
+#define MAX_SMC_OP_NUM (0x3)
+#define LOGTOP_OP_MASK (0xFF)
+#define LOGTOP_OP_SHIFT (8)
+enum {
+ SMC_OP_APU_LOG_BUF_NULL = 0,
+ SMC_OP_APU_LOG_BUF_T_SIZE,
+ SMC_OP_APU_LOG_BUF_W_PTR,
+ SMC_OP_APU_LOG_BUF_R_PTR,
+ SMC_OP_APU_LOG_BUF_CON,
+ SMC_OP_APU_LOG_BUF_NUM
+};
+
+struct smccc_res;
void apusys_rv_mbox_mpu_init(void);
+int apusys_infra_dcm_setup(void);
int apusys_kernel_apusys_rv_setup_reviser(void);
int apusys_kernel_apusys_rv_reset_mp(void);
int apusys_kernel_apusys_rv_setup_boot(void);
@@ -116,5 +127,13 @@
int apusys_kernel_apusys_rv_clear_wdt_isr(void);
int apusys_kernel_apusys_rv_cg_gating(void);
int apusys_kernel_apusys_rv_cg_ungating(void);
+int apusys_kernel_apusys_rv_setup_apummu(void);
+int apusys_kernel_apusys_rv_pwr_ctrl(enum APU_PWR_OP op);
+int apusys_kernel_apusys_logtop_reg_dump(uint32_t op, struct smccc_res *smccc_ret);
+int apusys_kernel_apusys_logtop_reg_write(uint32_t op, uint32_t write_val,
+ struct smccc_res *smccc_ret);
+int apusys_kernel_apusys_logtop_reg_w1c(uint32_t op, struct smccc_res *smccc_ret);
+int apusys_rv_cold_boot_clr_mbox_dummy(void);
+int apusys_rv_setup_ce_bin(void);
#endif /* APUSYS_RV_H */
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_sec_info.h b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_sec_info.h
new file mode 100644
index 0000000..581ed0a
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_sec_info.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_SECURE_INFO_H
+#define APUSYS_RV_SECURE_INFO_H
+
+#define CE_MAIN_MAGIC (0xCEC0DE88)
+#define CE_SUB_MAGIC (0xCEC0DE00)
+
+struct apusys_secure_info_t {
+ unsigned int total_sz;
+ unsigned int up_code_buf_ofs;
+ unsigned int up_code_buf_sz;
+
+ unsigned int up_fw_ofs;
+ unsigned int up_fw_sz;
+ unsigned int up_xfile_ofs;
+ unsigned int up_xfile_sz;
+ unsigned int mdla_fw_boot_ofs;
+ unsigned int mdla_fw_boot_sz;
+ unsigned int mdla_fw_main_ofs;
+ unsigned int mdla_fw_main_sz;
+ unsigned int mdla_xfile_ofs;
+ unsigned int mdla_xfile_sz;
+ unsigned int mvpu_fw_ofs;
+ unsigned int mvpu_fw_sz;
+ unsigned int mvpu_xfile_ofs;
+ unsigned int mvpu_xfile_sz;
+ unsigned int mvpu_sec_fw_ofs;
+ unsigned int mvpu_sec_fw_sz;
+ unsigned int mvpu_sec_xfile_ofs;
+ unsigned int mvpu_sec_xfile_sz;
+
+ unsigned int up_coredump_ofs;
+ unsigned int up_coredump_sz;
+ unsigned int mdla_coredump_ofs;
+ unsigned int mdla_coredump_sz;
+ unsigned int mvpu_coredump_ofs;
+ unsigned int mvpu_coredump_sz;
+ unsigned int mvpu_sec_coredump_ofs;
+ unsigned int mvpu_sec_coredump_sz;
+
+ unsigned int ce_bin_ofs;
+ unsigned int ce_bin_sz;
+};
+
+struct ce_main_hdr_t {
+ unsigned int magic; /* magic number*/
+ unsigned int hdr_size; /* header size */
+ unsigned int img_size; /* img size */
+ unsigned int bin_count; /* bin count */
+};
+
+struct ce_sub_hdr_t {
+ unsigned int magic; /* magic number */
+ unsigned int bin_offset; /* binary offset */
+ unsigned int bin_size; /* binary size */
+ unsigned int ce_enum; /* ce enum */
+ char job_name[8]; /* job name */
+ unsigned int mem_st; /* ce enum */
+ unsigned int hw_entry; /* hw entry */
+ unsigned int hw_entry_bit; /* hw entry bit */
+ unsigned int hw_entry_mask; /* hw entry mask */
+ unsigned int hw_entry_val; /* hw entry val*/
+ unsigned int user_info; /* user_info */
+};
+
+#endif /* APUSYS_RV_SECURE_INFO_H */
diff --git a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
index 1b77942..a15daa2 100644
--- a/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
+++ b/plat/mediatek/drivers/apusys/devapc/apusys_dapc_v1.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,8 +13,15 @@
* STRUCTURE DEFINITION
******************************************************************************/
enum apusys_apc_err_status {
- APUSYS_APC_OK = 0x0,
- APUSYS_APC_ERR_GENERIC = 0x1,
+ APUSYS_APC_OK = 0x0,
+ APUSYS_APC_ERR_GENERIC = 0x1000,
+ APUSYS_APC_ERR_INVALID_CMD = 0x1001,
+ APUSYS_APC_ERR_SLAVE_TYPE_NOT_SUPPORTED = 0x1002,
+ APUSYS_APC_ERR_SLAVE_IDX_NOT_SUPPORTED = 0x1003,
+ APUSYS_APC_ERR_DOMAIN_NOT_SUPPORTED = 0x1004,
+ APUSYS_APC_ERR_PERMISSION_NOT_SUPPORTED = 0x1005,
+ APUSYS_APC_ERR_OUT_OF_BOUNDARY = 0x1006,
+ APUSYS_APC_ERR_REQ_TYPE_NOT_SUPPORTED = 0x1007,
};
enum apusys_apc_perm_type {
@@ -155,4 +162,110 @@
FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D11_NO_PROTECT_D3_D5_D8_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ NO_PROTECTION, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, NO_PROTECTION, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ SEC_RW_NS_R, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D5_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ SEC_RW_NS_R, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D3_D5_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ NO_PROTECTION, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D4_D11_NO_PROTECT(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ NO_PROTECTION, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
+ NO_PROTECTION, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D5_SEC_RW_D0_NO_PROTECT(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ NO_PROTECTION, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ NO_PROTECTION, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D11_NO_PROTECT(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ NO_PROTECTION, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_D8_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ NO_PROTECTION, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, SEC_RW_ONLY, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_D8_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ SEC_RW_NS_R, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, \
+ SEC_RW_ONLY, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN)
+
+#define SLAVE_FORBID_EXCEPT_D0_D5_D7_D14_NO_PROTECT(domain) \
+ APUSYS_APC_AO_ATTR(domain, \
+ NO_PROTECTION, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION, \
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, \
+ FORBIDDEN, FORBIDDEN, NO_PROTECTION, FORBIDDEN)
+
#endif /* APUSYS_DAPC_V1_H */
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
index 0a2781b..746c81f 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
@@ -1,9 +1,10 @@
/*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <errno.h>
#include <inttypes.h>
/* TF-A system header */
@@ -18,6 +19,7 @@
#include "apusys.h"
#include "apusys_power.h"
#include "apusys_rv.h"
+#include "apusys_rv_pwr_ctrl.h"
#include <mtk_mmap_pool.h>
static spinlock_t apu_lock;
@@ -118,7 +120,7 @@
mmio_write_32(APU_MBOX0_BASE + PWR_FLOW_SYNC_REG, (cfg & 0x1));
}
-int apusys_kernel_apusys_pwr_top_on(void)
+static int apusys_kernel_apusys_pwr_top_on(void)
{
int ret;
@@ -184,7 +186,7 @@
udelay(100);
}
-int apusys_kernel_apusys_pwr_top_off(void)
+static int apusys_kernel_apusys_pwr_top_off(void)
{
int ret;
@@ -221,6 +223,19 @@
return ret;
}
+int apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
+{
+ if (op != APU_PWR_OFF && op != APU_PWR_ON) {
+ ERROR(MODULE_TAG "%s unknown request_ops = %d\n", __func__, op);
+ return -EINVAL;
+ }
+
+ if (op == APU_PWR_ON)
+ return apusys_kernel_apusys_pwr_top_on();
+
+ return apusys_kernel_apusys_pwr_top_off();
+}
+
static void get_pll_pcw(const uint32_t clk_rate, uint32_t *r1, uint32_t *r2)
{
unsigned int fvco = clk_rate;
@@ -481,3 +496,10 @@
return ret;
}
+
+int apusys_infra_dcm_setup(void)
+{
+ WARN(MODULE_TAG "%s not support\n", __func__);
+
+ return -EOPNOTSUPP;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.h b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
index 460cc50..e1ce4a4 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -242,7 +242,5 @@
#define CG_CLR (0xffffffff)
int apusys_power_init(void);
-int apusys_kernel_apusys_pwr_top_on(void);
-int apusys_kernel_apusys_pwr_top_off(void);
#endif /* APUSYS_POWER_H */
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h b/plat/mediatek/drivers/apusys/mt8188/apusys_rv_mbox_mpu.h
similarity index 95%
rename from plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h
rename to plat/mediatek/drivers/apusys/mt8188/apusys_rv_mbox_mpu.h
index 0ee4878..dbdf274 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv_mbox_mpu.h
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_rv_mbox_mpu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_rv_pwr_ctrl.h b/plat/mediatek/drivers/apusys/mt8188/apusys_rv_pwr_ctrl.h
new file mode 100644
index 0000000..329eadf
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_rv_pwr_ctrl.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_PWR_CTL_H
+#define APUSYS_RV_PWR_CTL_H
+
+#include "apusys_rv.h"
+
+/* APU MBOX */
+#define MBOX_FUNC_CFG (0xb0)
+#define MBOX_DOMAIN_CFG (0xe0)
+#define MBOX_CTRL_LOCK BIT(0)
+#define MBOX_NO_MPU_SHIFT (16)
+#define MBOX_RX_NS_SHIFT (16)
+#define MBOX_RX_DOMAIN_SHIFT (17)
+#define MBOX_TX_NS_SHIFT (24)
+#define MBOX_TX_DOMAIN_SHIFT (25)
+#define MBOX_SIZE (0x100)
+#define MBOX_NUM (8)
+
+#define APU_MBOX(i) (((i) < MBOX_NUM) ? (APU_MBOX0 + MBOX_SIZE * (i)) : \
+ (APU_MBOX1 + MBOX_SIZE * ((i) - MBOX_NUM)))
+#define APU_MBOX_FUNC_CFG(i) (APU_MBOX(i) + MBOX_FUNC_CFG)
+#define APU_MBOX_DOMAIN_CFG(i) (APU_MBOX(i) + MBOX_DOMAIN_CFG)
+
+#define HW_SEM_TIMEOUT (0)
+
+int apusys_rv_pwr_ctrl(enum APU_PWR_OP op);
+
+#endif /* APUSYS_RV_PWR_CTL_H */
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c
index 86bebe5..8517db0 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,8 @@
#include <common/debug.h>
#include <lib/mmio.h>
+#include "emi_mpu.h"
+
/* Vendor header */
#include "apusys_security_ctrl_plat.h"
@@ -41,3 +43,8 @@
{
apusys_domain_remap_init();
}
+
+int apusys_plat_setup_sec_mem(void)
+{
+ return set_apu_emi_mpu_region();
+}
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h
index f9181ae..f1b0a41 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_security_ctrl_plat.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -34,5 +34,6 @@
#define D15_REMAP_DOMAIN (15)
void apusys_security_ctrl_init(void);
+int apusys_plat_setup_sec_mem(void);
#endif /* APUSYS_SECURITY_CTRL_PLAT_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.c b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.c
new file mode 100644
index 0000000..fa1cd2c
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include "apusys_ammu.h"
+#include <apusys_security_ctrl_perm.h>
+#include <mtk_mmap_pool.h>
+
+static void apummu_set_segment_offset0(uint32_t vsid_idx, uint8_t seg_idx, uint32_t input_adr,
+ uint8_t res_bits, uint8_t page_sel, uint8_t page_len)
+{
+ mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_0),
+ APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, res_bits, page_sel, page_len));
+}
+
+static void apummu_set_segment_offset1(uint32_t vsid_idx, uint8_t seg_idx, uint32_t output_adr,
+ uint8_t res0, uint8_t iommu_en, uint8_t res1)
+{
+ mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_1),
+ APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, res0, iommu_en, res1));
+}
+
+static void apummu_set_segment_offset2(uint32_t vsid_idx, uint8_t seg_idx, uint8_t resv,
+ uint8_t domain, uint8_t acp_en, uint8_t aw_clr,
+ uint8_t aw_invalid, uint8_t ar_exclu, uint8_t ar_sepcu,
+ uint8_t aw_cache_allocate, uint8_t aw_slc_en,
+ uint8_t aw_slb_en, uint8_t ar_cache_allocate,
+ uint8_t ar_slc_en, uint8_t ar_slb_en, uint8_t ro,
+ uint8_t ns)
+{
+ mmio_write_32(APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, APUMMU_SEG_OFFSET_2),
+ APUMMU_BUILD_SEGMENT_OFFSET2(resv, domain, acp_en, aw_clr, aw_invalid,
+ ar_exclu, ar_sepcu, aw_cache_allocate,
+ aw_slc_en, aw_slb_en, ar_cache_allocate,
+ ar_slc_en, ar_slb_en, ro, ns));
+}
+
+static void apummu_vsid_segment_enable_init(uint8_t vsid_idx)
+{
+ mmio_write_32(APUMMU_VSID_SEGMENT_ENABLE(vsid_idx), 0);
+}
+
+static void apummu_set_single_segment(uint8_t vsid_idx, uint8_t seg_idx)
+{
+ mmio_setbits_32(APUMMU_VSID_SEGMENT_ENABLE(vsid_idx), BIT(seg_idx));
+}
+
+static int apummu_enable_vsid(uint32_t vsid_idx)
+{
+ if (vsid_idx > (APUMMU_VSID_ACTIVE - 1) &&
+ vsid_idx < (APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV + 1)) {
+ ERROR("invalid vsid index %d\n", vsid_idx);
+ return -1;
+ }
+
+ mmio_write_32(APUMMU_VSID_ENABLE_BASE(vsid_idx), BIT(vsid_idx & APUMMU_VSID_EN_MASK));
+ mmio_write_32(APUMMU_VSID_VALID_BASE(vsid_idx), BIT(vsid_idx & APUMMU_VSID_EN_MASK));
+
+ return 0;
+}
+
+static void apummu_enable(void)
+{
+ mmio_setbits_32(APUMMU_CMU_TOP_BASE, 0x1);
+}
+
+static void apummu_vsid_sram_config(void)
+{
+ uint32_t idx;
+ uint32_t base = (APUMMU_VSID_SRAM_TOTAL - APUMMU_VSID_RSV);
+
+ for (idx = 0; idx < APUMMU_VSID_RSV; idx++) {
+ mmio_write_32(APUMMU_VSID(APUMMU_RSV_VSID_IDX_START + idx),
+ APUMMU_VSID_DESC(base + idx));
+ apummu_vsid_segment_enable_init(base + idx);
+ }
+}
+
+static void apummu_bind_vsid(uint32_t tcu_base, uint32_t vsid_idx, uint8_t cor_id,
+ uint8_t hw_thread, uint8_t cor_valid, uint8_t vsid_valid)
+{
+ mmio_write_32((tcu_base + hw_thread * VSID_THREAD_SZ),
+ (((cor_id & VSID_CORID_MASK) << VSID_CORID_OFF) |
+ ((vsid_idx & VSID_IDX_MASK) << VSID_IDX_OFF) |
+ ((cor_valid & VSID_VALID_MASK) << VSID_COR_VALID_OFF) |
+ ((vsid_valid & VSID_VALID_MASK) << VSID_VALID_OFF)));
+}
+
+static int apummu_rv_bind_vsid(uint8_t hw_thread)
+{
+ uint8_t cor_id = 0, cor_valid = 0, vsid_valid = 1;
+
+ if (hw_thread > APUMMU_HW_THREAD_MAX) {
+ ERROR("%s: the hw thread id (%d) is not valid for rv/logger\n", __func__,
+ hw_thread);
+ return -EINVAL;
+ }
+
+ apummu_bind_vsid(APUMMU_RCX_UPRV_TCU_BASE, APUMMU_UPRV_RSV_VSID, cor_id, hw_thread,
+ cor_valid, vsid_valid);
+
+ return 0;
+}
+
+static int apummu_apmcu_bind_vsid(uint8_t hw_thread)
+{
+ uint8_t cor_id = 0, cor_valid = 0, vsid_valid = 1;
+
+ if (hw_thread > APUMMU_HW_THREAD_MAX) {
+ ERROR("%s: the hw thread id (%d) is not valid for apmcu\n", __func__, hw_thread);
+ return -EINVAL;
+ }
+
+ apummu_bind_vsid(APUMMU_RCX_EXTM_TCU_BASE, APUMMU_APMCU_RSV_VSID, cor_id, hw_thread,
+ cor_valid, vsid_valid);
+
+ return 0;
+}
+
+static int apummu_add_map(uint32_t vsid_idx, uint8_t seg_idx, uint64_t input_adr,
+ uint64_t output_adr, uint8_t page_sel, uint8_t page_len,
+ uint8_t domain, uint8_t ns)
+{
+ uint8_t smmu_sid;
+ bool smmu_sec_id;
+
+ if (seg_idx > APUMMU_SEG_MAX) {
+ ERROR("seg_idx is illegal (0x%x)\n", seg_idx);
+ return -EINVAL;
+ }
+
+ smmu_sec_id = false;
+ if (ns == 0)
+ smmu_sid = SMMU_NORMAL_1_4G_SID;
+ else
+ smmu_sid = (output_adr > 0xFFFFFFFF) ? SMMU_NORMAL_4_16G_SID
+ : SMMU_NORMAL_1_4G_SID;
+
+ /* fill segment */
+ apummu_set_segment_offset0(vsid_idx, seg_idx, (input_adr >> APUMMU_ADDR_SHIFT), 0,
+ page_sel, page_len);
+ apummu_set_segment_offset1(vsid_idx, seg_idx, (output_adr >> APUMMU_ADDR_SHIFT),
+ smmu_sid, 0, smmu_sec_id);
+ apummu_set_segment_offset2(vsid_idx, seg_idx, 0, domain,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ns);
+ apummu_set_single_segment(vsid_idx, seg_idx);
+
+ return 0;
+}
+
+static int apummu_get_dns(enum apusys_dev_type engine_type, enum apusys_sec_level sec_level,
+ uint8_t *domain, uint8_t *ns)
+{
+ int ret = 0;
+
+ if (engine_type != APUSYS_DEVICE_NUM) {
+ ret = sec_get_dns(engine_type, sec_level, domain, ns);
+ if (ret)
+ ERROR("engine:%d, sec: %d\n", engine_type, sec_level);
+ } else {
+ *domain = 7;
+ *ns = 1;
+ }
+
+ return ret;
+}
+
+static void apummu_init(void)
+{
+ apummu_vsid_sram_config();
+ mmio_write_32((APU_VCORE_CONFIG_BASE + APUMMU_SSID_SID_WIDTH_CTRL),
+ CSR_SMMU_AXMMUSID_WIDTH);
+ apummu_enable();
+}
+
+static void virtual_engine_thread(void)
+{
+ mmio_write_32((APUMMU_RCX_EXTM_TCU_BASE + APUMMU_INT_D2T_TBL0_OFS), APUMMU_THD_ID_TEE);
+}
+
+static int apummu_add_apmcu_map(uint32_t seg0_input, uint32_t seg0_output,
+ enum apummu_page_size page_size)
+{
+ int i, ret;
+ uint8_t domain, ns, seg;
+
+ ret = apummu_get_dns(APUSYS_DEVICE_NUM, SEC_LEVEL_SECURE, &domain, &ns);
+ if (ret) {
+ return ret;
+ }
+
+ seg = 0;
+ ret = apummu_add_map(APUMMU_APMCU_RSV_DESC_IDX, seg, seg0_input, seg0_output, 0,
+ page_size, domain, ns);
+ seg += 1;
+ if (ret)
+ return ret;
+
+ for (i = 0; i < 4; i++) {
+ ret = apummu_add_map(APUMMU_APMCU_RSV_DESC_IDX, seg,
+ APUSYS_TCM + (i * APUMMU_1M_SIZE),
+ APUSYS_TCM + (i * APUMMU_1M_SIZE),
+ 0, APUMMU_PAGE_LEN_1MB, domain, ns);
+ seg += 1;
+ if (ret)
+ return ret;
+ }
+
+ ret = apummu_enable_vsid(APUMMU_APMCU_RSV_VSID);
+
+ return ret;
+}
+
+static int apummu_add_rv_boot_map(uint32_t seg0_output, uint32_t seg1_output, uint32_t seg2_output)
+{
+ int ret;
+ uint8_t domain, ns;
+
+ ret = apummu_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_SECURE, &domain, &ns);
+ if (ret) {
+ ERROR("sec get dns fail %d\n", ret);
+ return ret;
+ }
+
+ /* must be in order */
+ ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 0, 0, seg0_output, 0,
+ APUMMU_PAGE_LEN_1MB, domain, ns);
+ ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 1, 0, seg1_output, 0,
+ APUMMU_PAGE_LEN_512MB, domain, ns);
+
+ ret |= apummu_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_NORMAL, &domain, &ns);
+ if (ret) {
+ return ret;
+ }
+
+ ret |= apummu_add_map(APUMMU_RSV_VSID_DESC_IDX_END, 2,
+ 0, seg2_output, 0, APUMMU_PAGE_LEN_4GB,
+ domain, ns);
+ if (ret) {
+ ERROR("sec add map fail %d\n", ret);
+ return ret;
+ }
+
+ ret = apummu_enable_vsid(APUMMU_UPRV_RSV_VSID);
+
+ return ret;
+}
+
+int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread,
+ enum apummu_page_size logger_page_size,
+ uint32_t XPU_seg_output, enum apummu_page_size XPU_page_size)
+{
+ int ret = 0;
+
+ apummu_init();
+
+ ret = apummu_add_rv_boot_map(uP_seg_output, 0, 0);
+ if (ret) {
+ return ret;
+ }
+
+ ret = apummu_rv_bind_vsid(uP_hw_thread);
+ if (ret)
+ return ret;
+
+ ret = apummu_rv_bind_vsid(uP_hw_thread + 1);
+ if (ret)
+ return ret;
+
+ virtual_engine_thread();
+
+ ret = apummu_add_apmcu_map(XPU_seg_output, XPU_seg_output,
+ XPU_page_size);
+ if (ret)
+ return ret;
+
+ ret = apummu_apmcu_bind_vsid(APUMMU_THD_ID_TEE);
+
+ return ret;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.h b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.h
new file mode 100644
index 0000000..61defc9
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_AMMU_H
+#define APUSYS_AMMU_H
+
+#include <platform_def.h>
+
+/* CMU */
+#define APUMMU_CMU_TOP_BASE (APU_CMU_TOP)
+#define APUMMU_CMU_TOP_TOPOLOGY (APUMMU_CMU_TOP_BASE + 0x04)
+#define APUMMU_VSID_ENABLE_OFFSET (0x50)
+#define APUMMU_VSID_VALID_OFFSET (0xb0)
+
+#define VSID_OFFSET(vsid_idx) (((vsid_idx) >> 5) * 0x4)
+
+#define APUMMU_VSID_ENABLE_BASE(vsid_idx) \
+ (APUMMU_CMU_TOP_BASE + VSID_OFFSET(vsid_idx) + APUMMU_VSID_ENABLE_OFFSET)
+#define APUMMU_VSID_VALID_BASE(vsid_idx) \
+ (APUMMU_CMU_TOP_BASE + VSID_OFFSET(vsid_idx) + APUMMU_VSID_VALID_OFFSET)
+
+/* VSID SRAM */
+#define APUMMU_VSID_BASE (APUMMU_CMU_TOP_BASE + 0x1000)
+#define APUMMU_VSID_DESC_BASE (APUMMU_VSID_BASE + 0x400)
+#define APUMMU_VSID_SRAM_SZIE (0x5C00)
+#define APUMMU_VSID_TBL_SZIE (0xF4)
+
+#define APUMMU_VSID(vsid_idx) (APUMMU_VSID_BASE + (vsid_idx) * 4)
+#define APUMMU_VSID_DESC(vsid_idx) \
+ (APUMMU_VSID_DESC_BASE + (vsid_idx) * APUMMU_VSID_TBL_SZIE)
+
+/* TCU RCX */
+#define APU_VCORE_CONFIG_BASE (APU_RCX_VCORE_CONFIG)
+#define APUMMU_RCX_EXTM_TCU_BASE (APU_RCX_EXTM_TCU)
+#define APUMMU_RCX_UPRV_TCU_BASE (APU_RCX_UPRV_TCU)
+
+#define APUMMU_SSID_SID_WIDTH_CTRL (0xCC0)
+#define CSR_SMMU_AXMMUSID_WIDTH BIT(7)
+#define APUMMU_1M_SIZE (0x100000)
+
+#define SMMU_NORMAL_0_1G_SID (0x8)
+#define SMMU_NORMAL_1_4G_SID (0x9)
+#define SMMU_NORMAL_4_16G_SID (0xA)
+
+enum apummu_page_size {
+ APUMMU_PAGE_LEN_128KB = 0,
+ APUMMU_PAGE_LEN_256KB,
+ APUMMU_PAGE_LEN_512KB,
+ APUMMU_PAGE_LEN_1MB,
+ APUMMU_PAGE_LEN_128MB,
+ APUMMU_PAGE_LEN_256MB,
+ APUMMU_PAGE_LEN_512MB,
+ APUMMU_PAGE_LEN_4GB,
+};
+
+#define APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, seg_offset) \
+ (APUMMU_VSID_DESC(vsid_idx) + (seg_idx) * 0xC + (seg_offset) * 0x04 + 0x4)
+
+#define APUMMU_VSID_SEGMENT_ENABLE(vsid_idx) (APUMMU_VSID_DESC(vsid_idx))
+
+#define APUMMU_VSID_SRAM_TOTAL (APUMMU_VSID_SRAM_SZIE / APUMMU_VSID_TBL_SZIE)
+#define APUMMU_RSV_VSID_DESC_IDX_END (APUMMU_VSID_SRAM_TOTAL - 1)
+#define APUMMU_UPRV_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END) /* 53 */
+#define APUMMU_LOGGER_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END - 1)
+#define APUMMU_APMCU_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END - 2)
+#define APUMMU_GPU_RSV_DESC_IDX (APUMMU_RSV_VSID_DESC_IDX_END - 3)
+
+#define APUMMU_SEG_OFFSET_0 (0)
+#define APUMMU_SEG_OFFSET_1 (1)
+#define APUMMU_SEG_OFFSET_2 (2)
+#define APUMMU_VSID_EN_MASK (0x1f)
+
+#define APUMMU_HW_THREAD_MAX (7)
+#define APUMMU_SEG_MAX (9)
+#define APUMMU_ADDR_SHIFT (12)
+
+#define VSID_THREAD_SZ (0x4)
+#define VSID_CORID_MASK (0x7f)
+#define VSID_CORID_OFF (11)
+#define VSID_IDX_MASK (0xff)
+#define VSID_IDX_OFF (3)
+#define VSID_VALID_MASK (0x1)
+#define VSID_COR_VALID_OFF (1)
+#define VSID_VALID_OFF (0)
+
+#define APUMMU_VSID_ACTIVE (32)
+#define APUMMU_VSID_RSV (4)
+#define APUMMU_VSID_UNUSED (12)
+#define APUMMU_VSID_USE_MAX (APUMMU_VSID_ACTIVE + APUMMU_VSID_RSV)
+
+#if ((APUMMU_VSID_RSV + APUMMU_VSID_ACTIVE + APUMMU_VSID_UNUSED + 1) > APUMMU_VSID_SRAM_TOTAL)
+#error APUMMU VSID Overflow
+#endif
+
+#define APUMMU_RSV_VSID_IDX_END (254)
+#define APUMMU_RSV_VSID_IDX_START (APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV + 1)
+
+#if ((APUMMU_RSV_VSID_IDX_END - APUMMU_RSV_VSID_IDX_START) > APUMMU_VSID_RSV)
+#error APUMMU VSID RSV Overflow
+#endif
+
+/* Reserve */
+#define APUMMU_UPRV_RSV_VSID (APUMMU_RSV_VSID_IDX_END)
+#define APUMMU_LOGGER_RSV_VSID (APUMMU_RSV_VSID_IDX_END - 1)
+#define APUMMU_APMCU_RSV_VSID (APUMMU_RSV_VSID_IDX_END - 2)
+#define APUMMU_GPU_RSV_VSID (APUMMU_RSV_VSID_IDX_END - 3)
+
+/* VSID bit mask */
+#define APUMMU_VSID_MAX_MASK_WORD ((APUMMU_VSID_USE_MAX + 32 - 1) / 32)
+
+/* VSID fields */
+#define READ_VSID_FIELD(vids, sg, offset, shift, mask) \
+ ((mmio_read_32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, offset)) >> sift) & mask)
+#define READ_VSID_FIELD_OFFESET0(vids, sg, shift, mask) \
+ READ_VSID_FIELD(vids, sg, 0, shift, mask)
+#define READ_VSID_FIELD_OFFESET1(vids, sg, shift, mask) \
+ READ_VSID_FIELD(vids, sg, 1, shift, mask)
+#define READ_VSID_FIELD_OFFESET2(vids, sg, shift, mask) \
+ READ_VSID_FIELD(vids, sg, 2, shift, mask)
+
+/* Get segment offset 0 data - 0x00 */
+#define APUMMU_SEGMENT_GET_INPUT(vsid, seg) \
+ READ_VSID_FIELD_OFFESET0(vsid, seg, 10, 0x3FFFFF)
+#define APUMMU_SEGMENT_GET_OFFSET0_RSRV(vsid, seg) \
+ READ_VSID_FIELD_OFFESET0(vsid, seg, 6, 0xF)
+#define APUMMU_SEGMENT_GET_PAGELEN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET0(vsid, seg, 0, 0x7)
+#define APUMMU_SEGMENT_GET_PAGESEL(vsid, seg) \
+ READ_VSID_FIELD_OFFESET0(vsid, seg, 3, 0x7)
+
+/* Get segment offset 1 data - 0x04 */
+#define APUMMU_SEGMENT_GET_IOMMU_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET1(vsid, seg, 1, 0x1)
+#define APUMMU_SEGMENT_GET_OFFSET1_RSRV0(vsid, seg) \
+ READ_VSID_FIELD_OFFESET1(vsid, seg, 2, 0xFF)
+#define APUMMU_SEGMENT_GET_OFFSET1_RSRV1(vsid, seg) \
+ READ_VSID_FIELD_OFFESET1(vsid, seg, 0, 0x1)
+#define APUMMU_SEGMENT_GET_OUTPUT(vsid, seg) \
+ READ_VSID_FIELD_OFFESET1(vsid, seg, 10, 0x3FFFFF)
+
+/* Get segment offset 2 data - 0x08 */
+#define APUMMU_SEGMENT_GET_ACP_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 12, 0x1)
+#define APUMMU_SEGMENT_GET_AR_CACHE_ALLOC(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 4, 0x1)
+#define APUMMU_SEGMENT_GET_AR_EXCLU(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 9, 0x1)
+#define APUMMU_SEGMENT_GET_AR_SEPCU(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 8, 0x1)
+#define APUMMU_SEGMENT_GET_AR_SLB_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 2, 0x1)
+#define APUMMU_SEGMENT_GET_AR_SLC_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 3, 0x1)
+#define APUMMU_SEGMENT_GET_AW_CACHE_ALLOC(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 7, 0x1)
+#define APUMMU_SEGMENT_GET_AW_CLR(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 11, 0x1)
+#define APUMMU_SEGMENT_GET_AW_INVALID(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 10, 0x1)
+#define APUMMU_SEGMENT_GET_AW_SLB_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 5, 0x1)
+#define APUMMU_SEGMENT_GET_AW_SLC_EN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 6, 0x1)
+#define APUMMU_SEGMENT_GET_DOMAIN(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 13, 0xF)
+#define APUMMU_SEGMENT_GET_NS(vsid, seg) \
+ READ_VSID_FIELD_OFFESET2(vsid, seg, 0, 0x1)
+
+/* Build segment data */
+/* Build segment offset 0 (0x00) data */
+#define APUMMU_VSID_SEGMENT_00_INPUT(input_adr) (((input_adr) & 0x3fffff) << 10)
+#define APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel) (((page_sel) & 0x7) << 3)
+#define APUMMU_VSID_SEGMENT_00_PAGELEN(page_len) (((page_len) & 0x7) << 0)
+#define APUMMU_VSID_SEGMENT_00_RESV(resv) (((resv) & 0xf) << 6)
+
+#define APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, resv, page_sel, page_len) \
+ (APUMMU_VSID_SEGMENT_00_INPUT(input_adr) | \
+ APUMMU_VSID_SEGMENT_00_RESV(resv) | \
+ APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel) | \
+ APUMMU_VSID_SEGMENT_00_PAGELEN(page_len))
+
+/* Build segment offset 1 (0x04) data */
+#define APUMMU_VSID_SEGMENT_04_IOMMU_EN(iommu_en) (((iommu_en) & 0x1) << 1)
+#define APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr) (((output_adr) & 0x3fffff) << 10)
+#define APUMMU_VSID_SEGMENT_04_RESV0(resv0) (((resv0) & 0xff) << 2)
+#define APUMMU_VSID_SEGMENT_04_RESV1(resv1) (((resv1) & 0x1) << 0)
+
+#define APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, resv0, iommu_en, resv1) \
+ (APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr) | \
+ APUMMU_VSID_SEGMENT_04_RESV0(resv0) | \
+ APUMMU_VSID_SEGMENT_04_IOMMU_EN(iommu_en) | \
+ APUMMU_VSID_SEGMENT_04_RESV1(resv1))
+
+/* Build segment offset 2 (0x08) data */
+#define APUMMU_VSID_SEGMENT_08_DOMAIN_MASK (0xf)
+#define APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT (13)
+#define APUMMU_VSID_SEGMENT_08_RESV_MASK (0x7fff)
+#define APUMMU_VSID_SEGMENT_08_RESV_SHIFT (17)
+
+#define APUMMU_VSID_SEGMENT_08_DOMAIN(domain) \
+ (((domain) & APUMMU_VSID_SEGMENT_08_DOMAIN_MASK) << APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT)
+#define APUMMU_VSID_SEGMENT_08_RESV(resv) \
+ (((resv) & APUMMU_VSID_SEGMENT_08_RESV_MASK) << APUMMU_VSID_SEGMENT_08_RESV_SHIFT)
+
+#define APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en) (((acp_en) & 0x1) << 12)
+#define APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu) (((ar_exclu) & 0x1) << 9)
+#define APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu) (((ar_sepcu) & 0x1) << 8)
+#define APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en) (((ar_slb_en) & 0x1) << 2)
+#define APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en) (((ar_slc_en) & 0x1) << 3)
+#define APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr) (((aw_clr) & 0x1) << 11)
+#define APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid) (((aw_invalid) & 0x1) << 10)
+#define APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en) (((aw_slb_en) & 0x1) << 5)
+#define APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en) (((aw_slc_en) & 0x1) << 6)
+#define APUMMU_VSID_SEGMENT_08_NS(ns) (((ns) & 0x1) << 0)
+#define APUMMU_VSID_SEGMENT_08_RO(ro) (((ro) & 0x1) << 1)
+
+#define APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate) \
+ (((ar_cache_allocate) & 0x1) << 4)
+#define APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate) \
+ (((aw_cache_allocate) & 0x1) << 7)
+
+#define APUMMU_BUILD_SEGMENT_OFFSET2(resv, domain, acp_en, aw_clr, \
+ aw_invalid, ar_exclu, ar_sepcu, \
+ aw_cache_allocate, aw_slc_en, aw_slb_en, ar_cache_allocate, \
+ ar_slc_en, ar_slb_en, ro, ns) \
+ ((APUMMU_VSID_SEGMENT_08_RESV(resv)) |\
+ (APUMMU_VSID_SEGMENT_08_DOMAIN(domain)) |\
+ (APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en)) |\
+ (APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr)) |\
+ (APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid)) |\
+ (APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu)) |\
+ (APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu)) |\
+ (APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate)) |\
+ (APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en)) |\
+ (APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en)) |\
+ (APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate)) |\
+ (APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en)) |\
+ (APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en)) |\
+ (APUMMU_VSID_SEGMENT_08_RO(ro)) | (APUMMU_VSID_SEGMENT_08_NS(ns)))
+
+/* Build segment offset 3 (0x0c) data */
+#define APUMMU_VSID_SEGMENT_0C_RESV(rsv) (((rsv) & 0x7fffffff) << 0)
+#define APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid) (((seg_valid) & 0x1U) << 31)
+#define APUMMU_BUILD_SEGMENT_OFFSET3(seg_valid, rsv) \
+ ((uint32_t)APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid) | \
+ APUMMU_VSID_SEGMENT_0C_RESV(rsv))
+
+#define APUMMU_INT_D2T_TBL0_OFS (0x40)
+
+#define APUSYS_TCM (0x4d100000)
+
+enum {
+ APUMMU_THD_ID_APMCU_NORMAL = 0,
+ APUMMU_THD_ID_TEE,
+};
+
+int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread,
+ enum apummu_page_size logger_page_size, uint32_t XPU_seg_output,
+ enum apummu_page_size XPU_page_size);
+
+#endif
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.c b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.c
new file mode 100644
index 0000000..09e35f1
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/utils_def.h>
+#include <platform_def.h>
+
+#include <apusys_devapc.h>
+#include <apusys_devapc_def.h>
+#include <mtk_mmap_pool.h>
+
+/* AO CONTROL DEVAPC - apu_rcx_ao_infra_dapc_con */
+static const struct apc_dom_16 APUSYS_CTRL_DAPC_AO[] = {
+ /* ctrl index = 0 */
+ SLAVE_RCX_BULK0("apu_ao_ctl_o-0"),
+ SLAVE_MD32_APB("apu_ao_ctl_o-1"),
+ SLAVE_ACP_TCU_SSC("apu_ao_ctl_o-2"),
+ SLAVE_PTP_THM("apu_ao_ctl_o-3"),
+ SLAVE_VCORE("apu_ao_ctl_o-4"),
+ SLAVE_IOMMU0_BANK0("apu_ao_ctl_o-5"),
+ SLAVE_IOMMU0_BANK1("apu_ao_ctl_o-6"),
+ SLAVE_IOMMU0_BANK2("apu_ao_ctl_o-7"),
+ SLAVE_IOMMU0_BANK3("apu_ao_ctl_o-8"),
+ SLAVE_IOMMU0_BANK4("apu_ao_ctl_o-9"),
+
+ /* ctrl index = 10 */
+ SLAVE_IOMMU1_BANK0("apu_ao_ctl_o-10"),
+ SLAVE_IOMMU1_BANK1("apu_ao_ctl_o-11"),
+ SLAVE_IOMMU1_BANK2("apu_ao_ctl_o-12"),
+ SLAVE_IOMMU1_BANK3("apu_ao_ctl_o-13"),
+ SLAVE_IOMMU1_BANK4("apu_ao_ctl_o-14"),
+ SLAVE_S0_SSC("apu_ao_ctl_o-15"),
+ SLAVE_N0_SSC("apu_ao_ctl_o-16"),
+ SLAVE_S1_SSC("apu_ao_ctl_o-17"),
+ SLAVE_N1_SSC("apu_ao_ctl_o-18"),
+ SLAVE_ACP_SSC("apu_ao_ctl_o-19"),
+
+ /* ctrl index = 20 */
+ SLAVE_WDEC("apu_ao_ctl_o-20"),
+ SLAVE_SMMU_IP_REG("apu_ao_ctl_o-21"),
+ SLAVE_SMMU_NSEC("apu_ao_ctl_o-22"),
+ SLAVE_SMMU_SEC("apu_ao_ctl_o-23"),
+ SLAVE_ARE0("apu_ao_ctl_o-24"),
+ SLAVE_ARE1("apu_ao_ctl_o-25"),
+ SLAVE_SONC("apu_ao_ctl_o-26"),
+ SLAVE_RPC("apu_ao_ctl_o-28"),
+ SLAVE_PCU("apu_ao_ctl_o-29"),
+ SLAVE_AO_CTRL("apu_ao_ctl_o-30"),
+
+ /* ctrl index = 30 */
+ SLAVE_AO_CTRL("apu_ao_ctl_o-31"),
+ SLAVE_ACC("apu_ao_ctl_o-32"),
+ SLAVE_SEC("apu_ao_ctl_o-33"),
+ SLAVE_PLL("apu_ao_ctl_o-34"),
+ SLAVE_RPC_MDLA("apu_ao_ctl_o-35"),
+ SLAVE_TOP_PMU("apu_ao_ctl_o-36"),
+ SLAVE_AO_BCRM("apu_ao_ctl_o-37"),
+ SLAVE_AO_DAPC_WRAP("apu_ao_ctl_o-38"),
+ SLAVE_AO_DAPC_CON("apu_ao_ctl_o-39"),
+ SLAVE_UNDEFINE0("apu_ao_ctl_o-40"),
+
+ /* ctrl index = 40 */
+ SLAVE_UNDEFINE1("apu_ao_ctl_o-41"),
+ SLAVE_RCX_BULK0("apu_ao_ctl_o-42"),
+ SLAVE_UNDEFINE2("apu_ao_ctl_o-43"),
+ SLAVE_UNDEFINE3("apu_ao_ctl_o-44"),
+ SLAVE_UNDEFINE4("apu_ao_ctl_o-45"),
+ SLAVE_UNDEFINE5("apu_ao_ctl_o-46"),
+ SLAVE_UNDEFINE6("apu_ao_ctl_o-47"),
+ SLAVE_UNDEFINE7("apu_ao_ctl_o-48"),
+ SLAVE_DATA_BULK("apu_ao_ctl_o-49"),
+ SLAVE_ACX0_BULK("apu_ao_ctl_o-50"),
+
+ /* ctrl index = 50 */
+ SLAVE_ACX0_AO("apu_ao_ctl_o-51"),
+ SLAVE_ACX1_BULK("apu_ao_ctl_o-52"),
+ SLAVE_ACX1_AO("apu_ao_ctl_o-53"),
+ SLAVE_NCX_BULK("apu_ao_ctl_o-54"),
+ SLAVE_NCX_AO("apu_ao_ctl_o-55"),
+ SLAVE_ACX0_BULK("apu_rcx2acx0_o-0"),
+ SLAVE_ACX0_AO("apu_rcx2acx0_o-1"),
+ SLAVE_ACX0_BULK("apu_sae2acx0_o-0"),
+ SLAVE_ACX0_AO("apu_sae2acx0_o-1"),
+ SLAVE_ACX1_BULK("apu_rcx2acx1_o-0"),
+
+ /* ctrl index = 60 */
+ SLAVE_ACX1_AO("apu_rcx2acx1_o-1"),
+ SLAVE_ACX1_BULK("apu_sae2acx1_o-0"),
+ SLAVE_ACX1_AO("apu_sae2acx1_o-1"),
+ SLAVE_NCX_BULK("apu_rcx2ncx_o-0"),
+ SLAVE_NCX_AO("apu_rcx2ncx_o-1"),
+ SLAVE_NCX_BULK("apu_sae2ncx_o-0"),
+ SLAVE_NCX_AO("apu_sae2ncx_o-1"),
+};
+
+
+/* RCX CONTROL DEVAPC - apu_rcx_infra_dapc_con */
+static const struct apc_dom_16 APUSYS_CTRL_DAPC_RCX[] = {
+ /* ctrl index = 0 */
+ SLAVE_ACX0_BULK("acx0_apbs-0"),
+ SLAVE_ACX0_RPC("acx0_apbs-1"),
+ SLAVE_ACX0_AO_CTRL("acx0_apbs-2"),
+ SLAVE_UNDEFINE8("acx0_apbs-3"),
+ SLAVE_ACX1_BULK("acx1_apbs-0"),
+ SLAVE_ACX1_RPC("acx1_apbs-1"),
+ SLAVE_ACX1_AO_CTRL("acx1_apbs-2"),
+ SLAVE_UNDEFINE9("acx1_apbs-3"),
+ SLAVE_NCX_BULK("ncx_apbs-0"),
+ SLAVE_NCX_RPC("ncx_apbs-1"),
+
+ /* ctrl index = 10 */
+ SLAVE_NCX_AO_CTRL("ncx_apbs-2"),
+ SLAVE_UNDEFINE10("ncx_apbs-3"),
+ SLAVE_MD32_SYSCTRL("md32_apb_s-0"),
+ SLAVE_MD32_PMU("md32_apb_s-1"),
+ SLAVE_MD32_WDT("md32_apb_s-2"),
+ SLAVE_MD32_CACHE("md32_apb_s-3"),
+ SLAVE_ARE0("apusys_ao-0"),
+ SLAVE_ARE1("apusys_ao-1"),
+ SLAVE_SONC("apusys_ao-2"),
+ SLAVE_RPC("apusys_ao-3"),
+
+ /* ctrl index = 20 */
+ SLAVE_PCU("apusys_ao-4"),
+ SLAVE_AO_CTRL("apusys_ao-5"),
+ SLAVE_AO_CTRL("apusys_ao-6"),
+ SLAVE_SEC("apusys_ao-7"),
+ SLAVE_PLL("apusys_ao-8"),
+ SLAVE_RPC_MDLA("apusys_ao-9"),
+ SLAVE_TOP_PMU("apusys_ao-10"),
+ SLAVE_AO_BCRM("apusys_ao-11"),
+ SLAVE_AO_DAPC_WRAP("apusys_ao-12"),
+ SLAVE_AO_DAPC_CON("apusys_ao-13"),
+
+ /* ctrl index = 30 */
+ SLAVE_VCORE("apusys_ao-14"),
+ SLAVE_IOMMU0_BANK0("apusys_ao-15"),
+ SLAVE_IOMMU0_BANK1("apusys_ao-16"),
+ SLAVE_IOMMU0_BANK2("apusys_ao-17"),
+ SLAVE_IOMMU0_BANK3("apusys_ao-18"),
+ SLAVE_IOMMU0_BANK4("apusys_ao-19"),
+ SLAVE_IOMMU1_BANK0("apu_ao_ctl_o-20"),
+ SLAVE_IOMMU1_BANK1("apu_ao_ctl_o-21"),
+ SLAVE_IOMMU1_BANK2("apu_ao_ctl_o-22"),
+ SLAVE_IOMMU1_BANK3("apu_ao_ctl_o-23"),
+
+ /* ctrl index = 40 */
+ SLAVE_IOMMU1_BANK4("apu_ao_ctl_o-24"),
+ SLAVE_S0_SSC("apu_ao_ctl_o-25"),
+ SLAVE_N0_SSC("apu_ao_ctl_o-26"),
+ SLAVE_S1_SSC("apu_ao_ctl_o-27"),
+ SLAVE_N1_SSC("apu_ao_ctl_o-28"),
+ SLAVE_ACP_SSC("apu_ao_ctl_o-29"),
+ SLAVE_ACP_TCU_SSC("apu_ao_ctl_o-30"),
+ SLAVE_PTP_THM("apu_ao_ctl_o-31"),
+ SLAVE_WDEC("apu_ao_ctl_o-32"),
+ SLAVE_SMMU_IP_REG("apu_ao_ctl_o-33"),
+
+ /* ctrl index = 50 */
+ SLAVE_SMMU_NSEC("apu_ao_ctl_o-34"),
+ SLAVE_SMMU_SEC("apu_ao_ctl_o-35"),
+ SLAVE_DATA_BULK("noc_axi"),
+ SLAVE_MD32_DBG("md32_dbg"),
+ SLAVE_MDLA_DBG("mdla_dbg"),
+ SLAVE_INFRA_DBG("apb_infra_dbg"),
+ SLAVE_LOG_TOP0("apu_logtop-0"),
+ SLAVE_LOG_TOP1("apu_logtop-1"),
+ SLAVE_RCX_CFG("apu_rcx_cfg"),
+ SLAVE_ACX_IPS("apu_acx_ips"),
+
+ /* ctrl index = 60 */
+ SLAVE_SEMA_STIMER("apu_sema_stimer"),
+ SLAVE_EMI_CFG("apu_emi_cfg"),
+ SLAVE_CPE_SENSOR("apu_cpe_sensor"),
+ SLAVE_CPE_COEF("apu_cpe_coef"),
+ SLAVE_CPE_CTRL("apu_cpe_ctrl"),
+ SLAVE_TPPA("apu_dfd"),
+ SLAVE_SENSOR_ACX0_DLA0("apu_sen_acx0_dla0"),
+ SLAVE_SENSOR_ACX0_VPU("apu_sen_acx0_vpu"),
+ SLAVE_SENSOR_ACX1_DLA0("apu_sen_acx1_dla0"),
+ SLAVE_SENSOR_ACX1_VPU("apu_sen_acx1_vpu"),
+
+ /* ctrl index = 70 */
+ SLAVE_SENSOR_NCX_DLA0("apu_sen_ncx_dla0"),
+ SLAVE_SENSOR_NCX_NVE("apu_sen_ncx_nve"),
+ SLAVE_RCX_TCU0("noc_cfg-0"),
+ SLAVE_RCX_TCU1("noc_cfg-1"),
+ SLAVE_RCX_TCU2("noc_cfg-2"),
+ SLAVE_RCX_TCU3("noc_cfg-3"),
+ SLAVE_RCX_TCU4("noc_cfg-4"),
+ SLAVE_RCX_TCU5("noc_cfg-5"),
+ SLAVE_RCX_TCU6("noc_cfg-6"),
+ SLAVE_RCX_NOC_CFG("noc_cfg-7"),
+
+ /* ctrl index = 80 */
+ SLAVE_SCMDQ("apu_hse-0"),
+ SLAVE_HSE("apu_hse-1"),
+ SLAVE_MDLA_CORE_CTRL("mdla_cfg-0"),
+ SLAVE_MDLA_BIU("mdla_cfg-1"),
+ SLAVE_MDLA_PMU("mdla_cfg-2"),
+ SLAVE_MDLA_CMDE("mdla_cfg-3"),
+ SLAVE_EDPA0("apu_edpa-0"),
+ SLAVE_EDPA1("apu_edpa-1"),
+ SLAVE_RCX_BCRM("infra_bcrm"),
+ SLAVE_RCX_DAPC_WRAP("infra_dpac_wrap"),
+
+ /* ctrl index = 90 */
+ SLAVE_RCX_DAPC_CON("infra_dapc_con"),
+ SLAVE_RCX_CMU("rcx_cmu"),
+ SLAVE_RCX_ACS("apu_rcx_acs"),
+ SLAVE_RCX_CBFC("rcx_cbfc"),
+ SLAVE_ACC("acc"),
+};
+
+static enum apusys_apc_err_status set_slave_ctrl_apc(uint32_t slave,
+ enum apusys_apc_type type,
+ enum apusys_apc_domain_id domain_id,
+ enum apusys_apc_perm_type perm)
+{
+ uint32_t apc_register_index;
+ uint32_t apc_set_index;
+ uint32_t base = 0;
+ uint32_t clr_bit;
+ uint32_t set_bit;
+ uint32_t slave_num_in_1_dom;
+ uint32_t slave_num, dom_num;
+ uint32_t dapc_base;
+
+ if (perm >= PERM_NUM) {
+ ERROR("%s: permission type:0x%x is not supported!\n", __func__, perm);
+ return APUSYS_APC_ERR_PERMISSION_NOT_SUPPORTED;
+ }
+
+ switch (type) {
+ case DAPC_AO:
+ slave_num_in_1_dom = APUSYS_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM;
+ slave_num = APUSYS_CTRL_DAPC_AO_SLAVE_NUM;
+ dom_num = APUSYS_CTRL_DAPC_AO_DOM_NUM;
+ dapc_base = APUSYS_CTRL_DAPC_AO_BASE;
+ break;
+ case DAPC_RCX:
+ slave_num_in_1_dom = APUSYS_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM;
+ slave_num = APUSYS_CTRL_DAPC_RCX_SLAVE_NUM;
+ dom_num = APUSYS_CTRL_DAPC_RCX_DOM_NUM;
+ dapc_base = APUSYS_CTRL_DAPC_RCX_BASE;
+ break;
+ default:
+ ERROR("%s: unsupported devapc type: %u\n", __func__, type);
+ return APUSYS_APC_ERR_GENERIC;
+ }
+
+ apc_register_index = slave / slave_num_in_1_dom;
+ apc_set_index = slave % slave_num_in_1_dom;
+
+ clr_bit = DEVAPC_MASK << (apc_set_index * DEVAPC_DOM_SHIFT);
+ set_bit = (uint32_t)perm << (apc_set_index * DEVAPC_DOM_SHIFT);
+
+ if (slave < slave_num && domain_id < dom_num) {
+ base = dapc_base + domain_id * DEVAPC_DOM_SIZE
+ + apc_register_index * DEVAPC_REG_SIZE;
+ } else {
+ ERROR("%s: out of boundary, devapc type: %d, slave: 0x%x, domain_id: 0x%x\n",
+ __func__, type, slave, domain_id);
+ return APUSYS_APC_ERR_OUT_OF_BOUNDARY;
+ }
+
+ if (!base)
+ return APUSYS_APC_ERR_GENERIC;
+
+ mmio_clrsetbits_32(base, clr_bit, set_bit);
+ return APUSYS_APC_OK;
+}
+
+static enum apusys_apc_err_status set_slave_ao_ctrl_apc(uint32_t slave,
+ enum apusys_apc_domain_id domain_id,
+ enum apusys_apc_perm_type perm)
+{
+ return set_slave_ctrl_apc(slave, DAPC_AO, domain_id, perm);
+}
+
+static enum apusys_apc_err_status set_slave_rcx_ctrl_apc(uint32_t slave,
+ enum apusys_apc_domain_id domain_id,
+ enum apusys_apc_perm_type perm)
+{
+ return set_slave_ctrl_apc(slave, DAPC_RCX, domain_id, perm);
+}
+
+static void apusys_devapc_init(uint32_t base)
+{
+ mmio_write_32(APUSYS_DAPC_CON(base), APUSYS_DAPC_CON_VIO_MASK);
+}
+
+int apusys_devapc_ao_init(void)
+{
+ int32_t ret = APUSYS_APC_OK;
+
+ apusys_devapc_init(APUSYS_CTRL_DAPC_AO_BASE);
+
+ ret = SET_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_AO, set_slave_ao_ctrl_apc);
+
+ if (ret) {
+ ERROR("[APUAPC_AO] %s: set_apusys_ao_ctrl_dapc failed\n", __func__);
+ return ret;
+ }
+
+#ifdef DUMP_CFG
+ DUMP_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_AO);
+#endif
+
+ INFO("[APUAPC_AO] %s done\n", __func__);
+
+ return ret;
+}
+
+int apusys_devapc_rcx_init(void)
+{
+ int32_t ret = APUSYS_APC_OK;
+
+ apusys_devapc_init(APUSYS_CTRL_DAPC_RCX_BASE);
+
+ ret = SET_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_RCX, set_slave_rcx_ctrl_apc);
+ if (ret) {
+ ERROR("[APUAPC_RCX] %s: set_slave_rcx_ctrl_apc failed\n", __func__);
+ return ret;
+ }
+
+#ifdef DUMP_CFG
+ DUMP_APUSYS_DAPC_V1(APUSYS_CTRL_DAPC_RCX);
+#endif
+
+ INFO("[APUAPC_RCX] %s done\n", __func__);
+
+ return ret;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.h b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.h
new file mode 100644
index 0000000..8d6204e
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_DEVAPC_H
+#define APUSYS_DEVAPC_H
+
+enum apusys_apc_type {
+ DAPC_AO = 0,
+ DAPC_RCX
+};
+
+int apusys_devapc_ao_init(void);
+int apusys_devapc_rcx_init(void);
+
+#endif /* APUSYS_DEVAPC_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_devapc_def.h b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc_def.h
new file mode 100644
index 0000000..af63c0c
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_devapc_def.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_DEVAPC_DEF_H
+#define APUSYS_DEVAPC_DEF_H
+
+#include <lib/mmio.h>
+
+#include <devapc/apusys_dapc_v1.h>
+
+/* Control */
+#define SLAVE_RCX_BULK0 SLAVE_FORBID_EXCEPT_D0_D11_NO_PROTECT_D3_D5_D8_SEC_RW
+#define SLAVE_RCX_BULK1 SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_D8_SEC_RW
+#define SLAVE_MD32_APB SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
+#define SLAVE_ACP_TCU_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_VCORE SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D3_D5_SEC_RW
+#define SLAVE_WDEC SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_SMMU_IP_REG SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D4_D11_NO_PROTECT
+#define SLAVE_SMMU_NSEC SLAVE_FORBID_EXCEPT_D5_SEC_RW_D0_NO_PROTECT
+#define SLAVE_SMMU_SEC SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_RPC SLAVE_FORBID_EXCEPT_D3_D5_SEC_RW_D0_D11_NO_PROTECT
+#define SLAVE_PCU SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
+#define SLAVE_AO_CTRL SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW
+#define SLAVE_ACC SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
+#define SLAVE_PLL SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_D8_SEC_RW
+#define SLAVE_SEC SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_ARE0 SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ARE1 SLAVE_FORBID_EXCEPT_D0_D11_NO_PROTECT_D3_D5_D8_SEC_RW
+#define SLAVE_RPC_MDLA SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW
+#define SLAVE_MDLA_DBG SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_TOP_PMU SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW
+#define SLAVE_UNDEFINE0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE1 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE2 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE3 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE4 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE5 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE6 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE7 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE8 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE9 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_UNDEFINE10 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_DATA_BULK SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_AO_BCRM SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_AO_DAPC_WRAP SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_AO_DAPC_CON SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_ACX0_AO SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX0_BULK SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX0_RPC SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX0_AO_CTRL SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_ACX1_AO SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX1_BULK SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX1_RPC SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_ACX1_AO_CTRL SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_NCX_AO SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_NCX_BULK SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#define SLAVE_NCX_RPC SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_NCX_AO_CTRL SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_MD32_SYSCTRL SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW
+#define SLAVE_MD32_PMU SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D3_D5_SEC_RW
+#define SLAVE_LOG_TOP0 SLAVE_FORBID_EXCEPT_D0_D5_D7_D14_NO_PROTECT
+#define SLAVE_LOG_TOP1 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_CFG SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D3_D5_SEC_RW
+#define SLAVE_ACX_IPS SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_TCU0 SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_RCX_TCU1 SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_RCX_TCU2 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_TCU3 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_TCU4 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_TCU5 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_TCU6 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_NOC_CFG SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_MDLA_CORE_CTRL SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_MDLA_BIU SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_MDLA_PMU SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_MDLA_CMDE SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_EDPA0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_EDPA1 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_CMU SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_RCX_ACS SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_MD32_WDT SLAVE_FORBID_EXCEPT_D0_D3_D5_SEC_RW
+#define SLAVE_MD32_CACHE SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_MD32_DBG SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_SEC_RW
+#define SLAVE_INFRA_DBG SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_IOMMU0_BANK0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU0_BANK1 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU0_BANK2 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU0_BANK3 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU0_BANK4 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU1_BANK0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU1_BANK1 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU1_BANK2 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU1_BANK3 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_IOMMU1_BANK4 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_S0_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_N0_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_ACP_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_S1_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_N1_SSC SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SEMA_STIMER SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_EMI_CFG SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_CPE_SENSOR SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_CPE_COEF SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_CPE_CTRL SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_TPPA SLAVE_FORBID_EXCEPT_D5_D8_SEC_RW
+#define SLAVE_SENSOR_ACX0_DLA0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SENSOR_ACX0_VPU SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SENSOR_ACX1_DLA0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SENSOR_ACX1_VPU SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SENSOR_NCX_DLA0 SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SENSOR_NCX_NVE SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_BCRM SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_DAPC_WRAP SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_DAPC_CON SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_HSE SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_RCX_CBFC SLAVE_FORBID_EXCEPT_D5_SEC_RW
+#define SLAVE_SONC SLAVE_FORBID_EXCEPT_D0_D5_SEC_RW
+#define SLAVE_SCMDQ SLAVE_FORBID_EXCEPT_D5_SEC_RW
+
+#if DEBUG
+#define SLAVE_PTP_THM SLAVE_FORBID_EXCEPT_D0_NO_PROTECT_D5_SEC_RW
+#else
+#define SLAVE_PTP_THM SLAVE_FORBID_EXCEPT_D0_SEC_RW_NS_R_D5_SEC_RW
+#endif
+
+/* Power Domain: AO */
+#define APUSYS_CTRL_DAPC_AO_SLAVE_NUM_IN_1_DOM (16)
+#define APUSYS_CTRL_DAPC_AO_DOM_NUM (16)
+#define APUSYS_CTRL_DAPC_AO_SLAVE_NUM (67) /* 0~66 */
+#define DEVAPC_MASK (0x3U)
+#define DEVAPC_DOM_SHIFT (2)
+
+/* Power Domain: RCX */
+#define APUSYS_CTRL_DAPC_RCX_SLAVE_NUM_IN_1_DOM (16)
+#define APUSYS_CTRL_DAPC_RCX_DOM_NUM (16)
+#define APUSYS_CTRL_DAPC_RCX_SLAVE_NUM (95) /* 0~94 */
+
+/* Dump Config */
+#define DUMP_CFG
+
+#endif
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_power.c b/plat/mediatek/drivers/apusys/mt8196/apusys_power.c
new file mode 100644
index 0000000..4262d63
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_power.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <inttypes.h>
+
+#define SPMI_ENABLE (0)
+
+#if SPMI_ENABLE
+#include <include/drivers/spmi_api.h>
+#endif
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include "apusys_power.h"
+
+static void apu_w_are(int entry, uint32_t reg, uint32_t data)
+{
+ uint32_t are_entry_addr;
+
+ are_entry_addr = APUSYS_BASE + APU_ARE + ARE_REG_SIZE * ARE_ENTRY(entry);
+ mmio_write_32(are_entry_addr, reg);
+ mmio_write_32((are_entry_addr + ARE_REG_SIZE), data);
+}
+
+static void get_pll_pcw(uint32_t clk_rate, uint32_t *r1, uint32_t *r2)
+{
+ unsigned int fvco = clk_rate;
+ unsigned int pcw_val;
+ unsigned int postdiv_val = 1;
+ unsigned int postdiv_reg = 0;
+
+ while (fvco <= OUT_CLK_FREQ_MIN) {
+ postdiv_val = postdiv_val << 1;
+ postdiv_reg = postdiv_reg + 1;
+ fvco = fvco << 1;
+ }
+
+ pcw_val = (fvco * (1 << DDS_SHIFT)) / BASIC_CLK_FREQ;
+
+ if (postdiv_reg == 0) {
+ pcw_val = pcw_val * 2;
+ postdiv_val = postdiv_val << 1;
+ postdiv_reg = postdiv_reg + 1;
+ }
+
+ *r1 = postdiv_reg;
+ *r2 = pcw_val;
+}
+
+static void buck_off_by_pcu(uint32_t ofs, uint32_t shift, uint32_t slv_id)
+{
+ uint32_t pmif_id = 0x0;
+ int retry = 10;
+
+ mmio_setbits_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, PMIC_IRQ_EN);
+ mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_TAR_BUF1,
+ (ofs << PMIC_OFF_ADDR_OFF) | BIT(shift));
+ mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_TAR_BUF2,
+ (slv_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_BUCK_OFF_CMD);
+ mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_CMD, PMIC_CMD_EN);
+
+ while ((mmio_read_32(APUSYS_PCU + APU_PCU_PMIC_IRQ) & PMIC_CMD_IRQ) == 0) {
+ udelay(10);
+ if (--retry < 0)
+ ERROR("%s wait APU_PCU_PMIC_IRQ timeout !\n", __func__);
+ }
+
+ mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_IRQ, PMIC_CMD_IRQ);
+}
+
+static void apu_buck_off_cfg(void)
+{
+ mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(10));
+ mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(9));
+ mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(12));
+ mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(14));
+
+ mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(10));
+ mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(9));
+ mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(12));
+ mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(14));
+ udelay(1);
+
+ mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_PROT_REQ_SET);
+ udelay(1);
+
+ mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, SRAM_AOC_LHENB_SET);
+ udelay(1);
+
+ mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, SRAM_AOC_ISO_SET);
+ udelay(1);
+
+ mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, PLL_AOC_ISO_EN_SET);
+ udelay(1);
+
+ mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_ELS_EN_SET);
+ udelay(1);
+
+ mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_AO_RST_B_CLR);
+ udelay(1);
+
+ buck_off_by_pcu(BUCK_VAPU_PMIC_REG_EN_CLR_ADDR, BUCK_VAPU_PMIC_REG_EN_SHIFT,
+ BUCK_VAPU_PMIC_ID);
+
+ mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(6));
+ udelay(1);
+ mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(7));
+ udelay(1);
+ mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(6));
+ udelay(1);
+ mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(7));
+ udelay(1);
+}
+
+static void apu_acc_init(void)
+{
+ uint32_t top_acc_base_arr[] = {MNOC_ACC_BASE, UP_ACC_BASE};
+ uint32_t eng_acc_base_arr[] = {MVPU_ACC_BASE, MDLA_ACC_BASE};
+ int acc_idx;
+ int are_idx = ACC_ENTRY_BEGIN;
+ uint32_t base_reg;
+
+ for (acc_idx = 0 ; acc_idx < ARRAY_SIZE(top_acc_base_arr) ; acc_idx++) {
+ base_reg = APUSYS_ACC + top_acc_base_arr[acc_idx];
+#if CFG_APU_ARDCM_ENABLE
+ apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_0);
+ apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_0);
+ apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_1);
+ apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_1);
+#endif
+ apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_CLR0, CGEN_SOC);
+ apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_SET0, HW_CTRL_EN);
+ }
+
+ for (acc_idx = 0 ; acc_idx < ARRAY_SIZE(eng_acc_base_arr) ; acc_idx++) {
+ base_reg = APUSYS_ACC + eng_acc_base_arr[acc_idx];
+#if CFG_APU_ARDCM_ENABLE
+ apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_0);
+ apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_0);
+ apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_1);
+ apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_1);
+#endif
+ apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_CLR0, CGEN_SOC);
+ apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_SET0, HW_CTRL_EN);
+ apu_w_are(are_idx++, base_reg + APU_ACC_AUTO_CTRL_SET0, CLK_REQ_SW_EN);
+ }
+}
+
+static void apu_pll_init(void)
+{
+ uint32_t pll_base_arr[] = {MNOC_PLL_BASE, UP_PLL_BASE, MVPU_PLL_BASE, MDLA_PLL_BASE};
+ int32_t pll_freq_out[] = {
+ APUPLL0_DEFAULT_FREQ,
+ APUPLL1_DEFAULT_FREQ,
+ APUPLL2_DEFAULT_FREQ,
+ APUPLL3_DEFAULT_FREQ
+ };
+ uint32_t pcw_val, posdiv_val;
+ int pll_idx, are_idx;
+ uint32_t base_reg;
+
+ mmio_setbits_32(APUSYS_BASE + APU_ARE, ARE_RCX_AO_EN);
+ mmio_setbits_32(APUSYS_BASE + APU_ARE_REG, ARE_RCX_AO_EN);
+
+ mmio_write_32(APUSYS_BASE + APU_ARE + ARE_RCX_AO_CONFIG, ARE_ENTRY(RCX_AO_BEGIN) |
+ (ARE_ENTRIES(RCX_AO_BEGIN, RCX_AO_END) << ARE_RCX_AO_CONFIG_HIGH_OFF));
+
+ are_idx = PLL_ENTRY_BEGIN;
+ for (pll_idx = 0 ; pll_idx < ARRAY_SIZE(pll_base_arr) ; pll_idx++) {
+ base_reg = APUSYS_PLL + pll_base_arr[pll_idx];
+
+ apu_w_are(are_idx++, base_reg + RG_PLLGP_LVR_REFSEL, RG_PLLGP_LVR_REFSEL_VAL);
+ apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_HP_EN, FHCTL_CTRL);
+ apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_RST_CON, FHCTL_NO_RESET);
+ apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_CLK_CON, FHCTL_CLKEN);
+ apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL0_CFG,
+ FHCTL_HOPPING_EN | FHCTL_SFSTR0_EN);
+
+ posdiv_val = 0;
+ pcw_val = 0;
+ get_pll_pcw(pll_freq_out[pll_idx], &posdiv_val, &pcw_val);
+
+ apu_w_are(are_idx++, base_reg + PLL1C_PLL1_CON1,
+ ((0x1U << RG_PLL_SDM_PCW_CHG_OFF) |
+ (posdiv_val << RG_PLL_POSDIV_OFF) | pcw_val));
+
+ apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL0_DDS,
+ ((0x1U << FHCTL0_PLL_TGL_ORG) | pcw_val));
+ }
+}
+
+static void apu_are_init(void)
+{
+ int entry = 0;
+
+ mmio_clrbits_32(APUSYS_BASE + APU_ARE, 0xFFFU << ARE_VCORE_OFF);
+
+ mmio_setbits_32(APUSYS_BASE + APU_ARE, ARE_VCORE_EN);
+ mmio_setbits_32(APUSYS_BASE + APU_ARE_REG, ARE_VCORE_EN);
+
+ for (entry = ARE_CONF_START; entry < ARE_CONF_END; entry += 4)
+ mmio_write_32(APUSYS_BASE + APU_ARE + entry, 0);
+}
+
+static void apu_rpclite_init(void)
+{
+ uint32_t sleep_type_offset[] = {
+ APU_RPC_SW_TYPE1_OFF,
+ APU_RPC_SW_TYPE2_OFF,
+ APU_RPC_SW_TYPE3_OFF,
+ APU_RPC_SW_TYPE4_OFF
+ };
+ uint32_t rpc_lite_base[] = {
+ APU_ACX0_RPC_LITE,
+ APU_ACX1_RPC_LITE,
+ APU_ACX2_RPC_LITE,
+ };
+ int ofs_idx, rpc_lite_idx;
+ uint32_t base;
+
+ for (rpc_lite_idx = 0; rpc_lite_idx < ARRAY_SIZE(rpc_lite_base); rpc_lite_idx++) {
+ base = APUSYS_BASE + rpc_lite_base[rpc_lite_idx];
+ for (ofs_idx = 0; ofs_idx < ARRAY_SIZE(sleep_type_offset); ofs_idx++)
+ mmio_clrbits_32(base + sleep_type_offset[ofs_idx],
+ SW_TYPE_MVPU_MDLA_RV);
+ mmio_setbits_32(base + APU_RPC_TOP_SEL, TOP_SEL_VAL);
+ }
+}
+
+static void apu_rpc_mdla_init(void)
+{
+ mmio_clrbits_32(APUSYS_BASE + APU_RPCTOP_MDLA + APU_RPC_SW_TYPE0_OFF, SW_TYPE_MVPU_MDLA_RV);
+}
+
+static void apu_rpc_init(void)
+{
+ mmio_write_32(APUSYS_RPC + APU_RPC_SW_TYPE0_OFF, RPC_TYPE_INIT_VAL);
+ mmio_setbits_32(APUSYS_RPC + APU_RPC_TOP_SEL, RPC_TOP_SEL_VAL);
+
+#if !CFG_CTL_RPC_BY_CE
+ mmio_clrbits_32(APUSYS_RPC + APU_RPC_TOP_SEL, CE_ENABLE);
+#endif
+
+ mmio_setbits_32(APUSYS_RPC + APU_RPC_TOP_SEL_1, BUCK_PROT_SEL);
+}
+
+static int apu_pcu_init(void)
+{
+ uint32_t pmif_id = 0x0;
+ uint32_t slave_id = BUCK_VAPU_PMIC_ID;
+ uint32_t en_set_offset = BUCK_VAPU_PMIC_REG_EN_SET_ADDR;
+ uint32_t en_clr_offset = BUCK_VAPU_PMIC_REG_EN_CLR_ADDR;
+ uint32_t en_shift = BUCK_VAPU_PMIC_REG_EN_SHIFT;
+#if SPMI_ENABLE
+ struct spmi_device *vsram_sdev;
+#endif
+ unsigned char vsram = 0;
+
+ mmio_write_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, AUTO_BUCK_EN);
+
+ mmio_write_32((APUSYS_PCU + APU_PCU_BUCK_STEP_SEL), BUCK_STEP_SEL_VAL);
+
+#if SPMI_ENABLE
+ vsram_sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
+ if (!vsram_sdev) {
+ ERROR("[APUPW] VSRAM BUCK4 get device fail\n");
+ return -1;
+ }
+
+ if (spmi_ext_register_readl(vsram_sdev, MT6363_RG_BUCK_VBUCK4_VOSEL_ADDR, &vsram, 1)) {
+ ERROR("[APUPW] VSRAM BUCK4 read fail\n");
+ return -1;
+ }
+#endif
+
+ mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_L,
+ (BUCK_VAPU_PMIC_REG_VOSEL_ADDR << PMIC_OFF_ADDR_OFF) | vsram);
+
+ mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_H,
+ (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
+
+ mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT1_L,
+ (en_set_offset << PMIC_OFF_ADDR_OFF) | (0x1U << en_shift));
+ mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT1_H,
+ (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
+
+ mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_OFF_DAT0_L,
+ (en_clr_offset << PMIC_OFF_ADDR_OFF) | (0x1U << en_shift));
+ mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_OFF_DAT0_H,
+ (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W);
+
+ mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_SLE0, 0);
+ mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_SLE1, VAPU_BUCK_ON_SETTLE_TIME);
+
+ return 0;
+}
+
+static void apu_aoc_init(void)
+{
+ uint32_t reg;
+
+ mmio_setbits_32(SPM_BASE + 0xF6C, BIT(4));
+ mmio_clrbits_32(SPM_BASE + 0x414, BIT(1));
+
+ mmio_write_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CONFIG, APUSYS_AO_SRAM_EN);
+ udelay(1);
+
+ reg = APUSYS_AO_CTL + APUSYS_AO_SRAM_SET;
+
+#if !CFG_CTL_RPC_BY_CE
+ mmio_setbits_32(reg, BIT(8));
+ udelay(1);
+ mmio_setbits_32(reg, BIT(11));
+ udelay(1);
+ mmio_setbits_32(reg, BIT(13));
+ udelay(1);
+
+ mmio_clrbits_32(reg, BIT(8));
+ udelay(1);
+ mmio_clrbits_32(reg, BIT(11));
+ udelay(1);
+ mmio_clrbits_32(reg, BIT(13));
+#else
+ mmio_setbits_32(reg, BIT(9));
+ mmio_setbits_32(reg, BIT(12));
+ mmio_setbits_32(reg, BIT(14));
+
+ mmio_clrbits_32(reg, BIT(9));
+ mmio_clrbits_32(reg, BIT(12));
+ mmio_clrbits_32(reg, BIT(14));
+ udelay(1);
+#endif
+
+ reg = APUSYS_RPC + APU_RPC_HW_CON;
+
+ mmio_write_32(reg, BUCK_ELS_EN_CLR);
+ udelay(1);
+
+ mmio_write_32(reg, BUCK_AO_RST_B_SET);
+ udelay(1);
+
+ mmio_write_32(reg, BUCK_PROT_REQ_CLR);
+ udelay(1);
+
+ mmio_write_32(reg, SRAM_AOC_ISO_CLR);
+ udelay(1);
+
+ mmio_write_32(reg, PLL_AOC_ISO_EN_CLR);
+ udelay(1);
+}
+
+static int init_hw_setting(void)
+{
+ int ret;
+
+ apu_aoc_init();
+ ret = apu_pcu_init();
+ apu_rpc_init();
+ apu_rpc_mdla_init();
+ apu_rpclite_init();
+ apu_are_init();
+ apu_pll_init();
+ apu_acc_init();
+ apu_buck_off_cfg();
+
+ return ret;
+}
+
+int apusys_power_init(void)
+{
+ int ret;
+
+ ret = init_hw_setting();
+ if (ret != 0)
+ ERROR("%s init HW failed\n", __func__);
+ else
+ INFO("%s init HW done\n", __func__);
+
+ mmio_write_32(APU_ACE_HW_FLAG_DIS, APU_ACE_DIS_FLAG_VAL);
+
+ return ret;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_power.h b/plat/mediatek/drivers/apusys/mt8196/apusys_power.h
new file mode 100644
index 0000000..ddf35c5
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_power.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_POWER_H
+#define APUSYS_POWER_H
+
+#include <platform_def.h>
+
+#define CFG_APU_ARDCM_ENABLE (0)
+#define CFG_CTL_RPC_BY_CE (1)
+
+#define APUPLL0_DEFAULT_FREQ (800)
+#define APUPLL1_DEFAULT_FREQ (960)
+#define APUPLL2_DEFAULT_FREQ (1200)
+#define APUPLL3_DEFAULT_FREQ (1230)
+
+enum t_acx_id {
+ D_ACX0 = 0,
+ ACX0,
+ ACX1,
+ ACX2,
+ CLUSTER_NUM,
+ RCX,
+};
+
+enum rcx_ao_range {
+ RCX_AO_BEGIN = 0,
+ PLL_ENTRY_BEGIN = 0,
+ PLL_ENTRY_END = 27,
+ ACC_ENTRY_BEGIN = 28,
+ ACC_ENTRY_END = 37,
+ RCX_AO_END = 37,
+};
+
+#define SYS_VLP (0x000000)
+#define SYS_SPM (0x000000)
+#define APU_RCX (0x020000)
+#define APU_RCX_DLA (0x040000)
+#define APU_ARE (0x0a0000)
+#define APU_ARE_REG (0x0b0000)
+#define APU_VCORE (0x0e0000)
+#define APU_MD32_MBOX (0x0e1000)
+#define APU_RPC (0x0f0000)
+#define APU_PCU (0x0f1000)
+#define APU_AO_CTL (0x0f2000)
+#define APU_ACC (0x0f3000)
+#define APU_PLL (0x0f6000)
+#define APU_RPCTOP_MDLA (0x0F7400)
+#define APU_ACX0 (0x100000)
+#define APU_ACX0_RPC_LITE (0x140000)
+#define APU_ACX1 (0x200000)
+#define APU_ACX1_RPC_LITE (0x240000)
+#define APU_ACX2 (0x300000)
+#define APU_ACX2_RPC_LITE (0x340000)
+
+/* APU GRP offset define */
+#define APU_GRP_0_BASE (0x0000)
+#define APU_GRP_1_BASE (0x0400)
+#define APU_GRP_2_BASE (0x0800)
+#define APU_GRP_3_BASE (0x0C00)
+
+#define MDLA_PLL_BASE APU_GRP_0_BASE
+#define MVPU_PLL_BASE APU_GRP_1_BASE
+#define MNOC_PLL_BASE APU_GRP_2_BASE
+#define UP_PLL_BASE APU_GRP_3_BASE
+
+#define MDLA_ACC_BASE APU_GRP_0_BASE
+#define MVPU_ACC_BASE APU_GRP_1_BASE
+#define MNOC_ACC_BASE APU_GRP_2_BASE
+#define UP_ACC_BASE APU_GRP_3_BASE
+
+/* RPC / RPC_LITE control */
+#define APU_RPC_SW_TYPE0_OFF (0x200)
+#define APU_RPC_SW_TYPE1_OFF (0x204)
+#define APU_RPC_SW_TYPE2_OFF (0x208)
+#define APU_RPC_SW_TYPE3_OFF (0x20C)
+#define APU_RPC_SW_TYPE4_OFF (0x210)
+#define SW_TYPE_MVPU_MDLA_RV BIT(0)
+#define CE_ENABLE BIT(10)
+#define BUCK_PROT_SEL BIT(20)
+#define RPC_TYPE_INIT_VAL (0x18)
+#define TOP_SEL_VAL (0xB2)
+#define RPC_TOP_SEL_VAL (0xB800D50F)
+
+#define APUSYS_AO_CTL (APUSYS_BASE + APU_AO_CTL)
+#define APUSYS_RPC (APUSYS_BASE + APU_RPC)
+#define APUSYS_ACC (APUSYS_BASE + APU_ACC)
+#define APUSYS_PLL (APUSYS_BASE + APU_PLL)
+#define APUSYS_PCU (APUSYS_BASE + APU_PCU)
+
+/* ARE control */
+#define ARE_VCORE_EN BIT(20)
+#define ARE_RCX_AO_EN BIT(21)
+#define ARE_VCORE_OFF (20)
+#define ARE_CONF_START (0x04)
+#define ARE_CONF_END (0x6C)
+#define ARE_REG_SIZE (4)
+
+/* ACC offset */
+#define APU_ACC_CONFG_SET0 (0x000)
+#define APU_ACC_CONFG_CLR0 (0x010)
+#define APU_ACC_AUTO_CTRL_SET0 (0x084)
+#define APU_ARDCM_CTRL0 (0x100)
+#define APU_ARDCM_CTRL1 (0x104)
+
+/* ACC control */
+#define APU_ARDCM_CTRL0_VAL_0 (0x00000016)
+#define APU_ARDCM_CTRL0_VAL_1 (0x00000036)
+#define APU_ARDCM_CTRL1_VAL_0 (0x00001006)
+#define APU_ARDCM_CTRL1_VAL_1 (0x07F0F006)
+#define CGEN_SOC BIT(2)
+#define CLK_REQ_SW_EN BIT(8)
+#define HW_CTRL_EN BIT(15)
+
+/* APU PLL1C offset */
+#define RG_PLLGP_LVR_REFSEL (0x204)
+#define PLL1C_PLL1_CON1 (0x20C)
+#define PLL1CPLL_FHCTL_HP_EN (0x300)
+#define PLL1CPLL_FHCTL_CLK_CON (0x308)
+#define PLL1CPLL_FHCTL_RST_CON (0x30C)
+#define PLL1CPLL_FHCTL0_CFG (0x314)
+#define PLL1CPLL_FHCTL0_DDS (0x31C)
+
+/* PLL control */
+#define RG_PLLGP_LVR_REFSEL_VAL (0x3)
+#define FHCTL_CTRL (0x1)
+#define FHCTL_NO_RESET (0x1)
+#define FHCTL_CLKEN (0x1)
+#define FHCTL_HOPPING_EN BIT(0)
+#define FHCTL_SFSTR0_EN BIT(2)
+#define RG_PLL_SDM_PCW_CHG_OFF (31)
+#define RG_PLL_POSDIV_OFF (24)
+#define FHCTL0_PLL_TGL_ORG (31)
+
+/* RPC offset define */
+#define APU_RPC_TOP_SEL (0x0004)
+#define APU_RPC_TOP_SEL_1 (0x0018)
+#define APU_RPC_HW_CON (0x001C)
+#define APU_RPC_STATUS_1 (0x0034)
+#define APU_RPC_INTF_PWR_RDY (0x0044)
+
+/* RPC control */
+#define SRAM_AOC_LHENB_SET BIT(4)
+#define SRAM_AOC_ISO_SET BIT(6)
+#define SRAM_AOC_ISO_CLR BIT(7)
+#define PLL_AOC_ISO_EN_SET BIT(8)
+#define PLL_AOC_ISO_EN_CLR BIT(9)
+#define BUCK_ELS_EN_SET BIT(10)
+#define BUCK_ELS_EN_CLR BIT(11)
+#define BUCK_AO_RST_B_SET BIT(12)
+#define BUCK_AO_RST_B_CLR BIT(13)
+#define BUCK_PROT_REQ_SET BIT(14)
+#define BUCK_PROT_REQ_CLR BIT(15)
+
+/* mt6373_vbuck2 */
+#define MT6373_SLAVE_ID (0x5)
+#define MT6373_RG_BUCK_VBUCK2_SET (0x241)
+#define MT6373_RG_BUCK_VBUCK2_CLR (0x242)
+#define MT6373_RG_BUCK_VBUCK2_EN_SHIFT (2)
+#define MT6373_RG_BUCK_VBUCK2_VOSEL_ADDR (0x24e)
+
+/* PCU initial data */
+#define APU_PCUTOP_CTRL_SET (0x0)
+#define APU_PCU_BUCK_STEP_SEL (0x0030)
+#define APU_PCU_BUCK_ON_DAT0_L (0x0080)
+#define APU_PCU_BUCK_ON_DAT0_H (0x0084)
+#define APU_PCU_BUCK_ON_DAT1_L (0x0088)
+#define APU_PCU_BUCK_ON_DAT1_H (0x008C)
+#define APU_PCU_BUCK_OFF_DAT0_L (0x00A0)
+#define APU_PCU_BUCK_OFF_DAT0_H (0x00A4)
+#define APU_PCU_BUCK_ON_SLE0 (0x00C0)
+#define APU_PCU_BUCK_ON_SLE1 (0x00C4)
+#define VAPU_BUCK_ON_SETTLE_TIME (0x00C8)
+#define APU_PCU_PMIC_TAR_BUF1 (0x0190)
+#define APU_PCU_PMIC_TAR_BUF2 (0x0194)
+#define APU_PCU_PMIC_CMD (0x0184)
+#define APU_PCU_PMIC_IRQ (0x0180)
+
+/* PCU control */
+#define PMIC_CMD_IRQ BIT(0)
+#define PMIC_IRQ_EN BIT(2)
+#define AUTO_BUCK_EN BIT(3)
+#define PMIC_PMIFID_OFF (3)
+#define PMIC_SLVID_OFF (4)
+#define PCU_CMD_OP_W (0x7)
+#define PMIC_OFF_ADDR_OFF (16)
+#define PMIC_CMD_EN (0x1)
+#define BUCK_STEP_SEL_VAL (0x13)
+#define PCU_BUCK_OFF_CMD (0x7)
+
+/* sram_core: mt6363_vbuck4 */
+#define MT6363_RG_BUCK_VBUCK4_VOSEL_ADDR (0x250)
+
+/* sub_pmic */
+#define BUCK_VAPU_PMIC_ID MT6373_SLAVE_ID
+#define BUCK_VAPU_PMIC_REG_VOSEL_ADDR MT6373_RG_BUCK_VBUCK2_VOSEL_ADDR
+#define BUCK_VAPU_PMIC_REG_EN_SET_ADDR MT6373_RG_BUCK_VBUCK2_SET
+#define BUCK_VAPU_PMIC_REG_EN_CLR_ADDR MT6373_RG_BUCK_VBUCK2_CLR
+#define BUCK_VAPU_PMIC_REG_EN_SHIFT MT6373_RG_BUCK_VBUCK2_EN_SHIFT
+
+/* vlp offset define */
+#define APUSYS_AO_SRAM_CONFIG (0x70)
+#define APUSYS_AO_SRAM_SET (0x74)
+#define APUSYS_AO_SRAM_CLR (0x78)
+
+#define APUSYS_AO_SRAM_EN (0x1)
+
+#define ARE_ENTRIES(x, y) ((((y) - (x)) + 1) * 2)
+#define ARE_ENTRY(x) (((x) * 2) + 36)
+#define ARE_RCX_AO_CONFIG (0x0014)
+#define ARE_RCX_AO_CONFIG_HIGH_OFF (16)
+
+#define APU_ACE_HW_FLAG_DIS (APUSYS_CE_BASE + 0x05D4)
+#define APU_ACE_DIS_FLAG_VAL (0xffff7ff8)
+
+#define OUT_CLK_FREQ_MIN (1500)
+#define DDS_SHIFT (14)
+#define BASIC_CLK_FREQ (26)
+
+int apusys_power_init(void);
+
+#endif /* APUSYS_POWER_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_rv_mbox_mpu.h b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_mbox_mpu.h
new file mode 100644
index 0000000..7a5b212
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_mbox_mpu.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_MBOX_MPU_H
+#define APUSYS_RV_MBOX_MPU_H
+
+#define MPU_EN (0)
+#define MPU_DIS (1)
+#define MBOX0_TX_DOMAIN (0)
+#define MBOX0_TX_NS (1)
+#define MBOX1_TX_DOMAIN (11)
+#define MBOX1_TX_NS (1)
+#define MBOX3_TX_DOMAIN (3)
+#define MBOX3_TX_NS (0)
+#define MBOX4_RX_DOMAIN (0)
+#define MBOX4_RX_NS (0)
+#define MBOX5_TX_DOMAIN (8)
+#define MBOX5_TX_NS (0)
+#define MBOX6_TX_DOMAIN (4)
+#define MBOX6_TX_NS (1)
+#define MBOX7_RX_DOMAIN (0)
+#define MBOX7_RX_NS (0)
+#define MBOXN_RX_DOMAIN (5)
+#define MBOXN_RX_NS (0)
+#define MBOXN_TX_DOMAIN (0)
+#define MBOXN_TX_NS (0)
+
+struct mbox_mpu_setting {
+ uint32_t no_mpu;
+ uint32_t rx_ns;
+ uint32_t rx_domain;
+ uint32_t tx_ns;
+ uint32_t tx_domain;
+};
+
+static const struct mbox_mpu_setting mbox_mpu_setting_tab[] = {
+ /* no_mpu, rx_ns, rx_domain, tx_ns, tx_domain */
+ {MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX0_TX_NS, MBOX0_TX_DOMAIN},
+ {MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX1_TX_NS, MBOX1_TX_DOMAIN},
+ {MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN},
+ {MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX3_TX_NS, MBOX3_TX_DOMAIN},
+ {MPU_DIS, MBOX4_RX_NS, MBOX4_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN},
+ {MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX5_TX_NS, MBOX5_TX_DOMAIN},
+ {MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOX6_TX_NS, MBOX6_TX_DOMAIN},
+ {MPU_DIS, MBOX7_RX_NS, MBOX7_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN},
+ {MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN},
+ {MPU_EN, MBOXN_RX_NS, MBOXN_RX_DOMAIN, MBOXN_TX_NS, MBOXN_TX_DOMAIN},
+};
+
+#define APU_MBOX_NUM ARRAY_SIZE(mbox_mpu_setting_tab)
+
+#endif /* APUSYS_RV_MBOX_MPU_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.c b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.c
new file mode 100644
index 0000000..632af52
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "apusys_power.h"
+#include "apusys_rv.h"
+#include "apusys_rv_pwr_ctrl.h"
+
+#define RPC_POWER_OFF_TIMEOUT_CNT (100000) /* 100ms */
+
+static int wait_for_state_ready(uint32_t reg, uint32_t mask, uint32_t expect,
+ uint32_t retry_times, uint32_t set_reg, uint32_t set_val)
+{
+ uint32_t count = 0;
+
+ while ((mmio_read_32(reg) & mask) != expect) {
+ if (count > retry_times) {
+ ERROR("%s: timed out, reg = %x, mask = %x, expect = %x\n",
+ __func__, reg, mask, expect);
+ return -EBUSY;
+ }
+ count += 1;
+
+ if (set_reg)
+ mmio_write_32(set_reg, set_val);
+ udelay(1);
+ }
+
+ return 0;
+}
+
+int apu_hw_sema_ctl_per_mbox(uint32_t sem_ctrl_addr, uint32_t sem_sta_addr,
+ uint8_t usr_bit, enum apu_hw_sem_op ctl, uint32_t timeout,
+ uint8_t bypass)
+{
+ int ret;
+ uint8_t ctl_bit = 0;
+
+ if (ctl == HW_SEM_GET)
+ ctl_bit = 0x1;
+ else if (ctl == HW_SEM_PUT)
+ ctl_bit = 0x2;
+ else
+ return -EINVAL;
+
+ /* return fail if semaphore is currently not held by this user */
+ if (ctl == HW_SEM_PUT && ((mmio_read_32(sem_sta_addr) & BIT(usr_bit)) == 0)
+ && !bypass) {
+ ERROR("%s release error: usr_bit:%d ctl:%d (sem_addr(0x%08x) = 0x%08x)\n",
+ __func__, usr_bit, ctl, sem_sta_addr, mmio_read_32(sem_sta_addr));
+ return -EINVAL;
+ }
+
+ mmio_write_32(sem_ctrl_addr, ctl_bit);
+
+ if (ctl == HW_SEM_PUT)
+ return 0;
+
+ ret = wait_for_state_ready(sem_sta_addr, BIT(usr_bit), BIT(usr_bit), timeout,
+ sem_ctrl_addr, ctl_bit);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
+{
+ int ret;
+ uint32_t global_ref_cnt;
+
+ ret = apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_CTRL,
+ APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_STA,
+ APU_HW_SEM_SYS_APMCU, HW_SEM_GET, HW_SEM_TIMEOUT, 0);
+
+ if (ret) {
+ ERROR("%s(%d): sem acquire timeout\n", __func__, op);
+ return ret;
+ }
+
+ global_ref_cnt = mmio_read_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY);
+
+ if (global_ref_cnt > 2) {
+ ERROR("%s: global_ref_cnt(%d) > 2\n", __func__, global_ref_cnt);
+ } else if (op == APU_PWR_OFF) {
+ global_ref_cnt--;
+ mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, global_ref_cnt);
+ if (global_ref_cnt == 0)
+ mmio_write_32(APU_MBOX_WKUP_CFG(11), 0);
+ } else if (op == APU_PWR_ON) {
+ global_ref_cnt++;
+ mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, global_ref_cnt);
+ if (global_ref_cnt == 1)
+ mmio_write_32(APU_MBOX_WKUP_CFG(11), 1);
+ }
+
+ ret = apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_CTRL,
+ APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA0_STA,
+ APU_HW_SEM_SYS_APMCU, HW_SEM_PUT, HW_SEM_TIMEOUT, 0);
+
+ if (ret)
+ ERROR("%s(%d): sem release timeout\n", __func__, op);
+
+ return ret;
+}
+
+int rv_iommu_hw_sem_trylock(void)
+{
+ return apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_CTRL,
+ APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_STA,
+ APU_HW_SEM_SYS_APMCU, HW_SEM_GET, 0, 0);
+}
+
+int rv_iommu_hw_sem_unlock(void)
+{
+ return apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_CTRL,
+ APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_STA,
+ APU_HW_SEM_SYS_APMCU, HW_SEM_PUT, 0, 0);
+}
+
+int apu_hw_sema_ctl(uint32_t sem_addr, uint8_t usr_bit, uint8_t ctl, uint32_t timeout,
+ uint8_t bypass)
+{
+ int ret;
+ uint8_t ctl_bit = 0;
+
+ if (ctl == HW_SEM_GET)
+ ctl_bit = usr_bit;
+ else if (ctl == HW_SEM_PUT)
+ ctl_bit = usr_bit + HW_SEM_PUT_BIT_SHIFT;
+ else
+ return -EINVAL;
+
+ if (ctl == HW_SEM_PUT && ((mmio_read_32(sem_addr) & BIT(ctl_bit)) == 0) && !bypass) {
+ ERROR("%s release error: usr_bit:%d ctl:%d (sem_addr(0x%08x) = 0x%08x)\n",
+ __func__, usr_bit, ctl, sem_addr, mmio_read_32(sem_addr));
+ return -EINVAL;
+ }
+
+ mmio_write_32(sem_addr, BIT(ctl_bit));
+
+ if (ctl == HW_SEM_PUT)
+ goto end;
+
+ ret = wait_for_state_ready(sem_addr, BIT(ctl_bit), BIT(ctl_bit), timeout,
+ sem_addr, BIT(ctl_bit));
+ if (ret)
+ return ret;
+
+end:
+ VERBOSE("%s: sem_addr = 0x%x, usr_bit: %d, ctl: %d, sem_addr = 0x%08x\n",
+ __func__, sem_addr, usr_bit, ctl, mmio_read_32(sem_addr));
+
+ return 0;
+}
+
+int apusys_infra_dcm_setup(void)
+{
+ mmio_write_32(APU_REG_AO_GLUE_CONFG,
+ mmio_read_32(APU_REG_AO_GLUE_CONFG) | BIT(24) | BIT(26));
+
+ return 0;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.h b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.h
new file mode 100644
index 0000000..b5a48e2
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_PWR_CTL_H
+#define APUSYS_RV_PWR_CTL_H
+
+#include <platform_def.h>
+
+#include "apusys_rv.h"
+
+#define SUPPORT_APU_CLEAR_MBOX_DUMMY (1)
+
+enum apu_hw_sem_sys_id {
+ APU_HW_SEM_SYS_APU = 0UL, /* mbox0 */
+ APU_HW_SEM_SYS_GZ = 1UL, /* mbox1 */
+ APU_HW_SEM_SYS_SCP = 3UL, /* mbox3 */
+ APU_HW_SEM_SYS_APMCU = 11UL, /* mbox11 */
+};
+
+int apusys_rv_pwr_ctrl(enum APU_PWR_OP op);
+int rv_iommu_hw_sem_unlock(void);
+int rv_iommu_hw_sem_trylock(void);
+int apu_hw_sema_ctl(uint32_t sem_addr, uint8_t usr_bit, uint8_t ctl, uint32_t timeout,
+ uint8_t bypass);
+
+#define HW_SEM_TIMEOUT (300) /* 300 us */
+
+/* APU MBOX */
+#define MBOX_WKUP_CFG (0x80)
+#define MBOX_WKUP_MASK (0x84)
+#define MBOX_FUNC_CFG (0xb0)
+#define MBOX_DOMAIN_CFG (0xe0)
+
+#define MBOX_CTRL_LOCK BIT(0)
+#define MBOX_NO_MPU_SHIFT (16)
+#define MBOX_RC_SHIFT (24)
+
+#define MBOX_RX_NS_SHIFT (16)
+#define MBOX_RX_DOMAIN_SHIFT (17)
+#define MBOX_TX_NS_SHIFT (24)
+#define MBOX_TX_DOMAIN_SHIFT (25)
+
+#define APU_REG_AO_GLUE_CONFG (APU_AO_CTRL + 0x20)
+
+#define ENABLE_INFRA_WA
+
+enum apu_infra_bit_id {
+ APU_INFRA_SYS_APMCU = 1UL,
+ APU_INFRA_SYS_GZ = 2UL,
+ APU_INFRA_SYS_SCP = 3UL,
+};
+
+#define APU_MBOX(i) (APU_MBOX0 + 0x10000 * i)
+
+#define APU_MBOX_FUNC_CFG(i) (APU_MBOX(i) + MBOX_FUNC_CFG)
+#define APU_MBOX_DOMAIN_CFG(i) (APU_MBOX(i) + MBOX_DOMAIN_CFG)
+#define APU_MBOX_WKUP_CFG(i) (APU_MBOX(i) + MBOX_WKUP_CFG)
+
+enum apu_hw_sem_op {
+ HW_SEM_PUT = 0,
+ HW_SEM_GET = 1,
+};
+
+#define HW_SEM_PUT_BIT_SHIFT (16)
+
+/* bypass mbox register Dump for secure master */
+#define APU_MBOX_DBG_EN (0x190f2380)
+
+/* apu_mbox register definition for mbox addr change*/
+#define APU_MBOX_SEMA0_CTRL (0x090)
+#define APU_MBOX_SEMA0_RST (0x094)
+#define APU_MBOX_SEMA0_STA (0x098)
+#define APU_MBOX_SEMA1_CTRL (0x0A0)
+#define APU_MBOX_SEMA1_RST (0x0A4)
+#define APU_MBOX_SEMA1_STA (0x0A8)
+#define APU_MBOX_DUMMY (0x040)
+#define APU_MBOX_OFFSET(i) (0x10000 * i)
+
+/* apu infra workaround */
+#define APU_INFRA_DISABLE (APU_INFRA_BASE + 0xC18)
+#define APU_INFRA_ENABLE (APU_INFRA_BASE + 0xC14)
+#define APU_INFRA_STATUS (APU_INFRA_BASE + 0xC10)
+#define APU_INFRA_STATUS_MASK (0x1fffe)
+#define APU_INFRA_HW_SEM (APUSYS_CE_BASE + 0xE00)
+#define APU_RPC_STATUS (0x190f0044)
+
+#define APU_INFRA_BIT_OFF (16)
+#define APU_RPC_STATUS_BIT BIT(0)
+
+#endif /* APUSYS_RV_PWR_CTL_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.c b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.c
new file mode 100644
index 0000000..f6c8f58
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include "apusys_security_ctrl_perm.h"
+#include "apusys_security_ctrl_perm_plat.h"
+
+#define SEC_CTRL_APU_SEC_CON_BASE (0x190F5000)
+#define SEC_CTRL_RV_DOMAIN_OFS (0x60)
+#define SEC_CTRL_RV_NS_OFS (0x64)
+#define SEC_CTRL_RV_DOMAIN_SHF (4)
+#define SEC_CTRL_RV_NS_SHF (1)
+
+#define SEC_LEVEL_NORMAL_DOMAIN (7)
+#define SEC_LEVEL_NORMAL_NS (1)
+#define SEC_LEVEL_SAPU_DOMAIN (5)
+#define SEC_LEVEL_SAPU_NS (1)
+#define SEC_LEVEL_AOV_DOMAIN (14)
+#define SEC_LEVEL_AOV_NS (1)
+#define SEC_LEVEL_UP_SECURE_DOMAIN (5)
+#define SEC_LEVEL_UP_SECURE_NS (0)
+#define SEC_LEVEL_MVPU_SECURE_DOMAIN (7)
+#define SEC_LEVEL_MVPU_SECURE_NS (0)
+#define SEC_LEVEL_MDLA_SECURE_DOMAIN (14)
+#define SEC_LEVEL_MDLA_SECURE_NS (0)
+#define DOMAIN(SEC_LVL) SEC_LEVEL_##SEC_LVL##_DOMAIN
+#define NS(SEC_LVL) SEC_LEVEL_##SEC_LVL##_NS
+
+int sec_get_dns(enum apusys_dev_type dev_type, enum apusys_sec_level sec_level,
+ uint8_t *domain, uint8_t *ns)
+{
+ if ((dev_type < 0) || (dev_type >= APUSYS_DEVICE_NUM)) {
+ ERROR("invalid dev type %d\n", dev_type);
+ return -EINVAL;
+ }
+
+ if ((sec_level < 0) || (sec_level >= SEC_LEVEL_NUM)) {
+ ERROR("invalid sec_level %d\n", sec_level);
+ return -EINVAL;
+ }
+
+ switch (sec_level) {
+ case SEC_LEVEL_NORMAL:
+ *domain = DOMAIN(NORMAL);
+ *ns = NS(NORMAL);
+ break;
+ case SEC_LEVEL_SECURE:
+ switch (dev_type) {
+ case APUSYS_DEVICE_MVPU:
+ *domain = DOMAIN(MVPU_SECURE);
+ *ns = NS(MVPU_SECURE);
+ break;
+ case APUSYS_DEVICE_MDLA:
+ *domain = DOMAIN(MDLA_SECURE);
+ *ns = NS(MDLA_SECURE);
+ break;
+ case APUSYS_DEVICE_UP:
+ *domain = DOMAIN(UP_SECURE);
+ *ns = NS(UP_SECURE);
+ break;
+ default:
+ ERROR("invalid dev type %d\n", dev_type);
+ return -EINVAL;
+ };
+ break;
+ case SEC_LEVEL_SAPU:
+ *domain = DOMAIN(SAPU);
+ *ns = NS(SAPU);
+ break;
+ case SEC_LEVEL_AOV:
+ *domain = DOMAIN(AOV);
+ *ns = NS(AOV);
+ break;
+ default:
+ ERROR("invalid sec_level %d\n", sec_level);
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+int sec_set_rv_dns(void)
+{
+ uint8_t normal_domain;
+ uint8_t normal_ns;
+ uint8_t sec_domain;
+ uint8_t sec_ns;
+ int ret;
+
+ ret = sec_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_SECURE, &sec_domain, &sec_ns);
+ if (ret) {
+ ERROR("%s failed.\n", __func__);
+ return ret;
+ }
+
+ ret = sec_get_dns(APUSYS_DEVICE_UP, SEC_LEVEL_NORMAL, &normal_domain, &normal_ns);
+ if (ret) {
+ ERROR("%s failed.\n", __func__);
+ return ret;
+ }
+
+ mmio_write_32(SEC_CTRL_APU_SEC_CON_BASE + SEC_CTRL_RV_DOMAIN_OFS,
+ (sec_domain << SEC_CTRL_RV_DOMAIN_SHF) | normal_domain);
+ mmio_write_32(SEC_CTRL_APU_SEC_CON_BASE + SEC_CTRL_RV_NS_OFS,
+ (sec_ns << SEC_CTRL_RV_NS_SHF) | normal_ns);
+
+ return 0;
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.h b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.h
new file mode 100644
index 0000000..d57a536
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_perm_plat.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_SECURITY_CTRL_PERM_PLAT_H
+#define APUSYS_SECURITY_CTRL_PERM_PLAT_H
+
+enum apusys_dev_type {
+ APUSYS_DEVICE_MDLA,
+ APUSYS_DEVICE_EDPA,
+ APUSYS_DEVICE_MVPU,
+ APUSYS_DEVICE_UP,
+ APUSYS_DEVICE_NUM,
+};
+
+#endif /* APUSYS_SECURITY_CTRL_PERM_PLAT_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
new file mode 100644
index 0000000..fbd2aa0
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define ENABLE_SMPU_PROTECT (0)
+
+#if ENABLE_SMPU_PROTECT
+#include "emi.h"
+#include "mt_emi.h"
+#endif
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <apusys_security_ctrl_plat.h>
+
+#define APUSYS_SEC_FW_EMI_REGION (23)
+
+#define bits_clr(x, m, o) (x & (~(m << o)))
+#define bits_set(x, v, m, o) ((bits_clr(x, m, o)) | ((v & m) << o))
+
+static void sec_sideband_init(void)
+{
+ uint32_t value = mmio_read_32(SEC_CTRL_SIDE_BAND);
+
+ value = bits_set(value, SEC_CTRL_NARE_DOMAIN, SEC_CTRL_DOMAIN_MASK,
+ SEC_CTRL_NARE_DOMAIN_SHF);
+ value = bits_set(value, SEC_CTRL_NARE_NS, SEC_CTRL_NS_MASK, SEC_CTRL_NARE_NS_SHF);
+ value = bits_set(value, SEC_CTRL_SARE0_DOMAIN, SEC_CTRL_DOMAIN_MASK,
+ SEC_CTRL_SARE0_DOMAIN_SHF);
+ value = bits_set(value, SEC_CTRL_SARE0_NS, SEC_CTRL_NS_MASK, SEC_CTRL_SARE0_NS_SHF);
+ value = bits_set(value, SEC_CTRL_SARE1_DOMAIN, SEC_CTRL_DOMAIN_MASK,
+ SEC_CTRL_SARE1_DOMAIN_SHF);
+ value = bits_set(value, SEC_CTRL_SARE1_NS, SEC_CTRL_NS_MASK, SEC_CTRL_SARE1_NS_SHF);
+
+ mmio_write_32(SEC_CTRL_SIDE_BAND, value);
+}
+
+static void domain_remap_init(void)
+{
+ const uint32_t remap_domains[] = {
+ D0_REMAP_DOMAIN, D1_REMAP_DOMAIN, D2_REMAP_DOMAIN, D3_REMAP_DOMAIN,
+ D4_REMAP_DOMAIN, D5_REMAP_DOMAIN, D6_REMAP_DOMAIN, D7_REMAP_DOMAIN,
+ D8_REMAP_DOMAIN, D9_REMAP_DOMAIN, D10_REMAP_DOMAIN, D11_REMAP_DOMAIN,
+ D12_REMAP_DOMAIN, D13_REMAP_DOMAIN, D14_REMAP_DOMAIN, D15_REMAP_DOMAIN,
+ };
+ uint32_t lower_domain = 0;
+ uint32_t higher_domain = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(remap_domains); i++) {
+ if (i < SEC_CTRL_REG_DOMAIN_NUM)
+ lower_domain |= (remap_domains[i] << (i * REG_DOMAIN_BITS));
+ else
+ higher_domain |= (remap_domains[i] <<
+ ((i - SEC_CTRL_REG_DOMAIN_NUM) * REG_DOMAIN_BITS));
+ }
+
+ mmio_write_32(SEC_CTRL_SOC2APU_SET1_0, lower_domain);
+ mmio_write_32(SEC_CTRL_SOC2APU_SET1_1, higher_domain);
+ mmio_setbits_32(APU_SEC_CON, SEC_CTRL_DOMAIN_REMAP_SEL);
+}
+
+void apusys_security_ctrl_init(void)
+{
+ domain_remap_init();
+ sec_sideband_init();
+}
+
+int apusys_plat_setup_sec_mem(void)
+{
+#if ENABLE_SMPU_PROTECT
+ return sip_emi_mpu_set_protection(APU_RESERVE_MEMORY >> EMI_MPU_ALIGN_BITS,
+ (APU_RESERVE_MEMORY + APU_RESERVE_SIZE) >> EMI_MPU_ALIGN_BITS,
+ APUSYS_SEC_FW_EMI_REGION);
+#else
+ INFO("%s: Bypass SMPU protection setup.\n", __func__);
+ return 0;
+#endif
+}
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.h b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.h
new file mode 100644
index 0000000..5e69777
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_SECURITY_CTRL_PLAT_H
+#define APUSYS_SECURITY_CTRL_PLAT_H
+
+#include <lib/utils_def.h>
+#include <platform_def.h>
+
+#define SEC_CTRL_SOC2APU_SET1_0 (APU_SEC_CON + 0xC)
+#define SEC_CTRL_SOC2APU_SET1_1 (APU_SEC_CON + 0x10)
+#define SEC_CTRL_SIDE_BAND (APU_SEC_CON + 0x24)
+
+#define SEC_CTRL_REG_DOMAIN_NUM (8)
+#define SEC_CTRL_DOMAIN_REMAP_SEL BIT(6)
+#define SEC_CTRL_DOMAIN_MASK (0xF)
+#define SEC_CTRL_NS_MASK (0x1)
+
+#define SEC_CTRL_NARE_DOMAIN (5)
+#define SEC_CTRL_NARE_NS (0)
+#define SEC_CTRL_NARE_DOMAIN_SHF (0)
+#define SEC_CTRL_NARE_NS_SHF (4)
+
+#define SEC_CTRL_SARE0_DOMAIN (5)
+#define SEC_CTRL_SARE0_NS (0)
+#define SEC_CTRL_SARE0_DOMAIN_SHF (5)
+#define SEC_CTRL_SARE0_NS_SHF (9)
+
+#define SEC_CTRL_SARE1_DOMAIN (5)
+#define SEC_CTRL_SARE1_NS (0)
+#define SEC_CTRL_SARE1_DOMAIN_SHF (10)
+#define SEC_CTRL_SARE1_NS_SHF (14)
+
+#define REG_DOMAIN_BITS (4)
+
+#define D0_REMAP_DOMAIN (0)
+#define D1_REMAP_DOMAIN (1)
+#define D2_REMAP_DOMAIN (2)
+#define D3_REMAP_DOMAIN (3)
+#define D4_REMAP_DOMAIN (4)
+#define D5_REMAP_DOMAIN (6)
+#define D6_REMAP_DOMAIN (6)
+#define D7_REMAP_DOMAIN (6)
+#define D8_REMAP_DOMAIN (8)
+#define D9_REMAP_DOMAIN (9)
+#define D10_REMAP_DOMAIN (10)
+#define D11_REMAP_DOMAIN (11)
+#define D12_REMAP_DOMAIN (12)
+#define D13_REMAP_DOMAIN (13)
+#define D14_REMAP_DOMAIN (6)
+#define D15_REMAP_DOMAIN (15)
+
+void apusys_security_ctrl_init(void);
+int apusys_plat_setup_sec_mem(void);
+
+#endif /* APUSYS_SECURITY_CTRL_PLAT_H */
diff --git a/plat/mediatek/drivers/apusys/mt8196/rules.mk b/plat/mediatek/drivers/apusys/mt8196/rules.mk
new file mode 100644
index 0000000..4ffaf73
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/mt8196/rules.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := apusys_${MTK_SOC}
+
+ifeq (${CONFIG_MTK_APUSYS_EMI_SUPPORT}, y)
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/common
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/${MTK_SOC}
+endif
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_ammu.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_devapc.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_power.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_rv_pwr_ctrl.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_security_ctrl_plat.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_security_ctrl_perm_plat.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/apusys/rules.mk b/plat/mediatek/drivers/apusys/rules.mk
index 498925c..24cc79c 100644
--- a/plat/mediatek/drivers/apusys/rules.mk
+++ b/plat/mediatek/drivers/apusys/rules.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -12,10 +12,19 @@
PLAT_INCLUDES += -I${LOCAL_DIR} -I${LOCAL_DIR}/${MTK_SOC} -I${LOCAL_DIR}/apusys_rv/2.0
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_CE_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_EMI_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_LOGTOP_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_SEC_CTRL))
+
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
SUB_RULES-y := ${LOCAL_DIR}/${MTK_SOC}
SUB_RULES-y += ${LOCAL_DIR}/devapc
SUB_RULES-y += ${LOCAL_DIR}/apusys_rv/2.0
+SUB_RULES-${CONFIG_MTK_APUSYS_SEC_CTRL} += $(LOCAL_DIR)/security_ctrl
$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/apusys/security_ctrl/apusys_security_ctrl_perm.h b/plat/mediatek/drivers/apusys/security_ctrl/apusys_security_ctrl_perm.h
new file mode 100644
index 0000000..17ccacf
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/security_ctrl/apusys_security_ctrl_perm.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURITY_CTRL_PERM_H
+#define SECURITY_CTRL_PERM_H
+
+#include "apusys_security_ctrl_perm_plat.h"
+
+enum apusys_sec_level {
+ SEC_LEVEL_NORMAL,
+ SEC_LEVEL_SECURE,
+ SEC_LEVEL_SAPU,
+ SEC_LEVEL_AOV,
+ SEC_LEVEL_NUM,
+};
+
+int sec_set_rv_dns(void);
+int sec_get_dns(enum apusys_dev_type dev_type, enum apusys_sec_level sec_level,
+ uint8_t *domain, uint8_t *ns);
+
+#endif
diff --git a/plat/mediatek/drivers/apusys/security_ctrl/rules.mk b/plat/mediatek/drivers/apusys/security_ctrl/rules.mk
new file mode 100644
index 0000000..a7ed5c9
--- /dev/null
+++ b/plat/mediatek/drivers/apusys/security_ctrl/rules.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/apusys/security_ctrl
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/apusys/${MTK_SOC}
diff --git a/plat/mediatek/drivers/emi/common/emi.h b/plat/mediatek/drivers/emi/common/emi.h
new file mode 100644
index 0000000..eb2a0d3
--- /dev/null
+++ b/plat/mediatek/drivers/emi/common/emi.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EMI_H
+#define EMI_H
+
+#include <stdint.h>
+
+#define EMI_MPU_ALIGN_BITS 12
+
+uint64_t sip_emi_mpu_set_protection(u_register_t start, u_register_t end, u_register_t region);
+
+#endif /* EMI_H */
diff --git a/plat/mediatek/drivers/emi/emi_stub.c b/plat/mediatek/drivers/emi/emi_stub.c
new file mode 100644
index 0000000..3682bf7
--- /dev/null
+++ b/plat/mediatek/drivers/emi/emi_stub.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <common/debug.h>
+
+#include "common/emi.h"
+#include <mtk_sip_svc.h>
+
+uint64_t sip_emi_mpu_set_protection(u_register_t start, u_register_t end,
+ u_register_t region)
+{
+ return MTK_SIP_E_NOT_SUPPORTED;
+}
diff --git a/plat/mediatek/drivers/emi/rules.mk b/plat/mediatek/drivers/emi/rules.mk
new file mode 100644
index 0000000..9f462bb
--- /dev/null
+++ b/plat/mediatek/drivers/emi/rules.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := emi
+
+ifeq ($(MTKLIB_PATH),)
+LOCAL_SRCS-y := $(LOCAL_DIR)/emi_stub.c
+endif
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/gpio/mtgpio_common.h b/plat/mediatek/drivers/gpio/mtgpio_common.h
index d6b858c..a93a065 100644
--- a/plat/mediatek/drivers/gpio/mtgpio_common.h
+++ b/plat/mediatek/drivers/gpio/mtgpio_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2024, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -97,7 +97,7 @@
}
struct mt_pin_info {
- uint8_t id;
+ uint16_t id;
uint8_t flag;
uint8_t bit;
uint16_t base;
diff --git a/plat/mediatek/drivers/vcp/mt8196/vcp_helper.h b/plat/mediatek/drivers/vcp/mt8196/vcp_helper.h
new file mode 100644
index 0000000..3d87d40
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/mt8196/vcp_helper.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VCP_HELPER_H
+#define VCP_HELPER_H
+
+#define MTK_VCP_SRAM_SIZE (0x60000)
+
+/* Export extern API */
+uint32_t get_mmup_fw_size(void);
+uint64_t get_mmup_l2tcm_offset(void);
+
+/* SMC calls OPS */
+enum mtk_tinysys_vcp_kernel_op {
+ MTK_TINYSYS_VCP_KERNEL_OP_RESET_SET = 0,
+ MTK_TINYSYS_VCP_KERNEL_OP_RESET_RELEASE,
+ MTK_TINYSYS_VCP_KERNEL_OP_COLD_BOOT_VCP,
+ MTK_TINYSYS_MMUP_KERNEL_OP_RESET_SET,
+ MTK_TINYSYS_MMUP_KERNEL_OP_RESET_RELEASE,
+ MTK_TINYSYS_MMUP_KERNEL_OP_SET_L2TCM_OFFSET,
+ MTK_TINYSYS_MMUP_KERNEL_OP_SET_FW_SIZE,
+ MTK_TINYSYS_MMUP_KERNEL_OP_COLD_BOOT_MMUP,
+ MTK_TINYSYS_VCP_KERNEL_OP_NUM,
+};
+
+#endif /* VCP_HELPER_H */
diff --git a/plat/mediatek/drivers/vcp/mt8196/vcp_reg.h b/plat/mediatek/drivers/vcp/mt8196/vcp_reg.h
new file mode 100644
index 0000000..4aa8332
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/mt8196/vcp_reg.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VCP_REG_H
+#define VCP_REG_H
+
+#include <platform_def.h>
+
+#define MTK_VCP_REG_BASE (IO_PHYS + 0x21800000)
+#define MTK_VCP_REG_BANK_SIZE (0x1000)
+
+/*******************************************************************************
+ * VCP power related setting
+ ******************************************************************************/
+#define VCP_POWER_STATUS (0xE60)
+#define MMUP_PWR_STA_BIT (30)
+#define MMUP_PWR_STA_EN ((uint32_t)(0x3))
+
+/*******************************************************************************
+ * VCP registers
+ ******************************************************************************/
+/* cfgreg */
+#define VCP_R_CFGREG (MTK_VCP_REG_BASE + 0x3d0000)
+
+#define VCP_R_CORE0_SW_RSTN_CLR (VCP_R_CFGREG + 0x0000)
+#define VCP_R_CORE0_SW_RSTN_SET (VCP_R_CFGREG + 0x0004)
+#define VCP_R_CORE1_SW_RSTN_CLR (VCP_R_CFGREG + 0x0008)
+#define VCP_R_CORE1_SW_RSTN_SET (VCP_R_CFGREG + 0x000c)
+#define VCP_R_GIPC_IN_SET (VCP_R_CFGREG + 0x0028)
+#define VCP_R_GIPC_IN_CLR (VCP_R_CFGREG + 0x002c)
+#define B_GIPC3_SETCLR_1 BIT(13)
+
+/* cfgreg_core0 */
+#define VCP_R_CFGREG_CORE0 (MTK_VCP_REG_BASE + 0x20a000)
+
+#define VCP_R_CORE0_STATUS (VCP_R_CFGREG_CORE0 + 0x0070)
+
+#define CORE0_R_GPR5 (VCP_R_CFGREG_CORE0 + 0x0054)
+#define VCP_GPR_C0_H0_REBOOT CORE0_R_GPR5
+#define CORE0_R_GPR6 (VCP_R_CFGREG_CORE0 + 0x0058)
+#define VCP_GPR_C0_H1_REBOOT CORE0_R_GPR6
+#define VCP_CORE_RDY_TO_REBOOT (0x34)
+#define VCP_CORE_REBOOT_OK BIT(0)
+
+/* cfgreg_core1 */
+#define VCP_R_CFGREG_CORE1 (MTK_VCP_REG_BASE + 0x20d000)
+
+#define VCP_R_CORE1_STATUS (VCP_R_CFGREG_CORE1 + 0x0070)
+#define CORE1_R_GPR5 (VCP_R_CFGREG_CORE1 + 0x0054)
+#define VCP_GPR_CORE1_REBOOT CORE1_R_GPR5
+
+/* sec */
+#define VCP_R_SEC_CTRL (MTK_VCP_REG_BASE + 0x270000)
+#define VCP_OFFSET_ENABLE_P BIT(13)
+#define VCP_OFFSET_ENABLE_B BIT(12)
+#define VCP_R_SEC_CTRL_2 (VCP_R_SEC_CTRL + 0x0004)
+#define CORE0_SEC_BIT_SEL BIT(0)
+#define CORE1_SEC_BIT_SEL BIT(8)
+#define VCP_GPR0_CFGREG_SEC (VCP_R_SEC_CTRL + 0x0040)
+#define VCP_GPR1_CFGREG_SEC (VCP_R_SEC_CTRL + 0x0044)
+#define VCP_GPR2_CFGREG_SEC (VCP_R_SEC_CTRL + 0x0048)
+#define VCP_GPR3_CFGREG_SEC (VCP_R_SEC_CTRL + 0x004C)
+#define VCP_R_SEC_DOMAIN (VCP_R_SEC_CTRL + 0x0080)
+#define VCP_DOMAIN_ID U(13)
+#define VCP_DOMAIN_MASK U(0xF)
+#define VCP_CORE0_TH0_PM_AXI_DOMAIN (0)
+#define VCP_CORE0_TH0_DM_AXI_DOMAIN (4)
+#define VCP_S_DMA0_DOMAIN (12)
+#define VCP_HWCCF_DOMAIN (16)
+#define VCP_CORE0_TH1_PM_AXI_DOMAIN (20)
+#define VCP_CORE0_TH1_DM_AXI_DOMAIN (24)
+#define VCP_DOMAIN_SET ((VCP_DOMAIN_ID << VCP_CORE0_TH0_PM_AXI_DOMAIN) | \
+ (VCP_DOMAIN_ID << VCP_CORE0_TH0_DM_AXI_DOMAIN) | \
+ (VCP_DOMAIN_ID << VCP_CORE0_TH1_PM_AXI_DOMAIN) | \
+ (VCP_DOMAIN_ID << VCP_CORE0_TH1_DM_AXI_DOMAIN) | \
+ (VCP_DOMAIN_ID << VCP_S_DMA0_DOMAIN))
+#define VCP_R_SEC_DOMAIN_MMPC (VCP_R_SEC_CTRL + 0x0084)
+#define VCP_CORE_MMPC_PM_AXI_DOMAIN (0)
+#define VCP_CORE_MMPC_DM_AXI_DOMAIN (4)
+#define VCP_DOMAIN_SET_MMPC ((VCP_DOMAIN_ID << VCP_CORE_MMPC_PM_AXI_DOMAIN) | \
+ (VCP_DOMAIN_ID << VCP_CORE_MMPC_DM_AXI_DOMAIN))
+#define R_L2TCM_OFFSET_RANGE_0_LOW (VCP_R_SEC_CTRL + 0x00B0)
+#define R_L2TCM_OFFSET_RANGE_0_HIGH (VCP_R_SEC_CTRL + 0x00B4)
+#define R_L2TCM_OFFSET (VCP_R_SEC_CTRL + 0x00D0)
+#define VCP_R_DYN_SECURE (VCP_R_SEC_CTRL + 0x01d0)
+#define VCP_NS_I0 BIT(4)
+#define VCP_NS_D0 BIT(6)
+#define VCP_NS_SECURE_B_REGION_ENABLE (24)
+#define RESET_NS_SECURE_B_REGION U(0xFF)
+#define VCP_R_DYN_SECURE_TH1 (VCP_R_SEC_CTRL + 0x01d4)
+#define VCP_NS_I1 BIT(5)
+#define VCP_NS_D1 BIT(7)
+#define VCP_R_S_DOM_EN0_31 (VCP_R_SEC_CTRL + 0x0200)
+#define VCP_R_S_DOM_EN32_63 (VCP_R_SEC_CTRL + 0x0204)
+#define VCP_R_NS_DOM_EN0_31 (VCP_R_SEC_CTRL + 0x0208)
+#define VCP_R_NS_DOM_EN32_63 (VCP_R_SEC_CTRL + 0x020c)
+/* IOMMU */
+#define VCP_R_AXIOMMUEN_DEV_APC (VCP_R_SEC_CTRL + 0x0088)
+#define VCP_R_CFG_DEVAPC_AO_BASE (MTK_VCP_REG_BASE + 0x2d0000)
+
+#endif /* VCP_REG_H */
diff --git a/plat/mediatek/drivers/vcp/rules.mk b/plat/mediatek/drivers/vcp/rules.mk
new file mode 100644
index 0000000..9e342de
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rules.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := vcp
+
+SUB_RULES-y := $(LOCAL_DIR)/rv
+
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/vcp/rv/mmup_common.c b/plat/mediatek/drivers/vcp/rv/mmup_common.c
new file mode 100644
index 0000000..a6d0819
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/mmup_common.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <inttypes.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include "mmup_common.h"
+#include "vcp_helper.h"
+#include "vcp_reg.h"
+
+#define MODULE_TAG "[MMUP]"
+
+bool mmup_smc_rstn_set(bool boot_ok)
+{
+ if (mmio_read_32(VCP_GPR_CORE1_REBOOT) != 0 &&
+ mmio_read_32(VCP_R_CORE1_STATUS) != 0 &&
+ (mmio_read_32(VCP_R_GIPC_IN_SET) & B_GIPC3_SETCLR_1) == 0 &&
+ (mmio_read_32(VCP_R_GIPC_IN_CLR) & B_GIPC3_SETCLR_1) == 0 &&
+ mmio_read_32(VCP_GPR_CORE1_REBOOT) != VCP_CORE_RDY_TO_REBOOT) {
+ ERROR("%s: [%s] mmup reset set fail!GIPC 0x%x 0x%x REBOOT 0x%x\n",
+ MODULE_TAG, __func__, mmio_read_32(VCP_R_GIPC_IN_SET),
+ mmio_read_32(VCP_R_GIPC_IN_CLR),
+ mmio_read_32(VCP_GPR_CORE1_REBOOT));
+ return false;
+ }
+
+ mmio_write_32(VCP_R_CORE1_SW_RSTN_SET, BIT(0));
+
+ /* reset sec control */
+ mmio_write_32(VCP_R_SEC_CTRL_2, 0);
+
+ /* reset domain setting */
+ mmio_write_32(VCP_R_S_DOM_EN0_31, 0x0);
+ mmio_write_32(VCP_R_S_DOM_EN32_63, 0x0);
+ mmio_write_32(VCP_R_NS_DOM_EN0_31, 0x0);
+ mmio_write_32(VCP_R_NS_DOM_EN32_63, 0x0);
+
+ /* reset sec setting */
+ mmio_clrbits_32(VCP_R_DYN_SECURE,
+ RESET_NS_SECURE_B_REGION << VCP_NS_SECURE_B_REGION_ENABLE);
+
+ if (boot_ok)
+ mmio_write_32(VCP_GPR_CORE1_REBOOT, VCP_CORE_REBOOT_OK);
+
+ dsbsy();
+ return true;
+}
+
+bool mmup_smc_rstn_clr(void)
+{
+ if ((mmio_read_32(VCP_R_CORE1_SW_RSTN_SET) & BIT(0)) == 1) {
+ ERROR("%s: [%s] mmup not reset set !\n", MODULE_TAG, __func__);
+ return false;
+ }
+
+ if ((get_mmup_fw_size() == 0) || get_mmup_l2tcm_offset() == 0) {
+ ERROR("%s: [%s] mmup no enough l2tcm to run !\n", MODULE_TAG, __func__);
+ return false;
+ }
+
+ mmio_write_32(VCP_R_SEC_DOMAIN_MMPC, VCP_DOMAIN_SET_MMPC);
+
+ /* enable IOVA Mode */
+ mmio_write_32(VCP_R_AXIOMMUEN_DEV_APC, BIT(0));
+
+ /* reset secure setting */
+ mmio_setbits_32(VCP_R_SEC_CTRL_2, CORE1_SEC_BIT_SEL);
+
+ /* l2tcm offset*/
+ mmio_setbits_32(VCP_R_SEC_CTRL, VCP_OFFSET_ENABLE_P | VCP_OFFSET_ENABLE_B);
+ mmio_write_32(R_L2TCM_OFFSET_RANGE_0_LOW, 0x0);
+ mmio_write_32(R_L2TCM_OFFSET_RANGE_0_HIGH, round_up(get_mmup_fw_size(), PAGE_SIZE));
+ mmio_write_32(R_L2TCM_OFFSET, get_mmup_l2tcm_offset());
+
+ /* start vcp-mmup */
+ mmio_write_32(VCP_R_CORE1_SW_RSTN_CLR, BIT(0));
+ dsbsy();
+ return true;
+}
diff --git a/plat/mediatek/drivers/vcp/rv/mmup_common.h b/plat/mediatek/drivers/vcp/rv/mmup_common.h
new file mode 100644
index 0000000..e70d25f
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/mmup_common.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MMUP_COMMON_H
+#define MMUP_COMMON_H
+
+bool mmup_smc_rstn_set(bool boot_ok);
+bool mmup_smc_rstn_clr(void);
+
+#endif /* MMUP_COMMON_H */
diff --git a/plat/mediatek/drivers/vcp/rv/rules.mk b/plat/mediatek/drivers/vcp/rv/rules.mk
new file mode 100644
index 0000000..e637067
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/rules.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := vcp_rv_${MTK_SOC}
+
+PLAT_INCLUDES += -I${MTK_PLAT}/drivers/vcp/${MTK_SOC}
+
+LOCAL_SRCS-${CONFIG_MTK_TINYSYS_VCP} := ${LOCAL_DIR}/vcp_common.c
+LOCAL_SRCS-${CONFIG_MTK_TINYSYS_VCP} += ${LOCAL_DIR}/mmup_common.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/vcp/rv/vcp_common.c b/plat/mediatek/drivers/vcp/rv/vcp_common.c
new file mode 100644
index 0000000..9dfb133
--- /dev/null
+++ b/plat/mediatek/drivers/vcp/rv/vcp_common.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <smccc_helpers.h>
+
+#include "mmup_common.h"
+#include <mtk_mmap_pool.h>
+#include <mtk_sip_svc.h>
+#include "vcp_helper.h"
+#include "vcp_reg.h"
+
+#define MODULE_TAG "[VCP]"
+
+static const mmap_region_t vcp_mmap[] MTK_MMAP_SECTION = {
+ MAP_REGION_FLAT(VCP_R_CFGREG, MTK_VCP_REG_BANK_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(VCP_R_CFGREG_CORE0, MTK_VCP_REG_BANK_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(VCP_R_CFGREG_CORE1, MTK_VCP_REG_BANK_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(VCP_R_SEC_CTRL, MTK_VCP_REG_BANK_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ {0}
+};
+DECLARE_MTK_MMAP_REGIONS(vcp_mmap);
+
+/* vcp-mmup l2tcm memory offset */
+static uint64_t g_l2tcm_offset;
+static uint32_t g_mmup_fw_size;
+
+static bool get_vcp_pwr_status(void)
+{
+#if defined(SPM_BASE)
+ uint32_t spm_pwr_sta = mmio_read_32(SPM_BASE + VCP_POWER_STATUS);
+
+ if (!(spm_pwr_sta & (MMUP_PWR_STA_EN << MMUP_PWR_STA_BIT))) {
+ ERROR("%s: pwr_sta:%x, bit:%d disable\n", MODULE_TAG,
+ spm_pwr_sta, MMUP_PWR_STA_BIT);
+ return false;
+ }
+#endif
+ return true;
+}
+
+uint32_t get_mmup_fw_size(void)
+{
+ return g_mmup_fw_size;
+}
+
+uint64_t get_mmup_l2tcm_offset(void)
+{
+ return g_l2tcm_offset;
+}
+
+static bool vcp_cold_boot_reset(void)
+{
+ mmio_write_32(VCP_GPR2_CFGREG_SEC, 0);
+ mmio_write_32(VCP_GPR3_CFGREG_SEC, 0);
+
+ return true;
+}
+
+static bool mmup_cold_boot_reset(void)
+{
+ mmio_write_32(VCP_GPR0_CFGREG_SEC, 0);
+ mmio_write_32(VCP_GPR1_CFGREG_SEC, 0);
+
+ return true;
+}
+
+static bool vcp_set_mmup_l2tcm_offset(uint64_t l2tcm_offset)
+{
+ g_l2tcm_offset = l2tcm_offset;
+
+ if (g_l2tcm_offset > MTK_VCP_SRAM_SIZE) {
+ g_l2tcm_offset = 0;
+ return false;
+ }
+
+ return true;
+}
+
+static bool vcp_set_mmup_fw_size(uint64_t fw_size)
+{
+ g_mmup_fw_size = fw_size;
+
+ if (g_mmup_fw_size > MTK_VCP_SRAM_SIZE - g_l2tcm_offset) {
+ g_mmup_fw_size = 0;
+ return false;
+ }
+
+ return true;
+}
+
+static bool vcp_smc_rstn_set(bool boot_ok)
+{
+ if (mmio_read_32(VCP_GPR_C0_H0_REBOOT) != 0 &&
+ mmio_read_32(VCP_R_CORE0_STATUS) != 0 &&
+ (mmio_read_32(VCP_R_GIPC_IN_SET) & B_GIPC3_SETCLR_1) == 0 &&
+ (mmio_read_32(VCP_R_GIPC_IN_CLR) & B_GIPC3_SETCLR_1) == 0 &&
+ mmio_read_32(VCP_GPR_C0_H0_REBOOT) != VCP_CORE_RDY_TO_REBOOT &&
+ mmio_read_32(VCP_GPR_C0_H1_REBOOT) != VCP_CORE_RDY_TO_REBOOT) {
+ ERROR("%s: [%s] mmup reset set fail!GIPC 0x%x 0x%x REBOOT 0x%x 0x%x\n",
+ MODULE_TAG, __func__, mmio_read_32(VCP_R_GIPC_IN_SET),
+ mmio_read_32(VCP_R_GIPC_IN_CLR),
+ mmio_read_32(VCP_GPR_C0_H0_REBOOT),
+ mmio_read_32(VCP_GPR_C0_H1_REBOOT));
+ return false;
+ }
+
+ mmio_write_32(VCP_R_CORE0_SW_RSTN_SET, BIT(0));
+
+ /* reset sec control */
+ mmio_write_32(VCP_R_SEC_CTRL_2, 0);
+
+ /* reset domain setting */
+ mmio_write_32(VCP_R_S_DOM_EN0_31, 0x0);
+ mmio_write_32(VCP_R_S_DOM_EN32_63, 0x0);
+ mmio_write_32(VCP_R_NS_DOM_EN0_31, 0x0);
+ mmio_write_32(VCP_R_NS_DOM_EN32_63, 0x0);
+
+ /* reset sec setting */
+ mmio_clrbits_32(VCP_R_DYN_SECURE,
+ RESET_NS_SECURE_B_REGION << VCP_NS_SECURE_B_REGION_ENABLE);
+
+ if (boot_ok) {
+ mmio_write_32(VCP_GPR_C0_H0_REBOOT, VCP_CORE_REBOOT_OK);
+ mmio_write_32(VCP_GPR_C0_H1_REBOOT, VCP_CORE_REBOOT_OK);
+ }
+
+ dsbsy();
+ return true;
+}
+
+static bool vcp_smc_rstn_clr(void)
+{
+ if ((mmio_read_32(VCP_R_CORE0_SW_RSTN_SET) & BIT(0)) == 1) {
+ ERROR("%s: [%s] mmup not reset set !\n", MODULE_TAG, __func__);
+ return false;
+ }
+
+ mmio_clrsetbits_32(VCP_R_SEC_DOMAIN,
+ ~(VCP_DOMAIN_MASK << VCP_HWCCF_DOMAIN), VCP_DOMAIN_SET);
+
+ /* enable IOVA Mode */
+ mmio_write_32(VCP_R_AXIOMMUEN_DEV_APC, BIT(0));
+
+ /* reset secure setting */
+ mmio_setbits_32(VCP_R_SEC_CTRL_2, CORE0_SEC_BIT_SEL);
+ mmio_clrbits_32(VCP_R_DYN_SECURE, VCP_NS_I0 | VCP_NS_D0);
+ mmio_clrbits_32(VCP_R_DYN_SECURE_TH1, VCP_NS_I1 | VCP_NS_D1);
+
+ /* start vcp */
+ mmio_write_32(VCP_R_CORE0_SW_RSTN_CLR, BIT(0));
+ dsbsy();
+ return true;
+}
+
+static u_register_t tinysys_vcp_kernel_control(u_register_t arg0,
+ u_register_t arg1,
+ u_register_t arg2,
+ u_register_t arg3,
+ void *handle,
+ struct smccc_res *smccc_ret)
+{
+ uint32_t request_ops;
+ uint64_t ret = MTK_SIP_E_SUCCESS;
+
+ if (!get_vcp_pwr_status())
+ return MTK_SIP_E_NOT_SUPPORTED;
+
+ request_ops = (uint32_t)arg0;
+
+ switch (request_ops) {
+ case MTK_TINYSYS_VCP_KERNEL_OP_RESET_SET:
+ ret = vcp_smc_rstn_set((bool)!!arg1);
+ break;
+ case MTK_TINYSYS_VCP_KERNEL_OP_RESET_RELEASE:
+ ret = vcp_smc_rstn_clr();
+ break;
+ case MTK_TINYSYS_VCP_KERNEL_OP_COLD_BOOT_VCP:
+ ret = vcp_cold_boot_reset();
+ break;
+ case MTK_TINYSYS_MMUP_KERNEL_OP_RESET_SET:
+ ret = mmup_smc_rstn_set((bool)!!arg1);
+ break;
+ case MTK_TINYSYS_MMUP_KERNEL_OP_RESET_RELEASE:
+ ret = mmup_smc_rstn_clr();
+ break;
+ case MTK_TINYSYS_MMUP_KERNEL_OP_SET_L2TCM_OFFSET:
+ ret = vcp_set_mmup_l2tcm_offset(arg1);
+ break;
+ case MTK_TINYSYS_MMUP_KERNEL_OP_SET_FW_SIZE:
+ ret = vcp_set_mmup_fw_size(arg1);
+ break;
+ case MTK_TINYSYS_MMUP_KERNEL_OP_COLD_BOOT_MMUP:
+ ret = mmup_cold_boot_reset();
+ break;
+ default:
+ ERROR("%s: %s, unknown request_ops = %x\n", MODULE_TAG, __func__, request_ops);
+ ret = MTK_SIP_E_INVALID_PARAM;
+ break;
+ }
+
+ return ret;
+}
+
+/* Register SiP SMC service */
+DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_VCP_CONTROL, tinysys_vcp_kernel_control);
diff --git a/plat/mediatek/include/drivers/apusys_rv_public.h b/plat/mediatek/include/drivers/apusys_rv_public.h
new file mode 100644
index 0000000..485453f
--- /dev/null
+++ b/plat/mediatek/include/drivers/apusys_rv_public.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef APUSYS_RV_PUBLIC_H
+#define APUSYS_RV_PUBLIC_H
+
+#ifdef CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT
+int apusys_rv_iommu_hw_sem_trylock(void);
+int apusys_rv_iommu_hw_sem_unlock(void);
+#else
+#define apusys_rv_iommu_hw_sem_trylock() 0
+#define apusys_rv_iommu_hw_sem_unlock() 0
+#endif /* CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT */
+
+#endif /* APUSYS_RV_PUBLIC_H */
diff --git a/plat/mediatek/include/mtk_sip_def.h b/plat/mediatek/include/mtk_sip_def.h
index a86a46c..6f496d2 100644
--- a/plat/mediatek/include/mtk_sip_def.h
+++ b/plat/mediatek/include/mtk_sip_def.h
@@ -13,16 +13,20 @@
_func(MTK_SIP_KERNEL_DFD, 0x205) \
_func(MTK_SIP_KERNEL_MSDC, 0x273) \
_func(MTK_SIP_VCORE_CONTROL, 0x506) \
+ _func(MTK_SIP_EMIDBG_CONTROL, 0x50B) \
_func(MTK_SIP_IOMMU_CONTROL, 0x514) \
_func(MTK_SIP_AUDIO_CONTROL, 0x517) \
_func(MTK_SIP_APUSYS_CONTROL, 0x51E) \
_func(MTK_SIP_DP_CONTROL, 0x523) \
- _func(MTK_SIP_KERNEL_GIC_OP, 0x526)
+ _func(MTK_SIP_KERNEL_GIC_OP, 0x526) \
+ _func(MTK_SIP_KERNEL_VCP_CONTROL, 0x52C)
#define MTK_SIP_SMC_FROM_S_EL1_TABLE(_func) \
- _func(MTK_SIP_TEE_MPU_PERM_SET, 0x031)
+ _func(MTK_SIP_TEE_MPU_PERM_SET, 0x031) \
+ _func(MTK_SIP_TEE_EMI_MPU_CONTROL, 0x048)
#define MTK_SIP_SMC_FROM_BL33_TABLE(_func) \
- _func(MTK_SIP_KERNEL_BOOT, 0x115)
+ _func(MTK_SIP_KERNEL_BOOT, 0x115) \
+ _func(MTK_SIP_BL_EMIMPU_CONTROL, 0x415)
#endif /* MTK_SIP_DEF_H */
diff --git a/plat/mediatek/mt8186/drivers/mcdi/mt_cpu_pm.c b/plat/mediatek/mt8186/drivers/mcdi/mt_cpu_pm.c
index 8c012e7..9eb348e 100644
--- a/plat/mediatek/mt8186/drivers/mcdi/mt_cpu_pm.c
+++ b/plat/mediatek/mt8186/drivers/mcdi/mt_cpu_pm.c
@@ -18,8 +18,6 @@
#include <plat_mtk_lpm.h>
#include <plat_pm.h>
-DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1);
-
static int plat_mt_lp_cpu_rc;
static int pwr_state_prompt(unsigned int cpu, const psci_power_state_t *state)
diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c
index b483c36..1df75f7 100644
--- a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c
+++ b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c
@@ -18,8 +18,6 @@
#include <plat_mtk_lpm.h>
#include <plat_pm.h>
-DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1);
-
static int plat_mt_lp_cpu_rc;
static int pwr_state_prompt(unsigned int cpu, const psci_power_state_t *state)
diff --git a/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c b/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c
index 5a80d95..d32a7df 100644
--- a/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c
+++ b/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c
@@ -18,8 +18,6 @@
#include <plat_mtk_lpm.h>
#include <plat_pm.h>
-DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1);
-
static int plat_mt_lp_cpu_rc;
static int pwr_state_prompt(unsigned int cpu, const psci_power_state_t *state)
diff --git a/plat/mediatek/mt8196/drivers/gpio/mtgpio.c b/plat/mediatek/mt8196/drivers/gpio/mtgpio.c
new file mode 100644
index 0000000..6257159
--- /dev/null
+++ b/plat/mediatek/mt8196/drivers/gpio/mtgpio.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <platform_def.h>
+#include <mtgpio.h>
+
+typedef enum {
+ REG_0 = 0,
+ REG_1,
+ REG_2,
+ REG_3,
+ REG_4,
+ REG_5,
+ REG_6,
+ REG_7,
+ REG_8,
+ REG_9,
+ REG_10,
+ REG_11,
+ REG_12,
+ REG_13,
+ REG_14
+} RegEnum;
+
+uintptr_t mt_gpio_find_reg_addr(uint32_t pin)
+{
+ uintptr_t reg_addr = 0U;
+ struct mt_pin_info gpio_info;
+
+ assert(pin < MAX_GPIO_PIN);
+
+ gpio_info = mt_pin_infos[pin];
+
+ switch (gpio_info.base & 0xF) {
+ case REG_0:
+ reg_addr = IOCFG_RT_BASE;
+ break;
+ case REG_1:
+ reg_addr = IOCFG_RM1_BASE;
+ break;
+ case REG_2:
+ reg_addr = IOCFG_RM2_BASE;
+ break;
+ case REG_3:
+ reg_addr = IOCFG_RB_BASE;
+ break;
+ case REG_4:
+ reg_addr = IOCFG_BM1_BASE;
+ break;
+ case REG_5:
+ reg_addr = IOCFG_BM2_BASE;
+ break;
+ case REG_6:
+ reg_addr = IOCFG_BM3_BASE;
+ break;
+ case REG_7:
+ reg_addr = IOCFG_LT_BASE;
+ break;
+ case REG_8:
+ reg_addr = IOCFG_LM1_BASE;
+ break;
+ case REG_9:
+ reg_addr = IOCFG_LM2_BASE;
+ break;
+ case REG_10:
+ reg_addr = IOCFG_LB1_BASE;
+ break;
+ case REG_11:
+ reg_addr = IOCFG_LB2_BASE;
+ break;
+ case REG_12:
+ reg_addr = IOCFG_TM1_BASE;
+ break;
+ case REG_13:
+ reg_addr = IOCFG_TM2_BASE;
+ break;
+ case REG_14:
+ reg_addr = IOCFG_TM3_BASE;
+ break;
+ default:
+ break;
+ }
+
+ return reg_addr;
+}
diff --git a/plat/mediatek/mt8196/drivers/gpio/mtgpio.h b/plat/mediatek/mt8196/drivers/gpio/mtgpio.h
new file mode 100644
index 0000000..a33bdad
--- /dev/null
+++ b/plat/mediatek/mt8196/drivers/gpio/mtgpio.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_GPIO_H
+#define MT_GPIO_H
+
+#include <mtgpio_common.h>
+
+/* Enumeration for GPIO pin */
+typedef enum GPIO_PIN {
+ GPIO_UNSUPPORTED = -1,
+ GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6,
+ GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, GPIO14,
+ GPIO15, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22,
+ GPIO23, GPIO24, GPIO25, GPIO26, GPIO27, GPIO28, GPIO29, GPIO30,
+ GPIO31, GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, GPIO37, GPIO38,
+ GPIO39, GPIO40, GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46,
+ GPIO47, GPIO48, GPIO49, GPIO50, GPIO51, GPIO52, GPIO53, GPIO54,
+ GPIO55, GPIO56, GPIO57, GPIO58, GPIO59, GPIO60, GPIO61, GPIO62,
+ GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70,
+ GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78,
+ GPIO79, GPIO80, GPIO81, GPIO82, GPIO83, GPIO84, GPIO85, GPIO86,
+ GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94,
+ GPIO95, GPIO96, GPIO97, GPIO98, GPIO99, GPIO100, GPIO101, GPIO102,
+ GPIO103, GPIO104, GPIO105, GPIO106, GPIO107, GPIO108, GPIO109, GPIO110,
+ GPIO111, GPIO112, GPIO113, GPIO114, GPIO115, GPIO116, GPIO117, GPIO118,
+ GPIO119, GPIO120, GPIO121, GPIO122, GPIO123, GPIO124, GPIO125, GPIO126,
+ GPIO127, GPIO128, GPIO129, GPIO130, GPIO131, GPIO132, GPIO133, GPIO134,
+ GPIO135, GPIO136, GPIO137, GPIO138, GPIO139, GPIO140, GPIO141, GPIO142,
+ GPIO143, GPIO144, GPIO145, GPIO146, GPIO147, GPIO148, GPIO149, GPIO150,
+ GPIO151, GPIO152, GPIO153, GPIO154, GPIO155, GPIO156, GPIO157, GPIO158,
+ GPIO159, GPIO160, GPIO161, GPIO162, GPIO163, GPIO164, GPIO165, GPIO166,
+ GPIO167, GPIO168, GPIO169, GPIO170, GPIO171, GPIO172, GPIO173, GPIO174,
+ GPIO175, GPIO176, GPIO177, GPIO178, GPIO179, GPIO180, GPIO181, GPIO182,
+ GPIO183, GPIO184, GPIO185, GPIO186, GPIO187, GPIO188, GPIO189, GPIO190,
+ GPIO191, GPIO192, GPIO193, GPIO194, GPIO195, GPIO196, GPIO197, GPIO198,
+ GPIO199, GPIO200, GPIO201, GPIO202, GPIO203, GPIO204, GPIO205, GPIO206,
+ GPIO207, GPIO208, GPIO209, GPIO210, GPIO211, GPIO212, GPIO213, GPIO214,
+ GPIO215, GPIO216, GPIO217, GPIO218, GPIO219, GPIO220, GPIO221, GPIO222,
+ GPIO223, GPIO224, GPIO225, GPIO226, GPIO227, GPIO228, GPIO229, GPIO230,
+ GPIO231, GPIO232, GPIO233, GPIO234, GPIO235, GPIO236, GPIO237, GPIO238,
+ GPIO239, GPIO240, GPIO241, GPIO242, GPIO243, GPIO244, GPIO245, GPIO246,
+ GPIO247, GPIO248, GPIO249, GPIO250, GPIO251, GPIO252, GPIO253, GPIO254,
+ GPIO255, GPIO256, GPIO257, GPIO258, GPIO259, GPIO260, GPIO261, GPIO262,
+ GPIO263, GPIO264, GPIO265, GPIO266, GPIO267, GPIO268, GPIO269, GPIO270,
+ MT_GPIO_BASE_MAX
+} GPIO_PIN;
+
+static const struct mt_pin_info mt_pin_infos[] = {
+ PIN(0, 0, 0, 0x18, 0x90),
+ PIN(1, 0, 1, 0x18, 0x90),
+ PIN(2, 0, 1, 0x1b, 0x70),
+ PIN(3, 0, 2, 0x1b, 0x70),
+ PIN(4, 0, 3, 0x1b, 0x70),
+ PIN(5, 0, 4, 0x1b, 0x70),
+ PIN(6, 0, 5, 0x1b, 0x70),
+ PIN(7, 0, 6, 0x1b, 0x70),
+ PIN(8, 0, 7, 0x1b, 0x70),
+ PIN(9, 0, 14, 0x29, 0xa0),
+ PIN(10, 0, 12, 0x29, 0xa0),
+ PIN(11, 0, 2, 0x18, 0x90),
+ PIN(12, 0, 13, 0x29, 0xa0),
+ PIN(13, 0, 1, 0x26, 0x90),
+ PIN(14, 0, 0, 0x13, 0x80),
+ PIN(15, 0, 2, 0x26, 0x90),
+ PIN(16, 0, 3, 0x26, 0x90),
+ PIN(17, 0, 4, 0x26, 0x90),
+ PIN(18, 0, 5, 0x26, 0x90),
+ PIN(19, 0, 6, 0x26, 0x90),
+ PIN(20, 0, 1, 0x13, 0x80),
+ PIN(21, 0, 3, 0x12, 0x80),
+ PIN(22, 0, 4, 0x12, 0x80),
+ PIN(23, 0, 5, 0x12, 0x80),
+ PIN(24, 0, 6, 0x12, 0x80),
+ PIN(25, 0, 7, 0x12, 0x80),
+ PIN(26, 0, 8, 0x12, 0x80),
+ PIN(27, 0, 9, 0x12, 0x80),
+ PIN(28, 0, 10, 0x12, 0x80),
+ PIN(29, 0, 11, 0x12, 0x80),
+ PIN(30, 0, 12, 0x12, 0x80),
+ PIN(31, 0, 13, 0x12, 0x80),
+ PIN(32, 0, 8, 0x11, 0x80),
+ PIN(33, 0, 9, 0x11, 0x80),
+ PIN(34, 0, 10, 0x11, 0x80),
+ PIN(35, 0, 11, 0x11, 0x80),
+ PIN(36, 0, 12, 0x11, 0x80),
+ PIN(37, 0, 13, 0x11, 0x80),
+ PIN(38, 0, 14, 0x11, 0x80),
+ PIN(39, 0, 6, 0x18, 0x90),
+ PIN(40, 0, 3, 0x18, 0x90),
+ PIN(41, 0, 5, 0x18, 0x90),
+ PIN(42, 0, 4, 0x18, 0x90),
+ PIN(43, 0, 7, 0x18, 0x90),
+ PIN(44, 0, 8, 0x18, 0x90),
+ PIN(45, 0, 9, 0x18, 0x90),
+ PIN(46, 0, 10, 0x18, 0x90),
+ PIN(47, 0, 13, 0x18, 0x90),
+ PIN(48, 0, 11, 0x18, 0x90),
+ PIN(49, 0, 14, 0x18, 0x90),
+ PIN(50, 0, 12, 0x18, 0x90),
+ PIN(51, 0, 15, 0x18, 0x90),
+ PIN(52, 0, 7, 0x29, 0xa0),
+ PIN(53, 0, 8, 0x29, 0xa0),
+ PIN(54, 0, 2, 0x29, 0xa0),
+ PIN(55, 0, 1, 0x29, 0xa0),
+ PIN(56, 0, 5, 0x29, 0xa0),
+ PIN(57, 0, 6, 0x29, 0xa0),
+ PIN(58, 0, 3, 0x29, 0xa0),
+ PIN(59, 0, 4, 0x29, 0xa0),
+ PIN(60, 1, 0, 0x29, 0xb0),
+ PIN(61, 0, 10, 0x29, 0xa0),
+ PIN(62, 0, 9, 0x29, 0xa0),
+ PIN(63, 0, 18, 0x29, 0xa0),
+ PIN(64, 0, 0, 0x29, 0xa0),
+ PIN(65, 0, 11, 0x29, 0xa0),
+ PIN(66, 0, 24, 0x29, 0xa0),
+ PIN(67, 0, 21, 0x29, 0xa0),
+ PIN(68, 0, 20, 0x29, 0xa0),
+ PIN(69, 0, 25, 0x29, 0xa0),
+ PIN(70, 0, 16, 0x29, 0xa0),
+ PIN(71, 0, 15, 0x29, 0xa0),
+ PIN(72, 0, 23, 0x29, 0xa0),
+ PIN(73, 0, 19, 0x29, 0xa0),
+ PIN(74, 0, 17, 0x29, 0xa0),
+ PIN(75, 0, 2, 0x1a, 0x80),
+ PIN(76, 0, 3, 0x1a, 0x80),
+ PIN(77, 0, 4, 0x1a, 0x80),
+ PIN(78, 0, 5, 0x1a, 0x80),
+ PIN(79, 0, 0, 0x1a, 0x80),
+ PIN(80, 0, 1, 0x1a, 0x80),
+ PIN(81, 0, 9, 0x1b, 0x70),
+ PIN(82, 0, 10, 0x1b, 0x70),
+ PIN(83, 0, 12, 0x1b, 0x70),
+ PIN(84, 0, 11, 0x1b, 0x70),
+ PIN(85, 0, 13, 0x1b, 0x70),
+ PIN(86, 0, 14, 0x1b, 0x70),
+ PIN(87, 0, 16, 0x1b, 0x70),
+ PIN(88, 0, 15, 0x1b, 0x70),
+ PIN(89, 0, 0, 0x1b, 0x70),
+ PIN(90, 0, 8, 0x1b, 0x70),
+ PIN(91, 0, 6, 0x1c, 0x80),
+ PIN(92, 0, 7, 0x1c, 0x80),
+ PIN(93, 0, 8, 0x1c, 0x80),
+ PIN(94, 0, 4, 0x1c, 0x80),
+ PIN(95, 0, 1, 0x1c, 0x80),
+ PIN(96, 0, 3, 0x1c, 0x80),
+ PIN(97, 0, 2, 0x1c, 0x80),
+ PIN(98, 0, 5, 0x1c, 0x80),
+ PIN(99, 0, 9, 0x1c, 0x80),
+ PIN(100, 0, 12, 0x1c, 0x80),
+ PIN(101, 0, 10, 0x1c, 0x80),
+ PIN(102, 0, 13, 0x1c, 0x80),
+ PIN(103, 0, 0, 0x1c, 0x80),
+ PIN(104, 0, 11, 0x1c, 0x80),
+ PIN(105, 0, 14, 0x1c, 0x80),
+ PIN(106, 0, 0, 0x15, 0x80),
+ PIN(107, 0, 1, 0x15, 0x80),
+ PIN(108, 0, 3, 0x15, 0x80),
+ PIN(109, 0, 2, 0x15, 0x80),
+ PIN(110, 0, 4, 0x15, 0x80),
+ PIN(111, 0, 5, 0x15, 0x80),
+ PIN(112, 0, 7, 0x15, 0x80),
+ PIN(113, 0, 6, 0x15, 0x80),
+ PIN(114, 0, 8, 0x15, 0x80),
+ PIN(115, 0, 9, 0x15, 0x80),
+ PIN(116, 0, 11, 0x15, 0x80),
+ PIN(117, 0, 10, 0x15, 0x80),
+ PIN(118, 0, 9, 0x26, 0x90),
+ PIN(119, 0, 10, 0x26, 0x90),
+ PIN(120, 0, 12, 0x26, 0x90),
+ PIN(121, 0, 11, 0x26, 0x90),
+ PIN(122, 0, 0, 0x26, 0x90),
+ PIN(123, 0, 7, 0x26, 0x90),
+ PIN(124, 0, 8, 0x26, 0x90),
+ PIN(125, 1, 0, 0x17, 0x80),
+ PIN(126, 1, 1, 0x17, 0x80),
+ PIN(127, 1, 2, 0x17, 0x80),
+ PIN(128, 1, 3, 0x17, 0x80),
+ PIN(129, 1, 4, 0x17, 0x80),
+ PIN(130, 1, 5, 0x17, 0x80),
+ PIN(131, 1, 9, 0x17, 0x80),
+ PIN(132, 1, 11, 0x17, 0x80),
+ PIN(133, 1, 10, 0x17, 0x80),
+ PIN(134, 1, 6, 0x17, 0x80),
+ PIN(135, 1, 8, 0x17, 0x80),
+ PIN(136, 1, 7, 0x17, 0x80),
+ PIN(137, 1, 10, 0x14, 0x70),
+ PIN(138, 1, 11, 0x14, 0x70),
+ PIN(139, 1, 12, 0x14, 0x70),
+ PIN(140, 1, 13, 0x14, 0x70),
+ PIN(141, 1, 14, 0x14, 0x70),
+ PIN(142, 1, 15, 0x14, 0x70),
+ PIN(143, 1, 16, 0x14, 0x70),
+ PIN(144, 1, 17, 0x14, 0x70),
+ PIN(145, 1, 0, 0x14, 0x70),
+ PIN(146, 1, 1, 0x14, 0x70),
+ PIN(147, 1, 2, 0x14, 0x70),
+ PIN(148, 1, 3, 0x14, 0x70),
+ PIN(149, 1, 4, 0x14, 0x70),
+ PIN(150, 1, 5, 0x14, 0x70),
+ PIN(151, 1, 6, 0x14, 0x70),
+ PIN(152, 1, 7, 0x14, 0x70),
+ PIN(153, 1, 9, 0x14, 0x70),
+ PIN(154, 1, 8, 0x14, 0x70),
+ PIN(155, 1, 18, 0x14, 0x70),
+ PIN(156, 1, 19, 0x14, 0x70),
+ PIN(157, 0, 1, 0x12, 0x80),
+ PIN(158, 0, 2, 0x12, 0x80),
+ PIN(159, 0, 0, 0x12, 0x80),
+ PIN(160, 0, 22, 0x13, 0x80),
+ PIN(161, 0, 20, 0x13, 0x80),
+ PIN(162, 0, 23, 0x13, 0x80),
+ PIN(163, 0, 21, 0x13, 0x80),
+ PIN(164, 0, 12, 0x13, 0x80),
+ PIN(165, 0, 14, 0x13, 0x80),
+ PIN(166, 0, 13, 0x13, 0x80),
+ PIN(167, 0, 15, 0x13, 0x80),
+ PIN(168, 0, 16, 0x13, 0x80),
+ PIN(169, 0, 17, 0x13, 0x80),
+ PIN(170, 0, 19, 0x13, 0x80),
+ PIN(171, 0, 18, 0x13, 0x80),
+ PIN(172, 0, 10, 0x13, 0x80),
+ PIN(173, 0, 11, 0x13, 0x80),
+ PIN(174, 0, 15, 0x11, 0x80),
+ PIN(175, 0, 16, 0x11, 0x80),
+ PIN(176, 0, 17, 0x11, 0x80),
+ PIN(177, 0, 18, 0x11, 0x80),
+ PIN(178, 0, 6, 0x11, 0x80),
+ PIN(179, 0, 7, 0x11, 0x80),
+ PIN(180, 0, 0, 0x11, 0x80),
+ PIN(181, 0, 1, 0x11, 0x80),
+ PIN(182, 0, 2, 0x11, 0x80),
+ PIN(183, 0, 3, 0x11, 0x80),
+ PIN(184, 0, 4, 0x11, 0x80),
+ PIN(185, 0, 5, 0x11, 0x80),
+ PIN(186, 0, 4, 0x1d, 0xc0),
+ PIN(187, 0, 5, 0x1d, 0xc0),
+ PIN(188, 0, 12, 0x1d, 0xc0),
+ PIN(189, 0, 17, 0x1d, 0xc0),
+ PIN(190, 0, 13, 0x1d, 0xc0),
+ PIN(191, 0, 18, 0x1d, 0xc0),
+ PIN(192, 0, 0, 0x1d, 0xc0),
+ PIN(193, 0, 6, 0x1d, 0xc0),
+ PIN(194, 0, 14, 0x1d, 0xc0),
+ PIN(195, 0, 19, 0x1d, 0xc0),
+ PIN(196, 0, 1, 0x1d, 0xc0),
+ PIN(197, 0, 7, 0x1d, 0xc0),
+ PIN(198, 0, 15, 0x1d, 0xc0),
+ PIN(199, 0, 20, 0x1d, 0xc0),
+ PIN(200, 0, 22, 0x1d, 0xc0),
+ PIN(201, 0, 25, 0x1d, 0xc0),
+ PIN(202, 0, 16, 0x1d, 0xc0),
+ PIN(203, 0, 21, 0x1d, 0xc0),
+ PIN(204, 0, 2, 0x1d, 0xc0),
+ PIN(205, 0, 3, 0x1d, 0xc0),
+ PIN(206, 0, 8, 0x1d, 0xc0),
+ PIN(207, 0, 9, 0x1d, 0xc0),
+ PIN(208, 0, 10, 0x1d, 0xc0),
+ PIN(209, 0, 11, 0x1d, 0xc0),
+ PIN(210, 0, 0, 0x2e, 0x90),
+ PIN(211, 0, 1, 0x2e, 0x90),
+ PIN(212, 0, 2, 0x2e, 0x90),
+ PIN(213, 0, 3, 0x2e, 0x90),
+ PIN(214, 0, 23, 0x1d, 0xc0),
+ PIN(215, 0, 24, 0x1d, 0xc0),
+ PIN(216, 0, 4, 0x2e, 0x90),
+ PIN(217, 1, 1, 0x2e, 0xa0),
+ PIN(218, 1, 2, 0x2e, 0xa0),
+ PIN(219, 1, 0, 0x2e, 0xa0),
+ PIN(220, 0, 5, 0x2e, 0x90),
+ PIN(221, 0, 6, 0x2e, 0x90),
+ PIN(222, 0, 8, 0x2e, 0x90),
+ PIN(223, 0, 7, 0x2e, 0x90),
+ PIN(224, 1, 3, 0x2e, 0xa0),
+ PIN(225, 1, 4, 0x2e, 0xa0),
+ PIN(226, 1, 5, 0x2e, 0xa0),
+ PIN(227, 1, 6, 0x2e, 0xa0),
+ PIN(228, 1, 7, 0x2e, 0xa0),
+ PIN(229, 1, 8, 0x2e, 0xa0),
+ PIN(230, 0, 13, 0x2f, 0x70),
+ PIN(231, 0, 14, 0x2f, 0x70),
+ PIN(232, 0, 10, 0x2f, 0x70),
+ PIN(233, 0, 0, 0x2f, 0x70),
+ PIN(234, 0, 3, 0x2f, 0x70),
+ PIN(235, 0, 1, 0x2f, 0x70),
+ PIN(236, 0, 2, 0x2f, 0x70),
+ PIN(237, 0, 6, 0x2f, 0x70),
+ PIN(238, 0, 5, 0x2f, 0x70),
+ PIN(239, 0, 19, 0x2f, 0x70),
+ PIN(240, 0, 18, 0x2f, 0x70),
+ PIN(241, 0, 16, 0x2f, 0x70),
+ PIN(242, 0, 17, 0x2f, 0x70),
+ PIN(243, 0, 15, 0x2f, 0x70),
+ PIN(244, 0, 12, 0x2f, 0x70),
+ PIN(245, 0, 9, 0x2f, 0x70),
+ PIN(246, 0, 8, 0x2f, 0x70),
+ PIN(247, 0, 7, 0x2f, 0x70),
+ PIN(248, 0, 4, 0x2f, 0x70),
+ PIN(249, 0, 20, 0x2f, 0x70),
+ PIN(250, 0, 11, 0x2f, 0x70),
+ PIN(251, 0, 2, 0x13, 0x80),
+ PIN(252, 0, 3, 0x13, 0x80),
+ PIN(253, 0, 4, 0x13, 0x80),
+ PIN(254, 0, 5, 0x13, 0x80),
+ PIN(255, 0, 6, 0x13, 0x80),
+ PIN(256, 0, 7, 0x13, 0x80),
+ PIN(257, 0, 8, 0x13, 0x80),
+ PIN(258, 0, 9, 0x13, 0x80),
+ PIN(259, 1, 9, 0x2e, 0xa0),
+ PIN(260, 1, 10, 0x2e, 0xa0),
+ PIN(261, 1, 11, 0x2e, 0xa0),
+ PIN(262, 1, 12, 0x2e, 0xa0),
+ PIN(263, 1, 13, 0x2e, 0xa0),
+ PIN(264, 1, 14, 0x2e, 0xa0),
+ PIN(265, 1, 15, 0x2e, 0xa0),
+ PIN(266, 1, 16, 0x2e, 0xa0),
+ PIN(267, 1, 2, 0x2f, 0x80),
+ PIN(268, 1, 3, 0x2f, 0x80),
+ PIN(269, 1, 0, 0x2f, 0x80),
+ PIN(270, 1, 1, 0x2f, 0x80),
+};
+
+#endif /* MT_GPIO_H */
diff --git a/plat/mediatek/mt8196/include/platform_def.h b/plat/mediatek/mt8196/include/platform_def.h
index 66c7cf8..6b6416a 100644
--- a/plat/mediatek/mt8196/include/platform_def.h
+++ b/plat/mediatek/mt8196/include/platform_def.h
@@ -31,11 +31,64 @@
#define AUDIO_BASE (IO_PHYS + 0x0a110000)
/*******************************************************************************
+ * APUSYS related constants
+ ******************************************************************************/
+#define APUSYS_BASE (IO_PHYS + 0x09000000)
+#define APU_MD32_SYSCTRL (IO_PHYS + 0x09001000)
+#define APU_MD32_WDT (IO_PHYS + 0x09002000)
+#define APU_LOGTOP (IO_PHYS + 0x09024000)
+#define APUSYS_CTRL_DAPC_RCX_BASE (IO_PHYS + 0x09030000)
+#define APU_REVISER (IO_PHYS + 0x0903C000)
+#define APU_RCX_UPRV_TCU (IO_PHYS + 0x09060000)
+#define APU_RCX_EXTM_TCU (IO_PHYS + 0x09061000)
+#define APU_CMU_TOP (IO_PHYS + 0x09067000)
+#define APUSYS_CE_BASE (IO_PHYS + 0x090B0000)
+#define APU_ARE_REG_BASE (IO_PHYS + 0x090B0000)
+#define APU_RCX_VCORE_CONFIG (IO_PHYS + 0x090E0000)
+#define APU_AO_CTRL (IO_PHYS + 0x090F2000)
+#define APU_SEC_CON (IO_PHYS + 0x090F5000)
+#define APUSYS_CTRL_DAPC_AO_BASE (IO_PHYS + 0x090FC000)
+
+#define APU_MBOX0 (0x4C200000)
+#define APU_MD32_TCM (0x4D000000)
+
+#define APU_MD32_TCM_SZ (0x50000)
+#define APU_MBOX0_SZ (0x100000)
+#define APU_INFRA_BASE (0x1002C000)
+#define APU_INFRA_SZ (0x1000)
+
+#define APU_RESERVE_MEMORY (0x95000000)
+#define APU_SEC_INFO_OFFSET (0x100000)
+#define APU_RESERVE_SIZE (0x1400000)
+
+/*******************************************************************************
* SPM related constants
******************************************************************************/
#define SPM_BASE (IO_PHYS + 0x0C004000)
/*******************************************************************************
+ * GPIO related constants
+ ******************************************************************************/
+#define GPIO_BASE (IO_PHYS + 0x0002D000)
+#define RGU_BASE (IO_PHYS + 0x0C00B000)
+#define DRM_BASE (IO_PHYS + 0x0000D000)
+#define IOCFG_RT_BASE (IO_PHYS + 0x02000000)
+#define IOCFG_RM1_BASE (IO_PHYS + 0x02020000)
+#define IOCFG_RM2_BASE (IO_PHYS + 0x02040000)
+#define IOCFG_RB_BASE (IO_PHYS + 0x02060000)
+#define IOCFG_BM1_BASE (IO_PHYS + 0x02820000)
+#define IOCFG_BM2_BASE (IO_PHYS + 0x02840000)
+#define IOCFG_BM3_BASE (IO_PHYS + 0x02860000)
+#define IOCFG_LT_BASE (IO_PHYS + 0x03000000)
+#define IOCFG_LM1_BASE (IO_PHYS + 0x03020000)
+#define IOCFG_LM2_BASE (IO_PHYS + 0x03040000)
+#define IOCFG_LB1_BASE (IO_PHYS + 0x030f0000)
+#define IOCFG_LB2_BASE (IO_PHYS + 0x03110000)
+#define IOCFG_TM1_BASE (IO_PHYS + 0x03800000)
+#define IOCFG_TM2_BASE (IO_PHYS + 0x03820000)
+#define IOCFG_TM3_BASE (IO_PHYS + 0x03860000)
+
+/*******************************************************************************
* UART related constants
******************************************************************************/
#define UART0_BASE (IO_PHYS + 0x06000000)
@@ -106,10 +159,31 @@
#define VDOSYS1_BASE (IO_PHYS + 0x0C100000)
/*******************************************************************************
+ * DP related constants
+ ******************************************************************************/
+#define EDP_SEC_BASE (IO_PHYS + 0x2EC50000)
+#define DP_SEC_BASE (IO_PHYS + 0x2EC10000)
+#define EDP_SEC_SIZE (0x1000)
+#define DP_SEC_SIZE (0x1000)
+
+/*******************************************************************************
* EMI MPU related constants
*******************************************************************************/
-#define EMI_MPU_BASE (IO_PHYS + 0x00428000)
-#define SUB_EMI_MPU_BASE (IO_PHYS + 0x00528000)
+#define EMI_MPU_BASE (IO_PHYS + 0x00428000)
+#define SUB_EMI_MPU_BASE (IO_PHYS + 0x00528000)
+#define EMI_SLB_BASE (IO_PHYS + 0x0042e000)
+#define SUB_EMI_SLB_BASE (IO_PHYS + 0x0052e000)
+#define CHN0_EMI_APB_BASE (IO_PHYS + 0x00201000)
+#define CHN1_EMI_APB_BASE (IO_PHYS + 0x00205000)
+#define CHN2_EMI_APB_BASE (IO_PHYS + 0x00209000)
+#define CHN3_EMI_APB_BASE (IO_PHYS + 0x0020D000)
+#define EMI_APB_BASE (IO_PHYS + 0x00429000)
+#define INFRA_EMI_DEBUG_CFG_BASE (IO_PHYS + 0x00425000)
+#define NEMI_SMPU_BASE (IO_PHYS + 0x0042f000)
+#define SEMI_SMPU_BASE (IO_PHYS + 0x0052f000)
+#define SUB_EMI_APB_BASE (IO_PHYS + 0x00529000)
+#define SUB_INFRA_EMI_DEBUG_CFG_BASE (IO_PHYS + 0x00525000)
+#define SUB_INFRACFG_AO_MEM_BASE (IO_PHYS + 0x00504000)
/*******************************************************************************
* System counter frequency related constants
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
index dd83b9a..0239a3f 100644
--- a/plat/mediatek/mt8196/plat_config.mk
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -26,6 +26,14 @@
CTX_INCLUDE_AARCH32_REGS := 0
CONFIG_ARCH_ARM_V9 := y
+CONFIG_MTK_APUSYS_CE_SUPPORT := y
+CONFIG_MTK_APUSYS_EMI_SUPPORT := n
+CONFIG_MTK_APUSYS_LOGTOP_SUPPORT := y
+CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT := y
+CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT := y
+CONFIG_MTK_APUSYS_RV_IOMMU_HW_SEM_SUPPORT := y
+CONFIG_MTK_APUSYS_SEC_CTRL := y
+CONFIG_MTK_APUSYS_SETUP_CE := y
CONFIG_MTK_MCUSYS := y
MCUSYS_VERSION := v1
CONFIG_MTK_PM_SUPPORT := y
@@ -36,6 +44,7 @@
CONFIG_MTK_CPU_SUSPEND_EN := y
CONFIG_MTK_SPM_VERSION := mt8196
CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND := y
+CONFIG_MTK_TINYSYS_VCP := y
CPU_PM_TINYSYS_SUPPORT := y
MTK_PUBEVENT_ENABLE := y
diff --git a/plat/mediatek/mt8196/plat_mmap.c b/plat/mediatek/mt8196/plat_mmap.c
index f7f819a..d32f4ee 100644
--- a/plat/mediatek/mt8196/plat_mmap.c
+++ b/plat/mediatek/mt8196/plat_mmap.c
@@ -17,6 +17,12 @@
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(CPU_IDLE_SRAM_BASE, CPU_IDLE_SRAM_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(DP_SEC_BASE, DP_SEC_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(EDP_SEC_BASE, EDP_SEC_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(APU_MBOX0, APU_MBOX0_SZ,
+ MT_DEVICE | MT_RW | MT_SECURE),
{ 0 }
};
DECLARE_MTK_MMAP_REGIONS(plat_mmap);
diff --git a/plat/mediatek/mt8196/platform.mk b/plat/mediatek/mt8196/platform.mk
index cd428b2..8ae8e28 100644
--- a/plat/mediatek/mt8196/platform.mk
+++ b/plat/mediatek/mt8196/platform.mk
@@ -14,26 +14,38 @@
include lib/xlat_tables_v2/xlat_tables.mk
PLAT_INCLUDES := -I${MTK_PLAT}/common \
+ -I${MTK_PLAT}/drivers/gpio/ \
-I${MTK_PLAT}/include \
-I${MTK_PLAT}/include/${ARCH_VERSION} \
-I${MTK_PLAT} \
+ -I${MTK_PLAT_SOC}/drivers/gpio/ \
-I${MTK_PLAT_SOC}/include \
-Idrivers/arm/gic \
MODULES-y += $(MTK_PLAT)/common
MODULES-y += $(MTK_PLAT)/lib/mtk_init
MODULES-y += $(MTK_PLAT)/lib/pm
+MODULES-y += $(MTK_PLAT)/drivers/apusys
+MODULES-y += $(MTK_PLAT)/drivers/dp
+MODULES-y += $(MTK_PLAT)/drivers/emi
MODULES-y += $(MTK_PLAT)/drivers/mcusys
MODULES-y += $(MTK_PLAT)/drivers/timer
+MODULES-y += $(MTK_PLAT)/drivers/vcp
MODULES-y += $(MTK_PLAT)/helpers
MODULES-y += $(MTK_PLAT)/topology
+ifneq ($(MTKLIB_PATH),)
+LDFLAGS += -L $(dir $(MTKLIB_PATH))
+LDLIBS += -l$(patsubst lib%.a,%,$(notdir $(MTKLIB_PATH)))
+endif
+
PLAT_BL_COMMON_SOURCES := common/desc_image_load.c \
drivers/ti/uart/aarch64/16550_console.S \
lib/bl_aux_params/bl_aux_params.c
BL31_SOURCES += drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ drivers/gpio/gpio.c \
lib/cpus/aarch64/cortex_a720.S \
lib/cpus/aarch64/cortex_x4.S \
lib/cpus/aarch64/cortex_x925.S \
@@ -44,6 +56,8 @@
plat/common/aarch64/crash_console_helpers.S \
${MTK_PLAT}/common/mtk_plat_common.c \
${MTK_PLAT}/common/params_setup.c \
+ ${MTK_PLAT}/drivers/gpio/mtgpio_common.c \
+ $(MTK_PLAT)/$(MTK_SOC)/drivers/gpio/mtgpio.c \
$(MTK_PLAT)/$(MTK_SOC)/plat_mmap.c
include plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
diff --git a/plat/nuvoton/npcm845x/platform.mk b/plat/nuvoton/npcm845x/platform.mk
index 1959aac..d73756c 100644
--- a/plat/nuvoton/npcm845x/platform.mk
+++ b/plat/nuvoton/npcm845x/platform.mk
@@ -318,9 +318,8 @@
endif
# Pointer Authentication sources
-ifeq (${ENABLE_PAUTH}, 1)
-PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c \
- lib/extensions/pauth/pauth_helpers.S
+ifeq ($(BRANCH_PROTECTION),$(filter $(BRANCH_PROTECTION),1 2 3))
+PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c
endif
ifeq (${SPD},spmd)
diff --git a/plat/nxp/s32/s32g274ardb2/include/platform_def.h b/plat/nxp/s32/s32g274ardb2/include/platform_def.h
index 1a4c495..cb16658 100644
--- a/plat/nxp/s32/s32g274ardb2/include/platform_def.h
+++ b/plat/nxp/s32/s32g274ardb2/include/platform_def.h
@@ -48,7 +48,7 @@
/* We'll be doing a 1:1 mapping anyway */
#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 36)
-#define MAX_MMAP_REGIONS U(8)
+#define MAX_MMAP_REGIONS U(18)
#define MAX_XLAT_TABLES U(32)
/* Console settings */
diff --git a/plat/nxp/s32/s32g274ardb2/include/s32cc-bl-common.h b/plat/nxp/s32/s32g274ardb2/include/s32cc-bl-common.h
new file mode 100644
index 0000000..0f0c804
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/s32cc-bl-common.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef S32CC_BL_COMMON_H
+#define S32CC_BL_COMMON_H
+
+int s32cc_bl_mmu_setup(void);
+
+#endif /* S32CC_BL_COMMON_H */
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
index 4645f01..0929f9d 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
@@ -4,15 +4,21 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <errno.h>
+
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <plat_console.h>
#include <s32cc-clk-drv.h>
+
#include <plat_io_storage.h>
+#include <s32cc-bl-common.h>
#include <s32cc-ncore.h>
+#define SIUL20_BASE UL(0x4009C000)
#define SIUL2_PC09_MSCR UL(0x4009C2E4)
#define SIUL2_PC10_MSCR UL(0x4009C2E8)
#define SIUL2_PC10_LIN0_IMCR UL(0x4009CA40)
@@ -38,6 +44,20 @@
void bl2_platform_setup(void)
{
+ int ret;
+
+ ret = mmap_add_dynamic_region(S32G_FIP_BASE, S32G_FIP_BASE,
+ S32G_FIP_SIZE,
+ MT_MEMORY | MT_RW | MT_SECURE);
+ if (ret != 0) {
+ panic();
+ }
+}
+
+static int s32g_mmap_siul2(void)
+{
+ return mmap_add_dynamic_region(SIUL20_BASE, SIUL20_BASE, PAGE_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE);
}
static void linflex_config_pinctrl(void)
@@ -55,14 +75,6 @@
{
int ret;
- ret = s32cc_init_early_clks();
- if (ret != 0) {
- panic();
- }
-
- linflex_config_pinctrl();
- console_s32g2_register();
-
/* Restore (clear) the CAIUTC[IsolEn] bit for the primary cluster, which
* we have manually set during early BL2 boot.
*/
@@ -71,6 +83,29 @@
ncore_init();
ncore_caiu_online(A53_CLUSTER0_CAIU);
+ ret = s32cc_init_core_clocks();
+ if (ret != 0) {
+ panic();
+ }
+
+ ret = s32cc_bl_mmu_setup();
+ if (ret != 0) {
+ panic();
+ }
+
+ ret = s32cc_init_early_clks();
+ if (ret != 0) {
+ panic();
+ }
+
+ ret = s32g_mmap_siul2();
+ if (ret != 0) {
+ panic();
+ }
+
+ linflex_config_pinctrl();
+ console_s32g2_register();
+
plat_s32g2_io_setup();
}
@@ -78,3 +113,26 @@
{
}
+int bl2_plat_handle_pre_image_load(unsigned int image_id)
+{
+ const struct bl_mem_params_node *desc = get_bl_mem_params_node(image_id);
+ const struct image_info *img_info;
+ size_t size;
+
+ if (desc == NULL) {
+ return -EINVAL;
+ }
+
+ img_info = &desc->image_info;
+
+ if ((img_info == NULL) || (img_info->image_max_size == 0U)) {
+ return -EINVAL;
+ }
+
+ size = page_align(img_info->image_max_size, UP);
+
+ return mmap_add_dynamic_region(img_info->image_base,
+ img_info->image_base,
+ size,
+ MT_MEMORY | MT_RW | MT_SECURE);
+}
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
index 03bf35c..22c66b0 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
@@ -4,10 +4,14 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <common/debug.h>
#include <drivers/arm/gicv3.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <plat_console.h>
+#include <s32cc-bl-common.h>
+
static entry_point_info_t bl33_image_ep_info;
static unsigned int s32g2_mpidr_to_core_pos(unsigned long mpidr);
@@ -25,8 +29,6 @@
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- console_s32g2_register();
-
SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
bl33_image_ep_info.pc = BL33_BASE;
bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
@@ -35,6 +37,14 @@
void bl31_plat_arch_setup(void)
{
+ int ret;
+
+ ret = s32cc_bl_mmu_setup();
+ if (ret != 0) {
+ panic();
+ }
+
+ console_s32g2_register();
}
struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
@@ -42,6 +52,31 @@
return &bl33_image_ep_info;
}
+static int mmap_gic(const gicv3_driver_data_t *gic_data)
+{
+ size_t gicr_size;
+ int ret;
+
+ ret = mmap_add_dynamic_region(gic_data->gicd_base,
+ gic_data->gicd_base,
+ PAGE_SIZE_64KB,
+ MT_DEVICE | MT_RW | MT_SECURE);
+ if (ret != 0) {
+ return ret;
+ }
+
+ gicr_size = gicv3_redist_size(0x0U);
+ ret = mmap_add_dynamic_region(gic_data->gicr_base,
+ gic_data->gicr_base,
+ gicr_size * gic_data->rdistif_num,
+ MT_DEVICE | MT_RW | MT_SECURE);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
void bl31_platform_setup(void)
{
static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
@@ -52,8 +87,13 @@
.rdistif_base_addrs = rdistif_base_addrs,
.mpidr_to_core_pos = s32g2_mpidr_to_core_pos,
};
-
unsigned int pos = plat_my_core_pos();
+ int ret;
+
+ ret = mmap_gic(&plat_gic_data);
+ if (ret != 0) {
+ panic();
+ }
gicv3_driver_init(&plat_gic_data);
gicv3_distif_init();
diff --git a/plat/nxp/s32/s32g274ardb2/plat_console.c b/plat/nxp/s32/s32g274ardb2/plat_console.c
index 542fa7b..e65e439 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_console.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_console.c
@@ -5,6 +5,7 @@
*/
#include <common/debug.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
#include <linflex.h>
#include <plat_console.h>
#include <platform_def.h>
@@ -17,6 +18,12 @@
};
int ret;
+ ret = mmap_add_dynamic_region(UART_BASE, UART_BASE, PAGE_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE);
+ if (ret != 0) {
+ panic();
+ }
+
ret = console_linflex_register(UART_BASE, UART_CLOCK_HZ,
UART_BAUDRATE, &s32g2_console);
if (ret == 0) {
diff --git a/plat/nxp/s32/s32g274ardb2/platform.mk b/plat/nxp/s32/s32g274ardb2/platform.mk
index 7d6e960..4ec7cd0 100644
--- a/plat/nxp/s32/s32g274ardb2/platform.mk
+++ b/plat/nxp/s32/s32g274ardb2/platform.mk
@@ -38,6 +38,9 @@
ERRATA_SPECULATIVE_AT := 1
ERRATA_S32_051700 := 1
+PLAT_XLAT_TABLES_DYNAMIC := 1
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+
# Selecting Drivers for SoC
$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
$(eval $(call SET_NXP_MAKE_FLAG,CLK_NEEDED,BL_COMM))
@@ -47,6 +50,8 @@
BL_COMMON_SOURCES += \
${PLAT_S32G274ARDB2}/plat_console.c \
${PLAT_S32G274ARDB2}/plat_helpers.S \
+ ${PLAT_S32G274ARDB2}/s32cc_bl_common.c \
+ ${XLAT_TABLES_LIB_SRCS} \
BL2_SOURCES += \
${BL_COMMON_SOURCES} \
diff --git a/plat/nxp/s32/s32g274ardb2/s32cc_bl_common.c b/plat/nxp/s32/s32g274ardb2/s32cc_bl_common.c
new file mode 100644
index 0000000..4664438
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/s32cc_bl_common.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+
+#include <common/bl_common.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <s32cc-bl-common.h>
+
+int s32cc_bl_mmu_setup(void)
+{
+ const unsigned long code_start = BL_CODE_BASE;
+ const unsigned long rw_start = BL_CODE_END;
+ unsigned long code_size;
+ unsigned long rw_size;
+
+ if (code_start > BL_CODE_END) {
+ return -EINVAL;
+ }
+
+ if (rw_start > BL_END) {
+ return -EINVAL;
+ }
+
+ code_size = BL_CODE_END - code_start;
+ rw_size = BL_END - rw_start;
+
+ mmap_add_region(code_start, code_start, code_size,
+ MT_RO | MT_MEMORY | MT_SECURE);
+ mmap_add_region(rw_start, rw_start, rw_size,
+ MT_RW | MT_MEMORY | MT_SECURE);
+
+ init_xlat_tables();
+ enable_mmu_el3(0);
+
+ return 0;
+}
diff --git a/plat/nxp/soc-lx2160a/ddr_fip.mk b/plat/nxp/soc-lx2160a/ddr_fip.mk
index c303ced..c1f14dc 100644
--- a/plat/nxp/soc-lx2160a/ddr_fip.mk
+++ b/plat/nxp/soc-lx2160a/ddr_fip.mk
@@ -1,5 +1,6 @@
#
# Copyright 2020 NXP
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -67,7 +68,7 @@
# Variables for use with Certificate Generation Tool
CRTTOOLPATH ?= tools/cert_create
-CRTTOOL ?= ${CRTTOOLPATH}/cert_create${BIN_EXT}
+CRTTOOL ?= ${CRTTOOLPATH}/cert_create$(.exe)
ifneq (${GENERATE_COT},0)
ddr_certificates: ${DDR_CRT_DEPS} ${CRTTOOL}
@@ -82,7 +83,7 @@
# Variables for use with Firmware Image Package
FIPTOOLPATH ?= tools/fiptool
-FIPTOOL ?= ${FIPTOOLPATH}/fiptool${BIN_EXT}
+FIPTOOL ?= ${FIPTOOLPATH}/fiptool$(.exe)
${BUILD_PLAT}/${DDR_FIP_NAME}: ${DDR_FIP_DEPS} ${FIPTOOL}
$(eval ${CHECK_DDR_FIP_CMD})
diff --git a/plat/qemu/common/common.mk b/plat/qemu/common/common.mk
index ed95bc6..5e3a61a 100644
--- a/plat/qemu/common/common.mk
+++ b/plat/qemu/common/common.mk
@@ -8,6 +8,7 @@
include common/fdt_wrappers.mk
PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
+ -I${PLAT_QEMU_COMMON_PATH}/ \
-I${PLAT_QEMU_COMMON_PATH}/include \
-I${PLAT_QEMU_PATH}/include \
-Iinclude/common/tbbr
@@ -65,7 +66,8 @@
${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c \
${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c \
common/desc_image_load.c \
- common/fdt_fixup.c
+ common/fdt_fixup.c \
+ ${FDT_WRAPPERS_SOURCES}
BL31_SOURCES += ${QEMU_CPU_LIBS} \
lib/semihosting/semihosting.c \
@@ -147,9 +149,8 @@
endif
# Pointer Authentication sources
-ifeq (${ENABLE_PAUTH}, 1)
+ifeq ($(BRANCH_PROTECTION),$(filter $(BRANCH_PROTECTION),1 2 3))
PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c
-CTX_INCLUDE_PAUTH_REGS := 1
endif
endif
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index c96e4b9..71f9cf7 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -22,9 +22,6 @@
#include <lib/transfer_list.h>
#include <lib/utils.h>
#include <plat/common/platform.h>
-#if ENABLE_RME
-#include <qemu_pas_def.h>
-#endif
#include "qemu_private.h"
@@ -84,8 +81,9 @@
#endif
int ret;
void *fdt = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
+ void *dst = plat_qemu_dt_runtime_address();
- ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE);
+ ret = fdt_open_into(fdt, dst, PLAT_QEMU_DT_MAX_SIZE);
if (ret < 0) {
ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret);
return;
@@ -150,54 +148,6 @@
#endif
}
-#if ENABLE_RME
-static void bl2_plat_gpt_setup(void)
-{
- /*
- * The GPT library might modify the gpt regions structure to optimize
- * the layout, so the array cannot be constant.
- */
- pas_region_t pas_regions[] = {
- QEMU_PAS_ROOT,
- QEMU_PAS_SECURE,
- QEMU_PAS_GPTS,
- QEMU_PAS_NS0,
- QEMU_PAS_REALM,
- QEMU_PAS_NS1,
- };
-
- /*
- * Initialize entire protected space to GPT_GPI_ANY. With each L0 entry
- * covering 1GB (currently the only supported option), then covering
- * 256TB of RAM (48-bit PA) would require a 2MB L0 region. At the
- * moment we use a 8KB table, which covers 1TB of RAM (40-bit PA).
- */
- if (gpt_init_l0_tables(GPCCR_PPS_1TB, PLAT_QEMU_L0_GPT_BASE,
- PLAT_QEMU_L0_GPT_SIZE +
- PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
- ERROR("gpt_init_l0_tables() failed!\n");
- panic();
- }
-
- /* Carve out defined PAS ranges. */
- if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
- PLAT_QEMU_L1_GPT_BASE,
- PLAT_QEMU_L1_GPT_SIZE,
- pas_regions,
- (unsigned int)(sizeof(pas_regions) /
- sizeof(pas_region_t))) < 0) {
- ERROR("gpt_init_pas_l1_tables() failed!\n");
- panic();
- }
-
- INFO("Enabling Granule Protection Checks\n");
- if (gpt_enable() < 0) {
- ERROR("gpt_enable() failed!\n");
- panic();
- }
-}
-#endif
-
void bl2_plat_arch_setup(void)
{
const mmap_region_t bl_regions[] = {
@@ -220,9 +170,6 @@
/* BL2 runs in EL3 when RME enabled. */
assert(is_feat_rme_present());
enable_mmu_el3(0);
-
- /* Initialise and enable granule protection after MMU. */
- bl2_plat_gpt_setup();
#else /* ENABLE_RME */
#ifdef __aarch64__
diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c
index 0a70cc2..81ce102 100644
--- a/plat/qemu/common/qemu_bl31_setup.c
+++ b/plat/qemu/common/qemu_bl31_setup.c
@@ -11,6 +11,16 @@
#include <lib/gpt_rme/gpt_rme.h>
#include <lib/transfer_list.h>
#include <plat/common/platform.h>
+#if ENABLE_RME
+#ifdef PLAT_qemu
+#include <qemu_pas_def.h>
+#elif PLAT_qemu_sbsa
+#include <qemu_sbsa_pas_def.h>
+#endif /* PLAT_qemu */
+#endif /* ENABLE_RME */
+#ifdef PLAT_qemu_sbsa
+#include <sbsa_platform.h>
+#endif
#include "qemu_private.h"
@@ -58,12 +68,15 @@
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
+ bool is64 = false;
+ uint64_t hval;
+
/* Initialize the console to provide early debug support */
qemu_console_init();
/* Platform names have to be lowercase. */
#ifdef PLAT_qemu_sbsa
- sip_svc_init();
+ sbsa_platform_init();
#endif
/*
@@ -82,6 +95,11 @@
* They are stored in Secure RAM, in BL2's address space.
*/
while (bl_params) {
+#ifdef __aarch64__
+ if (bl_params->image_id == BL31_IMAGE_ID &&
+ GET_RW(bl_params->ep_info->spsr) == MODE_RW_64)
+ is64 = true;
+#endif
if (bl_params->image_id == BL32_IMAGE_ID)
bl32_image_ep_info = *bl_params->ep_info;
@@ -103,12 +121,114 @@
panic();
#endif
- if (TRANSFER_LIST && arg1 == (TRANSFER_LIST_SIGNATURE |
- REGISTER_CONVENTION_VERSION_MASK) &&
- transfer_list_check_header((void *)arg3) != TL_OPS_NON) {
- bl31_tl = (void *)arg3; /* saved TL address from BL2 */
+ if (!TRANSFER_LIST ||
+ !transfer_list_check_header((void *)arg3))
+ return;
+
+ if (is64)
+ hval = TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
+ else
+ hval = TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+
+ if (arg1 != hval)
+ return;
+
+ bl31_tl = (void *)arg3; /* saved TL address from BL2 */
+}
+
+#if ENABLE_RME
+#if PLAT_qemu
+/*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+static pas_region_t pas_regions[] = {
+ QEMU_PAS_ROOT,
+ QEMU_PAS_SECURE,
+ QEMU_PAS_GPTS,
+ QEMU_PAS_NS0,
+ QEMU_PAS_REALM,
+ QEMU_PAS_NS1,
+};
+
+static inline void bl31_adjust_pas_regions(void) {}
+#elif PLAT_qemu_sbsa
+/*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+static pas_region_t pas_regions[] = {
+ QEMU_PAS_ROOT,
+ QEMU_PAS_SECURE,
+ QEMU_PAS_GPTS,
+ QEMU_PAS_REALM,
+ QEMU_PAS_NS0,
+};
+
+static void bl31_adjust_pas_regions(void)
+{
+ uint64_t base_addr = 0, total_size = 0;
+ struct platform_memory_data data;
+ uint32_t node;
+
+ /*
+ * The amount of memory supported by the SBSA platform is dynamic
+ * and dependent on user input. Since the configuration of the GPT
+ * needs to reflect the system memory, QEMU_PAS_NS0 needs to be set
+ * based on the information found in the device tree.
+ */
+
+ for (node = 0; node < sbsa_platform_num_memnodes(); node++) {
+ data = sbsa_platform_memory_node(node);
+
+ if (data.nodeid == 0) {
+ base_addr = data.addr_base;
+ }
+
+ total_size += data.addr_size;
+ }
+
+ /* Index '4' correspond to QEMU_PAS_NS0, see pas_regions[] above */
+ pas_regions[4].base_pa = base_addr;
+ pas_regions[4].size = total_size;
+}
+#endif /* PLAT_qemu */
+
+static void bl31_plat_gpt_setup(void)
+{
+ /*
+ * Initialize entire protected space to GPT_GPI_ANY. With each L0 entry
+ * covering 1GB (currently the only supported option), then covering
+ * 256TB of RAM (48-bit PA) would require a 2MB L0 region. At the
+ * moment we use a 8KB table, which covers 1TB of RAM (40-bit PA).
+ */
+ if (gpt_init_l0_tables(PLATFORM_GPCCR_PPS, PLAT_QEMU_L0_GPT_BASE,
+ PLAT_QEMU_L0_GPT_SIZE +
+ PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
+ ERROR("gpt_init_l0_tables() failed!\n");
+ panic();
+ }
+
+ bl31_adjust_pas_regions();
+
+ /* Carve out defined PAS ranges. */
+ if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
+ PLAT_QEMU_L1_GPT_BASE,
+ PLAT_QEMU_L1_GPT_SIZE,
+ pas_regions,
+ (unsigned int)(sizeof(pas_regions) /
+ sizeof(pas_region_t))) < 0) {
+ ERROR("gpt_init_pas_l1_tables() failed!\n");
+ panic();
+ }
+
+ INFO("Enabling Granule Protection Checks\n");
+ if (gpt_enable() < 0) {
+ ERROR("gpt_enable() failed!\n");
+ panic();
}
}
+#endif
void bl31_plat_arch_setup(void)
{
@@ -131,6 +251,9 @@
enable_mmu_el3(0);
#if ENABLE_RME
+ /* Initialise and enable granule protection after MMU. */
+ bl31_plat_gpt_setup();
+
/*
* Initialise Granule Protection library and enable GPC for the primary
* processor. The tables have already been initialized by a previous BL
@@ -202,10 +325,12 @@
#if TRANSFER_LIST
if (bl31_tl) {
/*
- * update the TL from S to NS memory before jump to BL33
+ * Relocate the TL from S to NS memory before EL3 exit
* to reflect all changes in TL done by BL32
*/
- memcpy((void *)FW_NS_HANDOFF_BASE, bl31_tl, bl31_tl->max_size);
+ if (!transfer_list_relocate(bl31_tl, (void *)FW_NS_HANDOFF_BASE,
+ bl31_tl->max_size))
+ ERROR("Relocate TL to NS memory failed\n");
}
#endif
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 9ccb2c8..5dc39a1 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -16,6 +16,9 @@
#if ENABLE_RME
#include <services/rmm_core_manifest.h>
#endif
+#ifdef PLAT_qemu_sbsa
+#include <sbsa_platform.h>
+#endif
#include <plat/common/platform.h>
#include "qemu_private.h"
@@ -224,12 +227,59 @@
return (size_t)RMM_SHARED_SIZE;
}
+#ifdef PLAT_qemu
+static uint32_t plat_get_num_memnodes(void)
+{
+ return 1;
+}
+
+static void plat_get_memory_node(int index, struct ns_dram_bank *bank_ptr)
+{
+ (void) index;
+ bank_ptr->base = NS_DRAM0_BASE;
+ bank_ptr->size = NS_DRAM0_SIZE;
+}
+#elif PLAT_qemu_sbsa
+static uint32_t plat_get_num_memnodes(void)
+{
+ return sbsa_platform_num_memnodes();
+}
+
+static void plat_get_memory_node(int index, struct ns_dram_bank *bank_ptr)
+{
+ struct platform_memory_data data = {0, 0, 0};
+
+ if (index < sbsa_platform_num_memnodes()) {
+ data = sbsa_platform_memory_node(index);
+ }
+
+ bank_ptr->base = data.addr_base;
+ bank_ptr->size = data.addr_size;
+}
+#endif /* PLAT_qemu */
+
+/*
+ * Calculate checksum of 64-bit words @buffer, of @size bytes
+ */
+static uint64_t checksum_calc(uint64_t *buffer, size_t size)
+{
+ uint64_t sum = 0UL;
+
+ assert(((uintptr_t)buffer & (sizeof(uint64_t) - 1UL)) == 0UL);
+ assert((size & (sizeof(uint64_t) - 1UL)) == 0UL);
+
+ for (unsigned long i = 0UL; i < (size / sizeof(uint64_t)); i++) {
+ sum += buffer[i];
+ }
+
+ return sum;
+}
+
int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
{
+ int i, last;
uint64_t checksum;
- uintptr_t base;
- uint64_t size;
- size_t num_banks = 1;
+ size_t num_banks = plat_get_num_memnodes();
size_t num_consoles = 1;
struct ns_dram_bank *bank_ptr;
struct console_info *console_ptr;
@@ -300,11 +350,30 @@
/* Calculate checksum of plat_dram structure */
checksum = num_banks + (uint64_t)bank_ptr;
- base = NS_DRAM0_BASE;
- size = NS_DRAM0_SIZE;
- bank_ptr[0].base = base;
- bank_ptr[0].size = size;
- checksum += base + size;
+ /*
+ * In the TF-A, NUMA nodes (if present) are stored in descending
+ * order, i.e:
+ *
+ * INFO: RAM 0: node-id: 1, address: 0x10080000000 - 0x101ffffffff
+ * INFO: RAM 1: node-id: 0, address: 0x10043000000 - 0x1007fffffff
+ *
+ * The RMM expects the memory banks to be presented in ascending order:
+ *
+ * INFO: RAM 1: node-id: 0, address: 0x10043000000 - 0x1007fffffff
+ * INFO: RAM 0: node-id: 1, address: 0x10080000000 - 0x101ffffffff
+ *
+ * As such, go through the NUMA nodes one by one and fill out
+ * @bank_ptr[] starting from the end. When NUMA nodes are not present
+ * there is only one memory bank and none of the above matters.
+ */
+ last = num_banks - 1;
+ for (i = 0; i < num_banks; i++) {
+ plat_get_memory_node(i, &bank_ptr[last]);
+ last--;
+ }
+
+ checksum += checksum_calc((uint64_t *)bank_ptr,
+ num_banks * sizeof(*bank_ptr));
/* Checksum must be 0 */
manifest->plat_dram.checksum = ~checksum + 1UL;
@@ -323,8 +392,8 @@
strlcpy(console_ptr[0].name, "pl011", sizeof(console_ptr[0].name));
/* Update checksum */
- checksum += console_ptr[0].base + console_ptr[0].map_pages +
- console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
+ checksum += checksum_calc((uint64_t *)console_ptr,
+ num_consoles * sizeof(*console_ptr));
/* Checksum must be 0 */
manifest->plat_console.checksum = ~checksum + 1UL;
@@ -332,3 +401,25 @@
return 0;
}
#endif /* ENABLE_RME */
+
+/**
+ * plat_qemu_dt_runtime_address() - Get the final DT location in RAM
+ *
+ * When support is enabled on SBSA, the device tree is relocated from its
+ * original place at the beginning of the NS RAM to after the RMM. This
+ * function returns the address of the final location in RAM of the device
+ * tree. See function update_dt() in qemu_bl2_setup.c
+ *
+ * Return: The address of the final location in RAM of the device tree
+ */
+#if (ENABLE_RME && PLAT_qemu_sbsa)
+void *plat_qemu_dt_runtime_address(void)
+{
+ return (void *)(uintptr_t)PLAT_QEMU_DT_BASE;
+}
+#else
+void *plat_qemu_dt_runtime_address(void)
+{
+ return (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
+}
+#endif /* (ENABLE_RME && PLAT_qemu_sbsa) */
diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h
index 25b14e2..046cb78 100644
--- a/plat/qemu/common/qemu_private.h
+++ b/plat/qemu/common/qemu_private.h
@@ -16,11 +16,9 @@
uintptr_t load_addr);
unsigned int plat_qemu_calc_core_pos(u_register_t mpidr);
const mmap_region_t *plat_qemu_get_mmap(void);
+void *plat_qemu_dt_runtime_address(void);
void qemu_console_init(void);
-#ifdef PLAT_qemu_sbsa
-void sip_svc_init(void);
-#endif
void plat_qemu_gic_init(void);
void qemu_pwr_gic_on_finish(void);
diff --git a/plat/qemu/qemu/include/qemu_pas_def.h b/plat/qemu/qemu/include/qemu_pas_def.h
index bcbea21..30934f0 100644
--- a/plat/qemu/qemu/include/qemu_pas_def.h
+++ b/plat/qemu/qemu/include/qemu_pas_def.h
@@ -102,6 +102,9 @@
QEMU_PAS_RMM_SHARED_SIZE, \
GPT_GPI_REALM)
+/* Cover 1TB with L0GTP */
+#define PLATFORM_GPCCR_PPS GPCCR_PPS_1TB
+
/* GPT Configuration options */
#define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 0d4cdb8..70e9faf 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -115,8 +115,7 @@
include drivers/auth/mbedtls/mbedtls_crypto.mk
endif
-BL2_SOURCES += ${FDT_WRAPPERS_SOURCES} \
- common/uuid.c
+BL2_SOURCES += common/uuid.c
ifeq ($(add-lib-optee),yes)
BL2_SOURCES += lib/optee/optee_utils.c
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
index 76a4da1..54a4156 100644
--- a/plat/qemu/qemu/qemu_measured_boot.c
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -65,6 +65,14 @@
event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
+ dump_event_log((uint8_t *)event_log_base, event_log_cur_size);
+
+#if TRANSFER_LIST
+ if (!plat_handoff_mboot((void *)event_log_base, event_log_cur_size,
+ (void *)(uintptr_t)FW_HANDOFF_BASE))
+ return;
+#endif
+
rc = qemu_set_nt_fw_info(
#ifdef SPD_opteed
(uintptr_t)event_log_base,
@@ -101,7 +109,6 @@
}
#endif /* defined(SPD_tspd) || defined(SPD_spmd) */
- dump_event_log((uint8_t *)event_log_base, event_log_cur_size);
}
int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index d230095..06e8abf 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -66,6 +66,9 @@
*/
#define PLAT_MAX_MEM_NODES 128
+/* Where QEMU starts the NS RAM */
+#define PLAT_QEMU_DRAM0_BASE 0x10000000000ULL
+
/*
* Partition memory into secure ROM, non-secure DRAM, secure "SRAM",
* and secure DRAM.
@@ -73,7 +76,12 @@
#define SEC_ROM_BASE 0x00000000
#define SEC_ROM_SIZE 0x00020000
-#define NS_DRAM0_BASE 0x10000000000ULL
+/*
+ * When the RME extension is enabled, the base of the NS RAM is shifted after
+ * RMM.
+ */
+#define NS_DRAM0_BASE (PLAT_QEMU_DRAM0_BASE + \
+ NS_DRAM0_BASE_OFFSET)
#define NS_DRAM0_SIZE 0x00020000000
#define SEC_SRAM_BASE 0x20000000
@@ -121,7 +129,8 @@
#define BL1_RO_BASE SEC_ROM_BASE
#define BL1_RO_LIMIT (SEC_ROM_BASE + SEC_ROM_SIZE)
#define BL1_RW_BASE (BL1_RW_LIMIT - BL1_SIZE)
-#define BL1_RW_LIMIT (BL_RAM_BASE + BL_RAM_SIZE)
+#define BL1_RW_LIMIT (BL_RAM_BASE + BL_RAM_SIZE - \
+ RME_GPT_DRAM_SIZE)
/*
* BL2 specific defines.
@@ -139,7 +148,7 @@
* Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
* current BL3-1 debug size plus a little space for growth.
*/
-#define BL31_SIZE 0x300000
+#define BL31_SIZE 0x400000
#define BL31_BASE (BL31_LIMIT - BL31_SIZE)
#define BL31_LIMIT (BL1_RW_BASE)
#define BL31_PROGBITS_LIMIT BL1_RW_BASE
@@ -154,8 +163,8 @@
#define BL32_SRAM_LIMIT BL2_BASE
#define BL32_MEM_BASE BL_RAM_BASE
-#define BL32_MEM_SIZE (BL_RAM_SIZE - BL1_SIZE - \
- BL2_SIZE - BL31_SIZE)
+#define BL32_MEM_SIZE (BL_RAM_SIZE - RME_GPT_DRAM_SIZE - \
+ BL1_SIZE - BL2_SIZE - BL31_SIZE)
#define BL32_BASE BL32_SRAM_BASE
#define BL32_LIMIT BL32_SRAM_LIMIT
@@ -167,6 +176,9 @@
#if SPM_MM
#define MAX_MMAP_REGIONS 12
#define MAX_XLAT_TABLES 12
+#elif ENABLE_RME
+#define MAX_MMAP_REGIONS 14
+#define MAX_XLAT_TABLES 14
#else
#define MAX_MMAP_REGIONS 11
#define MAX_XLAT_TABLES 11
@@ -205,7 +217,7 @@
#define QEMU_FLASH1_SIZE 0x10000000
#define PLAT_QEMU_FIP_BASE BL1_SIZE
-#define PLAT_QEMU_FIP_MAX_SIZE 0x00400000
+#define PLAT_QEMU_FIP_MAX_SIZE (QEMU_FLASH0_SIZE - BL1_SIZE)
/* This is map from GIC_DIST up to last CPU (255) GIC_REDISTR */
#define DEVICE0_BASE 0x40000000
@@ -377,4 +389,105 @@
#define QEMU_PRI_BITS 2
#define PLAT_SP_PRI 0x20
+#if !ENABLE_RME
+#define RME_GPT_DRAM_SIZE 0
+#define NS_DRAM0_BASE_OFFSET 0
+#else /* !ENABLE_RME */
+/*
+ * SBSA RAM starts at 1TB and we support up to 1TB of RAM. As such we
+ * have 2TB of physical address space to cover. Since the GPT size can be
+ * 4GB, 64GB, 1TB, 4TB and so on, we need to select 4GB. Note that it is
+ * possible to support more than 1TB of RAM but that will take more room in
+ * secure memory due to the L1 GPTES. See PLAT_QEMU_L1_GPT_SIZE for details.
+ *
+ * 4TB / 1GB == 4096 GPTEs
+ * 4096 * 8 (bytes per GPTE) == 32768 i.e 8 pages
+ */
+#define PLAT_QEMU_L0_GPT_SIZE (8 * PAGE_SIZE)
+#define PLAT_QEMU_L0_GPT_BASE (PLAT_QEMU_L1_GPT_BASE - \
+ (PLAT_QEMU_L0_GPT_SIZE + \
+ PLAT_QEMU_GPT_BITLOCK_SIZE + \
+ PLAT_QEMU_GPT_ALIGNMENT))
+
+#if RME_GPT_BITLOCK_BLOCK
+/*
+ * 4TB / (RME_GPT_BITLOCK_BLOCK * 512M * 8) == 1024
+ */
+#define PLAT_QEMU_GPT_BITLOCK_SIZE (1 * PAGE_SIZE)
+/*
+ * PLAT_QEMU_L0_GPT_SIZE is 8 pages and PLAT_QEMU_GPT_BITLOCK_SIZE
+ * is 1 page. As such we need 7 pages to have an 8 page alignment.
+ */
+#define PLAT_QEMU_GPT_ALIGNMENT (7 * PAGE_SIZE)
+#else /* RME_GPT_BITLOCK_BLOCK */
+#define PLAT_QEMU_GPT_BITLOCK_SIZE 0
+#define PLAT_QEMU_GPT_ALIGNMENT 0
+#endif /* RME_GPT_BITLOCK_BLOCK */
+
+/*
+ * If we have 1TB of RAM and each L1GPT covers 1GB, we need 1024 L1GPTs. With
+ * one more L1GPT to cover the other physical address spaces (see pas_regions[]
+ * in qemu_bl31_setup.c), we need a total of 1025 L1GPTs. Each L1GPT is 131072
+ * bytes, so we need 1025 * 131072 bytes = 0x8020000 of RAM to hold the L1GPTS.
+ */
+#define PLAT_QEMU_L1_GPT_SIZE UL(0x08020000)
+#define PLAT_QEMU_L1_GPT_BASE (BL_RAM_BASE + BL_RAM_SIZE - \
+ PLAT_QEMU_L1_GPT_SIZE)
+#define PLAT_QEMU_L1_GPT_END (PLAT_QEMU_L1_GPT_BASE + \
+ PLAT_QEMU_L1_GPT_SIZE - 1U)
+
+#define RME_GPT_DRAM_BASE PLAT_QEMU_L0_GPT_BASE
+#define RME_GPT_DRAM_SIZE (PLAT_QEMU_L1_GPT_SIZE + \
+ PLAT_QEMU_L0_GPT_SIZE + \
+ PLAT_QEMU_GPT_BITLOCK_SIZE + \
+ PLAT_QEMU_GPT_ALIGNMENT)
+
+#ifndef __ASSEMBLER__
+/* L0 table greater than 4KB must be naturally aligned */
+CASSERT((PLAT_QEMU_L0_GPT_BASE & (PLAT_QEMU_L0_GPT_SIZE - 1)) == 0,
+ assert_l0_gpt_naturally_aligned);
+#endif
+
+/* Reserved some DRAM space for RMM (1072MB) */
+#define REALM_DRAM_BASE PLAT_QEMU_DRAM0_BASE
+#define REALM_DRAM_SIZE 0x43000000
+
+#define PLAT_QEMU_RMM_SIZE (REALM_DRAM_SIZE - RMM_SHARED_SIZE)
+#define PLAT_QEMU_RMM_SHARED_SIZE (PAGE_SIZE) /* 4KB */
+
+#define RMM_BASE (REALM_DRAM_BASE)
+#define RMM_LIMIT (RMM_BASE + PLAT_QEMU_RMM_SIZE)
+#define RMM_SHARED_BASE (RMM_LIMIT)
+#define RMM_SHARED_SIZE PLAT_QEMU_RMM_SHARED_SIZE
+
+#define MAP_GPT_L0_REGION MAP_REGION_FLAT( \
+ PLAT_QEMU_L0_GPT_BASE, \
+ (PLAT_QEMU_L0_GPT_SIZE + \
+ PLAT_QEMU_GPT_BITLOCK_SIZE + \
+ PLAT_QEMU_GPT_ALIGNMENT), \
+ MT_MEMORY | MT_RW | EL3_PAS)
+
+#define MAP_GPT_L1_REGION MAP_REGION_FLAT( \
+ PLAT_QEMU_L1_GPT_BASE, \
+ PLAT_QEMU_L1_GPT_SIZE, \
+ MT_MEMORY | MT_RW | EL3_PAS)
+/*
+ * We add the 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 MAP_RMM_DRAM MAP_REGION_FLAT( \
+ RMM_BASE, \
+ (PLAT_QEMU_RMM_SIZE + \
+ RMM_SHARED_SIZE), \
+ MT_MEMORY | MT_RW | MT_REALM)
+
+#define MAP_RMM_SHARED_MEM MAP_REGION_FLAT( \
+ RMM_SHARED_BASE, \
+ RMM_SHARED_SIZE, \
+ MT_MEMORY | MT_RW | MT_REALM)
+
+/* When RME is enabled, the base of NS DRAM is moved forward after the RMM */
+#define NS_DRAM0_BASE_OFFSET REALM_DRAM_SIZE
+#endif /* !ENABLE_RME */
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/qemu_sbsa/include/qemu_sbsa_pas_def.h b/plat/qemu/qemu_sbsa/include/qemu_sbsa_pas_def.h
new file mode 100644
index 0000000..c73a162
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/include/qemu_sbsa_pas_def.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2024-2025, Linaro Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QEMU_PAS_DEF_H
+#define QEMU_PAS_DEF_H
+
+#include <lib/gpt_rme/gpt_rme.h>
+#include "platform_def.h"
+
+/*****************************************************************************
+ * PAS regions used to initialize the Granule Protection Table (GPT)
+ ****************************************************************************/
+
+/* EL3 SRAM */
+#define QEMU_PAS_ROOT_BASE (BL32_MEM_BASE + BL32_MEM_SIZE)
+#define QEMU_PAS_ROOT_SIZE (BL_RAM_SIZE - \
+ (BL32_MEM_SIZE + RME_GPT_DRAM_SIZE))
+
+/* Secure DRAM */
+#define QEMU_PAS_SEC_BASE BL32_MEM_BASE /* BL32_SRAM_BASE */
+#define QEMU_PAS_SEC_SIZE BL32_MEM_SIZE
+
+/* GPTs */
+#define QEMU_PAS_GPT_BASE RME_GPT_DRAM_BASE /* PLAT_QEMU_L0_GPT_BASE */
+#define QEMU_PAS_GPT_SIZE RME_GPT_DRAM_SIZE
+
+/* RMM */
+#define QEMU_PAS_RMM_BASE RMM_BASE
+#define QEMU_PAS_RMM_SIZE PLAT_QEMU_RMM_SIZE
+
+/* Shared area between EL3 and RMM */
+#define QEMU_PAS_RMM_SHARED_BASE RMM_SHARED_BASE
+#define QEMU_PAS_RMM_SHARED_SIZE RMM_SHARED_SIZE
+
+#define QEMU_PAS_ROOT GPT_MAP_REGION_GRANULE(QEMU_PAS_ROOT_BASE, \
+ QEMU_PAS_ROOT_SIZE, \
+ GPT_GPI_ROOT)
+
+#define QEMU_PAS_SECURE GPT_MAP_REGION_GRANULE(QEMU_PAS_SEC_BASE, \
+ QEMU_PAS_SEC_SIZE, \
+ GPT_GPI_SECURE)
+
+#define QEMU_PAS_GPTS GPT_MAP_REGION_GRANULE(QEMU_PAS_GPT_BASE, \
+ QEMU_PAS_GPT_SIZE, \
+ GPT_GPI_ROOT)
+
+/*
+ * NS0 base address and size are fetched from the DT at runtime.
+ * See bl31_adjust_pas_regions() for details
+ */
+#define QEMU_PAS_NS0 GPT_MAP_REGION_GRANULE(0, 0, GPT_GPI_NS)
+
+#define QEMU_PAS_REALM GPT_MAP_REGION_GRANULE(QEMU_PAS_RMM_BASE, \
+ QEMU_PAS_RMM_SIZE + \
+ QEMU_PAS_RMM_SHARED_SIZE, \
+ GPT_GPI_REALM)
+
+/* Cover 4TB with L0GTP */
+#define PLATFORM_GPCCR_PPS GPCCR_PPS_4TB
+
+/* GPT Configuration options */
+#define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS
+
+#endif /* QEMU_PAS_DEF_H */
diff --git a/plat/qemu/qemu_sbsa/include/sbsa_platform.h b/plat/qemu/qemu_sbsa/include/sbsa_platform.h
new file mode 100644
index 0000000..a3b3ea1
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/include/sbsa_platform.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2024-2025, Linaro Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SBSA_PLATFORM_H
+#define SBSA_PLATFORM_H
+
+#include <stdint.h>
+
+#include <platform_def.h>
+
+struct platform_cpu_data {
+ uint32_t nodeid;
+ uint32_t mpidr;
+};
+
+struct platform_memory_data {
+ uint32_t nodeid;
+ uint64_t addr_base;
+ uint64_t addr_size;
+};
+
+/*
+ * sockets: the number of sockets on sbsa-ref platform.
+ * clusters: the number of clusters in one socket.
+ * cores: the number of cores in one cluster.
+ * threads: the number of threads in one core.
+ */
+struct platform_cpu_topology {
+ uint32_t sockets;
+ uint32_t clusters;
+ uint32_t cores;
+ uint32_t threads;
+};
+
+struct qemu_platform_info {
+ uint32_t num_cpus;
+ uint32_t num_memnodes;
+ struct platform_cpu_data cpu[PLATFORM_CORE_COUNT];
+ struct platform_cpu_topology cpu_topo;
+ struct platform_memory_data memory[PLAT_MAX_MEM_NODES];
+};
+
+void sbsa_platform_init(void);
+int sbsa_platform_version_major(void);
+int sbsa_platform_version_minor(void);
+uint32_t sbsa_platform_num_cpus(void);
+uint32_t sbsa_platform_num_memnodes(void);
+uint64_t sbsa_platform_gic_its_addr(void);
+struct platform_cpu_data sbsa_platform_cpu_node(uint64_t index);
+struct platform_memory_data sbsa_platform_memory_node(uint64_t index);
+struct platform_cpu_topology sbsa_platform_cpu_topology(void);
+
+#endif /* SBSA_PLATFORM_H */
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 528e093..8ec3a82 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -29,8 +29,6 @@
$(eval $(call add_define,QEMU_LOAD_BL32))
endif
-BL2_SOURCES += $(LIBFDT_SRCS)
-
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
@@ -38,6 +36,7 @@
plat/common/plat_gicv3.c
BL31_SOURCES += ${PLAT_QEMU_PATH}/sbsa_gic.c \
+ ${PLAT_QEMU_PATH}/sbsa_platform.c \
${PLAT_QEMU_PATH}/sbsa_pm.c \
${PLAT_QEMU_PATH}/sbsa_sip_svc.c \
${PLAT_QEMU_PATH}/sbsa_topology.c
@@ -61,5 +60,5 @@
$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
-ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
+ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DRAM0_BASE
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
diff --git a/plat/qemu/qemu_sbsa/sbsa_platform.c b/plat/qemu/qemu_sbsa/sbsa_platform.c
new file mode 100644
index 0000000..8c8d632
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/sbsa_platform.c
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2024-2025, Linaro Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/fdt_wrappers.h>
+#include <libfdt.h>
+
+#include <sbsa_platform.h>
+
+#include "qemu_private.h"
+
+/* default platform version is 0.0 */
+static int platform_version_major;
+static int platform_version_minor;
+
+static uint64_t gic_its_addr;
+static struct qemu_platform_info dynamic_platform_info;
+
+void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base);
+
+/*
+ * QEMU provides us with minimal information about hardware platform using
+ * minimalistic DeviceTree. This is not a Linux DeviceTree. It is not even
+ * a firmware DeviceTree.
+ *
+ * It is information passed from QEMU to describe the information a hardware
+ * platform would have other mechanisms to discover at runtime, that are
+ * affected by the QEMU command line.
+ *
+ * Ultimately this device tree will be replaced by IPC calls to an emulated SCP.
+ * And when we do that, we won't then have to rewrite Normal world firmware to
+ * cope.
+ */
+
+static void read_cpu_topology_from_dt(void *dtb)
+{
+ int node;
+
+ /*
+ * QEMU gives us this DeviceTree node when we config:
+ * -smp 16,sockets=2,clusters=2,cores=2,threads=2
+ *
+ * topology {
+ * threads = <0x02>;
+ * cores = <0x02>;
+ * clusters = <0x02>;
+ * sockets = <0x02>;
+ * };
+ */
+
+ node = fdt_path_offset(dtb, "/cpus/topology");
+ if (node > 0) {
+ dynamic_platform_info.cpu_topo.sockets =
+ fdt_read_uint32_default(dtb, node, "sockets", 0);
+ dynamic_platform_info.cpu_topo.clusters =
+ fdt_read_uint32_default(dtb, node, "clusters", 0);
+ dynamic_platform_info.cpu_topo.cores =
+ fdt_read_uint32_default(dtb, node, "cores", 0);
+ dynamic_platform_info.cpu_topo.threads =
+ fdt_read_uint32_default(dtb, node, "threads", 0);
+ }
+
+ INFO("Cpu topology: sockets: %d, clusters: %d, cores: %d, threads: %d\n",
+ dynamic_platform_info.cpu_topo.sockets,
+ dynamic_platform_info.cpu_topo.clusters,
+ dynamic_platform_info.cpu_topo.cores,
+ dynamic_platform_info.cpu_topo.threads);
+}
+
+static void read_cpuinfo_from_dt(void *dtb)
+{
+ int node;
+ int prev;
+ int cpu = 0;
+ uintptr_t mpidr;
+
+ /*
+ * QEMU gives us this DeviceTree node:
+ * numa-node-id entries are only when NUMA config is used
+ *
+ * cpus {
+ * #size-cells = <0x00>;
+ * #address-cells = <0x02>;
+ *
+ * cpu@0 {
+ * numa-node-id = <0x00>;
+ * reg = <0x00 0x00>;
+ * };
+ *
+ * cpu@1 {
+ * numa-node-id = <0x03>;
+ * reg = <0x00 0x01>;
+ * };
+ * };
+ */
+ node = fdt_path_offset(dtb, "/cpus");
+ if (node < 0) {
+ ERROR("No information about cpus in DeviceTree.\n");
+ panic();
+ }
+
+ /*
+ * QEMU numbers cpus from 0 and there can be /cpus/cpu-map present so we
+ * cannot use fdt_first_subnode() here
+ */
+ node = fdt_path_offset(dtb, "/cpus/cpu@0");
+
+ while (node > 0) {
+ if (fdt_getprop(dtb, node, "reg", NULL)) {
+ fdt_get_reg_props_by_index(dtb, node, 0, &mpidr, NULL);
+ } else {
+ ERROR("Incomplete information for cpu %d in DeviceTree.\n", cpu);
+ panic();
+ }
+
+ dynamic_platform_info.cpu[cpu].mpidr = mpidr;
+ dynamic_platform_info.cpu[cpu].nodeid =
+ fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
+
+ INFO("CPU %d: node-id: %d, mpidr: %ld\n", cpu,
+ dynamic_platform_info.cpu[cpu].nodeid, mpidr);
+
+ cpu++;
+
+ prev = node;
+ node = fdt_next_subnode(dtb, prev);
+ }
+
+ dynamic_platform_info.num_cpus = cpu;
+ INFO("Found %d cpus\n", dynamic_platform_info.num_cpus);
+
+ read_cpu_topology_from_dt(dtb);
+}
+
+static void read_meminfo_from_dt(void *dtb)
+{
+ const fdt32_t *prop;
+ const char *type;
+ int prev, node;
+ int len;
+ uint32_t memnode = 0;
+ uint32_t higher_value, lower_value;
+ uint64_t cur_base, cur_size;
+
+ /*
+ * QEMU gives us this DeviceTree node:
+ *
+ * memory@100c0000000 {
+ * numa-node-id = <0x01>;
+ * reg = <0x100 0xc0000000 0x00 0x40000000>;
+ * device_type = "memory";
+ * };
+ *
+ * memory@10000000000 {
+ * numa-node-id = <0x00>;
+ * reg = <0x100 0x00 0x00 0xc0000000>;
+ * device_type = "memory";
+ * }
+ */
+
+ for (prev = 0;; prev = node) {
+ node = fdt_next_node(dtb, prev, NULL);
+ if (node < 0) {
+ break;
+ }
+
+ type = fdt_getprop(dtb, node, "device_type", &len);
+ if (type && strncmp(type, "memory", len) == 0) {
+ dynamic_platform_info.memory[memnode].nodeid =
+ fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
+
+ /*
+ * Get the 'reg' property of this node and
+ * assume two 8 bytes for base and size.
+ */
+ prop = fdt_getprop(dtb, node, "reg", &len);
+ if (prop != 0 && len == (2 * sizeof(int64_t))) {
+ higher_value = fdt32_to_cpu(*prop);
+ lower_value = fdt32_to_cpu(*(prop + 1));
+ cur_base = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
+
+ higher_value = fdt32_to_cpu(*(prop + 2));
+ lower_value = fdt32_to_cpu(*(prop + 3));
+ cur_size = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
+
+ dynamic_platform_info.memory[memnode].addr_base = cur_base;
+ dynamic_platform_info.memory[memnode].addr_size = cur_size;
+
+ INFO("RAM %d: node-id: %d, address: 0x%lx - 0x%lx\n",
+ memnode,
+ dynamic_platform_info.memory[memnode].nodeid,
+ dynamic_platform_info.memory[memnode].addr_base,
+ dynamic_platform_info.memory[memnode].addr_base +
+ dynamic_platform_info.memory[memnode].addr_size - 1);
+ }
+
+ memnode++;
+ }
+ }
+
+ dynamic_platform_info.num_memnodes = memnode;
+}
+
+static void read_platform_config_from_dt(void *dtb)
+{
+ int node;
+ const fdt64_t *data;
+ int err;
+ uintptr_t gicd_base;
+ uintptr_t gicr_base;
+
+ /*
+ * QEMU gives us this DeviceTree node:
+ *
+ * intc {
+ * reg = < 0x00 0x40060000 0x00 0x10000
+ * 0x00 0x40080000 0x00 0x4000000>;
+ * its {
+ * reg = <0x00 0x44081000 0x00 0x20000>;
+ * };
+ * };
+ */
+ node = fdt_path_offset(dtb, "/intc");
+ if (node < 0) {
+ return;
+ }
+
+ data = fdt_getprop(dtb, node, "reg", NULL);
+ if (data == NULL) {
+ return;
+ }
+
+ err = fdt_get_reg_props_by_index(dtb, node, 0, &gicd_base, NULL);
+ if (err < 0) {
+ ERROR("Failed to read GICD reg property of GIC node\n");
+ return;
+ }
+ INFO("GICD base = 0x%lx\n", gicd_base);
+
+ err = fdt_get_reg_props_by_index(dtb, node, 1, &gicr_base, NULL);
+ if (err < 0) {
+ ERROR("Failed to read GICR reg property of GIC node\n");
+ return;
+ }
+ INFO("GICR base = 0x%lx\n", gicr_base);
+
+ sbsa_set_gic_bases(gicd_base, gicr_base);
+
+ node = fdt_path_offset(dtb, "/intc/its");
+ if (node < 0) {
+ return;
+ }
+
+ err = fdt_get_reg_props_by_index(dtb, node, 0, &gic_its_addr, NULL);
+ if (err < 0) {
+ ERROR("Failed to read GICI reg property of GIC node\n");
+ return;
+ }
+ INFO("GICI base = 0x%lx\n", gic_its_addr);
+}
+
+static void read_platform_version(void *dtb)
+{
+ int node;
+
+ node = fdt_path_offset(dtb, "/");
+ if (node >= 0) {
+ platform_version_major =
+ fdt_read_uint32_default(dtb, node, "machine-version-major", 0);
+ platform_version_minor =
+ fdt_read_uint32_default(dtb, node, "machine-version-minor", 0);
+ }
+}
+
+#if !ENABLE_RME
+static int set_system_memory_base(void *dtb, uintptr_t new_base)
+{
+ (void)dtb;
+ (void)new_base;
+
+ return 0;
+}
+#else /* !ENABLE_RME */
+static int set_system_memory_base(void *dtb, uintptr_t new_base)
+{
+ uint64_t cur_base, cur_size, new_size, delta;
+ int len, prev, node, ret;
+ const fdt32_t *prop;
+ uint32_t node_id;
+ const char *type;
+ fdt64_t new[2];
+
+ /*
+ * QEMU gives us this DeviceTree node:
+ *
+ * memory@100c0000000 {
+ * numa-node-id = <0x01>;
+ * reg = <0x100 0xc0000000 0x00 0x40000000>;
+ * device_type = "memory";
+ * };
+ *
+ * memory@10000000000 {
+ * numa-node-id = <0x00>;
+ * reg = <0x100 0x00 0x00 0xc0000000>;
+ * device_type = "memory";
+ * }
+ */
+
+ for (prev = 0;; prev = node) {
+ node = fdt_next_node(dtb, prev, NULL);
+ if (node < 0) {
+ return node;
+ }
+
+ type = fdt_getprop(dtb, node, "device_type", &len);
+ if (type && strncmp(type, "memory", len) == 0) {
+
+ /*
+ * We are looking for numa node 0, i.e the start of the
+ * system memory. If a "numa-node-id" doesn't exists we
+ * take the first one.
+ */
+ node_id = fdt_read_uint32_default(dtb, node,
+ "numa-node-id", 0);
+
+ if (node_id == 0) {
+ break;
+ }
+ }
+ }
+
+ /*
+ * Get the 'reg' property of this node and
+ * assume two 8 bytes for base and size.
+ */
+ prop = fdt_getprop(dtb, node, "reg", &len);
+ if (!prop || len < 0) {
+ return len;
+ }
+
+ if (len != (2 * sizeof(uint64_t))) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ ret = fdt_get_reg_props_by_index(dtb, node, 0, &cur_base, &cur_size);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * @cur_base is the base of the NS RAM given to us by QEMU, we can't
+ * go lower than that.
+ */
+ if (new_base < cur_base) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ if (new_base == cur_base) {
+ return 0;
+ }
+
+ /*
+ * The new base is higher than the base set by QEMU, i.e we are moving
+ * the base memory up and shrinking the size.
+ */
+ delta = (size_t)(new_base - cur_base);
+
+ /*
+ * Make sure the new base is still within the base memory node, i.e
+ * the base memory node is big enough for the RMM.
+ */
+ if (delta >= cur_size) {
+ ERROR("Not enough space in base memory node for RMM\n");
+ return -FDT_ERR_BADVALUE;
+ }
+
+ new_size = cur_size - delta;
+
+ new[0] = cpu_to_fdt64(new_base);
+ new[1] = cpu_to_fdt64(new_size);
+
+ ret = fdt_setprop(dtb, node, "reg", new, len);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return fdt_pack(dtb);
+}
+#endif /* !ENABLE_RME */
+
+void sbsa_platform_init(void)
+{
+ /* Read DeviceTree data before MMU is enabled */
+
+ void *dtb = plat_qemu_dt_runtime_address();
+ int err;
+
+ err = fdt_open_into(dtb, dtb, PLAT_QEMU_DT_MAX_SIZE);
+ if (err < 0) {
+ ERROR("Invalid Device Tree at %p: error %d\n", dtb, err);
+ return;
+ }
+
+ err = fdt_check_header(dtb);
+ if (err < 0) {
+ ERROR("Invalid DTB file passed\n");
+ return;
+ }
+
+ read_platform_version(dtb);
+ INFO("Platform version: %d.%d\n", platform_version_major, platform_version_minor);
+
+ if (set_system_memory_base(dtb, NS_DRAM0_BASE)) {
+ ERROR("Failed to set system memory in Device Tree\n");
+ return;
+ }
+
+ read_platform_config_from_dt(dtb);
+ read_cpuinfo_from_dt(dtb);
+ read_meminfo_from_dt(dtb);
+}
+
+int sbsa_platform_version_major(void)
+{
+ return platform_version_major;
+}
+
+int sbsa_platform_version_minor(void)
+{
+ return platform_version_minor;
+}
+
+uint32_t sbsa_platform_num_cpus(void)
+{
+ return dynamic_platform_info.num_cpus;
+}
+
+uint32_t sbsa_platform_num_memnodes(void)
+{
+ return dynamic_platform_info.num_memnodes;
+}
+
+uint64_t sbsa_platform_gic_its_addr(void)
+{
+ return gic_its_addr;
+}
+
+struct platform_cpu_data sbsa_platform_cpu_node(uint64_t index)
+{
+ return dynamic_platform_info.cpu[index];
+}
+
+struct platform_memory_data sbsa_platform_memory_node(uint64_t index)
+{
+ return dynamic_platform_info.memory[index];
+}
+
+struct platform_cpu_topology sbsa_platform_cpu_topology(void)
+{
+ return dynamic_platform_info.cpu_topo;
+}
diff --git a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
index 83e66f3..839bb1c 100644
--- a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
+++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
@@ -6,14 +6,10 @@
#include <assert.h>
-#include <common/fdt_wrappers.h>
#include <common/runtime_svc.h>
-#include <libfdt.h>
#include <smccc_helpers.h>
-/* default platform version is 0.0 */
-static int platform_version_major;
-static int platform_version_minor;
+#include <sbsa_platform.h>
#define SMC_FASTCALL 0x80000000
#define SMC64_FUNCTION (SMC_FASTCALL | 0x40000000)
@@ -34,326 +30,10 @@
#define SIP_SVC_GET_MEMORY_NODE_COUNT SIP_FUNCTION_ID(300)
#define SIP_SVC_GET_MEMORY_NODE SIP_FUNCTION_ID(301)
-static uint64_t gic_its_addr;
-
-typedef struct {
- uint32_t nodeid;
- uint32_t mpidr;
-} cpu_data;
-
-typedef struct{
- uint32_t nodeid;
- uint64_t addr_base;
- uint64_t addr_size;
-} memory_data;
-
-/*
- * sockets: the number of sockets on sbsa-ref platform.
- * clusters: the number of clusters in one socket.
- * cores: the number of cores in one cluster.
- * threads: the number of threads in one core.
- */
-typedef struct {
- uint32_t sockets;
- uint32_t clusters;
- uint32_t cores;
- uint32_t threads;
-} cpu_topology;
-
-static struct {
- uint32_t num_cpus;
- uint32_t num_memnodes;
- cpu_data cpu[PLATFORM_CORE_COUNT];
- cpu_topology cpu_topo;
- memory_data memory[PLAT_MAX_MEM_NODES];
-} dynamic_platform_info;
-
-void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base);
uintptr_t sbsa_get_gicd(void);
uintptr_t sbsa_get_gicr(void);
/*
- * QEMU provides us with minimal information about hardware platform using
- * minimalistic DeviceTree. This is not a Linux DeviceTree. It is not even
- * a firmware DeviceTree.
- *
- * It is information passed from QEMU to describe the information a hardware
- * platform would have other mechanisms to discover at runtime, that are
- * affected by the QEMU command line.
- *
- * Ultimately this device tree will be replaced by IPC calls to an emulated SCP.
- * And when we do that, we won't then have to rewrite Normal world firmware to
- * cope.
- */
-
-static void read_cpu_topology_from_dt(void *dtb)
-{
- int node;
-
- /*
- * QEMU gives us this DeviceTree node when we config:
- * -smp 16,sockets=2,clusters=2,cores=2,threads=2
- *
- * topology {
- * threads = <0x02>;
- * cores = <0x02>;
- * clusters = <0x02>;
- * sockets = <0x02>;
- * };
- */
-
- node = fdt_path_offset(dtb, "/cpus/topology");
- if (node > 0) {
- dynamic_platform_info.cpu_topo.sockets =
- fdt_read_uint32_default(dtb, node, "sockets", 0);
- dynamic_platform_info.cpu_topo.clusters =
- fdt_read_uint32_default(dtb, node, "clusters", 0);
- dynamic_platform_info.cpu_topo.cores =
- fdt_read_uint32_default(dtb, node, "cores", 0);
- dynamic_platform_info.cpu_topo.threads =
- fdt_read_uint32_default(dtb, node, "threads", 0);
- }
-
- INFO("Cpu topology: sockets: %d, clusters: %d, cores: %d, threads: %d\n",
- dynamic_platform_info.cpu_topo.sockets,
- dynamic_platform_info.cpu_topo.clusters,
- dynamic_platform_info.cpu_topo.cores,
- dynamic_platform_info.cpu_topo.threads);
-}
-
-void read_cpuinfo_from_dt(void *dtb)
-{
- int node;
- int prev;
- int cpu = 0;
- uintptr_t mpidr;
-
- /*
- * QEMU gives us this DeviceTree node:
- * numa-node-id entries are only when NUMA config is used
- *
- * cpus {
- * #size-cells = <0x00>;
- * #address-cells = <0x02>;
- *
- * cpu@0 {
- * numa-node-id = <0x00>;
- * reg = <0x00 0x00>;
- * };
- *
- * cpu@1 {
- * numa-node-id = <0x03>;
- * reg = <0x00 0x01>;
- * };
- * };
- */
- node = fdt_path_offset(dtb, "/cpus");
- if (node < 0) {
- ERROR("No information about cpus in DeviceTree.\n");
- panic();
- }
-
- /*
- * QEMU numbers cpus from 0 and there can be /cpus/cpu-map present so we
- * cannot use fdt_first_subnode() here
- */
- node = fdt_path_offset(dtb, "/cpus/cpu@0");
-
- while (node > 0) {
- if (fdt_getprop(dtb, node, "reg", NULL)) {
- fdt_get_reg_props_by_index(dtb, node, 0, &mpidr, NULL);
- } else {
- ERROR("Incomplete information for cpu %d in DeviceTree.\n", cpu);
- panic();
- }
-
- dynamic_platform_info.cpu[cpu].mpidr = mpidr;
- dynamic_platform_info.cpu[cpu].nodeid =
- fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
-
- INFO("CPU %d: node-id: %d, mpidr: %ld\n", cpu,
- dynamic_platform_info.cpu[cpu].nodeid, mpidr);
-
- cpu++;
-
- prev = node;
- node = fdt_next_subnode(dtb, prev);
- }
-
- dynamic_platform_info.num_cpus = cpu;
- INFO("Found %d cpus\n", dynamic_platform_info.num_cpus);
-
- read_cpu_topology_from_dt(dtb);
-}
-
-void read_meminfo_from_dt(void *dtb)
-{
- const fdt32_t *prop;
- const char *type;
- int prev, node;
- int len;
- uint32_t memnode = 0;
- uint32_t higher_value, lower_value;
- uint64_t cur_base, cur_size;
-
- /*
- * QEMU gives us this DeviceTree node:
- *
- * memory@100c0000000 {
- * numa-node-id = <0x01>;
- * reg = <0x100 0xc0000000 0x00 0x40000000>;
- * device_type = "memory";
- * };
- *
- * memory@10000000000 {
- * numa-node-id = <0x00>;
- * reg = <0x100 0x00 0x00 0xc0000000>;
- * device_type = "memory";
- * }
- */
-
- for (prev = 0;; prev = node) {
- node = fdt_next_node(dtb, prev, NULL);
- if (node < 0) {
- break;
- }
-
- type = fdt_getprop(dtb, node, "device_type", &len);
- if (type && strncmp(type, "memory", len) == 0) {
- dynamic_platform_info.memory[memnode].nodeid =
- fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
-
- /*
- * Get the 'reg' property of this node and
- * assume two 8 bytes for base and size.
- */
- prop = fdt_getprop(dtb, node, "reg", &len);
- if (prop != 0 && len == (2 * sizeof(int64_t))) {
- higher_value = fdt32_to_cpu(*prop);
- lower_value = fdt32_to_cpu(*(prop + 1));
- cur_base = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
-
- higher_value = fdt32_to_cpu(*(prop + 2));
- lower_value = fdt32_to_cpu(*(prop + 3));
- cur_size = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
-
- dynamic_platform_info.memory[memnode].addr_base = cur_base;
- dynamic_platform_info.memory[memnode].addr_size = cur_size;
-
- INFO("RAM %d: node-id: %d, address: 0x%lx - 0x%lx\n",
- memnode,
- dynamic_platform_info.memory[memnode].nodeid,
- dynamic_platform_info.memory[memnode].addr_base,
- dynamic_platform_info.memory[memnode].addr_base +
- dynamic_platform_info.memory[memnode].addr_size - 1);
- }
-
- memnode++;
- }
- }
-
- dynamic_platform_info.num_memnodes = memnode;
-}
-
-void read_platform_config_from_dt(void *dtb)
-{
- int node;
- const fdt64_t *data;
- int err;
- uintptr_t gicd_base;
- uintptr_t gicr_base;
-
- /*
- * QEMU gives us this DeviceTree node:
- *
- * intc {
- * reg = < 0x00 0x40060000 0x00 0x10000
- * 0x00 0x40080000 0x00 0x4000000>;
- * its {
- * reg = <0x00 0x44081000 0x00 0x20000>;
- * };
- * };
- */
- node = fdt_path_offset(dtb, "/intc");
- if (node < 0) {
- return;
- }
-
- data = fdt_getprop(dtb, node, "reg", NULL);
- if (data == NULL) {
- return;
- }
-
- err = fdt_get_reg_props_by_index(dtb, node, 0, &gicd_base, NULL);
- if (err < 0) {
- ERROR("Failed to read GICD reg property of GIC node\n");
- return;
- }
- INFO("GICD base = 0x%lx\n", gicd_base);
-
- err = fdt_get_reg_props_by_index(dtb, node, 1, &gicr_base, NULL);
- if (err < 0) {
- ERROR("Failed to read GICR reg property of GIC node\n");
- return;
- }
- INFO("GICR base = 0x%lx\n", gicr_base);
-
- sbsa_set_gic_bases(gicd_base, gicr_base);
-
- node = fdt_path_offset(dtb, "/intc/its");
- if (node < 0) {
- return;
- }
-
- err = fdt_get_reg_props_by_index(dtb, node, 0, &gic_its_addr, NULL);
- if (err < 0) {
- ERROR("Failed to read GICI reg property of GIC node\n");
- return;
- }
- INFO("GICI base = 0x%lx\n", gic_its_addr);
-}
-
-void read_platform_version(void *dtb)
-{
- int node;
-
- node = fdt_path_offset(dtb, "/");
- if (node >= 0) {
- platform_version_major =
- fdt_read_uint32_default(dtb, node, "machine-version-major", 0);
- platform_version_minor =
- fdt_read_uint32_default(dtb, node, "machine-version-minor", 0);
- }
-}
-
-void sip_svc_init(void)
-{
- /* Read DeviceTree data before MMU is enabled */
-
- void *dtb = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
- int err;
-
- err = fdt_open_into(dtb, dtb, PLAT_QEMU_DT_MAX_SIZE);
- if (err < 0) {
- ERROR("Invalid Device Tree at %p: error %d\n", dtb, err);
- return;
- }
-
- err = fdt_check_header(dtb);
- if (err < 0) {
- ERROR("Invalid DTB file passed\n");
- return;
- }
-
- read_platform_version(dtb);
- INFO("Platform version: %d.%d\n", platform_version_major, platform_version_minor);
-
- read_platform_config_from_dt(dtb);
- read_cpuinfo_from_dt(dtb);
- read_meminfo_from_dt(dtb);
-}
-
-/*
* This function is responsible for handling all SiP calls from the NS world
*/
uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid,
@@ -378,49 +58,56 @@
switch (smc_fid) {
case SIP_SVC_VERSION:
INFO("Platform version requested\n");
- SMC_RET3(handle, NULL, platform_version_major, platform_version_minor);
+ SMC_RET3(handle, NULL, sbsa_platform_version_major(),
+ sbsa_platform_version_minor());
case SIP_SVC_GET_GIC:
SMC_RET3(handle, NULL, sbsa_get_gicd(), sbsa_get_gicr());
case SIP_SVC_GET_GIC_ITS:
- SMC_RET2(handle, NULL, gic_its_addr);
+ SMC_RET2(handle, NULL, sbsa_platform_gic_its_addr());
case SIP_SVC_GET_CPU_COUNT:
- SMC_RET2(handle, NULL, dynamic_platform_info.num_cpus);
+ SMC_RET2(handle, NULL, sbsa_platform_num_cpus());
case SIP_SVC_GET_CPU_NODE:
index = x1;
if (index < PLATFORM_CORE_COUNT) {
- SMC_RET3(handle, NULL,
- dynamic_platform_info.cpu[index].nodeid,
- dynamic_platform_info.cpu[index].mpidr);
+ struct platform_cpu_data data;
+
+ data = sbsa_platform_cpu_node(index);
+
+ SMC_RET3(handle, NULL, data.nodeid, data.mpidr);
} else {
SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
}
case SIP_SVC_GET_CPU_TOPOLOGY:
- if (dynamic_platform_info.cpu_topo.cores > 0) {
- SMC_RET5(handle, NULL,
- dynamic_platform_info.cpu_topo.sockets,
- dynamic_platform_info.cpu_topo.clusters,
- dynamic_platform_info.cpu_topo.cores,
- dynamic_platform_info.cpu_topo.threads);
+ struct platform_cpu_topology topology;
+
+ topology = sbsa_platform_cpu_topology();
+
+ if (topology.cores > 0) {
+ SMC_RET5(handle, NULL, topology.sockets,
+ topology.clusters, topology.cores,
+ topology.threads);
} else {
/* we do not know topology so we report SMC as unknown */
SMC_RET1(handle, SMC_UNK);
}
case SIP_SVC_GET_MEMORY_NODE_COUNT:
- SMC_RET2(handle, NULL, dynamic_platform_info.num_memnodes);
+ SMC_RET2(handle, NULL, sbsa_platform_num_memnodes());
case SIP_SVC_GET_MEMORY_NODE:
index = x1;
if (index < PLAT_MAX_MEM_NODES) {
- SMC_RET4(handle, NULL,
- dynamic_platform_info.memory[index].nodeid,
- dynamic_platform_info.memory[index].addr_base,
- dynamic_platform_info.memory[index].addr_size);
+ struct platform_memory_data data;
+
+ data = sbsa_platform_memory_node(index);
+
+ SMC_RET4(handle, NULL, data.nodeid,
+ data.addr_base, data.addr_size);
} else {
SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
}
diff --git a/plat/qemu/qemu_sbsa/trp/trp-qemu_sbsa.mk b/plat/qemu/qemu_sbsa/trp/trp-qemu_sbsa.mk
new file mode 100644
index 0000000..07ccac0
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/trp/trp-qemu_sbsa.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2024-2025, Linaro Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/qemu/common/trp/trp-qemu-common.mk
+
diff --git a/plat/qti/common/src/qti_gic_v3.c b/plat/qti/common/src/qti_gic_v3.c
index f00267a..746c6f1 100644
--- a/plat/qti/common/src/qti_gic_v3.c
+++ b/plat/qti/common/src/qti_gic_v3.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, The Linux Foundation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -54,24 +54,36 @@
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
#endif
+#ifdef QTISECLIB_INT_ID_A2_NOC_ERROR
INTR_PROP_DESC(QTISECLIB_INT_ID_A2_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_CONFIG_NOC_ERROR
INTR_PROP_DESC(QTISECLIB_INT_ID_CONFIG_NOC_ERROR,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_DC_NOC_ERROR
INTR_PROP_DESC(QTISECLIB_INT_ID_DC_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_MEM_NOC_ERROR
INTR_PROP_DESC(QTISECLIB_INT_ID_MEM_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_SYSTEM_NOC_ERROR
INTR_PROP_DESC(QTISECLIB_INT_ID_SYSTEM_NOC_ERROR,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
+#endif
+#ifdef QTISECLIB_INT_ID_MMSS_NOC_ERROR
INTR_PROP_DESC(QTISECLIB_INT_ID_MMSS_NOC_ERROR,
GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
GIC_INTR_CFG_EDGE),
+#endif
#ifdef QTISECLIB_INT_ID_LPASS_AGNOC_ERROR
INTR_PROP_DESC(QTISECLIB_INT_ID_LPASS_AGNOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0,
diff --git a/plat/qti/qcs615/inc/platform_def.h b/plat/qti/qcs615/inc/platform_def.h
new file mode 100644
index 0000000..5b8ff7d
--- /dev/null
+++ b/plat/qti/qcs615/inc/platform_def.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+/* Enable the dynamic translation tables library. */
+#define PLAT_XLAT_TABLES_DYNAMIC 1
+
+#include <common_def.h>
+
+#include <qti_board_def.h>
+#include <qtiseclib_defs_plat.h>
+
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/*
+ * MPIDR_PRIMARY_CPU
+ * You just need to have the correct core_affinity_val i.e. [7:0]
+ * and cluster_affinity_val i.e. [15:8]
+ * the other bits will be ignored
+ */
+/*----------------------------------------------------------------------------*/
+#define MPIDR_PRIMARY_CPU 0x0000
+/*----------------------------------------------------------------------------*/
+
+#define QTI_PWR_LVL0 MPIDR_AFFLVL0
+#define QTI_PWR_LVL1 MPIDR_AFFLVL1
+#define QTI_PWR_LVL2 MPIDR_AFFLVL2
+#define QTI_PWR_LVL3 MPIDR_AFFLVL3
+
+/*
+ * Macros for local power states encoded by State-ID field
+ * within the power-state parameter.
+ */
+/* Local power state for power domains in Run state. */
+#define QTI_LOCAL_STATE_RUN 0
+/*
+ * Local power state for clock-gating. Valid only for CPU and not cluster power
+ * domains
+ */
+#define QTI_LOCAL_STATE_STB 1
+/*
+ * Local power state for retention. Valid for CPU and cluster power
+ * domains
+ */
+#define QTI_LOCAL_STATE_RET 2
+/*
+ * Local power state for OFF/power down. Valid for CPU, cluster, RSC and PDC
+ * power domains
+ */
+#define QTI_LOCAL_STATE_OFF 3
+/*
+ * Local power state for DEEPOFF/power rail down. Valid for CPU, cluster and RSC
+ * power domains
+ */
+#define QTI_LOCAL_STATE_DEEPOFF 4
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE QTI_LOCAL_STATE_RET
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE QTI_LOCAL_STATE_DEEPOFF
+
+/******************************************************************************
+ * Required platform porting definitions common to all ARM standard platforms
+ *****************************************************************************/
+
+/*
+ * Platform specific page table and MMU setup constants.
+ */
+#define MAX_MMAP_REGIONS (PLAT_QTI_MMAP_ENTRIES)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 36)
+
+#define ARM_CACHE_WRITEBACK_SHIFT 6
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_GRANULE (1 << ARM_CACHE_WRITEBACK_SHIFT)
+
+/*
+ * One cache line needed for bakery locks on ARM platforms
+ */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
+
+/*----------------------------------------------------------------------------*/
+/* PSCI power domain topology definitions */
+/*----------------------------------------------------------------------------*/
+/* One domain each to represent RSC and PDC level */
+#define PLAT_PDC_COUNT 1
+#define PLAT_RSC_COUNT 1
+
+/* There is one top-level FCM cluster */
+#define PLAT_CLUSTER_COUNT 1
+
+/* No. of cores in the FCM cluster */
+#define PLAT_CLUSTER0_CORE_COUNT 8
+
+#define PLATFORM_CORE_COUNT (PLAT_CLUSTER0_CORE_COUNT)
+
+#define PLAT_NUM_PWR_DOMAINS (PLAT_PDC_COUNT +\
+ PLAT_RSC_COUNT +\
+ PLAT_CLUSTER_COUNT +\
+ PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL 3
+
+/*****************************************************************************/
+/* Memory mapped Generic timer interfaces */
+/*****************************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/* GIC-600 constants */
+/*----------------------------------------------------------------------------*/
+#define BASE_GICD_BASE 0x17A00000
+#define BASE_GICR_BASE 0x17A60000
+#define BASE_GICC_BASE 0x0
+#define BASE_GICH_BASE 0x0
+#define BASE_GICV_BASE 0x0
+
+#define QTI_GICD_BASE BASE_GICD_BASE
+#define QTI_GICR_BASE BASE_GICR_BASE
+#define QTI_GICC_BASE BASE_GICC_BASE
+
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/* UART related constants. */
+/*----------------------------------------------------------------------------*/
+/* BASE ADDRESS OF DIFFERENT REGISTER SPACES IN HW */
+#define GENI4_CFG 0x0
+#define GENI4_IMAGE_REGS 0x100
+#define GENI4_DATA 0x600
+
+/* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */
+#define GENI_STATUS_REG (GENI4_CFG + 0x00000040)
+#define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK (0x1)
+#define UART_TX_TRANS_LEN_REG (GENI4_IMAGE_REGS + 0x00000170)
+/* MASTER/TX ENGINE REGISTERS */
+#define GENI_M_CMD0_REG (GENI4_DATA + 0x00000000)
+/* FIFO, STATUS REGISTERS AND MASKS */
+#define GENI_TX_FIFOn_REG (GENI4_DATA + 0x00000100)
+
+#define GENI_M_CMD_TX (0x08000000)
+
+/*----------------------------------------------------------------------------*/
+/* Device address space for mapping. Excluding starting 4K */
+/*----------------------------------------------------------------------------*/
+#define QTI_DEVICE_BASE 0x1000
+#define QTI_DEVICE_SIZE (0x80000000 - QTI_DEVICE_BASE)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at DDR as per memory map. BL31_BASE is calculated using the
+ * current BL31 debug size plus a little space for growth.
+ */
+#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
+
+/*----------------------------------------------------------------------------*/
+/* AOSS registers */
+/*----------------------------------------------------------------------------*/
+#define QTI_PS_HOLD_REG 0x0C264000
+/*----------------------------------------------------------------------------*/
+/* AOP CMD DB address space for mapping */
+/*----------------------------------------------------------------------------*/
+#define QTI_AOP_CMD_DB_BASE 0x85F20000
+#define QTI_AOP_CMD_DB_SIZE 0x00020000
+/*----------------------------------------------------------------------------*/
+/* SOC hw version register */
+/*----------------------------------------------------------------------------*/
+#define QTI_SOC_VERSION_MASK U(0xFFFF)
+#define QTI_SOC_REVISION_REG 0x1FC8000
+#define QTI_SOC_REVISION_MASK U(0xFFFF)
+/*----------------------------------------------------------------------------*/
+/* LC PON register offsets */
+/*----------------------------------------------------------------------------*/
+#define PON_PS_HOLD_RESET_CTL 0x85a
+#define PON_PS_HOLD_RESET_CTL2 0x85b
+/*----------------------------------------------------------------------------*/
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/qti/qcs615/inc/qti_map_chipinfo.h b/plat/qti/qcs615/inc/qti_map_chipinfo.h
new file mode 100644
index 0000000..6092ea0
--- /dev/null
+++ b/plat/qti/qcs615/inc/qti_map_chipinfo.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_MAP_CHIPINFO_H
+#define QTI_MAP_CHIPINFO_H
+
+#include <stdint.h>
+
+#include <qti_plat.h>
+
+#define QTI_JTAG_ID_REG 0x786130
+#define QTI_JTAG_ID_SHIFT 12
+#define QTI_JTAG_ID_QCS615 U(0x02E9)
+#define QTI_JTAG_ID_SA6155P U(0x00EE)
+#define QTI_CHIPINFO_ID_QCS615 U(0x01E7)
+#define QTI_CHIPINFO_ID_SA6155P U(0x0179)
+#define QTI_DEFAULT_CHIPINFO_ID U(0xFFFF)
+
+static const chip_id_info_t g_map_jtag_chipinfo_id[] = {
+ {QTI_JTAG_ID_QCS615, QTI_CHIPINFO_ID_QCS615},
+ {QTI_JTAG_ID_SA6155P, QTI_CHIPINFO_ID_SA6155P},
+};
+
+#endif /* QTI_MAP_CHIPINFO_H */
diff --git a/plat/qti/qcs615/inc/qti_rng_io.h b/plat/qti/qcs615/inc/qti_rng_io.h
new file mode 100644
index 0000000..b5e521e
--- /dev/null
+++ b/plat/qti/qcs615/inc/qti_rng_io.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef QTI_RNG_IO_H
+#define QTI_RNG_IO_H
+
+#define SEC_PRNG_STATUS 0x791004
+#define SEC_PRNG_STATUS_DATA_AVAIL_BMSK 0x1
+#define SEC_PRNG_DATA_OUT 0x791000
+
+#endif /* QTI_RNG_IO_H */
+
diff --git a/plat/qti/qcs615/inc/qti_secure_io_cfg.h b/plat/qti/qcs615/inc/qti_secure_io_cfg.h
new file mode 100644
index 0000000..a78583e
--- /dev/null
+++ b/plat/qti/qcs615/inc/qti_secure_io_cfg.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_SECURE_IO_CFG_H
+#define QTI_SECURE_IO_CFG_H
+
+#include <stdint.h>
+
+/*
+ * List of peripheral/IO memory areas that are protected from
+ * non-secure world but not required to be secure.
+ */
+#define APPS_SMMU_TBU_PWR_STATUS 0x15002204
+#define APPS_SMMU_CUSTOM_CFG 0x15002300
+#define APPS_SMMU_STATS_SYNC_INV_TBU_ACK 0x150025DC
+#define APPS_SMMU_SAFE_SEC_CFG 0x15002644
+#define APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR 0x15002648
+
+static const uintptr_t qti_secure_io_allowed_regs[] = {
+ APPS_SMMU_TBU_PWR_STATUS,
+ APPS_SMMU_CUSTOM_CFG,
+ APPS_SMMU_STATS_SYNC_INV_TBU_ACK,
+ APPS_SMMU_SAFE_SEC_CFG,
+ APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR,
+};
+
+static const uintptr_t qti_secure_io_debug_allowed_regs[] = {
+};
+
+
+#endif /* QTI_SECURE_IO_CFG_H */
diff --git a/plat/qti/qcs615/platform.mk b/plat/qti/qcs615/platform.mk
new file mode 100644
index 0000000..a3136cb
--- /dev/null
+++ b/plat/qti/qcs615/platform.mk
@@ -0,0 +1,142 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, The Linux Foundation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Makefile for QCS615 QTI platform.
+
+QTI_PLAT_PATH := plat/qti
+CHIPSET := ${PLAT}
+
+# Turn On Separate code & data.
+SEPARATE_CODE_AND_RODATA := 1
+USE_COHERENT_MEM := 0
+WARMBOOT_ENABLE_DCACHE_EARLY := 1
+HW_ASSISTED_COHERENCY := 1
+
+# Enable errata configs for cortex_a76 and cortex_a55
+# QCS615 CPU core revisions are r1p0
+ERRATA_A55_1221012 := 1
+ERRATA_A55_1530923 := 1
+ERRATA_A76_1073348 := 1
+ERRATA_A76_1130799 := 1
+ERRATA_A76_1220197 := 1
+ERRATA_A76_1257314 := 1
+ERRATA_A76_1262606 := 1
+ERRATA_A76_1262888 := 1
+ERRATA_A76_1275112 := 1
+ERRATA_A76_1791580 := 1
+ERRATA_A76_1165522 := 1
+ERRATA_A76_1868343 := 1
+ERRATA_A76_1946160 := 1
+ERRATA_A76_2743102 := 1
+
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT := 0
+
+# Enable PSCI v1.0 extended state ID format
+PSCI_EXTENDED_STATE_ID := 1
+ARM_RECOM_STATE_ID_ENC := 1
+PSCI_OS_INIT_MODE := 1
+
+COLD_BOOT_SINGLE_CPU := 1
+PROGRAMMABLE_RESET_ADDRESS := 1
+
+RESET_TO_BL31 := 0
+
+QTI_SDI_BUILD := 0
+$(eval $(call assert_boolean,QTI_SDI_BUILD))
+$(eval $(call add_define,QTI_SDI_BUILD))
+
+#disable CTX_INCLUDE_AARCH32_REGS to support QCS615 gold cores
+override CTX_INCLUDE_AARCH32_REGS := 0
+
+# Set dynamic CVE_2018_3639 explicitly as it defaults to 0.
+# Others which are applicable: CVE_2017_5715 & CVE_2022_23960 default to 1
+DYNAMIC_WORKAROUND_CVE_2018_3639 := 1
+
+# Enable stack protector.
+ENABLE_STACK_PROTECTOR := strong
+
+
+QTI_EXTERNAL_INCLUDES := -I${QTI_PLAT_PATH}/${CHIPSET}/inc \
+ -I${QTI_PLAT_PATH}/common/inc \
+ -I${QTI_PLAT_PATH}/common/inc/$(ARCH) \
+ -I${QTI_PLAT_PATH}/qtiseclib/inc \
+ -I${QTI_PLAT_PATH}/qtiseclib/inc/${CHIPSET} \
+
+QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \
+ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_silver.S \
+ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_gold.S \
+ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S \
+ $(QTI_PLAT_PATH)/common/src/pm_ps_hold.c \
+ $(QTI_PLAT_PATH)/common/src/qti_stack_protector.c \
+ $(QTI_PLAT_PATH)/common/src/qti_common.c \
+ $(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c \
+ $(QTI_PLAT_PATH)/common/src/qti_gic_v3.c \
+ $(QTI_PLAT_PATH)/common/src/qti_interrupt_svc.c \
+ $(QTI_PLAT_PATH)/common/src/qti_syscall.c \
+ $(QTI_PLAT_PATH)/common/src/qti_topology.c \
+ $(QTI_PLAT_PATH)/common/src/qti_pm.c \
+ $(QTI_PLAT_PATH)/common/src/qti_rng.c \
+ $(QTI_PLAT_PATH)/common/src/spmi_arb.c \
+ $(QTI_PLAT_PATH)/qtiseclib/src/qtiseclib_cb_interface.c \
+
+
+PLAT_INCLUDES := -Iinclude/plat/common/ \
+ ${QTI_EXTERNAL_INCLUDES}
+
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} \
+ plat/common/aarch64/crash_console_helpers.S \
+ common/desc_image_load.c \
+ lib/bl_aux_params/bl_aux_params.c \
+
+include lib/coreboot/coreboot.mk
+
+#PSCI Sources.
+PSCI_SOURCES := plat/common/plat_psci_common.c \
+
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600 := 1
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+#Timer sources
+TIMER_SOURCES := drivers/delay_timer/generic_delay_timer.c \
+ drivers/delay_timer/delay_timer.c \
+
+#GIC sources.
+GIC_SOURCES := plat/common/plat_gicv3.c \
+ ${GICV3_SOURCES} \
+
+CPU_SOURCES := lib/cpus/aarch64/cortex_a76.S \
+ lib/cpus/aarch64/cortex_a55.S \
+
+BL31_SOURCES += ${QTI_BL31_SOURCES} \
+ ${PSCI_SOURCES} \
+ ${GIC_SOURCES} \
+ ${TIMER_SOURCES} \
+ ${CPU_SOURCES} \
+
+LIB_QTI_PATH := ${QTI_PLAT_PATH}/qtiseclib/lib/${CHIPSET}
+
+
+# Override this on the command line to point to the qtiseclib library which
+# will be available in coreboot.org
+QTISECLIB_PATH ?=
+
+ifeq ($(QTISECLIB_PATH),)
+# if No lib then use stub implementation for qtiseclib interface
+$(warning QTISECLIB_PATH is not provided while building, using stub implementation. \
+ Please refer docs/plat/qti.rst for more details \
+ THIS FIRMWARE WILL NOT BOOT!)
+BL31_SOURCES += plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
+else
+# use library provided by QTISECLIB_PATH
+LDFLAGS += -L $(dir $(QTISECLIB_PATH))
+LDLIBS += -l$(patsubst lib%.a,%,$(notdir $(QTISECLIB_PATH)))
+endif
+
diff --git a/plat/qti/qtiseclib/inc/qcs615/qtiseclib_defs_plat.h b/plat/qti/qtiseclib/inc/qcs615/qtiseclib_defs_plat.h
new file mode 100644
index 0000000..2dbcc83
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/qcs615/qtiseclib_defs_plat.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __QTISECLIB_DEFS_PLAT_H__
+#define __QTISECLIB_DEFS_PLAT_H__
+
+#define QTISECLIB_PLAT_CLUSTER_COUNT 1
+#define QTISECLIB_PLAT_CORE_COUNT 8
+
+#define BL31_BASE 0x86200000
+#define BL31_SIZE 0x00100000
+
+/*----------------------------------------------------------------------------*/
+/* AOP CMD DB address space for mapping */
+/*----------------------------------------------------------------------------*/
+#define QTI_AOP_CMD_DB_BASE 0x85F20000
+#define QTI_AOP_CMD_DB_SIZE 0x00020000
+
+/* Chipset specific secure interrupt number/ID defs. */
+#define QTISECLIB_INT_ID_SEC_WDOG_BARK (0x204)
+#define QTISECLIB_INT_ID_NON_SEC_WDOG_BITE (0x21)
+
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC (0xE6)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC (0xE7)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC (0xE8)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC (0xE9)
+
+#define QTISECLIB_INT_ID_XPU_SEC (0xE3)
+#define QTISECLIB_INT_ID_XPU_NON_SEC (0xE4)
+
+//NOC INterrupt
+#define QTISECLIB_INT_ID_A1_NOC_ERROR (0x18B)
+#define QTISECLIB_INT_ID_CONFIG_NOC_ERROR (0xE2)
+#define QTISECLIB_INT_ID_DC_NOC_ERROR (0x122)
+#define QTISECLIB_INT_ID_MEM_NOC_ERROR (0x6C) //GEM_NOC
+#define QTISECLIB_INT_ID_SYSTEM_NOC_ERROR (0xC6)
+#define QTISECLIB_INT_ID_MMSS_NOC_ERROR (0xBA)
+
+#endif /* __QTISECLIB_DEFS_PLAT_H__ */
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 4813949..c19eb36 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -148,6 +148,13 @@
endif
$(eval $(call add_define,RCAR_RPC_HYPERFLASH_LOCKED))
+# Support A/B switching with RPC HYPERFLASH access by default
+# Use together with https://github.com/marex/abloader .
+ifndef RCAR_RPC_HYPERFLASH_ABLOADER
+RCAR_RPC_HYPERFLASH_ABLOADER := 0
+endif
+$(eval $(call add_define,RCAR_RPC_HYPERFLASH_ABLOADER))
+
# Process RCAR_SECURE_BOOT flag
ifndef RCAR_SECURE_BOOT
RCAR_SECURE_BOOT := 1
diff --git a/plat/rockchip/common/drivers/pmu/pmu_com.h b/plat/rockchip/common/drivers/pmu/pmu_com.h
index 022bb02..84f9421 100644
--- a/plat/rockchip/common/drivers/pmu/pmu_com.h
+++ b/plat/rockchip/common/drivers/pmu/pmu_com.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,8 +32,6 @@
};
#pragma weak plat_ic_get_pending_interrupt_id
-#pragma weak pmu_power_domain_ctr
-#pragma weak check_cpu_wfie
static inline uint32_t pmu_power_domain_st(uint32_t pd)
{
diff --git a/plat/rockchip/px30/drivers/pmu/pmu.c b/plat/rockchip/px30/drivers/pmu/pmu.c
index 8770b2e..0d8e8b6 100644
--- a/plat/rockchip/px30/drivers/pmu/pmu.c
+++ b/plat/rockchip/px30/drivers/pmu/pmu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -867,18 +867,6 @@
ERROR("Can't wait pll:%d lock\n", pll_id);
}
-static inline void pll_pwr_ctr(uint32_t pll_base, uint32_t pll_id, uint32_t pd)
-{
- mmio_write_32(pll_base + PLL_CON(1),
- BITS_WITH_WMASK(1, 1U, 15));
- if (pd)
- mmio_write_32(pll_base + PLL_CON(1),
- BITS_WITH_WMASK(1, 1, 14));
- else
- mmio_write_32(pll_base + PLL_CON(1),
- BITS_WITH_WMASK(0, 1, 14));
-}
-
static inline void pll_set_mode(uint32_t pll_id, uint32_t mode)
{
uint32_t val = BITS_WITH_WMASK(mode, 0x3, PLL_MODE_SHIFT(pll_id));
diff --git a/plat/rockchip/rk3288/drivers/pmu/pmu.c b/plat/rockchip/rk3288/drivers/pmu/pmu.c
index 085976c..9e17cff 100644
--- a/plat/rockchip/rk3288/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3288/drivers/pmu/pmu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -36,90 +36,6 @@
ROCKCHIP_ARM_OFF_LOGIC_DEEP = 1,
};
-static inline int rk3288_pmu_bus_idle(uint32_t req, uint32_t idle)
-{
- uint32_t mask = BIT(req);
- uint32_t idle_mask = 0;
- uint32_t idle_target = 0;
- uint32_t val;
- uint32_t wait_cnt = 0;
-
- switch (req) {
- case bus_ide_req_gpu:
- idle_mask = BIT(pmu_idle_ack_gpu) | BIT(pmu_idle_gpu);
- idle_target = (idle << pmu_idle_ack_gpu) |
- (idle << pmu_idle_gpu);
- break;
- case bus_ide_req_core:
- idle_mask = BIT(pmu_idle_ack_core) | BIT(pmu_idle_core);
- idle_target = (idle << pmu_idle_ack_core) |
- (idle << pmu_idle_core);
- break;
- case bus_ide_req_cpup:
- idle_mask = BIT(pmu_idle_ack_cpup) | BIT(pmu_idle_cpup);
- idle_target = (idle << pmu_idle_ack_cpup) |
- (idle << pmu_idle_cpup);
- break;
- case bus_ide_req_bus:
- idle_mask = BIT(pmu_idle_ack_bus) | BIT(pmu_idle_bus);
- idle_target = (idle << pmu_idle_ack_bus) |
- (idle << pmu_idle_bus);
- break;
- case bus_ide_req_dma:
- idle_mask = BIT(pmu_idle_ack_dma) | BIT(pmu_idle_dma);
- idle_target = (idle << pmu_idle_ack_dma) |
- (idle << pmu_idle_dma);
- break;
- case bus_ide_req_peri:
- idle_mask = BIT(pmu_idle_ack_peri) | BIT(pmu_idle_peri);
- idle_target = (idle << pmu_idle_ack_peri) |
- (idle << pmu_idle_peri);
- break;
- case bus_ide_req_video:
- idle_mask = BIT(pmu_idle_ack_video) | BIT(pmu_idle_video);
- idle_target = (idle << pmu_idle_ack_video) |
- (idle << pmu_idle_video);
- break;
- case bus_ide_req_hevc:
- idle_mask = BIT(pmu_idle_ack_hevc) | BIT(pmu_idle_hevc);
- idle_target = (idle << pmu_idle_ack_hevc) |
- (idle << pmu_idle_hevc);
- break;
- case bus_ide_req_vio:
- idle_mask = BIT(pmu_idle_ack_vio) | BIT(pmu_idle_vio);
- idle_target = (pmu_idle_ack_vio) |
- (idle << pmu_idle_vio);
- break;
- case bus_ide_req_alive:
- idle_mask = BIT(pmu_idle_ack_alive) | BIT(pmu_idle_alive);
- idle_target = (idle << pmu_idle_ack_alive) |
- (idle << pmu_idle_alive);
- break;
- default:
- ERROR("%s: Unsupported the idle request\n", __func__);
- break;
- }
-
- val = mmio_read_32(PMU_BASE + PMU_BUS_IDE_REQ);
- if (idle)
- val |= mask;
- else
- val &= ~mask;
-
- mmio_write_32(PMU_BASE + PMU_BUS_IDE_REQ, val);
-
- while ((mmio_read_32(PMU_BASE +
- PMU_BUS_IDE_ST) & idle_mask) != idle_target) {
- wait_cnt++;
- if (!(wait_cnt % MAX_WAIT_CONUT))
- WARN("%s:st=%x(%x)\n", __func__,
- mmio_read_32(PMU_BASE + PMU_BUS_IDE_ST),
- idle_mask);
- }
-
- return 0;
-}
-
static bool rk3288_sleep_disable_osc(void)
{
static const uint32_t reg_offset[] = { GRF_UOC0_CON0, GRF_UOC1_CON0,
diff --git a/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c b/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
index 3cdb7a2..49faba8 100644
--- a/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
+++ b/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -778,7 +778,7 @@
else if (twr_tmp <= 8)
twr_tmp = 8;
else if (twr_tmp <= 12)
- twr_tmp = twr_tmp;
+ ; /* do nothing */
else if (twr_tmp <= 14)
twr_tmp = 14;
else
diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile
index 7913190..2bc87ae 100644
--- a/plat/rockchip/rk3399/drivers/m0/Makefile
+++ b/plat/rockchip/rk3399/drivers/m0/Makefile
@@ -5,13 +5,11 @@
#
include ../../../../../make_helpers/common.mk
+include ../../../../../make_helpers/build_macros.mk
include ../../../../../make_helpers/toolchain.mk
-# Cross Compile
-M0_CROSS_COMPILE ?= arm-none-eabi-
-
# Build architecture
-ARCH := cortex-m0
+ARCH := rk3399-m0
# Build platform
PLAT_M0 ?= rk3399m0
@@ -27,10 +25,13 @@
C_SOURCES_PMU := src/suspend.c
# Flags definition
-COMMON_FLAGS := -g -mcpu=$(ARCH) -mthumb -Wall -O3 -nostdlib -mfloat-abi=soft
+COMMON_FLAGS := -g -mcpu=cortex-m0 -mthumb -Wall -O3 -nostdlib -mfloat-abi=soft
CFLAGS := -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-common
-ASFLAGS := -Wa,--gdwarf-2
-LDFLAGS := -Wl,--gc-sections -Wl,--build-id=none
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
+CFLAGS += $(call cc_option, --param=min-pagesize=0)
+ASFLAGS := -Wa,--gdwarf-2 -Wa,--fatal-warnings
+LDFLAGS := -Wl,--gc-sections -Wl,--build-id=none -Wl,--fatal-warnings -z noexecstack
+LDFLAGS += $(call ld_option,-Xlinker --no-warn-rwx-segments)
# NOTE: The line continuation '\' is required in the next define otherwise we
# end up with a line-feed characer at the end of the last c filename.
@@ -62,7 +63,7 @@
$(OBJ) : $(2)
$(s)echo " CC $$<"
- $$(q)$(rk3399-m0-cc) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
+ $$(q)$($(ARCH)-cc) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
endef
define MAKE_S
@@ -70,7 +71,7 @@
$(OBJ) : $(2)
$(s)echo " AS $$<"
- $$(q)$(rk3399-m0-cc) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
+ $$(q)$($(ARCH)-as) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
endef
define MAKE_OBJS
@@ -91,20 +92,20 @@
.DEFAULT_GOAL := all
$(LINKERFILE): $(LINKERFILE_SRC)
- $(rk3399-m0-cc) $(COMMON_FLAGS) $(INCLUDES) -P -E -D__LINKER__ -MMD -MF $@.d -MT $@ -o $@ $<
+ $(q)$($(ARCH)-cc) $(COMMON_FLAGS) $(INCLUDES) -P -E -D__LINKER__ -MMD -MF $@.d -MT $@ -o $@ $<
-include $(LINKERFILE).d
$(ELF) : $(OBJS) $(OBJS_COMMON) $(LINKERFILE)
$(s)echo " LD $@"
- $(q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
+ $(q)$($(ARCH)-ld) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
%.bin : %.elf
$(s)echo " BIN $@"
- $(q)$(rk3399-m0-oc) -O binary $< $@
+ $(q)$($(ARCH)-oc) -O binary $< $@
$(ELF_PMU) : $(OBJS_COMMON) $(OBJS_PMU) $(LINKERFILE)
$(s)echo " LD $@"
- $(q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE_PMU) -Wl,-T$(LINKERFILE) $(OBJS_PMU) $(OBJS_COMMON)
+ $(q)$($(ARCH)-ld) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE_PMU) -Wl,-T$(LINKERFILE) $(OBJS_PMU) $(OBJS_COMMON)
$(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES_COMMON),$(1)))
$(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES),$(1)))
diff --git a/plat/rockchip/rk3588/drivers/pmu/pmu.c b/plat/rockchip/rk3588/drivers/pmu/pmu.c
index f693dbd..a4128b2 100644
--- a/plat/rockchip/rk3588/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3588/drivers/pmu/pmu.c
@@ -760,10 +760,10 @@
"mrs x0, S3_0_C15_C2_7\n"
"orr x0, x0, #0x1\n"
"msr S3_0_C15_C2_7, x0\n"
- "wfi_loop:\n"
+ "1:\n"
"isb\n"
"wfi\n"
- "b wfi_loop\n");
+ "b 1b\n");
}
static void nonboot_cpus_off(void)
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index e4ae87b..7a5a03c 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -25,6 +25,14 @@
# Libraries
include lib/xlat_tables_v2/xlat_tables.mk
+ifeq (${TRANSFER_LIST}, 1)
+include lib/transfer_list/transfer_list.mk
+endif
+
+ifeq (${HOB_LIST}, 1)
+include lib/hob/hob.mk
+endif
+
PLAT_PATH := plat/socionext/synquacer
PLAT_INCLUDES := -I$(PLAT_PATH)/include \
-I$(PLAT_PATH)/drivers/scpi \
diff --git a/plat/st/common/common.mk b/plat/st/common/common.mk
index 7395a36..dc753a0 100644
--- a/plat/st/common/common.mk
+++ b/plat/st/common/common.mk
@@ -1,5 +1,6 @@
#
# Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -76,7 +77,7 @@
# Variables for use with stm32image
STM32IMAGEPATH ?= tools/stm32image
-STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT}
+STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image$(.exe)
STM32IMAGE_SRC := ${STM32IMAGEPATH}/stm32image.c
STM32_DEPS += ${STM32IMAGE}
diff --git a/plat/st/common/include/stm32mp_svc_setup.h b/plat/st/common/include/stm32mp_svc_setup.h
new file mode 100644
index 0000000..e0e0d7f
--- /dev/null
+++ b/plat/st/common/include/stm32mp_svc_setup.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP_SVC_SETUP_H
+#define STM32MP_SVC_SETUP_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/* Common SMC function IDs for STM32 Service queries across STM32MP paltforms */
+#define STM32_SIP_SVC_CALL_COUNT 0x8200ff00
+#define STM32_SIP_SVC_UID 0x8200ff01
+/* 0x8200ff02 is reserved */
+#define STM32_SIP_SVC_VERSION 0x8200ff03
+
+/* STM32 SiP Service Calls version numbers */
+#define STM32_SIP_SVC_VERSION_MAJOR 0x0
+#define STM32_SIP_SVC_VERSION_MINOR 0x1
+
+/* SMC error codes */
+#define STM32_SMC_OK 0x00000000U
+#define STM32_SMC_NOT_SUPPORTED 0xFFFFFFFFU
+#define STM32_SMC_FAILED 0xFFFFFFFEU
+#define STM32_SMC_INVALID_PARAMS 0xFFFFFFFDU
+
+void plat_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4, uint32_t *ret1,
+ uint32_t *ret2, bool *ret2_enabled,
+ u_register_t flags);
+
+#endif /* STM32MP_SVC_SETUP_H */
diff --git a/plat/st/common/stm32mp_svc_setup.c b/plat/st/common/stm32mp_svc_setup.c
new file mode 100644
index 0000000..7fce896
--- /dev/null
+++ b/plat/st/common/stm32mp_svc_setup.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/scmi-msg.h>
+#include <lib/psci/psci.h>
+#include <platform_def.h>
+#include <tools_share/uuid.h>
+
+#include <stm32mp_svc_setup.h>
+
+/* STM32 SiP Service UUID */
+DEFINE_SVC_UUID2(stm32_sip_svc_uid,
+ 0xa778aa50, 0xf49b, 0x144a, 0x8a, 0x5e,
+ 0x26, 0x4d, 0x59, 0x94, 0xc2, 0x14);
+
+/* Setup STM32MP Standard Services */
+static int32_t stm32mp_svc_setup(void)
+{
+ /*
+ * PSCI is the only specification implemented as a Standard Service.
+ * Invoke PSCI setup from here.
+ */
+ return 0;
+}
+
+/*
+ * Top-level Standard Service SMC handler. This handler will dispatch the SMC
+ * to the correct feature handler or default call a platform handler
+ */
+static uintptr_t stm32mp_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4, void *cookie,
+ void *handle, u_register_t flags)
+{
+ uint32_t ret1 = 0U, ret2 = 0U;
+ bool ret_uid = false, ret2_enabled = false;
+
+ switch (smc_fid) {
+ case STM32_SIP_SVC_UID:
+ /* Return UUID to the caller */
+ ret_uid = true;
+ break;
+
+ case STM32_SIP_SVC_VERSION:
+ /* Return the version of current implementation */
+ ret1 = STM32_SIP_SVC_VERSION_MAJOR;
+ ret2 = STM32_SIP_SVC_VERSION_MINOR;
+ ret2_enabled = true;
+ break;
+ default:
+ plat_svc_smc_handler(smc_fid, x1, x2, x3, x4, &ret1, &ret2, &ret2_enabled, flags);
+ break;
+ }
+
+ if (ret_uid) {
+ SMC_UUID_RET(handle, stm32_sip_svc_uid);
+ }
+
+ if (ret2_enabled) {
+ SMC_RET2(handle, ret1, ret2);
+ }
+
+ SMC_RET1(handle, ret1);
+}
+
+/* Register Standard Service Calls as runtime service */
+DECLARE_RT_SVC(stm32mp_sip_svc,
+ OEN_SIP_START,
+ OEN_SIP_END,
+ SMC_TYPE_FAST,
+ stm32mp_svc_setup,
+ stm32mp_svc_smc_handler
+);
diff --git a/plat/st/stm32mp1/include/stm32mp1_smc.h b/plat/st/stm32mp1/include/stm32mp1_smc.h
index 52088de..ca4c88d 100644
--- a/plat/st/stm32mp1/include/stm32mp1_smc.h
+++ b/plat/st/stm32mp1/include/stm32mp1_smc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -39,16 +39,6 @@
#define STM32_SIP_SMC_SCMI_AGENT0 0x82002000
#define STM32_SIP_SMC_SCMI_AGENT1 0x82002001
-/* SMC function IDs for SiP Service queries */
-#define STM32_SIP_SVC_CALL_COUNT 0x8200ff00
-#define STM32_SIP_SVC_UID 0x8200ff01
-/* 0x8200ff02 is reserved */
-#define STM32_SIP_SVC_VERSION 0x8200ff03
-
-/* STM32 SiP Service Calls version numbers */
-#define STM32_SIP_SVC_VERSION_MAJOR 0x0
-#define STM32_SIP_SVC_VERSION_MINOR 0x1
-
/* Number of STM32 SiP Calls implemented */
#define STM32_COMMON_SIP_NUM_CALLS 3
@@ -58,10 +48,4 @@
#define STM32_SMC_WRITE_SHADOW 0x03
#define STM32_SMC_READ_OTP 0x04
-/* SMC error codes */
-#define STM32_SMC_OK 0x00000000U
-#define STM32_SMC_NOT_SUPPORTED 0xFFFFFFFFU
-#define STM32_SMC_FAILED 0xFFFFFFFEU
-#define STM32_SMC_INVALID_PARAMS 0xFFFFFFFDU
-
#endif /* STM32MP1_SMC_H */
diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c
index 7cc0013..418a2e5 100644
--- a/plat/st/stm32mp1/services/bsec_svc.c
+++ b/plat/st/stm32mp1/services/bsec_svc.c
@@ -11,6 +11,7 @@
#include <platform_def.h>
#include <stm32mp1_smc.h>
+#include <stm32mp_svc_setup.h>
#include "bsec_svc.h"
diff --git a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
index ed8a448..6e5544d 100644
--- a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
+++ b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2014-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,56 +14,27 @@
#include <tools_share/uuid.h>
#include <stm32mp1_smc.h>
+#include <stm32mp_svc_setup.h>
#include "bsec_svc.h"
-/* STM32 SiP Service UUID */
-DEFINE_SVC_UUID2(stm32_sip_svc_uid,
- 0xa778aa50, 0xf49b, 0x144a, 0x8a, 0x5e,
- 0x26, 0x4d, 0x59, 0x94, 0xc2, 0x14);
-
-/* Setup STM32MP1 Standard Services */
-static int32_t stm32mp1_svc_setup(void)
-{
- /*
- * PSCI is the only specification implemented as a Standard Service.
- * Invoke PSCI setup from here.
- */
- return 0;
-}
-
/*
- * Top-level Standard Service SMC handler. This handler will in turn dispatch
- * calls to PSCI SMC handler.
+ * Platform Standard Service SMC handler. This handler will dispatch
+ * calls to features handlers.
*/
-static uintptr_t stm32mp1_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
- u_register_t x2, u_register_t x3,
- u_register_t x4, void *cookie,
- void *handle, u_register_t flags)
+void plat_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4, uint32_t *ret1,
+ uint32_t *ret2, bool *ret2_enabled,
+ u_register_t flags)
{
- uint32_t ret1 = 0U, ret2 = 0U;
- bool ret_uid = false, ret2_enabled = false;
-
switch (smc_fid) {
case STM32_SIP_SVC_CALL_COUNT:
- ret1 = STM32_COMMON_SIP_NUM_CALLS;
+ *ret1 = STM32_COMMON_SIP_NUM_CALLS;
break;
-
- case STM32_SIP_SVC_UID:
- /* Return UUID to the caller */
- ret_uid = true;
- break;
-
- case STM32_SIP_SVC_VERSION:
- /* Return the version of current implementation */
- ret1 = STM32_SIP_SVC_VERSION_MAJOR;
- ret2 = STM32_SIP_SVC_VERSION_MINOR;
- ret2_enabled = true;
- break;
-
case STM32_SMC_BSEC:
- ret1 = bsec_main(x1, x2, x3, &ret2);
- ret2_enabled = true;
+ *ret1 = bsec_main(x1, x2, x3, ret2);
+ *ret2_enabled = true;
break;
case STM32_SIP_SMC_SCMI_AGENT0:
@@ -75,26 +46,7 @@
default:
WARN("Unimplemented STM32MP1 Service Call: 0x%x\n", smc_fid);
- ret1 = STM32_SMC_NOT_SUPPORTED;
+ *ret1 = STM32_SMC_NOT_SUPPORTED;
break;
}
-
- if (ret_uid) {
- SMC_UUID_RET(handle, stm32_sip_svc_uid);
- }
-
- if (ret2_enabled) {
- SMC_RET2(handle, ret1, ret2);
- }
-
- SMC_RET1(handle, ret1);
}
-
-/* Register Standard Service Calls as runtime service */
-DECLARE_RT_SVC(stm32mp1_sip_svc,
- OEN_SIP_START,
- OEN_SIP_END,
- SMC_TYPE_FAST,
- stm32mp1_svc_setup,
- stm32mp1_svc_smc_handler
-);
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index 9695c9b..0e34848 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -45,6 +45,7 @@
drivers/scmi-msg/smt.c
# stm32mp1 specific services
-BL32_SOURCES += plat/st/stm32mp1/services/bsec_svc.c \
+BL32_SOURCES += plat/st/common/stm32mp_svc_setup.c \
+ plat/st/stm32mp1/services/bsec_svc.c \
plat/st/stm32mp1/services/stm32mp1_svc_setup.c \
plat/st/stm32mp1/stm32mp1_scmi.c
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 2fabc41..621b784 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -385,6 +385,11 @@
break;
case BL33_IMAGE_ID:
+#if PSA_FWU_SUPPORT
+ stm32_fwu_set_boot_idx();
+#endif /* PSA_FWU_SUPPORT */
+ break;
+
default:
/* Do nothing in default case */
break;
diff --git a/plat/st/stm32mp2/include/stm32mp2_smc.h b/plat/st/stm32mp2/include/stm32mp2_smc.h
new file mode 100644
index 0000000..3bf6a84
--- /dev/null
+++ b/plat/st/stm32mp2/include/stm32mp2_smc.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_SMC_H
+#define STM32MP2_SMC_H
+
+#define STM32_COMMON_SIP_NUM_CALLS 1U
+
+/*
+ * STM32_SIP_SMC_STGEN_SET_RATE call API
+ * This service is opened to secure world only.
+ *
+ * Argument a0: (input) SMCC ID
+ * (output) status return code
+ * Argument a1: (input) Frequency to set (given by sender)
+ */
+#define STM32_SIP_SMC_STGEN_SET_RATE 0x82000000
+
+#endif /* STM32MP2_SMC_H */
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index 25ae593..a9f8d8f 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -202,6 +202,13 @@
# Generic PSCI
BL31_SOURCES += plat/common/plat_psci_common.c
+BL31_SOURCES += plat/st/common/stm32mp_svc_setup.c \
+ plat/st/stm32mp2/services/stgen_svc.c \
+ plat/st/stm32mp2/services/stm32mp2_svc_setup.c
+
+# Arm Archtecture services
+BL31_SOURCES += services/arm_arch_svc/arm_arch_svc_setup.c
+
# Compilation rules
.PHONY: check_ddr_type
bl2: check_ddr_type
diff --git a/plat/st/stm32mp2/services/stgen_svc.c b/plat/st/stm32mp2/services/stgen_svc.c
new file mode 100644
index 0000000..dada315
--- /dev/null
+++ b/plat/st/stm32mp2/services/stgen_svc.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/st/stm32mp_clkfunc.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include "stgen_svc.h"
+#include <stm32mp2_smc.h>
+#include <stm32mp_common.h>
+#include <stm32mp_svc_setup.h>
+
+/*
+ * This function reads and applies the STGEN frequency value in the STGENC base frequency register,
+ * which is the frequency the system base counter use for our platforms.
+ */
+uint32_t stgen_svc_handler(void)
+{
+ unsigned long freq_to_set = mmio_read_32(STGEN_BASE + CNTFID_OFF);
+
+ VERBOSE("STGEN frequency set to %lu\n", freq_to_set);
+
+ /*
+ * Update the system counter frequency according to STGEN's base
+ * counter frequency register
+ */
+ write_cntfrq_el0((u_register_t)freq_to_set);
+
+ /* Need to update timer with new frequency */
+ generic_delay_timer_init();
+
+ return STM32_SMC_OK;
+}
diff --git a/plat/st/stm32mp2/services/stgen_svc.h b/plat/st/stm32mp2/services/stgen_svc.h
new file mode 100644
index 0000000..98c2304
--- /dev/null
+++ b/plat/st/stm32mp2/services/stgen_svc.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STGEN_SVC_H
+#define STGEN_SVC_H
+
+uint32_t stgen_svc_handler(void);
+
+#endif /* STGEN_SVC_H */
diff --git a/plat/st/stm32mp2/services/stm32mp2_svc_setup.c b/plat/st/stm32mp2/services/stm32mp2_svc_setup.c
new file mode 100644
index 0000000..1162757
--- /dev/null
+++ b/plat/st/stm32mp2/services/stm32mp2_svc_setup.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+
+#include <stm32mp2_smc.h>
+#include <stm32mp_svc_setup.h>
+
+#include "stgen_svc.h"
+
+/*
+ * Platform-level Standard Service SIP SMC handler. This handler will dispatch
+ * the SMC to the correct feature handler.
+ */
+void plat_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4, uint32_t *ret1,
+ uint32_t *ret2, bool *ret2_enabled,
+ u_register_t flags)
+{
+ switch (smc_fid) {
+ case STM32_SIP_SVC_CALL_COUNT:
+ *ret1 = STM32_COMMON_SIP_NUM_CALLS;
+ break;
+ case STM32_SIP_SMC_STGEN_SET_RATE:
+ if (!is_caller_secure(flags)) {
+ *ret1 = STM32_SMC_FAILED;
+ break;
+ }
+
+ *ret1 = stgen_svc_handler();
+ break;
+ default:
+ WARN("Unimplemented STM32MP2 Service Call: 0x%x\n", smc_fid);
+ *ret1 = STM32_SMC_NOT_SUPPORTED;
+ break;
+ }
+}
diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c
index 5be4c5a..ea9d2fc 100644
--- a/plat/st/stm32mp2/stm32mp2_private.c
+++ b/plat/st/stm32mp2/stm32mp2_private.c
@@ -10,6 +10,7 @@
#include <platform_def.h>
+#define BKPR_FWU_INFO 48U
#define BKPR_BOOT_MODE 96U
#if defined(IMAGE_BL31)
@@ -328,6 +329,13 @@
return tamp_bkpr(BKPR_BOOT_MODE);
}
+#if PSA_FWU_SUPPORT
+uintptr_t stm32_get_bkpr_fwu_info_addr(void)
+{
+ return tamp_bkpr(BKPR_FWU_INFO);
+}
+#endif /* PSA_FWU_SUPPORT */
+
uintptr_t stm32_ddrdbg_get_base(void)
{
return DDRDBG_BASE;
diff --git a/plat/xilinx/common/include/ipi.h b/plat/xilinx/common/include/ipi.h
index 1d62f3e..d792710 100644
--- a/plat/xilinx/common/include/ipi.h
+++ b/plat/xilinx/common/include/ipi.h
@@ -29,7 +29,7 @@
********************************************************************/
#define IPI_SECURE_MASK (0x1U)
#define IPI_IS_SECURE(I) ((ipi_table[(I)].secure_only & \
- IPI_SECURE_MASK) ? 1 : 0)
+ IPI_SECURE_MASK) ? true : false)
/*********************************************************************
* Struct definitions
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index d7c70f3..cc4b04d 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -90,11 +90,11 @@
{
int ret = 0;
- if (!is_ipi_mb_within_range(local, remote)) {
+ if (is_ipi_mb_within_range(local, remote) == 0) {
ret = -EINVAL;
- } else if (IPI_IS_SECURE(local) && !is_secure) {
+ } else if (IPI_IS_SECURE(local) && (is_secure == 0U)) {
ret = -EPERM;
- } else if (IPI_IS_SECURE(remote) && !is_secure) {
+ } else if (IPI_IS_SECURE(remote) && (is_secure == 0U)) {
ret = -EPERM;
} else {
/* To fix the misra 15.7 warning */
@@ -111,9 +111,12 @@
*/
void ipi_mb_open(uint32_t local, uint32_t remote)
{
- mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+ uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
+ uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
+
+ mmio_write_32(idr_offset,
IPI_BIT_MASK(remote));
- mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
+ mmio_write_32(isr_offset,
IPI_BIT_MASK(remote));
}
@@ -125,7 +128,9 @@
*/
void ipi_mb_release(uint32_t local, uint32_t remote)
{
- mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+ uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
+
+ mmio_write_32(idr_offset,
IPI_BIT_MASK(remote));
}
@@ -142,12 +147,14 @@
{
int ret = 0U;
uint32_t status;
+ uint64_t obr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
+ uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
- status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
+ status = mmio_read_32(obr_offset);
if ((status & IPI_BIT_MASK(remote)) != 0U) {
ret |= IPI_MB_STATUS_SEND_PENDING;
}
- status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
+ status = mmio_read_32(isr_offset);
if ((status & IPI_BIT_MASK(remote)) != 0U) {
ret |= IPI_MB_STATUS_RECV_PENDING;
}
@@ -167,13 +174,14 @@
void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
{
uint32_t status;
+ uint64_t trig_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_TRIG_OFFSET);
+ uint64_t obr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
- mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
+ mmio_write_32(trig_offset,
IPI_BIT_MASK(remote));
if (is_blocking != 0U) {
do {
- status = mmio_read_32(IPI_REG_BASE(local) +
- IPI_OBR_OFFSET);
+ status = mmio_read_32(obr_offset);
} while ((status & IPI_BIT_MASK(remote)) != 0U);
}
}
@@ -188,7 +196,9 @@
*/
void ipi_mb_ack(uint32_t local, uint32_t remote)
{
- mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
+ uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
+
+ mmio_write_32(isr_offset,
IPI_BIT_MASK(remote));
}
@@ -202,7 +212,9 @@
*/
void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
{
- mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+ uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
+
+ mmio_write_32(idr_offset,
IPI_BIT_MASK(remote));
}
@@ -216,6 +228,8 @@
*/
void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
{
- mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
+ uint64_t ier_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IER_OFFSET);
+
+ mmio_write_32(ier_offset,
IPI_BIT_MASK(remote));
}
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 9a0149b..1882669 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -78,8 +78,8 @@
uint32_t ipi_remote_id;
uint32_t is_secure;
- ipi_local_id = x1 & UNSIGNED32_MASK;
- ipi_remote_id = x2 & UNSIGNED32_MASK;
+ ipi_local_id = (uint32_t)(x1 & UNSIGNED32_MASK);
+ ipi_remote_id = (uint32_t)(x2 & UNSIGNED32_MASK);
/* OEN Number 48 to 63 is for Trusted App and OS
* GET_SMC_OEN limits the return value of OEN number to 63 by bitwise
@@ -106,30 +106,32 @@
SMC_RET1(handle, 0);
case IPI_MAILBOX_STATUS_ENQUIRY:
{
- int32_t disable_interrupt;
+ bool disable_interrupt;
- disable_interrupt = (x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) ? 1 : 0;
+ disable_interrupt = ((x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) != 0U);
ret = ipi_mb_enquire_status(ipi_local_id, ipi_remote_id);
- if ((ret & IPI_MB_STATUS_RECV_PENDING) && disable_interrupt)
+ if ((((uint32_t)ret & IPI_MB_STATUS_RECV_PENDING) > 0U) && disable_interrupt) {
ipi_mb_disable_irq(ipi_local_id, ipi_remote_id);
+ }
SMC_RET1(handle, ret);
}
case IPI_MAILBOX_NOTIFY:
{
uint32_t is_blocking;
- is_blocking = (x3 & IPI_SMC_NOTIFY_BLOCK_MASK) ? 1 : 0;
+ is_blocking = ((x3 & IPI_SMC_NOTIFY_BLOCK_MASK) != 0U);
ipi_mb_notify(ipi_local_id, ipi_remote_id, is_blocking);
SMC_RET1(handle, 0);
}
case IPI_MAILBOX_ACK:
{
- int32_t enable_interrupt;
+ bool enable_interrupt;
- enable_interrupt = (x3 & IPI_SMC_ACK_EIRQ_MASK) ? 1 : 0;
+ enable_interrupt = ((x3 & IPI_SMC_ACK_EIRQ_MASK) != 0U);
ipi_mb_ack(ipi_local_id, ipi_remote_id);
- if (enable_interrupt != 0)
+ if (enable_interrupt != 0) {
ipi_mb_enable_irq(ipi_local_id, ipi_remote_id);
+ }
SMC_RET1(handle, 0);
}
case IPI_MAILBOX_ENABLE_IRQ:
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index 149ba2d..c5c52a8 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -72,11 +72,13 @@
* Return: XBL_FLAGS_A53_0, XBL_FLAGS_A53_1, XBL_FLAGS_A53_2 or XBL_FLAGS_A53_3.
*
*/
-static int32_t get_xbl_cpu(const struct xbl_partition *partition)
+static uint32_t get_xbl_cpu(const struct xbl_partition *partition)
{
uint64_t flags = partition->flags & XBL_FLAGS_CPU_MASK;
- return flags >> XBL_FLAGS_CPU_SHIFT;
+ flags >>= XBL_FLAGS_CPU_SHIFT;
+
+ return (uint32_t)flags;
}
/**
@@ -86,11 +88,13 @@
* Return: XBL_FLAGS_EL0, XBL_FLAGS_EL1, XBL_FLAGS_EL2 or XBL_FLAGS_EL3.
*
*/
-static int32_t get_xbl_el(const struct xbl_partition *partition)
+static uint32_t get_xbl_el(const struct xbl_partition *partition)
{
uint64_t flags = partition->flags & XBL_FLAGS_EL_MASK;
- return flags >> XBL_FLAGS_EL_SHIFT;
+ flags >>= XBL_FLAGS_EL_SHIFT;
+
+ return (uint32_t)flags;
}
/**
@@ -100,11 +104,13 @@
* Return: XBL_FLAGS_NON_SECURE or XBL_FLAGS_SECURE.
*
*/
-static int32_t get_xbl_ss(const struct xbl_partition *partition)
+static uint32_t get_xbl_ss(const struct xbl_partition *partition)
{
uint64_t flags = partition->flags & XBL_FLAGS_TZ_MASK;
- return flags >> XBL_FLAGS_TZ_SHIFT;
+ flags >>= XBL_FLAGS_TZ_SHIFT;
+
+ return (uint32_t)flags;
}
/**
@@ -114,17 +120,20 @@
* Return: SPSR_E_LITTLE or SPSR_E_BIG.
*
*/
-static int32_t get_xbl_endian(const struct xbl_partition *partition)
+static uint32_t get_xbl_endian(const struct xbl_partition *partition)
{
uint64_t flags = partition->flags & XBL_FLAGS_ENDIAN_MASK;
+ uint32_t spsr_value = 0U;
flags >>= XBL_FLAGS_ENDIAN_SHIFT;
if (flags == XBL_FLAGS_ENDIAN_BE) {
- return SPSR_E_BIG;
+ spsr_value = SPSR_E_BIG;
} else {
- return SPSR_E_LITTLE;
+ spsr_value = SPSR_E_LITTLE;
}
+
+ return spsr_value;
}
/**
@@ -134,11 +143,13 @@
* Return: XBL_FLAGS_ESTATE_A32 or XBL_FLAGS_ESTATE_A64.
*
*/
-static int32_t get_xbl_estate(const struct xbl_partition *partition)
+static uint32_t get_xbl_estate(const struct xbl_partition *partition)
{
uint64_t flags = partition->flags & XBL_FLAGS_ESTATE_MASK;
- return flags >> XBL_FLAGS_ESTATE_SHIFT;
+ flags >>= XBL_FLAGS_ESTATE_SHIFT;
+
+ return flags;
}
#if defined(PLAT_versal_net)
@@ -148,11 +159,11 @@
*
* Return: cluster number for the partition.
*/
-static int32_t get_xbl_cluster(const struct xbl_partition *partition)
+static uint32_t get_xbl_cluster(const struct xbl_partition *partition)
{
uint64_t flags = partition->flags & XBL_FLAGS_CLUSTER_MASK;
- return (int32_t)(flags >> XBL_FLAGS_CLUSTER_SHIFT);
+ return (flags >> XBL_FLAGS_CLUSTER_SHIFT);
}
#endif /* PLAT_versal_net */
@@ -174,19 +185,22 @@
uint64_t handoff_addr)
{
const struct xbl_handoff_params *HandoffParams;
+ enum xbl_handoff xbl_status = XBL_HANDOFF_SUCCESS;
- if (!handoff_addr) {
+ if (handoff_addr == 0U) {
WARN("BL31: No handoff structure passed\n");
- return XBL_HANDOFF_NO_STRUCT;
+ xbl_status = XBL_HANDOFF_NO_STRUCT;
+ goto exit_label;
}
HandoffParams = (struct xbl_handoff_params *)handoff_addr;
- if ((HandoffParams->magic[0] != 'X') ||
- (HandoffParams->magic[1] != 'L') ||
- (HandoffParams->magic[2] != 'N') ||
- (HandoffParams->magic[3] != 'X')) {
+ if ((HandoffParams->magic[0] != (uint8_t)'X') ||
+ (HandoffParams->magic[1] != (uint8_t)'L') ||
+ (HandoffParams->magic[2] != (uint8_t)'N') ||
+ (HandoffParams->magic[3] != (uint8_t)'X')) {
ERROR("BL31: invalid handoff structure at %" PRIx64 "\n", handoff_addr);
- return XBL_HANDOFF_INVAL_STRUCT;
+ xbl_status = XBL_HANDOFF_INVAL_STRUCT;
+ goto exit_label;
}
VERBOSE("BL31: TF-A handoff params at:0x%" PRIx64 ", entries:%u\n",
@@ -194,7 +208,8 @@
if (HandoffParams->num_entries > XBL_MAX_PARTITIONS) {
ERROR("BL31: TF-A handoff params: too many partitions (%u/%u)\n",
HandoffParams->num_entries, XBL_MAX_PARTITIONS);
- return XBL_HANDOFF_TOO_MANY_PARTS;
+ xbl_status = XBL_HANDOFF_TOO_MANY_PARTS;
+ goto exit_label;
}
/*
@@ -204,7 +219,7 @@
*/
for (size_t i = 0; i < HandoffParams->num_entries; i++) {
entry_point_info_t *image;
- int32_t target_estate, target_secure, target_cpu;
+ uint32_t target_estate, target_secure, target_cpu;
uint32_t target_endianness, target_el;
VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i,
@@ -251,8 +266,8 @@
image = bl32;
if (target_estate == XBL_FLAGS_ESTATE_A32) {
- bl32->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
- target_endianness,
+ bl32->spsr = (uint32_t)SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+ (uint64_t)target_endianness,
DISABLE_ALL_EXCEPTIONS);
} else {
bl32->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
@@ -268,8 +283,8 @@
target_el = MODE32_sys;
}
- bl33->spsr = SPSR_MODE32(target_el, SPSR_T_ARM,
- target_endianness,
+ bl33->spsr = (uint32_t)SPSR_MODE32((uint64_t)target_el, SPSR_T_ARM,
+ (uint64_t)target_endianness,
DISABLE_ALL_EXCEPTIONS);
} else {
if (target_el == XBL_FLAGS_EL2) {
@@ -278,7 +293,7 @@
target_el = MODE_EL1;
}
- bl33->spsr = SPSR_64(target_el, MODE_SP_ELX,
+ bl33->spsr = (uint32_t)SPSR_64((uint64_t)target_el, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
}
}
@@ -296,5 +311,6 @@
}
}
- return XBL_HANDOFF_SUCCESS;
+exit_label:
+ return xbl_status;
}
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index e9c5f13..9af8bb2 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -56,7 +56,8 @@
for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
uint32_t base_irq = reg_num << ISENABLER_SHIFT;
- uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
+ isenabler1 += (reg_num << 2);
+ uint32_t reg = mmio_read_32((uint64_t)isenabler1);
if (reg == 0U) {
continue;
@@ -117,7 +118,7 @@
module_id = (x0 & MODULE_ID_MASK) >> 8U;
//default module id is for LIBPM
- if (module_id == 0) {
+ if (module_id == 0U) {
module_id = LIBPM_MODULE_ID;
}
@@ -148,10 +149,11 @@
uint32_t payload[PAYLOAD_ARG_CNT];
uint32_t cpuid = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpuid);
+ enum pm_ret_status ret = PM_RET_ERROR_INTERNAL;
if (proc == NULL) {
WARN("Failed to get proc %d\n", cpuid);
- return PM_RET_ERROR_INTERNAL;
+ goto exit_label;
}
/*
@@ -164,7 +166,10 @@
PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, flag, PM_SELF_SUSPEND,
proc->node_id, latency, state, address,
(address >> 32));
- return pm_ipi_send_sync(proc, payload, NULL, 0);
+ ret = pm_ipi_send_sync(proc, payload, NULL, 0);
+
+exit_label:
+ return ret;
}
/**
@@ -214,15 +219,18 @@
uint32_t flag)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
/* Send request to the PMU */
PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_REQ_SUSPEND, target,
latency, state);
- if (ack == IPI_BLOCKING) {
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ if (ack == (uint32_t)IPI_BLOCKING) {
+ ret = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
} else {
- return pm_ipi_send(primary_proc, payload);
+ ret = pm_ipi_send(primary_proc, payload);
}
+
+ return ret;
}
/**
@@ -272,15 +280,15 @@
enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack)
{
enum pm_ret_status ret = PM_RET_SUCCESS;
+
/* Return if interrupt is not from PMU */
- if (pm_ipi_irq_status(primary_proc) == 0) {
- return ret;
- }
+ if (pm_ipi_irq_status(primary_proc) != 0U) {
- ret = pm_ipi_buff_read_callb(data, count);
+ ret = pm_ipi_buff_read_callb(data, count);
- if (ack != 0U) {
- pm_ipi_irq_clear(primary_proc);
+ if (ack != 0U) {
+ pm_ipi_irq_clear(primary_proc);
+ }
}
return ret;
@@ -301,16 +309,19 @@
uint32_t flag)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
/* Send request to the PMC */
PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_FORCE_POWERDOWN,
target, ack);
- if (ack == IPI_BLOCKING) {
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ if (ack == (uint32_t)IPI_BLOCKING) {
+ ret = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
} else {
- return pm_ipi_send(primary_proc, payload);
+ ret = pm_ipi_send(primary_proc, payload);
}
+
+ return ret;
}
/**
@@ -327,18 +338,22 @@
uint32_t flag)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
/* Setting scope for subsequent PSCI reboot or shutdown */
pm_shutdown_scope = subtype;
- return PM_RET_SUCCESS;
+ goto exit_label;
}
/* Send request to the PMC */
PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SYSTEM_SHUTDOWN,
type, subtype);
- return pm_ipi_send_non_blocking(primary_proc, payload);
+ ret = pm_ipi_send_non_blocking(primary_proc, payload);
+
+exit_label:
+ return ret;
}
/**
@@ -411,16 +426,19 @@
{
uint32_t payload[PAYLOAD_ARG_CNT];
uint32_t module_id;
+ enum pm_ret_status ret;
/* Return version of API which are implemented in TF-A only */
switch (api_id) {
case PM_GET_CALLBACK_DATA:
case PM_GET_TRUSTZONE_VERSION:
ret_payload[0] = PM_API_VERSION_2;
- return PM_RET_SUCCESS;
+ ret = PM_RET_SUCCESS;
+ goto exit_label;
case TF_A_PM_REGISTER_SGI:
ret_payload[0] = PM_API_BASE_VERSION;
- return PM_RET_SUCCESS;
+ ret = PM_RET_SUCCESS;
+ goto exit_label;
default:
break;
}
@@ -431,13 +449,18 @@
* feature check should be done only for LIBPM module
* If module_id is 0, then we consider it LIBPM module as default id
*/
- if ((module_id > 0) && (module_id != LIBPM_MODULE_ID)) {
- return PM_RET_SUCCESS;
+ if ((module_id > 0U) && (module_id != LIBPM_MODULE_ID)) {
+ ret = PM_RET_SUCCESS;
+ goto exit_label;
}
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
- PM_FEATURE_CHECK, api_id);
- return pm_ipi_send_sync(primary_proc, payload, ret_payload, RET_PAYLOAD_ARG_CNT);
+ PM_FEATURE_CHECK, api_id);
+ ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, RET_PAYLOAD_ARG_CNT);
+
+exit_label:
+ return ret;
+
}
/**
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index c3872fc..bf1fd55 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -226,7 +226,7 @@
IPI_BUFFER_REQ_OFFSET;
enum pm_ret_status ret = PM_RET_SUCCESS;
- if (local_count > IPI_BUFFER_MAX_WORDS) {
+ if (local_count > (uint32_t)IPI_BUFFER_MAX_WORDS) {
local_count = IPI_BUFFER_MAX_WORDS;
}
@@ -273,7 +273,7 @@
goto unlock;
}
- ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count));
+ ret = ERROR_CODE_MASK & (uint32_t)(pm_ipi_buff_read(proc, value, count));
unlock:
pm_ipi_lock_release();
@@ -294,14 +294,17 @@
uint32_t pm_ipi_irq_status(const struct pm_proc *proc)
{
int32_t ret;
+ int32_t result = 0;
ret = ipi_mb_enquire_status(proc->ipi->local_ipi_id,
proc->ipi->remote_ipi_id);
- if (ret & IPI_MB_STATUS_RECV_PENDING) {
- return 1;
+ if (((uint32_t)ret & IPI_MB_STATUS_RECV_PENDING) != 0U) {
+ result = 1;
} else {
- return 0;
+ result = 0;
}
+
+ return result;
}
#if IPI_CRC_CHECK
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index afb9a96..237761a 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -112,8 +112,9 @@
VERBOSE("CPU power down request received\n");
/* Send powerdown request to online secondary core(s) */
- ret = psci_stop_other_cores(PWRDWN_WAIT_TIMEOUT, raise_pwr_down_interrupt);
- if (ret != PSCI_E_SUCCESS) {
+ ret = psci_stop_other_cores(plat_my_core_pos(), PWRDWN_WAIT_TIMEOUT,
+ raise_pwr_down_interrupt);
+ if (ret != (uint32_t)PSCI_E_SUCCESS) {
ERROR("Failed to powerdown secondary core(s)\n");
}
@@ -140,11 +141,11 @@
(void)plat_ic_acknowledge_interrupt();
/* Check status register for each IPI except PMC */
- for (i = IPI_ID_APU; i <= IPI_ID_5; i++) {
+ for (i = (int32_t)IPI_ID_APU; i <= IPI_ID_5; i++) {
ipi_status = ipi_mb_enquire_status(IPI_ID_APU, i);
/* If any agent other than PMC has generated IPI FIQ then send SGI to mbox driver */
- if (ipi_status & IPI_MB_STATUS_RECV_PENDING) {
+ if ((uint32_t)ipi_status & IPI_MB_STATUS_RECV_PENDING) {
plat_ic_raise_ns_sgi(MBOX_SGI_SHARED_IPI, read_mpidr_el1());
break;
}
@@ -152,15 +153,15 @@
/* If PMC has not generated interrupt then end ISR */
ipi_status = ipi_mb_enquire_status(IPI_ID_APU, IPI_ID_PMC);
- if ((ipi_status & IPI_MB_STATUS_RECV_PENDING) == 0) {
+ if (((uint32_t)ipi_status & IPI_MB_STATUS_RECV_PENDING) == 0U) {
plat_ic_end_of_interrupt(id);
- return 0;
+ goto exit_label;
}
/* Handle PMC case */
ret = pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
if (ret != PM_RET_SUCCESS) {
- payload[0] = ret;
+ payload[0] = (uint32_t)ret;
}
switch (payload[0]) {
@@ -201,6 +202,7 @@
/* Clear FIQ */
plat_ic_end_of_interrupt(id);
+exit_label:
return 0;
}
@@ -218,21 +220,19 @@
*/
int32_t pm_register_sgi(uint32_t sgi_num, uint32_t reset)
{
+ int32_t ret = 0;
+
if (reset == 1U) {
sgi = INVALID_SGI;
- return 0;
+ } else if (sgi != INVALID_SGI) {
+ ret = -EBUSY;
+ } else if (sgi_num >= GICV3_MAX_SGI_TARGETS) {
+ ret = -EINVAL;
+ } else {
+ sgi = (uint32_t)sgi_num;
}
- if (sgi != INVALID_SGI) {
- return -EBUSY;
- }
-
- if (sgi_num >= GICV3_MAX_SGI_TARGETS) {
- return -EINVAL;
- }
-
- sgi = (uint32_t)sgi_num;
- return 0;
+ return ret;
}
/**
@@ -278,7 +278,7 @@
gicd_write_irouter(gicv3_driver_data->gicd_base, PLAT_VERSAL_IPI_IRQ, MODE);
/* Register for idle callback during force power down/restart */
- ret = pm_register_notifier(primary_proc->node_id, EVENT_CPU_PWRDWN,
+ ret = (int32_t)pm_register_notifier(primary_proc->node_id, EVENT_CPU_PWRDWN,
0x0U, 0x1U, SECURE_FLAG);
if (ret != 0) {
WARN("BL31: registering idle callback for restart/force power down failed\n");
@@ -428,7 +428,7 @@
ret = pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag, 1U);
if (ret != 0) {
- result[0] = ret;
+ result[0] = (uint32_t)ret;
}
SMC_RET2(handle,
@@ -478,8 +478,8 @@
* than other eemi calls.
*/
if (api_id == (uint32_t)PM_QUERY_DATA) {
- if (((pm_arg[0] == XPM_QID_CLOCK_GET_NAME) ||
- (pm_arg[0] == XPM_QID_PINCTRL_GET_FUNCTION_NAME)) &&
+ if (((pm_arg[0] == (uint32_t)XPM_QID_CLOCK_GET_NAME) ||
+ (pm_arg[0] == (uint32_t)XPM_QID_PINCTRL_GET_FUNCTION_NAME)) &&
(ret == PM_RET_SUCCESS)) {
SMC_RET2(handle, (uint64_t)buf[0] | ((uint64_t)buf[1] << 32U),
(uint64_t)buf[2] | ((uint64_t)buf[3] << 32U));
diff --git a/plat/xilinx/common/versal.c b/plat/xilinx/common/versal.c
index b37dc76..dc0ae10 100644
--- a/plat/xilinx/common/versal.c
+++ b/plat/xilinx/common/versal.c
@@ -25,12 +25,17 @@
*/
int32_t plat_is_smccc_feature_available(u_register_t fid)
{
+ int32_t ret = 0;
+
switch (fid) {
case SMCCC_ARCH_SOC_ID:
- return SMC_ARCH_CALL_SUCCESS;
+ ret = SMC_ARCH_CALL_SUCCESS;
+ break;
default:
- return SMC_ARCH_CALL_NOT_SUPPORTED;
+ ret = SMC_ARCH_CALL_NOT_SUPPORTED;
}
+
+ return ret;
}
/**
@@ -60,5 +65,5 @@
*/
int32_t plat_get_soc_revision(void)
{
- return (platform_id & SOC_ID_REV_MASK);
+ return (int32_t)(platform_id & SOC_ID_REV_MASK);
}
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 819a55b..befe36c 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -117,7 +117,7 @@
SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
- PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1, PM_LOAD_GET_HANDOFF_PARAMS,
+ PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1U, PM_LOAD_GET_HANDOFF_PARAMS,
(uintptr_t)addr >> 32U, (uintptr_t)addr, max_size);
ret_status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
if (ret_status == PM_RET_SUCCESS) {
@@ -151,16 +151,19 @@
{
static uint32_t index;
uint32_t i;
+ int32_t ret = 0;
/* Validate 'handler' and 'id' parameters */
if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit_label;
}
/* Check if a handler has already been registered */
for (i = 0; i < index; i++) {
if (id == type_el3_interrupt_table[i].id) {
- return -EALREADY;
+ ret = -EALREADY;
+ goto exit_label;
}
}
@@ -169,7 +172,8 @@
index++;
- return 0;
+exit_label:
+ return ret;
}
static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
@@ -178,6 +182,7 @@
(void)id;
uint32_t intr_id;
uint32_t i;
+ uint64_t ret = 0;
interrupt_type_handler_t handler = NULL;
intr_id = plat_ic_get_pending_interrupt_id();
@@ -189,10 +194,10 @@
}
if (handler != NULL) {
- return handler(intr_id, flags, handle, cookie);
+ ret = handler(intr_id, flags, handle, cookie);
}
- return 0;
+ return ret;
}
void bl31_platform_setup(void)
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index 3a1c127..c5bcc95 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -16,7 +16,7 @@
#define PLATFORM_VERSION_MASK GENMASK(31U, 28U)
/* number of interrupt handlers. increase as required */
-#define MAX_INTR_EL3 2
+#define MAX_INTR_EL3 2U
/* List all consoles */
#define VERSAL_CONSOLE_ID_none 0
#define VERSAL_CONSOLE_ID_pl011 1
@@ -49,10 +49,10 @@
/*******************************************************************************
* memory map related constants
******************************************************************************/
-#define DEVICE0_BASE 0xFF000000
-#define DEVICE0_SIZE 0x00E00000
-#define DEVICE1_BASE 0xF9000000
-#define DEVICE1_SIZE 0x00800000
+#define DEVICE0_BASE U(0xFF000000)
+#define DEVICE0_SIZE U(0x00E00000)
+#define DEVICE1_BASE U(0xF9000000)
+#define DEVICE1_SIZE U(0x00800000)
/*******************************************************************************
* IRQ constants
@@ -63,16 +63,16 @@
/*******************************************************************************
* CCI-400 related constants
******************************************************************************/
-#define PLAT_ARM_CCI_BASE 0xFD000000
-#define PLAT_ARM_CCI_SIZE 0x00100000
+#define PLAT_ARM_CCI_BASE U(0xFD000000)
+#define PLAT_ARM_CCI_SIZE U(0x00100000)
#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 4
#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 5
/*******************************************************************************
* UART related constants
******************************************************************************/
-#define VERSAL_UART0_BASE 0xFF000000
-#define VERSAL_UART1_BASE 0xFF010000
+#define VERSAL_UART0_BASE U(0xFF000000)
+#define VERSAL_UART1_BASE U(0xFF010000)
#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
# define UART_BASE VERSAL_UART0_BASE
@@ -115,8 +115,8 @@
#define ACTLR_EL3_CPUACTLR_BIT (1 << 0)
/* For cpu reset APU space here too 0xFE5F1000 CRF_APB*/
-#define CRF_BASE 0xFD1A0000
-#define CRF_SIZE 0x00600000
+#define CRF_BASE U(0xFD1A0000)
+#define CRF_SIZE U(0x00600000)
/* CRF registers and bitfields */
#define CRF_RST_APU (CRF_BASE + 0X00000300)
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 3fc6dbd..b976267 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -28,16 +28,17 @@
{
int32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
const struct pm_proc *proc;
+ int32_t ret = PSCI_E_INTERN_FAIL;
VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
if (cpu_id == -1) {
- return PSCI_E_INTERN_FAIL;
+ goto exit_label;
}
proc = pm_get_proc((uint32_t)cpu_id);
if (proc == NULL) {
- return PSCI_E_INTERN_FAIL;
+ goto exit_label;
}
/* Send request to PMC to wake up selected ACPU core */
@@ -47,7 +48,10 @@
/* Clear power down request */
pm_client_wakeup(proc);
- return PSCI_E_SUCCESS;
+ ret = PSCI_E_SUCCESS;
+
+exit_label:
+ return ret;
}
/**
@@ -222,7 +226,7 @@
* be set.
*/
ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version_type[0], SECURE_FLAG);
- if (ret == PM_RET_SUCCESS) {
+ if (ret == (uint32_t)PM_RET_SUCCESS) {
fw_api_version = version_type[0] & 0xFFFFU;
if (fw_api_version >= 3U) {
(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0,
@@ -246,6 +250,7 @@
static int32_t versal_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state)
{
+ int32_t ret = PSCI_E_SUCCESS;
VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
uint32_t pstate = psci_get_pstate_type(power_state);
@@ -261,10 +266,10 @@
/* We expect the 'state id' to be zero */
if (psci_get_pstate_id(power_state) != 0U) {
- return PSCI_E_INVALID_PARAMS;
+ ret = PSCI_E_INVALID_PARAMS;
}
- return PSCI_E_SUCCESS;
+ return ret;
}
/**
diff --git a/plat/xilinx/versal/plat_versal.c b/plat/xilinx/versal/plat_versal.c
index ba17b1d..6e0b2d6 100644
--- a/plat/xilinx/versal/plat_versal.c
+++ b/plat/xilinx/versal/plat_versal.c
@@ -10,13 +10,12 @@
int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
{
- if ((mpidr & MPIDR_CLUSTER_MASK) != 0U) {
- return -1;
+ int32_t ret = -1;
+
+ if (((mpidr & MPIDR_CLUSTER_MASK) == 0U) &&
+ ((mpidr & MPIDR_CPU_MASK) < PLATFORM_CORE_COUNT)) {
+ ret = versal_calc_core_pos(mpidr);
}
- if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT) {
- return -1;
- }
-
- return (int32_t)versal_calc_core_pos(mpidr);
+ return ret;
}
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 3e44153..de2cac8 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -26,7 +26,7 @@
#include "pm_defs.h"
#include <versal_def.h>
-#define UNDEFINED_CPUID (~0)
+#define UNDEFINED_CPUID (~0U)
DEFINE_BAKERY_LOCK(pm_client_secure_lock);
@@ -232,12 +232,16 @@
*/
static uint32_t pm_get_cpuid(uint32_t nid)
{
- for (size_t i = 0U; i < ARRAY_SIZE(pm_procs_all); i++) {
+ uint32_t ret = UNDEFINED_CPUID;
+ uint32_t i;
+
+ for (i = 0U; i < ARRAY_SIZE(pm_procs_all); i++) {
if (pm_procs_all[i].node_id == nid) {
- return i;
+ ret = i;
+ break;
}
}
- return UNDEFINED_CPUID;
+ return ret;
}
/**
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_common.c b/plat/xilinx/versal_net/aarch64/versal_net_common.c
index 0dd0194..7365818 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_common.c
+++ b/plat/xilinx/versal_net/aarch64/versal_net_common.c
@@ -42,20 +42,28 @@
/* For saving cpu clock for certain platform */
uint32_t cpu_clock;
-char *board_name_decode(void)
+const char *board_name_decode(void)
{
+ const char *platform;
+
switch (platform_id) {
case VERSAL_NET_SPP:
- return "IPP";
+ platform = "IPP";
+ break;
case VERSAL_NET_EMU:
- return "EMU";
+ platform = "EMU";
+ break;
case VERSAL_NET_SILICON:
- return "Silicon";
+ platform = "Silicon";
+ break;
case VERSAL_NET_QEMU:
- return "QEMU";
+ platform = "QEMU";
+ break;
default:
- return "Unknown";
+ platform = "Unknown";
}
+
+ return platform;
}
void board_detection(void)
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index cf2368a..d131a92 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -55,7 +55,7 @@
bl32_image_ep_info.pc = BL32_BASE;
bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
- bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+ bl33_image_ep_info.spsr = (uint32_t)SPSR_64(MODE_EL2, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
}
@@ -117,6 +117,9 @@
set_cnt_freq();
+ /* Initialize the platform config for future decision making */
+ versal_net_config_setup();
+
setup_console();
NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
@@ -124,8 +127,6 @@
versal_net_setup_qos();
- /* Initialize the platform config for future decision making */
- versal_net_config_setup();
/*
* Do initial security configuration to allow DRAM/device access. On
@@ -140,7 +141,7 @@
SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
#if !(TFA_NO_PM)
- PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1, PM_LOAD_GET_HANDOFF_PARAMS,
+ PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1U, PM_LOAD_GET_HANDOFF_PARAMS,
(uintptr_t)buff >> 32U, (uintptr_t)buff, max_size);
ret_status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
@@ -177,16 +178,19 @@
{
static uint32_t index;
uint32_t i;
+ int32_t ret = 0;
/* Validate 'handler' and 'id' parameters */
if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit_label;
}
/* Check if a handler has already been registered */
for (i = 0; i < index; i++) {
if (id == type_el3_interrupt_table[i].id) {
- return -EALREADY;
+ ret = -EALREADY;
+ goto exit_label;
}
}
@@ -195,7 +199,8 @@
index++;
- return 0;
+exit_label:
+ return ret;
}
static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
diff --git a/plat/xilinx/versal_net/include/plat_private.h b/plat/xilinx/versal_net/include/plat_private.h
index 0b82ca7..8b4020e 100644
--- a/plat/xilinx/versal_net/include/plat_private.h
+++ b/plat/xilinx/versal_net/include/plat_private.h
@@ -35,7 +35,7 @@
extern uint32_t cpu_clock, platform_id, platform_version;
void board_detection(void);
-char *board_name_decode(void);
+const char *board_name_decode(void);
uint64_t smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
uint64_t x4, void *cookie, void *handle, uint64_t flags);
int32_t sip_svc_setup_init(void);
diff --git a/plat/xilinx/versal_net/include/platform_def.h b/plat/xilinx/versal_net/include/platform_def.h
index 8cb7deb..a7ff84e 100644
--- a/plat/xilinx/versal_net/include/platform_def.h
+++ b/plat/xilinx/versal_net/include/platform_def.h
@@ -25,6 +25,9 @@
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * PLATFORM_CORE_COUNT_PER_CLUSTER)
+#define E_INVALID_CORE_COUNT -1
+#define E_INVALID_CLUSTER_COUNT -3
+
#define PLAT_MAX_PWR_LVL U(2)
#define PLAT_MAX_RET_STATE U(1)
#define PLAT_MAX_OFF_STATE U(2)
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index 5caf376..54f9cc9 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -12,7 +12,7 @@
#include <plat/arm/common/smccc_def.h>
#include <plat/common/common_def.h>
-#define MAX_INTR_EL3 2
+#define MAX_INTR_EL3 2U
/* List all consoles */
#define VERSAL_NET_CONSOLE_ID_none U(0)
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index 1c32879..a76832e 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -27,19 +27,20 @@
static int32_t versal_net_pwr_domain_on(u_register_t mpidr)
{
- uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+ int32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
const struct pm_proc *proc;
+ int32_t ret = PSCI_E_INTERN_FAIL;
VERBOSE("%s: mpidr: 0x%lx, cpuid: %x\n",
__func__, mpidr, cpu_id);
if (cpu_id == -1) {
- return PSCI_E_INTERN_FAIL;
+ goto exit_label;
}
proc = pm_get_proc(cpu_id);
if (proc == NULL) {
- return PSCI_E_INTERN_FAIL;
+ goto exit_label;
}
(void)pm_req_wakeup(proc->node_id, (versal_net_sec_entry & 0xFFFFFFFFU) | 0x1U,
@@ -48,7 +49,10 @@
/* Clear power down request */
pm_client_wakeup(proc);
- return PSCI_E_SUCCESS;
+ ret = PSCI_E_SUCCESS;
+
+exit_label:
+ return ret;
}
/**
@@ -64,7 +68,7 @@
const struct pm_proc *proc = pm_get_proc(cpu_id);
if (proc == NULL) {
- return;
+ goto exit_label;
}
for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -84,7 +88,7 @@
* be set.
*/
ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version_type[0], SECURE_FLAG);
- if (ret == PM_RET_SUCCESS) {
+ if (ret == (uint32_t)PM_RET_SUCCESS) {
fw_api_version = version_type[0] & 0xFFFFU;
if (fw_api_version >= 3U) {
(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0,
@@ -94,6 +98,9 @@
SECURE_FLAG);
}
}
+
+exit_label:
+ return;
}
/**
@@ -148,7 +155,7 @@
const struct pm_proc *proc = pm_get_proc(cpu_id);
if (proc == NULL) {
- return;
+ goto exit_label;
}
for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -170,6 +177,9 @@
SECURE_FLAG);
/* TODO: disable coherency */
+
+exit_label:
+ return;
}
static void versal_net_pwr_domain_on_finish(const psci_power_state_t *target_state)
@@ -195,12 +205,13 @@
const struct pm_proc *proc = pm_get_proc(cpu_id);
if (proc == NULL) {
- return;
+ goto exit_label;
}
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+ for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
+ }
/* Clear the APU power control register for this cpu */
pm_client_wakeup(proc);
@@ -213,6 +224,9 @@
}
plat_arm_gic_cpuif_enable();
+
+exit_label:
+ return;
}
/**
@@ -243,9 +257,11 @@
static int32_t versal_net_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
+ int32_t ret = PSCI_E_INVALID_PARAMS;
+
VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
- int32_t pstate = psci_get_pstate_type(power_state);
+ uint32_t pstate = psci_get_pstate_type(power_state);
assert(req_state != NULL);
@@ -257,11 +273,11 @@
}
/* We expect the 'state id' to be zero */
- if (psci_get_pstate_id(power_state) != 0U) {
- return PSCI_E_INVALID_PARAMS;
+ if (psci_get_pstate_id(power_state) == 0U) {
+ ret = PSCI_E_SUCCESS;
}
- return PSCI_E_SUCCESS;
+ return ret;
}
/**
@@ -274,8 +290,9 @@
{
uint64_t i;
- for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+ for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) {
req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+ }
}
static const struct plat_psci_ops versal_net_nopmc_psci_ops = {
diff --git a/plat/xilinx/versal_net/plat_topology.c b/plat/xilinx/versal_net/plat_topology.c
index ee756c4..ef5c426 100644
--- a/plat/xilinx/versal_net/plat_topology.c
+++ b/plat/xilinx/versal_net/plat_topology.c
@@ -41,14 +41,16 @@
int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
{
uint32_t cluster_id, cpu_id;
+ int32_t ret;
mpidr &= MPIDR_AFFINITY_MASK;
- cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
- cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
+ cluster_id = (uint32_t)MPIDR_AFFLVL2_VAL(mpidr);
+ cpu_id = (uint32_t)MPIDR_AFFLVL1_VAL(mpidr);
if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
- return -3;
+ ret = E_INVALID_CLUSTER_COUNT;
+ goto exit_label;
}
/*
@@ -56,8 +58,11 @@
* one of the two clusters present on the platform.
*/
if (cpu_id >= PLATFORM_CORE_COUNT_PER_CLUSTER) {
- return -1;
+ ret = E_INVALID_CORE_COUNT;
+ } else {
+ ret = (int32_t)(cpu_id + (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER));
}
- return (cpu_id + (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER));
+exit_label:
+ return ret;
}
diff --git a/plat/xilinx/versal_net/pm_service/pm_client.c b/plat/xilinx/versal_net/pm_service/pm_client.c
index cff400c..9b2ca6f 100644
--- a/plat/xilinx/versal_net/pm_service/pm_client.c
+++ b/plat/xilinx/versal_net/pm_service/pm_client.c
@@ -26,7 +26,7 @@
#include "pm_client.h"
#include <versal_net_def.h>
-#define UNDEFINED_CPUID (~0)
+#define UNDEFINED_CPUID (~0U)
DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7)
@@ -340,12 +340,16 @@
*/
static uint32_t pm_get_cpuid(uint32_t nid)
{
- for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
+ uint32_t ret = UNDEFINED_CPUID;
+ uint32_t i;
+
+ for (i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
if (pm_procs_all[i].node_id == nid) {
- return i;
+ ret = i;
+ break;
}
}
- return UNDEFINED_CPUID;
+ return ret;
}
/**
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index bf06e2c..21657ab 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -37,7 +37,7 @@
/* SiP Service UUID */
DEFINE_SVC_UUID2(versal_net_sip_uuid,
- 0x80d4c25a, 0xebaf, 0x11eb, 0x94, 0x68,
+ 0x80d4c25au, 0xebaf, 0x11eb, 0x94, 0x68,
0x0b, 0x4e, 0x3b, 0x8f, 0xc3, 0x60);
/**
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 0e698f7..412238d 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -9,7 +9,6 @@
#include <string.h>
#include <common/debug.h>
-#include <drivers/generic_delay_timer.h>
#include <lib/mmio.h>
#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
@@ -42,9 +41,9 @@
static uint32_t zynqmp_get_silicon_ver(void)
{
- static unsigned int ver;
+ static uint32_t ver;
- if (!ver) {
+ if (ver == 0U) {
ver = mmio_read_32(ZYNQMP_CSU_BASEADDR +
ZYNQMP_CSU_VERSION_OFFSET);
ver &= ZYNQMP_SILICON_VER_MASK;
@@ -57,12 +56,15 @@
uint32_t get_uart_clk(void)
{
unsigned int ver = zynqmp_get_silicon_ver();
+ uint32_t uart_clk = 0U;
if (ver == ZYNQMP_CSU_VERSION_QEMU) {
- return 133000000;
+ uart_clk = 133000000U;
} else {
- return 100000000;
+ uart_clk = 100000000U;
}
+
+ return uart_clk;
}
#if LOG_LEVEL >= LOG_LEVEL_NOTICE
@@ -270,7 +272,7 @@
return zynqmp_devices[i].name;
}
- len = strlen(zynqmp_devices[i].name) - 2;
+ len = strlen(zynqmp_devices[i].name) - 2U;
for (j = 0; j < strlen(name); j++) {
zynqmp_devices[i].name[len] = name[j];
len++;
@@ -312,27 +314,31 @@
int32_t plat_is_smccc_feature_available(u_register_t fid)
{
+ int32_t ret = SMC_ARCH_CALL_NOT_SUPPORTED;
+
switch (fid) {
case SMCCC_ARCH_SOC_ID:
- return SMC_ARCH_CALL_SUCCESS;
+ ret = SMC_ARCH_CALL_SUCCESS;
+ break;
default:
- return SMC_ARCH_CALL_NOT_SUPPORTED;
+ break;
}
- return SMC_ARCH_CALL_NOT_SUPPORTED;
+ return ret;
}
int32_t plat_get_soc_version(void)
{
uint32_t chip_id = zynqmp_get_silicon_ver();
uint32_t manfid = SOC_ID_SET_JEP_106(JEDEC_XILINX_BKID, JEDEC_XILINX_MFID);
+ uint32_t result = (manfid | (chip_id & 0xFFFFU));
- return (int32_t)(manfid | (chip_id & 0xFFFF));
+ return (int32_t)result;
}
int32_t plat_get_soc_revision(void)
{
- return mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
+ return (int32_t)mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
}
static uint32_t zynqmp_get_ps_ver(void)
@@ -366,7 +372,7 @@
VERBOSE("TF-A running on %s/%s at 0x%x\n",
zynqmp_print_silicon_idcode(), label, BL31_BASE);
VERBOSE("TF-A running on v%d/RTL%d.%d\n",
- zynqmp_get_ps_ver(), (rtl & 0xf0) >> 4, rtl & 0xf);
+ zynqmp_get_ps_ver(), (rtl & 0xf0U) >> 4U, rtl & 0xfU);
}
#else
static inline void zynqmp_print_platform_name(void) { }
@@ -375,7 +381,7 @@
uint32_t zynqmp_get_bootmode(void)
{
uint32_t r;
- unsigned int ret;
+ enum pm_ret_status ret;
ret = pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r);
@@ -388,29 +394,22 @@
void zynqmp_config_setup(void)
{
- uint64_t counter_freq;
-
/* Configure IPI data for ZynqMP */
zynqmp_ipi_config_table_init();
zynqmp_print_platform_name();
-
- /* Configure counter frequency */
- counter_freq = read_cntfrq_el0();
- if (counter_freq == ZYNQMP_DEFAULT_COUNTER_FREQ) {
- write_cntfrq_el0(plat_get_syscnt_freq2());
- }
-
- generic_delay_timer_init();
}
uint32_t plat_get_syscnt_freq2(void)
{
uint32_t ver = zynqmp_get_silicon_ver();
+ uint32_t ret = 0U;
if (ver == ZYNQMP_CSU_VERSION_QEMU) {
- return 65000000;
+ ret = 65000000U;
} else {
- return mmio_read_32(IOU_SCNTRS_BASEFREQ);
+ ret = mmio_read_32((uint64_t)IOU_SCNTRS_BASEFREQ);
}
+
+ return ret;
}
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index ede3a21..b29e1c6 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -13,6 +13,7 @@
#include <common/debug.h>
#include <common/fdt_fixup.h>
#include <common/fdt_wrappers.h>
+#include <drivers/generic_delay_timer.h>
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <libfdt.h>
@@ -59,7 +60,7 @@
bl32_image_ep_info.pc = BL32_BASE;
bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
- bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+ bl33_image_ep_info.spsr = (uint32_t)SPSR_64(MODE_EL2, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
}
@@ -77,6 +78,15 @@
(void)arg2;
(void)arg3;
uint64_t tfa_handoff_addr;
+ uint64_t counter_freq;
+
+ /* Configure counter frequency */
+ counter_freq = read_cntfrq_el0();
+ if (counter_freq == ZYNQMP_DEFAULT_COUNTER_FREQ) {
+ write_cntfrq_el0(plat_get_syscnt_freq2());
+ }
+
+ generic_delay_timer_init();
setup_console();
@@ -96,7 +106,7 @@
SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
- tfa_handoff_addr = mmio_read_32(PMU_GLOBAL_GEN_STORAGE6);
+ tfa_handoff_addr = (uint64_t)mmio_read_32(PMU_GLOBAL_GEN_STORAGE6);
if (zynqmp_get_bootmode() == ZYNQMP_BOOTMODE_JTAG) {
bl31_set_default_config();
@@ -109,10 +119,10 @@
panic();
}
}
- if (bl32_image_ep_info.pc != 0) {
+ if (bl32_image_ep_info.pc != 0U) {
NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
}
- if (bl33_image_ep_info.pc != 0) {
+ if (bl33_image_ep_info.pc != 0U) {
NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
}
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 68485cf..cd3bbbc 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -60,9 +60,9 @@
/* CRL registers and bitfields */
#define CRL_APB_BASE U(0xFF5E0000)
-#define CRL_APB_BOOT_MODE_USER (CRL_APB_BASE + 0x200)
-#define CRL_APB_RESET_CTRL (CRL_APB_BASE + 0x218)
-#define CRL_APB_RST_LPD_TOP (CRL_APB_BASE + 0x23C)
+#define CRL_APB_BOOT_MODE_USER (CRL_APB_BASE + U(0x200))
+#define CRL_APB_RESET_CTRL (CRL_APB_BASE + U(0x218))
+#define CRL_APB_RST_LPD_TOP (CRL_APB_BASE + U(0x23C))
#define CRL_APB_BOOT_PIN_CTRL (CRL_APB_BASE + U(0x250))
#define CRL_APB_CLK_BASE U(0xFF5E0020)
@@ -75,18 +75,15 @@
#define CRL_APB_BOOT_PIN_MASK (U(0xf0f) << 0)
#define CRL_APB_BOOT_DRIVE_PIN_1_SHIFT U(9)
#define CRL_APB_BOOT_ENABLE_PIN_1_SHIFT U(1)
-#define CRL_APB_BOOT_ENABLE_PIN_1 (U(0x1) << \
- CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
-#define CRL_APB_BOOT_DRIVE_PIN_1 (U(0x1) << \
- CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
+#define CRL_APB_BOOT_ENABLE_PIN_1 (U(0x1) << CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
+#define CRL_APB_BOOT_DRIVE_PIN_1 (U(0x1) << CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
#define ZYNQMP_BOOTMODE_JTAG U(0)
-#define ZYNQMP_ULPI_RESET_VAL_HIGH (CRL_APB_BOOT_ENABLE_PIN_1 | \
- CRL_APB_BOOT_DRIVE_PIN_1)
+#define ZYNQMP_ULPI_RESET_VAL_HIGH (CRL_APB_BOOT_ENABLE_PIN_1 | CRL_APB_BOOT_DRIVE_PIN_1)
#define ZYNQMP_ULPI_RESET_VAL_LOW CRL_APB_BOOT_ENABLE_PIN_1
/* system counter registers and bitfields */
#define IOU_SCNTRS_BASE U(0xFF260000)
-#define IOU_SCNTRS_BASEFREQ (IOU_SCNTRS_BASE + 0x20)
+#define IOU_SCNTRS_BASEFREQ (IOU_SCNTRS_BASE + U(0x20))
/* APU registers and bitfields */
#define APU_BASE U(0xFD5C0000)
@@ -104,11 +101,11 @@
/* PMU registers and bitfields */
#define PMU_GLOBAL_BASE U(0xFFD80000)
#define PMU_GLOBAL_CNTRL (PMU_GLOBAL_BASE + 0)
-#define PMU_GLOBAL_GEN_STORAGE6 (PMU_GLOBAL_BASE + 0x48)
-#define PMU_GLOBAL_REQ_PWRUP_STATUS (PMU_GLOBAL_BASE + 0x110)
-#define PMU_GLOBAL_REQ_PWRUP_EN (PMU_GLOBAL_BASE + 0x118)
-#define PMU_GLOBAL_REQ_PWRUP_DIS (PMU_GLOBAL_BASE + 0x11c)
-#define PMU_GLOBAL_REQ_PWRUP_TRIG (PMU_GLOBAL_BASE + 0x120)
+#define PMU_GLOBAL_GEN_STORAGE6 (PMU_GLOBAL_BASE + U(0x48))
+#define PMU_GLOBAL_REQ_PWRUP_STATUS (PMU_GLOBAL_BASE + U(0x110))
+#define PMU_GLOBAL_REQ_PWRUP_EN (PMU_GLOBAL_BASE + U(0x118))
+#define PMU_GLOBAL_REQ_PWRUP_DIS (PMU_GLOBAL_BASE + U(0x11c))
+#define PMU_GLOBAL_REQ_PWRUP_TRIG (PMU_GLOBAL_BASE + U(0x120))
#define PMU_GLOBAL_CNTRL_FW_IS_PRESENT (1 << 4)
@@ -191,10 +188,10 @@
#define UART_BAUDRATE 115200
/* Silicon version detection */
-#define ZYNQMP_SILICON_VER_MASK 0xF000
+#define ZYNQMP_SILICON_VER_MASK U(0xF000)
#define ZYNQMP_SILICON_VER_SHIFT 12
#define ZYNQMP_CSU_VERSION_SILICON 0
-#define ZYNQMP_CSU_VERSION_QEMU 3
+#define ZYNQMP_CSU_VERSION_QEMU U(3)
#define ZYNQMP_RTL_VER_MASK 0xFF0U
#define ZYNQMP_RTL_VER_SHIFT 4
@@ -203,38 +200,32 @@
#define ZYNQMP_PS_VER_SHIFT 0
#define ZYNQMP_CSU_BASEADDR U(0xFFCA0000)
-#define ZYNQMP_CSU_IDCODE_OFFSET 0x40U
+#define ZYNQMP_CSU_IDCODE_OFFSET U(0x40)
-#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_XILINX_ID_SHIFT U(0)
+#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK (U(0xFFF) << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
+#define ZYNQMP_CSU_IDCODE_XILINX_ID U(0x093)
-#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 15U
-#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK (0xFU << \
- ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
-#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 21U
-#define ZYNQMP_CSU_IDCODE_FAMILY_MASK (0x7FU << \
- ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
-#define ZYNQMP_CSU_IDCODE_FAMILY 0x23
+#define ZYNQMP_CSU_IDCODE_SVD_SHIFT U(12)
+#define ZYNQMP_CSU_IDCODE_SVD_MASK (0x7U << ZYNQMP_CSU_IDCODE_SVD_SHIFT)
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT U(15)
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK (U(0xF) << ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT U(19)
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK (U(0x3) << ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
+#define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT U(21)
+#define ZYNQMP_CSU_IDCODE_FAMILY_MASK (U(0x7F) << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
+#define ZYNQMP_CSU_IDCODE_FAMILY U(0x23)
-#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT 28U
-#define ZYNQMP_CSU_IDCODE_REVISION_MASK (0xFU << \
- ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
-#define ZYNQMP_CSU_IDCODE_REVISION 0U
+#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT U(28)
+#define ZYNQMP_CSU_IDCODE_REVISION_MASK (U(0xF) << ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
+#define ZYNQMP_CSU_IDCODE_REVISION U(0)
-#define ZYNQMP_CSU_VERSION_OFFSET 0x44U
+#define ZYNQMP_CSU_VERSION_OFFSET U(0x44)
/* Efuse */
#define EFUSE_BASEADDR U(0xFFCC0000)
#define EFUSE_IPDISABLE_OFFSET 0x1018
-#define EFUSE_IPDISABLE_VERSION 0x1FFU
+#define EFUSE_IPDISABLE_VERSION U(0x1FF)
#define ZYNQMP_EFUSE_IPDISABLE_SHIFT 20
/* Access control register defines */
@@ -356,11 +347,11 @@
#define IOU_SLCR_WDT_CLK_SEL (IOU_SLCR_BASEADDR + 0x300)
/* Global general storage register base address */
-#define GGS_BASEADDR (0xFFD80030U)
+#define GGS_BASEADDR U(0xFFD80030)
#define GGS_NUM_REGS U(4)
/* Persistent global general storage register base address */
-#define PGGS_BASEADDR (0xFFD80050U)
+#define PGGS_BASEADDR U(0xFFD80050)
#define PGGS_NUM_REGS U(4)
/* PMU GGS4 register 4 is used for warm restart boot health status */
@@ -369,7 +360,7 @@
#define PM_BOOT_HEALTH_STATUS_MASK U(0x01)
/* WDT restart scope shift and mask */
#define RESTART_SCOPE_SHIFT (3)
-#define RESTART_SCOPE_MASK (0x3U << RESTART_SCOPE_SHIFT)
+#define RESTART_SCOPE_MASK (U(0x3) << RESTART_SCOPE_SHIFT)
/* AFI registers */
#define AFIFM6_WRCTRL U(13)
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index 58db2e4..3fae407 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -32,26 +32,27 @@
static int32_t zynqmp_pwr_domain_on(u_register_t mpidr)
{
- uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+ int32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
const struct pm_proc *proc;
uint32_t buff[3];
enum pm_ret_status ret;
+ int32_t result = PSCI_E_INTERN_FAIL;
VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
if (cpu_id == -1) {
- return PSCI_E_INTERN_FAIL;
+ goto exit_label;
}
proc = pm_get_proc(cpu_id);
if (proc == NULL) {
- return PSCI_E_INTERN_FAIL;
+ goto exit_label;
}
/* Check the APU proc status before wakeup */
ret = pm_get_node_status(proc->node_id, buff);
if ((ret != PM_RET_SUCCESS) || (buff[0] == PM_PROC_STATE_SUSPENDING)) {
- return PSCI_E_INTERN_FAIL;
+ goto exit_label;
}
/* Clear power down request */
@@ -60,7 +61,10 @@
/* Send request to PMU to wake up selected APU CPU core */
(void)pm_req_wakeup(proc->node_id, 1, zynqmp_sec_entry, REQ_ACK_BLOCKING);
- return PSCI_E_SUCCESS;
+ result = PSCI_E_SUCCESS;
+
+exit_label:
+ return result;
}
static void zynqmp_pwr_domain_off(const psci_power_state_t *target_state)
@@ -101,9 +105,10 @@
return;
}
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+ for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
+ }
state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ?
PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
@@ -194,6 +199,7 @@
VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
uint32_t pstate = psci_get_pstate_type(power_state);
+ int32_t result = PSCI_E_INVALID_PARAMS;
assert(req_state);
@@ -204,11 +210,11 @@
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
}
/* We expect the 'state id' to be zero */
- if (psci_get_pstate_id(power_state) != 0U) {
- return PSCI_E_INVALID_PARAMS;
+ if (psci_get_pstate_id(power_state) == 0U) {
+ result = PSCI_E_SUCCESS;
}
- return PSCI_E_SUCCESS;
+ return result;
}
static void zynqmp_get_sys_suspend_power_state(psci_power_state_t *req_state)
diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c
index 65faa2f..3a4c172 100644
--- a/plat/xilinx/zynqmp/plat_zynqmp.c
+++ b/plat/xilinx/zynqmp/plat_zynqmp.c
@@ -10,13 +10,12 @@
int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
{
- if ((mpidr & MPIDR_CLUSTER_MASK) != 0U) {
- return -1;
+ int32_t core_pos = -1;
+
+ if (((mpidr & MPIDR_CLUSTER_MASK) == 0U) &&
+ ((mpidr & MPIDR_CPU_MASK) < PLATFORM_CORE_COUNT)) {
+ core_pos = (int32_t)zynqmp_calc_core_pos(mpidr);
}
- if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT) {
- return -1;
- }
-
- return zynqmp_calc_core_pos(mpidr);
+ return core_pos;
}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 91adb07..aad3114 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -110,8 +110,8 @@
.type = TYPE_MUX, \
.offset = PERIPH_MUX_SHIFT, \
.width = PERIPH_MUX_WIDTH, \
- .clkflags = CLK_SET_RATE_NO_REPARENT | \
- CLK_IS_BASIC, \
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |\
+ CLK_IS_BASIC), \
.typeflags = NA_TYPE_FLAGS, \
.mult = NA_MULT, \
.div = NA_DIV, \
@@ -122,9 +122,9 @@
.type = TYPE_MUX, \
.offset = PERIPH_MUX_SHIFT, \
.width = PERIPH_MUX_WIDTH, \
- .clkflags = CLK_IGNORE_UNUSED | \
+ .clkflags = (uint16_t)(CLK_IGNORE_UNUSED |\
CLK_SET_RATE_NO_REPARENT | \
- CLK_IS_BASIC, \
+ CLK_IS_BASIC), \
.typeflags = NA_TYPE_FLAGS, \
.mult = NA_MULT, \
.div = NA_DIV, \
@@ -135,10 +135,10 @@
.type = TYPE_DIV1, \
.offset = PERIPH_DIV1_SHIFT, \
.width = PERIPH_DIV1_WIDTH, \
- .clkflags = CLK_SET_RATE_NO_REPARENT | \
- CLK_IS_BASIC, \
- .typeflags = CLK_DIVIDER_ONE_BASED | \
- CLK_DIVIDER_ALLOW_ZERO, \
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |\
+ CLK_IS_BASIC), \
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | \
+ CLK_DIVIDER_ALLOW_ZERO), \
.mult = NA_MULT, \
.div = NA_DIV, \
}
@@ -148,11 +148,11 @@
.type = TYPE_DIV2, \
.offset = PERIPH_DIV2_SHIFT, \
.width = PERIPH_DIV2_WIDTH, \
- .clkflags = CLK_SET_RATE_NO_REPARENT | \
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |\
CLK_SET_RATE_PARENT | \
- CLK_IS_BASIC, \
- .typeflags = CLK_DIVIDER_ONE_BASED | \
- CLK_DIVIDER_ALLOW_ZERO, \
+ CLK_IS_BASIC), \
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | \
+ CLK_DIVIDER_ALLOW_ZERO), \
.mult = NA_MULT, \
.div = NA_DIV, \
}
@@ -162,11 +162,11 @@
.type = TYPE_DIV##id, \
.offset = PERIPH_DIV##id##_SHIFT, \
.width = PERIPH_DIV##id##_WIDTH, \
- .clkflags = CLK_IGNORE_UNUSED | \
+ .clkflags = (uint16_t)(CLK_IGNORE_UNUSED | \
CLK_SET_RATE_NO_REPARENT | \
- CLK_IS_BASIC, \
- .typeflags = CLK_DIVIDER_ONE_BASED | \
- CLK_DIVIDER_ALLOW_ZERO, \
+ CLK_IS_BASIC), \
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | \
+ CLK_DIVIDER_ALLOW_ZERO), \
.mult = NA_MULT, \
.div = NA_DIV, \
}
@@ -176,9 +176,9 @@
.type = TYPE_GATE, \
.offset = PERIPH_GATE_SHIFT, \
.width = PERIPH_GATE_WIDTH, \
- .clkflags = CLK_SET_RATE_PARENT | \
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT | \
CLK_SET_RATE_GATE | \
- CLK_IS_BASIC, \
+ CLK_IS_BASIC), \
.typeflags = NA_TYPE_FLAGS, \
.mult = NA_MULT, \
.div = NA_DIV, \
@@ -189,9 +189,9 @@
.type = TYPE_GATE, \
.offset = PERIPH_GATE_SHIFT, \
.width = PERIPH_GATE_WIDTH, \
- .clkflags = CLK_SET_RATE_PARENT | \
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT | \
CLK_IGNORE_UNUSED | \
- CLK_IS_BASIC, \
+ CLK_IS_BASIC), \
.typeflags = NA_TYPE_FLAGS, \
.mult = NA_MULT, \
.div = NA_DIV, \
@@ -253,7 +253,7 @@
.type = TYPE_PLL,
.offset = NA_SHIFT,
.width = NA_WIDTH,
- .clkflags = CLK_SET_RATE_NO_REPARENT,
+ .clkflags = (uint16_t)CLK_SET_RATE_NO_REPARENT,
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -265,7 +265,7 @@
.type = TYPE_PLL,
.offset = NA_SHIFT,
.width = NA_WIDTH,
- .clkflags = CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT,
+ .clkflags = (uint16_t)(CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -277,7 +277,7 @@
.type = TYPE_MUX,
.offset = PLL_PRESRC_MUX_SHIFT,
.width = PLL_PRESRC_MUX_WIDTH,
- .clkflags = CLK_IS_BASIC,
+ .clkflags = (uint16_t)CLK_IS_BASIC,
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -289,7 +289,7 @@
.type = TYPE_FIXEDFACTOR,
.offset = NA_SHIFT,
.width = NA_WIDTH,
- .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT),
.typeflags = NA_TYPE_FLAGS,
.mult = 1,
.div = 2,
@@ -301,9 +301,9 @@
.type = TYPE_MUX,
.offset = PLL_DIV2_MUX_SHIFT,
.width = PLL_DIV2_MUX_WIDTH,
- .clkflags = CLK_SET_RATE_NO_REPARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |
CLK_SET_RATE_PARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -315,7 +315,7 @@
.type = TYPE_MUX,
.offset = PLL_POSTSRC_MUX_SHIFT,
.width = PLL_POSTSRC_MUX_WIDTH,
- .clkflags = CLK_IS_BASIC,
+ .clkflags = (uint16_t)CLK_IS_BASIC,
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -327,9 +327,9 @@
.type = TYPE_MUX,
.offset = PLL_BYPASS_MUX_SHIFT,
.width = PLL_BYPASS_MUX_WIDTH,
- .clkflags = CLK_SET_RATE_NO_REPARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |
CLK_SET_RATE_PARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -341,7 +341,7 @@
.type = TYPE_MUX,
.offset = PERIPH_MUX_SHIFT,
.width = PERIPH_MUX_WIDTH,
- .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -350,8 +350,8 @@
.type = TYPE_DIV1,
.offset = PERIPH_DIV1_SHIFT,
.width = PERIPH_DIV1_WIDTH,
- .clkflags = CLK_IS_BASIC,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .clkflags = (uint16_t)CLK_IS_BASIC,
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -386,9 +386,9 @@
.type = TYPE_MUX,
.offset = PERIPH_MUX_SHIFT,
.width = PERIPH_MUX_WIDTH,
- .clkflags = CLK_SET_RATE_NO_REPARENT |
- CLK_SET_RATE_PARENT | CLK_IS_BASIC,
- .typeflags = CLK_FRAC,
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |
+ CLK_SET_RATE_PARENT | CLK_IS_BASIC),
+ .typeflags = (uint16_t)CLK_FRAC,
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -396,10 +396,10 @@
.type = TYPE_DIV1,
.offset = PERIPH_DIV1_SHIFT,
.width = PERIPH_DIV1_WIDTH,
- .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
- CLK_IS_BASIC,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
- CLK_FRAC,
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
+ CLK_IS_BASIC),
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
+ CLK_FRAC),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -407,10 +407,10 @@
.type = TYPE_DIV2,
.offset = PERIPH_DIV2_SHIFT,
.width = PERIPH_DIV2_WIDTH,
- .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
- CLK_IS_BASIC,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
- CLK_FRAC,
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
+ CLK_IS_BASIC),
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
+ CLK_FRAC),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -418,9 +418,9 @@
.type = TYPE_GATE,
.offset = PERIPH_GATE_SHIFT,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_GATE |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -435,8 +435,8 @@
.type = TYPE_GATE,
.offset = USB_GATE_SHIFT,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC |
- CLK_SET_RATE_GATE,
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC |
+ CLK_SET_RATE_GATE),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -448,8 +448,8 @@
.type = TYPE_DIV1,
.offset = 8,
.width = 6,
- .clkflags = CLK_IS_BASIC,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .clkflags = (uint16_t)CLK_IS_BASIC,
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -460,8 +460,8 @@
.type = TYPE_DIV1,
.offset = 8,
.width = 6,
- .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -481,9 +481,9 @@
.type = TYPE_GATE,
.offset = 25,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_IGNORE_UNUSED |
+ .clkflags = (uint16_t)(CLK_IGNORE_UNUSED |
CLK_SET_RATE_PARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -495,9 +495,9 @@
.type = TYPE_GATE,
.offset = 24,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_IGNORE_UNUSED |
+ .clkflags = (uint16_t)(CLK_IGNORE_UNUSED |
CLK_SET_RATE_PARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -509,9 +509,9 @@
.type = TYPE_MUX,
.offset = 0,
.width = 1,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -524,8 +524,8 @@
.type = TYPE_DIV1,
.offset = 8,
.width = 6,
- .clkflags = CLK_IS_BASIC | CLK_IS_CRITICAL,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .clkflags = (uint16_t)(CLK_IS_BASIC | CLK_IS_CRITICAL),
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -537,8 +537,8 @@
.type = TYPE_DIV1,
.offset = PERIPH_DIV1_SHIFT,
.width = PERIPH_DIV1_WIDTH,
- .clkflags = CLK_IS_BASIC,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .clkflags = (uint16_t)(CLK_IS_BASIC),
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -546,8 +546,8 @@
.type = TYPE_DIV2,
.offset = PERIPH_DIV2_SHIFT,
.width = PERIPH_DIV2_WIDTH,
- .clkflags = CLK_IS_BASIC | CLK_SET_RATE_PARENT,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .clkflags = (uint16_t)(CLK_IS_BASIC | CLK_SET_RATE_PARENT),
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -555,7 +555,7 @@
.type = TYPE_GATE,
.offset = PERIPH_GATE_SHIFT,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -567,7 +567,7 @@
.type = TYPE_GATE,
.offset = 25,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -579,7 +579,7 @@
.type = TYPE_GATE,
.offset = 26,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -592,8 +592,8 @@
.type = TYPE_DIV1,
.offset = 8,
.width = 6,
- .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC),
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -601,9 +601,9 @@
.type = TYPE_DIV2,
.offset = 16,
.width = 6,
- .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC |
- CLK_SET_RATE_PARENT,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC |
+ CLK_SET_RATE_PARENT),
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -614,9 +614,9 @@
.type = TYPE_MUX,
.offset = 1,
.width = 1,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -628,9 +628,9 @@
.type = TYPE_MUX,
.offset = 6,
.width = 1,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -642,9 +642,9 @@
.type = TYPE_MUX,
.offset = 11,
.width = 1,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -656,9 +656,9 @@
.type = TYPE_MUX,
.offset = 16,
.width = 1,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -670,7 +670,7 @@
.type = TYPE_GATE,
.offset = 25,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -682,7 +682,7 @@
.type = TYPE_GATE,
.offset = 26,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_IS_BASIC,
+ .clkflags = (uint16_t)(CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -694,9 +694,9 @@
.type = TYPE_MUX,
.offset = 20,
.width = 2,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -708,9 +708,9 @@
.type = TYPE_MUX,
.offset = 0,
.width = 7,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -722,9 +722,9 @@
.type = TYPE_MUX,
.offset = 15,
.width = 1,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -736,9 +736,9 @@
.type = TYPE_MUX,
.offset = 7,
.width = 1,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -750,9 +750,9 @@
.type = TYPE_MUX,
.offset = 22,
.width = 1,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -764,8 +764,8 @@
.type = TYPE_GATE,
.offset = 25,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_IGNORE_UNUSED |
- CLK_IS_BASIC,
+ .clkflags = (uint16_t)(CLK_IGNORE_UNUSED |
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -777,9 +777,9 @@
.type = TYPE_MUX,
.offset = 0,
.width = 3,
- .clkflags = CLK_SET_RATE_PARENT |
+ .clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT |
- CLK_IS_BASIC,
+ CLK_IS_BASIC),
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -792,8 +792,8 @@
.type = TYPE_DIV1,
.offset = 8,
.width = 6,
- .clkflags = CLK_IS_BASIC,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .clkflags = (uint16_t)CLK_IS_BASIC,
+ .typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -831,7 +831,7 @@
.status_reg = CRF_APB_PLL_STATUS,
.parents = &((int32_t []) {CLK_APLL_PRE_SRC, CLK_NA_PARENT}),
.nodes = &ignore_unused_pll_nodes,
- .num_nodes = ARRAY_SIZE(ignore_unused_pll_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(ignore_unused_pll_nodes),
},
[CLK_APLL_PRE_SRC] = {
.name = "apll_pre_src",
@@ -849,7 +849,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_pre_src_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
},
[CLK_APLL_HALF] = {
.name = "apll_half",
@@ -857,7 +857,7 @@
.status_reg = CRF_APB_PLL_STATUS,
.parents = &((int32_t []) {CLK_APLL_INT, CLK_NA_PARENT}),
.nodes = &generic_pll_half_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
},
[CLK_APLL_INT_MUX] = {
.name = "apll_int_mux",
@@ -869,7 +869,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_int_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
},
[CLK_APLL_POST_SRC] = {
.name = "apll_post_src",
@@ -887,7 +887,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_post_src_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
},
[CLK_APLL] = {
.name = "apll",
@@ -899,7 +899,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_system_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
},
[CLK_DPLL_INT] = {
.name = "dpll_int",
@@ -907,7 +907,7 @@
.status_reg = CRF_APB_PLL_STATUS,
.parents = &((int32_t []) {CLK_DPLL_PRE_SRC, CLK_NA_PARENT}),
.nodes = &generic_pll_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_nodes),
},
[CLK_DPLL_PRE_SRC] = {
.name = "dpll_pre_src",
@@ -925,7 +925,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_pre_src_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
},
[CLK_DPLL_HALF] = {
.name = "dpll_half",
@@ -933,7 +933,7 @@
.status_reg = CRF_APB_PLL_STATUS,
.parents = &((int32_t []) {CLK_DPLL_INT, CLK_NA_PARENT}),
.nodes = &generic_pll_half_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
},
[CLK_DPLL_INT_MUX] = {
.name = "dpll_int_mux",
@@ -945,7 +945,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_int_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
},
[CLK_DPLL_POST_SRC] = {
.name = "dpll_post_src",
@@ -963,7 +963,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_post_src_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
},
[CLK_DPLL] = {
.name = "dpll",
@@ -975,7 +975,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_system_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
},
[CLK_VPLL_INT] = {
.name = "vpll_int",
@@ -983,7 +983,7 @@
.status_reg = CRF_APB_PLL_STATUS,
.parents = &((int32_t []) {CLK_VPLL_PRE_SRC, CLK_NA_PARENT}),
.nodes = &ignore_unused_pll_nodes,
- .num_nodes = ARRAY_SIZE(ignore_unused_pll_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(ignore_unused_pll_nodes),
},
[CLK_VPLL_PRE_SRC] = {
.name = "vpll_pre_src",
@@ -1001,7 +1001,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_pre_src_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
},
[CLK_VPLL_HALF] = {
.name = "vpll_half",
@@ -1009,7 +1009,7 @@
.status_reg = CRF_APB_PLL_STATUS,
.parents = &((int32_t []) {CLK_VPLL_INT, CLK_NA_PARENT}),
.nodes = &generic_pll_half_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
},
[CLK_VPLL_INT_MUX] = {
.name = "vpll_int_mux",
@@ -1021,7 +1021,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_int_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
},
[CLK_VPLL_POST_SRC] = {
.name = "vpll_post_src",
@@ -1051,7 +1051,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_system_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
},
[CLK_IOPLL_INT] = {
.name = "iopll_int",
@@ -1059,7 +1059,7 @@
.status_reg = CRF_APB_PLL_STATUS,
.parents = &((int32_t []) {CLK_IOPLL_PRE_SRC, CLK_NA_PARENT}),
.nodes = &generic_pll_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_nodes),
},
[CLK_IOPLL_PRE_SRC] = {
.name = "iopll_pre_src",
@@ -1077,7 +1077,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_pre_src_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
},
[CLK_IOPLL_HALF] = {
.name = "iopll_half",
@@ -1085,7 +1085,7 @@
.status_reg = CRF_APB_PLL_STATUS,
.parents = &((int32_t []) {CLK_IOPLL_INT, CLK_NA_PARENT}),
.nodes = &generic_pll_half_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
},
[CLK_IOPLL_INT_MUX] = {
.name = "iopll_int_mux",
@@ -1097,7 +1097,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_int_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
},
[CLK_IOPLL_POST_SRC] = {
.name = "iopll_post_src",
@@ -1115,7 +1115,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_post_src_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
},
[CLK_IOPLL] = {
.name = "iopll",
@@ -1127,7 +1127,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_system_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
},
[CLK_RPLL_INT] = {
.name = "rpll_int",
@@ -1135,7 +1135,7 @@
.status_reg = CRF_APB_PLL_STATUS,
.parents = &((int32_t []) {CLK_RPLL_PRE_SRC, CLK_NA_PARENT}),
.nodes = &generic_pll_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_nodes),
},
[CLK_RPLL_PRE_SRC] = {
.name = "rpll_pre_src",
@@ -1154,7 +1154,7 @@
}),
.nodes = &generic_pll_pre_src_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
},
[CLK_RPLL_HALF] = {
.name = "rpll_half",
@@ -1162,7 +1162,7 @@
.status_reg = CRF_APB_PLL_STATUS,
.parents = &((int32_t []) {CLK_RPLL_INT, CLK_NA_PARENT}),
.nodes = &generic_pll_half_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
},
[CLK_RPLL_INT_MUX] = {
.name = "rpll_int_mux",
@@ -1174,7 +1174,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_int_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
},
[CLK_RPLL_POST_SRC] = {
.name = "rpll_post_src",
@@ -1192,7 +1192,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_post_src_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
},
[CLK_RPLL] = {
.name = "rpll",
@@ -1204,7 +1204,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_pll_system_nodes,
- .num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
},
/* Peripheral Clocks */
[CLK_ACPU] = {
@@ -1219,7 +1219,7 @@
CLK_NA_PARENT
}),
.nodes = &acpu_nodes,
- .num_nodes = ARRAY_SIZE(acpu_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(acpu_nodes),
},
[CLK_ACPU_FULL] = {
.name = "acpu_full",
@@ -1244,7 +1244,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_DBG_FPD] = {
.name = "dbg_fpd",
@@ -1258,7 +1258,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_DBG_TSTMP] = {
.name = "dbg_tstmp",
@@ -1272,7 +1272,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_nodes),
},
[CLK_DP_VIDEO_REF] = {
.name = "dp_video_ref",
@@ -1286,7 +1286,7 @@
CLK_NA_PARENT
}),
.nodes = &dp_audio_video_ref_nodes,
- .num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(dp_audio_video_ref_nodes),
},
[CLK_DP_AUDIO_REF] = {
.name = "dp_audio_ref",
@@ -1300,7 +1300,7 @@
CLK_NA_PARENT
}),
.nodes = &dp_audio_video_ref_nodes,
- .num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(dp_audio_video_ref_nodes),
},
[CLK_DP_STC_REF] = {
.name = "dp_stc_ref",
@@ -1314,7 +1314,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_DPDMA_REF] = {
.name = "dpdma_ref",
@@ -1328,7 +1328,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_DDR_REF] = {
.name = "ddr_ref",
@@ -1340,7 +1340,7 @@
CLK_NA_PARENT
}),
.nodes = &ddr_nodes,
- .num_nodes = ARRAY_SIZE(ddr_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(ddr_nodes),
},
[CLK_GPU_REF] = {
.name = "gpu_ref",
@@ -1354,7 +1354,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_SATA_REF] = {
.name = "sata_ref",
@@ -1368,7 +1368,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_PCIE_REF] = {
.name = "pcie_ref",
@@ -1382,7 +1382,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_GDMA_REF] = {
.name = "gdma_ref",
@@ -1396,7 +1396,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_GTGREF0_REF] = {
.name = "gtgref0_ref",
@@ -1410,7 +1410,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_TOPSW_MAIN] = {
.name = "topsw_main",
@@ -1424,7 +1424,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_unused_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
},
[CLK_TOPSW_LSBUS] = {
.name = "topsw_lsbus",
@@ -1438,7 +1438,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_unused_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
},
[CLK_IOU_SWITCH] = {
.name = "iou_switch",
@@ -1452,7 +1452,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_unused_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
},
[CLK_GEM0_REF_UNGATED] = {
.name = "gem0_ref_ung",
@@ -1574,7 +1574,7 @@
CLK_NA_PARENT
}),
.nodes = &usb_nodes,
- .num_nodes = ARRAY_SIZE(usb_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(usb_nodes),
},
[CLK_USB1_BUS_REF] = {
.name = "usb1_bus_ref",
@@ -1588,7 +1588,7 @@
CLK_NA_PARENT
}),
.nodes = &usb_nodes,
- .num_nodes = ARRAY_SIZE(usb_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(usb_nodes),
},
[CLK_USB3_DUAL_REF] = {
.name = "usb3_dual_ref",
@@ -1602,7 +1602,7 @@
CLK_NA_PARENT
}),
.nodes = &usb_nodes,
- .num_nodes = ARRAY_SIZE(usb_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(usb_nodes),
},
[CLK_QSPI_REF] = {
.name = "qspi_ref",
@@ -1616,7 +1616,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_SDIO0_REF] = {
.name = "sdio0_ref",
@@ -1630,7 +1630,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_SDIO1_REF] = {
.name = "sdio1_ref",
@@ -1644,7 +1644,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_UART0_REF] = {
.name = "uart0_ref",
@@ -1658,7 +1658,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_UART1_REF] = {
.name = "uart1_ref",
@@ -1672,7 +1672,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_SPI0_REF] = {
.name = "spi0_ref",
@@ -1686,7 +1686,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_SPI1_REF] = {
.name = "spi1_ref",
@@ -1700,7 +1700,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_CAN0_REF] = {
.name = "can0_ref",
@@ -1714,7 +1714,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_CAN1_REF] = {
.name = "can1_ref",
@@ -1728,7 +1728,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_NAND_REF] = {
.name = "nand_ref",
@@ -1742,7 +1742,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_GEM_TSU_REF] = {
.name = "gem_tsu_ref",
@@ -1756,7 +1756,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_DLL_REF] = {
.name = "dll_ref",
@@ -1768,7 +1768,7 @@
CLK_NA_PARENT
}),
.nodes = &dll_ref_nodes,
- .num_nodes = ARRAY_SIZE(dll_ref_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(dll_ref_nodes),
},
[CLK_ADMA_REF] = {
.name = "adma_ref",
@@ -1782,7 +1782,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_DBG_LPD] = {
.name = "dbg_lpd",
@@ -1796,7 +1796,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_CPU_R5] = {
.name = "cpu_r5",
@@ -1810,7 +1810,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_unused_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
},
[CLK_CSU_PLL] = {
.name = "csu_pll",
@@ -1824,7 +1824,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_PCAP] = {
.name = "pcap",
@@ -1838,7 +1838,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
},
[CLK_LPD_LSBUS] = {
.name = "lpd_lsbus",
@@ -1852,7 +1852,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_unused_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
},
[CLK_LPD_SWITCH] = {
.name = "lpd_switch",
@@ -1866,7 +1866,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_unused_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
},
[CLK_I2C0_REF] = {
.name = "i2c0_ref",
@@ -1880,7 +1880,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_I2C1_REF] = {
.name = "i2c1_ref",
@@ -1894,7 +1894,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_TIMESTAMP_REF] = {
.name = "timestamp_ref",
@@ -1912,7 +1912,7 @@
CLK_NA_PARENT
}),
.nodes = ×tamp_ref_nodes,
- .num_nodes = ARRAY_SIZE(timestamp_ref_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(timestamp_ref_nodes),
},
[CLK_PL0_REF] = {
.name = "pl0_ref",
@@ -1926,7 +1926,7 @@
CLK_NA_PARENT
}),
.nodes = &pl_nodes,
- .num_nodes = ARRAY_SIZE(pl_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
},
[CLK_PL1_REF] = {
.name = "pl1_ref",
@@ -1940,7 +1940,7 @@
CLK_NA_PARENT
}),
.nodes = &pl_nodes,
- .num_nodes = ARRAY_SIZE(pl_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
},
[CLK_PL2_REF] = {
.name = "pl2_ref",
@@ -1954,7 +1954,7 @@
CLK_NA_PARENT
}),
.nodes = &pl_nodes,
- .num_nodes = ARRAY_SIZE(pl_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
},
[CLK_PL3_REF] = {
.name = "pl3_ref",
@@ -1968,7 +1968,7 @@
CLK_NA_PARENT
}),
.nodes = &pl_nodes,
- .num_nodes = ARRAY_SIZE(pl_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
},
[CLK_AMS_REF] = {
.name = "ams_ref",
@@ -1982,7 +1982,7 @@
CLK_NA_PARENT
}),
.nodes = &generic_mux_div_div_gate_nodes,
- .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
},
[CLK_IOPLL_TO_FPD] = {
.name = "iopll_to_fpd",
@@ -1990,7 +1990,7 @@
.status_reg = 0,
.parents = &((int32_t []) {CLK_IOPLL, CLK_NA_PARENT}),
.nodes = &generic_domain_crossing_nodes,
- .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
},
[CLK_RPLL_TO_FPD] = {
.name = "rpll_to_fpd",
@@ -1998,7 +1998,7 @@
.status_reg = 0,
.parents = &((int32_t []) {CLK_RPLL, CLK_NA_PARENT}),
.nodes = &rpll_to_fpd_nodes,
- .num_nodes = ARRAY_SIZE(rpll_to_fpd_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(rpll_to_fpd_nodes),
},
[CLK_APLL_TO_LPD] = {
.name = "apll_to_lpd",
@@ -2006,7 +2006,7 @@
.status_reg = 0,
.parents = &((int32_t []) {CLK_APLL, CLK_NA_PARENT}),
.nodes = &generic_domain_crossing_nodes,
- .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
},
[CLK_DPLL_TO_LPD] = {
.name = "dpll_to_lpd",
@@ -2014,7 +2014,7 @@
.status_reg = 0,
.parents = &((int32_t []) {CLK_DPLL, CLK_NA_PARENT}),
.nodes = &generic_domain_crossing_nodes,
- .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
},
[CLK_VPLL_TO_LPD] = {
.name = "vpll_to_lpd",
@@ -2022,7 +2022,7 @@
.status_reg = 0,
.parents = &((int32_t []) {CLK_VPLL, CLK_NA_PARENT}),
.nodes = &generic_domain_crossing_nodes,
- .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
},
[CLK_GEM0_TX] = {
.name = "gem0_tx",
@@ -2033,7 +2033,7 @@
CLK_NA_PARENT
}),
.nodes = &gem_tx_nodes,
- .num_nodes = ARRAY_SIZE(gem_tx_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
},
[CLK_GEM1_TX] = {
.name = "gem1_tx",
@@ -2044,7 +2044,7 @@
CLK_NA_PARENT
}),
.nodes = &gem_tx_nodes,
- .num_nodes = ARRAY_SIZE(gem_tx_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
},
[CLK_GEM2_TX] = {
.name = "gem2_tx",
@@ -2055,7 +2055,7 @@
CLK_NA_PARENT
}),
.nodes = &gem_tx_nodes,
- .num_nodes = ARRAY_SIZE(gem_tx_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
},
[CLK_GEM3_TX] = {
.name = "gem3_tx",
@@ -2066,7 +2066,7 @@
CLK_NA_PARENT
}),
.nodes = &gem_tx_nodes,
- .num_nodes = ARRAY_SIZE(gem_tx_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
},
[CLK_GEM0_RX] = {
.name = "gem0_rx",
@@ -2077,7 +2077,7 @@
CLK_NA_PARENT
}),
.nodes = &gem_rx_nodes,
- .num_nodes = ARRAY_SIZE(gem_rx_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
},
[CLK_GEM1_RX] = {
.name = "gem1_rx",
@@ -2088,7 +2088,7 @@
CLK_NA_PARENT
}),
.nodes = &gem_rx_nodes,
- .num_nodes = ARRAY_SIZE(gem_rx_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
},
[CLK_GEM2_RX] = {
.name = "gem2_rx",
@@ -2099,7 +2099,7 @@
CLK_NA_PARENT
}),
.nodes = &gem_rx_nodes,
- .num_nodes = ARRAY_SIZE(gem_rx_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
},
[CLK_GEM3_RX] = {
.name = "gem3_rx",
@@ -2110,7 +2110,7 @@
CLK_NA_PARENT
}),
.nodes = &gem_rx_nodes,
- .num_nodes = ARRAY_SIZE(gem_rx_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
},
[CLK_ACPU_HALF] = {
.name = "acpu_half",
@@ -2121,7 +2121,7 @@
CLK_NA_PARENT
}),
.nodes = &acpu_half_nodes,
- .num_nodes = ARRAY_SIZE(acpu_half_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(acpu_half_nodes),
},
[CLK_FPD_WDT] = {
.name = "fpd_wdt",
@@ -2133,7 +2133,7 @@
CLK_NA_PARENT
}),
.nodes = &wdt_nodes,
- .num_nodes = ARRAY_SIZE(wdt_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(wdt_nodes),
},
[CLK_GPU_PP0_REF] = {
.name = "gpu_pp0_ref",
@@ -2144,7 +2144,7 @@
CLK_NA_PARENT
}),
.nodes = &gpu_pp0_nodes,
- .num_nodes = ARRAY_SIZE(gpu_pp0_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gpu_pp0_nodes),
},
[CLK_GPU_PP1_REF] = {
.name = "gpu_pp1_ref",
@@ -2155,7 +2155,7 @@
CLK_NA_PARENT
}),
.nodes = &gpu_pp1_nodes,
- .num_nodes = ARRAY_SIZE(gpu_pp1_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gpu_pp1_nodes),
},
[CLK_GEM_TSU] = {
.name = "gem_tsu",
@@ -2169,7 +2169,7 @@
CLK_NA_PARENT
}),
.nodes = &gem_tsu_nodes,
- .num_nodes = ARRAY_SIZE(gem_tsu_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(gem_tsu_nodes),
},
[CLK_CPU_R5_CORE] = {
.name = "cpu_r5_core",
@@ -2181,7 +2181,7 @@
CLK_NA_PARENT
}),
.nodes = &cpu_r5_core_nodes,
- .num_nodes = ARRAY_SIZE(cpu_r5_core_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(cpu_r5_core_nodes),
},
[CLK_CAN0_MIO] = {
.name = "can0_mio",
@@ -2209,7 +2209,7 @@
CLK_NA_PARENT
}),
.nodes = &can0_nodes,
- .num_nodes = ARRAY_SIZE(can0_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(can0_nodes),
},
[CLK_CAN1] = {
.name = "can1",
@@ -2221,7 +2221,7 @@
CLK_NA_PARENT
}),
.nodes = &can1_nodes,
- .num_nodes = ARRAY_SIZE(can1_nodes),
+ .num_nodes = (uint8_t)ARRAY_SIZE(can1_nodes),
},
[CLK_LPD_WDT] = {
.name = "lpd_wdt",
@@ -2405,12 +2405,16 @@
static bool pm_clock_valid(uint32_t clock_id)
{
unsigned int i;
+ bool valid = true;
- for (i = 0U; i < ARRAY_SIZE(pm_clk_invalid_list); i++)
- if (pm_clk_invalid_list[i] == clock_id)
- return 0;
+ for (i = 0U; i < ARRAY_SIZE(pm_clk_invalid_list); i++) {
+ if (pm_clk_invalid_list[i] == clock_id) {
+ valid = false;
+ break;
+ }
+ }
- return 1;
+ return valid;
}
/**
@@ -2455,15 +2459,17 @@
*/
void pm_api_clock_get_name(uint32_t clock_id, char *name)
{
- if (clock_id == CLK_MAX) {
+ uint32_t clock_id_num = clock_id;
+
+ if (clock_id_num == CLK_MAX) {
(void)memcpy(name, END_OF_CLK, ((sizeof(END_OF_CLK) > CLK_NAME_LEN) ?
CLK_NAME_LEN : sizeof(END_OF_CLK)));
} else if ((clock_id > CLK_MAX) || (!pm_clock_valid(clock_id))) {
(void)memset(name, 0, CLK_NAME_LEN);
- } else if (clock_id < CLK_MAX_OUTPUT_CLK) {
- (void)memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
+ } else if (clock_id_num < (uint32_t)CLK_MAX_OUTPUT_CLK) {
+ (void)memcpy(name, clocks[clock_id_num].name, CLK_NAME_LEN);
} else {
- (void)memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
+ (void)memcpy(name, ext_clocks[clock_id_num - (uint32_t)CLK_MAX_OUTPUT_CLK].name,
CLK_NAME_LEN);
}
}
@@ -2490,13 +2496,15 @@
uint8_t num_nodes;
uint32_t i;
uint16_t typeflags;
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
if (!pm_clock_valid(clock_id)) {
- return PM_RET_ERROR_ARGS;
+ goto exit_label;
}
if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
- return PM_RET_ERROR_NOTSUPPORTED;
+ status = PM_RET_ERROR_NOTSUPPORTED;
+ goto exit_label;
}
(void)memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
@@ -2505,7 +2513,8 @@
/* Skip parent till index */
if (index >= num_nodes) {
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
+ goto exit_label;
}
for (i = 0; i < 3U; i++) {
@@ -2514,16 +2523,19 @@
}
topology[i] = clock_nodes[index + i].type;
- topology[i] |= clock_nodes[index + i].clkflags <<
- CLK_CLKFLAGS_SHIFT;
+ topology[i] |= ((uint32_t)clock_nodes[index + i].clkflags <<
+ CLK_CLKFLAGS_SHIFT);
typeflags = clock_nodes[index + i].typeflags;
- topology[i] |= (typeflags & CLK_TYPEFLAGS_BITS_MASK) <<
- CLK_TYPEFLAGS_SHIFT;
- topology[i] |= (typeflags & CLK_TYPEFLAGS2_BITS_MASK) >>
- (CLK_TYPEFLAGS_BITS - CLK_TYPEFLAGS2_SHIFT);
+ topology[i] |= ((uint32_t)(typeflags & CLK_TYPEFLAGS_BITS_MASK) <<
+ CLK_TYPEFLAGS_SHIFT);
+ topology[i] |= ((uint32_t)(typeflags & CLK_TYPEFLAGS2_BITS_MASK) >>
+ (CLK_TYPEFLAGS_BITS - CLK_TYPEFLAGS2_SHIFT));
}
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
+
+exit_label:
+ return status;
}
/**
@@ -2546,13 +2558,15 @@
const struct pm_clock_node *clock_nodes;
uint8_t num_nodes;
uint32_t type, i;
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
if (!pm_clock_valid(clock_id)) {
- return PM_RET_ERROR_ARGS;
+ goto exit_label;
}
if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
- return PM_RET_ERROR_NOTSUPPORTED;
+ status = PM_RET_ERROR_NOTSUPPORTED;
+ goto exit_label;
}
clock_nodes = *clocks[clock_id].nodes;
@@ -2568,11 +2582,12 @@
}
/* Clock is not fixed clock */
- if (i == num_nodes) {
- return PM_RET_ERROR_ARGS;
+ if (i != num_nodes) {
+ status = PM_RET_SUCCESS;
}
- return PM_RET_SUCCESS;
+exit_label:
+ return status;
}
/**
@@ -2599,18 +2614,20 @@
{
uint32_t i;
const int32_t *clk_parents;
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
if (!pm_clock_valid(clock_id)) {
- return PM_RET_ERROR_ARGS;
+ goto exit_label;
}
if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
- return PM_RET_ERROR_NOTSUPPORTED;
+ status = PM_RET_ERROR_NOTSUPPORTED;
+ goto exit_label;
}
clk_parents = *clocks[clock_id].parents;
if (clk_parents == NULL) {
- return PM_RET_ERROR_ARGS;
+ goto exit_label;
}
(void)memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
@@ -2618,18 +2635,22 @@
/* Skip parent till index */
for (i = 0; i < index; i++) {
if (clk_parents[i] == CLK_NA_PARENT) {
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
+ goto exit_label;
}
}
for (i = 0; i < 3U; i++) {
- parents[i] = clk_parents[index + i];
+ parents[i] = (uint32_t)clk_parents[index + i];
if (clk_parents[index + i] == CLK_NA_PARENT) {
break;
}
}
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
+
+exit_label:
+ return status;
}
/**
@@ -2646,8 +2667,10 @@
enum pm_ret_status pm_api_clock_get_attributes(uint32_t clock_id,
uint32_t *attr)
{
- if (clock_id >= CLK_MAX) {
- return PM_RET_ERROR_ARGS;
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
+
+ if (clock_id >= (uint32_t)CLK_MAX) {
+ goto exit_label;
}
/* Clock valid bit */
@@ -2656,7 +2679,10 @@
/* Clock type (Output/External) */
*attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT);
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
+
+exit_label:
+ return status;
}
/**
@@ -2676,25 +2702,29 @@
{
uint32_t i;
const struct pm_clock_node *nodes;
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
if (clock_id >= CLK_MAX_OUTPUT_CLK) {
- return PM_RET_ERROR_ARGS;
+ goto exit_label;
}
nodes = *clocks[clock_id].nodes;
for (i = 0; i < clocks[clock_id].num_nodes; i++) {
if (nodes[i].type == div_type) {
if ((CLK_DIVIDER_POWER_OF_TWO &
- nodes[i].typeflags) != 0U) {
- *max_div = (1U << (BIT(nodes[i].width) - 1U));
+ nodes[i].typeflags) != 0U) {
+ *max_div = (((uint32_t)1U <<
+ ((uint32_t)BIT(nodes[i].width) - (uint32_t)1U)));
} else {
- *max_div = BIT(nodes[i].width) - 1U;
+ *max_div = (uint32_t)BIT(nodes[i].width) - (uint32_t)1U;
}
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
+ break;
}
}
- return PM_RET_ERROR_ARGS;
+exit_label:
+ return status;
}
/**
@@ -2768,14 +2798,16 @@
struct pm_pll *pm_clock_get_pll(enum clock_id clock_id)
{
uint32_t i;
+ struct pm_pll *pll = NULL;
for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
if (pm_plls[i].cid == clock_id) {
- return &pm_plls[i];
+ pll = &pm_plls[i];
+ break;
}
}
- return NULL;
+ return pll;
}
/**
@@ -2790,13 +2822,14 @@
enum pm_node_id *node_id)
{
const struct pm_pll *pll = pm_clock_get_pll(clock_id);
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
if (pll != NULL) {
*node_id = pll->nid;
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
}
- return PM_RET_ERROR_ARGS;
+ return status;
}
/**
@@ -2810,17 +2843,19 @@
struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id)
{
uint32_t i;
+ struct pm_pll *pll = NULL;
for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
if ((pm_plls[i].pre_src == clock_id) ||
(pm_plls[i].post_src == clock_id) ||
(pm_plls[i].div2 == clock_id) ||
(pm_plls[i].bypass == clock_id)) {
- return &pm_plls[i];
+ pll = &pm_plls[i];
+ break;
}
}
- return NULL;
+ return pll;
}
/**
@@ -2835,16 +2870,18 @@
*/
enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll)
{
- if (pll == NULL) {
- return PM_RET_ERROR_ARGS;
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
+
+ if (pll != NULL) {
+ /* Set the PLL mode according to the buffered mode value */
+ if (pll->mode == PLL_FRAC_MODE) {
+ status = pm_pll_set_mode(pll->nid, PM_PLL_MODE_FRACTIONAL);
+ } else {
+ status = pm_pll_set_mode(pll->nid, PM_PLL_MODE_INTEGER);
+ }
}
- /* Set the PLL mode according to the buffered mode value */
- if (pll->mode == PLL_FRAC_MODE) {
- return pm_pll_set_mode(pll->nid, PM_PLL_MODE_FRACTIONAL);
- }
-
- return pm_pll_set_mode(pll->nid, PM_PLL_MODE_INTEGER);
+ return status;
}
/**
@@ -2859,11 +2896,13 @@
*/
enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll)
{
- if (pll == NULL) {
- return PM_RET_ERROR_ARGS;
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
+
+ if (pll != NULL) {
+ status = pm_pll_set_mode(pll->nid, PM_PLL_MODE_RESET);
}
- return pm_pll_set_mode(pll->nid, PM_PLL_MODE_RESET);
+ return status;
}
/**
@@ -2880,16 +2919,16 @@
enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
uint32_t *state)
{
- enum pm_ret_status status;
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
enum pm_pll_mode mode;
if ((pll == NULL) || (state == NULL)) {
- return PM_RET_ERROR_ARGS;
+ goto exit_label;
}
status = pm_pll_get_mode(pll->nid, &mode);
if (status != PM_RET_SUCCESS) {
- return status;
+ goto exit_label;
}
if (mode == PM_PLL_MODE_RESET) {
@@ -2898,7 +2937,10 @@
*state = 1;
}
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
+
+exit_label:
+ return status;
}
/**
@@ -2918,23 +2960,25 @@
enum clock_id clock_id,
uint32_t parent_index)
{
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
+
if (pll == NULL) {
- return PM_RET_ERROR_ARGS;
+ goto exit_label;
}
if (pll->pre_src == clock_id) {
- return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
- parent_index);
+ status = pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC, parent_index);
+ goto exit_label;
}
if (pll->post_src == clock_id) {
- return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
- parent_index);
+ status = pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_POST_SRC, parent_index);
+ goto exit_label;
}
if (pll->div2 == clock_id) {
- return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_DIV2,
- parent_index);
+ status = pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_DIV2, parent_index);
}
- return PM_RET_ERROR_ARGS;
+exit_label:
+ return status;
}
/**
@@ -2952,27 +2996,33 @@
enum clock_id clock_id,
uint32_t *parent_index)
{
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
+
if (pll == NULL) {
- return PM_RET_ERROR_ARGS;
+ goto exit_label;
}
if (pll->pre_src == clock_id) {
- return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
- parent_index);
+ status = pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
+ parent_index);
+ goto exit_label;
}
if (pll->post_src == clock_id) {
- return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
- parent_index);
+ status = pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
+ parent_index);
+ goto exit_label;
}
if (pll->div2 == clock_id) {
- return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_DIV2,
- parent_index);
+ status = pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_DIV2,
+ parent_index);
+ goto exit_label;
}
if (pll->bypass == clock_id) {
*parent_index = 0;
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
}
- return PM_RET_ERROR_ARGS;
+exit_label:
+ return status;
}
/**
@@ -2989,13 +3039,14 @@
uint32_t mode)
{
struct pm_pll *pll = pm_clock_get_pll(clock_id);
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
- if ((pll == NULL) || ((mode != PLL_FRAC_MODE) && (mode != PLL_INT_MODE))) {
- return PM_RET_ERROR_ARGS;
+ if (!((pll == NULL) || ((mode != PLL_FRAC_MODE) && (mode != PLL_INT_MODE)))) {
+ pll->mode = (uint8_t)mode;
+ status = PM_RET_SUCCESS;
}
- pll->mode = mode;
- return PM_RET_SUCCESS;
+ return status;
}
/**
@@ -3012,13 +3063,14 @@
uint32_t *mode)
{
const struct pm_pll *pll = pm_clock_get_pll(clock_id);
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
- if ((pll == NULL) || (mode == NULL)) {
- return PM_RET_ERROR_ARGS;
+ if ((pll != NULL) && (mode != NULL)) {
+ *mode = pll->mode;
+ status = PM_RET_SUCCESS;
}
- *mode = pll->mode;
- return PM_RET_SUCCESS;
+ return status;
}
/**
@@ -3030,15 +3082,17 @@
*/
enum pm_ret_status pm_clock_id_is_valid(uint32_t clock_id)
{
- if (!pm_clock_valid(clock_id)) {
- return PM_RET_ERROR_ARGS;
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
+
+ if (pm_clock_valid(clock_id)) {
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
+ status = PM_RET_ERROR_NOTSUPPORTED;
+ } else {
+ status = PM_RET_SUCCESS;
+ }
}
- if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
- return PM_RET_ERROR_NOTSUPPORTED;
- }
-
- return PM_RET_SUCCESS;
+ return status;
}
/**
@@ -3053,23 +3107,29 @@
{
uint32_t i;
const struct pm_clock_node *nodes;
+ uint8_t status = 0U;
- if (clock_id >= CLK_MAX_OUTPUT_CLK) {
- return 0;
+ if (clock_id >= (uint32_t)CLK_MAX_OUTPUT_CLK) {
+ goto exit_label;
}
nodes = *clocks[clock_id].nodes;
for (i = 0; i < clocks[clock_id].num_nodes; i++) {
if (nodes[i].type == TYPE_DIV1) {
- if (div_id == PM_CLOCK_DIV0_ID)
- return 1;
+ if (div_id == PM_CLOCK_DIV0_ID) {
+ status = 1U;
+ break;
+ }
} else if (nodes[i].type == TYPE_DIV2) {
- if (div_id == PM_CLOCK_DIV1_ID)
- return 1;
+ if (div_id == PM_CLOCK_DIV1_ID) {
+ status = 1U;
+ break;
+ }
} else {
/* To fix the misra 15.7 warning */
}
}
- return 0;
+exit_label:
+ return status;
}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index 0dbfa57..fd3992c 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -61,9 +61,11 @@
static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
{
uint32_t val;
+ enum pm_ret_status status = PM_RET_SUCCESS;
if ((mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) != 0U) {
- return PM_RET_ERROR_ACCESS;
+ status = PM_RET_ERROR_ACCESS;
+ goto exit_label;
}
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
@@ -77,12 +79,14 @@
val |= ZYNQMP_TCM_COMB_MASK;
val |= ZYNQMP_SLCLAMP_MASK;
} else {
- return PM_RET_ERROR_ARGS;
+ status = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
- return PM_RET_SUCCESS;
+exit_label:
+ return status;
}
/**
@@ -136,6 +140,7 @@
static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
{
uint32_t val;
+ enum pm_ret_status status = PM_RET_SUCCESS;
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
@@ -144,12 +149,14 @@
} else if (value == PM_RPU_TCM_COMB) {
val |= ZYNQMP_TCM_COMB_MASK;
} else {
- return PM_RET_ERROR_ARGS;
+ status = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
- return PM_RET_SUCCESS;
+exit_label:
+ return status;
}
/**
@@ -165,12 +172,16 @@
static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
uint32_t value)
{
+ enum pm_ret_status status = PM_RET_SUCCESS;
+
if ((((value != PM_TAPDELAY_BYPASS_ENABLE) &&
(value != PM_TAPDELAY_BYPASS_DISABLE)) || (type >= PM_TAPDELAY_MAX))) {
- return PM_RET_ERROR_ARGS;
+ status = PM_RET_ERROR_ARGS;
+ } else {
+ status = pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
}
- return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
+ return status;
}
/**
@@ -266,7 +277,7 @@
if (type == PM_TAPDELAY_INPUT) {
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
- (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
+ (uint64_t)(ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
(ZYNQMP_SD_ITAPCHGWIN << shift));
if (ret != PM_RET_SUCCESS) {
@@ -275,12 +286,12 @@
if (value == 0U) {
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
- (ZYNQMP_SD_ITAPDLYENA_MASK <<
+ (uint64_t)(ZYNQMP_SD_ITAPDLYENA_MASK <<
shift), 0);
} else {
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
- (ZYNQMP_SD_ITAPDLYENA_MASK <<
- shift), (ZYNQMP_SD_ITAPDLYENA <<
+ (uint64_t)(ZYNQMP_SD_ITAPDLYENA_MASK <<
+ shift), (uint64_t)(ZYNQMP_SD_ITAPDLYENA <<
shift));
}
@@ -289,7 +300,7 @@
}
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
- (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
+ (uint64_t)(ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
(value << shift));
if (ret != PM_RET_SUCCESS) {
@@ -297,17 +308,17 @@
}
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
- (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
+ (uint64_t)(ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
} else if (type == PM_TAPDELAY_OUTPUT) {
ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
- (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
+ (uint64_t)(ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
if (ret != PM_RET_SUCCESS) {
goto reset_release;
}
ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
- (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
+ (uint64_t)(ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
(value << shift));
} else {
ret = PM_RET_ERROR_ARGS;
@@ -372,11 +383,11 @@
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(pll, &pll_nid);
- if (status != PM_RET_SUCCESS) {
- return status;
+ if (status == PM_RET_SUCCESS) {
+ status = pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
}
- return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
+ return status;
}
/**
@@ -397,11 +408,11 @@
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(pll, &pll_nid);
- if (status != PM_RET_SUCCESS) {
- return status;
+ if (status == PM_RET_SUCCESS) {
+ status = pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
}
- return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
+ return status;
}
/**
@@ -418,12 +429,16 @@
static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
uint32_t value)
{
+ enum pm_ret_status ret_status = PM_RET_SUCCESS;
+
if (index >= GGS_NUM_REGS) {
- return PM_RET_ERROR_ARGS;
+ ret_status = PM_RET_ERROR_ARGS;
+ } else {
+ ret_status = pm_mmio_write((uint64_t)GGS_BASEADDR + (index << 2),
+ 0xFFFFFFFFU, value);
}
- return pm_mmio_write(GGS_BASEADDR + (index << 2),
- 0xFFFFFFFFU, value);
+ return ret_status;
}
/**
@@ -440,11 +455,15 @@
static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
uint32_t *value)
{
+ enum pm_ret_status ret_status = PM_RET_SUCCESS;
+
if (index >= GGS_NUM_REGS) {
- return PM_RET_ERROR_ARGS;
+ ret_status = PM_RET_ERROR_ARGS;
+ } else {
+ ret_status = pm_mmio_read((uint64_t)GGS_BASEADDR + (index << 2), value);
}
- return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
+ return ret_status;
}
/**
@@ -461,12 +480,16 @@
static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
uint32_t value)
{
+ enum pm_ret_status ret_status = PM_RET_SUCCESS;
+
if (index >= PGGS_NUM_REGS) {
- return PM_RET_ERROR_ARGS;
+ ret_status = PM_RET_ERROR_ARGS;
+ } else {
+ ret_status = pm_mmio_write((uint64_t)PGGS_BASEADDR + (index << 2),
+ 0xFFFFFFFFU, value);
}
- return pm_mmio_write(PGGS_BASEADDR + (index << 2),
- 0xFFFFFFFFU, value);
+ return ret_status;
}
/**
@@ -481,6 +504,7 @@
uint32_t value)
{
uint32_t mask;
+ enum pm_ret_status status = PM_RET_ERROR_ARGS;
const uint32_t regarr[] = {0xFD360000U,
0xFD360014U,
0xFD370000U,
@@ -499,17 +523,16 @@
0xFF419000U,
};
- if (index >= ARRAY_SIZE(regarr)) {
- return PM_RET_ERROR_ARGS;
+ if (index < ARRAY_SIZE(regarr)) {
+ if (index <= AFIFM6_WRCTRL) {
+ mask = FABRIC_WIDTH;
+ } else {
+ mask = 0xf00;
+ }
+ status = pm_mmio_write(regarr[index], mask, value);
}
- if (index <= AFIFM6_WRCTRL) {
- mask = FABRIC_WIDTH;
- } else {
- mask = 0xf00;
- }
-
- return pm_mmio_write(regarr[index], mask, value);
+ return status;
}
/**
@@ -526,11 +549,15 @@
static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
uint32_t *value)
{
+ enum pm_ret_status status = 0;
+
if (index >= PGGS_NUM_REGS) {
- return PM_RET_ERROR_ARGS;
+ status = PM_RET_ERROR_ARGS;
+ } else {
+ status = pm_mmio_read((uint64_t)PGGS_BASEADDR + (index << 2), value);
}
- return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
+ return status;
}
/**
@@ -548,7 +575,7 @@
ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
ZYNQMP_ULPI_RESET_VAL_HIGH);
if (ret != PM_RET_SUCCESS) {
- return ret;
+ goto exit_label;
}
/* Drive ULPI assert for atleast 1ms */
@@ -557,7 +584,7 @@
ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
ZYNQMP_ULPI_RESET_VAL_LOW);
if (ret != PM_RET_SUCCESS) {
- return ret;
+ goto exit_label;
}
/* Drive ULPI de-assert for atleast 1ms */
@@ -566,6 +593,7 @@
ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
ZYNQMP_ULPI_RESET_VAL_HIGH);
+exit_label:
return ret;
}
@@ -703,12 +731,13 @@
IOCTL_AFI,
};
uint8_t i, ioctl_id;
- int32_t ret;
+ enum pm_ret_status ret = PM_RET_SUCCESS;
for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
ioctl_id = supported_ids[i];
if (ioctl_id >= 64U) {
- return PM_RET_ERROR_NOTSUPPORTED;
+ ret = PM_RET_ERROR_NOTSUPPORTED;
+ break;
}
ret = check_api_dependency(ioctl_id);
if (ret == PM_RET_SUCCESS) {
@@ -716,5 +745,5 @@
}
}
- return PM_RET_SUCCESS;
+ return ret;
}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 1477e25..5ffd9ef 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -1991,13 +1991,16 @@
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;
+ enum pm_ret_status status = PM_RET_SUCCESS;
+
+ if (fid >= (uint32_t)MAX_FUNCTION) {
+ status = PM_RET_ERROR_ARGS;
+ } else {
+
+ *ngroups = pinctrl_functions[fid].group_size;
}
- *ngroups = pinctrl_functions[fid].group_size;
-
- return PM_RET_SUCCESS;
+ return status;
}
/**
@@ -2011,7 +2014,7 @@
*/
void pm_api_pinctrl_get_function_name(uint32_t fid, char *name)
{
- if (fid >= MAX_FUNCTION) {
+ if (fid >= (uint32_t)MAX_FUNCTION) {
(void)memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
} else {
(void)memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
@@ -2044,9 +2047,11 @@
uint16_t grps;
uint16_t end_of_grp_offset;
uint16_t i;
+ enum pm_ret_status status = PM_RET_SUCCESS;
- if (fid >= MAX_FUNCTION) {
- return PM_RET_ERROR_ARGS;
+ if (fid >= (uint32_t)MAX_FUNCTION) {
+ status = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
(void)memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
@@ -2058,10 +2063,11 @@
if ((grps + index + i) >= end_of_grp_offset) {
break;
}
- groups[i] = (grps + index + i);
+ groups[i] = (uint16_t)(grps + index + i);
}
- return PM_RET_SUCCESS;
+exit_label:
+ return status;
}
/**
@@ -2089,22 +2095,26 @@
{
uint32_t i;
const uint16_t *grps;
+ enum pm_ret_status status = PM_RET_SUCCESS;
- if (pin >= MAX_PIN) {
- return PM_RET_ERROR_ARGS;
+ if (pin >= (uint32_t)MAX_PIN) {
+ status = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
(void)memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
grps = *zynqmp_pin_groups[pin].groups;
if (grps == NULL) {
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
+ goto exit_label;
}
/* Skip groups till index */
for (i = 0; i < index; i++) {
if (grps[i] == (uint16_t)END_OF_GROUPS) {
- return PM_RET_SUCCESS;
+ status = PM_RET_SUCCESS;
+ goto exit_label;
}
}
@@ -2115,5 +2125,6 @@
}
}
- return PM_RET_SUCCESS;
+exit_label:
+ return status;
}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index a517257..cadde9a 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -46,22 +46,22 @@
/* Order in pm_procs_all array must match cpu ids */
static const struct pm_proc pm_procs_all[] = {
{
- .node_id = NODE_APU_0,
+ .node_id = (uint32_t)NODE_APU_0,
.pwrdn_mask = APU_0_PWRCTL_CPUPWRDWNREQ_MASK,
.ipi = &apu_ipi,
},
{
- .node_id = NODE_APU_1,
+ .node_id = (uint32_t)NODE_APU_1,
.pwrdn_mask = APU_1_PWRCTL_CPUPWRDWNREQ_MASK,
.ipi = &apu_ipi,
},
{
- .node_id = NODE_APU_2,
+ .node_id = (uint32_t)NODE_APU_2,
.pwrdn_mask = APU_2_PWRCTL_CPUPWRDWNREQ_MASK,
.ipi = &apu_ipi,
},
{
- .node_id = NODE_APU_3,
+ .node_id = (uint32_t)NODE_APU_3,
.pwrdn_mask = APU_3_PWRCTL_CPUPWRDWNREQ_MASK,
.ipi = &apu_ipi,
},
@@ -198,7 +198,7 @@
for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
uint32_t base_irq = reg_num << ISENABLER_SHIFT;
- uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2U));
+ uint32_t reg = mmio_read_32(isenabler1 + (uint64_t)(reg_num << 2U));
if (reg == 0) {
continue;
@@ -206,9 +206,10 @@
while (reg != 0U) {
enum pm_node_id node;
- uint32_t idx, ret, irq, lowest_set = reg & (-reg);
+ uint32_t idx, irq, lowest_set = reg & (-reg);
+ enum pm_ret_status ret;
- idx = __builtin_ctz(lowest_set);
+ idx = (uint32_t)__builtin_ctz(lowest_set);
irq = base_irq + idx;
if (irq > IRQ_MAX) {
@@ -237,11 +238,13 @@
*/
const struct pm_proc *pm_get_proc(uint32_t cpuid)
{
+ const struct pm_proc *ret = NULL;
+
if (cpuid < ARRAY_SIZE(pm_procs_all)) {
- return &pm_procs_all[cpuid];
+ ret = &pm_procs_all[cpuid];
}
- return NULL;
+ return ret;
}
/**
@@ -253,12 +256,16 @@
*/
static uint32_t pm_get_cpuid(enum pm_node_id nid)
{
+ uint32_t ret = UNDEFINED_CPUID;
+
for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
if (pm_procs_all[i].node_id == nid) {
- return i;
+ ret = i;
+ break;
}
}
- return UNDEFINED_CPUID;
+
+ return ret;
}
const struct pm_proc *primary_proc = &pm_procs_all[0];
@@ -320,28 +327,30 @@
void pm_client_wakeup(const struct pm_proc *proc)
{
uint32_t cpuid = pm_get_cpuid(proc->node_id);
+ uint32_t val;
- if (cpuid == UNDEFINED_CPUID) {
- return;
+ if (cpuid != UNDEFINED_CPUID) {
+ bakery_lock_get(&pm_client_secure_lock);
+
+ /* clear powerdown bit for affected cpu */
+ val = mmio_read_32(APU_PWRCTL);
+
+ val &= ~(proc->pwrdn_mask);
+ mmio_write_32(APU_PWRCTL, val);
+
+ bakery_lock_release(&pm_client_secure_lock);
}
-
- bakery_lock_get(&pm_client_secure_lock);
-
- /* clear powerdown bit for affected cpu */
- uint32_t val = mmio_read_32(APU_PWRCTL);
- val &= ~(proc->pwrdn_mask);
- mmio_write_32(APU_PWRCTL, val);
-
- bakery_lock_release(&pm_client_secure_lock);
}
enum pm_ret_status pm_set_suspend_mode(uint32_t mode)
{
- if ((mode != PM_SUSPEND_MODE_STD) &&
- (mode != PM_SUSPEND_MODE_POWER_OFF)) {
- return PM_RET_ERROR_ARGS;
+ enum pm_ret_status suspend_mode_status = PM_RET_ERROR_ARGS;
+
+ if ((mode == PM_SUSPEND_MODE_STD) ||
+ (mode == PM_SUSPEND_MODE_POWER_OFF)) {
+ suspend_mode = mode;
+ suspend_mode_status = PM_RET_SUCCESS;
}
- suspend_mode = mode;
- return PM_RET_SUCCESS;
+ return suspend_mode_status;
}
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index 719ab6f..81f681f 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -51,164 +51,164 @@
/* Dependent APIs for TF-A to check their version from firmware */
static const eemi_api_dependency api_dep_table[] = {
{
- .id = PM_SELF_SUSPEND,
- .api_id = PM_SELF_SUSPEND,
+ .id = (uint8_t)PM_SELF_SUSPEND,
+ .api_id = (uint8_t)PM_SELF_SUSPEND,
},
{
- .id = PM_REQ_WAKEUP,
- .api_id = PM_REQ_WAKEUP,
+ .id = (uint8_t)PM_REQ_WAKEUP,
+ .api_id = (uint8_t)PM_REQ_WAKEUP,
},
{
- .id = PM_ABORT_SUSPEND,
- .api_id = PM_ABORT_SUSPEND,
+ .id = (uint8_t)PM_ABORT_SUSPEND,
+ .api_id = (uint8_t)PM_ABORT_SUSPEND,
},
{
- .id = PM_SET_WAKEUP_SOURCE,
- .api_id = PM_SET_WAKEUP_SOURCE,
+ .id = (uint8_t)PM_SET_WAKEUP_SOURCE,
+ .api_id = (uint8_t)PM_SET_WAKEUP_SOURCE,
},
{
- .id = PM_SYSTEM_SHUTDOWN,
- .api_id = PM_SYSTEM_SHUTDOWN,
+ .id = (uint8_t)PM_SYSTEM_SHUTDOWN,
+ .api_id = (uint8_t)PM_SYSTEM_SHUTDOWN,
},
{
- .id = PM_GET_API_VERSION,
- .api_id = PM_GET_API_VERSION,
+ .id = (uint8_t)PM_GET_API_VERSION,
+ .api_id = (uint8_t)PM_GET_API_VERSION,
},
{
- .id = PM_CLOCK_ENABLE,
- .api_id = PM_PLL_SET_MODE,
+ .id = (uint8_t)PM_CLOCK_ENABLE,
+ .api_id = (uint8_t)PM_PLL_SET_MODE,
},
{
- .id = PM_CLOCK_ENABLE,
- .api_id = PM_CLOCK_ENABLE,
+ .id = (uint8_t)PM_CLOCK_ENABLE,
+ .api_id = (uint8_t)PM_CLOCK_ENABLE,
},
{
- .id = PM_CLOCK_DISABLE,
- .api_id = PM_PLL_SET_MODE,
+ .id = (uint8_t)PM_CLOCK_DISABLE,
+ .api_id = (uint8_t)PM_PLL_SET_MODE,
},
{
- .id = PM_CLOCK_DISABLE,
- .api_id = PM_CLOCK_DISABLE,
+ .id = (uint8_t)PM_CLOCK_DISABLE,
+ .api_id = (uint8_t)PM_CLOCK_DISABLE,
},
{
- .id = PM_CLOCK_GETSTATE,
- .api_id = PM_PLL_GET_MODE,
+ .id = (uint8_t)PM_CLOCK_GETSTATE,
+ .api_id = (uint8_t)PM_PLL_GET_MODE,
},
{
- .id = PM_CLOCK_GETSTATE,
- .api_id = PM_CLOCK_GETSTATE,
+ .id = (uint8_t)PM_CLOCK_GETSTATE,
+ .api_id = (uint8_t)PM_CLOCK_GETSTATE,
},
{
- .id = PM_CLOCK_SETDIVIDER,
- .api_id = PM_PLL_SET_PARAMETER,
+ .id = (uint8_t)PM_CLOCK_SETDIVIDER,
+ .api_id = (uint8_t)PM_PLL_SET_PARAMETER,
},
{
- .id = PM_CLOCK_SETDIVIDER,
- .api_id = PM_CLOCK_SETDIVIDER,
+ .id = (uint8_t)PM_CLOCK_SETDIVIDER,
+ .api_id = (uint8_t)PM_CLOCK_SETDIVIDER,
},
{
- .id = PM_CLOCK_GETDIVIDER,
- .api_id = PM_PLL_GET_PARAMETER,
+ .id = (uint8_t)PM_CLOCK_GETDIVIDER,
+ .api_id = (uint8_t)PM_PLL_GET_PARAMETER,
},
{
- .id = PM_CLOCK_GETDIVIDER,
- .api_id = PM_CLOCK_GETDIVIDER,
+ .id = (uint8_t)PM_CLOCK_GETDIVIDER,
+ .api_id = (uint8_t)PM_CLOCK_GETDIVIDER,
},
{
- .id = PM_CLOCK_SETPARENT,
- .api_id = PM_PLL_SET_PARAMETER,
+ .id = (uint8_t)PM_CLOCK_SETPARENT,
+ .api_id = (uint8_t)PM_PLL_SET_PARAMETER,
},
{
- .id = PM_CLOCK_SETPARENT,
- .api_id = PM_CLOCK_SETPARENT,
+ .id = (uint8_t)PM_CLOCK_SETPARENT,
+ .api_id = (uint8_t)PM_CLOCK_SETPARENT,
},
{
- .id = PM_CLOCK_GETPARENT,
- .api_id = PM_PLL_GET_PARAMETER,
+ .id = (uint8_t)PM_CLOCK_GETPARENT,
+ .api_id = (uint8_t)PM_PLL_GET_PARAMETER,
},
{
- .id = PM_CLOCK_GETPARENT,
- .api_id = PM_CLOCK_GETPARENT,
+ .id = (uint8_t)PM_CLOCK_GETPARENT,
+ .api_id = (uint8_t)PM_CLOCK_GETPARENT,
},
{
- .id = PM_PLL_SET_PARAMETER,
- .api_id = PM_PLL_SET_PARAMETER,
+ .id = (uint8_t)PM_PLL_SET_PARAMETER,
+ .api_id = (uint8_t)PM_PLL_SET_PARAMETER,
},
{
- .id = PM_PLL_GET_PARAMETER,
- .api_id = PM_PLL_GET_PARAMETER,
+ .id = (uint8_t)PM_PLL_GET_PARAMETER,
+ .api_id = (uint8_t)PM_PLL_GET_PARAMETER,
},
{
- .id = PM_PLL_SET_MODE,
- .api_id = PM_PLL_SET_MODE,
+ .id = (uint8_t)PM_PLL_SET_MODE,
+ .api_id = (uint8_t)PM_PLL_SET_MODE,
},
{
- .id = PM_PLL_GET_MODE,
- .api_id = PM_PLL_GET_MODE,
+ .id = (uint8_t)PM_PLL_GET_MODE,
+ .api_id = (uint8_t)PM_PLL_GET_MODE,
},
{
- .id = PM_REGISTER_ACCESS,
- .api_id = PM_MMIO_WRITE,
+ .id = (uint8_t)PM_REGISTER_ACCESS,
+ .api_id = (uint8_t)PM_MMIO_WRITE,
},
{
- .id = PM_REGISTER_ACCESS,
- .api_id = PM_MMIO_READ,
+ .id = (uint8_t)PM_REGISTER_ACCESS,
+ .api_id = (uint8_t)PM_MMIO_READ,
},
{
- .id = PM_FEATURE_CHECK,
- .api_id = PM_FEATURE_CHECK,
+ .id = (uint8_t)PM_FEATURE_CHECK,
+ .api_id = (uint8_t)PM_FEATURE_CHECK,
},
{
- .id = IOCTL_SET_TAPDELAY_BYPASS,
- .api_id = PM_MMIO_WRITE,
+ .id = (uint8_t)IOCTL_SET_TAPDELAY_BYPASS,
+ .api_id = (uint8_t)PM_MMIO_WRITE,
},
{
- .id = IOCTL_SD_DLL_RESET,
- .api_id = PM_MMIO_WRITE,
+ .id = (uint8_t)IOCTL_SD_DLL_RESET,
+ .api_id = (uint8_t)PM_MMIO_WRITE,
},
{
- .id = IOCTL_SET_SD_TAPDELAY,
- .api_id = PM_MMIO_WRITE,
+ .id = (uint8_t)IOCTL_SET_SD_TAPDELAY,
+ .api_id = (uint8_t)PM_MMIO_WRITE,
},
{
- .id = IOCTL_SET_SD_TAPDELAY,
- .api_id = PM_MMIO_READ,
+ .id = (uint8_t)IOCTL_SET_SD_TAPDELAY,
+ .api_id = (uint8_t)PM_MMIO_READ,
},
{
- .id = IOCTL_SET_PLL_FRAC_DATA,
- .api_id = PM_PLL_SET_PARAMETER,
+ .id = (uint8_t)IOCTL_SET_PLL_FRAC_DATA,
+ .api_id = (uint8_t)PM_PLL_SET_PARAMETER,
},
{
- .id = IOCTL_GET_PLL_FRAC_DATA,
- .api_id = PM_PLL_GET_PARAMETER,
+ .id = (uint8_t)IOCTL_GET_PLL_FRAC_DATA,
+ .api_id = (uint8_t)PM_PLL_GET_PARAMETER,
},
{
- .id = IOCTL_WRITE_GGS,
- .api_id = PM_MMIO_WRITE,
+ .id = (uint8_t)IOCTL_WRITE_GGS,
+ .api_id = (uint8_t)PM_MMIO_WRITE,
},
{
- .id = IOCTL_READ_GGS,
- .api_id = PM_MMIO_READ,
+ .id = (uint8_t)IOCTL_READ_GGS,
+ .api_id = (uint8_t)PM_MMIO_READ,
},
{
- .id = IOCTL_WRITE_PGGS,
- .api_id = PM_MMIO_WRITE,
+ .id = (uint8_t)IOCTL_WRITE_PGGS,
+ .api_id = (uint8_t)PM_MMIO_WRITE,
},
{
- .id = IOCTL_READ_PGGS,
- .api_id = PM_MMIO_READ,
+ .id = (uint8_t)IOCTL_READ_PGGS,
+ .api_id = (uint8_t)PM_MMIO_READ,
},
{
- .id = IOCTL_ULPI_RESET,
- .api_id = PM_MMIO_WRITE,
+ .id = (uint8_t)IOCTL_ULPI_RESET,
+ .api_id = (uint8_t)PM_MMIO_WRITE,
},
{
- .id = IOCTL_SET_BOOT_HEALTH_STATUS,
- .api_id = PM_MMIO_WRITE,
+ .id = (uint8_t)IOCTL_SET_BOOT_HEALTH_STATUS,
+ .api_id = (uint8_t)PM_MMIO_WRITE,
},
{
- .id = IOCTL_AFI,
- .api_id = PM_MMIO_WRITE,
+ .id = (uint8_t)IOCTL_AFI,
+ .api_id = (uint8_t)PM_MMIO_WRITE,
},
};
@@ -305,14 +305,17 @@
uint32_t latency, uint32_t state)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
/* Send request to the PMU */
PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
if (ack == REQ_ACK_BLOCKING) {
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ ret = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
} else {
- return pm_ipi_send(primary_proc, payload);
+ ret = pm_ipi_send(primary_proc, payload);
}
+
+ return ret;
}
/**
@@ -339,21 +342,23 @@
{
uint32_t payload[PAYLOAD_ARG_CNT];
uint64_t encoded_address;
-
+ enum pm_ret_status ret = PM_RET_SUCCESS;
/* encode set Address into 1st bit of address */
encoded_address = address;
- encoded_address |= !!set_address;
+ encoded_address |= (uint32_t)!!set_address;
/* Send request to the PMU to perform the wake of the PU */
PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
encoded_address >> 32, ack);
if (ack == REQ_ACK_BLOCKING) {
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ ret = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
} else {
- return pm_ipi_send(primary_proc, payload);
+ ret = pm_ipi_send(primary_proc, payload);
}
+
+ return ret;
}
/**
@@ -369,15 +374,18 @@
enum pm_request_ack ack)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);
if (ack == REQ_ACK_BLOCKING) {
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ ret = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
} else {
- return pm_ipi_send(primary_proc, payload);
+ ret = pm_ipi_send(primary_proc, payload);
}
+
+ return ret;
}
/**
@@ -439,15 +447,17 @@
enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
- if (type == PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
+ if (type == (uint32_t)PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
/* Setting scope for subsequent PSCI reboot or shutdown */
pm_shutdown_scope = subtype;
- return PM_RET_SUCCESS;
+ } else {
+ PM_PACK_PAYLOAD3(payload, PM_SYSTEM_SHUTDOWN, type, subtype);
+ ret = pm_ipi_send_non_blocking(primary_proc, payload);
}
- PM_PACK_PAYLOAD3(payload, PM_SYSTEM_SHUTDOWN, type, subtype);
- return pm_ipi_send_non_blocking(primary_proc, payload);
+ return ret;
}
/* APIs for managing PM slaves: */
@@ -468,14 +478,17 @@
enum pm_request_ack ack)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);
if (ack == REQ_ACK_BLOCKING) {
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ ret = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
} else {
- return pm_ipi_send(primary_proc, payload);
+ ret = pm_ipi_send(primary_proc, payload);
}
+
+ return ret;
}
/**
@@ -496,15 +509,18 @@
enum pm_request_ack ack)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
ack);
if (ack == REQ_ACK_BLOCKING) {
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ ret = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
} else {
- return pm_ipi_send(primary_proc, payload);
+ ret = pm_ipi_send(primary_proc, payload);
}
+
+ return ret;
}
/* Miscellaneous API functions */
@@ -709,13 +725,16 @@
enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count)
{
enum pm_ret_status ret = PM_RET_SUCCESS;
+
/* Return if interrupt is not from PMU */
- if (!pm_ipi_irq_status(primary_proc)) {
- return ret;
+ if ((pm_ipi_irq_status(primary_proc) == 0U)) {
+ goto exit_label;
}
ret = pm_ipi_buff_read_callb(data, count);
pm_ipi_irq_clear(primary_proc);
+
+exit_label:
return ret;
}
@@ -770,7 +789,7 @@
{
uint8_t i;
uint32_t version_type;
- int ret;
+ enum pm_ret_status ret = PM_RET_SUCCESS;
for (i = 0U; i < ARRAY_SIZE(api_dep_table); i++) {
if (api_dep_table[i].id == id) {
@@ -781,17 +800,19 @@
ret = fw_api_version(api_dep_table[i].api_id,
&version_type, 1);
if (ret != PM_RET_SUCCESS) {
- return ret;
+ goto exit_label;
}
/* Check if fw version matches TF-A expected version */
if (version_type != tfa_expected_ver_id[api_dep_table[i].api_id]) {
- return PM_RET_ERROR_NOTSUPPORTED;
+ ret = PM_RET_ERROR_NOTSUPPORTED;
+ goto exit_label;
}
}
}
- return PM_RET_SUCCESS;
+exit_label:
+ return ret;
}
/**
@@ -806,20 +827,26 @@
static enum pm_ret_status feature_check_tfa(uint32_t api_id, uint32_t *version,
uint32_t *bit_mask)
{
+ enum pm_ret_status ret = PM_RET_ERROR_NO_FEATURE;
+
switch (api_id) {
case PM_QUERY_DATA:
*version = TFA_API_QUERY_DATA_VERSION;
bit_mask[0] = (uint32_t)(PM_QUERY_FEATURE_BITMASK);
bit_mask[1] = (uint32_t)(PM_QUERY_FEATURE_BITMASK >> 32);
- return PM_RET_SUCCESS;
+ ret = PM_RET_SUCCESS;
+ break;
case PM_GET_CALLBACK_DATA:
case PM_GET_TRUSTZONE_VERSION:
case PM_SET_SUSPEND_MODE:
*version = TFA_API_BASE_VERSION;
- return PM_RET_SUCCESS;
+ ret = PM_RET_SUCCESS;
+ break;
default:
- return PM_RET_ERROR_NO_FEATURE;
+ break;
}
+
+ return ret;
}
/**
@@ -834,6 +861,8 @@
static enum pm_ret_status get_tfa_version_for_partial_apis(uint32_t api_id,
uint32_t *version)
{
+ enum pm_ret_status ret = PM_RET_ERROR_ARGS;
+
switch (api_id) {
case PM_SELF_SUSPEND:
case PM_REQ_WAKEUP:
@@ -854,13 +883,17 @@
case PM_PLL_GET_MODE:
case PM_REGISTER_ACCESS:
*version = TFA_API_BASE_VERSION;
- return PM_RET_SUCCESS;
+ ret = PM_RET_SUCCESS;
+ break;
case PM_FEATURE_CHECK:
*version = FW_API_VERSION_2;
- return PM_RET_SUCCESS;
+ ret = PM_RET_SUCCESS;
+ break;
default:
- return PM_RET_ERROR_ARGS;
+ break;
}
+
+ return ret;
}
/**
@@ -876,6 +909,7 @@
uint32_t *version)
{
uint32_t status;
+ uint32_t ret = PM_RET_ERROR_NO_FEATURE;
switch (api_id) {
case PM_SELF_SUSPEND:
@@ -899,12 +933,16 @@
case PM_FEATURE_CHECK:
status = check_api_dependency(api_id);
if (status != PM_RET_SUCCESS) {
- return status;
+ ret = status;
+ } else {
+ ret = get_tfa_version_for_partial_apis(api_id, version);
}
- return get_tfa_version_for_partial_apis(api_id, version);
+ break;
default:
- return PM_RET_ERROR_NO_FEATURE;
+ break;
}
+
+ return ret;
}
/**
@@ -921,18 +959,18 @@
uint32_t *bit_mask, uint8_t len)
{
uint32_t ret_payload[RET_PAYLOAD_ARG_CNT] = {0U};
- uint32_t status;
+ enum pm_ret_status status;
/* Get API version implemented in TF-A */
status = feature_check_tfa(api_id, version, bit_mask);
if (status != PM_RET_ERROR_NO_FEATURE) {
- return status;
+ goto exit_label;
}
/* Get API version implemented by firmware and TF-A both */
status = feature_check_partial(api_id, version);
if (status != PM_RET_ERROR_NO_FEATURE) {
- return status;
+ goto exit_label;
}
/* Get API version implemented by firmware */
@@ -940,20 +978,21 @@
/* IOCTL call may return failure whose ID is not implemented in
* firmware but implemented in TF-A
*/
- if ((api_id != PM_IOCTL) && (status != PM_RET_SUCCESS)) {
- return status;
+ if ((api_id != (uint32_t)PM_IOCTL) && (status != PM_RET_SUCCESS)) {
+ goto exit_label;
}
*version = ret_payload[0];
/* Update IOCTL bit mask which are implemented in TF-A */
- if ((api_id == PM_IOCTL) || (api_id == PM_GET_OP_CHARACTERISTIC)) {
- if (len < 2) {
- return PM_RET_ERROR_ARGS;
+ if ((api_id == (uint32_t)PM_IOCTL) || (api_id == (uint32_t)PM_GET_OP_CHARACTERISTIC)) {
+ if (len < 2U) {
+ status = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
bit_mask[0] = ret_payload[1];
bit_mask[1] = ret_payload[2];
- if (api_id == PM_IOCTL) {
+ if (api_id == (uint32_t)PM_IOCTL) {
/* Get IOCTL's implemented by TF-A */
status = tfa_ioctl_bitmask(bit_mask);
}
@@ -961,6 +1000,7 @@
/* Requires for MISRA */
}
+exit_label:
return status;
}
@@ -1112,7 +1152,7 @@
/* Check if clock ID is valid and return an error if it is not */
status = pm_clock_id_is_valid(clock_id);
if (status != PM_RET_SUCCESS) {
- return status;
+ goto exit_label;
}
if (enable != 0U) {
@@ -1130,6 +1170,7 @@
status = PM_RET_SUCCESS;
}
+exit_label:
return status;
}
@@ -1147,15 +1188,19 @@
enum pm_ret_status pm_clock_enable(uint32_t clock_id)
{
struct pm_pll *pll;
+ enum pm_ret_status ret = PM_RET_SUCCESS;
/* First try to handle it as a PLL */
pll = pm_clock_get_pll(clock_id);
if (pll != NULL) {
- return pm_clock_pll_enable(pll);
+ ret = pm_clock_pll_enable(pll);
+ } else {
+
+ /* It's an on-chip clock, PMU should configure clock's gate */
+ ret = pm_clock_gate(clock_id, 1);
}
- /* It's an on-chip clock, PMU should configure clock's gate */
- return pm_clock_gate(clock_id, 1);
+ return ret;
}
/**
@@ -1172,15 +1217,19 @@
enum pm_ret_status pm_clock_disable(uint32_t clock_id)
{
struct pm_pll *pll;
+ enum pm_ret_status ret = PM_RET_SUCCESS;
/* First try to handle it as a PLL */
pll = pm_clock_get_pll(clock_id);
if (pll != NULL) {
- return pm_clock_pll_disable(pll);
+ ret = pm_clock_pll_disable(pll);
+ } else {
+
+ /* It's an on-chip clock, PMU should configure clock's gate */
+ ret = pm_clock_gate(clock_id, 0);
}
- /* It's an on-chip clock, PMU should configure clock's gate */
- return pm_clock_gate(clock_id, 0);
+ return ret;
}
/**
@@ -1204,17 +1253,21 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll(clock_id);
if (pll != NULL) {
- return pm_clock_pll_get_state(pll, state);
+ status = pm_clock_pll_get_state(pll, state);
+ goto exit_label;
}
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
if (status != PM_RET_SUCCESS) {
- return status;
+ goto exit_label;
}
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETSTATE, clock_id);
- return pm_ipi_send_sync(primary_proc, payload, state, 1);
+ status = pm_ipi_send_sync(primary_proc, payload, state, 1);
+
+exit_label:
+ return status;
}
/**
@@ -1242,13 +1295,14 @@
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(clock_id, &nid);
if (status == PM_RET_SUCCESS) {
- return pm_pll_set_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
+ status = pm_pll_set_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
+ goto exit_label;
}
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
if (status != PM_RET_SUCCESS) {
- return status;
+ goto exit_label;
}
if (div0 == (divider & div0)) {
@@ -1258,12 +1312,16 @@
div_id = PM_CLOCK_DIV1_ID;
val = (divider & ~div1) >> 16;
} else {
- return PM_RET_ERROR_ARGS;
+ status = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
/* Send request to the PMU */
PM_PACK_PAYLOAD4(payload, PM_CLOCK_SETDIVIDER, clock_id, div_id, val);
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+
+exit_label:
+ return status;
}
/**
@@ -1280,7 +1338,7 @@
enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
uint32_t *divider)
{
- enum pm_ret_status status;
+ enum pm_ret_status status = PM_RET_SUCCESS;
enum pm_node_id nid;
uint32_t payload[PAYLOAD_ARG_CNT];
uint32_t val;
@@ -1288,22 +1346,23 @@
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(clock_id, &nid);
if (status == PM_RET_SUCCESS) {
- return pm_pll_get_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
+ status = pm_pll_get_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
+ goto exit_label;
}
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
if (status != PM_RET_SUCCESS) {
- return status;
+ goto exit_label;
}
if ((pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) != 0U) {
/* Send request to the PMU to get div0 */
PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
- PM_CLOCK_DIV0_ID);
+ PM_CLOCK_DIV0_ID);
status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
if (status != PM_RET_SUCCESS) {
- return status;
+ goto exit_label;
}
*divider = val;
}
@@ -1311,14 +1370,14 @@
if ((pm_clock_has_div(clock_id, PM_CLOCK_DIV1_ID)) != 0U) {
/* Send request to the PMU to get div1 */
PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
- PM_CLOCK_DIV1_ID);
+ PM_CLOCK_DIV1_ID);
status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
if (status != PM_RET_SUCCESS) {
- return status;
+ goto exit_label;
}
*divider |= val << 16;
}
-
+exit_label:
return status;
}
@@ -1342,18 +1401,22 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll_by_related_clk(clock_id);
if (pll != NULL) {
- return pm_clock_pll_set_parent(pll, clock_id, parent_index);
+ status = pm_clock_pll_set_parent(pll, clock_id, parent_index);
+ goto exit_label;
}
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
if (status != PM_RET_SUCCESS) {
- return status;
+ goto exit_label;
}
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_CLOCK_SETPARENT, clock_id, parent_index);
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+
+exit_label:
+ return status;
}
/**
@@ -1377,18 +1440,22 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll_by_related_clk(clock_id);
if (pll != NULL) {
- return pm_clock_pll_get_parent(pll, clock_id, parent_index);
+ status = pm_clock_pll_get_parent(pll, clock_id, parent_index);
+ goto exit_label;
}
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
if (status != PM_RET_SUCCESS) {
- return status;
+ goto exit_label;
}
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETPARENT, clock_id);
- return pm_ipi_send_sync(primary_proc, payload, parent_index, 1);
+ status = pm_ipi_send_sync(primary_proc, payload, parent_index, 1);
+
+exit_label:
+ return status;
}
/**
@@ -1521,47 +1588,47 @@
pm_clock_get_name(arg1, (char *)data);
break;
case PM_QID_CLOCK_GET_TOPOLOGY:
- data[0] = pm_clock_get_topology(arg1, arg2, &data[1]);
+ data[0] = (uint32_t)pm_clock_get_topology(arg1, arg2, &data[1]);
break;
case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
- data[0] = pm_clock_get_fixedfactor_params(arg1, &data[1],
+ data[0] = (uint32_t)pm_clock_get_fixedfactor_params(arg1, &data[1],
&data[2]);
break;
case PM_QID_CLOCK_GET_PARENTS:
- data[0] = pm_clock_get_parents(arg1, arg2, &data[1]);
+ data[0] = (uint32_t)pm_clock_get_parents(arg1, arg2, &data[1]);
break;
case PM_QID_CLOCK_GET_ATTRIBUTES:
- data[0] = pm_clock_get_attributes(arg1, &data[1]);
+ data[0] = (uint32_t)pm_clock_get_attributes(arg1, &data[1]);
break;
case PM_QID_PINCTRL_GET_NUM_PINS:
- data[0] = pm_pinctrl_get_num_pins(&data[1]);
+ data[0] = (uint32_t)pm_pinctrl_get_num_pins(&data[1]);
break;
case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
- data[0] = pm_pinctrl_get_num_functions(&data[1]);
+ data[0] = (uint32_t)pm_pinctrl_get_num_functions(&data[1]);
break;
case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
- data[0] = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
+ data[0] = (uint32_t)pm_pinctrl_get_num_function_groups(arg1, &data[1]);
break;
case PM_QID_PINCTRL_GET_FUNCTION_NAME:
pm_pinctrl_get_function_name(arg1, (char *)data);
break;
case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
- data[0] = pm_pinctrl_get_function_groups(arg1, arg2,
+ data[0] = (uint32_t)pm_pinctrl_get_function_groups(arg1, arg2,
(uint16_t *)&data[1]);
break;
case PM_QID_PINCTRL_GET_PIN_GROUPS:
- data[0] = pm_pinctrl_get_pin_groups(arg1, arg2,
+ data[0] = (uint32_t)pm_pinctrl_get_pin_groups(arg1, arg2,
(uint16_t *)&data[1]);
break;
case PM_QID_CLOCK_GET_NUM_CLOCKS:
- data[0] = pm_clock_get_num_clocks(&data[1]);
+ data[0] = (uint32_t)pm_clock_get_num_clocks(&data[1]);
break;
case PM_QID_CLOCK_GET_MAX_DIVISOR:
- data[0] = pm_clock_get_max_divisor(arg1, arg2, &data[1]);
+ data[0] = (uint32_t)pm_clock_get_max_divisor(arg1, (uint8_t)arg2, &data[1]);
break;
default:
- data[0] = PM_RET_ERROR_ARGS;
+ data[0] = (uint32_t)PM_RET_ERROR_ARGS;
WARN("Unimplemented query service call: 0x%x\n", qid);
break;
}
@@ -1655,20 +1722,26 @@
uint32_t value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = 0;
/* Check if given node ID is a PLL node */
if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
- return PM_RET_ERROR_ARGS;
+ ret = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
/* Check if parameter ID is valid and return an error if it's not */
if (param_id >= PM_PLL_PARAM_MAX) {
- return PM_RET_ERROR_ARGS;
+ ret = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
/* Send request to the PMU */
PM_PACK_PAYLOAD4(payload, PM_PLL_SET_PARAMETER, nid, param_id, value);
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ ret = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+
+exit_label:
+ return ret;
}
/**
@@ -1686,20 +1759,26 @@
uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
/* Check if given node ID is a PLL node */
if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
- return PM_RET_ERROR_ARGS;
+ ret = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
/* Check if parameter ID is valid and return an error if it's not */
if (param_id >= PM_PLL_PARAM_MAX) {
- return PM_RET_ERROR_ARGS;
+ ret = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_PLL_GET_PARAMETER, nid, param_id);
- return pm_ipi_send_sync(primary_proc, payload, value, 1);
+ ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
+
+exit_label:
+ return ret;
}
/**
@@ -1719,20 +1798,26 @@
enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
/* Check if given node ID is a PLL node */
if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
- return PM_RET_ERROR_ARGS;
+ ret = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
/* Check if PLL mode is valid */
if (mode >= PM_PLL_MODE_MAX) {
- return PM_RET_ERROR_ARGS;
+ ret = PM_RET_ERROR_ARGS;
+ goto exit_label;
}
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_PLL_SET_MODE, nid, mode);
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ ret = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+
+exit_label:
+ return ret;
}
/**
@@ -1747,15 +1832,18 @@
enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode)
{
uint32_t payload[PAYLOAD_ARG_CNT];
+ enum pm_ret_status ret = PM_RET_SUCCESS;
/* Check if given node ID is a PLL node */
if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
- return PM_RET_ERROR_ARGS;
+ ret = PM_RET_ERROR_ARGS;
+ } else {
+ /* Send request to the PMU */
+ PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
+ ret = pm_ipi_send_sync(primary_proc, payload, mode, 1);
}
- /* Send request to the PMU */
- PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
- return pm_ipi_send_sync(primary_proc, payload, mode, 1);
+ return ret;
}
/**
@@ -1783,7 +1871,8 @@
((CSUDMA_BASE & address) != CSUDMA_BASE) &&
((RSA_CORE_BASE & address) != RSA_CORE_BASE) &&
((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE)) {
- return PM_RET_ERROR_ACCESS;
+ ret = PM_RET_ERROR_ACCESS;
+ goto exit_label;
}
switch (register_access_id) {
@@ -1798,6 +1887,8 @@
WARN("Unimplemented register_access call\n\r");
break;
}
+
+exit_label:
return ret;
}
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
index af75c5c..c7d2b2c 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
@@ -187,9 +187,9 @@
*
*/
enum pm_shutdown_subtype {
- PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM,
- PMF_SHUTDOWN_SUBTYPE_PS_ONLY,
- PMF_SHUTDOWN_SUBTYPE_SYSTEM,
+ PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM = (0U),
+ PMF_SHUTDOWN_SUBTYPE_PS_ONLY = (1U),
+ PMF_SHUTDOWN_SUBTYPE_SYSTEM = (2U),
};
/**
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index 738699e..81db58b 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -220,6 +220,7 @@
int32_t pm_setup(void)
{
enum pm_ret_status err;
+ int32_t ret = -EINVAL;
pm_ipi_init(primary_proc);
@@ -227,17 +228,17 @@
if (err != PM_RET_SUCCESS) {
ERROR("BL31: Failed to read Platform Management API version. "
"Return: %d\n", err);
- return -EINVAL;
+ goto exit_label;
}
if (pm_ctx.api_version < PM_VERSION) {
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 & 0xFFFFU);
- return -EINVAL;
+ goto exit_label;
}
- int32_t status = 0, ret = 0;
+ int32_t status = 0;
#if ZYNQMP_WDT_RESTART
status = pm_wdt_restart_setup();
if (status)
@@ -253,8 +254,9 @@
ret = status;
}
- pm_up = !status;
+ pm_up = (status == 0);
+exit_label:
return ret;
}
@@ -322,7 +324,7 @@
uint32_t set_addr = pm_arg[1] & 0x1U;
uint64_t address = (uint64_t)pm_arg[2] << 32U;
- address |= pm_arg[1] & (~0x1U);
+ address |= (uint64_t)(pm_arg[1] & (~0x1U));
ret = pm_req_wakeup(pm_arg[0], set_addr, address,
pm_arg[3]);
SMC_RET1(handle, (uint64_t)ret);
@@ -354,7 +356,7 @@
SMC_RET1(handle, (uint64_t)ret);
case PM_GET_API_VERSION:
- if (ipi_irq_flag == 0U) {
+ if ((uint32_t)ipi_irq_flag == 0U) {
/*
* Enable IPI IRQ
* assume the rich OS is OK to handle callback IRQs now.
@@ -560,7 +562,7 @@
uint32_t bit_mask[2] = {0};
ret = pm_feature_check(pm_arg[0], &version_type, bit_mask,
- ARRAY_SIZE(bit_mask));
+ (uint8_t)ARRAY_SIZE(bit_mask));
SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)version_type << 32U)),
((uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32U)));
}
diff --git a/poetry.lock b/poetry.lock
index 91203d2..4127bcd 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
[[package]]
name = "alabaster"
@@ -399,13 +399,13 @@
[[package]]
name = "jinja2"
-version = "3.1.4"
+version = "3.1.5"
description = "A very fast and expressive template engine."
optional = false
python-versions = ">=3.7"
files = [
- {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
- {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
+ {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"},
+ {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"},
]
[package.dependencies]
@@ -1247,13 +1247,13 @@
[[package]]
name = "virtualenv"
-version = "20.26.4"
+version = "20.26.6"
description = "Virtual Python Environment builder"
optional = false
python-versions = ">=3.7"
files = [
- {file = "virtualenv-20.26.4-py3-none-any.whl", hash = "sha256:48f2695d9809277003f30776d155615ffc11328e6a0a8c1f0ec80188d7874a55"},
- {file = "virtualenv-20.26.4.tar.gz", hash = "sha256:c17f4e0f3e6036e9f26700446f85c76ab11df65ff6d8a9cbfad9f71aabfcf23c"},
+ {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"},
+ {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"},
]
[package.dependencies]
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 5456164..6acd1b6 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -14,6 +14,9 @@
#include <services/arm_arch_svc.h>
#include <smccc_helpers.h>
#include <plat/common/platform.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <lib/el3_runtime/context_mgmt.h>
static int32_t smccc_version(void)
{
@@ -90,6 +93,12 @@
}
return 0; /* ERRATA_APPLIES || ERRATA_MISSING */
#endif
+
+#if ARCH_FEATURE_AVAILABILITY
+ case SMCCC_ARCH_FEATURE_AVAILABILITY:
+ return SMC_ARCH_CALL_SUCCESS;
+#endif /* ARCH_FEATURE_AVAILABILITY */
+
#endif /* __aarch64__ */
/* Fallthrough */
@@ -113,6 +122,91 @@
}
/*
+ * Reads a system register, sanitises its value, and returns a bitmask
+ * representing which feature in that sysreg has been enabled by firmware. The
+ * bitmask is a 1:1 mapping to the register's fields.
+ */
+#if ARCH_FEATURE_AVAILABILITY
+static uintptr_t smccc_arch_feature_availability(u_register_t reg,
+ void *handle,
+ u_register_t flags)
+{
+ cpu_context_t *caller_context;
+ per_world_context_t *caller_per_world_context;
+ el3_state_t *state;
+ u_register_t bitmask, check;
+
+ /* check the caller security state */
+ if (is_caller_secure(flags)) {
+ caller_context = cm_get_context(SECURE);
+ caller_per_world_context = &per_world_context[CPU_CONTEXT_SECURE];
+ } else if (is_caller_non_secure(flags)) {
+ caller_context = cm_get_context(NON_SECURE);
+ caller_per_world_context = &per_world_context[CPU_CONTEXT_NS];
+ } else {
+#if ENABLE_RME
+ caller_context = cm_get_context(REALM);
+ caller_per_world_context = &per_world_context[CPU_CONTEXT_REALM];
+#else /* !ENABLE_RME */
+ assert(0); /* shouldn't be possible */
+#endif /* ENABLE_RME */
+ }
+
+ state = get_el3state_ctx(caller_context);
+
+ switch (reg) {
+ case SCR_EL3_OPCODE:
+ bitmask = read_ctx_reg(state, CTX_SCR_EL3);
+ bitmask &= ~SCR_EL3_IGNORED;
+ check = bitmask & ~SCR_EL3_FEATS;
+ bitmask &= SCR_EL3_FEATS;
+ bitmask ^= SCR_EL3_FLIPPED;
+ /* will only report 0 if neither is implemented */
+ if (is_feat_rng_trap_supported() || is_feat_rng_present())
+ bitmask |= SCR_TRNDR_BIT;
+ break;
+ case CPTR_EL3_OPCODE:
+ bitmask = caller_per_world_context->ctx_cptr_el3;
+ check = bitmask & ~CPTR_EL3_FEATS;
+ bitmask &= CPTR_EL3_FEATS;
+ bitmask ^= CPTR_EL3_FLIPPED;
+ break;
+ case MDCR_EL3_OPCODE:
+ bitmask = read_ctx_reg(state, CTX_MDCR_EL3);
+ bitmask &= ~MDCR_EL3_IGNORED;
+ check = bitmask & ~MDCR_EL3_FEATS;
+ bitmask &= MDCR_EL3_FEATS;
+ bitmask ^= MDCR_EL3_FLIPPED;
+ break;
+#if ENABLE_FEAT_MPAM
+ case MPAM3_EL3_OPCODE:
+ bitmask = caller_per_world_context->ctx_mpam3_el3;
+ bitmask &= ~MPAM3_EL3_IGNORED;
+ check = bitmask & ~MPAM3_EL3_FEATS;
+ bitmask &= MPAM3_EL3_FEATS;
+ bitmask ^= MPAM3_EL3_FLIPPED;
+ break;
+#endif /* ENABLE_FEAT_MPAM */
+ default:
+ SMC_RET2(handle, SMC_INVALID_PARAM, ULL(0));
+ }
+
+ /*
+ * failing this means that the requested register has a bit set that
+ * hasn't been declared as a known feature bit or an ignore bit. This is
+ * likely to happen when support for a new feature is added but the
+ * bitmask macros are not updated.
+ */
+ if (ENABLE_ASSERTIONS && check != 0) {
+ ERROR("Unexpected bits 0x%lx were set in register %lx!\n", check, reg);
+ assert(0);
+ }
+
+ SMC_RET2(handle, SMC_ARCH_CALL_SUCCESS, bitmask);
+}
+#endif /* ARCH_FEATURE_AVAILABILITY */
+
+/*
* Top-level Arm Architectural Service SMC handler.
*/
static uintptr_t arm_arch_svc_smc_handler(uint32_t smc_fid,
@@ -161,6 +255,11 @@
SMC_RET0(handle);
#endif
#endif /* __aarch64__ */
+#if ARCH_FEATURE_AVAILABILITY
+ /* return is 64 bit so only reply on SMC64 requests */
+ case SMCCC_ARCH_FEATURE_AVAILABILITY | (SMC_64 << FUNCID_CC_SHIFT):
+ return smccc_arch_feature_availability(x1, handle, flags);
+#endif /* ARCH_FEATURE_AVAILABILITY */
default:
WARN("Unimplemented Arm Architecture Service Call: 0x%x \n",
smc_fid);
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 9e83848..8910ec6 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -190,24 +190,28 @@
if (!optee_ep_info->pc)
return 1;
- if (TRANSFER_LIST &&
- optee_ep_info->args.arg1 == (TRANSFER_LIST_SIGNATURE |
- REGISTER_CONVENTION_VERSION_MASK)) {
- tl = (void *)optee_ep_info->args.arg3;
- if (transfer_list_check_header(tl) == TL_OPS_NON) {
- return 1;
- }
-
- opteed_rw = GET_RW(optee_ep_info->spsr);
+ tl = (void *)optee_ep_info->args.arg3;
+ if (TRANSFER_LIST && transfer_list_check_header(tl)) {
te = transfer_list_find(tl, TL_TAG_FDT);
dt = transfer_list_entry_data(te);
+ opteed_rw = GET_RW(optee_ep_info->spsr);
if (opteed_rw == OPTEE_AARCH64) {
+ if (optee_ep_info->args.arg1 !=
+ TRANSFER_LIST_HANDOFF_X1_VALUE(
+ REGISTER_CONVENTION_VERSION))
+ return 1;
+
arg0 = (uint64_t)dt;
arg2 = 0;
} else {
- arg2 = (uint64_t)dt;
+ if (optee_ep_info->args.arg1 !=
+ TRANSFER_LIST_HANDOFF_R1_VALUE(
+ REGISTER_CONVENTION_VERSION))
+ return 1;
+
arg0 = 0;
+ arg2 = (uint64_t)dt;
}
arg1 = optee_ep_info->args.arg1;
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c
index 8d27e96..f58f615 100644
--- a/services/std_svc/drtm/drtm_main.c
+++ b/services/std_svc/drtm/drtm_main.c
@@ -108,7 +108,7 @@
plat_drtm_get_imp_def_dlme_region_size();
dlme_data_min_size += dlme_data_hdr_init.dlme_addr_map_size +
- PLAT_DRTM_EVENT_LOG_MAX_SIZE +
+ ARM_DRTM_MIN_EVENT_LOG_SIZE +
dlme_data_hdr_init.dlme_tcb_hashes_table_size +
dlme_data_hdr_init.dlme_impdef_region_size;
@@ -208,7 +208,7 @@
return DENIED;
}
- running_on_single_core = psci_is_last_on_cpu_safe();
+ running_on_single_core = psci_is_last_on_cpu_safe(plat_my_core_pos());
if (!running_on_single_core) {
ERROR("DRTM: invalid launch due to non-boot PE not being turned off\n");
return SECONDARY_PE_NOT_OFF;
@@ -282,9 +282,9 @@
/* Prepare DRTM event log for DLME. */
drtm_serialise_event_log(dlme_data_cursor, &serialised_bytes_actual);
- assert(serialised_bytes_actual <= PLAT_DRTM_EVENT_LOG_MAX_SIZE);
- dlme_data_hdr->dlme_tpm_log_size = serialised_bytes_actual;
- dlme_data_cursor += serialised_bytes_actual;
+ assert(serialised_bytes_actual <= ARM_DRTM_MIN_EVENT_LOG_SIZE);
+ dlme_data_hdr->dlme_tpm_log_size = ARM_DRTM_MIN_EVENT_LOG_SIZE;
+ dlme_data_cursor += dlme_data_hdr->dlme_tpm_log_size;
/*
* TODO: Prepare the TCB hashes for DLME, currently its size
diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h
index a7d053f..c105b56 100644
--- a/services/std_svc/drtm/drtm_main.h
+++ b/services/std_svc/drtm/drtm_main.h
@@ -37,6 +37,11 @@
(((a)->dlme_paddr + (a)->dlme_img_off + (a)->dlme_img_ep_off))
/*
+ * Minimum size of Event Log in DLME data (64 KiB)
+ */
+#define ARM_DRTM_MIN_EVENT_LOG_SIZE U(0x10000)
+
+/*
* Range(Min/Max) of DRTM parameter structure versions supported
*/
#define ARM_DRTM_PARAMS_MIN_VERSION U(1)
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index d063ea3..10a2c42 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -33,6 +33,8 @@
#include <smccc_helpers.h>
#include <lib/extensions/sme.h>
#include <lib/extensions/sve.h>
+#include <lib/extensions/spe.h>
+#include <lib/extensions/trbe.h>
#include "rmmd_initial_context.h"
#include "rmmd_private.h"
@@ -119,14 +121,26 @@
static void manage_extensions_realm(cpu_context_t *ctx)
{
- pmuv3_enable(ctx);
-
/*
* Enable access to TPIDR2_EL0 if SME/SME2 is enabled for Non Secure world.
*/
if (is_feat_sme_supported()) {
sme_enable(ctx);
}
+
+ /*
+ * SPE and TRBE cannot be fully disabled from EL3 registers alone, only
+ * sysreg access can. In case the EL1 controls leave them active on
+ * context switch, we want the owning security state to be NS so Realm
+ * can't be DOSed.
+ */
+ if (is_feat_spe_supported()) {
+ spe_disable(ctx);
+ }
+
+ if (is_feat_trbe_supported()) {
+ trbe_disable(ctx);
+ }
}
static void manage_extensions_realm_per_world(void)
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
index e093a82..6fd0f2b 100644
--- a/services/std_svc/spm/el3_spmc/spmc.h
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -134,6 +134,9 @@
/* Track the source partition ID to validate a direct response. */
uint16_t dir_req_origin_id;
+
+ /* Track direct message function id to validate a direct response. */
+ uint16_t dir_req_funcid;
};
/*
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index c6ec30c..b0d6ba6 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -304,6 +304,7 @@
void *handle)
{
/* Retrieve populated Direct Response Arguments. */
+ uint64_t smc_fid = SMC_GET_GP(handle, CTX_GPREG_X0);
uint64_t x1 = SMC_GET_GP(handle, CTX_GPREG_X1);
uint64_t x2 = SMC_GET_GP(handle, CTX_GPREG_X2);
uint16_t src_id = ffa_endpoint_source(x1);
@@ -323,7 +324,8 @@
return false;
}
- if (!direct_msg_validate_arg2(x2)) {
+ if ((smc_fid != FFA_MSG_SEND_DIRECT_RESP2_SMC64) &&
+ !direct_msg_validate_arg2(x2)) {
ERROR("Invalid EL3 LP message encoding.\n");
return false;
}
@@ -331,6 +333,21 @@
}
/*******************************************************************************
+ * Helper function to check that partition can receive direct msg or not.
+ ******************************************************************************/
+static bool direct_msg_receivable(uint32_t properties, uint16_t dir_req_fnum)
+{
+ if ((dir_req_fnum == FFA_FNUM_MSG_SEND_DIRECT_REQ &&
+ ((properties & FFA_PARTITION_DIRECT_REQ_RECV) == 0U)) ||
+ (dir_req_fnum == FFA_FNUM_MSG_SEND_DIRECT_REQ2 &&
+ ((properties & FFA_PARTITION_DIRECT_REQ2_RECV) == 0U))) {
+ return false;
+ }
+
+ return true;
+}
+
+/*******************************************************************************
* Handle direct request messages and route to the appropriate destination.
******************************************************************************/
static uint64_t direct_req_smc_handler(uint32_t smc_fid,
@@ -345,14 +362,21 @@
{
uint16_t src_id = ffa_endpoint_source(x1);
uint16_t dst_id = ffa_endpoint_destination(x1);
+ uint16_t dir_req_funcid;
struct el3_lp_desc *el3_lp_descs;
struct secure_partition_desc *sp;
unsigned int idx;
- /* Check if arg2 has been populated correctly based on message type. */
- if (!direct_msg_validate_arg2(x2)) {
- return spmc_ffa_error_return(handle,
- FFA_ERROR_INVALID_PARAMETER);
+ dir_req_funcid = (smc_fid != FFA_MSG_SEND_DIRECT_REQ2_SMC64) ?
+ FFA_FNUM_MSG_SEND_DIRECT_REQ : FFA_FNUM_MSG_SEND_DIRECT_REQ2;
+
+ /*
+ * Sanity check for DIRECT_REQ:
+ * Check if arg2 has been populated correctly based on message type
+ */
+ if ((dir_req_funcid == FFA_FNUM_MSG_SEND_DIRECT_REQ) &&
+ !direct_msg_validate_arg2(x2)) {
+ return spmc_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER);
}
/* Validate Sender is either the current SP or from the normal world. */
@@ -368,6 +392,10 @@
/* Check if the request is destined for a Logical Partition. */
for (unsigned int i = 0U; i < MAX_EL3_LP_DESCS_COUNT; i++) {
if (el3_lp_descs[i].sp_id == dst_id) {
+ if (!direct_msg_receivable(el3_lp_descs[i].properties, dir_req_funcid)) {
+ return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+ }
+
uint64_t ret = el3_lp_descs[i].direct_req(
smc_fid, secure_origin, x1, x2,
x3, x4, cookie, handle, flags);
@@ -402,6 +430,10 @@
FFA_ERROR_INVALID_PARAMETER);
}
+ if (!direct_msg_receivable(sp->properties, dir_req_funcid)) {
+ return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+ }
+
/* Protect the runtime state of a UP S-EL0 SP with a lock. */
if (sp->runtime_el == S_EL0) {
spin_lock(&sp->rt_state_lock);
@@ -430,6 +462,7 @@
sp->ec[idx].rt_state = RT_STATE_RUNNING;
sp->ec[idx].rt_model = RT_MODEL_DIR_REQ;
sp->ec[idx].dir_req_origin_id = src_id;
+ sp->ec[idx].dir_req_funcid = dir_req_funcid;
if (sp->runtime_el == S_EL0) {
spin_unlock(&sp->rt_state_lock);
@@ -453,9 +486,13 @@
uint64_t flags)
{
uint16_t dst_id = ffa_endpoint_destination(x1);
+ uint16_t dir_req_funcid;
struct secure_partition_desc *sp;
unsigned int idx;
+ dir_req_funcid = (smc_fid != FFA_MSG_SEND_DIRECT_RESP2_SMC64) ?
+ FFA_FNUM_MSG_SEND_DIRECT_REQ : FFA_FNUM_MSG_SEND_DIRECT_REQ2;
+
/* Check if arg2 has been populated correctly based on message type. */
if (!direct_msg_validate_arg2(x2)) {
return spmc_ffa_error_return(handle,
@@ -507,6 +544,15 @@
return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
}
+ if (dir_req_funcid != sp->ec[idx].dir_req_funcid) {
+ WARN("Unmatched direct req/resp func id. req:%x, resp:%x on core%u.\n",
+ sp->ec[idx].dir_req_funcid, (smc_fid & FUNCID_NUM_MASK), idx);
+ if (sp->runtime_el == S_EL0) {
+ spin_unlock(&sp->rt_state_lock);
+ }
+ return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+ }
+
if (sp->ec[idx].dir_req_origin_id != dst_id) {
WARN("Invalid direct resp partition ID 0x%x != 0x%x on core%u.\n",
dst_id, sp->ec[idx].dir_req_origin_id, idx);
@@ -522,6 +568,9 @@
/* Clear the ongoing direct request ID. */
sp->ec[idx].dir_req_origin_id = INV_SP_ID;
+ /* Clear the ongoing direct request message version. */
+ sp->ec[idx].dir_req_funcid = 0U;
+
if (sp->runtime_el == S_EL0) {
spin_unlock(&sp->rt_state_lock);
}
@@ -647,6 +696,8 @@
{
struct secure_partition_desc *sp;
unsigned int idx;
+ uint16_t dst_id = ffa_endpoint_destination(x1);
+ bool cancel_dir_req = false;
/* Check that the response did not originate from the Normal world. */
if (!secure_origin) {
@@ -674,6 +725,32 @@
panic();
}
+ if (sp->runtime_el == S_EL0) {
+ spin_lock(&sp->rt_state_lock);
+ }
+
+ if (sp->ec[idx].rt_state == RT_STATE_RUNNING &&
+ sp->ec[idx].rt_model == RT_MODEL_DIR_REQ) {
+ sp->ec[idx].rt_state = RT_STATE_WAITING;
+ sp->ec[idx].dir_req_origin_id = INV_SP_ID;
+ sp->ec[idx].dir_req_funcid = 0x00;
+ cancel_dir_req = true;
+ }
+
+ if (sp->runtime_el == S_EL0) {
+ spin_unlock(&sp->rt_state_lock);
+ }
+
+ if (cancel_dir_req) {
+ if (dst_id == FFA_SPMC_ID) {
+ spmc_sp_synchronous_exit(&sp->ec[idx], x4);
+ /* Should not get here. */
+ panic();
+ } else
+ return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+ handle, cookie, flags, dst_id);
+ }
+
return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
}
@@ -1267,6 +1344,7 @@
case FFA_RX_RELEASE:
case FFA_MSG_SEND_DIRECT_REQ_SMC32:
case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+ case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
case FFA_PARTITION_INFO_GET:
case FFA_RXTX_MAP_SMC32:
case FFA_RXTX_MAP_SMC64:
@@ -1289,6 +1367,7 @@
case FFA_SECONDARY_EP_REGISTER_SMC64:
case FFA_MSG_SEND_DIRECT_RESP_SMC32:
case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+ case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
case FFA_MEM_RELINQUISH:
case FFA_MSG_WAIT:
case FFA_CONSOLE_LOG_SMC32:
@@ -1909,7 +1988,9 @@
/* Validate this entry, we currently only support direct messaging. */
if ((config_32 & ~(FFA_PARTITION_DIRECT_REQ_RECV |
- FFA_PARTITION_DIRECT_REQ_SEND)) != 0U) {
+ FFA_PARTITION_DIRECT_REQ_SEND |
+ FFA_PARTITION_DIRECT_REQ2_RECV |
+ FFA_PARTITION_DIRECT_REQ2_SEND)) != 0U) {
WARN("Invalid Secure Partition messaging method (0x%x)\n",
config_32);
return -EINVAL;
@@ -2077,39 +2158,34 @@
return ret;
}
- /* Check that the runtime EL in the manifest was correct. */
- if (sp->runtime_el != S_EL0 && sp->runtime_el != S_EL1) {
- ERROR("Unexpected runtime EL: %d\n", sp->runtime_el);
- return -EINVAL;
- }
-
/* Perform any common initialisation. */
spmc_sp_common_setup(sp, next_image_ep_info, boot_info_reg);
/* Perform any initialisation specific to S-EL1 SPs. */
if (sp->runtime_el == S_EL1) {
spmc_el1_sp_setup(sp, next_image_ep_info);
+ spmc_sp_common_ep_commit(sp, next_image_ep_info);
}
-
#if SPMC_AT_EL3_SEL0_SP
- /* Setup spsr in endpoint info for common context management routine. */
- if (sp->runtime_el == S_EL0) {
+ /* Perform any initialisation specific to S-EL0 SPs. */
+ else if (sp->runtime_el == S_EL0) {
+ /* Setup spsr in endpoint info for common context management routine. */
spmc_el0_sp_spsr_setup(next_image_ep_info);
- }
-#endif /* SPMC_AT_EL3_SEL0_SP */
- /* Initialize the SP context with the required ep info. */
- spmc_sp_common_ep_commit(sp, next_image_ep_info);
+ spmc_sp_common_ep_commit(sp, next_image_ep_info);
-#if SPMC_AT_EL3_SEL0_SP
- /*
- * Perform any initialisation specific to S-EL0 not set by common
- * context management routine.
- */
- if (sp->runtime_el == S_EL0) {
+ /*
+ * Perform any initialisation specific to S-EL0 not set by common
+ * context management routine.
+ */
spmc_el0_sp_setup(sp, boot_info_reg, sp_manifest);
}
#endif /* SPMC_AT_EL3_SEL0_SP */
+ else {
+ ERROR("Unexpected runtime EL: %u\n", sp->runtime_el);
+ return -EINVAL;
+ }
+
return 0;
}
@@ -2356,11 +2432,13 @@
case FFA_MSG_SEND_DIRECT_REQ_SMC32:
case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+ case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
return direct_req_smc_handler(smc_fid, secure_origin, x1, x2,
x3, x4, cookie, handle, flags);
case FFA_MSG_SEND_DIRECT_RESP_SMC32:
case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+ case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
return direct_resp_smc_handler(smc_fid, secure_origin, x1, x2,
x3, x4, cookie, handle, flags);
@@ -2426,11 +2504,13 @@
return spmc_ffa_console_log(smc_fid, secure_origin, x1, x2, x3,
x4, cookie, handle, flags);
- case FFA_MEM_PERM_GET:
+ case FFA_MEM_PERM_GET_SMC32:
+ case FFA_MEM_PERM_GET_SMC64:
return ffa_mem_perm_get_handler(smc_fid, secure_origin, x1, x2,
x3, x4, cookie, handle, flags);
- case FFA_MEM_PERM_SET:
+ case FFA_MEM_PERM_SET_SMC32:
+ case FFA_MEM_PERM_SET_SMC64:
return ffa_mem_perm_set_handler(smc_fid, secure_origin, x1, x2,
x3, x4, cookie, handle, flags);
diff --git a/services/std_svc/spm/el3_spmc/spmc_pm.c b/services/std_svc/spm/el3_spmc/spmc_pm.c
index 517d6d5..0a6215c 100644
--- a/services/std_svc/spm/el3_spmc/spmc_pm.c
+++ b/services/std_svc/spm/el3_spmc/spmc_pm.c
@@ -147,6 +147,8 @@
ec->rt_model = RT_MODEL_DIR_REQ;
ec->rt_state = RT_STATE_RUNNING;
ec->dir_req_origin_id = FFA_SPMC_ID;
+ /* Expect a direct message response from the SP. */
+ ec->dir_req_funcid = FFA_FNUM_MSG_SEND_DIRECT_REQ;
rc = spmc_sp_synchronous_entry(ec);
if (rc != 0ULL) {
diff --git a/services/std_svc/spm/el3_spmc/spmc_setup.c b/services/std_svc/spm/el3_spmc/spmc_setup.c
index f7357f1..d42115d 100644
--- a/services/std_svc/spm/el3_spmc/spmc_setup.c
+++ b/services/std_svc/spm/el3_spmc/spmc_setup.c
@@ -5,14 +5,22 @@
*/
#include <assert.h>
+#include <errno.h>
#include <string.h>
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <common/fdt_wrappers.h>
+
#include <context.h>
#include <lib/el3_runtime/context_mgmt.h>
+#if HOB_LIST
+#include <lib/hob/hob.h>
+#include <lib/hob/hob_guid.h>
+#include <lib/hob/mmram.h>
+#include <lib/hob/mpinfo.h>
+#endif
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <libfdt.h>
@@ -51,6 +59,199 @@
SP_MEM_REGION_NOT_SPECIFIED
};
+
+#if HOB_LIST
+static int get_memory_region_info(void *sp_manifest, int mem_region_node,
+ const char *name, uint32_t granularity,
+ uint64_t *base_address, uint32_t *size)
+{
+ char *property;
+ int node, ret;
+
+ if (name != NULL) {
+ node = fdt_subnode_offset_namelen(sp_manifest, mem_region_node,
+ name, strlen(name));
+ if (node < 0) {
+ ERROR("Not found '%s' region in memory regions configuration for SP.\n",
+ name);
+ return -ENOENT;
+ }
+ } else {
+ node = mem_region_node;
+ }
+
+ property = "base-address";
+ ret = fdt_read_uint64(sp_manifest, node, property, base_address);
+ if (ret < 0) {
+ ERROR("Not found property(%s) in memory region(%s).\n",
+ property, name);
+ return -ENOENT;
+ }
+
+ property = "pages-count";
+ ret = fdt_read_uint32(sp_manifest, node, property, size);
+ if (ret < 0) {
+ ERROR("Not found property(%s) in memory region(%s).\n",
+ property, name);
+ return -ENOENT;
+ }
+
+ *size = ((*size) << (PAGE_SIZE_SHIFT + (granularity << 1)));
+
+ return 0;
+}
+
+static struct efi_hob_handoff_info_table *build_sp_boot_hob_list(
+ void *sp_manifest, uintptr_t hob_table_start, size_t *hob_table_size)
+{
+ struct efi_hob_handoff_info_table *hob_table;
+ uintptr_t base_address;
+ int mem_region_node;
+ int32_t node, ret;
+ const char *name;
+ uint32_t granularity, size;
+ uint32_t mem_region_num;
+ struct efi_guid ns_buf_guid = MM_NS_BUFFER_GUID;
+ struct efi_guid mmram_resv_guid = MM_PEI_MMRAM_MEMORY_RESERVE_GUID;
+ struct efi_mmram_descriptor *mmram_desc_data;
+ struct efi_mmram_hob_descriptor_block *mmram_hob_desc_data;
+
+ if (sp_manifest == NULL || hob_table_size == NULL || *hob_table_size == 0) {
+ return NULL;
+ }
+
+ node = fdt_path_offset(sp_manifest, "/");
+ if (node < 0) {
+ ERROR("Failed to get root in sp_manifest.\n");
+ return NULL;
+ }
+
+ ret = fdt_read_uint32(sp_manifest, node, "xlat-granule", &granularity);
+ if (ret < 0) {
+ ERROR("Not found property(xlat-granule) in sp_manifest.\n");
+ return NULL;
+ }
+
+ if (granularity > 0x02) {
+ ERROR("Invalid granularity value: 0x%x\n", granularity);
+ return NULL;
+ }
+
+ mem_region_node = fdt_subnode_offset_namelen(sp_manifest, 0, "memory-regions",
+ sizeof("memory-regions") - 1);
+ if (node < 0) {
+ ERROR("Not found memory-region configuration for SP.\n");
+ return NULL;
+ }
+
+ INFO("Generating PHIT_HOB...\n");
+
+ hob_table = create_hob_list(BL32_BASE, BL32_LIMIT,
+ hob_table_start, *hob_table_size);
+ if (hob_table == NULL) {
+ ERROR("Failed to create Hob Table.\n");
+ return NULL;
+ }
+
+ /*
+ * Create fv hob.
+ */
+ ret = get_memory_region_info(sp_manifest, mem_region_node,
+ "stmm_region", granularity, &base_address, &size);
+ if (ret < 0) {
+ return NULL;
+ }
+
+ if (base_address != BL32_BASE &&
+ base_address + size > BL32_LIMIT) {
+ ERROR("Image is ouf of bound(0x%lx/0x%x), should be in (0x%llx/0x%llx)\n",
+ base_address, size, BL32_BASE, BL32_LIMIT - BL32_BASE);
+ return NULL;
+ }
+
+ ret = create_fv_hob(hob_table, base_address, size);
+ if (ret < 0) {
+ ERROR("Failed to create fv hob... ret:%d\n", ret);
+ return NULL;
+ }
+
+ INFO("Success to create FV hob(0x%lx/0x%x).\n", base_address, size);
+
+ /*
+ * Create Ns Buffer hob.
+ */
+ ret = get_memory_region_info(sp_manifest, mem_region_node,
+ "ns_comm_buffer", granularity, &base_address, &size);
+ if (ret < 0) {
+ return NULL;
+ }
+
+ ret = create_guid_hob(hob_table, &ns_buf_guid,
+ sizeof(struct efi_mmram_descriptor), (void **) &mmram_desc_data);
+ if (ret < 0) {
+ ERROR("Failed to create ns buffer hob\n");
+ return NULL;
+ }
+
+ mmram_desc_data->physical_start = base_address;
+ mmram_desc_data->physical_size = size;
+ mmram_desc_data->cpu_start = base_address;
+ mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+
+ /*
+ * Create mmram_resv hob.
+ */
+ for (node = fdt_first_subnode(sp_manifest, mem_region_node), mem_region_num = 0;
+ node >= 0;
+ node = fdt_next_subnode(sp_manifest, node), mem_region_num++) {
+ ret = get_memory_region_info(sp_manifest, node, NULL, granularity,
+ &base_address, &size);
+ if (ret < 0) {
+ name = fdt_get_name(sp_manifest, node, NULL);
+ ERROR("Invalid memory region(%s) found!\n", name);
+ return NULL;
+ }
+ }
+
+ ret = create_guid_hob(hob_table, &mmram_resv_guid,
+ (sizeof(struct efi_mmram_hob_descriptor_block) +
+ (sizeof(struct efi_mmram_descriptor) * mem_region_num)),
+ (void **) &mmram_hob_desc_data);
+ if (ret < 0) {
+ ERROR("Failed to create mmram_resv hob. ret: %d\n", ret);
+ return NULL;
+ }
+
+ mmram_hob_desc_data->number_of_mm_reserved_regions = mem_region_num;
+
+ for (node = fdt_first_subnode(sp_manifest, mem_region_node), mem_region_num = 0;
+ node >= 0;
+ node = fdt_next_subnode(sp_manifest, node), mem_region_num++) {
+ get_memory_region_info(sp_manifest, node, NULL, granularity,
+ &base_address, &size);
+ name = fdt_get_name(sp_manifest, node, NULL);
+
+ mmram_desc_data = &mmram_hob_desc_data->descriptor[mem_region_num];
+ mmram_desc_data->physical_start = base_address;
+ mmram_desc_data->physical_size = size;
+ mmram_desc_data->cpu_start = base_address;
+
+ if (!strcmp(name, "heap")) {
+ mmram_desc_data->region_state = EFI_CACHEABLE;
+ } else {
+ mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+ }
+ }
+
+ *hob_table_size = hob_table->efi_free_memory_bottom -
+ (efi_physical_address_t) hob_table;
+
+ return hob_table;
+}
+#endif
+
+
+
/*
* This function creates a initialization descriptor in the memory reserved
* for passing boot information to an SP. It then copies the partition manifest
@@ -62,14 +263,13 @@
{
struct ffa_boot_info_header *boot_header;
struct ffa_boot_info_desc *boot_descriptor;
- uintptr_t manifest_addr;
+ uintptr_t content_addr;
/*
* Calculate the maximum size of the manifest that can be accommodated
* in the boot information memory region.
*/
- const unsigned int
- max_manifest_sz = sizeof(ffa_boot_info_mem) -
+ size_t max_sz = sizeof(ffa_boot_info_mem) -
(sizeof(struct ffa_boot_info_header) +
sizeof(struct ffa_boot_info_desc));
@@ -83,17 +283,6 @@
return;
}
- /*
- * Check if the manifest will fit into the boot info memory region else
- * bail.
- */
- if (ep_info->args.arg1 > max_manifest_sz) {
- WARN("Unable to copy manifest into boot information. ");
- WARN("Max sz = %u bytes. Manifest sz = %lu bytes\n",
- max_manifest_sz, ep_info->args.arg1);
- return;
- }
-
/* Zero the memory region before populating. */
memset(ffa_boot_info_mem, 0, PAGE_SIZE);
@@ -125,29 +314,58 @@
/* Set the count. Currently 1 since only the manifest is specified. */
boot_header->count_boot_info_desc = 1;
+ boot_descriptor->flags =
+ FFA_BOOT_INFO_FLAG_NAME(FFA_BOOT_INFO_FLAG_NAME_UUID) |
+ FFA_BOOT_INFO_FLAG_CONTENT(FFA_BOOT_INFO_FLAG_CONTENT_ADR);
+
+ content_addr = (uintptr_t) (ffa_boot_info_mem +
+ boot_header->offset_boot_info_desc +
+ boot_header->size_boot_info_desc);
+
+#if HOB_LIST
+ /* Populate the boot information descriptor for the hob_list. */
+ boot_descriptor->type =
+ FFA_BOOT_INFO_TYPE(FFA_BOOT_INFO_TYPE_STD) |
+ FFA_BOOT_INFO_TYPE_ID(FFA_BOOT_INFO_TYPE_ID_HOB);
+
+ content_addr = (uintptr_t) build_sp_boot_hob_list(
+ (void *) ep_info->args.arg0, content_addr, &max_sz);
+ if (content_addr == (uintptr_t) NULL) {
+ WARN("Unable to create phit hob properly.");
+ return;
+ }
+
+ boot_descriptor->size_boot_info = max_sz;
+ boot_descriptor->content = content_addr;
+#else
+ /*
+ * Check if the manifest will fit into the boot info memory region else
+ * bail.
+ */
+ if (ep_info->args.arg1 > max_sz) {
+ WARN("Unable to copy manifest into boot information. ");
+ WARN("Max sz = %lu bytes. Manifest sz = %lu bytes\n",
+ max_sz, ep_info->args.arg1);
+ return;
+ }
+
/* Populate the boot information descriptor for the manifest. */
boot_descriptor->type =
FFA_BOOT_INFO_TYPE(FFA_BOOT_INFO_TYPE_STD) |
FFA_BOOT_INFO_TYPE_ID(FFA_BOOT_INFO_TYPE_ID_FDT);
- boot_descriptor->flags =
- FFA_BOOT_INFO_FLAG_NAME(FFA_BOOT_INFO_FLAG_NAME_UUID) |
- FFA_BOOT_INFO_FLAG_CONTENT(FFA_BOOT_INFO_FLAG_CONTENT_ADR);
-
/*
* Copy the manifest into boot info region after the boot information
* descriptor.
*/
boot_descriptor->size_boot_info = (uint32_t) ep_info->args.arg1;
- manifest_addr = (uintptr_t) (ffa_boot_info_mem +
- boot_header->offset_boot_info_desc +
- boot_header->size_boot_info_desc);
- memcpy((void *) manifest_addr, (void *) ep_info->args.arg0,
+ memcpy((void *) content_addr, (void *) ep_info->args.arg0,
boot_descriptor->size_boot_info);
- boot_descriptor->content = manifest_addr;
+ boot_descriptor->content = content_addr;
+#endif
/* Calculate the size of the total boot info blob. */
boot_header->size_boot_info_blob = boot_header->offset_boot_info_desc +
@@ -158,7 +376,7 @@
INFO("SP boot info @ 0x%lx, size: %u bytes.\n",
(uintptr_t) ffa_boot_info_mem,
boot_header->size_boot_info_blob);
- INFO("SP manifest @ 0x%lx, size: %u bytes.\n",
+ INFO("SP content @ 0x%lx, size: %u bytes.\n",
boot_descriptor->content,
boot_descriptor->size_boot_info);
}
@@ -194,6 +412,7 @@
out[0] = '\0';
} else {
memcpy(out, prop, MIN(lenp, (int)len));
+ out[MIN(lenp, (int)len) - 1] = '\0';
}
}
@@ -292,10 +511,11 @@
sp_mem_regions.base_va = base_address;
sp_mem_regions.size = size;
- INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx attr:0x%x\n",
+ INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx mem_attr: 0x%x, attr:0x%x\n",
sp_mem_regions.base_pa,
sp_mem_regions.base_va,
sp_mem_regions.size,
+ mem_attr,
sp_mem_regions.attr);
if (type == SP_MEM_REGION_DEVICE) {
@@ -464,7 +684,6 @@
}
spmc_el0_sp_setup_system_registers(sp, ctx);
-
}
#endif /* SPMC_AT_EL3_SEL0_SP */
diff --git a/services/std_svc/spm/spm_mm/spm_mm_setup.c b/services/std_svc/spm/spm_mm/spm_mm_setup.c
index de05459..66ce84c 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_setup.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_setup.c
@@ -13,6 +13,15 @@
#include <context.h>
#include <common/debug.h>
#include <lib/el3_runtime/context_mgmt.h>
+#if HOB_LIST
+#include <lib/hob/hob.h>
+#include <lib/hob/hob_guid.h>
+#include <lib/hob/mmram.h>
+#include <lib/hob/mpinfo.h>
+#endif
+#if TRANSFER_LIST
+#include <lib/transfer_list.h>
+#endif
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <platform_def.h>
#include <plat/common/common_def.h>
@@ -23,6 +32,92 @@
#include "spm_mm_private.h"
#include "spm_shim_private.h"
+#if HOB_LIST && TRANSFER_LIST
+static struct efi_hob_handoff_info_table *build_sp_boot_hob_list(
+ const spm_mm_boot_info_t *sp_boot_info, uint16_t *hob_table_size)
+{
+ int ret;
+ struct efi_hob_handoff_info_table *hob_table;
+ struct efi_guid ns_buf_guid = MM_NS_BUFFER_GUID;
+ struct efi_guid mmram_resv_guid = MM_PEI_MMRAM_MEMORY_RESERVE_GUID;
+ struct efi_mmram_descriptor *mmram_desc_data;
+ uint16_t mmram_resv_data_size;
+ struct efi_mmram_hob_descriptor_block *mmram_hob_desc_data;
+ uint64_t hob_table_offset;
+
+ hob_table_offset = sizeof(struct transfer_list_header) +
+ sizeof(struct transfer_list_entry);
+
+ *hob_table_size = 0U;
+
+ hob_table = create_hob_list(sp_boot_info->sp_mem_base,
+ sp_boot_info->sp_mem_limit - sp_boot_info->sp_mem_base,
+ sp_boot_info->sp_shared_buf_base + hob_table_offset,
+ sp_boot_info->sp_shared_buf_size);
+ if (hob_table == NULL) {
+ return NULL;
+ }
+
+ ret = create_fv_hob(hob_table, sp_boot_info->sp_image_base,
+ sp_boot_info->sp_image_size);
+ if (ret) {
+ return NULL;
+ }
+
+ ret = create_guid_hob(hob_table, &ns_buf_guid,
+ sizeof(struct efi_mmram_descriptor), (void **) &mmram_desc_data);
+ if (ret) {
+ return NULL;
+ }
+
+ mmram_desc_data->physical_start = sp_boot_info->sp_ns_comm_buf_base;
+ mmram_desc_data->physical_size = sp_boot_info->sp_ns_comm_buf_size;
+ mmram_desc_data->cpu_start = sp_boot_info->sp_ns_comm_buf_base;
+ mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+
+ mmram_resv_data_size = sizeof(struct efi_mmram_hob_descriptor_block) +
+ sizeof(struct efi_mmram_descriptor) * sp_boot_info->num_sp_mem_regions;
+
+ ret = create_guid_hob(hob_table, &mmram_resv_guid,
+ mmram_resv_data_size, (void **) &mmram_hob_desc_data);
+ if (ret) {
+ return NULL;
+ }
+
+ *hob_table_size = hob_table->efi_free_memory_bottom -
+ (efi_physical_address_t) hob_table;
+
+ mmram_hob_desc_data->number_of_mm_reserved_regions = 4U;
+ mmram_desc_data = &mmram_hob_desc_data->descriptor[0];
+
+ /* First, should be image mm range. */
+ mmram_desc_data[0].physical_start = sp_boot_info->sp_image_base;
+ mmram_desc_data[0].physical_size = sp_boot_info->sp_image_size;
+ mmram_desc_data[0].cpu_start = sp_boot_info->sp_image_base;
+ mmram_desc_data[0].region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+
+ /* Second, should be shared buffer mm range. */
+ mmram_desc_data[1].physical_start = sp_boot_info->sp_shared_buf_base;
+ mmram_desc_data[1].physical_size = sp_boot_info->sp_shared_buf_size;
+ mmram_desc_data[1].cpu_start = sp_boot_info->sp_shared_buf_base;
+ mmram_desc_data[1].region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+
+ /* Ns Buffer mm range */
+ mmram_desc_data[2].physical_start = sp_boot_info->sp_ns_comm_buf_base;
+ mmram_desc_data[2].physical_size = sp_boot_info->sp_ns_comm_buf_size;
+ mmram_desc_data[2].cpu_start = sp_boot_info->sp_ns_comm_buf_base;
+ mmram_desc_data[2].region_state = EFI_CACHEABLE | EFI_ALLOCATED;
+
+ /* Heap mm range */
+ mmram_desc_data[3].physical_start = sp_boot_info->sp_heap_base;
+ mmram_desc_data[3].physical_size = sp_boot_info->sp_heap_size;
+ mmram_desc_data[3].cpu_start = sp_boot_info->sp_heap_base;
+ mmram_desc_data[3].region_state = EFI_CACHEABLE;
+
+ return hob_table;
+}
+#endif
+
/* Setup context of the Secure Partition */
void spm_sp_setup(sp_context_t *sp_ctx)
{
@@ -32,6 +127,15 @@
const spm_mm_boot_info_t *sp_boot_info =
plat_get_secure_partition_boot_info(NULL);
+#if HOB_LIST && TRANSFER_LIST
+ struct efi_hob_handoff_info_table *hob_table;
+ struct transfer_list_header *sp_boot_tl;
+ struct transfer_list_entry *sp_boot_te;
+ uint16_t hob_table_size;
+#endif
+
+ assert(sp_boot_info != NULL);
+
/*
* Initialize CPU context
* ----------------------
@@ -195,7 +299,35 @@
* Prepare information in buffer shared between EL3 and S-EL0
* ----------------------------------------------------------
*/
+#if HOB_LIST && TRANSFER_LIST
+ sp_boot_tl = transfer_list_init((void *) sp_boot_info->sp_shared_buf_base,
+ sp_boot_info->sp_shared_buf_size);
+ assert(sp_boot_tl != NULL);
+ hob_table = build_sp_boot_hob_list(sp_boot_info, &hob_table_size);
+ assert(hob_table != NULL);
+
+ transfer_list_update_checksum(sp_boot_tl);
+
+ sp_boot_te = transfer_list_add(sp_boot_tl, TL_TAG_HOB_LIST,
+ hob_table_size, hob_table);
+ if (sp_boot_te == NULL) {
+ ERROR("Failed to add HOB list to xfer list\n");
+ }
+
+ transfer_list_set_handoff_args(sp_boot_tl, &ep_info);
+
+ transfer_list_dump(sp_boot_tl);
+
+ write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0,
+ ep_info.args.arg0);
+ write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1,
+ ep_info.args.arg1);
+ write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2,
+ ep_info.args.arg2);
+ write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3,
+ ep_info.args.arg3);
+#else
void *shared_buf_ptr = (void *) sp_boot_info->sp_shared_buf_base;
/* Copy the boot information into the shared buffer with the SP. */
@@ -205,7 +337,6 @@
assert(sp_boot_info->sp_shared_buf_base <=
(UINTPTR_MAX - sp_boot_info->sp_shared_buf_size + 1));
- assert(sp_boot_info != NULL);
memcpy((void *) shared_buf_ptr, (const void *) sp_boot_info,
sizeof(spm_mm_boot_info_t));
@@ -256,4 +387,5 @@
if (plat_my_core_pos() == sp_mp_info[index].linear_id)
sp_mp_info[index].flags |= MP_INFO_FLAG_PRIMARY_CPU;
}
+#endif
}
diff --git a/tools/amlogic/Makefile b/tools/amlogic/Makefile
index 7bfee7d..cdaf7e7 100644
--- a/tools/amlogic/Makefile
+++ b/tools/amlogic/Makefile
@@ -1,5 +1,6 @@
#
# Copyright (C) 2019 Remi Pommarel <repk@triplefau.lt>
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# https://spdx.org/licenses
@@ -7,11 +8,10 @@
MAKE_HELPERS_DIRECTORY := ../../make_helpers/
include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
include ${MAKE_HELPERS_DIRECTORY}common.mk
include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
-PROJECT := doimage${BIN_EXT}
+PROJECT := doimage$(.exe)
OBJECTS := doimage.o
HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE
@@ -38,6 +38,6 @@
$(q)$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
clean:
- $(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+ $(q)rm -rf $(PROJECT) $(OBJECTS)
distclean: clean
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index ce12a66..e403b2d 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -1,18 +1,17 @@
#
-# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
PLAT := none
DEBUG := 0
-CRTTOOL ?= cert_create${BIN_EXT}
+CRTTOOL ?= cert_create$(.exe)
BINARY := $(notdir ${CRTTOOL})
COT := tbbr
MAKE_HELPERS_DIRECTORY := ../../make_helpers/
include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
include ${MAKE_HELPERS_DIRECTORY}common.mk
include ${MAKE_HELPERS_DIRECTORY}defaults.mk
include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
@@ -95,7 +94,7 @@
endif
clean:
- $(call SHELL_DELETE_ALL,${OBJECTS})
+ $(q)rm -rf $(OBJECTS)
realclean: clean
- $(call SHELL_DELETE,${BINARY})
+ $(q)rm -f $(BINARY)
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
index f7adfab..83a7b18 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.h
@@ -45,8 +45,8 @@
{ 2048, 1024, 3072, 4096 }, /* KEY_ALG_RSA */
#ifndef OPENSSL_NO_EC
{ 256, 384 }, /* KEY_ALG_ECDSA_NIST */
- {}, /* KEY_ALG_ECDSA_BRAINPOOL_R */
- {} /* KEY_ALG_ECDSA_BRAINPOOL_T */
+ { 256 }, /* KEY_ALG_ECDSA_BRAINPOOL_R */
+ { 256 } /* KEY_ALG_ECDSA_BRAINPOOL_T */
#endif /* OPENSSL_NO_EC */
};
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 190c096..4fc0add 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -17,6 +17,7 @@
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
+#include <openssl/ssl.h>
#include "cert.h"
#include "cmd_opt.h"
@@ -214,6 +215,13 @@
EVP_PKEY *pkey;
ENGINE *e;
+#if !USING_OPENSSL3
+ if (!OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL)) {
+ fprintf(stderr, "Failed to init SSL\n");
+ return NULL;
+ }
+#endif
+
ENGINE_load_builtin_engines();
e = ENGINE_by_id("pkcs11");
if (!e) {
diff --git a/tools/cot_dt2c/poetry.lock b/tools/cot_dt2c/poetry.lock
index df58d54..eea96cd 100644
--- a/tools/cot_dt2c/poetry.lock
+++ b/tools/cot_dt2c/poetry.lock
@@ -1,35 +1,6 @@
# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
[[package]]
-name = "atomicwrites"
-version = "1.4.1"
-description = "Atomic file writes."
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-files = [
- {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"},
-]
-
-[[package]]
-name = "attrs"
-version = "24.2.0"
-description = "Classes Without Boilerplate"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"},
- {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"},
-]
-
-[package.extras]
-benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
-cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
-dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
-docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
-tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
-tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
-
-[[package]]
name = "click"
version = "8.1.7"
description = "Composable command line interface toolkit"
@@ -55,6 +26,20 @@
]
[[package]]
+name = "exceptiongroup"
+version = "1.2.2"
+description = "Backport of PEP 654 (exception groups)"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
+ {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
+]
+
+[package.extras]
+test = ["pytest (>=6)"]
+
+[[package]]
name = "igraph"
version = "0.11.6"
description = "High performance graph data structures and algorithms"
@@ -218,17 +203,6 @@
testing = ["pytest", "pytest-benchmark"]
[[package]]
-name = "py"
-version = "1.11.0"
-description = "library with cross-python path, ini-parsing, io, code, log facilities"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-files = [
- {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
- {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
-]
-
-[[package]]
name = "pydevicetree"
version = "0.0.13"
description = "A library for parsing Devicetree Source v1"
@@ -258,27 +232,25 @@
[[package]]
name = "pytest"
-version = "6.2.5"
+version = "8.3.4"
description = "pytest: simple powerful testing with Python"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
files = [
- {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
- {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
+ {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"},
+ {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"},
]
[package.dependencies]
-atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
-attrs = ">=19.2.0"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
-pluggy = ">=0.12,<2.0"
-py = ">=1.8.2"
-toml = "*"
+pluggy = ">=1.5,<2"
+tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras]
-testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
+dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]]
name = "tenacity"
@@ -318,6 +290,47 @@
]
[[package]]
+name = "tomli"
+version = "2.2.1"
+description = "A lil' TOML parser"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
+ {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
+ {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
+ {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
+ {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
+ {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
+ {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
+ {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
+ {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
+ {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
+ {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
+ {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
+ {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
+ {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
+ {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
+ {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
+ {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
+ {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
+ {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
+ {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
+ {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
+ {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
+ {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
+ {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
+ {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
+ {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
+ {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
+ {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
+ {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
+ {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
+ {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
+ {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
+]
+
+[[package]]
name = "typing-extensions"
version = "4.12.2"
description = "Backported and Experimental Type Hints for Python 3.8+"
@@ -331,4 +344,4 @@
[metadata]
lock-version = "2.0"
python-versions = "^3.8"
-content-hash = "afa5cb49be96467a848bab753a630c6f5ec42d6750d67d29920c3e3971774e36"
+content-hash = "0f5b2b008bb5de8545881eaeacfdd1a6fe50e5271feea4635d622ffce9e550dc"
diff --git a/tools/cot_dt2c/pyproject.toml b/tools/cot_dt2c/pyproject.toml
index 73251d7..fc31d54 100644
--- a/tools/cot_dt2c/pyproject.toml
+++ b/tools/cot_dt2c/pyproject.toml
@@ -38,7 +38,7 @@
[tool.poetry.group.dev.dependencies]
mypy = "^0.910"
-pytest = "^6.2.5"
+pytest = "^8.3.4"
[tool.mypy]
# https://mypy.readthedocs.io/en/latest/config_file.html#using-a-pyproject-toml-file
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index 50b0fa2..14def1d 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2024, Arm Limited. All rights reserved.
+# Copyright (c) 2024-2025, Arm Limited. All rights reserved.
# Copyright (c) 2019-2022, Linaro Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
@@ -7,13 +7,12 @@
BUILD_INFO ?= 1
DEBUG := 0
-ENCTOOL ?= encrypt_fw${BIN_EXT}
+ENCTOOL ?= encrypt_fw$(.exe)
BINARY := $(notdir ${ENCTOOL})
OPENSSL_DIR := /usr
MAKE_HELPERS_DIRECTORY := ../../make_helpers/
include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
include ${MAKE_HELPERS_DIRECTORY}common.mk
include ${MAKE_HELPERS_DIRECTORY}defaults.mk
include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
@@ -75,7 +74,7 @@
endif
clean:
- $(call SHELL_DELETE_ALL,${OBJECTS})
+ $(q)rm -rf $(OBJECTS)
realclean: clean
- $(call SHELL_DELETE,${BINARY})
+ $(q)rm -f $(BINARY)
diff --git a/tools/encrypt_fw/src/main.c b/tools/encrypt_fw/src/main.c
index 6e43e73..b6246f6 100644
--- a/tools/encrypt_fw/src/main.c
+++ b/tools/encrypt_fw/src/main.c
@@ -26,7 +26,9 @@
/* Global options */
+#if LOG_LEVEL >= LOG_LEVEL_NOTICE
static const char build_msg[] = "Built : " __TIME__ ", " __DATE__;
+#endif
static char *key_algs_str[] = {
[KEY_ALG_GCM] = "gcm",
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 54dee87..a660a50 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -1,17 +1,16 @@
#
-# Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
MAKE_HELPERS_DIRECTORY := ../../make_helpers/
include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
include ${MAKE_HELPERS_DIRECTORY}common.mk
include ${MAKE_HELPERS_DIRECTORY}defaults.mk
include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
-FIPTOOL ?= fiptool${BIN_EXT}
+FIPTOOL ?= fiptool$(.exe)
PROJECT := $(notdir ${FIPTOOL})
OBJECTS := fiptool.o tbbr_config.o
STATIC ?= 0
@@ -93,4 +92,4 @@
endif # STATIC
clean:
- $(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS} $(DEPS))
+ $(q)rm -rf $(PROJECT) $(OBJECTS) $(DEPS)
diff --git a/tools/fiptool/Makefile.msvc b/tools/fiptool/Makefile.msvc
deleted file mode 100644
index 9081bc6..0000000
--- a/tools/fiptool/Makefile.msvc
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-CC = cl.exe
-LD = link.exe
-
-# FIPTOOLPATH and FIPTOOL are passed from the main makefile.
-
-OBJECTS = $(FIPTOOLPATH)\fiptool.obj \
- $(FIPTOOLPATH)\tbbr_config.obj \
- $(FIPTOOLPATH)\win_posix.obj
-
-INC = -I$(FIPTOOLPATH) -Iinclude\tools_share
-
-CFLAGS = $(CFLAGS) /nologo /Za /Zi /c /O2 /MT
-
-all: $(FIPTOOL)
-
-$(FIPTOOL): $(OBJECTS)
- $(LD) /nologo /INCREMENTAL:NO /debug /nodefaultlib:libc.lib /out:$@ $(LIBS) $**
-
-.PHONY: clean realclean
-
-clean:
- -@del /f /q $(OBJECTS) > nul
- -@del /f /q $(FIPTOOLPATH)\*.pdb > nul
-
-realclean:
- -@del /f /q $(OBJECTS) > nul
- -@del /f /q $(FIPTOOLPATH)\*.pdb > nul
- -@del /f /q $(FIPTOOL) > nul
-
-.c.obj:
- $(CC) -c $(CFLAGS) $(INC) $< -Fo$@
diff --git a/tools/nxp/create_pbl/Makefile b/tools/nxp/create_pbl/Makefile
index 22aa921..965cc51 100644
--- a/tools/nxp/create_pbl/Makefile
+++ b/tools/nxp/create_pbl/Makefile
@@ -1,18 +1,18 @@
#
# Copyright 2018-2020 NXP
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
MAKE_HELPERS_DIRECTORY := ../../../make_helpers/
include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
include ${MAKE_HELPERS_DIRECTORY}common.mk
include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
-PROJECT_1 := create_pbl${BIN_EXT}
+PROJECT_1 := create_pbl$(.exe)
OBJECTS_1 := create_pbl.o
-PROJECT_2 := byte_swap${BIN_EXT}
+PROJECT_2 := byte_swap$(.exe)
OBJECTS_2 := byte_swap.o
override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
@@ -49,5 +49,5 @@
$(q)$(host-cc) -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
clean:
- $(call SHELL_DELETE_ALL, ${PROJECT_1} ${OBJECTS_1})
- $(call SHELL_DELETE_ALL, ${PROJECT_2} ${OBJECTS_2})
+ $(q)rm -rf $(PROJECT_1) $(OBJECTS_1)
+ $(q)rm -rf $(PROJECT_2) $(OBJECTS_2)
diff --git a/tools/nxp/create_pbl/create_pbl.mk b/tools/nxp/create_pbl/create_pbl.mk
index 305c049..81f6d13 100644
--- a/tools/nxp/create_pbl/create_pbl.mk
+++ b/tools/nxp/create_pbl/create_pbl.mk
@@ -1,12 +1,13 @@
#
# Copyright 2018-2020 NXP
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#
-CREATE_PBL ?= ${CREATE_PBL_TOOL_PATH}/create_pbl${BIN_EXT}
-BYTE_SWAP ?= ${CREATE_PBL_TOOL_PATH}/byte_swap${BIN_EXT}
+CREATE_PBL ?= ${CREATE_PBL_TOOL_PATH}/create_pbl$(.exe)
+BYTE_SWAP ?= ${CREATE_PBL_TOOL_PATH}/byte_swap$(.exe)
HOST_GCC := gcc
diff --git a/tools/nxp/create_pbl/pbl_ch2.mk b/tools/nxp/create_pbl/pbl_ch2.mk
index bf05a12..47ff892 100644
--- a/tools/nxp/create_pbl/pbl_ch2.mk
+++ b/tools/nxp/create_pbl/pbl_ch2.mk
@@ -1,12 +1,13 @@
#
# Copyright 2020 NXP
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#
-CREATE_PBL ?= ${CREATE_PBL_TOOL_PATH}/create_pbl${BIN_EXT}
-BYTE_SWAP ?= ${CREATE_PBL_TOOL_PATH}/byte_swap${BIN_EXT}
+CREATE_PBL ?= ${CREATE_PBL_TOOL_PATH}/create_pbl$(.exe)
+BYTE_SWAP ?= ${CREATE_PBL_TOOL_PATH}/byte_swap$(.exe)
HOST_GCC := gcc
diff --git a/tools/nxp/create_pbl/pbl_ch3.mk b/tools/nxp/create_pbl/pbl_ch3.mk
index 15129e4..f5d42cd 100644
--- a/tools/nxp/create_pbl/pbl_ch3.mk
+++ b/tools/nxp/create_pbl/pbl_ch3.mk
@@ -1,13 +1,14 @@
#
# Copyright 2018-2022 NXP
+# Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#
SHELL=/bin/bash
-CREATE_PBL ?= ${CREATE_PBL_TOOL_PATH}/create_pbl${BIN_EXT}
-BYTE_SWAP ?= ${CREATE_PBL_TOOL_PATH}/byte_swap${BIN_EXT}
+CREATE_PBL ?= ${CREATE_PBL_TOOL_PATH}/create_pbl$(.exe)
+BYTE_SWAP ?= ${CREATE_PBL_TOOL_PATH}/byte_swap$(.exe)
HOST_GCC := gcc
diff --git a/tools/renesas/rcar_layout_create/makefile b/tools/renesas/rcar_layout_create/makefile
index 7a64b19..f89f379 100644
--- a/tools/renesas/rcar_layout_create/makefile
+++ b/tools/renesas/rcar_layout_create/makefile
@@ -102,7 +102,7 @@
$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
$(OUTPUT_FILE_SA0): $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0) | $$(@D)/
- $(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib -T $(MEMORY_DEF_SA0) -o $(OUTPUT_FILE_SA0) -Wl,-Map $(FILE_NAME_SA0).map
+ $(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib -static -Wl,--build-id=none -T $(MEMORY_DEF_SA0) -o $(OUTPUT_FILE_SA0) -Wl,-Map $(FILE_NAME_SA0).map
$(FILE_NAME_SA6).srec: $(OUTPUT_FILE_SA6) | $$(@D)/
$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
@@ -111,7 +111,7 @@
$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).bin
$(OUTPUT_FILE_SA6): $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6) | $$(@D)/
- $(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib -T $(MEMORY_DEF_SA6) -o $(OUTPUT_FILE_SA6) -Wl,-Map $(FILE_NAME_SA6).map
+ $(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib -static -Wl,--build-id=none -T $(MEMORY_DEF_SA6) -o $(OUTPUT_FILE_SA6) -Wl,-Map $(FILE_NAME_SA6).map
###################################################
# Compile
diff --git a/tools/sptool/Makefile b/tools/sptool/Makefile
index 0da5c09..f579a42 100644
--- a/tools/sptool/Makefile
+++ b/tools/sptool/Makefile
@@ -1,16 +1,15 @@
#
-# Copyright (c) 2018-2024, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2025, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
MAKE_HELPERS_DIRECTORY := ../../make_helpers/
include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
include ${MAKE_HELPERS_DIRECTORY}common.mk
include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
-SPTOOL ?= sptool${BIN_EXT}
+SPTOOL ?= sptool$(.exe)
PROJECT := $(notdir ${SPTOOL})
OBJECTS := sptool.o
@@ -40,4 +39,4 @@
$(q)$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
clean:
- $(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+ $(q)rm -rf $(PROJECT) $(OBJECTS)
diff --git a/tools/stm32image/Makefile b/tools/stm32image/Makefile
index 453daae..64b6ccf 100644
--- a/tools/stm32image/Makefile
+++ b/tools/stm32image/Makefile
@@ -1,16 +1,15 @@
#
-# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
MAKE_HELPERS_DIRECTORY := ../../make_helpers/
include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
include ${MAKE_HELPERS_DIRECTORY}common.mk
include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
-PROJECT := stm32image${BIN_EXT}
+PROJECT := stm32image$(.exe)
OBJECTS := stm32image.o
HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE
@@ -37,6 +36,6 @@
$(q)$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
clean:
- $(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+ $(q)rm -rf $(PROJECT) $(OBJECTS)
distclean: clean
diff --git a/tools/tlc/poetry.lock b/tools/tlc/poetry.lock
index decec59..ea1b750 100644
--- a/tools/tlc/poetry.lock
+++ b/tools/tlc/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
[[package]]
name = "astroid"
@@ -495,13 +495,13 @@
[[package]]
name = "jinja2"
-version = "3.1.4"
+version = "3.1.5"
description = "A very fast and expressive template engine."
optional = false
python-versions = ">=3.7"
files = [
- {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
- {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
+ {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"},
+ {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"},
]
[package.dependencies]
@@ -1331,13 +1331,13 @@
[[package]]
name = "virtualenv"
-version = "20.26.5"
+version = "20.26.6"
description = "Virtual Python Environment builder"
optional = false
python-versions = ">=3.7"
files = [
- {file = "virtualenv-20.26.5-py3-none-any.whl", hash = "sha256:4f3ac17b81fba3ce3bd6f4ead2749a72da5929c01774948e243db9ba41df4ff6"},
- {file = "virtualenv-20.26.5.tar.gz", hash = "sha256:ce489cac131aa58f4b25e321d6d186171f78e6cb13fafbf32a840cee67733ff4"},
+ {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"},
+ {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"},
]
[package.dependencies]
@@ -1431,4 +1431,4 @@
[metadata]
lock-version = "2.0"
python-versions = "^3.8"
-content-hash = "aac9123f3fa544b8c3e9b085f41f5a1c6c4ed2d59ce3236dcda6ea2aef5a694c"
+content-hash = "a4b9c3bababadba14f49a8de0ccee1f5a141b6cea23d02a19ab8bf4f8c45533f"
diff --git a/tools/tlc/pyproject.toml b/tools/tlc/pyproject.toml
index b606238..e9ff26f 100644
--- a/tools/tlc/pyproject.toml
+++ b/tools/tlc/pyproject.toml
@@ -39,7 +39,7 @@
click = "^8.1.7"
pyyaml = "^6.0.1"
tox = "^4.18.0"
-jinja2 = "^3.1.4"
+jinja2 = "^3.1.5"
[tool.poetry.group.dev]
optional = true
diff --git a/tools/tlc/tests/conftest.py b/tools/tlc/tests/conftest.py
index b8f88b5..93e44a9 100644
--- a/tools/tlc/tests/conftest.py
+++ b/tools/tlc/tests/conftest.py
@@ -9,6 +9,8 @@
""" Common configurations and fixtures for test environment."""
+from random import randint
+
import pytest
import yaml
from click.testing import CliRunner
@@ -16,6 +18,10 @@
from tlc.cli import cli
+def generate_random_bytes(n):
+ return bytes([randint(0, 255) for _ in range(n)])
+
+
@pytest.fixture
def tmptlstr(tmpdir):
return tmpdir.join("tl.bin").strpath
@@ -63,10 +69,27 @@
def tlcrunner(tmptlstr):
runner = CliRunner()
with runner.isolated_filesystem():
- runner.invoke(cli, ["create", tmptlstr])
+ runner.invoke(cli, ["create", "--size", 0x1F000, tmptlstr])
return runner
@pytest.fixture
def tlc_entries(tmpfdt):
return [(0, "/dev/null"), (1, tmpfdt.strpath), (0x102, tmpfdt.strpath)]
+
+
+@pytest.fixture
+def random_entry():
+ def _random_entry(max_size):
+ return randint(0, 0xFFFFFF), generate_random_bytes(randint(0, max_size))
+
+ return _random_entry
+
+
+@pytest.fixture
+def random_entries(random_entry):
+ def _random_entries(n=5, max_size=0x100):
+ for _ in range(n):
+ yield random_entry(max_size)
+
+ return _random_entries
diff --git a/tools/tlc/tests/test_cli.py b/tools/tlc/tests/test_cli.py
index a5ef30e..ebe1f6a 100644
--- a/tools/tlc/tests/test_cli.py
+++ b/tools/tlc/tests/test_cli.py
@@ -17,6 +17,7 @@
import pytest
import yaml
from click.testing import CliRunner
+from conftest import generate_random_bytes
from tlc.cli import cli
from tlc.te import TransferEntry
@@ -32,6 +33,22 @@
assert TransferList.fromfile(test_file) is not None
+@pytest.mark.parametrize("align", [4, 6, 12, 13])
+def test_create_with_align(align, tlcrunner, tmpdir):
+ tl_file = tmpdir.join("tl.bin").strpath
+ tlcrunner.invoke(cli, ["create", "-s", "10000", "-a", align, tl_file])
+
+ blob = tmpdir.join("blob.bin")
+
+ blob.write_binary(generate_random_bytes(0x200))
+ tlcrunner.invoke(cli, ["add", "--entry", 1, blob.strpath, tl_file])
+
+ tl = TransferList.fromfile(tl_file)
+ te = tl.entries[-1]
+ assert tl.alignment == align
+ assert (te.offset + te.hdr_size) % (1 << align) == 0
+
+
def test_create_with_fdt(tmpdir):
runner = CliRunner()
fdt = tmpdir.join("fdt.dtb")
@@ -69,6 +86,20 @@
assert len(tl.entries) == len(tlc_entries)
+@pytest.mark.parametrize("align", [4, 6, 12, 13])
+def test_cli_add_entry_with_align(align, tlcrunner, tmpdir, tmptlstr):
+ blob = tmpdir.join("blob.bin")
+ blob.write_binary(bytes(0x100))
+
+ tlcrunner.invoke(cli, ["add", "--align", align, "--entry", 1, blob, tmptlstr])
+ tl = TransferList.fromfile(tmptlstr)
+ te = tl.entries[-1]
+
+ print(tl, *(te for te in tl.entries), sep="\n---------------\n")
+ assert (te.offset + te.hdr_size) % (1 << align) == 0
+ assert tl.alignment == align
+
+
def test_info(tlcrunner, tmptlstr, tmpfdt):
tlcrunner.invoke(cli, ["add", "--entry", "0", "/dev/null", tmptlstr])
tlcrunner.invoke(cli, ["add", "--fdt", tmpfdt.strpath, tmptlstr])
diff --git a/tools/tlc/tests/test_transfer_list.py b/tools/tlc/tests/test_transfer_list.py
index e8c430e..6900b41 100644
--- a/tools/tlc/tests/test_transfer_list.py
+++ b/tools/tlc/tests/test_transfer_list.py
@@ -9,6 +9,7 @@
"""Contains unit tests for the types TransferEntry and TransferList."""
import math
+from random import randint
import pytest
@@ -49,15 +50,39 @@
assert tl.checksum == csum
-@pytest.mark.parametrize(("tag_id", "data"), test_entries)
-def test_add_transfer_entry(tag_id, data):
+def test_add_transfer_entry(random_entries):
tl = TransferList(0x1000)
- te = TransferEntry(tag_id, len(data), data)
- tl.add_transfer_entry(tag_id, data)
-
+ # Add a single entry and check it's in the list of entries
+ te = tl.add_transfer_entry(1, bytes(100))
assert te in tl.entries
- assert tl.size == TransferList.hdr_size + te.size
+ assert tl.size % 8 == 0
+
+ # Add a range of tag id's
+ for id, data in random_entries(50, 1):
+ te = tl.add_transfer_entry(id, data)
+ assert te in tl.entries
+ assert tl.size % 8 == 0
+
+
+@pytest.mark.parametrize("align", [4, 6, 12, 13])
+def test_add_transfer_entry_with_align(align, random_entries, random_entry):
+ tl = TransferList(0xF00000)
+ id, data = random_entry(4)
+
+ tl.add_transfer_entry(id, data)
+
+ # Add an entry with a larger alignment requirement
+ _, data = random_entry(4)
+ te = tl.add_transfer_entry(1, data, data_align=align)
+ assert (te.offset + te.hdr_size) % (1 << align) == 0
+ assert tl.alignment == align
+
+ # Add some more entries and ensure the alignment is preserved
+ for id, data in random_entries(5, 0x200):
+ te = tl.add_transfer_entry(id, data, data_align=align)
+ assert (te.offset + te.hdr_size) % (1 << align) == 0
+ assert tl.alignment == align
@pytest.mark.parametrize(
@@ -88,12 +113,19 @@
assert te.sum_of_bytes == csum
-@pytest.mark.parametrize(("tag_id", "data"), test_entries)
-def test_calculate_tl_checksum(tag_id, data):
+def test_calc_tl_checksum(tmpdir, random_entries):
+ tl_file = tmpdir.join("tl.bin")
+
tl = TransferList(0x1000)
- tl.add_transfer_entry(tag_id, data)
- assert tl.sum_of_bytes() == 0
+ for id, data in random_entries(10):
+ tl.add_transfer_entry(id, data)
+
+ assert sum(tl.to_bytes()) % 256 == 0
+
+ # Write the transfer list to a file and check that the sum of bytes is 0
+ tl.write_to_file(tl_file)
+ assert sum(tl_file.read_binary()) % 256 == 0
def test_empty_transfer_list_blob(tmpdir):
@@ -125,28 +157,44 @@
assert f.read(te.data_size) == te.data
-def test_multiple_te_transfer_list(tmpdir):
+def test_write_multiple_tes_to_file(tmpdir, random_entries, random_entry):
"""Check that we can create a TL with multiple TE's."""
test_file = tmpdir.join("test_tl_blob.bin")
- tl = TransferList(0x1000)
+ tl = TransferList(0x4000)
+ _test_entries = list(random_entries())
- for tag_id, data in test_entries:
+ for tag_id, data in _test_entries:
tl.add_transfer_entry(tag_id, data)
+ # Add a few entries with special alignment requirements
+ blob_id, blob = random_entry(0x200)
+ tl.add_transfer_entry(blob_id, blob, data_align=12)
+
tl.write_to_file(test_file)
with open(test_file, "rb") as f:
assert f.read(tl.hdr_size) == tl.header_to_bytes()
# Ensure that TE's have the correct alignment
- for tag_id, data in test_entries:
- f.seek(int(math.ceil(f.tell() / 2**tl.alignment) * 2**tl.alignment))
- print(f.tell())
+ for tag_id, data in _test_entries:
+ f.seek(int(math.ceil(f.tell() / 8) * 8))
+
assert int.from_bytes(f.read(3), "little") == tag_id
assert int.from_bytes(f.read(1), "little") == TransferEntry.hdr_size
# Make sure the data in the TE matches the data in the original case
data_size = int.from_bytes(f.read(4), "little")
assert f.read(data_size) == data
+ f.seek(int(math.ceil(f.tell() / (1 << 12)) * (1 << 12)) - 8)
+ assert int.from_bytes(f.read(3), "little") == blob_id
+ assert int.from_bytes(f.read(1), "little") == TransferEntry.hdr_size
+ # Make sure the data in the TE matches the data in the original case
+ data_size = int.from_bytes(f.read(4), "little")
+ assert f.read(data_size) == blob
+
+ # padding is added to align TE's, make sure padding is added to the size of
+ # the TL by checking we don't overflow.
+ assert f.tell() <= tl.size
+
def test_read_empty_transfer_list_from_file(tmpdir):
test_file = tmpdir.join("test_tl_blob.bin")
@@ -196,19 +244,17 @@
assert tl.sum_of_bytes() == 0
-@pytest.mark.parametrize("tag", [tag for tag, _ in test_entries])
-def test_remove_tag_from_file(tag):
- tl = TransferList(0x1000)
+def test_remove_tag(random_entry):
+ """Adds a transfer entry and remove it, size == transfer list header."""
+ tl = TransferList(0x100)
+ id, data = random_entry(tl.total_size // 2)
- for tag_id, data in test_entries:
- tl.add_transfer_entry(tag_id, data)
+ te = tl.add_transfer_entry(id, data)
+ assert te in tl.entries
- removed_entries = list(filter(lambda te: te.id == tag, tl.entries))
- original_size = tl.size
- tl.remove_tag(tag)
-
- assert not any(tag == te.id for te in tl.entries)
- assert tl.size == original_size - sum(map(lambda te: te.size, removed_entries))
+ tl.remove_tag(id)
+ assert not tl.get_entry(id) and te not in tl.entries
+ assert tl.size == tl.hdr_size
def test_get_fdt_offset(tmpdir):
diff --git a/tools/tlc/tlc/cli.py b/tools/tlc/tlc/cli.py
index 3d60938..431af04 100644
--- a/tools/tlc/tlc/cli.py
+++ b/tools/tlc/tlc/cli.py
@@ -27,6 +27,14 @@
@cli.command()
@click.argument("filename", type=click.Path(dir_okay=False))
@click.option(
+ "-a",
+ "--align",
+ type=int,
+ default=3,
+ show_default=True,
+ help="Set alignment in powers of 2 (e.g., -a 3 for 8 byte alignment).",
+)
+@click.option(
"-s", "--size", default=0x1000, type=int, help="Maximum size of the Transfer List"
)
@click.option(
@@ -51,7 +59,7 @@
type=click.Path(exists=True),
help="Create the transfer list from a YAML config file.",
)
-def create(filename, size, fdt, entry, flags, from_yaml):
+def create(filename, align, size, fdt, entry, flags, from_yaml):
"""Create a new Transfer List."""
try:
if from_yaml:
@@ -60,12 +68,12 @@
tl = TransferList.from_dict(config)
else:
- tl = TransferList(size)
+ tl = TransferList(size, flags=flags, alignment=align)
entry = (*entry, (1, fdt)) if fdt else entry
for id, path in entry:
- tl.add_transfer_entry_from_file(id, path)
+ tl.add_transfer_entry_from_file(id, path, data_align=align)
except MemoryError as mem_excp:
raise MemoryError(
"TL max size exceeded, consider increasing with the option -s"
@@ -133,19 +141,24 @@
@cli.command()
-@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@click.option(
+ "-a",
+ "--align",
+ type=int,
+ help="Set alignment in powers of 2 (e.g., -a 3 for 8 byte alignment).",
+)
@click.option(
"--entry",
type=(int, click.Path(exists=True)),
multiple=True,
help="A tag ID and the corresponding path to a binary blob in the form <id> <path-to-blob>.",
)
-def add(filename, entry):
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+def add(align, entry, filename):
"""Update an existing Transfer List with given images."""
tl = TransferList.fromfile(filename)
-
for id, path in entry:
- tl.add_transfer_entry_from_file(id, path)
+ tl.add_transfer_entry_from_file(id, path, data_align=align)
tl.write_to_file(filename)
diff --git a/tools/tlc/tlc/te.py b/tools/tlc/tlc/te.py
index cf7aa67..0b6b532 100644
--- a/tools/tlc/tlc/te.py
+++ b/tools/tlc/tlc/te.py
@@ -48,7 +48,10 @@
@property
def sum_of_bytes(self) -> int:
- return (sum(self.header_to_bytes()) + sum(self.data)) % 256
+ return sum(self.to_bytes()) % 256
+
+ def to_bytes(self) -> bytes:
+ return self.header_to_bytes() + self.data
def header_to_bytes(self) -> bytes:
return self.id.to_bytes(3, "little") + struct.pack(
diff --git a/tools/tlc/tlc/tl.py b/tools/tlc/tlc/tl.py
index 98d2205..dfbea9f 100644
--- a/tools/tlc/tlc/tl.py
+++ b/tools/tlc/tlc/tl.py
@@ -83,13 +83,17 @@
hdr_size = 0x18
signature = 0x4A0FB10B
version = 1
+ granule = 8
def __init__(
- self, max_size: int = hdr_size, flags: int = TRANSFER_LIST_ENABLE_CHECKSUM
+ self,
+ max_size: int = hdr_size,
+ flags: int = TRANSFER_LIST_ENABLE_CHECKSUM,
+ alignment: int = 3,
) -> None:
assert max_size >= self.hdr_size
self.checksum: int = 0
- self.alignment: int = 3
+ self.alignment: int = alignment
self.size = self.hdr_size
self.total_size = max_size
self.flags = flags
@@ -138,16 +142,15 @@
# the 3-byte wide ID as a 4-byte uint, shift out this padding
# once we have the id.
te_base = f.tell()
- (id, hdr_size, data_size) = struct.unpack(
+ (id, _, data_size) = struct.unpack(
TransferEntry.encoding[0] + "I" + TransferEntry.encoding[1:],
b"\x00" + f.read(TransferEntry.hdr_size),
)
id >>= 8
-
te = tl.add_transfer_entry(id, f.read(data_size))
te.offset = te_base
- f.seek(align(te_base + hdr_size + data_size, 2**tl.alignment))
+ f.seek(align(f.tell(), tl.granule))
return tl
@@ -163,10 +166,14 @@
# get settings from config and set defaults
max_size = config.get("max_size", 0x1000)
has_checksum = config.get("has_checksum", True)
+ align = config.get("alignment", None)
flags = TRANSFER_LIST_ENABLE_CHECKSUM if has_checksum else 0
- tl = cls(max_size, flags)
+ if align:
+ tl = cls(max_size, flags, alignment=align)
+ else:
+ tl = cls(max_size, flags)
for entry in config["entries"]:
tl.add_transfer_entry_from_dict(entry)
@@ -189,13 +196,15 @@
def update_checksum(self) -> None:
"""Calculates the checksum based on the sum of bytes."""
- self.checksum = 256 - ((self.sum_of_bytes() - self.checksum) % 256)
+ self.checksum = (256 - (self.sum_of_bytes() - self.checksum)) % 256
+ assert self.checksum <= 0xFF
+
+ def to_bytes(self) -> bytes:
+ return self.header_to_bytes() + b"".join([te.to_bytes() for te in self.entries])
def sum_of_bytes(self) -> int:
"""Sum of all bytes between the base address and the end of that last TE (modulo 0xff)."""
- return (
- sum(self.header_to_bytes()) + sum(te.sum_of_bytes for te in self.entries)
- ) % 256
+ return (sum(self.to_bytes())) % 256
def get_entry(self, tag_id: int) -> Optional[TransferEntry]:
for te in self.entries:
@@ -213,18 +222,35 @@
return te.offset + te.hdr_size
- def add_transfer_entry(self, tag_id: int, data: bytes) -> TransferEntry:
+ def add_transfer_entry(
+ self, tag_id: int, data: bytes, data_align: int = 0
+ ) -> TransferEntry:
"""Appends a TransferEntry into the internal list of TE's."""
+ data_offset = TransferEntry.hdr_size + self.size
+ data_align = self.alignment if not data_align else data_align
+
+ aligned_data_offset = align(data_offset, 1 << data_align)
+
+ if tag_id != 0 and data_offset != aligned_data_offset:
+ void_len = aligned_data_offset - data_offset - TransferEntry.hdr_size
+ self.add_transfer_entry(0, bytes(void_len))
+
+ assert align(self.size, self.granule)
+
if not (self.total_size >= self.size + TransferEntry.hdr_size + len(data)):
raise MemoryError(
f"TL size has exceeded the maximum allocation {self.total_size}."
)
- else:
- te = TransferEntry(tag_id, len(data), data)
- self.entries.append(te)
- self.size += te.size
- self.update_checksum()
- return te
+
+ te = TransferEntry(tag_id, len(data), data, offset=self.size)
+ self.entries.append(te)
+
+ self.size += align(te.size, self.granule)
+ if data_align > self.alignment:
+ self.alignment = data_align
+
+ self.update_checksum()
+ return te
def add_transfer_entry_from_struct_format(
self, tag_id: int, struct_format: str, *args: Any
@@ -305,32 +331,40 @@
tag_id = entry["tag_id"]
if tag_id in tag_name_to_tag_id:
tag_id = tag_name_to_tag_id[tag_id]
- te_format = transfer_entry_formats[tag_id]
- tag_name = te_format["tag_name"]
+
+ align = entry.get("alignment", None)
if "blob_file_path" in entry:
- return self.add_transfer_entry_from_file(tag_id, entry["blob_file_path"])
- elif tag_name == "tpm_event_log_table":
- with open(entry["event_log"], "rb") as f:
- event_log_data = f.read()
-
- flags_bytes = entry["flags"].to_bytes(4, "little")
- data = flags_bytes + event_log_data
-
- return self.add_transfer_entry(tag_id, data)
- elif tag_name == "exec_ep_info":
- return self.add_entry_point_info_transfer_entry(entry)
- elif "format" in te_format and "fields" in te_format:
- fields = [entry[field] for field in te_format["fields"]]
- return self.add_transfer_entry_from_struct_format(
- tag_id, te_format["format"], *fields
+ return self.add_transfer_entry_from_file(
+ tag_id, entry["blob_file_path"], data_align=align
)
else:
- raise ValueError(f"Invalid transfer entry {entry}.")
+ te_format = transfer_entry_formats[tag_id]
+ tag_name = te_format["tag_name"]
- def add_transfer_entry_from_file(self, tag_id: int, path: Path) -> TransferEntry:
+ if tag_name == "tpm_event_log_table":
+ with open(entry["event_log"], "rb") as f:
+ event_log_data = f.read()
+
+ flags_bytes = entry["flags"].to_bytes(4, "little")
+ data = flags_bytes + event_log_data
+
+ return self.add_transfer_entry(tag_id, data, data_align=align)
+ elif tag_name == "exec_ep_info":
+ return self.add_entry_point_info_transfer_entry(entry)
+ elif "format" in te_format and "fields" in te_format:
+ fields = [entry[field] for field in te_format["fields"]]
+ return self.add_transfer_entry_from_struct_format(
+ tag_id, te_format["format"], *fields
+ )
+ else:
+ raise ValueError(f"Invalid transfer entry {entry}.")
+
+ def add_transfer_entry_from_file(
+ self, tag_id: int, path: Path, data_align: int = 0
+ ) -> TransferEntry:
with open(path, "rb") as f:
- return self.add_transfer_entry(tag_id, f.read())
+ return self.add_transfer_entry(tag_id, f.read(), data_align=data_align)
def write_to_file(self, file: Path) -> None:
"""Write the contents of the TL to a file."""
@@ -338,20 +372,11 @@
f.write(self.header_to_bytes())
for te in self.entries:
assert f.tell() + te.hdr_size + te.data_size < self.total_size
- te_base = f.tell()
+
f.write(te.header_to_bytes())
f.write(te.data)
- # Ensure the next TE has the correct alignment
- f.write(
- bytes(
- (
- align(
- te_base + te.hdr_size + te.data_size, 2**self.alignment
- )
- - f.tell()
- )
- )
- )
+ # Ensure the next TE is at an 8-byte aligned address
+ f.write(bytes((align(f.tell(), self.granule) - f.tell())))
def remove_tag(self, tag: int) -> None:
self.entries = list(filter(lambda te: te.id != tag, self.entries))