1*0cb64d01SAchin Gupta /* 2*0cb64d01SAchin Gupta * Copyright (c) 2020, Arm Limited. All rights reserved. 3*0cb64d01SAchin Gupta * 4*0cb64d01SAchin Gupta * SPDX-License-Identifier: BSD-3-Clause 5*0cb64d01SAchin Gupta */ 6*0cb64d01SAchin Gupta 7*0cb64d01SAchin Gupta #include <assert.h> 8*0cb64d01SAchin Gupta #include <string.h> 9*0cb64d01SAchin Gupta #include <libfdt.h> 10*0cb64d01SAchin Gupta 11*0cb64d01SAchin Gupta #include <common/debug.h> 12*0cb64d01SAchin Gupta #include <common/fdt_wrappers.h> 13*0cb64d01SAchin Gupta #include <errno.h> 14*0cb64d01SAchin Gupta #include <platform_def.h> 15*0cb64d01SAchin Gupta #include <services/spm_core_manifest.h> 16*0cb64d01SAchin Gupta 17*0cb64d01SAchin Gupta /******************************************************************************* 18*0cb64d01SAchin Gupta * Attribute section handler 19*0cb64d01SAchin Gupta ******************************************************************************/ 20*0cb64d01SAchin Gupta static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, 21*0cb64d01SAchin Gupta const void *fdt, 22*0cb64d01SAchin Gupta int node) 23*0cb64d01SAchin Gupta { 24*0cb64d01SAchin Gupta int rc = 0; 25*0cb64d01SAchin Gupta 26*0cb64d01SAchin Gupta assert(attr && fdt); 27*0cb64d01SAchin Gupta 28*0cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "maj_ver", 1, &attr->major_version); 29*0cb64d01SAchin Gupta if (rc) { 30*0cb64d01SAchin Gupta ERROR("Missing SPCI major version in SPM core manifest.\n"); 31*0cb64d01SAchin Gupta return -ENOENT; 32*0cb64d01SAchin Gupta } 33*0cb64d01SAchin Gupta 34*0cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "min_ver", 1, &attr->minor_version); 35*0cb64d01SAchin Gupta if (rc) { 36*0cb64d01SAchin Gupta ERROR("Missing SPCI minor version in SPM core manifest.\n"); 37*0cb64d01SAchin Gupta return -ENOENT; 38*0cb64d01SAchin Gupta } 39*0cb64d01SAchin Gupta 40*0cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "runtime_el", 1, &attr->runtime_el); 41*0cb64d01SAchin Gupta if (rc) { 42*0cb64d01SAchin Gupta ERROR("Missing SPM core runtime EL in manifest.\n"); 43*0cb64d01SAchin Gupta return -ENOENT; 44*0cb64d01SAchin Gupta } 45*0cb64d01SAchin Gupta 46*0cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); 47*0cb64d01SAchin Gupta if (rc) 48*0cb64d01SAchin Gupta NOTICE("Execution state not specified in SPM core manifest.\n"); 49*0cb64d01SAchin Gupta 50*0cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size); 51*0cb64d01SAchin Gupta if (rc) 52*0cb64d01SAchin Gupta NOTICE("Binary size not specified in SPM core manifest.\n"); 53*0cb64d01SAchin Gupta 54*0cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address); 55*0cb64d01SAchin Gupta if (rc) 56*0cb64d01SAchin Gupta NOTICE("Load address not specified in SPM core manifest.\n"); 57*0cb64d01SAchin Gupta 58*0cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint); 59*0cb64d01SAchin Gupta if (rc) 60*0cb64d01SAchin Gupta NOTICE("Entrypoint not specified in SPM core manifest.\n"); 61*0cb64d01SAchin Gupta 62*0cb64d01SAchin Gupta VERBOSE("SPM core manifest attribute section:\n"); 63*0cb64d01SAchin Gupta VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); 64*0cb64d01SAchin Gupta VERBOSE(" runtime_el: 0x%x\n", attr->runtime_el); 65*0cb64d01SAchin Gupta VERBOSE(" binary_size: 0x%x\n", attr->binary_size); 66*0cb64d01SAchin Gupta VERBOSE(" load_address: 0x%llx\n", attr->load_address); 67*0cb64d01SAchin Gupta VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint); 68*0cb64d01SAchin Gupta 69*0cb64d01SAchin Gupta return 0; 70*0cb64d01SAchin Gupta } 71*0cb64d01SAchin Gupta 72*0cb64d01SAchin Gupta /******************************************************************************* 73*0cb64d01SAchin Gupta * Root node handler 74*0cb64d01SAchin Gupta ******************************************************************************/ 75*0cb64d01SAchin Gupta static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest, 76*0cb64d01SAchin Gupta const void *fdt, 77*0cb64d01SAchin Gupta int root) 78*0cb64d01SAchin Gupta { 79*0cb64d01SAchin Gupta int node; 80*0cb64d01SAchin Gupta char *str; 81*0cb64d01SAchin Gupta 82*0cb64d01SAchin Gupta str = "attribute"; 83*0cb64d01SAchin Gupta node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); 84*0cb64d01SAchin Gupta if (node < 0) { 85*0cb64d01SAchin Gupta ERROR("Root node doesn't contain subnode '%s'\n", str); 86*0cb64d01SAchin Gupta return -ENOENT; 87*0cb64d01SAchin Gupta } 88*0cb64d01SAchin Gupta 89*0cb64d01SAchin Gupta return manifest_parse_attribute(manifest, fdt, node); 90*0cb64d01SAchin Gupta } 91*0cb64d01SAchin Gupta 92*0cb64d01SAchin Gupta /******************************************************************************* 93*0cb64d01SAchin Gupta * Platform handler to parse a SPM core manifest. 94*0cb64d01SAchin Gupta ******************************************************************************/ 95*0cb64d01SAchin Gupta int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest, 96*0cb64d01SAchin Gupta const void *ptr, 97*0cb64d01SAchin Gupta size_t size) 98*0cb64d01SAchin Gupta { 99*0cb64d01SAchin Gupta int rc; 100*0cb64d01SAchin Gupta int root_node; 101*0cb64d01SAchin Gupta 102*0cb64d01SAchin Gupta assert(manifest != NULL); 103*0cb64d01SAchin Gupta assert(ptr != NULL); 104*0cb64d01SAchin Gupta 105*0cb64d01SAchin Gupta INFO("Reading SPM core manifest at address %p\n", ptr); 106*0cb64d01SAchin Gupta 107*0cb64d01SAchin Gupta rc = fdt_check_header(ptr); 108*0cb64d01SAchin Gupta if (rc != 0) { 109*0cb64d01SAchin Gupta ERROR("Wrong format for SPM core manifest (%d).\n", rc); 110*0cb64d01SAchin Gupta return -EINVAL; 111*0cb64d01SAchin Gupta } 112*0cb64d01SAchin Gupta 113*0cb64d01SAchin Gupta INFO("Reading SPM core manifest at address %p\n", ptr); 114*0cb64d01SAchin Gupta 115*0cb64d01SAchin Gupta root_node = fdt_node_offset_by_compatible(ptr, -1, 116*0cb64d01SAchin Gupta "arm,spci-core-manifest-1.0"); 117*0cb64d01SAchin Gupta if (root_node < 0) { 118*0cb64d01SAchin Gupta ERROR("Unrecognized SPM core manifest\n"); 119*0cb64d01SAchin Gupta return -ENOENT; 120*0cb64d01SAchin Gupta } 121*0cb64d01SAchin Gupta 122*0cb64d01SAchin Gupta INFO("Reading SPM core manifest at address %p\n", ptr); 123*0cb64d01SAchin Gupta return manifest_parse_root(manifest, ptr, root_node); 124*0cb64d01SAchin Gupta } 125