Statistics
| Branch: | Revision:

root / hw / realview.c @ c988bfad

History | View | Annotate | Download (8 kB)

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
/* Board init.  */
20

    
21
static struct arm_boot_info realview_binfo = {
22
    .loader_start = 0x0,
23
    .smp_loader_start = 0x80000000,
24
    .board_id = 0x33b,
25
};
26

    
27
static void secondary_cpu_reset(void *opaque)
28
{
29
  CPUState *env = opaque;
30

    
31
  cpu_reset(env);
32
  /* Set entry point for secondary CPUs.  This assumes we're using
33
     the init code from arm_boot.c.  Real hardware resets all CPUs
34
     the same.  */
35
  env->regs[15] = 0x80000000;
36
}
37

    
38
enum realview_board_type {
39
    BOARD_EB,
40
    BOARD_EB_MPCORE
41
};
42

    
43
static void realview_init(ram_addr_t ram_size,
44
                     const char *boot_device,
45
                     const char *kernel_filename, const char *kernel_cmdline,
46
                     const char *initrd_filename, const char *cpu_model,
47
                     enum realview_board_type board_type)
48
{
49
    CPUState *env = NULL;
50
    ram_addr_t ram_offset;
51
    DeviceState *dev;
52
    SysBusDevice *busdev;
53
    qemu_irq *irqp;
54
    qemu_irq pic[64];
55
    PCIBus *pci_bus;
56
    NICInfo *nd;
57
    int n;
58
    int done_smc = 0;
59
    qemu_irq cpu_irq[4];
60
    int is_mpcore = (board_type == BOARD_EB_MPCORE);
61
    uint32_t proc_id = 0;
62

    
63
    for (n = 0; n < smp_cpus; n++) {
64
        env = cpu_init(cpu_model);
65
        if (!env) {
66
            fprintf(stderr, "Unable to find CPU definition\n");
67
            exit(1);
68
        }
69
        irqp = arm_pic_init_cpu(env);
70
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
71
        if (n > 0) {
72
            qemu_register_reset(secondary_cpu_reset, env);
73
        }
74
    }
75
    if (arm_feature(env, ARM_FEATURE_V7)) {
76
        proc_id = 0x0e000000;
77
    } else if (arm_feature(env, ARM_FEATURE_V6K)) {
78
        proc_id = 0x06000000;
79
    } else if (arm_feature(env, ARM_FEATURE_V6)) {
80
        proc_id = 0x04000000;
81
    } else {
82
        proc_id = 0x02000000;
83
    }
84

    
85
    ram_offset = qemu_ram_alloc(ram_size);
86
    /* ??? RAM should repeat to fill physical memory space.  */
87
    /* SDRAM at address zero.  */
88
    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
89

    
90
    arm_sysctl_init(0x10000000, 0xc1400400, proc_id);
91

    
92
    if (is_mpcore) {
93
        dev = qdev_create(NULL, "realview_mpcore");
94
        qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
95
        qdev_init_nofail(dev);
96
        busdev = sysbus_from_qdev(dev);
97
        for (n = 0; n < smp_cpus; n++) {
98
            sysbus_connect_irq(busdev, n, cpu_irq[n]);
99
        }
100
    } else {
101
        dev = sysbus_create_simple("realview_gic", 0x10040000, cpu_irq[0]);
102
    }
103
    for (n = 0; n < 64; n++) {
104
        pic[n] = qdev_get_gpio_in(dev, n);
105
    }
106

    
107
    sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);
108
    sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]);
109

    
110
    sysbus_create_simple("pl011", 0x10009000, pic[12]);
111
    sysbus_create_simple("pl011", 0x1000a000, pic[13]);
112
    sysbus_create_simple("pl011", 0x1000b000, pic[14]);
113
    sysbus_create_simple("pl011", 0x1000c000, pic[15]);
114

    
115
    /* DMA controller is optional, apparently.  */
116
    sysbus_create_simple("pl081", 0x10030000, pic[24]);
117

    
118
    sysbus_create_simple("sp804", 0x10011000, pic[4]);
119
    sysbus_create_simple("sp804", 0x10012000, pic[5]);
120

    
121
    sysbus_create_simple("pl110_versatile", 0x10020000, pic[23]);
122

    
123
    sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL);
124

    
125
    sysbus_create_simple("pl031", 0x10017000, pic[10]);
126

    
127
    dev = sysbus_create_varargs("realview_pci", 0x60000000,
128
                                pic[48], pic[49], pic[50], pic[51], NULL);
129
    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
130
    if (usb_enabled) {
131
        usb_ohci_init_pci(pci_bus, -1);
132
    }
133
    n = drive_get_max_bus(IF_SCSI);
134
    while (n >= 0) {
135
        pci_create_simple(pci_bus, -1, "lsi53c895a");
136
        n--;
137
    }
138
    for(n = 0; n < nb_nics; n++) {
139
        nd = &nd_table[n];
140

    
141
        if ((!nd->model && !done_smc) || strcmp(nd->model, "smc91c111") == 0) {
142
            smc91c111_init(nd, 0x4e000000, pic[28]);
143
            done_smc = 1;
144
        } else {
145
            pci_nic_init_nofail(nd, "rtl8139", NULL);
146
        }
147
    }
148

    
149
    /* Memory map for RealView Emulation Baseboard:  */
150
    /* 0x10000000 System registers.  */
151
    /*  0x10001000 System controller.  */
152
    /*  0x10002000 Two-Wire Serial Bus.  */
153
    /* 0x10003000 Reserved.  */
154
    /*  0x10004000 AACI.  */
155
    /*  0x10005000 MCI.  */
156
    /* 0x10006000 KMI0.  */
157
    /* 0x10007000 KMI1.  */
158
    /*  0x10008000 Character LCD.  */
159
    /* 0x10009000 UART0.  */
160
    /* 0x1000a000 UART1.  */
161
    /* 0x1000b000 UART2.  */
162
    /* 0x1000c000 UART3.  */
163
    /*  0x1000d000 SSPI.  */
164
    /*  0x1000e000 SCI.  */
165
    /* 0x1000f000 Reserved.  */
166
    /*  0x10010000 Watchdog.  */
167
    /* 0x10011000 Timer 0+1.  */
168
    /* 0x10012000 Timer 2+3.  */
169
    /*  0x10013000 GPIO 0.  */
170
    /*  0x10014000 GPIO 1.  */
171
    /*  0x10015000 GPIO 2.  */
172
    /* 0x10016000 Reserved.  */
173
    /* 0x10017000 RTC.  */
174
    /*  0x10018000 DMC.  */
175
    /*  0x10019000 PCI controller config.  */
176
    /*  0x10020000 CLCD.  */
177
    /* 0x10030000 DMA Controller.  */
178
    /* 0x10040000 GIC1.  */
179
    /* 0x10050000 GIC2.  */
180
    /* 0x10060000 GIC3.  */
181
    /* 0x10070000 GIC4.  */
182
    /*  0x10080000 SMC.  */
183
    /*  0x40000000 NOR flash.  */
184
    /*  0x44000000 DoC flash.  */
185
    /*  0x48000000 SRAM.  */
186
    /*  0x4c000000 Configuration flash.  */
187
    /* 0x4e000000 Ethernet.  */
188
    /*  0x4f000000 USB.  */
189
    /*  0x50000000 PISMO.  */
190
    /*  0x54000000 PISMO.  */
191
    /*  0x58000000 PISMO.  */
192
    /*  0x5c000000 PISMO.  */
193
    /* 0x60000000 PCI.  */
194
    /* 0x61000000 PCI Self Config.  */
195
    /* 0x62000000 PCI Config.  */
196
    /* 0x63000000 PCI IO.  */
197
    /* 0x64000000 PCI mem 0.  */
198
    /* 0x68000000 PCI mem 1.  */
199
    /* 0x6c000000 PCI mem 2.  */
200

    
201
    /* ??? Hack to map an additional page of ram for the secondary CPU
202
       startup code.  I guess this works on real hardware because the
203
       BootROM happens to be in ROM/flash or in memory that isn't clobbered
204
       until after Linux boots the secondary CPUs.  */
205
    ram_offset = qemu_ram_alloc(0x1000);
206
    cpu_register_physical_memory(0x80000000, 0x1000, ram_offset | IO_MEM_RAM);
207

    
208
    realview_binfo.ram_size = ram_size;
209
    realview_binfo.kernel_filename = kernel_filename;
210
    realview_binfo.kernel_cmdline = kernel_cmdline;
211
    realview_binfo.initrd_filename = initrd_filename;
212
    realview_binfo.nb_cpus = smp_cpus;
213
    arm_load_kernel(first_cpu, &realview_binfo);
214
}
215

    
216
static void realview_eb_init(ram_addr_t ram_size,
217
                     const char *boot_device,
218
                     const char *kernel_filename, const char *kernel_cmdline,
219
                     const char *initrd_filename, const char *cpu_model)
220
{
221
    if (!cpu_model) {
222
        cpu_model = "arm926";
223
    }
224
    realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline,
225
                  initrd_filename, cpu_model, BOARD_EB);
226
}
227

    
228
static void realview_eb_mpcore_init(ram_addr_t ram_size,
229
                     const char *boot_device,
230
                     const char *kernel_filename, const char *kernel_cmdline,
231
                     const char *initrd_filename, const char *cpu_model)
232
{
233
    if (!cpu_model) {
234
        cpu_model = "arm11mpcore";
235
    }
236
    realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline,
237
                  initrd_filename, cpu_model, BOARD_EB_MPCORE);
238
}
239

    
240
static QEMUMachine realview_eb_machine = {
241
    .name = "realview-eb",
242
    .desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
243
    .init = realview_eb_init,
244
    .use_scsi = 1,
245
};
246

    
247
static QEMUMachine realview_eb_mpcore_machine = {
248
    .name = "realview-eb-mpcore",
249
    .desc = "ARM RealView Emulation Baseboard (ARM11MPCore)",
250
    .init = realview_eb_mpcore_init,
251
    .use_scsi = 1,
252
    .max_cpus = 4,
253
};
254

    
255
static void realview_machine_init(void)
256
{
257
    qemu_register_machine(&realview_eb_machine);
258
    qemu_register_machine(&realview_eb_mpcore_machine);
259
}
260

    
261
machine_init(realview_machine_init);