[U-Boot] [PATCH 5/7] smbios: Expose in efi_loader as table

Simon Glass sjg at chromium.org
Wed Aug 17 06:15:56 CEST 2016


Hi Alex,

On 16 August 2016 at 02:38, Alexander Graf <agraf at suse.de> wrote:
> On 08/12/2016 10:07 PM, Simon Glass wrote:
>>
>> Hi Alex,
>>
>> On 12 August 2016 at 12:36, Alexander Graf <agraf at suse.de> wrote:
>>>
>>>
>>> On 12.08.16 19:20, Simon Glass wrote:
>>>>
>>>> Hi Alex,
>>>>
>>>> On 8 August 2016 at 08:06, Alexander Graf <agraf at suse.de> wrote:
>>>>>
>>>>> We can pass SMBIOS easily as EFI configuration table to an EFI payload.
>>>>> This
>>>>> patch adds enablement for that case.
>>>>>
>>>>> While at it, we also enable SMBIOS generation for ARM systems, since
>>>>> they support
>>>>> EFI_LOADER.
>>>>>
>>>>> Signed-off-by: Alexander Graf <agraf at suse.de>
>>>>> ---
>>>>>   cmd/bootefi.c        |  3 +++
>>>>>   include/efi_api.h    |  4 ++++
>>>>>   include/efi_loader.h |  2 ++
>>>>>   include/smbios.h     |  1 +
>>>>>   lib/Kconfig          |  4 ++--
>>>>>   lib/smbios.c         | 36 ++++++++++++++++++++++++++++++++++++
>>>>>   6 files changed, 48 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/cmd/bootefi.c b/cmd/bootefi.c
>>>>> index 53a6ee3..e241b7d 100644
>>>>> --- a/cmd/bootefi.c
>>>>> +++ b/cmd/bootefi.c
>>>>> @@ -205,6 +205,9 @@ static unsigned long do_bootefi_exec(void *efi,
>>>>> void *fdt)
>>>>>          if (!memcmp(bootefi_device_path[0].str, "N\0e\0t", 6))
>>>>>                  loaded_image_info.device_handle = nethandle;
>>>>>   #endif
>>>>> +#ifdef CONFIG_GENERATE_SMBIOS_TABLE
>>>>> +       efi_smbios_register();
>>>>> +#endif
>>>>>
>>>>>          /* Initialize EFI runtime services */
>>>>>          efi_reset_system_init();
>>>>> diff --git a/include/efi_api.h b/include/efi_api.h
>>>>> index f572b88..bdb600e 100644
>>>>> --- a/include/efi_api.h
>>>>> +++ b/include/efi_api.h
>>>>> @@ -201,6 +201,10 @@ struct efi_runtime_services {
>>>>>          EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, \
>>>>>                   0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
>>>>>
>>>>> +#define SMBIOS_TABLE_GUID \
>>>>> +       EFI_GUID(0xeb9d2d31, 0x2d88, 0x11d3,  \
>>>>> +                0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
>>>>> +
>>>>>   struct efi_configuration_table
>>>>>   {
>>>>>          efi_guid_t guid;
>>>>> diff --git a/include/efi_loader.h b/include/efi_loader.h
>>>>> index ac8b77a..b0e8a7f 100644
>>>>> --- a/include/efi_loader.h
>>>>> +++ b/include/efi_loader.h
>>>>> @@ -85,6 +85,8 @@ int efi_disk_register(void);
>>>>>   int efi_gop_register(void);
>>>>>   /* Called by bootefi to make the network interface available */
>>>>>   int efi_net_register(void **handle);
>>>>> +/* Called by bootefi to make SMBIOS tables available */
>>>>> +void efi_smbios_register(void);
>>>>>
>>>>>   /* Called by networking code to memorize the dhcp ack package */
>>>>>   void efi_net_set_dhcp_ack(void *pkt, int len);
>>>>> diff --git a/include/smbios.h b/include/smbios.h
>>>>> index 5962d4c..fb6396a 100644
>>>>> --- a/include/smbios.h
>>>>> +++ b/include/smbios.h
>>>>> @@ -55,6 +55,7 @@ struct __packed smbios_entry {
>>>>>   #define BIOS_CHARACTERISTICS_SELECTABLE_BOOT   (1 << 16)
>>>>>
>>>>>   #define BIOS_CHARACTERISTICS_EXT1_ACPI         (1 << 0)
>>>>> +#define BIOS_CHARACTERISTICS_EXT1_UEFI         (1 << 3)
>>>>>   #define BIOS_CHARACTERISTICS_EXT2_TARGET       (1 << 2)
>>>>>
>>>>>   struct __packed smbios_type0 {
>>>>> diff --git a/lib/Kconfig b/lib/Kconfig
>>>>> index 5a14530..d7f75fe 100644
>>>>> --- a/lib/Kconfig
>>>>> +++ b/lib/Kconfig
>>>>> @@ -150,12 +150,12 @@ config SPL_OF_LIBFDT
>>>>>            version of the device tree.
>>>>>
>>>>>   menu "System tables"
>>>>> -       depends on !EFI && !SYS_COREBOOT
>>>>> +       depends on (!EFI && !SYS_COREBOOT) || (ARM && EFI_LOADER)
>>>>>
>>>>>   config GENERATE_SMBIOS_TABLE
>>>>>          bool "Generate an SMBIOS (System Management BIOS) table"
>>>>>          default y
>>>>> -       depends on X86
>>>>> +       depends on X86 || EFI_LOADER
>>>>>          help
>>>>>            The System Management BIOS (SMBIOS) specification addresses
>>>>> how
>>>>>            motherboard and system vendors present management
>>>>> information about
>>>>> diff --git a/lib/smbios.c b/lib/smbios.c
>>>>> index 8dfd486..b9aa741 100644
>>>>> --- a/lib/smbios.c
>>>>> +++ b/lib/smbios.c
>>>>> @@ -7,10 +7,13 @@
>>>>>    */
>>>>>
>>>>>   #include <common.h>
>>>>> +#include <efi_loader.h>
>>>>>   #include <smbios.h>
>>>>>   #include <tables_csum.h>
>>>>>   #include <version.h>
>>>>> +#ifdef CONFIG_X86
>>>>>   #include <asm/cpu.h>
>>>>> +#endif
>>>>>
>>>>>   DECLARE_GLOBAL_DATA_PTR;
>>>>>
>>>>> @@ -79,14 +82,20 @@ static int smbios_write_type0(uintptr_t *current,
>>>>> int handle)
>>>>>          t->vendor = smbios_add_string(t->eos, "U-Boot");
>>>>>          t->bios_ver = smbios_add_string(t->eos, PLAIN_VERSION);
>>>>>          t->bios_release_date = smbios_add_string(t->eos,
>>>>> U_BOOT_DMI_DATE);
>>>>> +#ifdef CONFIG_ROM_SIZE
>>>>>          t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1;
>>>>> +#endif
>>>>>          t->bios_characteristics = BIOS_CHARACTERISTICS_PCI_SUPPORTED |
>>>>>                                    BIOS_CHARACTERISTICS_SELECTABLE_BOOT
>>>>> |
>>>>>                                    BIOS_CHARACTERISTICS_UPGRADEABLE;
>>>>>   #ifdef CONFIG_GENERATE_ACPI_TABLE
>>>>>          t->bios_characteristics_ext1 = BIOS_CHARACTERISTICS_EXT1_ACPI;
>>>>>   #endif
>>>>> +#ifdef CONFIG_EFI_LOADER
>>>>> +       t->bios_characteristics_ext1 |= BIOS_CHARACTERISTICS_EXT1_UEFI;
>>>>> +#endif
>>>>>          t->bios_characteristics_ext2 =
>>>>> BIOS_CHARACTERISTICS_EXT2_TARGET;
>>>>> +
>>>>>          t->bios_major_release = 0xff;
>>>>>          t->bios_minor_release = 0xff;
>>>>>          t->ec_major_release = 0xff;
>>>>> @@ -152,6 +161,7 @@ static int smbios_write_type3(uintptr_t *current,
>>>>> int handle)
>>>>>          return len;
>>>>>   }
>>>>>
>>>>> +#ifdef CONFIG_X86
>>>>>   static int smbios_write_type4(uintptr_t *current, int handle)
>>>>>   {
>>>>>          struct smbios_type4 *t = (struct smbios_type4 *)*current;
>>>>> @@ -184,6 +194,7 @@ static int smbios_write_type4(uintptr_t *current,
>>>>> int handle)
>>>>>
>>>>>          return len;
>>>>>   }
>>>>> +#endif
>>>>>
>>>>>   static int smbios_write_type32(uintptr_t *current, int handle)
>>>>>   {
>>>>> @@ -216,7 +227,9 @@ static smbios_write_type smbios_write_funcs[] = {
>>>>>          smbios_write_type1,
>>>>>          smbios_write_type2,
>>>>>          smbios_write_type3,
>>>>> +#ifdef CONFIG_X86
>>>>
>>>> This should become a parameter I think. Since you are making this into
>>>> generic code, it should avoid arch-specific #ifdefs.
>>>
>>> The type4 table really contains x86 cpu specific information, so I
>>> figured an #ifdef CONFIG_X86 makes the most sense here.
>>>
>>> Looking at
>>>
>>>
>>>
>>> https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf
>>>
>>> I guess you *could* put one in that addresses ARM as well. Looking at
>>> example output from a ThunderX system, that seems to be what other
>>> vendors do:
>>>
>>> Handle 0x0004, DMI type 4, 48 bytes
>>> Processor Information
>>>          Socket Designation: CPU 0
>>>          Type: Central Processor
>>>          Family: Other
>>>          Manufacturer: www.cavium.com
>>>          ID: 00 00 00 00 00 00 00 00
>>>          Version: 2.0
>>>          Voltage: 3.3 V
>>>          External Clock: 156 MHz
>>>          Max Speed: 2000 MHz
>>>          Current Speed: 2000 MHz
>>>          Status: Populated, Enabled
>>>          Upgrade: Other
>>>          L1 Cache Handle: 0x0080
>>>          L2 Cache Handle: 0x0082
>>>          L3 Cache Handle: 0x0007
>>>          Serial Number: 1.0
>>>          Asset Tag: 1.0
>>>          Part Number: [...]
>>>          Core Count: 48
>>>          Core Enabled: 48
>>>          Thread Count: 1
>>>          Characteristics: None
>>>
>>> So what we really need is a rename for smbios_write_type4 to
>>> smbios_write_type4_x86 which then is still surrounded by the #ifdef
>>> CONFIG_X86. We could just simply add another one for arm if we want to
>>> ;).
>>
>>  From what I can see, the problem is the cpu_get_name() call. Is that
>> right? If so, that could move to the CPU uclass and use cpu_get_info()
>> (with the name added as a new field) or perhaps a new cpu_get_name()
>> call.
>
>
> I see what you're aiming for, but I just fail to see how we could properly
> abstract away CPU specific information - and I don't think it's terribly
> useful either. I've refactored the code to be slightly more pretty now, but
> I really don't think that we should depend on CONFIG_CPU or introduce new

All you are getting here is the same and the processor ID, I think. It
is not hard to do what you need in the cpu uclass.

Please don't introduce this sort of cruft in what is now generic code.
You can make EFI_LOADER depend on CPU or you can put an #ifdef
CONFIG_CPU here, but what you have is just going to create a mess as
more things are added to it. Given that we have a defined CPU
interface, it is also unnecessary. With a little more effort you can
come to a nice solution.

> calls for every bit:
>
> static void smbios_write_type4_arch(struct smbios_type4 *t)
> {
>         u16 processor_family = SMBIOS_PROCESSOR_FAMILY_UNKNOWN;
>         const char *vendor = "Unknown";
>         char *name = "Unknown";
>
> #ifdef CONFIG_X86
>         char processor_name[CPU_MAX_NAME_LEN];
>         struct cpuid_result res;
>
>         processor_family = gd->arch.x86;
>         vendor = cpu_vendor_name(gd->arch.x86_vendor);
>         res = cpuid(1);
>         t->processor_id[0] = res.eax;
>         t->processor_id[1] = res.edx;
>         name = cpu_get_name(processor_name);
> #elif defined(CONFIG_ARM)
>         processor_family = SMBIOS_PROCESSOR_FAMILY_OTHER;
>         vendor = "ARM";
> #endif
>
>         t->processor_family = processor_family;
>         t->processor_manufacturer = smbios_add_string(t->eos, vendor);
>         t->processor_version = smbios_add_string(t->eos, name);
> }
>
>
> Alex
>

Regards,
Simon


More information about the U-Boot mailing list