blob: dc61cf62aa8f43b04abcafdeff5d9866897c6b50 [file] [log] [blame]
Chris Kay03be39d2021-05-05 13:38:30 +01001/*
johpow013ba9cb22022-02-13 21:00:10 -06002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
Chris Kay03be39d2021-05-05 13:38:30 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdbool.h>
8
9#include <common/debug.h>
10#include <lib/mpmm/mpmm.h>
11
12#include <plat/common/platform.h>
13
14#if ENABLE_MPMM_FCONF
15# include <lib/fconf/fconf.h>
16# include <lib/fconf/fconf_mpmm_getter.h>
17#endif
18
19static uint64_t read_cpuppmcr_el3_mpmmpinctl(void)
20{
21 return (read_cpuppmcr_el3() >> CPUPPMCR_EL3_MPMMPINCTL_SHIFT) &
22 CPUPPMCR_EL3_MPMMPINCTL_MASK;
23}
24
25static void write_cpumpmmcr_el3_mpmm_en(uint64_t mpmm_en)
26{
27 uint64_t value = read_cpumpmmcr_el3();
28
29 value &= ~(CPUMPMMCR_EL3_MPMM_EN_MASK << CPUMPMMCR_EL3_MPMM_EN_SHIFT);
30 value |= (mpmm_en & CPUMPMMCR_EL3_MPMM_EN_MASK) <<
31 CPUMPMMCR_EL3_MPMM_EN_SHIFT;
32
33 write_cpumpmmcr_el3(value);
34}
35
36static bool mpmm_supported(void)
37{
38 bool supported = false;
39 const struct mpmm_topology *topology;
40
41#if ENABLE_MPMM_FCONF
42 topology = FCONF_GET_PROPERTY(mpmm, config, topology);
43#else
44 topology = plat_mpmm_topology();
45#endif /* ENABLE_MPMM_FCONF */
46
47 /*
48 * For the current core firstly try to find out if the platform
49 * configuration has claimed support for MPMM, then make sure that MPMM
50 * is controllable through the system registers.
51 */
52
53 if (topology != NULL) {
54 unsigned int core_pos = plat_my_core_pos();
55
56 supported = topology->cores[core_pos].supported &&
57 (read_cpuppmcr_el3_mpmmpinctl() == 0U);
58 } else {
59 ERROR("MPMM: failed to generate MPMM topology\n");
60 }
61
62 return supported;
63}
64
johpow013ba9cb22022-02-13 21:00:10 -060065/* Defaults to false */
66static bool mpmm_disable_for_errata;
67
Chris Kay03be39d2021-05-05 13:38:30 +010068void mpmm_enable(void)
69{
johpow013ba9cb22022-02-13 21:00:10 -060070 if (mpmm_supported()) {
71 if (mpmm_disable_for_errata) {
72 WARN("MPMM: disabled by errata workaround\n");
73 return;
74 }
Chris Kay03be39d2021-05-05 13:38:30 +010075 write_cpumpmmcr_el3_mpmm_en(1U);
76 }
77}
johpow013ba9cb22022-02-13 21:00:10 -060078
79/*
80 * This function is called from assembly code very early in BL31 so it must be
81 * small and simple.
82 */
83void mpmm_errata_disable(void)
84{
85 mpmm_disable_for_errata = true;
86}