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