1
2
3
4
5
6
7
8
9
10
11#include "qemu/osdep.h"
12#include "qemu/units.h"
13#include "qapi/error.h"
14#include "qemu/log.h"
15#include "hw/irq.h"
16#include "hw/ppc/ppc4xx.h"
17#include "hw/qdev-properties.h"
18#include "hw/pci/pci.h"
19#include "sysemu/reset.h"
20#include "ppc440.h"
21
22
23
24
25enum {
26 DCR_L2CACHE_BASE = 0x30,
27 DCR_L2CACHE_CFG = DCR_L2CACHE_BASE,
28 DCR_L2CACHE_CMD,
29 DCR_L2CACHE_ADDR,
30 DCR_L2CACHE_DATA,
31 DCR_L2CACHE_STAT,
32 DCR_L2CACHE_CVER,
33 DCR_L2CACHE_SNP0,
34 DCR_L2CACHE_SNP1,
35 DCR_L2CACHE_END = DCR_L2CACHE_SNP1,
36};
37
38
39enum {
40 DCR_ISRAM0_BASE = 0x20,
41 DCR_ISRAM0_SB0CR = DCR_ISRAM0_BASE,
42 DCR_ISRAM0_SB1CR,
43 DCR_ISRAM0_SB2CR,
44 DCR_ISRAM0_SB3CR,
45 DCR_ISRAM0_BEAR,
46 DCR_ISRAM0_BESR0,
47 DCR_ISRAM0_BESR1,
48 DCR_ISRAM0_PMEG,
49 DCR_ISRAM0_CID,
50 DCR_ISRAM0_REVID,
51 DCR_ISRAM0_DPC,
52 DCR_ISRAM0_END = DCR_ISRAM0_DPC
53};
54
55enum {
56 DCR_ISRAM1_BASE = 0xb0,
57 DCR_ISRAM1_SB0CR = DCR_ISRAM1_BASE,
58
59 DCR_ISRAM1_BEAR = DCR_ISRAM1_BASE + 0x04,
60 DCR_ISRAM1_BESR0,
61 DCR_ISRAM1_BESR1,
62 DCR_ISRAM1_PMEG,
63 DCR_ISRAM1_CID,
64 DCR_ISRAM1_REVID,
65 DCR_ISRAM1_DPC,
66 DCR_ISRAM1_END = DCR_ISRAM1_DPC
67};
68
69typedef struct ppc4xx_l2sram_t {
70 MemoryRegion bank[4];
71 uint32_t l2cache[8];
72 uint32_t isram0[11];
73} ppc4xx_l2sram_t;
74
75#ifdef MAP_L2SRAM
76static void l2sram_update_mappings(ppc4xx_l2sram_t *l2sram,
77 uint32_t isarc, uint32_t isacntl,
78 uint32_t dsarc, uint32_t dsacntl)
79{
80 if (l2sram->isarc != isarc ||
81 (l2sram->isacntl & 0x80000000) != (isacntl & 0x80000000)) {
82 if (l2sram->isacntl & 0x80000000) {
83
84 memory_region_del_subregion(get_system_memory(),
85 &l2sram->isarc_ram);
86 }
87 if (isacntl & 0x80000000) {
88
89 memory_region_add_subregion(get_system_memory(), isarc,
90 &l2sram->isarc_ram);
91 }
92 }
93 if (l2sram->dsarc != dsarc ||
94 (l2sram->dsacntl & 0x80000000) != (dsacntl & 0x80000000)) {
95 if (l2sram->dsacntl & 0x80000000) {
96
97 if (!(isacntl & 0x80000000) || l2sram->dsarc != isarc) {
98
99 memory_region_del_subregion(get_system_memory(),
100 &l2sram->dsarc_ram);
101 }
102 }
103 if (dsacntl & 0x80000000) {
104
105 if (!(isacntl & 0x80000000) || dsarc != isarc) {
106
107 memory_region_add_subregion(get_system_memory(), dsarc,
108 &l2sram->dsarc_ram);
109 }
110 }
111 }
112}
113#endif
114
115static uint32_t dcr_read_l2sram(void *opaque, int dcrn)
116{
117 ppc4xx_l2sram_t *l2sram = opaque;
118 uint32_t ret = 0;
119
120 switch (dcrn) {
121 case DCR_L2CACHE_CFG:
122 case DCR_L2CACHE_CMD:
123 case DCR_L2CACHE_ADDR:
124 case DCR_L2CACHE_DATA:
125 case DCR_L2CACHE_STAT:
126 case DCR_L2CACHE_CVER:
127 case DCR_L2CACHE_SNP0:
128 case DCR_L2CACHE_SNP1:
129 ret = l2sram->l2cache[dcrn - DCR_L2CACHE_BASE];
130 break;
131
132 case DCR_ISRAM0_SB0CR:
133 case DCR_ISRAM0_SB1CR:
134 case DCR_ISRAM0_SB2CR:
135 case DCR_ISRAM0_SB3CR:
136 case DCR_ISRAM0_BEAR:
137 case DCR_ISRAM0_BESR0:
138 case DCR_ISRAM0_BESR1:
139 case DCR_ISRAM0_PMEG:
140 case DCR_ISRAM0_CID:
141 case DCR_ISRAM0_REVID:
142 case DCR_ISRAM0_DPC:
143 ret = l2sram->isram0[dcrn - DCR_ISRAM0_BASE];
144 break;
145
146 default:
147 break;
148 }
149
150 return ret;
151}
152
153static void dcr_write_l2sram(void *opaque, int dcrn, uint32_t val)
154{
155
156
157
158 switch (dcrn) {
159 case DCR_L2CACHE_CFG:
160 case DCR_L2CACHE_CMD:
161 case DCR_L2CACHE_ADDR:
162 case DCR_L2CACHE_DATA:
163 case DCR_L2CACHE_STAT:
164 case DCR_L2CACHE_CVER:
165 case DCR_L2CACHE_SNP0:
166 case DCR_L2CACHE_SNP1:
167
168 break;
169
170 case DCR_ISRAM0_SB0CR:
171 case DCR_ISRAM0_SB1CR:
172 case DCR_ISRAM0_SB2CR:
173 case DCR_ISRAM0_SB3CR:
174 case DCR_ISRAM0_BEAR:
175 case DCR_ISRAM0_BESR0:
176 case DCR_ISRAM0_BESR1:
177 case DCR_ISRAM0_PMEG:
178 case DCR_ISRAM0_CID:
179 case DCR_ISRAM0_REVID:
180 case DCR_ISRAM0_DPC:
181
182 break;
183
184 case DCR_ISRAM1_SB0CR:
185 case DCR_ISRAM1_BEAR:
186 case DCR_ISRAM1_BESR0:
187 case DCR_ISRAM1_BESR1:
188 case DCR_ISRAM1_PMEG:
189 case DCR_ISRAM1_CID:
190 case DCR_ISRAM1_REVID:
191 case DCR_ISRAM1_DPC:
192
193 break;
194 }
195
196}
197
198static void l2sram_reset(void *opaque)
199{
200 ppc4xx_l2sram_t *l2sram = opaque;
201
202 memset(l2sram->l2cache, 0, sizeof(l2sram->l2cache));
203 l2sram->l2cache[DCR_L2CACHE_STAT - DCR_L2CACHE_BASE] = 0x80000000;
204 memset(l2sram->isram0, 0, sizeof(l2sram->isram0));
205
206}
207
208void ppc4xx_l2sram_init(CPUPPCState *env)
209{
210 ppc4xx_l2sram_t *l2sram;
211
212 l2sram = g_malloc0(sizeof(*l2sram));
213
214 memory_region_init_ram(&l2sram->bank[0], NULL, "ppc4xx.l2sram_bank0",
215 64 * KiB, &error_abort);
216 memory_region_init_ram(&l2sram->bank[1], NULL, "ppc4xx.l2sram_bank1",
217 64 * KiB, &error_abort);
218 memory_region_init_ram(&l2sram->bank[2], NULL, "ppc4xx.l2sram_bank2",
219 64 * KiB, &error_abort);
220 memory_region_init_ram(&l2sram->bank[3], NULL, "ppc4xx.l2sram_bank3",
221 64 * KiB, &error_abort);
222 qemu_register_reset(&l2sram_reset, l2sram);
223 ppc_dcr_register(env, DCR_L2CACHE_CFG,
224 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
225 ppc_dcr_register(env, DCR_L2CACHE_CMD,
226 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
227 ppc_dcr_register(env, DCR_L2CACHE_ADDR,
228 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
229 ppc_dcr_register(env, DCR_L2CACHE_DATA,
230 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
231 ppc_dcr_register(env, DCR_L2CACHE_STAT,
232 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
233 ppc_dcr_register(env, DCR_L2CACHE_CVER,
234 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
235 ppc_dcr_register(env, DCR_L2CACHE_SNP0,
236 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
237 ppc_dcr_register(env, DCR_L2CACHE_SNP1,
238 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
239
240 ppc_dcr_register(env, DCR_ISRAM0_SB0CR,
241 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
242 ppc_dcr_register(env, DCR_ISRAM0_SB1CR,
243 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
244 ppc_dcr_register(env, DCR_ISRAM0_SB2CR,
245 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
246 ppc_dcr_register(env, DCR_ISRAM0_SB3CR,
247 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
248 ppc_dcr_register(env, DCR_ISRAM0_PMEG,
249 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
250 ppc_dcr_register(env, DCR_ISRAM0_DPC,
251 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
252
253 ppc_dcr_register(env, DCR_ISRAM1_SB0CR,
254 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
255 ppc_dcr_register(env, DCR_ISRAM1_PMEG,
256 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
257 ppc_dcr_register(env, DCR_ISRAM1_DPC,
258 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
259}
260
261
262
263enum {
264 CPR0_CFGADDR = 0xC,
265 CPR0_CFGDATA = 0xD,
266
267 CPR0_PLLD = 0x060,
268 CPR0_PLBED = 0x080,
269 CPR0_OPBD = 0x0C0,
270 CPR0_PERD = 0x0E0,
271 CPR0_AHBD = 0x100,
272};
273
274typedef struct ppc4xx_cpr_t {
275 uint32_t addr;
276} ppc4xx_cpr_t;
277
278static uint32_t dcr_read_cpr(void *opaque, int dcrn)
279{
280 ppc4xx_cpr_t *cpr = opaque;
281 uint32_t ret = 0;
282
283 switch (dcrn) {
284 case CPR0_CFGADDR:
285 ret = cpr->addr;
286 break;
287 case CPR0_CFGDATA:
288 switch (cpr->addr) {
289 case CPR0_PLLD:
290 ret = (0xb5 << 24) | (1 << 16) | (9 << 8);
291 break;
292 case CPR0_PLBED:
293 ret = (5 << 24);
294 break;
295 case CPR0_OPBD:
296 ret = (2 << 24);
297 break;
298 case CPR0_PERD:
299 case CPR0_AHBD:
300 ret = (1 << 24);
301 break;
302 default:
303 break;
304 }
305 break;
306 default:
307 break;
308 }
309
310 return ret;
311}
312
313static void dcr_write_cpr(void *opaque, int dcrn, uint32_t val)
314{
315 ppc4xx_cpr_t *cpr = opaque;
316
317 switch (dcrn) {
318 case CPR0_CFGADDR:
319 cpr->addr = val;
320 break;
321 case CPR0_CFGDATA:
322 break;
323 default:
324 break;
325 }
326}
327
328static void ppc4xx_cpr_reset(void *opaque)
329{
330 ppc4xx_cpr_t *cpr = opaque;
331
332 cpr->addr = 0;
333}
334
335void ppc4xx_cpr_init(CPUPPCState *env)
336{
337 ppc4xx_cpr_t *cpr;
338
339 cpr = g_malloc0(sizeof(*cpr));
340 ppc_dcr_register(env, CPR0_CFGADDR, cpr, &dcr_read_cpr, &dcr_write_cpr);
341 ppc_dcr_register(env, CPR0_CFGDATA, cpr, &dcr_read_cpr, &dcr_write_cpr);
342 qemu_register_reset(ppc4xx_cpr_reset, cpr);
343}
344
345
346
347typedef struct ppc4xx_sdr_t ppc4xx_sdr_t;
348struct ppc4xx_sdr_t {
349 uint32_t addr;
350};
351
352enum {
353 SDR0_CFGADDR = 0x00e,
354 SDR0_CFGDATA,
355 SDR0_STRP0 = 0x020,
356 SDR0_STRP1,
357 SDR0_102 = 0x66,
358 SDR0_103,
359 SDR0_128 = 0x80,
360 SDR0_ECID3 = 0x083,
361 SDR0_DDR0 = 0x0e1,
362 SDR0_USB0 = 0x320,
363};
364
365enum {
366 PESDR0_LOOP = 0x303,
367 PESDR0_RCSSET,
368 PESDR0_RCSSTS,
369 PESDR0_RSTSTA = 0x310,
370 PESDR1_LOOP = 0x343,
371 PESDR1_RCSSET,
372 PESDR1_RCSSTS,
373 PESDR1_RSTSTA = 0x365,
374};
375
376static uint32_t dcr_read_sdr(void *opaque, int dcrn)
377{
378 ppc4xx_sdr_t *sdr = opaque;
379 uint32_t ret = 0;
380
381 switch (dcrn) {
382 case SDR0_CFGADDR:
383 ret = sdr->addr;
384 break;
385 case SDR0_CFGDATA:
386 switch (sdr->addr) {
387 case SDR0_STRP0:
388 ret = (0xb5 << 8) | (1 << 4) | 9;
389 break;
390 case SDR0_STRP1:
391 ret = (5 << 29) | (2 << 26) | (1 << 24);
392 break;
393 case SDR0_ECID3:
394 ret = 1 << 20;
395 break;
396 case SDR0_DDR0:
397 ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
398 break;
399 case PESDR0_RCSSET:
400 case PESDR1_RCSSET:
401 ret = (1 << 24) | (1 << 16);
402 break;
403 case PESDR0_RCSSTS:
404 case PESDR1_RCSSTS:
405 ret = (1 << 16) | (1 << 12);
406 break;
407 case PESDR0_RSTSTA:
408 case PESDR1_RSTSTA:
409 ret = 1;
410 break;
411 case PESDR0_LOOP:
412 case PESDR1_LOOP:
413 ret = 1 << 12;
414 break;
415 default:
416 break;
417 }
418 break;
419 default:
420 break;
421 }
422
423 return ret;
424}
425
426static void dcr_write_sdr(void *opaque, int dcrn, uint32_t val)
427{
428 ppc4xx_sdr_t *sdr = opaque;
429
430 switch (dcrn) {
431 case SDR0_CFGADDR:
432 sdr->addr = val;
433 break;
434 case SDR0_CFGDATA:
435 switch (sdr->addr) {
436 case 0x00:
437 break;
438 default:
439 break;
440 }
441 break;
442 default:
443 break;
444 }
445}
446
447static void sdr_reset(void *opaque)
448{
449 ppc4xx_sdr_t *sdr = opaque;
450
451 sdr->addr = 0;
452}
453
454void ppc4xx_sdr_init(CPUPPCState *env)
455{
456 ppc4xx_sdr_t *sdr;
457
458 sdr = g_malloc0(sizeof(*sdr));
459 qemu_register_reset(&sdr_reset, sdr);
460 ppc_dcr_register(env, SDR0_CFGADDR,
461 sdr, &dcr_read_sdr, &dcr_write_sdr);
462 ppc_dcr_register(env, SDR0_CFGDATA,
463 sdr, &dcr_read_sdr, &dcr_write_sdr);
464 ppc_dcr_register(env, SDR0_102,
465 sdr, &dcr_read_sdr, &dcr_write_sdr);
466 ppc_dcr_register(env, SDR0_103,
467 sdr, &dcr_read_sdr, &dcr_write_sdr);
468 ppc_dcr_register(env, SDR0_128,
469 sdr, &dcr_read_sdr, &dcr_write_sdr);
470 ppc_dcr_register(env, SDR0_USB0,
471 sdr, &dcr_read_sdr, &dcr_write_sdr);
472}
473
474
475
476enum {
477 AHB_TOP = 0xA4,
478 AHB_BOT = 0xA5,
479};
480
481typedef struct ppc4xx_ahb_t {
482 uint32_t top;
483 uint32_t bot;
484} ppc4xx_ahb_t;
485
486static uint32_t dcr_read_ahb(void *opaque, int dcrn)
487{
488 ppc4xx_ahb_t *ahb = opaque;
489 uint32_t ret = 0;
490
491 switch (dcrn) {
492 case AHB_TOP:
493 ret = ahb->top;
494 break;
495 case AHB_BOT:
496 ret = ahb->bot;
497 break;
498 default:
499 break;
500 }
501
502 return ret;
503}
504
505static void dcr_write_ahb(void *opaque, int dcrn, uint32_t val)
506{
507 ppc4xx_ahb_t *ahb = opaque;
508
509 switch (dcrn) {
510 case AHB_TOP:
511 ahb->top = val;
512 break;
513 case AHB_BOT:
514 ahb->bot = val;
515 break;
516 }
517}
518
519static void ppc4xx_ahb_reset(void *opaque)
520{
521 ppc4xx_ahb_t *ahb = opaque;
522
523
524 ahb->top = 0;
525 ahb->bot = 0;
526}
527
528void ppc4xx_ahb_init(CPUPPCState *env)
529{
530 ppc4xx_ahb_t *ahb;
531
532 ahb = g_malloc0(sizeof(*ahb));
533 ppc_dcr_register(env, AHB_TOP, ahb, &dcr_read_ahb, &dcr_write_ahb);
534 ppc_dcr_register(env, AHB_BOT, ahb, &dcr_read_ahb, &dcr_write_ahb);
535 qemu_register_reset(ppc4xx_ahb_reset, ahb);
536}
537
538
539
540
541#define DMA0_CR_CE (1 << 31)
542#define DMA0_CR_PW (1 << 26 | 1 << 25)
543#define DMA0_CR_DAI (1 << 24)
544#define DMA0_CR_SAI (1 << 23)
545#define DMA0_CR_DEC (1 << 2)
546
547enum {
548 DMA0_CR = 0x00,
549 DMA0_CT,
550 DMA0_SAH,
551 DMA0_SAL,
552 DMA0_DAH,
553 DMA0_DAL,
554 DMA0_SGH,
555 DMA0_SGL,
556
557 DMA0_SR = 0x20,
558 DMA0_SGC = 0x23,
559 DMA0_SLP = 0x25,
560 DMA0_POL = 0x26,
561};
562
563typedef struct {
564 uint32_t cr;
565 uint32_t ct;
566 uint64_t sa;
567 uint64_t da;
568 uint64_t sg;
569} PPC4xxDmaChnl;
570
571typedef struct {
572 int base;
573 PPC4xxDmaChnl ch[4];
574 uint32_t sr;
575} PPC4xxDmaState;
576
577static uint32_t dcr_read_dma(void *opaque, int dcrn)
578{
579 PPC4xxDmaState *dma = opaque;
580 uint32_t val = 0;
581 int addr = dcrn - dma->base;
582 int chnl = addr / 8;
583
584 switch (addr) {
585 case 0x00 ... 0x1f:
586 switch (addr % 8) {
587 case DMA0_CR:
588 val = dma->ch[chnl].cr;
589 break;
590 case DMA0_CT:
591 val = dma->ch[chnl].ct;
592 break;
593 case DMA0_SAH:
594 val = dma->ch[chnl].sa >> 32;
595 break;
596 case DMA0_SAL:
597 val = dma->ch[chnl].sa;
598 break;
599 case DMA0_DAH:
600 val = dma->ch[chnl].da >> 32;
601 break;
602 case DMA0_DAL:
603 val = dma->ch[chnl].da;
604 break;
605 case DMA0_SGH:
606 val = dma->ch[chnl].sg >> 32;
607 break;
608 case DMA0_SGL:
609 val = dma->ch[chnl].sg;
610 break;
611 }
612 break;
613 case DMA0_SR:
614 val = dma->sr;
615 break;
616 default:
617 qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
618 __func__, dcrn, chnl, addr);
619 }
620
621 return val;
622}
623
624static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
625{
626 PPC4xxDmaState *dma = opaque;
627 int addr = dcrn - dma->base;
628 int chnl = addr / 8;
629
630 switch (addr) {
631 case 0x00 ... 0x1f:
632 switch (addr % 8) {
633 case DMA0_CR:
634 dma->ch[chnl].cr = val;
635 if (val & DMA0_CR_CE) {
636 int count = dma->ch[chnl].ct & 0xffff;
637
638 if (count) {
639 int width, i, sidx, didx;
640 uint8_t *rptr, *wptr;
641 hwaddr rlen, wlen;
642 hwaddr xferlen;
643
644 sidx = didx = 0;
645 width = 1 << ((val & DMA0_CR_PW) >> 25);
646 xferlen = count * width;
647 wlen = rlen = xferlen;
648 rptr = cpu_physical_memory_map(dma->ch[chnl].sa, &rlen,
649 false);
650 wptr = cpu_physical_memory_map(dma->ch[chnl].da, &wlen,
651 true);
652 if (rptr && rlen == xferlen && wptr && wlen == xferlen) {
653 if (!(val & DMA0_CR_DEC) &&
654 val & DMA0_CR_SAI && val & DMA0_CR_DAI) {
655
656 memmove(wptr, rptr, count * width);
657 sidx = didx = count * width;
658 } else {
659
660 for (sidx = didx = i = 0; i < count; i++) {
661 uint64_t v = ldn_le_p(rptr + sidx, width);
662 stn_le_p(wptr + didx, width, v);
663 if (val & DMA0_CR_SAI) {
664 sidx += width;
665 }
666 if (val & DMA0_CR_DAI) {
667 didx += width;
668 }
669 }
670 }
671 }
672 if (wptr) {
673 cpu_physical_memory_unmap(wptr, wlen, 1, didx);
674 }
675 if (rptr) {
676 cpu_physical_memory_unmap(rptr, rlen, 0, sidx);
677 }
678 }
679 }
680 break;
681 case DMA0_CT:
682 dma->ch[chnl].ct = val;
683 break;
684 case DMA0_SAH:
685 dma->ch[chnl].sa &= 0xffffffffULL;
686 dma->ch[chnl].sa |= (uint64_t)val << 32;
687 break;
688 case DMA0_SAL:
689 dma->ch[chnl].sa &= 0xffffffff00000000ULL;
690 dma->ch[chnl].sa |= val;
691 break;
692 case DMA0_DAH:
693 dma->ch[chnl].da &= 0xffffffffULL;
694 dma->ch[chnl].da |= (uint64_t)val << 32;
695 break;
696 case DMA0_DAL:
697 dma->ch[chnl].da &= 0xffffffff00000000ULL;
698 dma->ch[chnl].da |= val;
699 break;
700 case DMA0_SGH:
701 dma->ch[chnl].sg &= 0xffffffffULL;
702 dma->ch[chnl].sg |= (uint64_t)val << 32;
703 break;
704 case DMA0_SGL:
705 dma->ch[chnl].sg &= 0xffffffff00000000ULL;
706 dma->ch[chnl].sg |= val;
707 break;
708 }
709 break;
710 case DMA0_SR:
711 dma->sr &= ~val;
712 break;
713 default:
714 qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
715 __func__, dcrn, chnl, addr);
716 }
717}
718
719static void ppc4xx_dma_reset(void *opaque)
720{
721 PPC4xxDmaState *dma = opaque;
722 int dma_base = dma->base;
723
724 memset(dma, 0, sizeof(*dma));
725 dma->base = dma_base;
726}
727
728void ppc4xx_dma_init(CPUPPCState *env, int dcr_base)
729{
730 PPC4xxDmaState *dma;
731 int i;
732
733 dma = g_malloc0(sizeof(*dma));
734 dma->base = dcr_base;
735 qemu_register_reset(&ppc4xx_dma_reset, dma);
736 for (i = 0; i < 4; i++) {
737 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CR,
738 dma, &dcr_read_dma, &dcr_write_dma);
739 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CT,
740 dma, &dcr_read_dma, &dcr_write_dma);
741 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAH,
742 dma, &dcr_read_dma, &dcr_write_dma);
743 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAL,
744 dma, &dcr_read_dma, &dcr_write_dma);
745 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAH,
746 dma, &dcr_read_dma, &dcr_write_dma);
747 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAL,
748 dma, &dcr_read_dma, &dcr_write_dma);
749 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGH,
750 dma, &dcr_read_dma, &dcr_write_dma);
751 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGL,
752 dma, &dcr_read_dma, &dcr_write_dma);
753 }
754 ppc_dcr_register(env, dcr_base + DMA0_SR,
755 dma, &dcr_read_dma, &dcr_write_dma);
756 ppc_dcr_register(env, dcr_base + DMA0_SGC,
757 dma, &dcr_read_dma, &dcr_write_dma);
758 ppc_dcr_register(env, dcr_base + DMA0_SLP,
759 dma, &dcr_read_dma, &dcr_write_dma);
760 ppc_dcr_register(env, dcr_base + DMA0_POL,
761 dma, &dcr_read_dma, &dcr_write_dma);
762}
763
764
765
766
767
768
769
770#include "hw/pci/pcie_host.h"
771
772#define TYPE_PPC460EX_PCIE_HOST "ppc460ex-pcie-host"
773OBJECT_DECLARE_SIMPLE_TYPE(PPC460EXPCIEState, PPC460EX_PCIE_HOST)
774
775struct PPC460EXPCIEState {
776 PCIExpressHost host;
777
778 MemoryRegion iomem;
779 qemu_irq irq[4];
780 int32_t dcrn_base;
781
782 uint64_t cfg_base;
783 uint32_t cfg_mask;
784 uint64_t msg_base;
785 uint32_t msg_mask;
786 uint64_t omr1_base;
787 uint64_t omr1_mask;
788 uint64_t omr2_base;
789 uint64_t omr2_mask;
790 uint64_t omr3_base;
791 uint64_t omr3_mask;
792 uint64_t reg_base;
793 uint32_t reg_mask;
794 uint32_t special;
795 uint32_t cfg;
796};
797
798#define DCRN_PCIE0_BASE 0x100
799#define DCRN_PCIE1_BASE 0x120
800
801enum {
802 PEGPL_CFGBAH = 0x0,
803 PEGPL_CFGBAL,
804 PEGPL_CFGMSK,
805 PEGPL_MSGBAH,
806 PEGPL_MSGBAL,
807 PEGPL_MSGMSK,
808 PEGPL_OMR1BAH,
809 PEGPL_OMR1BAL,
810 PEGPL_OMR1MSKH,
811 PEGPL_OMR1MSKL,
812 PEGPL_OMR2BAH,
813 PEGPL_OMR2BAL,
814 PEGPL_OMR2MSKH,
815 PEGPL_OMR2MSKL,
816 PEGPL_OMR3BAH,
817 PEGPL_OMR3BAL,
818 PEGPL_OMR3MSKH,
819 PEGPL_OMR3MSKL,
820 PEGPL_REGBAH,
821 PEGPL_REGBAL,
822 PEGPL_REGMSK,
823 PEGPL_SPECIAL,
824 PEGPL_CFG,
825};
826
827static uint32_t dcr_read_pcie(void *opaque, int dcrn)
828{
829 PPC460EXPCIEState *state = opaque;
830 uint32_t ret = 0;
831
832 switch (dcrn - state->dcrn_base) {
833 case PEGPL_CFGBAH:
834 ret = state->cfg_base >> 32;
835 break;
836 case PEGPL_CFGBAL:
837 ret = state->cfg_base;
838 break;
839 case PEGPL_CFGMSK:
840 ret = state->cfg_mask;
841 break;
842 case PEGPL_MSGBAH:
843 ret = state->msg_base >> 32;
844 break;
845 case PEGPL_MSGBAL:
846 ret = state->msg_base;
847 break;
848 case PEGPL_MSGMSK:
849 ret = state->msg_mask;
850 break;
851 case PEGPL_OMR1BAH:
852 ret = state->omr1_base >> 32;
853 break;
854 case PEGPL_OMR1BAL:
855 ret = state->omr1_base;
856 break;
857 case PEGPL_OMR1MSKH:
858 ret = state->omr1_mask >> 32;
859 break;
860 case PEGPL_OMR1MSKL:
861 ret = state->omr1_mask;
862 break;
863 case PEGPL_OMR2BAH:
864 ret = state->omr2_base >> 32;
865 break;
866 case PEGPL_OMR2BAL:
867 ret = state->omr2_base;
868 break;
869 case PEGPL_OMR2MSKH:
870 ret = state->omr2_mask >> 32;
871 break;
872 case PEGPL_OMR2MSKL:
873 ret = state->omr3_mask;
874 break;
875 case PEGPL_OMR3BAH:
876 ret = state->omr3_base >> 32;
877 break;
878 case PEGPL_OMR3BAL:
879 ret = state->omr3_base;
880 break;
881 case PEGPL_OMR3MSKH:
882 ret = state->omr3_mask >> 32;
883 break;
884 case PEGPL_OMR3MSKL:
885 ret = state->omr3_mask;
886 break;
887 case PEGPL_REGBAH:
888 ret = state->reg_base >> 32;
889 break;
890 case PEGPL_REGBAL:
891 ret = state->reg_base;
892 break;
893 case PEGPL_REGMSK:
894 ret = state->reg_mask;
895 break;
896 case PEGPL_SPECIAL:
897 ret = state->special;
898 break;
899 case PEGPL_CFG:
900 ret = state->cfg;
901 break;
902 }
903
904 return ret;
905}
906
907static void dcr_write_pcie(void *opaque, int dcrn, uint32_t val)
908{
909 PPC460EXPCIEState *s = opaque;
910 uint64_t size;
911
912 switch (dcrn - s->dcrn_base) {
913 case PEGPL_CFGBAH:
914 s->cfg_base = ((uint64_t)val << 32) | (s->cfg_base & 0xffffffff);
915 break;
916 case PEGPL_CFGBAL:
917 s->cfg_base = (s->cfg_base & 0xffffffff00000000ULL) | val;
918 break;
919 case PEGPL_CFGMSK:
920 s->cfg_mask = val;
921 size = ~(val & 0xfffffffe) + 1;
922
923
924
925
926
927 if (size > PCIE_MMCFG_SIZE_MAX) {
928 size = PCIE_MMCFG_SIZE_MAX;
929 }
930 pcie_host_mmcfg_update(PCIE_HOST_BRIDGE(s), val & 1, s->cfg_base, size);
931 break;
932 case PEGPL_MSGBAH:
933 s->msg_base = ((uint64_t)val << 32) | (s->msg_base & 0xffffffff);
934 break;
935 case PEGPL_MSGBAL:
936 s->msg_base = (s->msg_base & 0xffffffff00000000ULL) | val;
937 break;
938 case PEGPL_MSGMSK:
939 s->msg_mask = val;
940 break;
941 case PEGPL_OMR1BAH:
942 s->omr1_base = ((uint64_t)val << 32) | (s->omr1_base & 0xffffffff);
943 break;
944 case PEGPL_OMR1BAL:
945 s->omr1_base = (s->omr1_base & 0xffffffff00000000ULL) | val;
946 break;
947 case PEGPL_OMR1MSKH:
948 s->omr1_mask = ((uint64_t)val << 32) | (s->omr1_mask & 0xffffffff);
949 break;
950 case PEGPL_OMR1MSKL:
951 s->omr1_mask = (s->omr1_mask & 0xffffffff00000000ULL) | val;
952 break;
953 case PEGPL_OMR2BAH:
954 s->omr2_base = ((uint64_t)val << 32) | (s->omr2_base & 0xffffffff);
955 break;
956 case PEGPL_OMR2BAL:
957 s->omr2_base = (s->omr2_base & 0xffffffff00000000ULL) | val;
958 break;
959 case PEGPL_OMR2MSKH:
960 s->omr2_mask = ((uint64_t)val << 32) | (s->omr2_mask & 0xffffffff);
961 break;
962 case PEGPL_OMR2MSKL:
963 s->omr2_mask = (s->omr2_mask & 0xffffffff00000000ULL) | val;
964 break;
965 case PEGPL_OMR3BAH:
966 s->omr3_base = ((uint64_t)val << 32) | (s->omr3_base & 0xffffffff);
967 break;
968 case PEGPL_OMR3BAL:
969 s->omr3_base = (s->omr3_base & 0xffffffff00000000ULL) | val;
970 break;
971 case PEGPL_OMR3MSKH:
972 s->omr3_mask = ((uint64_t)val << 32) | (s->omr3_mask & 0xffffffff);
973 break;
974 case PEGPL_OMR3MSKL:
975 s->omr3_mask = (s->omr3_mask & 0xffffffff00000000ULL) | val;
976 break;
977 case PEGPL_REGBAH:
978 s->reg_base = ((uint64_t)val << 32) | (s->reg_base & 0xffffffff);
979 break;
980 case PEGPL_REGBAL:
981 s->reg_base = (s->reg_base & 0xffffffff00000000ULL) | val;
982 break;
983 case PEGPL_REGMSK:
984 s->reg_mask = val;
985
986 size = (val == 0x7001 ? 4096 : ~(val & 0xfffffffe) + 1);
987 break;
988 case PEGPL_SPECIAL:
989 s->special = val;
990 break;
991 case PEGPL_CFG:
992 s->cfg = val;
993 break;
994 }
995}
996
997static void ppc460ex_set_irq(void *opaque, int irq_num, int level)
998{
999 PPC460EXPCIEState *s = opaque;
1000 qemu_set_irq(s->irq[irq_num], level);
1001}
1002
1003static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp)
1004{
1005 PPC460EXPCIEState *s = PPC460EX_PCIE_HOST(dev);
1006 PCIHostState *pci = PCI_HOST_BRIDGE(dev);
1007 int i, id;
1008 char buf[16];
1009
1010 switch (s->dcrn_base) {
1011 case DCRN_PCIE0_BASE:
1012 id = 0;
1013 break;
1014 case DCRN_PCIE1_BASE:
1015 id = 1;
1016 break;
1017 default:
1018 error_setg(errp, "invalid PCIe DCRN base");
1019 return;
1020 }
1021 snprintf(buf, sizeof(buf), "pcie%d-io", id);
1022 memory_region_init(&s->iomem, OBJECT(s), buf, UINT64_MAX);
1023 for (i = 0; i < 4; i++) {
1024 sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
1025 }
1026 snprintf(buf, sizeof(buf), "pcie.%d", id);
1027 pci->bus = pci_register_root_bus(DEVICE(s), buf, ppc460ex_set_irq,
1028 pci_swizzle_map_irq_fn, s, &s->iomem,
1029 get_system_io(), 0, 4, TYPE_PCIE_BUS);
1030}
1031
1032static Property ppc460ex_pcie_props[] = {
1033 DEFINE_PROP_INT32("dcrn-base", PPC460EXPCIEState, dcrn_base, -1),
1034 DEFINE_PROP_END_OF_LIST(),
1035};
1036
1037static void ppc460ex_pcie_class_init(ObjectClass *klass, void *data)
1038{
1039 DeviceClass *dc = DEVICE_CLASS(klass);
1040
1041 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
1042 dc->realize = ppc460ex_pcie_realize;
1043 device_class_set_props(dc, ppc460ex_pcie_props);
1044 dc->hotpluggable = false;
1045}
1046
1047static const TypeInfo ppc460ex_pcie_host_info = {
1048 .name = TYPE_PPC460EX_PCIE_HOST,
1049 .parent = TYPE_PCIE_HOST_BRIDGE,
1050 .instance_size = sizeof(PPC460EXPCIEState),
1051 .class_init = ppc460ex_pcie_class_init,
1052};
1053
1054static void ppc460ex_pcie_register(void)
1055{
1056 type_register_static(&ppc460ex_pcie_host_info);
1057}
1058
1059type_init(ppc460ex_pcie_register)
1060
1061static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s, CPUPPCState *env)
1062{
1063 ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAH, s,
1064 &dcr_read_pcie, &dcr_write_pcie);
1065 ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAL, s,
1066 &dcr_read_pcie, &dcr_write_pcie);
1067 ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGMSK, s,
1068 &dcr_read_pcie, &dcr_write_pcie);
1069 ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAH, s,
1070 &dcr_read_pcie, &dcr_write_pcie);
1071 ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAL, s,
1072 &dcr_read_pcie, &dcr_write_pcie);
1073 ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGMSK, s,
1074 &dcr_read_pcie, &dcr_write_pcie);
1075 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAH, s,
1076 &dcr_read_pcie, &dcr_write_pcie);
1077 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAL, s,
1078 &dcr_read_pcie, &dcr_write_pcie);
1079 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKH, s,
1080 &dcr_read_pcie, &dcr_write_pcie);
1081 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKL, s,
1082 &dcr_read_pcie, &dcr_write_pcie);
1083 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAH, s,
1084 &dcr_read_pcie, &dcr_write_pcie);
1085 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAL, s,
1086 &dcr_read_pcie, &dcr_write_pcie);
1087 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKH, s,
1088 &dcr_read_pcie, &dcr_write_pcie);
1089 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKL, s,
1090 &dcr_read_pcie, &dcr_write_pcie);
1091 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAH, s,
1092 &dcr_read_pcie, &dcr_write_pcie);
1093 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAL, s,
1094 &dcr_read_pcie, &dcr_write_pcie);
1095 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKH, s,
1096 &dcr_read_pcie, &dcr_write_pcie);
1097 ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKL, s,
1098 &dcr_read_pcie, &dcr_write_pcie);
1099 ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAH, s,
1100 &dcr_read_pcie, &dcr_write_pcie);
1101 ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAL, s,
1102 &dcr_read_pcie, &dcr_write_pcie);
1103 ppc_dcr_register(env, s->dcrn_base + PEGPL_REGMSK, s,
1104 &dcr_read_pcie, &dcr_write_pcie);
1105 ppc_dcr_register(env, s->dcrn_base + PEGPL_SPECIAL, s,
1106 &dcr_read_pcie, &dcr_write_pcie);
1107 ppc_dcr_register(env, s->dcrn_base + PEGPL_CFG, s,
1108 &dcr_read_pcie, &dcr_write_pcie);
1109}
1110
1111void ppc460ex_pcie_init(CPUPPCState *env)
1112{
1113 DeviceState *dev;
1114
1115 dev = qdev_new(TYPE_PPC460EX_PCIE_HOST);
1116 qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE0_BASE);
1117 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1118 ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
1119
1120 dev = qdev_new(TYPE_PPC460EX_PCIE_HOST);
1121 qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE1_BASE);
1122 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1123 ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env);
1124}
1125