drivers/secunet: Add driver to read DMI info from I2C EEPROM
The EEPROM layout is rather arbitrary and /just happened/. It needs a 256kbit part at least. Change-Id: Iae5c9138e8404acfc3a43dc2c7b55d47d4147060 Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/36298 Reviewed-by: Patrick Georgi <pgeorgi@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
dafcc7a26d
commit
34d8036333
|
@ -0,0 +1,3 @@
|
||||||
|
config SECUNET_DMI
|
||||||
|
bool
|
||||||
|
select SMBIOS_PROVIDED_BY_MOBO
|
|
@ -0,0 +1 @@
|
||||||
|
ramstage-$(CONFIG_SECUNET_DMI) += smbios.c
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SECUNET_DMI_EEPROM_H
|
||||||
|
#define _SECUNET_DMI_EEPROM_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
enum bx26_strings {
|
||||||
|
BOARD_MATNR,
|
||||||
|
BOARD_SERIAL_NUMBER,
|
||||||
|
BOARD_VERSION,
|
||||||
|
BOARD_MCTRL_FW_VERSION,
|
||||||
|
BOARD_CCR_FW_VERSION,
|
||||||
|
BOARD_NIC_FW_VERSION,
|
||||||
|
BOARD_LP_VERSION,
|
||||||
|
BOARD_VERSION_ID,
|
||||||
|
|
||||||
|
SYSTEM_PRODUCT_NAME,
|
||||||
|
SYSTEM_VERSION,
|
||||||
|
SYSTEM_SERIAL_NUMBER,
|
||||||
|
SYSTEM_UUID,
|
||||||
|
SYSTEM_MANUFACTURER,
|
||||||
|
SYSTEM_PRODUCTION_DATE,
|
||||||
|
SYSTEM_MLFB,
|
||||||
|
SYSTEM_MATNR,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bx26_location {
|
||||||
|
uint16_t offset;
|
||||||
|
uint16_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct bx26_location bx26_locations[] = {
|
||||||
|
[BOARD_MATNR] = { 0x0000, 0x20 },
|
||||||
|
[BOARD_SERIAL_NUMBER] = { 0x0020, 0x20 },
|
||||||
|
[BOARD_VERSION] = { 0x0040, 0x20 },
|
||||||
|
[BOARD_MCTRL_FW_VERSION] = { 0x0060, 0x20 },
|
||||||
|
[BOARD_CCR_FW_VERSION] = { 0x0080, 0x20 },
|
||||||
|
[BOARD_NIC_FW_VERSION] = { 0x00a0, 0x20 },
|
||||||
|
[BOARD_LP_VERSION] = { 0x00c0, 0x20 },
|
||||||
|
[BOARD_VERSION_ID] = { 0x0100, 0x20 },
|
||||||
|
|
||||||
|
[SYSTEM_PRODUCT_NAME] = { 0x4000, 0x20 },
|
||||||
|
[SYSTEM_VERSION] = { 0x4040, 0x10 },
|
||||||
|
[SYSTEM_SERIAL_NUMBER] = { 0x4060, 0x10 },
|
||||||
|
[SYSTEM_UUID] = { 0x4080, 0x24 },
|
||||||
|
[SYSTEM_MANUFACTURER] = { 0x40c0, 0x20 },
|
||||||
|
[SYSTEM_PRODUCTION_DATE] = { 0x4100, 0x20 },
|
||||||
|
[SYSTEM_MLFB] = { 0x4140, 0x20 },
|
||||||
|
[SYSTEM_MATNR] = { 0x4180, 0x20 },
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 secunet Security Networks AG
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 = {
|
||||||
|
CHIP_NAME("secunet DMI")
|
||||||
|
.enable_dev = enable_dev,
|
||||||
|
};
|
Loading…
Reference in New Issue