mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
ipmi/bmc-sim: Add 'Get Channel Info' command
Linux issues this command when booting a powernv machine. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Message-ID: <20250401140153.685523-4-npiggin@gmail.com> Signed-off-by: Corey Minyard <corey@minyard.net>
This commit is contained in:
parent
7376d10b50
commit
7f9e7af40a
4 changed files with 79 additions and 2 deletions
|
@ -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
|
||||
|
||||
|
@ -1020,8 +1021,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 +1220,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 +2078,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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue