summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/Kconfig1
-rw-r--r--hw/block/nand.c1
-rw-r--r--hw/core/register.c4
-rw-r--r--hw/display/ads7846.c2
-rw-r--r--hw/display/ssd0323.c1
-rw-r--r--hw/input/ps2.c9
-rw-r--r--hw/misc/max111x.c1
-rw-r--r--hw/misc/tmp105.c73
-rw-r--r--hw/misc/tmp105.h7
-rw-r--r--hw/scsi/scsi-disk.c19
-rw-r--r--hw/sd/sd.c15
-rw-r--r--hw/timer/exynos4210_mct.c4
-rw-r--r--hw/timer/exynos4210_pwm.c8
-rw-r--r--hw/virtio/vhost-user.c5
14 files changed, 115 insertions, 35 deletions
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 7d022eeefd..e69a9009cf 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -6,6 +6,7 @@ config ARM_VIRT
imply VFIO_PLATFORM
imply VFIO_XGMAC
imply TPM_TIS_SYSBUS
+ select ARM_GIC
select ACPI
select ARM_SMMUV3
select GPIO_KEY
diff --git a/hw/block/nand.c b/hw/block/nand.c
index bcceb64ebb..1d7a48a2ec 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -449,6 +449,7 @@ static void nand_class_init(ObjectClass *klass, void *data)
dc->reset = nand_reset;
dc->vmsd = &vmstate_nand;
device_class_set_props(dc, nand_properties);
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo nand_info = {
diff --git a/hw/core/register.c b/hw/core/register.c
index 31038bd7cc..3600ef5bde 100644
--- a/hw/core/register.c
+++ b/hw/core/register.c
@@ -258,10 +258,6 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
int index = rae[i].addr / data_size;
RegisterInfo *r = &ri[index];
- if (data + data_size * index == 0 || !&rae[i]) {
- continue;
- }
-
/* Init the register, this will zero it. */
object_initialize((void *)r, sizeof(*r), TYPE_REGISTER);
diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c
index 023165b2a3..cb3a431cfd 100644
--- a/hw/display/ads7846.c
+++ b/hw/display/ads7846.c
@@ -163,10 +163,12 @@ static void ads7846_realize(SSISlave *d, Error **errp)
static void ads7846_class_init(ObjectClass *klass, void *data)
{
+ DeviceClass *dc = DEVICE_CLASS(klass);
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->realize = ads7846_realize;
k->transfer = ads7846_transfer;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo ads7846_info = {
diff --git a/hw/display/ssd0323.c b/hw/display/ssd0323.c
index 17d4b32ae3..cbfd21dfd5 100644
--- a/hw/display/ssd0323.c
+++ b/hw/display/ssd0323.c
@@ -370,6 +370,7 @@ static void ssd0323_class_init(ObjectClass *klass, void *data)
k->transfer = ssd0323_transfer;
k->cs_polarity = SSI_CS_HIGH;
dc->vmsd = &vmstate_ssd0323;
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
}
static const TypeInfo ssd0323_info = {
diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index f8746d2f52..72cdb80ae1 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -33,12 +33,6 @@
#include "trace.h"
-/* debug PC keyboard */
-//#define DEBUG_KBD
-
-/* debug PC keyboard : only mouse */
-//#define DEBUG_MOUSE
-
/* Keyboard Commands */
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
#define KBD_CMD_ECHO 0xEE
@@ -790,9 +784,6 @@ void ps2_write_mouse(void *opaque, int val)
PS2MouseState *s = (PS2MouseState *)opaque;
trace_ps2_write_mouse(opaque, val);
-#ifdef DEBUG_MOUSE
- printf("kbd: write mouse 0x%02x\n", val);
-#endif
switch(s->common.write_cmd) {
default:
case -1:
diff --git a/hw/misc/max111x.c b/hw/misc/max111x.c
index 7e6723f343..eae0f9b598 100644
--- a/hw/misc/max111x.c
+++ b/hw/misc/max111x.c
@@ -185,6 +185,7 @@ static void max111x_class_init(ObjectClass *klass, void *data)
k->transfer = max111x_transfer;
dc->reset = max111x_reset;
dc->vmsd = &vmstate_max111x;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo max111x_info = {
diff --git a/hw/misc/tmp105.c b/hw/misc/tmp105.c
index b47120492a..d299d9b21b 100644
--- a/hw/misc/tmp105.c
+++ b/hw/misc/tmp105.c
@@ -41,16 +41,40 @@ static void tmp105_alarm_update(TMP105State *s)
return;
}
- if ((s->config >> 1) & 1) { /* TM */
- if (s->temperature >= s->limit[1])
- s->alarm = 1;
- else if (s->temperature < s->limit[0])
- s->alarm = 1;
+ if (s->config >> 1 & 1) {
+ /*
+ * TM == 1 : Interrupt mode. We signal Alert when the
+ * temperature rises above T_high, and expect the guest to clear
+ * it (eg by reading a device register).
+ */
+ if (s->detect_falling) {
+ if (s->temperature < s->limit[0]) {
+ s->alarm = 1;
+ s->detect_falling = false;
+ }
+ } else {
+ if (s->temperature >= s->limit[1]) {
+ s->alarm = 1;
+ s->detect_falling = true;
+ }
+ }
} else {
- if (s->temperature >= s->limit[1])
- s->alarm = 1;
- else if (s->temperature < s->limit[0])
- s->alarm = 0;
+ /*
+ * TM == 0 : Comparator mode. We signal Alert when the temperature
+ * rises above T_high, and stop signalling it when the temperature
+ * falls below T_low.
+ */
+ if (s->detect_falling) {
+ if (s->temperature < s->limit[0]) {
+ s->alarm = 0;
+ s->detect_falling = false;
+ }
+ } else {
+ if (s->temperature >= s->limit[1]) {
+ s->alarm = 1;
+ s->detect_falling = true;
+ }
+ }
}
tmp105_interrupt_update(s);
@@ -197,6 +221,29 @@ static int tmp105_post_load(void *opaque, int version_id)
return 0;
}
+static bool detect_falling_needed(void *opaque)
+{
+ TMP105State *s = opaque;
+
+ /*
+ * We only need to migrate the detect_falling bool if it's set;
+ * for migration from older machines we assume that it is false
+ * (ie temperature is not out of range).
+ */
+ return s->detect_falling;
+}
+
+static const VMStateDescription vmstate_tmp105_detect_falling = {
+ .name = "TMP105/detect-falling",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = detect_falling_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_BOOL(detect_falling, TMP105State),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_tmp105 = {
.name = "TMP105",
.version_id = 0,
@@ -212,6 +259,10 @@ static const VMStateDescription vmstate_tmp105 = {
VMSTATE_UINT8(alarm, TMP105State),
VMSTATE_I2C_SLAVE(i2c, TMP105State),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (const VMStateDescription*[]) {
+ &vmstate_tmp105_detect_falling,
+ NULL
}
};
@@ -224,6 +275,10 @@ static void tmp105_reset(I2CSlave *i2c)
s->config = 0;
s->faults = tmp105_faultq[(s->config >> 3) & 3];
s->alarm = 0;
+ s->detect_falling = false;
+
+ s->limit[0] = 0x4b00; /* T_LOW, 75 degrees C */
+ s->limit[1] = 0x5000; /* T_HIGH, 80 degrees C */
tmp105_interrupt_update(s);
}
diff --git a/hw/misc/tmp105.h b/hw/misc/tmp105.h
index e5198fce80..7c97071ad7 100644
--- a/hw/misc/tmp105.h
+++ b/hw/misc/tmp105.h
@@ -43,6 +43,13 @@ struct TMP105State {
int16_t limit[2];
int faults;
uint8_t alarm;
+ /*
+ * The TMP105 initially looks for a temperature rising above T_high;
+ * once this is detected, the condition it looks for next is the
+ * temperature falling below T_low. This flag is false when initially
+ * looking for T_high, true when looking for T_low.
+ */
+ bool detect_falling;
};
#endif
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index e859534eaf..90841ad791 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -461,6 +461,25 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed)
}
error = scsi_sense_buf_to_errno(r->req.sense, sizeof(r->req.sense));
break;
+#ifdef CONFIG_LINUX
+ /* These errno mapping are specific to Linux. For more information:
+ * - scsi_decide_disposition in drivers/scsi/scsi_error.c
+ * - scsi_result_to_blk_status in drivers/scsi/scsi_lib.c
+ * - blk_errors[] in block/blk-core.c
+ */
+ case EBADE:
+ /* DID_NEXUS_FAILURE -> BLK_STS_NEXUS. */
+ scsi_req_complete(&r->req, RESERVATION_CONFLICT);
+ break;
+ case ENODATA:
+ /* DID_MEDIUM_ERROR -> BLK_STS_MEDIUM. */
+ scsi_check_condition(r, SENSE_CODE(READ_ERROR));
+ break;
+ case EREMOTEIO:
+ /* DID_TARGET_FAILURE -> BLK_STS_TARGET. */
+ scsi_req_complete(&r->req, HARDWARE_ERROR);
+ break;
+#endif
case ENOMEDIUM:
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
break;
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 3091382614..1842c03797 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -389,10 +389,17 @@ static const uint8_t sd_csd_rw_mask[16] = {
static void sd_set_csd(SDState *sd, uint64_t size)
{
- uint32_t csize = (size >> (CMULT_SHIFT + HWBLOCK_SHIFT)) - 1;
+ int hwblock_shift = HWBLOCK_SHIFT;
+ uint32_t csize;
uint32_t sectsize = (1 << (SECTOR_SHIFT + 1)) - 1;
uint32_t wpsize = (1 << (WPGROUP_SHIFT + 1)) - 1;
+ /* To indicate 2 GiB card, BLOCK_LEN shall be 1024 bytes */
+ if (size == SDSC_MAX_CAPACITY) {
+ hwblock_shift += 1;
+ }
+ csize = (size >> (CMULT_SHIFT + hwblock_shift)) - 1;
+
if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
sd->csd[0] = 0x00; /* CSD structure */
sd->csd[1] = 0x26; /* Data read access-time-1 */
@@ -400,7 +407,7 @@ static void sd_set_csd(SDState *sd, uint64_t size)
sd->csd[3] = 0x32; /* Max. data transfer rate: 25 MHz */
sd->csd[4] = 0x5f; /* Card Command Classes */
sd->csd[5] = 0x50 | /* Max. read data block length */
- HWBLOCK_SHIFT;
+ hwblock_shift;
sd->csd[6] = 0xe0 | /* Partial block for read allowed */
((csize >> 10) & 0x03);
sd->csd[7] = 0x00 | /* Device size */
@@ -414,9 +421,9 @@ static void sd_set_csd(SDState *sd, uint64_t size)
sd->csd[11] = 0x00 | /* Write protect group size */
((sectsize << 7) & 0x80) | wpsize;
sd->csd[12] = 0x90 | /* Write speed factor */
- (HWBLOCK_SHIFT >> 2);
+ (hwblock_shift >> 2);
sd->csd[13] = 0x20 | /* Max. write data block length */
- ((HWBLOCK_SHIFT << 6) & 0xc0);
+ ((hwblock_shift << 6) & 0xc0);
sd->csd[14] = 0x00; /* File format group */
} else { /* SDHC */
size /= 512 * KiB;
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
index 08ee3ca76c..439053acd2 100644
--- a/hw/timer/exynos4210_mct.c
+++ b/hw/timer/exynos4210_mct.c
@@ -537,7 +537,7 @@ static void exynos4210_gcomp_raise_irq(void *opaque, uint32_t id)
/* If CSTAT is pending and IRQ is enabled */
if ((s->reg.int_cstat & G_INT_CSTAT_COMP(id)) &&
(s->reg.int_enb & G_INT_ENABLE(id))) {
- DPRINTF("gcmp timer[%d] IRQ\n", id);
+ DPRINTF("gcmp timer[%u] IRQ\n", id);
qemu_irq_raise(s->irq[id]);
}
}
@@ -1003,7 +1003,7 @@ static void exynos4210_mct_update_freq(Exynos4210MCTState *s)
MCT_CFG_GET_DIVIDER(s->reg_mct_cfg));
if (freq != s->freq) {
- DPRINTF("freq=%dHz\n", s->freq);
+ DPRINTF("freq=%uHz\n", s->freq);
/* global timer */
tx_ptimer_set_freq(s->g_timer.ptimer_frc, s->freq);
diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c
index 4fa3d87396..de181428b4 100644
--- a/hw/timer/exynos4210_pwm.c
+++ b/hw/timer/exynos4210_pwm.c
@@ -169,7 +169,7 @@ static void exynos4210_pwm_update_freq(Exynos4210PWMState *s, uint32_t id)
if (freq != s->timer[id].freq) {
ptimer_set_freq(s->timer[id].ptimer, s->timer[id].freq);
- DPRINTF("freq=%dHz\n", s->timer[id].freq);
+ DPRINTF("freq=%uHz\n", s->timer[id].freq);
}
}
@@ -183,14 +183,14 @@ static void exynos4210_pwm_tick(void *opaque)
uint32_t id = s->id;
bool cmp;
- DPRINTF("timer %d tick\n", id);
+ DPRINTF("timer %u tick\n", id);
/* set irq status */
p->reg_tint_cstat |= TINT_CSTAT_STATUS(id);
/* raise IRQ */
if (p->reg_tint_cstat & TINT_CSTAT_ENABLE(id)) {
- DPRINTF("timer %d IRQ\n", id);
+ DPRINTF("timer %u IRQ\n", id);
qemu_irq_raise(p->timer[id].irq);
}
@@ -202,7 +202,7 @@ static void exynos4210_pwm_tick(void *opaque)
}
if (cmp) {
- DPRINTF("auto reload timer %d count to %x\n", id,
+ DPRINTF("auto reload timer %u count to %x\n", id,
p->timer[id].reg_tcntb);
ptimer_set_count(p->timer[id].ptimer, p->timer[id].reg_tcntb);
ptimer_run(p->timer[id].ptimer, 1);
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 9c5b4f7fbc..2fdd5daf74 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -149,7 +149,7 @@ typedef struct VhostUserMemory {
} VhostUserMemory;
typedef struct VhostUserMemRegMsg {
- uint32_t padding;
+ uint64_t padding;
VhostUserMemoryRegion region;
} VhostUserMemRegMsg;
@@ -800,8 +800,7 @@ static int vhost_user_add_remove_regions(struct vhost_dev *dev,
uint64_t shadow_pcb[VHOST_USER_MAX_RAM_SLOTS] = {};
int nr_add_reg, nr_rem_reg;
- msg->hdr.size = sizeof(msg->payload.mem_reg.padding) +
- sizeof(VhostUserMemoryRegion);
+ msg->hdr.size = sizeof(msg->payload.mem_reg);
/* Find the regions which need to be removed or added. */
scrub_shadow_regions(dev, add_reg, &nr_add_reg, rem_reg, &nr_rem_reg,