Merge tag 'ipmi-for-qemu-10.0' of https://github.com/cminyard/qemu into staging

Some minor fixes for various things

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEE/Q1c5nzg9ZpmiCaGYfOMkJGb/4EFAmgAQuQACgkQYfOMkJGb
# /4G9EQ//do2GgBjj2NChR7G8CV7DyAA7rnhYx1txD8I4F1cyvMAW0flc8qE5MaC8
# pJpfvQwYJs60WQbg5RELEEPFubtMPz/OPgfZfpGsXBRwqbpl2c3JGrEpVnDpsqdW
# VXd24gFEuHyFKLoa4VMeJ40TvCsHsndkFTb7v12mneiH52YJyYDdb6ywkbeJS34F
# 1sX745LtgQbC/piFzcuwX/NvSPlk3O9FT84k4AdfUPpBJNicQ6aKeQB/kuXmecEU
# 6i6j8E/oCzZM9yLXWFFg3Fit5F24CBK9uDpFLE1ctoOW0lsVaQ+e8ogprvY7KMlO
# zZVu2CPOZPf6IwUC/nmvWukey1BHpJSpEwZPZJao3Bt+qxK3hEl2FNPQIBVLNsJ9
# /6f6VtdgYSkkMed3G11eVS+p5QwX+4GEg+rhV8HDMYPecpaSePR3DIomAUKTc9je
# t89ooW3iy6egONcbZSlFILPRmfRHv2h6aLOSMAAFXgx4aKt1I9b0EpjqBvDgTIxZ
# 3ehn2jnwG8jTYaJdkiXFvvYNn2A8qEJc1Hifud1skJchqFXn7e6mjneLuOWO4uYZ
# /VnOljqu+KwyDWxCnMfkLuOd+PNnHvB9fctqRvYJpsyc+WyjmRhH+YlbG2yt/FZj
# fmCjZWKrZR2e6GaUPQSTEpahbuySf4QV4B9sP+YOcSQFy3N8ocU=
# =V8+d
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 16 Apr 2025 19:53:08 EDT
# gpg:                using RSA key FD0D5CE67CE0F59A6688268661F38C90919BFF81
# gpg: Good signature from "Corey Minyard <cminyard@mvista.com>" [unknown]
# gpg:                 aka "Corey Minyard <corey@minyard.net>" [unknown]
# gpg:                 aka "Corey Minyard <minyard@mvista.com>" [unknown]
# gpg:                 aka "Corey Minyard <minyard@acm.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: FD0D 5CE6 7CE0 F59A 6688  2686 61F3 8C90 919B FF81

* tag 'ipmi-for-qemu-10.0' of https://github.com/cminyard/qemu:
  ipmi/bmc-sim: add error handling for 'Set BMC Global Enables' command
  ipmi/bmc-sim: implement watchdog dont log flag
  ipmi/bmc-sim: Add 'Get Channel Info' command
  ipmi: add fwinfo to pci ipmi devices
  ipmi/pci-ipmi-bt: Rename copy-paste variables
  hw/ipmi: Move vmsd registration to device class

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2025-04-23 09:29:02 -04:00
11 changed files with 170 additions and 46 deletions
+2 -1
View File
@@ -55,7 +55,8 @@ static Aml *aml_ipmi_crs(IPMIFwInfo *info)
abort();
}
if (info->interrupt_number) {
/* Should PCI interrupts also be appended? */
if (info->irq_source == IPMI_ISA_IRQ && info->interrupt_number) {
aml_append(crs, aml_irq_no_flags(info->interrupt_number));
}
+1 -2
View File
@@ -497,8 +497,6 @@ static void ipmi_bmc_extern_realize(DeviceState *dev, Error **errp)
qemu_chr_fe_set_handlers(&ibe->chr, can_receive, receive,
chr_event, NULL, ibe, NULL, true);
vmstate_register(NULL, 0, &vmstate_ipmi_bmc_extern, ibe);
}
static void ipmi_bmc_extern_init(Object *obj)
@@ -528,6 +526,7 @@ static void ipmi_bmc_extern_class_init(ObjectClass *oc, void *data)
bk->handle_reset = ipmi_bmc_extern_handle_reset;
dc->hotpluggable = false;
dc->realize = ipmi_bmc_extern_realize;
dc->vmsd = &vmstate_ipmi_bmc_extern;
device_class_set_props(dc, ipmi_bmc_extern_properties);
}
+93 -14
View File
@@ -70,6 +70,7 @@
#define IPMI_CMD_GET_MSG 0x33
#define IPMI_CMD_SEND_MSG 0x34
#define IPMI_CMD_READ_EVT_MSG_BUF 0x35
#define IPMI_CMD_GET_CHANNEL_INFO 0x42
#define IPMI_NETFN_STORAGE 0x0a
@@ -234,6 +235,7 @@ struct IPMIBmcSim {
#define IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(s) \
(IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE & (s)->msg_flags)
#define IPMI_BMC_GLOBAL_ENABLES_SUPPORTED 0x0f
#define IPMI_BMC_RCV_MSG_QUEUE_INT_BIT 0
#define IPMI_BMC_EVBUF_FULL_INT_BIT 1
#define IPMI_BMC_EVENT_MSG_BUF_BIT 2
@@ -513,7 +515,8 @@ static void gen_event(IPMIBmcSim *ibs, unsigned int sens_num, uint8_t deassert,
static void sensor_set_discrete_bit(IPMIBmcSim *ibs, unsigned int sensor,
unsigned int bit, unsigned int val,
uint8_t evd1, uint8_t evd2, uint8_t evd3)
uint8_t evd1, uint8_t evd2, uint8_t evd3,
bool do_log)
{
IPMISensor *sens;
uint16_t mask;
@@ -533,7 +536,7 @@ static void sensor_set_discrete_bit(IPMIBmcSim *ibs, unsigned int sensor,
return; /* Already asserted */
}
sens->assert_states |= mask & sens->assert_suppt;
if (sens->assert_enable & mask & sens->assert_states) {
if (do_log && (sens->assert_enable & mask & sens->assert_states)) {
/* Send an event on assert */
gen_event(ibs, sensor, 0, evd1, evd2, evd3);
}
@@ -543,7 +546,7 @@ static void sensor_set_discrete_bit(IPMIBmcSim *ibs, unsigned int sensor,
return; /* Already deasserted */
}
sens->deassert_states |= mask & sens->deassert_suppt;
if (sens->deassert_enable & mask & sens->deassert_states) {
if (do_log && (sens->deassert_enable & mask & sens->deassert_states)) {
/* Send an event on deassert */
gen_event(ibs, sensor, 1, evd1, evd2, evd3);
}
@@ -699,6 +702,7 @@ static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs)
{
IPMIInterface *s = ibs->parent.intf;
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
bool do_log = !IPMI_BMC_WATCHDOG_GET_DONT_LOG(ibs);
if (!ibs->watchdog_running) {
goto out;
@@ -710,14 +714,16 @@ static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs)
ibs->msg_flags |= IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK;
k->do_hw_op(s, IPMI_SEND_NMI, 0);
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 8, 1,
0xc8, (2 << 4) | 0xf, 0xff);
0xc8, (2 << 4) | 0xf, 0xff,
do_log);
break;
case IPMI_BMC_WATCHDOG_PRE_MSG_INT:
ibs->msg_flags |= IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK;
k->set_atn(s, 1, attn_irq_enabled(ibs));
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 8, 1,
0xc8, (3 << 4) | 0xf, 0xff);
0xc8, (3 << 4) | 0xf, 0xff,
do_log);
break;
default:
@@ -737,24 +743,28 @@ static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs)
switch (IPMI_BMC_WATCHDOG_GET_ACTION(ibs)) {
case IPMI_BMC_WATCHDOG_ACTION_NONE:
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 0, 1,
0xc0, ibs->watchdog_use & 0xf, 0xff);
0xc0, ibs->watchdog_use & 0xf, 0xff,
do_log);
break;
case IPMI_BMC_WATCHDOG_ACTION_RESET:
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 1, 1,
0xc1, ibs->watchdog_use & 0xf, 0xff);
0xc1, ibs->watchdog_use & 0xf, 0xff,
do_log);
k->do_hw_op(s, IPMI_RESET_CHASSIS, 0);
break;
case IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN:
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 2, 1,
0xc2, ibs->watchdog_use & 0xf, 0xff);
0xc2, ibs->watchdog_use & 0xf, 0xff,
do_log);
k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 0);
break;
case IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE:
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 2, 1,
0xc3, ibs->watchdog_use & 0xf, 0xff);
0xc3, ibs->watchdog_use & 0xf, 0xff,
do_log);
k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 0);
break;
}
@@ -925,7 +935,14 @@ static void set_bmc_global_enables(IPMIBmcSim *ibs,
uint8_t *cmd, unsigned int cmd_len,
RspBuffer *rsp)
{
set_global_enables(ibs, cmd[2]);
uint8_t val = cmd[2];
if (val & ~IPMI_BMC_GLOBAL_ENABLES_SUPPORTED) {
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
return;
}
set_global_enables(ibs, val);
}
static void get_bmc_global_enables(IPMIBmcSim *ibs,
@@ -1020,8 +1037,8 @@ static void send_msg(IPMIBmcSim *ibs,
uint8_t *buf;
uint8_t netfn, rqLun, rsLun, rqSeq;
if (cmd[2] != 0) {
/* We only handle channel 0 with no options */
if (cmd[2] != IPMI_CHANNEL_IPMB) {
/* We only handle channel 0h (IPMB) with no options */
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
return;
}
@@ -1219,6 +1236,68 @@ static void get_watchdog_timer(IPMIBmcSim *ibs,
}
}
static void get_channel_info(IPMIBmcSim *ibs,
uint8_t *cmd, unsigned int cmd_len,
RspBuffer *rsp)
{
IPMIInterface *s = ibs->parent.intf;
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
IPMIFwInfo info = {};
uint8_t ch = cmd[2] & 0x0f;
/* Only define channel 0h (IPMB) and Fh (system interface) */
if (ch == 0x0e) { /* "This channel" */
ch = IPMI_CHANNEL_SYSTEM;
}
rsp_buffer_push(rsp, ch);
if (ch != IPMI_CHANNEL_IPMB && ch != IPMI_CHANNEL_SYSTEM) {
/* Not a supported channel */
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
return;
}
if (k->get_fwinfo) {
k->get_fwinfo(s, &info);
}
if (ch == IPMI_CHANNEL_IPMB) {
rsp_buffer_push(rsp, IPMI_CHANNEL_MEDIUM_IPMB);
rsp_buffer_push(rsp, IPMI_CHANNEL_PROTOCOL_IPMB);
} else { /* IPMI_CHANNEL_SYSTEM */
rsp_buffer_push(rsp, IPMI_CHANNEL_MEDIUM_SYSTEM);
rsp_buffer_push(rsp, info.ipmi_channel_protocol);
}
rsp_buffer_push(rsp, 0x00); /* Session-less */
/* IPMI Enterprise Number for Vendor ID */
rsp_buffer_push(rsp, 0xf2);
rsp_buffer_push(rsp, 0x1b);
rsp_buffer_push(rsp, 0x00);
if (ch == IPMI_CHANNEL_SYSTEM) {
uint8_t irq;
if (info.irq_source == IPMI_ISA_IRQ) {
irq = info.interrupt_number;
} else if (info.irq_source == IPMI_PCI_IRQ) {
irq = 0x10 + info.interrupt_number;
} else {
irq = 0xff; /* no interrupt / unspecified */
}
/* Both interrupts use the same irq number */
rsp_buffer_push(rsp, irq);
rsp_buffer_push(rsp, irq);
} else {
/* Reserved */
rsp_buffer_push(rsp, 0x00);
rsp_buffer_push(rsp, 0x00);
}
}
static void get_sdr_rep_info(IPMIBmcSim *ibs,
uint8_t *cmd, unsigned int cmd_len,
RspBuffer *rsp)
@@ -2015,6 +2094,7 @@ static const IPMICmdHandler app_cmds[] = {
[IPMI_CMD_RESET_WATCHDOG_TIMER] = { reset_watchdog_timer },
[IPMI_CMD_SET_WATCHDOG_TIMER] = { set_watchdog_timer, 8 },
[IPMI_CMD_GET_WATCHDOG_TIMER] = { get_watchdog_timer },
[IPMI_CMD_GET_CHANNEL_INFO] = { get_channel_info, 3 },
};
static const IPMINetfn app_netfn = {
.cmd_nums = ARRAY_SIZE(app_cmds),
@@ -2187,8 +2267,6 @@ static void ipmi_sim_realize(DeviceState *dev, Error **errp)
register_cmds(ibs);
ibs->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ipmi_timeout, ibs);
vmstate_register(NULL, 0, &vmstate_ipmi_sim, ibs);
}
static const Property ipmi_sim_properties[] = {
@@ -2212,6 +2290,7 @@ static void ipmi_sim_class_init(ObjectClass *oc, void *data)
dc->hotpluggable = false;
dc->realize = ipmi_sim_realize;
dc->vmsd = &vmstate_ipmi_sim;
device_class_set_props(dc, ipmi_sim_properties);
bk->handle_command = ipmi_sim_handle_command;
}
+2
View File
@@ -419,6 +419,8 @@ void ipmi_bt_get_fwinfo(struct IPMIBT *ib, IPMIFwInfo *info)
info->interface_type = IPMI_SMBIOS_BT;
info->ipmi_spec_major_revision = 2;
info->ipmi_spec_minor_revision = 0;
/* BT System Interface Format, IPMI v1.5 */
info->ipmi_channel_protocol = IPMI_CHANNEL_PROTOCOL_BT_15;
info->base_address = ib->io_base;
info->register_length = ib->io_length;
info->register_spacing = 1;
+1
View File
@@ -405,6 +405,7 @@ void ipmi_kcs_get_fwinfo(IPMIKCS *ik, IPMIFwInfo *info)
info->interface_type = IPMI_SMBIOS_KCS;
info->ipmi_spec_major_revision = 2;
info->ipmi_spec_minor_revision = 0;
info->ipmi_channel_protocol = IPMI_CHANNEL_PROTOCOL_KCS;
info->base_address = ik->io_base;
info->i2c_slave_address = ik->bmc->slave_addr;
info->register_length = ik->io_length;
+2 -2
View File
@@ -49,6 +49,7 @@ static void isa_ipmi_bt_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info)
ISAIPMIBTDevice *iib = ISA_IPMI_BT(ii);
ipmi_bt_get_fwinfo(&iib->bt, info);
info->irq_source = IPMI_ISA_IRQ;
info->interrupt_number = iib->isairq;
info->i2c_slave_address = iib->bt.bmc->slave_addr;
info->uuid = iib->uuid;
@@ -117,8 +118,6 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
qdev_set_legacy_instance_id(dev, iib->bt.io_base, iib->bt.io_length);
isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base);
vmstate_register(NULL, 0, &vmstate_ISAIPMIBTDevice, dev);
}
static void isa_ipmi_bt_init(Object *obj)
@@ -147,6 +146,7 @@ static void isa_ipmi_bt_class_init(ObjectClass *oc, void *data)
AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(oc);
dc->realize = isa_ipmi_bt_realize;
dc->vmsd = &vmstate_ISAIPMIBTDevice;
device_class_set_props(dc, ipmi_isa_properties);
iic->get_backend_data = isa_ipmi_bt_get_backend_data;
+6 -7
View File
@@ -49,6 +49,7 @@ static void isa_ipmi_kcs_get_fwinfo(IPMIInterface *ii, IPMIFwInfo *info)
ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii);
ipmi_kcs_get_fwinfo(&iik->kcs, info);
info->irq_source = IPMI_ISA_IRQ;
info->interrupt_number = iik->isairq;
info->uuid = iik->uuid;
}
@@ -72,6 +73,10 @@ static bool vmstate_kcs_before_version2(void *opaque, int version)
return version <= 1;
}
/*
* Version 1 had an incorrect name, it clashed with the BT IPMI
* device, so receive it, but transmit a different version.
*/
static const VMStateDescription vmstate_ISAIPMIKCSDevice = {
.name = TYPE_IPMI_INTERFACE,
.version_id = 2,
@@ -119,13 +124,6 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
qdev_set_legacy_instance_id(dev, iik->kcs.io_base, iik->kcs.io_length);
isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base);
/*
* Version 1 had an incorrect name, it clashed with the BT
* IPMI device, so receive it, but transmit a different
* version.
*/
vmstate_register(NULL, 0, &vmstate_ISAIPMIKCSDevice, iik);
}
static void isa_ipmi_kcs_init(Object *obj)
@@ -154,6 +152,7 @@ static void isa_ipmi_kcs_class_init(ObjectClass *oc, void *data)
AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(oc);
dc->realize = ipmi_isa_realize;
dc->vmsd = &vmstate_ISAIPMIKCSDevice;
device_class_set_props(dc, ipmi_isa_properties);
iic->get_backend_data = isa_ipmi_kcs_get_backend_data;
+31 -19
View File
@@ -38,49 +38,60 @@ struct PCIIPMIBTDevice {
uint32_t uuid;
};
static void pci_ipmi_raise_irq(IPMIBT *ik)
static void pci_ipmi_bt_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info)
{
PCIIPMIBTDevice *pik = ik->opaque;
PCIIPMIBTDevice *pib = PCI_IPMI_BT(ii);
pci_set_irq(&pik->dev, true);
ipmi_bt_get_fwinfo(&pib->bt, info);
info->irq_source = IPMI_PCI_IRQ;
info->interrupt_number = pci_intx(&pib->dev);
info->i2c_slave_address = pib->bt.bmc->slave_addr;
info->uuid = pib->uuid;
}
static void pci_ipmi_lower_irq(IPMIBT *ik)
static void pci_ipmi_raise_irq(IPMIBT *ib)
{
PCIIPMIBTDevice *pik = ik->opaque;
PCIIPMIBTDevice *pib = ib->opaque;
pci_set_irq(&pik->dev, false);
pci_set_irq(&pib->dev, true);
}
static void pci_ipmi_lower_irq(IPMIBT *ib)
{
PCIIPMIBTDevice *pib = ib->opaque;
pci_set_irq(&pib->dev, false);
}
static void pci_ipmi_bt_realize(PCIDevice *pd, Error **errp)
{
Error *err = NULL;
PCIIPMIBTDevice *pik = PCI_IPMI_BT(pd);
PCIIPMIBTDevice *pib = PCI_IPMI_BT(pd);
IPMIInterface *ii = IPMI_INTERFACE(pd);
IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
if (!pik->bt.bmc) {
if (!pib->bt.bmc) {
error_setg(errp, "IPMI device requires a bmc attribute to be set");
return;
}
pik->uuid = ipmi_next_uuid();
pib->uuid = ipmi_next_uuid();
pik->bt.bmc->intf = ii;
pik->bt.opaque = pik;
pib->bt.bmc->intf = ii;
pib->bt.opaque = pib;
pci_config_set_prog_interface(pd->config, 0x02); /* BT */
pci_config_set_interrupt_pin(pd->config, 0x01);
pik->bt.use_irq = 1;
pik->bt.raise_irq = pci_ipmi_raise_irq;
pik->bt.lower_irq = pci_ipmi_lower_irq;
pib->bt.use_irq = 1;
pib->bt.raise_irq = pci_ipmi_raise_irq;
pib->bt.lower_irq = pci_ipmi_lower_irq;
iic->init(ii, 8, &err);
if (err) {
error_propagate(errp, err);
return;
}
pci_register_bar(pd, 0, PCI_BASE_ADDRESS_SPACE_IO, &pik->bt.io);
pci_register_bar(pd, 0, PCI_BASE_ADDRESS_SPACE_IO, &pib->bt.io);
}
const VMStateDescription vmstate_PCIIPMIBTDevice = {
@@ -96,16 +107,16 @@ const VMStateDescription vmstate_PCIIPMIBTDevice = {
static void pci_ipmi_bt_instance_init(Object *obj)
{
PCIIPMIBTDevice *pik = PCI_IPMI_BT(obj);
PCIIPMIBTDevice *pib = PCI_IPMI_BT(obj);
ipmi_bmc_find_and_link(obj, (Object **) &pik->bt.bmc);
ipmi_bmc_find_and_link(obj, (Object **) &pib->bt.bmc);
}
static void *pci_ipmi_bt_get_backend_data(IPMIInterface *ii)
{
PCIIPMIBTDevice *pik = PCI_IPMI_BT(ii);
PCIIPMIBTDevice *pib = PCI_IPMI_BT(ii);
return &pik->bt;
return &pib->bt;
}
static void pci_ipmi_bt_class_init(ObjectClass *oc, void *data)
@@ -125,6 +136,7 @@ static void pci_ipmi_bt_class_init(ObjectClass *oc, void *data)
iic->get_backend_data = pci_ipmi_bt_get_backend_data;
ipmi_bt_class_init(iic);
iic->get_fwinfo = pci_ipmi_bt_get_fwinfo;
}
static const TypeInfo pci_ipmi_bt_info = {
+11
View File
@@ -38,6 +38,16 @@ struct PCIIPMIKCSDevice {
uint32_t uuid;
};
static void pci_ipmi_kcs_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info)
{
PCIIPMIKCSDevice *pik = PCI_IPMI_KCS(ii);
ipmi_kcs_get_fwinfo(&pik->kcs, info);
info->irq_source = IPMI_PCI_IRQ;
info->interrupt_number = pci_intx(&pik->dev);
info->uuid = pik->uuid;
}
static void pci_ipmi_raise_irq(IPMIKCS *ik)
{
PCIIPMIKCSDevice *pik = ik->opaque;
@@ -125,6 +135,7 @@ static void pci_ipmi_kcs_class_init(ObjectClass *oc, void *data)
iic->get_backend_data = pci_ipmi_kcs_get_backend_data;
ipmi_kcs_class_init(iic);
iic->get_fwinfo = pci_ipmi_kcs_get_fwinfo;
}
static const TypeInfo pci_ipmi_kcs_info = {
+6 -1
View File
@@ -72,7 +72,12 @@ static void smbios_build_one_type_38(IPMIFwInfo *info)
" SMBIOS, ignoring this entry.", info->register_spacing);
return;
}
t->interrupt_number = info->interrupt_number;
if (info->irq_source == IPMI_ISA_IRQ) {
t->interrupt_number = info->interrupt_number;
} else {
/* TODO: How to handle PCI? */
t->interrupt_number = 0;
}
SMBIOS_BUILD_TABLE_POST;
}
+15
View File
@@ -41,6 +41,15 @@ enum ipmi_op {
IPMI_SEND_NMI
};
/* Channel properties */
#define IPMI_CHANNEL_IPMB 0x00
#define IPMI_CHANNEL_SYSTEM 0x0f
#define IPMI_CHANNEL_MEDIUM_IPMB 0x01
#define IPMI_CHANNEL_MEDIUM_SYSTEM 0x0c
#define IPMI_CHANNEL_PROTOCOL_IPMB 0x01
#define IPMI_CHANNEL_PROTOCOL_KCS 0x05
#define IPMI_CHANNEL_PROTOCOL_BT_15 0x08
#define IPMI_CC_INVALID_CMD 0xc1
#define IPMI_CC_COMMAND_INVALID_FOR_LUN 0xc2
#define IPMI_CC_TIMEOUT 0xc3
@@ -76,6 +85,7 @@ typedef struct IPMIFwInfo {
int interface_type;
uint8_t ipmi_spec_major_revision;
uint8_t ipmi_spec_minor_revision;
uint8_t ipmi_channel_protocol;
uint8_t i2c_slave_address;
uint32_t uuid;
@@ -90,6 +100,11 @@ typedef struct IPMIFwInfo {
} memspace;
int interrupt_number;
enum {
IPMI_NO_IRQ = 0,
IPMI_ISA_IRQ,
IPMI_PCI_IRQ,
} irq_source;
enum {
IPMI_LEVEL_IRQ,
IPMI_EDGE_IRQ