diff --git a/bl31/bl31.mk b/bl31/bl31.mk index ec7062755..f435815ce 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -148,8 +148,9 @@ BL31_SOURCES += common/feat_detect.c endif ifeq (${DRTM_SUPPORT},1) -BL31_SOURCES += services/std_svc/drtm/drtm_main.c \ - services/std_svc/drtm/drtm_dma_prot.c \ +BL31_SOURCES += services/std_svc/drtm/drtm_main.c \ + services/std_svc/drtm/drtm_dma_prot.c \ + services/std_svc/drtm/drtm_res_address_map.c \ ${MBEDTLS_SOURCES} endif diff --git a/include/lib/xlat_tables/xlat_tables_compat.h b/include/lib/xlat_tables/xlat_tables_compat.h index 90768db5d..5f281957a 100644 --- a/include/lib/xlat_tables/xlat_tables_compat.h +++ b/include/lib/xlat_tables/xlat_tables_compat.h @@ -1,11 +1,16 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#ifndef XLAT_TABLES_COMPAT_H +#define XLAT_TABLES_COMPAT_H + #if XLAT_TABLES_LIB_V2 #include #else #include #endif + +#endif /* XLAT_TABLES_COMPAT_H */ diff --git a/include/plat/common/plat_drtm.h b/include/plat/common/plat_drtm.h index 3c4e3d536..e9b8d6a70 100644 --- a/include/plat/common/plat_drtm.h +++ b/include/plat/common/plat_drtm.h @@ -7,11 +7,57 @@ #ifndef PLAT_DRTM_H #define PLAT_DRTM_H +#include +#include + +typedef struct { + uint8_t max_num_mem_prot_regions; + uint8_t dma_protection_support; +} plat_drtm_dma_prot_features_t; + +typedef struct { + bool tpm_based_hash_support; + uint32_t firmware_hash_algorithm; +} plat_drtm_tpm_features_t; + +typedef struct { + uint64_t region_address; + uint64_t region_size_type; +} __attribute__((packed)) drtm_mem_region_t; + +/* + * Memory region descriptor table structure as per DRTM beta0 section 3.13 + * Table 11 MEMORY_REGION_DESCRIPTOR_TABLE + */ +typedef struct { + uint16_t revision; + uint16_t reserved; + uint32_t num_regions; + drtm_mem_region_t region[]; +} __attribute__((packed)) drtm_memory_region_descriptor_table_t; + +/* platform specific address map functions */ +const mmap_region_t *plat_get_addr_mmap(void); + /* platform-specific DMA protection functions */ bool plat_has_non_host_platforms(void); bool plat_has_unmanaged_dma_peripherals(void); unsigned int plat_get_total_smmus(void); void plat_enumerate_smmus(const uintptr_t **smmus_out, size_t *smmu_count_out); +const plat_drtm_dma_prot_features_t *plat_drtm_get_dma_prot_features(void); +uint64_t plat_drtm_dma_prot_get_max_table_bytes(void); + +/* platform-specific TPM functions */ +const plat_drtm_tpm_features_t *plat_drtm_get_tpm_features(void); + +/* + * TODO: Implement these functions as per the platform use case, + * as of now none of the platform uses these functions + */ +uint64_t plat_drtm_get_min_size_normal_world_dce(void); +uint64_t plat_drtm_get_tcb_hash_table_size(void); +uint64_t plat_drtm_get_imp_def_dlme_region_size(void); +uint64_t plat_drtm_get_tcb_hash_features(void); #endif /* PLAT_DRTM_H */ diff --git a/include/services/drtm_svc.h b/include/services/drtm_svc.h index 6845ace9c..890cdbb0e 100644 --- a/include/services/drtm_svc.h +++ b/include/services/drtm_svc.h @@ -66,6 +66,158 @@ #define ARM_DRTM_FUNC_ID U(0x0) #define ARM_DRTM_FEAT_ID U(0x1) +/* + * Definitions for DRTM features as per DRTM beta0 section 3.3, + * Table 6 DRTM_FEATURES + */ +#define ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_SHIFT U(33) +#define ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_MASK ULL(0xF) +#define ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_DEFAULT ULL(0x1) + +#define ARM_DRTM_TPM_FEATURES_TPM_HASH_SHIFT U(32) +#define ARM_DRTM_TPM_FEATURES_TPM_HASH_MASK ULL(0x1) +#define ARM_DRTM_TPM_FEATURES_TPM_HASH_NOT_SUPPORTED ULL(0x0) +#define ARM_DRTM_TPM_FEATURES_TPM_HASH_SUPPORTED ULL(0x1) + +#define ARM_DRTM_TPM_FEATURES_FW_HASH_SHIFT U(0) +#define ARM_DRTM_TPM_FEATURES_FW_HASH_MASK ULL(0xFFFFFFFF) +#define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA256 ULL(0xB) +#define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA384 ULL(0xC) +#define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA512 ULL(0xD) + +#define ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_SHIFT U(32) +#define ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_MASK ULL(0xFFFFFFFF) + +#define ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_SHIFT U(0) +#define ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_MASK ULL(0xFFFFFFFF) + +#define ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_SHIFT U(8) +#define ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_MASK ULL(0xF) + +#define ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_SHIFT U(0) +#define ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_MASK ULL(0xFF) +#define ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_COMPLETE ULL(0x1) +#define ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_REGION ULL(0x2) + +#define ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_SHIFT U(0) +#define ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_MASK ULL(0xFF) + +#define ARM_DRTM_TPM_FEATURES_SET_PCR_SCHEMA(reg, val) \ + do { \ + reg = (((reg) & ~(ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_MASK \ + << ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_SHIFT)) | (((val) & \ + ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_MASK) << \ + ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_SHIFT)); \ + } while (false) + +#define ARM_DRTM_TPM_FEATURES_SET_TPM_HASH(reg, val) \ + do { \ + reg = (((reg) & ~(ARM_DRTM_TPM_FEATURES_TPM_HASH_MASK \ + << ARM_DRTM_TPM_FEATURES_TPM_HASH_SHIFT)) | (((val) & \ + ARM_DRTM_TPM_FEATURES_TPM_HASH_MASK) << \ + ARM_DRTM_TPM_FEATURES_TPM_HASH_SHIFT)); \ + } while (false) + +#define ARM_DRTM_TPM_FEATURES_SET_FW_HASH(reg, val) \ + do { \ + reg = (((reg) & ~(ARM_DRTM_TPM_FEATURES_FW_HASH_MASK \ + << ARM_DRTM_TPM_FEATURES_FW_HASH_SHIFT)) | (((val) & \ + ARM_DRTM_TPM_FEATURES_FW_HASH_MASK) << \ + ARM_DRTM_TPM_FEATURES_FW_HASH_SHIFT)); \ + } while (false) + +#define ARM_DRTM_MIN_MEM_REQ_SET_DCE_SIZE(reg, val) \ + do { \ + reg = (((reg) & ~(ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_MASK \ + << ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_SHIFT)) | (((val) & \ + ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_MASK) << \ + ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_SHIFT)); \ + } while (false) + +#define ARM_DRTM_MIN_MEM_REQ_SET_MIN_DLME_DATA_SIZE(reg, val) \ + do { \ + reg = (((reg) & \ + ~(ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_MASK << \ + ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_SHIFT)) | \ + (((val) & ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_MASK) \ + << ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_SHIFT)); \ + } while (false) + +#define ARM_DRTM_DMA_PROT_FEATURES_SET_MAX_REGIONS(reg, val) \ + do { \ + reg = (((reg) & \ + ~(ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_MASK << \ + ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_SHIFT)) | \ + (((val) & ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_MASK) \ + << ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_SHIFT)); \ + } while (false) + +#define ARM_DRTM_DMA_PROT_FEATURES_SET_DMA_SUPPORT(reg, val) \ + do { \ + reg = (((reg) & \ + ~(ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_MASK << \ + ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_SHIFT)) | \ + (((val) & ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_MASK) \ + << ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_SHIFT)); \ + } while (false) + +#define ARM_DRTM_TCB_HASH_FEATURES_SET_MAX_NUM_HASHES(reg, val) \ + do { \ + reg = (((reg) & \ + ~(ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_MASK << \ + ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_SHIFT)) | \ + (((val) & \ + ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_MASK) << \ + ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_SHIFT)); \ + } while (false) + +/* Definitions for DRTM address map */ +#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_SHIFT U(55) +#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_MASK ULL(0x3) +#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_NC ULL(0) +#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_WC ULL(1) +#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_WT ULL(2) +#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_WB ULL(3) + +#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_SHIFT U(52) +#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_MASK ULL(0x7) +#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NORMAL ULL(0) +#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NCAR ULL(1) +#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_DEVICE ULL(2) +#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NV ULL(3) +#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_RSVD ULL(4) + +#define ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_SHIFT U(0) +#define ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_MASK ULL(0xFFFFFFFFFFFFF) + +#define ARM_DRTM_REGION_SIZE_TYPE_SET_CACHEABILITY(reg, val) \ + do { \ + reg = (((reg) & \ + ~(ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_MASK << \ + ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_SHIFT)) | \ + (((val) & \ + ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_MASK) << \ + ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_SHIFT)); \ + } while (false) + +#define ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(reg, val) \ + do { \ + reg = (((reg) & \ + ~(ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_MASK << \ + ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_SHIFT)) | \ + (((val) & ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_MASK) \ + << ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_SHIFT)); \ + } while (false) + +#define ARM_DRTM_REGION_SIZE_TYPE_SET_4K_PAGE_NUM(reg, val) \ + do { \ + reg = (((reg) & \ + ~(ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_MASK << \ + ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_SHIFT)) | \ + (((val) & ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_MASK) \ + << ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_SHIFT)); \ + } while (false) + /* Initialization routine for the DRTM service */ int drtm_setup(void); diff --git a/plat/arm/board/fvp/fvp_drtm_dma_prot.c b/plat/arm/board/fvp/fvp_drtm_dma_prot.c index ec9cd7a2e..38ff7fe38 100644 --- a/plat/arm/board/fvp/fvp_drtm_dma_prot.c +++ b/plat/arm/board/fvp/fvp_drtm_dma_prot.c @@ -58,3 +58,19 @@ void plat_enumerate_smmus(const uintptr_t **smmus_out, *smmu_count_out = 0; } } + +/* DRTM DMA Protection Features */ +static const plat_drtm_dma_prot_features_t dma_prot_features = { + .max_num_mem_prot_regions = 0, /* No protection regions are present */ + .dma_protection_support = 0x1 /* Complete DMA protection only */ +}; + +const plat_drtm_dma_prot_features_t *plat_drtm_get_dma_prot_features(void) +{ + return &dma_prot_features; +} + +uint64_t plat_drtm_dma_prot_get_max_table_bytes(void) +{ + return 0U; +} diff --git a/plat/arm/board/fvp/fvp_drtm_measurement.c b/plat/arm/board/fvp/fvp_drtm_measurement.c new file mode 100644 index 000000000..4fbedd8bc --- /dev/null +++ b/plat/arm/board/fvp/fvp_drtm_measurement.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include + +#include + +/* DRTM TPM Features */ +static const plat_drtm_tpm_features_t tpm_features = { + /* No TPM-based hashing supported. */ + .tpm_based_hash_support = false, + + /* Set to decided algorithm by Event Log driver */ + .firmware_hash_algorithm = TPM_ALG_ID + +}; + +const plat_drtm_tpm_features_t *plat_drtm_get_tpm_features(void) +{ + return &tpm_features; +} diff --git a/plat/arm/board/fvp/fvp_drtm_stub.c b/plat/arm/board/fvp/fvp_drtm_stub.c new file mode 100644 index 000000000..e2bc5169a --- /dev/null +++ b/plat/arm/board/fvp/fvp_drtm_stub.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +#include + +#include + +/* + * This file contains DRTM platform functions which don't really do anything on + * FVP but are needed for DRTM to function. + */ + +uint64_t plat_drtm_get_min_size_normal_world_dce(void) +{ + return 0ULL; +} + +uint64_t plat_drtm_get_imp_def_dlme_region_size(void) +{ + return 0ULL; +} + +uint64_t plat_drtm_get_tcb_hash_features(void) +{ + return 0ULL; +} + +uint64_t plat_drtm_get_tcb_hash_table_size(void) +{ + return 0ULL; +} diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index efe149ab0..1ef6c87a2 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -403,4 +403,14 @@ */ #define PLAT_ARM_EVENT_LOG_MAX_SIZE UL(0x400) +/* + * Maximum size of Event Log buffer used for DRTM + */ +#define PLAT_DRTM_EVENT_LOG_MAX_SIZE UL(0x300) + +/* + * Number of MMAP entries used by DRTM implementation + */ +#define PLAT_DRTM_MMAP_ENTRIES PLAT_ARM_MMAP_ENTRIES + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 460227612..eb2b5e517 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -415,6 +415,8 @@ endif ifeq (${DRTM_SUPPORT}, 1) BL31_SOURCES += plat/arm/board/fvp/fvp_drtm_dma_prot.c \ + plat/arm/board/fvp/fvp_drtm_measurement.c \ + plat/arm/board/fvp/fvp_drtm_stub.c \ plat/arm/common/arm_dyn_cfg.c endif diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 946b7329f..fc681149e 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -237,3 +237,7 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) } #endif +const mmap_region_t *plat_get_addr_mmap(void) +{ + return plat_arm_mmap; +} diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c index adb929379..843fc5d35 100644 --- a/services/std_svc/drtm/drtm_main.c +++ b/services/std_svc/drtm/drtm_main.c @@ -14,22 +14,33 @@ #include #include +#include #include #include #include #include "drtm_main.h" +#include +#include #include +#include -/* This value is used by the SMC to advertise the boot PE */ -static uint64_t boot_pe_aff_value; +/* 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"); - boot_pe_aff_value = read_mpidr_el1() & MPIDR_AFFINITY_MASK; + /* 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) { @@ -43,6 +54,68 @@ int drtm_setup(void) */ 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; } diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h index 4c1adac04..b60d95458 100644 --- a/services/std_svc/drtm/drtm_main.h +++ b/services/std_svc/drtm/drtm_main.h @@ -23,4 +23,15 @@ enum drtm_retc { MEM_PROTECT_INVALID = -6, }; +typedef struct { + uint64_t tpm_features; + uint64_t minimum_memory_requirement; + uint64_t dma_prot_features; + uint64_t boot_pe_id; + uint64_t tcb_hash_features; +} drtm_features_t; + +drtm_memory_region_descriptor_table_t *drtm_build_address_map(void); +uint64_t drtm_get_address_map_size(void); + #endif /* DRTM_MAIN_H */ diff --git a/services/std_svc/drtm/drtm_res_address_map.c b/services/std_svc/drtm/drtm_res_address_map.c new file mode 100644 index 000000000..86367061e --- /dev/null +++ b/services/std_svc/drtm/drtm_res_address_map.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +/* Address map revision generated by this code. */ +#define DRTM_ADDRESS_MAP_REVISION U(0x0001) + +/* Amount of space needed for address map based on PLAT_DRTM_MMAP_ENTRIES */ +#define DRTM_ADDRESS_MAP_SIZE (sizeof(drtm_memory_region_descriptor_table_t) + \ + (sizeof(drtm_mem_region_t) * \ + PLAT_DRTM_MMAP_ENTRIES)) + +/* Allocate space for DRTM-formatted address map to be constructed. */ +static uint8_t drtm_address_map[DRTM_ADDRESS_MAP_SIZE]; + +static uint64_t drtm_address_map_size; + +drtm_memory_region_descriptor_table_t *drtm_build_address_map(void) +{ + /* Set up pointer to DRTM memory map. */ + drtm_memory_region_descriptor_table_t *map = + (drtm_memory_region_descriptor_table_t *)drtm_address_map; + + /* Get the platform memory map. */ + const mmap_region_t *mmap = plat_get_addr_mmap(); + unsigned int i; + + /* Set up header for address map structure. */ + map->revision = DRTM_ADDRESS_MAP_REVISION; + map->reserved = 0x0000; + + /* Iterate through mmap and generate DRTM address map. */ + for (i = 0U; mmap[i].base_pa != 0UL; i++) { + /* Set PA of region. */ + map->region[i].region_address = mmap[i].base_pa; + + /* Set size of region (in 4kb chunks). */ + map->region[i].region_size_type = 0; + ARM_DRTM_REGION_SIZE_TYPE_SET_4K_PAGE_NUM( + map->region[i].region_size_type, + mmap[i].size / PAGE_SIZE_4KB); + + /* Set type and cacheability. */ + switch (MT_TYPE(mmap[i].attr)) { + case MT_DEVICE: + ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE( + map->region[i].region_size_type, + ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_DEVICE); + break; + case MT_NON_CACHEABLE: + ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE( + map->region[i].region_size_type, + ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NCAR); + ARM_DRTM_REGION_SIZE_TYPE_SET_CACHEABILITY( + map->region[i].region_size_type, + ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_NC); + break; + case MT_MEMORY: + ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE( + map->region[i].region_size_type, + ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NORMAL); + break; + default: + return NULL; + } + } + + map->num_regions = i; + + /* Store total size of address map. */ + drtm_address_map_size = sizeof(drtm_memory_region_descriptor_table_t); + drtm_address_map_size += (i * sizeof(drtm_mem_region_t)); + + return map; +} + +uint64_t drtm_get_address_map_size(void) +{ + return drtm_address_map_size; +}