2 * QEMU PowerPC 4xx embedded processors shared devices emulation
4 * Copyright (c) 2007 Jocelyn Mayer
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
25 #include "qemu/osdep.h"
26 #include "qemu/units.h"
27 #include "sysemu/reset.h"
30 #include "hw/ppc/ppc.h"
31 #include "hw/ppc/ppc4xx.h"
32 #include "hw/qdev-properties.h"
34 #include "exec/address-spaces.h"
35 #include "qemu/error-report.h"
36 #include "qapi/error.h"
39 /*****************************************************************************/
40 /* SDRAM controller */
42 SDRAM0_CFGADDR
= 0x010,
43 SDRAM0_CFGDATA
= 0x011,
47 * XXX: TOFIX: some patches have made this code become inconsistent:
48 * there are type inconsistencies, mixing hwaddr, target_ulong
51 static uint32_t sdram_ddr_bcr(hwaddr ram_base
, hwaddr ram_size
)
78 qemu_log_mask(LOG_GUEST_ERROR
,
79 "%s: invalid RAM size 0x%" HWADDR_PRIx
"\n", __func__
,
83 bcr
|= ram_base
& 0xFF800000;
89 static inline hwaddr
sdram_ddr_base(uint32_t bcr
)
91 return bcr
& 0xFF800000;
94 static target_ulong
sdram_ddr_size(uint32_t bcr
)
99 sh
= (bcr
>> 17) & 0x7;
103 size
= (4 * MiB
) << sh
;
109 static void sdram_ddr_set_bcr(Ppc4xxSdramDdrState
*sdram
, int i
,
110 uint32_t bcr
, int enabled
)
112 if (sdram
->bank
[i
].bcr
& 1) {
114 trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram
->bank
[i
].bcr
),
115 sdram_ddr_size(sdram
->bank
[i
].bcr
));
116 memory_region_del_subregion(get_system_memory(),
117 &sdram
->bank
[i
].container
);
118 memory_region_del_subregion(&sdram
->bank
[i
].container
,
119 &sdram
->bank
[i
].ram
);
120 object_unparent(OBJECT(&sdram
->bank
[i
].container
));
122 sdram
->bank
[i
].bcr
= bcr
& 0xFFDEE001;
123 if (enabled
&& (bcr
& 1)) {
124 trace_ppc4xx_sdram_map(sdram_ddr_base(bcr
), sdram_ddr_size(bcr
));
125 memory_region_init(&sdram
->bank
[i
].container
, NULL
, "sdram-container",
126 sdram_ddr_size(bcr
));
127 memory_region_add_subregion(&sdram
->bank
[i
].container
, 0,
128 &sdram
->bank
[i
].ram
);
129 memory_region_add_subregion(get_system_memory(),
131 &sdram
->bank
[i
].container
);
135 static void sdram_ddr_map_bcr(Ppc4xxSdramDdrState
*sdram
)
139 for (i
= 0; i
< sdram
->nbanks
; i
++) {
140 if (sdram
->bank
[i
].size
!= 0) {
141 sdram_ddr_set_bcr(sdram
, i
, sdram_ddr_bcr(sdram
->bank
[i
].base
,
142 sdram
->bank
[i
].size
), 1);
144 sdram_ddr_set_bcr(sdram
, i
, 0, 0);
149 static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState
*sdram
)
153 for (i
= 0; i
< sdram
->nbanks
; i
++) {
154 trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram
->bank
[i
].bcr
),
155 sdram_ddr_size(sdram
->bank
[i
].bcr
));
156 memory_region_del_subregion(get_system_memory(),
157 &sdram
->bank
[i
].ram
);
161 static uint32_t sdram_ddr_dcr_read(void *opaque
, int dcrn
)
163 Ppc4xxSdramDdrState
*sdram
= opaque
;
171 switch (sdram
->addr
) {
172 case 0x00: /* SDRAM_BESR0 */
175 case 0x08: /* SDRAM_BESR1 */
178 case 0x10: /* SDRAM_BEAR */
181 case 0x20: /* SDRAM_CFG */
184 case 0x24: /* SDRAM_STATUS */
187 case 0x30: /* SDRAM_RTR */
190 case 0x34: /* SDRAM_PMIT */
193 case 0x40: /* SDRAM_B0CR */
194 ret
= sdram
->bank
[0].bcr
;
196 case 0x44: /* SDRAM_B1CR */
197 ret
= sdram
->bank
[1].bcr
;
199 case 0x48: /* SDRAM_B2CR */
200 ret
= sdram
->bank
[2].bcr
;
202 case 0x4C: /* SDRAM_B3CR */
203 ret
= sdram
->bank
[3].bcr
;
205 case 0x80: /* SDRAM_TR */
208 case 0x94: /* SDRAM_ECCCFG */
211 case 0x98: /* SDRAM_ECCESR */
220 /* Avoid gcc warning */
228 static void sdram_ddr_dcr_write(void *opaque
, int dcrn
, uint32_t val
)
230 Ppc4xxSdramDdrState
*sdram
= opaque
;
237 switch (sdram
->addr
) {
238 case 0x00: /* SDRAM_BESR0 */
239 sdram
->besr0
&= ~val
;
241 case 0x08: /* SDRAM_BESR1 */
242 sdram
->besr1
&= ~val
;
244 case 0x10: /* SDRAM_BEAR */
247 case 0x20: /* SDRAM_CFG */
249 if (!(sdram
->cfg
& 0x80000000) && (val
& 0x80000000)) {
250 trace_ppc4xx_sdram_enable("enable");
251 /* validate all RAM mappings */
252 sdram_ddr_map_bcr(sdram
);
253 sdram
->status
&= ~0x80000000;
254 } else if ((sdram
->cfg
& 0x80000000) && !(val
& 0x80000000)) {
255 trace_ppc4xx_sdram_enable("disable");
256 /* invalidate all RAM mappings */
257 sdram_ddr_unmap_bcr(sdram
);
258 sdram
->status
|= 0x80000000;
260 if (!(sdram
->cfg
& 0x40000000) && (val
& 0x40000000)) {
261 sdram
->status
|= 0x40000000;
262 } else if ((sdram
->cfg
& 0x40000000) && !(val
& 0x40000000)) {
263 sdram
->status
&= ~0x40000000;
267 case 0x24: /* SDRAM_STATUS */
268 /* Read-only register */
270 case 0x30: /* SDRAM_RTR */
271 sdram
->rtr
= val
& 0x3FF80000;
273 case 0x34: /* SDRAM_PMIT */
274 sdram
->pmit
= (val
& 0xF8000000) | 0x07C00000;
276 case 0x40: /* SDRAM_B0CR */
277 sdram_ddr_set_bcr(sdram
, 0, val
, sdram
->cfg
& 0x80000000);
279 case 0x44: /* SDRAM_B1CR */
280 sdram_ddr_set_bcr(sdram
, 1, val
, sdram
->cfg
& 0x80000000);
282 case 0x48: /* SDRAM_B2CR */
283 sdram_ddr_set_bcr(sdram
, 2, val
, sdram
->cfg
& 0x80000000);
285 case 0x4C: /* SDRAM_B3CR */
286 sdram_ddr_set_bcr(sdram
, 3, val
, sdram
->cfg
& 0x80000000);
288 case 0x80: /* SDRAM_TR */
289 sdram
->tr
= val
& 0x018FC01F;
291 case 0x94: /* SDRAM_ECCCFG */
292 sdram
->ecccfg
= val
& 0x00F00000;
294 case 0x98: /* SDRAM_ECCESR */
296 if (sdram
->eccesr
== 0 && val
!= 0) {
297 qemu_irq_raise(sdram
->irq
);
298 } else if (sdram
->eccesr
!= 0 && val
== 0) {
299 qemu_irq_lower(sdram
->irq
);
310 static void ppc4xx_sdram_ddr_reset(DeviceState
*dev
)
312 Ppc4xxSdramDdrState
*sdram
= PPC4xx_SDRAM_DDR(dev
);
316 sdram
->besr0
= 0; /* No error */
317 sdram
->besr1
= 0; /* No error */
319 sdram
->ecccfg
= 0; /* No ECC */
320 sdram
->eccesr
= 0; /* No error */
321 sdram
->pmit
= 0x07C00000;
322 sdram
->rtr
= 0x05F00000;
323 sdram
->tr
= 0x00854009;
324 /* We pre-initialize RAM banks */
326 sdram
->cfg
= 0x00800000;
329 static void ppc4xx_sdram_ddr_realize(DeviceState
*dev
, Error
**errp
)
331 Ppc4xxSdramDdrState
*s
= PPC4xx_SDRAM_DDR(dev
);
332 Ppc4xxDcrDeviceState
*dcr
= PPC4xx_DCR_DEVICE(dev
);
333 const ram_addr_t valid_bank_sizes
[] = {
334 256 * MiB
, 128 * MiB
, 64 * MiB
, 32 * MiB
, 16 * MiB
, 8 * MiB
, 4 * MiB
, 0
337 if (s
->nbanks
< 1 || s
->nbanks
> 4) {
338 error_setg(errp
, "Invalid number of RAM banks");
342 error_setg(errp
, "Missing dram memory region");
345 ppc4xx_sdram_banks(s
->dram_mr
, s
->nbanks
, s
->bank
, valid_bank_sizes
);
347 sysbus_init_irq(SYS_BUS_DEVICE(dev
), &s
->irq
);
349 ppc4xx_dcr_register(dcr
, SDRAM0_CFGADDR
,
350 s
, &sdram_ddr_dcr_read
, &sdram_ddr_dcr_write
);
351 ppc4xx_dcr_register(dcr
, SDRAM0_CFGDATA
,
352 s
, &sdram_ddr_dcr_read
, &sdram_ddr_dcr_write
);
355 static Property ppc4xx_sdram_ddr_props
[] = {
356 DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState
, dram_mr
, TYPE_MEMORY_REGION
,
358 DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState
, nbanks
, 4),
359 DEFINE_PROP_END_OF_LIST(),
362 static void ppc4xx_sdram_ddr_class_init(ObjectClass
*oc
, void *data
)
364 DeviceClass
*dc
= DEVICE_CLASS(oc
);
366 dc
->realize
= ppc4xx_sdram_ddr_realize
;
367 dc
->reset
= ppc4xx_sdram_ddr_reset
;
368 /* Reason: only works as function of a ppc4xx SoC */
369 dc
->user_creatable
= false;
370 device_class_set_props(dc
, ppc4xx_sdram_ddr_props
);
373 void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState
*s
)
375 sdram_ddr_dcr_write(s
, SDRAM0_CFGADDR
, 0x20);
376 sdram_ddr_dcr_write(s
, SDRAM0_CFGDATA
, 0x80000000);
380 * Split RAM between SDRAM banks.
382 * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1]
383 * and must be 0-terminated.
385 * The 4xx SDRAM controller supports a small number of banks, and each bank
386 * must be one of a small set of sizes. The number of banks and the supported
387 * sizes varies by SoC.
389 void ppc4xx_sdram_banks(MemoryRegion
*ram
, int nr_banks
,
390 Ppc4xxSdramBank ram_banks
[],
391 const ram_addr_t sdram_bank_sizes
[])
393 ram_addr_t size_left
= memory_region_size(ram
);
395 ram_addr_t bank_size
;
399 for (i
= 0; i
< nr_banks
; i
++) {
400 for (j
= 0; sdram_bank_sizes
[j
] != 0; j
++) {
401 bank_size
= sdram_bank_sizes
[j
];
402 if (bank_size
<= size_left
) {
405 ram_banks
[i
].base
= base
;
406 ram_banks
[i
].size
= bank_size
;
408 size_left
-= bank_size
;
409 snprintf(name
, sizeof(name
), "ppc4xx.sdram%d", i
);
410 memory_region_init_alias(&ram_banks
[i
].ram
, NULL
, name
, ram
,
411 ram_banks
[i
].base
, ram_banks
[i
].size
);
416 /* No need to use the remaining banks. */
422 ram_addr_t used_size
= memory_region_size(ram
) - size_left
;
423 GString
*s
= g_string_new(NULL
);
425 for (i
= 0; sdram_bank_sizes
[i
]; i
++) {
426 g_string_append_printf(s
, "%" PRIi64
"%s",
427 sdram_bank_sizes
[i
] / MiB
,
428 sdram_bank_sizes
[i
+ 1] ? ", " : "");
430 error_report("at most %d bank%s of %s MiB each supported",
431 nr_banks
, nr_banks
== 1 ? "" : "s", s
->str
);
432 error_printf("Possible valid RAM size: %" PRIi64
" MiB\n",
433 used_size
? used_size
/ MiB
: sdram_bank_sizes
[i
- 1] / MiB
);
435 g_string_free(s
, true);
440 /*****************************************************************************/
449 MAL0_TXEOBISR
= 0x186,
453 MAL0_RXEOBISR
= 0x192,
455 MAL0_TXCTP0R
= 0x1A0,
456 MAL0_RXCTP0R
= 0x1C0,
461 static void ppc4xx_mal_reset(DeviceState
*dev
)
463 Ppc4xxMalState
*mal
= PPC4xx_MAL(dev
);
465 mal
->cfg
= 0x0007C000;
466 mal
->esr
= 0x00000000;
467 mal
->ier
= 0x00000000;
468 mal
->rxcasr
= 0x00000000;
469 mal
->rxdeir
= 0x00000000;
470 mal
->rxeobisr
= 0x00000000;
471 mal
->txcasr
= 0x00000000;
472 mal
->txdeir
= 0x00000000;
473 mal
->txeobisr
= 0x00000000;
476 static uint32_t dcr_read_mal(void *opaque
, int dcrn
)
478 Ppc4xxMalState
*mal
= opaque
;
519 if (dcrn
>= MAL0_TXCTP0R
&& dcrn
< MAL0_TXCTP0R
+ mal
->txcnum
) {
520 ret
= mal
->txctpr
[dcrn
- MAL0_TXCTP0R
];
522 if (dcrn
>= MAL0_RXCTP0R
&& dcrn
< MAL0_RXCTP0R
+ mal
->rxcnum
) {
523 ret
= mal
->rxctpr
[dcrn
- MAL0_RXCTP0R
];
525 if (dcrn
>= MAL0_RCBS0
&& dcrn
< MAL0_RCBS0
+ mal
->rxcnum
) {
526 ret
= mal
->rcbs
[dcrn
- MAL0_RCBS0
];
532 static void dcr_write_mal(void *opaque
, int dcrn
, uint32_t val
)
534 Ppc4xxMalState
*mal
= opaque
;
538 if (val
& 0x80000000) {
539 ppc4xx_mal_reset(DEVICE(mal
));
541 mal
->cfg
= val
& 0x00FFC087;
548 mal
->ier
= val
& 0x0000001F;
551 mal
->txcasr
= val
& 0xF0000000;
554 mal
->txcarr
= val
& 0xF0000000;
558 mal
->txeobisr
&= ~val
;
565 mal
->rxcasr
= val
& 0xC0000000;
568 mal
->rxcarr
= val
& 0xC0000000;
572 mal
->rxeobisr
&= ~val
;
579 if (dcrn
>= MAL0_TXCTP0R
&& dcrn
< MAL0_TXCTP0R
+ mal
->txcnum
) {
580 mal
->txctpr
[dcrn
- MAL0_TXCTP0R
] = val
;
582 if (dcrn
>= MAL0_RXCTP0R
&& dcrn
< MAL0_RXCTP0R
+ mal
->rxcnum
) {
583 mal
->rxctpr
[dcrn
- MAL0_RXCTP0R
] = val
;
585 if (dcrn
>= MAL0_RCBS0
&& dcrn
< MAL0_RCBS0
+ mal
->rxcnum
) {
586 mal
->rcbs
[dcrn
- MAL0_RCBS0
] = val
& 0x000000FF;
590 static void ppc4xx_mal_realize(DeviceState
*dev
, Error
**errp
)
592 Ppc4xxMalState
*mal
= PPC4xx_MAL(dev
);
593 Ppc4xxDcrDeviceState
*dcr
= PPC4xx_DCR_DEVICE(dev
);
596 if (mal
->txcnum
> 32 || mal
->rxcnum
> 32) {
597 error_setg(errp
, "invalid TXC/RXC number");
601 mal
->txctpr
= g_new0(uint32_t, mal
->txcnum
);
602 mal
->rxctpr
= g_new0(uint32_t, mal
->rxcnum
);
603 mal
->rcbs
= g_new0(uint32_t, mal
->rxcnum
);
605 for (i
= 0; i
< ARRAY_SIZE(mal
->irqs
); i
++) {
606 sysbus_init_irq(SYS_BUS_DEVICE(dev
), &mal
->irqs
[i
]);
609 ppc4xx_dcr_register(dcr
, MAL0_CFG
, mal
, &dcr_read_mal
, &dcr_write_mal
);
610 ppc4xx_dcr_register(dcr
, MAL0_ESR
, mal
, &dcr_read_mal
, &dcr_write_mal
);
611 ppc4xx_dcr_register(dcr
, MAL0_IER
, mal
, &dcr_read_mal
, &dcr_write_mal
);
612 ppc4xx_dcr_register(dcr
, MAL0_TXCASR
, mal
, &dcr_read_mal
, &dcr_write_mal
);
613 ppc4xx_dcr_register(dcr
, MAL0_TXCARR
, mal
, &dcr_read_mal
, &dcr_write_mal
);
614 ppc4xx_dcr_register(dcr
, MAL0_TXEOBISR
, mal
, &dcr_read_mal
, &dcr_write_mal
);
615 ppc4xx_dcr_register(dcr
, MAL0_TXDEIR
, mal
, &dcr_read_mal
, &dcr_write_mal
);
616 ppc4xx_dcr_register(dcr
, MAL0_RXCASR
, mal
, &dcr_read_mal
, &dcr_write_mal
);
617 ppc4xx_dcr_register(dcr
, MAL0_RXCARR
, mal
, &dcr_read_mal
, &dcr_write_mal
);
618 ppc4xx_dcr_register(dcr
, MAL0_RXEOBISR
, mal
, &dcr_read_mal
, &dcr_write_mal
);
619 ppc4xx_dcr_register(dcr
, MAL0_RXDEIR
, mal
, &dcr_read_mal
, &dcr_write_mal
);
620 for (i
= 0; i
< mal
->txcnum
; i
++) {
621 ppc4xx_dcr_register(dcr
, MAL0_TXCTP0R
+ i
,
622 mal
, &dcr_read_mal
, &dcr_write_mal
);
624 for (i
= 0; i
< mal
->rxcnum
; i
++) {
625 ppc4xx_dcr_register(dcr
, MAL0_RXCTP0R
+ i
,
626 mal
, &dcr_read_mal
, &dcr_write_mal
);
628 for (i
= 0; i
< mal
->rxcnum
; i
++) {
629 ppc4xx_dcr_register(dcr
, MAL0_RCBS0
+ i
,
630 mal
, &dcr_read_mal
, &dcr_write_mal
);
634 static void ppc4xx_mal_finalize(Object
*obj
)
636 Ppc4xxMalState
*mal
= PPC4xx_MAL(obj
);
643 static Property ppc4xx_mal_properties
[] = {
644 DEFINE_PROP_UINT8("txc-num", Ppc4xxMalState
, txcnum
, 0),
645 DEFINE_PROP_UINT8("rxc-num", Ppc4xxMalState
, rxcnum
, 0),
646 DEFINE_PROP_END_OF_LIST(),
649 static void ppc4xx_mal_class_init(ObjectClass
*oc
, void *data
)
651 DeviceClass
*dc
= DEVICE_CLASS(oc
);
653 dc
->realize
= ppc4xx_mal_realize
;
654 dc
->reset
= ppc4xx_mal_reset
;
655 /* Reason: only works as function of a ppc4xx SoC */
656 dc
->user_creatable
= false;
657 device_class_set_props(dc
, ppc4xx_mal_properties
);
660 /*****************************************************************************/
661 /* Peripheral local bus arbitrer */
671 static uint32_t dcr_read_plb(void *opaque
, int dcrn
)
673 Ppc4xxPlbState
*plb
= opaque
;
687 /* Avoid gcc warning */
695 static void dcr_write_plb(void *opaque
, int dcrn
, uint32_t val
)
697 Ppc4xxPlbState
*plb
= opaque
;
702 * We don't care about the actual parameters written as
703 * we don't manage any priorities on the bus
705 plb
->acr
= val
& 0xF8000000;
717 static void ppc405_plb_reset(DeviceState
*dev
)
719 Ppc4xxPlbState
*plb
= PPC4xx_PLB(dev
);
721 plb
->acr
= 0x00000000;
722 plb
->bear
= 0x00000000;
723 plb
->besr
= 0x00000000;
726 static void ppc405_plb_realize(DeviceState
*dev
, Error
**errp
)
728 Ppc4xxPlbState
*plb
= PPC4xx_PLB(dev
);
729 Ppc4xxDcrDeviceState
*dcr
= PPC4xx_DCR_DEVICE(dev
);
731 ppc4xx_dcr_register(dcr
, PLB3A0_ACR
, plb
, &dcr_read_plb
, &dcr_write_plb
);
732 ppc4xx_dcr_register(dcr
, PLB4A0_ACR
, plb
, &dcr_read_plb
, &dcr_write_plb
);
733 ppc4xx_dcr_register(dcr
, PLB0_ACR
, plb
, &dcr_read_plb
, &dcr_write_plb
);
734 ppc4xx_dcr_register(dcr
, PLB0_BEAR
, plb
, &dcr_read_plb
, &dcr_write_plb
);
735 ppc4xx_dcr_register(dcr
, PLB0_BESR
, plb
, &dcr_read_plb
, &dcr_write_plb
);
736 ppc4xx_dcr_register(dcr
, PLB4A1_ACR
, plb
, &dcr_read_plb
, &dcr_write_plb
);
739 static void ppc405_plb_class_init(ObjectClass
*oc
, void *data
)
741 DeviceClass
*dc
= DEVICE_CLASS(oc
);
743 dc
->realize
= ppc405_plb_realize
;
744 dc
->reset
= ppc405_plb_reset
;
745 /* Reason: only works as function of a ppc4xx SoC */
746 dc
->user_creatable
= false;
749 /*****************************************************************************/
750 /* Peripheral controller */
752 EBC0_CFGADDR
= 0x012,
753 EBC0_CFGDATA
= 0x013,
756 static uint32_t dcr_read_ebc(void *opaque
, int dcrn
)
758 Ppc4xxEbcState
*ebc
= opaque
;
767 case 0x00: /* B0CR */
770 case 0x01: /* B1CR */
773 case 0x02: /* B2CR */
776 case 0x03: /* B3CR */
779 case 0x04: /* B4CR */
782 case 0x05: /* B5CR */
785 case 0x06: /* B6CR */
788 case 0x07: /* B7CR */
791 case 0x10: /* B0AP */
794 case 0x11: /* B1AP */
797 case 0x12: /* B2AP */
800 case 0x13: /* B3AP */
803 case 0x14: /* B4AP */
806 case 0x15: /* B5AP */
809 case 0x16: /* B6AP */
812 case 0x17: /* B7AP */
815 case 0x20: /* BEAR */
818 case 0x21: /* BESR0 */
821 case 0x22: /* BESR1 */
840 static void dcr_write_ebc(void *opaque
, int dcrn
, uint32_t val
)
842 Ppc4xxEbcState
*ebc
= opaque
;
850 case 0x00: /* B0CR */
852 case 0x01: /* B1CR */
854 case 0x02: /* B2CR */
856 case 0x03: /* B3CR */
858 case 0x04: /* B4CR */
860 case 0x05: /* B5CR */
862 case 0x06: /* B6CR */
864 case 0x07: /* B7CR */
866 case 0x10: /* B0AP */
868 case 0x11: /* B1AP */
870 case 0x12: /* B2AP */
872 case 0x13: /* B3AP */
874 case 0x14: /* B4AP */
876 case 0x15: /* B5AP */
878 case 0x16: /* B6AP */
880 case 0x17: /* B7AP */
882 case 0x20: /* BEAR */
884 case 0x21: /* BESR0 */
886 case 0x22: /* BESR1 */
899 static void ppc405_ebc_reset(DeviceState
*dev
)
901 Ppc4xxEbcState
*ebc
= PPC4xx_EBC(dev
);
904 ebc
->addr
= 0x00000000;
905 ebc
->bap
[0] = 0x7F8FFE80;
906 ebc
->bcr
[0] = 0xFFE28000;
907 for (i
= 0; i
< 8; i
++) {
908 ebc
->bap
[i
] = 0x00000000;
909 ebc
->bcr
[i
] = 0x00000000;
911 ebc
->besr0
= 0x00000000;
912 ebc
->besr1
= 0x00000000;
913 ebc
->cfg
= 0x80400000;
916 static void ppc405_ebc_realize(DeviceState
*dev
, Error
**errp
)
918 Ppc4xxEbcState
*ebc
= PPC4xx_EBC(dev
);
919 Ppc4xxDcrDeviceState
*dcr
= PPC4xx_DCR_DEVICE(dev
);
921 ppc4xx_dcr_register(dcr
, EBC0_CFGADDR
, ebc
, &dcr_read_ebc
, &dcr_write_ebc
);
922 ppc4xx_dcr_register(dcr
, EBC0_CFGDATA
, ebc
, &dcr_read_ebc
, &dcr_write_ebc
);
925 static void ppc405_ebc_class_init(ObjectClass
*oc
, void *data
)
927 DeviceClass
*dc
= DEVICE_CLASS(oc
);
929 dc
->realize
= ppc405_ebc_realize
;
930 dc
->reset
= ppc405_ebc_reset
;
931 /* Reason: only works as function of a ppc4xx SoC */
932 dc
->user_creatable
= false;
935 /* PPC4xx_DCR_DEVICE */
937 void ppc4xx_dcr_register(Ppc4xxDcrDeviceState
*dev
, int dcrn
, void *opaque
,
938 dcr_read_cb dcr_read
, dcr_write_cb dcr_write
)
941 ppc_dcr_register(&dev
->cpu
->env
, dcrn
, opaque
, dcr_read
, dcr_write
);
944 bool ppc4xx_dcr_realize(Ppc4xxDcrDeviceState
*dev
, PowerPCCPU
*cpu
,
947 object_property_set_link(OBJECT(dev
), "cpu", OBJECT(cpu
), &error_abort
);
948 return sysbus_realize(SYS_BUS_DEVICE(dev
), errp
);
951 static Property ppc4xx_dcr_properties
[] = {
952 DEFINE_PROP_LINK("cpu", Ppc4xxDcrDeviceState
, cpu
, TYPE_POWERPC_CPU
,
954 DEFINE_PROP_END_OF_LIST(),
957 static void ppc4xx_dcr_class_init(ObjectClass
*oc
, void *data
)
959 DeviceClass
*dc
= DEVICE_CLASS(oc
);
961 device_class_set_props(dc
, ppc4xx_dcr_properties
);
964 static const TypeInfo ppc4xx_types
[] = {
966 .name
= TYPE_PPC4xx_SDRAM_DDR
,
967 .parent
= TYPE_PPC4xx_DCR_DEVICE
,
968 .instance_size
= sizeof(Ppc4xxSdramDdrState
),
969 .class_init
= ppc4xx_sdram_ddr_class_init
,
971 .name
= TYPE_PPC4xx_MAL
,
972 .parent
= TYPE_PPC4xx_DCR_DEVICE
,
973 .instance_size
= sizeof(Ppc4xxMalState
),
974 .instance_finalize
= ppc4xx_mal_finalize
,
975 .class_init
= ppc4xx_mal_class_init
,
977 .name
= TYPE_PPC4xx_PLB
,
978 .parent
= TYPE_PPC4xx_DCR_DEVICE
,
979 .instance_size
= sizeof(Ppc4xxPlbState
),
980 .class_init
= ppc405_plb_class_init
,
982 .name
= TYPE_PPC4xx_EBC
,
983 .parent
= TYPE_PPC4xx_DCR_DEVICE
,
984 .instance_size
= sizeof(Ppc4xxEbcState
),
985 .class_init
= ppc405_ebc_class_init
,
987 .name
= TYPE_PPC4xx_DCR_DEVICE
,
988 .parent
= TYPE_SYS_BUS_DEVICE
,
989 .instance_size
= sizeof(Ppc4xxDcrDeviceState
),
990 .class_init
= ppc4xx_dcr_class_init
,
995 DEFINE_TYPES(ppc4xx_types
)