1 /* 2 * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <string.h> 9 10 #include <arch_helpers.h> 11 #include <common/debug.h> 12 #include <lib/mmio.h> 13 #include <lib/utils.h> 14 #include <lib/xlat_tables/xlat_tables_v2.h> 15 16 #include <memctrl.h> 17 #include <memctrl_v1.h> 18 #include <tegra_def.h> 19 20 /* Video Memory base and size (live values) */ 21 static uint64_t video_mem_base; 22 static uint64_t video_mem_size; 23 24 /* 25 * Init SMMU. 26 */ 27 void tegra_memctrl_setup(void) 28 { 29 /* 30 * Setup the Memory controller to allow only secure accesses to 31 * the TZDRAM carveout 32 */ 33 INFO("Tegra Memory Controller (v1)\n"); 34 35 /* allow translations for all MC engines */ 36 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_0_0, 37 (unsigned int)MC_SMMU_TRANSLATION_ENABLE); 38 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_1_0, 39 (unsigned int)MC_SMMU_TRANSLATION_ENABLE); 40 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_2_0, 41 (unsigned int)MC_SMMU_TRANSLATION_ENABLE); 42 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_3_0, 43 (unsigned int)MC_SMMU_TRANSLATION_ENABLE); 44 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_4_0, 45 (unsigned int)MC_SMMU_TRANSLATION_ENABLE); 46 47 tegra_mc_write_32(MC_SMMU_ASID_SECURITY_0, MC_SMMU_ASID_SECURITY); 48 49 tegra_mc_write_32(MC_SMMU_TLB_CONFIG_0, MC_SMMU_TLB_CONFIG_0_RESET_VAL); 50 tegra_mc_write_32(MC_SMMU_PTC_CONFIG_0, MC_SMMU_PTC_CONFIG_0_RESET_VAL); 51 52 /* flush PTC and TLB */ 53 tegra_mc_write_32(MC_SMMU_PTC_FLUSH_0, MC_SMMU_PTC_FLUSH_ALL); 54 (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */ 55 tegra_mc_write_32(MC_SMMU_TLB_FLUSH_0, MC_SMMU_TLB_FLUSH_ALL); 56 57 /* enable SMMU */ 58 tegra_mc_write_32(MC_SMMU_CONFIG_0, 59 MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE); 60 (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */ 61 62 /* video memory carveout */ 63 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, 64 (uint32_t)(video_mem_base >> 32)); 65 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base); 66 tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size); 67 } 68 69 /* 70 * Restore Memory Controller settings after "System Suspend" 71 */ 72 void tegra_memctrl_restore_settings(void) 73 { 74 tegra_memctrl_setup(); 75 } 76 77 /* 78 * Secure the BL31 DRAM aperture. 79 * 80 * phys_base = physical base of TZDRAM aperture 81 * size_in_bytes = size of aperture in bytes 82 */ 83 void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) 84 { 85 /* 86 * Setup the Memory controller to allow only secure accesses to 87 * the TZDRAM carveout 88 */ 89 INFO("Configuring TrustZone DRAM Memory Carveout\n"); 90 91 tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base); 92 tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20); 93 } 94 95 /* 96 * Secure the BL31 TZRAM aperture. 97 * 98 * phys_base = physical base of TZRAM aperture 99 * size_in_bytes = size of aperture in bytes 100 */ 101 void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) 102 { 103 /* 104 * The v1 hardware controller does not have any registers 105 * for setting up the on-chip TZRAM. 106 */ 107 } 108 109 static void tegra_clear_videomem(uintptr_t non_overlap_area_start, 110 unsigned long long non_overlap_area_size) 111 { 112 int ret; 113 114 /* 115 * Map the NS memory first, clean it and then unmap it. 116 */ 117 ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */ 118 non_overlap_area_start, /* VA */ 119 non_overlap_area_size, /* size */ 120 MT_NS | MT_RW | MT_EXECUTE_NEVER | 121 MT_NON_CACHEABLE); /* attrs */ 122 assert(ret == 0); 123 124 zeromem((void *)non_overlap_area_start, non_overlap_area_size); 125 flush_dcache_range(non_overlap_area_start, non_overlap_area_size); 126 127 mmap_remove_dynamic_region(non_overlap_area_start, 128 non_overlap_area_size); 129 } 130 131 /* 132 * Program the Video Memory carveout region 133 * 134 * phys_base = physical base of aperture 135 * size_in_bytes = size of aperture in bytes 136 */ 137 void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) 138 { 139 uintptr_t vmem_end_old = video_mem_base + (video_mem_size << 20); 140 uintptr_t vmem_end_new = phys_base + size_in_bytes; 141 unsigned long long non_overlap_area_size; 142 143 /* 144 * Setup the Memory controller to restrict CPU accesses to the Video 145 * Memory region 146 */ 147 INFO("Configuring Video Memory Carveout\n"); 148 149 /* 150 * Configure Memory Controller directly for the first time. 151 */ 152 if (video_mem_base == 0) 153 goto done; 154 155 /* 156 * Clear the old regions now being exposed. The following cases 157 * can occur - 158 * 159 * 1. clear whole old region (no overlap with new region) 160 * 2. clear old sub-region below new base 161 * 3. clear old sub-region above new end 162 */ 163 INFO("Cleaning previous Video Memory Carveout\n"); 164 165 if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) { 166 tegra_clear_videomem(video_mem_base, video_mem_size << 20); 167 } else { 168 if (video_mem_base < phys_base) { 169 non_overlap_area_size = phys_base - video_mem_base; 170 tegra_clear_videomem(video_mem_base, non_overlap_area_size); 171 } 172 if (vmem_end_old > vmem_end_new) { 173 non_overlap_area_size = vmem_end_old - vmem_end_new; 174 tegra_clear_videomem(vmem_end_new, non_overlap_area_size); 175 } 176 } 177 178 done: 179 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32)); 180 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base); 181 tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); 182 183 /* store new values */ 184 video_mem_base = phys_base; 185 video_mem_size = size_in_bytes >> 20; 186 } 187 188 /* 189 * During boot, USB3 and flash media (SDMMC/SATA) devices need access to 190 * IRAM. Because these clients connect to the MC and do not have a direct 191 * path to the IRAM, the MC implements AHB redirection during boot to allow 192 * path to IRAM. In this mode, accesses to a programmed memory address aperture 193 * are directed to the AHB bus, allowing access to the IRAM. The AHB aperture 194 * is defined by the IRAM_BASE_LO and IRAM_BASE_HI registers, which are 195 * initialized to disable this aperture. 196 * 197 * Once bootup is complete, we must program IRAM base to 0xffffffff and 198 * IRAM top to 0x00000000, thus disabling access to IRAM. DRAM is then 199 * potentially accessible in this address range. These aperture registers 200 * also have an access_control/lock bit. After disabling the aperture, the 201 * access_control register should be programmed to lock the registers. 202 */ 203 void tegra_memctrl_disable_ahb_redirection(void) 204 { 205 /* program the aperture registers */ 206 tegra_mc_write_32(MC_IRAM_BASE_LO, 0xFFFFFFFF); 207 tegra_mc_write_32(MC_IRAM_TOP_LO, 0); 208 tegra_mc_write_32(MC_IRAM_BASE_TOP_HI, 0); 209 210 /* lock the aperture registers */ 211 tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES); 212 } 213 214 void tegra_memctrl_clear_pending_interrupts(void) 215 { 216 uint32_t mcerr; 217 218 /* check if there are any pending interrupts */ 219 mcerr = mmio_read_32(TEGRA_MC_BASE + MC_INTSTATUS); 220 221 if (mcerr != (uint32_t)0U) { /* should not see error here */ 222 WARN("MC_INTSTATUS = 0x%x (should be zero)\n", mcerr); 223 mmio_write_32((TEGRA_MC_BASE + MC_INTSTATUS), mcerr); 224 } 225 } 226