mb/scaleway/tagada: Add bmcInfo interface

This interface gives access to configuration information stored in flash
by the Tagada BMC before booting the SoC.

Change-Id: I4351aa11b08bdf65e14706b261c532bbf8837aed
Signed-off-by: Julien Viard de Galbert <jviarddegalbert@online.net>
Reviewed-on: https://review.coreboot.org/23813
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Julien Viard de Galbert 2018-03-07 15:48:54 +01:00 committed by Martin Roth
parent 9d2e597908
commit 0e755d4f7a
7 changed files with 284 additions and 1 deletions

View File

@ -34,6 +34,12 @@ config MAINBOARD_VENDOR
string string
default "Scaleway" default "Scaleway"
config BMC_INFO_LOC
hex "BMC information location in flash"
default 0xff802000
help
Location of BMC SERIAL information.
config SMBIOS_ENCLOSURE_TYPE config SMBIOS_ENCLOSURE_TYPE
hex hex
default 0x19 default 0x19

View File

@ -14,6 +14,8 @@
## GNU General Public License for more details. ## GNU General Public License for more details.
## ##
bootblock-y += bootblock.c
romstage-y += hsio.c romstage-y += hsio.c
ramstage-y += ramstage.c ramstage-y += ramstage.c
@ -21,4 +23,10 @@ ramstage-y += hsio.c
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi_tables.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi_tables.c
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += fadt.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += fadt.c
bootblock-y += bmcinfo.c
postcar-y += bmcinfo.c
romstage-y += bmcinfo.c
ramstage-y += bmcinfo.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += bmcinfo.c
CPPFLAGS_common += -Isrc/mainboard/$(MAINBOARDDIR)/ CPPFLAGS_common += -Isrc/mainboard/$(MAINBOARDDIR)/

View File

@ -0,0 +1,191 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2017 - 2018 Online SAS.
*
* 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 <stdlib.h>
#include <string.h>
#include <arch/early_variables.h>
#include <console/console.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 enum biosBmcInfoValidFlag_e CAR_GLOBAL biosBmcInfoValidFlag;
static bool bmcinfo_is_valid(size_t minsize)
{
const biosBmcInfo_t *bmc_info = BMC_INFO;
int flag = car_get_var(biosBmcInfoValidFlag);
if (flag == BMCINFO_UNTESTED) {
flag = 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))
flag = BMCINFO_VALID;
else
flag = BMCINFO_VALID_NEED_WARN;
}
}
car_set_var(biosBmcInfoValidFlag, flag);
}
#if !defined(__PRE_RAM__)
if (flag == BMCINFO_INVALID) {
int length = offsetof(biosBmcInfo_t, endMarker);
printk(BIOS_CRIT, "WARNING bmcInfo struct"
"is not available please update your BMC.\n");
flag = BMCINFO_INVALID_WARNED;
car_set_var(biosBmcInfoValidFlag, flag);
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 (flag == BMCINFO_VALID_NEED_WARN) {
printk(BIOS_CRIT, "WARNING bmcInfo struct"
" is incomplete please update your BMC.\n");
flag = BMCINFO_VALID;
car_set_var(biosBmcInfoValidFlag, flag);
}
#endif
if (flag < 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 */

View File

@ -0,0 +1,41 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2017 Online SAS.
*
* 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 MAINBOARD_BMCINFO_H
#define MAINBOARD_BMCINFO_H
// Do not place disks in boot order
#define BOOT_OPTION_NIC_ONLY 0
// Boot to disk first (before network)
#define BOOT_OPTION_DISK_FIRST 1
// Boot to disk second (after network)
#define BOOT_OPTION_DISK_SECOND 2
// Boot order mask
#define BOOT_OPTION_ORDER_MASK 3
// Reset after boot sequence (don't go to EFI shell)
#define BOOT_OPTION_NO_EFISHELL 0x80
char *bmcinfo_serial(void);
u8 *bmcinfo_uuid(void);
int bmcinfo_slot(void);
int bmcinfo_hwrev(void);
u32 bmcinfo_baudrate(void);
int bmcinfo_coreboot_verbosity_level(void);
int bmcinfo_fsp_verbosity_level(void);
int bmcinfo_relax_security(void);
int bmcinfo_boot_option(void);
int bmcinfo_disable_nic1(void);
#endif /* MAINBOARD_BMCINFO_H */

View File

@ -0,0 +1,29 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2018 Online SAS.
*
* 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 <bootblock_common.h>
#include <console/console.h>
#include "bmcinfo.h"
/*
* Display board serial early
*/
void bootblock_mainboard_init(void)
{
if (IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE))
printk(BIOS_SPEW, "Board Serial: %s.\n", bmcinfo_serial());
}

View File

@ -19,8 +19,13 @@
#include <fsp/api.h> #include <fsp/api.h>
#include <soc/ramstage.h> #include <soc/ramstage.h>
#include "bmcinfo.h"
void mainboard_silicon_init_params(FSPS_UPD *params) void mainboard_silicon_init_params(FSPS_UPD *params)
{ {
/* Disable eMMC */ /* Disable eMMC */
params->FspsConfig.PcdEnableEmmc = 0; params->FspsConfig.PcdEnableEmmc = 0;
if (bmcinfo_disable_nic1())
params->FspsConfig.PcdEnableGbE = 2; // disable lan 1 only
} }

View File

@ -20,6 +20,7 @@
#include <fsp/api.h> #include <fsp/api.h>
#include <fsp/soc_binding.h> #include <fsp/soc_binding.h>
#include <string.h> #include <string.h>
#include "bmcinfo.h"
void mainboard_config_gpios(void); void mainboard_config_gpios(void);
void mainboard_memory_init_params(FSPM_UPD *mupd); void mainboard_memory_init_params(FSPM_UPD *mupd);
@ -32,6 +33,7 @@ void mainboard_config_gpios(void)
size_t num; size_t num;
const struct pad_config *table; const struct pad_config *table;
printk(BIOS_SPEW, "Board Serial: %s.\n", bmcinfo_serial());
/* Configure pads prior to SiliconInit() in case there's any /* Configure pads prior to SiliconInit() in case there's any
* dependencies during hardware initialization. * dependencies during hardware initialization.
*/ */
@ -50,7 +52,8 @@ void mainboard_config_gpios(void)
void mainboard_memory_init_params(FSPM_UPD *mupd) void mainboard_memory_init_params(FSPM_UPD *mupd)
{ {
mupd->FspmConfig.PcdFspDebugPrintErrorLevel = 3; // Verbose mupd->FspmConfig.PcdFspDebugPrintErrorLevel =
bmcinfo_fsp_verbosity_level();
// Enable Rmt and Fast Boot by default, RMT will be run only on first // Enable Rmt and Fast Boot by default, RMT will be run only on first
// boot or when dimms change // boot or when dimms change