1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (C) 2018 Marvell International Ltd. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu * https://spdx.org/licenses 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu #include <inttypes.h> 9*91f16700Schasinglulu #include <stdint.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <common/debug.h> 12*91f16700Schasinglulu #include <drivers/marvell/addr_map.h> 13*91f16700Schasinglulu #include <lib/mmio.h> 14*91f16700Schasinglulu 15*91f16700Schasinglulu #include <mvebu_def.h> 16*91f16700Schasinglulu 17*91f16700Schasinglulu #include "mc_trustzone.h" 18*91f16700Schasinglulu 19*91f16700Schasinglulu #define TZ_SIZE(x) ((x) >> 13) 20*91f16700Schasinglulu 21*91f16700Schasinglulu static int fls(int x) 22*91f16700Schasinglulu { 23*91f16700Schasinglulu if (!x) 24*91f16700Schasinglulu return 0; 25*91f16700Schasinglulu 26*91f16700Schasinglulu return 32 - __builtin_clz(x); 27*91f16700Schasinglulu } 28*91f16700Schasinglulu 29*91f16700Schasinglulu /* To not duplicate types, the addr_map_win is used, but the "target" 30*91f16700Schasinglulu * filed is referring to attributes instead of "target". 31*91f16700Schasinglulu */ 32*91f16700Schasinglulu void tz_enable_win(int ap_index, const struct addr_map_win *win, int win_id) 33*91f16700Schasinglulu { 34*91f16700Schasinglulu int tz_size; 35*91f16700Schasinglulu uint32_t val, base = win->base_addr; 36*91f16700Schasinglulu 37*91f16700Schasinglulu if ((win_id < 0) || (win_id > MVEBU_TZ_MAX_WINS)) { 38*91f16700Schasinglulu ERROR("Enabling wrong MC TrustZone window %d!\n", win_id); 39*91f16700Schasinglulu return; 40*91f16700Schasinglulu } 41*91f16700Schasinglulu 42*91f16700Schasinglulu /* map the window size to trustzone register convention */ 43*91f16700Schasinglulu tz_size = fls(TZ_SIZE(win->win_size)); 44*91f16700Schasinglulu 45*91f16700Schasinglulu VERBOSE("%s: window size = 0x%" PRIx64 " maps to tz_size %d\n", 46*91f16700Schasinglulu __func__, win->win_size, tz_size); 47*91f16700Schasinglulu if (tz_size < 0 || tz_size > 31) { 48*91f16700Schasinglulu ERROR("Using not allowed size for MC TrustZone window %d!\n", 49*91f16700Schasinglulu win_id); 50*91f16700Schasinglulu return; 51*91f16700Schasinglulu } 52*91f16700Schasinglulu 53*91f16700Schasinglulu if (base & 0xfff) { 54*91f16700Schasinglulu base = base & ~0xfff; 55*91f16700Schasinglulu WARN("Attempt to open MC TZ win. at 0x%" PRIx64 ", truncate to 0x%x\n", 56*91f16700Schasinglulu win->base_addr, base); 57*91f16700Schasinglulu } 58*91f16700Schasinglulu 59*91f16700Schasinglulu val = base | (tz_size << 7) | win->target_id | TZ_VALID; 60*91f16700Schasinglulu 61*91f16700Schasinglulu VERBOSE("%s: base 0x%x, tz_size moved 0x%x, attr 0x%x, val 0x%x\n", 62*91f16700Schasinglulu __func__, base, (tz_size << 7), win->target_id, val); 63*91f16700Schasinglulu 64*91f16700Schasinglulu mmio_write_32(MVEBU_AP_MC_TRUSTZONE_REG_LOW(ap_index, win_id), val); 65*91f16700Schasinglulu 66*91f16700Schasinglulu VERBOSE("%s: Win%d[0x%x] configured to 0x%x\n", __func__, win_id, 67*91f16700Schasinglulu MVEBU_AP_MC_TRUSTZONE_REG_LOW(ap_index, win_id), 68*91f16700Schasinglulu mmio_read_32(MVEBU_AP_MC_TRUSTZONE_REG_LOW(ap_index, win_id))); 69*91f16700Schasinglulu 70*91f16700Schasinglulu mmio_write_32(MVEBU_AP_MC_TRUSTZONE_REG_HIGH(ap_index, win_id), 71*91f16700Schasinglulu (win->base_addr >> 32)); 72*91f16700Schasinglulu 73*91f16700Schasinglulu VERBOSE("%s: Win%d[0x%x] configured to 0x%x\n", __func__, win_id, 74*91f16700Schasinglulu MVEBU_AP_MC_TRUSTZONE_REG_HIGH(ap_index, win_id), 75*91f16700Schasinglulu mmio_read_32(MVEBU_AP_MC_TRUSTZONE_REG_HIGH(ap_index, win_id))); 76*91f16700Schasinglulu } 77