func: static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
  
  {
  
      GICState *s = (GICState *)opaque;
  
      uint32_t res;
  
      int irq;
  
      int i;
  
      int cpu;
  
      int cm;
  
      int mask;
  
  
  
      cpu = gic_get_current_cpu(s);
  
      cm = 1 << cpu;
  
      if (offset < 0x100) {
  
          if (offset == 0)
  
              return s->enabled;
  
          if (offset == 4)
  
              /* Interrupt Controller Type Register */
  
              return ((s->num_irq / 32) - 1)
  
                      | ((NUM_CPU(s) - 1) << 5)
  
                      | (s->security_extn << 10);
  
          if (offset < 0x08)
  
              return 0;
  
          if (offset >= 0x80) {
  
              /* Interrupt Group Registers: these RAZ/WI if this is an NS
  
               * access to a GIC with the security extensions, or if the GIC
  
               * doesn't have groups at all.
  
               */
  
              res = 0;
  
              if (!(s->security_extn && !attrs.secure) && gic_has_groups(s)) {
  
                  /* Every byte offset holds 8 group status bits */
  
                  irq = (offset - 0x080) * 8 + GIC_BASE_IRQ;
  
                  if (irq >= s->num_irq) {
  
                      goto bad_reg;
  
                  }
  
                  for (i = 0; i < 8; i++) {
  
                      if (GIC_TEST_GROUP(irq + i, cm)) {
  
                          res |= (1 << i);
  
                      }
  
                  }
  
              }
  
              return res;
  
          }
  
          goto bad_reg;
  
      } else if (offset < 0x200) {
  
          /* Interrupt Set/Clear Enable.  */
  
          if (offset < 0x180)
  
              irq = (offset - 0x100) * 8;
  
          else
  
              irq = (offset - 0x180) * 8;
  
          irq += GIC_BASE_IRQ;
  
          if (irq >= s->num_irq)
  
              goto bad_reg;
  
          res = 0;
  
          for (i = 0; i < 8; i++) {
  
              if (GIC_TEST_ENABLED(irq + i, cm)) {
  
                  res |= (1 << i);
  
              }
  
          }
  
      } else if (offset < 0x300) {
  
          /* Interrupt Set/Clear Pending.  */
  
          if (offset < 0x280)
  
              irq = (offset - 0x200) * 8;
  
          else
  
              irq = (offset - 0x280) * 8;
  
          irq += GIC_BASE_IRQ;
  
          if (irq >= s->num_irq)
  
              goto bad_reg;
  
          res = 0;
  
          mask = (irq < GIC_INTERNAL) ?  cm : ALL_CPU_MASK;
  
          for (i = 0; i < 8; i++) {
  
              if (gic_test_pending(s, irq + i, mask)) {
  
                  res |= (1 << i);
  
              }
  
          }
  
      } else if (offset < 0x400) {
  
          /* Interrupt Active.  */
  
          irq = (offset - 0x300) * 8 + GIC_BASE_IRQ;
  
          if (irq >= s->num_irq)
  
              goto bad_reg;
  
          res = 0;
  
          mask = (irq < GIC_INTERNAL) ?  cm : ALL_CPU_MASK;
  
          for (i = 0; i < 8; i++) {
  
              if (GIC_TEST_ACTIVE(irq + i, mask)) {
  
                  res |= (1 << i);
  
              }
  
          }
  
      } else if (offset < 0x800) {
  
          /* Interrupt Priority.  */
  
          irq = (offset - 0x400) + GIC_BASE_IRQ;
  
          if (irq >= s->num_irq)
  
              goto bad_reg;
  
          res = GIC_GET_PRIORITY(irq, cpu);
  
      } else if (offset < 0xc00) {
  
          /* Interrupt CPU Target.  */
  
          if (s->num_cpu == 1 && s->revision != REV_11MPCORE) {
  
              /* For uniprocessor GICs these RAZ/WI */
  
              res = 0;
  
          } else {
  
              irq = (offset - 0x800) + GIC_BASE_IRQ;
  
              if (irq >= s->num_irq) {
  
                  goto bad_reg;
  
              }
  
              if (irq >= 29 && irq <= 31) {
  
                  res = cm;
  
              } else {
  
                  res = GIC_TARGET(irq);
  
              }
  
          }
  
      } else if (offset < 0xf00) {
  
          /* Interrupt Configuration.  */
  
          irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
  
          if (irq >= s->num_irq)
  
              goto bad_reg;
  
          res = 0;
  
          for (i = 0; i < 4; i++) {
  
              if (GIC_TEST_MODEL(irq + i))
  
                  res |= (1 << (i * 2));
  
              if (GIC_TEST_EDGE_TRIGGER(irq + i))
  
                  res |= (2 << (i * 2));
  
          }
  
      } else if (offset < 0xf10) {
  
          goto bad_reg;
  
      } else if (offset < 0xf30) {
  
          if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
  
              goto bad_reg;
  
          }
  
  
  
          if (offset < 0xf20) {
  
              /* GICD_CPENDSGIRn */
  
              irq = (offset - 0xf10);
  
          } else {
  
              irq = (offset - 0xf20);
  
              /* GICD_SPENDSGIRn */
  
          }
  
  
  
          res = s->sgi_pending[irq][cpu];
  
      } else if (offset < 0xfe0) {
  
          goto bad_reg;
  
      } else /* offset >= 0xfe0 */ {
  
          if (offset & 3) {
  
              res = 0;
  
          } else {
  
              res = gic_id[(offset - 0xfe0) >> 2];
  
          }
  
      }
  
      return res;
  
  bad_reg:
  
      qemu_log_mask(LOG_GUEST_ERROR,
  
                    "gic_dist_readb: Bad offset %x\n", (int)offset);
  
      return 0;
  
  }
  