提交 a156dd9a 编写于 作者: P Peter Maydell

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: NPeter Maydell <peter.maydell@linaro.org>
......@@ -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
......
......@@ -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;
......
......@@ -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 = {
......
......@@ -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 = {
......
......@@ -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.
......
......@@ -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,
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册