feat(drtm): prepare DLME data for DLME launch
Prepared DLME data before DLME launch
Change-Id: I28e2132d9c832ab5bd25cf884925b99cc48258ea
Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c
index a96706d..ad2b774 100644
--- a/services/std_svc/drtm/drtm_main.c
+++ b/services/std_svc/drtm/drtm_main.c
@@ -33,12 +33,17 @@
/* DRTM-formatted memory map. */
static drtm_memory_region_descriptor_table_t *plat_drtm_mem_map;
+/* DLME header */
+struct_dlme_data_header dlme_data_hdr_init;
+
+/* Minimum data memory requirement */
+uint64_t dlme_data_min_size;
+
int drtm_setup(void)
{
bool rc;
const plat_drtm_tpm_features_t *plat_tpm_feat;
const plat_drtm_dma_prot_features_t *plat_dma_prot_feat;
- uint64_t dlme_data_min_size;
INFO("DRTM service setup\n");
@@ -85,6 +90,7 @@
dlme_data_min_size =
sizeof(drtm_memory_region_descriptor_table_t) +
sizeof(drtm_mem_region_t);
+ dlme_data_hdr_init.dlme_prot_regions_size = dlme_data_min_size;
} else {
/*
* TODO set protected regions table size based on platform DMA
@@ -93,10 +99,16 @@
panic();
}
- dlme_data_min_size += (drtm_get_address_map_size() +
- PLAT_DRTM_EVENT_LOG_MAX_SIZE +
- plat_drtm_get_tcb_hash_table_size() +
- plat_drtm_get_imp_def_dlme_region_size());
+ dlme_data_hdr_init.dlme_addr_map_size = drtm_get_address_map_size();
+ dlme_data_hdr_init.dlme_tcb_hashes_table_size =
+ plat_drtm_get_tcb_hash_table_size();
+ dlme_data_hdr_init.dlme_impdef_region_size =
+ plat_drtm_get_imp_def_dlme_region_size();
+
+ dlme_data_min_size += dlme_data_hdr_init.dlme_addr_map_size +
+ PLAT_DRTM_EVENT_LOG_MAX_SIZE +
+ dlme_data_hdr_init.dlme_tcb_hashes_table_size +
+ dlme_data_hdr_init.dlme_impdef_region_size;
dlme_data_min_size = page_align(dlme_data_min_size, UP)/PAGE_SIZE;
@@ -196,12 +208,97 @@
return SUCCESS;
}
-static enum drtm_retc drtm_dl_prepare_dlme_data(const struct_drtm_dl_args *args,
- size_t *dlme_data_size_out)
+static enum drtm_retc drtm_dl_prepare_dlme_data(const struct_drtm_dl_args *args)
{
- size_t dlme_data_total_bytes_req = 0;
+ int rc;
+ uint64_t dlme_data_paddr;
+ size_t dlme_data_max_size;
+ uintptr_t dlme_data_mapping;
+ struct_dlme_data_header *dlme_data_hdr;
+ uint8_t *dlme_data_cursor;
+ size_t dlme_data_mapping_bytes;
+ size_t serialised_bytes_actual;
+
+ dlme_data_paddr = args->dlme_paddr + args->dlme_data_off;
+ dlme_data_max_size = args->dlme_size - args->dlme_data_off;
+
+ /*
+ * The capacity of the given DLME data region is checked when
+ * the other dynamic launch arguments are.
+ */
+ if (dlme_data_max_size < dlme_data_min_size) {
+ ERROR("%s: assertion failed:"
+ " dlme_data_max_size (%ld) < dlme_data_total_bytes_req (%ld)\n",
+ __func__, dlme_data_max_size, dlme_data_min_size);
+ panic();
+ }
+
+ /* Map the DLME data region as NS memory. */
+ dlme_data_mapping_bytes = ALIGNED_UP(dlme_data_max_size, DRTM_PAGE_SIZE);
+ rc = mmap_add_dynamic_region_alloc_va(dlme_data_paddr,
+ &dlme_data_mapping,
+ dlme_data_mapping_bytes,
+ MT_RW_DATA | MT_NS |
+ MT_SHAREABILITY_ISH);
+ if (rc != 0) {
+ WARN("DRTM: %s: mmap_add_dynamic_region() failed rc=%d\n",
+ __func__, rc);
+ return INTERNAL_ERROR;
+ }
+ dlme_data_hdr = (struct_dlme_data_header *)dlme_data_mapping;
+ dlme_data_cursor = (uint8_t *)dlme_data_hdr + sizeof(*dlme_data_hdr);
+
+ memcpy(dlme_data_hdr, (const void *)&dlme_data_hdr_init,
+ sizeof(*dlme_data_hdr));
+
+ /* Set the header version and size. */
+ dlme_data_hdr->version = 1;
+ dlme_data_hdr->this_hdr_size = sizeof(*dlme_data_hdr);
+
+ /* Prepare DLME protected regions. */
+ drtm_dma_prot_serialise_table(dlme_data_cursor,
+ &serialised_bytes_actual);
+ assert(serialised_bytes_actual ==
+ dlme_data_hdr->dlme_prot_regions_size);
+ dlme_data_cursor += serialised_bytes_actual;
+
+ /* Prepare DLME address map. */
+ if (plat_drtm_mem_map != NULL) {
+ memcpy(dlme_data_cursor, plat_drtm_mem_map,
+ dlme_data_hdr->dlme_addr_map_size);
+ } else {
+ WARN("DRTM: DLME address map is not in the cache\n");
+ }
+ dlme_data_cursor += dlme_data_hdr->dlme_addr_map_size;
+
+ /* Prepare DRTM event log for DLME. */
+ drtm_serialise_event_log(dlme_data_cursor, &serialised_bytes_actual);
+ assert(serialised_bytes_actual <= PLAT_DRTM_EVENT_LOG_MAX_SIZE);
+ dlme_data_hdr->dlme_tpm_log_size = serialised_bytes_actual;
+ dlme_data_cursor += serialised_bytes_actual;
+
+ /*
+ * TODO: Prepare the TCB hashes for DLME, currently its size
+ * 0
+ */
+ dlme_data_cursor += dlme_data_hdr->dlme_tcb_hashes_table_size;
+
+ /* Implementation-specific region size is unused. */
+ dlme_data_cursor += dlme_data_hdr->dlme_impdef_region_size;
+
+ /*
+ * Prepare DLME data size, includes all data region referenced above
+ * alongwith the DLME data header
+ */
+ dlme_data_hdr->dlme_data_size = dlme_data_cursor - (uint8_t *)dlme_data_hdr;
- *dlme_data_size_out = dlme_data_total_bytes_req;
+ /* Unmap the DLME data region. */
+ rc = mmap_remove_dynamic_region(dlme_data_mapping, dlme_data_mapping_bytes);
+ if (rc != 0) {
+ ERROR("%s(): mmap_remove_dynamic_region() failed"
+ " unexpectedly rc=%d\n", __func__, rc);
+ panic();
+ }
return SUCCESS;
}
@@ -220,7 +317,6 @@
size_t args_mapping_size;
struct_drtm_dl_args *a;
struct_drtm_dl_args args_buf;
- size_t dlme_data_size_req;
int rc;
if (x1 % DRTM_PAGE_SIZE != 0) {
@@ -324,15 +420,9 @@
return INVALID_PARAMETERS;
}
- rc = drtm_dl_prepare_dlme_data(NULL, &dlme_data_size_req);
- if (rc) {
- ERROR("%s: drtm_dl_prepare_dlme_data() failed unexpectedly rc=%d\n",
- __func__, rc);
- panic();
- }
- if (dlme_data_end - dlme_data_start < dlme_data_size_req) {
+ if (dlme_data_end - dlme_data_start < dlme_data_min_size) {
ERROR("DRTM: argument DLME data region is short of %lu bytes\n",
- dlme_data_size_req - (size_t)(dlme_data_end - dlme_data_start));
+ dlme_data_min_size - (size_t)(dlme_data_end - dlme_data_start));
return INVALID_PARAMETERS;
}
@@ -404,6 +494,11 @@
goto err_undo_dma_prot;
}
+ ret = drtm_dl_prepare_dlme_data(&args);
+ if (ret != SUCCESS) {
+ goto err_undo_dma_prot;
+ }
+
SMC_RET1(handle, ret);
err_undo_dma_prot:
diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h
index 9bf5400..230cbcf 100644
--- a/services/std_svc/drtm/drtm_main.h
+++ b/services/std_svc/drtm/drtm_main.h
@@ -55,7 +55,7 @@
} drtm_features_t;
struct __packed drtm_dl_args_v1 {
- uint16_t version; /* Must be 1. */
+ uint16_t version; /* Must be 1. */
uint8_t __res[2];
uint32_t features;
uint64_t dlme_paddr;
@@ -69,6 +69,20 @@
drtm_dl_dma_prot_args_v1_t dma_prot_args;
} __aligned(__alignof(uint16_t /* First member's type, `uint16_t version' */));
+struct __packed dlme_data_header_v1 {
+ uint16_t version; /* Must be 1. */
+ uint16_t this_hdr_size;
+ uint8_t __res[4];
+ uint64_t dlme_data_size;
+ uint64_t dlme_prot_regions_size;
+ uint64_t dlme_addr_map_size;
+ uint64_t dlme_tpm_log_size;
+ uint64_t dlme_tcb_hashes_table_size;
+ uint64_t dlme_impdef_region_size;
+} __aligned(__alignof(uint16_t /* First member's type, `uint16_t version'. */));
+
+typedef struct dlme_data_header_v1 struct_dlme_data_header;
+
drtm_memory_region_descriptor_table_t *drtm_build_address_map(void);
uint64_t drtm_get_address_map_size(void);