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