xref: /arm-trusted-firmware/lib/fconf/fconf_mpmm_getter.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2021, Arm Limited. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <stddef.h>
8*91f16700Schasinglulu #include <stdint.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <common/debug.h>
11*91f16700Schasinglulu #include <common/fdt_wrappers.h>
12*91f16700Schasinglulu #include <lib/fconf/fconf.h>
13*91f16700Schasinglulu #include <lib/fconf/fconf_mpmm_getter.h>
14*91f16700Schasinglulu #include <libfdt.h>
15*91f16700Schasinglulu 
16*91f16700Schasinglulu #include <plat/common/platform.h>
17*91f16700Schasinglulu 
18*91f16700Schasinglulu struct fconf_mpmm_config fconf_mpmm_config;
19*91f16700Schasinglulu static struct mpmm_topology fconf_mpmm_topology;
20*91f16700Schasinglulu 
21*91f16700Schasinglulu /*
22*91f16700Schasinglulu  * Within a `cpu` node, determine support for MPMM via the `supports-mpmm`
23*91f16700Schasinglulu  * property.
24*91f16700Schasinglulu  *
25*91f16700Schasinglulu  * Returns `0` on success, or a negative integer representing an error code.
26*91f16700Schasinglulu  */
27*91f16700Schasinglulu static int fconf_populate_mpmm_cpu(const void *fdt, int off, uintptr_t mpidr)
28*91f16700Schasinglulu {
29*91f16700Schasinglulu 	int ret, len;
30*91f16700Schasinglulu 
31*91f16700Schasinglulu 	int core_pos;
32*91f16700Schasinglulu 	struct mpmm_core *core;
33*91f16700Schasinglulu 
34*91f16700Schasinglulu 	core_pos = plat_core_pos_by_mpidr(mpidr);
35*91f16700Schasinglulu 	if (core_pos < 0) {
36*91f16700Schasinglulu 		return -FDT_ERR_BADVALUE;
37*91f16700Schasinglulu 	}
38*91f16700Schasinglulu 
39*91f16700Schasinglulu 	core = &fconf_mpmm_topology.cores[core_pos];
40*91f16700Schasinglulu 
41*91f16700Schasinglulu 	fdt_getprop(fdt, off, "supports-mpmm", &len);
42*91f16700Schasinglulu 	if (len >= 0) {
43*91f16700Schasinglulu 		core->supported = true;
44*91f16700Schasinglulu 		ret = 0;
45*91f16700Schasinglulu 	} else {
46*91f16700Schasinglulu 		core->supported = false;
47*91f16700Schasinglulu 		ret = len;
48*91f16700Schasinglulu 	}
49*91f16700Schasinglulu 
50*91f16700Schasinglulu 	return ret;
51*91f16700Schasinglulu }
52*91f16700Schasinglulu 
53*91f16700Schasinglulu /*
54*91f16700Schasinglulu  * Populates the global `fconf_mpmm_config` structure based on what's described
55*91f16700Schasinglulu  * by the hardware configuration device tree blob.
56*91f16700Schasinglulu  *
57*91f16700Schasinglulu  * The device tree is expected to provide a `supports-mpmm` property for each
58*91f16700Schasinglulu  * `cpu` node, like so:
59*91f16700Schasinglulu  *
60*91f16700Schasinglulu  *     cpu@0 {
61*91f16700Schasinglulu  *       supports-mpmm;
62*91f16700Schasinglulu  *     };
63*91f16700Schasinglulu  *
64*91f16700Schasinglulu  * This property indicates whether the core implements MPMM, as we cannot detect
65*91f16700Schasinglulu  * support for it dynamically.
66*91f16700Schasinglulu  */
67*91f16700Schasinglulu static int fconf_populate_mpmm(uintptr_t config)
68*91f16700Schasinglulu {
69*91f16700Schasinglulu 	int ret = fdtw_for_each_cpu(
70*91f16700Schasinglulu 		(const void *)config, fconf_populate_mpmm_cpu);
71*91f16700Schasinglulu 	if (ret == 0) {
72*91f16700Schasinglulu 		fconf_mpmm_config.topology = &fconf_mpmm_topology;
73*91f16700Schasinglulu 	} else {
74*91f16700Schasinglulu 		ERROR("FCONF: failed to configure MPMM: %d\n", ret);
75*91f16700Schasinglulu 	}
76*91f16700Schasinglulu 
77*91f16700Schasinglulu 	return ret;
78*91f16700Schasinglulu }
79*91f16700Schasinglulu 
80*91f16700Schasinglulu FCONF_REGISTER_POPULATOR(HW_CONFIG, mpmm, fconf_populate_mpmm);
81