diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/skiboot/core/affinity.c | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/skiboot/core/affinity.c')
-rw-r--r-- | roms/skiboot/core/affinity.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/roms/skiboot/core/affinity.c b/roms/skiboot/core/affinity.c new file mode 100644 index 000000000..0209d3cd9 --- /dev/null +++ b/roms/skiboot/core/affinity.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +/* + * + * We currently construct our associativity properties as such: + * + * - For "chip" devices (bridges, memory, ...), 4 entries: + * + * - CCM node ID + * - HW card ID + * - HW module ID + * - Chip ID + * + * The information is constructed based on the chip ID which (unlike + * pHyp) is our HW chip ID (aka "XSCOM" chip ID). We use it to retrieve + * the other properties from the corresponding chip/xscom node in the + * device-tree. If those properties are absent, 0 is used. + * + * - For "core" devices, we add a 5th entry: + * + * - Core ID + * + * Here too, we do not use the "cooked" HW processor ID from HDAT but + * instead use the real HW core ID which is basically the interrupt + * server number of thread 0 on that core. + * + * + * The ibm,associativity-reference-points property is currently set to + * 4,4 indicating that the chip ID is our only reference point. This + * should be extended to encompass the node IDs eventually. + */ +#include <skiboot.h> +#include <opal.h> +#include <device.h> +#include <console.h> +#include <trace.h> +#include <chip.h> +#include <cpu.h> +#include <affinity.h> + +static uint32_t get_chip_node_id(struct proc_chip *chip) +{ + /* If the xscom node has an ibm,ccm-node-id property, use it */ + if (dt_has_node_property(chip->devnode, "ibm,ccm-node-id", NULL)) + return dt_prop_get_u32(chip->devnode, "ibm,ccm-node-id"); + + /* + * Else use the 3 top bits of the chip ID which should be + * the node on P8 + */ + return chip->id >> 3; +} + +void add_associativity_ref_point(void) +{ + int ref2 = 0x4; + + /* + * Note about our use of reference points: + * + * Linux currently supports up to three levels of NUMA. We use the + * first reference point for the node ID and the second reference + * point for a second level of affinity. We always use the chip ID + * (4) for the first reference point. + * + * Choosing the second level of affinity is model specific + * unfortunately. Current POWER8E models should use the DCM + * as a second level of NUMA. + * + * If there is a way to obtain this information from the FSP + * that would be ideal, but for now hardwire our POWER8E setting. + * + * For GPU nodes we add a third level of NUMA, such that the + * distance of the GPU node from all other nodes is uniformly + * the highest. + */ + if (PVR_TYPE(mfspr(SPR_PVR)) == PVR_TYPE_P8E) + ref2 = 0x3; + + dt_add_property_cells(opal_node, "ibm,associativity-reference-points", + 0x4, ref2, 0x2); +} + +void add_chip_dev_associativity(struct dt_node *dev) +{ + uint32_t chip_id = dt_get_chip_id(dev); + struct proc_chip *chip = get_chip(chip_id); + uint32_t hw_cid, hw_mid; + + if (!chip) + return; + + hw_cid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-card-id", 0); + hw_mid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-module-id", 0); + + dt_add_property_cells(dev, "ibm,associativity", 4, + get_chip_node_id(chip), + hw_cid, hw_mid, chip_id); +} + +void add_core_associativity(struct cpu_thread *cpu) +{ + struct proc_chip *chip = get_chip(cpu->chip_id); + uint32_t hw_cid, hw_mid, core_id; + + if (!chip) + return; + + if (proc_gen == proc_gen_p8) + core_id = (cpu->pir >> 3) & 0xf; + else if (proc_gen == proc_gen_p9) + core_id = (cpu->pir >> 2) & 0x1f; + else if (proc_gen == proc_gen_p10) + core_id = (cpu->pir >> 2) & 0x1f; + else + return; + + hw_cid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-card-id", 0); + hw_mid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-module-id", 0); + + dt_add_property_cells(cpu->node, "ibm,associativity", 5, + get_chip_node_id(chip), + hw_cid, hw_mid, chip->id, core_id); +} |