blob: a66f2aad3ab1664f82db46ef854edb6f4d598072 [file] [log] [blame]
Chris Kay03be39d2021-05-05 13:38:30 +01001/*
2 * Copyright (c) 2021, Arm Limited. All rights reserved.
3 *
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
65void mpmm_enable(void)
66{
67 bool supported = mpmm_supported();
68
69 if (supported) {
70 write_cpumpmmcr_el3_mpmm_en(1U);
71 }
72}