1b4315306SDan Handley /* 2*ef1daa42SManish V Badarkhe * Copyright (c) 2015-2021, ARM Limited. All rights reserved. 3b4315306SDan Handley * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5b4315306SDan Handley */ 609d40e0eSAntonio Nino Diaz 709d40e0eSAntonio Nino Diaz #include <common/debug.h> 809d40e0eSAntonio Nino Diaz #include <drivers/io/io_driver.h> 909d40e0eSAntonio Nino Diaz #include <drivers/io/io_fip.h> 1009d40e0eSAntonio Nino Diaz #include <drivers/io/io_memmap.h> 1109d40e0eSAntonio Nino Diaz #include <drivers/io/io_storage.h> 12*ef1daa42SManish V Badarkhe #include <drivers/partition/partition.h> 1309d40e0eSAntonio Nino Diaz #include <lib/utils.h> 14a6de824fSLouis Mayencourt 15a6de824fSLouis Mayencourt #include <plat/arm/common/arm_fconf_getter.h> 16a6de824fSLouis Mayencourt #include <plat/arm/common/arm_fconf_io_storage.h> 17bd9344f6SAntonio Nino Diaz #include <plat/arm/common/plat_arm.h> 1809d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 19a6de824fSLouis Mayencourt #include <platform_def.h> 2009d40e0eSAntonio Nino Diaz 21b4315306SDan Handley /* IO devices */ 22b4315306SDan Handley static const io_dev_connector_t *fip_dev_con; 23a6de824fSLouis Mayencourt uintptr_t fip_dev_handle; 24b4315306SDan Handley static const io_dev_connector_t *memmap_dev_con; 25a6de824fSLouis Mayencourt uintptr_t memmap_dev_handle; 26b4315306SDan Handley 27b4315306SDan Handley /* Weak definitions may be overridden in specific ARM standard platform */ 28b4315306SDan Handley #pragma weak plat_arm_io_setup 29b4315306SDan Handley #pragma weak plat_arm_get_alt_image_source 30b4315306SDan Handley 31a6de824fSLouis Mayencourt int open_fip(const uintptr_t spec) 32b4315306SDan Handley { 33b4315306SDan Handley int result; 34b4315306SDan Handley uintptr_t local_image_handle; 35b4315306SDan Handley 36b4315306SDan Handley /* See if a Firmware Image Package is available */ 3716948ae1SJuan Castillo result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 38e098e244SJuan Castillo if (result == 0) { 39b4315306SDan Handley result = io_open(fip_dev_handle, spec, &local_image_handle); 40e098e244SJuan Castillo if (result == 0) { 41b4315306SDan Handley VERBOSE("Using FIP\n"); 42b4315306SDan Handley io_close(local_image_handle); 43b4315306SDan Handley } 44b4315306SDan Handley } 45b4315306SDan Handley return result; 46b4315306SDan Handley } 47b4315306SDan Handley 48a6de824fSLouis Mayencourt int open_memmap(const uintptr_t spec) 49b4315306SDan Handley { 50b4315306SDan Handley int result; 51b4315306SDan Handley uintptr_t local_image_handle; 52b4315306SDan Handley 53b4315306SDan Handley result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 54e098e244SJuan Castillo if (result == 0) { 55b4315306SDan Handley result = io_open(memmap_dev_handle, spec, &local_image_handle); 56e098e244SJuan Castillo if (result == 0) { 57b4315306SDan Handley VERBOSE("Using Memmap\n"); 58b4315306SDan Handley io_close(local_image_handle); 59b4315306SDan Handley } 60b4315306SDan Handley } 61b4315306SDan Handley return result; 62b4315306SDan Handley } 63b4315306SDan Handley 6497399821SLouis Mayencourt int arm_io_setup(void) 65b4315306SDan Handley { 66b4315306SDan Handley int io_result; 67b4315306SDan Handley 68b4315306SDan Handley io_result = register_io_dev_fip(&fip_dev_con); 6997399821SLouis Mayencourt if (io_result < 0) { 7097399821SLouis Mayencourt return io_result; 7197399821SLouis Mayencourt } 72b4315306SDan Handley 73b4315306SDan Handley io_result = register_io_dev_memmap(&memmap_dev_con); 7497399821SLouis Mayencourt if (io_result < 0) { 7597399821SLouis Mayencourt return io_result; 7697399821SLouis Mayencourt } 77b4315306SDan Handley 78b4315306SDan Handley /* Open connections to devices and cache the handles */ 79b4315306SDan Handley io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 80b4315306SDan Handley &fip_dev_handle); 8197399821SLouis Mayencourt if (io_result < 0) { 8297399821SLouis Mayencourt return io_result; 8397399821SLouis Mayencourt } 84b4315306SDan Handley 85b4315306SDan Handley io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 86b4315306SDan Handley &memmap_dev_handle); 87b4315306SDan Handley 8897399821SLouis Mayencourt return io_result; 89b4315306SDan Handley } 90b4315306SDan Handley 91b4315306SDan Handley void plat_arm_io_setup(void) 92b4315306SDan Handley { 9397399821SLouis Mayencourt int err; 9497399821SLouis Mayencourt 9597399821SLouis Mayencourt err = arm_io_setup(); 9697399821SLouis Mayencourt if (err < 0) { 9797399821SLouis Mayencourt panic(); 9897399821SLouis Mayencourt } 99b4315306SDan Handley } 100b4315306SDan Handley 101b4315306SDan Handley int plat_arm_get_alt_image_source( 10265cd299fSSoren Brinkmann unsigned int image_id __unused, 10365cd299fSSoren Brinkmann uintptr_t *dev_handle __unused, 10465cd299fSSoren Brinkmann uintptr_t *image_spec __unused) 105b4315306SDan Handley { 106b4315306SDan Handley /* By default do not try an alternative */ 107e098e244SJuan Castillo return -ENOENT; 108b4315306SDan Handley } 109b4315306SDan Handley 110b4315306SDan Handley /* Return an IO device handle and specification which can be used to access 111b4315306SDan Handley * an image. Use this to enforce platform load policy */ 11216948ae1SJuan Castillo int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 113b4315306SDan Handley uintptr_t *image_spec) 114b4315306SDan Handley { 115e098e244SJuan Castillo int result; 116b4315306SDan Handley const struct plat_io_policy *policy; 117b4315306SDan Handley 118a6de824fSLouis Mayencourt policy = FCONF_GET_PROPERTY(arm, io_policies, image_id); 119b4315306SDan Handley result = policy->check(policy->image_spec); 120e098e244SJuan Castillo if (result == 0) { 121b4315306SDan Handley *image_spec = policy->image_spec; 122b4315306SDan Handley *dev_handle = *(policy->dev_handle); 123b4315306SDan Handley } else { 12416948ae1SJuan Castillo VERBOSE("Trying alternative IO\n"); 12516948ae1SJuan Castillo result = plat_arm_get_alt_image_source(image_id, dev_handle, 12616948ae1SJuan Castillo image_spec); 127b4315306SDan Handley } 12816948ae1SJuan Castillo 129b4315306SDan Handley return result; 130b4315306SDan Handley } 131436223deSYatharth Kochar 132436223deSYatharth Kochar /* 133436223deSYatharth Kochar * See if a Firmware Image Package is available, 134436223deSYatharth Kochar * by checking if TOC is valid or not. 135436223deSYatharth Kochar */ 136d6dcbcadSLouis Mayencourt bool arm_io_is_toc_valid(void) 137436223deSYatharth Kochar { 138d6dcbcadSLouis Mayencourt return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); 139436223deSYatharth Kochar } 140*ef1daa42SManish V Badarkhe 141*ef1daa42SManish V Badarkhe #if ARM_GPT_SUPPORT 142*ef1daa42SManish V Badarkhe /********************************************************************** 143*ef1daa42SManish V Badarkhe * arm_set_image_source: Set image specification in IO policy 144*ef1daa42SManish V Badarkhe * 145*ef1daa42SManish V Badarkhe * @image_id: id of the image whose specification to be set 146*ef1daa42SManish V Badarkhe * 147*ef1daa42SManish V Badarkhe * @part_name: name of the partition that to be read for entry details 148*ef1daa42SManish V Badarkhe * 149*ef1daa42SManish V Badarkhe * set the entry and offset details of partition in global IO policy 150*ef1daa42SManish V Badarkhe * of the image 151*ef1daa42SManish V Badarkhe *********************************************************************/ 152*ef1daa42SManish V Badarkhe int arm_set_image_source(unsigned int image_id, const char *part_name) 153*ef1daa42SManish V Badarkhe { 154*ef1daa42SManish V Badarkhe const partition_entry_t *entry = get_partition_entry(part_name); 155*ef1daa42SManish V Badarkhe 156*ef1daa42SManish V Badarkhe if (entry == NULL) { 157*ef1daa42SManish V Badarkhe ERROR("Unable to find the %s partition\n", part_name); 158*ef1daa42SManish V Badarkhe return -ENOENT; 159*ef1daa42SManish V Badarkhe } 160*ef1daa42SManish V Badarkhe 161*ef1daa42SManish V Badarkhe const struct plat_io_policy *policy = FCONF_GET_PROPERTY(arm, 162*ef1daa42SManish V Badarkhe io_policies, 163*ef1daa42SManish V Badarkhe image_id); 164*ef1daa42SManish V Badarkhe 165*ef1daa42SManish V Badarkhe assert(policy != NULL); 166*ef1daa42SManish V Badarkhe assert(policy->image_spec != 0UL); 167*ef1daa42SManish V Badarkhe 168*ef1daa42SManish V Badarkhe /* set offset and length of the image */ 169*ef1daa42SManish V Badarkhe io_block_spec_t *image_spec = (io_block_spec_t *)policy->image_spec; 170*ef1daa42SManish V Badarkhe 171*ef1daa42SManish V Badarkhe image_spec->offset = PLAT_ARM_FLASH_IMAGE_BASE + entry->start; 172*ef1daa42SManish V Badarkhe image_spec->length = entry->length; 173*ef1daa42SManish V Badarkhe 174*ef1daa42SManish V Badarkhe return 0; 175*ef1daa42SManish V Badarkhe } 176*ef1daa42SManish V Badarkhe #endif 177