1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021, EPAM Systems
4 */
5 #include <assert.h>
6 #include <kernel/panic.h>
7 #include <mm/core_memprot.h>
8 #include <mm/core_mmu.h>
9
10 #include "rcar.h"
11 #include "romapi.h"
12
get_api_table_index(void)13 static int get_api_table_index(void)
14 {
15 /*
16 * Depending on SoC type and version, there are 4 possible addresses
17 * for each ROMAPI function
18 */
19 static int index __nex_data = -1;
20
21 if (index != -1)
22 return index;
23
24 switch (rcar_prr_value & PRR_PRODUCT_MASK) {
25 case PRR_PRODUCT_H3:
26 switch (rcar_prr_value & PRR_CUT_MASK) {
27 case PRR_CUT_10: /* H3 ES1.0 */
28 case PRR_CUT_11: /* H3 ES1.1 */
29 index = 0;
30 break;
31 case PRR_CUT_20: /* H3 ES2.0 */
32 index = 1;
33 break;
34 default: /* Newer H3 versions use unified table */
35 index = 3;
36 break;
37 }
38 break;
39 case PRR_PRODUCT_M3W:
40 switch (rcar_prr_value & PRR_CUT_MASK) {
41 case PRR_CUT_10: /* M3 ES1.0 */
42 index = 2;
43 break;
44 default: /* Newer M3 versions use unified table */
45 index = 3;
46 break;
47 }
48 break;
49 default: /* All other SoCs use unified table */
50 index = 3;
51 break;
52 }
53
54 return index;
55 }
56
57 /* implemented in romapi_call.S */
58 extern uint32_t __plat_romapi_wrapper(paddr_t func, uint64_t arg1,
59 uint64_t arg2, uint64_t arg3);
60
__plat_romapi_direct(paddr_t func,uint64_t arg1,uint64_t arg2,uint64_t arg3)61 static uint32_t __plat_romapi_direct(paddr_t func, uint64_t arg1,
62 uint64_t arg2, uint64_t arg3)
63 {
64 uint32_t (*fptr)(uint64_t arg1, uint64_t arg2, uint64_t arg3) = NULL;
65
66 assert(!cpu_mmu_enabled());
67
68 fptr = (typeof(fptr))func;
69
70 return fptr(arg1, arg2, arg3);
71 }
72
plat_call_romapi(paddr_t func,uint64_t arg1,uint64_t arg2,uint64_t arg3)73 static uint32_t plat_call_romapi(paddr_t func, uint64_t arg1,
74 uint64_t arg2, uint64_t arg3)
75 {
76 uint32_t (*fptr)(paddr_t func, uint64_t arg1, uint64_t arg2,
77 uint64_t arg3) = NULL;
78
79 /*
80 * If MMU is enabled, we need to use trampoline function that will
81 * disable MMU and switch stack pointer to physical address. On other
82 * hand, if MMU is disabled, we can call the ROM function directly.
83 */
84 if (cpu_mmu_enabled())
85 /*
86 * With ASLR enabled __plat_romapi_wrapper() function will be
87 * mapped at two addresses: at random address (with the rest of
88 * OP-TEE) and at identity address. We need to map it at
89 * identity address and call it at identity address because this
90 * function turns off MMU to perform ROM API call. But
91 * __plat_romapi_wrapper *symbol* will be relocated by ASLR
92 * code. To get identity address of the function we need to use
93 * virt_to_phys().
94 */
95 fptr = (void *)virt_to_phys(__plat_romapi_wrapper);
96 else
97 /*
98 * With MMU disabled we can call ROM code directly.
99 */
100 fptr = __plat_romapi_direct;
101
102 return fptr(func, arg1, arg2, arg3);
103 }
104
va2pa(void * ptr)105 static paddr_t va2pa(void *ptr)
106 {
107 if (cpu_mmu_enabled())
108 return virt_to_phys(ptr);
109 else
110 return (paddr_t)ptr;
111 }
112
113 static const paddr_t romapi_getrndvector[] = {
114 0xEB10DFC4, /* H3 1.0/1.1, needs confirmation */
115 0xEB117134, /* H3 2.0 */
116 0xEB11055C, /* M3 1.0/1.05, needs confirmation */
117 0xEB100188, /* H3 3.0, M3 1.1+, M3N, E3, D3, V3M 2.0 */
118 };
119
plat_rom_getrndvector(uint8_t rndbuff[PLAT_RND_VECTOR_SZ],uint8_t * scratch,uint32_t scratch_sz)120 uint32_t plat_rom_getrndvector(uint8_t rndbuff[PLAT_RND_VECTOR_SZ],
121 uint8_t *scratch, uint32_t scratch_sz)
122 {
123 uint32_t ret = -1;
124 paddr_t func_addr = romapi_getrndvector[get_api_table_index()];
125 paddr_t rndbuff_pa = va2pa(rndbuff);
126 paddr_t scratch_pa = va2pa(scratch);
127
128 assert(scratch_sz >= 4096);
129 assert(rndbuff_pa % RCAR_CACHE_LINE_SZ == 0);
130 assert(scratch_pa % RCAR_CACHE_LINE_SZ == 0);
131
132 ret = plat_call_romapi(func_addr, rndbuff_pa, scratch_pa, scratch_sz);
133
134 /*
135 * ROM code is called with MMU turned off, so any accesses to rndbuff
136 * are not affected by data cache. This can lead to two problems:
137 *
138 * 1. Any prior writes can be cached but may not reach memory. So staled
139 * values can be flushed to memory later and overwrite new data written
140 * by ROM code. This includes stack as well.
141 *
142 * 2. ROM code will write new data to the buffer, but we may see old,
143 * cached values.
144 *
145 * ROM code wrapper will issue dcache_op_all(DCACHE_OP_CLEAN). This will
146 * ensure that all writes reached memory. After the call we need to
147 * invalidate the cache to see new data.
148 *
149 * We are not accessing scratch area, so no need to do cache maintenance
150 * for that buffer.
151 */
152 cache_op_inner(DCACHE_AREA_INVALIDATE, rndbuff, PLAT_RND_VECTOR_SZ);
153
154 return ret;
155 }
156