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"
52 #include "qemu/error-report.h"
53 #include "hw/empty_slot.h"
55 //#define DEBUG_BOARD_INIT
57 #define ENVP_ADDR 0x80002000l
58 #define ENVP_NB_ENTRIES 16
59 #define ENVP_ENTRY_SIZE 256
61 /* Hardware addresses */
62 #define FLASH_ADDRESS 0x1e000000ULL
63 #define FPGA_ADDRESS 0x1f000000ULL
64 #define RESET_ADDRESS 0x1fc00000ULL
66 #define FLASH_SIZE 0x400000
72 MemoryRegion iomem_lo
; /* 0 - 0x900 */
73 MemoryRegion iomem_hi
; /* 0xa00 - 0x100000 */
81 CharDriverState
*display
;
86 #define TYPE_MIPS_MALTA "mips-malta"
87 #define MIPS_MALTA(obj) OBJECT_CHECK(MaltaState, (obj), TYPE_MIPS_MALTA)
90 SysBusDevice parent_obj
;
95 static ISADevice
*pit
;
97 static struct _loaderparams
{
99 const char *kernel_filename
;
100 const char *kernel_cmdline
;
101 const char *initrd_filename
;
105 static void malta_fpga_update_display(void *opaque
)
109 MaltaFPGAState
*s
= opaque
;
111 for (i
= 7 ; i
>= 0 ; i
--) {
112 if (s
->leds
& (1 << i
))
119 qemu_chr_fe_printf(s
->display
, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text
);
120 qemu_chr_fe_printf(s
->display
, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s
->display_text
);
124 * EEPROM 24C01 / 24C02 emulation.
126 * Emulation for serial EEPROMs:
127 * 24C01 - 1024 bit (128 x 8)
128 * 24C02 - 2048 bit (256 x 8)
130 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
136 # define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
138 # define logout(fmt, ...) ((void)0)
141 struct _eeprom24c0x_t
{
150 uint8_t contents
[256];
153 typedef struct _eeprom24c0x_t eeprom24c0x_t
;
155 static eeprom24c0x_t spd_eeprom
= {
157 /* 00000000: */ 0x80,0x08,0xFF,0x0D,0x0A,0xFF,0x40,0x00,
158 /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
159 /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x00,0x00,
160 /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0xFF,
161 /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
162 /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
163 /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
164 /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
165 /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
166 /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
167 /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
168 /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
169 /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
170 /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
171 /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
172 /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
176 static void generate_eeprom_spd(uint8_t *eeprom
, ram_addr_t ram_size
)
178 enum { SDR
= 0x4, DDR2
= 0x8 } type
;
179 uint8_t *spd
= spd_eeprom
.contents
;
181 uint16_t density
= 0;
184 /* work in terms of MB */
187 while ((ram_size
>= 4) && (nbanks
<= 2)) {
188 int sz_log2
= MIN(31 - clz32(ram_size
), 14);
190 density
|= 1 << (sz_log2
- 2);
191 ram_size
-= 1 << sz_log2
;
194 /* split to 2 banks if possible */
195 if ((nbanks
== 1) && (density
> 1)) {
200 if (density
& 0xff00) {
201 density
= (density
& 0xe0) | ((density
>> 8) & 0x1f);
203 } else if (!(density
& 0x1f)) {
210 fprintf(stderr
, "Warning: SPD cannot represent final %dMB"
211 " of SDRAM\n", (int)ram_size
);
214 /* fill in SPD memory information */
221 for (i
= 0; i
< 63; i
++) {
226 memcpy(eeprom
, spd
, sizeof(spd_eeprom
.contents
));
229 static void generate_eeprom_serial(uint8_t *eeprom
)
232 uint8_t mac
[6] = { 0x00 };
233 uint8_t sn
[5] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
236 eeprom
[pos
++] = 0x01;
239 eeprom
[pos
++] = 0x02;
242 eeprom
[pos
++] = 0x01; /* MAC */
243 eeprom
[pos
++] = 0x06; /* length */
244 memcpy(&eeprom
[pos
], mac
, sizeof(mac
));
248 eeprom
[pos
++] = 0x02; /* serial */
249 eeprom
[pos
++] = 0x05; /* length */
250 memcpy(&eeprom
[pos
], sn
, sizeof(sn
));
255 for (i
= 0; i
< pos
; i
++) {
256 eeprom
[pos
] += eeprom
[i
];
260 static uint8_t eeprom24c0x_read(eeprom24c0x_t
*eeprom
)
262 logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
263 eeprom
->tick
, eeprom
->scl
, eeprom
->sda
, eeprom
->data
);
267 static void eeprom24c0x_write(eeprom24c0x_t
*eeprom
, int scl
, int sda
)
269 if (eeprom
->scl
&& scl
&& (eeprom
->sda
!= sda
)) {
270 logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
271 eeprom
->tick
, eeprom
->scl
, scl
, eeprom
->sda
, sda
,
272 sda
? "stop" : "start");
277 } else if (eeprom
->tick
== 0 && !eeprom
->ack
) {
278 /* Waiting for start. */
279 logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
280 eeprom
->tick
, eeprom
->scl
, scl
, eeprom
->sda
, sda
);
281 } else if (!eeprom
->scl
&& scl
) {
282 logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
283 eeprom
->tick
, eeprom
->scl
, scl
, eeprom
->sda
, sda
);
285 logout("\ti2c ack bit = 0\n");
288 } else if (eeprom
->sda
== sda
) {
289 uint8_t bit
= (sda
!= 0);
290 logout("\ti2c bit = %d\n", bit
);
291 if (eeprom
->tick
< 9) {
292 eeprom
->command
<<= 1;
293 eeprom
->command
+= bit
;
295 if (eeprom
->tick
== 9) {
296 logout("\tcommand 0x%04x, %s\n", eeprom
->command
,
297 bit
? "read" : "write");
300 } else if (eeprom
->tick
< 17) {
301 if (eeprom
->command
& 1) {
302 sda
= ((eeprom
->data
& 0x80) != 0);
304 eeprom
->address
<<= 1;
305 eeprom
->address
+= bit
;
308 if (eeprom
->tick
== 17) {
309 eeprom
->data
= eeprom
->contents
[eeprom
->address
];
310 logout("\taddress 0x%04x, data 0x%02x\n",
311 eeprom
->address
, eeprom
->data
);
315 } else if (eeprom
->tick
>= 17) {
319 logout("\tsda changed with raising scl\n");
322 logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom
->tick
, eeprom
->scl
,
323 scl
, eeprom
->sda
, sda
);
329 static uint64_t malta_fpga_read(void *opaque
, hwaddr addr
,
332 MaltaFPGAState
*s
= opaque
;
336 saddr
= (addr
& 0xfffff);
340 /* SWITCH Register */
342 val
= 0x00000000; /* All switches closed */
345 /* STATUS Register */
347 #ifdef TARGET_WORDS_BIGENDIAN
359 /* LEDBAR Register */
364 /* BRKRES Register */
369 /* UART Registers are handled directly by the serial device */
376 /* XXX: implement a real I2C controller */
380 /* IN = OUT until a real I2C control is implemented */
387 /* I2CINP Register */
389 val
= ((s
->i2cin
& ~1) | eeprom24c0x_read(&spd_eeprom
));
397 /* I2COUT Register */
402 /* I2CSEL Register */
409 printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx
"\n",
417 static void malta_fpga_write(void *opaque
, hwaddr addr
,
418 uint64_t val
, unsigned size
)
420 MaltaFPGAState
*s
= opaque
;
423 saddr
= (addr
& 0xfffff);
427 /* SWITCH Register */
435 /* LEDBAR Register */
437 s
->leds
= val
& 0xff;
438 malta_fpga_update_display(s
);
441 /* ASCIIWORD Register */
443 snprintf(s
->display_text
, 9, "%08X", (uint32_t)val
);
444 malta_fpga_update_display(s
);
447 /* ASCIIPOS0 to ASCIIPOS7 Registers */
456 s
->display_text
[(saddr
- 0x00418) >> 3] = (char) val
;
457 malta_fpga_update_display(s
);
460 /* SOFTRES Register */
463 qemu_system_reset_request ();
466 /* BRKRES Register */
471 /* UART Registers are handled directly by the serial device */
475 s
->gpout
= val
& 0xff;
480 s
->i2coe
= val
& 0x03;
483 /* I2COUT Register */
485 eeprom24c0x_write(&spd_eeprom
, val
& 0x02, val
& 0x01);
489 /* I2CSEL Register */
491 s
->i2csel
= val
& 0x01;
496 printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx
"\n",
503 static const MemoryRegionOps malta_fpga_ops
= {
504 .read
= malta_fpga_read
,
505 .write
= malta_fpga_write
,
506 .endianness
= DEVICE_NATIVE_ENDIAN
,
509 static void malta_fpga_reset(void *opaque
)
511 MaltaFPGAState
*s
= opaque
;
521 s
->display_text
[8] = '\0';
522 snprintf(s
->display_text
, 9, " ");
525 static void malta_fpga_led_init(CharDriverState
*chr
)
527 qemu_chr_fe_printf(chr
, "\e[HMalta LEDBAR\r\n");
528 qemu_chr_fe_printf(chr
, "+--------+\r\n");
529 qemu_chr_fe_printf(chr
, "+ +\r\n");
530 qemu_chr_fe_printf(chr
, "+--------+\r\n");
531 qemu_chr_fe_printf(chr
, "\n");
532 qemu_chr_fe_printf(chr
, "Malta ASCII\r\n");
533 qemu_chr_fe_printf(chr
, "+--------+\r\n");
534 qemu_chr_fe_printf(chr
, "+ +\r\n");
535 qemu_chr_fe_printf(chr
, "+--------+\r\n");
538 static MaltaFPGAState
*malta_fpga_init(MemoryRegion
*address_space
,
539 hwaddr base
, qemu_irq uart_irq
, CharDriverState
*uart_chr
)
543 s
= (MaltaFPGAState
*)g_malloc0(sizeof(MaltaFPGAState
));
545 memory_region_init_io(&s
->iomem
, NULL
, &malta_fpga_ops
, s
,
546 "malta-fpga", 0x100000);
547 memory_region_init_alias(&s
->iomem_lo
, NULL
, "malta-fpga",
548 &s
->iomem
, 0, 0x900);
549 memory_region_init_alias(&s
->iomem_hi
, NULL
, "malta-fpga",
550 &s
->iomem
, 0xa00, 0x10000-0xa00);
552 memory_region_add_subregion(address_space
, base
, &s
->iomem_lo
);
553 memory_region_add_subregion(address_space
, base
+ 0xa00, &s
->iomem_hi
);
555 s
->display
= qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init
);
557 s
->uart
= serial_mm_init(address_space
, base
+ 0x900, 3, uart_irq
,
558 230400, uart_chr
, DEVICE_NATIVE_ENDIAN
);
561 qemu_register_reset(malta_fpga_reset
, s
);
566 /* Network support */
567 static void network_init(PCIBus
*pci_bus
)
571 for(i
= 0; i
< nb_nics
; i
++) {
572 NICInfo
*nd
= &nd_table
[i
];
573 const char *default_devaddr
= NULL
;
575 if (i
== 0 && (!nd
->model
|| strcmp(nd
->model
, "pcnet") == 0))
576 /* The malta board has a PCNet card using PCI SLOT 11 */
577 default_devaddr
= "0b";
579 pci_nic_init_nofail(nd
, pci_bus
, "pcnet", default_devaddr
);
583 /* ROM and pseudo bootloader
585 The following code implements a very very simple bootloader. It first
586 loads the registers a0 to a3 to the values expected by the OS, and
587 then jump at the kernel address.
589 The bootloader should pass the locations of the kernel arguments and
590 environment variables tables. Those tables contain the 32-bit address
591 of NULL terminated strings. The environment variables table should be
592 terminated by a NULL address.
594 For a simpler implementation, the number of kernel arguments is fixed
595 to two (the name of the kernel and the command line), and the two
596 tables are actually the same one.
598 The registers a0 to a3 should contain the following values:
599 a0 - number of kernel arguments
600 a1 - 32-bit address of the kernel arguments table
601 a2 - 32-bit address of the environment variables table
602 a3 - RAM size in bytes
605 static void write_bootloader (CPUMIPSState
*env
, uint8_t *base
,
606 int64_t kernel_entry
)
610 /* Small bootloader */
611 p
= (uint32_t *)base
;
612 stl_p(p
++, 0x0bf00160); /* j 0x1fc00580 */
613 stl_p(p
++, 0x00000000); /* nop */
615 /* YAMON service vector */
616 stl_p(base
+ 0x500, 0xbfc00580); /* start: */
617 stl_p(base
+ 0x504, 0xbfc0083c); /* print_count: */
618 stl_p(base
+ 0x520, 0xbfc00580); /* start: */
619 stl_p(base
+ 0x52c, 0xbfc00800); /* flush_cache: */
620 stl_p(base
+ 0x534, 0xbfc00808); /* print: */
621 stl_p(base
+ 0x538, 0xbfc00800); /* reg_cpu_isr: */
622 stl_p(base
+ 0x53c, 0xbfc00800); /* unred_cpu_isr: */
623 stl_p(base
+ 0x540, 0xbfc00800); /* reg_ic_isr: */
624 stl_p(base
+ 0x544, 0xbfc00800); /* unred_ic_isr: */
625 stl_p(base
+ 0x548, 0xbfc00800); /* reg_esr: */
626 stl_p(base
+ 0x54c, 0xbfc00800); /* unreg_esr: */
627 stl_p(base
+ 0x550, 0xbfc00800); /* getchar: */
628 stl_p(base
+ 0x554, 0xbfc00800); /* syscon_read: */
631 /* Second part of the bootloader */
632 p
= (uint32_t *) (base
+ 0x580);
633 stl_p(p
++, 0x24040002); /* addiu a0, zero, 2 */
634 stl_p(p
++, 0x3c1d0000 | (((ENVP_ADDR
- 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
635 stl_p(p
++, 0x37bd0000 | ((ENVP_ADDR
- 64) & 0xffff)); /* ori sp, sp, low(ENVP_ADDR) */
636 stl_p(p
++, 0x3c050000 | ((ENVP_ADDR
>> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
637 stl_p(p
++, 0x34a50000 | (ENVP_ADDR
& 0xffff)); /* ori a1, a1, low(ENVP_ADDR) */
638 stl_p(p
++, 0x3c060000 | (((ENVP_ADDR
+ 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
639 stl_p(p
++, 0x34c60000 | ((ENVP_ADDR
+ 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */
640 stl_p(p
++, 0x3c070000 | (loaderparams
.ram_size
>> 16)); /* lui a3, high(ram_size) */
641 stl_p(p
++, 0x34e70000 | (loaderparams
.ram_size
& 0xffff)); /* ori a3, a3, low(ram_size) */
643 /* Load BAR registers as done by YAMON */
644 stl_p(p
++, 0x3c09b400); /* lui t1, 0xb400 */
646 #ifdef TARGET_WORDS_BIGENDIAN
647 stl_p(p
++, 0x3c08df00); /* lui t0, 0xdf00 */
649 stl_p(p
++, 0x340800df); /* ori t0, r0, 0x00df */
651 stl_p(p
++, 0xad280068); /* sw t0, 0x0068(t1) */
653 stl_p(p
++, 0x3c09bbe0); /* lui t1, 0xbbe0 */
655 #ifdef TARGET_WORDS_BIGENDIAN
656 stl_p(p
++, 0x3c08c000); /* lui t0, 0xc000 */
658 stl_p(p
++, 0x340800c0); /* ori t0, r0, 0x00c0 */
660 stl_p(p
++, 0xad280048); /* sw t0, 0x0048(t1) */
661 #ifdef TARGET_WORDS_BIGENDIAN
662 stl_p(p
++, 0x3c084000); /* lui t0, 0x4000 */
664 stl_p(p
++, 0x34080040); /* ori t0, r0, 0x0040 */
666 stl_p(p
++, 0xad280050); /* sw t0, 0x0050(t1) */
668 #ifdef TARGET_WORDS_BIGENDIAN
669 stl_p(p
++, 0x3c088000); /* lui t0, 0x8000 */
671 stl_p(p
++, 0x34080080); /* ori t0, r0, 0x0080 */
673 stl_p(p
++, 0xad280058); /* sw t0, 0x0058(t1) */
674 #ifdef TARGET_WORDS_BIGENDIAN
675 stl_p(p
++, 0x3c083f00); /* lui t0, 0x3f00 */
677 stl_p(p
++, 0x3408003f); /* ori t0, r0, 0x003f */
679 stl_p(p
++, 0xad280060); /* sw t0, 0x0060(t1) */
681 #ifdef TARGET_WORDS_BIGENDIAN
682 stl_p(p
++, 0x3c08c100); /* lui t0, 0xc100 */
684 stl_p(p
++, 0x340800c1); /* ori t0, r0, 0x00c1 */
686 stl_p(p
++, 0xad280080); /* sw t0, 0x0080(t1) */
687 #ifdef TARGET_WORDS_BIGENDIAN
688 stl_p(p
++, 0x3c085e00); /* lui t0, 0x5e00 */
690 stl_p(p
++, 0x3408005e); /* ori t0, r0, 0x005e */
692 stl_p(p
++, 0xad280088); /* sw t0, 0x0088(t1) */
694 /* Jump to kernel code */
695 stl_p(p
++, 0x3c1f0000 | ((kernel_entry
>> 16) & 0xffff)); /* lui ra, high(kernel_entry) */
696 stl_p(p
++, 0x37ff0000 | (kernel_entry
& 0xffff)); /* ori ra, ra, low(kernel_entry) */
697 stl_p(p
++, 0x03e00008); /* jr ra */
698 stl_p(p
++, 0x00000000); /* nop */
700 /* YAMON subroutines */
701 p
= (uint32_t *) (base
+ 0x800);
702 stl_p(p
++, 0x03e00008); /* jr ra */
703 stl_p(p
++, 0x24020000); /* li v0,0 */
704 /* 808 YAMON print */
705 stl_p(p
++, 0x03e06821); /* move t5,ra */
706 stl_p(p
++, 0x00805821); /* move t3,a0 */
707 stl_p(p
++, 0x00a05021); /* move t2,a1 */
708 stl_p(p
++, 0x91440000); /* lbu a0,0(t2) */
709 stl_p(p
++, 0x254a0001); /* addiu t2,t2,1 */
710 stl_p(p
++, 0x10800005); /* beqz a0,834 */
711 stl_p(p
++, 0x00000000); /* nop */
712 stl_p(p
++, 0x0ff0021c); /* jal 870 */
713 stl_p(p
++, 0x00000000); /* nop */
714 stl_p(p
++, 0x08000205); /* j 814 */
715 stl_p(p
++, 0x00000000); /* nop */
716 stl_p(p
++, 0x01a00008); /* jr t5 */
717 stl_p(p
++, 0x01602021); /* move a0,t3 */
718 /* 0x83c YAMON print_count */
719 stl_p(p
++, 0x03e06821); /* move t5,ra */
720 stl_p(p
++, 0x00805821); /* move t3,a0 */
721 stl_p(p
++, 0x00a05021); /* move t2,a1 */
722 stl_p(p
++, 0x00c06021); /* move t4,a2 */
723 stl_p(p
++, 0x91440000); /* lbu a0,0(t2) */
724 stl_p(p
++, 0x0ff0021c); /* jal 870 */
725 stl_p(p
++, 0x00000000); /* nop */
726 stl_p(p
++, 0x254a0001); /* addiu t2,t2,1 */
727 stl_p(p
++, 0x258cffff); /* addiu t4,t4,-1 */
728 stl_p(p
++, 0x1580fffa); /* bnez t4,84c */
729 stl_p(p
++, 0x00000000); /* nop */
730 stl_p(p
++, 0x01a00008); /* jr t5 */
731 stl_p(p
++, 0x01602021); /* move a0,t3 */
733 stl_p(p
++, 0x3c08b800); /* lui t0,0xb400 */
734 stl_p(p
++, 0x350803f8); /* ori t0,t0,0x3f8 */
735 stl_p(p
++, 0x91090005); /* lbu t1,5(t0) */
736 stl_p(p
++, 0x00000000); /* nop */
737 stl_p(p
++, 0x31290040); /* andi t1,t1,0x40 */
738 stl_p(p
++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */
739 stl_p(p
++, 0x00000000); /* nop */
740 stl_p(p
++, 0x03e00008); /* jr ra */
741 stl_p(p
++, 0xa1040000); /* sb a0,0(t0) */
745 static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf
, int index
,
746 const char *string
, ...)
751 if (index
>= ENVP_NB_ENTRIES
)
754 if (string
== NULL
) {
759 table_addr
= sizeof(int32_t) * ENVP_NB_ENTRIES
+ index
* ENVP_ENTRY_SIZE
;
760 prom_buf
[index
] = tswap32(ENVP_ADDR
+ table_addr
);
762 va_start(ap
, string
);
763 vsnprintf((char *)prom_buf
+ table_addr
, ENVP_ENTRY_SIZE
, string
, ap
);
768 static int64_t load_kernel (void)
770 int64_t kernel_entry
, kernel_high
;
772 ram_addr_t initrd_offset
;
778 #ifdef TARGET_WORDS_BIGENDIAN
784 if (load_elf(loaderparams
.kernel_filename
, cpu_mips_kseg0_to_phys
, NULL
,
785 (uint64_t *)&kernel_entry
, NULL
, (uint64_t *)&kernel_high
,
786 big_endian
, ELF_MACHINE
, 1) < 0) {
787 fprintf(stderr
, "qemu: could not load kernel '%s'\n",
788 loaderparams
.kernel_filename
);
795 if (loaderparams
.initrd_filename
) {
796 initrd_size
= get_image_size (loaderparams
.initrd_filename
);
797 if (initrd_size
> 0) {
798 initrd_offset
= (kernel_high
+ ~INITRD_PAGE_MASK
) & INITRD_PAGE_MASK
;
799 if (initrd_offset
+ initrd_size
> ram_size
) {
801 "qemu: memory too small for initial ram disk '%s'\n",
802 loaderparams
.initrd_filename
);
805 initrd_size
= load_image_targphys(loaderparams
.initrd_filename
,
807 ram_size
- initrd_offset
);
809 if (initrd_size
== (target_ulong
) -1) {
810 fprintf(stderr
, "qemu: could not load initial ram disk '%s'\n",
811 loaderparams
.initrd_filename
);
816 /* Setup prom parameters. */
817 prom_size
= ENVP_NB_ENTRIES
* (sizeof(int32_t) + ENVP_ENTRY_SIZE
);
818 prom_buf
= g_malloc(prom_size
);
820 prom_set(prom_buf
, prom_index
++, "%s", loaderparams
.kernel_filename
);
821 if (initrd_size
> 0) {
822 prom_set(prom_buf
, prom_index
++, "rd_start=0x%" PRIx64
" rd_size=%li %s",
823 cpu_mips_phys_to_kseg0(NULL
, initrd_offset
), initrd_size
,
824 loaderparams
.kernel_cmdline
);
826 prom_set(prom_buf
, prom_index
++, "%s", loaderparams
.kernel_cmdline
);
829 prom_set(prom_buf
, prom_index
++, "memsize");
830 prom_set(prom_buf
, prom_index
++, "%i",
831 MIN(loaderparams
.ram_size
, 256 << 20));
832 prom_set(prom_buf
, prom_index
++, "modetty0");
833 prom_set(prom_buf
, prom_index
++, "38400n8r");
834 prom_set(prom_buf
, prom_index
++, NULL
);
836 rom_add_blob_fixed("prom", prom_buf
, prom_size
,
837 cpu_mips_kseg0_to_phys(NULL
, ENVP_ADDR
));
842 static void malta_mips_config(MIPSCPU
*cpu
)
844 CPUMIPSState
*env
= &cpu
->env
;
845 CPUState
*cs
= CPU(cpu
);
847 env
->mvp
->CP0_MVPConf0
|= ((smp_cpus
- 1) << CP0MVPC0_PVPE
) |
848 ((smp_cpus
* cs
->nr_threads
- 1) << CP0MVPC0_PTC
);
851 static void main_cpu_reset(void *opaque
)
853 MIPSCPU
*cpu
= opaque
;
854 CPUMIPSState
*env
= &cpu
->env
;
858 /* The bootloader does not need to be rewritten as it is located in a
859 read only location. The kernel location and the arguments table
860 location does not change. */
861 if (loaderparams
.kernel_filename
) {
862 env
->CP0_Status
&= ~((1 << CP0St_BEV
) | (1 << CP0St_ERL
));
865 malta_mips_config(cpu
);
868 static void cpu_request_exit(void *opaque
, int irq
, int level
)
870 CPUState
*cpu
= current_cpu
;
878 void mips_malta_init(MachineState
*machine
)
880 ram_addr_t ram_size
= machine
->ram_size
;
881 const char *cpu_model
= machine
->cpu_model
;
882 const char *kernel_filename
= machine
->kernel_filename
;
883 const char *kernel_cmdline
= machine
->kernel_cmdline
;
884 const char *initrd_filename
= machine
->initrd_filename
;
887 MemoryRegion
*system_memory
= get_system_memory();
888 MemoryRegion
*ram_high
= g_new(MemoryRegion
, 1);
889 MemoryRegion
*ram_low_preio
= g_new(MemoryRegion
, 1);
890 MemoryRegion
*ram_low_postio
;
891 MemoryRegion
*bios
, *bios_copy
= g_new(MemoryRegion
, 1);
892 target_long bios_size
= FLASH_SIZE
;
893 const size_t smbus_eeprom_size
= 8 * 256;
894 uint8_t *smbus_eeprom_buf
= g_malloc0(smbus_eeprom_size
);
895 int64_t kernel_entry
;
901 qemu_irq
*cpu_exit_irq
;
906 DriveInfo
*hd
[MAX_IDE_BUS
* MAX_IDE_DEVS
];
907 DriveInfo
*fd
[MAX_FD
];
909 int fl_sectors
= bios_size
>> 16;
912 DeviceState
*dev
= qdev_create(NULL
, TYPE_MIPS_MALTA
);
913 MaltaState
*s
= MIPS_MALTA(dev
);
915 /* The whole address space decoded by the GT-64120A doesn't generate
916 exception when accessing invalid memory. Create an empty slot to
917 emulate this feature. */
918 empty_slot_init(0, 0x20000000);
920 qdev_init_nofail(dev
);
922 /* Make sure the first 3 serial ports are associated with a device. */
923 for(i
= 0; i
< 3; i
++) {
924 if (!serial_hds
[i
]) {
926 snprintf(label
, sizeof(label
), "serial%d", i
);
927 serial_hds
[i
] = qemu_chr_new(label
, "null", NULL
);
932 if (cpu_model
== NULL
) {
940 for (i
= 0; i
< smp_cpus
; i
++) {
941 cpu
= cpu_mips_init(cpu_model
);
943 fprintf(stderr
, "Unable to find CPU definition\n");
948 /* Init internal devices */
949 cpu_mips_irq_init_cpu(env
);
950 cpu_mips_clock_init(env
);
951 qemu_register_reset(main_cpu_reset
, cpu
);
953 cpu
= MIPS_CPU(first_cpu
);
957 if (ram_size
> (2048u << 20)) {
959 "qemu: Too much memory for this machine: %d MB, maximum 2048 MB\n",
960 ((unsigned int)ram_size
/ (1 << 20)));
964 /* register RAM at high address where it is undisturbed by IO */
965 memory_region_init_ram(ram_high
, NULL
, "mips_malta.ram", ram_size
);
966 vmstate_register_ram_global(ram_high
);
967 memory_region_add_subregion(system_memory
, 0x80000000, ram_high
);
969 /* alias for pre IO hole access */
970 memory_region_init_alias(ram_low_preio
, NULL
, "mips_malta_low_preio.ram",
971 ram_high
, 0, MIN(ram_size
, (256 << 20)));
972 memory_region_add_subregion(system_memory
, 0, ram_low_preio
);
974 /* alias for post IO hole access, if there is enough RAM */
975 if (ram_size
> (512 << 20)) {
976 ram_low_postio
= g_new(MemoryRegion
, 1);
977 memory_region_init_alias(ram_low_postio
, NULL
,
978 "mips_malta_low_postio.ram",
980 ram_size
- (512 << 20));
981 memory_region_add_subregion(system_memory
, 512 << 20, ram_low_postio
);
984 /* generate SPD EEPROM data */
985 generate_eeprom_spd(&smbus_eeprom_buf
[0 * 256], ram_size
);
986 generate_eeprom_serial(&smbus_eeprom_buf
[6 * 256]);
988 #ifdef TARGET_WORDS_BIGENDIAN
994 /* The CBUS UART is attached to the MIPS CPU INT2 pin, ie interrupt 4 */
995 malta_fpga_init(system_memory
, FPGA_ADDRESS
, env
->irq
[4], serial_hds
[2]);
997 /* Load firmware in flash / BIOS. */
998 dinfo
= drive_get(IF_PFLASH
, 0, fl_idx
);
999 #ifdef DEBUG_BOARD_INIT
1001 printf("Register parallel flash %d size " TARGET_FMT_lx
" at "
1002 "addr %08llx '%s' %x\n",
1003 fl_idx
, bios_size
, FLASH_ADDRESS
,
1004 bdrv_get_device_name(dinfo
->bdrv
), fl_sectors
);
1007 fl
= pflash_cfi01_register(FLASH_ADDRESS
, NULL
, "mips_malta.bios",
1008 BIOS_SIZE
, dinfo
? dinfo
->bdrv
: NULL
,
1010 4, 0x0000, 0x0000, 0x0000, 0x0000, be
);
1011 bios
= pflash_cfi01_get_memory(fl
);
1013 if (kernel_filename
) {
1014 /* Write a small bootloader to the flash location. */
1015 loaderparams
.ram_size
= MIN(ram_size
, 256 << 20);
1016 loaderparams
.kernel_filename
= kernel_filename
;
1017 loaderparams
.kernel_cmdline
= kernel_cmdline
;
1018 loaderparams
.initrd_filename
= initrd_filename
;
1019 kernel_entry
= load_kernel();
1020 write_bootloader(env
, memory_region_get_ram_ptr(bios
), kernel_entry
);
1022 /* Load firmware from flash. */
1024 /* Load a BIOS image. */
1025 if (bios_name
== NULL
) {
1026 bios_name
= BIOS_FILENAME
;
1028 filename
= qemu_find_file(QEMU_FILE_TYPE_BIOS
, bios_name
);
1030 bios_size
= load_image_targphys(filename
, FLASH_ADDRESS
,
1036 if ((bios_size
< 0 || bios_size
> BIOS_SIZE
) &&
1037 !kernel_filename
&& !qtest_enabled()) {
1038 error_report("Could not load MIPS bios '%s', and no "
1039 "-kernel argument was specified", bios_name
);
1043 /* In little endian mode the 32bit words in the bios are swapped,
1044 a neat trick which allows bi-endian firmware. */
1045 #ifndef TARGET_WORDS_BIGENDIAN
1047 uint32_t *end
, *addr
= rom_ptr(FLASH_ADDRESS
);
1049 addr
= memory_region_get_ram_ptr(bios
);
1051 end
= (void *)addr
+ MIN(bios_size
, 0x3e0000);
1052 while (addr
< end
) {
1061 * Map the BIOS at a 2nd physical location, as on the real board.
1062 * Copy it so that we can patch in the MIPS revision, which cannot be
1063 * handled by an overlapping region as the resulting ROM code subpage
1064 * regions are not executable.
1066 memory_region_init_ram(bios_copy
, NULL
, "bios.1fc", BIOS_SIZE
);
1067 if (!rom_copy(memory_region_get_ram_ptr(bios_copy
),
1068 FLASH_ADDRESS
, BIOS_SIZE
)) {
1069 memcpy(memory_region_get_ram_ptr(bios_copy
),
1070 memory_region_get_ram_ptr(bios
), BIOS_SIZE
);
1072 memory_region_set_readonly(bios_copy
, true);
1073 memory_region_add_subregion(system_memory
, RESET_ADDRESS
, bios_copy
);
1075 /* Board ID = 0x420 (Malta Board with CoreLV) */
1076 stl_p(memory_region_get_ram_ptr(bios_copy
) + 0x10, 0x00000420);
1078 /* Init internal devices */
1079 cpu_mips_irq_init_cpu(env
);
1080 cpu_mips_clock_init(env
);
1083 * We have a circular dependency problem: pci_bus depends on isa_irq,
1084 * isa_irq is provided by i8259, i8259 depends on ISA, ISA depends
1085 * on piix4, and piix4 depends on pci_bus. To stop the cycle we have
1086 * qemu_irq_proxy() adds an extra bit of indirection, allowing us
1087 * to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
1089 isa_irq
= qemu_irq_proxy(&s
->i8259
, 16);
1092 pci_bus
= gt64120_register(isa_irq
);
1095 ide_drive_get(hd
, MAX_IDE_BUS
);
1097 piix4_devfn
= piix4_init(pci_bus
, &isa_bus
, 80);
1099 /* Interrupt controller */
1100 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
1101 s
->i8259
= i8259_init(isa_bus
, env
->irq
[2]);
1103 isa_bus_irqs(isa_bus
, s
->i8259
);
1104 pci_piix4_ide_init(pci_bus
, hd
, piix4_devfn
+ 1);
1105 pci_create_simple(pci_bus
, piix4_devfn
+ 2, "piix4-usb-uhci");
1106 smbus
= piix4_pm_init(pci_bus
, piix4_devfn
+ 3, 0x1100,
1107 isa_get_irq(NULL
, 9), NULL
, 0, NULL
);
1108 smbus_eeprom_init(smbus
, 8, smbus_eeprom_buf
, smbus_eeprom_size
);
1109 g_free(smbus_eeprom_buf
);
1110 pit
= pit_init(isa_bus
, 0x40, 0, NULL
);
1111 cpu_exit_irq
= qemu_allocate_irqs(cpu_request_exit
, NULL
, 1);
1112 DMA_init(0, cpu_exit_irq
);
1115 isa_create_simple(isa_bus
, "i8042");
1117 rtc_init(isa_bus
, 2000, NULL
);
1118 serial_isa_init(isa_bus
, 0, serial_hds
[0]);
1119 serial_isa_init(isa_bus
, 1, serial_hds
[1]);
1120 if (parallel_hds
[0])
1121 parallel_init(isa_bus
, 0, parallel_hds
[0]);
1122 for(i
= 0; i
< MAX_FD
; i
++) {
1123 fd
[i
] = drive_get(IF_FLOPPY
, 0, i
);
1125 fdctrl_init_isa(isa_bus
, fd
);
1128 network_init(pci_bus
);
1130 /* Optional PCI video card */
1131 pci_vga_init(pci_bus
);
1134 static int mips_malta_sysbus_device_init(SysBusDevice
*sysbusdev
)
1139 static void mips_malta_class_init(ObjectClass
*klass
, void *data
)
1141 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
1143 k
->init
= mips_malta_sysbus_device_init
;
1146 static const TypeInfo mips_malta_device
= {
1147 .name
= TYPE_MIPS_MALTA
,
1148 .parent
= TYPE_SYS_BUS_DEVICE
,
1149 .instance_size
= sizeof(MaltaState
),
1150 .class_init
= mips_malta_class_init
,
1153 static QEMUMachine mips_malta_machine
= {
1155 .desc
= "MIPS Malta Core LV",
1156 .init
= mips_malta_init
,
1161 static void mips_malta_register_types(void)
1163 type_register_static(&mips_malta_device
);
1166 static void mips_malta_machine_init(void)
1168 qemu_register_machine(&mips_malta_machine
);
1171 type_init(mips_malta_register_types
)
1172 machine_init(mips_malta_machine_init
);