Statistics
| Branch: | Revision:

root / hw / mips_r4k.c @ 5dc4b744

History | View | Annotate | Download (6.5 kB)

1
/*
2
 * QEMU/MIPS pseudo-board
3
 *
4
 * emulates a simple machine with ISA-like bus.
5
 * ISA IO space mapped to the 0x14000000 (PHYS) and
6
 * ISA memory at the 0x10000000 (PHYS, 16Mb in size).
7
 * All peripherial devices are attached to this "bus" with
8
 * the standard PC ISA addresses.
9
*/
10
#include "vl.h"
11

    
12
#define BIOS_FILENAME "mips_bios.bin"
13
//#define BIOS_FILENAME "system.bin"
14
#define KERNEL_LOAD_ADDR (int32_t)0x80010000
15
#ifdef MIPS_HAS_MIPS64
16
#define INITRD_LOAD_ADDR (int64_t)0x80800000
17
#else
18
#define INITRD_LOAD_ADDR (int32_t)0x80800000
19
#endif
20

    
21
#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
22

    
23
static const int ide_iobase[2] = { 0x1f0, 0x170 };
24
static const int ide_iobase2[2] = { 0x3f6, 0x376 };
25
static const int ide_irq[2] = { 14, 15 };
26

    
27
extern FILE *logfile;
28

    
29
static PITState *pit; /* PIT i8254 */
30

    
31
/*i8254 PIT is attached to the IRQ0 at PIC i8259 */
32
/*The PIC is attached to the MIPS CPU INT0 pin */
33
static void pic_irq_request(void *opaque, int level)
34
{
35
    CPUState *env = first_cpu;
36
    if (level) {
37
        env->CP0_Cause |= 0x00000400;
38
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
39
    } else {
40
        env->CP0_Cause &= ~0x00000400;
41
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
42
    }
43
}
44

    
45
static void mips_qemu_writel (void *opaque, target_phys_addr_t addr,
46
                              uint32_t val)
47
{
48
    if ((addr & 0xffff) == 0 && val == 42)
49
        qemu_system_reset_request ();
50
    else if ((addr & 0xffff) == 4 && val == 42)
51
        qemu_system_shutdown_request ();
52
}
53

    
54
static uint32_t mips_qemu_readl (void *opaque, target_phys_addr_t addr)
55
{
56
    return 0;
57
}
58

    
59
static CPUWriteMemoryFunc *mips_qemu_write[] = {
60
    &mips_qemu_writel,
61
    &mips_qemu_writel,
62
    &mips_qemu_writel,
63
};
64

    
65
static CPUReadMemoryFunc *mips_qemu_read[] = {
66
    &mips_qemu_readl,
67
    &mips_qemu_readl,
68
    &mips_qemu_readl,
69
};
70

    
71
static int mips_qemu_iomemtype = 0;
72

    
73
void load_kernel (CPUState *env, int ram_size, const char *kernel_filename,
74
                  const char *kernel_cmdline,
75
                  const char *initrd_filename)
76
{
77
    int64_t entry = 0;
78
    long kernel_size, initrd_size;
79

    
80
    kernel_size = load_elf(kernel_filename, VIRT_TO_PHYS_ADDEND, &entry);
81
    if (kernel_size >= 0) {
82
        if ((entry & ~0x7fffffffULL) == 0x80000000)
83
            entry = (int32_t)entry;
84
        env->PC = entry;
85
    } else {
86
        kernel_size = load_image(kernel_filename,
87
                                 phys_ram_base + KERNEL_LOAD_ADDR + VIRT_TO_PHYS_ADDEND);
88
        if (kernel_size < 0) {
89
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
90
                    kernel_filename);
91
            exit(1);
92
        }
93
        env->PC = KERNEL_LOAD_ADDR;
94
    }
95

    
96
    /* load initrd */
97
    initrd_size = 0;
98
    if (initrd_filename) {
99
        initrd_size = load_image(initrd_filename,
100
                                 phys_ram_base + INITRD_LOAD_ADDR + VIRT_TO_PHYS_ADDEND);
101
        if (initrd_size == (target_ulong) -1) {
102
            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
103
                    initrd_filename);
104
            exit(1);
105
        }
106
    }
107

    
108
    /* Store command line.  */
109
    if (initrd_size > 0) {
110
        int ret;
111
        ret = sprintf(phys_ram_base + (16 << 20) - 256,
112
                      "rd_start=0x" TLSZ " rd_size=%li ",
113
                      INITRD_LOAD_ADDR,
114
                      initrd_size);
115
        strcpy (phys_ram_base + (16 << 20) - 256 + ret, kernel_cmdline);
116
    }
117
    else {
118
        strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline);
119
    }
120

    
121
    *(int *)(phys_ram_base + (16 << 20) - 260) = tswap32 (0x12345678);
122
    *(int *)(phys_ram_base + (16 << 20) - 264) = tswap32 (ram_size);
123
}
124

    
125
static void main_cpu_reset(void *opaque)
126
{
127
    CPUState *env = opaque;
128
    cpu_reset(env);
129

    
130
    if (env->kernel_filename)
131
        load_kernel (env, env->ram_size, env->kernel_filename,
132
                     env->kernel_cmdline, env->initrd_filename);
133
}
134

    
135
void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
136
                    DisplayState *ds, const char **fd_filename, int snapshot,
137
                    const char *kernel_filename, const char *kernel_cmdline,
138
                    const char *initrd_filename)
139
{
140
    char buf[1024];
141
    unsigned long bios_offset;
142
    int ret;
143
    CPUState *env;
144
    static RTCState *rtc_state;
145
    int i;
146

    
147
    env = cpu_init();
148
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
149
    qemu_register_reset(main_cpu_reset, env);
150

    
151
    /* allocate RAM */
152
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
153

    
154
    if (!mips_qemu_iomemtype) {
155
        mips_qemu_iomemtype = cpu_register_io_memory(0, mips_qemu_read,
156
                                                     mips_qemu_write, NULL);
157
    }
158
    cpu_register_physical_memory(0x1fbf0000, 0x10000, mips_qemu_iomemtype);
159

    
160
    /* Try to load a BIOS image. If this fails, we continue regardless,
161
       but initialize the hardware ourselves. When a kernel gets
162
       preloaded we also initialize the hardware, since the BIOS wasn't
163
       run. */
164
    bios_offset = ram_size + vga_ram_size;
165
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
166
    ret = load_image(buf, phys_ram_base + bios_offset);
167
    if (ret == BIOS_SIZE) {
168
        cpu_register_physical_memory((uint32_t)(0x1fc00000),
169
                                     BIOS_SIZE, bios_offset | IO_MEM_ROM);
170
    } else {
171
        /* not fatal */
172
        fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
173
                buf);
174
    }
175

    
176
    if (kernel_filename) {
177
        load_kernel (env, ram_size, kernel_filename, kernel_cmdline,
178
                     initrd_filename);
179
        env->ram_size = ram_size;
180
        env->kernel_filename = kernel_filename;
181
        env->kernel_cmdline = kernel_cmdline;
182
        env->initrd_filename = initrd_filename;
183
    }
184

    
185
    /* Init CPU internal devices */
186
    cpu_mips_clock_init(env);
187
    cpu_mips_irqctrl_init();
188

    
189
    rtc_state = rtc_init(0x70, 8);
190

    
191
    /* Register 64 KB of ISA IO space at 0x14000000 */
192
    isa_mmio_init(0x14000000, 0x00010000);
193
    isa_mem_base = 0x10000000;
194

    
195
    isa_pic = pic_init(pic_irq_request, env);
196
    pit = pit_init(0x40, 0);
197

    
198
    serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
199
    isa_vga_init(ds, phys_ram_base + ram_size, ram_size, 
200
                 vga_ram_size);
201

    
202
    if (nd_table[0].vlan) {
203
        if (nd_table[0].model == NULL
204
            || strcmp(nd_table[0].model, "ne2k_isa") == 0) {
205
            isa_ne2000_init(0x300, 9, &nd_table[0]);
206
        } else {
207
            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
208
            exit (1);
209
        }
210
    }
211

    
212
    for(i = 0; i < 2; i++)
213
        isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
214
                     bs_table[2 * i], bs_table[2 * i + 1]);
215
}
216

    
217
QEMUMachine mips_machine = {
218
    "mips",
219
    "mips r4k platform",
220
    mips_r4k_init,
221
};