blob: 5dfbb5d8b7a5a74c97735b69eb5a1ed786ac368f [file] [log] [blame]
Nico Huber34d80362019-10-24 15:14:42 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2017 secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <stdint.h>
17#include <string.h>
18#include <ctype.h>
19#include <commonlib/helpers.h>
20#include <uuid.h>
21#include <console/console.h>
22#include <device/device.h>
23#include <device/i2c_bus.h>
24#include <smbios.h>
25
26#include "eeprom.h"
27
28#define MAX_STRING_LENGTH UUID_STRLEN
29
30static struct device *eeprom;
31
32static const char *eeprom_read_string(const enum bx26_strings idx)
33{
34 static char str[MAX_STRING_LENGTH + 1];
35
36 if (!eeprom) {
37 printk(BIOS_WARNING, "DMI: Serial EEPROM not found\n");
38 str[0] = '\0';
39 return str;
40 }
41
42 const size_t offset = bx26_locations[idx].offset;
43 const size_t length = MIN(bx26_locations[idx].length, MAX_STRING_LENGTH);
44
45 if (i2c_dev_read_at16(eeprom, (u8 *)str, length, offset) != length) {
46 printk(BIOS_WARNING, "DMI: Failed to read serial EEPROM\n");
47 str[0] = '\0';
48 } else {
49 unsigned int i;
50 /* Terminate at first non-printable character. */
51 for (i = 0; i < length; ++i) {
52 if (!isprint(str[i]))
53 break;
54 }
55 str[i] = '\0';
56 }
57
58 return str;
59}
60
61const char *smbios_system_manufacturer(void)
62{
63 return eeprom_read_string(SYSTEM_MANUFACTURER);
64}
65
66const char *smbios_system_product_name(void)
67{
68 return eeprom_read_string(SYSTEM_PRODUCT_NAME);
69}
70
71const char *smbios_system_serial_number(void)
72{
73 return eeprom_read_string(SYSTEM_SERIAL_NUMBER);
74}
75
76const char *smbios_system_version(void)
77{
78 return eeprom_read_string(SYSTEM_VERSION);
79}
80
81void smbios_system_set_uuid(u8 *const uuid)
82{
83 if (parse_uuid(uuid, eeprom_read_string(SYSTEM_UUID))) {
84 printk(BIOS_WARNING, "DMI: Cannot parse UUID\n");
85 memset(uuid, 0x00, UUID_LEN);
86 }
87}
88
89const char *smbios_mainboard_serial_number(void)
90{
91 return eeprom_read_string(BOARD_SERIAL_NUMBER);
92}
93
94const char *smbios_mainboard_version(void)
95{
96 return eeprom_read_string(BOARD_VERSION);
97}
98
99static void enable_dev(struct device *dev)
100{
101 if (dev->path.type != DEVICE_PATH_I2C || (dev->path.i2c.device & 0xf0) != 0x50)
102 return;
103 eeprom = dev;
104}
105
106struct chip_operations drivers_secunet_dmi_ops = {
107 CHIP_NAME("secunet DMI")
108 .enable_dev = enable_dev,
109};