Statistics
| Branch: | Revision:

root / hw / integratorcp.c @ bf4f74c0

History | View | Annotate | Download (14.6 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
typedef struct {
19 b5ff1b31 bellard
    uint32_t flash_offset;
20 b5ff1b31 bellard
    uint32_t cm_osc;
21 b5ff1b31 bellard
    uint32_t cm_ctrl;
22 b5ff1b31 bellard
    uint32_t cm_lock;
23 b5ff1b31 bellard
    uint32_t cm_auxosc;
24 b5ff1b31 bellard
    uint32_t cm_sdram;
25 b5ff1b31 bellard
    uint32_t cm_init;
26 b5ff1b31 bellard
    uint32_t cm_flags;
27 b5ff1b31 bellard
    uint32_t cm_nvflags;
28 b5ff1b31 bellard
    uint32_t int_level;
29 b5ff1b31 bellard
    uint32_t irq_enabled;
30 b5ff1b31 bellard
    uint32_t fiq_enabled;
31 b5ff1b31 bellard
} integratorcm_state;
32 b5ff1b31 bellard
33 b5ff1b31 bellard
static uint8_t integrator_spd[128] = {
34 b5ff1b31 bellard
   128, 8, 4, 11, 9, 1, 64, 0,  2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
35 b5ff1b31 bellard
   0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
36 b5ff1b31 bellard
};
37 b5ff1b31 bellard
38 b5ff1b31 bellard
static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset)
39 b5ff1b31 bellard
{
40 b5ff1b31 bellard
    integratorcm_state *s = (integratorcm_state *)opaque;
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 4d1165fa pbrook
            "integratorcm_read: Unimplemented offset 0x%x\n", (int)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
    switch (offset >> 2) {
144 b5ff1b31 bellard
    case 2: /* CM_OSC */
145 b5ff1b31 bellard
        if (s->cm_lock == 0xa05f)
146 b5ff1b31 bellard
            s->cm_osc = value;
147 b5ff1b31 bellard
        break;
148 b5ff1b31 bellard
    case 3: /* CM_CTRL */
149 b5ff1b31 bellard
        integratorcm_set_ctrl(s, value);
150 b5ff1b31 bellard
        break;
151 b5ff1b31 bellard
    case 5: /* CM_LOCK */
152 b5ff1b31 bellard
        s->cm_lock = value & 0xffff;
153 b5ff1b31 bellard
        break;
154 b5ff1b31 bellard
    case 7: /* CM_AUXOSC */
155 b5ff1b31 bellard
        if (s->cm_lock == 0xa05f)
156 b5ff1b31 bellard
            s->cm_auxosc = value;
157 b5ff1b31 bellard
        break;
158 b5ff1b31 bellard
    case 8: /* CM_SDRAM */
159 b5ff1b31 bellard
        s->cm_sdram = value;
160 b5ff1b31 bellard
        break;
161 b5ff1b31 bellard
    case 9: /* CM_INIT */
162 b5ff1b31 bellard
        /* ??? This can change the memory bus frequency.  */
163 b5ff1b31 bellard
        s->cm_init = value;
164 b5ff1b31 bellard
        break;
165 b5ff1b31 bellard
    case 12: /* CM_FLAGSS */
166 b5ff1b31 bellard
        s->cm_flags |= value;
167 b5ff1b31 bellard
        break;
168 b5ff1b31 bellard
    case 13: /* CM_FLAGSC */
169 b5ff1b31 bellard
        s->cm_flags &= ~value;
170 b5ff1b31 bellard
        break;
171 b5ff1b31 bellard
    case 14: /* CM_NVFLAGSS */
172 b5ff1b31 bellard
        s->cm_nvflags |= value;
173 b5ff1b31 bellard
        break;
174 b5ff1b31 bellard
    case 15: /* CM_NVFLAGSS */
175 b5ff1b31 bellard
        s->cm_nvflags &= ~value;
176 b5ff1b31 bellard
        break;
177 b5ff1b31 bellard
    case 18: /* CM_IRQ_ENSET */
178 b5ff1b31 bellard
        s->irq_enabled |= value;
179 b5ff1b31 bellard
        integratorcm_update(s);
180 b5ff1b31 bellard
        break;
181 b5ff1b31 bellard
    case 19: /* CM_IRQ_ENCLR */
182 b5ff1b31 bellard
        s->irq_enabled &= ~value;
183 b5ff1b31 bellard
        integratorcm_update(s);
184 b5ff1b31 bellard
        break;
185 b5ff1b31 bellard
    case 20: /* CM_SOFT_INTSET */
186 b5ff1b31 bellard
        s->int_level |= (value & 1);
187 b5ff1b31 bellard
        integratorcm_update(s);
188 b5ff1b31 bellard
        break;
189 b5ff1b31 bellard
    case 21: /* CM_SOFT_INTCLR */
190 b5ff1b31 bellard
        s->int_level &= ~(value & 1);
191 b5ff1b31 bellard
        integratorcm_update(s);
192 b5ff1b31 bellard
        break;
193 b5ff1b31 bellard
    case 26: /* CM_FIQ_ENSET */
194 b5ff1b31 bellard
        s->fiq_enabled |= value;
195 b5ff1b31 bellard
        integratorcm_update(s);
196 b5ff1b31 bellard
        break;
197 b5ff1b31 bellard
    case 27: /* CM_FIQ_ENCLR */
198 b5ff1b31 bellard
        s->fiq_enabled &= ~value;
199 b5ff1b31 bellard
        integratorcm_update(s);
200 b5ff1b31 bellard
        break;
201 b5ff1b31 bellard
    case 32: /* CM_VOLTAGE_CTL0 */
202 b5ff1b31 bellard
    case 33: /* CM_VOLTAGE_CTL1 */
203 b5ff1b31 bellard
    case 34: /* CM_VOLTAGE_CTL2 */
204 b5ff1b31 bellard
    case 35: /* CM_VOLTAGE_CTL3 */
205 b5ff1b31 bellard
        /* ??? Voltage control unimplemented.  */
206 b5ff1b31 bellard
        break;
207 b5ff1b31 bellard
    default:
208 b5ff1b31 bellard
        cpu_abort (cpu_single_env,
209 4d1165fa pbrook
            "integratorcm_write: Unimplemented offset 0x%x\n", (int)offset);
210 b5ff1b31 bellard
        break;
211 b5ff1b31 bellard
    }
212 b5ff1b31 bellard
}
213 b5ff1b31 bellard
214 b5ff1b31 bellard
/* Integrator/CM control registers.  */
215 b5ff1b31 bellard
216 b5ff1b31 bellard
static CPUReadMemoryFunc *integratorcm_readfn[] = {
217 b5ff1b31 bellard
   integratorcm_read,
218 b5ff1b31 bellard
   integratorcm_read,
219 b5ff1b31 bellard
   integratorcm_read
220 b5ff1b31 bellard
};
221 b5ff1b31 bellard
222 b5ff1b31 bellard
static CPUWriteMemoryFunc *integratorcm_writefn[] = {
223 b5ff1b31 bellard
   integratorcm_write,
224 b5ff1b31 bellard
   integratorcm_write,
225 b5ff1b31 bellard
   integratorcm_write
226 b5ff1b31 bellard
};
227 b5ff1b31 bellard
228 7fb4fdcf balrog
static void integratorcm_init(int memsz)
229 b5ff1b31 bellard
{
230 b5ff1b31 bellard
    int iomemtype;
231 b5ff1b31 bellard
    integratorcm_state *s;
232 b5ff1b31 bellard
233 b5ff1b31 bellard
    s = (integratorcm_state *)qemu_mallocz(sizeof(integratorcm_state));
234 b5ff1b31 bellard
    s->cm_osc = 0x01000048;
235 b5ff1b31 bellard
    /* ??? What should the high bits of this value be?  */
236 b5ff1b31 bellard
    s->cm_auxosc = 0x0007feff;
237 b5ff1b31 bellard
    s->cm_sdram = 0x00011122;
238 b5ff1b31 bellard
    if (memsz >= 256) {
239 b5ff1b31 bellard
        integrator_spd[31] = 64;
240 b5ff1b31 bellard
        s->cm_sdram |= 0x10;
241 b5ff1b31 bellard
    } else if (memsz >= 128) {
242 b5ff1b31 bellard
        integrator_spd[31] = 32;
243 b5ff1b31 bellard
        s->cm_sdram |= 0x0c;
244 b5ff1b31 bellard
    } else if (memsz >= 64) {
245 b5ff1b31 bellard
        integrator_spd[31] = 16;
246 b5ff1b31 bellard
        s->cm_sdram |= 0x08;
247 b5ff1b31 bellard
    } else if (memsz >= 32) {
248 b5ff1b31 bellard
        integrator_spd[31] = 4;
249 b5ff1b31 bellard
        s->cm_sdram |= 0x04;
250 b5ff1b31 bellard
    } else {
251 b5ff1b31 bellard
        integrator_spd[31] = 2;
252 b5ff1b31 bellard
    }
253 b5ff1b31 bellard
    memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
254 b5ff1b31 bellard
    s->cm_init = 0x00000112;
255 7fb4fdcf balrog
    s->flash_offset = qemu_ram_alloc(0x100000);
256 b5ff1b31 bellard
257 b5ff1b31 bellard
    iomemtype = cpu_register_io_memory(0, integratorcm_readfn,
258 b5ff1b31 bellard
                                       integratorcm_writefn, s);
259 187337f8 pbrook
    cpu_register_physical_memory(0x10000000, 0x00800000, iomemtype);
260 b5ff1b31 bellard
    integratorcm_do_remap(s, 1);
261 b5ff1b31 bellard
    /* ??? Save/restore.  */
262 b5ff1b31 bellard
}
263 b5ff1b31 bellard
264 b5ff1b31 bellard
/* Integrator/CP hardware emulation.  */
265 b5ff1b31 bellard
/* Primary interrupt controller.  */
266 b5ff1b31 bellard
267 b5ff1b31 bellard
typedef struct icp_pic_state
268 b5ff1b31 bellard
{
269 b5ff1b31 bellard
  uint32_t level;
270 b5ff1b31 bellard
  uint32_t irq_enabled;
271 b5ff1b31 bellard
  uint32_t fiq_enabled;
272 d537cf6c pbrook
  qemu_irq parent_irq;
273 d537cf6c pbrook
  qemu_irq parent_fiq;
274 b5ff1b31 bellard
} icp_pic_state;
275 b5ff1b31 bellard
276 b5ff1b31 bellard
static void icp_pic_update(icp_pic_state *s)
277 b5ff1b31 bellard
{
278 cdbdb648 pbrook
    uint32_t flags;
279 b5ff1b31 bellard
280 d537cf6c pbrook
    flags = (s->level & s->irq_enabled);
281 d537cf6c pbrook
    qemu_set_irq(s->parent_irq, flags != 0);
282 d537cf6c pbrook
    flags = (s->level & s->fiq_enabled);
283 d537cf6c pbrook
    qemu_set_irq(s->parent_fiq, flags != 0);
284 b5ff1b31 bellard
}
285 b5ff1b31 bellard
286 cdbdb648 pbrook
static void icp_pic_set_irq(void *opaque, int irq, int level)
287 b5ff1b31 bellard
{
288 80337b66 bellard
    icp_pic_state *s = (icp_pic_state *)opaque;
289 b5ff1b31 bellard
    if (level)
290 80337b66 bellard
        s->level |= 1 << irq;
291 b5ff1b31 bellard
    else
292 80337b66 bellard
        s->level &= ~(1 << irq);
293 b5ff1b31 bellard
    icp_pic_update(s);
294 b5ff1b31 bellard
}
295 b5ff1b31 bellard
296 b5ff1b31 bellard
static uint32_t icp_pic_read(void *opaque, target_phys_addr_t offset)
297 b5ff1b31 bellard
{
298 b5ff1b31 bellard
    icp_pic_state *s = (icp_pic_state *)opaque;
299 b5ff1b31 bellard
300 b5ff1b31 bellard
    switch (offset >> 2) {
301 b5ff1b31 bellard
    case 0: /* IRQ_STATUS */
302 b5ff1b31 bellard
        return s->level & s->irq_enabled;
303 b5ff1b31 bellard
    case 1: /* IRQ_RAWSTAT */
304 b5ff1b31 bellard
        return s->level;
305 b5ff1b31 bellard
    case 2: /* IRQ_ENABLESET */
306 b5ff1b31 bellard
        return s->irq_enabled;
307 b5ff1b31 bellard
    case 4: /* INT_SOFTSET */
308 b5ff1b31 bellard
        return s->level & 1;
309 b5ff1b31 bellard
    case 8: /* FRQ_STATUS */
310 b5ff1b31 bellard
        return s->level & s->fiq_enabled;
311 b5ff1b31 bellard
    case 9: /* FRQ_RAWSTAT */
312 b5ff1b31 bellard
        return s->level;
313 b5ff1b31 bellard
    case 10: /* FRQ_ENABLESET */
314 b5ff1b31 bellard
        return s->fiq_enabled;
315 b5ff1b31 bellard
    case 3: /* IRQ_ENABLECLR */
316 b5ff1b31 bellard
    case 5: /* INT_SOFTCLR */
317 b5ff1b31 bellard
    case 11: /* FRQ_ENABLECLR */
318 b5ff1b31 bellard
    default:
319 29bfb117 pbrook
        printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
320 b5ff1b31 bellard
        return 0;
321 b5ff1b31 bellard
    }
322 b5ff1b31 bellard
}
323 b5ff1b31 bellard
324 b5ff1b31 bellard
static void icp_pic_write(void *opaque, target_phys_addr_t offset,
325 b5ff1b31 bellard
                          uint32_t value)
326 b5ff1b31 bellard
{
327 b5ff1b31 bellard
    icp_pic_state *s = (icp_pic_state *)opaque;
328 b5ff1b31 bellard
329 b5ff1b31 bellard
    switch (offset >> 2) {
330 b5ff1b31 bellard
    case 2: /* IRQ_ENABLESET */
331 b5ff1b31 bellard
        s->irq_enabled |= value;
332 b5ff1b31 bellard
        break;
333 b5ff1b31 bellard
    case 3: /* IRQ_ENABLECLR */
334 b5ff1b31 bellard
        s->irq_enabled &= ~value;
335 b5ff1b31 bellard
        break;
336 b5ff1b31 bellard
    case 4: /* INT_SOFTSET */
337 b5ff1b31 bellard
        if (value & 1)
338 d537cf6c pbrook
            icp_pic_set_irq(s, 0, 1);
339 b5ff1b31 bellard
        break;
340 b5ff1b31 bellard
    case 5: /* INT_SOFTCLR */
341 b5ff1b31 bellard
        if (value & 1)
342 d537cf6c pbrook
            icp_pic_set_irq(s, 0, 0);
343 b5ff1b31 bellard
        break;
344 b5ff1b31 bellard
    case 10: /* FRQ_ENABLESET */
345 b5ff1b31 bellard
        s->fiq_enabled |= value;
346 b5ff1b31 bellard
        break;
347 b5ff1b31 bellard
    case 11: /* FRQ_ENABLECLR */
348 b5ff1b31 bellard
        s->fiq_enabled &= ~value;
349 b5ff1b31 bellard
        break;
350 b5ff1b31 bellard
    case 0: /* IRQ_STATUS */
351 b5ff1b31 bellard
    case 1: /* IRQ_RAWSTAT */
352 b5ff1b31 bellard
    case 8: /* FRQ_STATUS */
353 b5ff1b31 bellard
    case 9: /* FRQ_RAWSTAT */
354 b5ff1b31 bellard
    default:
355 29bfb117 pbrook
        printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
356 b5ff1b31 bellard
        return;
357 b5ff1b31 bellard
    }
358 b5ff1b31 bellard
    icp_pic_update(s);
359 b5ff1b31 bellard
}
360 b5ff1b31 bellard
361 b5ff1b31 bellard
static CPUReadMemoryFunc *icp_pic_readfn[] = {
362 b5ff1b31 bellard
   icp_pic_read,
363 b5ff1b31 bellard
   icp_pic_read,
364 b5ff1b31 bellard
   icp_pic_read
365 b5ff1b31 bellard
};
366 b5ff1b31 bellard
367 b5ff1b31 bellard
static CPUWriteMemoryFunc *icp_pic_writefn[] = {
368 b5ff1b31 bellard
   icp_pic_write,
369 b5ff1b31 bellard
   icp_pic_write,
370 b5ff1b31 bellard
   icp_pic_write
371 b5ff1b31 bellard
};
372 b5ff1b31 bellard
373 d537cf6c pbrook
static qemu_irq *icp_pic_init(uint32_t base,
374 d537cf6c pbrook
                              qemu_irq parent_irq, qemu_irq parent_fiq)
375 b5ff1b31 bellard
{
376 b5ff1b31 bellard
    icp_pic_state *s;
377 b5ff1b31 bellard
    int iomemtype;
378 d537cf6c pbrook
    qemu_irq *qi;
379 b5ff1b31 bellard
380 b5ff1b31 bellard
    s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));
381 b5ff1b31 bellard
    if (!s)
382 b5ff1b31 bellard
        return NULL;
383 d537cf6c pbrook
    qi = qemu_allocate_irqs(icp_pic_set_irq, s, 32);
384 b5ff1b31 bellard
    s->parent_irq = parent_irq;
385 cdbdb648 pbrook
    s->parent_fiq = parent_fiq;
386 b5ff1b31 bellard
    iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
387 b5ff1b31 bellard
                                       icp_pic_writefn, s);
388 187337f8 pbrook
    cpu_register_physical_memory(base, 0x00800000, iomemtype);
389 b5ff1b31 bellard
    /* ??? Save/restore.  */
390 d537cf6c pbrook
    return qi;
391 b5ff1b31 bellard
}
392 b5ff1b31 bellard
393 b5ff1b31 bellard
/* CP control registers.  */
394 b5ff1b31 bellard
static uint32_t icp_control_read(void *opaque, target_phys_addr_t offset)
395 b5ff1b31 bellard
{
396 b5ff1b31 bellard
    switch (offset >> 2) {
397 b5ff1b31 bellard
    case 0: /* CP_IDFIELD */
398 b5ff1b31 bellard
        return 0x41034003;
399 b5ff1b31 bellard
    case 1: /* CP_FLASHPROG */
400 b5ff1b31 bellard
        return 0;
401 b5ff1b31 bellard
    case 2: /* CP_INTREG */
402 b5ff1b31 bellard
        return 0;
403 b5ff1b31 bellard
    case 3: /* CP_DECODE */
404 b5ff1b31 bellard
        return 0x11;
405 b5ff1b31 bellard
    default:
406 4d1165fa pbrook
        cpu_abort (cpu_single_env, "icp_control_read: Bad offset %x\n",
407 4d1165fa pbrook
                   (int)offset);
408 b5ff1b31 bellard
        return 0;
409 b5ff1b31 bellard
    }
410 b5ff1b31 bellard
}
411 b5ff1b31 bellard
412 b5ff1b31 bellard
static void icp_control_write(void *opaque, target_phys_addr_t offset,
413 b5ff1b31 bellard
                          uint32_t value)
414 b5ff1b31 bellard
{
415 b5ff1b31 bellard
    switch (offset >> 2) {
416 b5ff1b31 bellard
    case 1: /* CP_FLASHPROG */
417 b5ff1b31 bellard
    case 2: /* CP_INTREG */
418 b5ff1b31 bellard
    case 3: /* CP_DECODE */
419 b5ff1b31 bellard
        /* Nothing interesting implemented yet.  */
420 b5ff1b31 bellard
        break;
421 b5ff1b31 bellard
    default:
422 4d1165fa pbrook
        cpu_abort (cpu_single_env, "icp_control_write: Bad offset %x\n",
423 4d1165fa pbrook
                   (int)offset);
424 b5ff1b31 bellard
    }
425 b5ff1b31 bellard
}
426 b5ff1b31 bellard
static CPUReadMemoryFunc *icp_control_readfn[] = {
427 b5ff1b31 bellard
   icp_control_read,
428 b5ff1b31 bellard
   icp_control_read,
429 b5ff1b31 bellard
   icp_control_read
430 b5ff1b31 bellard
};
431 b5ff1b31 bellard
432 b5ff1b31 bellard
static CPUWriteMemoryFunc *icp_control_writefn[] = {
433 b5ff1b31 bellard
   icp_control_write,
434 b5ff1b31 bellard
   icp_control_write,
435 b5ff1b31 bellard
   icp_control_write
436 b5ff1b31 bellard
};
437 b5ff1b31 bellard
438 b5ff1b31 bellard
static void icp_control_init(uint32_t base)
439 b5ff1b31 bellard
{
440 b5ff1b31 bellard
    int iomemtype;
441 b5ff1b31 bellard
442 b5ff1b31 bellard
    iomemtype = cpu_register_io_memory(0, icp_control_readfn,
443 8da3ff18 pbrook
                                       icp_control_writefn, NULL);
444 187337f8 pbrook
    cpu_register_physical_memory(base, 0x00800000, iomemtype);
445 b5ff1b31 bellard
    /* ??? Save/restore.  */
446 b5ff1b31 bellard
}
447 b5ff1b31 bellard
448 b5ff1b31 bellard
449 b5ff1b31 bellard
/* Board init.  */
450 b5ff1b31 bellard
451 f93eb9ff balrog
static struct arm_boot_info integrator_binfo = {
452 f93eb9ff balrog
    .loader_start = 0x0,
453 f93eb9ff balrog
    .board_id = 0x113,
454 f93eb9ff balrog
};
455 f93eb9ff balrog
456 00f82b8a aurel32
static void integratorcp_init(ram_addr_t ram_size, int vga_ram_size,
457 6ac0e82d balrog
                     const char *boot_device, DisplayState *ds,
458 b5ff1b31 bellard
                     const char *kernel_filename, const char *kernel_cmdline,
459 3371d272 pbrook
                     const char *initrd_filename, const char *cpu_model)
460 b5ff1b31 bellard
{
461 b5ff1b31 bellard
    CPUState *env;
462 7fb4fdcf balrog
    uint32_t ram_offset;
463 d537cf6c pbrook
    qemu_irq *pic;
464 d537cf6c pbrook
    qemu_irq *cpu_pic;
465 e4bcb14c ths
    int sd;
466 b5ff1b31 bellard
467 3371d272 pbrook
    if (!cpu_model)
468 3371d272 pbrook
        cpu_model = "arm926";
469 aaed909a bellard
    env = cpu_init(cpu_model);
470 aaed909a bellard
    if (!env) {
471 aaed909a bellard
        fprintf(stderr, "Unable to find CPU definition\n");
472 aaed909a bellard
        exit(1);
473 aaed909a bellard
    }
474 7fb4fdcf balrog
    ram_offset = qemu_ram_alloc(ram_size);
475 b5ff1b31 bellard
    /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
476 1235fc06 ths
    /* ??? RAM should repeat to fill physical memory space.  */
477 b5ff1b31 bellard
    /* SDRAM at address zero*/
478 7fb4fdcf balrog
    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
479 b5ff1b31 bellard
    /* And again at address 0x80000000 */
480 7fb4fdcf balrog
    cpu_register_physical_memory(0x80000000, ram_size, ram_offset | IO_MEM_RAM);
481 b5ff1b31 bellard
482 7fb4fdcf balrog
    integratorcm_init(ram_size >> 20);
483 cdbdb648 pbrook
    cpu_pic = arm_pic_init_cpu(env);
484 d537cf6c pbrook
    pic = icp_pic_init(0x14000000, cpu_pic[ARM_PIC_CPU_IRQ],
485 d537cf6c pbrook
                       cpu_pic[ARM_PIC_CPU_FIQ]);
486 d537cf6c pbrook
    icp_pic_init(0xca000000, pic[26], NULL);
487 cdbdb648 pbrook
    icp_pit_init(0x13000000, pic, 5);
488 7e1543c2 pbrook
    pl031_init(0x15000000, pic[8]);
489 9ee6e8bb pbrook
    pl011_init(0x16000000, pic[1], serial_hds[0], PL011_ARM);
490 9ee6e8bb pbrook
    pl011_init(0x17000000, pic[2], serial_hds[1], PL011_ARM);
491 b5ff1b31 bellard
    icp_control_init(0xcb000000);
492 d537cf6c pbrook
    pl050_init(0x18000000, pic[3], 0);
493 d537cf6c pbrook
    pl050_init(0x19000000, pic[4], 1);
494 e4bcb14c ths
    sd = drive_get_index(IF_SD, 0, 0);
495 e4bcb14c ths
    if (sd == -1) {
496 e4bcb14c ths
        fprintf(stderr, "qemu: missing SecureDigital card\n");
497 e4bcb14c ths
        exit(1);
498 e4bcb14c ths
    }
499 e4bcb14c ths
    pl181_init(0x1c000000, drives_table[sd].bdrv, pic[23], pic[24]);
500 a41b2ff2 pbrook
    if (nd_table[0].vlan) {
501 a41b2ff2 pbrook
        if (nd_table[0].model == NULL
502 a41b2ff2 pbrook
            || strcmp(nd_table[0].model, "smc91c111") == 0) {
503 d537cf6c pbrook
            smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
504 c4a7060c blueswir1
        } else if (strcmp(nd_table[0].model, "?") == 0) {
505 c4a7060c blueswir1
            fprintf(stderr, "qemu: Supported NICs: smc91c111\n");
506 c4a7060c blueswir1
            exit (1);
507 a41b2ff2 pbrook
        } else {
508 a41b2ff2 pbrook
            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
509 a41b2ff2 pbrook
            exit (1);
510 a41b2ff2 pbrook
        }
511 a41b2ff2 pbrook
    }
512 d537cf6c pbrook
    pl110_init(ds, 0xc0000000, pic[22], 0);
513 b5ff1b31 bellard
514 f93eb9ff balrog
    integrator_binfo.ram_size = ram_size;
515 f93eb9ff balrog
    integrator_binfo.kernel_filename = kernel_filename;
516 f93eb9ff balrog
    integrator_binfo.kernel_cmdline = kernel_cmdline;
517 f93eb9ff balrog
    integrator_binfo.initrd_filename = initrd_filename;
518 f93eb9ff balrog
    arm_load_kernel(env, &integrator_binfo);
519 b5ff1b31 bellard
}
520 b5ff1b31 bellard
521 3371d272 pbrook
QEMUMachine integratorcp_machine = {
522 4b32e168 aliguori
    .name = "integratorcp",
523 4b32e168 aliguori
    .desc = "ARM Integrator/CP (ARM926EJ-S)",
524 4b32e168 aliguori
    .init = integratorcp_init,
525 4b32e168 aliguori
    .ram_require = 0x100000,
526 b5ff1b31 bellard
};