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
compare_regions(const void * a,const void * b)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
drtm_build_address_map(void)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
drtm_get_address_map_size(void)103 uint64_t drtm_get_address_map_size(void)
104 {
105 return drtm_address_map_size;
106 }
107