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/arm/common/plat_arm.h>
12 #include <plat/common/platform.h>
13 #include <platform_def.h>
14
15 #include <tpm2.h>
16 #include <tpm2_chip.h>
17
18 #include <common/desc_image_load.h>
19 #include <common/ep_info.h>
20 #include <drivers/auth/crypto_mod.h>
21 #include <drivers/delay_timer.h>
22 #include <drivers/gpio_spi.h>
23 #include <drivers/measured_boot/metadata.h>
24 #include <drivers/tpm/tpm2_slb9670/slb9670_gpio.h>
25 #include <event_measure.h>
26 #include <event_print.h>
27 #if TRANSFER_LIST
28 #include <tpm_event_log.h>
29 #include <transfer_list.h>
30 #endif
31 #include <rpi_shared.h>
32
33 /* Event Log data */
34 #if TRANSFER_LIST
35 static uint8_t *event_log;
36 #else
37 uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE];
38 #endif
39
40 /* RPI3 table with platform specific image IDs, names and PCRs */
41 const event_log_metadata_t rpi3_event_log_metadata[] = {
42 { FW_CONFIG_ID, MBOOT_FW_CONFIG_STRING, PCR_0 },
43 { TB_FW_CONFIG_ID, MBOOT_TB_FW_CONFIG_STRING, PCR_0 },
44 { BL2_IMAGE_ID, MBOOT_BL2_IMAGE_STRING, PCR_0 },
45
46 { EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
47 };
48
49 #if DISCRETE_TPM
50 extern struct tpm_chip_data tpm_chip_data;
51 #if (TPM_INTERFACE == FIFO_SPI)
52
53 #endif
54
rpi3_bl1_tpm_early_interface_setup(void)55 static void rpi3_bl1_tpm_early_interface_setup(void)
56 {
57 #if TPM_INTERFACE_FIFO_SPI
58 int rc;
59 struct tpm_spi_plat *spidev;
60 const struct tpm_timeout_ops timeout_ops = {
61 .timeout_init_us = timeout_init_us,
62 .timeout_elapsed = timeout_elapsed
63 };
64 const struct gpio_spi_config *tpm_rpi3_gpio_data =
65 tpm2_slb9670_get_config();
66
67 tpm2_slb9670_gpio_init(tpm_rpi3_gpio_data);
68
69 tpm2_slb9670_reset_chip(tpm_rpi3_gpio_data);
70
71 spidev = gpio_spi_init(tpm_rpi3_gpio_data);
72
73 rc = tpm_interface_init(spidev, &timeout_ops, &tpm_chip_data, 0);
74 if (rc != 0) {
75 ERROR("BL1: TPM interface init failed\n");
76 panic();
77 }
78
79 #endif
80 }
81 #endif
82
bl1_plat_mboot_init(void)83 void bl1_plat_mboot_init(void)
84 {
85 size_t event_log_max_size __unused;
86 tpm_alg_id algorithms[] = {
87 #ifdef TPM_ALG_ID
88 TPM_ALG_ID
89 #else
90 /*
91 * TODO: with MEASURED_BOOT=1 several algorithms now compiled into Mbed-TLS,
92 * we ought to query the backend to figure out what algorithms to use.
93 */
94 EVLOG_TPM_ALG_SHA256,
95 EVLOG_TPM_ALG_SHA384,
96 EVLOG_TPM_ALG_SHA512,
97 #endif
98 };
99 int rc;
100
101 #if DISCRETE_TPM
102
103 rpi3_bl1_tpm_early_interface_setup();
104 rc = tpm_startup(&tpm_chip_data, TPM_SU_CLEAR);
105 if (rc != 0) {
106 ERROR("BL1: TPM Startup failed\n");
107 panic();
108 }
109 #endif
110
111 #if TRANSFER_LIST
112 event_log_max_size = PLAT_ARM_EVENT_LOG_MAX_SIZE;
113 event_log = transfer_list_event_log_extend(secure_tl, event_log_max_size);
114 assert(event_log != NULL);
115 rc = event_log_init_and_reg(event_log, event_log + event_log_max_size,
116 0U, crypto_mod_tcg_hash);
117 #else
118 rc = event_log_init_and_reg(event_log, event_log + sizeof(event_log),
119 0U, crypto_mod_tcg_hash);
120 #endif
121 if (rc < 0) {
122 ERROR("Failed to initialize event log (%d).\n", rc);
123 panic();
124 }
125
126 rc = event_log_write_header(algorithms, ARRAY_SIZE(algorithms), 0, NULL,
127 0);
128 if (rc < 0) {
129 ERROR("Failed to write event log header (%d).\n", rc);
130 panic();
131 }
132 }
133
bl1_plat_mboot_finish(void)134 void bl1_plat_mboot_finish(void)
135 {
136 size_t event_log_cur_size;
137 image_desc_t *image_desc;
138 entry_point_info_t *ep_info;
139 uint8_t *rc_ptr __unused;
140
141 event_log_cur_size = event_log_get_cur_size(event_log);
142 image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
143 assert(image_desc != NULL);
144
145 /* Get the entry point info */
146 ep_info = &image_desc->ep_info;
147 #if TRANSFER_LIST
148 /* Finalize event log TE size and set TL handoff args */
149 rc_ptr = transfer_list_event_log_finish(
150 secure_tl, (uintptr_t)event_log + event_log_cur_size);
151 if (rc_ptr == NULL) {
152 ERROR("BL1: Failed to finalize Event Log TL entry\n");
153 panic();
154 }
155 /* Ensure changes are visible to the next stage. */
156 flush_dcache_range((uintptr_t)secure_tl, secure_tl->size);
157 ep_info->args.arg3 = (uint64_t)secure_tl;
158 #else
159 ep_info->args.arg2 = (uint64_t) event_log;
160 ep_info->args.arg3 = (uint32_t) event_log_cur_size;
161 #endif
162
163 #if DISCRETE_TPM
164 int rc;
165
166 /* relinquish control of TPM locality 0 and close interface */
167 rc = tpm_interface_close(&tpm_chip_data, 0);
168 if (rc != 0) {
169 ERROR("BL1: TPM interface close failed\n");
170 panic();
171 }
172 #endif
173
174 /* Dump Event Log for user view */
175 event_log_dump((uint8_t *)event_log, event_log_get_cur_size(event_log));
176 }
177