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/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
  70REG32(PACKET, 0x00)
  71    FIELD(PACKET, PACKET_SIZE, 11, 0)
  72    FIELD(PACKET, PACKET_COUNT, 12, 12)
  73    #define R_PACKET_RSVD 0xff000800
  74
  75REG32(MEMORY_ADDR_1, 0x04)
  76
  77REG32(MEMORY_ADDR_2, 0x08)
  78    FIELD(MEMORY_ADDR_2, MEMORY_ADDR, 8, 0)
  79    #define R_MEMORY_ADDR_2_BUS_WIDTH (1 << 24)
  80    FIELD(MEMORY_ADDR_2, NFC_BCH_MODE, 3, 25)
  81    FIELD(MEMORY_ADDR_2, MODE, 2, 28)
  82    FIELD(MEMORY_ADDR_2, CHIP_SELECT, 2, 30)
  83    #define R_MEMORY_ADDR_2_RSVD 0x00FFFF00
  84
  85REG32(CMD, 0x0C)
  86    FIELD(CMD, CMD1, 8, 0)
  87    FIELD(CMD, CMD2, 8, 8)
  88    FIELD(CMD, PAGE_SIZE, 3, 23)
  89    FIELD(CMD, DMA_EN, 2, 26)
  90    /* deviated from TRM name as its overly long and typod */
  91    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
 105REG32(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    
 135REG32(INT_STATUS_EN, 0x14)
 136REG32(INT_SIGNAL_EN, 0x18)
 137REG32(INT_STATUS, 0x1C)
 138    /* dropped the redundant STS_EN, 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
 149REG32(FLASH_STATUS, 0x28)
 150    FIELD(FLASH_STATUS, FLASH_STATUS, 16, 0)
 151    #define R_FLASH_STATUS_RSVD 0xffff0000
 152
 153REG32(TIMING, 0x2C)
 154    FIELD(TIMING, TCCS_TIME, 2, 0)
 155    #define R_TIMING_SLOW_FAST_TCAD (1 << 2)
 156    FIELD(TIMING, DQS_BUFF_SEL, 4, 3)
 157    FIELD(TIMING, TADL_TIME, 7, 7)
 158
 159REG32(BUF_DATA_PORT, 0x30)
 160
 161REG32(ECC, 0x34)
 162    FIELD(ECC, ECC_ADDR, 16, 0)
 163    FIELD(ECC, ECC_SIZE, 11, 16)
 164    #define R_ECC_SLC_MLC (1 << 25)
 165    #define R_ECC_RSVD 0xfe000000
 166
 167REG32(ECC_ERR_COUNT, 0x38)
 168    FIELD(ECC_ERR_COUNT, PACKET_BOUND, 8, 0)
 169    FIELD(ECC_ERR_COUNT, PAGE_BOUND, 8, 8)
 170    #define R_ECC_ERR_COUNT_RSVD 0xFFFF0000
 171
 172REG32(ECC_SPARE_CMD, 0x3C)
 173    FIELD(ECC_SPARE_CMD, CMD1, 8, 0)
 174    FIELD(ECC_SPARE_CMD, CMD2, 8, 8)
 175    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
 189REG32(DMA_SYSTEM_ADDR1, 0x24)
 190REG32(DMA_SYSTEM_ADDR0, 0x50)
 191
 192REG32(DMA_BUF_BOUNDARY, 0x54)
 193    #define R_DMA_BUF_BOUNDARY_RSVD (ONES(29) << 3)
 194
 195REG32(DATA_INTERFACE,   0x6C)
 196    FIELD(DATA_INTERFACE, SDR, 3, 0)
 197    FIELD(DATA_INTERFACE, NV_DDR, 3, 3)
 198    FIELD(DATA_INTERFACE, NV_DDR2, 3, 6)
 199    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    RegisterInfo 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[AF_EX32(s->regs, CMD,
 268                                                             PAGE_SIZE)];
 269    int ecc_bytes_per_subpage = 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 < 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 (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 (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 ? AF_EX32(s->regs, ECC_SPARE_CMD, CMD2) :
 327                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 ? AF_EX32(s->regs, ECC_SPARE_CMD, CMD1) :
 341                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 ? AF_EX32(s->regs, ECC_SPARE_CMD, NUM_ADDR_CYCLES) :
 346                       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 (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 = ONES(s->regs[R_DMA_BUF_BOUNDARY] + 12);
 387        uint8_t tmp;
 388
 389        if (rnw) {
 390            tmp = fifo_pop8(&s->buffer);
 391        }
 392
 393        dma_memory_rw(s->dma_as, s->dma_sar, &tmp, 1, dir);
 394
 395        if (debug_squelch) {
 396            DB_PRINT("Doing dma %s with addr %08" PRIx64 " = %02" PRIx8 "\n",
 397                     rnw ? "read" : "write", s->dma_sar, tmp);
 398            debug_squelch--;
 399        }
 400
 401        if (!rnw) {
 402            fifo_push8(&s->buffer, tmp);
 403        }
 404
 405        if ((s->regs[R_DMA_BUF_BOUNDARY] & 1 << 3) &&
 406            (s->dma_sar & dbb_mask) == dbb_mask) {
 407            s->dbb_blocked = true;
 408                arasan_nfc_irq_event(s, R_INT_DMA_INT);
 409        }
 410        s->dma_sar++;
 411    }
 412}
 413
 414static inline bool arasan_nfc_write_check_ecc(ArasanNFCState *s)
 415{
 416  return (s->regs[R_PGRAM] & R_PGRAM_PAGE_PROGRAM) &&
 417         arasan_nfc_ecc_enabled(s);
 418}
 419
 420static uint32_t arasan_nfc_get_packet_size(ArasanNFCState *s, uint32_t pgram) {
 421    uint32_t packet_size = AF_EX32(s->regs, PACKET, PACKET_SIZE);
 422
 423        switch (pgram) {
 424        case R_PGRAM_SET_FEATURES:
 425        case R_PGRAM_GET_FEATURES:
 426        case R_PGRAM_READ_ID:
 427        case R_PGRAM_READ_STATUS_ENH:
 428        case R_PGRAM_READ_STATUS:
 429        if (AF_EX32(s->regs, DATA_INTERFACE, DATA_INTF)) {
 430            DB_PRINT("Halving payload size for DDR command\n");
 431            packet_size /= 2;
 432        }
 433    }
 434    return packet_size;
 435}
 436
 437static void arasan_nfc_set_current(ArasanNFCState *s)
 438{
 439    int cs_dev = AF_EX32(s->regs, MEMORY_ADDR_2, CHIP_SELECT);
 440
 441    /* Lazy-init nand if its not initialised at realize,
 442     * i.e no pflash arg at command line */
 443    if (!s->nand[cs_dev]) {
 444        s->nand[cs_dev] = nand_init(NULL, NAND_MFR_MICRON, 0x44);
 445    }
 446    s->current = s->nand[cs_dev];
 447}
 448
 449static inline void arasan_nfc_update_state(ArasanNFCState *s)
 450{
 451    int i;
 452    uint32_t packet_size;
 453
 454    switch (s->regs[R_PGRAM]) {
 455    case R_PGRAM_READ:
 456        arasan_nfc_do_dma(s, true);
 457    case R_PGRAM_GET_FEATURES:
 458    case R_PGRAM_READ_PARAMETER_PAGE:
 459    case R_PGRAM_READ_ID:
 460                if (fifo_is_empty(&s->buffer)) {
 461                    DB_PRINT("read completed\n");
 462                    arasan_nfc_irq_event(s, R_INT_TRANS_COMP);
 463                    s->regs[R_PGRAM] = 0;
 464                }
 465        break;
 466    case R_PGRAM_READ_STATUS:
 467    case R_PGRAM_READ_STATUS_ENH:
 468                if (!fifo_is_empty(&s->buffer)) {
 469            AF_DP32(s->regs, FLASH_STATUS, FLASH_STATUS, fifo_pop8(&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        }
 475
 476        if (s->regs[R_PGRAM] & R_PGRAM_PAGE_PROGRAM) {
 477        arasan_nfc_do_dma(s, false);
 478    }
 479        if ((s->regs[R_PGRAM] & R_PGRAM_PAGE_PROGRAM) ||
 480        (s->regs[R_PGRAM] & R_PGRAM_SET_FEATURES)) {
 481                arasan_nfc_set_current(s);
 482                if (fifo_is_full(&s->buffer)) {
 483                        DB_PRINT("write completed\n");
 484                    arasan_nfc_irq_event(s, R_INT_TRANS_COMP);
 485                    /* We are slow - do everything at the end */
 486                nand_setpins(s->current, 0, 0, 0, 1, 0); /* data */
 487            if (arasan_nfc_write_check_ecc(s)) {
 488                arasan_nfc_ecc_init(s);
 489            }
 490                    while (!fifo_is_empty(&s->buffer)) {
 491                        uint8_t to_write = fifo_pop8(&s->buffer);
 492                if (arasan_nfc_write_check_ecc(s)) {
 493                    arasan_nfc_ecc_digest(s, to_write);
 494                }
 495                        nand_setio(s->current, to_write);
 496                                DB_PRINT("write byte %#02" PRIx8 "\n", to_write);
 497                    }
 498            if (arasan_nfc_write_check_ecc(s)) {
 499                arasan_nfc_do_cmd(s, 2, true, false);
 500                nand_setpins(s->current, 0, 0, 0, 1, 0); /* data */
 501                for (i = 0; i < AF_EX32(s->regs, ECC, ECC_SIZE); ++i) {
 502                    nand_setio(s->current, s->ecc_digest[i]);
 503                    DB_PRINT("write ecc byte %#02" PRIx8 "\n", s->ecc_digest[i]);
 504                }
 505            }
 506            if (s->regs[R_PGRAM] & R_PGRAM_PAGE_PROGRAM) {
 507                arasan_nfc_do_cmd2(s, false);
 508            }
 509                    s->regs[R_PGRAM] = 0;
 510        }
 511        }
 512
 513    packet_size = arasan_nfc_get_packet_size(s, s->regs[R_PGRAM]);
 514    s->regs[R_INT_STATUS] &= ~(R_INT_BUFF_RD_RDY | R_INT_BUFF_WR_RDY);
 515    s->regs[R_INT_STATUS] |= s->regs[R_INT_STATUS_EN] & (
 516            (s->buffer.num <= s->buffer.capacity - packet_size ?
 517                              R_INT_BUFF_WR_RDY : 0) |
 518            (s->buffer.num >= packet_size && packet_size ?
 519                              R_INT_BUFF_RD_RDY : 0));
 520
 521    qemu_set_irq(s->irq, !!(s->regs[R_INT_SIGNAL_EN] &
 522                            s->regs[R_INT_STATUS]));
 523
 524}
 525
 526static void arasan_nfc_update_state_pw(RegisterInfo *reg, uint64_t val)
 527{
 528    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 529
 530    arasan_nfc_update_state(s);
 531}
 532
 533static void arasan_nfc_reset(DeviceState *dev) {
 534    ArasanNFCState *s = ARASAN_NFC(dev);
 535
 536    /* Reset the registers */
 537    arasan_nfc_update_state(s);
 538}    
 539
 540static void arasan_nfc_r_unimp_post_write(RegisterInfo *reg, uint64_t val)
 541{
 542        fprintf(stderr, "unimplemented functionality touched\n");
 543}
 544
 545static uint64_t arasan_nfc_r_buffer_data_port_pr(RegisterInfo *reg, uint64_t val)
 546{
 547    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 548    int i;
 549    uint8_t buf[4];
 550
 551    memset(buf, 0, 4);
 552
 553    for (i = 0; i < 4 && !fifo_is_empty(&s->buffer); ++i) {
 554        buf[i] = fifo_pop8(&s->buffer);
 555    }
 556
 557    arasan_nfc_update_state(s);
 558    return cpu_to_le32(*((uint32_t *)buf));
 559}
 560
 561static void arasan_nfc_r_buffer_data_port_pw(RegisterInfo *reg, uint64_t val)
 562{
 563    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 564    int i;
 565    uint8_t buf[4];
 566
 567    if (!(s->regs[R_PGRAM] & R_PGRAM_PAGE_PROGRAM) &&
 568        !(s->regs[R_PGRAM] & R_PGRAM_SET_FEATURES)) {
 569        /* FIXME: Prettyify */
 570        qemu_log_mask(LOG_GUEST_ERROR, "Write to buffer data port with no data");
 571        return;
 572    }
 573
 574    *((uint32_t *)buf) = le32_to_cpu((uint32_t)val);
 575    for (i = 0; i < 4; ++i) {
 576        fifo_push8(&s->buffer, buf[i]);
 577    }
 578
 579        arasan_nfc_update_state(s);
 580}
 581
 582static void arasan_nfc_r_dma_system_addr1_pw(RegisterInfo *reg, uint64_t val)
 583{
 584    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 585
 586    arasan_nfc_sync_dma_addr(s);
 587}
 588
 589static void arasan_nfc_r_dma_system_addr_pw(RegisterInfo *reg, uint64_t val)
 590{
 591    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 592
 593    arasan_nfc_sync_dma_addr(s);
 594    s->dbb_blocked = false;
 595        arasan_nfc_update_state(s);
 596}
 597
 598static uint64_t r_program_pre_write(RegisterInfo *reg, uint64_t val)
 599{
 600    ArasanNFCState *s = ARASAN_NFC(reg->opaque);
 601    int i, j;
 602
 603    DB_PRINT("val = %#08" PRIx32 "\n", (uint32_t)val);
 604
 605    if (val && s->regs[R_PGRAM]) {
 606        qemu_log_mask(LOG_GUEST_ERROR, "%s:CMD already in progress", reg->prefix);
 607        return 0;
 608    }
 609
 610    arasan_nfc_set_current(s);
 611    for (i = 0; i < 32; ++i) {
 612        uint32_t pgram = val & (1 << i);
 613        uint32_t payload_size = arasan_nfc_get_packet_size(s, pgram) *
 614                                AF_EX32(s->regs, PACKET, PACKET_COUNT);
 615
 616        switch (pgram) {
 617            case R_PGRAM_READ_STATUS_ENH:
 618            case R_PGRAM_READ_STATUS:
 619            case R_PGRAM_PAGE_PROGRAM:
 620            case R_PGRAM_READ_ID:
 621            case R_PGRAM_SET_FEATURES:
 622            case R_PGRAM_GET_FEATURES:
 623            case R_PGRAM_READ_PARAMETER_PAGE:
 624            case R_PGRAM_READ:
 625                    fifo_destroy(&s->buffer);
 626                    fifo_create8(&s->buffer, payload_size);
 627        }
 628
 629        switch (pgram) {
 630        case R_PGRAM_RESET:
 631            arasan_nfc_do_cmd(s, 0, false, false);
 632                val &= ~R_PGRAM_RESET;
 633                    arasan_nfc_irq_event(s, R_INT_TRANS_COMP);
 634                break;
 635        case R_PGRAM_READ_ID:
 636                arasan_nfc_do_cmd(s, 1, false, false);
 637            break;
 638        case R_PGRAM_BLOCK_ERASE:
 639            arasan_nfc_do_cmd(s, 3, false, false);
 640            arasan_nfc_do_cmd2(s, false);
 641                val &= ~R_PGRAM_BLOCK_ERASE;
 642                    arasan_nfc_irq_event(s, R_INT_TRANS_COMP);
 643            break;
 644        case R_PGRAM_READ_STATUS:
 645            arasan_nfc_do_cmd(s, 0, false, true);
 646            break;
 647        case R_PGRAM_READ_STATUS_ENH:
 648            arasan_nfc_do_cmd(s, 3, false, true);
 649            break;
 650        case R_PGRAM_SET_FEATURES:
 651        case R_PGRAM_GET_FEATURES:
 652        case R_PGRAM_READ_PARAMETER_PAGE:
 653            arasan_nfc_do_cmd(s, 1, false, true);
 654            break;
 655        case R_PGRAM_READ:
 656            arasan_nfc_do_cmd(s, 5, false, false);
 657            arasan_nfc_do_cmd2(s, false);
 658            break;
 659        case R_PGRAM_PAGE_PROGRAM:
 660            arasan_nfc_do_cmd(s, 5, false, true);
 661            break;
 662        case 0:
 663            continue;
 664        default:
 665            arasan_nfc_r_unimp_post_write(reg, val);
 666            qemu_log_mask(LOG_UNIMP, "%s:Unimplemented CMD %" PRIx32, reg->prefix, pgram);
 667        }
 668
 669        /* we are fast! Do reads now now now!! */
 670        switch (pgram) {
 671        case R_PGRAM_READ_STATUS:
 672        case R_PGRAM_READ_STATUS_ENH:
 673        case R_PGRAM_READ_ID:
 674        case R_PGRAM_GET_FEATURES:
 675        case R_PGRAM_READ_PARAMETER_PAGE:
 676                nand_setpins(s->current, 0, 0, 0, 1, 0); /* data */
 677            for (j = 0; j < payload_size; ++j) {
 678                uint8_t to_read = nand_getio(s->current);
 679                fifo_push8(&s->buffer, to_read);
 680                DB_PRINT("read byte %#02" PRIx8 "\n", to_read);
 681            }
 682            break;
 683        case R_PGRAM_READ:
 684            if (arasan_nfc_ecc_enabled(s)) {
 685                s->regs[R_ECC_ERR_COUNT] = 0;
 686                arasan_nfc_ecc_init(s);
 687            }
 688            nand_setpins(s->current, 0, 0, 0, 1, 0); /* data */
 689            for (j = 0; j < payload_size; ++j) {
 690                uint8_t to_read = nand_getio(s->current);
 691                if (arasan_nfc_ecc_enabled(s)) {
 692                    arasan_nfc_ecc_digest(s, to_read);
 693                }
 694                fifo_push8(&s->buffer, to_read);
 695                DB_PRINT("read byte %#02" PRIx8 "\n", to_read);
 696            }
 697            /* FIXME: ECC is done backwards for reads, reading the payload
 698             * first, then the ECC data late. Real HW is the other way round.
 699             */
 700            if (arasan_nfc_ecc_enabled(s)) {
 701                arasan_nfc_do_cmd(s, 2, true, false);
 702                arasan_nfc_do_cmd2(s, true);
 703                for (j = 0; j < AF_EX32(s->regs, ECC, ECC_SIZE); ++j) {
 704                    s->ecc_oob[j] = nand_getio(s->current);
 705                    DB_PRINT("read ecc %#02" PRIx8 "\n", s->ecc_oob[j]);
 706                }
 707                arasan_nfc_ecc_correct(s);
 708            }
 709        }
 710    }
 711
 712    return val;
 713}
 714
 715static const MemoryRegionOps arasan_nfc_ops = {
 716    .read = register_read_memory_le,
 717    .write = register_write_memory_le,
 718    .endianness = DEVICE_NATIVE_ENDIAN,
 719    .valid = {
 720        .min_access_size = 4,
 721        .max_access_size = 4
 722    }
 723};
 724
 725static const RegisterAccessInfo arasan_nfc_regs_info[] = {
 726    {   .name = "Packet",                   .decode.addr = A_PACKET,
 727            .rsvd = R_PACKET_RSVD,
 728            .reset = 0x200 << R_PACKET_PACKET_SIZE_SHIFT,
 729    },{ .name = "Memory Address 1",         .decode.addr = A_MEMORY_ADDR_1,
 730    },{ .name = "Memory Address 2",         .decode.addr = A_MEMORY_ADDR_2,
 731            .rsvd = R_MEMORY_ADDR_2_RSVD,
 732            .post_write = arasan_nfc_update_state_pw,
 733    },{ .name = "CMD",                      .decode.addr = A_CMD,
 734            .rsvd = R_CMD_RSVD,
 735            .reset = 0x2 << R_CMD_PAGE_SIZE_SHIFT,
 736    },{ .name = "Program",                  .decode.addr = A_PGRAM,
 737            .rsvd = R_PGRAM_RSVD,
 738            .pre_write = r_program_pre_write,
 739            .post_write = arasan_nfc_update_state_pw,
 740    },{ .name = "Interrupt Status Enable",  .decode.addr = A_INT_STATUS_EN,
 741            .rsvd = R_INT_RSVD,
 742            .post_write = arasan_nfc_update_state_pw,
 743    },{ .name = "Interrupt Signal Enable",  .decode.addr = A_INT_SIGNAL_EN,
 744            .rsvd = R_INT_RSVD,
 745            .post_write = arasan_nfc_update_state_pw,
 746    },{ .name = "Interrupt Status",         .decode.addr = A_INT_STATUS,
 747            .rsvd = R_INT_RSVD,
 748            .w1c = R_INT_ANY,
 749            .post_write = arasan_nfc_update_state_pw,
 750    },{ .name = "Flash Status",             .decode.addr = A_FLASH_STATUS,
 751            .ro = ~0,
 752    },{ .name = "Timing",                   .decode.addr = A_TIMING,
 753            .reset = 0x6 << R_TIMING_DQS_BUFF_SEL_SHIFT,
 754    },{ .name = "Buffer Data Port",         .decode.addr = A_BUF_DATA_PORT,
 755            .post_write = arasan_nfc_r_buffer_data_port_pw,
 756            .post_read = arasan_nfc_r_buffer_data_port_pr,
 757    },{ .name = "ECC",                      .decode.addr = A_ECC,
 758        .rsvd = R_ECC_RSVD,
 759    },{ .name = "ECC Error Count",          .decode.addr = A_ECC_ERR_COUNT,
 760        .rsvd = R_ECC_ERR_COUNT_RSVD,
 761    },{ .name = "ECC Spare Command",        .decode.addr = A_ECC_SPARE_CMD,
 762        .rsvd = R_ECC_SPARE_CMD_RSVD,
 763    },{ .name = "DMA System Addr High",     .decode.addr = A_DMA_SYSTEM_ADDR1,
 764            .post_write = arasan_nfc_r_dma_system_addr1_pw,
 765    },{ .name = "DMA System Addr Low",      .decode.addr = A_DMA_SYSTEM_ADDR0,
 766            .post_write = arasan_nfc_r_dma_system_addr_pw,
 767    },{ .name = "DMA Buffer Boundary",      .decode.addr = A_DMA_BUF_BOUNDARY,
 768            .rsvd = R_DMA_BUF_BOUNDARY_RSVD,
 769    },{ .name = "Data Interface",           .decode.addr = A_DATA_INTERFACE,
 770            .rsvd = R_DATA_INTERFACE_RSVD,
 771    },
 772};
 773
 774static void arasan_nfc_realize(DeviceState *dev, Error ** errp)
 775{
 776    ArasanNFCState *s = ARASAN_NFC(dev);
 777    const char *prefix = object_get_canonical_path(OBJECT(dev));
 778    DriveInfo *dinfo;
 779    int i;
 780
 781    /* FIXME: add support for multiple chips */
 782    dinfo = drive_get_next(IF_PFLASH);
 783    if (dinfo) {
 784        s->nand[0] = nand_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
 785                               NAND_MFR_MICRON, 0x44);
 786    }
 787    dinfo = drive_get_next(IF_PFLASH);
 788    if (dinfo) {
 789        s->nand[1] = nand_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
 790                               NAND_MFR_MICRON, 0x44);
 791    }
 792    for (i = 0; i < ARRAY_SIZE(arasan_nfc_regs_info); ++i) {
 793        RegisterInfo *r = &s->regs_info[i];
 794
 795        *r = (RegisterInfo) {
 796            .data = &s->regs[arasan_nfc_regs_info[i].decode.addr/4],
 797            .data_size = sizeof(uint32_t),
 798            .access = &arasan_nfc_regs_info[i],
 799            .debug = qemu_loglevel_mask(DEV_LOG_NANDC),
 800            .prefix = prefix,
 801            .opaque = s,
 802        };
 803        memory_region_init_io(&r->mem, OBJECT(dev), &arasan_nfc_ops, r,
 804                              r->access->name, 4);
 805        memory_region_add_subregion(&s->iomem, r->access->decode.addr, &r->mem);
 806    }
 807
 808    fifo_create8(&s->buffer, 1);
 809
 810    s->dma_as = s->dma_mr ? address_space_init_shareable(s->dma_mr, NULL)
 811                          : &address_space_memory;
 812}
 813
 814static void arasan_nfc_init(Object *obj)
 815{
 816    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 817    ArasanNFCState *s = ARASAN_NFC(obj);
 818
 819    object_property_add_link(obj, "nand0", TYPE_DEVICE,
 820                             (Object **)&s->nand[0],
 821                             object_property_allow_set_link,
 822                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 823                             &error_abort);
 824    object_property_add_link(obj, "nand1", TYPE_DEVICE,
 825                             (Object **)&s->nand[1],
 826                             object_property_allow_set_link,
 827                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 828                             &error_abort);
 829
 830    sysbus_init_irq(sbd, &s->irq);
 831
 832    memory_region_init(&s->iomem, obj, "nand", R_MAX*4);
 833    sysbus_init_mmio(sbd, &s->iomem);
 834
 835    object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
 836                             (Object **)&s->dma_mr,
 837                             qdev_prop_allow_set_link_before_realize,
 838                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 839                             &error_abort);
 840}
 841
 842static Property arasan_nfc_properties[] = {
 843    DEFINE_PROP_UINT8("num-cs", ArasanNFCState, num_cs, 2),
 844    DEFINE_PROP_BOOL("has-mdma", ArasanNFCState, has_mdma, true),
 845    DEFINE_PROP_BOOL("boot-en", ArasanNFCState, boot_en, false),
 846    DEFINE_PROP_END_OF_LIST(),
 847};
 848
 849static const VMStateDescription vmstate_arasan_nfc = {
 850    .name = TYPE_ARASAN_NFC,
 851    .version_id = 1,
 852    .minimum_version_id = 1,
 853    .fields = (VMStateField[]) {
 854        VMSTATE_END_OF_LIST()
 855    }
 856};
 857
 858static void arasan_nfc_class_init(ObjectClass *klass, void *data)
 859{
 860    DeviceClass *dc = DEVICE_CLASS(klass);
 861
 862    dc->reset = arasan_nfc_reset;
 863    dc->realize = arasan_nfc_realize;
 864    dc->props = arasan_nfc_properties;
 865    dc->vmsd = &vmstate_arasan_nfc;
 866}
 867
 868static TypeInfo arasan_nfc_info = {
 869    .name           = TYPE_ARASAN_NFC,
 870    .parent         = TYPE_SYS_BUS_DEVICE,
 871    .instance_size  = sizeof(ArasanNFCState),
 872    .class_init     = arasan_nfc_class_init,
 873    .instance_init  = arasan_nfc_init,
 874};
 875
 876static void arasan_nfc_register_types(void)
 877{
 878    type_register_static(&arasan_nfc_info);
 879}
 880
 881type_init(arasan_nfc_register_types)
 882