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