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