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