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