1e62748e3SManish V Badarkhe /* 2e62748e3SManish V Badarkhe * Copyright (c) 2022 Arm Limited. All rights reserved. 3e62748e3SManish V Badarkhe * 4e62748e3SManish V Badarkhe * SPDX-License-Identifier: BSD-3-Clause 5e62748e3SManish V Badarkhe * 6e62748e3SManish V Badarkhe * DRTM service 7e62748e3SManish V Badarkhe * 8e62748e3SManish V Badarkhe * Authors: 9e62748e3SManish V Badarkhe * Lucian Paul-Trifu <lucian.paultrifu@gmail.com> 10e62748e3SManish V Badarkhe * Brian Nezvadovitz <brinez@microsoft.com> 2021-02-01 11e62748e3SManish V Badarkhe */ 12e62748e3SManish V Badarkhe 13e62748e3SManish V Badarkhe #include <stdint.h> 14e62748e3SManish V Badarkhe 15d54792bdSManish V Badarkhe #include <arch.h> 16d54792bdSManish V Badarkhe #include <arch_helpers.h> 172a1cdee4Sjohpow01 #include <common/bl_common.h> 18e62748e3SManish V Badarkhe #include <common/debug.h> 19e62748e3SManish V Badarkhe #include <common/runtime_svc.h> 20d54792bdSManish V Badarkhe #include <drivers/auth/crypto_mod.h> 21e62748e3SManish V Badarkhe #include "drtm_main.h" 222a1cdee4Sjohpow01 #include <lib/xlat_tables/xlat_tables_v2.h> 232a1cdee4Sjohpow01 #include <plat/common/platform.h> 24e62748e3SManish V Badarkhe #include <services/drtm_svc.h> 252a1cdee4Sjohpow01 #include <platform_def.h> 26e62748e3SManish V Badarkhe 272a1cdee4Sjohpow01 /* Structure to store DRTM features specific to the platform. */ 282a1cdee4Sjohpow01 static drtm_features_t plat_drtm_features; 292a1cdee4Sjohpow01 302a1cdee4Sjohpow01 /* DRTM-formatted memory map. */ 312a1cdee4Sjohpow01 static drtm_memory_region_descriptor_table_t *plat_drtm_mem_map; 32d54792bdSManish V Badarkhe 33e62748e3SManish V Badarkhe int drtm_setup(void) 34e62748e3SManish V Badarkhe { 35d54792bdSManish V Badarkhe bool rc; 362a1cdee4Sjohpow01 const plat_drtm_tpm_features_t *plat_tpm_feat; 372a1cdee4Sjohpow01 const plat_drtm_dma_prot_features_t *plat_dma_prot_feat; 382a1cdee4Sjohpow01 uint64_t dlme_data_min_size; 39d54792bdSManish V Badarkhe 40e62748e3SManish V Badarkhe INFO("DRTM service setup\n"); 41e62748e3SManish V Badarkhe 422a1cdee4Sjohpow01 /* Read boot PE ID from MPIDR */ 432a1cdee4Sjohpow01 plat_drtm_features.boot_pe_id = read_mpidr_el1() & MPIDR_AFFINITY_MASK; 44d54792bdSManish V Badarkhe 45d54792bdSManish V Badarkhe rc = drtm_dma_prot_init(); 46d54792bdSManish V Badarkhe if (rc) { 47d54792bdSManish V Badarkhe return INTERNAL_ERROR; 48d54792bdSManish V Badarkhe } 49d54792bdSManish V Badarkhe 50d54792bdSManish V Badarkhe /* 51d54792bdSManish V Badarkhe * initialise the platform supported crypto module that will 52d54792bdSManish V Badarkhe * be used by the DRTM-service to calculate hash of DRTM- 53d54792bdSManish V Badarkhe * implementation specific components 54d54792bdSManish V Badarkhe */ 55d54792bdSManish V Badarkhe crypto_mod_init(); 56d54792bdSManish V Badarkhe 572a1cdee4Sjohpow01 /* Build DRTM-compatible address map. */ 582a1cdee4Sjohpow01 plat_drtm_mem_map = drtm_build_address_map(); 592a1cdee4Sjohpow01 if (plat_drtm_mem_map == NULL) { 602a1cdee4Sjohpow01 return INTERNAL_ERROR; 612a1cdee4Sjohpow01 } 622a1cdee4Sjohpow01 632a1cdee4Sjohpow01 /* Get DRTM features from platform hooks. */ 642a1cdee4Sjohpow01 plat_tpm_feat = plat_drtm_get_tpm_features(); 652a1cdee4Sjohpow01 if (plat_tpm_feat == NULL) { 662a1cdee4Sjohpow01 return INTERNAL_ERROR; 672a1cdee4Sjohpow01 } 682a1cdee4Sjohpow01 692a1cdee4Sjohpow01 plat_dma_prot_feat = plat_drtm_get_dma_prot_features(); 702a1cdee4Sjohpow01 if (plat_dma_prot_feat == NULL) { 712a1cdee4Sjohpow01 return INTERNAL_ERROR; 722a1cdee4Sjohpow01 } 732a1cdee4Sjohpow01 742a1cdee4Sjohpow01 /* 752a1cdee4Sjohpow01 * Add up minimum DLME data memory. 762a1cdee4Sjohpow01 * 772a1cdee4Sjohpow01 * For systems with complete DMA protection there is only one entry in 782a1cdee4Sjohpow01 * the protected regions table. 792a1cdee4Sjohpow01 */ 802a1cdee4Sjohpow01 if (plat_dma_prot_feat->dma_protection_support == 812a1cdee4Sjohpow01 ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_COMPLETE) { 822a1cdee4Sjohpow01 dlme_data_min_size = 832a1cdee4Sjohpow01 sizeof(drtm_memory_region_descriptor_table_t) + 842a1cdee4Sjohpow01 sizeof(drtm_mem_region_t); 852a1cdee4Sjohpow01 } else { 862a1cdee4Sjohpow01 /* 872a1cdee4Sjohpow01 * TODO set protected regions table size based on platform DMA 882a1cdee4Sjohpow01 * protection configuration 892a1cdee4Sjohpow01 */ 902a1cdee4Sjohpow01 panic(); 912a1cdee4Sjohpow01 } 922a1cdee4Sjohpow01 932a1cdee4Sjohpow01 dlme_data_min_size += (drtm_get_address_map_size() + 942a1cdee4Sjohpow01 PLAT_DRTM_EVENT_LOG_MAX_SIZE + 952a1cdee4Sjohpow01 plat_drtm_get_tcb_hash_table_size() + 962a1cdee4Sjohpow01 plat_drtm_get_imp_def_dlme_region_size()); 972a1cdee4Sjohpow01 982a1cdee4Sjohpow01 dlme_data_min_size = page_align(dlme_data_min_size, UP)/PAGE_SIZE; 992a1cdee4Sjohpow01 1002a1cdee4Sjohpow01 /* Fill out platform DRTM features structure */ 1012a1cdee4Sjohpow01 /* Only support default PCR schema (0x1) in this implementation. */ 1022a1cdee4Sjohpow01 ARM_DRTM_TPM_FEATURES_SET_PCR_SCHEMA(plat_drtm_features.tpm_features, 1032a1cdee4Sjohpow01 ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_DEFAULT); 1042a1cdee4Sjohpow01 ARM_DRTM_TPM_FEATURES_SET_TPM_HASH(plat_drtm_features.tpm_features, 1052a1cdee4Sjohpow01 plat_tpm_feat->tpm_based_hash_support); 1062a1cdee4Sjohpow01 ARM_DRTM_TPM_FEATURES_SET_FW_HASH(plat_drtm_features.tpm_features, 1072a1cdee4Sjohpow01 plat_tpm_feat->firmware_hash_algorithm); 1082a1cdee4Sjohpow01 ARM_DRTM_MIN_MEM_REQ_SET_MIN_DLME_DATA_SIZE(plat_drtm_features.minimum_memory_requirement, 1092a1cdee4Sjohpow01 dlme_data_min_size); 1102a1cdee4Sjohpow01 ARM_DRTM_MIN_MEM_REQ_SET_DCE_SIZE(plat_drtm_features.minimum_memory_requirement, 1112a1cdee4Sjohpow01 plat_drtm_get_min_size_normal_world_dce()); 1122a1cdee4Sjohpow01 ARM_DRTM_DMA_PROT_FEATURES_SET_MAX_REGIONS(plat_drtm_features.dma_prot_features, 1132a1cdee4Sjohpow01 plat_dma_prot_feat->max_num_mem_prot_regions); 1142a1cdee4Sjohpow01 ARM_DRTM_DMA_PROT_FEATURES_SET_DMA_SUPPORT(plat_drtm_features.dma_prot_features, 1152a1cdee4Sjohpow01 plat_dma_prot_feat->dma_protection_support); 1162a1cdee4Sjohpow01 ARM_DRTM_TCB_HASH_FEATURES_SET_MAX_NUM_HASHES(plat_drtm_features.tcb_hash_features, 1172a1cdee4Sjohpow01 plat_drtm_get_tcb_hash_features()); 1182a1cdee4Sjohpow01 119e62748e3SManish V Badarkhe return 0; 120e62748e3SManish V Badarkhe } 121e62748e3SManish V Badarkhe 122*e9467afbSManish V Badarkhe static inline uint64_t drtm_features_tpm(void *ctx) 123*e9467afbSManish V Badarkhe { 124*e9467afbSManish V Badarkhe SMC_RET2(ctx, 1ULL, /* TPM feature is supported */ 125*e9467afbSManish V Badarkhe plat_drtm_features.tpm_features); 126*e9467afbSManish V Badarkhe } 127*e9467afbSManish V Badarkhe 128*e9467afbSManish V Badarkhe static inline uint64_t drtm_features_mem_req(void *ctx) 129*e9467afbSManish V Badarkhe { 130*e9467afbSManish V Badarkhe SMC_RET2(ctx, 1ULL, /* memory req Feature is supported */ 131*e9467afbSManish V Badarkhe plat_drtm_features.minimum_memory_requirement); 132*e9467afbSManish V Badarkhe } 133*e9467afbSManish V Badarkhe 134*e9467afbSManish V Badarkhe static inline uint64_t drtm_features_boot_pe_id(void *ctx) 135*e9467afbSManish V Badarkhe { 136*e9467afbSManish V Badarkhe SMC_RET2(ctx, 1ULL, /* Boot PE feature is supported */ 137*e9467afbSManish V Badarkhe plat_drtm_features.boot_pe_id); 138*e9467afbSManish V Badarkhe } 139*e9467afbSManish V Badarkhe 140*e9467afbSManish V Badarkhe static inline uint64_t drtm_features_dma_prot(void *ctx) 141*e9467afbSManish V Badarkhe { 142*e9467afbSManish V Badarkhe SMC_RET2(ctx, 1ULL, /* DMA protection feature is supported */ 143*e9467afbSManish V Badarkhe plat_drtm_features.dma_prot_features); 144*e9467afbSManish V Badarkhe } 145*e9467afbSManish V Badarkhe 146*e9467afbSManish V Badarkhe static inline uint64_t drtm_features_tcb_hashes(void *ctx) 147*e9467afbSManish V Badarkhe { 148*e9467afbSManish V Badarkhe SMC_RET2(ctx, 1ULL, /* TCB hash feature is supported */ 149*e9467afbSManish V Badarkhe plat_drtm_features.tcb_hash_features); 150*e9467afbSManish V Badarkhe } 151*e9467afbSManish V Badarkhe 152e62748e3SManish V Badarkhe uint64_t drtm_smc_handler(uint32_t smc_fid, 153e62748e3SManish V Badarkhe uint64_t x1, 154e62748e3SManish V Badarkhe uint64_t x2, 155e62748e3SManish V Badarkhe uint64_t x3, 156e62748e3SManish V Badarkhe uint64_t x4, 157e62748e3SManish V Badarkhe void *cookie, 158e62748e3SManish V Badarkhe void *handle, 159e62748e3SManish V Badarkhe uint64_t flags) 160e62748e3SManish V Badarkhe { 161e62748e3SManish V Badarkhe /* Check that the SMC call is from the Normal World. */ 162e62748e3SManish V Badarkhe if (!is_caller_non_secure(flags)) { 163e62748e3SManish V Badarkhe SMC_RET1(handle, NOT_SUPPORTED); 164e62748e3SManish V Badarkhe } 165e62748e3SManish V Badarkhe 166e62748e3SManish V Badarkhe switch (smc_fid) { 167e62748e3SManish V Badarkhe case ARM_DRTM_SVC_VERSION: 168e62748e3SManish V Badarkhe INFO("DRTM service handler: version\n"); 169e62748e3SManish V Badarkhe /* Return the version of current implementation */ 170e62748e3SManish V Badarkhe SMC_RET1(handle, ARM_DRTM_VERSION); 171e62748e3SManish V Badarkhe break; /* not reached */ 172e62748e3SManish V Badarkhe 173e62748e3SManish V Badarkhe case ARM_DRTM_SVC_FEATURES: 174e62748e3SManish V Badarkhe if (((x1 >> ARM_DRTM_FUNC_SHIFT) & ARM_DRTM_FUNC_MASK) == 175e62748e3SManish V Badarkhe ARM_DRTM_FUNC_ID) { 176e62748e3SManish V Badarkhe /* Dispatch function-based queries. */ 177e62748e3SManish V Badarkhe switch (x1 & FUNCID_MASK) { 178e62748e3SManish V Badarkhe case ARM_DRTM_SVC_VERSION: 179e62748e3SManish V Badarkhe SMC_RET1(handle, SUCCESS); 180e62748e3SManish V Badarkhe break; /* not reached */ 181e62748e3SManish V Badarkhe 182e62748e3SManish V Badarkhe case ARM_DRTM_SVC_FEATURES: 183e62748e3SManish V Badarkhe SMC_RET1(handle, SUCCESS); 184e62748e3SManish V Badarkhe break; /* not reached */ 185e62748e3SManish V Badarkhe 186e62748e3SManish V Badarkhe case ARM_DRTM_SVC_UNPROTECT_MEM: 187e62748e3SManish V Badarkhe SMC_RET1(handle, SUCCESS); 188e62748e3SManish V Badarkhe break; /* not reached */ 189e62748e3SManish V Badarkhe 190e62748e3SManish V Badarkhe case ARM_DRTM_SVC_DYNAMIC_LAUNCH: 191e62748e3SManish V Badarkhe SMC_RET1(handle, SUCCESS); 192e62748e3SManish V Badarkhe break; /* not reached */ 193e62748e3SManish V Badarkhe 194e62748e3SManish V Badarkhe case ARM_DRTM_SVC_CLOSE_LOCALITY: 195e62748e3SManish V Badarkhe WARN("ARM_DRTM_SVC_CLOSE_LOCALITY feature %s", 196e62748e3SManish V Badarkhe "is not supported\n"); 197e62748e3SManish V Badarkhe SMC_RET1(handle, NOT_SUPPORTED); 198e62748e3SManish V Badarkhe break; /* not reached */ 199e62748e3SManish V Badarkhe 200e62748e3SManish V Badarkhe case ARM_DRTM_SVC_GET_ERROR: 201e62748e3SManish V Badarkhe SMC_RET1(handle, SUCCESS); 202e62748e3SManish V Badarkhe break; /* not reached */ 203e62748e3SManish V Badarkhe 204e62748e3SManish V Badarkhe case ARM_DRTM_SVC_SET_ERROR: 205e62748e3SManish V Badarkhe SMC_RET1(handle, SUCCESS); 206e62748e3SManish V Badarkhe break; /* not reached */ 207e62748e3SManish V Badarkhe 208e62748e3SManish V Badarkhe case ARM_DRTM_SVC_SET_TCB_HASH: 209e62748e3SManish V Badarkhe WARN("ARM_DRTM_SVC_TCB_HASH feature %s", 210e62748e3SManish V Badarkhe "is not supported\n"); 211e62748e3SManish V Badarkhe SMC_RET1(handle, NOT_SUPPORTED); 212e62748e3SManish V Badarkhe break; /* not reached */ 213e62748e3SManish V Badarkhe 214e62748e3SManish V Badarkhe case ARM_DRTM_SVC_LOCK_TCB_HASH: 215e62748e3SManish V Badarkhe WARN("ARM_DRTM_SVC_LOCK_TCB_HASH feature %s", 216e62748e3SManish V Badarkhe "is not supported\n"); 217e62748e3SManish V Badarkhe SMC_RET1(handle, NOT_SUPPORTED); 218e62748e3SManish V Badarkhe break; /* not reached */ 219e62748e3SManish V Badarkhe 220e62748e3SManish V Badarkhe default: 221e62748e3SManish V Badarkhe ERROR("Unknown DRTM service function\n"); 222e62748e3SManish V Badarkhe SMC_RET1(handle, NOT_SUPPORTED); 223e62748e3SManish V Badarkhe break; /* not reached */ 224e62748e3SManish V Badarkhe } 225*e9467afbSManish V Badarkhe } else { 226*e9467afbSManish V Badarkhe /* Dispatch feature-based queries. */ 227*e9467afbSManish V Badarkhe switch (x1 & ARM_DRTM_FEAT_ID_MASK) { 228*e9467afbSManish V Badarkhe case ARM_DRTM_FEATURES_TPM: 229*e9467afbSManish V Badarkhe INFO("++ DRTM service handler: TPM features\n"); 230*e9467afbSManish V Badarkhe return drtm_features_tpm(handle); 231*e9467afbSManish V Badarkhe break; /* not reached */ 232*e9467afbSManish V Badarkhe 233*e9467afbSManish V Badarkhe case ARM_DRTM_FEATURES_MEM_REQ: 234*e9467afbSManish V Badarkhe INFO("++ DRTM service handler: Min. mem." 235*e9467afbSManish V Badarkhe " requirement features\n"); 236*e9467afbSManish V Badarkhe return drtm_features_mem_req(handle); 237*e9467afbSManish V Badarkhe break; /* not reached */ 238*e9467afbSManish V Badarkhe 239*e9467afbSManish V Badarkhe case ARM_DRTM_FEATURES_DMA_PROT: 240*e9467afbSManish V Badarkhe INFO("++ DRTM service handler: " 241*e9467afbSManish V Badarkhe "DMA protection features\n"); 242*e9467afbSManish V Badarkhe return drtm_features_dma_prot(handle); 243*e9467afbSManish V Badarkhe break; /* not reached */ 244*e9467afbSManish V Badarkhe 245*e9467afbSManish V Badarkhe case ARM_DRTM_FEATURES_BOOT_PE_ID: 246*e9467afbSManish V Badarkhe INFO("++ DRTM service handler: " 247*e9467afbSManish V Badarkhe "Boot PE ID features\n"); 248*e9467afbSManish V Badarkhe return drtm_features_boot_pe_id(handle); 249*e9467afbSManish V Badarkhe break; /* not reached */ 250*e9467afbSManish V Badarkhe 251*e9467afbSManish V Badarkhe case ARM_DRTM_FEATURES_TCB_HASHES: 252*e9467afbSManish V Badarkhe INFO("++ DRTM service handler: " 253*e9467afbSManish V Badarkhe "TCB-hashes features\n"); 254*e9467afbSManish V Badarkhe return drtm_features_tcb_hashes(handle); 255*e9467afbSManish V Badarkhe break; /* not reached */ 256*e9467afbSManish V Badarkhe 257*e9467afbSManish V Badarkhe default: 258*e9467afbSManish V Badarkhe ERROR("Unknown ARM DRTM service feature\n"); 259*e9467afbSManish V Badarkhe SMC_RET1(handle, NOT_SUPPORTED); 260*e9467afbSManish V Badarkhe break; /* not reached */ 261*e9467afbSManish V Badarkhe } 262e62748e3SManish V Badarkhe } 263e62748e3SManish V Badarkhe 264e62748e3SManish V Badarkhe case ARM_DRTM_SVC_UNPROTECT_MEM: 265e62748e3SManish V Badarkhe INFO("DRTM service handler: unprotect mem\n"); 266e62748e3SManish V Badarkhe SMC_RET1(handle, SMC_OK); 267e62748e3SManish V Badarkhe break; /* not reached */ 268e62748e3SManish V Badarkhe 269e62748e3SManish V Badarkhe case ARM_DRTM_SVC_DYNAMIC_LAUNCH: 270e62748e3SManish V Badarkhe INFO("DRTM service handler: dynamic launch\n"); 271e62748e3SManish V Badarkhe SMC_RET1(handle, SMC_OK); 272e62748e3SManish V Badarkhe break; /* not reached */ 273e62748e3SManish V Badarkhe 274e62748e3SManish V Badarkhe case ARM_DRTM_SVC_CLOSE_LOCALITY: 275e62748e3SManish V Badarkhe WARN("DRTM service handler: close locality %s\n", 276e62748e3SManish V Badarkhe "is not supported"); 277e62748e3SManish V Badarkhe SMC_RET1(handle, NOT_SUPPORTED); 278e62748e3SManish V Badarkhe break; /* not reached */ 279e62748e3SManish V Badarkhe 280e62748e3SManish V Badarkhe case ARM_DRTM_SVC_GET_ERROR: 281e62748e3SManish V Badarkhe INFO("DRTM service handler: get error\n"); 282e62748e3SManish V Badarkhe SMC_RET2(handle, SMC_OK, 0); 283e62748e3SManish V Badarkhe break; /* not reached */ 284e62748e3SManish V Badarkhe 285e62748e3SManish V Badarkhe case ARM_DRTM_SVC_SET_ERROR: 286e62748e3SManish V Badarkhe INFO("DRTM service handler: set error\n"); 287e62748e3SManish V Badarkhe SMC_RET1(handle, SMC_OK); 288e62748e3SManish V Badarkhe break; /* not reached */ 289e62748e3SManish V Badarkhe 290e62748e3SManish V Badarkhe case ARM_DRTM_SVC_SET_TCB_HASH: 291e62748e3SManish V Badarkhe WARN("DRTM service handler: set TCB hash %s\n", 292e62748e3SManish V Badarkhe "is not supported"); 293e62748e3SManish V Badarkhe SMC_RET1(handle, NOT_SUPPORTED); 294e62748e3SManish V Badarkhe break; /* not reached */ 295e62748e3SManish V Badarkhe 296e62748e3SManish V Badarkhe case ARM_DRTM_SVC_LOCK_TCB_HASH: 297e62748e3SManish V Badarkhe WARN("DRTM service handler: lock TCB hash %s\n", 298e62748e3SManish V Badarkhe "is not supported"); 299e62748e3SManish V Badarkhe SMC_RET1(handle, NOT_SUPPORTED); 300e62748e3SManish V Badarkhe break; /* not reached */ 301e62748e3SManish V Badarkhe 302e62748e3SManish V Badarkhe default: 303e62748e3SManish V Badarkhe ERROR("Unknown DRTM service function: 0x%x\n", smc_fid); 304e62748e3SManish V Badarkhe SMC_RET1(handle, SMC_UNK); 305e62748e3SManish V Badarkhe break; /* not reached */ 306e62748e3SManish V Badarkhe } 307e62748e3SManish V Badarkhe 308e62748e3SManish V Badarkhe /* not reached */ 309e62748e3SManish V Badarkhe SMC_RET1(handle, SMC_UNK); 310e62748e3SManish V Badarkhe } 311