1 /* Copyright (C) 2007-2008 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 #include "qemu_file.h" 13 #include "goldfish_nand_reg.h" 14 #include "goldfish_nand.h" 15 #include "goldfish_vmem.h" 16 #include "android/utils/tempfile.h" 17 #include "qemu_debug.h" 18 #include "android/android.h" 19 20 #define DEBUG 1 21 #if DEBUG 22 # define D(...) VERBOSE_PRINT(init,__VA_ARGS__) 23 # define D_ACTIVE VERBOSE_CHECK(init) 24 # define T(...) VERBOSE_PRINT(nand_limits,__VA_ARGS__) 25 # define T_ACTIVE VERBOSE_CHECK(nand_limits) 26 #else 27 # define D(...) ((void)0) 28 # define D_ACTIVE 0 29 # define T(...) ((void)0) 30 # define T_ACTIVE 0 31 #endif 32 33 /* lseek uses 64-bit offsets on Darwin. */ 34 /* prefer lseek64 on Linux */ 35 #ifdef __APPLE__ 36 # define llseek lseek 37 #elif defined(__linux__) 38 # define llseek lseek64 39 #endif 40 41 #define XLOG xlog 42 43 static void 44 xlog( const char* format, ... ) 45 { 46 va_list args; 47 va_start(args, format); 48 fprintf(stderr, "NAND: "); 49 vfprintf(stderr, format, args); 50 va_end(args); 51 } 52 53 /* Information on a single device/nand image used by the emulator 54 */ 55 typedef struct { 56 char* devname; /* name for this device (not null-terminated, use len below) */ 57 size_t devname_len; 58 uint8_t* data; /* buffer for read/write actions to underlying image */ 59 int fd; 60 uint32_t flags; 61 uint32_t page_size; 62 uint32_t extra_size; 63 uint32_t erase_size; /* size of the data buffer mentioned above */ 64 uint64_t max_size; /* Capacity limit for the image. The actual underlying 65 * file may be smaller. */ 66 } nand_dev; 67 68 nand_threshold android_nand_write_threshold; 69 nand_threshold android_nand_read_threshold; 70 71 #ifdef CONFIG_NAND_THRESHOLD 72 73 /* update a threshold, return 1 if limit is hit, 0 otherwise */ 74 static void 75 nand_threshold_update( nand_threshold* t, uint32_t len ) 76 { 77 if (t->counter < t->limit) { 78 uint64_t avail = t->limit - t->counter; 79 if (avail > len) 80 avail = len; 81 82 if (t->counter == 0) { 83 T("%s: starting threshold counting to %lld", 84 __FUNCTION__, t->limit); 85 } 86 t->counter += avail; 87 if (t->counter >= t->limit) { 88 /* threshold reach, send a signal to an external process */ 89 T( "%s: sending signal %d to pid %d !", 90 __FUNCTION__, t->signal, t->pid ); 91 92 kill( t->pid, t->signal ); 93 } 94 } 95 return; 96 } 97 98 #define NAND_UPDATE_READ_THRESHOLD(len) \ 99 nand_threshold_update( &android_nand_read_threshold, (uint32_t)(len) ) 100 101 #define NAND_UPDATE_WRITE_THRESHOLD(len) \ 102 nand_threshold_update( &android_nand_write_threshold, (uint32_t)(len) ) 103 104 #else /* !NAND_THRESHOLD */ 105 106 #define NAND_UPDATE_READ_THRESHOLD(len) \ 107 do {} while (0) 108 109 #define NAND_UPDATE_WRITE_THRESHOLD(len) \ 110 do {} while (0) 111 112 #endif /* !NAND_THRESHOLD */ 113 114 static nand_dev *nand_devs = NULL; 115 static uint32_t nand_dev_count = 0; 116 117 /* The controller is the single access point for all NAND images currently 118 * attached to the system. 119 */ 120 typedef struct { 121 uint32_t base; 122 123 // register state 124 uint32_t dev; /* offset in nand_devs for the device that is 125 * currently being accessed */ 126 uint32_t addr_low; 127 uint32_t addr_high; 128 uint32_t transfer_size; 129 uint32_t data; 130 uint32_t batch_addr_low; 131 uint32_t batch_addr_high; 132 uint32_t result; 133 } nand_dev_controller_state; 134 135 /* update this everytime you change the nand_dev_controller_state structure 136 * 1: initial version, saving only nand_dev_controller_state fields 137 * 2: saving actual disk contents as well 138 * 3: use the correct data length and truncate to avoid padding. 139 */ 140 #define NAND_DEV_STATE_SAVE_VERSION 4 141 142 #define QFIELD_STRUCT nand_dev_controller_state 143 QFIELD_BEGIN(nand_dev_controller_state_fields) 144 QFIELD_INT32(dev), 145 QFIELD_INT32(addr_low), 146 QFIELD_INT32(addr_high), 147 QFIELD_INT32(transfer_size), 148 QFIELD_INT32(data), 149 QFIELD_INT32(batch_addr_low), 150 QFIELD_INT32(batch_addr_high), 151 QFIELD_INT32(result), 152 QFIELD_END 153 154 155 /* EINTR-proof read - due to SIGALRM in use elsewhere */ 156 static int do_read(int fd, void* buf, size_t size) 157 { 158 int ret; 159 do { 160 ret = read(fd, buf, size); 161 } while (ret < 0 && errno == EINTR); 162 163 return ret; 164 } 165 166 /* EINTR-proof write - due to SIGALRM in use elsewhere */ 167 static int do_write(int fd, const void* buf, size_t size) 168 { 169 int ret; 170 do { 171 ret = write(fd, buf, size); 172 } while (ret < 0 && errno == EINTR); 173 174 return ret; 175 } 176 177 /* EINTR-proof lseek - due to SIGALRM in use elsewhere */ 178 static int do_lseek(int fd, off_t offset, int whence) 179 { 180 int ret; 181 do { 182 ret = lseek(fd, offset, whence); 183 } while (ret < 0 && errno == EINTR); 184 185 return ret; 186 } 187 188 /* EINTR-proof ftruncate - due to SIGALRM in use elsewhere */ 189 static int do_ftruncate(int fd, size_t size) 190 { 191 int ret; 192 do { 193 ret = ftruncate(fd, size); 194 } while (ret < 0 && errno == EINTR); 195 196 return ret; 197 } 198 199 #define NAND_DEV_SAVE_DISK_BUF_SIZE 2048 200 201 202 /** 203 * Copies the current contents of a disk image into the snapshot file. 204 * 205 * TODO optimize this using some kind of copy-on-write mechanism for 206 * unchanged disk sections. 207 */ 208 static void nand_dev_save_disk_state(QEMUFile *f, nand_dev *dev) 209 { 210 int buf_size = NAND_DEV_SAVE_DISK_BUF_SIZE; 211 uint8_t buffer[NAND_DEV_SAVE_DISK_BUF_SIZE] = {0}; 212 int ret; 213 uint64_t total_copied = 0; 214 215 /* Size of file to restore, hence size of data block following. 216 * TODO Work out whether to use lseek64 here. */ 217 218 ret = do_lseek(dev->fd, 0, SEEK_END); 219 if (ret < 0) { 220 XLOG("%s EOF seek failed: %s\n", __FUNCTION__, strerror(errno)); 221 qemu_file_set_error(f); 222 return; 223 } 224 const uint64_t total_size = ret; 225 qemu_put_be64(f, total_size); 226 227 /* copy all data from the stream to the stored image */ 228 ret = do_lseek(dev->fd, 0, SEEK_SET); 229 if (ret < 0) { 230 XLOG("%s seek failed: %s\n", __FUNCTION__, strerror(errno)); 231 qemu_file_set_error(f); 232 return; 233 } 234 do { 235 ret = do_read(dev->fd, buffer, buf_size); 236 if (ret < 0) { 237 XLOG("%s read failed: %s\n", __FUNCTION__, strerror(errno)); 238 qemu_file_set_error(f); 239 return; 240 } 241 qemu_put_buffer(f, buffer, ret); 242 243 total_copied += ret; 244 } 245 while (ret == buf_size && total_copied < dev->max_size); 246 247 /* TODO Maybe check that we've written total_size bytes */ 248 } 249 250 251 /** 252 * Saves the state of all disks managed by this controller to a snapshot file. 253 */ 254 static void nand_dev_save_disks(QEMUFile *f) 255 { 256 int i; 257 for (i = 0; i < nand_dev_count; i++) { 258 nand_dev_save_disk_state(f, nand_devs + i); 259 } 260 } 261 262 /** 263 * Overwrites the contents of the disk image managed by this device with the 264 * contents as they were at the point the snapshot was made. 265 */ 266 static int nand_dev_load_disk_state(QEMUFile *f, nand_dev *dev) 267 { 268 int buf_size = NAND_DEV_SAVE_DISK_BUF_SIZE; 269 uint8_t buffer[NAND_DEV_SAVE_DISK_BUF_SIZE] = {0}; 270 int ret; 271 272 /* File size for restore and truncate */ 273 uint64_t total_size = qemu_get_be64(f); 274 if (total_size > dev->max_size) { 275 XLOG("%s, restore failed: size required (%lld) exceeds device limit (%lld)\n", 276 __FUNCTION__, total_size, dev->max_size); 277 return -EIO; 278 } 279 280 /* overwrite disk contents with snapshot contents */ 281 uint64_t next_offset = 0; 282 ret = do_lseek(dev->fd, 0, SEEK_SET); 283 if (ret < 0) { 284 XLOG("%s seek failed: %s\n", __FUNCTION__, strerror(errno)); 285 return -EIO; 286 } 287 while (next_offset < total_size) { 288 /* snapshot buffer may not be an exact multiple of buf_size 289 * if necessary, adjust buffer size for last copy operation */ 290 if (total_size - next_offset < buf_size) { 291 buf_size = total_size - next_offset; 292 } 293 294 ret = qemu_get_buffer(f, buffer, buf_size); 295 if (ret != buf_size) { 296 XLOG("%s read failed: expected %d bytes but got %d\n", 297 __FUNCTION__, buf_size, ret); 298 return -EIO; 299 } 300 ret = do_write(dev->fd, buffer, buf_size); 301 if (ret != buf_size) { 302 XLOG("%s, write failed: %s\n", __FUNCTION__, strerror(errno)); 303 return -EIO; 304 } 305 306 next_offset += buf_size; 307 } 308 309 ret = do_ftruncate(dev->fd, total_size); 310 if (ret < 0) { 311 XLOG("%s ftruncate failed: %s\n", __FUNCTION__, strerror(errno)); 312 return -EIO; 313 } 314 315 return 0; 316 } 317 318 /** 319 * Restores the state of all disks managed by this driver from a snapshot file. 320 */ 321 static int nand_dev_load_disks(QEMUFile *f) 322 { 323 int i, ret; 324 for (i = 0; i < nand_dev_count; i++) { 325 ret = nand_dev_load_disk_state(f, nand_devs + i); 326 if (ret) 327 return ret; // abort on error 328 } 329 330 return 0; 331 } 332 333 static void nand_dev_controller_state_save(QEMUFile *f, void *opaque) 334 { 335 nand_dev_controller_state* s = opaque; 336 337 qemu_put_struct(f, nand_dev_controller_state_fields, s); 338 339 /* The guest will continue writing to the disk image after the state has 340 * been saved. To guarantee that the state is identical after resume, save 341 * a copy of the current disk state in the snapshot. 342 */ 343 nand_dev_save_disks(f); 344 } 345 346 static int nand_dev_controller_state_load(QEMUFile *f, void *opaque, int version_id) 347 { 348 nand_dev_controller_state* s = opaque; 349 int ret; 350 351 if (version_id != NAND_DEV_STATE_SAVE_VERSION) 352 return -1; 353 354 if ((ret = qemu_get_struct(f, nand_dev_controller_state_fields, s))) 355 return ret; 356 if ((ret = nand_dev_load_disks(f))) 357 return ret; 358 359 return 0; 360 } 361 362 static uint32_t nand_dev_read_file(nand_dev *dev, uint32_t data, uint64_t addr, uint32_t total_len) 363 { 364 uint32_t len = total_len; 365 size_t read_len = dev->erase_size; 366 int eof = 0; 367 368 NAND_UPDATE_READ_THRESHOLD(total_len); 369 370 do_lseek(dev->fd, addr, SEEK_SET); 371 while(len > 0) { 372 if(read_len < dev->erase_size) { 373 memset(dev->data, 0xff, dev->erase_size); 374 read_len = dev->erase_size; 375 eof = 1; 376 } 377 if(len < read_len) 378 read_len = len; 379 if(!eof) { 380 read_len = do_read(dev->fd, dev->data, read_len); 381 } 382 safe_memory_rw_debug(cpu_single_env, data, dev->data, read_len, 1); 383 data += read_len; 384 len -= read_len; 385 } 386 return total_len; 387 } 388 389 static uint32_t nand_dev_write_file(nand_dev *dev, uint32_t data, uint64_t addr, uint32_t total_len) 390 { 391 uint32_t len = total_len; 392 size_t write_len = dev->erase_size; 393 int ret; 394 395 NAND_UPDATE_WRITE_THRESHOLD(total_len); 396 397 do_lseek(dev->fd, addr, SEEK_SET); 398 while(len > 0) { 399 if(len < write_len) 400 write_len = len; 401 safe_memory_rw_debug(cpu_single_env, data, dev->data, write_len, 0); 402 ret = do_write(dev->fd, dev->data, write_len); 403 if(ret < write_len) { 404 XLOG("nand_dev_write_file, write failed: %s\n", strerror(errno)); 405 break; 406 } 407 data += write_len; 408 len -= write_len; 409 } 410 return total_len - len; 411 } 412 413 static uint32_t nand_dev_erase_file(nand_dev *dev, uint64_t addr, uint32_t total_len) 414 { 415 uint32_t len = total_len; 416 size_t write_len = dev->erase_size; 417 int ret; 418 419 do_lseek(dev->fd, addr, SEEK_SET); 420 memset(dev->data, 0xff, dev->erase_size); 421 while(len > 0) { 422 if(len < write_len) 423 write_len = len; 424 ret = do_write(dev->fd, dev->data, write_len); 425 if(ret < write_len) { 426 XLOG( "nand_dev_write_file, write failed: %s\n", strerror(errno)); 427 break; 428 } 429 len -= write_len; 430 } 431 return total_len - len; 432 } 433 434 /* this is a huge hack required to make the PowerPC emulator binary usable 435 * on Mac OS X. If you define this function as 'static', the emulated kernel 436 * will panic when attempting to mount the /data partition. 437 * 438 * worse, if you do *not* define the function as static on Linux-x86, the 439 * emulated kernel will also panic !? 440 * 441 * I still wonder if this is a compiler bug, or due to some nasty thing the 442 * emulator does with CPU registers during execution of the translated code. 443 */ 444 #if !(defined __APPLE__ && defined __powerpc__) 445 static 446 #endif 447 uint32_t nand_dev_do_cmd(nand_dev_controller_state *s, uint32_t cmd) 448 { 449 uint32_t size; 450 uint64_t addr; 451 nand_dev *dev; 452 453 if (cmd == NAND_CMD_WRITE_BATCH || cmd == NAND_CMD_READ_BATCH || 454 cmd == NAND_CMD_ERASE_BATCH) { 455 struct batch_data bd; 456 uint64_t bd_addr = ((uint64_t)s->batch_addr_high << 32) | s->batch_addr_low; 457 458 cpu_physical_memory_read(bd_addr, (void*)&bd, sizeof(struct batch_data)); 459 s->dev = bd.dev; 460 s->addr_low = bd.addr_low; 461 s->addr_high = bd.addr_high; 462 s->transfer_size = bd.transfer_size; 463 s->data = bd.data; 464 } 465 addr = s->addr_low | ((uint64_t)s->addr_high << 32); 466 size = s->transfer_size; 467 if(s->dev >= nand_dev_count) 468 return 0; 469 dev = nand_devs + s->dev; 470 471 switch(cmd) { 472 case NAND_CMD_GET_DEV_NAME: 473 if(size > dev->devname_len) 474 size = dev->devname_len; 475 safe_memory_rw_debug(cpu_single_env, s->data, (uint8_t*)dev->devname, size, 1); 476 return size; 477 case NAND_CMD_READ_BATCH: 478 case NAND_CMD_READ: 479 if(addr >= dev->max_size) 480 return 0; 481 if(size > dev->max_size - addr) 482 size = dev->max_size - addr; 483 if(dev->fd >= 0) 484 return nand_dev_read_file(dev, s->data, addr, size); 485 safe_memory_rw_debug(cpu_single_env,s->data, &dev->data[addr], size, 1); 486 return size; 487 case NAND_CMD_WRITE_BATCH: 488 case NAND_CMD_WRITE: 489 if(dev->flags & NAND_DEV_FLAG_READ_ONLY) 490 return 0; 491 if(addr >= dev->max_size) 492 return 0; 493 if(size > dev->max_size - addr) 494 size = dev->max_size - addr; 495 if(dev->fd >= 0) 496 return nand_dev_write_file(dev, s->data, addr, size); 497 safe_memory_rw_debug(cpu_single_env,s->data, &dev->data[addr], size, 0); 498 return size; 499 case NAND_CMD_ERASE_BATCH: 500 case NAND_CMD_ERASE: 501 if(dev->flags & NAND_DEV_FLAG_READ_ONLY) 502 return 0; 503 if(addr >= dev->max_size) 504 return 0; 505 if(size > dev->max_size - addr) 506 size = dev->max_size - addr; 507 if(dev->fd >= 0) 508 return nand_dev_erase_file(dev, addr, size); 509 memset(&dev->data[addr], 0xff, size); 510 return size; 511 case NAND_CMD_BLOCK_BAD_GET: // no bad block support 512 return 0; 513 case NAND_CMD_BLOCK_BAD_SET: 514 if(dev->flags & NAND_DEV_FLAG_READ_ONLY) 515 return 0; 516 return 0; 517 default: 518 cpu_abort(cpu_single_env, "nand_dev_do_cmd: Bad command %x\n", cmd); 519 return 0; 520 } 521 } 522 523 /* I/O write */ 524 static void nand_dev_write(void *opaque, target_phys_addr_t offset, uint32_t value) 525 { 526 nand_dev_controller_state *s = (nand_dev_controller_state *)opaque; 527 528 switch (offset) { 529 case NAND_DEV: 530 s->dev = value; 531 if(s->dev >= nand_dev_count) { 532 cpu_abort(cpu_single_env, "nand_dev_write: Bad dev %x\n", value); 533 } 534 break; 535 case NAND_ADDR_HIGH: 536 s->addr_high = value; 537 break; 538 case NAND_ADDR_LOW: 539 s->addr_low = value; 540 break; 541 case NAND_BATCH_ADDR_LOW: 542 s->batch_addr_low = value; 543 break; 544 case NAND_BATCH_ADDR_HIGH: 545 s->batch_addr_high = value; 546 break; 547 case NAND_TRANSFER_SIZE: 548 s->transfer_size = value; 549 break; 550 case NAND_DATA: 551 s->data = value; 552 break; 553 case NAND_COMMAND: 554 s->result = nand_dev_do_cmd(s, value); 555 if (value == NAND_CMD_WRITE_BATCH || value == NAND_CMD_READ_BATCH || 556 value == NAND_CMD_ERASE_BATCH) { 557 struct batch_data bd; 558 uint64_t bd_addr = ((uint64_t)s->batch_addr_high << 32) | s->batch_addr_low; 559 bd.result = s->result; 560 cpu_physical_memory_write(bd_addr, (void*)&bd, sizeof(struct batch_data)); 561 } 562 break; 563 default: 564 cpu_abort(cpu_single_env, "nand_dev_write: Bad offset %x\n", offset); 565 break; 566 } 567 } 568 569 /* I/O read */ 570 static uint32_t nand_dev_read(void *opaque, target_phys_addr_t offset) 571 { 572 nand_dev_controller_state *s = (nand_dev_controller_state *)opaque; 573 nand_dev *dev; 574 575 switch (offset) { 576 case NAND_VERSION: 577 return NAND_VERSION_CURRENT; 578 case NAND_NUM_DEV: 579 return nand_dev_count; 580 case NAND_RESULT: 581 return s->result; 582 } 583 584 if(s->dev >= nand_dev_count) 585 return 0; 586 587 dev = nand_devs + s->dev; 588 589 switch (offset) { 590 case NAND_DEV_FLAGS: 591 return dev->flags; 592 593 case NAND_DEV_NAME_LEN: 594 return dev->devname_len; 595 596 case NAND_DEV_PAGE_SIZE: 597 return dev->page_size; 598 599 case NAND_DEV_EXTRA_SIZE: 600 return dev->extra_size; 601 602 case NAND_DEV_ERASE_SIZE: 603 return dev->erase_size; 604 605 case NAND_DEV_SIZE_LOW: 606 return (uint32_t)dev->max_size; 607 608 case NAND_DEV_SIZE_HIGH: 609 return (uint32_t)(dev->max_size >> 32); 610 611 default: 612 cpu_abort(cpu_single_env, "nand_dev_read: Bad offset %x\n", offset); 613 return 0; 614 } 615 } 616 617 static CPUReadMemoryFunc *nand_dev_readfn[] = { 618 nand_dev_read, 619 nand_dev_read, 620 nand_dev_read 621 }; 622 623 static CPUWriteMemoryFunc *nand_dev_writefn[] = { 624 nand_dev_write, 625 nand_dev_write, 626 nand_dev_write 627 }; 628 629 /* initialize the QFB device */ 630 void nand_dev_init(uint32_t base) 631 { 632 int iomemtype; 633 static int instance_id = 0; 634 nand_dev_controller_state *s; 635 636 s = (nand_dev_controller_state *)qemu_mallocz(sizeof(nand_dev_controller_state)); 637 iomemtype = cpu_register_io_memory(nand_dev_readfn, nand_dev_writefn, s); 638 cpu_register_physical_memory(base, 0x00000fff, iomemtype); 639 s->base = base; 640 641 register_savevm( "nand_dev", instance_id++, NAND_DEV_STATE_SAVE_VERSION, 642 nand_dev_controller_state_save, nand_dev_controller_state_load, s); 643 } 644 645 static int arg_match(const char *a, const char *b, size_t b_len) 646 { 647 while(*a && b_len--) { 648 if(*a++ != *b++) 649 return 0; 650 } 651 return b_len == 0; 652 } 653 654 void nand_add_dev(const char *arg) 655 { 656 uint64_t dev_size = 0; 657 const char *next_arg; 658 const char *value; 659 size_t arg_len, value_len; 660 nand_dev *new_devs, *dev; 661 char *devname = NULL; 662 size_t devname_len = 0; 663 char *initfilename = NULL; 664 char *rwfilename = NULL; 665 int initfd = -1; 666 int rwfd = -1; 667 int read_only = 0; 668 int pad; 669 ssize_t read_size; 670 uint32_t page_size = 512; 671 uint32_t extra_size = 0; 672 uint32_t erase_pages = 64; 673 674 VERBOSE_PRINT(init, "%s: %s", __FUNCTION__, arg); 675 676 while(arg) { 677 next_arg = strchr(arg, ','); 678 value = strchr(arg, '='); 679 if(next_arg != NULL) { 680 arg_len = next_arg - arg; 681 next_arg++; 682 if(value >= next_arg) 683 value = NULL; 684 } 685 else 686 arg_len = strlen(arg); 687 if(value != NULL) { 688 size_t new_arg_len = value - arg; 689 value_len = arg_len - new_arg_len - 1; 690 arg_len = new_arg_len; 691 value++; 692 } 693 else 694 value_len = 0; 695 696 if(devname == NULL) { 697 if(value != NULL) 698 goto bad_arg_and_value; 699 devname_len = arg_len; 700 devname = malloc(arg_len+1); 701 if(devname == NULL) 702 goto out_of_memory; 703 memcpy(devname, arg, arg_len); 704 devname[arg_len] = 0; 705 } 706 else if(value == NULL) { 707 if(arg_match("readonly", arg, arg_len)) { 708 read_only = 1; 709 } 710 else { 711 XLOG("bad arg: %.*s\n", arg_len, arg); 712 exit(1); 713 } 714 } 715 else { 716 if(arg_match("size", arg, arg_len)) { 717 char *ep; 718 dev_size = strtoull(value, &ep, 0); 719 if(ep != value + value_len) 720 goto bad_arg_and_value; 721 } 722 else if(arg_match("pagesize", arg, arg_len)) { 723 char *ep; 724 page_size = strtoul(value, &ep, 0); 725 if(ep != value + value_len) 726 goto bad_arg_and_value; 727 } 728 else if(arg_match("extrasize", arg, arg_len)) { 729 char *ep; 730 extra_size = strtoul(value, &ep, 0); 731 if(ep != value + value_len) 732 goto bad_arg_and_value; 733 } 734 else if(arg_match("erasepages", arg, arg_len)) { 735 char *ep; 736 erase_pages = strtoul(value, &ep, 0); 737 if(ep != value + value_len) 738 goto bad_arg_and_value; 739 } 740 else if(arg_match("initfile", arg, arg_len)) { 741 initfilename = malloc(value_len + 1); 742 if(initfilename == NULL) 743 goto out_of_memory; 744 memcpy(initfilename, value, value_len); 745 initfilename[value_len] = '\0'; 746 } 747 else if(arg_match("file", arg, arg_len)) { 748 rwfilename = malloc(value_len + 1); 749 if(rwfilename == NULL) 750 goto out_of_memory; 751 memcpy(rwfilename, value, value_len); 752 rwfilename[value_len] = '\0'; 753 } 754 else { 755 goto bad_arg_and_value; 756 } 757 } 758 759 arg = next_arg; 760 } 761 762 if (rwfilename == NULL) { 763 /* we create a temporary file to store everything */ 764 TempFile* tmp = tempfile_create(); 765 766 if (tmp == NULL) { 767 XLOG("could not create temp file for %.*s NAND disk image: %s\n", 768 devname_len, devname, strerror(errno)); 769 exit(1); 770 } 771 rwfilename = (char*) tempfile_path(tmp); 772 if (VERBOSE_CHECK(init)) 773 dprint( "mapping '%.*s' NAND image to %s", devname_len, devname, rwfilename); 774 } 775 776 if(rwfilename) { 777 if (initfilename) { 778 /* Overwrite with content of the 'initfilename'. */ 779 if (read_only) { 780 /* Cannot be readonly when initializing the device from another file. */ 781 XLOG("incompatible read only option is requested while initializing %.*s from %s\n", 782 devname_len, devname, initfilename); 783 exit(1); 784 } 785 rwfd = open(rwfilename, O_BINARY | O_TRUNC | O_RDWR); 786 } else { 787 rwfd = open(rwfilename, O_BINARY | (read_only ? O_RDONLY : O_RDWR)); 788 } 789 if(rwfd < 0) { 790 XLOG("could not open file %s, %s\n", rwfilename, strerror(errno)); 791 exit(1); 792 } 793 /* this could be a writable temporary file. use atexit_close_fd to ensure 794 * that it is properly cleaned up at exit on Win32 795 */ 796 if (!read_only) 797 atexit_close_fd(rwfd); 798 } 799 800 if(initfilename) { 801 initfd = open(initfilename, O_BINARY | O_RDONLY); 802 if(initfd < 0) { 803 XLOG("could not open file %s, %s\n", initfilename, strerror(errno)); 804 exit(1); 805 } 806 if(dev_size == 0) { 807 dev_size = do_lseek(initfd, 0, SEEK_END); 808 do_lseek(initfd, 0, SEEK_SET); 809 } 810 } 811 812 new_devs = realloc(nand_devs, sizeof(nand_devs[0]) * (nand_dev_count + 1)); 813 if(new_devs == NULL) 814 goto out_of_memory; 815 nand_devs = new_devs; 816 dev = &new_devs[nand_dev_count]; 817 818 dev->page_size = page_size; 819 dev->extra_size = extra_size; 820 dev->erase_size = erase_pages * (page_size + extra_size); 821 pad = dev_size % dev->erase_size; 822 if (pad != 0) { 823 dev_size += (dev->erase_size - pad); 824 D("rounding devsize up to a full eraseunit, now %llx\n", dev_size); 825 } 826 dev->devname = devname; 827 dev->devname_len = devname_len; 828 dev->max_size = dev_size; 829 dev->data = malloc(dev->erase_size); 830 if(dev->data == NULL) 831 goto out_of_memory; 832 dev->flags = read_only ? NAND_DEV_FLAG_READ_ONLY : 0; 833 #ifdef TARGET_I386 834 dev->flags |= NAND_DEV_FLAG_BATCH_CAP; 835 #endif 836 837 if (initfd >= 0) { 838 do { 839 read_size = do_read(initfd, dev->data, dev->erase_size); 840 if(read_size < 0) { 841 XLOG("could not read file %s, %s\n", initfilename, strerror(errno)); 842 exit(1); 843 } 844 if(do_write(rwfd, dev->data, read_size) != read_size) { 845 XLOG("could not write file %s, %s\n", rwfilename, strerror(errno)); 846 exit(1); 847 } 848 } while(read_size == dev->erase_size); 849 close(initfd); 850 } 851 dev->fd = rwfd; 852 853 nand_dev_count++; 854 855 return; 856 857 out_of_memory: 858 XLOG("out of memory\n"); 859 exit(1); 860 861 bad_arg_and_value: 862 XLOG("bad arg: %.*s=%.*s\n", arg_len, arg, value_len, value); 863 exit(1); 864 } 865 866 #ifdef CONFIG_NAND_LIMITS 867 868 static uint64_t 869 parse_nand_rw_limit( const char* value ) 870 { 871 char* end; 872 uint64_t val = strtoul( value, &end, 0 ); 873 874 if (end == value) { 875 derror( "bad parameter value '%s': expecting unsigned integer", value ); 876 exit(1); 877 } 878 879 switch (end[0]) { 880 case 'K': val <<= 10; break; 881 case 'M': val <<= 20; break; 882 case 'G': val <<= 30; break; 883 case 0: break; 884 default: 885 derror( "bad read/write limit suffix: use K, M or G" ); 886 exit(1); 887 } 888 return val; 889 } 890 891 void 892 parse_nand_limits(char* limits) 893 { 894 int pid = -1, signal = -1; 895 int64_t reads = 0, writes = 0; 896 char* item = limits; 897 898 /* parse over comma-separated items */ 899 while (item && *item) { 900 char* next = strchr(item, ','); 901 char* end; 902 903 if (next == NULL) { 904 next = item + strlen(item); 905 } else { 906 *next++ = 0; 907 } 908 909 if ( !memcmp(item, "pid=", 4) ) { 910 pid = strtol(item+4, &end, 10); 911 if (end == NULL || *end) { 912 derror( "bad parameter, expecting pid=<number>, got '%s'", 913 item ); 914 exit(1); 915 } 916 if (pid <= 0) { 917 derror( "bad parameter: process identifier must be > 0" ); 918 exit(1); 919 } 920 } 921 else if ( !memcmp(item, "signal=", 7) ) { 922 signal = strtol(item+7,&end, 10); 923 if (end == NULL || *end) { 924 derror( "bad parameter: expecting signal=<number>, got '%s'", 925 item ); 926 exit(1); 927 } 928 if (signal <= 0) { 929 derror( "bad parameter: signal number must be > 0" ); 930 exit(1); 931 } 932 } 933 else if ( !memcmp(item, "reads=", 6) ) { 934 reads = parse_nand_rw_limit(item+6); 935 } 936 else if ( !memcmp(item, "writes=", 7) ) { 937 writes = parse_nand_rw_limit(item+7); 938 } 939 else { 940 derror( "bad parameter '%s' (see -help-nand-limits)", item ); 941 exit(1); 942 } 943 item = next; 944 } 945 if (pid < 0) { 946 derror( "bad paramater: missing pid=<number>" ); 947 exit(1); 948 } 949 else if (signal < 0) { 950 derror( "bad parameter: missing signal=<number>" ); 951 exit(1); 952 } 953 else if (reads == 0 && writes == 0) { 954 dwarning( "no read or write limit specified. ignoring -nand-limits" ); 955 } else { 956 nand_threshold* t; 957 958 t = &android_nand_read_threshold; 959 t->pid = pid; 960 t->signal = signal; 961 t->counter = 0; 962 t->limit = reads; 963 964 t = &android_nand_write_threshold; 965 t->pid = pid; 966 t->signal = signal; 967 t->counter = 0; 968 t->limit = writes; 969 } 970 } 971 #endif /* CONFIG_NAND_LIMITS */ 972