qemu/hw/block/arasan_nfc.c
<<
>>
Prefs
   1/*
   2 * QEMU model of Arasan Nand Flash Controller
   3 *
   4 * Copyright (c) 2013 Xilinx Inc.
   5 * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com>.
   6 *
   7 * Permission is hereby granted, free of charge, to any person obtaining a copy
   8 * of this software and associated documentation files (the "Software"), to deal
   9 * in the Software without restriction, including without limitation the rights
  10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 * copies of the Software, and to permit persons to whom the Software is
  12 * furnished to do so, subject to the following conditions:
  13 *
  14 * The above copyright notice and this permission notice shall be included in
  15 * all copies or substantial portions of the Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 * THE SOFTWARE.
  24 */
  25
  26#include "qemu/osdep.h"
  27#include "qemu/timer.h"
  28#include "qemu/bitops.h"
  29#include "sysemu/sysemu.h"
  30#include "sysemu/dma.h"
  31#include "hw/hw.h"
  32#include "hw/register-dep.h"
  33#include "hw/sysbus.h"
  34#include "hw/block/flash.h"
  35#include "qapi/qmp/qerror.h"
  36#include "qemu/fifo.h"
  37#include "sysemu/blockdev.h"
  38#include "qemu/log.h"
  39#include "qapi/error.h"
  40
  41#ifndef ARASAN_NFC_ERR_DEBUG
  42#define ARASAN_NFC_ERR_DEBUG 0
  43#endif
  44
  45#define DB_PRINT_L(level, ...) do { \
  46    if (ARASAN_NFC_ERR_DEBUG > (level)) { \
  47        qemu_log_mask(DEV_LOG_NANDC, ": %s: ", __func__); \
  48        qemu_log_mask(DEV_LOG_NANDC, ## __VA_ARGS__); \
  49    } \
  50} while (0);
  51
  52#define DB_PRINT(...) DB_PRINT_L(0, ## __VA_ARGS__)
  53
  54#define TYPE_ARASAN_NFC "arasan.nfc"
  55
  56#define ARASAN_NFC(obj) \
  57     OBJECT_CHECK(ArasanNFCState, (obj), TYPE_ARASAN_NFC)
  58
  59
  60/* The TRM has overly long names for everthing. The following substitutions
  61 * are mechanically (and unconditionally) made for the sake of 80 char sanity.
  62 * s/ADDR/ADDR
  63 * s/ENHANCED/ENH
  64 * s/INTERRUPT/INT
  65 * s/COMMAND/CMD
  66 * s/ENABLE/EN
  67 * s/BUFFER/BUF
  68 */
  69
  70DEP_REG32(PACKET, 0x00)
  71    DEP_FIELD(PACKET, PACKET_SIZE, 11, 0)
  72    DEP_FIELD(PACKET, PACKET_COUNT, 12, 12)
  73    #define R_PACKET_RSVD 0xff000800
  74
  75DEP_REG32(MEMORY_ADDR_1, 0x04)
  76
  77DEP_REG32(MEMORY_ADDR_2, 0x08)
  78    DEP_FIELD(MEMORY_ADDR_2, MEMORY_ADDR, 8, 0)
  79    #define R_MEMORY_ADDR_2_BUS_WIDTH (1 << 24)
  80    DEP_FIELD(MEMORY_ADDR_2, NFC_BCH_MODE, 3, 25)
  81    DEP_FIELD(MEMORY_ADDR_2, MODE, 2, 28)
  82    DEP_FIELD(MEMORY_ADDR_2, CHIP_SELECT, 2, 30)
  83    #define R_MEMORY_ADDR_2_RSVD 0x00FFFF00
  84
  85DEP_REG32(CMD, 0x0C)
  86    DEP_FIELD(CMD, CMD1, 8, 0)
  87    DEP_FIELD(CMD, CMD2, 8, 8)
  88    DEP_FIELD(CMD, PAGE_SIZE, 3, 23)
  89    DEP_FIELD(CMD, DMA_EN, 2, 26)
  90    /* deviated from TRM name as its overly long and typod */
  91    DEP_FIELD(CMD, NUM_ADDR_CYCLES, 3, 28)
  92    #define R_CMD_ECC_ON_OFF (1 << 31)
  93    #define R_CMD_RSVD 0x007F0000
  94
  95static uint32_t arasan_nfc_page_size_lookup [] = {
  96    [0] = 512,
  97    [1] = 2 * 1024,
  98    [2] = 4 * 1024,
  99    [3] = 8 * 1024,
 100    [4] = 16 * 1024,
 101    /* dont support 16b flash just at the moment */
 102    [7] = 0
 103};
 104
 105DEP_REG32(PGRAM, 0x10)
 106    #define R_PGRAM_READ (1 << 0)
 107    #define R_PGRAM_MULTI_DIE (1 << 1)
 108    #define R_PGRAM_BLOCK_ERASE (1 << 2)
 109    #define R_PGRAM_READ_STATUS (1 << 3)
 110    #define R_PGRAM_PAGE_PROGRAM (1 << 4)
 111    #define R_PGRAM_MUTLI_DIE_RD (1 << 5)
 112    #define R_PGRAM_READ_ID (1 << 6)
 113    #define R_PGRAM_READ_PARAMETER_PAGE (1 << 7)
 114    #define R_PGRAM_RESET (1 << 8)
 115    #define R_PGRAM_GET_FEATURES (1 << 9)
 116    #define R_PGRAM_SET_FEATURES (1 << 10)
 117    #define R_PGRAM_READ_UNIQUE_ID (1 << 11)
 118    #define R_PGRAM_READ_STATUS_ENH (1 << 12)
 119    #define R_PGRAM_READ_INTERLEAVED (1 << 13)
 120    #define R_PGRAM_CHANGE_READ_COLUMN_ENH (1 << 14)
 121    #define R_PGRAM_COPY_BACK_INTERLEAVED (1 << 15)
 122    #define R_PGRAM_READ_CACHE_START (1 << 16)
 123    #define R_PGRAM_READ_CACHE_SEQUENTIAL (1 << 17)
 124    #define R_PGRAM_READ_CACHE_RANDOM (1 << 18)
 125    #define R_PGRAM_READ_CACHE_END (1 << 19)
 126    #define R_PGRAM_SMALL_DATA_MOVE (1 << 20)
 127    #define R_PGRAM_CHANGE_ROW_ADDR (1 << 21)
 128    #define R_PGRAM_CHANGE_ROW_ADDR_END (1 << 22)
 129    #define R_PGRAM_RESET_LUN (1 << 23)
 130    #define R_PGRAM_PGM_PG_REG32_CLR (1 << 24)
 131    #define R_PGRAM_VOLUME_SELECT (1 << 25)
 132    #define R_PGRAM_ODT_CONFIGURE (1 << 26)
 133    #define R_PGRAM_RSVD (0x1f << 27)
 134    
 135DEP_REG32(INT_STATUS_EN, 0x14)
 136DEP_REG32(INT_SIGNAL_EN, 0x18)
 137DEP_REG32(INT_STATUS, 0x1C)
 138    /* dropped the redundant STS_EN, DEP_REG32 and SIG_EN suffixes from TRM names */
 139    #define R_INT_BUFF_WR_RDY (1 << 0)
 140    #define R_INT_BUFF_RD_RDY (1 << 1)
 141    #define R_INT_TRANS_COMP (1 << 2)
 142    #define R_INT_MUL_BIT_ERR (1 << 3)
 143    #define R_INT_ERR_INTRPT (1 << 4)
 144    #define R_INT_DMA_INT (1 << 6)
 145    #define R_INT_ERROR_AHB (1 << 7)
 146    #define R_INT_RSVD 0xFFFFFF00
 147    #define R_INT_ANY (~(R_INT_RSVD))
 148
 149DEP_REG32(FLASH_STATUS, 0x28)
 150    DEP_FIELD(FLASH_STATUS, FLASH_STATUS, 16, 0)
 151    #define R_FLASH_STATUS_RSVD 0xffff0000
 152
 153DEP_REG32(TIMING, 0x2C)
 154    DEP_FIELD(TIMING, TCCS_TIME, 2, 0)
 155    #define R_TIMING_SLOW_FAST_TCAD (1 << 2)
 156    DEP_FIELD(TIMING, DQS_BUFF_SEL, 4, 3)
 157    DEP_FIELD(TIMING, TADL_TIME, 7, 7)
 158
 159DEP_REG32(BUF_DATA_PORT, 0x30)
 160
 161DEP_REG32(ECC, 0x34)
 162    DEP_FIELD(ECC, ECC_ADDR, 16, 0)
 163    DEP_FIELD(ECC, ECC_SIZE, 11, 16)
 164    #define R_ECC_SLC_MLC (1 << 25)
 165    #define R_ECC_RSVD 0xfe000000
 166
 167DEP_REG32(ECC_ERR_COUNT, 0x38)
 168    DEP_FIELD(ECC_ERR_COUNT, PACKET_BOUND, 8, 0)
 169    DEP_FIELD(ECC_ERR_COUNT, PAGE_BOUND, 8, 8)
 170    #define R_ECC_ERR_COUNT_RSVD 0xFFFF0000
 171
 172DEP_REG32(ECC_SPARE_CMD, 0x3C)
 173    DEP_FIELD(ECC_SPARE_CMD, CMD1, 8, 0)
 174    DEP_FIELD(ECC_SPARE_CMD, CMD2, 8, 8)
 175    DEP_FIELD(ECC_SPARE_CMD, NUM_ADDR_CYCLES, 3, 28)
 176    #define R_ECC_SPARE_CMD_RSVD 0x8FFF0000
 177
 178/* FIXME Finish this */
 179#define R_ERR_COUNT_1BIT (0x40/4)
 180#define R_ERR_COUNT_2BIT (0x44/4)
 181#define R_ERR_COUNT_3BIT (0x48/4)
 182#define R_ERR_COUNT_4BIT (0x4C/4)
 183#define R_CPU_RELEASE (0x58/4)
 184#define R_ERR_COUNT_5BIT (0x5C/4)
 185#define R_ERR_COUNT_6BIT (0x60/4)
 186#define R_ERR_COUNT_7BIT (0x64/4)
 187#define R_ERR_COUNT_8BIT (0x68/4)
 188
 189DEP_REG32(DMA_SYSTEM_ADDR1, 0x24)
 190DEP_REG32(DMA_SYSTEM_ADDR0, 0x50)
 191
 192DEP_REG32(DMA_BUF_BOUNDARY, 0x54)
 193    #define R_DMA_BUF_BOUNDARY_RSVD (ONES(29) << 3)
 194
 195DEP_REG32(DATA_INTERFACE,   0x6C)
 196    DEP_FIELD(DATA_INTERFACE, SDR, 3, 0)
 197    DEP_FIELD(DATA_INTERFACE, NV_DDR, 3, 3)
 198    DEP_FIELD(DATA_INTERFACE, NV_DDR2, 3, 6)
 199    DEP_FIELD(DATA_INTERFACE, DATA_INTF, 2, 9)
 200    #define R_DATA_INTERFACE_RSVD 0xFFFFF800
 201
 202#define R_MAX (R_DATA_INTERFACE+1)
 203
 204/* The codeword size does vary in real hw between 512 and 1024 depding
 205 * on mode. But since we do not actually model a genuine ECC algorithm,
 206 * The actual ECC contents are undefined outside the context of QEMU.
 207 * Therefore it's valid to implement 1024B codeword as 2x512 without
 208 * consequence. Simplify by fixing the codeword at 512.
 209 */
 210
 211#define ECC_CODEWORD_SIZE 512
 212
 213typedef struct ArasanNFCState {
 214    SysBusDevice parent_obj;
 215
 216    MemoryRegion iomem;
 217    MemoryRegion *dma_mr;
 218    AddressSpace *dma_as;
 219    qemu_irq irq;
 220
 221    DeviceState *nand[2];
 222    DeviceState *current;
 223
 224    /* FIXME: Use a saner size */
 225    uint8_t ecc_digest[128 * 1024];
 226    uint8_t ecc_oob[128 * 1024];
 227    uint32_t ecc_pos, ecc_subpage_offset;
 228
 229    bool has_mdma;
 230    bool boot_en;
 231    uint8_t num_cs;
 232
 233    uint64_t dma_sar;
 234    bool dbb_blocked;
 235    Fifo buffer;
 236
 237    uint32_t regs[R_MAX];
 238    DepRegisterInfo regs_info[R_MAX];
 239
 240} ArasanNFCState;
 241
 242static inline void arasan_nfc_irq_event(ArasanNFCState *s, uint32_t ev)
 243{
 244    DB_PRINT("IRQ event %" PRIx32 " happened\n", ev);
 245    s->regs[R_INT_STATUS] |= ev & s->regs[R_INT_STATUS_EN];
 246}
 247
 248static inline bool arasan_nfc_ecc_enabled(ArasanNFCState *s)
 249{
 250    return s->regs[R_CMD] & R_CMD_ECC_ON_OFF;
 251}
 252
 253static void arasan_nfc_ecc_init(ArasanNFCState *s)
 254{
 255    /* FIXME: Bad performance */
 256    memset(s->ecc_digest, 0xFF, 16 * 1024);
 257    s->ecc_pos = 0;
 258    s->ecc_subpage_offset = 0;
 259}
 260
 261/* not an ECC algorithm, but gives a deterministic OOB that
 262 * depends on the in band data
 263 */
 264
 265static void arasan_nfc_ecc_digest(ArasanNFCState *s, uint8_t data)
 266{
 267    uint32_t page_size = arasan_nfc_page_size_lookup[DEP_AF_EX32(s->regs, CMD,
 268                                                             PAGE_SIZE)];
 269    int ecc_bytes_per_subpage = DEP_AF_EX32(s->regs, ECC, ECC_SIZE) /
 270                                (page_size / ECC_CODEWORD_SIZE);
 271
 272    s->ecc_digest[s->ecc_pos++] ^= ~data;
 273    if (!(s->ecc_pos % ecc_bytes_per_subpage)) {
 274        s->ecc_pos -= ecc_bytes_per_subpage;
 275    }
 276
 277    s->ecc_subpage_offset++;
 278    if (s->ecc_subpage_offset == ECC_CODEWORD_SIZE) {
 279        s->ecc_subpage_offset = 0;
 280        do {
 281            s->ecc_pos++;
 282        } while (s->ecc_pos % ecc_bytes_per_subpage);
 283    }
 284}
 285
 286static bool arasan_nfc_ecc_correct(ArasanNFCState *s)
 287{
 288    int i;
 289    uint8_t cef = 0;
 290
 291    for (i = 0; i < DEP_AF_EX32(s->regs, ECC, ECC_SIZE); ++i) {
 292        if (s->ecc_oob[i] != s->ecc_digest[i]) {
 293            arasan_nfc_irq_event(s, R_INT_MUL_BIT_ERR);
 294            if (DEP_AF_EX32(s->regs, ECC_ERR_COUNT, PAGE_BOUND) != 0xFF) {
 295                s->regs[R_ECC_ERR_COUNT] +=
 296                    1 << R_ECC_ERR_COUNT_PAGE_BOUND_SHIFT;
 297            }
 298            /* FIXME: All errors in the first packet - not right */
 299            if (DEP_AF_EX32(s->regs, ECC_ERR_COUNT, PACKET_BOUND) != 0xFF) {
 300                s->regs[R_ECC_ERR_COUNT] +=
 301                    1 << R_ECC_ERR_COUNT_PACKET_BOUND_SHIFT;
 302            }
 303            DB_PRINT("ECC check failed on ECC byte %#x, %#02" PRIx8 " != %#02"
 304                     PRIx8 "\n", i, s->ecc_oob[i], s->ecc_digest[i]);
 305            return true;
 306        } else {
 307            cef ^= s->ecc_oob[i];
 308        }
 309    }
 310    /* Fake random successful single bit corrections for hamming */
 311    for (i = 0; i < 7; ++i) {
 312        cef = (cef >> 1) ^ (cef & 0x1);
 313    }
 314    if ((cef & 0x1) && ((s->regs[R_ECC] & R_ECC_SLC_MLC))) {
 315        arasan_nfc_irq_event(s, R_INT_ERR_INTRPT);
 316    }
 317    DB_PRINT("ECC check passed");
 318    return false;
 319}
 320
 321static void arasan_nfc_do_cmd2(ArasanNFCState *s, bool ecc)
 322{
 323    uint8_t cmd;
 324
 325    nand_setpins(s->current, 1, 0, 0, 1, 0); /* CMD */
 326    cmd = ecc ? DEP_AF_EX32(s->regs, ECC_SPARE_CMD, CMD2) :
 327                DEP_AF_EX32(s->regs, CMD, CMD2);
 328    nand_setio(s->current, cmd);
 329    DB_PRINT("send second command cycle %#02" PRIx8 "\n", cmd);
 330}
 331
 332static void arasan_nfc_do_cmd(ArasanNFCState *s, uint8_t addr_cycles, bool ecc,
 333                              bool force_addr_cycles)
 334{
 335    int i;
 336    uint8_t num_cycles;
 337    uint8_t cmd;
 338
 339    nand_setpins(s->current, 1, 0, 0, 1, 0); /* CMD */
 340    cmd = ecc ? DEP_AF_EX32(s->regs, ECC_SPARE_CMD, CMD1) :
 341                DEP_AF_EX32(s->regs, CMD, CMD1);
 342    nand_setio(s->current, cmd);
 343    DB_PRINT("send command cycle %#02" PRIx8 "\n", cmd);
 344
 345    num_cycles = ecc ? DEP_AF_EX32(s->regs, ECC_SPARE_CMD, NUM_ADDR_CYCLES) :
 346                       DEP_AF_EX32(s->regs, CMD, NUM_ADDR_CYCLES);
 347    if (force_addr_cycles) {
 348        num_cycles = addr_cycles;
 349    } else if (num_cycles != addr_cycles) {
 350        qemu_log_mask(LOG_GUEST_ERROR, "Mismatched between given (%d) and "
 351                      "expected(%d) address cycles\n", num_cycles, addr_cycles);
 352    }
 353
 354    for (i = 0; i < num_cycles; ++i) {
 355        uint8_t data;
 356        if (i < 4) {
 357            data = s->regs[ecc ? R_ECC : R_MEMORY_ADDR_1] >> (i * 8);
 358        } else if (i == 4) {
 359            data = s->regs[R_MEMORY_ADDR_2];
 360        } else {
 361            qemu_log_mask(LOG_GUEST_ERROR, "BAD number of NAND addr cycles\n");
 362            break;
 363        }
 364        nand_setpins(s->current, 0, 1, 0, 1, 0); /* address */
 365        nand_setio(s->current, data);
 366        DB_PRINT("send addr cycle %#02" PRIx8 "\n", data);
 367    }
 368}
 369
 370static inline void arasan_nfc_sync_dma_addr(ArasanNFCState *s)
 371{
 372    s->dma_sar = ((uint64_t)s->regs[R_DMA_SYSTEM_ADDR1] << 32) +
 373                 s->regs[R_DMA_SYSTEM_ADDR0];
 374}
 375
 376static inline void arasan_nfc_do_dma(ArasanNFCState *s, bool rnw)
 377{
 378    DMADirection dir = rnw ? DMA_DIRECTION_FROM_DEVICE :
 379                             DMA_DIRECTION_TO_DEVICE;
 380    int debug_squelch = 5;
 381
 382    /* FIXME: Be less dumb */
 383    while (DEP_AF_EX32(s->regs, CMD, DMA_EN) == 0x2 &&
 384           !(rnw ? fifo_is_empty : fifo_is_full)(&s->buffer) &&
 385           !s->dbb_blocked) {
 386        uint32_t dbb_mask = MAKE_64BIT_MASK(0,
 387                                            s->regs[R_DMA_BUF_BOUNDARY] + 12);
 388        uint8_t tmp;
 389
 390        if (rnw) {
 391            tmp = fifo_pop8(&s->buffer);
 392        }
 393
 394        dma_memory_rw(s->dma_as, s->dma_sar, &tmp, 1, dir);
 395
 396        if (debug_squelch) {
 397            DB_PRINT("Doing dma %s with addr %08" PRIx64 " = %02" PRIx8 "\n",
 398                     rnw ? "read" : "write", s->dma_sar, tmp);
 399            debug_squelch--;
 400        }
 401
 402        if (!rnw) {
 403            fifo_push8(&s->buffer, tmp);
 404        }
 405
 406        if ((s->regs[R_DMA_BUF_BOUNDARY] & 1 << 3) &&
 407            (s->dma_sar & dbb_mask) == dbb_mask) {
 408            s->dbb_blocked = true;
 409                arasan_nfc_irq_event(s, R_INT_DMA_INT);
 410        }
 411        s->dma_sar++;
 412    }
 413}
 414
 415static inline bool arasan_nfc_write_check_ecc(ArasanNFCState *s)
 416{
 417  return (s->regs[R_PGRAM] & R_PGRAM_PAGE_PROGRAM) &&
 418         arasan_nfc_ecc_enabled(s);
 419}
 420
 421static uint32_t arasan_nfc_get_packet_size(ArasanNFCState *s, uint32_t pgram) {
 422    uint32_t packet_size = DEP_AF_EX32(s->regs, PACKET, PACKET_SIZE);
 423
 424        switch (pgram) {
 425        case R_PGRAM_SET_FEATURES:
 426        case R_PGRAM_GET_FEATURES:
 427        case R_PGRAM_READ_ID:
 428        case R_PGRAM_READ_STATUS_ENH:
 429        case R_PGRAM_READ_STATUS:
 430        if (DEP_AF_EX32(s->regs, DATA_INTERFACE, DATA_INTF)) {
 431            DB_PRINT("Halving payload size for DDR command\n");
 432            packet_size /= 2;
 433        }
 434    }
 435    return packet_size;
 436}
 437
 438static void arasan_nfc_set_current(ArasanNFCState *s)
 439{
 440    int cs_dev = DEP_AF_EX32(s->regs, MEMORY_ADDR_2, CHIP_SELECT);
 441
 442    /* Lazy-init nand if its not initialised at realize,
 443     * i.e no pflash arg at command line */
 444    if (!s->nand[cs_dev]) {
 445        s->nand[cs_dev] = nand_init(NULL, NAND_MFR_MICRON, 0x44);
 446    }
 447    s->current = s->nand[cs_dev];
 448}
 449
 450static inline void arasan_nfc_update_state(ArasanNFCState *s)
 451{
 452    int i;
 453    uint32_t packet_size;
 454
 455    switch (s->regs[R_PGRAM]) {
 456    case R_PGRAM_READ:
 457        arasan_nfc_do_dma(s, true);
 458    case R_PGRAM_GET_FEATURES:
 459    case R_PGRAM_READ_PARAMETER_PAGE:
 460    case R_PGRAM_READ_ID:
 461                if (fifo_is_empty(&s->buffer)) {
 462                    DB_PRINT("read completed\n");
 463                    arasan_nfc_irq_event(s, R_INT_TRANS_COMP);
 464                    s->regs[R_PGRAM] = 0;
 465                }
 466        break;
 467    case R_PGRAM_READ_STATUS:
 468    case R_PGRAM_READ_STATUS_ENH:
 469                if (!fifo_is_empty(&s->buffer)) {
 470            DEP_AF_DP32(s->regs, FLASH_STATUS, FLASH_STATUS, fifo_pop8(&s->buffer));
 471                    DB_PRINT("read completed\n");
 472                    arasan_nfc_irq_event(s, R_INT_TRANS_COMP);
 473                    s->regs[R_PGRAM] = 0;
 474        }
 475        }
 476
 477        if (s->regs[R_PGRAM] & R_PGRAM_PAGE_PROGRAM) {
 478        arasan_nfc_do_dma(s, false);
 479    }
 480        if ((s->regs[R_PGRAM] & R_PGRAM_PAGE_PROGRAM) ||
 481        (s->regs[R_PGRAM] & R_PGRAM_SET_FEATURES)) {
 482                arasan_nfc_set_current(s);
 483                if (fifo_is_full(&s->buffer)) {
 484                        DB_PRINT("write completed\n");
 485                    arasan_nfc_irq_event(s, R_INT_TRANS_COMP);
 486                    /* We are slow - do everything at the end */
 487                nand_setpins(s->current, 0, 0, 0, 1, 0); /* data */
 488            if (arasan_nfc_write_check_ecc(s)) {
 489                arasan_nfc_ecc_init(s);
 490            }
 491                    while (!fifo_is_empty(&s->buffer)) {
 492                        uint8_t to_write = fifo_pop8(&s->buffer);
 493                if (arasan_nfc_write_check_ecc(s)) {
 494                    arasan_nfc_ecc_digest(s, to_write);
 495                }
 496                        nand_setio(s->current, to_write);
 497                                DB_PRINT("write byte %#02" PRIx8 "\n", to_write);
 498                    }
 499            if (arasan_nfc_write_check_ecc(s)) {
 500                arasan_nfc_do_cmd(s, 2, true, false);
 501                nand_setpins(s->current, 0, 0, 0, 1, 0); /* data */
 502                for (i = 0; i < DEP_AF_EX32(s->regs, ECC, ECC_SIZE); ++i) {
 503                    nand_setio(s->current, s->ecc_digest[i]);
 504                    DB_PRINT("write ecc byte %#02" PRIx8 "\n", s->ecc_digest[i]);
 505                }
 506            }
 507            if (s->regs[R_PGRAM] & R_PGRAM_PAGE_PROGRAM) {
 508                arasan_nfc_do_cmd2(s, false);
 509            }
 510                    s->regs[R_PGRAM] = 0;
 511        }
 512        }
 513
 514    packet_size = arasan_nfc_get_packet_size(s, s->regs[R_PGRAM]);
 515    s->regs[R_INT_STATUS] &= ~(R_INT_BUFF_RD_RDY | R_INT_BUFF_WR_RDY);
 516    s->regs[R_INT_STATUS] |= s->regs[R_INT_STATUS_EN] & (
 517            (s->buffer.num <= s->buffer.capacity - packet_size ?
 518                              R_INT_BUFF_WR_RDY : 0) |
 519            (s->buffer.num >= packet_size && packet_size ?
 520                              R_INT_BUFF_RD_RDY : 0));
 521
 522    qemu_set_irq(s->irq, !!(s->regs[R_INT_SIGNAL_EN] &
 523                            s->regs[R_INT_STATUS]));
 524
 525}
 526
 527static void arasan_nfc_update_state_pw(DepRegisterInfo *reg, uint64_t val)
 528{
 529    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 530
 531    arasan_nfc_update_state(s);
 532}
 533
 534static void arasan_nfc_reset(DeviceState *dev) {
 535    ArasanNFCState *s = ARASAN_NFC(dev);
 536
 537    /* Reset the registers */
 538    arasan_nfc_update_state(s);
 539}    
 540
 541static void arasan_nfc_r_unimp_post_write(DepRegisterInfo *reg, uint64_t val)
 542{
 543        fprintf(stderr, "unimplemented functionality touched\n");
 544}
 545
 546static uint64_t arasan_nfc_r_buffer_data_port_pr(DepRegisterInfo *reg, uint64_t val)
 547{
 548    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 549    int i;
 550    uint8_t buf[4];
 551
 552    memset(buf, 0, 4);
 553
 554    for (i = 0; i < 4 && !fifo_is_empty(&s->buffer); ++i) {
 555        buf[i] = fifo_pop8(&s->buffer);
 556    }
 557
 558    arasan_nfc_update_state(s);
 559    return cpu_to_le32(*((uint32_t *)buf));
 560}
 561
 562static void arasan_nfc_r_buffer_data_port_pw(DepRegisterInfo *reg, uint64_t val)
 563{
 564    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 565    int i;
 566    uint8_t buf[4];
 567
 568    if (!(s->regs[R_PGRAM] & R_PGRAM_PAGE_PROGRAM) &&
 569        !(s->regs[R_PGRAM] & R_PGRAM_SET_FEATURES)) {
 570        /* FIXME: Prettyify */
 571        qemu_log_mask(LOG_GUEST_ERROR, "Write to buffer data port with no data");
 572        return;
 573    }
 574
 575    *((uint32_t *)buf) = le32_to_cpu((uint32_t)val);
 576    for (i = 0; i < 4; ++i) {
 577        fifo_push8(&s->buffer, buf[i]);
 578    }
 579
 580        arasan_nfc_update_state(s);
 581}
 582
 583static void arasan_nfc_r_dma_system_addr1_pw(DepRegisterInfo *reg, uint64_t val)
 584{
 585    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 586
 587    arasan_nfc_sync_dma_addr(s);
 588}
 589
 590static void arasan_nfc_r_dma_system_addr_pw(DepRegisterInfo *reg, uint64_t val)
 591{
 592    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 593
 594    arasan_nfc_sync_dma_addr(s);
 595    s->dbb_blocked = false;
 596        arasan_nfc_update_state(s);
 597}
 598
 599static uint64_t r_program_pre_write(DepRegisterInfo *reg, uint64_t val)
 600{
 601    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 602    int i, j;
 603
 604    DB_PRINT("val = %#08" PRIx32 "\n", (uint32_t)val);
 605
 606    if (val && s->regs[R_PGRAM]) {
 607        qemu_log_mask(LOG_GUEST_ERROR, "%s:CMD already in progress", reg->prefix);
 608        return 0;
 609    }
 610
 611    arasan_nfc_set_current(s);
 612    for (i = 0; i < 32; ++i) {
 613        uint32_t pgram = val & (1 << i);
 614        uint32_t payload_size = arasan_nfc_get_packet_size(s, pgram) *
 615                                DEP_AF_EX32(s->regs, PACKET, PACKET_COUNT);
 616
 617        switch (pgram) {
 618            case R_PGRAM_READ_STATUS_ENH:
 619            case R_PGRAM_READ_STATUS:
 620            case R_PGRAM_PAGE_PROGRAM:
 621            case R_PGRAM_READ_ID:
 622            case R_PGRAM_SET_FEATURES:
 623            case R_PGRAM_GET_FEATURES:
 624            case R_PGRAM_READ_PARAMETER_PAGE:
 625            case R_PGRAM_READ:
 626                    fifo_destroy(&s->buffer);
 627                    fifo_create8(&s->buffer, payload_size);
 628        }
 629
 630        switch (pgram) {
 631        case R_PGRAM_RESET:
 632            arasan_nfc_do_cmd(s, 0, false, false);
 633                val &= ~R_PGRAM_RESET;
 634                    arasan_nfc_irq_event(s, R_INT_TRANS_COMP);
 635                break;
 636        case R_PGRAM_READ_ID:
 637                arasan_nfc_do_cmd(s, 1, false, false);
 638            break;
 639        case R_PGRAM_BLOCK_ERASE:
 640            arasan_nfc_do_cmd(s, 3, false, false);
 641            arasan_nfc_do_cmd2(s, false);
 642                val &= ~R_PGRAM_BLOCK_ERASE;
 643                    arasan_nfc_irq_event(s, R_INT_TRANS_COMP);
 644            break;
 645        case R_PGRAM_READ_STATUS:
 646            arasan_nfc_do_cmd(s, 0, false, true);
 647            break;
 648        case R_PGRAM_READ_STATUS_ENH:
 649            arasan_nfc_do_cmd(s, 3, false, true);
 650            break;
 651        case R_PGRAM_SET_FEATURES:
 652        case R_PGRAM_GET_FEATURES:
 653        case R_PGRAM_READ_PARAMETER_PAGE:
 654            arasan_nfc_do_cmd(s, 1, false, true);
 655            break;
 656        case R_PGRAM_READ:
 657            arasan_nfc_do_cmd(s, 5, false, false);
 658            arasan_nfc_do_cmd2(s, false);
 659            break;
 660        case R_PGRAM_PAGE_PROGRAM:
 661            arasan_nfc_do_cmd(s, 5, false, true);
 662            break;
 663        case 0:
 664            continue;
 665        default:
 666            arasan_nfc_r_unimp_post_write(reg, val);
 667            qemu_log_mask(LOG_UNIMP, "%s:Unimplemented CMD %" PRIx32, reg->prefix, pgram);
 668        }
 669
 670        /* we are fast! Do reads now now now!! */
 671        switch (pgram) {
 672        case R_PGRAM_READ_STATUS:
 673        case R_PGRAM_READ_STATUS_ENH:
 674        case R_PGRAM_READ_ID:
 675        case R_PGRAM_GET_FEATURES:
 676        case R_PGRAM_READ_PARAMETER_PAGE:
 677                nand_setpins(s->current, 0, 0, 0, 1, 0); /* data */
 678            for (j = 0; j < payload_size; ++j) {
 679                uint8_t to_read = nand_getio(s->current);
 680                fifo_push8(&s->buffer, to_read);
 681                DB_PRINT("read byte %#02" PRIx8 "\n", to_read);
 682            }
 683            break;
 684        case R_PGRAM_READ:
 685            if (arasan_nfc_ecc_enabled(s)) {
 686                s->regs[R_ECC_ERR_COUNT] = 0;
 687                arasan_nfc_ecc_init(s);
 688            }
 689            nand_setpins(s->current, 0, 0, 0, 1, 0); /* data */
 690            for (j = 0; j < payload_size; ++j) {
 691                uint8_t to_read = nand_getio(s->current);
 692                if (arasan_nfc_ecc_enabled(s)) {
 693                    arasan_nfc_ecc_digest(s, to_read);
 694                }
 695                fifo_push8(&s->buffer, to_read);
 696                DB_PRINT("read byte %#02" PRIx8 "\n", to_read);
 697            }
 698            /* FIXME: ECC is done backwards for reads, reading the payload
 699             * first, then the ECC data late. Real HW is the other way round.
 700             */
 701            if (arasan_nfc_ecc_enabled(s)) {
 702                arasan_nfc_do_cmd(s, 2, true, false);
 703                arasan_nfc_do_cmd2(s, true);
 704                for (j = 0; j < DEP_AF_EX32(s->regs, ECC, ECC_SIZE); ++j) {
 705                    s->ecc_oob[j] = nand_getio(s->current);
 706                    DB_PRINT("read ecc %#02" PRIx8 "\n", s->ecc_oob[j]);
 707                }
 708                arasan_nfc_ecc_correct(s);
 709            }
 710        }
 711    }
 712
 713    return val;
 714}
 715
 716static const MemoryRegionOps arasan_nfc_ops = {
 717    .read = dep_register_read_memory_le,
 718    .write = dep_register_write_memory_le,
 719    .endianness = DEVICE_NATIVE_ENDIAN,
 720    .valid = {
 721        .min_access_size = 4,
 722        .max_access_size = 4
 723    }
 724};
 725
 726static const DepRegisterAccessInfo arasan_nfc_regs_info[] = {
 727    {   .name = "Packet",                   .decode.addr = A_PACKET,
 728            .rsvd = R_PACKET_RSVD,
 729            .reset = 0x200 << R_PACKET_PACKET_SIZE_SHIFT,
 730    },{ .name = "Memory Address 1",         .decode.addr = A_MEMORY_ADDR_1,
 731    },{ .name = "Memory Address 2",         .decode.addr = A_MEMORY_ADDR_2,
 732            .rsvd = R_MEMORY_ADDR_2_RSVD,
 733            .post_write = arasan_nfc_update_state_pw,
 734    },{ .name = "CMD",                      .decode.addr = A_CMD,
 735            .rsvd = R_CMD_RSVD,
 736            .reset = 0x2 << R_CMD_PAGE_SIZE_SHIFT,
 737    },{ .name = "Program",                  .decode.addr = A_PGRAM,
 738            .rsvd = R_PGRAM_RSVD,
 739            .pre_write = r_program_pre_write,
 740            .post_write = arasan_nfc_update_state_pw,
 741    },{ .name = "Interrupt Status Enable",  .decode.addr = A_INT_STATUS_EN,
 742            .rsvd = R_INT_RSVD,
 743            .post_write = arasan_nfc_update_state_pw,
 744    },{ .name = "Interrupt Signal Enable",  .decode.addr = A_INT_SIGNAL_EN,
 745            .rsvd = R_INT_RSVD,
 746            .post_write = arasan_nfc_update_state_pw,
 747    },{ .name = "Interrupt Status",         .decode.addr = A_INT_STATUS,
 748            .rsvd = R_INT_RSVD,
 749            .w1c = R_INT_ANY,
 750            .post_write = arasan_nfc_update_state_pw,
 751    },{ .name = "Flash Status",             .decode.addr = A_FLASH_STATUS,
 752            .ro = ~0,
 753    },{ .name = "Timing",                   .decode.addr = A_TIMING,
 754            .reset = 0x6 << R_TIMING_DQS_BUFF_SEL_SHIFT,
 755    },{ .name = "Buffer Data Port",         .decode.addr = A_BUF_DATA_PORT,
 756            .post_write = arasan_nfc_r_buffer_data_port_pw,
 757            .post_read = arasan_nfc_r_buffer_data_port_pr,
 758    },{ .name = "ECC",                      .decode.addr = A_ECC,
 759        .rsvd = R_ECC_RSVD,
 760    },{ .name = "ECC Error Count",          .decode.addr = A_ECC_ERR_COUNT,
 761        .rsvd = R_ECC_ERR_COUNT_RSVD,
 762    },{ .name = "ECC Spare Command",        .decode.addr = A_ECC_SPARE_CMD,
 763        .rsvd = R_ECC_SPARE_CMD_RSVD,
 764    },{ .name = "DMA System Addr High",     .decode.addr = A_DMA_SYSTEM_ADDR1,
 765            .post_write = arasan_nfc_r_dma_system_addr1_pw,
 766    },{ .name = "DMA System Addr Low",      .decode.addr = A_DMA_SYSTEM_ADDR0,
 767            .post_write = arasan_nfc_r_dma_system_addr_pw,
 768    },{ .name = "DMA Buffer Boundary",      .decode.addr = A_DMA_BUF_BOUNDARY,
 769            .rsvd = R_DMA_BUF_BOUNDARY_RSVD,
 770    },{ .name = "Data Interface",           .decode.addr = A_DATA_INTERFACE,
 771            .rsvd = R_DATA_INTERFACE_RSVD,
 772    },
 773};
 774
 775static void arasan_nfc_realize(DeviceState *dev, Error ** errp)
 776{
 777    ArasanNFCState *s = ARASAN_NFC(dev);
 778    const char *prefix = object_get_canonical_path(OBJECT(dev));
 779    DriveInfo *dinfo;
 780    int i;
 781
 782    /* FIXME: add support for multiple chips */
 783    dinfo = drive_get_next(IF_PFLASH);
 784    if (dinfo) {
 785        s->nand[0] = nand_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
 786                               NAND_MFR_MICRON, 0x44);
 787    }
 788    dinfo = drive_get_next(IF_PFLASH);
 789    if (dinfo) {
 790        s->nand[1] = nand_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
 791                               NAND_MFR_MICRON, 0x44);
 792    }
 793    for (i = 0; i < ARRAY_SIZE(arasan_nfc_regs_info); ++i) {
 794        DepRegisterInfo *r = &s->regs_info[i];
 795
 796        *r = (DepRegisterInfo) {
 797            .data = &s->regs[arasan_nfc_regs_info[i].decode.addr/4],
 798            .data_size = sizeof(uint32_t),
 799            .access = &arasan_nfc_regs_info[i],
 800            .debug = qemu_loglevel_mask(DEV_LOG_NANDC),
 801            .prefix = prefix,
 802            .opaque = s,
 803        };
 804        memory_region_init_io(&r->mem, OBJECT(dev), &arasan_nfc_ops, r,
 805                              r->access->name, 4);
 806        memory_region_add_subregion(&s->iomem, r->access->decode.addr, &r->mem);
 807    }
 808
 809    fifo_create8(&s->buffer, 1);
 810
 811    if (s->dma_mr) {
 812        s->dma_as = g_malloc0(sizeof(AddressSpace));
 813        address_space_init(s->dma_as, s->dma_mr, NULL);
 814    } else {
 815        s->dma_as = &address_space_memory;
 816    }
 817}
 818
 819static void arasan_nfc_init(Object *obj)
 820{
 821    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 822    ArasanNFCState *s = ARASAN_NFC(obj);
 823
 824    object_property_add_link(obj, "nand0", TYPE_DEVICE,
 825                             (Object **)&s->nand[0],
 826                             object_property_allow_set_link,
 827                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 828                             &error_abort);
 829    object_property_add_link(obj, "nand1", TYPE_DEVICE,
 830                             (Object **)&s->nand[1],
 831                             object_property_allow_set_link,
 832                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 833                             &error_abort);
 834
 835    sysbus_init_irq(sbd, &s->irq);
 836
 837    memory_region_init(&s->iomem, obj, "nand", R_MAX*4);
 838    sysbus_init_mmio(sbd, &s->iomem);
 839
 840    object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
 841                             (Object **)&s->dma_mr,
 842                             qdev_prop_allow_set_link_before_realize,
 843                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 844                             &error_abort);
 845}
 846
 847static Property arasan_nfc_properties[] = {
 848    DEFINE_PROP_UINT8("num-cs", ArasanNFCState, num_cs, 2),
 849    DEFINE_PROP_BOOL("has-mdma", ArasanNFCState, has_mdma, true),
 850    DEFINE_PROP_BOOL("boot-en", ArasanNFCState, boot_en, false),
 851    DEFINE_PROP_END_OF_LIST(),
 852};
 853
 854static const VMStateDescription vmstate_arasan_nfc = {
 855    .name = TYPE_ARASAN_NFC,
 856    .version_id = 1,
 857    .minimum_version_id = 1,
 858    .fields = (VMStateField[]) {
 859        VMSTATE_END_OF_LIST()
 860    }
 861};
 862
 863static void arasan_nfc_class_init(ObjectClass *klass, void *data)
 864{
 865    DeviceClass *dc = DEVICE_CLASS(klass);
 866
 867    dc->reset = arasan_nfc_reset;
 868    dc->realize = arasan_nfc_realize;
 869    dc->props = arasan_nfc_properties;
 870    dc->vmsd = &vmstate_arasan_nfc;
 871}
 872
 873static TypeInfo arasan_nfc_info = {
 874    .name           = TYPE_ARASAN_NFC,
 875    .parent         = TYPE_SYS_BUS_DEVICE,
 876    .instance_size  = sizeof(ArasanNFCState),
 877    .class_init     = arasan_nfc_class_init,
 878    .instance_init  = arasan_nfc_init,
 879};
 880
 881static void arasan_nfc_register_types(void)
 882{
 883    type_register_static(&arasan_nfc_info);
 884}
 885
 886type_init(arasan_nfc_register_types)
 887