diff options
author | Justin M. Forbes <jforbes@redhat.com> | 2012-02-01 11:24:47 -0600 |
---|---|---|
committer | Justin M. Forbes <jforbes@redhat.com> | 2012-02-01 11:24:47 -0600 |
commit | 102dd9167c121d09c78d6b98da0ff8ed1001590a (patch) | |
tree | d1b7bef952720fd5f6d43102387a3ae57425dc94 | |
parent | d0ed2d2e8e863a9a64c9fc9c08fa68bee546ad00 (diff) | |
parent | d928541b51731a185214924cc5b44cd28020fa4f (diff) |
Merge branch 'ppc-1.0' of git://repo.or.cz/qemu/agraf
-rw-r--r-- | console.c | 4 | ||||
-rw-r--r-- | hw/ppce500_spin.c | 1 | ||||
-rw-r--r-- | hw/spapr.c | 2 | ||||
-rw-r--r-- | hw/spapr_pci.c | 2 | ||||
-rw-r--r-- | hw/spapr_vio.c | 84 | ||||
-rw-r--r-- | hw/spapr_vio.h | 3 | ||||
-rw-r--r-- | hw/spapr_vty.c | 47 | ||||
-rw-r--r-- | target-ppc/kvm.c | 14 |
8 files changed, 138 insertions, 19 deletions
@@ -186,7 +186,9 @@ void vga_hw_screen_dump(const char *filename) consoles[0]->hw_screen_dump(consoles[0]->hw, filename); } - console_select(previous_active_console->index); + if (previous_active_console) { + console_select(previous_active_console->index); + } } void vga_hw_text_update(console_ch_t *chardata) diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c index cccd94073a..2b527282b6 100644 --- a/hw/ppce500_spin.c +++ b/hw/ppce500_spin.c @@ -112,6 +112,7 @@ static void spin_kick(void *data) env->halted = 0; env->exception_index = -1; + env->stopped = 0; qemu_cpu_kick(env); } diff --git a/hw/spapr.c b/hw/spapr.c index 2b901f105e..5a98d8651f 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -351,6 +351,8 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr, fprintf(stderr, "Couldn't set up RTAS device tree properties\n"); } + spapr_populate_chosen_stdout(fdt, spapr->vio_bus); + _FDT((fdt_pack(fdt))); cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt)); diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 7162588543..9b6a032cce 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -454,7 +454,7 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb, reg[0].size = 0; n = 0; - for (i = 0; i < PCI_NUM_REGIONS; ++i) { + for (i = 0; i < ARRAY_SIZE(bars); ++i) { if (0 == dev->io_regions[i].size) { continue; } diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c index 2dcc0361ed..464fe87442 100644 --- a/hw/spapr_vio.c +++ b/hw/spapr_vio.c @@ -749,21 +749,95 @@ static void spapr_vio_register_devices(void) device_init(spapr_vio_register_devices) #ifdef CONFIG_FDT +static int compare_reg(const void *p1, const void *p2) +{ + VIOsPAPRDevice const *dev1, *dev2; + + dev1 = (VIOsPAPRDevice *)*(DeviceState **)p1; + dev2 = (VIOsPAPRDevice *)*(DeviceState **)p2; + + if (dev1->reg < dev2->reg) { + return -1; + } + if (dev1->reg == dev2->reg) { + return 0; + } + + /* dev1->reg > dev2->reg */ + return 1; +} + int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt) { - DeviceState *qdev; - int ret = 0; + DeviceState *qdev, **qdevs; + int i, num, ret = 0; + /* Count qdevs on the bus list */ + num = 0; QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { - VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev; + num++; + } + + /* Copy out into an array of pointers */ + qdevs = g_malloc(sizeof(qdev) * num); + num = 0; + QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { + qdevs[num++] = qdev; + } + + /* Sort the array */ + qsort(qdevs, num, sizeof(qdev), compare_reg); + + /* Hack alert. Give the devices to libfdt in reverse order, we happen + * to know that will mean they are in forward order in the tree. */ + for (i = num - 1; i >= 0; i--) { + VIOsPAPRDevice *dev = (VIOsPAPRDevice *)(qdevs[i]); ret = vio_make_devnode(dev, fdt); if (ret < 0) { - return ret; + goto out; } } - return 0; + ret = 0; +out: + free(qdevs); + + return ret; +} + +int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus) +{ + VIOsPAPRDevice *dev; + char *name, *path; + int ret, offset; + + dev = spapr_vty_get_default(bus); + if (!dev) + return 0; + + offset = fdt_path_offset(fdt, "/chosen"); + if (offset < 0) { + return offset; + } + + name = vio_format_dev_name(dev); + if (!name) { + return -ENOMEM; + } + + if (asprintf(&path, "/vdevice/%s", name) < 0) { + path = NULL; + ret = -ENOMEM; + goto out; + } + + ret = fdt_setprop_string(fdt, offset, "linux,stdout-path", path); +out: + free(name); + free(path); + + return ret; } #endif /* CONFIG_FDT */ diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h index a325a5f4b3..9fcd304adc 100644 --- a/hw/spapr_vio.h +++ b/hw/spapr_vio.h @@ -83,6 +83,7 @@ extern VIOsPAPRBus *spapr_vio_bus_init(void); extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg); extern void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info); extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt); +extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus); extern int spapr_vio_signal(VIOsPAPRDevice *dev, target_ulong mode); @@ -108,6 +109,8 @@ void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev); void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd); void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg); +VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus); + int spapr_tce_set_bypass(uint32_t unit, uint32_t enable); void spapr_vio_quiesce(void); diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c index f23cc36231..386ccf7206 100644 --- a/hw/spapr_vty.c +++ b/hw/spapr_vty.c @@ -156,24 +156,53 @@ static VIOsPAPRDeviceInfo spapr_vty = { }, }; +VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus) +{ + VIOsPAPRDevice *sdev, *selected; + DeviceState *iter; + + /* + * To avoid the console bouncing around we want one VTY to be + * the "default". We haven't really got anything to go on, so + * arbitrarily choose the one with the lowest reg value. + */ + + selected = NULL; + QTAILQ_FOREACH(iter, &bus->bus.children, sibling) { + /* Only look at VTY devices */ + if (iter->info != &spapr_vty.qdev) { + continue; + } + + sdev = DO_UPCAST(VIOsPAPRDevice, qdev, iter); + + /* First VTY we've found, so it is selected for now */ + if (!selected) { + selected = sdev; + continue; + } + + /* Choose VTY with lowest reg value */ + if (sdev->reg < selected->reg) { + selected = sdev; + } + } + + return selected; +} + static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg) { VIOsPAPRDevice *sdev; sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); if (!sdev && reg == 0) { - DeviceState *qdev; - /* Hack for kernel early debug, which always specifies reg==0. - * We search all VIO devices, and grab the first available vty - * device. This attempts to mimic existing PowerVM behaviour + * We search all VIO devices, and grab the vty with the lowest + * reg. This attempts to mimic existing PowerVM behaviour * (early debug does work there, despite having no vty with * reg==0. */ - QTAILQ_FOREACH(qdev, &spapr->vio_bus->bus.children, sibling) { - if (qdev->info == &spapr_vty.qdev) { - return DO_UPCAST(VIOsPAPRDevice, qdev, qdev); - } - } + return spapr_vty_get_default(spapr->vio_bus); } return sdev; diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 429349fb94..0410901b56 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -504,7 +504,7 @@ void kvm_arch_post_run(CPUState *env, struct kvm_run *run) int kvm_arch_process_async_events(CPUState *env) { - return 0; + return env->halted; } static int kvmppc_handle_halt(CPUState *env) @@ -838,12 +838,18 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd) int fd; void *table; + /* Must set fd to -1 so we don't try to munmap when called for + * destroying the table, which the upper layers -will- do + */ + *pfd = -1; if (!cap_spapr_tce) { return NULL; } fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args); if (fd < 0) { + fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n", + liobn); return NULL; } @@ -852,6 +858,8 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd) table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (table == MAP_FAILED) { + fprintf(stderr, "KVM: Failed to map TCE table for liobn 0x%x\n", + liobn); close(fd); return NULL; } @@ -871,8 +879,8 @@ int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t window_size) len = (window_size / SPAPR_VIO_TCE_PAGE_SIZE)*sizeof(VIOsPAPR_RTCE); if ((munmap(table, len) < 0) || (close(fd) < 0)) { - fprintf(stderr, "KVM: Unexpected error removing KVM SPAPR TCE " - "table: %s", strerror(errno)); + fprintf(stderr, "KVM: Unexpected error removing TCE table: %s", + strerror(errno)); /* Leak the table */ } |