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