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