Statistics
| Branch: | Revision:

root / hw / realview.c @ 313feaab

History | View | Annotate | Download (6.5 kB)

1 5fafdf24 ths
/*
2 e69954b9 pbrook
 * ARM RealView Baseboard System emulation.
3 e69954b9 pbrook
 *
4 a1bb27b1 pbrook
 * Copyright (c) 2006-2007 CodeSourcery.
5 e69954b9 pbrook
 * Written by Paul Brook
6 e69954b9 pbrook
 *
7 e69954b9 pbrook
 * This code is licenced under the GPL.
8 e69954b9 pbrook
 */
9 e69954b9 pbrook
10 2e9bdce5 Paul Brook
#include "sysbus.h"
11 87ecb68b pbrook
#include "arm-misc.h"
12 87ecb68b pbrook
#include "primecell.h"
13 87ecb68b pbrook
#include "devices.h"
14 87ecb68b pbrook
#include "pci.h"
15 87ecb68b pbrook
#include "net.h"
16 87ecb68b pbrook
#include "sysemu.h"
17 87ecb68b pbrook
#include "boards.h"
18 e69954b9 pbrook
19 e69954b9 pbrook
/* Board init.  */
20 e69954b9 pbrook
21 f93eb9ff balrog
static struct arm_boot_info realview_binfo = {
22 f93eb9ff balrog
    .loader_start = 0x0,
23 52b43737 pbrook
    .smp_loader_start = 0x80000000,
24 f93eb9ff balrog
    .board_id = 0x33b,
25 f93eb9ff balrog
};
26 f93eb9ff balrog
27 fbe1b595 Paul Brook
static void realview_init(ram_addr_t ram_size,
28 3023f332 aliguori
                     const char *boot_device,
29 e69954b9 pbrook
                     const char *kernel_filename, const char *kernel_cmdline,
30 94fc95cd j_mayer
                     const char *initrd_filename, const char *cpu_model)
31 e69954b9 pbrook
{
32 e69954b9 pbrook
    CPUState *env;
33 7ffab4d7 pbrook
    ram_addr_t ram_offset;
34 0027b06d Paul Brook
    DeviceState *dev;
35 fe7e8758 Paul Brook
    qemu_irq *irqp;
36 fe7e8758 Paul Brook
    qemu_irq pic[64];
37 e69954b9 pbrook
    PCIBus *pci_bus;
38 e69954b9 pbrook
    NICInfo *nd;
39 e69954b9 pbrook
    int n;
40 e69954b9 pbrook
    int done_smc = 0;
41 9ee6e8bb pbrook
    qemu_irq cpu_irq[4];
42 9ee6e8bb pbrook
    int ncpu;
43 e69954b9 pbrook
44 3371d272 pbrook
    if (!cpu_model)
45 3371d272 pbrook
        cpu_model = "arm926";
46 9ee6e8bb pbrook
    /* FIXME: obey smp_cpus.  */
47 9ee6e8bb pbrook
    if (strcmp(cpu_model, "arm11mpcore") == 0) {
48 9ee6e8bb pbrook
        ncpu = 4;
49 9ee6e8bb pbrook
    } else {
50 9ee6e8bb pbrook
        ncpu = 1;
51 9ee6e8bb pbrook
    }
52 9ee6e8bb pbrook
53 9ee6e8bb pbrook
    for (n = 0; n < ncpu; n++) {
54 9ee6e8bb pbrook
        env = cpu_init(cpu_model);
55 9ee6e8bb pbrook
        if (!env) {
56 9ee6e8bb pbrook
            fprintf(stderr, "Unable to find CPU definition\n");
57 9ee6e8bb pbrook
            exit(1);
58 9ee6e8bb pbrook
        }
59 fe7e8758 Paul Brook
        irqp = arm_pic_init_cpu(env);
60 fe7e8758 Paul Brook
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
61 9ee6e8bb pbrook
        if (n > 0) {
62 9ee6e8bb pbrook
            /* Set entry point for secondary CPUs.  This assumes we're using
63 9ee6e8bb pbrook
               the init code from arm_boot.c.  Real hardware resets all CPUs
64 9ee6e8bb pbrook
               the same.  */
65 9ee6e8bb pbrook
            env->regs[15] = 0x80000000;
66 9ee6e8bb pbrook
        }
67 aaed909a bellard
    }
68 aaed909a bellard
69 7ffab4d7 pbrook
    ram_offset = qemu_ram_alloc(ram_size);
70 1235fc06 ths
    /* ??? RAM should repeat to fill physical memory space.  */
71 e69954b9 pbrook
    /* SDRAM at address zero.  */
72 7ffab4d7 pbrook
    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
73 e69954b9 pbrook
74 e69954b9 pbrook
    arm_sysctl_init(0x10000000, 0xc1400400);
75 9ee6e8bb pbrook
76 9ee6e8bb pbrook
    if (ncpu == 1) {
77 9ee6e8bb pbrook
        /* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3
78 9ee6e8bb pbrook
           is nIRQ (there are inconsistencies).  However Linux 2.6.17 expects
79 9ee6e8bb pbrook
           GIC1 to be nIRQ and ignores all the others, so do that for now.  */
80 fe7e8758 Paul Brook
        dev = sysbus_create_simple("realview_gic", 0x10040000, cpu_irq[0]);
81 9ee6e8bb pbrook
    } else {
82 fe7e8758 Paul Brook
        dev = sysbus_create_varargs("realview_mpcore", -1,
83 fe7e8758 Paul Brook
                                    cpu_irq[0], cpu_irq[1], cpu_irq[2],
84 fe7e8758 Paul Brook
                                    cpu_irq[3], NULL);
85 fe7e8758 Paul Brook
    }
86 fe7e8758 Paul Brook
    for (n = 0; n < 64; n++) {
87 067a3ddc Paul Brook
        pic[n] = qdev_get_gpio_in(dev, n);
88 9ee6e8bb pbrook
    }
89 9ee6e8bb pbrook
90 86394e96 Paul Brook
    sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);
91 86394e96 Paul Brook
    sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]);
92 e69954b9 pbrook
93 a7d518a6 Paul Brook
    sysbus_create_simple("pl011", 0x10009000, pic[12]);
94 a7d518a6 Paul Brook
    sysbus_create_simple("pl011", 0x1000a000, pic[13]);
95 a7d518a6 Paul Brook
    sysbus_create_simple("pl011", 0x1000b000, pic[14]);
96 a7d518a6 Paul Brook
    sysbus_create_simple("pl011", 0x1000c000, pic[15]);
97 e69954b9 pbrook
98 e69954b9 pbrook
    /* DMA controller is optional, apparently.  */
99 b4496b13 Paul Brook
    sysbus_create_simple("pl081", 0x10030000, pic[24]);
100 e69954b9 pbrook
101 6a824ec3 Paul Brook
    sysbus_create_simple("sp804", 0x10011000, pic[4]);
102 6a824ec3 Paul Brook
    sysbus_create_simple("sp804", 0x10012000, pic[5]);
103 e69954b9 pbrook
104 2e9bdce5 Paul Brook
    sysbus_create_simple("pl110_versatile", 0x10020000, pic[23]);
105 e69954b9 pbrook
106 aa9311d8 Paul Brook
    sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL);
107 a1bb27b1 pbrook
108 a63bdb31 Paul Brook
    sysbus_create_simple("pl031", 0x10017000, pic[10]);
109 7e1543c2 pbrook
110 0027b06d Paul Brook
    dev = sysbus_create_varargs("realview_pci", 0x60000000,
111 0027b06d Paul Brook
                                pic[48], pic[49], pic[50], pic[51], NULL);
112 02e2da45 Paul Brook
    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
113 e69954b9 pbrook
    if (usb_enabled) {
114 e24ad6f1 pbrook
        usb_ohci_init_pci(pci_bus, 3, -1);
115 e69954b9 pbrook
    }
116 9be5dafe Paul Brook
    n = drive_get_max_bus(IF_SCSI);
117 9be5dafe Paul Brook
    while (n >= 0) {
118 9be5dafe Paul Brook
        pci_create_simple(pci_bus, -1, "lsi53c895a");
119 9be5dafe Paul Brook
        n--;
120 e69954b9 pbrook
    }
121 e69954b9 pbrook
    for(n = 0; n < nb_nics; n++) {
122 e69954b9 pbrook
        nd = &nd_table[n];
123 0ae18cee aliguori
124 0ae18cee aliguori
        if ((!nd->model && !done_smc) || strcmp(nd->model, "smc91c111") == 0) {
125 d537cf6c pbrook
            smc91c111_init(nd, 0x4e000000, pic[28]);
126 0ae18cee aliguori
            done_smc = 1;
127 e69954b9 pbrook
        } else {
128 5607c388 Markus Armbruster
            pci_nic_init(nd, "rtl8139", NULL);
129 e69954b9 pbrook
        }
130 e69954b9 pbrook
    }
131 e69954b9 pbrook
132 e69954b9 pbrook
    /* Memory map for RealView Emulation Baseboard:  */
133 e69954b9 pbrook
    /* 0x10000000 System registers.  */
134 e69954b9 pbrook
    /*  0x10001000 System controller.  */
135 e69954b9 pbrook
    /*  0x10002000 Two-Wire Serial Bus.  */
136 e69954b9 pbrook
    /* 0x10003000 Reserved.  */
137 e69954b9 pbrook
    /*  0x10004000 AACI.  */
138 e69954b9 pbrook
    /*  0x10005000 MCI.  */
139 e69954b9 pbrook
    /* 0x10006000 KMI0.  */
140 e69954b9 pbrook
    /* 0x10007000 KMI1.  */
141 e69954b9 pbrook
    /*  0x10008000 Character LCD.  */
142 e69954b9 pbrook
    /* 0x10009000 UART0.  */
143 e69954b9 pbrook
    /* 0x1000a000 UART1.  */
144 e69954b9 pbrook
    /* 0x1000b000 UART2.  */
145 e69954b9 pbrook
    /* 0x1000c000 UART3.  */
146 e69954b9 pbrook
    /*  0x1000d000 SSPI.  */
147 e69954b9 pbrook
    /*  0x1000e000 SCI.  */
148 e69954b9 pbrook
    /* 0x1000f000 Reserved.  */
149 e69954b9 pbrook
    /*  0x10010000 Watchdog.  */
150 e69954b9 pbrook
    /* 0x10011000 Timer 0+1.  */
151 e69954b9 pbrook
    /* 0x10012000 Timer 2+3.  */
152 e69954b9 pbrook
    /*  0x10013000 GPIO 0.  */
153 e69954b9 pbrook
    /*  0x10014000 GPIO 1.  */
154 e69954b9 pbrook
    /*  0x10015000 GPIO 2.  */
155 e69954b9 pbrook
    /* 0x10016000 Reserved.  */
156 7e1543c2 pbrook
    /* 0x10017000 RTC.  */
157 e69954b9 pbrook
    /*  0x10018000 DMC.  */
158 e69954b9 pbrook
    /*  0x10019000 PCI controller config.  */
159 e69954b9 pbrook
    /*  0x10020000 CLCD.  */
160 e69954b9 pbrook
    /* 0x10030000 DMA Controller.  */
161 9ee6e8bb pbrook
    /* 0x10040000 GIC1.  */
162 9ee6e8bb pbrook
    /* 0x10050000 GIC2.  */
163 9ee6e8bb pbrook
    /* 0x10060000 GIC3.  */
164 9ee6e8bb pbrook
    /* 0x10070000 GIC4.  */
165 e69954b9 pbrook
    /*  0x10080000 SMC.  */
166 e69954b9 pbrook
    /*  0x40000000 NOR flash.  */
167 e69954b9 pbrook
    /*  0x44000000 DoC flash.  */
168 e69954b9 pbrook
    /*  0x48000000 SRAM.  */
169 e69954b9 pbrook
    /*  0x4c000000 Configuration flash.  */
170 e69954b9 pbrook
    /* 0x4e000000 Ethernet.  */
171 e69954b9 pbrook
    /*  0x4f000000 USB.  */
172 e69954b9 pbrook
    /*  0x50000000 PISMO.  */
173 e69954b9 pbrook
    /*  0x54000000 PISMO.  */
174 e69954b9 pbrook
    /*  0x58000000 PISMO.  */
175 e69954b9 pbrook
    /*  0x5c000000 PISMO.  */
176 e69954b9 pbrook
    /* 0x60000000 PCI.  */
177 e69954b9 pbrook
    /* 0x61000000 PCI Self Config.  */
178 e69954b9 pbrook
    /* 0x62000000 PCI Config.  */
179 e69954b9 pbrook
    /* 0x63000000 PCI IO.  */
180 e69954b9 pbrook
    /* 0x64000000 PCI mem 0.  */
181 e69954b9 pbrook
    /* 0x68000000 PCI mem 1.  */
182 e69954b9 pbrook
    /* 0x6c000000 PCI mem 2.  */
183 e69954b9 pbrook
184 7ffab4d7 pbrook
    /* ??? Hack to map an additional page of ram for the secondary CPU
185 7ffab4d7 pbrook
       startup code.  I guess this works on real hardware because the
186 7ffab4d7 pbrook
       BootROM happens to be in ROM/flash or in memory that isn't clobbered
187 7ffab4d7 pbrook
       until after Linux boots the secondary CPUs.  */
188 7ffab4d7 pbrook
    ram_offset = qemu_ram_alloc(0x1000);
189 7ffab4d7 pbrook
    cpu_register_physical_memory(0x80000000, 0x1000, ram_offset | IO_MEM_RAM);
190 7ffab4d7 pbrook
191 f93eb9ff balrog
    realview_binfo.ram_size = ram_size;
192 f93eb9ff balrog
    realview_binfo.kernel_filename = kernel_filename;
193 f93eb9ff balrog
    realview_binfo.kernel_cmdline = kernel_cmdline;
194 f93eb9ff balrog
    realview_binfo.initrd_filename = initrd_filename;
195 f93eb9ff balrog
    realview_binfo.nb_cpus = ncpu;
196 f93eb9ff balrog
    arm_load_kernel(first_cpu, &realview_binfo);
197 e69954b9 pbrook
}
198 e69954b9 pbrook
199 e69954b9 pbrook
QEMUMachine realview_machine = {
200 c9b1ae2c blueswir1
    .name = "realview",
201 c9b1ae2c blueswir1
    .desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
202 c9b1ae2c blueswir1
    .init = realview_init,
203 c9b1ae2c blueswir1
    .use_scsi = 1,
204 e69954b9 pbrook
};
205 f80f9ec9 Anthony Liguori
206 f80f9ec9 Anthony Liguori
static void realview_machine_init(void)
207 f80f9ec9 Anthony Liguori
{
208 f80f9ec9 Anthony Liguori
    qemu_register_machine(&realview_machine);
209 f80f9ec9 Anthony Liguori
}
210 f80f9ec9 Anthony Liguori
211 f80f9ec9 Anthony Liguori
machine_init(realview_machine_init);