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