aboutsummaryrefslogtreecommitdiff
path: root/hdata
diff options
context:
space:
mode:
authorVasant Hegde <hegdevasant@linux.vnet.ibm.com>2017-10-13 16:51:18 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-12-18 17:58:32 -0600
commit5110b54067c0db11122ab9a57dd2dcc56f026581 (patch)
treed7dc013bf9ee0baf8c1906707213d03901a99e1d /hdata
parent1953b41e1dd5a1a91d6e6a5dbfba0672955defc9 (diff)
downloadskiboot-5110b54067c0db11122ab9a57dd2dcc56f026581.zip
skiboot-5110b54067c0db11122ab9a57dd2dcc56f026581.tar.gz
skiboot-5110b54067c0db11122ab9a57dd2dcc56f026581.tar.bz2
hdata: Add memory hierarchy under xscom node
We have memory to chip mapping but doesn't have complete memory hierarchy. This patch adds memory hierarchy under xscom node. This is specific to P9 system as these hierarchy may change between processor generation. It uses memory controller ID details and populates nodes like: xscom@<addr>/mcbist@<mcbist_id>/mcs@<mcs_id>/mca@<mca_id>/dimm@<resource_id> Also this patch adds few properties under dimm node. Finally make sure xscom nodes created before calling memory_parse(). Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hdata')
-rw-r--r--hdata/memory.c130
-rw-r--r--hdata/spira.c6
-rw-r--r--hdata/test/p8-840-spira.dts10
-rw-r--r--hdata/test/p81-811.spira.dts20
4 files changed, 146 insertions, 20 deletions
diff --git a/hdata/memory.c b/hdata/memory.c
index dbb0ac4..74eedff 100644
--- a/hdata/memory.c
+++ b/hdata/memory.c
@@ -22,6 +22,7 @@
#include <mem_region.h>
#include <types.h>
#include <inttypes.h>
+#include <processor.h>
#include "spira.h"
#include "hdata.h"
@@ -44,8 +45,13 @@ struct HDIF_ms_area_address_range {
__be32 chip;
__be32 mirror_attr;
__be64 mirror_start;
+ __be32 controller_id;
} __packed;
+#define MS_CONTROLLER_MCBIST_ID(id) GETFIELD(PPC_BITMASK32(0, 1), id)
+#define MS_CONTROLLER_MCS_ID(id) GETFIELD(PPC_BITMASK32(4, 7), id)
+#define MS_CONTROLLER_MCA_ID(id) GETFIELD(PPC_BITMASK32(8, 15), id)
+
struct HDIF_ms_area_id {
__be16 id;
#define MS_PTYPE_RISER_CARD 0x8000
@@ -313,6 +319,121 @@ static void vpd_add_ram_area(const struct HDIF_common_hdr *msarea)
}
}
+static void add_mca_dimm_info(struct dt_node *mca,
+ const struct HDIF_common_hdr *msarea)
+{
+ unsigned int i;
+ const struct HDIF_child_ptr *ramptr;
+ const struct HDIF_common_hdr *ramarea;
+ const struct spira_fru_id *fru_id;
+ const struct HDIF_ram_area_id *ram_id;
+ const struct HDIF_ram_area_size *ram_area_sz;
+ struct dt_node *dimm;
+
+ ramptr = HDIF_child_arr(msarea, 0);
+ if (!CHECK_SPPTR(ramptr)) {
+ prerror("MS AREA: No RAM area at %p\n", msarea);
+ return;
+ }
+
+ for (i = 0; i < be32_to_cpu(ramptr->count); i++) {
+ ramarea = HDIF_child(msarea, ramptr, i, "RAM ");
+ if (!CHECK_SPPTR(ramarea))
+ continue;
+
+ fru_id = HDIF_get_idata(ramarea, 0, NULL);
+ if (!fru_id)
+ continue;
+
+ /* Use Resource ID to add dimm node */
+ dimm = dt_find_by_name_addr(mca, "dimm",
+ be16_to_cpu(fru_id->rsrc_id));
+ if (dimm)
+ continue;
+ dimm= dt_new_addr(mca, "dimm", be16_to_cpu(fru_id->rsrc_id));
+ assert(dimm);
+ dt_add_property_cells(dimm, "reg", be16_to_cpu(fru_id->rsrc_id));
+
+ /* Add location code */
+ slca_vpd_add_loc_code(dimm, be16_to_cpu(fru_id->slca_index));
+
+ /* DIMM size */
+ ram_area_sz = HDIF_get_idata(ramarea, 3, NULL);
+ if (!CHECK_SPPTR(ram_area_sz))
+ continue;
+ dt_add_property_cells(dimm, "size", be32_to_cpu(ram_area_sz->mb));
+
+ /* DIMM state */
+ ram_id = HDIF_get_idata(ramarea, 2, NULL);
+ if (!CHECK_SPPTR(ram_id))
+ continue;
+
+ if ((be16_to_cpu(ram_id->flags) & RAM_AREA_INSTALLED) &&
+ (be16_to_cpu(ram_id->flags) & RAM_AREA_FUNCTIONAL))
+ dt_add_property_string(dimm, "status", "okay");
+ else
+ dt_add_property_string(dimm, "status", "disabled");
+ }
+}
+
+static inline void dt_add_mem_reg_property(struct dt_node *node, u64 addr)
+{
+ dt_add_property_cells(node, "#address-cells", 1);
+ dt_add_property_cells(node, "#size-cells", 0);
+ dt_add_property_cells(node, "reg", addr);
+}
+
+static void add_memory_controller(const struct HDIF_common_hdr *msarea,
+ const struct HDIF_ms_area_address_range *arange)
+{
+ uint32_t chip_id, version;
+ uint32_t controller_id, mcbist_id, mcs_id, mca_id;
+ struct dt_node *xscom, *mcbist, *mcs, *mca;
+
+ /*
+ * Memory hierarchy may change between processor version. Presently
+ * its creating memory hierarchy for P9 (Nimbus) only.
+ */
+ version = PVR_TYPE(mfspr(SPR_PVR));
+ if (version != PVR_TYPE_P9)
+ return;
+
+ chip_id = pcid_to_chip_id(be32_to_cpu(arange->chip));
+ controller_id = be32_to_cpu(arange->controller_id);
+ xscom = find_xscom_for_chip(chip_id);
+ if (!xscom) {
+ prlog(PR_WARNING,
+ "MS AREA: Can't find XSCOM for chip %d\n", chip_id);
+ return;
+ }
+
+ mcbist_id = MS_CONTROLLER_MCBIST_ID(controller_id);
+ mcbist = dt_find_by_name_addr(xscom, "mcbist", mcbist_id);
+ if (!mcbist) {
+ mcbist = dt_new_addr(xscom, "mcbist", mcbist_id);
+ assert(mcbist);
+ dt_add_mem_reg_property(mcbist, mcbist_id);
+ }
+
+ mcs_id = MS_CONTROLLER_MCS_ID(controller_id);
+ mcs = dt_find_by_name_addr(mcbist, "mcs", mcs_id);
+ if (!mcs) {
+ mcs = dt_new_addr(mcbist, "mcs", mcs_id);
+ assert(mcs);
+ dt_add_mem_reg_property(mcs, mcs_id);
+ }
+
+ mca_id = MS_CONTROLLER_MCA_ID(controller_id);
+ mca = dt_find_by_name_addr(mcs, "mca", mca_id);
+ if (!mca) {
+ mca = dt_new_addr(mcs, "mca", mca_id);
+ assert(mca);
+ dt_add_mem_reg_property(mca, mca_id);
+ }
+
+ add_mca_dimm_info(mca, msarea);
+}
+
static void get_msareas(struct dt_node *root,
const struct HDIF_common_hdr *ms_vpd)
{
@@ -332,7 +453,7 @@ static void get_msareas(struct dt_node *root,
const struct HDIF_ms_area_address_range *arange;
const struct HDIF_ms_area_id *id;
const void *fruid;
- unsigned int size, j;
+ unsigned int size, j, offset;
u16 flags;
msarea = HDIF_child(ms_vpd, msptr, i, "MSAREA");
@@ -372,7 +493,8 @@ static void get_msareas(struct dt_node *root,
return;
}
- if (be32_to_cpu(arr->eactsz) < sizeof(*arange)) {
+ offset = offsetof(struct HDIF_ms_area_address_range, mirror_start);
+ if (be32_to_cpu(arr->eactsz) < offset) {
prerror("MS VPD: %p msarea #%i arange size too small!\n",
ms_vpd, i);
return;
@@ -392,6 +514,10 @@ static void get_msareas(struct dt_node *root,
/* This offset is from the arr, not the header! */
arange = (void *)arr + be32_to_cpu(arr->offset);
for (j = 0; j < be32_to_cpu(arr->ecnt); j++) {
+ offset = offsetof(struct HDIF_ms_area_address_range, controller_id);
+ if (be32_to_cpu(arr->eactsz) >= offset)
+ add_memory_controller(msarea, arange);
+
if (!add_address_range(root, id, arange))
return;
arange = (void *)arange + be32_to_cpu(arr->esize);
diff --git a/hdata/spira.c b/hdata/spira.c
index 57b1d41..e13c504 100644
--- a/hdata/spira.c
+++ b/hdata/spira.c
@@ -1592,12 +1592,12 @@ int parse_hdat(bool is_opal)
/* IPL params */
add_iplparams();
- /* Parse MS VPD */
- memory_parse();
-
/* Add XSCOM node (must be before chiptod, IO and FSP) */
add_xscom();
+ /* Parse MS VPD */
+ memory_parse();
+
/* Add any FSPs */
fsp_parse();
diff --git a/hdata/test/p8-840-spira.dts b/hdata/test/p8-840-spira.dts
index 3e6bf6e..8877b5f 100644
--- a/hdata/test/p8-840-spira.dts
+++ b/hdata/test/p8-840-spira.dts
@@ -568,7 +568,7 @@
};
memory@0 {
- phandle = <0x41>;
+ phandle = <0x45>;
device_type = "memory";
ibm,chip-id = <0x0>;
reg = <0x0 0x0 0x8 0x0>;
@@ -864,7 +864,7 @@
};
xscom@3fc0000000000 {
- phandle = <0x42>;
+ phandle = <0x41>;
ibm,chip-id = <0x0>;
ibm,proc-chip-id = <0x0>;
#address-cells = <0x1>;
@@ -918,7 +918,7 @@
};
psihb@2010900 {
- phandle = <0x43>;
+ phandle = <0x42>;
reg = <0x2010900 0x20>;
compatible = "ibm,power8-psihb-x", "ibm,psihb-x";
boot-link;
@@ -927,7 +927,7 @@
};
xscom@3fc0800000000 {
- phandle = <0x44>;
+ phandle = <0x43>;
ibm,chip-id = <0x1>;
ibm,proc-chip-id = <0x1>;
#address-cells = <0x1>;
@@ -981,7 +981,7 @@
};
psihb@2010900 {
- phandle = <0x45>;
+ phandle = <0x44>;
reg = <0x2010900 0x20>;
compatible = "ibm,power8-psihb-x", "ibm,psihb-x";
};
diff --git a/hdata/test/p81-811.spira.dts b/hdata/test/p81-811.spira.dts
index d354ad5..669b24e 100644
--- a/hdata/test/p81-811.spira.dts
+++ b/hdata/test/p81-811.spira.dts
@@ -1660,14 +1660,14 @@
};
memory@0 {
- phandle = <0x81>;
+ phandle = <0x89>;
device_type = "memory";
ibm,chip-id = <0x0>;
reg = <0x0 0x0 0x10 0x0>;
};
memory@1000000000 {
- phandle = <0x82>;
+ phandle = <0x8a>;
device_type = "memory";
ibm,chip-id = <0x10>;
reg = <0x10 0x0 0x10 0x0>;
@@ -2059,7 +2059,7 @@
};
xscom@3fc0000000000 {
- phandle = <0x83>;
+ phandle = <0x81>;
ibm,chip-id = <0x0>;
ibm,proc-chip-id = <0x0>;
#address-cells = <0x1>;
@@ -2113,7 +2113,7 @@
};
psihb@2010900 {
- phandle = <0x84>;
+ phandle = <0x82>;
reg = <0x2010900 0x20>;
compatible = "ibm,power8-psihb-x", "ibm,psihb-x";
boot-link;
@@ -2122,7 +2122,7 @@
};
xscom@3fc0800000000 {
- phandle = <0x85>;
+ phandle = <0x83>;
ibm,chip-id = <0x1>;
ibm,proc-chip-id = <0x1>;
#address-cells = <0x1>;
@@ -2175,14 +2175,14 @@
};
psihb@2010900 {
- phandle = <0x86>;
+ phandle = <0x84>;
reg = <0x2010900 0x20>;
compatible = "ibm,power8-psihb-x", "ibm,psihb-x";
};
};
xscom@3fc8000000000 {
- phandle = <0x87>;
+ phandle = <0x85>;
ibm,chip-id = <0x10>;
ibm,proc-chip-id = <0x2>;
#address-cells = <0x1>;
@@ -2225,7 +2225,7 @@
};
psihb@2010900 {
- phandle = <0x88>;
+ phandle = <0x86>;
reg = <0x2010900 0x20>;
compatible = "ibm,power8-psihb-x", "ibm,psihb-x";
status = "ok";
@@ -2233,7 +2233,7 @@
};
xscom@3fc8800000000 {
- phandle = <0x89>;
+ phandle = <0x87>;
ibm,chip-id = <0x11>;
ibm,proc-chip-id = <0x3>;
#address-cells = <0x1>;
@@ -2286,7 +2286,7 @@
};
psihb@2010900 {
- phandle = <0x8a>;
+ phandle = <0x88>;
reg = <0x2010900 0x20>;
compatible = "ibm,power8-psihb-x", "ibm,psihb-x";
};