plat_spmd_manifest.c 3.55 KB
Newer Older
1
2
3
4
5
6
7
/*
 * Copyright (c) 2020, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
Olivier Deprez's avatar
Olivier Deprez committed
8
#include <errno.h>
9
10
11
12
13
14
15
16
#include <string.h>
#include <libfdt.h>

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

Olivier Deprez's avatar
Olivier Deprez committed
17
18
#define ATTRIBUTE_ROOT_NODE_STR "attribute"

19
/*******************************************************************************
Olivier Deprez's avatar
Olivier Deprez committed
20
 * SPMC attribute node parser
21
 ******************************************************************************/
Olivier Deprez's avatar
Olivier Deprez committed
22
static int manifest_parse_attribute(spmc_manifest_attribute_t *attr,
23
24
25
				    const void *fdt,
				    int node)
{
26
	uint32_t val32;
Olivier Deprez's avatar
Olivier Deprez committed
27
	int rc;
28

Olivier Deprez's avatar
Olivier Deprez committed
29
	assert((attr != NULL) && (fdt != NULL));
30

31
	rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version);
Olivier Deprez's avatar
Olivier Deprez committed
32
33
34
35
	if (rc != 0) {
		ERROR("Missing SPCI %s version in SPM Core manifest.\n",
			"major");
		return rc;
36
37
	}

38
	rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version);
Olivier Deprez's avatar
Olivier Deprez committed
39
40
41
42
	if (rc != 0) {
		ERROR("Missing SPCI %s version in SPM Core manifest.\n",
			"minor");
		return rc;
43
44
	}

45
	rc = fdt_read_uint32(fdt, node, "spmc_id", &val32);
Olivier Deprez's avatar
Olivier Deprez committed
46
	if (rc != 0) {
47
		ERROR("Missing SPMC ID in manifest.\n");
Olivier Deprez's avatar
Olivier Deprez committed
48
		return rc;
49
	}
Olivier Deprez's avatar
Olivier Deprez committed
50
51

	attr->spmc_id = val32 & 0xffff;
52

53
	rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state);
Olivier Deprez's avatar
Olivier Deprez committed
54
55
56
57
	if (rc != 0) {
		NOTICE("%s not specified in SPM Core manifest.\n",
			"Execution state");
	}
58

59
	rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size);
Olivier Deprez's avatar
Olivier Deprez committed
60
61
62
63
	if (rc != 0) {
		NOTICE("%s not specified in SPM Core manifest.\n",
			"Binary size");
	}
64

65
	rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address);
Olivier Deprez's avatar
Olivier Deprez committed
66
67
68
69
	if (rc != 0) {
		NOTICE("%s not specified in SPM Core manifest.\n",
			"Load address");
	}
70

71
	rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint);
Olivier Deprez's avatar
Olivier Deprez committed
72
73
74
75
	if (rc != 0) {
		NOTICE("%s not specified in SPM Core manifest.\n",
			"Entry point");
	}
76

Olivier Deprez's avatar
Olivier Deprez committed
77
78
79
	VERBOSE("SPM Core manifest attribute section:\n");
	VERBOSE("  version: %u.%u\n", attr->major_version, attr->minor_version);
	VERBOSE("  spmc_id: 0x%x\n", attr->spmc_id);
80
81
82
83
84
85
86
87
88
89
	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
 ******************************************************************************/
Olivier Deprez's avatar
Olivier Deprez committed
90
91
92
static int manifest_parse_root(spmc_manifest_attribute_t *manifest,
			       const void *fdt,
			       int root)
93
94
95
{
	int node;

Olivier Deprez's avatar
Olivier Deprez committed
96
97
98
99
	assert(manifest != NULL);

	node = fdt_subnode_offset_namelen(fdt, root, ATTRIBUTE_ROOT_NODE_STR,
		sizeof(ATTRIBUTE_ROOT_NODE_STR) - 1);
100
	if (node < 0) {
Olivier Deprez's avatar
Olivier Deprez committed
101
102
103
		ERROR("Root node doesn't contain subnode '%s'\n",
			ATTRIBUTE_ROOT_NODE_STR);
		return node;
104
105
106
107
108
109
	}

	return manifest_parse_attribute(manifest, fdt, node);
}

/*******************************************************************************
Olivier Deprez's avatar
Olivier Deprez committed
110
 * Platform handler to parse a SPM Core manifest.
111
 ******************************************************************************/
Olivier Deprez's avatar
Olivier Deprez committed
112
int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
113
114
115
116
117
118
119
120
				const void *ptr,
				size_t size)
{
	int rc;

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

Olivier Deprez's avatar
Olivier Deprez committed
121
	INFO("Reading SPM Core manifest at address %p\n", ptr);
122
123
124

	rc = fdt_check_header(ptr);
	if (rc != 0) {
Olivier Deprez's avatar
Olivier Deprez committed
125
126
		ERROR("Wrong format for SPM Core manifest (%d).\n", rc);
		return rc;
127
128
	}

Olivier Deprez's avatar
Olivier Deprez committed
129
	rc = fdt_node_offset_by_compatible(ptr, -1,
130
				"arm,spci-core-manifest-1.0");
Olivier Deprez's avatar
Olivier Deprez committed
131
132
133
	if (rc < 0) {
		ERROR("Unrecognized SPM Core manifest\n");
		return rc;
134
135
	}

Olivier Deprez's avatar
Olivier Deprez committed
136
	return manifest_parse_root(manifest, ptr, rc);
137
}