From 2f448e415f364d0ec4c5556993e44ca183e31c5c Mon Sep 17 00:00:00 2001 From: Alyssa Milburn Date: Thu, 4 Feb 2016 18:40:57 +0000 Subject: hw: fix some debug message format strings Signed-off-by: Alyssa Milburn Signed-off-by: David Gibson --- hw/nvram/mac_nvram.c | 6 ++++-- hw/pci-host/uninorth.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c index 564ef936d1..1671f4686e 100644 --- a/hw/nvram/mac_nvram.c +++ b/hw/nvram/mac_nvram.c @@ -49,7 +49,8 @@ static void macio_nvram_writeb(void *opaque, hwaddr addr, addr = (addr >> s->it_shift) & (s->size - 1); s->data[addr] = value; - NVR_DPRINTF("writeb addr %04" PHYS_PRIx " val %" PRIx64 "\n", addr, value); + NVR_DPRINTF("writeb addr %04" HWADDR_PRIx " val %" PRIx64 "\n", + addr, value); } static uint64_t macio_nvram_readb(void *opaque, hwaddr addr, @@ -60,7 +61,8 @@ static uint64_t macio_nvram_readb(void *opaque, hwaddr addr, addr = (addr >> s->it_shift) & (s->size - 1); value = s->data[addr]; - NVR_DPRINTF("readb addr %04x val %x\n", (int)addr, value); + NVR_DPRINTF("readb addr %04" HWADDR_PRIx " val %" PRIx32 "\n", + addr, value); return value; } diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 40a2e3e6b4..15b1054232 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -120,7 +120,7 @@ static void unin_data_write(void *opaque, hwaddr addr, { UNINState *s = opaque; PCIHostState *phb = PCI_HOST_BRIDGE(s); - UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n", + UNIN_DPRINTF("write addr " TARGET_FMT_plx " len %d val %"PRIx64"\n", addr, len, val); pci_data_write(phb->bus, unin_get_config_reg(phb->config_reg, addr), @@ -137,7 +137,7 @@ static uint64_t unin_data_read(void *opaque, hwaddr addr, val = pci_data_read(phb->bus, unin_get_config_reg(phb->config_reg, addr), len); - UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n", + UNIN_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n", addr, len, val); return val; } -- cgit v1.2.3 From b7f0bbd2590a22be4c707e27f85e2334158e83aa Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 9 Feb 2016 09:28:25 +1000 Subject: target-ppc: Remove unused kvmppc_update_sdr1() stub This KVM stub implementation isn't used anywhere. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- target-ppc/kvm_ppc.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 62406ce4e1..aaa828c055 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -184,11 +184,6 @@ static inline uint64_t kvmppc_rma_size(uint64_t current_size, return ram_size; } -static inline int kvmppc_update_sdr1(CPUPPCState *env) -{ - return 0; -} - #endif /* !CONFIG_USER_ONLY */ static inline bool kvmppc_has_cap_epr(void) -- cgit v1.2.3 From 808bc3b069fdb5fc660f89e6bc7774eeefdc97ea Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 9 Feb 2016 09:28:43 +1000 Subject: target-ppc: Include missing MMU models for SDR1 in info registers The HMP command "info registers" produces somewhat different information on different ppc cpu variants. For those with a hash MMU it's supposed to include the SDR1, DAR and DSISR registers related to the MMU. However, the switch is missing a couple of MMU model variants, meaning we will miss out this information on certain CPUs which should have it. This patch corrects the oversight. (Really these MMU model IDs need a big cleanup, but we might as well fix the bug in the interim). Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- target-ppc/translate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index ffef754fe0..ecc85f0e6d 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -11352,7 +11352,9 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, case POWERPC_MMU_64B: case POWERPC_MMU_2_03: case POWERPC_MMU_2_06: + case POWERPC_MMU_2_06a: case POWERPC_MMU_2_07: + case POWERPC_MMU_2_07a: #endif cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " DAR " TARGET_FMT_lx " DSISR " TARGET_FMT_lx "\n", env->spr[SPR_SDR1], -- cgit v1.2.3 From 715c54071a43ab978dc12b9da22a5016203ed284 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 9 Feb 2016 09:28:58 +1000 Subject: pseries: Simplify handling of the hash page table fd When migrating the 'pseries' machine type with KVM, we use a special fd to access the hash page table stored within KVM. Usually, this fd is opened at the beginning of migration, and kept open until the migration is complete. However, if there is a guest reset during the migration, the fd can become stale and we need to re-open it. At the moment we use an 'htab_fd_stale' flag in sPAPRMachineState to signal this, which is checked in the migration iterators. But that's rather ugly. It's simpler to just close and invalidate the fd on reset, and lazily re-open it in migration if necessary. This patch implements that change. This requires a small addition to the machine state's instance_init, so that htab_fd is initialized to -1 (telling the migration code it needs to open it) instead of 0, which could be a valid fd. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 86 ++++++++++++++++++++++++-------------------------- include/hw/ppc/spapr.h | 1 - 2 files changed, 41 insertions(+), 46 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5bd8fd3ef8..c3157154e0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1024,6 +1024,32 @@ static void emulate_spapr_hypercall(PowerPCCPU *cpu) #define CLEAN_HPTE(_hpte) ((*(uint64_t *)(_hpte)) &= tswap64(~HPTE64_V_HPTE_DIRTY)) #define DIRTY_HPTE(_hpte) ((*(uint64_t *)(_hpte)) |= tswap64(HPTE64_V_HPTE_DIRTY)) +/* + * Get the fd to access the kernel htab, re-opening it if necessary + */ +static int get_htab_fd(sPAPRMachineState *spapr) +{ + if (spapr->htab_fd >= 0) { + return spapr->htab_fd; + } + + spapr->htab_fd = kvmppc_get_htab_fd(false); + if (spapr->htab_fd < 0) { + error_report("Unable to open fd for reading hash table from KVM: %s", + strerror(errno)); + } + + return spapr->htab_fd; +} + +static void close_htab_fd(sPAPRMachineState *spapr) +{ + if (spapr->htab_fd >= 0) { + close(spapr->htab_fd); + } + spapr->htab_fd = -1; +} + static void spapr_alloc_htab(sPAPRMachineState *spapr) { long shift; @@ -1085,10 +1111,7 @@ static void spapr_reset_htab(sPAPRMachineState *spapr) error_setg(&error_abort, "Requested HTAB allocation failed during reset"); } - /* Tell readers to update their file descriptor */ - if (spapr->htab_fd >= 0) { - spapr->htab_fd_stale = true; - } + close_htab_fd(spapr); } else { memset(spapr->htab, 0, HTAB_SIZE(spapr)); @@ -1121,28 +1144,6 @@ static int find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque) return 0; } -/* - * A guest reset will cause spapr->htab_fd to become stale if being used. - * Reopen the file descriptor to make sure the whole HTAB is properly read. - */ -static int spapr_check_htab_fd(sPAPRMachineState *spapr) -{ - int rc = 0; - - if (spapr->htab_fd_stale) { - close(spapr->htab_fd); - spapr->htab_fd = kvmppc_get_htab_fd(false); - if (spapr->htab_fd < 0) { - error_report("Unable to open fd for reading hash table from KVM: " - "%s", strerror(errno)); - rc = -1; - } - spapr->htab_fd_stale = false; - } - - return rc; -} - static void ppc_spapr_reset(void) { sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); @@ -1313,14 +1314,6 @@ static int htab_save_setup(QEMUFile *f, void *opaque) spapr->htab_first_pass = true; } else { assert(kvm_enabled()); - - spapr->htab_fd = kvmppc_get_htab_fd(false); - spapr->htab_fd_stale = false; - if (spapr->htab_fd < 0) { - fprintf(stderr, "Unable to open fd for reading hash table from KVM: %s\n", - strerror(errno)); - return -1; - } } @@ -1460,6 +1453,7 @@ static int htab_save_later_pass(QEMUFile *f, sPAPRMachineState *spapr, static int htab_save_iterate(QEMUFile *f, void *opaque) { sPAPRMachineState *spapr = opaque; + int fd; int rc = 0; /* Iteration header */ @@ -1468,13 +1462,12 @@ static int htab_save_iterate(QEMUFile *f, void *opaque) if (!spapr->htab) { assert(kvm_enabled()); - rc = spapr_check_htab_fd(spapr); - if (rc < 0) { - return rc; + fd = get_htab_fd(spapr); + if (fd < 0) { + return fd; } - rc = kvmppc_save_htab(f, spapr->htab_fd, - MAX_KVM_BUF_SIZE, MAX_ITERATION_NS); + rc = kvmppc_save_htab(f, fd, MAX_KVM_BUF_SIZE, MAX_ITERATION_NS); if (rc < 0) { return rc; } @@ -1495,6 +1488,7 @@ static int htab_save_iterate(QEMUFile *f, void *opaque) static int htab_save_complete(QEMUFile *f, void *opaque) { sPAPRMachineState *spapr = opaque; + int fd; /* Iteration header */ qemu_put_be32(f, 0); @@ -1504,17 +1498,16 @@ static int htab_save_complete(QEMUFile *f, void *opaque) assert(kvm_enabled()); - rc = spapr_check_htab_fd(spapr); - if (rc < 0) { - return rc; + fd = get_htab_fd(spapr); + if (fd < 0) { + return fd; } - rc = kvmppc_save_htab(f, spapr->htab_fd, MAX_KVM_BUF_SIZE, -1); + rc = kvmppc_save_htab(f, fd, MAX_KVM_BUF_SIZE, -1); if (rc < 0) { return rc; } - close(spapr->htab_fd); - spapr->htab_fd = -1; + close_htab_fd(spapr); } else { htab_save_later_pass(f, spapr, -1); } @@ -2125,6 +2118,9 @@ static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp) static void spapr_machine_initfn(Object *obj) { + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + + spapr->htab_fd = -1; object_property_add_str(obj, "kvm-type", spapr_get_kvm_type, spapr_set_kvm_type, NULL); object_property_set_description(obj, "kvm-type", diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 1f9e722545..098d85d1a1 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -72,7 +72,6 @@ struct sPAPRMachineState { int htab_save_index; bool htab_first_pass; int htab_fd; - bool htab_fd_stale; /* RTAS state */ QTAILQ_HEAD(, sPAPRConfigureConnectorState) ccs_list; -- cgit v1.2.3 From 8dfe8e7f4facef400ef1c220f29196ae5cfc526c Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 9 Feb 2016 10:15:12 +1000 Subject: pseries: Add helper to calculate recommended hash page table size At present we calculate the recommended hash page table (HPT) size for a pseries guest just once in ppc_spapr_init() before allocating the HPT. In future patches we're going to want this calculation in other places, so this splits it out into a helper function. While we're at it, change the calculation to use ctz() instead of an explicit loop. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c3157154e0..2a81e8f8a9 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1050,6 +1050,19 @@ static void close_htab_fd(sPAPRMachineState *spapr) spapr->htab_fd = -1; } +static int spapr_hpt_shift_for_ramsize(uint64_t ramsize) +{ + int shift; + + /* We aim for a hash table of size 1/128 the size of RAM (rounded + * up). The PAPR recommendation is actually 1/64 of RAM size, but + * that's much more than is needed for Linux guests */ + shift = ctz64(pow2ceil(ramsize)) - 7; + shift = MAX(shift, 18); /* Minimum architected size */ + shift = MIN(shift, 46); /* Maximum architected size */ + return shift; +} + static void spapr_alloc_htab(sPAPRMachineState *spapr) { long shift; @@ -1790,16 +1803,7 @@ static void ppc_spapr_init(MachineState *machine) /* Setup a load limit for the ramdisk leaving room for SLOF and FDT */ load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD; - /* We aim for a hash table of size 1/128 the size of RAM. The - * normal rule of thumb is 1/64 the size of RAM, but that's much - * more than needed for the Linux guests we support. */ - spapr->htab_shift = 18; /* Minimum architected size */ - while (spapr->htab_shift <= 46) { - if ((1ULL << (spapr->htab_shift + 7)) >= machine->maxram_size) { - break; - } - spapr->htab_shift++; - } + spapr->htab_shift = spapr_hpt_shift_for_ramsize(machine->maxram_size); spapr_alloc_htab(spapr); /* Set up Interrupt Controller before we create the VCPUs */ -- cgit v1.2.3 From c5f54f3e31bf693f70a98d4d73ea5dbe05689857 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 9 Feb 2016 10:21:56 +1000 Subject: pseries: Move hash page table allocation to reset time At the moment the size of the hash page table (HPT) is fixed based on the maximum memory allowed to the guest. As such, we allocate the table during machine construction, and just clear it at reset. However, we're planning to implement a PAPR extension allowing the hash page table to be resized at runtime. This will mean that on reset we want to revert it to the default size. It also means that when migrating, we need to make sure the destination allocates an HPT of size matching the host, since the guest could have changed it before the migration. This patch replaces the spapr_alloc_htab() and spapr_reset_htab() functions with a new spapr_reallocate_hpt() function. This is called at reset and inbound migration only, not during machine init any more. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 130 +++++++++++++++++++++++++-------------------------------- 1 file changed, 56 insertions(+), 74 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 2a81e8f8a9..907439a95b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1063,81 +1063,55 @@ static int spapr_hpt_shift_for_ramsize(uint64_t ramsize) return shift; } -static void spapr_alloc_htab(sPAPRMachineState *spapr) -{ - long shift; - int index; - - /* allocate hash page table. For now we always make this 16mb, - * later we should probably make it scale to the size of guest - * RAM */ - - shift = kvmppc_reset_htab(spapr->htab_shift); - if (shift < 0) { - /* - * For HV KVM, host kernel will return -ENOMEM when requested - * HTAB size can't be allocated. - */ - error_setg(&error_abort, "Failed to allocate HTAB of requested size, try with smaller maxmem"); - } else if (shift > 0) { - /* - * Kernel handles htab, we don't need to allocate one - * - * Older kernels can fall back to lower HTAB shift values, - * but we don't allow booting of such guests. - */ - if (shift != spapr->htab_shift) { - error_setg(&error_abort, "Failed to allocate HTAB of requested size, try with smaller maxmem"); +static void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift, + Error **errp) +{ + long rc; + + /* Clean up any HPT info from a previous boot */ + g_free(spapr->htab); + spapr->htab = NULL; + spapr->htab_shift = 0; + close_htab_fd(spapr); + + rc = kvmppc_reset_htab(shift); + if (rc < 0) { + /* kernel-side HPT needed, but couldn't allocate one */ + error_setg_errno(errp, errno, + "Failed to allocate KVM HPT of order %d (try smaller maxmem?)", + shift); + /* This is almost certainly fatal, but if the caller really + * wants to carry on with shift == 0, it's welcome to try */ + } else if (rc > 0) { + /* kernel-side HPT allocated */ + if (rc != shift) { + error_setg(errp, + "Requested order %d HPT, but kernel allocated order %ld (try smaller maxmem?)", + shift, rc); } spapr->htab_shift = shift; kvmppc_kern_htab = true; } else { - /* Allocate htab */ - spapr->htab = qemu_memalign(HTAB_SIZE(spapr), HTAB_SIZE(spapr)); - - /* And clear it */ - memset(spapr->htab, 0, HTAB_SIZE(spapr)); - - for (index = 0; index < HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; index++) { - DIRTY_HPTE(HPTE(spapr->htab, index)); - } - } -} - -/* - * Clear HTAB entries during reset. - * - * If host kernel has allocated HTAB, KVM_PPC_ALLOCATE_HTAB ioctl is - * used to clear HTAB. Otherwise QEMU-allocated HTAB is cleared manually. - */ -static void spapr_reset_htab(sPAPRMachineState *spapr) -{ - long shift; - int index; + /* kernel-side HPT not needed, allocate in userspace instead */ + size_t size = 1ULL << shift; + int i; - shift = kvmppc_reset_htab(spapr->htab_shift); - if (shift < 0) { - error_setg(&error_abort, "Failed to reset HTAB"); - } else if (shift > 0) { - if (shift != spapr->htab_shift) { - error_setg(&error_abort, "Requested HTAB allocation failed during reset"); + spapr->htab = qemu_memalign(size, size); + if (!spapr->htab) { + error_setg_errno(errp, errno, + "Could not allocate HPT of order %d", shift); + return; } - close_htab_fd(spapr); - } else { - memset(spapr->htab, 0, HTAB_SIZE(spapr)); + memset(spapr->htab, 0, size); + spapr->htab_shift = shift; + kvmppc_kern_htab = false; - for (index = 0; index < HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; index++) { - DIRTY_HPTE(HPTE(spapr->htab, index)); + for (i = 0; i < size / HASH_PTE_SIZE_64; i++) { + DIRTY_HPTE(HPTE(spapr->htab, i)); } } - - /* Update the RMA size if necessary */ - if (spapr->vrma_adjust) { - spapr->rma_size = kvmppc_rma_size(spapr_node0_size(), - spapr->htab_shift); - } } static int find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque) @@ -1159,15 +1133,24 @@ static int find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque) static void ppc_spapr_reset(void) { - sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + MachineState *machine = MACHINE(qdev_get_machine()); + sPAPRMachineState *spapr = SPAPR_MACHINE(machine); PowerPCCPU *first_ppc_cpu; uint32_t rtas_limit; /* Check for unknown sysbus devices */ foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL); - /* Reset the hash table & recalc the RMA */ - spapr_reset_htab(spapr); + /* Allocate and/or reset the hash page table */ + spapr_reallocate_hpt(spapr, + spapr_hpt_shift_for_ramsize(machine->maxram_size), + &error_fatal); + + /* Update the RMA size if necessary */ + if (spapr->vrma_adjust) { + spapr->rma_size = kvmppc_rma_size(spapr_node0_size(), + spapr->htab_shift); + } qemu_devices_reset(); @@ -1547,10 +1530,12 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id) section_hdr = qemu_get_be32(f); if (section_hdr) { - /* First section, just the hash shift */ - if (spapr->htab_shift != section_hdr) { - error_report("htab_shift mismatch: source %d target %d", - section_hdr, spapr->htab_shift); + Error *local_err; + + /* First section gives the htab size */ + spapr_reallocate_hpt(spapr, section_hdr, &local_err); + if (local_err) { + error_report_err(local_err); return -EINVAL; } return 0; @@ -1803,9 +1788,6 @@ static void ppc_spapr_init(MachineState *machine) /* Setup a load limit for the ramdisk leaving room for SLOF and FDT */ load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD; - spapr->htab_shift = spapr_hpt_shift_for_ramsize(machine->maxram_size); - spapr_alloc_htab(spapr); - /* Set up Interrupt Controller before we create the VCPUs */ spapr->icp = xics_system_init(machine, DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(), -- cgit v1.2.3 From fa48b4328c39b2532e47efcfcba6d4031512f514 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 9 Feb 2016 09:30:21 +1000 Subject: target-ppc: Remove hack for ppc_hash64_load_hpte*() with HV KVM With HV KVM, the guest's hash page table (HPT) is managed by the kernel and not directly accessible to QEMU. This means that spapr->htab is NULL and normally env->external_htab would also be NULL for each cpu. However, that would cause ppc_hash64_load_hpte*() to do the wrong thing in the few cases where QEMU does need to load entries from the in-kernel HPT. Specifically, seeing external_htab is NULL, they would look for an HPT within the guest's address space instead. To stop that we have an ugly hack in the pseries machine type code to set external htab to (void *)1 instead. This patch removes that hack by having ppc_hash64_load_hpte*() explicitly check kvmppc_kern_htab instead, which makes more sense. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 7 ------- target-ppc/mmu-hash64.h | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 907439a95b..c85a12547f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1197,13 +1197,6 @@ static void spapr_cpu_reset(void *opaque) env->spr[SPR_HIOR] = 0; env->external_htab = (uint8_t *)spapr->htab; - if (kvm_enabled() && !env->external_htab) { - /* - * HV KVM, set external_htab to 1 so our ppc_hash64_load_hpte* - * functions do the right thing. - */ - env->external_htab = (void *)1; - } env->htab_base = -1; /* * htab_mask is the mask used to normalize hash value to PTEG index. diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h index ab0f86b222..e7d9925411 100644 --- a/target-ppc/mmu-hash64.h +++ b/target-ppc/mmu-hash64.h @@ -102,7 +102,7 @@ static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU *cpu, uint64_t addr; addr = token + (index * HASH_PTE_SIZE_64); - if (env->external_htab) { + if (kvmppc_kern_htab || env->external_htab) { return ldq_p((const void *)(uintptr_t)addr); } else { return ldq_phys(CPU(cpu)->as, addr); @@ -116,7 +116,7 @@ static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU *cpu, uint64_t addr; addr = token + (index * HASH_PTE_SIZE_64) + HASH_PTE_SIZE_64/2; - if (env->external_htab) { + if (kvmppc_kern_htab || env->external_htab) { return ldq_p((const void *)(uintptr_t)addr); } else { return ldq_phys(CPU(cpu)->as, addr); -- cgit v1.2.3 From 378bc21756f016abfde16a0de4977be49f499b1c Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 11 Feb 2016 10:40:44 +1000 Subject: migration: ensure htab_save_first completes after timeout htab_save_first_pass could return without finishing its work due to timeout. The patch checks if another invocation of it is necessary and will call it in htab_save_complete if necessary. Signed-off-by: Jianjun Duan Reviewed-by: Michael Roth [removed overlong line] Signed-off-by: David Gibson --- hw/ppc/spapr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c85a12547f..276d6b4ceb 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1312,6 +1312,7 @@ static int htab_save_setup(QEMUFile *f, void *opaque) static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr, int64_t max_ns) { + bool has_timeout = max_ns != -1; int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; int index = spapr->htab_save_index; int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); @@ -1345,7 +1346,8 @@ static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr, qemu_put_buffer(f, HPTE(spapr->htab, chunkstart), HASH_PTE_SIZE_64 * n_valid); - if ((qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) { + if (has_timeout && + (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) { break; } } @@ -1498,6 +1500,9 @@ static int htab_save_complete(QEMUFile *f, void *opaque) } close_htab_fd(spapr); } else { + if (spapr->htab_first_pass) { + htab_save_first_pass(f, spapr, -1); + } htab_save_later_pass(f, spapr, -1); } -- cgit v1.2.3 From 423576f771db8c6dbb944ddb8dc15b472f62de4a Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 11 Feb 2016 13:47:18 +0100 Subject: hw/ppc/spapr: Add h_set_sprg0 hypercall This is a very simple hypercall that only sets up the SPRG0 register for the guest (since writing to SPRG0 was only permitted to the hypervisor in older versions of the PowerISA). Signed-off-by: Thomas Huth Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 12f8c33db7..63f41ece66 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -332,6 +332,15 @@ static target_ulong h_read(PowerPCCPU *cpu, sPAPRMachineState *spapr, return H_SUCCESS; } +static target_ulong h_set_sprg0(PowerPCCPU *cpu, sPAPRMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + cpu_synchronize_state(CPU(cpu)); + cpu->env.spr[SPR_SPRG0] = args[0]; + + return H_SUCCESS; +} + static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { @@ -997,6 +1006,10 @@ static void hypercall_register_types(void) spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa); spapr_register_hypercall(H_CEDE, h_cede); + /* processor register resource access h-calls */ + spapr_register_hypercall(H_SET_SPRG0, h_set_sprg0); + spapr_register_hypercall(H_SET_MODE, h_set_mode); + /* "debugger" hcalls (also used by SLOF). Note: We do -not- differenciate * here between the "CI" and the "CACHE" variants, they will use whatever * mapping attributes qemu is using. When using KVM, the kernel will @@ -1013,8 +1026,6 @@ static void hypercall_register_types(void) /* qemu/KVM-PPC specific hcalls */ spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas); - spapr_register_hypercall(H_SET_MODE, h_set_mode); - /* ibm,client-architecture-support support */ spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support); } -- cgit v1.2.3 From af08a58f0ca338eafee855921859a8c1ace0175b Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 11 Feb 2016 13:47:19 +0100 Subject: hw/ppc/spapr: Implement h_set_dabr According to LoPAPR, h_set_dabr should simply set DABRX to 3 (if the register is available), and load the parameter into DABR. If DABRX is not available, the hypervisor has to check the "Breakpoint Translation" bit of the DABR register first. Signed-off-by: Thomas Huth Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 63f41ece66..0004ca5885 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -38,6 +38,12 @@ static void set_spr(CPUState *cs, int spr, target_ulong value, run_on_cpu(cs, do_spr_sync, &s); } +static bool has_spr(PowerPCCPU *cpu, int spr) +{ + /* We can test whether the SPR is defined by checking for a valid name */ + return cpu->env.spr_cb[spr].name != NULL; +} + static inline bool valid_pte_index(CPUPPCState *env, target_ulong pte_index) { /* @@ -344,8 +350,19 @@ static target_ulong h_set_sprg0(PowerPCCPU *cpu, sPAPRMachineState *spapr, static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { - /* FIXME: actually implement this */ - return H_HARDWARE; + if (!has_spr(cpu, SPR_DABR)) { + return H_HARDWARE; /* DABR register not available */ + } + cpu_synchronize_state(CPU(cpu)); + + if (has_spr(cpu, SPR_DABRX)) { + cpu->env.spr[SPR_DABRX] = 0x3; /* Use Problem and Privileged state */ + } else if (!(args[0] & 0x4)) { /* Breakpoint Translation set? */ + return H_RESERVED_DABR; + } + + cpu->env.spr[SPR_DABR] = args[0]; + return H_SUCCESS; } #define FLAGS_REGISTER_VPA 0x0000200000000000ULL @@ -999,15 +1016,13 @@ static void hypercall_register_types(void) /* hcall-bulk */ spapr_register_hypercall(H_BULK_REMOVE, h_bulk_remove); - /* hcall-dabr */ - spapr_register_hypercall(H_SET_DABR, h_set_dabr); - /* hcall-splpar */ spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa); spapr_register_hypercall(H_CEDE, h_cede); /* processor register resource access h-calls */ spapr_register_hypercall(H_SET_SPRG0, h_set_sprg0); + spapr_register_hypercall(H_SET_DABR, h_set_dabr); spapr_register_hypercall(H_SET_MODE, h_set_mode); /* "debugger" hcalls (also used by SLOF). Note: We do -not- differenciate -- cgit v1.2.3 From e49ff266f8ade3f3a21ec48d13ecf4a77b1c8572 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 11 Feb 2016 13:47:20 +0100 Subject: hw/ppc/spapr: Implement the h_set_xdabr hypercall The H_SET_XDABR hypercall is similar to H_SET_DABR, but also sets the extended DABR (DABRX) register. Signed-off-by: Thomas Huth Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 0004ca5885..6e9b6be58c 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -365,6 +365,27 @@ static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPRMachineState *spapr, return H_SUCCESS; } +static target_ulong h_set_xdabr(PowerPCCPU *cpu, sPAPRMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + target_ulong dabrx = args[1]; + + if (!has_spr(cpu, SPR_DABR) || !has_spr(cpu, SPR_DABRX)) { + return H_HARDWARE; + } + + if ((dabrx & ~0xfULL) != 0 || (dabrx & H_DABRX_HYPERVISOR) != 0 + || (dabrx & (H_DABRX_KERNEL | H_DABRX_USER)) == 0) { + return H_PARAMETER; + } + + cpu_synchronize_state(CPU(cpu)); + cpu->env.spr[SPR_DABRX] = dabrx; + cpu->env.spr[SPR_DABR] = args[0]; + + return H_SUCCESS; +} + #define FLAGS_REGISTER_VPA 0x0000200000000000ULL #define FLAGS_REGISTER_DTL 0x0000400000000000ULL #define FLAGS_REGISTER_SLBSHADOW 0x0000600000000000ULL @@ -1023,6 +1044,7 @@ static void hypercall_register_types(void) /* processor register resource access h-calls */ spapr_register_hypercall(H_SET_SPRG0, h_set_sprg0); spapr_register_hypercall(H_SET_DABR, h_set_dabr); + spapr_register_hypercall(H_SET_XDABR, h_set_xdabr); spapr_register_hypercall(H_SET_MODE, h_set_mode); /* "debugger" hcalls (also used by SLOF). Note: We do -not- differenciate -- cgit v1.2.3 From d20efaeb13c95059f07c9d15c512b2e538142471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:04 +0100 Subject: cuda: add a framework to handle commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Next commits will port existing CUDA commands to this framework. Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 316c1ac8da..8659dc3ea4 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -535,13 +535,47 @@ static void cuda_adb_poll(void *opaque) (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ)); } +/* description of commands */ +typedef struct CudaCommand { + uint8_t command; + const char *name; + bool (*handler)(CUDAState *s, + const uint8_t *in_args, int in_len, + uint8_t *out_args, int *out_len); +} CudaCommand; + +static const CudaCommand handlers[] = { +}; + static void cuda_receive_packet(CUDAState *s, const uint8_t *data, int len) { uint8_t obuf[16] = { CUDA_PACKET, 0, data[0] }; int autopoll; + int i, out_len = 0; uint32_t ti; + for (i = 0; i < ARRAY_SIZE(handlers); i++) { + const CudaCommand *desc = &handlers[i]; + if (desc->command == data[0]) { + CUDA_DPRINTF("handling command %s\n", desc->name); + out_len = 0; + if (desc->handler(s, data + 1, len - 1, obuf + 3, &out_len)) { + cuda_send_packet_to_host(s, obuf, 3 + out_len); + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "CUDA: %s: wrong parameters %d\n", + desc->name, len); + obuf[0] = ERROR_PACKET; + obuf[1] = 0x5; /* bad parameters */ + obuf[2] = CUDA_PACKET; + obuf[3] = data[0]; + cuda_send_packet_to_host(s, obuf, 4); + } + return; + } + } + switch(data[0]) { case CUDA_AUTOPOLL: autopoll = (data[1] != 0); -- cgit v1.2.3 From 0e8176e80953ada5b255988aa7226e14eb66ff95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:05 +0100 Subject: cuda: move unknown commands reject out of switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 8659dc3ea4..81e34e76b6 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -590,15 +590,15 @@ static void cuda_receive_packet(CUDAState *s, } } cuda_send_packet_to_host(s, obuf, 3); - break; + return; case CUDA_GET_6805_ADDR: cuda_send_packet_to_host(s, obuf, 3); - break; + return; case CUDA_SET_TIME: ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + (((uint32_t)data[3]) << 8) + data[4]; s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec()); cuda_send_packet_to_host(s, obuf, 3); - break; + return; case CUDA_GET_TIME: ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec()); obuf[3] = ti >> 24; @@ -606,28 +606,28 @@ static void cuda_receive_packet(CUDAState *s, obuf[5] = ti >> 8; obuf[6] = ti; cuda_send_packet_to_host(s, obuf, 7); - break; + return; case CUDA_FILE_SERVER_FLAG: case CUDA_SET_DEVICE_LIST: case CUDA_SET_AUTO_RATE: case CUDA_SET_POWER_MESSAGES: cuda_send_packet_to_host(s, obuf, 3); - break; + return; case CUDA_POWERDOWN: cuda_send_packet_to_host(s, obuf, 3); qemu_system_shutdown_request(); - break; + return; case CUDA_RESET_SYSTEM: cuda_send_packet_to_host(s, obuf, 3); qemu_system_reset_request(); - break; + return; case CUDA_COMBINED_FORMAT_IIC: obuf[0] = ERROR_PACKET; obuf[1] = 0x5; obuf[2] = CUDA_PACKET; obuf[3] = data[0]; cuda_send_packet_to_host(s, obuf, 4); - break; + return; case CUDA_GET_SET_IIC: if (len == 4) { cuda_send_packet_to_host(s, obuf, 3); @@ -638,15 +638,17 @@ static void cuda_receive_packet(CUDAState *s, obuf[3] = data[0]; cuda_send_packet_to_host(s, obuf, 4); } - break; + return; default: - obuf[0] = ERROR_PACKET; - obuf[1] = 0x2; - obuf[2] = CUDA_PACKET; - obuf[3] = data[0]; - cuda_send_packet_to_host(s, obuf, 4); break; } + + qemu_log_mask(LOG_GUEST_ERROR, "CUDA: unknown command 0x%02x\n", data[0]); + obuf[0] = ERROR_PACKET; + obuf[1] = 0x2; /* unknown command */ + obuf[2] = CUDA_PACKET; + obuf[3] = data[0]; + cuda_send_packet_to_host(s, obuf, 4); } static void cuda_receive_packet_from_host(CUDAState *s, -- cgit v1.2.3 From 1cdab104468d900c1ed0a2e689b944ec8e2d12d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:06 +0100 Subject: cuda: port AUTOPOLL command to new framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: David Gibson Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 81e34e76b6..ea4237a2da 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -544,14 +544,38 @@ typedef struct CudaCommand { uint8_t *out_args, int *out_len); } CudaCommand; +static bool cuda_cmd_autopoll(CUDAState *s, + const uint8_t *in_data, int in_len, + uint8_t *out_data, int *out_len) +{ + int autopoll; + + if (in_len != 1) { + return false; + } + + autopoll = (in_data[0] != 0); + if (autopoll != s->autopoll) { + s->autopoll = autopoll; + if (autopoll) { + timer_mod(s->adb_poll_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ)); + } else { + timer_del(s->adb_poll_timer); + } + } + return true; +} + static const CudaCommand handlers[] = { + { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll }, }; static void cuda_receive_packet(CUDAState *s, const uint8_t *data, int len) { uint8_t obuf[16] = { CUDA_PACKET, 0, data[0] }; - int autopoll; int i, out_len = 0; uint32_t ti; @@ -577,20 +601,6 @@ static void cuda_receive_packet(CUDAState *s, } switch(data[0]) { - case CUDA_AUTOPOLL: - autopoll = (data[1] != 0); - if (autopoll != s->autopoll) { - s->autopoll = autopoll; - if (autopoll) { - timer_mod(s->adb_poll_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ)); - } else { - timer_del(s->adb_poll_timer); - } - } - cuda_send_packet_to_host(s, obuf, 3); - return; case CUDA_GET_6805_ADDR: cuda_send_packet_to_host(s, obuf, 3); return; -- cgit v1.2.3 From 374312e7c5cd04e29a5a6279dd7006a4a94c0f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:07 +0100 Subject: cuda: port SET_AUTO_RATE command to new framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also implement the command, by removing the hardcoded period of 20 ms/50 Hz and replacing it by the one requested by user. Update VMState version to store this new parameter. Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 36 ++++++++++++++++++++++++++++++------ hw/ppc/mac.h | 1 + 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index ea4237a2da..71fd97c8a2 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -106,7 +106,6 @@ #define CUDA_COMBINED_FORMAT_IIC 0x25 #define CUDA_TIMER_FREQ (4700000 / 6) -#define CUDA_ADB_POLL_FREQ 50 /* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */ #define RTC_OFFSET 2082844800 @@ -532,7 +531,7 @@ static void cuda_adb_poll(void *opaque) } timer_mod(s->adb_poll_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ)); + (get_ticks_per_sec() / (1000 / s->autopoll_rate_ms))); } /* description of commands */ @@ -560,7 +559,7 @@ static bool cuda_cmd_autopoll(CUDAState *s, if (autopoll) { timer_mod(s->adb_poll_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ)); + (get_ticks_per_sec() / (1000 / s->autopoll_rate_ms))); } else { timer_del(s->adb_poll_timer); } @@ -568,8 +567,32 @@ static bool cuda_cmd_autopoll(CUDAState *s, return true; } +static bool cuda_cmd_set_autorate(CUDAState *s, + const uint8_t *in_data, int in_len, + uint8_t *out_data, int *out_len) +{ + if (in_len != 1) { + return false; + } + + /* we don't want a period of 0 ms */ + /* FIXME: check what real hardware does */ + if (in_data[0] == 0) { + return false; + } + + s->autopoll_rate_ms = in_data[0]; + if (s->autopoll) { + timer_mod(s->adb_poll_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (get_ticks_per_sec() / (1000 / s->autopoll_rate_ms))); + } + return true; +} + static const CudaCommand handlers[] = { { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll }, + { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE", cuda_cmd_set_autorate }, }; static void cuda_receive_packet(CUDAState *s, @@ -619,7 +642,6 @@ static void cuda_receive_packet(CUDAState *s, return; case CUDA_FILE_SERVER_FLAG: case CUDA_SET_DEVICE_LIST: - case CUDA_SET_AUTO_RATE: case CUDA_SET_POWER_MESSAGES: cuda_send_packet_to_host(s, obuf, 3); return; @@ -756,8 +778,8 @@ static const VMStateDescription vmstate_cuda_timer = { static const VMStateDescription vmstate_cuda = { .name = "cuda", - .version_id = 3, - .minimum_version_id = 3, + .version_id = 4, + .minimum_version_id = 4, .fields = (VMStateField[]) { VMSTATE_UINT8(a, CUDAState), VMSTATE_UINT8(b, CUDAState), @@ -775,6 +797,7 @@ static const VMStateDescription vmstate_cuda = { VMSTATE_INT32(data_in_index, CUDAState), VMSTATE_INT32(data_out_index, CUDAState), VMSTATE_UINT8(autopoll, CUDAState), + VMSTATE_UINT8(autopoll_rate_ms, CUDAState), VMSTATE_BUFFER(data_in, CUDAState), VMSTATE_BUFFER(data_out, CUDAState), VMSTATE_UINT32(tick_offset, CUDAState), @@ -828,6 +851,7 @@ static void cuda_realizefn(DeviceState *dev, Error **errp) s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET; s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s); + s->autopoll_rate_ms = 20; } static void cuda_initfn(Object *obj) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index ecf7792bc9..887c8c182b 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -111,6 +111,7 @@ typedef struct CUDAState { int data_out_index; qemu_irq irq; + uint8_t autopoll_rate_ms; uint8_t autopoll; uint8_t data_in[128]; uint8_t data_out[16]; -- cgit v1.2.3 From 216c906e62626acc82427a00e9410ff39d9669a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:08 +0100 Subject: cuda: port SET_DEVICE_LIST command to new framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also implement the command, by taking device list mask into account when polling ADB devices. Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/input/adb.c | 18 ++++++++++-------- hw/misc/macio/cuda.c | 18 ++++++++++++++++-- hw/ppc/mac.h | 1 + include/hw/input/adb.h | 2 +- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/hw/input/adb.c b/hw/input/adb.c index c384856c13..f0ad0d4471 100644 --- a/hw/input/adb.c +++ b/hw/input/adb.c @@ -89,7 +89,7 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len) } /* XXX: move that to cuda ? */ -int adb_poll(ADBBusState *s, uint8_t *obuf) +int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask) { ADBDevice *d; int olen, i; @@ -100,13 +100,15 @@ int adb_poll(ADBBusState *s, uint8_t *obuf) if (s->poll_index >= s->nb_devices) s->poll_index = 0; d = s->devices[s->poll_index]; - buf[0] = ADB_READREG | (d->devaddr << 4); - olen = adb_request(s, obuf + 1, buf, 1); - /* if there is data, we poll again the same device */ - if (olen > 0) { - obuf[0] = buf[0]; - olen++; - break; + if ((1 << d->devaddr) & poll_mask) { + buf[0] = ADB_READREG | (d->devaddr << 4); + olen = adb_request(s, obuf + 1, buf, 1); + /* if there is data, we poll again the same device */ + if (olen > 0) { + obuf[0] = buf[0]; + olen++; + break; + } } s->poll_index++; } diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 71fd97c8a2..a2e31d0473 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -523,7 +523,7 @@ static void cuda_adb_poll(void *opaque) uint8_t obuf[ADB_MAX_OUT_LEN + 2]; int olen; - olen = adb_poll(&s->adb_bus, obuf + 2); + olen = adb_poll(&s->adb_bus, obuf + 2, s->adb_poll_mask); if (olen > 0) { obuf[0] = ADB_PACKET; obuf[1] = 0x40; /* polled data */ @@ -590,9 +590,22 @@ static bool cuda_cmd_set_autorate(CUDAState *s, return true; } +static bool cuda_cmd_set_device_list(CUDAState *s, + const uint8_t *in_data, int in_len, + uint8_t *out_data, int *out_len) +{ + if (in_len != 2) { + return false; + } + + s->adb_poll_mask = (((uint16_t)in_data[0]) << 8) | in_data[1]; + return true; +} + static const CudaCommand handlers[] = { { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll }, { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE", cuda_cmd_set_autorate }, + { CUDA_SET_DEVICE_LIST, "SET_DEVICE_LIST", cuda_cmd_set_device_list }, }; static void cuda_receive_packet(CUDAState *s, @@ -641,7 +654,6 @@ static void cuda_receive_packet(CUDAState *s, cuda_send_packet_to_host(s, obuf, 7); return; case CUDA_FILE_SERVER_FLAG: - case CUDA_SET_DEVICE_LIST: case CUDA_SET_POWER_MESSAGES: cuda_send_packet_to_host(s, obuf, 3); return; @@ -798,6 +810,7 @@ static const VMStateDescription vmstate_cuda = { VMSTATE_INT32(data_out_index, CUDAState), VMSTATE_UINT8(autopoll, CUDAState), VMSTATE_UINT8(autopoll_rate_ms, CUDAState), + VMSTATE_UINT16(adb_poll_mask, CUDAState), VMSTATE_BUFFER(data_in, CUDAState), VMSTATE_BUFFER(data_out, CUDAState), VMSTATE_UINT32(tick_offset, CUDAState), @@ -852,6 +865,7 @@ static void cuda_realizefn(DeviceState *dev, Error **errp) s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s); s->autopoll_rate_ms = 20; + s->adb_poll_mask = 0xffff; } static void cuda_initfn(Object *obj) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 887c8c182b..5764b86c28 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -111,6 +111,7 @@ typedef struct CUDAState { int data_out_index; qemu_irq irq; + uint16_t adb_poll_mask; uint8_t autopoll_rate_ms; uint8_t autopoll; uint8_t data_in[128]; diff --git a/include/hw/input/adb.h b/include/hw/input/adb.h index bdfccd4041..db51d03804 100644 --- a/include/hw/input/adb.h +++ b/include/hw/input/adb.h @@ -79,7 +79,7 @@ struct ADBBusState { int adb_request(ADBBusState *s, uint8_t *buf_out, const uint8_t *buf, int len); -int adb_poll(ADBBusState *s, uint8_t *buf_out); +int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask); #define TYPE_ADB_KEYBOARD "adb-keyboard" #define TYPE_ADB_MOUSE "adb-mouse" -- cgit v1.2.3 From 017da0b568073fd34bce85ec2e2507d45b04aedf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:09 +0100 Subject: cuda: port POWERDOWN command to new framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: David Gibson Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index a2e31d0473..9948e18424 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -602,10 +602,23 @@ static bool cuda_cmd_set_device_list(CUDAState *s, return true; } +static bool cuda_cmd_powerdown(CUDAState *s, + const uint8_t *in_data, int in_len, + uint8_t *out_data, int *out_len) +{ + if (in_len != 0) { + return false; + } + + qemu_system_shutdown_request(); + return true; +} + static const CudaCommand handlers[] = { { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll }, { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE", cuda_cmd_set_autorate }, { CUDA_SET_DEVICE_LIST, "SET_DEVICE_LIST", cuda_cmd_set_device_list }, + { CUDA_POWERDOWN, "POWERDOWN", cuda_cmd_powerdown }, }; static void cuda_receive_packet(CUDAState *s, @@ -657,10 +670,6 @@ static void cuda_receive_packet(CUDAState *s, case CUDA_SET_POWER_MESSAGES: cuda_send_packet_to_host(s, obuf, 3); return; - case CUDA_POWERDOWN: - cuda_send_packet_to_host(s, obuf, 3); - qemu_system_shutdown_request(); - return; case CUDA_RESET_SYSTEM: cuda_send_packet_to_host(s, obuf, 3); qemu_system_reset_request(); -- cgit v1.2.3 From 54e894442e971667f2a19d4808e8f64a953dbbbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:10 +0100 Subject: cuda: port RESET_SYSTEM command to new framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: David Gibson Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 9948e18424..ca11fc8b9b 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -614,11 +614,24 @@ static bool cuda_cmd_powerdown(CUDAState *s, return true; } +static bool cuda_cmd_reset_system(CUDAState *s, + const uint8_t *in_data, int in_len, + uint8_t *out_data, int *out_len) +{ + if (in_len != 0) { + return false; + } + + qemu_system_reset_request(); + return true; +} + static const CudaCommand handlers[] = { { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll }, { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE", cuda_cmd_set_autorate }, { CUDA_SET_DEVICE_LIST, "SET_DEVICE_LIST", cuda_cmd_set_device_list }, { CUDA_POWERDOWN, "POWERDOWN", cuda_cmd_powerdown }, + { CUDA_RESET_SYSTEM, "RESET_SYSTEM", cuda_cmd_reset_system }, }; static void cuda_receive_packet(CUDAState *s, @@ -670,10 +683,6 @@ static void cuda_receive_packet(CUDAState *s, case CUDA_SET_POWER_MESSAGES: cuda_send_packet_to_host(s, obuf, 3); return; - case CUDA_RESET_SYSTEM: - cuda_send_packet_to_host(s, obuf, 3); - qemu_system_reset_request(); - return; case CUDA_COMBINED_FORMAT_IIC: obuf[0] = ERROR_PACKET; obuf[1] = 0x5; -- cgit v1.2.3 From f5b941120e242e10af829c05f20276533dc3bac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:11 +0100 Subject: cuda: port FILE_SERVER_FLAG command to new framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This command tells if computer should automatically wake-up after a power loss. Reviewed-by: David Gibson Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index ca11fc8b9b..4ddec34621 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -626,12 +626,28 @@ static bool cuda_cmd_reset_system(CUDAState *s, return true; } +static bool cuda_cmd_set_file_server_flag(CUDAState *s, + const uint8_t *in_data, int in_len, + uint8_t *out_data, int *out_len) +{ + if (in_len != 1) { + return false; + } + + qemu_log_mask(LOG_UNIMP, + "CUDA: unimplemented command FILE_SERVER_FLAG %d\n", + in_data[0]); + return true; +} + static const CudaCommand handlers[] = { { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll }, { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE", cuda_cmd_set_autorate }, { CUDA_SET_DEVICE_LIST, "SET_DEVICE_LIST", cuda_cmd_set_device_list }, { CUDA_POWERDOWN, "POWERDOWN", cuda_cmd_powerdown }, { CUDA_RESET_SYSTEM, "RESET_SYSTEM", cuda_cmd_reset_system }, + { CUDA_FILE_SERVER_FLAG, "FILE_SERVER_FLAG", + cuda_cmd_set_file_server_flag }, }; static void cuda_receive_packet(CUDAState *s, @@ -679,7 +695,6 @@ static void cuda_receive_packet(CUDAState *s, obuf[6] = ti; cuda_send_packet_to_host(s, obuf, 7); return; - case CUDA_FILE_SERVER_FLAG: case CUDA_SET_POWER_MESSAGES: cuda_send_packet_to_host(s, obuf, 3); return; -- cgit v1.2.3 From 15b7b09b1d8a6b809f976a1f963923f1fa07d5af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:12 +0100 Subject: cuda: port SET_POWER_MESSAGES command to new framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: David Gibson Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 4ddec34621..16f9ad6100 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -640,6 +640,20 @@ static bool cuda_cmd_set_file_server_flag(CUDAState *s, return true; } +static bool cuda_cmd_set_power_message(CUDAState *s, + const uint8_t *in_data, int in_len, + uint8_t *out_data, int *out_len) +{ + if (in_len != 1) { + return false; + } + + qemu_log_mask(LOG_UNIMP, + "CUDA: unimplemented command SET_POWER_MESSAGE %d\n", + in_data[0]); + return true; +} + static const CudaCommand handlers[] = { { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll }, { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE", cuda_cmd_set_autorate }, @@ -648,6 +662,8 @@ static const CudaCommand handlers[] = { { CUDA_RESET_SYSTEM, "RESET_SYSTEM", cuda_cmd_reset_system }, { CUDA_FILE_SERVER_FLAG, "FILE_SERVER_FLAG", cuda_cmd_set_file_server_flag }, + { CUDA_SET_POWER_MESSAGES, "SET_POWER_MESSAGES", + cuda_cmd_set_power_message }, }; static void cuda_receive_packet(CUDAState *s, @@ -695,9 +711,6 @@ static void cuda_receive_packet(CUDAState *s, obuf[6] = ti; cuda_send_packet_to_host(s, obuf, 7); return; - case CUDA_SET_POWER_MESSAGES: - cuda_send_packet_to_host(s, obuf, 3); - return; case CUDA_COMBINED_FORMAT_IIC: obuf[0] = ERROR_PACKET; obuf[1] = 0x5; -- cgit v1.2.3 From 547a4d1969ce9d385ecfbda6f0d3ea627b4e5d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:13 +0100 Subject: cuda: port GET_TIME command to new framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: David Gibson Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 16f9ad6100..8ee1414193 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -654,6 +654,26 @@ static bool cuda_cmd_set_power_message(CUDAState *s, return true; } +static bool cuda_cmd_get_time(CUDAState *s, + const uint8_t *in_data, int in_len, + uint8_t *out_data, int *out_len) +{ + uint32_t ti; + + if (in_len != 0) { + return false; + } + + ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + / get_ticks_per_sec()); + out_data[0] = ti >> 24; + out_data[1] = ti >> 16; + out_data[2] = ti >> 8; + out_data[3] = ti; + *out_len = 4; + return true; +} + static const CudaCommand handlers[] = { { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll }, { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE", cuda_cmd_set_autorate }, @@ -664,6 +684,7 @@ static const CudaCommand handlers[] = { cuda_cmd_set_file_server_flag }, { CUDA_SET_POWER_MESSAGES, "SET_POWER_MESSAGES", cuda_cmd_set_power_message }, + { CUDA_GET_TIME, "GET_TIME", cuda_cmd_get_time }, }; static void cuda_receive_packet(CUDAState *s, @@ -703,14 +724,6 @@ static void cuda_receive_packet(CUDAState *s, s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec()); cuda_send_packet_to_host(s, obuf, 3); return; - case CUDA_GET_TIME: - ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec()); - obuf[3] = ti >> 24; - obuf[4] = ti >> 16; - obuf[5] = ti >> 8; - obuf[6] = ti; - cuda_send_packet_to_host(s, obuf, 7); - return; case CUDA_COMBINED_FORMAT_IIC: obuf[0] = ERROR_PACKET; obuf[1] = 0x5; -- cgit v1.2.3 From e6473178920685da3215813a959fb747976a2b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:14 +0100 Subject: cuda: port SET_TIME command to new framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: David Gibson Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 8ee1414193..611b4140f6 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -674,6 +674,23 @@ static bool cuda_cmd_get_time(CUDAState *s, return true; } +static bool cuda_cmd_set_time(CUDAState *s, + const uint8_t *in_data, int in_len, + uint8_t *out_data, int *out_len) +{ + uint32_t ti; + + if (in_len != 4) { + return false; + } + + ti = (((uint32_t)in_data[1]) << 24) + (((uint32_t)in_data[2]) << 16) + + (((uint32_t)in_data[3]) << 8) + in_data[4]; + s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + / get_ticks_per_sec()); + return true; +} + static const CudaCommand handlers[] = { { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll }, { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE", cuda_cmd_set_autorate }, @@ -685,6 +702,7 @@ static const CudaCommand handlers[] = { { CUDA_SET_POWER_MESSAGES, "SET_POWER_MESSAGES", cuda_cmd_set_power_message }, { CUDA_GET_TIME, "GET_TIME", cuda_cmd_get_time }, + { CUDA_SET_TIME, "SET_TIME", cuda_cmd_set_time }, }; static void cuda_receive_packet(CUDAState *s, @@ -692,7 +710,6 @@ static void cuda_receive_packet(CUDAState *s, { uint8_t obuf[16] = { CUDA_PACKET, 0, data[0] }; int i, out_len = 0; - uint32_t ti; for (i = 0; i < ARRAY_SIZE(handlers); i++) { const CudaCommand *desc = &handlers[i]; @@ -719,11 +736,6 @@ static void cuda_receive_packet(CUDAState *s, case CUDA_GET_6805_ADDR: cuda_send_packet_to_host(s, obuf, 3); return; - case CUDA_SET_TIME: - ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + (((uint32_t)data[3]) << 8) + data[4]; - s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec()); - cuda_send_packet_to_host(s, obuf, 3); - return; case CUDA_COMBINED_FORMAT_IIC: obuf[0] = ERROR_PACKET; obuf[1] = 0x5; -- cgit v1.2.3 From e230d43e80267073e5a405500372a93cb0cf9599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:15 +0100 Subject: cuda: remove GET_6805_ADDR command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It doesn't seem to be used, and operating systems should accept a 'unknown command' answer. Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 611b4140f6..d65a36a912 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -733,9 +733,6 @@ static void cuda_receive_packet(CUDAState *s, } switch(data[0]) { - case CUDA_GET_6805_ADDR: - cuda_send_packet_to_host(s, obuf, 3); - return; case CUDA_COMBINED_FORMAT_IIC: obuf[0] = ERROR_PACKET; obuf[1] = 0x5; -- cgit v1.2.3 From e4d162d72f6202ac50284307cfcab8fb6a996e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 7 Feb 2016 21:34:16 +0100 Subject: cuda: remove CUDA_GET_SET_IIC/CUDA_COMBINED_FORMAT_IIC commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We currently don't emulate the I2C bus provided by CUDA. Signed-off-by: Hervé Poussineau Reviewed-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index d65a36a912..481abdb754 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -732,29 +732,6 @@ static void cuda_receive_packet(CUDAState *s, } } - switch(data[0]) { - case CUDA_COMBINED_FORMAT_IIC: - obuf[0] = ERROR_PACKET; - obuf[1] = 0x5; - obuf[2] = CUDA_PACKET; - obuf[3] = data[0]; - cuda_send_packet_to_host(s, obuf, 4); - return; - case CUDA_GET_SET_IIC: - if (len == 4) { - cuda_send_packet_to_host(s, obuf, 3); - } else { - obuf[0] = ERROR_PACKET; - obuf[1] = 0x2; - obuf[2] = CUDA_PACKET; - obuf[3] = data[0]; - cuda_send_packet_to_host(s, obuf, 4); - } - return; - default: - break; - } - qemu_log_mask(LOG_GUEST_ERROR, "CUDA: unknown command 0x%02x\n", data[0]); obuf[0] = ERROR_PACKET; obuf[1] = 0x2; /* unknown command */ -- cgit v1.2.3 From 1c81003accd70e79f1663ad4429435b4d3300d62 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 17 Feb 2016 10:25:37 +1100 Subject: pseries: Include missing pseries-2.5 compat properties in pseries-2.4 Commit 4b23699 "pseries: Add pseries-2.6 machine type" added a new SPAPR_COMPAT_2_5 macro in the usual way. However, it didn't add this macro to the existing SPAPR_COMPAT_2_4 macro so that pseries-2.4 inherits newer compatibility properties which are needed for 2.5 and earlier. This corrects the oversight. Reported-by: Laszlo Ersek Signed-off-by: David Gibson Reviewed-by: Laszlo Ersek Reviewed-by: Laurent Vivier --- hw/ppc/spapr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 276d6b4ceb..e214a34257 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2391,6 +2391,7 @@ DEFINE_SPAPR_MACHINE(2_5, "2.5", false); * pseries-2.4 */ #define SPAPR_COMPAT_2_4 \ + SPAPR_COMPAT_2_5 \ HW_COMPAT_2_4 static void spapr_machine_2_4_instance_options(MachineState *machine) -- cgit v1.2.3 From 8a9c1b77e9df5b4a9fcc1ffe08b4fcff7b0c791f Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 17 Feb 2016 19:23:19 +0100 Subject: hw/ppc/spapr: Halt CPU when powering off via RTAS call The LoPAPR specification defines the following for the RTAS power-off call: "On successful operation, does not return". However, the implementation in QEMU currently returns and runs the guest CPU again for some more cycles. This caused some trouble with the new ppc implementation of the kvm-unit-tests recently. So let's make sure that the QEMU implementation follows the spec, thus stop the CPU to make sure that the RTAS call does not return to the guest anymore. Signed-off-by: Thomas Huth Tested-by: Andrew Jones Signed-off-by: David Gibson --- hw/ppc/spapr_rtas.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 07ad672e5a..b7c5ebde40 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -113,6 +113,7 @@ static void rtas_power_off(PowerPCCPU *cpu, sPAPRMachineState *spapr, return; } qemu_system_shutdown_request(); + cpu_stop_current(); rtas_st(rets, 0, RTAS_OUT_SUCCESS); } -- cgit v1.2.3