Malta has no ISA bus.
[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                     c->init.init_pci (pci_bus, s);
456             }
457         }
458     }
459 }
460 #endif
461
462 /* Network support */
463 static void network_init (PCIBus *pci_bus)
464 {
465     int i;
466     NICInfo *nd;
467
468     for(i = 0; i < nb_nics; i++) {
469         nd = &nd_table[i];
470         if (!nd->model) {
471             nd->model = "pcnet";
472         }
473         if (i == 0  && strcmp(nd->model, "pcnet") == 0) {
474             /* The malta board has a PCNet card using PCI SLOT 11 */
475             pci_nic_init(pci_bus, nd, 88);
476         } else {
477             pci_nic_init(pci_bus, nd, -1);
478         }
479     }
480 }
481
482 /* ROM and pseudo bootloader
483
484    The following code implements a very very simple bootloader. It first
485    loads the registers a0 to a3 to the values expected by the OS, and
486    then jump at the kernel address.
487
488    The bootloader should pass the locations of the kernel arguments and
489    environment variables tables. Those tables contain the 32-bit address
490    of NULL terminated strings. The environment variables table should be
491    terminated by a NULL address.
492
493    For a simpler implementation, the number of kernel arguments is fixed
494    to two (the name of the kernel and the command line), and the two
495    tables are actually the same one.
496
497    The registers a0 to a3 should contain the following values:
498      a0 - number of kernel arguments
499      a1 - 32-bit address of the kernel arguments table
500      a2 - 32-bit address of the environment variables table
501      a3 - RAM size in bytes
502 */
503
504 static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t kernel_entry)
505 {
506     uint32_t *p;
507
508     /* Small bootloader */
509     p = (uint32_t *) (phys_ram_base + bios_offset);
510     stl_raw(p++, 0x0bf00160);                                      /* j 0x1fc00580 */
511     stl_raw(p++, 0x00000000);                                      /* nop */
512
513     /* YAMON service vector */
514     stl_raw(phys_ram_base + bios_offset + 0x500, 0xbfc00580);      /* start: */                                 
515     stl_raw(phys_ram_base + bios_offset + 0x504, 0xbfc0083c);      /* print_count: */
516     stl_raw(phys_ram_base + bios_offset + 0x520, 0xbfc00580);      /* start: */                                 
517     stl_raw(phys_ram_base + bios_offset + 0x52c, 0xbfc00800);      /* flush_cache: */
518     stl_raw(phys_ram_base + bios_offset + 0x534, 0xbfc00808);      /* print: */
519     stl_raw(phys_ram_base + bios_offset + 0x538, 0xbfc00800);      /* reg_cpu_isr: */
520     stl_raw(phys_ram_base + bios_offset + 0x53c, 0xbfc00800);      /* unred_cpu_isr: */
521     stl_raw(phys_ram_base + bios_offset + 0x540, 0xbfc00800);      /* reg_ic_isr: */
522     stl_raw(phys_ram_base + bios_offset + 0x544, 0xbfc00800);      /* unred_ic_isr: */
523     stl_raw(phys_ram_base + bios_offset + 0x548, 0xbfc00800);      /* reg_esr: */
524     stl_raw(phys_ram_base + bios_offset + 0x54c, 0xbfc00800);      /* unreg_esr: */
525     stl_raw(phys_ram_base + bios_offset + 0x550, 0xbfc00800);      /* getchar: */
526     stl_raw(phys_ram_base + bios_offset + 0x554, 0xbfc00800);      /* syscon_read: */
527
528
529     /* Second part of the bootloader */
530     p = (uint32_t *) (phys_ram_base + bios_offset + 0x580);
531     stl_raw(p++, 0x24040002);                                      /* addiu a0, zero, 2 */
532     stl_raw(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
533     stl_raw(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff));        /* ori sp, sp, low(ENVP_ADDR) */
534     stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));       /* lui a1, high(ENVP_ADDR) */
535     stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a1, low(ENVP_ADDR) */
536     stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
537     stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));         /* ori a2, a2, low(ENVP_ADDR + 8) */
538     stl_raw(p++, 0x3c070000 | (env->ram_size >> 16));              /* lui a3, high(env->ram_size) */
539     stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff));           /* ori a3, a3, low(env->ram_size) */
540
541     /* Load BAR registers as done by YAMON */
542     stl_raw(p++, 0x3c09bbe0);                                      /* lui t1, 0xbbe0 */
543
544 #ifdef TARGET_WORDS_BIGENDIAN
545     stl_raw(p++, 0x3c08c000);                                      /* lui t0, 0xc000 */
546 #else
547     stl_raw(p++, 0x340800c0);                                      /* ori t0, r0, 0x00c0 */
548 #endif
549     stl_raw(p++, 0xad280048);                                      /* sw t0, 0x0048(t1) */
550 #ifdef TARGET_WORDS_BIGENDIAN
551     stl_raw(p++, 0x3c084000);                                      /* lui t0, 0x4000 */
552 #else
553     stl_raw(p++, 0x34080040);                                      /* ori t0, r0, 0x0040 */
554 #endif
555     stl_raw(p++, 0xad280050);                                      /* sw t0, 0x0050(t1) */
556
557 #ifdef TARGET_WORDS_BIGENDIAN
558     stl_raw(p++, 0x3c088000);                                      /* lui t0, 0x8000 */
559 #else
560     stl_raw(p++, 0x34080080);                                      /* ori t0, r0, 0x0080 */
561 #endif
562     stl_raw(p++, 0xad280058);                                      /* sw t0, 0x0058(t1) */
563 #ifdef TARGET_WORDS_BIGENDIAN
564     stl_raw(p++, 0x3c083f00);                                      /* lui t0, 0x3f00 */
565 #else
566     stl_raw(p++, 0x3408003f);                                      /* ori t0, r0, 0x003f */
567 #endif
568     stl_raw(p++, 0xad280060);                                      /* sw t0, 0x0060(t1) */
569
570 #ifdef TARGET_WORDS_BIGENDIAN
571     stl_raw(p++, 0x3c08c100);                                      /* lui t0, 0xc100 */
572 #else
573     stl_raw(p++, 0x340800c1);                                      /* ori t0, r0, 0x00c1 */
574 #endif
575     stl_raw(p++, 0xad280080);                                      /* sw t0, 0x0080(t1) */
576 #ifdef TARGET_WORDS_BIGENDIAN
577     stl_raw(p++, 0x3c085e00);                                      /* lui t0, 0x5e00 */
578 #else
579     stl_raw(p++, 0x3408005e);                                      /* ori t0, r0, 0x005e */
580 #endif
581     stl_raw(p++, 0xad280088);                                      /* sw t0, 0x0088(t1) */
582
583     /* Jump to kernel code */
584     stl_raw(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff));    /* lui ra, high(kernel_entry) */
585     stl_raw(p++, 0x37ff0000 | (kernel_entry & 0xffff));            /* ori ra, ra, low(kernel_entry) */
586     stl_raw(p++, 0x03e00008);                                      /* jr ra */
587     stl_raw(p++, 0x00000000);                                      /* nop */
588
589     /* YAMON subroutines */
590     p = (uint32_t *) (phys_ram_base + bios_offset + 0x800);
591     stl_raw(p++, 0x03e00008);                                     /* jr ra */
592     stl_raw(p++, 0x24020000);                                     /* li v0,0 */
593    /* 808 YAMON print */
594     stl_raw(p++, 0x03e06821);                                     /* move t5,ra */
595     stl_raw(p++, 0x00805821);                                     /* move t3,a0 */
596     stl_raw(p++, 0x00a05021);                                     /* move t2,a1 */
597     stl_raw(p++, 0x91440000);                                     /* lbu a0,0(t2) */
598     stl_raw(p++, 0x254a0001);                                     /* addiu t2,t2,1 */
599     stl_raw(p++, 0x10800005);                                     /* beqz a0,834 */
600     stl_raw(p++, 0x00000000);                                     /* nop */
601     stl_raw(p++, 0x0ff0021c);                                     /* jal 870 */
602     stl_raw(p++, 0x00000000);                                     /* nop */
603     stl_raw(p++, 0x08000205);                                     /* j 814 */
604     stl_raw(p++, 0x00000000);                                     /* nop */
605     stl_raw(p++, 0x01a00008);                                     /* jr t5 */
606     stl_raw(p++, 0x01602021);                                     /* move a0,t3 */
607     /* 0x83c YAMON print_count */
608     stl_raw(p++, 0x03e06821);                                     /* move t5,ra */
609     stl_raw(p++, 0x00805821);                                     /* move t3,a0 */
610     stl_raw(p++, 0x00a05021);                                     /* move t2,a1 */
611     stl_raw(p++, 0x00c06021);                                     /* move t4,a2 */
612     stl_raw(p++, 0x91440000);                                     /* lbu a0,0(t2) */
613     stl_raw(p++, 0x0ff0021c);                                     /* jal 870 */
614     stl_raw(p++, 0x00000000);                                     /* nop */
615     stl_raw(p++, 0x254a0001);                                     /* addiu t2,t2,1 */
616     stl_raw(p++, 0x258cffff);                                     /* addiu t4,t4,-1 */
617     stl_raw(p++, 0x1580fffa);                                     /* bnez t4,84c */
618     stl_raw(p++, 0x00000000);                                     /* nop */
619     stl_raw(p++, 0x01a00008);                                     /* jr t5 */
620     stl_raw(p++, 0x01602021);                                     /* move a0,t3 */
621     /* 0x870 */
622     stl_raw(p++, 0x3c08b800);                                     /* lui t0,0xb400 */
623     stl_raw(p++, 0x350803f8);                                     /* ori t0,t0,0x3f8 */
624     stl_raw(p++, 0x91090005);                                     /* lbu t1,5(t0) */
625     stl_raw(p++, 0x00000000);                                     /* nop */
626     stl_raw(p++, 0x31290040);                                     /* andi t1,t1,0x40 */
627     stl_raw(p++, 0x1120fffc);                                     /* beqz t1,878 <outch+0x8> */
628     stl_raw(p++, 0x00000000);                                     /* nop */
629     stl_raw(p++, 0x03e00008);                                     /* jr ra */
630     stl_raw(p++, 0xa1040000);                                     /* sb a0,0(t0) */
631
632 }
633
634 static void prom_set(int index, const char *string, ...)
635 {
636     va_list ap;
637     int32_t *p;
638     int32_t table_addr;
639     char *s;
640
641     if (index >= ENVP_NB_ENTRIES)
642         return;
643
644     p = (int32_t *) (phys_ram_base + ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
645     p += index;
646
647     if (string == NULL) {
648         stl_raw(p, 0);
649         return;
650     }
651
652     table_addr = ENVP_ADDR + sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
653     s = (char *) (phys_ram_base + VIRT_TO_PHYS_ADDEND + table_addr);
654
655     stl_raw(p, table_addr);
656
657     va_start(ap, string);
658     vsnprintf (s, ENVP_ENTRY_SIZE, string, ap);
659     va_end(ap);
660 }
661
662 /* Kernel */
663 static int64_t load_kernel (CPUState *env)
664 {
665     int64_t kernel_entry, kernel_low, kernel_high;
666     int index = 0;
667     long initrd_size;
668     ram_addr_t initrd_offset;
669
670     if (load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND,
671                  &kernel_entry, &kernel_low, &kernel_high) < 0) {
672         fprintf(stderr, "qemu: could not load kernel '%s'\n",
673                 env->kernel_filename);
674       exit(1);
675     }
676
677     /* load initrd */
678     initrd_size = 0;
679     initrd_offset = 0;
680     if (env->initrd_filename) {
681         initrd_size = get_image_size (env->initrd_filename);
682         if (initrd_size > 0) {
683             initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
684             if (initrd_offset + initrd_size > env->ram_size) {
685                 fprintf(stderr,
686                         "qemu: memory too small for initial ram disk '%s'\n",
687                         env->initrd_filename);
688                 exit(1);
689             }
690             initrd_size = load_image(env->initrd_filename,
691                                      phys_ram_base + initrd_offset);
692         }
693         if (initrd_size == (target_ulong) -1) {
694             fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
695                     env->initrd_filename);
696             exit(1);
697         }
698     }
699
700     /* Store command line.  */
701     prom_set(index++, env->kernel_filename);
702     if (initrd_size > 0)
703         prom_set(index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s",
704                  PHYS_TO_VIRT(initrd_offset), initrd_size,
705                  env->kernel_cmdline);
706     else
707         prom_set(index++, env->kernel_cmdline);
708
709     /* Setup minimum environment variables */
710     prom_set(index++, "memsize");
711     prom_set(index++, "%i", env->ram_size);
712     prom_set(index++, "modetty0");
713     prom_set(index++, "38400n8r");
714     prom_set(index++, NULL);
715
716     return kernel_entry;
717 }
718
719 static void main_cpu_reset(void *opaque)
720 {
721     CPUState *env = opaque;
722     cpu_reset(env);
723     cpu_mips_register(env, NULL);
724
725     /* The bootload does not need to be rewritten as it is located in a
726        read only location. The kernel location and the arguments table
727        location does not change. */
728     if (env->kernel_filename) {
729         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
730         load_kernel (env);
731     }
732 }
733
734 static
735 void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
736                       DisplayState *ds, const char **fd_filename, int snapshot,
737                       const char *kernel_filename, const char *kernel_cmdline,
738                       const char *initrd_filename, const char *cpu_model)
739 {
740     char buf[1024];
741     unsigned long bios_offset;
742     int64_t kernel_entry;
743     PCIBus *pci_bus;
744     CPUState *env;
745     RTCState *rtc_state;
746     /* fdctrl_t *floppy_controller; */
747     MaltaFPGAState *malta_fpga;
748     int ret;
749     mips_def_t *def;
750     qemu_irq *i8259;
751     int piix4_devfn;
752     uint8_t *eeprom_buf;
753     i2c_bus *smbus;
754     int i;
755
756     /* init CPUs */
757     if (cpu_model == NULL) {
758 #ifdef TARGET_MIPS64
759         cpu_model = "20Kc";
760 #else
761         cpu_model = "24Kf";
762 #endif
763     }
764     if (mips_find_by_name(cpu_model, &def) != 0)
765         def = NULL;
766     env = cpu_init();
767     cpu_mips_register(env, def);
768     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
769     qemu_register_reset(main_cpu_reset, env);
770
771     /* allocate RAM */
772     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
773
774     /* Map the bios at two physical locations, as on the real board */
775     bios_offset = ram_size + vga_ram_size;
776     cpu_register_physical_memory(0x1e000000LL,
777                                  BIOS_SIZE, bios_offset | IO_MEM_ROM);
778     cpu_register_physical_memory(0x1fc00000LL,
779                                  BIOS_SIZE, bios_offset | IO_MEM_ROM);
780
781     /* Load a BIOS image except if a kernel image has been specified. In
782        the later case, just write a small bootloader to the flash
783        location. */
784     if (kernel_filename) {
785         env->ram_size = ram_size;
786         env->kernel_filename = kernel_filename;
787         env->kernel_cmdline = kernel_cmdline;
788         env->initrd_filename = initrd_filename;
789         kernel_entry = load_kernel(env);
790         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
791         write_bootloader(env, bios_offset, kernel_entry);
792     } else {
793         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
794         ret = load_image(buf, phys_ram_base + bios_offset);
795         if (ret < 0 || ret > BIOS_SIZE) {
796             fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
797                     buf);
798             exit(1);
799         }
800     }
801
802     /* Board ID = 0x420 (Malta Board with CoreLV)
803        XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
804        map to the board ID. */
805     stl_raw(phys_ram_base + bios_offset + 0x10, 0x00000420);
806
807     /* Init internal devices */
808     cpu_mips_irq_init_cpu(env);
809     cpu_mips_clock_init(env);
810     cpu_mips_irqctrl_init();
811
812     /* FPGA */
813     malta_fpga = malta_fpga_init(0x1f000000LL, env);
814
815     /* Interrupt controller */
816     /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
817     i8259 = i8259_init(env->irq[2]);
818
819     /* Northbridge */
820     pci_bus = pci_gt64120_init(i8259);
821
822     /* Southbridge */
823     piix4_devfn = piix4_init(pci_bus, 80);
824     pci_piix4_ide_init(pci_bus, bs_table, piix4_devfn + 1, i8259);
825     usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
826     smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100);
827     eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
828     for (i = 0; i < 8; i++) {
829         /* TODO: Populate SPD eeprom data.  */
830         smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256));
831     }
832     pit = pit_init(0x40, i8259[0]);
833     DMA_init(0);
834
835     /* Super I/O */
836     i8042_init(i8259[1], i8259[12], 0x60);
837     rtc_state = rtc_init(0x70, i8259[8]);
838     if (serial_hds[0])
839         serial_init(0x3f8, i8259[4], serial_hds[0]);
840     if (serial_hds[1])
841         serial_init(0x2f8, i8259[3], serial_hds[1]);
842     if (parallel_hds[0])
843         parallel_init(0x378, i8259[7], parallel_hds[0]);
844     /* XXX: The floppy controller does not work correctly, something is
845        probably wrong.
846     floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table); */
847
848     /* Sound card */
849 #ifdef HAS_AUDIO
850     audio_init(pci_bus);
851 #endif
852
853     /* Network card */
854     network_init(pci_bus);
855
856     /* Optional PCI video card */
857     pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size,
858                         ram_size, vga_ram_size);
859 }
860
861 QEMUMachine mips_malta_machine = {
862     "malta",
863     "MIPS Malta Core LV",
864     mips_malta_init,
865 };