blob: 9c3dc71776a8564d67b50ee0cb1d8abb397af759 [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
Achin Guptada6ef0e2019-10-11 14:54:48 +010040 rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state);
41 if (rc)
42 NOTICE("Execution state not specified in SPM core manifest.\n");
43
44 rc = fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size);
45 if (rc)
46 NOTICE("Binary size not specified in SPM core manifest.\n");
47
48 rc = fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address);
49 if (rc)
50 NOTICE("Load address not specified in SPM core manifest.\n");
51
52 rc = fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint);
53 if (rc)
54 NOTICE("Entrypoint not specified in SPM core manifest.\n");
55
56 VERBOSE("SPM core manifest attribute section:\n");
57 VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version);
Achin Guptada6ef0e2019-10-11 14:54:48 +010058 VERBOSE(" binary_size: 0x%x\n", attr->binary_size);
59 VERBOSE(" load_address: 0x%llx\n", attr->load_address);
60 VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint);
61
62 return 0;
63}
64
65/*******************************************************************************
66 * Root node handler
67 ******************************************************************************/
68static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest,
69 const void *fdt,
70 int root)
71{
72 int node;
73 char *str;
74
75 str = "attribute";
76 node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
77 if (node < 0) {
78 ERROR("Root node doesn't contain subnode '%s'\n", str);
79 return -ENOENT;
80 }
81
82 return manifest_parse_attribute(manifest, fdt, node);
83}
84
85/*******************************************************************************
86 * Platform handler to parse a SPM core manifest.
87 ******************************************************************************/
88int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest,
89 const void *ptr,
90 size_t size)
91{
92 int rc;
93 int root_node;
94
95 assert(manifest != NULL);
96 assert(ptr != NULL);
97
98 INFO("Reading SPM core manifest at address %p\n", ptr);
99
100 rc = fdt_check_header(ptr);
101 if (rc != 0) {
102 ERROR("Wrong format for SPM core manifest (%d).\n", rc);
103 return -EINVAL;
104 }
105
106 INFO("Reading SPM core manifest at address %p\n", ptr);
107
108 root_node = fdt_node_offset_by_compatible(ptr, -1,
109 "arm,spci-core-manifest-1.0");
110 if (root_node < 0) {
111 ERROR("Unrecognized SPM core manifest\n");
112 return -ENOENT;
113 }
114
115 INFO("Reading SPM core manifest at address %p\n", ptr);
116 return manifest_parse_root(manifest, ptr, root_node);
117}