12a1cdee4Sjohpow01 /*
2*7cf37848SManish V Badarkhe * Copyright (c) 2022-2025 Arm Limited. All rights reserved.
32a1cdee4Sjohpow01 *
42a1cdee4Sjohpow01 * SPDX-License-Identifier: BSD-3-Clause
52a1cdee4Sjohpow01 */
62a1cdee4Sjohpow01
72a1cdee4Sjohpow01 #include <stdint.h>
8*7cf37848SManish V Badarkhe #include <stdlib.h>
92a1cdee4Sjohpow01
102a1cdee4Sjohpow01 #include <plat/common/platform.h>
112a1cdee4Sjohpow01 #include <services/drtm_svc.h>
122a1cdee4Sjohpow01 #include <platform_def.h>
132a1cdee4Sjohpow01
142a1cdee4Sjohpow01 /* Address map revision generated by this code. */
152a1cdee4Sjohpow01 #define DRTM_ADDRESS_MAP_REVISION U(0x0001)
162a1cdee4Sjohpow01
172a1cdee4Sjohpow01 /* Amount of space needed for address map based on PLAT_DRTM_MMAP_ENTRIES */
182a1cdee4Sjohpow01 #define DRTM_ADDRESS_MAP_SIZE (sizeof(drtm_memory_region_descriptor_table_t) + \
192a1cdee4Sjohpow01 (sizeof(drtm_mem_region_t) * \
202a1cdee4Sjohpow01 PLAT_DRTM_MMAP_ENTRIES))
212a1cdee4Sjohpow01
222a1cdee4Sjohpow01 /* Allocate space for DRTM-formatted address map to be constructed. */
232a1cdee4Sjohpow01 static uint8_t drtm_address_map[DRTM_ADDRESS_MAP_SIZE];
242a1cdee4Sjohpow01
252a1cdee4Sjohpow01 static uint64_t drtm_address_map_size;
262a1cdee4Sjohpow01
compare_regions(const void * a,const void * b)27*7cf37848SManish V Badarkhe static int compare_regions(const void *a, const void *b)
28*7cf37848SManish V Badarkhe {
29*7cf37848SManish V Badarkhe const drtm_mem_region_t *region_a = (const drtm_mem_region_t *)a;
30*7cf37848SManish V Badarkhe const drtm_mem_region_t *region_b = (const drtm_mem_region_t *)b;
31*7cf37848SManish V Badarkhe
32*7cf37848SManish V Badarkhe if (region_a->region_address < region_b->region_address) {
33*7cf37848SManish V Badarkhe return -1;
34*7cf37848SManish V Badarkhe } else if (region_a->region_address > region_b->region_address) {
35*7cf37848SManish V Badarkhe return 1;
36*7cf37848SManish V Badarkhe } else {
37*7cf37848SManish V Badarkhe return 0;
38*7cf37848SManish V Badarkhe }
39*7cf37848SManish V Badarkhe }
40*7cf37848SManish V Badarkhe
drtm_build_address_map(void)412a1cdee4Sjohpow01 drtm_memory_region_descriptor_table_t *drtm_build_address_map(void)
422a1cdee4Sjohpow01 {
432a1cdee4Sjohpow01 /* Set up pointer to DRTM memory map. */
442a1cdee4Sjohpow01 drtm_memory_region_descriptor_table_t *map =
452a1cdee4Sjohpow01 (drtm_memory_region_descriptor_table_t *)drtm_address_map;
462a1cdee4Sjohpow01
472a1cdee4Sjohpow01 /* Get the platform memory map. */
482a1cdee4Sjohpow01 const mmap_region_t *mmap = plat_get_addr_mmap();
492a1cdee4Sjohpow01 unsigned int i;
502a1cdee4Sjohpow01
512a1cdee4Sjohpow01 /* Set up header for address map structure. */
522a1cdee4Sjohpow01 map->revision = DRTM_ADDRESS_MAP_REVISION;
532a1cdee4Sjohpow01 map->reserved = 0x0000;
542a1cdee4Sjohpow01
552a1cdee4Sjohpow01 /* Iterate through mmap and generate DRTM address map. */
562a1cdee4Sjohpow01 for (i = 0U; mmap[i].base_pa != 0UL; i++) {
572a1cdee4Sjohpow01 /* Set PA of region. */
582a1cdee4Sjohpow01 map->region[i].region_address = mmap[i].base_pa;
592a1cdee4Sjohpow01
602a1cdee4Sjohpow01 /* Set size of region (in 4kb chunks). */
612a1cdee4Sjohpow01 map->region[i].region_size_type = 0;
622a1cdee4Sjohpow01 ARM_DRTM_REGION_SIZE_TYPE_SET_4K_PAGE_NUM(
632a1cdee4Sjohpow01 map->region[i].region_size_type,
642a1cdee4Sjohpow01 mmap[i].size / PAGE_SIZE_4KB);
652a1cdee4Sjohpow01
662a1cdee4Sjohpow01 /* Set type and cacheability. */
672a1cdee4Sjohpow01 switch (MT_TYPE(mmap[i].attr)) {
682a1cdee4Sjohpow01 case MT_DEVICE:
692a1cdee4Sjohpow01 ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(
702a1cdee4Sjohpow01 map->region[i].region_size_type,
712a1cdee4Sjohpow01 ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_DEVICE);
722a1cdee4Sjohpow01 break;
732a1cdee4Sjohpow01 case MT_NON_CACHEABLE:
742a1cdee4Sjohpow01 ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(
752a1cdee4Sjohpow01 map->region[i].region_size_type,
762a1cdee4Sjohpow01 ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NCAR);
772a1cdee4Sjohpow01 ARM_DRTM_REGION_SIZE_TYPE_SET_CACHEABILITY(
782a1cdee4Sjohpow01 map->region[i].region_size_type,
792a1cdee4Sjohpow01 ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_NC);
802a1cdee4Sjohpow01 break;
812a1cdee4Sjohpow01 case MT_MEMORY:
822a1cdee4Sjohpow01 ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(
832a1cdee4Sjohpow01 map->region[i].region_size_type,
842a1cdee4Sjohpow01 ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NORMAL);
852a1cdee4Sjohpow01 break;
862a1cdee4Sjohpow01 default:
872a1cdee4Sjohpow01 return NULL;
882a1cdee4Sjohpow01 }
892a1cdee4Sjohpow01 }
902a1cdee4Sjohpow01
912a1cdee4Sjohpow01 map->num_regions = i;
922a1cdee4Sjohpow01
93*7cf37848SManish V Badarkhe qsort(map->region, map->num_regions, sizeof(drtm_mem_region_t),
94*7cf37848SManish V Badarkhe compare_regions);
95*7cf37848SManish V Badarkhe
962a1cdee4Sjohpow01 /* Store total size of address map. */
972a1cdee4Sjohpow01 drtm_address_map_size = sizeof(drtm_memory_region_descriptor_table_t);
982a1cdee4Sjohpow01 drtm_address_map_size += (i * sizeof(drtm_mem_region_t));
992a1cdee4Sjohpow01
1002a1cdee4Sjohpow01 return map;
1012a1cdee4Sjohpow01 }
1022a1cdee4Sjohpow01
drtm_get_address_map_size(void)1032a1cdee4Sjohpow01 uint64_t drtm_get_address_map_size(void)
1042a1cdee4Sjohpow01 {
1052a1cdee4Sjohpow01 return drtm_address_map_size;
1062a1cdee4Sjohpow01 }
107