ping and a short question: would it make more sense to put the parsing code into smbios.c and unconditionally compile it?
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 > 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 > + * > + * @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 > + 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 > -- greets -- Christian Gmeiner, MSc https://christian-gmeiner.info/privacypolicy