From 7c860f25e4e44b046ee44eac9e2e0834fd4a3dbc Mon Sep 17 00:00:00 2001 From: Oliver O'Halloran Date: Fri, 13 Jan 2017 17:56:19 +1100 Subject: hdat: Rework service procesor information parsing With OpenPower machines using HDAT on P9 the SPINFO structures have been amended to support BMCs in addition to the FSP. This patch reworks the existing parsing to prepare for adding BMC support. Signed-off-by: Oliver O'Halloran [stewart@linux.vnet.ibm.com: s/UNK/UNKNOWN/ suggested by Vasant] Signed-off-by: Stewart Smith --- hdata/fsp.c | 166 ++++++++++++++++++++++++++++++-------------- hdata/test/p8-840-spira.dt | 2 +- hdata/test/p81-811.spira.dt | 2 +- 3 files changed, 117 insertions(+), 53 deletions(-) diff --git a/hdata/fsp.c b/hdata/fsp.c index 90e8e5b9..0b307b75 100644 --- a/hdata/fsp.c +++ b/hdata/fsp.c @@ -20,36 +20,101 @@ #include #include #include +#include #include "hdata.h" -static struct dt_node *fsp_create_node(const void *spss, int i, - struct dt_node *parent) +enum sp_type { + SP_BAD = 0, + SP_UNKNOWN, + SP_FSP, + SP_BMC, +}; + +static const char * const sp_names[] = { + "Broken", "Unknown", "FSP", "BMC", +}; + +static enum sp_type find_service_proc_type(const struct HDIF_common_hdr *spss, + int index) { const struct spss_sp_impl *sp_impl; - struct dt_node *node; - unsigned int mask; + int hw_ver, sw_ver, flags; + enum sp_type sp_type; + bool functional, installed; /* Find an check the SP Implementation structure */ sp_impl = HDIF_get_idata(spss, SPSS_IDATA_SP_IMPL, NULL); if (!CHECK_SPPTR(sp_impl)) { - prerror("FSP #%d: SPSS/SP_Implementation not found !\n", i); - return NULL; + prerror("SP #%d: SPSS/SP_Implementation not found !\n", index); + return SP_BAD; + } + + hw_ver = be16_to_cpu(sp_impl->hw_version); + sw_ver = be16_to_cpu(sp_impl->sw_version); + flags = be16_to_cpu(sp_impl->func_flags); + + switch (hw_ver) { + case 0x2: /* We only support FSP2 */ + sp_type = SP_FSP; + break; + case 0x3: + sp_type = SP_BMC; + break; + default: + sp_type = SP_UNKNOWN; } - prlog(PR_INFO, "FSP #%d: FSP HW version %d, SW version %d," - " chip DD%d.%d\n", i, - be16_to_cpu(sp_impl->hw_version), - be16_to_cpu(sp_impl->sw_version), - sp_impl->chip_version >> 4, sp_impl->chip_version & 0xf); - mask = SPSS_SP_IMPL_FLAGS_INSTALLED | SPSS_SP_IMPL_FLAGS_FUNCTIONAL; - if ((be16_to_cpu(sp_impl->func_flags) & mask) != mask) { - prerror("FSP #%d: FSP not installed or not functional\n", i); - return NULL; + if (sp_type == SP_UNKNOWN) + return SP_UNKNOWN; + + installed = !!(flags & SPSS_SP_IMPL_FLAGS_INSTALLED); + functional = !!(flags & SPSS_SP_IMPL_FLAGS_FUNCTIONAL); + + if (!installed || !functional) { + prerror("%s #%d not usable: %sinstalled, %sfunctional\n", + sp_names[sp_type], index, + installed ? "" : "not ", + functional ? "" : "not "); + + return SP_BAD; } + prlog(PR_INFO, "%s #%d: HW version %d, SW version %d, chip DD%d.%d\n", + sp_names[sp_type], index, hw_ver, sw_ver, + sp_impl->chip_version >> 4, + sp_impl->chip_version & 0xf); + + return sp_type; +} + +/* + * Note on DT representation of the PSI links and FSPs: + * + * We create a XSCOM node for each PSI host bridge(one per chip), + * + * This is done in spira.c + * + * We do not create the /psi MMIO variant at this stage, it will + * be added by the psi driver in skiboot. + * + * We do not put the FSP(s) as children of these. Instead, we create + * a top-level /fsps node with the FSPs as children. + * + * Each FSP then has a "links" property which is an array of chip IDs + */ + +static struct dt_node *fsp_create_node(const void *spss, int i, + struct dt_node *parent) +{ + const struct spss_sp_impl *sp_impl; + struct dt_node *node; + + sp_impl = HDIF_get_idata(spss, SPSS_IDATA_SP_IMPL, NULL); + node = dt_new_addr(parent, "fsp", i); assert(node); + dt_add_property_cells(node, "reg", i); if (be16_to_cpu(sp_impl->hw_version) == 1) { @@ -97,8 +162,8 @@ static uint32_t fsp_create_link(const struct spss_iopath *iopath, int index, default: ststr = "Unknown"; } - prlog(PR_DEBUG, "FSP #%d: IO PATH %d is %s PSI Link, GXHB at %llx\n", - fsp_index, index, ststr, (long long)be64_to_cpu(iopath->psi.gxhb_base)); + prlog(PR_DEBUG, "FSP #%d: IO PATH %d is %s PSI Link, GXHB at %" PRIx64 "\n", + fsp_index, index, ststr, be64_to_cpu(iopath->psi.gxhb_base)); chip_id = pcid_to_chip_id(be32_to_cpu(iopath->psi.proc_chip_id)); node = dt_find_compatible_node_on_chip(dt_root, NULL, "ibm,psihb-x", @@ -160,43 +225,42 @@ static void fsp_create_links(const void *spss, int index, void fsp_parse(void) { - const void *base_spss, *spss; - struct dt_node *fsp_root, *fsp_node; - int i; - - /* - * Note on DT representation of the PSI links and FSPs: - * - * We create a XSCOM node for each PSI host bridge(one per chip), - * - * This is done in spira.c - * - * We do not create the /psi MMIO variant at this stage, it will - * be added by the psi driver in skiboot. - * - * We do not put the FSP(s) as children of these. Instead, we create - * a top-level /fsps node with the FSPs as children. - * - * Each FSP then has a "links" property which is an array of chip IDs - */ - - /* Find SPSS in SPIRA */ - base_spss = get_hdif(&spira.ntuples.sp_subsys, SPSS_HDIF_SIG); - if (!base_spss) { - prlog(PR_WARNING, "FSP: No SPSS in SPIRA !\n"); + struct dt_node *fsp_root = NULL, *fsp_node; + const void *sp; + int index; + + /* Find SPSS tuple in SPIRA */ + sp = get_hdif(&spira.ntuples.sp_subsys, SPSS_HDIF_SIG); + if (!sp) { + prlog(PR_WARNING, "HDAT: No FSP/BMC found!\n"); return; } - fsp_root = dt_new(dt_root, "fsps"); - assert(fsp_root); - dt_add_property_cells(fsp_root, "#address-cells", 1); - dt_add_property_cells(fsp_root, "#size-cells", 0); + for_each_ntuple_idx(&spira.ntuples.sp_subsys, sp, index, SPSS_HDIF_SIG) { + switch (find_service_proc_type(sp, index)) { + case SP_FSP: + if (!fsp_root) { + fsp_root = dt_new(dt_root, "fsps"); + assert(fsp_root); + + dt_add_property_cells(fsp_root, + "#address-cells", 1); + dt_add_property_cells(fsp_root, + "#size-cells", 0); + } + + fsp_node = fsp_create_node(sp, index, fsp_root); + if (fsp_node) + fsp_create_links(sp, index, fsp_node); + + break; + + case SP_BAD: + break; - /* Iterate FSPs in SPIRA */ - for_each_ntuple_idx(&spira.ntuples.sp_subsys, spss, i, SPSS_HDIF_SIG) { - fsp_node = fsp_create_node(spss, i, fsp_root); - if (fsp_node) - fsp_create_links(spss, i, fsp_node); + default: + prerror("SP #%d: This service processor is not supported\n", index); + break; + } } } - diff --git a/hdata/test/p8-840-spira.dt b/hdata/test/p8-840-spira.dt index 79e43af4..7566e9ce 100644 --- a/hdata/test/p8-840-spira.dt +++ b/hdata/test/p8-840-spira.dt @@ -26,7 +26,7 @@ XSCOM: Found HW ID 0x0 (PCID 0x0) @ 0x3c0000000000 VPD: CCIN desc not available for : 54E1 XSCOM: Found HW ID 0x1 (PCID 0x1) @ 0x3c0800000000 VPD: CCIN desc not available for : 54E1 -FSP #0: FSP HW version 2, SW version 1, chip DD1.0 +FSP #0: HW version 2, SW version 1, chip DD1.0 CEC: HUB FRU 0 is CPU Card CEC: 2 chips in FRU CEC: Murano ! diff --git a/hdata/test/p81-811.spira.dt b/hdata/test/p81-811.spira.dt index 6098ef4a..a98cc46e 100644 --- a/hdata/test/p81-811.spira.dt +++ b/hdata/test/p81-811.spira.dt @@ -71,7 +71,7 @@ XSCOM: Found HW ID 0x10 (PCID 0x2) @ 0x3c8000000000 VPD: CCIN desc not available for : 54E8 XSCOM: Found HW ID 0x11 (PCID 0x3) @ 0x3c8800000000 VPD: CCIN desc not available for : 54E8 -FSP #0: FSP HW version 2, SW version 1, chip DD1.0 +FSP #0: HW version 2, SW version 1, chip DD1.0 CEC: HUB FRU 0 is CPU Card CEC: 2 chips in FRU CEC: Murano ! -- cgit v1.2.1