aboutsummaryrefslogtreecommitdiff
path: root/plat/common/plat_spmd_manifest.c
blob: f63674b9846017d0be59bb0b82d664f4b022aa4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * Copyright (c) 2019, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <string.h>

#include <libfdt.h>

#include <platform_def.h>

#include <common/debug.h>
#include <common/fdt_wrappers.h>
#include <errno.h>
#include <services/spm_core_manifest.h>

/*******************************************************************************
 * Attribute section handler
 ******************************************************************************/
static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr,
				    const void *fdt,
				    int node)
{
	int rc = 0;

	assert(attr && fdt);

	rc = fdtw_read_cells(fdt, node, "maj_ver", 1, &attr->major_version);
	if (rc) {
		ERROR("Missing SPCI major version in SPM core manifest.\n");
		return -ENOENT;
	}

	rc = fdtw_read_cells(fdt, node, "min_ver", 1, &attr->minor_version);
	if (rc) {
		ERROR("Missing SPCI minor version in SPM core manifest.\n");
		return -ENOENT;
	}

	rc = fdtw_read_cells(fdt, node, "runtime_el", 1, &attr->runtime_el);
	if (rc) {
		ERROR("Missing SPM core runtime EL in manifest.\n");
		return -ENOENT;
	}

	rc = fdtw_read_cells(fdt, node, "spmc_id", 1, &attr->spmc_id);
	if (rc) {
		ERROR("Missing SPMC ID in manifest.\n");
		return -ENOENT;
	}

	rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state);
	if (rc)
		NOTICE("Execution state not specified in SPM core manifest.\n");

	rc = fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size);
	if (rc)
		NOTICE("Binary size not specified in SPM core manifest.\n");

	rc = fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address);
	if (rc)
		NOTICE("Load address not specified in SPM core manifest.\n");

	rc = fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint);
	if (rc)
		NOTICE("Entrypoint not specified in SPM core manifest.\n");

	VERBOSE("SPM core manifest attribute section:\n");
	VERBOSE("  version: %x.%x\n", attr->major_version, attr->minor_version);
	VERBOSE("  spmc id: %x\n", attr->spmc_id);
	VERBOSE("  runtime_el: 0x%x\n", attr->runtime_el);
	VERBOSE("  binary_size: 0x%x\n", attr->binary_size);
	VERBOSE("  load_address: 0x%llx\n", attr->load_address);
	VERBOSE("  entrypoint: 0x%llx\n", attr->entrypoint);

	return 0;
}

/*******************************************************************************
 * Root node handler
 ******************************************************************************/
static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest,
				const void *fdt,
				int root)
{
	int node;
	char *str;

	str = "attribute";
	node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
	if (node < 0) {
		ERROR("Root node doesn't contain subnode '%s'\n", str);
		return -ENOENT;
	}

	return manifest_parse_attribute(manifest, fdt, node);
}

/*******************************************************************************
 * Platform handler to parse a SPM core manifest.
 ******************************************************************************/
int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest,
				const void *ptr,
				size_t size)
{
	int rc;
	int root_node;

	assert(manifest != NULL);
	assert(ptr != NULL);

	INFO("Reading SPM core manifest at address %p\n", ptr);

	rc = fdt_check_header(ptr);
	if (rc != 0) {
		ERROR("Wrong format for SPM core manifest (%d).\n", rc);
		return -EINVAL;
	}

	INFO("Reading SPM core manifest at address %p\n", ptr);

	root_node = fdt_node_offset_by_compatible(ptr, -1, "arm,spmc_rd");
	if (root_node < 0) {
		ERROR("Unrecognized SPM core manifest\n");
		return -ENOENT;
	}

	INFO("Reading SPM core manifest at address %p\n", ptr);
	return manifest_parse_root(manifest, ptr, root_node);
}