xref: /aosp_15_r20/external/arm-trusted-firmware/lib/mpmm/mpmm.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2021, Arm Limited. All rights reserved.
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  */
6*54fd6939SJiyong Park 
7*54fd6939SJiyong Park #include <stdbool.h>
8*54fd6939SJiyong Park 
9*54fd6939SJiyong Park #include <common/debug.h>
10*54fd6939SJiyong Park #include <lib/mpmm/mpmm.h>
11*54fd6939SJiyong Park 
12*54fd6939SJiyong Park #include <plat/common/platform.h>
13*54fd6939SJiyong Park 
14*54fd6939SJiyong Park #if ENABLE_MPMM_FCONF
15*54fd6939SJiyong Park #	include <lib/fconf/fconf.h>
16*54fd6939SJiyong Park #	include <lib/fconf/fconf_mpmm_getter.h>
17*54fd6939SJiyong Park #endif
18*54fd6939SJiyong Park 
read_cpuppmcr_el3_mpmmpinctl(void)19*54fd6939SJiyong Park static uint64_t read_cpuppmcr_el3_mpmmpinctl(void)
20*54fd6939SJiyong Park {
21*54fd6939SJiyong Park 	return (read_cpuppmcr_el3() >> CPUPPMCR_EL3_MPMMPINCTL_SHIFT) &
22*54fd6939SJiyong Park 		CPUPPMCR_EL3_MPMMPINCTL_MASK;
23*54fd6939SJiyong Park }
24*54fd6939SJiyong Park 
write_cpumpmmcr_el3_mpmm_en(uint64_t mpmm_en)25*54fd6939SJiyong Park static void write_cpumpmmcr_el3_mpmm_en(uint64_t mpmm_en)
26*54fd6939SJiyong Park {
27*54fd6939SJiyong Park 	uint64_t value = read_cpumpmmcr_el3();
28*54fd6939SJiyong Park 
29*54fd6939SJiyong Park 	value &= ~(CPUMPMMCR_EL3_MPMM_EN_MASK << CPUMPMMCR_EL3_MPMM_EN_SHIFT);
30*54fd6939SJiyong Park 	value |= (mpmm_en & CPUMPMMCR_EL3_MPMM_EN_MASK) <<
31*54fd6939SJiyong Park 		CPUMPMMCR_EL3_MPMM_EN_SHIFT;
32*54fd6939SJiyong Park 
33*54fd6939SJiyong Park 	write_cpumpmmcr_el3(value);
34*54fd6939SJiyong Park }
35*54fd6939SJiyong Park 
mpmm_supported(void)36*54fd6939SJiyong Park static bool mpmm_supported(void)
37*54fd6939SJiyong Park {
38*54fd6939SJiyong Park 	bool supported = false;
39*54fd6939SJiyong Park 	const struct mpmm_topology *topology;
40*54fd6939SJiyong Park 
41*54fd6939SJiyong Park #if ENABLE_MPMM_FCONF
42*54fd6939SJiyong Park 	topology = FCONF_GET_PROPERTY(mpmm, config, topology);
43*54fd6939SJiyong Park #else
44*54fd6939SJiyong Park 	topology = plat_mpmm_topology();
45*54fd6939SJiyong Park #endif /* ENABLE_MPMM_FCONF */
46*54fd6939SJiyong Park 
47*54fd6939SJiyong Park 	/*
48*54fd6939SJiyong Park 	 * For the current core firstly try to find out if the platform
49*54fd6939SJiyong Park 	 * configuration has claimed support for MPMM, then make sure that MPMM
50*54fd6939SJiyong Park 	 * is controllable through the system registers.
51*54fd6939SJiyong Park 	 */
52*54fd6939SJiyong Park 
53*54fd6939SJiyong Park 	if (topology != NULL) {
54*54fd6939SJiyong Park 		unsigned int core_pos = plat_my_core_pos();
55*54fd6939SJiyong Park 
56*54fd6939SJiyong Park 		supported = topology->cores[core_pos].supported &&
57*54fd6939SJiyong Park 			(read_cpuppmcr_el3_mpmmpinctl() == 0U);
58*54fd6939SJiyong Park 	} else {
59*54fd6939SJiyong Park 		ERROR("MPMM: failed to generate MPMM topology\n");
60*54fd6939SJiyong Park 	}
61*54fd6939SJiyong Park 
62*54fd6939SJiyong Park 	return supported;
63*54fd6939SJiyong Park }
64*54fd6939SJiyong Park 
mpmm_enable(void)65*54fd6939SJiyong Park void mpmm_enable(void)
66*54fd6939SJiyong Park {
67*54fd6939SJiyong Park 	bool supported = mpmm_supported();
68*54fd6939SJiyong Park 
69*54fd6939SJiyong Park 	if (supported) {
70*54fd6939SJiyong Park 		write_cpumpmmcr_el3_mpmm_en(1U);
71*54fd6939SJiyong Park 	}
72*54fd6939SJiyong Park }
73