diff options
Diffstat (limited to 'include/hw')
-rw-r--r-- | include/hw/boards.h | 1 | ||||
-rw-r--r-- | include/hw/i2c/i2c.h | 7 | ||||
-rw-r--r-- | include/hw/i2c/pm_smbus.h | 17 | ||||
-rw-r--r-- | include/hw/i2c/smbus_eeprom.h | 35 | ||||
-rw-r--r-- | include/hw/i2c/smbus_master.h (renamed from include/hw/i2c/smbus.h) | 54 | ||||
-rw-r--r-- | include/hw/i2c/smbus_slave.h | 100 |
6 files changed, 160 insertions, 54 deletions
diff --git a/include/hw/boards.h b/include/hw/boards.h index 05f9f45c3d..21212f0859 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -206,6 +206,7 @@ struct MachineClass { void (*numa_auto_assign_ram)(MachineClass *mc, NodeInfo *nodes, int nb_nodes, ram_addr_t size); bool ignore_boot_device_suffixes; + bool smbus_no_migration_support; HotplugHandler *(*get_hotplug_handler)(MachineState *machine, DeviceState *dev); diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h index cf4c45a98f..8e236f7bb4 100644 --- a/include/hw/i2c/i2c.h +++ b/include/hw/i2c/i2c.h @@ -33,10 +33,9 @@ typedef struct I2CSlaveClass { /* * Slave to master. This cannot fail, the device should always - * return something here. Negative values probably result in 0xff - * and a possible log from the driver, and shouldn't be used. + * return something here. */ - int (*recv)(I2CSlave *s); + uint8_t (*recv)(I2CSlave *s); /* * Notify the slave of a bus state change. For start event, @@ -78,7 +77,7 @@ void i2c_end_transfer(I2CBus *bus); void i2c_nack(I2CBus *bus); int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send); int i2c_send(I2CBus *bus, uint8_t data); -int i2c_recv(I2CBus *bus); +uint8_t i2c_recv(I2CBus *bus); DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr); diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h index 060d3c6ac0..fb55c44444 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 +#include "hw/i2c/smbus_master.h" + #define PM_SMBUS_MAX_MSG_SIZE 32 typedef struct PMSMBus { @@ -31,8 +33,23 @@ typedef struct PMSMBus { /* 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; + + /* Set during an I2C block read, so we know how to handle data. */ + bool in_i2c_block_read; + + /* Used to work around a bug in AMIBIOS, see smb_transaction_start() */ + bool start_transaction_on_status_read; } PMSMBus; void pm_smbus_init(DeviceState *parent, PMSMBus *smb, bool force_aux_blk); +/* + * For backwards compatibility on migration, older versions don't have + * working migration for pm_smbus, this lets us ignore the migrations + * for older machine versions. + */ +bool pm_smbus_vmstate_needed(void); + +extern const VMStateDescription pmsmb_vmstate; + #endif /* PM_SMBUS_H */ diff --git a/include/hw/i2c/smbus_eeprom.h b/include/hw/i2c/smbus_eeprom.h new file mode 100644 index 0000000000..0f96836bab --- /dev/null +++ b/include/hw/i2c/smbus_eeprom.h @@ -0,0 +1,35 @@ +/* + * QEMU SMBus EEPROM API + * + * 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. + */ + +#ifndef HW_SMBUS_EEPROM_H +#define HW_SMBUS_EEPROM_H + +#include "hw/i2c/i2c.h" + +void smbus_eeprom_init_one(I2CBus *bus, uint8_t address, uint8_t *eeprom_buf); +void smbus_eeprom_init(I2CBus *bus, int nb_eeprom, + const uint8_t *eeprom_spd, int size); + +enum sdram_type { SDR = 0x4, DDR = 0x7, DDR2 = 0x8 }; +uint8_t *spd_data_generate(enum sdram_type type, ram_addr_t size, Error **errp); + +#endif diff --git a/include/hw/i2c/smbus.h b/include/hw/i2c/smbus_master.h index 89dfea1a08..bb13bc423c 100644 --- a/include/hw/i2c/smbus.h +++ b/include/hw/i2c/smbus_master.h @@ -1,8 +1,5 @@ -#ifndef QEMU_SMBUS_H -#define QEMU_SMBUS_H - /* - * QEMU SMBus API + * QEMU SMBus host (master) API * * Copyright (c) 2007 Arastra, Inc. * @@ -25,46 +22,10 @@ * THE SOFTWARE. */ -#include "hw/i2c/i2c.h" - -#define TYPE_SMBUS_DEVICE "smbus-device" -#define SMBUS_DEVICE(obj) \ - OBJECT_CHECK(SMBusDevice, (obj), TYPE_SMBUS_DEVICE) -#define SMBUS_DEVICE_CLASS(klass) \ - OBJECT_CLASS_CHECK(SMBusDeviceClass, (klass), TYPE_SMBUS_DEVICE) -#define SMBUS_DEVICE_GET_CLASS(obj) \ - OBJECT_GET_CLASS(SMBusDeviceClass, (obj), TYPE_SMBUS_DEVICE) - -typedef struct SMBusDevice SMBusDevice; - -typedef struct SMBusDeviceClass -{ - I2CSlaveClass parent_class; - void (*quick_cmd)(SMBusDevice *dev, uint8_t read); - void (*send_byte)(SMBusDevice *dev, uint8_t val); - uint8_t (*receive_byte)(SMBusDevice *dev); - /* We can't distinguish between a word write and a block write with - length 1, so pass the whole data block including the length byte - (if present). The device is responsible figuring out what type of - command this is. */ - void (*write_data)(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len); - /* Likewise we can't distinguish between different reads, or even know - the length of the read until the read is complete, so read data a - byte at a time. The device is responsible for adding the length - byte on block reads. */ - uint8_t (*read_data)(SMBusDevice *dev, uint8_t cmd, int n); -} SMBusDeviceClass; +#ifndef HW_SMBUS_MASTER_H +#define HW_SMBUS_MASTER_H -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. */ - uint8_t command; -}; +#include "hw/i2c/i2c.h" /* Master device commands. */ int smbus_quick_command(I2CBus *bus, uint8_t addr, int read); @@ -91,11 +52,4 @@ int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data, int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data, int len, bool send_len); -void smbus_eeprom_init_one(I2CBus *smbus, uint8_t address, uint8_t *eeprom_buf); -void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom, - const uint8_t *eeprom_spd, int size); - -enum sdram_type { SDR = 0x4, DDR = 0x7, DDR2 = 0x8 }; -uint8_t *spd_data_generate(enum sdram_type type, ram_addr_t size, Error **errp); - #endif diff --git a/include/hw/i2c/smbus_slave.h b/include/hw/i2c/smbus_slave.h new file mode 100644 index 0000000000..ebe068304e --- /dev/null +++ b/include/hw/i2c/smbus_slave.h @@ -0,0 +1,100 @@ +/* + * QEMU SMBus device (slave) API + * + * Copyright (c) 2007 Arastra, Inc. + * + * 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. + */ + +#ifndef HW_SMBUS_SLAVE_H +#define HW_SMBUS_SLAVE_H + +#include "hw/i2c/i2c.h" + +#define TYPE_SMBUS_DEVICE "smbus-device" +#define SMBUS_DEVICE(obj) \ + OBJECT_CHECK(SMBusDevice, (obj), TYPE_SMBUS_DEVICE) +#define SMBUS_DEVICE_CLASS(klass) \ + OBJECT_CLASS_CHECK(SMBusDeviceClass, (klass), TYPE_SMBUS_DEVICE) +#define SMBUS_DEVICE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(SMBusDeviceClass, (obj), TYPE_SMBUS_DEVICE) + +typedef struct SMBusDevice SMBusDevice; + +typedef struct SMBusDeviceClass +{ + I2CSlaveClass parent_class; + + /* + * An operation with no data, special in SMBus. + * This may be NULL, quick commands are ignore in that case. + */ + void (*quick_cmd)(SMBusDevice *dev, uint8_t read); + + /* + * We can't distinguish between a word write and a block write with + * length 1, so pass the whole data block including the length byte + * (if present). The device is responsible figuring out what type of + * command this is. + * This may be NULL if no data is written to the device. Writes + * will be ignore in that case. + */ + int (*write_data)(SMBusDevice *dev, uint8_t *buf, uint8_t len); + + /* + * Likewise we can't distinguish between different reads, or even know + * the length of the read until the read is complete, so read data a + * byte at a time. The device is responsible for adding the length + * byte on block reads. This call cannot fail, it should return + * something, preferably 0xff if nothing is available. + * This may be NULL if no data is read from the device. Reads will + * return 0xff in that case. + */ + uint8_t (*receive_byte)(SMBusDevice *dev); +} 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. */ + int32_t mode; + int32_t data_len; + uint8_t data_buf[SMBUS_DATA_MAX_LEN]; +}; + +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), \ +} + +/* + * Users should call this in their .needed functions to know if the + * SMBus slave data needs to be transferred. + */ +bool smbus_vmstate_needed(SMBusDevice *dev); + +#endif |