Statistics
| Branch: | Revision:

root / hw / realview.c @ 089b7c0a

History | View | Annotate | Download (5.8 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 87ecb68b pbrook
#include "hw.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 6ac0e82d balrog
static void realview_init(int ram_size, int vga_ram_size,
22 6ac0e82d balrog
                     const char *boot_device, DisplayState *ds,
23 e69954b9 pbrook
                     const char *kernel_filename, const char *kernel_cmdline,
24 94fc95cd j_mayer
                     const char *initrd_filename, const char *cpu_model)
25 e69954b9 pbrook
{
26 e69954b9 pbrook
    CPUState *env;
27 d537cf6c pbrook
    qemu_irq *pic;
28 e69954b9 pbrook
    void *scsi_hba;
29 e69954b9 pbrook
    PCIBus *pci_bus;
30 e69954b9 pbrook
    NICInfo *nd;
31 e69954b9 pbrook
    int n;
32 e69954b9 pbrook
    int done_smc = 0;
33 9ee6e8bb pbrook
    qemu_irq cpu_irq[4];
34 9ee6e8bb pbrook
    int ncpu;
35 e4bcb14c ths
    int index;
36 e69954b9 pbrook
37 3371d272 pbrook
    if (!cpu_model)
38 3371d272 pbrook
        cpu_model = "arm926";
39 9ee6e8bb pbrook
    /* FIXME: obey smp_cpus.  */
40 9ee6e8bb pbrook
    if (strcmp(cpu_model, "arm11mpcore") == 0) {
41 9ee6e8bb pbrook
        ncpu = 4;
42 9ee6e8bb pbrook
    } else {
43 9ee6e8bb pbrook
        ncpu = 1;
44 9ee6e8bb pbrook
    }
45 9ee6e8bb pbrook
46 9ee6e8bb pbrook
    for (n = 0; n < ncpu; n++) {
47 9ee6e8bb pbrook
        env = cpu_init(cpu_model);
48 9ee6e8bb pbrook
        if (!env) {
49 9ee6e8bb pbrook
            fprintf(stderr, "Unable to find CPU definition\n");
50 9ee6e8bb pbrook
            exit(1);
51 9ee6e8bb pbrook
        }
52 9ee6e8bb pbrook
        pic = arm_pic_init_cpu(env);
53 9ee6e8bb pbrook
        cpu_irq[n] = pic[ARM_PIC_CPU_IRQ];
54 9ee6e8bb pbrook
        if (n > 0) {
55 9ee6e8bb pbrook
            /* Set entry point for secondary CPUs.  This assumes we're using
56 9ee6e8bb pbrook
               the init code from arm_boot.c.  Real hardware resets all CPUs
57 9ee6e8bb pbrook
               the same.  */
58 9ee6e8bb pbrook
            env->regs[15] = 0x80000000;
59 9ee6e8bb pbrook
        }
60 aaed909a bellard
    }
61 aaed909a bellard
62 e69954b9 pbrook
    /* ??? RAM shoud repeat to fill physical memory space.  */
63 e69954b9 pbrook
    /* SDRAM at address zero.  */
64 e69954b9 pbrook
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
65 e69954b9 pbrook
66 e69954b9 pbrook
    arm_sysctl_init(0x10000000, 0xc1400400);
67 9ee6e8bb pbrook
68 9ee6e8bb pbrook
    if (ncpu == 1) {
69 9ee6e8bb pbrook
        /* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3
70 9ee6e8bb pbrook
           is nIRQ (there are inconsistencies).  However Linux 2.6.17 expects
71 9ee6e8bb pbrook
           GIC1 to be nIRQ and ignores all the others, so do that for now.  */
72 9ee6e8bb pbrook
        pic = realview_gic_init(0x10040000, cpu_irq[0]);
73 9ee6e8bb pbrook
    } else {
74 9ee6e8bb pbrook
        pic = mpcore_irq_init(cpu_irq);
75 9ee6e8bb pbrook
    }
76 9ee6e8bb pbrook
77 d537cf6c pbrook
    pl050_init(0x10006000, pic[20], 0);
78 d537cf6c pbrook
    pl050_init(0x10007000, pic[21], 1);
79 e69954b9 pbrook
80 9ee6e8bb pbrook
    pl011_init(0x10009000, pic[12], serial_hds[0], PL011_ARM);
81 9ee6e8bb pbrook
    pl011_init(0x1000a000, pic[13], serial_hds[1], PL011_ARM);
82 9ee6e8bb pbrook
    pl011_init(0x1000b000, pic[14], serial_hds[2], PL011_ARM);
83 9ee6e8bb pbrook
    pl011_init(0x1000c000, pic[15], serial_hds[3], PL011_ARM);
84 e69954b9 pbrook
85 e69954b9 pbrook
    /* DMA controller is optional, apparently.  */
86 d537cf6c pbrook
    pl080_init(0x10030000, pic[24], 2);
87 e69954b9 pbrook
88 d537cf6c pbrook
    sp804_init(0x10011000, pic[4]);
89 d537cf6c pbrook
    sp804_init(0x10012000, pic[5]);
90 e69954b9 pbrook
91 d537cf6c pbrook
    pl110_init(ds, 0x10020000, pic[23], 1);
92 e69954b9 pbrook
93 e4bcb14c ths
    index = drive_get_index(IF_SD, 0, 0);
94 e4bcb14c ths
    if (index == -1) {
95 e4bcb14c ths
        fprintf(stderr, "qemu: missing SecureDigital card\n");
96 e4bcb14c ths
        exit(1);
97 e4bcb14c ths
    }
98 e4bcb14c ths
    pl181_init(0x10005000, drives_table[index].bdrv, pic[17], pic[18]);
99 a1bb27b1 pbrook
100 7e1543c2 pbrook
    pl031_init(0x10017000, pic[10]);
101 7e1543c2 pbrook
102 e69954b9 pbrook
    pci_bus = pci_vpb_init(pic, 48, 1);
103 e69954b9 pbrook
    if (usb_enabled) {
104 e24ad6f1 pbrook
        usb_ohci_init_pci(pci_bus, 3, -1);
105 e69954b9 pbrook
    }
106 e4bcb14c ths
    if (drive_get_max_bus(IF_SCSI) > 0) {
107 e4bcb14c ths
        fprintf(stderr, "qemu: too many SCSI bus\n");
108 e4bcb14c ths
        exit(1);
109 e4bcb14c ths
    }
110 e69954b9 pbrook
    scsi_hba = lsi_scsi_init(pci_bus, -1);
111 e4bcb14c ths
    for (n = 0; n < LSI_MAX_DEVS; n++) {
112 e4bcb14c ths
        index = drive_get_index(IF_SCSI, 0, n);
113 e4bcb14c ths
        if (index == -1)
114 e4bcb14c ths
            continue;
115 e4bcb14c ths
        lsi_scsi_attach(scsi_hba, drives_table[index].bdrv, n);
116 e69954b9 pbrook
    }
117 e69954b9 pbrook
    for(n = 0; n < nb_nics; n++) {
118 e69954b9 pbrook
        nd = &nd_table[n];
119 e69954b9 pbrook
        if (!nd->model)
120 e69954b9 pbrook
            nd->model = done_smc ? "rtl8139" : "smc91c111";
121 e69954b9 pbrook
        if (strcmp(nd->model, "smc91c111") == 0) {
122 d537cf6c pbrook
            smc91c111_init(nd, 0x4e000000, pic[28]);
123 e69954b9 pbrook
        } else {
124 abcebc7e ths
            pci_nic_init(pci_bus, nd, -1);
125 e69954b9 pbrook
        }
126 e69954b9 pbrook
    }
127 e69954b9 pbrook
128 e69954b9 pbrook
    /* Memory map for RealView Emulation Baseboard:  */
129 e69954b9 pbrook
    /* 0x10000000 System registers.  */
130 e69954b9 pbrook
    /*  0x10001000 System controller.  */
131 e69954b9 pbrook
    /*  0x10002000 Two-Wire Serial Bus.  */
132 e69954b9 pbrook
    /* 0x10003000 Reserved.  */
133 e69954b9 pbrook
    /*  0x10004000 AACI.  */
134 e69954b9 pbrook
    /*  0x10005000 MCI.  */
135 e69954b9 pbrook
    /* 0x10006000 KMI0.  */
136 e69954b9 pbrook
    /* 0x10007000 KMI1.  */
137 e69954b9 pbrook
    /*  0x10008000 Character LCD.  */
138 e69954b9 pbrook
    /* 0x10009000 UART0.  */
139 e69954b9 pbrook
    /* 0x1000a000 UART1.  */
140 e69954b9 pbrook
    /* 0x1000b000 UART2.  */
141 e69954b9 pbrook
    /* 0x1000c000 UART3.  */
142 e69954b9 pbrook
    /*  0x1000d000 SSPI.  */
143 e69954b9 pbrook
    /*  0x1000e000 SCI.  */
144 e69954b9 pbrook
    /* 0x1000f000 Reserved.  */
145 e69954b9 pbrook
    /*  0x10010000 Watchdog.  */
146 e69954b9 pbrook
    /* 0x10011000 Timer 0+1.  */
147 e69954b9 pbrook
    /* 0x10012000 Timer 2+3.  */
148 e69954b9 pbrook
    /*  0x10013000 GPIO 0.  */
149 e69954b9 pbrook
    /*  0x10014000 GPIO 1.  */
150 e69954b9 pbrook
    /*  0x10015000 GPIO 2.  */
151 e69954b9 pbrook
    /* 0x10016000 Reserved.  */
152 7e1543c2 pbrook
    /* 0x10017000 RTC.  */
153 e69954b9 pbrook
    /*  0x10018000 DMC.  */
154 e69954b9 pbrook
    /*  0x10019000 PCI controller config.  */
155 e69954b9 pbrook
    /*  0x10020000 CLCD.  */
156 e69954b9 pbrook
    /* 0x10030000 DMA Controller.  */
157 9ee6e8bb pbrook
    /* 0x10040000 GIC1.  */
158 9ee6e8bb pbrook
    /* 0x10050000 GIC2.  */
159 9ee6e8bb pbrook
    /* 0x10060000 GIC3.  */
160 9ee6e8bb pbrook
    /* 0x10070000 GIC4.  */
161 e69954b9 pbrook
    /*  0x10080000 SMC.  */
162 e69954b9 pbrook
    /*  0x40000000 NOR flash.  */
163 e69954b9 pbrook
    /*  0x44000000 DoC flash.  */
164 e69954b9 pbrook
    /*  0x48000000 SRAM.  */
165 e69954b9 pbrook
    /*  0x4c000000 Configuration flash.  */
166 e69954b9 pbrook
    /* 0x4e000000 Ethernet.  */
167 e69954b9 pbrook
    /*  0x4f000000 USB.  */
168 e69954b9 pbrook
    /*  0x50000000 PISMO.  */
169 e69954b9 pbrook
    /*  0x54000000 PISMO.  */
170 e69954b9 pbrook
    /*  0x58000000 PISMO.  */
171 e69954b9 pbrook
    /*  0x5c000000 PISMO.  */
172 e69954b9 pbrook
    /* 0x60000000 PCI.  */
173 e69954b9 pbrook
    /* 0x61000000 PCI Self Config.  */
174 e69954b9 pbrook
    /* 0x62000000 PCI Config.  */
175 e69954b9 pbrook
    /* 0x63000000 PCI IO.  */
176 e69954b9 pbrook
    /* 0x64000000 PCI mem 0.  */
177 e69954b9 pbrook
    /* 0x68000000 PCI mem 1.  */
178 e69954b9 pbrook
    /* 0x6c000000 PCI mem 2.  */
179 e69954b9 pbrook
180 9ee6e8bb pbrook
    arm_load_kernel(first_cpu, ram_size, kernel_filename, kernel_cmdline,
181 9d551997 balrog
                    initrd_filename, 0x33b, 0x0);
182 9ee6e8bb pbrook
183 9ee6e8bb pbrook
    /* ??? Hack to map an additional page of ram for the secondary CPU
184 9ee6e8bb pbrook
       startup code.  I guess this works on real hardware because the
185 9ee6e8bb pbrook
       BootROM happens to be in ROM/flash or in memory that isn't clobbered
186 9ee6e8bb pbrook
       until after Linux boots the secondary CPUs.  */
187 9ee6e8bb pbrook
    cpu_register_physical_memory(0x80000000, 0x1000, IO_MEM_RAM + ram_size);
188 e69954b9 pbrook
}
189 e69954b9 pbrook
190 e69954b9 pbrook
QEMUMachine realview_machine = {
191 e69954b9 pbrook
    "realview",
192 e69954b9 pbrook
    "ARM RealView Emulation Baseboard (ARM926EJ-S)",
193 e69954b9 pbrook
    realview_init
194 e69954b9 pbrook
};