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