tz-ppc.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /*
  2. * ARM TrustZone peripheral protection controller emulation
  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/tz-ppc.h"
  21. #include "hw/qdev-properties.h"
  22. static void tz_ppc_update_irq(TZPPC *s)
  23. {
  24. bool level = s->irq_status && s->irq_enable;
  25. trace_tz_ppc_update_irq(level);
  26. qemu_set_irq(s->irq, level);
  27. }
  28. static void tz_ppc_cfg_nonsec(void *opaque, int n, int level)
  29. {
  30. TZPPC *s = TZ_PPC(opaque);
  31. assert(n < TZ_NUM_PORTS);
  32. trace_tz_ppc_cfg_nonsec(n, level);
  33. s->cfg_nonsec[n] = level;
  34. }
  35. static void tz_ppc_cfg_ap(void *opaque, int n, int level)
  36. {
  37. TZPPC *s = TZ_PPC(opaque);
  38. assert(n < TZ_NUM_PORTS);
  39. trace_tz_ppc_cfg_ap(n, level);
  40. s->cfg_ap[n] = level;
  41. }
  42. static void tz_ppc_cfg_sec_resp(void *opaque, int n, int level)
  43. {
  44. TZPPC *s = TZ_PPC(opaque);
  45. trace_tz_ppc_cfg_sec_resp(level);
  46. s->cfg_sec_resp = level;
  47. }
  48. static void tz_ppc_irq_enable(void *opaque, int n, int level)
  49. {
  50. TZPPC *s = TZ_PPC(opaque);
  51. trace_tz_ppc_irq_enable(level);
  52. s->irq_enable = level;
  53. tz_ppc_update_irq(s);
  54. }
  55. static void tz_ppc_irq_clear(void *opaque, int n, int level)
  56. {
  57. TZPPC *s = TZ_PPC(opaque);
  58. trace_tz_ppc_irq_clear(level);
  59. s->irq_clear = level;
  60. if (level) {
  61. s->irq_status = false;
  62. tz_ppc_update_irq(s);
  63. }
  64. }
  65. static bool tz_ppc_check(TZPPC *s, int n, MemTxAttrs attrs)
  66. {
  67. /* Check whether to allow an access to port n; return true if
  68. * the check passes, and false if the transaction must be blocked.
  69. * If the latter, the caller must check cfg_sec_resp to determine
  70. * whether to abort or RAZ/WI the transaction.
  71. * The checks are:
  72. * + nonsec_mask suppresses any check of the secure attribute
  73. * + otherwise, block if cfg_nonsec is 1 and transaction is secure,
  74. * or if cfg_nonsec is 0 and transaction is non-secure
  75. * + block if transaction is usermode and cfg_ap is 0
  76. */
  77. if ((attrs.secure == s->cfg_nonsec[n] && !(s->nonsec_mask & (1 << n))) ||
  78. (attrs.user && !s->cfg_ap[n])) {
  79. /* Block the transaction. */
  80. if (!s->irq_clear) {
  81. /* Note that holding irq_clear high suppresses interrupts */
  82. s->irq_status = true;
  83. tz_ppc_update_irq(s);
  84. }
  85. return false;
  86. }
  87. return true;
  88. }
  89. static MemTxResult tz_ppc_read(void *opaque, hwaddr addr, uint64_t *pdata,
  90. unsigned size, MemTxAttrs attrs)
  91. {
  92. TZPPCPort *p = opaque;
  93. TZPPC *s = p->ppc;
  94. int n = p - s->port;
  95. AddressSpace *as = &p->downstream_as;
  96. uint64_t data;
  97. MemTxResult res;
  98. if (!tz_ppc_check(s, n, attrs)) {
  99. trace_tz_ppc_read_blocked(n, addr, attrs.secure, attrs.user);
  100. if (s->cfg_sec_resp) {
  101. return MEMTX_ERROR;
  102. } else {
  103. *pdata = 0;
  104. return MEMTX_OK;
  105. }
  106. }
  107. switch (size) {
  108. case 1:
  109. data = address_space_ldub(as, addr, attrs, &res);
  110. break;
  111. case 2:
  112. data = address_space_lduw_le(as, addr, attrs, &res);
  113. break;
  114. case 4:
  115. data = address_space_ldl_le(as, addr, attrs, &res);
  116. break;
  117. case 8:
  118. data = address_space_ldq_le(as, addr, attrs, &res);
  119. break;
  120. default:
  121. g_assert_not_reached();
  122. }
  123. *pdata = data;
  124. return res;
  125. }
  126. static MemTxResult tz_ppc_write(void *opaque, hwaddr addr, uint64_t val,
  127. unsigned size, MemTxAttrs attrs)
  128. {
  129. TZPPCPort *p = opaque;
  130. TZPPC *s = p->ppc;
  131. AddressSpace *as = &p->downstream_as;
  132. int n = p - s->port;
  133. MemTxResult res;
  134. if (!tz_ppc_check(s, n, attrs)) {
  135. trace_tz_ppc_write_blocked(n, addr, attrs.secure, attrs.user);
  136. if (s->cfg_sec_resp) {
  137. return MEMTX_ERROR;
  138. } else {
  139. return MEMTX_OK;
  140. }
  141. }
  142. switch (size) {
  143. case 1:
  144. address_space_stb(as, addr, val, attrs, &res);
  145. break;
  146. case 2:
  147. address_space_stw_le(as, addr, val, attrs, &res);
  148. break;
  149. case 4:
  150. address_space_stl_le(as, addr, val, attrs, &res);
  151. break;
  152. case 8:
  153. address_space_stq_le(as, addr, val, attrs, &res);
  154. break;
  155. default:
  156. g_assert_not_reached();
  157. }
  158. return res;
  159. }
  160. static const MemoryRegionOps tz_ppc_ops = {
  161. .read_with_attrs = tz_ppc_read,
  162. .write_with_attrs = tz_ppc_write,
  163. .endianness = DEVICE_LITTLE_ENDIAN,
  164. };
  165. static bool tz_ppc_dummy_accepts(void *opaque, hwaddr addr,
  166. unsigned size, bool is_write,
  167. MemTxAttrs attrs)
  168. {
  169. /*
  170. * Board code should never map the upstream end of an unused port,
  171. * so we should never try to make a memory access to it.
  172. */
  173. g_assert_not_reached();
  174. }
  175. static const MemoryRegionOps tz_ppc_dummy_ops = {
  176. .valid.accepts = tz_ppc_dummy_accepts,
  177. };
  178. static void tz_ppc_reset(DeviceState *dev)
  179. {
  180. TZPPC *s = TZ_PPC(dev);
  181. trace_tz_ppc_reset();
  182. s->cfg_sec_resp = false;
  183. memset(s->cfg_nonsec, 0, sizeof(s->cfg_nonsec));
  184. memset(s->cfg_ap, 0, sizeof(s->cfg_ap));
  185. }
  186. static void tz_ppc_init(Object *obj)
  187. {
  188. DeviceState *dev = DEVICE(obj);
  189. TZPPC *s = TZ_PPC(obj);
  190. qdev_init_gpio_in_named(dev, tz_ppc_cfg_nonsec, "cfg_nonsec", TZ_NUM_PORTS);
  191. qdev_init_gpio_in_named(dev, tz_ppc_cfg_ap, "cfg_ap", TZ_NUM_PORTS);
  192. qdev_init_gpio_in_named(dev, tz_ppc_cfg_sec_resp, "cfg_sec_resp", 1);
  193. qdev_init_gpio_in_named(dev, tz_ppc_irq_enable, "irq_enable", 1);
  194. qdev_init_gpio_in_named(dev, tz_ppc_irq_clear, "irq_clear", 1);
  195. qdev_init_gpio_out_named(dev, &s->irq, "irq", 1);
  196. }
  197. static void tz_ppc_realize(DeviceState *dev, Error **errp)
  198. {
  199. Object *obj = OBJECT(dev);
  200. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  201. TZPPC *s = TZ_PPC(dev);
  202. int i;
  203. int max_port = 0;
  204. /* We can't create the upstream end of the port until realize,
  205. * as we don't know the size of the MR used as the downstream until then.
  206. */
  207. for (i = 0; i < TZ_NUM_PORTS; i++) {
  208. if (s->port[i].downstream) {
  209. max_port = i;
  210. }
  211. }
  212. for (i = 0; i <= max_port; i++) {
  213. TZPPCPort *port = &s->port[i];
  214. char *name;
  215. uint64_t size;
  216. if (!port->downstream) {
  217. /*
  218. * Create dummy sysbus MMIO region so the sysbus region
  219. * numbering doesn't get out of sync with the port numbers.
  220. * The size is entirely arbitrary.
  221. */
  222. name = g_strdup_printf("tz-ppc-dummy-port[%d]", i);
  223. memory_region_init_io(&port->upstream, obj, &tz_ppc_dummy_ops,
  224. port, name, 0x10000);
  225. sysbus_init_mmio(sbd, &port->upstream);
  226. g_free(name);
  227. continue;
  228. }
  229. name = g_strdup_printf("tz-ppc-port[%d]", i);
  230. port->ppc = s;
  231. address_space_init(&port->downstream_as, port->downstream, name);
  232. size = memory_region_size(port->downstream);
  233. memory_region_init_io(&port->upstream, obj, &tz_ppc_ops,
  234. port, name, size);
  235. sysbus_init_mmio(sbd, &port->upstream);
  236. g_free(name);
  237. }
  238. }
  239. static const VMStateDescription tz_ppc_vmstate = {
  240. .name = "tz-ppc",
  241. .version_id = 1,
  242. .minimum_version_id = 1,
  243. .fields = (VMStateField[]) {
  244. VMSTATE_BOOL_ARRAY(cfg_nonsec, TZPPC, 16),
  245. VMSTATE_BOOL_ARRAY(cfg_ap, TZPPC, 16),
  246. VMSTATE_BOOL(cfg_sec_resp, TZPPC),
  247. VMSTATE_BOOL(irq_enable, TZPPC),
  248. VMSTATE_BOOL(irq_clear, TZPPC),
  249. VMSTATE_BOOL(irq_status, TZPPC),
  250. VMSTATE_END_OF_LIST()
  251. }
  252. };
  253. #define DEFINE_PORT(N) \
  254. DEFINE_PROP_LINK("port[" #N "]", TZPPC, port[N].downstream, \
  255. TYPE_MEMORY_REGION, MemoryRegion *)
  256. static Property tz_ppc_properties[] = {
  257. DEFINE_PROP_UINT32("NONSEC_MASK", TZPPC, nonsec_mask, 0),
  258. DEFINE_PORT(0),
  259. DEFINE_PORT(1),
  260. DEFINE_PORT(2),
  261. DEFINE_PORT(3),
  262. DEFINE_PORT(4),
  263. DEFINE_PORT(5),
  264. DEFINE_PORT(6),
  265. DEFINE_PORT(7),
  266. DEFINE_PORT(8),
  267. DEFINE_PORT(9),
  268. DEFINE_PORT(10),
  269. DEFINE_PORT(11),
  270. DEFINE_PORT(12),
  271. DEFINE_PORT(13),
  272. DEFINE_PORT(14),
  273. DEFINE_PORT(15),
  274. DEFINE_PROP_END_OF_LIST(),
  275. };
  276. static void tz_ppc_class_init(ObjectClass *klass, void *data)
  277. {
  278. DeviceClass *dc = DEVICE_CLASS(klass);
  279. dc->realize = tz_ppc_realize;
  280. dc->vmsd = &tz_ppc_vmstate;
  281. dc->reset = tz_ppc_reset;
  282. dc->props = tz_ppc_properties;
  283. }
  284. static const TypeInfo tz_ppc_info = {
  285. .name = TYPE_TZ_PPC,
  286. .parent = TYPE_SYS_BUS_DEVICE,
  287. .instance_size = sizeof(TZPPC),
  288. .instance_init = tz_ppc_init,
  289. .class_init = tz_ppc_class_init,
  290. };
  291. static void tz_ppc_register_types(void)
  292. {
  293. type_register_static(&tz_ppc_info);
  294. }
  295. type_init(tz_ppc_register_types);