Diff for /qemu/hw/slavio_intctl.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2018/04/24 16:48:24 version 1.1.1.5, 2018/04/24 16:52:29
Line 49  do { printf("IRQ: " fmt , ##args); } whi Line 49  do { printf("IRQ: " fmt , ##args); } whi
 #define MAX_CPUS 16  #define MAX_CPUS 16
 #define MAX_PILS 16  #define MAX_PILS 16
   
   struct SLAVIO_CPUINTCTLState;
   
 typedef struct SLAVIO_INTCTLState {  typedef struct SLAVIO_INTCTLState {
     uint32_t intreg_pending[MAX_CPUS];  
     uint32_t intregm_pending;      uint32_t intregm_pending;
     uint32_t intregm_disabled;      uint32_t intregm_disabled;
     uint32_t target_cpu;      uint32_t target_cpu;
Line 61  typedef struct SLAVIO_INTCTLState { Line 62  typedef struct SLAVIO_INTCTLState {
     const uint32_t *intbit_to_level;      const uint32_t *intbit_to_level;
     uint32_t cputimer_lbit, cputimer_mbit;      uint32_t cputimer_lbit, cputimer_mbit;
     uint32_t pil_out[MAX_CPUS];      uint32_t pil_out[MAX_CPUS];
       struct SLAVIO_CPUINTCTLState *slaves[MAX_CPUS];
 } SLAVIO_INTCTLState;  } SLAVIO_INTCTLState;
   
   typedef struct SLAVIO_CPUINTCTLState {
       uint32_t intreg_pending;
       SLAVIO_INTCTLState *master;
       uint32_t cpu;
   } SLAVIO_CPUINTCTLState;
   
 #define INTCTL_MAXADDR 0xf  #define INTCTL_MAXADDR 0xf
 #define INTCTL_SIZE (INTCTL_MAXADDR + 1)  #define INTCTL_SIZE (INTCTL_MAXADDR + 1)
 #define INTCTLM_MAXADDR 0x13  #define INTCTLM_SIZE 0x14
 #define INTCTLM_SIZE (INTCTLM_MAXADDR + 1)  
 #define INTCTLM_MASK 0x1f  
 #define MASTER_IRQ_MASK ~0x0fa2007f  #define MASTER_IRQ_MASK ~0x0fa2007f
 #define MASTER_DISABLE 0x80000000  #define MASTER_DISABLE 0x80000000
 #define CPU_SOFTIRQ_MASK 0xfffe0000  #define CPU_SOFTIRQ_MASK 0xfffe0000
Line 75  typedef struct SLAVIO_INTCTLState { Line 81  typedef struct SLAVIO_INTCTLState {
 #define CPU_IRQ_INT15_IN 0x0004000  #define CPU_IRQ_INT15_IN 0x0004000
 #define CPU_IRQ_INT15_MASK 0x80000000  #define CPU_IRQ_INT15_MASK 0x80000000
   
 static void slavio_check_interrupts(void *opaque);  static void slavio_check_interrupts(SLAVIO_INTCTLState *s);
   
 // per-cpu interrupt controller  // per-cpu interrupt controller
 static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr)  static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr)
 {  {
     SLAVIO_INTCTLState *s = opaque;      SLAVIO_CPUINTCTLState *s = opaque;
     uint32_t saddr, ret;      uint32_t saddr, ret;
     int cpu;  
   
     cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12;      saddr = addr >> 2;
     saddr = (addr & INTCTL_MAXADDR) >> 2;  
     switch (saddr) {      switch (saddr) {
     case 0:      case 0:
         ret = s->intreg_pending[cpu];          ret = s->intreg_pending;
         break;          break;
     default:      default:
         ret = 0;          ret = 0;
         break;          break;
     }      }
     DPRINTF("read cpu %d reg 0x" TARGET_FMT_plx " = %x\n", cpu, addr, ret);      DPRINTF("read cpu %d reg 0x" TARGET_FMT_plx " = %x\n", s->cpu, addr, ret);
   
     return ret;      return ret;
 }  }
   
 static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)  static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr,
                                        uint32_t val)
 {  {
     SLAVIO_INTCTLState *s = opaque;      SLAVIO_CPUINTCTLState *s = opaque;
     uint32_t saddr;      uint32_t saddr;
     int cpu;  
   
     cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12;      saddr = addr >> 2;
     saddr = (addr & INTCTL_MAXADDR) >> 2;      DPRINTF("write cpu %d reg 0x" TARGET_FMT_plx " = %x\n", s->cpu, addr, val);
     DPRINTF("write cpu %d reg 0x" TARGET_FMT_plx " = %x\n", cpu, addr, val);  
     switch (saddr) {      switch (saddr) {
     case 1: // clear pending softints      case 1: // clear pending softints
         if (val & CPU_IRQ_INT15_IN)          if (val & CPU_IRQ_INT15_IN)
             val |= CPU_IRQ_INT15_MASK;              val |= CPU_IRQ_INT15_MASK;
         val &= CPU_SOFTIRQ_MASK;          val &= CPU_SOFTIRQ_MASK;
         s->intreg_pending[cpu] &= ~val;          s->intreg_pending &= ~val;
         slavio_check_interrupts(s);          slavio_check_interrupts(s->master);
         DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);          DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", s->cpu, val,
                   s->intreg_pending);
         break;          break;
     case 2: // set softint      case 2: // set softint
         val &= CPU_SOFTIRQ_MASK;          val &= CPU_SOFTIRQ_MASK;
         s->intreg_pending[cpu] |= val;          s->intreg_pending |= val;
         slavio_check_interrupts(s);          slavio_check_interrupts(s->master);
         DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);          DPRINTF("Set cpu %d irq mask %x, curmask %x\n", s->cpu, val,
                   s->intreg_pending);
         break;          break;
     default:      default:
         break;          break;
Line 146  static uint32_t slavio_intctlm_mem_readl Line 151  static uint32_t slavio_intctlm_mem_readl
     SLAVIO_INTCTLState *s = opaque;      SLAVIO_INTCTLState *s = opaque;
     uint32_t saddr, ret;      uint32_t saddr, ret;
   
     saddr = (addr & INTCTLM_MASK) >> 2;      saddr = addr >> 2;
     switch (saddr) {      switch (saddr) {
     case 0:      case 0:
         ret = s->intregm_pending & ~MASTER_DISABLE;          ret = s->intregm_pending & ~MASTER_DISABLE;
Line 166  static uint32_t slavio_intctlm_mem_readl Line 171  static uint32_t slavio_intctlm_mem_readl
     return ret;      return ret;
 }  }
   
 static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)  static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr,
                                         uint32_t val)
 {  {
     SLAVIO_INTCTLState *s = opaque;      SLAVIO_INTCTLState *s = opaque;
     uint32_t saddr;      uint32_t saddr;
   
     saddr = (addr & INTCTLM_MASK) >> 2;      saddr = addr >> 2;
     DPRINTF("write system reg 0x" TARGET_FMT_plx " = %x\n", addr, val);      DPRINTF("write system reg 0x" TARGET_FMT_plx " = %x\n", addr, val);
     switch (saddr) {      switch (saddr) {
     case 2: // clear (enable)      case 2: // clear (enable)
         // Force clear unused bits          // Force clear unused bits
         val &= MASTER_IRQ_MASK;          val &= MASTER_IRQ_MASK;
         s->intregm_disabled &= ~val;          s->intregm_disabled &= ~val;
         DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);          DPRINTF("Enabled master irq mask %x, curmask %x\n", val,
                   s->intregm_disabled);
         slavio_check_interrupts(s);          slavio_check_interrupts(s);
         break;          break;
     case 3: // set (disable, clear pending)      case 3: // set (disable, clear pending)
Line 187  static void slavio_intctlm_mem_writel(vo Line 194  static void slavio_intctlm_mem_writel(vo
         s->intregm_disabled |= val;          s->intregm_disabled |= val;
         s->intregm_pending &= ~val;          s->intregm_pending &= ~val;
         slavio_check_interrupts(s);          slavio_check_interrupts(s);
         DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);          DPRINTF("Disabled master irq mask %x, curmask %x\n", val,
                   s->intregm_disabled);
         break;          break;
     case 4:      case 4:
         s->target_cpu = val & (MAX_CPUS - 1);          s->target_cpu = val & (MAX_CPUS - 1);
Line 217  void slavio_pic_info(void *opaque) Line 225  void slavio_pic_info(void *opaque)
     int i;      int i;
   
     for (i = 0; i < MAX_CPUS; i++) {      for (i = 0; i < MAX_CPUS; i++) {
         term_printf("per-cpu %d: pending 0x%08x\n", i, s->intreg_pending[i]);          term_printf("per-cpu %d: pending 0x%08x\n", i,
                       s->slaves[i]->intreg_pending);
     }      }
     term_printf("master: pending 0x%08x, disabled 0x%08x\n", s->intregm_pending, s->intregm_disabled);      term_printf("master: pending 0x%08x, disabled 0x%08x\n",
                   s->intregm_pending, s->intregm_disabled);
 }  }
   
 void slavio_irq_info(void *opaque)  void slavio_irq_info(void *opaque)
Line 240  void slavio_irq_info(void *opaque) Line 250  void slavio_irq_info(void *opaque)
 #endif  #endif
 }  }
   
 static void slavio_check_interrupts(void *opaque)  static void slavio_check_interrupts(SLAVIO_INTCTLState *s)
 {  {
     SLAVIO_INTCTLState *s = opaque;  
     uint32_t pending = s->intregm_pending, pil_pending;      uint32_t pending = s->intregm_pending, pil_pending;
     unsigned int i, j;      unsigned int i, j;
   
Line 258  static void slavio_check_interrupts(void Line 267  static void slavio_check_interrupts(void
                     pil_pending |= 1 << s->intbit_to_level[j];                      pil_pending |= 1 << s->intbit_to_level[j];
             }              }
         }          }
         pil_pending |= (s->intreg_pending[i] & CPU_SOFTIRQ_MASK) >> 16;          pil_pending |= (s->slaves[i]->intreg_pending & CPU_SOFTIRQ_MASK) >> 16;
   
         for (j = 0; j < MAX_PILS; j++) {          for (j = 0; j < MAX_PILS; j++) {
             if (pil_pending & (1 << j)) {              if (pil_pending & (1 << j)) {
Line 291  static void slavio_set_irq(void *opaque, Line 300  static void slavio_set_irq(void *opaque,
             s->irq_count[pil]++;              s->irq_count[pil]++;
 #endif  #endif
             s->intregm_pending |= mask;              s->intregm_pending |= mask;
             s->intreg_pending[s->target_cpu] |= 1 << pil;              s->slaves[s->target_cpu]->intreg_pending |= 1 << pil;
         } else {          } else {
             s->intregm_pending &= ~mask;              s->intregm_pending &= ~mask;
             s->intreg_pending[s->target_cpu] &= ~(1 << pil);              s->slaves[s->target_cpu]->intreg_pending &= ~(1 << pil);
         }          }
         slavio_check_interrupts(s);          slavio_check_interrupts(s);
     }      }
Line 308  static void slavio_set_timer_irq_cpu(voi Line 317  static void slavio_set_timer_irq_cpu(voi
   
     if (level) {      if (level) {
         s->intregm_pending |= s->cputimer_mbit;          s->intregm_pending |= s->cputimer_mbit;
         s->intreg_pending[cpu] |= s->cputimer_lbit;          s->slaves[cpu]->intreg_pending |= s->cputimer_lbit;
     } else {      } else {
         s->intregm_pending &= ~s->cputimer_mbit;          s->intregm_pending &= ~s->cputimer_mbit;
         s->intreg_pending[cpu] &= ~s->cputimer_lbit;          s->slaves[cpu]->intreg_pending &= ~s->cputimer_lbit;
     }      }
   
     slavio_check_interrupts(s);      slavio_check_interrupts(s);
Line 323  static void slavio_intctl_save(QEMUFile  Line 332  static void slavio_intctl_save(QEMUFile 
     int i;      int i;
   
     for (i = 0; i < MAX_CPUS; i++) {      for (i = 0; i < MAX_CPUS; i++) {
         qemu_put_be32s(f, &s->intreg_pending[i]);          qemu_put_be32s(f, &s->slaves[i]->intreg_pending);
     }      }
     qemu_put_be32s(f, &s->intregm_pending);      qemu_put_be32s(f, &s->intregm_pending);
     qemu_put_be32s(f, &s->intregm_disabled);      qemu_put_be32s(f, &s->intregm_disabled);
Line 339  static int slavio_intctl_load(QEMUFile * Line 348  static int slavio_intctl_load(QEMUFile *
         return -EINVAL;          return -EINVAL;
   
     for (i = 0; i < MAX_CPUS; i++) {      for (i = 0; i < MAX_CPUS; i++) {
         qemu_get_be32s(f, &s->intreg_pending[i]);          qemu_get_be32s(f, &s->slaves[i]->intreg_pending);
     }      }
     qemu_get_be32s(f, &s->intregm_pending);      qemu_get_be32s(f, &s->intregm_pending);
     qemu_get_be32s(f, &s->intregm_disabled);      qemu_get_be32s(f, &s->intregm_disabled);
Line 354  static void slavio_intctl_reset(void *op Line 363  static void slavio_intctl_reset(void *op
     int i;      int i;
   
     for (i = 0; i < MAX_CPUS; i++) {      for (i = 0; i < MAX_CPUS; i++) {
         s->intreg_pending[i] = 0;          s->slaves[i]->intreg_pending = 0;
     }      }
     s->intregm_disabled = ~MASTER_IRQ_MASK;      s->intregm_disabled = ~MASTER_IRQ_MASK;
     s->intregm_pending = 0;      s->intregm_pending = 0;
Line 369  void *slavio_intctl_init(target_phys_add Line 378  void *slavio_intctl_init(target_phys_add
 {  {
     int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;      int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;
     SLAVIO_INTCTLState *s;      SLAVIO_INTCTLState *s;
       SLAVIO_CPUINTCTLState *slave;
   
     s = qemu_mallocz(sizeof(SLAVIO_INTCTLState));      s = qemu_mallocz(sizeof(SLAVIO_INTCTLState));
     if (!s)  
         return NULL;  
   
     s->intbit_to_level = intbit_to_level;      s->intbit_to_level = intbit_to_level;
     for (i = 0; i < MAX_CPUS; i++) {      for (i = 0; i < MAX_CPUS; i++) {
         slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s);          slave = qemu_mallocz(sizeof(SLAVIO_CPUINTCTLState));
   
           slave->cpu = i;
           slave->master = s;
   
           slavio_intctl_io_memory = cpu_register_io_memory(0,
                                                            slavio_intctl_mem_read,
                                                            slavio_intctl_mem_write,
                                                            slave);
         cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,          cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
                                      slavio_intctl_io_memory);                                       slavio_intctl_io_memory);
   
           s->slaves[i] = slave;
         s->cpu_irqs[i] = parent_irq[i];          s->cpu_irqs[i] = parent_irq[i];
     }      }
   
     slavio_intctlm_io_memory = cpu_register_io_memory(0, slavio_intctlm_mem_read, slavio_intctlm_mem_write, s);      slavio_intctlm_io_memory = cpu_register_io_memory(0,
                                                         slavio_intctlm_mem_read,
                                                         slavio_intctlm_mem_write,
                                                         s);
     cpu_register_physical_memory(addrg, INTCTLM_SIZE, slavio_intctlm_io_memory);      cpu_register_physical_memory(addrg, INTCTLM_SIZE, slavio_intctlm_io_memory);
   
     register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s);      register_savevm("slavio_intctl", addr, 1, slavio_intctl_save,
                       slavio_intctl_load, s);
     qemu_register_reset(slavio_intctl_reset, s);      qemu_register_reset(slavio_intctl_reset, s);
     *irq = qemu_allocate_irqs(slavio_set_irq, s, 32);      *irq = qemu_allocate_irqs(slavio_set_irq, s, 32);
   
Line 395  void *slavio_intctl_init(target_phys_add Line 417  void *slavio_intctl_init(target_phys_add
     slavio_intctl_reset(s);      slavio_intctl_reset(s);
     return s;      return s;
 }  }
   

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


unix.superglobalmegacorp.com