[Skiboot] [PATCH 4/7] hdat: Rework service procesor information parsing
Vasant Hegde
hegdevasant at linux.vnet.ibm.com
Fri Jan 13 21:24:23 AEDT 2017
On 01/13/2017 12:26 PM, Oliver O'Halloran wrote:
> 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 <oohall at gmail.com>
> ---
> 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 90e8e5b90e3c..069a2d189d9f 100644
> --- a/hdata/fsp.c
> +++ b/hdata/fsp.c
> @@ -20,36 +20,101 @@
> #include <vpd.h>
> #include <ccan/str/str.h>
> #include <interrupts.h>
> +#include <inttypes.h>
>
> #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_UNK,
Better 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)
There are few other places we are adding fsp specific properties. We should make
this function as global, so that we can validate before adding those properties.
> {
> 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_UNK;
better return SP_UNK so that you can avoid next if condition.
> }
>
> - 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_UNK)
> + return SP_UNK;
> +
> + 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);
Better to use newly added dt_check_new() so that we can avoid redundant checks.
-Vasant
More information about the Skiboot
mailing list