1 /* 2 * QEMU PowerPC PowerNV Emulation of a few OCC related registers 3 * 4 * Copyright (c) 2015-2017, 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 "target/ppc/cpu.h" 21 #include "qapi/error.h" 22 #include "qemu/log.h" 23 #include "qemu/module.h" 24 #include "hw/irq.h" 25 #include "hw/qdev-properties.h" 26 #include "hw/ppc/pnv.h" 27 #include "hw/ppc/pnv_xscom.h" 28 #include "hw/ppc/pnv_occ.h" 29 30 #define OCB_OCI_OCCMISC 0x4020 31 #define OCB_OCI_OCCMISC_AND 0x4021 32 #define OCB_OCI_OCCMISC_OR 0x4022 33 34 /* OCC sensors */ 35 #define OCC_SENSOR_DATA_BLOCK_OFFSET 0x580000 36 #define OCC_SENSOR_DATA_VALID 0x580001 37 #define OCC_SENSOR_DATA_VERSION 0x580002 38 #define OCC_SENSOR_DATA_READING_VERSION 0x580004 39 #define OCC_SENSOR_DATA_NR_SENSORS 0x580008 40 #define OCC_SENSOR_DATA_NAMES_OFFSET 0x580010 41 #define OCC_SENSOR_DATA_READING_PING_OFFSET 0x580014 42 #define OCC_SENSOR_DATA_READING_PONG_OFFSET 0x58000c 43 #define OCC_SENSOR_DATA_NAME_LENGTH 0x58000d 44 #define OCC_SENSOR_NAME_STRUCTURE_TYPE 0x580023 45 #define OCC_SENSOR_LOC_CORE 0x580022 46 #define OCC_SENSOR_LOC_GPU 0x580020 47 #define OCC_SENSOR_TYPE_POWER 0x580003 48 #define OCC_SENSOR_NAME 0x580005 49 #define HWMON_SENSORS_MASK 0x58001e 50 #define SLW_IMAGE_BASE 0x0 51 52 static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val) 53 { 54 bool irq_state; 55 56 val &= 0xffff000000000000ull; 57 58 occ->occmisc = val; 59 irq_state = !!(val >> 63); 60 qemu_set_irq(occ->psi_irq, irq_state); 61 } 62 63 static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr, 64 unsigned size) 65 { 66 PnvOCC *occ = PNV_OCC(opaque); 67 uint32_t offset = addr >> 3; 68 uint64_t val = 0; 69 70 switch (offset) { 71 case OCB_OCI_OCCMISC: 72 val = occ->occmisc; 73 break; 74 default: 75 qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%" 76 HWADDR_PRIx "\n", addr >> 3); 77 } 78 return val; 79 } 80 81 static void pnv_occ_power8_xscom_write(void *opaque, hwaddr addr, 82 uint64_t val, unsigned size) 83 { 84 PnvOCC *occ = PNV_OCC(opaque); 85 uint32_t offset = addr >> 3; 86 87 switch (offset) { 88 case OCB_OCI_OCCMISC_AND: 89 pnv_occ_set_misc(occ, occ->occmisc & val); 90 break; 91 case OCB_OCI_OCCMISC_OR: 92 pnv_occ_set_misc(occ, occ->occmisc | val); 93 break; 94 case OCB_OCI_OCCMISC: 95 pnv_occ_set_misc(occ, val); 96 break; 97 default: 98 qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%" 99 HWADDR_PRIx "\n", addr >> 3); 100 } 101 } 102 103 static uint64_t pnv_occ_common_area_read(void *opaque, hwaddr addr, 104 unsigned width) 105 { 106 switch (addr) { 107 /* 108 * occ-sensor sanity check that asserts the sensor 109 * header block 110 */ 111 case OCC_SENSOR_DATA_BLOCK_OFFSET: 112 case OCC_SENSOR_DATA_VALID: 113 case OCC_SENSOR_DATA_VERSION: 114 case OCC_SENSOR_DATA_READING_VERSION: 115 case OCC_SENSOR_DATA_NR_SENSORS: 116 case OCC_SENSOR_DATA_NAMES_OFFSET: 117 case OCC_SENSOR_DATA_READING_PING_OFFSET: 118 case OCC_SENSOR_DATA_READING_PONG_OFFSET: 119 case OCC_SENSOR_NAME_STRUCTURE_TYPE: 120 return 1; 121 case OCC_SENSOR_DATA_NAME_LENGTH: 122 return 0x30; 123 case OCC_SENSOR_LOC_CORE: 124 return 0x0040; 125 case OCC_SENSOR_TYPE_POWER: 126 return 0x0080; 127 case OCC_SENSOR_NAME: 128 return 0x1000; 129 case HWMON_SENSORS_MASK: 130 case OCC_SENSOR_LOC_GPU: 131 return 0x8e00; 132 case SLW_IMAGE_BASE: 133 return 0x1000000000000000; 134 } 135 return 0; 136 } 137 138 static void pnv_occ_common_area_write(void *opaque, hwaddr addr, 139 uint64_t val, unsigned width) 140 { 141 /* callback function defined to occ common area write */ 142 return; 143 } 144 145 static const MemoryRegionOps pnv_occ_power8_xscom_ops = { 146 .read = pnv_occ_power8_xscom_read, 147 .write = pnv_occ_power8_xscom_write, 148 .valid.min_access_size = 8, 149 .valid.max_access_size = 8, 150 .impl.min_access_size = 8, 151 .impl.max_access_size = 8, 152 .endianness = DEVICE_BIG_ENDIAN, 153 }; 154 155 const MemoryRegionOps pnv_occ_sram_ops = { 156 .read = pnv_occ_common_area_read, 157 .write = pnv_occ_common_area_write, 158 .valid.min_access_size = 1, 159 .valid.max_access_size = 8, 160 .impl.min_access_size = 1, 161 .impl.max_access_size = 8, 162 .endianness = DEVICE_BIG_ENDIAN, 163 }; 164 165 static void pnv_occ_power8_class_init(ObjectClass *klass, void *data) 166 { 167 PnvOCCClass *poc = PNV_OCC_CLASS(klass); 168 169 poc->xscom_size = PNV_XSCOM_OCC_SIZE; 170 poc->xscom_ops = &pnv_occ_power8_xscom_ops; 171 } 172 173 static const TypeInfo pnv_occ_power8_type_info = { 174 .name = TYPE_PNV8_OCC, 175 .parent = TYPE_PNV_OCC, 176 .instance_size = sizeof(PnvOCC), 177 .class_init = pnv_occ_power8_class_init, 178 }; 179 180 #define P9_OCB_OCI_OCCMISC 0x6080 181 #define P9_OCB_OCI_OCCMISC_CLEAR 0x6081 182 #define P9_OCB_OCI_OCCMISC_OR 0x6082 183 184 185 static uint64_t pnv_occ_power9_xscom_read(void *opaque, hwaddr addr, 186 unsigned size) 187 { 188 PnvOCC *occ = PNV_OCC(opaque); 189 uint32_t offset = addr >> 3; 190 uint64_t val = 0; 191 192 switch (offset) { 193 case P9_OCB_OCI_OCCMISC: 194 val = occ->occmisc; 195 break; 196 default: 197 qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%" 198 HWADDR_PRIx "\n", addr >> 3); 199 } 200 return val; 201 } 202 203 static void pnv_occ_power9_xscom_write(void *opaque, hwaddr addr, 204 uint64_t val, unsigned size) 205 { 206 PnvOCC *occ = PNV_OCC(opaque); 207 uint32_t offset = addr >> 3; 208 209 switch (offset) { 210 case P9_OCB_OCI_OCCMISC_CLEAR: 211 pnv_occ_set_misc(occ, 0); 212 break; 213 case P9_OCB_OCI_OCCMISC_OR: 214 pnv_occ_set_misc(occ, occ->occmisc | val); 215 break; 216 case P9_OCB_OCI_OCCMISC: 217 pnv_occ_set_misc(occ, val); 218 break; 219 default: 220 qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%" 221 HWADDR_PRIx "\n", addr >> 3); 222 } 223 } 224 225 static const MemoryRegionOps pnv_occ_power9_xscom_ops = { 226 .read = pnv_occ_power9_xscom_read, 227 .write = pnv_occ_power9_xscom_write, 228 .valid.min_access_size = 8, 229 .valid.max_access_size = 8, 230 .impl.min_access_size = 8, 231 .impl.max_access_size = 8, 232 .endianness = DEVICE_BIG_ENDIAN, 233 }; 234 235 static void pnv_occ_power9_class_init(ObjectClass *klass, void *data) 236 { 237 PnvOCCClass *poc = PNV_OCC_CLASS(klass); 238 DeviceClass *dc = DEVICE_CLASS(klass); 239 240 dc->desc = "PowerNV OCC Controller (POWER9)"; 241 poc->xscom_size = PNV9_XSCOM_OCC_SIZE; 242 poc->xscom_ops = &pnv_occ_power9_xscom_ops; 243 } 244 245 static const TypeInfo pnv_occ_power9_type_info = { 246 .name = TYPE_PNV9_OCC, 247 .parent = TYPE_PNV_OCC, 248 .instance_size = sizeof(PnvOCC), 249 .class_init = pnv_occ_power9_class_init, 250 }; 251 252 static void pnv_occ_power10_class_init(ObjectClass *klass, void *data) 253 { 254 DeviceClass *dc = DEVICE_CLASS(klass); 255 256 dc->desc = "PowerNV OCC Controller (POWER10)"; 257 } 258 259 static const TypeInfo pnv_occ_power10_type_info = { 260 .name = TYPE_PNV10_OCC, 261 .parent = TYPE_PNV9_OCC, 262 .class_init = pnv_occ_power10_class_init, 263 }; 264 265 static void pnv_occ_realize(DeviceState *dev, Error **errp) 266 { 267 PnvOCC *occ = PNV_OCC(dev); 268 PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ); 269 270 occ->occmisc = 0; 271 272 /* XScom region for OCC registers */ 273 pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), poc->xscom_ops, 274 occ, "xscom-occ", poc->xscom_size); 275 276 /* OCC common area mmio region for OCC SRAM registers */ 277 memory_region_init_io(&occ->sram_regs, OBJECT(dev), &pnv_occ_sram_ops, 278 occ, "occ-common-area", 279 PNV_OCC_SENSOR_DATA_BLOCK_SIZE); 280 281 qdev_init_gpio_out(DEVICE(dev), &occ->psi_irq, 1); 282 } 283 284 static void pnv_occ_class_init(ObjectClass *klass, void *data) 285 { 286 DeviceClass *dc = DEVICE_CLASS(klass); 287 288 dc->realize = pnv_occ_realize; 289 dc->desc = "PowerNV OCC Controller"; 290 dc->user_creatable = false; 291 } 292 293 static const TypeInfo pnv_occ_type_info = { 294 .name = TYPE_PNV_OCC, 295 .parent = TYPE_DEVICE, 296 .instance_size = sizeof(PnvOCC), 297 .class_init = pnv_occ_class_init, 298 .class_size = sizeof(PnvOCCClass), 299 .abstract = true, 300 }; 301 302 static void pnv_occ_register_types(void) 303 { 304 type_register_static(&pnv_occ_type_info); 305 type_register_static(&pnv_occ_power8_type_info); 306 type_register_static(&pnv_occ_power9_type_info); 307 type_register_static(&pnv_occ_power10_type_info); 308 } 309 310 type_init(pnv_occ_register_types); 311