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