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