]> git.proxmox.com Git - mirror_qemu.git/blame - hw/ppc405_uc.c
Support it_shift for mmapped pckbd.
[mirror_qemu.git] / hw / ppc405_uc.c
CommitLineData
8ecc7913
JM
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
26extern int loglevel;
27extern 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 */
42CPUState *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))
78struct 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
85static 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
94static 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
102static CPUReadMemoryFunc *unassigned_mem_read[3] = {
103 unassigned_mem_readb,
104 unassigned_mem_readb,
105 unassigned_mem_readb,
106};
107
108static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
109 unassigned_mem_writeb,
110 unassigned_mem_writeb,
111 unassigned_mem_writeb,
112};
113
114static 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
132static 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
147static 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
156static 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
165static 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
174static 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
183static 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
192static 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
201static CPUReadMemoryFunc *mmio_read[] = {
202 &mmio_readb,
203 &mmio_readw,
204 &mmio_readl,
205};
206
207static CPUWriteMemoryFunc *mmio_write[] = {
208 &mmio_writeb,
209 &mmio_writew,
210 &mmio_writel,
211};
212
213int 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
239ppc4xx_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 */
262enum {
263 PLB0_BESR = 0x084,
264 PLB0_BEAR = 0x086,
265 PLB0_ACR = 0x087,
266};
267
268typedef struct ppc4xx_plb_t ppc4xx_plb_t;
269struct ppc4xx_plb_t {
270 uint32_t acr;
271 uint32_t bear;
272 uint32_t besr;
273};
274
275static 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
300static 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
319static 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
329void 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 */
345enum {
346 POB0_BESR0 = 0x0A0,
347 POB0_BESR1 = 0x0A2,
348 POB0_BEAR = 0x0A4,
349};
350
351typedef struct ppc4xx_pob_t ppc4xx_pob_t;
352struct ppc4xx_pob_t {
353 uint32_t bear;
354 uint32_t besr[2];
355};
356
357static 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
380static 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
397static 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
408void 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 */
424typedef struct ppc4xx_opba_t ppc4xx_opba_t;
425struct ppc4xx_opba_t {
426 target_ulong base;
427 uint8_t cr;
428 uint8_t pr;
429};
430
431static 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
455static 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
476static 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
489static 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
499static 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
512static 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
522static CPUReadMemoryFunc *opba_read[] = {
523 &opba_readb,
524 &opba_readw,
525 &opba_readl,
526};
527
528static CPUWriteMemoryFunc *opba_write[] = {
529 &opba_writeb,
530 &opba_writew,
531 &opba_writel,
532};
533
534static 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
543void 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 */
562enum {
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
576typedef struct ppcuic_t ppcuic_t;
577struct 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
590static 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
660static 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
703static 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
749static 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
796static 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
812qemu_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 */
841typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
842struct 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
861enum {
862 SDRAM0_CFGADDR = 0x010,
863 SDRAM0_CFGDATA = 0x011,
864};
865
866static 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
902static inline target_ulong sdram_base (uint32_t bcr)
903{
904 return bcr & 0xFF800000;
905}
906
907static 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
921static 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
943static 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
958static 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
969static 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
1037static 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
1122static 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
1143void 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 */
1167typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
1168struct 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
1178enum {
1179 EBC0_CFGADDR = 0x012,
1180 EBC0_CFGDATA = 0x013,
1181};
1182
1183static 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
1267static 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;
1288 case 0x05: /* B5CR */
1289 break;
1290 case 0x06: /* B6CR */
1291 break;
1292 case 0x07: /* B7CR */
1293 break;
1294 case 0x10: /* B0AP */
1295 break;
1296 case 0x11: /* B1AP */
1297 break;
1298 case 0x12: /* B2AP */
1299 break;
1300 case 0x13: /* B3AP */
1301 break;
1302 case 0x14: /* B4AP */
1303 break;
1304 case 0x15: /* B5AP */
1305 break;
1306 case 0x16: /* B6AP */
1307 break;
1308 case 0x17: /* B7AP */
1309 break;
1310 case 0x20: /* BEAR */
1311 break;
1312 case 0x21: /* BESR0 */
1313 break;
1314 case 0x22: /* BESR1 */
1315 break;
1316 case 0x23: /* CFG */
1317 break;
1318 default:
1319 break;
1320 }
1321 break;
1322 default:
1323 break;
1324 }
1325}
1326
1327static void ebc_reset (void *opaque)
1328{
1329 ppc4xx_ebc_t *ebc;
1330 int i;
1331
1332 ebc = opaque;
1333 ebc->addr = 0x00000000;
1334 ebc->bap[0] = 0x7F8FFE80;
1335 ebc->bcr[0] = 0xFFE28000;
1336 for (i = 0; i < 8; i++) {
1337 ebc->bap[i] = 0x00000000;
1338 ebc->bcr[i] = 0x00000000;
1339 }
1340 ebc->besr0 = 0x00000000;
1341 ebc->besr1 = 0x00000000;
1342 ebc->cfg = 0x07C00000;
1343}
1344
1345void ppc405_ebc_init (CPUState *env)
1346{
1347 ppc4xx_ebc_t *ebc;
1348
1349 ebc = qemu_mallocz(sizeof(ppc4xx_ebc_t));
1350 if (ebc != NULL) {
1351 ebc_reset(ebc);
1352 qemu_register_reset(&ebc_reset, ebc);
1353 ppc_dcr_register(env, EBC0_CFGADDR,
1354 ebc, &dcr_read_ebc, &dcr_write_ebc);
1355 ppc_dcr_register(env, EBC0_CFGDATA,
1356 ebc, &dcr_read_ebc, &dcr_write_ebc);
1357 }
1358}
1359
1360/*****************************************************************************/
1361/* DMA controller */
1362enum {
1363 DMA0_CR0 = 0x100,
1364 DMA0_CT0 = 0x101,
1365 DMA0_DA0 = 0x102,
1366 DMA0_SA0 = 0x103,
1367 DMA0_SG0 = 0x104,
1368 DMA0_CR1 = 0x108,
1369 DMA0_CT1 = 0x109,
1370 DMA0_DA1 = 0x10A,
1371 DMA0_SA1 = 0x10B,
1372 DMA0_SG1 = 0x10C,
1373 DMA0_CR2 = 0x110,
1374 DMA0_CT2 = 0x111,
1375 DMA0_DA2 = 0x112,
1376 DMA0_SA2 = 0x113,
1377 DMA0_SG2 = 0x114,
1378 DMA0_CR3 = 0x118,
1379 DMA0_CT3 = 0x119,
1380 DMA0_DA3 = 0x11A,
1381 DMA0_SA3 = 0x11B,
1382 DMA0_SG3 = 0x11C,
1383 DMA0_SR = 0x120,
1384 DMA0_SGC = 0x123,
1385 DMA0_SLP = 0x125,
1386 DMA0_POL = 0x126,
1387};
1388
1389typedef struct ppc405_dma_t ppc405_dma_t;
1390struct ppc405_dma_t {
1391 qemu_irq irqs[4];
1392 uint32_t cr[4];
1393 uint32_t ct[4];
1394 uint32_t da[4];
1395 uint32_t sa[4];
1396 uint32_t sg[4];
1397 uint32_t sr;
1398 uint32_t sgc;
1399 uint32_t slp;
1400 uint32_t pol;
1401};
1402
1403static target_ulong dcr_read_dma (void *opaque, int dcrn)
1404{
1405 ppc405_dma_t *dma;
1406
1407 dma = opaque;
1408
1409 return 0;
1410}
1411
1412static void dcr_write_dma (void *opaque, int dcrn, target_ulong val)
1413{
1414 ppc405_dma_t *dma;
1415
1416 dma = opaque;
1417}
1418
1419static void ppc405_dma_reset (void *opaque)
1420{
1421 ppc405_dma_t *dma;
1422 int i;
1423
1424 dma = opaque;
1425 for (i = 0; i < 4; i++) {
1426 dma->cr[i] = 0x00000000;
1427 dma->ct[i] = 0x00000000;
1428 dma->da[i] = 0x00000000;
1429 dma->sa[i] = 0x00000000;
1430 dma->sg[i] = 0x00000000;
1431 }
1432 dma->sr = 0x00000000;
1433 dma->sgc = 0x00000000;
1434 dma->slp = 0x7C000000;
1435 dma->pol = 0x00000000;
1436}
1437
1438void ppc405_dma_init (CPUState *env, qemu_irq irqs[4])
1439{
1440 ppc405_dma_t *dma;
1441
1442 dma = qemu_mallocz(sizeof(ppc405_dma_t));
1443 if (dma != NULL) {
1444 memcpy(dma->irqs, irqs, 4 * sizeof(qemu_irq));
1445 ppc405_dma_reset(dma);
1446 qemu_register_reset(&ppc405_dma_reset, dma);
1447 ppc_dcr_register(env, DMA0_CR0,
1448 dma, &dcr_read_dma, &dcr_write_dma);
1449 ppc_dcr_register(env, DMA0_CT0,
1450 dma, &dcr_read_dma, &dcr_write_dma);
1451 ppc_dcr_register(env, DMA0_DA0,
1452 dma, &dcr_read_dma, &dcr_write_dma);
1453 ppc_dcr_register(env, DMA0_SA0,
1454 dma, &dcr_read_dma, &dcr_write_dma);
1455 ppc_dcr_register(env, DMA0_SG0,
1456 dma, &dcr_read_dma, &dcr_write_dma);
1457 ppc_dcr_register(env, DMA0_CR1,
1458 dma, &dcr_read_dma, &dcr_write_dma);
1459 ppc_dcr_register(env, DMA0_CT1,
1460 dma, &dcr_read_dma, &dcr_write_dma);
1461 ppc_dcr_register(env, DMA0_DA1,
1462 dma, &dcr_read_dma, &dcr_write_dma);
1463 ppc_dcr_register(env, DMA0_SA1,
1464 dma, &dcr_read_dma, &dcr_write_dma);
1465 ppc_dcr_register(env, DMA0_SG1,
1466 dma, &dcr_read_dma, &dcr_write_dma);
1467 ppc_dcr_register(env, DMA0_CR2,
1468 dma, &dcr_read_dma, &dcr_write_dma);
1469 ppc_dcr_register(env, DMA0_CT2,
1470 dma, &dcr_read_dma, &dcr_write_dma);
1471 ppc_dcr_register(env, DMA0_DA2,
1472 dma, &dcr_read_dma, &dcr_write_dma);
1473 ppc_dcr_register(env, DMA0_SA2,
1474 dma, &dcr_read_dma, &dcr_write_dma);
1475 ppc_dcr_register(env, DMA0_SG2,
1476 dma, &dcr_read_dma, &dcr_write_dma);
1477 ppc_dcr_register(env, DMA0_CR3,
1478 dma, &dcr_read_dma, &dcr_write_dma);
1479 ppc_dcr_register(env, DMA0_CT3,
1480 dma, &dcr_read_dma, &dcr_write_dma);
1481 ppc_dcr_register(env, DMA0_DA3,
1482 dma, &dcr_read_dma, &dcr_write_dma);
1483 ppc_dcr_register(env, DMA0_SA3,
1484 dma, &dcr_read_dma, &dcr_write_dma);
1485 ppc_dcr_register(env, DMA0_SG3,
1486 dma, &dcr_read_dma, &dcr_write_dma);
1487 ppc_dcr_register(env, DMA0_SR,
1488 dma, &dcr_read_dma, &dcr_write_dma);
1489 ppc_dcr_register(env, DMA0_SGC,
1490 dma, &dcr_read_dma, &dcr_write_dma);
1491 ppc_dcr_register(env, DMA0_SLP,
1492 dma, &dcr_read_dma, &dcr_write_dma);
1493 ppc_dcr_register(env, DMA0_POL,
1494 dma, &dcr_read_dma, &dcr_write_dma);
1495 }
1496}
1497
1498/*****************************************************************************/
1499/* GPIO */
1500typedef struct ppc405_gpio_t ppc405_gpio_t;
1501struct ppc405_gpio_t {
1502 uint32_t base;
1503 uint32_t or;
1504 uint32_t tcr;
1505 uint32_t osrh;
1506 uint32_t osrl;
1507 uint32_t tsrh;
1508 uint32_t tsrl;
1509 uint32_t odr;
1510 uint32_t ir;
1511 uint32_t rr1;
1512 uint32_t isr1h;
1513 uint32_t isr1l;
1514};
1515
1516static uint32_t ppc405_gpio_readb (void *opaque, target_phys_addr_t addr)
1517{
1518 ppc405_gpio_t *gpio;
1519
1520 gpio = opaque;
1521#ifdef DEBUG_GPIO
1522 printf("%s: addr " PADDRX "\n", __func__, addr);
1523#endif
1524
1525 return 0;
1526}
1527
1528static void ppc405_gpio_writeb (void *opaque,
1529 target_phys_addr_t addr, uint32_t value)
1530{
1531 ppc405_gpio_t *gpio;
1532
1533 gpio = opaque;
1534#ifdef DEBUG_GPIO
1535 printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
1536#endif
1537}
1538
1539static uint32_t ppc405_gpio_readw (void *opaque, target_phys_addr_t addr)
1540{
1541 ppc405_gpio_t *gpio;
1542
1543 gpio = opaque;
1544#ifdef DEBUG_GPIO
1545 printf("%s: addr " PADDRX "\n", __func__, addr);
1546#endif
1547
1548 return 0;
1549}
1550
1551static void ppc405_gpio_writew (void *opaque,
1552 target_phys_addr_t addr, uint32_t value)
1553{
1554 ppc405_gpio_t *gpio;
1555
1556 gpio = opaque;
1557#ifdef DEBUG_GPIO
1558 printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
1559#endif
1560}
1561
1562static uint32_t ppc405_gpio_readl (void *opaque, target_phys_addr_t addr)
1563{
1564 ppc405_gpio_t *gpio;
1565
1566 gpio = opaque;
1567#ifdef DEBUG_GPIO
1568 printf("%s: addr " PADDRX "\n", __func__, addr);
1569#endif
1570
1571 return 0;
1572}
1573
1574static void ppc405_gpio_writel (void *opaque,
1575 target_phys_addr_t addr, uint32_t value)
1576{
1577 ppc405_gpio_t *gpio;
1578
1579 gpio = opaque;
1580#ifdef DEBUG_GPIO
1581 printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
1582#endif
1583}
1584
1585static CPUReadMemoryFunc *ppc405_gpio_read[] = {
1586 &ppc405_gpio_readb,
1587 &ppc405_gpio_readw,
1588 &ppc405_gpio_readl,
1589};
1590
1591static CPUWriteMemoryFunc *ppc405_gpio_write[] = {
1592 &ppc405_gpio_writeb,
1593 &ppc405_gpio_writew,
1594 &ppc405_gpio_writel,
1595};
1596
1597static void ppc405_gpio_reset (void *opaque)
1598{
1599 ppc405_gpio_t *gpio;
1600
1601 gpio = opaque;
1602}
1603
1604void ppc405_gpio_init (CPUState *env, ppc4xx_mmio_t *mmio, uint32_t offset)
1605{
1606 ppc405_gpio_t *gpio;
1607
1608 gpio = qemu_mallocz(sizeof(ppc405_gpio_t));
1609 if (gpio != NULL) {
1610 gpio->base = mmio->base + offset;
1611 ppc405_gpio_reset(gpio);
1612 qemu_register_reset(&ppc405_gpio_reset, gpio);
1613#ifdef DEBUG_GPIO
1614 printf("%s: offset=%08x\n", __func__, offset);
1615#endif
1616 ppc4xx_mmio_register(env, mmio, offset, 0x038,
1617 ppc405_gpio_read, ppc405_gpio_write, gpio);
1618 }
1619}
1620
1621/*****************************************************************************/
1622/* Serial ports */
1623static CPUReadMemoryFunc *serial_mm_read[] = {
1624 &serial_mm_readb,
1625 &serial_mm_readw,
1626 &serial_mm_readl,
1627};
1628
1629static CPUWriteMemoryFunc *serial_mm_write[] = {
1630 &serial_mm_writeb,
1631 &serial_mm_writew,
1632 &serial_mm_writel,
1633};
1634
1635void ppc405_serial_init (CPUState *env, ppc4xx_mmio_t *mmio,
1636 uint32_t offset, qemu_irq irq,
1637 CharDriverState *chr)
1638{
1639 void *serial;
1640
1641#ifdef DEBUG_SERIAL
1642 printf("%s: offset=%08x\n", __func__, offset);
1643#endif
1644 serial = serial_mm_init(mmio->base + offset, 0, irq, chr, 0);
1645 ppc4xx_mmio_register(env, mmio, offset, 0x008,
1646 serial_mm_read, serial_mm_write, serial);
1647}
1648
1649/*****************************************************************************/
1650/* On Chip Memory */
1651enum {
1652 OCM0_ISARC = 0x018,
1653 OCM0_ISACNTL = 0x019,
1654 OCM0_DSARC = 0x01A,
1655 OCM0_DSACNTL = 0x01B,
1656};
1657
1658typedef struct ppc405_ocm_t ppc405_ocm_t;
1659struct ppc405_ocm_t {
1660 target_ulong offset;
1661 uint32_t isarc;
1662 uint32_t isacntl;
1663 uint32_t dsarc;
1664 uint32_t dsacntl;
1665};
1666
1667static void ocm_update_mappings (ppc405_ocm_t *ocm,
1668 uint32_t isarc, uint32_t isacntl,
1669 uint32_t dsarc, uint32_t dsacntl)
1670{
1671#ifdef DEBUG_OCM
1672 printf("OCM update ISA %08x %08x (%08x %08x) DSA %08x %08x (%08x %08x)\n",
1673 isarc, isacntl, dsarc, dsacntl,
1674 ocm->isarc, ocm->isacntl, ocm->dsarc, ocm->dsacntl);
1675#endif
1676 if (ocm->isarc != isarc ||
1677 (ocm->isacntl & 0x80000000) != (isacntl & 0x80000000)) {
1678 if (ocm->isacntl & 0x80000000) {
1679 /* Unmap previously assigned memory region */
1680 printf("OCM unmap ISA %08x\n", ocm->isarc);
1681 cpu_register_physical_memory(ocm->isarc, 0x04000000,
1682 IO_MEM_UNASSIGNED);
1683 }
1684 if (isacntl & 0x80000000) {
1685 /* Map new instruction memory region */
1686#ifdef DEBUG_OCM
1687 printf("OCM map ISA %08x\n", isarc);
1688#endif
1689 cpu_register_physical_memory(isarc, 0x04000000,
1690 ocm->offset | IO_MEM_RAM);
1691 }
1692 }
1693 if (ocm->dsarc != dsarc ||
1694 (ocm->dsacntl & 0x80000000) != (dsacntl & 0x80000000)) {
1695 if (ocm->dsacntl & 0x80000000) {
1696 /* Beware not to unmap the region we just mapped */
1697 if (!(isacntl & 0x80000000) || ocm->dsarc != isarc) {
1698 /* Unmap previously assigned memory region */
1699#ifdef DEBUG_OCM
1700 printf("OCM unmap DSA %08x\n", ocm->dsarc);
1701#endif
1702 cpu_register_physical_memory(ocm->dsarc, 0x04000000,
1703 IO_MEM_UNASSIGNED);
1704 }
1705 }
1706 if (dsacntl & 0x80000000) {
1707 /* Beware not to remap the region we just mapped */
1708 if (!(isacntl & 0x80000000) || dsarc != isarc) {
1709 /* Map new data memory region */
1710#ifdef DEBUG_OCM
1711 printf("OCM map DSA %08x\n", dsarc);
1712#endif
1713 cpu_register_physical_memory(dsarc, 0x04000000,
1714 ocm->offset | IO_MEM_RAM);
1715 }
1716 }
1717 }
1718}
1719
1720static target_ulong dcr_read_ocm (void *opaque, int dcrn)
1721{
1722 ppc405_ocm_t *ocm;
1723 target_ulong ret;
1724
1725 ocm = opaque;
1726 switch (dcrn) {
1727 case OCM0_ISARC:
1728 ret = ocm->isarc;
1729 break;
1730 case OCM0_ISACNTL:
1731 ret = ocm->isacntl;
1732 break;
1733 case OCM0_DSARC:
1734 ret = ocm->dsarc;
1735 break;
1736 case OCM0_DSACNTL:
1737 ret = ocm->dsacntl;
1738 break;
1739 default:
1740 ret = 0;
1741 break;
1742 }
1743
1744 return ret;
1745}
1746
1747static void dcr_write_ocm (void *opaque, int dcrn, target_ulong val)
1748{
1749 ppc405_ocm_t *ocm;
1750 uint32_t isarc, dsarc, isacntl, dsacntl;
1751
1752 ocm = opaque;
1753 isarc = ocm->isarc;
1754 dsarc = ocm->dsarc;
1755 isacntl = ocm->isacntl;
1756 dsacntl = ocm->dsacntl;
1757 switch (dcrn) {
1758 case OCM0_ISARC:
1759 isarc = val & 0xFC000000;
1760 break;
1761 case OCM0_ISACNTL:
1762 isacntl = val & 0xC0000000;
1763 break;
1764 case OCM0_DSARC:
1765 isarc = val & 0xFC000000;
1766 break;
1767 case OCM0_DSACNTL:
1768 isacntl = val & 0xC0000000;
1769 break;
1770 }
1771 ocm_update_mappings(ocm, isarc, isacntl, dsarc, dsacntl);
1772 ocm->isarc = isarc;
1773 ocm->dsarc = dsarc;
1774 ocm->isacntl = isacntl;
1775 ocm->dsacntl = dsacntl;
1776}
1777
1778static void ocm_reset (void *opaque)
1779{
1780 ppc405_ocm_t *ocm;
1781 uint32_t isarc, dsarc, isacntl, dsacntl;
1782
1783 ocm = opaque;
1784 isarc = 0x00000000;
1785 isacntl = 0x00000000;
1786 dsarc = 0x00000000;
1787 dsacntl = 0x00000000;
1788 ocm_update_mappings(ocm, isarc, isacntl, dsarc, dsacntl);
1789 ocm->isarc = isarc;
1790 ocm->dsarc = dsarc;
1791 ocm->isacntl = isacntl;
1792 ocm->dsacntl = dsacntl;
1793}
1794
1795void ppc405_ocm_init (CPUState *env, unsigned long offset)
1796{
1797 ppc405_ocm_t *ocm;
1798
1799 ocm = qemu_mallocz(sizeof(ppc405_ocm_t));
1800 if (ocm != NULL) {
1801 ocm->offset = offset;
1802 ocm_reset(ocm);
1803 qemu_register_reset(&ocm_reset, ocm);
1804 ppc_dcr_register(env, OCM0_ISARC,
1805 ocm, &dcr_read_ocm, &dcr_write_ocm);
1806 ppc_dcr_register(env, OCM0_ISACNTL,
1807 ocm, &dcr_read_ocm, &dcr_write_ocm);
1808 ppc_dcr_register(env, OCM0_DSARC,
1809 ocm, &dcr_read_ocm, &dcr_write_ocm);
1810 ppc_dcr_register(env, OCM0_DSACNTL,
1811 ocm, &dcr_read_ocm, &dcr_write_ocm);
1812 }
1813}
1814
1815/*****************************************************************************/
1816/* I2C controller */
1817typedef struct ppc4xx_i2c_t ppc4xx_i2c_t;
1818struct ppc4xx_i2c_t {
1819 uint32_t base;
1820 uint8_t mdata;
1821 uint8_t lmadr;
1822 uint8_t hmadr;
1823 uint8_t cntl;
1824 uint8_t mdcntl;
1825 uint8_t sts;
1826 uint8_t extsts;
1827 uint8_t sdata;
1828 uint8_t lsadr;
1829 uint8_t hsadr;
1830 uint8_t clkdiv;
1831 uint8_t intrmsk;
1832 uint8_t xfrcnt;
1833 uint8_t xtcntlss;
1834 uint8_t directcntl;
1835};
1836
1837static uint32_t ppc4xx_i2c_readb (void *opaque, target_phys_addr_t addr)
1838{
1839 ppc4xx_i2c_t *i2c;
1840 uint32_t ret;
1841
1842#ifdef DEBUG_I2C
1843 printf("%s: addr " PADDRX "\n", __func__, addr);
1844#endif
1845 i2c = opaque;
1846 switch (addr - i2c->base) {
1847 case 0x00:
1848 // i2c_readbyte(&i2c->mdata);
1849 ret = i2c->mdata;
1850 break;
1851 case 0x02:
1852 ret = i2c->sdata;
1853 break;
1854 case 0x04:
1855 ret = i2c->lmadr;
1856 break;
1857 case 0x05:
1858 ret = i2c->hmadr;
1859 break;
1860 case 0x06:
1861 ret = i2c->cntl;
1862 break;
1863 case 0x07:
1864 ret = i2c->mdcntl;
1865 break;
1866 case 0x08:
1867 ret = i2c->sts;
1868 break;
1869 case 0x09:
1870 ret = i2c->extsts;
1871 break;
1872 case 0x0A:
1873 ret = i2c->lsadr;
1874 break;
1875 case 0x0B:
1876 ret = i2c->hsadr;
1877 break;
1878 case 0x0C:
1879 ret = i2c->clkdiv;
1880 break;
1881 case 0x0D:
1882 ret = i2c->intrmsk;
1883 break;
1884 case 0x0E:
1885 ret = i2c->xfrcnt;
1886 break;
1887 case 0x0F:
1888 ret = i2c->xtcntlss;
1889 break;
1890 case 0x10:
1891 ret = i2c->directcntl;
1892 break;
1893 default:
1894 ret = 0x00;
1895 break;
1896 }
1897#ifdef DEBUG_I2C
1898 printf("%s: addr " PADDRX " %02x\n", __func__, addr, ret);
1899#endif
1900
1901 return ret;
1902}
1903
1904static void ppc4xx_i2c_writeb (void *opaque,
1905 target_phys_addr_t addr, uint32_t value)
1906{
1907 ppc4xx_i2c_t *i2c;
1908
1909#ifdef DEBUG_I2C
1910 printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
1911#endif
1912 i2c = opaque;
1913 switch (addr - i2c->base) {
1914 case 0x00:
1915 i2c->mdata = value;
1916 // i2c_sendbyte(&i2c->mdata);
1917 break;
1918 case 0x02:
1919 i2c->sdata = value;
1920 break;
1921 case 0x04:
1922 i2c->lmadr = value;
1923 break;
1924 case 0x05:
1925 i2c->hmadr = value;
1926 break;
1927 case 0x06:
1928 i2c->cntl = value;
1929 break;
1930 case 0x07:
1931 i2c->mdcntl = value & 0xDF;
1932 break;
1933 case 0x08:
1934 i2c->sts &= ~(value & 0x0A);
1935 break;
1936 case 0x09:
1937 i2c->extsts &= ~(value & 0x8F);
1938 break;
1939 case 0x0A:
1940 i2c->lsadr = value;
1941 break;
1942 case 0x0B:
1943 i2c->hsadr = value;
1944 break;
1945 case 0x0C:
1946 i2c->clkdiv = value;
1947 break;
1948 case 0x0D:
1949 i2c->intrmsk = value;
1950 break;
1951 case 0x0E:
1952 i2c->xfrcnt = value & 0x77;
1953 break;
1954 case 0x0F:
1955 i2c->xtcntlss = value;
1956 break;
1957 case 0x10:
1958 i2c->directcntl = value & 0x7;
1959 break;
1960 }
1961}
1962
1963static uint32_t ppc4xx_i2c_readw (void *opaque, target_phys_addr_t addr)
1964{
1965 uint32_t ret;
1966
1967#ifdef DEBUG_I2C
1968 printf("%s: addr " PADDRX "\n", __func__, addr);
1969#endif
1970 ret = ppc4xx_i2c_readb(opaque, addr) << 8;
1971 ret |= ppc4xx_i2c_readb(opaque, addr + 1);
1972
1973 return ret;
1974}
1975
1976static void ppc4xx_i2c_writew (void *opaque,
1977 target_phys_addr_t addr, uint32_t value)
1978{
1979#ifdef DEBUG_I2C
1980 printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
1981#endif
1982 ppc4xx_i2c_writeb(opaque, addr, value >> 8);
1983 ppc4xx_i2c_writeb(opaque, addr + 1, value);
1984}
1985
1986static uint32_t ppc4xx_i2c_readl (void *opaque, target_phys_addr_t addr)
1987{
1988 uint32_t ret;
1989
1990#ifdef DEBUG_I2C
1991 printf("%s: addr " PADDRX "\n", __func__, addr);
1992#endif
1993 ret = ppc4xx_i2c_readb(opaque, addr) << 24;
1994 ret |= ppc4xx_i2c_readb(opaque, addr + 1) << 16;
1995 ret |= ppc4xx_i2c_readb(opaque, addr + 2) << 8;
1996 ret |= ppc4xx_i2c_readb(opaque, addr + 3);
1997
1998 return ret;
1999}
2000
2001static void ppc4xx_i2c_writel (void *opaque,
2002 target_phys_addr_t addr, uint32_t value)
2003{
2004#ifdef DEBUG_I2C
2005 printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
2006#endif
2007 ppc4xx_i2c_writeb(opaque, addr, value >> 24);
2008 ppc4xx_i2c_writeb(opaque, addr + 1, value >> 16);
2009 ppc4xx_i2c_writeb(opaque, addr + 2, value >> 8);
2010 ppc4xx_i2c_writeb(opaque, addr + 3, value);
2011}
2012
2013static CPUReadMemoryFunc *i2c_read[] = {
2014 &ppc4xx_i2c_readb,
2015 &ppc4xx_i2c_readw,
2016 &ppc4xx_i2c_readl,
2017};
2018
2019static CPUWriteMemoryFunc *i2c_write[] = {
2020 &ppc4xx_i2c_writeb,
2021 &ppc4xx_i2c_writew,
2022 &ppc4xx_i2c_writel,
2023};
2024
2025static void ppc4xx_i2c_reset (void *opaque)
2026{
2027 ppc4xx_i2c_t *i2c;
2028
2029 i2c = opaque;
2030 i2c->mdata = 0x00;
2031 i2c->sdata = 0x00;
2032 i2c->cntl = 0x00;
2033 i2c->mdcntl = 0x00;
2034 i2c->sts = 0x00;
2035 i2c->extsts = 0x00;
2036 i2c->clkdiv = 0x00;
2037 i2c->xfrcnt = 0x00;
2038 i2c->directcntl = 0x0F;
2039}
2040
2041void ppc405_i2c_init (CPUState *env, ppc4xx_mmio_t *mmio, uint32_t offset)
2042{
2043 ppc4xx_i2c_t *i2c;
2044
2045 i2c = qemu_mallocz(sizeof(ppc4xx_i2c_t));
2046 if (i2c != NULL) {
2047 i2c->base = mmio->base + offset;
2048 ppc4xx_i2c_reset(i2c);
2049#ifdef DEBUG_I2C
2050 printf("%s: offset=%08x\n", __func__, offset);
2051#endif
2052 ppc4xx_mmio_register(env, mmio, offset, 0x011,
2053 i2c_read, i2c_write, i2c);
2054 qemu_register_reset(ppc4xx_i2c_reset, i2c);
2055 }
2056}
2057
2058/*****************************************************************************/
2059/* SPR */
2060void ppc40x_core_reset (CPUState *env)
2061{
2062 target_ulong dbsr;
2063
2064 printf("Reset PowerPC core\n");
2065 cpu_ppc_reset(env);
2066 dbsr = env->spr[SPR_40x_DBSR];
2067 dbsr &= ~0x00000300;
2068 dbsr |= 0x00000100;
2069 env->spr[SPR_40x_DBSR] = dbsr;
2070 cpu_loop_exit();
2071}
2072
2073void ppc40x_chip_reset (CPUState *env)
2074{
2075 target_ulong dbsr;
2076
2077 printf("Reset PowerPC chip\n");
2078 cpu_ppc_reset(env);
2079 /* XXX: TODO reset all internal peripherals */
2080 dbsr = env->spr[SPR_40x_DBSR];
2081 dbsr &= ~0x00000300;
2082 dbsr |= 0x00000100;
2083 env->spr[SPR_40x_DBSR] = dbsr;
2084 cpu_loop_exit();
2085}
2086
2087void ppc40x_system_reset (CPUState *env)
2088{
2089 printf("Reset PowerPC system\n");
2090 qemu_system_reset_request();
2091}
2092
2093void store_40x_dbcr0 (CPUState *env, uint32_t val)
2094{
2095 switch ((val >> 28) & 0x3) {
2096 case 0x0:
2097 /* No action */
2098 break;
2099 case 0x1:
2100 /* Core reset */
2101 ppc40x_core_reset(env);
2102 break;
2103 case 0x2:
2104 /* Chip reset */
2105 ppc40x_chip_reset(env);
2106 break;
2107 case 0x3:
2108 /* System reset */
2109 ppc40x_system_reset(env);
2110 break;
2111 }
2112}
2113
2114/*****************************************************************************/
2115/* PowerPC 405CR */
2116enum {
2117 PPC405CR_CPC0_PLLMR = 0x0B0,
2118 PPC405CR_CPC0_CR0 = 0x0B1,
2119 PPC405CR_CPC0_CR1 = 0x0B2,
2120 PPC405CR_CPC0_PSR = 0x0B4,
2121 PPC405CR_CPC0_JTAGID = 0x0B5,
2122 PPC405CR_CPC0_ER = 0x0B9,
2123 PPC405CR_CPC0_FR = 0x0BA,
2124 PPC405CR_CPC0_SR = 0x0BB,
2125};
2126
2127typedef struct ppc405cr_cpc_t ppc405cr_cpc_t;
2128struct ppc405cr_cpc_t {
2129 clk_setup_t clk_setup[7];
2130 uint32_t sysclk;
2131 uint32_t psr;
2132 uint32_t cr0;
2133 uint32_t cr1;
2134 uint32_t jtagid;
2135 uint32_t pllmr;
2136 uint32_t er;
2137 uint32_t fr;
2138};
2139
2140static void ppc405cr_clk_setup (ppc405cr_cpc_t *cpc)
2141{
2142 uint64_t VCO_out, PLL_out;
2143 uint32_t CPU_clk, TMR_clk, SDRAM_clk, PLB_clk, OPB_clk, EXT_clk, UART_clk;
2144 int M, D0, D1, D2;
2145
2146 D0 = ((cpc->pllmr >> 26) & 0x3) + 1; /* CBDV */
2147 if (cpc->pllmr & 0x80000000) {
2148 D1 = (((cpc->pllmr >> 20) - 1) & 0xF) + 1; /* FBDV */
2149 D2 = 8 - ((cpc->pllmr >> 16) & 0x7); /* FWDVA */
2150 M = D0 * D1 * D2;
2151 VCO_out = cpc->sysclk * M;
2152 if (VCO_out < 400000000 || VCO_out > 800000000) {
2153 /* PLL cannot lock */
2154 cpc->pllmr &= ~0x80000000;
2155 goto bypass_pll;
2156 }
2157 PLL_out = VCO_out / D2;
2158 } else {
2159 /* Bypass PLL */
2160 bypass_pll:
2161 M = D0;
2162 PLL_out = cpc->sysclk * M;
2163 }
2164 CPU_clk = PLL_out;
2165 if (cpc->cr1 & 0x00800000)
2166 TMR_clk = cpc->sysclk; /* Should have a separate clock */
2167 else
2168 TMR_clk = CPU_clk;
2169 PLB_clk = CPU_clk / D0;
2170 SDRAM_clk = PLB_clk;
2171 D0 = ((cpc->pllmr >> 10) & 0x3) + 1;
2172 OPB_clk = PLB_clk / D0;
2173 D0 = ((cpc->pllmr >> 24) & 0x3) + 2;
2174 EXT_clk = PLB_clk / D0;
2175 D0 = ((cpc->cr0 >> 1) & 0x1F) + 1;
2176 UART_clk = CPU_clk / D0;
2177 /* Setup CPU clocks */
2178 clk_setup(&cpc->clk_setup[0], CPU_clk);
2179 /* Setup time-base clock */
2180 clk_setup(&cpc->clk_setup[1], TMR_clk);
2181 /* Setup PLB clock */
2182 clk_setup(&cpc->clk_setup[2], PLB_clk);
2183 /* Setup SDRAM clock */
2184 clk_setup(&cpc->clk_setup[3], SDRAM_clk);
2185 /* Setup OPB clock */
2186 clk_setup(&cpc->clk_setup[4], OPB_clk);
2187 /* Setup external clock */
2188 clk_setup(&cpc->clk_setup[5], EXT_clk);
2189 /* Setup UART clock */
2190 clk_setup(&cpc->clk_setup[6], UART_clk);
2191}
2192
2193static target_ulong dcr_read_crcpc (void *opaque, int dcrn)
2194{
2195 ppc405cr_cpc_t *cpc;
2196 target_ulong ret;
2197
2198 cpc = opaque;
2199 switch (dcrn) {
2200 case PPC405CR_CPC0_PLLMR:
2201 ret = cpc->pllmr;
2202 break;
2203 case PPC405CR_CPC0_CR0:
2204 ret = cpc->cr0;
2205 break;
2206 case PPC405CR_CPC0_CR1:
2207 ret = cpc->cr1;
2208 break;
2209 case PPC405CR_CPC0_PSR:
2210 ret = cpc->psr;
2211 break;
2212 case PPC405CR_CPC0_JTAGID:
2213 ret = cpc->jtagid;
2214 break;
2215 case PPC405CR_CPC0_ER:
2216 ret = cpc->er;
2217 break;
2218 case PPC405CR_CPC0_FR:
2219 ret = cpc->fr;
2220 break;
2221 case PPC405CR_CPC0_SR:
2222 ret = ~(cpc->er | cpc->fr) & 0xFFFF0000;
2223 break;
2224 default:
2225 /* Avoid gcc warning */
2226 ret = 0;
2227 break;
2228 }
2229
2230 return ret;
2231}
2232
2233static void dcr_write_crcpc (void *opaque, int dcrn, target_ulong val)
2234{
2235 ppc405cr_cpc_t *cpc;
2236
2237 cpc = opaque;
2238 switch (dcrn) {
2239 case PPC405CR_CPC0_PLLMR:
2240 cpc->pllmr = val & 0xFFF77C3F;
2241 break;
2242 case PPC405CR_CPC0_CR0:
2243 cpc->cr0 = val & 0x0FFFFFFE;
2244 break;
2245 case PPC405CR_CPC0_CR1:
2246 cpc->cr1 = val & 0x00800000;
2247 break;
2248 case PPC405CR_CPC0_PSR:
2249 /* Read-only */
2250 break;
2251 case PPC405CR_CPC0_JTAGID:
2252 /* Read-only */
2253 break;
2254 case PPC405CR_CPC0_ER:
2255 cpc->er = val & 0xBFFC0000;
2256 break;
2257 case PPC405CR_CPC0_FR:
2258 cpc->fr = val & 0xBFFC0000;
2259 break;
2260 case PPC405CR_CPC0_SR:
2261 /* Read-only */
2262 break;
2263 }
2264}
2265
2266static void ppc405cr_cpc_reset (void *opaque)
2267{
2268 ppc405cr_cpc_t *cpc;
2269 int D;
2270
2271 cpc = opaque;
2272 /* Compute PLLMR value from PSR settings */
2273 cpc->pllmr = 0x80000000;
2274 /* PFWD */
2275 switch ((cpc->psr >> 30) & 3) {
2276 case 0:
2277 /* Bypass */
2278 cpc->pllmr &= ~0x80000000;
2279 break;
2280 case 1:
2281 /* Divide by 3 */
2282 cpc->pllmr |= 5 << 16;
2283 break;
2284 case 2:
2285 /* Divide by 4 */
2286 cpc->pllmr |= 4 << 16;
2287 break;
2288 case 3:
2289 /* Divide by 6 */
2290 cpc->pllmr |= 2 << 16;
2291 break;
2292 }
2293 /* PFBD */
2294 D = (cpc->psr >> 28) & 3;
2295 cpc->pllmr |= (D + 1) << 20;
2296 /* PT */
2297 D = (cpc->psr >> 25) & 7;
2298 switch (D) {
2299 case 0x2:
2300 cpc->pllmr |= 0x13;
2301 break;
2302 case 0x4:
2303 cpc->pllmr |= 0x15;
2304 break;
2305 case 0x5:
2306 cpc->pllmr |= 0x16;
2307 break;
2308 default:
2309 break;
2310 }
2311 /* PDC */
2312 D = (cpc->psr >> 23) & 3;
2313 cpc->pllmr |= D << 26;
2314 /* ODP */
2315 D = (cpc->psr >> 21) & 3;
2316 cpc->pllmr |= D << 10;
2317 /* EBPD */
2318 D = (cpc->psr >> 17) & 3;
2319 cpc->pllmr |= D << 24;
2320 cpc->cr0 = 0x0000003C;
2321 cpc->cr1 = 0x2B0D8800;
2322 cpc->er = 0x00000000;
2323 cpc->fr = 0x00000000;
2324 ppc405cr_clk_setup(cpc);
2325}
2326
2327static void ppc405cr_clk_init (ppc405cr_cpc_t *cpc)
2328{
2329 int D;
2330
2331 /* XXX: this should be read from IO pins */
2332 cpc->psr = 0x00000000; /* 8 bits ROM */
2333 /* PFWD */
2334 D = 0x2; /* Divide by 4 */
2335 cpc->psr |= D << 30;
2336 /* PFBD */
2337 D = 0x1; /* Divide by 2 */
2338 cpc->psr |= D << 28;
2339 /* PDC */
2340 D = 0x1; /* Divide by 2 */
2341 cpc->psr |= D << 23;
2342 /* PT */
2343 D = 0x5; /* M = 16 */
2344 cpc->psr |= D << 25;
2345 /* ODP */
2346 D = 0x1; /* Divide by 2 */
2347 cpc->psr |= D << 21;
2348 /* EBDP */
2349 D = 0x2; /* Divide by 4 */
2350 cpc->psr |= D << 17;
2351}
2352
2353static void ppc405cr_cpc_init (CPUState *env, clk_setup_t clk_setup[7],
2354 uint32_t sysclk)
2355{
2356 ppc405cr_cpc_t *cpc;
2357
2358 cpc = qemu_mallocz(sizeof(ppc405cr_cpc_t));
2359 if (cpc != NULL) {
2360 memcpy(cpc->clk_setup, clk_setup, 7 * sizeof(clk_setup_t));
2361 cpc->sysclk = sysclk;
2362 cpc->jtagid = 0x42051049;
2363 ppc_dcr_register(env, PPC405CR_CPC0_PSR, cpc,
2364 &dcr_read_crcpc, &dcr_write_crcpc);
2365 ppc_dcr_register(env, PPC405CR_CPC0_CR0, cpc,
2366 &dcr_read_crcpc, &dcr_write_crcpc);
2367 ppc_dcr_register(env, PPC405CR_CPC0_CR1, cpc,
2368 &dcr_read_crcpc, &dcr_write_crcpc);
2369 ppc_dcr_register(env, PPC405CR_CPC0_JTAGID, cpc,
2370 &dcr_read_crcpc, &dcr_write_crcpc);
2371 ppc_dcr_register(env, PPC405CR_CPC0_PLLMR, cpc,
2372 &dcr_read_crcpc, &dcr_write_crcpc);
2373 ppc_dcr_register(env, PPC405CR_CPC0_ER, cpc,
2374 &dcr_read_crcpc, &dcr_write_crcpc);
2375 ppc_dcr_register(env, PPC405CR_CPC0_FR, cpc,
2376 &dcr_read_crcpc, &dcr_write_crcpc);
2377 ppc_dcr_register(env, PPC405CR_CPC0_SR, cpc,
2378 &dcr_read_crcpc, &dcr_write_crcpc);
2379 ppc405cr_clk_init(cpc);
2380 qemu_register_reset(ppc405cr_cpc_reset, cpc);
2381 ppc405cr_cpc_reset(cpc);
2382 }
2383}
2384
2385CPUState *ppc405cr_init (target_ulong ram_bases[4], target_ulong ram_sizes[4],
2386 uint32_t sysclk, qemu_irq **picp,
2387 ram_addr_t *offsetp)
2388{
2389 clk_setup_t clk_setup[7];
2390 qemu_irq dma_irqs[4];
2391 CPUState *env;
2392 ppc4xx_mmio_t *mmio;
2393 qemu_irq *pic, *irqs;
2394 ram_addr_t offset;
2395 int i;
2396
2397 memset(clk_setup, 0, sizeof(clk_setup));
2398 env = ppc405_init("405cr", &clk_setup[0], &clk_setup[1], sysclk);
2399 /* Memory mapped devices registers */
2400 mmio = ppc4xx_mmio_init(env, 0xEF600000);
2401 /* PLB arbitrer */
2402 ppc4xx_plb_init(env);
2403 /* PLB to OPB bridge */
2404 ppc4xx_pob_init(env);
2405 /* OBP arbitrer */
2406 ppc4xx_opba_init(env, mmio, 0x600);
2407 /* Universal interrupt controller */
2408 irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
2409 irqs[PPCUIC_OUTPUT_INT] =
2410 ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_INT];
2411 irqs[PPCUIC_OUTPUT_CINT] =
2412 ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_CINT];
2413 pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
2414 *picp = pic;
2415 /* SDRAM controller */
2416 ppc405_sdram_init(env, pic[17], 1, ram_bases, ram_sizes);
2417 offset = 0;
2418 for (i = 0; i < 4; i++)
2419 offset += ram_sizes[i];
2420 /* External bus controller */
2421 ppc405_ebc_init(env);
2422 /* DMA controller */
2423 dma_irqs[0] = pic[5];
2424 dma_irqs[1] = pic[6];
2425 dma_irqs[2] = pic[7];
2426 dma_irqs[3] = pic[8];
2427 ppc405_dma_init(env, dma_irqs);
2428 /* Serial ports */
2429 if (serial_hds[0] != NULL) {
2430 ppc405_serial_init(env, mmio, 0x400, pic[0], serial_hds[0]);
2431 }
2432 if (serial_hds[1] != NULL) {
2433 ppc405_serial_init(env, mmio, 0x300, pic[1], serial_hds[1]);
2434 }
2435 /* IIC controller */
2436 ppc405_i2c_init(env, mmio, 0x500);
2437 /* GPIO */
2438 ppc405_gpio_init(env, mmio, 0x700);
2439 /* CPU control */
2440 ppc405cr_cpc_init(env, clk_setup, sysclk);
2441 *offsetp = offset;
2442
2443 return env;
2444}
2445
2446/*****************************************************************************/
2447/* PowerPC 405EP */
2448/* CPU control */
2449enum {
2450 PPC405EP_CPC0_PLLMR0 = 0x0F0,
2451 PPC405EP_CPC0_BOOT = 0x0F1,
2452 PPC405EP_CPC0_EPCTL = 0x0F3,
2453 PPC405EP_CPC0_PLLMR1 = 0x0F4,
2454 PPC405EP_CPC0_UCR = 0x0F5,
2455 PPC405EP_CPC0_SRR = 0x0F6,
2456 PPC405EP_CPC0_JTAGID = 0x0F7,
2457 PPC405EP_CPC0_PCI = 0x0F9,
2458};
2459
2460typedef struct ppc405ep_cpc_t ppc405ep_cpc_t;
2461struct ppc405ep_cpc_t {
2462 uint32_t sysclk;
2463 clk_setup_t clk_setup[8];
2464 uint32_t boot;
2465 uint32_t epctl;
2466 uint32_t pllmr[2];
2467 uint32_t ucr;
2468 uint32_t srr;
2469 uint32_t jtagid;
2470 uint32_t pci;
2471};
2472
2473static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
2474{
2475 uint32_t CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk;
2476 uint32_t UART0_clk, UART1_clk;
2477 uint64_t VCO_out, PLL_out;
2478 int M, D;
2479
2480 VCO_out = 0;
2481 if ((cpc->pllmr[1] & 0x80000000) && !(cpc->pllmr[1] & 0x40000000)) {
2482 M = (((cpc->pllmr[1] >> 20) - 1) & 0xF) + 1; /* FBMUL */
2483 // printf("FBMUL %01x %d\n", (cpc->pllmr[1] >> 20) & 0xF, M);
2484 D = 8 - ((cpc->pllmr[1] >> 16) & 0x7); /* FWDA */
2485 // printf("FWDA %01x %d\n", (cpc->pllmr[1] >> 16) & 0x7, D);
2486 VCO_out = cpc->sysclk * M * D;
2487 if (VCO_out < 500000000UL || VCO_out > 1000000000UL) {
2488 /* Error - unlock the PLL */
2489 printf("VCO out of range %" PRIu64 "\n", VCO_out);
2490#if 0
2491 cpc->pllmr[1] &= ~0x80000000;
2492 goto pll_bypass;
2493#endif
2494 }
2495 PLL_out = VCO_out / D;
2496 } else {
2497#if 0
2498 pll_bypass:
2499#endif
2500 PLL_out = cpc->sysclk;
2501 }
2502 /* Now, compute all other clocks */
2503 D = ((cpc->pllmr[0] >> 20) & 0x3) + 1; /* CCDV */
2504#ifdef DEBUG_CLOCKS
2505 // printf("CCDV %01x %d\n", (cpc->pllmr[0] >> 20) & 0x3, D);
2506#endif
2507 CPU_clk = PLL_out / D;
2508 D = ((cpc->pllmr[0] >> 16) & 0x3) + 1; /* CBDV */
2509#ifdef DEBUG_CLOCKS
2510 // printf("CBDV %01x %d\n", (cpc->pllmr[0] >> 16) & 0x3, D);
2511#endif
2512 PLB_clk = CPU_clk / D;
2513 D = ((cpc->pllmr[0] >> 12) & 0x3) + 1; /* OPDV */
2514#ifdef DEBUG_CLOCKS
2515 // printf("OPDV %01x %d\n", (cpc->pllmr[0] >> 12) & 0x3, D);
2516#endif
2517 OPB_clk = PLB_clk / D;
2518 D = ((cpc->pllmr[0] >> 8) & 0x3) + 2; /* EPDV */
2519#ifdef DEBUG_CLOCKS
2520 // printf("EPDV %01x %d\n", (cpc->pllmr[0] >> 8) & 0x3, D);
2521#endif
2522 EBC_clk = PLB_clk / D;
2523 D = ((cpc->pllmr[0] >> 4) & 0x3) + 1; /* MPDV */
2524#ifdef DEBUG_CLOCKS
2525 // printf("MPDV %01x %d\n", (cpc->pllmr[0] >> 4) & 0x3, D);
2526#endif
2527 MAL_clk = PLB_clk / D;
2528 D = (cpc->pllmr[0] & 0x3) + 1; /* PPDV */
2529#ifdef DEBUG_CLOCKS
2530 // printf("PPDV %01x %d\n", cpc->pllmr[0] & 0x3, D);
2531#endif
2532 PCI_clk = PLB_clk / D;
2533 D = ((cpc->ucr - 1) & 0x7F) + 1; /* U0DIV */
2534#ifdef DEBUG_CLOCKS
2535 // printf("U0DIV %01x %d\n", cpc->ucr & 0x7F, D);
2536#endif
2537 UART0_clk = PLL_out / D;
2538 D = (((cpc->ucr >> 8) - 1) & 0x7F) + 1; /* U1DIV */
2539#ifdef DEBUG_CLOCKS
2540 // printf("U1DIV %01x %d\n", (cpc->ucr >> 8) & 0x7F, D);
2541#endif
2542 UART1_clk = PLL_out / D;
2543#ifdef DEBUG_CLOCKS
2544 printf("Setup PPC405EP clocks - sysclk %d VCO %" PRIu64
2545 " PLL out %" PRIu64 " Hz\n", cpc->sysclk, VCO_out, PLL_out);
2546 printf("CPU %d PLB %d OPB %d EBC %d MAL %d PCI %d UART0 %d UART1 %d\n",
2547 CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk,
2548 UART0_clk, UART1_clk);
2549#endif
2550 /* Setup CPU clocks */
2551 clk_setup(&cpc->clk_setup[0], CPU_clk);
2552 /* Setup PLB clock */
2553 clk_setup(&cpc->clk_setup[1], PLB_clk);
2554 /* Setup OPB clock */
2555 clk_setup(&cpc->clk_setup[2], OPB_clk);
2556 /* Setup external clock */
2557 clk_setup(&cpc->clk_setup[3], EBC_clk);
2558 /* Setup MAL clock */
2559 clk_setup(&cpc->clk_setup[4], MAL_clk);
2560 /* Setup PCI clock */
2561 clk_setup(&cpc->clk_setup[5], PCI_clk);
2562 /* Setup UART0 clock */
2563 clk_setup(&cpc->clk_setup[6], UART0_clk);
2564 /* Setup UART1 clock */
2565 clk_setup(&cpc->clk_setup[7], UART0_clk);
2566}
2567
2568static target_ulong dcr_read_epcpc (void *opaque, int dcrn)
2569{
2570 ppc405ep_cpc_t *cpc;
2571 target_ulong ret;
2572
2573 cpc = opaque;
2574 switch (dcrn) {
2575 case PPC405EP_CPC0_BOOT:
2576 ret = cpc->boot;
2577 break;
2578 case PPC405EP_CPC0_EPCTL:
2579 ret = cpc->epctl;
2580 break;
2581 case PPC405EP_CPC0_PLLMR0:
2582 ret = cpc->pllmr[0];
2583 break;
2584 case PPC405EP_CPC0_PLLMR1:
2585 ret = cpc->pllmr[1];
2586 break;
2587 case PPC405EP_CPC0_UCR:
2588 ret = cpc->ucr;
2589 break;
2590 case PPC405EP_CPC0_SRR:
2591 ret = cpc->srr;
2592 break;
2593 case PPC405EP_CPC0_JTAGID:
2594 ret = cpc->jtagid;
2595 break;
2596 case PPC405EP_CPC0_PCI:
2597 ret = cpc->pci;
2598 break;
2599 default:
2600 /* Avoid gcc warning */
2601 ret = 0;
2602 break;
2603 }
2604
2605 return ret;
2606}
2607
2608static void dcr_write_epcpc (void *opaque, int dcrn, target_ulong val)
2609{
2610 ppc405ep_cpc_t *cpc;
2611
2612 cpc = opaque;
2613 switch (dcrn) {
2614 case PPC405EP_CPC0_BOOT:
2615 /* Read-only register */
2616 break;
2617 case PPC405EP_CPC0_EPCTL:
2618 /* Don't care for now */
2619 cpc->epctl = val & 0xC00000F3;
2620 break;
2621 case PPC405EP_CPC0_PLLMR0:
2622 cpc->pllmr[0] = val & 0x00633333;
2623 ppc405ep_compute_clocks(cpc);
2624 break;
2625 case PPC405EP_CPC0_PLLMR1:
2626 cpc->pllmr[1] = val & 0xC0F73FFF;
2627 ppc405ep_compute_clocks(cpc);
2628 break;
2629 case PPC405EP_CPC0_UCR:
2630 /* UART control - don't care for now */
2631 cpc->ucr = val & 0x003F7F7F;
2632 break;
2633 case PPC405EP_CPC0_SRR:
2634 cpc->srr = val;
2635 break;
2636 case PPC405EP_CPC0_JTAGID:
2637 /* Read-only */
2638 break;
2639 case PPC405EP_CPC0_PCI:
2640 cpc->pci = val;
2641 break;
2642 }
2643}
2644
2645static void ppc405ep_cpc_reset (void *opaque)
2646{
2647 ppc405ep_cpc_t *cpc = opaque;
2648
2649 cpc->boot = 0x00000010; /* Boot from PCI - IIC EEPROM disabled */
2650 cpc->epctl = 0x00000000;
2651 cpc->pllmr[0] = 0x00011010;
2652 cpc->pllmr[1] = 0x40000000;
2653 cpc->ucr = 0x00000000;
2654 cpc->srr = 0x00040000;
2655 cpc->pci = 0x00000000;
2656 ppc405ep_compute_clocks(cpc);
2657}
2658
2659/* XXX: sysclk should be between 25 and 100 MHz */
2660static void ppc405ep_cpc_init (CPUState *env, clk_setup_t clk_setup[8],
2661 uint32_t sysclk)
2662{
2663 ppc405ep_cpc_t *cpc;
2664
2665 cpc = qemu_mallocz(sizeof(ppc405ep_cpc_t));
2666 if (cpc != NULL) {
2667 memcpy(cpc->clk_setup, clk_setup, 7 * sizeof(clk_setup_t));
2668 cpc->jtagid = 0x20267049;
2669 cpc->sysclk = sysclk;
2670 ppc405ep_cpc_reset(cpc);
2671 qemu_register_reset(&ppc405ep_cpc_reset, cpc);
2672 ppc_dcr_register(env, PPC405EP_CPC0_BOOT, cpc,
2673 &dcr_read_epcpc, &dcr_write_epcpc);
2674 ppc_dcr_register(env, PPC405EP_CPC0_EPCTL, cpc,
2675 &dcr_read_epcpc, &dcr_write_epcpc);
2676 ppc_dcr_register(env, PPC405EP_CPC0_PLLMR0, cpc,
2677 &dcr_read_epcpc, &dcr_write_epcpc);
2678 ppc_dcr_register(env, PPC405EP_CPC0_PLLMR1, cpc,
2679 &dcr_read_epcpc, &dcr_write_epcpc);
2680 ppc_dcr_register(env, PPC405EP_CPC0_UCR, cpc,
2681 &dcr_read_epcpc, &dcr_write_epcpc);
2682 ppc_dcr_register(env, PPC405EP_CPC0_SRR, cpc,
2683 &dcr_read_epcpc, &dcr_write_epcpc);
2684 ppc_dcr_register(env, PPC405EP_CPC0_JTAGID, cpc,
2685 &dcr_read_epcpc, &dcr_write_epcpc);
2686 ppc_dcr_register(env, PPC405EP_CPC0_PCI, cpc,
2687 &dcr_read_epcpc, &dcr_write_epcpc);
2688 }
2689}
2690
2691CPUState *ppc405ep_init (target_ulong ram_bases[2], target_ulong ram_sizes[2],
2692 uint32_t sysclk, qemu_irq **picp,
2693 ram_addr_t *offsetp)
2694{
2695 clk_setup_t clk_setup[8];
2696 qemu_irq dma_irqs[4];
2697 CPUState *env;
2698 ppc4xx_mmio_t *mmio;
2699 qemu_irq *pic, *irqs;
2700 ram_addr_t offset;
2701 int i;
2702
2703 memset(clk_setup, 0, sizeof(clk_setup));
2704 /* init CPUs */
2705 env = ppc405_init("405ep", &clk_setup[0], &clk_setup[1], sysclk);
2706 /* Internal devices init */
2707 /* Memory mapped devices registers */
2708 mmio = ppc4xx_mmio_init(env, 0xEF600000);
2709 /* PLB arbitrer */
2710 ppc4xx_plb_init(env);
2711 /* PLB to OPB bridge */
2712 ppc4xx_pob_init(env);
2713 /* OBP arbitrer */
2714 ppc4xx_opba_init(env, mmio, 0x600);
2715 /* Universal interrupt controller */
2716 irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
2717 irqs[PPCUIC_OUTPUT_INT] =
2718 ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_INT];
2719 irqs[PPCUIC_OUTPUT_CINT] =
2720 ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_CINT];
2721 pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
2722 *picp = pic;
2723 /* SDRAM controller */
2724 ppc405_sdram_init(env, pic[17], 2, ram_bases, ram_sizes);
2725 offset = 0;
2726 for (i = 0; i < 2; i++)
2727 offset += ram_sizes[i];
2728 /* External bus controller */
2729 ppc405_ebc_init(env);
2730 /* DMA controller */
2731 dma_irqs[0] = pic[5];
2732 dma_irqs[1] = pic[6];
2733 dma_irqs[2] = pic[7];
2734 dma_irqs[3] = pic[8];
2735 ppc405_dma_init(env, dma_irqs);
2736 /* IIC controller */
2737 ppc405_i2c_init(env, mmio, 0x500);
2738 /* GPIO */
2739 ppc405_gpio_init(env, mmio, 0x700);
2740 /* Serial ports */
2741 if (serial_hds[0] != NULL) {
2742 ppc405_serial_init(env, mmio, 0x300, pic[0], serial_hds[0]);
2743 }
2744 if (serial_hds[1] != NULL) {
2745 ppc405_serial_init(env, mmio, 0x400, pic[1], serial_hds[1]);
2746 }
2747 /* OCM */
2748 ppc405_ocm_init(env, ram_sizes[0] + ram_sizes[1]);
2749 offset += 4096;
2750 /* PCI */
2751 /* CPU control */
2752 ppc405ep_cpc_init(env, clk_setup, sysclk);
2753 *offsetp = offset;
2754
2755 return env;
2756}