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