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 { 240cb64d01SAchin Gupta int rc = 0; 250cb64d01SAchin Gupta 260cb64d01SAchin Gupta assert(attr && fdt); 270cb64d01SAchin Gupta 280cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "maj_ver", 1, &attr->major_version); 290cb64d01SAchin Gupta if (rc) { 300cb64d01SAchin Gupta ERROR("Missing SPCI major version in SPM core manifest.\n"); 310cb64d01SAchin Gupta return -ENOENT; 320cb64d01SAchin Gupta } 330cb64d01SAchin Gupta 340cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "min_ver", 1, &attr->minor_version); 350cb64d01SAchin Gupta if (rc) { 360cb64d01SAchin Gupta ERROR("Missing SPCI minor version in SPM core manifest.\n"); 370cb64d01SAchin Gupta return -ENOENT; 380cb64d01SAchin Gupta } 390cb64d01SAchin Gupta 40*ac03ac5eSMax Shvetsov rc = fdtw_read_cells(fdt, node, "spmc_id", 1, &attr->spmc_id); 41*ac03ac5eSMax Shvetsov if (rc) { 42*ac03ac5eSMax Shvetsov ERROR("Missing SPMC ID in manifest.\n"); 43*ac03ac5eSMax Shvetsov return -ENOENT; 44*ac03ac5eSMax Shvetsov } 45*ac03ac5eSMax Shvetsov 460cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); 470cb64d01SAchin Gupta if (rc) 480cb64d01SAchin Gupta NOTICE("Execution state not specified in SPM core manifest.\n"); 490cb64d01SAchin Gupta 500cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size); 510cb64d01SAchin Gupta if (rc) 520cb64d01SAchin Gupta NOTICE("Binary size not specified in SPM core manifest.\n"); 530cb64d01SAchin Gupta 540cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address); 550cb64d01SAchin Gupta if (rc) 560cb64d01SAchin Gupta NOTICE("Load address not specified in SPM core manifest.\n"); 570cb64d01SAchin Gupta 580cb64d01SAchin Gupta rc = fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint); 590cb64d01SAchin Gupta if (rc) 600cb64d01SAchin Gupta NOTICE("Entrypoint not specified in SPM core manifest.\n"); 610cb64d01SAchin Gupta 620cb64d01SAchin Gupta VERBOSE("SPM core manifest attribute section:\n"); 630cb64d01SAchin Gupta VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); 64*ac03ac5eSMax Shvetsov VERBOSE(" spmc_id: %x\n", attr->spmc_id); 650cb64d01SAchin Gupta VERBOSE(" binary_size: 0x%x\n", attr->binary_size); 660cb64d01SAchin Gupta VERBOSE(" load_address: 0x%llx\n", attr->load_address); 670cb64d01SAchin Gupta VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint); 680cb64d01SAchin Gupta 690cb64d01SAchin Gupta return 0; 700cb64d01SAchin Gupta } 710cb64d01SAchin Gupta 720cb64d01SAchin Gupta /******************************************************************************* 730cb64d01SAchin Gupta * Root node handler 740cb64d01SAchin Gupta ******************************************************************************/ 750cb64d01SAchin Gupta static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest, 760cb64d01SAchin Gupta const void *fdt, 770cb64d01SAchin Gupta int root) 780cb64d01SAchin Gupta { 790cb64d01SAchin Gupta int node; 800cb64d01SAchin Gupta char *str; 810cb64d01SAchin Gupta 820cb64d01SAchin Gupta str = "attribute"; 830cb64d01SAchin Gupta node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); 840cb64d01SAchin Gupta if (node < 0) { 850cb64d01SAchin Gupta ERROR("Root node doesn't contain subnode '%s'\n", str); 860cb64d01SAchin Gupta return -ENOENT; 870cb64d01SAchin Gupta } 880cb64d01SAchin Gupta 890cb64d01SAchin Gupta return manifest_parse_attribute(manifest, fdt, node); 900cb64d01SAchin Gupta } 910cb64d01SAchin Gupta 920cb64d01SAchin Gupta /******************************************************************************* 930cb64d01SAchin Gupta * Platform handler to parse a SPM core manifest. 940cb64d01SAchin Gupta ******************************************************************************/ 950cb64d01SAchin Gupta int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest, 960cb64d01SAchin Gupta const void *ptr, 970cb64d01SAchin Gupta size_t size) 980cb64d01SAchin Gupta { 990cb64d01SAchin Gupta int rc; 1000cb64d01SAchin Gupta int root_node; 1010cb64d01SAchin Gupta 1020cb64d01SAchin Gupta assert(manifest != NULL); 1030cb64d01SAchin Gupta assert(ptr != NULL); 1040cb64d01SAchin Gupta 1050cb64d01SAchin Gupta INFO("Reading SPM core manifest at address %p\n", ptr); 1060cb64d01SAchin Gupta 1070cb64d01SAchin Gupta rc = fdt_check_header(ptr); 1080cb64d01SAchin Gupta if (rc != 0) { 1090cb64d01SAchin Gupta ERROR("Wrong format for SPM core manifest (%d).\n", rc); 1100cb64d01SAchin Gupta return -EINVAL; 1110cb64d01SAchin Gupta } 1120cb64d01SAchin Gupta 1130cb64d01SAchin Gupta INFO("Reading SPM core manifest at address %p\n", ptr); 1140cb64d01SAchin Gupta 1150cb64d01SAchin Gupta root_node = fdt_node_offset_by_compatible(ptr, -1, 1160cb64d01SAchin Gupta "arm,spci-core-manifest-1.0"); 1170cb64d01SAchin Gupta if (root_node < 0) { 1180cb64d01SAchin Gupta ERROR("Unrecognized SPM core manifest\n"); 1190cb64d01SAchin Gupta return -ENOENT; 1200cb64d01SAchin Gupta } 1210cb64d01SAchin Gupta 1220cb64d01SAchin Gupta INFO("Reading SPM core manifest at address %p\n", ptr); 1230cb64d01SAchin Gupta return manifest_parse_root(manifest, ptr, root_node); 1240cb64d01SAchin Gupta } 125