~ahs3/+junk/cq-qemu

« back to all changes in this revision

Viewing changes to hw/ppc4xx_devs.c

  • Committer: Al Stone
  • Date: 2012-02-09 01:17:20 UTC
  • Revision ID: albert.stone@canonical.com-20120209011720-tztl7ik3qayz80p4
first commit to bzr for qemu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * QEMU PowerPC 4xx embedded processors shared devices emulation
 
3
 *
 
4
 * Copyright (c) 2007 Jocelyn Mayer
 
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
#include "hw.h"
 
25
#include "ppc.h"
 
26
#include "ppc4xx.h"
 
27
#include "qemu-log.h"
 
28
#include "exec-memory.h"
 
29
 
 
30
//#define DEBUG_MMIO
 
31
//#define DEBUG_UNASSIGNED
 
32
#define DEBUG_UIC
 
33
 
 
34
 
 
35
#ifdef DEBUG_UIC
 
36
#  define LOG_UIC(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
 
37
#else
 
38
#  define LOG_UIC(...) do { } while (0)
 
39
#endif
 
40
 
 
41
/*****************************************************************************/
 
42
/* Generic PowerPC 4xx processor instantiation */
 
43
CPUState *ppc4xx_init (const char *cpu_model,
 
44
                       clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
 
45
                       uint32_t sysclk)
 
46
{
 
47
    CPUState *env;
 
48
 
 
49
    /* init CPUs */
 
50
    env = cpu_init(cpu_model);
 
51
    if (!env) {
 
52
        fprintf(stderr, "Unable to find PowerPC %s CPU definition\n",
 
53
                cpu_model);
 
54
        exit(1);
 
55
    }
 
56
    cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
 
57
    cpu_clk->opaque = env;
 
58
    /* Set time-base frequency to sysclk */
 
59
    tb_clk->cb = ppc_40x_timers_init(env, sysclk, PPC_INTERRUPT_PIT);
 
60
    tb_clk->opaque = env;
 
61
    ppc_dcr_init(env, NULL, NULL);
 
62
    /* Register qemu callbacks */
 
63
    qemu_register_reset((QEMUResetHandler*)&cpu_reset, env);
 
64
 
 
65
    return env;
 
66
}
 
67
 
 
68
/*****************************************************************************/
 
69
/* "Universal" Interrupt controller */
 
70
enum {
 
71
    DCR_UICSR  = 0x000,
 
72
    DCR_UICSRS = 0x001,
 
73
    DCR_UICER  = 0x002,
 
74
    DCR_UICCR  = 0x003,
 
75
    DCR_UICPR  = 0x004,
 
76
    DCR_UICTR  = 0x005,
 
77
    DCR_UICMSR = 0x006,
 
78
    DCR_UICVR  = 0x007,
 
79
    DCR_UICVCR = 0x008,
 
80
    DCR_UICMAX = 0x009,
 
81
};
 
82
 
 
83
#define UIC_MAX_IRQ 32
 
84
typedef struct ppcuic_t ppcuic_t;
 
85
struct ppcuic_t {
 
86
    uint32_t dcr_base;
 
87
    int use_vectors;
 
88
    uint32_t level;  /* Remembers the state of level-triggered interrupts. */
 
89
    uint32_t uicsr;  /* Status register */
 
90
    uint32_t uicer;  /* Enable register */
 
91
    uint32_t uiccr;  /* Critical register */
 
92
    uint32_t uicpr;  /* Polarity register */
 
93
    uint32_t uictr;  /* Triggering register */
 
94
    uint32_t uicvcr; /* Vector configuration register */
 
95
    uint32_t uicvr;
 
96
    qemu_irq *irqs;
 
97
};
 
98
 
 
99
static void ppcuic_trigger_irq (ppcuic_t *uic)
 
100
{
 
101
    uint32_t ir, cr;
 
102
    int start, end, inc, i;
 
103
 
 
104
    /* Trigger interrupt if any is pending */
 
105
    ir = uic->uicsr & uic->uicer & (~uic->uiccr);
 
106
    cr = uic->uicsr & uic->uicer & uic->uiccr;
 
107
    LOG_UIC("%s: uicsr %08" PRIx32 " uicer %08" PRIx32
 
108
                " uiccr %08" PRIx32 "\n"
 
109
                "   %08" PRIx32 " ir %08" PRIx32 " cr %08" PRIx32 "\n",
 
110
                __func__, uic->uicsr, uic->uicer, uic->uiccr,
 
111
                uic->uicsr & uic->uicer, ir, cr);
 
112
    if (ir != 0x0000000) {
 
113
        LOG_UIC("Raise UIC interrupt\n");
 
114
        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_INT]);
 
115
    } else {
 
116
        LOG_UIC("Lower UIC interrupt\n");
 
117
        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_INT]);
 
118
    }
 
119
    /* Trigger critical interrupt if any is pending and update vector */
 
120
    if (cr != 0x0000000) {
 
121
        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_CINT]);
 
122
        if (uic->use_vectors) {
 
123
            /* Compute critical IRQ vector */
 
124
            if (uic->uicvcr & 1) {
 
125
                start = 31;
 
126
                end = 0;
 
127
                inc = -1;
 
128
            } else {
 
129
                start = 0;
 
130
                end = 31;
 
131
                inc = 1;
 
132
            }
 
133
            uic->uicvr = uic->uicvcr & 0xFFFFFFFC;
 
134
            for (i = start; i <= end; i += inc) {
 
135
                if (cr & (1 << i)) {
 
136
                    uic->uicvr += (i - start) * 512 * inc;
 
137
                    break;
 
138
                }
 
139
            }
 
140
        }
 
141
        LOG_UIC("Raise UIC critical interrupt - "
 
142
                    "vector %08" PRIx32 "\n", uic->uicvr);
 
143
    } else {
 
144
        LOG_UIC("Lower UIC critical interrupt\n");
 
145
        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_CINT]);
 
146
        uic->uicvr = 0x00000000;
 
147
    }
 
148
}
 
149
 
 
150
static void ppcuic_set_irq (void *opaque, int irq_num, int level)
 
151
{
 
152
    ppcuic_t *uic;
 
153
    uint32_t mask, sr;
 
154
 
 
155
    uic = opaque;
 
156
    mask = 1 << (31-irq_num);
 
157
    LOG_UIC("%s: irq %d level %d uicsr %08" PRIx32
 
158
                " mask %08" PRIx32 " => %08" PRIx32 " %08" PRIx32 "\n",
 
159
                __func__, irq_num, level,
 
160
                uic->uicsr, mask, uic->uicsr & mask, level << irq_num);
 
161
    if (irq_num < 0 || irq_num > 31)
 
162
        return;
 
163
    sr = uic->uicsr;
 
164
 
 
165
    /* Update status register */
 
166
    if (uic->uictr & mask) {
 
167
        /* Edge sensitive interrupt */
 
168
        if (level == 1)
 
169
            uic->uicsr |= mask;
 
170
    } else {
 
171
        /* Level sensitive interrupt */
 
172
        if (level == 1) {
 
173
            uic->uicsr |= mask;
 
174
            uic->level |= mask;
 
175
        } else {
 
176
            uic->uicsr &= ~mask;
 
177
            uic->level &= ~mask;
 
178
        }
 
179
    }
 
180
    LOG_UIC("%s: irq %d level %d sr %" PRIx32 " => "
 
181
                "%08" PRIx32 "\n", __func__, irq_num, level, uic->uicsr, sr);
 
182
    if (sr != uic->uicsr)
 
183
        ppcuic_trigger_irq(uic);
 
184
}
 
185
 
 
186
static uint32_t dcr_read_uic (void *opaque, int dcrn)
 
187
{
 
188
    ppcuic_t *uic;
 
189
    uint32_t ret;
 
190
 
 
191
    uic = opaque;
 
192
    dcrn -= uic->dcr_base;
 
193
    switch (dcrn) {
 
194
    case DCR_UICSR:
 
195
    case DCR_UICSRS:
 
196
        ret = uic->uicsr;
 
197
        break;
 
198
    case DCR_UICER:
 
199
        ret = uic->uicer;
 
200
        break;
 
201
    case DCR_UICCR:
 
202
        ret = uic->uiccr;
 
203
        break;
 
204
    case DCR_UICPR:
 
205
        ret = uic->uicpr;
 
206
        break;
 
207
    case DCR_UICTR:
 
208
        ret = uic->uictr;
 
209
        break;
 
210
    case DCR_UICMSR:
 
211
        ret = uic->uicsr & uic->uicer;
 
212
        break;
 
213
    case DCR_UICVR:
 
214
        if (!uic->use_vectors)
 
215
            goto no_read;
 
216
        ret = uic->uicvr;
 
217
        break;
 
218
    case DCR_UICVCR:
 
219
        if (!uic->use_vectors)
 
220
            goto no_read;
 
221
        ret = uic->uicvcr;
 
222
        break;
 
223
    default:
 
224
    no_read:
 
225
        ret = 0x00000000;
 
226
        break;
 
227
    }
 
228
 
 
229
    return ret;
 
230
}
 
231
 
 
232
static void dcr_write_uic (void *opaque, int dcrn, uint32_t val)
 
233
{
 
234
    ppcuic_t *uic;
 
235
 
 
236
    uic = opaque;
 
237
    dcrn -= uic->dcr_base;
 
238
    LOG_UIC("%s: dcr %d val 0x%x\n", __func__, dcrn, val);
 
239
    switch (dcrn) {
 
240
    case DCR_UICSR:
 
241
        uic->uicsr &= ~val;
 
242
        uic->uicsr |= uic->level;
 
243
        ppcuic_trigger_irq(uic);
 
244
        break;
 
245
    case DCR_UICSRS:
 
246
        uic->uicsr |= val;
 
247
        ppcuic_trigger_irq(uic);
 
248
        break;
 
249
    case DCR_UICER:
 
250
        uic->uicer = val;
 
251
        ppcuic_trigger_irq(uic);
 
252
        break;
 
253
    case DCR_UICCR:
 
254
        uic->uiccr = val;
 
255
        ppcuic_trigger_irq(uic);
 
256
        break;
 
257
    case DCR_UICPR:
 
258
        uic->uicpr = val;
 
259
        break;
 
260
    case DCR_UICTR:
 
261
        uic->uictr = val;
 
262
        ppcuic_trigger_irq(uic);
 
263
        break;
 
264
    case DCR_UICMSR:
 
265
        break;
 
266
    case DCR_UICVR:
 
267
        break;
 
268
    case DCR_UICVCR:
 
269
        uic->uicvcr = val & 0xFFFFFFFD;
 
270
        ppcuic_trigger_irq(uic);
 
271
        break;
 
272
    }
 
273
}
 
274
 
 
275
static void ppcuic_reset (void *opaque)
 
276
{
 
277
    ppcuic_t *uic;
 
278
 
 
279
    uic = opaque;
 
280
    uic->uiccr = 0x00000000;
 
281
    uic->uicer = 0x00000000;
 
282
    uic->uicpr = 0x00000000;
 
283
    uic->uicsr = 0x00000000;
 
284
    uic->uictr = 0x00000000;
 
285
    if (uic->use_vectors) {
 
286
        uic->uicvcr = 0x00000000;
 
287
        uic->uicvr = 0x0000000;
 
288
    }
 
289
}
 
290
 
 
291
qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
 
292
                       uint32_t dcr_base, int has_ssr, int has_vr)
 
293
{
 
294
    ppcuic_t *uic;
 
295
    int i;
 
296
 
 
297
    uic = g_malloc0(sizeof(ppcuic_t));
 
298
    uic->dcr_base = dcr_base;
 
299
    uic->irqs = irqs;
 
300
    if (has_vr)
 
301
        uic->use_vectors = 1;
 
302
    for (i = 0; i < DCR_UICMAX; i++) {
 
303
        ppc_dcr_register(env, dcr_base + i, uic,
 
304
                         &dcr_read_uic, &dcr_write_uic);
 
305
    }
 
306
    qemu_register_reset(ppcuic_reset, uic);
 
307
 
 
308
    return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ);
 
309
}
 
310
 
 
311
/*****************************************************************************/
 
312
/* SDRAM controller */
 
313
typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
 
314
struct ppc4xx_sdram_t {
 
315
    uint32_t addr;
 
316
    int nbanks;
 
317
    MemoryRegion containers[4]; /* used for clipping */
 
318
    MemoryRegion *ram_memories;
 
319
    target_phys_addr_t ram_bases[4];
 
320
    target_phys_addr_t ram_sizes[4];
 
321
    uint32_t besr0;
 
322
    uint32_t besr1;
 
323
    uint32_t bear;
 
324
    uint32_t cfg;
 
325
    uint32_t status;
 
326
    uint32_t rtr;
 
327
    uint32_t pmit;
 
328
    uint32_t bcr[4];
 
329
    uint32_t tr;
 
330
    uint32_t ecccfg;
 
331
    uint32_t eccesr;
 
332
    qemu_irq irq;
 
333
};
 
334
 
 
335
enum {
 
336
    SDRAM0_CFGADDR = 0x010,
 
337
    SDRAM0_CFGDATA = 0x011,
 
338
};
 
339
 
 
340
/* XXX: TOFIX: some patches have made this code become inconsistent:
 
341
 *      there are type inconsistencies, mixing target_phys_addr_t, target_ulong
 
342
 *      and uint32_t
 
343
 */
 
344
static uint32_t sdram_bcr (target_phys_addr_t ram_base,
 
345
                           target_phys_addr_t ram_size)
 
346
{
 
347
    uint32_t bcr;
 
348
 
 
349
    switch (ram_size) {
 
350
    case (4 * 1024 * 1024):
 
351
        bcr = 0x00000000;
 
352
        break;
 
353
    case (8 * 1024 * 1024):
 
354
        bcr = 0x00020000;
 
355
        break;
 
356
    case (16 * 1024 * 1024):
 
357
        bcr = 0x00040000;
 
358
        break;
 
359
    case (32 * 1024 * 1024):
 
360
        bcr = 0x00060000;
 
361
        break;
 
362
    case (64 * 1024 * 1024):
 
363
        bcr = 0x00080000;
 
364
        break;
 
365
    case (128 * 1024 * 1024):
 
366
        bcr = 0x000A0000;
 
367
        break;
 
368
    case (256 * 1024 * 1024):
 
369
        bcr = 0x000C0000;
 
370
        break;
 
371
    default:
 
372
        printf("%s: invalid RAM size " TARGET_FMT_plx "\n", __func__,
 
373
               ram_size);
 
374
        return 0x00000000;
 
375
    }
 
376
    bcr |= ram_base & 0xFF800000;
 
377
    bcr |= 1;
 
378
 
 
379
    return bcr;
 
380
}
 
381
 
 
382
static inline target_phys_addr_t sdram_base(uint32_t bcr)
 
383
{
 
384
    return bcr & 0xFF800000;
 
385
}
 
386
 
 
387
static target_ulong sdram_size (uint32_t bcr)
 
388
{
 
389
    target_ulong size;
 
390
    int sh;
 
391
 
 
392
    sh = (bcr >> 17) & 0x7;
 
393
    if (sh == 7)
 
394
        size = -1;
 
395
    else
 
396
        size = (4 * 1024 * 1024) << sh;
 
397
 
 
398
    return size;
 
399
}
 
400
 
 
401
static void sdram_set_bcr(ppc4xx_sdram_t *sdram,
 
402
                          uint32_t *bcrp, uint32_t bcr, int enabled)
 
403
{
 
404
    unsigned n = bcrp - sdram->bcr;
 
405
 
 
406
    if (*bcrp & 0x00000001) {
 
407
        /* Unmap RAM */
 
408
#ifdef DEBUG_SDRAM
 
409
        printf("%s: unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
 
410
               __func__, sdram_base(*bcrp), sdram_size(*bcrp));
 
411
#endif
 
412
        memory_region_del_subregion(get_system_memory(),
 
413
                                    &sdram->containers[n]);
 
414
        memory_region_del_subregion(&sdram->containers[n],
 
415
                                    &sdram->ram_memories[n]);
 
416
        memory_region_destroy(&sdram->containers[n]);
 
417
    }
 
418
    *bcrp = bcr & 0xFFDEE001;
 
419
    if (enabled && (bcr & 0x00000001)) {
 
420
#ifdef DEBUG_SDRAM
 
421
        printf("%s: Map RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
 
422
               __func__, sdram_base(bcr), sdram_size(bcr));
 
423
#endif
 
424
        memory_region_init(&sdram->containers[n], "sdram-containers",
 
425
                           sdram_size(bcr));
 
426
        memory_region_add_subregion(&sdram->containers[n], 0,
 
427
                                    &sdram->ram_memories[n]);
 
428
        memory_region_add_subregion(get_system_memory(),
 
429
                                    sdram_base(bcr),
 
430
                                    &sdram->containers[n]);
 
431
    }
 
432
}
 
433
 
 
434
static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
 
435
{
 
436
    int i;
 
437
 
 
438
    for (i = 0; i < sdram->nbanks; i++) {
 
439
        if (sdram->ram_sizes[i] != 0) {
 
440
            sdram_set_bcr(sdram,
 
441
                          &sdram->bcr[i],
 
442
                          sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]),
 
443
                          1);
 
444
        } else {
 
445
            sdram_set_bcr(sdram, &sdram->bcr[i], 0x00000000, 0);
 
446
        }
 
447
    }
 
448
}
 
449
 
 
450
static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
 
451
{
 
452
    int i;
 
453
 
 
454
    for (i = 0; i < sdram->nbanks; i++) {
 
455
#ifdef DEBUG_SDRAM
 
456
        printf("%s: Unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
 
457
               __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
 
458
#endif
 
459
        memory_region_del_subregion(get_system_memory(),
 
460
                                    &sdram->ram_memories[i]);
 
461
    }
 
462
}
 
463
 
 
464
static uint32_t dcr_read_sdram (void *opaque, int dcrn)
 
465
{
 
466
    ppc4xx_sdram_t *sdram;
 
467
    uint32_t ret;
 
468
 
 
469
    sdram = opaque;
 
470
    switch (dcrn) {
 
471
    case SDRAM0_CFGADDR:
 
472
        ret = sdram->addr;
 
473
        break;
 
474
    case SDRAM0_CFGDATA:
 
475
        switch (sdram->addr) {
 
476
        case 0x00: /* SDRAM_BESR0 */
 
477
            ret = sdram->besr0;
 
478
            break;
 
479
        case 0x08: /* SDRAM_BESR1 */
 
480
            ret = sdram->besr1;
 
481
            break;
 
482
        case 0x10: /* SDRAM_BEAR */
 
483
            ret = sdram->bear;
 
484
            break;
 
485
        case 0x20: /* SDRAM_CFG */
 
486
            ret = sdram->cfg;
 
487
            break;
 
488
        case 0x24: /* SDRAM_STATUS */
 
489
            ret = sdram->status;
 
490
            break;
 
491
        case 0x30: /* SDRAM_RTR */
 
492
            ret = sdram->rtr;
 
493
            break;
 
494
        case 0x34: /* SDRAM_PMIT */
 
495
            ret = sdram->pmit;
 
496
            break;
 
497
        case 0x40: /* SDRAM_B0CR */
 
498
            ret = sdram->bcr[0];
 
499
            break;
 
500
        case 0x44: /* SDRAM_B1CR */
 
501
            ret = sdram->bcr[1];
 
502
            break;
 
503
        case 0x48: /* SDRAM_B2CR */
 
504
            ret = sdram->bcr[2];
 
505
            break;
 
506
        case 0x4C: /* SDRAM_B3CR */
 
507
            ret = sdram->bcr[3];
 
508
            break;
 
509
        case 0x80: /* SDRAM_TR */
 
510
            ret = -1; /* ? */
 
511
            break;
 
512
        case 0x94: /* SDRAM_ECCCFG */
 
513
            ret = sdram->ecccfg;
 
514
            break;
 
515
        case 0x98: /* SDRAM_ECCESR */
 
516
            ret = sdram->eccesr;
 
517
            break;
 
518
        default: /* Error */
 
519
            ret = -1;
 
520
            break;
 
521
        }
 
522
        break;
 
523
    default:
 
524
        /* Avoid gcc warning */
 
525
        ret = 0x00000000;
 
526
        break;
 
527
    }
 
528
 
 
529
    return ret;
 
530
}
 
531
 
 
532
static void dcr_write_sdram (void *opaque, int dcrn, uint32_t val)
 
533
{
 
534
    ppc4xx_sdram_t *sdram;
 
535
 
 
536
    sdram = opaque;
 
537
    switch (dcrn) {
 
538
    case SDRAM0_CFGADDR:
 
539
        sdram->addr = val;
 
540
        break;
 
541
    case SDRAM0_CFGDATA:
 
542
        switch (sdram->addr) {
 
543
        case 0x00: /* SDRAM_BESR0 */
 
544
            sdram->besr0 &= ~val;
 
545
            break;
 
546
        case 0x08: /* SDRAM_BESR1 */
 
547
            sdram->besr1 &= ~val;
 
548
            break;
 
549
        case 0x10: /* SDRAM_BEAR */
 
550
            sdram->bear = val;
 
551
            break;
 
552
        case 0x20: /* SDRAM_CFG */
 
553
            val &= 0xFFE00000;
 
554
            if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
 
555
#ifdef DEBUG_SDRAM
 
556
                printf("%s: enable SDRAM controller\n", __func__);
 
557
#endif
 
558
                /* validate all RAM mappings */
 
559
                sdram_map_bcr(sdram);
 
560
                sdram->status &= ~0x80000000;
 
561
            } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
 
562
#ifdef DEBUG_SDRAM
 
563
                printf("%s: disable SDRAM controller\n", __func__);
 
564
#endif
 
565
                /* invalidate all RAM mappings */
 
566
                sdram_unmap_bcr(sdram);
 
567
                sdram->status |= 0x80000000;
 
568
            }
 
569
            if (!(sdram->cfg & 0x40000000) && (val & 0x40000000))
 
570
                sdram->status |= 0x40000000;
 
571
            else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000))
 
572
                sdram->status &= ~0x40000000;
 
573
            sdram->cfg = val;
 
574
            break;
 
575
        case 0x24: /* SDRAM_STATUS */
 
576
            /* Read-only register */
 
577
            break;
 
578
        case 0x30: /* SDRAM_RTR */
 
579
            sdram->rtr = val & 0x3FF80000;
 
580
            break;
 
581
        case 0x34: /* SDRAM_PMIT */
 
582
            sdram->pmit = (val & 0xF8000000) | 0x07C00000;
 
583
            break;
 
584
        case 0x40: /* SDRAM_B0CR */
 
585
            sdram_set_bcr(sdram, &sdram->bcr[0], val, sdram->cfg & 0x80000000);
 
586
            break;
 
587
        case 0x44: /* SDRAM_B1CR */
 
588
            sdram_set_bcr(sdram, &sdram->bcr[1], val, sdram->cfg & 0x80000000);
 
589
            break;
 
590
        case 0x48: /* SDRAM_B2CR */
 
591
            sdram_set_bcr(sdram, &sdram->bcr[2], val, sdram->cfg & 0x80000000);
 
592
            break;
 
593
        case 0x4C: /* SDRAM_B3CR */
 
594
            sdram_set_bcr(sdram, &sdram->bcr[3], val, sdram->cfg & 0x80000000);
 
595
            break;
 
596
        case 0x80: /* SDRAM_TR */
 
597
            sdram->tr = val & 0x018FC01F;
 
598
            break;
 
599
        case 0x94: /* SDRAM_ECCCFG */
 
600
            sdram->ecccfg = val & 0x00F00000;
 
601
            break;
 
602
        case 0x98: /* SDRAM_ECCESR */
 
603
            val &= 0xFFF0F000;
 
604
            if (sdram->eccesr == 0 && val != 0)
 
605
                qemu_irq_raise(sdram->irq);
 
606
            else if (sdram->eccesr != 0 && val == 0)
 
607
                qemu_irq_lower(sdram->irq);
 
608
            sdram->eccesr = val;
 
609
            break;
 
610
        default: /* Error */
 
611
            break;
 
612
        }
 
613
        break;
 
614
    }
 
615
}
 
616
 
 
617
static void sdram_reset (void *opaque)
 
618
{
 
619
    ppc4xx_sdram_t *sdram;
 
620
 
 
621
    sdram = opaque;
 
622
    sdram->addr = 0x00000000;
 
623
    sdram->bear = 0x00000000;
 
624
    sdram->besr0 = 0x00000000; /* No error */
 
625
    sdram->besr1 = 0x00000000; /* No error */
 
626
    sdram->cfg = 0x00000000;
 
627
    sdram->ecccfg = 0x00000000; /* No ECC */
 
628
    sdram->eccesr = 0x00000000; /* No error */
 
629
    sdram->pmit = 0x07C00000;
 
630
    sdram->rtr = 0x05F00000;
 
631
    sdram->tr = 0x00854009;
 
632
    /* We pre-initialize RAM banks */
 
633
    sdram->status = 0x00000000;
 
634
    sdram->cfg = 0x00800000;
 
635
}
 
636
 
 
637
void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
 
638
                        MemoryRegion *ram_memories,
 
639
                        target_phys_addr_t *ram_bases,
 
640
                        target_phys_addr_t *ram_sizes,
 
641
                        int do_init)
 
642
{
 
643
    ppc4xx_sdram_t *sdram;
 
644
 
 
645
    sdram = g_malloc0(sizeof(ppc4xx_sdram_t));
 
646
    sdram->irq = irq;
 
647
    sdram->nbanks = nbanks;
 
648
    sdram->ram_memories = ram_memories;
 
649
    memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t));
 
650
    memcpy(sdram->ram_bases, ram_bases,
 
651
           nbanks * sizeof(target_phys_addr_t));
 
652
    memset(sdram->ram_sizes, 0, 4 * sizeof(target_phys_addr_t));
 
653
    memcpy(sdram->ram_sizes, ram_sizes,
 
654
           nbanks * sizeof(target_phys_addr_t));
 
655
    qemu_register_reset(&sdram_reset, sdram);
 
656
    ppc_dcr_register(env, SDRAM0_CFGADDR,
 
657
                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 
658
    ppc_dcr_register(env, SDRAM0_CFGDATA,
 
659
                     sdram, &dcr_read_sdram, &dcr_write_sdram);
 
660
    if (do_init)
 
661
        sdram_map_bcr(sdram);
 
662
}
 
663
 
 
664
/* Fill in consecutive SDRAM banks with 'ram_size' bytes of memory.
 
665
 *
 
666
 * sdram_bank_sizes[] must be 0-terminated.
 
667
 *
 
668
 * The 4xx SDRAM controller supports a small number of banks, and each bank
 
669
 * must be one of a small set of sizes. The number of banks and the supported
 
670
 * sizes varies by SoC. */
 
671
ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
 
672
                               MemoryRegion ram_memories[],
 
673
                               target_phys_addr_t ram_bases[],
 
674
                               target_phys_addr_t ram_sizes[],
 
675
                               const unsigned int sdram_bank_sizes[])
 
676
{
 
677
    ram_addr_t size_left = ram_size;
 
678
    ram_addr_t base = 0;
 
679
    int i;
 
680
    int j;
 
681
 
 
682
    for (i = 0; i < nr_banks; i++) {
 
683
        for (j = 0; sdram_bank_sizes[j] != 0; j++) {
 
684
            unsigned int bank_size = sdram_bank_sizes[j];
 
685
 
 
686
            if (bank_size <= size_left) {
 
687
                char name[32];
 
688
                snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
 
689
                memory_region_init_ram(&ram_memories[i], NULL, name, bank_size);
 
690
                ram_bases[i] = base;
 
691
                ram_sizes[i] = bank_size;
 
692
                base += ram_size;
 
693
                size_left -= bank_size;
 
694
                break;
 
695
            }
 
696
        }
 
697
 
 
698
        if (!size_left) {
 
699
            /* No need to use the remaining banks. */
 
700
            break;
 
701
        }
 
702
    }
 
703
 
 
704
    ram_size -= size_left;
 
705
    if (size_left)
 
706
        printf("Truncating memory to %d MiB to fit SDRAM controller limits.\n",
 
707
               (int)(ram_size >> 20));
 
708
 
 
709
    return ram_size;
 
710
}