ARMv8/sec_firmware: Remove SEC_FIRMWARE_FIT_CNF_NAME
[platform/kernel/u-boot.git] / arch / arm / cpu / armv8 / sec_firmware.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2016 NXP Semiconductor, Inc.
4  */
5
6 #include <common.h>
7 #include <cpu_func.h>
8 #include <errno.h>
9 #include <fdt_support.h>
10 #include <image.h>
11 #include <log.h>
12 #include <asm/cache.h>
13 #include <asm/global_data.h>
14 #include <asm/ptrace.h>
15 #include <linux/kernel.h>
16 #include <linux/arm-smccc.h>
17 #include <asm/io.h>
18 #include <asm/system.h>
19 #include <asm/types.h>
20 #include <asm/macro.h>
21 #include <asm/armv8/sec_firmware.h>
22
23 DECLARE_GLOBAL_DATA_PTR;
24 extern void c_runtime_cpu_setup(void);
25
26 #define SEC_FIRMWARE_LOADED     0x1
27 #define SEC_FIRMWARE_RUNNING    0x2
28 #define SEC_FIRMWARE_ADDR_MASK  (~0x3)
29 /*
30  * Secure firmware load addr
31  * Flags used: 0x1 secure firmware has been loaded to secure memory
32  *             0x2 secure firmware is running
33  */
34 phys_addr_t sec_firmware_addr;
35
36 #ifndef SEC_FIRMWARE_FIT_IMAGE
37 #define SEC_FIRMWARE_FIT_IMAGE          "firmware"
38 #endif
39 #ifndef SEC_FIRMWARE_TARGET_EL
40 #define SEC_FIRMWARE_TARGET_EL          2
41 #endif
42
43 static int sec_firmware_get_data(const void *sec_firmware_img,
44                                 const void **data, size_t *size)
45 {
46         int conf_node_off, fw_node_off;
47         char *desc;
48         int ret;
49
50         conf_node_off = fit_conf_get_node(sec_firmware_img, NULL);
51         if (conf_node_off < 0) {
52                 puts("SEC Firmware: no config\n");
53                 return -ENOENT;
54         }
55
56         fw_node_off = fit_conf_get_prop_node(sec_firmware_img, conf_node_off,
57                         SEC_FIRMWARE_FIT_IMAGE);
58         if (fw_node_off < 0) {
59                 printf("SEC Firmware: No '%s' in config\n",
60                        SEC_FIRMWARE_FIT_IMAGE);
61                 return -ENOLINK;
62         }
63
64         /* Verify secure firmware image */
65         if (!(fit_image_verify(sec_firmware_img, fw_node_off))) {
66                 printf("SEC Firmware: Bad firmware image (bad CRC)\n");
67                 return -EINVAL;
68         }
69
70         if (fit_image_get_data(sec_firmware_img, fw_node_off, data, size)) {
71                 printf("SEC Firmware: Can't get %s subimage data/size",
72                        SEC_FIRMWARE_FIT_IMAGE);
73                 return -ENOENT;
74         }
75
76         ret = fit_get_desc(sec_firmware_img, fw_node_off, &desc);
77         if (ret)
78                 printf("SEC Firmware: Can't get description\n");
79         else
80                 printf("%s\n", desc);
81
82         return ret;
83 }
84
85 /*
86  * SEC Firmware FIT image parser checks if the image is in FIT
87  * format, verifies integrity of the image and calculates raw
88  * image address and size values.
89  *
90  * Returns 0 on success and a negative errno on error task fail.
91  */
92 static int sec_firmware_parse_image(const void *sec_firmware_img,
93                                         const void **raw_image_addr,
94                                         size_t *raw_image_size)
95 {
96         int ret;
97
98         ret = sec_firmware_get_data(sec_firmware_img, raw_image_addr,
99                                         raw_image_size);
100         if (ret)
101                 return ret;
102
103         debug("SEC Firmware: raw_image_addr = 0x%p, raw_image_size = 0x%lx\n",
104               *raw_image_addr, *raw_image_size);
105
106         return 0;
107 }
108
109 /*
110  * SEC Firmware FIT image parser to check if any loadable is
111  * present. If present, verify integrity of the loadable and
112  * copy loadable to address provided in (loadable_h, loadable_l).
113  *
114  * Returns 0 on success and a negative errno on error task fail.
115  */
116 static int sec_firmware_check_copy_loadable(const void *sec_firmware_img,
117                                             u32 *loadable_l, u32 *loadable_h)
118 {
119         phys_addr_t sec_firmware_loadable_addr = 0;
120         int conf_node_off, ld_node_off, images;
121         const void *data;
122         size_t size;
123         ulong load;
124         const char *name, *str, *type;
125         int len;
126
127         conf_node_off = fit_conf_get_node(sec_firmware_img, NULL);
128         if (conf_node_off < 0) {
129                 puts("SEC Firmware: no config\n");
130                 return -ENOENT;
131         }
132
133         /* find the node holding the images information */
134         images = fdt_path_offset(sec_firmware_img, FIT_IMAGES_PATH);
135         if (images < 0) {
136                 printf("%s: Cannot find /images node: %d\n", __func__, images);
137                 return -1;
138         }
139
140         type = FIT_LOADABLE_PROP;
141
142         name = fdt_getprop(sec_firmware_img, conf_node_off, type, &len);
143         if (!name) {
144                 /* Loadables not present */
145                 return 0;
146         }
147
148         printf("SEC Firmware: '%s' present in config\n", type);
149
150         for (str = name; str && ((str - name) < len);
151              str = strchr(str, '\0') + 1) {
152                 printf("%s: '%s'\n", type, str);
153                 ld_node_off = fdt_subnode_offset(sec_firmware_img, images, str);
154                 if (ld_node_off < 0) {
155                         printf("cannot find image node '%s': %d\n", str,
156                                ld_node_off);
157                         return -EINVAL;
158                 }
159
160                 /* Verify secure firmware image */
161                 if (!(fit_image_verify(sec_firmware_img, ld_node_off))) {
162                         printf("SEC Loadable: Bad loadable image (bad CRC)\n");
163                         return -EINVAL;
164                 }
165
166                 if (fit_image_get_data(sec_firmware_img, ld_node_off,
167                                        &data, &size)) {
168                         printf("SEC Loadable: Can't get subimage data/size");
169                         return -ENOENT;
170                 }
171
172                 /* Get load address, treated as load offset to secure memory */
173                 if (fit_image_get_load(sec_firmware_img, ld_node_off, &load)) {
174                         printf("SEC Loadable: Can't get subimage load");
175                         return -ENOENT;
176                 }
177
178                 /* Compute load address for loadable in secure memory */
179                 sec_firmware_loadable_addr = (sec_firmware_addr -
180                                                 gd->arch.tlb_size) + load;
181
182                 /* Copy loadable to secure memory and flush dcache */
183                 debug("%s copied to address 0x%p\n",
184                       FIT_LOADABLE_PROP, (void *)sec_firmware_loadable_addr);
185                 memcpy((void *)sec_firmware_loadable_addr, data, size);
186                 flush_dcache_range(sec_firmware_loadable_addr,
187                                    sec_firmware_loadable_addr + size);
188
189                 /* Populate loadable address only for Trusted OS */
190                 if (!strcmp(str, "trustedOS@1")) {
191                         /*
192                          * Populate address ptrs for loadable image with
193                          * loadbale addr
194                          */
195                         out_le32(loadable_l, (sec_firmware_loadable_addr &
196                                               WORD_MASK));
197                         out_le32(loadable_h, (sec_firmware_loadable_addr >>
198                                               WORD_SHIFT));
199                 }
200         }
201
202         return 0;
203 }
204
205 static int sec_firmware_copy_image(const char *title,
206                          u64 image_addr, u32 image_size, u64 sec_firmware)
207 {
208         debug("%s copied to address 0x%p\n", title, (void *)sec_firmware);
209         memcpy((void *)sec_firmware, (void *)image_addr, image_size);
210         flush_dcache_range(sec_firmware, sec_firmware + image_size);
211
212         return 0;
213 }
214
215 /*
216  * This function will parse the SEC Firmware image, and then load it
217  * to secure memory. Also load any loadable if present along with SEC
218  * Firmware image.
219  */
220 static int sec_firmware_load_image(const void *sec_firmware_img,
221                                    u32 *loadable_l, u32 *loadable_h)
222 {
223         const void *raw_image_addr;
224         size_t raw_image_size = 0;
225         int ret;
226
227         /*
228          * The Excetpion Level must be EL3 to load and initialize
229          * the SEC Firmware.
230          */
231         if (current_el() != 3) {
232                 ret = -EACCES;
233                 goto out;
234         }
235
236 #ifdef CONFIG_SYS_MEM_RESERVE_SECURE
237         /*
238          * The SEC Firmware must be stored in secure memory.
239          * Append SEC Firmware to secure mmu table.
240          */
241         if (!(gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED)) {
242                 ret = -ENXIO;
243                 goto out;
244         }
245
246         sec_firmware_addr = (gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK) +
247                         gd->arch.tlb_size;
248 #else
249 #error "The CONFIG_SYS_MEM_RESERVE_SECURE must be defined when enabled SEC Firmware support"
250 #endif
251
252         /* Align SEC Firmware base address to 4K */
253         sec_firmware_addr = (sec_firmware_addr + 0xfff) & ~0xfff;
254         debug("SEC Firmware: Load address: 0x%llx\n",
255               sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);
256
257         ret = sec_firmware_parse_image(sec_firmware_img, &raw_image_addr,
258                         &raw_image_size);
259         if (ret)
260                 goto out;
261
262         /* TODO:
263          * Check if the end addr of SEC Firmware has been extend the secure
264          * memory.
265          */
266
267         /* Copy the secure firmware to secure memory */
268         ret = sec_firmware_copy_image("SEC Firmware", (u64)raw_image_addr,
269                         raw_image_size, sec_firmware_addr &
270                         SEC_FIRMWARE_ADDR_MASK);
271         if (ret)
272                 goto out;
273
274         /*
275          * Check if any loadable are present along with firmware image, if
276          * present load them.
277          */
278         ret = sec_firmware_check_copy_loadable(sec_firmware_img, loadable_l,
279                                                loadable_h);
280         if (ret)
281                 goto out;
282
283         sec_firmware_addr |= SEC_FIRMWARE_LOADED;
284         debug("SEC Firmware: Entry point: 0x%llx\n",
285               sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);
286
287         return 0;
288
289 out:
290         printf("SEC Firmware: error (%d)\n", ret);
291         sec_firmware_addr = 0;
292
293         return ret;
294 }
295
296 static int sec_firmware_entry(u32 *eret_hold_l, u32 *eret_hold_h)
297 {
298         const void *entry = (void *)(sec_firmware_addr &
299                                 SEC_FIRMWARE_ADDR_MASK);
300
301         return _sec_firmware_entry(entry, eret_hold_l, eret_hold_h);
302 }
303
304 /* Check the secure firmware FIT image */
305 __weak bool sec_firmware_is_valid(const void *sec_firmware_img)
306 {
307         if (fdt_check_header(sec_firmware_img)) {
308                 printf("SEC Firmware: Bad firmware image (not a FIT image)\n");
309                 return false;
310         }
311
312         if (fit_check_format(sec_firmware_img, IMAGE_SIZE_INVAL)) {
313                 printf("SEC Firmware: Bad firmware image (bad FIT header)\n");
314                 return false;
315         }
316
317         return true;
318 }
319
320 #ifdef CONFIG_SEC_FIRMWARE_ARMV8_PSCI
321 /*
322  * The PSCI_VERSION function is added from PSCI v0.2. When the PSCI
323  * v0.1 received this function, the NOT_SUPPORTED (0xffff_ffff) error
324  * number will be returned according to SMC Calling Conventions. But
325  * when getting the NOT_SUPPORTED error number, we cannot ensure if
326  * the PSCI version is v0.1 or other error occurred. So, PSCI v0.1
327  * won't be supported by this framework.
328  * And if the secure firmware isn't running, return NOT_SUPPORTED.
329  *
330  * The return value on success is PSCI version in format
331  * major[31:16]:minor[15:0].
332  */
333 unsigned int sec_firmware_support_psci_version(void)
334 {
335         if (current_el() == SEC_FIRMWARE_TARGET_EL)
336                 return _sec_firmware_support_psci_version();
337
338         return PSCI_INVALID_VER;
339 }
340 #endif
341
342 /*
343  * Check with sec_firmware if it supports random number generation
344  * via HW RNG
345  *
346  * The return value will be true if it is supported
347  */
348 bool sec_firmware_support_hwrng(void)
349 {
350 #ifdef CONFIG_TFABOOT
351         /* return true as TFA has one job ring reserved */
352         return true;
353 #endif
354         if (sec_firmware_addr & SEC_FIRMWARE_RUNNING) {
355                 return true;
356         }
357
358         return false;
359 }
360
361 /*
362  * sec_firmware_get_random - Get a random number from SEC Firmware
363  * @rand:               random number buffer to be filled
364  * @bytes:              Number of bytes of random number to be supported
365  * @eret:               -1 in case of error, 0 for success
366  */
367 int sec_firmware_get_random(uint8_t *rand, int bytes)
368 {
369         struct arm_smccc_res res;
370         unsigned long long num;
371         int param1;
372
373         if (!bytes || bytes > 8) {
374                 printf("Max Random bytes genration supported is 8\n");
375                 return -1;
376         }
377         if (bytes <= 4)
378                 param1 = 0;
379         else
380                 param1 = 1;
381
382 #define SIP_RNG_64 0xC200FF11
383         arm_smccc_smc(SIP_RNG_64, param1, 0, 0, 0, 0, 0, 0, &res);
384         if (res.a0)
385                 return -1;
386
387         num = res.a1;
388         memcpy(rand, &num, bytes);
389
390         return 0;
391 }
392
393 /*
394  * sec_firmware_init - Initialize the SEC Firmware
395  * @sec_firmware_img:   the SEC Firmware image address
396  * @eret_hold_l:        the address to hold exception return address low
397  * @eret_hold_h:        the address to hold exception return address high
398  * @loadable_l:         the address to hold loadable address low
399  * @loadable_h:         the address to hold loadable address high
400  */
401 int sec_firmware_init(const void *sec_firmware_img,
402                         u32 *eret_hold_l,
403                         u32 *eret_hold_h,
404                         u32 *loadable_l,
405                         u32 *loadable_h)
406 {
407         int ret;
408
409         if (!sec_firmware_is_valid(sec_firmware_img))
410                 return -EINVAL;
411
412         ret = sec_firmware_load_image(sec_firmware_img, loadable_l,
413                                       loadable_h);
414         if (ret) {
415                 printf("SEC Firmware: Failed to load image\n");
416                 return ret;
417         } else if (sec_firmware_addr & SEC_FIRMWARE_LOADED) {
418                 ret = sec_firmware_entry(eret_hold_l, eret_hold_h);
419                 if (ret) {
420                         printf("SEC Firmware: Failed to initialize\n");
421                         return ret;
422                 }
423         }
424
425         debug("SEC Firmware: Return from SEC Firmware: current_el = %d\n",
426               current_el());
427
428         /*
429          * The PE will be turned into target EL when returned from
430          * SEC Firmware.
431          */
432         if (current_el() != SEC_FIRMWARE_TARGET_EL)
433                 return -EACCES;
434
435         sec_firmware_addr |= SEC_FIRMWARE_RUNNING;
436
437         /* Set exception table and enable caches if it isn't EL3 */
438         if (current_el() != 3) {
439                 c_runtime_cpu_setup();
440                 enable_caches();
441         }
442
443         return 0;
444 }
445
446 /*
447  * fdt_fix_kaslr - Add kalsr-seed node in Device tree
448  * @fdt:                Device tree
449  * @eret:               0 in case of error, 1 for success
450  */
451 int fdt_fixup_kaslr(void *fdt)
452 {
453         int nodeoffset;
454         int err, ret = 0;
455         u8 rand[8];
456
457 #if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT)
458         /* Check if random seed generation is  supported */
459         if (sec_firmware_support_hwrng() == false) {
460                 printf("WARNING: SEC firmware not running, no kaslr-seed\n");
461                 return 0;
462         }
463
464         err = sec_firmware_get_random(rand, 8);
465         if (err < 0) {
466                 printf("WARNING: No random number to set kaslr-seed\n");
467                 return 0;
468         }
469
470         err = fdt_check_header(fdt);
471         if (err < 0) {
472                 printf("fdt_chosen: %s\n", fdt_strerror(err));
473                 return 0;
474         }
475
476         /* find or create "/chosen" node. */
477         nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
478         if (nodeoffset < 0)
479                 return 0;
480
481         err = fdt_setprop(fdt, nodeoffset, "kaslr-seed", rand,
482                                   sizeof(rand));
483         if (err < 0) {
484                 printf("WARNING: can't set kaslr-seed %s.\n",
485                        fdt_strerror(err));
486                 return 0;
487         }
488         ret = 1;
489 #endif
490
491         return ret;
492 }