Diff for /qemu/hw/openpic.c between versions 1.1.1.6 and 1.1.1.7

version 1.1.1.6, 2018/04/24 17:37:10 version 1.1.1.7, 2018/04/24 18:28:07
Line 141  enum mpic_ide_bits { Line 141  enum mpic_ide_bits {
 #error "Please select which OpenPic implementation is to be emulated"  #error "Please select which OpenPic implementation is to be emulated"
 #endif  #endif
   
   #define OPENPIC_PAGE_SIZE 4096
   
 #define BF_WIDTH(_bits_) \  #define BF_WIDTH(_bits_) \
 (((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))  (((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
   
Line 219  typedef struct openpic_t { Line 221  typedef struct openpic_t {
     int nb_cpus;      int nb_cpus;
     /* Timer registers */      /* Timer registers */
     struct {      struct {
         uint32_t ticc;  /* Global timer current count register */          uint32_t ticc;  /* Global timer current count register */
         uint32_t tibc;  /* Global timer base count register */          uint32_t tibc;  /* Global timer base count register */
     } timers[MAX_TMR];      } timers[MAX_TMR];
 #if MAX_DBL > 0  #if MAX_DBL > 0
     /* Doorbell registers */      /* Doorbell registers */
     uint32_t dar;        /* Doorbell activate register */      uint32_t dar;        /* Doorbell activate register */
     struct {      struct {
         uint32_t dmr;    /* Doorbell messaging register */          uint32_t dmr;    /* Doorbell messaging register */
     } doorbells[MAX_DBL];      } doorbells[MAX_DBL];
 #endif  #endif
 #if MAX_MBX > 0  #if MAX_MBX > 0
     /* Mailbox registers */      /* Mailbox registers */
     struct {      struct {
         uint32_t mbr;    /* Mailbox register */          uint32_t mbr;    /* Mailbox register */
     } mailboxes[MAX_MAILBOXES];      } mailboxes[MAX_MAILBOXES];
 #endif  #endif
     /* IRQ out is used when in bypass mode (not implemented) */      /* IRQ out is used when in bypass mode (not implemented) */
Line 276  static void IRQ_check (openpic_t *opp, I Line 278  static void IRQ_check (openpic_t *opp, I
     next = -1;      next = -1;
     priority = -1;      priority = -1;
     for (i = 0; i < opp->max_irq; i++) {      for (i = 0; i < opp->max_irq; i++) {
         if (IRQ_testbit(q, i)) {          if (IRQ_testbit(q, i)) {
             DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",              DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
                     i, IPVP_PRIORITY(opp->src[i].ipvp), priority);                      i, IPVP_PRIORITY(opp->src[i].ipvp), priority);
             if (IPVP_PRIORITY(opp->src[i].ipvp) > priority) {              if (IPVP_PRIORITY(opp->src[i].ipvp) > priority) {
                 next = i;                  next = i;
                 priority = IPVP_PRIORITY(opp->src[i].ipvp);                  priority = IPVP_PRIORITY(opp->src[i].ipvp);
             }              }
         }          }
     }      }
     q->next = next;      q->next = next;
     q->priority = priority;      q->priority = priority;
Line 293  static int IRQ_get_next (openpic_t *opp, Line 295  static int IRQ_get_next (openpic_t *opp,
 {  {
     if (q->next == -1) {      if (q->next == -1) {
         /* XXX: optimize */          /* XXX: optimize */
         IRQ_check(opp, q);          IRQ_check(opp, q);
     }      }
   
     return q->next;      return q->next;
Line 309  static void IRQ_local_pipe (openpic_t *o Line 311  static void IRQ_local_pipe (openpic_t *o
     src = &opp->src[n_IRQ];      src = &opp->src[n_IRQ];
     priority = IPVP_PRIORITY(src->ipvp);      priority = IPVP_PRIORITY(src->ipvp);
     if (priority <= dst->pctp) {      if (priority <= dst->pctp) {
         /* Too low priority */          /* Too low priority */
         DPRINTF("%s: IRQ %d has too low priority on CPU %d\n",          DPRINTF("%s: IRQ %d has too low priority on CPU %d\n",
                 __func__, n_IRQ, n_CPU);                  __func__, n_IRQ, n_CPU);
         return;          return;
     }      }
     if (IRQ_testbit(&dst->raised, n_IRQ)) {      if (IRQ_testbit(&dst->raised, n_IRQ)) {
         /* Interrupt miss */          /* Interrupt miss */
         DPRINTF("%s: IRQ %d was missed on CPU %d\n",          DPRINTF("%s: IRQ %d was missed on CPU %d\n",
                 __func__, n_IRQ, n_CPU);                  __func__, n_IRQ, n_CPU);
         return;          return;
     }      }
     set_bit(&src->ipvp, IPVP_ACTIVITY);      set_bit(&src->ipvp, IPVP_ACTIVITY);
     IRQ_setbit(&dst->raised, n_IRQ);      IRQ_setbit(&dst->raised, n_IRQ);
Line 354  static void openpic_update_irq(openpic_t Line 356  static void openpic_update_irq(openpic_t
         return;          return;
     }      }
     if (test_bit(&src->ipvp, IPVP_MASK)) {      if (test_bit(&src->ipvp, IPVP_MASK)) {
         /* Interrupt source is disabled */          /* Interrupt source is disabled */
         DPRINTF("%s: IRQ %d is disabled\n", __func__, n_IRQ);          DPRINTF("%s: IRQ %d is disabled\n", __func__, n_IRQ);
         return;          return;
     }      }
     if (IPVP_PRIORITY(src->ipvp) == 0) {      if (IPVP_PRIORITY(src->ipvp) == 0) {
         /* Priority set to zero */          /* Priority set to zero */
         DPRINTF("%s: IRQ %d has 0 priority\n", __func__, n_IRQ);          DPRINTF("%s: IRQ %d has 0 priority\n", __func__, n_IRQ);
         return;          return;
     }      }
     if (test_bit(&src->ipvp, IPVP_ACTIVITY)) {      if (test_bit(&src->ipvp, IPVP_ACTIVITY)) {
         /* IRQ already active */          /* IRQ already active */
Line 369  static void openpic_update_irq(openpic_t Line 371  static void openpic_update_irq(openpic_t
         return;          return;
     }      }
     if (src->ide == 0x00000000) {      if (src->ide == 0x00000000) {
         /* No target */          /* No target */
         DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ);          DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ);
         return;          return;
     }      }
   
     if (src->ide == (1 << src->last_cpu)) {      if (src->ide == (1 << src->last_cpu)) {
Line 434  static void openpic_reset (void *opaque) Line 436  static void openpic_reset (void *opaque)
     opp->micr = 0x00000000;      opp->micr = 0x00000000;
     /* Initialise IRQ sources */      /* Initialise IRQ sources */
     for (i = 0; i < opp->max_irq; i++) {      for (i = 0; i < opp->max_irq; i++) {
         opp->src[i].ipvp = 0xA0000000;          opp->src[i].ipvp = 0xA0000000;
         opp->src[i].ide  = 0x00000000;          opp->src[i].ide  = 0x00000000;
     }      }
     /* Initialise IRQ destinations */      /* Initialise IRQ destinations */
     for (i = 0; i < MAX_CPU; i++) {      for (i = 0; i < MAX_CPU; i++) {
         opp->dst[i].pctp      = 0x0000000F;          opp->dst[i].pctp      = 0x0000000F;
         opp->dst[i].pcsr      = 0x00000000;          opp->dst[i].pcsr      = 0x00000000;
         memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t));          memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t));
         memset(&opp->dst[i].servicing, 0, sizeof(IRQ_queue_t));          opp->dst[i].raised.next = -1;
           memset(&opp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
           opp->dst[i].servicing.next = -1;
     }      }
     /* Initialise timers */      /* Initialise timers */
     for (i = 0; i < MAX_TMR; i++) {      for (i = 0; i < MAX_TMR; i++) {
         opp->timers[i].ticc = 0x00000000;          opp->timers[i].ticc = 0x00000000;
         opp->timers[i].tibc = 0x80000000;          opp->timers[i].tibc = 0x80000000;
     }      }
     /* Initialise doorbells */      /* Initialise doorbells */
 #if MAX_DBL > 0  #if MAX_DBL > 0
     opp->dar = 0x00000000;      opp->dar = 0x00000000;
     for (i = 0; i < MAX_DBL; i++) {      for (i = 0; i < MAX_DBL; i++) {
         opp->doorbells[i].dmr  = 0x00000000;          opp->doorbells[i].dmr  = 0x00000000;
     }      }
 #endif  #endif
     /* Initialise mailboxes */      /* Initialise mailboxes */
 #if MAX_MBX > 0  #if MAX_MBX > 0
     for (i = 0; i < MAX_MBX; i++) { /* ? */      for (i = 0; i < MAX_MBX; i++) { /* ? */
         opp->mailboxes[i].mbr   = 0x00000000;          opp->mailboxes[i].mbr   = 0x00000000;
     }      }
 #endif  #endif
     /* Go out of RESET state */      /* Go out of RESET state */
Line 472  static inline uint32_t read_IRQreg (open Line 476  static inline uint32_t read_IRQreg (open
   
     switch (reg) {      switch (reg) {
     case IRQ_IPVP:      case IRQ_IPVP:
         retval = opp->src[n_IRQ].ipvp;          retval = opp->src[n_IRQ].ipvp;
         break;          break;
     case IRQ_IDE:      case IRQ_IDE:
         retval = opp->src[n_IRQ].ide;          retval = opp->src[n_IRQ].ide;
         break;          break;
     }      }
   
     return retval;      return retval;
Line 492  static inline void write_IRQreg (openpic Line 496  static inline void write_IRQreg (openpic
         /* NOTE: not fully accurate for special IRQs, but simple and          /* NOTE: not fully accurate for special IRQs, but simple and
            sufficient */             sufficient */
         /* ACTIVITY bit is read-only */          /* ACTIVITY bit is read-only */
         opp->src[n_IRQ].ipvp =          opp->src[n_IRQ].ipvp =
             (opp->src[n_IRQ].ipvp & 0x40000000) |              (opp->src[n_IRQ].ipvp & 0x40000000) |
             (val & 0x800F00FF);              (val & 0x800F00FF);
         openpic_update_irq(opp, n_IRQ);          openpic_update_irq(opp, n_IRQ);
         DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n",          DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n",
                 n_IRQ, val, opp->src[n_IRQ].ipvp);                  n_IRQ, val, opp->src[n_IRQ].ipvp);
         break;          break;
     case IRQ_IDE:      case IRQ_IDE:
         tmp = val & 0xC0000000;          tmp = val & 0xC0000000;
         tmp |= val & ((1 << MAX_CPU) - 1);          tmp |= val & ((1 << MAX_CPU) - 1);
         opp->src[n_IRQ].ide = tmp;          opp->src[n_IRQ].ide = tmp;
         DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide);          DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide);
         break;          break;
     }      }
 }  }
   
 #if 0 // Code provision for Intel model  #if 0 // Code provision for Intel model
 #if MAX_DBL > 0  #if MAX_DBL > 0
 static uint32_t read_doorbell_register (openpic_t *opp,  static uint32_t read_doorbell_register (openpic_t *opp,
                                         int n_dbl, uint32_t offset)                                          int n_dbl, uint32_t offset)
 {  {
     uint32_t retval;      uint32_t retval;
   
     switch (offset) {      switch (offset) {
     case DBL_IPVP_OFFSET:      case DBL_IPVP_OFFSET:
         retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP);          retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP);
         break;          break;
     case DBL_IDE_OFFSET:      case DBL_IDE_OFFSET:
         retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE);          retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE);
         break;          break;
     case DBL_DMR_OFFSET:      case DBL_DMR_OFFSET:
         retval = opp->doorbells[n_dbl].dmr;          retval = opp->doorbells[n_dbl].dmr;
         break;          break;
     }      }
   
     return retval;      return retval;
 }  }
   
 static void write_doorbell_register (penpic_t *opp, int n_dbl,  static void write_doorbell_register (penpic_t *opp, int n_dbl,
                                      uint32_t offset, uint32_t value)                                       uint32_t offset, uint32_t value)
 {  {
     switch (offset) {      switch (offset) {
     case DBL_IVPR_OFFSET:      case DBL_IVPR_OFFSET:
         write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP, value);          write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP, value);
         break;          break;
     case DBL_IDE_OFFSET:      case DBL_IDE_OFFSET:
         write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE, value);          write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE, value);
         break;          break;
     case DBL_DMR_OFFSET:      case DBL_DMR_OFFSET:
         opp->doorbells[n_dbl].dmr = value;          opp->doorbells[n_dbl].dmr = value;
         break;          break;
     }      }
 }  }
 #endif  #endif
   
 #if MAX_MBX > 0  #if MAX_MBX > 0
 static uint32_t read_mailbox_register (openpic_t *opp,  static uint32_t read_mailbox_register (openpic_t *opp,
                                        int n_mbx, uint32_t offset)                                         int n_mbx, uint32_t offset)
 {  {
     uint32_t retval;      uint32_t retval;
   
     switch (offset) {      switch (offset) {
     case MBX_MBR_OFFSET:      case MBX_MBR_OFFSET:
         retval = opp->mailboxes[n_mbx].mbr;          retval = opp->mailboxes[n_mbx].mbr;
         break;          break;
     case MBX_IVPR_OFFSET:      case MBX_IVPR_OFFSET:
         retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP);          retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP);
         break;          break;
     case MBX_DMR_OFFSET:      case MBX_DMR_OFFSET:
         retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE);          retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE);
         break;          break;
     }      }
   
     return retval;      return retval;
 }  }
   
 static void write_mailbox_register (openpic_t *opp, int n_mbx,  static void write_mailbox_register (openpic_t *opp, int n_mbx,
                                     uint32_t address, uint32_t value)                                      uint32_t address, uint32_t value)
 {  {
     switch (offset) {      switch (offset) {
     case MBX_MBR_OFFSET:      case MBX_MBR_OFFSET:
         opp->mailboxes[n_mbx].mbr = value;          opp->mailboxes[n_mbx].mbr = value;
         break;          break;
     case MBX_IVPR_OFFSET:      case MBX_IVPR_OFFSET:
         write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP, value);          write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP, value);
         break;          break;
     case MBX_DMR_OFFSET:      case MBX_DMR_OFFSET:
         write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE, value);          write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE, value);
         break;          break;
     }      }
 }  }
 #endif  #endif
Line 595  static void openpic_gbl_write (void *opa Line 599  static void openpic_gbl_write (void *opa
     DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);      DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
     if (addr & 0xF)      if (addr & 0xF)
         return;          return;
 #if defined TARGET_WORDS_BIGENDIAN  
     val = openpic_swap32(opp, val);      val = openpic_swap32(opp, val);
 #endif  
     addr &= 0xFF;      addr &= 0xFF;
     switch (addr) {      switch (addr) {
     case 0x00: /* FREP */      case 0x00: /* FREP */
Line 606  static void openpic_gbl_write (void *opa Line 608  static void openpic_gbl_write (void *opa
         if (val & 0x80000000 && opp->reset)          if (val & 0x80000000 && opp->reset)
             opp->reset(opp);              opp->reset(opp);
         opp->glbc = val & ~0x80000000;          opp->glbc = val & ~0x80000000;
         break;          break;
     case 0x80: /* VENI */      case 0x80: /* VENI */
         break;          break;
     case 0x90: /* PINT */      case 0x90: /* PINT */
         for (idx = 0; idx < opp->nb_cpus; idx++) {          for (idx = 0; idx < opp->nb_cpus; idx++) {
             if ((val & (1 << idx)) && !(opp->pint & (1 << idx))) {              if ((val & (1 << idx)) && !(opp->pint & (1 << idx))) {
Line 622  static void openpic_gbl_write (void *opa Line 624  static void openpic_gbl_write (void *opa
             }              }
         }          }
         opp->pint = val;          opp->pint = val;
         break;          break;
 #if MAX_IPI > 0  #if MAX_IPI > 0
     case 0xA0: /* IPI_IPVP */      case 0xA0: /* IPI_IPVP */
     case 0xB0:      case 0xB0:
Line 640  static void openpic_gbl_write (void *opa Line 642  static void openpic_gbl_write (void *opa
         break;          break;
     case 0xF0: /* TIFR */      case 0xF0: /* TIFR */
         opp->tifr = val;          opp->tifr = val;
         break;          break;
     default:      default:
         break;          break;
     }      }
Line 662  static uint32_t openpic_gbl_read (void * Line 664  static uint32_t openpic_gbl_read (void *
         break;          break;
     case 0x20: /* GLBC */      case 0x20: /* GLBC */
         retval = opp->glbc;          retval = opp->glbc;
         break;          break;
     case 0x80: /* VENI */      case 0x80: /* VENI */
         retval = opp->veni;          retval = opp->veni;
         break;          break;
     case 0x90: /* PINT */      case 0x90: /* PINT */
         retval = 0x00000000;          retval = 0x00000000;
         break;          break;
 #if MAX_IPI > 0  #if MAX_IPI > 0
     case 0xA0: /* IPI_IPVP */      case 0xA0: /* IPI_IPVP */
     case 0xB0:      case 0xB0:
Line 679  static uint32_t openpic_gbl_read (void * Line 681  static uint32_t openpic_gbl_read (void *
             idx = (addr - 0xA0) >> 4;              idx = (addr - 0xA0) >> 4;
             retval = read_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IPVP);              retval = read_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IPVP);
         }          }
         break;          break;
 #endif  #endif
     case 0xE0: /* SPVE */      case 0xE0: /* SPVE */
         retval = opp->spve;          retval = opp->spve;
         break;          break;
     case 0xF0: /* TIFR */      case 0xF0: /* TIFR */
         retval = opp->tifr;          retval = opp->tifr;
         break;          break;
     default:      default:
         break;          break;
     }      }
     DPRINTF("%s: => %08x\n", __func__, retval);      DPRINTF("%s: => %08x\n", __func__, retval);
 #if defined TARGET_WORDS_BIGENDIAN  
     retval = openpic_swap32(opp, retval);      retval = openpic_swap32(opp, retval);
 #endif  
   
     return retval;      return retval;
 }  }
Line 706  static void openpic_timer_write (void *o Line 706  static void openpic_timer_write (void *o
     DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);      DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
     if (addr & 0xF)      if (addr & 0xF)
         return;          return;
 #if defined TARGET_WORDS_BIGENDIAN  
     val = openpic_swap32(opp, val);      val = openpic_swap32(opp, val);
 #endif  
     addr -= 0x1100;      addr -= 0x1100;
     addr &= 0xFFFF;      addr &= 0xFFFF;
     idx = (addr & 0xFFF0) >> 6;      idx = (addr & 0xFFF0) >> 6;
Line 717  static void openpic_timer_write (void *o Line 715  static void openpic_timer_write (void *o
     case 0x00: /* TICC */      case 0x00: /* TICC */
         break;          break;
     case 0x10: /* TIBC */      case 0x10: /* TIBC */
         if ((opp->timers[idx].ticc & 0x80000000) != 0 &&          if ((opp->timers[idx].ticc & 0x80000000) != 0 &&
             (val & 0x80000000) == 0 &&              (val & 0x80000000) == 0 &&
             (opp->timers[idx].tibc & 0x80000000) != 0)              (opp->timers[idx].tibc & 0x80000000) != 0)
             opp->timers[idx].ticc &= ~0x80000000;              opp->timers[idx].ticc &= ~0x80000000;
         opp->timers[idx].tibc = val;          opp->timers[idx].tibc = val;
         break;          break;
     case 0x20: /* TIVP */      case 0x20: /* TIVP */
         write_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IPVP, val);          write_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IPVP, val);
         break;          break;
     case 0x30: /* TIDE */      case 0x30: /* TIDE */
         write_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IDE, val);          write_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IDE, val);
         break;          break;
     }      }
 }  }
   
Line 748  static uint32_t openpic_timer_read (void Line 746  static uint32_t openpic_timer_read (void
     addr = addr & 0x30;      addr = addr & 0x30;
     switch (addr) {      switch (addr) {
     case 0x00: /* TICC */      case 0x00: /* TICC */
         retval = opp->timers[idx].ticc;          retval = opp->timers[idx].ticc;
         break;          break;
     case 0x10: /* TIBC */      case 0x10: /* TIBC */
         retval = opp->timers[idx].tibc;          retval = opp->timers[idx].tibc;
         break;          break;
     case 0x20: /* TIPV */      case 0x20: /* TIPV */
         retval = read_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IPVP);          retval = read_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IPVP);
         break;          break;
     case 0x30: /* TIDE */      case 0x30: /* TIDE */
         retval = read_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IDE);          retval = read_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IDE);
         break;          break;
     }      }
     DPRINTF("%s: => %08x\n", __func__, retval);      DPRINTF("%s: => %08x\n", __func__, retval);
 #if defined TARGET_WORDS_BIGENDIAN  
     retval = openpic_swap32(opp, retval);      retval = openpic_swap32(opp, retval);
 #endif  
   
     return retval;      return retval;
 }  }
Line 776  static void openpic_src_write (void *opa Line 772  static void openpic_src_write (void *opa
     DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);      DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
     if (addr & 0xF)      if (addr & 0xF)
         return;          return;
 #if defined TARGET_WORDS_BIGENDIAN  
     val = openpic_swap32(opp, val);      val = openpic_swap32(opp, val);
 #endif  
     addr = addr & 0xFFF0;      addr = addr & 0xFFF0;
     idx = addr >> 5;      idx = addr >> 5;
     if (addr & 0x10) {      if (addr & 0x10) {
Line 810  static uint32_t openpic_src_read (void * Line 804  static uint32_t openpic_src_read (void *
         retval = read_IRQreg(opp, idx, IRQ_IPVP);          retval = read_IRQreg(opp, idx, IRQ_IPVP);
     }      }
     DPRINTF("%s: => %08x\n", __func__, retval);      DPRINTF("%s: => %08x\n", __func__, retval);
 #if defined TARGET_WORDS_BIGENDIAN  
     retval = openpic_swap32(opp, retval);      retval = openpic_swap32(opp, retval);
 #endif  
   
     return retval;      return retval;
 }  }
Line 827  static void openpic_cpu_write (void *opa Line 819  static void openpic_cpu_write (void *opa
     DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);      DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
     if (addr & 0xF)      if (addr & 0xF)
         return;          return;
 #if defined TARGET_WORDS_BIGENDIAN  
     val = openpic_swap32(opp, val);      val = openpic_swap32(opp, val);
 #endif  
     addr &= 0x1FFF0;      addr &= 0x1FFF0;
     idx = addr / 0x1000;      idx = addr / 0x1000;
     dst = &opp->dst[idx];      dst = &opp->dst[idx];
Line 847  static void openpic_cpu_write (void *opa Line 837  static void openpic_cpu_write (void *opa
         break;          break;
 #endif  #endif
     case 0x80: /* PCTP */      case 0x80: /* PCTP */
         dst->pctp = val & 0x0000000F;          dst->pctp = val & 0x0000000F;
         break;          break;
     case 0x90: /* WHOAMI */      case 0x90: /* WHOAMI */
         /* Read-only register */          /* Read-only register */
         break;          break;
     case 0xA0: /* PIAC */      case 0xA0: /* PIAC */
         /* Read-only register */          /* Read-only register */
         break;          break;
     case 0xB0: /* PEOI */      case 0xB0: /* PEOI */
         DPRINTF("PEOI\n");          DPRINTF("PEOI\n");
         s_IRQ = IRQ_get_next(opp, &dst->servicing);          s_IRQ = IRQ_get_next(opp, &dst->servicing);
         IRQ_resetbit(&dst->servicing, s_IRQ);          IRQ_resetbit(&dst->servicing, s_IRQ);
         dst->servicing.next = -1;          dst->servicing.next = -1;
         /* Set up next servicing IRQ */          /* Set up next servicing IRQ */
         s_IRQ = IRQ_get_next(opp, &dst->servicing);          s_IRQ = IRQ_get_next(opp, &dst->servicing);
         /* Check queued interrupts. */          /* Check queued interrupts. */
         n_IRQ = IRQ_get_next(opp, &dst->raised);          n_IRQ = IRQ_get_next(opp, &dst->raised);
         src = &opp->src[n_IRQ];          src = &opp->src[n_IRQ];
Line 872  static void openpic_cpu_write (void *opa Line 862  static void openpic_cpu_write (void *opa
                     idx, n_IRQ);                      idx, n_IRQ);
             opp->irq_raise(opp, idx, src);              opp->irq_raise(opp, idx, src);
         }          }
         break;          break;
     default:      default:
         break;          break;
     }      }
Line 896  static uint32_t openpic_cpu_read (void * Line 886  static uint32_t openpic_cpu_read (void *
     addr &= 0xFF0;      addr &= 0xFF0;
     switch (addr) {      switch (addr) {
     case 0x80: /* PCTP */      case 0x80: /* PCTP */
         retval = dst->pctp;          retval = dst->pctp;
         break;          break;
     case 0x90: /* WHOAMI */      case 0x90: /* WHOAMI */
         retval = idx;          retval = idx;
         break;          break;
     case 0xA0: /* PIAC */      case 0xA0: /* PIAC */
         DPRINTF("Lower OpenPIC INT output\n");          DPRINTF("Lower OpenPIC INT output\n");
         qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);          qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
         n_IRQ = IRQ_get_next(opp, &dst->raised);          n_IRQ = IRQ_get_next(opp, &dst->raised);
         DPRINTF("PIAC: irq=%d\n", n_IRQ);          DPRINTF("PIAC: irq=%d\n", n_IRQ);
         if (n_IRQ == -1) {          if (n_IRQ == -1) {
             /* No more interrupt pending */              /* No more interrupt pending */
             retval = IPVP_VECTOR(opp->spve);              retval = IPVP_VECTOR(opp->spve);
         } else {          } else {
             src = &opp->src[n_IRQ];              src = &opp->src[n_IRQ];
             if (!test_bit(&src->ipvp, IPVP_ACTIVITY) ||              if (!test_bit(&src->ipvp, IPVP_ACTIVITY) ||
                 !(IPVP_PRIORITY(src->ipvp) > dst->pctp)) {                  !(IPVP_PRIORITY(src->ipvp) > dst->pctp)) {
                 /* - Spurious level-sensitive IRQ                  /* - Spurious level-sensitive IRQ
                  * - Priorities has been changed                   * - Priorities has been changed
                  *   and the pending IRQ isn't allowed anymore                   *   and the pending IRQ isn't allowed anymore
                  */                   */
                 reset_bit(&src->ipvp, IPVP_ACTIVITY);                  reset_bit(&src->ipvp, IPVP_ACTIVITY);
                 retval = IPVP_VECTOR(opp->spve);                  retval = IPVP_VECTOR(opp->spve);
             } else {              } else {
                 /* IRQ enter servicing state */                  /* IRQ enter servicing state */
                 IRQ_setbit(&dst->servicing, n_IRQ);                  IRQ_setbit(&dst->servicing, n_IRQ);
                 retval = IPVP_VECTOR(src->ipvp);                  retval = IPVP_VECTOR(src->ipvp);
             }              }
             IRQ_resetbit(&dst->raised, n_IRQ);              IRQ_resetbit(&dst->raised, n_IRQ);
             dst->raised.next = -1;              dst->raised.next = -1;
             if (!test_bit(&src->ipvp, IPVP_SENSE)) {              if (!test_bit(&src->ipvp, IPVP_SENSE)) {
                 /* edge-sensitive IRQ */                  /* edge-sensitive IRQ */
                 reset_bit(&src->ipvp, IPVP_ACTIVITY);                  reset_bit(&src->ipvp, IPVP_ACTIVITY);
                 src->pending = 0;                  src->pending = 0;
             }              }
         }          }
         break;          break;
     case 0xB0: /* PEOI */      case 0xB0: /* PEOI */
         retval = 0;          retval = 0;
         break;          break;
 #if MAX_IPI > 0  #if MAX_IPI > 0
     case 0x40: /* IDE */      case 0x40: /* IDE */
     case 0x50:      case 0x50:
Line 947  static uint32_t openpic_cpu_read (void * Line 937  static uint32_t openpic_cpu_read (void *
         break;          break;
     }      }
     DPRINTF("%s: => %08x\n", __func__, retval);      DPRINTF("%s: => %08x\n", __func__, retval);
 #if defined TARGET_WORDS_BIGENDIAN  
     retval = openpic_swap32(opp, retval);      retval = openpic_swap32(opp, retval);
 #endif  
   
     return retval;      return retval;
 }  }
Line 1206  qemu_irq *openpic_init (PCIBus *bus, int Line 1194  qemu_irq *openpic_init (PCIBus *bus, int
         pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_IBM);          pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_IBM);
         pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_IBM_OPENPIC2);          pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_IBM_OPENPIC2);
         pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); // FIXME?          pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); // FIXME?
         pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type  
         pci_conf[0x3d] = 0x00; // no interrupt pin          pci_conf[0x3d] = 0x00; // no interrupt pin
   
         /* Register I/O spaces */          /* Register I/O spaces */
Line 1246  qemu_irq *openpic_init (PCIBus *bus, int Line 1233  qemu_irq *openpic_init (PCIBus *bus, int
     opp->irq_out = irq_out;      opp->irq_out = irq_out;
     opp->need_swap = 1;      opp->need_swap = 1;
   
     register_savevm("openpic", 0, 2, openpic_save, openpic_load, opp);      register_savevm(&opp->pci_dev.qdev, "openpic", 0, 2,
                       openpic_save, openpic_load, opp);
     qemu_register_reset(openpic_reset, opp);      qemu_register_reset(openpic_reset, opp);
   
     opp->irq_raise = openpic_irq_raise;      opp->irq_raise = openpic_irq_raise;
Line 1382  static void mpic_src_ext_write (void *op Line 1370  static void mpic_src_ext_write (void *op
     if (addr & 0xF)      if (addr & 0xF)
         return;          return;
   
     addr -= MPIC_EXT_REG_START & (TARGET_PAGE_SIZE - 1);      addr -= MPIC_EXT_REG_START & (OPENPIC_PAGE_SIZE - 1);
     if (addr < MPIC_EXT_REG_SIZE) {      if (addr < MPIC_EXT_REG_SIZE) {
         idx += (addr & 0xFFF0) >> 5;          idx += (addr & 0xFFF0) >> 5;
         if (addr & 0x10) {          if (addr & 0x10) {
Line 1406  static uint32_t mpic_src_ext_read (void  Line 1394  static uint32_t mpic_src_ext_read (void 
     if (addr & 0xF)      if (addr & 0xF)
         return retval;          return retval;
   
     addr -= MPIC_EXT_REG_START & (TARGET_PAGE_SIZE - 1);      addr -= MPIC_EXT_REG_START & (OPENPIC_PAGE_SIZE - 1);
     if (addr < MPIC_EXT_REG_SIZE) {      if (addr < MPIC_EXT_REG_SIZE) {
         idx += (addr & 0xFFF0) >> 5;          idx += (addr & 0xFFF0) >> 5;
         if (addr & 0x10) {          if (addr & 0x10) {
Line 1432  static void mpic_src_int_write (void *op Line 1420  static void mpic_src_int_write (void *op
     if (addr & 0xF)      if (addr & 0xF)
         return;          return;
   
     addr -= MPIC_INT_REG_START & (TARGET_PAGE_SIZE - 1);      addr -= MPIC_INT_REG_START & (OPENPIC_PAGE_SIZE - 1);
     if (addr < MPIC_INT_REG_SIZE) {      if (addr < MPIC_INT_REG_SIZE) {
         idx += (addr & 0xFFF0) >> 5;          idx += (addr & 0xFFF0) >> 5;
         if (addr & 0x10) {          if (addr & 0x10) {
Line 1456  static uint32_t mpic_src_int_read (void  Line 1444  static uint32_t mpic_src_int_read (void 
     if (addr & 0xF)      if (addr & 0xF)
         return retval;          return retval;
   
     addr -= MPIC_INT_REG_START & (TARGET_PAGE_SIZE - 1);      addr -= MPIC_INT_REG_START & (OPENPIC_PAGE_SIZE - 1);
     if (addr < MPIC_INT_REG_SIZE) {      if (addr < MPIC_INT_REG_SIZE) {
         idx += (addr & 0xFFF0) >> 5;          idx += (addr & 0xFFF0) >> 5;
         if (addr & 0x10) {          if (addr & 0x10) {
Line 1482  static void mpic_src_msg_write (void *op Line 1470  static void mpic_src_msg_write (void *op
     if (addr & 0xF)      if (addr & 0xF)
         return;          return;
   
     addr -= MPIC_MSG_REG_START & (TARGET_PAGE_SIZE - 1);      addr -= MPIC_MSG_REG_START & (OPENPIC_PAGE_SIZE - 1);
     if (addr < MPIC_MSG_REG_SIZE) {      if (addr < MPIC_MSG_REG_SIZE) {
         idx += (addr & 0xFFF0) >> 5;          idx += (addr & 0xFFF0) >> 5;
         if (addr & 0x10) {          if (addr & 0x10) {
Line 1506  static uint32_t mpic_src_msg_read (void  Line 1494  static uint32_t mpic_src_msg_read (void 
     if (addr & 0xF)      if (addr & 0xF)
         return retval;          return retval;
   
     addr -= MPIC_MSG_REG_START & (TARGET_PAGE_SIZE - 1);      addr -= MPIC_MSG_REG_START & (OPENPIC_PAGE_SIZE - 1);
     if (addr < MPIC_MSG_REG_SIZE) {      if (addr < MPIC_MSG_REG_SIZE) {
         idx += (addr & 0xFFF0) >> 5;          idx += (addr & 0xFFF0) >> 5;
         if (addr & 0x10) {          if (addr & 0x10) {
Line 1532  static void mpic_src_msi_write (void *op Line 1520  static void mpic_src_msi_write (void *op
     if (addr & 0xF)      if (addr & 0xF)
         return;          return;
   
     addr -= MPIC_MSI_REG_START & (TARGET_PAGE_SIZE - 1);      addr -= MPIC_MSI_REG_START & (OPENPIC_PAGE_SIZE - 1);
     if (addr < MPIC_MSI_REG_SIZE) {      if (addr < MPIC_MSI_REG_SIZE) {
         idx += (addr & 0xFFF0) >> 5;          idx += (addr & 0xFFF0) >> 5;
         if (addr & 0x10) {          if (addr & 0x10) {
Line 1555  static uint32_t mpic_src_msi_read (void  Line 1543  static uint32_t mpic_src_msi_read (void 
     if (addr & 0xF)      if (addr & 0xF)
         return retval;          return retval;
   
     addr -= MPIC_MSI_REG_START & (TARGET_PAGE_SIZE - 1);      addr -= MPIC_MSI_REG_START & (OPENPIC_PAGE_SIZE - 1);
     if (addr < MPIC_MSI_REG_SIZE) {      if (addr < MPIC_MSI_REG_SIZE) {
         idx += (addr & 0xFFF0) >> 5;          idx += (addr & 0xFFF0) >> 5;
         if (addr & 0x10) {          if (addr & 0x10) {
Line 1704  qemu_irq *mpic_init (target_phys_addr_t  Line 1692  qemu_irq *mpic_init (target_phys_addr_t 
     mpp->irq_raise = mpic_irq_raise;      mpp->irq_raise = mpic_irq_raise;
     mpp->reset = mpic_reset;      mpp->reset = mpic_reset;
   
     register_savevm("mpic", 0, 2, openpic_save, openpic_load, mpp);      register_savevm(NULL, "mpic", 0, 2, openpic_save, openpic_load, mpp);
     qemu_register_reset(mpic_reset, mpp);      qemu_register_reset(mpic_reset, mpp);
   
     return qemu_allocate_irqs(openpic_set_irq, mpp, mpp->max_irq);      return qemu_allocate_irqs(openpic_set_irq, mpp, mpp->max_irq);

Removed from v.1.1.1.6  
changed lines
  Added in v.1.1.1.7


unix.superglobalmegacorp.com