提交 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 @@ ...@@ -2,7 +2,7 @@
The code in this directory is a subset of libvixl: The code in this directory is a subset of libvixl:
https://github.com/armvixl/vixl https://github.com/armvixl/vixl
(specifically, it is the set of files needed for disassembly only, (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. Bugfixes should preferably be sent upstream initially.
The disassembler does not currently support the entire A64 instruction The disassembler does not currently support the entire A64 instruction
......
...@@ -1369,7 +1369,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr, ...@@ -1369,7 +1369,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
VIXL_ASSERT(format[5] == 'L'); VIXL_ASSERT(format[5] == 'L');
AppendToOutput("#0x%" PRIx64, instr->ImmMoveWide()); AppendToOutput("#0x%" PRIx64, instr->ImmMoveWide());
if (instr->ShiftMoveWide() > 0) { if (instr->ShiftMoveWide() > 0) {
AppendToOutput(", lsl #%d", 16 * instr->ShiftMoveWide()); AppendToOutput(", lsl #%" PRId64, 16 * instr->ShiftMoveWide());
} }
} }
return 8; return 8;
...@@ -1418,7 +1418,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr, ...@@ -1418,7 +1418,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
} }
case 'F': { // IFPSingle, IFPDouble or IFPFBits. case 'F': { // IFPSingle, IFPDouble or IFPFBits.
if (format[3] == 'F') { // IFPFbits. if (format[3] == 'F') { // IFPFbits.
AppendToOutput("#%d", 64 - instr->FPScale()); AppendToOutput("#%" PRId64, 64 - instr->FPScale());
return 8; return 8;
} else { } else {
AppendToOutput("#0x%" PRIx64 " (%.4f)", instr->ImmFP(), AppendToOutput("#0x%" PRIx64 " (%.4f)", instr->ImmFP(),
...@@ -1439,23 +1439,23 @@ int Disassembler::SubstituteImmediateField(Instruction* instr, ...@@ -1439,23 +1439,23 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
return 5; return 5;
} }
case 'P': { // IP - Conditional compare. case 'P': { // IP - Conditional compare.
AppendToOutput("#%d", instr->ImmCondCmp()); AppendToOutput("#%" PRId64, instr->ImmCondCmp());
return 2; return 2;
} }
case 'B': { // Bitfields. case 'B': { // Bitfields.
return SubstituteBitfieldImmediateField(instr, format); return SubstituteBitfieldImmediateField(instr, format);
} }
case 'E': { // IExtract. case 'E': { // IExtract.
AppendToOutput("#%d", instr->ImmS()); AppendToOutput("#%" PRId64, instr->ImmS());
return 8; return 8;
} }
case 'S': { // IS - Test and branch bit. case 'S': { // IS - Test and branch bit.
AppendToOutput("#%d", (instr->ImmTestBranchBit5() << 5) | AppendToOutput("#%" PRId64, (instr->ImmTestBranchBit5() << 5) |
instr->ImmTestBranchBit40()); instr->ImmTestBranchBit40());
return 2; return 2;
} }
case 'D': { // IDebug - HLT and BRK instructions. case 'D': { // IDebug - HLT and BRK instructions.
AppendToOutput("#0x%x", instr->ImmException()); AppendToOutput("#0x%" PRIx64, instr->ImmException());
return 6; return 6;
} }
default: { default: {
...@@ -1626,12 +1626,12 @@ int Disassembler::SubstituteExtendField(Instruction* instr, ...@@ -1626,12 +1626,12 @@ int Disassembler::SubstituteExtendField(Instruction* instr,
(((instr->ExtendMode() == UXTW) && (instr->SixtyFourBits() == 0)) || (((instr->ExtendMode() == UXTW) && (instr->SixtyFourBits() == 0)) ||
(instr->ExtendMode() == UXTX))) { (instr->ExtendMode() == UXTX))) {
if (instr->ImmExtendShift() > 0) { if (instr->ImmExtendShift() > 0) {
AppendToOutput(", lsl #%d", instr->ImmExtendShift()); AppendToOutput(", lsl #%" PRId64, instr->ImmExtendShift());
} }
} else { } else {
AppendToOutput(", %s", extend_mode[instr->ExtendMode()]); AppendToOutput(", %s", extend_mode[instr->ExtendMode()]);
if (instr->ImmExtendShift() > 0) { if (instr->ImmExtendShift() > 0) {
AppendToOutput(" #%d", instr->ImmExtendShift()); AppendToOutput(" #%" PRId64, instr->ImmExtendShift());
} }
} }
return 3; return 3;
...@@ -1660,7 +1660,7 @@ int Disassembler::SubstituteLSRegOffsetField(Instruction* instr, ...@@ -1660,7 +1660,7 @@ int Disassembler::SubstituteLSRegOffsetField(Instruction* instr,
if (!((ext == UXTX) && (shift == 0))) { if (!((ext == UXTX) && (shift == 0))) {
AppendToOutput(", %s", extend_mode[ext]); AppendToOutput(", %s", extend_mode[ext]);
if (shift != 0) { if (shift != 0) {
AppendToOutput(" #%d", instr->SizeLS()); AppendToOutput(" #%" PRId64, instr->SizeLS());
} }
} }
return 9; return 9;
......
...@@ -36,7 +36,6 @@ struct PXA2xxGPIOInfo { ...@@ -36,7 +36,6 @@ struct PXA2xxGPIOInfo {
uint32_t rising[PXA2XX_GPIO_BANKS]; uint32_t rising[PXA2XX_GPIO_BANKS];
uint32_t falling[PXA2XX_GPIO_BANKS]; uint32_t falling[PXA2XX_GPIO_BANKS];
uint32_t status[PXA2XX_GPIO_BANKS]; uint32_t status[PXA2XX_GPIO_BANKS];
uint32_t gpsr[PXA2XX_GPIO_BANKS];
uint32_t gafr[PXA2XX_GPIO_BANKS * 2]; uint32_t gafr[PXA2XX_GPIO_BANKS * 2];
uint32_t prev_level[PXA2XX_GPIO_BANKS]; uint32_t prev_level[PXA2XX_GPIO_BANKS];
...@@ -162,14 +161,14 @@ static uint64_t pxa2xx_gpio_read(void *opaque, hwaddr offset, ...@@ -162,14 +161,14 @@ static uint64_t pxa2xx_gpio_read(void *opaque, hwaddr offset,
return s->dir[bank]; return s->dir[bank];
case GPSR: /* GPIO Pin-Output Set registers */ case GPSR: /* GPIO Pin-Output Set registers */
printf("%s: Read from a write-only register " REG_FMT "\n", qemu_log_mask(LOG_GUEST_ERROR,
__FUNCTION__, offset); "pxa2xx GPIO: read from write only register GPSR\n");
return s->gpsr[bank]; /* Return last written value. */ return 0;
case GPCR: /* GPIO Pin-Output Clear registers */ case GPCR: /* GPIO Pin-Output Clear registers */
printf("%s: Read from a write-only register " REG_FMT "\n", qemu_log_mask(LOG_GUEST_ERROR,
__FUNCTION__, offset); "pxa2xx GPIO: read from write only register GPCR\n");
return 31337; /* Specified as unpredictable in the docs. */ return 0;
case GRER: /* GPIO Rising-Edge Detect Enable registers */ case GRER: /* GPIO Rising-Edge Detect Enable registers */
return s->rising[bank]; return s->rising[bank];
...@@ -217,7 +216,6 @@ static void pxa2xx_gpio_write(void *opaque, hwaddr offset, ...@@ -217,7 +216,6 @@ static void pxa2xx_gpio_write(void *opaque, hwaddr offset,
case GPSR: /* GPIO Pin-Output Set registers */ case GPSR: /* GPIO Pin-Output Set registers */
s->olevel[bank] |= value; s->olevel[bank] |= value;
pxa2xx_gpio_handler_update(s); pxa2xx_gpio_handler_update(s);
s->gpsr[bank] = value;
break; break;
case GPCR: /* GPIO Pin-Output Clear registers */ case GPCR: /* GPIO Pin-Output Clear registers */
...@@ -314,7 +312,6 @@ static const VMStateDescription vmstate_pxa2xx_gpio_regs = { ...@@ -314,7 +312,6 @@ static const VMStateDescription vmstate_pxa2xx_gpio_regs = {
.version_id = 1, .version_id = 1,
.minimum_version_id = 1, .minimum_version_id = 1,
.fields = (VMStateField[]) { .fields = (VMStateField[]) {
VMSTATE_INT32(lines, PXA2xxGPIOInfo),
VMSTATE_UINT32_ARRAY(ilevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS), VMSTATE_UINT32_ARRAY(ilevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_UINT32_ARRAY(olevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS), VMSTATE_UINT32_ARRAY(olevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_UINT32_ARRAY(dir, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS), VMSTATE_UINT32_ARRAY(dir, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
...@@ -322,6 +319,7 @@ static const VMStateDescription vmstate_pxa2xx_gpio_regs = { ...@@ -322,6 +319,7 @@ static const VMStateDescription vmstate_pxa2xx_gpio_regs = {
VMSTATE_UINT32_ARRAY(falling, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS), VMSTATE_UINT32_ARRAY(falling, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_UINT32_ARRAY(status, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS), VMSTATE_UINT32_ARRAY(status, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_UINT32_ARRAY(gafr, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS * 2), VMSTATE_UINT32_ARRAY(gafr, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS * 2),
VMSTATE_UINT32_ARRAY(prev_level, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
VMSTATE_END_OF_LIST(), VMSTATE_END_OF_LIST(),
}, },
}; };
...@@ -340,6 +338,7 @@ static void pxa2xx_gpio_class_init(ObjectClass *klass, void *data) ...@@ -340,6 +338,7 @@ static void pxa2xx_gpio_class_init(ObjectClass *klass, void *data)
k->init = pxa2xx_gpio_initfn; k->init = pxa2xx_gpio_initfn;
dc->desc = "PXA2xx GPIO controller"; dc->desc = "PXA2xx GPIO controller";
dc->props = pxa2xx_gpio_properties; dc->props = pxa2xx_gpio_properties;
dc->vmsd = &vmstate_pxa2xx_gpio_regs;
} }
static const TypeInfo pxa2xx_gpio_info = { static const TypeInfo pxa2xx_gpio_info = {
......
...@@ -480,7 +480,6 @@ struct StrongARMGPIOInfo { ...@@ -480,7 +480,6 @@ struct StrongARMGPIOInfo {
uint32_t rising; uint32_t rising;
uint32_t falling; uint32_t falling;
uint32_t status; uint32_t status;
uint32_t gpsr;
uint32_t gafr; uint32_t gafr;
uint32_t prev_level; uint32_t prev_level;
...@@ -544,14 +543,14 @@ static uint64_t strongarm_gpio_read(void *opaque, hwaddr offset, ...@@ -544,14 +543,14 @@ static uint64_t strongarm_gpio_read(void *opaque, hwaddr offset,
return s->dir; return s->dir;
case GPSR: /* GPIO Pin-Output Set registers */ case GPSR: /* GPIO Pin-Output Set registers */
DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n", qemu_log_mask(LOG_GUEST_ERROR,
__func__, offset); "strongarm GPIO: read from write only register GPSR\n");
return s->gpsr; /* Return last written value. */ return 0;
case GPCR: /* GPIO Pin-Output Clear registers */ case GPCR: /* GPIO Pin-Output Clear registers */
DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n", qemu_log_mask(LOG_GUEST_ERROR,
__func__, offset); "strongarm GPIO: read from write only register GPCR\n");
return 31337; /* Specified as unpredictable in the docs. */ return 0;
case GRER: /* GPIO Rising-Edge Detect Enable registers */ case GRER: /* GPIO Rising-Edge Detect Enable registers */
return s->rising; return s->rising;
...@@ -590,7 +589,6 @@ static void strongarm_gpio_write(void *opaque, hwaddr offset, ...@@ -590,7 +589,6 @@ static void strongarm_gpio_write(void *opaque, hwaddr offset,
case GPSR: /* GPIO Pin-Output Set registers */ case GPSR: /* GPIO Pin-Output Set registers */
s->olevel |= value; s->olevel |= value;
strongarm_gpio_handler_update(s); strongarm_gpio_handler_update(s);
s->gpsr = value;
break; break;
case GPCR: /* GPIO Pin-Output Clear registers */ case GPCR: /* GPIO Pin-Output Clear registers */
...@@ -676,6 +674,7 @@ static const VMStateDescription vmstate_strongarm_gpio_regs = { ...@@ -676,6 +674,7 @@ static const VMStateDescription vmstate_strongarm_gpio_regs = {
VMSTATE_UINT32(falling, StrongARMGPIOInfo), VMSTATE_UINT32(falling, StrongARMGPIOInfo),
VMSTATE_UINT32(status, StrongARMGPIOInfo), VMSTATE_UINT32(status, StrongARMGPIOInfo),
VMSTATE_UINT32(gafr, StrongARMGPIOInfo), VMSTATE_UINT32(gafr, StrongARMGPIOInfo),
VMSTATE_UINT32(prev_level, StrongARMGPIOInfo),
VMSTATE_END_OF_LIST(), VMSTATE_END_OF_LIST(),
}, },
}; };
...@@ -687,6 +686,7 @@ static void strongarm_gpio_class_init(ObjectClass *klass, void *data) ...@@ -687,6 +686,7 @@ static void strongarm_gpio_class_init(ObjectClass *klass, void *data)
k->init = strongarm_gpio_initfn; k->init = strongarm_gpio_initfn;
dc->desc = "StrongARM GPIO controller"; dc->desc = "StrongARM GPIO controller";
dc->vmsd = &vmstate_strongarm_gpio_regs;
} }
static const TypeInfo strongarm_gpio_info = { static const TypeInfo strongarm_gpio_info = {
...@@ -846,6 +846,7 @@ static const VMStateDescription vmstate_strongarm_ppc_regs = { ...@@ -846,6 +846,7 @@ static const VMStateDescription vmstate_strongarm_ppc_regs = {
VMSTATE_UINT32(ppar, StrongARMPPCInfo), VMSTATE_UINT32(ppar, StrongARMPPCInfo),
VMSTATE_UINT32(psdr, StrongARMPPCInfo), VMSTATE_UINT32(psdr, StrongARMPPCInfo),
VMSTATE_UINT32(ppfr, StrongARMPPCInfo), VMSTATE_UINT32(ppfr, StrongARMPPCInfo),
VMSTATE_UINT32(prev_level, StrongARMPPCInfo),
VMSTATE_END_OF_LIST(), VMSTATE_END_OF_LIST(),
}, },
}; };
...@@ -857,6 +858,7 @@ static void strongarm_ppc_class_init(ObjectClass *klass, void *data) ...@@ -857,6 +858,7 @@ static void strongarm_ppc_class_init(ObjectClass *klass, void *data)
k->init = strongarm_ppc_init; k->init = strongarm_ppc_init;
dc->desc = "StrongARM PPC controller"; dc->desc = "StrongARM PPC controller";
dc->vmsd = &vmstate_strongarm_ppc_regs;
} }
static const TypeInfo strongarm_ppc_info = { static const TypeInfo strongarm_ppc_info = {
......
...@@ -65,6 +65,7 @@ enum { ...@@ -65,6 +65,7 @@ enum {
VIRT_GIC_CPU, VIRT_GIC_CPU,
VIRT_UART, VIRT_UART,
VIRT_MMIO, VIRT_MMIO,
VIRT_RTC,
}; };
typedef struct MemMapEntry { typedef struct MemMapEntry {
...@@ -92,6 +93,8 @@ typedef struct VirtBoardInfo { ...@@ -92,6 +93,8 @@ typedef struct VirtBoardInfo {
* high memory region beyond 4GB). * high memory region beyond 4GB).
* This represents a compromise between how much RAM can be given to * 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. * 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[] = { static const MemMapEntry a15memmap[] = {
/* Space up to 0x8000000 is reserved for a boot ROM */ /* Space up to 0x8000000 is reserved for a boot ROM */
...@@ -101,6 +104,7 @@ static const MemMapEntry a15memmap[] = { ...@@ -101,6 +104,7 @@ static const MemMapEntry a15memmap[] = {
[VIRT_GIC_DIST] = { 0x8000000, 0x10000 }, [VIRT_GIC_DIST] = { 0x8000000, 0x10000 },
[VIRT_GIC_CPU] = { 0x8010000, 0x10000 }, [VIRT_GIC_CPU] = { 0x8010000, 0x10000 },
[VIRT_UART] = { 0x9000000, 0x1000 }, [VIRT_UART] = { 0x9000000, 0x1000 },
[VIRT_RTC] = { 0x90010000, 0x1000 },
[VIRT_MMIO] = { 0xa000000, 0x200 }, [VIRT_MMIO] = { 0xa000000, 0x200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
/* 0x10000000 .. 0x40000000 reserved for PCI */ /* 0x10000000 .. 0x40000000 reserved for PCI */
...@@ -109,6 +113,7 @@ static const MemMapEntry a15memmap[] = { ...@@ -109,6 +113,7 @@ static const MemMapEntry a15memmap[] = {
static const int a15irqmap[] = { static const int a15irqmap[] = {
[VIRT_UART] = 1, [VIRT_UART] = 1,
[VIRT_RTC] = 2,
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */ [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
}; };
...@@ -353,6 +358,29 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic) ...@@ -353,6 +358,29 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
g_free(nodename); 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) static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
{ {
int i; int i;
...@@ -469,6 +497,8 @@ static void machvirt_init(MachineState *machine) ...@@ -469,6 +497,8 @@ static void machvirt_init(MachineState *machine)
create_uart(vbi, pic); create_uart(vbi, pic);
create_rtc(vbi, pic);
/* Create mmio transports, so the user can create virtio backends /* Create mmio transports, so the user can create virtio backends
* (which will be automatically plugged in to the transports). If * (which will be automatically plugged in to the transports). If
* no backend is created the transport will just sit harmlessly idle. * 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) ...@@ -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); 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; int i;
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
cadence_timer_init(133000000, &s->timer[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); "timer", 0x1000);
sysbus_init_mmio(dev, &s->iomem); sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
return 0;
} }
static void cadence_timer_pre_save(void *opaque) static void cadence_timer_pre_save(void *opaque)
...@@ -474,9 +472,7 @@ static const VMStateDescription vmstate_cadence_ttc = { ...@@ -474,9 +472,7 @@ static const VMStateDescription vmstate_cadence_ttc = {
static void cadence_ttc_class_init(ObjectClass *klass, void *data) static void cadence_ttc_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
sdc->init = cadence_ttc_init;
dc->vmsd = &vmstate_cadence_ttc; dc->vmsd = &vmstate_cadence_ttc;
} }
...@@ -484,6 +480,7 @@ static const TypeInfo cadence_ttc_info = { ...@@ -484,6 +480,7 @@ static const TypeInfo cadence_ttc_info = {
.name = TYPE_CADENCE_TTC, .name = TYPE_CADENCE_TTC,
.parent = TYPE_SYS_BUS_DEVICE, .parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(CadenceTTCState), .instance_size = sizeof(CadenceTTCState),
.instance_init = cadence_ttc_init,
.class_init = cadence_ttc_class_init, .class_init = cadence_ttc_class_init,
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册