[FOSS_TLK]platform: tegra: cleanup fuse handling
[3rdparty/ote_partner/tlk.git] / platform / tegra / common / platform.c
1 /*
2  * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23
24 #include <assert.h>
25 #include <errno.h>
26 #include <err.h>
27 #include <debug.h>
28 #include <rand.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <lib/heap.h>
32 #include <arch/arm/mmu.h>
33 #include <arch/ops.h>
34 #include <arch/arm.h>
35 #include <platform.h>
36 #include <platform/memmap.h>
37 #include <platform/irqs.h>
38 #include <platform/platform_fuse.h>
39 #include <kernel/task.h>
40 #include <target/debugconfig.h>
41 #include <lib/monitor/monitor_vector.h>
42 #if ARM_WITH_OUTER_CACHE
43 #include <arch/outercache.h>
44 #endif
45 #include <platform/platform_p.h>
46 #include <platform/platform_monitor.h>
47
48 #define MB              (1024 * 1024)
49
50 extern unsigned long boot_secondary_cpu_addr;
51 extern unsigned int coldboot_normal_os;
52 extern unsigned int normal_os_coldboot_fn;
53 extern uint32_t device_uid[4];
54
55 #if !defined(WITH_MONITOR_BIN)
56 extern uint32_t __save_boot_regs[9];
57 extern uint32_t __save_boot_cpsr;
58 extern uint32_t __jumpback_addr;
59 #endif
60
61 uint32_t debug_uart_id = DEFAULT_DEBUG_PORT;
62
63 /* track available kernel VA space */
64 vaddr_t platform_vaspace_ptr;
65 vaddr_t platform_vaspace_end;
66
67 extern unsigned long cbstruct_addr;
68 extern unsigned long cbuf_addr;
69
70 void platform_early_init(void)
71 {
72 #if WITH_LIB_VERSION
73         extern char *version;
74 #endif
75         platform_init_debug_port(debug_uart_id);
76
77 #if WITH_LIB_VERSION
78         dprintf(CRITICAL, "starting platform early init (TLK %s)\n", version);
79 #endif
80 }
81
82 void platform_idle(void)
83 {
84         struct tz_monitor_frame frame, *smc_frame;
85 #if ARM_CPU_CORTEX_A9
86         uint32_t val;
87 #endif
88
89 #if !defined(WITH_MONITOR_BIN)
90         /* mark the entire TLK carveout as secure in the MC */
91         platform_secure_dram_aperture();
92 #endif
93
94 #if !defined(WITH_MONITOR_BIN)
95         memset(&frame, 0, sizeof(frame));
96
97         ASSERT(__jumpback_addr);
98         frame.pc = __jumpback_addr;
99         frame.spsr = __save_boot_cpsr;  /* interrupts disabled, in svc */
100         memcpy(&frame.r[4], __save_boot_regs, sizeof(__save_boot_regs));
101 #endif
102
103 #if ARM_CPU_CORTEX_A9
104         /*
105          * Before going to the NS world for the first time, set ACTLR.FW.
106          * The NSACR.NS_SMP setting granted it the capability to set ACTLR.SMP,
107          * but it doesn't cover NS writing ACTLR.FW.
108          */
109         val = arm_read_actlr();
110         val |= 0x1;
111         arm_write_actlr(val);
112 #endif
113
114         dputs(CRITICAL, "TLK initialization complete. Jumping to non-secure world\n");
115
116         smc_frame = tz_switch_to_ns(SMC_TOS_INITIAL_NS_RETURN, &frame);
117         while (smc_frame) {
118                 tz_stdcall_handler(smc_frame);
119                 smc_frame = tz_switch_to_ns(SMC_TOS_COMPLETION, smc_frame);
120         }
121 }
122
123 void platform_init(void)
124 {
125         uint32_t reg = 0;
126
127         platform_init_cpu();
128
129         platform_setup_keys();
130
131         platform_fuse_init();
132
133         /*
134          * Set SE_TZRAM_SECURITY sticky bit to respect secure TZRAM accesses.
135          * Note: No need to reprogram it after LP0 exit as it's part of SE's
136          * sticky bits HW LP0 context, so will be restored by the BR.
137          */
138         reg = *(volatile uint32_t *)(TEGRA_SE_BASE + 0x4);
139         reg &= ~(0x1);
140         *(volatile uint32_t *)(TEGRA_SE_BASE + 0x4) = reg;
141 }
142
143 void platform_init_mmu_mappings(void)
144 {
145         extern int _heap_end;
146         extern uint32_t __load_phys_size, __early_heap_allocs;
147
148         /*
149          * End of the kernel's heap is the carveout size, reduced by
150          * any early allocations (e.g. pages used for pagetables).
151          */
152         _heap_end = (VMEMBASE + __load_phys_size) - __early_heap_allocs;
153         _heap_end &= ~PAGE_MASK;
154
155         /* setup available vaspace (starts at end of carveout memory) */
156         platform_vaspace_ptr = VMEMBASE + __load_phys_size;
157         platform_vaspace_end = platform_vaspace_ptr + (VMEMSIZE - __load_phys_size);
158 }
159
160 uint64_t platform_translate_nsaddr(nsaddr_t vaddr, uint32_t type)
161 {
162 #if defined(WITH_MONITOR_BIN)
163         struct tz_monitor_frame frame;
164         frame.r[0] = vaddr;
165         frame.r[1] = type;
166         monitor_send_receive(SMC_TOS_ADDR_TRANSLATE, &frame);
167         return frame.r[0];
168 #else
169         arm_write_v2p(vaddr, type);
170         return arm_read_par();
171 #endif
172 }
173
174 uint32_t platform_get_rand32(void)
175 {
176         return rand();
177 }
178
179 uint32_t platform_get_time_us(void)
180 {
181         return *(volatile uint32_t *)(TEGRA_TMRUS_BASE);
182 }
183
184 status_t platform_ss_register_handler(struct tz_monitor_frame *frame)
185 {
186         return NO_ERROR;
187 }
188
189 /*
190  * Calculate the physical address of the shared buffer that we have got for
191  * logging from the linux kernel. All references to the shared buffer from
192  * within tlk are made directly to the physical address.
193  */
194 status_t set_log_phy_addr(nsaddr_t _ns_cb_struct_addr)
195 {
196         struct circular_buffer *cbstruct;
197         nsaddr_t cbuf;
198
199         cbstruct = (struct circular_buffer *)
200                         tz_map_shared_mem(_ns_cb_struct_addr, PAGE_SIZE);
201         if (cbstruct == NULL) {
202                 dprintf(CRITICAL, "%s: failed to map cbstruct\n", __func__);
203                 return ERR_NO_MEMORY;
204         }
205
206         cbuf = tz_map_shared_mem(cbstruct->buf, cbstruct->size);
207         if (cbuf == NULL) {
208                 dprintf(CRITICAL, "%s: failed to map cbuf\n", __func__);
209                 return ERR_NO_MEMORY;
210         }
211
212         cbstruct_addr = (unsigned long)cbstruct;
213         cbuf_addr = (unsigned long)cbuf;
214
215         return NO_ERROR;
216 }
217
218 int platform_ss_request_handler(void)
219 {
220         struct tz_monitor_frame frame;
221
222         memset(&frame, 0, sizeof(struct tz_monitor_frame));
223         frame.r[0] = SMC_ERR_PREEMPT_BY_FS;
224
225         (void)tz_switch_to_ns(SMC_TOS_PREEMPT_BY_FS, &frame);
226
227         return 0;
228 }
229
230 int platform_ss_get_config(uint32_t *ss_config)
231 {
232         *ss_config = 0;
233
234         /*
235          * If we're on an ODM production unit, then return bits
236          * indicating if rollback protection should be enabled and
237          * if so, should key provisioning be performed.
238          */
239         if (platform_fuse_get(FUSE_ID_ODM_PROD)) {
240                 if (platform_fuse_get(FUSE_ID_RB_ENABLE)) {
241                         *ss_config |= OTE_SS_CONFIG_RB_ENABLE;
242                         if (!platform_fuse_get(FUSE_ID_RB_KEY_PROGRAMMED)) {
243                                 *ss_config |= OTE_SS_CONFIG_RB_PROGRAM_KEY;
244                         }
245                 }
246         }
247
248         return 0;
249 }
250
251 void platform_get_device_id(te_device_id_args_t *out)
252 {
253         if (out)
254                 memcpy(out, device_uid, sizeof(te_device_id_args_t));
255 }
256
257 void platform_clean_invalidate_cache_range(vaddr_t range, uint32_t length)
258 {
259 #if defined(ARM_USE_CPU_CACHING)
260         arch_clean_invalidate_cache_range(range, length);
261
262 #if ARM_WITH_OUTER_CACHE
263         outer_clean_range(virtual_to_physical(range), length);
264         outer_inv_range(virtual_to_physical(range), length);
265 #endif
266 #endif
267 }