smbios.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // Copyright 2022 Google LLC
  3. // Author: Ard Biesheuvel <[email protected]>
  4. #include <linux/efi.h>
  5. #include "efistub.h"
  6. typedef struct efi_smbios_protocol efi_smbios_protocol_t;
  7. struct efi_smbios_protocol {
  8. efi_status_t (__efiapi *add)(efi_smbios_protocol_t *, efi_handle_t,
  9. u16 *, struct efi_smbios_record *);
  10. efi_status_t (__efiapi *update_string)(efi_smbios_protocol_t *, u16 *,
  11. unsigned long *, u8 *);
  12. efi_status_t (__efiapi *remove)(efi_smbios_protocol_t *, u16);
  13. efi_status_t (__efiapi *get_next)(efi_smbios_protocol_t *, u16 *, u8 *,
  14. struct efi_smbios_record **,
  15. efi_handle_t *);
  16. u8 major_version;
  17. u8 minor_version;
  18. };
  19. const struct efi_smbios_record *efi_get_smbios_record(u8 type)
  20. {
  21. struct efi_smbios_record *record;
  22. efi_smbios_protocol_t *smbios;
  23. efi_status_t status;
  24. u16 handle = 0xfffe;
  25. status = efi_bs_call(locate_protocol, &EFI_SMBIOS_PROTOCOL_GUID, NULL,
  26. (void **)&smbios) ?:
  27. efi_call_proto(smbios, get_next, &handle, &type, &record, NULL);
  28. if (status != EFI_SUCCESS)
  29. return NULL;
  30. return record;
  31. }
  32. const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
  33. u8 type, int offset, int recsize)
  34. {
  35. const u8 *strtable;
  36. if (!record)
  37. return NULL;
  38. strtable = (u8 *)record + record->length;
  39. for (int i = 1; i < ((u8 *)record)[offset]; i++) {
  40. int len = strlen(strtable);
  41. if (!len)
  42. return NULL;
  43. strtable += len + 1;
  44. }
  45. return strtable;
  46. }