Lines Matching +full:ssif +full:- +full:bmc
2 * QEMU IPMI SMBus (SSIF) emulation
28 #include "qemu/error-report.h"
33 #define TYPE_SMBUS_IPMI "smbus-ipmi"
52 IPMIBmc *bmc; member
84 if (sid->waiting_rsp == msg_id) { in smbus_ipmi_handle_rsp()
85 sid->waiting_rsp++; in smbus_ipmi_handle_rsp()
91 memcpy(sid->outmsg, rsp, rsp_len); in smbus_ipmi_handle_rsp()
92 sid->outlen = rsp_len; in smbus_ipmi_handle_rsp()
93 sid->outpos = 0; in smbus_ipmi_handle_rsp()
94 sid->currblk = 0; in smbus_ipmi_handle_rsp()
109 uint8_t *msg = sid->inmsg; in smbus_ipmi_send_msg()
110 uint32_t len = sid->inlen; in smbus_ipmi_send_msg()
111 IPMIBmcClass *bk = IPMI_BMC_GET_CLASS(sid->bmc); in smbus_ipmi_send_msg()
113 sid->outlen = 0; in smbus_ipmi_send_msg()
114 sid->outpos = 0; in smbus_ipmi_send_msg()
115 sid->currblk = 0; in smbus_ipmi_send_msg()
120 sid->outmsg[0] = (IPMI_NETFN_APP + 1) << 2; in smbus_ipmi_send_msg()
121 sid->outmsg[1] = msg[1]; in smbus_ipmi_send_msg()
123 sid->outmsg[2] = IPMI_CC_REQUEST_DATA_LENGTH_INVALID; in smbus_ipmi_send_msg()
124 sid->outlen = 3; in smbus_ipmi_send_msg()
126 sid->outmsg[2] = IPMI_CC_INVALID_DATA_FIELD; in smbus_ipmi_send_msg()
127 sid->outlen = 3; in smbus_ipmi_send_msg()
129 sid->outmsg[2] = 0; in smbus_ipmi_send_msg()
130 sid->outmsg[3] = 0; in smbus_ipmi_send_msg()
131 sid->outmsg[4] = (2 << 6); /* Multi-part supported. */ in smbus_ipmi_send_msg()
132 sid->outmsg[5] = MAX_SSIF_IPMI_MSG_SIZE; in smbus_ipmi_send_msg()
133 sid->outmsg[6] = MAX_SSIF_IPMI_MSG_SIZE; in smbus_ipmi_send_msg()
134 sid->outlen = 7; in smbus_ipmi_send_msg()
139 bk->handle_command(sid->bmc, sid->inmsg, sid->inlen, sizeof(sid->inmsg), in smbus_ipmi_send_msg()
140 sid->waiting_rsp); in smbus_ipmi_send_msg()
147 if (sid->outpos >= sizeof(sid->outbuf)) { in ipmi_receive_byte()
151 return sid->outbuf[sid->outpos++]; in ipmi_receive_byte()
156 unsigned int block = sid->currblk, pos, len; in ipmi_load_readbuf()
158 if (sid->outlen == 0) { in ipmi_load_readbuf()
159 return -1; in ipmi_load_readbuf()
162 if (sid->outlen <= 32) { in ipmi_load_readbuf()
164 return -1; in ipmi_load_readbuf()
166 sid->outbuf[0] = sid->outlen; in ipmi_load_readbuf()
167 memcpy(sid->outbuf + 1, sid->outmsg, sid->outlen); in ipmi_load_readbuf()
168 sid->outpos = 0; in ipmi_load_readbuf()
173 sid->outbuf[0] = 32; in ipmi_load_readbuf()
174 sid->outbuf[1] = 0; in ipmi_load_readbuf()
175 sid->outbuf[2] = 1; in ipmi_load_readbuf()
176 memcpy(sid->outbuf + 3, sid->outmsg, 30); in ipmi_load_readbuf()
177 sid->outpos = 0; in ipmi_load_readbuf()
185 pos = 30 + (block - 1) * 31; in ipmi_load_readbuf()
187 if (pos >= sid->outlen) { in ipmi_load_readbuf()
188 return -1; in ipmi_load_readbuf()
191 len = sid->outlen - pos; in ipmi_load_readbuf()
196 sid->outbuf[1] = block - 1; in ipmi_load_readbuf()
198 sid->outbuf[1] = 0xff; /* End of message marker. */ in ipmi_load_readbuf()
201 sid->outbuf[0] = len + 1; in ipmi_load_readbuf()
202 memcpy(sid->outbuf + 2, sid->outmsg + pos, len); in ipmi_load_readbuf()
203 sid->outpos = 0; in ipmi_load_readbuf()
216 len--; in ipmi_write_data()
221 sid->currblk = 0; in ipmi_write_data()
226 sid->currblk++; in ipmi_write_data()
232 sid->currblk = buf[0]; in ipmi_write_data()
235 ret = -1; in ipmi_write_data()
245 if (*buf != len - 1 || *buf > MAX_SSIF_IPMI_MSG_CHUNK) { in ipmi_write_data()
246 return -1; /* Bogus message */ in ipmi_write_data()
249 len--; in ipmi_write_data()
258 return -1; /* Bogus. */ in ipmi_write_data()
260 memcpy(sid->inmsg, buf, len); in ipmi_write_data()
261 sid->inlen = len; in ipmi_write_data()
268 if (!sid->inlen) { in ipmi_write_data()
269 return -1; /* Bogus. */ in ipmi_write_data()
271 if (sid->inlen + len > MAX_SSIF_IPMI_MSG_SIZE) { in ipmi_write_data()
272 sid->inlen = 0; /* Discard the message. */ in ipmi_write_data()
273 return -1; /* Bogus. */ in ipmi_write_data()
277 * Special hack, a multi-part middle that is less than 32 bytes in ipmi_write_data()
285 memcpy(sid->inmsg + sid->inlen, buf, len); in ipmi_write_data()
287 sid->inlen += len; in ipmi_write_data()
291 if (send && sid->inlen) { in ipmi_write_data()
322 if (!sid->bmc) { in smbus_ipmi_realize()
323 error_setg(errp, "IPMI device requires a bmc attribute to be set"); in smbus_ipmi_realize()
327 sid->uuid = ipmi_next_uuid(); in smbus_ipmi_realize()
329 sid->bmc->intf = ii; in smbus_ipmi_realize()
336 ipmi_bmc_find_and_link(obj, (Object **) &sid->bmc); in smbus_ipmi_init()
343 info->interface_name = "smbus"; in smbus_ipmi_get_fwinfo()
344 info->interface_type = IPMI_SMBIOS_SSIF; in smbus_ipmi_get_fwinfo()
345 info->ipmi_spec_major_revision = 2; in smbus_ipmi_get_fwinfo()
346 info->ipmi_spec_minor_revision = 0; in smbus_ipmi_get_fwinfo()
347 info->i2c_slave_address = sid->bmc->slave_addr; in smbus_ipmi_get_fwinfo()
348 info->base_address = sid->parent.i2c.address; in smbus_ipmi_get_fwinfo()
349 info->memspace = IPMI_MEMSPACE_SMBUS; in smbus_ipmi_get_fwinfo()
350 info->register_spacing = 1; in smbus_ipmi_get_fwinfo()
351 info->uuid = sid->uuid; in smbus_ipmi_get_fwinfo()
361 sc->receive_byte = ipmi_receive_byte; in smbus_ipmi_class_init()
362 sc->write_data = ipmi_write_data; in smbus_ipmi_class_init()
363 dc->vmsd = &vmstate_smbus_ipmi; in smbus_ipmi_class_init()
364 dc->realize = smbus_ipmi_realize; in smbus_ipmi_class_init()
365 iic->set_atn = smbus_ipmi_set_atn; in smbus_ipmi_class_init()
366 iic->handle_rsp = smbus_ipmi_handle_rsp; in smbus_ipmi_class_init()
367 iic->handle_if_event = smbus_ipmi_handle_event; in smbus_ipmi_class_init()
368 iic->set_irq_enable = smbus_ipmi_set_irq_enable; in smbus_ipmi_class_init()
369 iic->get_fwinfo = smbus_ipmi_get_fwinfo; in smbus_ipmi_class_init()
370 adevc->build_dev_aml = build_ipmi_dev_aml; in smbus_ipmi_class_init()