1 /* 2 * Arm IoT Kit security controller 3 * 4 * Copyright (c) 2018 Linaro Limited 5 * Written by Peter Maydell 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 or 9 * (at your option) any later version. 10 */ 11 12 #include "qemu/osdep.h" 13 #include "qemu/log.h" 14 #include "qemu/module.h" 15 #include "qapi/error.h" 16 #include "trace.h" 17 #include "hw/sysbus.h" 18 #include "hw/registerfields.h" 19 #include "hw/irq.h" 20 #include "hw/misc/iotkit-secctl.h" 21 22 /* Registers in the secure privilege control block */ 23 REG32(SECRESPCFG, 0x10) 24 REG32(NSCCFG, 0x14) 25 REG32(SECMPCINTSTATUS, 0x1c) 26 REG32(SECPPCINTSTAT, 0x20) 27 REG32(SECPPCINTCLR, 0x24) 28 REG32(SECPPCINTEN, 0x28) 29 REG32(SECMSCINTSTAT, 0x30) 30 REG32(SECMSCINTCLR, 0x34) 31 REG32(SECMSCINTEN, 0x38) 32 REG32(BRGINTSTAT, 0x40) 33 REG32(BRGINTCLR, 0x44) 34 REG32(BRGINTEN, 0x48) 35 REG32(AHBNSPPC0, 0x50) 36 REG32(AHBNSPPCEXP0, 0x60) 37 REG32(AHBNSPPCEXP1, 0x64) 38 REG32(AHBNSPPCEXP2, 0x68) 39 REG32(AHBNSPPCEXP3, 0x6c) 40 REG32(APBNSPPC0, 0x70) 41 REG32(APBNSPPC1, 0x74) 42 REG32(APBNSPPCEXP0, 0x80) 43 REG32(APBNSPPCEXP1, 0x84) 44 REG32(APBNSPPCEXP2, 0x88) 45 REG32(APBNSPPCEXP3, 0x8c) 46 REG32(AHBSPPPC0, 0x90) 47 REG32(AHBSPPPCEXP0, 0xa0) 48 REG32(AHBSPPPCEXP1, 0xa4) 49 REG32(AHBSPPPCEXP2, 0xa8) 50 REG32(AHBSPPPCEXP3, 0xac) 51 REG32(APBSPPPC0, 0xb0) 52 REG32(APBSPPPC1, 0xb4) 53 REG32(APBSPPPCEXP0, 0xc0) 54 REG32(APBSPPPCEXP1, 0xc4) 55 REG32(APBSPPPCEXP2, 0xc8) 56 REG32(APBSPPPCEXP3, 0xcc) 57 REG32(NSMSCEXP, 0xd0) 58 REG32(PID4, 0xfd0) 59 REG32(PID5, 0xfd4) 60 REG32(PID6, 0xfd8) 61 REG32(PID7, 0xfdc) 62 REG32(PID0, 0xfe0) 63 REG32(PID1, 0xfe4) 64 REG32(PID2, 0xfe8) 65 REG32(PID3, 0xfec) 66 REG32(CID0, 0xff0) 67 REG32(CID1, 0xff4) 68 REG32(CID2, 0xff8) 69 REG32(CID3, 0xffc) 70 71 /* Registers in the non-secure privilege control block */ 72 REG32(AHBNSPPPC0, 0x90) 73 REG32(AHBNSPPPCEXP0, 0xa0) 74 REG32(AHBNSPPPCEXP1, 0xa4) 75 REG32(AHBNSPPPCEXP2, 0xa8) 76 REG32(AHBNSPPPCEXP3, 0xac) 77 REG32(APBNSPPPC0, 0xb0) 78 REG32(APBNSPPPC1, 0xb4) 79 REG32(APBNSPPPCEXP0, 0xc0) 80 REG32(APBNSPPPCEXP1, 0xc4) 81 REG32(APBNSPPPCEXP2, 0xc8) 82 REG32(APBNSPPPCEXP3, 0xcc) 83 /* PID and CID registers are also present in the NS block */ 84 85 static const uint8_t iotkit_secctl_s_idregs[] = { 86 0x04, 0x00, 0x00, 0x00, 87 0x52, 0xb8, 0x0b, 0x00, 88 0x0d, 0xf0, 0x05, 0xb1, 89 }; 90 91 static const uint8_t iotkit_secctl_ns_idregs[] = { 92 0x04, 0x00, 0x00, 0x00, 93 0x53, 0xb8, 0x0b, 0x00, 94 0x0d, 0xf0, 0x05, 0xb1, 95 }; 96 97 /* The register sets for the various PPCs (AHB internal, APB internal, 98 * AHB expansion, APB expansion) are all set up so that they are 99 * in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs 100 * 0, 1, 2, 3 of that type, so we can convert a register address offset 101 * into an an index into a PPC array easily. 102 */ 103 static inline int offset_to_ppc_idx(uint32_t offset) 104 { 105 return extract32(offset, 2, 2); 106 } 107 108 typedef void PerPPCFunction(IoTKitSecCtlPPC *ppc); 109 110 static void foreach_ppc(IoTKitSecCtl *s, PerPPCFunction *fn) 111 { 112 int i; 113 114 for (i = 0; i < IOTS_NUM_APB_PPC; i++) { 115 fn(&s->apb[i]); 116 } 117 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) { 118 fn(&s->apbexp[i]); 119 } 120 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) { 121 fn(&s->ahbexp[i]); 122 } 123 } 124 125 static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr, 126 uint64_t *pdata, 127 unsigned size, MemTxAttrs attrs) 128 { 129 uint64_t r; 130 uint32_t offset = addr & ~0x3; 131 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 132 133 switch (offset) { 134 case A_AHBNSPPC0: 135 case A_AHBSPPPC0: 136 r = 0; 137 break; 138 case A_SECRESPCFG: 139 r = s->secrespcfg; 140 break; 141 case A_NSCCFG: 142 r = s->nsccfg; 143 break; 144 case A_SECMPCINTSTATUS: 145 r = s->mpcintstatus; 146 break; 147 case A_SECPPCINTSTAT: 148 r = s->secppcintstat; 149 break; 150 case A_SECPPCINTEN: 151 r = s->secppcinten; 152 break; 153 case A_BRGINTSTAT: 154 /* QEMU's bus fabric can never report errors as it doesn't buffer 155 * writes, so we never report bridge interrupts. 156 */ 157 r = 0; 158 break; 159 case A_BRGINTEN: 160 r = s->brginten; 161 break; 162 case A_AHBNSPPCEXP0: 163 case A_AHBNSPPCEXP1: 164 case A_AHBNSPPCEXP2: 165 case A_AHBNSPPCEXP3: 166 r = s->ahbexp[offset_to_ppc_idx(offset)].ns; 167 break; 168 case A_APBNSPPC0: 169 case A_APBNSPPC1: 170 r = s->apb[offset_to_ppc_idx(offset)].ns; 171 break; 172 case A_APBNSPPCEXP0: 173 case A_APBNSPPCEXP1: 174 case A_APBNSPPCEXP2: 175 case A_APBNSPPCEXP3: 176 r = s->apbexp[offset_to_ppc_idx(offset)].ns; 177 break; 178 case A_AHBSPPPCEXP0: 179 case A_AHBSPPPCEXP1: 180 case A_AHBSPPPCEXP2: 181 case A_AHBSPPPCEXP3: 182 r = s->apbexp[offset_to_ppc_idx(offset)].sp; 183 break; 184 case A_APBSPPPC0: 185 case A_APBSPPPC1: 186 r = s->apb[offset_to_ppc_idx(offset)].sp; 187 break; 188 case A_APBSPPPCEXP0: 189 case A_APBSPPPCEXP1: 190 case A_APBSPPPCEXP2: 191 case A_APBSPPPCEXP3: 192 r = s->apbexp[offset_to_ppc_idx(offset)].sp; 193 break; 194 case A_SECMSCINTSTAT: 195 r = s->secmscintstat; 196 break; 197 case A_SECMSCINTEN: 198 r = s->secmscinten; 199 break; 200 case A_NSMSCEXP: 201 r = s->nsmscexp; 202 break; 203 case A_PID4: 204 case A_PID5: 205 case A_PID6: 206 case A_PID7: 207 case A_PID0: 208 case A_PID1: 209 case A_PID2: 210 case A_PID3: 211 case A_CID0: 212 case A_CID1: 213 case A_CID2: 214 case A_CID3: 215 r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4]; 216 break; 217 case A_SECPPCINTCLR: 218 case A_SECMSCINTCLR: 219 case A_BRGINTCLR: 220 qemu_log_mask(LOG_GUEST_ERROR, 221 "IotKit SecCtl S block read: write-only offset 0x%x\n", 222 offset); 223 r = 0; 224 break; 225 default: 226 qemu_log_mask(LOG_GUEST_ERROR, 227 "IotKit SecCtl S block read: bad offset 0x%x\n", offset); 228 r = 0; 229 break; 230 } 231 232 if (size != 4) { 233 /* None of our registers are access-sensitive, so just pull the right 234 * byte out of the word read result. 235 */ 236 r = extract32(r, (addr & 3) * 8, size * 8); 237 } 238 239 trace_iotkit_secctl_s_read(offset, r, size); 240 *pdata = r; 241 return MEMTX_OK; 242 } 243 244 static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc) 245 { 246 int i; 247 248 for (i = 0; i < ppc->numports; i++) { 249 bool v; 250 251 if (extract32(ppc->ns, i, 1)) { 252 v = extract32(ppc->nsp, i, 1); 253 } else { 254 v = extract32(ppc->sp, i, 1); 255 } 256 qemu_set_irq(ppc->ap[i], v); 257 } 258 } 259 260 static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value) 261 { 262 int i; 263 264 ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports); 265 for (i = 0; i < ppc->numports; i++) { 266 qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1)); 267 } 268 iotkit_secctl_update_ppc_ap(ppc); 269 } 270 271 static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value) 272 { 273 ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports); 274 iotkit_secctl_update_ppc_ap(ppc); 275 } 276 277 static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value) 278 { 279 ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports); 280 iotkit_secctl_update_ppc_ap(ppc); 281 } 282 283 static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc) 284 { 285 uint32_t value = ppc->parent->secppcintstat; 286 287 qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1)); 288 } 289 290 static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc) 291 { 292 uint32_t value = ppc->parent->secppcinten; 293 294 qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1)); 295 } 296 297 static void iotkit_secctl_update_mscexp_irqs(qemu_irq *msc_irqs, uint32_t value) 298 { 299 int i; 300 301 for (i = 0; i < IOTS_NUM_EXP_MSC; i++) { 302 qemu_set_irq(msc_irqs[i], extract32(value, i + 16, 1)); 303 } 304 } 305 306 static void iotkit_secctl_update_msc_irq(IoTKitSecCtl *s) 307 { 308 /* Update the combined MSC IRQ, based on S_MSCEXP_STATUS and S_MSCEXP_EN */ 309 bool level = s->secmscintstat & s->secmscinten; 310 311 qemu_set_irq(s->msc_irq, level); 312 } 313 314 static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr, 315 uint64_t value, 316 unsigned size, MemTxAttrs attrs) 317 { 318 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 319 uint32_t offset = addr; 320 IoTKitSecCtlPPC *ppc; 321 322 trace_iotkit_secctl_s_write(offset, value, size); 323 324 if (size != 4) { 325 /* Byte and halfword writes are ignored */ 326 qemu_log_mask(LOG_GUEST_ERROR, 327 "IotKit SecCtl S block write: bad size, ignored\n"); 328 return MEMTX_OK; 329 } 330 331 switch (offset) { 332 case A_NSCCFG: 333 s->nsccfg = value & 3; 334 qemu_set_irq(s->nsc_cfg_irq, s->nsccfg); 335 break; 336 case A_SECRESPCFG: 337 value &= 1; 338 s->secrespcfg = value; 339 qemu_set_irq(s->sec_resp_cfg, s->secrespcfg); 340 break; 341 case A_SECPPCINTCLR: 342 value &= 0x00f000f3; 343 foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear); 344 break; 345 case A_SECPPCINTEN: 346 s->secppcinten = value & 0x00f000f3; 347 foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable); 348 break; 349 case A_BRGINTCLR: 350 break; 351 case A_BRGINTEN: 352 s->brginten = value & 0xffff0000; 353 break; 354 case A_AHBNSPPCEXP0: 355 case A_AHBNSPPCEXP1: 356 case A_AHBNSPPCEXP2: 357 case A_AHBNSPPCEXP3: 358 ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; 359 iotkit_secctl_ppc_ns_write(ppc, value); 360 break; 361 case A_APBNSPPC0: 362 case A_APBNSPPC1: 363 ppc = &s->apb[offset_to_ppc_idx(offset)]; 364 iotkit_secctl_ppc_ns_write(ppc, value); 365 break; 366 case A_APBNSPPCEXP0: 367 case A_APBNSPPCEXP1: 368 case A_APBNSPPCEXP2: 369 case A_APBNSPPCEXP3: 370 ppc = &s->apbexp[offset_to_ppc_idx(offset)]; 371 iotkit_secctl_ppc_ns_write(ppc, value); 372 break; 373 case A_AHBSPPPCEXP0: 374 case A_AHBSPPPCEXP1: 375 case A_AHBSPPPCEXP2: 376 case A_AHBSPPPCEXP3: 377 ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; 378 iotkit_secctl_ppc_sp_write(ppc, value); 379 break; 380 case A_APBSPPPC0: 381 case A_APBSPPPC1: 382 ppc = &s->apb[offset_to_ppc_idx(offset)]; 383 iotkit_secctl_ppc_sp_write(ppc, value); 384 break; 385 case A_APBSPPPCEXP0: 386 case A_APBSPPPCEXP1: 387 case A_APBSPPPCEXP2: 388 case A_APBSPPPCEXP3: 389 ppc = &s->apbexp[offset_to_ppc_idx(offset)]; 390 iotkit_secctl_ppc_sp_write(ppc, value); 391 break; 392 case A_SECMSCINTCLR: 393 iotkit_secctl_update_mscexp_irqs(s->mscexp_clear, value); 394 break; 395 case A_SECMSCINTEN: 396 s->secmscinten = value; 397 iotkit_secctl_update_msc_irq(s); 398 break; 399 case A_NSMSCEXP: 400 s->nsmscexp = value; 401 iotkit_secctl_update_mscexp_irqs(s->mscexp_ns, value); 402 break; 403 case A_SECMPCINTSTATUS: 404 case A_SECPPCINTSTAT: 405 case A_SECMSCINTSTAT: 406 case A_BRGINTSTAT: 407 case A_AHBNSPPC0: 408 case A_AHBSPPPC0: 409 case A_PID4: 410 case A_PID5: 411 case A_PID6: 412 case A_PID7: 413 case A_PID0: 414 case A_PID1: 415 case A_PID2: 416 case A_PID3: 417 case A_CID0: 418 case A_CID1: 419 case A_CID2: 420 case A_CID3: 421 qemu_log_mask(LOG_GUEST_ERROR, 422 "IoTKit SecCtl S block write: " 423 "read-only offset 0x%x\n", offset); 424 break; 425 default: 426 qemu_log_mask(LOG_GUEST_ERROR, 427 "IotKit SecCtl S block write: bad offset 0x%x\n", 428 offset); 429 break; 430 } 431 432 return MEMTX_OK; 433 } 434 435 static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr, 436 uint64_t *pdata, 437 unsigned size, MemTxAttrs attrs) 438 { 439 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 440 uint64_t r; 441 uint32_t offset = addr & ~0x3; 442 443 switch (offset) { 444 case A_AHBNSPPPC0: 445 r = 0; 446 break; 447 case A_AHBNSPPPCEXP0: 448 case A_AHBNSPPPCEXP1: 449 case A_AHBNSPPPCEXP2: 450 case A_AHBNSPPPCEXP3: 451 r = s->ahbexp[offset_to_ppc_idx(offset)].nsp; 452 break; 453 case A_APBNSPPPC0: 454 case A_APBNSPPPC1: 455 r = s->apb[offset_to_ppc_idx(offset)].nsp; 456 break; 457 case A_APBNSPPPCEXP0: 458 case A_APBNSPPPCEXP1: 459 case A_APBNSPPPCEXP2: 460 case A_APBNSPPPCEXP3: 461 r = s->apbexp[offset_to_ppc_idx(offset)].nsp; 462 break; 463 case A_PID4: 464 case A_PID5: 465 case A_PID6: 466 case A_PID7: 467 case A_PID0: 468 case A_PID1: 469 case A_PID2: 470 case A_PID3: 471 case A_CID0: 472 case A_CID1: 473 case A_CID2: 474 case A_CID3: 475 r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4]; 476 break; 477 default: 478 qemu_log_mask(LOG_GUEST_ERROR, 479 "IotKit SecCtl NS block write: bad offset 0x%x\n", 480 offset); 481 r = 0; 482 break; 483 } 484 485 if (size != 4) { 486 /* None of our registers are access-sensitive, so just pull the right 487 * byte out of the word read result. 488 */ 489 r = extract32(r, (addr & 3) * 8, size * 8); 490 } 491 492 trace_iotkit_secctl_ns_read(offset, r, size); 493 *pdata = r; 494 return MEMTX_OK; 495 } 496 497 static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr, 498 uint64_t value, 499 unsigned size, MemTxAttrs attrs) 500 { 501 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 502 uint32_t offset = addr; 503 IoTKitSecCtlPPC *ppc; 504 505 trace_iotkit_secctl_ns_write(offset, value, size); 506 507 if (size != 4) { 508 /* Byte and halfword writes are ignored */ 509 qemu_log_mask(LOG_GUEST_ERROR, 510 "IotKit SecCtl NS block write: bad size, ignored\n"); 511 return MEMTX_OK; 512 } 513 514 switch (offset) { 515 case A_AHBNSPPPCEXP0: 516 case A_AHBNSPPPCEXP1: 517 case A_AHBNSPPPCEXP2: 518 case A_AHBNSPPPCEXP3: 519 ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; 520 iotkit_secctl_ppc_nsp_write(ppc, value); 521 break; 522 case A_APBNSPPPC0: 523 case A_APBNSPPPC1: 524 ppc = &s->apb[offset_to_ppc_idx(offset)]; 525 iotkit_secctl_ppc_nsp_write(ppc, value); 526 break; 527 case A_APBNSPPPCEXP0: 528 case A_APBNSPPPCEXP1: 529 case A_APBNSPPPCEXP2: 530 case A_APBNSPPPCEXP3: 531 ppc = &s->apbexp[offset_to_ppc_idx(offset)]; 532 iotkit_secctl_ppc_nsp_write(ppc, value); 533 break; 534 case A_AHBNSPPPC0: 535 case A_PID4: 536 case A_PID5: 537 case A_PID6: 538 case A_PID7: 539 case A_PID0: 540 case A_PID1: 541 case A_PID2: 542 case A_PID3: 543 case A_CID0: 544 case A_CID1: 545 case A_CID2: 546 case A_CID3: 547 qemu_log_mask(LOG_GUEST_ERROR, 548 "IoTKit SecCtl NS block write: " 549 "read-only offset 0x%x\n", offset); 550 break; 551 default: 552 qemu_log_mask(LOG_GUEST_ERROR, 553 "IotKit SecCtl NS block write: bad offset 0x%x\n", 554 offset); 555 break; 556 } 557 558 return MEMTX_OK; 559 } 560 561 static const MemoryRegionOps iotkit_secctl_s_ops = { 562 .read_with_attrs = iotkit_secctl_s_read, 563 .write_with_attrs = iotkit_secctl_s_write, 564 .endianness = DEVICE_LITTLE_ENDIAN, 565 .valid.min_access_size = 1, 566 .valid.max_access_size = 4, 567 .impl.min_access_size = 1, 568 .impl.max_access_size = 4, 569 }; 570 571 static const MemoryRegionOps iotkit_secctl_ns_ops = { 572 .read_with_attrs = iotkit_secctl_ns_read, 573 .write_with_attrs = iotkit_secctl_ns_write, 574 .endianness = DEVICE_LITTLE_ENDIAN, 575 .valid.min_access_size = 1, 576 .valid.max_access_size = 4, 577 .impl.min_access_size = 1, 578 .impl.max_access_size = 4, 579 }; 580 581 static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc) 582 { 583 ppc->ns = 0; 584 ppc->sp = 0; 585 ppc->nsp = 0; 586 } 587 588 static void iotkit_secctl_reset(DeviceState *dev) 589 { 590 IoTKitSecCtl *s = IOTKIT_SECCTL(dev); 591 592 s->secppcintstat = 0; 593 s->secppcinten = 0; 594 s->secrespcfg = 0; 595 s->nsccfg = 0; 596 s->brginten = 0; 597 598 foreach_ppc(s, iotkit_secctl_reset_ppc); 599 } 600 601 static void iotkit_secctl_mpc_status(void *opaque, int n, int level) 602 { 603 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 604 605 s->mpcintstatus = deposit32(s->mpcintstatus, n, 1, !!level); 606 } 607 608 static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level) 609 { 610 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 611 612 s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level); 613 } 614 615 static void iotkit_secctl_mscexp_status(void *opaque, int n, int level) 616 { 617 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 618 619 s->secmscintstat = deposit32(s->secmscintstat, n + 16, 1, !!level); 620 iotkit_secctl_update_msc_irq(s); 621 } 622 623 static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level) 624 { 625 IoTKitSecCtlPPC *ppc = opaque; 626 IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent); 627 int irqbit = ppc->irq_bit_offset + n; 628 629 s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level); 630 } 631 632 static void iotkit_secctl_init_ppc(IoTKitSecCtl *s, 633 IoTKitSecCtlPPC *ppc, 634 const char *name, 635 int numports, 636 int irq_bit_offset) 637 { 638 char *gpioname; 639 DeviceState *dev = DEVICE(s); 640 641 ppc->numports = numports; 642 ppc->irq_bit_offset = irq_bit_offset; 643 ppc->parent = s; 644 645 gpioname = g_strdup_printf("%s_nonsec", name); 646 qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports); 647 g_free(gpioname); 648 gpioname = g_strdup_printf("%s_ap", name); 649 qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports); 650 g_free(gpioname); 651 gpioname = g_strdup_printf("%s_irq_enable", name); 652 qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1); 653 g_free(gpioname); 654 gpioname = g_strdup_printf("%s_irq_clear", name); 655 qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1); 656 g_free(gpioname); 657 gpioname = g_strdup_printf("%s_irq_status", name); 658 qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus, 659 ppc, gpioname, 1); 660 g_free(gpioname); 661 } 662 663 static void iotkit_secctl_init(Object *obj) 664 { 665 IoTKitSecCtl *s = IOTKIT_SECCTL(obj); 666 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 667 DeviceState *dev = DEVICE(obj); 668 int i; 669 670 iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0", 671 IOTS_APB_PPC0_NUM_PORTS, 0); 672 iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1", 673 IOTS_APB_PPC1_NUM_PORTS, 1); 674 675 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) { 676 IoTKitSecCtlPPC *ppc = &s->apbexp[i]; 677 char *ppcname = g_strdup_printf("apb_ppcexp%d", i); 678 iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i); 679 g_free(ppcname); 680 } 681 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) { 682 IoTKitSecCtlPPC *ppc = &s->ahbexp[i]; 683 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i); 684 iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i); 685 g_free(ppcname); 686 } 687 688 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1); 689 qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1); 690 691 qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status", 692 IOTS_NUM_MPC); 693 qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status, 694 "mpcexp_status", IOTS_NUM_EXP_MPC); 695 696 qdev_init_gpio_in_named(dev, iotkit_secctl_mscexp_status, 697 "mscexp_status", IOTS_NUM_EXP_MSC); 698 qdev_init_gpio_out_named(dev, s->mscexp_clear, "mscexp_clear", 699 IOTS_NUM_EXP_MSC); 700 qdev_init_gpio_out_named(dev, s->mscexp_ns, "mscexp_ns", 701 IOTS_NUM_EXP_MSC); 702 qdev_init_gpio_out_named(dev, &s->msc_irq, "msc_irq", 1); 703 704 memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops, 705 s, "iotkit-secctl-s-regs", 0x1000); 706 memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops, 707 s, "iotkit-secctl-ns-regs", 0x1000); 708 sysbus_init_mmio(sbd, &s->s_regs); 709 sysbus_init_mmio(sbd, &s->ns_regs); 710 } 711 712 static const VMStateDescription iotkit_secctl_ppc_vmstate = { 713 .name = "iotkit-secctl-ppc", 714 .version_id = 1, 715 .minimum_version_id = 1, 716 .fields = (VMStateField[]) { 717 VMSTATE_UINT32(ns, IoTKitSecCtlPPC), 718 VMSTATE_UINT32(sp, IoTKitSecCtlPPC), 719 VMSTATE_UINT32(nsp, IoTKitSecCtlPPC), 720 VMSTATE_END_OF_LIST() 721 } 722 }; 723 724 static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = { 725 .name = "iotkit-secctl-mpcintstatus", 726 .version_id = 1, 727 .minimum_version_id = 1, 728 .fields = (VMStateField[]) { 729 VMSTATE_UINT32(mpcintstatus, IoTKitSecCtl), 730 VMSTATE_END_OF_LIST() 731 } 732 }; 733 734 static bool needed_always(void *opaque) 735 { 736 return true; 737 } 738 739 static const VMStateDescription iotkit_secctl_msc_vmstate = { 740 .name = "iotkit-secctl/msc", 741 .version_id = 1, 742 .minimum_version_id = 1, 743 .needed = needed_always, 744 .fields = (VMStateField[]) { 745 VMSTATE_UINT32(secmscintstat, IoTKitSecCtl), 746 VMSTATE_UINT32(secmscinten, IoTKitSecCtl), 747 VMSTATE_UINT32(nsmscexp, IoTKitSecCtl), 748 VMSTATE_END_OF_LIST() 749 } 750 }; 751 752 static const VMStateDescription iotkit_secctl_vmstate = { 753 .name = "iotkit-secctl", 754 .version_id = 1, 755 .minimum_version_id = 1, 756 .fields = (VMStateField[]) { 757 VMSTATE_UINT32(secppcintstat, IoTKitSecCtl), 758 VMSTATE_UINT32(secppcinten, IoTKitSecCtl), 759 VMSTATE_UINT32(secrespcfg, IoTKitSecCtl), 760 VMSTATE_UINT32(nsccfg, IoTKitSecCtl), 761 VMSTATE_UINT32(brginten, IoTKitSecCtl), 762 VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1, 763 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), 764 VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1, 765 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), 766 VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1, 767 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), 768 VMSTATE_END_OF_LIST() 769 }, 770 .subsections = (const VMStateDescription*[]) { 771 &iotkit_secctl_mpcintstatus_vmstate, 772 &iotkit_secctl_msc_vmstate, 773 NULL 774 }, 775 }; 776 777 static void iotkit_secctl_class_init(ObjectClass *klass, void *data) 778 { 779 DeviceClass *dc = DEVICE_CLASS(klass); 780 781 dc->vmsd = &iotkit_secctl_vmstate; 782 dc->reset = iotkit_secctl_reset; 783 } 784 785 static const TypeInfo iotkit_secctl_info = { 786 .name = TYPE_IOTKIT_SECCTL, 787 .parent = TYPE_SYS_BUS_DEVICE, 788 .instance_size = sizeof(IoTKitSecCtl), 789 .instance_init = iotkit_secctl_init, 790 .class_init = iotkit_secctl_class_init, 791 }; 792 793 static void iotkit_secctl_register_types(void) 794 { 795 type_register_static(&iotkit_secctl_info); 796 } 797 798 type_init(iotkit_secctl_register_types); 799