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