On Mon, Nov 2, 2020 at 5:21 PM Christian Gmeiner <christian.gmei...@gmail.com> wrote: > > ping and a short question: would it make more sense to put the parsing > code into smbios.c and unconditionally compile it?
I think it's fine to leave this as a separte module. Reviewed-by: Bin Meng <bmeng...@gmail.com> But nits below: > > Am Mi., 7. Okt. 2020 um 14:33 Uhr schrieb Christian Gmeiner > <christian.gmei...@gmail.com>: > > > > Add an very simple API to be able to access SMBIOS strings an -> a > > like vendor, model and bios version. > > > > Signed-off-by: Christian Gmeiner <christian.gmei...@gmail.com> > > --- > > include/smbios.h | 27 +++++++++++++ > > lib/Kconfig | 6 +++ > > lib/Makefile | 1 + > > lib/smbios-parser.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ > > 4 files changed, 130 insertions(+) > > create mode 100644 lib/smbios-parser.c > > > > diff --git a/include/smbios.h b/include/smbios.h > > index 97b9ddce23..ed60c00fae 100644 > > --- a/include/smbios.h > > +++ b/include/smbios.h > > @@ -237,4 +237,31 @@ typedef int (*smbios_write_type)(ulong *addr, int > > handle); > > */ > > ulong write_smbios_table(ulong addr); > > > > +/** > > + * smbios_entry() - Get a vaild struct smbios_entry pointer typo: valid > > + * > > + * @address: address where smbios tables is located > > + * @size: size of smbios table > > + * @return: NULL or a valid pointer to a struct smbios_entry > > + */ > > +const struct smbios_entry *smbios_entry(u64 address, u32 size); > > + > > +/** > > + * smbios_header() - Search for SMBIOS header type > > + * > > + * @entry: pointer to a struct smbios_entry > > + * @type: SMBIOS type > > + * @return: NULL or a valid pointer to a struct smbios_header > > + */ > > +const struct smbios_header *smbios_header(const struct smbios_entry > > *entry, int type); > > + > > +/** > > + * smbios_string() - Return string from SMBIOS > > + * > > + * @header: pointer to struct smbios_header > > + * @index: string index > > + * @return: NULL or a valid const char pointer > > + */ > > +const char *smbios_string(const struct smbios_header *header, int index); > > + > > #endif /* _SMBIOS_H_ */ > > diff --git a/lib/Kconfig b/lib/Kconfig > > index 8efb154f73..c92131b7bc 100644 > > --- a/lib/Kconfig > > +++ b/lib/Kconfig > > @@ -667,6 +667,12 @@ config OID_REGISTRY > > help > > Enable fast lookup object identifier registry. > > > > +config SMBIOS_PARSER > > + bool "SMBIOS parser" > > + default n nits: remove default n, because it is Kconfig default > > + help > > + A simple parser for SMBIOS data. > > + > > source lib/efi/Kconfig > > source lib/efi_loader/Kconfig > > source lib/optee/Kconfig > > diff --git a/lib/Makefile b/lib/Makefile > > index 0cd7bea282..0383fddf2c 100644 > > --- a/lib/Makefile > > +++ b/lib/Makefile > > @@ -37,6 +37,7 @@ obj-$(CONFIG_FIT) += fdtdec_common.o > > obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o > > obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o > > obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o > > +obj-$(CONFIG_SMBIOS_PARSER) += smbios-parser.o > > obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o > > obj-y += ldiv.o > > obj-$(CONFIG_XXHASH) += xxhash.o > > diff --git a/lib/smbios-parser.c b/lib/smbios-parser.c > > new file mode 100644 > > index 0000000000..b89f988ef9 > > --- /dev/null > > +++ b/lib/smbios-parser.c > > @@ -0,0 +1,96 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * Copyright (C) 2020, Bachmann electronic GmbH > > + */ > > + > > +#include <common.h> > > +#include <smbios.h> > > + > > +static inline int verify_checksum(const struct smbios_entry *e) > > +{ > > + /* > > + * Checksums for SMBIOS tables are calculated to have a value, so > > that > > + * the sum over all bytes yields zero (using unsigned 8 bit > > arithmetic). > > + */ > > + u8 *byte = (u8 *)e; > > + u8 sum = 0; > > + > > + for (int i = 0; i < e->length; i++) > > + sum += byte[i]; > > + > > + return sum; > > +} > > + > > +const struct smbios_entry *smbios_entry(u64 address, u32 size) > > +{ > > + const struct smbios_entry *entry = (struct smbios_entry > > *)(uintptr_t)address; > > + > > + if (!address | !size) > > + return NULL; > > + > > + if (memcmp(entry->anchor, "_SM_", 4)) > > + return NULL; > > + > > + if (verify_checksum(entry)) > > + return NULL; > > + > > + return entry; > > +} > > + > > +static const struct smbios_header *next_header(const struct smbios_header > > *curr) > > +{ > > + u8 *pos = ((u8 *)curr) + curr->length; > > + > > + /* search for _double_ NULL bytes */ > > + while (!((*pos == 0) && (*(pos + 1) == 0))) > > + pos++; > > + > > + /* step behind the double NULL bytes */ > > + pos += 2; > > + > > + return (struct smbios_header *)pos; > > +} > > + > > +const struct smbios_header *smbios_header(const struct smbios_entry > > *entry, int type) > > +{ > > + const unsigned int num_header = entry->struct_count; > > + const struct smbios_header *header = (struct smbios_header > > *)entry->struct_table_address; > > + > > + for (unsigned int i = 0; i < num_header; i++) { > > + if (header->type == type) > > + return header; > > + > > + header = next_header(header); > > + } > > + > > + return NULL; > > +} > > + > > +static const char *string_from_smbios_table(const struct smbios_header > > *header, > > + int idx) > > +{ > > + unsigned int i = 1; > > + u8 *pos; > > + > > + if (!header) > > + return NULL; > > + > > + pos = ((u8 *)header) + header->length; > > + > > + while (i < idx) { > > + if (*pos == 0x0) > > + i++; > > + > > + pos++; > > + } > > + > > + return (const char *)pos; > > +} > > + > > +const char *smbios_string(const struct smbios_header *header, int index) > > +{ > > + if (!header) > > + return NULL; > > + > > + return string_from_smbios_table(header, index); > > +} > > -- > > 2.28.0 Regards, Bin