xref: /rk3399_ARM-atf/plat/common/plat_spmd_manifest.c (revision ff4e6c35c9f3f0b1d190b5d3761a13d701af6925)
10cb64d01SAchin Gupta /*
20cb64d01SAchin Gupta  * Copyright (c) 2020, Arm Limited. All rights reserved.
30cb64d01SAchin Gupta  *
40cb64d01SAchin Gupta  * SPDX-License-Identifier: BSD-3-Clause
50cb64d01SAchin Gupta  */
60cb64d01SAchin Gupta 
70cb64d01SAchin Gupta #include <assert.h>
80cb64d01SAchin Gupta #include <string.h>
90cb64d01SAchin Gupta #include <libfdt.h>
100cb64d01SAchin Gupta 
110cb64d01SAchin Gupta #include <common/debug.h>
120cb64d01SAchin Gupta #include <common/fdt_wrappers.h>
130cb64d01SAchin Gupta #include <errno.h>
140cb64d01SAchin Gupta #include <platform_def.h>
150cb64d01SAchin Gupta #include <services/spm_core_manifest.h>
160cb64d01SAchin Gupta 
170cb64d01SAchin Gupta /*******************************************************************************
180cb64d01SAchin Gupta  * Attribute section handler
190cb64d01SAchin Gupta  ******************************************************************************/
200cb64d01SAchin Gupta static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr,
210cb64d01SAchin Gupta 				    const void *fdt,
220cb64d01SAchin Gupta 				    int node)
230cb64d01SAchin Gupta {
24*ff4e6c35SAndre Przywara 	uint32_t val32;
250cb64d01SAchin Gupta 	int rc = 0;
260cb64d01SAchin Gupta 
270cb64d01SAchin Gupta 	assert(attr && fdt);
280cb64d01SAchin Gupta 
29*ff4e6c35SAndre Przywara 	rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version);
300cb64d01SAchin Gupta 	if (rc) {
310cb64d01SAchin Gupta 		ERROR("Missing SPCI major version in SPM core manifest.\n");
320cb64d01SAchin Gupta 		return -ENOENT;
330cb64d01SAchin Gupta 	}
340cb64d01SAchin Gupta 
35*ff4e6c35SAndre Przywara 	rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version);
360cb64d01SAchin Gupta 	if (rc) {
370cb64d01SAchin Gupta 		ERROR("Missing SPCI minor version in SPM core manifest.\n");
380cb64d01SAchin Gupta 		return -ENOENT;
390cb64d01SAchin Gupta 	}
400cb64d01SAchin Gupta 
41*ff4e6c35SAndre Przywara 	rc = fdt_read_uint32(fdt, node, "spmc_id", &val32);
42ac03ac5eSMax Shvetsov 	if (rc) {
43ac03ac5eSMax Shvetsov 		ERROR("Missing SPMC ID in manifest.\n");
44ac03ac5eSMax Shvetsov 		return -ENOENT;
45ac03ac5eSMax Shvetsov 	}
46*ff4e6c35SAndre Przywara 	attr->spmc_id = val32;
47ac03ac5eSMax Shvetsov 
48*ff4e6c35SAndre Przywara 	rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state);
490cb64d01SAchin Gupta 	if (rc)
500cb64d01SAchin Gupta 		NOTICE("Execution state not specified in SPM core manifest.\n");
510cb64d01SAchin Gupta 
52*ff4e6c35SAndre Przywara 	rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size);
530cb64d01SAchin Gupta 	if (rc)
540cb64d01SAchin Gupta 		NOTICE("Binary size not specified in SPM core manifest.\n");
550cb64d01SAchin Gupta 
56*ff4e6c35SAndre Przywara 	rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address);
570cb64d01SAchin Gupta 	if (rc)
580cb64d01SAchin Gupta 		NOTICE("Load address not specified in SPM core manifest.\n");
590cb64d01SAchin Gupta 
60*ff4e6c35SAndre Przywara 	rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint);
610cb64d01SAchin Gupta 	if (rc)
620cb64d01SAchin Gupta 		NOTICE("Entrypoint not specified in SPM core manifest.\n");
630cb64d01SAchin Gupta 
640cb64d01SAchin Gupta 	VERBOSE("SPM core manifest attribute section:\n");
650cb64d01SAchin Gupta 	VERBOSE("  version: %x.%x\n", attr->major_version, attr->minor_version);
66ac03ac5eSMax Shvetsov 	VERBOSE("  spmc_id: %x\n", attr->spmc_id);
670cb64d01SAchin Gupta 	VERBOSE("  binary_size: 0x%x\n", attr->binary_size);
680cb64d01SAchin Gupta 	VERBOSE("  load_address: 0x%llx\n", attr->load_address);
690cb64d01SAchin Gupta 	VERBOSE("  entrypoint: 0x%llx\n", attr->entrypoint);
700cb64d01SAchin Gupta 
710cb64d01SAchin Gupta 	return 0;
720cb64d01SAchin Gupta }
730cb64d01SAchin Gupta 
740cb64d01SAchin Gupta /*******************************************************************************
750cb64d01SAchin Gupta  * Root node handler
760cb64d01SAchin Gupta  ******************************************************************************/
770cb64d01SAchin Gupta static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest,
780cb64d01SAchin Gupta 				const void *fdt,
790cb64d01SAchin Gupta 				int root)
800cb64d01SAchin Gupta {
810cb64d01SAchin Gupta 	int node;
820cb64d01SAchin Gupta 	char *str;
830cb64d01SAchin Gupta 
840cb64d01SAchin Gupta 	str = "attribute";
850cb64d01SAchin Gupta 	node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
860cb64d01SAchin Gupta 	if (node < 0) {
870cb64d01SAchin Gupta 		ERROR("Root node doesn't contain subnode '%s'\n", str);
880cb64d01SAchin Gupta 		return -ENOENT;
890cb64d01SAchin Gupta 	}
900cb64d01SAchin Gupta 
910cb64d01SAchin Gupta 	return manifest_parse_attribute(manifest, fdt, node);
920cb64d01SAchin Gupta }
930cb64d01SAchin Gupta 
940cb64d01SAchin Gupta /*******************************************************************************
950cb64d01SAchin Gupta  * Platform handler to parse a SPM core manifest.
960cb64d01SAchin Gupta  ******************************************************************************/
970cb64d01SAchin Gupta int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest,
980cb64d01SAchin Gupta 				const void *ptr,
990cb64d01SAchin Gupta 				size_t size)
1000cb64d01SAchin Gupta {
1010cb64d01SAchin Gupta 	int rc;
1020cb64d01SAchin Gupta 	int root_node;
1030cb64d01SAchin Gupta 
1040cb64d01SAchin Gupta 	assert(manifest != NULL);
1050cb64d01SAchin Gupta 	assert(ptr != NULL);
1060cb64d01SAchin Gupta 
1070cb64d01SAchin Gupta 	INFO("Reading SPM core manifest at address %p\n", ptr);
1080cb64d01SAchin Gupta 
1090cb64d01SAchin Gupta 	rc = fdt_check_header(ptr);
1100cb64d01SAchin Gupta 	if (rc != 0) {
1110cb64d01SAchin Gupta 		ERROR("Wrong format for SPM core manifest (%d).\n", rc);
1120cb64d01SAchin Gupta 		return -EINVAL;
1130cb64d01SAchin Gupta 	}
1140cb64d01SAchin Gupta 
1150cb64d01SAchin Gupta 	INFO("Reading SPM core manifest at address %p\n", ptr);
1160cb64d01SAchin Gupta 
1170cb64d01SAchin Gupta 	root_node = fdt_node_offset_by_compatible(ptr, -1,
1180cb64d01SAchin Gupta 				"arm,spci-core-manifest-1.0");
1190cb64d01SAchin Gupta 	if (root_node < 0) {
1200cb64d01SAchin Gupta 		ERROR("Unrecognized SPM core manifest\n");
1210cb64d01SAchin Gupta 		return -ENOENT;
1220cb64d01SAchin Gupta 	}
1230cb64d01SAchin Gupta 
1240cb64d01SAchin Gupta 	INFO("Reading SPM core manifest at address %p\n", ptr);
1250cb64d01SAchin Gupta 	return manifest_parse_root(manifest, ptr, root_node);
1260cb64d01SAchin Gupta }
127