1 /* 2 * Copyright (c) 2022-2025 Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stdint.h> 8 #include <stdlib.h> 9 10 #include <plat/common/platform.h> 11 #include <services/drtm_svc.h> 12 #include <platform_def.h> 13 14 /* Address map revision generated by this code. */ 15 #define DRTM_ADDRESS_MAP_REVISION U(0x0001) 16 17 /* Amount of space needed for address map based on PLAT_DRTM_MMAP_ENTRIES */ 18 #define DRTM_ADDRESS_MAP_SIZE (sizeof(drtm_memory_region_descriptor_table_t) + \ 19 (sizeof(drtm_mem_region_t) * \ 20 PLAT_DRTM_MMAP_ENTRIES)) 21 22 /* Allocate space for DRTM-formatted address map to be constructed. */ 23 static uint8_t drtm_address_map[DRTM_ADDRESS_MAP_SIZE]; 24 25 static uint64_t drtm_address_map_size; 26 27 static int compare_regions(const void *a, const void *b) 28 { 29 const drtm_mem_region_t *region_a = (const drtm_mem_region_t *)a; 30 const drtm_mem_region_t *region_b = (const drtm_mem_region_t *)b; 31 32 if (region_a->region_address < region_b->region_address) { 33 return -1; 34 } else if (region_a->region_address > region_b->region_address) { 35 return 1; 36 } else { 37 return 0; 38 } 39 } 40 41 drtm_memory_region_descriptor_table_t *drtm_build_address_map(void) 42 { 43 /* Set up pointer to DRTM memory map. */ 44 drtm_memory_region_descriptor_table_t *map = 45 (drtm_memory_region_descriptor_table_t *)drtm_address_map; 46 47 /* Get the platform memory map. */ 48 const mmap_region_t *mmap = plat_get_addr_mmap(); 49 unsigned int i; 50 51 /* Set up header for address map structure. */ 52 map->revision = DRTM_ADDRESS_MAP_REVISION; 53 map->reserved = 0x0000; 54 55 /* Iterate through mmap and generate DRTM address map. */ 56 for (i = 0U; mmap[i].base_pa != 0UL; i++) { 57 /* Set PA of region. */ 58 map->region[i].region_address = mmap[i].base_pa; 59 60 /* Set size of region (in 4kb chunks). */ 61 map->region[i].region_size_type = 0; 62 ARM_DRTM_REGION_SIZE_TYPE_SET_4K_PAGE_NUM( 63 map->region[i].region_size_type, 64 mmap[i].size / PAGE_SIZE_4KB); 65 66 /* Set type and cacheability. */ 67 switch (MT_TYPE(mmap[i].attr)) { 68 case MT_DEVICE: 69 ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE( 70 map->region[i].region_size_type, 71 ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_DEVICE); 72 break; 73 case MT_NON_CACHEABLE: 74 ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE( 75 map->region[i].region_size_type, 76 ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NCAR); 77 ARM_DRTM_REGION_SIZE_TYPE_SET_CACHEABILITY( 78 map->region[i].region_size_type, 79 ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_NC); 80 break; 81 case MT_MEMORY: 82 ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE( 83 map->region[i].region_size_type, 84 ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NORMAL); 85 break; 86 default: 87 return NULL; 88 } 89 } 90 91 map->num_regions = i; 92 93 qsort(map->region, map->num_regions, sizeof(drtm_mem_region_t), 94 compare_regions); 95 96 /* Store total size of address map. */ 97 drtm_address_map_size = sizeof(drtm_memory_region_descriptor_table_t); 98 drtm_address_map_size += (i * sizeof(drtm_mem_region_t)); 99 100 return map; 101 } 102 103 uint64_t drtm_get_address_map_size(void) 104 { 105 return drtm_address_map_size; 106 } 107