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