Merge branch 'ppc-1.0' of git://repo.or.cz/qemu/agraf
* 'ppc-1.0' of git://repo.or.cz/qemu/agraf: pseries: Fix qdev.id handling in the VIO bus code pseries: Allow kernel's early debug output to work pseries: Default reg for vty should be SPAPR_VTY_BASE_ADDRESS pseries: Check we have a chardev in spapr_vty_init() pseries: Fix buggy spapr_vio_find_by_reg() pseries: Correct RAM size check for SLOF PPC: Fix for the gdb single step problem on an rfi instruction tcg-ppc64: Fix compile errors for userspace only builds with gcc 4.6 pseries: Fix initialization of sPAPREnvironment structure
This commit is contained in:
commit
05a86f23e5
10
hw/spapr.c
10
hw/spapr.c
@ -57,7 +57,7 @@
|
||||
#define FW_MAX_SIZE 0x400000
|
||||
#define FW_FILE_NAME "slof.bin"
|
||||
|
||||
#define MIN_RAM_SLOF 512UL
|
||||
#define MIN_RMA_SLOF 128UL
|
||||
|
||||
#define TIMEBASE_FREQ 512000000ULL
|
||||
|
||||
@ -407,7 +407,9 @@ static void ppc_spapr_init(ram_addr_t ram_size,
|
||||
long pteg_shift = 17;
|
||||
char *filename;
|
||||
|
||||
spapr = g_malloc(sizeof(*spapr));
|
||||
spapr = g_malloc0(sizeof(*spapr));
|
||||
QLIST_INIT(&spapr->phbs);
|
||||
|
||||
cpu_ppc_hypercall = emulate_spapr_hypercall;
|
||||
|
||||
/* Allocate RMA if necessary */
|
||||
@ -560,9 +562,9 @@ static void ppc_spapr_init(ram_addr_t ram_size,
|
||||
|
||||
spapr->entry_point = KERNEL_LOAD_ADDR;
|
||||
} else {
|
||||
if (ram_size < (MIN_RAM_SLOF << 20)) {
|
||||
if (rma_size < (MIN_RMA_SLOF << 20)) {
|
||||
fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "
|
||||
"%ldM guest RAM\n", MIN_RAM_SLOF);
|
||||
"%ldM guest RMA (Real Mode Area memory)\n", MIN_RMA_SLOF);
|
||||
exit(1);
|
||||
}
|
||||
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, FW_FILE_NAME);
|
||||
|
@ -66,11 +66,24 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
|
||||
QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
|
||||
dev = (VIOsPAPRDevice *)qdev;
|
||||
if (dev->reg == reg) {
|
||||
break;
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
|
||||
return dev;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *vio_format_dev_name(VIOsPAPRDevice *dev)
|
||||
{
|
||||
VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
|
||||
char *name;
|
||||
|
||||
/* Device tree style name device@reg */
|
||||
if (asprintf(&name, "%s@%x", info->dt_name, dev->reg) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FDT
|
||||
@ -78,15 +91,21 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
|
||||
void *fdt)
|
||||
{
|
||||
VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
|
||||
int vdevice_off, node_off;
|
||||
int ret;
|
||||
int vdevice_off, node_off, ret;
|
||||
char *dt_name;
|
||||
|
||||
vdevice_off = fdt_path_offset(fdt, "/vdevice");
|
||||
if (vdevice_off < 0) {
|
||||
return vdevice_off;
|
||||
}
|
||||
|
||||
node_off = fdt_add_subnode(fdt, vdevice_off, dev->qdev.id);
|
||||
dt_name = vio_format_dev_name(dev);
|
||||
if (!dt_name) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
node_off = fdt_add_subnode(fdt, vdevice_off, dt_name);
|
||||
free(dt_name);
|
||||
if (node_off < 0) {
|
||||
return node_off;
|
||||
}
|
||||
@ -608,12 +627,15 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
|
||||
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
|
||||
char *id;
|
||||
|
||||
if (asprintf(&id, "%s@%x", info->dt_name, dev->reg) < 0) {
|
||||
return -1;
|
||||
/* Don't overwrite ids assigned on the command line */
|
||||
if (!dev->qdev.id) {
|
||||
id = vio_format_dev_name(dev);
|
||||
if (!id) {
|
||||
return -1;
|
||||
}
|
||||
dev->qdev.id = id;
|
||||
}
|
||||
|
||||
dev->qdev.id = id;
|
||||
|
||||
dev->qirq = spapr_allocate_irq(dev->vio_irq_num, &dev->vio_irq_num);
|
||||
if (!dev->qirq) {
|
||||
return -1;
|
||||
|
@ -58,12 +58,20 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev)
|
||||
{
|
||||
VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
|
||||
|
||||
if (!dev->chardev) {
|
||||
fprintf(stderr, "spapr-vty: Can't create vty without a chardev!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
qemu_chr_add_handlers(dev->chardev, vty_can_receive,
|
||||
vty_receive, NULL, dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg);
|
||||
|
||||
static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
@ -71,9 +79,10 @@ static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr,
|
||||
target_ulong len = args[1];
|
||||
target_ulong char0_7 = args[2];
|
||||
target_ulong char8_15 = args[3];
|
||||
VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
VIOsPAPRDevice *sdev;
|
||||
uint8_t buf[16];
|
||||
|
||||
sdev = vty_lookup(spapr, reg);
|
||||
if (!sdev) {
|
||||
return H_PARAMETER;
|
||||
}
|
||||
@ -97,9 +106,10 @@ static target_ulong h_get_term_char(CPUState *env, sPAPREnvironment *spapr,
|
||||
target_ulong *len = args + 0;
|
||||
target_ulong *char0_7 = args + 1;
|
||||
target_ulong *char8_15 = args + 2;
|
||||
VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
VIOsPAPRDevice *sdev;
|
||||
uint8_t buf[16];
|
||||
|
||||
sdev = vty_lookup(spapr, reg);
|
||||
if (!sdev) {
|
||||
return H_PARAMETER;
|
||||
}
|
||||
@ -140,12 +150,35 @@ static VIOsPAPRDeviceInfo spapr_vty = {
|
||||
.qdev.name = "spapr-vty",
|
||||
.qdev.size = sizeof(VIOsPAPRVTYDevice),
|
||||
.qdev.props = (Property[]) {
|
||||
DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, 0, 0),
|
||||
DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, SPAPR_VTY_BASE_ADDRESS, 0),
|
||||
DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
},
|
||||
};
|
||||
|
||||
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
|
||||
* (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 sdev;
|
||||
}
|
||||
|
||||
static void spapr_vty_register(void)
|
||||
{
|
||||
spapr_vio_bus_register_withprop(&spapr_vty);
|
||||
|
@ -298,8 +298,10 @@ static inline void gen_debug_exception(DisasContext *ctx)
|
||||
{
|
||||
TCGv_i32 t0;
|
||||
|
||||
if (ctx->exception != POWERPC_EXCP_BRANCH)
|
||||
if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
|
||||
(ctx->exception != POWERPC_EXCP_SYNC)) {
|
||||
gen_update_nip(ctx, ctx->nip);
|
||||
}
|
||||
t0 = tcg_const_i32(EXCP_DEBUG);
|
||||
gen_helper_raise_exception(t0);
|
||||
tcg_temp_free_i32(t0);
|
||||
|
@ -616,18 +616,19 @@ static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
|
||||
|
||||
static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
|
||||
{
|
||||
int addr_reg, data_reg, r0, r1, rbase, mem_index, s_bits, bswap;
|
||||
int addr_reg, data_reg, r0, r1, rbase, bswap;
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
int r2;
|
||||
int r2, mem_index, s_bits;
|
||||
void *label1_ptr, *label2_ptr;
|
||||
#endif
|
||||
|
||||
data_reg = *args++;
|
||||
addr_reg = *args++;
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
mem_index = *args;
|
||||
s_bits = opc & 3;
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
r0 = 3;
|
||||
r1 = 4;
|
||||
r2 = 0;
|
||||
@ -763,17 +764,18 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
|
||||
|
||||
static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
|
||||
{
|
||||
int addr_reg, r0, r1, rbase, data_reg, mem_index, bswap;
|
||||
int addr_reg, r0, r1, rbase, data_reg, bswap;
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
int r2;
|
||||
int r2, mem_index;
|
||||
void *label1_ptr, *label2_ptr;
|
||||
#endif
|
||||
|
||||
data_reg = *args++;
|
||||
addr_reg = *args++;
|
||||
mem_index = *args;
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
mem_index = *args;
|
||||
|
||||
r0 = 3;
|
||||
r1 = 4;
|
||||
r2 = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user