~ubuntu-branches/debian/jessie/qemu/jessie

« back to all changes in this revision

Viewing changes to hw/mst_fpga.c

  • Committer: Package Import Robot
  • Author(s): Vagrant Cascadian
  • Date: 2011-10-03 12:29:18 UTC
  • mfrom: (1.2.13) (10.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20111003122918-zc4kv6epchrbgdta
Tags: 0.15.0+dfsg-1
* New upstream version.
* Install new qemu-system, qemu-user and qemu-user-static variants: 
  lm32, microblazeel, s390x, unicore32
* Patch from upstream to set QEMU_INCLUDES before QEMU_CFLAGS.
* Update debian/watch to check http://qemu.org/download.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 * This code is licensed under the GNU GPL v2.
9
9
 */
10
10
#include "hw.h"
11
 
#include "pxa.h"
12
 
#include "mainstone.h"
 
11
#include "sysbus.h"
13
12
 
14
13
/* Mainstone FPGA for extern irqs */
15
14
#define FPGA_GPIO_PIN   0
27
26
#define MST_PCMCIA0             0xe0
28
27
#define MST_PCMCIA1             0xe4
29
28
 
 
29
#define MST_PCMCIAx_READY       (1 << 10)
 
30
#define MST_PCMCIAx_nCD         (1 << 5)
 
31
 
 
32
#define MST_PCMCIA_CD0_IRQ      9
 
33
#define MST_PCMCIA_CD1_IRQ      13
 
34
 
30
35
typedef struct mst_irq_state{
31
 
        qemu_irq *parent;
32
 
        qemu_irq *pins;
 
36
        SysBusDevice busdev;
 
37
 
 
38
        qemu_irq parent;
33
39
 
34
40
        uint32_t prev_level;
35
41
        uint32_t leddat1;
47
53
}mst_irq_state;
48
54
 
49
55
static void
50
 
mst_fpga_update_gpio(mst_irq_state *s)
51
 
{
52
 
        uint32_t level, diff;
53
 
        int bit;
54
 
        level = s->prev_level ^ s->intsetclr;
55
 
 
56
 
        for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
57
 
                bit = ffs(diff) - 1;
58
 
                qemu_set_irq(s->pins[bit], (level >> bit) & 1 );
59
 
        }
60
 
        s->prev_level = level;
61
 
}
62
 
 
63
 
static void
64
56
mst_fpga_set_irq(void *opaque, int irq, int level)
65
57
{
66
58
        mst_irq_state *s = (mst_irq_state *)opaque;
 
59
        uint32_t oldint = s->intsetclr & s->intmskena;
67
60
 
68
61
        if (level)
69
62
                s->prev_level |= 1u << irq;
70
63
        else
71
64
                s->prev_level &= ~(1u << irq);
72
65
 
73
 
        if(s->intmskena & (1u << irq)) {
74
 
                s->intsetclr = 1u << irq;
75
 
                qemu_set_irq(s->parent[0], level);
 
66
        switch(irq) {
 
67
        case MST_PCMCIA_CD0_IRQ:
 
68
                if (level)
 
69
                        s->pcmcia0 &= ~MST_PCMCIAx_nCD;
 
70
                else
 
71
                        s->pcmcia0 |=  MST_PCMCIAx_nCD;
 
72
                break;
 
73
        case MST_PCMCIA_CD1_IRQ:
 
74
                if (level)
 
75
                        s->pcmcia1 &= ~MST_PCMCIAx_nCD;
 
76
                else
 
77
                        s->pcmcia1 |=  MST_PCMCIAx_nCD;
 
78
                break;
76
79
        }
 
80
 
 
81
        if ((s->intmskena & (1u << irq)) && level)
 
82
                s->intsetclr |= 1u << irq;
 
83
 
 
84
        if (oldint != (s->intsetclr & s->intmskena))
 
85
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
77
86
}
78
87
 
79
88
 
109
118
                return s->pcmcia1;
110
119
        default:
111
120
                printf("Mainstone - mst_fpga_readb: Bad register offset "
112
 
                        REG_FMT " \n", addr);
 
121
                        "0x" TARGET_FMT_plx " \n", addr);
113
122
        }
114
123
        return 0;
115
124
}
145
154
        case MST_MSCRD:
146
155
                s->mscrd =  value;
147
156
                break;
148
 
        case MST_INTMSKENA:     /* Mask interupt */
 
157
        case MST_INTMSKENA:     /* Mask interrupt */
149
158
                s->intmskena = (value & 0xFEEFF);
150
 
                mst_fpga_update_gpio(s);
 
159
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
151
160
                break;
152
161
        case MST_INTSETCLR:     /* clear or set interrupt */
153
162
                s->intsetclr = (value & 0xFEEFF);
 
163
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
154
164
                break;
 
165
                /* For PCMCIAx allow the to change only power and reset */
155
166
        case MST_PCMCIA0:
156
 
                s->pcmcia0 = value;
 
167
                s->pcmcia0 = (value & 0x1f) | (s->pcmcia0 & ~0x1f);
157
168
                break;
158
169
        case MST_PCMCIA1:
159
 
                s->pcmcia1 = value;
 
170
                s->pcmcia1 = (value & 0x1f) | (s->pcmcia1 & ~0x1f);
160
171
                break;
161
172
        default:
162
173
                printf("Mainstone - mst_fpga_writeb: Bad register offset "
163
 
                        REG_FMT " \n", addr);
 
174
                        "0x" TARGET_FMT_plx " \n", addr);
164
175
        }
165
176
}
166
177
 
175
186
        mst_fpga_writeb,
176
187
};
177
188
 
178
 
static void
179
 
mst_fpga_save(QEMUFile *f, void *opaque)
180
 
{
181
 
        struct mst_irq_state *s = (mst_irq_state *) opaque;
182
 
 
183
 
        qemu_put_be32s(f, &s->prev_level);
184
 
        qemu_put_be32s(f, &s->leddat1);
185
 
        qemu_put_be32s(f, &s->leddat2);
186
 
        qemu_put_be32s(f, &s->ledctrl);
187
 
        qemu_put_be32s(f, &s->gpswr);
188
 
        qemu_put_be32s(f, &s->mscwr1);
189
 
        qemu_put_be32s(f, &s->mscwr2);
190
 
        qemu_put_be32s(f, &s->mscwr3);
191
 
        qemu_put_be32s(f, &s->mscrd);
192
 
        qemu_put_be32s(f, &s->intmskena);
193
 
        qemu_put_be32s(f, &s->intsetclr);
194
 
        qemu_put_be32s(f, &s->pcmcia0);
195
 
        qemu_put_be32s(f, &s->pcmcia1);
196
 
}
197
 
 
198
 
static int
199
 
mst_fpga_load(QEMUFile *f, void *opaque, int version_id)
 
189
 
 
190
static int mst_fpga_post_load(void *opaque, int version_id)
200
191
{
201
192
        mst_irq_state *s = (mst_irq_state *) opaque;
202
193
 
203
 
        qemu_get_be32s(f, &s->prev_level);
204
 
        qemu_get_be32s(f, &s->leddat1);
205
 
        qemu_get_be32s(f, &s->leddat2);
206
 
        qemu_get_be32s(f, &s->ledctrl);
207
 
        qemu_get_be32s(f, &s->gpswr);
208
 
        qemu_get_be32s(f, &s->mscwr1);
209
 
        qemu_get_be32s(f, &s->mscwr2);
210
 
        qemu_get_be32s(f, &s->mscwr3);
211
 
        qemu_get_be32s(f, &s->mscrd);
212
 
        qemu_get_be32s(f, &s->intmskena);
213
 
        qemu_get_be32s(f, &s->intsetclr);
214
 
        qemu_get_be32s(f, &s->pcmcia0);
215
 
        qemu_get_be32s(f, &s->pcmcia1);
 
194
        qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
216
195
        return 0;
217
196
}
218
197
 
219
 
qemu_irq *mst_irq_init(PXA2xxState *cpu, uint32_t base, int irq)
 
198
static int mst_fpga_init(SysBusDevice *dev)
220
199
{
221
200
        mst_irq_state *s;
222
201
        int iomemtype;
223
 
        qemu_irq *qi;
224
 
 
225
 
        s = (mst_irq_state  *)
226
 
                qemu_mallocz(sizeof(mst_irq_state));
227
 
 
228
 
        s->parent = &cpu->pic[irq];
 
202
 
 
203
        s = FROM_SYSBUS(mst_irq_state, dev);
 
204
 
 
205
        s->pcmcia0 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
 
206
        s->pcmcia1 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
 
207
 
 
208
        sysbus_init_irq(dev, &s->parent);
229
209
 
230
210
        /* alloc the external 16 irqs */
231
 
        qi  = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS);
232
 
        s->pins = qi;
 
211
        qdev_init_gpio_in(&dev->qdev, mst_fpga_set_irq, MST_NUM_IRQS);
233
212
 
234
213
        iomemtype = cpu_register_io_memory(mst_fpga_readfn,
235
214
                mst_fpga_writefn, s, DEVICE_NATIVE_ENDIAN);
236
 
        cpu_register_physical_memory(base, 0x00100000, iomemtype);
237
 
        register_savevm(NULL, "mainstone_fpga", 0, 0, mst_fpga_save,
238
 
                        mst_fpga_load, s);
239
 
        return qi;
240
 
}
 
215
        sysbus_init_mmio(dev, 0x00100000, iomemtype);
 
216
        return 0;
 
217
}
 
218
 
 
219
static VMStateDescription vmstate_mst_fpga_regs = {
 
220
        .name = "mainstone_fpga",
 
221
        .version_id = 0,
 
222
        .minimum_version_id = 0,
 
223
        .minimum_version_id_old = 0,
 
224
        .post_load = mst_fpga_post_load,
 
225
        .fields = (VMStateField []) {
 
226
                VMSTATE_UINT32(prev_level, mst_irq_state),
 
227
                VMSTATE_UINT32(leddat1, mst_irq_state),
 
228
                VMSTATE_UINT32(leddat2, mst_irq_state),
 
229
                VMSTATE_UINT32(ledctrl, mst_irq_state),
 
230
                VMSTATE_UINT32(gpswr, mst_irq_state),
 
231
                VMSTATE_UINT32(mscwr1, mst_irq_state),
 
232
                VMSTATE_UINT32(mscwr2, mst_irq_state),
 
233
                VMSTATE_UINT32(mscwr3, mst_irq_state),
 
234
                VMSTATE_UINT32(mscrd, mst_irq_state),
 
235
                VMSTATE_UINT32(intmskena, mst_irq_state),
 
236
                VMSTATE_UINT32(intsetclr, mst_irq_state),
 
237
                VMSTATE_UINT32(pcmcia0, mst_irq_state),
 
238
                VMSTATE_UINT32(pcmcia1, mst_irq_state),
 
239
                VMSTATE_END_OF_LIST(),
 
240
        },
 
241
};
 
242
 
 
243
static SysBusDeviceInfo mst_fpga_info = {
 
244
        .init = mst_fpga_init,
 
245
        .qdev.name = "mainstone-fpga",
 
246
        .qdev.desc = "Mainstone II FPGA",
 
247
        .qdev.size = sizeof(mst_irq_state),
 
248
        .qdev.vmsd = &vmstate_mst_fpga_regs,
 
249
};
 
250
 
 
251
static void mst_fpga_register(void)
 
252
{
 
253
        sysbus_register_withprop(&mst_fpga_info);
 
254
}
 
255
device_init(mst_fpga_register);