blob: 4c789795e6879308cdc159f1c437895efa50237d [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{
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, "runtime_el", 1, &attr->runtime_el);
41 if (rc) {
42 ERROR("Missing SPM core runtime EL 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(" runtime_el: 0x%x\n", attr->runtime_el);
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 ******************************************************************************/
75static 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 ******************************************************************************/
95int 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}