qemu/hw/alpha/typhoon.c
<<
>>
Prefs
   1/*
   2 * DEC 21272 (TSUNAMI/TYPHOON) chipset emulation.
   3 *
   4 * Written by Richard Henderson.
   5 *
   6 * This work is licensed under the GNU GPL license version 2 or later.
   7 */
   8
   9#include "qemu/osdep.h"
  10#include "qapi/error.h"
  11#include "cpu.h"
  12#include "hw/hw.h"
  13#include "hw/devices.h"
  14#include "sysemu/sysemu.h"
  15#include "alpha_sys.h"
  16#include "exec/address-spaces.h"
  17
  18
  19#define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost"
  20
  21typedef struct TyphoonCchip {
  22    MemoryRegion region;
  23    uint64_t misc;
  24    uint64_t drir;
  25    uint64_t dim[4];
  26    uint32_t iic[4];
  27    AlphaCPU *cpu[4];
  28} TyphoonCchip;
  29
  30typedef struct TyphoonWindow {
  31    uint64_t wba;
  32    uint64_t wsm;
  33    uint64_t tba;
  34} TyphoonWindow;
  35 
  36typedef struct TyphoonPchip {
  37    MemoryRegion region;
  38    MemoryRegion reg_iack;
  39    MemoryRegion reg_mem;
  40    MemoryRegion reg_io;
  41    MemoryRegion reg_conf;
  42
  43    AddressSpace iommu_as;
  44    MemoryRegion iommu;
  45
  46    uint64_t ctl;
  47    TyphoonWindow win[4];
  48} TyphoonPchip;
  49
  50#define TYPHOON_PCI_HOST_BRIDGE(obj) \
  51    OBJECT_CHECK(TyphoonState, (obj), TYPE_TYPHOON_PCI_HOST_BRIDGE)
  52
  53typedef struct TyphoonState {
  54    PCIHostState parent_obj;
  55
  56    TyphoonCchip cchip;
  57    TyphoonPchip pchip;
  58    MemoryRegion dchip_region;
  59    MemoryRegion ram_region;
  60} TyphoonState;
  61
  62/* Called when one of DRIR or DIM changes.  */
  63static void cpu_irq_change(AlphaCPU *cpu, uint64_t req)
  64{
  65    /* If there are any non-masked interrupts, tell the cpu.  */
  66    if (cpu != NULL) {
  67        CPUState *cs = CPU(cpu);
  68        if (req) {
  69            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
  70        } else {
  71            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
  72        }
  73    }
  74}
  75
  76static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
  77{
  78    CPUState *cpu = current_cpu;
  79    TyphoonState *s = opaque;
  80    uint64_t ret = 0;
  81
  82    switch (addr) {
  83    case 0x0000:
  84        /* CSC: Cchip System Configuration Register.  */
  85        /* All sorts of data here; probably the only thing relevant is
  86           PIP<14> Pchip 1 Present = 0.  */
  87        break;
  88
  89    case 0x0040:
  90        /* MTR: Memory Timing Register.  */
  91        /* All sorts of stuff related to real DRAM.  */
  92        break;
  93
  94    case 0x0080:
  95        /* MISC: Miscellaneous Register.  */
  96        ret = s->cchip.misc | (cpu->cpu_index & 3);
  97        break;
  98
  99    case 0x00c0:
 100        /* MPD: Memory Presence Detect Register.  */
 101        break;
 102
 103    case 0x0100: /* AAR0 */
 104    case 0x0140: /* AAR1 */
 105    case 0x0180: /* AAR2 */
 106    case 0x01c0: /* AAR3 */
 107        /* AAR: Array Address Register.  */
 108        /* All sorts of information about DRAM.  */
 109        break;
 110
 111    case 0x0200:
 112        /* DIM0: Device Interrupt Mask Register, CPU0.  */
 113        ret = s->cchip.dim[0];
 114        break;
 115    case 0x0240:
 116        /* DIM1: Device Interrupt Mask Register, CPU1.  */
 117        ret = s->cchip.dim[1];
 118        break;
 119    case 0x0280:
 120        /* DIR0: Device Interrupt Request Register, CPU0.  */
 121        ret = s->cchip.dim[0] & s->cchip.drir;
 122        break;
 123    case 0x02c0:
 124        /* DIR1: Device Interrupt Request Register, CPU1.  */
 125        ret = s->cchip.dim[1] & s->cchip.drir;
 126        break;
 127    case 0x0300:
 128        /* DRIR: Device Raw Interrupt Request Register.  */
 129        ret = s->cchip.drir;
 130        break;
 131
 132    case 0x0340:
 133        /* PRBEN: Probe Enable Register.  */
 134        break;
 135
 136    case 0x0380:
 137        /* IIC0: Interval Ignore Count Register, CPU0.  */
 138        ret = s->cchip.iic[0];
 139        break;
 140    case 0x03c0:
 141        /* IIC1: Interval Ignore Count Register, CPU1.  */
 142        ret = s->cchip.iic[1];
 143        break;
 144
 145    case 0x0400: /* MPR0 */
 146    case 0x0440: /* MPR1 */
 147    case 0x0480: /* MPR2 */
 148    case 0x04c0: /* MPR3 */
 149        /* MPR: Memory Programming Register.  */
 150        break;
 151
 152    case 0x0580:
 153        /* TTR: TIGbus Timing Register.  */
 154        /* All sorts of stuff related to interrupt delivery timings.  */
 155        break;
 156    case 0x05c0:
 157        /* TDR: TIGbug Device Timing Register.  */
 158        break;
 159
 160    case 0x0600:
 161        /* DIM2: Device Interrupt Mask Register, CPU2.  */
 162        ret = s->cchip.dim[2];
 163        break;
 164    case 0x0640:
 165        /* DIM3: Device Interrupt Mask Register, CPU3.  */
 166        ret = s->cchip.dim[3];
 167        break;
 168    case 0x0680:
 169        /* DIR2: Device Interrupt Request Register, CPU2.  */
 170        ret = s->cchip.dim[2] & s->cchip.drir;
 171        break;
 172    case 0x06c0:
 173        /* DIR3: Device Interrupt Request Register, CPU3.  */
 174        ret = s->cchip.dim[3] & s->cchip.drir;
 175        break;
 176
 177    case 0x0700:
 178        /* IIC2: Interval Ignore Count Register, CPU2.  */
 179        ret = s->cchip.iic[2];
 180        break;
 181    case 0x0740:
 182        /* IIC3: Interval Ignore Count Register, CPU3.  */
 183        ret = s->cchip.iic[3];
 184        break;
 185
 186    case 0x0780:
 187        /* PWR: Power Management Control.   */
 188        break;
 189    
 190    case 0x0c00: /* CMONCTLA */
 191    case 0x0c40: /* CMONCTLB */
 192    case 0x0c80: /* CMONCNT01 */
 193    case 0x0cc0: /* CMONCNT23 */
 194        break;
 195
 196    default:
 197        cpu_unassigned_access(cpu, addr, false, false, 0, size);
 198        return -1;
 199    }
 200
 201    return ret;
 202}
 203
 204static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size)
 205{
 206    /* Skip this.  It's all related to DRAM timing and setup.  */
 207    return 0;
 208}
 209
 210static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
 211{
 212    TyphoonState *s = opaque;
 213    uint64_t ret = 0;
 214
 215    switch (addr) {
 216    case 0x0000:
 217        /* WSBA0: Window Space Base Address Register.  */
 218        ret = s->pchip.win[0].wba;
 219        break;
 220    case 0x0040:
 221        /* WSBA1 */
 222        ret = s->pchip.win[1].wba;
 223        break;
 224    case 0x0080:
 225        /* WSBA2 */
 226        ret = s->pchip.win[2].wba;
 227        break;
 228    case 0x00c0:
 229        /* WSBA3 */
 230        ret = s->pchip.win[3].wba;
 231        break;
 232
 233    case 0x0100:
 234        /* WSM0: Window Space Mask Register.  */
 235        ret = s->pchip.win[0].wsm;
 236        break;
 237    case 0x0140:
 238        /* WSM1 */
 239        ret = s->pchip.win[1].wsm;
 240        break;
 241    case 0x0180:
 242        /* WSM2 */
 243        ret = s->pchip.win[2].wsm;
 244        break;
 245    case 0x01c0:
 246        /* WSM3 */
 247        ret = s->pchip.win[3].wsm;
 248        break;
 249
 250    case 0x0200:
 251        /* TBA0: Translated Base Address Register.  */
 252        ret = s->pchip.win[0].tba;
 253        break;
 254    case 0x0240:
 255        /* TBA1 */
 256        ret = s->pchip.win[1].tba;
 257        break;
 258    case 0x0280:
 259        /* TBA2 */
 260        ret = s->pchip.win[2].tba;
 261        break;
 262    case 0x02c0:
 263        /* TBA3 */
 264        ret = s->pchip.win[3].tba;
 265        break;
 266
 267    case 0x0300:
 268        /* PCTL: Pchip Control Register.  */
 269        ret = s->pchip.ctl;
 270        break;
 271    case 0x0340:
 272        /* PLAT: Pchip Master Latency Register.  */
 273        break;
 274    case 0x03c0:
 275        /* PERROR: Pchip Error Register.  */
 276        break;
 277    case 0x0400:
 278        /* PERRMASK: Pchip Error Mask Register.  */
 279        break;
 280    case 0x0440:
 281        /* PERRSET: Pchip Error Set Register.  */
 282        break;
 283    case 0x0480:
 284        /* TLBIV: Translation Buffer Invalidate Virtual Register (WO).  */
 285        break;
 286    case 0x04c0:
 287        /* TLBIA: Translation Buffer Invalidate All Register (WO).  */
 288        break;
 289    case 0x0500: /* PMONCTL */
 290    case 0x0540: /* PMONCNT */
 291    case 0x0800: /* SPRST */
 292        break;
 293
 294    default:
 295        cpu_unassigned_access(current_cpu, addr, false, false, 0, size);
 296        return -1;
 297    }
 298
 299    return ret;
 300}
 301
 302static void cchip_write(void *opaque, hwaddr addr,
 303                        uint64_t val, unsigned size)
 304{
 305    TyphoonState *s = opaque;
 306    uint64_t oldval, newval;
 307
 308    switch (addr) {
 309    case 0x0000:
 310        /* CSC: Cchip System Configuration Register.  */
 311        /* All sorts of data here; nothing relevant RW.  */
 312        break;
 313
 314    case 0x0040:
 315        /* MTR: Memory Timing Register.  */
 316        /* All sorts of stuff related to real DRAM.  */
 317        break;
 318
 319    case 0x0080:
 320        /* MISC: Miscellaneous Register.  */
 321        newval = oldval = s->cchip.misc;
 322        newval &= ~(val & 0x10000ff0);     /* W1C fields */
 323        if (val & 0x100000) {
 324            newval &= ~0xff0000ull;        /* ACL clears ABT and ABW */
 325        } else {
 326            newval |= val & 0x00f00000;    /* ABT field is W1S */
 327            if ((newval & 0xf0000) == 0) {
 328                newval |= val & 0xf0000;   /* ABW field is W1S iff zero */
 329            }
 330        }
 331        newval |= (val & 0xf000) >> 4;     /* IPREQ field sets IPINTR.  */
 332
 333        newval &= ~0xf0000000000ull;       /* WO and RW fields */
 334        newval |= val & 0xf0000000000ull;
 335        s->cchip.misc = newval;
 336
 337        /* Pass on changes to IPI and ITI state.  */
 338        if ((newval ^ oldval) & 0xff0) {
 339            int i;
 340            for (i = 0; i < 4; ++i) {
 341                AlphaCPU *cpu = s->cchip.cpu[i];
 342                if (cpu != NULL) {
 343                    CPUState *cs = CPU(cpu);
 344                    /* IPI can be either cleared or set by the write.  */
 345                    if (newval & (1 << (i + 8))) {
 346                        cpu_interrupt(cs, CPU_INTERRUPT_SMP);
 347                    } else {
 348                        cpu_reset_interrupt(cs, CPU_INTERRUPT_SMP);
 349                    }
 350
 351                    /* ITI can only be cleared by the write.  */
 352                    if ((newval & (1 << (i + 4))) == 0) {
 353                        cpu_reset_interrupt(cs, CPU_INTERRUPT_TIMER);
 354                    }
 355                }
 356            }
 357        }
 358        break;
 359
 360    case 0x00c0:
 361        /* MPD: Memory Presence Detect Register.  */
 362        break;
 363
 364    case 0x0100: /* AAR0 */
 365    case 0x0140: /* AAR1 */
 366    case 0x0180: /* AAR2 */
 367    case 0x01c0: /* AAR3 */
 368        /* AAR: Array Address Register.  */
 369        /* All sorts of information about DRAM.  */
 370        break;
 371
 372    case 0x0200: /* DIM0 */
 373        /* DIM: Device Interrupt Mask Register, CPU0.  */
 374        s->cchip.dim[0] = val;
 375        cpu_irq_change(s->cchip.cpu[0], val & s->cchip.drir);
 376        break;
 377    case 0x0240: /* DIM1 */
 378        /* DIM: Device Interrupt Mask Register, CPU1.  */
 379        s->cchip.dim[0] = val;
 380        cpu_irq_change(s->cchip.cpu[1], val & s->cchip.drir);
 381        break;
 382
 383    case 0x0280: /* DIR0 (RO) */
 384    case 0x02c0: /* DIR1 (RO) */
 385    case 0x0300: /* DRIR (RO) */
 386        break;
 387
 388    case 0x0340:
 389        /* PRBEN: Probe Enable Register.  */
 390        break;
 391
 392    case 0x0380: /* IIC0 */
 393        s->cchip.iic[0] = val & 0xffffff;
 394        break;
 395    case 0x03c0: /* IIC1 */
 396        s->cchip.iic[1] = val & 0xffffff;
 397        break;
 398
 399    case 0x0400: /* MPR0 */
 400    case 0x0440: /* MPR1 */
 401    case 0x0480: /* MPR2 */
 402    case 0x04c0: /* MPR3 */
 403        /* MPR: Memory Programming Register.  */
 404        break;
 405
 406    case 0x0580:
 407        /* TTR: TIGbus Timing Register.  */
 408        /* All sorts of stuff related to interrupt delivery timings.  */
 409        break;
 410    case 0x05c0:
 411        /* TDR: TIGbug Device Timing Register.  */
 412        break;
 413
 414    case 0x0600:
 415        /* DIM2: Device Interrupt Mask Register, CPU2.  */
 416        s->cchip.dim[2] = val;
 417        cpu_irq_change(s->cchip.cpu[2], val & s->cchip.drir);
 418        break;
 419    case 0x0640:
 420        /* DIM3: Device Interrupt Mask Register, CPU3.  */
 421        s->cchip.dim[3] = val;
 422        cpu_irq_change(s->cchip.cpu[3], val & s->cchip.drir);
 423        break;
 424
 425    case 0x0680: /* DIR2 (RO) */
 426    case 0x06c0: /* DIR3 (RO) */
 427        break;
 428
 429    case 0x0700: /* IIC2 */
 430        s->cchip.iic[2] = val & 0xffffff;
 431        break;
 432    case 0x0740: /* IIC3 */
 433        s->cchip.iic[3] = val & 0xffffff;
 434        break;
 435
 436    case 0x0780:
 437        /* PWR: Power Management Control.   */
 438        break;
 439    
 440    case 0x0c00: /* CMONCTLA */
 441    case 0x0c40: /* CMONCTLB */
 442    case 0x0c80: /* CMONCNT01 */
 443    case 0x0cc0: /* CMONCNT23 */
 444        break;
 445
 446    default:
 447        cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
 448        return;
 449    }
 450}
 451
 452static void dchip_write(void *opaque, hwaddr addr,
 453                        uint64_t val, unsigned size)
 454{
 455    /* Skip this.  It's all related to DRAM timing and setup.  */
 456}
 457
 458static void pchip_write(void *opaque, hwaddr addr,
 459                        uint64_t val, unsigned size)
 460{
 461    TyphoonState *s = opaque;
 462    uint64_t oldval;
 463
 464    switch (addr) {
 465    case 0x0000:
 466        /* WSBA0: Window Space Base Address Register.  */
 467        s->pchip.win[0].wba = val & 0xfff00003u;
 468        break;
 469    case 0x0040:
 470        /* WSBA1 */
 471        s->pchip.win[1].wba = val & 0xfff00003u;
 472        break;
 473    case 0x0080:
 474        /* WSBA2 */
 475        s->pchip.win[2].wba = val & 0xfff00003u;
 476        break;
 477    case 0x00c0:
 478        /* WSBA3 */
 479        s->pchip.win[3].wba = (val & 0x80fff00001ull) | 2;
 480        break;
 481
 482    case 0x0100:
 483        /* WSM0: Window Space Mask Register.  */
 484        s->pchip.win[0].wsm = val & 0xfff00000u;
 485        break;
 486    case 0x0140:
 487        /* WSM1 */
 488        s->pchip.win[1].wsm = val & 0xfff00000u;
 489        break;
 490    case 0x0180:
 491        /* WSM2 */
 492        s->pchip.win[2].wsm = val & 0xfff00000u;
 493        break;
 494    case 0x01c0:
 495        /* WSM3 */
 496        s->pchip.win[3].wsm = val & 0xfff00000u;
 497        break;
 498
 499    case 0x0200:
 500        /* TBA0: Translated Base Address Register.  */
 501        s->pchip.win[0].tba = val & 0x7fffffc00ull;
 502        break;
 503    case 0x0240:
 504        /* TBA1 */
 505        s->pchip.win[1].tba = val & 0x7fffffc00ull;
 506        break;
 507    case 0x0280:
 508        /* TBA2 */
 509        s->pchip.win[2].tba = val & 0x7fffffc00ull;
 510        break;
 511    case 0x02c0:
 512        /* TBA3 */
 513        s->pchip.win[3].tba = val & 0x7fffffc00ull;
 514        break;
 515
 516    case 0x0300:
 517        /* PCTL: Pchip Control Register.  */
 518        oldval = s->pchip.ctl;
 519        oldval &= ~0x00001cff0fc7ffull;       /* RW fields */
 520        oldval |= val & 0x00001cff0fc7ffull;
 521        s->pchip.ctl = oldval;
 522        break;
 523
 524    case 0x0340:
 525        /* PLAT: Pchip Master Latency Register.  */
 526        break;
 527    case 0x03c0:
 528        /* PERROR: Pchip Error Register.  */
 529        break;
 530    case 0x0400:
 531        /* PERRMASK: Pchip Error Mask Register.  */
 532        break;
 533    case 0x0440:
 534        /* PERRSET: Pchip Error Set Register.  */
 535        break;
 536
 537    case 0x0480:
 538        /* TLBIV: Translation Buffer Invalidate Virtual Register.  */
 539        break;
 540
 541    case 0x04c0:
 542        /* TLBIA: Translation Buffer Invalidate All Register (WO).  */
 543        break;
 544
 545    case 0x0500:
 546        /* PMONCTL */
 547    case 0x0540:
 548        /* PMONCNT */
 549    case 0x0800:
 550        /* SPRST */
 551        break;
 552
 553    default:
 554        cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
 555        return;
 556    }
 557}
 558
 559static const MemoryRegionOps cchip_ops = {
 560    .read = cchip_read,
 561    .write = cchip_write,
 562    .endianness = DEVICE_LITTLE_ENDIAN,
 563    .valid = {
 564        .min_access_size = 8,
 565        .max_access_size = 8,
 566    },
 567    .impl = {
 568        .min_access_size = 8,
 569        .max_access_size = 8,
 570    },
 571};
 572
 573static const MemoryRegionOps dchip_ops = {
 574    .read = dchip_read,
 575    .write = dchip_write,
 576    .endianness = DEVICE_LITTLE_ENDIAN,
 577    .valid = {
 578        .min_access_size = 8,
 579        .max_access_size = 8,
 580    },
 581    .impl = {
 582        .min_access_size = 8,
 583        .max_access_size = 8,
 584    },
 585};
 586
 587static const MemoryRegionOps pchip_ops = {
 588    .read = pchip_read,
 589    .write = pchip_write,
 590    .endianness = DEVICE_LITTLE_ENDIAN,
 591    .valid = {
 592        .min_access_size = 8,
 593        .max_access_size = 8,
 594    },
 595    .impl = {
 596        .min_access_size = 8,
 597        .max_access_size = 8,
 598    },
 599};
 600
 601/* A subroutine of typhoon_translate_iommu that builds an IOMMUTLBEntry
 602   using the given translated address and mask.  */
 603static bool make_iommu_tlbe(hwaddr taddr, hwaddr mask, IOMMUTLBEntry *ret)
 604{
 605    *ret = (IOMMUTLBEntry) {
 606        .target_as = &address_space_memory,
 607        .translated_addr = taddr,
 608        .addr_mask = mask,
 609        .perm = IOMMU_RW,
 610    };
 611    return true;
 612}
 613
 614/* A subroutine of typhoon_translate_iommu that handles scatter-gather
 615   translation, given the address of the PTE.  */
 616static bool pte_translate(hwaddr pte_addr, IOMMUTLBEntry *ret)
 617{
 618    uint64_t pte = address_space_ldq(&address_space_memory, pte_addr,
 619                                     MEMTXATTRS_UNSPECIFIED, NULL);
 620
 621    /* Check valid bit.  */
 622    if ((pte & 1) == 0) {
 623        return false;
 624    }
 625
 626    return make_iommu_tlbe((pte & 0x3ffffe) << 12, 0x1fff, ret);
 627}
 628
 629/* A subroutine of typhoon_translate_iommu that handles one of the
 630   four single-address-cycle translation windows.  */
 631static bool window_translate(TyphoonWindow *win, hwaddr addr,
 632                             IOMMUTLBEntry *ret)
 633{
 634    uint32_t wba = win->wba;
 635    uint64_t wsm = win->wsm;
 636    uint64_t tba = win->tba;
 637    uint64_t wsm_ext = wsm | 0xfffff;
 638
 639    /* Check for window disabled.  */
 640    if ((wba & 1) == 0) {
 641        return false;
 642    }
 643
 644    /* Check for window hit.  */
 645    if ((addr & ~wsm_ext) != (wba & 0xfff00000u)) {
 646        return false;
 647    }
 648
 649    if (wba & 2) {
 650        /* Scatter-gather translation.  */
 651        hwaddr pte_addr;
 652
 653        /* See table 10-6, Generating PTE address for PCI DMA Address.  */
 654        pte_addr  = tba & ~(wsm >> 10);
 655        pte_addr |= (addr & (wsm | 0xfe000)) >> 10;
 656        return pte_translate(pte_addr, ret);
 657    } else {
 658        /* Direct-mapped translation.  */
 659        return make_iommu_tlbe(tba & ~wsm_ext, wsm_ext, ret);
 660    }
 661}
 662
 663/* Handle PCI-to-system address translation.  */
 664/* TODO: A translation failure here ought to set PCI error codes on the
 665   Pchip and generate a machine check interrupt.  */
 666static IOMMUTLBEntry typhoon_translate_iommu(MemoryRegion *iommu, hwaddr addr,
 667                                             bool is_write)
 668{
 669    TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu);
 670    IOMMUTLBEntry ret;
 671    int i;
 672
 673    if (addr <= 0xffffffffu) {
 674        /* Single-address cycle.  */
 675
 676        /* Check for the Window Hole, inhibiting matching.  */
 677        if ((pchip->ctl & 0x20)
 678            && addr >= 0x80000
 679            && addr <= 0xfffff) {
 680            goto failure;
 681        }
 682
 683        /* Check the first three windows.  */
 684        for (i = 0; i < 3; ++i) {
 685            if (window_translate(&pchip->win[i], addr, &ret)) {
 686                goto success;
 687            }
 688        }
 689
 690        /* Check the fourth window for DAC disable.  */
 691        if ((pchip->win[3].wba & 0x80000000000ull) == 0
 692            && window_translate(&pchip->win[3], addr, &ret)) {
 693            goto success;
 694        }
 695    } else {
 696        /* Double-address cycle.  */
 697
 698        if (addr >= 0x10000000000ull && addr < 0x20000000000ull) {
 699            /* Check for the DMA monster window.  */
 700            if (pchip->ctl & 0x40) {
 701                /* See 10.1.4.4; in particular <39:35> is ignored.  */
 702                make_iommu_tlbe(0, 0x007ffffffffull, &ret);
 703                goto success;
 704            }
 705        }
 706
 707        if (addr >= 0x80000000000ull && addr <= 0xfffffffffffull) {
 708            /* Check the fourth window for DAC enable and window enable.  */
 709            if ((pchip->win[3].wba & 0x80000000001ull) == 0x80000000001ull) {
 710                uint64_t pte_addr;
 711
 712                pte_addr  = pchip->win[3].tba & 0x7ffc00000ull;
 713                pte_addr |= (addr & 0xffffe000u) >> 10;
 714                if (pte_translate(pte_addr, &ret)) {
 715                        goto success;
 716                }
 717            }
 718        }
 719    }
 720
 721 failure:
 722    ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE };
 723 success:
 724    return ret;
 725}
 726
 727static const MemoryRegionIOMMUOps typhoon_iommu_ops = {
 728    .translate = typhoon_translate_iommu,
 729};
 730
 731static AddressSpace *typhoon_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
 732{
 733    TyphoonState *s = opaque;
 734    return &s->pchip.iommu_as;
 735}
 736
 737static void typhoon_set_irq(void *opaque, int irq, int level)
 738{
 739    TyphoonState *s = opaque;
 740    uint64_t drir;
 741    int i;
 742
 743    /* Set/Reset the bit in CCHIP.DRIR based on IRQ+LEVEL.  */
 744    drir = s->cchip.drir;
 745    if (level) {
 746        drir |= 1ull << irq;
 747    } else {
 748        drir &= ~(1ull << irq);
 749    }
 750    s->cchip.drir = drir;
 751
 752    for (i = 0; i < 4; ++i) {
 753        cpu_irq_change(s->cchip.cpu[i], s->cchip.dim[i] & drir);
 754    }
 755}
 756
 757static void typhoon_set_isa_irq(void *opaque, int irq, int level)
 758{
 759    typhoon_set_irq(opaque, 55, level);
 760}
 761
 762static void typhoon_set_timer_irq(void *opaque, int irq, int level)
 763{
 764    TyphoonState *s = opaque;
 765    int i;
 766
 767    /* Thankfully, the mc146818rtc code doesn't track the IRQ state,
 768       and so we don't have to worry about missing interrupts just
 769       because we never actually ACK the interrupt.  Just ignore any
 770       case of the interrupt level going low.  */
 771    if (level == 0) {
 772        return;
 773    }
 774
 775    /* Deliver the interrupt to each CPU, considering each CPU's IIC.  */
 776    for (i = 0; i < 4; ++i) {
 777        AlphaCPU *cpu = s->cchip.cpu[i];
 778        if (cpu != NULL) {
 779            uint32_t iic = s->cchip.iic[i];
 780
 781            /* ??? The verbage in Section 10.2.2.10 isn't 100% clear.
 782               Bit 24 is the OverFlow bit, RO, and set when the count
 783               decrements past 0.  When is OF cleared?  My guess is that
 784               OF is actually cleared when the IIC is written, and that
 785               the ICNT field always decrements.  At least, that's an
 786               interpretation that makes sense, and "allows the CPU to
 787               determine exactly how mant interval timer ticks were
 788               skipped".  At least within the next 4M ticks...  */
 789
 790            iic = ((iic - 1) & 0x1ffffff) | (iic & 0x1000000);
 791            s->cchip.iic[i] = iic;
 792
 793            if (iic & 0x1000000) {
 794                /* Set the ITI bit for this cpu.  */
 795                s->cchip.misc |= 1 << (i + 4);
 796                /* And signal the interrupt.  */
 797                cpu_interrupt(CPU(cpu), CPU_INTERRUPT_TIMER);
 798            }
 799        }
 800    }
 801}
 802
 803static void typhoon_alarm_timer(void *opaque)
 804{
 805    TyphoonState *s = (TyphoonState *)((uintptr_t)opaque & ~3);
 806    int cpu = (uintptr_t)opaque & 3;
 807
 808    /* Set the ITI bit for this cpu.  */
 809    s->cchip.misc |= 1 << (cpu + 4);
 810    cpu_interrupt(CPU(s->cchip.cpu[cpu]), CPU_INTERRUPT_TIMER);
 811}
 812
 813PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
 814                     qemu_irq *p_rtc_irq,
 815                     AlphaCPU *cpus[4], pci_map_irq_fn sys_map_irq)
 816{
 817    const uint64_t MB = 1024 * 1024;
 818    const uint64_t GB = 1024 * MB;
 819    MemoryRegion *addr_space = get_system_memory();
 820    DeviceState *dev;
 821    TyphoonState *s;
 822    PCIHostState *phb;
 823    PCIBus *b;
 824    int i;
 825
 826    dev = qdev_create(NULL, TYPE_TYPHOON_PCI_HOST_BRIDGE);
 827    qdev_init_nofail(dev);
 828
 829    s = TYPHOON_PCI_HOST_BRIDGE(dev);
 830    phb = PCI_HOST_BRIDGE(dev);
 831
 832    s->cchip.misc = 0x800000000ull; /* Revision: Typhoon.  */
 833    s->pchip.win[3].wba = 2;        /* Window 3 SG always enabled. */
 834
 835    /* Remember the CPUs so that we can deliver interrupts to them.  */
 836    for (i = 0; i < 4; i++) {
 837        AlphaCPU *cpu = cpus[i];
 838        s->cchip.cpu[i] = cpu;
 839        if (cpu != NULL) {
 840            cpu->alarm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
 841                                                 typhoon_alarm_timer,
 842                                                 (void *)((uintptr_t)s + i));
 843        }
 844    }
 845
 846    *p_rtc_irq = qemu_allocate_irq(typhoon_set_timer_irq, s, 0);
 847
 848    /* Main memory region, 0x00.0000.0000.  Real hardware supports 32GB,
 849       but the address space hole reserved at this point is 8TB.  */
 850    memory_region_allocate_system_memory(&s->ram_region, OBJECT(s), "ram",
 851                                         ram_size);
 852    memory_region_add_subregion(addr_space, 0, &s->ram_region);
 853
 854    /* TIGbus, 0x801.0000.0000, 1GB.  */
 855    /* ??? The TIGbus is used for delivering interrupts, and access to
 856       the flash ROM.  I'm not sure that we need to implement it at all.  */
 857
 858    /* Pchip0 CSRs, 0x801.8000.0000, 256MB.  */
 859    memory_region_init_io(&s->pchip.region, OBJECT(s), &pchip_ops, s, "pchip0",
 860                          256*MB);
 861    memory_region_add_subregion(addr_space, 0x80180000000ULL,
 862                                &s->pchip.region);
 863
 864    /* Cchip CSRs, 0x801.A000.0000, 256MB.  */
 865    memory_region_init_io(&s->cchip.region, OBJECT(s), &cchip_ops, s, "cchip0",
 866                          256*MB);
 867    memory_region_add_subregion(addr_space, 0x801a0000000ULL,
 868                                &s->cchip.region);
 869
 870    /* Dchip CSRs, 0x801.B000.0000, 256MB.  */
 871    memory_region_init_io(&s->dchip_region, OBJECT(s), &dchip_ops, s, "dchip0",
 872                          256*MB);
 873    memory_region_add_subregion(addr_space, 0x801b0000000ULL,
 874                                &s->dchip_region);
 875
 876    /* Pchip0 PCI memory, 0x800.0000.0000, 4GB.  */
 877    memory_region_init(&s->pchip.reg_mem, OBJECT(s), "pci0-mem", 4*GB);
 878    memory_region_add_subregion(addr_space, 0x80000000000ULL,
 879                                &s->pchip.reg_mem);
 880
 881    /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB.  */
 882    memory_region_init_io(&s->pchip.reg_io, OBJECT(s), &alpha_pci_ignore_ops,
 883                          NULL, "pci0-io", 32*MB);
 884    memory_region_add_subregion(addr_space, 0x801fc000000ULL,
 885                                &s->pchip.reg_io);
 886
 887    b = pci_register_bus(dev, "pci",
 888                         typhoon_set_irq, sys_map_irq, s,
 889                         &s->pchip.reg_mem, &s->pchip.reg_io,
 890                         0, 64, TYPE_PCI_BUS);
 891    phb->bus = b;
 892
 893    /* Host memory as seen from the PCI side, via the IOMMU.  */
 894    memory_region_init_iommu(&s->pchip.iommu, OBJECT(s), &typhoon_iommu_ops,
 895                             "iommu-typhoon", UINT64_MAX);
 896    address_space_init(&s->pchip.iommu_as, &s->pchip.iommu, "pchip0-pci");
 897    pci_setup_iommu(b, typhoon_pci_dma_iommu, s);
 898
 899    /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB.  */
 900    memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
 901                          b, "pci0-iack", 64*MB);
 902    memory_region_add_subregion(addr_space, 0x801f8000000ULL,
 903                                &s->pchip.reg_iack);
 904
 905    /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB.  */
 906    memory_region_init_io(&s->pchip.reg_conf, OBJECT(s), &alpha_pci_conf1_ops,
 907                          b, "pci0-conf", 16*MB);
 908    memory_region_add_subregion(addr_space, 0x801fe000000ULL,
 909                                &s->pchip.reg_conf);
 910
 911    /* For the record, these are the mappings for the second PCI bus.
 912       We can get away with not implementing them because we indicate
 913       via the Cchip.CSC<PIP> bit that Pchip1 is not present.  */
 914    /* Pchip1 PCI memory, 0x802.0000.0000, 4GB.  */
 915    /* Pchip1 CSRs, 0x802.8000.0000, 256MB.  */
 916    /* Pchip1 PCI special/interrupt acknowledge, 0x802.F800.0000, 64MB.  */
 917    /* Pchip1 PCI I/O, 0x802.FC00.0000, 32MB.  */
 918    /* Pchip1 PCI configuration, 0x802.FE00.0000, 16MB.  */
 919
 920    /* Init the ISA bus.  */
 921    /* ??? Technically there should be a cy82c693ub pci-isa bridge.  */
 922    {
 923        qemu_irq *isa_irqs;
 924
 925        *isa_bus = isa_bus_new(NULL, get_system_memory(), &s->pchip.reg_io,
 926                               &error_abort);
 927        isa_irqs = i8259_init(*isa_bus,
 928                              qemu_allocate_irq(typhoon_set_isa_irq, s, 0));
 929        isa_bus_irqs(*isa_bus, isa_irqs);
 930    }
 931
 932    return b;
 933}
 934
 935static int typhoon_pcihost_init(SysBusDevice *dev)
 936{
 937    return 0;
 938}
 939
 940static void typhoon_pcihost_class_init(ObjectClass *klass, void *data)
 941{
 942    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 943
 944    k->init = typhoon_pcihost_init;
 945}
 946
 947static const TypeInfo typhoon_pcihost_info = {
 948    .name          = TYPE_TYPHOON_PCI_HOST_BRIDGE,
 949    .parent        = TYPE_PCI_HOST_BRIDGE,
 950    .instance_size = sizeof(TyphoonState),
 951    .class_init    = typhoon_pcihost_class_init,
 952};
 953
 954static void typhoon_register_types(void)
 955{
 956    type_register_static(&typhoon_pcihost_info);
 957}
 958
 959type_init(typhoon_register_types)
 960