Merge "fix(spmd): relax use of EHF with SPMC at S-EL2" into integration
diff --git a/.versionrc.js b/.versionrc.js
index 4e9c71f..3a21ded 100644
--- a/.versionrc.js
+++ b/.versionrc.js
@@ -101,6 +101,25 @@
"type": "json"
},
{
+ "filename": "docs/conf.py",
+ "updater": {
+ "readVersion": function (contents) {
+ const _ver = contents.match(/version\s=.*"(\d)\.(\d)\.(\d)/);
+
+ return `${_ver[1]}.${_ver[2]}.${_ver[2]}`;
+ },
+
+ "writeVersion": function (contents, version) {
+ const _ver = 'version = "' + version + '"'
+ const _rel = 'release = "' + version + '"'
+
+ contents = contents.replace(/^(version\s=\s")((\d).?)*$/m, _ver)
+ contents = contents.replace(/^(release\s=\s")((\d).?)*$/m, _rel)
+ return contents
+ }
+ },
+ },
+ {
"filename": "tools/conventional-changelog-tf-a/package.json",
"type": "json"
},
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index a2527e6..49dda85 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -41,6 +41,7 @@
*bl1_entrypoint.o(.text*)
*(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
+ __TEXT_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
@@ -72,6 +73,7 @@
* aligned and lld does not align the LMA to the alignment specified
* on the .data section.
*/
+ __RODATA_END_UNALIGNED__ = .;
__RODATA_END__ = .;
. = ALIGN(16);
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index 5f689d5..db83a0c 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -35,6 +35,7 @@
*(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
+ __TEXT_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
@@ -57,6 +58,7 @@
RODATA_COMMON
+ __RODATA_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
__RODATA_END__ = .;
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 5da631c..4aa5cb0 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -65,6 +65,7 @@
*(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
+ __TEXT_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
@@ -78,6 +79,7 @@
RODATA_COMMON
+ __RODATA_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
__RODATA_END__ = .;
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index 21c91b4..7b1a101 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -32,6 +32,7 @@
*bl2u_entrypoint.o(.text*)
*(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
+ __TEXT_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
@@ -53,6 +54,7 @@
RODATA_COMMON
+ __RODATA_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
__RODATA_END__ = .;
} >RAM
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index abcae0c..7a8c41a 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -42,6 +42,7 @@
*bl31_entrypoint.o(.text*)
*(SORT_BY_ALIGNMENT(SORT(.text*)))
*(.vectors)
+ __TEXT_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
@@ -62,6 +63,7 @@
. = ALIGN(8);
# include <lib/el3_runtime/pubsub_events.h>
+ __RODATA_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 0a2bad0..dd81973 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -34,6 +34,7 @@
*entrypoint.o(.text*)
*(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
+ __TEXT_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
@@ -58,6 +59,7 @@
. = ALIGN(8);
# include <lib/el3_runtime/pubsub_events.h>
+ __RODATA_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S
index b735f45..22bf11d 100644
--- a/bl32/tsp/tsp.ld.S
+++ b/bl32/tsp/tsp.ld.S
@@ -30,6 +30,7 @@
*tsp_entrypoint.o(.text*)
*(.text*)
*(.vectors)
+ __TEXT_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
@@ -43,6 +44,7 @@
RODATA_COMMON
+ __RODATA_END_UNALIGNED__ = .;
. = ALIGN(PAGE_SIZE);
__RODATA_END__ = .;
diff --git a/docs/conf.py b/docs/conf.py
index 371632a..345f53b 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2023, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -9,27 +9,34 @@
#
# See the options documentation at http://www.sphinx-doc.org/en/master/config
-import os
# -- Project information -----------------------------------------------------
-project = 'Trusted Firmware-A'
+project = "Trusted Firmware-A"
+author = "Trusted Firmware-A contributors"
+version = "2.9.0"
+release = "2.9.0"
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
-extensions = ['myst_parser', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.plantuml']
+extensions = [
+ "myst_parser",
+ "sphinx.ext.autosectionlabel",
+ "sphinxcontrib.plantuml",
+ "sphinxcontrib.inkscapeconverter",
+]
# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
# The suffix(es) of source filenames.
-source_suffix = ['.md', '.rst']
+source_suffix = [".md", ".rst"]
# The master toctree document.
-master_doc = 'index'
+master_doc = "index"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -45,15 +52,16 @@
exclude_patterns = [".env", "env", ".venv", "venv"]
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
# Load the contents of the global substitutions file into the 'rst_prolog'
-# variable. This ensures that the substitutions are all inserted into each page.
-with open('global_substitutions.txt', 'r') as subs:
- rst_prolog = subs.read()
+# variable. This ensures that the substitutions are all inserted into each
+# page.
+with open("global_substitutions.txt", "r") as subs:
+ rst_prolog = subs.read()
# Minimum version of sphinx required
-needs_sphinx = '2.0'
+needs_sphinx = "2.0"
# -- Options for HTML output -------------------------------------------------
@@ -68,21 +76,21 @@
html_theme = "sphinx_rtd_theme"
# The logo to display in the sidebar
-html_logo = 'resources/TrustedFirmware-Logo_standard-white.png'
+html_logo = "resources/TrustedFirmware-Logo_standard-white.png"
# Options for the "sphinx-rtd-theme" theme
html_theme_options = {
- 'collapse_navigation': False, # Can expand and collapse sidebar entries
- 'prev_next_buttons_location': 'both', # Top and bottom of the page
- 'style_external_links': True # Display an icon next to external links
+ "collapse_navigation": False, # Can expand and collapse sidebar entries
+ "prev_next_buttons_location": "both", # Top and bottom of the page
+ "style_external_links": True, # Display an icon next to external links
}
# Path to _static directory
-html_static_path = ['_static']
+html_static_path = ["_static"]
# Path to css file relative to html_static_path
html_css_files = [
- 'css/custom.css',
+ "css/custom.css",
]
# -- Options for autosectionlabel --------------------------------------------
@@ -92,4 +100,12 @@
# -- Options for plantuml ----------------------------------------------------
+plantuml_output_format = "svg_img"
+
-plantuml_output_format = 'svg_img'
+# -- Options for latexmk ----------------------------------------------------
+
+latex_engine = "xelatex"
+latex_elements = {
+ "maxlistdepth": "10",
+ "pointsize": "11pt",
+}
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 998824f..50839bd 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -1559,8 +1559,10 @@
- ``__RO_START__``
- ``__RO_END__``
- ``__TEXT_START__``
+- ``__TEXT_END_UNALIGNED__``
- ``__TEXT_END__``
- ``__RODATA_START__``
+- ``__RODATA_END_UNALIGNED__``
- ``__RODATA_END__``
BL1's linker symbols
diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst
index 7f73d7e..7f9519e 100644
--- a/docs/design_documents/measured_boot_poc.rst
+++ b/docs/design_documents/measured_boot_poc.rst
@@ -5,10 +5,10 @@
critical data used at boot time, for example using a TPM, so that the
security state can be attested later.
-The current implementation of the driver included in Trusted Firmware-A
-(TF-A) stores the measurements into a `TCG event log`_ in secure
-memory. No other means of recording measurements (such as a discrete TPM) is
-supported right now.
+The current implementation of the driver included in |TF-A| supports several
+backends and each has a different means to store the measurements.
+This section focuses on the `TCG event log`_ backend, which stores measurements
+in secure memory.
The driver also provides mechanisms to pass the Event Log to normal world if
needed.
diff --git a/docs/design_documents/psci_osi_mode.rst b/docs/design_documents/psci_osi_mode.rst
index 3296e27..a6e1bdf 100644
--- a/docs/design_documents/psci_osi_mode.rst
+++ b/docs/design_documents/psci_osi_mode.rst
@@ -4,7 +4,7 @@
:Author: Maulik Shah & Wing Li
:Organization: Qualcomm Innovation Center, Inc. & Google LLC
:Contact: Maulik Shah <quic_mkshah@quicinc.com> & Wing Li <wingers@google.com>
-:Status: RFC
+:Status: Accepted
.. contents:: Table of Contents
@@ -367,9 +367,11 @@
``psci_validate_state_coordination``. If validation fails, propagate the
error up the call stack.
-* Update the return type of the platform specific ``pwr_domain_suspend``
- handler from ``void`` to ``int``, to allow the platform to optionally perform
- validations based on hardware states.
+* Add a new optional member ``pwr_domain_validate_suspend`` to
+ ``plat_psci_ops_t`` to allow the platform to optionally perform validations
+ based on hardware states.
+
+* The platform specific ``pwr_domain_suspend`` handler remains unchanged.
.. image:: ../resources/diagrams/psci-osi-mode.png
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 1250071..8182f91 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2818,6 +2818,17 @@
for the higher power domain levels depending on the result of state
coordination. The generic code expects the handler to succeed.
+plat_psci_ops.pwr_domain_validate_suspend() [optional]
+......................................................
+
+This is an optional function that is only compiled into the build if the build
+option ``PSCI_OS_INIT_MODE`` is enabled.
+
+If implemented, this function allows the platform to perform platform specific
+validations based on hardware states. The generic code expects this function to
+return PSCI_E_SUCCESS on success, or either PSCI_E_DENIED or
+PSCI_E_INVALID_PARAMS as appropriate for any invalid requests.
+
plat_psci_ops.pwr_domain_suspend_pwrdown_early() [optional]
...........................................................
@@ -2876,10 +2887,6 @@
data, for example in DRAM. The Distributor can then be powered down using an
implementation-defined sequence.
-If the build option ``PSCI_OS_INIT_MODE`` is enabled, the generic code expects
-the platform to return PSCI_E_SUCCESS on success, or either PSCI_E_DENIED or
-PSCI_E_INVALID_PARAMS as appropriate for any invalid requests.
-
plat_psci_ops.pwr_domain_pwr_down_wfi()
.......................................
diff --git a/docs/resources/diagrams/psci-osi-mode.png b/docs/resources/diagrams/psci-osi-mode.png
index d322953..09175e5 100644
--- a/docs/resources/diagrams/psci-osi-mode.png
+++ b/docs/resources/diagrams/psci-osi-mode.png
Binary files differ
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index 4d7e58e..01dc3cb 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -319,13 +319,13 @@
int (*pwr_domain_on)(u_register_t mpidr);
void (*pwr_domain_off)(const psci_power_state_t *target_state);
int (*pwr_domain_off_early)(const psci_power_state_t *target_state);
+#if PSCI_OS_INIT_MODE
+ int (*pwr_domain_validate_suspend)(
+ const psci_power_state_t *target_state);
+#endif
void (*pwr_domain_suspend_pwrdown_early)(
const psci_power_state_t *target_state);
-#if PSCI_OS_INIT_MODE
- int (*pwr_domain_suspend)(const psci_power_state_t *target_state);
-#else
void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
-#endif
void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
void (*pwr_domain_on_finish_late)(
const psci_power_state_t *target_state);
diff --git a/include/services/el3_spmc_logical_sp.h b/include/services/el3_spmc_logical_sp.h
index 5ce33ed..dccd362 100644
--- a/include/services/el3_spmc_logical_sp.h
+++ b/include/services/el3_spmc_logical_sp.h
@@ -49,8 +49,7 @@
* Function & variable prototypes.
******************************************************************************/
int el3_sp_desc_validate(void);
-uintptr_t handle_el3_sp(uint32_t smc_fid, void *cookie, void *handle,
- unsigned int flags);
+
IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_START__, EL3_LP_DESCS_START);
IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_END__, EL3_LP_DESCS_END);
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index c893476..bfc09cc 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -451,8 +451,8 @@
* enter. This function will be called after coordination of requested power
* states has been done for each power level.
*****************************************************************************/
-static void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
- const psci_power_state_t *target_state)
+void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
+ const psci_power_state_t *target_state)
{
unsigned int parent_idx, lvl;
const plat_local_state_t *pd_state = target_state->pwr_domain_state;
@@ -474,7 +474,6 @@
}
}
-
/*******************************************************************************
* PSCI helper function to get the parent nodes corresponding to a cpu_index.
******************************************************************************/
@@ -595,9 +594,6 @@
state_info->pwr_domain_state[lvl] = PSCI_LOCAL_STATE_RUN;
}
-
- /* Update the target state in the power domain nodes */
- psci_set_target_local_pwr_states(end_pwrlvl, state_info);
}
#if PSCI_OS_INIT_MODE
@@ -684,9 +680,6 @@
return rc;
}
- /* Update the target state in the power domain nodes */
- psci_set_target_local_pwr_states(end_pwrlvl, state_info);
-
return rc;
}
#endif
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index 9f36ac7..f83753f 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -104,6 +104,9 @@
*/
psci_do_state_coordination(end_pwrlvl, &state_info);
+ /* Update the target state in the power domain nodes */
+ psci_set_target_local_pwr_states(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);
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index b9987fe..04f93bd 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -298,6 +298,8 @@
#endif
void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
psci_power_state_t *target_state);
+void psci_set_target_local_pwr_states(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,
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index 861b875..d93e60d 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -219,6 +219,19 @@
}
#endif
+#if PSCI_OS_INIT_MODE
+ if (psci_plat_pm_ops->pwr_domain_validate_suspend != NULL) {
+ rc = psci_plat_pm_ops->pwr_domain_validate_suspend(state_info);
+ if (rc != PSCI_E_SUCCESS) {
+ skip_wfi = true;
+ goto exit;
+ }
+ }
+#endif
+
+ /* Update the target state in the power domain nodes */
+ psci_set_target_local_pwr_states(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);
@@ -234,15 +247,7 @@
* program the power controller etc.
*/
-#if PSCI_OS_INIT_MODE
- rc = psci_plat_pm_ops->pwr_domain_suspend(state_info);
- if (rc != PSCI_E_SUCCESS) {
- skip_wfi = true;
- goto exit;
- }
-#else
psci_plat_pm_ops->pwr_domain_suspend(state_info);
-#endif
#if ENABLE_PSCI_STAT
plat_psci_stat_accounting_start(state_info);
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index a3289b6..b8c97f8 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -228,11 +228,7 @@
* FVP handler called when a power domain is about to be suspended. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
-#if PSCI_OS_INIT_MODE
-static int fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
-#else
static void fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
-#endif
{
unsigned long mpidr;
@@ -242,11 +238,7 @@
*/
if (target_state->pwr_domain_state[ARM_PWR_LVL0] ==
ARM_LOCAL_STATE_RET)
-#if PSCI_OS_INIT_MODE
- return PSCI_E_SUCCESS;
-#else
return;
-#endif
assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
ARM_LOCAL_STATE_OFF);
@@ -279,11 +271,7 @@
/* Program the power controller to power off this cpu. */
fvp_pwrc_write_ppoffr(read_mpidr_el1());
-#if PSCI_OS_INIT_MODE
- return PSCI_E_SUCCESS;
-#else
return;
-#endif
}
/*******************************************************************************
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
index 1405ca6..487a56e 100644
--- a/plat/qti/common/src/qti_pm.c
+++ b/plat/qti/common/src/qti_pm.c
@@ -191,18 +191,6 @@
}
}
-#if PSCI_OS_INIT_MODE
-static int qti_node_suspend(const psci_power_state_t *target_state)
-{
- qtiseclib_psci_node_suspend((const uint8_t *)target_state->
- pwr_domain_state);
- if (is_cpu_off(target_state)) {
- plat_qti_gic_cpuif_disable();
- qti_set_cpupwrctlr_val();
- }
- return PSCI_E_SUCCESS;
-}
-#else
static void qti_node_suspend(const psci_power_state_t *target_state)
{
qtiseclib_psci_node_suspend((const uint8_t *)target_state->
@@ -212,7 +200,6 @@
qti_set_cpupwrctlr_val();
}
}
-#endif
static void qti_node_suspend_finish(const psci_power_state_t *target_state)
{
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 81a5445..af5263d 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -121,6 +121,48 @@
case 57:
dev_idx = XPM_NODEIDX_DEV_GEM_0;
break;
+ case 58:
+ case 59:
+ dev_idx = XPM_NODEIDX_DEV_GEM_1;
+ break;
+ case 60:
+ dev_idx = XPM_NODEIDX_DEV_ADMA_0;
+ break;
+ case 61:
+ dev_idx = XPM_NODEIDX_DEV_ADMA_1;
+ break;
+ case 62:
+ dev_idx = XPM_NODEIDX_DEV_ADMA_2;
+ break;
+ case 63:
+ dev_idx = XPM_NODEIDX_DEV_ADMA_3;
+ break;
+ case 64:
+ dev_idx = XPM_NODEIDX_DEV_ADMA_4;
+ break;
+ case 65:
+ dev_idx = XPM_NODEIDX_DEV_ADMA_5;
+ break;
+ case 66:
+ dev_idx = XPM_NODEIDX_DEV_ADMA_6;
+ break;
+ case 67:
+ dev_idx = XPM_NODEIDX_DEV_ADMA_7;
+ break;
+ case 74:
+ dev_idx = XPM_NODEIDX_DEV_USB_0;
+ break;
+ case 126:
+ case 127:
+ dev_idx = XPM_NODEIDX_DEV_SDIO_0;
+ break;
+ case 128:
+ case 129:
+ dev_idx = XPM_NODEIDX_DEV_SDIO_1;
+ break;
+ case 142:
+ dev_idx = XPM_NODEIDX_DEV_RTC;
+ break;
default:
dev_idx = XPM_NODEIDX_DEV_MIN;
break;
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 6cadaab..b00513e 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -212,7 +212,7 @@
/* Reserve memory used by Trusted Firmware. */
if (fdt_add_reserved_memory(dtb, "tf-a", BL31_BASE,
- BL31_LIMIT - BL31_BASE + 1)) {
+ (size_t) (BL31_LIMIT - BL31_BASE))) {
WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
}
diff --git a/poetry.lock b/poetry.lock
index 92b38da..07cd572 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,10 +1,9 @@
-# This file is automatically @generated by Poetry and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.5.0 and should not be changed by hand.
[[package]]
name = "alabaster"
version = "0.7.13"
description = "A configurable sidebar-enabled Sphinx theme"
-category = "dev"
optional = false
python-versions = ">=3.6"
files = [
@@ -16,7 +15,6 @@
name = "anytree"
version = "2.8.0"
description = "Powerful and Lightweight Python Tree Data Structure.."
-category = "dev"
optional = false
python-versions = "*"
files = [
@@ -35,7 +33,6 @@
name = "babel"
version = "2.12.1"
description = "Internationalization utilities"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -50,7 +47,6 @@
name = "build"
version = "0.10.0"
description = "A simple, correct Python build frontend"
-category = "dev"
optional = false
python-versions = ">= 3.7"
files = [
@@ -74,7 +70,6 @@
name = "certifi"
version = "2022.12.7"
description = "Python package for providing Mozilla's CA Bundle."
-category = "dev"
optional = false
python-versions = ">=3.6"
files = [
@@ -86,7 +81,6 @@
name = "charset-normalizer"
version = "3.1.0"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-category = "dev"
optional = false
python-versions = ">=3.7.0"
files = [
@@ -171,7 +165,6 @@
name = "click"
version = "8.1.3"
description = "Composable command line interface toolkit"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -186,7 +179,6 @@
name = "colorama"
version = "0.4.6"
description = "Cross-platform colored terminal text."
-category = "dev"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [
@@ -198,7 +190,6 @@
name = "docutils"
version = "0.18.1"
description = "Docutils -- Python Documentation Utilities"
-category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
files = [
@@ -210,7 +201,6 @@
name = "idna"
version = "3.4"
description = "Internationalized Domain Names in Applications (IDNA)"
-category = "dev"
optional = false
python-versions = ">=3.5"
files = [
@@ -222,7 +212,6 @@
name = "imagesize"
version = "1.4.1"
description = "Getting image size from png/jpeg/jpeg2000/gif file"
-category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = [
@@ -234,7 +223,6 @@
name = "importlib-metadata"
version = "6.6.0"
description = "Read metadata from Python packages"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -254,7 +242,6 @@
name = "jinja2"
version = "3.1.2"
description = "A very fast and expressive template engine."
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -272,7 +259,6 @@
name = "markdown-it-py"
version = "2.2.0"
description = "Python port of markdown-it. Markdown parsing, done right!"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -297,7 +283,6 @@
name = "markupsafe"
version = "2.1.2"
description = "Safely add untrusted strings to HTML/XML markup."
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -357,7 +342,6 @@
name = "mdit-py-plugins"
version = "0.3.5"
description = "Collection of plugins for markdown-it-py"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -377,7 +361,6 @@
name = "mdurl"
version = "0.1.2"
description = "Markdown URL utilities"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -389,7 +372,6 @@
name = "myst-parser"
version = "0.18.1"
description = "An extended commonmark compliant parser, with bridges to docutils & sphinx."
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -416,7 +398,6 @@
name = "packaging"
version = "23.1"
description = "Core utilities for Python packages"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -428,7 +409,6 @@
name = "pip"
version = "23.1.2"
description = "The PyPA recommended tool for installing Python packages."
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -440,7 +420,6 @@
name = "pip-tools"
version = "6.13.0"
description = "pip-tools keeps your pinned dependencies fresh."
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -463,7 +442,6 @@
name = "prettytable"
version = "3.7.0"
description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -481,7 +459,6 @@
name = "pyelftools"
version = "0.29"
description = "Library for analyzing ELF files and DWARF debugging information"
-category = "dev"
optional = false
python-versions = "*"
files = [
@@ -493,7 +470,6 @@
name = "pygments"
version = "2.15.1"
description = "Pygments is a syntax highlighting package written in Python."
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -508,7 +484,6 @@
name = "pyproject-hooks"
version = "1.0.0"
description = "Wrappers to call pyproject.toml-based build backend hooks."
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -523,7 +498,6 @@
name = "pytz"
version = "2023.3"
description = "World timezone definitions, modern and historical"
-category = "dev"
optional = false
python-versions = "*"
files = [
@@ -535,7 +509,6 @@
name = "pyyaml"
version = "6.0"
description = "YAML parser and emitter for Python"
-category = "dev"
optional = false
python-versions = ">=3.6"
files = [
@@ -585,7 +558,6 @@
name = "requests"
version = "2.30.0"
description = "Python HTTP for Humans."
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -607,7 +579,6 @@
name = "setuptools"
version = "67.7.2"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -624,7 +595,6 @@
name = "six"
version = "1.16.0"
description = "Python 2 and 3 compatibility utilities"
-category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
files = [
@@ -636,7 +606,6 @@
name = "snowballstemmer"
version = "2.2.0"
description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
-category = "dev"
optional = false
python-versions = "*"
files = [
@@ -648,7 +617,6 @@
name = "sphinx"
version = "5.3.0"
description = "Python documentation generator"
-category = "dev"
optional = false
python-versions = ">=3.6"
files = [
@@ -684,7 +652,6 @@
name = "sphinx-rtd-theme"
version = "1.2.0"
description = "Read the Docs theme for Sphinx"
-category = "dev"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
files = [
@@ -704,7 +671,6 @@
name = "sphinxcontrib-applehelp"
version = "1.0.4"
description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
-category = "dev"
optional = false
python-versions = ">=3.8"
files = [
@@ -720,7 +686,6 @@
name = "sphinxcontrib-devhelp"
version = "1.0.2"
description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
-category = "dev"
optional = false
python-versions = ">=3.5"
files = [
@@ -736,7 +701,6 @@
name = "sphinxcontrib-htmlhelp"
version = "2.0.1"
description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
-category = "dev"
optional = false
python-versions = ">=3.8"
files = [
@@ -752,7 +716,6 @@
name = "sphinxcontrib-jquery"
version = "4.1"
description = "Extension to include jQuery on newer Sphinx releases"
-category = "dev"
optional = false
python-versions = ">=2.7"
files = [
@@ -767,7 +730,6 @@
name = "sphinxcontrib-jsmath"
version = "1.0.1"
description = "A sphinx extension which renders display math in HTML via JavaScript"
-category = "dev"
optional = false
python-versions = ">=3.5"
files = [
@@ -782,7 +744,6 @@
name = "sphinxcontrib-plantuml"
version = "0.24.1"
description = "Sphinx \"plantuml\" extension"
-category = "dev"
optional = false
python-versions = "*"
files = [
@@ -799,7 +760,6 @@
name = "sphinxcontrib-qthelp"
version = "1.0.3"
description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
-category = "dev"
optional = false
python-versions = ">=3.5"
files = [
@@ -815,7 +775,6 @@
name = "sphinxcontrib-serializinghtml"
version = "1.1.5"
description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
-category = "dev"
optional = false
python-versions = ">=3.5"
files = [
@@ -828,10 +787,26 @@
test = ["pytest"]
[[package]]
+name = "sphinxcontrib-svg2pdfconverter"
+version = "1.2.2"
+description = "Sphinx SVG to PDF converter extension"
+optional = false
+python-versions = "~=3.4"
+files = [
+ {file = "sphinxcontrib-svg2pdfconverter-1.2.2.tar.gz", hash = "sha256:80a55ca61f70eae93efc65f3814f2f177c86ba55934a9f6c5022f1778b62146b"},
+ {file = "sphinxcontrib_svg2pdfconverter-1.2.2-py3-none-any.whl", hash = "sha256:04ec767b55780a6b18d89cc1a8ada6d900c6efde9d1683abdb98a49b144465ca"},
+]
+
+[package.dependencies]
+Sphinx = ">=1.6.3"
+
+[package.extras]
+cairosvg = ["cairosvg (>=1.0)"]
+
+[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -843,7 +818,6 @@
name = "typing-extensions"
version = "4.5.0"
description = "Backported and Experimental Type Hints for Python 3.7+"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -855,7 +829,6 @@
name = "urllib3"
version = "2.0.2"
description = "HTTP library with thread-safe connection pooling, file post, and more."
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -873,7 +846,6 @@
name = "wcwidth"
version = "0.2.6"
description = "Measures the displayed width of unicode strings in a terminal"
-category = "dev"
optional = false
python-versions = "*"
files = [
@@ -885,7 +857,6 @@
name = "wheel"
version = "0.40.0"
description = "A built-package format for Python"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -900,7 +871,6 @@
name = "zipp"
version = "3.15.0"
description = "Backport of pathlib-compatible object wrapper for zip files"
-category = "dev"
optional = false
python-versions = ">=3.7"
files = [
@@ -915,4 +885,4 @@
[metadata]
lock-version = "2.0"
python-versions = "^3.8"
-content-hash = "9c25ef33612d10c7caafa551a3cf6a12753167c6400f49cc261fddd18c7eaf6e"
+content-hash = "62d9ce9ca1c9f4669c7b40724acfc93968cde31c0460d1d7515d289739dc9464"
diff --git a/pyproject.toml b/pyproject.toml
index 44e78d3..19ba4d8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -21,6 +21,7 @@
sphinxcontrib-plantuml = "^0.24.1"
sphinx-rtd-theme = "^1.1.1"
pip-tools = "^6.4.0"
+sphinxcontrib-svg2pdfconverter = "^1.2.2"
[tool.poetry.group.ci.dependencies]
click = "^8.1.3"
diff --git a/tools/memory/memory/buildparser.py b/tools/memory/memory/buildparser.py
index c128c36..dedff79 100755
--- a/tools/memory/memory/buildparser.py
+++ b/tools/memory/memory/buildparser.py
@@ -8,14 +8,16 @@
from pathlib import Path
from memory.elfparser import TfaElfParser
+from memory.mapparser import TfaMapParser
class TfaBuildParser:
"""A class for performing analysis on the memory layout of a TF-A build."""
- def __init__(self, path: Path):
+ def __init__(self, path: Path, map_backend=False):
self._modules = dict()
self._path = path
+ self.map_backend = map_backend
self._parse_modules()
def __getitem__(self, module: str):
@@ -23,15 +25,24 @@
return self._modules[module]
def _parse_modules(self):
- """Parse ELF files in the build path."""
- for elf_file in self._path.glob("**/*.elf"):
- module_name = elf_file.name.split("/")[-1].split(".")[0]
- with open(elf_file, "rb") as file:
- self._modules[module_name] = TfaElfParser(file)
+ """Parse the build files using the selected backend."""
+ backend = TfaElfParser
+ files = list(self._path.glob("**/*.elf"))
+ io_perms = "rb"
+
+ if self.map_backend or len(files) == 0:
+ backend = TfaMapParser
+ files = self._path.glob("**/*.map")
+ io_perms = "r"
+
+ for file in files:
+ module_name = file.name.split("/")[-1].split(".")[0]
+ with open(file, io_perms) as f:
+ self._modules[module_name] = backend(f)
if not len(self._modules):
raise FileNotFoundError(
- f"failed to find ELF files in path {self._path}!"
+ f"failed to find files to analyse in path {self._path}!"
)
@property
@@ -54,7 +65,7 @@
"""Returns map of memory usage per memory type for each module."""
mem_map = {}
for k, v in self._modules.items():
- mod_mem_map = v.get_elf_memory_layout()
+ mod_mem_map = v.get_memory_layout()
if len(mod_mem_map):
mem_map[k] = mod_mem_map
return mem_map
diff --git a/tools/memory/memory/elfparser.py b/tools/memory/memory/elfparser.py
index 1bd68b1..2dd2513 100644
--- a/tools/memory/memory/elfparser.py
+++ b/tools/memory/memory/elfparser.py
@@ -131,7 +131,7 @@
"""Get a dictionary of segments and their section mappings."""
return [asdict(v) for k, v in self._segments.items()]
- def get_elf_memory_layout(self):
+ def get_memory_layout(self):
"""Get the total memory consumed by this module from the memory
configuration.
{"rom": {"start": 0x0, "end": 0xFF, "length": ... }
diff --git a/tools/memory/memory/mapparser.py b/tools/memory/memory/mapparser.py
new file mode 100644
index 0000000..b1a4b4c
--- /dev/null
+++ b/tools/memory/memory/mapparser.py
@@ -0,0 +1,75 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+from re import match, search
+from typing import TextIO
+
+
+class TfaMapParser:
+ """A class representing a map file built for TF-A.
+
+ Provides a basic interface for reading the symbol table. The constructor
+ accepts a file-like object with the contents a Map file. Only GNU map files
+ are supported at this stage.
+ """
+
+ def __init__(self, map_file: TextIO):
+ self._symbols = self.read_symbols(map_file)
+
+ @property
+ def symbols(self):
+ return self._symbols.items()
+
+ @staticmethod
+ def read_symbols(file: TextIO, pattern: str = None) -> dict:
+ pattern = r"\b(0x\w*)\s*(\w*)\s=" if not pattern else pattern
+ symbols = {}
+
+ for line in file.readlines():
+ match = search(pattern, line)
+
+ if match is not None:
+ value, name = match.groups()
+ symbols[name] = int(value, 16)
+
+ return symbols
+
+ def get_memory_layout(self) -> dict:
+ """Get the total memory consumed by this module from the memory
+ configuration.
+ {"rom": {"start": 0x0, "end": 0xFF, "length": ... }
+ """
+ assert len(self._symbols), "Symbol table is empty!"
+ expr = r".*(.?R.M)_REGION.*(START|END|LENGTH)"
+ memory_layout = {}
+
+ region_symbols = filter(lambda s: match(expr, s), self._symbols)
+
+ for symbol in region_symbols:
+ region, _, attr = tuple(symbol.lower().strip("__").split("_"))
+ if region not in memory_layout:
+ memory_layout[region] = {}
+
+ memory_layout[region][attr] = self._symbols[symbol]
+
+ if "start" and "length" and "end" in memory_layout[region]:
+ memory_layout[region]["limit"] = (
+ memory_layout[region]["end"]
+ + memory_layout[region]["length"]
+ )
+ memory_layout[region]["free"] = (
+ memory_layout[region]["limit"]
+ - memory_layout[region]["end"]
+ )
+ memory_layout[region]["total"] = memory_layout[region][
+ "length"
+ ]
+ memory_layout[region]["size"] = (
+ memory_layout[region]["end"]
+ - memory_layout[region]["start"]
+ )
+
+ return memory_layout
diff --git a/tools/memory/memory/memmap.py b/tools/memory/memory/memmap.py
index 6d6f39d..99149b5 100755
--- a/tools/memory/memory/memmap.py
+++ b/tools/memory/memory/memmap.py
@@ -66,6 +66,11 @@
default=False,
help="Display numbers in decimal base.",
)
+@click.option(
+ "--no-elf-images",
+ is_flag=True,
+ help="Analyse the build's map files instead of ELF images.",
+)
def main(
root: Path,
platform: str,
@@ -76,11 +81,12 @@
depth: int,
width: int,
d: bool,
+ no_elf_images: bool,
):
build_path = root if root else Path("build/", platform, build_type)
click.echo(f"build-path: {build_path.resolve()}")
- parser = TfaBuildParser(build_path)
+ parser = TfaBuildParser(build_path, map_backend=no_elf_images)
printer = TfaPrettyPrinter(columns=width, as_decimal=d)
if footprint or not (tree or symbols):
@@ -94,7 +100,7 @@
if symbols:
expr = (
r"(.*)(TEXT|BSS|RODATA|STACKS|_OPS|PMF|XLAT|GOT|FCONF"
- r"|R.M)(.*)(START|END)__$"
+ r"|R.M)(.*)(START|UNALIGNED|END)__$"
)
printer.print_symbol_table(
parser.filter_symbols(parser.symbols, expr), parser.module_names
diff --git a/tools/memory/memory/printer.py b/tools/memory/memory/printer.py
index 6bc6bff..4b18560 100755
--- a/tools/memory/memory/printer.py
+++ b/tools/memory/memory/printer.py
@@ -95,13 +95,16 @@
self,
symbols: list,
modules: list,
- start: int = 11,
+ start: int = 12,
):
assert len(symbols), "Empty symbol list!"
modules = sorted(modules)
col_width = int((self.term_size - start) / len(modules))
+ address_fixed_width = 11
- num_fmt = "0=#010x" if not self.as_decimal else ">10"
+ num_fmt = (
+ f"0=#0{address_fixed_width}x" if not self.as_decimal else ">10"
+ )
_symbol_map = [
" " * start