]> Git Repo - qemu.git/blame - hw/ppc/pnv.c
ppc/pnv: Add cut down PSI bridge model and hookup external interrupt
[qemu.git] / hw / ppc / pnv.c
CommitLineData
9e933f4a
BH
1/*
2 * QEMU PowerPC PowerNV machine model
3 *
4 * Copyright (c) 2016, IBM Corporation.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "qemu/osdep.h"
21#include "qapi/error.h"
22#include "sysemu/sysemu.h"
23#include "sysemu/numa.h"
d2528bdc 24#include "sysemu/cpus.h"
9e933f4a 25#include "hw/hw.h"
fcf5ef2a 26#include "target/ppc/cpu.h"
9e933f4a
BH
27#include "qemu/log.h"
28#include "hw/ppc/fdt.h"
29#include "hw/ppc/ppc.h"
30#include "hw/ppc/pnv.h"
d2fd9612 31#include "hw/ppc/pnv_core.h"
9e933f4a
BH
32#include "hw/loader.h"
33#include "exec/address-spaces.h"
34#include "qemu/cutils.h"
e997040e 35#include "qapi/visitor.h"
47fea43a
CLG
36#include "monitor/monitor.h"
37#include "hw/intc/intc.h"
9e933f4a 38
36fc6f08 39#include "hw/ppc/xics.h"
967b7523
CLG
40#include "hw/ppc/pnv_xscom.h"
41
3495b6b6
CLG
42#include "hw/isa/isa.h"
43#include "hw/char/serial.h"
44#include "hw/timer/mc146818rtc.h"
45
9e933f4a
BH
46#include <libfdt.h>
47
48#define FDT_MAX_SIZE 0x00100000
49
50#define FW_FILE_NAME "skiboot.lid"
51#define FW_LOAD_ADDR 0x0
52#define FW_MAX_SIZE 0x00400000
53
54#define KERNEL_LOAD_ADDR 0x20000000
55#define INITRD_LOAD_ADDR 0x40000000
56
57/*
58 * On Power Systems E880 (POWER8), the max cpus (threads) should be :
59 * 4 * 4 sockets * 12 cores * 8 threads = 1536
60 * Let's make it 2^11
61 */
62#define MAX_CPUS 2048
63
64/*
65 * Memory nodes are created by hostboot, one for each range of memory
66 * that has a different "affinity". In practice, it means one range
67 * per chip.
68 */
69static void powernv_populate_memory_node(void *fdt, int chip_id, hwaddr start,
70 hwaddr size)
71{
72 char *mem_name;
73 uint64_t mem_reg_property[2];
74 int off;
75
76 mem_reg_property[0] = cpu_to_be64(start);
77 mem_reg_property[1] = cpu_to_be64(size);
78
79 mem_name = g_strdup_printf("memory@%"HWADDR_PRIx, start);
80 off = fdt_add_subnode(fdt, 0, mem_name);
81 g_free(mem_name);
82
83 _FDT((fdt_setprop_string(fdt, off, "device_type", "memory")));
84 _FDT((fdt_setprop(fdt, off, "reg", mem_reg_property,
85 sizeof(mem_reg_property))));
86 _FDT((fdt_setprop_cell(fdt, off, "ibm,chip-id", chip_id)));
87}
88
d2fd9612
CLG
89static int get_cpus_node(void *fdt)
90{
91 int cpus_offset = fdt_path_offset(fdt, "/cpus");
92
93 if (cpus_offset < 0) {
94 cpus_offset = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"),
95 "cpus");
96 if (cpus_offset) {
97 _FDT((fdt_setprop_cell(fdt, cpus_offset, "#address-cells", 0x1)));
98 _FDT((fdt_setprop_cell(fdt, cpus_offset, "#size-cells", 0x0)));
99 }
100 }
101 _FDT(cpus_offset);
102 return cpus_offset;
103}
104
105/*
106 * The PowerNV cores (and threads) need to use real HW ids and not an
107 * incremental index like it has been done on other platforms. This HW
108 * id is stored in the CPU PIR, it is used to create cpu nodes in the
109 * device tree, used in XSCOM to address cores and in interrupt
110 * servers.
111 */
112static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt)
113{
114 CPUState *cs = CPU(DEVICE(pc->threads));
115 DeviceClass *dc = DEVICE_GET_CLASS(cs);
116 PowerPCCPU *cpu = POWERPC_CPU(cs);
8bd9530e 117 int smt_threads = CPU_CORE(pc)->nr_threads;
d2fd9612
CLG
118 CPUPPCState *env = &cpu->env;
119 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
120 uint32_t servers_prop[smt_threads];
121 int i;
122 uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
123 0xffffffff, 0xffffffff};
124 uint32_t tbfreq = PNV_TIMEBASE_FREQ;
125 uint32_t cpufreq = 1000000000;
126 uint32_t page_sizes_prop[64];
127 size_t page_sizes_prop_size;
128 const uint8_t pa_features[] = { 24, 0,
129 0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xf0,
130 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
132 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
133 int offset;
134 char *nodename;
135 int cpus_offset = get_cpus_node(fdt);
136
137 nodename = g_strdup_printf("%s@%x", dc->fw_name, pc->pir);
138 offset = fdt_add_subnode(fdt, cpus_offset, nodename);
139 _FDT(offset);
140 g_free(nodename);
141
142 _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id", chip->chip_id)));
143
144 _FDT((fdt_setprop_cell(fdt, offset, "reg", pc->pir)));
145 _FDT((fdt_setprop_cell(fdt, offset, "ibm,pir", pc->pir)));
146 _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));
147
148 _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR])));
149 _FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size",
150 env->dcache_line_size)));
151 _FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size",
152 env->dcache_line_size)));
153 _FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size",
154 env->icache_line_size)));
155 _FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size",
156 env->icache_line_size)));
157
158 if (pcc->l1_dcache_size) {
159 _FDT((fdt_setprop_cell(fdt, offset, "d-cache-size",
160 pcc->l1_dcache_size)));
161 } else {
162 error_report("Warning: Unknown L1 dcache size for cpu");
163 }
164 if (pcc->l1_icache_size) {
165 _FDT((fdt_setprop_cell(fdt, offset, "i-cache-size",
166 pcc->l1_icache_size)));
167 } else {
168 error_report("Warning: Unknown L1 icache size for cpu");
169 }
170
171 _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq)));
172 _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq)));
173 _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", env->slb_nr)));
174 _FDT((fdt_setprop_string(fdt, offset, "status", "okay")));
175 _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0)));
176
177 if (env->spr_cb[SPR_PURR].oea_read) {
178 _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0)));
179 }
180
181 if (env->mmu_model & POWERPC_MMU_1TSEG) {
182 _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes",
183 segs, sizeof(segs))));
184 }
185
186 /* Advertise VMX/VSX (vector extensions) if available
187 * 0 / no property == no vector extensions
188 * 1 == VMX / Altivec available
189 * 2 == VSX available */
190 if (env->insns_flags & PPC_ALTIVEC) {
191 uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
192
193 _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));
194 }
195
196 /* Advertise DFP (Decimal Floating Point) if available
197 * 0 / no property == no DFP
198 * 1 == DFP available */
199 if (env->insns_flags2 & PPC2_DFP) {
200 _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
201 }
202
203 page_sizes_prop_size = ppc_create_page_sizes_prop(env, page_sizes_prop,
204 sizeof(page_sizes_prop));
205 if (page_sizes_prop_size) {
206 _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes",
207 page_sizes_prop, page_sizes_prop_size)));
208 }
209
210 _FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
211 pa_features, sizeof(pa_features))));
212
d2fd9612
CLG
213 /* Build interrupt servers properties */
214 for (i = 0; i < smt_threads; i++) {
215 servers_prop[i] = cpu_to_be32(pc->pir + i);
216 }
217 _FDT((fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
218 servers_prop, sizeof(servers_prop))));
219}
220
bf5615e7
CLG
221static void powernv_populate_icp(PnvChip *chip, void *fdt, uint32_t pir,
222 uint32_t nr_threads)
223{
224 uint64_t addr = PNV_ICP_BASE(chip) | (pir << 12);
225 char *name;
226 const char compat[] = "IBM,power8-icp\0IBM,ppc-xicp";
227 uint32_t irange[2], i, rsize;
228 uint64_t *reg;
229 int offset;
230
231 irange[0] = cpu_to_be32(pir);
232 irange[1] = cpu_to_be32(nr_threads);
233
234 rsize = sizeof(uint64_t) * 2 * nr_threads;
235 reg = g_malloc(rsize);
236 for (i = 0; i < nr_threads; i++) {
237 reg[i * 2] = cpu_to_be64(addr | ((pir + i) * 0x1000));
238 reg[i * 2 + 1] = cpu_to_be64(0x1000);
239 }
240
241 name = g_strdup_printf("interrupt-controller@%"PRIX64, addr);
242 offset = fdt_add_subnode(fdt, 0, name);
243 _FDT(offset);
244 g_free(name);
245
246 _FDT((fdt_setprop(fdt, offset, "compatible", compat, sizeof(compat))));
247 _FDT((fdt_setprop(fdt, offset, "reg", reg, rsize)));
248 _FDT((fdt_setprop_string(fdt, offset, "device_type",
249 "PowerPC-External-Interrupt-Presentation")));
250 _FDT((fdt_setprop(fdt, offset, "interrupt-controller", NULL, 0)));
251 _FDT((fdt_setprop(fdt, offset, "ibm,interrupt-server-ranges",
252 irange, sizeof(irange))));
253 _FDT((fdt_setprop_cell(fdt, offset, "#interrupt-cells", 1)));
254 _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0)));
255 g_free(reg);
256}
257
e997040e
CLG
258static void powernv_populate_chip(PnvChip *chip, void *fdt)
259{
d2fd9612
CLG
260 PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
261 char *typename = pnv_core_typename(pcc->cpu_model);
262 size_t typesize = object_type_get_instance_size(typename);
263 int i;
264
967b7523
CLG
265 pnv_xscom_populate(chip, fdt, 0);
266
d2fd9612
CLG
267 for (i = 0; i < chip->nr_cores; i++) {
268 PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
269
270 powernv_create_core_node(chip, pnv_core, fdt);
bf5615e7
CLG
271
272 /* Interrupt Control Presenters (ICP). One per core. */
273 powernv_populate_icp(chip, fdt, pnv_core->pir,
274 CPU_CORE(pnv_core)->nr_threads);
d2fd9612
CLG
275 }
276
e997040e
CLG
277 if (chip->ram_size) {
278 powernv_populate_memory_node(fdt, chip->chip_id, chip->ram_start,
279 chip->ram_size);
280 }
d2fd9612 281 g_free(typename);
e997040e
CLG
282}
283
9e933f4a
BH
284static void *powernv_create_fdt(MachineState *machine)
285{
286 const char plat_compat[] = "qemu,powernv\0ibm,powernv";
287 PnvMachineState *pnv = POWERNV_MACHINE(machine);
288 void *fdt;
289 char *buf;
290 int off;
e997040e 291 int i;
9e933f4a
BH
292
293 fdt = g_malloc0(FDT_MAX_SIZE);
294 _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE)));
295
296 /* Root node */
297 _FDT((fdt_setprop_cell(fdt, 0, "#address-cells", 0x2)));
298 _FDT((fdt_setprop_cell(fdt, 0, "#size-cells", 0x2)));
299 _FDT((fdt_setprop_string(fdt, 0, "model",
300 "IBM PowerNV (emulated by qemu)")));
301 _FDT((fdt_setprop(fdt, 0, "compatible", plat_compat,
302 sizeof(plat_compat))));
303
304 buf = qemu_uuid_unparse_strdup(&qemu_uuid);
305 _FDT((fdt_setprop_string(fdt, 0, "vm,uuid", buf)));
306 if (qemu_uuid_set) {
307 _FDT((fdt_property_string(fdt, "system-id", buf)));
308 }
309 g_free(buf);
310
311 off = fdt_add_subnode(fdt, 0, "chosen");
312 if (machine->kernel_cmdline) {
313 _FDT((fdt_setprop_string(fdt, off, "bootargs",
314 machine->kernel_cmdline)));
315 }
316
317 if (pnv->initrd_size) {
318 uint32_t start_prop = cpu_to_be32(pnv->initrd_base);
319 uint32_t end_prop = cpu_to_be32(pnv->initrd_base + pnv->initrd_size);
320
321 _FDT((fdt_setprop(fdt, off, "linux,initrd-start",
322 &start_prop, sizeof(start_prop))));
323 _FDT((fdt_setprop(fdt, off, "linux,initrd-end",
324 &end_prop, sizeof(end_prop))));
325 }
326
e997040e
CLG
327 /* Populate device tree for each chip */
328 for (i = 0; i < pnv->num_chips; i++) {
329 powernv_populate_chip(pnv->chips[i], fdt);
330 }
9e933f4a
BH
331 return fdt;
332}
333
334static void ppc_powernv_reset(void)
335{
336 MachineState *machine = MACHINE(qdev_get_machine());
337 void *fdt;
338
339 qemu_devices_reset();
340
341 fdt = powernv_create_fdt(machine);
342
343 /* Pack resulting tree */
344 _FDT((fdt_pack(fdt)));
345
346 cpu_physical_memory_write(PNV_FDT_ADDR, fdt, fdt_totalsize(fdt));
347}
348
3495b6b6
CLG
349/* If we don't use the built-in LPC interrupt deserializer, we need
350 * to provide a set of qirqs for the ISA bus or things will go bad.
351 *
352 * Most machines using pre-Naples chips (without said deserializer)
353 * have a CPLD that will collect the SerIRQ and shoot them as a
354 * single level interrupt to the P8 chip. So let's setup a hook
355 * for doing just that.
3495b6b6
CLG
356 */
357static void pnv_lpc_isa_irq_handler_cpld(void *opaque, int n, int level)
358{
54f59d78
CLG
359 PnvMachineState *pnv = POWERNV_MACHINE(qdev_get_machine());
360 uint32_t old_state = pnv->cpld_irqstate;
361 PnvChip *chip = opaque;
362
363 if (level) {
364 pnv->cpld_irqstate |= 1u << n;
365 } else {
366 pnv->cpld_irqstate &= ~(1u << n);
367 }
368 if (pnv->cpld_irqstate != old_state) {
369 pnv_psi_irq_set(&chip->psi, PSIHB_IRQ_EXTERNAL,
370 pnv->cpld_irqstate != 0);
371 }
3495b6b6
CLG
372}
373
374static void pnv_lpc_isa_irq_handler(void *opaque, int n, int level)
375{
376 /* XXX TODO */
377}
378
379static ISABus *pnv_isa_create(PnvChip *chip)
380{
381 PnvLpcController *lpc = &chip->lpc;
382 ISABus *isa_bus;
383 qemu_irq *irqs;
384 PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
385
386 /* let isa_bus_new() create its own bridge on SysBus otherwise
387 * devices speficied on the command line won't find the bus and
388 * will fail to create.
389 */
390 isa_bus = isa_bus_new(NULL, &lpc->isa_mem, &lpc->isa_io,
391 &error_fatal);
392
393 /* Not all variants have a working serial irq decoder. If not,
394 * handling of LPC interrupts becomes a platform issue (some
395 * platforms have a CPLD to do it).
396 */
397 if (pcc->chip_type == PNV_CHIP_POWER8NVL) {
398 irqs = qemu_allocate_irqs(pnv_lpc_isa_irq_handler, chip, ISA_NUM_IRQS);
399 } else {
400 irqs = qemu_allocate_irqs(pnv_lpc_isa_irq_handler_cpld, chip,
401 ISA_NUM_IRQS);
402 }
403
404 isa_bus_irqs(isa_bus, irqs);
405 return isa_bus;
406}
407
9e933f4a
BH
408static void ppc_powernv_init(MachineState *machine)
409{
410 PnvMachineState *pnv = POWERNV_MACHINE(machine);
411 MemoryRegion *ram;
412 char *fw_filename;
413 long fw_size;
e997040e
CLG
414 int i;
415 char *chip_typename;
9e933f4a
BH
416
417 /* allocate RAM */
418 if (machine->ram_size < (1 * G_BYTE)) {
419 error_report("Warning: skiboot may not work with < 1GB of RAM");
420 }
421
422 ram = g_new(MemoryRegion, 1);
423 memory_region_allocate_system_memory(ram, NULL, "ppc_powernv.ram",
424 machine->ram_size);
425 memory_region_add_subregion(get_system_memory(), 0, ram);
426
427 /* load skiboot firmware */
428 if (bios_name == NULL) {
429 bios_name = FW_FILE_NAME;
430 }
431
432 fw_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
433
434 fw_size = load_image_targphys(fw_filename, FW_LOAD_ADDR, FW_MAX_SIZE);
435 if (fw_size < 0) {
802fc7ab 436 error_report("Could not load OPAL '%s'", fw_filename);
9e933f4a
BH
437 exit(1);
438 }
439 g_free(fw_filename);
440
441 /* load kernel */
442 if (machine->kernel_filename) {
443 long kernel_size;
444
445 kernel_size = load_image_targphys(machine->kernel_filename,
446 KERNEL_LOAD_ADDR, 0x2000000);
447 if (kernel_size < 0) {
802fc7ab 448 error_report("Could not load kernel '%s'",
7c6e8797 449 machine->kernel_filename);
9e933f4a
BH
450 exit(1);
451 }
452 }
453
454 /* load initrd */
455 if (machine->initrd_filename) {
456 pnv->initrd_base = INITRD_LOAD_ADDR;
457 pnv->initrd_size = load_image_targphys(machine->initrd_filename,
458 pnv->initrd_base, 0x10000000); /* 128MB max */
459 if (pnv->initrd_size < 0) {
802fc7ab 460 error_report("Could not load initial ram disk '%s'",
9e933f4a
BH
461 machine->initrd_filename);
462 exit(1);
463 }
464 }
e997040e
CLG
465
466 /* We need some cpu model to instantiate the PnvChip class */
467 if (machine->cpu_model == NULL) {
468 machine->cpu_model = "POWER8";
469 }
470
471 /* Create the processor chips */
472 chip_typename = g_strdup_printf(TYPE_PNV_CHIP "-%s", machine->cpu_model);
473 if (!object_class_by_name(chip_typename)) {
474 error_report("qemu: invalid CPU model '%s' for %s machine",
475 machine->cpu_model, MACHINE_GET_CLASS(machine)->name);
476 exit(1);
477 }
478
479 pnv->chips = g_new0(PnvChip *, pnv->num_chips);
480 for (i = 0; i < pnv->num_chips; i++) {
481 char chip_name[32];
482 Object *chip = object_new(chip_typename);
483
484 pnv->chips[i] = PNV_CHIP(chip);
485
486 /* TODO: put all the memory in one node on chip 0 until we find a
487 * way to specify different ranges for each chip
488 */
489 if (i == 0) {
490 object_property_set_int(chip, machine->ram_size, "ram-size",
491 &error_fatal);
492 }
493
494 snprintf(chip_name, sizeof(chip_name), "chip[%d]", PNV_CHIP_HWID(i));
495 object_property_add_child(OBJECT(pnv), chip_name, chip, &error_fatal);
496 object_property_set_int(chip, PNV_CHIP_HWID(i), "chip-id",
497 &error_fatal);
397a79e7 498 object_property_set_int(chip, smp_cores, "nr-cores", &error_fatal);
e997040e
CLG
499 object_property_set_bool(chip, true, "realized", &error_fatal);
500 }
501 g_free(chip_typename);
3495b6b6
CLG
502
503 /* Instantiate ISA bus on chip 0 */
504 pnv->isa_bus = pnv_isa_create(pnv->chips[0]);
505
506 /* Create serial port */
507 serial_hds_isa_init(pnv->isa_bus, 0, MAX_SERIAL_PORTS);
508
509 /* Create an RTC ISA device too */
510 rtc_init(pnv->isa_bus, 2000, NULL);
e997040e
CLG
511}
512
631adaff
CLG
513/*
514 * 0:21 Reserved - Read as zeros
515 * 22:24 Chip ID
516 * 25:28 Core number
517 * 29:31 Thread ID
518 */
519static uint32_t pnv_chip_core_pir_p8(PnvChip *chip, uint32_t core_id)
520{
521 return (chip->chip_id << 7) | (core_id << 3);
522}
523
524/*
525 * 0:48 Reserved - Read as zeroes
526 * 49:52 Node ID
527 * 53:55 Chip ID
528 * 56 Reserved - Read as zero
529 * 57:61 Core number
530 * 62:63 Thread ID
531 *
532 * We only care about the lower bits. uint32_t is fine for the moment.
533 */
534static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
535{
536 return (chip->chip_id << 8) | (core_id << 2);
537}
538
397a79e7
CLG
539/* Allowed core identifiers on a POWER8 Processor Chip :
540 *
541 * <EX0 reserved>
542 * EX1 - Venice only
543 * EX2 - Venice only
544 * EX3 - Venice only
545 * EX4
546 * EX5
547 * EX6
548 * <EX7,8 reserved> <reserved>
549 * EX9 - Venice only
550 * EX10 - Venice only
551 * EX11 - Venice only
552 * EX12
553 * EX13
554 * EX14
555 * <EX15 reserved>
556 */
557#define POWER8E_CORE_MASK (0x7070ull)
558#define POWER8_CORE_MASK (0x7e7eull)
559
560/*
561 * POWER9 has 24 cores, ids starting at 0x20
562 */
563#define POWER9_CORE_MASK (0xffffff00000000ull)
564
e997040e
CLG
565static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
566{
567 DeviceClass *dc = DEVICE_CLASS(klass);
568 PnvChipClass *k = PNV_CHIP_CLASS(klass);
569
570 k->cpu_model = "POWER8E";
571 k->chip_type = PNV_CHIP_POWER8E;
572 k->chip_cfam_id = 0x221ef04980000000ull; /* P8 Murano DD2.1 */
397a79e7 573 k->cores_mask = POWER8E_CORE_MASK;
631adaff 574 k->core_pir = pnv_chip_core_pir_p8;
967b7523 575 k->xscom_base = 0x003fc0000000000ull;
ad521238 576 k->xscom_core_base = 0x10000000ull;
e997040e
CLG
577 dc->desc = "PowerNV Chip POWER8E";
578}
579
580static const TypeInfo pnv_chip_power8e_info = {
581 .name = TYPE_PNV_CHIP_POWER8E,
582 .parent = TYPE_PNV_CHIP,
583 .instance_size = sizeof(PnvChip),
584 .class_init = pnv_chip_power8e_class_init,
585};
586
587static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
588{
589 DeviceClass *dc = DEVICE_CLASS(klass);
590 PnvChipClass *k = PNV_CHIP_CLASS(klass);
591
592 k->cpu_model = "POWER8";
593 k->chip_type = PNV_CHIP_POWER8;
594 k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */
397a79e7 595 k->cores_mask = POWER8_CORE_MASK;
631adaff 596 k->core_pir = pnv_chip_core_pir_p8;
967b7523 597 k->xscom_base = 0x003fc0000000000ull;
ad521238 598 k->xscom_core_base = 0x10000000ull;
e997040e
CLG
599 dc->desc = "PowerNV Chip POWER8";
600}
601
602static const TypeInfo pnv_chip_power8_info = {
603 .name = TYPE_PNV_CHIP_POWER8,
604 .parent = TYPE_PNV_CHIP,
605 .instance_size = sizeof(PnvChip),
606 .class_init = pnv_chip_power8_class_init,
607};
608
609static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
610{
611 DeviceClass *dc = DEVICE_CLASS(klass);
612 PnvChipClass *k = PNV_CHIP_CLASS(klass);
613
614 k->cpu_model = "POWER8NVL";
615 k->chip_type = PNV_CHIP_POWER8NVL;
616 k->chip_cfam_id = 0x120d304980000000ull; /* P8 Naples DD1.0 */
397a79e7 617 k->cores_mask = POWER8_CORE_MASK;
631adaff 618 k->core_pir = pnv_chip_core_pir_p8;
967b7523 619 k->xscom_base = 0x003fc0000000000ull;
ad521238 620 k->xscom_core_base = 0x10000000ull;
e997040e
CLG
621 dc->desc = "PowerNV Chip POWER8NVL";
622}
623
624static const TypeInfo pnv_chip_power8nvl_info = {
625 .name = TYPE_PNV_CHIP_POWER8NVL,
626 .parent = TYPE_PNV_CHIP,
627 .instance_size = sizeof(PnvChip),
628 .class_init = pnv_chip_power8nvl_class_init,
629};
630
631static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
632{
633 DeviceClass *dc = DEVICE_CLASS(klass);
634 PnvChipClass *k = PNV_CHIP_CLASS(klass);
635
636 k->cpu_model = "POWER9";
637 k->chip_type = PNV_CHIP_POWER9;
638 k->chip_cfam_id = 0x100d104980000000ull; /* P9 Nimbus DD1.0 */
397a79e7 639 k->cores_mask = POWER9_CORE_MASK;
631adaff 640 k->core_pir = pnv_chip_core_pir_p9;
967b7523 641 k->xscom_base = 0x00603fc00000000ull;
ad521238 642 k->xscom_core_base = 0x0ull;
e997040e
CLG
643 dc->desc = "PowerNV Chip POWER9";
644}
645
646static const TypeInfo pnv_chip_power9_info = {
647 .name = TYPE_PNV_CHIP_POWER9,
648 .parent = TYPE_PNV_CHIP,
649 .instance_size = sizeof(PnvChip),
650 .class_init = pnv_chip_power9_class_init,
651};
652
397a79e7
CLG
653static void pnv_chip_core_sanitize(PnvChip *chip, Error **errp)
654{
655 PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
656 int cores_max;
657
658 /*
659 * No custom mask for this chip, let's use the default one from *
660 * the chip class
661 */
662 if (!chip->cores_mask) {
663 chip->cores_mask = pcc->cores_mask;
664 }
665
666 /* filter alien core ids ! some are reserved */
667 if ((chip->cores_mask & pcc->cores_mask) != chip->cores_mask) {
668 error_setg(errp, "warning: invalid core mask for chip Ox%"PRIx64" !",
669 chip->cores_mask);
670 return;
671 }
672 chip->cores_mask &= pcc->cores_mask;
673
674 /* now that we have a sane layout, let check the number of cores */
27d9ffd4 675 cores_max = ctpop64(chip->cores_mask);
397a79e7
CLG
676 if (chip->nr_cores > cores_max) {
677 error_setg(errp, "warning: too many cores for chip ! Limit is %d",
678 cores_max);
679 return;
680 }
681}
682
967b7523
CLG
683static void pnv_chip_init(Object *obj)
684{
685 PnvChip *chip = PNV_CHIP(obj);
686 PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
687
688 chip->xscom_base = pcc->xscom_base;
a3980bf5
BH
689
690 object_initialize(&chip->lpc, sizeof(chip->lpc), TYPE_PNV_LPC);
691 object_property_add_child(obj, "lpc", OBJECT(&chip->lpc), NULL);
54f59d78
CLG
692
693 object_initialize(&chip->psi, sizeof(chip->psi), TYPE_PNV_PSI);
694 object_property_add_child(obj, "psi", OBJECT(&chip->psi), NULL);
695 object_property_add_const_link(OBJECT(&chip->psi), "xics",
696 OBJECT(qdev_get_machine()), &error_abort);
967b7523
CLG
697}
698
bf5615e7
CLG
699static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
700{
701 PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
702 char *typename = pnv_core_typename(pcc->cpu_model);
703 size_t typesize = object_type_get_instance_size(typename);
704 int i, j;
705 char *name;
706 XICSFabric *xi = XICS_FABRIC(qdev_get_machine());
707
708 name = g_strdup_printf("icp-%x", chip->chip_id);
709 memory_region_init(&chip->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE);
710 sysbus_init_mmio(SYS_BUS_DEVICE(chip), &chip->icp_mmio);
711 g_free(name);
712
713 sysbus_mmio_map(SYS_BUS_DEVICE(chip), 1, PNV_ICP_BASE(chip));
714
715 /* Map the ICP registers for each thread */
716 for (i = 0; i < chip->nr_cores; i++) {
717 PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
718 int core_hwid = CPU_CORE(pnv_core)->core_id;
719
720 for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
721 uint32_t pir = pcc->core_pir(chip, core_hwid) + j;
722 PnvICPState *icp = PNV_ICP(xics_icp_get(xi, pir));
723
724 memory_region_add_subregion(&chip->icp_mmio, pir << 12, &icp->mmio);
725 }
726 }
727
728 g_free(typename);
729}
730
e997040e
CLG
731static void pnv_chip_realize(DeviceState *dev, Error **errp)
732{
397a79e7
CLG
733 PnvChip *chip = PNV_CHIP(dev);
734 Error *error = NULL;
d2fd9612
CLG
735 PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
736 char *typename = pnv_core_typename(pcc->cpu_model);
737 size_t typesize = object_type_get_instance_size(typename);
738 int i, core_hwid;
739
740 if (!object_class_by_name(typename)) {
741 error_setg(errp, "Unable to find PowerNV CPU Core '%s'", typename);
742 return;
743 }
397a79e7 744
967b7523
CLG
745 /* XSCOM bridge */
746 pnv_xscom_realize(chip, &error);
747 if (error) {
748 error_propagate(errp, error);
749 return;
750 }
751 sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV_XSCOM_BASE(chip));
752
d2fd9612 753 /* Cores */
397a79e7
CLG
754 pnv_chip_core_sanitize(chip, &error);
755 if (error) {
756 error_propagate(errp, error);
757 return;
758 }
d2fd9612
CLG
759
760 chip->cores = g_malloc0(typesize * chip->nr_cores);
761
762 for (i = 0, core_hwid = 0; (core_hwid < sizeof(chip->cores_mask) * 8)
763 && (i < chip->nr_cores); core_hwid++) {
764 char core_name[32];
765 void *pnv_core = chip->cores + i * typesize;
766
767 if (!(chip->cores_mask & (1ull << core_hwid))) {
768 continue;
769 }
770
771 object_initialize(pnv_core, typesize, typename);
772 snprintf(core_name, sizeof(core_name), "core[%d]", core_hwid);
773 object_property_add_child(OBJECT(chip), core_name, OBJECT(pnv_core),
774 &error_fatal);
775 object_property_set_int(OBJECT(pnv_core), smp_threads, "nr-threads",
776 &error_fatal);
777 object_property_set_int(OBJECT(pnv_core), core_hwid,
778 CPU_CORE_PROP_CORE_ID, &error_fatal);
779 object_property_set_int(OBJECT(pnv_core),
780 pcc->core_pir(chip, core_hwid),
781 "pir", &error_fatal);
960fbd29
CLG
782 object_property_add_const_link(OBJECT(pnv_core), "xics",
783 qdev_get_machine(), &error_fatal);
d2fd9612
CLG
784 object_property_set_bool(OBJECT(pnv_core), true, "realized",
785 &error_fatal);
786 object_unref(OBJECT(pnv_core));
24ece072
CLG
787
788 /* Each core has an XSCOM MMIO region */
ad521238
CLG
789 pnv_xscom_add_subregion(chip,
790 PNV_XSCOM_EX_CORE_BASE(pcc->xscom_core_base,
791 core_hwid),
24ece072 792 &PNV_CORE(pnv_core)->xscom_regs);
d2fd9612
CLG
793 i++;
794 }
795 g_free(typename);
a3980bf5
BH
796
797 /* Create LPC controller */
798 object_property_set_bool(OBJECT(&chip->lpc), true, "realized",
799 &error_fatal);
800 pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip->lpc.xscom_regs);
bf5615e7
CLG
801
802 /* Interrupt Management Area. This is the memory region holding
803 * all the Interrupt Control Presenter (ICP) registers */
804 pnv_chip_icp_realize(chip, &error);
805 if (error) {
806 error_propagate(errp, error);
807 return;
808 }
54f59d78
CLG
809
810 /* Processor Service Interface (PSI) Host Bridge */
811 object_property_set_int(OBJECT(&chip->psi), PNV_PSIHB_BASE(chip),
812 "bar", &error_fatal);
813 object_property_set_bool(OBJECT(&chip->psi), true, "realized", &error);
814 if (error) {
815 error_propagate(errp, error);
816 return;
817 }
818 pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip->psi.xscom_regs);
e997040e
CLG
819}
820
821static Property pnv_chip_properties[] = {
822 DEFINE_PROP_UINT32("chip-id", PnvChip, chip_id, 0),
823 DEFINE_PROP_UINT64("ram-start", PnvChip, ram_start, 0),
824 DEFINE_PROP_UINT64("ram-size", PnvChip, ram_size, 0),
397a79e7
CLG
825 DEFINE_PROP_UINT32("nr-cores", PnvChip, nr_cores, 1),
826 DEFINE_PROP_UINT64("cores-mask", PnvChip, cores_mask, 0x0),
e997040e
CLG
827 DEFINE_PROP_END_OF_LIST(),
828};
829
830static void pnv_chip_class_init(ObjectClass *klass, void *data)
831{
832 DeviceClass *dc = DEVICE_CLASS(klass);
833
9d169fb3 834 set_bit(DEVICE_CATEGORY_CPU, dc->categories);
e997040e
CLG
835 dc->realize = pnv_chip_realize;
836 dc->props = pnv_chip_properties;
837 dc->desc = "PowerNV Chip";
838}
839
840static const TypeInfo pnv_chip_info = {
841 .name = TYPE_PNV_CHIP,
842 .parent = TYPE_SYS_BUS_DEVICE,
843 .class_init = pnv_chip_class_init,
967b7523 844 .instance_init = pnv_chip_init,
e997040e
CLG
845 .class_size = sizeof(PnvChipClass),
846 .abstract = true,
847};
848
54f59d78
CLG
849static ICSState *pnv_ics_get(XICSFabric *xi, int irq)
850{
851 PnvMachineState *pnv = POWERNV_MACHINE(xi);
852 int i;
853
854 for (i = 0; i < pnv->num_chips; i++) {
855 if (ics_valid_irq(&pnv->chips[i]->psi.ics, irq)) {
856 return &pnv->chips[i]->psi.ics;
857 }
858 }
859 return NULL;
860}
861
862static void pnv_ics_resend(XICSFabric *xi)
863{
864 PnvMachineState *pnv = POWERNV_MACHINE(xi);
865 int i;
866
867 for (i = 0; i < pnv->num_chips; i++) {
868 ics_resend(&pnv->chips[i]->psi.ics);
869 }
870}
871
36fc6f08
CLG
872static PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
873{
874 CPUState *cs;
875
876 CPU_FOREACH(cs) {
877 PowerPCCPU *cpu = POWERPC_CPU(cs);
878 CPUPPCState *env = &cpu->env;
879
880 if (env->spr_cb[SPR_PIR].default_value == pir) {
881 return cpu;
882 }
883 }
884
885 return NULL;
886}
887
888static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
889{
890 PowerPCCPU *cpu = ppc_get_vcpu_by_pir(pir);
891
892 return cpu ? ICP(cpu->intc) : NULL;
893}
894
47fea43a
CLG
895static void pnv_pic_print_info(InterruptStatsProvider *obj,
896 Monitor *mon)
897{
54f59d78
CLG
898 PnvMachineState *pnv = POWERNV_MACHINE(obj);
899 int i;
47fea43a
CLG
900 CPUState *cs;
901
902 CPU_FOREACH(cs) {
903 PowerPCCPU *cpu = POWERPC_CPU(cs);
904
905 icp_pic_print_info(ICP(cpu->intc), mon);
906 }
54f59d78
CLG
907
908 for (i = 0; i < pnv->num_chips; i++) {
909 ics_pic_print_info(&pnv->chips[i]->psi.ics, mon);
910 }
47fea43a
CLG
911}
912
e997040e
CLG
913static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
914 void *opaque, Error **errp)
915{
916 visit_type_uint32(v, name, &POWERNV_MACHINE(obj)->num_chips, errp);
917}
918
919static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name,
920 void *opaque, Error **errp)
921{
922 PnvMachineState *pnv = POWERNV_MACHINE(obj);
923 uint32_t num_chips;
924 Error *local_err = NULL;
925
926 visit_type_uint32(v, name, &num_chips, &local_err);
927 if (local_err) {
928 error_propagate(errp, local_err);
929 return;
930 }
931
932 /*
933 * TODO: should we decide on how many chips we can create based
934 * on #cores and Venice vs. Murano vs. Naples chip type etc...,
935 */
936 if (!is_power_of_2(num_chips) || num_chips > 4) {
937 error_setg(errp, "invalid number of chips: '%d'", num_chips);
938 return;
939 }
940
941 pnv->num_chips = num_chips;
942}
943
944static void powernv_machine_initfn(Object *obj)
945{
946 PnvMachineState *pnv = POWERNV_MACHINE(obj);
947 pnv->num_chips = 1;
948}
949
950static void powernv_machine_class_props_init(ObjectClass *oc)
951{
952 object_class_property_add(oc, "num-chips", "uint32_t",
953 pnv_get_num_chips, pnv_set_num_chips,
954 NULL, NULL, NULL);
955 object_class_property_set_description(oc, "num-chips",
956 "Specifies the number of processor chips",
957 NULL);
9e933f4a
BH
958}
959
960static void powernv_machine_class_init(ObjectClass *oc, void *data)
961{
962 MachineClass *mc = MACHINE_CLASS(oc);
36fc6f08 963 XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
47fea43a 964 InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
9e933f4a
BH
965
966 mc->desc = "IBM PowerNV (Non-Virtualized)";
967 mc->init = ppc_powernv_init;
968 mc->reset = ppc_powernv_reset;
969 mc->max_cpus = MAX_CPUS;
970 mc->block_default_type = IF_IDE; /* Pnv provides a AHCI device for
971 * storage */
972 mc->no_parallel = 1;
973 mc->default_boot_order = NULL;
974 mc->default_ram_size = 1 * G_BYTE;
36fc6f08 975 xic->icp_get = pnv_icp_get;
54f59d78
CLG
976 xic->ics_get = pnv_ics_get;
977 xic->ics_resend = pnv_ics_resend;
47fea43a 978 ispc->print_info = pnv_pic_print_info;
e997040e
CLG
979
980 powernv_machine_class_props_init(oc);
9e933f4a
BH
981}
982
983static const TypeInfo powernv_machine_info = {
984 .name = TYPE_POWERNV_MACHINE,
985 .parent = TYPE_MACHINE,
986 .instance_size = sizeof(PnvMachineState),
e997040e 987 .instance_init = powernv_machine_initfn,
9e933f4a 988 .class_init = powernv_machine_class_init,
36fc6f08
CLG
989 .interfaces = (InterfaceInfo[]) {
990 { TYPE_XICS_FABRIC },
47fea43a 991 { TYPE_INTERRUPT_STATS_PROVIDER },
36fc6f08
CLG
992 { },
993 },
9e933f4a
BH
994};
995
996static void powernv_machine_register_types(void)
997{
998 type_register_static(&powernv_machine_info);
e997040e
CLG
999 type_register_static(&pnv_chip_info);
1000 type_register_static(&pnv_chip_power8e_info);
1001 type_register_static(&pnv_chip_power8_info);
1002 type_register_static(&pnv_chip_power8nvl_info);
1003 type_register_static(&pnv_chip_power9_info);
9e933f4a
BH
1004}
1005
1006type_init(powernv_machine_register_types)
This page took 0.163221 seconds and 4 git commands to generate.