aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Forbes <jforbes@redhat.com>2012-02-01 11:24:47 -0600
committerJustin M. Forbes <jforbes@redhat.com>2012-02-01 11:24:47 -0600
commit102dd9167c121d09c78d6b98da0ff8ed1001590a (patch)
treed1b7bef952720fd5f6d43102387a3ae57425dc94
parentd0ed2d2e8e863a9a64c9fc9c08fa68bee546ad00 (diff)
parentd928541b51731a185214924cc5b44cd28020fa4f (diff)
Merge branch 'ppc-1.0' of git://repo.or.cz/qemu/agraf
-rw-r--r--console.c4
-rw-r--r--hw/ppce500_spin.c1
-rw-r--r--hw/spapr.c2
-rw-r--r--hw/spapr_pci.c2
-rw-r--r--hw/spapr_vio.c84
-rw-r--r--hw/spapr_vio.h3
-rw-r--r--hw/spapr_vty.c47
-rw-r--r--target-ppc/kvm.c14
8 files changed, 138 insertions, 19 deletions
diff --git a/console.c b/console.c
index f6fe44195..ed6a653fd 100644
--- a/console.c
+++ b/console.c
@@ -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 cccd94073..2b527282b 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 2b901f105..5a98d8651 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 716258854..9b6a032cc 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 2dcc0361e..464fe8744 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 a325a5f4b..9fcd304ad 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 f23cc3623..386ccf720 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 429349fb9..0410901b5 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 */
}