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