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 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_memories, 352 hwaddr *ram_bases, 353 hwaddr *ram_sizes, 354 int do_init) 355 { 356 ppc4xx_sdram_t *sdram; 357 int i; 358 359 sdram = g_new0(ppc4xx_sdram_t, 1); 360 sdram->irq = irq; 361 sdram->nbanks = nbanks; 362 for (i = 0; i < nbanks; i++) { 363 sdram->bank[i].ram = ram_memories[i]; 364 sdram->bank[i].base = ram_bases[i]; 365 sdram->bank[i].size = ram_sizes[i]; 366 } 367 qemu_register_reset(&sdram_reset, sdram); 368 ppc_dcr_register(env, SDRAM0_CFGADDR, 369 sdram, &dcr_read_sdram, &dcr_write_sdram); 370 ppc_dcr_register(env, SDRAM0_CFGDATA, 371 sdram, &dcr_read_sdram, &dcr_write_sdram); 372 if (do_init) { 373 sdram_map_bcr(sdram); 374 } 375 } 376 377 /* 378 * Split RAM between SDRAM banks. 379 * 380 * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1] 381 * and must be 0-terminated. 382 * 383 * The 4xx SDRAM controller supports a small number of banks, and each bank 384 * must be one of a small set of sizes. The number of banks and the supported 385 * sizes varies by SoC. 386 */ 387 void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, 388 MemoryRegion ram_memories[], 389 hwaddr ram_bases[], hwaddr ram_sizes[], 390 const ram_addr_t sdram_bank_sizes[]) 391 { 392 ram_addr_t size_left = memory_region_size(ram); 393 ram_addr_t base = 0; 394 ram_addr_t bank_size; 395 int i; 396 int j; 397 398 for (i = 0; i < nr_banks; i++) { 399 for (j = 0; sdram_bank_sizes[j] != 0; j++) { 400 bank_size = sdram_bank_sizes[j]; 401 if (bank_size <= size_left) { 402 char name[32]; 403 404 ram_bases[i] = base; 405 ram_sizes[i] = bank_size; 406 base += bank_size; 407 size_left -= bank_size; 408 snprintf(name, sizeof(name), "ppc4xx.sdram%d", i); 409 memory_region_init_alias(&ram_memories[i], NULL, name, ram, 410 ram_bases[i], ram_sizes[i]); 411 break; 412 } 413 } 414 if (!size_left) { 415 /* No need to use the remaining banks. */ 416 break; 417 } 418 } 419 420 if (size_left) { 421 ram_addr_t used_size = memory_region_size(ram) - size_left; 422 GString *s = g_string_new(NULL); 423 424 for (i = 0; sdram_bank_sizes[i]; i++) { 425 g_string_append_printf(s, "%" PRIi64 "%s", 426 sdram_bank_sizes[i] / MiB, 427 sdram_bank_sizes[i + 1] ? ", " : ""); 428 } 429 error_report("at most %d bank%s of %s MiB each supported", 430 nr_banks, nr_banks == 1 ? "" : "s", s->str); 431 error_printf("Possible valid RAM size: %" PRIi64 " MiB\n", 432 used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB); 433 434 g_string_free(s, true); 435 exit(EXIT_FAILURE); 436 } 437 } 438 439 /*****************************************************************************/ 440 /* MAL */ 441 442 enum { 443 MAL0_CFG = 0x180, 444 MAL0_ESR = 0x181, 445 MAL0_IER = 0x182, 446 MAL0_TXCASR = 0x184, 447 MAL0_TXCARR = 0x185, 448 MAL0_TXEOBISR = 0x186, 449 MAL0_TXDEIR = 0x187, 450 MAL0_RXCASR = 0x190, 451 MAL0_RXCARR = 0x191, 452 MAL0_RXEOBISR = 0x192, 453 MAL0_RXDEIR = 0x193, 454 MAL0_TXCTP0R = 0x1A0, 455 MAL0_RXCTP0R = 0x1C0, 456 MAL0_RCBS0 = 0x1E0, 457 MAL0_RCBS1 = 0x1E1, 458 }; 459 460 static void ppc4xx_mal_reset(DeviceState *dev) 461 { 462 Ppc4xxMalState *mal = PPC4xx_MAL(dev); 463 464 mal->cfg = 0x0007C000; 465 mal->esr = 0x00000000; 466 mal->ier = 0x00000000; 467 mal->rxcasr = 0x00000000; 468 mal->rxdeir = 0x00000000; 469 mal->rxeobisr = 0x00000000; 470 mal->txcasr = 0x00000000; 471 mal->txdeir = 0x00000000; 472 mal->txeobisr = 0x00000000; 473 } 474 475 static uint32_t dcr_read_mal(void *opaque, int dcrn) 476 { 477 Ppc4xxMalState *mal = opaque; 478 uint32_t ret; 479 480 switch (dcrn) { 481 case MAL0_CFG: 482 ret = mal->cfg; 483 break; 484 case MAL0_ESR: 485 ret = mal->esr; 486 break; 487 case MAL0_IER: 488 ret = mal->ier; 489 break; 490 case MAL0_TXCASR: 491 ret = mal->txcasr; 492 break; 493 case MAL0_TXCARR: 494 ret = mal->txcarr; 495 break; 496 case MAL0_TXEOBISR: 497 ret = mal->txeobisr; 498 break; 499 case MAL0_TXDEIR: 500 ret = mal->txdeir; 501 break; 502 case MAL0_RXCASR: 503 ret = mal->rxcasr; 504 break; 505 case MAL0_RXCARR: 506 ret = mal->rxcarr; 507 break; 508 case MAL0_RXEOBISR: 509 ret = mal->rxeobisr; 510 break; 511 case MAL0_RXDEIR: 512 ret = mal->rxdeir; 513 break; 514 default: 515 ret = 0; 516 break; 517 } 518 if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) { 519 ret = mal->txctpr[dcrn - MAL0_TXCTP0R]; 520 } 521 if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) { 522 ret = mal->rxctpr[dcrn - MAL0_RXCTP0R]; 523 } 524 if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) { 525 ret = mal->rcbs[dcrn - MAL0_RCBS0]; 526 } 527 528 return ret; 529 } 530 531 static void dcr_write_mal(void *opaque, int dcrn, uint32_t val) 532 { 533 Ppc4xxMalState *mal = opaque; 534 535 switch (dcrn) { 536 case MAL0_CFG: 537 if (val & 0x80000000) { 538 ppc4xx_mal_reset(DEVICE(mal)); 539 } 540 mal->cfg = val & 0x00FFC087; 541 break; 542 case MAL0_ESR: 543 /* Read/clear */ 544 mal->esr &= ~val; 545 break; 546 case MAL0_IER: 547 mal->ier = val & 0x0000001F; 548 break; 549 case MAL0_TXCASR: 550 mal->txcasr = val & 0xF0000000; 551 break; 552 case MAL0_TXCARR: 553 mal->txcarr = val & 0xF0000000; 554 break; 555 case MAL0_TXEOBISR: 556 /* Read/clear */ 557 mal->txeobisr &= ~val; 558 break; 559 case MAL0_TXDEIR: 560 /* Read/clear */ 561 mal->txdeir &= ~val; 562 break; 563 case MAL0_RXCASR: 564 mal->rxcasr = val & 0xC0000000; 565 break; 566 case MAL0_RXCARR: 567 mal->rxcarr = val & 0xC0000000; 568 break; 569 case MAL0_RXEOBISR: 570 /* Read/clear */ 571 mal->rxeobisr &= ~val; 572 break; 573 case MAL0_RXDEIR: 574 /* Read/clear */ 575 mal->rxdeir &= ~val; 576 break; 577 } 578 if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) { 579 mal->txctpr[dcrn - MAL0_TXCTP0R] = val; 580 } 581 if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) { 582 mal->rxctpr[dcrn - MAL0_RXCTP0R] = val; 583 } 584 if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) { 585 mal->rcbs[dcrn - MAL0_RCBS0] = val & 0x000000FF; 586 } 587 } 588 589 static void ppc4xx_mal_realize(DeviceState *dev, Error **errp) 590 { 591 Ppc4xxMalState *mal = PPC4xx_MAL(dev); 592 Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); 593 int i; 594 595 if (mal->txcnum > 32 || mal->rxcnum > 32) { 596 error_setg(errp, "invalid TXC/RXC number"); 597 return; 598 } 599 600 mal->txctpr = g_new0(uint32_t, mal->txcnum); 601 mal->rxctpr = g_new0(uint32_t, mal->rxcnum); 602 mal->rcbs = g_new0(uint32_t, mal->rxcnum); 603 604 for (i = 0; i < ARRAY_SIZE(mal->irqs); i++) { 605 sysbus_init_irq(SYS_BUS_DEVICE(dev), &mal->irqs[i]); 606 } 607 608 ppc4xx_dcr_register(dcr, MAL0_CFG, mal, &dcr_read_mal, &dcr_write_mal); 609 ppc4xx_dcr_register(dcr, MAL0_ESR, mal, &dcr_read_mal, &dcr_write_mal); 610 ppc4xx_dcr_register(dcr, MAL0_IER, mal, &dcr_read_mal, &dcr_write_mal); 611 ppc4xx_dcr_register(dcr, MAL0_TXCASR, mal, &dcr_read_mal, &dcr_write_mal); 612 ppc4xx_dcr_register(dcr, MAL0_TXCARR, mal, &dcr_read_mal, &dcr_write_mal); 613 ppc4xx_dcr_register(dcr, MAL0_TXEOBISR, mal, &dcr_read_mal, &dcr_write_mal); 614 ppc4xx_dcr_register(dcr, MAL0_TXDEIR, mal, &dcr_read_mal, &dcr_write_mal); 615 ppc4xx_dcr_register(dcr, MAL0_RXCASR, mal, &dcr_read_mal, &dcr_write_mal); 616 ppc4xx_dcr_register(dcr, MAL0_RXCARR, mal, &dcr_read_mal, &dcr_write_mal); 617 ppc4xx_dcr_register(dcr, MAL0_RXEOBISR, mal, &dcr_read_mal, &dcr_write_mal); 618 ppc4xx_dcr_register(dcr, MAL0_RXDEIR, mal, &dcr_read_mal, &dcr_write_mal); 619 for (i = 0; i < mal->txcnum; i++) { 620 ppc4xx_dcr_register(dcr, MAL0_TXCTP0R + i, 621 mal, &dcr_read_mal, &dcr_write_mal); 622 } 623 for (i = 0; i < mal->rxcnum; i++) { 624 ppc4xx_dcr_register(dcr, MAL0_RXCTP0R + i, 625 mal, &dcr_read_mal, &dcr_write_mal); 626 } 627 for (i = 0; i < mal->rxcnum; i++) { 628 ppc4xx_dcr_register(dcr, MAL0_RCBS0 + i, 629 mal, &dcr_read_mal, &dcr_write_mal); 630 } 631 } 632 633 static void ppc4xx_mal_finalize(Object *obj) 634 { 635 Ppc4xxMalState *mal = PPC4xx_MAL(obj); 636 637 g_free(mal->rcbs); 638 g_free(mal->rxctpr); 639 g_free(mal->txctpr); 640 } 641 642 static Property ppc4xx_mal_properties[] = { 643 DEFINE_PROP_UINT8("txc-num", Ppc4xxMalState, txcnum, 0), 644 DEFINE_PROP_UINT8("rxc-num", Ppc4xxMalState, rxcnum, 0), 645 DEFINE_PROP_END_OF_LIST(), 646 }; 647 648 static void ppc4xx_mal_class_init(ObjectClass *oc, void *data) 649 { 650 DeviceClass *dc = DEVICE_CLASS(oc); 651 652 dc->realize = ppc4xx_mal_realize; 653 dc->reset = ppc4xx_mal_reset; 654 /* Reason: only works as function of a ppc4xx SoC */ 655 dc->user_creatable = false; 656 device_class_set_props(dc, ppc4xx_mal_properties); 657 } 658 659 /*****************************************************************************/ 660 /* Peripheral local bus arbitrer */ 661 enum { 662 PLB3A0_ACR = 0x077, 663 PLB4A0_ACR = 0x081, 664 PLB0_BESR = 0x084, 665 PLB0_BEAR = 0x086, 666 PLB0_ACR = 0x087, 667 PLB4A1_ACR = 0x089, 668 }; 669 670 static uint32_t dcr_read_plb(void *opaque, int dcrn) 671 { 672 Ppc4xxPlbState *plb = opaque; 673 uint32_t ret; 674 675 switch (dcrn) { 676 case PLB0_ACR: 677 ret = plb->acr; 678 break; 679 case PLB0_BEAR: 680 ret = plb->bear; 681 break; 682 case PLB0_BESR: 683 ret = plb->besr; 684 break; 685 default: 686 /* Avoid gcc warning */ 687 ret = 0; 688 break; 689 } 690 691 return ret; 692 } 693 694 static void dcr_write_plb(void *opaque, int dcrn, uint32_t val) 695 { 696 Ppc4xxPlbState *plb = opaque; 697 698 switch (dcrn) { 699 case PLB0_ACR: 700 /* 701 * We don't care about the actual parameters written as 702 * we don't manage any priorities on the bus 703 */ 704 plb->acr = val & 0xF8000000; 705 break; 706 case PLB0_BEAR: 707 /* Read only */ 708 break; 709 case PLB0_BESR: 710 /* Write-clear */ 711 plb->besr &= ~val; 712 break; 713 } 714 } 715 716 static void ppc405_plb_reset(DeviceState *dev) 717 { 718 Ppc4xxPlbState *plb = PPC4xx_PLB(dev); 719 720 plb->acr = 0x00000000; 721 plb->bear = 0x00000000; 722 plb->besr = 0x00000000; 723 } 724 725 static void ppc405_plb_realize(DeviceState *dev, Error **errp) 726 { 727 Ppc4xxPlbState *plb = PPC4xx_PLB(dev); 728 Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); 729 730 ppc4xx_dcr_register(dcr, PLB3A0_ACR, plb, &dcr_read_plb, &dcr_write_plb); 731 ppc4xx_dcr_register(dcr, PLB4A0_ACR, plb, &dcr_read_plb, &dcr_write_plb); 732 ppc4xx_dcr_register(dcr, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb); 733 ppc4xx_dcr_register(dcr, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb); 734 ppc4xx_dcr_register(dcr, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb); 735 ppc4xx_dcr_register(dcr, PLB4A1_ACR, plb, &dcr_read_plb, &dcr_write_plb); 736 } 737 738 static void ppc405_plb_class_init(ObjectClass *oc, void *data) 739 { 740 DeviceClass *dc = DEVICE_CLASS(oc); 741 742 dc->realize = ppc405_plb_realize; 743 dc->reset = ppc405_plb_reset; 744 /* Reason: only works as function of a ppc4xx SoC */ 745 dc->user_creatable = false; 746 } 747 748 /*****************************************************************************/ 749 /* Peripheral controller */ 750 enum { 751 EBC0_CFGADDR = 0x012, 752 EBC0_CFGDATA = 0x013, 753 }; 754 755 static uint32_t dcr_read_ebc(void *opaque, int dcrn) 756 { 757 Ppc4xxEbcState *ebc = opaque; 758 uint32_t ret; 759 760 switch (dcrn) { 761 case EBC0_CFGADDR: 762 ret = ebc->addr; 763 break; 764 case EBC0_CFGDATA: 765 switch (ebc->addr) { 766 case 0x00: /* B0CR */ 767 ret = ebc->bcr[0]; 768 break; 769 case 0x01: /* B1CR */ 770 ret = ebc->bcr[1]; 771 break; 772 case 0x02: /* B2CR */ 773 ret = ebc->bcr[2]; 774 break; 775 case 0x03: /* B3CR */ 776 ret = ebc->bcr[3]; 777 break; 778 case 0x04: /* B4CR */ 779 ret = ebc->bcr[4]; 780 break; 781 case 0x05: /* B5CR */ 782 ret = ebc->bcr[5]; 783 break; 784 case 0x06: /* B6CR */ 785 ret = ebc->bcr[6]; 786 break; 787 case 0x07: /* B7CR */ 788 ret = ebc->bcr[7]; 789 break; 790 case 0x10: /* B0AP */ 791 ret = ebc->bap[0]; 792 break; 793 case 0x11: /* B1AP */ 794 ret = ebc->bap[1]; 795 break; 796 case 0x12: /* B2AP */ 797 ret = ebc->bap[2]; 798 break; 799 case 0x13: /* B3AP */ 800 ret = ebc->bap[3]; 801 break; 802 case 0x14: /* B4AP */ 803 ret = ebc->bap[4]; 804 break; 805 case 0x15: /* B5AP */ 806 ret = ebc->bap[5]; 807 break; 808 case 0x16: /* B6AP */ 809 ret = ebc->bap[6]; 810 break; 811 case 0x17: /* B7AP */ 812 ret = ebc->bap[7]; 813 break; 814 case 0x20: /* BEAR */ 815 ret = ebc->bear; 816 break; 817 case 0x21: /* BESR0 */ 818 ret = ebc->besr0; 819 break; 820 case 0x22: /* BESR1 */ 821 ret = ebc->besr1; 822 break; 823 case 0x23: /* CFG */ 824 ret = ebc->cfg; 825 break; 826 default: 827 ret = 0x00000000; 828 break; 829 } 830 break; 831 default: 832 ret = 0x00000000; 833 break; 834 } 835 836 return ret; 837 } 838 839 static void dcr_write_ebc(void *opaque, int dcrn, uint32_t val) 840 { 841 Ppc4xxEbcState *ebc = opaque; 842 843 switch (dcrn) { 844 case EBC0_CFGADDR: 845 ebc->addr = val; 846 break; 847 case EBC0_CFGDATA: 848 switch (ebc->addr) { 849 case 0x00: /* B0CR */ 850 break; 851 case 0x01: /* B1CR */ 852 break; 853 case 0x02: /* B2CR */ 854 break; 855 case 0x03: /* B3CR */ 856 break; 857 case 0x04: /* B4CR */ 858 break; 859 case 0x05: /* B5CR */ 860 break; 861 case 0x06: /* B6CR */ 862 break; 863 case 0x07: /* B7CR */ 864 break; 865 case 0x10: /* B0AP */ 866 break; 867 case 0x11: /* B1AP */ 868 break; 869 case 0x12: /* B2AP */ 870 break; 871 case 0x13: /* B3AP */ 872 break; 873 case 0x14: /* B4AP */ 874 break; 875 case 0x15: /* B5AP */ 876 break; 877 case 0x16: /* B6AP */ 878 break; 879 case 0x17: /* B7AP */ 880 break; 881 case 0x20: /* BEAR */ 882 break; 883 case 0x21: /* BESR0 */ 884 break; 885 case 0x22: /* BESR1 */ 886 break; 887 case 0x23: /* CFG */ 888 break; 889 default: 890 break; 891 } 892 break; 893 default: 894 break; 895 } 896 } 897 898 static void ppc405_ebc_reset(DeviceState *dev) 899 { 900 Ppc4xxEbcState *ebc = PPC4xx_EBC(dev); 901 int i; 902 903 ebc->addr = 0x00000000; 904 ebc->bap[0] = 0x7F8FFE80; 905 ebc->bcr[0] = 0xFFE28000; 906 for (i = 0; i < 8; i++) { 907 ebc->bap[i] = 0x00000000; 908 ebc->bcr[i] = 0x00000000; 909 } 910 ebc->besr0 = 0x00000000; 911 ebc->besr1 = 0x00000000; 912 ebc->cfg = 0x80400000; 913 } 914 915 static void ppc405_ebc_realize(DeviceState *dev, Error **errp) 916 { 917 Ppc4xxEbcState *ebc = PPC4xx_EBC(dev); 918 Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); 919 920 ppc4xx_dcr_register(dcr, EBC0_CFGADDR, ebc, &dcr_read_ebc, &dcr_write_ebc); 921 ppc4xx_dcr_register(dcr, EBC0_CFGDATA, ebc, &dcr_read_ebc, &dcr_write_ebc); 922 } 923 924 static void ppc405_ebc_class_init(ObjectClass *oc, void *data) 925 { 926 DeviceClass *dc = DEVICE_CLASS(oc); 927 928 dc->realize = ppc405_ebc_realize; 929 dc->reset = ppc405_ebc_reset; 930 /* Reason: only works as function of a ppc4xx SoC */ 931 dc->user_creatable = false; 932 } 933 934 /* PPC4xx_DCR_DEVICE */ 935 936 void ppc4xx_dcr_register(Ppc4xxDcrDeviceState *dev, int dcrn, void *opaque, 937 dcr_read_cb dcr_read, dcr_write_cb dcr_write) 938 { 939 assert(dev->cpu); 940 ppc_dcr_register(&dev->cpu->env, dcrn, opaque, dcr_read, dcr_write); 941 } 942 943 bool ppc4xx_dcr_realize(Ppc4xxDcrDeviceState *dev, PowerPCCPU *cpu, 944 Error **errp) 945 { 946 object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort); 947 return sysbus_realize(SYS_BUS_DEVICE(dev), errp); 948 } 949 950 static Property ppc4xx_dcr_properties[] = { 951 DEFINE_PROP_LINK("cpu", Ppc4xxDcrDeviceState, cpu, TYPE_POWERPC_CPU, 952 PowerPCCPU *), 953 DEFINE_PROP_END_OF_LIST(), 954 }; 955 956 static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data) 957 { 958 DeviceClass *dc = DEVICE_CLASS(oc); 959 960 device_class_set_props(dc, ppc4xx_dcr_properties); 961 } 962 963 static const TypeInfo ppc4xx_types[] = { 964 { 965 .name = TYPE_PPC4xx_MAL, 966 .parent = TYPE_PPC4xx_DCR_DEVICE, 967 .instance_size = sizeof(Ppc4xxMalState), 968 .instance_finalize = ppc4xx_mal_finalize, 969 .class_init = ppc4xx_mal_class_init, 970 }, { 971 .name = TYPE_PPC4xx_PLB, 972 .parent = TYPE_PPC4xx_DCR_DEVICE, 973 .instance_size = sizeof(Ppc4xxPlbState), 974 .class_init = ppc405_plb_class_init, 975 }, { 976 .name = TYPE_PPC4xx_EBC, 977 .parent = TYPE_PPC4xx_DCR_DEVICE, 978 .instance_size = sizeof(Ppc4xxEbcState), 979 .class_init = ppc405_ebc_class_init, 980 }, { 981 .name = TYPE_PPC4xx_DCR_DEVICE, 982 .parent = TYPE_SYS_BUS_DEVICE, 983 .instance_size = sizeof(Ppc4xxDcrDeviceState), 984 .class_init = ppc4xx_dcr_class_init, 985 .abstract = true, 986 } 987 }; 988 989 DEFINE_TYPES(ppc4xx_types) 990