Skip to content

Commit b442119

Browse files
committed
Merge remote-tracking branch 'remotes/cminyard/tags/for-qemu-ipmi-5' into staging
Man page update and new set sensor command Some minor man page updates for fairly obvious things. The set sensor command addition has been in the Power group's tree for a long time and I have neglected to submit it. -corey # gpg: Signature made Fri 17 Jul 2020 17:45:32 BST # gpg: using RSA key FD0D5CE67CE0F59A6688268661F38C90919BFF81 # gpg: Good signature from "Corey Minyard <[email protected]>" [unknown] # gpg: aka "Corey Minyard <[email protected]>" [unknown] # gpg: aka "Corey Minyard <[email protected]>" [unknown] # gpg: aka "Corey Minyard <[email protected]>" [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 * remotes/cminyard/tags/for-qemu-ipmi-5: ipmi: add SET_SENSOR_READING command ipmi: Fix a man page entry ipmi: Add man page pieces for the IPMI PCI devices Signed-off-by: Peter Maydell <[email protected]>
2 parents 939ab64 + e3f7320 commit b442119

File tree

2 files changed

+233
-1
lines changed

2 files changed

+233
-1
lines changed

hw/ipmi/ipmi_bmc_sim.c

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#define IPMI_CMD_GET_SENSOR_READING 0x2d
5050
#define IPMI_CMD_SET_SENSOR_TYPE 0x2e
5151
#define IPMI_CMD_GET_SENSOR_TYPE 0x2f
52+
#define IPMI_CMD_SET_SENSOR_READING 0x30
5253

5354
/* #define IPMI_NETFN_APP 0x06 In ipmi.h */
5455

@@ -1747,6 +1748,227 @@ static void get_sensor_type(IPMIBmcSim *ibs,
17471748
rsp_buffer_push(rsp, sens->evt_reading_type_code);
17481749
}
17491750

1751+
/*
1752+
* bytes parameter
1753+
* 1 sensor number
1754+
* 2 operation (see below for bits meaning)
1755+
* 3 sensor reading
1756+
* 4:5 assertion states (optional)
1757+
* 6:7 deassertion states (optional)
1758+
* 8:10 event data 1,2,3 (optional)
1759+
*/
1760+
static void set_sensor_reading(IPMIBmcSim *ibs,
1761+
uint8_t *cmd, unsigned int cmd_len,
1762+
RspBuffer *rsp)
1763+
{
1764+
IPMISensor *sens;
1765+
uint8_t evd1 = 0;
1766+
uint8_t evd2 = 0;
1767+
uint8_t evd3 = 0;
1768+
uint8_t new_reading = 0;
1769+
uint16_t new_assert_states = 0;
1770+
uint16_t new_deassert_states = 0;
1771+
bool change_reading = false;
1772+
bool change_assert = false;
1773+
bool change_deassert = false;
1774+
enum {
1775+
SENSOR_GEN_EVENT_NONE,
1776+
SENSOR_GEN_EVENT_DATA,
1777+
SENSOR_GEN_EVENT_BMC,
1778+
} do_gen_event = SENSOR_GEN_EVENT_NONE;
1779+
1780+
if ((cmd[2] >= MAX_SENSORS) ||
1781+
!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1782+
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1783+
return;
1784+
}
1785+
1786+
sens = ibs->sensors + cmd[2];
1787+
1788+
/* [1:0] Sensor Reading operation */
1789+
switch ((cmd[3]) & 0x3) {
1790+
case 0: /* Do not change */
1791+
break;
1792+
case 1: /* write given value to sensor reading byte */
1793+
new_reading = cmd[4];
1794+
if (sens->reading != new_reading) {
1795+
change_reading = true;
1796+
}
1797+
break;
1798+
case 2:
1799+
case 3:
1800+
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1801+
return;
1802+
}
1803+
1804+
/* [3:2] Deassertion bits operation */
1805+
switch ((cmd[3] >> 2) & 0x3) {
1806+
case 0: /* Do not change */
1807+
break;
1808+
case 1: /* write given value */
1809+
if (cmd_len > 7) {
1810+
new_deassert_states = cmd[7];
1811+
change_deassert = true;
1812+
}
1813+
if (cmd_len > 8) {
1814+
new_deassert_states |= (cmd[8] << 8);
1815+
}
1816+
break;
1817+
1818+
case 2: /* mask on */
1819+
if (cmd_len > 7) {
1820+
new_deassert_states = (sens->deassert_states | cmd[7]);
1821+
change_deassert = true;
1822+
}
1823+
if (cmd_len > 8) {
1824+
new_deassert_states |= (sens->deassert_states | (cmd[8] << 8));
1825+
}
1826+
break;
1827+
1828+
case 3: /* mask off */
1829+
if (cmd_len > 7) {
1830+
new_deassert_states = (sens->deassert_states & cmd[7]);
1831+
change_deassert = true;
1832+
}
1833+
if (cmd_len > 8) {
1834+
new_deassert_states |= (sens->deassert_states & (cmd[8] << 8));
1835+
}
1836+
break;
1837+
}
1838+
1839+
if (change_deassert && (new_deassert_states == sens->deassert_states)) {
1840+
change_deassert = false;
1841+
}
1842+
1843+
/* [5:4] Assertion bits operation */
1844+
switch ((cmd[3] >> 4) & 0x3) {
1845+
case 0: /* Do not change */
1846+
break;
1847+
case 1: /* write given value */
1848+
if (cmd_len > 5) {
1849+
new_assert_states = cmd[5];
1850+
change_assert = true;
1851+
}
1852+
if (cmd_len > 6) {
1853+
new_assert_states |= (cmd[6] << 8);
1854+
}
1855+
break;
1856+
1857+
case 2: /* mask on */
1858+
if (cmd_len > 5) {
1859+
new_assert_states = (sens->assert_states | cmd[5]);
1860+
change_assert = true;
1861+
}
1862+
if (cmd_len > 6) {
1863+
new_assert_states |= (sens->assert_states | (cmd[6] << 8));
1864+
}
1865+
break;
1866+
1867+
case 3: /* mask off */
1868+
if (cmd_len > 5) {
1869+
new_assert_states = (sens->assert_states & cmd[5]);
1870+
change_assert = true;
1871+
}
1872+
if (cmd_len > 6) {
1873+
new_assert_states |= (sens->assert_states & (cmd[6] << 8));
1874+
}
1875+
break;
1876+
}
1877+
1878+
if (change_assert && (new_assert_states == sens->assert_states)) {
1879+
change_assert = false;
1880+
}
1881+
1882+
if (cmd_len > 9) {
1883+
evd1 = cmd[9];
1884+
}
1885+
if (cmd_len > 10) {
1886+
evd2 = cmd[10];
1887+
}
1888+
if (cmd_len > 11) {
1889+
evd3 = cmd[11];
1890+
}
1891+
1892+
/* [7:6] Event Data Bytes operation */
1893+
switch ((cmd[3] >> 6) & 0x3) {
1894+
case 0: /*
1895+
* Don’t use Event Data bytes from this command. BMC will
1896+
* generate it's own Event Data bytes based on its sensor
1897+
* implementation.
1898+
*/
1899+
evd1 = evd2 = evd3 = 0x0;
1900+
do_gen_event = SENSOR_GEN_EVENT_BMC;
1901+
break;
1902+
case 1: /*
1903+
* Write given values to event data bytes including bits
1904+
* [3:0] Event Data 1.
1905+
*/
1906+
do_gen_event = SENSOR_GEN_EVENT_DATA;
1907+
break;
1908+
case 2: /*
1909+
* Write given values to event data bytes excluding bits
1910+
* [3:0] Event Data 1.
1911+
*/
1912+
evd1 &= 0xf0;
1913+
do_gen_event = SENSOR_GEN_EVENT_DATA;
1914+
break;
1915+
case 3:
1916+
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1917+
return;
1918+
}
1919+
1920+
/*
1921+
* Event Data Bytes operation and parameter are inconsistent. The
1922+
* Specs are not clear on that topic but generating an error seems
1923+
* correct.
1924+
*/
1925+
if (do_gen_event == SENSOR_GEN_EVENT_DATA && cmd_len < 10) {
1926+
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1927+
return;
1928+
}
1929+
1930+
/* commit values */
1931+
if (change_reading) {
1932+
sens->reading = new_reading;
1933+
}
1934+
1935+
if (change_assert) {
1936+
sens->assert_states = new_assert_states;
1937+
}
1938+
1939+
if (change_deassert) {
1940+
sens->deassert_states = new_deassert_states;
1941+
}
1942+
1943+
/* TODO: handle threshold sensor */
1944+
if (!IPMI_SENSOR_IS_DISCRETE(sens)) {
1945+
return;
1946+
}
1947+
1948+
switch (do_gen_event) {
1949+
case SENSOR_GEN_EVENT_DATA: {
1950+
unsigned int bit = evd1 & 0xf;
1951+
uint16_t mask = (1 << bit);
1952+
1953+
if (sens->assert_states & mask & sens->assert_enable) {
1954+
gen_event(ibs, cmd[2], 0, evd1, evd2, evd3);
1955+
}
1956+
1957+
if (sens->deassert_states & mask & sens->deassert_enable) {
1958+
gen_event(ibs, cmd[2], 1, evd1, evd2, evd3);
1959+
}
1960+
break;
1961+
}
1962+
case SENSOR_GEN_EVENT_BMC:
1963+
/*
1964+
* TODO: generate event and event data bytes depending on the
1965+
* sensor
1966+
*/
1967+
break;
1968+
case SENSOR_GEN_EVENT_NONE:
1969+
break;
1970+
}
1971+
}
17501972

17511973
static const IPMICmdHandler chassis_cmds[] = {
17521974
[IPMI_CMD_GET_CHASSIS_CAPABILITIES] = { chassis_capabilities },
@@ -1768,6 +1990,7 @@ static const IPMICmdHandler sensor_event_cmds[] = {
17681990
[IPMI_CMD_GET_SENSOR_READING] = { get_sensor_reading, 3 },
17691991
[IPMI_CMD_SET_SENSOR_TYPE] = { set_sensor_type, 5 },
17701992
[IPMI_CMD_GET_SENSOR_TYPE] = { get_sensor_type, 3 },
1993+
[IPMI_CMD_SET_SENSOR_READING] = { set_sensor_reading, 5 },
17711994
};
17721995
static const IPMINetfn sensor_event_netfn = {
17731996
.cmd_nums = ARRAY_SIZE(sensor_event_cmds),

qemu-options.hx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ SRST
806806

807807
Some drivers are:
808808

809-
``-device ipmi-bmc-sim,id=id[,slave_addr=val][,sdrfile=file][,furareasize=val][,furdatafile=file][,guid=uuid]``
809+
``-device ipmi-bmc-sim,id=id[,prop[=value][,...]]``
810810
Add an IPMI BMC. This is a simulation of a hardware management
811811
interface processor that normally sits on a system. It provides a
812812
watchdog and the ability to reset and power control the system. You
@@ -876,6 +876,15 @@ SRST
876876
``-device isa-ipmi-bt,bmc=id[,ioport=val][,irq=val]``
877877
Like the KCS interface, but defines a BT interface. The default port
878878
is 0xe4 and the default interrupt is 5.
879+
880+
``-device pci-ipmi-kcs,bmc=id``
881+
Add a KCS IPMI interafce on the PCI bus.
882+
883+
``bmc=id``
884+
The BMC to connect to, one of ipmi-bmc-sim or ipmi-bmc-extern above.
885+
886+
``-device pci-ipmi-bt,bmc=id``
887+
Like the KCS interface, but defines a BT interface on the PCI bus.
879888
ERST
880889

881890
DEF("name", HAS_ARG, QEMU_OPTION_name,

0 commit comments

Comments
 (0)