Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ 50d3eeae

History | View | Annotate | Download (20.6 kB)

1 5856de80 ths
/*
2 5856de80 ths
 * QEMU Malta board support
3 5856de80 ths
 *
4 5856de80 ths
 * Copyright (c) 2006 Aurelien Jarno
5 5856de80 ths
 *
6 5856de80 ths
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 5856de80 ths
 * of this software and associated documentation files (the "Software"), to deal
8 5856de80 ths
 * in the Software without restriction, including without limitation the rights
9 5856de80 ths
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 5856de80 ths
 * copies of the Software, and to permit persons to whom the Software is
11 5856de80 ths
 * furnished to do so, subject to the following conditions:
12 5856de80 ths
 *
13 5856de80 ths
 * The above copyright notice and this permission notice shall be included in
14 5856de80 ths
 * all copies or substantial portions of the Software.
15 5856de80 ths
 *
16 5856de80 ths
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 5856de80 ths
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 5856de80 ths
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 5856de80 ths
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 5856de80 ths
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 5856de80 ths
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 5856de80 ths
 * THE SOFTWARE.
23 5856de80 ths
 */
24 5856de80 ths
25 5856de80 ths
#include "vl.h"
26 5856de80 ths
27 44cbbf18 ths
#ifdef TARGET_WORDS_BIGENDIAN
28 44cbbf18 ths
#define BIOS_FILENAME "mips_bios.bin"
29 44cbbf18 ths
#else
30 44cbbf18 ths
#define BIOS_FILENAME "mipsel_bios.bin"
31 44cbbf18 ths
#endif
32 44cbbf18 ths
33 5856de80 ths
#ifdef MIPS_HAS_MIPS64
34 44cbbf18 ths
#define INITRD_LOAD_ADDR         (int64_t)0x80800000
35 5856de80 ths
#else
36 44cbbf18 ths
#define INITRD_LOAD_ADDR         (int32_t)0x80800000
37 5856de80 ths
#endif
38 5856de80 ths
39 3ddd0065 ths
#define ENVP_ADDR                (int32_t)0x80002000
40 44cbbf18 ths
#define VIRT_TO_PHYS_ADDEND         (-((int64_t)(int32_t)0x80000000))
41 5856de80 ths
42 5856de80 ths
#define ENVP_NB_ENTRIES                 16
43 5856de80 ths
#define ENVP_ENTRY_SIZE                 256
44 5856de80 ths
45 5856de80 ths
46 5856de80 ths
extern FILE *logfile;
47 5856de80 ths
48 5856de80 ths
typedef struct {
49 5856de80 ths
    uint32_t leds;
50 5856de80 ths
    uint32_t brk;
51 5856de80 ths
    uint32_t gpout;
52 130751ee ths
    uint32_t i2cin;
53 5856de80 ths
    uint32_t i2coe;
54 5856de80 ths
    uint32_t i2cout;
55 5856de80 ths
    uint32_t i2csel;
56 5856de80 ths
    CharDriverState *display;
57 5856de80 ths
    char display_text[9];
58 5856de80 ths
} MaltaFPGAState;
59 5856de80 ths
60 5856de80 ths
static PITState *pit;
61 5856de80 ths
62 4de9b249 ths
/* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
63 5856de80 ths
static void pic_irq_request(void *opaque, int level)
64 5856de80 ths
{
65 4de9b249 ths
    cpu_mips_irq_request(opaque, 2, level);
66 5856de80 ths
}
67 5856de80 ths
68 5856de80 ths
/* Malta FPGA */
69 5856de80 ths
static void malta_fpga_update_display(void *opaque)
70 5856de80 ths
{
71 5856de80 ths
    char leds_text[9];
72 5856de80 ths
    int i;
73 5856de80 ths
    MaltaFPGAState *s = opaque;
74 5856de80 ths
75 5856de80 ths
    for (i = 7 ; i >= 0 ; i--) {
76 5856de80 ths
        if (s->leds & (1 << i))
77 5856de80 ths
            leds_text[i] = '#';
78 5856de80 ths
        else
79 5856de80 ths
            leds_text[i] = ' ';
80 5856de80 ths
    }
81 5856de80 ths
    leds_text[8] = '\0';
82 5856de80 ths
83 472c5273 ths
    qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
84 472c5273 ths
    qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
85 5856de80 ths
}
86 5856de80 ths
87 130751ee ths
/*
88 130751ee ths
 * EEPROM 24C01 / 24C02 emulation.
89 130751ee ths
 *
90 130751ee ths
 * Emulation for serial EEPROMs:
91 130751ee ths
 * 24C01 - 1024 bit (128 x 8)
92 130751ee ths
 * 24C02 - 2048 bit (256 x 8)
93 130751ee ths
 *
94 130751ee ths
 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
95 130751ee ths
 */
96 130751ee ths
97 130751ee ths
//~ #define DEBUG
98 130751ee ths
99 130751ee ths
#if defined(DEBUG)
100 130751ee ths
#  define logout(fmt, args...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ##args)
101 130751ee ths
#else
102 130751ee ths
#  define logout(fmt, args...) ((void)0)
103 130751ee ths
#endif
104 130751ee ths
105 130751ee ths
struct _eeprom24c0x_t {
106 130751ee ths
  uint8_t tick;
107 130751ee ths
  uint8_t address;
108 130751ee ths
  uint8_t command;
109 130751ee ths
  uint8_t ack;
110 130751ee ths
  uint8_t scl;
111 130751ee ths
  uint8_t sda;
112 130751ee ths
  uint8_t data;
113 130751ee ths
  //~ uint16_t size;
114 130751ee ths
  uint8_t contents[256];
115 130751ee ths
};
116 130751ee ths
117 130751ee ths
typedef struct _eeprom24c0x_t eeprom24c0x_t;
118 130751ee ths
119 130751ee ths
static eeprom24c0x_t eeprom = {
120 130751ee ths
    contents: {
121 130751ee ths
        /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
122 130751ee ths
        /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
123 130751ee ths
        /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
124 130751ee ths
        /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
125 130751ee ths
        /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
126 130751ee ths
        /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
127 130751ee ths
        /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128 130751ee ths
        /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
129 130751ee ths
        /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130 130751ee ths
        /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131 130751ee ths
        /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132 130751ee ths
        /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133 130751ee ths
        /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134 130751ee ths
        /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135 130751ee ths
        /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
136 130751ee ths
        /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
137 130751ee ths
    },
138 130751ee ths
};
139 130751ee ths
140 130751ee ths
static uint8_t eeprom24c0x_read()
141 130751ee ths
{
142 130751ee ths
    logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
143 130751ee ths
        eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
144 130751ee ths
    return eeprom.sda;
145 130751ee ths
}
146 130751ee ths
147 130751ee ths
static void eeprom24c0x_write(int scl, int sda)
148 130751ee ths
{
149 130751ee ths
    if (eeprom.scl && scl && (eeprom.sda != sda)) {
150 130751ee ths
        logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
151 130751ee ths
                eeprom.tick, eeprom.scl, scl, eeprom.sda, sda, sda ? "stop" : "start");
152 130751ee ths
        if (!sda) {
153 130751ee ths
            eeprom.tick = 1;
154 130751ee ths
            eeprom.command = 0;
155 130751ee ths
        }
156 130751ee ths
    } else if (eeprom.tick == 0 && !eeprom.ack) {
157 130751ee ths
        /* Waiting for start. */
158 130751ee ths
        logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
159 130751ee ths
                eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
160 130751ee ths
    } else if (!eeprom.scl && scl) {
161 130751ee ths
        logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
162 130751ee ths
                eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
163 130751ee ths
        if (eeprom.ack) {
164 130751ee ths
            logout("\ti2c ack bit = 0\n");
165 130751ee ths
            sda = 0;
166 130751ee ths
            eeprom.ack = 0;
167 130751ee ths
        } else if (eeprom.sda == sda) {
168 130751ee ths
            uint8_t bit = (sda != 0);
169 130751ee ths
            logout("\ti2c bit = %d\n", bit);
170 130751ee ths
            if (eeprom.tick < 9) {
171 130751ee ths
                eeprom.command <<= 1;
172 130751ee ths
                eeprom.command += bit;
173 130751ee ths
                eeprom.tick++;
174 130751ee ths
                if (eeprom.tick == 9) {
175 130751ee ths
                    logout("\tcommand 0x%04x, %s\n", eeprom.command, bit ? "read" : "write");
176 130751ee ths
                    eeprom.ack = 1;
177 130751ee ths
                }
178 130751ee ths
            } else if (eeprom.tick < 17) {
179 130751ee ths
                if (eeprom.command & 1) {
180 130751ee ths
                    sda = ((eeprom.data & 0x80) != 0);
181 130751ee ths
                }
182 130751ee ths
                eeprom.address <<= 1;
183 130751ee ths
                eeprom.address += bit;
184 130751ee ths
                eeprom.tick++;
185 130751ee ths
                eeprom.data <<= 1;
186 130751ee ths
                if (eeprom.tick == 17) {
187 130751ee ths
                    eeprom.data = eeprom.contents[eeprom.address];
188 130751ee ths
                    logout("\taddress 0x%04x, data 0x%02x\n", eeprom.address, eeprom.data);
189 130751ee ths
                    eeprom.ack = 1;
190 130751ee ths
                    eeprom.tick = 0;
191 130751ee ths
                }
192 130751ee ths
            } else if (eeprom.tick >= 17) {
193 130751ee ths
                sda = 0;
194 130751ee ths
            }
195 130751ee ths
        } else {
196 130751ee ths
            logout("\tsda changed with raising scl\n");
197 130751ee ths
        }
198 130751ee ths
    } else {
199 130751ee ths
        logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
200 130751ee ths
    }
201 130751ee ths
    eeprom.scl = scl;
202 130751ee ths
    eeprom.sda = sda;
203 130751ee ths
}
204 130751ee ths
205 5856de80 ths
static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
206 5856de80 ths
{
207 5856de80 ths
    MaltaFPGAState *s = opaque;
208 5856de80 ths
    uint32_t val = 0;
209 5856de80 ths
    uint32_t saddr;
210 5856de80 ths
211 5856de80 ths
    saddr = (addr & 0xfffff);
212 5856de80 ths
213 5856de80 ths
    switch (saddr) {
214 5856de80 ths
215 5856de80 ths
    /* SWITCH Register */
216 5856de80 ths
    case 0x00200:
217 5856de80 ths
        val = 0x00000000;                /* All switches closed */
218 5856de80 ths
        break;
219 5856de80 ths
220 5856de80 ths
    /* STATUS Register */
221 5856de80 ths
    case 0x00208:
222 5856de80 ths
#ifdef TARGET_WORDS_BIGENDIAN
223 5856de80 ths
        val = 0x00000012;
224 5856de80 ths
#else
225 5856de80 ths
        val = 0x00000010;
226 5856de80 ths
#endif
227 5856de80 ths
        break;
228 5856de80 ths
229 5856de80 ths
    /* JMPRS Register */
230 5856de80 ths
    case 0x00210:
231 5856de80 ths
        val = 0x00;
232 5856de80 ths
        break;
233 5856de80 ths
234 5856de80 ths
    /* LEDBAR Register */
235 5856de80 ths
    case 0x00408:
236 5856de80 ths
        val = s->leds;
237 5856de80 ths
        break;
238 5856de80 ths
239 5856de80 ths
    /* BRKRES Register */
240 5856de80 ths
    case 0x00508:
241 5856de80 ths
        val = s->brk;
242 5856de80 ths
        break;
243 5856de80 ths
244 5856de80 ths
    /* GPOUT Register */
245 5856de80 ths
    case 0x00a00:
246 5856de80 ths
        val = s->gpout;
247 5856de80 ths
        break;
248 5856de80 ths
249 5856de80 ths
    /* XXX: implement a real I2C controller */
250 5856de80 ths
251 5856de80 ths
    /* GPINP Register */
252 5856de80 ths
    case 0x00a08:
253 5856de80 ths
        /* IN = OUT until a real I2C control is implemented */
254 5856de80 ths
        if (s->i2csel)
255 5856de80 ths
            val = s->i2cout;
256 5856de80 ths
        else
257 5856de80 ths
            val = 0x00;
258 5856de80 ths
        break;
259 5856de80 ths
260 5856de80 ths
    /* I2CINP Register */
261 5856de80 ths
    case 0x00b00:
262 130751ee ths
        val = ((s->i2cin & ~1) | eeprom24c0x_read());
263 5856de80 ths
        break;
264 5856de80 ths
265 5856de80 ths
    /* I2COE Register */
266 5856de80 ths
    case 0x00b08:
267 5856de80 ths
        val = s->i2coe;
268 5856de80 ths
        break;
269 5856de80 ths
270 5856de80 ths
    /* I2COUT Register */
271 5856de80 ths
    case 0x00b10:
272 5856de80 ths
        val = s->i2cout;
273 5856de80 ths
        break;
274 5856de80 ths
275 5856de80 ths
    /* I2CSEL Register */
276 5856de80 ths
    case 0x00b18:
277 130751ee ths
        val = s->i2csel;
278 5856de80 ths
        break;
279 5856de80 ths
280 5856de80 ths
    default:
281 5856de80 ths
#if 0
282 3594c774 ths
        printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
283 44cbbf18 ths
                addr);
284 5856de80 ths
#endif
285 5856de80 ths
        break;
286 5856de80 ths
    }
287 5856de80 ths
    return val;
288 5856de80 ths
}
289 5856de80 ths
290 5856de80 ths
static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
291 5856de80 ths
                              uint32_t val)
292 5856de80 ths
{
293 5856de80 ths
    MaltaFPGAState *s = opaque;
294 5856de80 ths
    uint32_t saddr;
295 5856de80 ths
296 5856de80 ths
    saddr = (addr & 0xfffff);
297 5856de80 ths
298 5856de80 ths
    switch (saddr) {
299 5856de80 ths
300 5856de80 ths
    /* SWITCH Register */
301 5856de80 ths
    case 0x00200:
302 5856de80 ths
        break;
303 5856de80 ths
304 5856de80 ths
    /* JMPRS Register */
305 5856de80 ths
    case 0x00210:
306 5856de80 ths
        break;
307 5856de80 ths
308 5856de80 ths
    /* LEDBAR Register */
309 5856de80 ths
    /* XXX: implement a 8-LED array */
310 5856de80 ths
    case 0x00408:
311 5856de80 ths
        s->leds = val & 0xff;
312 5856de80 ths
        break;
313 5856de80 ths
314 5856de80 ths
    /* ASCIIWORD Register */
315 5856de80 ths
    case 0x00410:
316 5856de80 ths
        snprintf(s->display_text, 9, "%08X", val);
317 5856de80 ths
        malta_fpga_update_display(s);
318 5856de80 ths
        break;
319 5856de80 ths
320 5856de80 ths
    /* ASCIIPOS0 to ASCIIPOS7 Registers */
321 5856de80 ths
    case 0x00418:
322 5856de80 ths
    case 0x00420:
323 5856de80 ths
    case 0x00428:
324 5856de80 ths
    case 0x00430:
325 5856de80 ths
    case 0x00438:
326 5856de80 ths
    case 0x00440:
327 5856de80 ths
    case 0x00448:
328 5856de80 ths
    case 0x00450:
329 5856de80 ths
        s->display_text[(saddr - 0x00418) >> 3] = (char) val;
330 5856de80 ths
        malta_fpga_update_display(s);
331 5856de80 ths
        break;
332 5856de80 ths
333 5856de80 ths
    /* SOFTRES Register */
334 5856de80 ths
    case 0x00500:
335 5856de80 ths
        if (val == 0x42)
336 5856de80 ths
            qemu_system_reset_request ();
337 5856de80 ths
        break;
338 5856de80 ths
339 5856de80 ths
    /* BRKRES Register */
340 5856de80 ths
    case 0x00508:
341 5856de80 ths
        s->brk = val & 0xff;
342 5856de80 ths
        break;
343 5856de80 ths
344 5856de80 ths
    /* GPOUT Register */
345 5856de80 ths
    case 0x00a00:
346 5856de80 ths
        s->gpout = val & 0xff;
347 5856de80 ths
        break;
348 5856de80 ths
349 5856de80 ths
    /* I2COE Register */
350 5856de80 ths
    case 0x00b08:
351 5856de80 ths
        s->i2coe = val & 0x03;
352 5856de80 ths
        break;
353 5856de80 ths
354 5856de80 ths
    /* I2COUT Register */
355 5856de80 ths
    case 0x00b10:
356 130751ee ths
        eeprom24c0x_write(val & 0x02, val & 0x01);
357 130751ee ths
        s->i2cout = val;
358 5856de80 ths
        break;
359 5856de80 ths
360 5856de80 ths
    /* I2CSEL Register */
361 5856de80 ths
    case 0x00b18:
362 130751ee ths
        s->i2csel = val & 0x01;
363 5856de80 ths
        break;
364 5856de80 ths
365 5856de80 ths
    default:
366 5856de80 ths
#if 0
367 3594c774 ths
        printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
368 44cbbf18 ths
                addr);
369 5856de80 ths
#endif
370 5856de80 ths
        break;
371 5856de80 ths
    }
372 5856de80 ths
}
373 5856de80 ths
374 5856de80 ths
static CPUReadMemoryFunc *malta_fpga_read[] = {
375 5856de80 ths
   malta_fpga_readl,
376 5856de80 ths
   malta_fpga_readl,
377 5856de80 ths
   malta_fpga_readl
378 5856de80 ths
};
379 5856de80 ths
380 5856de80 ths
static CPUWriteMemoryFunc *malta_fpga_write[] = {
381 5856de80 ths
   malta_fpga_writel,
382 5856de80 ths
   malta_fpga_writel,
383 5856de80 ths
   malta_fpga_writel
384 5856de80 ths
};
385 5856de80 ths
386 5856de80 ths
void malta_fpga_reset(void *opaque)
387 5856de80 ths
{
388 5856de80 ths
    MaltaFPGAState *s = opaque;
389 5856de80 ths
390 5856de80 ths
    s->leds   = 0x00;
391 5856de80 ths
    s->brk    = 0x0a;
392 5856de80 ths
    s->gpout  = 0x00;
393 130751ee ths
    s->i2cin  = 0x3;
394 5856de80 ths
    s->i2coe  = 0x0;
395 5856de80 ths
    s->i2cout = 0x3;
396 5856de80 ths
    s->i2csel = 0x1;
397 5856de80 ths
398 5856de80 ths
    s->display_text[8] = '\0';
399 5856de80 ths
    snprintf(s->display_text, 9, "        ");
400 5856de80 ths
    malta_fpga_update_display(s);
401 5856de80 ths
}
402 5856de80 ths
403 5856de80 ths
MaltaFPGAState *malta_fpga_init(target_phys_addr_t base)
404 5856de80 ths
{
405 5856de80 ths
    MaltaFPGAState *s;
406 5856de80 ths
    int malta;
407 5856de80 ths
408 5856de80 ths
    s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
409 5856de80 ths
410 5856de80 ths
    malta = cpu_register_io_memory(0, malta_fpga_read,
411 5856de80 ths
                                   malta_fpga_write, s);
412 5856de80 ths
    cpu_register_physical_memory(base, 0x100000, malta);
413 5856de80 ths
414 5856de80 ths
    s->display = qemu_chr_open("vc");
415 af23902b ths
    qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
416 5856de80 ths
    qemu_chr_printf(s->display, "+--------+\r\n");
417 5856de80 ths
    qemu_chr_printf(s->display, "+        +\r\n");
418 5856de80 ths
    qemu_chr_printf(s->display, "+--------+\r\n");
419 5856de80 ths
    qemu_chr_printf(s->display, "\n");
420 5856de80 ths
    qemu_chr_printf(s->display, "Malta ASCII\r\n");
421 5856de80 ths
    qemu_chr_printf(s->display, "+--------+\r\n");
422 5856de80 ths
    qemu_chr_printf(s->display, "+        +\r\n");
423 5856de80 ths
    qemu_chr_printf(s->display, "+--------+\r\n");
424 5856de80 ths
425 5856de80 ths
    malta_fpga_reset(s);
426 5856de80 ths
    qemu_register_reset(malta_fpga_reset, s);
427 5856de80 ths
428 5856de80 ths
    return s;
429 5856de80 ths
}
430 5856de80 ths
431 5856de80 ths
/* Audio support */
432 5856de80 ths
#ifdef HAS_AUDIO
433 5856de80 ths
static void audio_init (PCIBus *pci_bus)
434 5856de80 ths
{
435 5856de80 ths
    struct soundhw *c;
436 5856de80 ths
    int audio_enabled = 0;
437 5856de80 ths
438 5856de80 ths
    for (c = soundhw; !audio_enabled && c->name; ++c) {
439 5856de80 ths
        audio_enabled = c->enabled;
440 5856de80 ths
    }
441 5856de80 ths
442 5856de80 ths
    if (audio_enabled) {
443 5856de80 ths
        AudioState *s;
444 5856de80 ths
445 5856de80 ths
        s = AUD_init ();
446 5856de80 ths
        if (s) {
447 5856de80 ths
            for (c = soundhw; c->name; ++c) {
448 5856de80 ths
                if (c->enabled) {
449 5856de80 ths
                    if (c->isa) {
450 5856de80 ths
                        fprintf(stderr, "qemu: Unsupported Sound Card: %s\n", c->name);
451 5856de80 ths
                        exit(1);
452 5856de80 ths
                    }
453 5856de80 ths
                    else {
454 5856de80 ths
                        if (pci_bus) {
455 5856de80 ths
                            c->init.init_pci (pci_bus, s);
456 5856de80 ths
                        }
457 5856de80 ths
                    }
458 5856de80 ths
                }
459 5856de80 ths
            }
460 5856de80 ths
        }
461 5856de80 ths
    }
462 5856de80 ths
}
463 5856de80 ths
#endif
464 5856de80 ths
465 5856de80 ths
/* Network support */
466 5856de80 ths
static void network_init (PCIBus *pci_bus)
467 5856de80 ths
{
468 5856de80 ths
    int i;
469 5856de80 ths
    NICInfo *nd;
470 5856de80 ths
471 5856de80 ths
    for(i = 0; i < nb_nics; i++) {
472 5856de80 ths
        nd = &nd_table[i];
473 5856de80 ths
        if (!nd->model) {
474 5856de80 ths
            nd->model = "pcnet";
475 5856de80 ths
        }
476 5856de80 ths
        if (i == 0  && strcmp(nd->model, "pcnet") == 0) {
477 5856de80 ths
            /* The malta board has a PCNet card using PCI SLOT 11 */
478 5856de80 ths
            pci_nic_init(pci_bus, nd, 88);
479 5856de80 ths
        } else {
480 5856de80 ths
            pci_nic_init(pci_bus, nd, -1);
481 5856de80 ths
        }
482 5856de80 ths
    }
483 5856de80 ths
}
484 5856de80 ths
485 5856de80 ths
/* ROM and pseudo bootloader
486 5856de80 ths

487 5856de80 ths
   The following code implements a very very simple bootloader. It first
488 5856de80 ths
   loads the registers a0 to a3 to the values expected by the OS, and
489 5856de80 ths
   then jump at the kernel address.
490 5856de80 ths

491 5856de80 ths
   The bootloader should pass the locations of the kernel arguments and
492 5856de80 ths
   environment variables tables. Those tables contain the 32-bit address
493 5856de80 ths
   of NULL terminated strings. The environment variables table should be
494 5856de80 ths
   terminated by a NULL address.
495 5856de80 ths

496 5856de80 ths
   For a simpler implementation, the number of kernel arguments is fixed
497 5856de80 ths
   to two (the name of the kernel and the command line), and the two
498 5856de80 ths
   tables are actually the same one.
499 5856de80 ths

500 5856de80 ths
   The registers a0 to a3 should contain the following values:
501 5856de80 ths
     a0 - number of kernel arguments
502 5856de80 ths
     a1 - 32-bit address of the kernel arguments table
503 5856de80 ths
     a2 - 32-bit address of the environment variables table
504 5856de80 ths
     a3 - RAM size in bytes
505 5856de80 ths
*/
506 5856de80 ths
507 5856de80 ths
static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t kernel_addr)
508 5856de80 ths
{
509 5856de80 ths
    uint32_t *p;
510 5856de80 ths
511 5856de80 ths
    /* Small bootloader */
512 5856de80 ths
    p = (uint32_t *) (phys_ram_base + bios_offset);
513 3ddd0065 ths
    stl_raw(p++, 0x0bf00010);                                      /* j 0x1fc00040 */
514 3ddd0065 ths
    stl_raw(p++, 0x00000000);                                      /* nop */
515 5856de80 ths
516 5856de80 ths
    /* Second part of the bootloader */
517 5856de80 ths
    p = (uint32_t *) (phys_ram_base + bios_offset + 0x040);
518 3ddd0065 ths
    stl_raw(p++, 0x3c040000);                                      /* lui a0, 0 */
519 3ddd0065 ths
    stl_raw(p++, 0x34840002);                                      /* ori a0, a0, 2 */
520 3ddd0065 ths
    stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));       /* lui a1, high(ENVP_ADDR) */
521 3ddd0065 ths
    stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a0, low(ENVP_ADDR) */
522 3ddd0065 ths
    stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
523 3ddd0065 ths
    stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));         /* ori a2, a2, low(ENVP_ADDR + 8) */
524 3ddd0065 ths
    stl_raw(p++, 0x3c070000 | (env->ram_size >> 16));              /* lui a3, high(env->ram_size) */
525 3ddd0065 ths
    stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff));           /* ori a3, a3, low(env->ram_size) */
526 3ddd0065 ths
    stl_raw(p++, 0x3c1f0000 | ((kernel_addr >> 16) & 0xffff));     /* lui ra, high(kernel_addr) */;
527 3ddd0065 ths
    stl_raw(p++, 0x37ff0000 | (kernel_addr & 0xffff));             /* ori ra, ra, low(kernel_addr) */
528 3ddd0065 ths
    stl_raw(p++, 0x03e00008);                                      /* jr ra */
529 3ddd0065 ths
    stl_raw(p++, 0x00000000);                                      /* nop */
530 5856de80 ths
}
531 5856de80 ths
532 5856de80 ths
static void prom_set(int index, const char *string, ...)
533 5856de80 ths
{
534 5856de80 ths
    va_list ap;
535 3ddd0065 ths
    int32_t *p;
536 3ddd0065 ths
    int32_t table_addr;
537 5856de80 ths
    char *s;
538 5856de80 ths
539 5856de80 ths
    if (index >= ENVP_NB_ENTRIES)
540 5856de80 ths
        return;
541 5856de80 ths
542 3ddd0065 ths
    p = (int32_t *) (phys_ram_base + ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
543 5856de80 ths
    p += index;
544 5856de80 ths
545 5856de80 ths
    if (string == NULL) {
546 5856de80 ths
        stl_raw(p, 0);
547 5856de80 ths
        return;
548 5856de80 ths
    }
549 5856de80 ths
550 3ddd0065 ths
    table_addr = ENVP_ADDR + sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
551 5856de80 ths
    s = (char *) (phys_ram_base + VIRT_TO_PHYS_ADDEND + table_addr);
552 5856de80 ths
553 5856de80 ths
    stl_raw(p, table_addr);
554 5856de80 ths
555 5856de80 ths
    va_start(ap, string);
556 5856de80 ths
    vsnprintf (s, ENVP_ENTRY_SIZE, string, ap);
557 5856de80 ths
    va_end(ap);
558 5856de80 ths
}
559 5856de80 ths
560 5856de80 ths
/* Kernel */
561 5856de80 ths
static int64_t load_kernel (CPUState *env)
562 5856de80 ths
{
563 5856de80 ths
    int64_t kernel_addr = 0;
564 5856de80 ths
    int index = 0;
565 5856de80 ths
    long initrd_size;
566 5856de80 ths
567 5856de80 ths
    if (load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND, &kernel_addr) < 0) {
568 5856de80 ths
        fprintf(stderr, "qemu: could not load kernel '%s'\n",
569 5856de80 ths
                env->kernel_filename);
570 5856de80 ths
      exit(1);
571 5856de80 ths
    }
572 5856de80 ths
573 5856de80 ths
    /* load initrd */
574 5856de80 ths
    initrd_size = 0;
575 5856de80 ths
    if (env->initrd_filename) {
576 5856de80 ths
        initrd_size = load_image(env->initrd_filename,
577 5856de80 ths
                                 phys_ram_base + INITRD_LOAD_ADDR + VIRT_TO_PHYS_ADDEND);
578 5856de80 ths
        if (initrd_size == (target_ulong) -1) {
579 5856de80 ths
            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
580 5856de80 ths
                    env->initrd_filename);
581 5856de80 ths
            exit(1);
582 5856de80 ths
        }
583 5856de80 ths
    }
584 5856de80 ths
585 5856de80 ths
    /* Store command line.  */
586 5856de80 ths
    prom_set(index++, env->kernel_filename);
587 5856de80 ths
    if (initrd_size > 0)
588 3594c774 ths
        prom_set(index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s", INITRD_LOAD_ADDR, initrd_size, env->kernel_cmdline);
589 5856de80 ths
    else
590 5856de80 ths
        prom_set(index++, env->kernel_cmdline);
591 5856de80 ths
592 5856de80 ths
    /* Setup minimum environment variables */
593 5856de80 ths
    prom_set(index++, "memsize");
594 5856de80 ths
    prom_set(index++, "%i", env->ram_size);
595 5856de80 ths
    prom_set(index++, "modetty0");
596 5856de80 ths
    prom_set(index++, "38400n8r");
597 5856de80 ths
    prom_set(index++, NULL);
598 5856de80 ths
599 5856de80 ths
    return kernel_addr;
600 5856de80 ths
}
601 5856de80 ths
602 5856de80 ths
static void main_cpu_reset(void *opaque)
603 5856de80 ths
{
604 5856de80 ths
    CPUState *env = opaque;
605 5856de80 ths
    cpu_reset(env);
606 5856de80 ths
607 5856de80 ths
    /* The bootload does not need to be rewritten as it is located in a
608 5856de80 ths
       read only location. The kernel location and the arguments table
609 5856de80 ths
       location does not change. */
610 5856de80 ths
    if (env->kernel_filename)
611 5856de80 ths
        load_kernel (env);
612 5856de80 ths
}
613 5856de80 ths
614 70705261 ths
static
615 5856de80 ths
void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
616 5856de80 ths
                      DisplayState *ds, const char **fd_filename, int snapshot,
617 5856de80 ths
                      const char *kernel_filename, const char *kernel_cmdline,
618 94fc95cd j_mayer
                      const char *initrd_filename, const char *cpu_model)
619 5856de80 ths
{
620 5856de80 ths
    char buf[1024];
621 5856de80 ths
    unsigned long bios_offset;
622 5856de80 ths
    int64_t kernel_addr;
623 5856de80 ths
    PCIBus *pci_bus;
624 5856de80 ths
    CPUState *env;
625 5856de80 ths
    RTCState *rtc_state;
626 f1770b3e ths
    /* fdctrl_t *floppy_controller; */
627 5856de80 ths
    MaltaFPGAState *malta_fpga;
628 5856de80 ths
    int ret;
629 33d68b5f ths
    mips_def_t *def;
630 5856de80 ths
631 33d68b5f ths
    /* init CPUs */
632 33d68b5f ths
    if (cpu_model == NULL) {
633 33d68b5f ths
#ifdef MIPS_HAS_MIPS64
634 33d68b5f ths
        cpu_model = "R4000";
635 33d68b5f ths
#else
636 33d68b5f ths
        cpu_model = "4KEc";
637 33d68b5f ths
#endif
638 33d68b5f ths
    }
639 33d68b5f ths
    if (mips_find_by_name(cpu_model, &def) != 0)
640 33d68b5f ths
        def = NULL;
641 5856de80 ths
    env = cpu_init();
642 33d68b5f ths
    cpu_mips_register(env, def);
643 5856de80 ths
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
644 5856de80 ths
    qemu_register_reset(main_cpu_reset, env);
645 5856de80 ths
646 5856de80 ths
    /* allocate RAM */
647 5856de80 ths
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
648 5856de80 ths
649 5856de80 ths
    /* Map the bios at two physical locations, as on the real board */
650 5856de80 ths
    bios_offset = ram_size + vga_ram_size;
651 5856de80 ths
    cpu_register_physical_memory(0x1e000000LL,
652 5856de80 ths
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
653 5856de80 ths
    cpu_register_physical_memory(0x1fc00000LL,
654 5856de80 ths
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
655 5856de80 ths
656 5856de80 ths
    /* Load a BIOS image except if a kernel image has been specified. In
657 5856de80 ths
       the later case, just write a small bootloader to the flash
658 5856de80 ths
       location. */
659 5856de80 ths
    if (kernel_filename) {
660 5856de80 ths
        env->ram_size = ram_size;
661 5856de80 ths
        env->kernel_filename = kernel_filename;
662 5856de80 ths
        env->kernel_cmdline = kernel_cmdline;
663 5856de80 ths
        env->initrd_filename = initrd_filename;
664 5856de80 ths
        kernel_addr = load_kernel(env);
665 5856de80 ths
        write_bootloader(env, bios_offset, kernel_addr);
666 5856de80 ths
    } else {
667 5856de80 ths
        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
668 5856de80 ths
        ret = load_image(buf, phys_ram_base + bios_offset);
669 331ad6f4 ths
        if (ret < 0 || ret > BIOS_SIZE) {
670 5856de80 ths
            fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
671 5856de80 ths
                    buf);
672 5856de80 ths
            exit(1);
673 5856de80 ths
        }
674 5856de80 ths
    }
675 5856de80 ths
676 5856de80 ths
    /* Board ID = 0x420 (Malta Board with CoreLV)
677 5856de80 ths
       XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
678 5856de80 ths
       map to the board ID. */
679 5856de80 ths
    stl_raw(phys_ram_base + bios_offset + 0x10, 0x00000420);
680 5856de80 ths
681 5856de80 ths
    /* Init internal devices */
682 5856de80 ths
    cpu_mips_clock_init(env);
683 5856de80 ths
    cpu_mips_irqctrl_init();
684 5856de80 ths
685 5856de80 ths
    /* FPGA */
686 5856de80 ths
    malta_fpga = malta_fpga_init(0x1f000000LL);
687 5856de80 ths
688 5856de80 ths
    /* Interrupt controller */
689 5856de80 ths
    isa_pic = pic_init(pic_irq_request, env);
690 5856de80 ths
691 5856de80 ths
    /* Northbridge */
692 5856de80 ths
    pci_bus = pci_gt64120_init(isa_pic);
693 5856de80 ths
694 5856de80 ths
    /* Southbridge */
695 5856de80 ths
    piix4_init(pci_bus, 80);
696 5856de80 ths
    pci_piix3_ide_init(pci_bus, bs_table, 81);
697 5856de80 ths
    usb_uhci_init(pci_bus, 82);
698 5856de80 ths
    piix4_pm_init(pci_bus, 83);
699 5856de80 ths
    pit = pit_init(0x40, 0);
700 5856de80 ths
    DMA_init(0);
701 5856de80 ths
702 5856de80 ths
    /* Super I/O */
703 5856de80 ths
    kbd_init();
704 5856de80 ths
    rtc_state = rtc_init(0x70, 8);
705 7bcc17dc ths
    if (serial_hds[0])
706 7bcc17dc ths
        serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
707 7bcc17dc ths
    if (serial_hds[1])
708 c05ac0cd ths
        serial_init(&pic_set_irq_new, isa_pic, 0x2f8, 3, serial_hds[1]);
709 7bcc17dc ths
    if (parallel_hds[0])
710 7bcc17dc ths
        parallel_init(0x378, 7, parallel_hds[0]);
711 5856de80 ths
    /* XXX: The floppy controller does not work correctly, something is
712 f1770b3e ths
       probably wrong.
713 f1770b3e ths
    floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); */
714 5856de80 ths
715 5856de80 ths
    /* Sound card */
716 5856de80 ths
#ifdef HAS_AUDIO
717 5856de80 ths
    audio_init(pci_bus);
718 5856de80 ths
#endif
719 5856de80 ths
720 5856de80 ths
    /* Network card */
721 5856de80 ths
    network_init(pci_bus);
722 11f29511 ths
723 11f29511 ths
    /* Optional PCI video card */
724 11f29511 ths
    pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size,
725 11f29511 ths
                        ram_size, vga_ram_size);
726 5856de80 ths
}
727 5856de80 ths
728 5856de80 ths
QEMUMachine mips_malta_machine = {
729 5856de80 ths
    "malta",
730 5856de80 ths
    "MIPS Malta Core LV",
731 5856de80 ths
    mips_malta_init,
732 5856de80 ths
};