Statistics
| Branch: | Revision:

root / hw / mips_fulong2e.c @ c9940edb

History | View | Annotate | Download (12.3 kB)

1 051c190b Huacai Chen
/*
2 051c190b Huacai Chen
 * QEMU fulong 2e mini pc support
3 051c190b Huacai Chen
 *
4 051c190b Huacai Chen
 * Copyright (c) 2008 yajin (yajin@vm-kernel.org)
5 051c190b Huacai Chen
 * Copyright (c) 2009 chenming (chenming@rdc.faw.com.cn)
6 051c190b Huacai Chen
 * Copyright (c) 2010 Huacai Chen (zltjiangshi@gmail.com)
7 051c190b Huacai Chen
 * This code is licensed under the GNU GPL v2.
8 051c190b Huacai Chen
 */
9 051c190b Huacai Chen
10 051c190b Huacai Chen
/*
11 051c190b Huacai Chen
 * Fulong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 800MHz)
12 051c190b Huacai Chen
 * http://www.linux-mips.org/wiki/Fulong
13 051c190b Huacai Chen
 *
14 051c190b Huacai Chen
 * Loongson 2e user manual:
15 051c190b Huacai Chen
 * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf
16 051c190b Huacai Chen
 */
17 051c190b Huacai Chen
18 051c190b Huacai Chen
#include "hw.h"
19 051c190b Huacai Chen
#include "pc.h"
20 051c190b Huacai Chen
#include "fdc.h"
21 051c190b Huacai Chen
#include "net.h"
22 051c190b Huacai Chen
#include "boards.h"
23 051c190b Huacai Chen
#include "smbus.h"
24 051c190b Huacai Chen
#include "block.h"
25 051c190b Huacai Chen
#include "flash.h"
26 051c190b Huacai Chen
#include "mips.h"
27 051c190b Huacai Chen
#include "mips_cpudevs.h"
28 051c190b Huacai Chen
#include "pci.h"
29 051c190b Huacai Chen
#include "usb-uhci.h"
30 051c190b Huacai Chen
#include "qemu-char.h"
31 051c190b Huacai Chen
#include "sysemu.h"
32 051c190b Huacai Chen
#include "audio/audio.h"
33 051c190b Huacai Chen
#include "qemu-log.h"
34 051c190b Huacai Chen
#include "loader.h"
35 051c190b Huacai Chen
#include "mips-bios.h"
36 051c190b Huacai Chen
#include "ide.h"
37 051c190b Huacai Chen
#include "elf.h"
38 051c190b Huacai Chen
#include "vt82c686.h"
39 051c190b Huacai Chen
#include "mc146818rtc.h"
40 2446333c Blue Swirl
#include "blockdev.h"
41 13faf2a7 Avi Kivity
#include "exec-memory.h"
42 051c190b Huacai Chen
43 051c190b Huacai Chen
#define DEBUG_FULONG2E_INIT
44 051c190b Huacai Chen
45 051c190b Huacai Chen
#define ENVP_ADDR       0x80002000l
46 051c190b Huacai Chen
#define ENVP_NB_ENTRIES                 16
47 051c190b Huacai Chen
#define ENVP_ENTRY_SIZE                 256
48 051c190b Huacai Chen
49 051c190b Huacai Chen
#define MAX_IDE_BUS 2
50 051c190b Huacai Chen
51 051c190b Huacai Chen
/*
52 051c190b Huacai Chen
 * PMON is not part of qemu and released with BSD license, anyone
53 051c190b Huacai Chen
 * who want to build a pmon binary please first git-clone the source
54 051c190b Huacai Chen
 * from the git repository at:
55 051c190b Huacai Chen
 * http://www.loongson.cn/support/git/pmon
56 051c190b Huacai Chen
 * Then follow the "Compile Guide" available at:
57 051c190b Huacai Chen
 * http://dev.lemote.com/code/pmon
58 051c190b Huacai Chen
 *
59 051c190b Huacai Chen
 * Notes:
60 051c190b Huacai Chen
 * 1, don't use the source at http://dev.lemote.com/http_git/pmon.git
61 051c190b Huacai Chen
 * 2, use "Bonito2edev" to replace "dir_corresponding_to_your_target_hardware"
62 051c190b Huacai Chen
 * in the "Compile Guide".
63 051c190b Huacai Chen
 */
64 051c190b Huacai Chen
#define FULONG_BIOSNAME "pmon_fulong2e.bin"
65 051c190b Huacai Chen
66 051c190b Huacai Chen
/* PCI SLOT in fulong 2e */
67 051c190b Huacai Chen
#define FULONG2E_VIA_SLOT        5
68 051c190b Huacai Chen
#define FULONG2E_ATI_SLOT        6
69 051c190b Huacai Chen
#define FULONG2E_RTL8139_SLOT    7
70 051c190b Huacai Chen
71 64d7e9a4 Blue Swirl
static ISADevice *pit;
72 051c190b Huacai Chen
73 051c190b Huacai Chen
static struct _loaderparams {
74 051c190b Huacai Chen
    int ram_size;
75 051c190b Huacai Chen
    const char *kernel_filename;
76 051c190b Huacai Chen
    const char *kernel_cmdline;
77 051c190b Huacai Chen
    const char *initrd_filename;
78 051c190b Huacai Chen
} loaderparams;
79 051c190b Huacai Chen
80 8b7968f7 Stefan Weil
static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf, int index,
81 8b7968f7 Stefan Weil
                                        const char *string, ...)
82 051c190b Huacai Chen
{
83 051c190b Huacai Chen
    va_list ap;
84 051c190b Huacai Chen
    int32_t table_addr;
85 051c190b Huacai Chen
86 051c190b Huacai Chen
    if (index >= ENVP_NB_ENTRIES)
87 051c190b Huacai Chen
        return;
88 051c190b Huacai Chen
89 051c190b Huacai Chen
    if (string == NULL) {
90 051c190b Huacai Chen
        prom_buf[index] = 0;
91 051c190b Huacai Chen
        return;
92 051c190b Huacai Chen
    }
93 051c190b Huacai Chen
94 051c190b Huacai Chen
    table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
95 051c190b Huacai Chen
    prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
96 051c190b Huacai Chen
97 051c190b Huacai Chen
    va_start(ap, string);
98 051c190b Huacai Chen
    vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
99 051c190b Huacai Chen
    va_end(ap);
100 051c190b Huacai Chen
}
101 051c190b Huacai Chen
102 051c190b Huacai Chen
static int64_t load_kernel (CPUState *env)
103 051c190b Huacai Chen
{
104 051c190b Huacai Chen
    int64_t kernel_entry, kernel_low, kernel_high;
105 051c190b Huacai Chen
    int index = 0;
106 051c190b Huacai Chen
    long initrd_size;
107 051c190b Huacai Chen
    ram_addr_t initrd_offset;
108 051c190b Huacai Chen
    uint32_t *prom_buf;
109 051c190b Huacai Chen
    long prom_size;
110 051c190b Huacai Chen
111 051c190b Huacai Chen
    if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
112 051c190b Huacai Chen
                 (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
113 051c190b Huacai Chen
                 (uint64_t *)&kernel_high, 0, ELF_MACHINE, 1) < 0) {
114 051c190b Huacai Chen
        fprintf(stderr, "qemu: could not load kernel '%s'\n",
115 051c190b Huacai Chen
                loaderparams.kernel_filename);
116 051c190b Huacai Chen
        exit(1);
117 051c190b Huacai Chen
    }
118 051c190b Huacai Chen
119 051c190b Huacai Chen
    /* load initrd */
120 051c190b Huacai Chen
    initrd_size = 0;
121 051c190b Huacai Chen
    initrd_offset = 0;
122 051c190b Huacai Chen
    if (loaderparams.initrd_filename) {
123 051c190b Huacai Chen
        initrd_size = get_image_size (loaderparams.initrd_filename);
124 051c190b Huacai Chen
        if (initrd_size > 0) {
125 051c190b Huacai Chen
            initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
126 051c190b Huacai Chen
            if (initrd_offset + initrd_size > ram_size) {
127 051c190b Huacai Chen
                fprintf(stderr,
128 051c190b Huacai Chen
                        "qemu: memory too small for initial ram disk '%s'\n",
129 051c190b Huacai Chen
                        loaderparams.initrd_filename);
130 051c190b Huacai Chen
                exit(1);
131 051c190b Huacai Chen
            }
132 051c190b Huacai Chen
            initrd_size = load_image_targphys(loaderparams.initrd_filename,
133 051c190b Huacai Chen
                                     initrd_offset, ram_size - initrd_offset);
134 051c190b Huacai Chen
        }
135 051c190b Huacai Chen
        if (initrd_size == (target_ulong) -1) {
136 051c190b Huacai Chen
            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
137 051c190b Huacai Chen
                    loaderparams.initrd_filename);
138 051c190b Huacai Chen
            exit(1);
139 051c190b Huacai Chen
        }
140 051c190b Huacai Chen
    }
141 051c190b Huacai Chen
142 051c190b Huacai Chen
    /* Setup prom parameters. */
143 051c190b Huacai Chen
    prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
144 7267c094 Anthony Liguori
    prom_buf = g_malloc(prom_size);
145 051c190b Huacai Chen
146 1ed1139d Stefan Weil
    prom_set(prom_buf, index++, "%s", loaderparams.kernel_filename);
147 051c190b Huacai Chen
    if (initrd_size > 0) {
148 1ed1139d Stefan Weil
        prom_set(prom_buf, index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
149 051c190b Huacai Chen
                 cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
150 051c190b Huacai Chen
                 loaderparams.kernel_cmdline);
151 051c190b Huacai Chen
    } else {
152 1ed1139d Stefan Weil
        prom_set(prom_buf, index++, "%s", loaderparams.kernel_cmdline);
153 051c190b Huacai Chen
    }
154 051c190b Huacai Chen
155 051c190b Huacai Chen
    /* Setup minimum environment variables */
156 051c190b Huacai Chen
    prom_set(prom_buf, index++, "busclock=33000000");
157 051c190b Huacai Chen
    prom_set(prom_buf, index++, "cpuclock=100000000");
158 051c190b Huacai Chen
    prom_set(prom_buf, index++, "memsize=%i", loaderparams.ram_size/1024/1024);
159 051c190b Huacai Chen
    prom_set(prom_buf, index++, "modetty0=38400n8r");
160 051c190b Huacai Chen
    prom_set(prom_buf, index++, NULL);
161 051c190b Huacai Chen
162 051c190b Huacai Chen
    rom_add_blob_fixed("prom", prom_buf, prom_size,
163 051c190b Huacai Chen
                       cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
164 051c190b Huacai Chen
165 051c190b Huacai Chen
    return kernel_entry;
166 051c190b Huacai Chen
}
167 051c190b Huacai Chen
168 051c190b Huacai Chen
static void write_bootloader (CPUState *env, uint8_t *base, int64_t kernel_addr)
169 051c190b Huacai Chen
{
170 051c190b Huacai Chen
    uint32_t *p;
171 051c190b Huacai Chen
172 051c190b Huacai Chen
    /* Small bootloader */
173 051c190b Huacai Chen
    p = (uint32_t *) base;
174 051c190b Huacai Chen
175 051c190b Huacai Chen
    stl_raw(p++, 0x0bf00010);                                      /* j 0x1fc00040 */
176 051c190b Huacai Chen
    stl_raw(p++, 0x00000000);                                      /* nop */
177 051c190b Huacai Chen
178 051c190b Huacai Chen
    /* Second part of the bootloader */
179 051c190b Huacai Chen
    p = (uint32_t *) (base + 0x040);
180 051c190b Huacai Chen
181 051c190b Huacai Chen
    stl_raw(p++, 0x3c040000);                                      /* lui a0, 0 */
182 051c190b Huacai Chen
    stl_raw(p++, 0x34840002);                                      /* ori a0, a0, 2 */
183 051c190b Huacai Chen
    stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));       /* lui a1, high(ENVP_ADDR) */
184 051c190b Huacai Chen
    stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a0, low(ENVP_ADDR) */
185 051c190b Huacai Chen
    stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
186 051c190b Huacai Chen
    stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));         /* ori a2, a2, low(ENVP_ADDR + 8) */
187 051c190b Huacai Chen
    stl_raw(p++, 0x3c070000 | (loaderparams.ram_size >> 16));      /* lui a3, high(env->ram_size) */
188 051c190b Huacai Chen
    stl_raw(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff));   /* ori a3, a3, low(env->ram_size) */
189 051c190b Huacai Chen
    stl_raw(p++, 0x3c1f0000 | ((kernel_addr >> 16) & 0xffff));     /* lui ra, high(kernel_addr) */;
190 051c190b Huacai Chen
    stl_raw(p++, 0x37ff0000 | (kernel_addr & 0xffff));             /* ori ra, ra, low(kernel_addr) */
191 051c190b Huacai Chen
    stl_raw(p++, 0x03e00008);                                      /* jr ra */
192 051c190b Huacai Chen
    stl_raw(p++, 0x00000000);                                      /* nop */
193 051c190b Huacai Chen
}
194 051c190b Huacai Chen
195 051c190b Huacai Chen
196 051c190b Huacai Chen
static void main_cpu_reset(void *opaque)
197 051c190b Huacai Chen
{
198 051c190b Huacai Chen
    CPUState *env = opaque;
199 051c190b Huacai Chen
200 051c190b Huacai Chen
    cpu_reset(env);
201 051c190b Huacai Chen
    /* TODO: 2E reset stuff */
202 051c190b Huacai Chen
    if (loaderparams.kernel_filename) {
203 051c190b Huacai Chen
        env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
204 051c190b Huacai Chen
    }
205 051c190b Huacai Chen
}
206 051c190b Huacai Chen
207 051c190b Huacai Chen
uint8_t eeprom_spd[0x80] = {
208 051c190b Huacai Chen
    0x80,0x08,0x07,0x0d,0x09,0x02,0x40,0x00,0x04,0x70,
209 051c190b Huacai Chen
    0x70,0x00,0x82,0x10,0x00,0x01,0x0e,0x04,0x0c,0x01,
210 051c190b Huacai Chen
    0x02,0x20,0x80,0x75,0x70,0x00,0x00,0x50,0x3c,0x50,
211 051c190b Huacai Chen
    0x2d,0x20,0xb0,0xb0,0x50,0x50,0x00,0x00,0x00,0x00,
212 051c190b Huacai Chen
    0x00,0x41,0x48,0x3c,0x32,0x75,0x00,0x00,0x00,0x00,
213 051c190b Huacai Chen
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
214 051c190b Huacai Chen
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
215 051c190b Huacai Chen
    0x00,0x00,0x00,0x9c,0x7b,0x07,0x00,0x00,0x00,0x00,
216 051c190b Huacai Chen
    0x00,0x00,0x00,0x00,0x48,0x42,0x35,0x34,0x41,0x32,
217 051c190b Huacai Chen
    0x35,0x36,0x38,0x4b,0x4e,0x2d,0x41,0x37,0x35,0x42,
218 051c190b Huacai Chen
    0x20,0x30,0x20
219 051c190b Huacai Chen
};
220 051c190b Huacai Chen
221 051c190b Huacai Chen
/* Audio support */
222 051c190b Huacai Chen
static void audio_init (PCIBus *pci_bus)
223 051c190b Huacai Chen
{
224 7899f799 Isaku Yamahata
    vt82c686b_ac97_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 5));
225 7899f799 Isaku Yamahata
    vt82c686b_mc97_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 6));
226 051c190b Huacai Chen
}
227 051c190b Huacai Chen
228 051c190b Huacai Chen
/* Network support */
229 051c190b Huacai Chen
static void network_init (void)
230 051c190b Huacai Chen
{
231 051c190b Huacai Chen
    int i;
232 051c190b Huacai Chen
233 051c190b Huacai Chen
    for(i = 0; i < nb_nics; i++) {
234 051c190b Huacai Chen
        NICInfo *nd = &nd_table[i];
235 051c190b Huacai Chen
        const char *default_devaddr = NULL;
236 051c190b Huacai Chen
237 051c190b Huacai Chen
        if (i == 0 && (!nd->model || strcmp(nd->model, "rtl8139") == 0)) {
238 051c190b Huacai Chen
            /* The fulong board has a RTL8139 card using PCI SLOT 7 */
239 051c190b Huacai Chen
            default_devaddr = "07";
240 051c190b Huacai Chen
        }
241 051c190b Huacai Chen
242 051c190b Huacai Chen
        pci_nic_init_nofail(nd, "rtl8139", default_devaddr);
243 051c190b Huacai Chen
    }
244 051c190b Huacai Chen
}
245 051c190b Huacai Chen
246 051c190b Huacai Chen
static void cpu_request_exit(void *opaque, int irq, int level)
247 051c190b Huacai Chen
{
248 051c190b Huacai Chen
    CPUState *env = cpu_single_env;
249 051c190b Huacai Chen
250 051c190b Huacai Chen
    if (env && level) {
251 051c190b Huacai Chen
        cpu_exit(env);
252 051c190b Huacai Chen
    }
253 051c190b Huacai Chen
}
254 051c190b Huacai Chen
255 051c190b Huacai Chen
static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
256 051c190b Huacai Chen
                        const char *kernel_filename, const char *kernel_cmdline,
257 051c190b Huacai Chen
                        const char *initrd_filename, const char *cpu_model)
258 051c190b Huacai Chen
{
259 051c190b Huacai Chen
    char *filename;
260 13faf2a7 Avi Kivity
    MemoryRegion *address_space_mem = get_system_memory();
261 13faf2a7 Avi Kivity
    MemoryRegion *ram = g_new(MemoryRegion, 1);
262 13faf2a7 Avi Kivity
    MemoryRegion *bios = g_new(MemoryRegion, 1);
263 093209cd Blue Swirl
    long bios_size;
264 051c190b Huacai Chen
    int64_t kernel_entry;
265 051c190b Huacai Chen
    qemu_irq *i8259;
266 051c190b Huacai Chen
    qemu_irq *cpu_exit_irq;
267 051c190b Huacai Chen
    PCIBus *pci_bus;
268 48a18b3c Hervé Poussineau
    ISABus *isa_bus;
269 051c190b Huacai Chen
    i2c_bus *smbus;
270 051c190b Huacai Chen
    int i;
271 051c190b Huacai Chen
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
272 051c190b Huacai Chen
    CPUState *env;
273 051c190b Huacai Chen
274 051c190b Huacai Chen
    /* init CPUs */
275 051c190b Huacai Chen
    if (cpu_model == NULL) {
276 051c190b Huacai Chen
        cpu_model = "Loongson-2E";
277 051c190b Huacai Chen
    }
278 051c190b Huacai Chen
    env = cpu_init(cpu_model);
279 051c190b Huacai Chen
    if (!env) {
280 051c190b Huacai Chen
        fprintf(stderr, "Unable to find CPU definition\n");
281 051c190b Huacai Chen
        exit(1);
282 051c190b Huacai Chen
    }
283 051c190b Huacai Chen
284 0be71e32 Alex Williamson
    register_savevm(NULL, "cpu", 0, 3, cpu_save, cpu_load, env);
285 051c190b Huacai Chen
    qemu_register_reset(main_cpu_reset, env);
286 051c190b Huacai Chen
287 051c190b Huacai Chen
    /* fulong 2e has 256M ram. */
288 051c190b Huacai Chen
    ram_size = 256 * 1024 * 1024;
289 051c190b Huacai Chen
290 051c190b Huacai Chen
    /* fulong 2e has a 1M flash.Winbond W39L040AP70Z */
291 051c190b Huacai Chen
    bios_size = 1024 * 1024;
292 051c190b Huacai Chen
293 051c190b Huacai Chen
    /* allocate RAM */
294 13faf2a7 Avi Kivity
    memory_region_init_ram(ram, NULL, "fulong2e.ram", ram_size);
295 13faf2a7 Avi Kivity
    memory_region_init_ram(bios, NULL, "fulong2e.bios", bios_size);
296 13faf2a7 Avi Kivity
    memory_region_set_readonly(bios, true);
297 051c190b Huacai Chen
298 13faf2a7 Avi Kivity
    memory_region_add_subregion(address_space_mem, 0, ram);
299 13faf2a7 Avi Kivity
    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios);
300 051c190b Huacai Chen
301 051c190b Huacai Chen
    /* We do not support flash operation, just loading pmon.bin as raw BIOS.
302 051c190b Huacai Chen
     * Please use -L to set the BIOS path and -bios to set bios name. */
303 051c190b Huacai Chen
304 051c190b Huacai Chen
    if (kernel_filename) {
305 051c190b Huacai Chen
        loaderparams.ram_size = ram_size;
306 051c190b Huacai Chen
        loaderparams.kernel_filename = kernel_filename;
307 051c190b Huacai Chen
        loaderparams.kernel_cmdline = kernel_cmdline;
308 051c190b Huacai Chen
        loaderparams.initrd_filename = initrd_filename;
309 051c190b Huacai Chen
        kernel_entry = load_kernel (env);
310 13faf2a7 Avi Kivity
        write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
311 051c190b Huacai Chen
    } else {
312 33dd2983 Aurelien Jarno
        if (bios_name == NULL) {
313 33dd2983 Aurelien Jarno
                bios_name = FULONG_BIOSNAME;
314 051c190b Huacai Chen
        }
315 051c190b Huacai Chen
        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
316 051c190b Huacai Chen
        if (filename) {
317 051c190b Huacai Chen
            bios_size = load_image_targphys(filename, 0x1fc00000LL,
318 051c190b Huacai Chen
                                            BIOS_SIZE);
319 7267c094 Anthony Liguori
            g_free(filename);
320 051c190b Huacai Chen
        } else {
321 051c190b Huacai Chen
            bios_size = -1;
322 051c190b Huacai Chen
        }
323 051c190b Huacai Chen
324 33dd2983 Aurelien Jarno
        if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
325 33dd2983 Aurelien Jarno
            fprintf(stderr, "qemu: Could not load MIPS bios '%s'\n", bios_name);
326 051c190b Huacai Chen
            exit(1);
327 33dd2983 Aurelien Jarno
        }
328 051c190b Huacai Chen
    }
329 051c190b Huacai Chen
330 051c190b Huacai Chen
    /* Init internal devices */
331 051c190b Huacai Chen
    cpu_mips_irq_init_cpu(env);
332 051c190b Huacai Chen
    cpu_mips_clock_init(env);
333 051c190b Huacai Chen
334 051c190b Huacai Chen
    /* North bridge, Bonito --> IP2 */
335 051c190b Huacai Chen
    pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
336 051c190b Huacai Chen
337 051c190b Huacai Chen
    /* South bridge */
338 75717903 Isaku Yamahata
    ide_drive_get(hd, MAX_IDE_BUS);
339 051c190b Huacai Chen
340 c9940edb Hervé Poussineau
    isa_bus = vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 0));
341 c9940edb Hervé Poussineau
    if (!isa_bus) {
342 b2bedb21 Stefan Weil
        fprintf(stderr, "vt82c686b_init error\n");
343 051c190b Huacai Chen
        exit(1);
344 051c190b Huacai Chen
    }
345 051c190b Huacai Chen
346 7e17a217 Jan Kiszka
    /* Interrupt controller */
347 7e17a217 Jan Kiszka
    /* The 8259 -> IP5  */
348 48a18b3c Hervé Poussineau
    i8259 = i8259_init(isa_bus, env->irq[5]);
349 48a18b3c Hervé Poussineau
    isa_bus_irqs(isa_bus, i8259);
350 7e17a217 Jan Kiszka
351 7899f799 Isaku Yamahata
    vt82c686b_ide_init(pci_bus, hd, PCI_DEVFN(FULONG2E_VIA_SLOT, 1));
352 7899f799 Isaku Yamahata
    usb_uhci_vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 2));
353 7899f799 Isaku Yamahata
    usb_uhci_vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 3));
354 051c190b Huacai Chen
355 7899f799 Isaku Yamahata
    smbus = vt82c686b_pm_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 4),
356 051c190b Huacai Chen
                              0xeee1, NULL);
357 051c190b Huacai Chen
    /* TODO: Populate SPD eeprom data.  */
358 a88df0b9 Isaku Yamahata
    smbus_eeprom_init(smbus, 1, eeprom_spd, sizeof(eeprom_spd));
359 051c190b Huacai Chen
360 051c190b Huacai Chen
    /* init other devices */
361 48a18b3c Hervé Poussineau
    pit = pit_init(isa_bus, 0x40, 0);
362 051c190b Huacai Chen
    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
363 051c190b Huacai Chen
    DMA_init(0, cpu_exit_irq);
364 051c190b Huacai Chen
365 051c190b Huacai Chen
    /* Super I/O */
366 48a18b3c Hervé Poussineau
    isa_create_simple(isa_bus, "i8042");
367 051c190b Huacai Chen
368 48a18b3c Hervé Poussineau
    rtc_init(isa_bus, 2000, NULL);
369 051c190b Huacai Chen
370 051c190b Huacai Chen
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
371 051c190b Huacai Chen
        if (serial_hds[i]) {
372 48a18b3c Hervé Poussineau
            serial_isa_init(isa_bus, i, serial_hds[i]);
373 051c190b Huacai Chen
        }
374 051c190b Huacai Chen
    }
375 051c190b Huacai Chen
376 051c190b Huacai Chen
    if (parallel_hds[0]) {
377 48a18b3c Hervé Poussineau
        parallel_init(isa_bus, 0, parallel_hds[0]);
378 051c190b Huacai Chen
    }
379 051c190b Huacai Chen
380 051c190b Huacai Chen
    /* Sound card */
381 051c190b Huacai Chen
    audio_init(pci_bus);
382 051c190b Huacai Chen
    /* Network card */
383 051c190b Huacai Chen
    network_init();
384 051c190b Huacai Chen
}
385 051c190b Huacai Chen
386 051c190b Huacai Chen
QEMUMachine mips_fulong2e_machine = {
387 051c190b Huacai Chen
    .name = "fulong2e",
388 051c190b Huacai Chen
    .desc = "Fulong 2e mini pc",
389 051c190b Huacai Chen
    .init = mips_fulong2e_init,
390 051c190b Huacai Chen
};
391 051c190b Huacai Chen
392 051c190b Huacai Chen
static void mips_fulong2e_machine_init(void)
393 051c190b Huacai Chen
{
394 051c190b Huacai Chen
    qemu_register_machine(&mips_fulong2e_machine);
395 051c190b Huacai Chen
}
396 051c190b Huacai Chen
397 051c190b Huacai Chen
machine_init(mips_fulong2e_machine_init);