Re: [Qemu-devel] [PATCH] PIIX4 SMBus host, EEPROM device emulation

2007-01-31 Thread Thiemo Seufer
Ed Swierk wrote:
 Here's a revised patch with the mmap stuff removed. I'll refine the
 persistence support, but in the meantime the EEPROM device is usable
 even if it forgets its contents when qemu exits.

It doesn't apply for current CVS. Could you please update the patch?
I would also prefer to have enums instead of raw constants in all those
case statements.


Thiemo


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] PIIX4 SMBus host, EEPROM device emulation

2007-01-23 Thread Fabrice Bellard

Ed Swierk wrote:

The attached patch adds SMBus host support to the emulated PIIX4 power
management device (acpi.c), and adds an emulated serial EEPROM device
accessible via the SMBus interface.

I tried to follow the Intel 82371AB spec for the SMBus support; the
interface should be generic enough to implement a variety of
SMBus-compliant devices.

The EEPROM device can use a file for persistent storage
(smbus_eeprom.bin in the BIOS directory). If this file does not exist,
a temporary buffer is used instead.

I tested the devices with Linux using the i2c-piix4 host driver and
the eeprom chip driver. I have no idea what will happen on other OSes.

Comments and suggestions welcome.

 [...]

OK, but avoid using mmap() in the device code. Moreover, files in the 
BIOS directory are not writable.


Regards,

Fabrice.


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] PIIX4 SMBus host, EEPROM device emulation

2007-01-23 Thread Ed Swierk

Here's a revised patch with the mmap stuff removed. I'll refine the
persistence support, but in the meantime the EEPROM device is usable
even if it forgets its contents when qemu exits.

--Ed
Index: qemu-0.8.2/hw/acpi.c
===
--- qemu-0.8.2.orig/hw/acpi.c
+++ qemu-0.8.2/hw/acpi.c
@@ -27,6 +27,7 @@
 #define PM_IO_BASE0xb000
 #define SMI_CMD_IO_ADDR   0xb040
 #define ACPI_DBG_IO_ADDR  0xb044
+#define SMB_IO_BASE 0xb100
 
 typedef struct PIIX4PMState {
 PCIDevice dev;
@@ -35,6 +36,15 @@ typedef struct PIIX4PMState {
 uint16_t pmcntrl;
 QEMUTimer *tmr_timer;
 int64_t tmr_overflow_time;
+SMBusDevice *smb_dev[128];
+uint8_t smb_stat;
+uint8_t smb_ctl;
+uint8_t smb_cmd;
+uint8_t smb_addr;
+uint8_t smb_data0;
+uint8_t smb_data1;
+uint8_t smb_data[32];
+uint8_t smb_index;
 } PIIX4PMState;
 
 #define RTC_EN (1  10)
@@ -46,8 +56,6 @@ typedef struct PIIX4PMState {
 
 #define SUS_EN (1  13)
 
-/* Note: only used for ACPI bios init. Could be deleted when ACPI init
-   is integrated in Bochs BIOS */
 static PIIX4PMState *piix4_pm_state;
 
 static uint32_t get_pmtmr(PIIX4PMState *s)
@@ -218,13 +226,163 @@ static void acpi_dbg_writel(void *opaque
 #endif
 }
 
+static void smb_transaction(PIIX4PMState *s)
+{
+uint8_t prot = (s-smb_ctl  2)  0x07;
+uint8_t read = s-smb_addr  0x01;
+uint8_t cmd = s-smb_cmd;
+uint8_t addr = s-smb_addr  1;
+SMBusDevice *dev = s-smb_dev[addr];
+
+#ifdef DEBUG
+printf(SMBus trans addr=0x%02x prot=0x%02x\n, addr, prot);
+#endif
+if (!dev) goto error;
+
+switch(prot) {
+case 0x0:
+if (!dev-quick_cmd) goto error;
+(*dev-quick_cmd)(dev, read);
+break;
+case 0x1:
+if (read) {
+if (!dev-receive_byte) goto error;
+s-smb_data0 = (*dev-receive_byte)(dev);
+}
+else {
+if (!dev-send_byte) goto error;
+(*dev-send_byte)(dev, cmd);
+}
+break;
+case 0x2:
+if (read) {
+if (!dev-read_byte) goto error;
+s-smb_data0 = (*dev-read_byte)(dev, cmd);
+}
+else {
+if (!dev-write_byte) goto error;
+(*dev-write_byte)(dev, cmd, s-smb_data0);
+}
+break;
+case 0x3:
+if (read) {
+uint16_t val;
+if (!dev-read_word) goto error;
+val = (*dev-read_word)(dev, cmd);
+s-smb_data0 = val;
+s-smb_data1 = val  8;
+}
+else {
+if (!dev-write_word) goto error;
+(*dev-write_word)(dev, cmd, (s-smb_data1  8) | s-smb_data0);
+}
+break;
+case 0x5:
+if (read) {
+if (!dev-read_block) goto error;
+s-smb_data0 = (*dev-read_block)(dev, cmd, s-smb_data);
+}
+else {
+if (!dev-write_block) goto error;
+(*dev-write_block)(dev, cmd, s-smb_data0, s-smb_data);
+}
+break;
+default:
+goto error;
+}
+return;
+
+  error:
+s-smb_stat |= 0x04;
+}
+
+static void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+PIIX4PMState *s = opaque;
+addr = 0x3f;
+#ifdef DEBUG
+printf(SMB writeb port=0x%04x val=0x%02x\n, addr, val);
+#endif
+switch(addr) {
+case 0x00: /* SMBHSTSTS */
+s-smb_stat = 0;
+s-smb_index = 0;
+break;
+case 0x02: /* SMBHSTCNT */
+s-smb_ctl = val;
+if (val  0x40)
+smb_transaction(s);
+break;
+case 0x03: /* SMBHSTCMD */
+s-smb_cmd = val;
+break;
+case 0x04: /* SMBHSTADD */
+s-smb_addr = val;
+break;
+case 0x05: /* SMBHSTDAT0 */
+s-smb_data0 = val;
+break;
+case 0x06: /* SMBHSTDAT1 */
+s-smb_data1 = val;
+break;
+case 0x07: /* SMBBLKDAT */
+s-smb_data[s-smb_index++] = val;
+if (s-smb_index  31)
+s-smb_index = 0;
+break;
+default:
+break;
+}
+}
+
+static uint32_t smb_ioport_readb(void *opaque, uint32_t addr)
+{
+PIIX4PMState *s = opaque;
+uint32_t val;
+
+addr = 0x3f;
+switch(addr) {
+case 0x00: /* SMBHSTSTS */
+val = s-smb_stat;
+break;
+case 0x02: /* SMBHSTCNT */
+s-smb_index = 0;
+val = s-smb_ctl  0x1f;
+break;
+case 0x03: /* SMBHSTCMD */
+val = s-smb_cmd;
+break;
+case 0x04: /* SMBHSTADD */
+val = s-smb_addr;
+break;
+case 0x05: /* SMBHSTDAT0 */
+val = s-smb_data0;
+break;
+case 0x06: /* SMBHSTDAT1 */
+val = s-smb_data1;
+break;
+case 0x07: /* SMBBLKDAT */
+val = s-smb_data[s-smb_index++];
+if (s-smb_index  31)
+s-smb_index = 0;
+break;
+default:
+val = 0;
+break;
+}
+#ifdef DEBUG
+printf(SMB readb port=0x%04x