xref: /rk3399_ARM-atf/plat/rpi/rpi3/rpi3_bl2_mboot.c (revision f4c8834472dd55031e7b29a38a47ecb3ef53bb37)
1 /*
2  * Copyright (c) 2025-2026, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <stdarg.h>
9 #include <stdint.h>
10 
11 #include <plat/common/common_def.h>
12 #include <plat/common/platform.h>
13 #include <platform_def.h>
14 
15 #include <drivers/auth/crypto_mod.h>
16 #include <drivers/delay_timer.h>
17 #include <drivers/gpio_spi.h>
18 #include <drivers/measured_boot/metadata.h>
19 #include <drivers/tpm/tpm2_slb9670/slb9670_gpio.h>
20 #include <event_measure.h>
21 #include <event_print.h>
22 #include <tpm2.h>
23 #include <tpm2_chip.h>
24 #if TRANSFER_LIST
25 #include <tpm_event_log.h>
26 #include <transfer_list.h>
27 extern struct transfer_list_header *bl2_tl;
28 #endif
29 #include <tools_share/tbbr_oid.h>
30 
31 #include "./include/rpi3_measured_boot.h"
32 
33 /* RPI3 table with platform specific image IDs, names and PCRs */
34 const event_log_metadata_t rpi3_event_log_metadata[] = {
35 	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
36 	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
37 	{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
38 
39 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
40 };
41 
42 #if DISCRETE_TPM
43 extern struct tpm_chip_data tpm_chip_data;
44 
rpi3_bl2_tpm_early_interface_setup(void)45 static void rpi3_bl2_tpm_early_interface_setup(void)
46 {
47 #if TPM_INTERFACE_FIFO_SPI
48 	struct tpm_spi_plat *spidev;
49 	const struct tpm_timeout_ops timeout_ops = {
50 		.timeout_init_us = timeout_init_us,
51 		.timeout_elapsed = timeout_elapsed
52 	};
53 
54 	const struct gpio_spi_config *tpm_rpi3_gpio_data =
55 		tpm2_slb9670_get_config();
56 	int rc;
57 
58 	tpm2_slb9670_gpio_init(tpm_rpi3_gpio_data);
59 
60 	spidev = gpio_spi_init(tpm_rpi3_gpio_data);
61 
62 	rc = tpm_interface_init(spidev, &timeout_ops, &tpm_chip_data, 0);
63 	if (rc != 0) {
64 		ERROR("BL2: TPM interface init failed\n");
65 		panic();
66 	}
67 
68 #endif
69 }
70 #endif
71 
72 static uint8_t *event_log_start;
73 static size_t event_log_size;
74 static uint8_t *event_log_base;
75 static uint8_t *event_log_finish;
76 
bl2_plat_mboot_init(void)77 void bl2_plat_mboot_init(void)
78 {
79 	struct transfer_list_entry *te __unused;
80 	int rc;
81 #if DISCRETE_TPM
82 	rpi3_bl2_tpm_early_interface_setup();
83 #endif
84 
85 #if TRANSFER_LIST
86 	if (bl2_tl != NULL &&
87 	    transfer_list_check_header(bl2_tl) != TL_OPS_NON) {
88 		event_log_start = transfer_list_event_log_extend(
89 			bl2_tl, PLAT_ARM_EVENT_LOG_MAX_SIZE);
90 		flush_dcache_range((uintptr_t)bl2_tl, bl2_tl->size);
91 		/*
92 	 * Retrieve the extend event log entry from the transfer list, the API above
93 	 * returns a cursor position rather than the base address - we need both to
94 	 * init the library.
95 	 */
96 		te = transfer_list_find(bl2_tl, TL_TAG_TPM_EVLOG);
97 
98 		event_log_base =
99 			transfer_list_entry_data(te) + EVENT_LOG_RESERVED_BYTES;
100 		event_log_finish = transfer_list_entry_data(te) + te->data_size;
101 
102 		event_log_size = event_log_start - event_log_base;
103 	} else {
104 		ERROR("BL2: Valid transfer list not found");
105 		panic();
106 	}
107 #else
108 	rpi3_mboot_fetch_eventlog_info(&event_log_start, &event_log_size);
109 	event_log_base = event_log_start;
110 	event_log_finish = event_log_start + PLAT_ARM_EVENT_LOG_MAX_SIZE;
111 #endif
112 	rc = event_log_init_and_reg(event_log_base, event_log_finish,
113 				    event_log_size, crypto_mod_tcg_hash);
114 	if (rc < 0) {
115 		ERROR("Failed to initialize event log (%d).\n", rc);
116 		panic();
117 	}
118 }
119 
bl2_plat_mboot_finish(void)120 void bl2_plat_mboot_finish(void)
121 {
122 	int rc;
123 	size_t event_log_cur_size;
124 #if TRANSFER_LIST
125 	struct transfer_list_header *ns_tl = NULL;
126 	uint8_t *cursor;
127 	uint8_t *base_after_finish;
128 
129 	event_log_cur_size = event_log_get_cur_size(event_log_start);
130 	cursor = event_log_start + event_log_cur_size;
131 	base_after_finish =
132 		transfer_list_event_log_finish(bl2_tl, (uintptr_t)cursor);
133 	if (base_after_finish == NULL) {
134 		WARN("BL2: Failed to finalize TL Event Log\n");
135 	} else {
136 		flush_dcache_range((uintptr_t)bl2_tl, bl2_tl->size);
137 		transfer_list_update_checksum(bl2_tl);
138 		event_log_start = base_after_finish;
139 		event_log_cur_size = event_log_get_cur_size(event_log_start);
140 #ifdef FW_NS_HANDOFF_BASE
141 		/* Update contents in NS Transfer List at FW_NS_HANDOFF_BASE */
142 		ns_tl = transfer_list_relocate(
143 			bl2_tl, (void *)(uintptr_t)FW_NS_HANDOFF_BASE,
144 			bl2_tl->max_size);
145 		if (!ns_tl) {
146 			ERROR("Relocate TL to 0x%lx failed\n",
147 			      (unsigned long)FW_NS_HANDOFF_BASE);
148 			panic();
149 		}
150 #endif
151 	}
152 #else
153 
154 	/* Event Log address in Non-Secure memory */
155 	uintptr_t ns_log_addr;
156 
157 	event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_start);
158 
159 	/* write the eventlog addr and size to NT_FW_CONFIG TPM entry */
160 	rc = rpi3_set_nt_fw_info(event_log_cur_size, &ns_log_addr);
161 	if (rc != 0) {
162 		ERROR("%s(): Unable to update %s_FW_CONFIG\n", __func__, "NT");
163 		/*
164 		 * fatal error due to Bl33 maintaining the assumption
165 		 * that the eventlog is successfully passed via
166 		 * NT_FW_CONFIG.
167 		 */
168 		panic();
169 	}
170 
171 	/* Copy Event Log to Non-secure memory */
172 	(void)memcpy((void *)ns_log_addr, (const void *)event_log_start,
173 		     event_log_cur_size);
174 
175 	/* Ensure that the Event Log is visible in Non-secure memory */
176 	flush_dcache_range(ns_log_addr, event_log_cur_size);
177 #endif /* TRANSFER_LIST */
178 	/* Dump Event Log for user view */
179 	event_log_dump((uint8_t *)event_log_start, event_log_cur_size);
180 
181 #if DISCRETE_TPM
182 	/* relinquish control of TPM locality 0 and close interface */
183 	rc = tpm_interface_close(&tpm_chip_data, 0);
184 	if (rc != 0) {
185 		ERROR("BL2: TPM interface close failed\n");
186 		panic();
187 	}
188 #endif
189 }
190