func: static void cchip_write(void *opaque, hwaddr addr,
  
                          uint64_t val, unsigned size)
  
  {
  
      TyphoonState *s = opaque;
  
      uint64_t oldval, newval;
  
  
  
      switch (addr) {
  
      case 0x0000:
  
          /* CSC: Cchip System Configuration Register.  */
  
          /* All sorts of data here; nothing relevant RW.  */
  
          break;
  
  
  
      case 0x0040:
  
          /* MTR: Memory Timing Register.  */
  
          /* All sorts of stuff related to real DRAM.  */
  
          break;
  
  
  
      case 0x0080:
  
          /* MISC: Miscellaneous Register.  */
  
          newval = oldval = s->cchip.misc;
  
          newval &= ~(val & 0x10000ff0);     /* W1C fields */
  
          if (val & 0x100000) {
  
              newval &= ~0xff0000ull;        /* ACL clears ABT and ABW */
  
          } else {
  
              newval |= val & 0x00f00000;    /* ABT field is W1S */
  
              if ((newval & 0xf0000) == 0) {
  
                  newval |= val & 0xf0000;   /* ABW field is W1S iff zero */
  
              }
  
          }
  
          newval |= (val & 0xf000) >> 4;     /* IPREQ field sets IPINTR.  */
  
  
  
          newval &= ~0xf0000000000ull;       /* WO and RW fields */
  
          newval |= val & 0xf0000000000ull;
  
          s->cchip.misc = newval;
  
  
  
          /* Pass on changes to IPI and ITI state.  */
  
          if ((newval ^ oldval) & 0xff0) {
  
              int i;
  
              for (i = 0; i < 4; ++i) {
  
                  AlphaCPU *cpu = s->cchip.cpu[i];
  
                  if (cpu != NULL) {
  
                      CPUState *cs = CPU(cpu);
  
                      /* IPI can be either cleared or set by the write.  */
  
                      if (newval & (1 << (i + 8))) {
  
                          cpu_interrupt(cs, CPU_INTERRUPT_SMP);
  
                      } else {
  
                          cpu_reset_interrupt(cs, CPU_INTERRUPT_SMP);
  
                      }
  
  
  
                      /* ITI can only be cleared by the write.  */
  
                      if ((newval & (1 << (i + 4))) == 0) {
  
                          cpu_reset_interrupt(cs, CPU_INTERRUPT_TIMER);
  
                      }
  
                  }
  
              }
  
          }
  
          break;
  
  
  
      case 0x00c0:
  
          /* MPD: Memory Presence Detect Register.  */
  
          break;
  
  
  
      case 0x0100: /* AAR0 */
  
      case 0x0140: /* AAR1 */
  
      case 0x0180: /* AAR2 */
  
      case 0x01c0: /* AAR3 */
  
          /* AAR: Array Address Register.  */
  
          /* All sorts of information about DRAM.  */
  
          break;
  
  
  
      case 0x0200: /* DIM0 */
  
          /* DIM: Device Interrupt Mask Register, CPU0.  */
  
          s->cchip.dim[0] = val;
  
          cpu_irq_change(s->cchip.cpu[0], val & s->cchip.drir);
  
          break;
  
      case 0x0240: /* DIM1 */
  
          /* DIM: Device Interrupt Mask Register, CPU1.  */
  
          s->cchip.dim[0] = val;
  
          cpu_irq_change(s->cchip.cpu[1], val & s->cchip.drir);
  
          break;
  
  
  
      case 0x0280: /* DIR0 (RO) */
  
      case 0x02c0: /* DIR1 (RO) */
  
      case 0x0300: /* DRIR (RO) */
  
          break;
  
  
  
      case 0x0340:
  
          /* PRBEN: Probe Enable Register.  */
  
          break;
  
  
  
      case 0x0380: /* IIC0 */
  
          s->cchip.iic[0] = val & 0xffffff;
  
          break;
  
      case 0x03c0: /* IIC1 */
  
          s->cchip.iic[1] = val & 0xffffff;
  
          break;
  
  
  
      case 0x0400: /* MPR0 */
  
      case 0x0440: /* MPR1 */
  
      case 0x0480: /* MPR2 */
  
      case 0x04c0: /* MPR3 */
  
          /* MPR: Memory Programming Register.  */
  
          break;
  
  
  
      case 0x0580:
  
          /* TTR: TIGbus Timing Register.  */
  
          /* All sorts of stuff related to interrupt delivery timings.  */
  
          break;
  
      case 0x05c0:
  
          /* TDR: TIGbug Device Timing Register.  */
  
          break;
  
  
  
      case 0x0600:
  
          /* DIM2: Device Interrupt Mask Register, CPU2.  */
  
          s->cchip.dim[2] = val;
  
          cpu_irq_change(s->cchip.cpu[2], val & s->cchip.drir);
  
          break;
  
      case 0x0640:
  
          /* DIM3: Device Interrupt Mask Register, CPU3.  */
  
          s->cchip.dim[3] = val;
  
          cpu_irq_change(s->cchip.cpu[3], val & s->cchip.drir);
  
          break;
  
  
  
      case 0x0680: /* DIR2 (RO) */
  
      case 0x06c0: /* DIR3 (RO) */
  
          break;
  
  
  
      case 0x0700: /* IIC2 */
  
          s->cchip.iic[2] = val & 0xffffff;
  
          break;
  
      case 0x0740: /* IIC3 */
  
          s->cchip.iic[3] = val & 0xffffff;
  
          break;
  
  
  
      case 0x0780:
  
          /* PWR: Power Management Control.   */
  
          break;
  
      
  
      case 0x0c00: /* CMONCTLA */
  
      case 0x0c40: /* CMONCTLB */
  
      case 0x0c80: /* CMONCNT01 */
  
      case 0x0cc0: /* CMONCNT23 */
  
          break;
  
  
  
      default:
  
          cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
  
          return;
  
      }
  
  }
  