qemu

Форк
0
/
aspeed_sdmc.c 
704 строки · 21.0 Кб
1
/*
2
 * ASPEED SDRAM Memory Controller
3
 *
4
 * Copyright (C) 2016 IBM Corp.
5
 *
6
 * This code is licensed under the GPL version 2 or later.  See
7
 * the COPYING file in the top-level directory.
8
 */
9

10
#include "qemu/osdep.h"
11
#include "qemu/log.h"
12
#include "qemu/module.h"
13
#include "qemu/error-report.h"
14
#include "hw/misc/aspeed_sdmc.h"
15
#include "hw/qdev-properties.h"
16
#include "migration/vmstate.h"
17
#include "qapi/error.h"
18
#include "trace.h"
19
#include "qemu/units.h"
20
#include "qemu/cutils.h"
21
#include "qapi/visitor.h"
22

23
/* Protection Key Register */
24
#define R_PROT            (0x00 / 4)
25
#define   PROT_UNLOCKED      0x01
26
#define   PROT_HARDLOCKED    0x10  /* AST2600 */
27
#define   PROT_SOFTLOCKED    0x00
28

29
#define   PROT_KEY_UNLOCK     0xFC600309
30
#define   PROT_2700_KEY_UNLOCK  0x1688A8A8
31
#define   PROT_KEY_HARDLOCK   0xDEADDEAD /* AST2600 */
32

33
/* Configuration Register */
34
#define R_CONF            (0x04 / 4)
35

36
/* Interrupt control/status */
37
#define R_ISR             (0x50 / 4)
38

39
/* Control/Status Register #1 (ast2500) */
40
#define R_STATUS1         (0x60 / 4)
41
#define   PHY_BUSY_STATE      BIT(0)
42
#define   PHY_PLL_LOCK_STATUS BIT(4)
43

44
/* Reserved */
45
#define R_MCR6C           (0x6c / 4)
46

47
#define R_ECC_TEST_CTRL   (0x70 / 4)
48
#define   ECC_TEST_FINISHED   BIT(12)
49
#define   ECC_TEST_FAIL       BIT(13)
50

51
#define R_TEST_START_LEN  (0x74 / 4)
52
#define R_TEST_FAIL_DQ    (0x78 / 4)
53
#define R_TEST_INIT_VAL   (0x7c / 4)
54
#define R_DRAM_SW         (0x88 / 4)
55
#define R_DRAM_TIME       (0x8c / 4)
56
#define R_ECC_ERR_INJECT  (0xb4 / 4)
57

58
/* AST2700 Register */
59
#define R_2700_PROT                 (0x00 / 4)
60
#define R_INT_STATUS                (0x04 / 4)
61
#define R_INT_CLEAR                 (0x08 / 4)
62
#define R_INT_MASK                  (0x0c / 4)
63
#define R_MAIN_CONF                 (0x10 / 4)
64
#define R_MAIN_CONTROL              (0x14 / 4)
65
#define R_MAIN_STATUS               (0x18 / 4)
66
#define R_ERR_STATUS                (0x1c / 4)
67
#define R_ECC_FAIL_STATUS           (0x78 / 4)
68
#define R_ECC_FAIL_ADDR             (0x7c / 4)
69
#define R_ECC_TESTING_CONTROL       (0x80 / 4)
70
#define R_PROT_REGION_LOCK_STATUS   (0x94 / 4)
71
#define R_TEST_FAIL_ADDR            (0xd4 / 4)
72
#define R_TEST_FAIL_D0              (0xd8 / 4)
73
#define R_TEST_FAIL_D1              (0xdc / 4)
74
#define R_TEST_FAIL_D2              (0xe0 / 4)
75
#define R_TEST_FAIL_D3              (0xe4 / 4)
76
#define R_DBG_STATUS                (0xf4 / 4)
77
#define R_PHY_INTERFACE_STATUS      (0xf8 / 4)
78
#define R_GRAPHIC_MEM_BASE_ADDR     (0x10c / 4)
79
#define R_PORT0_INTERFACE_MONITOR0  (0x240 / 4)
80
#define R_PORT0_INTERFACE_MONITOR1  (0x244 / 4)
81
#define R_PORT0_INTERFACE_MONITOR2  (0x248 / 4)
82
#define R_PORT1_INTERFACE_MONITOR0  (0x2c0 / 4)
83
#define R_PORT1_INTERFACE_MONITOR1  (0x2c4 / 4)
84
#define R_PORT1_INTERFACE_MONITOR2  (0x2c8 / 4)
85
#define R_PORT2_INTERFACE_MONITOR0  (0x340 / 4)
86
#define R_PORT2_INTERFACE_MONITOR1  (0x344 / 4)
87
#define R_PORT2_INTERFACE_MONITOR2  (0x348 / 4)
88
#define R_PORT3_INTERFACE_MONITOR0  (0x3c0 / 4)
89
#define R_PORT3_INTERFACE_MONITOR1  (0x3c4 / 4)
90
#define R_PORT3_INTERFACE_MONITOR2  (0x3c8 / 4)
91
#define R_PORT4_INTERFACE_MONITOR0  (0x440 / 4)
92
#define R_PORT4_INTERFACE_MONITOR1  (0x444 / 4)
93
#define R_PORT4_INTERFACE_MONITOR2  (0x448 / 4)
94
#define R_PORT5_INTERFACE_MONITOR0  (0x4c0 / 4)
95
#define R_PORT5_INTERFACE_MONITOR1  (0x4c4 / 4)
96
#define R_PORT5_INTERFACE_MONITOR2  (0x4c8 / 4)
97

98
/*
99
 * Configuration register Ox4 (for Aspeed AST2400 SOC)
100
 *
101
 * These are for the record and future use. ASPEED_SDMC_DRAM_SIZE is
102
 * what we care about right now as it is checked by U-Boot to
103
 * determine the RAM size.
104
 */
105

106
#define ASPEED_SDMC_RESERVED            0xFFFFF800 /* 31:11 reserved */
107
#define ASPEED_SDMC_AST2300_COMPAT      (1 << 10)
108
#define ASPEED_SDMC_SCRAMBLE_PATTERN    (1 << 9)
109
#define ASPEED_SDMC_DATA_SCRAMBLE       (1 << 8)
110
#define ASPEED_SDMC_ECC_ENABLE          (1 << 7)
111
#define ASPEED_SDMC_VGA_COMPAT          (1 << 6) /* readonly */
112
#define ASPEED_SDMC_DRAM_BANK           (1 << 5)
113
#define ASPEED_SDMC_DRAM_BURST          (1 << 4)
114
#define ASPEED_SDMC_VGA_APERTURE(x)     ((x & 0x3) << 2) /* readonly */
115
#define     ASPEED_SDMC_VGA_8MB             0x0
116
#define     ASPEED_SDMC_VGA_16MB            0x1
117
#define     ASPEED_SDMC_VGA_32MB            0x2
118
#define     ASPEED_SDMC_VGA_64MB            0x3
119
#define ASPEED_SDMC_DRAM_SIZE(x)        (x & 0x3)
120

121
#define ASPEED_SDMC_READONLY_MASK                       \
122
    (ASPEED_SDMC_RESERVED | ASPEED_SDMC_VGA_COMPAT |    \
123
     ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))
124
/*
125
 * Configuration register Ox4 (for Aspeed AST2500 SOC and higher)
126
 *
127
 * Incompatibilities are annotated in the list. ASPEED_SDMC_HW_VERSION
128
 * should be set to 1 for the AST2500 SOC.
129
 */
130
#define ASPEED_SDMC_HW_VERSION(x)       ((x & 0xf) << 28) /* readonly */
131
#define ASPEED_SDMC_SW_VERSION          ((x & 0xff) << 20)
132
#define ASPEED_SDMC_CACHE_INITIAL_DONE  (1 << 19)  /* readonly */
133
#define ASPEED_SDMC_AST2500_RESERVED    0x7C000 /* 18:14 reserved */
134
#define ASPEED_SDMC_CACHE_DDR4_CONF     (1 << 13)
135
#define ASPEED_SDMC_CACHE_INITIAL       (1 << 12)
136
#define ASPEED_SDMC_CACHE_RANGE_CTRL    (1 << 11)
137
#define ASPEED_SDMC_CACHE_ENABLE        (1 << 10) /* differs from AST2400 */
138
#define ASPEED_SDMC_DRAM_TYPE           (1 << 4)  /* differs from AST2400 */
139

140
#define ASPEED_SDMC_AST2500_READONLY_MASK                               \
141
    (ASPEED_SDMC_HW_VERSION(0xf) | ASPEED_SDMC_CACHE_INITIAL_DONE |     \
142
     ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT |            \
143
     ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))
144

145
/*
146
 * Main Configuration register Ox10 (for Aspeed AST2700 SOC and higher)
147
 *
148
 */
149
#define ASPEED_SDMC_AST2700_RESERVED        0xFFFF2082 /* 31:16, 13, 7, 1 */
150
#define ASPEED_SDMC_AST2700_DATA_SCRAMBLE           (1 << 8)
151
#define ASPEED_SDMC_AST2700_ECC_ENABLE              (1 << 6)
152
#define ASPEED_SDMC_AST2700_PAGE_MATCHING_ENABLE    (1 << 5)
153
#define ASPEED_SDMC_AST2700_DRAM_SIZE(x)            ((x & 0x7) << 2)
154

155
#define ASPEED_SDMC_AST2700_READONLY_MASK   \
156
     (ASPEED_SDMC_AST2700_RESERVED)
157

158
static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
159
{
160
    AspeedSDMCState *s = ASPEED_SDMC(opaque);
161

162
    addr >>= 2;
163

164
    if (addr >= ARRAY_SIZE(s->regs)) {
165
        qemu_log_mask(LOG_GUEST_ERROR,
166
                      "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
167
                      __func__, addr * 4);
168
        return 0;
169
    }
170

171
    trace_aspeed_sdmc_read(addr, s->regs[addr]);
172
    return s->regs[addr];
173
}
174

175
static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
176
                             unsigned int size)
177
{
178
    AspeedSDMCState *s = ASPEED_SDMC(opaque);
179
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
180

181
    addr >>= 2;
182

183
    if (addr >= ARRAY_SIZE(s->regs)) {
184
        qemu_log_mask(LOG_GUEST_ERROR,
185
                      "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
186
                      __func__, addr);
187
        return;
188
    }
189

190
    trace_aspeed_sdmc_write(addr, data);
191
    asc->write(s, addr, data);
192
}
193

194
static const MemoryRegionOps aspeed_sdmc_ops = {
195
    .read = aspeed_sdmc_read,
196
    .write = aspeed_sdmc_write,
197
    .endianness = DEVICE_LITTLE_ENDIAN,
198
    .valid.min_access_size = 4,
199
    .valid.max_access_size = 4,
200
};
201

202
static void aspeed_sdmc_reset(DeviceState *dev)
203
{
204
    AspeedSDMCState *s = ASPEED_SDMC(dev);
205
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
206

207
    memset(s->regs, 0, sizeof(s->regs));
208

209
    /* Set ram size bit and defaults values */
210
    s->regs[R_CONF] = asc->compute_conf(s, 0);
211

212
    /*
213
     * PHY status:
214
     *  - set phy status ok (set bit 1)
215
     *  - initial PVT calibration ok (clear bit 3)
216
     *  - runtime calibration ok (clear bit 5)
217
     */
218
    s->regs[0x100] = BIT(1);
219

220
    /* PHY eye window: set all as passing */
221
    s->regs[0x100 | (0x68 / 4)] = 0xff;
222
    s->regs[0x100 | (0x7c / 4)] = 0xff;
223
    s->regs[0x100 | (0x50 / 4)] = 0xfffffff;
224
}
225

226
static void aspeed_sdmc_get_ram_size(Object *obj, Visitor *v, const char *name,
227
                                     void *opaque, Error **errp)
228
{
229
    AspeedSDMCState *s = ASPEED_SDMC(obj);
230
    int64_t value = s->ram_size;
231

232
    visit_type_int(v, name, &value, errp);
233
}
234

235
static void aspeed_sdmc_set_ram_size(Object *obj, Visitor *v, const char *name,
236
                                     void *opaque, Error **errp)
237
{
238
    int i;
239
    char *sz;
240
    int64_t value;
241
    AspeedSDMCState *s = ASPEED_SDMC(obj);
242
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
243

244
    if (!visit_type_int(v, name, &value, errp)) {
245
        return;
246
    }
247

248
    for (i = 0; asc->valid_ram_sizes[i]; i++) {
249
        if (value == asc->valid_ram_sizes[i]) {
250
            s->ram_size = value;
251
            return;
252
        }
253
    }
254

255
    sz = size_to_str(value);
256
    error_setg(errp, "Invalid RAM size %s", sz);
257
    g_free(sz);
258
}
259

260
static void aspeed_sdmc_initfn(Object *obj)
261
{
262
    object_property_add(obj, "ram-size", "int",
263
                        aspeed_sdmc_get_ram_size, aspeed_sdmc_set_ram_size,
264
                        NULL, NULL);
265
}
266

267
static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
268
{
269
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
270
    AspeedSDMCState *s = ASPEED_SDMC(dev);
271
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
272

273
    assert(asc->max_ram_size < 4 * GiB || asc->is_bus64bit);
274

275
    if (!s->ram_size) {
276
        error_setg(errp, "RAM size is not set");
277
        return;
278
    }
279

280
    s->max_ram_size = asc->max_ram_size;
281

282
    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sdmc_ops, s,
283
                          TYPE_ASPEED_SDMC, 0x1000);
284
    sysbus_init_mmio(sbd, &s->iomem);
285
}
286

287
static const VMStateDescription vmstate_aspeed_sdmc = {
288
    .name = "aspeed.sdmc",
289
    .version_id = 2,
290
    .minimum_version_id = 2,
291
    .fields = (const VMStateField[]) {
292
        VMSTATE_UINT32_ARRAY(regs, AspeedSDMCState, ASPEED_SDMC_NR_REGS),
293
        VMSTATE_END_OF_LIST()
294
    }
295
};
296

297
static Property aspeed_sdmc_properties[] = {
298
    DEFINE_PROP_UINT64("max-ram-size", AspeedSDMCState, max_ram_size, 0),
299
    DEFINE_PROP_BOOL("unlocked", AspeedSDMCState, unlocked, false),
300
    DEFINE_PROP_END_OF_LIST(),
301
};
302

303
static void aspeed_sdmc_class_init(ObjectClass *klass, void *data)
304
{
305
    DeviceClass *dc = DEVICE_CLASS(klass);
306
    dc->realize = aspeed_sdmc_realize;
307
    dc->reset = aspeed_sdmc_reset;
308
    dc->desc = "ASPEED SDRAM Memory Controller";
309
    dc->vmsd = &vmstate_aspeed_sdmc;
310
    device_class_set_props(dc, aspeed_sdmc_properties);
311
}
312

313
static const TypeInfo aspeed_sdmc_info = {
314
    .name = TYPE_ASPEED_SDMC,
315
    .parent = TYPE_SYS_BUS_DEVICE,
316
    .instance_size = sizeof(AspeedSDMCState),
317
    .instance_init = aspeed_sdmc_initfn,
318
    .class_init = aspeed_sdmc_class_init,
319
    .class_size = sizeof(AspeedSDMCClass),
320
    .abstract   = true,
321
};
322

323
static int aspeed_sdmc_get_ram_bits(AspeedSDMCState *s)
324
{
325
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
326
    int i;
327

328
    /*
329
     * The bitfield value encoding the RAM size is the index of the
330
     * possible RAM size array
331
     */
332
    for (i = 0; asc->valid_ram_sizes[i]; i++) {
333
        if (s->ram_size == asc->valid_ram_sizes[i]) {
334
            return i;
335
        }
336
    }
337

338
    /*
339
     * Invalid RAM sizes should have been excluded when setting the
340
     * SoC RAM size.
341
     */
342
    g_assert_not_reached();
343
}
344

345
static uint32_t aspeed_2400_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
346
{
347
    uint32_t fixed_conf = ASPEED_SDMC_VGA_COMPAT |
348
        ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
349

350
    /* Make sure readonly bits are kept */
351
    data &= ~ASPEED_SDMC_READONLY_MASK;
352

353
    return data | fixed_conf;
354
}
355

356
static void aspeed_2400_sdmc_write(AspeedSDMCState *s, uint32_t reg,
357
                                   uint32_t data)
358
{
359
    if (reg == R_PROT) {
360
        s->regs[reg] =
361
            (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
362
        return;
363
    }
364

365
    if (!s->regs[R_PROT]) {
366
        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
367
        return;
368
    }
369

370
    switch (reg) {
371
    case R_CONF:
372
        data = aspeed_2400_sdmc_compute_conf(s, data);
373
        break;
374
    default:
375
        break;
376
    }
377

378
    s->regs[reg] = data;
379
}
380

381
static const uint64_t
382
aspeed_2400_ram_sizes[] = { 64 * MiB, 128 * MiB, 256 * MiB, 512 * MiB, 0};
383

384
static void aspeed_2400_sdmc_class_init(ObjectClass *klass, void *data)
385
{
386
    DeviceClass *dc = DEVICE_CLASS(klass);
387
    AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);
388

389
    dc->desc = "ASPEED 2400 SDRAM Memory Controller";
390
    asc->max_ram_size = 512 * MiB;
391
    asc->compute_conf = aspeed_2400_sdmc_compute_conf;
392
    asc->write = aspeed_2400_sdmc_write;
393
    asc->valid_ram_sizes = aspeed_2400_ram_sizes;
394
}
395

396
static const TypeInfo aspeed_2400_sdmc_info = {
397
    .name = TYPE_ASPEED_2400_SDMC,
398
    .parent = TYPE_ASPEED_SDMC,
399
    .class_init = aspeed_2400_sdmc_class_init,
400
};
401

402
static uint32_t aspeed_2500_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
403
{
404
    uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(1) |
405
        ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
406
        ASPEED_SDMC_CACHE_INITIAL_DONE |
407
        ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
408

409
    /* Make sure readonly bits are kept */
410
    data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;
411

412
    return data | fixed_conf;
413
}
414

415
static void aspeed_2500_sdmc_write(AspeedSDMCState *s, uint32_t reg,
416
                                   uint32_t data)
417
{
418
    if (reg == R_PROT) {
419
        s->regs[reg] =
420
            (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
421
        return;
422
    }
423

424
    if (!s->regs[R_PROT]) {
425
        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
426
        return;
427
    }
428

429
    switch (reg) {
430
    case R_CONF:
431
        data = aspeed_2500_sdmc_compute_conf(s, data);
432
        break;
433
    case R_STATUS1:
434
        /* Will never return 'busy' */
435
        data &= ~PHY_BUSY_STATE;
436
        break;
437
    case R_ECC_TEST_CTRL:
438
        /* Always done, always happy */
439
        data |= ECC_TEST_FINISHED;
440
        data &= ~ECC_TEST_FAIL;
441
        break;
442
    default:
443
        break;
444
    }
445

446
    s->regs[reg] = data;
447
}
448

449
static const uint64_t
450
aspeed_2500_ram_sizes[] = { 128 * MiB, 256 * MiB, 512 * MiB, 1024 * MiB, 0};
451

452
static void aspeed_2500_sdmc_class_init(ObjectClass *klass, void *data)
453
{
454
    DeviceClass *dc = DEVICE_CLASS(klass);
455
    AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);
456

457
    dc->desc = "ASPEED 2500 SDRAM Memory Controller";
458
    asc->max_ram_size = 1 * GiB;
459
    asc->compute_conf = aspeed_2500_sdmc_compute_conf;
460
    asc->write = aspeed_2500_sdmc_write;
461
    asc->valid_ram_sizes = aspeed_2500_ram_sizes;
462
}
463

464
static const TypeInfo aspeed_2500_sdmc_info = {
465
    .name = TYPE_ASPEED_2500_SDMC,
466
    .parent = TYPE_ASPEED_SDMC,
467
    .class_init = aspeed_2500_sdmc_class_init,
468
};
469

470
static uint32_t aspeed_2600_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
471
{
472
    uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(3) |
473
        ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
474
        ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
475

476
    /* Make sure readonly bits are kept (use ast2500 mask) */
477
    data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;
478

479
    return data | fixed_conf;
480
}
481

482
static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg,
483
                                   uint32_t data)
484
{
485
    /* Unprotected registers */
486
    switch (reg) {
487
    case R_ISR:
488
    case R_MCR6C:
489
    case R_TEST_START_LEN:
490
    case R_TEST_FAIL_DQ:
491
    case R_TEST_INIT_VAL:
492
    case R_DRAM_SW:
493
    case R_DRAM_TIME:
494
    case R_ECC_ERR_INJECT:
495
        s->regs[reg] = data;
496
        return;
497
    }
498

499
    if (s->regs[R_PROT] == PROT_HARDLOCKED) {
500
        qemu_log_mask(LOG_GUEST_ERROR,
501
                      "%s: SDMC is locked until system reset!\n",
502
                      __func__);
503
        return;
504
    }
505

506
    if (reg != R_PROT && s->regs[R_PROT] == PROT_SOFTLOCKED) {
507
        qemu_log_mask(LOG_GUEST_ERROR,
508
                      "%s: SDMC is locked! (write to MCR%02x blocked)\n",
509
                      __func__, reg * 4);
510
        return;
511
    }
512

513
    switch (reg) {
514
    case R_PROT:
515
        if (data == PROT_KEY_UNLOCK)  {
516
            data = PROT_UNLOCKED;
517
        } else if (data == PROT_KEY_HARDLOCK) {
518
            data = PROT_HARDLOCKED;
519
        } else {
520
            data = PROT_SOFTLOCKED;
521
        }
522
        break;
523
    case R_CONF:
524
        data = aspeed_2600_sdmc_compute_conf(s, data);
525
        break;
526
    case R_STATUS1:
527
        /* Will never return 'busy'. 'lock status' is always set */
528
        data &= ~PHY_BUSY_STATE;
529
        data |= PHY_PLL_LOCK_STATUS;
530
        break;
531
    case R_ECC_TEST_CTRL:
532
        /* Always done, always happy */
533
        data |= ECC_TEST_FINISHED;
534
        data &= ~ECC_TEST_FAIL;
535
        break;
536
    default:
537
        break;
538
    }
539

540
    s->regs[reg] = data;
541
}
542

543
static const uint64_t
544
aspeed_2600_ram_sizes[] = { 256 * MiB, 512 * MiB, 1024 * MiB, 2048 * MiB, 0};
545

546
static void aspeed_2600_sdmc_class_init(ObjectClass *klass, void *data)
547
{
548
    DeviceClass *dc = DEVICE_CLASS(klass);
549
    AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);
550

551
    dc->desc = "ASPEED 2600 SDRAM Memory Controller";
552
    asc->max_ram_size = 2 * GiB;
553
    asc->compute_conf = aspeed_2600_sdmc_compute_conf;
554
    asc->write = aspeed_2600_sdmc_write;
555
    asc->valid_ram_sizes = aspeed_2600_ram_sizes;
556
}
557

558
static const TypeInfo aspeed_2600_sdmc_info = {
559
    .name = TYPE_ASPEED_2600_SDMC,
560
    .parent = TYPE_ASPEED_SDMC,
561
    .class_init = aspeed_2600_sdmc_class_init,
562
};
563

564
static void aspeed_2700_sdmc_reset(DeviceState *dev)
565
{
566
    AspeedSDMCState *s = ASPEED_SDMC(dev);
567
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
568

569
    memset(s->regs, 0, sizeof(s->regs));
570

571
    /* Set ram size bit and defaults values */
572
    s->regs[R_MAIN_CONF] = asc->compute_conf(s, 0);
573

574
    if (s->unlocked) {
575
        s->regs[R_2700_PROT] = PROT_UNLOCKED;
576
    }
577
}
578

579
static uint32_t aspeed_2700_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
580
{
581
    uint32_t fixed_conf = ASPEED_SDMC_AST2700_PAGE_MATCHING_ENABLE |
582
        ASPEED_SDMC_AST2700_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
583

584
    /* Make sure readonly bits are kept */
585
    data &= ~ASPEED_SDMC_AST2700_READONLY_MASK;
586

587
    return data | fixed_conf;
588
}
589

590
static void aspeed_2700_sdmc_write(AspeedSDMCState *s, uint32_t reg,
591
                                   uint32_t data)
592
{
593
    /* Unprotected registers */
594
    switch (reg) {
595
    case R_INT_STATUS:
596
    case R_INT_CLEAR:
597
    case R_INT_MASK:
598
    case R_ERR_STATUS:
599
    case R_ECC_FAIL_STATUS:
600
    case R_ECC_FAIL_ADDR:
601
    case R_PROT_REGION_LOCK_STATUS:
602
    case R_TEST_FAIL_ADDR:
603
    case R_TEST_FAIL_D0:
604
    case R_TEST_FAIL_D1:
605
    case R_TEST_FAIL_D2:
606
    case R_TEST_FAIL_D3:
607
    case R_DBG_STATUS:
608
    case R_PHY_INTERFACE_STATUS:
609
    case R_GRAPHIC_MEM_BASE_ADDR:
610
    case R_PORT0_INTERFACE_MONITOR0:
611
    case R_PORT0_INTERFACE_MONITOR1:
612
    case R_PORT0_INTERFACE_MONITOR2:
613
    case R_PORT1_INTERFACE_MONITOR0:
614
    case R_PORT1_INTERFACE_MONITOR1:
615
    case R_PORT1_INTERFACE_MONITOR2:
616
    case R_PORT2_INTERFACE_MONITOR0:
617
    case R_PORT2_INTERFACE_MONITOR1:
618
    case R_PORT2_INTERFACE_MONITOR2:
619
    case R_PORT3_INTERFACE_MONITOR0:
620
    case R_PORT3_INTERFACE_MONITOR1:
621
    case R_PORT3_INTERFACE_MONITOR2:
622
    case R_PORT4_INTERFACE_MONITOR0:
623
    case R_PORT4_INTERFACE_MONITOR1:
624
    case R_PORT4_INTERFACE_MONITOR2:
625
    case R_PORT5_INTERFACE_MONITOR0:
626
    case R_PORT5_INTERFACE_MONITOR1:
627
    case R_PORT5_INTERFACE_MONITOR2:
628
        s->regs[reg] = data;
629
        return;
630
    }
631

632
    if (s->regs[R_2700_PROT] == PROT_HARDLOCKED) {
633
        qemu_log_mask(LOG_GUEST_ERROR,
634
                      "%s: SDMC is locked until system reset!\n",
635
                      __func__);
636
        return;
637
    }
638

639
    if (reg != R_2700_PROT && s->regs[R_2700_PROT] == PROT_SOFTLOCKED) {
640
        qemu_log_mask(LOG_GUEST_ERROR,
641
                      "%s: SDMC is locked! (write to MCR%02x blocked)\n",
642
                      __func__, reg * 4);
643
        return;
644
    }
645

646
    switch (reg) {
647
    case R_2700_PROT:
648
        if (data == PROT_2700_KEY_UNLOCK)  {
649
            data = PROT_UNLOCKED;
650
        } else if (data == PROT_KEY_HARDLOCK) {
651
            data = PROT_HARDLOCKED;
652
        } else {
653
            data = PROT_SOFTLOCKED;
654
        }
655
        break;
656
    case R_MAIN_CONF:
657
        data = aspeed_2700_sdmc_compute_conf(s, data);
658
        break;
659
    case R_MAIN_STATUS:
660
        /* Will never return 'busy'. */
661
        data &= ~PHY_BUSY_STATE;
662
        break;
663
    default:
664
        break;
665
    }
666

667
    s->regs[reg] = data;
668
}
669

670
static const uint64_t
671
    aspeed_2700_ram_sizes[] = { 256 * MiB, 512 * MiB, 1024 * MiB,
672
                                2048 * MiB, 4096 * MiB, 8192 * MiB, 0};
673

674
static void aspeed_2700_sdmc_class_init(ObjectClass *klass, void *data)
675
{
676
    DeviceClass *dc = DEVICE_CLASS(klass);
677
    AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);
678

679
    dc->desc = "ASPEED 2700 SDRAM Memory Controller";
680
    dc->reset = aspeed_2700_sdmc_reset;
681

682
    asc->is_bus64bit = true;
683
    asc->max_ram_size = 8 * GiB;
684
    asc->compute_conf = aspeed_2700_sdmc_compute_conf;
685
    asc->write = aspeed_2700_sdmc_write;
686
    asc->valid_ram_sizes = aspeed_2700_ram_sizes;
687
}
688

689
static const TypeInfo aspeed_2700_sdmc_info = {
690
    .name = TYPE_ASPEED_2700_SDMC,
691
    .parent = TYPE_ASPEED_SDMC,
692
    .class_init = aspeed_2700_sdmc_class_init,
693
};
694

695
static void aspeed_sdmc_register_types(void)
696
{
697
    type_register_static(&aspeed_sdmc_info);
698
    type_register_static(&aspeed_2400_sdmc_info);
699
    type_register_static(&aspeed_2500_sdmc_info);
700
    type_register_static(&aspeed_2600_sdmc_info);
701
    type_register_static(&aspeed_2700_sdmc_info);
702
}
703

704
type_init(aspeed_sdmc_register_types);
705

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.