Statistics
| Branch: | Revision:

root / hw / mips_jazz.c @ 4efbe58f

History | View | Annotate | Download (8.1 kB)

1 4ce7ff6e aurel32
/*
2 4ce7ff6e aurel32
 * QEMU MIPS Jazz support
3 4ce7ff6e aurel32
 *
4 4ce7ff6e aurel32
 * Copyright (c) 2007-2008 Hervé Poussineau
5 4ce7ff6e aurel32
 *
6 4ce7ff6e aurel32
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 4ce7ff6e aurel32
 * of this software and associated documentation files (the "Software"), to deal
8 4ce7ff6e aurel32
 * in the Software without restriction, including without limitation the rights
9 4ce7ff6e aurel32
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 4ce7ff6e aurel32
 * copies of the Software, and to permit persons to whom the Software is
11 4ce7ff6e aurel32
 * furnished to do so, subject to the following conditions:
12 4ce7ff6e aurel32
 *
13 4ce7ff6e aurel32
 * The above copyright notice and this permission notice shall be included in
14 4ce7ff6e aurel32
 * all copies or substantial portions of the Software.
15 4ce7ff6e aurel32
 *
16 4ce7ff6e aurel32
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 4ce7ff6e aurel32
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 4ce7ff6e aurel32
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 4ce7ff6e aurel32
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 4ce7ff6e aurel32
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 4ce7ff6e aurel32
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 4ce7ff6e aurel32
 * THE SOFTWARE.
23 4ce7ff6e aurel32
 */
24 4ce7ff6e aurel32
25 4ce7ff6e aurel32
#include "hw.h"
26 4ce7ff6e aurel32
#include "mips.h"
27 4ce7ff6e aurel32
#include "pc.h"
28 4ce7ff6e aurel32
#include "isa.h"
29 4ce7ff6e aurel32
#include "fdc.h"
30 4ce7ff6e aurel32
#include "sysemu.h"
31 4ce7ff6e aurel32
#include "audio/audio.h"
32 4ce7ff6e aurel32
#include "boards.h"
33 4ce7ff6e aurel32
#include "net.h"
34 4ce7ff6e aurel32
#include "scsi.h"
35 4ce7ff6e aurel32
36 4ce7ff6e aurel32
#ifdef TARGET_WORDS_BIGENDIAN
37 4ce7ff6e aurel32
#define BIOS_FILENAME "mips_bios.bin"
38 4ce7ff6e aurel32
#else
39 4ce7ff6e aurel32
#define BIOS_FILENAME "mipsel_bios.bin"
40 4ce7ff6e aurel32
#endif
41 4ce7ff6e aurel32
42 4ce7ff6e aurel32
enum jazz_model_e
43 4ce7ff6e aurel32
{
44 4ce7ff6e aurel32
    JAZZ_MAGNUM,
45 c171148c aurel32
    JAZZ_PICA61,
46 4ce7ff6e aurel32
};
47 4ce7ff6e aurel32
48 4ce7ff6e aurel32
static void main_cpu_reset(void *opaque)
49 4ce7ff6e aurel32
{
50 4ce7ff6e aurel32
    CPUState *env = opaque;
51 4ce7ff6e aurel32
    cpu_reset(env);
52 4ce7ff6e aurel32
}
53 4ce7ff6e aurel32
54 4ce7ff6e aurel32
static uint32_t rtc_readb(void *opaque, target_phys_addr_t addr)
55 4ce7ff6e aurel32
{
56 4ce7ff6e aurel32
    CPUState *env = opaque;
57 4ce7ff6e aurel32
    return cpu_inw(env, 0x71);
58 4ce7ff6e aurel32
}
59 4ce7ff6e aurel32
60 4ce7ff6e aurel32
static void rtc_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
61 4ce7ff6e aurel32
{
62 4ce7ff6e aurel32
    CPUState *env = opaque;
63 4ce7ff6e aurel32
    cpu_outw(env, 0x71, val & 0xff);
64 4ce7ff6e aurel32
}
65 4ce7ff6e aurel32
66 4ce7ff6e aurel32
static CPUReadMemoryFunc *rtc_read[3] = {
67 4ce7ff6e aurel32
    rtc_readb,
68 4ce7ff6e aurel32
    rtc_readb,
69 4ce7ff6e aurel32
    rtc_readb,
70 4ce7ff6e aurel32
};
71 4ce7ff6e aurel32
72 4ce7ff6e aurel32
static CPUWriteMemoryFunc *rtc_write[3] = {
73 4ce7ff6e aurel32
    rtc_writeb,
74 4ce7ff6e aurel32
    rtc_writeb,
75 4ce7ff6e aurel32
    rtc_writeb,
76 4ce7ff6e aurel32
};
77 4ce7ff6e aurel32
78 4ce7ff6e aurel32
#ifdef HAS_AUDIO
79 4ce7ff6e aurel32
static void audio_init(qemu_irq *pic)
80 4ce7ff6e aurel32
{
81 4ce7ff6e aurel32
    struct soundhw *c;
82 4ce7ff6e aurel32
    int audio_enabled = 0;
83 4ce7ff6e aurel32
84 4ce7ff6e aurel32
    for (c = soundhw; !audio_enabled && c->name; ++c) {
85 4ce7ff6e aurel32
        audio_enabled = c->enabled;
86 4ce7ff6e aurel32
    }
87 4ce7ff6e aurel32
88 4ce7ff6e aurel32
    if (audio_enabled) {
89 4ce7ff6e aurel32
        AudioState *s;
90 4ce7ff6e aurel32
91 4ce7ff6e aurel32
        s = AUD_init();
92 4ce7ff6e aurel32
        if (s) {
93 4ce7ff6e aurel32
            for (c = soundhw; c->name; ++c) {
94 4ce7ff6e aurel32
                if (c->enabled) {
95 4ce7ff6e aurel32
                    if (c->isa) {
96 4ce7ff6e aurel32
                        c->init.init_isa(s, pic);
97 4ce7ff6e aurel32
                    }
98 4ce7ff6e aurel32
                }
99 4ce7ff6e aurel32
            }
100 4ce7ff6e aurel32
        }
101 4ce7ff6e aurel32
    }
102 4ce7ff6e aurel32
}
103 4ce7ff6e aurel32
#endif
104 4ce7ff6e aurel32
105 cd5158ea aurel32
static void espdma_memory_read(void *opaque, uint8_t *buf, int len)
106 4ce7ff6e aurel32
{
107 4ce7ff6e aurel32
    printf("espdma_memory_read(buf %p, len %d) not implemented\n", buf, len);
108 4ce7ff6e aurel32
}
109 4ce7ff6e aurel32
110 cd5158ea aurel32
static void espdma_memory_write(void *opaque, uint8_t *buf, int len)
111 4ce7ff6e aurel32
{
112 4ce7ff6e aurel32
    printf("espdma_memory_write(buf %p, len %d) not implemented\n", buf, len);
113 4ce7ff6e aurel32
}
114 4ce7ff6e aurel32
115 4ce7ff6e aurel32
#define MAGNUM_BIOS_SIZE_MAX 0x7e000
116 4ce7ff6e aurel32
#define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX)
117 4ce7ff6e aurel32
118 4ce7ff6e aurel32
static
119 00f82b8a aurel32
void mips_jazz_init (ram_addr_t ram_size, int vga_ram_size,
120 4ce7ff6e aurel32
                     DisplayState *ds, const char *cpu_model,
121 4ce7ff6e aurel32
                     enum jazz_model_e jazz_model)
122 4ce7ff6e aurel32
{
123 4ce7ff6e aurel32
    char buf[1024];
124 4ce7ff6e aurel32
    unsigned long bios_offset;
125 4ce7ff6e aurel32
    int bios_size, n;
126 4ce7ff6e aurel32
    CPUState *env;
127 4ce7ff6e aurel32
    qemu_irq *rc4030, *i8259;
128 4ce7ff6e aurel32
    void *scsi_hba;
129 4ce7ff6e aurel32
    int hd;
130 4ce7ff6e aurel32
    int s_rtc;
131 4ce7ff6e aurel32
    PITState *pit;
132 4ce7ff6e aurel32
    BlockDriverState *fds[MAX_FD];
133 4ce7ff6e aurel32
    qemu_irq esp_reset;
134 4ce7ff6e aurel32
135 4ce7ff6e aurel32
    /* init CPUs */
136 4ce7ff6e aurel32
    if (cpu_model == NULL) {
137 4ce7ff6e aurel32
#ifdef TARGET_MIPS64
138 4ce7ff6e aurel32
        cpu_model = "R4000";
139 4ce7ff6e aurel32
#else
140 4ce7ff6e aurel32
        /* FIXME: All wrong, this maybe should be R3000 for the older JAZZs. */
141 4ce7ff6e aurel32
        cpu_model = "24Kf";
142 4ce7ff6e aurel32
#endif
143 4ce7ff6e aurel32
    }
144 4ce7ff6e aurel32
    env = cpu_init(cpu_model);
145 4ce7ff6e aurel32
    if (!env) {
146 4ce7ff6e aurel32
        fprintf(stderr, "Unable to find CPU definition\n");
147 4ce7ff6e aurel32
        exit(1);
148 4ce7ff6e aurel32
    }
149 4ce7ff6e aurel32
    qemu_register_reset(main_cpu_reset, env);
150 4ce7ff6e aurel32
151 4ce7ff6e aurel32
    /* allocate RAM */
152 4ce7ff6e aurel32
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
153 4ce7ff6e aurel32
154 4ce7ff6e aurel32
    /* load the BIOS image. */
155 4ce7ff6e aurel32
    bios_offset = ram_size + vga_ram_size;
156 4ce7ff6e aurel32
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
157 4ce7ff6e aurel32
    bios_size = load_image(buf, phys_ram_base + bios_offset);
158 4ce7ff6e aurel32
    if (bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) {
159 4ce7ff6e aurel32
        fprintf(stderr, "qemu: Could not load MIPS bios '%s'\n",
160 4ce7ff6e aurel32
                buf);
161 4ce7ff6e aurel32
        exit(1);
162 4ce7ff6e aurel32
    }
163 4ce7ff6e aurel32
164 4ce7ff6e aurel32
    cpu_register_physical_memory(0x1fc00000LL,
165 4ce7ff6e aurel32
                                 MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM);
166 4ce7ff6e aurel32
    cpu_register_physical_memory(0xfff00000LL,
167 4ce7ff6e aurel32
                                 MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM);
168 4ce7ff6e aurel32
169 4ce7ff6e aurel32
    /* Init CPU internal devices */
170 4ce7ff6e aurel32
    cpu_mips_irq_init_cpu(env);
171 4ce7ff6e aurel32
    cpu_mips_clock_init(env);
172 4ce7ff6e aurel32
173 4ce7ff6e aurel32
    /* Chipset */
174 4ce7ff6e aurel32
    rc4030 = rc4030_init(env->irq[6], env->irq[3]);
175 4ce7ff6e aurel32
176 4ce7ff6e aurel32
    /* ISA devices */
177 4ce7ff6e aurel32
    i8259 = i8259_init(env->irq[4]);
178 4ce7ff6e aurel32
    pit = pit_init(0x40, i8259[0]);
179 4ce7ff6e aurel32
    pcspk_init(pit);
180 4ce7ff6e aurel32
181 4ce7ff6e aurel32
    /* ISA IO space at 0x90000000 */
182 4ce7ff6e aurel32
    isa_mmio_init(0x90000000, 0x01000000);
183 4ce7ff6e aurel32
    isa_mem_base = 0x11000000;
184 4ce7ff6e aurel32
185 4ce7ff6e aurel32
    /* Video card */
186 4ce7ff6e aurel32
    switch (jazz_model) {
187 4ce7ff6e aurel32
    case JAZZ_MAGNUM:
188 4ce7ff6e aurel32
        g364fb_mm_init(ds, vga_ram_size, 0, 0x40000000, 0x60000000);
189 4ce7ff6e aurel32
        break;
190 c171148c aurel32
    case JAZZ_PICA61:
191 c171148c aurel32
        isa_vga_mm_init(ds, phys_ram_base + ram_size, ram_size, vga_ram_size,
192 c171148c aurel32
                        0x40000000, 0x60000000, 0);
193 c171148c aurel32
        break;
194 4ce7ff6e aurel32
    default:
195 4ce7ff6e aurel32
        break;
196 4ce7ff6e aurel32
    }
197 4ce7ff6e aurel32
198 4ce7ff6e aurel32
    /* Network controller */
199 4ce7ff6e aurel32
    /* FIXME: missing NS SONIC DP83932 */
200 4ce7ff6e aurel32
201 4ce7ff6e aurel32
    /* SCSI adapter */
202 5d20fa6b blueswir1
    scsi_hba = esp_init(0x80002000, 0,
203 4ce7ff6e aurel32
                        espdma_memory_read, espdma_memory_write, NULL,
204 4ce7ff6e aurel32
                        rc4030[5], &esp_reset);
205 4ce7ff6e aurel32
    for (n = 0; n < ESP_MAX_DEVS; n++) {
206 4ce7ff6e aurel32
        hd = drive_get_index(IF_SCSI, 0, n);
207 4ce7ff6e aurel32
        if (hd != -1) {
208 4ce7ff6e aurel32
            esp_scsi_attach(scsi_hba, drives_table[hd].bdrv, n);
209 4ce7ff6e aurel32
        }
210 4ce7ff6e aurel32
    }
211 4ce7ff6e aurel32
212 4ce7ff6e aurel32
    /* Floppy */
213 4ce7ff6e aurel32
    if (drive_get_max_bus(IF_FLOPPY) >= MAX_FD) {
214 4ce7ff6e aurel32
        fprintf(stderr, "qemu: too many floppy drives\n");
215 4ce7ff6e aurel32
        exit(1);
216 4ce7ff6e aurel32
    }
217 4ce7ff6e aurel32
    for (n = 0; n < MAX_FD; n++) {
218 4ce7ff6e aurel32
        int fd = drive_get_index(IF_FLOPPY, 0, n);
219 4ce7ff6e aurel32
        if (fd != -1)
220 4ce7ff6e aurel32
            fds[n] = drives_table[fd].bdrv;
221 4ce7ff6e aurel32
        else
222 4ce7ff6e aurel32
            fds[n] = NULL;
223 4ce7ff6e aurel32
    }
224 4ce7ff6e aurel32
    fdctrl_init(rc4030[1], 0, 1, 0x80003000, fds);
225 4ce7ff6e aurel32
226 4ce7ff6e aurel32
    /* Real time clock */
227 4ce7ff6e aurel32
    rtc_init(0x70, i8259[8]);
228 4ce7ff6e aurel32
    s_rtc = cpu_register_io_memory(0, rtc_read, rtc_write, env);
229 4ce7ff6e aurel32
    cpu_register_physical_memory(0x80004000, 0x00001000, s_rtc);
230 4ce7ff6e aurel32
231 4ce7ff6e aurel32
    /* Keyboard (i8042) */
232 4efbe58f aurel32
    i8042_mm_init(rc4030[6], rc4030[7], 0x80005000, 0x1000, 0x1);
233 4ce7ff6e aurel32
234 4ce7ff6e aurel32
    /* Serial ports */
235 4ce7ff6e aurel32
    if (serial_hds[0])
236 b6cd0ea1 aurel32
        serial_mm_init(0x80006000, 0, rc4030[8], 8000000/16, serial_hds[0], 1);
237 4ce7ff6e aurel32
    if (serial_hds[1])
238 b6cd0ea1 aurel32
        serial_mm_init(0x80007000, 0, rc4030[9], 8000000/16, serial_hds[1], 1);
239 4ce7ff6e aurel32
240 4ce7ff6e aurel32
    /* Parallel port */
241 4ce7ff6e aurel32
    if (parallel_hds[0])
242 4ce7ff6e aurel32
        parallel_mm_init(0x80008000, 0, rc4030[0], parallel_hds[0]);
243 4ce7ff6e aurel32
244 4ce7ff6e aurel32
    /* Sound card */
245 4ce7ff6e aurel32
    /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */
246 4ce7ff6e aurel32
#ifdef HAS_AUDIO
247 4ce7ff6e aurel32
    audio_init(i8259);
248 4ce7ff6e aurel32
#endif
249 4ce7ff6e aurel32
250 4ce7ff6e aurel32
    /* NVRAM: Unprotected at 0x9000, Protected at 0xa000, Read only at 0xb000 */
251 4ce7ff6e aurel32
    ds1225y_init(0x80009000, "nvram");
252 4ce7ff6e aurel32
253 4ce7ff6e aurel32
    /* LED indicator */
254 4ce7ff6e aurel32
    jazz_led_init(ds, 0x8000f000);
255 4ce7ff6e aurel32
}
256 4ce7ff6e aurel32
257 4ce7ff6e aurel32
static
258 00f82b8a aurel32
void mips_magnum_init (ram_addr_t ram_size, int vga_ram_size,
259 4ce7ff6e aurel32
                       const char *boot_device, DisplayState *ds,
260 4ce7ff6e aurel32
                       const char *kernel_filename, const char *kernel_cmdline,
261 4ce7ff6e aurel32
                       const char *initrd_filename, const char *cpu_model)
262 4ce7ff6e aurel32
{
263 4ce7ff6e aurel32
    mips_jazz_init(ram_size, vga_ram_size, ds, cpu_model, JAZZ_MAGNUM);
264 4ce7ff6e aurel32
}
265 4ce7ff6e aurel32
266 c171148c aurel32
static
267 00f82b8a aurel32
void mips_pica61_init (ram_addr_t ram_size, int vga_ram_size,
268 c171148c aurel32
                       const char *boot_device, DisplayState *ds,
269 c171148c aurel32
                       const char *kernel_filename, const char *kernel_cmdline,
270 c171148c aurel32
                       const char *initrd_filename, const char *cpu_model)
271 c171148c aurel32
{
272 c171148c aurel32
    mips_jazz_init(ram_size, vga_ram_size, ds, cpu_model, JAZZ_PICA61);
273 c171148c aurel32
}
274 c171148c aurel32
275 4ce7ff6e aurel32
QEMUMachine mips_magnum_machine = {
276 eec2743e ths
    .name = "magnum",
277 eec2743e ths
    .desc = "MIPS Magnum",
278 eec2743e ths
    .init = mips_magnum_init,
279 eec2743e ths
    .ram_require = MAGNUM_BIOS_SIZE + VGA_RAM_SIZE,
280 eec2743e ths
    .nodisk_ok = 1,
281 4ce7ff6e aurel32
};
282 c171148c aurel32
283 c171148c aurel32
QEMUMachine mips_pica61_machine = {
284 eec2743e ths
    .name = "pica61",
285 eec2743e ths
    .desc = "Acer Pica 61",
286 eec2743e ths
    .init = mips_pica61_init,
287 eec2743e ths
    .ram_require = MAGNUM_BIOS_SIZE + VGA_RAM_SIZE,
288 eec2743e ths
    .nodisk_ok = 1,
289 c171148c aurel32
};