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