Message ID | 20201022141949.711984-4-sjg@chromium.org |
---|---|
State | Superseded |
Delegated to: | Bin Meng |
Headers | show |
Series | x86: Updates to SMBIOS | expand |
Hi Simon, On Thu, Oct 22, 2020 at 10:21 PM Simon Glass <sjg@chromium.org> wrote: > > Support a way to put SMBIOS properties in the device tree. These can be > placed in a 'board' device in an 'smbios' subnode. > > Signed-off-by: Simon Glass <sjg@chromium.org> > --- > > Changes in v4: > - Fix build error with vexpress_ca9x4 > > Changes in v3: > - Use a different binding with subnodes for each table type > > lib/smbios.c | 98 +++++++++++++++++++++++++++++++++++++++++++--------- > 1 file changed, 81 insertions(+), 17 deletions(-) > > diff --git a/lib/smbios.c b/lib/smbios.c > index b0f5e936044..be72a98c49d 100644 > --- a/lib/smbios.c > +++ b/lib/smbios.c > @@ -17,6 +17,18 @@ > #include <dm/uclass-internal.h> > #endif > > +/** > + * struct smbios_write_method - Informaiton about a table-writing function typo: Information > + * > + * @write: Function to call > + * @subnode_name: Name of subnode which has the information for this function, > + * NULL if none > + */ > +struct smbios_write_method { > + smbios_write_type write; > + const char *subnode_name; > +}; > + > /** > * smbios_add_string() - add a string to the string area > * > @@ -52,6 +64,43 @@ static int smbios_add_string(char *start, const char *str) > } > } > > +/** > + * smbios_add_prop_default() - Add a property from the device tree or default > + * > + * @start: string area start address > + * @node: node containing the information to write (ofnode_null() if none) > + * @prop: property to write > + * @def: default string if the node has no such property > + * @return 0 if not found, else SMBIOS string number (1 or more) > + */ > +static int smbios_add_prop_default(char *start, ofnode node, const char *prop, > + const char *def) > +{ > + const char *str = NULL; > + > + if (IS_ENABLED(CONFIG_OF_CONTROL)) > + str = ofnode_read_string(node, prop); > + if (str) > + return smbios_add_string(start, str); > + else if (def) > + return smbios_add_string(start, def); > + > + return 0; > +} > + > +/** > + * smbios_add_prop() - Add a property from the device tree > + * > + * @start: string area start address > + * @node: node containing the information to write (ofnode_null() if none) > + * @prop: property to write > + * @return 0 if not found, else SMBIOS string number (1 or more) > + */ > +static int smbios_add_prop(char *start, ofnode node, const char *prop) > +{ > + return smbios_add_prop_default(start, node, prop, NULL); > +} > + > /** > * smbios_string_table_len() - compute the string area size > * > @@ -120,11 +169,15 @@ static int smbios_write_type1(ulong *current, int handle, ofnode node) > t = map_sysmem(*current, len); > memset(t, 0, sizeof(struct smbios_type1)); > fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle); > - t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER); > - t->product_name = smbios_add_string(t->eos, CONFIG_SMBIOS_PRODUCT_NAME); > + t->manufacturer = smbios_add_prop_default(t->eos, node, "manufactuer", typo: manufacturer > + CONFIG_SMBIOS_MANUFACTURER); > + t->product_name = smbios_add_prop_default(t->eos, node, "product", > + CONFIG_SMBIOS_PRODUCT_NAME); > if (serial_str) { > - strncpy((char *)t->uuid, serial_str, sizeof(t->uuid)); > t->serial_number = smbios_add_string(t->eos, serial_str); > + strncpy((char *)t->uuid, serial_str, sizeof(t->uuid)); > + } else { > + t->serial_number = smbios_add_prop(t->eos, node, "serial"); > } > > len = t->length + smbios_string_table_len(t->eos); > @@ -142,8 +195,10 @@ static int smbios_write_type2(ulong *current, int handle, ofnode node) > t = map_sysmem(*current, len); > memset(t, 0, sizeof(struct smbios_type2)); > fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle); > - t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER); > - t->product_name = smbios_add_string(t->eos, CONFIG_SMBIOS_PRODUCT_NAME); > + t->manufacturer = smbios_add_prop_default(t->eos, node, "manufactuer", ditto > + CONFIG_SMBIOS_MANUFACTURER); > + t->product_name = smbios_add_prop_default(t->eos, node, "product", > + CONFIG_SMBIOS_PRODUCT_NAME); > t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING; > t->board_type = SMBIOS_BOARD_MOTHERBOARD; > > @@ -162,7 +217,8 @@ static int smbios_write_type3(ulong *current, int handle, ofnode node) > t = map_sysmem(*current, len); > memset(t, 0, sizeof(struct smbios_type3)); > fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle); > - t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER); > + t->manufacturer = smbios_add_prop_default(t->eos, node, "manufactuer", ditto > + CONFIG_SMBIOS_MANUFACTURER); > t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP; > t->bootup_state = SMBIOS_STATE_SAFE; > t->power_supply_state = SMBIOS_STATE_SAFE; > @@ -262,19 +318,19 @@ static int smbios_write_type127(ulong *current, int handle, ofnode node) > return len; > } > > -static smbios_write_type smbios_write_funcs[] = { > - smbios_write_type0, > - smbios_write_type1, > - smbios_write_type2, > - smbios_write_type3, > - smbios_write_type4, > - smbios_write_type32, > - smbios_write_type127 > +static struct smbios_write_method smbios_write_funcs[] = { > + { smbios_write_type0, }, > + { smbios_write_type1, "system", }, > + { smbios_write_type2, "baseboard", }, > + { smbios_write_type3, "chassis", }, > + { smbios_write_type4, }, > + { smbios_write_type32, }, > + { smbios_write_type127 }, > }; > > ulong write_smbios_table(ulong addr) > { > - ofnode node = ofnode_null(); > + ofnode parent_node = ofnode_null(); > struct smbios_entry *se; > struct udevice *dev; > ulong table_addr; > @@ -289,7 +345,7 @@ ulong write_smbios_table(ulong addr) > if (IS_ENABLED(CONFIG_OF_CONTROL)) { > uclass_first_device(UCLASS_SYSINFO, &dev); > if (dev) > - node = dev_read_subnode(dev, "smbios"); > + parent_node = dev_read_subnode(dev, "smbios"); > } > > /* 16 byte align the table address */ > @@ -304,7 +360,15 @@ ulong write_smbios_table(ulong addr) > > /* populate minimum required tables */ > for (i = 0; i < ARRAY_SIZE(smbios_write_funcs); i++) { > - int tmp = smbios_write_funcs[i]((ulong *)&addr, handle++, node); > + const struct smbios_write_method *method; > + ofnode node = ofnode_null(); > + int tmp; > + > + method = &smbios_write_funcs[i]; > + if (IS_ENABLED(CONFIG_OF_CONTROL) && method->subnode_name) > + node = ofnode_find_subnode(parent_node, > + method->subnode_name); > + tmp = method->write((ulong *)&addr, handle++, node); > > max_struct_size = max(max_struct_size, tmp); > len += tmp; > -- Regards, Bin
diff --git a/lib/smbios.c b/lib/smbios.c index b0f5e936044..be72a98c49d 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -17,6 +17,18 @@ #include <dm/uclass-internal.h> #endif +/** + * struct smbios_write_method - Informaiton about a table-writing function + * + * @write: Function to call + * @subnode_name: Name of subnode which has the information for this function, + * NULL if none + */ +struct smbios_write_method { + smbios_write_type write; + const char *subnode_name; +}; + /** * smbios_add_string() - add a string to the string area * @@ -52,6 +64,43 @@ static int smbios_add_string(char *start, const char *str) } } +/** + * smbios_add_prop_default() - Add a property from the device tree or default + * + * @start: string area start address + * @node: node containing the information to write (ofnode_null() if none) + * @prop: property to write + * @def: default string if the node has no such property + * @return 0 if not found, else SMBIOS string number (1 or more) + */ +static int smbios_add_prop_default(char *start, ofnode node, const char *prop, + const char *def) +{ + const char *str = NULL; + + if (IS_ENABLED(CONFIG_OF_CONTROL)) + str = ofnode_read_string(node, prop); + if (str) + return smbios_add_string(start, str); + else if (def) + return smbios_add_string(start, def); + + return 0; +} + +/** + * smbios_add_prop() - Add a property from the device tree + * + * @start: string area start address + * @node: node containing the information to write (ofnode_null() if none) + * @prop: property to write + * @return 0 if not found, else SMBIOS string number (1 or more) + */ +static int smbios_add_prop(char *start, ofnode node, const char *prop) +{ + return smbios_add_prop_default(start, node, prop, NULL); +} + /** * smbios_string_table_len() - compute the string area size * @@ -120,11 +169,15 @@ static int smbios_write_type1(ulong *current, int handle, ofnode node) t = map_sysmem(*current, len); memset(t, 0, sizeof(struct smbios_type1)); fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle); - t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER); - t->product_name = smbios_add_string(t->eos, CONFIG_SMBIOS_PRODUCT_NAME); + t->manufacturer = smbios_add_prop_default(t->eos, node, "manufactuer", + CONFIG_SMBIOS_MANUFACTURER); + t->product_name = smbios_add_prop_default(t->eos, node, "product", + CONFIG_SMBIOS_PRODUCT_NAME); if (serial_str) { - strncpy((char *)t->uuid, serial_str, sizeof(t->uuid)); t->serial_number = smbios_add_string(t->eos, serial_str); + strncpy((char *)t->uuid, serial_str, sizeof(t->uuid)); + } else { + t->serial_number = smbios_add_prop(t->eos, node, "serial"); } len = t->length + smbios_string_table_len(t->eos); @@ -142,8 +195,10 @@ static int smbios_write_type2(ulong *current, int handle, ofnode node) t = map_sysmem(*current, len); memset(t, 0, sizeof(struct smbios_type2)); fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle); - t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER); - t->product_name = smbios_add_string(t->eos, CONFIG_SMBIOS_PRODUCT_NAME); + t->manufacturer = smbios_add_prop_default(t->eos, node, "manufactuer", + CONFIG_SMBIOS_MANUFACTURER); + t->product_name = smbios_add_prop_default(t->eos, node, "product", + CONFIG_SMBIOS_PRODUCT_NAME); t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING; t->board_type = SMBIOS_BOARD_MOTHERBOARD; @@ -162,7 +217,8 @@ static int smbios_write_type3(ulong *current, int handle, ofnode node) t = map_sysmem(*current, len); memset(t, 0, sizeof(struct smbios_type3)); fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle); - t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER); + t->manufacturer = smbios_add_prop_default(t->eos, node, "manufactuer", + CONFIG_SMBIOS_MANUFACTURER); t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP; t->bootup_state = SMBIOS_STATE_SAFE; t->power_supply_state = SMBIOS_STATE_SAFE; @@ -262,19 +318,19 @@ static int smbios_write_type127(ulong *current, int handle, ofnode node) return len; } -static smbios_write_type smbios_write_funcs[] = { - smbios_write_type0, - smbios_write_type1, - smbios_write_type2, - smbios_write_type3, - smbios_write_type4, - smbios_write_type32, - smbios_write_type127 +static struct smbios_write_method smbios_write_funcs[] = { + { smbios_write_type0, }, + { smbios_write_type1, "system", }, + { smbios_write_type2, "baseboard", }, + { smbios_write_type3, "chassis", }, + { smbios_write_type4, }, + { smbios_write_type32, }, + { smbios_write_type127 }, }; ulong write_smbios_table(ulong addr) { - ofnode node = ofnode_null(); + ofnode parent_node = ofnode_null(); struct smbios_entry *se; struct udevice *dev; ulong table_addr; @@ -289,7 +345,7 @@ ulong write_smbios_table(ulong addr) if (IS_ENABLED(CONFIG_OF_CONTROL)) { uclass_first_device(UCLASS_SYSINFO, &dev); if (dev) - node = dev_read_subnode(dev, "smbios"); + parent_node = dev_read_subnode(dev, "smbios"); } /* 16 byte align the table address */ @@ -304,7 +360,15 @@ ulong write_smbios_table(ulong addr) /* populate minimum required tables */ for (i = 0; i < ARRAY_SIZE(smbios_write_funcs); i++) { - int tmp = smbios_write_funcs[i]((ulong *)&addr, handle++, node); + const struct smbios_write_method *method; + ofnode node = ofnode_null(); + int tmp; + + method = &smbios_write_funcs[i]; + if (IS_ENABLED(CONFIG_OF_CONTROL) && method->subnode_name) + node = ofnode_find_subnode(parent_node, + method->subnode_name); + tmp = method->write((ulong *)&addr, handle++, node); max_struct_size = max(max_struct_size, tmp); len += tmp;
Support a way to put SMBIOS properties in the device tree. These can be placed in a 'board' device in an 'smbios' subnode. Signed-off-by: Simon Glass <sjg@chromium.org> --- Changes in v4: - Fix build error with vexpress_ca9x4 Changes in v3: - Use a different binding with subnodes for each table type lib/smbios.c | 98 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 17 deletions(-)