]> git.proxmox.com Git - mirror_qemu.git/blame - hw/ppc/pnv.c
ppc/pnv: add a core mask to PnvChip
[mirror_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"
24#include "hw/hw.h"
25#include "target-ppc/cpu.h"
26#include "qemu/log.h"
27#include "hw/ppc/fdt.h"
28#include "hw/ppc/ppc.h"
29#include "hw/ppc/pnv.h"
30#include "hw/loader.h"
31#include "exec/address-spaces.h"
32#include "qemu/cutils.h"
e997040e 33#include "qapi/visitor.h"
9e933f4a
BH
34
35#include <libfdt.h>
36
37#define FDT_MAX_SIZE 0x00100000
38
39#define FW_FILE_NAME "skiboot.lid"
40#define FW_LOAD_ADDR 0x0
41#define FW_MAX_SIZE 0x00400000
42
43#define KERNEL_LOAD_ADDR 0x20000000
44#define INITRD_LOAD_ADDR 0x40000000
45
46/*
47 * On Power Systems E880 (POWER8), the max cpus (threads) should be :
48 * 4 * 4 sockets * 12 cores * 8 threads = 1536
49 * Let's make it 2^11
50 */
51#define MAX_CPUS 2048
52
53/*
54 * Memory nodes are created by hostboot, one for each range of memory
55 * that has a different "affinity". In practice, it means one range
56 * per chip.
57 */
58static void powernv_populate_memory_node(void *fdt, int chip_id, hwaddr start,
59 hwaddr size)
60{
61 char *mem_name;
62 uint64_t mem_reg_property[2];
63 int off;
64
65 mem_reg_property[0] = cpu_to_be64(start);
66 mem_reg_property[1] = cpu_to_be64(size);
67
68 mem_name = g_strdup_printf("memory@%"HWADDR_PRIx, start);
69 off = fdt_add_subnode(fdt, 0, mem_name);
70 g_free(mem_name);
71
72 _FDT((fdt_setprop_string(fdt, off, "device_type", "memory")));
73 _FDT((fdt_setprop(fdt, off, "reg", mem_reg_property,
74 sizeof(mem_reg_property))));
75 _FDT((fdt_setprop_cell(fdt, off, "ibm,chip-id", chip_id)));
76}
77
e997040e
CLG
78static void powernv_populate_chip(PnvChip *chip, void *fdt)
79{
80 if (chip->ram_size) {
81 powernv_populate_memory_node(fdt, chip->chip_id, chip->ram_start,
82 chip->ram_size);
83 }
84}
85
9e933f4a
BH
86static void *powernv_create_fdt(MachineState *machine)
87{
88 const char plat_compat[] = "qemu,powernv\0ibm,powernv";
89 PnvMachineState *pnv = POWERNV_MACHINE(machine);
90 void *fdt;
91 char *buf;
92 int off;
e997040e 93 int i;
9e933f4a
BH
94
95 fdt = g_malloc0(FDT_MAX_SIZE);
96 _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE)));
97
98 /* Root node */
99 _FDT((fdt_setprop_cell(fdt, 0, "#address-cells", 0x2)));
100 _FDT((fdt_setprop_cell(fdt, 0, "#size-cells", 0x2)));
101 _FDT((fdt_setprop_string(fdt, 0, "model",
102 "IBM PowerNV (emulated by qemu)")));
103 _FDT((fdt_setprop(fdt, 0, "compatible", plat_compat,
104 sizeof(plat_compat))));
105
106 buf = qemu_uuid_unparse_strdup(&qemu_uuid);
107 _FDT((fdt_setprop_string(fdt, 0, "vm,uuid", buf)));
108 if (qemu_uuid_set) {
109 _FDT((fdt_property_string(fdt, "system-id", buf)));
110 }
111 g_free(buf);
112
113 off = fdt_add_subnode(fdt, 0, "chosen");
114 if (machine->kernel_cmdline) {
115 _FDT((fdt_setprop_string(fdt, off, "bootargs",
116 machine->kernel_cmdline)));
117 }
118
119 if (pnv->initrd_size) {
120 uint32_t start_prop = cpu_to_be32(pnv->initrd_base);
121 uint32_t end_prop = cpu_to_be32(pnv->initrd_base + pnv->initrd_size);
122
123 _FDT((fdt_setprop(fdt, off, "linux,initrd-start",
124 &start_prop, sizeof(start_prop))));
125 _FDT((fdt_setprop(fdt, off, "linux,initrd-end",
126 &end_prop, sizeof(end_prop))));
127 }
128
e997040e
CLG
129 /* Populate device tree for each chip */
130 for (i = 0; i < pnv->num_chips; i++) {
131 powernv_populate_chip(pnv->chips[i], fdt);
132 }
9e933f4a
BH
133 return fdt;
134}
135
136static void ppc_powernv_reset(void)
137{
138 MachineState *machine = MACHINE(qdev_get_machine());
139 void *fdt;
140
141 qemu_devices_reset();
142
143 fdt = powernv_create_fdt(machine);
144
145 /* Pack resulting tree */
146 _FDT((fdt_pack(fdt)));
147
148 cpu_physical_memory_write(PNV_FDT_ADDR, fdt, fdt_totalsize(fdt));
149}
150
151static void ppc_powernv_init(MachineState *machine)
152{
153 PnvMachineState *pnv = POWERNV_MACHINE(machine);
154 MemoryRegion *ram;
155 char *fw_filename;
156 long fw_size;
e997040e
CLG
157 int i;
158 char *chip_typename;
9e933f4a
BH
159
160 /* allocate RAM */
161 if (machine->ram_size < (1 * G_BYTE)) {
162 error_report("Warning: skiboot may not work with < 1GB of RAM");
163 }
164
165 ram = g_new(MemoryRegion, 1);
166 memory_region_allocate_system_memory(ram, NULL, "ppc_powernv.ram",
167 machine->ram_size);
168 memory_region_add_subregion(get_system_memory(), 0, ram);
169
170 /* load skiboot firmware */
171 if (bios_name == NULL) {
172 bios_name = FW_FILE_NAME;
173 }
174
175 fw_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
176
177 fw_size = load_image_targphys(fw_filename, FW_LOAD_ADDR, FW_MAX_SIZE);
178 if (fw_size < 0) {
179 hw_error("qemu: could not load OPAL '%s'\n", fw_filename);
180 exit(1);
181 }
182 g_free(fw_filename);
183
184 /* load kernel */
185 if (machine->kernel_filename) {
186 long kernel_size;
187
188 kernel_size = load_image_targphys(machine->kernel_filename,
189 KERNEL_LOAD_ADDR, 0x2000000);
190 if (kernel_size < 0) {
191 hw_error("qemu: could not load kernel'%s'\n",
192 machine->kernel_filename);
193 exit(1);
194 }
195 }
196
197 /* load initrd */
198 if (machine->initrd_filename) {
199 pnv->initrd_base = INITRD_LOAD_ADDR;
200 pnv->initrd_size = load_image_targphys(machine->initrd_filename,
201 pnv->initrd_base, 0x10000000); /* 128MB max */
202 if (pnv->initrd_size < 0) {
203 error_report("qemu: could not load initial ram disk '%s'",
204 machine->initrd_filename);
205 exit(1);
206 }
207 }
e997040e
CLG
208
209 /* We need some cpu model to instantiate the PnvChip class */
210 if (machine->cpu_model == NULL) {
211 machine->cpu_model = "POWER8";
212 }
213
214 /* Create the processor chips */
215 chip_typename = g_strdup_printf(TYPE_PNV_CHIP "-%s", machine->cpu_model);
216 if (!object_class_by_name(chip_typename)) {
217 error_report("qemu: invalid CPU model '%s' for %s machine",
218 machine->cpu_model, MACHINE_GET_CLASS(machine)->name);
219 exit(1);
220 }
221
222 pnv->chips = g_new0(PnvChip *, pnv->num_chips);
223 for (i = 0; i < pnv->num_chips; i++) {
224 char chip_name[32];
225 Object *chip = object_new(chip_typename);
226
227 pnv->chips[i] = PNV_CHIP(chip);
228
229 /* TODO: put all the memory in one node on chip 0 until we find a
230 * way to specify different ranges for each chip
231 */
232 if (i == 0) {
233 object_property_set_int(chip, machine->ram_size, "ram-size",
234 &error_fatal);
235 }
236
237 snprintf(chip_name, sizeof(chip_name), "chip[%d]", PNV_CHIP_HWID(i));
238 object_property_add_child(OBJECT(pnv), chip_name, chip, &error_fatal);
239 object_property_set_int(chip, PNV_CHIP_HWID(i), "chip-id",
240 &error_fatal);
397a79e7 241 object_property_set_int(chip, smp_cores, "nr-cores", &error_fatal);
e997040e
CLG
242 object_property_set_bool(chip, true, "realized", &error_fatal);
243 }
244 g_free(chip_typename);
245}
246
397a79e7
CLG
247/* Allowed core identifiers on a POWER8 Processor Chip :
248 *
249 * <EX0 reserved>
250 * EX1 - Venice only
251 * EX2 - Venice only
252 * EX3 - Venice only
253 * EX4
254 * EX5
255 * EX6
256 * <EX7,8 reserved> <reserved>
257 * EX9 - Venice only
258 * EX10 - Venice only
259 * EX11 - Venice only
260 * EX12
261 * EX13
262 * EX14
263 * <EX15 reserved>
264 */
265#define POWER8E_CORE_MASK (0x7070ull)
266#define POWER8_CORE_MASK (0x7e7eull)
267
268/*
269 * POWER9 has 24 cores, ids starting at 0x20
270 */
271#define POWER9_CORE_MASK (0xffffff00000000ull)
272
e997040e
CLG
273static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
274{
275 DeviceClass *dc = DEVICE_CLASS(klass);
276 PnvChipClass *k = PNV_CHIP_CLASS(klass);
277
278 k->cpu_model = "POWER8E";
279 k->chip_type = PNV_CHIP_POWER8E;
280 k->chip_cfam_id = 0x221ef04980000000ull; /* P8 Murano DD2.1 */
397a79e7 281 k->cores_mask = POWER8E_CORE_MASK;
e997040e
CLG
282 dc->desc = "PowerNV Chip POWER8E";
283}
284
285static const TypeInfo pnv_chip_power8e_info = {
286 .name = TYPE_PNV_CHIP_POWER8E,
287 .parent = TYPE_PNV_CHIP,
288 .instance_size = sizeof(PnvChip),
289 .class_init = pnv_chip_power8e_class_init,
290};
291
292static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
293{
294 DeviceClass *dc = DEVICE_CLASS(klass);
295 PnvChipClass *k = PNV_CHIP_CLASS(klass);
296
297 k->cpu_model = "POWER8";
298 k->chip_type = PNV_CHIP_POWER8;
299 k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */
397a79e7 300 k->cores_mask = POWER8_CORE_MASK;
e997040e
CLG
301 dc->desc = "PowerNV Chip POWER8";
302}
303
304static const TypeInfo pnv_chip_power8_info = {
305 .name = TYPE_PNV_CHIP_POWER8,
306 .parent = TYPE_PNV_CHIP,
307 .instance_size = sizeof(PnvChip),
308 .class_init = pnv_chip_power8_class_init,
309};
310
311static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
312{
313 DeviceClass *dc = DEVICE_CLASS(klass);
314 PnvChipClass *k = PNV_CHIP_CLASS(klass);
315
316 k->cpu_model = "POWER8NVL";
317 k->chip_type = PNV_CHIP_POWER8NVL;
318 k->chip_cfam_id = 0x120d304980000000ull; /* P8 Naples DD1.0 */
397a79e7 319 k->cores_mask = POWER8_CORE_MASK;
e997040e
CLG
320 dc->desc = "PowerNV Chip POWER8NVL";
321}
322
323static const TypeInfo pnv_chip_power8nvl_info = {
324 .name = TYPE_PNV_CHIP_POWER8NVL,
325 .parent = TYPE_PNV_CHIP,
326 .instance_size = sizeof(PnvChip),
327 .class_init = pnv_chip_power8nvl_class_init,
328};
329
330static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
331{
332 DeviceClass *dc = DEVICE_CLASS(klass);
333 PnvChipClass *k = PNV_CHIP_CLASS(klass);
334
335 k->cpu_model = "POWER9";
336 k->chip_type = PNV_CHIP_POWER9;
337 k->chip_cfam_id = 0x100d104980000000ull; /* P9 Nimbus DD1.0 */
397a79e7 338 k->cores_mask = POWER9_CORE_MASK;
e997040e
CLG
339 dc->desc = "PowerNV Chip POWER9";
340}
341
342static const TypeInfo pnv_chip_power9_info = {
343 .name = TYPE_PNV_CHIP_POWER9,
344 .parent = TYPE_PNV_CHIP,
345 .instance_size = sizeof(PnvChip),
346 .class_init = pnv_chip_power9_class_init,
347};
348
397a79e7
CLG
349static void pnv_chip_core_sanitize(PnvChip *chip, Error **errp)
350{
351 PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
352 int cores_max;
353
354 /*
355 * No custom mask for this chip, let's use the default one from *
356 * the chip class
357 */
358 if (!chip->cores_mask) {
359 chip->cores_mask = pcc->cores_mask;
360 }
361
362 /* filter alien core ids ! some are reserved */
363 if ((chip->cores_mask & pcc->cores_mask) != chip->cores_mask) {
364 error_setg(errp, "warning: invalid core mask for chip Ox%"PRIx64" !",
365 chip->cores_mask);
366 return;
367 }
368 chip->cores_mask &= pcc->cores_mask;
369
370 /* now that we have a sane layout, let check the number of cores */
371 cores_max = hweight_long(chip->cores_mask);
372 if (chip->nr_cores > cores_max) {
373 error_setg(errp, "warning: too many cores for chip ! Limit is %d",
374 cores_max);
375 return;
376 }
377}
378
e997040e
CLG
379static void pnv_chip_realize(DeviceState *dev, Error **errp)
380{
397a79e7
CLG
381 PnvChip *chip = PNV_CHIP(dev);
382 Error *error = NULL;
383
384 /* Early checks on the core settings */
385 pnv_chip_core_sanitize(chip, &error);
386 if (error) {
387 error_propagate(errp, error);
388 return;
389 }
e997040e
CLG
390}
391
392static Property pnv_chip_properties[] = {
393 DEFINE_PROP_UINT32("chip-id", PnvChip, chip_id, 0),
394 DEFINE_PROP_UINT64("ram-start", PnvChip, ram_start, 0),
395 DEFINE_PROP_UINT64("ram-size", PnvChip, ram_size, 0),
397a79e7
CLG
396 DEFINE_PROP_UINT32("nr-cores", PnvChip, nr_cores, 1),
397 DEFINE_PROP_UINT64("cores-mask", PnvChip, cores_mask, 0x0),
e997040e
CLG
398 DEFINE_PROP_END_OF_LIST(),
399};
400
401static void pnv_chip_class_init(ObjectClass *klass, void *data)
402{
403 DeviceClass *dc = DEVICE_CLASS(klass);
404
405 dc->realize = pnv_chip_realize;
406 dc->props = pnv_chip_properties;
407 dc->desc = "PowerNV Chip";
408}
409
410static const TypeInfo pnv_chip_info = {
411 .name = TYPE_PNV_CHIP,
412 .parent = TYPE_SYS_BUS_DEVICE,
413 .class_init = pnv_chip_class_init,
414 .class_size = sizeof(PnvChipClass),
415 .abstract = true,
416};
417
418static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
419 void *opaque, Error **errp)
420{
421 visit_type_uint32(v, name, &POWERNV_MACHINE(obj)->num_chips, errp);
422}
423
424static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name,
425 void *opaque, Error **errp)
426{
427 PnvMachineState *pnv = POWERNV_MACHINE(obj);
428 uint32_t num_chips;
429 Error *local_err = NULL;
430
431 visit_type_uint32(v, name, &num_chips, &local_err);
432 if (local_err) {
433 error_propagate(errp, local_err);
434 return;
435 }
436
437 /*
438 * TODO: should we decide on how many chips we can create based
439 * on #cores and Venice vs. Murano vs. Naples chip type etc...,
440 */
441 if (!is_power_of_2(num_chips) || num_chips > 4) {
442 error_setg(errp, "invalid number of chips: '%d'", num_chips);
443 return;
444 }
445
446 pnv->num_chips = num_chips;
447}
448
449static void powernv_machine_initfn(Object *obj)
450{
451 PnvMachineState *pnv = POWERNV_MACHINE(obj);
452 pnv->num_chips = 1;
453}
454
455static void powernv_machine_class_props_init(ObjectClass *oc)
456{
457 object_class_property_add(oc, "num-chips", "uint32_t",
458 pnv_get_num_chips, pnv_set_num_chips,
459 NULL, NULL, NULL);
460 object_class_property_set_description(oc, "num-chips",
461 "Specifies the number of processor chips",
462 NULL);
9e933f4a
BH
463}
464
465static void powernv_machine_class_init(ObjectClass *oc, void *data)
466{
467 MachineClass *mc = MACHINE_CLASS(oc);
468
469 mc->desc = "IBM PowerNV (Non-Virtualized)";
470 mc->init = ppc_powernv_init;
471 mc->reset = ppc_powernv_reset;
472 mc->max_cpus = MAX_CPUS;
473 mc->block_default_type = IF_IDE; /* Pnv provides a AHCI device for
474 * storage */
475 mc->no_parallel = 1;
476 mc->default_boot_order = NULL;
477 mc->default_ram_size = 1 * G_BYTE;
e997040e
CLG
478
479 powernv_machine_class_props_init(oc);
9e933f4a
BH
480}
481
482static const TypeInfo powernv_machine_info = {
483 .name = TYPE_POWERNV_MACHINE,
484 .parent = TYPE_MACHINE,
485 .instance_size = sizeof(PnvMachineState),
e997040e 486 .instance_init = powernv_machine_initfn,
9e933f4a
BH
487 .class_init = powernv_machine_class_init,
488};
489
490static void powernv_machine_register_types(void)
491{
492 type_register_static(&powernv_machine_info);
e997040e
CLG
493 type_register_static(&pnv_chip_info);
494 type_register_static(&pnv_chip_power8e_info);
495 type_register_static(&pnv_chip_power8_info);
496 type_register_static(&pnv_chip_power8nvl_info);
497 type_register_static(&pnv_chip_power9_info);
9e933f4a
BH
498}
499
500type_init(powernv_machine_register_types)