* [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device
@ 2017-12-07 21:46 minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 01/14] i2c:pm_smbus: Clean up some style issues minyard
` (13 more replies)
0 siblings, 14 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel
The pm_smbus code has a few issues, and it's missing a lot of the
device capabilities required by IPMI. This has been submitted
before, but it has some new things, like vmstate handling for the
smbus devices.
^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 01/14] i2c:pm_smbus: Clean up some style issues
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
@ 2017-12-07 21:46 ` minyard
2018-08-17 17:24 ` Paolo Bonzini
2017-12-07 21:46 ` [Qemu-devel] [PATCH 02/14] i2c:pm_smbus: Fix the semantics of block I2C transfers minyard
` (12 subsequent siblings)
13 siblings, 1 reply; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard, Michael S . Tsirkin, Paolo Bonzini
From: Corey Minyard <cminyard@mvista.com>
Fix some spacing issues, remove extraneous comments, add some
defines instead of hard-coding numbers.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i2c/pm_smbus.c | 58 ++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 20 deletions(-)
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index 6fc3923..92c3aebd 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -23,8 +23,6 @@
#include "hw/i2c/pm_smbus.h"
#include "hw/i2c/smbus.h"
-/* no save/load? */
-
#define SMBHSTSTS 0x00
#define SMBHSTCNT 0x02
#define SMBHSTCMD 0x03
@@ -33,19 +31,34 @@
#define SMBHSTDAT1 0x06
#define SMBBLKDAT 0x07
-#define STS_HOST_BUSY (1)
-#define STS_INTR (1<<1)
-#define STS_DEV_ERR (1<<2)
-#define STS_BUS_ERR (1<<3)
-#define STS_FAILED (1<<4)
-#define STS_SMBALERT (1<<5)
-#define STS_INUSE_STS (1<<6)
-#define STS_BYTE_DONE (1<<7)
+#define STS_HOST_BUSY (1 << 0)
+#define STS_INTR (1 << 1)
+#define STS_DEV_ERR (1 << 2)
+#define STS_BUS_ERR (1 << 3)
+#define STS_FAILED (1 << 4)
+#define STS_SMBALERT (1 << 5)
+#define STS_INUSE_STS (1 << 6)
+#define STS_BYTE_DONE (1 << 7)
/* Signs of successfully transaction end :
* ByteDoneStatus = 1 (STS_BYTE_DONE) and INTR = 1 (STS_INTR )
*/
-//#define DEBUG
+#define CTL_INTREN (1 << 0)
+#define CTL_KILL (1 << 1)
+#define CTL_LAST_BYTE (1 << 5)
+#define CTL_START (1 << 6)
+#define CTL_PEC_EN (1 << 7)
+#define CTL_RETURN_MASK 0x1f
+
+#define PROT_QUICK 0
+#define PROT_BYTE 1
+#define PROT_BYTE_DATA 2
+#define PROT_WORD_DATA 3
+#define PROT_PROC_CALL 4
+#define PROT_BLOCK_DATA 5
+#define PROT_I2C_BLOCK_DATA 6
+
+/*#define DEBUG*/
#ifdef DEBUG
# define SMBUS_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
@@ -68,11 +81,12 @@ static void smb_transaction(PMSMBus *s)
if ((s->smb_stat & STS_DEV_ERR) != 0) {
goto error;
}
+
switch(prot) {
- case 0x0:
+ case PROT_QUICK:
ret = smbus_quick_command(bus, addr, read);
goto done;
- case 0x1:
+ case PROT_BYTE:
if (read) {
ret = smbus_receive_byte(bus, addr);
goto data8;
@@ -80,7 +94,7 @@ static void smb_transaction(PMSMBus *s)
ret = smbus_send_byte(bus, addr, cmd);
goto done;
}
- case 0x2:
+ case PROT_BYTE_DATA:
if (read) {
ret = smbus_read_byte(bus, addr, cmd);
goto data8;
@@ -89,16 +103,17 @@ static void smb_transaction(PMSMBus *s)
goto done;
}
break;
- case 0x3:
+ case PROT_WORD_DATA:
if (read) {
ret = smbus_read_word(bus, addr, cmd);
goto data16;
} else {
- ret = smbus_write_word(bus, addr, cmd, (s->smb_data1 << 8) | s->smb_data0);
+ ret = smbus_write_word(bus, addr, cmd,
+ (s->smb_data1 << 8) | s->smb_data0);
goto done;
}
break;
- case 0x5:
+ case PROT_I2C_BLOCK_DATA:
if (read) {
ret = smbus_read_block(bus, addr, cmd, s->smb_data);
goto data8;
@@ -149,8 +164,9 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
break;
case SMBHSTCNT:
s->smb_ctl = val;
- if (val & 0x40)
+ if (s->smb_ctl & CTL_START) {
smb_transaction(s);
+ }
break;
case SMBHSTCMD:
s->smb_cmd = val;
@@ -185,7 +201,7 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
break;
case SMBHSTCNT:
s->smb_index = 0;
- val = s->smb_ctl & 0x1f;
+ val = s->smb_ctl & CTL_RETURN_MASK;
break;
case SMBHSTCMD:
val = s->smb_cmd;
@@ -208,7 +224,9 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
val = 0;
break;
}
- SMBUS_DPRINTF("SMB readb port=0x%04" HWADDR_PRIx " val=0x%02x\n", addr, val);
+ SMBUS_DPRINTF("SMB readb port=0x%04" HWADDR_PRIx " val=0x%02x\n",
+ addr, val);
+
return val;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 02/14] i2c:pm_smbus: Fix the semantics of block I2C transfers
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 01/14] i2c:pm_smbus: Clean up some style issues minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 03/14] i2c:pm_smbus: Make the I2C block read command read-only minyard
` (11 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard, Michael S . Tsirkin, Paolo Bonzini
From: Corey Minyard <cminyard@mvista.com>
The I2C block transfer commands was not implemented correctly, it
read a length byte and such like it was an smbus transfer.
So fix the smbus_read_block() and smbus_write_block() functions
so they can properly handle I2C transfers, and normal SMBus
transfers (for upcoming changes). Pass in a transfer size and
a bool to know whether to use the size byte (like SMBus) or use
the length given (like I2C).
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i2c/pm_smbus.c | 10 ++++++++--
hw/i2c/smbus.c | 37 ++++++++++++++++++++++++-------------
include/hw/i2c/smbus.h | 17 +++++++++++++++--
3 files changed, 47 insertions(+), 17 deletions(-)
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index 92c3aebd..679edbc 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -115,10 +115,16 @@ static void smb_transaction(PMSMBus *s)
break;
case PROT_I2C_BLOCK_DATA:
if (read) {
- ret = smbus_read_block(bus, addr, cmd, s->smb_data);
+ int xfersize = s->smb_data0;
+ if (xfersize > sizeof(s->smb_data)) {
+ xfersize = sizeof(s->smb_data);
+ }
+ ret = smbus_read_block(bus, addr, s->smb_data1, s->smb_data,
+ xfersize, false, true);
goto data8;
} else {
- ret = smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0);
+ ret = smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0,
+ false);
goto done;
}
break;
diff --git a/hw/i2c/smbus.c b/hw/i2c/smbus.c
index 2d1b79a..4b0e264 100644
--- a/hw/i2c/smbus.c
+++ b/hw/i2c/smbus.c
@@ -301,33 +301,42 @@ int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
return 0;
}
-int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
+int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
+ int len, bool recv_len, bool send_cmd)
{
- int len;
+ int rlen;
int i;
- if (i2c_start_transfer(bus, addr, 0)) {
- return -1;
+ if (send_cmd) {
+ if (i2c_start_transfer(bus, addr, 0)) {
+ return -1;
+ }
+ i2c_send(bus, command);
}
- i2c_send(bus, command);
if (i2c_start_transfer(bus, addr, 1)) {
- i2c_end_transfer(bus);
+ if (send_cmd) {
+ i2c_end_transfer(bus);
+ }
return -1;
}
- len = i2c_recv(bus);
- if (len > 32) {
- len = 0;
+ if (recv_len) {
+ rlen = i2c_recv(bus);
+ } else {
+ rlen = len;
}
- for (i = 0; i < len; i++) {
+ if (rlen > len) {
+ rlen = 0;
+ }
+ for (i = 0; i < rlen; i++) {
data[i] = i2c_recv(bus);
}
i2c_nack(bus);
i2c_end_transfer(bus);
- return len;
+ return rlen;
}
int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
- int len)
+ int len, bool send_len)
{
int i;
@@ -338,7 +347,9 @@ int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
return -1;
}
i2c_send(bus, command);
- i2c_send(bus, len);
+ if (send_len) {
+ i2c_send(bus, len);
+ }
for (i = 0; i < len; i++) {
i2c_send(bus, data[i]);
}
diff --git a/include/hw/i2c/smbus.h b/include/hw/i2c/smbus.h
index 544bbc1..f1b8078 100644
--- a/include/hw/i2c/smbus.h
+++ b/include/hw/i2c/smbus.h
@@ -73,9 +73,22 @@ int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command);
int smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data);
int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command);
int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data);
-int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data);
+
+/*
+ * Do a block transfer from an I2C device. If recv_len is set, then the
+ * first received byte is a length field and is used to know how much data
+ * to receive. Otherwise receive "len" bytes. If send_cmd is set, send
+ * the command byte first before receiving the data.
+ */
+int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
+ int len, bool recv_len, bool send_cmd);
+
+/*
+ * Do a block transfer to an I2C device. If send_len is set, send the
+ * "len" value before the data.
+ */
int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
- int len);
+ int len, bool send_len);
void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
const uint8_t *eeprom_spd, int size);
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 03/14] i2c:pm_smbus: Make the I2C block read command read-only
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 01/14] i2c:pm_smbus: Clean up some style issues minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 02/14] i2c:pm_smbus: Fix the semantics of block I2C transfers minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 04/14] i2c:pm_smbus: Add block transfer capability minyard
` (10 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard, Michael S . Tsirkin, Paolo Bonzini
From: Corey Minyard <cminyard@mvista.com>
It did have write capability, but the manual says the behavior
with write enabled is undefined. So just set an error in this
case.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i2c/pm_smbus.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index 679edbc..e7a8e92 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -56,7 +56,7 @@
#define PROT_WORD_DATA 3
#define PROT_PROC_CALL 4
#define PROT_BLOCK_DATA 5
-#define PROT_I2C_BLOCK_DATA 6
+#define PROT_I2C_BLOCK_READ 6
/*#define DEBUG*/
@@ -113,7 +113,7 @@ static void smb_transaction(PMSMBus *s)
goto done;
}
break;
- case PROT_I2C_BLOCK_DATA:
+ case PROT_I2C_BLOCK_READ:
if (read) {
int xfersize = s->smb_data0;
if (xfersize > sizeof(s->smb_data)) {
@@ -123,9 +123,8 @@ static void smb_transaction(PMSMBus *s)
xfersize, false, true);
goto data8;
} else {
- ret = smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0,
- false);
- goto done;
+ /* The manual says the behavior is undefined, just set DEV_ERR. */
+ goto error;
}
break;
default:
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 04/14] i2c:pm_smbus: Add block transfer capability
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (2 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 03/14] i2c:pm_smbus: Make the I2C block read command read-only minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 05/14] i2c:pm_smbus: Fix state transfer minyard
` (9 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard, Michael S . Tsirkin, Paolo Bonzini
From: Corey Minyard <cminyard@mvista.com>
There was no block transfer code in pm_smbus.c, and it is needed
for some devices. So add it.
This adds both byte-by-byte block transfers and buffered block
transfers.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i2c/pm_smbus.c | 151 ++++++++++++++++++++++++++++++++++++++++++----
hw/i2c/smbus_ich9.c | 8 ++-
include/hw/i2c/pm_smbus.h | 20 +++++-
3 files changed, 164 insertions(+), 15 deletions(-)
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index e7a8e92..686d411 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -30,6 +30,7 @@
#define SMBHSTDAT0 0x05
#define SMBHSTDAT1 0x06
#define SMBBLKDAT 0x07
+#define SMBAUXCTL 0x0d
#define STS_HOST_BUSY (1 << 0)
#define STS_INTR (1 << 1)
@@ -58,6 +59,10 @@
#define PROT_BLOCK_DATA 5
#define PROT_I2C_BLOCK_READ 6
+#define AUX_PEC (1 << 0)
+#define AUX_BLK (1 << 1)
+#define AUX_MASK 0x3
+
/*#define DEBUG*/
#ifdef DEBUG
@@ -127,6 +132,51 @@ static void smb_transaction(PMSMBus *s)
goto error;
}
break;
+ case PROT_BLOCK_DATA:
+ if (read) {
+ ret = smbus_read_block(bus, addr, cmd, s->smb_data,
+ sizeof(s->smb_data), !s->i2c_enable,
+ !s->i2c_enable);
+ if (ret < 0) {
+ goto error;
+ }
+ s->smb_index = 0;
+ s->op_done = false;
+ if (s->smb_auxctl & AUX_BLK) {
+ s->smb_stat |= STS_INTR;
+ } else {
+ s->smb_blkdata = s->smb_data[0];
+ s->smb_stat |= STS_HOST_BUSY | STS_BYTE_DONE;
+ }
+ s->smb_data0 = ret;
+ goto out;
+ } else {
+ if (s->smb_auxctl & AUX_BLK) {
+ if (s->smb_index != s->smb_data0) {
+ s->smb_index = 0;
+ goto error;
+ }
+ /* Data is already all written to the queue, just do
+ the operation. */
+ s->smb_index = 0;
+ ret = smbus_write_block(bus, addr, cmd, s->smb_data,
+ s->smb_data0, !s->i2c_enable);
+ if (ret < 0) {
+ goto error;
+ }
+ s->op_done = true;
+ s->smb_stat |= STS_INTR;
+ s->smb_stat &= ~STS_HOST_BUSY;
+ } else {
+ s->op_done = false;
+ s->smb_stat |= STS_HOST_BUSY | STS_BYTE_DONE;
+ s->smb_data[0] = s->smb_blkdata;
+ s->smb_index = 0;
+ ret = 0;
+ }
+ goto out;
+ }
+ break;
default:
goto error;
}
@@ -146,13 +196,13 @@ done:
if (ret < 0) {
goto error;
}
- s->smb_stat |= STS_BYTE_DONE | STS_INTR;
+ s->smb_stat |= STS_INTR;
+out:
return;
error:
s->smb_stat |= STS_DEV_ERR;
return;
-
}
static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
@@ -164,14 +214,61 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
" val=0x%02" PRIx64 "\n", addr, val);
switch(addr) {
case SMBHSTSTS:
- s->smb_stat = (~(val & 0xff)) & s->smb_stat;
- s->smb_index = 0;
+ s->smb_stat &= ~(val & ~STS_HOST_BUSY);
+ if (!s->op_done && !(s->smb_auxctl & AUX_BLK)) {
+ uint8_t read = s->smb_addr & 0x01;
+
+ s->smb_index++;
+ if (!read && s->smb_index == s->smb_data0) {
+ uint8_t prot = (s->smb_ctl >> 2) & 0x07;
+ uint8_t cmd = s->smb_cmd;
+ uint8_t addr = s->smb_addr >> 1;
+ int ret;
+
+ if (prot == PROT_I2C_BLOCK_READ) {
+ s->smb_stat |= STS_DEV_ERR;
+ goto out;
+ }
+
+ ret = smbus_write_block(s->smbus, addr, cmd, s->smb_data,
+ s->smb_data0, !s->i2c_enable);
+ if (ret < 0) {
+ s->smb_stat |= STS_DEV_ERR;
+ goto out;
+ }
+ s->op_done = true;
+ s->smb_stat |= STS_INTR;
+ s->smb_stat &= ~STS_HOST_BUSY;
+ } else if (!read) {
+ s->smb_data[s->smb_index] = s->smb_blkdata;
+ s->smb_stat |= STS_BYTE_DONE;
+ } else if (s->smb_ctl & CTL_LAST_BYTE) {
+ s->op_done = true;
+ s->smb_blkdata = s->smb_data[s->smb_index];
+ s->smb_index = 0;
+ s->smb_stat |= STS_INTR;
+ s->smb_stat &= ~STS_HOST_BUSY;
+ } else {
+ s->smb_blkdata = s->smb_data[s->smb_index];
+ s->smb_stat |= STS_BYTE_DONE;
+ }
+ }
break;
case SMBHSTCNT:
- s->smb_ctl = val;
- if (s->smb_ctl & CTL_START) {
+ s->smb_ctl = val & ~CTL_START; /* CTL_START always reads 0 */
+ if (val & CTL_START) {
+ if (!s->op_done) {
+ s->smb_index = 0;
+ s->op_done = true;
+ }
smb_transaction(s);
}
+ if (s->smb_ctl & CTL_KILL) {
+ s->op_done = true;
+ s->smb_index = 0;
+ s->smb_stat |= STS_FAILED;
+ s->smb_stat &= ~STS_HOST_BUSY;
+ }
break;
case SMBHSTCMD:
s->smb_cmd = val;
@@ -186,13 +283,24 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
s->smb_data1 = val;
break;
case SMBBLKDAT:
- s->smb_data[s->smb_index++] = val;
- if (s->smb_index > 31)
+ if (s->smb_index >= PM_SMBUS_MAX_MSG_SIZE) {
s->smb_index = 0;
+ }
+ if (s->smb_auxctl & AUX_BLK) {
+ s->smb_data[s->smb_index++] = val;
+ } else {
+ s->smb_blkdata = val;
+ }
+ break;
+ case SMBAUXCTL:
+ s->smb_auxctl = val & AUX_MASK;
break;
default:
break;
}
+
+ out:
+ return;
}
static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
@@ -205,7 +313,6 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
val = s->smb_stat;
break;
case SMBHSTCNT:
- s->smb_index = 0;
val = s->smb_ctl & CTL_RETURN_MASK;
break;
case SMBHSTCMD:
@@ -221,9 +328,22 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
val = s->smb_data1;
break;
case SMBBLKDAT:
- val = s->smb_data[s->smb_index++];
- if (s->smb_index > 31)
+ if (s->smb_index >= PM_SMBUS_MAX_MSG_SIZE) {
s->smb_index = 0;
+ }
+ if (s->smb_auxctl & AUX_BLK) {
+ val = s->smb_data[s->smb_index++];
+ if (!s->op_done && s->smb_index == s->smb_data0) {
+ s->op_done = true;
+ s->smb_index = 0;
+ s->smb_stat &= ~STS_HOST_BUSY;
+ }
+ } else {
+ val = s->smb_blkdata;
+ }
+ break;
+ case SMBAUXCTL:
+ val = s->smb_auxctl;
break;
default:
val = 0;
@@ -235,6 +355,13 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
return val;
}
+static void pm_smbus_reset(PMSMBus *s)
+{
+ s->op_done = true;
+ s->smb_index = 0;
+ s->smb_stat = 0;
+}
+
static const MemoryRegionOps pm_smbus_ops = {
.read = smb_ioport_readb,
.write = smb_ioport_writeb,
@@ -245,6 +372,8 @@ static const MemoryRegionOps pm_smbus_ops = {
void pm_smbus_init(DeviceState *parent, PMSMBus *smb)
{
+ smb->op_done = true;
+ smb->reset = pm_smbus_reset;
smb->smbus = i2c_init_bus(parent, "i2c");
memory_region_init_io(&smb->io, OBJECT(parent), &pm_smbus_ops, smb,
"pm-smbus", 64);
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index e47556c..59e165a 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -62,12 +62,16 @@ static void ich9_smbus_write_config(PCIDevice *d, uint32_t address,
pci_default_write_config(d, address, val, len);
if (range_covers_byte(address, len, ICH9_SMB_HOSTC)) {
uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC];
- if ((hostc & ICH9_SMB_HOSTC_HST_EN) &&
- !(hostc & ICH9_SMB_HOSTC_I2C_EN)) {
+ if (hostc & ICH9_SMB_HOSTC_HST_EN) {
memory_region_set_enabled(&s->smb.io, true);
} else {
memory_region_set_enabled(&s->smb.io, false);
}
+ s->smb.i2c_enable = (hostc & ICH9_SMB_HOSTC_I2C_EN) != 0;
+ if (hostc & ICH9_SMB_HOSTC_SSRESET) {
+ s->smb.reset(&s->smb);
+ s->dev.config[ICH9_SMB_HOSTC] &= ~ICH9_SMB_HOSTC_SSRESET;
+ }
}
}
diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h
index 2a837af..99d5489 100644
--- a/include/hw/i2c/pm_smbus.h
+++ b/include/hw/i2c/pm_smbus.h
@@ -1,6 +1,8 @@
#ifndef PM_SMBUS_H
#define PM_SMBUS_H
+#define PM_SMBUS_MAX_MSG_SIZE 32
+
typedef struct PMSMBus {
I2CBus *smbus;
MemoryRegion io;
@@ -11,8 +13,22 @@ typedef struct PMSMBus {
uint8_t smb_addr;
uint8_t smb_data0;
uint8_t smb_data1;
- uint8_t smb_data[32];
- uint8_t smb_index;
+ uint8_t smb_data[PM_SMBUS_MAX_MSG_SIZE];
+ uint8_t smb_blkdata;
+ uint8_t smb_auxctl;
+ uint32_t smb_index;
+
+ /* Set by pm_smbus.c */
+ void (*reset)(struct PMSMBus *s);
+
+ /* Set by the user. */
+ bool i2c_enable;
+
+ /* Internally used by pm_smbus. */
+
+ /* Set on block transfers after the last byte has been read, so the
+ INTR bit can be set at the right time. */
+ bool op_done;
} PMSMBus;
void pm_smbus_init(DeviceState *parent, PMSMBus *smb);
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 05/14] i2c:pm_smbus: Fix state transfer
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (3 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 04/14] i2c:pm_smbus: Add block transfer capability minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 06/14] i2c:pm_smbus: Add interrupt handling minyard
` (8 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard, Michael S . Tsirkin, Paolo Bonzini
From: Corey Minyard <cminyard@mvista.com>
Transfer the state information for the SMBus registers and
internal data so it will work on a VM transfer.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
hw/acpi/piix4.c | 1 +
hw/i2c/pm_smbus.c | 19 +++++++++++++++++++
hw/i2c/smbus_ich9.c | 3 ++-
include/hw/i2c/pm_smbus.h | 2 ++
4 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index a0fb1ce..18c1ffa 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -321,6 +321,7 @@ static const VMStateDescription vmstate_acpi = {
VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState),
VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
+ VMSTATE_STRUCT(smb, PIIX4PMState, 1, pmsmb_vmstate, PMSMBus),
VMSTATE_TIMER_PTR(ar.tmr.timer, PIIX4PMState),
VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState),
VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index 686d411..eb2df4d 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -370,6 +370,25 @@ static const MemoryRegionOps pm_smbus_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
+const VMStateDescription pmsmb_vmstate = {
+ .name = "pmsmb",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(smb_stat, PMSMBus),
+ VMSTATE_UINT8(smb_ctl, PMSMBus),
+ VMSTATE_UINT8(smb_cmd, PMSMBus),
+ VMSTATE_UINT8(smb_addr, PMSMBus),
+ VMSTATE_UINT8(smb_data0, PMSMBus),
+ VMSTATE_UINT8(smb_data1, PMSMBus),
+ VMSTATE_VBUFFER_UINT32(smb_data, PMSMBus, 1, NULL, smb_index),
+ VMSTATE_UINT8(smb_auxctl, PMSMBus),
+ VMSTATE_BOOL(i2c_enable, PMSMBus),
+ VMSTATE_BOOL(op_done, PMSMBus),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
void pm_smbus_init(DeviceState *parent, PMSMBus *smb)
{
smb->op_done = true;
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index 59e165a..706b9ec 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -49,7 +49,8 @@ static const VMStateDescription vmstate_ich9_smbus = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_PCI_DEVICE(dev, struct ICH9SMBState),
+ VMSTATE_PCI_DEVICE(dev, ICH9SMBState),
+ VMSTATE_STRUCT(smb, ICH9SMBState, 1, pmsmb_vmstate, PMSMBus),
VMSTATE_END_OF_LIST()
}
};
diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h
index 99d5489..b1e1970 100644
--- a/include/hw/i2c/pm_smbus.h
+++ b/include/hw/i2c/pm_smbus.h
@@ -33,4 +33,6 @@ typedef struct PMSMBus {
void pm_smbus_init(DeviceState *parent, PMSMBus *smb);
+extern const VMStateDescription pmsmb_vmstate;
+
#endif /* PM_SMBUS_H */
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 06/14] i2c:pm_smbus: Add interrupt handling
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (4 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 05/14] i2c:pm_smbus: Fix state transfer minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 07/14] i2c:pm_smbus: Add the ability to force block transfer enable minyard
` (7 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard, Michael S . Tsirkin, Paolo Bonzini
From: Corey Minyard <cminyard@mvista.com>
Add the necessary code so that interrupts actually work from
the pm_smbus device.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i2c/pm_smbus.c | 14 +++++++++++++-
hw/i2c/smbus_ich9.c | 17 +++++++++++++++++
include/hw/i2c/pm_smbus.h | 2 ++
3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index eb2df4d..2fb00d0 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -205,6 +205,12 @@ error:
return;
}
+static bool
+smb_irq_value(PMSMBus *s)
+{
+ return ((s->smb_stat & ~STS_HOST_BUSY) != 0) && (s->smb_ctl & CTL_INTREN);
+}
+
static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
unsigned width)
{
@@ -300,7 +306,9 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
}
out:
- return;
+ if (s->set_irq) {
+ s->set_irq(s, smb_irq_value(s));
+ }
}
static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
@@ -352,6 +360,10 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
SMBUS_DPRINTF("SMB readb port=0x%04" HWADDR_PRIx " val=0x%02x\n",
addr, val);
+ if (s->set_irq) {
+ s->set_irq(s, smb_irq_value(s));
+ }
+
return val;
}
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index 706b9ec..d029816 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -41,6 +41,8 @@
typedef struct ICH9SMBState {
PCIDevice dev;
+ bool irq_enabled;
+
PMSMBus smb;
} ICH9SMBState;
@@ -50,6 +52,7 @@ static const VMStateDescription vmstate_ich9_smbus = {
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, ICH9SMBState),
+ VMSTATE_BOOL(irq_enabled, ICH9SMBState),
VMSTATE_STRUCT(smb, ICH9SMBState, 1, pmsmb_vmstate, PMSMBus),
VMSTATE_END_OF_LIST()
}
@@ -111,11 +114,25 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data)
dc->user_creatable = false;
}
+static void ich9_smb_set_irq(PMSMBus *pmsmb, bool enabled)
+{
+ ICH9SMBState *s = pmsmb->opaque;
+
+ if (enabled == s->irq_enabled) {
+ return;
+ }
+
+ s->irq_enabled = enabled;
+ pci_set_irq(&s->dev, enabled);
+}
+
I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
{
PCIDevice *d =
pci_create_simple_multifunction(bus, devfn, true, TYPE_ICH9_SMB_DEVICE);
ICH9SMBState *s = ICH9_SMB_DEVICE(d);
+ s->smb.set_irq = ich9_smb_set_irq;
+ s->smb.opaque = s;
return s->smb.smbus;
}
diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h
index b1e1970..cfe596f 100644
--- a/include/hw/i2c/pm_smbus.h
+++ b/include/hw/i2c/pm_smbus.h
@@ -23,6 +23,8 @@ typedef struct PMSMBus {
/* Set by the user. */
bool i2c_enable;
+ void (*set_irq)(struct PMSMBus *s, bool enabled);
+ void *opaque;
/* Internally used by pm_smbus. */
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 07/14] i2c:pm_smbus: Add the ability to force block transfer enable
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (5 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 06/14] i2c:pm_smbus: Add interrupt handling minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 08/14] i2c: Add an SMBus vmstate structure minyard
` (6 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard, Michael S . Tsirkin, Paolo Bonzini
From: Corey Minyard <cminyard@mvista.com>
The PIIX4 hardware has block transfer buffer always enabled in
the hardware, but the i801 does not. Add a parameter to pm_smbus_init
to force on the block transfer so the PIIX4 handler can enable this
by default, as it was disabled by default before.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
hw/acpi/piix4.c | 2 +-
hw/i2c/pm_smbus.c | 5 ++++-
hw/i2c/smbus_ich9.c | 2 +-
hw/isa/vt82c686.c | 2 +-
include/hw/i2c/pm_smbus.h | 2 +-
5 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 18c1ffa..7018235 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -514,7 +514,7 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
pci_conf[0x90] = s->smb_io_base | 1;
pci_conf[0x91] = s->smb_io_base >> 8;
pci_conf[0xd2] = 0x09;
- pm_smbus_init(DEVICE(dev), &s->smb);
+ pm_smbus_init(DEVICE(dev), &s->smb, true);
memory_region_set_enabled(&s->smb.io, pci_conf[0xd2] & 1);
memory_region_add_subregion(pci_address_space_io(dev),
s->smb_io_base, &s->smb.io);
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index 2fb00d0..2afc5e1 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -401,11 +401,14 @@ const VMStateDescription pmsmb_vmstate = {
}
};
-void pm_smbus_init(DeviceState *parent, PMSMBus *smb)
+void pm_smbus_init(DeviceState *parent, PMSMBus *smb, bool force_aux_blk)
{
smb->op_done = true;
smb->reset = pm_smbus_reset;
smb->smbus = i2c_init_bus(parent, "i2c");
+ if (force_aux_blk) {
+ smb->smb_auxctl |= AUX_BLK;
+ }
memory_region_init_io(&smb->io, OBJECT(parent), &pm_smbus_ops, smb,
"pm-smbus", 64);
}
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index d029816..ce5ea9e 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -89,7 +89,7 @@ static void ich9_smbus_realize(PCIDevice *d, Error **errp)
pci_set_byte(d->config + ICH9_SMB_HOSTC, 0);
/* TODO bar0, bar1: 64bit BAR support*/
- pm_smbus_init(&d->qdev, &s->smb);
+ pm_smbus_init(&d->qdev, &s->smb, false);
pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
&s->smb.io);
}
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index c129985..78b7468 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -370,7 +370,7 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp)
pci_conf[0x90] = s->smb_io_base | 1;
pci_conf[0x91] = s->smb_io_base >> 8;
pci_conf[0xd2] = 0x90;
- pm_smbus_init(&s->dev.qdev, &s->smb);
+ pm_smbus_init(&s->dev.qdev, &s->smb, false);
memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io);
apm_init(dev, &s->apm, NULL, s);
diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h
index cfe596f..471345e 100644
--- a/include/hw/i2c/pm_smbus.h
+++ b/include/hw/i2c/pm_smbus.h
@@ -33,7 +33,7 @@ typedef struct PMSMBus {
bool op_done;
} PMSMBus;
-void pm_smbus_init(DeviceState *parent, PMSMBus *smb);
+void pm_smbus_init(DeviceState *parent, PMSMBus *smb, bool force_aux_blk);
extern const VMStateDescription pmsmb_vmstate;
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 08/14] i2c: Add an SMBus vmstate structure
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (6 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 07/14] i2c:pm_smbus: Add the ability to force block transfer enable minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 09/14] i2c: Add vmstate handling to the smbus eeprom minyard
` (5 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard
From: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
hw/i2c/smbus.c | 14 ++++++++++++++
include/hw/i2c/smbus.h | 18 +++++++++++++++---
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/hw/i2c/smbus.c b/hw/i2c/smbus.c
index 4b0e264..e15f3f2 100644
--- a/hw/i2c/smbus.c
+++ b/hw/i2c/smbus.c
@@ -357,6 +357,20 @@ int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
return 0;
}
+const VMStateDescription vmstate_smbus_device = {
+ .name = TYPE_SMBUS_DEVICE,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_I2C_SLAVE(i2c, SMBusDevice),
+ VMSTATE_INT32(mode, SMBusDevice),
+ VMSTATE_INT32(data_len, SMBusDevice),
+ VMSTATE_UINT8_ARRAY(data_buf, SMBusDevice, SMBUS_DATA_MAX_LEN),
+ VMSTATE_UINT8(command, SMBusDevice),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void smbus_device_class_init(ObjectClass *klass, void *data)
{
I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
diff --git a/include/hw/i2c/smbus.h b/include/hw/i2c/smbus.h
index f1b8078..7794026 100644
--- a/include/hw/i2c/smbus.h
+++ b/include/hw/i2c/smbus.h
@@ -54,14 +54,16 @@ typedef struct SMBusDeviceClass
uint8_t (*read_data)(SMBusDevice *dev, uint8_t cmd, int n);
} SMBusDeviceClass;
+#define SMBUS_DATA_MAX_LEN 34 /* command + len + 32 bytes of data. */
+
struct SMBusDevice {
/* The SMBus protocol is implemented on top of I2C. */
I2CSlave i2c;
/* Remaining fields for internal use only. */
- int mode;
- int data_len;
- uint8_t data_buf[34]; /* command + len + 32 bytes of data. */
+ int32_t mode;
+ int32_t data_len;
+ uint8_t data_buf[SMBUS_DATA_MAX_LEN];
uint8_t command;
};
@@ -93,4 +95,14 @@ int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
const uint8_t *eeprom_spd, int size);
+extern const VMStateDescription vmstate_smbus_device;
+
+#define VMSTATE_SMBUS_DEVICE(_field, _state) { \
+ .name = (stringify(_field)), \
+ .size = sizeof(SMBusDevice), \
+ .vmsd = &vmstate_smbus_device, \
+ .flags = VMS_STRUCT, \
+ .offset = vmstate_offset_value(_state, _field, SMBusDevice), \
+}
+
#endif
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 09/14] i2c: Add vmstate handling to the smbus eeprom
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (7 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 08/14] i2c: Add an SMBus vmstate structure minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 10/14] ipmi: Add an SMBus IPMI interface minyard
` (4 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard
From: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
hw/i2c/smbus_eeprom.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
index b13ec0f..089005d 100644
--- a/hw/i2c/smbus_eeprom.c
+++ b/hw/i2c/smbus_eeprom.c
@@ -29,6 +29,8 @@
//#define DEBUG
+#define TYPE_SMBUS_EEPROM_DEVICE "smbus-eeprom"
+
typedef struct SMBusEEPROMDevice {
SMBusDevice smbusdev;
void *data;
@@ -97,6 +99,17 @@ static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
return eeprom_receive_byte(dev);
}
+static const VMStateDescription vmstate_smbus_eeprom = {
+ .name = TYPE_SMBUS_EEPROM_DEVICE,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_SMBUS_DEVICE(smbusdev, SMBusEEPROMDevice),
+ VMSTATE_UINT8(offset, SMBusEEPROMDevice),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static int smbus_eeprom_initfn(SMBusDevice *dev)
{
SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev;
@@ -122,12 +135,13 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
sc->write_data = eeprom_write_data;
sc->read_data = eeprom_read_data;
dc->props = smbus_eeprom_properties;
+ dc->vmsd = &vmstate_smbus_eeprom;
/* Reason: pointer property "data" */
dc->user_creatable = false;
}
static const TypeInfo smbus_eeprom_info = {
- .name = "smbus-eeprom",
+ .name = TYPE_SMBUS_EEPROM_DEVICE,
.parent = TYPE_SMBUS_DEVICE,
.instance_size = sizeof(SMBusEEPROMDevice),
.class_init = smbus_eeprom_class_initfn,
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 10/14] ipmi: Add an SMBus IPMI interface
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (8 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 09/14] i2c: Add vmstate handling to the smbus eeprom minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 11/14] acpi: Add i2c serial bus CRS handling minyard
` (3 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard
From: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
default-configs/i386-softmmu.mak | 1 +
default-configs/x86_64-softmmu.mak | 1 +
hw/ipmi/Makefile.objs | 1 +
hw/ipmi/smbus_ipmi.c | 236 +++++++++++++++++++++++++++++++++++++
4 files changed, 239 insertions(+)
create mode 100644 hw/ipmi/smbus_ipmi.c
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 07aaf77..7791418 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -17,6 +17,7 @@ CONFIG_ISA_IPMI_KCS=y
CONFIG_PCI_IPMI_KCS=y
CONFIG_ISA_IPMI_BT=y
CONFIG_PCI_IPMI_BT=y
+CONFIG_IPMI_SSIF=y
CONFIG_SERIAL=y
CONFIG_SERIAL_ISA=y
CONFIG_PARALLEL=y
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index 179ca35..7d8d673 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -17,6 +17,7 @@ CONFIG_ISA_IPMI_KCS=y
CONFIG_PCI_IPMI_KCS=y
CONFIG_ISA_IPMI_BT=y
CONFIG_PCI_IPMI_BT=y
+CONFIG_IPMI_SSIF=y
CONFIG_SERIAL=y
CONFIG_SERIAL_ISA=y
CONFIG_PARALLEL=y
diff --git a/hw/ipmi/Makefile.objs b/hw/ipmi/Makefile.objs
index 2d7f080..3cca10b 100644
--- a/hw/ipmi/Makefile.objs
+++ b/hw/ipmi/Makefile.objs
@@ -5,3 +5,4 @@ common-obj-$(CONFIG_ISA_IPMI_KCS) += isa_ipmi_kcs.o
common-obj-$(CONFIG_PCI_IPMI_KCS) += pci_ipmi_kcs.o
common-obj-$(CONFIG_ISA_IPMI_BT) += isa_ipmi_bt.o
common-obj-$(CONFIG_PCI_IPMI_BT) += pci_ipmi_bt.o
+common-obj-$(CONFIG_IPMI_SSIF) += smbus_ipmi.o
diff --git a/hw/ipmi/smbus_ipmi.c b/hw/ipmi/smbus_ipmi.c
new file mode 100644
index 0000000..75e26c8
--- /dev/null
+++ b/hw/ipmi/smbus_ipmi.c
@@ -0,0 +1,236 @@
+/*
+ * QEMU IPMI SMBus (SSIF) emulation
+ *
+ * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/i2c/smbus.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "hw/ipmi/ipmi.h"
+
+#define TYPE_SMBUS_IPMI "smbus-ipmi"
+#define SMBUS_IPMI(obj) OBJECT_CHECK(SMBusIPMIDevice, (obj), TYPE_SMBUS_IPMI)
+
+#define SSIF_IPMI_REQUEST 2
+#define SSIF_IPMI_MULTI_PART_REQUEST_START 6
+#define SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE 7
+#define SSIF_IPMI_RESPONSE 3
+#define SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE 9
+
+typedef struct SMBusIPMIDevice {
+ SMBusDevice parent;
+
+ IPMIBmc *bmc;
+
+ uint8_t outmsg[MAX_IPMI_MSG_SIZE];
+ uint32_t outpos;
+ uint32_t outlen;
+
+ uint8_t inmsg[MAX_IPMI_MSG_SIZE];
+ uint32_t inlen;
+
+ /*
+ * This is a response number that we send with the command to make
+ * sure that the response matches the command.
+ */
+ uint8_t waiting_rsp;
+
+ uint32_t uuid;
+} SMBusIPMIDevice;
+
+static void smbus_ipmi_handle_event(IPMIInterface *ii)
+{
+ /* No interrupts, so nothing to do here. */
+}
+
+static void smbus_ipmi_handle_rsp(IPMIInterface *ii, uint8_t msg_id,
+ unsigned char *rsp, unsigned int rsp_len)
+{
+ SMBusIPMIDevice *sid = SMBUS_IPMI(ii);
+
+ if (sid->waiting_rsp == msg_id) {
+ sid->waiting_rsp++;
+
+ memcpy(sid->outmsg, rsp, rsp_len);
+ sid->outlen = rsp_len;
+ sid->outpos = 0;
+ }
+}
+
+static void smbus_ipmi_set_atn(IPMIInterface *ii, int val, int irq)
+{
+ /* This is where PEC would go. */
+}
+
+static void smbus_ipmi_set_irq_enable(IPMIInterface *ii, int val)
+{
+}
+
+static void ipmi_quick_cmd(SMBusDevice *dev, uint8_t read)
+{
+}
+
+static void ipmi_send_byte(SMBusDevice *dev, uint8_t val)
+{
+}
+
+static uint8_t ipmi_receive_byte(SMBusDevice *dev)
+{
+ SMBusIPMIDevice *sid = SMBUS_IPMI(dev);
+
+ if (sid->outpos >= sid->outlen) {
+ return 0;
+ }
+
+ return sid->outmsg[sid->outpos++];
+}
+
+static void ipmi_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf,
+ int len)
+{
+ SMBusIPMIDevice *sid = SMBUS_IPMI(dev);
+ IPMIBmcClass *bk = IPMI_BMC_GET_CLASS(sid->bmc);
+
+ if (cmd != SSIF_IPMI_REQUEST) {
+ return;
+ }
+
+ if (len < 3 || len > MAX_IPMI_MSG_SIZE || buf[0] != len - 1) {
+ return;
+ }
+
+ memcpy(sid->inmsg, buf + 1, len - 1);
+ sid->inlen = len;
+
+ sid->outlen = 0;
+ sid->outpos = 0;
+ bk->handle_command(sid->bmc, sid->inmsg, sid->inlen, sizeof(sid->inmsg),
+ sid->waiting_rsp);
+}
+
+static uint8_t ipmi_read_data(SMBusDevice *dev, uint8_t cmd, int n)
+{
+ SMBusIPMIDevice *sid = SMBUS_IPMI(dev);
+
+ if (cmd != SSIF_IPMI_RESPONSE) {
+ return 0;
+ }
+
+ if (n == 0) {
+ return sid->outlen;
+ }
+
+ return ipmi_receive_byte(dev);
+}
+
+static const VMStateDescription vmstate_smbus_ipmi = {
+ .name = TYPE_SMBUS_IPMI,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_SMBUS_DEVICE(parent, SMBusIPMIDevice),
+ VMSTATE_UINT8(waiting_rsp, SMBusIPMIDevice),
+ VMSTATE_UINT32(outpos, SMBusIPMIDevice),
+ VMSTATE_UINT32(outlen, SMBusIPMIDevice),
+ VMSTATE_UINT8_ARRAY(outmsg, SMBusIPMIDevice, MAX_IPMI_MSG_SIZE),
+ VMSTATE_UINT32(inlen, SMBusIPMIDevice),
+ VMSTATE_UINT8_ARRAY(inmsg, SMBusIPMIDevice, MAX_IPMI_MSG_SIZE),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void smbus_ipmi_realize(DeviceState *dev, Error **errp)
+{
+ SMBusIPMIDevice *sid = SMBUS_IPMI(dev);
+ IPMIInterface *ii = IPMI_INTERFACE(dev);
+
+ if (!sid->bmc) {
+ error_setg(errp, "IPMI device requires a bmc attribute to be set");
+ return;
+ }
+
+ sid->uuid = ipmi_next_uuid();
+
+ sid->bmc->intf = ii;
+}
+
+static void smbus_ipmi_init(Object *obj)
+{
+ SMBusIPMIDevice *sid = SMBUS_IPMI(obj);
+
+ ipmi_bmc_find_and_link(OBJECT(obj), (Object **) &sid->bmc);
+}
+
+static void smbus_ipmi_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info)
+{
+ SMBusIPMIDevice *sid = SMBUS_IPMI(ii);
+
+ info->interface_name = "smbus";
+ info->interface_type = IPMI_SMBIOS_SSIF;
+ info->ipmi_spec_major_revision = 2;
+ info->ipmi_spec_minor_revision = 0;
+ info->i2c_slave_address = sid->bmc->slave_addr;
+ info->base_address = sid->parent.i2c.address;
+ info->memspace = IPMI_MEMSPACE_SMBUS;
+ info->register_spacing = 1;
+ info->uuid = sid->uuid;
+}
+
+static void smbus_ipmi_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc);
+ SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(oc);
+
+ sc->quick_cmd = ipmi_quick_cmd;
+ sc->send_byte = ipmi_send_byte;
+ sc->receive_byte = ipmi_receive_byte;
+ sc->write_data = ipmi_write_data;
+ sc->read_data = ipmi_read_data;
+ dc->vmsd = &vmstate_smbus_ipmi;
+ dc->realize = smbus_ipmi_realize;
+ iic->set_atn = smbus_ipmi_set_atn;
+ iic->handle_rsp = smbus_ipmi_handle_rsp;
+ iic->handle_if_event = smbus_ipmi_handle_event;
+ iic->set_irq_enable = smbus_ipmi_set_irq_enable;
+ iic->get_fwinfo = smbus_ipmi_get_fwinfo;
+}
+
+static const TypeInfo smbus_ipmi_info = {
+ .name = TYPE_SMBUS_IPMI,
+ .parent = TYPE_SMBUS_DEVICE,
+ .instance_size = sizeof(SMBusIPMIDevice),
+ .instance_init = smbus_ipmi_init,
+ .class_init = smbus_ipmi_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_IPMI_INTERFACE },
+ { }
+ }
+};
+
+static void smbus_ipmi_register_types(void)
+{
+ type_register_static(&smbus_ipmi_info);
+}
+
+type_init(smbus_ipmi_register_types)
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 11/14] acpi: Add i2c serial bus CRS handling
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (9 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 10/14] ipmi: Add an SMBus IPMI interface minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 12/14] ipmi: Fix SSIF ACPI handling to use the right CRS minyard
` (2 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard
From: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
hw/acpi/aml-build.c | 40 ++++++++++++++++++++++++++++++++++++++++
include/hw/acpi/aml-build.h | 18 ++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 36a6cc4..36e2263 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1662,3 +1662,43 @@ void build_slit(GArray *table_data, BIOSLinker *linker)
"SLIT",
table_data->len - slit_start, 1, NULL, NULL);
}
+
+/* ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors */
+static Aml *aml_serial_bus_device(uint8_t serial_bus_type, uint8_t flags,
+ uint16_t type_flags,
+ uint8_t revid, uint16_t data_length,
+ uint16_t resource_source_len)
+{
+ Aml *var = aml_alloc();
+ uint16_t length = data_length + resource_source_len + 9;
+
+ build_append_byte(var->buf, 0x8e); /* Serial Bus Connection Descriptor */
+ build_append_int_noprefix(var->buf, length, sizeof(length));
+ build_append_byte(var->buf, 1); /* Revision ID */
+ build_append_byte(var->buf, 0); /* Resource Source Index */
+ build_append_byte(var->buf, serial_bus_type); /* Serial Bus Type */
+ build_append_byte(var->buf, flags); /* General Flags */
+ build_append_int_noprefix(var->buf, type_flags, /* Type Specific Flags */
+ sizeof(type_flags));
+ build_append_byte(var->buf, revid); /* Type Specification Revision ID */
+ build_append_int_noprefix(var->buf, data_length, sizeof(data_length));
+
+ return var;
+}
+
+/* ACPI 5.0: 6.4.3.8.2.1 I2C Serial Bus Connection Resource Descriptor */
+Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source)
+{
+ uint16_t resource_source_len = strlen(resource_source) + 1;
+ Aml *var = aml_serial_bus_device(AML_SERIAL_BUS_TYPE_I2C, 0, 0, 1,
+ 6, resource_source_len);
+
+ /* Connection Speed. Just set to 100K for now, it doesn't really matter. */
+ build_append_int_noprefix(var->buf, 100000, 4);
+ build_append_int_noprefix(var->buf, address, sizeof(address));
+
+ /* This is a string, not a name, so just copy it directly in. */
+ g_array_append_vals(var->buf, resource_source, resource_source_len);
+
+ return var;
+}
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 88d0738..26fece8 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -214,6 +214,23 @@ struct AcpiBuildTables {
BIOSLinker *linker;
} AcpiBuildTables;
+/*
+ * ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors
+ * Serial Bus Type
+ */
+#define AML_SERIAL_BUS_TYPE_I2C 1
+#define AML_SERIAL_BUS_TYPE_SPI 2
+#define AML_SERIAL_BUS_TYPE_UART 3
+
+/*
+ * ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors
+ * General Flags
+ */
+/* Slave Mode */
+#define AML_SERIAL_BUS_FLAG_MASTER_DEVICE (1 << 0)
+/* Consumer/Producer */
+#define AML_SERIAL_BUS_FLAG_CONSUME_ONLY (1 << 1)
+
/**
* init_aml_allocator:
*
@@ -338,6 +355,7 @@ Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
uint8_t channel);
Aml *aml_sleep(uint64_t msec);
+Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source);
/* Block AML object primitives */
Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 12/14] ipmi: Fix SSIF ACPI handling to use the right CRS
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (10 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 11/14] acpi: Add i2c serial bus CRS handling minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 13/14] i386: Rename bools in PCMachineState to end in _enabled minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 14/14] pc: Add an SMB0 ACPI device to q35 minyard
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard
From: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
hw/acpi/ipmi-stub.c | 2 +-
hw/acpi/ipmi.c | 13 +++++++------
hw/i386/acpi-build.c | 2 +-
include/hw/acpi/ipmi.h | 2 +-
4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/hw/acpi/ipmi-stub.c b/hw/acpi/ipmi-stub.c
index 98b6dce..6c71d6c 100644
--- a/hw/acpi/ipmi-stub.c
+++ b/hw/acpi/ipmi-stub.c
@@ -9,6 +9,6 @@
#include "hw/acpi/ipmi.h"
-void build_acpi_ipmi_devices(Aml *table, BusState *bus)
+void build_acpi_ipmi_devices(Aml *table, BusState *bus, const char *resource)
{
}
diff --git a/hw/acpi/ipmi.c b/hw/acpi/ipmi.c
index 651e2e9..96e48eb 100644
--- a/hw/acpi/ipmi.c
+++ b/hw/acpi/ipmi.c
@@ -13,7 +13,7 @@
#include "hw/acpi/acpi.h"
#include "hw/acpi/ipmi.h"
-static Aml *aml_ipmi_crs(IPMIFwInfo *info)
+static Aml *aml_ipmi_crs(IPMIFwInfo *info, const char *resource)
{
Aml *crs = aml_resource_template();
@@ -48,7 +48,8 @@ static Aml *aml_ipmi_crs(IPMIFwInfo *info)
info->register_spacing, info->register_length));
break;
case IPMI_MEMSPACE_SMBUS:
- aml_append(crs, aml_return(aml_int(info->base_address)));
+ aml_append(crs, aml_i2c_serial_bus_device(info->base_address,
+ resource));
break;
default:
abort();
@@ -61,7 +62,7 @@ static Aml *aml_ipmi_crs(IPMIFwInfo *info)
return crs;
}
-static Aml *aml_ipmi_device(IPMIFwInfo *info)
+static Aml *aml_ipmi_device(IPMIFwInfo *info, const char *resource)
{
Aml *dev;
uint16_t version = ((info->ipmi_spec_major_revision << 8)
@@ -74,14 +75,14 @@ static Aml *aml_ipmi_device(IPMIFwInfo *info)
aml_append(dev, aml_name_decl("_STR", aml_string("ipmi_%s",
info->interface_name)));
aml_append(dev, aml_name_decl("_UID", aml_int(info->uuid)));
- aml_append(dev, aml_name_decl("_CRS", aml_ipmi_crs(info)));
+ aml_append(dev, aml_name_decl("_CRS", aml_ipmi_crs(info, resource)));
aml_append(dev, aml_name_decl("_IFT", aml_int(info->interface_type)));
aml_append(dev, aml_name_decl("_SRV", aml_int(version)));
return dev;
}
-void build_acpi_ipmi_devices(Aml *scope, BusState *bus)
+void build_acpi_ipmi_devices(Aml *scope, BusState *bus, const char *resource)
{
BusChild *kid;
@@ -101,6 +102,6 @@ void build_acpi_ipmi_devices(Aml *scope, BusState *bus)
iic = IPMI_INTERFACE_GET_CLASS(obj);
memset(&info, 0, sizeof(info));
iic->get_fwinfo(ii, &info);
- aml_append(scope, aml_ipmi_device(&info));
+ aml_append(scope, aml_ipmi_device(&info, resource));
}
}
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 73519ab..84d82bc 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1340,7 +1340,7 @@ static void build_isa_devices_aml(Aml *table)
} else if (!obj) {
error_report("No ISA bus, unable to define IPMI ACPI data");
} else {
- build_acpi_ipmi_devices(scope, BUS(obj));
+ build_acpi_ipmi_devices(scope, BUS(obj), "\\_SB.PCI0.ISA");
}
aml_append(table, scope);
diff --git a/include/hw/acpi/ipmi.h b/include/hw/acpi/ipmi.h
index ab2bb29..d68bc85 100644
--- a/include/hw/acpi/ipmi.h
+++ b/include/hw/acpi/ipmi.h
@@ -17,6 +17,6 @@
* bus matches the given bus. The resource is the ACPI resource that
* contains the IPMI device, this is required for the I2C CRS.
*/
-void build_acpi_ipmi_devices(Aml *table, BusState *bus);
+void build_acpi_ipmi_devices(Aml *table, BusState *bus, const char *resource);
#endif /* HW_ACPI_IPMI_H */
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 13/14] i386: Rename bools in PCMachineState to end in _enabled
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (11 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 12/14] ipmi: Fix SSIF ACPI handling to use the right CRS minyard
@ 2017-12-07 21:46 ` minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 14/14] pc: Add an SMB0 ACPI device to q35 minyard
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard
From: Corey Minyard <cminyard@mvista.com>
This makes their function more clear and prevents conflicts when adding
the actual devices to the machine state, if necessary.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
hw/i386/pc.c | 18 +++++++++---------
hw/i386/pc_piix.c | 3 ++-
hw/i386/pc_q35.c | 6 +++---
include/hw/i386/pc.h | 6 +++---
4 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 186545d..51f38b8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2184,42 +2184,42 @@ static bool pc_machine_get_smbus(Object *obj, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
- return pcms->smbus;
+ return pcms->smbus_enabled;
}
static void pc_machine_set_smbus(Object *obj, bool value, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
- pcms->smbus = value;
+ pcms->smbus_enabled = value;
}
static bool pc_machine_get_sata(Object *obj, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
- return pcms->sata;
+ return pcms->sata_enabled;
}
static void pc_machine_set_sata(Object *obj, bool value, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
- pcms->sata = value;
+ pcms->sata_enabled = value;
}
static bool pc_machine_get_pit(Object *obj, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
- return pcms->pit;
+ return pcms->pit_enabled;
}
static void pc_machine_set_pit(Object *obj, bool value, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
- pcms->pit = value;
+ pcms->pit_enabled = value;
}
static void pc_machine_initfn(Object *obj)
@@ -2233,9 +2233,9 @@ static void pc_machine_initfn(Object *obj)
pcms->acpi_nvdimm_state.is_enabled = false;
/* acpi build is enabled by default if machine supports it */
pcms->acpi_build_enabled = PC_MACHINE_GET_CLASS(pcms)->has_acpi_build;
- pcms->smbus = true;
- pcms->sata = true;
- pcms->pit = true;
+ pcms->smbus_enabled = true;
+ pcms->sata_enabled = true;
+ pcms->pit_enabled = true;
}
static void pc_machine_reset(void)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 5e47528..7e87ef0 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -237,7 +237,8 @@ static void pc_init1(MachineState *machine,
/* init basic PC hardware */
pc_basic_device_init(isa_bus, pcms->gsi, &rtc_state, true,
- (pcms->vmport != ON_OFF_AUTO_ON), pcms->pit, 0x4);
+ (pcms->vmport != ON_OFF_AUTO_ON), pcms->pit_enabled,
+ 0x4);
pc_nic_init(isa_bus, pci_bus);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index d606004..6e4bf1a 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -230,13 +230,13 @@ static void pc_q35_init(MachineState *machine)
/* init basic PC hardware */
pc_basic_device_init(isa_bus, pcms->gsi, &rtc_state, !mc->no_floppy,
- (pcms->vmport != ON_OFF_AUTO_ON), pcms->pit,
+ (pcms->vmport != ON_OFF_AUTO_ON), pcms->pit_enabled,
0xff0104);
/* connect pm stuff to lpc */
ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms));
- if (pcms->sata) {
+ if (pcms->sata_enabled) {
/* ahci and SATA device, for q35 1 ahci controller is built-in */
ahci = pci_create_simple_multifunction(host_bus,
PCI_DEVFN(ICH9_SATA1_DEV,
@@ -256,7 +256,7 @@ static void pc_q35_init(MachineState *machine)
ehci_create_ich9_with_companions(host_bus, 0x1d);
}
- if (pcms->smbus) {
+ if (pcms->smbus_enabled) {
/* TODO: Populate SPD eeprom data. */
smbus_eeprom_init(ich9_smb_init(host_bus,
PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC),
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index ef438bd..713aa33 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -50,9 +50,9 @@ struct PCMachineState {
AcpiNVDIMMState acpi_nvdimm_state;
bool acpi_build_enabled;
- bool smbus;
- bool sata;
- bool pit;
+ bool smbus_enabled;
+ bool sata_enabled;
+ bool pit_enabled;
/* RAM information (sizes, addresses, configuration): */
ram_addr_t below_4g_mem_size, above_4g_mem_size;
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 14/14] pc: Add an SMB0 ACPI device to q35
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
` (12 preceding siblings ...)
2017-12-07 21:46 ` [Qemu-devel] [PATCH 13/14] i386: Rename bools in PCMachineState to end in _enabled minyard
@ 2017-12-07 21:46 ` minyard
13 siblings, 0 replies; 17+ messages in thread
From: minyard @ 2017-12-07 21:46 UTC (permalink / raw)
To: qemu-devel; +Cc: Corey Minyard
From: Corey Minyard <cminyard@mvista.com>
This is so I2C devices can be found in the ACPI namespace. Currently
that's only IPMI, but devices can be easily added now.
Adding the devices required some PCI information, and the bus itself
to be added to the PCMachineState structure.
Note that this only works on Q35, the ACPI for PIIX4 is not capable
of handling an SMBus device.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
hw/i386/acpi-build.c | 15 +++++++++++++++
hw/i386/pc_piix.c | 12 ++++++------
hw/i386/pc_q35.c | 9 +++++----
include/hw/i386/pc.h | 2 ++
tests/acpi-test-data/q35/DSDT | Bin 7828 -> 7866 bytes
tests/acpi-test-data/q35/DSDT.bridge | Bin 7845 -> 7883 bytes
tests/acpi-test-data/q35/DSDT.cphp | Bin 8291 -> 8329 bytes
tests/acpi-test-data/q35/DSDT.ipmibt | Bin 7903 -> 7941 bytes
tests/acpi-test-data/q35/DSDT.memhp | Bin 9193 -> 9231 bytes
9 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 84d82bc..9ec8268 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1859,6 +1859,18 @@ static Aml *build_q35_osc_method(void)
return method;
}
+static void build_smb0(Aml *table, I2CBus *smbus, int devnr, int func)
+{
+ Aml *scope = aml_scope("_SB.PCI0");
+ Aml *dev = aml_device("SMB0");
+
+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("APP0005")));
+ aml_append(dev, aml_name_decl("_ADR", aml_int(devnr << 16 | func)));
+ build_acpi_ipmi_devices(dev, BUS(smbus), "\\_SB.PCI0.SMB0");
+ aml_append(scope, dev);
+ aml_append(table, scope);
+}
+
static void
build_dsdt(GArray *table_data, BIOSLinker *linker,
AcpiPmInfo *pm, AcpiMiscInfo *misc,
@@ -1910,6 +1922,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
build_q35_isa_bridge(dsdt);
build_isa_devices_aml(dsdt);
build_q35_pci0_int(dsdt);
+ if (pcms->smbus && !pcmc->do_not_add_smb_acpi) {
+ build_smb0(dsdt, pcms->smbus, ICH9_SMB_DEV, ICH9_SMB_FUNC);
+ }
}
if (pcmc->legacy_cpu_hotplug) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7e87ef0..2a7ae72 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -276,15 +276,14 @@ static void pc_init1(MachineState *machine,
if (pcmc->pci_enabled && acpi_enabled) {
DeviceState *piix4_pm;
- I2CBus *smbus;
smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0);
/* TODO: Populate SPD eeprom data. */
- smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
- pcms->gsi[9], smi_irq,
- pc_machine_is_smm_enabled(pcms),
- &piix4_pm);
- smbus_eeprom_init(smbus, 8, NULL, 0);
+ pcms->smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
+ pcms->gsi[9], smi_irq,
+ pc_machine_is_smm_enabled(pcms),
+ &piix4_pm);
+ smbus_eeprom_init(pcms->smbus, 8, NULL, 0);
object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
TYPE_HOTPLUG_HANDLER,
@@ -489,6 +488,7 @@ static void pc_i440fx_2_6_machine_options(MachineClass *m)
pc_i440fx_2_7_machine_options(m);
pcmc->legacy_cpu_hotplug = true;
pcmc->linuxboot_dma_enabled = false;
+ pcmc->do_not_add_smb_acpi = true;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
}
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 6e4bf1a..0777bb3 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -258,10 +258,10 @@ static void pc_q35_init(MachineState *machine)
if (pcms->smbus_enabled) {
/* TODO: Populate SPD eeprom data. */
- smbus_eeprom_init(ich9_smb_init(host_bus,
- PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC),
- 0xb100),
- 8, NULL, 0);
+ pcms->smbus = ich9_smb_init(host_bus,
+ PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC),
+ 0xb100);
+ smbus_eeprom_init(pcms->smbus, 8, NULL, 0);
}
pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);
@@ -358,6 +358,7 @@ static void pc_q35_2_6_machine_options(MachineClass *m)
pc_q35_2_7_machine_options(m);
pcmc->legacy_cpu_hotplug = true;
pcmc->linuxboot_dma_enabled = false;
+ pcmc->do_not_add_smb_acpi = true;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
}
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 713aa33..5b19d10 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -39,6 +39,7 @@ struct PCMachineState {
HotplugHandler *acpi_dev;
ISADevice *rtc;
PCIBus *bus;
+ I2CBus *smbus;
FWCfgState *fw_cfg;
qemu_irq *gsi;
@@ -122,6 +123,7 @@ struct PCMachineClass {
bool rsdp_in_ram;
int legacy_acpi_table_size;
unsigned acpi_data_size;
+ bool do_not_add_smb_acpi;
/* SMBIOS compat: */
bool smbios_defaults;
diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT
index aa402cca667f82ed0a2dc4969508d8f6e38ad910..3d95d15cedc4727a07652b5055bb3fb6553e9521 100644
GIT binary patch
delta 62
zcmbPYyUUi#CD<iommC8FWBNueV@Xw2z4&0K_yA{5gXkv7U|%N#j(87G7aleN23C%E
RN0%TTW(IkN%{Gz|tN{Dz4qN~L
delta 24
fcmdmGJH?jECD<ioiW~z2quNF;W690QlHsfXSdIp5
diff --git a/tests/acpi-test-data/q35/DSDT.bridge b/tests/acpi-test-data/q35/DSDT.bridge
index fc3e79c583ababf5615e76ba2f7bc3df1483abb4..8d7c4dcd9dbd1f7b8c06fb20e526fca7d9e99b45 100644
GIT binary patch
delta 62
zcmZ2#d)k)ECD<k8v>XEiBl|`!V@Xw2z4&0K_yA{5gXkv7U|%N#j(87G7aleN23C%E
RN0%TTW(IkN%{G#mtN`_@4nP0^
delta 24
fcmX?YyVRD;CD<iosT>0X<FSog#*&+pB{Nt7V*LkE
diff --git a/tests/acpi-test-data/q35/DSDT.cphp b/tests/acpi-test-data/q35/DSDT.cphp
index fd3cb3421814d0383863dc780d9a2a9077b727a3..8b4c0dabb7e986a42178f40db858fd976a25d0f9 100644
GIT binary patch
delta 62
zcmaFt(CNtK66_MvsldR%_+TTKv81Z1UVN}qe1Nm3L3ER3u&<K=N4$rp3lEzB11m?o
Rqe~DEGlM+CW*bR$b^sC74x9i0
delta 24
fcmeBleC)vG66_L^tiZs)IDaFTvE=4tNi}u=T=E93
diff --git a/tests/acpi-test-data/q35/DSDT.ipmibt b/tests/acpi-test-data/q35/DSDT.ipmibt
index 332237529e114256384c051858fdac36b024c72e..c765b9fc8f8a878159f4acd89eb7e881162d9bcb 100644
GIT binary patch
delta 62
zcmca_+iJ(<66_MfD$l^c*u9afPEu7>FFx2QKET=2Ai7C1*w@K`Bi_T)g@;Xmft4fP
R(Itq7nL(ambGu{&D**Ah4tW3o
delta 24
fcmZp*yKl?o66_LkUygx+(R(9To#f_qlHsfXV=o7a
diff --git a/tests/acpi-test-data/q35/DSDT.memhp b/tests/acpi-test-data/q35/DSDT.memhp
index f0a27e1a3093ff7525f62b7509ea44dfe9eb8908..eb08477a6b90726dd7722d095d0be548d913c4ac 100644
GIT binary patch
delta 62
zcmaFq-tWQX66_Mfufo8<n6Z(|SW;D0FFx2QKET=2Ai7C1*w@K`Bi_T)g@;Xmft4fP
R(Itq7nL(amvyJ3hE&%EV4p9IA
delta 24
fcmeD8c<IjN66_N4Qkj8)QDY;QvE=4t$u(R6W2XmV
--
2.7.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 01/14] i2c:pm_smbus: Clean up some style issues
2017-12-07 21:46 ` [Qemu-devel] [PATCH 01/14] i2c:pm_smbus: Clean up some style issues minyard
@ 2018-08-17 17:24 ` Paolo Bonzini
2018-08-17 17:33 ` Corey Minyard
0 siblings, 1 reply; 17+ messages in thread
From: Paolo Bonzini @ 2018-08-17 17:24 UTC (permalink / raw)
To: minyard, qemu-devel; +Cc: Corey Minyard, Michael S . Tsirkin
On 07/12/2017 22:46, minyard@acm.org wrote:
> From: Corey Minyard <cminyard@mvista.com>
>
> Fix some spacing issues, remove extraneous comments, add some
> defines instead of hard-coding numbers.
>
> Signed-off-by: Corey Minyard <cminyard@mvista.com>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> ---
> hw/i2c/pm_smbus.c | 58 ++++++++++++++++++++++++++++++++++++-------------------
> 1 file changed, 38 insertions(+), 20 deletions(-)
Hi Corey, I just found this patch and the rest of the series. If it
still applies, could you please resend it?
Thanks,
Paolo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 01/14] i2c:pm_smbus: Clean up some style issues
2018-08-17 17:24 ` Paolo Bonzini
@ 2018-08-17 17:33 ` Corey Minyard
0 siblings, 0 replies; 17+ messages in thread
From: Corey Minyard @ 2018-08-17 17:33 UTC (permalink / raw)
To: Paolo Bonzini, minyard, qemu-devel; +Cc: Michael S . Tsirkin
On 08/17/2018 12:24 PM, Paolo Bonzini wrote:
> On 07/12/2017 22:46, minyard@acm.org wrote:
>> From: Corey Minyard <cminyard@mvista.com>
>>
>> Fix some spacing issues, remove extraneous comments, add some
>> defines instead of hard-coding numbers.
>>
>> Signed-off-by: Corey Minyard <cminyard@mvista.com>
>> Cc: Michael S. Tsirkin <mst@redhat.com>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>> hw/i2c/pm_smbus.c | 58 ++++++++++++++++++++++++++++++++++++-------------------
>> 1 file changed, 38 insertions(+), 20 deletions(-)
> Hi Corey, I just found this patch and the rest of the series. If it
> still applies, could you please resend it?
>
> Thanks,
>
> Paolo
I've been meaning to resend this and some other thing, but I've been
distracted with a lot of other things. I'll resend as soon as I can.
Is this
pressing for another reason? I can increase the priority if so.
-corey
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2018-08-17 17:35 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-07 21:46 [Qemu-devel] [PATCH 00/13] pm_smbus fixes and and IPMI SMBus device minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 01/14] i2c:pm_smbus: Clean up some style issues minyard
2018-08-17 17:24 ` Paolo Bonzini
2018-08-17 17:33 ` Corey Minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 02/14] i2c:pm_smbus: Fix the semantics of block I2C transfers minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 03/14] i2c:pm_smbus: Make the I2C block read command read-only minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 04/14] i2c:pm_smbus: Add block transfer capability minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 05/14] i2c:pm_smbus: Fix state transfer minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 06/14] i2c:pm_smbus: Add interrupt handling minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 07/14] i2c:pm_smbus: Add the ability to force block transfer enable minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 08/14] i2c: Add an SMBus vmstate structure minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 09/14] i2c: Add vmstate handling to the smbus eeprom minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 10/14] ipmi: Add an SMBus IPMI interface minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 11/14] acpi: Add i2c serial bus CRS handling minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 12/14] ipmi: Fix SSIF ACPI handling to use the right CRS minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 13/14] i386: Rename bools in PCMachineState to end in _enabled minyard
2017-12-07 21:46 ` [Qemu-devel] [PATCH 14/14] pc: Add an SMB0 ACPI device to q35 minyard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).