1 // SPDX-License-Identifier: (BSD-2-Clause AND BSD-3-Clause) 2 /* 3 * Copyright (c) 2015, Linaro Limited 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 /* 29 * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions are met: 33 * 34 * Redistributions of source code must retain the above copyright notice, this 35 * list of conditions and the following disclaimer. 36 * 37 * Redistributions in binary form must reproduce the above copyright notice, 38 * this list of conditions and the following disclaimer in the documentation 39 * and/or other materials provided with the distribution. 40 * 41 * Neither the name of ARM nor the names of its contributors may be used 42 * to endorse or promote products derived from this software without specific 43 * prior written permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 46 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 49 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 50 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 51 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 52 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 53 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 55 * POSSIBILITY OF SUCH DAMAGE. 56 */ 57 58 #include <assert.h> 59 #include <drivers/tzc400.h> 60 #include <io.h> 61 #include <kernel/panic.h> 62 #include <stddef.h> 63 #include <trace.h> 64 #include <util.h> 65 66 /* 67 * Implementation defined values used to validate inputs later. 68 * Filters : max of 4 ; 0 to 3 69 * Regions : max of 9 ; 0 to 8 70 * Address width : Values between 32 to 64 71 */ 72 struct tzc_instance { 73 vaddr_t base; 74 uint8_t addr_width; 75 uint8_t num_filters; 76 uint8_t num_regions; 77 }; 78 79 static struct tzc_instance tzc; 80 81 82 static uint32_t tzc_read_build_config(vaddr_t base) 83 { 84 return io_read32(base + BUILD_CONFIG_OFF); 85 } 86 87 static uint32_t tzc_read_gate_keeper(vaddr_t base) 88 { 89 return io_read32(base + GATE_KEEPER_OFF); 90 } 91 92 static void tzc_write_gate_keeper(vaddr_t base, uint32_t val) 93 { 94 io_write32(base + GATE_KEEPER_OFF, val); 95 } 96 97 static void tzc_write_action(vaddr_t base, enum tzc_action action) 98 { 99 io_write32(base + ACTION_OFF, action); 100 } 101 102 static uint32_t tzc_read_region_base_low(vaddr_t base, uint32_t region) 103 { 104 return io_read32(base + REGION_BASE_LOW_OFF + REGION_NUM_OFF(region)); 105 } 106 107 static void tzc_write_region_base_low(vaddr_t base, uint32_t region, 108 uint32_t val) 109 { 110 io_write32(base + REGION_BASE_LOW_OFF + REGION_NUM_OFF(region), val); 111 } 112 113 static uint32_t tzc_read_region_base_high(vaddr_t base, uint32_t region) 114 { 115 return io_read32(base + REGION_BASE_HIGH_OFF + REGION_NUM_OFF(region)); 116 } 117 118 static void tzc_write_region_base_high(vaddr_t base, uint32_t region, 119 uint32_t val) 120 { 121 io_write32(base + REGION_BASE_HIGH_OFF + REGION_NUM_OFF(region), val); 122 } 123 124 static uint32_t tzc_read_region_top_low(vaddr_t base, uint32_t region) 125 { 126 return io_read32(base + REGION_TOP_LOW_OFF + REGION_NUM_OFF(region)); 127 } 128 129 static void tzc_write_region_top_low(vaddr_t base, uint32_t region, 130 uint32_t val) 131 { 132 io_write32(base + REGION_TOP_LOW_OFF + REGION_NUM_OFF(region), val); 133 } 134 135 static uint32_t tzc_read_region_top_high(vaddr_t base, uint32_t region) 136 { 137 return io_read32(base + REGION_TOP_HIGH_OFF + REGION_NUM_OFF(region)); 138 } 139 140 static void tzc_write_region_top_high(vaddr_t base, uint32_t region, 141 uint32_t val) 142 { 143 io_write32(base + REGION_TOP_HIGH_OFF + REGION_NUM_OFF(region), val); 144 } 145 146 static uint32_t tzc_read_region_attributes(vaddr_t base, uint32_t region) 147 { 148 return io_read32(base + REGION_ATTRIBUTES_OFF + REGION_NUM_OFF(region)); 149 } 150 151 static void tzc_write_region_attributes(vaddr_t base, uint32_t region, 152 uint32_t val) 153 { 154 io_write32(base + REGION_ATTRIBUTES_OFF + REGION_NUM_OFF(region), val); 155 } 156 157 static uint32_t tzc_read_region_id_access(vaddr_t base, uint32_t region) 158 { 159 return io_read32(base + REGION_ID_ACCESS_OFF + REGION_NUM_OFF(region)); 160 } 161 162 static void tzc_write_region_id_access(vaddr_t base, uint32_t region, 163 uint32_t val) 164 { 165 io_write32(base + REGION_ID_ACCESS_OFF + REGION_NUM_OFF(region), val); 166 } 167 168 static uint32_t tzc_read_component_id(vaddr_t base) 169 { 170 uint32_t id; 171 172 id = io_read8(base + CID0_OFF); 173 id |= SHIFT_U32(io_read8(base + CID1_OFF), 8); 174 id |= SHIFT_U32(io_read8(base + CID2_OFF), 16); 175 id |= SHIFT_U32(io_read8(base + CID3_OFF), 24); 176 177 return id; 178 } 179 180 static uint32_t tzc_get_gate_keeper(vaddr_t base, uint8_t filter) 181 { 182 uint32_t tmp; 183 184 tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & 185 GATE_KEEPER_OS_MASK; 186 187 return (tmp >> filter) & GATE_KEEPER_FILTER_MASK; 188 } 189 190 /* This function is not MP safe. */ 191 static void tzc_set_gate_keeper(vaddr_t base, uint8_t filter, uint32_t val) 192 { 193 uint32_t tmp; 194 195 /* Upper half is current state. Lower half is requested state. */ 196 tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & 197 GATE_KEEPER_OS_MASK; 198 199 if (val) 200 tmp |= (1 << filter); 201 else 202 tmp &= ~(1 << filter); 203 204 tzc_write_gate_keeper(base, (tmp & GATE_KEEPER_OR_MASK) << 205 GATE_KEEPER_OR_SHIFT); 206 207 /* Wait here until we see the change reflected in the TZC status. */ 208 while (((tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & 209 GATE_KEEPER_OS_MASK) != tmp) 210 ; 211 } 212 213 214 void tzc_init(vaddr_t base) 215 { 216 uint32_t tzc_id, tzc_build; 217 218 assert(base); 219 tzc.base = base; 220 221 /* 222 * We expect to see a tzc400. Check component ID. The TZC-400 TRM shows 223 * component ID is expected to be "0xB105F00D". 224 */ 225 tzc_id = tzc_read_component_id(tzc.base); 226 if (tzc_id != TZC400_COMPONENT_ID) { 227 EMSG("TZC : Wrong device ID (0x%" PRIx32 ")", tzc_id); 228 panic(); 229 } 230 231 /* Save values we will use later. */ 232 tzc_build = tzc_read_build_config(tzc.base); 233 tzc.num_filters = ((tzc_build >> BUILD_CONFIG_NF_SHIFT) & 234 BUILD_CONFIG_NF_MASK) + 1; 235 tzc.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) & 236 BUILD_CONFIG_AW_MASK) + 1; 237 tzc.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) & 238 BUILD_CONFIG_NR_MASK) + 1; 239 } 240 241 static uint32_t addr_low(vaddr_t addr) 242 { 243 return (uint32_t)addr; 244 } 245 246 static uint32_t addr_high(vaddr_t addr __unused) 247 { 248 #if (UINTPTR_MAX == UINT64_MAX) 249 return (addr >> 32); 250 #else 251 return 0; 252 #endif 253 } 254 255 256 /* 257 * `tzc_configure_region` is used to program regions into the TrustZone 258 * controller. A region can be associated with more than one filter. The 259 * associated filters are passed in as a bitmap (bit0 = filter0). 260 * NOTE: 261 * The region 0 covers the whole address space and is enabled on all filters, 262 * this cannot be changed. It is, however, possible to change some region 0 263 * permissions. 264 */ 265 void tzc_configure_region(uint8_t region, const struct tzc_region_config *cfg) 266 { 267 assert(tzc.base && cfg); 268 269 /* Do range checks on filters and regions. */ 270 assert(((cfg->filters >> tzc.num_filters) == 0) && 271 (region < tzc.num_regions)); 272 273 /* 274 * Do address range check based on TZC configuration. A 64bit address is 275 * the max and expected case. 276 */ 277 #if (UINTPTR_MAX == UINT64_MAX) 278 assert(((cfg->top <= (UINT64_MAX >> (64 - tzc.addr_width))) && 279 (cfg->base < cfg->top))); 280 #endif 281 /* region_base and (region_top + 1) must be 4KB aligned */ 282 assert(((cfg->base | (cfg->top + 1)) & (4096 - 1)) == 0); 283 284 assert(cfg->sec_attr <= TZC_REGION_S_RDWR); 285 286 /* 287 * Inputs look ok, start programming registers. 288 * All the address registers are 32 bits wide and have a LOW and HIGH 289 * component used to construct a up to a 64bit address. 290 */ 291 tzc_write_region_base_low(tzc.base, region, addr_low(cfg->base)); 292 tzc_write_region_base_high(tzc.base, region, addr_high(cfg->base)); 293 294 tzc_write_region_top_low(tzc.base, region, addr_low(cfg->top)); 295 tzc_write_region_top_high(tzc.base, region, addr_high(cfg->top)); 296 297 /* Assign the region to a filter and set secure attributes */ 298 tzc_write_region_attributes(tzc.base, region, 299 (cfg->sec_attr << REG_ATTR_SEC_SHIFT) | 300 cfg->filters); 301 302 /* 303 * Specify which non-secure devices have permission to access this 304 * region. 305 */ 306 tzc_write_region_id_access(tzc.base, region, cfg->ns_device_access); 307 } 308 309 TEE_Result tzc_get_region_config(uint8_t region, struct tzc_region_config *cfg) 310 { 311 uint32_t val32 = 0; 312 313 if (region >= tzc.num_regions) 314 return TEE_ERROR_GENERIC; 315 316 cfg->base = reg_pair_to_64(tzc_read_region_base_high(tzc.base, region), 317 tzc_read_region_base_low(tzc.base, region)); 318 cfg->top = reg_pair_to_64(tzc_read_region_top_high(tzc.base, region), 319 tzc_read_region_top_low(tzc.base, region)); 320 321 cfg->ns_device_access = tzc_read_region_id_access(tzc.base, region); 322 323 val32 = tzc_read_region_attributes(tzc.base, region); 324 cfg->sec_attr = val32 >> REG_ATTR_SEC_SHIFT; 325 cfg->filters = val32 & REG_ATTR_F_EN_MASK; 326 327 return TEE_SUCCESS; 328 } 329 330 void tzc_set_action(enum tzc_action action) 331 { 332 assert(tzc.base); 333 334 /* 335 * - Currently no handler is provided to trap an error via interrupt 336 * or exception. 337 * - The interrupt action has not been tested. 338 */ 339 tzc_write_action(tzc.base, action); 340 } 341 342 343 void tzc_enable_filters(void) 344 { 345 uint32_t state; 346 uint32_t filter; 347 348 assert(tzc.base); 349 350 for (filter = 0; filter < tzc.num_filters; filter++) { 351 state = tzc_get_gate_keeper(tzc.base, filter); 352 if (state) { 353 /* 354 * The TZC filter is already configured. Changing the 355 * programmer's view in an active system can cause 356 * unpredictable behavior therefore panic for now rather 357 * than try to determine whether this is safe in this 358 * instance. See: 359 * http://infocenter.arm.com/help/index.jsp?\ 360 * topic=/com.arm.doc.ddi0504c/CJHHECBF.html 361 */ 362 EMSG("TZC : Filter %d Gatekeeper already enabled", 363 filter); 364 panic(); 365 } 366 tzc_set_gate_keeper(tzc.base, filter, 1); 367 } 368 } 369 370 371 void tzc_disable_filters(void) 372 { 373 uint32_t filter; 374 375 assert(tzc.base); 376 377 /* 378 * We don't do the same state check as above as the Gatekeepers are 379 * disabled after reset. 380 */ 381 for (filter = 0; filter < tzc.num_filters; filter++) 382 tzc_set_gate_keeper(tzc.base, filter, 0); 383 } 384 385 static bool __maybe_unused write_not_read(unsigned int filter) 386 { 387 return io_read32(tzc.base + FAIL_CONTROL(filter)) & 388 FAIL_CONTROL_DIRECTION_WRITE; 389 } 390 391 static bool __maybe_unused nonsecure_not_secure(unsigned int filter) 392 { 393 return io_read32(tzc.base + FAIL_CONTROL(filter)) & 394 FAIL_CONTROL_NONSECURE; 395 } 396 397 static bool __maybe_unused priv_not_unpriv(unsigned int filter) 398 { 399 return io_read32(tzc.base + FAIL_CONTROL(filter)) & 400 FAIL_CONTROL_PRIVILEGED; 401 } 402 403 static void dump_fail_filter(unsigned int filter) 404 { 405 uint64_t __maybe_unused addr = 0; 406 uint32_t status = io_read32(tzc.base + INT_STATUS); 407 408 if (!(status & BIT(filter + INT_STATUS_OVERLAP_SHIFT)) && 409 !(status & BIT(filter + INT_STATUS_OVERRUN_SHIFT)) && 410 !(status & BIT(filter + INT_STATUS_STATUS_SHIFT))) 411 return; 412 413 if (status & BIT(filter + INT_STATUS_OVERLAP_SHIFT)) 414 EMSG("Overlap violation on filter %u", filter); 415 416 if (status & BIT(filter + INT_STATUS_OVERRUN_SHIFT)) 417 EMSG("Overrun violation on filter %u", filter); 418 419 if (status & BIT(filter + INT_STATUS_STATUS_SHIFT)) 420 EMSG("Permission violation on filter %u", filter); 421 422 addr = reg_pair_to_64(io_read32(tzc.base + FAIL_ADDRESS_HIGH(filter)), 423 io_read32(tzc.base + FAIL_ADDRESS_LOW(filter))); 424 425 EMSG("Violation @0x%"PRIx64", %ssecure %sprivileged %s, AXI ID %"PRIx32, 426 addr, 427 nonsecure_not_secure(filter) ? "non-" : "", 428 priv_not_unpriv(filter) ? "" : "un", 429 write_not_read(filter) ? "write" : "read", 430 io_read32(tzc.base + FAIL_ID(filter))); 431 } 432 433 /* 434 * Dump info when TZC400 catches an unallowed access with TZC 435 * interrupt enabled. 436 */ 437 void tzc_fail_dump(void) 438 { 439 unsigned int filter = 0; 440 441 for (filter = 0; filter < tzc.num_filters; filter++) 442 dump_fail_filter(filter); 443 } 444 445 void tzc_int_clear(void) 446 { 447 assert(tzc.base); 448 449 io_setbits32(tzc.base + INT_CLEAR, GENMASK_32(tzc.num_filters - 1, 0)); 450 } 451 452 #if TRACE_LEVEL >= TRACE_DEBUG 453 454 #define REGION_MAX 8 455 static const __maybe_unused char * const tzc_attr_msg[] = { 456 "TZC_REGION_S_NONE", 457 "TZC_REGION_S_RD", 458 "TZC_REGION_S_WR", 459 "TZC_REGION_S_RDWR" 460 }; 461 462 void tzc_dump_state(void) 463 { 464 uint32_t n; 465 uint32_t temp_32reg, temp_32reg_h; 466 unsigned int filter = 0; 467 468 for (n = 0; n <= REGION_MAX; n++) { 469 temp_32reg = tzc_read_region_attributes(tzc.base, n); 470 if (!(temp_32reg & REG_ATTR_F_EN_MASK)) 471 continue; 472 473 DMSG("region %d", n); 474 temp_32reg = tzc_read_region_base_low(tzc.base, n); 475 temp_32reg_h = tzc_read_region_base_high(tzc.base, n); 476 DMSG("region_base: 0x%08x%08x", temp_32reg_h, temp_32reg); 477 temp_32reg = tzc_read_region_top_low(tzc.base, n); 478 temp_32reg_h = tzc_read_region_top_high(tzc.base, n); 479 DMSG("region_top: 0x%08x%08x", temp_32reg_h, temp_32reg); 480 temp_32reg = tzc_read_region_attributes(tzc.base, n); 481 DMSG("secure rw: %s", 482 tzc_attr_msg[temp_32reg >> REG_ATTR_SEC_SHIFT]); 483 484 for (filter = 0; filter < tzc.num_filters; filter++) 485 if (temp_32reg & BIT(filter)) 486 DMSG("filter %u enable", filter); 487 } 488 } 489 490 #endif /* CFG_TRACE_LEVEL >= TRACE_DEBUG */ 491