xref: /rk3399_ARM-atf/drivers/io/io_block.c (revision 61f72a34250d063da67f4fc2b0eb8c3fda3376be)
1 /*
2  * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <debug.h>
9 #include <errno.h>
10 #include <io_block.h>
11 #include <io_driver.h>
12 #include <io_storage.h>
13 #include <platform_def.h>
14 #include <string.h>
15 #include <utils.h>
16 
17 typedef struct {
18 	io_block_dev_spec_t	*dev_spec;
19 	uintptr_t		base;
20 	size_t			file_pos;
21 	size_t			size;
22 } block_dev_state_t;
23 
24 #define is_power_of_2(x)	((x != 0) && ((x & (x - 1)) == 0))
25 
26 io_type_t device_type_block(void);
27 
28 static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
29 		      io_entity_t *entity);
30 static int block_seek(io_entity_t *entity, int mode, ssize_t offset);
31 static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
32 		      size_t *length_read);
33 static int block_write(io_entity_t *entity, const uintptr_t buffer,
34 		       size_t length, size_t *length_written);
35 static int block_close(io_entity_t *entity);
36 static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
37 static int block_dev_close(io_dev_info_t *dev_info);
38 
39 static const io_dev_connector_t block_dev_connector = {
40 	.dev_open	= block_dev_open
41 };
42 
43 static const io_dev_funcs_t block_dev_funcs = {
44 	.type		= device_type_block,
45 	.open		= block_open,
46 	.seek		= block_seek,
47 	.size		= NULL,
48 	.read		= block_read,
49 	.write		= block_write,
50 	.close		= block_close,
51 	.dev_init	= NULL,
52 	.dev_close	= block_dev_close,
53 };
54 
55 static block_dev_state_t state_pool[MAX_IO_BLOCK_DEVICES];
56 static io_dev_info_t dev_info_pool[MAX_IO_BLOCK_DEVICES];
57 
58 /* Track number of allocated block state */
59 static unsigned int block_dev_count;
60 
61 io_type_t device_type_block(void)
62 {
63 	return IO_TYPE_BLOCK;
64 }
65 
66 /* Locate a block state in the pool, specified by address */
67 static int find_first_block_state(const io_block_dev_spec_t *dev_spec,
68 				  unsigned int *index_out)
69 {
70 	int result = -ENOENT;
71 	for (int index = 0; index < MAX_IO_BLOCK_DEVICES; ++index) {
72 		/* dev_spec is used as identifier since it's unique */
73 		if (state_pool[index].dev_spec == dev_spec) {
74 			result = 0;
75 			*index_out = index;
76 			break;
77 		}
78 	}
79 	return result;
80 }
81 
82 /* Allocate a device info from the pool and return a pointer to it */
83 static int allocate_dev_info(io_dev_info_t **dev_info)
84 {
85 	int result = -ENOMEM;
86 	assert(dev_info != NULL);
87 
88 	if (block_dev_count < MAX_IO_BLOCK_DEVICES) {
89 		unsigned int index = 0;
90 		result = find_first_block_state(NULL, &index);
91 		assert(result == 0);
92 		/* initialize dev_info */
93 		dev_info_pool[index].funcs = &block_dev_funcs;
94 		dev_info_pool[index].info = (uintptr_t)&state_pool[index];
95 		*dev_info = &dev_info_pool[index];
96 		++block_dev_count;
97 	}
98 
99 	return result;
100 }
101 
102 
103 /* Release a device info to the pool */
104 static int free_dev_info(io_dev_info_t *dev_info)
105 {
106 	int result;
107 	unsigned int index = 0;
108 	block_dev_state_t *state;
109 	assert(dev_info != NULL);
110 
111 	state = (block_dev_state_t *)dev_info->info;
112 	result = find_first_block_state(state->dev_spec, &index);
113 	if (result ==  0) {
114 		/* free if device info is valid */
115 		zeromem(state, sizeof(block_dev_state_t));
116 		zeromem(dev_info, sizeof(io_dev_info_t));
117 		--block_dev_count;
118 	}
119 
120 	return result;
121 }
122 
123 static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
124 		      io_entity_t *entity)
125 {
126 	block_dev_state_t *cur;
127 	io_block_spec_t *region;
128 
129 	assert((dev_info->info != (uintptr_t)NULL) &&
130 	       (spec != (uintptr_t)NULL) &&
131 	       (entity->info == (uintptr_t)NULL));
132 
133 	region = (io_block_spec_t *)spec;
134 	cur = (block_dev_state_t *)dev_info->info;
135 	assert(((region->offset % cur->dev_spec->block_size) == 0) &&
136 	       ((region->length % cur->dev_spec->block_size) == 0));
137 
138 	cur->base = region->offset;
139 	cur->size = region->length;
140 	cur->file_pos = 0;
141 
142 	entity->info = (uintptr_t)cur;
143 	return 0;
144 }
145 
146 /* parameter offset is relative address at here */
147 static int block_seek(io_entity_t *entity, int mode, ssize_t offset)
148 {
149 	block_dev_state_t *cur;
150 
151 	assert(entity->info != (uintptr_t)NULL);
152 
153 	cur = (block_dev_state_t *)entity->info;
154 	assert((offset >= 0) && (offset < cur->size));
155 
156 	switch (mode) {
157 	case IO_SEEK_SET:
158 		cur->file_pos = offset;
159 		break;
160 	case IO_SEEK_CUR:
161 		cur->file_pos += offset;
162 		break;
163 	default:
164 		return -EINVAL;
165 	}
166 	assert(cur->file_pos < cur->size);
167 	return 0;
168 }
169 
170 /*
171  * This function allows the caller to read any number of bytes
172  * from any position. It hides from the caller that the low level
173  * driver only can read aligned blocks of data. For this reason
174  * we need to handle the use case where the first byte to be read is not
175  * aligned to start of the block, the last byte to be read is also not
176  * aligned to the end of a block, and there are zero or more blocks-worth
177  * of data in between.
178  *
179  * In such a case we need to read more bytes than requested (i.e. full
180  * blocks) and strip-out the leading bytes (aka skip) and the trailing
181  * bytes (aka padding). See diagram below
182  *
183  * cur->file_pos ------------
184  *                          |
185  * cur->base                |
186  *  |                       |
187  *  v                       v<----  length   ---->
188  *  --------------------------------------------------------------
189  * |           |         block#1    |        |   block#n          |
190  * |  block#0  |            +       |   ...  |     +              |
191  * |           | <- skip -> +       |        |     + <- padding ->|
192  *  ------------------------+----------------------+--------------
193  *             ^                                                  ^
194  *             |                                                  |
195  *             v    iteration#1                iteration#n        v
196  *              --------------------------------------------------
197  *             |                    |        |                    |
198  *             |<----  request ---->|  ...   |<----- request ---->|
199  *             |                    |        |                    |
200  *              --------------------------------------------------
201  *            /                   /          |                    |
202  *           /                   /           |                    |
203  *          /                   /            |                    |
204  *         /                   /             |                    |
205  *        /                   /              |                    |
206  *       /                   /               |                    |
207  *      /                   /                |                    |
208  *     /                   /                 |                    |
209  *    /                   /                  |                    |
210  *   /                   /                   |                    |
211  *  <---- request ------>                    <------ request  ----->
212  *  ---------------------                    -----------------------
213  *  |        |          |                    |          |           |
214  *  |<-skip->|<-nbytes->|           -------->|<-nbytes->|<-padding->|
215  *  |        |          |           |        |          |           |
216  *  ---------------------           |        -----------------------
217  *  ^        \           \          |        |          |
218  *  |         \           \         |        |          |
219  *  |          \           \        |        |          |
220  *  buf->offset \           \   buf->offset  |          |
221  *               \           \               |          |
222  *                \           \              |          |
223  *                 \           \             |          |
224  *                  \           \            |          |
225  *                   \           \           |          |
226  *                    \           \          |          |
227  *                     \           \         |          |
228  *                      --------------------------------
229  *                      |           |        |         |
230  * buffer-------------->|           | ...    |         |
231  *                      |           |        |         |
232  *                      --------------------------------
233  *                      <-count#1->|                   |
234  *                      <----------  count#n   -------->
235  *                      <----------  length  ---------->
236  *
237  * Additionally, the IO driver has an underlying buffer that is at least
238  * one block-size and may be big enough to allow.
239  */
240 static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
241 		      size_t *length_read)
242 {
243 	block_dev_state_t *cur;
244 	io_block_spec_t *buf;
245 	io_block_ops_t *ops;
246 	int lba;
247 	size_t block_size, left;
248 	size_t nbytes;  /* number of bytes read in one iteration */
249 	size_t request; /* number of requested bytes in one iteration */
250 	size_t count;   /* number of bytes already read */
251 	/*
252 	 * number of leading bytes from start of the block
253 	 * to the first byte to be read
254 	 */
255 	size_t skip;
256 
257 	/*
258 	 * number of trailing bytes between the last byte
259 	 * to be read and the end of the block
260 	 */
261 	size_t padding;
262 
263 	assert(entity->info != (uintptr_t)NULL);
264 	cur = (block_dev_state_t *)entity->info;
265 	ops = &(cur->dev_spec->ops);
266 	buf = &(cur->dev_spec->buffer);
267 	block_size = cur->dev_spec->block_size;
268 	assert((length <= cur->size) &&
269 	       (length > 0) &&
270 	       (ops->read != 0));
271 
272 	/*
273 	 * We don't know the number of bytes that we are going
274 	 * to read in every iteration, because it will depend
275 	 * on the low level driver.
276 	 */
277 	count = 0;
278 	for (left = length; left > 0; left -= nbytes) {
279 		/*
280 		 * We must only request operations aligned to the block
281 		 * size. Therefore if file_pos is not block-aligned,
282 		 * we have to request the operation to start at the
283 		 * previous block boundary and skip the leading bytes. And
284 		 * similarly, the number of bytes requested must be a
285 		 * block size multiple
286 		 */
287 		skip = cur->file_pos & (block_size - 1);
288 
289 		/*
290 		 * Calculate the block number containing file_pos
291 		 * - e.g. block 3.
292 		 */
293 		lba = (cur->file_pos + cur->base) / block_size;
294 
295 		if (skip + left > buf->length) {
296 			/*
297 			 * The underlying read buffer is too small to
298 			 * read all the required data - limit to just
299 			 * fill the buffer, and then read again.
300 			 */
301 			request = buf->length;
302 		} else {
303 			/*
304 			 * The underlying read buffer is big enough to
305 			 * read all the required data. Calculate the
306 			 * number of bytes to read to align with the
307 			 * block size.
308 			 */
309 			request = skip + left;
310 			request = (request + (block_size - 1)) & ~(block_size - 1);
311 		}
312 		request = ops->read(lba, buf->offset, request);
313 
314 		if (request <= skip) {
315 			/*
316 			 * We couldn't read enough bytes to jump over
317 			 * the skip bytes, so we should have to read
318 			 * again the same block, thus generating
319 			 * the same error.
320 			 */
321 			return -EIO;
322 		}
323 
324 		/*
325 		 * Need to remove skip and padding bytes,if any, from
326 		 * the read data when copying to the user buffer.
327 		 */
328 		nbytes = request - skip;
329 		padding = (nbytes > left) ? nbytes - left : 0;
330 		nbytes -= padding;
331 
332 		memcpy((void *)(buffer + count),
333 		       (void *)(buf->offset + skip),
334 		       nbytes);
335 
336 		cur->file_pos += nbytes;
337 		count += nbytes;
338 	}
339 	assert(count == length);
340 	*length_read = count;
341 
342 	return 0;
343 }
344 
345 /*
346  * This function allows the caller to write any number of bytes
347  * from any position. It hides from the caller that the low level
348  * driver only can write aligned blocks of data.
349  * See comments for block_read for more details.
350  */
351 static int block_write(io_entity_t *entity, const uintptr_t buffer,
352 		       size_t length, size_t *length_written)
353 {
354 	block_dev_state_t *cur;
355 	io_block_spec_t *buf;
356 	io_block_ops_t *ops;
357 	int lba;
358 	size_t block_size, left;
359 	size_t nbytes;  /* number of bytes read in one iteration */
360 	size_t request; /* number of requested bytes in one iteration */
361 	size_t count;   /* number of bytes already read */
362 	/*
363 	 * number of leading bytes from start of the block
364 	 * to the first byte to be read
365 	 */
366 	size_t skip;
367 
368 	/*
369 	 * number of trailing bytes between the last byte
370 	 * to be read and the end of the block
371 	 */
372 	size_t padding;
373 
374 	assert(entity->info != (uintptr_t)NULL);
375 	cur = (block_dev_state_t *)entity->info;
376 	ops = &(cur->dev_spec->ops);
377 	buf = &(cur->dev_spec->buffer);
378 	block_size = cur->dev_spec->block_size;
379 	assert((length <= cur->size) &&
380 	       (length > 0) &&
381 	       (ops->read != 0) &&
382 	       (ops->write != 0));
383 
384 	/*
385 	 * We don't know the number of bytes that we are going
386 	 * to write in every iteration, because it will depend
387 	 * on the low level driver.
388 	 */
389 	count = 0;
390 	for (left = length; left > 0; left -= nbytes) {
391 		/*
392 		 * We must only request operations aligned to the block
393 		 * size. Therefore if file_pos is not block-aligned,
394 		 * we have to request the operation to start at the
395 		 * previous block boundary and skip the leading bytes. And
396 		 * similarly, the number of bytes requested must be a
397 		 * block size multiple
398 		 */
399 		skip = cur->file_pos & (block_size - 1);
400 
401 		/*
402 		 * Calculate the block number containing file_pos
403 		 * - e.g. block 3.
404 		 */
405 		lba = (cur->file_pos + cur->base) / block_size;
406 
407 		if (skip + left > buf->length) {
408 			/*
409 			 * The underlying read buffer is too small to
410 			 * read all the required data - limit to just
411 			 * fill the buffer, and then read again.
412 			 */
413 			request = buf->length;
414 		} else {
415 			/*
416 			 * The underlying read buffer is big enough to
417 			 * read all the required data. Calculate the
418 			 * number of bytes to read to align with the
419 			 * block size.
420 			 */
421 			request = skip + left;
422 			request = (request + (block_size - 1)) & ~(block_size - 1);
423 		}
424 
425 		/*
426 		 * The number of bytes that we are going to write
427 		 * from the user buffer will depend of the size
428 		 * of the current request.
429 		 */
430 		nbytes = request - skip;
431 		padding = (nbytes > left) ? nbytes - left : 0;
432 		nbytes -= padding;
433 
434 		/*
435 		 * If we have skip or padding bytes then we have to preserve
436 		 * some content and it means that we have to read before
437 		 * writing
438 		 */
439 		if (skip > 0 || padding > 0) {
440 			request = ops->read(lba, buf->offset, request);
441 			/*
442 			 * The read may return size less than
443 			 * requested. Round down to the nearest block
444 			 * boundary
445 			 */
446 			request &= ~(block_size-1);
447 			if (request <= skip) {
448 				/*
449 				 * We couldn't read enough bytes to jump over
450 				 * the skip bytes, so we should have to read
451 				 * again the same block, thus generating
452 				 * the same error.
453 				 */
454 				return -EIO;
455 			}
456 			nbytes = request - skip;
457 			padding = (nbytes > left) ? nbytes - left : 0;
458 			nbytes -= padding;
459 		}
460 
461 		memcpy((void *)(buf->offset + skip),
462 		       (void *)(buffer + count),
463 		       nbytes);
464 
465 		request = ops->write(lba, buf->offset, request);
466 		if (request <= skip)
467 			return -EIO;
468 
469 		/*
470 		 * And the previous write operation may modify the size
471 		 * of the request, so again, we have to calculate the
472 		 * number of bytes that we consumed from the user
473 		 * buffer
474 		 */
475 		nbytes = request - skip;
476 		padding = (nbytes > left) ? nbytes - left : 0;
477 		nbytes -= padding;
478 
479 		cur->file_pos += nbytes;
480 		count += nbytes;
481 	}
482 	assert(count == length);
483 	*length_written = count;
484 
485 	return 0;
486 }
487 
488 static int block_close(io_entity_t *entity)
489 {
490 	entity->info = (uintptr_t)NULL;
491 	return 0;
492 }
493 
494 static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info)
495 {
496 	block_dev_state_t *cur;
497 	io_block_spec_t *buffer;
498 	io_dev_info_t *info;
499 	size_t block_size;
500 	int result;
501 
502 	assert(dev_info != NULL);
503 	result = allocate_dev_info(&info);
504 	if (result)
505 		return -ENOENT;
506 
507 	cur = (block_dev_state_t *)info->info;
508 	/* dev_spec is type of io_block_dev_spec_t. */
509 	cur->dev_spec = (io_block_dev_spec_t *)dev_spec;
510 	buffer = &(cur->dev_spec->buffer);
511 	block_size = cur->dev_spec->block_size;
512 	assert((block_size > 0) &&
513 	       (is_power_of_2(block_size) != 0) &&
514 	       ((buffer->offset % block_size) == 0) &&
515 	       ((buffer->length % block_size) == 0));
516 
517 	*dev_info = info;	/* cast away const */
518 	(void)block_size;
519 	(void)buffer;
520 	return 0;
521 }
522 
523 static int block_dev_close(io_dev_info_t *dev_info)
524 {
525 	return free_dev_info(dev_info);
526 }
527 
528 /* Exported functions */
529 
530 /* Register the Block driver with the IO abstraction */
531 int register_io_dev_block(const io_dev_connector_t **dev_con)
532 {
533 	int result;
534 
535 	assert(dev_con != NULL);
536 
537 	/*
538 	 * Since dev_info isn't really used in io_register_device, always
539 	 * use the same device info at here instead.
540 	 */
541 	result = io_register_device(&dev_info_pool[0]);
542 	if (result == 0)
543 		*dev_con = &block_dev_connector;
544 	return result;
545 }
546