提交 0d2fa03d 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180608' into staging

target-arm queue:
 * arm_gicv3_kvm: fix migration of registers corresponding to
   IRQs 992 to 1020 in the KVM GIC
 * aspeed: remove ignore_memory_transaction_failures on all boards
 * aspeed: add support for the witherspoon-bmc board
 * aspeed: add an I2C RTC device and EEPROM I2C devices
 * aspeed: add the pc9552 chips to the witherspoon machine
 * ftgmac100: fix various bugs
 * hw/arm: Remove the deprecated xlnx-ep108 machine
 * hw/i2c: Add trace events
 * add missing '\n' on various qemu_log() logging strings
 * sdcard: clean up spec version support so we report the
   right spec version to the guest and only implement the
   commands that are supposed to be present in that version

# gpg: Signature made Fri 08 Jun 2018 13:36:37 BST
# gpg:                using RSA key 3C2525ED14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>"
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20180608: (31 commits)
  sdcard: Disable CMD19/CMD23 for Spec v2
  sdcard: Reflect when the Spec v3 is supported in the Config Register (SCR)
  sdcard: Disable SEND_IF_COND (CMD8) for Spec v1
  sdcard: Add a 'spec_version' property, default to Spec v2.00
  sdcard: Allow commands valid in SPI mode
  sdcard: Update the Configuration Register (SCR) to Spec Version 1.10
  target/xtensa: Add trailing '\n' to qemu_log() calls
  RISC-V: Add trailing '\n' to qemu_log() calls
  target/m68k: Add trailing '\n' to qemu_log() call
  target/arm: Add trailing '\n' to qemu_log() calls
  stellaris: Add trailing '\n' to qemu_log() calls
  hw/mips/boston: Add trailing '\n' to qemu_log() calls
  hw/core/register: Add trailing '\n' to qemu_log() call
  ppc/pnv: Add trailing '\n' to qemu_log() calls
  xilinx-dp: Add trailing '\n' to qemu_log() call
  hw/digic: Add trailing '\n' to qemu_log() calls
  hw/sd/milkymist-memcard: Add trailing '\n' to qemu_log() call
  hw/i2c: Add trace events
  hw/arm: Remove the deprecated xlnx-ep108 machine
  ftgmac100: remove check on runt messages
  ...
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -213,6 +213,7 @@ trace-events-subdirs += hw/char
trace-events-subdirs += hw/display
trace-events-subdirs += hw/dma
trace-events-subdirs += hw/hppa
trace-events-subdirs += hw/i2c
trace-events-subdirs += hw/i386
trace-events-subdirs += hw/i386/xen
trace-events-subdirs += hw/ide
......
......@@ -16,6 +16,7 @@ CONFIG_TSC2005=y
CONFIG_LM832X=y
CONFIG_TMP105=y
CONFIG_TMP421=y
CONFIG_PCA9552=y
CONFIG_STELLARIS=y
CONFIG_STELLARIS_INPUT=y
CONFIG_STELLARIS_ENET=y
......
......@@ -17,6 +17,7 @@
#include "hw/arm/arm.h"
#include "hw/arm/aspeed_soc.h"
#include "hw/boards.h"
#include "hw/i2c/smbus.h"
#include "qemu/log.h"
#include "sysemu/block-backend.h"
#include "hw/loader.h"
......@@ -45,6 +46,7 @@ enum {
PALMETTO_BMC,
AST2500_EVB,
ROMULUS_BMC,
WITHERSPOON_BMC,
};
/* Palmetto hardware value: 0x120CE416 */
......@@ -82,8 +84,13 @@ enum {
SCU_AST2500_HW_STRAP_ACPI_ENABLE | \
SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
/* Witherspoon hardware value: 0xF10AD216 (but use romulus definition) */
#define WITHERSPOON_BMC_HW_STRAP1 ROMULUS_BMC_HW_STRAP1
static void palmetto_bmc_i2c_init(AspeedBoardState *bmc);
static void ast2500_evb_i2c_init(AspeedBoardState *bmc);
static void romulus_bmc_i2c_init(AspeedBoardState *bmc);
static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc);
static const AspeedBoardConfig aspeed_boards[] = {
[PALMETTO_BMC] = {
......@@ -108,6 +115,15 @@ static const AspeedBoardConfig aspeed_boards[] = {
.fmc_model = "n25q256a",
.spi_model = "mx66l1g45g",
.num_cs = 2,
.i2c_init = romulus_bmc_i2c_init,
},
[WITHERSPOON_BMC] = {
.soc_name = "ast2500-a1",
.hw_strap1 = WITHERSPOON_BMC_HW_STRAP1,
.fmc_model = "mx25l25635e",
.spi_model = "mx66l1g45g",
.num_cs = 2,
.i2c_init = witherspoon_bmc_i2c_init,
},
};
......@@ -248,11 +264,15 @@ static void palmetto_bmc_i2c_init(AspeedBoardState *bmc)
{
AspeedSoCState *soc = &bmc->soc;
DeviceState *dev;
uint8_t *eeprom_buf = g_malloc0(32 * 1024);
/* The palmetto platform expects a ds3231 RTC but a ds1338 is
* enough to provide basic RTC features. Alarms will be missing */
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 0), "ds1338", 0x68);
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 0), 0x50,
eeprom_buf);
/* add a TMP423 temperature sensor */
dev = i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 2),
"tmp423", 0x4c);
......@@ -278,7 +298,6 @@ static void palmetto_bmc_class_init(ObjectClass *oc, void *data)
mc->no_floppy = 1;
mc->no_cdrom = 1;
mc->no_parallel = 1;
mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo palmetto_bmc_type = {
......@@ -290,9 +309,17 @@ static const TypeInfo palmetto_bmc_type = {
static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
{
AspeedSoCState *soc = &bmc->soc;
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), 0x50,
eeprom_buf);
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
* plugged on the I2C bus header */
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32);
}
static void ast2500_evb_init(MachineState *machine)
......@@ -311,7 +338,6 @@ static void ast2500_evb_class_init(ObjectClass *oc, void *data)
mc->no_floppy = 1;
mc->no_cdrom = 1;
mc->no_parallel = 1;
mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo ast2500_evb_type = {
......@@ -320,6 +346,15 @@ static const TypeInfo ast2500_evb_type = {
.class_init = ast2500_evb_class_init,
};
static void romulus_bmc_i2c_init(AspeedBoardState *bmc)
{
AspeedSoCState *soc = &bmc->soc;
/* The romulus board expects Epson RX8900 I2C RTC but a ds1338 is
* good enough */
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32);
}
static void romulus_bmc_init(MachineState *machine)
{
aspeed_board_init(machine, &aspeed_boards[ROMULUS_BMC]);
......@@ -336,7 +371,6 @@ static void romulus_bmc_class_init(ObjectClass *oc, void *data)
mc->no_floppy = 1;
mc->no_cdrom = 1;
mc->no_parallel = 1;
mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo romulus_bmc_type = {
......@@ -345,11 +379,59 @@ static const TypeInfo romulus_bmc_type = {
.class_init = romulus_bmc_class_init,
};
static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
{
AspeedSoCState *soc = &bmc->soc;
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
* good enough */
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32);
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
eeprom_buf);
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
0x60);
}
static void witherspoon_bmc_init(MachineState *machine)
{
aspeed_board_init(machine, &aspeed_boards[WITHERSPOON_BMC]);
}
static void witherspoon_bmc_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)";
mc->init = witherspoon_bmc_init;
mc->max_cpus = 1;
mc->no_sdcard = 1;
mc->no_floppy = 1;
mc->no_cdrom = 1;
mc->no_parallel = 1;
}
static const TypeInfo witherspoon_bmc_type = {
.name = MACHINE_TYPE_NAME("witherspoon-bmc"),
.parent = TYPE_MACHINE,
.class_init = witherspoon_bmc_class_init,
};
static void aspeed_machine_init(void)
{
type_register_static(&palmetto_bmc_type);
type_register_static(&ast2500_evb_type);
type_register_static(&romulus_bmc_type);
type_register_static(&witherspoon_bmc_type);
}
type_init(aspeed_machine_init)
......@@ -203,11 +203,11 @@ static uint64_t gptm_read(void *opaque, hwaddr offset,
return s->rtc;
}
qemu_log_mask(LOG_UNIMP,
"GPTM: read of TAR but timer read not supported");
"GPTM: read of TAR but timer read not supported\n");
return 0;
case 0x4c: /* TBR */
qemu_log_mask(LOG_UNIMP,
"GPTM: read of TBR but timer read not supported");
"GPTM: read of TBR but timer read not supported\n");
return 0;
default:
qemu_log_mask(LOG_GUEST_ERROR,
......@@ -836,11 +836,12 @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
break;
case 0x20: /* MCR */
if (value & 1) {
qemu_log_mask(LOG_UNIMP, "stellaris_i2c: Loopback not implemented");
qemu_log_mask(LOG_UNIMP,
"stellaris_i2c: Loopback not implemented\n");
}
if (value & 0x20) {
qemu_log_mask(LOG_UNIMP,
"stellaris_i2c: Slave mode not implemented");
"stellaris_i2c: Slave mode not implemented\n");
}
s->mcr = value & 0x31;
break;
......@@ -1124,7 +1125,7 @@ static void stellaris_adc_write(void *opaque, hwaddr offset,
s->sspri = value;
break;
case 0x28: /* PSSI */
qemu_log_mask(LOG_UNIMP, "ADC: sample initiate unimplemented");
qemu_log_mask(LOG_UNIMP, "ADC: sample initiate unimplemented\n");
break;
case 0x30: /* SAC */
s->sac = value;
......
......@@ -39,10 +39,6 @@ typedef struct XlnxZCU102 {
#define ZCU102_MACHINE(obj) \
OBJECT_CHECK(XlnxZCU102, (obj), TYPE_ZCU102_MACHINE)
#define TYPE_EP108_MACHINE MACHINE_TYPE_NAME("xlnx-ep108")
#define EP108_MACHINE(obj) \
OBJECT_CHECK(XlnxZCU102, (obj), TYPE_EP108_MACHINE)
static struct arm_boot_info xlnx_zcu102_binfo;
static bool zcu102_get_secure(Object *obj, Error **errp)
......@@ -73,8 +69,9 @@ static void zcu102_set_virt(Object *obj, bool value, Error **errp)
s->virt = value;
}
static void xlnx_zynqmp_init(XlnxZCU102 *s, MachineState *machine)
static void xlnx_zcu102_init(MachineState *machine)
{
XlnxZCU102 *s = ZCU102_MACHINE(machine);
int i;
uint64_t ram_size = machine->ram_size;
......@@ -183,60 +180,6 @@ static void xlnx_zynqmp_init(XlnxZCU102 *s, MachineState *machine)
arm_load_kernel(s->soc.boot_cpu_ptr, &xlnx_zcu102_binfo);
}
static void xlnx_ep108_init(MachineState *machine)
{
XlnxZCU102 *s = EP108_MACHINE(machine);
if (!qtest_enabled()) {
info_report("The Xilinx EP108 machine is deprecated, please use the "
"ZCU102 machine (which has the same features) instead.");
}
xlnx_zynqmp_init(s, machine);
}
static void xlnx_ep108_machine_instance_init(Object *obj)
{
XlnxZCU102 *s = EP108_MACHINE(obj);
/* EP108, we don't support setting secure or virt */
s->secure = false;
s->virt = false;
}
static void xlnx_ep108_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
mc->desc = "Xilinx ZynqMP EP108 board (Deprecated, please use xlnx-zcu102)";
mc->init = xlnx_ep108_init;
mc->block_default_type = IF_IDE;
mc->units_per_default_bus = 1;
mc->ignore_memory_transaction_failures = true;
mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS;
mc->default_cpus = XLNX_ZYNQMP_NUM_APU_CPUS;
}
static const TypeInfo xlnx_ep108_machine_init_typeinfo = {
.name = MACHINE_TYPE_NAME("xlnx-ep108"),
.parent = TYPE_MACHINE,
.class_init = xlnx_ep108_machine_class_init,
.instance_init = xlnx_ep108_machine_instance_init,
.instance_size = sizeof(XlnxZCU102),
};
static void xlnx_ep108_machine_init_register_types(void)
{
type_register_static(&xlnx_ep108_machine_init_typeinfo);
}
static void xlnx_zcu102_init(MachineState *machine)
{
XlnxZCU102 *s = ZCU102_MACHINE(machine);
xlnx_zynqmp_init(s, machine);
}
static void xlnx_zcu102_machine_instance_init(Object *obj)
{
XlnxZCU102 *s = ZCU102_MACHINE(obj);
......@@ -289,4 +232,3 @@ static void xlnx_zcu102_machine_init_register_types(void)
}
type_init(xlnx_zcu102_machine_init_register_types)
type_init(xlnx_ep108_machine_init_register_types)
......@@ -60,7 +60,7 @@ static uint64_t digic_uart_read(void *opaque, hwaddr addr,
default:
qemu_log_mask(LOG_UNIMP,
"digic-uart: read access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
TARGET_FMT_plx "\n", addr << 2);
}
return ret;
......@@ -98,7 +98,7 @@ static void digic_uart_write(void *opaque, hwaddr addr, uint64_t value,
default:
qemu_log_mask(LOG_UNIMP,
"digic-uart: write access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
TARGET_FMT_plx "\n", addr << 2);
}
}
......
......@@ -96,7 +96,7 @@ void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
if (test) {
qemu_log_mask(LOG_UNIMP,
"%s:%s writing %#" PRIx64 " to unimplemented bits:" \
" %#" PRIx64 "",
" %#" PRIx64 "\n",
prefix, reg->access->name, val, ac->unimp);
}
......
......@@ -1074,7 +1074,9 @@ static void xlnx_dp_avbufm_write(void *opaque, hwaddr offset, uint64_t value,
case AV_BUF_STC_SNAPSHOT1:
case AV_BUF_HCOUNT_VCOUNT_INT0:
case AV_BUF_HCOUNT_VCOUNT_INT1:
qemu_log_mask(LOG_UNIMP, "avbufm: unimplmented");
qemu_log_mask(LOG_UNIMP, "avbufm: unimplemented register 0x%04"
PRIx64 "\n",
offset << 2);
break;
default:
s->avbufm_registers[offset] = value;
......
......@@ -9,6 +9,7 @@
#include "qemu/osdep.h"
#include "hw/i2c/i2c.h"
#include "trace.h"
#define I2C_BROADCAST 0x00
......@@ -130,14 +131,16 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
}
QLIST_FOREACH(node, &bus->current_devs, next) {
I2CSlave *s = node->elt;
int rv;
sc = I2C_SLAVE_GET_CLASS(node->elt);
sc = I2C_SLAVE_GET_CLASS(s);
/* If the bus is already busy, assume this is a repeated
start condition. */
if (sc->event) {
rv = sc->event(node->elt, recv ? I2C_START_RECV : I2C_START_SEND);
trace_i2c_event("start", s->address);
rv = sc->event(s, recv ? I2C_START_RECV : I2C_START_SEND);
if (rv && !bus->broadcast) {
if (bus_scanned) {
/* First call, terminate the transfer. */
......@@ -156,9 +159,11 @@ void i2c_end_transfer(I2CBus *bus)
I2CNode *node, *next;
QLIST_FOREACH_SAFE(node, &bus->current_devs, next, next) {
sc = I2C_SLAVE_GET_CLASS(node->elt);
I2CSlave *s = node->elt;
sc = I2C_SLAVE_GET_CLASS(s);
if (sc->event) {
sc->event(node->elt, I2C_FINISH);
trace_i2c_event("finish", s->address);
sc->event(s, I2C_FINISH);
}
QLIST_REMOVE(node, next);
g_free(node);
......@@ -169,14 +174,17 @@ void i2c_end_transfer(I2CBus *bus)
int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send)
{
I2CSlaveClass *sc;
I2CSlave *s;
I2CNode *node;
int ret = 0;
if (send) {
QLIST_FOREACH(node, &bus->current_devs, next) {
sc = I2C_SLAVE_GET_CLASS(node->elt);
s = node->elt;
sc = I2C_SLAVE_GET_CLASS(s);
if (sc->send) {
ret = ret || sc->send(node->elt, *data);
trace_i2c_send(s->address, *data);
ret = ret || sc->send(s, *data);
} else {
ret = -1;
}
......@@ -189,7 +197,9 @@ int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send)
sc = I2C_SLAVE_GET_CLASS(QLIST_FIRST(&bus->current_devs)->elt);
if (sc->recv) {
ret = sc->recv(QLIST_FIRST(&bus->current_devs)->elt);
s = QLIST_FIRST(&bus->current_devs)->elt;
ret = sc->recv(s);
trace_i2c_recv(s->address, ret);
if (ret < 0) {
return ret;
} else {
......@@ -226,6 +236,7 @@ void i2c_nack(I2CBus *bus)
QLIST_FOREACH(node, &bus->current_devs, next) {
sc = I2C_SLAVE_GET_CLASS(node->elt);
if (sc->event) {
trace_i2c_event("nack", node->elt->address);
sc->event(node->elt, I2C_NACK);
}
}
......
......@@ -139,6 +139,16 @@ static void smbus_eeprom_register_types(void)
type_init(smbus_eeprom_register_types)
void smbus_eeprom_init_one(I2CBus *smbus, uint8_t address, uint8_t *eeprom_buf)
{
DeviceState *dev;
dev = qdev_create((BusState *) smbus, "smbus-eeprom");
qdev_prop_set_uint8(dev, "address", address);
qdev_prop_set_ptr(dev, "data", eeprom_buf);
qdev_init_nofail(dev);
}
void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
const uint8_t *eeprom_spd, int eeprom_spd_size)
{
......@@ -149,10 +159,6 @@ void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
}
for (i = 0; i < nb_eeprom; i++) {
DeviceState *eeprom;
eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
qdev_init_nofail(eeprom);
smbus_eeprom_init_one(smbus, 0x50 + i, eeprom_buf + (i * 256));
}
}
# See docs/devel/tracing.txt for syntax documentation.
# hw/i2c/core.c
i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
......@@ -27,6 +27,7 @@
#include "hw/intc/arm_gicv3_common.h"
#include "gicv3_internal.h"
#include "hw/arm/linux-boot-if.h"
#include "sysemu/kvm.h"
static int gicv3_pre_save(void *opaque)
{
......@@ -141,6 +142,79 @@ static const VMStateDescription vmstate_gicv3_cpu = {
}
};
static int gicv3_gicd_no_migration_shift_bug_pre_load(void *opaque)
{
GICv3State *cs = opaque;
/*
* The gicd_no_migration_shift_bug flag is used for migration compatibility
* for old version QEMU which may have the GICD bmp shift bug under KVM mode.
* Strictly, what we want to know is whether the migration source is using
* KVM. Since we don't have any way to determine that, we look at whether the
* destination is using KVM; this is close enough because for the older QEMU
* versions with this bug KVM -> TCG migration didn't work anyway. If the
* source is a newer QEMU without this bug it will transmit the migration
* subsection which sets the flag to true; otherwise it will remain set to
* the value we select here.
*/
if (kvm_enabled()) {
cs->gicd_no_migration_shift_bug = false;
}
return 0;
}
static int gicv3_gicd_no_migration_shift_bug_post_load(void *opaque,
int version_id)
{
GICv3State *cs = opaque;
if (cs->gicd_no_migration_shift_bug) {
return 0;
}
/* Older versions of QEMU had a bug in the handling of state save/restore
* to the KVM GICv3: they got the offset in the bitmap arrays wrong,
* so that instead of the data for external interrupts 32 and up
* starting at bit position 32 in the bitmap, it started at bit
* position 64. If we're receiving data from a QEMU with that bug,
* we must move the data down into the right place.
*/
memmove(cs->group, (uint8_t *)cs->group + GIC_INTERNAL / 8,
sizeof(cs->group) - GIC_INTERNAL / 8);
memmove(cs->grpmod, (uint8_t *)cs->grpmod + GIC_INTERNAL / 8,
sizeof(cs->grpmod) - GIC_INTERNAL / 8);
memmove(cs->enabled, (uint8_t *)cs->enabled + GIC_INTERNAL / 8,
sizeof(cs->enabled) - GIC_INTERNAL / 8);
memmove(cs->pending, (uint8_t *)cs->pending + GIC_INTERNAL / 8,
sizeof(cs->pending) - GIC_INTERNAL / 8);
memmove(cs->active, (uint8_t *)cs->active + GIC_INTERNAL / 8,
sizeof(cs->active) - GIC_INTERNAL / 8);
memmove(cs->edge_trigger, (uint8_t *)cs->edge_trigger + GIC_INTERNAL / 8,
sizeof(cs->edge_trigger) - GIC_INTERNAL / 8);
/*
* While this new version QEMU doesn't have this kind of bug as we fix it,
* so it needs to set the flag to true to indicate that and it's necessary
* for next migration to work from this new version QEMU.
*/
cs->gicd_no_migration_shift_bug = true;
return 0;
}
const VMStateDescription vmstate_gicv3_gicd_no_migration_shift_bug = {
.name = "arm_gicv3/gicd_no_migration_shift_bug",
.version_id = 1,
.minimum_version_id = 1,
.pre_load = gicv3_gicd_no_migration_shift_bug_pre_load,
.post_load = gicv3_gicd_no_migration_shift_bug_post_load,
.fields = (VMStateField[]) {
VMSTATE_BOOL(gicd_no_migration_shift_bug, GICv3State),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_gicv3 = {
.name = "arm_gicv3",
.version_id = 1,
......@@ -165,6 +239,10 @@ static const VMStateDescription vmstate_gicv3 = {
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, GICv3State, num_cpu,
vmstate_gicv3_cpu, GICv3CPUState),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * []) {
&vmstate_gicv3_gicd_no_migration_shift_bug,
NULL
}
};
......@@ -364,6 +442,7 @@ static void arm_gicv3_common_reset(DeviceState *dev)
gicv3_gicd_group_set(s, i);
}
}
s->gicd_no_migration_shift_bug = true;
}
static void arm_gic_common_linux_init(ARMLinuxBootIf *obj,
......
......@@ -164,6 +164,14 @@ static void kvm_dist_get_edge_trigger(GICv3State *s, uint32_t offset,
uint32_t reg;
int irq;
/* For the KVM GICv3, affinity routing is always enabled, and the first 2
* GICD_ICFGR<n> registers are always RAZ/WI. The corresponding
* functionality is replaced by GICR_ICFGR<n>. It doesn't need to sync
* them. So it should increase the offset to skip GIC_INTERNAL irqs.
* This matches the for_each_dist_irq_reg() macro which also skips the
* first GIC_INTERNAL irqs.
*/
offset += (GIC_INTERNAL * 2) / 8;
for_each_dist_irq_reg(irq, s->num_irq, 2) {
kvm_gicd_access(s, offset, &reg, false);
reg = half_unshuffle32(reg >> 1);
......@@ -181,6 +189,14 @@ static void kvm_dist_put_edge_trigger(GICv3State *s, uint32_t offset,
uint32_t reg;
int irq;
/* For the KVM GICv3, affinity routing is always enabled, and the first 2
* GICD_ICFGR<n> registers are always RAZ/WI. The corresponding
* functionality is replaced by GICR_ICFGR<n>. It doesn't need to sync
* them. So it should increase the offset to skip GIC_INTERNAL irqs.
* This matches the for_each_dist_irq_reg() macro which also skips the
* first GIC_INTERNAL irqs.
*/
offset += (GIC_INTERNAL * 2) / 8;
for_each_dist_irq_reg(irq, s->num_irq, 2) {
reg = *gic_bmp_ptr32(bmp, irq);
if (irq % 32 != 0) {
......@@ -222,6 +238,15 @@ static void kvm_dist_getbmp(GICv3State *s, uint32_t offset, uint32_t *bmp)
uint32_t reg;
int irq;
/* For the KVM GICv3, affinity routing is always enabled, and the
* GICD_IGROUPR0/GICD_IGRPMODR0/GICD_ISENABLER0/GICD_ISPENDR0/
* GICD_ISACTIVER0 registers are always RAZ/WI. The corresponding
* functionality is replaced by the GICR registers. It doesn't need to sync
* them. So it should increase the offset to skip GIC_INTERNAL irqs.
* This matches the for_each_dist_irq_reg() macro which also skips the
* first GIC_INTERNAL irqs.
*/
offset += (GIC_INTERNAL * 1) / 8;
for_each_dist_irq_reg(irq, s->num_irq, 1) {
kvm_gicd_access(s, offset, &reg, false);
*gic_bmp_ptr32(bmp, irq) = reg;
......@@ -235,6 +260,19 @@ static void kvm_dist_putbmp(GICv3State *s, uint32_t offset,
uint32_t reg;
int irq;
/* For the KVM GICv3, affinity routing is always enabled, and the
* GICD_IGROUPR0/GICD_IGRPMODR0/GICD_ISENABLER0/GICD_ISPENDR0/
* GICD_ISACTIVER0 registers are always RAZ/WI. The corresponding
* functionality is replaced by the GICR registers. It doesn't need to sync
* them. So it should increase the offset and clroffset to skip GIC_INTERNAL
* irqs. This matches the for_each_dist_irq_reg() macro which also skips the
* first GIC_INTERNAL irqs.
*/
offset += (GIC_INTERNAL * 1) / 8;
if (clroffset != 0) {
clroffset += (GIC_INTERNAL * 1) / 8;
}
for_each_dist_irq_reg(irq, s->num_irq, 1) {
/* If this bitmap is a set/clear register pair, first write to the
* clear-reg to clear all bits before using the set-reg to write
......
......@@ -176,7 +176,7 @@ static uint64_t boston_platreg_read(void *opaque, hwaddr addr,
uint32_t gic_freq, val;
if (size != 4) {
qemu_log_mask(LOG_UNIMP, "%uB platform register read", size);
qemu_log_mask(LOG_UNIMP, "%uB platform register read\n", size);
return 0;
}
......@@ -205,7 +205,7 @@ static uint64_t boston_platreg_read(void *opaque, hwaddr addr,
val |= PLAT_DDR_CFG_MHZ;
return val;
default:
qemu_log_mask(LOG_UNIMP, "Read platform register 0x%" HWADDR_PRIx,
qemu_log_mask(LOG_UNIMP, "Read platform register 0x%" HWADDR_PRIx "\n",
addr & 0xffff);
return 0;
}
......@@ -215,7 +215,7 @@ static void boston_platreg_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
if (size != 4) {
qemu_log_mask(LOG_UNIMP, "%uB platform register write", size);
qemu_log_mask(LOG_UNIMP, "%uB platform register write\n", size);
return;
}
......@@ -237,7 +237,7 @@ static void boston_platreg_write(void *opaque, hwaddr addr,
break;
default:
qemu_log_mask(LOG_UNIMP, "Write platform register 0x%" HWADDR_PRIx
" = 0x%" PRIx64, addr & 0xffff, val);
" = 0x%" PRIx64 "\n", addr & 0xffff, val);
break;
}
}
......
......@@ -7,6 +7,7 @@ common-obj-$(CONFIG_SGA) += sga.o
common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
common-obj-$(CONFIG_EDU) += edu.o
common-obj-$(CONFIG_PCA9552) += pca9552.o
common-obj-y += unimp.o
common-obj-$(CONFIG_FW_CFG_DMA) += vmcoreinfo.o
......
/*
* PCA9552 I2C LED blinker
*
* https://www.nxp.com/docs/en/application-note/AN264.pdf
*
* Copyright (c) 2017-2018, IBM Corporation.
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/hw.h"
#include "hw/misc/pca9552.h"
#include "hw/misc/pca9552_regs.h"
#define PCA9552_LED_ON 0x0
#define PCA9552_LED_OFF 0x1
#define PCA9552_LED_PWM0 0x2
#define PCA9552_LED_PWM1 0x3
static uint8_t pca9552_pin_get_config(PCA9552State *s, int pin)
{
uint8_t reg = PCA9552_LS0 + (pin / 4);
uint8_t shift = (pin % 4) << 1;
return extract32(s->regs[reg], shift, 2);
}
static void pca9552_update_pin_input(PCA9552State *s)
{
int i;
for (i = 0; i < s->nr_leds; i++) {
uint8_t input_reg = PCA9552_INPUT0 + (i / 8);
uint8_t input_shift = (i % 8);
uint8_t config = pca9552_pin_get_config(s, i);
switch (config) {
case PCA9552_LED_ON:
s->regs[input_reg] |= 1 << input_shift;
break;
case PCA9552_LED_OFF:
s->regs[input_reg] &= ~(1 << input_shift);
break;
case PCA9552_LED_PWM0:
case PCA9552_LED_PWM1:
/* TODO */
default:
break;
}
}
}
static uint8_t pca9552_read(PCA9552State *s, uint8_t reg)
{
switch (reg) {
case PCA9552_INPUT0:
case PCA9552_INPUT1:
case PCA9552_PSC0:
case PCA9552_PWM0:
case PCA9552_PSC1:
case PCA9552_PWM1:
case PCA9552_LS0:
case PCA9552_LS1:
case PCA9552_LS2:
case PCA9552_LS3:
return s->regs[reg];
default:
qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected read to register %d\n",
__func__, reg);
return 0xFF;
}
}
static void pca9552_write(PCA9552State *s, uint8_t reg, uint8_t data)
{
switch (reg) {
case PCA9552_PSC0:
case PCA9552_PWM0:
case PCA9552_PSC1:
case PCA9552_PWM1:
s->regs[reg] = data;
break;
case PCA9552_LS0:
case PCA9552_LS1:
case PCA9552_LS2:
case PCA9552_LS3:
s->regs[reg] = data;
pca9552_update_pin_input(s);
break;
case PCA9552_INPUT0:
case PCA9552_INPUT1:
default:
qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected write to register %d\n",
__func__, reg);
}
}
/*
* When Auto-Increment is on, the register address is incremented
* after each byte is sent to or received by the device. The index
* rollovers to 0 when the maximum register address is reached.
*/
static void pca9552_autoinc(PCA9552State *s)
{
if (s->pointer != 0xFF && s->pointer & PCA9552_AUTOINC) {
uint8_t reg = s->pointer & 0xf;
reg = (reg + 1) % (s->max_reg + 1);
s->pointer = reg | PCA9552_AUTOINC;
}
}
static int pca9552_recv(I2CSlave *i2c)
{
PCA9552State *s = PCA9552(i2c);
uint8_t ret;
ret = pca9552_read(s, s->pointer & 0xf);
/*
* From the Specs:
*
* Important Note: When a Read sequence is initiated and the
* AI bit is set to Logic Level 1, the Read Sequence MUST
* start by a register different from 0.
*
* I don't know what should be done in this case, so throw an
* error.
*/
if (s->pointer == PCA9552_AUTOINC) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Autoincrement read starting with register 0\n",
__func__);
}
pca9552_autoinc(s);
return ret;
}
static int pca9552_send(I2CSlave *i2c, uint8_t data)
{
PCA9552State *s = PCA9552(i2c);
/* First byte sent by is the register address */
if (s->len == 0) {
s->pointer = data;
s->len++;
} else {
pca9552_write(s, s->pointer & 0xf, data);
pca9552_autoinc(s);
}
return 0;
}
static int pca9552_event(I2CSlave *i2c, enum i2c_event event)
{
PCA9552State *s = PCA9552(i2c);
s->len = 0;
return 0;
}
static const VMStateDescription pca9552_vmstate = {
.name = "PCA9552",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT8(len, PCA9552State),
VMSTATE_UINT8(pointer, PCA9552State),
VMSTATE_UINT8_ARRAY(regs, PCA9552State, PCA9552_NR_REGS),
VMSTATE_I2C_SLAVE(i2c, PCA9552State),
VMSTATE_END_OF_LIST()
}
};
static void pca9552_reset(DeviceState *dev)
{
PCA9552State *s = PCA9552(dev);
s->regs[PCA9552_PSC0] = 0xFF;
s->regs[PCA9552_PWM0] = 0x80;
s->regs[PCA9552_PSC1] = 0xFF;
s->regs[PCA9552_PWM1] = 0x80;
s->regs[PCA9552_LS0] = 0x55; /* all OFF */
s->regs[PCA9552_LS1] = 0x55;
s->regs[PCA9552_LS2] = 0x55;
s->regs[PCA9552_LS3] = 0x55;
pca9552_update_pin_input(s);
s->pointer = 0xFF;
s->len = 0;
}
static void pca9552_initfn(Object *obj)
{
PCA9552State *s = PCA9552(obj);
/* If support for the other PCA955X devices are implemented, these
* constant values might be part of class structure describing the
* PCA955X device
*/
s->max_reg = PCA9552_LS3;
s->nr_leds = 16;
}
static void pca9552_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
k->event = pca9552_event;
k->recv = pca9552_recv;
k->send = pca9552_send;
dc->reset = pca9552_reset;
dc->vmsd = &pca9552_vmstate;
}
static const TypeInfo pca9552_info = {
.name = TYPE_PCA9552,
.parent = TYPE_I2C_SLAVE,
.instance_init = pca9552_initfn,
.instance_size = sizeof(PCA9552State),
.class_init = pca9552_class_init,
};
static void pca9552_register_types(void)
{
type_register_static(&pca9552_info);
}
type_init(pca9552_register_types)
......@@ -207,16 +207,18 @@ typedef struct {
/*
* Max frame size for the receiving buffer
*/
#define FTGMAC100_MAX_FRAME_SIZE 10240
#define FTGMAC100_MAX_FRAME_SIZE 9220
/* Limits depending on the type of the frame
*
* 9216 for Jumbo frames (+ 4 for VLAN)
* 1518 for other frames (+ 4 for VLAN)
*/
static int ftgmac100_max_frame_size(FTGMAC100State *s)
static int ftgmac100_max_frame_size(FTGMAC100State *s, uint16_t proto)
{
return (s->maccr & FTGMAC100_MACCR_JUMBO_LF ? 9216 : 1518) + 4;
int max = (s->maccr & FTGMAC100_MACCR_JUMBO_LF ? 9216 : 1518);
return max + (proto == ETH_P_VLAN ? 4 : 0);
}
static void ftgmac100_update_irq(FTGMAC100State *s)
......@@ -408,7 +410,6 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
uint8_t *ptr = s->frame;
uint32_t addr = tx_descriptor;
uint32_t flags = 0;
int max_frame_size = ftgmac100_max_frame_size(s);
while (1) {
FTGMAC100Desc bd;
......@@ -427,11 +428,12 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
flags = bd.des1;
}
len = bd.des0 & 0x3FFF;
if (frame_size + len > max_frame_size) {
len = FTGMAC100_TXDES0_TXBUF_SIZE(bd.des0);
if (frame_size + len > sizeof(s->frame)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: frame too big : %d bytes\n",
__func__, len);
len = max_frame_size - frame_size;
s->isr |= FTGMAC100_INT_XPKT_LOST;
len = sizeof(s->frame) - frame_size;
}
if (dma_memory_read(&address_space_memory, bd.des3, ptr, len)) {
......@@ -441,6 +443,22 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
break;
}
/* Check for VLAN */
if (bd.des0 & FTGMAC100_TXDES0_FTS &&
bd.des1 & FTGMAC100_TXDES1_INS_VLANTAG &&
be16_to_cpu(PKT_GET_ETH_HDR(ptr)->h_proto) != ETH_P_VLAN) {
if (frame_size + len + 4 > sizeof(s->frame)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: frame too big : %d bytes\n",
__func__, len);
s->isr |= FTGMAC100_INT_XPKT_LOST;
len = sizeof(s->frame) - frame_size - 4;
}
memmove(ptr + 16, ptr + 12, len - 12);
stw_be_p(ptr + 12, ETH_P_VLAN);
stw_be_p(ptr + 14, bd.des1);
len += 4;
}
ptr += len;
frame_size += len;
if (bd.des0 & FTGMAC100_TXDES0_LTS) {
......@@ -758,8 +776,8 @@ static int ftgmac100_filter(FTGMAC100State *s, const uint8_t *buf, size_t len)
return 0;
}
/* TODO: this does not seem to work for ftgmac100 */
mcast_idx = net_crc32(buf, ETH_ALEN) >> 26;
mcast_idx = net_crc32_le(buf, ETH_ALEN);
mcast_idx = (~(mcast_idx >> 2)) & 0x3f;
if (!(s->math[mcast_idx / 32] & (1 << (mcast_idx % 32)))) {
return 0;
}
......@@ -788,7 +806,8 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf,
uint32_t buf_len;
size_t size = len;
uint32_t first = FTGMAC100_RXDES0_FRS;
int max_frame_size = ftgmac100_max_frame_size(s);
uint16_t proto = be16_to_cpu(PKT_GET_ETH_HDR(buf)->h_proto);
int max_frame_size = ftgmac100_max_frame_size(s, proto);
if ((s->maccr & (FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_RXMAC_EN))
!= (FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_RXMAC_EN)) {
......@@ -803,12 +822,6 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf,
return size;
}
if (size < 64 && !(s->maccr & FTGMAC100_MACCR_RX_RUNT)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: dropped runt frame of %zd bytes\n",
__func__, size);
return size;
}
if (!ftgmac100_filter(s, buf, size)) {
return size;
}
......@@ -820,9 +833,9 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf,
/* Huge frames are truncated. */
if (size > max_frame_size) {
size = max_frame_size;
qemu_log_mask(LOG_GUEST_ERROR, "%s: frame too big : %zd bytes\n",
__func__, size);
size = max_frame_size;
flags |= FTGMAC100_RXDES0_FTL;
}
......@@ -861,7 +874,20 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf,
buf_len += size - 4;
}
buf_addr = bd.des3;
dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
if (first && proto == ETH_P_VLAN && buf_len >= 18) {
bd.des1 = lduw_be_p(buf + 14) | FTGMAC100_RXDES1_VLANTAG_AVAIL;
if (s->maccr & FTGMAC100_MACCR_RM_VLAN) {
dma_memory_write(&address_space_memory, buf_addr, buf, 12);
dma_memory_write(&address_space_memory, buf_addr + 12, buf + 16,
buf_len - 16);
} else {
dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
}
} else {
bd.des1 = 0;
dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
}
buf += buf_len;
if (size < 4) {
dma_memory_write(&address_space_memory, buf_addr + buf_len,
......@@ -940,8 +966,6 @@ static void ftgmac100_realize(DeviceState *dev, Error **errp)
object_get_typename(OBJECT(dev)), DEVICE(dev)->id,
s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
s->frame = g_malloc(FTGMAC100_MAX_FRAME_SIZE);
}
static const VMStateDescription vmstate_ftgmac100 = {
......
......@@ -97,7 +97,7 @@ static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
val = 0x24f000000000000ull;
break;
default:
qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx,
qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n",
addr);
}
......@@ -107,7 +107,7 @@ static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
static void pnv_core_xscom_write(void *opaque, hwaddr addr, uint64_t val,
unsigned int width)
{
qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx,
qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
addr);
}
......
......@@ -140,7 +140,7 @@ static uint64_t memcard_read(void *opaque, hwaddr addr,
r = s->response[s->response_read_ptr++];
if (s->response_read_ptr > s->response_len) {
qemu_log_mask(LOG_GUEST_ERROR, "milkymist_memcard: "
"read more cmd bytes than available. Clipping.");
"read more cmd bytes than available: clipping\n");
s->response_read_ptr = 0;
}
}
......
/*
* SD Memory Card emulation as defined in the "SD Memory Card Physical
* layer specification, Version 1.10."
* layer specification, Version 2.00."
*
* Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
* Copyright (c) 2007 CodeSourcery
* Copyright (c) 2018 Philippe Mathieu-Daudé <f4bug@amsat.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -91,6 +92,7 @@ struct SDState {
uint8_t sd_status[64];
/* Configurable properties */
uint8_t spec_version;
BlockBackend *blk;
bool spi;
......@@ -310,11 +312,18 @@ static void sd_ocr_powerup(void *opaque)
static void sd_set_scr(SDState *sd)
{
sd->scr[0] = (0 << 4) /* SCR version 1.0 */
| 0; /* Spec Versions 1.0 and 1.01 */
sd->scr[0] = 0 << 4; /* SCR structure version 1.0 */
if (sd->spec_version == SD_PHY_SPECv1_10_VERS) {
sd->scr[0] |= 1; /* Spec Version 1.10 */
} else {
sd->scr[0] |= 2; /* Spec Version 2.00 or Version 3.0X */
}
sd->scr[1] = (2 << 4) /* SDSC Card (Security Version 1.01) */
| 0b0101; /* 1-bit or 4-bit width bus modes */
sd->scr[2] = 0x00; /* Extended Security is not supported. */
if (sd->spec_version >= SD_PHY_SPECv3_01_VERS) {
sd->scr[2] |= 1 << 7; /* Spec Version 3.0X */
}
sd->scr[3] = 0x00;
/* reserved for manufacturer usage */
sd->scr[4] = 0x00;
......@@ -960,8 +969,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
return sd_illegal;
case 6: /* CMD6: SWITCH_FUNCTION */
if (sd->spi)
goto bad_cmd;
switch (sd->mode) {
case sd_data_transfer_mode:
sd_function_switch(sd, req.arg);
......@@ -1014,7 +1021,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
case 8: /* CMD8: SEND_IF_COND */
/* Physical Layer Specification Version 2.00 command */
if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
break;
}
if (sd->state != sd_idle_state) {
break;
}
......@@ -1170,6 +1179,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */
if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
break;
}
if (sd->state == sd_transfer_state) {
sd->state = sd_sendingdata_state;
sd->data_offset = 0;
......@@ -1178,6 +1190,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
case 23: /* CMD23: SET_BLOCK_COUNT */
if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
break;
}
switch (sd->state) {
case sd_transfer_state:
sd->multi_blk_cnt = req.arg;
......@@ -1190,9 +1205,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
/* Block write commands (Class 4) */
case 24: /* CMD24: WRITE_SINGLE_BLOCK */
if (sd->spi) {
goto unimplemented_spi_cmd;
}
switch (sd->state) {
case sd_transfer_state:
/* Writing in SPI mode not implemented. */
......@@ -1217,9 +1229,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */
if (sd->spi) {
goto unimplemented_spi_cmd;
}
switch (sd->state) {
case sd_transfer_state:
/* Writing in SPI mode not implemented. */
......@@ -1259,9 +1268,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
case 27: /* CMD27: PROGRAM_CSD */
if (sd->spi) {
goto unimplemented_spi_cmd;
}
switch (sd->state) {
case sd_transfer_state:
sd->state = sd_receivingdata_state;
......@@ -1371,9 +1377,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
/* Lock card commands (Class 7) */
case 42: /* CMD42: LOCK_UNLOCK */
if (sd->spi) {
goto unimplemented_spi_cmd;
}
switch (sd->state) {
case sd_transfer_state:
sd->state = sd_receivingdata_state;
......@@ -2072,6 +2075,15 @@ static void sd_realize(DeviceState *dev, Error **errp)
sd->proto_name = sd->spi ? "SPI" : "SD";
switch (sd->spec_version) {
case SD_PHY_SPECv1_10_VERS
... SD_PHY_SPECv3_01_VERS:
break;
default:
error_setg(errp, "Invalid SD card Spec version: %u", sd->spec_version);
return;
}
if (sd->blk && blk_is_read_only(sd->blk)) {
error_setg(errp, "Cannot use read-only drive as SD card");
return;
......@@ -2088,6 +2100,8 @@ static void sd_realize(DeviceState *dev, Error **errp)
}
static Property sd_properties[] = {
DEFINE_PROP_UINT8("spec_version", SDState,
spec_version, SD_PHY_SPECv2_00_VERS),
DEFINE_PROP_DRIVE("drive", SDState, blk),
/* We do not model the chip select pin, so allow the board to select
* whether card should be in SSI or MMC/SD mode. It is also up to the
......
......@@ -73,7 +73,7 @@ static uint64_t digic_timer_read(void *opaque, hwaddr offset, unsigned size)
default:
qemu_log_mask(LOG_UNIMP,
"digic-timer: read access to unknown register 0x"
TARGET_FMT_plx, offset);
TARGET_FMT_plx "\n", offset);
}
return ret;
......@@ -109,7 +109,7 @@ static void digic_timer_write(void *opaque, hwaddr offset,
default:
qemu_log_mask(LOG_UNIMP,
"digic-timer: read access to unknown register 0x"
TARGET_FMT_plx, offset);
TARGET_FMT_plx "\n", offset);
}
}
......
......@@ -76,6 +76,7 @@ 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);
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);
......
......@@ -217,6 +217,7 @@ struct GICv3State {
uint32_t revision;
bool security_extn;
bool irq_reset_nonsecure;
bool gicd_no_migration_shift_bug;
int dev_fd; /* kvm device fd if backed by kvm vgic support */
Error *migration_blocker;
......
/*
* PCA9552 I2C LED blinker
*
* Copyright (c) 2017-2018, IBM Corporation.
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory.
*/
#ifndef PCA9552_H
#define PCA9552_H
#include "hw/i2c/i2c.h"
#define TYPE_PCA9552 "pca9552"
#define PCA9552(obj) OBJECT_CHECK(PCA9552State, (obj), TYPE_PCA9552)
#define PCA9552_NR_REGS 10
typedef struct PCA9552State {
/*< private >*/
I2CSlave i2c;
/*< public >*/
uint8_t len;
uint8_t pointer;
uint8_t regs[PCA9552_NR_REGS];
uint8_t max_reg;
uint8_t nr_leds;
} PCA9552State;
#endif
/*
* PCA9552 I2C LED blinker registers
*
* Copyright (c) 2017-2018, IBM Corporation.
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory.
*/
#ifndef PCA9552_REGS_H
#define PCA9552_REGS_H
/*
* Bits [0:3] are used to address a specific register.
*/
#define PCA9552_INPUT0 0 /* read only input register 0 */
#define PCA9552_INPUT1 1 /* read only input register 1 */
#define PCA9552_PSC0 2 /* read/write frequency prescaler 0 */
#define PCA9552_PWM0 3 /* read/write PWM register 0 */
#define PCA9552_PSC1 4 /* read/write frequency prescaler 1 */
#define PCA9552_PWM1 5 /* read/write PWM register 1 */
#define PCA9552_LS0 6 /* read/write LED0 to LED3 selector */
#define PCA9552_LS1 7 /* read/write LED4 to LED7 selector */
#define PCA9552_LS2 8 /* read/write LED8 to LED11 selector */
#define PCA9552_LS3 9 /* read/write LED12 to LED15 selector */
/*
* Bit [4] is used to activate the Auto-Increment option of the
* register address
*/
#define PCA9552_AUTOINC (1 << 4)
#endif
......@@ -16,6 +16,11 @@
#include "hw/sysbus.h"
#include "net/net.h"
/*
* Max frame size for the receiving buffer
*/
#define FTGMAC100_MAX_FRAME_SIZE 9220
typedef struct FTGMAC100State {
/*< private >*/
SysBusDevice parent_obj;
......@@ -26,7 +31,7 @@ typedef struct FTGMAC100State {
qemu_irq irq;
MemoryRegion iomem;
uint8_t *frame;
uint8_t frame[FTGMAC100_MAX_FRAME_SIZE];
uint32_t irq_state;
uint32_t isr;
......
......@@ -54,6 +54,12 @@
#define APP_CMD (1 << 5)
#define AKE_SEQ_ERROR (1 << 3)
enum SDPhySpecificationVersion {
SD_PHY_SPECv1_10_VERS = 1,
SD_PHY_SPECv2_00_VERS = 2,
SD_PHY_SPECv3_01_VERS = 3,
};
typedef enum {
SD_VOLTAGE_0_4V = 400, /* currently not supported */
SD_VOLTAGE_1_8V = 1800,
......
......@@ -2965,11 +2965,6 @@ support page sizes < 4096 any longer.
@section System emulator machines
@subsection Xilinx EP108 (since 2.11.0)
The ``xlnx-ep108'' machine has been replaced by the ``xlnx-zcu102'' machine.
The ``xlnx-zcu102'' machine has the same features and capabilites in QEMU.
@section Block device options
@subsection "backing": "" (since 2.12.0)
......
......@@ -4570,7 +4570,7 @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
case 4: /* unlinked address mismatch (reserved if AArch64) */
case 5: /* linked address mismatch (reserved if AArch64) */
qemu_log_mask(LOG_UNIMP,
"arm: address mismatch breakpoint types not implemented");
"arm: address mismatch breakpoint types not implemented\n");
return;
case 0: /* unlinked address match */
case 1: /* linked address match */
......@@ -4604,7 +4604,7 @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
case 8: /* unlinked VMID match (reserved if no EL2) */
case 10: /* unlinked context ID and VMID match (reserved if no EL2) */
qemu_log_mask(LOG_UNIMP,
"arm: unlinked context breakpoint types not implemented");
"arm: unlinked context breakpoint types not implemented\n");
return;
case 9: /* linked VMID match (reserved if no EL2) */
case 11: /* linked context ID and VMID match (reserved if no EL2) */
......
......@@ -1556,7 +1556,7 @@ DISAS_INSN(undef)
/* ??? This is both instructions that are as yet unimplemented
for the 680x0 series, as well as those that are implemented
but actually illegal for CPU32 or pre-68020. */
qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %08x",
qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %08x\n",
insn, s->insn_pc);
gen_exception(s, s->insn_pc, EXCP_UNSUPPORTED);
}
......
......@@ -293,7 +293,8 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
if ((val_to_write & 3) == 0) {
env->stvec = val_to_write >> 2 << 2;
} else {
qemu_log_mask(LOG_UNIMP, "CSR_STVEC: vectored traps not supported");
qemu_log_mask(LOG_UNIMP,
"CSR_STVEC: vectored traps not supported\n");
}
break;
case CSR_SCOUNTEREN:
......@@ -320,7 +321,8 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
if ((val_to_write & 3) == 0) {
env->mtvec = val_to_write >> 2 << 2;
} else {
qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: vectored traps not supported");
qemu_log_mask(LOG_UNIMP,
"CSR_MTVEC: vectored traps not supported\n");
}
break;
case CSR_MCOUNTEREN:
......
......@@ -2234,7 +2234,7 @@ static void translate_rur(DisasContext *dc, const uint32_t arg[],
if (uregnames[par[0]].name) {
tcg_gen_mov_i32(cpu_R[arg[0]], cpu_UR[par[0]]);
} else {
qemu_log_mask(LOG_UNIMP, "RUR %d not implemented, ", par[0]);
qemu_log_mask(LOG_UNIMP, "RUR %d not implemented\n", par[0]);
}
}
}
......@@ -2375,7 +2375,7 @@ static void translate_slli(DisasContext *dc, const uint32_t arg[],
{
if (gen_window_check2(dc, arg[0], arg[1])) {
if (arg[2] == 32) {
qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined",
qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n",
arg[0], arg[1]);
}
tcg_gen_shli_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2] & 0x1f);
......@@ -2571,7 +2571,7 @@ static void translate_wur(DisasContext *dc, const uint32_t arg[],
if (uregnames[par[0]].name) {
gen_wur(par[0], cpu_R[arg[0]]);
} else {
qemu_log_mask(LOG_UNIMP, "WUR %d not implemented, ", par[0]);
qemu_log_mask(LOG_UNIMP, "WUR %d not implemented\n", par[0]);
}
}
}
......
......@@ -373,6 +373,7 @@ check-qtest-sparc64-y += tests/prom-env-test$(EXESUF)
check-qtest-sparc64-y += tests/boot-serial-test$(EXESUF)
check-qtest-arm-y = tests/tmp105-test$(EXESUF)
check-qtest-arm-y += tests/pca9552-test$(EXESUF)
check-qtest-arm-y += tests/ds1338-test$(EXESUF)
check-qtest-arm-y += tests/m25p80-test$(EXESUF)
gcov-files-arm-y += hw/misc/tmp105.c
......@@ -778,6 +779,7 @@ tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \
tests/boot-sector.o tests/acpi-utils.o $(libqos-obj-y)
tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y)
tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
tests/pca9552-test$(EXESUF): tests/pca9552-test.o $(libqos-omap-obj-y)
tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
tests/m25p80-test$(EXESUF): tests/m25p80-test.o
tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
......
......@@ -21,6 +21,8 @@ struct I2CAdapter {
QTestState *qts;
};
#define OMAP2_I2C_1_BASE 0x48070000
void i2c_send(I2CAdapter *i2c, uint8_t addr,
const uint8_t *buf, uint16_t len);
void i2c_recv(I2CAdapter *i2c, uint8_t addr,
......
/*
* QTest testcase for the PCA9552 LED blinker
*
* Copyright (c) 2017-2018, IBM Corporation.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "libqtest.h"
#include "libqos/i2c.h"
#include "hw/misc/pca9552_regs.h"
#define PCA9552_TEST_ID "pca9552-test"
#define PCA9552_TEST_ADDR 0x60
static I2CAdapter *i2c;
static uint8_t pca9552_get8(I2CAdapter *i2c, uint8_t addr, uint8_t reg)
{
uint8_t resp[1];
i2c_send(i2c, addr, &reg, 1);
i2c_recv(i2c, addr, resp, 1);
return resp[0];
}
static void pca9552_set8(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
uint8_t value)
{
uint8_t cmd[2];
uint8_t resp[1];
cmd[0] = reg;
cmd[1] = value;
i2c_send(i2c, addr, cmd, 2);
i2c_recv(i2c, addr, resp, 1);
g_assert_cmphex(resp[0], ==, cmd[1]);
}
static void receive_autoinc(void)
{
uint8_t resp;
uint8_t reg = PCA9552_LS0 | PCA9552_AUTOINC;
i2c_send(i2c, PCA9552_TEST_ADDR, &reg, 1);
/* PCA9552_LS0 */
i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1);
g_assert_cmphex(resp, ==, 0x54);
/* PCA9552_LS1 */
i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1);
g_assert_cmphex(resp, ==, 0x55);
/* PCA9552_LS2 */
i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1);
g_assert_cmphex(resp, ==, 0x55);
/* PCA9552_LS3 */
i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1);
g_assert_cmphex(resp, ==, 0x54);
}
static void send_and_receive(void)
{
uint8_t value;
value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_LS0);
g_assert_cmphex(value, ==, 0x55);
value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_INPUT0);
g_assert_cmphex(value, ==, 0x0);
/* Switch on LED 0 */
pca9552_set8(i2c, PCA9552_TEST_ADDR, PCA9552_LS0, 0x54);
value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_LS0);
g_assert_cmphex(value, ==, 0x54);
value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_INPUT0);
g_assert_cmphex(value, ==, 0x01);
/* Switch on LED 12 */
pca9552_set8(i2c, PCA9552_TEST_ADDR, PCA9552_LS3, 0x54);
value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_LS3);
g_assert_cmphex(value, ==, 0x54);
value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_INPUT1);
g_assert_cmphex(value, ==, 0x10);
}
int main(int argc, char **argv)
{
QTestState *s = NULL;
int ret;
g_test_init(&argc, &argv, NULL);
s = qtest_start("-machine n800 "
"-device pca9552,bus=i2c-bus.0,id=" PCA9552_TEST_ID
",address=0x60");
i2c = omap_i2c_create(s, OMAP2_I2C_1_BASE);
qtest_add_func("/pca9552/tx-rx", send_and_receive);
qtest_add_func("/pca9552/rx-autoinc", receive_autoinc);
ret = g_test_run();
if (s) {
qtest_quit(s);
}
g_free(i2c);
return ret;
}
......@@ -14,8 +14,6 @@
#include "qapi/qmp/qdict.h"
#include "hw/misc/tmp105_regs.h"
#define OMAP2_I2C_1_BASE 0x48070000
#define TMP105_TEST_ID "tmp105-test"
#define TMP105_TEST_ADDR 0x49
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册