13887d241SBalamuruhan S /*
23887d241SBalamuruhan S * QEMU PowerPC PowerNV Emulation of a few HOMER related registers
33887d241SBalamuruhan S *
43887d241SBalamuruhan S * Copyright (c) 2019, IBM Corporation.
53887d241SBalamuruhan S *
63887d241SBalamuruhan S * This program is free software; you can redistribute it and/or modify
73887d241SBalamuruhan S * it under the terms of the GNU General Public License, version 2, as
83887d241SBalamuruhan S * published by the Free Software Foundation.
93887d241SBalamuruhan S *
103887d241SBalamuruhan S * This program is distributed in the hope that it will be useful,
113887d241SBalamuruhan S * but WITHOUT ANY WARRANTY; without even the implied warranty of
123887d241SBalamuruhan S * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
133887d241SBalamuruhan S * GNU General Public License for more details.
143887d241SBalamuruhan S *
153887d241SBalamuruhan S * You should have received a copy of the GNU General Public License
163887d241SBalamuruhan S * along with this program; if not, see <http://www.gnu.org/licenses/>.
173887d241SBalamuruhan S */
183887d241SBalamuruhan S
193887d241SBalamuruhan S #include "qemu/osdep.h"
208f092316SCédric Le Goater #include "qemu/log.h"
213887d241SBalamuruhan S #include "qapi/error.h"
223887d241SBalamuruhan S #include "exec/hwaddr.h"
233887d241SBalamuruhan S #include "exec/memory.h"
243887d241SBalamuruhan S #include "sysemu/cpus.h"
253887d241SBalamuruhan S #include "hw/qdev-core.h"
26f2582acfSGreg Kurz #include "hw/qdev-properties.h"
273887d241SBalamuruhan S #include "hw/ppc/pnv.h"
28*2c6fe2e2SMarkus Armbruster #include "hw/ppc/pnv_chip.h"
293887d241SBalamuruhan S #include "hw/ppc/pnv_homer.h"
308f092316SCédric Le Goater #include "hw/ppc/pnv_xscom.h"
313887d241SBalamuruhan S
323887d241SBalamuruhan S
core_max_array(PnvHomer * homer,hwaddr addr)333887d241SBalamuruhan S static bool core_max_array(PnvHomer *homer, hwaddr addr)
343887d241SBalamuruhan S {
353887d241SBalamuruhan S int i;
363887d241SBalamuruhan S PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer);
373887d241SBalamuruhan S
383887d241SBalamuruhan S for (i = 0; i <= homer->chip->nr_cores; i++) {
393887d241SBalamuruhan S if (addr == (hmrc->core_max_base + i)) {
403887d241SBalamuruhan S return true;
413887d241SBalamuruhan S }
423887d241SBalamuruhan S }
433887d241SBalamuruhan S return false;
443887d241SBalamuruhan S }
453887d241SBalamuruhan S
463887d241SBalamuruhan S /* P8 Pstate table */
473887d241SBalamuruhan S
483887d241SBalamuruhan S #define PNV8_OCC_PSTATE_VERSION 0x1f8001
493887d241SBalamuruhan S #define PNV8_OCC_PSTATE_MIN 0x1f8003
503887d241SBalamuruhan S #define PNV8_OCC_PSTATE_VALID 0x1f8000
513887d241SBalamuruhan S #define PNV8_OCC_PSTATE_THROTTLE 0x1f8002
523887d241SBalamuruhan S #define PNV8_OCC_PSTATE_NOM 0x1f8004
533887d241SBalamuruhan S #define PNV8_OCC_PSTATE_TURBO 0x1f8005
543887d241SBalamuruhan S #define PNV8_OCC_PSTATE_ULTRA_TURBO 0x1f8006
553887d241SBalamuruhan S #define PNV8_OCC_PSTATE_DATA 0x1f8008
563887d241SBalamuruhan S #define PNV8_OCC_PSTATE_ID_ZERO 0x1f8010
573887d241SBalamuruhan S #define PNV8_OCC_PSTATE_ID_ONE 0x1f8018
583887d241SBalamuruhan S #define PNV8_OCC_PSTATE_ID_TWO 0x1f8020
593887d241SBalamuruhan S #define PNV8_OCC_VDD_VOLTAGE_IDENTIFIER 0x1f8012
603887d241SBalamuruhan S #define PNV8_OCC_VCS_VOLTAGE_IDENTIFIER 0x1f8013
613887d241SBalamuruhan S #define PNV8_OCC_PSTATE_ZERO_FREQUENCY 0x1f8014
623887d241SBalamuruhan S #define PNV8_OCC_PSTATE_ONE_FREQUENCY 0x1f801c
633887d241SBalamuruhan S #define PNV8_OCC_PSTATE_TWO_FREQUENCY 0x1f8024
643887d241SBalamuruhan S #define PNV8_CORE_MAX_BASE 0x1f8810
653887d241SBalamuruhan S
663887d241SBalamuruhan S
pnv_power8_homer_read(void * opaque,hwaddr addr,unsigned size)673887d241SBalamuruhan S static uint64_t pnv_power8_homer_read(void *opaque, hwaddr addr,
683887d241SBalamuruhan S unsigned size)
693887d241SBalamuruhan S {
703887d241SBalamuruhan S PnvHomer *homer = PNV_HOMER(opaque);
713887d241SBalamuruhan S
723887d241SBalamuruhan S switch (addr) {
733887d241SBalamuruhan S case PNV8_OCC_PSTATE_VERSION:
743887d241SBalamuruhan S case PNV8_OCC_PSTATE_MIN:
753887d241SBalamuruhan S case PNV8_OCC_PSTATE_ID_ZERO:
763887d241SBalamuruhan S return 0;
773887d241SBalamuruhan S case PNV8_OCC_PSTATE_VALID:
783887d241SBalamuruhan S case PNV8_OCC_PSTATE_THROTTLE:
793887d241SBalamuruhan S case PNV8_OCC_PSTATE_NOM:
803887d241SBalamuruhan S case PNV8_OCC_PSTATE_TURBO:
813887d241SBalamuruhan S case PNV8_OCC_PSTATE_ID_ONE:
823887d241SBalamuruhan S case PNV8_OCC_VDD_VOLTAGE_IDENTIFIER:
833887d241SBalamuruhan S case PNV8_OCC_VCS_VOLTAGE_IDENTIFIER:
843887d241SBalamuruhan S return 1;
853887d241SBalamuruhan S case PNV8_OCC_PSTATE_ULTRA_TURBO:
863887d241SBalamuruhan S case PNV8_OCC_PSTATE_ID_TWO:
873887d241SBalamuruhan S return 2;
883887d241SBalamuruhan S case PNV8_OCC_PSTATE_DATA:
893887d241SBalamuruhan S return 0x1000000000000000;
903887d241SBalamuruhan S /* P8 frequency for 0, 1, and 2 pstates */
913887d241SBalamuruhan S case PNV8_OCC_PSTATE_ZERO_FREQUENCY:
923887d241SBalamuruhan S case PNV8_OCC_PSTATE_ONE_FREQUENCY:
933887d241SBalamuruhan S case PNV8_OCC_PSTATE_TWO_FREQUENCY:
943887d241SBalamuruhan S return 3000;
953887d241SBalamuruhan S }
963887d241SBalamuruhan S /* pstate table core max array */
973887d241SBalamuruhan S if (core_max_array(homer, addr)) {
983887d241SBalamuruhan S return 1;
993887d241SBalamuruhan S }
1003887d241SBalamuruhan S return 0;
1013887d241SBalamuruhan S }
1023887d241SBalamuruhan S
pnv_power8_homer_write(void * opaque,hwaddr addr,uint64_t val,unsigned size)1033887d241SBalamuruhan S static void pnv_power8_homer_write(void *opaque, hwaddr addr,
1043887d241SBalamuruhan S uint64_t val, unsigned size)
1053887d241SBalamuruhan S {
1063887d241SBalamuruhan S /* callback function defined to homer write */
1073887d241SBalamuruhan S return;
1083887d241SBalamuruhan S }
1093887d241SBalamuruhan S
1103887d241SBalamuruhan S static const MemoryRegionOps pnv_power8_homer_ops = {
1113887d241SBalamuruhan S .read = pnv_power8_homer_read,
1123887d241SBalamuruhan S .write = pnv_power8_homer_write,
1133887d241SBalamuruhan S .valid.min_access_size = 1,
1143887d241SBalamuruhan S .valid.max_access_size = 8,
1153887d241SBalamuruhan S .impl.min_access_size = 1,
1163887d241SBalamuruhan S .impl.max_access_size = 8,
1173887d241SBalamuruhan S .endianness = DEVICE_BIG_ENDIAN,
1183887d241SBalamuruhan S };
1193887d241SBalamuruhan S
1208f092316SCédric Le Goater /* P8 PBA BARs */
1218f092316SCédric Le Goater #define PBA_BAR0 0x00
1228f092316SCédric Le Goater #define PBA_BAR1 0x01
1238f092316SCédric Le Goater #define PBA_BAR2 0x02
1248f092316SCédric Le Goater #define PBA_BAR3 0x03
1258f092316SCédric Le Goater #define PBA_BARMASK0 0x04
1268f092316SCédric Le Goater #define PBA_BARMASK1 0x05
1278f092316SCédric Le Goater #define PBA_BARMASK2 0x06
1288f092316SCédric Le Goater #define PBA_BARMASK3 0x07
1298f092316SCédric Le Goater
pnv_homer_power8_pba_read(void * opaque,hwaddr addr,unsigned size)1308f092316SCédric Le Goater static uint64_t pnv_homer_power8_pba_read(void *opaque, hwaddr addr,
1318f092316SCédric Le Goater unsigned size)
1328f092316SCédric Le Goater {
1338f092316SCédric Le Goater PnvHomer *homer = PNV_HOMER(opaque);
1348f092316SCédric Le Goater PnvChip *chip = homer->chip;
1358f092316SCédric Le Goater uint32_t reg = addr >> 3;
1368f092316SCédric Le Goater uint64_t val = 0;
1378f092316SCédric Le Goater
1388f092316SCédric Le Goater switch (reg) {
1398f092316SCédric Le Goater case PBA_BAR0:
1408f092316SCédric Le Goater val = PNV_HOMER_BASE(chip);
1418f092316SCédric Le Goater break;
1428f092316SCédric Le Goater case PBA_BARMASK0: /* P8 homer region mask */
1438f092316SCédric Le Goater val = (PNV_HOMER_SIZE - 1) & 0x300000;
1448f092316SCédric Le Goater break;
1458f092316SCédric Le Goater case PBA_BAR3: /* P8 occ common area */
1468f092316SCédric Le Goater val = PNV_OCC_COMMON_AREA_BASE;
1478f092316SCédric Le Goater break;
1488f092316SCédric Le Goater case PBA_BARMASK3: /* P8 occ common area mask */
1498f092316SCédric Le Goater val = (PNV_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
1508f092316SCédric Le Goater break;
1518f092316SCédric Le Goater default:
1528f092316SCédric Le Goater qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
1538f092316SCédric Le Goater HWADDR_PRIx "\n", addr >> 3);
1548f092316SCédric Le Goater }
1558f092316SCédric Le Goater return val;
1568f092316SCédric Le Goater }
1578f092316SCédric Le Goater
pnv_homer_power8_pba_write(void * opaque,hwaddr addr,uint64_t val,unsigned size)1588f092316SCédric Le Goater static void pnv_homer_power8_pba_write(void *opaque, hwaddr addr,
1598f092316SCédric Le Goater uint64_t val, unsigned size)
1608f092316SCédric Le Goater {
1618f092316SCédric Le Goater qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
1628f092316SCédric Le Goater HWADDR_PRIx "\n", addr >> 3);
1638f092316SCédric Le Goater }
1648f092316SCédric Le Goater
1658f092316SCédric Le Goater static const MemoryRegionOps pnv_homer_power8_pba_ops = {
1668f092316SCédric Le Goater .read = pnv_homer_power8_pba_read,
1678f092316SCédric Le Goater .write = pnv_homer_power8_pba_write,
1688f092316SCédric Le Goater .valid.min_access_size = 8,
1698f092316SCédric Le Goater .valid.max_access_size = 8,
1708f092316SCédric Le Goater .impl.min_access_size = 8,
1718f092316SCédric Le Goater .impl.max_access_size = 8,
1728f092316SCédric Le Goater .endianness = DEVICE_BIG_ENDIAN,
1738f092316SCédric Le Goater };
1748f092316SCédric Le Goater
pnv_homer_power8_class_init(ObjectClass * klass,void * data)1753887d241SBalamuruhan S static void pnv_homer_power8_class_init(ObjectClass *klass, void *data)
1763887d241SBalamuruhan S {
1773887d241SBalamuruhan S PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
1783887d241SBalamuruhan S
1798f092316SCédric Le Goater homer->pba_size = PNV_XSCOM_PBA_SIZE;
1808f092316SCédric Le Goater homer->pba_ops = &pnv_homer_power8_pba_ops;
1813887d241SBalamuruhan S homer->homer_size = PNV_HOMER_SIZE;
1823887d241SBalamuruhan S homer->homer_ops = &pnv_power8_homer_ops;
1833887d241SBalamuruhan S homer->core_max_base = PNV8_CORE_MAX_BASE;
1843887d241SBalamuruhan S }
1853887d241SBalamuruhan S
1863887d241SBalamuruhan S static const TypeInfo pnv_homer_power8_type_info = {
1873887d241SBalamuruhan S .name = TYPE_PNV8_HOMER,
1883887d241SBalamuruhan S .parent = TYPE_PNV_HOMER,
1893887d241SBalamuruhan S .instance_size = sizeof(PnvHomer),
1903887d241SBalamuruhan S .class_init = pnv_homer_power8_class_init,
1913887d241SBalamuruhan S };
1923887d241SBalamuruhan S
1933887d241SBalamuruhan S /* P9 Pstate table */
1943887d241SBalamuruhan S
1953887d241SBalamuruhan S #define PNV9_OCC_PSTATE_ID_ZERO 0xe2018
1963887d241SBalamuruhan S #define PNV9_OCC_PSTATE_ID_ONE 0xe2020
1973887d241SBalamuruhan S #define PNV9_OCC_PSTATE_ID_TWO 0xe2028
1983887d241SBalamuruhan S #define PNV9_OCC_PSTATE_DATA 0xe2000
1993887d241SBalamuruhan S #define PNV9_OCC_PSTATE_DATA_AREA 0xe2008
2003887d241SBalamuruhan S #define PNV9_OCC_PSTATE_MIN 0xe2003
2013887d241SBalamuruhan S #define PNV9_OCC_PSTATE_NOM 0xe2004
2023887d241SBalamuruhan S #define PNV9_OCC_PSTATE_TURBO 0xe2005
2033887d241SBalamuruhan S #define PNV9_OCC_PSTATE_ULTRA_TURBO 0xe2818
2043887d241SBalamuruhan S #define PNV9_OCC_MAX_PSTATE_ULTRA_TURBO 0xe2006
2053887d241SBalamuruhan S #define PNV9_OCC_PSTATE_MAJOR_VERSION 0xe2001
2063887d241SBalamuruhan S #define PNV9_OCC_OPAL_RUNTIME_DATA 0xe2b85
2073887d241SBalamuruhan S #define PNV9_CHIP_HOMER_IMAGE_POINTER 0x200008
2083887d241SBalamuruhan S #define PNV9_CHIP_HOMER_BASE 0x0
2093887d241SBalamuruhan S #define PNV9_OCC_PSTATE_ZERO_FREQUENCY 0xe201c
2103887d241SBalamuruhan S #define PNV9_OCC_PSTATE_ONE_FREQUENCY 0xe2024
2113887d241SBalamuruhan S #define PNV9_OCC_PSTATE_TWO_FREQUENCY 0xe202c
2123887d241SBalamuruhan S #define PNV9_OCC_ROLE_MASTER_OR_SLAVE 0xe2002
2133887d241SBalamuruhan S #define PNV9_CORE_MAX_BASE 0xe2819
2143887d241SBalamuruhan S
2153887d241SBalamuruhan S
pnv_power9_homer_read(void * opaque,hwaddr addr,unsigned size)2163887d241SBalamuruhan S static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr,
2173887d241SBalamuruhan S unsigned size)
2183887d241SBalamuruhan S {
2193887d241SBalamuruhan S PnvHomer *homer = PNV_HOMER(opaque);
2203887d241SBalamuruhan S
2213887d241SBalamuruhan S switch (addr) {
2223887d241SBalamuruhan S case PNV9_OCC_MAX_PSTATE_ULTRA_TURBO:
2233887d241SBalamuruhan S case PNV9_OCC_PSTATE_ID_ZERO:
2243887d241SBalamuruhan S return 0;
2253887d241SBalamuruhan S case PNV9_OCC_PSTATE_DATA:
2263887d241SBalamuruhan S case PNV9_OCC_ROLE_MASTER_OR_SLAVE:
2273887d241SBalamuruhan S case PNV9_OCC_PSTATE_NOM:
2283887d241SBalamuruhan S case PNV9_OCC_PSTATE_TURBO:
2293887d241SBalamuruhan S case PNV9_OCC_PSTATE_ID_ONE:
2303887d241SBalamuruhan S case PNV9_OCC_PSTATE_ULTRA_TURBO:
2313887d241SBalamuruhan S case PNV9_OCC_OPAL_RUNTIME_DATA:
2323887d241SBalamuruhan S return 1;
2333887d241SBalamuruhan S case PNV9_OCC_PSTATE_MIN:
2343887d241SBalamuruhan S case PNV9_OCC_PSTATE_ID_TWO:
2353887d241SBalamuruhan S return 2;
2363887d241SBalamuruhan S
2373887d241SBalamuruhan S /* 3000 khz frequency for 0, 1, and 2 pstates */
2383887d241SBalamuruhan S case PNV9_OCC_PSTATE_ZERO_FREQUENCY:
2393887d241SBalamuruhan S case PNV9_OCC_PSTATE_ONE_FREQUENCY:
2403887d241SBalamuruhan S case PNV9_OCC_PSTATE_TWO_FREQUENCY:
2413887d241SBalamuruhan S return 3000;
2423887d241SBalamuruhan S case PNV9_OCC_PSTATE_MAJOR_VERSION:
2433887d241SBalamuruhan S return 0x90;
2443887d241SBalamuruhan S case PNV9_CHIP_HOMER_BASE:
2453887d241SBalamuruhan S case PNV9_OCC_PSTATE_DATA_AREA:
2463887d241SBalamuruhan S case PNV9_CHIP_HOMER_IMAGE_POINTER:
2473887d241SBalamuruhan S return 0x1000000000000000;
2483887d241SBalamuruhan S }
2493887d241SBalamuruhan S /* pstate table core max array */
2503887d241SBalamuruhan S if (core_max_array(homer, addr)) {
2513887d241SBalamuruhan S return 1;
2523887d241SBalamuruhan S }
2533887d241SBalamuruhan S return 0;
2543887d241SBalamuruhan S }
2553887d241SBalamuruhan S
pnv_power9_homer_write(void * opaque,hwaddr addr,uint64_t val,unsigned size)2563887d241SBalamuruhan S static void pnv_power9_homer_write(void *opaque, hwaddr addr,
2573887d241SBalamuruhan S uint64_t val, unsigned size)
2583887d241SBalamuruhan S {
2593887d241SBalamuruhan S /* callback function defined to homer write */
2603887d241SBalamuruhan S return;
2613887d241SBalamuruhan S }
2623887d241SBalamuruhan S
2633887d241SBalamuruhan S static const MemoryRegionOps pnv_power9_homer_ops = {
2643887d241SBalamuruhan S .read = pnv_power9_homer_read,
2653887d241SBalamuruhan S .write = pnv_power9_homer_write,
2663887d241SBalamuruhan S .valid.min_access_size = 1,
2673887d241SBalamuruhan S .valid.max_access_size = 8,
2683887d241SBalamuruhan S .impl.min_access_size = 1,
2693887d241SBalamuruhan S .impl.max_access_size = 8,
2703887d241SBalamuruhan S .endianness = DEVICE_BIG_ENDIAN,
2713887d241SBalamuruhan S };
2723887d241SBalamuruhan S
pnv_homer_power9_pba_read(void * opaque,hwaddr addr,unsigned size)2738f092316SCédric Le Goater static uint64_t pnv_homer_power9_pba_read(void *opaque, hwaddr addr,
2748f092316SCédric Le Goater unsigned size)
2758f092316SCédric Le Goater {
2768f092316SCédric Le Goater PnvHomer *homer = PNV_HOMER(opaque);
2778f092316SCédric Le Goater PnvChip *chip = homer->chip;
2788f092316SCédric Le Goater uint32_t reg = addr >> 3;
2798f092316SCédric Le Goater uint64_t val = 0;
2808f092316SCédric Le Goater
2818f092316SCédric Le Goater switch (reg) {
2828f092316SCédric Le Goater case PBA_BAR0:
2838f092316SCédric Le Goater val = PNV9_HOMER_BASE(chip);
2848f092316SCédric Le Goater break;
2858f092316SCédric Le Goater case PBA_BARMASK0: /* P9 homer region mask */
2868f092316SCédric Le Goater val = (PNV9_HOMER_SIZE - 1) & 0x300000;
2878f092316SCédric Le Goater break;
2888f092316SCédric Le Goater case PBA_BAR2: /* P9 occ common area */
2898f092316SCédric Le Goater val = PNV9_OCC_COMMON_AREA_BASE;
2908f092316SCédric Le Goater break;
2918f092316SCédric Le Goater case PBA_BARMASK2: /* P9 occ common area size */
2928f092316SCédric Le Goater val = (PNV9_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
2938f092316SCédric Le Goater break;
2948f092316SCédric Le Goater default:
2958f092316SCédric Le Goater qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
2968f092316SCédric Le Goater HWADDR_PRIx "\n", addr >> 3);
2978f092316SCédric Le Goater }
2988f092316SCédric Le Goater return val;
2998f092316SCédric Le Goater }
3008f092316SCédric Le Goater
pnv_homer_power9_pba_write(void * opaque,hwaddr addr,uint64_t val,unsigned size)3018f092316SCédric Le Goater static void pnv_homer_power9_pba_write(void *opaque, hwaddr addr,
3028f092316SCédric Le Goater uint64_t val, unsigned size)
3038f092316SCédric Le Goater {
3048f092316SCédric Le Goater qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
3058f092316SCédric Le Goater HWADDR_PRIx "\n", addr >> 3);
3068f092316SCédric Le Goater }
3078f092316SCédric Le Goater
3088f092316SCédric Le Goater static const MemoryRegionOps pnv_homer_power9_pba_ops = {
3098f092316SCédric Le Goater .read = pnv_homer_power9_pba_read,
3108f092316SCédric Le Goater .write = pnv_homer_power9_pba_write,
3118f092316SCédric Le Goater .valid.min_access_size = 8,
3128f092316SCédric Le Goater .valid.max_access_size = 8,
3138f092316SCédric Le Goater .impl.min_access_size = 8,
3148f092316SCédric Le Goater .impl.max_access_size = 8,
3158f092316SCédric Le Goater .endianness = DEVICE_BIG_ENDIAN,
3168f092316SCédric Le Goater };
3178f092316SCédric Le Goater
pnv_homer_power9_class_init(ObjectClass * klass,void * data)3183887d241SBalamuruhan S static void pnv_homer_power9_class_init(ObjectClass *klass, void *data)
3193887d241SBalamuruhan S {
3203887d241SBalamuruhan S PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
3213887d241SBalamuruhan S
3228f092316SCédric Le Goater homer->pba_size = PNV9_XSCOM_PBA_SIZE;
3238f092316SCédric Le Goater homer->pba_ops = &pnv_homer_power9_pba_ops;
3243887d241SBalamuruhan S homer->homer_size = PNV9_HOMER_SIZE;
3253887d241SBalamuruhan S homer->homer_ops = &pnv_power9_homer_ops;
3263887d241SBalamuruhan S homer->core_max_base = PNV9_CORE_MAX_BASE;
3273887d241SBalamuruhan S }
3283887d241SBalamuruhan S
3293887d241SBalamuruhan S static const TypeInfo pnv_homer_power9_type_info = {
3303887d241SBalamuruhan S .name = TYPE_PNV9_HOMER,
3313887d241SBalamuruhan S .parent = TYPE_PNV_HOMER,
3323887d241SBalamuruhan S .instance_size = sizeof(PnvHomer),
3333887d241SBalamuruhan S .class_init = pnv_homer_power9_class_init,
3343887d241SBalamuruhan S };
3353887d241SBalamuruhan S
pnv_homer_power10_pba_read(void * opaque,hwaddr addr,unsigned size)33692499676SCédric Le Goater static uint64_t pnv_homer_power10_pba_read(void *opaque, hwaddr addr,
33792499676SCédric Le Goater unsigned size)
33892499676SCédric Le Goater {
33992499676SCédric Le Goater PnvHomer *homer = PNV_HOMER(opaque);
34092499676SCédric Le Goater PnvChip *chip = homer->chip;
34192499676SCédric Le Goater uint32_t reg = addr >> 3;
34292499676SCédric Le Goater uint64_t val = 0;
34392499676SCédric Le Goater
34492499676SCédric Le Goater switch (reg) {
34592499676SCédric Le Goater case PBA_BAR0:
34692499676SCédric Le Goater val = PNV10_HOMER_BASE(chip);
34792499676SCédric Le Goater break;
34892499676SCédric Le Goater case PBA_BARMASK0: /* P10 homer region mask */
34992499676SCédric Le Goater val = (PNV10_HOMER_SIZE - 1) & 0x300000;
35092499676SCédric Le Goater break;
35192499676SCédric Le Goater case PBA_BAR2: /* P10 occ common area */
35292499676SCédric Le Goater val = PNV10_OCC_COMMON_AREA_BASE;
35392499676SCédric Le Goater break;
35492499676SCédric Le Goater case PBA_BARMASK2: /* P10 occ common area size */
35592499676SCédric Le Goater val = (PNV10_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
35692499676SCédric Le Goater break;
35792499676SCédric Le Goater default:
35892499676SCédric Le Goater qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
35992499676SCédric Le Goater HWADDR_PRIx "\n", addr >> 3);
36092499676SCédric Le Goater }
36192499676SCédric Le Goater return val;
36292499676SCédric Le Goater }
36392499676SCédric Le Goater
pnv_homer_power10_pba_write(void * opaque,hwaddr addr,uint64_t val,unsigned size)36492499676SCédric Le Goater static void pnv_homer_power10_pba_write(void *opaque, hwaddr addr,
36592499676SCédric Le Goater uint64_t val, unsigned size)
36692499676SCédric Le Goater {
36792499676SCédric Le Goater qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
36892499676SCédric Le Goater HWADDR_PRIx "\n", addr >> 3);
36992499676SCédric Le Goater }
37092499676SCédric Le Goater
37192499676SCédric Le Goater static const MemoryRegionOps pnv_homer_power10_pba_ops = {
37292499676SCédric Le Goater .read = pnv_homer_power10_pba_read,
37392499676SCédric Le Goater .write = pnv_homer_power10_pba_write,
37492499676SCédric Le Goater .valid.min_access_size = 8,
37592499676SCédric Le Goater .valid.max_access_size = 8,
37692499676SCédric Le Goater .impl.min_access_size = 8,
37792499676SCédric Le Goater .impl.max_access_size = 8,
37892499676SCédric Le Goater .endianness = DEVICE_BIG_ENDIAN,
37992499676SCédric Le Goater };
38092499676SCédric Le Goater
pnv_homer_power10_class_init(ObjectClass * klass,void * data)38192499676SCédric Le Goater static void pnv_homer_power10_class_init(ObjectClass *klass, void *data)
38292499676SCédric Le Goater {
38392499676SCédric Le Goater PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
38492499676SCédric Le Goater
38592499676SCédric Le Goater homer->pba_size = PNV10_XSCOM_PBA_SIZE;
38692499676SCédric Le Goater homer->pba_ops = &pnv_homer_power10_pba_ops;
38792499676SCédric Le Goater homer->homer_size = PNV10_HOMER_SIZE;
38892499676SCédric Le Goater homer->homer_ops = &pnv_power9_homer_ops; /* TODO */
38992499676SCédric Le Goater homer->core_max_base = PNV9_CORE_MAX_BASE;
39092499676SCédric Le Goater }
39192499676SCédric Le Goater
39292499676SCédric Le Goater static const TypeInfo pnv_homer_power10_type_info = {
39392499676SCédric Le Goater .name = TYPE_PNV10_HOMER,
39492499676SCédric Le Goater .parent = TYPE_PNV_HOMER,
39592499676SCédric Le Goater .instance_size = sizeof(PnvHomer),
39692499676SCédric Le Goater .class_init = pnv_homer_power10_class_init,
39792499676SCédric Le Goater };
39892499676SCédric Le Goater
pnv_homer_realize(DeviceState * dev,Error ** errp)3993887d241SBalamuruhan S static void pnv_homer_realize(DeviceState *dev, Error **errp)
4003887d241SBalamuruhan S {
4013887d241SBalamuruhan S PnvHomer *homer = PNV_HOMER(dev);
4023887d241SBalamuruhan S PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer);
4033887d241SBalamuruhan S
404f2582acfSGreg Kurz assert(homer->chip);
405f2582acfSGreg Kurz
4068f092316SCédric Le Goater pnv_xscom_region_init(&homer->pba_regs, OBJECT(dev), hmrc->pba_ops,
4078f092316SCédric Le Goater homer, "xscom-pba", hmrc->pba_size);
4088f092316SCédric Le Goater
4093887d241SBalamuruhan S /* homer region */
4103887d241SBalamuruhan S memory_region_init_io(&homer->regs, OBJECT(dev),
4113887d241SBalamuruhan S hmrc->homer_ops, homer, "homer-main-memory",
4123887d241SBalamuruhan S hmrc->homer_size);
4133887d241SBalamuruhan S }
4143887d241SBalamuruhan S
415f2582acfSGreg Kurz static Property pnv_homer_properties[] = {
416f2582acfSGreg Kurz DEFINE_PROP_LINK("chip", PnvHomer, chip, TYPE_PNV_CHIP, PnvChip *),
417f2582acfSGreg Kurz DEFINE_PROP_END_OF_LIST(),
418f2582acfSGreg Kurz };
419f2582acfSGreg Kurz
pnv_homer_class_init(ObjectClass * klass,void * data)4203887d241SBalamuruhan S static void pnv_homer_class_init(ObjectClass *klass, void *data)
4213887d241SBalamuruhan S {
4223887d241SBalamuruhan S DeviceClass *dc = DEVICE_CLASS(klass);
4233887d241SBalamuruhan S
4243887d241SBalamuruhan S dc->realize = pnv_homer_realize;
4253887d241SBalamuruhan S dc->desc = "PowerNV HOMER Memory";
4264f67d30bSMarc-André Lureau device_class_set_props(dc, pnv_homer_properties);
42723a782ebSCédric Le Goater dc->user_creatable = false;
4283887d241SBalamuruhan S }
4293887d241SBalamuruhan S
4303887d241SBalamuruhan S static const TypeInfo pnv_homer_type_info = {
4313887d241SBalamuruhan S .name = TYPE_PNV_HOMER,
4323887d241SBalamuruhan S .parent = TYPE_DEVICE,
4333887d241SBalamuruhan S .instance_size = sizeof(PnvHomer),
4343887d241SBalamuruhan S .class_init = pnv_homer_class_init,
4353887d241SBalamuruhan S .class_size = sizeof(PnvHomerClass),
4363887d241SBalamuruhan S .abstract = true,
4373887d241SBalamuruhan S };
4383887d241SBalamuruhan S
pnv_homer_register_types(void)4393887d241SBalamuruhan S static void pnv_homer_register_types(void)
4403887d241SBalamuruhan S {
4413887d241SBalamuruhan S type_register_static(&pnv_homer_type_info);
4423887d241SBalamuruhan S type_register_static(&pnv_homer_power8_type_info);
4433887d241SBalamuruhan S type_register_static(&pnv_homer_power9_type_info);
44492499676SCédric Le Goater type_register_static(&pnv_homer_power10_type_info);
4453887d241SBalamuruhan S }
4463887d241SBalamuruhan S
4473887d241SBalamuruhan S type_init(pnv_homer_register_types);
448