blob: 2de2f2e3a0c845aa835123c3252cbfb1c43a3689 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
#include <console/console.h>
#include <console/uart.h>
#include <types.h>
#include "bmcinfo.h"
typedef struct {
u32 magic0; // "BMCI"
u32 magic1; // "nfo0"
u16 length;
u16 chksum;
u8 uuid[16];
u8 bmcSerial[9]; // as null terminated string
u8 slot;
u8 corebootVerbosityLevel;
u8 relaxSecurity;
u32 baudrate;
u8 bootOption;
u8 hwRev; // Note: Initial implementation ended here
u8 disableNic1;
u8 endMarker; // Insert new fields before
} biosBmcInfo_t;
#define BIOSBMCINFO_MAGIC0 0x49434d42
#define BIOSBMCINFO_MAGIC1 0x306f666e
#define BMC_INFO ((biosBmcInfo_t *)CONFIG_BMC_INFO_LOC)
enum biosBmcInfoValidFlag_e {
BMCINFO_UNTESTED = 0,
BMCINFO_INVALID,
BMCINFO_INVALID_WARNED,
BMCINFO_VALID_NEED_WARN,
BMCINFO_VALID,
};
static bool bmcinfo_is_valid(size_t minsize)
{
static enum biosBmcInfoValidFlag_e biosBmcInfoValidFlag;
const biosBmcInfo_t *bmc_info = BMC_INFO;
if (biosBmcInfoValidFlag == BMCINFO_UNTESTED) {
biosBmcInfoValidFlag = BMCINFO_INVALID;
if ((bmc_info->magic0 == BIOSBMCINFO_MAGIC0)
&& (bmc_info->magic1 == BIOSBMCINFO_MAGIC1)
&& (bmc_info->length >= offsetof(biosBmcInfo_t, hwRev))
&& (bmc_info->length <= 0x1000)) {
u16 chksum = 0 - (bmc_info->chksum & 0xff)
- (bmc_info->chksum >> 8);
int i;
for (i = 0; i < bmc_info->length ; i++)
chksum += ((u8 *)bmc_info)[i];
if (bmc_info->chksum == chksum) {
if (bmc_info->length >= offsetof(biosBmcInfo_t,
endMarker))
biosBmcInfoValidFlag = BMCINFO_VALID;
else
biosBmcInfoValidFlag = BMCINFO_VALID_NEED_WARN;
}
}
}
if (ENV_RAMSTAGE && biosBmcInfoValidFlag == BMCINFO_INVALID) {
int length = offsetof(biosBmcInfo_t, endMarker);
printk(BIOS_CRIT, "WARNING bmcInfo struct"
"is not available please update your BMC.\n");
biosBmcInfoValidFlag = BMCINFO_INVALID_WARNED;
printk(BIOS_CRIT, "bmcInfo magic = \"%x-%x\"\n",
bmc_info->magic0, bmc_info->magic1);
printk(BIOS_CRIT, "bmcInfo length = %d expected = %d\"\n",
bmc_info->length, length);
u16 chksum = 0 - (bmc_info->chksum & 0xff)
- (bmc_info->chksum >> 8);
int i;
for (i = 0; i < bmc_info->length; i++)
chksum += ((u8 *)bmc_info)[i];
printk(BIOS_CRIT, "bmcInfo chksum = 0x%x expected = 0x%x\"\n",
bmc_info->chksum, chksum);
}
if (ENV_RAMSTAGE && biosBmcInfoValidFlag == BMCINFO_VALID_NEED_WARN) {
printk(BIOS_CRIT, "WARNING bmcInfo struct"
" is incomplete please update your BMC.\n");
biosBmcInfoValidFlag = BMCINFO_VALID;
}
if (biosBmcInfoValidFlag < BMCINFO_VALID_NEED_WARN)
return false;
return (bmc_info->length >= minsize);
}
#define IS_BMC_INFO_FIELD_VALID(field) \
(bmcinfo_is_valid(offsetof(biosBmcInfo_t, field) \
+ sizeof(((biosBmcInfo_t *)0)->field)))
char *bmcinfo_serial(void)
{
if (IS_BMC_INFO_FIELD_VALID(bmcSerial))
return (char *)BMC_INFO->bmcSerial;
return NULL;
}
u8 *bmcinfo_uuid(void)
{
if (IS_BMC_INFO_FIELD_VALID(uuid))
return BMC_INFO->uuid;
return NULL;
}
int bmcinfo_slot(void)
{
if (IS_BMC_INFO_FIELD_VALID(slot))
return BMC_INFO->slot;
return -1;
}
int bmcinfo_hwrev(void)
{
if (IS_BMC_INFO_FIELD_VALID(hwRev))
return BMC_INFO->hwRev;
return -1;
}
u32 bmcinfo_baudrate(void)
{
if (IS_BMC_INFO_FIELD_VALID(baudrate))
return BMC_INFO->baudrate;
return 0;
}
int bmcinfo_coreboot_verbosity_level(void)
{
if (IS_BMC_INFO_FIELD_VALID(corebootVerbosityLevel))
return BMC_INFO->corebootVerbosityLevel & 0xf;
return BIOS_CRIT;
}
int bmcinfo_fsp_verbosity_level(void)
{
if (IS_BMC_INFO_FIELD_VALID(corebootVerbosityLevel))
return BMC_INFO->corebootVerbosityLevel >> 4;
return 0;
}
int bmcinfo_relax_security(void)
{
if (IS_BMC_INFO_FIELD_VALID(relaxSecurity))
return BMC_INFO->relaxSecurity;
return 0;
}
int bmcinfo_boot_option(void)
{
if (IS_BMC_INFO_FIELD_VALID(bootOption))
return BMC_INFO->bootOption;
return 0;
}
int bmcinfo_disable_nic1(void)
{
if (IS_BMC_INFO_FIELD_VALID(disableNic1))
return BMC_INFO->disableNic1;
return 0;
}
/* Add override functions below */
/* Override default uart baudrate */
unsigned int get_uart_baudrate(void)
{
int baudrate = bmcinfo_baudrate();
if (baudrate)
return baudrate;
return 115200;
}
#if __CONSOLE_ENABLE__
/* Override default console loglevel */
int get_console_loglevel(void)
{
return bmcinfo_coreboot_verbosity_level();
}
#endif