xref: /rk3399_ARM-atf/plat/common/plat_spmd_manifest.c (revision 52696946ab3f441496436ad7223cb2bd853c8beb)
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>
8*52696946SOlivier Deprez #include <errno.h>
90cb64d01SAchin Gupta #include <string.h>
100cb64d01SAchin Gupta #include <libfdt.h>
110cb64d01SAchin Gupta 
120cb64d01SAchin Gupta #include <common/debug.h>
130cb64d01SAchin Gupta #include <common/fdt_wrappers.h>
140cb64d01SAchin Gupta #include <platform_def.h>
150cb64d01SAchin Gupta #include <services/spm_core_manifest.h>
160cb64d01SAchin Gupta 
17*52696946SOlivier Deprez #define ATTRIBUTE_ROOT_NODE_STR "attribute"
18*52696946SOlivier Deprez 
190cb64d01SAchin Gupta /*******************************************************************************
20*52696946SOlivier Deprez  * SPMC attribute node parser
210cb64d01SAchin Gupta  ******************************************************************************/
22*52696946SOlivier Deprez static int manifest_parse_attribute(spmc_manifest_attribute_t *attr,
230cb64d01SAchin Gupta 				    const void *fdt,
240cb64d01SAchin Gupta 				    int node)
250cb64d01SAchin Gupta {
26ff4e6c35SAndre Przywara 	uint32_t val32;
27*52696946SOlivier Deprez 	int rc;
280cb64d01SAchin Gupta 
29*52696946SOlivier Deprez 	assert((attr != NULL) && (fdt != NULL));
300cb64d01SAchin Gupta 
31ff4e6c35SAndre Przywara 	rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version);
32*52696946SOlivier Deprez 	if (rc != 0) {
33*52696946SOlivier Deprez 		ERROR("Missing SPCI %s version in SPM Core manifest.\n",
34*52696946SOlivier Deprez 			"major");
35*52696946SOlivier Deprez 		return rc;
360cb64d01SAchin Gupta 	}
370cb64d01SAchin Gupta 
38ff4e6c35SAndre Przywara 	rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version);
39*52696946SOlivier Deprez 	if (rc != 0) {
40*52696946SOlivier Deprez 		ERROR("Missing SPCI %s version in SPM Core manifest.\n",
41*52696946SOlivier Deprez 			"minor");
42*52696946SOlivier Deprez 		return rc;
430cb64d01SAchin Gupta 	}
440cb64d01SAchin Gupta 
45ff4e6c35SAndre Przywara 	rc = fdt_read_uint32(fdt, node, "spmc_id", &val32);
46*52696946SOlivier Deprez 	if (rc != 0) {
47ac03ac5eSMax Shvetsov 		ERROR("Missing SPMC ID in manifest.\n");
48*52696946SOlivier Deprez 		return rc;
49ac03ac5eSMax Shvetsov 	}
50*52696946SOlivier Deprez 
51*52696946SOlivier Deprez 	attr->spmc_id = val32 & 0xffff;
52ac03ac5eSMax Shvetsov 
53ff4e6c35SAndre Przywara 	rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state);
54*52696946SOlivier Deprez 	if (rc != 0) {
55*52696946SOlivier Deprez 		NOTICE("%s not specified in SPM Core manifest.\n",
56*52696946SOlivier Deprez 			"Execution state");
57*52696946SOlivier Deprez 	}
580cb64d01SAchin Gupta 
59ff4e6c35SAndre Przywara 	rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size);
60*52696946SOlivier Deprez 	if (rc != 0) {
61*52696946SOlivier Deprez 		NOTICE("%s not specified in SPM Core manifest.\n",
62*52696946SOlivier Deprez 			"Binary size");
63*52696946SOlivier Deprez 	}
640cb64d01SAchin Gupta 
65ff4e6c35SAndre Przywara 	rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address);
66*52696946SOlivier Deprez 	if (rc != 0) {
67*52696946SOlivier Deprez 		NOTICE("%s not specified in SPM Core manifest.\n",
68*52696946SOlivier Deprez 			"Load address");
69*52696946SOlivier Deprez 	}
700cb64d01SAchin Gupta 
71ff4e6c35SAndre Przywara 	rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint);
72*52696946SOlivier Deprez 	if (rc != 0) {
73*52696946SOlivier Deprez 		NOTICE("%s not specified in SPM Core manifest.\n",
74*52696946SOlivier Deprez 			"Entry point");
75*52696946SOlivier Deprez 	}
760cb64d01SAchin Gupta 
77*52696946SOlivier Deprez 	VERBOSE("SPM Core manifest attribute section:\n");
78*52696946SOlivier Deprez 	VERBOSE("  version: %u.%u\n", attr->major_version, attr->minor_version);
79*52696946SOlivier Deprez 	VERBOSE("  spmc_id: 0x%x\n", attr->spmc_id);
800cb64d01SAchin Gupta 	VERBOSE("  binary_size: 0x%x\n", attr->binary_size);
810cb64d01SAchin Gupta 	VERBOSE("  load_address: 0x%llx\n", attr->load_address);
820cb64d01SAchin Gupta 	VERBOSE("  entrypoint: 0x%llx\n", attr->entrypoint);
830cb64d01SAchin Gupta 
840cb64d01SAchin Gupta 	return 0;
850cb64d01SAchin Gupta }
860cb64d01SAchin Gupta 
870cb64d01SAchin Gupta /*******************************************************************************
880cb64d01SAchin Gupta  * Root node handler
890cb64d01SAchin Gupta  ******************************************************************************/
90*52696946SOlivier Deprez static int manifest_parse_root(spmc_manifest_attribute_t *manifest,
910cb64d01SAchin Gupta 			       const void *fdt,
920cb64d01SAchin Gupta 			       int root)
930cb64d01SAchin Gupta {
940cb64d01SAchin Gupta 	int node;
950cb64d01SAchin Gupta 
96*52696946SOlivier Deprez 	assert(manifest != NULL);
97*52696946SOlivier Deprez 
98*52696946SOlivier Deprez 	node = fdt_subnode_offset_namelen(fdt, root, ATTRIBUTE_ROOT_NODE_STR,
99*52696946SOlivier Deprez 		sizeof(ATTRIBUTE_ROOT_NODE_STR) - 1);
1000cb64d01SAchin Gupta 	if (node < 0) {
101*52696946SOlivier Deprez 		ERROR("Root node doesn't contain subnode '%s'\n",
102*52696946SOlivier Deprez 			ATTRIBUTE_ROOT_NODE_STR);
103*52696946SOlivier Deprez 		return node;
1040cb64d01SAchin Gupta 	}
1050cb64d01SAchin Gupta 
1060cb64d01SAchin Gupta 	return manifest_parse_attribute(manifest, fdt, node);
1070cb64d01SAchin Gupta }
1080cb64d01SAchin Gupta 
1090cb64d01SAchin Gupta /*******************************************************************************
110*52696946SOlivier Deprez  * Platform handler to parse a SPM Core manifest.
1110cb64d01SAchin Gupta  ******************************************************************************/
112*52696946SOlivier Deprez int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
1130cb64d01SAchin Gupta 				const void *ptr,
1140cb64d01SAchin Gupta 				size_t size)
1150cb64d01SAchin Gupta {
1160cb64d01SAchin Gupta 	int rc;
1170cb64d01SAchin Gupta 
1180cb64d01SAchin Gupta 	assert(manifest != NULL);
1190cb64d01SAchin Gupta 	assert(ptr != NULL);
1200cb64d01SAchin Gupta 
121*52696946SOlivier Deprez 	INFO("Reading SPM Core manifest at address %p\n", ptr);
1220cb64d01SAchin Gupta 
1230cb64d01SAchin Gupta 	rc = fdt_check_header(ptr);
1240cb64d01SAchin Gupta 	if (rc != 0) {
125*52696946SOlivier Deprez 		ERROR("Wrong format for SPM Core manifest (%d).\n", rc);
126*52696946SOlivier Deprez 		return rc;
1270cb64d01SAchin Gupta 	}
1280cb64d01SAchin Gupta 
129*52696946SOlivier Deprez 	rc = fdt_node_offset_by_compatible(ptr, -1,
1300cb64d01SAchin Gupta 				"arm,spci-core-manifest-1.0");
131*52696946SOlivier Deprez 	if (rc < 0) {
132*52696946SOlivier Deprez 		ERROR("Unrecognized SPM Core manifest\n");
133*52696946SOlivier Deprez 		return rc;
1340cb64d01SAchin Gupta 	}
1350cb64d01SAchin Gupta 
136*52696946SOlivier Deprez 	return manifest_parse_root(manifest, ptr, rc);
1370cb64d01SAchin Gupta }
138