Merge branch 'ppc-1.0' of git://repo.or.cz/qemu/agraf
This commit is contained in:
commit
102dd9167c
|
@ -186,7 +186,9 @@ void vga_hw_screen_dump(const char *filename)
|
||||||
consoles[0]->hw_screen_dump(consoles[0]->hw, 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)
|
void vga_hw_text_update(console_ch_t *chardata)
|
||||||
|
|
|
@ -112,6 +112,7 @@ static void spin_kick(void *data)
|
||||||
|
|
||||||
env->halted = 0;
|
env->halted = 0;
|
||||||
env->exception_index = -1;
|
env->exception_index = -1;
|
||||||
|
env->stopped = 0;
|
||||||
qemu_cpu_kick(env);
|
qemu_cpu_kick(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -351,6 +351,8 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
|
||||||
fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
|
fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spapr_populate_chosen_stdout(fdt, spapr->vio_bus);
|
||||||
|
|
||||||
_FDT((fdt_pack(fdt)));
|
_FDT((fdt_pack(fdt)));
|
||||||
|
|
||||||
cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
|
cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
|
||||||
|
|
|
@ -454,7 +454,7 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb,
|
||||||
reg[0].size = 0;
|
reg[0].size = 0;
|
||||||
|
|
||||||
n = 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) {
|
if (0 == dev->io_regions[i].size) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -749,21 +749,95 @@ static void spapr_vio_register_devices(void)
|
||||||
device_init(spapr_vio_register_devices)
|
device_init(spapr_vio_register_devices)
|
||||||
|
|
||||||
#ifdef CONFIG_FDT
|
#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)
|
int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt)
|
||||||
{
|
{
|
||||||
DeviceState *qdev;
|
DeviceState *qdev, **qdevs;
|
||||||
int ret = 0;
|
int i, num, ret = 0;
|
||||||
|
|
||||||
|
/* Count qdevs on the bus list */
|
||||||
|
num = 0;
|
||||||
QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
|
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);
|
ret = vio_make_devnode(dev, fdt);
|
||||||
|
|
||||||
if (ret < 0) {
|
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 */
|
#endif /* CONFIG_FDT */
|
||||||
|
|
|
@ -83,6 +83,7 @@ extern VIOsPAPRBus *spapr_vio_bus_init(void);
|
||||||
extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
|
extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
|
||||||
extern void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info);
|
extern void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info);
|
||||||
extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
|
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);
|
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_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd);
|
||||||
void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg);
|
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);
|
int spapr_tce_set_bypass(uint32_t unit, uint32_t enable);
|
||||||
void spapr_vio_quiesce(void);
|
void spapr_vio_quiesce(void);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
|
||||||
{
|
{
|
||||||
VIOsPAPRDevice *sdev;
|
VIOsPAPRDevice *sdev;
|
||||||
|
|
||||||
sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||||
if (!sdev && reg == 0) {
|
if (!sdev && reg == 0) {
|
||||||
DeviceState *qdev;
|
|
||||||
|
|
||||||
/* Hack for kernel early debug, which always specifies reg==0.
|
/* Hack for kernel early debug, which always specifies reg==0.
|
||||||
* We search all VIO devices, and grab the first available vty
|
* We search all VIO devices, and grab the vty with the lowest
|
||||||
* device. This attempts to mimic existing PowerVM behaviour
|
* reg. This attempts to mimic existing PowerVM behaviour
|
||||||
* (early debug does work there, despite having no vty with
|
* (early debug does work there, despite having no vty with
|
||||||
* reg==0. */
|
* reg==0. */
|
||||||
QTAILQ_FOREACH(qdev, &spapr->vio_bus->bus.children, sibling) {
|
return spapr_vty_get_default(spapr->vio_bus);
|
||||||
if (qdev->info == &spapr_vty.qdev) {
|
|
||||||
return DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sdev;
|
return sdev;
|
||||||
|
|
|
@ -504,7 +504,7 @@ void kvm_arch_post_run(CPUState *env, struct kvm_run *run)
|
||||||
|
|
||||||
int kvm_arch_process_async_events(CPUState *env)
|
int kvm_arch_process_async_events(CPUState *env)
|
||||||
{
|
{
|
||||||
return 0;
|
return env->halted;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kvmppc_handle_halt(CPUState *env)
|
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;
|
int fd;
|
||||||
void *table;
|
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) {
|
if (!cap_spapr_tce) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
|
fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
|
||||||
|
liobn);
|
||||||
return NULL;
|
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);
|
table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
if (table == MAP_FAILED) {
|
if (table == MAP_FAILED) {
|
||||||
|
fprintf(stderr, "KVM: Failed to map TCE table for liobn 0x%x\n",
|
||||||
|
liobn);
|
||||||
close(fd);
|
close(fd);
|
||||||
return NULL;
|
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);
|
len = (window_size / SPAPR_VIO_TCE_PAGE_SIZE)*sizeof(VIOsPAPR_RTCE);
|
||||||
if ((munmap(table, len) < 0) ||
|
if ((munmap(table, len) < 0) ||
|
||||||
(close(fd) < 0)) {
|
(close(fd) < 0)) {
|
||||||
fprintf(stderr, "KVM: Unexpected error removing KVM SPAPR TCE "
|
fprintf(stderr, "KVM: Unexpected error removing TCE table: %s",
|
||||||
"table: %s", strerror(errno));
|
strerror(errno));
|
||||||
/* Leak the table */
|
/* Leak the table */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue