Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/33255
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add SPMI ACPI code * Add chips ops for IPMI KCS. * Set firmware version over KCS. * Get IPMI version over KCS. * Generate ACPI SPMI for IPMI KCS. * Generate SMBIOS type 38 for IPMI KCS.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/arch/x86/acpi.c M src/arch/x86/include/arch/acpi.h M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 6 files changed, 337 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/33255/1
diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c index bf9813c..8938147 100644 --- a/src/arch/x86/acpi.c +++ b/src/arch/x86/acpi.c @@ -772,6 +772,53 @@ header->checksum = acpi_checksum((void *)vfct, header->length); }
+void acpi_create_ipmi(struct device *device, + struct acpi_spmi *spmi, + const u16 ipmi_revision, + const acpi_addr_t *addr, + const enum acpi_ipmi_interface_type type, + const s8 gpe_interrupt, + const u32 apic_interrupt) +{ + acpi_header_t *header = &(spmi->header); + memset((void *)spmi, 0, sizeof(struct acpi_spmi)); + + /* Fill out header fields. */ + memcpy(header->signature, "SPMI", 4); + memcpy(header->oem_id, OEM_ID, 6); + memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); + memcpy(header->asl_compiler_id, ASLC, 4); + + header->asl_compiler_revision = asl_revision; + header->length = sizeof(struct acpi_spmi); + header->revision = get_acpi_table_revision(SPMI); + + if (device->path.type == DEVICE_PATH_PCI) { + spmi->pci_device_flag = 1; + spmi->pci_bus = device->bus->secondary; + spmi->pci_device = device->path.pci.devfn >> 3; + spmi->pci_function = device->path.pci.devfn & 0x7; + } + + spmi->base_address = *addr; + spmi->specification_revision = ipmi_revision; + + spmi->interface_type = type; + + if (gpe_interrupt >= 0 && gpe_interrupt < 32) { + spmi->gpe = gpe_interrupt; + spmi->interrupt_type |= 1; + } + if (apic_interrupt > 0) { + spmi->global_system_interrupt = apic_interrupt; + spmi->interrupt_type |= 2; + } + + /* (Re)calculate length and checksum. */ + header->length = sizeof(struct acpi_spmi); + header->checksum = acpi_checksum((void *)spmi, header->length); +} + void acpi_create_ivrs(acpi_ivrs_t *ivrs, unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct, unsigned long current)) @@ -1490,6 +1537,8 @@ return 1; case SLIT: /* ACPI 2.0 upto 6.3: 1 */ return 1; + case SPMI: /* IMPI 2.0 */ + return 5; case HPET: /* Currently 1. Table added in ACPI 2.0. */ return 1; case VFCT: /* ACPI 2.0/3.0/4.0: 1 */ diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h index dbf46a9..a864071 100644 --- a/src/arch/x86/include/arch/acpi.h +++ b/src/arch/x86/include/arch/acpi.h @@ -82,7 +82,7 @@ BERT, DBG2, DMAR, DSDT, FACS, FADT, HEST, HPET, IVRS, MADT, MCFG, RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT, /* Additional proprietary tables used by coreboot */ - VFCT, NHLT + VFCT, NHLT, SPMI };
/* RSDP (Root System Description Pointer) */ @@ -782,6 +782,39 @@ UPC_TYPE_HUB };
+enum acpi_ipmi_interface_type { + IPMI_INTERFACE_RESERVED, + IPMI_INTERFACE_KCS, + IPMI_INTERFACE_SMIC, + IPMI_INTERFACE_BT, + IPMI_INTERFACE_SSIF, +}; + +/* ACPI IPMI 2.0 */ +struct acpi_spmi { + struct acpi_table_header header; + u8 interface_type; + u8 reserved; + u16 specification_revision; + u8 interrupt_type; + u8 gpe; + u8 reserved2; + u8 pci_device_flag; + + u32 global_system_interrupt; + acpi_addr_t base_address; + union { + struct { + u8 pci_segment_group; + u8 pci_bus; + u8 pci_device; + u8 pci_function; + }; + u8 uid[4]; + }; + u8 reserved3; +} __packed ; + unsigned long fw_cfg_acpi_tables(unsigned long start);
/* These are implemented by the target port or north/southbridge. */ @@ -834,6 +867,14 @@ struct acpi_vfct *vfct_struct, unsigned long current));
+void acpi_create_ipmi(struct device *device, + struct acpi_spmi *spmi, + const u16 ipmi_revision, + const acpi_addr_t *addr, + const enum acpi_ipmi_interface_type type, + const s8 gpe_interrupt, + const u32 apic_interrupt); + void acpi_create_ivrs(acpi_ivrs_t *ivrs, unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct, unsigned long current)); diff --git a/src/drivers/ipmi/Makefile.inc b/src/drivers/ipmi/Makefile.inc index e9e7ff3..a29c2e2 100644 --- a/src/drivers/ipmi/Makefile.inc +++ b/src/drivers/ipmi/Makefile.inc @@ -1 +1,2 @@ ramstage-$(CONFIG_IPMI_KCS) += ipmi_kcs.c +ramstage-$(CONFIG_IPMI_KCS) += ipmi_kcs_ops.c diff --git a/src/drivers/ipmi/chip.h b/src/drivers/ipmi/chip.h new file mode 100644 index 0000000..eb8b4e6 --- /dev/null +++ b/src/drivers/ipmi/chip.h @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Patrick Rudolph siro@das-labor.org + * + * 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 _IMPI_CHIP_H_ +#define _IPMI_CHIP_H_ + +struct drivers_ipmi_config { + u8 bmc_i2c_address; + u8 have_nv_storage; + u8 nv_storage_device_address; + u8 have_gpe; + u8 gpe_interrupt; + u8 have_apic; + u32 apic_interrupt; +}; + +#endif /* _IMPI_CHIP_H_ */ diff --git a/src/drivers/ipmi/ipmi_kcs.h b/src/drivers/ipmi/ipmi_kcs.h index 3cd7609..b43f043 100644 --- a/src/drivers/ipmi/ipmi_kcs.h +++ b/src/drivers/ipmi/ipmi_kcs.h @@ -26,7 +26,26 @@
#define IPMI_CMD_ACPI_POWERON 0x06
+#define IPMI_SET_SYS_INFO 0x58 +#define IPMI_GET_SYS_INFO 0x59 + +#define IPMI_BMC_GET_DEVICE_ID 0x01 + extern int ipmi_kcs_message(int port, int netfn, int lun, int cmd, const unsigned char *inmsg, int inlen, unsigned char *outmsg, int outlen); + +struct ipmi_devid_rsp { + uint8_t device_id; + uint8_t device_revision; + uint8_t fw_rev1; + uint8_t fw_rev2; + uint8_t ipmi_version; + uint8_t adtl_device_support; + uint8_t manufacturer_id[3]; + uint8_t product_id[2]; + uint8_t aux_fw_rev[4]; +} __packed; + + #endif diff --git a/src/drivers/ipmi/ipmi_kcs_ops.c b/src/drivers/ipmi/ipmi_kcs_ops.c new file mode 100644 index 0000000..3c394db --- /dev/null +++ b/src/drivers/ipmi/ipmi_kcs_ops.c @@ -0,0 +1,197 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 9elements Agency GmbH + * + * 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. + * + * Place in devicetree.cb: + * + * chip drivers/ipmi + * device pnp 3ca.0 on end # IPMI KCS + * end + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pnp.h> +#include <arch/acpi.h> +#include <smbios.h> +#include <version.h> +#include <delay.h> +#include "ipmi_kcs.h" +#include "chip.h" + +u16 ipmi_revision = 0x1500; + +static void ipmi_set_firmware_version(struct device *dev, const char *firmware) +{ + char msg[18]; + + if (!firmware || strlen(firmware) > 255) + return; + + msg[0] = 1; + msg[1] = 0; + msg[2] = 0; + msg[3] = strlen(firmware); + + memcpy(&msg[4], firmware, MIN(strlen(firmware), 12)); + firmware += MIN(strlen(firmware), 12); + + ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0, + IPMI_SET_SYS_INFO, (const u8 *)msg, sizeof(msg), + NULL, 0); + + do { + msg[1] ++; + memset(&msg[2], 0, 16); + + if (strlen(firmware)) { + memcpy(&msg[2], firmware, MIN(strlen(firmware), 16)); + firmware += MIN(strlen(firmware), 16); + } + + ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0, + IPMI_SET_SYS_INFO, (const u8 *)msg, + sizeof(msg), NULL, 0); + + } while (strlen(firmware)); +} + +static int ipmi_get_device_id(struct device *dev, struct ipmi_devid_rsp *rsp) +{ + if (ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0, + IPMI_BMC_GET_DEVICE_ID, NULL, 0, (u8 *)rsp, + sizeof(*rsp)) != sizeof(*rsp)) { + printk(BIOS_ERR, "IPMI: Failed to get device id\n"); + return 1; + } + return 0; +} + +static void ipmi_kcs_init(struct device *dev) +{ + struct ipmi_devid_rsp rsp; + + if (!dev->enabled) + return; + + /* Set firmware version string */ + ipmi_set_firmware_version(dev, coreboot_version); + + /* Get IPMI version for ACPI */ + if (!ipmi_get_device_id(dev, &rsp)) + ipmi_revision = rsp.ipmi_version; +} + +static void ipmi_set_resources(struct device *dev) +{ +} + +static void ipmi_enable_resources(struct device *dev) +{ +} + +#if CONFIG(HAVE_ACPI_TABLES) +static unsigned long +ipmi_write_acpi_tables(struct device *dev, unsigned long current, + struct acpi_rsdp *rsdp) +{ + struct drivers_ipmi_config *conf = NULL; + struct acpi_spmi *spmi; + s8 gpe_interrupt = -1; + u32 apic_interrupt = 0; + acpi_addr_t addr = { + .space_id = ACPI_ADDRESS_SPACE_IO, + .access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS, + .addrl = dev->path.pnp.port, + }; + + current = ALIGN(current, 8); + printk(BIOS_DEBUG, "ACPI: * SPMI at %lx\n", current); + spmi = (struct acpi_spmi *)current; + + if (dev->chip_info) + conf = dev->chip_info; + + if (conf) { + if (conf->have_gpe) + gpe_interrupt = conf->gpe_interrupt; + if (conf->have_apic) + apic_interrupt = conf->apic_interrupt; + } + acpi_create_ipmi(dev, spmi, ipmi_revision, &addr, IPMI_INTERFACE_KCS, + gpe_interrupt, apic_interrupt); + + acpi_add_table(rsdp, spmi); + + current += spmi->header.length; + + return current; +} +#endif + +#if CONFIG(GENERATE_SMBIOS_TABLES) +static int ipmi_smbios_data(struct device *dev, int *handle, + unsigned long *current) +{ + struct drivers_ipmi_config *conf = NULL; + u8 nv_storage = 0xff; + u8 i2c_address = 0; + int len = 0; + + if (dev->chip_info) + conf = dev->chip_info; + + if (conf) { + if (conf->have_nv_storage) + nv_storage = conf->nv_storage_device_address; + i2c_address = conf->bmc_i2c_address; + } + + // add IPMI Device Information + len += smbios_write_type38( + current, handle, + SMBIOS_BMC_INTERFACE_KCS, + ipmi_revision >> 4, // IPMI Version + i2c_address, // I2C address + nv_storage, // NV storage + dev->path.pnp.port | 1, // IO port interface address + 0, + 0); // no IRQ + + return len; +} +#endif + +static struct device_operations ops = { + .read_resources = pnp_read_resources, + .set_resources = ipmi_set_resources, + .enable_resources = ipmi_enable_resources, + .init = ipmi_kcs_init, +#if CONFIG(HAVE_ACPI_TABLES) + .write_acpi_tables = ipmi_write_acpi_tables, +#endif +#if CONFIG(GENERATE_SMBIOS_TABLES) + .get_smbios_data = ipmi_smbios_data, +#endif +}; + +static void enable_dev(struct device *dev) +{ + dev->ops = &ops; +} + +struct chip_operations drivers_ipmi_kcs_ops = { + CHIP_NAME("IPMI KCS") + .enable_dev = enable_dev, +};
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 1:
(2 comments)
https://review.coreboot.org/#/c/33255/1/src/arch/x86/include/arch/acpi.h File src/arch/x86/include/arch/acpi.h:
https://review.coreboot.org/#/c/33255/1/src/arch/x86/include/arch/acpi.h@816 PS1, Line 816: } __packed ; space prohibited before semicolon
https://review.coreboot.org/#/c/33255/1/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/1/src/drivers/ipmi/ipmi_kcs_ops.c@55 PS1, Line 55: msg[1] ++; space prohibited before that '++' (ctx:WxO)
Hello build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/33255
to look at the new patch set (#2).
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add SPMI ACPI code * Add chips ops for IPMI KCS. * Set firmware version over KCS. * Get IPMI version over KCS. * Generate ACPI SPMI for IPMI KCS. * Generate SMBIOS type 38 for IPMI KCS.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/arch/x86/acpi.c M src/arch/x86/include/arch/acpi.h M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 6 files changed, 382 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/33255/2
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 2:
(2 comments)
https://review.coreboot.org/#/c/33255/2/src/arch/x86/include/arch/acpi.h File src/arch/x86/include/arch/acpi.h:
https://review.coreboot.org/#/c/33255/2/src/arch/x86/include/arch/acpi.h@816 PS2, Line 816: } __packed ; space prohibited before semicolon
https://review.coreboot.org/#/c/33255/2/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/2/src/drivers/ipmi/ipmi_kcs_ops.c@60 PS2, Line 60: msg[1] ++; space prohibited before that '++' (ctx:WxO)
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 3:
(2 comments)
https://review.coreboot.org/#/c/33255/3/src/arch/x86/include/arch/acpi.h File src/arch/x86/include/arch/acpi.h:
https://review.coreboot.org/#/c/33255/3/src/arch/x86/include/arch/acpi.h@816 PS3, Line 816: } __packed ; space prohibited before semicolon
https://review.coreboot.org/#/c/33255/3/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/3/src/drivers/ipmi/ipmi_kcs_ops.c@60 PS3, Line 60: msg[1] ++; space prohibited before that '++' (ctx:WxO)
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 4:
(2 comments)
https://review.coreboot.org/#/c/33255/4/src/arch/x86/include/arch/acpi.h File src/arch/x86/include/arch/acpi.h:
https://review.coreboot.org/#/c/33255/4/src/arch/x86/include/arch/acpi.h@816 PS4, Line 816: } __packed ; space prohibited before semicolon
https://review.coreboot.org/#/c/33255/4/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/4/src/drivers/ipmi/ipmi_kcs_ops.c@60 PS4, Line 60: msg[1] ++; space prohibited before that '++' (ctx:WxO)
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 5:
(2 comments)
https://review.coreboot.org/#/c/33255/5/src/arch/x86/include/arch/acpi.h File src/arch/x86/include/arch/acpi.h:
https://review.coreboot.org/#/c/33255/5/src/arch/x86/include/arch/acpi.h@816 PS5, Line 816: } __packed ; space prohibited before semicolon
https://review.coreboot.org/#/c/33255/5/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/5/src/drivers/ipmi/ipmi_kcs_ops.c@60 PS5, Line 60: msg[1] ++; space prohibited before that '++' (ctx:WxO)
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 6:
(2 comments)
https://review.coreboot.org/#/c/33255/6/src/arch/x86/include/arch/acpi.h File src/arch/x86/include/arch/acpi.h:
https://review.coreboot.org/#/c/33255/6/src/arch/x86/include/arch/acpi.h@816 PS6, Line 816: } __packed ; space prohibited before semicolon
https://review.coreboot.org/#/c/33255/6/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/6/src/drivers/ipmi/ipmi_kcs_ops.c@60 PS6, Line 60: msg[1] ++; space prohibited before that '++' (ctx:WxO)
Hello Christian Walter, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/33255
to look at the new patch set (#7).
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add chips ops for IPMI KCS. * Get IPMI version over KCS. * Generates ACPI SPMI table for IPMI KCS. * Generates SMBIOS type 38 for IPMI KCS. * Generates ACPI SPMI device for IPMI KCS on LPC device. * Add documentation
To use this driver on BMC that support KCS on I/O:
1. Add an entry to the devicetree.cb:
chip drivers/ipmi device pnp ca2.0 on end # IPMI KCS end
2. Select IPMI_KCS in Kconfig. 3. (Optional) enable LPC I/O decode for the given address.
Tested on Wedge100s.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- A Documentation/drivers/index.md A Documentation/drivers/ipmi_kcs.md M Documentation/index.md M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 7 files changed, 360 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/33255/7
Hello Timothy Pearson, Felix Held, Łukasz Siudut, David Hendricks, Christian Walter, Philipp Deppenwiese, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/33255
to look at the new patch set (#8).
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add chips ops for IPMI KCS. * Get IPMI version over KCS. * Generates ACPI SPMI table for IPMI KCS. * Generates SMBIOS type 38 for IPMI KCS. * Generates ACPI SPMI device for IPMI KCS on LPC device. * Add documentation
To use this driver on BMC that support KCS on I/O:
1. Add an entry to the devicetree.cb:
chip drivers/ipmi device pnp ca2.0 on end # IPMI KCS end
2. Select IPMI_KCS in Kconfig. 3. (Optional) enable LPC I/O decode for the given address.
Tested on Wedge100s.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- A Documentation/drivers/index.md A Documentation/drivers/ipmi_kcs.md M Documentation/index.md M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 7 files changed, 368 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/33255/8
Felix Held has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 8:
(2 comments)
didn't really review ipmi_kcs_ops.c yet
https://review.coreboot.org/#/c/33255/8/Documentation/drivers/ipmi_kcs.md File Documentation/drivers/ipmi_kcs.md:
https://review.coreboot.org/#/c/33255/8/Documentation/drivers/ipmi_kcs.md@14 PS8, Line 14: remove whitespace
https://review.coreboot.org/#/c/33255/8/src/drivers/ipmi/ipmi_kcs.h File src/drivers/ipmi/ipmi_kcs.h:
https://review.coreboot.org/#/c/33255/8/src/drivers/ipmi/ipmi_kcs.h@51 PS8, Line 51: adtl this abbreviation for additional isn't very obvious; i'd either not abbreviate it (preferred option) or at least name it addtl (just the vowel removed and not the rest deduplicated)
Hello Timothy Pearson, Felix Held, Łukasz Siudut, David Hendricks, Christian Walter, Philipp Deppenwiese, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/33255
to look at the new patch set (#9).
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add chips ops for IPMI KCS. * Get IPMI version over KCS. * Generates ACPI SPMI table for IPMI KCS. * Generates SMBIOS type 38 for IPMI KCS. * Generates ACPI SPMI device for IPMI KCS on LPC device. * Add documentation
To use this driver on BMC that support KCS on I/O:
1. Add an entry to the devicetree.cb:
chip drivers/ipmi device pnp ca2.0 on end # IPMI KCS end
2. Select IPMI_KCS in Kconfig. 3. (Optional) enable LPC I/O decode for the given address.
Tested on Wedge100s.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- A Documentation/drivers/index.md A Documentation/drivers/ipmi_kcs.md M Documentation/index.md M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 7 files changed, 368 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/33255/9
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 9:
(2 comments)
https://review.coreboot.org/#/c/33255/8/Documentation/drivers/ipmi_kcs.md File Documentation/drivers/ipmi_kcs.md:
https://review.coreboot.org/#/c/33255/8/Documentation/drivers/ipmi_kcs.md@14 PS8, Line 14:
remove whitespace
Done
https://review.coreboot.org/#/c/33255/8/src/drivers/ipmi/ipmi_kcs.h File src/drivers/ipmi/ipmi_kcs.h:
https://review.coreboot.org/#/c/33255/8/src/drivers/ipmi/ipmi_kcs.h@51 PS8, Line 51: adtl
this abbreviation for additional isn't very obvious; i'd either not abbreviate it (preferred option) […]
Done
Christian Walter has uploaded a new patch set (#10) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add SPMI ACPI code * Add chips ops for IPMI KCS. * Set firmware version over KCS. * Get IPMI version over KCS. * Generate ACPI SPMI for IPMI KCS. * Generate SMBIOS type 38 for IPMI KCS.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/arch/x86/acpi.c M src/arch/x86/include/arch/acpi.h M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 6 files changed, 382 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/33255/10
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 10:
(2 comments)
https://review.coreboot.org/#/c/33255/10/src/arch/x86/include/arch/acpi.h File src/arch/x86/include/arch/acpi.h:
https://review.coreboot.org/#/c/33255/10/src/arch/x86/include/arch/acpi.h@81... PS10, Line 816: } __packed ; space prohibited before semicolon
https://review.coreboot.org/#/c/33255/10/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/10/src/drivers/ipmi/ipmi_kcs_ops.c@60 PS10, Line 60: msg[1] ++; space prohibited before that '++' (ctx:WxO)
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 11:
(2 comments)
https://review.coreboot.org/#/c/33255/11/src/arch/x86/include/arch/acpi.h File src/arch/x86/include/arch/acpi.h:
https://review.coreboot.org/#/c/33255/11/src/arch/x86/include/arch/acpi.h@81... PS11, Line 816: } __packed ; space prohibited before semicolon
https://review.coreboot.org/#/c/33255/11/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/11/src/drivers/ipmi/ipmi_kcs_ops.c@60 PS11, Line 60: msg[1] ++; space prohibited before that '++' (ctx:WxO)
Christian Walter has uploaded a new patch set (#12) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add SPMI ACPI code * Add chips ops for IPMI KCS. * Set firmware version over KCS. * Get IPMI version over KCS. * Generate ACPI SPMI for IPMI KCS. * Generate SMBIOS type 38 for IPMI KCS.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/arch/x86/acpi.c M src/arch/x86/include/arch/acpi.h M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 6 files changed, 382 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/33255/12
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 12:
(2 comments)
https://review.coreboot.org/#/c/33255/12/src/arch/x86/include/arch/acpi.h File src/arch/x86/include/arch/acpi.h:
https://review.coreboot.org/#/c/33255/12/src/arch/x86/include/arch/acpi.h@81... PS12, Line 816: } __packed ; space prohibited before semicolon
https://review.coreboot.org/#/c/33255/12/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/12/src/drivers/ipmi/ipmi_kcs_ops.c@60 PS12, Line 60: msg[1] ++; space prohibited before that '++' (ctx:WxO)
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 13:
(2 comments)
https://review.coreboot.org/#/c/33255/13/src/arch/x86/include/arch/acpi.h File src/arch/x86/include/arch/acpi.h:
https://review.coreboot.org/#/c/33255/13/src/arch/x86/include/arch/acpi.h@81... PS13, Line 816: } __packed ; space prohibited before semicolon
https://review.coreboot.org/#/c/33255/13/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/13/src/drivers/ipmi/ipmi_kcs_ops.c@60 PS13, Line 60: msg[1] ++; space prohibited before that '++' (ctx:WxO)
Hello Timothy Pearson, Felix Held, Łukasz Siudut, David Hendricks, Christian Walter, Philipp Deppenwiese, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/33255
to look at the new patch set (#14).
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add chips ops for IPMI KCS. * Get IPMI version over KCS. * Generates ACPI SPMI table for IPMI KCS. * Generates SMBIOS type 38 for IPMI KCS. * Generates ACPI SPMI device for IPMI KCS on LPC device. * Add documentation
To use this driver on BMC that support KCS on I/O:
1. Add an entry to the devicetree.cb:
chip drivers/ipmi device pnp ca2.0 on end # IPMI KCS end
2. Select IPMI_KCS in Kconfig. 3. (Optional) enable LPC I/O decode for the given address.
Tested on Wedge100s.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- A Documentation/drivers/index.md A Documentation/drivers/ipmi_kcs.md M Documentation/index.md M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 7 files changed, 375 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/33255/14
Hello Timothy Pearson, Felix Held, Łukasz Siudut, David Hendricks, Christian Walter, Philipp Deppenwiese, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/33255
to look at the new patch set (#16).
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add chips ops for IPMI KCS. * Get IPMI version over KCS. * Generates ACPI SPMI table for IPMI KCS. * Generates SMBIOS type 38 for IPMI KCS. * Generates ACPI SPMI device for IPMI KCS on LPC device. * Add documentation
To use this driver on BMC that support KCS on I/O:
1. Add an entry to the devicetree.cb:
chip drivers/ipmi device pnp ca2.0 on end # IPMI KCS end
2. Select IPMI_KCS in Kconfig. 3. (Optional) enable LPC I/O decode for the given address.
Tested on Wedge100s.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- A Documentation/drivers/index.md A Documentation/drivers/ipmi_kcs.md M Documentation/index.md M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 7 files changed, 375 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/33255/16
Felix Held has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 16:
(6 comments)
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@107 PS16, Line 107: ALIGN ALIGN_UP does the same, but is more obvious; had to look in the code to see if it does what i'd expect
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@157 PS16, Line 157: acpigen_write_STA(0xf); haven't looked at the details, but is this correct? didn't see the 0xf mentioned in the spec at this place
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@209 PS16, Line 209: 1 having this as a define would be nice, but could be done in a follow-up patch
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@230 PS16, Line 230: static void ipmi_enable_resources(struct device *dev) is it really needed to have this empty function? also see the ops struct below
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@237 PS16, Line 237: res->base = dev->path.pnp.port; maybe check for alignment or mask the last bit?
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@245 PS16, Line 245: .enable_resources = ipmi_enable_resources, see above
Hello Timothy Pearson, Felix Held, Łukasz Siudut, David Hendricks, Christian Walter, Philipp Deppenwiese, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/33255
to look at the new patch set (#17).
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add chips ops for IPMI KCS. * Get IPMI version over KCS. * Generates ACPI SPMI table for IPMI KCS. * Generates SMBIOS type 38 for IPMI KCS. * Generates ACPI SPMI device for IPMI KCS on LPC device. * Add documentation
To use this driver on BMC that support KCS on I/O:
1. Add an entry to the devicetree.cb:
chip drivers/ipmi device pnp ca2.0 on end # IPMI KCS end
2. Select IPMI_KCS in Kconfig. 3. (Optional) enable LPC I/O decode for the given address.
Tested on Wedge100s.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- A Documentation/drivers/index.md A Documentation/drivers/ipmi_kcs.md M Documentation/index.md M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 7 files changed, 376 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/33255/17
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 17:
(6 comments)
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c File src/drivers/ipmi/ipmi_kcs_ops.c:
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@107 PS16, Line 107: ALIGN
ALIGN_UP does the same, but is more obvious; had to look in the code to see if it does what i'd expe […]
All of the acpi code uses ALIGN. Used ALIGN_UP to clarify.
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@157 PS16, Line 157: acpigen_write_STA(0xf);
haven't looked at the details, but is this correct? didn't see the 0xf mentioned in the spec at this […]
IPMI spec chapter "C3-2 Locating IPMI System Interfaces in ACPI Name Space" recommends the usage of _STA, but it's not shown in the examples.
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@209 PS16, Line 209: 1
having this as a define would be nice, but could be done in a follow-up patch
Ack
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@230 PS16, Line 230: static void ipmi_enable_resources(struct device *dev)
is it really needed to have this empty function? also see the ops struct below
Done
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@237 PS16, Line 237: res->base = dev->path.pnp.port;
maybe check for alignment or mask the last bit?
done in enable_dev
https://review.coreboot.org/#/c/33255/16/src/drivers/ipmi/ipmi_kcs_ops.c@245 PS16, Line 245: .enable_resources = ipmi_enable_resources,
see above
Done
Felix Held has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
Patch Set 17: Code-Review+2
Felix Held has submitted this change and it was merged. ( https://review.coreboot.org/c/coreboot/+/33255 )
Change subject: drivers/ipmi: Add chip ops ......................................................................
drivers/ipmi: Add chip ops
* Add chips ops for IPMI KCS. * Get IPMI version over KCS. * Generates ACPI SPMI table for IPMI KCS. * Generates SMBIOS type 38 for IPMI KCS. * Generates ACPI SPMI device for IPMI KCS on LPC device. * Add documentation
To use this driver on BMC that support KCS on I/O:
1. Add an entry to the devicetree.cb:
chip drivers/ipmi device pnp ca2.0 on end # IPMI KCS end
2. Select IPMI_KCS in Kconfig. 3. (Optional) enable LPC I/O decode for the given address.
Tested on Wedge100s.
Change-Id: I73cbd2058ccdc5395baf244f31345a85eb0047d7 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/33255 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Felix Held felix-coreboot@felixheld.de --- A Documentation/drivers/index.md A Documentation/drivers/ipmi_kcs.md M Documentation/index.md M src/drivers/ipmi/Makefile.inc A src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_kcs.h A src/drivers/ipmi/ipmi_kcs_ops.c 7 files changed, 376 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Felix Held: Looks good to me, approved
diff --git a/Documentation/drivers/index.md b/Documentation/drivers/index.md new file mode 100644 index 0000000..642ae1a --- /dev/null +++ b/Documentation/drivers/index.md @@ -0,0 +1,7 @@ +# Platform indenpendend drivers documentation + +The drivers can be found in `src/drivers`. They are intended for onboard +and plugin devices, significantly reducing integration complexity and +they allow to easily reuse existing code accross platforms. + +* [IPMI KCS](ipmi_kcs.md) diff --git a/Documentation/drivers/ipmi_kcs.md b/Documentation/drivers/ipmi_kcs.md new file mode 100644 index 0000000..f6f0fb9 --- /dev/null +++ b/Documentation/drivers/ipmi_kcs.md @@ -0,0 +1,47 @@ +# IPMI KCS driver + +The driver can be found in `src/drivers/ipmi/`. It works with BMC that provide +a KCS I/O interface as specified in the [IPMI] standard. + +The driver detects the IPMI version, reserves the I/O space in coreboot's +resource allocator and writes the required ACPI and SMBIOS tables. + +## For developers + +To use the driver, select the `IPMI_KCS` Kconfig and add the following PNP +device under the LPC bridge device (in example for the KCS at 0xca2): + +``` + chip drivers/ipmi + device pnp ca2.0 on end # IPMI KCS + end +``` + +**Note:** The I/O base address needs to be aligned to 2. + +The following registers can be set: + +* `have_nv_storage` + * Boolean + * If true `nv_storage_device_address` will be added to SMBIOS type 38. +* `nv_storage_device_address` + * Integer + * The NV storage address as defined in SMBIOS spec for type 38. +* `bmc_i2c_address` + * Integer + * The i2c address of the BMC. zero if not applicable. +* `have_apic` + * Boolean + * If true the `apic_interrupt` will be added to SPMI table. +* `apic_interrupt` + * Integer + * The APIC interrupt used to notify about a change on the KCS. +* `have_gpe` + * Boolean + * If true the `gpe_interrupt` will be added to SPMI table. +* `gpe_interrupt` + * Integer + * The bit in GPE (SCI) used to notify about a change on the KCS. + + +[IPMI]: https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/... diff --git a/Documentation/index.md b/Documentation/index.md index 76faffa..a2c2878 100644 --- a/Documentation/index.md +++ b/Documentation/index.md @@ -175,6 +175,7 @@ * [Native Graphics Initialization with libgfxinit](gfx/libgfxinit.md) * [Display panel-specific documentation](gfx/display-panel.md) * [Architecture-specific documentation](arch/index.md) +* [Platform independend drivers documentation](drivers/index.md) * [Northbridge-specific documentation](northbridge/index.md) * [System on Chip-specific documentation](soc/index.md) * [Mainboard-specific documentation](mainboard/index.md) diff --git a/src/drivers/ipmi/Makefile.inc b/src/drivers/ipmi/Makefile.inc index e9e7ff3..a29c2e2 100644 --- a/src/drivers/ipmi/Makefile.inc +++ b/src/drivers/ipmi/Makefile.inc @@ -1 +1,2 @@ ramstage-$(CONFIG_IPMI_KCS) += ipmi_kcs.c +ramstage-$(CONFIG_IPMI_KCS) += ipmi_kcs_ops.c diff --git a/src/drivers/ipmi/chip.h b/src/drivers/ipmi/chip.h new file mode 100644 index 0000000..eb8b4e6 --- /dev/null +++ b/src/drivers/ipmi/chip.h @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Patrick Rudolph siro@das-labor.org + * + * 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 _IMPI_CHIP_H_ +#define _IPMI_CHIP_H_ + +struct drivers_ipmi_config { + u8 bmc_i2c_address; + u8 have_nv_storage; + u8 nv_storage_device_address; + u8 have_gpe; + u8 gpe_interrupt; + u8 have_apic; + u32 apic_interrupt; +}; + +#endif /* _IMPI_CHIP_H_ */ diff --git a/src/drivers/ipmi/ipmi_kcs.h b/src/drivers/ipmi/ipmi_kcs.h index 3cd7609..a194dd2 100644 --- a/src/drivers/ipmi/ipmi_kcs.h +++ b/src/drivers/ipmi/ipmi_kcs.h @@ -20,6 +20,10 @@ #define IPMI_NETFN_BRIDGE 0x02 #define IPMI_NETFN_SENSOREVENT 0x04 #define IPMI_NETFN_APPLICATION 0x06 +#define IPMI_BMC_GET_DEVICE_ID 0x01 +#define IPMI_IPMI_VERSION_MINOR(x) ((x) >> 4) +#define IPMI_IPMI_VERSION_MAJOR(x) ((x) & 0xf) + #define IPMI_NETFN_FIRMWARE 0x08 #define IPMI_NETFN_STORAGE 0x0a #define IPMI_NETFN_TRANSPORT 0x0c @@ -29,4 +33,24 @@ extern int ipmi_kcs_message(int port, int netfn, int lun, int cmd, const unsigned char *inmsg, int inlen, unsigned char *outmsg, int outlen); + +struct ipmi_rsp { + uint8_t lun; + uint8_t cmd; + uint8_t completion_code; +} __packed; + +/* Get Device ID */ +struct ipmi_devid_rsp { + struct ipmi_rsp resp; + uint8_t device_id; + uint8_t device_revision; + uint8_t fw_rev1; + uint8_t fw_rev2; + uint8_t ipmi_version; + uint8_t additional_device_support; + uint8_t manufacturer_id[3]; + uint8_t product_id[2]; +} __packed; + #endif diff --git a/src/drivers/ipmi/ipmi_kcs_ops.c b/src/drivers/ipmi/ipmi_kcs_ops.c new file mode 100644 index 0000000..0cc4e0a --- /dev/null +++ b/src/drivers/ipmi/ipmi_kcs_ops.c @@ -0,0 +1,267 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 9elements Agency GmbH + * + * 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. + * + * Place in devicetree.cb: + * + * chip drivers/ipmi + * device pnp ca2.0 on end # IPMI KCS + * end + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pnp.h> +#if CONFIG(HAVE_ACPI_TABLES) +#include <arch/acpi.h> +#include <arch/acpigen.h> +#endif +#if CONFIG(GENERATE_SMBIOS_TABLES) +#include <smbios.h> +#endif +#include <version.h> +#include <delay.h> +#include "ipmi_kcs.h" +#include "chip.h" + +/* 4 bit encoding */ +static u8 ipmi_revision_major = 0x1; +static u8 ipmi_revision_minor = 0x0; + +static int ipmi_get_device_id(struct device *dev, struct ipmi_devid_rsp *rsp) +{ + int ret; + + ret = ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0, + IPMI_BMC_GET_DEVICE_ID, NULL, 0, (u8 *)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 1; + } + if (ret != sizeof(*rsp)) { + printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__); + return 1; + } + return 0; +} + +static void ipmi_kcs_init(struct device *dev) +{ + struct ipmi_devid_rsp rsp; + uint32_t man_id = 0, prod_id = 0; + + if (!dev->enabled) + return; + + /* Get IPMI version for ACPI and SMBIOS */ + if (!ipmi_get_device_id(dev, &rsp)) { + ipmi_revision_minor = IPMI_IPMI_VERSION_MINOR(rsp.ipmi_version); + ipmi_revision_major = IPMI_IPMI_VERSION_MAJOR(rsp.ipmi_version); + + memcpy(&man_id, rsp.manufacturer_id, + sizeof(rsp.manufacturer_id)); + + memcpy(&prod_id, rsp.product_id, sizeof(rsp.product_id)); + + printk(BIOS_INFO, "IPMI: Found man_id 0x%06x, prod_id 0x%04x\n", + man_id, prod_id); + + printk(BIOS_INFO, "IPMI: Version %01x.%01x\n", + ipmi_revision_major, ipmi_revision_minor); + } else { + /* Don't write tables if communication failed */ + dev->enabled = 0; + } +} + +#if CONFIG(HAVE_ACPI_TABLES) +static uint32_t uid_cnt = 0; + +static unsigned long +ipmi_write_acpi_tables(struct device *dev, unsigned long current, + struct acpi_rsdp *rsdp) +{ + struct drivers_ipmi_config *conf = NULL; + struct acpi_spmi *spmi; + s8 gpe_interrupt = -1; + u32 apic_interrupt = 0; + acpi_addr_t addr = { + .space_id = ACPI_ADDRESS_SPACE_IO, + .access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS, + .addrl = dev->path.pnp.port, + }; + + current = ALIGN_UP(current, 8); + printk(BIOS_DEBUG, "ACPI: * SPMI at %lx\n", current); + spmi = (struct acpi_spmi *)current; + + if (dev->chip_info) + conf = dev->chip_info; + + if (conf) { + if (conf->have_gpe) + gpe_interrupt = conf->gpe_interrupt; + if (conf->have_apic) + apic_interrupt = conf->apic_interrupt; + } + + /* Use command to get UID from ipmi_ssdt */ + acpi_create_ipmi(dev, spmi, (ipmi_revision_major << 8) | + (ipmi_revision_minor << 4), &addr, + IPMI_INTERFACE_KCS, gpe_interrupt, apic_interrupt, + dev->command); + + acpi_add_table(rsdp, spmi); + + current += spmi->header.length; + + return current; +} + +static void ipmi_ssdt(struct device *dev) +{ + const char *scope = acpi_device_scope(dev); + struct drivers_ipmi_config *conf = NULL; + + if (!scope) { + printk(BIOS_ERR, "IPMI: Missing ACPI scope for %s\n", + dev_path(dev)); + return; + } + + if (dev->chip_info) + conf = dev->chip_info; + + /* Use command to pass UID to ipmi_write_acpi_tables */ + dev->command = uid_cnt++; + + /* write SPMI device */ + acpigen_write_scope(scope); + acpigen_write_device("SPMI"); + acpigen_write_name_string("_HID", "IPI0001"); + acpigen_write_name_string("_STR", "IPMI_KCS"); + acpigen_write_name_byte("_UID", dev->command); + acpigen_write_STA(0xf); + acpigen_write_name("_CRS"); + acpigen_write_resourcetemplate_header(); + acpigen_write_io16(dev->path.pnp.port, dev->path.pnp.port, 1, 2, 1); + + if (conf) { + // FIXME: is that correct? + if (conf->have_apic) + acpigen_write_irq(1 << conf->apic_interrupt); + } + + acpigen_write_resourcetemplate_footer(); + + acpigen_write_method("_IFT", 0); + acpigen_write_return_byte(1); // KCS + acpigen_pop_len(); + + acpigen_write_method("_SRV", 0); + acpigen_write_return_integer((ipmi_revision_major << 8) | + (ipmi_revision_minor << 4)); + acpigen_pop_len(); + + acpigen_pop_len(); /* pop device */ + acpigen_pop_len(); /* pop scope */ +} +#endif + +#if CONFIG(GENERATE_SMBIOS_TABLES) +static int ipmi_smbios_data(struct device *dev, int *handle, + unsigned long *current) +{ + struct drivers_ipmi_config *conf = NULL; + u8 nv_storage = 0xff; + u8 i2c_address = 0; + int len = 0; + + if (dev->chip_info) + conf = dev->chip_info; + + if (conf) { + if (conf->have_nv_storage) + nv_storage = conf->nv_storage_device_address; + i2c_address = conf->bmc_i2c_address; + } + + // add IPMI Device Information + len += smbios_write_type38( + current, handle, + SMBIOS_BMC_INTERFACE_KCS, + ipmi_revision_minor | (ipmi_revision_major << 4), + i2c_address, // I2C address + nv_storage, // NV storage + dev->path.pnp.port | 1, // IO interface + 0, + 0); // no IRQ + + return len; +} +#endif + +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, + .enable_resources = DEVICE_NOOP, + .init = ipmi_kcs_init, +#if CONFIG(HAVE_ACPI_TABLES) + .write_acpi_tables = ipmi_write_acpi_tables, + .acpi_fill_ssdt_generator = ipmi_ssdt, +#endif +#if CONFIG(GENERATE_SMBIOS_TABLES) + .get_smbios_data = ipmi_smbios_data, +#endif +}; + +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_ipmi_ops = { + CHIP_NAME("IPMI KCS") + .enable_dev = enable_dev, +};