Statistics
| Branch: | Revision:

root / hw / integratorcp.c @ ca87d03b

History | View | Annotate | Download (14.8 kB)

1 5fafdf24 ths
/*
2 b5ff1b31 bellard
 * ARM Integrator CP System emulation.
3 b5ff1b31 bellard
 *
4 a1bb27b1 pbrook
 * Copyright (c) 2005-2007 CodeSourcery.
5 b5ff1b31 bellard
 * Written by Paul Brook
6 b5ff1b31 bellard
 *
7 b5ff1b31 bellard
 * This code is licenced under the GPL
8 b5ff1b31 bellard
 */
9 b5ff1b31 bellard
10 87ecb68b pbrook
#include "hw.h"
11 87ecb68b pbrook
#include "primecell.h"
12 87ecb68b pbrook
#include "devices.h"
13 87ecb68b pbrook
#include "sysemu.h"
14 87ecb68b pbrook
#include "boards.h"
15 87ecb68b pbrook
#include "arm-misc.h"
16 87ecb68b pbrook
#include "net.h"
17 b5ff1b31 bellard
18 b5ff1b31 bellard
void DMA_run (void)
19 b5ff1b31 bellard
{
20 b5ff1b31 bellard
}
21 b5ff1b31 bellard
22 b5ff1b31 bellard
typedef struct {
23 b5ff1b31 bellard
    uint32_t flash_offset;
24 b5ff1b31 bellard
    uint32_t cm_osc;
25 b5ff1b31 bellard
    uint32_t cm_ctrl;
26 b5ff1b31 bellard
    uint32_t cm_lock;
27 b5ff1b31 bellard
    uint32_t cm_auxosc;
28 b5ff1b31 bellard
    uint32_t cm_sdram;
29 b5ff1b31 bellard
    uint32_t cm_init;
30 b5ff1b31 bellard
    uint32_t cm_flags;
31 b5ff1b31 bellard
    uint32_t cm_nvflags;
32 b5ff1b31 bellard
    uint32_t int_level;
33 b5ff1b31 bellard
    uint32_t irq_enabled;
34 b5ff1b31 bellard
    uint32_t fiq_enabled;
35 b5ff1b31 bellard
} integratorcm_state;
36 b5ff1b31 bellard
37 b5ff1b31 bellard
static uint8_t integrator_spd[128] = {
38 b5ff1b31 bellard
   128, 8, 4, 11, 9, 1, 64, 0,  2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
39 b5ff1b31 bellard
   0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
40 b5ff1b31 bellard
};
41 b5ff1b31 bellard
42 b5ff1b31 bellard
static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset)
43 b5ff1b31 bellard
{
44 b5ff1b31 bellard
    integratorcm_state *s = (integratorcm_state *)opaque;
45 b5ff1b31 bellard
    offset -= 0x10000000;
46 b5ff1b31 bellard
    if (offset >= 0x100 && offset < 0x200) {
47 b5ff1b31 bellard
        /* CM_SPD */
48 b5ff1b31 bellard
        if (offset >= 0x180)
49 b5ff1b31 bellard
            return 0;
50 b5ff1b31 bellard
        return integrator_spd[offset >> 2];
51 b5ff1b31 bellard
    }
52 b5ff1b31 bellard
    switch (offset >> 2) {
53 b5ff1b31 bellard
    case 0: /* CM_ID */
54 b5ff1b31 bellard
        return 0x411a3001;
55 b5ff1b31 bellard
    case 1: /* CM_PROC */
56 b5ff1b31 bellard
        return 0;
57 b5ff1b31 bellard
    case 2: /* CM_OSC */
58 b5ff1b31 bellard
        return s->cm_osc;
59 b5ff1b31 bellard
    case 3: /* CM_CTRL */
60 b5ff1b31 bellard
        return s->cm_ctrl;
61 b5ff1b31 bellard
    case 4: /* CM_STAT */
62 b5ff1b31 bellard
        return 0x00100000;
63 b5ff1b31 bellard
    case 5: /* CM_LOCK */
64 b5ff1b31 bellard
        if (s->cm_lock == 0xa05f) {
65 b5ff1b31 bellard
            return 0x1a05f;
66 b5ff1b31 bellard
        } else {
67 b5ff1b31 bellard
            return s->cm_lock;
68 b5ff1b31 bellard
        }
69 b5ff1b31 bellard
    case 6: /* CM_LMBUSCNT */
70 b5ff1b31 bellard
        /* ??? High frequency timer.  */
71 b5ff1b31 bellard
        cpu_abort(cpu_single_env, "integratorcm_read: CM_LMBUSCNT");
72 b5ff1b31 bellard
    case 7: /* CM_AUXOSC */
73 b5ff1b31 bellard
        return s->cm_auxosc;
74 b5ff1b31 bellard
    case 8: /* CM_SDRAM */
75 b5ff1b31 bellard
        return s->cm_sdram;
76 b5ff1b31 bellard
    case 9: /* CM_INIT */
77 b5ff1b31 bellard
        return s->cm_init;
78 b5ff1b31 bellard
    case 10: /* CM_REFCT */
79 b5ff1b31 bellard
        /* ??? High frequency timer.  */
80 b5ff1b31 bellard
        cpu_abort(cpu_single_env, "integratorcm_read: CM_REFCT");
81 b5ff1b31 bellard
    case 12: /* CM_FLAGS */
82 b5ff1b31 bellard
        return s->cm_flags;
83 b5ff1b31 bellard
    case 14: /* CM_NVFLAGS */
84 b5ff1b31 bellard
        return s->cm_nvflags;
85 b5ff1b31 bellard
    case 16: /* CM_IRQ_STAT */
86 b5ff1b31 bellard
        return s->int_level & s->irq_enabled;
87 b5ff1b31 bellard
    case 17: /* CM_IRQ_RSTAT */
88 b5ff1b31 bellard
        return s->int_level;
89 b5ff1b31 bellard
    case 18: /* CM_IRQ_ENSET */
90 b5ff1b31 bellard
        return s->irq_enabled;
91 b5ff1b31 bellard
    case 20: /* CM_SOFT_INTSET */
92 b5ff1b31 bellard
        return s->int_level & 1;
93 b5ff1b31 bellard
    case 24: /* CM_FIQ_STAT */
94 b5ff1b31 bellard
        return s->int_level & s->fiq_enabled;
95 b5ff1b31 bellard
    case 25: /* CM_FIQ_RSTAT */
96 b5ff1b31 bellard
        return s->int_level;
97 b5ff1b31 bellard
    case 26: /* CM_FIQ_ENSET */
98 b5ff1b31 bellard
        return s->fiq_enabled;
99 b5ff1b31 bellard
    case 32: /* CM_VOLTAGE_CTL0 */
100 b5ff1b31 bellard
    case 33: /* CM_VOLTAGE_CTL1 */
101 b5ff1b31 bellard
    case 34: /* CM_VOLTAGE_CTL2 */
102 b5ff1b31 bellard
    case 35: /* CM_VOLTAGE_CTL3 */
103 b5ff1b31 bellard
        /* ??? Voltage control unimplemented.  */
104 b5ff1b31 bellard
        return 0;
105 b5ff1b31 bellard
    default:
106 b5ff1b31 bellard
        cpu_abort (cpu_single_env,
107 4d1165fa pbrook
            "integratorcm_read: Unimplemented offset 0x%x\n", (int)offset);
108 b5ff1b31 bellard
        return 0;
109 b5ff1b31 bellard
    }
110 b5ff1b31 bellard
}
111 b5ff1b31 bellard
112 b5ff1b31 bellard
static void integratorcm_do_remap(integratorcm_state *s, int flash)
113 b5ff1b31 bellard
{
114 b5ff1b31 bellard
    if (flash) {
115 b5ff1b31 bellard
        cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM);
116 b5ff1b31 bellard
    } else {
117 b5ff1b31 bellard
        cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM);
118 b5ff1b31 bellard
    }
119 b5ff1b31 bellard
    //??? tlb_flush (cpu_single_env, 1);
120 b5ff1b31 bellard
}
121 b5ff1b31 bellard
122 b5ff1b31 bellard
static void integratorcm_set_ctrl(integratorcm_state *s, uint32_t value)
123 b5ff1b31 bellard
{
124 b5ff1b31 bellard
    if (value & 8) {
125 b5ff1b31 bellard
        cpu_abort(cpu_single_env, "Board reset\n");
126 b5ff1b31 bellard
    }
127 b5ff1b31 bellard
    if ((s->cm_init ^ value) & 4) {
128 b5ff1b31 bellard
        integratorcm_do_remap(s, (value & 4) == 0);
129 b5ff1b31 bellard
    }
130 b5ff1b31 bellard
    if ((s->cm_init ^ value) & 1) {
131 b5ff1b31 bellard
        printf("Green LED %s\n", (value & 1) ? "on" : "off");
132 b5ff1b31 bellard
    }
133 b5ff1b31 bellard
    s->cm_init = (s->cm_init & ~ 5) | (value ^ 5);
134 b5ff1b31 bellard
}
135 b5ff1b31 bellard
136 b5ff1b31 bellard
static void integratorcm_update(integratorcm_state *s)
137 b5ff1b31 bellard
{
138 b5ff1b31 bellard
    /* ??? The CPU irq/fiq is raised when either the core module or base PIC
139 b5ff1b31 bellard
       are active.  */
140 b5ff1b31 bellard
    if (s->int_level & (s->irq_enabled | s->fiq_enabled))
141 b5ff1b31 bellard
        cpu_abort(cpu_single_env, "Core module interrupt\n");
142 b5ff1b31 bellard
}
143 b5ff1b31 bellard
144 b5ff1b31 bellard
static void integratorcm_write(void *opaque, target_phys_addr_t offset,
145 b5ff1b31 bellard
                               uint32_t value)
146 b5ff1b31 bellard
{
147 b5ff1b31 bellard
    integratorcm_state *s = (integratorcm_state *)opaque;
148 b5ff1b31 bellard
    offset -= 0x10000000;
149 b5ff1b31 bellard
    switch (offset >> 2) {
150 b5ff1b31 bellard
    case 2: /* CM_OSC */
151 b5ff1b31 bellard
        if (s->cm_lock == 0xa05f)
152 b5ff1b31 bellard
            s->cm_osc = value;
153 b5ff1b31 bellard
        break;
154 b5ff1b31 bellard
    case 3: /* CM_CTRL */
155 b5ff1b31 bellard
        integratorcm_set_ctrl(s, value);
156 b5ff1b31 bellard
        break;
157 b5ff1b31 bellard
    case 5: /* CM_LOCK */
158 b5ff1b31 bellard
        s->cm_lock = value & 0xffff;
159 b5ff1b31 bellard
        break;
160 b5ff1b31 bellard
    case 7: /* CM_AUXOSC */
161 b5ff1b31 bellard
        if (s->cm_lock == 0xa05f)
162 b5ff1b31 bellard
            s->cm_auxosc = value;
163 b5ff1b31 bellard
        break;
164 b5ff1b31 bellard
    case 8: /* CM_SDRAM */
165 b5ff1b31 bellard
        s->cm_sdram = value;
166 b5ff1b31 bellard
        break;
167 b5ff1b31 bellard
    case 9: /* CM_INIT */
168 b5ff1b31 bellard
        /* ??? This can change the memory bus frequency.  */
169 b5ff1b31 bellard
        s->cm_init = value;
170 b5ff1b31 bellard
        break;
171 b5ff1b31 bellard
    case 12: /* CM_FLAGSS */
172 b5ff1b31 bellard
        s->cm_flags |= value;
173 b5ff1b31 bellard
        break;
174 b5ff1b31 bellard
    case 13: /* CM_FLAGSC */
175 b5ff1b31 bellard
        s->cm_flags &= ~value;
176 b5ff1b31 bellard
        break;
177 b5ff1b31 bellard
    case 14: /* CM_NVFLAGSS */
178 b5ff1b31 bellard
        s->cm_nvflags |= value;
179 b5ff1b31 bellard
        break;
180 b5ff1b31 bellard
    case 15: /* CM_NVFLAGSS */
181 b5ff1b31 bellard
        s->cm_nvflags &= ~value;
182 b5ff1b31 bellard
        break;
183 b5ff1b31 bellard
    case 18: /* CM_IRQ_ENSET */
184 b5ff1b31 bellard
        s->irq_enabled |= value;
185 b5ff1b31 bellard
        integratorcm_update(s);
186 b5ff1b31 bellard
        break;
187 b5ff1b31 bellard
    case 19: /* CM_IRQ_ENCLR */
188 b5ff1b31 bellard
        s->irq_enabled &= ~value;
189 b5ff1b31 bellard
        integratorcm_update(s);
190 b5ff1b31 bellard
        break;
191 b5ff1b31 bellard
    case 20: /* CM_SOFT_INTSET */
192 b5ff1b31 bellard
        s->int_level |= (value & 1);
193 b5ff1b31 bellard
        integratorcm_update(s);
194 b5ff1b31 bellard
        break;
195 b5ff1b31 bellard
    case 21: /* CM_SOFT_INTCLR */
196 b5ff1b31 bellard
        s->int_level &= ~(value & 1);
197 b5ff1b31 bellard
        integratorcm_update(s);
198 b5ff1b31 bellard
        break;
199 b5ff1b31 bellard
    case 26: /* CM_FIQ_ENSET */
200 b5ff1b31 bellard
        s->fiq_enabled |= value;
201 b5ff1b31 bellard
        integratorcm_update(s);
202 b5ff1b31 bellard
        break;
203 b5ff1b31 bellard
    case 27: /* CM_FIQ_ENCLR */
204 b5ff1b31 bellard
        s->fiq_enabled &= ~value;
205 b5ff1b31 bellard
        integratorcm_update(s);
206 b5ff1b31 bellard
        break;
207 b5ff1b31 bellard
    case 32: /* CM_VOLTAGE_CTL0 */
208 b5ff1b31 bellard
    case 33: /* CM_VOLTAGE_CTL1 */
209 b5ff1b31 bellard
    case 34: /* CM_VOLTAGE_CTL2 */
210 b5ff1b31 bellard
    case 35: /* CM_VOLTAGE_CTL3 */
211 b5ff1b31 bellard
        /* ??? Voltage control unimplemented.  */
212 b5ff1b31 bellard
        break;
213 b5ff1b31 bellard
    default:
214 b5ff1b31 bellard
        cpu_abort (cpu_single_env,
215 4d1165fa pbrook
            "integratorcm_write: Unimplemented offset 0x%x\n", (int)offset);
216 b5ff1b31 bellard
        break;
217 b5ff1b31 bellard
    }
218 b5ff1b31 bellard
}
219 b5ff1b31 bellard
220 b5ff1b31 bellard
/* Integrator/CM control registers.  */
221 b5ff1b31 bellard
222 b5ff1b31 bellard
static CPUReadMemoryFunc *integratorcm_readfn[] = {
223 b5ff1b31 bellard
   integratorcm_read,
224 b5ff1b31 bellard
   integratorcm_read,
225 b5ff1b31 bellard
   integratorcm_read
226 b5ff1b31 bellard
};
227 b5ff1b31 bellard
228 b5ff1b31 bellard
static CPUWriteMemoryFunc *integratorcm_writefn[] = {
229 b5ff1b31 bellard
   integratorcm_write,
230 b5ff1b31 bellard
   integratorcm_write,
231 b5ff1b31 bellard
   integratorcm_write
232 b5ff1b31 bellard
};
233 b5ff1b31 bellard
234 b5ff1b31 bellard
static void integratorcm_init(int memsz, uint32_t flash_offset)
235 b5ff1b31 bellard
{
236 b5ff1b31 bellard
    int iomemtype;
237 b5ff1b31 bellard
    integratorcm_state *s;
238 b5ff1b31 bellard
239 b5ff1b31 bellard
    s = (integratorcm_state *)qemu_mallocz(sizeof(integratorcm_state));
240 b5ff1b31 bellard
    s->cm_osc = 0x01000048;
241 b5ff1b31 bellard
    /* ??? What should the high bits of this value be?  */
242 b5ff1b31 bellard
    s->cm_auxosc = 0x0007feff;
243 b5ff1b31 bellard
    s->cm_sdram = 0x00011122;
244 b5ff1b31 bellard
    if (memsz >= 256) {
245 b5ff1b31 bellard
        integrator_spd[31] = 64;
246 b5ff1b31 bellard
        s->cm_sdram |= 0x10;
247 b5ff1b31 bellard
    } else if (memsz >= 128) {
248 b5ff1b31 bellard
        integrator_spd[31] = 32;
249 b5ff1b31 bellard
        s->cm_sdram |= 0x0c;
250 b5ff1b31 bellard
    } else if (memsz >= 64) {
251 b5ff1b31 bellard
        integrator_spd[31] = 16;
252 b5ff1b31 bellard
        s->cm_sdram |= 0x08;
253 b5ff1b31 bellard
    } else if (memsz >= 32) {
254 b5ff1b31 bellard
        integrator_spd[31] = 4;
255 b5ff1b31 bellard
        s->cm_sdram |= 0x04;
256 b5ff1b31 bellard
    } else {
257 b5ff1b31 bellard
        integrator_spd[31] = 2;
258 b5ff1b31 bellard
    }
259 b5ff1b31 bellard
    memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
260 b5ff1b31 bellard
    s->cm_init = 0x00000112;
261 b5ff1b31 bellard
    s->flash_offset = flash_offset;
262 b5ff1b31 bellard
263 b5ff1b31 bellard
    iomemtype = cpu_register_io_memory(0, integratorcm_readfn,
264 b5ff1b31 bellard
                                       integratorcm_writefn, s);
265 187337f8 pbrook
    cpu_register_physical_memory(0x10000000, 0x00800000, iomemtype);
266 b5ff1b31 bellard
    integratorcm_do_remap(s, 1);
267 b5ff1b31 bellard
    /* ??? Save/restore.  */
268 b5ff1b31 bellard
}
269 b5ff1b31 bellard
270 b5ff1b31 bellard
/* Integrator/CP hardware emulation.  */
271 b5ff1b31 bellard
/* Primary interrupt controller.  */
272 b5ff1b31 bellard
273 b5ff1b31 bellard
typedef struct icp_pic_state
274 b5ff1b31 bellard
{
275 b5ff1b31 bellard
  uint32_t base;
276 b5ff1b31 bellard
  uint32_t level;
277 b5ff1b31 bellard
  uint32_t irq_enabled;
278 b5ff1b31 bellard
  uint32_t fiq_enabled;
279 d537cf6c pbrook
  qemu_irq parent_irq;
280 d537cf6c pbrook
  qemu_irq parent_fiq;
281 b5ff1b31 bellard
} icp_pic_state;
282 b5ff1b31 bellard
283 b5ff1b31 bellard
static void icp_pic_update(icp_pic_state *s)
284 b5ff1b31 bellard
{
285 cdbdb648 pbrook
    uint32_t flags;
286 b5ff1b31 bellard
287 d537cf6c pbrook
    flags = (s->level & s->irq_enabled);
288 d537cf6c pbrook
    qemu_set_irq(s->parent_irq, flags != 0);
289 d537cf6c pbrook
    flags = (s->level & s->fiq_enabled);
290 d537cf6c pbrook
    qemu_set_irq(s->parent_fiq, flags != 0);
291 b5ff1b31 bellard
}
292 b5ff1b31 bellard
293 cdbdb648 pbrook
static void icp_pic_set_irq(void *opaque, int irq, int level)
294 b5ff1b31 bellard
{
295 80337b66 bellard
    icp_pic_state *s = (icp_pic_state *)opaque;
296 b5ff1b31 bellard
    if (level)
297 80337b66 bellard
        s->level |= 1 << irq;
298 b5ff1b31 bellard
    else
299 80337b66 bellard
        s->level &= ~(1 << irq);
300 b5ff1b31 bellard
    icp_pic_update(s);
301 b5ff1b31 bellard
}
302 b5ff1b31 bellard
303 b5ff1b31 bellard
static uint32_t icp_pic_read(void *opaque, target_phys_addr_t offset)
304 b5ff1b31 bellard
{
305 b5ff1b31 bellard
    icp_pic_state *s = (icp_pic_state *)opaque;
306 b5ff1b31 bellard
307 b5ff1b31 bellard
    offset -= s->base;
308 b5ff1b31 bellard
    switch (offset >> 2) {
309 b5ff1b31 bellard
    case 0: /* IRQ_STATUS */
310 b5ff1b31 bellard
        return s->level & s->irq_enabled;
311 b5ff1b31 bellard
    case 1: /* IRQ_RAWSTAT */
312 b5ff1b31 bellard
        return s->level;
313 b5ff1b31 bellard
    case 2: /* IRQ_ENABLESET */
314 b5ff1b31 bellard
        return s->irq_enabled;
315 b5ff1b31 bellard
    case 4: /* INT_SOFTSET */
316 b5ff1b31 bellard
        return s->level & 1;
317 b5ff1b31 bellard
    case 8: /* FRQ_STATUS */
318 b5ff1b31 bellard
        return s->level & s->fiq_enabled;
319 b5ff1b31 bellard
    case 9: /* FRQ_RAWSTAT */
320 b5ff1b31 bellard
        return s->level;
321 b5ff1b31 bellard
    case 10: /* FRQ_ENABLESET */
322 b5ff1b31 bellard
        return s->fiq_enabled;
323 b5ff1b31 bellard
    case 3: /* IRQ_ENABLECLR */
324 b5ff1b31 bellard
    case 5: /* INT_SOFTCLR */
325 b5ff1b31 bellard
    case 11: /* FRQ_ENABLECLR */
326 b5ff1b31 bellard
    default:
327 29bfb117 pbrook
        printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
328 b5ff1b31 bellard
        return 0;
329 b5ff1b31 bellard
    }
330 b5ff1b31 bellard
}
331 b5ff1b31 bellard
332 b5ff1b31 bellard
static void icp_pic_write(void *opaque, target_phys_addr_t offset,
333 b5ff1b31 bellard
                          uint32_t value)
334 b5ff1b31 bellard
{
335 b5ff1b31 bellard
    icp_pic_state *s = (icp_pic_state *)opaque;
336 b5ff1b31 bellard
    offset -= s->base;
337 b5ff1b31 bellard
338 b5ff1b31 bellard
    switch (offset >> 2) {
339 b5ff1b31 bellard
    case 2: /* IRQ_ENABLESET */
340 b5ff1b31 bellard
        s->irq_enabled |= value;
341 b5ff1b31 bellard
        break;
342 b5ff1b31 bellard
    case 3: /* IRQ_ENABLECLR */
343 b5ff1b31 bellard
        s->irq_enabled &= ~value;
344 b5ff1b31 bellard
        break;
345 b5ff1b31 bellard
    case 4: /* INT_SOFTSET */
346 b5ff1b31 bellard
        if (value & 1)
347 d537cf6c pbrook
            icp_pic_set_irq(s, 0, 1);
348 b5ff1b31 bellard
        break;
349 b5ff1b31 bellard
    case 5: /* INT_SOFTCLR */
350 b5ff1b31 bellard
        if (value & 1)
351 d537cf6c pbrook
            icp_pic_set_irq(s, 0, 0);
352 b5ff1b31 bellard
        break;
353 b5ff1b31 bellard
    case 10: /* FRQ_ENABLESET */
354 b5ff1b31 bellard
        s->fiq_enabled |= value;
355 b5ff1b31 bellard
        break;
356 b5ff1b31 bellard
    case 11: /* FRQ_ENABLECLR */
357 b5ff1b31 bellard
        s->fiq_enabled &= ~value;
358 b5ff1b31 bellard
        break;
359 b5ff1b31 bellard
    case 0: /* IRQ_STATUS */
360 b5ff1b31 bellard
    case 1: /* IRQ_RAWSTAT */
361 b5ff1b31 bellard
    case 8: /* FRQ_STATUS */
362 b5ff1b31 bellard
    case 9: /* FRQ_RAWSTAT */
363 b5ff1b31 bellard
    default:
364 29bfb117 pbrook
        printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
365 b5ff1b31 bellard
        return;
366 b5ff1b31 bellard
    }
367 b5ff1b31 bellard
    icp_pic_update(s);
368 b5ff1b31 bellard
}
369 b5ff1b31 bellard
370 b5ff1b31 bellard
static CPUReadMemoryFunc *icp_pic_readfn[] = {
371 b5ff1b31 bellard
   icp_pic_read,
372 b5ff1b31 bellard
   icp_pic_read,
373 b5ff1b31 bellard
   icp_pic_read
374 b5ff1b31 bellard
};
375 b5ff1b31 bellard
376 b5ff1b31 bellard
static CPUWriteMemoryFunc *icp_pic_writefn[] = {
377 b5ff1b31 bellard
   icp_pic_write,
378 b5ff1b31 bellard
   icp_pic_write,
379 b5ff1b31 bellard
   icp_pic_write
380 b5ff1b31 bellard
};
381 b5ff1b31 bellard
382 d537cf6c pbrook
static qemu_irq *icp_pic_init(uint32_t base,
383 d537cf6c pbrook
                              qemu_irq parent_irq, qemu_irq parent_fiq)
384 b5ff1b31 bellard
{
385 b5ff1b31 bellard
    icp_pic_state *s;
386 b5ff1b31 bellard
    int iomemtype;
387 d537cf6c pbrook
    qemu_irq *qi;
388 b5ff1b31 bellard
389 b5ff1b31 bellard
    s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));
390 b5ff1b31 bellard
    if (!s)
391 b5ff1b31 bellard
        return NULL;
392 d537cf6c pbrook
    qi = qemu_allocate_irqs(icp_pic_set_irq, s, 32);
393 b5ff1b31 bellard
    s->base = base;
394 b5ff1b31 bellard
    s->parent_irq = parent_irq;
395 cdbdb648 pbrook
    s->parent_fiq = parent_fiq;
396 b5ff1b31 bellard
    iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
397 b5ff1b31 bellard
                                       icp_pic_writefn, s);
398 187337f8 pbrook
    cpu_register_physical_memory(base, 0x00800000, iomemtype);
399 b5ff1b31 bellard
    /* ??? Save/restore.  */
400 d537cf6c pbrook
    return qi;
401 b5ff1b31 bellard
}
402 b5ff1b31 bellard
403 b5ff1b31 bellard
/* CP control registers.  */
404 b5ff1b31 bellard
typedef struct {
405 b5ff1b31 bellard
    uint32_t base;
406 b5ff1b31 bellard
} icp_control_state;
407 b5ff1b31 bellard
408 b5ff1b31 bellard
static uint32_t icp_control_read(void *opaque, target_phys_addr_t offset)
409 b5ff1b31 bellard
{
410 b5ff1b31 bellard
    icp_control_state *s = (icp_control_state *)opaque;
411 b5ff1b31 bellard
    offset -= s->base;
412 b5ff1b31 bellard
    switch (offset >> 2) {
413 b5ff1b31 bellard
    case 0: /* CP_IDFIELD */
414 b5ff1b31 bellard
        return 0x41034003;
415 b5ff1b31 bellard
    case 1: /* CP_FLASHPROG */
416 b5ff1b31 bellard
        return 0;
417 b5ff1b31 bellard
    case 2: /* CP_INTREG */
418 b5ff1b31 bellard
        return 0;
419 b5ff1b31 bellard
    case 3: /* CP_DECODE */
420 b5ff1b31 bellard
        return 0x11;
421 b5ff1b31 bellard
    default:
422 4d1165fa pbrook
        cpu_abort (cpu_single_env, "icp_control_read: Bad offset %x\n",
423 4d1165fa pbrook
                   (int)offset);
424 b5ff1b31 bellard
        return 0;
425 b5ff1b31 bellard
    }
426 b5ff1b31 bellard
}
427 b5ff1b31 bellard
428 b5ff1b31 bellard
static void icp_control_write(void *opaque, target_phys_addr_t offset,
429 b5ff1b31 bellard
                          uint32_t value)
430 b5ff1b31 bellard
{
431 b5ff1b31 bellard
    icp_control_state *s = (icp_control_state *)opaque;
432 b5ff1b31 bellard
    offset -= s->base;
433 b5ff1b31 bellard
    switch (offset >> 2) {
434 b5ff1b31 bellard
    case 1: /* CP_FLASHPROG */
435 b5ff1b31 bellard
    case 2: /* CP_INTREG */
436 b5ff1b31 bellard
    case 3: /* CP_DECODE */
437 b5ff1b31 bellard
        /* Nothing interesting implemented yet.  */
438 b5ff1b31 bellard
        break;
439 b5ff1b31 bellard
    default:
440 4d1165fa pbrook
        cpu_abort (cpu_single_env, "icp_control_write: Bad offset %x\n",
441 4d1165fa pbrook
                   (int)offset);
442 b5ff1b31 bellard
    }
443 b5ff1b31 bellard
}
444 b5ff1b31 bellard
static CPUReadMemoryFunc *icp_control_readfn[] = {
445 b5ff1b31 bellard
   icp_control_read,
446 b5ff1b31 bellard
   icp_control_read,
447 b5ff1b31 bellard
   icp_control_read
448 b5ff1b31 bellard
};
449 b5ff1b31 bellard
450 b5ff1b31 bellard
static CPUWriteMemoryFunc *icp_control_writefn[] = {
451 b5ff1b31 bellard
   icp_control_write,
452 b5ff1b31 bellard
   icp_control_write,
453 b5ff1b31 bellard
   icp_control_write
454 b5ff1b31 bellard
};
455 b5ff1b31 bellard
456 b5ff1b31 bellard
static void icp_control_init(uint32_t base)
457 b5ff1b31 bellard
{
458 b5ff1b31 bellard
    int iomemtype;
459 b5ff1b31 bellard
    icp_control_state *s;
460 b5ff1b31 bellard
461 b5ff1b31 bellard
    s = (icp_control_state *)qemu_mallocz(sizeof(icp_control_state));
462 b5ff1b31 bellard
    iomemtype = cpu_register_io_memory(0, icp_control_readfn,
463 b5ff1b31 bellard
                                       icp_control_writefn, s);
464 187337f8 pbrook
    cpu_register_physical_memory(base, 0x00800000, iomemtype);
465 b5ff1b31 bellard
    s->base = base;
466 b5ff1b31 bellard
    /* ??? Save/restore.  */
467 b5ff1b31 bellard
}
468 b5ff1b31 bellard
469 b5ff1b31 bellard
470 b5ff1b31 bellard
/* Board init.  */
471 b5ff1b31 bellard
472 6ac0e82d balrog
static void integratorcp_init(int ram_size, int vga_ram_size,
473 6ac0e82d balrog
                     const char *boot_device, DisplayState *ds,
474 b5ff1b31 bellard
                     const char *kernel_filename, const char *kernel_cmdline,
475 3371d272 pbrook
                     const char *initrd_filename, const char *cpu_model)
476 b5ff1b31 bellard
{
477 b5ff1b31 bellard
    CPUState *env;
478 b5ff1b31 bellard
    uint32_t bios_offset;
479 d537cf6c pbrook
    qemu_irq *pic;
480 d537cf6c pbrook
    qemu_irq *cpu_pic;
481 e4bcb14c ths
    int sd;
482 b5ff1b31 bellard
483 3371d272 pbrook
    if (!cpu_model)
484 3371d272 pbrook
        cpu_model = "arm926";
485 aaed909a bellard
    env = cpu_init(cpu_model);
486 aaed909a bellard
    if (!env) {
487 aaed909a bellard
        fprintf(stderr, "Unable to find CPU definition\n");
488 aaed909a bellard
        exit(1);
489 aaed909a bellard
    }
490 b5ff1b31 bellard
    bios_offset = ram_size + vga_ram_size;
491 b5ff1b31 bellard
    /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
492 b5ff1b31 bellard
    /* ??? RAM shoud repeat to fill physical memory space.  */
493 b5ff1b31 bellard
    /* SDRAM at address zero*/
494 b5ff1b31 bellard
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
495 b5ff1b31 bellard
    /* And again at address 0x80000000 */
496 b5ff1b31 bellard
    cpu_register_physical_memory(0x80000000, ram_size, IO_MEM_RAM);
497 b5ff1b31 bellard
498 b5ff1b31 bellard
    integratorcm_init(ram_size >> 20, bios_offset);
499 cdbdb648 pbrook
    cpu_pic = arm_pic_init_cpu(env);
500 d537cf6c pbrook
    pic = icp_pic_init(0x14000000, cpu_pic[ARM_PIC_CPU_IRQ],
501 d537cf6c pbrook
                       cpu_pic[ARM_PIC_CPU_FIQ]);
502 d537cf6c pbrook
    icp_pic_init(0xca000000, pic[26], NULL);
503 cdbdb648 pbrook
    icp_pit_init(0x13000000, pic, 5);
504 7e1543c2 pbrook
    pl031_init(0x15000000, pic[8]);
505 9ee6e8bb pbrook
    pl011_init(0x16000000, pic[1], serial_hds[0], PL011_ARM);
506 9ee6e8bb pbrook
    pl011_init(0x17000000, pic[2], serial_hds[1], PL011_ARM);
507 b5ff1b31 bellard
    icp_control_init(0xcb000000);
508 d537cf6c pbrook
    pl050_init(0x18000000, pic[3], 0);
509 d537cf6c pbrook
    pl050_init(0x19000000, pic[4], 1);
510 e4bcb14c ths
    sd = drive_get_index(IF_SD, 0, 0);
511 e4bcb14c ths
    if (sd == -1) {
512 e4bcb14c ths
        fprintf(stderr, "qemu: missing SecureDigital card\n");
513 e4bcb14c ths
        exit(1);
514 e4bcb14c ths
    }
515 e4bcb14c ths
    pl181_init(0x1c000000, drives_table[sd].bdrv, pic[23], pic[24]);
516 a41b2ff2 pbrook
    if (nd_table[0].vlan) {
517 a41b2ff2 pbrook
        if (nd_table[0].model == NULL
518 a41b2ff2 pbrook
            || strcmp(nd_table[0].model, "smc91c111") == 0) {
519 d537cf6c pbrook
            smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
520 c4a7060c blueswir1
        } else if (strcmp(nd_table[0].model, "?") == 0) {
521 c4a7060c blueswir1
            fprintf(stderr, "qemu: Supported NICs: smc91c111\n");
522 c4a7060c blueswir1
            exit (1);
523 a41b2ff2 pbrook
        } else {
524 a41b2ff2 pbrook
            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
525 a41b2ff2 pbrook
            exit (1);
526 a41b2ff2 pbrook
        }
527 a41b2ff2 pbrook
    }
528 d537cf6c pbrook
    pl110_init(ds, 0xc0000000, pic[22], 0);
529 b5ff1b31 bellard
530 daf90626 pbrook
    arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
531 9d551997 balrog
                    initrd_filename, 0x113, 0x0);
532 b5ff1b31 bellard
}
533 b5ff1b31 bellard
534 3371d272 pbrook
QEMUMachine integratorcp_machine = {
535 3371d272 pbrook
    "integratorcp",
536 40f137e1 pbrook
    "ARM Integrator/CP (ARM926EJ-S)",
537 3371d272 pbrook
    integratorcp_init,
538 b5ff1b31 bellard
};