diff mbox

[4/7] hdat: Rework service procesor information parsing

Message ID 1484290582-5863-4-git-send-email-oohall@gmail.com
State Accepted
Headers show

Commit Message

Oliver O'Halloran Jan. 13, 2017, 6:56 a.m. UTC
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@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(-)

Comments

Vasant Hegde Jan. 13, 2017, 10:24 a.m. UTC | #1
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@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
diff mbox

Patch

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,
+	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_UNK;
 	}
 
-	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);
+
+				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 79e43af4f6d4..7566e9cebd6b 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 6098ef4a8768..a98cc46eede2 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 !