xref: /rk3399_ARM-atf/plat/arm/common/arm_io_storage.c (revision ef1daa420f7b2920b2ee35379de2aefed6ab2605)
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