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