iotkit-secctl.c 22 KB

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