xref: /rk3399_ARM-atf/services/std_svc/drtm/drtm_res_address_map.c (revision 4e1e680cae0a559baadca7947f0b3139e4cee682)
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