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