On Mon Mar 31, 2025 at 11:25 PM AEST, Corey Minyard wrote: > On Mon, Mar 31, 2025 at 10:57:24PM +1000, Nicholas Piggin wrote: >> Linux issues this command when booting a powernv machine. > > This is good, just a couple of nits. > >> >> Signed-off-by: Nicholas Piggin <npig...@gmail.com> >> --- >> include/hw/ipmi/ipmi.h | 14 +++++++++++ >> hw/ipmi/ipmi_bmc_sim.c | 56 ++++++++++++++++++++++++++++++++++++++++-- >> hw/ipmi/ipmi_bt.c | 2 ++ >> hw/ipmi/ipmi_kcs.c | 1 + >> 4 files changed, 71 insertions(+), 2 deletions(-) >> >> diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h >> index 77a7213ed93..5f01a50cd86 100644 >> --- a/include/hw/ipmi/ipmi.h >> +++ b/include/hw/ipmi/ipmi.h >> @@ -41,6 +41,15 @@ enum ipmi_op { >> IPMI_SEND_NMI >> }; >> >> +/* Channel properties */ >> +#define IPMI_CHANNEL_IPMB 0x00 >> +#define IPMI_CHANNEL_SYSTEM 0x0f >> +#define IPMI_CH_MEDIUM_IPMB 0x01 >> +#define IPMI_CH_MEDIUM_SYSTEM 0x0c >> +#define IPMI_CH_PROTOCOL_IPMB 0x01 >> +#define IPMI_CH_PROTOCOL_KCS 0x05 >> +#define IPMI_CH_PROTOCOL_BT_15 0x08 > > I know it's picky, but could you spell out CHANNEL here?
Sure. >> + >> #define IPMI_CC_INVALID_CMD 0xc1 >> #define IPMI_CC_COMMAND_INVALID_FOR_LUN 0xc2 >> #define IPMI_CC_TIMEOUT 0xc3 >> @@ -170,6 +179,11 @@ struct IPMIInterfaceClass { >> * Return the firmware info for a device. >> */ >> void (*get_fwinfo)(struct IPMIInterface *s, IPMIFwInfo *info); >> + >> + /* >> + * IPMI channel protocol type number. >> + */ >> + uint8_t protocol; >> }; >> >> /* >> diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c >> index 8c3313aa65f..9198f854bd9 100644 >> --- a/hw/ipmi/ipmi_bmc_sim.c >> +++ b/hw/ipmi/ipmi_bmc_sim.c >> @@ -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 >> >> @@ -1033,8 +1034,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; >> } >> @@ -1232,6 +1233,56 @@ 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); >> + uint8_t ch = cmd[1] & 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 supported */ > > I think that an all zero response is a valid response. I think you > should return a IPMI_CC_INVALID_DATA_FIELD instead, right? I can't remember, I dug the patch out from a while ago. I can't actually see anywhere it is made clear in the spec, do you? I agree an invalid error sounds better. I'll try to see how ipmi tools handles it. >> + int i; >> + for (i = 0; i < 8; i++) { >> + rsp_buffer_push(rsp, 0x00); >> + } >> + return; >> + } >> + >> + if (ch == IPMI_CHANNEL_IPMB) { >> + rsp_buffer_push(rsp, IPMI_CH_MEDIUM_IPMB); >> + rsp_buffer_push(rsp, IPMI_CH_PROTOCOL_IPMB); >> + } else { /* IPMI_CHANNEL_SYSTEM */ >> + rsp_buffer_push(rsp, IPMI_CH_MEDIUM_SYSTEM); >> + rsp_buffer_push(rsp, k->protocol); >> + } >> + >> + rsp_buffer_push(rsp, 0x00); /* Session-less */ >> + >> + /* IPMI Vendor ID */ >> + rsp_buffer_push(rsp, 0xf2); >> + rsp_buffer_push(rsp, 0x1b); >> + rsp_buffer_push(rsp, 0x00); > > Where does this come from? IPMI spec Get Channel Info Command, search "IPMI Enterprise Number" >From my reading, all channel info responses contain this. >> + >> + if (ch == IPMI_CHANNEL_SYSTEM) { >> + /* IRQ assigned by ACPI/PnP (XXX?) */ >> + rsp_buffer_push(rsp, 0x60); >> + rsp_buffer_push(rsp, 0x60); > > The interrupt should be available. For the isa versions there is a > get_fwinfo function pointer that you can fetch this with. For PCI it's > more complicated, unfortunately. These are for the two interrupts. QEMU seems to tie both to the same line, I guess that's okay? That interface looks good, but what I was concerned about is whether that implies the irq is hard coded or whether the platform can assign it, does it mean unassigned? I don't know a lot about irq routing or what IPMI clients would use it for. Anyhow I'll respin with changes. Thanks, Nick