1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
/* SPDX-License-Identifier: GPL-2.0-only */
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <commonlib/helpers.h>
#include <uuid.h>
#include <console/console.h>
#include <device/device.h>
#include <device/i2c_bus.h>
#include <smbios.h>
#include "eeprom.h"
#define MAX_STRING_LENGTH UUID_STRLEN
static struct device *eeprom;
static const char *eeprom_read_string(const enum bx26_strings idx)
{
static char str[MAX_STRING_LENGTH + 1];
if (!eeprom) {
printk(BIOS_WARNING, "DMI: Serial EEPROM not found\n");
str[0] = '\0';
return str;
}
const size_t offset = bx26_locations[idx].offset;
const size_t length = MIN(bx26_locations[idx].length, MAX_STRING_LENGTH);
if (i2c_dev_read_at16(eeprom, (u8 *)str, length, offset) != length) {
printk(BIOS_WARNING, "DMI: Failed to read serial EEPROM\n");
str[0] = '\0';
} else {
unsigned int i;
/* Terminate at first non-printable character. */
for (i = 0; i < length; ++i) {
if (!isprint(str[i]))
break;
}
str[i] = '\0';
}
return str;
}
const char *smbios_system_manufacturer(void)
{
return eeprom_read_string(SYSTEM_MANUFACTURER);
}
const char *smbios_system_product_name(void)
{
return eeprom_read_string(SYSTEM_PRODUCT_NAME);
}
const char *smbios_system_serial_number(void)
{
return eeprom_read_string(SYSTEM_SERIAL_NUMBER);
}
const char *smbios_system_version(void)
{
return eeprom_read_string(SYSTEM_VERSION);
}
void smbios_system_set_uuid(u8 *const uuid)
{
if (parse_uuid(uuid, eeprom_read_string(SYSTEM_UUID))) {
printk(BIOS_WARNING, "DMI: Cannot parse UUID\n");
memset(uuid, 0x00, UUID_LEN);
}
}
const char *smbios_mainboard_serial_number(void)
{
return eeprom_read_string(BOARD_SERIAL_NUMBER);
}
const char *smbios_mainboard_version(void)
{
return eeprom_read_string(BOARD_VERSION);
}
static void enable_dev(struct device *dev)
{
if (dev->path.type != DEVICE_PATH_I2C || (dev->path.i2c.device & 0xf0) != 0x50)
return;
eeprom = dev;
}
struct chip_operations drivers_secunet_dmi_ops = {
.name = "secunet DMI",
.enable_dev = enable_dev,
};
|