xref: /qemu/hw/ppc/pnv.c (revision 9940412a)
19e933f4aSBenjamin Herrenschmidt /*
29e933f4aSBenjamin Herrenschmidt  * QEMU PowerPC PowerNV machine model
39e933f4aSBenjamin Herrenschmidt  *
49e933f4aSBenjamin Herrenschmidt  * Copyright (c) 2016, IBM Corporation.
59e933f4aSBenjamin Herrenschmidt  *
69e933f4aSBenjamin Herrenschmidt  * This library is free software; you can redistribute it and/or
79e933f4aSBenjamin Herrenschmidt  * modify it under the terms of the GNU Lesser General Public
89e933f4aSBenjamin Herrenschmidt  * License as published by the Free Software Foundation; either
9f70c5966SChetan Pant  * version 2.1 of the License, or (at your option) any later version.
109e933f4aSBenjamin Herrenschmidt  *
119e933f4aSBenjamin Herrenschmidt  * This library is distributed in the hope that it will be useful,
129e933f4aSBenjamin Herrenschmidt  * but WITHOUT ANY WARRANTY; without even the implied warranty of
139e933f4aSBenjamin Herrenschmidt  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
149e933f4aSBenjamin Herrenschmidt  * Lesser General Public License for more details.
159e933f4aSBenjamin Herrenschmidt  *
169e933f4aSBenjamin Herrenschmidt  * You should have received a copy of the GNU Lesser General Public
179e933f4aSBenjamin Herrenschmidt  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
189e933f4aSBenjamin Herrenschmidt  */
199e933f4aSBenjamin Herrenschmidt 
209e933f4aSBenjamin Herrenschmidt #include "qemu/osdep.h"
212c65db5eSPaolo Bonzini #include "qemu/datadir.h"
22fc6b3cf9SPhilippe Mathieu-Daudé #include "qemu/units.h"
23dd7ef911SCédric Le Goater #include "qemu/cutils.h"
249e933f4aSBenjamin Herrenschmidt #include "qapi/error.h"
2538d2448aSGreg Kurz #include "sysemu/qtest.h"
269e933f4aSBenjamin Herrenschmidt #include "sysemu/sysemu.h"
279e933f4aSBenjamin Herrenschmidt #include "sysemu/numa.h"
2871e8a915SMarkus Armbruster #include "sysemu/reset.h"
2954d31236SMarkus Armbruster #include "sysemu/runstate.h"
30d2528bdcSPaolo Bonzini #include "sysemu/cpus.h"
318d409261SCédric Le Goater #include "sysemu/device_tree.h"
3201b552b0SNicholas Piggin #include "sysemu/hw_accel.h"
33fcf5ef2aSThomas Huth #include "target/ppc/cpu.h"
349e933f4aSBenjamin Herrenschmidt #include "hw/ppc/fdt.h"
359e933f4aSBenjamin Herrenschmidt #include "hw/ppc/ppc.h"
369e933f4aSBenjamin Herrenschmidt #include "hw/ppc/pnv.h"
37d2fd9612SCédric Le Goater #include "hw/ppc/pnv_core.h"
389e933f4aSBenjamin Herrenschmidt #include "hw/loader.h"
3901b552b0SNicholas Piggin #include "hw/nmi.h"
40e997040eSCédric Le Goater #include "qapi/visitor.h"
4147fea43aSCédric Le Goater #include "monitor/monitor.h"
4247fea43aSCédric Le Goater #include "hw/intc/intc.h"
43aeaef83dSCédric Le Goater #include "hw/ipmi/ipmi.h"
4458969eeeSDavid Gibson #include "target/ppc/mmu-hash64.h"
454f9924c4SBenjamin Herrenschmidt #include "hw/pci/msi.h"
461f5d6b2aSDaniel Henrique Barboza #include "hw/pci-host/pnv_phb.h"
472c6fe2e2SMarkus Armbruster #include "hw/pci-host/pnv_phb3.h"
482c6fe2e2SMarkus Armbruster #include "hw/pci-host/pnv_phb4.h"
499e933f4aSBenjamin Herrenschmidt 
5036fc6f08SCédric Le Goater #include "hw/ppc/xics.h"
51a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
522c6fe2e2SMarkus Armbruster #include "hw/ppc/pnv_chip.h"
53967b7523SCédric Le Goater #include "hw/ppc/pnv_xscom.h"
5435dde576SCédric Le Goater #include "hw/ppc/pnv_pnor.h"
55967b7523SCédric Le Goater 
563495b6b6SCédric Le Goater #include "hw/isa/isa.h"
573495b6b6SCédric Le Goater #include "hw/char/serial.h"
58bcdb9064SPhilippe Mathieu-Daudé #include "hw/rtc/mc146818rtc.h"
593495b6b6SCédric Le Goater 
609e933f4aSBenjamin Herrenschmidt #include <libfdt.h>
619e933f4aSBenjamin Herrenschmidt 
62b268a616SMurilo Opsfelder Araujo #define FDT_MAX_SIZE            (1 * MiB)
639e933f4aSBenjamin Herrenschmidt 
649e933f4aSBenjamin Herrenschmidt #define FW_FILE_NAME            "skiboot.lid"
659e933f4aSBenjamin Herrenschmidt #define FW_LOAD_ADDR            0x0
6683fa6e2aSCédric Le Goater #define FW_MAX_SIZE             (16 * MiB)
679e933f4aSBenjamin Herrenschmidt 
689e933f4aSBenjamin Herrenschmidt #define KERNEL_LOAD_ADDR        0x20000000
6905ce9b73SCédric Le Goater #define KERNEL_MAX_SIZE         (128 * MiB)
7005ce9b73SCédric Le Goater #define INITRD_LOAD_ADDR        0x28000000
7105ce9b73SCédric Le Goater #define INITRD_MAX_SIZE         (128 * MiB)
729e933f4aSBenjamin Herrenschmidt 
pnv_chip_core_typename(const PnvChip * o)7340abf43fSIgor Mammedov static const char *pnv_chip_core_typename(const PnvChip *o)
7440abf43fSIgor Mammedov {
7540abf43fSIgor Mammedov     const char *chip_type = object_class_get_name(object_get_class(OBJECT(o)));
7640abf43fSIgor Mammedov     int len = strlen(chip_type) - strlen(PNV_CHIP_TYPE_SUFFIX);
7740abf43fSIgor Mammedov     char *s = g_strdup_printf(PNV_CORE_TYPE_NAME("%.*s"), len, chip_type);
7840abf43fSIgor Mammedov     const char *core_type = object_class_get_name(object_class_by_name(s));
7940abf43fSIgor Mammedov     g_free(s);
8040abf43fSIgor Mammedov     return core_type;
8140abf43fSIgor Mammedov }
8240abf43fSIgor Mammedov 
839e933f4aSBenjamin Herrenschmidt /*
849e933f4aSBenjamin Herrenschmidt  * On Power Systems E880 (POWER8), the max cpus (threads) should be :
859e933f4aSBenjamin Herrenschmidt  *     4 * 4 sockets * 12 cores * 8 threads = 1536
869e933f4aSBenjamin Herrenschmidt  * Let's make it 2^11
879e933f4aSBenjamin Herrenschmidt  */
889e933f4aSBenjamin Herrenschmidt #define MAX_CPUS                2048
899e933f4aSBenjamin Herrenschmidt 
909e933f4aSBenjamin Herrenschmidt /*
919e933f4aSBenjamin Herrenschmidt  * Memory nodes are created by hostboot, one for each range of memory
929e933f4aSBenjamin Herrenschmidt  * that has a different "affinity". In practice, it means one range
939e933f4aSBenjamin Herrenschmidt  * per chip.
949e933f4aSBenjamin Herrenschmidt  */
pnv_dt_memory(void * fdt,int chip_id,hwaddr start,hwaddr size)95b168a138SCédric Le Goater static void pnv_dt_memory(void *fdt, int chip_id, hwaddr start, hwaddr size)
969e933f4aSBenjamin Herrenschmidt {
979e933f4aSBenjamin Herrenschmidt     char *mem_name;
989e933f4aSBenjamin Herrenschmidt     uint64_t mem_reg_property[2];
999e933f4aSBenjamin Herrenschmidt     int off;
1009e933f4aSBenjamin Herrenschmidt 
1019e933f4aSBenjamin Herrenschmidt     mem_reg_property[0] = cpu_to_be64(start);
1029e933f4aSBenjamin Herrenschmidt     mem_reg_property[1] = cpu_to_be64(size);
1039e933f4aSBenjamin Herrenschmidt 
1049e933f4aSBenjamin Herrenschmidt     mem_name = g_strdup_printf("memory@%"HWADDR_PRIx, start);
1059e933f4aSBenjamin Herrenschmidt     off = fdt_add_subnode(fdt, 0, mem_name);
1069e933f4aSBenjamin Herrenschmidt     g_free(mem_name);
1079e933f4aSBenjamin Herrenschmidt 
1089e933f4aSBenjamin Herrenschmidt     _FDT((fdt_setprop_string(fdt, off, "device_type", "memory")));
1099e933f4aSBenjamin Herrenschmidt     _FDT((fdt_setprop(fdt, off, "reg", mem_reg_property,
1109e933f4aSBenjamin Herrenschmidt                        sizeof(mem_reg_property))));
1119e933f4aSBenjamin Herrenschmidt     _FDT((fdt_setprop_cell(fdt, off, "ibm,chip-id", chip_id)));
1129e933f4aSBenjamin Herrenschmidt }
1139e933f4aSBenjamin Herrenschmidt 
get_cpus_node(void * fdt)114d2fd9612SCédric Le Goater static int get_cpus_node(void *fdt)
115d2fd9612SCédric Le Goater {
116d2fd9612SCédric Le Goater     int cpus_offset = fdt_path_offset(fdt, "/cpus");
117d2fd9612SCédric Le Goater 
118d2fd9612SCédric Le Goater     if (cpus_offset < 0) {
119a4f3885cSGreg Kurz         cpus_offset = fdt_add_subnode(fdt, 0, "cpus");
120d2fd9612SCédric Le Goater         if (cpus_offset) {
121d2fd9612SCédric Le Goater             _FDT((fdt_setprop_cell(fdt, cpus_offset, "#address-cells", 0x1)));
122d2fd9612SCédric Le Goater             _FDT((fdt_setprop_cell(fdt, cpus_offset, "#size-cells", 0x0)));
123d2fd9612SCédric Le Goater         }
124d2fd9612SCédric Le Goater     }
125d2fd9612SCédric Le Goater     _FDT(cpus_offset);
126d2fd9612SCédric Le Goater     return cpus_offset;
127d2fd9612SCédric Le Goater }
128d2fd9612SCédric Le Goater 
129d2fd9612SCédric Le Goater /*
130d2fd9612SCédric Le Goater  * The PowerNV cores (and threads) need to use real HW ids and not an
131d2fd9612SCédric Le Goater  * incremental index like it has been done on other platforms. This HW
132d2fd9612SCédric Le Goater  * id is stored in the CPU PIR, it is used to create cpu nodes in the
133d2fd9612SCédric Le Goater  * device tree, used in XSCOM to address cores and in interrupt
134d2fd9612SCédric Le Goater  * servers.
135d2fd9612SCédric Le Goater  */
pnv_dt_core(PnvChip * chip,PnvCore * pc,void * fdt)136ce2b8536SNicholas Piggin static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
137d2fd9612SCédric Le Goater {
13808304a86SDavid Gibson     PowerPCCPU *cpu = pc->threads[0];
13908304a86SDavid Gibson     CPUState *cs = CPU(cpu);
140d2fd9612SCédric Le Goater     DeviceClass *dc = DEVICE_GET_CLASS(cs);
1418bd9530eSDavid Gibson     int smt_threads = CPU_CORE(pc)->nr_threads;
142d2fd9612SCédric Le Goater     CPUPPCState *env = &cpu->env;
143d2fd9612SCédric Le Goater     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
1449940412aSCaleb Schlossin     PnvChipClass *pnv_cc = PNV_CHIP_GET_CLASS(chip);
145a580fdcdSPhilippe Mathieu-Daudé     g_autofree uint32_t *servers_prop = g_new(uint32_t, smt_threads);
146d2fd9612SCédric Le Goater     int i;
1479940412aSCaleb Schlossin     uint32_t pir;
148d2fd9612SCédric Le Goater     uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
149d2fd9612SCédric Le Goater                        0xffffffff, 0xffffffff};
150d2fd9612SCédric Le Goater     uint32_t tbfreq = PNV_TIMEBASE_FREQ;
151d2fd9612SCédric Le Goater     uint32_t cpufreq = 1000000000;
152d2fd9612SCédric Le Goater     uint32_t page_sizes_prop[64];
153d2fd9612SCédric Le Goater     size_t page_sizes_prop_size;
154d2fd9612SCédric Le Goater     int offset;
155d2fd9612SCédric Le Goater     char *nodename;
156d2fd9612SCédric Le Goater     int cpus_offset = get_cpus_node(fdt);
157d2fd9612SCédric Le Goater 
1589940412aSCaleb Schlossin     pir = pnv_cc->chip_pir(chip, pc->hwid, 0);
1599940412aSCaleb Schlossin 
1609940412aSCaleb Schlossin     nodename = g_strdup_printf("%s@%x", dc->fw_name, pir);
161d2fd9612SCédric Le Goater     offset = fdt_add_subnode(fdt, cpus_offset, nodename);
162d2fd9612SCédric Le Goater     _FDT(offset);
163d2fd9612SCédric Le Goater     g_free(nodename);
164d2fd9612SCédric Le Goater 
165d2fd9612SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id", chip->chip_id)));
166d2fd9612SCédric Le Goater 
1679940412aSCaleb Schlossin     _FDT((fdt_setprop_cell(fdt, offset, "reg", pir)));
1689940412aSCaleb Schlossin     _FDT((fdt_setprop_cell(fdt, offset, "ibm,pir", pir)));
169d2fd9612SCédric Le Goater     _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));
170d2fd9612SCédric Le Goater 
171d2fd9612SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR])));
172d2fd9612SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size",
173d2fd9612SCédric Le Goater                             env->dcache_line_size)));
174d2fd9612SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size",
175d2fd9612SCédric Le Goater                             env->dcache_line_size)));
176d2fd9612SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size",
177d2fd9612SCédric Le Goater                             env->icache_line_size)));
178d2fd9612SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size",
179d2fd9612SCédric Le Goater                             env->icache_line_size)));
180d2fd9612SCédric Le Goater 
181d2fd9612SCédric Le Goater     if (pcc->l1_dcache_size) {
182d2fd9612SCédric Le Goater         _FDT((fdt_setprop_cell(fdt, offset, "d-cache-size",
183d2fd9612SCédric Le Goater                                pcc->l1_dcache_size)));
184d2fd9612SCédric Le Goater     } else {
1853dc6f869SAlistair Francis         warn_report("Unknown L1 dcache size for cpu");
186d2fd9612SCédric Le Goater     }
187d2fd9612SCédric Le Goater     if (pcc->l1_icache_size) {
188d2fd9612SCédric Le Goater         _FDT((fdt_setprop_cell(fdt, offset, "i-cache-size",
189d2fd9612SCédric Le Goater                                pcc->l1_icache_size)));
190d2fd9612SCédric Le Goater     } else {
1913dc6f869SAlistair Francis         warn_report("Unknown L1 icache size for cpu");
192d2fd9612SCédric Le Goater     }
193d2fd9612SCédric Le Goater 
194d2fd9612SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq)));
195d2fd9612SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq)));
19659b7c1c2SBalamuruhan S     _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size",
19759b7c1c2SBalamuruhan S                            cpu->hash64_opts->slb_size)));
198d2fd9612SCédric Le Goater     _FDT((fdt_setprop_string(fdt, offset, "status", "okay")));
199d2fd9612SCédric Le Goater     _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0)));
200d2fd9612SCédric Le Goater 
20103282a3aSLucas Mateus Castro (alqotel)     if (ppc_has_spr(cpu, SPR_PURR)) {
202d2fd9612SCédric Le Goater         _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0)));
203d2fd9612SCédric Le Goater     }
204d2fd9612SCédric Le Goater 
20558969eeeSDavid Gibson     if (ppc_hash64_has(cpu, PPC_HASH64_1TSEG)) {
206d2fd9612SCédric Le Goater         _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes",
207d2fd9612SCédric Le Goater                            segs, sizeof(segs))));
208d2fd9612SCédric Le Goater     }
209d2fd9612SCédric Le Goater 
21059b7c1c2SBalamuruhan S     /*
21159b7c1c2SBalamuruhan S      * Advertise VMX/VSX (vector extensions) if available
212d2fd9612SCédric Le Goater      *   0 / no property == no vector extensions
213d2fd9612SCédric Le Goater      *   1               == VMX / Altivec available
21459b7c1c2SBalamuruhan S      *   2               == VSX available
21559b7c1c2SBalamuruhan S      */
216d2fd9612SCédric Le Goater     if (env->insns_flags & PPC_ALTIVEC) {
217d2fd9612SCédric Le Goater         uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
218d2fd9612SCédric Le Goater 
219d2fd9612SCédric Le Goater         _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));
220d2fd9612SCédric Le Goater     }
221d2fd9612SCédric Le Goater 
22259b7c1c2SBalamuruhan S     /*
22359b7c1c2SBalamuruhan S      * Advertise DFP (Decimal Floating Point) if available
224d2fd9612SCédric Le Goater      *   0 / no property == no DFP
22559b7c1c2SBalamuruhan S      *   1               == DFP available
22659b7c1c2SBalamuruhan S      */
227d2fd9612SCédric Le Goater     if (env->insns_flags2 & PPC2_DFP) {
228d2fd9612SCédric Le Goater         _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
229d2fd9612SCédric Le Goater     }
230d2fd9612SCédric Le Goater 
231644a2c99SDavid Gibson     page_sizes_prop_size = ppc_create_page_sizes_prop(cpu, page_sizes_prop,
232d2fd9612SCédric Le Goater                                                       sizeof(page_sizes_prop));
233d2fd9612SCédric Le Goater     if (page_sizes_prop_size) {
234d2fd9612SCédric Le Goater         _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes",
235d2fd9612SCédric Le Goater                            page_sizes_prop, page_sizes_prop_size)));
236d2fd9612SCédric Le Goater     }
237d2fd9612SCédric Le Goater 
238d2fd9612SCédric Le Goater     /* Build interrupt servers properties */
239d2fd9612SCédric Le Goater     for (i = 0; i < smt_threads; i++) {
2409940412aSCaleb Schlossin         servers_prop[i] = cpu_to_be32(pnv_cc->chip_pir(chip, pc->hwid, i));
241d2fd9612SCédric Le Goater     }
242d2fd9612SCédric Le Goater     _FDT((fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
243a580fdcdSPhilippe Mathieu-Daudé                        servers_prop, sizeof(*servers_prop) * smt_threads)));
244ce2b8536SNicholas Piggin 
245ce2b8536SNicholas Piggin     return offset;
246d2fd9612SCédric Le Goater }
247d2fd9612SCédric Le Goater 
pnv_dt_icp(PnvChip * chip,void * fdt,uint32_t hwid,uint32_t nr_threads)2489940412aSCaleb Schlossin static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t hwid,
249bf5615e7SCédric Le Goater                        uint32_t nr_threads)
250bf5615e7SCédric Le Goater {
2519940412aSCaleb Schlossin     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
2529940412aSCaleb Schlossin     uint32_t pir = pcc->chip_pir(chip, hwid, 0);
253bf5615e7SCédric Le Goater     uint64_t addr = PNV_ICP_BASE(chip) | (pir << 12);
254bf5615e7SCédric Le Goater     char *name;
255bf5615e7SCédric Le Goater     const char compat[] = "IBM,power8-icp\0IBM,ppc-xicp";
256bf5615e7SCédric Le Goater     uint32_t irange[2], i, rsize;
257bf5615e7SCédric Le Goater     uint64_t *reg;
258bf5615e7SCédric Le Goater     int offset;
259bf5615e7SCédric Le Goater 
260bf5615e7SCédric Le Goater     irange[0] = cpu_to_be32(pir);
261bf5615e7SCédric Le Goater     irange[1] = cpu_to_be32(nr_threads);
262bf5615e7SCédric Le Goater 
263bf5615e7SCédric Le Goater     rsize = sizeof(uint64_t) * 2 * nr_threads;
264bf5615e7SCédric Le Goater     reg = g_malloc(rsize);
265bf5615e7SCédric Le Goater     for (i = 0; i < nr_threads; i++) {
2669940412aSCaleb Schlossin         /* We know P8 PIR is linear with thread id */
267bf5615e7SCédric Le Goater         reg[i * 2] = cpu_to_be64(addr | ((pir + i) * 0x1000));
268bf5615e7SCédric Le Goater         reg[i * 2 + 1] = cpu_to_be64(0x1000);
269bf5615e7SCédric Le Goater     }
270bf5615e7SCédric Le Goater 
271bf5615e7SCédric Le Goater     name = g_strdup_printf("interrupt-controller@%"PRIX64, addr);
272bf5615e7SCédric Le Goater     offset = fdt_add_subnode(fdt, 0, name);
273bf5615e7SCédric Le Goater     _FDT(offset);
274bf5615e7SCédric Le Goater     g_free(name);
275bf5615e7SCédric Le Goater 
276bf5615e7SCédric Le Goater     _FDT((fdt_setprop(fdt, offset, "compatible", compat, sizeof(compat))));
277bf5615e7SCédric Le Goater     _FDT((fdt_setprop(fdt, offset, "reg", reg, rsize)));
278bf5615e7SCédric Le Goater     _FDT((fdt_setprop_string(fdt, offset, "device_type",
279bf5615e7SCédric Le Goater                               "PowerPC-External-Interrupt-Presentation")));
280bf5615e7SCédric Le Goater     _FDT((fdt_setprop(fdt, offset, "interrupt-controller", NULL, 0)));
281bf5615e7SCédric Le Goater     _FDT((fdt_setprop(fdt, offset, "ibm,interrupt-server-ranges",
282bf5615e7SCédric Le Goater                        irange, sizeof(irange))));
283bf5615e7SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, offset, "#interrupt-cells", 1)));
284bf5615e7SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0)));
285bf5615e7SCédric Le Goater     g_free(reg);
286bf5615e7SCédric Le Goater }
287bf5615e7SCédric Le Goater 
288ba47c3a4SDaniel Henrique Barboza /*
289ddf0676fSFrederic Barrat  * Adds a PnvPHB to the chip on P8.
290ddf0676fSFrederic Barrat  * Implemented here, like for defaults PHBs
291ba47c3a4SDaniel Henrique Barboza  */
pnv_chip_add_phb(PnvChip * chip,PnvPHB * phb)292ddf0676fSFrederic Barrat PnvChip *pnv_chip_add_phb(PnvChip *chip, PnvPHB *phb)
293ba47c3a4SDaniel Henrique Barboza {
2940d512c71SDaniel Henrique Barboza     Pnv8Chip *chip8 = PNV8_CHIP(chip);
2950d512c71SDaniel Henrique Barboza 
2960d512c71SDaniel Henrique Barboza     phb->chip = chip;
2970d512c71SDaniel Henrique Barboza 
2980d512c71SDaniel Henrique Barboza     chip8->phbs[chip8->num_phbs] = phb;
2990d512c71SDaniel Henrique Barboza     chip8->num_phbs++;
300ddf0676fSFrederic Barrat     return chip;
301ba47c3a4SDaniel Henrique Barboza }
302ba47c3a4SDaniel Henrique Barboza 
303ce2b8536SNicholas Piggin /*
304ce2b8536SNicholas Piggin  * Same as spapr pa_features_207 except pnv always enables CI largepages bit.
305ce2b8536SNicholas Piggin  * HTM is always enabled because TCG does implement HTM, it's just a
306ce2b8536SNicholas Piggin  * degenerate implementation.
307ce2b8536SNicholas Piggin  */
308ce2b8536SNicholas Piggin static const uint8_t pa_features_207[] = { 24, 0,
309ce2b8536SNicholas Piggin                  0xf6, 0x3f, 0xc7, 0xc0, 0x00, 0xf0,
310ce2b8536SNicholas Piggin                  0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
311ce2b8536SNicholas Piggin                  0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
312ce2b8536SNicholas Piggin                  0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
313ce2b8536SNicholas Piggin 
pnv_chip_power8_dt_populate(PnvChip * chip,void * fdt)314eb859a27SCédric Le Goater static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
315e997040eSCédric Le Goater {
316c396c58aSGreg Kurz     static const char compat[] = "ibm,power8-xscom\0ibm,xscom";
317d2fd9612SCédric Le Goater     int i;
318d2fd9612SCédric Le Goater 
3193f5b45caSGreg Kurz     pnv_dt_xscom(chip, fdt, 0,
3203f5b45caSGreg Kurz                  cpu_to_be64(PNV_XSCOM_BASE(chip)),
321c396c58aSGreg Kurz                  cpu_to_be64(PNV_XSCOM_SIZE),
322c396c58aSGreg Kurz                  compat, sizeof(compat));
323967b7523SCédric Le Goater 
324d2fd9612SCédric Le Goater     for (i = 0; i < chip->nr_cores; i++) {
3254fa28f23SGreg Kurz         PnvCore *pnv_core = chip->cores[i];
326ce2b8536SNicholas Piggin         int offset;
327d2fd9612SCédric Le Goater 
328ce2b8536SNicholas Piggin         offset = pnv_dt_core(chip, pnv_core, fdt);
329ce2b8536SNicholas Piggin 
330ce2b8536SNicholas Piggin         _FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
331ce2b8536SNicholas Piggin                            pa_features_207, sizeof(pa_features_207))));
332bf5615e7SCédric Le Goater 
333bf5615e7SCédric Le Goater         /* Interrupt Control Presenters (ICP). One per core. */
3349940412aSCaleb Schlossin         pnv_dt_icp(chip, fdt, pnv_core->hwid, CPU_CORE(pnv_core)->nr_threads);
335d2fd9612SCédric Le Goater     }
336d2fd9612SCédric Le Goater 
337e997040eSCédric Le Goater     if (chip->ram_size) {
338b168a138SCédric Le Goater         pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
339e997040eSCédric Le Goater     }
340e997040eSCédric Le Goater }
341e997040eSCédric Le Goater 
34224a9d20cSNicholas Piggin /*
34324a9d20cSNicholas Piggin  * Same as spapr pa_features_300 except pnv always enables CI largepages bit.
34424a9d20cSNicholas Piggin  */
34524a9d20cSNicholas Piggin static const uint8_t pa_features_300[] = { 66, 0,
34624a9d20cSNicholas Piggin     /* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: CILRG|fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
34724a9d20cSNicholas Piggin     /* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
34824a9d20cSNicholas Piggin     0xf6, 0x3f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
34924a9d20cSNicholas Piggin     /* 6: DS207 */
35024a9d20cSNicholas Piggin     0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
35124a9d20cSNicholas Piggin     /* 16: Vector */
35224a9d20cSNicholas Piggin     0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
35324a9d20cSNicholas Piggin     /* 18: Vec. Scalar, 20: Vec. XOR, 22: HTM */
35424a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 18 - 23 */
35524a9d20cSNicholas Piggin     /* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
35624a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
35724a9d20cSNicholas Piggin     /* 32: LE atomic, 34: EBB + ext EBB */
35824a9d20cSNicholas Piggin     0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
35924a9d20cSNicholas Piggin     /* 40: Radix MMU */
36024a9d20cSNicholas Piggin     0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
36124a9d20cSNicholas Piggin     /* 42: PM, 44: PC RA, 46: SC vec'd */
36224a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
36324a9d20cSNicholas Piggin     /* 48: SIMD, 50: QP BFP, 52: String */
36424a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
36524a9d20cSNicholas Piggin     /* 54: DecFP, 56: DecI, 58: SHA */
36624a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
36724a9d20cSNicholas Piggin     /* 60: NM atomic, 62: RNG */
36824a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
36924a9d20cSNicholas Piggin };
37024a9d20cSNicholas Piggin 
pnv_chip_power9_dt_populate(PnvChip * chip,void * fdt)371eb859a27SCédric Le Goater static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
372eb859a27SCédric Le Goater {
373c396c58aSGreg Kurz     static const char compat[] = "ibm,power9-xscom\0ibm,xscom";
374eb859a27SCédric Le Goater     int i;
375eb859a27SCédric Le Goater 
3763f5b45caSGreg Kurz     pnv_dt_xscom(chip, fdt, 0,
3773f5b45caSGreg Kurz                  cpu_to_be64(PNV9_XSCOM_BASE(chip)),
378c396c58aSGreg Kurz                  cpu_to_be64(PNV9_XSCOM_SIZE),
379c396c58aSGreg Kurz                  compat, sizeof(compat));
380eb859a27SCédric Le Goater 
381eb859a27SCédric Le Goater     for (i = 0; i < chip->nr_cores; i++) {
3824fa28f23SGreg Kurz         PnvCore *pnv_core = chip->cores[i];
383ce2b8536SNicholas Piggin         int offset;
384eb859a27SCédric Le Goater 
385ce2b8536SNicholas Piggin         offset = pnv_dt_core(chip, pnv_core, fdt);
386ce2b8536SNicholas Piggin 
387ce2b8536SNicholas Piggin         _FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
38824a9d20cSNicholas Piggin                            pa_features_300, sizeof(pa_features_300))));
389eb859a27SCédric Le Goater     }
390eb859a27SCédric Le Goater 
391eb859a27SCédric Le Goater     if (chip->ram_size) {
392eb859a27SCédric Le Goater         pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
393eb859a27SCédric Le Goater     }
39415376c66SCédric Le Goater 
3952661f6abSCédric Le Goater     pnv_dt_lpc(chip, fdt, 0, PNV9_LPCM_BASE(chip), PNV9_LPCM_SIZE);
396eb859a27SCédric Le Goater }
397eb859a27SCédric Le Goater 
39824a9d20cSNicholas Piggin /*
39924a9d20cSNicholas Piggin  * Same as spapr pa_features_31 except pnv always enables CI largepages bit,
40024a9d20cSNicholas Piggin  * always disables copy/paste.
40124a9d20cSNicholas Piggin  */
40224a9d20cSNicholas Piggin static const uint8_t pa_features_31[] = { 74, 0,
40324a9d20cSNicholas Piggin     /* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: CILRG|fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
40424a9d20cSNicholas Piggin     /* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
40524a9d20cSNicholas Piggin     0xf6, 0x3f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
40624a9d20cSNicholas Piggin     /* 6: DS207 */
40724a9d20cSNicholas Piggin     0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
40824a9d20cSNicholas Piggin     /* 16: Vector */
40924a9d20cSNicholas Piggin     0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
41024a9d20cSNicholas Piggin     /* 18: Vec. Scalar, 20: Vec. XOR */
41124a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
41224a9d20cSNicholas Piggin     /* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
41324a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
41424a9d20cSNicholas Piggin     /* 32: LE atomic, 34: EBB + ext EBB */
41524a9d20cSNicholas Piggin     0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
41624a9d20cSNicholas Piggin     /* 40: Radix MMU */
41724a9d20cSNicholas Piggin     0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
41824a9d20cSNicholas Piggin     /* 42: PM, 44: PC RA, 46: SC vec'd */
41924a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
42024a9d20cSNicholas Piggin     /* 48: SIMD, 50: QP BFP, 52: String */
42124a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
42224a9d20cSNicholas Piggin     /* 54: DecFP, 56: DecI, 58: SHA */
42324a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
42424a9d20cSNicholas Piggin     /* 60: NM atomic, 62: RNG */
42524a9d20cSNicholas Piggin     0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
42624a9d20cSNicholas Piggin     /* 68: DEXCR[SBHE|IBRTPDUS|SRAPD|NPHIE|PHIE] */
42724a9d20cSNicholas Piggin     0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 66 - 71 */
42824a9d20cSNicholas Piggin     /* 72: [P]HASHST/[P]HASHCHK */
42924a9d20cSNicholas Piggin     0x80, 0x00,                         /* 72 - 73 */
43024a9d20cSNicholas Piggin };
43124a9d20cSNicholas Piggin 
pnv_chip_power10_dt_populate(PnvChip * chip,void * fdt)4322b548a42SCédric Le Goater static void pnv_chip_power10_dt_populate(PnvChip *chip, void *fdt)
4332b548a42SCédric Le Goater {
434c396c58aSGreg Kurz     static const char compat[] = "ibm,power10-xscom\0ibm,xscom";
4352b548a42SCédric Le Goater     int i;
4362b548a42SCédric Le Goater 
4373f5b45caSGreg Kurz     pnv_dt_xscom(chip, fdt, 0,
4383f5b45caSGreg Kurz                  cpu_to_be64(PNV10_XSCOM_BASE(chip)),
439c396c58aSGreg Kurz                  cpu_to_be64(PNV10_XSCOM_SIZE),
440c396c58aSGreg Kurz                  compat, sizeof(compat));
4412b548a42SCédric Le Goater 
4422b548a42SCédric Le Goater     for (i = 0; i < chip->nr_cores; i++) {
4432b548a42SCédric Le Goater         PnvCore *pnv_core = chip->cores[i];
444ce2b8536SNicholas Piggin         int offset;
4452b548a42SCédric Le Goater 
446ce2b8536SNicholas Piggin         offset = pnv_dt_core(chip, pnv_core, fdt);
447ce2b8536SNicholas Piggin 
448ce2b8536SNicholas Piggin         _FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
44924a9d20cSNicholas Piggin                            pa_features_31, sizeof(pa_features_31))));
4502b548a42SCédric Le Goater     }
4512b548a42SCédric Le Goater 
4522b548a42SCédric Le Goater     if (chip->ram_size) {
4532b548a42SCédric Le Goater         pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
4542b548a42SCédric Le Goater     }
4552661f6abSCédric Le Goater 
4562661f6abSCédric Le Goater     pnv_dt_lpc(chip, fdt, 0, PNV10_LPCM_BASE(chip), PNV10_LPCM_SIZE);
4572b548a42SCédric Le Goater }
4582b548a42SCédric Le Goater 
pnv_dt_rtc(ISADevice * d,void * fdt,int lpc_off)459b168a138SCédric Le Goater static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
460c5ffdcaeSCédric Le Goater {
461c5ffdcaeSCédric Le Goater     uint32_t io_base = d->ioport_id;
462c5ffdcaeSCédric Le Goater     uint32_t io_regs[] = {
463c5ffdcaeSCédric Le Goater         cpu_to_be32(1),
464c5ffdcaeSCédric Le Goater         cpu_to_be32(io_base),
465c5ffdcaeSCédric Le Goater         cpu_to_be32(2)
466c5ffdcaeSCédric Le Goater     };
467c5ffdcaeSCédric Le Goater     char *name;
468c5ffdcaeSCédric Le Goater     int node;
469c5ffdcaeSCédric Le Goater 
470c5ffdcaeSCédric Le Goater     name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base);
471c5ffdcaeSCédric Le Goater     node = fdt_add_subnode(fdt, lpc_off, name);
472c5ffdcaeSCédric Le Goater     _FDT(node);
473c5ffdcaeSCédric Le Goater     g_free(name);
474c5ffdcaeSCédric Le Goater 
475c5ffdcaeSCédric Le Goater     _FDT((fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs))));
476c5ffdcaeSCédric Le Goater     _FDT((fdt_setprop_string(fdt, node, "compatible", "pnpPNP,b00")));
477c5ffdcaeSCédric Le Goater }
478c5ffdcaeSCédric Le Goater 
pnv_dt_serial(ISADevice * d,void * fdt,int lpc_off)479b168a138SCédric Le Goater static void pnv_dt_serial(ISADevice *d, void *fdt, int lpc_off)
480cb228f5aSCédric Le Goater {
481cb228f5aSCédric Le Goater     const char compatible[] = "ns16550\0pnpPNP,501";
482cb228f5aSCédric Le Goater     uint32_t io_base = d->ioport_id;
483cb228f5aSCédric Le Goater     uint32_t io_regs[] = {
484cb228f5aSCédric Le Goater         cpu_to_be32(1),
485cb228f5aSCédric Le Goater         cpu_to_be32(io_base),
486cb228f5aSCédric Le Goater         cpu_to_be32(8)
487cb228f5aSCédric Le Goater     };
488632fc0b3SBernhard Beschow     uint32_t irq;
489cb228f5aSCédric Le Goater     char *name;
490cb228f5aSCédric Le Goater     int node;
491cb228f5aSCédric Le Goater 
492632fc0b3SBernhard Beschow     irq = object_property_get_uint(OBJECT(d), "irq", &error_fatal);
493632fc0b3SBernhard Beschow 
494cb228f5aSCédric Le Goater     name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base);
495cb228f5aSCédric Le Goater     node = fdt_add_subnode(fdt, lpc_off, name);
496cb228f5aSCédric Le Goater     _FDT(node);
497cb228f5aSCédric Le Goater     g_free(name);
498cb228f5aSCédric Le Goater 
499cb228f5aSCédric Le Goater     _FDT((fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs))));
500cb228f5aSCédric Le Goater     _FDT((fdt_setprop(fdt, node, "compatible", compatible,
501cb228f5aSCédric Le Goater                       sizeof(compatible))));
502cb228f5aSCédric Le Goater 
503cb228f5aSCédric Le Goater     _FDT((fdt_setprop_cell(fdt, node, "clock-frequency", 1843200)));
504cb228f5aSCédric Le Goater     _FDT((fdt_setprop_cell(fdt, node, "current-speed", 115200)));
505632fc0b3SBernhard Beschow     _FDT((fdt_setprop_cell(fdt, node, "interrupts", irq)));
506cb228f5aSCédric Le Goater     _FDT((fdt_setprop_cell(fdt, node, "interrupt-parent",
507cb228f5aSCédric Le Goater                            fdt_get_phandle(fdt, lpc_off))));
508cb228f5aSCédric Le Goater 
509cb228f5aSCédric Le Goater     /* This is needed by Linux */
510cb228f5aSCédric Le Goater     _FDT((fdt_setprop_string(fdt, node, "device_type", "serial")));
511cb228f5aSCédric Le Goater }
512cb228f5aSCédric Le Goater 
pnv_dt_ipmi_bt(ISADevice * d,void * fdt,int lpc_off)513b168a138SCédric Le Goater static void pnv_dt_ipmi_bt(ISADevice *d, void *fdt, int lpc_off)
51404f6c8b2SCédric Le Goater {
51504f6c8b2SCédric Le Goater     const char compatible[] = "bt\0ipmi-bt";
51604f6c8b2SCédric Le Goater     uint32_t io_base;
51704f6c8b2SCédric Le Goater     uint32_t io_regs[] = {
51804f6c8b2SCédric Le Goater         cpu_to_be32(1),
51904f6c8b2SCédric Le Goater         0, /* 'io_base' retrieved from the 'ioport' property of 'isa-ipmi-bt' */
52004f6c8b2SCédric Le Goater         cpu_to_be32(3)
52104f6c8b2SCédric Le Goater     };
52204f6c8b2SCédric Le Goater     uint32_t irq;
52304f6c8b2SCédric Le Goater     char *name;
52404f6c8b2SCédric Le Goater     int node;
52504f6c8b2SCédric Le Goater 
52604f6c8b2SCédric Le Goater     io_base = object_property_get_int(OBJECT(d), "ioport", &error_fatal);
52704f6c8b2SCédric Le Goater     io_regs[1] = cpu_to_be32(io_base);
52804f6c8b2SCédric Le Goater 
52904f6c8b2SCédric Le Goater     irq = object_property_get_int(OBJECT(d), "irq", &error_fatal);
53004f6c8b2SCédric Le Goater 
53104f6c8b2SCédric Le Goater     name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base);
53204f6c8b2SCédric Le Goater     node = fdt_add_subnode(fdt, lpc_off, name);
53304f6c8b2SCédric Le Goater     _FDT(node);
53404f6c8b2SCédric Le Goater     g_free(name);
53504f6c8b2SCédric Le Goater 
5367032d92aSCédric Le Goater     _FDT((fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs))));
5377032d92aSCédric Le Goater     _FDT((fdt_setprop(fdt, node, "compatible", compatible,
5387032d92aSCédric Le Goater                       sizeof(compatible))));
53904f6c8b2SCédric Le Goater 
54004f6c8b2SCédric Le Goater     /* Mark it as reserved to avoid Linux trying to claim it */
54104f6c8b2SCédric Le Goater     _FDT((fdt_setprop_string(fdt, node, "status", "reserved")));
54204f6c8b2SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, node, "interrupts", irq)));
54304f6c8b2SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, node, "interrupt-parent",
54404f6c8b2SCédric Le Goater                            fdt_get_phandle(fdt, lpc_off))));
54504f6c8b2SCédric Le Goater }
54604f6c8b2SCédric Le Goater 
547e7a3fee3SCédric Le Goater typedef struct ForeachPopulateArgs {
548e7a3fee3SCédric Le Goater     void *fdt;
549e7a3fee3SCédric Le Goater     int offset;
550e7a3fee3SCédric Le Goater } ForeachPopulateArgs;
551e7a3fee3SCédric Le Goater 
pnv_dt_isa_device(DeviceState * dev,void * opaque)552b168a138SCédric Le Goater static int pnv_dt_isa_device(DeviceState *dev, void *opaque)
553e7a3fee3SCédric Le Goater {
554c5ffdcaeSCédric Le Goater     ForeachPopulateArgs *args = opaque;
555c5ffdcaeSCédric Le Goater     ISADevice *d = ISA_DEVICE(dev);
556c5ffdcaeSCédric Le Goater 
557c5ffdcaeSCédric Le Goater     if (object_dynamic_cast(OBJECT(dev), TYPE_MC146818_RTC)) {
558b168a138SCédric Le Goater         pnv_dt_rtc(d, args->fdt, args->offset);
559cb228f5aSCédric Le Goater     } else if (object_dynamic_cast(OBJECT(dev), TYPE_ISA_SERIAL)) {
560b168a138SCédric Le Goater         pnv_dt_serial(d, args->fdt, args->offset);
56104f6c8b2SCédric Le Goater     } else if (object_dynamic_cast(OBJECT(dev), "isa-ipmi-bt")) {
562b168a138SCédric Le Goater         pnv_dt_ipmi_bt(d, args->fdt, args->offset);
563c5ffdcaeSCédric Le Goater     } else {
564c5ffdcaeSCédric Le Goater         error_report("unknown isa device %s@i%x", qdev_fw_name(dev),
565c5ffdcaeSCédric Le Goater                      d->ioport_id);
566c5ffdcaeSCédric Le Goater     }
567c5ffdcaeSCédric Le Goater 
568e7a3fee3SCédric Le Goater     return 0;
569e7a3fee3SCédric Le Goater }
570e7a3fee3SCédric Le Goater 
57159b7c1c2SBalamuruhan S /*
57259b7c1c2SBalamuruhan S  * The default LPC bus of a multichip system is on chip 0. It's
573bb7ab95cSCédric Le Goater  * recognized by the firmware (skiboot) using a "primary" property.
574bb7ab95cSCédric Le Goater  */
pnv_dt_isa(PnvMachineState * pnv,void * fdt)575bb7ab95cSCédric Le Goater static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
576bb7ab95cSCédric Le Goater {
57764d011d5SCédric Le Goater     int isa_offset = fdt_path_offset(fdt, pnv->chips[0]->dt_isa_nodename);
578e7a3fee3SCédric Le Goater     ForeachPopulateArgs args = {
579e7a3fee3SCédric Le Goater         .fdt = fdt,
580bb7ab95cSCédric Le Goater         .offset = isa_offset,
581e7a3fee3SCédric Le Goater     };
582f47a08d1SCédric Le Goater     uint32_t phandle;
583e7a3fee3SCédric Le Goater 
584bb7ab95cSCédric Le Goater     _FDT((fdt_setprop(fdt, isa_offset, "primary", NULL, 0)));
585bb7ab95cSCédric Le Goater 
586f47a08d1SCédric Le Goater     phandle = qemu_fdt_alloc_phandle(fdt);
587f47a08d1SCédric Le Goater     assert(phandle > 0);
588f47a08d1SCédric Le Goater     _FDT((fdt_setprop_cell(fdt, isa_offset, "phandle", phandle)));
589f47a08d1SCédric Le Goater 
59059b7c1c2SBalamuruhan S     /*
59159b7c1c2SBalamuruhan S      * ISA devices are not necessarily parented to the ISA bus so we
59259b7c1c2SBalamuruhan S      * can not use object_child_foreach()
59359b7c1c2SBalamuruhan S      */
594bb7ab95cSCédric Le Goater     qbus_walk_children(BUS(pnv->isa_bus), pnv_dt_isa_device, NULL, NULL, NULL,
595bb7ab95cSCédric Le Goater                        &args);
596e7a3fee3SCédric Le Goater }
597e7a3fee3SCédric Le Goater 
pnv_dt_power_mgt(PnvMachineState * pnv,void * fdt)5987a90c6a1SGreg Kurz static void pnv_dt_power_mgt(PnvMachineState *pnv, void *fdt)
599e5694793SCédric Le Goater {
600e5694793SCédric Le Goater     int off;
601e5694793SCédric Le Goater 
602e5694793SCédric Le Goater     off = fdt_add_subnode(fdt, 0, "ibm,opal");
603e5694793SCédric Le Goater     off = fdt_add_subnode(fdt, off, "power-mgt");
604e5694793SCédric Le Goater 
605e5694793SCédric Le Goater     _FDT(fdt_setprop_cell(fdt, off, "ibm,enabled-stop-levels", 0xc0000000));
606e5694793SCédric Le Goater }
607e5694793SCédric Le Goater 
pnv_dt_create(MachineState * machine)608b168a138SCédric Le Goater static void *pnv_dt_create(MachineState *machine)
6099e933f4aSBenjamin Herrenschmidt {
610d76f2da7SGreg Kurz     PnvMachineClass *pmc = PNV_MACHINE_GET_CLASS(machine);
611b168a138SCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(machine);
6129e933f4aSBenjamin Herrenschmidt     void *fdt;
6139e933f4aSBenjamin Herrenschmidt     char *buf;
6149e933f4aSBenjamin Herrenschmidt     int off;
615e997040eSCédric Le Goater     int i;
6169e933f4aSBenjamin Herrenschmidt 
6179e933f4aSBenjamin Herrenschmidt     fdt = g_malloc0(FDT_MAX_SIZE);
6189e933f4aSBenjamin Herrenschmidt     _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE)));
6199e933f4aSBenjamin Herrenschmidt 
620ccb099b3SCédric Le Goater     /* /qemu node */
621ccb099b3SCédric Le Goater     _FDT((fdt_add_subnode(fdt, 0, "qemu")));
622ccb099b3SCédric Le Goater 
6239e933f4aSBenjamin Herrenschmidt     /* Root node */
6249e933f4aSBenjamin Herrenschmidt     _FDT((fdt_setprop_cell(fdt, 0, "#address-cells", 0x2)));
6259e933f4aSBenjamin Herrenschmidt     _FDT((fdt_setprop_cell(fdt, 0, "#size-cells", 0x2)));
6269e933f4aSBenjamin Herrenschmidt     _FDT((fdt_setprop_string(fdt, 0, "model",
6279e933f4aSBenjamin Herrenschmidt                              "IBM PowerNV (emulated by qemu)")));
628d76f2da7SGreg Kurz     _FDT((fdt_setprop(fdt, 0, "compatible", pmc->compat, pmc->compat_size)));
6299e933f4aSBenjamin Herrenschmidt 
6309e933f4aSBenjamin Herrenschmidt     buf =  qemu_uuid_unparse_strdup(&qemu_uuid);
6319e933f4aSBenjamin Herrenschmidt     _FDT((fdt_setprop_string(fdt, 0, "vm,uuid", buf)));
6329e933f4aSBenjamin Herrenschmidt     if (qemu_uuid_set) {
633bbfbbff5SDaniel Henrique Barboza         _FDT((fdt_setprop_string(fdt, 0, "system-id", buf)));
6349e933f4aSBenjamin Herrenschmidt     }
6359e933f4aSBenjamin Herrenschmidt     g_free(buf);
6369e933f4aSBenjamin Herrenschmidt 
6379e933f4aSBenjamin Herrenschmidt     off = fdt_add_subnode(fdt, 0, "chosen");
6389e933f4aSBenjamin Herrenschmidt     if (machine->kernel_cmdline) {
6399e933f4aSBenjamin Herrenschmidt         _FDT((fdt_setprop_string(fdt, off, "bootargs",
6409e933f4aSBenjamin Herrenschmidt                                  machine->kernel_cmdline)));
6419e933f4aSBenjamin Herrenschmidt     }
6429e933f4aSBenjamin Herrenschmidt 
6439e933f4aSBenjamin Herrenschmidt     if (pnv->initrd_size) {
6449e933f4aSBenjamin Herrenschmidt         uint32_t start_prop = cpu_to_be32(pnv->initrd_base);
6459e933f4aSBenjamin Herrenschmidt         uint32_t end_prop = cpu_to_be32(pnv->initrd_base + pnv->initrd_size);
6469e933f4aSBenjamin Herrenschmidt 
6479e933f4aSBenjamin Herrenschmidt         _FDT((fdt_setprop(fdt, off, "linux,initrd-start",
6489e933f4aSBenjamin Herrenschmidt                                &start_prop, sizeof(start_prop))));
6499e933f4aSBenjamin Herrenschmidt         _FDT((fdt_setprop(fdt, off, "linux,initrd-end",
6509e933f4aSBenjamin Herrenschmidt                                &end_prop, sizeof(end_prop))));
6519e933f4aSBenjamin Herrenschmidt     }
6529e933f4aSBenjamin Herrenschmidt 
653e997040eSCédric Le Goater     /* Populate device tree for each chip */
654e997040eSCédric Le Goater     for (i = 0; i < pnv->num_chips; i++) {
655eb859a27SCédric Le Goater         PNV_CHIP_GET_CLASS(pnv->chips[i])->dt_populate(pnv->chips[i], fdt);
656e997040eSCédric Le Goater     }
657e7a3fee3SCédric Le Goater 
658e7a3fee3SCédric Le Goater     /* Populate ISA devices on chip 0 */
659bb7ab95cSCédric Le Goater     pnv_dt_isa(pnv, fdt);
660aeaef83dSCédric Le Goater 
661aeaef83dSCédric Le Goater     if (pnv->bmc) {
662b168a138SCédric Le Goater         pnv_dt_bmc_sensors(pnv->bmc, fdt);
663aeaef83dSCédric Le Goater     }
664aeaef83dSCédric Le Goater 
6657a90c6a1SGreg Kurz     /* Create an extra node for power management on machines that support it */
6667a90c6a1SGreg Kurz     if (pmc->dt_power_mgt) {
6677a90c6a1SGreg Kurz         pmc->dt_power_mgt(pnv, fdt);
668e5694793SCédric Le Goater     }
669e5694793SCédric Le Goater 
6709e933f4aSBenjamin Herrenschmidt     return fdt;
6719e933f4aSBenjamin Herrenschmidt }
6729e933f4aSBenjamin Herrenschmidt 
pnv_powerdown_notify(Notifier * n,void * opaque)673bce0b691SCédric Le Goater static void pnv_powerdown_notify(Notifier *n, void *opaque)
674bce0b691SCédric Le Goater {
6758f06e370SCédric Le Goater     PnvMachineState *pnv = container_of(n, PnvMachineState, powerdown_notifier);
676bce0b691SCédric Le Goater 
677bce0b691SCédric Le Goater     if (pnv->bmc) {
678bce0b691SCédric Le Goater         pnv_bmc_powerdown(pnv->bmc);
679bce0b691SCédric Le Goater     }
680bce0b691SCédric Le Goater }
681bce0b691SCédric Le Goater 
pnv_reset(MachineState * machine,ShutdownCause reason)6827966d70fSJason A. Donenfeld static void pnv_reset(MachineState *machine, ShutdownCause reason)
6839e933f4aSBenjamin Herrenschmidt {
68425f3170bSCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(machine);
68525f3170bSCédric Le Goater     IPMIBmc *bmc;
6869e933f4aSBenjamin Herrenschmidt     void *fdt;
6879e933f4aSBenjamin Herrenschmidt 
6887966d70fSJason A. Donenfeld     qemu_devices_reset(reason);
6899e933f4aSBenjamin Herrenschmidt 
69025f3170bSCédric Le Goater     /*
69125f3170bSCédric Le Goater      * The machine should provide by default an internal BMC simulator.
69225f3170bSCédric Le Goater      * If not, try to use the BMC device that was provided on the command
69325f3170bSCédric Le Goater      * line.
69425f3170bSCédric Le Goater      */
69525f3170bSCédric Le Goater     bmc = pnv_bmc_find(&error_fatal);
69625f3170bSCédric Le Goater     if (!pnv->bmc) {
69725f3170bSCédric Le Goater         if (!bmc) {
69838d2448aSGreg Kurz             if (!qtest_enabled()) {
69925f3170bSCédric Le Goater                 warn_report("machine has no BMC device. Use '-device "
70025f3170bSCédric Le Goater                             "ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10' "
70125f3170bSCédric Le Goater                             "to define one");
70238d2448aSGreg Kurz             }
70325f3170bSCédric Le Goater         } else {
70425f3170bSCédric Le Goater             pnv_bmc_set_pnor(bmc, pnv->pnor);
70525f3170bSCédric Le Goater             pnv->bmc = bmc;
70625f3170bSCédric Le Goater         }
70725f3170bSCédric Le Goater     }
70825f3170bSCédric Le Goater 
709b168a138SCédric Le Goater     fdt = pnv_dt_create(machine);
7109e933f4aSBenjamin Herrenschmidt 
7119e933f4aSBenjamin Herrenschmidt     /* Pack resulting tree */
7129e933f4aSBenjamin Herrenschmidt     _FDT((fdt_pack(fdt)));
7139e933f4aSBenjamin Herrenschmidt 
7148d409261SCédric Le Goater     qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
7159e933f4aSBenjamin Herrenschmidt     cpu_physical_memory_write(PNV_FDT_ADDR, fdt, fdt_totalsize(fdt));
716b2fb7a43SPan Nengyuan 
717adb77996SDaniel Henrique Barboza     /*
718adb77996SDaniel Henrique Barboza      * Set machine->fdt for 'dumpdtb' QMP/HMP command. Free
719adb77996SDaniel Henrique Barboza      * the existing machine->fdt to avoid leaking it during
720adb77996SDaniel Henrique Barboza      * a reset.
721adb77996SDaniel Henrique Barboza      */
722adb77996SDaniel Henrique Barboza     g_free(machine->fdt);
723adb77996SDaniel Henrique Barboza     machine->fdt = fdt;
7249e933f4aSBenjamin Herrenschmidt }
7259e933f4aSBenjamin Herrenschmidt 
pnv_chip_power8_isa_create(PnvChip * chip,Error ** errp)72604026890SCédric Le Goater static ISABus *pnv_chip_power8_isa_create(PnvChip *chip, Error **errp)
7273495b6b6SCédric Le Goater {
72877864267SCédric Le Goater     Pnv8Chip *chip8 = PNV8_CHIP(chip);
729c05aa140SCédric Le Goater     qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip8->psi), PSIHB_IRQ_EXTERNAL);
730c05aa140SCédric Le Goater 
731c05aa140SCédric Le Goater     qdev_connect_gpio_out(DEVICE(&chip8->lpc), 0, irq);
73277864267SCédric Le Goater     return pnv_lpc_isa_create(&chip8->lpc, true, errp);
73304026890SCédric Le Goater }
7343495b6b6SCédric Le Goater 
pnv_chip_power8nvl_isa_create(PnvChip * chip,Error ** errp)73504026890SCédric Le Goater static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp)
73604026890SCédric Le Goater {
73777864267SCédric Le Goater     Pnv8Chip *chip8 = PNV8_CHIP(chip);
738c05aa140SCédric Le Goater     qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip8->psi), PSIHB_IRQ_LPC_I2C);
739c05aa140SCédric Le Goater 
740c05aa140SCédric Le Goater     qdev_connect_gpio_out(DEVICE(&chip8->lpc), 0, irq);
74177864267SCédric Le Goater     return pnv_lpc_isa_create(&chip8->lpc, false, errp);
74204026890SCédric Le Goater }
7433495b6b6SCédric Le Goater 
pnv_chip_power9_isa_create(PnvChip * chip,Error ** errp)74404026890SCédric Le Goater static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
74504026890SCédric Le Goater {
74615376c66SCédric Le Goater     Pnv9Chip *chip9 = PNV9_CHIP(chip);
747c05aa140SCédric Le Goater     qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip9->psi), PSIHB9_IRQ_LPCHC);
748c05aa140SCédric Le Goater 
749c05aa140SCédric Le Goater     qdev_connect_gpio_out(DEVICE(&chip9->lpc), 0, irq);
75015376c66SCédric Le Goater     return pnv_lpc_isa_create(&chip9->lpc, false, errp);
75104026890SCédric Le Goater }
7523495b6b6SCédric Le Goater 
pnv_chip_power10_isa_create(PnvChip * chip,Error ** errp)7532b548a42SCédric Le Goater static ISABus *pnv_chip_power10_isa_create(PnvChip *chip, Error **errp)
7542b548a42SCédric Le Goater {
7552661f6abSCédric Le Goater     Pnv10Chip *chip10 = PNV10_CHIP(chip);
756c05aa140SCédric Le Goater     qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip10->psi), PSIHB9_IRQ_LPCHC);
757c05aa140SCédric Le Goater 
758c05aa140SCédric Le Goater     qdev_connect_gpio_out(DEVICE(&chip10->lpc), 0, irq);
7592661f6abSCédric Le Goater     return pnv_lpc_isa_create(&chip10->lpc, false, errp);
7602b548a42SCédric Le Goater }
7612b548a42SCédric Le Goater 
pnv_isa_create(PnvChip * chip,Error ** errp)76204026890SCédric Le Goater static ISABus *pnv_isa_create(PnvChip *chip, Error **errp)
76304026890SCédric Le Goater {
76404026890SCédric Le Goater     return PNV_CHIP_GET_CLASS(chip)->isa_create(chip, errp);
7653495b6b6SCédric Le Goater }
7663495b6b6SCédric Le Goater 
pnv_chip_power8_pic_print_info(PnvChip * chip,Monitor * mon)767d8e4aad5SCédric Le Goater static void pnv_chip_power8_pic_print_info(PnvChip *chip, Monitor *mon)
768d8e4aad5SCédric Le Goater {
769d8e4aad5SCédric Le Goater     Pnv8Chip *chip8 = PNV8_CHIP(chip);
7708a69bca7SDaniel Henrique Barboza     int i;
771d8e4aad5SCédric Le Goater 
772d8e4aad5SCédric Le Goater     ics_pic_print_info(&chip8->psi.ics, mon);
7738a69bca7SDaniel Henrique Barboza 
7748a69bca7SDaniel Henrique Barboza     for (i = 0; i < chip8->num_phbs; i++) {
7750d512c71SDaniel Henrique Barboza         PnvPHB *phb = chip8->phbs[i];
7761f5d6b2aSDaniel Henrique Barboza         PnvPHB3 *phb3 = PNV_PHB3(phb->backend);
7778a69bca7SDaniel Henrique Barboza 
7788a69bca7SDaniel Henrique Barboza         pnv_phb3_msi_pic_print_info(&phb3->msis, mon);
7798a69bca7SDaniel Henrique Barboza         ics_pic_print_info(&phb3->lsis, mon);
7808a69bca7SDaniel Henrique Barboza     }
781d8e4aad5SCédric Le Goater }
782d8e4aad5SCédric Le Goater 
pnv_chip_power9_pic_print_info_child(Object * child,void * opaque)7830e6232bcSCédric Le Goater static int pnv_chip_power9_pic_print_info_child(Object *child, void *opaque)
7840e6232bcSCédric Le Goater {
7850e6232bcSCédric Le Goater     Monitor *mon = opaque;
786210aacb3SDaniel Henrique Barboza     PnvPHB *phb =  (PnvPHB *) object_dynamic_cast(child, TYPE_PNV_PHB);
7870e6232bcSCédric Le Goater 
788210aacb3SDaniel Henrique Barboza     if (!phb) {
789210aacb3SDaniel Henrique Barboza         return 0;
7900e6232bcSCédric Le Goater     }
791210aacb3SDaniel Henrique Barboza 
792210aacb3SDaniel Henrique Barboza     pnv_phb4_pic_print_info(PNV_PHB4(phb->backend), mon);
793210aacb3SDaniel Henrique Barboza 
7940e6232bcSCédric Le Goater     return 0;
7950e6232bcSCédric Le Goater }
7960e6232bcSCédric Le Goater 
pnv_chip_power9_pic_print_info(PnvChip * chip,Monitor * mon)797d8e4aad5SCédric Le Goater static void pnv_chip_power9_pic_print_info(PnvChip *chip, Monitor *mon)
798d8e4aad5SCédric Le Goater {
799d8e4aad5SCédric Le Goater     Pnv9Chip *chip9 = PNV9_CHIP(chip);
800d8e4aad5SCédric Le Goater 
801d8e4aad5SCédric Le Goater     pnv_xive_pic_print_info(&chip9->xive, mon);
802c38536bcSCédric Le Goater     pnv_psi_pic_print_info(&chip9->psi, mon);
8034f9924c4SBenjamin Herrenschmidt 
8040e6232bcSCédric Le Goater     object_child_foreach_recursive(OBJECT(chip),
8050e6232bcSCédric Le Goater                          pnv_chip_power9_pic_print_info_child, mon);
806d8e4aad5SCédric Le Goater }
807d8e4aad5SCédric Le Goater 
pnv_chip_power8_xscom_core_base(PnvChip * chip,uint32_t core_id)808c4b2c40cSGreg Kurz static uint64_t pnv_chip_power8_xscom_core_base(PnvChip *chip,
809c4b2c40cSGreg Kurz                                                 uint32_t core_id)
810c4b2c40cSGreg Kurz {
811c4b2c40cSGreg Kurz     return PNV_XSCOM_EX_BASE(core_id);
812c4b2c40cSGreg Kurz }
813c4b2c40cSGreg Kurz 
pnv_chip_power9_xscom_core_base(PnvChip * chip,uint32_t core_id)814c4b2c40cSGreg Kurz static uint64_t pnv_chip_power9_xscom_core_base(PnvChip *chip,
815c4b2c40cSGreg Kurz                                                 uint32_t core_id)
816c4b2c40cSGreg Kurz {
817c4b2c40cSGreg Kurz     return PNV9_XSCOM_EC_BASE(core_id);
818c4b2c40cSGreg Kurz }
819c4b2c40cSGreg Kurz 
pnv_chip_power10_xscom_core_base(PnvChip * chip,uint32_t core_id)820c4b2c40cSGreg Kurz static uint64_t pnv_chip_power10_xscom_core_base(PnvChip *chip,
821c4b2c40cSGreg Kurz                                                  uint32_t core_id)
822c4b2c40cSGreg Kurz {
823c4b2c40cSGreg Kurz     return PNV10_XSCOM_EC_BASE(core_id);
824c4b2c40cSGreg Kurz }
825c4b2c40cSGreg Kurz 
pnv_match_cpu(const char * default_type,const char * cpu_type)826f30c843cSCédric Le Goater static bool pnv_match_cpu(const char *default_type, const char *cpu_type)
827f30c843cSCédric Le Goater {
828f30c843cSCédric Le Goater     PowerPCCPUClass *ppc_default =
829f30c843cSCédric Le Goater         POWERPC_CPU_CLASS(object_class_by_name(default_type));
830f30c843cSCédric Le Goater     PowerPCCPUClass *ppc =
831f30c843cSCédric Le Goater         POWERPC_CPU_CLASS(object_class_by_name(cpu_type));
832f30c843cSCédric Le Goater 
83321d3a78eSNicholas Piggin     return ppc_default->pvr_match(ppc_default, ppc->pvr, false);
834f30c843cSCédric Le Goater }
835f30c843cSCédric Le Goater 
pnv_ipmi_bt_init(ISABus * bus,IPMIBmc * bmc,uint32_t irq)836e2392d43SCédric Le Goater static void pnv_ipmi_bt_init(ISABus *bus, IPMIBmc *bmc, uint32_t irq)
837e2392d43SCédric Le Goater {
838c23e0561SMarkus Armbruster     ISADevice *dev = isa_new("isa-ipmi-bt");
839e2392d43SCédric Le Goater 
8405325cc34SMarkus Armbruster     object_property_set_link(OBJECT(dev), "bmc", OBJECT(bmc), &error_fatal);
8415325cc34SMarkus Armbruster     object_property_set_int(OBJECT(dev), "irq", irq, &error_fatal);
842c23e0561SMarkus Armbruster     isa_realize_and_unref(dev, bus, &error_fatal);
843e2392d43SCédric Le Goater }
844e2392d43SCédric Le Goater 
pnv_chip_power10_pic_print_info(PnvChip * chip,Monitor * mon)8452b548a42SCédric Le Goater static void pnv_chip_power10_pic_print_info(PnvChip *chip, Monitor *mon)
8462b548a42SCédric Le Goater {
8478b50ce85SCédric Le Goater     Pnv10Chip *chip10 = PNV10_CHIP(chip);
8488b50ce85SCédric Le Goater 
849da71b7e3SCédric Le Goater     pnv_xive2_pic_print_info(&chip10->xive, mon);
8508b50ce85SCédric Le Goater     pnv_psi_pic_print_info(&chip10->psi, mon);
851623575e1SCédric Le Goater 
852623575e1SCédric Le Goater     object_child_foreach_recursive(OBJECT(chip),
853623575e1SCédric Le Goater                          pnv_chip_power9_pic_print_info_child, mon);
8542b548a42SCédric Le Goater }
8552b548a42SCédric Le Goater 
856458c6f01SCédric Le Goater /* Always give the first 1GB to chip 0 else we won't boot */
pnv_chip_get_ram_size(PnvMachineState * pnv,int chip_id)857458c6f01SCédric Le Goater static uint64_t pnv_chip_get_ram_size(PnvMachineState *pnv, int chip_id)
858458c6f01SCédric Le Goater {
859458c6f01SCédric Le Goater     MachineState *machine = MACHINE(pnv);
860458c6f01SCédric Le Goater     uint64_t ram_per_chip;
861458c6f01SCédric Le Goater 
862458c6f01SCédric Le Goater     assert(machine->ram_size >= 1 * GiB);
863458c6f01SCédric Le Goater 
864458c6f01SCédric Le Goater     ram_per_chip = machine->ram_size / pnv->num_chips;
865458c6f01SCédric Le Goater     if (ram_per_chip >= 1 * GiB) {
866458c6f01SCédric Le Goater         return QEMU_ALIGN_DOWN(ram_per_chip, 1 * MiB);
867458c6f01SCédric Le Goater     }
868458c6f01SCédric Le Goater 
869f640afecSCédric Le Goater     assert(pnv->num_chips > 1);
870f640afecSCédric Le Goater 
871458c6f01SCédric Le Goater     ram_per_chip = (machine->ram_size - 1 * GiB) / (pnv->num_chips - 1);
872458c6f01SCédric Le Goater     return chip_id == 0 ? 1 * GiB : QEMU_ALIGN_DOWN(ram_per_chip, 1 * MiB);
873458c6f01SCédric Le Goater }
874458c6f01SCédric Le Goater 
pnv_init(MachineState * machine)875b168a138SCédric Le Goater static void pnv_init(MachineState *machine)
8769e933f4aSBenjamin Herrenschmidt {
877cd7b9498SPaolo Bonzini     const char *bios_name = machine->firmware ?: FW_FILE_NAME;
878b168a138SCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(machine);
879f30c843cSCédric Le Goater     MachineClass *mc = MACHINE_GET_CLASS(machine);
88033467ecbSGlenn Miles     PnvMachineClass *pmc = PNV_MACHINE_GET_CLASS(machine);
8819e933f4aSBenjamin Herrenschmidt     char *fw_filename;
8829e933f4aSBenjamin Herrenschmidt     long fw_size;
883458c6f01SCédric Le Goater     uint64_t chip_ram_start = 0;
884e997040eSCédric Le Goater     int i;
885e997040eSCédric Le Goater     char *chip_typename;
88635dde576SCédric Le Goater     DriveInfo *pnor = drive_get(IF_MTD, 0, 0);
88735dde576SCédric Le Goater     DeviceState *dev;
8889e933f4aSBenjamin Herrenschmidt 
889ebe6c3faSDaniel Henrique Barboza     if (kvm_enabled()) {
890518f72ecSCédric Le Goater         error_report("machine %s does not support the KVM accelerator",
891518f72ecSCédric Le Goater                      mc->name);
892ebe6c3faSDaniel Henrique Barboza         exit(EXIT_FAILURE);
893ebe6c3faSDaniel Henrique Barboza     }
894ebe6c3faSDaniel Henrique Barboza 
8959e933f4aSBenjamin Herrenschmidt     /* allocate RAM */
896dd7ef911SCédric Le Goater     if (machine->ram_size < mc->default_ram_size) {
897dd7ef911SCédric Le Goater         char *sz = size_to_str(mc->default_ram_size);
898dd7ef911SCédric Le Goater         error_report("Invalid RAM size, should be bigger than %s", sz);
899dd7ef911SCédric Le Goater         g_free(sz);
900dd7ef911SCédric Le Goater         exit(EXIT_FAILURE);
9019e933f4aSBenjamin Herrenschmidt     }
902173a36d8SIgor Mammedov     memory_region_add_subregion(get_system_memory(), 0, machine->ram);
9039e933f4aSBenjamin Herrenschmidt 
90435dde576SCédric Le Goater     /*
90535dde576SCédric Le Goater      * Create our simple PNOR device
90635dde576SCédric Le Goater      */
9073e80f690SMarkus Armbruster     dev = qdev_new(TYPE_PNV_PNOR);
90835dde576SCédric Le Goater     if (pnor) {
909934df912SMarkus Armbruster         qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(pnor));
91035dde576SCédric Le Goater     }
9113c6ef471SMarkus Armbruster     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
91235dde576SCédric Le Goater     pnv->pnor = PNV_PNOR(dev);
91335dde576SCédric Le Goater 
9149e933f4aSBenjamin Herrenschmidt     /* load skiboot firmware  */
9159e933f4aSBenjamin Herrenschmidt     fw_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
91615fcedb2SCédric Le Goater     if (!fw_filename) {
91715fcedb2SCédric Le Goater         error_report("Could not find OPAL firmware '%s'", bios_name);
91815fcedb2SCédric Le Goater         exit(1);
91915fcedb2SCédric Le Goater     }
9209e933f4aSBenjamin Herrenschmidt 
92108c3f3a7SCédric Le Goater     fw_size = load_image_targphys(fw_filename, pnv->fw_load_addr, FW_MAX_SIZE);
9229e933f4aSBenjamin Herrenschmidt     if (fw_size < 0) {
92315fcedb2SCédric Le Goater         error_report("Could not load OPAL firmware '%s'", fw_filename);
9249e933f4aSBenjamin Herrenschmidt         exit(1);
9259e933f4aSBenjamin Herrenschmidt     }
9269e933f4aSBenjamin Herrenschmidt     g_free(fw_filename);
9279e933f4aSBenjamin Herrenschmidt 
9289e933f4aSBenjamin Herrenschmidt     /* load kernel */
9299e933f4aSBenjamin Herrenschmidt     if (machine->kernel_filename) {
9309e933f4aSBenjamin Herrenschmidt         long kernel_size;
9319e933f4aSBenjamin Herrenschmidt 
9329e933f4aSBenjamin Herrenschmidt         kernel_size = load_image_targphys(machine->kernel_filename,
933b45b56baSMurilo Opsfelder Araujo                                           KERNEL_LOAD_ADDR, KERNEL_MAX_SIZE);
9349e933f4aSBenjamin Herrenschmidt         if (kernel_size < 0) {
935802fc7abSThomas Huth             error_report("Could not load kernel '%s'",
9369e933f4aSBenjamin Herrenschmidt                          machine->kernel_filename);
9379e933f4aSBenjamin Herrenschmidt             exit(1);
9389e933f4aSBenjamin Herrenschmidt         }
9399e933f4aSBenjamin Herrenschmidt     }
9409e933f4aSBenjamin Herrenschmidt 
9419e933f4aSBenjamin Herrenschmidt     /* load initrd */
9429e933f4aSBenjamin Herrenschmidt     if (machine->initrd_filename) {
9439e933f4aSBenjamin Herrenschmidt         pnv->initrd_base = INITRD_LOAD_ADDR;
9449e933f4aSBenjamin Herrenschmidt         pnv->initrd_size = load_image_targphys(machine->initrd_filename,
945584ea7e7SMurilo Opsfelder Araujo                                   pnv->initrd_base, INITRD_MAX_SIZE);
9469e933f4aSBenjamin Herrenschmidt         if (pnv->initrd_size < 0) {
947802fc7abSThomas Huth             error_report("Could not load initial ram disk '%s'",
9489e933f4aSBenjamin Herrenschmidt                          machine->initrd_filename);
9499e933f4aSBenjamin Herrenschmidt             exit(1);
9509e933f4aSBenjamin Herrenschmidt         }
9519e933f4aSBenjamin Herrenschmidt     }
952e997040eSCédric Le Goater 
9534f9924c4SBenjamin Herrenschmidt     /* MSIs are supported on this platform */
9544f9924c4SBenjamin Herrenschmidt     msi_nonbroken = true;
9554f9924c4SBenjamin Herrenschmidt 
956f30c843cSCédric Le Goater     /*
957f30c843cSCédric Le Goater      * Check compatibility of the specified CPU with the machine
958f30c843cSCédric Le Goater      * default.
959f30c843cSCédric Le Goater      */
960f30c843cSCédric Le Goater     if (!pnv_match_cpu(mc->default_cpu_type, machine->cpu_type)) {
961f30c843cSCédric Le Goater         error_report("invalid CPU model '%s' for %s machine",
962f30c843cSCédric Le Goater                      machine->cpu_type, mc->name);
963f30c843cSCédric Le Goater         exit(1);
964f30c843cSCédric Le Goater     }
965f30c843cSCédric Le Goater 
966e997040eSCédric Le Goater     /* Create the processor chips */
9674a12c699SIgor Mammedov     i = strlen(machine->cpu_type) - strlen(POWERPC_CPU_TYPE_SUFFIX);
9687fd544d8SIgor Mammedov     chip_typename = g_strdup_printf(PNV_CHIP_TYPE_NAME("%.*s"),
9694a12c699SIgor Mammedov                                     i, machine->cpu_type);
970e997040eSCédric Le Goater     if (!object_class_by_name(chip_typename)) {
971f30c843cSCédric Le Goater         error_report("invalid chip model '%.*s' for %s machine",
972f30c843cSCédric Le Goater                      i, machine->cpu_type, mc->name);
973e997040eSCédric Le Goater         exit(1);
974e997040eSCédric Le Goater     }
975e997040eSCédric Le Goater 
976e44acde2SGreg Kurz     pnv->num_chips =
977e44acde2SGreg Kurz         machine->smp.max_cpus / (machine->smp.cores * machine->smp.threads);
978934676c7SNicholas Piggin 
979934676c7SNicholas Piggin     if (machine->smp.threads > 8) {
980934676c7SNicholas Piggin         error_report("Cannot support more than 8 threads/core "
981934676c7SNicholas Piggin                      "on a powernv machine");
982934676c7SNicholas Piggin         exit(1);
983934676c7SNicholas Piggin     }
984934676c7SNicholas Piggin     if (!is_power_of_2(machine->smp.threads)) {
985934676c7SNicholas Piggin         error_report("Cannot support %d threads/core on a powernv"
986934676c7SNicholas Piggin                      "machine because it must be a power of 2",
987934676c7SNicholas Piggin                      machine->smp.threads);
988934676c7SNicholas Piggin         exit(1);
989934676c7SNicholas Piggin     }
990e44acde2SGreg Kurz     /*
991e44acde2SGreg Kurz      * TODO: should we decide on how many chips we can create based
992e44acde2SGreg Kurz      * on #cores and Venice vs. Murano vs. Naples chip type etc...,
993e44acde2SGreg Kurz      */
994ab17a3feSCédric Le Goater     if (!is_power_of_2(pnv->num_chips) || pnv->num_chips > 16) {
995e44acde2SGreg Kurz         error_report("invalid number of chips: '%d'", pnv->num_chips);
996ab17a3feSCédric Le Goater         error_printf(
997ab17a3feSCédric Le Goater             "Try '-smp sockets=N'. Valid values are : 1, 2, 4, 8 and 16.\n");
998e44acde2SGreg Kurz         exit(1);
999e44acde2SGreg Kurz     }
1000e44acde2SGreg Kurz 
1001e997040eSCédric Le Goater     pnv->chips = g_new0(PnvChip *, pnv->num_chips);
1002e997040eSCédric Le Goater     for (i = 0; i < pnv->num_chips; i++) {
1003e997040eSCédric Le Goater         char chip_name[32];
1004df707969SMarkus Armbruster         Object *chip = OBJECT(qdev_new(chip_typename));
10050e5e9ff4SCédric Le Goater         uint64_t chip_ram_size =  pnv_chip_get_ram_size(pnv, i);
1006e997040eSCédric Le Goater 
1007e997040eSCédric Le Goater         pnv->chips[i] = PNV_CHIP(chip);
1008e997040eSCédric Le Goater 
1009458c6f01SCédric Le Goater         /* Distribute RAM among the chips  */
1010458c6f01SCédric Le Goater         object_property_set_int(chip, "ram-start", chip_ram_start,
1011e997040eSCédric Le Goater                                 &error_fatal);
1012458c6f01SCédric Le Goater         object_property_set_int(chip, "ram-size", chip_ram_size,
1013458c6f01SCédric Le Goater                                 &error_fatal);
1014458c6f01SCédric Le Goater         chip_ram_start += chip_ram_size;
1015e997040eSCédric Le Goater 
10160e5e9ff4SCédric Le Goater         snprintf(chip_name, sizeof(chip_name), "chip[%d]", i);
1017d2623129SMarkus Armbruster         object_property_add_child(OBJECT(pnv), chip_name, chip);
10180e5e9ff4SCédric Le Goater         object_property_set_int(chip, "chip-id", i, &error_fatal);
10195325cc34SMarkus Armbruster         object_property_set_int(chip, "nr-cores", machine->smp.cores,
10205325cc34SMarkus Armbruster                                 &error_fatal);
10215325cc34SMarkus Armbruster         object_property_set_int(chip, "nr-threads", machine->smp.threads,
10225325cc34SMarkus Armbruster                                 &error_fatal);
1023245cdb7fSCédric Le Goater         /*
1024245cdb7fSCédric Le Goater          * The POWER8 machine use the XICS interrupt interface.
1025245cdb7fSCédric Le Goater          * Propagate the XICS fabric to the chip and its controllers.
1026245cdb7fSCédric Le Goater          */
1027245cdb7fSCédric Le Goater         if (object_dynamic_cast(OBJECT(pnv), TYPE_XICS_FABRIC)) {
10285325cc34SMarkus Armbruster             object_property_set_link(chip, "xics", OBJECT(pnv), &error_abort);
1029245cdb7fSCédric Le Goater         }
1030d1214b81SGreg Kurz         if (object_dynamic_cast(OBJECT(pnv), TYPE_XIVE_FABRIC)) {
10315325cc34SMarkus Armbruster             object_property_set_link(chip, "xive-fabric", OBJECT(pnv),
1032d1214b81SGreg Kurz                                      &error_abort);
1033d1214b81SGreg Kurz         }
10343c6ef471SMarkus Armbruster         sysbus_realize_and_unref(SYS_BUS_DEVICE(chip), &error_fatal);
1035e997040eSCédric Le Goater     }
1036e997040eSCédric Le Goater     g_free(chip_typename);
10373495b6b6SCédric Le Goater 
10383495b6b6SCédric Le Goater     /* Instantiate ISA bus on chip 0 */
103904026890SCédric Le Goater     pnv->isa_bus = pnv_isa_create(pnv->chips[0], &error_fatal);
10403495b6b6SCédric Le Goater 
10413495b6b6SCédric Le Goater     /* Create serial port */
1042def337ffSPeter Maydell     serial_hds_isa_init(pnv->isa_bus, 0, MAX_ISA_SERIAL_PORTS);
10433495b6b6SCédric Le Goater 
10443495b6b6SCédric Le Goater     /* Create an RTC ISA device too */
10456c646a11SPhilippe Mathieu-Daudé     mc146818_rtc_init(pnv->isa_bus, 2000, NULL);
1046bce0b691SCédric Le Goater 
104725f3170bSCédric Le Goater     /*
104825f3170bSCédric Le Goater      * Create the machine BMC simulator and the IPMI BT device for
104925f3170bSCédric Le Goater      * communication with the BMC
105025f3170bSCédric Le Goater      */
105125f3170bSCédric Le Goater     if (defaults_enabled()) {
105225f3170bSCédric Le Goater         pnv->bmc = pnv_bmc_create(pnv->pnor);
1053e2392d43SCédric Le Goater         pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
105425f3170bSCédric Le Goater     }
1055e2392d43SCédric Le Goater 
105659b7c1c2SBalamuruhan S     /*
1057032c226bSCédric Le Goater      * The PNOR is mapped on the LPC FW address space by the BMC.
1058032c226bSCédric Le Goater      * Since we can not reach the remote BMC machine with LPC memops,
1059032c226bSCédric Le Goater      * map it always for now.
1060032c226bSCédric Le Goater      */
1061032c226bSCédric Le Goater     memory_region_add_subregion(pnv->chips[0]->fw_mr, PNOR_SPI_OFFSET,
1062032c226bSCédric Le Goater                                 &pnv->pnor->mmio);
1063032c226bSCédric Le Goater 
1064032c226bSCédric Le Goater     /*
106559b7c1c2SBalamuruhan S      * OpenPOWER systems use a IPMI SEL Event message to notify the
106659b7c1c2SBalamuruhan S      * host to powerdown
106759b7c1c2SBalamuruhan S      */
1068bce0b691SCédric Le Goater     pnv->powerdown_notifier.notify = pnv_powerdown_notify;
1069bce0b691SCédric Le Goater     qemu_register_powerdown_notifier(&pnv->powerdown_notifier);
107033467ecbSGlenn Miles 
107133467ecbSGlenn Miles     /*
107233467ecbSGlenn Miles      * Create/Connect any machine-specific I2C devices
107333467ecbSGlenn Miles      */
107433467ecbSGlenn Miles     if (pmc->i2c_init) {
107533467ecbSGlenn Miles         pmc->i2c_init(pnv);
107633467ecbSGlenn Miles     }
1077e997040eSCédric Le Goater }
1078e997040eSCédric Le Goater 
1079631adaffSCédric Le Goater /*
1080631adaffSCédric Le Goater  *    0:21  Reserved - Read as zeros
1081631adaffSCédric Le Goater  *   22:24  Chip ID
1082631adaffSCédric Le Goater  *   25:28  Core number
1083631adaffSCédric Le Goater  *   29:31  Thread ID
1084631adaffSCédric Le Goater  */
pnv_chip_pir_p8(PnvChip * chip,uint32_t core_id,uint32_t thread_id)10859940412aSCaleb Schlossin static uint32_t pnv_chip_pir_p8(PnvChip *chip, uint32_t core_id,
10869940412aSCaleb Schlossin                                 uint32_t thread_id)
1087631adaffSCédric Le Goater {
10889940412aSCaleb Schlossin     return (chip->chip_id << 7) | (core_id << 3) | thread_id;
1089631adaffSCédric Le Goater }
1090631adaffSCédric Le Goater 
pnv_chip_power8_intc_create(PnvChip * chip,PowerPCCPU * cpu,Error ** errp)10918fa1f4efSCédric Le Goater static void pnv_chip_power8_intc_create(PnvChip *chip, PowerPCCPU *cpu,
1092d35aefa9SCédric Le Goater                                         Error **errp)
1093d35aefa9SCédric Le Goater {
1094245cdb7fSCédric Le Goater     Pnv8Chip *chip8 = PNV8_CHIP(chip);
10958fa1f4efSCédric Le Goater     Error *local_err = NULL;
10968fa1f4efSCédric Le Goater     Object *obj;
10978907fc25SCédric Le Goater     PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
10988fa1f4efSCédric Le Goater 
1099245cdb7fSCédric Le Goater     obj = icp_create(OBJECT(cpu), TYPE_PNV_ICP, chip8->xics, &local_err);
11008fa1f4efSCédric Le Goater     if (local_err) {
11018fa1f4efSCédric Le Goater         error_propagate(errp, local_err);
11028fa1f4efSCédric Le Goater         return;
11038fa1f4efSCédric Le Goater     }
11048fa1f4efSCédric Le Goater 
1105956b8f46SCédric Le Goater     pnv_cpu->intc = obj;
1106d35aefa9SCédric Le Goater }
1107d35aefa9SCédric Le Goater 
11080990ce6aSGreg Kurz 
pnv_chip_power8_intc_reset(PnvChip * chip,PowerPCCPU * cpu)1109d49e8a9bSCédric Le Goater static void pnv_chip_power8_intc_reset(PnvChip *chip, PowerPCCPU *cpu)
1110d49e8a9bSCédric Le Goater {
1111d49e8a9bSCédric Le Goater     PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
1112d49e8a9bSCédric Le Goater 
1113d49e8a9bSCédric Le Goater     icp_reset(ICP(pnv_cpu->intc));
1114d49e8a9bSCédric Le Goater }
1115d49e8a9bSCédric Le Goater 
pnv_chip_power8_intc_destroy(PnvChip * chip,PowerPCCPU * cpu)11160990ce6aSGreg Kurz static void pnv_chip_power8_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
11170990ce6aSGreg Kurz {
11180990ce6aSGreg Kurz     PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
11190990ce6aSGreg Kurz 
11200990ce6aSGreg Kurz     icp_destroy(ICP(pnv_cpu->intc));
11210990ce6aSGreg Kurz     pnv_cpu->intc = NULL;
11220990ce6aSGreg Kurz }
11230990ce6aSGreg Kurz 
pnv_chip_power8_intc_print_info(PnvChip * chip,PowerPCCPU * cpu,Monitor * mon)112485913070SGreg Kurz static void pnv_chip_power8_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
112585913070SGreg Kurz                                             Monitor *mon)
112685913070SGreg Kurz {
112785913070SGreg Kurz     icp_pic_print_info(ICP(pnv_cpu_state(cpu)->intc), mon);
112885913070SGreg Kurz }
112985913070SGreg Kurz 
1130631adaffSCédric Le Goater /*
1131631adaffSCédric Le Goater  *    0:48  Reserved - Read as zeroes
1132631adaffSCédric Le Goater  *   49:52  Node ID
1133631adaffSCédric Le Goater  *   53:55  Chip ID
1134631adaffSCédric Le Goater  *   56     Reserved - Read as zero
1135631adaffSCédric Le Goater  *   57:61  Core number
1136631adaffSCédric Le Goater  *   62:63  Thread ID
1137631adaffSCédric Le Goater  *
1138631adaffSCédric Le Goater  * We only care about the lower bits. uint32_t is fine for the moment.
1139631adaffSCédric Le Goater  */
pnv_chip_pir_p9(PnvChip * chip,uint32_t core_id,uint32_t thread_id)11409940412aSCaleb Schlossin static uint32_t pnv_chip_pir_p9(PnvChip *chip, uint32_t core_id,
11419940412aSCaleb Schlossin                                 uint32_t thread_id)
1142631adaffSCédric Le Goater {
11439940412aSCaleb Schlossin     if (chip->nr_threads == 8) {
11449940412aSCaleb Schlossin         return (chip->chip_id << 8) | ((thread_id & 1) << 2) | (core_id << 3) |
11459940412aSCaleb Schlossin                (thread_id >> 1);
11469940412aSCaleb Schlossin     } else {
11479940412aSCaleb Schlossin         return (chip->chip_id << 8) | (core_id << 2) | thread_id;
11489940412aSCaleb Schlossin     }
1149631adaffSCédric Le Goater }
1150631adaffSCédric Le Goater 
11519940412aSCaleb Schlossin /*
11529940412aSCaleb Schlossin  *    0:48  Reserved - Read as zeroes
11539940412aSCaleb Schlossin  *   49:52  Node ID
11549940412aSCaleb Schlossin  *   53:55  Chip ID
11559940412aSCaleb Schlossin  *   56     Reserved - Read as zero
11569940412aSCaleb Schlossin  *   57:59  Quad ID
11579940412aSCaleb Schlossin  *   60     Core Chiplet Pair ID
11589940412aSCaleb Schlossin  *   61:63  Thread/Core Chiplet ID t0-t2
11599940412aSCaleb Schlossin  *
11609940412aSCaleb Schlossin  * We only care about the lower bits. uint32_t is fine for the moment.
11619940412aSCaleb Schlossin  */
pnv_chip_pir_p10(PnvChip * chip,uint32_t core_id,uint32_t thread_id)11629940412aSCaleb Schlossin static uint32_t pnv_chip_pir_p10(PnvChip *chip, uint32_t core_id,
11639940412aSCaleb Schlossin                                  uint32_t thread_id)
11642b548a42SCédric Le Goater {
11659940412aSCaleb Schlossin     if (chip->nr_threads == 8) {
11669940412aSCaleb Schlossin         return (chip->chip_id << 8) | ((core_id / 4) << 4) |
11679940412aSCaleb Schlossin                ((core_id % 2) << 3) | thread_id;
11689940412aSCaleb Schlossin     } else {
11699940412aSCaleb Schlossin         return (chip->chip_id << 8) | (core_id << 2) | thread_id;
11709940412aSCaleb Schlossin     }
11712b548a42SCédric Le Goater }
11722b548a42SCédric Le Goater 
pnv_chip_power9_intc_create(PnvChip * chip,PowerPCCPU * cpu,Error ** errp)11738fa1f4efSCédric Le Goater static void pnv_chip_power9_intc_create(PnvChip *chip, PowerPCCPU *cpu,
1174d35aefa9SCédric Le Goater                                         Error **errp)
1175d35aefa9SCédric Le Goater {
11762dfa91a2SCédric Le Goater     Pnv9Chip *chip9 = PNV9_CHIP(chip);
11772dfa91a2SCédric Le Goater     Error *local_err = NULL;
11782dfa91a2SCédric Le Goater     Object *obj;
11792dfa91a2SCédric Le Goater     PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
11802dfa91a2SCédric Le Goater 
11812dfa91a2SCédric Le Goater     /*
11822dfa91a2SCédric Le Goater      * The core creates its interrupt presenter but the XIVE interrupt
11832dfa91a2SCédric Le Goater      * controller object is initialized afterwards. Hopefully, it's
11842dfa91a2SCédric Le Goater      * only used at runtime.
11852dfa91a2SCédric Le Goater      */
118647950946SCédric Le Goater     obj = xive_tctx_create(OBJECT(cpu), XIVE_PRESENTER(&chip9->xive),
118747950946SCédric Le Goater                            &local_err);
11882dfa91a2SCédric Le Goater     if (local_err) {
11892dfa91a2SCédric Le Goater         error_propagate(errp, local_err);
11908fa1f4efSCédric Le Goater         return;
1191d35aefa9SCédric Le Goater     }
1192d35aefa9SCédric Le Goater 
11932dfa91a2SCédric Le Goater     pnv_cpu->intc = obj;
11942dfa91a2SCédric Le Goater }
11952dfa91a2SCédric Le Goater 
pnv_chip_power9_intc_reset(PnvChip * chip,PowerPCCPU * cpu)1196d49e8a9bSCédric Le Goater static void pnv_chip_power9_intc_reset(PnvChip *chip, PowerPCCPU *cpu)
1197d49e8a9bSCédric Le Goater {
1198d49e8a9bSCédric Le Goater     PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
1199d49e8a9bSCédric Le Goater 
1200d49e8a9bSCédric Le Goater     xive_tctx_reset(XIVE_TCTX(pnv_cpu->intc));
1201d49e8a9bSCédric Le Goater }
1202d49e8a9bSCédric Le Goater 
pnv_chip_power9_intc_destroy(PnvChip * chip,PowerPCCPU * cpu)12030990ce6aSGreg Kurz static void pnv_chip_power9_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
12040990ce6aSGreg Kurz {
12050990ce6aSGreg Kurz     PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
12060990ce6aSGreg Kurz 
12070990ce6aSGreg Kurz     xive_tctx_destroy(XIVE_TCTX(pnv_cpu->intc));
12080990ce6aSGreg Kurz     pnv_cpu->intc = NULL;
12090990ce6aSGreg Kurz }
12100990ce6aSGreg Kurz 
pnv_chip_power9_intc_print_info(PnvChip * chip,PowerPCCPU * cpu,Monitor * mon)121185913070SGreg Kurz static void pnv_chip_power9_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
121285913070SGreg Kurz                                             Monitor *mon)
121385913070SGreg Kurz {
121485913070SGreg Kurz     xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), mon);
121585913070SGreg Kurz }
121685913070SGreg Kurz 
pnv_chip_power10_intc_create(PnvChip * chip,PowerPCCPU * cpu,Error ** errp)12172b548a42SCédric Le Goater static void pnv_chip_power10_intc_create(PnvChip *chip, PowerPCCPU *cpu,
12182b548a42SCédric Le Goater                                         Error **errp)
12192b548a42SCédric Le Goater {
1220da71b7e3SCédric Le Goater     Pnv10Chip *chip10 = PNV10_CHIP(chip);
1221da71b7e3SCédric Le Goater     Error *local_err = NULL;
1222da71b7e3SCédric Le Goater     Object *obj;
12232b548a42SCédric Le Goater     PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
12242b548a42SCédric Le Goater 
1225da71b7e3SCédric Le Goater     /*
1226da71b7e3SCédric Le Goater      * The core creates its interrupt presenter but the XIVE2 interrupt
1227da71b7e3SCédric Le Goater      * controller object is initialized afterwards. Hopefully, it's
1228da71b7e3SCédric Le Goater      * only used at runtime.
1229da71b7e3SCédric Le Goater      */
1230da71b7e3SCédric Le Goater     obj = xive_tctx_create(OBJECT(cpu), XIVE_PRESENTER(&chip10->xive),
1231da71b7e3SCédric Le Goater                            &local_err);
1232da71b7e3SCédric Le Goater     if (local_err) {
1233da71b7e3SCédric Le Goater         error_propagate(errp, local_err);
1234da71b7e3SCédric Le Goater         return;
1235da71b7e3SCédric Le Goater     }
1236da71b7e3SCédric Le Goater 
1237da71b7e3SCédric Le Goater     pnv_cpu->intc = obj;
12382b548a42SCédric Le Goater }
12392b548a42SCédric Le Goater 
pnv_chip_power10_intc_reset(PnvChip * chip,PowerPCCPU * cpu)12402b548a42SCédric Le Goater static void pnv_chip_power10_intc_reset(PnvChip *chip, PowerPCCPU *cpu)
12412b548a42SCédric Le Goater {
1242da71b7e3SCédric Le Goater     PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
1243da71b7e3SCédric Le Goater 
1244da71b7e3SCédric Le Goater     xive_tctx_reset(XIVE_TCTX(pnv_cpu->intc));
12452b548a42SCédric Le Goater }
12462b548a42SCédric Le Goater 
pnv_chip_power10_intc_destroy(PnvChip * chip,PowerPCCPU * cpu)12472b548a42SCédric Le Goater static void pnv_chip_power10_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
12482b548a42SCédric Le Goater {
12492b548a42SCédric Le Goater     PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
12502b548a42SCédric Le Goater 
1251da71b7e3SCédric Le Goater     xive_tctx_destroy(XIVE_TCTX(pnv_cpu->intc));
12522b548a42SCédric Le Goater     pnv_cpu->intc = NULL;
12532b548a42SCédric Le Goater }
12542b548a42SCédric Le Goater 
pnv_chip_power10_intc_print_info(PnvChip * chip,PowerPCCPU * cpu,Monitor * mon)125585913070SGreg Kurz static void pnv_chip_power10_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
125685913070SGreg Kurz                                              Monitor *mon)
125785913070SGreg Kurz {
1258da71b7e3SCédric Le Goater     xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), mon);
125985913070SGreg Kurz }
126085913070SGreg Kurz 
126159b7c1c2SBalamuruhan S /*
126259b7c1c2SBalamuruhan S  * Allowed core identifiers on a POWER8 Processor Chip :
1263397a79e7SCédric Le Goater  *
1264397a79e7SCédric Le Goater  * <EX0 reserved>
1265397a79e7SCédric Le Goater  *  EX1  - Venice only
1266397a79e7SCédric Le Goater  *  EX2  - Venice only
1267397a79e7SCédric Le Goater  *  EX3  - Venice only
1268397a79e7SCédric Le Goater  *  EX4
1269397a79e7SCédric Le Goater  *  EX5
1270397a79e7SCédric Le Goater  *  EX6
1271397a79e7SCédric Le Goater  * <EX7,8 reserved> <reserved>
1272397a79e7SCédric Le Goater  *  EX9  - Venice only
1273397a79e7SCédric Le Goater  *  EX10 - Venice only
1274397a79e7SCédric Le Goater  *  EX11 - Venice only
1275397a79e7SCédric Le Goater  *  EX12
1276397a79e7SCédric Le Goater  *  EX13
1277397a79e7SCédric Le Goater  *  EX14
1278397a79e7SCédric Le Goater  * <EX15 reserved>
1279397a79e7SCédric Le Goater  */
1280397a79e7SCédric Le Goater #define POWER8E_CORE_MASK  (0x7070ull)
1281397a79e7SCédric Le Goater #define POWER8_CORE_MASK   (0x7e7eull)
1282397a79e7SCédric Le Goater 
1283397a79e7SCédric Le Goater /*
128409279d7eSCédric Le Goater  * POWER9 has 24 cores, ids starting at 0x0
1285397a79e7SCédric Le Goater  */
128609279d7eSCédric Le Goater #define POWER9_CORE_MASK   (0xffffffffffffffull)
1287397a79e7SCédric Le Goater 
12882b548a42SCédric Le Goater 
12892b548a42SCédric Le Goater #define POWER10_CORE_MASK  (0xffffffffffffffull)
12902b548a42SCédric Le Goater 
pnv_chip_power8_instance_init(Object * obj)129177864267SCédric Le Goater static void pnv_chip_power8_instance_init(Object *obj)
129277864267SCédric Le Goater {
129377864267SCédric Le Goater     Pnv8Chip *chip8 = PNV8_CHIP(obj);
12949ae1329eSCédric Le Goater     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(obj);
12959ae1329eSCédric Le Goater     int i;
129677864267SCédric Le Goater 
1297245cdb7fSCédric Le Goater     object_property_add_link(obj, "xics", TYPE_XICS_FABRIC,
1298245cdb7fSCédric Le Goater                              (Object **)&chip8->xics,
1299245cdb7fSCédric Le Goater                              object_property_allow_set_link,
1300d2623129SMarkus Armbruster                              OBJ_PROP_LINK_STRONG);
1301245cdb7fSCédric Le Goater 
13029fc7fc4dSMarkus Armbruster     object_initialize_child(obj, "psi", &chip8->psi, TYPE_PNV8_PSI);
130377864267SCédric Le Goater 
13049fc7fc4dSMarkus Armbruster     object_initialize_child(obj, "lpc", &chip8->lpc, TYPE_PNV8_LPC);
130577864267SCédric Le Goater 
13069fc7fc4dSMarkus Armbruster     object_initialize_child(obj, "occ", &chip8->occ, TYPE_PNV8_OCC);
13073887d241SBalamuruhan S 
13089fc7fc4dSMarkus Armbruster     object_initialize_child(obj, "homer", &chip8->homer, TYPE_PNV8_HOMER);
13099ae1329eSCédric Le Goater 
1310892c3ad0SDaniel Henrique Barboza     if (defaults_enabled()) {
1311eb93c828SCédric Le Goater         chip8->num_phbs = pcc->num_phbs;
13121f6a88ffSCédric Le Goater 
1313eb93c828SCédric Le Goater         for (i = 0; i < chip8->num_phbs; i++) {
13140d512c71SDaniel Henrique Barboza             Object *phb = object_new(TYPE_PNV_PHB);
13150d512c71SDaniel Henrique Barboza 
13160d512c71SDaniel Henrique Barboza             /*
13170d512c71SDaniel Henrique Barboza              * We need the chip to parent the PHB to allow the DT
13180d512c71SDaniel Henrique Barboza              * to build correctly (via pnv_xscom_dt()).
13190d512c71SDaniel Henrique Barboza              *
13200d512c71SDaniel Henrique Barboza              * TODO: the PHB should be parented by a PEC device that, at
13210d512c71SDaniel Henrique Barboza              * this moment, is not modelled powernv8/phb3.
13220d512c71SDaniel Henrique Barboza              */
13230d512c71SDaniel Henrique Barboza             object_property_add_child(obj, "phb[*]", phb);
13240d512c71SDaniel Henrique Barboza             chip8->phbs[i] = PNV_PHB(phb);
13259ae1329eSCédric Le Goater         }
1326892c3ad0SDaniel Henrique Barboza     }
13279ae1329eSCédric Le Goater 
132877864267SCédric Le Goater }
132977864267SCédric Le Goater 
pnv_chip_icp_realize(Pnv8Chip * chip8,Error ** errp)133077864267SCédric Le Goater static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp)
133177864267SCédric Le Goater  {
133277864267SCédric Le Goater     PnvChip *chip = PNV_CHIP(chip8);
133377864267SCédric Le Goater     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
133477864267SCédric Le Goater     int i, j;
133577864267SCédric Le Goater     char *name;
133677864267SCédric Le Goater 
133777864267SCédric Le Goater     name = g_strdup_printf("icp-%x", chip->chip_id);
133877864267SCédric Le Goater     memory_region_init(&chip8->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE);
133977864267SCédric Le Goater     g_free(name);
1340bf3b9754SPhilippe Mathieu-Daudé     memory_region_add_subregion(get_system_memory(), PNV_ICP_BASE(chip),
1341bf3b9754SPhilippe Mathieu-Daudé                                 &chip8->icp_mmio);
134277864267SCédric Le Goater 
134377864267SCédric Le Goater     /* Map the ICP registers for each thread */
134477864267SCédric Le Goater     for (i = 0; i < chip->nr_cores; i++) {
13454fa28f23SGreg Kurz         PnvCore *pnv_core = chip->cores[i];
134677864267SCédric Le Goater         int core_hwid = CPU_CORE(pnv_core)->core_id;
134777864267SCédric Le Goater 
134877864267SCédric Le Goater         for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
13499940412aSCaleb Schlossin             uint32_t pir = pcc->chip_pir(chip, core_hwid, j);
1350245cdb7fSCédric Le Goater             PnvICPState *icp = PNV_ICP(xics_icp_get(chip8->xics, pir));
135177864267SCédric Le Goater 
135277864267SCédric Le Goater             memory_region_add_subregion(&chip8->icp_mmio, pir << 12,
135377864267SCédric Le Goater                                         &icp->mmio);
135477864267SCédric Le Goater         }
135577864267SCédric Le Goater     }
135677864267SCédric Le Goater }
135777864267SCédric Le Goater 
pnv_chip_power8_realize(DeviceState * dev,Error ** errp)135877864267SCédric Le Goater static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
135977864267SCédric Le Goater {
136077864267SCédric Le Goater     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
136177864267SCédric Le Goater     PnvChip *chip = PNV_CHIP(dev);
136277864267SCédric Le Goater     Pnv8Chip *chip8 = PNV8_CHIP(dev);
1363ae856055SCédric Le Goater     Pnv8Psi *psi8 = &chip8->psi;
136477864267SCédric Le Goater     Error *local_err = NULL;
13659ae1329eSCédric Le Goater     int i;
136677864267SCédric Le Goater 
1367245cdb7fSCédric Le Goater     assert(chip8->xics);
1368245cdb7fSCédric Le Goater 
1369709044fdSCédric Le Goater     /* XSCOM bridge is first */
1370326f7acbSPhilippe Mathieu-Daudé     pnv_xscom_init(chip, PNV_XSCOM_SIZE, PNV_XSCOM_BASE(chip));
1371709044fdSCédric Le Goater 
137277864267SCédric Le Goater     pcc->parent_realize(dev, &local_err);
137377864267SCédric Le Goater     if (local_err) {
137477864267SCédric Le Goater         error_propagate(errp, local_err);
137577864267SCédric Le Goater         return;
137677864267SCédric Le Goater     }
137777864267SCédric Le Goater 
137877864267SCédric Le Goater     /* Processor Service Interface (PSI) Host Bridge */
13795325cc34SMarkus Armbruster     object_property_set_int(OBJECT(psi8), "bar", PNV_PSIHB_BASE(chip),
13805325cc34SMarkus Armbruster                             &error_fatal);
13815325cc34SMarkus Armbruster     object_property_set_link(OBJECT(psi8), ICS_PROP_XICS,
13825325cc34SMarkus Armbruster                              OBJECT(chip8->xics), &error_abort);
1383668f62ecSMarkus Armbruster     if (!qdev_realize(DEVICE(psi8), NULL, errp)) {
138477864267SCédric Le Goater         return;
138577864267SCédric Le Goater     }
1386ae856055SCédric Le Goater     pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE,
1387ae856055SCédric Le Goater                             &PNV_PSI(psi8)->xscom_regs);
138877864267SCédric Le Goater 
138977864267SCédric Le Goater     /* Create LPC controller */
1390ce189ab2SMarkus Armbruster     qdev_realize(DEVICE(&chip8->lpc), NULL, &error_fatal);
139177864267SCédric Le Goater     pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
139277864267SCédric Le Goater 
1393032c226bSCédric Le Goater     chip->fw_mr = &chip8->lpc.isa_fw;
139464d011d5SCédric Le Goater     chip->dt_isa_nodename = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
139564d011d5SCédric Le Goater                                             (uint64_t) PNV_XSCOM_BASE(chip),
139664d011d5SCédric Le Goater                                             PNV_XSCOM_LPC_BASE);
139764d011d5SCédric Le Goater 
139859b7c1c2SBalamuruhan S     /*
139959b7c1c2SBalamuruhan S      * Interrupt Management Area. This is the memory region holding
140059b7c1c2SBalamuruhan S      * all the Interrupt Control Presenter (ICP) registers
140159b7c1c2SBalamuruhan S      */
140277864267SCédric Le Goater     pnv_chip_icp_realize(chip8, &local_err);
140377864267SCédric Le Goater     if (local_err) {
140477864267SCédric Le Goater         error_propagate(errp, local_err);
140577864267SCédric Le Goater         return;
140677864267SCédric Le Goater     }
140777864267SCédric Le Goater 
140877864267SCédric Le Goater     /* Create the simplified OCC model */
1409668f62ecSMarkus Armbruster     if (!qdev_realize(DEVICE(&chip8->occ), NULL, errp)) {
141077864267SCédric Le Goater         return;
141177864267SCédric Le Goater     }
141277864267SCédric Le Goater     pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip8->occ.xscom_regs);
1413b0ae5c69SCédric Le Goater     qdev_connect_gpio_out(DEVICE(&chip8->occ), 0,
1414b0ae5c69SCédric Le Goater                           qdev_get_gpio_in(DEVICE(psi8), PSIHB_IRQ_OCC));
1415f3db8266SBalamuruhan S 
1416f3db8266SBalamuruhan S     /* OCC SRAM model */
14173a1b70b6SCédric Le Goater     memory_region_add_subregion(get_system_memory(), PNV_OCC_SENSOR_BASE(chip),
1418f3db8266SBalamuruhan S                                 &chip8->occ.sram_regs);
14193887d241SBalamuruhan S 
14203887d241SBalamuruhan S     /* HOMER */
14215325cc34SMarkus Armbruster     object_property_set_link(OBJECT(&chip8->homer), "chip", OBJECT(chip),
1422f2582acfSGreg Kurz                              &error_abort);
1423668f62ecSMarkus Armbruster     if (!qdev_realize(DEVICE(&chip8->homer), NULL, errp)) {
14243887d241SBalamuruhan S         return;
14253887d241SBalamuruhan S     }
14268f092316SCédric Le Goater     /* Homer Xscom region */
14278f092316SCédric Le Goater     pnv_xscom_add_subregion(chip, PNV_XSCOM_PBA_BASE, &chip8->homer.pba_regs);
14288f092316SCédric Le Goater 
14298f092316SCédric Le Goater     /* Homer mmio region */
14303887d241SBalamuruhan S     memory_region_add_subregion(get_system_memory(), PNV_HOMER_BASE(chip),
14313887d241SBalamuruhan S                                 &chip8->homer.regs);
14329ae1329eSCédric Le Goater 
14331f5d6b2aSDaniel Henrique Barboza     /* PHB controllers */
1434eb93c828SCédric Le Goater     for (i = 0; i < chip8->num_phbs; i++) {
14350d512c71SDaniel Henrique Barboza         PnvPHB *phb = chip8->phbs[i];
14369ae1329eSCédric Le Goater 
14375325cc34SMarkus Armbruster         object_property_set_int(OBJECT(phb), "index", i, &error_fatal);
14385325cc34SMarkus Armbruster         object_property_set_int(OBJECT(phb), "chip-id", chip->chip_id,
14399ae1329eSCédric Le Goater                                 &error_fatal);
14402c4d3a50SCédric Le Goater         object_property_set_link(OBJECT(phb), "chip", OBJECT(chip),
14412c4d3a50SCédric Le Goater                                  &error_fatal);
1442668f62ecSMarkus Armbruster         if (!sysbus_realize(SYS_BUS_DEVICE(phb), errp)) {
14439ae1329eSCédric Le Goater             return;
14449ae1329eSCédric Le Goater         }
14459ae1329eSCédric Le Goater     }
144677864267SCédric Le Goater }
144777864267SCédric Le Goater 
pnv_chip_power8_xscom_pcba(PnvChip * chip,uint64_t addr)144870c059e9SGreg Kurz static uint32_t pnv_chip_power8_xscom_pcba(PnvChip *chip, uint64_t addr)
144970c059e9SGreg Kurz {
145070c059e9SGreg Kurz     addr &= (PNV_XSCOM_SIZE - 1);
145170c059e9SGreg Kurz     return ((addr >> 4) & ~0xfull) | ((addr >> 3) & 0xf);
145270c059e9SGreg Kurz }
145370c059e9SGreg Kurz 
pnv_chip_power8e_class_init(ObjectClass * klass,void * data)1454e997040eSCédric Le Goater static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
1455e997040eSCédric Le Goater {
1456e997040eSCédric Le Goater     DeviceClass *dc = DEVICE_CLASS(klass);
1457e997040eSCédric Le Goater     PnvChipClass *k = PNV_CHIP_CLASS(klass);
1458e997040eSCédric Le Goater 
1459e997040eSCédric Le Goater     k->chip_cfam_id = 0x221ef04980000000ull;  /* P8 Murano DD2.1 */
1460397a79e7SCédric Le Goater     k->cores_mask = POWER8E_CORE_MASK;
14619ae1329eSCédric Le Goater     k->num_phbs = 3;
14629940412aSCaleb Schlossin     k->chip_pir = pnv_chip_pir_p8;
1463d35aefa9SCédric Le Goater     k->intc_create = pnv_chip_power8_intc_create;
1464d49e8a9bSCédric Le Goater     k->intc_reset = pnv_chip_power8_intc_reset;
14650990ce6aSGreg Kurz     k->intc_destroy = pnv_chip_power8_intc_destroy;
146685913070SGreg Kurz     k->intc_print_info = pnv_chip_power8_intc_print_info;
146704026890SCédric Le Goater     k->isa_create = pnv_chip_power8_isa_create;
1468eb859a27SCédric Le Goater     k->dt_populate = pnv_chip_power8_dt_populate;
1469d8e4aad5SCédric Le Goater     k->pic_print_info = pnv_chip_power8_pic_print_info;
1470c4b2c40cSGreg Kurz     k->xscom_core_base = pnv_chip_power8_xscom_core_base;
147170c059e9SGreg Kurz     k->xscom_pcba = pnv_chip_power8_xscom_pcba;
1472e997040eSCédric Le Goater     dc->desc = "PowerNV Chip POWER8E";
147377864267SCédric Le Goater 
147477864267SCédric Le Goater     device_class_set_parent_realize(dc, pnv_chip_power8_realize,
147577864267SCédric Le Goater                                     &k->parent_realize);
1476e997040eSCédric Le Goater }
1477e997040eSCédric Le Goater 
pnv_chip_power8_class_init(ObjectClass * klass,void * data)1478e997040eSCédric Le Goater static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
1479e997040eSCédric Le Goater {
1480e997040eSCédric Le Goater     DeviceClass *dc = DEVICE_CLASS(klass);
1481e997040eSCédric Le Goater     PnvChipClass *k = PNV_CHIP_CLASS(klass);
1482e997040eSCédric Le Goater 
1483e997040eSCédric Le Goater     k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */
1484397a79e7SCédric Le Goater     k->cores_mask = POWER8_CORE_MASK;
14859ae1329eSCédric Le Goater     k->num_phbs = 3;
14869940412aSCaleb Schlossin     k->chip_pir = pnv_chip_pir_p8;
1487d35aefa9SCédric Le Goater     k->intc_create = pnv_chip_power8_intc_create;
1488d49e8a9bSCédric Le Goater     k->intc_reset = pnv_chip_power8_intc_reset;
14890990ce6aSGreg Kurz     k->intc_destroy = pnv_chip_power8_intc_destroy;
149085913070SGreg Kurz     k->intc_print_info = pnv_chip_power8_intc_print_info;
149104026890SCédric Le Goater     k->isa_create = pnv_chip_power8_isa_create;
1492eb859a27SCédric Le Goater     k->dt_populate = pnv_chip_power8_dt_populate;
1493d8e4aad5SCédric Le Goater     k->pic_print_info = pnv_chip_power8_pic_print_info;
1494c4b2c40cSGreg Kurz     k->xscom_core_base = pnv_chip_power8_xscom_core_base;
149570c059e9SGreg Kurz     k->xscom_pcba = pnv_chip_power8_xscom_pcba;
1496e997040eSCédric Le Goater     dc->desc = "PowerNV Chip POWER8";
149777864267SCédric Le Goater 
149877864267SCédric Le Goater     device_class_set_parent_realize(dc, pnv_chip_power8_realize,
149977864267SCédric Le Goater                                     &k->parent_realize);
1500e997040eSCédric Le Goater }
1501e997040eSCédric Le Goater 
pnv_chip_power8nvl_class_init(ObjectClass * klass,void * data)1502e997040eSCédric Le Goater static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
1503e997040eSCédric Le Goater {
1504e997040eSCédric Le Goater     DeviceClass *dc = DEVICE_CLASS(klass);
1505e997040eSCédric Le Goater     PnvChipClass *k = PNV_CHIP_CLASS(klass);
1506e997040eSCédric Le Goater 
1507e997040eSCédric Le Goater     k->chip_cfam_id = 0x120d304980000000ull;  /* P8 Naples DD1.0 */
1508397a79e7SCédric Le Goater     k->cores_mask = POWER8_CORE_MASK;
1509316717feSCédric Le Goater     k->num_phbs = 4;
15109940412aSCaleb Schlossin     k->chip_pir = pnv_chip_pir_p8;
1511d35aefa9SCédric Le Goater     k->intc_create = pnv_chip_power8_intc_create;
1512d49e8a9bSCédric Le Goater     k->intc_reset = pnv_chip_power8_intc_reset;
15130990ce6aSGreg Kurz     k->intc_destroy = pnv_chip_power8_intc_destroy;
151485913070SGreg Kurz     k->intc_print_info = pnv_chip_power8_intc_print_info;
151504026890SCédric Le Goater     k->isa_create = pnv_chip_power8nvl_isa_create;
1516eb859a27SCédric Le Goater     k->dt_populate = pnv_chip_power8_dt_populate;
1517d8e4aad5SCédric Le Goater     k->pic_print_info = pnv_chip_power8_pic_print_info;
1518c4b2c40cSGreg Kurz     k->xscom_core_base = pnv_chip_power8_xscom_core_base;
151970c059e9SGreg Kurz     k->xscom_pcba = pnv_chip_power8_xscom_pcba;
1520e997040eSCédric Le Goater     dc->desc = "PowerNV Chip POWER8NVL";
152177864267SCédric Le Goater 
152277864267SCédric Le Goater     device_class_set_parent_realize(dc, pnv_chip_power8_realize,
152377864267SCédric Le Goater                                     &k->parent_realize);
152477864267SCédric Le Goater }
152577864267SCédric Le Goater 
pnv_chip_power9_instance_init(Object * obj)152677864267SCédric Le Goater static void pnv_chip_power9_instance_init(Object *obj)
152777864267SCédric Le Goater {
15284f9924c4SBenjamin Herrenschmidt     PnvChip *chip = PNV_CHIP(obj);
15292dfa91a2SCédric Le Goater     Pnv9Chip *chip9 = PNV9_CHIP(obj);
15304f9924c4SBenjamin Herrenschmidt     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(obj);
15314f9924c4SBenjamin Herrenschmidt     int i;
15322dfa91a2SCédric Le Goater 
1533db873cc5SMarkus Armbruster     object_initialize_child(obj, "xive", &chip9->xive, TYPE_PNV_XIVE);
1534d1214b81SGreg Kurz     object_property_add_alias(obj, "xive-fabric", OBJECT(&chip9->xive),
1535d2623129SMarkus Armbruster                               "xive-fabric");
1536c38536bcSCédric Le Goater 
15379fc7fc4dSMarkus Armbruster     object_initialize_child(obj, "psi", &chip9->psi, TYPE_PNV9_PSI);
153815376c66SCédric Le Goater 
15399fc7fc4dSMarkus Armbruster     object_initialize_child(obj, "lpc", &chip9->lpc, TYPE_PNV9_LPC);
15406598a70dSCédric Le Goater 
1541de3ba0ccSNicholas Piggin     object_initialize_child(obj, "chiptod", &chip9->chiptod, TYPE_PNV9_CHIPTOD);
1542de3ba0ccSNicholas Piggin 
15439fc7fc4dSMarkus Armbruster     object_initialize_child(obj, "occ", &chip9->occ, TYPE_PNV9_OCC);
15443887d241SBalamuruhan S 
15450bf4d77eSNicholas Piggin     object_initialize_child(obj, "sbe", &chip9->sbe, TYPE_PNV9_SBE);
15460bf4d77eSNicholas Piggin 
15479fc7fc4dSMarkus Armbruster     object_initialize_child(obj, "homer", &chip9->homer, TYPE_PNV9_HOMER);
15484f9924c4SBenjamin Herrenschmidt 
1549422fd92eSCédric Le Goater     /* Number of PECs is the chip default */
1550422fd92eSCédric Le Goater     chip->num_pecs = pcc->num_pecs;
1551422fd92eSCédric Le Goater 
1552422fd92eSCédric Le Goater     for (i = 0; i < chip->num_pecs; i++) {
15534f9924c4SBenjamin Herrenschmidt         object_initialize_child(obj, "pec[*]", &chip9->pecs[i],
15549fc7fc4dSMarkus Armbruster                                 TYPE_PNV_PHB4_PEC);
15554f9924c4SBenjamin Herrenschmidt     }
15565f066121SCédric Le Goater 
15575f066121SCédric Le Goater     for (i = 0; i < pcc->i2c_num_engines; i++) {
15585f066121SCédric Le Goater         object_initialize_child(obj, "i2c[*]", &chip9->i2c[i], TYPE_PNV_I2C);
15595f066121SCédric Le Goater     }
156077864267SCédric Le Goater }
156177864267SCédric Le Goater 
pnv_chip_quad_realize_one(PnvChip * chip,PnvQuad * eq,PnvCore * pnv_core,const char * type)1562ae4c68e3SCédric Le Goater static void pnv_chip_quad_realize_one(PnvChip *chip, PnvQuad *eq,
1563fdc2b46aSJoel Stanley                                       PnvCore *pnv_core,
1564fdc2b46aSJoel Stanley                                       const char *type)
15655dad902cSCédric Le Goater {
15665dad902cSCédric Le Goater     char eq_name[32];
15675dad902cSCédric Le Goater     int core_id = CPU_CORE(pnv_core)->core_id;
15685dad902cSCédric Le Goater 
15695dad902cSCédric Le Goater     snprintf(eq_name, sizeof(eq_name), "eq[%d]", core_id);
15709fc7fc4dSMarkus Armbruster     object_initialize_child_with_props(OBJECT(chip), eq_name, eq,
1571fdc2b46aSJoel Stanley                                        sizeof(*eq), type,
15729fc7fc4dSMarkus Armbruster                                        &error_fatal, NULL);
15735dad902cSCédric Le Goater 
157492612f15SCédric Le Goater     object_property_set_int(OBJECT(eq), "quad-id", core_id, &error_fatal);
1575ce189ab2SMarkus Armbruster     qdev_realize(DEVICE(eq), NULL, &error_fatal);
1576ae4c68e3SCédric Le Goater }
1577ae4c68e3SCédric Le Goater 
pnv_chip_quad_realize(Pnv9Chip * chip9,Error ** errp)1578ae4c68e3SCédric Le Goater static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp)
1579ae4c68e3SCédric Le Goater {
1580ae4c68e3SCédric Le Goater     PnvChip *chip = PNV_CHIP(chip9);
1581ae4c68e3SCédric Le Goater     int i;
1582ae4c68e3SCédric Le Goater 
1583ae4c68e3SCédric Le Goater     chip9->nr_quads = DIV_ROUND_UP(chip->nr_cores, 4);
1584ae4c68e3SCédric Le Goater     chip9->quads = g_new0(PnvQuad, chip9->nr_quads);
1585ae4c68e3SCédric Le Goater 
1586ae4c68e3SCédric Le Goater     for (i = 0; i < chip9->nr_quads; i++) {
1587ae4c68e3SCédric Le Goater         PnvQuad *eq = &chip9->quads[i];
1588ae4c68e3SCédric Le Goater 
1589fdc2b46aSJoel Stanley         pnv_chip_quad_realize_one(chip, eq, chip->cores[i * 4],
1590fdc2b46aSJoel Stanley                                   PNV_QUAD_TYPE_NAME("power9"));
15915dad902cSCédric Le Goater 
159292612f15SCédric Le Goater         pnv_xscom_add_subregion(chip, PNV9_XSCOM_EQ_BASE(eq->quad_id),
15935dad902cSCédric Le Goater                                 &eq->xscom_regs);
15945dad902cSCédric Le Goater     }
15955dad902cSCédric Le Goater }
15965dad902cSCédric Le Goater 
pnv_chip_power9_pec_realize(PnvChip * chip,Error ** errp)159713480fc5SCédric Le Goater static void pnv_chip_power9_pec_realize(PnvChip *chip, Error **errp)
15984f9924c4SBenjamin Herrenschmidt {
15994f9924c4SBenjamin Herrenschmidt     Pnv9Chip *chip9 = PNV9_CHIP(chip);
160013480fc5SCédric Le Goater     int i;
16014f9924c4SBenjamin Herrenschmidt 
1602422fd92eSCédric Le Goater     for (i = 0; i < chip->num_pecs; i++) {
16034f9924c4SBenjamin Herrenschmidt         PnvPhb4PecState *pec = &chip9->pecs[i];
16044f9924c4SBenjamin Herrenschmidt         PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(pec);
16054f9924c4SBenjamin Herrenschmidt         uint32_t pec_nest_base;
16064f9924c4SBenjamin Herrenschmidt         uint32_t pec_pci_base;
16074f9924c4SBenjamin Herrenschmidt 
16085325cc34SMarkus Armbruster         object_property_set_int(OBJECT(pec), "index", i, &error_fatal);
16095325cc34SMarkus Armbruster         object_property_set_int(OBJECT(pec), "chip-id", chip->chip_id,
16104f9924c4SBenjamin Herrenschmidt                                 &error_fatal);
16116f43d255SCédric Le Goater         object_property_set_link(OBJECT(pec), "chip", OBJECT(chip),
16126f43d255SCédric Le Goater                                  &error_fatal);
1613668f62ecSMarkus Armbruster         if (!qdev_realize(DEVICE(pec), NULL, errp)) {
16144f9924c4SBenjamin Herrenschmidt             return;
16154f9924c4SBenjamin Herrenschmidt         }
16164f9924c4SBenjamin Herrenschmidt 
16174f9924c4SBenjamin Herrenschmidt         pec_nest_base = pecc->xscom_nest_base(pec);
16184f9924c4SBenjamin Herrenschmidt         pec_pci_base = pecc->xscom_pci_base(pec);
16194f9924c4SBenjamin Herrenschmidt 
16204f9924c4SBenjamin Herrenschmidt         pnv_xscom_add_subregion(chip, pec_nest_base, &pec->nest_regs_mr);
16214f9924c4SBenjamin Herrenschmidt         pnv_xscom_add_subregion(chip, pec_pci_base, &pec->pci_regs_mr);
16224f9924c4SBenjamin Herrenschmidt     }
16234f9924c4SBenjamin Herrenschmidt }
16244f9924c4SBenjamin Herrenschmidt 
pnv_chip_power9_realize(DeviceState * dev,Error ** errp)162577864267SCédric Le Goater static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
162677864267SCédric Le Goater {
162777864267SCédric Le Goater     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
16282dfa91a2SCédric Le Goater     Pnv9Chip *chip9 = PNV9_CHIP(dev);
16292dfa91a2SCédric Le Goater     PnvChip *chip = PNV_CHIP(dev);
1630c38536bcSCédric Le Goater     Pnv9Psi *psi9 = &chip9->psi;
163177864267SCédric Le Goater     Error *local_err = NULL;
16325f066121SCédric Le Goater     int i;
163377864267SCédric Le Goater 
1634709044fdSCédric Le Goater     /* XSCOM bridge is first */
1635326f7acbSPhilippe Mathieu-Daudé     pnv_xscom_init(chip, PNV9_XSCOM_SIZE, PNV9_XSCOM_BASE(chip));
1636709044fdSCédric Le Goater 
163777864267SCédric Le Goater     pcc->parent_realize(dev, &local_err);
163877864267SCédric Le Goater     if (local_err) {
163977864267SCédric Le Goater         error_propagate(errp, local_err);
164077864267SCédric Le Goater         return;
164177864267SCédric Le Goater     }
16422dfa91a2SCédric Le Goater 
16435dad902cSCédric Le Goater     pnv_chip_quad_realize(chip9, &local_err);
16445dad902cSCédric Le Goater     if (local_err) {
16455dad902cSCédric Le Goater         error_propagate(errp, local_err);
16465dad902cSCédric Le Goater         return;
16475dad902cSCédric Le Goater     }
16485dad902cSCédric Le Goater 
16492dfa91a2SCédric Le Goater     /* XIVE interrupt controller (POWER9) */
16505325cc34SMarkus Armbruster     object_property_set_int(OBJECT(&chip9->xive), "ic-bar",
16515325cc34SMarkus Armbruster                             PNV9_XIVE_IC_BASE(chip), &error_fatal);
16525325cc34SMarkus Armbruster     object_property_set_int(OBJECT(&chip9->xive), "vc-bar",
16535325cc34SMarkus Armbruster                             PNV9_XIVE_VC_BASE(chip), &error_fatal);
16545325cc34SMarkus Armbruster     object_property_set_int(OBJECT(&chip9->xive), "pc-bar",
16555325cc34SMarkus Armbruster                             PNV9_XIVE_PC_BASE(chip), &error_fatal);
16565325cc34SMarkus Armbruster     object_property_set_int(OBJECT(&chip9->xive), "tm-bar",
16575325cc34SMarkus Armbruster                             PNV9_XIVE_TM_BASE(chip), &error_fatal);
16585325cc34SMarkus Armbruster     object_property_set_link(OBJECT(&chip9->xive), "chip", OBJECT(chip),
16597ae54cc3SGreg Kurz                              &error_abort);
1660668f62ecSMarkus Armbruster     if (!sysbus_realize(SYS_BUS_DEVICE(&chip9->xive), errp)) {
16612dfa91a2SCédric Le Goater         return;
16622dfa91a2SCédric Le Goater     }
16632dfa91a2SCédric Le Goater     pnv_xscom_add_subregion(chip, PNV9_XSCOM_XIVE_BASE,
16642dfa91a2SCédric Le Goater                             &chip9->xive.xscom_regs);
1665c38536bcSCédric Le Goater 
1666c38536bcSCédric Le Goater     /* Processor Service Interface (PSI) Host Bridge */
16675325cc34SMarkus Armbruster     object_property_set_int(OBJECT(psi9), "bar", PNV9_PSIHB_BASE(chip),
16685325cc34SMarkus Armbruster                             &error_fatal);
166924c8fa96SCédric Le Goater     /* This is the only device with 4k ESB pages */
167024c8fa96SCédric Le Goater     object_property_set_int(OBJECT(psi9), "shift", XIVE_ESB_4K,
167124c8fa96SCédric Le Goater                             &error_fatal);
1672668f62ecSMarkus Armbruster     if (!qdev_realize(DEVICE(psi9), NULL, errp)) {
1673c38536bcSCédric Le Goater         return;
1674c38536bcSCédric Le Goater     }
1675c38536bcSCédric Le Goater     pnv_xscom_add_subregion(chip, PNV9_XSCOM_PSIHB_BASE,
1676c38536bcSCédric Le Goater                             &PNV_PSI(psi9)->xscom_regs);
167715376c66SCédric Le Goater 
167815376c66SCédric Le Goater     /* LPC */
1679668f62ecSMarkus Armbruster     if (!qdev_realize(DEVICE(&chip9->lpc), NULL, errp)) {
168015376c66SCédric Le Goater         return;
168115376c66SCédric Le Goater     }
168215376c66SCédric Le Goater     memory_region_add_subregion(get_system_memory(), PNV9_LPCM_BASE(chip),
168315376c66SCédric Le Goater                                 &chip9->lpc.xscom_regs);
168415376c66SCédric Le Goater 
1685032c226bSCédric Le Goater     chip->fw_mr = &chip9->lpc.isa_fw;
168615376c66SCédric Le Goater     chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
168715376c66SCédric Le Goater                                             (uint64_t) PNV9_LPCM_BASE(chip));
16886598a70dSCédric Le Goater 
1689de3ba0ccSNicholas Piggin     /* ChipTOD */
1690de3ba0ccSNicholas Piggin     object_property_set_bool(OBJECT(&chip9->chiptod), "primary",
1691de3ba0ccSNicholas Piggin                              chip->chip_id == 0, &error_abort);
1692de3ba0ccSNicholas Piggin     object_property_set_bool(OBJECT(&chip9->chiptod), "secondary",
1693de3ba0ccSNicholas Piggin                              chip->chip_id == 1, &error_abort);
1694de3ba0ccSNicholas Piggin     object_property_set_link(OBJECT(&chip9->chiptod), "chip", OBJECT(chip),
1695de3ba0ccSNicholas Piggin                              &error_abort);
1696de3ba0ccSNicholas Piggin     if (!qdev_realize(DEVICE(&chip9->chiptod), NULL, errp)) {
1697de3ba0ccSNicholas Piggin         return;
1698de3ba0ccSNicholas Piggin     }
1699de3ba0ccSNicholas Piggin     pnv_xscom_add_subregion(chip, PNV9_XSCOM_CHIPTOD_BASE,
1700de3ba0ccSNicholas Piggin                             &chip9->chiptod.xscom_regs);
1701de3ba0ccSNicholas Piggin 
17026598a70dSCédric Le Goater     /* Create the simplified OCC model */
1703668f62ecSMarkus Armbruster     if (!qdev_realize(DEVICE(&chip9->occ), NULL, errp)) {
17046598a70dSCédric Le Goater         return;
17056598a70dSCédric Le Goater     }
17066598a70dSCédric Le Goater     pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
1707b0ae5c69SCédric Le Goater     qdev_connect_gpio_out(DEVICE(&chip9->occ), 0, qdev_get_gpio_in(
1708b0ae5c69SCédric Le Goater                               DEVICE(psi9), PSIHB9_IRQ_OCC));
1709f3db8266SBalamuruhan S 
1710f3db8266SBalamuruhan S     /* OCC SRAM model */
17113a1b70b6SCédric Le Goater     memory_region_add_subregion(get_system_memory(), PNV9_OCC_SENSOR_BASE(chip),
1712f3db8266SBalamuruhan S                                 &chip9->occ.sram_regs);
17133887d241SBalamuruhan S 
17140bf4d77eSNicholas Piggin     /* SBE */
17150bf4d77eSNicholas Piggin     if (!qdev_realize(DEVICE(&chip9->sbe), NULL, errp)) {
17160bf4d77eSNicholas Piggin         return;
17170bf4d77eSNicholas Piggin     }
17180bf4d77eSNicholas Piggin     pnv_xscom_add_subregion(chip, PNV9_XSCOM_SBE_CTRL_BASE,
17190bf4d77eSNicholas Piggin                             &chip9->sbe.xscom_ctrl_regs);
17200bf4d77eSNicholas Piggin     pnv_xscom_add_subregion(chip, PNV9_XSCOM_SBE_MBOX_BASE,
17210bf4d77eSNicholas Piggin                             &chip9->sbe.xscom_mbox_regs);
17220bf4d77eSNicholas Piggin     qdev_connect_gpio_out(DEVICE(&chip9->sbe), 0, qdev_get_gpio_in(
17230bf4d77eSNicholas Piggin                               DEVICE(psi9), PSIHB9_IRQ_PSU));
17240bf4d77eSNicholas Piggin 
17253887d241SBalamuruhan S     /* HOMER */
17265325cc34SMarkus Armbruster     object_property_set_link(OBJECT(&chip9->homer), "chip", OBJECT(chip),
1727f2582acfSGreg Kurz                              &error_abort);
1728668f62ecSMarkus Armbruster     if (!qdev_realize(DEVICE(&chip9->homer), NULL, errp)) {
17293887d241SBalamuruhan S         return;
17303887d241SBalamuruhan S     }
17318f092316SCédric Le Goater     /* Homer Xscom region */
17328f092316SCédric Le Goater     pnv_xscom_add_subregion(chip, PNV9_XSCOM_PBA_BASE, &chip9->homer.pba_regs);
17338f092316SCédric Le Goater 
17348f092316SCédric Le Goater     /* Homer mmio region */
17353887d241SBalamuruhan S     memory_region_add_subregion(get_system_memory(), PNV9_HOMER_BASE(chip),
17363887d241SBalamuruhan S                                 &chip9->homer.regs);
17374f9924c4SBenjamin Herrenschmidt 
173813480fc5SCédric Le Goater     /* PEC PHBs */
173913480fc5SCédric Le Goater     pnv_chip_power9_pec_realize(chip, &local_err);
17404f9924c4SBenjamin Herrenschmidt     if (local_err) {
17414f9924c4SBenjamin Herrenschmidt         error_propagate(errp, local_err);
17424f9924c4SBenjamin Herrenschmidt         return;
17434f9924c4SBenjamin Herrenschmidt     }
17445f066121SCédric Le Goater 
17455f066121SCédric Le Goater     /*
17465f066121SCédric Le Goater      * I2C
17475f066121SCédric Le Goater      */
17485f066121SCédric Le Goater     for (i = 0; i < pcc->i2c_num_engines; i++) {
17495f066121SCédric Le Goater         Object *obj =  OBJECT(&chip9->i2c[i]);
17505f066121SCédric Le Goater 
17515f066121SCédric Le Goater         object_property_set_int(obj, "engine", i + 1, &error_fatal);
17520d1dcb0bSGlenn Miles         object_property_set_int(obj, "num-busses",
17530d1dcb0bSGlenn Miles                                 pcc->i2c_ports_per_engine[i],
17545f066121SCédric Le Goater                                 &error_fatal);
17555f066121SCédric Le Goater         object_property_set_link(obj, "chip", OBJECT(chip), &error_abort);
17565f066121SCédric Le Goater         if (!qdev_realize(DEVICE(obj), NULL, errp)) {
17575f066121SCédric Le Goater             return;
17585f066121SCédric Le Goater         }
17595f066121SCédric Le Goater         pnv_xscom_add_subregion(chip, PNV9_XSCOM_I2CM_BASE +
176047dfdd23SGlenn Miles                                 (chip9->i2c[i].engine - 1) *
176147dfdd23SGlenn Miles                                         PNV9_XSCOM_I2CM_SIZE,
17625f066121SCédric Le Goater                                 &chip9->i2c[i].xscom_regs);
17635f066121SCédric Le Goater         qdev_connect_gpio_out(DEVICE(&chip9->i2c[i]), 0,
17645f066121SCédric Le Goater                               qdev_get_gpio_in(DEVICE(psi9),
17655f066121SCédric Le Goater                                                PSIHB9_IRQ_SBE_I2C));
17665f066121SCédric Le Goater     }
1767e997040eSCédric Le Goater }
1768e997040eSCédric Le Goater 
pnv_chip_power9_xscom_pcba(PnvChip * chip,uint64_t addr)176970c059e9SGreg Kurz static uint32_t pnv_chip_power9_xscom_pcba(PnvChip *chip, uint64_t addr)
177070c059e9SGreg Kurz {
177170c059e9SGreg Kurz     addr &= (PNV9_XSCOM_SIZE - 1);
177270c059e9SGreg Kurz     return addr >> 3;
177370c059e9SGreg Kurz }
177470c059e9SGreg Kurz 
pnv_chip_power9_class_init(ObjectClass * klass,void * data)1775e997040eSCédric Le Goater static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
1776e997040eSCédric Le Goater {
1777e997040eSCédric Le Goater     DeviceClass *dc = DEVICE_CLASS(klass);
1778e997040eSCédric Le Goater     PnvChipClass *k = PNV_CHIP_CLASS(klass);
17790d1dcb0bSGlenn Miles     static const int i2c_ports_per_engine[PNV9_CHIP_MAX_I2C] = {2, 13, 2, 2};
1780e997040eSCédric Le Goater 
178183028a2bSCédric Le Goater     k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */
1782397a79e7SCédric Le Goater     k->cores_mask = POWER9_CORE_MASK;
17839940412aSCaleb Schlossin     k->chip_pir = pnv_chip_pir_p9;
1784d35aefa9SCédric Le Goater     k->intc_create = pnv_chip_power9_intc_create;
1785d49e8a9bSCédric Le Goater     k->intc_reset = pnv_chip_power9_intc_reset;
17860990ce6aSGreg Kurz     k->intc_destroy = pnv_chip_power9_intc_destroy;
178785913070SGreg Kurz     k->intc_print_info = pnv_chip_power9_intc_print_info;
178804026890SCédric Le Goater     k->isa_create = pnv_chip_power9_isa_create;
1789eb859a27SCédric Le Goater     k->dt_populate = pnv_chip_power9_dt_populate;
1790d8e4aad5SCédric Le Goater     k->pic_print_info = pnv_chip_power9_pic_print_info;
1791c4b2c40cSGreg Kurz     k->xscom_core_base = pnv_chip_power9_xscom_core_base;
179270c059e9SGreg Kurz     k->xscom_pcba = pnv_chip_power9_xscom_pcba;
1793e997040eSCédric Le Goater     dc->desc = "PowerNV Chip POWER9";
1794422fd92eSCédric Le Goater     k->num_pecs = PNV9_CHIP_MAX_PEC;
17955f066121SCédric Le Goater     k->i2c_num_engines = PNV9_CHIP_MAX_I2C;
17960d1dcb0bSGlenn Miles     k->i2c_ports_per_engine = i2c_ports_per_engine;
179777864267SCédric Le Goater 
179877864267SCédric Le Goater     device_class_set_parent_realize(dc, pnv_chip_power9_realize,
179977864267SCédric Le Goater                                     &k->parent_realize);
1800e997040eSCédric Le Goater }
1801e997040eSCédric Le Goater 
pnv_chip_power10_instance_init(Object * obj)18022b548a42SCédric Le Goater static void pnv_chip_power10_instance_init(Object *obj)
18032b548a42SCédric Le Goater {
1804623575e1SCédric Le Goater     PnvChip *chip = PNV_CHIP(obj);
18058b50ce85SCédric Le Goater     Pnv10Chip *chip10 = PNV10_CHIP(obj);
1806623575e1SCédric Le Goater     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(obj);
1807623575e1SCédric Le Goater     int i;
18088b50ce85SCédric Le Goater 
1809da71b7e3SCédric Le Goater     object_initialize_child(obj, "xive", &chip10->xive, TYPE_PNV_XIVE2);
1810da71b7e3SCédric Le Goater     object_property_add_alias(obj, "xive-fabric", OBJECT(&chip10->xive),
1811da71b7e3SCédric Le Goater                               "xive-fabric");
18129fc7fc4dSMarkus Armbruster     object_initialize_child(obj, "psi", &chip10->psi, TYPE_PNV10_PSI);
18139fc7fc4dSMarkus Armbruster     object_initialize_child(obj, "lpc", &chip10->lpc, TYPE_PNV10_LPC);
1814de3ba0ccSNicholas Piggin     object_initialize_child(obj, "chiptod", &chip10->chiptod,
1815de3ba0ccSNicholas Piggin                             TYPE_PNV10_CHIPTOD);
18168bf682a3SCédric Le Goater     object_initialize_child(obj, "occ",  &chip10->occ, TYPE_PNV10_OCC);
18170bf4d77eSNicholas Piggin     object_initialize_child(obj, "sbe",  &chip10->sbe, TYPE_PNV10_SBE);
181892499676SCédric Le Goater     object_initialize_child(obj, "homer", &chip10->homer, TYPE_PNV10_HOMER);
1819c295d3b0SChalapathi V     object_initialize_child(obj, "n1-chiplet", &chip10->n1_chiplet,
1820c295d3b0SChalapathi V                             TYPE_PNV_N1_CHIPLET);
1821623575e1SCédric Le Goater 
1822623575e1SCédric Le Goater     chip->num_pecs = pcc->num_pecs;
1823623575e1SCédric Le Goater 
1824623575e1SCédric Le Goater     for (i = 0; i < chip->num_pecs; i++) {
1825623575e1SCédric Le Goater         object_initialize_child(obj, "pec[*]", &chip10->pecs[i],
1826623575e1SCédric Le Goater                                 TYPE_PNV_PHB5_PEC);
1827623575e1SCédric Le Goater     }
18281ceda19cSGlenn Miles 
18291ceda19cSGlenn Miles     for (i = 0; i < pcc->i2c_num_engines; i++) {
18301ceda19cSGlenn Miles         object_initialize_child(obj, "i2c[*]", &chip10->i2c[i], TYPE_PNV_I2C);
18311ceda19cSGlenn Miles     }
18322b548a42SCédric Le Goater }
18332b548a42SCédric Le Goater 
pnv_chip_power10_quad_realize(Pnv10Chip * chip10,Error ** errp)1834ae4c68e3SCédric Le Goater static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp)
1835ae4c68e3SCédric Le Goater {
1836ae4c68e3SCédric Le Goater     PnvChip *chip = PNV_CHIP(chip10);
1837ae4c68e3SCédric Le Goater     int i;
1838ae4c68e3SCédric Le Goater 
1839ae4c68e3SCédric Le Goater     chip10->nr_quads = DIV_ROUND_UP(chip->nr_cores, 4);
1840ae4c68e3SCédric Le Goater     chip10->quads = g_new0(PnvQuad, chip10->nr_quads);
1841ae4c68e3SCédric Le Goater 
1842ae4c68e3SCédric Le Goater     for (i = 0; i < chip10->nr_quads; i++) {
1843ae4c68e3SCédric Le Goater         PnvQuad *eq = &chip10->quads[i];
1844ae4c68e3SCédric Le Goater 
1845fdc2b46aSJoel Stanley         pnv_chip_quad_realize_one(chip, eq, chip->cores[i * 4],
1846a1d64b9eSJoel Stanley                                   PNV_QUAD_TYPE_NAME("power10"));
1847ae4c68e3SCédric Le Goater 
1848ae4c68e3SCédric Le Goater         pnv_xscom_add_subregion(chip, PNV10_XSCOM_EQ_BASE(eq->quad_id),
1849ae4c68e3SCédric Le Goater                                 &eq->xscom_regs);
1850bdb97596SJoel Stanley 
1851bdb97596SJoel Stanley         pnv_xscom_add_subregion(chip, PNV10_XSCOM_QME_BASE(eq->quad_id),
1852bdb97596SJoel Stanley                                 &eq->xscom_qme_regs);
1853ae4c68e3SCédric Le Goater     }
1854ae4c68e3SCédric Le Goater }
1855ae4c68e3SCédric Le Goater 
pnv_chip_power10_phb_realize(PnvChip * chip,Error ** errp)1856623575e1SCédric Le Goater static void pnv_chip_power10_phb_realize(PnvChip *chip, Error **errp)
1857623575e1SCédric Le Goater {
1858623575e1SCédric Le Goater     Pnv10Chip *chip10 = PNV10_CHIP(chip);
1859623575e1SCédric Le Goater     int i;
1860623575e1SCédric Le Goater 
1861623575e1SCédric Le Goater     for (i = 0; i < chip->num_pecs; i++) {
1862623575e1SCédric Le Goater         PnvPhb4PecState *pec = &chip10->pecs[i];
1863623575e1SCédric Le Goater         PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(pec);
1864623575e1SCédric Le Goater         uint32_t pec_nest_base;
1865623575e1SCédric Le Goater         uint32_t pec_pci_base;
1866623575e1SCédric Le Goater 
1867623575e1SCédric Le Goater         object_property_set_int(OBJECT(pec), "index", i, &error_fatal);
1868623575e1SCédric Le Goater         object_property_set_int(OBJECT(pec), "chip-id", chip->chip_id,
1869623575e1SCédric Le Goater                                 &error_fatal);
1870623575e1SCédric Le Goater         object_property_set_link(OBJECT(pec), "chip", OBJECT(chip),
1871623575e1SCédric Le Goater                                  &error_fatal);
1872623575e1SCédric Le Goater         if (!qdev_realize(DEVICE(pec), NULL, errp)) {
1873623575e1SCédric Le Goater             return;
1874623575e1SCédric Le Goater         }
1875623575e1SCédric Le Goater 
1876623575e1SCédric Le Goater         pec_nest_base = pecc->xscom_nest_base(pec);
1877623575e1SCédric Le Goater         pec_pci_base = pecc->xscom_pci_base(pec);
1878623575e1SCédric Le Goater 
1879623575e1SCédric Le Goater         pnv_xscom_add_subregion(chip, pec_nest_base, &pec->nest_regs_mr);
1880623575e1SCédric Le Goater         pnv_xscom_add_subregion(chip, pec_pci_base, &pec->pci_regs_mr);
1881623575e1SCédric Le Goater     }
1882623575e1SCédric Le Goater }
1883623575e1SCédric Le Goater 
pnv_chip_power10_realize(DeviceState * dev,Error ** errp)18842b548a42SCédric Le Goater static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
18852b548a42SCédric Le Goater {
18862b548a42SCédric Le Goater     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
18872b548a42SCédric Le Goater     PnvChip *chip = PNV_CHIP(dev);
18888b50ce85SCédric Le Goater     Pnv10Chip *chip10 = PNV10_CHIP(dev);
18892b548a42SCédric Le Goater     Error *local_err = NULL;
18901ceda19cSGlenn Miles     int i;
18912b548a42SCédric Le Goater 
18922b548a42SCédric Le Goater     /* XSCOM bridge is first */
1893326f7acbSPhilippe Mathieu-Daudé     pnv_xscom_init(chip, PNV10_XSCOM_SIZE, PNV10_XSCOM_BASE(chip));
18942b548a42SCédric Le Goater 
18952b548a42SCédric Le Goater     pcc->parent_realize(dev, &local_err);
18962b548a42SCédric Le Goater     if (local_err) {
18972b548a42SCédric Le Goater         error_propagate(errp, local_err);
18982b548a42SCédric Le Goater         return;
18992b548a42SCédric Le Goater     }
19008b50ce85SCédric Le Goater 
1901ae4c68e3SCédric Le Goater     pnv_chip_power10_quad_realize(chip10, &local_err);
1902ae4c68e3SCédric Le Goater     if (local_err) {
1903ae4c68e3SCédric Le Goater         error_propagate(errp, local_err);
1904ae4c68e3SCédric Le Goater         return;
1905ae4c68e3SCédric Le Goater     }
1906ae4c68e3SCédric Le Goater 
1907da71b7e3SCédric Le Goater     /* XIVE2 interrupt controller (POWER10) */
1908da71b7e3SCédric Le Goater     object_property_set_int(OBJECT(&chip10->xive), "ic-bar",
1909da71b7e3SCédric Le Goater                             PNV10_XIVE2_IC_BASE(chip), &error_fatal);
1910da71b7e3SCédric Le Goater     object_property_set_int(OBJECT(&chip10->xive), "esb-bar",
1911da71b7e3SCédric Le Goater                             PNV10_XIVE2_ESB_BASE(chip), &error_fatal);
1912da71b7e3SCédric Le Goater     object_property_set_int(OBJECT(&chip10->xive), "end-bar",
1913da71b7e3SCédric Le Goater                             PNV10_XIVE2_END_BASE(chip), &error_fatal);
1914da71b7e3SCédric Le Goater     object_property_set_int(OBJECT(&chip10->xive), "nvpg-bar",
1915da71b7e3SCédric Le Goater                             PNV10_XIVE2_NVPG_BASE(chip), &error_fatal);
1916da71b7e3SCédric Le Goater     object_property_set_int(OBJECT(&chip10->xive), "nvc-bar",
1917da71b7e3SCédric Le Goater                             PNV10_XIVE2_NVC_BASE(chip), &error_fatal);
1918da71b7e3SCédric Le Goater     object_property_set_int(OBJECT(&chip10->xive), "tm-bar",
1919da71b7e3SCédric Le Goater                             PNV10_XIVE2_TM_BASE(chip), &error_fatal);
1920da71b7e3SCédric Le Goater     object_property_set_link(OBJECT(&chip10->xive), "chip", OBJECT(chip),
1921da71b7e3SCédric Le Goater                              &error_abort);
1922da71b7e3SCédric Le Goater     if (!sysbus_realize(SYS_BUS_DEVICE(&chip10->xive), errp)) {
1923da71b7e3SCédric Le Goater         return;
1924da71b7e3SCédric Le Goater     }
1925da71b7e3SCédric Le Goater     pnv_xscom_add_subregion(chip, PNV10_XSCOM_XIVE2_BASE,
1926da71b7e3SCédric Le Goater                             &chip10->xive.xscom_regs);
1927da71b7e3SCédric Le Goater 
19288b50ce85SCédric Le Goater     /* Processor Service Interface (PSI) Host Bridge */
19295325cc34SMarkus Armbruster     object_property_set_int(OBJECT(&chip10->psi), "bar",
19305325cc34SMarkus Armbruster                             PNV10_PSIHB_BASE(chip), &error_fatal);
193124c8fa96SCédric Le Goater     /* PSI can now be configured to use 64k ESB pages on POWER10 */
193224c8fa96SCédric Le Goater     object_property_set_int(OBJECT(&chip10->psi), "shift", XIVE_ESB_64K,
193324c8fa96SCédric Le Goater                             &error_fatal);
1934668f62ecSMarkus Armbruster     if (!qdev_realize(DEVICE(&chip10->psi), NULL, errp)) {
19358b50ce85SCédric Le Goater         return;
19368b50ce85SCédric Le Goater     }
19378b50ce85SCédric Le Goater     pnv_xscom_add_subregion(chip, PNV10_XSCOM_PSIHB_BASE,
19388b50ce85SCédric Le Goater                             &PNV_PSI(&chip10->psi)->xscom_regs);
19392661f6abSCédric Le Goater 
19402661f6abSCédric Le Goater     /* LPC */
1941668f62ecSMarkus Armbruster     if (!qdev_realize(DEVICE(&chip10->lpc), NULL, errp)) {
19422661f6abSCédric Le Goater         return;
19432661f6abSCédric Le Goater     }
19442661f6abSCédric Le Goater     memory_region_add_subregion(get_system_memory(), PNV10_LPCM_BASE(chip),
19452661f6abSCédric Le Goater                                 &chip10->lpc.xscom_regs);
19462661f6abSCédric Le Goater 
1947032c226bSCédric Le Goater     chip->fw_mr = &chip10->lpc.isa_fw;
19482661f6abSCédric Le Goater     chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
19492661f6abSCédric Le Goater                                             (uint64_t) PNV10_LPCM_BASE(chip));
19508bf682a3SCédric Le Goater 
1951de3ba0ccSNicholas Piggin     /* ChipTOD */
1952de3ba0ccSNicholas Piggin     object_property_set_bool(OBJECT(&chip10->chiptod), "primary",
1953de3ba0ccSNicholas Piggin                              chip->chip_id == 0, &error_abort);
1954de3ba0ccSNicholas Piggin     object_property_set_bool(OBJECT(&chip10->chiptod), "secondary",
1955de3ba0ccSNicholas Piggin                              chip->chip_id == 1, &error_abort);
1956de3ba0ccSNicholas Piggin     object_property_set_link(OBJECT(&chip10->chiptod), "chip", OBJECT(chip),
1957de3ba0ccSNicholas Piggin                              &error_abort);
1958de3ba0ccSNicholas Piggin     if (!qdev_realize(DEVICE(&chip10->chiptod), NULL, errp)) {
1959de3ba0ccSNicholas Piggin         return;
1960de3ba0ccSNicholas Piggin     }
1961de3ba0ccSNicholas Piggin     pnv_xscom_add_subregion(chip, PNV10_XSCOM_CHIPTOD_BASE,
1962de3ba0ccSNicholas Piggin                             &chip10->chiptod.xscom_regs);
1963de3ba0ccSNicholas Piggin 
19648bf682a3SCédric Le Goater     /* Create the simplified OCC model */
19658bf682a3SCédric Le Goater     if (!qdev_realize(DEVICE(&chip10->occ), NULL, errp)) {
19668bf682a3SCédric Le Goater         return;
19678bf682a3SCédric Le Goater     }
19688bf682a3SCédric Le Goater     pnv_xscom_add_subregion(chip, PNV10_XSCOM_OCC_BASE,
19698bf682a3SCédric Le Goater                             &chip10->occ.xscom_regs);
1970b0ae5c69SCédric Le Goater     qdev_connect_gpio_out(DEVICE(&chip10->occ), 0, qdev_get_gpio_in(
1971b0ae5c69SCédric Le Goater                               DEVICE(&chip10->psi), PSIHB9_IRQ_OCC));
1972623575e1SCédric Le Goater 
197392499676SCédric Le Goater     /* OCC SRAM model */
197492499676SCédric Le Goater     memory_region_add_subregion(get_system_memory(),
197592499676SCédric Le Goater                                 PNV10_OCC_SENSOR_BASE(chip),
197692499676SCédric Le Goater                                 &chip10->occ.sram_regs);
197792499676SCédric Le Goater 
19780bf4d77eSNicholas Piggin     /* SBE */
19790bf4d77eSNicholas Piggin     if (!qdev_realize(DEVICE(&chip10->sbe), NULL, errp)) {
19800bf4d77eSNicholas Piggin         return;
19810bf4d77eSNicholas Piggin     }
19820bf4d77eSNicholas Piggin     pnv_xscom_add_subregion(chip, PNV10_XSCOM_SBE_CTRL_BASE,
19830bf4d77eSNicholas Piggin                             &chip10->sbe.xscom_ctrl_regs);
19840bf4d77eSNicholas Piggin     pnv_xscom_add_subregion(chip, PNV10_XSCOM_SBE_MBOX_BASE,
19850bf4d77eSNicholas Piggin                             &chip10->sbe.xscom_mbox_regs);
19860bf4d77eSNicholas Piggin     qdev_connect_gpio_out(DEVICE(&chip10->sbe), 0, qdev_get_gpio_in(
19870bf4d77eSNicholas Piggin                               DEVICE(&chip10->psi), PSIHB9_IRQ_PSU));
19880bf4d77eSNicholas Piggin 
198992499676SCédric Le Goater     /* HOMER */
199092499676SCédric Le Goater     object_property_set_link(OBJECT(&chip10->homer), "chip", OBJECT(chip),
199192499676SCédric Le Goater                              &error_abort);
199292499676SCédric Le Goater     if (!qdev_realize(DEVICE(&chip10->homer), NULL, errp)) {
199392499676SCédric Le Goater         return;
199492499676SCédric Le Goater     }
199592499676SCédric Le Goater     /* Homer Xscom region */
199692499676SCédric Le Goater     pnv_xscom_add_subregion(chip, PNV10_XSCOM_PBA_BASE,
199792499676SCédric Le Goater                             &chip10->homer.pba_regs);
199892499676SCédric Le Goater 
199992499676SCédric Le Goater     /* Homer mmio region */
200092499676SCédric Le Goater     memory_region_add_subregion(get_system_memory(), PNV10_HOMER_BASE(chip),
200192499676SCédric Le Goater                                 &chip10->homer.regs);
200292499676SCédric Le Goater 
2003c295d3b0SChalapathi V     /* N1 chiplet */
2004c295d3b0SChalapathi V     if (!qdev_realize(DEVICE(&chip10->n1_chiplet), NULL, errp)) {
2005c295d3b0SChalapathi V         return;
2006c295d3b0SChalapathi V     }
2007c295d3b0SChalapathi V     pnv_xscom_add_subregion(chip, PNV10_XSCOM_N1_CHIPLET_CTRL_REGS_BASE,
2008c295d3b0SChalapathi V              &chip10->n1_chiplet.nest_pervasive.xscom_ctrl_regs_mr);
2009c295d3b0SChalapathi V 
2010c295d3b0SChalapathi V     pnv_xscom_add_subregion(chip, PNV10_XSCOM_N1_PB_SCOM_EQ_BASE,
2011c295d3b0SChalapathi V                            &chip10->n1_chiplet.xscom_pb_eq_mr);
2012c295d3b0SChalapathi V 
2013c295d3b0SChalapathi V     pnv_xscom_add_subregion(chip, PNV10_XSCOM_N1_PB_SCOM_ES_BASE,
2014c295d3b0SChalapathi V                            &chip10->n1_chiplet.xscom_pb_es_mr);
2015c295d3b0SChalapathi V 
2016623575e1SCédric Le Goater     /* PHBs */
2017623575e1SCédric Le Goater     pnv_chip_power10_phb_realize(chip, &local_err);
2018623575e1SCédric Le Goater     if (local_err) {
2019623575e1SCédric Le Goater         error_propagate(errp, local_err);
2020623575e1SCédric Le Goater         return;
2021623575e1SCédric Le Goater     }
20221ceda19cSGlenn Miles 
20231ceda19cSGlenn Miles 
20241ceda19cSGlenn Miles     /*
20251ceda19cSGlenn Miles      * I2C
20261ceda19cSGlenn Miles      */
20271ceda19cSGlenn Miles     for (i = 0; i < pcc->i2c_num_engines; i++) {
20281ceda19cSGlenn Miles         Object *obj =  OBJECT(&chip10->i2c[i]);
20291ceda19cSGlenn Miles 
20301ceda19cSGlenn Miles         object_property_set_int(obj, "engine", i + 1, &error_fatal);
20310d1dcb0bSGlenn Miles         object_property_set_int(obj, "num-busses",
20320d1dcb0bSGlenn Miles                                 pcc->i2c_ports_per_engine[i],
20331ceda19cSGlenn Miles                                 &error_fatal);
20341ceda19cSGlenn Miles         object_property_set_link(obj, "chip", OBJECT(chip), &error_abort);
20351ceda19cSGlenn Miles         if (!qdev_realize(DEVICE(obj), NULL, errp)) {
20361ceda19cSGlenn Miles             return;
20371ceda19cSGlenn Miles         }
20381ceda19cSGlenn Miles         pnv_xscom_add_subregion(chip, PNV10_XSCOM_I2CM_BASE +
203947dfdd23SGlenn Miles                                 (chip10->i2c[i].engine - 1) *
204047dfdd23SGlenn Miles                                         PNV10_XSCOM_I2CM_SIZE,
20411ceda19cSGlenn Miles                                 &chip10->i2c[i].xscom_regs);
20421ceda19cSGlenn Miles         qdev_connect_gpio_out(DEVICE(&chip10->i2c[i]), 0,
20431ceda19cSGlenn Miles                               qdev_get_gpio_in(DEVICE(&chip10->psi),
20441ceda19cSGlenn Miles                                                PSIHB9_IRQ_SBE_I2C));
20451ceda19cSGlenn Miles     }
204633467ecbSGlenn Miles 
204733467ecbSGlenn Miles }
204833467ecbSGlenn Miles 
pnv_rainier_i2c_init(PnvMachineState * pnv)204933467ecbSGlenn Miles static void pnv_rainier_i2c_init(PnvMachineState *pnv)
205033467ecbSGlenn Miles {
205133467ecbSGlenn Miles     int i;
205233467ecbSGlenn Miles     for (i = 0; i < pnv->num_chips; i++) {
205333467ecbSGlenn Miles         Pnv10Chip *chip10 = PNV10_CHIP(pnv->chips[i]);
205433467ecbSGlenn Miles 
205533467ecbSGlenn Miles         /*
205633467ecbSGlenn Miles          * Add a PCA9552 I2C device for PCIe hotplug control
205733467ecbSGlenn Miles          * to engine 2, bus 1, address 0x63
205833467ecbSGlenn Miles          */
20596f86885aSGlenn Miles         I2CSlave *dev = i2c_slave_create_simple(chip10->i2c[2].busses[1],
20606f86885aSGlenn Miles                                                 "pca9552", 0x63);
20616f86885aSGlenn Miles 
20626f86885aSGlenn Miles         /*
20636f86885aSGlenn Miles          * Connect PCA9552 GPIO pins 0-4 (SLOTx_EN) outputs to GPIO pins 5-9
20646f86885aSGlenn Miles          * (SLOTx_PG) inputs in order to fake the pgood state of PCIe slots
20656f86885aSGlenn Miles          * after hypervisor code sets a SLOTx_EN pin high.
20666f86885aSGlenn Miles          */
20676f86885aSGlenn Miles         qdev_connect_gpio_out(DEVICE(dev), 0, qdev_get_gpio_in(DEVICE(dev), 5));
20686f86885aSGlenn Miles         qdev_connect_gpio_out(DEVICE(dev), 1, qdev_get_gpio_in(DEVICE(dev), 6));
20696f86885aSGlenn Miles         qdev_connect_gpio_out(DEVICE(dev), 2, qdev_get_gpio_in(DEVICE(dev), 7));
20706f86885aSGlenn Miles         qdev_connect_gpio_out(DEVICE(dev), 3, qdev_get_gpio_in(DEVICE(dev), 8));
20716f86885aSGlenn Miles         qdev_connect_gpio_out(DEVICE(dev), 4, qdev_get_gpio_in(DEVICE(dev), 9));
20726aa4ef32SGlenn Miles 
20736aa4ef32SGlenn Miles         /*
20746aa4ef32SGlenn Miles          * Add a PCA9554 I2C device for cable card presence detection
20756aa4ef32SGlenn Miles          * to engine 2, bus 1, address 0x25
20766aa4ef32SGlenn Miles          */
20776aa4ef32SGlenn Miles         i2c_slave_create_simple(chip10->i2c[2].busses[1], "pca9554", 0x25);
207833467ecbSGlenn Miles     }
20792b548a42SCédric Le Goater }
20802b548a42SCédric Le Goater 
pnv_chip_power10_xscom_pcba(PnvChip * chip,uint64_t addr)208170c059e9SGreg Kurz static uint32_t pnv_chip_power10_xscom_pcba(PnvChip *chip, uint64_t addr)
208270c059e9SGreg Kurz {
208370c059e9SGreg Kurz     addr &= (PNV10_XSCOM_SIZE - 1);
208470c059e9SGreg Kurz     return addr >> 3;
208570c059e9SGreg Kurz }
208670c059e9SGreg Kurz 
pnv_chip_power10_class_init(ObjectClass * klass,void * data)20872b548a42SCédric Le Goater static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
20882b548a42SCédric Le Goater {
20892b548a42SCédric Le Goater     DeviceClass *dc = DEVICE_CLASS(klass);
20902b548a42SCédric Le Goater     PnvChipClass *k = PNV_CHIP_CLASS(klass);
20910d1dcb0bSGlenn Miles     static const int i2c_ports_per_engine[PNV10_CHIP_MAX_I2C] = {14, 14, 2, 16};
20922b548a42SCédric Le Goater 
20932b548a42SCédric Le Goater     k->chip_cfam_id = 0x120da04900008000ull; /* P10 DD1.0 (with NX) */
20942b548a42SCédric Le Goater     k->cores_mask = POWER10_CORE_MASK;
20959940412aSCaleb Schlossin     k->chip_pir = pnv_chip_pir_p10;
20962b548a42SCédric Le Goater     k->intc_create = pnv_chip_power10_intc_create;
20972b548a42SCédric Le Goater     k->intc_reset = pnv_chip_power10_intc_reset;
20982b548a42SCédric Le Goater     k->intc_destroy = pnv_chip_power10_intc_destroy;
209985913070SGreg Kurz     k->intc_print_info = pnv_chip_power10_intc_print_info;
21002b548a42SCédric Le Goater     k->isa_create = pnv_chip_power10_isa_create;
21012b548a42SCédric Le Goater     k->dt_populate = pnv_chip_power10_dt_populate;
21022b548a42SCédric Le Goater     k->pic_print_info = pnv_chip_power10_pic_print_info;
2103c4b2c40cSGreg Kurz     k->xscom_core_base = pnv_chip_power10_xscom_core_base;
210470c059e9SGreg Kurz     k->xscom_pcba = pnv_chip_power10_xscom_pcba;
21052b548a42SCédric Le Goater     dc->desc = "PowerNV Chip POWER10";
2106623575e1SCédric Le Goater     k->num_pecs = PNV10_CHIP_MAX_PEC;
21071ceda19cSGlenn Miles     k->i2c_num_engines = PNV10_CHIP_MAX_I2C;
21080d1dcb0bSGlenn Miles     k->i2c_ports_per_engine = i2c_ports_per_engine;
21092b548a42SCédric Le Goater 
21102b548a42SCédric Le Goater     device_class_set_parent_realize(dc, pnv_chip_power10_realize,
21112b548a42SCédric Le Goater                                     &k->parent_realize);
21122b548a42SCédric Le Goater }
21132b548a42SCédric Le Goater 
pnv_chip_core_sanitize(PnvChip * chip,Error ** errp)2114397a79e7SCédric Le Goater static void pnv_chip_core_sanitize(PnvChip *chip, Error **errp)
2115397a79e7SCédric Le Goater {
2116397a79e7SCédric Le Goater     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
2117397a79e7SCédric Le Goater     int cores_max;
2118397a79e7SCédric Le Goater 
2119397a79e7SCédric Le Goater     /*
2120397a79e7SCédric Le Goater      * No custom mask for this chip, let's use the default one from *
2121397a79e7SCédric Le Goater      * the chip class
2122397a79e7SCédric Le Goater      */
2123397a79e7SCédric Le Goater     if (!chip->cores_mask) {
2124397a79e7SCédric Le Goater         chip->cores_mask = pcc->cores_mask;
2125397a79e7SCédric Le Goater     }
2126397a79e7SCédric Le Goater 
2127397a79e7SCédric Le Goater     /* filter alien core ids ! some are reserved */
2128397a79e7SCédric Le Goater     if ((chip->cores_mask & pcc->cores_mask) != chip->cores_mask) {
2129397a79e7SCédric Le Goater         error_setg(errp, "warning: invalid core mask for chip Ox%"PRIx64" !",
2130397a79e7SCédric Le Goater                    chip->cores_mask);
2131397a79e7SCédric Le Goater         return;
2132397a79e7SCédric Le Goater     }
2133397a79e7SCédric Le Goater     chip->cores_mask &= pcc->cores_mask;
2134397a79e7SCédric Le Goater 
2135397a79e7SCédric Le Goater     /* now that we have a sane layout, let check the number of cores */
213627d9ffd4SDavid Gibson     cores_max = ctpop64(chip->cores_mask);
2137397a79e7SCédric Le Goater     if (chip->nr_cores > cores_max) {
2138397a79e7SCédric Le Goater         error_setg(errp, "warning: too many cores for chip ! Limit is %d",
2139397a79e7SCédric Le Goater                    cores_max);
2140397a79e7SCédric Le Goater         return;
2141397a79e7SCédric Le Goater     }
2142397a79e7SCédric Le Goater }
2143397a79e7SCédric Le Goater 
pnv_chip_core_realize(PnvChip * chip,Error ** errp)214451c04728SCédric Le Goater static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
2145e997040eSCédric Le Goater {
2146397a79e7SCédric Le Goater     Error *error = NULL;
2147d2fd9612SCédric Le Goater     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
214840abf43fSIgor Mammedov     const char *typename = pnv_chip_core_typename(chip);
2149d2fd9612SCédric Le Goater     int i, core_hwid;
215008c3f3a7SCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
2151397a79e7SCédric Le Goater 
2152d2fd9612SCédric Le Goater     if (!object_class_by_name(typename)) {
2153d2fd9612SCédric Le Goater         error_setg(errp, "Unable to find PowerNV CPU Core '%s'", typename);
2154d2fd9612SCédric Le Goater         return;
2155d2fd9612SCédric Le Goater     }
2156d2fd9612SCédric Le Goater 
2157d2fd9612SCédric Le Goater     /* Cores */
2158397a79e7SCédric Le Goater     pnv_chip_core_sanitize(chip, &error);
2159397a79e7SCédric Le Goater     if (error) {
2160397a79e7SCédric Le Goater         error_propagate(errp, error);
2161397a79e7SCédric Le Goater         return;
2162397a79e7SCédric Le Goater     }
2163d2fd9612SCédric Le Goater 
21644fa28f23SGreg Kurz     chip->cores = g_new0(PnvCore *, chip->nr_cores);
2165d2fd9612SCédric Le Goater 
2166d2fd9612SCédric Le Goater     for (i = 0, core_hwid = 0; (core_hwid < sizeof(chip->cores_mask) * 8)
2167d2fd9612SCédric Le Goater              && (i < chip->nr_cores); core_hwid++) {
2168d2fd9612SCédric Le Goater         char core_name[32];
21694fa28f23SGreg Kurz         PnvCore *pnv_core;
2170c035851aSCédric Le Goater         uint64_t xscom_core_base;
2171d2fd9612SCédric Le Goater 
2172d2fd9612SCédric Le Goater         if (!(chip->cores_mask & (1ull << core_hwid))) {
2173d2fd9612SCédric Le Goater             continue;
2174d2fd9612SCédric Le Goater         }
2175d2fd9612SCédric Le Goater 
21764fa28f23SGreg Kurz         pnv_core = PNV_CORE(object_new(typename));
21774fa28f23SGreg Kurz 
2178d2fd9612SCédric Le Goater         snprintf(core_name, sizeof(core_name), "core[%d]", core_hwid);
2179d2623129SMarkus Armbruster         object_property_add_child(OBJECT(chip), core_name, OBJECT(pnv_core));
21804fa28f23SGreg Kurz         chip->cores[i] = pnv_core;
21815325cc34SMarkus Armbruster         object_property_set_int(OBJECT(pnv_core), "nr-threads",
21825325cc34SMarkus Armbruster                                 chip->nr_threads, &error_fatal);
21835325cc34SMarkus Armbruster         object_property_set_int(OBJECT(pnv_core), CPU_CORE_PROP_CORE_ID,
21845325cc34SMarkus Armbruster                                 core_hwid, &error_fatal);
21859940412aSCaleb Schlossin         object_property_set_int(OBJECT(pnv_core), "hwid", core_hwid,
21869940412aSCaleb Schlossin                                 &error_fatal);
21875325cc34SMarkus Armbruster         object_property_set_int(OBJECT(pnv_core), "hrmor", pnv->fw_load_addr,
21885325cc34SMarkus Armbruster                                 &error_fatal);
21895325cc34SMarkus Armbruster         object_property_set_link(OBJECT(pnv_core), "chip", OBJECT(chip),
2190158e17a6SGreg Kurz                                  &error_abort);
2191ce189ab2SMarkus Armbruster         qdev_realize(DEVICE(pnv_core), NULL, &error_fatal);
219224ece072SCédric Le Goater 
219324ece072SCédric Le Goater         /* Each core has an XSCOM MMIO region */
2194c4b2c40cSGreg Kurz         xscom_core_base = pcc->xscom_core_base(chip, core_hwid);
2195c035851aSCédric Le Goater 
2196c035851aSCédric Le Goater         pnv_xscom_add_subregion(chip, xscom_core_base,
21974fa28f23SGreg Kurz                                 &pnv_core->xscom_regs);
2198d2fd9612SCédric Le Goater         i++;
2199d2fd9612SCédric Le Goater     }
220051c04728SCédric Le Goater }
220151c04728SCédric Le Goater 
pnv_chip_realize(DeviceState * dev,Error ** errp)220251c04728SCédric Le Goater static void pnv_chip_realize(DeviceState *dev, Error **errp)
220351c04728SCédric Le Goater {
220451c04728SCédric Le Goater     PnvChip *chip = PNV_CHIP(dev);
220551c04728SCédric Le Goater     Error *error = NULL;
220651c04728SCédric Le Goater 
220751c04728SCédric Le Goater     /* Cores */
220851c04728SCédric Le Goater     pnv_chip_core_realize(chip, &error);
220951c04728SCédric Le Goater     if (error) {
221051c04728SCédric Le Goater         error_propagate(errp, error);
221151c04728SCédric Le Goater         return;
221251c04728SCédric Le Goater     }
2213e997040eSCédric Le Goater }
2214e997040eSCédric Le Goater 
2215e997040eSCédric Le Goater static Property pnv_chip_properties[] = {
2216e997040eSCédric Le Goater     DEFINE_PROP_UINT32("chip-id", PnvChip, chip_id, 0),
2217e997040eSCédric Le Goater     DEFINE_PROP_UINT64("ram-start", PnvChip, ram_start, 0),
2218e997040eSCédric Le Goater     DEFINE_PROP_UINT64("ram-size", PnvChip, ram_size, 0),
2219397a79e7SCédric Le Goater     DEFINE_PROP_UINT32("nr-cores", PnvChip, nr_cores, 1),
2220397a79e7SCédric Le Goater     DEFINE_PROP_UINT64("cores-mask", PnvChip, cores_mask, 0x0),
2221764f9b25SGreg Kurz     DEFINE_PROP_UINT32("nr-threads", PnvChip, nr_threads, 1),
2222e997040eSCédric Le Goater     DEFINE_PROP_END_OF_LIST(),
2223e997040eSCédric Le Goater };
2224e997040eSCédric Le Goater 
pnv_chip_class_init(ObjectClass * klass,void * data)2225e997040eSCédric Le Goater static void pnv_chip_class_init(ObjectClass *klass, void *data)
2226e997040eSCédric Le Goater {
2227e997040eSCédric Le Goater     DeviceClass *dc = DEVICE_CLASS(klass);
2228e997040eSCédric Le Goater 
22299d169fb3SThomas Huth     set_bit(DEVICE_CATEGORY_CPU, dc->categories);
2230e997040eSCédric Le Goater     dc->realize = pnv_chip_realize;
22314f67d30bSMarc-André Lureau     device_class_set_props(dc, pnv_chip_properties);
2232e997040eSCédric Le Goater     dc->desc = "PowerNV Chip";
2233e997040eSCédric Le Goater }
2234e997040eSCédric Le Goater 
pnv_chip_find_core(PnvChip * chip,uint32_t core_id)2235cde2ba34SNicholas Piggin PnvCore *pnv_chip_find_core(PnvChip *chip, uint32_t core_id)
2236cde2ba34SNicholas Piggin {
2237cde2ba34SNicholas Piggin     int i;
2238cde2ba34SNicholas Piggin 
2239cde2ba34SNicholas Piggin     for (i = 0; i < chip->nr_cores; i++) {
2240cde2ba34SNicholas Piggin         PnvCore *pc = chip->cores[i];
2241cde2ba34SNicholas Piggin         CPUCore *cc = CPU_CORE(pc);
2242cde2ba34SNicholas Piggin 
2243cde2ba34SNicholas Piggin         if (cc->core_id == core_id) {
2244cde2ba34SNicholas Piggin             return pc;
2245cde2ba34SNicholas Piggin         }
2246cde2ba34SNicholas Piggin     }
2247cde2ba34SNicholas Piggin     return NULL;
2248cde2ba34SNicholas Piggin }
2249cde2ba34SNicholas Piggin 
pnv_chip_find_cpu(PnvChip * chip,uint32_t pir)2250119eaa9dSCédric Le Goater PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir)
2251119eaa9dSCédric Le Goater {
2252119eaa9dSCédric Le Goater     int i, j;
2253119eaa9dSCédric Le Goater 
2254119eaa9dSCédric Le Goater     for (i = 0; i < chip->nr_cores; i++) {
2255119eaa9dSCédric Le Goater         PnvCore *pc = chip->cores[i];
2256119eaa9dSCédric Le Goater         CPUCore *cc = CPU_CORE(pc);
2257119eaa9dSCédric Le Goater 
2258119eaa9dSCédric Le Goater         for (j = 0; j < cc->nr_threads; j++) {
2259119eaa9dSCédric Le Goater             if (ppc_cpu_pir(pc->threads[j]) == pir) {
2260119eaa9dSCédric Le Goater                 return pc->threads[j];
2261119eaa9dSCédric Le Goater             }
2262119eaa9dSCédric Le Goater         }
2263119eaa9dSCédric Le Goater     }
2264119eaa9dSCédric Le Goater     return NULL;
2265119eaa9dSCédric Le Goater }
2266119eaa9dSCédric Le Goater 
pnv_ics_get(XICSFabric * xi,int irq)226754f59d78SCédric Le Goater static ICSState *pnv_ics_get(XICSFabric *xi, int irq)
226854f59d78SCédric Le Goater {
2269b168a138SCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(xi);
2270da6be501SDaniel Henrique Barboza     int i, j;
227154f59d78SCédric Le Goater 
227254f59d78SCédric Le Goater     for (i = 0; i < pnv->num_chips; i++) {
227377864267SCédric Le Goater         Pnv8Chip *chip8 = PNV8_CHIP(pnv->chips[i]);
227477864267SCédric Le Goater 
227577864267SCédric Le Goater         if (ics_valid_irq(&chip8->psi.ics, irq)) {
227677864267SCédric Le Goater             return &chip8->psi.ics;
227754f59d78SCédric Le Goater         }
22782ff73ddaSCédric Le Goater 
2279da6be501SDaniel Henrique Barboza         for (j = 0; j < chip8->num_phbs; j++) {
22800d512c71SDaniel Henrique Barboza             PnvPHB *phb = chip8->phbs[j];
22811f5d6b2aSDaniel Henrique Barboza             PnvPHB3 *phb3 = PNV_PHB3(phb->backend);
2282da6be501SDaniel Henrique Barboza 
2283da6be501SDaniel Henrique Barboza             if (ics_valid_irq(&phb3->lsis, irq)) {
2284da6be501SDaniel Henrique Barboza                 return &phb3->lsis;
2285da6be501SDaniel Henrique Barboza             }
2286da6be501SDaniel Henrique Barboza 
2287da6be501SDaniel Henrique Barboza             if (ics_valid_irq(ICS(&phb3->msis), irq)) {
2288da6be501SDaniel Henrique Barboza                 return ICS(&phb3->msis);
2289da6be501SDaniel Henrique Barboza             }
22909ae1329eSCédric Le Goater         }
229154f59d78SCédric Le Goater     }
229254f59d78SCédric Le Goater     return NULL;
229354f59d78SCédric Le Goater }
229454f59d78SCédric Le Goater 
pnv_get_chip(PnvMachineState * pnv,uint32_t chip_id)22951f6a88ffSCédric Le Goater PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id)
22961f6a88ffSCédric Le Goater {
22971f6a88ffSCédric Le Goater     int i;
22981f6a88ffSCédric Le Goater 
22991f6a88ffSCédric Le Goater     for (i = 0; i < pnv->num_chips; i++) {
23001f6a88ffSCédric Le Goater         PnvChip *chip = pnv->chips[i];
23011f6a88ffSCédric Le Goater         if (chip->chip_id == chip_id) {
23021f6a88ffSCédric Le Goater             return chip;
23031f6a88ffSCédric Le Goater         }
23041f6a88ffSCédric Le Goater     }
23051f6a88ffSCédric Le Goater     return NULL;
23061f6a88ffSCédric Le Goater }
23071f6a88ffSCédric Le Goater 
pnv_ics_resend(XICSFabric * xi)230854f59d78SCédric Le Goater static void pnv_ics_resend(XICSFabric *xi)
230954f59d78SCédric Le Goater {
2310b168a138SCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(xi);
2311ca459489SDaniel Henrique Barboza     int i, j;
231254f59d78SCédric Le Goater 
231354f59d78SCédric Le Goater     for (i = 0; i < pnv->num_chips; i++) {
231477864267SCédric Le Goater         Pnv8Chip *chip8 = PNV8_CHIP(pnv->chips[i]);
23159ae1329eSCédric Le Goater 
231677864267SCédric Le Goater         ics_resend(&chip8->psi.ics);
2317ca459489SDaniel Henrique Barboza 
2318ca459489SDaniel Henrique Barboza         for (j = 0; j < chip8->num_phbs; j++) {
23190d512c71SDaniel Henrique Barboza             PnvPHB *phb = chip8->phbs[j];
23201f5d6b2aSDaniel Henrique Barboza             PnvPHB3 *phb3 = PNV_PHB3(phb->backend);
2321ca459489SDaniel Henrique Barboza 
2322ca459489SDaniel Henrique Barboza             ics_resend(&phb3->lsis);
2323ca459489SDaniel Henrique Barboza             ics_resend(ICS(&phb3->msis));
2324ca459489SDaniel Henrique Barboza         }
232554f59d78SCédric Le Goater     }
232654f59d78SCédric Le Goater }
232754f59d78SCédric Le Goater 
pnv_icp_get(XICSFabric * xi,int pir)232836fc6f08SCédric Le Goater static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
232936fc6f08SCédric Le Goater {
233036fc6f08SCédric Le Goater     PowerPCCPU *cpu = ppc_get_vcpu_by_pir(pir);
233136fc6f08SCédric Le Goater 
2332956b8f46SCédric Le Goater     return cpu ? ICP(pnv_cpu_state(cpu)->intc) : NULL;
233336fc6f08SCédric Le Goater }
233436fc6f08SCédric Le Goater 
pnv_pic_print_info(InterruptStatsProvider * obj,Monitor * mon)233547fea43aSCédric Le Goater static void pnv_pic_print_info(InterruptStatsProvider *obj,
233647fea43aSCédric Le Goater                                Monitor *mon)
233747fea43aSCédric Le Goater {
2338b168a138SCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(obj);
233954f59d78SCédric Le Goater     int i;
234047fea43aSCédric Le Goater     CPUState *cs;
234147fea43aSCédric Le Goater 
234247fea43aSCédric Le Goater     CPU_FOREACH(cs) {
234347fea43aSCédric Le Goater         PowerPCCPU *cpu = POWERPC_CPU(cs);
234447fea43aSCédric Le Goater 
234585913070SGreg Kurz         /* XXX: loop on each chip/core/thread instead of CPU_FOREACH() */
234685913070SGreg Kurz         PNV_CHIP_GET_CLASS(pnv->chips[0])->intc_print_info(pnv->chips[0], cpu,
234785913070SGreg Kurz                                                            mon);
2348d8e4aad5SCédric Le Goater     }
234954f59d78SCédric Le Goater 
235054f59d78SCédric Le Goater     for (i = 0; i < pnv->num_chips; i++) {
2351d8e4aad5SCédric Le Goater         PNV_CHIP_GET_CLASS(pnv->chips[i])->pic_print_info(pnv->chips[i], mon);
235254f59d78SCédric Le Goater     }
235347fea43aSCédric Le Goater }
235447fea43aSCédric Le Goater 
pnv_match_nvt(XiveFabric * xfb,uint8_t format,uint8_t nvt_blk,uint32_t nvt_idx,bool cam_ignore,uint8_t priority,uint32_t logic_serv,XiveTCTXMatch * match)2355c722579eSCédric Le Goater static int pnv_match_nvt(XiveFabric *xfb, uint8_t format,
2356c722579eSCédric Le Goater                          uint8_t nvt_blk, uint32_t nvt_idx,
2357c722579eSCédric Le Goater                          bool cam_ignore, uint8_t priority,
2358c722579eSCédric Le Goater                          uint32_t logic_serv,
2359c722579eSCédric Le Goater                          XiveTCTXMatch *match)
2360c722579eSCédric Le Goater {
2361c722579eSCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(xfb);
2362c722579eSCédric Le Goater     int total_count = 0;
2363c722579eSCédric Le Goater     int i;
2364c722579eSCédric Le Goater 
2365c722579eSCédric Le Goater     for (i = 0; i < pnv->num_chips; i++) {
2366c722579eSCédric Le Goater         Pnv9Chip *chip9 = PNV9_CHIP(pnv->chips[i]);
2367c722579eSCédric Le Goater         XivePresenter *xptr = XIVE_PRESENTER(&chip9->xive);
2368c722579eSCédric Le Goater         XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
2369c722579eSCédric Le Goater         int count;
2370c722579eSCédric Le Goater 
2371c722579eSCédric Le Goater         count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
2372c722579eSCédric Le Goater                                priority, logic_serv, match);
2373c722579eSCédric Le Goater 
2374c722579eSCédric Le Goater         if (count < 0) {
2375c722579eSCédric Le Goater             return count;
2376c722579eSCédric Le Goater         }
2377c722579eSCédric Le Goater 
2378c722579eSCédric Le Goater         total_count += count;
2379c722579eSCédric Le Goater     }
2380c722579eSCédric Le Goater 
2381c722579eSCédric Le Goater     return total_count;
2382c722579eSCédric Le Goater }
2383c722579eSCédric Le Goater 
pnv10_xive_match_nvt(XiveFabric * xfb,uint8_t format,uint8_t nvt_blk,uint32_t nvt_idx,bool cam_ignore,uint8_t priority,uint32_t logic_serv,XiveTCTXMatch * match)2384da71b7e3SCédric Le Goater static int pnv10_xive_match_nvt(XiveFabric *xfb, uint8_t format,
2385da71b7e3SCédric Le Goater                                 uint8_t nvt_blk, uint32_t nvt_idx,
2386da71b7e3SCédric Le Goater                                 bool cam_ignore, uint8_t priority,
2387da71b7e3SCédric Le Goater                                 uint32_t logic_serv,
2388da71b7e3SCédric Le Goater                                 XiveTCTXMatch *match)
2389da71b7e3SCédric Le Goater {
2390da71b7e3SCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(xfb);
2391da71b7e3SCédric Le Goater     int total_count = 0;
2392da71b7e3SCédric Le Goater     int i;
2393da71b7e3SCédric Le Goater 
2394da71b7e3SCédric Le Goater     for (i = 0; i < pnv->num_chips; i++) {
2395da71b7e3SCédric Le Goater         Pnv10Chip *chip10 = PNV10_CHIP(pnv->chips[i]);
2396da71b7e3SCédric Le Goater         XivePresenter *xptr = XIVE_PRESENTER(&chip10->xive);
2397da71b7e3SCédric Le Goater         XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
2398da71b7e3SCédric Le Goater         int count;
2399da71b7e3SCédric Le Goater 
2400da71b7e3SCédric Le Goater         count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
2401da71b7e3SCédric Le Goater                                priority, logic_serv, match);
2402da71b7e3SCédric Le Goater 
2403da71b7e3SCédric Le Goater         if (count < 0) {
2404da71b7e3SCédric Le Goater             return count;
2405da71b7e3SCédric Le Goater         }
2406da71b7e3SCédric Le Goater 
2407da71b7e3SCédric Le Goater         total_count += count;
2408da71b7e3SCédric Le Goater     }
2409da71b7e3SCédric Le Goater 
2410da71b7e3SCédric Le Goater     return total_count;
2411da71b7e3SCédric Le Goater }
2412da71b7e3SCédric Le Goater 
pnv_machine_power8_class_init(ObjectClass * oc,void * data)2413f30c843cSCédric Le Goater static void pnv_machine_power8_class_init(ObjectClass *oc, void *data)
24149e933f4aSBenjamin Herrenschmidt {
24159e933f4aSBenjamin Herrenschmidt     MachineClass *mc = MACHINE_CLASS(oc);
241636fc6f08SCédric Le Goater     XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
2417d76f2da7SGreg Kurz     PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
2418d76f2da7SGreg Kurz     static const char compat[] = "qemu,powernv8\0qemu,powernv\0ibm,powernv";
2419f30c843cSCédric Le Goater 
24201f5d6b2aSDaniel Henrique Barboza     static GlobalProperty phb_compat[] = {
24211f5d6b2aSDaniel Henrique Barboza         { TYPE_PNV_PHB, "version", "3" },
242280515061SDaniel Henrique Barboza         { TYPE_PNV_PHB_ROOT_PORT, "version", "3" },
24231f5d6b2aSDaniel Henrique Barboza     };
24241f5d6b2aSDaniel Henrique Barboza 
2425f30c843cSCédric Le Goater     mc->desc = "IBM PowerNV (Non-Virtualized) POWER8";
2426f30c843cSCédric Le Goater     mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
24271f5d6b2aSDaniel Henrique Barboza     compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
2428f30c843cSCédric Le Goater 
2429f30c843cSCédric Le Goater     xic->icp_get = pnv_icp_get;
2430f30c843cSCédric Le Goater     xic->ics_get = pnv_ics_get;
2431f30c843cSCédric Le Goater     xic->ics_resend = pnv_ics_resend;
2432d76f2da7SGreg Kurz 
2433d76f2da7SGreg Kurz     pmc->compat = compat;
2434d76f2da7SGreg Kurz     pmc->compat_size = sizeof(compat);
2435892c3ad0SDaniel Henrique Barboza 
2436892c3ad0SDaniel Henrique Barboza     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PNV_PHB);
2437f30c843cSCédric Le Goater }
2438f30c843cSCédric Le Goater 
pnv_machine_power9_class_init(ObjectClass * oc,void * data)2439f30c843cSCédric Le Goater static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)
2440f30c843cSCédric Le Goater {
2441f30c843cSCédric Le Goater     MachineClass *mc = MACHINE_CLASS(oc);
2442c722579eSCédric Le Goater     XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
2443d76f2da7SGreg Kurz     PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
2444d76f2da7SGreg Kurz     static const char compat[] = "qemu,powernv9\0ibm,powernv";
2445f30c843cSCédric Le Goater 
2446210aacb3SDaniel Henrique Barboza     static GlobalProperty phb_compat[] = {
2447210aacb3SDaniel Henrique Barboza         { TYPE_PNV_PHB, "version", "4" },
2448c8d14603SDaniel Henrique Barboza         { TYPE_PNV_PHB_ROOT_PORT, "version", "4" },
2449210aacb3SDaniel Henrique Barboza     };
2450210aacb3SDaniel Henrique Barboza 
2451f30c843cSCédric Le Goater     mc->desc = "IBM PowerNV (Non-Virtualized) POWER9";
2452277ee172SNicholas Piggin     mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.2");
2453210aacb3SDaniel Henrique Barboza     compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
2454210aacb3SDaniel Henrique Barboza 
2455c722579eSCédric Le Goater     xfc->match_nvt = pnv_match_nvt;
2456f30c843cSCédric Le Goater 
2457d76f2da7SGreg Kurz     pmc->compat = compat;
2458d76f2da7SGreg Kurz     pmc->compat_size = sizeof(compat);
24597a90c6a1SGreg Kurz     pmc->dt_power_mgt = pnv_dt_power_mgt;
2460d786be3fSDaniel Henrique Barboza 
2461d786be3fSDaniel Henrique Barboza     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PNV_PHB);
2462f30c843cSCédric Le Goater }
2463f30c843cSCédric Le Goater 
pnv_machine_p10_common_class_init(ObjectClass * oc,void * data)2464ab874668SGlenn Miles static void pnv_machine_p10_common_class_init(ObjectClass *oc, void *data)
24652b548a42SCédric Le Goater {
24662b548a42SCédric Le Goater     MachineClass *mc = MACHINE_CLASS(oc);
2467d76f2da7SGreg Kurz     PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
2468da71b7e3SCédric Le Goater     XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
2469d76f2da7SGreg Kurz     static const char compat[] = "qemu,powernv10\0ibm,powernv";
24702b548a42SCédric Le Goater 
2471210aacb3SDaniel Henrique Barboza     static GlobalProperty phb_compat[] = {
2472210aacb3SDaniel Henrique Barboza         { TYPE_PNV_PHB, "version", "5" },
2473c8d14603SDaniel Henrique Barboza         { TYPE_PNV_PHB_ROOT_PORT, "version", "5" },
2474210aacb3SDaniel Henrique Barboza     };
2475210aacb3SDaniel Henrique Barboza 
24766bc8c046SCédric Le Goater     mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v2.0");
2477210aacb3SDaniel Henrique Barboza     compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
2478d76f2da7SGreg Kurz 
247921465adeSNicholas Piggin     mc->alias = "powernv";
248021465adeSNicholas Piggin 
2481d76f2da7SGreg Kurz     pmc->compat = compat;
2482d76f2da7SGreg Kurz     pmc->compat_size = sizeof(compat);
24837a90c6a1SGreg Kurz     pmc->dt_power_mgt = pnv_dt_power_mgt;
2484da71b7e3SCédric Le Goater 
2485da71b7e3SCédric Le Goater     xfc->match_nvt = pnv10_xive_match_nvt;
2486f1327fdeSDaniel Henrique Barboza 
2487f1327fdeSDaniel Henrique Barboza     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PNV_PHB);
24882b548a42SCédric Le Goater }
24892b548a42SCédric Le Goater 
pnv_machine_power10_class_init(ObjectClass * oc,void * data)2490ab874668SGlenn Miles static void pnv_machine_power10_class_init(ObjectClass *oc, void *data)
2491ab874668SGlenn Miles {
2492ab874668SGlenn Miles     MachineClass *mc = MACHINE_CLASS(oc);
2493ab874668SGlenn Miles 
2494ab874668SGlenn Miles     pnv_machine_p10_common_class_init(oc, data);
2495ab874668SGlenn Miles     mc->desc = "IBM PowerNV (Non-Virtualized) POWER10";
2496ab874668SGlenn Miles }
2497ab874668SGlenn Miles 
pnv_machine_p10_rainier_class_init(ObjectClass * oc,void * data)2498ab874668SGlenn Miles static void pnv_machine_p10_rainier_class_init(ObjectClass *oc, void *data)
2499ab874668SGlenn Miles {
2500ab874668SGlenn Miles     MachineClass *mc = MACHINE_CLASS(oc);
250133467ecbSGlenn Miles     PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
2502ab874668SGlenn Miles 
2503ab874668SGlenn Miles     pnv_machine_p10_common_class_init(oc, data);
2504ab874668SGlenn Miles     mc->desc = "IBM PowerNV (Non-Virtualized) POWER10 Rainier";
250533467ecbSGlenn Miles     pmc->i2c_init = pnv_rainier_i2c_init;
2506ab874668SGlenn Miles }
2507ab874668SGlenn Miles 
pnv_machine_get_hb(Object * obj,Error ** errp)250808c3f3a7SCédric Le Goater static bool pnv_machine_get_hb(Object *obj, Error **errp)
250908c3f3a7SCédric Le Goater {
251008c3f3a7SCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(obj);
251108c3f3a7SCédric Le Goater 
251208c3f3a7SCédric Le Goater     return !!pnv->fw_load_addr;
251308c3f3a7SCédric Le Goater }
251408c3f3a7SCédric Le Goater 
pnv_machine_set_hb(Object * obj,bool value,Error ** errp)251508c3f3a7SCédric Le Goater static void pnv_machine_set_hb(Object *obj, bool value, Error **errp)
251608c3f3a7SCédric Le Goater {
251708c3f3a7SCédric Le Goater     PnvMachineState *pnv = PNV_MACHINE(obj);
251808c3f3a7SCédric Le Goater 
251908c3f3a7SCédric Le Goater     if (value) {
252008c3f3a7SCédric Le Goater         pnv->fw_load_addr = 0x8000000;
252108c3f3a7SCédric Le Goater     }
252208c3f3a7SCédric Le Goater }
252308c3f3a7SCédric Le Goater 
pnv_cpu_do_nmi_on_cpu(CPUState * cs,run_on_cpu_data arg)252401b552b0SNicholas Piggin static void pnv_cpu_do_nmi_on_cpu(CPUState *cs, run_on_cpu_data arg)
252501b552b0SNicholas Piggin {
252601b552b0SNicholas Piggin     CPUPPCState *env = cpu_env(cs);
252701b552b0SNicholas Piggin 
252801b552b0SNicholas Piggin     cpu_synchronize_state(cs);
252901b552b0SNicholas Piggin     ppc_cpu_do_system_reset(cs);
253001b552b0SNicholas Piggin     if (env->spr[SPR_SRR1] & SRR1_WAKESTATE) {
25310911a60cSLeonardo Bras         /*
253201b552b0SNicholas Piggin          * Power-save wakeups, as indicated by non-zero SRR1[46:47] put the
2533fe837714SNicholas Piggin          * wakeup reason in SRR1[42:45], system reset is indicated with 0b0100
2534fe837714SNicholas Piggin          * (PPC_BIT(43)).
2535fe837714SNicholas Piggin          */
253601b552b0SNicholas Piggin         if (!(env->spr[SPR_SRR1] & SRR1_WAKERESET)) {
25370911a60cSLeonardo Bras             warn_report("ppc_cpu_do_system_reset does not set system reset wakeup reason");
2538fe837714SNicholas Piggin             env->spr[SPR_SRR1] |= SRR1_WAKERESET;
25390911a60cSLeonardo Bras         }
254001b552b0SNicholas Piggin     } else {
2541fe837714SNicholas Piggin         /*
2542fe837714SNicholas Piggin          * For non-powersave system resets, SRR1[42:45] are defined to be
2543fe837714SNicholas Piggin          * implementation-dependent. The POWER9 User Manual specifies that
2544fe837714SNicholas Piggin          * an external (SCOM driven, which may come from a BMC nmi command or
2545fe837714SNicholas Piggin          * another CPU requesting a NMI IPI) system reset exception should be
2546fe837714SNicholas Piggin          * 0b0010 (PPC_BIT(44)).
2547fe837714SNicholas Piggin          */
2548fe837714SNicholas Piggin         env->spr[SPR_SRR1] |= SRR1_WAKESCOM;
25490911a60cSLeonardo Bras     }
2550fe837714SNicholas Piggin }
2551fe837714SNicholas Piggin 
pnv_nmi(NMIState * n,int cpu_index,Error ** errp)255201b552b0SNicholas Piggin static void pnv_nmi(NMIState *n, int cpu_index, Error **errp)
255301b552b0SNicholas Piggin {
255401b552b0SNicholas Piggin     CPUState *cs;
255501b552b0SNicholas Piggin 
255601b552b0SNicholas Piggin     CPU_FOREACH(cs) {
255701b552b0SNicholas Piggin         async_run_on_cpu(cs, pnv_cpu_do_nmi_on_cpu, RUN_ON_CPU_NULL);
255801b552b0SNicholas Piggin     }
255901b552b0SNicholas Piggin }
256001b552b0SNicholas Piggin 
pnv_machine_class_init(ObjectClass * oc,void * data)256101b552b0SNicholas Piggin static void pnv_machine_class_init(ObjectClass *oc, void *data)
2562f30c843cSCédric Le Goater {
2563f30c843cSCédric Le Goater     MachineClass *mc = MACHINE_CLASS(oc);
2564f30c843cSCédric Le Goater     InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
256547fea43aSCédric Le Goater     NMIClass *nc = NMI_CLASS(oc);
256601b552b0SNicholas Piggin 
25679e933f4aSBenjamin Herrenschmidt     mc->desc = "IBM PowerNV (Non-Virtualized)";
25689e933f4aSBenjamin Herrenschmidt     mc->init = pnv_init;
2569b168a138SCédric Le Goater     mc->reset = pnv_reset;
2570b168a138SCédric Le Goater     mc->max_cpus = MAX_CPUS;
25719e933f4aSBenjamin Herrenschmidt     /* Pnv provides a AHCI device for storage */
257259b7c1c2SBalamuruhan S     mc->block_default_type = IF_IDE;
257359b7c1c2SBalamuruhan S     mc->no_parallel = 1;
25749e933f4aSBenjamin Herrenschmidt     mc->default_boot_order = NULL;
25759e933f4aSBenjamin Herrenschmidt     /*
2576f1d18b0aSJoel Stanley      * RAM defaults to less than 2048 for 32-bit hosts, and large
2577f1d18b0aSJoel Stanley      * enough to fit the maximum initrd size at it's load address
2578f1d18b0aSJoel Stanley      */
2579f1d18b0aSJoel Stanley     mc->default_ram_size = 1 * GiB;
2580dd7ef911SCédric Le Goater     mc->default_ram_id = "pnv.ram";
2581173a36d8SIgor Mammedov     ispc->print_info = pnv_pic_print_info;
258247fea43aSCédric Le Goater     nc->nmi_monitor_handler = pnv_nmi;
258301b552b0SNicholas Piggin 
258408c3f3a7SCédric Le Goater     object_class_property_add_bool(oc, "hb-mode",
258508c3f3a7SCédric Le Goater                                    pnv_machine_get_hb, pnv_machine_set_hb);
2586d2623129SMarkus Armbruster     object_class_property_set_description(oc, "hb-mode",
258708c3f3a7SCédric Le Goater                               "Use a hostboot like boot loader");
25887eecec7dSMarkus Armbruster }
25899e933f4aSBenjamin Herrenschmidt 
25909e933f4aSBenjamin Herrenschmidt #define DEFINE_PNV8_CHIP_TYPE(type, class_initfn) \
259177864267SCédric Le Goater     {                                             \
2592beba5c0fSIgor Mammedov         .name          = type,                    \
2593beba5c0fSIgor Mammedov         .class_init    = class_initfn,            \
2594beba5c0fSIgor Mammedov         .parent        = TYPE_PNV8_CHIP,          \
259577864267SCédric Le Goater     }
259677864267SCédric Le Goater 
259777864267SCédric Le Goater #define DEFINE_PNV9_CHIP_TYPE(type, class_initfn) \
259877864267SCédric Le Goater     {                                             \
259977864267SCédric Le Goater         .name          = type,                    \
260077864267SCédric Le Goater         .class_init    = class_initfn,            \
260177864267SCédric Le Goater         .parent        = TYPE_PNV9_CHIP,          \
260277864267SCédric Le Goater     }
2603beba5c0fSIgor Mammedov 
2604beba5c0fSIgor Mammedov #define DEFINE_PNV10_CHIP_TYPE(type, class_initfn) \
26052b548a42SCédric Le Goater     {                                              \
26062b548a42SCédric Le Goater         .name          = type,                     \
26072b548a42SCédric Le Goater         .class_init    = class_initfn,             \
26082b548a42SCédric Le Goater         .parent        = TYPE_PNV10_CHIP,          \
26092b548a42SCédric Le Goater     }
26102b548a42SCédric Le Goater 
26112b548a42SCédric Le Goater static const TypeInfo types[] = {
2612beba5c0fSIgor Mammedov     {
26131aba8716SCédric Le Goater         .name          = MACHINE_TYPE_NAME("powernv10-rainier"),
2614ab874668SGlenn Miles         .parent        = MACHINE_TYPE_NAME("powernv10"),
2615ab874668SGlenn Miles         .class_init    = pnv_machine_p10_rainier_class_init,
2616ab874668SGlenn Miles     },
2617ab874668SGlenn Miles     {
2618ab874668SGlenn Miles         .name          = MACHINE_TYPE_NAME("powernv10"),
26192b548a42SCédric Le Goater         .parent        = TYPE_PNV_MACHINE,
26202b548a42SCédric Le Goater         .class_init    = pnv_machine_power10_class_init,
26212b548a42SCédric Le Goater         .interfaces = (InterfaceInfo[]) {
2622da71b7e3SCédric Le Goater             { TYPE_XIVE_FABRIC },
2623da71b7e3SCédric Le Goater             { },
2624da71b7e3SCédric Le Goater         },
2625da71b7e3SCédric Le Goater     },
26262b548a42SCédric Le Goater     {
26272b548a42SCédric Le Goater         .name          = MACHINE_TYPE_NAME("powernv9"),
26281aba8716SCédric Le Goater         .parent        = TYPE_PNV_MACHINE,
26291aba8716SCédric Le Goater         .class_init    = pnv_machine_power9_class_init,
26301aba8716SCédric Le Goater         .interfaces = (InterfaceInfo[]) {
2631c722579eSCédric Le Goater             { TYPE_XIVE_FABRIC },
2632c722579eSCédric Le Goater             { },
2633c722579eSCédric Le Goater         },
2634c722579eSCédric Le Goater     },
26351aba8716SCédric Le Goater     {
26361aba8716SCédric Le Goater         .name          = MACHINE_TYPE_NAME("powernv8"),
26371aba8716SCédric Le Goater         .parent        = TYPE_PNV_MACHINE,
26381aba8716SCédric Le Goater         .class_init    = pnv_machine_power8_class_init,
26391aba8716SCédric Le Goater         .interfaces = (InterfaceInfo[]) {
26401aba8716SCédric Le Goater             { TYPE_XICS_FABRIC },
26411aba8716SCédric Le Goater             { },
26421aba8716SCédric Le Goater         },
26431aba8716SCédric Le Goater     },
26441aba8716SCédric Le Goater     {
2645beba5c0fSIgor Mammedov         .name          = TYPE_PNV_MACHINE,
2646b168a138SCédric Le Goater         .parent        = TYPE_MACHINE,
26479e933f4aSBenjamin Herrenschmidt         .abstract       = true,
2648f30c843cSCédric Le Goater         .instance_size = sizeof(PnvMachineState),
26499e933f4aSBenjamin Herrenschmidt         .class_init    = pnv_machine_class_init,
2650b168a138SCédric Le Goater         .class_size    = sizeof(PnvMachineClass),
2651d76f2da7SGreg Kurz         .interfaces = (InterfaceInfo[]) {
265236fc6f08SCédric Le Goater             { TYPE_INTERRUPT_STATS_PROVIDER },
265347fea43aSCédric Le Goater             { TYPE_NMI },
265401b552b0SNicholas Piggin             { },
265536fc6f08SCédric Le Goater         },
265636fc6f08SCédric Le Goater     },
2657beba5c0fSIgor Mammedov     {
2658beba5c0fSIgor Mammedov         .name          = TYPE_PNV_CHIP,
2659beba5c0fSIgor Mammedov         .parent        = TYPE_SYS_BUS_DEVICE,
2660beba5c0fSIgor Mammedov         .class_init    = pnv_chip_class_init,
2661beba5c0fSIgor Mammedov         .instance_size = sizeof(PnvChip),
2662beba5c0fSIgor Mammedov         .class_size    = sizeof(PnvChipClass),
2663beba5c0fSIgor Mammedov         .abstract      = true,
2664beba5c0fSIgor Mammedov     },
2665beba5c0fSIgor Mammedov 
266677864267SCédric Le Goater     /*
266777864267SCédric Le Goater      * P10 chip and variants
26682b548a42SCédric Le Goater      */
26692b548a42SCédric Le Goater     {
26702b548a42SCédric Le Goater         .name          = TYPE_PNV10_CHIP,
26712b548a42SCédric Le Goater         .parent        = TYPE_PNV_CHIP,
26722b548a42SCédric Le Goater         .instance_init = pnv_chip_power10_instance_init,
26732b548a42SCédric Le Goater         .instance_size = sizeof(Pnv10Chip),
26742b548a42SCédric Le Goater     },
26752b548a42SCédric Le Goater     DEFINE_PNV10_CHIP_TYPE(TYPE_PNV_CHIP_POWER10, pnv_chip_power10_class_init),
26762b548a42SCédric Le Goater 
26772b548a42SCédric Le Goater     /*
26782b548a42SCédric Le Goater      * P9 chip and variants
267977864267SCédric Le Goater      */
268077864267SCédric Le Goater     {
268177864267SCédric Le Goater         .name          = TYPE_PNV9_CHIP,
268277864267SCédric Le Goater         .parent        = TYPE_PNV_CHIP,
268377864267SCédric Le Goater         .instance_init = pnv_chip_power9_instance_init,
268477864267SCédric Le Goater         .instance_size = sizeof(Pnv9Chip),
268577864267SCédric Le Goater     },
268677864267SCédric Le Goater     DEFINE_PNV9_CHIP_TYPE(TYPE_PNV_CHIP_POWER9, pnv_chip_power9_class_init),
268777864267SCédric Le Goater 
268877864267SCédric Le Goater     /*
268977864267SCédric Le Goater      * P8 chip and variants
269077864267SCédric Le Goater      */
269177864267SCédric Le Goater     {
269277864267SCédric Le Goater         .name          = TYPE_PNV8_CHIP,
269377864267SCédric Le Goater         .parent        = TYPE_PNV_CHIP,
269477864267SCédric Le Goater         .instance_init = pnv_chip_power8_instance_init,
269577864267SCédric Le Goater         .instance_size = sizeof(Pnv8Chip),
269677864267SCédric Le Goater     },
269777864267SCédric Le Goater     DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8, pnv_chip_power8_class_init),
269877864267SCédric Le Goater     DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8E, pnv_chip_power8e_class_init),
269977864267SCédric Le Goater     DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8NVL,
270077864267SCédric Le Goater                           pnv_chip_power8nvl_class_init),
2701beba5c0fSIgor Mammedov };
27029e933f4aSBenjamin Herrenschmidt 
27039e933f4aSBenjamin Herrenschmidt DEFINE_TYPES(types)
2704beba5c0fSIgor Mammedov