// SPDX-License-Identifier: GPL-2.0-only
#include <linux/export.h>
#include <linux/bitops.h>
+#include <linux/dmi.h>
#include <linux/elf.h>
#include <linux/mm.h>
#include <linux/kvm_types.h>
return 0;
}
late_initcall(print_s5_reset_status_mmio);
+
+static void __init dmi_scan_additional(const struct dmi_header *d, void *p)
+{
+ struct dmi_a_info *info = (struct dmi_a_info *)d;
+ void *next, *end;
+
+ if (!IS_ENABLED(CONFIG_DMI))
+ return;
+
+ if (info->header.type != DMI_ENTRY_ADDITIONAL ||
+ info->header.length < DMI_A_INFO_MIN_SIZE ||
+ info->count < 1)
+ return;
+
+ next = (void *)(info + 1);
+ end = (void *)info + info->header.length;
+
+ do {
+ struct dmi_a_info_entry *entry;
+ const char *string_ptr;
+
+ entry = (struct dmi_a_info_entry *)next;
+
+ /*
+ * Not much can be done to validate data. At least the entry
+ * length shouldn't be 0.
+ */
+ if (!entry->length)
+ return;
+
+ string_ptr = dmi_string_nosave(&info->header, entry->str_num);
+
+ /* Sample string: AGESA!V9 StrixKrackanPI-FP8 1.1.0.0c */
+ if (!strncmp(string_ptr, "AGESA", 5)) {
+ pr_info("AGESA: %s\n", string_ptr);
+ break;
+ }
+
+ next += entry->length;
+ } while (end - next >= DMI_A_INFO_ENT_MIN_SIZE);
+}
+
+static __init int print_dmi_agesa(void)
+{
+ dmi_walk(dmi_scan_additional, NULL);
+ return 0;
+}
+late_initcall(print_dmi_agesa);
static int dmi_memdev_nr;
static int dmi_memdev_populated_nr __initdata;
-static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s)
+const char *dmi_string_nosave(const struct dmi_header *dm, u8 s)
{
const u8 *bp = ((u8 *) dm) + dm->length;
const u8 *nsp;
return dmi_empty_string;
}
+EXPORT_SYMBOL_GPL(dmi_string_nosave);
static const char * __init dmi_string(const struct dmi_header *dm, u8 s)
{
void *device_data; /* Type specific data */
};
+#define DMI_A_INFO_ENT_MIN_SIZE 0x6
+struct dmi_a_info_entry {
+ u8 length;
+ u16 handle;
+ u8 offset;
+ u8 str_num;
+ u8 value[];
+} __packed;
+
+#define DMI_A_INFO_MIN_SIZE 0xB
+struct dmi_a_info {
+ struct dmi_header header;
+ u8 count;
+} __packed;
+
#ifdef CONFIG_DMI
struct dmi_dev_onboard {
extern u64 dmi_memdev_size(u16 handle);
extern u8 dmi_memdev_type(u16 handle);
extern u16 dmi_memdev_handle(int slot);
+const char *dmi_string_nosave(const struct dmi_header *dm, u8 s);
#else
static inline u16 dmi_memdev_handle(int slot) { return 0xffff; }
static inline const struct dmi_system_id *
dmi_first_match(const struct dmi_system_id *list) { return NULL; }
+static inline const char *
+ dmi_string_nosave(const struct dmi_header *dm, u8 s) { return ""; }
#endif