1*c1e65709SSungmin Han // SPDX-License-Identifier: BSD-2-Clause
2*c1e65709SSungmin Han /*
3*c1e65709SSungmin Han * Copyright (c) 2024, Telechips Inc.
4*c1e65709SSungmin Han */
5*c1e65709SSungmin Han
6*c1e65709SSungmin Han #include <console.h>
7*c1e65709SSungmin Han #include <crypto/crypto.h>
8*c1e65709SSungmin Han #include <drivers/gic.h>
9*c1e65709SSungmin Han #include <drivers/pl011.h>
10*c1e65709SSungmin Han #include <drivers/tcc_otp.h>
11*c1e65709SSungmin Han #include <kernel/boot.h>
12*c1e65709SSungmin Han #include <kernel/tee_common_otp.h>
13*c1e65709SSungmin Han #include <otprom.h>
14*c1e65709SSungmin Han #include <platform_config.h>
15*c1e65709SSungmin Han
16*c1e65709SSungmin Han register_phys_mem(MEM_AREA_IO_SEC, TCC_IO_BASE, TCC_IO_SIZE);
17*c1e65709SSungmin Han #if defined(TZC_BASE)
18*c1e65709SSungmin Han register_phys_mem(MEM_AREA_IO_SEC, TZC_BASE, TZC_SIZE);
19*c1e65709SSungmin Han #endif
20*c1e65709SSungmin Han
21*c1e65709SSungmin Han register_ddr(DRAM0_BASE, DRAM0_SIZE);
22*c1e65709SSungmin Han #if defined(DRAM1_BASE)
23*c1e65709SSungmin Han register_ddr(DRAM1_BASE, DRAM1_SIZE);
24*c1e65709SSungmin Han #endif
25*c1e65709SSungmin Han
26*c1e65709SSungmin Han static bool huk_is_ready;
27*c1e65709SSungmin Han static uint32_t plat_huk[OTP_DATA_TEE_HUK_SIZE / sizeof(uint32_t)];
28*c1e65709SSungmin Han
boot_primary_init_intc(void)29*c1e65709SSungmin Han void boot_primary_init_intc(void)
30*c1e65709SSungmin Han {
31*c1e65709SSungmin Han gic_init(GICC_BASE, GICD_BASE);
32*c1e65709SSungmin Han }
33*c1e65709SSungmin Han
boot_secondary_init_intc(void)34*c1e65709SSungmin Han void boot_secondary_init_intc(void)
35*c1e65709SSungmin Han {
36*c1e65709SSungmin Han gic_init_per_cpu();
37*c1e65709SSungmin Han }
38*c1e65709SSungmin Han
plat_console_init(void)39*c1e65709SSungmin Han void plat_console_init(void)
40*c1e65709SSungmin Han {
41*c1e65709SSungmin Han #if defined(CFG_PL011)
42*c1e65709SSungmin Han static struct pl011_data console_data;
43*c1e65709SSungmin Han
44*c1e65709SSungmin Han pl011_init(&console_data, CONSOLE_UART_BASE, CONSOLE_UART_CLK_IN_HZ,
45*c1e65709SSungmin Han CONSOLE_BAUDRATE);
46*c1e65709SSungmin Han register_serial_console(&console_data.chip);
47*c1e65709SSungmin Han #endif
48*c1e65709SSungmin Han }
49*c1e65709SSungmin Han
tee_otp_get_hw_unique_key(struct tee_hw_unique_key * hwkey)50*c1e65709SSungmin Han TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey)
51*c1e65709SSungmin Han {
52*c1e65709SSungmin Han static_assert(sizeof(plat_huk) == sizeof(hwkey->data));
53*c1e65709SSungmin Han
54*c1e65709SSungmin Han if (!huk_is_ready)
55*c1e65709SSungmin Han return TEE_ERROR_GENERIC;
56*c1e65709SSungmin Han
57*c1e65709SSungmin Han memcpy(hwkey->data, plat_huk, OTP_DATA_TEE_HUK_SIZE);
58*c1e65709SSungmin Han return TEE_SUCCESS;
59*c1e65709SSungmin Han }
60*c1e65709SSungmin Han
init_huk(void)61*c1e65709SSungmin Han static TEE_Result init_huk(void)
62*c1e65709SSungmin Han {
63*c1e65709SSungmin Han TEE_Result res = TEE_ERROR_GENERIC;
64*c1e65709SSungmin Han
65*c1e65709SSungmin Han res = tcc_otp_read_128(OTP_DATA_TEE_HUK_OFFSET, plat_huk);
66*c1e65709SSungmin Han if (res == TEE_ERROR_NO_DATA) {
67*c1e65709SSungmin Han IMSG("There is no HUK in OTP. Starting HUK Provisioning");
68*c1e65709SSungmin Han if (!crypto_rng_read(plat_huk, OTP_DATA_TEE_HUK_SIZE)) {
69*c1e65709SSungmin Han tcc_otp_write_128(OTP_DATA_TEE_HUK_OFFSET, plat_huk);
70*c1e65709SSungmin Han res = tcc_otp_read_128(OTP_DATA_TEE_HUK_OFFSET,
71*c1e65709SSungmin Han plat_huk);
72*c1e65709SSungmin Han if (res != TEE_SUCCESS)
73*c1e65709SSungmin Han EMSG("Failed to store HUK to OTP");
74*c1e65709SSungmin Han } else {
75*c1e65709SSungmin Han EMSG("Failed to generate random number for HUK");
76*c1e65709SSungmin Han }
77*c1e65709SSungmin Han }
78*c1e65709SSungmin Han
79*c1e65709SSungmin Han if (res == TEE_SUCCESS)
80*c1e65709SSungmin Han huk_is_ready = true;
81*c1e65709SSungmin Han else
82*c1e65709SSungmin Han EMSG("Failed to get HUK from OTP");
83*c1e65709SSungmin Han
84*c1e65709SSungmin Han return res;
85*c1e65709SSungmin Han }
86*c1e65709SSungmin Han service_init(init_huk);
87