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