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