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