target/i386: avoid trunc and ext for MULX and RORX
[qemu/ar7.git] / hw / ppc / ppc440_uc.c
blob7d6ca7038751be1dd7b3bc2206491d23ea854c8f
1 /*
2 * QEMU PowerPC 440 embedded processors emulation
4 * Copyright (c) 2012 François Revol
5 * Copyright (c) 2016-2019 BALATON Zoltan
7 * This work is licensed under the GNU GPL license version 2 or later.
9 */
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 "cpu.h"
21 #include "ppc440.h"
23 /*****************************************************************************/
24 /* L2 Cache as SRAM */
25 /* FIXME:fix names */
26 enum {
27 DCR_L2CACHE_BASE = 0x30,
28 DCR_L2CACHE_CFG = DCR_L2CACHE_BASE,
29 DCR_L2CACHE_CMD,
30 DCR_L2CACHE_ADDR,
31 DCR_L2CACHE_DATA,
32 DCR_L2CACHE_STAT,
33 DCR_L2CACHE_CVER,
34 DCR_L2CACHE_SNP0,
35 DCR_L2CACHE_SNP1,
36 DCR_L2CACHE_END = DCR_L2CACHE_SNP1,
39 /* base is 460ex-specific, cf. U-Boot, ppc4xx-isram.h */
40 enum {
41 DCR_ISRAM0_BASE = 0x20,
42 DCR_ISRAM0_SB0CR = DCR_ISRAM0_BASE,
43 DCR_ISRAM0_SB1CR,
44 DCR_ISRAM0_SB2CR,
45 DCR_ISRAM0_SB3CR,
46 DCR_ISRAM0_BEAR,
47 DCR_ISRAM0_BESR0,
48 DCR_ISRAM0_BESR1,
49 DCR_ISRAM0_PMEG,
50 DCR_ISRAM0_CID,
51 DCR_ISRAM0_REVID,
52 DCR_ISRAM0_DPC,
53 DCR_ISRAM0_END = DCR_ISRAM0_DPC
56 enum {
57 DCR_ISRAM1_BASE = 0xb0,
58 DCR_ISRAM1_SB0CR = DCR_ISRAM1_BASE,
59 /* single bank */
60 DCR_ISRAM1_BEAR = DCR_ISRAM1_BASE + 0x04,
61 DCR_ISRAM1_BESR0,
62 DCR_ISRAM1_BESR1,
63 DCR_ISRAM1_PMEG,
64 DCR_ISRAM1_CID,
65 DCR_ISRAM1_REVID,
66 DCR_ISRAM1_DPC,
67 DCR_ISRAM1_END = DCR_ISRAM1_DPC
70 typedef struct ppc4xx_l2sram_t {
71 MemoryRegion bank[4];
72 uint32_t l2cache[8];
73 uint32_t isram0[11];
74 } ppc4xx_l2sram_t;
76 static uint32_t dcr_read_l2sram(void *opaque, int dcrn)
78 ppc4xx_l2sram_t *l2sram = opaque;
79 uint32_t ret = 0;
81 switch (dcrn) {
82 case DCR_L2CACHE_CFG:
83 case DCR_L2CACHE_CMD:
84 case DCR_L2CACHE_ADDR:
85 case DCR_L2CACHE_DATA:
86 case DCR_L2CACHE_STAT:
87 case DCR_L2CACHE_CVER:
88 case DCR_L2CACHE_SNP0:
89 case DCR_L2CACHE_SNP1:
90 ret = l2sram->l2cache[dcrn - DCR_L2CACHE_BASE];
91 break;
93 case DCR_ISRAM0_SB0CR:
94 case DCR_ISRAM0_SB1CR:
95 case DCR_ISRAM0_SB2CR:
96 case DCR_ISRAM0_SB3CR:
97 case DCR_ISRAM0_BEAR:
98 case DCR_ISRAM0_BESR0:
99 case DCR_ISRAM0_BESR1:
100 case DCR_ISRAM0_PMEG:
101 case DCR_ISRAM0_CID:
102 case DCR_ISRAM0_REVID:
103 case DCR_ISRAM0_DPC:
104 ret = l2sram->isram0[dcrn - DCR_ISRAM0_BASE];
105 break;
107 default:
108 break;
111 return ret;
114 static void dcr_write_l2sram(void *opaque, int dcrn, uint32_t val)
116 /*ppc4xx_l2sram_t *l2sram = opaque;*/
117 /* FIXME: Actually handle L2 cache mapping */
119 switch (dcrn) {
120 case DCR_L2CACHE_CFG:
121 case DCR_L2CACHE_CMD:
122 case DCR_L2CACHE_ADDR:
123 case DCR_L2CACHE_DATA:
124 case DCR_L2CACHE_STAT:
125 case DCR_L2CACHE_CVER:
126 case DCR_L2CACHE_SNP0:
127 case DCR_L2CACHE_SNP1:
128 /*l2sram->l2cache[dcrn - DCR_L2CACHE_BASE] = val;*/
129 break;
131 case DCR_ISRAM0_SB0CR:
132 case DCR_ISRAM0_SB1CR:
133 case DCR_ISRAM0_SB2CR:
134 case DCR_ISRAM0_SB3CR:
135 case DCR_ISRAM0_BEAR:
136 case DCR_ISRAM0_BESR0:
137 case DCR_ISRAM0_BESR1:
138 case DCR_ISRAM0_PMEG:
139 case DCR_ISRAM0_CID:
140 case DCR_ISRAM0_REVID:
141 case DCR_ISRAM0_DPC:
142 /*l2sram->isram0[dcrn - DCR_L2CACHE_BASE] = val;*/
143 break;
145 case DCR_ISRAM1_SB0CR:
146 case DCR_ISRAM1_BEAR:
147 case DCR_ISRAM1_BESR0:
148 case DCR_ISRAM1_BESR1:
149 case DCR_ISRAM1_PMEG:
150 case DCR_ISRAM1_CID:
151 case DCR_ISRAM1_REVID:
152 case DCR_ISRAM1_DPC:
153 /*l2sram->isram1[dcrn - DCR_L2CACHE_BASE] = val;*/
154 break;
158 static void l2sram_reset(void *opaque)
160 ppc4xx_l2sram_t *l2sram = opaque;
162 memset(l2sram->l2cache, 0, sizeof(l2sram->l2cache));
163 l2sram->l2cache[DCR_L2CACHE_STAT - DCR_L2CACHE_BASE] = 0x80000000;
164 memset(l2sram->isram0, 0, sizeof(l2sram->isram0));
167 void ppc4xx_l2sram_init(CPUPPCState *env)
169 ppc4xx_l2sram_t *l2sram;
171 l2sram = g_malloc0(sizeof(*l2sram));
172 /* XXX: Size is 4*64kB for 460ex, cf. U-Boot, ppc4xx-isram.h */
173 memory_region_init_ram(&l2sram->bank[0], NULL, "ppc4xx.l2sram_bank0",
174 64 * KiB, &error_abort);
175 memory_region_init_ram(&l2sram->bank[1], NULL, "ppc4xx.l2sram_bank1",
176 64 * KiB, &error_abort);
177 memory_region_init_ram(&l2sram->bank[2], NULL, "ppc4xx.l2sram_bank2",
178 64 * KiB, &error_abort);
179 memory_region_init_ram(&l2sram->bank[3], NULL, "ppc4xx.l2sram_bank3",
180 64 * KiB, &error_abort);
181 qemu_register_reset(&l2sram_reset, l2sram);
182 ppc_dcr_register(env, DCR_L2CACHE_CFG,
183 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
184 ppc_dcr_register(env, DCR_L2CACHE_CMD,
185 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
186 ppc_dcr_register(env, DCR_L2CACHE_ADDR,
187 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
188 ppc_dcr_register(env, DCR_L2CACHE_DATA,
189 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
190 ppc_dcr_register(env, DCR_L2CACHE_STAT,
191 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
192 ppc_dcr_register(env, DCR_L2CACHE_CVER,
193 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
194 ppc_dcr_register(env, DCR_L2CACHE_SNP0,
195 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
196 ppc_dcr_register(env, DCR_L2CACHE_SNP1,
197 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
199 ppc_dcr_register(env, DCR_ISRAM0_SB0CR,
200 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
201 ppc_dcr_register(env, DCR_ISRAM0_SB1CR,
202 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
203 ppc_dcr_register(env, DCR_ISRAM0_SB2CR,
204 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
205 ppc_dcr_register(env, DCR_ISRAM0_SB3CR,
206 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
207 ppc_dcr_register(env, DCR_ISRAM0_PMEG,
208 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
209 ppc_dcr_register(env, DCR_ISRAM0_DPC,
210 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
212 ppc_dcr_register(env, DCR_ISRAM1_SB0CR,
213 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
214 ppc_dcr_register(env, DCR_ISRAM1_PMEG,
215 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
216 ppc_dcr_register(env, DCR_ISRAM1_DPC,
217 l2sram, &dcr_read_l2sram, &dcr_write_l2sram);
220 /*****************************************************************************/
221 /* Clocking Power on Reset */
222 enum {
223 CPR0_CFGADDR = 0xC,
224 CPR0_CFGDATA = 0xD,
226 CPR0_PLLD = 0x060,
227 CPR0_PLBED = 0x080,
228 CPR0_OPBD = 0x0C0,
229 CPR0_PERD = 0x0E0,
230 CPR0_AHBD = 0x100,
233 typedef struct ppc4xx_cpr_t {
234 uint32_t addr;
235 } ppc4xx_cpr_t;
237 static uint32_t dcr_read_cpr(void *opaque, int dcrn)
239 ppc4xx_cpr_t *cpr = opaque;
240 uint32_t ret = 0;
242 switch (dcrn) {
243 case CPR0_CFGADDR:
244 ret = cpr->addr;
245 break;
246 case CPR0_CFGDATA:
247 switch (cpr->addr) {
248 case CPR0_PLLD:
249 ret = (0xb5 << 24) | (1 << 16) | (9 << 8);
250 break;
251 case CPR0_PLBED:
252 ret = (5 << 24);
253 break;
254 case CPR0_OPBD:
255 ret = (2 << 24);
256 break;
257 case CPR0_PERD:
258 case CPR0_AHBD:
259 ret = (1 << 24);
260 break;
261 default:
262 break;
264 break;
265 default:
266 break;
269 return ret;
272 static void dcr_write_cpr(void *opaque, int dcrn, uint32_t val)
274 ppc4xx_cpr_t *cpr = opaque;
276 switch (dcrn) {
277 case CPR0_CFGADDR:
278 cpr->addr = val;
279 break;
280 case CPR0_CFGDATA:
281 break;
282 default:
283 break;
287 static void ppc4xx_cpr_reset(void *opaque)
289 ppc4xx_cpr_t *cpr = opaque;
291 cpr->addr = 0;
294 void ppc4xx_cpr_init(CPUPPCState *env)
296 ppc4xx_cpr_t *cpr;
298 cpr = g_malloc0(sizeof(*cpr));
299 ppc_dcr_register(env, CPR0_CFGADDR, cpr, &dcr_read_cpr, &dcr_write_cpr);
300 ppc_dcr_register(env, CPR0_CFGDATA, cpr, &dcr_read_cpr, &dcr_write_cpr);
301 qemu_register_reset(ppc4xx_cpr_reset, cpr);
304 /*****************************************************************************/
305 /* System DCRs */
306 typedef struct ppc4xx_sdr_t ppc4xx_sdr_t;
307 struct ppc4xx_sdr_t {
308 uint32_t addr;
311 enum {
312 SDR0_CFGADDR = 0x00e,
313 SDR0_CFGDATA,
314 SDR0_STRP0 = 0x020,
315 SDR0_STRP1,
316 SDR0_102 = 0x66,
317 SDR0_103,
318 SDR0_128 = 0x80,
319 SDR0_ECID3 = 0x083,
320 SDR0_DDR0 = 0x0e1,
321 SDR0_USB0 = 0x320,
324 enum {
325 PESDR0_LOOP = 0x303,
326 PESDR0_RCSSET,
327 PESDR0_RCSSTS,
328 PESDR0_RSTSTA = 0x310,
329 PESDR1_LOOP = 0x343,
330 PESDR1_RCSSET,
331 PESDR1_RCSSTS,
332 PESDR1_RSTSTA = 0x365,
335 static uint32_t dcr_read_sdr(void *opaque, int dcrn)
337 ppc4xx_sdr_t *sdr = opaque;
338 uint32_t ret = 0;
340 switch (dcrn) {
341 case SDR0_CFGADDR:
342 ret = sdr->addr;
343 break;
344 case SDR0_CFGDATA:
345 switch (sdr->addr) {
346 case SDR0_STRP0:
347 ret = (0xb5 << 8) | (1 << 4) | 9;
348 break;
349 case SDR0_STRP1:
350 ret = (5 << 29) | (2 << 26) | (1 << 24);
351 break;
352 case SDR0_ECID3:
353 ret = 1 << 20; /* No Security/Kasumi support */
354 break;
355 case SDR0_DDR0:
356 ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
357 break;
358 case PESDR0_RCSSET:
359 case PESDR1_RCSSET:
360 ret = (1 << 24) | (1 << 16);
361 break;
362 case PESDR0_RCSSTS:
363 case PESDR1_RCSSTS:
364 ret = (1 << 16) | (1 << 12);
365 break;
366 case PESDR0_RSTSTA:
367 case PESDR1_RSTSTA:
368 ret = 1;
369 break;
370 case PESDR0_LOOP:
371 case PESDR1_LOOP:
372 ret = 1 << 12;
373 break;
374 default:
375 break;
377 break;
378 default:
379 break;
382 return ret;
385 static void dcr_write_sdr(void *opaque, int dcrn, uint32_t val)
387 ppc4xx_sdr_t *sdr = opaque;
389 switch (dcrn) {
390 case SDR0_CFGADDR:
391 sdr->addr = val;
392 break;
393 case SDR0_CFGDATA:
394 switch (sdr->addr) {
395 case 0x00: /* B0CR */
396 break;
397 default:
398 break;
400 break;
401 default:
402 break;
406 static void sdr_reset(void *opaque)
408 ppc4xx_sdr_t *sdr = opaque;
410 sdr->addr = 0;
413 void ppc4xx_sdr_init(CPUPPCState *env)
415 ppc4xx_sdr_t *sdr;
417 sdr = g_malloc0(sizeof(*sdr));
418 qemu_register_reset(&sdr_reset, sdr);
419 ppc_dcr_register(env, SDR0_CFGADDR,
420 sdr, &dcr_read_sdr, &dcr_write_sdr);
421 ppc_dcr_register(env, SDR0_CFGDATA,
422 sdr, &dcr_read_sdr, &dcr_write_sdr);
423 ppc_dcr_register(env, SDR0_102,
424 sdr, &dcr_read_sdr, &dcr_write_sdr);
425 ppc_dcr_register(env, SDR0_103,
426 sdr, &dcr_read_sdr, &dcr_write_sdr);
427 ppc_dcr_register(env, SDR0_128,
428 sdr, &dcr_read_sdr, &dcr_write_sdr);
429 ppc_dcr_register(env, SDR0_USB0,
430 sdr, &dcr_read_sdr, &dcr_write_sdr);
433 /*****************************************************************************/
434 /* PLB to AHB bridge */
435 enum {
436 AHB_TOP = 0xA4,
437 AHB_BOT = 0xA5,
440 typedef struct ppc4xx_ahb_t {
441 uint32_t top;
442 uint32_t bot;
443 } ppc4xx_ahb_t;
445 static uint32_t dcr_read_ahb(void *opaque, int dcrn)
447 ppc4xx_ahb_t *ahb = opaque;
448 uint32_t ret = 0;
450 switch (dcrn) {
451 case AHB_TOP:
452 ret = ahb->top;
453 break;
454 case AHB_BOT:
455 ret = ahb->bot;
456 break;
457 default:
458 break;
461 return ret;
464 static void dcr_write_ahb(void *opaque, int dcrn, uint32_t val)
466 ppc4xx_ahb_t *ahb = opaque;
468 switch (dcrn) {
469 case AHB_TOP:
470 ahb->top = val;
471 break;
472 case AHB_BOT:
473 ahb->bot = val;
474 break;
478 static void ppc4xx_ahb_reset(void *opaque)
480 ppc4xx_ahb_t *ahb = opaque;
482 /* No error */
483 ahb->top = 0;
484 ahb->bot = 0;
487 void ppc4xx_ahb_init(CPUPPCState *env)
489 ppc4xx_ahb_t *ahb;
491 ahb = g_malloc0(sizeof(*ahb));
492 ppc_dcr_register(env, AHB_TOP, ahb, &dcr_read_ahb, &dcr_write_ahb);
493 ppc_dcr_register(env, AHB_BOT, ahb, &dcr_read_ahb, &dcr_write_ahb);
494 qemu_register_reset(ppc4xx_ahb_reset, ahb);
497 /*****************************************************************************/
498 /* DMA controller */
500 #define DMA0_CR_CE (1 << 31)
501 #define DMA0_CR_PW (1 << 26 | 1 << 25)
502 #define DMA0_CR_DAI (1 << 24)
503 #define DMA0_CR_SAI (1 << 23)
504 #define DMA0_CR_DEC (1 << 2)
506 enum {
507 DMA0_CR = 0x00,
508 DMA0_CT,
509 DMA0_SAH,
510 DMA0_SAL,
511 DMA0_DAH,
512 DMA0_DAL,
513 DMA0_SGH,
514 DMA0_SGL,
516 DMA0_SR = 0x20,
517 DMA0_SGC = 0x23,
518 DMA0_SLP = 0x25,
519 DMA0_POL = 0x26,
522 typedef struct {
523 uint32_t cr;
524 uint32_t ct;
525 uint64_t sa;
526 uint64_t da;
527 uint64_t sg;
528 } PPC4xxDmaChnl;
530 typedef struct {
531 int base;
532 PPC4xxDmaChnl ch[4];
533 uint32_t sr;
534 } PPC4xxDmaState;
536 static uint32_t dcr_read_dma(void *opaque, int dcrn)
538 PPC4xxDmaState *dma = opaque;
539 uint32_t val = 0;
540 int addr = dcrn - dma->base;
541 int chnl = addr / 8;
543 switch (addr) {
544 case 0x00 ... 0x1f:
545 switch (addr % 8) {
546 case DMA0_CR:
547 val = dma->ch[chnl].cr;
548 break;
549 case DMA0_CT:
550 val = dma->ch[chnl].ct;
551 break;
552 case DMA0_SAH:
553 val = dma->ch[chnl].sa >> 32;
554 break;
555 case DMA0_SAL:
556 val = dma->ch[chnl].sa;
557 break;
558 case DMA0_DAH:
559 val = dma->ch[chnl].da >> 32;
560 break;
561 case DMA0_DAL:
562 val = dma->ch[chnl].da;
563 break;
564 case DMA0_SGH:
565 val = dma->ch[chnl].sg >> 32;
566 break;
567 case DMA0_SGL:
568 val = dma->ch[chnl].sg;
569 break;
571 break;
572 case DMA0_SR:
573 val = dma->sr;
574 break;
575 default:
576 qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
577 __func__, dcrn, chnl, addr);
580 return val;
583 static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
585 PPC4xxDmaState *dma = opaque;
586 int addr = dcrn - dma->base;
587 int chnl = addr / 8;
589 switch (addr) {
590 case 0x00 ... 0x1f:
591 switch (addr % 8) {
592 case DMA0_CR:
593 dma->ch[chnl].cr = val;
594 if (val & DMA0_CR_CE) {
595 int count = dma->ch[chnl].ct & 0xffff;
597 if (count) {
598 int width, i, sidx, didx;
599 uint8_t *rptr, *wptr;
600 hwaddr rlen, wlen;
601 hwaddr xferlen;
603 sidx = didx = 0;
604 width = 1 << ((val & DMA0_CR_PW) >> 25);
605 xferlen = count * width;
606 wlen = rlen = xferlen;
607 rptr = cpu_physical_memory_map(dma->ch[chnl].sa, &rlen,
608 false);
609 wptr = cpu_physical_memory_map(dma->ch[chnl].da, &wlen,
610 true);
611 if (rptr && rlen == xferlen && wptr && wlen == xferlen) {
612 if (!(val & DMA0_CR_DEC) &&
613 val & DMA0_CR_SAI && val & DMA0_CR_DAI) {
614 /* optimise common case */
615 memmove(wptr, rptr, count * width);
616 sidx = didx = count * width;
617 } else {
618 /* do it the slow way */
619 for (sidx = didx = i = 0; i < count; i++) {
620 uint64_t v = ldn_le_p(rptr + sidx, width);
621 stn_le_p(wptr + didx, width, v);
622 if (val & DMA0_CR_SAI) {
623 sidx += width;
625 if (val & DMA0_CR_DAI) {
626 didx += width;
631 if (wptr) {
632 cpu_physical_memory_unmap(wptr, wlen, 1, didx);
634 if (rptr) {
635 cpu_physical_memory_unmap(rptr, rlen, 0, sidx);
639 break;
640 case DMA0_CT:
641 dma->ch[chnl].ct = val;
642 break;
643 case DMA0_SAH:
644 dma->ch[chnl].sa &= 0xffffffffULL;
645 dma->ch[chnl].sa |= (uint64_t)val << 32;
646 break;
647 case DMA0_SAL:
648 dma->ch[chnl].sa &= 0xffffffff00000000ULL;
649 dma->ch[chnl].sa |= val;
650 break;
651 case DMA0_DAH:
652 dma->ch[chnl].da &= 0xffffffffULL;
653 dma->ch[chnl].da |= (uint64_t)val << 32;
654 break;
655 case DMA0_DAL:
656 dma->ch[chnl].da &= 0xffffffff00000000ULL;
657 dma->ch[chnl].da |= val;
658 break;
659 case DMA0_SGH:
660 dma->ch[chnl].sg &= 0xffffffffULL;
661 dma->ch[chnl].sg |= (uint64_t)val << 32;
662 break;
663 case DMA0_SGL:
664 dma->ch[chnl].sg &= 0xffffffff00000000ULL;
665 dma->ch[chnl].sg |= val;
666 break;
668 break;
669 case DMA0_SR:
670 dma->sr &= ~val;
671 break;
672 default:
673 qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n",
674 __func__, dcrn, chnl, addr);
678 static void ppc4xx_dma_reset(void *opaque)
680 PPC4xxDmaState *dma = opaque;
681 int dma_base = dma->base;
683 memset(dma, 0, sizeof(*dma));
684 dma->base = dma_base;
687 void ppc4xx_dma_init(CPUPPCState *env, int dcr_base)
689 PPC4xxDmaState *dma;
690 int i;
692 dma = g_malloc0(sizeof(*dma));
693 dma->base = dcr_base;
694 qemu_register_reset(&ppc4xx_dma_reset, dma);
695 for (i = 0; i < 4; i++) {
696 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CR,
697 dma, &dcr_read_dma, &dcr_write_dma);
698 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CT,
699 dma, &dcr_read_dma, &dcr_write_dma);
700 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAH,
701 dma, &dcr_read_dma, &dcr_write_dma);
702 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAL,
703 dma, &dcr_read_dma, &dcr_write_dma);
704 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAH,
705 dma, &dcr_read_dma, &dcr_write_dma);
706 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAL,
707 dma, &dcr_read_dma, &dcr_write_dma);
708 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGH,
709 dma, &dcr_read_dma, &dcr_write_dma);
710 ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGL,
711 dma, &dcr_read_dma, &dcr_write_dma);
713 ppc_dcr_register(env, dcr_base + DMA0_SR,
714 dma, &dcr_read_dma, &dcr_write_dma);
715 ppc_dcr_register(env, dcr_base + DMA0_SGC,
716 dma, &dcr_read_dma, &dcr_write_dma);
717 ppc_dcr_register(env, dcr_base + DMA0_SLP,
718 dma, &dcr_read_dma, &dcr_write_dma);
719 ppc_dcr_register(env, dcr_base + DMA0_POL,
720 dma, &dcr_read_dma, &dcr_write_dma);
723 /*****************************************************************************/
724 /* PCI Express controller */
726 * FIXME: This is not complete and does not work, only implemented partially
727 * to allow firmware and guests to find an empty bus. Cards should use PCI.
729 #include "hw/pci/pcie_host.h"
731 OBJECT_DECLARE_SIMPLE_TYPE(PPC460EXPCIEState, PPC460EX_PCIE_HOST)
733 struct PPC460EXPCIEState {
734 PCIExpressHost parent_obj;
736 MemoryRegion busmem;
737 MemoryRegion iomem;
738 qemu_irq irq[4];
739 int32_t num;
740 int32_t dcrn_base;
741 PowerPCCPU *cpu;
743 uint64_t cfg_base;
744 uint32_t cfg_mask;
745 uint64_t msg_base;
746 uint32_t msg_mask;
747 uint64_t omr1_base;
748 uint64_t omr1_mask;
749 uint64_t omr2_base;
750 uint64_t omr2_mask;
751 uint64_t omr3_base;
752 uint64_t omr3_mask;
753 uint64_t reg_base;
754 uint32_t reg_mask;
755 uint32_t special;
756 uint32_t cfg;
759 enum {
760 PEGPL_CFGBAH = 0x0,
761 PEGPL_CFGBAL,
762 PEGPL_CFGMSK,
763 PEGPL_MSGBAH,
764 PEGPL_MSGBAL,
765 PEGPL_MSGMSK,
766 PEGPL_OMR1BAH,
767 PEGPL_OMR1BAL,
768 PEGPL_OMR1MSKH,
769 PEGPL_OMR1MSKL,
770 PEGPL_OMR2BAH,
771 PEGPL_OMR2BAL,
772 PEGPL_OMR2MSKH,
773 PEGPL_OMR2MSKL,
774 PEGPL_OMR3BAH,
775 PEGPL_OMR3BAL,
776 PEGPL_OMR3MSKH,
777 PEGPL_OMR3MSKL,
778 PEGPL_REGBAH,
779 PEGPL_REGBAL,
780 PEGPL_REGMSK,
781 PEGPL_SPECIAL,
782 PEGPL_CFG,
785 static uint32_t dcr_read_pcie(void *opaque, int dcrn)
787 PPC460EXPCIEState *s = opaque;
788 uint32_t ret = 0;
790 switch (dcrn - s->dcrn_base) {
791 case PEGPL_CFGBAH:
792 ret = s->cfg_base >> 32;
793 break;
794 case PEGPL_CFGBAL:
795 ret = s->cfg_base;
796 break;
797 case PEGPL_CFGMSK:
798 ret = s->cfg_mask;
799 break;
800 case PEGPL_MSGBAH:
801 ret = s->msg_base >> 32;
802 break;
803 case PEGPL_MSGBAL:
804 ret = s->msg_base;
805 break;
806 case PEGPL_MSGMSK:
807 ret = s->msg_mask;
808 break;
809 case PEGPL_OMR1BAH:
810 ret = s->omr1_base >> 32;
811 break;
812 case PEGPL_OMR1BAL:
813 ret = s->omr1_base;
814 break;
815 case PEGPL_OMR1MSKH:
816 ret = s->omr1_mask >> 32;
817 break;
818 case PEGPL_OMR1MSKL:
819 ret = s->omr1_mask;
820 break;
821 case PEGPL_OMR2BAH:
822 ret = s->omr2_base >> 32;
823 break;
824 case PEGPL_OMR2BAL:
825 ret = s->omr2_base;
826 break;
827 case PEGPL_OMR2MSKH:
828 ret = s->omr2_mask >> 32;
829 break;
830 case PEGPL_OMR2MSKL:
831 ret = s->omr3_mask;
832 break;
833 case PEGPL_OMR3BAH:
834 ret = s->omr3_base >> 32;
835 break;
836 case PEGPL_OMR3BAL:
837 ret = s->omr3_base;
838 break;
839 case PEGPL_OMR3MSKH:
840 ret = s->omr3_mask >> 32;
841 break;
842 case PEGPL_OMR3MSKL:
843 ret = s->omr3_mask;
844 break;
845 case PEGPL_REGBAH:
846 ret = s->reg_base >> 32;
847 break;
848 case PEGPL_REGBAL:
849 ret = s->reg_base;
850 break;
851 case PEGPL_REGMSK:
852 ret = s->reg_mask;
853 break;
854 case PEGPL_SPECIAL:
855 ret = s->special;
856 break;
857 case PEGPL_CFG:
858 ret = s->cfg;
859 break;
862 return ret;
865 static void dcr_write_pcie(void *opaque, int dcrn, uint32_t val)
867 PPC460EXPCIEState *s = opaque;
868 uint64_t size;
870 switch (dcrn - s->dcrn_base) {
871 case PEGPL_CFGBAH:
872 s->cfg_base = ((uint64_t)val << 32) | (s->cfg_base & 0xffffffff);
873 break;
874 case PEGPL_CFGBAL:
875 s->cfg_base = (s->cfg_base & 0xffffffff00000000ULL) | val;
876 break;
877 case PEGPL_CFGMSK:
878 s->cfg_mask = val;
879 size = ~(val & 0xfffffffe) + 1;
881 * Firmware sets this register to E0000001. Why we are not sure,
882 * but the current guess is anything above PCIE_MMCFG_SIZE_MAX is
883 * ignored.
885 if (size > PCIE_MMCFG_SIZE_MAX) {
886 size = PCIE_MMCFG_SIZE_MAX;
888 pcie_host_mmcfg_update(PCIE_HOST_BRIDGE(s), val & 1, s->cfg_base, size);
889 break;
890 case PEGPL_MSGBAH:
891 s->msg_base = ((uint64_t)val << 32) | (s->msg_base & 0xffffffff);
892 break;
893 case PEGPL_MSGBAL:
894 s->msg_base = (s->msg_base & 0xffffffff00000000ULL) | val;
895 break;
896 case PEGPL_MSGMSK:
897 s->msg_mask = val;
898 break;
899 case PEGPL_OMR1BAH:
900 s->omr1_base = ((uint64_t)val << 32) | (s->omr1_base & 0xffffffff);
901 break;
902 case PEGPL_OMR1BAL:
903 s->omr1_base = (s->omr1_base & 0xffffffff00000000ULL) | val;
904 break;
905 case PEGPL_OMR1MSKH:
906 s->omr1_mask = ((uint64_t)val << 32) | (s->omr1_mask & 0xffffffff);
907 break;
908 case PEGPL_OMR1MSKL:
909 s->omr1_mask = (s->omr1_mask & 0xffffffff00000000ULL) | val;
910 break;
911 case PEGPL_OMR2BAH:
912 s->omr2_base = ((uint64_t)val << 32) | (s->omr2_base & 0xffffffff);
913 break;
914 case PEGPL_OMR2BAL:
915 s->omr2_base = (s->omr2_base & 0xffffffff00000000ULL) | val;
916 break;
917 case PEGPL_OMR2MSKH:
918 s->omr2_mask = ((uint64_t)val << 32) | (s->omr2_mask & 0xffffffff);
919 break;
920 case PEGPL_OMR2MSKL:
921 s->omr2_mask = (s->omr2_mask & 0xffffffff00000000ULL) | val;
922 break;
923 case PEGPL_OMR3BAH:
924 s->omr3_base = ((uint64_t)val << 32) | (s->omr3_base & 0xffffffff);
925 break;
926 case PEGPL_OMR3BAL:
927 s->omr3_base = (s->omr3_base & 0xffffffff00000000ULL) | val;
928 break;
929 case PEGPL_OMR3MSKH:
930 s->omr3_mask = ((uint64_t)val << 32) | (s->omr3_mask & 0xffffffff);
931 break;
932 case PEGPL_OMR3MSKL:
933 s->omr3_mask = (s->omr3_mask & 0xffffffff00000000ULL) | val;
934 break;
935 case PEGPL_REGBAH:
936 s->reg_base = ((uint64_t)val << 32) | (s->reg_base & 0xffffffff);
937 break;
938 case PEGPL_REGBAL:
939 s->reg_base = (s->reg_base & 0xffffffff00000000ULL) | val;
940 break;
941 case PEGPL_REGMSK:
942 s->reg_mask = val;
943 /* FIXME: how is size encoded? */
944 size = (val == 0x7001 ? 4096 : ~(val & 0xfffffffe) + 1);
945 break;
946 case PEGPL_SPECIAL:
947 s->special = val;
948 break;
949 case PEGPL_CFG:
950 s->cfg = val;
951 break;
955 static void ppc460ex_set_irq(void *opaque, int irq_num, int level)
957 PPC460EXPCIEState *s = opaque;
958 qemu_set_irq(s->irq[irq_num], level);
961 #define PPC440_PCIE_DCR(s, dcrn) \
962 ppc_dcr_register(&(s)->cpu->env, (s)->dcrn_base + (dcrn), (s), \
963 &dcr_read_pcie, &dcr_write_pcie)
966 static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s)
968 PPC440_PCIE_DCR(s, PEGPL_CFGBAH);
969 PPC440_PCIE_DCR(s, PEGPL_CFGBAL);
970 PPC440_PCIE_DCR(s, PEGPL_CFGMSK);
971 PPC440_PCIE_DCR(s, PEGPL_MSGBAH);
972 PPC440_PCIE_DCR(s, PEGPL_MSGBAL);
973 PPC440_PCIE_DCR(s, PEGPL_MSGMSK);
974 PPC440_PCIE_DCR(s, PEGPL_OMR1BAH);
975 PPC440_PCIE_DCR(s, PEGPL_OMR1BAL);
976 PPC440_PCIE_DCR(s, PEGPL_OMR1MSKH);
977 PPC440_PCIE_DCR(s, PEGPL_OMR1MSKL);
978 PPC440_PCIE_DCR(s, PEGPL_OMR2BAH);
979 PPC440_PCIE_DCR(s, PEGPL_OMR2BAL);
980 PPC440_PCIE_DCR(s, PEGPL_OMR2MSKH);
981 PPC440_PCIE_DCR(s, PEGPL_OMR2MSKL);
982 PPC440_PCIE_DCR(s, PEGPL_OMR3BAH);
983 PPC440_PCIE_DCR(s, PEGPL_OMR3BAL);
984 PPC440_PCIE_DCR(s, PEGPL_OMR3MSKH);
985 PPC440_PCIE_DCR(s, PEGPL_OMR3MSKL);
986 PPC440_PCIE_DCR(s, PEGPL_REGBAH);
987 PPC440_PCIE_DCR(s, PEGPL_REGBAL);
988 PPC440_PCIE_DCR(s, PEGPL_REGMSK);
989 PPC440_PCIE_DCR(s, PEGPL_SPECIAL);
990 PPC440_PCIE_DCR(s, PEGPL_CFG);
993 static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp)
995 PPC460EXPCIEState *s = PPC460EX_PCIE_HOST(dev);
996 PCIHostState *pci = PCI_HOST_BRIDGE(dev);
997 int i;
998 char buf[20];
1000 if (!s->cpu) {
1001 error_setg(errp, "cpu link property must be set");
1002 return;
1004 if (s->num < 0 || s->dcrn_base < 0) {
1005 error_setg(errp, "busnum and dcrn-base properties must be set");
1006 return;
1008 snprintf(buf, sizeof(buf), "pcie%d-mem", s->num);
1009 memory_region_init(&s->busmem, OBJECT(s), buf, UINT64_MAX);
1010 snprintf(buf, sizeof(buf), "pcie%d-io", s->num);
1011 memory_region_init(&s->iomem, OBJECT(s), buf, 64 * KiB);
1012 for (i = 0; i < 4; i++) {
1013 sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
1015 snprintf(buf, sizeof(buf), "pcie.%d", s->num);
1016 pci->bus = pci_register_root_bus(DEVICE(s), buf, ppc460ex_set_irq,
1017 pci_swizzle_map_irq_fn, s, &s->busmem,
1018 &s->iomem, 0, 4, TYPE_PCIE_BUS);
1019 ppc460ex_pcie_register_dcrs(s);
1022 static Property ppc460ex_pcie_props[] = {
1023 DEFINE_PROP_INT32("busnum", PPC460EXPCIEState, num, -1),
1024 DEFINE_PROP_INT32("dcrn-base", PPC460EXPCIEState, dcrn_base, -1),
1025 DEFINE_PROP_LINK("cpu", PPC460EXPCIEState, cpu, TYPE_POWERPC_CPU,
1026 PowerPCCPU *),
1027 DEFINE_PROP_END_OF_LIST(),
1030 static void ppc460ex_pcie_class_init(ObjectClass *klass, void *data)
1032 DeviceClass *dc = DEVICE_CLASS(klass);
1034 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
1035 dc->realize = ppc460ex_pcie_realize;
1036 device_class_set_props(dc, ppc460ex_pcie_props);
1037 dc->hotpluggable = false;
1040 static const TypeInfo ppc460ex_pcie_host_info = {
1041 .name = TYPE_PPC460EX_PCIE_HOST,
1042 .parent = TYPE_PCIE_HOST_BRIDGE,
1043 .instance_size = sizeof(PPC460EXPCIEState),
1044 .class_init = ppc460ex_pcie_class_init,
1047 static void ppc460ex_pcie_register(void)
1049 type_register_static(&ppc460ex_pcie_host_info);
1052 type_init(ppc460ex_pcie_register)