Home | History | Annotate | Download | only in goldfish
      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 
     45 static void
     46 xlog( 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  */
     57 typedef 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 
     70 nand_threshold    android_nand_write_threshold;
     71 nand_threshold    android_nand_read_threshold;
     72 
     73 #ifdef CONFIG_NAND_THRESHOLD
     74 
     75 /* update a threshold, return 1 if limit is hit, 0 otherwise */
     76 static void
     77 nand_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 
    116 static nand_dev *nand_devs = NULL;
    117 static 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  */
    122 typedef 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
    146 QFIELD_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),
    155 QFIELD_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.
    159 QFIELD_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),
    164 QFIELD_END
    165 
    166 QFIELD_BEGIN(nand_dev_controller_state_legacy_2_fields)
    167     QFIELD_INT32(batch_addr_low),
    168     QFIELD_INT32(batch_addr_high),
    169     QFIELD_INT32(result),
    170 QFIELD_END
    171 
    172 /* EINTR-proof read - due to SIGALRM in use elsewhere */
    173 static 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 */
    184 static 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 */
    195 static 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 */
    206 static 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  */
    225 static 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  */
    272 static 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  */
    284 static 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  */
    340 static 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 
    352 static 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 
    365 static 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 
    387 static 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 
    414 static 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 
    438 static 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__)
    470 static
    471 #endif
    472 uint32_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 */
    558 static 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 */
    613 static 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 
    660 static CPUReadMemoryFunc *nand_dev_readfn[] = {
    661    nand_dev_read,
    662    nand_dev_read,
    663    nand_dev_read
    664 };
    665 
    666 static CPUWriteMemoryFunc *nand_dev_writefn[] = {
    667    nand_dev_write,
    668    nand_dev_write,
    669    nand_dev_write
    670 };
    671 
    672 /* initialize the QFB device */
    673 void 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 
    693 static 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 
    702 void 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 
    905 out_of_memory:
    906     XLOG("out of memory\n");
    907     exit(1);
    908 
    909 bad_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 
    916 static uint64_t
    917 parse_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 
    939 void
    940 parse_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