1 // SPDX-License-Identifier: BSD-3-Clause 2 /* 3 * Copyright (c) 2020-2022, 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 err = fdt_setprop(fdt, node, dt_tpm_event_log_addr, &zero_addr, 51 sizeof(uint32_t) * 2); 52 if (err < 0) { 53 EMSG("Error setting property DTB to zero\n"); 54 return err; 55 } 56 57 /* 58 * Get the TPM Log size. 59 */ 60 property = fdt_getprop(fdt, node, "tpm_event_log_size", &len_prop); 61 62 if (!property || len_prop != sizeof(uint32_t)) 63 return -1; 64 65 *size = fdt32_to_cpu(property[0]); 66 *buf = log_addr; 67 68 return *size; 69 } 70 #endif 71 72 static void get_tpm_phys_params(void *fdt __maybe_unused, 73 paddr_t *addr, size_t *size) 74 { 75 #ifdef CFG_DT 76 int node = 0; 77 const char *dt_tpm_match_table = { 78 "arm,tpm_event_log", 79 }; 80 81 if (!fdt) { 82 EMSG("TPM: No DTB found"); 83 return; 84 } 85 86 node = fdt_node_offset_by_compatible(fdt, -1, dt_tpm_match_table); 87 88 if (node < 0) { 89 EMSG("TPM: Fail to find TPM node %i", node); 90 return; 91 } 92 93 if (read_dt_tpm_log_info((void *)fdt, node, addr, size) < 0) { 94 EMSG("TPM: Fail to retrieve DTB properties from node %i", 95 node); 96 return; 97 } 98 #else 99 *size = CFG_TPM_MAX_LOG_SIZE; 100 *addr = CFG_TPM_LOG_BASE_ADDR; 101 #endif /* CFG_DT */ 102 } 103 104 TEE_Result tpm_get_event_log(void *buf, size_t *size) 105 { 106 const size_t buf_size = *size; 107 108 *size = tpm_log_size; 109 if (!buf) { 110 EMSG("TPM: Invalid buffer"); 111 return TEE_ERROR_BAD_PARAMETERS; 112 } 113 114 if (buf_size < tpm_log_size) { 115 EMSG("TPM: Not enough space for the log: %zu, %zu", 116 buf_size, tpm_log_size); 117 return TEE_ERROR_SHORT_BUFFER; 118 } 119 120 memcpy(buf, tpm_log_addr, tpm_log_size); 121 122 return TEE_SUCCESS; 123 } 124 125 TEE_Result tpm_get_event_log_size(size_t *size) 126 { 127 *size = tpm_log_size; 128 129 return TEE_SUCCESS; 130 } 131 132 void tpm_map_log_area(void *fdt) 133 { 134 paddr_t log_addr = 0; 135 unsigned int rounded_size = 0; 136 137 get_tpm_phys_params(fdt, &log_addr, &tpm_log_size); 138 139 DMSG("TPM Event log PA: %#" PRIxPA, log_addr); 140 DMSG("TPM Event log size: %zu Bytes", tpm_log_size); 141 142 rounded_size = ROUNDUP(tpm_log_size, SMALL_PAGE_SIZE); 143 144 tpm_log_addr = core_mmu_add_mapping(MEM_AREA_RAM_SEC, log_addr, 145 rounded_size); 146 if (!tpm_log_addr) { 147 EMSG("TPM: Failed to map TPM log memory"); 148 return; 149 } 150 } 151