1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include <stdbool.h>
- #include <common/debug.h>
- #include <lib/mpmm/mpmm.h>
- #include <plat/common/platform.h>
- #if ENABLE_MPMM_FCONF
- # include <lib/fconf/fconf.h>
- # include <lib/fconf/fconf_mpmm_getter.h>
- #endif
- static uint64_t read_cpuppmcr_el3_mpmmpinctl(void)
- {
- return (read_cpuppmcr_el3() >> CPUPPMCR_EL3_MPMMPINCTL_SHIFT) &
- CPUPPMCR_EL3_MPMMPINCTL_MASK;
- }
- static void write_cpumpmmcr_el3_mpmm_en(uint64_t mpmm_en)
- {
- uint64_t value = read_cpumpmmcr_el3();
- value &= ~(CPUMPMMCR_EL3_MPMM_EN_MASK << CPUMPMMCR_EL3_MPMM_EN_SHIFT);
- value |= (mpmm_en & CPUMPMMCR_EL3_MPMM_EN_MASK) <<
- CPUMPMMCR_EL3_MPMM_EN_SHIFT;
- write_cpumpmmcr_el3(value);
- }
- static bool mpmm_supported(void)
- {
- bool supported = false;
- const struct mpmm_topology *topology;
- #if ENABLE_MPMM_FCONF
- topology = FCONF_GET_PROPERTY(mpmm, config, topology);
- #else
- topology = plat_mpmm_topology();
- #endif /* ENABLE_MPMM_FCONF */
- /*
- * For the current core firstly try to find out if the platform
- * configuration has claimed support for MPMM, then make sure that MPMM
- * is controllable through the system registers.
- */
- if (topology != NULL) {
- unsigned int core_pos = plat_my_core_pos();
- supported = topology->cores[core_pos].supported &&
- (read_cpuppmcr_el3_mpmmpinctl() == 0U);
- } else {
- ERROR("MPMM: failed to generate MPMM topology\n");
- }
- return supported;
- }
- /* Defaults to false */
- static bool mpmm_disable_for_errata;
- void mpmm_enable(void)
- {
- if (mpmm_supported()) {
- if (mpmm_disable_for_errata) {
- WARN("MPMM: disabled by errata workaround\n");
- return;
- }
- write_cpumpmmcr_el3_mpmm_en(1U);
- }
- }
- /*
- * This function is called from assembly code very early in BL31 so it must be
- * small and simple.
- */
- void mpmm_errata_disable(void)
- {
- mpmm_disable_for_errata = true;
- }
|