diff options
| -rw-r--r-- | disas/libvixl/README | 2 | ||||
| -rw-r--r-- | disas/libvixl/a64/disasm-a64.cc | 20 | ||||
| -rw-r--r-- | hw/arm/pxa2xx_gpio.c | 17 | ||||
| -rw-r--r-- | hw/arm/strongarm.c | 18 | ||||
| -rw-r--r-- | hw/arm/virt.c | 30 | ||||
| -rw-r--r-- | hw/timer/cadence_ttc.c | 15 | ||||
| -rw-r--r-- | ui/cocoa.m | 108 |
7 files changed, 140 insertions, 70 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, }; diff --git a/ui/cocoa.m b/ui/cocoa.m index f20fd1ffa2..3147178118 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -256,7 +256,7 @@ static int cocoa_keycode_to_qemu(int keycode) BOOL isMouseGrabbed; BOOL isFullscreen; BOOL isAbsoluteEnabled; - BOOL isTabletEnabled; + BOOL isMouseDeassociated; } - (void) switchSurface:(DisplaySurface *)surface; - (void) grabMouse; @@ -264,8 +264,21 @@ static int cocoa_keycode_to_qemu(int keycode) - (void) toggleFullScreen:(id)sender; - (void) handleEvent:(NSEvent *)event; - (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled; +/* The state surrounding mouse grabbing is potentially confusing. + * isAbsoluteEnabled tracks qemu_input_is_absolute() [ie "is the emulated + * pointing device an absolute-position one?"], but is only updated on + * next refresh. + * isMouseGrabbed tracks whether GUI events are directed to the guest; + * it controls whether special keys like Cmd get sent to the guest, + * and whether we capture the mouse when in non-absolute mode. + * isMouseDeassociated tracks whether we've told MacOSX to disassociate + * the mouse and mouse cursor position by calling + * CGAssociateMouseAndMouseCursorPosition(FALSE) + * (which basically happens if we grab in non-absolute mode). + */ - (BOOL) isMouseGrabbed; - (BOOL) isAbsoluteEnabled; +- (BOOL) isMouseDeassociated; - (float) cdx; - (float) cdy; - (QEMUScreen) gscreen; @@ -305,6 +318,27 @@ QemuCocoaView *cocoaView; return YES; } +- (BOOL) screenContainsPoint:(NSPoint) p +{ + return (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height); +} + +- (void) hideCursor +{ + if (!cursor_hide) { + return; + } + [NSCursor hide]; +} + +- (void) unhideCursor +{ + if (!cursor_hide) { + return; + } + [NSCursor unhide]; +} + - (void) drawRect:(NSRect) rect { COCOA_DEBUG("QemuCocoaView: drawRect\n"); @@ -404,7 +438,11 @@ QemuCocoaView *cocoaView; int w = surface_width(surface); int h = surface_height(surface); - bool isResize = (w != screen.width || h != screen.height); + /* cdx == 0 means this is our very first surface, in which case we need + * to recalculate the content dimensions even if it happens to be the size + * of the initial empty window. + */ + bool isResize = (w != screen.width || h != screen.height || cdx == 0.0); int oldh = screen.height; if (isResize) { @@ -603,15 +641,13 @@ QemuCocoaView *cocoaView; break; case NSMouseMoved: if (isAbsoluteEnabled) { - if (p.x < 0 || p.x > screen.width || p.y < 0 || p.y > screen.height || ![[self window] isKeyWindow]) { - if (isTabletEnabled) { // if we leave the window, deactivate the tablet - [NSCursor unhide]; - isTabletEnabled = FALSE; + if (![self screenContainsPoint:p] || ![[self window] isKeyWindow]) { + if (isMouseGrabbed) { + [self ungrabMouse]; } } else { - if (!isTabletEnabled) { // if we enter the window, activate the tablet - [NSCursor hide]; - isTabletEnabled = TRUE; + if (!isMouseGrabbed) { + [self grabMouse]; } } } @@ -650,16 +686,9 @@ QemuCocoaView *cocoaView; mouse_event = true; break; case NSLeftMouseUp: - if (isTabletEnabled) { - mouse_event = true; - } else if (!isMouseGrabbed) { - if (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height) { - [self grabMouse]; - } else { - [NSApp sendEvent:event]; - } - } else { - mouse_event = true; + mouse_event = true; + if (!isMouseGrabbed && [self screenContainsPoint:p]) { + [self grabMouse]; } break; case NSRightMouseUp: @@ -669,13 +698,11 @@ QemuCocoaView *cocoaView; mouse_event = true; break; case NSScrollWheel: - if (isTabletEnabled || isMouseGrabbed) { + if (isMouseGrabbed) { buttons |= ([event deltaY] < 0) ? MOUSE_EVENT_WHEELUP : MOUSE_EVENT_WHEELDN; - mouse_event = true; - } else { - [NSApp sendEvent:event]; } + mouse_event = true; break; default: [NSApp sendEvent:event]; @@ -693,12 +720,20 @@ QemuCocoaView *cocoaView; qemu_input_update_buttons(dcl->con, bmap, last_buttons, buttons); last_buttons = buttons; } - if (isTabletEnabled) { - qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, screen.width); - qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, p.y, screen.height); - } else if (isMouseGrabbed) { - qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event deltaX]); - qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, (int)[event deltaY]); + if (isMouseGrabbed) { + if (isAbsoluteEnabled) { + /* Note that the origin for Cocoa mouse coords is bottom left, not top left. + * The check on screenContainsPoint is to avoid sending out of range values for + * clicks in the titlebar. + */ + if ([self screenContainsPoint:p]) { + qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, screen.width); + qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height - p.y, screen.height); + } + } else { + qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event deltaX]); + qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, (int)[event deltaY]); + } } else { [NSApp sendEvent:event]; } @@ -716,8 +751,11 @@ QemuCocoaView *cocoaView; else [normalWindow setTitle:@"QEMU - (Press ctrl + alt to release Mouse)"]; } - [NSCursor hide]; - CGAssociateMouseAndMouseCursorPosition(FALSE); + [self hideCursor]; + if (!isAbsoluteEnabled) { + isMouseDeassociated = TRUE; + CGAssociateMouseAndMouseCursorPosition(FALSE); + } isMouseGrabbed = TRUE; // while isMouseGrabbed = TRUE, QemuCocoaApp sends all events to [cocoaView handleEvent:] } @@ -731,14 +769,18 @@ QemuCocoaView *cocoaView; else [normalWindow setTitle:@"QEMU"]; } - [NSCursor unhide]; - CGAssociateMouseAndMouseCursorPosition(TRUE); + [self unhideCursor]; + if (isMouseDeassociated) { + CGAssociateMouseAndMouseCursorPosition(TRUE); + isMouseDeassociated = FALSE; + } isMouseGrabbed = FALSE; } - (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled {isAbsoluteEnabled = tIsAbsoluteEnabled;} - (BOOL) isMouseGrabbed {return isMouseGrabbed;} - (BOOL) isAbsoluteEnabled {return isAbsoluteEnabled;} +- (BOOL) isMouseDeassociated {return isMouseDeassociated;} - (float) cdx {return cdx;} - (float) cdy {return cdy;} - (QEMUScreen) gscreen {return screen;} |