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