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