]> Git Repo - qemu.git/blob - hw/realview.c
GPIO I2C rework
[qemu.git] / hw / realview.c
1 /*
2  * ARM RealView Baseboard System emulation.
3  *
4  * Copyright (c) 2006-2007 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licenced under the GPL.
8  */
9
10 #include "sysbus.h"
11 #include "arm-misc.h"
12 #include "primecell.h"
13 #include "devices.h"
14 #include "pci.h"
15 #include "net.h"
16 #include "sysemu.h"
17 #include "boards.h"
18
19 #define SMP_BOOT_ADDR 0xe0000000
20 /* Board init.  */
21
22 static struct arm_boot_info realview_binfo = {
23     .smp_loader_start = SMP_BOOT_ADDR,
24 };
25
26 static void secondary_cpu_reset(void *opaque)
27 {
28   CPUState *env = opaque;
29
30   cpu_reset(env);
31   /* Set entry point for secondary CPUs.  This assumes we're using
32      the init code from arm_boot.c.  Real hardware resets all CPUs
33      the same.  */
34   env->regs[15] = SMP_BOOT_ADDR;
35 }
36
37 /* The following two lists must be consistent.  */
38 enum realview_board_type {
39     BOARD_EB,
40     BOARD_EB_MPCORE,
41     BOARD_PB_A8,
42     BOARD_PBX_A9,
43 };
44
45 int realview_board_id[] = {
46     0x33b,
47     0x33b,
48     0x769,
49     0x76d
50 };
51
52 static void realview_init(ram_addr_t ram_size,
53                      const char *boot_device,
54                      const char *kernel_filename, const char *kernel_cmdline,
55                      const char *initrd_filename, const char *cpu_model,
56                      enum realview_board_type board_type)
57 {
58     CPUState *env = NULL;
59     ram_addr_t ram_offset;
60     DeviceState *dev;
61     SysBusDevice *busdev;
62     qemu_irq *irqp;
63     qemu_irq pic[64];
64     PCIBus *pci_bus;
65     NICInfo *nd;
66     int n;
67     int done_nic = 0;
68     qemu_irq cpu_irq[4];
69     int is_mpcore = 0;
70     int is_pb = 0;
71     uint32_t proc_id = 0;
72     uint32_t sys_id;
73     ram_addr_t low_ram_size;
74
75     switch (board_type) {
76     case BOARD_EB:
77         break;
78     case BOARD_EB_MPCORE:
79         is_mpcore = 1;
80         break;
81     case BOARD_PB_A8:
82         is_pb = 1;
83         break;
84     case BOARD_PBX_A9:
85         is_mpcore = 1;
86         is_pb = 1;
87         break;
88     }
89     for (n = 0; n < smp_cpus; n++) {
90         env = cpu_init(cpu_model);
91         if (!env) {
92             fprintf(stderr, "Unable to find CPU definition\n");
93             exit(1);
94         }
95         irqp = arm_pic_init_cpu(env);
96         cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
97         if (n > 0) {
98             qemu_register_reset(secondary_cpu_reset, env);
99         }
100     }
101     if (arm_feature(env, ARM_FEATURE_V7)) {
102         if (is_mpcore) {
103             proc_id = 0x0c000000;
104         } else {
105             proc_id = 0x0e000000;
106         }
107     } else if (arm_feature(env, ARM_FEATURE_V6K)) {
108         proc_id = 0x06000000;
109     } else if (arm_feature(env, ARM_FEATURE_V6)) {
110         proc_id = 0x04000000;
111     } else {
112         proc_id = 0x02000000;
113     }
114
115     ram_offset = qemu_ram_alloc(ram_size);
116     low_ram_size = ram_size;
117     if (low_ram_size > 0x10000000)
118       low_ram_size = 0x10000000;
119     /* ??? RAM should repeat to fill physical memory space.  */
120     /* SDRAM at address zero.  */
121     cpu_register_physical_memory(0, low_ram_size, ram_offset | IO_MEM_RAM);
122     if (is_pb) {
123         /* And again at a high address.  */
124         cpu_register_physical_memory(0x70000000, ram_size,
125                                      ram_offset | IO_MEM_RAM);
126     } else {
127         ram_size = low_ram_size;
128     }
129
130     sys_id = is_pb ? 0x01780500 : 0xc1400400;
131     arm_sysctl_init(0x10000000, sys_id, proc_id);
132
133     if (is_mpcore) {
134         dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore");
135         qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
136         qdev_init_nofail(dev);
137         busdev = sysbus_from_qdev(dev);
138         if (is_pb) {
139             realview_binfo.smp_priv_base = 0x1f000000;
140         } else {
141             realview_binfo.smp_priv_base = 0x10100000;
142         }
143         sysbus_mmio_map(busdev, 0, realview_binfo.smp_priv_base);
144         for (n = 0; n < smp_cpus; n++) {
145             sysbus_connect_irq(busdev, n, cpu_irq[n]);
146         }
147     } else {
148         uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000;
149         /* For now just create the nIRQ GIC, and ignore the others.  */
150         dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]);
151     }
152     for (n = 0; n < 64; n++) {
153         pic[n] = qdev_get_gpio_in(dev, n);
154     }
155
156     sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);
157     sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]);
158
159     sysbus_create_simple("pl011", 0x10009000, pic[12]);
160     sysbus_create_simple("pl011", 0x1000a000, pic[13]);
161     sysbus_create_simple("pl011", 0x1000b000, pic[14]);
162     sysbus_create_simple("pl011", 0x1000c000, pic[15]);
163
164     /* DMA controller is optional, apparently.  */
165     sysbus_create_simple("pl081", 0x10030000, pic[24]);
166
167     sysbus_create_simple("sp804", 0x10011000, pic[4]);
168     sysbus_create_simple("sp804", 0x10012000, pic[5]);
169
170     sysbus_create_simple("pl110_versatile", 0x10020000, pic[23]);
171
172     sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL);
173
174     sysbus_create_simple("pl031", 0x10017000, pic[10]);
175
176     if (!is_pb) {
177         dev = sysbus_create_varargs("realview_pci", 0x60000000,
178                                     pic[48], pic[49], pic[50], pic[51], NULL);
179         pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
180         if (usb_enabled) {
181             usb_ohci_init_pci(pci_bus, -1);
182         }
183         n = drive_get_max_bus(IF_SCSI);
184         while (n >= 0) {
185             pci_create_simple(pci_bus, -1, "lsi53c895a");
186             n--;
187         }
188     }
189     for(n = 0; n < nb_nics; n++) {
190         nd = &nd_table[n];
191
192         if ((!nd->model && !done_nic)
193             || strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0) {
194             if (is_pb) {
195                 lan9118_init(nd, 0x4e000000, pic[28]);
196             } else {
197                 smc91c111_init(nd, 0x4e000000, pic[28]);
198             }
199             done_nic = 1;
200         } else {
201             pci_nic_init_nofail(nd, "rtl8139", NULL);
202         }
203     }
204
205     /* Memory map for RealView Emulation Baseboard:  */
206     /* 0x10000000 System registers.  */
207     /*  0x10001000 System controller.  */
208     /*  0x10002000 Two-Wire Serial Bus.  */
209     /* 0x10003000 Reserved.  */
210     /*  0x10004000 AACI.  */
211     /*  0x10005000 MCI.  */
212     /* 0x10006000 KMI0.  */
213     /* 0x10007000 KMI1.  */
214     /*  0x10008000 Character LCD. (EB) */
215     /* 0x10009000 UART0.  */
216     /* 0x1000a000 UART1.  */
217     /* 0x1000b000 UART2.  */
218     /* 0x1000c000 UART3.  */
219     /*  0x1000d000 SSPI.  */
220     /*  0x1000e000 SCI.  */
221     /* 0x1000f000 Reserved.  */
222     /*  0x10010000 Watchdog.  */
223     /* 0x10011000 Timer 0+1.  */
224     /* 0x10012000 Timer 2+3.  */
225     /*  0x10013000 GPIO 0.  */
226     /*  0x10014000 GPIO 1.  */
227     /*  0x10015000 GPIO 2.  */
228     /*  0x10002000 Two-Wire Serial Bus - DVI. (PB) */
229     /* 0x10017000 RTC.  */
230     /*  0x10018000 DMC.  */
231     /*  0x10019000 PCI controller config.  */
232     /*  0x10020000 CLCD.  */
233     /* 0x10030000 DMA Controller.  */
234     /* 0x10040000 GIC1. (EB) */
235     /*  0x10050000 GIC2. (EB) */
236     /*  0x10060000 GIC3. (EB) */
237     /*  0x10070000 GIC4. (EB) */
238     /*  0x10080000 SMC.  */
239     /* 0x1e000000 GIC1. (PB) */
240     /*  0x1e001000 GIC2. (PB) */
241     /*  0x1e002000 GIC3. (PB) */
242     /*  0x1e003000 GIC4. (PB) */
243     /*  0x40000000 NOR flash.  */
244     /*  0x44000000 DoC flash.  */
245     /*  0x48000000 SRAM.  */
246     /*  0x4c000000 Configuration flash.  */
247     /* 0x4e000000 Ethernet.  */
248     /*  0x4f000000 USB.  */
249     /*  0x50000000 PISMO.  */
250     /*  0x54000000 PISMO.  */
251     /*  0x58000000 PISMO.  */
252     /*  0x5c000000 PISMO.  */
253     /* 0x60000000 PCI.  */
254     /* 0x61000000 PCI Self Config.  */
255     /* 0x62000000 PCI Config.  */
256     /* 0x63000000 PCI IO.  */
257     /* 0x64000000 PCI mem 0.  */
258     /* 0x68000000 PCI mem 1.  */
259     /* 0x6c000000 PCI mem 2.  */
260
261     /* ??? Hack to map an additional page of ram for the secondary CPU
262        startup code.  I guess this works on real hardware because the
263        BootROM happens to be in ROM/flash or in memory that isn't clobbered
264        until after Linux boots the secondary CPUs.  */
265     ram_offset = qemu_ram_alloc(0x1000);
266     cpu_register_physical_memory(SMP_BOOT_ADDR, 0x1000,
267                                  ram_offset | IO_MEM_RAM);
268
269     realview_binfo.ram_size = ram_size;
270     realview_binfo.kernel_filename = kernel_filename;
271     realview_binfo.kernel_cmdline = kernel_cmdline;
272     realview_binfo.initrd_filename = initrd_filename;
273     realview_binfo.nb_cpus = smp_cpus;
274     realview_binfo.board_id = realview_board_id[board_type];
275     realview_binfo.loader_start = is_pb ? 0x70000000 : 0;
276     arm_load_kernel(first_cpu, &realview_binfo);
277 }
278
279 static void realview_eb_init(ram_addr_t ram_size,
280                      const char *boot_device,
281                      const char *kernel_filename, const char *kernel_cmdline,
282                      const char *initrd_filename, const char *cpu_model)
283 {
284     if (!cpu_model) {
285         cpu_model = "arm926";
286     }
287     realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline,
288                   initrd_filename, cpu_model, BOARD_EB);
289 }
290
291 static void realview_eb_mpcore_init(ram_addr_t ram_size,
292                      const char *boot_device,
293                      const char *kernel_filename, const char *kernel_cmdline,
294                      const char *initrd_filename, const char *cpu_model)
295 {
296     if (!cpu_model) {
297         cpu_model = "arm11mpcore";
298     }
299     realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline,
300                   initrd_filename, cpu_model, BOARD_EB_MPCORE);
301 }
302
303 static void realview_pb_a8_init(ram_addr_t ram_size,
304                      const char *boot_device,
305                      const char *kernel_filename, const char *kernel_cmdline,
306                      const char *initrd_filename, const char *cpu_model)
307 {
308     if (!cpu_model) {
309         cpu_model = "cortex-a8";
310     }
311     realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline,
312                   initrd_filename, cpu_model, BOARD_PB_A8);
313 }
314
315 static void realview_pbx_a9_init(ram_addr_t ram_size,
316                      const char *boot_device,
317                      const char *kernel_filename, const char *kernel_cmdline,
318                      const char *initrd_filename, const char *cpu_model)
319 {
320     if (!cpu_model) {
321         cpu_model = "cortex-a9";
322     }
323     realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline,
324                   initrd_filename, cpu_model, BOARD_PBX_A9);
325 }
326
327 static QEMUMachine realview_eb_machine = {
328     .name = "realview-eb",
329     .desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
330     .init = realview_eb_init,
331     .use_scsi = 1,
332 };
333
334 static QEMUMachine realview_eb_mpcore_machine = {
335     .name = "realview-eb-mpcore",
336     .desc = "ARM RealView Emulation Baseboard (ARM11MPCore)",
337     .init = realview_eb_mpcore_init,
338     .use_scsi = 1,
339     .max_cpus = 4,
340 };
341
342 static QEMUMachine realview_pb_a8_machine = {
343     .name = "realview-pb-a8",
344     .desc = "ARM RealView Platform Baseboard for Cortex-A8",
345     .init = realview_pb_a8_init,
346 };
347
348 static QEMUMachine realview_pbx_a9_machine = {
349     .name = "realview-pbx-a9",
350     .desc = "ARM RealView Platform Baseboard Explore for Cortex-A9",
351     .init = realview_pbx_a9_init,
352     .use_scsi = 1,
353     .max_cpus = 4,
354 };
355
356 static void realview_machine_init(void)
357 {
358     qemu_register_machine(&realview_eb_machine);
359     qemu_register_machine(&realview_eb_mpcore_machine);
360     qemu_register_machine(&realview_pb_a8_machine);
361     qemu_register_machine(&realview_pbx_a9_machine);
362 }
363
364 machine_init(realview_machine_init);
This page took 0.043792 seconds and 4 git commands to generate.