1 /* 2 * QEMU PowerPC PowerNV ADU unit 3 * 4 * The ADU unit actually implements XSCOM, which is the bridge between MMIO 5 * and PIB. However it also includes control and status registers and other 6 * functions that are exposed as PIB (xscom) registers. 7 * 8 * To keep things simple, pnv_xscom.c remains the XSCOM bridge 9 * implementation, and pnv_adu.c implements the ADU registers and other 10 * functions. 11 * 12 * Copyright (c) 2024, IBM Corporation. 13 * 14 * SPDX-License-Identifier: GPL-2.0-or-later 15 */ 16 17 #include "qemu/osdep.h" 18 #include "qemu/log.h" 19 20 #include "hw/qdev-properties.h" 21 #include "hw/ppc/pnv.h" 22 #include "hw/ppc/pnv_adu.h" 23 #include "hw/ppc/pnv_chip.h" 24 #include "hw/ppc/pnv_xscom.h" 25 #include "trace.h" 26 27 static uint64_t pnv_adu_xscom_read(void *opaque, hwaddr addr, unsigned width) 28 { 29 uint32_t offset = addr >> 3; 30 uint64_t val = 0; 31 32 switch (offset) { 33 case 0x18: /* Receive status reg */ 34 case 0x12: /* log register */ 35 case 0x13: /* error register */ 36 break; 37 38 default: 39 qemu_log_mask(LOG_UNIMP, "ADU Unimplemented read register: Ox%08x\n", 40 offset); 41 } 42 43 trace_pnv_adu_xscom_read(addr, val); 44 45 return val; 46 } 47 48 static void pnv_adu_xscom_write(void *opaque, hwaddr addr, uint64_t val, 49 unsigned width) 50 { 51 uint32_t offset = addr >> 3; 52 53 trace_pnv_adu_xscom_write(addr, val); 54 55 switch (offset) { 56 case 0x18: /* Receive status reg */ 57 case 0x12: /* log register */ 58 case 0x13: /* error register */ 59 break; 60 61 default: 62 qemu_log_mask(LOG_UNIMP, "ADU Unimplemented write register: Ox%08x\n", 63 offset); 64 } 65 } 66 67 const MemoryRegionOps pnv_adu_xscom_ops = { 68 .read = pnv_adu_xscom_read, 69 .write = pnv_adu_xscom_write, 70 .valid.min_access_size = 8, 71 .valid.max_access_size = 8, 72 .impl.min_access_size = 8, 73 .impl.max_access_size = 8, 74 .endianness = DEVICE_BIG_ENDIAN, 75 }; 76 77 static void pnv_adu_realize(DeviceState *dev, Error **errp) 78 { 79 PnvADU *adu = PNV_ADU(dev); 80 81 /* XScom regions for ADU registers */ 82 pnv_xscom_region_init(&adu->xscom_regs, OBJECT(dev), 83 &pnv_adu_xscom_ops, adu, "xscom-adu", 84 PNV9_XSCOM_ADU_SIZE); 85 } 86 87 static void pnv_adu_class_init(ObjectClass *klass, void *data) 88 { 89 DeviceClass *dc = DEVICE_CLASS(klass); 90 91 dc->realize = pnv_adu_realize; 92 dc->desc = "PowerNV ADU"; 93 dc->user_creatable = false; 94 } 95 96 static const TypeInfo pnv_adu_type_info = { 97 .name = TYPE_PNV_ADU, 98 .parent = TYPE_DEVICE, 99 .instance_size = sizeof(PnvADU), 100 .class_init = pnv_adu_class_init, 101 .interfaces = (InterfaceInfo[]) { 102 { TYPE_PNV_XSCOM_INTERFACE }, 103 { } }, 104 }; 105 106 static void pnv_adu_register_types(void) 107 { 108 type_register_static(&pnv_adu_type_info); 109 } 110 111 type_init(pnv_adu_register_types); 112