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/intc/ppc-uic.h" 33 #include "hw/qdev-properties.h" 34 #include "qemu/log.h" 35 #include "exec/address-spaces.h" 36 #include "qemu/error-report.h" 37 #include "qapi/error.h" 38 #include "trace.h" 39 40 /*****************************************************************************/ 41 /* SDRAM controller */ 42 typedef struct ppc4xx_sdram_t ppc4xx_sdram_t; 43 struct ppc4xx_sdram_t { 44 uint32_t addr; 45 int nbanks; 46 MemoryRegion containers[4]; /* used for clipping */ 47 MemoryRegion *ram_memories; 48 hwaddr ram_bases[4]; 49 hwaddr ram_sizes[4]; 50 uint32_t besr0; 51 uint32_t besr1; 52 uint32_t bear; 53 uint32_t cfg; 54 uint32_t status; 55 uint32_t rtr; 56 uint32_t pmit; 57 uint32_t bcr[4]; 58 uint32_t tr; 59 uint32_t ecccfg; 60 uint32_t eccesr; 61 qemu_irq irq; 62 }; 63 64 enum { 65 SDRAM0_CFGADDR = 0x010, 66 SDRAM0_CFGDATA = 0x011, 67 }; 68 69 /* XXX: TOFIX: some patches have made this code become inconsistent: 70 * there are type inconsistencies, mixing hwaddr, target_ulong 71 * and uint32_t 72 */ 73 static uint32_t sdram_bcr (hwaddr ram_base, 74 hwaddr ram_size) 75 { 76 uint32_t bcr; 77 78 switch (ram_size) { 79 case 4 * MiB: 80 bcr = 0x00000000; 81 break; 82 case 8 * MiB: 83 bcr = 0x00020000; 84 break; 85 case 16 * MiB: 86 bcr = 0x00040000; 87 break; 88 case 32 * MiB: 89 bcr = 0x00060000; 90 break; 91 case 64 * MiB: 92 bcr = 0x00080000; 93 break; 94 case 128 * MiB: 95 bcr = 0x000A0000; 96 break; 97 case 256 * MiB: 98 bcr = 0x000C0000; 99 break; 100 default: 101 qemu_log_mask(LOG_GUEST_ERROR, 102 "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__, 103 ram_size); 104 return 0x00000000; 105 } 106 bcr |= ram_base & 0xFF800000; 107 bcr |= 1; 108 109 return bcr; 110 } 111 112 static inline hwaddr sdram_base(uint32_t bcr) 113 { 114 return bcr & 0xFF800000; 115 } 116 117 static target_ulong sdram_size (uint32_t bcr) 118 { 119 target_ulong size; 120 int sh; 121 122 sh = (bcr >> 17) & 0x7; 123 if (sh == 7) 124 size = -1; 125 else 126 size = (4 * MiB) << sh; 127 128 return size; 129 } 130 131 static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i, 132 uint32_t bcr, int enabled) 133 { 134 if (sdram->bcr[i] & 0x00000001) { 135 /* Unmap RAM */ 136 trace_ppc4xx_sdram_unmap(sdram_base(sdram->bcr[i]), 137 sdram_size(sdram->bcr[i])); 138 memory_region_del_subregion(get_system_memory(), 139 &sdram->containers[i]); 140 memory_region_del_subregion(&sdram->containers[i], 141 &sdram->ram_memories[i]); 142 object_unparent(OBJECT(&sdram->containers[i])); 143 } 144 sdram->bcr[i] = bcr & 0xFFDEE001; 145 if (enabled && (bcr & 0x00000001)) { 146 trace_ppc4xx_sdram_unmap(sdram_base(bcr), sdram_size(bcr)); 147 memory_region_init(&sdram->containers[i], NULL, "sdram-containers", 148 sdram_size(bcr)); 149 memory_region_add_subregion(&sdram->containers[i], 0, 150 &sdram->ram_memories[i]); 151 memory_region_add_subregion(get_system_memory(), 152 sdram_base(bcr), 153 &sdram->containers[i]); 154 } 155 } 156 157 static void sdram_map_bcr (ppc4xx_sdram_t *sdram) 158 { 159 int i; 160 161 for (i = 0; i < sdram->nbanks; i++) { 162 if (sdram->ram_sizes[i] != 0) { 163 sdram_set_bcr(sdram, i, sdram_bcr(sdram->ram_bases[i], 164 sdram->ram_sizes[i]), 1); 165 } else { 166 sdram_set_bcr(sdram, i, 0x00000000, 0); 167 } 168 } 169 } 170 171 static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram) 172 { 173 int i; 174 175 for (i = 0; i < sdram->nbanks; i++) { 176 trace_ppc4xx_sdram_unmap(sdram_base(sdram->bcr[i]), 177 sdram_size(sdram->bcr[i])); 178 memory_region_del_subregion(get_system_memory(), 179 &sdram->ram_memories[i]); 180 } 181 } 182 183 static uint32_t dcr_read_sdram (void *opaque, int dcrn) 184 { 185 ppc4xx_sdram_t *sdram; 186 uint32_t ret; 187 188 sdram = opaque; 189 switch (dcrn) { 190 case SDRAM0_CFGADDR: 191 ret = sdram->addr; 192 break; 193 case SDRAM0_CFGDATA: 194 switch (sdram->addr) { 195 case 0x00: /* SDRAM_BESR0 */ 196 ret = sdram->besr0; 197 break; 198 case 0x08: /* SDRAM_BESR1 */ 199 ret = sdram->besr1; 200 break; 201 case 0x10: /* SDRAM_BEAR */ 202 ret = sdram->bear; 203 break; 204 case 0x20: /* SDRAM_CFG */ 205 ret = sdram->cfg; 206 break; 207 case 0x24: /* SDRAM_STATUS */ 208 ret = sdram->status; 209 break; 210 case 0x30: /* SDRAM_RTR */ 211 ret = sdram->rtr; 212 break; 213 case 0x34: /* SDRAM_PMIT */ 214 ret = sdram->pmit; 215 break; 216 case 0x40: /* SDRAM_B0CR */ 217 ret = sdram->bcr[0]; 218 break; 219 case 0x44: /* SDRAM_B1CR */ 220 ret = sdram->bcr[1]; 221 break; 222 case 0x48: /* SDRAM_B2CR */ 223 ret = sdram->bcr[2]; 224 break; 225 case 0x4C: /* SDRAM_B3CR */ 226 ret = sdram->bcr[3]; 227 break; 228 case 0x80: /* SDRAM_TR */ 229 ret = -1; /* ? */ 230 break; 231 case 0x94: /* SDRAM_ECCCFG */ 232 ret = sdram->ecccfg; 233 break; 234 case 0x98: /* SDRAM_ECCESR */ 235 ret = sdram->eccesr; 236 break; 237 default: /* Error */ 238 ret = -1; 239 break; 240 } 241 break; 242 default: 243 /* Avoid gcc warning */ 244 ret = 0x00000000; 245 break; 246 } 247 248 return ret; 249 } 250 251 static void dcr_write_sdram (void *opaque, int dcrn, uint32_t val) 252 { 253 ppc4xx_sdram_t *sdram; 254 255 sdram = opaque; 256 switch (dcrn) { 257 case SDRAM0_CFGADDR: 258 sdram->addr = val; 259 break; 260 case SDRAM0_CFGDATA: 261 switch (sdram->addr) { 262 case 0x00: /* SDRAM_BESR0 */ 263 sdram->besr0 &= ~val; 264 break; 265 case 0x08: /* SDRAM_BESR1 */ 266 sdram->besr1 &= ~val; 267 break; 268 case 0x10: /* SDRAM_BEAR */ 269 sdram->bear = val; 270 break; 271 case 0x20: /* SDRAM_CFG */ 272 val &= 0xFFE00000; 273 if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) { 274 trace_ppc4xx_sdram_enable("enable"); 275 /* validate all RAM mappings */ 276 sdram_map_bcr(sdram); 277 sdram->status &= ~0x80000000; 278 } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) { 279 trace_ppc4xx_sdram_enable("disable"); 280 /* invalidate all RAM mappings */ 281 sdram_unmap_bcr(sdram); 282 sdram->status |= 0x80000000; 283 } 284 if (!(sdram->cfg & 0x40000000) && (val & 0x40000000)) 285 sdram->status |= 0x40000000; 286 else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000)) 287 sdram->status &= ~0x40000000; 288 sdram->cfg = val; 289 break; 290 case 0x24: /* SDRAM_STATUS */ 291 /* Read-only register */ 292 break; 293 case 0x30: /* SDRAM_RTR */ 294 sdram->rtr = val & 0x3FF80000; 295 break; 296 case 0x34: /* SDRAM_PMIT */ 297 sdram->pmit = (val & 0xF8000000) | 0x07C00000; 298 break; 299 case 0x40: /* SDRAM_B0CR */ 300 sdram_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000); 301 break; 302 case 0x44: /* SDRAM_B1CR */ 303 sdram_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000); 304 break; 305 case 0x48: /* SDRAM_B2CR */ 306 sdram_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000); 307 break; 308 case 0x4C: /* SDRAM_B3CR */ 309 sdram_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000); 310 break; 311 case 0x80: /* SDRAM_TR */ 312 sdram->tr = val & 0x018FC01F; 313 break; 314 case 0x94: /* SDRAM_ECCCFG */ 315 sdram->ecccfg = val & 0x00F00000; 316 break; 317 case 0x98: /* SDRAM_ECCESR */ 318 val &= 0xFFF0F000; 319 if (sdram->eccesr == 0 && val != 0) 320 qemu_irq_raise(sdram->irq); 321 else if (sdram->eccesr != 0 && val == 0) 322 qemu_irq_lower(sdram->irq); 323 sdram->eccesr = val; 324 break; 325 default: /* Error */ 326 break; 327 } 328 break; 329 } 330 } 331 332 static void sdram_reset (void *opaque) 333 { 334 ppc4xx_sdram_t *sdram; 335 336 sdram = opaque; 337 sdram->addr = 0x00000000; 338 sdram->bear = 0x00000000; 339 sdram->besr0 = 0x00000000; /* No error */ 340 sdram->besr1 = 0x00000000; /* No error */ 341 sdram->cfg = 0x00000000; 342 sdram->ecccfg = 0x00000000; /* No ECC */ 343 sdram->eccesr = 0x00000000; /* No error */ 344 sdram->pmit = 0x07C00000; 345 sdram->rtr = 0x05F00000; 346 sdram->tr = 0x00854009; 347 /* We pre-initialize RAM banks */ 348 sdram->status = 0x00000000; 349 sdram->cfg = 0x00800000; 350 } 351 352 void ppc4xx_sdram_init (CPUPPCState *env, qemu_irq irq, int nbanks, 353 MemoryRegion *ram_memories, 354 hwaddr *ram_bases, 355 hwaddr *ram_sizes, 356 int do_init) 357 { 358 ppc4xx_sdram_t *sdram; 359 360 sdram = g_new0(ppc4xx_sdram_t, 1); 361 sdram->irq = irq; 362 sdram->nbanks = nbanks; 363 sdram->ram_memories = ram_memories; 364 memset(sdram->ram_bases, 0, 4 * sizeof(hwaddr)); 365 memcpy(sdram->ram_bases, ram_bases, 366 nbanks * sizeof(hwaddr)); 367 memset(sdram->ram_sizes, 0, 4 * sizeof(hwaddr)); 368 memcpy(sdram->ram_sizes, ram_sizes, 369 nbanks * sizeof(hwaddr)); 370 qemu_register_reset(&sdram_reset, sdram); 371 ppc_dcr_register(env, SDRAM0_CFGADDR, 372 sdram, &dcr_read_sdram, &dcr_write_sdram); 373 ppc_dcr_register(env, SDRAM0_CFGDATA, 374 sdram, &dcr_read_sdram, &dcr_write_sdram); 375 if (do_init) 376 sdram_map_bcr(sdram); 377 } 378 379 /* 380 * Split RAM between SDRAM banks. 381 * 382 * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1] 383 * and must be 0-terminated. 384 * 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. 388 */ 389 void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, 390 MemoryRegion ram_memories[], 391 hwaddr ram_bases[], hwaddr ram_sizes[], 392 const ram_addr_t sdram_bank_sizes[]) 393 { 394 ram_addr_t size_left = memory_region_size(ram); 395 ram_addr_t base = 0; 396 ram_addr_t bank_size; 397 int i; 398 int j; 399 400 for (i = 0; i < nr_banks; i++) { 401 for (j = 0; sdram_bank_sizes[j] != 0; j++) { 402 bank_size = sdram_bank_sizes[j]; 403 if (bank_size <= size_left) { 404 char name[32]; 405 406 ram_bases[i] = base; 407 ram_sizes[i] = bank_size; 408 base += bank_size; 409 size_left -= bank_size; 410 snprintf(name, sizeof(name), "ppc4xx.sdram%d", i); 411 memory_region_init_alias(&ram_memories[i], NULL, name, ram, 412 ram_bases[i], ram_sizes[i]); 413 break; 414 } 415 } 416 if (!size_left) { 417 /* No need to use the remaining banks. */ 418 break; 419 } 420 } 421 422 if (size_left) { 423 ram_addr_t used_size = memory_region_size(ram) - size_left; 424 GString *s = g_string_new(NULL); 425 426 for (i = 0; sdram_bank_sizes[i]; i++) { 427 g_string_append_printf(s, "%" PRIi64 "%s", 428 sdram_bank_sizes[i] / MiB, 429 sdram_bank_sizes[i + 1] ? ", " : ""); 430 } 431 error_report("at most %d bank%s of %s MiB each supported", 432 nr_banks, nr_banks == 1 ? "" : "s", s->str); 433 error_printf("Possible valid RAM size: %" PRIi64 " MiB \n", 434 used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB); 435 436 g_string_free(s, true); 437 exit(EXIT_FAILURE); 438 } 439 } 440 441 /*****************************************************************************/ 442 /* MAL */ 443 444 enum { 445 MAL0_CFG = 0x180, 446 MAL0_ESR = 0x181, 447 MAL0_IER = 0x182, 448 MAL0_TXCASR = 0x184, 449 MAL0_TXCARR = 0x185, 450 MAL0_TXEOBISR = 0x186, 451 MAL0_TXDEIR = 0x187, 452 MAL0_RXCASR = 0x190, 453 MAL0_RXCARR = 0x191, 454 MAL0_RXEOBISR = 0x192, 455 MAL0_RXDEIR = 0x193, 456 MAL0_TXCTP0R = 0x1A0, 457 MAL0_RXCTP0R = 0x1C0, 458 MAL0_RCBS0 = 0x1E0, 459 MAL0_RCBS1 = 0x1E1, 460 }; 461 462 typedef struct ppc4xx_mal_t ppc4xx_mal_t; 463 struct ppc4xx_mal_t { 464 qemu_irq irqs[4]; 465 uint32_t cfg; 466 uint32_t esr; 467 uint32_t ier; 468 uint32_t txcasr; 469 uint32_t txcarr; 470 uint32_t txeobisr; 471 uint32_t txdeir; 472 uint32_t rxcasr; 473 uint32_t rxcarr; 474 uint32_t rxeobisr; 475 uint32_t rxdeir; 476 uint32_t *txctpr; 477 uint32_t *rxctpr; 478 uint32_t *rcbs; 479 uint8_t txcnum; 480 uint8_t rxcnum; 481 }; 482 483 static void ppc4xx_mal_reset(void *opaque) 484 { 485 ppc4xx_mal_t *mal; 486 487 mal = opaque; 488 mal->cfg = 0x0007C000; 489 mal->esr = 0x00000000; 490 mal->ier = 0x00000000; 491 mal->rxcasr = 0x00000000; 492 mal->rxdeir = 0x00000000; 493 mal->rxeobisr = 0x00000000; 494 mal->txcasr = 0x00000000; 495 mal->txdeir = 0x00000000; 496 mal->txeobisr = 0x00000000; 497 } 498 499 static uint32_t dcr_read_mal(void *opaque, int dcrn) 500 { 501 ppc4xx_mal_t *mal; 502 uint32_t ret; 503 504 mal = opaque; 505 switch (dcrn) { 506 case MAL0_CFG: 507 ret = mal->cfg; 508 break; 509 case MAL0_ESR: 510 ret = mal->esr; 511 break; 512 case MAL0_IER: 513 ret = mal->ier; 514 break; 515 case MAL0_TXCASR: 516 ret = mal->txcasr; 517 break; 518 case MAL0_TXCARR: 519 ret = mal->txcarr; 520 break; 521 case MAL0_TXEOBISR: 522 ret = mal->txeobisr; 523 break; 524 case MAL0_TXDEIR: 525 ret = mal->txdeir; 526 break; 527 case MAL0_RXCASR: 528 ret = mal->rxcasr; 529 break; 530 case MAL0_RXCARR: 531 ret = mal->rxcarr; 532 break; 533 case MAL0_RXEOBISR: 534 ret = mal->rxeobisr; 535 break; 536 case MAL0_RXDEIR: 537 ret = mal->rxdeir; 538 break; 539 default: 540 ret = 0; 541 break; 542 } 543 if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) { 544 ret = mal->txctpr[dcrn - MAL0_TXCTP0R]; 545 } 546 if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) { 547 ret = mal->rxctpr[dcrn - MAL0_RXCTP0R]; 548 } 549 if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) { 550 ret = mal->rcbs[dcrn - MAL0_RCBS0]; 551 } 552 553 return ret; 554 } 555 556 static void dcr_write_mal(void *opaque, int dcrn, uint32_t val) 557 { 558 ppc4xx_mal_t *mal; 559 560 mal = opaque; 561 switch (dcrn) { 562 case MAL0_CFG: 563 if (val & 0x80000000) { 564 ppc4xx_mal_reset(mal); 565 } 566 mal->cfg = val & 0x00FFC087; 567 break; 568 case MAL0_ESR: 569 /* Read/clear */ 570 mal->esr &= ~val; 571 break; 572 case MAL0_IER: 573 mal->ier = val & 0x0000001F; 574 break; 575 case MAL0_TXCASR: 576 mal->txcasr = val & 0xF0000000; 577 break; 578 case MAL0_TXCARR: 579 mal->txcarr = val & 0xF0000000; 580 break; 581 case MAL0_TXEOBISR: 582 /* Read/clear */ 583 mal->txeobisr &= ~val; 584 break; 585 case MAL0_TXDEIR: 586 /* Read/clear */ 587 mal->txdeir &= ~val; 588 break; 589 case MAL0_RXCASR: 590 mal->rxcasr = val & 0xC0000000; 591 break; 592 case MAL0_RXCARR: 593 mal->rxcarr = val & 0xC0000000; 594 break; 595 case MAL0_RXEOBISR: 596 /* Read/clear */ 597 mal->rxeobisr &= ~val; 598 break; 599 case MAL0_RXDEIR: 600 /* Read/clear */ 601 mal->rxdeir &= ~val; 602 break; 603 } 604 if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) { 605 mal->txctpr[dcrn - MAL0_TXCTP0R] = val; 606 } 607 if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) { 608 mal->rxctpr[dcrn - MAL0_RXCTP0R] = val; 609 } 610 if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) { 611 mal->rcbs[dcrn - MAL0_RCBS0] = val & 0x000000FF; 612 } 613 } 614 615 void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum, 616 qemu_irq irqs[4]) 617 { 618 ppc4xx_mal_t *mal; 619 int i; 620 621 assert(txcnum <= 32 && rxcnum <= 32); 622 mal = g_malloc0(sizeof(*mal)); 623 mal->txcnum = txcnum; 624 mal->rxcnum = rxcnum; 625 mal->txctpr = g_new0(uint32_t, txcnum); 626 mal->rxctpr = g_new0(uint32_t, rxcnum); 627 mal->rcbs = g_new0(uint32_t, rxcnum); 628 for (i = 0; i < 4; i++) { 629 mal->irqs[i] = irqs[i]; 630 } 631 qemu_register_reset(&ppc4xx_mal_reset, mal); 632 ppc_dcr_register(env, MAL0_CFG, 633 mal, &dcr_read_mal, &dcr_write_mal); 634 ppc_dcr_register(env, MAL0_ESR, 635 mal, &dcr_read_mal, &dcr_write_mal); 636 ppc_dcr_register(env, MAL0_IER, 637 mal, &dcr_read_mal, &dcr_write_mal); 638 ppc_dcr_register(env, MAL0_TXCASR, 639 mal, &dcr_read_mal, &dcr_write_mal); 640 ppc_dcr_register(env, MAL0_TXCARR, 641 mal, &dcr_read_mal, &dcr_write_mal); 642 ppc_dcr_register(env, MAL0_TXEOBISR, 643 mal, &dcr_read_mal, &dcr_write_mal); 644 ppc_dcr_register(env, MAL0_TXDEIR, 645 mal, &dcr_read_mal, &dcr_write_mal); 646 ppc_dcr_register(env, MAL0_RXCASR, 647 mal, &dcr_read_mal, &dcr_write_mal); 648 ppc_dcr_register(env, MAL0_RXCARR, 649 mal, &dcr_read_mal, &dcr_write_mal); 650 ppc_dcr_register(env, MAL0_RXEOBISR, 651 mal, &dcr_read_mal, &dcr_write_mal); 652 ppc_dcr_register(env, MAL0_RXDEIR, 653 mal, &dcr_read_mal, &dcr_write_mal); 654 for (i = 0; i < txcnum; i++) { 655 ppc_dcr_register(env, MAL0_TXCTP0R + i, 656 mal, &dcr_read_mal, &dcr_write_mal); 657 } 658 for (i = 0; i < rxcnum; i++) { 659 ppc_dcr_register(env, MAL0_RXCTP0R + i, 660 mal, &dcr_read_mal, &dcr_write_mal); 661 } 662 for (i = 0; i < rxcnum; i++) { 663 ppc_dcr_register(env, MAL0_RCBS0 + i, 664 mal, &dcr_read_mal, &dcr_write_mal); 665 } 666 } 667 668 /* PPC4xx_DCR_DEVICE */ 669 670 void ppc4xx_dcr_register(Ppc4xxDcrDeviceState *dev, int dcrn, void *opaque, 671 dcr_read_cb dcr_read, dcr_write_cb dcr_write) 672 { 673 assert(dev->cpu); 674 ppc_dcr_register(&dev->cpu->env, dcrn, opaque, dcr_read, dcr_write); 675 } 676 677 bool ppc4xx_dcr_realize(Ppc4xxDcrDeviceState *dev, PowerPCCPU *cpu, 678 Error **errp) 679 { 680 object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort); 681 return sysbus_realize(SYS_BUS_DEVICE(dev), errp); 682 } 683 684 static Property ppc4xx_dcr_properties[] = { 685 DEFINE_PROP_LINK("cpu", Ppc4xxDcrDeviceState, cpu, TYPE_POWERPC_CPU, 686 PowerPCCPU *), 687 DEFINE_PROP_END_OF_LIST(), 688 }; 689 690 static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data) 691 { 692 DeviceClass *dc = DEVICE_CLASS(oc); 693 694 device_class_set_props(dc, ppc4xx_dcr_properties); 695 } 696 697 static const TypeInfo ppc4xx_types[] = { 698 { 699 .name = TYPE_PPC4xx_DCR_DEVICE, 700 .parent = TYPE_SYS_BUS_DEVICE, 701 .instance_size = sizeof(Ppc4xxDcrDeviceState), 702 .class_init = ppc4xx_dcr_class_init, 703 .abstract = true, 704 } 705 }; 706 707 DEFINE_TYPES(ppc4xx_types) 708