Revision 7233b355 hw/mainstone.c

b/hw/mainstone.c
14 14
#include "net.h"
15 15
#include "devices.h"
16 16
#include "boards.h"
17

  
18
#define MST_ETH_PHYS	0x10000300
19
#define MST_FPGA_PHYS	0x08000000
20

  
21
/* Mainstone FPGA for extern irqs */
22
#define FPGA_GPIO_PIN	0
23
#define MST_NUM_IRQS	16
24
#define MST_BASE	MST_FPGA_PHYS
25
#define MST_LEDDAT1	0x10
26
#define MST_LEDDAT2	0x14
27
#define MST_LEDCTRL	0x40
28
#define MST_GPSWR	0x60
29
#define MST_MSCWR1	0x80
30
#define MST_MSCWR2	0x84
31
#define MST_MSCWR3	0x88
32
#define MST_MSCRD	0x90
33
#define MST_INTMSKENA	0xc0
34
#define MST_INTSETCLR	0xd0
35
#define MST_PCMCIA0	0xe0
36
#define MST_PCMCIA1	0xe4
37

  
38
/* IRQ definitions */
39
#define ETHERNET_IRQ	3
40

  
41
typedef struct mst_irq_state {
42
    target_phys_addr_t target_base;
43
    qemu_irq *parent;
44
    qemu_irq *pins;
45

  
46
    uint32_t prev_level;
47
    uint32_t leddat1;
48
    uint32_t leddat2;
49
    uint32_t ledctrl;
50
    uint32_t gpswr;
51
    uint32_t mscwr1;
52
    uint32_t mscwr2;
53
    uint32_t mscwr3;
54
    uint32_t mscrd;
55
    uint32_t intmskena;
56
    uint32_t intsetclr;
57
    uint32_t pcmcia0;
58
    uint32_t pcmcia1;
59
} mst_irq_state;
60

  
61
static void 
62
mst_fpga_update_gpio(mst_irq_state *s)
63
{
64
    uint32_t level, diff;
65
    int bit;
66
    level = s->prev_level ^ s->intsetclr;
67

  
68
    for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
69
        bit = ffs(diff) - 1;
70
        qemu_set_irq(s->pins[bit], (level >> bit) & 1 );
71
    }
72
    s->prev_level = level;
73
}
74

  
75
static void 
76
mst_fpga_set_irq(void *opaque, int irq, int level)
77
{
78
    mst_irq_state *s = (mst_irq_state *)opaque;
79

  
80
    if (level)
81
        s->prev_level |= 1u << irq;
82
    else
83
        s->prev_level &= ~(1u << irq);
84

  
85
    if(s->intmskena & (1u << irq)) {
86
        s->intsetclr = 1u << irq;
87
        qemu_set_irq(s->parent[0], level);
88
    }
89
}
90

  
91
static uint32_t 
92
mst_fpga_readb(void *opaque, target_phys_addr_t addr)
93
{
94
    mst_irq_state *s = (mst_irq_state *) opaque;
95
    addr -= s->target_base;
96

  
97
    switch (addr) {
98
    case MST_LEDDAT1:
99
        return s->leddat1;
100
    case MST_LEDDAT2:
101
        return s->leddat2;
102
    case MST_LEDCTRL:
103
        return s->ledctrl;
104
    case MST_GPSWR:
105
        return s->gpswr;
106
    case MST_MSCWR1:
107
        return s->mscwr1;
108
    case MST_MSCWR2:
109
        return s->mscwr2;
110
    case MST_MSCWR3:
111
        return s->mscwr3;
112
    case MST_MSCRD:
113
        return s->mscrd;
114
    case MST_INTMSKENA:
115
        return s->intmskena;
116
    case MST_INTSETCLR:
117
        return s->intsetclr;
118
    case MST_PCMCIA0:
119
        return s->pcmcia0;
120
    case MST_PCMCIA1:
121
        return s->pcmcia1;
122
    default:
123
        printf("Mainstone - mst_fpga_readb: Bad register offset " 
124
                REG_FMT " \n", addr);
125
    }
126
    return 0;
127
}
128

  
129
static void 
130
mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
131
{
132
    mst_irq_state *s = (mst_irq_state *) opaque;
133
    addr -= s->target_base;
134
    value &= 0xffffffff;
135

  
136
    switch (addr) {
137
    case MST_LEDDAT1:
138
        s->leddat1 = value;
139
        break;
140
    case MST_LEDDAT2:
141
        s->leddat2 = value;
142
        break;
143
    case MST_LEDCTRL:
144
        s->ledctrl = value;
145
        break;
146
    case MST_GPSWR:
147
        s->gpswr = value;
148
        break;
149
    case MST_MSCWR1:
150
        s->mscwr1 = value;
151
        break;
152
    case MST_MSCWR2:
153
        s->mscwr2 = value;
154
        break;
155
    case MST_MSCWR3:
156
        s->mscwr3 = value;
157
        break;
158
    case MST_MSCRD:
159
        s->mscrd =  value;
160
        break;
161
    case MST_INTMSKENA:	/* Mask interupt */
162
        s->intmskena = (value & 0xFEEFF);
163
        mst_fpga_update_gpio(s);
164
        break;
165
    case MST_INTSETCLR:	/* clear or set interrupt */
166
        s->intsetclr = (value & 0xFEEFF);
167
        break;
168
    case MST_PCMCIA0:
169
        s->pcmcia0 = value;
170
        break;
171
    case MST_PCMCIA1:
172
        s->pcmcia1 = value;
173
        break;
174
    default:
175
        printf("Mainstone - mst_fpga_writeb: Bad register offset "
176
                REG_FMT " \n", addr);
177
    }
178
}
179

  
180
CPUReadMemoryFunc *mst_fpga_readfn[] = {
181
    mst_fpga_readb,
182
    mst_fpga_readb,
183
    mst_fpga_readb,
184
};
185
CPUWriteMemoryFunc *mst_fpga_writefn[] = {
186
    mst_fpga_writeb,
187
    mst_fpga_writeb,
188
    mst_fpga_writeb,
189
};
190

  
191
static void 
192
mst_fpga_save(QEMUFile *f, void *opaque)
193
{
194
    struct mst_irq_state *s = (mst_irq_state *) opaque;
195

  
196
    qemu_put_be32s(f, &s->prev_level);
197
    qemu_put_be32s(f, &s->leddat1);
198
    qemu_put_be32s(f, &s->leddat2);
199
    qemu_put_be32s(f, &s->ledctrl);
200
    qemu_put_be32s(f, &s->gpswr);
201
    qemu_put_be32s(f, &s->mscwr1);
202
    qemu_put_be32s(f, &s->mscwr2);
203
    qemu_put_be32s(f, &s->mscwr3);
204
    qemu_put_be32s(f, &s->mscrd);
205
    qemu_put_be32s(f, &s->intmskena);
206
    qemu_put_be32s(f, &s->intsetclr);
207
    qemu_put_be32s(f, &s->pcmcia0);
208
    qemu_put_be32s(f, &s->pcmcia1);
209
}
210

  
211
static int 
212
mst_fpga_load(QEMUFile *f, void *opaque, int version_id)
213
{
214
    mst_irq_state *s = (mst_irq_state *) opaque;
215

  
216
    qemu_get_be32s(f, &s->prev_level);
217
    qemu_get_be32s(f, &s->leddat1);
218
    qemu_get_be32s(f, &s->leddat2);
219
    qemu_get_be32s(f, &s->ledctrl);
220
    qemu_get_be32s(f, &s->gpswr);
221
    qemu_get_be32s(f, &s->mscwr1);
222
    qemu_get_be32s(f, &s->mscwr2);
223
    qemu_get_be32s(f, &s->mscwr3);
224
    qemu_get_be32s(f, &s->mscrd);
225
    qemu_get_be32s(f, &s->intmskena);
226
    qemu_get_be32s(f, &s->intsetclr);
227
    qemu_get_be32s(f, &s->pcmcia0);
228
    qemu_get_be32s(f, &s->pcmcia1);
229
    return 0;
230
}
231

  
232
static qemu_irq 
233
*mst_irq_init(struct pxa2xx_state_s *cpu, uint32_t base, int irq)
234
{
235
    mst_irq_state *s;
236
    int iomemtype;
237
    qemu_irq *qi;
238

  
239
    s = (mst_irq_state *) qemu_mallocz(sizeof(mst_irq_state));
240

  
241
    if (!s)
242
        return NULL;
243
    s->target_base = base;
244
    s->parent = &cpu->pic[irq];
245

  
246
    /* alloc the external 16 irqs */
247
    qi = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS);
248
    s->pins = qi;
249

  
250
    iomemtype = cpu_register_io_memory(0, mst_fpga_readfn,
251
                    mst_fpga_writefn, s);
252
    cpu_register_physical_memory(MST_BASE, 0x00100000, iomemtype);
253
    register_savevm("mainstone_fpga", 0, 0, mst_fpga_save, mst_fpga_load, s);
254
    return qi;
255
}
17
#include "mainstone.h"
18
#include "sysemu.h"
19
#include "flash.h"
256 20

  
257 21
enum mainstone_model_e { mainstone };
258 22

  
......
283 47
    /* Setup initial (reset) machine state */
284 48
    cpu->env->regs[15] = PXA2XX_SDRAM_BASE;
285 49

  
286
    mst_irq = mst_irq_init(cpu, MST_BASE, PXA2XX_PIC_GPIO_0);
50
	/* There are two 32MiB flash devices on the board */
51
	if (!pflash_register(MST_FLASH_0, mainstone_ram + PXA2XX_INTERNAL_SIZE,
52
		pflash_table[0], 256 * 1024, 128, 4, 0, 0, 0, 0)) {
53
			fprintf(stderr, "qemu: Error register flash memory.\n");
54
			exit(1);
55
	}
56

  
57
	if (!pflash_register(MST_FLASH_1, mainstone_ram + PXA2XX_INTERNAL_SIZE,
58
		pflash_table[1], 256 * 1024, 128, 4, 0, 0, 0, 0)) {
59
			fprintf(stderr, "qemu: Error register flash memory.\n");
60
			exit(1);
61
	}
62

  
63
    mst_irq = mst_irq_init(cpu, MST_FPGA_PHYS, PXA2XX_PIC_GPIO_0);
287 64
    smc91c111_init(&nd_table[0], MST_ETH_PHYS, mst_irq[ETHERNET_IRQ]);
288 65

  
289 66
    arm_load_kernel(cpu->env, mainstone_ram, kernel_filename, kernel_cmdline,

Also available in: Unified diff