mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-06 15:01:35 +00:00
Add OTP support
One Time Programmable memory can be used to store permanent data like serial numbers. Reorganize the code to support writing serial number to OTP, in addition to pstate (if using its own memory bank) or autogenerate from unique id (hammer). + Add CONFIG_OTP to enable OTP code + Add CONFIG_SERIALNO_LEN to indicate the size of the serial number string. Currently set to 28, when USB serial number is needed. + Expose flash_read|write_pstate_serial and add otp_read|write_serail, remove more generic flash_read|write_serial. + Make board_read|write_serial generic, declared outside of USB subsystem. Priority order to read|write serial string: - board definition (like hammer) - pstate location, if stored in its private memory bank - otp area If none of these methods are available, a compilation error is raised. BUG=chromium:746471 BRANCH=none TEST=compile Change-Id: I3d16125a6c0f424fb30e38123e63cf074b3cb2d3 Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/580289 Reviewed-by: Nick Sanders <nsanders@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
734ebcbbb4
commit
1b25735b73
@@ -172,7 +172,7 @@ int board_get_entropy(void *buffer, int len)
|
||||
*/
|
||||
const char *board_read_serial(void)
|
||||
{
|
||||
static char str[USB_STRING_LEN];
|
||||
static char str[CONFIG_SERIALNO_LEN];
|
||||
|
||||
if (str[0] == '\0') {
|
||||
uint8_t *id;
|
||||
@@ -188,3 +188,9 @@ const char *board_read_serial(void)
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
int board_write_serial(const char *serialno)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1434,7 +1434,7 @@ static int usb_set_serial(const char *serialno)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Convert into unicode usb string desc. */
|
||||
for (i = 0; i < USB_STRING_LEN; i++) {
|
||||
for (i = 0; i < CONFIG_SERIALNO_LEN; i++) {
|
||||
sd->_data[i] = serialno[i];
|
||||
if (serialno[i] == 0)
|
||||
break;
|
||||
@@ -1460,7 +1460,7 @@ DECLARE_HOOK(HOOK_INIT, usb_load_serialno, HOOK_PRIO_DEFAULT - 1);
|
||||
static int command_serialno(int argc, char **argv)
|
||||
{
|
||||
struct usb_string_desc *sd = usb_serialno_desc;
|
||||
char buf[USB_STRING_LEN];
|
||||
char buf[CONFIG_SERIALNO_LEN];
|
||||
int rv = EC_SUCCESS;
|
||||
int i;
|
||||
|
||||
@@ -1469,7 +1469,7 @@ static int command_serialno(int argc, char **argv)
|
||||
rv = usb_set_serial(argv[1]);
|
||||
}
|
||||
|
||||
for (i = 0; i < USB_STRING_LEN; i++)
|
||||
for (i = 0; i < CONFIG_SERIALNO_LEN; i++)
|
||||
buf[i] = sd->_data[i];
|
||||
ccprintf("Serial number: %s\n", buf);
|
||||
return rv;
|
||||
|
||||
@@ -645,7 +645,7 @@ static int usb_set_serial(const char *serialno)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Convert into unicode usb string desc. */
|
||||
for (i = 0; i < USB_STRING_LEN; i++) {
|
||||
for (i = 0; i < CONFIG_SERIALNO_LEN; i++) {
|
||||
sd->_data[i] = serialno[i];
|
||||
if (serialno[i] == 0)
|
||||
break;
|
||||
@@ -657,13 +657,6 @@ static int usb_set_serial(const char *serialno)
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/* By default, read serial number from flash, can be overridden. */
|
||||
__attribute__((weak))
|
||||
const char *board_read_serial(void)
|
||||
{
|
||||
return flash_read_serial();
|
||||
}
|
||||
|
||||
/* Retrieve serial number from pstate flash. */
|
||||
static int usb_load_serial(void)
|
||||
{
|
||||
@@ -687,7 +680,7 @@ static int usb_save_serial(const char *serialno)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Save this new serial number to flash. */
|
||||
rv = flash_write_serial(serialno);
|
||||
rv = board_write_serial(serialno);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
@@ -699,7 +692,7 @@ static int usb_save_serial(const char *serialno)
|
||||
static int command_serialno(int argc, char **argv)
|
||||
{
|
||||
struct usb_string_desc *sd = usb_serialno_desc;
|
||||
char buf[USB_STRING_LEN];
|
||||
char buf[CONFIG_SERIALNO_LEN];
|
||||
int rv = EC_SUCCESS;
|
||||
int i;
|
||||
|
||||
@@ -716,7 +709,7 @@ static int command_serialno(int argc, char **argv)
|
||||
return EC_ERROR_INVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < USB_STRING_LEN; i++)
|
||||
for (i = 0; i < CONFIG_SERIALNO_LEN; i++)
|
||||
buf[i] = sd->_data[i];
|
||||
ccprintf("Serial number: %s\n", buf);
|
||||
return rv;
|
||||
@@ -725,4 +718,4 @@ static int command_serialno(int argc, char **argv)
|
||||
DECLARE_CONSOLE_COMMAND(serialno, command_serialno,
|
||||
"load/set [value]",
|
||||
"Read and write USB serial number");
|
||||
#endif
|
||||
#endif /* CONFIG_USB_SERIALNO */
|
||||
|
||||
@@ -1359,7 +1359,7 @@ static int usb_set_serial(const char *serialno)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Convert into unicode usb string desc. */
|
||||
for (i = 0; i < USB_STRING_LEN; i++) {
|
||||
for (i = 0; i < CONFIG_SERIALNO_LEN; i++) {
|
||||
sd->_data[i] = serialno[i];
|
||||
if (serialno[i] == 0)
|
||||
break;
|
||||
@@ -1371,13 +1371,6 @@ static int usb_set_serial(const char *serialno)
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/* By default, read serial number from flash, can be overridden. */
|
||||
__attribute__((weak))
|
||||
const char *board_read_serial(void)
|
||||
{
|
||||
return flash_read_serial();
|
||||
}
|
||||
|
||||
/* Retrieve serial number from pstate flash. */
|
||||
static int usb_load_serial(void)
|
||||
{
|
||||
@@ -1392,7 +1385,6 @@ static int usb_load_serial(void)
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* Save serial number into pstate region. */
|
||||
static int usb_save_serial(const char *serialno)
|
||||
{
|
||||
@@ -1402,7 +1394,7 @@ static int usb_save_serial(const char *serialno)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Save this new serial number to flash. */
|
||||
rv = flash_write_serial(serialno);
|
||||
rv = board_write_serial(serialno);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
@@ -1414,7 +1406,7 @@ static int usb_save_serial(const char *serialno)
|
||||
static int command_serialno(int argc, char **argv)
|
||||
{
|
||||
struct usb_string_desc *sd = usb_serialno_desc;
|
||||
char buf[USB_STRING_LEN];
|
||||
char buf[CONFIG_SERIALNO_LEN];
|
||||
int rv = EC_SUCCESS;
|
||||
int i;
|
||||
|
||||
@@ -1431,7 +1423,7 @@ static int command_serialno(int argc, char **argv)
|
||||
return EC_ERROR_INVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < USB_STRING_LEN; i++)
|
||||
for (i = 0; i < CONFIG_SERIALNO_LEN; i++)
|
||||
buf[i] = sd->_data[i];
|
||||
ccprintf("Serial number: %s\n", buf);
|
||||
return rv;
|
||||
@@ -1440,5 +1432,4 @@ static int command_serialno(int argc, char **argv)
|
||||
DECLARE_CONSOLE_COMMAND(serialno, command_serialno,
|
||||
"load/set [value]",
|
||||
"Read and write USB serial number");
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_USB_SERIALNO */
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
#include "host_command.h"
|
||||
#include "otp.h"
|
||||
#include "shared_mem.h"
|
||||
#include "system.h"
|
||||
#include "util.h"
|
||||
@@ -39,7 +40,6 @@
|
||||
/* NOTE: It's not expected that RO and RW will support
|
||||
* differing PSTATE versions. */
|
||||
#define PERSIST_STATE_VERSION 3 /* Expected persist_state.version */
|
||||
#define SERIALNO_MAX 28
|
||||
|
||||
/* Flags for persist_state.flags */
|
||||
/* Protect persist state and RO firmware at boot */
|
||||
@@ -52,7 +52,11 @@ struct persist_state {
|
||||
uint8_t flags; /* Lock flags (PERSIST_FLAG_*) */
|
||||
uint8_t valid_fields; /* Flags for valid data. */
|
||||
uint8_t reserved; /* Reserved; set 0 */
|
||||
uint8_t serialno[SERIALNO_MAX]; /* Serial number. */
|
||||
#ifdef CONFIG_SERIALNO_LEN
|
||||
uint8_t serialno[CONFIG_SERIALNO_LEN]; /* Serial number. */
|
||||
#else
|
||||
uint8_t padding[4 % CONFIG_FLASH_WRITE_SIZE];
|
||||
#endif
|
||||
};
|
||||
/* written with flash_physical_write, need to respect alignment constraints */
|
||||
#ifndef CHIP_FAMILY_STM32L /* STM32L1xx is somewhat lying to us */
|
||||
@@ -216,10 +220,11 @@ static uint32_t flash_read_pstate(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIALNO_LEN
|
||||
/**
|
||||
* Read and return persistent serial number.
|
||||
*/
|
||||
static const char *flash_read_pstate_serial(void)
|
||||
const char *flash_read_pstate_serial(void)
|
||||
{
|
||||
const struct persist_state *pstate =
|
||||
(const struct persist_state *)
|
||||
@@ -230,8 +235,9 @@ static const char *flash_read_pstate_serial(void)
|
||||
return (const char *)(pstate->serialno);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Write persistent state after erasing.
|
||||
@@ -312,13 +318,14 @@ static int flash_write_pstate(uint32_t flags)
|
||||
return flash_write_pstate_data(&newpstate);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIALNO_LEN
|
||||
/**
|
||||
* Write persistent serial number to pstate, erasing if necessary.
|
||||
*
|
||||
* @param serialno New iascii serial number to set in pstate.
|
||||
* @return EC_SUCCESS, or nonzero if error.
|
||||
*/
|
||||
static int flash_write_pstate_serial(const char *serialno)
|
||||
int flash_write_pstate_serial(const char *serialno)
|
||||
{
|
||||
int i;
|
||||
struct persist_state newpstate;
|
||||
@@ -335,17 +342,18 @@ static int flash_write_pstate_serial(const char *serialno)
|
||||
validate_pstate_struct(&newpstate);
|
||||
|
||||
/* Copy in serialno. */
|
||||
for (i = 0; i < SERIALNO_MAX - 1; i++) {
|
||||
for (i = 0; i < CONFIG_SERIALNO_LEN - 1; i++) {
|
||||
newpstate.serialno[i] = serialno[i];
|
||||
if (serialno[i] == 0)
|
||||
break;
|
||||
}
|
||||
for (; i < SERIALNO_MAX; i++)
|
||||
for (; i < CONFIG_SERIALNO_LEN; i++)
|
||||
newpstate.serialno[i] = 0;
|
||||
newpstate.valid_fields |= PSTATE_VALID_SERIALNO;
|
||||
|
||||
return flash_write_pstate_data(&newpstate);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -515,24 +523,6 @@ int flash_erase(int offset, int size)
|
||||
return flash_physical_erase(offset, size);
|
||||
}
|
||||
|
||||
const char *flash_read_serial(void)
|
||||
{
|
||||
#if defined(CONFIG_FLASH_PSTATE) && defined(CONFIG_FLASH_PSTATE_BANK)
|
||||
return flash_read_pstate_serial();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int flash_write_serial(const char *serialno)
|
||||
{
|
||||
#if defined(CONFIG_FLASH_PSTATE) && defined(CONFIG_FLASH_PSTATE_BANK)
|
||||
return flash_write_pstate_serial(serialno);
|
||||
#else
|
||||
return EC_ERROR_UNIMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
int flash_protect_at_boot(uint32_t new_flags)
|
||||
{
|
||||
#ifdef CONFIG_FLASH_PSTATE
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "host_command.h"
|
||||
#include "i2c.h"
|
||||
#include "lpc.h"
|
||||
#include "otp.h"
|
||||
#include "rwsig.h"
|
||||
#include "spi_flash.h"
|
||||
#ifdef CONFIG_MPU
|
||||
@@ -1321,3 +1322,34 @@ int system_can_boot_ap(void)
|
||||
|
||||
return power_good;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIALNO_LEN
|
||||
/* By default, read serial number from flash, can be overridden. */
|
||||
#if defined(CONFIG_FLASH_PSTATE) && defined(CONFIG_FLASH_PSTATE_BANK)
|
||||
__attribute__((weak))
|
||||
const char *board_read_serial(void)
|
||||
{
|
||||
return flash_read_pstate_serial();
|
||||
}
|
||||
#elif defined(CONFIG_OTP)
|
||||
__attribute__((weak))
|
||||
const char *board_read_serial(void)
|
||||
{
|
||||
return otp_read_serial();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FLASH_PSTATE) && defined(CONFIG_FLASH_PSTATE_BANK)
|
||||
__attribute__((weak))
|
||||
int board_write_serial(const char *serialno)
|
||||
{
|
||||
return flash_write_pstate_serial(serialno);
|
||||
}
|
||||
#elif defined(CONFIG_OTP)
|
||||
__attribute__((weak))
|
||||
int board_write_serial(const char *serialno)
|
||||
{
|
||||
return otp_write_serial(serialno);
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_SERIALNO_LEN */
|
||||
|
||||
@@ -1815,6 +1815,9 @@
|
||||
/* Support one-wire interface */
|
||||
#undef CONFIG_ONEWIRE
|
||||
|
||||
/* Support One Time Protection structure */
|
||||
#undef CONFIG_OTP
|
||||
|
||||
/* Support PECI interface to x86 processor */
|
||||
#undef CONFIG_PECI
|
||||
|
||||
@@ -2001,6 +2004,9 @@
|
||||
#undef CONFIG_RW_SIG_ADDR
|
||||
#undef CONFIG_RW_SIG_SIZE
|
||||
|
||||
/* Size of the serial number if needed */
|
||||
#undef CONFIG_SERIALNO_LEN
|
||||
|
||||
/****************************************************************************/
|
||||
/* Shared objects library. */
|
||||
|
||||
@@ -2940,4 +2946,8 @@
|
||||
#error "CONFIG_AUX_TIMER_PERIOD_MS must be at least 2x HOOK_TICK_INTERVAL_MS"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_SERIALNO
|
||||
#define CONFIG_SERIALNO_LEN 28
|
||||
#endif
|
||||
|
||||
#endif /* __CROS_EC_CONFIG_H */
|
||||
|
||||
@@ -320,17 +320,18 @@ int flash_set_protect(uint32_t mask, uint32_t flags);
|
||||
* Get the serial number from flash.
|
||||
*
|
||||
* @return char * ascii serial number string.
|
||||
* NULL if error.
|
||||
*/
|
||||
const char *flash_read_serial(void);
|
||||
const char *flash_read_pstate_serial(void);
|
||||
|
||||
/**
|
||||
* Set the serial number in flash.
|
||||
*
|
||||
* @param serialno ascii serial number string < 30 char.
|
||||
* @param serialno ascii serial number string.
|
||||
*
|
||||
* @return success status.
|
||||
*/
|
||||
int flash_write_serial(const char *serialno);
|
||||
int flash_write_pstate_serial(const char *serialno);
|
||||
|
||||
/**
|
||||
* Lock or unlock HW necessary for mapped storage read.
|
||||
|
||||
32
include/otp.h
Normal file
32
include/otp.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* Copyright 2017 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/* OTP memory module for Chrome EC */
|
||||
|
||||
#ifndef __CROS_EC_OTP_H
|
||||
#define __CROS_EC_OTP_H
|
||||
|
||||
/*
|
||||
* OTP: One Time Programable memory is used for storing persistent data.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the serial number in OTP memory.
|
||||
*
|
||||
* @param serialno ascii serial number string.
|
||||
*
|
||||
* @return success status.
|
||||
*/
|
||||
int otp_write_serial(const char *serialno);
|
||||
|
||||
/**
|
||||
* Get the serial number from flash.
|
||||
*
|
||||
* @return char * ascii serial number string.
|
||||
* NULL if error.
|
||||
*/
|
||||
const char *otp_read_serial(void);
|
||||
|
||||
#endif /* __CROS_EC_OTP_H */
|
||||
@@ -287,10 +287,15 @@ int system_get_chip_unique_id(uint8_t **id);
|
||||
|
||||
/**
|
||||
* Optional board-level callback functions to read a unique serial number per
|
||||
* chip. Default implementation reads from flash (flash_read_serial).
|
||||
* chip. Default implementation reads from flash/otp (flash/otp_read_serial).
|
||||
*/
|
||||
const char *board_read_serial(void) __attribute__((weak));
|
||||
|
||||
/**
|
||||
* Optional board-level callback functions to write a unique serial number per
|
||||
* chip. Default implementation reads from flash/otp (flash/otp_write_serial).
|
||||
*/
|
||||
int board_write_serial(const char *serial) __attribute__((weak));
|
||||
/*
|
||||
* Common bbram entries. Chips don't necessarily need to implement
|
||||
* all of these, error will be returned from system_get/set_bbram if
|
||||
|
||||
@@ -258,11 +258,10 @@ struct usb_setup_packet {
|
||||
|
||||
#ifdef CONFIG_USB_SERIALNO
|
||||
/* String Descriptor for USB, for editable strings. */
|
||||
#define USB_STRING_LEN 28
|
||||
struct usb_string_desc {
|
||||
uint8_t _len;
|
||||
uint8_t _type;
|
||||
wchar_t _data[USB_STRING_LEN];
|
||||
wchar_t _data[CONFIG_SERIALNO_LEN];
|
||||
};
|
||||
#define USB_WR_STRING_DESC(str) \
|
||||
(&(struct usb_string_desc) { \
|
||||
|
||||
Reference in New Issue
Block a user