~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to hw/ssi/aspeed_smc.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#define   CONF_ENABLE_W2       18
40
40
#define   CONF_ENABLE_W1       17
41
41
#define   CONF_ENABLE_W0       16
42
 
#define   CONF_FLASH_TYPE4     9
43
 
#define   CONF_FLASH_TYPE3     7
44
 
#define   CONF_FLASH_TYPE2     5
45
 
#define   CONF_FLASH_TYPE1     3
46
 
#define   CONF_FLASH_TYPE0     1
 
42
#define   CONF_FLASH_TYPE4     8
 
43
#define   CONF_FLASH_TYPE3     6
 
44
#define   CONF_FLASH_TYPE2     4
 
45
#define   CONF_FLASH_TYPE1     2
 
46
#define   CONF_FLASH_TYPE0     0
 
47
#define      CONF_FLASH_TYPE_NOR   0x0
 
48
#define      CONF_FLASH_TYPE_NAND  0x1
 
49
#define      CONF_FLASH_TYPE_SPI   0x2
47
50
 
48
51
/* CE Control Register */
49
52
#define R_CE_CTRL            (0x04 / 4)
66
69
#define R_CTRL0           (0x10 / 4)
67
70
#define   CTRL_CMD_SHIFT           16
68
71
#define   CTRL_CMD_MASK            0xff
 
72
#define   CTRL_DUMMY_HIGH_SHIFT    14
 
73
#define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
 
74
#define   CTRL_DUMMY_LOW_SHIFT     6 /* 2 bits [7:6] */
69
75
#define   CTRL_CE_STOP_ACTIVE      (1 << 2)
70
76
#define   CTRL_CMD_MODE_MASK       0x3
71
77
#define     CTRL_READMODE          0x0
127
133
#define R_SPI_MISC_CTRL   (0x10 / 4)
128
134
#define R_SPI_TIMINGS     (0x14 / 4)
129
135
 
 
136
#define ASPEED_SMC_R_SPI_MAX (0x20 / 4)
 
137
#define ASPEED_SMC_R_SMC_MAX (0x20 / 4)
 
138
 
130
139
#define ASPEED_SOC_SMC_FLASH_BASE   0x10000000
131
140
#define ASPEED_SOC_FMC_FLASH_BASE   0x20000000
132
141
#define ASPEED_SOC_SPI_FLASH_BASE   0x30000000
133
142
#define ASPEED_SOC_SPI2_FLASH_BASE  0x38000000
134
143
 
 
144
/* Flash opcodes. */
 
145
#define SPI_OP_READ       0x03    /* Read data bytes (low frequency) */
 
146
 
135
147
/*
136
148
 * Default segments mapping addresses and size for each slave per
137
149
 * controller. These can be changed when board is initialized with the
170
182
};
171
183
 
172
184
static const AspeedSMCController controllers[] = {
173
 
    { "aspeed.smc.smc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
174
 
      CONF_ENABLE_W0, 5, aspeed_segments_legacy,
175
 
      ASPEED_SOC_SMC_FLASH_BASE, 0x6000000 },
176
 
    { "aspeed.smc.fmc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
177
 
      CONF_ENABLE_W0, 5, aspeed_segments_fmc,
178
 
      ASPEED_SOC_FMC_FLASH_BASE, 0x10000000 },
179
 
    { "aspeed.smc.spi", R_SPI_CONF, 0xff, R_SPI_CTRL0, R_SPI_TIMINGS,
180
 
      SPI_CONF_ENABLE_W0, 1, aspeed_segments_spi,
181
 
      ASPEED_SOC_SPI_FLASH_BASE, 0x10000000 },
182
 
    { "aspeed.smc.ast2500-fmc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
183
 
      CONF_ENABLE_W0, 3, aspeed_segments_ast2500_fmc,
184
 
      ASPEED_SOC_FMC_FLASH_BASE, 0x10000000 },
185
 
    { "aspeed.smc.ast2500-spi1", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
186
 
      CONF_ENABLE_W0, 2, aspeed_segments_ast2500_spi1,
187
 
      ASPEED_SOC_SPI_FLASH_BASE, 0x8000000 },
188
 
    { "aspeed.smc.ast2500-spi2", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
189
 
      CONF_ENABLE_W0, 2, aspeed_segments_ast2500_spi2,
190
 
      ASPEED_SOC_SPI2_FLASH_BASE, 0x8000000 },
 
185
    {
 
186
        .name              = "aspeed.smc.smc",
 
187
        .r_conf            = R_CONF,
 
188
        .r_ce_ctrl         = R_CE_CTRL,
 
189
        .r_ctrl0           = R_CTRL0,
 
190
        .r_timings         = R_TIMINGS,
 
191
        .conf_enable_w0    = CONF_ENABLE_W0,
 
192
        .max_slaves        = 5,
 
193
        .segments          = aspeed_segments_legacy,
 
194
        .flash_window_base = ASPEED_SOC_SMC_FLASH_BASE,
 
195
        .flash_window_size = 0x6000000,
 
196
        .has_dma           = false,
 
197
        .nregs             = ASPEED_SMC_R_SMC_MAX,
 
198
    }, {
 
199
        .name              = "aspeed.smc.fmc",
 
200
        .r_conf            = R_CONF,
 
201
        .r_ce_ctrl         = R_CE_CTRL,
 
202
        .r_ctrl0           = R_CTRL0,
 
203
        .r_timings         = R_TIMINGS,
 
204
        .conf_enable_w0    = CONF_ENABLE_W0,
 
205
        .max_slaves        = 5,
 
206
        .segments          = aspeed_segments_fmc,
 
207
        .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
 
208
        .flash_window_size = 0x10000000,
 
209
        .has_dma           = true,
 
210
        .nregs             = ASPEED_SMC_R_MAX,
 
211
    }, {
 
212
        .name              = "aspeed.smc.spi",
 
213
        .r_conf            = R_SPI_CONF,
 
214
        .r_ce_ctrl         = 0xff,
 
215
        .r_ctrl0           = R_SPI_CTRL0,
 
216
        .r_timings         = R_SPI_TIMINGS,
 
217
        .conf_enable_w0    = SPI_CONF_ENABLE_W0,
 
218
        .max_slaves        = 1,
 
219
        .segments          = aspeed_segments_spi,
 
220
        .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
 
221
        .flash_window_size = 0x10000000,
 
222
        .has_dma           = false,
 
223
        .nregs             = ASPEED_SMC_R_SPI_MAX,
 
224
    }, {
 
225
        .name              = "aspeed.smc.ast2500-fmc",
 
226
        .r_conf            = R_CONF,
 
227
        .r_ce_ctrl         = R_CE_CTRL,
 
228
        .r_ctrl0           = R_CTRL0,
 
229
        .r_timings         = R_TIMINGS,
 
230
        .conf_enable_w0    = CONF_ENABLE_W0,
 
231
        .max_slaves        = 3,
 
232
        .segments          = aspeed_segments_ast2500_fmc,
 
233
        .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
 
234
        .flash_window_size = 0x10000000,
 
235
        .has_dma           = true,
 
236
        .nregs             = ASPEED_SMC_R_MAX,
 
237
    }, {
 
238
        .name              = "aspeed.smc.ast2500-spi1",
 
239
        .r_conf            = R_CONF,
 
240
        .r_ce_ctrl         = R_CE_CTRL,
 
241
        .r_ctrl0           = R_CTRL0,
 
242
        .r_timings         = R_TIMINGS,
 
243
        .conf_enable_w0    = CONF_ENABLE_W0,
 
244
        .max_slaves        = 2,
 
245
        .segments          = aspeed_segments_ast2500_spi1,
 
246
        .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
 
247
        .flash_window_size = 0x8000000,
 
248
        .has_dma           = false,
 
249
        .nregs             = ASPEED_SMC_R_MAX,
 
250
    }, {
 
251
        .name              = "aspeed.smc.ast2500-spi2",
 
252
        .r_conf            = R_CONF,
 
253
        .r_ce_ctrl         = R_CE_CTRL,
 
254
        .r_ctrl0           = R_CTRL0,
 
255
        .r_timings         = R_TIMINGS,
 
256
        .conf_enable_w0    = CONF_ENABLE_W0,
 
257
        .max_slaves        = 2,
 
258
        .segments          = aspeed_segments_ast2500_spi2,
 
259
        .flash_window_base = ASPEED_SOC_SPI2_FLASH_BASE,
 
260
        .flash_window_size = 0x8000000,
 
261
        .has_dma           = false,
 
262
        .nregs             = ASPEED_SMC_R_MAX,
 
263
    },
191
264
};
192
265
 
193
266
/*
253
326
        qemu_log_mask(LOG_GUEST_ERROR,
254
327
                      "%s: Tried to change CS0 start address to 0x%"
255
328
                      HWADDR_PRIx "\n", s->ctrl->name, seg.addr);
256
 
        return;
 
329
        seg.addr = s->ctrl->flash_window_base;
 
330
        new = aspeed_smc_segment_to_reg(&seg);
257
331
    }
258
332
 
259
333
    /*
267
341
        s->ctrl->segments[cs].size) {
268
342
        qemu_log_mask(LOG_GUEST_ERROR,
269
343
                      "%s: Tried to change CS%d end address to 0x%"
270
 
                      HWADDR_PRIx "\n", s->ctrl->name, cs, seg.addr);
271
 
        return;
 
344
                      HWADDR_PRIx "\n", s->ctrl->name, cs, seg.addr + seg.size);
 
345
        seg.size = s->ctrl->segments[cs].addr + s->ctrl->segments[cs].size -
 
346
            seg.addr;
 
347
        new = aspeed_smc_segment_to_reg(&seg);
272
348
    }
273
349
 
274
350
    /* Keep the segment in the overall flash window */
281
357
    }
282
358
 
283
359
    /* Check start address vs. alignment */
284
 
    if (seg.addr % seg.size) {
 
360
    if (seg.size && !QEMU_IS_ALIGNED(seg.addr, seg.size)) {
285
361
        qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is not "
286
362
                      "aligned : [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
287
363
                      s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
288
364
    }
289
365
 
290
 
    /* And segments should not overlap */
291
 
    if (aspeed_smc_flash_overlap(s, &seg, cs)) {
292
 
        return;
293
 
    }
 
366
    /* And segments should not overlap (in the specs) */
 
367
    aspeed_smc_flash_overlap(s, &seg, cs);
294
368
 
295
369
    /* All should be fine now to move the region */
296
370
    memory_region_transaction_begin();
327
401
    },
328
402
};
329
403
 
330
 
static inline int aspeed_smc_flash_mode(const AspeedSMCState *s, int cs)
331
 
{
332
 
    return s->regs[s->r_ctrl0 + cs] & CTRL_CMD_MODE_MASK;
333
 
}
334
 
 
335
 
static inline bool aspeed_smc_is_usermode(const AspeedSMCState *s, int cs)
336
 
{
337
 
    return aspeed_smc_flash_mode(s, cs) == CTRL_USERMODE;
338
 
}
339
 
 
340
 
static inline bool aspeed_smc_is_writable(const AspeedSMCState *s, int cs)
341
 
{
342
 
    return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + cs));
 
404
static inline int aspeed_smc_flash_mode(const AspeedSMCFlash *fl)
 
405
{
 
406
    const AspeedSMCState *s = fl->controller;
 
407
 
 
408
    return s->regs[s->r_ctrl0 + fl->id] & CTRL_CMD_MODE_MASK;
 
409
}
 
410
 
 
411
static inline bool aspeed_smc_is_writable(const AspeedSMCFlash *fl)
 
412
{
 
413
    const AspeedSMCState *s = fl->controller;
 
414
 
 
415
    return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->id));
 
416
}
 
417
 
 
418
static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
 
419
{
 
420
    const AspeedSMCState *s = fl->controller;
 
421
    int cmd = (s->regs[s->r_ctrl0 + fl->id] >> CTRL_CMD_SHIFT) & CTRL_CMD_MASK;
 
422
 
 
423
    /* In read mode, the default SPI command is READ (0x3). In other
 
424
     * modes, the command should necessarily be defined */
 
425
    if (aspeed_smc_flash_mode(fl) == CTRL_READMODE) {
 
426
        cmd = SPI_OP_READ;
 
427
    }
 
428
 
 
429
    if (!cmd) {
 
430
        qemu_log_mask(LOG_GUEST_ERROR, "%s: no command defined for mode %d\n",
 
431
                      __func__, aspeed_smc_flash_mode(fl));
 
432
    }
 
433
 
 
434
    return cmd;
 
435
}
 
436
 
 
437
static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl)
 
438
{
 
439
    const AspeedSMCState *s = fl->controller;
 
440
 
 
441
    if (s->ctrl->segments == aspeed_segments_spi) {
 
442
        return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
 
443
    } else {
 
444
        return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->id));
 
445
    }
 
446
}
 
447
 
 
448
static inline bool aspeed_smc_is_ce_stop_active(const AspeedSMCFlash *fl)
 
449
{
 
450
    const AspeedSMCState *s = fl->controller;
 
451
 
 
452
    return s->regs[s->r_ctrl0 + fl->id] & CTRL_CE_STOP_ACTIVE;
 
453
}
 
454
 
 
455
static void aspeed_smc_flash_select(AspeedSMCFlash *fl)
 
456
{
 
457
    AspeedSMCState *s = fl->controller;
 
458
 
 
459
    s->regs[s->r_ctrl0 + fl->id] &= ~CTRL_CE_STOP_ACTIVE;
 
460
    qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
 
461
}
 
462
 
 
463
static void aspeed_smc_flash_unselect(AspeedSMCFlash *fl)
 
464
{
 
465
    AspeedSMCState *s = fl->controller;
 
466
 
 
467
    s->regs[s->r_ctrl0 + fl->id] |= CTRL_CE_STOP_ACTIVE;
 
468
    qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
 
469
}
 
470
 
 
471
static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
 
472
                                              uint32_t addr)
 
473
{
 
474
    const AspeedSMCState *s = fl->controller;
 
475
    AspeedSegments seg;
 
476
 
 
477
    aspeed_smc_reg_to_segment(s->regs[R_SEG_ADDR0 + fl->id], &seg);
 
478
    if ((addr % seg.size) != addr) {
 
479
        qemu_log_mask(LOG_GUEST_ERROR,
 
480
                      "%s: invalid address 0x%08x for CS%d segment : "
 
481
                      "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
 
482
                      s->ctrl->name, addr, fl->id, seg.addr,
 
483
                      seg.addr + seg.size);
 
484
        addr %= seg.size;
 
485
    }
 
486
 
 
487
    return addr;
 
488
}
 
489
 
 
490
static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
 
491
{
 
492
    const AspeedSMCState *s = fl->controller;
 
493
    uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->id];
 
494
    uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
 
495
    uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
 
496
 
 
497
    return ((dummy_high << 2) | dummy_low) * 8;
 
498
}
 
499
 
 
500
static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
 
501
{
 
502
    const AspeedSMCState *s = fl->controller;
 
503
    uint8_t cmd = aspeed_smc_flash_cmd(fl);
 
504
 
 
505
    /* Flash access can not exceed CS segment */
 
506
    addr = aspeed_smc_check_segment_addr(fl, addr);
 
507
 
 
508
    ssi_transfer(s->spi, cmd);
 
509
 
 
510
    if (aspeed_smc_flash_is_4byte(fl)) {
 
511
        ssi_transfer(s->spi, (addr >> 24) & 0xff);
 
512
    }
 
513
    ssi_transfer(s->spi, (addr >> 16) & 0xff);
 
514
    ssi_transfer(s->spi, (addr >> 8) & 0xff);
 
515
    ssi_transfer(s->spi, (addr & 0xff));
343
516
}
344
517
 
345
518
static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
346
519
{
347
520
    AspeedSMCFlash *fl = opaque;
348
 
    const AspeedSMCState *s = fl->controller;
 
521
    AspeedSMCState *s = fl->controller;
349
522
    uint64_t ret = 0;
350
523
    int i;
351
524
 
352
 
    if (aspeed_smc_is_usermode(s, fl->id)) {
353
 
        for (i = 0; i < size; i++) {
354
 
            ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
355
 
        }
356
 
    } else {
357
 
        qemu_log_mask(LOG_UNIMP, "%s: usermode not implemented\n",
358
 
                      __func__);
359
 
        ret = -1;
 
525
    switch (aspeed_smc_flash_mode(fl)) {
 
526
    case CTRL_USERMODE:
 
527
        for (i = 0; i < size; i++) {
 
528
            ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
 
529
        }
 
530
        break;
 
531
    case CTRL_READMODE:
 
532
    case CTRL_FREADMODE:
 
533
        aspeed_smc_flash_select(fl);
 
534
        aspeed_smc_flash_send_addr(fl, addr);
 
535
 
 
536
        /*
 
537
         * Use fake transfers to model dummy bytes. The value should
 
538
         * be configured to some non-zero value in fast read mode and
 
539
         * zero in read mode. But, as the HW allows inconsistent
 
540
         * settings, let's check for fast read mode.
 
541
         */
 
542
        if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) {
 
543
            for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
 
544
                ssi_transfer(fl->controller->spi, 0xFF);
 
545
            }
 
546
        }
 
547
 
 
548
        for (i = 0; i < size; i++) {
 
549
            ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
 
550
        }
 
551
 
 
552
        aspeed_smc_flash_unselect(fl);
 
553
        break;
 
554
    default:
 
555
        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid flash mode %d\n",
 
556
                      __func__, aspeed_smc_flash_mode(fl));
360
557
    }
361
558
 
362
559
    return ret;
366
563
                           unsigned size)
367
564
{
368
565
    AspeedSMCFlash *fl = opaque;
369
 
    const AspeedSMCState *s = fl->controller;
 
566
    AspeedSMCState *s = fl->controller;
370
567
    int i;
371
568
 
372
 
    if (!aspeed_smc_is_writable(s, fl->id)) {
 
569
    if (!aspeed_smc_is_writable(fl)) {
373
570
        qemu_log_mask(LOG_GUEST_ERROR, "%s: flash is not writable at 0x%"
374
571
                      HWADDR_PRIx "\n", __func__, addr);
375
572
        return;
376
573
    }
377
574
 
378
 
    if (!aspeed_smc_is_usermode(s, fl->id)) {
379
 
        qemu_log_mask(LOG_UNIMP, "%s: usermode not implemented\n",
380
 
                      __func__);
381
 
        return;
382
 
    }
383
 
 
384
 
    for (i = 0; i < size; i++) {
385
 
        ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
 
575
    switch (aspeed_smc_flash_mode(fl)) {
 
576
    case CTRL_USERMODE:
 
577
        for (i = 0; i < size; i++) {
 
578
            ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
 
579
        }
 
580
        break;
 
581
    case CTRL_WRITEMODE:
 
582
        aspeed_smc_flash_select(fl);
 
583
        aspeed_smc_flash_send_addr(fl, addr);
 
584
 
 
585
        for (i = 0; i < size; i++) {
 
586
            ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
 
587
        }
 
588
 
 
589
        aspeed_smc_flash_unselect(fl);
 
590
        break;
 
591
    default:
 
592
        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid flash mode %d\n",
 
593
                      __func__, aspeed_smc_flash_mode(fl));
386
594
    }
387
595
}
388
596
 
396
604
    },
397
605
};
398
606
 
399
 
static bool aspeed_smc_is_ce_stop_active(const AspeedSMCState *s, int cs)
400
 
{
401
 
    return s->regs[s->r_ctrl0 + cs] & CTRL_CE_STOP_ACTIVE;
402
 
}
403
 
 
404
 
static void aspeed_smc_update_cs(const AspeedSMCState *s)
405
 
{
406
 
    int i;
407
 
 
408
 
    for (i = 0; i < s->num_cs; ++i) {
409
 
        qemu_set_irq(s->cs_lines[i], aspeed_smc_is_ce_stop_active(s, i));
410
 
    }
 
607
static void aspeed_smc_flash_update_cs(AspeedSMCFlash *fl)
 
608
{
 
609
    const AspeedSMCState *s = fl->controller;
 
610
 
 
611
    qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
411
612
}
412
613
 
413
614
static void aspeed_smc_reset(DeviceState *d)
423
624
    /* Unselect all slaves */
424
625
    for (i = 0; i < s->num_cs; ++i) {
425
626
        s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
 
627
        qemu_set_irq(s->cs_lines[i], true);
426
628
    }
427
629
 
428
630
    /* setup default segment register values for all */
431
633
            aspeed_smc_segment_to_reg(&s->ctrl->segments[i]);
432
634
    }
433
635
 
434
 
    aspeed_smc_update_cs(s);
 
636
    /* HW strapping for AST2500 FMC controllers  */
 
637
    if (s->ctrl->segments == aspeed_segments_ast2500_fmc) {
 
638
        /* flash type is fixed to SPI for CE0 and CE1 */
 
639
        s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
 
640
        s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1);
 
641
 
 
642
        /* 4BYTE mode is autodetected for CE0. Let's force it to 1 for
 
643
         * now */
 
644
        s->regs[s->r_ce_ctrl] |= (1 << (CTRL_EXTENDED0));
 
645
    }
 
646
 
 
647
    /* HW strapping for AST2400 FMC controllers (SCU70). Let's use the
 
648
     * configuration of the palmetto-bmc machine */
 
649
    if (s->ctrl->segments == aspeed_segments_fmc) {
 
650
        s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
 
651
 
 
652
        s->regs[s->r_ce_ctrl] |= (1 << (CTRL_EXTENDED0));
 
653
    }
435
654
}
436
655
 
437
656
static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
440
659
 
441
660
    addr >>= 2;
442
661
 
443
 
    if (addr >= ARRAY_SIZE(s->regs)) {
444
 
        qemu_log_mask(LOG_GUEST_ERROR,
445
 
                      "%s: Out-of-bounds read at 0x%" HWADDR_PRIx "\n",
446
 
                      __func__, addr);
447
 
        return 0;
448
 
    }
449
 
 
450
662
    if (addr == s->r_conf ||
451
663
        addr == s->r_timings ||
452
664
        addr == s->r_ce_ctrl ||
469
681
 
470
682
    addr >>= 2;
471
683
 
472
 
    if (addr >= ARRAY_SIZE(s->regs)) {
473
 
        qemu_log_mask(LOG_GUEST_ERROR,
474
 
                      "%s: Out-of-bounds write at 0x%" HWADDR_PRIx "\n",
475
 
                      __func__, addr);
476
 
        return;
477
 
    }
478
 
 
479
684
    if (addr == s->r_conf ||
480
685
        addr == s->r_timings ||
481
686
        addr == s->r_ce_ctrl) {
482
687
        s->regs[addr] = value;
483
688
    } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
 
689
        int cs = addr - s->r_ctrl0;
484
690
        s->regs[addr] = value;
485
 
        aspeed_smc_update_cs(s);
 
691
        aspeed_smc_flash_update_cs(&s->flashes[cs]);
486
692
    } else if (addr >= R_SEG_ADDR0 &&
487
693
               addr < R_SEG_ADDR0 + s->ctrl->max_slaves) {
488
694
        int cs = addr - R_SEG_ADDR0;
540
746
        sysbus_init_irq(sbd, &s->cs_lines[i]);
541
747
    }
542
748
 
543
 
    aspeed_smc_reset(dev);
544
 
 
545
749
    /* The memory region for the controller registers */
546
750
    memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
547
 
                          s->ctrl->name, ASPEED_SMC_R_MAX * 4);
 
751
                          s->ctrl->name, s->ctrl->nregs * 4);
548
752
    sysbus_init_mmio(sbd, &s->mmio);
549
753
 
550
754
    /*