blob: a3e30e89cc7d751e01928e8bb717f01cdf2e9544 [file] [log] [blame]
Achin Gupta0cb64d02019-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>
Olivier Deprez52696942020-04-16 13:39:06 +02008#include <errno.h>
Achin Gupta0cb64d02019-10-11 14:54:48 +01009#include <string.h>
10#include <libfdt.h>
11
12#include <common/debug.h>
13#include <common/fdt_wrappers.h>
Achin Gupta0cb64d02019-10-11 14:54:48 +010014#include <platform_def.h>
15#include <services/spm_core_manifest.h>
16
Olivier Deprez52696942020-04-16 13:39:06 +020017#define ATTRIBUTE_ROOT_NODE_STR "attribute"
18
Achin Gupta0cb64d02019-10-11 14:54:48 +010019/*******************************************************************************
Olivier Deprez52696942020-04-16 13:39:06 +020020 * SPMC attribute node parser
Achin Gupta0cb64d02019-10-11 14:54:48 +010021 ******************************************************************************/
Olivier Deprez52696942020-04-16 13:39:06 +020022static int manifest_parse_attribute(spmc_manifest_attribute_t *attr,
Achin Gupta0cb64d02019-10-11 14:54:48 +010023 const void *fdt,
24 int node)
25{
Andre Przywaraff4e6c32020-03-26 11:22:37 +000026 uint32_t val32;
Olivier Deprez52696942020-04-16 13:39:06 +020027 int rc;
Achin Gupta0cb64d02019-10-11 14:54:48 +010028
Olivier Deprez52696942020-04-16 13:39:06 +020029 assert((attr != NULL) && (fdt != NULL));
Achin Gupta0cb64d02019-10-11 14:54:48 +010030
Andre Przywaraff4e6c32020-03-26 11:22:37 +000031 rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version);
Olivier Deprez52696942020-04-16 13:39:06 +020032 if (rc != 0) {
33 ERROR("Missing SPCI %s version in SPM Core manifest.\n",
34 "major");
35 return rc;
Achin Gupta0cb64d02019-10-11 14:54:48 +010036 }
37
Andre Przywaraff4e6c32020-03-26 11:22:37 +000038 rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version);
Olivier Deprez52696942020-04-16 13:39:06 +020039 if (rc != 0) {
40 ERROR("Missing SPCI %s version in SPM Core manifest.\n",
41 "minor");
42 return rc;
Achin Gupta0cb64d02019-10-11 14:54:48 +010043 }
44
Andre Przywaraff4e6c32020-03-26 11:22:37 +000045 rc = fdt_read_uint32(fdt, node, "spmc_id", &val32);
Olivier Deprez52696942020-04-16 13:39:06 +020046 if (rc != 0) {
Max Shvetsovac03ac52020-03-12 15:16:40 +000047 ERROR("Missing SPMC ID in manifest.\n");
Olivier Deprez52696942020-04-16 13:39:06 +020048 return rc;
Max Shvetsovac03ac52020-03-12 15:16:40 +000049 }
Olivier Deprez52696942020-04-16 13:39:06 +020050
51 attr->spmc_id = val32 & 0xffff;
Max Shvetsovac03ac52020-03-12 15:16:40 +000052
Andre Przywaraff4e6c32020-03-26 11:22:37 +000053 rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state);
Olivier Deprez52696942020-04-16 13:39:06 +020054 if (rc != 0) {
55 NOTICE("%s not specified in SPM Core manifest.\n",
56 "Execution state");
57 }
Achin Gupta0cb64d02019-10-11 14:54:48 +010058
Andre Przywaraff4e6c32020-03-26 11:22:37 +000059 rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size);
Olivier Deprez52696942020-04-16 13:39:06 +020060 if (rc != 0) {
61 NOTICE("%s not specified in SPM Core manifest.\n",
62 "Binary size");
63 }
Achin Gupta0cb64d02019-10-11 14:54:48 +010064
Andre Przywaraff4e6c32020-03-26 11:22:37 +000065 rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address);
Olivier Deprez52696942020-04-16 13:39:06 +020066 if (rc != 0) {
67 NOTICE("%s not specified in SPM Core manifest.\n",
68 "Load address");
69 }
Achin Gupta0cb64d02019-10-11 14:54:48 +010070
Andre Przywaraff4e6c32020-03-26 11:22:37 +000071 rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint);
Olivier Deprez52696942020-04-16 13:39:06 +020072 if (rc != 0) {
73 NOTICE("%s not specified in SPM Core manifest.\n",
74 "Entry point");
75 }
Achin Gupta0cb64d02019-10-11 14:54:48 +010076
Olivier Deprez52696942020-04-16 13:39:06 +020077 VERBOSE("SPM Core manifest attribute section:\n");
78 VERBOSE(" version: %u.%u\n", attr->major_version, attr->minor_version);
79 VERBOSE(" spmc_id: 0x%x\n", attr->spmc_id);
Achin Gupta0cb64d02019-10-11 14:54:48 +010080 VERBOSE(" binary_size: 0x%x\n", attr->binary_size);
81 VERBOSE(" load_address: 0x%llx\n", attr->load_address);
82 VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint);
83
84 return 0;
85}
86
87/*******************************************************************************
88 * Root node handler
89 ******************************************************************************/
Olivier Deprez52696942020-04-16 13:39:06 +020090static int manifest_parse_root(spmc_manifest_attribute_t *manifest,
91 const void *fdt,
92 int root)
Achin Gupta0cb64d02019-10-11 14:54:48 +010093{
94 int node;
Achin Gupta0cb64d02019-10-11 14:54:48 +010095
Olivier Deprez52696942020-04-16 13:39:06 +020096 assert(manifest != NULL);
97
98 node = fdt_subnode_offset_namelen(fdt, root, ATTRIBUTE_ROOT_NODE_STR,
99 sizeof(ATTRIBUTE_ROOT_NODE_STR) - 1);
Achin Gupta0cb64d02019-10-11 14:54:48 +0100100 if (node < 0) {
Olivier Deprez52696942020-04-16 13:39:06 +0200101 ERROR("Root node doesn't contain subnode '%s'\n",
102 ATTRIBUTE_ROOT_NODE_STR);
103 return node;
Achin Gupta0cb64d02019-10-11 14:54:48 +0100104 }
105
106 return manifest_parse_attribute(manifest, fdt, node);
107}
108
109/*******************************************************************************
Olivier Deprez52696942020-04-16 13:39:06 +0200110 * Platform handler to parse a SPM Core manifest.
Achin Gupta0cb64d02019-10-11 14:54:48 +0100111 ******************************************************************************/
Olivier Deprez52696942020-04-16 13:39:06 +0200112int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
Achin Gupta0cb64d02019-10-11 14:54:48 +0100113 const void *ptr,
114 size_t size)
115{
116 int rc;
Achin Gupta0cb64d02019-10-11 14:54:48 +0100117
118 assert(manifest != NULL);
119 assert(ptr != NULL);
120
Olivier Deprez52696942020-04-16 13:39:06 +0200121 INFO("Reading SPM Core manifest at address %p\n", ptr);
Achin Gupta0cb64d02019-10-11 14:54:48 +0100122
123 rc = fdt_check_header(ptr);
124 if (rc != 0) {
Olivier Deprez52696942020-04-16 13:39:06 +0200125 ERROR("Wrong format for SPM Core manifest (%d).\n", rc);
126 return rc;
Achin Gupta0cb64d02019-10-11 14:54:48 +0100127 }
128
Olivier Deprez52696942020-04-16 13:39:06 +0200129 rc = fdt_node_offset_by_compatible(ptr, -1,
Achin Gupta0cb64d02019-10-11 14:54:48 +0100130 "arm,spci-core-manifest-1.0");
Olivier Deprez52696942020-04-16 13:39:06 +0200131 if (rc < 0) {
132 ERROR("Unrecognized SPM Core manifest\n");
133 return rc;
Achin Gupta0cb64d02019-10-11 14:54:48 +0100134 }
135
Olivier Deprez52696942020-04-16 13:39:06 +0200136 return manifest_parse_root(manifest, ptr, rc);
Achin Gupta0cb64d02019-10-11 14:54:48 +0100137}