xref: /rk3399_ARM-atf/plat/common/plat_spmd_manifest.c (revision 52696946ab3f441496436ad7223cb2bd853c8beb)
1 /*
2  * Copyright (c) 2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 #include <string.h>
10 #include <libfdt.h>
11 
12 #include <common/debug.h>
13 #include <common/fdt_wrappers.h>
14 #include <platform_def.h>
15 #include <services/spm_core_manifest.h>
16 
17 #define ATTRIBUTE_ROOT_NODE_STR "attribute"
18 
19 /*******************************************************************************
20  * SPMC attribute node parser
21  ******************************************************************************/
22 static int manifest_parse_attribute(spmc_manifest_attribute_t *attr,
23 				    const void *fdt,
24 				    int node)
25 {
26 	uint32_t val32;
27 	int rc;
28 
29 	assert((attr != NULL) && (fdt != NULL));
30 
31 	rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version);
32 	if (rc != 0) {
33 		ERROR("Missing SPCI %s version in SPM Core manifest.\n",
34 			"major");
35 		return rc;
36 	}
37 
38 	rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version);
39 	if (rc != 0) {
40 		ERROR("Missing SPCI %s version in SPM Core manifest.\n",
41 			"minor");
42 		return rc;
43 	}
44 
45 	rc = fdt_read_uint32(fdt, node, "spmc_id", &val32);
46 	if (rc != 0) {
47 		ERROR("Missing SPMC ID in manifest.\n");
48 		return rc;
49 	}
50 
51 	attr->spmc_id = val32 & 0xffff;
52 
53 	rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state);
54 	if (rc != 0) {
55 		NOTICE("%s not specified in SPM Core manifest.\n",
56 			"Execution state");
57 	}
58 
59 	rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size);
60 	if (rc != 0) {
61 		NOTICE("%s not specified in SPM Core manifest.\n",
62 			"Binary size");
63 	}
64 
65 	rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address);
66 	if (rc != 0) {
67 		NOTICE("%s not specified in SPM Core manifest.\n",
68 			"Load address");
69 	}
70 
71 	rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint);
72 	if (rc != 0) {
73 		NOTICE("%s not specified in SPM Core manifest.\n",
74 			"Entry point");
75 	}
76 
77 	VERBOSE("SPM Core manifest attribute section:\n");
78 	VERBOSE("  version: %u.%u\n", attr->major_version, attr->minor_version);
79 	VERBOSE("  spmc_id: 0x%x\n", attr->spmc_id);
80 	VERBOSE("  binary_size: 0x%x\n", attr->binary_size);
81 	VERBOSE("  load_address: 0x%llx\n", attr->load_address);
82 	VERBOSE("  entrypoint: 0x%llx\n", attr->entrypoint);
83 
84 	return 0;
85 }
86 
87 /*******************************************************************************
88  * Root node handler
89  ******************************************************************************/
90 static int manifest_parse_root(spmc_manifest_attribute_t *manifest,
91 			       const void *fdt,
92 			       int root)
93 {
94 	int node;
95 
96 	assert(manifest != NULL);
97 
98 	node = fdt_subnode_offset_namelen(fdt, root, ATTRIBUTE_ROOT_NODE_STR,
99 		sizeof(ATTRIBUTE_ROOT_NODE_STR) - 1);
100 	if (node < 0) {
101 		ERROR("Root node doesn't contain subnode '%s'\n",
102 			ATTRIBUTE_ROOT_NODE_STR);
103 		return node;
104 	}
105 
106 	return manifest_parse_attribute(manifest, fdt, node);
107 }
108 
109 /*******************************************************************************
110  * Platform handler to parse a SPM Core manifest.
111  ******************************************************************************/
112 int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
113 				const void *ptr,
114 				size_t size)
115 {
116 	int rc;
117 
118 	assert(manifest != NULL);
119 	assert(ptr != NULL);
120 
121 	INFO("Reading SPM Core manifest at address %p\n", ptr);
122 
123 	rc = fdt_check_header(ptr);
124 	if (rc != 0) {
125 		ERROR("Wrong format for SPM Core manifest (%d).\n", rc);
126 		return rc;
127 	}
128 
129 	rc = fdt_node_offset_by_compatible(ptr, -1,
130 				"arm,spci-core-manifest-1.0");
131 	if (rc < 0) {
132 		ERROR("Unrecognized SPM Core manifest\n");
133 		return rc;
134 	}
135 
136 	return manifest_parse_root(manifest, ptr, rc);
137 }
138