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