Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2020, Arm Limited. All rights reserved. |
| 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | |
| 7 | #include <assert.h> |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 8 | #include <errno.h> |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 9 | #include <string.h> |
| 10 | #include <libfdt.h> |
| 11 | |
| 12 | #include <common/debug.h> |
| 13 | #include <common/fdt_wrappers.h> |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 14 | #include <platform_def.h> |
| 15 | #include <services/spm_core_manifest.h> |
| 16 | |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 17 | #define ATTRIBUTE_ROOT_NODE_STR "attribute" |
| 18 | |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 19 | /******************************************************************************* |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 20 | * SPMC attribute node parser |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 21 | ******************************************************************************/ |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 22 | static int manifest_parse_attribute(spmc_manifest_attribute_t *attr, |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 23 | const void *fdt, |
| 24 | int node) |
| 25 | { |
Andre Przywara | ff4e6c3 | 2020-03-26 11:22:37 +0000 | [diff] [blame] | 26 | uint32_t val32; |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 27 | int rc; |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 28 | |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 29 | assert((attr != NULL) && (fdt != NULL)); |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 30 | |
Andre Przywara | ff4e6c3 | 2020-03-26 11:22:37 +0000 | [diff] [blame] | 31 | rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version); |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 32 | if (rc != 0) { |
| 33 | ERROR("Missing SPCI %s version in SPM Core manifest.\n", |
| 34 | "major"); |
| 35 | return rc; |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 36 | } |
| 37 | |
Andre Przywara | ff4e6c3 | 2020-03-26 11:22:37 +0000 | [diff] [blame] | 38 | rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version); |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 39 | if (rc != 0) { |
| 40 | ERROR("Missing SPCI %s version in SPM Core manifest.\n", |
| 41 | "minor"); |
| 42 | return rc; |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 43 | } |
| 44 | |
Andre Przywara | ff4e6c3 | 2020-03-26 11:22:37 +0000 | [diff] [blame] | 45 | rc = fdt_read_uint32(fdt, node, "spmc_id", &val32); |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 46 | if (rc != 0) { |
Max Shvetsov | ac03ac5 | 2020-03-12 15:16:40 +0000 | [diff] [blame] | 47 | ERROR("Missing SPMC ID in manifest.\n"); |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 48 | return rc; |
Max Shvetsov | ac03ac5 | 2020-03-12 15:16:40 +0000 | [diff] [blame] | 49 | } |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 50 | |
| 51 | attr->spmc_id = val32 & 0xffff; |
Max Shvetsov | ac03ac5 | 2020-03-12 15:16:40 +0000 | [diff] [blame] | 52 | |
Andre Przywara | ff4e6c3 | 2020-03-26 11:22:37 +0000 | [diff] [blame] | 53 | rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state); |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 54 | if (rc != 0) { |
| 55 | NOTICE("%s not specified in SPM Core manifest.\n", |
| 56 | "Execution state"); |
| 57 | } |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 58 | |
Andre Przywara | ff4e6c3 | 2020-03-26 11:22:37 +0000 | [diff] [blame] | 59 | rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size); |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 60 | if (rc != 0) { |
| 61 | NOTICE("%s not specified in SPM Core manifest.\n", |
| 62 | "Binary size"); |
| 63 | } |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 64 | |
Andre Przywara | ff4e6c3 | 2020-03-26 11:22:37 +0000 | [diff] [blame] | 65 | rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address); |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 66 | if (rc != 0) { |
| 67 | NOTICE("%s not specified in SPM Core manifest.\n", |
| 68 | "Load address"); |
| 69 | } |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 70 | |
Andre Przywara | ff4e6c3 | 2020-03-26 11:22:37 +0000 | [diff] [blame] | 71 | rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint); |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 72 | if (rc != 0) { |
| 73 | NOTICE("%s not specified in SPM Core manifest.\n", |
| 74 | "Entry point"); |
| 75 | } |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 76 | |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 77 | 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 Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 80 | 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 Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 90 | static int manifest_parse_root(spmc_manifest_attribute_t *manifest, |
| 91 | const void *fdt, |
| 92 | int root) |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 93 | { |
| 94 | int node; |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 95 | |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 96 | assert(manifest != NULL); |
| 97 | |
| 98 | node = fdt_subnode_offset_namelen(fdt, root, ATTRIBUTE_ROOT_NODE_STR, |
| 99 | sizeof(ATTRIBUTE_ROOT_NODE_STR) - 1); |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 100 | if (node < 0) { |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 101 | ERROR("Root node doesn't contain subnode '%s'\n", |
| 102 | ATTRIBUTE_ROOT_NODE_STR); |
| 103 | return node; |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 104 | } |
| 105 | |
| 106 | return manifest_parse_attribute(manifest, fdt, node); |
| 107 | } |
| 108 | |
| 109 | /******************************************************************************* |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 110 | * Platform handler to parse a SPM Core manifest. |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 111 | ******************************************************************************/ |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 112 | int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest, |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 113 | const void *ptr, |
| 114 | size_t size) |
| 115 | { |
| 116 | int rc; |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 117 | |
| 118 | assert(manifest != NULL); |
| 119 | assert(ptr != NULL); |
| 120 | |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 121 | INFO("Reading SPM Core manifest at address %p\n", ptr); |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 122 | |
| 123 | rc = fdt_check_header(ptr); |
| 124 | if (rc != 0) { |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 125 | ERROR("Wrong format for SPM Core manifest (%d).\n", rc); |
| 126 | return rc; |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 127 | } |
| 128 | |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 129 | rc = fdt_node_offset_by_compatible(ptr, -1, |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 130 | "arm,spci-core-manifest-1.0"); |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 131 | if (rc < 0) { |
| 132 | ERROR("Unrecognized SPM Core manifest\n"); |
| 133 | return rc; |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 134 | } |
| 135 | |
Olivier Deprez | 5269694 | 2020-04-16 13:39:06 +0200 | [diff] [blame^] | 136 | return manifest_parse_root(manifest, ptr, rc); |
Achin Gupta | 0cb64d0 | 2019-10-11 14:54:48 +0100 | [diff] [blame] | 137 | } |