xref: /aosp_15_r20/external/arm-trusted-firmware/drivers/io/io_dummy.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  */
6*54fd6939SJiyong Park 
7*54fd6939SJiyong Park #include <assert.h>
8*54fd6939SJiyong Park #include <string.h>
9*54fd6939SJiyong Park 
10*54fd6939SJiyong Park #include <common/debug.h>
11*54fd6939SJiyong Park #include <drivers/io/io_driver.h>
12*54fd6939SJiyong Park #include <drivers/io/io_dummy.h>
13*54fd6939SJiyong Park #include <drivers/io/io_storage.h>
14*54fd6939SJiyong Park 
15*54fd6939SJiyong Park struct file_state {
16*54fd6939SJiyong Park 	int in_use;
17*54fd6939SJiyong Park 	size_t size;
18*54fd6939SJiyong Park };
19*54fd6939SJiyong Park 
20*54fd6939SJiyong Park static struct file_state current_file = {0};
21*54fd6939SJiyong Park 
22*54fd6939SJiyong Park /* Identify the device type as dummy */
device_type_dummy(void)23*54fd6939SJiyong Park static io_type_t device_type_dummy(void)
24*54fd6939SJiyong Park {
25*54fd6939SJiyong Park 	return IO_TYPE_DUMMY;
26*54fd6939SJiyong Park }
27*54fd6939SJiyong Park 
28*54fd6939SJiyong Park /* Dummy device functions */
29*54fd6939SJiyong Park static int dummy_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
30*54fd6939SJiyong Park static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
31*54fd6939SJiyong Park 			     io_entity_t *entity);
32*54fd6939SJiyong Park static int dummy_block_len(io_entity_t *entity, size_t *length);
33*54fd6939SJiyong Park static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
34*54fd6939SJiyong Park 			     size_t length, size_t *length_read);
35*54fd6939SJiyong Park static int dummy_block_close(io_entity_t *entity);
36*54fd6939SJiyong Park static int dummy_dev_close(io_dev_info_t *dev_info);
37*54fd6939SJiyong Park 
38*54fd6939SJiyong Park 
39*54fd6939SJiyong Park static const io_dev_connector_t dummy_dev_connector = {
40*54fd6939SJiyong Park 	.dev_open = dummy_dev_open
41*54fd6939SJiyong Park };
42*54fd6939SJiyong Park 
43*54fd6939SJiyong Park 
44*54fd6939SJiyong Park static const io_dev_funcs_t dummy_dev_funcs = {
45*54fd6939SJiyong Park 	.type = device_type_dummy,
46*54fd6939SJiyong Park 	.open = dummy_block_open,
47*54fd6939SJiyong Park 	.seek = NULL,
48*54fd6939SJiyong Park 	.size = dummy_block_len,
49*54fd6939SJiyong Park 	.read = dummy_block_read,
50*54fd6939SJiyong Park 	.write = NULL,
51*54fd6939SJiyong Park 	.close = dummy_block_close,
52*54fd6939SJiyong Park 	.dev_init = NULL,
53*54fd6939SJiyong Park 	.dev_close = dummy_dev_close,
54*54fd6939SJiyong Park };
55*54fd6939SJiyong Park 
56*54fd6939SJiyong Park 
57*54fd6939SJiyong Park static const io_dev_info_t dummy_dev_info = {
58*54fd6939SJiyong Park 	.funcs = &dummy_dev_funcs,
59*54fd6939SJiyong Park 	.info = (uintptr_t)NULL
60*54fd6939SJiyong Park };
61*54fd6939SJiyong Park 
62*54fd6939SJiyong Park 
63*54fd6939SJiyong Park /* Open a connection to the dummy device */
dummy_dev_open(const uintptr_t dev_spec,io_dev_info_t ** dev_info)64*54fd6939SJiyong Park static int dummy_dev_open(const uintptr_t dev_spec __attribute__((unused)),
65*54fd6939SJiyong Park 			   io_dev_info_t **dev_info)
66*54fd6939SJiyong Park {
67*54fd6939SJiyong Park 	assert(dev_info != NULL);
68*54fd6939SJiyong Park 	*dev_info = (io_dev_info_t *)&dummy_dev_info;
69*54fd6939SJiyong Park 
70*54fd6939SJiyong Park 	return 0;
71*54fd6939SJiyong Park }
72*54fd6939SJiyong Park 
73*54fd6939SJiyong Park 
74*54fd6939SJiyong Park /* Close a connection to the dummy device */
dummy_dev_close(io_dev_info_t * dev_info)75*54fd6939SJiyong Park static int dummy_dev_close(io_dev_info_t *dev_info)
76*54fd6939SJiyong Park {
77*54fd6939SJiyong Park 	return 0;
78*54fd6939SJiyong Park }
79*54fd6939SJiyong Park 
80*54fd6939SJiyong Park 
81*54fd6939SJiyong Park /* Open a file on the dummy device */
dummy_block_open(io_dev_info_t * dev_info,const uintptr_t spec,io_entity_t * entity)82*54fd6939SJiyong Park static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
83*54fd6939SJiyong Park 			     io_entity_t *entity)
84*54fd6939SJiyong Park {
85*54fd6939SJiyong Park 	int result;
86*54fd6939SJiyong Park 	const io_block_spec_t *block_spec = (io_block_spec_t *)spec;
87*54fd6939SJiyong Park 
88*54fd6939SJiyong Park 	if (current_file.in_use == 0) {
89*54fd6939SJiyong Park 		assert(block_spec != NULL);
90*54fd6939SJiyong Park 		assert(entity != NULL);
91*54fd6939SJiyong Park 
92*54fd6939SJiyong Park 		current_file.in_use = 1;
93*54fd6939SJiyong Park 		current_file.size = block_spec->length;
94*54fd6939SJiyong Park 		entity->info = (uintptr_t)&current_file;
95*54fd6939SJiyong Park 		result = 0;
96*54fd6939SJiyong Park 	} else {
97*54fd6939SJiyong Park 		WARN("A Dummy device is already active. Close first.\n");
98*54fd6939SJiyong Park 		result = -ENOMEM;
99*54fd6939SJiyong Park 	}
100*54fd6939SJiyong Park 
101*54fd6939SJiyong Park 	return result;
102*54fd6939SJiyong Park }
103*54fd6939SJiyong Park 
104*54fd6939SJiyong Park 
105*54fd6939SJiyong Park /* Return the size of a file on the dummy device */
dummy_block_len(io_entity_t * entity,size_t * length)106*54fd6939SJiyong Park static int dummy_block_len(io_entity_t *entity, size_t *length)
107*54fd6939SJiyong Park {
108*54fd6939SJiyong Park 	assert(entity != NULL);
109*54fd6939SJiyong Park 	assert(length != NULL);
110*54fd6939SJiyong Park 
111*54fd6939SJiyong Park 	*length =  ((struct file_state *)entity->info)->size;
112*54fd6939SJiyong Park 
113*54fd6939SJiyong Park 	return 0;
114*54fd6939SJiyong Park }
115*54fd6939SJiyong Park 
116*54fd6939SJiyong Park 
117*54fd6939SJiyong Park /* Read data from a file on the dummy device */
dummy_block_read(io_entity_t * entity,uintptr_t buffer,size_t length,size_t * length_read)118*54fd6939SJiyong Park static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
119*54fd6939SJiyong Park 			     size_t length, size_t *length_read)
120*54fd6939SJiyong Park {
121*54fd6939SJiyong Park 	assert(length_read != NULL);
122*54fd6939SJiyong Park 
123*54fd6939SJiyong Park 	*length_read = length;
124*54fd6939SJiyong Park 
125*54fd6939SJiyong Park 	return 0;
126*54fd6939SJiyong Park }
127*54fd6939SJiyong Park 
128*54fd6939SJiyong Park 
129*54fd6939SJiyong Park /* Close a file on the dummy device */
dummy_block_close(io_entity_t * entity)130*54fd6939SJiyong Park static int dummy_block_close(io_entity_t *entity)
131*54fd6939SJiyong Park {
132*54fd6939SJiyong Park 	assert(entity != NULL);
133*54fd6939SJiyong Park 
134*54fd6939SJiyong Park 	entity->info = 0;
135*54fd6939SJiyong Park 	current_file.in_use = 0;
136*54fd6939SJiyong Park 
137*54fd6939SJiyong Park 	return 0;
138*54fd6939SJiyong Park }
139*54fd6939SJiyong Park 
140*54fd6939SJiyong Park 
141*54fd6939SJiyong Park /* Exported functions */
142*54fd6939SJiyong Park 
143*54fd6939SJiyong Park /* Register the dummy driver with the IO abstraction */
register_io_dev_dummy(const io_dev_connector_t ** dev_con)144*54fd6939SJiyong Park int register_io_dev_dummy(const io_dev_connector_t **dev_con)
145*54fd6939SJiyong Park {
146*54fd6939SJiyong Park 	int result;
147*54fd6939SJiyong Park 
148*54fd6939SJiyong Park 	assert(dev_con != NULL);
149*54fd6939SJiyong Park 
150*54fd6939SJiyong Park 	result = io_register_device(&dummy_dev_info);
151*54fd6939SJiyong Park 	if (result == 0)
152*54fd6939SJiyong Park 		*dev_con = &dummy_dev_connector;
153*54fd6939SJiyong Park 
154*54fd6939SJiyong Park 	return result;
155*54fd6939SJiyong Park }
156