Revision 8ecc7913

b/Makefile.target
421 421
endif
422 422
ifeq ($(TARGET_BASE_ARCH), ppc)
423 423
VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
424
VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
424
VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o pflash_cfi02.o
425 425
VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
426
VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o
426
VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o ppc405_uc.o
427 427
CPPFLAGS += -DHAS_AUDIO
428 428
endif
429 429
ifeq ($(TARGET_BASE_ARCH), mips)
b/hw/ppc.c
290 290
    int cur_level;
291 291

  
292 292
#if defined(PPC_DEBUG_IRQ)
293
    printf("%s: env %p pin %d level %d\n", __func__, env, pin, level);
293
    if (loglevel & CPU_LOG_INT) {
294
        fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
295
                env, pin, level);
296
    }
294 297
#endif
295 298
    cur_level = (env->irq_input_state >> pin) & 1;
296 299
    /* Don't generate spurious events */
297 300
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
298 301
        switch (pin) {
299 302
        case PPC405_INPUT_RESET_SYS:
300
            /* XXX: TODO: reset all peripherals */
301
            /* No break here */
303
            if (level) {
304
#if defined(PPC_DEBUG_IRQ)
305
                if (loglevel & CPU_LOG_INT) {
306
                    fprintf(logfile, "%s: reset the PowerPC system\n",
307
                            __func__);
308
                }
309
#endif
310
                ppc40x_system_reset(env);
311
            }
312
            break;
302 313
        case PPC405_INPUT_RESET_CHIP:
303
            /* XXX: TODO: reset on-chip peripherals */
314
            if (level) {
315
#if defined(PPC_DEBUG_IRQ)
316
                if (loglevel & CPU_LOG_INT) {
317
                    fprintf(logfile, "%s: reset the PowerPC chip\n", __func__);
318
                }
319
#endif
320
                ppc40x_chip_reset(env);
321
            }
322
            break;
304 323
            /* No break here */
305 324
        case PPC405_INPUT_RESET_CORE:
306 325
            /* XXX: TODO: update DBSR[MRR] */
307 326
            if (level) {
308
#if 0 // XXX: TOFIX
309 327
#if defined(PPC_DEBUG_IRQ)
310
                printf("%s: reset the CPU\n", __func__);
311
#endif
312
                cpu_reset(env);
328
                if (loglevel & CPU_LOG_INT) {
329
                    fprintf(logfile, "%s: reset the PowerPC core\n", __func__);
330
                }
313 331
#endif
332
                ppc40x_core_reset(env);
314 333
            }
315 334
            break;
316 335
        case PPC405_INPUT_CINT:
317 336
            /* Level sensitive - active high */
318 337
#if defined(PPC_DEBUG_IRQ)
319
            printf("%s: set the critical IRQ state to %d\n", __func__, level);
338
            if (loglevel & CPU_LOG_INT) {
339
                fprintf(logfile, "%s: set the critical IRQ state to %d\n",
340
                        __func__, level);
341
            }
320 342
#endif
321 343
            /* XXX: TOFIX */
322 344
            ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
......
538 560
    _cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
539 561
}
540 562

  
563
static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
564
{
565
    CPUState *env = opaque;
566
    ppc_tb_t *tb_env = env->tb_env;
567

  
568
    tb_env->tb_freq = freq;
569
    /* There is a bug in Linux 2.4 kernels:
570
     * if a decrementer exception is pending when it enables msr_ee at startup,
571
     * it's not ready to handle it...
572
     */
573
    _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
574
}
575

  
541 576
/* Set up (once) timebase frequency (in Hz) */
542
ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq)
577
clk_setup_cb cpu_ppc_tb_init (CPUState *env, uint32_t freq)
543 578
{
544 579
    ppc_tb_t *tb_env;
545 580

  
......
547 582
    if (tb_env == NULL)
548 583
        return NULL;
549 584
    env->tb_env = tb_env;
550
    if (tb_env->tb_freq == 0 || 1) {
551
        tb_env->tb_freq = freq;
552
        /* Create new timer */
553
        tb_env->decr_timer =
554
            qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
555
        /* There is a bug in Linux 2.4 kernels:
556
         * if a decrementer exception is pending when it enables msr_ee,
557
         * it's not ready to handle it...
558
         */
559
        _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
560
    }
585
    /* Create new timer */
586
    tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
587
    cpu_ppc_set_tb_clk(env, freq);
561 588

  
562
    return tb_env;
589
    return &cpu_ppc_set_tb_clk;
563 590
}
564 591

  
565 592
/* Specific helpers for POWER & PowerPC 601 RTC */
566
ppc_tb_t *cpu_ppc601_rtc_init (CPUState *env)
593
clk_setup_cb cpu_ppc601_rtc_init (CPUState *env)
567 594
{
568 595
    return cpu_ppc_tb_init(env, 7812500);
569 596
}
......
733 760
            /* No reset */
734 761
            break;
735 762
        case 0x1: /* Core reset */
763
            ppc40x_core_reset(env);
764
            break;
736 765
        case 0x2: /* Chip reset */
766
            ppc40x_chip_reset(env);
767
            break;
737 768
        case 0x3: /* System reset */
738
            qemu_system_reset_request();
739
            return;
769
            ppc40x_system_reset(env);
770
            break;
740 771
        }
741 772
    }
742 773
}
......
784 815

  
785 816
void store_booke_tcr (CPUState *env, target_ulong val)
786 817
{
787
    /* We don't update timers now. Maybe we should... */
788 818
    env->spr[SPR_40x_TCR] = val & 0xFF800000;
819
    cpu_4xx_wdt_cb(env);
789 820
}
790 821

  
791
void ppc_emb_timers_init (CPUState *env)
822
clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq)
792 823
{
793 824
    ppc_tb_t *tb_env;
794 825
    ppcemb_timer_t *ppcemb_timer;
795 826

  
796
    tb_env = env->tb_env;
827
    tb_env = qemu_mallocz(sizeof(ppc_tb_t));
828
    if (tb_env == NULL)
829
        return NULL;
830
    env->tb_env = tb_env;
797 831
    ppcemb_timer = qemu_mallocz(sizeof(ppcemb_timer_t));
832
    tb_env->tb_freq = freq;
798 833
    tb_env->opaque = ppcemb_timer;
799
    if (loglevel)
834
    if (loglevel) {
800 835
        fprintf(logfile, "%s %p %p\n", __func__, tb_env, ppcemb_timer);
836
    }
801 837
    if (ppcemb_timer != NULL) {
802 838
        /* We use decr timer for PIT */
803 839
        tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_4xx_pit_cb, env);
......
806 842
        ppcemb_timer->wdt_timer =
807 843
            qemu_new_timer(vm_clock, &cpu_4xx_wdt_cb, env);
808 844
    }
845

  
846
    /* XXX: TODO: add callback for clock frequency change */
847
    return NULL;
809 848
}
810 849

  
811 850
/*****************************************************************************/
b/hw/ppc405_uc.c
1
/*
2
 * QEMU PowerPC 405 embedded processors 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 "vl.h"
25

  
26
extern int loglevel;
27
extern FILE *logfile;
28

  
29
#define DEBUG_MMIO
30
#define DEBUG_OPBA
31
#define DEBUG_SDRAM
32
#define DEBUG_GPIO
33
#define DEBUG_SERIAL
34
#define DEBUG_OCM
35
#define DEBUG_I2C
36
#define DEBUG_UIC
37
#define DEBUG_CLOCKS
38
#define DEBUG_UNASSIGNED
39

  
40
/*****************************************************************************/
41
/* Generic PowerPC 405 processor instanciation */
42
CPUState *ppc405_init (const unsigned char *cpu_model,
43
                       clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
44
                       uint32_t sysclk)
45
{
46
    CPUState *env;
47
    ppc_def_t *def;
48

  
49
    /* init CPUs */
50
    env = cpu_init();
51
    qemu_register_reset(&cpu_ppc_reset, env);
52
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
53
    ppc_find_by_name(cpu_model, &def);
54
    if (def == NULL) {
55
        cpu_abort(env, "Unable to find PowerPC %s CPU definition\n",
56
                  cpu_model);
57
    }
58
    cpu_ppc_register(env, def);
59
    cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
60
    cpu_clk->opaque = env;
61
    /* Set time-base frequency to sysclk */
62
    tb_clk->cb = ppc_emb_timers_init(env, sysclk);
63
    tb_clk->opaque = env;
64
    ppc_dcr_init(env, NULL, NULL);
65

  
66
    return env;
67
}
68

  
69
/*****************************************************************************/
70
/* Shared peripherals */
71

  
72
/*****************************************************************************/
73
/* Fake device used to map multiple devices in a single memory page */
74
#define MMIO_AREA_BITS 8
75
#define MMIO_AREA_LEN (1 << MMIO_AREA_BITS)
76
#define MMIO_AREA_NB (1 << (TARGET_PAGE_BITS - MMIO_AREA_BITS))
77
#define MMIO_IDX(addr) (((addr) >> MMIO_AREA_BITS) & (MMIO_AREA_NB - 1))
78
struct ppc4xx_mmio_t {
79
    uint32_t base;
80
    CPUReadMemoryFunc **mem_read[MMIO_AREA_NB];
81
    CPUWriteMemoryFunc **mem_write[MMIO_AREA_NB];
82
    void *opaque[MMIO_AREA_NB];
83
};
84

  
85
static uint32_t unassigned_mem_readb (void *opaque, target_phys_addr_t addr)
86
{
87
#ifdef DEBUG_UNASSIGNED
88
    printf("Unassigned mem read 0x" PADDRX "\n", addr);
89
#endif
90

  
91
    return 0;
92
}
93

  
94
static void unassigned_mem_writeb (void *opaque,
95
                                   target_phys_addr_t addr, uint32_t val)
96
{
97
#ifdef DEBUG_UNASSIGNED
98
    printf("Unassigned mem write 0x" PADDRX " = 0x%x\n", addr, val);
99
#endif
100
}
101

  
102
static CPUReadMemoryFunc *unassigned_mem_read[3] = {
103
    unassigned_mem_readb,
104
    unassigned_mem_readb,
105
    unassigned_mem_readb,
106
};
107

  
108
static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
109
    unassigned_mem_writeb,
110
    unassigned_mem_writeb,
111
    unassigned_mem_writeb,
112
};
113

  
114
static uint32_t mmio_readlen (ppc4xx_mmio_t *mmio,
115
                              target_phys_addr_t addr, int len)
116
{
117
    CPUReadMemoryFunc **mem_read;
118
    uint32_t ret;
119
    int idx;
120

  
121
    idx = MMIO_IDX(addr - mmio->base);
122
#if defined(DEBUG_MMIO)
123
    printf("%s: mmio %p len %d addr " PADDRX " idx %d\n", __func__,
124
           mmio, len, addr, idx);
125
#endif
126
    mem_read = mmio->mem_read[idx];
127
    ret = (*mem_read[len])(mmio->opaque[idx], addr);
128

  
129
    return ret;
130
}
131

  
132
static void mmio_writelen (ppc4xx_mmio_t *mmio,
133
                           target_phys_addr_t addr, uint32_t value, int len)
134
{
135
    CPUWriteMemoryFunc **mem_write;
136
    int idx;
137

  
138
    idx = MMIO_IDX(addr - mmio->base);
139
#if defined(DEBUG_MMIO)
140
    printf("%s: mmio %p len %d addr " PADDRX " idx %d value %08x\n", __func__,
141
           mmio, len, addr, idx, value);
142
#endif
143
    mem_write = mmio->mem_write[idx];
144
    (*mem_write[len])(mmio->opaque[idx], addr, value);
145
}
146

  
147
static uint32_t mmio_readb (void *opaque, target_phys_addr_t addr)
148
{
149
#if defined(DEBUG_MMIO)
150
    printf("%s: addr " PADDRX "\n", __func__, addr);
151
#endif
152

  
153
    return mmio_readlen(opaque, addr, 0);
154
}
155

  
156
static void mmio_writeb (void *opaque,
157
                         target_phys_addr_t addr, uint32_t value)
158
{
159
#if defined(DEBUG_MMIO)
160
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
161
#endif
162
    mmio_writelen(opaque, addr, value, 0);
163
}
164

  
165
static uint32_t mmio_readw (void *opaque, target_phys_addr_t addr)
166
{
167
#if defined(DEBUG_MMIO)
168
    printf("%s: addr " PADDRX "\n", __func__, addr);
169
#endif
170

  
171
    return mmio_readlen(opaque, addr, 1);
172
}
173

  
174
static void mmio_writew (void *opaque,
175
                         target_phys_addr_t addr, uint32_t value)
176
{
177
#if defined(DEBUG_MMIO)
178
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
179
#endif
180
    mmio_writelen(opaque, addr, value, 1);
181
}
182

  
183
static uint32_t mmio_readl (void *opaque, target_phys_addr_t addr)
184
{
185
#if defined(DEBUG_MMIO)
186
    printf("%s: addr " PADDRX "\n", __func__, addr);
187
#endif
188

  
189
    return mmio_readlen(opaque, addr, 2);
190
}
191

  
192
static void mmio_writel (void *opaque,
193
                         target_phys_addr_t addr, uint32_t value)
194
{
195
#if defined(DEBUG_MMIO)
196
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
197
#endif
198
    mmio_writelen(opaque, addr, value, 2);
199
}
200

  
201
static CPUReadMemoryFunc *mmio_read[] = {
202
    &mmio_readb,
203
    &mmio_readw,
204
    &mmio_readl,
205
};
206

  
207
static CPUWriteMemoryFunc *mmio_write[] = {
208
    &mmio_writeb,
209
    &mmio_writew,
210
    &mmio_writel,
211
};
212

  
213
int ppc4xx_mmio_register (CPUState *env, ppc4xx_mmio_t *mmio,
214
                          uint32_t offset, uint32_t len,
215
                          CPUReadMemoryFunc **mem_read,
216
                          CPUWriteMemoryFunc **mem_write, void *opaque)
217
{
218
    uint32_t end;
219
    int idx, eidx;
220

  
221
    if ((offset + len) > TARGET_PAGE_SIZE)
222
        return -1;
223
    idx = MMIO_IDX(offset);
224
    end = offset + len - 1;
225
    eidx = MMIO_IDX(end);
226
#if defined(DEBUG_MMIO)
227
    printf("%s: offset %08x len %08x %08x %d %d\n", __func__, offset, len,
228
           end, idx, eidx);
229
#endif
230
    for (; idx <= eidx; idx++) {
231
        mmio->mem_read[idx] = mem_read;
232
        mmio->mem_write[idx] = mem_write;
233
        mmio->opaque[idx] = opaque;
234
    }
235

  
236
    return 0;
237
}
238

  
239
ppc4xx_mmio_t *ppc4xx_mmio_init (CPUState *env, uint32_t base)
240
{
241
    ppc4xx_mmio_t *mmio;
242
    int mmio_memory;
243

  
244
    mmio = qemu_mallocz(sizeof(ppc4xx_mmio_t));
245
    if (mmio != NULL) {
246
        mmio->base = base;
247
        mmio_memory = cpu_register_io_memory(0, mmio_read, mmio_write, mmio);
248
#if defined(DEBUG_MMIO)
249
        printf("%s: %p base %08x len %08x %d\n", __func__,
250
               mmio, base, TARGET_PAGE_SIZE, mmio_memory);
251
#endif
252
        cpu_register_physical_memory(base, TARGET_PAGE_SIZE, mmio_memory);
253
        ppc4xx_mmio_register(env, mmio, 0, TARGET_PAGE_SIZE,
254
                             unassigned_mem_read, unassigned_mem_write, NULL);
255
    }
256

  
257
    return mmio;
258
}
259

  
260
/*****************************************************************************/
261
/* Peripheral local bus arbitrer */
262
enum {
263
    PLB0_BESR = 0x084,
264
    PLB0_BEAR = 0x086,
265
    PLB0_ACR  = 0x087,
266
};
267

  
268
typedef struct ppc4xx_plb_t ppc4xx_plb_t;
269
struct ppc4xx_plb_t {
270
    uint32_t acr;
271
    uint32_t bear;
272
    uint32_t besr;
273
};
274

  
275
static target_ulong dcr_read_plb (void *opaque, int dcrn)
276
{
277
    ppc4xx_plb_t *plb;
278
    target_ulong ret;
279

  
280
    plb = opaque;
281
    switch (dcrn) {
282
    case PLB0_ACR:
283
        ret = plb->acr;
284
        break;
285
    case PLB0_BEAR:
286
        ret = plb->bear;
287
        break;
288
    case PLB0_BESR:
289
        ret = plb->besr;
290
        break;
291
    default:
292
        /* Avoid gcc warning */
293
        ret = 0;
294
        break;
295
    }
296

  
297
    return ret;
298
}
299

  
300
static void dcr_write_plb (void *opaque, int dcrn, target_ulong val)
301
{
302
    ppc4xx_plb_t *plb;
303

  
304
    plb = opaque;
305
    switch (dcrn) {
306
    case PLB0_ACR:
307
        plb->acr = val & 0xFC000000;
308
        break;
309
    case PLB0_BEAR:
310
        /* Read only */
311
        break;
312
    case PLB0_BESR:
313
        /* Write-clear */
314
        plb->besr &= ~val;
315
        break;
316
    }
317
}
318

  
319
static void ppc4xx_plb_reset (void *opaque)
320
{
321
    ppc4xx_plb_t *plb;
322

  
323
    plb = opaque;
324
    plb->acr = 0x00000000;
325
    plb->bear = 0x00000000;
326
    plb->besr = 0x00000000;
327
}
328

  
329
void ppc4xx_plb_init (CPUState *env)
330
{
331
    ppc4xx_plb_t *plb;
332

  
333
    plb = qemu_mallocz(sizeof(ppc4xx_plb_t));
334
    if (plb != NULL) {
335
        ppc_dcr_register(env, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
336
        ppc_dcr_register(env, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);
337
        ppc_dcr_register(env, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);
338
        ppc4xx_plb_reset(plb);
339
        qemu_register_reset(ppc4xx_plb_reset, plb);
340
    }
341
}
342

  
343
/*****************************************************************************/
344
/* PLB to OPB bridge */
345
enum {
346
    POB0_BESR0 = 0x0A0,
347
    POB0_BESR1 = 0x0A2,
348
    POB0_BEAR  = 0x0A4,
349
};
350

  
351
typedef struct ppc4xx_pob_t ppc4xx_pob_t;
352
struct ppc4xx_pob_t {
353
    uint32_t bear;
354
    uint32_t besr[2];
355
};
356

  
357
static target_ulong dcr_read_pob (void *opaque, int dcrn)
358
{
359
    ppc4xx_pob_t *pob;
360
    target_ulong ret;
361

  
362
    pob = opaque;
363
    switch (dcrn) {
364
    case POB0_BEAR:
365
        ret = pob->bear;
366
        break;
367
    case POB0_BESR0:
368
    case POB0_BESR1:
369
        ret = pob->besr[dcrn - POB0_BESR0];
370
        break;
371
    default:
372
        /* Avoid gcc warning */
373
        ret = 0;
374
        break;
375
    }
376

  
377
    return ret;
378
}
379

  
380
static void dcr_write_pob (void *opaque, int dcrn, target_ulong val)
381
{
382
    ppc4xx_pob_t *pob;
383

  
384
    pob = opaque;
385
    switch (dcrn) {
386
    case POB0_BEAR:
387
        /* Read only */
388
        break;
389
    case POB0_BESR0:
390
    case POB0_BESR1:
391
        /* Write-clear */
392
        pob->besr[dcrn - POB0_BESR0] &= ~val;
393
        break;
394
    }
395
}
396

  
397
static void ppc4xx_pob_reset (void *opaque)
398
{
399
    ppc4xx_pob_t *pob;
400

  
401
    pob = opaque;
402
    /* No error */
403
    pob->bear = 0x00000000;
404
    pob->besr[0] = 0x0000000;
405
    pob->besr[1] = 0x0000000;
406
}
407

  
408
void ppc4xx_pob_init (CPUState *env)
409
{
410
    ppc4xx_pob_t *pob;
411

  
412
    pob = qemu_mallocz(sizeof(ppc4xx_pob_t));
413
    if (pob != NULL) {
414
        ppc_dcr_register(env, POB0_BEAR, pob, &dcr_read_pob, &dcr_write_pob);
415
        ppc_dcr_register(env, POB0_BESR0, pob, &dcr_read_pob, &dcr_write_pob);
416
        ppc_dcr_register(env, POB0_BESR1, pob, &dcr_read_pob, &dcr_write_pob);
417
        qemu_register_reset(ppc4xx_pob_reset, pob);
418
        ppc4xx_pob_reset(env);
419
    }
420
}
421

  
422
/*****************************************************************************/
423
/* OPB arbitrer */
424
typedef struct ppc4xx_opba_t ppc4xx_opba_t;
425
struct ppc4xx_opba_t {
426
    target_ulong base;
427
    uint8_t cr;
428
    uint8_t pr;
429
};
430

  
431
static uint32_t opba_readb (void *opaque, target_phys_addr_t addr)
432
{
433
    ppc4xx_opba_t *opba;
434
    uint32_t ret;
435

  
436
#ifdef DEBUG_OPBA
437
    printf("%s: addr " PADDRX "\n", __func__, addr);
438
#endif
439
    opba = opaque;
440
    switch (addr - opba->base) {
441
    case 0x00:
442
        ret = opba->cr;
443
        break;
444
    case 0x01:
445
        ret = opba->pr;
446
        break;
447
    default:
448
        ret = 0x00;
449
        break;
450
    }
451

  
452
    return ret;
453
}
454

  
455
static void opba_writeb (void *opaque,
456
                         target_phys_addr_t addr, uint32_t value)
457
{
458
    ppc4xx_opba_t *opba;
459

  
460
#ifdef DEBUG_OPBA
461
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
462
#endif
463
    opba = opaque;
464
    switch (addr - opba->base) {
465
    case 0x00:
466
        opba->cr = value & 0xF8;
467
        break;
468
    case 0x01:
469
        opba->pr = value & 0xFF;
470
        break;
471
    default:
472
        break;
473
    }
474
}
475

  
476
static uint32_t opba_readw (void *opaque, target_phys_addr_t addr)
477
{
478
    uint32_t ret;
479

  
480
#ifdef DEBUG_OPBA
481
    printf("%s: addr " PADDRX "\n", __func__, addr);
482
#endif
483
    ret = opba_readb(opaque, addr) << 8;
484
    ret |= opba_readb(opaque, addr + 1);
485

  
486
    return ret;
487
}
488

  
489
static void opba_writew (void *opaque,
490
                         target_phys_addr_t addr, uint32_t value)
491
{
492
#ifdef DEBUG_OPBA
493
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
494
#endif
495
    opba_writeb(opaque, addr, value >> 8);
496
    opba_writeb(opaque, addr + 1, value);
497
}
498

  
499
static uint32_t opba_readl (void *opaque, target_phys_addr_t addr)
500
{
501
    uint32_t ret;
502

  
503
#ifdef DEBUG_OPBA
504
    printf("%s: addr " PADDRX "\n", __func__, addr);
505
#endif
506
    ret = opba_readb(opaque, addr) << 24;
507
    ret |= opba_readb(opaque, addr + 1) << 16;
508

  
509
    return ret;
510
}
511

  
512
static void opba_writel (void *opaque,
513
                         target_phys_addr_t addr, uint32_t value)
514
{
515
#ifdef DEBUG_OPBA
516
    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
517
#endif
518
    opba_writeb(opaque, addr, value >> 24);
519
    opba_writeb(opaque, addr + 1, value >> 16);
520
}
521

  
522
static CPUReadMemoryFunc *opba_read[] = {
523
    &opba_readb,
524
    &opba_readw,
525
    &opba_readl,
526
};
527

  
528
static CPUWriteMemoryFunc *opba_write[] = {
529
    &opba_writeb,
530
    &opba_writew,
531
    &opba_writel,
532
};
533

  
534
static void ppc4xx_opba_reset (void *opaque)
535
{
536
    ppc4xx_opba_t *opba;
537

  
538
    opba = opaque;
539
    opba->cr = 0x00; /* No dynamic priorities - park disabled */
540
    opba->pr = 0x11;
541
}
542

  
543
void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio, uint32_t offset)
544
{
545
    ppc4xx_opba_t *opba;
546

  
547
    opba = qemu_mallocz(sizeof(ppc4xx_opba_t));
548
    if (opba != NULL) {
549
        opba->base = mmio->base + offset;
550
#ifdef DEBUG_OPBA
551
        printf("%s: offset=%08x\n", __func__, offset);
552
#endif
553
        ppc4xx_mmio_register(env, mmio, offset, 0x002,
554
                             opba_read, opba_write, opba);
555
        qemu_register_reset(ppc4xx_opba_reset, opba);
556
        ppc4xx_opba_reset(opba);
557
    }
558
}
559

  
560
/*****************************************************************************/
561
/* "Universal" Interrupt controller */
562
enum {
563
    DCR_UICSR  = 0x000,
564
    DCR_UICSRS = 0x001,
565
    DCR_UICER  = 0x002,
566
    DCR_UICCR  = 0x003,
567
    DCR_UICPR  = 0x004,
568
    DCR_UICTR  = 0x005,
569
    DCR_UICMSR = 0x006,
570
    DCR_UICVR  = 0x007,
571
    DCR_UICVCR = 0x008,
572
    DCR_UICMAX = 0x009,
573
};
574

  
575
#define UIC_MAX_IRQ 32
576
typedef struct ppcuic_t ppcuic_t;
577
struct ppcuic_t {
578
    uint32_t dcr_base;
579
    int use_vectors;
580
    uint32_t uicsr;  /* Status register */
581
    uint32_t uicer;  /* Enable register */
582
    uint32_t uiccr;  /* Critical register */
583
    uint32_t uicpr;  /* Polarity register */
584
    uint32_t uictr;  /* Triggering register */
585
    uint32_t uicvcr; /* Vector configuration register */
586
    uint32_t uicvr;
587
    qemu_irq *irqs;
588
};
589

  
590
static void ppcuic_trigger_irq (ppcuic_t *uic)
591
{
592
    uint32_t ir, cr;
593
    int start, end, inc, i;
594

  
595
    /* Trigger interrupt if any is pending */
596
    ir = uic->uicsr & uic->uicer & (~uic->uiccr);
597
    cr = uic->uicsr & uic->uicer & uic->uiccr;
598
#ifdef DEBUG_UIC
599
    if (loglevel & CPU_LOG_INT) {
600
        fprintf(logfile, "%s: uicsr %08x uicer %08x uiccr %08x\n"
601
                "   %08x ir %08x cr %08x\n", __func__,
602
                uic->uicsr, uic->uicer, uic->uiccr,
603
                uic->uicsr & uic->uicer, ir, cr);
604
    }
605
#endif
606
    if (ir != 0x0000000) {
607
#ifdef DEBUG_UIC
608
        if (loglevel & CPU_LOG_INT) {
609
            fprintf(logfile, "Raise UIC interrupt\n");
610
        }
611
#endif
612
        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_INT]);
613
    } else {
614
#ifdef DEBUG_UIC
615
        if (loglevel & CPU_LOG_INT) {
616
            fprintf(logfile, "Lower UIC interrupt\n");
617
        }
618
#endif
619
        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_INT]);
620
    }
621
    /* Trigger critical interrupt if any is pending and update vector */
622
    if (cr != 0x0000000) {
623
        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_CINT]);
624
        if (uic->use_vectors) {
625
            /* Compute critical IRQ vector */
626
            if (uic->uicvcr & 1) {
627
                start = 31;
628
                end = 0;
629
                inc = -1;
630
            } else {
631
                start = 0;
632
                end = 31;
633
                inc = 1;
634
            }
635
            uic->uicvr = uic->uicvcr & 0xFFFFFFFC;
636
            for (i = start; i <= end; i += inc) {
637
                if (cr & (1 << i)) {
638
                    uic->uicvr += (i - start) * 512 * inc;
639
                    break;
640
                }
641
            }
642
        }
643
#ifdef DEBUG_UIC
644
        if (loglevel & CPU_LOG_INT) {
645
            fprintf(logfile, "Raise UIC critical interrupt - vector %08x\n",
646
                    uic->uicvr);
647
        }
648
#endif
649
    } else {
650
#ifdef DEBUG_UIC
651
        if (loglevel & CPU_LOG_INT) {
652
            fprintf(logfile, "Lower UIC critical interrupt\n");
653
        }
654
#endif
655
        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_CINT]);
656
        uic->uicvr = 0x00000000;
657
    }
658
}
659

  
660
static void ppcuic_set_irq (void *opaque, int irq_num, int level)
661
{
662
    ppcuic_t *uic;
663
    uint32_t mask, sr;
664

  
665
    uic = opaque;
666
    mask = 1 << irq_num;
667
#ifdef DEBUG_UIC
668
    if (loglevel & CPU_LOG_INT) {
669
        fprintf(logfile, "%s: irq %d level %d uicsr %08x mask %08x => %08x "
670
                "%08x\n", __func__, irq_num, level,
671
                uic->uicsr, mask, uic->uicsr & mask, level << irq_num);
672
    }
673
#endif
674
    if (irq_num < 0 || irq_num > 31)
675
        return;
676
    sr = uic->uicsr;
677
    if (!(uic->uicpr & mask)) {
678
        /* Negatively asserted IRQ */
679
        level = level == 0 ? 1 : 0;
680
    }
681
    /* Update status register */
682
    if (uic->uictr & mask) {
683
        /* Edge sensitive interrupt */
684
        if (level == 1)
685
            uic->uicsr |= mask;
686
    } else {
687
        /* Level sensitive interrupt */
688
        if (level == 1)
689
            uic->uicsr |= mask;
690
        else
691
            uic->uicsr &= ~mask;
692
    }
693
#ifdef DEBUG_UIC
694
    if (loglevel & CPU_LOG_INT) {
695
        fprintf(logfile, "%s: irq %d level %d sr %08x => %08x\n", __func__,
696
                irq_num, level, uic->uicsr, sr);
697
    }
698
#endif
699
    if (sr != uic->uicsr)
700
        ppcuic_trigger_irq(uic);
701
}
702

  
703
static target_ulong dcr_read_uic (void *opaque, int dcrn)
704
{
705
    ppcuic_t *uic;
706
    target_ulong ret;
707

  
708
    uic = opaque;
709
    dcrn -= uic->dcr_base;
710
    switch (dcrn) {
711
    case DCR_UICSR:
712
    case DCR_UICSRS:
713
        ret = uic->uicsr;
714
        break;
715
    case DCR_UICER:
716
        ret = uic->uicer;
717
        break;
718
    case DCR_UICCR:
719
        ret = uic->uiccr;
720
        break;
721
    case DCR_UICPR:
722
        ret = uic->uicpr;
723
        break;
724
    case DCR_UICTR:
725
        ret = uic->uictr;
726
        break;
727
    case DCR_UICMSR:
728
        ret = uic->uicsr & uic->uicer;
729
        break;
730
    case DCR_UICVR:
731
        if (!uic->use_vectors)
732
            goto no_read;
733
        ret = uic->uicvr;
734
        break;
735
    case DCR_UICVCR:
736
        if (!uic->use_vectors)
737
            goto no_read;
738
        ret = uic->uicvcr;
739
        break;
740
    default:
741
    no_read:
742
        ret = 0x00000000;
743
        break;
744
    }
745

  
746
    return ret;
747
}
748

  
749
static void dcr_write_uic (void *opaque, int dcrn, target_ulong val)
750
{
751
    ppcuic_t *uic;
752

  
753
    uic = opaque;
754
    dcrn -= uic->dcr_base;
755
#ifdef DEBUG_UIC
756
    if (loglevel & CPU_LOG_INT) {
757
        fprintf(logfile, "%s: dcr %d val " ADDRX "\n", __func__, dcrn, val);
758
    }
759
#endif
760
    switch (dcrn) {
761
    case DCR_UICSR:
762
        uic->uicsr &= ~val;
763
        ppcuic_trigger_irq(uic);
764
        break;
765
    case DCR_UICSRS:
766
        uic->uicsr |= val;
767
        ppcuic_trigger_irq(uic);
768
        break;
769
    case DCR_UICER:
770
        uic->uicer = val;
771
        ppcuic_trigger_irq(uic);
772
        break;
773
    case DCR_UICCR:
774
        uic->uiccr = val;
775
        ppcuic_trigger_irq(uic);
776
        break;
777
    case DCR_UICPR:
778
        uic->uicpr = val;
779
        ppcuic_trigger_irq(uic);
780
        break;
781
    case DCR_UICTR:
782
        uic->uictr = val;
783
        ppcuic_trigger_irq(uic);
784
        break;
785
    case DCR_UICMSR:
786
        break;
787
    case DCR_UICVR:
788
        break;
789
    case DCR_UICVCR:
790
        uic->uicvcr = val & 0xFFFFFFFD;
791
        ppcuic_trigger_irq(uic);
792
        break;
793
    }
794
}
795

  
796
static void ppcuic_reset (void *opaque)
797
{
798
    ppcuic_t *uic;
799

  
800
    uic = opaque;
801
    uic->uiccr = 0x00000000;
802
    uic->uicer = 0x00000000;
803
    uic->uicpr = 0x00000000;
804
    uic->uicsr = 0x00000000;
805
    uic->uictr = 0x00000000;
806
    if (uic->use_vectors) {
807
        uic->uicvcr = 0x00000000;
808
        uic->uicvr = 0x0000000;
809
    }
810
}
811

  
812
qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
813
                       uint32_t dcr_base, int has_ssr, int has_vr)
814
{
815
    ppcuic_t *uic;
816
    int i;
817

  
818
    uic = qemu_mallocz(sizeof(ppcuic_t));
819
    if (uic != NULL) {
820
        uic->dcr_base = dcr_base;
821
        uic->irqs = irqs;
822
        if (has_vr)
823
            uic->use_vectors = 1;
824
        for (i = 0; i < DCR_UICMAX; i++) {
825
            ppc_dcr_register(env, dcr_base + i, uic,
826
                             &dcr_read_uic, &dcr_write_uic);
827
        }
828
        qemu_register_reset(ppcuic_reset, uic);
829
        ppcuic_reset(uic);
830
    }
831

  
832
    return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ);
833
}
834

  
835
/*****************************************************************************/
836
/* Code decompression controller */
837
/* XXX: TODO */
838

  
839
/*****************************************************************************/
840
/* SDRAM controller */
841
typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
842
struct ppc4xx_sdram_t {
843
    uint32_t addr;
844
    int nbanks;
845
    target_ulong ram_bases[4];
846
    target_ulong ram_sizes[4];
847
    uint32_t besr0;
848
    uint32_t besr1;
849
    uint32_t bear;
850
    uint32_t cfg;
851
    uint32_t status;
852
    uint32_t rtr;
853
    uint32_t pmit;
854
    uint32_t bcr[4];
855
    uint32_t tr;
856
    uint32_t ecccfg;
857
    uint32_t eccesr;
858
    qemu_irq irq;
859
};
860

  
861
enum {
862
    SDRAM0_CFGADDR = 0x010,
863
    SDRAM0_CFGDATA = 0x011,
864
};
865

  
866
static uint32_t sdram_bcr (target_ulong ram_base, target_ulong ram_size)
867
{
868
    uint32_t bcr;
869

  
870
    switch (ram_size) {
871
    case (4 * 1024 * 1024):
872
        bcr = 0x00000000;
873
        break;
874
    case (8 * 1024 * 1024):
875
        bcr = 0x00020000;
876
        break;
877
    case (16 * 1024 * 1024):
878
        bcr = 0x00040000;
879
        break;
880
    case (32 * 1024 * 1024):
881
        bcr = 0x00060000;
882
        break;
883
    case (64 * 1024 * 1024):
884
        bcr = 0x00080000;
885
        break;
886
    case (128 * 1024 * 1024):
887
        bcr = 0x000A0000;
888
        break;
889
    case (256 * 1024 * 1024):
890
        bcr = 0x000C0000;
891
        break;
892
    default:
893
        printf("%s: invalid RAM size " TARGET_FMT_ld "\n", __func__, ram_size);
894
        return 0x00000000;
895
    }
896
    bcr |= ram_base & 0xFF800000;
897
    bcr |= 1;
898

  
899
    return bcr;
900
}
901

  
902
static inline target_ulong sdram_base (uint32_t bcr)
903
{
904
    return bcr & 0xFF800000;
905
}
906

  
907
static target_ulong sdram_size (uint32_t bcr)
908
{
909
    target_ulong size;
910
    int sh;
911

  
912
    sh = (bcr >> 17) & 0x7;
913
    if (sh == 7)
914
        size = -1;
915
    else
916
        size = (4 * 1024 * 1024) << sh;
917

  
918
    return size;
919
}
920

  
921
static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled)
922
{
923
    if (*bcrp & 0x00000001) {
924
        /* Unmap RAM */
925
#ifdef DEBUG_SDRAM
926
        printf("%s: unmap RAM area " ADDRX " " ADDRX "\n", __func__,
927
               sdram_base(*bcrp), sdram_size(*bcrp));
928
#endif
929
        cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp),
930
                                     IO_MEM_UNASSIGNED);
931
    }
932
    *bcrp = bcr & 0xFFDEE001;
933
    if (enabled && (bcr & 0x00000001)) {
934
#ifdef DEBUG_SDRAM
935
        printf("%s: Map RAM area " ADDRX " " ADDRX "\n", __func__,
936
               sdram_base(bcr), sdram_size(bcr));
937
#endif
938
        cpu_register_physical_memory(sdram_base(bcr), sdram_size(bcr),
939
                                     sdram_base(bcr) | IO_MEM_RAM);
940
    }
941
}
942

  
943
static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
944
{
945
    int i;
946

  
947
    for (i = 0; i < sdram->nbanks; i++) {
948
        if (sdram->ram_sizes[i] != 0) {
949
            sdram_set_bcr(&sdram->bcr[i],
950
                          sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]),
951
                          1);
952
        } else {
953
            sdram_set_bcr(&sdram->bcr[i], 0x00000000, 0);
954
        }
955
    }
956
}
957

  
958
static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
959
{
960
    int i;
961

  
962
    for (i = 0; i < sdram->nbanks; i++) {
963
        cpu_register_physical_memory(sdram_base(sdram->bcr[i]),
964
                                     sdram_size(sdram->bcr[i]),
965
                                     IO_MEM_UNASSIGNED);
966
    }
967
}
968

  
969
static target_ulong dcr_read_sdram (void *opaque, int dcrn)
970
{
971
    ppc4xx_sdram_t *sdram;
972
    target_ulong ret;
973

  
974
    sdram = opaque;
975
    switch (dcrn) {
976
    case SDRAM0_CFGADDR:
977
        ret = sdram->addr;
978
        break;
979
    case SDRAM0_CFGDATA:
980
        switch (sdram->addr) {
981
        case 0x00: /* SDRAM_BESR0 */
982
            ret = sdram->besr0;
983
            break;
984
        case 0x08: /* SDRAM_BESR1 */
985
            ret = sdram->besr1;
986
            break;
987
        case 0x10: /* SDRAM_BEAR */
988
            ret = sdram->bear;
989
            break;
990
        case 0x20: /* SDRAM_CFG */
991
            ret = sdram->cfg;
992
            break;
993
        case 0x24: /* SDRAM_STATUS */
994
            ret = sdram->status;
995
            break;
996
        case 0x30: /* SDRAM_RTR */
997
            ret = sdram->rtr;
998
            break;
999
        case 0x34: /* SDRAM_PMIT */
1000
            ret = sdram->pmit;
1001
            break;
1002
        case 0x40: /* SDRAM_B0CR */
1003
            ret = sdram->bcr[0];
1004
            break;
1005
        case 0x44: /* SDRAM_B1CR */
1006
            ret = sdram->bcr[1];
1007
            break;
1008
        case 0x48: /* SDRAM_B2CR */
1009
            ret = sdram->bcr[2];
1010
            break;
1011
        case 0x4C: /* SDRAM_B3CR */
1012
            ret = sdram->bcr[3];
1013
            break;
1014
        case 0x80: /* SDRAM_TR */
1015
            ret = -1; /* ? */
1016
            break;
1017
        case 0x94: /* SDRAM_ECCCFG */
1018
            ret = sdram->ecccfg;
1019
            break;
1020
        case 0x98: /* SDRAM_ECCESR */
1021
            ret = sdram->eccesr;
1022
            break;
1023
        default: /* Error */
1024
            ret = -1;
1025
            break;
1026
        }
1027
        break;
1028
    default:
1029
        /* Avoid gcc warning */
1030
        ret = 0x00000000;
1031
        break;
1032
    }
1033

  
1034
    return ret;
1035
}
1036

  
1037
static void dcr_write_sdram (void *opaque, int dcrn, target_ulong val)
1038
{
1039
    ppc4xx_sdram_t *sdram;
1040

  
1041
    sdram = opaque;
1042
    switch (dcrn) {
1043
    case SDRAM0_CFGADDR:
1044
        sdram->addr = val;
1045
        break;
1046
    case SDRAM0_CFGDATA:
1047
        switch (sdram->addr) {
1048
        case 0x00: /* SDRAM_BESR0 */
1049
            sdram->besr0 &= ~val;
1050
            break;
1051
        case 0x08: /* SDRAM_BESR1 */
1052
            sdram->besr1 &= ~val;
1053
            break;
1054
        case 0x10: /* SDRAM_BEAR */
1055
            sdram->bear = val;
1056
            break;
1057
        case 0x20: /* SDRAM_CFG */
1058
            val &= 0xFFE00000;
1059
            if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
1060
#ifdef DEBUG_SDRAM
1061
                printf("%s: enable SDRAM controller\n", __func__);
1062
#endif
1063
                /* validate all RAM mappings */
1064
                sdram_map_bcr(sdram);
1065
                sdram->status &= ~0x80000000;
1066
            } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
1067
#ifdef DEBUG_SDRAM
1068
                printf("%s: disable SDRAM controller\n", __func__);
1069
#endif
1070
                /* invalidate all RAM mappings */
1071
                sdram_unmap_bcr(sdram);
1072
                sdram->status |= 0x80000000;
1073
            }
1074
            if (!(sdram->cfg & 0x40000000) && (val & 0x40000000))
1075
                sdram->status |= 0x40000000;
1076
            else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000))
1077
                sdram->status &= ~0x40000000;
1078
            sdram->cfg = val;
1079
            break;
1080
        case 0x24: /* SDRAM_STATUS */
1081
            /* Read-only register */
1082
            break;
1083
        case 0x30: /* SDRAM_RTR */
1084
            sdram->rtr = val & 0x3FF80000;
1085
            break;
1086
        case 0x34: /* SDRAM_PMIT */
1087
            sdram->pmit = (val & 0xF8000000) | 0x07C00000;
1088
            break;
1089
        case 0x40: /* SDRAM_B0CR */
1090
            sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000);
1091
            break;
1092
        case 0x44: /* SDRAM_B1CR */
1093
            sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000);
1094
            break;
1095
        case 0x48: /* SDRAM_B2CR */
1096
            sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000);
1097
            break;
1098
        case 0x4C: /* SDRAM_B3CR */
1099
            sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000);
1100
            break;
1101
        case 0x80: /* SDRAM_TR */
1102
            sdram->tr = val & 0x018FC01F;
1103
            break;
1104
        case 0x94: /* SDRAM_ECCCFG */
1105
            sdram->ecccfg = val & 0x00F00000;
1106
            break;
1107
        case 0x98: /* SDRAM_ECCESR */
1108
            val &= 0xFFF0F000;
1109
            if (sdram->eccesr == 0 && val != 0)
1110
                qemu_irq_raise(sdram->irq);
1111
            else if (sdram->eccesr != 0 && val == 0)
1112
                qemu_irq_lower(sdram->irq);
1113
            sdram->eccesr = val;
1114
            break;
1115
        default: /* Error */
1116
            break;
1117
        }
1118
        break;
1119
    }
1120
}
1121

  
1122
static void sdram_reset (void *opaque)
1123
{
1124
    ppc4xx_sdram_t *sdram;
1125

  
1126
    sdram = opaque;
1127
    sdram->addr = 0x00000000;
1128
    sdram->bear = 0x00000000;
1129
    sdram->besr0 = 0x00000000; /* No error */
1130
    sdram->besr1 = 0x00000000; /* No error */
1131
    sdram->cfg = 0x00000000;
1132
    sdram->ecccfg = 0x00000000; /* No ECC */
1133
    sdram->eccesr = 0x00000000; /* No error */
1134
    sdram->pmit = 0x07C00000;
1135
    sdram->rtr = 0x05F00000;
1136
    sdram->tr = 0x00854009;
1137
    /* We pre-initialize RAM banks */
1138
    sdram->status = 0x00000000;
1139
    sdram->cfg = 0x00800000;
1140
    sdram_unmap_bcr(sdram);
1141
}
1142

  
1143
void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
1144
                        target_ulong *ram_bases, target_ulong *ram_sizes)
1145
{
1146
    ppc4xx_sdram_t *sdram;
1147

  
1148
    sdram = qemu_mallocz(sizeof(ppc4xx_sdram_t));
1149
    if (sdram != NULL) {
1150
        sdram->irq = irq;
1151
        sdram->nbanks = nbanks;
1152
        memset(sdram->ram_bases, 0, 4 * sizeof(target_ulong));
1153
        memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(target_ulong));
1154
        memset(sdram->ram_sizes, 0, 4 * sizeof(target_ulong));
1155
        memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(target_ulong));
1156
        sdram_reset(sdram);
1157
        qemu_register_reset(&sdram_reset, sdram);
1158
        ppc_dcr_register(env, SDRAM0_CFGADDR,
1159
                         sdram, &dcr_read_sdram, &dcr_write_sdram);
1160
        ppc_dcr_register(env, SDRAM0_CFGDATA,
1161
                         sdram, &dcr_read_sdram, &dcr_write_sdram);
1162
    }
1163
}
1164

  
1165
/*****************************************************************************/
1166
/* Peripheral controller */
1167
typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
1168
struct ppc4xx_ebc_t {
1169
    uint32_t addr;
1170
    uint32_t bcr[8];
1171
    uint32_t bap[8];
1172
    uint32_t bear;
1173
    uint32_t besr0;
1174
    uint32_t besr1;
1175
    uint32_t cfg;
1176
};
1177

  
1178
enum {
1179
    EBC0_CFGADDR = 0x012,
1180
    EBC0_CFGDATA = 0x013,
1181
};
1182

  
1183
static target_ulong dcr_read_ebc (void *opaque, int dcrn)
1184
{
1185
    ppc4xx_ebc_t *ebc;
1186
    target_ulong ret;
1187

  
1188
    ebc = opaque;
1189
    switch (dcrn) {
1190
    case EBC0_CFGADDR:
1191
        ret = ebc->addr;
1192
        break;
1193
    case EBC0_CFGDATA:
1194
        switch (ebc->addr) {
1195
        case 0x00: /* B0CR */
1196
            ret = ebc->bcr[0];
1197
            break;
1198
        case 0x01: /* B1CR */
1199
            ret = ebc->bcr[1];
1200
            break;
1201
        case 0x02: /* B2CR */
1202
            ret = ebc->bcr[2];
1203
            break;
1204
        case 0x03: /* B3CR */
1205
            ret = ebc->bcr[3];
1206
            break;
1207
        case 0x04: /* B4CR */
1208
            ret = ebc->bcr[4];
1209
            break;
1210
        case 0x05: /* B5CR */
1211
            ret = ebc->bcr[5];
1212
            break;
1213
        case 0x06: /* B6CR */
1214
            ret = ebc->bcr[6];
1215
            break;
1216
        case 0x07: /* B7CR */
1217
            ret = ebc->bcr[7];
1218
            break;
1219
        case 0x10: /* B0AP */
1220
            ret = ebc->bap[0];
1221
            break;
1222
        case 0x11: /* B1AP */
1223
            ret = ebc->bap[1];
1224
            break;
1225
        case 0x12: /* B2AP */
1226
            ret = ebc->bap[2];
1227
            break;
1228
        case 0x13: /* B3AP */
1229
            ret = ebc->bap[3];
1230
            break;
1231
        case 0x14: /* B4AP */
1232
            ret = ebc->bap[4];
1233
            break;
1234
        case 0x15: /* B5AP */
1235
            ret = ebc->bap[5];
1236
            break;
1237
        case 0x16: /* B6AP */
1238
            ret = ebc->bap[6];
1239
            break;
1240
        case 0x17: /* B7AP */
1241
            ret = ebc->bap[7];
1242
            break;
1243
        case 0x20: /* BEAR */
1244
            ret = ebc->bear;
1245
            break;
1246
        case 0x21: /* BESR0 */
1247
            ret = ebc->besr0;
1248
            break;
1249
        case 0x22: /* BESR1 */
1250
            ret = ebc->besr1;
1251
            break;
1252
        case 0x23: /* CFG */
1253
            ret = ebc->cfg;
1254
            break;
1255
        default:
1256
            ret = 0x00000000;
1257
            break;
1258
        }
1259
    default:
1260
        ret = 0x00000000;
1261
        break;
1262
    }
1263

  
1264
    return ret;
1265
}
1266

  
1267
static void dcr_write_ebc (void *opaque, int dcrn, target_ulong val)
1268
{
1269
    ppc4xx_ebc_t *ebc;
1270

  
1271
    ebc = opaque;
1272
    switch (dcrn) {
1273
    case EBC0_CFGADDR:
1274
        ebc->addr = val;
1275
        break;
1276
    case EBC0_CFGDATA:
1277
        switch (ebc->addr) {
1278
        case 0x00: /* B0CR */
1279
            break;
1280
        case 0x01: /* B1CR */
1281
            break;
1282
        case 0x02: /* B2CR */
1283
            break;
1284
        case 0x03: /* B3CR */
1285
            break;
1286
        case 0x04: /* B4CR */
1287
            break;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff