Statistics
| Branch: | Revision:

root / hw / versatilepb.c @ 0986ac3b

History | View | Annotate | Download (12.6 kB)

1 cdbdb648 pbrook
/* 
2 16406950 pbrook
 * ARM Versatile Platform/Application Baseboard System emulation.
3 cdbdb648 pbrook
 *
4 cdbdb648 pbrook
 * Copyright (c) 2005-2006 CodeSourcery.
5 cdbdb648 pbrook
 * Written by Paul Brook
6 cdbdb648 pbrook
 *
7 cdbdb648 pbrook
 * This code is licenced under the GPL.
8 cdbdb648 pbrook
 */
9 cdbdb648 pbrook
10 cdbdb648 pbrook
#include "vl.h"
11 cdbdb648 pbrook
#include "arm_pic.h"
12 cdbdb648 pbrook
13 502a5395 pbrook
#define LOCK_VALUE 0xa05f
14 502a5395 pbrook
15 cdbdb648 pbrook
/* Primary interrupt controller.  */
16 cdbdb648 pbrook
17 cdbdb648 pbrook
typedef struct vpb_sic_state
18 cdbdb648 pbrook
{
19 cdbdb648 pbrook
  arm_pic_handler handler;
20 cdbdb648 pbrook
  uint32_t base;
21 cdbdb648 pbrook
  uint32_t level;
22 cdbdb648 pbrook
  uint32_t mask;
23 cdbdb648 pbrook
  uint32_t pic_enable;
24 cdbdb648 pbrook
  void *parent;
25 cdbdb648 pbrook
  int irq;
26 cdbdb648 pbrook
} vpb_sic_state;
27 cdbdb648 pbrook
28 cdbdb648 pbrook
static void vpb_sic_update(vpb_sic_state *s)
29 cdbdb648 pbrook
{
30 cdbdb648 pbrook
    uint32_t flags;
31 cdbdb648 pbrook
32 cdbdb648 pbrook
    flags = s->level & s->mask;
33 cdbdb648 pbrook
    pic_set_irq_new(s->parent, s->irq, flags != 0);
34 cdbdb648 pbrook
}
35 cdbdb648 pbrook
36 cdbdb648 pbrook
static void vpb_sic_update_pic(vpb_sic_state *s)
37 cdbdb648 pbrook
{
38 cdbdb648 pbrook
    int i;
39 cdbdb648 pbrook
    uint32_t mask;
40 cdbdb648 pbrook
41 cdbdb648 pbrook
    for (i = 21; i <= 30; i++) {
42 cdbdb648 pbrook
        mask = 1u << i;
43 cdbdb648 pbrook
        if (!(s->pic_enable & mask))
44 cdbdb648 pbrook
            continue;
45 cdbdb648 pbrook
        pic_set_irq_new(s->parent, i, (s->level & mask) != 0);
46 cdbdb648 pbrook
    }
47 cdbdb648 pbrook
}
48 cdbdb648 pbrook
49 cdbdb648 pbrook
static void vpb_sic_set_irq(void *opaque, int irq, int level)
50 cdbdb648 pbrook
{
51 cdbdb648 pbrook
    vpb_sic_state *s = (vpb_sic_state *)opaque;
52 cdbdb648 pbrook
    if (level)
53 cdbdb648 pbrook
        s->level |= 1u << irq;
54 cdbdb648 pbrook
    else
55 cdbdb648 pbrook
        s->level &= ~(1u << irq);
56 cdbdb648 pbrook
    if (s->pic_enable & (1u << irq))
57 cdbdb648 pbrook
        pic_set_irq_new(s->parent, irq, level);
58 cdbdb648 pbrook
    vpb_sic_update(s);
59 cdbdb648 pbrook
}
60 cdbdb648 pbrook
61 cdbdb648 pbrook
static uint32_t vpb_sic_read(void *opaque, target_phys_addr_t offset)
62 cdbdb648 pbrook
{
63 cdbdb648 pbrook
    vpb_sic_state *s = (vpb_sic_state *)opaque;
64 cdbdb648 pbrook
65 cdbdb648 pbrook
    offset -= s->base;
66 cdbdb648 pbrook
    switch (offset >> 2) {
67 cdbdb648 pbrook
    case 0: /* STATUS */
68 cdbdb648 pbrook
        return s->level & s->mask;
69 cdbdb648 pbrook
    case 1: /* RAWSTAT */
70 cdbdb648 pbrook
        return s->level;
71 cdbdb648 pbrook
    case 2: /* ENABLE */
72 cdbdb648 pbrook
        return s->mask;
73 cdbdb648 pbrook
    case 4: /* SOFTINT */
74 cdbdb648 pbrook
        return s->level & 1;
75 cdbdb648 pbrook
    case 8: /* PICENABLE */
76 cdbdb648 pbrook
        return s->pic_enable;
77 cdbdb648 pbrook
    default:
78 cdbdb648 pbrook
        printf ("vpb_sic_read: Bad register offset 0x%x\n", offset);
79 cdbdb648 pbrook
        return 0;
80 cdbdb648 pbrook
    }
81 cdbdb648 pbrook
}
82 cdbdb648 pbrook
83 cdbdb648 pbrook
static void vpb_sic_write(void *opaque, target_phys_addr_t offset,
84 cdbdb648 pbrook
                          uint32_t value)
85 cdbdb648 pbrook
{
86 cdbdb648 pbrook
    vpb_sic_state *s = (vpb_sic_state *)opaque;
87 cdbdb648 pbrook
    offset -= s->base;
88 cdbdb648 pbrook
89 cdbdb648 pbrook
    switch (offset >> 2) {
90 cdbdb648 pbrook
    case 2: /* ENSET */
91 cdbdb648 pbrook
        s->mask |= value;
92 cdbdb648 pbrook
        break;
93 cdbdb648 pbrook
    case 3: /* ENCLR */
94 cdbdb648 pbrook
        s->mask &= ~value;
95 cdbdb648 pbrook
        break;
96 cdbdb648 pbrook
    case 4: /* SOFTINTSET */
97 cdbdb648 pbrook
        if (value)
98 cdbdb648 pbrook
            s->mask |= 1;
99 cdbdb648 pbrook
        break;
100 cdbdb648 pbrook
    case 5: /* SOFTINTCLR */
101 cdbdb648 pbrook
        if (value)
102 cdbdb648 pbrook
            s->mask &= ~1u;
103 cdbdb648 pbrook
        break;
104 cdbdb648 pbrook
    case 8: /* PICENSET */
105 cdbdb648 pbrook
        s->pic_enable |= (value & 0x7fe00000);
106 cdbdb648 pbrook
        vpb_sic_update_pic(s);
107 cdbdb648 pbrook
        break;
108 cdbdb648 pbrook
    case 9: /* PICENCLR */
109 cdbdb648 pbrook
        s->pic_enable &= ~value;
110 cdbdb648 pbrook
        vpb_sic_update_pic(s);
111 cdbdb648 pbrook
        break;
112 cdbdb648 pbrook
    default:
113 cdbdb648 pbrook
        printf ("vpb_sic_write: Bad register offset 0x%x\n", offset);
114 cdbdb648 pbrook
        return;
115 cdbdb648 pbrook
    }
116 cdbdb648 pbrook
    vpb_sic_update(s);
117 cdbdb648 pbrook
}
118 cdbdb648 pbrook
119 cdbdb648 pbrook
static CPUReadMemoryFunc *vpb_sic_readfn[] = {
120 cdbdb648 pbrook
   vpb_sic_read,
121 cdbdb648 pbrook
   vpb_sic_read,
122 cdbdb648 pbrook
   vpb_sic_read
123 cdbdb648 pbrook
};
124 cdbdb648 pbrook
125 cdbdb648 pbrook
static CPUWriteMemoryFunc *vpb_sic_writefn[] = {
126 cdbdb648 pbrook
   vpb_sic_write,
127 cdbdb648 pbrook
   vpb_sic_write,
128 cdbdb648 pbrook
   vpb_sic_write
129 cdbdb648 pbrook
};
130 cdbdb648 pbrook
131 cdbdb648 pbrook
static vpb_sic_state *vpb_sic_init(uint32_t base, void *parent, int irq)
132 cdbdb648 pbrook
{
133 cdbdb648 pbrook
    vpb_sic_state *s;
134 cdbdb648 pbrook
    int iomemtype;
135 cdbdb648 pbrook
136 cdbdb648 pbrook
    s = (vpb_sic_state *)qemu_mallocz(sizeof(vpb_sic_state));
137 cdbdb648 pbrook
    if (!s)
138 cdbdb648 pbrook
        return NULL;
139 cdbdb648 pbrook
    s->handler = vpb_sic_set_irq;
140 cdbdb648 pbrook
    s->base = base;
141 cdbdb648 pbrook
    s->parent = parent;
142 cdbdb648 pbrook
    s->irq = irq;
143 cdbdb648 pbrook
    iomemtype = cpu_register_io_memory(0, vpb_sic_readfn,
144 cdbdb648 pbrook
                                       vpb_sic_writefn, s);
145 cdbdb648 pbrook
    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
146 cdbdb648 pbrook
    /* ??? Save/restore.  */
147 cdbdb648 pbrook
    return s;
148 cdbdb648 pbrook
}
149 cdbdb648 pbrook
150 502a5395 pbrook
/* System controller.  */
151 502a5395 pbrook
152 502a5395 pbrook
typedef struct {
153 502a5395 pbrook
    uint32_t base;
154 502a5395 pbrook
    uint32_t leds;
155 502a5395 pbrook
    uint16_t lockval;
156 502a5395 pbrook
    uint32_t cfgdata1;
157 502a5395 pbrook
    uint32_t cfgdata2;
158 502a5395 pbrook
    uint32_t flags;
159 502a5395 pbrook
    uint32_t nvflags;
160 502a5395 pbrook
    uint32_t resetlevel;
161 502a5395 pbrook
} vpb_sys_state;
162 502a5395 pbrook
163 502a5395 pbrook
static uint32_t vpb_sys_read(void *opaque, target_phys_addr_t offset)
164 502a5395 pbrook
{
165 502a5395 pbrook
    vpb_sys_state *s = (vpb_sys_state *)opaque;
166 502a5395 pbrook
167 502a5395 pbrook
    offset -= s->base;
168 502a5395 pbrook
    switch (offset) {
169 502a5395 pbrook
    case 0x00: /* ID */
170 502a5395 pbrook
        return 0x41007004;
171 502a5395 pbrook
    case 0x04: /* SW */
172 502a5395 pbrook
        /* General purpose hardware switches.
173 502a5395 pbrook
           We don't have a useful way of exposing these to the user.  */
174 502a5395 pbrook
        return 0;
175 502a5395 pbrook
    case 0x08: /* LED */
176 502a5395 pbrook
        return s->leds;
177 502a5395 pbrook
    case 0x20: /* LOCK */
178 502a5395 pbrook
        return s->lockval;
179 502a5395 pbrook
    case 0x0c: /* OSC0 */
180 502a5395 pbrook
    case 0x10: /* OSC1 */
181 502a5395 pbrook
    case 0x14: /* OSC2 */
182 502a5395 pbrook
    case 0x18: /* OSC3 */
183 502a5395 pbrook
    case 0x1c: /* OSC4 */
184 502a5395 pbrook
    case 0x24: /* 100HZ */
185 502a5395 pbrook
        /* ??? Implement these.  */
186 502a5395 pbrook
        return 0;
187 502a5395 pbrook
    case 0x28: /* CFGDATA1 */
188 502a5395 pbrook
        return s->cfgdata1;
189 502a5395 pbrook
    case 0x2c: /* CFGDATA2 */
190 502a5395 pbrook
        return s->cfgdata2;
191 502a5395 pbrook
    case 0x30: /* FLAGS */
192 502a5395 pbrook
        return s->flags;
193 502a5395 pbrook
    case 0x38: /* NVFLAGS */
194 502a5395 pbrook
        return s->nvflags;
195 502a5395 pbrook
    case 0x40: /* RESETCTL */
196 502a5395 pbrook
        return s->resetlevel;
197 502a5395 pbrook
    case 0x44: /* PCICTL */
198 502a5395 pbrook
        return 1;
199 502a5395 pbrook
    case 0x48: /* MCI */
200 502a5395 pbrook
        return 0;
201 502a5395 pbrook
    case 0x4c: /* FLASH */
202 502a5395 pbrook
        return 0;
203 502a5395 pbrook
    case 0x50: /* CLCD */
204 502a5395 pbrook
        return 0x1000;
205 502a5395 pbrook
    case 0x54: /* CLCDSER */
206 502a5395 pbrook
        return 0;
207 502a5395 pbrook
    case 0x58: /* BOOTCS */
208 502a5395 pbrook
        return 0;
209 502a5395 pbrook
    case 0x5c: /* 24MHz */
210 502a5395 pbrook
        /* ??? not implemented.  */
211 502a5395 pbrook
        return 0;
212 502a5395 pbrook
    case 0x60: /* MISC */
213 502a5395 pbrook
        return 0;
214 502a5395 pbrook
    case 0x64: /* DMAPSR0 */
215 502a5395 pbrook
    case 0x68: /* DMAPSR1 */
216 502a5395 pbrook
    case 0x6c: /* DMAPSR2 */
217 502a5395 pbrook
    case 0x8c: /* OSCRESET0 */
218 502a5395 pbrook
    case 0x90: /* OSCRESET1 */
219 502a5395 pbrook
    case 0x94: /* OSCRESET2 */
220 502a5395 pbrook
    case 0x98: /* OSCRESET3 */
221 502a5395 pbrook
    case 0x9c: /* OSCRESET4 */
222 502a5395 pbrook
    case 0xc0: /* SYS_TEST_OSC0 */
223 502a5395 pbrook
    case 0xc4: /* SYS_TEST_OSC1 */
224 502a5395 pbrook
    case 0xc8: /* SYS_TEST_OSC2 */
225 502a5395 pbrook
    case 0xcc: /* SYS_TEST_OSC3 */
226 502a5395 pbrook
    case 0xd0: /* SYS_TEST_OSC4 */
227 502a5395 pbrook
        return 0;
228 502a5395 pbrook
    default:
229 502a5395 pbrook
        printf ("vpb_sys_read: Bad register offset 0x%x\n", offset);
230 502a5395 pbrook
        return 0;
231 502a5395 pbrook
    }
232 502a5395 pbrook
}
233 502a5395 pbrook
234 502a5395 pbrook
static void vpb_sys_write(void *opaque, target_phys_addr_t offset,
235 502a5395 pbrook
                          uint32_t val)
236 502a5395 pbrook
{
237 502a5395 pbrook
    vpb_sys_state *s = (vpb_sys_state *)opaque;
238 502a5395 pbrook
    offset -= s->base;
239 502a5395 pbrook
240 502a5395 pbrook
    switch (offset) {
241 502a5395 pbrook
    case 0x08: /* LED */
242 502a5395 pbrook
        s->leds = val;
243 502a5395 pbrook
    case 0x0c: /* OSC0 */
244 502a5395 pbrook
    case 0x10: /* OSC1 */
245 502a5395 pbrook
    case 0x14: /* OSC2 */
246 502a5395 pbrook
    case 0x18: /* OSC3 */
247 502a5395 pbrook
    case 0x1c: /* OSC4 */
248 502a5395 pbrook
        /* ??? */
249 502a5395 pbrook
        break;
250 502a5395 pbrook
    case 0x20: /* LOCK */
251 502a5395 pbrook
        if (val == LOCK_VALUE)
252 502a5395 pbrook
            s->lockval = val;
253 502a5395 pbrook
        else
254 502a5395 pbrook
            s->lockval = val & 0x7fff;
255 502a5395 pbrook
        break;
256 502a5395 pbrook
    case 0x28: /* CFGDATA1 */
257 502a5395 pbrook
        /* ??? Need to implement this.  */
258 502a5395 pbrook
        s->cfgdata1 = val;
259 502a5395 pbrook
        break;
260 502a5395 pbrook
    case 0x2c: /* CFGDATA2 */
261 502a5395 pbrook
        /* ??? Need to implement this.  */
262 502a5395 pbrook
        s->cfgdata2 = val;
263 502a5395 pbrook
        break;
264 502a5395 pbrook
    case 0x30: /* FLAGSSET */
265 502a5395 pbrook
        s->flags |= val;
266 502a5395 pbrook
        break;
267 502a5395 pbrook
    case 0x34: /* FLAGSCLR */
268 502a5395 pbrook
        s->flags &= ~val;
269 502a5395 pbrook
        break;
270 502a5395 pbrook
    case 0x38: /* NVFLAGSSET */
271 502a5395 pbrook
        s->nvflags |= val;
272 502a5395 pbrook
        break;
273 502a5395 pbrook
    case 0x3c: /* NVFLAGSCLR */
274 502a5395 pbrook
        s->nvflags &= ~val;
275 502a5395 pbrook
        break;
276 502a5395 pbrook
    case 0x40: /* RESETCTL */
277 502a5395 pbrook
        if (s->lockval == LOCK_VALUE) {
278 502a5395 pbrook
            s->resetlevel = val;
279 502a5395 pbrook
            if (val & 0x100)
280 502a5395 pbrook
                cpu_abort(cpu_single_env, "Board reset\n");
281 502a5395 pbrook
        }
282 502a5395 pbrook
        break;
283 502a5395 pbrook
    case 0x44: /* PCICTL */
284 502a5395 pbrook
        /* nothing to do.  */
285 502a5395 pbrook
        break;
286 502a5395 pbrook
    case 0x4c: /* FLASH */
287 502a5395 pbrook
    case 0x50: /* CLCD */
288 502a5395 pbrook
    case 0x54: /* CLCDSER */
289 502a5395 pbrook
    case 0x64: /* DMAPSR0 */
290 502a5395 pbrook
    case 0x68: /* DMAPSR1 */
291 502a5395 pbrook
    case 0x6c: /* DMAPSR2 */
292 502a5395 pbrook
    case 0x8c: /* OSCRESET0 */
293 502a5395 pbrook
    case 0x90: /* OSCRESET1 */
294 502a5395 pbrook
    case 0x94: /* OSCRESET2 */
295 502a5395 pbrook
    case 0x98: /* OSCRESET3 */
296 502a5395 pbrook
    case 0x9c: /* OSCRESET4 */
297 502a5395 pbrook
        break;
298 502a5395 pbrook
    default:
299 502a5395 pbrook
        printf ("vpb_sys_write: Bad register offset 0x%x\n", offset);
300 502a5395 pbrook
        return;
301 502a5395 pbrook
    }
302 502a5395 pbrook
}
303 502a5395 pbrook
304 502a5395 pbrook
static CPUReadMemoryFunc *vpb_sys_readfn[] = {
305 502a5395 pbrook
   vpb_sys_read,
306 502a5395 pbrook
   vpb_sys_read,
307 502a5395 pbrook
   vpb_sys_read
308 502a5395 pbrook
};
309 502a5395 pbrook
310 502a5395 pbrook
static CPUWriteMemoryFunc *vpb_sys_writefn[] = {
311 502a5395 pbrook
   vpb_sys_write,
312 502a5395 pbrook
   vpb_sys_write,
313 502a5395 pbrook
   vpb_sys_write
314 502a5395 pbrook
};
315 502a5395 pbrook
316 502a5395 pbrook
static vpb_sys_state *vpb_sys_init(uint32_t base)
317 502a5395 pbrook
{
318 502a5395 pbrook
    vpb_sys_state *s;
319 502a5395 pbrook
    int iomemtype;
320 502a5395 pbrook
321 502a5395 pbrook
    s = (vpb_sys_state *)qemu_mallocz(sizeof(vpb_sys_state));
322 502a5395 pbrook
    if (!s)
323 502a5395 pbrook
        return NULL;
324 502a5395 pbrook
    s->base = base;
325 502a5395 pbrook
    iomemtype = cpu_register_io_memory(0, vpb_sys_readfn,
326 502a5395 pbrook
                                       vpb_sys_writefn, s);
327 502a5395 pbrook
    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
328 502a5395 pbrook
    /* ??? Save/restore.  */
329 502a5395 pbrook
    return s;
330 502a5395 pbrook
}
331 502a5395 pbrook
332 cdbdb648 pbrook
/* Board init.  */
333 cdbdb648 pbrook
334 16406950 pbrook
/* The AB and PB boards both use the same core, just with different
335 16406950 pbrook
   peripherans and expansion busses.  For now we emulate a subset of the
336 16406950 pbrook
   PB peripherals and just change the board ID.  */
337 cdbdb648 pbrook
338 16406950 pbrook
static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
339 cdbdb648 pbrook
                     DisplayState *ds, const char **fd_filename, int snapshot,
340 cdbdb648 pbrook
                     const char *kernel_filename, const char *kernel_cmdline,
341 16406950 pbrook
                     const char *initrd_filename, int board_id)
342 cdbdb648 pbrook
{
343 cdbdb648 pbrook
    CPUState *env;
344 cdbdb648 pbrook
    void *pic;
345 cdbdb648 pbrook
    void *sic;
346 7d8406be pbrook
    void *scsi_hba;
347 502a5395 pbrook
    PCIBus *pci_bus;
348 502a5395 pbrook
    NICInfo *nd;
349 502a5395 pbrook
    int n;
350 502a5395 pbrook
    int done_smc = 0;
351 cdbdb648 pbrook
352 cdbdb648 pbrook
    env = cpu_init();
353 cdbdb648 pbrook
    cpu_arm_set_model(env, ARM_CPUID_ARM926);
354 cdbdb648 pbrook
    /* ??? RAM shoud repeat to fill physical memory space.  */
355 cdbdb648 pbrook
    /* SDRAM at address zero.  */
356 cdbdb648 pbrook
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
357 cdbdb648 pbrook
358 502a5395 pbrook
    vpb_sys_init(0x10000000);
359 cdbdb648 pbrook
    pic = arm_pic_init_cpu(env);
360 cdbdb648 pbrook
    pic = pl190_init(0x10140000, pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
361 cdbdb648 pbrook
    sic = vpb_sic_init(0x10003000, pic, 31);
362 cdbdb648 pbrook
    pl050_init(0x10006000, sic, 3, 0);
363 cdbdb648 pbrook
    pl050_init(0x10007000, sic, 4, 1);
364 cdbdb648 pbrook
365 502a5395 pbrook
    pci_bus = pci_vpb_init(sic);
366 502a5395 pbrook
    /* The Versatile PCI bridge does not provide access to PCI IO space,
367 502a5395 pbrook
       so many of the qemu PCI devices are not useable.  */
368 502a5395 pbrook
    for(n = 0; n < nb_nics; n++) {
369 502a5395 pbrook
        nd = &nd_table[n];
370 502a5395 pbrook
        if (!nd->model)
371 502a5395 pbrook
            nd->model = done_smc ? "rtl8139" : "smc91c111";
372 502a5395 pbrook
        if (strcmp(nd->model, "smc91c111") == 0) {
373 502a5395 pbrook
            smc91c111_init(nd, 0x10010000, sic, 25);
374 cdbdb648 pbrook
        } else {
375 502a5395 pbrook
            pci_nic_init(pci_bus, nd);
376 cdbdb648 pbrook
        }
377 cdbdb648 pbrook
    }
378 0d92ed30 pbrook
    if (usb_enabled) {
379 0d92ed30 pbrook
        usb_ohci_init(pci_bus, 3, -1);
380 0d92ed30 pbrook
    }
381 7d8406be pbrook
    scsi_hba = lsi_scsi_init(pci_bus, -1);
382 7d8406be pbrook
    for (n = 0; n < MAX_DISKS; n++) {
383 7d8406be pbrook
        if (bs_table[n]) {
384 7d8406be pbrook
            lsi_scsi_attach(scsi_hba, bs_table[n], n);
385 7d8406be pbrook
        }
386 7d8406be pbrook
    }
387 cdbdb648 pbrook
388 cdbdb648 pbrook
    pl011_init(0x101f1000, pic, 12, serial_hds[0]);
389 cdbdb648 pbrook
    pl011_init(0x101f2000, pic, 13, serial_hds[1]);
390 cdbdb648 pbrook
    pl011_init(0x101f3000, pic, 14, serial_hds[2]);
391 cdbdb648 pbrook
    pl011_init(0x10009000, sic, 6, serial_hds[3]);
392 cdbdb648 pbrook
393 cdbdb648 pbrook
    pl080_init(0x10130000, pic, 17);
394 cdbdb648 pbrook
    sp804_init(0x101e2000, pic, 4);
395 cdbdb648 pbrook
    sp804_init(0x101e3000, pic, 5);
396 cdbdb648 pbrook
397 cdbdb648 pbrook
    /* The versatile/PB actually has a modified Color LCD controller
398 cdbdb648 pbrook
       that includes hardware cursor support from the PL111.  */
399 cdbdb648 pbrook
    pl110_init(ds, 0x10120000, pic, 16, 1);
400 cdbdb648 pbrook
401 16406950 pbrook
    /* Memory map for Versatile/PB:  */
402 cdbdb648 pbrook
    /* 0x10000000 System registers.  */
403 cdbdb648 pbrook
    /* 0x10001000 PCI controller config registers.  */
404 cdbdb648 pbrook
    /* 0x10002000 Serial bus interface.  */
405 cdbdb648 pbrook
    /*  0x10003000 Secondary interrupt controller.  */
406 cdbdb648 pbrook
    /* 0x10004000 AACI (audio).  */
407 cdbdb648 pbrook
    /* 0x10005000 MMCI0.  */
408 cdbdb648 pbrook
    /*  0x10006000 KMI0 (keyboard).  */
409 cdbdb648 pbrook
    /*  0x10007000 KMI1 (mouse).  */
410 cdbdb648 pbrook
    /* 0x10008000 Character LCD Interface.  */
411 cdbdb648 pbrook
    /*  0x10009000 UART3.  */
412 cdbdb648 pbrook
    /* 0x1000a000 Smart card 1.  */
413 cdbdb648 pbrook
    /* 0x1000b000 MMCI1.  */
414 cdbdb648 pbrook
    /*  0x10010000 Ethernet.  */
415 cdbdb648 pbrook
    /* 0x10020000 USB.  */
416 cdbdb648 pbrook
    /* 0x10100000 SSMC.  */
417 cdbdb648 pbrook
    /* 0x10110000 MPMC.  */
418 cdbdb648 pbrook
    /*  0x10120000 CLCD Controller.  */
419 cdbdb648 pbrook
    /*  0x10130000 DMA Controller.  */
420 cdbdb648 pbrook
    /*  0x10140000 Vectored interrupt controller.  */
421 cdbdb648 pbrook
    /* 0x101d0000 AHB Monitor Interface.  */
422 cdbdb648 pbrook
    /* 0x101e0000 System Controller.  */
423 cdbdb648 pbrook
    /* 0x101e1000 Watchdog Interface.  */
424 cdbdb648 pbrook
    /* 0x101e2000 Timer 0/1.  */
425 cdbdb648 pbrook
    /* 0x101e3000 Timer 2/3.  */
426 cdbdb648 pbrook
    /* 0x101e4000 GPIO port 0.  */
427 cdbdb648 pbrook
    /* 0x101e5000 GPIO port 1.  */
428 cdbdb648 pbrook
    /* 0x101e6000 GPIO port 2.  */
429 cdbdb648 pbrook
    /* 0x101e7000 GPIO port 3.  */
430 cdbdb648 pbrook
    /* 0x101e8000 RTC.  */
431 cdbdb648 pbrook
    /* 0x101f0000 Smart card 0.  */
432 cdbdb648 pbrook
    /*  0x101f1000 UART0.  */
433 cdbdb648 pbrook
    /*  0x101f2000 UART1.  */
434 cdbdb648 pbrook
    /*  0x101f3000 UART2.  */
435 cdbdb648 pbrook
    /* 0x101f4000 SSPI.  */
436 cdbdb648 pbrook
437 16406950 pbrook
    arm_load_kernel(ram_size, kernel_filename, kernel_cmdline,
438 16406950 pbrook
                    initrd_filename, board_id);
439 16406950 pbrook
}
440 16406950 pbrook
441 16406950 pbrook
static void vpb_init(int ram_size, int vga_ram_size, int boot_device,
442 16406950 pbrook
                     DisplayState *ds, const char **fd_filename, int snapshot,
443 16406950 pbrook
                     const char *kernel_filename, const char *kernel_cmdline,
444 16406950 pbrook
                     const char *initrd_filename)
445 16406950 pbrook
{
446 16406950 pbrook
    versatile_init(ram_size, vga_ram_size, boot_device,
447 16406950 pbrook
                   ds, fd_filename, snapshot,
448 16406950 pbrook
                   kernel_filename, kernel_cmdline,
449 16406950 pbrook
                   initrd_filename, 0x183);
450 16406950 pbrook
}
451 16406950 pbrook
452 16406950 pbrook
static void vab_init(int ram_size, int vga_ram_size, int boot_device,
453 16406950 pbrook
                     DisplayState *ds, const char **fd_filename, int snapshot,
454 16406950 pbrook
                     const char *kernel_filename, const char *kernel_cmdline,
455 16406950 pbrook
                     const char *initrd_filename)
456 16406950 pbrook
{
457 16406950 pbrook
    versatile_init(ram_size, vga_ram_size, boot_device,
458 16406950 pbrook
                   ds, fd_filename, snapshot,
459 16406950 pbrook
                   kernel_filename, kernel_cmdline,
460 16406950 pbrook
                   initrd_filename, 0x25e);
461 cdbdb648 pbrook
}
462 cdbdb648 pbrook
463 cdbdb648 pbrook
QEMUMachine versatilepb_machine = {
464 cdbdb648 pbrook
    "versatilepb",
465 cdbdb648 pbrook
    "ARM Versatile/PB (ARM926EJ-S)",
466 cdbdb648 pbrook
    vpb_init,
467 cdbdb648 pbrook
};
468 16406950 pbrook
469 16406950 pbrook
QEMUMachine versatileab_machine = {
470 16406950 pbrook
    "versatileab",
471 16406950 pbrook
    "ARM Versatile/AB (ARM926EJ-S)",
472 16406950 pbrook
    vab_init,
473 16406950 pbrook
};