On Fri, Jun 06, 2025 at 10:10:52AM +0200, Jean Delvare wrote: > Hi Jerry, > > On Thu, 5 Jun 2025 15:29:01 -0600, Jerry Hoemann wrote: > > Record type 202: DIMM Location Record > > Thanks for contributing this type, it seems very useful. > > > Signed-off-by: Jerry Hoemann <jerry.hoem...@hpe.com> > > --- > > dmioem.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 90 insertions(+) > > > > diff --git a/dmioem.c b/dmioem.c > > index d4d83e2..b5d0402 100644 > > --- a/dmioem.c > > +++ b/dmioem.c > > @@ -1147,6 +1147,96 @@ static int dmi_decode_hp(const struct dmi_header *h) > > } > > break; > > > > + case 202: > > + /* > > + * Vendor Specific: HPE DIMM Location Record > > + * > > + * This record allows software to correlate a Type 17 > > Memory Device Record > > + * with a specific DIMM (DIMM, Board, and/or Processor > > number if appropriate). > > + * > > + * There will be one Record Type 202 for each DIMM > > socket possible in the system. > > + * A system will include a record for each DIMM socket > > even if that DIMM socket > > + * is on a memory board which is not currently > > installed. > > + * > > + * Offset | Name | Width | Description > > + * ------------------------------------- > > + * 0x00 | Type | BYTE | 0xCA, DIMM Location > > Record > > + * 0x01 | Length | BYTE | Length of structure > > + * 0x02 | Handle | WORD | Unique handle > > + * 0x04 | Assoc Record | WORD | Handle of Associated > > Type 17 Memory Record > > + * 0x06 | Board Number | BYTE | 1-based Memory Board > > number. 0FFh: DIMM on system board > > + * 0x07 | DIMM Number | BYTE | 1-based DIMM number > > + * 0x08 | Proc Number | BYTE | 1-based procssor > > number. 0FFh don't display > > + * 0x09 | Log DIMM Num | BYTE | 1-based Logical DIMM > > number mapping to ACPI numbering > > + * 0x0A | UEFI Dev Path| STRING| String number for > > UEFI Device Path > > + * 0x0B | UEFI Dev Name| STRING| String number for > > UEFI Device Structured Name > > + * 0x0C | Device Name | STRING| String number for > > Device Name > > + * 0x0D | Mem Cntr Num | BYTE | 1-based Memory > > controller number > > Cntr -> Cntrl for consistency.
done. > > > + * 0x0E | Mem Chan Num | BYTE | 1-based memory > > channel number (matches silk screen) > > + * 0x0F | IE DIMM Num | BYTE | 0-based DIMM number > > repored by IE. FF -> not supported > > + * | Reserved G12 or later > > + * 0x10 | IE PLDM ID | BYTE | IE PLDM Sensor ID. > > FF -> not supported > > + * | Reserved G12 or later > > Out of curiosity, what do "IE" and "PLDM" stand for in this context? It > may be worth spelling them out in the description for reference. IE Innovation Engine (IE) Firmware. (Intel based fw.) I believe PLDM is "Platform Level Data Model" > > > + * 0x11 | Vendor ID | WORD | Module manufacturers > > ID code as read by SPD > > + * 0x13 | Device ID | WORD | (NVDIMM only) Module > > product ID code from SPD > > I find it suspicious that Device ID is for NVDIMM only, if Vendor ID is > not. Vendor ID is not just for NVDIMM. I have several examples were Vendor ID is defined, but device id is not. > > > + * 0x15 | Sys Cntrl Ven| WORD | (NVDIMM only) > > Controller manufacturer ID from SPD > > + * 0x17 | Sub Cntrl Dev| WORD | (NVDIMM only) > > Controller product ID from SPD > > Inconsistent name fields, I think it should be either "Sys" for both, of > "Sub" for both (or maybe neither, as "Cntrl" seems descriptive enough). fixed. Sub for both. > > > + * 0x19 | Interleave | BYTE | 1-based unique > > interleave set within Procssor Number > > + * 0x1A | Part Number | STRING| String number for > > HPE part number from OEM SPD > > + * 0x1B | DIMM Index | BYTE | 0-based DIMM Index > > Per Channel > > + */ > > + > > + if (gen < G9) return 0; > > + pr_handle_name("%s DIMM Location Record", company); > > + > > + if (h->length < 0x09) break; > > + pr_attr("Associated Memory Record", "0x%04X", WORD(data > > + 0x04)); > > We traditionally don't display handle references in quiet mode, so > please add a conditional: if (!(opt.flags & FLAG_QUIET)). done. > > > + if (data[0x06] == 0xFF) > > + pr_attr("Board Number", "%s", "System Board"); > > + else > > + pr_attr("Board Number", "%d", data[0x06]); > > + pr_attr("DIMM Number", "%d", data[0x07]); > > + if (data[0x08] != 0xFF) > > + pr_attr("Processor Number", "%d", data[0x08]); > > + > > + if (h->length < 0x0A) break; > > + pr_attr("Logical DIMM Number", "%d", data[0x09]); > > + > > + if (h->length < 0x0B) break; > > + if (data[0x0A]) > > + pr_attr("UEFI Device Path", "%s", dmi_string(h, > > data[0x0A])); > > + > > + if (h->length < 0x0E) break; > > + if (data[0x0B]) > > + pr_attr("UEFI Device Name", "%s", dmi_string(h, > > data[0x0B])); > > + if (data[0x0C]) > > + pr_attr("Device Name", "%s", dmi_string(h, > > data[0x0C])); > > + if (data[0x0D]) > > + pr_attr("Memory Controller Number", "%d", > > data[0x0D]); > > + > > + if (h->length < 0x1B) break; > > In my collection of HPE DMI tables, I see type 202 records of length 25 > (=0x19, DL380/DL385/DL560 Gen10) and 26 (=0x1A, various Gen10 and Gen10 > Plus). These lengths are not tested, which causes some available fields > not to be displayed on these systems. done. > > > + if (data[0x0E]) > > + pr_attr("Memory Channel Number", "%d", > > data[0x0E]); > > + if (gen < G12 && data[0x0F] != 0xFF) > > + pr_attr("IE DIMM Number", "%d", data[0x0F]); > > + if (gen < G12 && data[0x10] != 0xFF) > > + pr_attr("IE PLDM ID", "%d", data[0x10]); > > + if (data[0x11] || data[0x12]) > > + pr_attr("Vendor ID", "0x%x", WORD(data + 0x11)); > > + if (data[0x13] || data[0x14]) > > + pr_attr("Device ID", "0x%x", WORD(data + 0x13)); > > + if (data[0x15] || data[0x16]) > > + pr_attr("Controller Manufacturing ID", "0x%x", > > WORD(data + 0x15)); > > I think it's rather "Manufacturer"? done. > > > + if (data[0x17] || data[0x18]) > > + pr_attr("Controller Product ID", "0x%x", > > WORD(data + 0x17)); > > I recommend format "0x%04X" for the 4 fields above, to be consistent > with dmi_memory_product_id(). In fact it might make sense to export > this function and reuse it here, and maybe dmi_memory_manufacturer_id() > too. The latter prints things in a different way, I don't know if that > would be a problem or a benefit for you. done. > > > + if (data[0x19]) > > + pr_attr("Best Interleave", "0x%x", data[0x19]); > > This needs to be clarified. The description mentions an "interleave > set", which I would expect to be a decimal number. Not sure what "best" > refers to in the attribute label above. Please check with your firmware > team what this field contains and how its contents should be > interpreted. This is for persistant memory supported only on Gen10/+. Quoating the spec: ---------------------------------------- For certain NVDIMMs configurations, there is a defined “best-interleave” DIMM combination that will provide optimal memory performance. The Best Interleaved Set field in this record will contain a unique interleave set number (1-based) within the indicated Processor Number if the DIMM is a part of this “best-interleaved” set. DIMMs with identical Best Interleaved Set values and identical Processor Numbers means those DIMMs are best-interleaved together on that specific processor. If a DIMM is not interleaved, the value of the Best Interleaved Set field will be set to 0 ---------------------------------------- There are RBSU controls w.r.t. PMM interleave settings. A starting point for more information: https://support.hpe.com/hpesc/public/docDisplay?docId=a00077643en_us&docLocale=en_US > > > + pr_attr("Part Number", "%s", dmi_string(h, data[0x1A])); > > + > > + if (h->length < 0x1C) break; > > + pr_attr("DIMM Index", "%d", data[0x1B]); > > + break; > > + > > case 203: > > /* > > * Vendor Specific: HP Device Correlation Record > > Thanks, > -- > Jean Delvare > SUSE L3 Support -- ----------------------------------------------------------------------------- Jerry Hoemann Software Engineer Hewlett Packard Enterprise -----------------------------------------------------------------------------