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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJTsVuxAAoJEDwlJe0UNgzeSX0P/1e24zP1QlEKSWLLDRceUhvR tAvAOXPGtrDqQpzWXMZ/cbxZruPA/0LrRTwqccApNXGGvzotkqf+P22gHJYEKEMH gCcyd1bKCTvBpis4CxCaM7KMMBNlQ22n4aaVgMJyczETM5atxOM6csGUJOjpHUY0 4qsTwLVVnCZBB7hz9LRkb8SKNW98lHuaYT9q0JFt0PqFWT2/eT9czHGz0JMvUaUr Fy8v0GpE2nxDy8//6LZofsrbYaIuJoojhflaSXeUqtDoSGPTxrJZuiQUSqbF+6D9 64V/aGT/NzT4qoZUxYxYdJL9tE4R6lAkR6/hniFUFHEPiFMB0adLJ1+j48zw4gzB lN0PuEJ42wCV2ixdNXyN7VqFwipD2ta1PB4/NOnfqHG5udJUGpYougOKwhnrdMTM rgqJsxy5Ari+5xrqGAIlWwdUItAhHC0PJoOrVvqvwy5+hlCa6Tb4psl6Z9CLjGzR 4TAAe/L6CGpyWH6erSn7+tTIFTMAgnANYkNZ6ttiEDFsdjggCB35ebgMVBUxi4+N m1TjexOFCPHwfruYmW4pIG2pnIQchxT9BIVCikGjykdj+6Na4/mOwVlDVIhzRRvb J3JkRE/7oQ3sOWxYBNXWECcHB9VHDFNAW47o5uCXzlu5vJXYLIDT9dBw+KS29e56 i3kG0byQWtojyLikVs3k =leR3 -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
a156dd9a22
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue