]> git.proxmox.com Git - qemu.git/blame - hw/intc/etraxfs_pic.c
a15mpcore: Convert to QOM realize
[qemu.git] / hw / intc / etraxfs_pic.c
CommitLineData
e62b5b13
EI
1/*
2 * QEMU ETRAX Interrupt Controller.
3 *
4 * Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
83c9f4ca
PB
25#include "hw/sysbus.h"
26#include "hw/hw.h"
1ad2134f
PB
27//#include "pc.h"
28//#include "etraxfs.h"
e62b5b13
EI
29
30#define D(x)
31
979d98ca
EI
32#define R_RW_MASK 0
33#define R_R_VECT 1
34#define R_R_MASKED_VECT 2
35#define R_R_NMI 3
36#define R_R_GURU 4
37#define R_MAX 5
8d13fcc0 38
9062143f
AF
39#define TYPE_ETRAX_FS_PIC "etraxfs,pic"
40#define ETRAX_FS_PIC(obj) \
41 OBJECT_CHECK(struct etrax_pic, (obj), TYPE_ETRAX_FS_PIC)
42
fd6dc90b 43struct etrax_pic
e62b5b13 44{
9062143f
AF
45 SysBusDevice parent_obj;
46
5dd25f36 47 MemoryRegion mmio;
ddde095c 48 void *interrupt_vector;
fd6dc90b
EI
49 qemu_irq parent_irq;
50 qemu_irq parent_nmi;
979d98ca 51 uint32_t regs[R_MAX];
e62b5b13
EI
52};
53
fd6dc90b 54static void pic_update(struct etrax_pic *fs)
979d98ca 55{
979d98ca
EI
56 uint32_t vector = 0;
57 int i;
58
59 fs->regs[R_R_MASKED_VECT] = fs->regs[R_R_VECT] & fs->regs[R_RW_MASK];
60
66a0a2cb 61 /* The ETRAX interrupt controller signals interrupts to the core
979d98ca
EI
62 through an interrupt request wire and an irq vector bus. If
63 multiple interrupts are simultaneously active it chooses vector
64 0x30 and lets the sw choose the priorities. */
65 if (fs->regs[R_R_MASKED_VECT]) {
66 uint32_t mv = fs->regs[R_R_MASKED_VECT];
67 for (i = 0; i < 31; i++) {
68 if (mv & 1) {
69 vector = 0x31 + i;
70 /* Check for multiple interrupts. */
71 if (mv > 1)
72 vector = 0x30;
73 break;
74 }
75 mv >>= 1;
76 }
979d98ca 77 }
fd6dc90b
EI
78
79 if (fs->interrupt_vector) {
ddde095c
GH
80 /* hack alert: ptr property */
81 *(uint32_t*)(fs->interrupt_vector) = vector;
fd6dc90b
EI
82 }
83 qemu_set_irq(fs->parent_irq, !!vector);
e62b5b13
EI
84}
85
5dd25f36 86static uint64_t
a8170e5e 87pic_read(void *opaque, hwaddr addr, unsigned int size)
e62b5b13 88{
fd6dc90b 89 struct etrax_pic *fs = opaque;
979d98ca 90 uint32_t rval;
e62b5b13 91
979d98ca
EI
92 rval = fs->regs[addr >> 2];
93 D(printf("%s %x=%x\n", __func__, addr, rval));
94 return rval;
e62b5b13
EI
95}
96
a8170e5e 97static void pic_write(void *opaque, hwaddr addr,
5dd25f36 98 uint64_t value, unsigned int size)
e62b5b13 99{
fd6dc90b 100 struct etrax_pic *fs = opaque;
979d98ca 101 D(printf("%s addr=%x val=%x\n", __func__, addr, value));
8d13fcc0 102
979d98ca
EI
103 if (addr == R_RW_MASK) {
104 fs->regs[R_RW_MASK] = value;
105 pic_update(fs);
106 }
e62b5b13
EI
107}
108
5dd25f36
EI
109static const MemoryRegionOps pic_ops = {
110 .read = pic_read,
111 .write = pic_write,
112 .endianness = DEVICE_NATIVE_ENDIAN,
113 .valid = {
114 .min_access_size = 4,
115 .max_access_size = 4
116 }
e62b5b13
EI
117};
118
5ef98b47 119static void nmi_handler(void *opaque, int irq, int level)
979d98ca 120{
fd6dc90b 121 struct etrax_pic *fs = (void *)opaque;
979d98ca
EI
122 uint32_t mask;
123
124 mask = 1 << irq;
125 if (level)
126 fs->regs[R_R_NMI] |= mask;
127 else
128 fs->regs[R_R_NMI] &= ~mask;
129
fd6dc90b 130 qemu_set_irq(fs->parent_nmi, !!fs->regs[R_R_NMI]);
5ef98b47
EI
131}
132
73cfd29f 133static void irq_handler(void *opaque, int irq, int level)
979d98ca 134{
fd6dc90b 135 struct etrax_pic *fs = (void *)opaque;
73cfd29f 136
979d98ca
EI
137 if (irq >= 30)
138 return nmi_handler(opaque, irq, level);
73cfd29f 139
979d98ca
EI
140 irq -= 1;
141 fs->regs[R_R_VECT] &= ~(1 << irq);
142 fs->regs[R_R_VECT] |= (!!level << irq);
143 pic_update(fs);
5ef98b47
EI
144}
145
9062143f 146static int etraxfs_pic_init(SysBusDevice *sbd)
e62b5b13 147{
9062143f
AF
148 DeviceState *dev = DEVICE(sbd);
149 struct etrax_pic *s = ETRAX_FS_PIC(dev);
e62b5b13 150
9062143f
AF
151 qdev_init_gpio_in(dev, irq_handler, 32);
152 sysbus_init_irq(sbd, &s->parent_irq);
153 sysbus_init_irq(sbd, &s->parent_nmi);
e62b5b13 154
1437c94b
PB
155 memory_region_init_io(&s->mmio, OBJECT(s), &pic_ops, s,
156 "etraxfs-pic", R_MAX * 4);
9062143f 157 sysbus_init_mmio(sbd, &s->mmio);
81a322d4 158 return 0;
e62b5b13 159}
fd6dc90b 160
999e12bb
AL
161static Property etraxfs_pic_properties[] = {
162 DEFINE_PROP_PTR("interrupt_vector", struct etrax_pic, interrupt_vector),
163 DEFINE_PROP_END_OF_LIST(),
164};
165
166static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
167{
39bffca2 168 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb
AL
169 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
170
171 k->init = etraxfs_pic_init;
39bffca2 172 dc->props = etraxfs_pic_properties;
999e12bb
AL
173}
174
8c43a6f0 175static const TypeInfo etraxfs_pic_info = {
9062143f 176 .name = TYPE_ETRAX_FS_PIC,
39bffca2
AL
177 .parent = TYPE_SYS_BUS_DEVICE,
178 .instance_size = sizeof(struct etrax_pic),
179 .class_init = etraxfs_pic_class_init,
ee6847d1
GH
180};
181
83f7d43a 182static void etraxfs_pic_register_types(void)
fd6dc90b 183{
39bffca2 184 type_register_static(&etraxfs_pic_info);
fd6dc90b
EI
185}
186
83f7d43a 187type_init(etraxfs_pic_register_types)