1 // SPDX-License-Identifier: BSD-3-Clause 2 /* 3 * Copyright (c) 2020-2023, ARM Limited. All rights reserved. 4 * Copyright (c) 2025, NVIDIA Corporation & AFFILIATES. 5 */ 6 7 #include <compiler.h> 8 #include <kernel/dt.h> 9 #include <kernel/tpm.h> 10 #include <libfdt.h> 11 #include <mm/core_memprot.h> 12 #include <string.h> 13 14 static void *tpm_log_addr; 15 static size_t tpm_log_size; 16 17 /* 18 * Check whether the node at @offs contains TPM Event Log information or not. 19 * 20 * @offs is the offset of the node that describes the device in @fdt. 21 * @buf will contain the phy address of the TPM Event log. 22 * @size will contain the size of the mapped area. 23 * 24 * Returns the size of the mapped area or < 0 on failure. 25 */ 26 #ifdef CFG_DT 27 static int read_dt_tpm_log_info(void *fdt, int node, paddr_t *buf, 28 size_t *size) 29 { 30 const uint32_t *property = NULL; 31 const uint64_t zero_addr = 0; 32 int len_prop = 0; 33 paddr_t log_addr = 0; 34 int err = 0; 35 #ifdef CFG_MAP_EXT_DT_SECURE 36 const char *dt_tpm_event_log_addr = "tpm_event_log_addr"; 37 #else 38 const char *dt_tpm_event_log_addr = "tpm_event_log_sm_addr"; 39 #endif 40 41 /* 42 * Get the TPM Log address. 43 */ 44 property = fdt_getprop(fdt, node, dt_tpm_event_log_addr, &len_prop); 45 46 if (!property || len_prop != sizeof(uint32_t) * 2) 47 return -1; 48 49 log_addr = reg_pair_to_64(fdt32_to_cpu(property[0]), 50 fdt32_to_cpu(property[1])); 51 52 if (!IS_ENABLED(CFG_CORE_FFA)) { 53 err = fdt_setprop(fdt, node, dt_tpm_event_log_addr, &zero_addr, 54 sizeof(uint32_t) * 2); 55 if (err < 0) { 56 EMSG("Error setting property DTB to zero"); 57 return err; 58 } 59 } 60 61 /* 62 * Get the TPM Log size. 63 */ 64 property = fdt_getprop(fdt, node, "tpm_event_log_size", &len_prop); 65 66 if (!property || len_prop != sizeof(uint32_t)) 67 return -1; 68 69 *size = fdt32_to_cpu(property[0]); 70 *buf = log_addr; 71 72 return *size; 73 } 74 #endif 75 76 static void get_tpm_phys_params(void *fdt __maybe_unused, 77 paddr_t *addr, size_t *size) 78 { 79 #ifdef CFG_DT 80 int node = 0; 81 const char *dt_tpm_match_table = { 82 "arm,tpm_event_log", 83 }; 84 85 if (!fdt) { 86 EMSG("TPM: No DTB found"); 87 return; 88 } 89 90 node = fdt_node_offset_by_compatible(fdt, -1, dt_tpm_match_table); 91 92 if (node < 0) { 93 EMSG("TPM: Fail to find TPM node %i", node); 94 return; 95 } 96 97 if (read_dt_tpm_log_info((void *)fdt, node, addr, size) < 0) { 98 EMSG("TPM: Fail to retrieve DTB properties from node %i", 99 node); 100 return; 101 } 102 #else 103 *size = CFG_TPM_MAX_LOG_SIZE; 104 *addr = CFG_TPM_LOG_BASE_ADDR; 105 #endif /* CFG_DT */ 106 } 107 108 TEE_Result tpm_get_event_log(void *buf, size_t *size) 109 { 110 const size_t buf_size = *size; 111 112 *size = tpm_log_size; 113 if (!buf) { 114 EMSG("TPM: Invalid buffer"); 115 return TEE_ERROR_BAD_PARAMETERS; 116 } 117 118 if (buf_size < tpm_log_size) { 119 EMSG("TPM: Not enough space for the log: %zu, %zu", 120 buf_size, tpm_log_size); 121 return TEE_ERROR_SHORT_BUFFER; 122 } 123 124 memcpy(buf, tpm_log_addr, tpm_log_size); 125 126 return TEE_SUCCESS; 127 } 128 129 TEE_Result tpm_get_event_log_size(size_t *size) 130 { 131 *size = tpm_log_size; 132 133 return TEE_SUCCESS; 134 } 135 136 void tpm_map_log_area(void *fdt) 137 { 138 paddr_t log_addr = 0; 139 unsigned int rounded_size = 0; 140 141 get_tpm_phys_params(fdt, &log_addr, &tpm_log_size); 142 143 DMSG("TPM Event log PA: %#" PRIxPA, log_addr); 144 DMSG("TPM Event log size: %zu Bytes", tpm_log_size); 145 146 rounded_size = ROUNDUP(tpm_log_size, SMALL_PAGE_SIZE); 147 148 tpm_log_addr = core_mmu_add_mapping(MEM_AREA_RAM_SEC, log_addr, 149 rounded_size); 150 if (!tpm_log_addr) { 151 EMSG("TPM: Failed to map TPM log memory"); 152 return; 153 } 154 } 155