blob: 8330356ae93831d2a48c21cc12c75fd947e3dc78 [file] [log] [blame]
Achin Guptada6ef0e2019-10-11 14:54:48 +01001/*
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 ******************************************************************************/
20static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr,
21 const void *fdt,
22 int node)
23{
Andre Przywarafe5bdf52020-03-26 11:22:37 +000024 uint32_t val32;
Achin Guptada6ef0e2019-10-11 14:54:48 +010025 int rc = 0;
26
27 assert(attr && fdt);
28
Andre Przywarafe5bdf52020-03-26 11:22:37 +000029 rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version);
Achin Guptada6ef0e2019-10-11 14:54:48 +010030 if (rc) {
31 ERROR("Missing SPCI major version in SPM core manifest.\n");
32 return -ENOENT;
33 }
34
Andre Przywarafe5bdf52020-03-26 11:22:37 +000035 rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version);
Achin Guptada6ef0e2019-10-11 14:54:48 +010036 if (rc) {
37 ERROR("Missing SPCI minor version in SPM core manifest.\n");
38 return -ENOENT;
39 }
40
Andre Przywarafe5bdf52020-03-26 11:22:37 +000041 rc = fdt_read_uint32(fdt, node, "spmc_id", &val32);
Max Shvetsove79062e2020-03-12 15:16:40 +000042 if (rc) {
43 ERROR("Missing SPMC ID in manifest.\n");
44 return -ENOENT;
45 }
Andre Przywarafe5bdf52020-03-26 11:22:37 +000046 attr->spmc_id = val32;
Max Shvetsove79062e2020-03-12 15:16:40 +000047
Andre Przywarafe5bdf52020-03-26 11:22:37 +000048 rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state);
Achin Guptada6ef0e2019-10-11 14:54:48 +010049 if (rc)
50 NOTICE("Execution state not specified in SPM core manifest.\n");
51
Andre Przywarafe5bdf52020-03-26 11:22:37 +000052 rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size);
Achin Guptada6ef0e2019-10-11 14:54:48 +010053 if (rc)
54 NOTICE("Binary size not specified in SPM core manifest.\n");
55
Andre Przywarafe5bdf52020-03-26 11:22:37 +000056 rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address);
Achin Guptada6ef0e2019-10-11 14:54:48 +010057 if (rc)
58 NOTICE("Load address not specified in SPM core manifest.\n");
59
Andre Przywarafe5bdf52020-03-26 11:22:37 +000060 rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint);
Achin Guptada6ef0e2019-10-11 14:54:48 +010061 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);
Max Shvetsove79062e2020-03-12 15:16:40 +000066 VERBOSE(" spmc_id: %x\n", attr->spmc_id);
Achin Guptada6ef0e2019-10-11 14:54:48 +010067 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 ******************************************************************************/
77static 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 ******************************************************************************/
97int 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}