qemu/hw/ssi/aspeed_smc.c
<<
>>
Prefs
   1/*
   2 * ASPEED AST2400 SMC Controller (SPI Flash Only)
   3 *
   4 * Copyright (C) 2016 IBM Corp.
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24
  25#include "qemu/osdep.h"
  26#include "hw/sysbus.h"
  27#include "sysemu/sysemu.h"
  28#include "qemu/log.h"
  29#include "qemu/error-report.h"
  30
  31#include "hw/ssi/aspeed_smc.h"
  32
  33/* CE Type Setting Register */
  34#define R_CONF            (0x00 / 4)
  35#define   CONF_LEGACY_DISABLE  (1 << 31)
  36#define   CONF_ENABLE_W4       20
  37#define   CONF_ENABLE_W3       19
  38#define   CONF_ENABLE_W2       18
  39#define   CONF_ENABLE_W1       17
  40#define   CONF_ENABLE_W0       16
  41#define   CONF_FLASH_TYPE4     8
  42#define   CONF_FLASH_TYPE3     6
  43#define   CONF_FLASH_TYPE2     4
  44#define   CONF_FLASH_TYPE1     2
  45#define   CONF_FLASH_TYPE0     0
  46#define      CONF_FLASH_TYPE_NOR   0x0
  47#define      CONF_FLASH_TYPE_NAND  0x1
  48#define      CONF_FLASH_TYPE_SPI   0x2
  49
  50/* CE Control Register */
  51#define R_CE_CTRL            (0x04 / 4)
  52#define   CTRL_EXTENDED4       4  /* 32 bit addressing for SPI */
  53#define   CTRL_EXTENDED3       3  /* 32 bit addressing for SPI */
  54#define   CTRL_EXTENDED2       2  /* 32 bit addressing for SPI */
  55#define   CTRL_EXTENDED1       1  /* 32 bit addressing for SPI */
  56#define   CTRL_EXTENDED0       0  /* 32 bit addressing for SPI */
  57
  58/* Interrupt Control and Status Register */
  59#define R_INTR_CTRL       (0x08 / 4)
  60#define   INTR_CTRL_DMA_STATUS            (1 << 11)
  61#define   INTR_CTRL_CMD_ABORT_STATUS      (1 << 10)
  62#define   INTR_CTRL_WRITE_PROTECT_STATUS  (1 << 9)
  63#define   INTR_CTRL_DMA_EN                (1 << 3)
  64#define   INTR_CTRL_CMD_ABORT_EN          (1 << 2)
  65#define   INTR_CTRL_WRITE_PROTECT_EN      (1 << 1)
  66
  67/* CEx Control Register */
  68#define R_CTRL0           (0x10 / 4)
  69#define   CTRL_IO_DUAL_DATA        (1 << 29)
  70#define   CTRL_IO_DUAL_ADDR_DATA   (1 << 28) /* Includes dummies */
  71#define   CTRL_CMD_SHIFT           16
  72#define   CTRL_CMD_MASK            0xff
  73#define   CTRL_DUMMY_HIGH_SHIFT    14
  74#define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
  75#define   CTRL_DUMMY_LOW_SHIFT     6 /* 2 bits [7:6] */
  76#define   CTRL_CE_STOP_ACTIVE      (1 << 2)
  77#define   CTRL_CMD_MODE_MASK       0x3
  78#define     CTRL_READMODE          0x0
  79#define     CTRL_FREADMODE         0x1
  80#define     CTRL_WRITEMODE         0x2
  81#define     CTRL_USERMODE          0x3
  82#define R_CTRL1           (0x14 / 4)
  83#define R_CTRL2           (0x18 / 4)
  84#define R_CTRL3           (0x1C / 4)
  85#define R_CTRL4           (0x20 / 4)
  86
  87/* CEx Segment Address Register */
  88#define R_SEG_ADDR0       (0x30 / 4)
  89#define   SEG_END_SHIFT        24   /* 8MB units */
  90#define   SEG_END_MASK         0xff
  91#define   SEG_START_SHIFT      16   /* address bit [A29-A23] */
  92#define   SEG_START_MASK       0xff
  93#define R_SEG_ADDR1       (0x34 / 4)
  94#define R_SEG_ADDR2       (0x38 / 4)
  95#define R_SEG_ADDR3       (0x3C / 4)
  96#define R_SEG_ADDR4       (0x40 / 4)
  97
  98/* Misc Control Register #1 */
  99#define R_MISC_CTRL1      (0x50 / 4)
 100
 101/* Misc Control Register #2 */
 102#define R_MISC_CTRL2      (0x54 / 4)
 103
 104/* DMA Control/Status Register */
 105#define R_DMA_CTRL        (0x80 / 4)
 106#define   DMA_CTRL_DELAY_MASK   0xf
 107#define   DMA_CTRL_DELAY_SHIFT  8
 108#define   DMA_CTRL_FREQ_MASK    0xf
 109#define   DMA_CTRL_FREQ_SHIFT   4
 110#define   DMA_CTRL_MODE         (1 << 3)
 111#define   DMA_CTRL_CKSUM        (1 << 2)
 112#define   DMA_CTRL_DIR          (1 << 1)
 113#define   DMA_CTRL_EN           (1 << 0)
 114
 115/* DMA Flash Side Address */
 116#define R_DMA_FLASH_ADDR  (0x84 / 4)
 117
 118/* DMA DRAM Side Address */
 119#define R_DMA_DRAM_ADDR   (0x88 / 4)
 120
 121/* DMA Length Register */
 122#define R_DMA_LEN         (0x8C / 4)
 123
 124/* Checksum Calculation Result */
 125#define R_DMA_CHECKSUM    (0x90 / 4)
 126
 127/* Misc Control Register #2 */
 128#define R_TIMINGS         (0x94 / 4)
 129
 130/* SPI controller registers and bits */
 131#define R_SPI_CONF        (0x00 / 4)
 132#define   SPI_CONF_ENABLE_W0   0
 133#define R_SPI_CTRL0       (0x4 / 4)
 134#define R_SPI_MISC_CTRL   (0x10 / 4)
 135#define R_SPI_TIMINGS     (0x14 / 4)
 136
 137#define ASPEED_SMC_R_SPI_MAX (0x20 / 4)
 138#define ASPEED_SMC_R_SMC_MAX (0x20 / 4)
 139
 140#define ASPEED_SOC_SMC_FLASH_BASE   0x10000000
 141#define ASPEED_SOC_FMC_FLASH_BASE   0x20000000
 142#define ASPEED_SOC_SPI_FLASH_BASE   0x30000000
 143#define ASPEED_SOC_SPI2_FLASH_BASE  0x38000000
 144
 145/* Flash opcodes. */
 146#define SPI_OP_READ       0x03    /* Read data bytes (low frequency) */
 147
 148/*
 149 * Default segments mapping addresses and size for each slave per
 150 * controller. These can be changed when board is initialized with the
 151 * Segment Address Registers.
 152 */
 153static const AspeedSegments aspeed_segments_legacy[] = {
 154    { 0x10000000, 32 * 1024 * 1024 },
 155};
 156
 157static const AspeedSegments aspeed_segments_fmc[] = {
 158    { 0x20000000, 64 * 1024 * 1024 }, /* start address is readonly */
 159    { 0x24000000, 32 * 1024 * 1024 },
 160    { 0x26000000, 32 * 1024 * 1024 },
 161    { 0x28000000, 32 * 1024 * 1024 },
 162    { 0x2A000000, 32 * 1024 * 1024 }
 163};
 164
 165static const AspeedSegments aspeed_segments_spi[] = {
 166    { 0x30000000, 64 * 1024 * 1024 },
 167};
 168
 169static const AspeedSegments aspeed_segments_ast2500_fmc[] = {
 170    { 0x20000000, 128 * 1024 * 1024 }, /* start address is readonly */
 171    { 0x28000000,  32 * 1024 * 1024 },
 172    { 0x2A000000,  32 * 1024 * 1024 },
 173};
 174
 175static const AspeedSegments aspeed_segments_ast2500_spi1[] = {
 176    { 0x30000000, 32 * 1024 * 1024 }, /* start address is readonly */
 177    { 0x32000000, 96 * 1024 * 1024 }, /* end address is readonly */
 178};
 179
 180static const AspeedSegments aspeed_segments_ast2500_spi2[] = {
 181    { 0x38000000, 32 * 1024 * 1024 }, /* start address is readonly */
 182    { 0x3A000000, 96 * 1024 * 1024 }, /* end address is readonly */
 183};
 184
 185static const AspeedSMCController controllers[] = {
 186    {
 187        .name              = "aspeed.smc.smc",
 188        .r_conf            = R_CONF,
 189        .r_ce_ctrl         = R_CE_CTRL,
 190        .r_ctrl0           = R_CTRL0,
 191        .r_timings         = R_TIMINGS,
 192        .conf_enable_w0    = CONF_ENABLE_W0,
 193        .max_slaves        = 5,
 194        .segments          = aspeed_segments_legacy,
 195        .flash_window_base = ASPEED_SOC_SMC_FLASH_BASE,
 196        .flash_window_size = 0x6000000,
 197        .has_dma           = false,
 198        .nregs             = ASPEED_SMC_R_SMC_MAX,
 199    }, {
 200        .name              = "aspeed.smc.fmc",
 201        .r_conf            = R_CONF,
 202        .r_ce_ctrl         = R_CE_CTRL,
 203        .r_ctrl0           = R_CTRL0,
 204        .r_timings         = R_TIMINGS,
 205        .conf_enable_w0    = CONF_ENABLE_W0,
 206        .max_slaves        = 5,
 207        .segments          = aspeed_segments_fmc,
 208        .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
 209        .flash_window_size = 0x10000000,
 210        .has_dma           = true,
 211        .nregs             = ASPEED_SMC_R_MAX,
 212    }, {
 213        .name              = "aspeed.smc.spi",
 214        .r_conf            = R_SPI_CONF,
 215        .r_ce_ctrl         = 0xff,
 216        .r_ctrl0           = R_SPI_CTRL0,
 217        .r_timings         = R_SPI_TIMINGS,
 218        .conf_enable_w0    = SPI_CONF_ENABLE_W0,
 219        .max_slaves        = 1,
 220        .segments          = aspeed_segments_spi,
 221        .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
 222        .flash_window_size = 0x10000000,
 223        .has_dma           = false,
 224        .nregs             = ASPEED_SMC_R_SPI_MAX,
 225    }, {
 226        .name              = "aspeed.smc.ast2500-fmc",
 227        .r_conf            = R_CONF,
 228        .r_ce_ctrl         = R_CE_CTRL,
 229        .r_ctrl0           = R_CTRL0,
 230        .r_timings         = R_TIMINGS,
 231        .conf_enable_w0    = CONF_ENABLE_W0,
 232        .max_slaves        = 3,
 233        .segments          = aspeed_segments_ast2500_fmc,
 234        .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
 235        .flash_window_size = 0x10000000,
 236        .has_dma           = true,
 237        .nregs             = ASPEED_SMC_R_MAX,
 238    }, {
 239        .name              = "aspeed.smc.ast2500-spi1",
 240        .r_conf            = R_CONF,
 241        .r_ce_ctrl         = R_CE_CTRL,
 242        .r_ctrl0           = R_CTRL0,
 243        .r_timings         = R_TIMINGS,
 244        .conf_enable_w0    = CONF_ENABLE_W0,
 245        .max_slaves        = 2,
 246        .segments          = aspeed_segments_ast2500_spi1,
 247        .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
 248        .flash_window_size = 0x8000000,
 249        .has_dma           = false,
 250        .nregs             = ASPEED_SMC_R_MAX,
 251    }, {
 252        .name              = "aspeed.smc.ast2500-spi2",
 253        .r_conf            = R_CONF,
 254        .r_ce_ctrl         = R_CE_CTRL,
 255        .r_ctrl0           = R_CTRL0,
 256        .r_timings         = R_TIMINGS,
 257        .conf_enable_w0    = CONF_ENABLE_W0,
 258        .max_slaves        = 2,
 259        .segments          = aspeed_segments_ast2500_spi2,
 260        .flash_window_base = ASPEED_SOC_SPI2_FLASH_BASE,
 261        .flash_window_size = 0x8000000,
 262        .has_dma           = false,
 263        .nregs             = ASPEED_SMC_R_MAX,
 264    },
 265};
 266
 267/*
 268 * The Segment Register uses a 8MB unit to encode the start address
 269 * and the end address of the mapping window of a flash SPI slave :
 270 *
 271 *        | byte 1 | byte 2 | byte 3 | byte 4 |
 272 *        +--------+--------+--------+--------+
 273 *        |  end   |  start |   0    |   0    |
 274 *
 275 */
 276static inline uint32_t aspeed_smc_segment_to_reg(const AspeedSegments *seg)
 277{
 278    uint32_t reg = 0;
 279    reg |= ((seg->addr >> 23) & SEG_START_MASK) << SEG_START_SHIFT;
 280    reg |= (((seg->addr + seg->size) >> 23) & SEG_END_MASK) << SEG_END_SHIFT;
 281    return reg;
 282}
 283
 284static inline void aspeed_smc_reg_to_segment(uint32_t reg, AspeedSegments *seg)
 285{
 286    seg->addr = ((reg >> SEG_START_SHIFT) & SEG_START_MASK) << 23;
 287    seg->size = (((reg >> SEG_END_SHIFT) & SEG_END_MASK) << 23) - seg->addr;
 288}
 289
 290static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
 291                                     const AspeedSegments *new,
 292                                     int cs)
 293{
 294    AspeedSegments seg;
 295    int i;
 296
 297    for (i = 0; i < s->ctrl->max_slaves; i++) {
 298        if (i == cs) {
 299            continue;
 300        }
 301
 302        aspeed_smc_reg_to_segment(s->regs[R_SEG_ADDR0 + i], &seg);
 303
 304        if (new->addr + new->size > seg.addr &&
 305            new->addr < seg.addr + seg.size) {
 306            qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment CS%d [ 0x%"
 307                          HWADDR_PRIx" - 0x%"HWADDR_PRIx" ] overlaps with "
 308                          "CS%d [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
 309                          s->ctrl->name, cs, new->addr, new->addr + new->size,
 310                          i, seg.addr, seg.addr + seg.size);
 311            return true;
 312        }
 313    }
 314    return false;
 315}
 316
 317static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
 318                                         uint64_t new)
 319{
 320    AspeedSMCFlash *fl = &s->flashes[cs];
 321    AspeedSegments seg;
 322
 323    aspeed_smc_reg_to_segment(new, &seg);
 324
 325    /* The start address of CS0 is read-only */
 326    if (cs == 0 && seg.addr != s->ctrl->flash_window_base) {
 327        qemu_log_mask(LOG_GUEST_ERROR,
 328                      "%s: Tried to change CS0 start address to 0x%"
 329                      HWADDR_PRIx "\n", s->ctrl->name, seg.addr);
 330        seg.addr = s->ctrl->flash_window_base;
 331        new = aspeed_smc_segment_to_reg(&seg);
 332    }
 333
 334    /*
 335     * The end address of the AST2500 spi controllers is also
 336     * read-only.
 337     */
 338    if ((s->ctrl->segments == aspeed_segments_ast2500_spi1 ||
 339         s->ctrl->segments == aspeed_segments_ast2500_spi2) &&
 340        cs == s->ctrl->max_slaves &&
 341        seg.addr + seg.size != s->ctrl->segments[cs].addr +
 342        s->ctrl->segments[cs].size) {
 343        qemu_log_mask(LOG_GUEST_ERROR,
 344                      "%s: Tried to change CS%d end address to 0x%"
 345                      HWADDR_PRIx "\n", s->ctrl->name, cs, seg.addr + seg.size);
 346        seg.size = s->ctrl->segments[cs].addr + s->ctrl->segments[cs].size -
 347            seg.addr;
 348        new = aspeed_smc_segment_to_reg(&seg);
 349    }
 350
 351    /* Keep the segment in the overall flash window */
 352    if (seg.addr + seg.size <= s->ctrl->flash_window_base ||
 353        seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) {
 354        qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
 355                      "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
 356                      s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
 357        return;
 358    }
 359
 360    /* Check start address vs. alignment */
 361    if (seg.size && !QEMU_IS_ALIGNED(seg.addr, seg.size)) {
 362        qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is not "
 363                      "aligned : [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
 364                      s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
 365    }
 366
 367    /* And segments should not overlap (in the specs) */
 368    aspeed_smc_flash_overlap(s, &seg, cs);
 369
 370    /* All should be fine now to move the region */
 371    memory_region_transaction_begin();
 372    memory_region_set_size(&fl->mmio, seg.size);
 373    memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
 374    memory_region_set_enabled(&fl->mmio, true);
 375    memory_region_transaction_commit();
 376
 377    s->regs[R_SEG_ADDR0 + cs] = new;
 378}
 379
 380static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
 381                                              unsigned size)
 382{
 383    qemu_log_mask(LOG_GUEST_ERROR, "%s: To 0x%" HWADDR_PRIx " of size %u"
 384                  PRIx64 "\n", __func__, addr, size);
 385    return 0;
 386}
 387
 388static void aspeed_smc_flash_default_write(void *opaque, hwaddr addr,
 389                                           uint64_t data, unsigned size)
 390{
 391   qemu_log_mask(LOG_GUEST_ERROR, "%s: To 0x%" HWADDR_PRIx " of size %u: 0x%"
 392                 PRIx64 "\n", __func__, addr, size, data);
 393}
 394
 395static const MemoryRegionOps aspeed_smc_flash_default_ops = {
 396    .read = aspeed_smc_flash_default_read,
 397    .write = aspeed_smc_flash_default_write,
 398    .endianness = DEVICE_LITTLE_ENDIAN,
 399    .valid = {
 400        .min_access_size = 1,
 401        .max_access_size = 4,
 402    },
 403};
 404
 405static inline int aspeed_smc_flash_mode(const AspeedSMCFlash *fl)
 406{
 407    const AspeedSMCState *s = fl->controller;
 408
 409    return s->regs[s->r_ctrl0 + fl->id] & CTRL_CMD_MODE_MASK;
 410}
 411
 412static inline bool aspeed_smc_is_writable(const AspeedSMCFlash *fl)
 413{
 414    const AspeedSMCState *s = fl->controller;
 415
 416    return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->id));
 417}
 418
 419static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
 420{
 421    const AspeedSMCState *s = fl->controller;
 422    int cmd = (s->regs[s->r_ctrl0 + fl->id] >> CTRL_CMD_SHIFT) & CTRL_CMD_MASK;
 423
 424    /* In read mode, the default SPI command is READ (0x3). In other
 425     * modes, the command should necessarily be defined */
 426    if (aspeed_smc_flash_mode(fl) == CTRL_READMODE) {
 427        cmd = SPI_OP_READ;
 428    }
 429
 430    if (!cmd) {
 431        qemu_log_mask(LOG_GUEST_ERROR, "%s: no command defined for mode %d\n",
 432                      __func__, aspeed_smc_flash_mode(fl));
 433    }
 434
 435    return cmd;
 436}
 437
 438static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl)
 439{
 440    const AspeedSMCState *s = fl->controller;
 441
 442    if (s->ctrl->segments == aspeed_segments_spi) {
 443        return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
 444    } else {
 445        return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->id));
 446    }
 447}
 448
 449static inline bool aspeed_smc_is_ce_stop_active(const AspeedSMCFlash *fl)
 450{
 451    const AspeedSMCState *s = fl->controller;
 452
 453    return s->regs[s->r_ctrl0 + fl->id] & CTRL_CE_STOP_ACTIVE;
 454}
 455
 456static void aspeed_smc_flash_select(AspeedSMCFlash *fl)
 457{
 458    AspeedSMCState *s = fl->controller;
 459
 460    s->regs[s->r_ctrl0 + fl->id] &= ~CTRL_CE_STOP_ACTIVE;
 461    qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
 462}
 463
 464static void aspeed_smc_flash_unselect(AspeedSMCFlash *fl)
 465{
 466    AspeedSMCState *s = fl->controller;
 467
 468    s->regs[s->r_ctrl0 + fl->id] |= CTRL_CE_STOP_ACTIVE;
 469    qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
 470}
 471
 472static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
 473                                              uint32_t addr)
 474{
 475    const AspeedSMCState *s = fl->controller;
 476    AspeedSegments seg;
 477
 478    aspeed_smc_reg_to_segment(s->regs[R_SEG_ADDR0 + fl->id], &seg);
 479    if ((addr % seg.size) != addr) {
 480        qemu_log_mask(LOG_GUEST_ERROR,
 481                      "%s: invalid address 0x%08x for CS%d segment : "
 482                      "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
 483                      s->ctrl->name, addr, fl->id, seg.addr,
 484                      seg.addr + seg.size);
 485        addr %= seg.size;
 486    }
 487
 488    return addr;
 489}
 490
 491static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
 492{
 493    const AspeedSMCState *s = fl->controller;
 494    uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->id];
 495    uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
 496    uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
 497    uint32_t dummies = ((dummy_high << 2) | dummy_low) * 8;
 498
 499    if (r_ctrl0 & CTRL_IO_DUAL_ADDR_DATA) {
 500        dummies /= 2;
 501    }
 502
 503    return dummies;
 504}
 505
 506static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr)
 507{
 508    const AspeedSMCState *s = fl->controller;
 509    uint8_t cmd = aspeed_smc_flash_cmd(fl);
 510    int i;
 511
 512    /* Flash access can not exceed CS segment */
 513    addr = aspeed_smc_check_segment_addr(fl, addr);
 514
 515    ssi_transfer(s->spi, cmd);
 516
 517    if (aspeed_smc_flash_is_4byte(fl)) {
 518        ssi_transfer(s->spi, (addr >> 24) & 0xff);
 519    }
 520    ssi_transfer(s->spi, (addr >> 16) & 0xff);
 521    ssi_transfer(s->spi, (addr >> 8) & 0xff);
 522    ssi_transfer(s->spi, (addr & 0xff));
 523
 524    /*
 525     * Use fake transfers to model dummy bytes. The value should
 526     * be configured to some non-zero value in fast read mode and
 527     * zero in read mode. But, as the HW allows inconsistent
 528     * settings, let's check for fast read mode.
 529     */
 530    if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) {
 531        for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
 532                ssi_transfer(fl->controller->spi, 0xFF);
 533        }
 534    }
 535}
 536
 537static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
 538{
 539    AspeedSMCFlash *fl = opaque;
 540    AspeedSMCState *s = fl->controller;
 541    uint64_t ret = 0;
 542    int i;
 543
 544    switch (aspeed_smc_flash_mode(fl)) {
 545    case CTRL_USERMODE:
 546        for (i = 0; i < size; i++) {
 547            ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
 548        }
 549        break;
 550    case CTRL_READMODE:
 551    case CTRL_FREADMODE:
 552        aspeed_smc_flash_select(fl);
 553        aspeed_smc_flash_setup(fl, addr);
 554
 555        for (i = 0; i < size; i++) {
 556            ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
 557        }
 558
 559        aspeed_smc_flash_unselect(fl);
 560        break;
 561    default:
 562        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid flash mode %d\n",
 563                      __func__, aspeed_smc_flash_mode(fl));
 564    }
 565
 566    return ret;
 567}
 568
 569static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
 570                           unsigned size)
 571{
 572    AspeedSMCFlash *fl = opaque;
 573    AspeedSMCState *s = fl->controller;
 574    int i;
 575
 576    if (!aspeed_smc_is_writable(fl)) {
 577        qemu_log_mask(LOG_GUEST_ERROR, "%s: flash is not writable at 0x%"
 578                      HWADDR_PRIx "\n", __func__, addr);
 579        return;
 580    }
 581
 582    switch (aspeed_smc_flash_mode(fl)) {
 583    case CTRL_USERMODE:
 584        for (i = 0; i < size; i++) {
 585            ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
 586        }
 587        break;
 588    case CTRL_WRITEMODE:
 589        aspeed_smc_flash_select(fl);
 590        aspeed_smc_flash_setup(fl, addr);
 591
 592        for (i = 0; i < size; i++) {
 593            ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
 594        }
 595
 596        aspeed_smc_flash_unselect(fl);
 597        break;
 598    default:
 599        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid flash mode %d\n",
 600                      __func__, aspeed_smc_flash_mode(fl));
 601    }
 602}
 603
 604static const MemoryRegionOps aspeed_smc_flash_ops = {
 605    .read = aspeed_smc_flash_read,
 606    .write = aspeed_smc_flash_write,
 607    .endianness = DEVICE_LITTLE_ENDIAN,
 608    .valid = {
 609        .min_access_size = 1,
 610        .max_access_size = 4,
 611    },
 612};
 613
 614static void aspeed_smc_flash_update_cs(AspeedSMCFlash *fl)
 615{
 616    const AspeedSMCState *s = fl->controller;
 617
 618    qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
 619}
 620
 621static void aspeed_smc_reset(DeviceState *d)
 622{
 623    AspeedSMCState *s = ASPEED_SMC(d);
 624    int i;
 625
 626    memset(s->regs, 0, sizeof s->regs);
 627
 628    /* Pretend DMA is done (u-boot initialization) */
 629    s->regs[R_INTR_CTRL] = INTR_CTRL_DMA_STATUS;
 630
 631    /* Unselect all slaves */
 632    for (i = 0; i < s->num_cs; ++i) {
 633        s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
 634        qemu_set_irq(s->cs_lines[i], true);
 635    }
 636
 637    /* setup default segment register values for all */
 638    for (i = 0; i < s->ctrl->max_slaves; ++i) {
 639        s->regs[R_SEG_ADDR0 + i] =
 640            aspeed_smc_segment_to_reg(&s->ctrl->segments[i]);
 641    }
 642
 643    /* HW strapping flash type for FMC controllers  */
 644    if (s->ctrl->segments == aspeed_segments_ast2500_fmc) {
 645        /* flash type is fixed to SPI for CE0 and CE1 */
 646        s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
 647        s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1);
 648    }
 649
 650    /* HW strapping for AST2400 FMC controllers (SCU70). Let's use the
 651     * configuration of the palmetto-bmc machine */
 652    if (s->ctrl->segments == aspeed_segments_fmc) {
 653        s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
 654    }
 655}
 656
 657static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
 658{
 659    AspeedSMCState *s = ASPEED_SMC(opaque);
 660
 661    addr >>= 2;
 662
 663    if (addr == s->r_conf ||
 664        addr == s->r_timings ||
 665        addr == s->r_ce_ctrl ||
 666        addr == R_INTR_CTRL ||
 667        (addr >= R_SEG_ADDR0 && addr < R_SEG_ADDR0 + s->ctrl->max_slaves) ||
 668        (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs)) {
 669        return s->regs[addr];
 670    } else {
 671        qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
 672                      __func__, addr);
 673        return 0;
 674    }
 675}
 676
 677static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
 678                             unsigned int size)
 679{
 680    AspeedSMCState *s = ASPEED_SMC(opaque);
 681    uint32_t value = data;
 682
 683    addr >>= 2;
 684
 685    if (addr == s->r_conf ||
 686        addr == s->r_timings ||
 687        addr == s->r_ce_ctrl) {
 688        s->regs[addr] = value;
 689    } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
 690        int cs = addr - s->r_ctrl0;
 691        s->regs[addr] = value;
 692        aspeed_smc_flash_update_cs(&s->flashes[cs]);
 693    } else if (addr >= R_SEG_ADDR0 &&
 694               addr < R_SEG_ADDR0 + s->ctrl->max_slaves) {
 695        int cs = addr - R_SEG_ADDR0;
 696
 697        if (value != s->regs[R_SEG_ADDR0 + cs]) {
 698            aspeed_smc_flash_set_segment(s, cs, value);
 699        }
 700    } else {
 701        qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
 702                      __func__, addr);
 703        return;
 704    }
 705}
 706
 707static const MemoryRegionOps aspeed_smc_ops = {
 708    .read = aspeed_smc_read,
 709    .write = aspeed_smc_write,
 710    .endianness = DEVICE_LITTLE_ENDIAN,
 711    .valid.unaligned = true,
 712};
 713
 714static void aspeed_smc_realize(DeviceState *dev, Error **errp)
 715{
 716    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 717    AspeedSMCState *s = ASPEED_SMC(dev);
 718    AspeedSMCClass *mc = ASPEED_SMC_GET_CLASS(s);
 719    int i;
 720    char name[32];
 721    hwaddr offset = 0;
 722
 723    s->ctrl = mc->ctrl;
 724
 725    /* keep a copy under AspeedSMCState to speed up accesses */
 726    s->r_conf = s->ctrl->r_conf;
 727    s->r_ce_ctrl = s->ctrl->r_ce_ctrl;
 728    s->r_ctrl0 = s->ctrl->r_ctrl0;
 729    s->r_timings = s->ctrl->r_timings;
 730    s->conf_enable_w0 = s->ctrl->conf_enable_w0;
 731
 732    /* Enforce some real HW limits */
 733    if (s->num_cs > s->ctrl->max_slaves) {
 734        qemu_log_mask(LOG_GUEST_ERROR, "%s: num_cs cannot exceed: %d\n",
 735                      __func__, s->ctrl->max_slaves);
 736        s->num_cs = s->ctrl->max_slaves;
 737    }
 738
 739    s->spi = ssi_create_bus(dev, "spi");
 740
 741    /* Setup cs_lines for slaves */
 742    sysbus_init_irq(sbd, &s->irq);
 743    s->cs_lines = g_new0(qemu_irq, s->num_cs);
 744    ssi_auto_connect_slaves(dev, s->cs_lines, s->spi);
 745
 746    for (i = 0; i < s->num_cs; ++i) {
 747        sysbus_init_irq(sbd, &s->cs_lines[i]);
 748    }
 749
 750    /* The memory region for the controller registers */
 751    memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
 752                          s->ctrl->name, s->ctrl->nregs * 4);
 753    sysbus_init_mmio(sbd, &s->mmio);
 754
 755    /*
 756     * The container memory region representing the address space
 757     * window in which the flash modules are mapped. The size and
 758     * address depends on the SoC model and controller type.
 759     */
 760    snprintf(name, sizeof(name), "%s.flash", s->ctrl->name);
 761
 762    memory_region_init_io(&s->mmio_flash, OBJECT(s),
 763                          &aspeed_smc_flash_default_ops, s, name,
 764                          s->ctrl->flash_window_size);
 765    sysbus_init_mmio(sbd, &s->mmio_flash);
 766
 767    s->flashes = g_new0(AspeedSMCFlash, s->ctrl->max_slaves);
 768
 769    /*
 770     * Let's create a sub memory region for each possible slave. All
 771     * have a configurable memory segment in the overall flash mapping
 772     * window of the controller but, there is not necessarily a flash
 773     * module behind to handle the memory accesses. This depends on
 774     * the board configuration.
 775     */
 776    for (i = 0; i < s->ctrl->max_slaves; ++i) {
 777        AspeedSMCFlash *fl = &s->flashes[i];
 778
 779        snprintf(name, sizeof(name), "%s.%d", s->ctrl->name, i);
 780
 781        fl->id = i;
 782        fl->controller = s;
 783        fl->size = s->ctrl->segments[i].size;
 784        memory_region_init_io(&fl->mmio, OBJECT(s), &aspeed_smc_flash_ops,
 785                              fl, name, fl->size);
 786        memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio);
 787        offset += fl->size;
 788    }
 789}
 790
 791static const VMStateDescription vmstate_aspeed_smc = {
 792    .name = "aspeed.smc",
 793    .version_id = 1,
 794    .minimum_version_id = 1,
 795    .fields = (VMStateField[]) {
 796        VMSTATE_UINT32_ARRAY(regs, AspeedSMCState, ASPEED_SMC_R_MAX),
 797        VMSTATE_END_OF_LIST()
 798    }
 799};
 800
 801static Property aspeed_smc_properties[] = {
 802    DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
 803    DEFINE_PROP_END_OF_LIST(),
 804};
 805
 806static void aspeed_smc_class_init(ObjectClass *klass, void *data)
 807{
 808    DeviceClass *dc = DEVICE_CLASS(klass);
 809    AspeedSMCClass *mc = ASPEED_SMC_CLASS(klass);
 810
 811    dc->realize = aspeed_smc_realize;
 812    dc->reset = aspeed_smc_reset;
 813    dc->props = aspeed_smc_properties;
 814    dc->vmsd = &vmstate_aspeed_smc;
 815    mc->ctrl = data;
 816}
 817
 818static const TypeInfo aspeed_smc_info = {
 819    .name           = TYPE_ASPEED_SMC,
 820    .parent         = TYPE_SYS_BUS_DEVICE,
 821    .instance_size  = sizeof(AspeedSMCState),
 822    .class_size     = sizeof(AspeedSMCClass),
 823    .abstract       = true,
 824};
 825
 826static void aspeed_smc_register_types(void)
 827{
 828    int i;
 829
 830    type_register_static(&aspeed_smc_info);
 831    for (i = 0; i < ARRAY_SIZE(controllers); ++i) {
 832        TypeInfo ti = {
 833            .name       = controllers[i].name,
 834            .parent     = TYPE_ASPEED_SMC,
 835            .class_init = aspeed_smc_class_init,
 836            .class_data = (void *)&controllers[i],
 837        };
 838        type_register(&ti);
 839    }
 840}
 841
 842type_init(aspeed_smc_register_types)
 843