xref: /qemu/hw/ppc/ppc4xx_devs.c (revision 94452ac4)
1 /*
2  * QEMU PowerPC 4xx embedded processors shared devices emulation
3  *
4  * Copyright (c) 2007 Jocelyn Mayer
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 #include "qemu/osdep.h"
26 #include "qemu/units.h"
27 #include "sysemu/reset.h"
28 #include "cpu.h"
29 #include "hw/irq.h"
30 #include "hw/ppc/ppc.h"
31 #include "hw/ppc/ppc4xx.h"
32 #include "hw/qdev-properties.h"
33 #include "qemu/log.h"
34 #include "exec/address-spaces.h"
35 #include "qemu/error-report.h"
36 #include "qapi/error.h"
37 #include "trace.h"
38 
39 /*****************************************************************************/
40 /* SDRAM controller */
41 typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
42 struct ppc4xx_sdram_t {
43     uint32_t addr;
44     int nbanks;
45     MemoryRegion containers[4]; /* used for clipping */
46     MemoryRegion *ram_memories;
47     hwaddr ram_bases[4];
48     hwaddr ram_sizes[4];
49     uint32_t besr0;
50     uint32_t besr1;
51     uint32_t bear;
52     uint32_t cfg;
53     uint32_t status;
54     uint32_t rtr;
55     uint32_t pmit;
56     uint32_t bcr[4];
57     uint32_t tr;
58     uint32_t ecccfg;
59     uint32_t eccesr;
60     qemu_irq irq;
61 };
62 
63 enum {
64     SDRAM0_CFGADDR = 0x010,
65     SDRAM0_CFGDATA = 0x011,
66 };
67 
68 /*
69  * XXX: TOFIX: some patches have made this code become inconsistent:
70  *      there are type inconsistencies, mixing hwaddr, target_ulong
71  *      and uint32_t
72  */
73 static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)
74 {
75     uint32_t bcr;
76 
77     switch (ram_size) {
78     case 4 * MiB:
79         bcr = 0x00000000;
80         break;
81     case 8 * MiB:
82         bcr = 0x00020000;
83         break;
84     case 16 * MiB:
85         bcr = 0x00040000;
86         break;
87     case 32 * MiB:
88         bcr = 0x00060000;
89         break;
90     case 64 * MiB:
91         bcr = 0x00080000;
92         break;
93     case 128 * MiB:
94         bcr = 0x000A0000;
95         break;
96     case 256 * MiB:
97         bcr = 0x000C0000;
98         break;
99     default:
100         qemu_log_mask(LOG_GUEST_ERROR,
101                       "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
102                       ram_size);
103         return 0x00000000;
104     }
105     bcr |= ram_base & 0xFF800000;
106     bcr |= 1;
107 
108     return bcr;
109 }
110 
111 static inline hwaddr sdram_base(uint32_t bcr)
112 {
113     return bcr & 0xFF800000;
114 }
115 
116 static target_ulong sdram_size(uint32_t bcr)
117 {
118     target_ulong size;
119     int sh;
120 
121     sh = (bcr >> 17) & 0x7;
122     if (sh == 7) {
123         size = -1;
124     } else {
125         size = (4 * MiB) << sh;
126     }
127 
128     return size;
129 }
130 
131 static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
132                           uint32_t bcr, int enabled)
133 {
134     if (sdram->bcr[i] & 0x00000001) {
135         /* Unmap RAM */
136         trace_ppc4xx_sdram_unmap(sdram_base(sdram->bcr[i]),
137                                  sdram_size(sdram->bcr[i]));
138         memory_region_del_subregion(get_system_memory(),
139                                     &sdram->containers[i]);
140         memory_region_del_subregion(&sdram->containers[i],
141                                     &sdram->ram_memories[i]);
142         object_unparent(OBJECT(&sdram->containers[i]));
143     }
144     sdram->bcr[i] = bcr & 0xFFDEE001;
145     if (enabled && (bcr & 0x00000001)) {
146         trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
147         memory_region_init(&sdram->containers[i], NULL, "sdram-containers",
148                            sdram_size(bcr));
149         memory_region_add_subregion(&sdram->containers[i], 0,
150                                     &sdram->ram_memories[i]);
151         memory_region_add_subregion(get_system_memory(),
152                                     sdram_base(bcr),
153                                     &sdram->containers[i]);
154     }
155 }
156 
157 static void sdram_map_bcr(ppc4xx_sdram_t *sdram)
158 {
159     int i;
160 
161     for (i = 0; i < sdram->nbanks; i++) {
162         if (sdram->ram_sizes[i] != 0) {
163             sdram_set_bcr(sdram, i, sdram_bcr(sdram->ram_bases[i],
164                                               sdram->ram_sizes[i]), 1);
165         } else {
166             sdram_set_bcr(sdram, i, 0x00000000, 0);
167         }
168     }
169 }
170 
171 static void sdram_unmap_bcr(ppc4xx_sdram_t *sdram)
172 {
173     int i;
174 
175     for (i = 0; i < sdram->nbanks; i++) {
176         trace_ppc4xx_sdram_unmap(sdram_base(sdram->bcr[i]),
177                                  sdram_size(sdram->bcr[i]));
178         memory_region_del_subregion(get_system_memory(),
179                                     &sdram->ram_memories[i]);
180     }
181 }
182 
183 static uint32_t dcr_read_sdram(void *opaque, int dcrn)
184 {
185     ppc4xx_sdram_t *sdram;
186     uint32_t ret;
187 
188     sdram = opaque;
189     switch (dcrn) {
190     case SDRAM0_CFGADDR:
191         ret = sdram->addr;
192         break;
193     case SDRAM0_CFGDATA:
194         switch (sdram->addr) {
195         case 0x00: /* SDRAM_BESR0 */
196             ret = sdram->besr0;
197             break;
198         case 0x08: /* SDRAM_BESR1 */
199             ret = sdram->besr1;
200             break;
201         case 0x10: /* SDRAM_BEAR */
202             ret = sdram->bear;
203             break;
204         case 0x20: /* SDRAM_CFG */
205             ret = sdram->cfg;
206             break;
207         case 0x24: /* SDRAM_STATUS */
208             ret = sdram->status;
209             break;
210         case 0x30: /* SDRAM_RTR */
211             ret = sdram->rtr;
212             break;
213         case 0x34: /* SDRAM_PMIT */
214             ret = sdram->pmit;
215             break;
216         case 0x40: /* SDRAM_B0CR */
217             ret = sdram->bcr[0];
218             break;
219         case 0x44: /* SDRAM_B1CR */
220             ret = sdram->bcr[1];
221             break;
222         case 0x48: /* SDRAM_B2CR */
223             ret = sdram->bcr[2];
224             break;
225         case 0x4C: /* SDRAM_B3CR */
226             ret = sdram->bcr[3];
227             break;
228         case 0x80: /* SDRAM_TR */
229             ret = -1; /* ? */
230             break;
231         case 0x94: /* SDRAM_ECCCFG */
232             ret = sdram->ecccfg;
233             break;
234         case 0x98: /* SDRAM_ECCESR */
235             ret = sdram->eccesr;
236             break;
237         default: /* Error */
238             ret = -1;
239             break;
240         }
241         break;
242     default:
243         /* Avoid gcc warning */
244         ret = 0x00000000;
245         break;
246     }
247 
248     return ret;
249 }
250 
251 static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)
252 {
253     ppc4xx_sdram_t *sdram;
254 
255     sdram = opaque;
256     switch (dcrn) {
257     case SDRAM0_CFGADDR:
258         sdram->addr = val;
259         break;
260     case SDRAM0_CFGDATA:
261         switch (sdram->addr) {
262         case 0x00: /* SDRAM_BESR0 */
263             sdram->besr0 &= ~val;
264             break;
265         case 0x08: /* SDRAM_BESR1 */
266             sdram->besr1 &= ~val;
267             break;
268         case 0x10: /* SDRAM_BEAR */
269             sdram->bear = val;
270             break;
271         case 0x20: /* SDRAM_CFG */
272             val &= 0xFFE00000;
273             if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
274                 trace_ppc4xx_sdram_enable("enable");
275                 /* validate all RAM mappings */
276                 sdram_map_bcr(sdram);
277                 sdram->status &= ~0x80000000;
278             } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
279                 trace_ppc4xx_sdram_enable("disable");
280                 /* invalidate all RAM mappings */
281                 sdram_unmap_bcr(sdram);
282                 sdram->status |= 0x80000000;
283             }
284             if (!(sdram->cfg & 0x40000000) && (val & 0x40000000)) {
285                 sdram->status |= 0x40000000;
286             } else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000)) {
287                 sdram->status &= ~0x40000000;
288             }
289             sdram->cfg = val;
290             break;
291         case 0x24: /* SDRAM_STATUS */
292             /* Read-only register */
293             break;
294         case 0x30: /* SDRAM_RTR */
295             sdram->rtr = val & 0x3FF80000;
296             break;
297         case 0x34: /* SDRAM_PMIT */
298             sdram->pmit = (val & 0xF8000000) | 0x07C00000;
299             break;
300         case 0x40: /* SDRAM_B0CR */
301             sdram_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000);
302             break;
303         case 0x44: /* SDRAM_B1CR */
304             sdram_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000);
305             break;
306         case 0x48: /* SDRAM_B2CR */
307             sdram_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000);
308             break;
309         case 0x4C: /* SDRAM_B3CR */
310             sdram_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000);
311             break;
312         case 0x80: /* SDRAM_TR */
313             sdram->tr = val & 0x018FC01F;
314             break;
315         case 0x94: /* SDRAM_ECCCFG */
316             sdram->ecccfg = val & 0x00F00000;
317             break;
318         case 0x98: /* SDRAM_ECCESR */
319             val &= 0xFFF0F000;
320             if (sdram->eccesr == 0 && val != 0) {
321                 qemu_irq_raise(sdram->irq);
322             } else if (sdram->eccesr != 0 && val == 0) {
323                 qemu_irq_lower(sdram->irq);
324             }
325             sdram->eccesr = val;
326             break;
327         default: /* Error */
328             break;
329         }
330         break;
331     }
332 }
333 
334 static void sdram_reset(void *opaque)
335 {
336     ppc4xx_sdram_t *sdram;
337 
338     sdram = opaque;
339     sdram->addr = 0x00000000;
340     sdram->bear = 0x00000000;
341     sdram->besr0 = 0x00000000; /* No error */
342     sdram->besr1 = 0x00000000; /* No error */
343     sdram->cfg = 0x00000000;
344     sdram->ecccfg = 0x00000000; /* No ECC */
345     sdram->eccesr = 0x00000000; /* No error */
346     sdram->pmit = 0x07C00000;
347     sdram->rtr = 0x05F00000;
348     sdram->tr = 0x00854009;
349     /* We pre-initialize RAM banks */
350     sdram->status = 0x00000000;
351     sdram->cfg = 0x00800000;
352 }
353 
354 void ppc4xx_sdram_init(CPUPPCState *env, qemu_irq irq, int nbanks,
355                        MemoryRegion *ram_memories,
356                        hwaddr *ram_bases,
357                        hwaddr *ram_sizes,
358                        int do_init)
359 {
360     ppc4xx_sdram_t *sdram;
361 
362     sdram = g_new0(ppc4xx_sdram_t, 1);
363     sdram->irq = irq;
364     sdram->nbanks = nbanks;
365     sdram->ram_memories = ram_memories;
366     memset(sdram->ram_bases, 0, 4 * sizeof(hwaddr));
367     memcpy(sdram->ram_bases, ram_bases,
368            nbanks * sizeof(hwaddr));
369     memset(sdram->ram_sizes, 0, 4 * sizeof(hwaddr));
370     memcpy(sdram->ram_sizes, ram_sizes,
371            nbanks * sizeof(hwaddr));
372     qemu_register_reset(&sdram_reset, sdram);
373     ppc_dcr_register(env, SDRAM0_CFGADDR,
374                      sdram, &dcr_read_sdram, &dcr_write_sdram);
375     ppc_dcr_register(env, SDRAM0_CFGDATA,
376                      sdram, &dcr_read_sdram, &dcr_write_sdram);
377     if (do_init) {
378         sdram_map_bcr(sdram);
379     }
380 }
381 
382 /*
383  * Split RAM between SDRAM banks.
384  *
385  * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1]
386  * and must be 0-terminated.
387  *
388  * The 4xx SDRAM controller supports a small number of banks, and each bank
389  * must be one of a small set of sizes. The number of banks and the supported
390  * sizes varies by SoC.
391  */
392 void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks,
393                         MemoryRegion ram_memories[],
394                         hwaddr ram_bases[], hwaddr ram_sizes[],
395                         const ram_addr_t sdram_bank_sizes[])
396 {
397     ram_addr_t size_left = memory_region_size(ram);
398     ram_addr_t base = 0;
399     ram_addr_t bank_size;
400     int i;
401     int j;
402 
403     for (i = 0; i < nr_banks; i++) {
404         for (j = 0; sdram_bank_sizes[j] != 0; j++) {
405             bank_size = sdram_bank_sizes[j];
406             if (bank_size <= size_left) {
407                 char name[32];
408 
409                 ram_bases[i] = base;
410                 ram_sizes[i] = bank_size;
411                 base += bank_size;
412                 size_left -= bank_size;
413                 snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
414                 memory_region_init_alias(&ram_memories[i], NULL, name, ram,
415                                          ram_bases[i], ram_sizes[i]);
416                 break;
417             }
418         }
419         if (!size_left) {
420             /* No need to use the remaining banks. */
421             break;
422         }
423     }
424 
425     if (size_left) {
426         ram_addr_t used_size = memory_region_size(ram) - size_left;
427         GString *s = g_string_new(NULL);
428 
429         for (i = 0; sdram_bank_sizes[i]; i++) {
430             g_string_append_printf(s, "%" PRIi64 "%s",
431                                    sdram_bank_sizes[i] / MiB,
432                                    sdram_bank_sizes[i + 1] ? ", " : "");
433         }
434         error_report("at most %d bank%s of %s MiB each supported",
435                      nr_banks, nr_banks == 1 ? "" : "s", s->str);
436         error_printf("Possible valid RAM size: %" PRIi64 " MiB\n",
437             used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB);
438 
439         g_string_free(s, true);
440         exit(EXIT_FAILURE);
441     }
442 }
443 
444 /*****************************************************************************/
445 /* MAL */
446 
447 enum {
448     MAL0_CFG      = 0x180,
449     MAL0_ESR      = 0x181,
450     MAL0_IER      = 0x182,
451     MAL0_TXCASR   = 0x184,
452     MAL0_TXCARR   = 0x185,
453     MAL0_TXEOBISR = 0x186,
454     MAL0_TXDEIR   = 0x187,
455     MAL0_RXCASR   = 0x190,
456     MAL0_RXCARR   = 0x191,
457     MAL0_RXEOBISR = 0x192,
458     MAL0_RXDEIR   = 0x193,
459     MAL0_TXCTP0R  = 0x1A0,
460     MAL0_RXCTP0R  = 0x1C0,
461     MAL0_RCBS0    = 0x1E0,
462     MAL0_RCBS1    = 0x1E1,
463 };
464 
465 static void ppc4xx_mal_reset(DeviceState *dev)
466 {
467     Ppc4xxMalState *mal = PPC4xx_MAL(dev);
468 
469     mal->cfg = 0x0007C000;
470     mal->esr = 0x00000000;
471     mal->ier = 0x00000000;
472     mal->rxcasr = 0x00000000;
473     mal->rxdeir = 0x00000000;
474     mal->rxeobisr = 0x00000000;
475     mal->txcasr = 0x00000000;
476     mal->txdeir = 0x00000000;
477     mal->txeobisr = 0x00000000;
478 }
479 
480 static uint32_t dcr_read_mal(void *opaque, int dcrn)
481 {
482     Ppc4xxMalState *mal = opaque;
483     uint32_t ret;
484 
485     switch (dcrn) {
486     case MAL0_CFG:
487         ret = mal->cfg;
488         break;
489     case MAL0_ESR:
490         ret = mal->esr;
491         break;
492     case MAL0_IER:
493         ret = mal->ier;
494         break;
495     case MAL0_TXCASR:
496         ret = mal->txcasr;
497         break;
498     case MAL0_TXCARR:
499         ret = mal->txcarr;
500         break;
501     case MAL0_TXEOBISR:
502         ret = mal->txeobisr;
503         break;
504     case MAL0_TXDEIR:
505         ret = mal->txdeir;
506         break;
507     case MAL0_RXCASR:
508         ret = mal->rxcasr;
509         break;
510     case MAL0_RXCARR:
511         ret = mal->rxcarr;
512         break;
513     case MAL0_RXEOBISR:
514         ret = mal->rxeobisr;
515         break;
516     case MAL0_RXDEIR:
517         ret = mal->rxdeir;
518         break;
519     default:
520         ret = 0;
521         break;
522     }
523     if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) {
524         ret = mal->txctpr[dcrn - MAL0_TXCTP0R];
525     }
526     if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) {
527         ret = mal->rxctpr[dcrn - MAL0_RXCTP0R];
528     }
529     if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) {
530         ret = mal->rcbs[dcrn - MAL0_RCBS0];
531     }
532 
533     return ret;
534 }
535 
536 static void dcr_write_mal(void *opaque, int dcrn, uint32_t val)
537 {
538     Ppc4xxMalState *mal = opaque;
539 
540     switch (dcrn) {
541     case MAL0_CFG:
542         if (val & 0x80000000) {
543             ppc4xx_mal_reset(DEVICE(mal));
544         }
545         mal->cfg = val & 0x00FFC087;
546         break;
547     case MAL0_ESR:
548         /* Read/clear */
549         mal->esr &= ~val;
550         break;
551     case MAL0_IER:
552         mal->ier = val & 0x0000001F;
553         break;
554     case MAL0_TXCASR:
555         mal->txcasr = val & 0xF0000000;
556         break;
557     case MAL0_TXCARR:
558         mal->txcarr = val & 0xF0000000;
559         break;
560     case MAL0_TXEOBISR:
561         /* Read/clear */
562         mal->txeobisr &= ~val;
563         break;
564     case MAL0_TXDEIR:
565         /* Read/clear */
566         mal->txdeir &= ~val;
567         break;
568     case MAL0_RXCASR:
569         mal->rxcasr = val & 0xC0000000;
570         break;
571     case MAL0_RXCARR:
572         mal->rxcarr = val & 0xC0000000;
573         break;
574     case MAL0_RXEOBISR:
575         /* Read/clear */
576         mal->rxeobisr &= ~val;
577         break;
578     case MAL0_RXDEIR:
579         /* Read/clear */
580         mal->rxdeir &= ~val;
581         break;
582     }
583     if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) {
584         mal->txctpr[dcrn - MAL0_TXCTP0R] = val;
585     }
586     if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) {
587         mal->rxctpr[dcrn - MAL0_RXCTP0R] = val;
588     }
589     if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) {
590         mal->rcbs[dcrn - MAL0_RCBS0] = val & 0x000000FF;
591     }
592 }
593 
594 static void ppc4xx_mal_realize(DeviceState *dev, Error **errp)
595 {
596     Ppc4xxMalState *mal = PPC4xx_MAL(dev);
597     Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
598     int i;
599 
600     if (mal->txcnum > 32 || mal->rxcnum > 32) {
601         error_setg(errp, "invalid TXC/RXC number");
602         return;
603     }
604 
605     mal->txctpr = g_new0(uint32_t, mal->txcnum);
606     mal->rxctpr = g_new0(uint32_t, mal->rxcnum);
607     mal->rcbs = g_new0(uint32_t, mal->rxcnum);
608 
609     for (i = 0; i < ARRAY_SIZE(mal->irqs); i++) {
610         sysbus_init_irq(SYS_BUS_DEVICE(dev), &mal->irqs[i]);
611     }
612 
613     ppc4xx_dcr_register(dcr, MAL0_CFG, mal, &dcr_read_mal, &dcr_write_mal);
614     ppc4xx_dcr_register(dcr, MAL0_ESR, mal, &dcr_read_mal, &dcr_write_mal);
615     ppc4xx_dcr_register(dcr, MAL0_IER, mal, &dcr_read_mal, &dcr_write_mal);
616     ppc4xx_dcr_register(dcr, MAL0_TXCASR, mal, &dcr_read_mal, &dcr_write_mal);
617     ppc4xx_dcr_register(dcr, MAL0_TXCARR, mal, &dcr_read_mal, &dcr_write_mal);
618     ppc4xx_dcr_register(dcr, MAL0_TXEOBISR, mal, &dcr_read_mal, &dcr_write_mal);
619     ppc4xx_dcr_register(dcr, MAL0_TXDEIR, mal, &dcr_read_mal, &dcr_write_mal);
620     ppc4xx_dcr_register(dcr, MAL0_RXCASR, mal, &dcr_read_mal, &dcr_write_mal);
621     ppc4xx_dcr_register(dcr, MAL0_RXCARR, mal, &dcr_read_mal, &dcr_write_mal);
622     ppc4xx_dcr_register(dcr, MAL0_RXEOBISR, mal, &dcr_read_mal, &dcr_write_mal);
623     ppc4xx_dcr_register(dcr, MAL0_RXDEIR, mal, &dcr_read_mal, &dcr_write_mal);
624     for (i = 0; i < mal->txcnum; i++) {
625         ppc4xx_dcr_register(dcr, MAL0_TXCTP0R + i,
626                             mal, &dcr_read_mal, &dcr_write_mal);
627     }
628     for (i = 0; i < mal->rxcnum; i++) {
629         ppc4xx_dcr_register(dcr, MAL0_RXCTP0R + i,
630                             mal, &dcr_read_mal, &dcr_write_mal);
631     }
632     for (i = 0; i < mal->rxcnum; i++) {
633         ppc4xx_dcr_register(dcr, MAL0_RCBS0 + i,
634                             mal, &dcr_read_mal, &dcr_write_mal);
635     }
636 }
637 
638 static void ppc4xx_mal_finalize(Object *obj)
639 {
640     Ppc4xxMalState *mal = PPC4xx_MAL(obj);
641 
642     g_free(mal->rcbs);
643     g_free(mal->rxctpr);
644     g_free(mal->txctpr);
645 }
646 
647 static Property ppc4xx_mal_properties[] = {
648     DEFINE_PROP_UINT8("txc-num", Ppc4xxMalState, txcnum, 0),
649     DEFINE_PROP_UINT8("rxc-num", Ppc4xxMalState, rxcnum, 0),
650     DEFINE_PROP_END_OF_LIST(),
651 };
652 
653 static void ppc4xx_mal_class_init(ObjectClass *oc, void *data)
654 {
655     DeviceClass *dc = DEVICE_CLASS(oc);
656 
657     dc->realize = ppc4xx_mal_realize;
658     dc->reset = ppc4xx_mal_reset;
659     /* Reason: only works as function of a ppc4xx SoC */
660     dc->user_creatable = false;
661     device_class_set_props(dc, ppc4xx_mal_properties);
662 }
663 
664 /*****************************************************************************/
665 /* Peripheral local bus arbitrer */
666 enum {
667     PLB3A0_ACR = 0x077,
668     PLB4A0_ACR = 0x081,
669     PLB0_BESR  = 0x084,
670     PLB0_BEAR  = 0x086,
671     PLB0_ACR   = 0x087,
672     PLB4A1_ACR = 0x089,
673 };
674 
675 static uint32_t dcr_read_plb(void *opaque, int dcrn)
676 {
677     Ppc4xxPlbState *plb = opaque;
678     uint32_t ret;
679 
680     switch (dcrn) {
681     case PLB0_ACR:
682         ret = plb->acr;
683         break;
684     case PLB0_BEAR:
685         ret = plb->bear;
686         break;
687     case PLB0_BESR:
688         ret = plb->besr;
689         break;
690     default:
691         /* Avoid gcc warning */
692         ret = 0;
693         break;
694     }
695 
696     return ret;
697 }
698 
699 static void dcr_write_plb(void *opaque, int dcrn, uint32_t val)
700 {
701     Ppc4xxPlbState *plb = opaque;
702 
703     switch (dcrn) {
704     case PLB0_ACR:
705         /*
706          * We don't care about the actual parameters written as
707          * we don't manage any priorities on the bus
708          */
709         plb->acr = val & 0xF8000000;
710         break;
711     case PLB0_BEAR:
712         /* Read only */
713         break;
714     case PLB0_BESR:
715         /* Write-clear */
716         plb->besr &= ~val;
717         break;
718     }
719 }
720 
721 static void ppc405_plb_reset(DeviceState *dev)
722 {
723     Ppc4xxPlbState *plb = PPC4xx_PLB(dev);
724 
725     plb->acr = 0x00000000;
726     plb->bear = 0x00000000;
727     plb->besr = 0x00000000;
728 }
729 
730 static void ppc405_plb_realize(DeviceState *dev, Error **errp)
731 {
732     Ppc4xxPlbState *plb = PPC4xx_PLB(dev);
733     Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
734 
735     ppc4xx_dcr_register(dcr, PLB3A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
736     ppc4xx_dcr_register(dcr, PLB4A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
737     ppc4xx_dcr_register(dcr, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
738     ppc4xx_dcr_register(dcr, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);
739     ppc4xx_dcr_register(dcr, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);
740     ppc4xx_dcr_register(dcr, PLB4A1_ACR, plb, &dcr_read_plb, &dcr_write_plb);
741 }
742 
743 static void ppc405_plb_class_init(ObjectClass *oc, void *data)
744 {
745     DeviceClass *dc = DEVICE_CLASS(oc);
746 
747     dc->realize = ppc405_plb_realize;
748     dc->reset = ppc405_plb_reset;
749     /* Reason: only works as function of a ppc4xx SoC */
750     dc->user_creatable = false;
751 }
752 
753 /*****************************************************************************/
754 /* Peripheral controller */
755 enum {
756     EBC0_CFGADDR = 0x012,
757     EBC0_CFGDATA = 0x013,
758 };
759 
760 static uint32_t dcr_read_ebc(void *opaque, int dcrn)
761 {
762     Ppc4xxEbcState *ebc = opaque;
763     uint32_t ret;
764 
765     switch (dcrn) {
766     case EBC0_CFGADDR:
767         ret = ebc->addr;
768         break;
769     case EBC0_CFGDATA:
770         switch (ebc->addr) {
771         case 0x00: /* B0CR */
772             ret = ebc->bcr[0];
773             break;
774         case 0x01: /* B1CR */
775             ret = ebc->bcr[1];
776             break;
777         case 0x02: /* B2CR */
778             ret = ebc->bcr[2];
779             break;
780         case 0x03: /* B3CR */
781             ret = ebc->bcr[3];
782             break;
783         case 0x04: /* B4CR */
784             ret = ebc->bcr[4];
785             break;
786         case 0x05: /* B5CR */
787             ret = ebc->bcr[5];
788             break;
789         case 0x06: /* B6CR */
790             ret = ebc->bcr[6];
791             break;
792         case 0x07: /* B7CR */
793             ret = ebc->bcr[7];
794             break;
795         case 0x10: /* B0AP */
796             ret = ebc->bap[0];
797             break;
798         case 0x11: /* B1AP */
799             ret = ebc->bap[1];
800             break;
801         case 0x12: /* B2AP */
802             ret = ebc->bap[2];
803             break;
804         case 0x13: /* B3AP */
805             ret = ebc->bap[3];
806             break;
807         case 0x14: /* B4AP */
808             ret = ebc->bap[4];
809             break;
810         case 0x15: /* B5AP */
811             ret = ebc->bap[5];
812             break;
813         case 0x16: /* B6AP */
814             ret = ebc->bap[6];
815             break;
816         case 0x17: /* B7AP */
817             ret = ebc->bap[7];
818             break;
819         case 0x20: /* BEAR */
820             ret = ebc->bear;
821             break;
822         case 0x21: /* BESR0 */
823             ret = ebc->besr0;
824             break;
825         case 0x22: /* BESR1 */
826             ret = ebc->besr1;
827             break;
828         case 0x23: /* CFG */
829             ret = ebc->cfg;
830             break;
831         default:
832             ret = 0x00000000;
833             break;
834         }
835         break;
836     default:
837         ret = 0x00000000;
838         break;
839     }
840 
841     return ret;
842 }
843 
844 static void dcr_write_ebc(void *opaque, int dcrn, uint32_t val)
845 {
846     Ppc4xxEbcState *ebc = opaque;
847 
848     switch (dcrn) {
849     case EBC0_CFGADDR:
850         ebc->addr = val;
851         break;
852     case EBC0_CFGDATA:
853         switch (ebc->addr) {
854         case 0x00: /* B0CR */
855             break;
856         case 0x01: /* B1CR */
857             break;
858         case 0x02: /* B2CR */
859             break;
860         case 0x03: /* B3CR */
861             break;
862         case 0x04: /* B4CR */
863             break;
864         case 0x05: /* B5CR */
865             break;
866         case 0x06: /* B6CR */
867             break;
868         case 0x07: /* B7CR */
869             break;
870         case 0x10: /* B0AP */
871             break;
872         case 0x11: /* B1AP */
873             break;
874         case 0x12: /* B2AP */
875             break;
876         case 0x13: /* B3AP */
877             break;
878         case 0x14: /* B4AP */
879             break;
880         case 0x15: /* B5AP */
881             break;
882         case 0x16: /* B6AP */
883             break;
884         case 0x17: /* B7AP */
885             break;
886         case 0x20: /* BEAR */
887             break;
888         case 0x21: /* BESR0 */
889             break;
890         case 0x22: /* BESR1 */
891             break;
892         case 0x23: /* CFG */
893             break;
894         default:
895             break;
896         }
897         break;
898     default:
899         break;
900     }
901 }
902 
903 static void ppc405_ebc_reset(DeviceState *dev)
904 {
905     Ppc4xxEbcState *ebc = PPC4xx_EBC(dev);
906     int i;
907 
908     ebc->addr = 0x00000000;
909     ebc->bap[0] = 0x7F8FFE80;
910     ebc->bcr[0] = 0xFFE28000;
911     for (i = 0; i < 8; i++) {
912         ebc->bap[i] = 0x00000000;
913         ebc->bcr[i] = 0x00000000;
914     }
915     ebc->besr0 = 0x00000000;
916     ebc->besr1 = 0x00000000;
917     ebc->cfg = 0x80400000;
918 }
919 
920 static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
921 {
922     Ppc4xxEbcState *ebc = PPC4xx_EBC(dev);
923     Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
924 
925     ppc4xx_dcr_register(dcr, EBC0_CFGADDR, ebc, &dcr_read_ebc, &dcr_write_ebc);
926     ppc4xx_dcr_register(dcr, EBC0_CFGDATA, ebc, &dcr_read_ebc, &dcr_write_ebc);
927 }
928 
929 static void ppc405_ebc_class_init(ObjectClass *oc, void *data)
930 {
931     DeviceClass *dc = DEVICE_CLASS(oc);
932 
933     dc->realize = ppc405_ebc_realize;
934     dc->reset = ppc405_ebc_reset;
935     /* Reason: only works as function of a ppc4xx SoC */
936     dc->user_creatable = false;
937 }
938 
939 /* PPC4xx_DCR_DEVICE */
940 
941 void ppc4xx_dcr_register(Ppc4xxDcrDeviceState *dev, int dcrn, void *opaque,
942                          dcr_read_cb dcr_read, dcr_write_cb dcr_write)
943 {
944     assert(dev->cpu);
945     ppc_dcr_register(&dev->cpu->env, dcrn, opaque, dcr_read, dcr_write);
946 }
947 
948 bool ppc4xx_dcr_realize(Ppc4xxDcrDeviceState *dev, PowerPCCPU *cpu,
949                         Error **errp)
950 {
951     object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort);
952     return sysbus_realize(SYS_BUS_DEVICE(dev), errp);
953 }
954 
955 static Property ppc4xx_dcr_properties[] = {
956     DEFINE_PROP_LINK("cpu", Ppc4xxDcrDeviceState, cpu, TYPE_POWERPC_CPU,
957                      PowerPCCPU *),
958     DEFINE_PROP_END_OF_LIST(),
959 };
960 
961 static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data)
962 {
963     DeviceClass *dc = DEVICE_CLASS(oc);
964 
965     device_class_set_props(dc, ppc4xx_dcr_properties);
966 }
967 
968 static const TypeInfo ppc4xx_types[] = {
969     {
970         .name           = TYPE_PPC4xx_MAL,
971         .parent         = TYPE_PPC4xx_DCR_DEVICE,
972         .instance_size  = sizeof(Ppc4xxMalState),
973         .instance_finalize = ppc4xx_mal_finalize,
974         .class_init     = ppc4xx_mal_class_init,
975     }, {
976         .name           = TYPE_PPC4xx_PLB,
977         .parent         = TYPE_PPC4xx_DCR_DEVICE,
978         .instance_size  = sizeof(Ppc4xxPlbState),
979         .class_init     = ppc405_plb_class_init,
980     }, {
981         .name           = TYPE_PPC4xx_EBC,
982         .parent         = TYPE_PPC4xx_DCR_DEVICE,
983         .instance_size  = sizeof(Ppc4xxEbcState),
984         .class_init     = ppc405_ebc_class_init,
985     }, {
986         .name           = TYPE_PPC4xx_DCR_DEVICE,
987         .parent         = TYPE_SYS_BUS_DEVICE,
988         .instance_size  = sizeof(Ppc4xxDcrDeviceState),
989         .class_init     = ppc4xx_dcr_class_init,
990         .abstract       = true,
991     }
992 };
993 
994 DEFINE_TYPES(ppc4xx_types)
995