blob: 86367061eff0c0e3333ed8d6c90d65eb6b84649c [file] [log] [blame]
/*
* Copyright (c) 2022 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <plat/common/platform.h>
#include <services/drtm_svc.h>
#include <platform_def.h>
/* Address map revision generated by this code. */
#define DRTM_ADDRESS_MAP_REVISION U(0x0001)
/* Amount of space needed for address map based on PLAT_DRTM_MMAP_ENTRIES */
#define DRTM_ADDRESS_MAP_SIZE (sizeof(drtm_memory_region_descriptor_table_t) + \
(sizeof(drtm_mem_region_t) * \
PLAT_DRTM_MMAP_ENTRIES))
/* Allocate space for DRTM-formatted address map to be constructed. */
static uint8_t drtm_address_map[DRTM_ADDRESS_MAP_SIZE];
static uint64_t drtm_address_map_size;
drtm_memory_region_descriptor_table_t *drtm_build_address_map(void)
{
/* Set up pointer to DRTM memory map. */
drtm_memory_region_descriptor_table_t *map =
(drtm_memory_region_descriptor_table_t *)drtm_address_map;
/* Get the platform memory map. */
const mmap_region_t *mmap = plat_get_addr_mmap();
unsigned int i;
/* Set up header for address map structure. */
map->revision = DRTM_ADDRESS_MAP_REVISION;
map->reserved = 0x0000;
/* Iterate through mmap and generate DRTM address map. */
for (i = 0U; mmap[i].base_pa != 0UL; i++) {
/* Set PA of region. */
map->region[i].region_address = mmap[i].base_pa;
/* Set size of region (in 4kb chunks). */
map->region[i].region_size_type = 0;
ARM_DRTM_REGION_SIZE_TYPE_SET_4K_PAGE_NUM(
map->region[i].region_size_type,
mmap[i].size / PAGE_SIZE_4KB);
/* Set type and cacheability. */
switch (MT_TYPE(mmap[i].attr)) {
case MT_DEVICE:
ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(
map->region[i].region_size_type,
ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_DEVICE);
break;
case MT_NON_CACHEABLE:
ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(
map->region[i].region_size_type,
ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NCAR);
ARM_DRTM_REGION_SIZE_TYPE_SET_CACHEABILITY(
map->region[i].region_size_type,
ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_NC);
break;
case MT_MEMORY:
ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(
map->region[i].region_size_type,
ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NORMAL);
break;
default:
return NULL;
}
}
map->num_regions = i;
/* Store total size of address map. */
drtm_address_map_size = sizeof(drtm_memory_region_descriptor_table_t);
drtm_address_map_size += (i * sizeof(drtm_mem_region_t));
return map;
}
uint64_t drtm_get_address_map_size(void)
{
return drtm_address_map_size;
}