xref: /openbmc/qemu/hw/ppc/pnv_homer.c (revision 634cf61e463a8020cb8eb835fae4e2939f387975)
1 /*
2  * QEMU PowerPC PowerNV Emulation of a few HOMER related registers
3  *
4  * Copyright (c) 2019, IBM Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License, version 2, as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "qemu/osdep.h"
20 #include "qemu/log.h"
21 #include "qapi/error.h"
22 #include "exec/hwaddr.h"
23 #include "exec/memory.h"
24 #include "system/cpus.h"
25 #include "hw/qdev-core.h"
26 #include "hw/qdev-properties.h"
27 #include "hw/ppc/pnv.h"
28 #include "hw/ppc/pnv_chip.h"
29 #include "hw/ppc/pnv_homer.h"
30 #include "hw/ppc/pnv_xscom.h"
31 
32 
33 static bool core_max_array(PnvHomer *homer, hwaddr addr)
34 {
35     int i;
36     PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer);
37 
38     for (i = 0; i <= homer->chip->nr_cores; i++) {
39         if (addr == (hmrc->core_max_base + i)) {
40             return true;
41        }
42     }
43     return false;
44 }
45 
46 /* P8 Pstate table */
47 
48 #define PNV8_OCC_PSTATE_VERSION          0x1f8001
49 #define PNV8_OCC_PSTATE_MIN              0x1f8003
50 #define PNV8_OCC_PSTATE_VALID            0x1f8000
51 #define PNV8_OCC_PSTATE_THROTTLE         0x1f8002
52 #define PNV8_OCC_PSTATE_NOM              0x1f8004
53 #define PNV8_OCC_PSTATE_TURBO            0x1f8005
54 #define PNV8_OCC_PSTATE_ULTRA_TURBO      0x1f8006
55 #define PNV8_OCC_PSTATE_DATA             0x1f8008
56 #define PNV8_OCC_PSTATE_ID_ZERO          0x1f8010
57 #define PNV8_OCC_PSTATE_ID_ONE           0x1f8018
58 #define PNV8_OCC_PSTATE_ID_TWO           0x1f8020
59 #define PNV8_OCC_VDD_VOLTAGE_IDENTIFIER  0x1f8012
60 #define PNV8_OCC_VCS_VOLTAGE_IDENTIFIER  0x1f8013
61 #define PNV8_OCC_PSTATE_ZERO_FREQUENCY   0x1f8014
62 #define PNV8_OCC_PSTATE_ONE_FREQUENCY    0x1f801c
63 #define PNV8_OCC_PSTATE_TWO_FREQUENCY    0x1f8024
64 #define PNV8_CORE_MAX_BASE               0x1f8810
65 
66 
67 static uint64_t pnv_power8_homer_read(void *opaque, hwaddr addr,
68                                       unsigned size)
69 {
70     PnvHomer *homer = PNV_HOMER(opaque);
71 
72     switch (addr) {
73     case PNV8_OCC_PSTATE_VALID:
74         return 1;
75     case PNV8_OCC_PSTATE_THROTTLE:
76         return 0;
77     case PNV8_OCC_PSTATE_VERSION:
78         return 0x02;
79     case PNV8_OCC_PSTATE_MIN:
80         return -2;
81     case PNV8_OCC_PSTATE_NOM:
82     case PNV8_OCC_PSTATE_TURBO:
83         return -1;
84     case PNV8_OCC_PSTATE_ULTRA_TURBO:
85         return 0;
86     case PNV8_OCC_PSTATE_ID_ZERO:
87         return 0;
88     case PNV8_OCC_VDD_VOLTAGE_IDENTIFIER:
89     case PNV8_OCC_VCS_VOLTAGE_IDENTIFIER:
90         return 1;
91     case PNV8_OCC_PSTATE_DATA:
92         return 0;
93     /* P8 frequency for 0, 1, and 2 pstates */
94     case PNV8_OCC_PSTATE_ZERO_FREQUENCY:
95     case PNV8_OCC_PSTATE_ONE_FREQUENCY:
96     case PNV8_OCC_PSTATE_TWO_FREQUENCY:
97         return 3000;
98     case PNV8_OCC_PSTATE_ID_ONE:
99         return -1;
100     case PNV8_OCC_PSTATE_ID_TWO:
101         return -2;
102     }
103     /* pstate table core max array */
104     if (core_max_array(homer, addr)) {
105         return 1;
106     }
107     return 0;
108 }
109 
110 static void pnv_power8_homer_write(void *opaque, hwaddr addr,
111                                    uint64_t val, unsigned size)
112 {
113     /* callback function defined to homer write */
114     return;
115 }
116 
117 static const MemoryRegionOps pnv_power8_homer_ops = {
118     .read = pnv_power8_homer_read,
119     .write = pnv_power8_homer_write,
120     .valid.min_access_size = 1,
121     .valid.max_access_size = 8,
122     .impl.min_access_size = 1,
123     .impl.max_access_size = 8,
124     .endianness = DEVICE_BIG_ENDIAN,
125 };
126 
127 /* P8 PBA BARs */
128 #define PBA_BAR0                     0x00
129 #define PBA_BAR1                     0x01
130 #define PBA_BAR2                     0x02
131 #define PBA_BAR3                     0x03
132 #define PBA_BARMASK0                 0x04
133 #define PBA_BARMASK1                 0x05
134 #define PBA_BARMASK2                 0x06
135 #define PBA_BARMASK3                 0x07
136 
137 static uint64_t pnv_homer_power8_pba_read(void *opaque, hwaddr addr,
138                                           unsigned size)
139 {
140     PnvHomer *homer = PNV_HOMER(opaque);
141     PnvChip *chip = homer->chip;
142     uint32_t reg = addr >> 3;
143     uint64_t val = 0;
144 
145     switch (reg) {
146     case PBA_BAR0:
147         val = PNV_HOMER_BASE(chip);
148         break;
149     case PBA_BARMASK0: /* P8 homer region mask */
150         val = (PNV_HOMER_SIZE - 1) & 0x300000;
151         break;
152     case PBA_BAR3: /* P8 occ common area */
153         val = PNV_OCC_COMMON_AREA_BASE;
154         break;
155     case PBA_BARMASK3: /* P8 occ common area mask */
156         val = (PNV_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
157         break;
158     default:
159         qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
160                       HWADDR_PRIx "\n", addr >> 3);
161     }
162     return val;
163 }
164 
165 static void pnv_homer_power8_pba_write(void *opaque, hwaddr addr,
166                                          uint64_t val, unsigned size)
167 {
168     qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
169                   HWADDR_PRIx "\n", addr >> 3);
170 }
171 
172 static const MemoryRegionOps pnv_homer_power8_pba_ops = {
173     .read = pnv_homer_power8_pba_read,
174     .write = pnv_homer_power8_pba_write,
175     .valid.min_access_size = 8,
176     .valid.max_access_size = 8,
177     .impl.min_access_size = 8,
178     .impl.max_access_size = 8,
179     .endianness = DEVICE_BIG_ENDIAN,
180 };
181 
182 static void pnv_homer_power8_class_init(ObjectClass *klass, void *data)
183 {
184     PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
185 
186     homer->pba_size = PNV_XSCOM_PBA_SIZE;
187     homer->pba_ops = &pnv_homer_power8_pba_ops;
188     homer->homer_size = PNV_HOMER_SIZE;
189     homer->homer_ops = &pnv_power8_homer_ops;
190     homer->core_max_base = PNV8_CORE_MAX_BASE;
191 }
192 
193 static const TypeInfo pnv_homer_power8_type_info = {
194     .name          = TYPE_PNV8_HOMER,
195     .parent        = TYPE_PNV_HOMER,
196     .instance_size = sizeof(PnvHomer),
197     .class_init    = pnv_homer_power8_class_init,
198 };
199 
200 /* P9 Pstate table */
201 
202 #define PNV9_OCC_PSTATE_VALID            0xe2000
203 #define PNV9_OCC_PSTATE_ID_ZERO          0xe2018
204 #define PNV9_OCC_PSTATE_ID_ONE           0xe2020
205 #define PNV9_OCC_PSTATE_ID_TWO           0xe2028
206 #define PNV9_OCC_PSTATE_DATA             0xe2000
207 #define PNV9_OCC_PSTATE_MINOR_VERSION    0xe2008
208 #define PNV9_OCC_PSTATE_MIN              0xe2003
209 #define PNV9_OCC_PSTATE_NOM              0xe2004
210 #define PNV9_OCC_PSTATE_TURBO            0xe2005
211 #define PNV9_OCC_PSTATE_ULTRA_TURBO      0xe2818
212 #define PNV9_OCC_MAX_PSTATE_ULTRA_TURBO  0xe2006
213 #define PNV9_OCC_PSTATE_MAJOR_VERSION    0xe2001
214 #define PNV9_OCC_OPAL_RUNTIME_DATA       0xe2b85
215 #define PNV9_CHIP_HOMER_IMAGE_POINTER    0x200008
216 #define PNV9_CHIP_HOMER_BASE             0x0
217 #define PNV9_OCC_PSTATE_ZERO_FREQUENCY   0xe201c
218 #define PNV9_OCC_PSTATE_ONE_FREQUENCY    0xe2024
219 #define PNV9_OCC_PSTATE_TWO_FREQUENCY    0xe202c
220 #define PNV9_OCC_ROLE_MASTER_OR_SLAVE    0xe2002
221 #define PNV9_CORE_MAX_BASE               0xe2819
222 #define PNV9_DYNAMIC_DATA_STATE          0xe2b80
223 
224 static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr,
225                                       unsigned size)
226 {
227     PnvHomer *homer = PNV_HOMER(opaque);
228 
229     switch (addr) {
230     case PNV9_OCC_PSTATE_VALID:
231         return 1;
232     case PNV9_OCC_MAX_PSTATE_ULTRA_TURBO:
233     case PNV9_OCC_PSTATE_ID_ZERO:
234         return 0;
235     case PNV9_OCC_ROLE_MASTER_OR_SLAVE:
236         if (homer->chip->chip_id == 0) {
237             return 0x1; /* master */
238         } else {
239             return 0x0; /* slave */
240         }
241     case PNV9_OCC_PSTATE_NOM:
242     case PNV9_OCC_PSTATE_TURBO:
243     case PNV9_OCC_PSTATE_ID_ONE:
244     case PNV9_OCC_PSTATE_ULTRA_TURBO:
245     case PNV9_OCC_OPAL_RUNTIME_DATA:
246         return 1;
247     case PNV9_OCC_PSTATE_MIN:
248     case PNV9_OCC_PSTATE_ID_TWO:
249         return 2;
250 
251     /* 3000 khz frequency for 0, 1, and 2 pstates */
252     case PNV9_OCC_PSTATE_ZERO_FREQUENCY:
253     case PNV9_OCC_PSTATE_ONE_FREQUENCY:
254     case PNV9_OCC_PSTATE_TWO_FREQUENCY:
255         return 3000;
256     case PNV9_OCC_PSTATE_MAJOR_VERSION:
257         return 0x90;
258     case PNV9_OCC_PSTATE_MINOR_VERSION:
259         return 0x01;
260     case PNV9_CHIP_HOMER_BASE:
261     case PNV9_CHIP_HOMER_IMAGE_POINTER:
262         return 0;
263     case PNV9_DYNAMIC_DATA_STATE:
264         return 0x03; /* active */
265     }
266     /* pstate table core max array */
267     if (core_max_array(homer, addr)) {
268         return 1;
269     }
270     return 0;
271 }
272 
273 static void pnv_power9_homer_write(void *opaque, hwaddr addr,
274                                    uint64_t val, unsigned size)
275 {
276     /* callback function defined to homer write */
277     return;
278 }
279 
280 static const MemoryRegionOps pnv_power9_homer_ops = {
281     .read = pnv_power9_homer_read,
282     .write = pnv_power9_homer_write,
283     .valid.min_access_size = 1,
284     .valid.max_access_size = 8,
285     .impl.min_access_size = 1,
286     .impl.max_access_size = 8,
287     .endianness = DEVICE_BIG_ENDIAN,
288 };
289 
290 static uint64_t pnv_homer_power9_pba_read(void *opaque, hwaddr addr,
291                                           unsigned size)
292 {
293     PnvHomer *homer = PNV_HOMER(opaque);
294     PnvChip *chip = homer->chip;
295     uint32_t reg = addr >> 3;
296     uint64_t val = 0;
297 
298     switch (reg) {
299     case PBA_BAR0:
300         val = PNV9_HOMER_BASE(chip);
301         break;
302     case PBA_BARMASK0: /* P9 homer region mask */
303         val = (PNV9_HOMER_SIZE - 1) & 0x300000;
304         break;
305     case PBA_BAR2: /* P9 occ common area */
306         val = PNV9_OCC_COMMON_AREA_BASE;
307         break;
308     case PBA_BARMASK2: /* P9 occ common area size */
309         val = (PNV9_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
310         break;
311     default:
312         qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
313                       HWADDR_PRIx "\n", addr >> 3);
314     }
315     return val;
316 }
317 
318 static void pnv_homer_power9_pba_write(void *opaque, hwaddr addr,
319                                          uint64_t val, unsigned size)
320 {
321     qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
322                   HWADDR_PRIx "\n", addr >> 3);
323 }
324 
325 static const MemoryRegionOps pnv_homer_power9_pba_ops = {
326     .read = pnv_homer_power9_pba_read,
327     .write = pnv_homer_power9_pba_write,
328     .valid.min_access_size = 8,
329     .valid.max_access_size = 8,
330     .impl.min_access_size = 8,
331     .impl.max_access_size = 8,
332     .endianness = DEVICE_BIG_ENDIAN,
333 };
334 
335 static void pnv_homer_power9_class_init(ObjectClass *klass, void *data)
336 {
337     PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
338 
339     homer->pba_size = PNV9_XSCOM_PBA_SIZE;
340     homer->pba_ops = &pnv_homer_power9_pba_ops;
341     homer->homer_size = PNV9_HOMER_SIZE;
342     homer->homer_ops = &pnv_power9_homer_ops;
343     homer->core_max_base = PNV9_CORE_MAX_BASE;
344 }
345 
346 static const TypeInfo pnv_homer_power9_type_info = {
347     .name          = TYPE_PNV9_HOMER,
348     .parent        = TYPE_PNV_HOMER,
349     .instance_size = sizeof(PnvHomer),
350     .class_init    = pnv_homer_power9_class_init,
351 };
352 
353 static uint64_t pnv_homer_power10_pba_read(void *opaque, hwaddr addr,
354                                           unsigned size)
355 {
356     PnvHomer *homer = PNV_HOMER(opaque);
357     PnvChip *chip = homer->chip;
358     uint32_t reg = addr >> 3;
359     uint64_t val = 0;
360 
361     switch (reg) {
362     case PBA_BAR0:
363         val = PNV10_HOMER_BASE(chip);
364         break;
365     case PBA_BARMASK0: /* P10 homer region mask */
366         val = (PNV10_HOMER_SIZE - 1) & 0x300000;
367         break;
368     case PBA_BAR2: /* P10 occ common area */
369         val = PNV10_OCC_COMMON_AREA_BASE;
370         break;
371     case PBA_BARMASK2: /* P10 occ common area size */
372         val = (PNV10_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
373         break;
374     default:
375         qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
376                       HWADDR_PRIx "\n", addr >> 3);
377     }
378     return val;
379 }
380 
381 static void pnv_homer_power10_pba_write(void *opaque, hwaddr addr,
382                                          uint64_t val, unsigned size)
383 {
384     qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
385                   HWADDR_PRIx "\n", addr >> 3);
386 }
387 
388 static const MemoryRegionOps pnv_homer_power10_pba_ops = {
389     .read = pnv_homer_power10_pba_read,
390     .write = pnv_homer_power10_pba_write,
391     .valid.min_access_size = 8,
392     .valid.max_access_size = 8,
393     .impl.min_access_size = 8,
394     .impl.max_access_size = 8,
395     .endianness = DEVICE_BIG_ENDIAN,
396 };
397 
398 static void pnv_homer_power10_class_init(ObjectClass *klass, void *data)
399 {
400     PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
401 
402     homer->pba_size = PNV10_XSCOM_PBA_SIZE;
403     homer->pba_ops = &pnv_homer_power10_pba_ops;
404     homer->homer_size = PNV10_HOMER_SIZE;
405     homer->homer_ops = &pnv_power9_homer_ops; /* TODO */
406     homer->core_max_base = PNV9_CORE_MAX_BASE;
407 }
408 
409 static const TypeInfo pnv_homer_power10_type_info = {
410     .name          = TYPE_PNV10_HOMER,
411     .parent        = TYPE_PNV_HOMER,
412     .instance_size = sizeof(PnvHomer),
413     .class_init    = pnv_homer_power10_class_init,
414 };
415 
416 static void pnv_homer_realize(DeviceState *dev, Error **errp)
417 {
418     PnvHomer *homer = PNV_HOMER(dev);
419     PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer);
420 
421     assert(homer->chip);
422 
423     pnv_xscom_region_init(&homer->pba_regs, OBJECT(dev), hmrc->pba_ops,
424                           homer, "xscom-pba", hmrc->pba_size);
425 
426     /* homer region */
427     memory_region_init_io(&homer->regs, OBJECT(dev),
428                           hmrc->homer_ops, homer, "homer-main-memory",
429                           hmrc->homer_size);
430 }
431 
432 static const Property pnv_homer_properties[] = {
433     DEFINE_PROP_LINK("chip", PnvHomer, chip, TYPE_PNV_CHIP, PnvChip *),
434 };
435 
436 static void pnv_homer_class_init(ObjectClass *klass, void *data)
437 {
438     DeviceClass *dc = DEVICE_CLASS(klass);
439 
440     dc->realize = pnv_homer_realize;
441     dc->desc = "PowerNV HOMER Memory";
442     device_class_set_props(dc, pnv_homer_properties);
443     dc->user_creatable = false;
444 }
445 
446 static const TypeInfo pnv_homer_type_info = {
447     .name          = TYPE_PNV_HOMER,
448     .parent        = TYPE_DEVICE,
449     .instance_size = sizeof(PnvHomer),
450     .class_init    = pnv_homer_class_init,
451     .class_size    = sizeof(PnvHomerClass),
452     .abstract      = true,
453 };
454 
455 static void pnv_homer_register_types(void)
456 {
457     type_register_static(&pnv_homer_type_info);
458     type_register_static(&pnv_homer_power8_type_info);
459     type_register_static(&pnv_homer_power9_type_info);
460     type_register_static(&pnv_homer_power10_type_info);
461 }
462 
463 type_init(pnv_homer_register_types);
464