Tim Chu has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41605 )
Change subject: drivers/ocp/ipmi: Add ipmi POST start/end command ......................................................................
drivers/ocp/ipmi: Add ipmi POST start/end command
Add functions of sending POST start/end command to BMC. These functions are used in ramstage.
Signed-off-by: TimChu Tim.Chu@quantatw.com Change-Id: Ide0e2a52876db555ed8b5e919215e85731fd80ed --- A src/drivers/ocp/ipmi/Kconfig A src/drivers/ocp/ipmi/Makefile.inc A src/drivers/ocp/ipmi/ipmi_ocp.c A src/drivers/ocp/ipmi/ipmi_ocp.h 4 files changed, 132 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/05/41605/1
diff --git a/src/drivers/ocp/ipmi/Kconfig b/src/drivers/ocp/ipmi/Kconfig new file mode 100644 index 0000000..95c51c0 --- /dev/null +++ b/src/drivers/ocp/ipmi/Kconfig @@ -0,0 +1,3 @@ +config IPMI_OCP + bool + default n diff --git a/src/drivers/ocp/ipmi/Makefile.inc b/src/drivers/ocp/ipmi/Makefile.inc new file mode 100644 index 0000000..8291f82 --- /dev/null +++ b/src/drivers/ocp/ipmi/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_IPMI_OCP) += ipmi_ocp.c diff --git a/src/drivers/ocp/ipmi/ipmi_ocp.c b/src/drivers/ocp/ipmi/ipmi_ocp.c new file mode 100644 index 0000000..c1766d9 --- /dev/null +++ b/src/drivers/ocp/ipmi/ipmi_ocp.c @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Place in devicetree.cb: + * + * chip drivers/ocp/ipmi # OCP specific IPMI porting + device pnp ca2.1 on end + * end + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pnp.h> +#include "chip.h" +#include "drivers/ipmi/ipmi_kcs.h" +#include "ipmi_ocp.h" + +static int ipmi_set_post_start(struct device *dev, struct ipmi_rsp *rsp) +{ + int ret; + + ret = ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_OEM, 0, + IPMI_BMC_SET_POST_START, NULL, 0, (u8 *)rsp, + sizeof(*rsp)); + + if (ret < sizeof(struct ipmi_rsp) || rsp->completion_code) { + printk(BIOS_ERR, "IPMI: %s command failed (ret=%d rsp=0x%x)\n", + __func__, ret, rsp->completion_code); + return 1; + } + if (ret != sizeof(*rsp)) { + printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__); + return 1; + } + return 0; +} + +static int ipmi_set_post_end(struct device *dev, struct ipmi_rsp *rsp) +{ + int ret; + + ret = ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_OEM, 0, + IPMI_BMC_SET_POST_END, NULL, 0, (u8 *)rsp, + sizeof(*rsp)); + + if (ret < sizeof(struct ipmi_rsp) || rsp->completion_code) { + printk(BIOS_ERR, "IPMI: %s command failed (ret=%d rsp=0x%x)\n", + __func__, ret, rsp->completion_code); + return 1; + } + if (ret != sizeof(*rsp)) { + printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__); + return 1; + } + return 0; +} + +static void ipmi_ocp_init(struct device *dev) +{ + struct ipmi_rsp postrsp; + + /* Send POST start to BMC. */ + if (!ipmi_set_post_start(dev, &postrsp)) + printk(BIOS_DEBUG, "IPMI BMC POST is started\n"); +} + +static void ipmi_ocp_final(struct device *dev) +{ + struct ipmi_rsp postrsp; + + /* Send POST end to BMC. */ + if (!ipmi_set_post_end(dev, &postrsp)) + printk(BIOS_DEBUG, "IPMI BMC POST is ended\n"); +} + +static void ipmi_set_resources(struct device *dev) +{ + struct resource *res; + + for (res = dev->resource_list; res; res = res->next) { + if (!(res->flags & IORESOURCE_ASSIGNED)) + continue; + + res->flags |= IORESOURCE_STORED; + report_resource_stored(dev, res, ""); + } +} + +static void ipmi_read_resources(struct device *dev) +{ + struct resource *res = new_resource(dev, 0); + res->base = dev->path.pnp.port; + res->size = 2; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; +} + +static struct device_operations ops = { + .read_resources = ipmi_read_resources, + .set_resources = ipmi_set_resources, + .init = ipmi_ocp_init, + .final = ipmi_ocp_final, +}; + +static void enable_dev(struct device *dev) +{ + if (dev->path.type != DEVICE_PATH_PNP) + printk(BIOS_ERR, "%s: Unsupported device type\n", + dev_path(dev)); + else if (dev->path.pnp.port & 1) + printk(BIOS_ERR, "%s: Base address needs to be aligned to 2\n", + dev_path(dev)); + else + dev->ops = &ops; +} + +struct chip_operations drivers_ocp_ipmi_ops = { + CHIP_NAME("IPMI OCP") + .enable_dev = enable_dev, +}; diff --git a/src/drivers/ocp/ipmi/ipmi_ocp.h b/src/drivers/ocp/ipmi/ipmi_ocp.h new file mode 100644 index 0000000..1cdea2f --- /dev/null +++ b/src/drivers/ocp/ipmi/ipmi_ocp.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __IPMI_OCP_H +#define __IPMI_OCP_H + +#define IPMI_NETFN_OEM 0x30 +#define IPMI_BMC_SET_POST_START 0x73 +#define IPMI_BMC_SET_POST_END 0x74 + +#endif