1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2016-2023, Linaro Limited
4 * Copyright (c) 2014-2023, STMicroelectronics International N.V.
5 * Copyright (C) 2022-2023 Nuvoton Ltd.
6 */
7
8 #include <console.h>
9 #include <drivers/gic.h>
10 #include <drivers/ns16550.h>
11 #include <kernel/boot.h>
12 #include <kernel/linker.h>
13 #include <kernel/tee_common_otp.h>
14 #include <mm/core_memprot.h>
15 #include <platform_config.h>
16 #include <tee/tee_cryp_utl.h>
17 #include <trace.h>
18
19 #define COLOR_NORMAL "\x1B[0m"
20 #define COLOR_RED "\x1B[31m"
21 #define COLOR_GREEN "\x1B[32m"
22 #define COLOR_YELLOW "\x1B[33m"
23 #define COLOR_BLUE "\x1B[34m"
24 #define COLOR_MAGENTA "\x1B[35m"
25 #define COLOR_CYAN "\x1B[36m"
26 #define COLOR_WHITE "\x1B[37m"
27
28 #define NPCM_MEASURE_BASE 0xF0848000
29 #define NPCM_MEASURE_UUID 0xC50
30 #define NPCM_MEASURE_SIZE 5
31
32 static struct ns16550_data console_data __nex_bss;
33
34 static struct {
35 uint8_t data[HW_UNIQUE_KEY_LENGTH];
36 bool ready;
37 } npcm_hwkey;
38
39 register_phys_mem_pgdir(MEM_AREA_IO_SEC, CONSOLE_UART_BASE, UART_REG_SIZE);
40 register_phys_mem_pgdir(MEM_AREA_IO_SEC, GICD_BASE, GIC_DIST_REG_SIZE);
41 register_phys_mem_pgdir(MEM_AREA_IO_SEC, GICC_BASE, GIC_DIST_REG_SIZE);
42 register_phys_mem_pgdir(MEM_AREA_RAM_NSEC, NPCM_MEASURE_BASE, SMALL_PAGE_SIZE);
43
44 register_ddr(DRAM0_BASE, DRAM0_SIZE);
45
print_version(void)46 static void print_version(void)
47 {
48 IMSG(COLOR_MAGENTA);
49 IMSG(">================================================");
50 IMSG("OP-TEE OS Version %s", core_v_str);
51 IMSG(">================================================");
52 IMSG(COLOR_NORMAL);
53 }
54
boot_primary_init_intc(void)55 void boot_primary_init_intc(void)
56 {
57 if (IS_ENABLED(CFG_NPCM_DEBUG))
58 print_version();
59
60 gic_init(GICC_BASE, GICD_BASE);
61 }
62
plat_console_init(void)63 void plat_console_init(void)
64 {
65 ns16550_init(&console_data, CONSOLE_UART_BASE, IO_WIDTH_U32, 2);
66 register_serial_console(&console_data.chip);
67 }
68
tee_otp_get_hw_unique_key(struct tee_hw_unique_key * hwkey)69 TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey)
70 {
71 void *vaddr = NULL;
72 TEE_Result res = TEE_SUCCESS;
73 uint32_t bin[HW_UNIQUE_KEY_LENGTH / sizeof(uint32_t)] = {};
74 uint8_t *bin_val = (uint8_t *)(&bin[0]);
75
76 if (npcm_hwkey.ready)
77 goto out;
78
79 vaddr = phys_to_virt(NPCM_MEASURE_BASE + NPCM_MEASURE_UUID,
80 MEM_AREA_RAM_NSEC, NPCM_MEASURE_SIZE);
81 if (!vaddr) {
82 EMSG("Not enough memory mapped");
83 return TEE_ERROR_SECURITY;
84 }
85
86 res = tee_hash_createdigest(TEE_ALG_SHA256, (uint8_t *)vaddr,
87 NPCM_MEASURE_SIZE, bin_val,
88 HW_UNIQUE_KEY_LENGTH);
89 if (res != TEE_SUCCESS) {
90 EMSG("Can't create a digest for HUK");
91 return TEE_ERROR_SECURITY;
92 }
93
94 memcpy(&npcm_hwkey.data[0], bin, HW_UNIQUE_KEY_LENGTH);
95 npcm_hwkey.ready = true;
96
97 IMSG("HUK Initialized");
98
99 out:
100 memcpy(hwkey->data, npcm_hwkey.data, HW_UNIQUE_KEY_LENGTH);
101
102 return res;
103 }
104