2 * QEMU Malta board support
4 * Copyright (c) 2006 Aurelien Jarno
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
26 #include "hw/i386/pc.h"
27 #include "hw/char/serial.h"
28 #include "hw/block/fdc.h"
30 #include "hw/boards.h"
31 #include "hw/i2c/smbus.h"
32 #include "block/block.h"
33 #include "hw/block/flash.h"
34 #include "hw/mips/mips.h"
35 #include "hw/mips/cpudevs.h"
36 #include "hw/pci/pci.h"
37 #include "sysemu/char.h"
38 #include "sysemu/sysemu.h"
39 #include "sysemu/arch_init.h"
41 #include "hw/mips/bios.h"
43 #include "hw/loader.h"
45 #include "hw/timer/mc146818rtc.h"
46 #include "hw/timer/i8254.h"
47 #include "sysemu/blockdev.h"
48 #include "exec/address-spaces.h"
49 #include "hw/sysbus.h" /* SysBusDevice */
50 #include "qemu/host-utils.h"
51 #include "sysemu/qtest.h"
53 //#define DEBUG_BOARD_INIT
55 #define ENVP_ADDR 0x80002000l
56 #define ENVP_NB_ENTRIES 16
57 #define ENVP_ENTRY_SIZE 256
59 /* Hardware addresses */
60 #define FLASH_ADDRESS 0x1e000000ULL
61 #define FPGA_ADDRESS 0x1f000000ULL
62 #define RESET_ADDRESS 0x1fc00000ULL
64 #define FLASH_SIZE 0x400000
70 MemoryRegion iomem_lo
; /* 0 - 0x900 */
71 MemoryRegion iomem_hi
; /* 0xa00 - 0x100000 */
79 CharDriverState
*display
;
84 #define TYPE_MIPS_MALTA "mips-malta"
85 #define MIPS_MALTA(obj) OBJECT_CHECK(MaltaState, (obj), TYPE_MIPS_MALTA)
88 SysBusDevice parent_obj
;
93 static ISADevice
*pit
;
95 static struct _loaderparams
{
97 const char *kernel_filename
;
98 const char *kernel_cmdline
;
99 const char *initrd_filename
;
103 static void malta_fpga_update_display(void *opaque
)
107 MaltaFPGAState
*s
= opaque
;
109 for (i
= 7 ; i
>= 0 ; i
--) {
110 if (s
->leds
& (1 << i
))
117 qemu_chr_fe_printf(s
->display
, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text
);
118 qemu_chr_fe_printf(s
->display
, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s
->display_text
);
122 * EEPROM 24C01 / 24C02 emulation.
124 * Emulation for serial EEPROMs:
125 * 24C01 - 1024 bit (128 x 8)
126 * 24C02 - 2048 bit (256 x 8)
128 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
134 # define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
136 # define logout(fmt, ...) ((void)0)
139 struct _eeprom24c0x_t
{
148 uint8_t contents
[256];
151 typedef struct _eeprom24c0x_t eeprom24c0x_t
;
153 static eeprom24c0x_t spd_eeprom
= {
155 /* 00000000: */ 0x80,0x08,0xFF,0x0D,0x0A,0xFF,0x40,0x00,
156 /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
157 /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x00,0x00,
158 /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0xFF,
159 /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
160 /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
161 /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
162 /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
163 /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
164 /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
165 /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
166 /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
167 /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
168 /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
169 /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
170 /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
174 static void generate_eeprom_spd(uint8_t *eeprom
, ram_addr_t ram_size
)
176 enum { SDR
= 0x4, DDR2
= 0x8 } type
;
177 uint8_t *spd
= spd_eeprom
.contents
;
179 uint16_t density
= 0;
182 /* work in terms of MB */
185 while ((ram_size
>= 4) && (nbanks
<= 2)) {
186 int sz_log2
= MIN(31 - clz32(ram_size
), 14);
188 density
|= 1 << (sz_log2
- 2);
189 ram_size
-= 1 << sz_log2
;
192 /* split to 2 banks if possible */
193 if ((nbanks
== 1) && (density
> 1)) {
198 if (density
& 0xff00) {
199 density
= (density
& 0xe0) | ((density
>> 8) & 0x1f);
201 } else if (!(density
& 0x1f)) {
208 fprintf(stderr
, "Warning: SPD cannot represent final %dMB"
209 " of SDRAM\n", (int)ram_size
);
212 /* fill in SPD memory information */
219 for (i
= 0; i
< 63; i
++) {
224 memcpy(eeprom
, spd
, sizeof(spd_eeprom
.contents
));
227 static void generate_eeprom_serial(uint8_t *eeprom
)
230 uint8_t mac
[6] = { 0x00 };
231 uint8_t sn
[5] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
234 eeprom
[pos
++] = 0x01;
237 eeprom
[pos
++] = 0x02;
240 eeprom
[pos
++] = 0x01; /* MAC */
241 eeprom
[pos
++] = 0x06; /* length */
242 memcpy(&eeprom
[pos
], mac
, sizeof(mac
));
246 eeprom
[pos
++] = 0x02; /* serial */
247 eeprom
[pos
++] = 0x05; /* length */
248 memcpy(&eeprom
[pos
], sn
, sizeof(sn
));
253 for (i
= 0; i
< pos
; i
++) {
254 eeprom
[pos
] += eeprom
[i
];
258 static uint8_t eeprom24c0x_read(eeprom24c0x_t
*eeprom
)
260 logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
261 eeprom
->tick
, eeprom
->scl
, eeprom
->sda
, eeprom
->data
);
265 static void eeprom24c0x_write(eeprom24c0x_t
*eeprom
, int scl
, int sda
)
267 if (eeprom
->scl
&& scl
&& (eeprom
->sda
!= sda
)) {
268 logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
269 eeprom
->tick
, eeprom
->scl
, scl
, eeprom
->sda
, sda
,
270 sda
? "stop" : "start");
275 } else if (eeprom
->tick
== 0 && !eeprom
->ack
) {
276 /* Waiting for start. */
277 logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
278 eeprom
->tick
, eeprom
->scl
, scl
, eeprom
->sda
, sda
);
279 } else if (!eeprom
->scl
&& scl
) {
280 logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
281 eeprom
->tick
, eeprom
->scl
, scl
, eeprom
->sda
, sda
);
283 logout("\ti2c ack bit = 0\n");
286 } else if (eeprom
->sda
== sda
) {
287 uint8_t bit
= (sda
!= 0);
288 logout("\ti2c bit = %d\n", bit
);
289 if (eeprom
->tick
< 9) {
290 eeprom
->command
<<= 1;
291 eeprom
->command
+= bit
;
293 if (eeprom
->tick
== 9) {
294 logout("\tcommand 0x%04x, %s\n", eeprom
->command
,
295 bit
? "read" : "write");
298 } else if (eeprom
->tick
< 17) {
299 if (eeprom
->command
& 1) {
300 sda
= ((eeprom
->data
& 0x80) != 0);
302 eeprom
->address
<<= 1;
303 eeprom
->address
+= bit
;
306 if (eeprom
->tick
== 17) {
307 eeprom
->data
= eeprom
->contents
[eeprom
->address
];
308 logout("\taddress 0x%04x, data 0x%02x\n",
309 eeprom
->address
, eeprom
->data
);
313 } else if (eeprom
->tick
>= 17) {
317 logout("\tsda changed with raising scl\n");
320 logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom
->tick
, eeprom
->scl
,
321 scl
, eeprom
->sda
, sda
);
327 static uint64_t malta_fpga_read(void *opaque
, hwaddr addr
,
330 MaltaFPGAState
*s
= opaque
;
334 saddr
= (addr
& 0xfffff);
338 /* SWITCH Register */
340 val
= 0x00000000; /* All switches closed */
343 /* STATUS Register */
345 #ifdef TARGET_WORDS_BIGENDIAN
357 /* LEDBAR Register */
362 /* BRKRES Register */
367 /* UART Registers are handled directly by the serial device */
374 /* XXX: implement a real I2C controller */
378 /* IN = OUT until a real I2C control is implemented */
385 /* I2CINP Register */
387 val
= ((s
->i2cin
& ~1) | eeprom24c0x_read(&spd_eeprom
));
395 /* I2COUT Register */
400 /* I2CSEL Register */
407 printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx
"\n",
415 static void malta_fpga_write(void *opaque
, hwaddr addr
,
416 uint64_t val
, unsigned size
)
418 MaltaFPGAState
*s
= opaque
;
421 saddr
= (addr
& 0xfffff);
425 /* SWITCH Register */
433 /* LEDBAR Register */
435 s
->leds
= val
& 0xff;
436 malta_fpga_update_display(s
);
439 /* ASCIIWORD Register */
441 snprintf(s
->display_text
, 9, "%08X", (uint32_t)val
);
442 malta_fpga_update_display(s
);
445 /* ASCIIPOS0 to ASCIIPOS7 Registers */
454 s
->display_text
[(saddr
- 0x00418) >> 3] = (char) val
;
455 malta_fpga_update_display(s
);
458 /* SOFTRES Register */
461 qemu_system_reset_request ();
464 /* BRKRES Register */
469 /* UART Registers are handled directly by the serial device */
473 s
->gpout
= val
& 0xff;
478 s
->i2coe
= val
& 0x03;
481 /* I2COUT Register */
483 eeprom24c0x_write(&spd_eeprom
, val
& 0x02, val
& 0x01);
487 /* I2CSEL Register */
489 s
->i2csel
= val
& 0x01;
494 printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx
"\n",
501 static const MemoryRegionOps malta_fpga_ops
= {
502 .read
= malta_fpga_read
,
503 .write
= malta_fpga_write
,
504 .endianness
= DEVICE_NATIVE_ENDIAN
,
507 static void malta_fpga_reset(void *opaque
)
509 MaltaFPGAState
*s
= opaque
;
519 s
->display_text
[8] = '\0';
520 snprintf(s
->display_text
, 9, " ");
523 static void malta_fpga_led_init(CharDriverState
*chr
)
525 qemu_chr_fe_printf(chr
, "\e[HMalta LEDBAR\r\n");
526 qemu_chr_fe_printf(chr
, "+--------+\r\n");
527 qemu_chr_fe_printf(chr
, "+ +\r\n");
528 qemu_chr_fe_printf(chr
, "+--------+\r\n");
529 qemu_chr_fe_printf(chr
, "\n");
530 qemu_chr_fe_printf(chr
, "Malta ASCII\r\n");
531 qemu_chr_fe_printf(chr
, "+--------+\r\n");
532 qemu_chr_fe_printf(chr
, "+ +\r\n");
533 qemu_chr_fe_printf(chr
, "+--------+\r\n");
536 static MaltaFPGAState
*malta_fpga_init(MemoryRegion
*address_space
,
537 hwaddr base
, qemu_irq uart_irq
, CharDriverState
*uart_chr
)
541 s
= (MaltaFPGAState
*)g_malloc0(sizeof(MaltaFPGAState
));
543 memory_region_init_io(&s
->iomem
, NULL
, &malta_fpga_ops
, s
,
544 "malta-fpga", 0x100000);
545 memory_region_init_alias(&s
->iomem_lo
, NULL
, "malta-fpga",
546 &s
->iomem
, 0, 0x900);
547 memory_region_init_alias(&s
->iomem_hi
, NULL
, "malta-fpga",
548 &s
->iomem
, 0xa00, 0x10000-0xa00);
550 memory_region_add_subregion(address_space
, base
, &s
->iomem_lo
);
551 memory_region_add_subregion(address_space
, base
+ 0xa00, &s
->iomem_hi
);
553 s
->display
= qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init
);
555 s
->uart
= serial_mm_init(address_space
, base
+ 0x900, 3, uart_irq
,
556 230400, uart_chr
, DEVICE_NATIVE_ENDIAN
);
559 qemu_register_reset(malta_fpga_reset
, s
);
564 /* Network support */
565 static void network_init(PCIBus
*pci_bus
)
569 for(i
= 0; i
< nb_nics
; i
++) {
570 NICInfo
*nd
= &nd_table
[i
];
571 const char *default_devaddr
= NULL
;
573 if (i
== 0 && (!nd
->model
|| strcmp(nd
->model
, "pcnet") == 0))
574 /* The malta board has a PCNet card using PCI SLOT 11 */
575 default_devaddr
= "0b";
577 pci_nic_init_nofail(nd
, pci_bus
, "pcnet", default_devaddr
);
581 /* ROM and pseudo bootloader
583 The following code implements a very very simple bootloader. It first
584 loads the registers a0 to a3 to the values expected by the OS, and
585 then jump at the kernel address.
587 The bootloader should pass the locations of the kernel arguments and
588 environment variables tables. Those tables contain the 32-bit address
589 of NULL terminated strings. The environment variables table should be
590 terminated by a NULL address.
592 For a simpler implementation, the number of kernel arguments is fixed
593 to two (the name of the kernel and the command line), and the two
594 tables are actually the same one.
596 The registers a0 to a3 should contain the following values:
597 a0 - number of kernel arguments
598 a1 - 32-bit address of the kernel arguments table
599 a2 - 32-bit address of the environment variables table
600 a3 - RAM size in bytes
603 static void write_bootloader (CPUMIPSState
*env
, uint8_t *base
,
604 int64_t kernel_entry
)
608 /* Small bootloader */
609 p
= (uint32_t *)base
;
610 stl_raw(p
++, 0x0bf00160); /* j 0x1fc00580 */
611 stl_raw(p
++, 0x00000000); /* nop */
613 /* YAMON service vector */
614 stl_raw(base
+ 0x500, 0xbfc00580); /* start: */
615 stl_raw(base
+ 0x504, 0xbfc0083c); /* print_count: */
616 stl_raw(base
+ 0x520, 0xbfc00580); /* start: */
617 stl_raw(base
+ 0x52c, 0xbfc00800); /* flush_cache: */
618 stl_raw(base
+ 0x534, 0xbfc00808); /* print: */
619 stl_raw(base
+ 0x538, 0xbfc00800); /* reg_cpu_isr: */
620 stl_raw(base
+ 0x53c, 0xbfc00800); /* unred_cpu_isr: */
621 stl_raw(base
+ 0x540, 0xbfc00800); /* reg_ic_isr: */
622 stl_raw(base
+ 0x544, 0xbfc00800); /* unred_ic_isr: */
623 stl_raw(base
+ 0x548, 0xbfc00800); /* reg_esr: */
624 stl_raw(base
+ 0x54c, 0xbfc00800); /* unreg_esr: */
625 stl_raw(base
+ 0x550, 0xbfc00800); /* getchar: */
626 stl_raw(base
+ 0x554, 0xbfc00800); /* syscon_read: */
629 /* Second part of the bootloader */
630 p
= (uint32_t *) (base
+ 0x580);
631 stl_raw(p
++, 0x24040002); /* addiu a0, zero, 2 */
632 stl_raw(p
++, 0x3c1d0000 | (((ENVP_ADDR
- 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
633 stl_raw(p
++, 0x37bd0000 | ((ENVP_ADDR
- 64) & 0xffff)); /* ori sp, sp, low(ENVP_ADDR) */
634 stl_raw(p
++, 0x3c050000 | ((ENVP_ADDR
>> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
635 stl_raw(p
++, 0x34a50000 | (ENVP_ADDR
& 0xffff)); /* ori a1, a1, low(ENVP_ADDR) */
636 stl_raw(p
++, 0x3c060000 | (((ENVP_ADDR
+ 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
637 stl_raw(p
++, 0x34c60000 | ((ENVP_ADDR
+ 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */
638 stl_raw(p
++, 0x3c070000 | (loaderparams
.ram_size
>> 16)); /* lui a3, high(ram_size) */
639 stl_raw(p
++, 0x34e70000 | (loaderparams
.ram_size
& 0xffff)); /* ori a3, a3, low(ram_size) */
641 /* Load BAR registers as done by YAMON */
642 stl_raw(p
++, 0x3c09b400); /* lui t1, 0xb400 */
644 #ifdef TARGET_WORDS_BIGENDIAN
645 stl_raw(p
++, 0x3c08df00); /* lui t0, 0xdf00 */
647 stl_raw(p
++, 0x340800df); /* ori t0, r0, 0x00df */
649 stl_raw(p
++, 0xad280068); /* sw t0, 0x0068(t1) */
651 stl_raw(p
++, 0x3c09bbe0); /* lui t1, 0xbbe0 */
653 #ifdef TARGET_WORDS_BIGENDIAN
654 stl_raw(p
++, 0x3c08c000); /* lui t0, 0xc000 */
656 stl_raw(p
++, 0x340800c0); /* ori t0, r0, 0x00c0 */
658 stl_raw(p
++, 0xad280048); /* sw t0, 0x0048(t1) */
659 #ifdef TARGET_WORDS_BIGENDIAN
660 stl_raw(p
++, 0x3c084000); /* lui t0, 0x4000 */
662 stl_raw(p
++, 0x34080040); /* ori t0, r0, 0x0040 */
664 stl_raw(p
++, 0xad280050); /* sw t0, 0x0050(t1) */
666 #ifdef TARGET_WORDS_BIGENDIAN
667 stl_raw(p
++, 0x3c088000); /* lui t0, 0x8000 */
669 stl_raw(p
++, 0x34080080); /* ori t0, r0, 0x0080 */
671 stl_raw(p
++, 0xad280058); /* sw t0, 0x0058(t1) */
672 #ifdef TARGET_WORDS_BIGENDIAN
673 stl_raw(p
++, 0x3c083f00); /* lui t0, 0x3f00 */
675 stl_raw(p
++, 0x3408003f); /* ori t0, r0, 0x003f */
677 stl_raw(p
++, 0xad280060); /* sw t0, 0x0060(t1) */
679 #ifdef TARGET_WORDS_BIGENDIAN
680 stl_raw(p
++, 0x3c08c100); /* lui t0, 0xc100 */
682 stl_raw(p
++, 0x340800c1); /* ori t0, r0, 0x00c1 */
684 stl_raw(p
++, 0xad280080); /* sw t0, 0x0080(t1) */
685 #ifdef TARGET_WORDS_BIGENDIAN
686 stl_raw(p
++, 0x3c085e00); /* lui t0, 0x5e00 */
688 stl_raw(p
++, 0x3408005e); /* ori t0, r0, 0x005e */
690 stl_raw(p
++, 0xad280088); /* sw t0, 0x0088(t1) */
692 /* Jump to kernel code */
693 stl_raw(p
++, 0x3c1f0000 | ((kernel_entry
>> 16) & 0xffff)); /* lui ra, high(kernel_entry) */
694 stl_raw(p
++, 0x37ff0000 | (kernel_entry
& 0xffff)); /* ori ra, ra, low(kernel_entry) */
695 stl_raw(p
++, 0x03e00008); /* jr ra */
696 stl_raw(p
++, 0x00000000); /* nop */
698 /* YAMON subroutines */
699 p
= (uint32_t *) (base
+ 0x800);
700 stl_raw(p
++, 0x03e00008); /* jr ra */
701 stl_raw(p
++, 0x24020000); /* li v0,0 */
702 /* 808 YAMON print */
703 stl_raw(p
++, 0x03e06821); /* move t5,ra */
704 stl_raw(p
++, 0x00805821); /* move t3,a0 */
705 stl_raw(p
++, 0x00a05021); /* move t2,a1 */
706 stl_raw(p
++, 0x91440000); /* lbu a0,0(t2) */
707 stl_raw(p
++, 0x254a0001); /* addiu t2,t2,1 */
708 stl_raw(p
++, 0x10800005); /* beqz a0,834 */
709 stl_raw(p
++, 0x00000000); /* nop */
710 stl_raw(p
++, 0x0ff0021c); /* jal 870 */
711 stl_raw(p
++, 0x00000000); /* nop */
712 stl_raw(p
++, 0x08000205); /* j 814 */
713 stl_raw(p
++, 0x00000000); /* nop */
714 stl_raw(p
++, 0x01a00008); /* jr t5 */
715 stl_raw(p
++, 0x01602021); /* move a0,t3 */
716 /* 0x83c YAMON print_count */
717 stl_raw(p
++, 0x03e06821); /* move t5,ra */
718 stl_raw(p
++, 0x00805821); /* move t3,a0 */
719 stl_raw(p
++, 0x00a05021); /* move t2,a1 */
720 stl_raw(p
++, 0x00c06021); /* move t4,a2 */
721 stl_raw(p
++, 0x91440000); /* lbu a0,0(t2) */
722 stl_raw(p
++, 0x0ff0021c); /* jal 870 */
723 stl_raw(p
++, 0x00000000); /* nop */
724 stl_raw(p
++, 0x254a0001); /* addiu t2,t2,1 */
725 stl_raw(p
++, 0x258cffff); /* addiu t4,t4,-1 */
726 stl_raw(p
++, 0x1580fffa); /* bnez t4,84c */
727 stl_raw(p
++, 0x00000000); /* nop */
728 stl_raw(p
++, 0x01a00008); /* jr t5 */
729 stl_raw(p
++, 0x01602021); /* move a0,t3 */
731 stl_raw(p
++, 0x3c08b800); /* lui t0,0xb400 */
732 stl_raw(p
++, 0x350803f8); /* ori t0,t0,0x3f8 */
733 stl_raw(p
++, 0x91090005); /* lbu t1,5(t0) */
734 stl_raw(p
++, 0x00000000); /* nop */
735 stl_raw(p
++, 0x31290040); /* andi t1,t1,0x40 */
736 stl_raw(p
++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */
737 stl_raw(p
++, 0x00000000); /* nop */
738 stl_raw(p
++, 0x03e00008); /* jr ra */
739 stl_raw(p
++, 0xa1040000); /* sb a0,0(t0) */
743 static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf
, int index
,
744 const char *string
, ...)
749 if (index
>= ENVP_NB_ENTRIES
)
752 if (string
== NULL
) {
757 table_addr
= sizeof(int32_t) * ENVP_NB_ENTRIES
+ index
* ENVP_ENTRY_SIZE
;
758 prom_buf
[index
] = tswap32(ENVP_ADDR
+ table_addr
);
760 va_start(ap
, string
);
761 vsnprintf((char *)prom_buf
+ table_addr
, ENVP_ENTRY_SIZE
, string
, ap
);
766 static int64_t load_kernel (void)
768 int64_t kernel_entry
, kernel_high
;
770 ram_addr_t initrd_offset
;
776 #ifdef TARGET_WORDS_BIGENDIAN
782 if (load_elf(loaderparams
.kernel_filename
, cpu_mips_kseg0_to_phys
, NULL
,
783 (uint64_t *)&kernel_entry
, NULL
, (uint64_t *)&kernel_high
,
784 big_endian
, ELF_MACHINE
, 1) < 0) {
785 fprintf(stderr
, "qemu: could not load kernel '%s'\n",
786 loaderparams
.kernel_filename
);
793 if (loaderparams
.initrd_filename
) {
794 initrd_size
= get_image_size (loaderparams
.initrd_filename
);
795 if (initrd_size
> 0) {
796 initrd_offset
= (kernel_high
+ ~INITRD_PAGE_MASK
) & INITRD_PAGE_MASK
;
797 if (initrd_offset
+ initrd_size
> ram_size
) {
799 "qemu: memory too small for initial ram disk '%s'\n",
800 loaderparams
.initrd_filename
);
803 initrd_size
= load_image_targphys(loaderparams
.initrd_filename
,
805 ram_size
- initrd_offset
);
807 if (initrd_size
== (target_ulong
) -1) {
808 fprintf(stderr
, "qemu: could not load initial ram disk '%s'\n",
809 loaderparams
.initrd_filename
);
814 /* Setup prom parameters. */
815 prom_size
= ENVP_NB_ENTRIES
* (sizeof(int32_t) + ENVP_ENTRY_SIZE
);
816 prom_buf
= g_malloc(prom_size
);
818 prom_set(prom_buf
, prom_index
++, "%s", loaderparams
.kernel_filename
);
819 if (initrd_size
> 0) {
820 prom_set(prom_buf
, prom_index
++, "rd_start=0x%" PRIx64
" rd_size=%li %s",
821 cpu_mips_phys_to_kseg0(NULL
, initrd_offset
), initrd_size
,
822 loaderparams
.kernel_cmdline
);
824 prom_set(prom_buf
, prom_index
++, "%s", loaderparams
.kernel_cmdline
);
827 prom_set(prom_buf
, prom_index
++, "memsize");
828 prom_set(prom_buf
, prom_index
++, "%i", loaderparams
.ram_size
);
829 prom_set(prom_buf
, prom_index
++, "modetty0");
830 prom_set(prom_buf
, prom_index
++, "38400n8r");
831 prom_set(prom_buf
, prom_index
++, NULL
);
833 rom_add_blob_fixed("prom", prom_buf
, prom_size
,
834 cpu_mips_kseg0_to_phys(NULL
, ENVP_ADDR
));
839 static void malta_mips_config(MIPSCPU
*cpu
)
841 CPUMIPSState
*env
= &cpu
->env
;
842 CPUState
*cs
= CPU(cpu
);
844 env
->mvp
->CP0_MVPConf0
|= ((smp_cpus
- 1) << CP0MVPC0_PVPE
) |
845 ((smp_cpus
* cs
->nr_threads
- 1) << CP0MVPC0_PTC
);
848 static void main_cpu_reset(void *opaque
)
850 MIPSCPU
*cpu
= opaque
;
851 CPUMIPSState
*env
= &cpu
->env
;
855 /* The bootloader does not need to be rewritten as it is located in a
856 read only location. The kernel location and the arguments table
857 location does not change. */
858 if (loaderparams
.kernel_filename
) {
859 env
->CP0_Status
&= ~((1 << CP0St_BEV
) | (1 << CP0St_ERL
));
862 malta_mips_config(cpu
);
865 static void cpu_request_exit(void *opaque
, int irq
, int level
)
867 CPUState
*cpu
= current_cpu
;
875 void mips_malta_init(QEMUMachineInitArgs
*args
)
877 ram_addr_t ram_size
= args
->ram_size
;
878 const char *cpu_model
= args
->cpu_model
;
879 const char *kernel_filename
= args
->kernel_filename
;
880 const char *kernel_cmdline
= args
->kernel_cmdline
;
881 const char *initrd_filename
= args
->initrd_filename
;
884 MemoryRegion
*system_memory
= get_system_memory();
885 MemoryRegion
*ram
= g_new(MemoryRegion
, 1);
886 MemoryRegion
*bios
, *bios_copy
= g_new(MemoryRegion
, 1);
887 target_long bios_size
= FLASH_SIZE
;
888 const size_t smbus_eeprom_size
= 8 * 256;
889 uint8_t *smbus_eeprom_buf
= g_malloc0(smbus_eeprom_size
);
890 int64_t kernel_entry
;
896 qemu_irq
*cpu_exit_irq
;
901 DriveInfo
*hd
[MAX_IDE_BUS
* MAX_IDE_DEVS
];
902 DriveInfo
*fd
[MAX_FD
];
904 int fl_sectors
= bios_size
>> 16;
907 DeviceState
*dev
= qdev_create(NULL
, TYPE_MIPS_MALTA
);
908 MaltaState
*s
= MIPS_MALTA(dev
);
910 qdev_init_nofail(dev
);
912 /* Make sure the first 3 serial ports are associated with a device. */
913 for(i
= 0; i
< 3; i
++) {
914 if (!serial_hds
[i
]) {
916 snprintf(label
, sizeof(label
), "serial%d", i
);
917 serial_hds
[i
] = qemu_chr_new(label
, "null", NULL
);
922 if (cpu_model
== NULL
) {
930 for (i
= 0; i
< smp_cpus
; i
++) {
931 cpu
= cpu_mips_init(cpu_model
);
933 fprintf(stderr
, "Unable to find CPU definition\n");
938 /* Init internal devices */
939 cpu_mips_irq_init_cpu(env
);
940 cpu_mips_clock_init(env
);
941 qemu_register_reset(main_cpu_reset
, cpu
);
943 cpu
= MIPS_CPU(first_cpu
);
947 if (ram_size
> (256 << 20)) {
949 "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",
950 ((unsigned int)ram_size
/ (1 << 20)));
953 memory_region_init_ram(ram
, NULL
, "mips_malta.ram", ram_size
);
954 vmstate_register_ram_global(ram
);
955 memory_region_add_subregion(system_memory
, 0, ram
);
957 /* generate SPD EEPROM data */
958 generate_eeprom_spd(&smbus_eeprom_buf
[0 * 256], ram_size
);
959 generate_eeprom_serial(&smbus_eeprom_buf
[6 * 256]);
961 #ifdef TARGET_WORDS_BIGENDIAN
967 /* The CBUS UART is attached to the MIPS CPU INT2 pin, ie interrupt 4 */
968 malta_fpga_init(system_memory
, FPGA_ADDRESS
, env
->irq
[4], serial_hds
[2]);
970 /* Load firmware in flash / BIOS. */
971 dinfo
= drive_get(IF_PFLASH
, 0, fl_idx
);
972 #ifdef DEBUG_BOARD_INIT
974 printf("Register parallel flash %d size " TARGET_FMT_lx
" at "
975 "addr %08llx '%s' %x\n",
976 fl_idx
, bios_size
, FLASH_ADDRESS
,
977 bdrv_get_device_name(dinfo
->bdrv
), fl_sectors
);
980 fl
= pflash_cfi01_register(FLASH_ADDRESS
, NULL
, "mips_malta.bios",
981 BIOS_SIZE
, dinfo
? dinfo
->bdrv
: NULL
,
983 4, 0x0000, 0x0000, 0x0000, 0x0000, be
);
984 bios
= pflash_cfi01_get_memory(fl
);
986 if (kernel_filename
) {
987 /* Write a small bootloader to the flash location. */
988 loaderparams
.ram_size
= ram_size
;
989 loaderparams
.kernel_filename
= kernel_filename
;
990 loaderparams
.kernel_cmdline
= kernel_cmdline
;
991 loaderparams
.initrd_filename
= initrd_filename
;
992 kernel_entry
= load_kernel();
993 write_bootloader(env
, memory_region_get_ram_ptr(bios
), kernel_entry
);
995 /* Load firmware from flash. */
997 /* Load a BIOS image. */
998 if (bios_name
== NULL
) {
999 bios_name
= BIOS_FILENAME
;
1001 filename
= qemu_find_file(QEMU_FILE_TYPE_BIOS
, bios_name
);
1003 bios_size
= load_image_targphys(filename
, FLASH_ADDRESS
,
1009 if ((bios_size
< 0 || bios_size
> BIOS_SIZE
) &&
1010 !kernel_filename
&& !qtest_enabled()) {
1012 "qemu: Warning, could not load MIPS bios '%s', and no -kernel argument was specified\n",
1016 /* In little endian mode the 32bit words in the bios are swapped,
1017 a neat trick which allows bi-endian firmware. */
1018 #ifndef TARGET_WORDS_BIGENDIAN
1020 uint32_t *end
, *addr
= rom_ptr(FLASH_ADDRESS
);
1022 addr
= memory_region_get_ram_ptr(bios
);
1024 end
= (void *)addr
+ MIN(bios_size
, 0x3e0000);
1025 while (addr
< end
) {
1034 * Map the BIOS at a 2nd physical location, as on the real board.
1035 * Copy it so that we can patch in the MIPS revision, which cannot be
1036 * handled by an overlapping region as the resulting ROM code subpage
1037 * regions are not executable.
1039 memory_region_init_ram(bios_copy
, NULL
, "bios.1fc", BIOS_SIZE
);
1040 if (!rom_copy(memory_region_get_ram_ptr(bios_copy
),
1041 FLASH_ADDRESS
, BIOS_SIZE
)) {
1042 memcpy(memory_region_get_ram_ptr(bios_copy
),
1043 memory_region_get_ram_ptr(bios
), BIOS_SIZE
);
1045 memory_region_set_readonly(bios_copy
, true);
1046 memory_region_add_subregion(system_memory
, RESET_ADDRESS
, bios_copy
);
1048 /* Board ID = 0x420 (Malta Board with CoreLV) */
1049 stl_p(memory_region_get_ram_ptr(bios_copy
) + 0x10, 0x00000420);
1051 /* Init internal devices */
1052 cpu_mips_irq_init_cpu(env
);
1053 cpu_mips_clock_init(env
);
1056 * We have a circular dependency problem: pci_bus depends on isa_irq,
1057 * isa_irq is provided by i8259, i8259 depends on ISA, ISA depends
1058 * on piix4, and piix4 depends on pci_bus. To stop the cycle we have
1059 * qemu_irq_proxy() adds an extra bit of indirection, allowing us
1060 * to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
1062 isa_irq
= qemu_irq_proxy(&s
->i8259
, 16);
1065 pci_bus
= gt64120_register(isa_irq
);
1068 ide_drive_get(hd
, MAX_IDE_BUS
);
1070 piix4_devfn
= piix4_init(pci_bus
, &isa_bus
, 80);
1072 /* Interrupt controller */
1073 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
1074 s
->i8259
= i8259_init(isa_bus
, env
->irq
[2]);
1076 isa_bus_irqs(isa_bus
, s
->i8259
);
1077 pci_piix4_ide_init(pci_bus
, hd
, piix4_devfn
+ 1);
1078 pci_create_simple(pci_bus
, piix4_devfn
+ 2, "piix4-usb-uhci");
1079 smbus
= piix4_pm_init(pci_bus
, piix4_devfn
+ 3, 0x1100,
1080 isa_get_irq(NULL
, 9), NULL
, 0, NULL
);
1081 smbus_eeprom_init(smbus
, 8, smbus_eeprom_buf
, smbus_eeprom_size
);
1082 g_free(smbus_eeprom_buf
);
1083 pit
= pit_init(isa_bus
, 0x40, 0, NULL
);
1084 cpu_exit_irq
= qemu_allocate_irqs(cpu_request_exit
, NULL
, 1);
1085 DMA_init(0, cpu_exit_irq
);
1088 isa_create_simple(isa_bus
, "i8042");
1090 rtc_init(isa_bus
, 2000, NULL
);
1091 serial_isa_init(isa_bus
, 0, serial_hds
[0]);
1092 serial_isa_init(isa_bus
, 1, serial_hds
[1]);
1093 if (parallel_hds
[0])
1094 parallel_init(isa_bus
, 0, parallel_hds
[0]);
1095 for(i
= 0; i
< MAX_FD
; i
++) {
1096 fd
[i
] = drive_get(IF_FLOPPY
, 0, i
);
1098 fdctrl_init_isa(isa_bus
, fd
);
1101 network_init(pci_bus
);
1103 /* Optional PCI video card */
1104 pci_vga_init(pci_bus
);
1107 static int mips_malta_sysbus_device_init(SysBusDevice
*sysbusdev
)
1112 static void mips_malta_class_init(ObjectClass
*klass
, void *data
)
1114 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
1116 k
->init
= mips_malta_sysbus_device_init
;
1119 static const TypeInfo mips_malta_device
= {
1120 .name
= TYPE_MIPS_MALTA
,
1121 .parent
= TYPE_SYS_BUS_DEVICE
,
1122 .instance_size
= sizeof(MaltaState
),
1123 .class_init
= mips_malta_class_init
,
1126 static QEMUMachine mips_malta_machine
= {
1128 .desc
= "MIPS Malta Core LV",
1129 .init
= mips_malta_init
,
1132 DEFAULT_MACHINE_OPTIONS
,
1135 static void mips_malta_register_types(void)
1137 type_register_static(&mips_malta_device
);
1140 static void mips_malta_machine_init(void)
1142 qemu_register_machine(&mips_malta_machine
);
1145 type_init(mips_malta_register_types
)
1146 machine_init(mips_malta_machine_init
);