* it has to be aligned to num to support multiple
* MSI vectors. MSI-X is not affected by this.
* The hint is used for the first IRQ, the rest should
- * be allocated continously.
+ * be allocated continuously.
*/
if (msi) {
assert((num == 1) || (num == 2) || (num == 4) ||
return NULL;
}
- return XICS(dev);
+ return XICS_COMMON(dev);
}
static XICSState *xics_system_init(int nr_servers, int nr_irqs)
{
XICSState *icp = NULL;
- icp = try_create_xics(TYPE_XICS, nr_servers, nr_irqs);
+ if (kvm_enabled()) {
+ QemuOpts *machine_opts = qemu_get_machine_opts();
+ bool irqchip_allowed = qemu_opt_get_bool(machine_opts,
+ "kernel_irqchip", true);
+ bool irqchip_required = qemu_opt_get_bool(machine_opts,
+ "kernel_irqchip", false);
+ if (irqchip_allowed) {
+ icp = try_create_xics(TYPE_KVM_XICS, nr_servers, nr_irqs);
+ }
+
+ if (irqchip_required && !icp) {
+ perror("Failed to create in-kernel XICS\n");
+ abort();
+ }
+ }
+
+ if (!icp) {
+ icp = try_create_xics(TYPE_XICS, nr_servers, nr_irqs);
+ }
+
if (!icp) {
perror("Failed to create XICS\n");
abort();
int smt = kvmppc_smt_threads();
uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
- assert(spapr->cpu_model);
-
CPU_FOREACH(cpu) {
+ DeviceClass *dc = DEVICE_GET_CLASS(cpu);
uint32_t associativity[] = {cpu_to_be32(0x5),
cpu_to_be32(0x0),
cpu_to_be32(0x0),
continue;
}
- snprintf(cpu_model, 32, "/cpus/%s@%x", spapr->cpu_model,
+ snprintf(cpu_model, 32, "/cpus/%s@%x", dc->fw_name,
cpu->cpu_index);
offset = fdt_path_offset(fdt, cpu_model);
} while (0)
-static void *spapr_create_fdt_skel(const char *cpu_model,
- hwaddr initrd_base,
+static void *spapr_create_fdt_skel(hwaddr initrd_base,
hwaddr initrd_size,
hwaddr kernel_size,
bool little_endian,
char qemu_hypertas_prop[] = "hcall-memop1";
uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
- char *modelname;
int i, smt = kvmppc_smt_threads();
unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
_FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
_FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
- modelname = g_strdup(cpu_model);
-
- for (i = 0; i < strlen(modelname); i++) {
- modelname[i] = toupper(modelname[i]);
- }
-
- /* This is needed during FDT finalization */
- spapr->cpu_model = g_strdup(modelname);
-
CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
+ DeviceClass *dc = DEVICE_GET_CLASS(cs);
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
int index = cs->cpu_index;
uint32_t servers_prop[smp_threads];
continue;
}
- nodename = g_strdup_printf("%s@%x", modelname, index);
+ nodename = g_strdup_printf("%s@%x", dc->fw_name, index);
_FDT((fdt_begin_node(fdt, nodename)));
_FDT((fdt_property(fdt, "ibm,ppc-interrupt-gserver#s",
gservers_prop, sizeof(gservers_prop))));
+ if (env->spr_cb[SPR_PURR].oea_read) {
+ _FDT((fdt_property(fdt, "ibm,purr", NULL, 0)));
+ }
+
if (env->mmu_model & POWERPC_MMU_1TSEG) {
_FDT((fdt_property(fdt, "ibm,processor-segment-sizes",
segs, sizeof(segs))));
_FDT((fdt_end_node(fdt)));
}
- g_free(modelname);
-
_FDT((fdt_end_node(fdt)));
/* RTAS */
}
env = &cpu->env;
- xics_cpu_setup(spapr->icp, cpu);
-
/* Set time-base frequency to 512 MHz */
cpu_ppc_tb_init(env, TIMEBASE_FREQ);
kvmppc_set_papr(cpu);
}
+ xics_cpu_setup(spapr->icp, cpu);
+
qemu_register_reset(spapr_cpu_reset, cpu);
}
&savevm_htab_handlers, spapr);
/* Prepare the device tree */
- spapr->fdt_skel = spapr_create_fdt_skel(cpu_model,
- initrd_base, initrd_size,
+ spapr->fdt_skel = spapr_create_fdt_skel(initrd_base, initrd_size,
kernel_size, kernel_le,
boot_device, kernel_cmdline,
spapr->epow_irq);