From 3dfd5a2a50fc4907728eb83569c84b0d98b56582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 6 Nov 2017 19:39:15 +0100 Subject: tpm: lookup the the TPM interface instead of TIS device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will allow to introduce new devices implementing TPM. Signed-off-by: Marc-André Lureau Reviewed-by: Stefan Berger Signed-off-by: Stefan Berger --- hw/i386/acpi-build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/i386') diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 73519ab..cdb4aa9 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -208,7 +208,7 @@ static void acpi_get_misc_info(AcpiMiscInfo *info) } info->has_hpet = hpet_find(); - info->tpm_version = tpm_get_version(); + info->tpm_version = tpm_get_version(tpm_find()); info->pvpanic_port = pvpanic_port(); info->applesmc_io_base = applesmc_port(); } -- cgit v1.1 From ff5ce21e1b959206f257967d6de2efa6f4e3d188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 6 Nov 2017 19:39:18 +0100 Subject: acpi: change TPM TIS data conditions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The device should be exposed if present. It shouldn't have an undefined version (or else backend init failed, and device should fail too). Finally, make the fields specific to TIS device model. Signed-off-by: Marc-André Lureau Reviewed-by: Stefan Berger Signed-off-by: Stefan Berger --- hw/i386/acpi-build.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'hw/i386') diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index cdb4aa9..dd1420b 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2038,7 +2038,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, } } - if (misc->tpm_version != TPM_VERSION_UNSPEC) { + if (TPM_IS_TIS(tpm_find())) { aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE, TPM_TIS_ADDR_SIZE, AML_READ_WRITE)); } @@ -2204,7 +2204,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, /* Scan all PCI buses. Generate tables to support hotplug. */ build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en); - if (misc->tpm_version != TPM_VERSION_UNSPEC) { + if (TPM_IS_TIS(tpm_find())) { dev = aml_device("ISA.TPM"); aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C31"))); aml_append(dev, aml_name_decl("_STA", aml_int(0xF))); @@ -2281,8 +2281,12 @@ build_tpm2(GArray *table_data, BIOSLinker *linker) tpm2_ptr = acpi_data_push(table_data, sizeof *tpm2_ptr); tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT); - tpm2_ptr->control_area_address = cpu_to_le64(0); - tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO); + if (TPM_IS_TIS(tpm_find())) { + tpm2_ptr->control_area_address = cpu_to_le64(0); + tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO); + } else { + g_warn_if_reached(); + } build_header(linker, table_data, (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4, NULL, NULL); -- cgit v1.1 From ab1ce9bd4897b9909836e2d50bca86f2f3f2dddc Mon Sep 17 00:00:00 2001 From: Michael McConville Date: Fri, 1 Dec 2017 11:31:57 -0700 Subject: mmap(2) returns MAP_FAILED, not NULL, on failure Signed-off-by: Michael McConville Reviewed-by: John Snow Signed-off-by: Michael Tokarev --- hw/i386/xen/xen-mapcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/i386') diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c index baab93b..efa35dc 100644 --- a/hw/i386/xen/xen-mapcache.c +++ b/hw/i386/xen/xen-mapcache.c @@ -199,7 +199,7 @@ static void xen_remap_bucket(MapCacheEntry *entry, */ vaddr_base = mmap(vaddr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); - if (vaddr_base == NULL) { + if (vaddr_base == MAP_FAILED) { perror("mmap"); exit(-1); } -- cgit v1.1 From 433545d56930ad8867ff6950bd47e2b438173ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 17 Oct 2017 13:44:07 -0300 Subject: amd_iommu: avoid needless includes in header file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit instead move them to the source file Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Signed-off-by: Michael Tokarev --- hw/i386/amd_iommu.c | 5 ++++- hw/i386/amd_iommu.h | 5 ----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'hw/i386') diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index ad8155c..eeaf0e0 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -20,7 +20,10 @@ * Cache implementation inspired by hw/i386/intel_iommu.c */ #include "qemu/osdep.h" -#include "hw/i386/amd_iommu.h" +#include "hw/i386/pc.h" +#include "hw/pci/msi.h" +#include "hw/pci/pci_bus.h" +#include "amd_iommu.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "trace.h" diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index d370ae3..aeef802 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -23,11 +23,6 @@ #include "hw/hw.h" #include "hw/pci/pci.h" -#include "hw/pci/msi.h" -#include "hw/sysbus.h" -#include "sysemu/dma.h" -#include "hw/i386/pc.h" -#include "hw/pci/pci_bus.h" #include "hw/i386/x86-iommu.h" /* Capability registers */ -- cgit v1.1 From 09db4d37d204c03924912924a39f22891b125148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 17 Oct 2017 13:44:08 -0300 Subject: misc: remove old i386 dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Reviewed-by: Anthony PERARD Signed-off-by: Michael Tokarev --- hw/i386/xen/xen_platform.c | 1 - 1 file changed, 1 deletion(-) (limited to 'hw/i386') diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index 056b87d..fc8623c 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -26,7 +26,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "hw/hw.h" -#include "hw/i386/pc.h" #include "hw/ide.h" #include "hw/pci/pci.h" #include "hw/irq.h" -- cgit v1.1 From acf695eca605ed18fd485af3414e78d1edf93082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 17 Oct 2017 13:44:15 -0300 Subject: hw/timer/i8254: rename pit_init() -> i8254_pit_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and remove the old i386/pc dependency Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Hervé Poussineau Signed-off-by: Michael Tokarev --- hw/i386/pc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/i386') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 186545d..6a60415 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1573,7 +1573,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, if (kvm_pit_in_kernel()) { pit = kvm_pit_init(isa_bus, 0x40); } else { - pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq); + pit = i8254_pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq); } if (hpet) { /* connect PIT to output control line of the HPET */ -- cgit v1.1 From 6c646a11bf5ef87424fa07d3c42d04e709cd7c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 17 Oct 2017 13:44:16 -0300 Subject: hw/timer/mc146818: rename rtc_init() -> mc146818_rtc_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Hervé Poussineau Reviewed-by: David Gibson Signed-off-by: Michael Tokarev --- hw/i386/pc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/i386') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 6a60415..fe5e8b5 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1565,7 +1565,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, rtc_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_RTC_INT); } } - *rtc_state = rtc_init(isa_bus, 2000, rtc_irq); + *rtc_state = mc146818_rtc_init(isa_bus, 2000, rtc_irq); qemu_register_boot_set(pc_boot_set, *rtc_state); -- cgit v1.1 From 489983d6b4cb501a86dfd08648fb370aec0f9b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 17 Oct 2017 13:44:22 -0300 Subject: hw/net/ne2000: extract ne2k-isa code from i386/pc to ne2000-isa.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add "hw/net/ne2000-isa.h" - remove the old i386 dependency Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Hervé Poussineau Acked-by: David Gibson [PPC] Signed-off-by: Michael Tokarev --- hw/i386/pc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hw/i386') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index fe5e8b5..3fcf318 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -69,6 +69,7 @@ #include "qom/cpu.h" #include "hw/nmi.h" #include "hw/i386/intel_iommu.h" +#include "hw/net/ne2000-isa.h" /* debug PC/ISA interrupts */ //#define DEBUG_IRQ -- cgit v1.1 From 0d5d8a3a906f782eab8a85079eede78879dc8155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 17 Oct 2017 13:44:23 -0300 Subject: hw/misc/pvpanic: extract public API from i386/pc to "hw/misc/pvpanic.h" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and remove the old i386/pc dependency. Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Michael Tokarev --- hw/i386/acpi-build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/i386') diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index dd1420b..5a6dee0 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -28,8 +28,8 @@ #include "qemu/error-report.h" #include "hw/pci/pci.h" #include "qom/cpu.h" -#include "hw/i386/pc.h" #include "target/i386/cpu.h" +#include "hw/misc/pvpanic.h" #include "hw/timer/hpet.h" #include "hw/acpi/acpi-defs.h" #include "hw/acpi/acpi.h" -- cgit v1.1 From 323d7d1d999d8be31e4d5a50ee18f7e2ca5d096a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 17 Oct 2017 13:44:24 -0300 Subject: i386/pc: move vmport.c to hw/i386/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a x86-only device, so it does not make sense to keep it in the shared misc folder. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Signed-off-by: Michael Tokarev --- hw/i386/Makefile.objs | 1 + hw/i386/vmport.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 hw/i386/vmport.c (limited to 'hw/i386') diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 2e5e129..1548ad1 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -5,6 +5,7 @@ obj-y += pc_sysfw.o obj-y += x86-iommu.o intel_iommu.o obj-y += amd_iommu.o obj-$(CONFIG_XEN) += ../xenpv/ xen/ +obj-$(CONFIG_VMPORT) += vmport.o obj-y += kvmvapic.o obj-y += acpi-build.o diff --git a/hw/i386/vmport.c b/hw/i386/vmport.c new file mode 100644 index 0000000..eb880c6 --- /dev/null +++ b/hw/i386/vmport.c @@ -0,0 +1,182 @@ +/* + * QEMU VMPort emulation + * + * Copyright (C) 2007 Hervé Poussineau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "hw/isa/isa.h" +#include "hw/i386/pc.h" +#include "sysemu/hw_accel.h" +#include "hw/qdev.h" + +/* #define VMPORT_DEBUG */ + +#define VMPORT_CMD_GETVERSION 0x0a +#define VMPORT_CMD_GETRAMSIZE 0x14 + +#define VMPORT_ENTRIES 0x2c +#define VMPORT_MAGIC 0x564D5868 + +#define VMPORT(obj) OBJECT_CHECK(VMPortState, (obj), TYPE_VMPORT) + +typedef struct VMPortState { + ISADevice parent_obj; + + MemoryRegion io; + VMPortReadFunc *func[VMPORT_ENTRIES]; + void *opaque[VMPORT_ENTRIES]; +} VMPortState; + +static VMPortState *port_state; + +void vmport_register(unsigned char command, VMPortReadFunc *func, void *opaque) +{ + if (command >= VMPORT_ENTRIES) { + return; + } + + port_state->func[command] = func; + port_state->opaque[command] = opaque; +} + +static uint64_t vmport_ioport_read(void *opaque, hwaddr addr, + unsigned size) +{ + VMPortState *s = opaque; + CPUState *cs = current_cpu; + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; + unsigned char command; + uint32_t eax; + + cpu_synchronize_state(cs); + + eax = env->regs[R_EAX]; + if (eax != VMPORT_MAGIC) { + return eax; + } + + command = env->regs[R_ECX]; + if (command >= VMPORT_ENTRIES) { + return eax; + } + if (!s->func[command]) { +#ifdef VMPORT_DEBUG + fprintf(stderr, "vmport: unknown command %x\n", command); +#endif + return eax; + } + + return s->func[command](s->opaque[command], addr); +} + +static void vmport_ioport_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + X86CPU *cpu = X86_CPU(current_cpu); + + cpu->env.regs[R_EAX] = vmport_ioport_read(opaque, addr, 4); +} + +static uint32_t vmport_cmd_get_version(void *opaque, uint32_t addr) +{ + X86CPU *cpu = X86_CPU(current_cpu); + + cpu->env.regs[R_EBX] = VMPORT_MAGIC; + return 6; +} + +static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr) +{ + X86CPU *cpu = X86_CPU(current_cpu); + + cpu->env.regs[R_EBX] = 0x1177; + return ram_size; +} + +/* vmmouse helpers */ +void vmmouse_get_data(uint32_t *data) +{ + X86CPU *cpu = X86_CPU(current_cpu); + CPUX86State *env = &cpu->env; + + data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX]; + data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX]; + data[4] = env->regs[R_ESI]; data[5] = env->regs[R_EDI]; +} + +void vmmouse_set_data(const uint32_t *data) +{ + X86CPU *cpu = X86_CPU(current_cpu); + CPUX86State *env = &cpu->env; + + env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1]; + env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3]; + env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5]; +} + +static const MemoryRegionOps vmport_ops = { + .read = vmport_ioport_read, + .write = vmport_ioport_write, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void vmport_realizefn(DeviceState *dev, Error **errp) +{ + ISADevice *isadev = ISA_DEVICE(dev); + VMPortState *s = VMPORT(dev); + + memory_region_init_io(&s->io, OBJECT(s), &vmport_ops, s, "vmport", 1); + isa_register_ioport(isadev, &s->io, 0x5658); + + port_state = s; + /* Register some generic port commands */ + vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, NULL); + vmport_register(VMPORT_CMD_GETRAMSIZE, vmport_cmd_ram_size, NULL); +} + +static void vmport_class_initfn(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = vmport_realizefn; + /* Reason: realize sets global port_state */ + dc->user_creatable = false; +} + +static const TypeInfo vmport_info = { + .name = TYPE_VMPORT, + .parent = TYPE_ISA_DEVICE, + .instance_size = sizeof(VMPortState), + .class_init = vmport_class_initfn, +}; + +static void vmport_register_types(void) +{ + type_register_static(&vmport_info); +} + +type_init(vmport_register_types) -- cgit v1.1 From 664b4be5e8bcb538ae8e68fe54ff27fedc5ea5b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 17 Oct 2017 13:44:25 -0300 Subject: i386/pc: move vmmouse.c to hw/i386/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a x86-only device, so it does not make sense to keep it in the shared misc folder. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Signed-off-by: Michael Tokarev --- hw/i386/Makefile.objs | 1 + hw/i386/vmmouse.c | 303 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 304 insertions(+) create mode 100644 hw/i386/vmmouse.c (limited to 'hw/i386') diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 1548ad1..fd279e7 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -6,6 +6,7 @@ obj-y += x86-iommu.o intel_iommu.o obj-y += amd_iommu.o obj-$(CONFIG_XEN) += ../xenpv/ xen/ obj-$(CONFIG_VMPORT) += vmport.o +obj-$(CONFIG_VMMOUSE) += vmmouse.o obj-y += kvmvapic.o obj-y += acpi-build.o diff --git a/hw/i386/vmmouse.c b/hw/i386/vmmouse.c new file mode 100644 index 0000000..65ef553 --- /dev/null +++ b/hw/i386/vmmouse.c @@ -0,0 +1,303 @@ +/* + * QEMU VMMouse emulation + * + * Copyright (C) 2007 Anthony Liguori + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "ui/console.h" +#include "hw/i386/pc.h" +#include "hw/qdev.h" + +/* debug only vmmouse */ +//#define DEBUG_VMMOUSE + +/* VMMouse Commands */ +#define VMMOUSE_GETVERSION 10 +#define VMMOUSE_DATA 39 +#define VMMOUSE_STATUS 40 +#define VMMOUSE_COMMAND 41 + +#define VMMOUSE_READ_ID 0x45414552 +#define VMMOUSE_DISABLE 0x000000f5 +#define VMMOUSE_REQUEST_RELATIVE 0x4c455252 +#define VMMOUSE_REQUEST_ABSOLUTE 0x53424152 + +#define VMMOUSE_QUEUE_SIZE 1024 + +#define VMMOUSE_VERSION 0x3442554a + +#ifdef DEBUG_VMMOUSE +#define DPRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) +#else +#define DPRINTF(fmt, ...) do { } while (0) +#endif + +#define TYPE_VMMOUSE "vmmouse" +#define VMMOUSE(obj) OBJECT_CHECK(VMMouseState, (obj), TYPE_VMMOUSE) + +typedef struct VMMouseState +{ + ISADevice parent_obj; + + uint32_t queue[VMMOUSE_QUEUE_SIZE]; + int32_t queue_size; + uint16_t nb_queue; + uint16_t status; + uint8_t absolute; + QEMUPutMouseEntry *entry; + void *ps2_mouse; +} VMMouseState; + +static uint32_t vmmouse_get_status(VMMouseState *s) +{ + DPRINTF("vmmouse_get_status()\n"); + return (s->status << 16) | s->nb_queue; +} + +static void vmmouse_mouse_event(void *opaque, int x, int y, int dz, int buttons_state) +{ + VMMouseState *s = opaque; + int buttons = 0; + + if (s->nb_queue > (VMMOUSE_QUEUE_SIZE - 4)) + return; + + DPRINTF("vmmouse_mouse_event(%d, %d, %d, %d)\n", + x, y, dz, buttons_state); + + if ((buttons_state & MOUSE_EVENT_LBUTTON)) + buttons |= 0x20; + if ((buttons_state & MOUSE_EVENT_RBUTTON)) + buttons |= 0x10; + if ((buttons_state & MOUSE_EVENT_MBUTTON)) + buttons |= 0x08; + + if (s->absolute) { + x <<= 1; + y <<= 1; + } + + s->queue[s->nb_queue++] = buttons; + s->queue[s->nb_queue++] = x; + s->queue[s->nb_queue++] = y; + s->queue[s->nb_queue++] = dz; + + /* need to still generate PS2 events to notify driver to + read from queue */ + i8042_isa_mouse_fake_event(s->ps2_mouse); +} + +static void vmmouse_remove_handler(VMMouseState *s) +{ + if (s->entry) { + qemu_remove_mouse_event_handler(s->entry); + s->entry = NULL; + } +} + +static void vmmouse_update_handler(VMMouseState *s, int absolute) +{ + if (s->status != 0) { + return; + } + if (s->absolute != absolute) { + s->absolute = absolute; + vmmouse_remove_handler(s); + } + if (s->entry == NULL) { + s->entry = qemu_add_mouse_event_handler(vmmouse_mouse_event, + s, s->absolute, + "vmmouse"); + qemu_activate_mouse_event_handler(s->entry); + } +} + +static void vmmouse_read_id(VMMouseState *s) +{ + DPRINTF("vmmouse_read_id()\n"); + + if (s->nb_queue == VMMOUSE_QUEUE_SIZE) + return; + + s->queue[s->nb_queue++] = VMMOUSE_VERSION; + s->status = 0; +} + +static void vmmouse_request_relative(VMMouseState *s) +{ + DPRINTF("vmmouse_request_relative()\n"); + vmmouse_update_handler(s, 0); +} + +static void vmmouse_request_absolute(VMMouseState *s) +{ + DPRINTF("vmmouse_request_absolute()\n"); + vmmouse_update_handler(s, 1); +} + +static void vmmouse_disable(VMMouseState *s) +{ + DPRINTF("vmmouse_disable()\n"); + s->status = 0xffff; + vmmouse_remove_handler(s); +} + +static void vmmouse_data(VMMouseState *s, uint32_t *data, uint32_t size) +{ + int i; + + DPRINTF("vmmouse_data(%d)\n", size); + + if (size == 0 || size > 6 || size > s->nb_queue) { + printf("vmmouse: driver requested too much data %d\n", size); + s->status = 0xffff; + vmmouse_remove_handler(s); + return; + } + + for (i = 0; i < size; i++) + data[i] = s->queue[i]; + + s->nb_queue -= size; + if (s->nb_queue) + memmove(s->queue, &s->queue[size], sizeof(s->queue[0]) * s->nb_queue); +} + +static uint32_t vmmouse_ioport_read(void *opaque, uint32_t addr) +{ + VMMouseState *s = opaque; + uint32_t data[6]; + uint16_t command; + + vmmouse_get_data(data); + + command = data[2] & 0xFFFF; + + switch (command) { + case VMMOUSE_STATUS: + data[0] = vmmouse_get_status(s); + break; + case VMMOUSE_COMMAND: + switch (data[1]) { + case VMMOUSE_DISABLE: + vmmouse_disable(s); + break; + case VMMOUSE_READ_ID: + vmmouse_read_id(s); + break; + case VMMOUSE_REQUEST_RELATIVE: + vmmouse_request_relative(s); + break; + case VMMOUSE_REQUEST_ABSOLUTE: + vmmouse_request_absolute(s); + break; + default: + printf("vmmouse: unknown command %x\n", data[1]); + break; + } + break; + case VMMOUSE_DATA: + vmmouse_data(s, data, data[1]); + break; + default: + printf("vmmouse: unknown command %x\n", command); + break; + } + + vmmouse_set_data(data); + return data[0]; +} + +static int vmmouse_post_load(void *opaque, int version_id) +{ + VMMouseState *s = opaque; + + vmmouse_remove_handler(s); + vmmouse_update_handler(s, s->absolute); + return 0; +} + +static const VMStateDescription vmstate_vmmouse = { + .name = "vmmouse", + .version_id = 0, + .minimum_version_id = 0, + .post_load = vmmouse_post_load, + .fields = (VMStateField[]) { + VMSTATE_INT32_EQUAL(queue_size, VMMouseState, NULL), + VMSTATE_UINT32_ARRAY(queue, VMMouseState, VMMOUSE_QUEUE_SIZE), + VMSTATE_UINT16(nb_queue, VMMouseState), + VMSTATE_UINT16(status, VMMouseState), + VMSTATE_UINT8(absolute, VMMouseState), + VMSTATE_END_OF_LIST() + } +}; + +static void vmmouse_reset(DeviceState *d) +{ + VMMouseState *s = VMMOUSE(d); + + s->queue_size = VMMOUSE_QUEUE_SIZE; + + vmmouse_disable(s); +} + +static void vmmouse_realizefn(DeviceState *dev, Error **errp) +{ + VMMouseState *s = VMMOUSE(dev); + + DPRINTF("vmmouse_init\n"); + + vmport_register(VMMOUSE_STATUS, vmmouse_ioport_read, s); + vmport_register(VMMOUSE_COMMAND, vmmouse_ioport_read, s); + vmport_register(VMMOUSE_DATA, vmmouse_ioport_read, s); +} + +static Property vmmouse_properties[] = { + DEFINE_PROP_PTR("ps2_mouse", VMMouseState, ps2_mouse), + DEFINE_PROP_END_OF_LIST(), +}; + +static void vmmouse_class_initfn(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = vmmouse_realizefn; + dc->reset = vmmouse_reset; + dc->vmsd = &vmstate_vmmouse; + dc->props = vmmouse_properties; + /* Reason: pointer property "ps2_mouse" */ + dc->user_creatable = false; +} + +static const TypeInfo vmmouse_info = { + .name = TYPE_VMMOUSE, + .parent = TYPE_ISA_DEVICE, + .instance_size = sizeof(VMMouseState), + .class_init = vmmouse_class_initfn, +}; + +static void vmmouse_register_types(void) +{ + type_register_static(&vmmouse_info); +} + +type_init(vmmouse_register_types) -- cgit v1.1 From 7299e1a411de99761a4260e44b4f1cf2e4e126ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 15 Dec 2017 00:43:55 -0300 Subject: hw/i386/vmport: replace fprintf() by trace events or LOG_UNIMP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20171215034356.4449-2-f4bug@amsat.org> [Replace unknown command tracepoint with LOG_UNIMP, add generic tracepoint for vmport commands. - Paolo] Signed-off-by: Paolo Bonzini --- hw/i386/trace-events | 4 ++++ hw/i386/vmport.c | 14 +++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'hw/i386') diff --git a/hw/i386/trace-events b/hw/i386/trace-events index d43b4b6..22d4464 100644 --- a/hw/i386/trace-events +++ b/hw/i386/trace-events @@ -113,3 +113,7 @@ amdvi_mode_invalid(uint8_t level, uint64_t addr)"error: translation level 0x%"PR amdvi_page_fault(uint64_t addr) "error: page fault accessing guest physical address 0x%"PRIx64 amdvi_iotlb_hit(uint8_t bus, uint8_t slot, uint8_t func, uint64_t addr, uint64_t txaddr) "hit iotlb devid %02x:%02x.%x gpa 0x%"PRIx64" hpa 0x%"PRIx64 amdvi_translation_result(uint8_t bus, uint8_t slot, uint8_t func, uint64_t addr, uint64_t txaddr) "devid: %02x:%02x.%x gpa 0x%"PRIx64" hpa 0x%"PRIx64 + +# hw/i386/vmport.c +vmport_register(unsigned char command, void *func, void *opaque) "command: 0x%02x func: %p opaque: %p" +vmport_command(unsigned char command) "command: 0x%02x" diff --git a/hw/i386/vmport.c b/hw/i386/vmport.c index eb880c6..9b8c688 100644 --- a/hw/i386/vmport.c +++ b/hw/i386/vmport.c @@ -27,8 +27,7 @@ #include "hw/i386/pc.h" #include "sysemu/hw_accel.h" #include "hw/qdev.h" - -/* #define VMPORT_DEBUG */ +#include "trace.h" #define VMPORT_CMD_GETVERSION 0x0a #define VMPORT_CMD_GETRAMSIZE 0x14 @@ -54,6 +53,7 @@ void vmport_register(unsigned char command, VMPortReadFunc *func, void *opaque) return; } + trace_vmport_register(command, func, opaque); port_state->func[command] = func; port_state->opaque[command] = opaque; } @@ -76,13 +76,9 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr, } command = env->regs[R_ECX]; - if (command >= VMPORT_ENTRIES) { - return eax; - } - if (!s->func[command]) { -#ifdef VMPORT_DEBUG - fprintf(stderr, "vmport: unknown command %x\n", command); -#endif + trace_vmport_command(command); + if (command >= VMPORT_ENTRIES || !s->func[command]) { + qemu_log_mask(LOG_UNIMP, "vmport: unknown command %x\n", command); return eax; } -- cgit v1.1 From e267d16496e3998f271767a80ff9b0cc43be8a35 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Sun, 10 Dec 2017 14:38:18 +0800 Subject: kvm-i8259: support "info pic" and "info irq" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's leverage the i8259 common code for kvm-i8259 too. I think it's still possible that stats can lost when i8259 is in kernel and meanwhile when irqfd is used, e.g., by vfio or vhost devices. However that should be rare IMHO since they should be using MSIs mostly if they really want performance (that's why people use vhost and device assignment), and no old INTx should be used. As long as the INTx users are emulated in QEMU the stats will be correct. For "info pic", it should be always accurate since we fetch kvm regs before dump. More importantly, it's just too simple to do this now - it's only 10+ LOC to gain this feature. Signed-off-by: Peter Xu Message-Id: <20171210063819.14892-5-peterx@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Paolo Bonzini --- hw/i386/kvm/i8259.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'hw/i386') diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c index 11d1b72..57abe09 100644 --- a/hw/i386/kvm/i8259.c +++ b/hw/i386/kvm/i8259.c @@ -111,6 +111,7 @@ static void kvm_pic_set_irq(void *opaque, int irq, int level) { int delivered; + pic_stat_update_irq(irq, level); delivered = kvm_set_irq(kvm_state, irq, level); apic_report_irq_delivered(delivered); } @@ -139,12 +140,15 @@ static void kvm_i8259_class_init(ObjectClass *klass, void *data) KVMPICClass *kpc = KVM_PIC_CLASS(klass); PICCommonClass *k = PIC_COMMON_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); + InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass); dc->reset = kvm_pic_reset; kpc->parent_realize = dc->realize; dc->realize = kvm_pic_realize; k->pre_save = kvm_pic_get; k->post_load = kvm_pic_put; + ic->get_statistics = pic_get_statistics; + ic->print_info = pic_print_info; } static const TypeInfo kvm_i8259_info = { @@ -153,6 +157,10 @@ static const TypeInfo kvm_i8259_info = { .instance_size = sizeof(PICCommonState), .class_init = kvm_i8259_class_init, .class_size = sizeof(KVMPICClass), + .interfaces = (InterfaceInfo[]) { + { TYPE_INTERRUPT_STATS_PROVIDER }, + { } + }, }; static void kvm_pic_register_types(void) -- cgit v1.1 From b8c7723440324a7822acdb0b6f35c7ccb791862a Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Sun, 10 Dec 2017 14:38:19 +0800 Subject: i8259: move TYPE_INTERRUPT_STATS_PROVIDER upper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now both classes (i8259, i8259-kvm) support this. Move this upper to the common class code. Signed-off-by: Peter Xu Message-Id: <20171210063819.14892-6-peterx@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Paolo Bonzini --- hw/i386/kvm/i8259.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'hw/i386') diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c index 57abe09..b91e980 100644 --- a/hw/i386/kvm/i8259.c +++ b/hw/i386/kvm/i8259.c @@ -140,15 +140,12 @@ static void kvm_i8259_class_init(ObjectClass *klass, void *data) KVMPICClass *kpc = KVM_PIC_CLASS(klass); PICCommonClass *k = PIC_COMMON_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass); dc->reset = kvm_pic_reset; kpc->parent_realize = dc->realize; dc->realize = kvm_pic_realize; k->pre_save = kvm_pic_get; k->post_load = kvm_pic_put; - ic->get_statistics = pic_get_statistics; - ic->print_info = pic_print_info; } static const TypeInfo kvm_i8259_info = { @@ -157,10 +154,6 @@ static const TypeInfo kvm_i8259_info = { .instance_size = sizeof(PICCommonState), .class_init = kvm_i8259_class_init, .class_size = sizeof(KVMPICClass), - .interfaces = (InterfaceInfo[]) { - { TYPE_INTERRUPT_STATS_PROVIDER }, - { } - }, }; static void kvm_pic_register_types(void) -- cgit v1.1 From 43ab9a5376c95c61ae898a222c4d04bdf60e239b Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Thu, 21 Dec 2017 22:11:03 +0100 Subject: hw/i386/vmport: fix missing definitions with non-log trace backends When compiled with anything other than the 'log' trace backend, we have: error: implicit declaration of function 'qemu_log_mask' error: 'LOG_UNIMP' undeclared (first use in this function) This patch adds the missing include. Fixes: 7299e1a411 ("hw/i386/vmport: replace fprintf() by trace events or LOG_UNIMP") Signed-off-by: Laurent Vivier Message-id: 20171221211103.30311-1-laurent@vivier.eu [PMM: fixed commit message description of when problem occurs] Signed-off-by: Peter Maydell --- hw/i386/vmport.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hw/i386') diff --git a/hw/i386/vmport.c b/hw/i386/vmport.c index 9b8c688..116aa09 100644 --- a/hw/i386/vmport.c +++ b/hw/i386/vmport.c @@ -27,6 +27,7 @@ #include "hw/i386/pc.h" #include "sysemu/hw_accel.h" #include "hw/qdev.h" +#include "qemu/log.h" #include "trace.h" #define VMPORT_CMD_GETVERSION 0x0a -- cgit v1.1 From 4a42fa0ee20b51b326f6494cb50218b52471a261 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Tue, 14 Nov 2017 13:42:42 -0500 Subject: acpi: Update TPM2 ACPI table to more recent specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More recent specs of the TPM2 ACPI table add fields for the log area start address and the log area minimum size, which we already use for the TCPA table. Signed-off-by: Stefan Berger Reviewed-by: Marc-André Lureau --- hw/i386/acpi-build.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'hw/i386') diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 5a6dee0..18b939e 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2274,16 +2274,25 @@ build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog) } static void -build_tpm2(GArray *table_data, BIOSLinker *linker) +build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog) { - Acpi20TPM2 *tpm2_ptr; - - tpm2_ptr = acpi_data_push(table_data, sizeof *tpm2_ptr); + Acpi20TPM2 *tpm2_ptr = acpi_data_push(table_data, sizeof *tpm2_ptr); + unsigned log_addr_size = sizeof(tpm2_ptr->log_area_start_address); + unsigned log_addr_offset = + (char *)&tpm2_ptr->log_area_start_address - table_data->data; tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT); if (TPM_IS_TIS(tpm_find())) { tpm2_ptr->control_area_address = cpu_to_le64(0); tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO); + + tpm2_ptr->log_area_minimum_length = + cpu_to_le32(TPM_LOG_AREA_MINIMUM_SIZE); + + /* log area start address to be filled by Guest linker */ + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, log_addr_offset, log_addr_size, + ACPI_BUILD_TPMLOG_FILE, 0); } else { g_warn_if_reached(); } @@ -2695,7 +2704,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) if (misc.tpm_version == TPM_VERSION_2_0) { acpi_add_table(table_offsets, tables_blob); - build_tpm2(tables_blob, tables->linker); + build_tpm2(tables_blob, tables->linker, tables->tcpalog); } } if (pcms->numa_nodes) { -- cgit v1.1