From 0e755d4f7a6458b6b12008d89a6c689a5b65a03c Mon Sep 17 00:00:00 2001 From: Julien Viard de Galbert Date: Wed, 7 Mar 2018 15:48:54 +0100 Subject: [PATCH] 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 Reviewed-on: https://review.coreboot.org/23813 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/mainboard/scaleway/tagada/Kconfig | 6 + src/mainboard/scaleway/tagada/Makefile.inc | 8 + src/mainboard/scaleway/tagada/bmcinfo.c | 191 +++++++++++++++++++++ src/mainboard/scaleway/tagada/bmcinfo.h | 41 +++++ src/mainboard/scaleway/tagada/bootblock.c | 29 ++++ src/mainboard/scaleway/tagada/ramstage.c | 5 + src/mainboard/scaleway/tagada/romstage.c | 5 +- 7 files changed, 284 insertions(+), 1 deletion(-) create mode 100644 src/mainboard/scaleway/tagada/bmcinfo.c create mode 100644 src/mainboard/scaleway/tagada/bmcinfo.h create mode 100644 src/mainboard/scaleway/tagada/bootblock.c diff --git a/src/mainboard/scaleway/tagada/Kconfig b/src/mainboard/scaleway/tagada/Kconfig index d2b914dad2..ecce0df793 100644 --- a/src/mainboard/scaleway/tagada/Kconfig +++ b/src/mainboard/scaleway/tagada/Kconfig @@ -34,6 +34,12 @@ config MAINBOARD_VENDOR string default "Scaleway" +config BMC_INFO_LOC + hex "BMC information location in flash" + default 0xff802000 + help + Location of BMC SERIAL information. + config SMBIOS_ENCLOSURE_TYPE hex default 0x19 diff --git a/src/mainboard/scaleway/tagada/Makefile.inc b/src/mainboard/scaleway/tagada/Makefile.inc index 2c8186fc25..7d426dfa82 100644 --- a/src/mainboard/scaleway/tagada/Makefile.inc +++ b/src/mainboard/scaleway/tagada/Makefile.inc @@ -14,6 +14,8 @@ ## GNU General Public License for more details. ## +bootblock-y += bootblock.c + romstage-y += hsio.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) += 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)/ diff --git a/src/mainboard/scaleway/tagada/bmcinfo.c b/src/mainboard/scaleway/tagada/bmcinfo.c new file mode 100644 index 0000000000..9eb2ef1d0b --- /dev/null +++ b/src/mainboard/scaleway/tagada/bmcinfo.c @@ -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 +#include +#include +#include + +#include + +#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 */ diff --git a/src/mainboard/scaleway/tagada/bmcinfo.h b/src/mainboard/scaleway/tagada/bmcinfo.h new file mode 100644 index 0000000000..8e64a84b29 --- /dev/null +++ b/src/mainboard/scaleway/tagada/bmcinfo.h @@ -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 */ diff --git a/src/mainboard/scaleway/tagada/bootblock.c b/src/mainboard/scaleway/tagada/bootblock.c new file mode 100644 index 0000000000..b926275302 --- /dev/null +++ b/src/mainboard/scaleway/tagada/bootblock.c @@ -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 +#include +#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()); +} diff --git a/src/mainboard/scaleway/tagada/ramstage.c b/src/mainboard/scaleway/tagada/ramstage.c index 0aa6f13f85..55cd17562e 100644 --- a/src/mainboard/scaleway/tagada/ramstage.c +++ b/src/mainboard/scaleway/tagada/ramstage.c @@ -19,8 +19,13 @@ #include #include +#include "bmcinfo.h" + void mainboard_silicon_init_params(FSPS_UPD *params) { /* Disable eMMC */ params->FspsConfig.PcdEnableEmmc = 0; + + if (bmcinfo_disable_nic1()) + params->FspsConfig.PcdEnableGbE = 2; // disable lan 1 only } diff --git a/src/mainboard/scaleway/tagada/romstage.c b/src/mainboard/scaleway/tagada/romstage.c index d6a128209e..c29ff9dff7 100644 --- a/src/mainboard/scaleway/tagada/romstage.c +++ b/src/mainboard/scaleway/tagada/romstage.c @@ -20,6 +20,7 @@ #include #include #include +#include "bmcinfo.h" void mainboard_config_gpios(void); void mainboard_memory_init_params(FSPM_UPD *mupd); @@ -32,6 +33,7 @@ void mainboard_config_gpios(void) size_t num; const struct pad_config *table; + printk(BIOS_SPEW, "Board Serial: %s.\n", bmcinfo_serial()); /* Configure pads prior to SiliconInit() in case there's any * dependencies during hardware initialization. */ @@ -50,7 +52,8 @@ void mainboard_config_gpios(void) 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 // boot or when dimms change