Add PowerPC power-management state check callback.
[qemu] / hw / pxa2xx_pic.c
1 /*
2  * Intel XScale PXA Programmable Interrupt Controller.
3  *
4  * Copyright (c) 2006 Openedhand Ltd.
5  * Copyright (c) 2006 Thorsten Zitterell
6  * Written by Andrzej Zaborowski <balrog@zabor.org>
7  *
8  * This code is licenced under the GPL.
9  */
10
11 #include "vl.h"
12
13 #define ICIP    0x00    /* Interrupt Controller IRQ Pending register */
14 #define ICMR    0x04    /* Interrupt Controller Mask register */
15 #define ICLR    0x08    /* Interrupt Controller Level register */
16 #define ICFP    0x0c    /* Interrupt Controller FIQ Pending register */
17 #define ICPR    0x10    /* Interrupt Controller Pending register */
18 #define ICCR    0x14    /* Interrupt Controller Control register */
19 #define ICHP    0x18    /* Interrupt Controller Highest Priority register */
20 #define IPR0    0x1c    /* Interrupt Controller Priority register 0 */
21 #define IPR31   0x98    /* Interrupt Controller Priority register 31 */
22 #define ICIP2   0x9c    /* Interrupt Controller IRQ Pending register 2 */
23 #define ICMR2   0xa0    /* Interrupt Controller Mask register 2 */
24 #define ICLR2   0xa4    /* Interrupt Controller Level register 2 */
25 #define ICFP2   0xa8    /* Interrupt Controller FIQ Pending register 2 */
26 #define ICPR2   0xac    /* Interrupt Controller Pending register 2 */
27 #define IPR32   0xb0    /* Interrupt Controller Priority register 32 */
28 #define IPR39   0xcc    /* Interrupt Controller Priority register 39 */
29
30 #define PXA2XX_PIC_SRCS 40
31
32 struct pxa2xx_pic_state_s {
33     target_phys_addr_t base;
34     CPUState *cpu_env;
35     uint32_t int_enabled[2];
36     uint32_t int_pending[2];
37     uint32_t is_fiq[2];
38     uint32_t int_idle;
39     uint32_t priority[PXA2XX_PIC_SRCS];
40 };
41
42 static void pxa2xx_pic_update(void *opaque)
43 {
44     uint32_t mask[2];
45     struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
46
47     if (s->cpu_env->halted) {
48         mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle);
49         mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle);
50         if (mask[0] || mask[1])
51             cpu_interrupt(s->cpu_env, CPU_INTERRUPT_EXITTB);
52     }
53
54     mask[0] = s->int_pending[0] & s->int_enabled[0];
55     mask[1] = s->int_pending[1] & s->int_enabled[1];
56
57     if ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1]))
58         cpu_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
59     else
60         cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
61
62     if ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1]))
63         cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
64     else
65         cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
66 }
67
68 /* Note: Here level means state of the signal on a pin, not
69  * IRQ/FIQ distinction as in PXA Developer Manual.  */
70 static void pxa2xx_pic_set_irq(void *opaque, int irq, int level)
71 {
72     struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
73     int int_set = (irq >= 32);
74     irq &= 31;
75
76     if (level)
77         s->int_pending[int_set] |= 1 << irq;
78     else
79         s->int_pending[int_set] &= ~(1 << irq);
80
81     pxa2xx_pic_update(opaque);
82 }
83
84 static inline uint32_t pxa2xx_pic_highest(struct pxa2xx_pic_state_s *s) {
85     int i, int_set, irq;
86     uint32_t bit, mask[2];
87     uint32_t ichp = 0x003f003f; /* Both IDs invalid */
88
89     mask[0] = s->int_pending[0] & s->int_enabled[0];
90     mask[1] = s->int_pending[1] & s->int_enabled[1];
91
92     for (i = PXA2XX_PIC_SRCS - 1; i >= 0; i --) {
93         irq = s->priority[i] & 0x3f;
94         if ((s->priority[i] & (1 << 31)) && irq < PXA2XX_PIC_SRCS) {
95             /* Source peripheral ID is valid.  */
96             bit = 1 << (irq & 31);
97             int_set = (irq >= 32);
98
99             if (mask[int_set] & bit & s->is_fiq[int_set]) {
100                 /* FIQ asserted */
101                 ichp &= 0xffff0000;
102                 ichp |= (1 << 15) | irq;
103             }
104
105             if (mask[int_set] & bit & ~s->is_fiq[int_set]) {
106                 /* IRQ asserted */
107                 ichp &= 0x0000ffff;
108                 ichp |= (1 << 31) | (irq << 16);
109             }
110         }
111     }
112
113     return ichp;
114 }
115
116 static uint32_t pxa2xx_pic_mem_read(void *opaque, target_phys_addr_t offset)
117 {
118     struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
119     offset -= s->base;
120
121     switch (offset) {
122     case ICIP:  /* IRQ Pending register */
123         return s->int_pending[0] & ~s->is_fiq[0] & s->int_enabled[0];
124     case ICIP2: /* IRQ Pending register 2 */
125         return s->int_pending[1] & ~s->is_fiq[1] & s->int_enabled[1];
126     case ICMR:  /* Mask register */
127         return s->int_enabled[0];
128     case ICMR2: /* Mask register 2 */
129         return s->int_enabled[1];
130     case ICLR:  /* Level register */
131         return s->is_fiq[0];
132     case ICLR2: /* Level register 2 */
133         return s->is_fiq[1];
134     case ICCR:  /* Idle mask */
135         return (s->int_idle == 0);
136     case ICFP:  /* FIQ Pending register */
137         return s->int_pending[0] & s->is_fiq[0] & s->int_enabled[0];
138     case ICFP2: /* FIQ Pending register 2 */
139         return s->int_pending[1] & s->is_fiq[1] & s->int_enabled[1];
140     case ICPR:  /* Pending register */
141         return s->int_pending[0];
142     case ICPR2: /* Pending register 2 */
143         return s->int_pending[1];
144     case IPR0  ... IPR31:
145         return s->priority[0  + ((offset - IPR0 ) >> 2)];
146     case IPR32 ... IPR39:
147         return s->priority[32 + ((offset - IPR32) >> 2)];
148     case ICHP:  /* Highest Priority register */
149         return pxa2xx_pic_highest(s);
150     default:
151         printf("%s: Bad register offset " REG_FMT "\n", __FUNCTION__, offset);
152         return 0;
153     }
154 }
155
156 static void pxa2xx_pic_mem_write(void *opaque, target_phys_addr_t offset,
157                 uint32_t value)
158 {
159     struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
160     offset -= s->base;
161
162     switch (offset) {
163     case ICMR:  /* Mask register */
164         s->int_enabled[0] = value;
165         break;
166     case ICMR2: /* Mask register 2 */
167         s->int_enabled[1] = value;
168         break;
169     case ICLR:  /* Level register */
170         s->is_fiq[0] = value;
171         break;
172     case ICLR2: /* Level register 2 */
173         s->is_fiq[1] = value;
174         break;
175     case ICCR:  /* Idle mask */
176         s->int_idle = (value & 1) ? 0 : ~0;
177         break;
178     case IPR0  ... IPR31:
179         s->priority[0  + ((offset - IPR0 ) >> 2)] = value & 0x8000003f;
180         break;
181     case IPR32 ... IPR39:
182         s->priority[32 + ((offset - IPR32) >> 2)] = value & 0x8000003f;
183         break;
184     default:
185         printf("%s: Bad register offset " REG_FMT "\n", __FUNCTION__, offset);
186         return;
187     }
188     pxa2xx_pic_update(opaque);
189 }
190
191 /* Interrupt Controller Coprocessor Space Register Mapping */
192 static const int pxa2xx_cp_reg_map[0x10] = {
193     [0x0 ... 0xf] = -1,
194     [0x0] = ICIP,
195     [0x1] = ICMR,
196     [0x2] = ICLR,
197     [0x3] = ICFP,
198     [0x4] = ICPR,
199     [0x5] = ICHP,
200     [0x6] = ICIP2,
201     [0x7] = ICMR2,
202     [0x8] = ICLR2,
203     [0x9] = ICFP2,
204     [0xa] = ICPR2,
205 };
206
207 static uint32_t pxa2xx_pic_cp_read(void *opaque, int op2, int reg, int crm)
208 {
209     struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
210     target_phys_addr_t offset;
211
212     if (pxa2xx_cp_reg_map[reg] == -1) {
213         printf("%s: Bad register 0x%x\n", __FUNCTION__, reg);
214         return 0;
215     }
216
217     offset = s->base + pxa2xx_cp_reg_map[reg];
218     return pxa2xx_pic_mem_read(opaque, offset);
219 }
220
221 static void pxa2xx_pic_cp_write(void *opaque, int op2, int reg, int crm,
222                 uint32_t value)
223 {
224     struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
225     target_phys_addr_t offset;
226
227     if (pxa2xx_cp_reg_map[reg] == -1) {
228         printf("%s: Bad register 0x%x\n", __FUNCTION__, reg);
229         return;
230     }
231
232     offset = s->base + pxa2xx_cp_reg_map[reg];
233     pxa2xx_pic_mem_write(opaque, offset, value);
234 }
235
236 static CPUReadMemoryFunc *pxa2xx_pic_readfn[] = {
237     pxa2xx_pic_mem_read,
238     pxa2xx_pic_mem_read,
239     pxa2xx_pic_mem_read,
240 };
241
242 static CPUWriteMemoryFunc *pxa2xx_pic_writefn[] = {
243     pxa2xx_pic_mem_write,
244     pxa2xx_pic_mem_write,
245     pxa2xx_pic_mem_write,
246 };
247
248 static void pxa2xx_pic_save(QEMUFile *f, void *opaque)
249 {
250     struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
251     int i;
252
253     for (i = 0; i < 2; i ++)
254         qemu_put_be32s(f, &s->int_enabled[i]);
255     for (i = 0; i < 2; i ++)
256         qemu_put_be32s(f, &s->int_pending[i]);
257     for (i = 0; i < 2; i ++)
258         qemu_put_be32s(f, &s->is_fiq[i]);
259     qemu_put_be32s(f, &s->int_idle);
260     for (i = 0; i < PXA2XX_PIC_SRCS; i ++)
261         qemu_put_be32s(f, &s->priority[i]);
262 }
263
264 static int pxa2xx_pic_load(QEMUFile *f, void *opaque, int version_id)
265 {
266     struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
267     int i;
268
269     for (i = 0; i < 2; i ++)
270         qemu_get_be32s(f, &s->int_enabled[i]);
271     for (i = 0; i < 2; i ++)
272         qemu_get_be32s(f, &s->int_pending[i]);
273     for (i = 0; i < 2; i ++)
274         qemu_get_be32s(f, &s->is_fiq[i]);
275     qemu_get_be32s(f, &s->int_idle);
276     for (i = 0; i < PXA2XX_PIC_SRCS; i ++)
277         qemu_get_be32s(f, &s->priority[i]);
278
279     pxa2xx_pic_update(opaque);
280     return 0;
281 }
282
283 qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env)
284 {
285     struct pxa2xx_pic_state_s *s;
286     int iomemtype;
287     qemu_irq *qi;
288
289     s = (struct pxa2xx_pic_state_s *)
290             qemu_mallocz(sizeof(struct pxa2xx_pic_state_s));
291     if (!s)
292         return NULL;
293
294     s->cpu_env = env;
295     s->base = base;
296
297     s->int_pending[0] = 0;
298     s->int_pending[1] = 0;
299     s->int_enabled[0] = 0;
300     s->int_enabled[1] = 0;
301     s->is_fiq[0] = 0;
302     s->is_fiq[1] = 0;
303
304     qi = qemu_allocate_irqs(pxa2xx_pic_set_irq, s, PXA2XX_PIC_SRCS);
305
306     /* Enable IC memory-mapped registers access.  */
307     iomemtype = cpu_register_io_memory(0, pxa2xx_pic_readfn,
308                     pxa2xx_pic_writefn, s);
309     cpu_register_physical_memory(base, 0x00100000, iomemtype);
310
311     /* Enable IC coprocessor access.  */
312     cpu_arm_set_cp_io(env, 6, pxa2xx_pic_cp_read, pxa2xx_pic_cp_write, s);
313
314     register_savevm("pxa2xx_pic", 0, 0, pxa2xx_pic_save, pxa2xx_pic_load, s);
315
316     return qi;
317 }