2
0

iotkit-secctl.c 24 KB

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