10cb64d01SAchin Gupta /* 20cb64d01SAchin Gupta * Copyright (c) 2020, Arm Limited. All rights reserved. 30cb64d01SAchin Gupta * 40cb64d01SAchin Gupta * SPDX-License-Identifier: BSD-3-Clause 50cb64d01SAchin Gupta */ 60cb64d01SAchin Gupta 70cb64d01SAchin Gupta #include <assert.h> 80cb64d01SAchin Gupta #include <string.h> 90cb64d01SAchin Gupta #include <libfdt.h> 100cb64d01SAchin Gupta 110cb64d01SAchin Gupta #include <common/debug.h> 120cb64d01SAchin Gupta #include <common/fdt_wrappers.h> 130cb64d01SAchin Gupta #include <errno.h> 140cb64d01SAchin Gupta #include <platform_def.h> 150cb64d01SAchin Gupta #include <services/spm_core_manifest.h> 160cb64d01SAchin Gupta 170cb64d01SAchin Gupta /******************************************************************************* 180cb64d01SAchin Gupta * Attribute section handler 190cb64d01SAchin Gupta ******************************************************************************/ 200cb64d01SAchin Gupta static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, 210cb64d01SAchin Gupta const void *fdt, 220cb64d01SAchin Gupta int node) 230cb64d01SAchin Gupta { 24*ff4e6c35SAndre Przywara uint32_t val32; 250cb64d01SAchin Gupta int rc = 0; 260cb64d01SAchin Gupta 270cb64d01SAchin Gupta assert(attr && fdt); 280cb64d01SAchin Gupta 29*ff4e6c35SAndre Przywara rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version); 300cb64d01SAchin Gupta if (rc) { 310cb64d01SAchin Gupta ERROR("Missing SPCI major version in SPM core manifest.\n"); 320cb64d01SAchin Gupta return -ENOENT; 330cb64d01SAchin Gupta } 340cb64d01SAchin Gupta 35*ff4e6c35SAndre Przywara rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version); 360cb64d01SAchin Gupta if (rc) { 370cb64d01SAchin Gupta ERROR("Missing SPCI minor version in SPM core manifest.\n"); 380cb64d01SAchin Gupta return -ENOENT; 390cb64d01SAchin Gupta } 400cb64d01SAchin Gupta 41*ff4e6c35SAndre Przywara rc = fdt_read_uint32(fdt, node, "spmc_id", &val32); 42ac03ac5eSMax Shvetsov if (rc) { 43ac03ac5eSMax Shvetsov ERROR("Missing SPMC ID in manifest.\n"); 44ac03ac5eSMax Shvetsov return -ENOENT; 45ac03ac5eSMax Shvetsov } 46*ff4e6c35SAndre Przywara attr->spmc_id = val32; 47ac03ac5eSMax Shvetsov 48*ff4e6c35SAndre Przywara rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state); 490cb64d01SAchin Gupta if (rc) 500cb64d01SAchin Gupta NOTICE("Execution state not specified in SPM core manifest.\n"); 510cb64d01SAchin Gupta 52*ff4e6c35SAndre Przywara rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size); 530cb64d01SAchin Gupta if (rc) 540cb64d01SAchin Gupta NOTICE("Binary size not specified in SPM core manifest.\n"); 550cb64d01SAchin Gupta 56*ff4e6c35SAndre Przywara rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address); 570cb64d01SAchin Gupta if (rc) 580cb64d01SAchin Gupta NOTICE("Load address not specified in SPM core manifest.\n"); 590cb64d01SAchin Gupta 60*ff4e6c35SAndre Przywara rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint); 610cb64d01SAchin Gupta if (rc) 620cb64d01SAchin Gupta NOTICE("Entrypoint not specified in SPM core manifest.\n"); 630cb64d01SAchin Gupta 640cb64d01SAchin Gupta VERBOSE("SPM core manifest attribute section:\n"); 650cb64d01SAchin Gupta VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); 66ac03ac5eSMax Shvetsov VERBOSE(" spmc_id: %x\n", attr->spmc_id); 670cb64d01SAchin Gupta VERBOSE(" binary_size: 0x%x\n", attr->binary_size); 680cb64d01SAchin Gupta VERBOSE(" load_address: 0x%llx\n", attr->load_address); 690cb64d01SAchin Gupta VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint); 700cb64d01SAchin Gupta 710cb64d01SAchin Gupta return 0; 720cb64d01SAchin Gupta } 730cb64d01SAchin Gupta 740cb64d01SAchin Gupta /******************************************************************************* 750cb64d01SAchin Gupta * Root node handler 760cb64d01SAchin Gupta ******************************************************************************/ 770cb64d01SAchin Gupta static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest, 780cb64d01SAchin Gupta const void *fdt, 790cb64d01SAchin Gupta int root) 800cb64d01SAchin Gupta { 810cb64d01SAchin Gupta int node; 820cb64d01SAchin Gupta char *str; 830cb64d01SAchin Gupta 840cb64d01SAchin Gupta str = "attribute"; 850cb64d01SAchin Gupta node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); 860cb64d01SAchin Gupta if (node < 0) { 870cb64d01SAchin Gupta ERROR("Root node doesn't contain subnode '%s'\n", str); 880cb64d01SAchin Gupta return -ENOENT; 890cb64d01SAchin Gupta } 900cb64d01SAchin Gupta 910cb64d01SAchin Gupta return manifest_parse_attribute(manifest, fdt, node); 920cb64d01SAchin Gupta } 930cb64d01SAchin Gupta 940cb64d01SAchin Gupta /******************************************************************************* 950cb64d01SAchin Gupta * Platform handler to parse a SPM core manifest. 960cb64d01SAchin Gupta ******************************************************************************/ 970cb64d01SAchin Gupta int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest, 980cb64d01SAchin Gupta const void *ptr, 990cb64d01SAchin Gupta size_t size) 1000cb64d01SAchin Gupta { 1010cb64d01SAchin Gupta int rc; 1020cb64d01SAchin Gupta int root_node; 1030cb64d01SAchin Gupta 1040cb64d01SAchin Gupta assert(manifest != NULL); 1050cb64d01SAchin Gupta assert(ptr != NULL); 1060cb64d01SAchin Gupta 1070cb64d01SAchin Gupta INFO("Reading SPM core manifest at address %p\n", ptr); 1080cb64d01SAchin Gupta 1090cb64d01SAchin Gupta rc = fdt_check_header(ptr); 1100cb64d01SAchin Gupta if (rc != 0) { 1110cb64d01SAchin Gupta ERROR("Wrong format for SPM core manifest (%d).\n", rc); 1120cb64d01SAchin Gupta return -EINVAL; 1130cb64d01SAchin Gupta } 1140cb64d01SAchin Gupta 1150cb64d01SAchin Gupta INFO("Reading SPM core manifest at address %p\n", ptr); 1160cb64d01SAchin Gupta 1170cb64d01SAchin Gupta root_node = fdt_node_offset_by_compatible(ptr, -1, 1180cb64d01SAchin Gupta "arm,spci-core-manifest-1.0"); 1190cb64d01SAchin Gupta if (root_node < 0) { 1200cb64d01SAchin Gupta ERROR("Unrecognized SPM core manifest\n"); 1210cb64d01SAchin Gupta return -ENOENT; 1220cb64d01SAchin Gupta } 1230cb64d01SAchin Gupta 1240cb64d01SAchin Gupta INFO("Reading SPM core manifest at address %p\n", ptr); 1250cb64d01SAchin Gupta return manifest_parse_root(manifest, ptr, root_node); 1260cb64d01SAchin Gupta } 127