1008ff9d7Sj_mayer /*
2008ff9d7Sj_mayer * QEMU PowerPC 4xx embedded processors shared devices emulation
3008ff9d7Sj_mayer *
4008ff9d7Sj_mayer * Copyright (c) 2007 Jocelyn Mayer
5008ff9d7Sj_mayer *
6008ff9d7Sj_mayer * Permission is hereby granted, free of charge, to any person obtaining a copy
7008ff9d7Sj_mayer * of this software and associated documentation files (the "Software"), to deal
8008ff9d7Sj_mayer * in the Software without restriction, including without limitation the rights
9008ff9d7Sj_mayer * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10008ff9d7Sj_mayer * copies of the Software, and to permit persons to whom the Software is
11008ff9d7Sj_mayer * furnished to do so, subject to the following conditions:
12008ff9d7Sj_mayer *
13008ff9d7Sj_mayer * The above copyright notice and this permission notice shall be included in
14008ff9d7Sj_mayer * all copies or substantial portions of the Software.
15008ff9d7Sj_mayer *
16008ff9d7Sj_mayer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17008ff9d7Sj_mayer * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18008ff9d7Sj_mayer * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19008ff9d7Sj_mayer * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20008ff9d7Sj_mayer * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21008ff9d7Sj_mayer * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22008ff9d7Sj_mayer * THE SOFTWARE.
23008ff9d7Sj_mayer */
2471e8a915SMarkus Armbruster
250d75590dSPeter Maydell #include "qemu/osdep.h"
2633c11879SPaolo Bonzini #include "cpu.h"
270d09e41aSPaolo Bonzini #include "hw/ppc/ppc4xx.h"
2834d0831fSPeter Maydell #include "hw/qdev-properties.h"
2934d0831fSPeter Maydell #include "qapi/error.h"
30b7da58fdSaurel32
31517284a7SBALATON Zoltan /*****************************************************************************/
32517284a7SBALATON Zoltan /* MAL */
3304534280SBALATON Zoltan
34517284a7SBALATON Zoltan enum {
35517284a7SBALATON Zoltan MAL0_CFG = 0x180,
36517284a7SBALATON Zoltan MAL0_ESR = 0x181,
37517284a7SBALATON Zoltan MAL0_IER = 0x182,
38517284a7SBALATON Zoltan MAL0_TXCASR = 0x184,
39517284a7SBALATON Zoltan MAL0_TXCARR = 0x185,
40517284a7SBALATON Zoltan MAL0_TXEOBISR = 0x186,
41517284a7SBALATON Zoltan MAL0_TXDEIR = 0x187,
42517284a7SBALATON Zoltan MAL0_RXCASR = 0x190,
43517284a7SBALATON Zoltan MAL0_RXCARR = 0x191,
44517284a7SBALATON Zoltan MAL0_RXEOBISR = 0x192,
45517284a7SBALATON Zoltan MAL0_RXDEIR = 0x193,
46517284a7SBALATON Zoltan MAL0_TXCTP0R = 0x1A0,
47517284a7SBALATON Zoltan MAL0_RXCTP0R = 0x1C0,
48517284a7SBALATON Zoltan MAL0_RCBS0 = 0x1E0,
49517284a7SBALATON Zoltan MAL0_RCBS1 = 0x1E1,
50517284a7SBALATON Zoltan };
51517284a7SBALATON Zoltan
ppc4xx_mal_reset(DeviceState * dev)52da116a8aSCédric Le Goater static void ppc4xx_mal_reset(DeviceState *dev)
5304534280SBALATON Zoltan {
54da116a8aSCédric Le Goater Ppc4xxMalState *mal = PPC4xx_MAL(dev);
5504534280SBALATON Zoltan
5604534280SBALATON Zoltan mal->cfg = 0x0007C000;
5704534280SBALATON Zoltan mal->esr = 0x00000000;
5804534280SBALATON Zoltan mal->ier = 0x00000000;
5904534280SBALATON Zoltan mal->rxcasr = 0x00000000;
6004534280SBALATON Zoltan mal->rxdeir = 0x00000000;
6104534280SBALATON Zoltan mal->rxeobisr = 0x00000000;
6204534280SBALATON Zoltan mal->txcasr = 0x00000000;
6304534280SBALATON Zoltan mal->txdeir = 0x00000000;
6404534280SBALATON Zoltan mal->txeobisr = 0x00000000;
6504534280SBALATON Zoltan }
66517284a7SBALATON Zoltan
dcr_read_mal(void * opaque,int dcrn)67517284a7SBALATON Zoltan static uint32_t dcr_read_mal(void *opaque, int dcrn)
68517284a7SBALATON Zoltan {
69da116a8aSCédric Le Goater Ppc4xxMalState *mal = opaque;
70517284a7SBALATON Zoltan uint32_t ret;
71517284a7SBALATON Zoltan
72517284a7SBALATON Zoltan switch (dcrn) {
73517284a7SBALATON Zoltan case MAL0_CFG:
74517284a7SBALATON Zoltan ret = mal->cfg;
75517284a7SBALATON Zoltan break;
76517284a7SBALATON Zoltan case MAL0_ESR:
77517284a7SBALATON Zoltan ret = mal->esr;
78517284a7SBALATON Zoltan break;
79517284a7SBALATON Zoltan case MAL0_IER:
80517284a7SBALATON Zoltan ret = mal->ier;
81517284a7SBALATON Zoltan break;
82517284a7SBALATON Zoltan case MAL0_TXCASR:
83517284a7SBALATON Zoltan ret = mal->txcasr;
84517284a7SBALATON Zoltan break;
85517284a7SBALATON Zoltan case MAL0_TXCARR:
86517284a7SBALATON Zoltan ret = mal->txcarr;
87517284a7SBALATON Zoltan break;
88517284a7SBALATON Zoltan case MAL0_TXEOBISR:
89517284a7SBALATON Zoltan ret = mal->txeobisr;
90517284a7SBALATON Zoltan break;
91517284a7SBALATON Zoltan case MAL0_TXDEIR:
92517284a7SBALATON Zoltan ret = mal->txdeir;
93517284a7SBALATON Zoltan break;
94517284a7SBALATON Zoltan case MAL0_RXCASR:
95517284a7SBALATON Zoltan ret = mal->rxcasr;
96517284a7SBALATON Zoltan break;
97517284a7SBALATON Zoltan case MAL0_RXCARR:
98517284a7SBALATON Zoltan ret = mal->rxcarr;
99517284a7SBALATON Zoltan break;
100517284a7SBALATON Zoltan case MAL0_RXEOBISR:
101517284a7SBALATON Zoltan ret = mal->rxeobisr;
102517284a7SBALATON Zoltan break;
103517284a7SBALATON Zoltan case MAL0_RXDEIR:
104517284a7SBALATON Zoltan ret = mal->rxdeir;
105517284a7SBALATON Zoltan break;
106517284a7SBALATON Zoltan default:
107517284a7SBALATON Zoltan ret = 0;
108517284a7SBALATON Zoltan break;
109517284a7SBALATON Zoltan }
11004534280SBALATON Zoltan if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) {
11104534280SBALATON Zoltan ret = mal->txctpr[dcrn - MAL0_TXCTP0R];
11204534280SBALATON Zoltan }
11304534280SBALATON Zoltan if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) {
11404534280SBALATON Zoltan ret = mal->rxctpr[dcrn - MAL0_RXCTP0R];
11504534280SBALATON Zoltan }
11604534280SBALATON Zoltan if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) {
11704534280SBALATON Zoltan ret = mal->rcbs[dcrn - MAL0_RCBS0];
11804534280SBALATON Zoltan }
119517284a7SBALATON Zoltan
120517284a7SBALATON Zoltan return ret;
121517284a7SBALATON Zoltan }
122517284a7SBALATON Zoltan
dcr_write_mal(void * opaque,int dcrn,uint32_t val)123517284a7SBALATON Zoltan static void dcr_write_mal(void *opaque, int dcrn, uint32_t val)
124517284a7SBALATON Zoltan {
125da116a8aSCédric Le Goater Ppc4xxMalState *mal = opaque;
126517284a7SBALATON Zoltan
127517284a7SBALATON Zoltan switch (dcrn) {
128517284a7SBALATON Zoltan case MAL0_CFG:
129517284a7SBALATON Zoltan if (val & 0x80000000) {
130da116a8aSCédric Le Goater ppc4xx_mal_reset(DEVICE(mal));
131517284a7SBALATON Zoltan }
132517284a7SBALATON Zoltan mal->cfg = val & 0x00FFC087;
133517284a7SBALATON Zoltan break;
134517284a7SBALATON Zoltan case MAL0_ESR:
135517284a7SBALATON Zoltan /* Read/clear */
136517284a7SBALATON Zoltan mal->esr &= ~val;
137517284a7SBALATON Zoltan break;
138517284a7SBALATON Zoltan case MAL0_IER:
139517284a7SBALATON Zoltan mal->ier = val & 0x0000001F;
140517284a7SBALATON Zoltan break;
141517284a7SBALATON Zoltan case MAL0_TXCASR:
142517284a7SBALATON Zoltan mal->txcasr = val & 0xF0000000;
143517284a7SBALATON Zoltan break;
144517284a7SBALATON Zoltan case MAL0_TXCARR:
145517284a7SBALATON Zoltan mal->txcarr = val & 0xF0000000;
146517284a7SBALATON Zoltan break;
147517284a7SBALATON Zoltan case MAL0_TXEOBISR:
148517284a7SBALATON Zoltan /* Read/clear */
149517284a7SBALATON Zoltan mal->txeobisr &= ~val;
150517284a7SBALATON Zoltan break;
151517284a7SBALATON Zoltan case MAL0_TXDEIR:
152517284a7SBALATON Zoltan /* Read/clear */
153517284a7SBALATON Zoltan mal->txdeir &= ~val;
154517284a7SBALATON Zoltan break;
155517284a7SBALATON Zoltan case MAL0_RXCASR:
156517284a7SBALATON Zoltan mal->rxcasr = val & 0xC0000000;
157517284a7SBALATON Zoltan break;
158517284a7SBALATON Zoltan case MAL0_RXCARR:
159517284a7SBALATON Zoltan mal->rxcarr = val & 0xC0000000;
160517284a7SBALATON Zoltan break;
161517284a7SBALATON Zoltan case MAL0_RXEOBISR:
162517284a7SBALATON Zoltan /* Read/clear */
163517284a7SBALATON Zoltan mal->rxeobisr &= ~val;
164517284a7SBALATON Zoltan break;
165517284a7SBALATON Zoltan case MAL0_RXDEIR:
166517284a7SBALATON Zoltan /* Read/clear */
167517284a7SBALATON Zoltan mal->rxdeir &= ~val;
168517284a7SBALATON Zoltan break;
16904534280SBALATON Zoltan }
17004534280SBALATON Zoltan if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) {
17104534280SBALATON Zoltan mal->txctpr[dcrn - MAL0_TXCTP0R] = val;
17204534280SBALATON Zoltan }
17304534280SBALATON Zoltan if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) {
17404534280SBALATON Zoltan mal->rxctpr[dcrn - MAL0_RXCTP0R] = val;
17504534280SBALATON Zoltan }
17604534280SBALATON Zoltan if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) {
17704534280SBALATON Zoltan mal->rcbs[dcrn - MAL0_RCBS0] = val & 0x000000FF;
178517284a7SBALATON Zoltan }
179517284a7SBALATON Zoltan }
180517284a7SBALATON Zoltan
ppc4xx_mal_realize(DeviceState * dev,Error ** errp)181da116a8aSCédric Le Goater static void ppc4xx_mal_realize(DeviceState *dev, Error **errp)
182517284a7SBALATON Zoltan {
183da116a8aSCédric Le Goater Ppc4xxMalState *mal = PPC4xx_MAL(dev);
184da116a8aSCédric Le Goater Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
185517284a7SBALATON Zoltan int i;
186517284a7SBALATON Zoltan
187da116a8aSCédric Le Goater if (mal->txcnum > 32 || mal->rxcnum > 32) {
188da116a8aSCédric Le Goater error_setg(errp, "invalid TXC/RXC number");
189da116a8aSCédric Le Goater return;
190517284a7SBALATON Zoltan }
191da116a8aSCédric Le Goater
192da116a8aSCédric Le Goater mal->txctpr = g_new0(uint32_t, mal->txcnum);
193da116a8aSCédric Le Goater mal->rxctpr = g_new0(uint32_t, mal->rxcnum);
194da116a8aSCédric Le Goater mal->rcbs = g_new0(uint32_t, mal->rxcnum);
195da116a8aSCédric Le Goater
196da116a8aSCédric Le Goater for (i = 0; i < ARRAY_SIZE(mal->irqs); i++) {
197da116a8aSCédric Le Goater sysbus_init_irq(SYS_BUS_DEVICE(dev), &mal->irqs[i]);
198da116a8aSCédric Le Goater }
199da116a8aSCédric Le Goater
200da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_CFG, mal, &dcr_read_mal, &dcr_write_mal);
201da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_ESR, mal, &dcr_read_mal, &dcr_write_mal);
202da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_IER, mal, &dcr_read_mal, &dcr_write_mal);
203da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_TXCASR, mal, &dcr_read_mal, &dcr_write_mal);
204da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_TXCARR, mal, &dcr_read_mal, &dcr_write_mal);
205da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_TXEOBISR, mal, &dcr_read_mal, &dcr_write_mal);
206da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_TXDEIR, mal, &dcr_read_mal, &dcr_write_mal);
207da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_RXCASR, mal, &dcr_read_mal, &dcr_write_mal);
208da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_RXCARR, mal, &dcr_read_mal, &dcr_write_mal);
209da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_RXEOBISR, mal, &dcr_read_mal, &dcr_write_mal);
210da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_RXDEIR, mal, &dcr_read_mal, &dcr_write_mal);
211da116a8aSCédric Le Goater for (i = 0; i < mal->txcnum; i++) {
212da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_TXCTP0R + i,
213517284a7SBALATON Zoltan mal, &dcr_read_mal, &dcr_write_mal);
21404534280SBALATON Zoltan }
215da116a8aSCédric Le Goater for (i = 0; i < mal->rxcnum; i++) {
216da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_RXCTP0R + i,
217517284a7SBALATON Zoltan mal, &dcr_read_mal, &dcr_write_mal);
21804534280SBALATON Zoltan }
219da116a8aSCédric Le Goater for (i = 0; i < mal->rxcnum; i++) {
220da116a8aSCédric Le Goater ppc4xx_dcr_register(dcr, MAL0_RCBS0 + i,
221517284a7SBALATON Zoltan mal, &dcr_read_mal, &dcr_write_mal);
22204534280SBALATON Zoltan }
223517284a7SBALATON Zoltan }
224629cae61SCédric Le Goater
ppc4xx_mal_finalize(Object * obj)225da116a8aSCédric Le Goater static void ppc4xx_mal_finalize(Object *obj)
226da116a8aSCédric Le Goater {
227da116a8aSCédric Le Goater Ppc4xxMalState *mal = PPC4xx_MAL(obj);
228da116a8aSCédric Le Goater
229da116a8aSCédric Le Goater g_free(mal->rcbs);
230da116a8aSCédric Le Goater g_free(mal->rxctpr);
231da116a8aSCédric Le Goater g_free(mal->txctpr);
232da116a8aSCédric Le Goater }
233da116a8aSCédric Le Goater
23490f5755eSRichard Henderson static const Property ppc4xx_mal_properties[] = {
235da116a8aSCédric Le Goater DEFINE_PROP_UINT8("txc-num", Ppc4xxMalState, txcnum, 0),
236da116a8aSCédric Le Goater DEFINE_PROP_UINT8("rxc-num", Ppc4xxMalState, rxcnum, 0),
237da116a8aSCédric Le Goater };
238da116a8aSCédric Le Goater
ppc4xx_mal_class_init(ObjectClass * oc,const void * data)239*12d1a768SPhilippe Mathieu-Daudé static void ppc4xx_mal_class_init(ObjectClass *oc, const void *data)
240da116a8aSCédric Le Goater {
241da116a8aSCédric Le Goater DeviceClass *dc = DEVICE_CLASS(oc);
242da116a8aSCédric Le Goater
243da116a8aSCédric Le Goater dc->realize = ppc4xx_mal_realize;
244e3d08143SPeter Maydell device_class_set_legacy_reset(dc, ppc4xx_mal_reset);
245da116a8aSCédric Le Goater /* Reason: only works as function of a ppc4xx SoC */
246da116a8aSCédric Le Goater dc->user_creatable = false;
247da116a8aSCédric Le Goater device_class_set_props(dc, ppc4xx_mal_properties);
248da116a8aSCédric Le Goater }
249da116a8aSCédric Le Goater
2502d54aaf1SBALATON Zoltan /*****************************************************************************/
2512d54aaf1SBALATON Zoltan /* Peripheral local bus arbitrer */
2522d54aaf1SBALATON Zoltan enum {
2532d54aaf1SBALATON Zoltan PLB3A0_ACR = 0x077,
2542d54aaf1SBALATON Zoltan PLB4A0_ACR = 0x081,
2552d54aaf1SBALATON Zoltan PLB0_BESR = 0x084,
2562d54aaf1SBALATON Zoltan PLB0_BEAR = 0x086,
2572d54aaf1SBALATON Zoltan PLB0_ACR = 0x087,
2582d54aaf1SBALATON Zoltan PLB4A1_ACR = 0x089,
2592d54aaf1SBALATON Zoltan };
2602d54aaf1SBALATON Zoltan
dcr_read_plb(void * opaque,int dcrn)2612d54aaf1SBALATON Zoltan static uint32_t dcr_read_plb(void *opaque, int dcrn)
2622d54aaf1SBALATON Zoltan {
263052c779bSBALATON Zoltan Ppc4xxPlbState *plb = opaque;
2642d54aaf1SBALATON Zoltan uint32_t ret;
2652d54aaf1SBALATON Zoltan
2662d54aaf1SBALATON Zoltan switch (dcrn) {
2672d54aaf1SBALATON Zoltan case PLB0_ACR:
2682d54aaf1SBALATON Zoltan ret = plb->acr;
2692d54aaf1SBALATON Zoltan break;
2702d54aaf1SBALATON Zoltan case PLB0_BEAR:
2712d54aaf1SBALATON Zoltan ret = plb->bear;
2722d54aaf1SBALATON Zoltan break;
2732d54aaf1SBALATON Zoltan case PLB0_BESR:
2742d54aaf1SBALATON Zoltan ret = plb->besr;
2752d54aaf1SBALATON Zoltan break;
2762d54aaf1SBALATON Zoltan default:
2772d54aaf1SBALATON Zoltan /* Avoid gcc warning */
2782d54aaf1SBALATON Zoltan ret = 0;
2792d54aaf1SBALATON Zoltan break;
2802d54aaf1SBALATON Zoltan }
2812d54aaf1SBALATON Zoltan
2822d54aaf1SBALATON Zoltan return ret;
2832d54aaf1SBALATON Zoltan }
2842d54aaf1SBALATON Zoltan
dcr_write_plb(void * opaque,int dcrn,uint32_t val)2852d54aaf1SBALATON Zoltan static void dcr_write_plb(void *opaque, int dcrn, uint32_t val)
2862d54aaf1SBALATON Zoltan {
287052c779bSBALATON Zoltan Ppc4xxPlbState *plb = opaque;
2882d54aaf1SBALATON Zoltan
2892d54aaf1SBALATON Zoltan switch (dcrn) {
2902d54aaf1SBALATON Zoltan case PLB0_ACR:
2912d54aaf1SBALATON Zoltan /*
2922d54aaf1SBALATON Zoltan * We don't care about the actual parameters written as
2932d54aaf1SBALATON Zoltan * we don't manage any priorities on the bus
2942d54aaf1SBALATON Zoltan */
2952d54aaf1SBALATON Zoltan plb->acr = val & 0xF8000000;
2962d54aaf1SBALATON Zoltan break;
2972d54aaf1SBALATON Zoltan case PLB0_BEAR:
2982d54aaf1SBALATON Zoltan /* Read only */
2992d54aaf1SBALATON Zoltan break;
3002d54aaf1SBALATON Zoltan case PLB0_BESR:
3012d54aaf1SBALATON Zoltan /* Write-clear */
3022d54aaf1SBALATON Zoltan plb->besr &= ~val;
3032d54aaf1SBALATON Zoltan break;
3042d54aaf1SBALATON Zoltan }
3052d54aaf1SBALATON Zoltan }
3062d54aaf1SBALATON Zoltan
ppc405_plb_reset(DeviceState * dev)3072d54aaf1SBALATON Zoltan static void ppc405_plb_reset(DeviceState *dev)
3082d54aaf1SBALATON Zoltan {
309052c779bSBALATON Zoltan Ppc4xxPlbState *plb = PPC4xx_PLB(dev);
3102d54aaf1SBALATON Zoltan
3112d54aaf1SBALATON Zoltan plb->acr = 0x00000000;
3122d54aaf1SBALATON Zoltan plb->bear = 0x00000000;
3132d54aaf1SBALATON Zoltan plb->besr = 0x00000000;
3142d54aaf1SBALATON Zoltan }
3152d54aaf1SBALATON Zoltan
ppc405_plb_realize(DeviceState * dev,Error ** errp)3162d54aaf1SBALATON Zoltan static void ppc405_plb_realize(DeviceState *dev, Error **errp)
3172d54aaf1SBALATON Zoltan {
318052c779bSBALATON Zoltan Ppc4xxPlbState *plb = PPC4xx_PLB(dev);
3192d54aaf1SBALATON Zoltan Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
3202d54aaf1SBALATON Zoltan
3212d54aaf1SBALATON Zoltan ppc4xx_dcr_register(dcr, PLB3A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
3222d54aaf1SBALATON Zoltan ppc4xx_dcr_register(dcr, PLB4A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
3232d54aaf1SBALATON Zoltan ppc4xx_dcr_register(dcr, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
3242d54aaf1SBALATON Zoltan ppc4xx_dcr_register(dcr, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);
3252d54aaf1SBALATON Zoltan ppc4xx_dcr_register(dcr, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);
3262d54aaf1SBALATON Zoltan ppc4xx_dcr_register(dcr, PLB4A1_ACR, plb, &dcr_read_plb, &dcr_write_plb);
3272d54aaf1SBALATON Zoltan }
3282d54aaf1SBALATON Zoltan
ppc405_plb_class_init(ObjectClass * oc,const void * data)329*12d1a768SPhilippe Mathieu-Daudé static void ppc405_plb_class_init(ObjectClass *oc, const void *data)
3302d54aaf1SBALATON Zoltan {
3312d54aaf1SBALATON Zoltan DeviceClass *dc = DEVICE_CLASS(oc);
3322d54aaf1SBALATON Zoltan
3332d54aaf1SBALATON Zoltan dc->realize = ppc405_plb_realize;
334e3d08143SPeter Maydell device_class_set_legacy_reset(dc, ppc405_plb_reset);
3352d54aaf1SBALATON Zoltan /* Reason: only works as function of a ppc4xx SoC */
3362d54aaf1SBALATON Zoltan dc->user_creatable = false;
3372d54aaf1SBALATON Zoltan }
3382d54aaf1SBALATON Zoltan
339127ba8d0SBALATON Zoltan /*****************************************************************************/
340127ba8d0SBALATON Zoltan /* Peripheral controller */
341127ba8d0SBALATON Zoltan enum {
342127ba8d0SBALATON Zoltan EBC0_CFGADDR = 0x012,
343127ba8d0SBALATON Zoltan EBC0_CFGDATA = 0x013,
344127ba8d0SBALATON Zoltan };
345127ba8d0SBALATON Zoltan
dcr_read_ebc(void * opaque,int dcrn)346127ba8d0SBALATON Zoltan static uint32_t dcr_read_ebc(void *opaque, int dcrn)
347127ba8d0SBALATON Zoltan {
348cba58aa7SBALATON Zoltan Ppc4xxEbcState *ebc = opaque;
349127ba8d0SBALATON Zoltan uint32_t ret;
350127ba8d0SBALATON Zoltan
351127ba8d0SBALATON Zoltan switch (dcrn) {
352127ba8d0SBALATON Zoltan case EBC0_CFGADDR:
353127ba8d0SBALATON Zoltan ret = ebc->addr;
354127ba8d0SBALATON Zoltan break;
355127ba8d0SBALATON Zoltan case EBC0_CFGDATA:
356127ba8d0SBALATON Zoltan switch (ebc->addr) {
357127ba8d0SBALATON Zoltan case 0x00: /* B0CR */
358127ba8d0SBALATON Zoltan ret = ebc->bcr[0];
359127ba8d0SBALATON Zoltan break;
360127ba8d0SBALATON Zoltan case 0x01: /* B1CR */
361127ba8d0SBALATON Zoltan ret = ebc->bcr[1];
362127ba8d0SBALATON Zoltan break;
363127ba8d0SBALATON Zoltan case 0x02: /* B2CR */
364127ba8d0SBALATON Zoltan ret = ebc->bcr[2];
365127ba8d0SBALATON Zoltan break;
366127ba8d0SBALATON Zoltan case 0x03: /* B3CR */
367127ba8d0SBALATON Zoltan ret = ebc->bcr[3];
368127ba8d0SBALATON Zoltan break;
369127ba8d0SBALATON Zoltan case 0x04: /* B4CR */
370127ba8d0SBALATON Zoltan ret = ebc->bcr[4];
371127ba8d0SBALATON Zoltan break;
372127ba8d0SBALATON Zoltan case 0x05: /* B5CR */
373127ba8d0SBALATON Zoltan ret = ebc->bcr[5];
374127ba8d0SBALATON Zoltan break;
375127ba8d0SBALATON Zoltan case 0x06: /* B6CR */
376127ba8d0SBALATON Zoltan ret = ebc->bcr[6];
377127ba8d0SBALATON Zoltan break;
378127ba8d0SBALATON Zoltan case 0x07: /* B7CR */
379127ba8d0SBALATON Zoltan ret = ebc->bcr[7];
380127ba8d0SBALATON Zoltan break;
381127ba8d0SBALATON Zoltan case 0x10: /* B0AP */
382127ba8d0SBALATON Zoltan ret = ebc->bap[0];
383127ba8d0SBALATON Zoltan break;
384127ba8d0SBALATON Zoltan case 0x11: /* B1AP */
385127ba8d0SBALATON Zoltan ret = ebc->bap[1];
386127ba8d0SBALATON Zoltan break;
387127ba8d0SBALATON Zoltan case 0x12: /* B2AP */
388127ba8d0SBALATON Zoltan ret = ebc->bap[2];
389127ba8d0SBALATON Zoltan break;
390127ba8d0SBALATON Zoltan case 0x13: /* B3AP */
391127ba8d0SBALATON Zoltan ret = ebc->bap[3];
392127ba8d0SBALATON Zoltan break;
393127ba8d0SBALATON Zoltan case 0x14: /* B4AP */
394127ba8d0SBALATON Zoltan ret = ebc->bap[4];
395127ba8d0SBALATON Zoltan break;
396127ba8d0SBALATON Zoltan case 0x15: /* B5AP */
397127ba8d0SBALATON Zoltan ret = ebc->bap[5];
398127ba8d0SBALATON Zoltan break;
399127ba8d0SBALATON Zoltan case 0x16: /* B6AP */
400127ba8d0SBALATON Zoltan ret = ebc->bap[6];
401127ba8d0SBALATON Zoltan break;
402127ba8d0SBALATON Zoltan case 0x17: /* B7AP */
403127ba8d0SBALATON Zoltan ret = ebc->bap[7];
404127ba8d0SBALATON Zoltan break;
405127ba8d0SBALATON Zoltan case 0x20: /* BEAR */
406127ba8d0SBALATON Zoltan ret = ebc->bear;
407127ba8d0SBALATON Zoltan break;
408127ba8d0SBALATON Zoltan case 0x21: /* BESR0 */
409127ba8d0SBALATON Zoltan ret = ebc->besr0;
410127ba8d0SBALATON Zoltan break;
411127ba8d0SBALATON Zoltan case 0x22: /* BESR1 */
412127ba8d0SBALATON Zoltan ret = ebc->besr1;
413127ba8d0SBALATON Zoltan break;
414127ba8d0SBALATON Zoltan case 0x23: /* CFG */
415127ba8d0SBALATON Zoltan ret = ebc->cfg;
416127ba8d0SBALATON Zoltan break;
417127ba8d0SBALATON Zoltan default:
418127ba8d0SBALATON Zoltan ret = 0x00000000;
419127ba8d0SBALATON Zoltan break;
420127ba8d0SBALATON Zoltan }
421127ba8d0SBALATON Zoltan break;
422127ba8d0SBALATON Zoltan default:
423127ba8d0SBALATON Zoltan ret = 0x00000000;
424127ba8d0SBALATON Zoltan break;
425127ba8d0SBALATON Zoltan }
426127ba8d0SBALATON Zoltan
427127ba8d0SBALATON Zoltan return ret;
428127ba8d0SBALATON Zoltan }
429127ba8d0SBALATON Zoltan
dcr_write_ebc(void * opaque,int dcrn,uint32_t val)430127ba8d0SBALATON Zoltan static void dcr_write_ebc(void *opaque, int dcrn, uint32_t val)
431127ba8d0SBALATON Zoltan {
432cba58aa7SBALATON Zoltan Ppc4xxEbcState *ebc = opaque;
433127ba8d0SBALATON Zoltan
434127ba8d0SBALATON Zoltan switch (dcrn) {
435127ba8d0SBALATON Zoltan case EBC0_CFGADDR:
436127ba8d0SBALATON Zoltan ebc->addr = val;
437127ba8d0SBALATON Zoltan break;
438127ba8d0SBALATON Zoltan case EBC0_CFGDATA:
439127ba8d0SBALATON Zoltan switch (ebc->addr) {
440127ba8d0SBALATON Zoltan case 0x00: /* B0CR */
441127ba8d0SBALATON Zoltan break;
442127ba8d0SBALATON Zoltan case 0x01: /* B1CR */
443127ba8d0SBALATON Zoltan break;
444127ba8d0SBALATON Zoltan case 0x02: /* B2CR */
445127ba8d0SBALATON Zoltan break;
446127ba8d0SBALATON Zoltan case 0x03: /* B3CR */
447127ba8d0SBALATON Zoltan break;
448127ba8d0SBALATON Zoltan case 0x04: /* B4CR */
449127ba8d0SBALATON Zoltan break;
450127ba8d0SBALATON Zoltan case 0x05: /* B5CR */
451127ba8d0SBALATON Zoltan break;
452127ba8d0SBALATON Zoltan case 0x06: /* B6CR */
453127ba8d0SBALATON Zoltan break;
454127ba8d0SBALATON Zoltan case 0x07: /* B7CR */
455127ba8d0SBALATON Zoltan break;
456127ba8d0SBALATON Zoltan case 0x10: /* B0AP */
457127ba8d0SBALATON Zoltan break;
458127ba8d0SBALATON Zoltan case 0x11: /* B1AP */
459127ba8d0SBALATON Zoltan break;
460127ba8d0SBALATON Zoltan case 0x12: /* B2AP */
461127ba8d0SBALATON Zoltan break;
462127ba8d0SBALATON Zoltan case 0x13: /* B3AP */
463127ba8d0SBALATON Zoltan break;
464127ba8d0SBALATON Zoltan case 0x14: /* B4AP */
465127ba8d0SBALATON Zoltan break;
466127ba8d0SBALATON Zoltan case 0x15: /* B5AP */
467127ba8d0SBALATON Zoltan break;
468127ba8d0SBALATON Zoltan case 0x16: /* B6AP */
469127ba8d0SBALATON Zoltan break;
470127ba8d0SBALATON Zoltan case 0x17: /* B7AP */
471127ba8d0SBALATON Zoltan break;
472127ba8d0SBALATON Zoltan case 0x20: /* BEAR */
473127ba8d0SBALATON Zoltan break;
474127ba8d0SBALATON Zoltan case 0x21: /* BESR0 */
475127ba8d0SBALATON Zoltan break;
476127ba8d0SBALATON Zoltan case 0x22: /* BESR1 */
477127ba8d0SBALATON Zoltan break;
478127ba8d0SBALATON Zoltan case 0x23: /* CFG */
479127ba8d0SBALATON Zoltan break;
480127ba8d0SBALATON Zoltan default:
481127ba8d0SBALATON Zoltan break;
482127ba8d0SBALATON Zoltan }
483127ba8d0SBALATON Zoltan break;
484127ba8d0SBALATON Zoltan default:
485127ba8d0SBALATON Zoltan break;
486127ba8d0SBALATON Zoltan }
487127ba8d0SBALATON Zoltan }
488127ba8d0SBALATON Zoltan
ppc405_ebc_reset(DeviceState * dev)489127ba8d0SBALATON Zoltan static void ppc405_ebc_reset(DeviceState *dev)
490127ba8d0SBALATON Zoltan {
491cba58aa7SBALATON Zoltan Ppc4xxEbcState *ebc = PPC4xx_EBC(dev);
492127ba8d0SBALATON Zoltan int i;
493127ba8d0SBALATON Zoltan
494127ba8d0SBALATON Zoltan ebc->addr = 0x00000000;
495127ba8d0SBALATON Zoltan ebc->bap[0] = 0x7F8FFE80;
496127ba8d0SBALATON Zoltan ebc->bcr[0] = 0xFFE28000;
497127ba8d0SBALATON Zoltan for (i = 0; i < 8; i++) {
498127ba8d0SBALATON Zoltan ebc->bap[i] = 0x00000000;
499127ba8d0SBALATON Zoltan ebc->bcr[i] = 0x00000000;
500127ba8d0SBALATON Zoltan }
501127ba8d0SBALATON Zoltan ebc->besr0 = 0x00000000;
502127ba8d0SBALATON Zoltan ebc->besr1 = 0x00000000;
503127ba8d0SBALATON Zoltan ebc->cfg = 0x80400000;
504127ba8d0SBALATON Zoltan }
505127ba8d0SBALATON Zoltan
ppc405_ebc_realize(DeviceState * dev,Error ** errp)506127ba8d0SBALATON Zoltan static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
507127ba8d0SBALATON Zoltan {
508cba58aa7SBALATON Zoltan Ppc4xxEbcState *ebc = PPC4xx_EBC(dev);
509127ba8d0SBALATON Zoltan Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
510127ba8d0SBALATON Zoltan
511127ba8d0SBALATON Zoltan ppc4xx_dcr_register(dcr, EBC0_CFGADDR, ebc, &dcr_read_ebc, &dcr_write_ebc);
512127ba8d0SBALATON Zoltan ppc4xx_dcr_register(dcr, EBC0_CFGDATA, ebc, &dcr_read_ebc, &dcr_write_ebc);
513127ba8d0SBALATON Zoltan }
514127ba8d0SBALATON Zoltan
ppc405_ebc_class_init(ObjectClass * oc,const void * data)515*12d1a768SPhilippe Mathieu-Daudé static void ppc405_ebc_class_init(ObjectClass *oc, const void *data)
516127ba8d0SBALATON Zoltan {
517127ba8d0SBALATON Zoltan DeviceClass *dc = DEVICE_CLASS(oc);
518127ba8d0SBALATON Zoltan
519127ba8d0SBALATON Zoltan dc->realize = ppc405_ebc_realize;
520e3d08143SPeter Maydell device_class_set_legacy_reset(dc, ppc405_ebc_reset);
521127ba8d0SBALATON Zoltan /* Reason: only works as function of a ppc4xx SoC */
522127ba8d0SBALATON Zoltan dc->user_creatable = false;
523127ba8d0SBALATON Zoltan }
524127ba8d0SBALATON Zoltan
525629cae61SCédric Le Goater /* PPC4xx_DCR_DEVICE */
526629cae61SCédric Le Goater
ppc4xx_dcr_register(Ppc4xxDcrDeviceState * dev,int dcrn,void * opaque,dcr_read_cb dcr_read,dcr_write_cb dcr_write)527629cae61SCédric Le Goater void ppc4xx_dcr_register(Ppc4xxDcrDeviceState *dev, int dcrn, void *opaque,
528629cae61SCédric Le Goater dcr_read_cb dcr_read, dcr_write_cb dcr_write)
529629cae61SCédric Le Goater {
530629cae61SCédric Le Goater assert(dev->cpu);
531629cae61SCédric Le Goater ppc_dcr_register(&dev->cpu->env, dcrn, opaque, dcr_read, dcr_write);
532629cae61SCédric Le Goater }
533629cae61SCédric Le Goater
ppc4xx_dcr_realize(Ppc4xxDcrDeviceState * dev,PowerPCCPU * cpu,Error ** errp)534629cae61SCédric Le Goater bool ppc4xx_dcr_realize(Ppc4xxDcrDeviceState *dev, PowerPCCPU *cpu,
535629cae61SCédric Le Goater Error **errp)
536629cae61SCédric Le Goater {
537629cae61SCédric Le Goater object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort);
538629cae61SCédric Le Goater return sysbus_realize(SYS_BUS_DEVICE(dev), errp);
539629cae61SCédric Le Goater }
540629cae61SCédric Le Goater
54190f5755eSRichard Henderson static const Property ppc4xx_dcr_properties[] = {
542629cae61SCédric Le Goater DEFINE_PROP_LINK("cpu", Ppc4xxDcrDeviceState, cpu, TYPE_POWERPC_CPU,
543629cae61SCédric Le Goater PowerPCCPU *),
544629cae61SCédric Le Goater };
545629cae61SCédric Le Goater
ppc4xx_dcr_class_init(ObjectClass * oc,const void * data)546*12d1a768SPhilippe Mathieu-Daudé static void ppc4xx_dcr_class_init(ObjectClass *oc, const void *data)
547629cae61SCédric Le Goater {
548629cae61SCédric Le Goater DeviceClass *dc = DEVICE_CLASS(oc);
549629cae61SCédric Le Goater
550629cae61SCédric Le Goater device_class_set_props(dc, ppc4xx_dcr_properties);
551629cae61SCédric Le Goater }
552629cae61SCédric Le Goater
553629cae61SCédric Le Goater static const TypeInfo ppc4xx_types[] = {
554629cae61SCédric Le Goater {
555da116a8aSCédric Le Goater .name = TYPE_PPC4xx_MAL,
556da116a8aSCédric Le Goater .parent = TYPE_PPC4xx_DCR_DEVICE,
557da116a8aSCédric Le Goater .instance_size = sizeof(Ppc4xxMalState),
558da116a8aSCédric Le Goater .instance_finalize = ppc4xx_mal_finalize,
559da116a8aSCédric Le Goater .class_init = ppc4xx_mal_class_init,
560da116a8aSCédric Le Goater }, {
561052c779bSBALATON Zoltan .name = TYPE_PPC4xx_PLB,
5622d54aaf1SBALATON Zoltan .parent = TYPE_PPC4xx_DCR_DEVICE,
563052c779bSBALATON Zoltan .instance_size = sizeof(Ppc4xxPlbState),
5642d54aaf1SBALATON Zoltan .class_init = ppc405_plb_class_init,
5652d54aaf1SBALATON Zoltan }, {
566cba58aa7SBALATON Zoltan .name = TYPE_PPC4xx_EBC,
567127ba8d0SBALATON Zoltan .parent = TYPE_PPC4xx_DCR_DEVICE,
568cba58aa7SBALATON Zoltan .instance_size = sizeof(Ppc4xxEbcState),
569127ba8d0SBALATON Zoltan .class_init = ppc405_ebc_class_init,
570127ba8d0SBALATON Zoltan }, {
571629cae61SCédric Le Goater .name = TYPE_PPC4xx_DCR_DEVICE,
572629cae61SCédric Le Goater .parent = TYPE_SYS_BUS_DEVICE,
573629cae61SCédric Le Goater .instance_size = sizeof(Ppc4xxDcrDeviceState),
574629cae61SCédric Le Goater .class_init = ppc4xx_dcr_class_init,
575629cae61SCédric Le Goater .abstract = true,
576629cae61SCédric Le Goater }
577629cae61SCédric Le Goater };
578629cae61SCédric Le Goater
579629cae61SCédric Le Goater DEFINE_TYPES(ppc4xx_types)
580