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