Clear BEV and ERL for the fake bootloader.
[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 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
64 static void pic_irq_request(void *opaque, int level)
65 {
66     cpu_mips_irq_request(opaque, 2, level);
67 }
68
69 /* Malta FPGA */
70 static void malta_fpga_update_display(void *opaque)
71 {
72     char leds_text[9];
73     int i;
74     MaltaFPGAState *s = opaque;
75
76     for (i = 7 ; i >= 0 ; i--) {
77         if (s->leds & (1 << i))
78             leds_text[i] = '#';
79         else
80             leds_text[i] = ' ';
81     }
82     leds_text[8] = '\0';
83
84     qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
85     qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
86 }
87
88 /*
89  * EEPROM 24C01 / 24C02 emulation.
90  *
91  * Emulation for serial EEPROMs:
92  * 24C01 - 1024 bit (128 x 8)
93  * 24C02 - 2048 bit (256 x 8)
94  *
95  * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
96  */
97
98 //~ #define DEBUG
99
100 #if defined(DEBUG)
101 #  define logout(fmt, args...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ##args)
102 #else
103 #  define logout(fmt, args...) ((void)0)
104 #endif
105
106 struct _eeprom24c0x_t {
107   uint8_t tick;
108   uint8_t address;
109   uint8_t command;
110   uint8_t ack;
111   uint8_t scl;
112   uint8_t sda;
113   uint8_t data;
114   //~ uint16_t size;
115   uint8_t contents[256];
116 };
117
118 typedef struct _eeprom24c0x_t eeprom24c0x_t;
119
120 static eeprom24c0x_t eeprom = {
121     contents: {
122         /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
123         /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
124         /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
125         /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
126         /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
127         /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128         /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
129         /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
130         /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131         /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132         /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133         /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134         /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135         /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
136         /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
137         /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
138     },
139 };
140
141 static uint8_t eeprom24c0x_read()
142 {
143     logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
144         eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
145     return eeprom.sda;
146 }
147
148 static void eeprom24c0x_write(int scl, int sda)
149 {
150     if (eeprom.scl && scl && (eeprom.sda != sda)) {
151         logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
152                 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda, sda ? "stop" : "start");
153         if (!sda) {
154             eeprom.tick = 1;
155             eeprom.command = 0;
156         }
157     } else if (eeprom.tick == 0 && !eeprom.ack) {
158         /* Waiting for start. */
159         logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
160                 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
161     } else if (!eeprom.scl && scl) {
162         logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
163                 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
164         if (eeprom.ack) {
165             logout("\ti2c ack bit = 0\n");
166             sda = 0;
167             eeprom.ack = 0;
168         } else if (eeprom.sda == sda) {
169             uint8_t bit = (sda != 0);
170             logout("\ti2c bit = %d\n", bit);
171             if (eeprom.tick < 9) {
172                 eeprom.command <<= 1;
173                 eeprom.command += bit;
174                 eeprom.tick++;
175                 if (eeprom.tick == 9) {
176                     logout("\tcommand 0x%04x, %s\n", eeprom.command, bit ? "read" : "write");
177                     eeprom.ack = 1;
178                 }
179             } else if (eeprom.tick < 17) {
180                 if (eeprom.command & 1) {
181                     sda = ((eeprom.data & 0x80) != 0);
182                 }
183                 eeprom.address <<= 1;
184                 eeprom.address += bit;
185                 eeprom.tick++;
186                 eeprom.data <<= 1;
187                 if (eeprom.tick == 17) {
188                     eeprom.data = eeprom.contents[eeprom.address];
189                     logout("\taddress 0x%04x, data 0x%02x\n", eeprom.address, eeprom.data);
190                     eeprom.ack = 1;
191                     eeprom.tick = 0;
192                 }
193             } else if (eeprom.tick >= 17) {
194                 sda = 0;
195             }
196         } else {
197             logout("\tsda changed with raising scl\n");
198         }
199     } else {
200         logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
201     }
202     eeprom.scl = scl;
203     eeprom.sda = sda;
204 }
205
206 static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
207 {
208     MaltaFPGAState *s = opaque;
209     uint32_t val = 0;
210     uint32_t saddr;
211
212     saddr = (addr & 0xfffff);
213
214     switch (saddr) {
215
216     /* SWITCH Register */
217     case 0x00200:
218         val = 0x00000000;               /* All switches closed */
219         break;
220
221     /* STATUS Register */
222     case 0x00208:
223 #ifdef TARGET_WORDS_BIGENDIAN
224         val = 0x00000012;
225 #else
226         val = 0x00000010;
227 #endif
228         break;
229
230     /* JMPRS Register */
231     case 0x00210:
232         val = 0x00;
233         break;
234
235     /* LEDBAR Register */
236     case 0x00408:
237         val = s->leds;
238         break;
239
240     /* BRKRES Register */
241     case 0x00508:
242         val = s->brk;
243         break;
244
245     /* UART Registers */
246     case 0x00900:
247     case 0x00908:
248     case 0x00910:
249     case 0x00918:
250     case 0x00920:
251     case 0x00928:
252     case 0x00930:
253     case 0x00938:
254         val = serial_mm_readb(s->uart, addr);
255         break;
256
257     /* GPOUT Register */
258     case 0x00a00:
259         val = s->gpout;
260         break;
261
262     /* XXX: implement a real I2C controller */
263
264     /* GPINP Register */
265     case 0x00a08:
266         /* IN = OUT until a real I2C control is implemented */
267         if (s->i2csel)
268             val = s->i2cout;
269         else
270             val = 0x00;
271         break;
272
273     /* I2CINP Register */
274     case 0x00b00:
275         val = ((s->i2cin & ~1) | eeprom24c0x_read());
276         break;
277
278     /* I2COE Register */
279     case 0x00b08:
280         val = s->i2coe;
281         break;
282
283     /* I2COUT Register */
284     case 0x00b10:
285         val = s->i2cout;
286         break;
287
288     /* I2CSEL Register */
289     case 0x00b18:
290         val = s->i2csel;
291         break;
292
293     default:
294 #if 0
295         printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
296                 addr);
297 #endif
298         break;
299     }
300     return val;
301 }
302
303 static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
304                               uint32_t val)
305 {
306     MaltaFPGAState *s = opaque;
307     uint32_t saddr;
308
309     saddr = (addr & 0xfffff);
310
311     switch (saddr) {
312
313     /* SWITCH Register */
314     case 0x00200:
315         break;
316
317     /* JMPRS Register */
318     case 0x00210:
319         break;
320
321     /* LEDBAR Register */
322     /* XXX: implement a 8-LED array */
323     case 0x00408:
324         s->leds = val & 0xff;
325         break;
326
327     /* ASCIIWORD Register */
328     case 0x00410:
329         snprintf(s->display_text, 9, "%08X", val);
330         malta_fpga_update_display(s);
331         break;
332
333     /* ASCIIPOS0 to ASCIIPOS7 Registers */
334     case 0x00418:
335     case 0x00420:
336     case 0x00428:
337     case 0x00430:
338     case 0x00438:
339     case 0x00440:
340     case 0x00448:
341     case 0x00450:
342         s->display_text[(saddr - 0x00418) >> 3] = (char) val;
343         malta_fpga_update_display(s);
344         break;
345
346     /* SOFTRES Register */
347     case 0x00500:
348         if (val == 0x42)
349             qemu_system_reset_request ();
350         break;
351
352     /* BRKRES Register */
353     case 0x00508:
354         s->brk = val & 0xff;
355         break;
356
357     /* UART Registers */
358     case 0x00900:
359     case 0x00908:
360     case 0x00910:
361     case 0x00918:
362     case 0x00920:
363     case 0x00928:
364     case 0x00930:
365     case 0x00938:
366         serial_mm_writeb(s->uart, addr, val);
367         break;
368
369     /* GPOUT Register */
370     case 0x00a00:
371         s->gpout = val & 0xff;
372         break;
373
374     /* I2COE Register */
375     case 0x00b08:
376         s->i2coe = val & 0x03;
377         break;
378
379     /* I2COUT Register */
380     case 0x00b10:
381         eeprom24c0x_write(val & 0x02, val & 0x01);
382         s->i2cout = val;
383         break;
384
385     /* I2CSEL Register */
386     case 0x00b18:
387         s->i2csel = val & 0x01;
388         break;
389
390     default:
391 #if 0
392         printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
393                 addr);
394 #endif
395         break;
396     }
397 }
398
399 static CPUReadMemoryFunc *malta_fpga_read[] = {
400    malta_fpga_readl,
401    malta_fpga_readl,
402    malta_fpga_readl
403 };
404
405 static CPUWriteMemoryFunc *malta_fpga_write[] = {
406    malta_fpga_writel,
407    malta_fpga_writel,
408    malta_fpga_writel
409 };
410
411 void malta_fpga_reset(void *opaque)
412 {
413     MaltaFPGAState *s = opaque;
414
415     s->leds   = 0x00;
416     s->brk    = 0x0a;
417     s->gpout  = 0x00;
418     s->i2cin  = 0x3;
419     s->i2coe  = 0x0;
420     s->i2cout = 0x3;
421     s->i2csel = 0x1;
422
423     s->display_text[8] = '\0';
424     snprintf(s->display_text, 9, "        ");
425     malta_fpga_update_display(s);
426 }
427
428 MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, CPUState *env)
429 {
430     MaltaFPGAState *s;
431     CharDriverState *uart_chr;
432     int malta;
433
434     s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
435
436     malta = cpu_register_io_memory(0, malta_fpga_read,
437                                    malta_fpga_write, s);
438
439     cpu_register_physical_memory(base, 0x100000, malta);
440
441     s->display = qemu_chr_open("vc");
442     qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
443     qemu_chr_printf(s->display, "+--------+\r\n");
444     qemu_chr_printf(s->display, "+        +\r\n");
445     qemu_chr_printf(s->display, "+--------+\r\n");
446     qemu_chr_printf(s->display, "\n");
447     qemu_chr_printf(s->display, "Malta ASCII\r\n");
448     qemu_chr_printf(s->display, "+--------+\r\n");
449     qemu_chr_printf(s->display, "+        +\r\n");
450     qemu_chr_printf(s->display, "+--------+\r\n");
451
452     uart_chr = qemu_chr_open("vc");
453     qemu_chr_printf(uart_chr, "CBUS UART\r\n");
454     s->uart = serial_mm_init(&cpu_mips_irq_request, env, base, 3, 2,
455                              uart_chr, 0);
456
457     malta_fpga_reset(s);
458     qemu_register_reset(malta_fpga_reset, s);
459
460     return s;
461 }
462
463 /* Audio support */
464 #ifdef HAS_AUDIO
465 static void audio_init (PCIBus *pci_bus)
466 {
467     struct soundhw *c;
468     int audio_enabled = 0;
469
470     for (c = soundhw; !audio_enabled && c->name; ++c) {
471         audio_enabled = c->enabled;
472     }
473
474     if (audio_enabled) {
475         AudioState *s;
476
477         s = AUD_init ();
478         if (s) {
479             for (c = soundhw; c->name; ++c) {
480                 if (c->enabled) {
481                     if (c->isa) {
482                         fprintf(stderr, "qemu: Unsupported Sound Card: %s\n", c->name);
483                         exit(1);
484                     }
485                     else {
486                         if (pci_bus) {
487                             c->init.init_pci (pci_bus, s);
488                         }
489                     }
490                 }
491             }
492         }
493     }
494 }
495 #endif
496
497 /* Network support */
498 static void network_init (PCIBus *pci_bus)
499 {
500     int i;
501     NICInfo *nd;
502
503     for(i = 0; i < nb_nics; i++) {
504         nd = &nd_table[i];
505         if (!nd->model) {
506             nd->model = "pcnet";
507         }
508         if (i == 0  && strcmp(nd->model, "pcnet") == 0) {
509             /* The malta board has a PCNet card using PCI SLOT 11 */
510             pci_nic_init(pci_bus, nd, 88);
511         } else {
512             pci_nic_init(pci_bus, nd, -1);
513         }
514     }
515 }
516
517 /* ROM and pseudo bootloader
518
519    The following code implements a very very simple bootloader. It first
520    loads the registers a0 to a3 to the values expected by the OS, and
521    then jump at the kernel address.
522
523    The bootloader should pass the locations of the kernel arguments and
524    environment variables tables. Those tables contain the 32-bit address
525    of NULL terminated strings. The environment variables table should be
526    terminated by a NULL address.
527
528    For a simpler implementation, the number of kernel arguments is fixed
529    to two (the name of the kernel and the command line), and the two
530    tables are actually the same one.
531
532    The registers a0 to a3 should contain the following values:
533      a0 - number of kernel arguments
534      a1 - 32-bit address of the kernel arguments table
535      a2 - 32-bit address of the environment variables table
536      a3 - RAM size in bytes
537 */
538
539 static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t kernel_entry)
540 {
541     uint32_t *p;
542
543     /* Small bootloader */
544     p = (uint32_t *) (phys_ram_base + bios_offset);
545     stl_raw(p++, 0x0bf00010);                                      /* j 0x1fc00040 */
546     stl_raw(p++, 0x00000000);                                      /* nop */
547
548     /* Second part of the bootloader */
549     p = (uint32_t *) (phys_ram_base + bios_offset + 0x040);
550     stl_raw(p++, 0x3c040000);                                      /* lui a0, 0 */
551     stl_raw(p++, 0x34840002);                                      /* ori a0, a0, 2 */
552     stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));       /* lui a1, high(ENVP_ADDR) */
553     stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a0, low(ENVP_ADDR) */
554     stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
555     stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));         /* ori a2, a2, low(ENVP_ADDR + 8) */
556     stl_raw(p++, 0x3c070000 | (env->ram_size >> 16));              /* lui a3, high(env->ram_size) */
557     stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff));           /* ori a3, a3, low(env->ram_size) */
558     stl_raw(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff));    /* lui ra, high(kernel_entry) */
559     stl_raw(p++, 0x37ff0000 | (kernel_entry & 0xffff));            /* ori ra, ra, low(kernel_entry) */
560     stl_raw(p++, 0x03e00008);                                      /* jr ra */
561     stl_raw(p++, 0x00000000);                                      /* nop */
562 }
563
564 static void prom_set(int index, const char *string, ...)
565 {
566     va_list ap;
567     int32_t *p;
568     int32_t table_addr;
569     char *s;
570
571     if (index >= ENVP_NB_ENTRIES)
572         return;
573
574     p = (int32_t *) (phys_ram_base + ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
575     p += index;
576
577     if (string == NULL) {
578         stl_raw(p, 0);
579         return;
580     }
581
582     table_addr = ENVP_ADDR + sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
583     s = (char *) (phys_ram_base + VIRT_TO_PHYS_ADDEND + table_addr);
584
585     stl_raw(p, table_addr);
586
587     va_start(ap, string);
588     vsnprintf (s, ENVP_ENTRY_SIZE, string, ap);
589     va_end(ap);
590 }
591
592 /* Kernel */
593 static int64_t load_kernel (CPUState *env)
594 {
595     int64_t kernel_entry, kernel_low, kernel_high;
596     int index = 0;
597     long initrd_size;
598     ram_addr_t initrd_offset;
599
600     if (load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND,
601                  &kernel_entry, &kernel_low, &kernel_high) < 0) {
602         fprintf(stderr, "qemu: could not load kernel '%s'\n",
603                 env->kernel_filename);
604       exit(1);
605     }
606
607     /* load initrd */
608     initrd_size = 0;
609     initrd_offset = 0;
610     if (env->initrd_filename) {
611         initrd_size = get_image_size (env->initrd_filename);
612         if (initrd_size > 0) {
613             initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
614             if (initrd_offset + initrd_size > env->ram_size) {
615                 fprintf(stderr,
616                         "qemu: memory too small for initial ram disk '%s'\n",
617                         env->initrd_filename);
618                 exit(1);
619             }
620             initrd_size = load_image(env->initrd_filename,
621                                      phys_ram_base + initrd_offset);
622         }
623         if (initrd_size == (target_ulong) -1) {
624             fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
625                     env->initrd_filename);
626             exit(1);
627         }
628     }
629
630     /* Store command line.  */
631     prom_set(index++, env->kernel_filename);
632     if (initrd_size > 0)
633         prom_set(index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s",
634                  PHYS_TO_VIRT(initrd_offset), initrd_size,
635                  env->kernel_cmdline);
636     else
637         prom_set(index++, env->kernel_cmdline);
638
639     /* Setup minimum environment variables */
640     prom_set(index++, "memsize");
641     prom_set(index++, "%i", env->ram_size);
642     prom_set(index++, "modetty0");
643     prom_set(index++, "38400n8r");
644     prom_set(index++, NULL);
645
646     return kernel_entry;
647 }
648
649 static void main_cpu_reset(void *opaque)
650 {
651     CPUState *env = opaque;
652     cpu_reset(env);
653
654     /* The bootload does not need to be rewritten as it is located in a
655        read only location. The kernel location and the arguments table
656        location does not change. */
657     if (env->kernel_filename) {
658         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
659         load_kernel (env);
660     }
661 }
662
663 static
664 void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
665                       DisplayState *ds, const char **fd_filename, int snapshot,
666                       const char *kernel_filename, const char *kernel_cmdline,
667                       const char *initrd_filename, const char *cpu_model)
668 {
669     char buf[1024];
670     unsigned long bios_offset;
671     int64_t kernel_entry;
672     PCIBus *pci_bus;
673     CPUState *env;
674     RTCState *rtc_state;
675     /* fdctrl_t *floppy_controller; */
676     MaltaFPGAState *malta_fpga;
677     int ret;
678     mips_def_t *def;
679
680     /* init CPUs */
681     if (cpu_model == NULL) {
682 #ifdef TARGET_MIPS64
683         cpu_model = "R4000";
684 #else
685         cpu_model = "4KEc";
686 #endif
687     }
688     if (mips_find_by_name(cpu_model, &def) != 0)
689         def = NULL;
690     env = cpu_init();
691     cpu_mips_register(env, def);
692     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
693     qemu_register_reset(main_cpu_reset, env);
694
695     /* allocate RAM */
696     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
697
698     /* Map the bios at two physical locations, as on the real board */
699     bios_offset = ram_size + vga_ram_size;
700     cpu_register_physical_memory(0x1e000000LL,
701                                  BIOS_SIZE, bios_offset | IO_MEM_ROM);
702     cpu_register_physical_memory(0x1fc00000LL,
703                                  BIOS_SIZE, bios_offset | IO_MEM_ROM);
704
705     /* Load a BIOS image except if a kernel image has been specified. In
706        the later case, just write a small bootloader to the flash
707        location. */
708     if (kernel_filename) {
709         env->ram_size = ram_size;
710         env->kernel_filename = kernel_filename;
711         env->kernel_cmdline = kernel_cmdline;
712         env->initrd_filename = initrd_filename;
713         kernel_entry = load_kernel(env);
714         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
715         write_bootloader(env, bios_offset, kernel_entry);
716     } else {
717         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
718         ret = load_image(buf, phys_ram_base + bios_offset);
719         if (ret < 0 || ret > BIOS_SIZE) {
720             fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
721                     buf);
722             exit(1);
723         }
724     }
725
726     /* Board ID = 0x420 (Malta Board with CoreLV)
727        XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
728        map to the board ID. */
729     stl_raw(phys_ram_base + bios_offset + 0x10, 0x00000420);
730
731     /* Init internal devices */
732     cpu_mips_clock_init(env);
733     cpu_mips_irqctrl_init();
734
735     /* FPGA */
736     malta_fpga = malta_fpga_init(0x1f000000LL, env);
737
738     /* Interrupt controller */
739     isa_pic = pic_init(pic_irq_request, env);
740
741     /* Northbridge */
742     pci_bus = pci_gt64120_init(isa_pic);
743
744     /* Southbridge */
745     piix4_init(pci_bus, 80);
746     pci_piix3_ide_init(pci_bus, bs_table, 81);
747     usb_uhci_init(pci_bus, 82);
748     piix4_pm_init(pci_bus, 83);
749     pit = pit_init(0x40, 0);
750     DMA_init(0);
751
752     /* Super I/O */
753     kbd_init();
754     rtc_state = rtc_init(0x70, 8);
755     if (serial_hds[0])
756         serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
757     if (serial_hds[1])
758         serial_init(&pic_set_irq_new, isa_pic, 0x2f8, 3, serial_hds[1]);
759     if (parallel_hds[0])
760         parallel_init(0x378, 7, parallel_hds[0]);
761     /* XXX: The floppy controller does not work correctly, something is
762        probably wrong.
763     floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); */
764
765     /* Sound card */
766 #ifdef HAS_AUDIO
767     audio_init(pci_bus);
768 #endif
769
770     /* Network card */
771     network_init(pci_bus);
772
773     /* Optional PCI video card */
774     pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size,
775                         ram_size, vga_ram_size);
776 }
777
778 QEMUMachine mips_malta_machine = {
779     "malta",
780     "MIPS Malta Core LV",
781     mips_malta_init,
782 };