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