Use the correct PCI IDs for Malta.
[qemu] / hw / mips_malta.c
1 /*
2  * QEMU Malta board support
3  *
4  * Copyright (c) 2006 Aurelien Jarno
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24
25 #include "vl.h"
26
27 #ifdef TARGET_WORDS_BIGENDIAN
28 #define BIOS_FILENAME "mips_bios.bin"
29 #else
30 #define BIOS_FILENAME "mipsel_bios.bin"
31 #endif
32
33 #ifdef TARGET_MIPS64
34 #define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
35 #else
36 #define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
37 #endif
38
39 #define ENVP_ADDR (int32_t)0x80002000
40 #define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
41
42 #define ENVP_NB_ENTRIES         16
43 #define ENVP_ENTRY_SIZE         256
44
45
46 extern FILE *logfile;
47
48 typedef struct {
49     uint32_t leds;
50     uint32_t brk;
51     uint32_t gpout;
52     uint32_t i2cin;
53     uint32_t i2coe;
54     uint32_t i2cout;
55     uint32_t i2csel;
56     CharDriverState *display;
57     char display_text[9];
58     SerialState *uart;
59 } MaltaFPGAState;
60
61 static PITState *pit;
62
63 /* Malta FPGA */
64 static void malta_fpga_update_display(void *opaque)
65 {
66     char leds_text[9];
67     int i;
68     MaltaFPGAState *s = opaque;
69
70     for (i = 7 ; i >= 0 ; i--) {
71         if (s->leds & (1 << i))
72             leds_text[i] = '#';
73         else
74             leds_text[i] = ' ';
75     }
76     leds_text[8] = '\0';
77
78     qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
79     qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
80 }
81
82 /*
83  * EEPROM 24C01 / 24C02 emulation.
84  *
85  * Emulation for serial EEPROMs:
86  * 24C01 - 1024 bit (128 x 8)
87  * 24C02 - 2048 bit (256 x 8)
88  *
89  * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
90  */
91
92 //~ #define DEBUG
93
94 #if defined(DEBUG)
95 #  define logout(fmt, args...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ##args)
96 #else
97 #  define logout(fmt, args...) ((void)0)
98 #endif
99
100 struct _eeprom24c0x_t {
101   uint8_t tick;
102   uint8_t address;
103   uint8_t command;
104   uint8_t ack;
105   uint8_t scl;
106   uint8_t sda;
107   uint8_t data;
108   //~ uint16_t size;
109   uint8_t contents[256];
110 };
111
112 typedef struct _eeprom24c0x_t eeprom24c0x_t;
113
114 static eeprom24c0x_t eeprom = {
115     contents: {
116         /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
117         /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
118         /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
119         /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
120         /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
121         /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
122         /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
123         /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
124         /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
125         /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
126         /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
127         /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128         /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
129         /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130         /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131         /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
132     },
133 };
134
135 static uint8_t eeprom24c0x_read()
136 {
137     logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
138         eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
139     return eeprom.sda;
140 }
141
142 static void eeprom24c0x_write(int scl, int sda)
143 {
144     if (eeprom.scl && scl && (eeprom.sda != sda)) {
145         logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
146                 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda, sda ? "stop" : "start");
147         if (!sda) {
148             eeprom.tick = 1;
149             eeprom.command = 0;
150         }
151     } else if (eeprom.tick == 0 && !eeprom.ack) {
152         /* Waiting for start. */
153         logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
154                 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
155     } else if (!eeprom.scl && scl) {
156         logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
157                 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
158         if (eeprom.ack) {
159             logout("\ti2c ack bit = 0\n");
160             sda = 0;
161             eeprom.ack = 0;
162         } else if (eeprom.sda == sda) {
163             uint8_t bit = (sda != 0);
164             logout("\ti2c bit = %d\n", bit);
165             if (eeprom.tick < 9) {
166                 eeprom.command <<= 1;
167                 eeprom.command += bit;
168                 eeprom.tick++;
169                 if (eeprom.tick == 9) {
170                     logout("\tcommand 0x%04x, %s\n", eeprom.command, bit ? "read" : "write");
171                     eeprom.ack = 1;
172                 }
173             } else if (eeprom.tick < 17) {
174                 if (eeprom.command & 1) {
175                     sda = ((eeprom.data & 0x80) != 0);
176                 }
177                 eeprom.address <<= 1;
178                 eeprom.address += bit;
179                 eeprom.tick++;
180                 eeprom.data <<= 1;
181                 if (eeprom.tick == 17) {
182                     eeprom.data = eeprom.contents[eeprom.address];
183                     logout("\taddress 0x%04x, data 0x%02x\n", eeprom.address, eeprom.data);
184                     eeprom.ack = 1;
185                     eeprom.tick = 0;
186                 }
187             } else if (eeprom.tick >= 17) {
188                 sda = 0;
189             }
190         } else {
191             logout("\tsda changed with raising scl\n");
192         }
193     } else {
194         logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
195     }
196     eeprom.scl = scl;
197     eeprom.sda = sda;
198 }
199
200 static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
201 {
202     MaltaFPGAState *s = opaque;
203     uint32_t val = 0;
204     uint32_t saddr;
205
206     saddr = (addr & 0xfffff);
207
208     switch (saddr) {
209
210     /* SWITCH Register */
211     case 0x00200:
212         val = 0x00000000;               /* All switches closed */
213         break;
214
215     /* STATUS Register */
216     case 0x00208:
217 #ifdef TARGET_WORDS_BIGENDIAN
218         val = 0x00000012;
219 #else
220         val = 0x00000010;
221 #endif
222         break;
223
224     /* JMPRS Register */
225     case 0x00210:
226         val = 0x00;
227         break;
228
229     /* LEDBAR Register */
230     case 0x00408:
231         val = s->leds;
232         break;
233
234     /* BRKRES Register */
235     case 0x00508:
236         val = s->brk;
237         break;
238
239     /* UART Registers are handled directly by the serial device */
240
241     /* GPOUT Register */
242     case 0x00a00:
243         val = s->gpout;
244         break;
245
246     /* XXX: implement a real I2C controller */
247
248     /* GPINP Register */
249     case 0x00a08:
250         /* IN = OUT until a real I2C control is implemented */
251         if (s->i2csel)
252             val = s->i2cout;
253         else
254             val = 0x00;
255         break;
256
257     /* I2CINP Register */
258     case 0x00b00:
259         val = ((s->i2cin & ~1) | eeprom24c0x_read());
260         break;
261
262     /* I2COE Register */
263     case 0x00b08:
264         val = s->i2coe;
265         break;
266
267     /* I2COUT Register */
268     case 0x00b10:
269         val = s->i2cout;
270         break;
271
272     /* I2CSEL Register */
273     case 0x00b18:
274         val = s->i2csel;
275         break;
276
277     default:
278 #if 0
279         printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
280                 addr);
281 #endif
282         break;
283     }
284     return val;
285 }
286
287 static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
288                               uint32_t val)
289 {
290     MaltaFPGAState *s = opaque;
291     uint32_t saddr;
292
293     saddr = (addr & 0xfffff);
294
295     switch (saddr) {
296
297     /* SWITCH Register */
298     case 0x00200:
299         break;
300
301     /* JMPRS Register */
302     case 0x00210:
303         break;
304
305     /* LEDBAR Register */
306     /* XXX: implement a 8-LED array */
307     case 0x00408:
308         s->leds = val & 0xff;
309         break;
310
311     /* ASCIIWORD Register */
312     case 0x00410:
313         snprintf(s->display_text, 9, "%08X", val);
314         malta_fpga_update_display(s);
315         break;
316
317     /* ASCIIPOS0 to ASCIIPOS7 Registers */
318     case 0x00418:
319     case 0x00420:
320     case 0x00428:
321     case 0x00430:
322     case 0x00438:
323     case 0x00440:
324     case 0x00448:
325     case 0x00450:
326         s->display_text[(saddr - 0x00418) >> 3] = (char) val;
327         malta_fpga_update_display(s);
328         break;
329
330     /* SOFTRES Register */
331     case 0x00500:
332         if (val == 0x42)
333             qemu_system_reset_request ();
334         break;
335
336     /* BRKRES Register */
337     case 0x00508:
338         s->brk = val & 0xff;
339         break;
340
341     /* UART Registers are handled directly by the serial device */
342
343     /* GPOUT Register */
344     case 0x00a00:
345         s->gpout = val & 0xff;
346         break;
347
348     /* I2COE Register */
349     case 0x00b08:
350         s->i2coe = val & 0x03;
351         break;
352
353     /* I2COUT Register */
354     case 0x00b10:
355         eeprom24c0x_write(val & 0x02, val & 0x01);
356         s->i2cout = val;
357         break;
358
359     /* I2CSEL Register */
360     case 0x00b18:
361         s->i2csel = val & 0x01;
362         break;
363
364     default:
365 #if 0
366         printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
367                 addr);
368 #endif
369         break;
370     }
371 }
372
373 static CPUReadMemoryFunc *malta_fpga_read[] = {
374    malta_fpga_readl,
375    malta_fpga_readl,
376    malta_fpga_readl
377 };
378
379 static CPUWriteMemoryFunc *malta_fpga_write[] = {
380    malta_fpga_writel,
381    malta_fpga_writel,
382    malta_fpga_writel
383 };
384
385 void malta_fpga_reset(void *opaque)
386 {
387     MaltaFPGAState *s = opaque;
388
389     s->leds   = 0x00;
390     s->brk    = 0x0a;
391     s->gpout  = 0x00;
392     s->i2cin  = 0x3;
393     s->i2coe  = 0x0;
394     s->i2cout = 0x3;
395     s->i2csel = 0x1;
396
397     s->display_text[8] = '\0';
398     snprintf(s->display_text, 9, "        ");
399     malta_fpga_update_display(s);
400 }
401
402 MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, CPUState *env)
403 {
404     MaltaFPGAState *s;
405     CharDriverState *uart_chr;
406     int malta;
407
408     s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
409
410     malta = cpu_register_io_memory(0, malta_fpga_read,
411                                    malta_fpga_write, s);
412
413     cpu_register_physical_memory(base, 0x900, malta);
414     cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
415
416     s->display = qemu_chr_open("vc");
417     qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
418     qemu_chr_printf(s->display, "+--------+\r\n");
419     qemu_chr_printf(s->display, "+        +\r\n");
420     qemu_chr_printf(s->display, "+--------+\r\n");
421     qemu_chr_printf(s->display, "\n");
422     qemu_chr_printf(s->display, "Malta ASCII\r\n");
423     qemu_chr_printf(s->display, "+--------+\r\n");
424     qemu_chr_printf(s->display, "+        +\r\n");
425     qemu_chr_printf(s->display, "+--------+\r\n");
426
427     uart_chr = qemu_chr_open("vc");
428     qemu_chr_printf(uart_chr, "CBUS UART\r\n");
429     s->uart = serial_mm_init(base + 0x900, 3, env->irq[2], uart_chr, 1);
430
431     malta_fpga_reset(s);
432     qemu_register_reset(malta_fpga_reset, s);
433
434     return s;
435 }
436
437 /* Audio support */
438 #ifdef HAS_AUDIO
439 static void audio_init (PCIBus *pci_bus)
440 {
441     struct soundhw *c;
442     int audio_enabled = 0;
443
444     for (c = soundhw; !audio_enabled && c->name; ++c) {
445         audio_enabled = c->enabled;
446     }
447
448     if (audio_enabled) {
449         AudioState *s;
450
451         s = AUD_init ();
452         if (s) {
453             for (c = soundhw; c->name; ++c) {
454                 if (c->enabled) {
455                     if (c->isa) {
456                         fprintf(stderr, "qemu: Unsupported Sound Card: %s\n", c->name);
457                         exit(1);
458                     }
459                     else {
460                         if (pci_bus) {
461                             c->init.init_pci (pci_bus, s);
462                         }
463                     }
464                 }
465             }
466         }
467     }
468 }
469 #endif
470
471 /* Network support */
472 static void network_init (PCIBus *pci_bus)
473 {
474     int i;
475     NICInfo *nd;
476
477     for(i = 0; i < nb_nics; i++) {
478         nd = &nd_table[i];
479         if (!nd->model) {
480             nd->model = "pcnet";
481         }
482         if (i == 0  && strcmp(nd->model, "pcnet") == 0) {
483             /* The malta board has a PCNet card using PCI SLOT 11 */
484             pci_nic_init(pci_bus, nd, 88);
485         } else {
486             pci_nic_init(pci_bus, nd, -1);
487         }
488     }
489 }
490
491 /* ROM and pseudo bootloader
492
493    The following code implements a very very simple bootloader. It first
494    loads the registers a0 to a3 to the values expected by the OS, and
495    then jump at the kernel address.
496
497    The bootloader should pass the locations of the kernel arguments and
498    environment variables tables. Those tables contain the 32-bit address
499    of NULL terminated strings. The environment variables table should be
500    terminated by a NULL address.
501
502    For a simpler implementation, the number of kernel arguments is fixed
503    to two (the name of the kernel and the command line), and the two
504    tables are actually the same one.
505
506    The registers a0 to a3 should contain the following values:
507      a0 - number of kernel arguments
508      a1 - 32-bit address of the kernel arguments table
509      a2 - 32-bit address of the environment variables table
510      a3 - RAM size in bytes
511 */
512
513 static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t kernel_entry)
514 {
515     uint32_t *p;
516
517     /* Small bootloader */
518     p = (uint32_t *) (phys_ram_base + bios_offset);
519     stl_raw(p++, 0x0bf00160);                                      /* j 0x1fc00580 */
520     stl_raw(p++, 0x00000000);                                      /* nop */
521
522     /* YAMON service vector */
523     stl_raw(phys_ram_base + bios_offset + 0x500, 0xbfc00580);      /* start: */                                 
524     stl_raw(phys_ram_base + bios_offset + 0x504, 0xbfc0083c);      /* print_count: */
525     stl_raw(phys_ram_base + bios_offset + 0x520, 0xbfc00580);      /* start: */                                 
526     stl_raw(phys_ram_base + bios_offset + 0x52c, 0xbfc00800);      /* flush_cache: */
527     stl_raw(phys_ram_base + bios_offset + 0x534, 0xbfc00808);      /* print: */
528     stl_raw(phys_ram_base + bios_offset + 0x538, 0xbfc00800);      /* reg_cpu_isr: */
529     stl_raw(phys_ram_base + bios_offset + 0x53c, 0xbfc00800);      /* unred_cpu_isr: */
530     stl_raw(phys_ram_base + bios_offset + 0x540, 0xbfc00800);      /* reg_ic_isr: */
531     stl_raw(phys_ram_base + bios_offset + 0x544, 0xbfc00800);      /* unred_ic_isr: */
532     stl_raw(phys_ram_base + bios_offset + 0x548, 0xbfc00800);      /* reg_esr: */
533     stl_raw(phys_ram_base + bios_offset + 0x54c, 0xbfc00800);      /* unreg_esr: */
534     stl_raw(phys_ram_base + bios_offset + 0x550, 0xbfc00800);      /* getchar: */
535     stl_raw(phys_ram_base + bios_offset + 0x554, 0xbfc00800);      /* syscon_read: */
536
537
538     /* Second part of the bootloader */
539     p = (uint32_t *) (phys_ram_base + bios_offset + 0x580);
540     stl_raw(p++, 0x24040002);                                      /* addiu a0, zero, 2 */
541     stl_raw(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
542     stl_raw(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff));        /* ori sp, sp, low(ENVP_ADDR) */
543     stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));       /* lui a1, high(ENVP_ADDR) */
544     stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a1, low(ENVP_ADDR) */
545     stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
546     stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));         /* ori a2, a2, low(ENVP_ADDR + 8) */
547     stl_raw(p++, 0x3c070000 | (env->ram_size >> 16));              /* lui a3, high(env->ram_size) */
548     stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff));           /* ori a3, a3, low(env->ram_size) */
549
550     /* Load BAR registers as done by YAMON */
551     stl_raw(p++, 0x3c09bbe0);                                      /* lui t1, 0xbbe0 */
552
553 #ifdef TARGET_WORDS_BIGENDIAN
554     stl_raw(p++, 0x3c08c000);                                      /* lui t0, 0xc000 */
555 #else
556     stl_raw(p++, 0x340800c0);                                      /* ori t0, r0, 0x00c0 */
557 #endif
558     stl_raw(p++, 0xad280048);                                      /* sw t0, 0x0048(t1) */
559 #ifdef TARGET_WORDS_BIGENDIAN
560     stl_raw(p++, 0x3c084000);                                      /* lui t0, 0x4000 */
561 #else
562     stl_raw(p++, 0x34080040);                                      /* ori t0, r0, 0x0040 */
563 #endif
564     stl_raw(p++, 0xad280050);                                      /* sw t0, 0x0050(t1) */
565
566 #ifdef TARGET_WORDS_BIGENDIAN
567     stl_raw(p++, 0x3c088000);                                      /* lui t0, 0x8000 */
568 #else
569     stl_raw(p++, 0x34080080);                                      /* ori t0, r0, 0x0080 */
570 #endif
571     stl_raw(p++, 0xad280058);                                      /* sw t0, 0x0058(t1) */
572 #ifdef TARGET_WORDS_BIGENDIAN
573     stl_raw(p++, 0x3c083f00);                                      /* lui t0, 0x3f00 */
574 #else
575     stl_raw(p++, 0x3408003f);                                      /* ori t0, r0, 0x003f */
576 #endif
577     stl_raw(p++, 0xad280060);                                      /* sw t0, 0x0060(t1) */
578
579 #ifdef TARGET_WORDS_BIGENDIAN
580     stl_raw(p++, 0x3c08c100);                                      /* lui t0, 0xc100 */
581 #else
582     stl_raw(p++, 0x340800c1);                                      /* ori t0, r0, 0x00c1 */
583 #endif
584     stl_raw(p++, 0xad280080);                                      /* sw t0, 0x0080(t1) */
585 #ifdef TARGET_WORDS_BIGENDIAN
586     stl_raw(p++, 0x3c085e00);                                      /* lui t0, 0x5e00 */
587 #else
588     stl_raw(p++, 0x3408005e);                                      /* ori t0, r0, 0x005e */
589 #endif
590     stl_raw(p++, 0xad280088);                                      /* sw t0, 0x0088(t1) */
591
592     /* Jump to kernel code */
593     stl_raw(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff));    /* lui ra, high(kernel_entry) */
594     stl_raw(p++, 0x37ff0000 | (kernel_entry & 0xffff));            /* ori ra, ra, low(kernel_entry) */
595     stl_raw(p++, 0x03e00008);                                      /* jr ra */
596     stl_raw(p++, 0x00000000);                                      /* nop */
597
598     /* YAMON subroutines */
599     p = (uint32_t *) (phys_ram_base + bios_offset + 0x800);
600     stl_raw(p++, 0x03e00008);                                     /* jr ra */
601     stl_raw(p++, 0x24020000);                                     /* li v0,0 */
602    /* 808 YAMON print */
603     stl_raw(p++, 0x03e06821);                                     /* move t5,ra */
604     stl_raw(p++, 0x00805821);                                     /* move t3,a0 */
605     stl_raw(p++, 0x00a05021);                                     /* move t2,a1 */
606     stl_raw(p++, 0x91440000);                                     /* lbu a0,0(t2) */
607     stl_raw(p++, 0x254a0001);                                     /* addiu t2,t2,1 */
608     stl_raw(p++, 0x10800005);                                     /* beqz a0,834 */
609     stl_raw(p++, 0x00000000);                                     /* nop */
610     stl_raw(p++, 0x0ff0021c);                                     /* jal 870 */
611     stl_raw(p++, 0x00000000);                                     /* nop */
612     stl_raw(p++, 0x08000205);                                     /* j 814 */
613     stl_raw(p++, 0x00000000);                                     /* nop */
614     stl_raw(p++, 0x01a00008);                                     /* jr t5 */
615     stl_raw(p++, 0x01602021);                                     /* move a0,t3 */
616     /* 0x83c YAMON print_count */
617     stl_raw(p++, 0x03e06821);                                     /* move t5,ra */
618     stl_raw(p++, 0x00805821);                                     /* move t3,a0 */
619     stl_raw(p++, 0x00a05021);                                     /* move t2,a1 */
620     stl_raw(p++, 0x00c06021);                                     /* move t4,a2 */
621     stl_raw(p++, 0x91440000);                                     /* lbu a0,0(t2) */
622     stl_raw(p++, 0x0ff0021c);                                     /* jal 870 */
623     stl_raw(p++, 0x00000000);                                     /* nop */
624     stl_raw(p++, 0x254a0001);                                     /* addiu t2,t2,1 */
625     stl_raw(p++, 0x258cffff);                                     /* addiu t4,t4,-1 */
626     stl_raw(p++, 0x1580fffa);                                     /* bnez t4,84c */
627     stl_raw(p++, 0x00000000);                                     /* nop */
628     stl_raw(p++, 0x01a00008);                                     /* jr t5 */
629     stl_raw(p++, 0x01602021);                                     /* move a0,t3 */
630     /* 0x870 */
631     stl_raw(p++, 0x3c08b800);                                     /* lui t0,0xb400 */
632     stl_raw(p++, 0x350803f8);                                     /* ori t0,t0,0x3f8 */
633     stl_raw(p++, 0x91090005);                                     /* lbu t1,5(t0) */
634     stl_raw(p++, 0x00000000);                                     /* nop */
635     stl_raw(p++, 0x31290040);                                     /* andi t1,t1,0x40 */
636     stl_raw(p++, 0x1120fffc);                                     /* beqz t1,878 <outch+0x8> */
637     stl_raw(p++, 0x00000000);                                     /* nop */
638     stl_raw(p++, 0x03e00008);                                     /* jr ra */
639     stl_raw(p++, 0xa1040000);                                     /* sb a0,0(t0) */
640
641 }
642
643 static void prom_set(int index, const char *string, ...)
644 {
645     va_list ap;
646     int32_t *p;
647     int32_t table_addr;
648     char *s;
649
650     if (index >= ENVP_NB_ENTRIES)
651         return;
652
653     p = (int32_t *) (phys_ram_base + ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
654     p += index;
655
656     if (string == NULL) {
657         stl_raw(p, 0);
658         return;
659     }
660
661     table_addr = ENVP_ADDR + sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
662     s = (char *) (phys_ram_base + VIRT_TO_PHYS_ADDEND + table_addr);
663
664     stl_raw(p, table_addr);
665
666     va_start(ap, string);
667     vsnprintf (s, ENVP_ENTRY_SIZE, string, ap);
668     va_end(ap);
669 }
670
671 /* Kernel */
672 static int64_t load_kernel (CPUState *env)
673 {
674     int64_t kernel_entry, kernel_low, kernel_high;
675     int index = 0;
676     long initrd_size;
677     ram_addr_t initrd_offset;
678
679     if (load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND,
680                  &kernel_entry, &kernel_low, &kernel_high) < 0) {
681         fprintf(stderr, "qemu: could not load kernel '%s'\n",
682                 env->kernel_filename);
683       exit(1);
684     }
685
686     /* load initrd */
687     initrd_size = 0;
688     initrd_offset = 0;
689     if (env->initrd_filename) {
690         initrd_size = get_image_size (env->initrd_filename);
691         if (initrd_size > 0) {
692             initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
693             if (initrd_offset + initrd_size > env->ram_size) {
694                 fprintf(stderr,
695                         "qemu: memory too small for initial ram disk '%s'\n",
696                         env->initrd_filename);
697                 exit(1);
698             }
699             initrd_size = load_image(env->initrd_filename,
700                                      phys_ram_base + initrd_offset);
701         }
702         if (initrd_size == (target_ulong) -1) {
703             fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
704                     env->initrd_filename);
705             exit(1);
706         }
707     }
708
709     /* Store command line.  */
710     prom_set(index++, env->kernel_filename);
711     if (initrd_size > 0)
712         prom_set(index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s",
713                  PHYS_TO_VIRT(initrd_offset), initrd_size,
714                  env->kernel_cmdline);
715     else
716         prom_set(index++, env->kernel_cmdline);
717
718     /* Setup minimum environment variables */
719     prom_set(index++, "memsize");
720     prom_set(index++, "%i", env->ram_size);
721     prom_set(index++, "modetty0");
722     prom_set(index++, "38400n8r");
723     prom_set(index++, NULL);
724
725     return kernel_entry;
726 }
727
728 static void main_cpu_reset(void *opaque)
729 {
730     CPUState *env = opaque;
731     cpu_reset(env);
732     cpu_mips_register(env, NULL);
733
734     /* The bootload does not need to be rewritten as it is located in a
735        read only location. The kernel location and the arguments table
736        location does not change. */
737     if (env->kernel_filename) {
738         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
739         load_kernel (env);
740     }
741 }
742
743 static
744 void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
745                       DisplayState *ds, const char **fd_filename, int snapshot,
746                       const char *kernel_filename, const char *kernel_cmdline,
747                       const char *initrd_filename, const char *cpu_model)
748 {
749     char buf[1024];
750     unsigned long bios_offset;
751     int64_t kernel_entry;
752     PCIBus *pci_bus;
753     CPUState *env;
754     RTCState *rtc_state;
755     /* fdctrl_t *floppy_controller; */
756     MaltaFPGAState *malta_fpga;
757     int ret;
758     mips_def_t *def;
759     qemu_irq *i8259;
760     int piix4_devfn;
761     uint8_t *eeprom_buf;
762     i2c_bus *smbus;
763     int i;
764
765     /* init CPUs */
766     if (cpu_model == NULL) {
767 #ifdef TARGET_MIPS64
768         cpu_model = "20Kc";
769 #else
770         cpu_model = "24Kf";
771 #endif
772     }
773     if (mips_find_by_name(cpu_model, &def) != 0)
774         def = NULL;
775     env = cpu_init();
776     cpu_mips_register(env, def);
777     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
778     qemu_register_reset(main_cpu_reset, env);
779
780     /* allocate RAM */
781     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
782
783     /* Map the bios at two physical locations, as on the real board */
784     bios_offset = ram_size + vga_ram_size;
785     cpu_register_physical_memory(0x1e000000LL,
786                                  BIOS_SIZE, bios_offset | IO_MEM_ROM);
787     cpu_register_physical_memory(0x1fc00000LL,
788                                  BIOS_SIZE, bios_offset | IO_MEM_ROM);
789
790     /* Load a BIOS image except if a kernel image has been specified. In
791        the later case, just write a small bootloader to the flash
792        location. */
793     if (kernel_filename) {
794         env->ram_size = ram_size;
795         env->kernel_filename = kernel_filename;
796         env->kernel_cmdline = kernel_cmdline;
797         env->initrd_filename = initrd_filename;
798         kernel_entry = load_kernel(env);
799         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
800         write_bootloader(env, bios_offset, kernel_entry);
801     } else {
802         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
803         ret = load_image(buf, phys_ram_base + bios_offset);
804         if (ret < 0 || ret > BIOS_SIZE) {
805             fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
806                     buf);
807             exit(1);
808         }
809     }
810
811     /* Board ID = 0x420 (Malta Board with CoreLV)
812        XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
813        map to the board ID. */
814     stl_raw(phys_ram_base + bios_offset + 0x10, 0x00000420);
815
816     /* Init internal devices */
817     cpu_mips_irq_init_cpu(env);
818     cpu_mips_clock_init(env);
819     cpu_mips_irqctrl_init();
820
821     /* FPGA */
822     malta_fpga = malta_fpga_init(0x1f000000LL, env);
823
824     /* Interrupt controller */
825     /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
826     i8259 = i8259_init(env->irq[2]);
827
828     /* Northbridge */
829     pci_bus = pci_gt64120_init(i8259);
830
831     /* Southbridge */
832     piix4_devfn = piix4_init(pci_bus, 80);
833     pci_piix4_ide_init(pci_bus, bs_table, piix4_devfn + 1, i8259);
834     usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
835     smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100);
836     eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
837     for (i = 0; i < 8; i++) {
838         /* TODO: Populate SPD eeprom data.  */
839         smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256));
840     }
841     pit = pit_init(0x40, i8259[0]);
842     DMA_init(0);
843
844     /* Super I/O */
845     i8042_init(i8259[1], i8259[12], 0x60);
846     rtc_state = rtc_init(0x70, i8259[8]);
847     if (serial_hds[0])
848         serial_init(0x3f8, i8259[4], serial_hds[0]);
849     if (serial_hds[1])
850         serial_init(0x2f8, i8259[3], serial_hds[1]);
851     if (parallel_hds[0])
852         parallel_init(0x378, i8259[7], parallel_hds[0]);
853     /* XXX: The floppy controller does not work correctly, something is
854        probably wrong.
855     floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table); */
856
857     /* Sound card */
858 #ifdef HAS_AUDIO
859     audio_init(pci_bus);
860 #endif
861
862     /* Network card */
863     network_init(pci_bus);
864
865     /* Optional PCI video card */
866     pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size,
867                         ram_size, vga_ram_size);
868 }
869
870 QEMUMachine mips_malta_machine = {
871     "malta",
872     "MIPS Malta Core LV",
873     mips_malta_init,
874 };