Statistics
| Branch: | Revision:

root / hw / integratorcp.c @ 5dcb6b91

History | View | Annotate | Download (14.2 kB)

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