~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/slavio_intctl.c

  • Committer: ths
  • Date: 2007-10-08 12:45:38 UTC
  • Revision ID: git-v1:450d4ff553af32fc9d83fef20d7106b0151526b8
CRIS disassembler, originally from binutils, by Edgar E. Iglesias.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3356 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
 * THE SOFTWARE.
23
23
 */
24
 
#include "hw.h"
25
 
#include "sun4m.h"
26
 
#include "console.h"
27
 
 
 
24
#include "vl.h"
28
25
//#define DEBUG_IRQ_COUNT
29
26
//#define DEBUG_IRQ
30
27
 
59
56
#endif
60
57
    qemu_irq *cpu_irqs[MAX_CPUS];
61
58
    const uint32_t *intbit_to_level;
62
 
    uint32_t cputimer_lbit, cputimer_mbit;
 
59
    uint32_t cputimer_bit;
63
60
    uint32_t pil_out[MAX_CPUS];
64
61
} SLAVIO_INTCTLState;
65
62
 
68
65
#define INTCTLM_MAXADDR 0x13
69
66
#define INTCTLM_SIZE (INTCTLM_MAXADDR + 1)
70
67
#define INTCTLM_MASK 0x1f
71
 
#define MASTER_IRQ_MASK ~0x0fa2007f
72
 
#define MASTER_DISABLE 0x80000000
73
 
#define CPU_SOFTIRQ_MASK 0xfffe0000
74
 
#define CPU_HARDIRQ_MASK 0x0000fffe
75
 
#define CPU_IRQ_INT15_IN 0x0004000
76
 
#define CPU_IRQ_INT15_MASK 0x80000000
77
 
 
78
68
static void slavio_check_interrupts(void *opaque);
79
69
 
80
70
// per-cpu interrupt controller
99
89
    return ret;
100
90
}
101
91
 
102
 
static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr,
103
 
                                     uint32_t val)
 
92
static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
104
93
{
105
94
    SLAVIO_INTCTLState *s = opaque;
106
95
    uint32_t saddr;
111
100
    DPRINTF("write cpu %d reg 0x" TARGET_FMT_plx " = %x\n", cpu, addr, val);
112
101
    switch (saddr) {
113
102
    case 1: // clear pending softints
114
 
        if (val & CPU_IRQ_INT15_IN)
115
 
            val |= CPU_IRQ_INT15_MASK;
116
 
        val &= CPU_SOFTIRQ_MASK;
 
103
        if (val & 0x4000)
 
104
            val |= 80000000;
 
105
        val &= 0xfffe0000;
117
106
        s->intreg_pending[cpu] &= ~val;
118
107
        slavio_check_interrupts(s);
119
 
        DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val,
120
 
                s->intreg_pending[cpu]);
 
108
        DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);
121
109
        break;
122
110
    case 2: // set softint
123
 
        val &= CPU_SOFTIRQ_MASK;
 
111
        val &= 0xfffe0000;
124
112
        s->intreg_pending[cpu] |= val;
125
113
        slavio_check_interrupts(s);
126
 
        DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val,
127
 
                s->intreg_pending[cpu]);
 
114
        DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);
128
115
        break;
129
116
    default:
130
117
        break;
132
119
}
133
120
 
134
121
static CPUReadMemoryFunc *slavio_intctl_mem_read[3] = {
135
 
    NULL,
136
 
    NULL,
 
122
    slavio_intctl_mem_readl,
 
123
    slavio_intctl_mem_readl,
137
124
    slavio_intctl_mem_readl,
138
125
};
139
126
 
140
127
static CPUWriteMemoryFunc *slavio_intctl_mem_write[3] = {
141
 
    NULL,
142
 
    NULL,
 
128
    slavio_intctl_mem_writel,
 
129
    slavio_intctl_mem_writel,
143
130
    slavio_intctl_mem_writel,
144
131
};
145
132
 
149
136
    SLAVIO_INTCTLState *s = opaque;
150
137
    uint32_t saddr, ret;
151
138
 
152
 
    saddr = (addr & INTCTLM_MASK) >> 2;
 
139
    saddr = (addr & INTCTLM_MAXADDR) >> 2;
153
140
    switch (saddr) {
154
141
    case 0:
155
 
        ret = s->intregm_pending & ~MASTER_DISABLE;
 
142
        ret = s->intregm_pending & 0x7fffffff;
156
143
        break;
157
144
    case 1:
158
 
        ret = s->intregm_disabled & MASTER_IRQ_MASK;
 
145
        ret = s->intregm_disabled;
159
146
        break;
160
147
    case 4:
161
148
        ret = s->target_cpu;
169
156
    return ret;
170
157
}
171
158
 
172
 
static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr,
173
 
                                      uint32_t val)
 
159
static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
174
160
{
175
161
    SLAVIO_INTCTLState *s = opaque;
176
162
    uint32_t saddr;
180
166
    switch (saddr) {
181
167
    case 2: // clear (enable)
182
168
        // Force clear unused bits
183
 
        val &= MASTER_IRQ_MASK;
 
169
        val &= ~0x4fb2007f;
184
170
        s->intregm_disabled &= ~val;
185
 
        DPRINTF("Enabled master irq mask %x, curmask %x\n", val,
186
 
                s->intregm_disabled);
 
171
        DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
187
172
        slavio_check_interrupts(s);
188
173
        break;
189
174
    case 3: // set (disable, clear pending)
190
175
        // Force clear unused bits
191
 
        val &= MASTER_IRQ_MASK;
 
176
        val &= ~0x4fb2007f;
192
177
        s->intregm_disabled |= val;
193
178
        s->intregm_pending &= ~val;
194
179
        slavio_check_interrupts(s);
195
 
        DPRINTF("Disabled master irq mask %x, curmask %x\n", val,
196
 
                s->intregm_disabled);
 
180
        DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
197
181
        break;
198
182
    case 4:
199
183
        s->target_cpu = val & (MAX_CPUS - 1);
206
190
}
207
191
 
208
192
static CPUReadMemoryFunc *slavio_intctlm_mem_read[3] = {
209
 
    NULL,
210
 
    NULL,
 
193
    slavio_intctlm_mem_readl,
 
194
    slavio_intctlm_mem_readl,
211
195
    slavio_intctlm_mem_readl,
212
196
};
213
197
 
214
198
static CPUWriteMemoryFunc *slavio_intctlm_mem_write[3] = {
215
 
    NULL,
216
 
    NULL,
 
199
    slavio_intctlm_mem_writel,
 
200
    slavio_intctlm_mem_writel,
217
201
    slavio_intctlm_mem_writel,
218
202
};
219
203
 
225
209
    for (i = 0; i < MAX_CPUS; i++) {
226
210
        term_printf("per-cpu %d: pending 0x%08x\n", i, s->intreg_pending[i]);
227
211
    }
228
 
    term_printf("master: pending 0x%08x, disabled 0x%08x\n",
229
 
                s->intregm_pending, s->intregm_disabled);
 
212
    term_printf("master: pending 0x%08x, disabled 0x%08x\n", s->intregm_pending, s->intregm_disabled);
230
213
}
231
214
 
232
215
void slavio_irq_info(void *opaque)
258
241
    DPRINTF("pending %x disabled %x\n", pending, s->intregm_disabled);
259
242
    for (i = 0; i < MAX_CPUS; i++) {
260
243
        pil_pending = 0;
261
 
        if (pending && !(s->intregm_disabled & MASTER_DISABLE) &&
 
244
        if (pending && !(s->intregm_disabled & 0x80000000) &&
262
245
            (i == s->target_cpu)) {
263
246
            for (j = 0; j < 32; j++) {
264
247
                if (pending & (1 << j))
265
248
                    pil_pending |= 1 << s->intbit_to_level[j];
266
249
            }
267
250
        }
268
 
        pil_pending |= (s->intreg_pending[i] & CPU_SOFTIRQ_MASK) >> 16;
 
251
        pil_pending |= (s->intreg_pending[i] >> 16) & 0xfffe;
269
252
 
270
253
        for (j = 0; j < MAX_PILS; j++) {
271
254
            if (pil_pending & (1 << j)) {
313
296
 
314
297
    DPRINTF("Set cpu %d local timer level %d\n", cpu, level);
315
298
 
316
 
    if (level) {
317
 
        s->intregm_pending |= s->cputimer_mbit;
318
 
        s->intreg_pending[cpu] |= s->cputimer_lbit;
319
 
    } else {
320
 
        s->intregm_pending &= ~s->cputimer_mbit;
321
 
        s->intreg_pending[cpu] &= ~s->cputimer_lbit;
322
 
    }
 
299
    if (level)
 
300
        s->intreg_pending[cpu] |= s->cputimer_bit;
 
301
    else
 
302
        s->intreg_pending[cpu] &= ~s->cputimer_bit;
323
303
 
324
304
    slavio_check_interrupts(s);
325
305
}
363
343
    for (i = 0; i < MAX_CPUS; i++) {
364
344
        s->intreg_pending[i] = 0;
365
345
    }
366
 
    s->intregm_disabled = ~MASTER_IRQ_MASK;
 
346
    s->intregm_disabled = ~0xffb2007f;
367
347
    s->intregm_pending = 0;
368
348
    s->target_cpu = 0;
369
349
    slavio_check_interrupts(s);
383
363
 
384
364
    s->intbit_to_level = intbit_to_level;
385
365
    for (i = 0; i < MAX_CPUS; i++) {
386
 
        slavio_intctl_io_memory = cpu_register_io_memory(0,
387
 
                                                         slavio_intctl_mem_read,
388
 
                                                         slavio_intctl_mem_write,
389
 
                                                         s);
 
366
        slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s);
390
367
        cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
391
368
                                     slavio_intctl_io_memory);
392
369
        s->cpu_irqs[i] = parent_irq[i];
393
370
    }
394
371
 
395
 
    slavio_intctlm_io_memory = cpu_register_io_memory(0,
396
 
                                                      slavio_intctlm_mem_read,
397
 
                                                      slavio_intctlm_mem_write,
398
 
                                                      s);
 
372
    slavio_intctlm_io_memory = cpu_register_io_memory(0, slavio_intctlm_mem_read, slavio_intctlm_mem_write, s);
399
373
    cpu_register_physical_memory(addrg, INTCTLM_SIZE, slavio_intctlm_io_memory);
400
374
 
401
 
    register_savevm("slavio_intctl", addr, 1, slavio_intctl_save,
402
 
                    slavio_intctl_load, s);
 
375
    register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s);
403
376
    qemu_register_reset(slavio_intctl_reset, s);
404
377
    *irq = qemu_allocate_irqs(slavio_set_irq, s, 32);
405
378
 
406
379
    *cpu_irq = qemu_allocate_irqs(slavio_set_timer_irq_cpu, s, MAX_CPUS);
407
 
    s->cputimer_mbit = 1 << cputimer;
408
 
    s->cputimer_lbit = 1 << intbit_to_level[cputimer];
 
380
    s->cputimer_bit = 1 << s->intbit_to_level[cputimer];
409
381
    slavio_intctl_reset(s);
410
382
    return s;
411
383
}