/[qemu]/qemu/hw/slavio_intctl.c
ViewVC logotype

Diff of /qemu/hw/slavio_intctl.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by bellard, Mon Nov 21 23:29:55 2005 UTC revision 1.6 by bellard, Mon Dec 5 20:31:52 2005 UTC
# Line 53  typedef struct SLAVIO_INTCTLState { Line 53  typedef struct SLAVIO_INTCTLState {
53  #ifdef DEBUG_IRQ_COUNT  #ifdef DEBUG_IRQ_COUNT
54      uint64_t irq_count[32];      uint64_t irq_count[32];
55  #endif  #endif
56        CPUState *cpu_envs[MAX_CPUS];
57  } SLAVIO_INTCTLState;  } SLAVIO_INTCTLState;
58    
59  #define INTCTL_MAXADDR 0xf  #define INTCTL_MAXADDR 0xf
# Line 96  static void slavio_intctl_mem_writel(voi Line 97  static void slavio_intctl_mem_writel(voi
97      case 2: // set softint      case 2: // set softint
98          val &= 0xfffe0000;          val &= 0xfffe0000;
99          s->intreg_pending[cpu] |= val;          s->intreg_pending[cpu] |= val;
100            slavio_check_interrupts(s);
101          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", cpu, val, s->intreg_pending[cpu]);
102          break;          break;
103      default:      default:
# Line 216  static void slavio_check_interrupts(void Line 218  static void slavio_check_interrupts(void
218      CPUState *env;      CPUState *env;
219      SLAVIO_INTCTLState *s = opaque;      SLAVIO_INTCTLState *s = opaque;
220      uint32_t pending = s->intregm_pending;      uint32_t pending = s->intregm_pending;
221      unsigned int i, max = 0;      unsigned int i, j, max = 0;
222    
223      pending &= ~s->intregm_disabled;      pending &= ~s->intregm_disabled;
224    
# Line 227  static void slavio_check_interrupts(void Line 229  static void slavio_check_interrupts(void
229                      max = intbit_to_level[i];                      max = intbit_to_level[i];
230              }              }
231          }          }
232          env = first_cpu;          env = s->cpu_envs[s->target_cpu];
233          if (env->interrupt_index == 0) {          if (!env) {
234              DPRINTF("Triggered pil %d\n", max);              DPRINTF("No CPU %d, not triggered (pending %x)\n", s->target_cpu, pending);
235            }
236            else {
237                if (env->halted)
238                    env->halted = 0;
239                if (env->interrupt_index == 0) {
240                    DPRINTF("Triggered CPU %d pil %d\n", s->target_cpu, max);
241  #ifdef DEBUG_IRQ_COUNT  #ifdef DEBUG_IRQ_COUNT
242              s->irq_count[max]++;                  s->irq_count[max]++;
243  #endif  #endif
244              env->interrupt_index = TT_EXTINT | max;                  env->interrupt_index = TT_EXTINT | max;
245              cpu_interrupt(env, CPU_INTERRUPT_HARD);                  cpu_interrupt(env, CPU_INTERRUPT_HARD);
246                }
247                else
248                    DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index);
249          }          }
         else  
             DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index);  
250      }      }
251      else      else
252          DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled);          DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled);
253        
254        for (i = 0; i < MAX_CPUS; i++) {
255            max = 0;
256            env = s->cpu_envs[i];
257            if (!env)
258                continue;
259            for (j = 17; j < 32; j++) {
260                if (s->intreg_pending[i] & (1 << j)) {
261                    if (max < j - 16)
262                        max = j - 16;
263                }
264            }
265            if (max > 0) {
266                if (env->halted)
267                    env->halted = 0;
268                if (env->interrupt_index == 0) {
269                    DPRINTF("Triggered softint %d for cpu %d (pending %x)\n", max, i, pending);
270    #ifdef DEBUG_IRQ_COUNT
271                    s->irq_count[max]++;
272    #endif
273                    env->interrupt_index = TT_EXTINT | max;
274                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
275                }
276            }
277        }
278  }  }
279    
280  /*  /*
# Line 251  void slavio_pic_set_irq(void *opaque, in Line 285  void slavio_pic_set_irq(void *opaque, in
285  {  {
286      SLAVIO_INTCTLState *s = opaque;      SLAVIO_INTCTLState *s = opaque;
287    
288      DPRINTF("Set irq %d level %d\n", irq, level);      DPRINTF("Set cpu %d irq %d level %d\n", s->target_cpu, irq, level);
289      if (irq < 32) {      if (irq < 32) {
290          uint32_t mask = 1 << irq;          uint32_t mask = 1 << irq;
291          uint32_t pil = intbit_to_level[irq];          uint32_t pil = intbit_to_level[irq];
# Line 269  void slavio_pic_set_irq(void *opaque, in Line 303  void slavio_pic_set_irq(void *opaque, in
303      slavio_check_interrupts(s);      slavio_check_interrupts(s);
304  }  }
305    
306    void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu)
307    {
308        SLAVIO_INTCTLState *s = opaque;
309    
310        DPRINTF("Set cpu %d local irq %d level %d\n", cpu, irq, level);
311        if (cpu == (unsigned int)-1) {
312            slavio_pic_set_irq(opaque, irq, level);
313            return;
314        }
315        if (irq < 32) {
316            uint32_t pil = intbit_to_level[irq];
317            if (pil > 0) {
318                if (level) {
319                    s->intreg_pending[cpu] |= 1 << pil;
320                }
321                else {
322                    s->intreg_pending[cpu] &= ~(1 << pil);
323                }
324            }
325        }
326        slavio_check_interrupts(s);
327    }
328    
329  static void slavio_intctl_save(QEMUFile *f, void *opaque)  static void slavio_intctl_save(QEMUFile *f, void *opaque)
330  {  {
331      SLAVIO_INTCTLState *s = opaque;      SLAVIO_INTCTLState *s = opaque;
# Line 312  static void slavio_intctl_reset(void *op Line 369  static void slavio_intctl_reset(void *op
369      s->target_cpu = 0;      s->target_cpu = 0;
370  }  }
371    
372    void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env)
373    {
374        SLAVIO_INTCTLState *s = opaque;
375        s->cpu_envs[cpu] = env;
376    }
377    
378  void *slavio_intctl_init(uint32_t addr, uint32_t addrg)  void *slavio_intctl_init(uint32_t addr, uint32_t addrg)
379  {  {
380      int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;      int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26