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