[U-Boot] [PATCH 1/2] smbios: add parsing API
Alexander Graf
agraf at csgraf.de
Mon Apr 29 15:35:42 UTC 2019
On 29.04.19 16:29, Christian Gmeiner wrote:
> Hi
>
> Am Do., 25. Apr. 2019 um 12:09 Uhr schrieb Alexander Graf <agraf at csgraf.de>:
>>
>> On 16.04.19 13:38, Christian Gmeiner wrote:
>>> Add an very simple API to be able to access SMBIOS strings
>>> like vendor, model and bios version.
>>>
>>> Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
>>> ---
>>> include/smbios.h | 37 ++++++++++
>>> lib/Kconfig | 6 ++
>>> lib/Makefile | 1 +
>>> lib/smbios-parser.c | 162 ++++++++++++++++++++++++++++++++++++++++++++
>>> 4 files changed, 206 insertions(+)
>>> create mode 100644 lib/smbios-parser.c
>>>
>>> diff --git a/include/smbios.h b/include/smbios.h
>>> index 97b9ddce23..ad44e54245 100644
>>> --- a/include/smbios.h
>>> +++ b/include/smbios.h
>>> @@ -237,4 +237,41 @@ typedef int (*smbios_write_type)(ulong *addr, int handle);
>>> */
>>> ulong write_smbios_table(ulong addr);
>>>
>>> +
>>> +struct smbios_parser;
>>> +
>>> +/**
>>> + * smbios_parser_create() - Create smbios parser
>>> + *
>>> + * @addr: start address to search for SMBIOS structure
>>> + * @len: size of search area
>>> + * @return: NULL or valid pointer to a struct smbios_parser
>>> + */
>>> +struct smbios_parser *smbios_parser_create(unsigned int addr, unsigned int len);
>>> +
>>> +/**
>>> + * smbios_parser_destroy() - Destroy smbios parser
>>> + *
>>> + * @p: pointer to a struct smbios_parser
>>> + */
>>> +void smbios_parser_destroy(struct smbios_parser *p);
>>> +
>>> +/**
>>> + * smbios_header() - Search for SMBIOS header type
>>> + *
>>> + * @p: pointer to a struct smbios_parser
>>> + * @type: SMBIOS type
>>> + * @return: NULL or a valid pointer to a struct smbios_header
>>> + */
>>> +struct smbios_header *smbios_header(const struct smbios_parser *p, 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 2120216593..59aafc63a7 100644
>>> --- a/lib/Kconfig
>>> +++ b/lib/Kconfig
>>> @@ -432,6 +432,12 @@ config SMBIOS_PRODUCT_NAME
>>>
>>> endmenu
>>>
>>> +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 47829bfed5..f095bd420a 100644
>>> --- a/lib/Makefile
>>> +++ b/lib/Makefile
>>> @@ -34,6 +34,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_MD5) += md5.o
>>> diff --git a/lib/smbios-parser.c b/lib/smbios-parser.c
>>> new file mode 100644
>>> index 0000000000..b24fd7210c
>>> --- /dev/null
>>> +++ b/lib/smbios-parser.c
>>> @@ -0,0 +1,162 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (C) 2019, Bachmann electronic GmbH
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <malloc.h>
>>> +#include <mapmem.h>
>>> +#include <smbios.h>
>>> +
>>> +struct smbios_parser {
>>> + void *search_area;
>>> + unsigned int search_area_len;
>>> + struct smbios_entry *entry;
>>> + void *data;
>>> +};
>>> +
>>> +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;
>>> +}
>>> +
>>> +static struct smbios_entry *find_smbios_entry(const struct smbios_parser *p)
>>> +{
>>> + static const char sm_sig[] = "_SM_";
>>> + u8 *buf = (u8 *)p->search_area;
>>> + const u8 *end = (u8 *)p->search_area + p->search_area_len;
>>> + struct smbios_entry *entry = NULL;
>>> +
>>> + /* look for smbios entry */
>>> + while (buf < end) {
>>
>> Don't you have a way to pass the DMI pointer directly, maybe using cbfs?
>> Searching through the SMBIOS search area is so 1990s (and pretty much
>> only works on x86).
>>
> Coreboot adds a smbios cbmem entry which can be used to get the base address.
> Will make use of that mechanism in the next version of the patch set.
Thanks, that will make this code a lot more robust :).
>
>> I also don't think we really need all the smbios_parser logic. No need
>> to create special pseudo objects. IMHO you should either create an
>> actual UCLASS for SMBIOS with genuine callbacks and expose the table as
>> DM object or just make all search functions in this patch stateless. I'd
>> opt for the latter - it's how the SMBIOS creation works too.
>>
> I am not sure what you mean with 'special pseudo objects' - struct
> smbios_parser?
Yes. The parser is stateful. I would ideally like it best if it wasn't :).
Alex
More information about the U-Boot
mailing list