mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 18:14:24 +00:00

Added platform hooks to retrieve DRTM features and address map. Additionally, implemented these hooks for the FVP platform. Signed-off-by: John Powell <john.powell@arm.com> Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com> Change-Id: I5621cc9807ffff8139ae8876250147f7b2c76759
243 lines
6.7 KiB
C
243 lines
6.7 KiB
C
/*
|
|
* Copyright (c) 2022 Arm Limited. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*
|
|
* DRTM service
|
|
*
|
|
* Authors:
|
|
* Lucian Paul-Trifu <lucian.paultrifu@gmail.com>
|
|
* Brian Nezvadovitz <brinez@microsoft.com> 2021-02-01
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <arch.h>
|
|
#include <arch_helpers.h>
|
|
#include <common/bl_common.h>
|
|
#include <common/debug.h>
|
|
#include <common/runtime_svc.h>
|
|
#include <drivers/auth/crypto_mod.h>
|
|
#include "drtm_main.h"
|
|
#include <lib/xlat_tables/xlat_tables_v2.h>
|
|
#include <plat/common/platform.h>
|
|
#include <services/drtm_svc.h>
|
|
#include <platform_def.h>
|
|
|
|
/* Structure to store DRTM features specific to the platform. */
|
|
static drtm_features_t plat_drtm_features;
|
|
|
|
/* DRTM-formatted memory map. */
|
|
static drtm_memory_region_descriptor_table_t *plat_drtm_mem_map;
|
|
|
|
int drtm_setup(void)
|
|
{
|
|
bool rc;
|
|
const plat_drtm_tpm_features_t *plat_tpm_feat;
|
|
const plat_drtm_dma_prot_features_t *plat_dma_prot_feat;
|
|
uint64_t dlme_data_min_size;
|
|
|
|
INFO("DRTM service setup\n");
|
|
|
|
/* Read boot PE ID from MPIDR */
|
|
plat_drtm_features.boot_pe_id = read_mpidr_el1() & MPIDR_AFFINITY_MASK;
|
|
|
|
rc = drtm_dma_prot_init();
|
|
if (rc) {
|
|
return INTERNAL_ERROR;
|
|
}
|
|
|
|
/*
|
|
* initialise the platform supported crypto module that will
|
|
* be used by the DRTM-service to calculate hash of DRTM-
|
|
* implementation specific components
|
|
*/
|
|
crypto_mod_init();
|
|
|
|
/* Build DRTM-compatible address map. */
|
|
plat_drtm_mem_map = drtm_build_address_map();
|
|
if (plat_drtm_mem_map == NULL) {
|
|
return INTERNAL_ERROR;
|
|
}
|
|
|
|
/* Get DRTM features from platform hooks. */
|
|
plat_tpm_feat = plat_drtm_get_tpm_features();
|
|
if (plat_tpm_feat == NULL) {
|
|
return INTERNAL_ERROR;
|
|
}
|
|
|
|
plat_dma_prot_feat = plat_drtm_get_dma_prot_features();
|
|
if (plat_dma_prot_feat == NULL) {
|
|
return INTERNAL_ERROR;
|
|
}
|
|
|
|
/*
|
|
* Add up minimum DLME data memory.
|
|
*
|
|
* For systems with complete DMA protection there is only one entry in
|
|
* the protected regions table.
|
|
*/
|
|
if (plat_dma_prot_feat->dma_protection_support ==
|
|
ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_COMPLETE) {
|
|
dlme_data_min_size =
|
|
sizeof(drtm_memory_region_descriptor_table_t) +
|
|
sizeof(drtm_mem_region_t);
|
|
} else {
|
|
/*
|
|
* TODO set protected regions table size based on platform DMA
|
|
* protection configuration
|
|
*/
|
|
panic();
|
|
}
|
|
|
|
dlme_data_min_size += (drtm_get_address_map_size() +
|
|
PLAT_DRTM_EVENT_LOG_MAX_SIZE +
|
|
plat_drtm_get_tcb_hash_table_size() +
|
|
plat_drtm_get_imp_def_dlme_region_size());
|
|
|
|
dlme_data_min_size = page_align(dlme_data_min_size, UP)/PAGE_SIZE;
|
|
|
|
/* Fill out platform DRTM features structure */
|
|
/* Only support default PCR schema (0x1) in this implementation. */
|
|
ARM_DRTM_TPM_FEATURES_SET_PCR_SCHEMA(plat_drtm_features.tpm_features,
|
|
ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_DEFAULT);
|
|
ARM_DRTM_TPM_FEATURES_SET_TPM_HASH(plat_drtm_features.tpm_features,
|
|
plat_tpm_feat->tpm_based_hash_support);
|
|
ARM_DRTM_TPM_FEATURES_SET_FW_HASH(plat_drtm_features.tpm_features,
|
|
plat_tpm_feat->firmware_hash_algorithm);
|
|
ARM_DRTM_MIN_MEM_REQ_SET_MIN_DLME_DATA_SIZE(plat_drtm_features.minimum_memory_requirement,
|
|
dlme_data_min_size);
|
|
ARM_DRTM_MIN_MEM_REQ_SET_DCE_SIZE(plat_drtm_features.minimum_memory_requirement,
|
|
plat_drtm_get_min_size_normal_world_dce());
|
|
ARM_DRTM_DMA_PROT_FEATURES_SET_MAX_REGIONS(plat_drtm_features.dma_prot_features,
|
|
plat_dma_prot_feat->max_num_mem_prot_regions);
|
|
ARM_DRTM_DMA_PROT_FEATURES_SET_DMA_SUPPORT(plat_drtm_features.dma_prot_features,
|
|
plat_dma_prot_feat->dma_protection_support);
|
|
ARM_DRTM_TCB_HASH_FEATURES_SET_MAX_NUM_HASHES(plat_drtm_features.tcb_hash_features,
|
|
plat_drtm_get_tcb_hash_features());
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint64_t drtm_smc_handler(uint32_t smc_fid,
|
|
uint64_t x1,
|
|
uint64_t x2,
|
|
uint64_t x3,
|
|
uint64_t x4,
|
|
void *cookie,
|
|
void *handle,
|
|
uint64_t flags)
|
|
{
|
|
/* Check that the SMC call is from the Normal World. */
|
|
if (!is_caller_non_secure(flags)) {
|
|
SMC_RET1(handle, NOT_SUPPORTED);
|
|
}
|
|
|
|
switch (smc_fid) {
|
|
case ARM_DRTM_SVC_VERSION:
|
|
INFO("DRTM service handler: version\n");
|
|
/* Return the version of current implementation */
|
|
SMC_RET1(handle, ARM_DRTM_VERSION);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_FEATURES:
|
|
if (((x1 >> ARM_DRTM_FUNC_SHIFT) & ARM_DRTM_FUNC_MASK) ==
|
|
ARM_DRTM_FUNC_ID) {
|
|
/* Dispatch function-based queries. */
|
|
switch (x1 & FUNCID_MASK) {
|
|
case ARM_DRTM_SVC_VERSION:
|
|
SMC_RET1(handle, SUCCESS);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_FEATURES:
|
|
SMC_RET1(handle, SUCCESS);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_UNPROTECT_MEM:
|
|
SMC_RET1(handle, SUCCESS);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_DYNAMIC_LAUNCH:
|
|
SMC_RET1(handle, SUCCESS);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_CLOSE_LOCALITY:
|
|
WARN("ARM_DRTM_SVC_CLOSE_LOCALITY feature %s",
|
|
"is not supported\n");
|
|
SMC_RET1(handle, NOT_SUPPORTED);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_GET_ERROR:
|
|
SMC_RET1(handle, SUCCESS);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_SET_ERROR:
|
|
SMC_RET1(handle, SUCCESS);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_SET_TCB_HASH:
|
|
WARN("ARM_DRTM_SVC_TCB_HASH feature %s",
|
|
"is not supported\n");
|
|
SMC_RET1(handle, NOT_SUPPORTED);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_LOCK_TCB_HASH:
|
|
WARN("ARM_DRTM_SVC_LOCK_TCB_HASH feature %s",
|
|
"is not supported\n");
|
|
SMC_RET1(handle, NOT_SUPPORTED);
|
|
break; /* not reached */
|
|
|
|
default:
|
|
ERROR("Unknown DRTM service function\n");
|
|
SMC_RET1(handle, NOT_SUPPORTED);
|
|
break; /* not reached */
|
|
}
|
|
}
|
|
|
|
case ARM_DRTM_SVC_UNPROTECT_MEM:
|
|
INFO("DRTM service handler: unprotect mem\n");
|
|
SMC_RET1(handle, SMC_OK);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_DYNAMIC_LAUNCH:
|
|
INFO("DRTM service handler: dynamic launch\n");
|
|
SMC_RET1(handle, SMC_OK);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_CLOSE_LOCALITY:
|
|
WARN("DRTM service handler: close locality %s\n",
|
|
"is not supported");
|
|
SMC_RET1(handle, NOT_SUPPORTED);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_GET_ERROR:
|
|
INFO("DRTM service handler: get error\n");
|
|
SMC_RET2(handle, SMC_OK, 0);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_SET_ERROR:
|
|
INFO("DRTM service handler: set error\n");
|
|
SMC_RET1(handle, SMC_OK);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_SET_TCB_HASH:
|
|
WARN("DRTM service handler: set TCB hash %s\n",
|
|
"is not supported");
|
|
SMC_RET1(handle, NOT_SUPPORTED);
|
|
break; /* not reached */
|
|
|
|
case ARM_DRTM_SVC_LOCK_TCB_HASH:
|
|
WARN("DRTM service handler: lock TCB hash %s\n",
|
|
"is not supported");
|
|
SMC_RET1(handle, NOT_SUPPORTED);
|
|
break; /* not reached */
|
|
|
|
default:
|
|
ERROR("Unknown DRTM service function: 0x%x\n", smc_fid);
|
|
SMC_RET1(handle, SMC_UNK);
|
|
break; /* not reached */
|
|
}
|
|
|
|
/* not reached */
|
|
SMC_RET1(handle, SMC_UNK);
|
|
}
|