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