mb/ocp/deltalake: Populate SMBIOS data and set the read PPIN to BMC

1. Populate SMBIOS data from OCP_DMI driver read from FRU and PPIN MSR
   for OEM string 1 to 6, add string 8 for PCIE configuration.
2. Set the read PPIN MSR to BMC.

Tested on OCP Delta Lake.

Change-Id: I9127cf5da1c56d8012694d070615aec24cc22fdf
Signed-off-by: Johnny Lin <johnny_lin@wiwynn.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41279
Reviewed-by: Jonathan Zhang <jonzhang@fb.com>
Reviewed-by: Christian Walter <christian.walter@9elements.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Johnny Lin 2020-05-12 10:05:27 +08:00 committed by Philipp Deppenwiese
parent 54a7f41de1
commit 407b35aa9f
5 changed files with 142 additions and 1 deletions

View File

@ -9,6 +9,7 @@ config BOARD_SPECIFIC_OPTIONS
select SOC_INTEL_COOPERLAKE_SP
select SUPERIO_ASPEED_AST2400
select IPMI_KCS
select OCP_DMI
config IPMI_KCS_REGISTER_SPACING
int

View File

@ -4,7 +4,7 @@ bootblock-y += bootblock.c
romstage-y += romstage.c
ramstage-y += ramstage.c
ramstage-y += ramstage.c ipmi.c
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += fadt.c
CPPFLAGS_common += -Isrc/mainboard/$(MAINBOARDDIR)/

View File

@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <console/console.h>
#include <drivers/ipmi/ipmi_kcs.h>
#include <drivers/ipmi/ipmi_ops.h>
#include "ipmi.h"
enum cb_err ipmi_set_ppin(struct ppin_req *req)
{
int ret;
struct ipmi_rsp rsp;
ret = ipmi_kcs_message(CONFIG_BMC_KCS_BASE, IPMI_NETFN_OEM, 0x0, IPMI_OEM_SET_PPIN,
(const unsigned char *) req, sizeof(*req),
(unsigned char *) &rsp, sizeof(rsp));
if (ret < sizeof(struct ipmi_rsp) || rsp.completion_code) {
printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n",
__func__, ret, rsp.completion_code);
return CB_ERR;
}
return CB_SUCCESS;
}
enum cb_err ipmi_get_pcie_config(uint8_t *pcie_config)
{
int ret;
struct ipmi_config_rsp {
struct ipmi_rsp resp;
uint8_t config;
} __packed;
struct ipmi_config_rsp rsp;
ret = ipmi_kcs_message(CONFIG_BMC_KCS_BASE, IPMI_NETFN_OEM, 0x0,
IPMI_OEM_GET_PCIE_CONFIG, NULL, 0, (unsigned char *) &rsp,
sizeof(rsp));
if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) {
printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n",
__func__, ret, rsp.resp.completion_code);
return CB_ERR;
}
*pcie_config = rsp.config;
return CB_SUCCESS;
}

View File

@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef DELTALAKE_IPMI_H
#define DELTALAKE_IPMI_H
#include <stdint.h>
#define IPMI_NETFN_OEM 0x30
#define IPMI_OEM_SET_PPIN 0x77
#define IPMI_OEM_GET_PCIE_CONFIG 0xf4
#define PCIE_CONFIG_UNKNOWN 0x0
#define PCIE_CONFIG_A 0x1
#define PCIE_CONFIG_B 0x2
#define PCIE_CONFIG_C 0x3
#define PCIE_CONFIG_D 0x4
struct ppin_req {
uint32_t cpu0_lo;
uint32_t cpu0_hi;
uint32_t cpu1_lo;
uint32_t cpu1_hi;
} __packed;
enum cb_err ipmi_set_ppin(struct ppin_req *req);
enum cb_err ipmi_get_pcie_config(uint8_t *config);
#endif

View File

@ -1,7 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <console/console.h>
#include <drivers/ipmi/ipmi_ops.h>
#include <drivers/ocp/dmi/ocp_dmi.h>
#include <soc/ramstage.h>
#include "ipmi.h"
extern struct fru_info_str fru_strings;
static void dl_oem_smbios_strings(struct device *dev, struct smbios_type11 *t)
{
uint8_t pcie_config = 0;
/* OEM string 1 to 6 */
ocp_oem_smbios_strings(dev, t);
/* TODO: Add real OEM string 7, add TBF for now */
t->count = smbios_add_oem_string(t->eos, TBF);
/* Add OEM string 8 */
if (ipmi_get_pcie_config(&pcie_config) == CB_SUCCESS) {
switch (pcie_config) {
case PCIE_CONFIG_UNKNOWN:
t->count = smbios_add_oem_string(t->eos, "0x0: Unknown");
break;
case PCIE_CONFIG_A:
t->count = smbios_add_oem_string(t->eos, "0x1: YV3 Config-A");
break;
case PCIE_CONFIG_B:
t->count = smbios_add_oem_string(t->eos, "0x2: YV3 Config-B");
break;
case PCIE_CONFIG_C:
t->count = smbios_add_oem_string(t->eos, "0x3: YV3 Config-C");
break;
case PCIE_CONFIG_D:
t->count = smbios_add_oem_string(t->eos, "0x4: YV3 Config-D");
break;
default:
t->count = smbios_add_oem_string(t->eos, "Check BMC return data");
}
} else {
printk(BIOS_ERR, "Failed to get IPMI PCIe config\n");
}
}
static void mainboard_enable(struct device *dev)
{
dev->ops->get_smbios_strings = dl_oem_smbios_strings,
read_fru_areas(CONFIG_BMC_KCS_BASE, CONFIG_FRU_DEVICE_ID, 0, &fru_strings);
}
void mainboard_silicon_init_params(FSPS_UPD *params)
{
}
static void mainboard_final(void *chip_info)
{
struct ppin_req req = {0};
req.cpu0_lo = xeon_sp_ppin[0].lo;
req.cpu0_hi = xeon_sp_ppin[0].hi;
/* Set PPIN to BMC */
if (ipmi_set_ppin(&req) != CB_SUCCESS)
printk(BIOS_ERR, "ipmi_set_ppin failed\n");
}
struct chip_operations mainboard_ops = {
.enable_dev = mainboard_enable,
.final = mainboard_final,
};