summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-06-30 15:16:25 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-06-30 15:16:26 +0100
commita156dd9a223d98779da6207144d33a4dea90b683 (patch)
treeb4bd7374b47ed9ce5ca1e1e0f8572f65bf597b45
parent9328cfd2fe4a7ff86a41b2c26ea33974241d7d4e (diff)
parentffebe8997523fd922da58a8e19ddffee6b035429 (diff)
downloadqemu-a156dd9a223d98779da6207144d33a4dea90b683.tar.gz
qemu-a156dd9a223d98779da6207144d33a4dea90b683.tar.bz2
qemu-a156dd9a223d98779da6207144d33a4dea90b683.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140630' into staging
target-arm: * provide PL031 RTC in virt board * fix missing pxa2xx and strongarm vmstate * convert cadence_ttc to instance_init * fix libvixl format strings and README # gpg: Signature made Mon 30 Jun 2014 13:44:33 BST using RSA key ID 14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" * remotes/pmaydell/tags/pull-target-arm-20140630: disas/libvixl: Fix wrong format strings disas/libvixl: Update README for version base timer: cadence_ttc: Convert to instance_init hw/arm/pxa2xx_gpio: Correct and register vmstate hw/arm/pxa2xx_gpio: Fix handling of GPSR/GPCR reads hw/arm/strongarm: Wire up missing GPIO and PPC vmstate hw/arm/strongarm: Fix handling of GPSR/GPCR reads hw/arm/virt: Provide PL031 RTC Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--disas/libvixl/README2
-rw-r--r--disas/libvixl/a64/disasm-a64.cc20
-rw-r--r--hw/arm/pxa2xx_gpio.c17
-rw-r--r--hw/arm/strongarm.c18
-rw-r--r--hw/arm/virt.c30
-rw-r--r--hw/timer/cadence_ttc.c15
6 files changed, 65 insertions, 37 deletions
diff --git a/disas/libvixl/README b/disas/libvixl/README
index 96814a5dc1..a0ecac3dd3 100644
--- a/disas/libvixl/README
+++ b/disas/libvixl/README
@@ -2,7 +2,7 @@
The code in this directory is a subset of libvixl:
https://github.com/armvixl/vixl
(specifically, it is the set of files needed for disassembly only,
-taken from libvixl 1.1).
+taken from libvixl 1.4).
Bugfixes should preferably be sent upstream initially.
The disassembler does not currently support the entire A64 instruction
diff --git a/disas/libvixl/a64/disasm-a64.cc b/disas/libvixl/a64/disasm-a64.cc
index aa133a99bf..f81ce4bbb8 100644
--- a/disas/libvixl/a64/disasm-a64.cc
+++ b/disas/libvixl/a64/disasm-a64.cc
@@ -1369,7 +1369,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
VIXL_ASSERT(format[5] == 'L');
AppendToOutput("#0x%" PRIx64, instr->ImmMoveWide());
if (instr->ShiftMoveWide() > 0) {
- AppendToOutput(", lsl #%d", 16 * instr->ShiftMoveWide());
+ AppendToOutput(", lsl #%" PRId64, 16 * instr->ShiftMoveWide());
}
}
return 8;
@@ -1418,7 +1418,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
}
case 'F': { // IFPSingle, IFPDouble or IFPFBits.
if (format[3] == 'F') { // IFPFbits.
- AppendToOutput("#%d", 64 - instr->FPScale());
+ AppendToOutput("#%" PRId64, 64 - instr->FPScale());
return 8;
} else {
AppendToOutput("#0x%" PRIx64 " (%.4f)", instr->ImmFP(),
@@ -1439,23 +1439,23 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
return 5;
}
case 'P': { // IP - Conditional compare.
- AppendToOutput("#%d", instr->ImmCondCmp());
+ AppendToOutput("#%" PRId64, instr->ImmCondCmp());
return 2;
}
case 'B': { // Bitfields.
return SubstituteBitfieldImmediateField(instr, format);
}
case 'E': { // IExtract.
- AppendToOutput("#%d", instr->ImmS());
+ AppendToOutput("#%" PRId64, instr->ImmS());
return 8;
}
case 'S': { // IS - Test and branch bit.
- AppendToOutput("#%d", (instr->ImmTestBranchBit5() << 5) |
- instr->ImmTestBranchBit40());
+ AppendToOutput("#%" PRId64, (instr->ImmTestBranchBit5() << 5) |
+ instr->ImmTestBranchBit40());
return 2;
}
case 'D': { // IDebug - HLT and BRK instructions.
- AppendToOutput("#0x%x", instr->ImmException());
+ AppendToOutput("#0x%" PRIx64, instr->ImmException());
return 6;
}
default: {
@@ -1626,12 +1626,12 @@ int Disassembler::SubstituteExtendField(Instruction* instr,
(((instr->ExtendMode() == UXTW) && (instr->SixtyFourBits() == 0)) ||
(instr->ExtendMode() == UXTX))) {
if (instr->ImmExtendShift() > 0) {
- AppendToOutput(", lsl #%d", instr->ImmExtendShift());
+ AppendToOutput(", lsl #%" PRId64, instr->ImmExtendShift());
}
} else {
AppendToOutput(", %s", extend_mode[instr->ExtendMode()]);
if (instr->ImmExtendShift() > 0) {
- AppendToOutput(" #%d", instr->ImmExtendShift());
+ AppendToOutput(" #%" PRId64, instr->ImmExtendShift());
}
}
return 3;
@@ -1660,7 +1660,7 @@ int Disassembler::SubstituteLSRegOffsetField(Instruction* instr,
if (!((ext == UXTX) && (shift == 0))) {
AppendToOutput(", %s", extend_mode[ext]);
if (shift != 0) {
- AppendToOutput(" #%d", instr->SizeLS());
+ AppendToOutput(" #%" PRId64, instr->SizeLS());
}
}
return 9;
diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c
index 7f75f05137..354ccf1ea1 100644
--- a/hw/arm/pxa2xx_gpio.c
+++ b/hw/arm/pxa2xx_gpio.c
@@ -36,7 +36,6 @@ struct PXA2xxGPIOInfo {
uint32_t rising[PXA2XX_GPIO_BANKS];
uint32_t falling[PXA2XX_GPIO_BANKS];
uint32_t status[PXA2XX_GPIO_BANKS];
- uint32_t gpsr[PXA2XX_GPIO_BANKS];
uint32_t gafr[PXA2XX_GPIO_BANKS * 2];
uint32_t prev_level[PXA2XX_GPIO_BANKS];
@@ -162,14 +161,14 @@ static uint64_t pxa2xx_gpio_read(void *opaque, hwaddr offset,
return s->dir[bank];
case GPSR: /* GPIO Pin-Output Set registers */
- printf("%s: Read from a write-only register " REG_FMT "\n",
- __FUNCTION__, offset);
- return s->gpsr[bank]; /* Return last written value. */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "pxa2xx GPIO: read from write only register GPSR\n");
+ return 0;
case GPCR: /* GPIO Pin-Output Clear registers */
- printf("%s: Read from a write-only register " REG_FMT "\n",
- __FUNCTION__, offset);
- return 31337; /* Specified as unpredictable in the docs. */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "pxa2xx GPIO: read from write only register GPCR\n");
+ return 0;
case GRER: /* GPIO Rising-Edge Detect Enable registers */
return s->rising[bank];
@@ -217,7 +216,6 @@ static void pxa2xx_gpio_write(void *opaque, hwaddr offset,
case GPSR: /* GPIO Pin-Output Set registers */
s->olevel[bank] |= value;
pxa2xx_gpio_handler_update(s);
- s->gpsr[bank] = value;
break;
case GPCR: /* GPIO Pin-Output Clear registers */
@@ -314,7 +312,6 @@ static const VMStateDescription vmstate_pxa2xx_gpio_regs = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_INT32(lines, PXA2xxGPIOInfo),
VMSTATE_UINT32_ARRAY(ilevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_UINT32_ARRAY(olevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_UINT32_ARRAY(dir, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
@@ -322,6 +319,7 @@ static const VMStateDescription vmstate_pxa2xx_gpio_regs = {
VMSTATE_UINT32_ARRAY(falling, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_UINT32_ARRAY(status, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_UINT32_ARRAY(gafr, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS * 2),
+ VMSTATE_UINT32_ARRAY(prev_level, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_END_OF_LIST(),
},
};
@@ -340,6 +338,7 @@ static void pxa2xx_gpio_class_init(ObjectClass *klass, void *data)
k->init = pxa2xx_gpio_initfn;
dc->desc = "PXA2xx GPIO controller";
dc->props = pxa2xx_gpio_properties;
+ dc->vmsd = &vmstate_pxa2xx_gpio_regs;
}
static const TypeInfo pxa2xx_gpio_info = {
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 0da9015333..9e2a0d48aa 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -480,7 +480,6 @@ struct StrongARMGPIOInfo {
uint32_t rising;
uint32_t falling;
uint32_t status;
- uint32_t gpsr;
uint32_t gafr;
uint32_t prev_level;
@@ -544,14 +543,14 @@ static uint64_t strongarm_gpio_read(void *opaque, hwaddr offset,
return s->dir;
case GPSR: /* GPIO Pin-Output Set registers */
- DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n",
- __func__, offset);
- return s->gpsr; /* Return last written value. */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "strongarm GPIO: read from write only register GPSR\n");
+ return 0;
case GPCR: /* GPIO Pin-Output Clear registers */
- DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n",
- __func__, offset);
- return 31337; /* Specified as unpredictable in the docs. */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "strongarm GPIO: read from write only register GPCR\n");
+ return 0;
case GRER: /* GPIO Rising-Edge Detect Enable registers */
return s->rising;
@@ -590,7 +589,6 @@ static void strongarm_gpio_write(void *opaque, hwaddr offset,
case GPSR: /* GPIO Pin-Output Set registers */
s->olevel |= value;
strongarm_gpio_handler_update(s);
- s->gpsr = value;
break;
case GPCR: /* GPIO Pin-Output Clear registers */
@@ -676,6 +674,7 @@ static const VMStateDescription vmstate_strongarm_gpio_regs = {
VMSTATE_UINT32(falling, StrongARMGPIOInfo),
VMSTATE_UINT32(status, StrongARMGPIOInfo),
VMSTATE_UINT32(gafr, StrongARMGPIOInfo),
+ VMSTATE_UINT32(prev_level, StrongARMGPIOInfo),
VMSTATE_END_OF_LIST(),
},
};
@@ -687,6 +686,7 @@ static void strongarm_gpio_class_init(ObjectClass *klass, void *data)
k->init = strongarm_gpio_initfn;
dc->desc = "StrongARM GPIO controller";
+ dc->vmsd = &vmstate_strongarm_gpio_regs;
}
static const TypeInfo strongarm_gpio_info = {
@@ -846,6 +846,7 @@ static const VMStateDescription vmstate_strongarm_ppc_regs = {
VMSTATE_UINT32(ppar, StrongARMPPCInfo),
VMSTATE_UINT32(psdr, StrongARMPPCInfo),
VMSTATE_UINT32(ppfr, StrongARMPPCInfo),
+ VMSTATE_UINT32(prev_level, StrongARMPPCInfo),
VMSTATE_END_OF_LIST(),
},
};
@@ -857,6 +858,7 @@ static void strongarm_ppc_class_init(ObjectClass *klass, void *data)
k->init = strongarm_ppc_init;
dc->desc = "StrongARM PPC controller";
+ dc->vmsd = &vmstate_strongarm_ppc_regs;
}
static const TypeInfo strongarm_ppc_info = {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 72fe030e93..405c61d39c 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -65,6 +65,7 @@ enum {
VIRT_GIC_CPU,
VIRT_UART,
VIRT_MMIO,
+ VIRT_RTC,
};
typedef struct MemMapEntry {
@@ -92,6 +93,8 @@ typedef struct VirtBoardInfo {
* high memory region beyond 4GB).
* This represents a compromise between how much RAM can be given to
* a 32 bit VM and leaving space for expansion and in particular for PCI.
+ * Note that devices should generally be placed at multiples of 0x10000,
+ * to accommodate guests using 64K pages.
*/
static const MemMapEntry a15memmap[] = {
/* Space up to 0x8000000 is reserved for a boot ROM */
@@ -101,6 +104,7 @@ static const MemMapEntry a15memmap[] = {
[VIRT_GIC_DIST] = { 0x8000000, 0x10000 },
[VIRT_GIC_CPU] = { 0x8010000, 0x10000 },
[VIRT_UART] = { 0x9000000, 0x1000 },
+ [VIRT_RTC] = { 0x90010000, 0x1000 },
[VIRT_MMIO] = { 0xa000000, 0x200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
/* 0x10000000 .. 0x40000000 reserved for PCI */
@@ -109,6 +113,7 @@ static const MemMapEntry a15memmap[] = {
static const int a15irqmap[] = {
[VIRT_UART] = 1,
+ [VIRT_RTC] = 2,
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
};
@@ -353,6 +358,29 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
g_free(nodename);
}
+static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
+{
+ char *nodename;
+ hwaddr base = vbi->memmap[VIRT_RTC].base;
+ hwaddr size = vbi->memmap[VIRT_RTC].size;
+ int irq = vbi->irqmap[VIRT_RTC];
+ const char compat[] = "arm,pl031\0arm,primecell";
+
+ sysbus_create_simple("pl031", base, pic[irq]);
+
+ nodename = g_strdup_printf("/pl031@%" PRIx64, base);
+ qemu_fdt_add_subnode(vbi->fdt, nodename);
+ qemu_fdt_setprop(vbi->fdt, nodename, "compatible", compat, sizeof(compat));
+ qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
+ 2, base, 2, size);
+ qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
+ GIC_FDT_IRQ_TYPE_SPI, irq,
+ GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+ qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);
+ qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");
+ g_free(nodename);
+}
+
static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
{
int i;
@@ -469,6 +497,8 @@ static void machvirt_init(MachineState *machine)
create_uart(vbi, pic);
+ create_rtc(vbi, pic);
+
/* Create mmio transports, so the user can create virtio backends
* (which will be automatically plugged in to the transports). If
* no backend is created the transport will just sit harmlessly idle.
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
index 52bbbbca7f..d46db3c0e2 100644
--- a/hw/timer/cadence_ttc.c
+++ b/hw/timer/cadence_ttc.c
@@ -406,21 +406,19 @@ static void cadence_timer_init(uint32_t freq, CadenceTimerState *s)
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cadence_timer_tick, s);
}
-static int cadence_ttc_init(SysBusDevice *dev)
+static void cadence_ttc_init(Object *obj)
{
- CadenceTTCState *s = CADENCE_TTC(dev);
+ CadenceTTCState *s = CADENCE_TTC(obj);
int i;
for (i = 0; i < 3; ++i) {
cadence_timer_init(133000000, &s->timer[i]);
- sysbus_init_irq(dev, &s->timer[i].irq);
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->timer[i].irq);
}
- memory_region_init_io(&s->iomem, OBJECT(s), &cadence_ttc_ops, s,
+ memory_region_init_io(&s->iomem, obj, &cadence_ttc_ops, s,
"timer", 0x1000);
- sysbus_init_mmio(dev, &s->iomem);
-
- return 0;
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
}
static void cadence_timer_pre_save(void *opaque)
@@ -474,9 +472,7 @@ static const VMStateDescription vmstate_cadence_ttc = {
static void cadence_ttc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
- sdc->init = cadence_ttc_init;
dc->vmsd = &vmstate_cadence_ttc;
}
@@ -484,6 +480,7 @@ static const TypeInfo cadence_ttc_info = {
.name = TYPE_CADENCE_TTC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(CadenceTTCState),
+ .instance_init = cadence_ttc_init,
.class_init = cadence_ttc_class_init,
};