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