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