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