Merge branch 'ppc-1.0' of git://repo.or.cz/qemu/agraf

This commit is contained in:
Justin M. Forbes 2012-02-01 11:24:47 -06:00
commit 102dd9167c
8 changed files with 138 additions and 19 deletions

View File

@ -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)

View File

@ -112,6 +112,7 @@ static void spin_kick(void *data)
env->halted = 0;
env->exception_index = -1;
env->stopped = 0;
qemu_cpu_kick(env);
}

View File

@ -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));

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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 */
}