xref: /optee_os/core/arch/arm/plat-nuvoton/main.c (revision 55ab8f06a831946a49717446cd2e4495a2b5d659)
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