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