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
27 #ifdef TARGET_WORDS_BIGENDIAN
28 #define BIOS_FILENAME "mips_bios.bin"
30 #define BIOS_FILENAME "mipsel_bios.bin"
33 #ifdef MIPS_HAS_MIPS64
34 #define INITRD_LOAD_ADDR (int64_t)0x80800000
36 #define INITRD_LOAD_ADDR (int32_t)0x80800000
39 #define ENVP_ADDR (int32_t)0x80002000
40 #define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
42 #define ENVP_NB_ENTRIES 16
43 #define ENVP_ENTRY_SIZE 256
56 CharDriverState
*display
;
62 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
63 static void pic_irq_request(void *opaque
, int level
)
65 cpu_mips_irq_request(opaque
, 2, level
);
69 static void malta_fpga_update_display(void *opaque
)
73 MaltaFPGAState
*s
= opaque
;
75 for (i
= 7 ; i
>= 0 ; i
--) {
76 if (s
->leds
& (1 << i
))
83 qemu_chr_printf(s
->display
, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text
);
84 qemu_chr_printf(s
->display
, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s
->display_text
);
88 * EEPROM 24C01 / 24C02 emulation.
90 * Emulation for serial EEPROMs:
91 * 24C01 - 1024 bit (128 x 8)
92 * 24C02 - 2048 bit (256 x 8)
94 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
100 # define logout(fmt, args...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ##args)
102 # define logout(fmt, args...) ((void)0)
105 struct _eeprom24c0x_t
{
114 uint8_t contents
[256];
117 typedef struct _eeprom24c0x_t eeprom24c0x_t
;
119 static eeprom24c0x_t eeprom
= {
121 /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
122 /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
123 /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
124 /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
125 /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
126 /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
127 /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128 /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
129 /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130 /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131 /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132 /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133 /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134 /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135 /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
136 /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
140 static uint8_t eeprom24c0x_read()
142 logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
143 eeprom
.tick
, eeprom
.scl
, eeprom
.sda
, eeprom
.data
);
147 static void eeprom24c0x_write(int scl
, int sda
)
149 if (eeprom
.scl
&& scl
&& (eeprom
.sda
!= sda
)) {
150 logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
151 eeprom
.tick
, eeprom
.scl
, scl
, eeprom
.sda
, sda
, sda
? "stop" : "start");
156 } else if (eeprom
.tick
== 0 && !eeprom
.ack
) {
157 /* Waiting for start. */
158 logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
159 eeprom
.tick
, eeprom
.scl
, scl
, eeprom
.sda
, sda
);
160 } else if (!eeprom
.scl
&& scl
) {
161 logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
162 eeprom
.tick
, eeprom
.scl
, scl
, eeprom
.sda
, sda
);
164 logout("\ti2c ack bit = 0\n");
167 } else if (eeprom
.sda
== sda
) {
168 uint8_t bit
= (sda
!= 0);
169 logout("\ti2c bit = %d\n", bit
);
170 if (eeprom
.tick
< 9) {
171 eeprom
.command
<<= 1;
172 eeprom
.command
+= bit
;
174 if (eeprom
.tick
== 9) {
175 logout("\tcommand 0x%04x, %s\n", eeprom
.command
, bit
? "read" : "write");
178 } else if (eeprom
.tick
< 17) {
179 if (eeprom
.command
& 1) {
180 sda
= ((eeprom
.data
& 0x80) != 0);
182 eeprom
.address
<<= 1;
183 eeprom
.address
+= bit
;
186 if (eeprom
.tick
== 17) {
187 eeprom
.data
= eeprom
.contents
[eeprom
.address
];
188 logout("\taddress 0x%04x, data 0x%02x\n", eeprom
.address
, eeprom
.data
);
192 } else if (eeprom
.tick
>= 17) {
196 logout("\tsda changed with raising scl\n");
199 logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom
.tick
, eeprom
.scl
, scl
, eeprom
.sda
, sda
);
205 static uint32_t malta_fpga_readl(void *opaque
, target_phys_addr_t addr
)
207 MaltaFPGAState
*s
= opaque
;
211 saddr
= (addr
& 0xfffff);
215 /* SWITCH Register */
217 val
= 0x00000000; /* All switches closed */
220 /* STATUS Register */
222 #ifdef TARGET_WORDS_BIGENDIAN
234 /* LEDBAR Register */
239 /* BRKRES Register */
249 /* XXX: implement a real I2C controller */
253 /* IN = OUT until a real I2C control is implemented */
260 /* I2CINP Register */
262 val
= ((s
->i2cin
& ~1) | eeprom24c0x_read());
270 /* I2COUT Register */
275 /* I2CSEL Register */
282 printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx
"\n",
290 static void malta_fpga_writel(void *opaque
, target_phys_addr_t addr
,
293 MaltaFPGAState
*s
= opaque
;
296 saddr
= (addr
& 0xfffff);
300 /* SWITCH Register */
308 /* LEDBAR Register */
309 /* XXX: implement a 8-LED array */
311 s
->leds
= val
& 0xff;
314 /* ASCIIWORD Register */
316 snprintf(s
->display_text
, 9, "%08X", val
);
317 malta_fpga_update_display(s
);
320 /* ASCIIPOS0 to ASCIIPOS7 Registers */
329 s
->display_text
[(saddr
- 0x00418) >> 3] = (char) val
;
330 malta_fpga_update_display(s
);
333 /* SOFTRES Register */
336 qemu_system_reset_request ();
339 /* BRKRES Register */
346 s
->gpout
= val
& 0xff;
351 s
->i2coe
= val
& 0x03;
354 /* I2COUT Register */
356 eeprom24c0x_write(val
& 0x02, val
& 0x01);
360 /* I2CSEL Register */
362 s
->i2csel
= val
& 0x01;
367 printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx
"\n",
374 static CPUReadMemoryFunc
*malta_fpga_read
[] = {
380 static CPUWriteMemoryFunc
*malta_fpga_write
[] = {
386 void malta_fpga_reset(void *opaque
)
388 MaltaFPGAState
*s
= opaque
;
398 s
->display_text
[8] = '\0';
399 snprintf(s
->display_text
, 9, " ");
400 malta_fpga_update_display(s
);
403 MaltaFPGAState
*malta_fpga_init(target_phys_addr_t base
)
408 s
= (MaltaFPGAState
*)qemu_mallocz(sizeof(MaltaFPGAState
));
410 malta
= cpu_register_io_memory(0, malta_fpga_read
,
411 malta_fpga_write
, s
);
412 cpu_register_physical_memory(base
, 0x100000, malta
);
414 s
->display
= qemu_chr_open("vc");
415 qemu_chr_printf(s
->display
, "\e[HMalta LEDBAR\r\n");
416 qemu_chr_printf(s
->display
, "+--------+\r\n");
417 qemu_chr_printf(s
->display
, "+ +\r\n");
418 qemu_chr_printf(s
->display
, "+--------+\r\n");
419 qemu_chr_printf(s
->display
, "\n");
420 qemu_chr_printf(s
->display
, "Malta ASCII\r\n");
421 qemu_chr_printf(s
->display
, "+--------+\r\n");
422 qemu_chr_printf(s
->display
, "+ +\r\n");
423 qemu_chr_printf(s
->display
, "+--------+\r\n");
426 qemu_register_reset(malta_fpga_reset
, s
);
433 static void audio_init (PCIBus
*pci_bus
)
436 int audio_enabled
= 0;
438 for (c
= soundhw
; !audio_enabled
&& c
->name
; ++c
) {
439 audio_enabled
= c
->enabled
;
447 for (c
= soundhw
; c
->name
; ++c
) {
450 fprintf(stderr
, "qemu: Unsupported Sound Card: %s\n", c
->name
);
455 c
->init
.init_pci (pci_bus
, s
);
465 /* Network support */
466 static void network_init (PCIBus
*pci_bus
)
471 for(i
= 0; i
< nb_nics
; i
++) {
476 if (i
== 0 && strcmp(nd
->model
, "pcnet") == 0) {
477 /* The malta board has a PCNet card using PCI SLOT 11 */
478 pci_nic_init(pci_bus
, nd
, 88);
480 pci_nic_init(pci_bus
, nd
, -1);
485 /* ROM and pseudo bootloader
487 The following code implements a very very simple bootloader. It first
488 loads the registers a0 to a3 to the values expected by the OS, and
489 then jump at the kernel address.
491 The bootloader should pass the locations of the kernel arguments and
492 environment variables tables. Those tables contain the 32-bit address
493 of NULL terminated strings. The environment variables table should be
494 terminated by a NULL address.
496 For a simpler implementation, the number of kernel arguments is fixed
497 to two (the name of the kernel and the command line), and the two
498 tables are actually the same one.
500 The registers a0 to a3 should contain the following values:
501 a0 - number of kernel arguments
502 a1 - 32-bit address of the kernel arguments table
503 a2 - 32-bit address of the environment variables table
504 a3 - RAM size in bytes
507 static void write_bootloader (CPUState
*env
, unsigned long bios_offset
, int64_t kernel_addr
)
511 /* Small bootloader */
512 p
= (uint32_t *) (phys_ram_base
+ bios_offset
);
513 stl_raw(p
++, 0x0bf00010); /* j 0x1fc00040 */
514 stl_raw(p
++, 0x00000000); /* nop */
516 /* Second part of the bootloader */
517 p
= (uint32_t *) (phys_ram_base
+ bios_offset
+ 0x040);
518 stl_raw(p
++, 0x3c040000); /* lui a0, 0 */
519 stl_raw(p
++, 0x34840002); /* ori a0, a0, 2 */
520 stl_raw(p
++, 0x3c050000 | ((ENVP_ADDR
>> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
521 stl_raw(p
++, 0x34a50000 | (ENVP_ADDR
& 0xffff)); /* ori a1, a0, low(ENVP_ADDR) */
522 stl_raw(p
++, 0x3c060000 | (((ENVP_ADDR
+ 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
523 stl_raw(p
++, 0x34c60000 | ((ENVP_ADDR
+ 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */
524 stl_raw(p
++, 0x3c070000 | (env
->ram_size
>> 16)); /* lui a3, high(env->ram_size) */
525 stl_raw(p
++, 0x34e70000 | (env
->ram_size
& 0xffff)); /* ori a3, a3, low(env->ram_size) */
526 stl_raw(p
++, 0x3c1f0000 | ((kernel_addr
>> 16) & 0xffff)); /* lui ra, high(kernel_addr) */;
527 stl_raw(p
++, 0x37ff0000 | (kernel_addr
& 0xffff)); /* ori ra, ra, low(kernel_addr) */
528 stl_raw(p
++, 0x03e00008); /* jr ra */
529 stl_raw(p
++, 0x00000000); /* nop */
532 static void prom_set(int index
, const char *string
, ...)
539 if (index
>= ENVP_NB_ENTRIES
)
542 p
= (int32_t *) (phys_ram_base
+ ENVP_ADDR
+ VIRT_TO_PHYS_ADDEND
);
545 if (string
== NULL
) {
550 table_addr
= ENVP_ADDR
+ sizeof(int32_t) * ENVP_NB_ENTRIES
+ index
* ENVP_ENTRY_SIZE
;
551 s
= (char *) (phys_ram_base
+ VIRT_TO_PHYS_ADDEND
+ table_addr
);
553 stl_raw(p
, table_addr
);
555 va_start(ap
, string
);
556 vsnprintf (s
, ENVP_ENTRY_SIZE
, string
, ap
);
561 static int64_t load_kernel (CPUState
*env
)
563 int64_t kernel_addr
= 0;
567 if (load_elf(env
->kernel_filename
, VIRT_TO_PHYS_ADDEND
, &kernel_addr
) < 0) {
568 fprintf(stderr
, "qemu: could not load kernel '%s'\n",
569 env
->kernel_filename
);
575 if (env
->initrd_filename
) {
576 initrd_size
= load_image(env
->initrd_filename
,
577 phys_ram_base
+ INITRD_LOAD_ADDR
+ VIRT_TO_PHYS_ADDEND
);
578 if (initrd_size
== (target_ulong
) -1) {
579 fprintf(stderr
, "qemu: could not load initial ram disk '%s'\n",
580 env
->initrd_filename
);
585 /* Store command line. */
586 prom_set(index
++, env
->kernel_filename
);
588 prom_set(index
++, "rd_start=0x" TARGET_FMT_lx
" rd_size=%li %s", INITRD_LOAD_ADDR
, initrd_size
, env
->kernel_cmdline
);
590 prom_set(index
++, env
->kernel_cmdline
);
592 /* Setup minimum environment variables */
593 prom_set(index
++, "memsize");
594 prom_set(index
++, "%i", env
->ram_size
);
595 prom_set(index
++, "modetty0");
596 prom_set(index
++, "38400n8r");
597 prom_set(index
++, NULL
);
602 static void main_cpu_reset(void *opaque
)
604 CPUState
*env
= opaque
;
607 /* The bootload does not need to be rewritten as it is located in a
608 read only location. The kernel location and the arguments table
609 location does not change. */
610 if (env
->kernel_filename
)
615 void mips_malta_init (int ram_size
, int vga_ram_size
, int boot_device
,
616 DisplayState
*ds
, const char **fd_filename
, int snapshot
,
617 const char *kernel_filename
, const char *kernel_cmdline
,
618 const char *initrd_filename
, const char *cpu_model
)
621 unsigned long bios_offset
;
626 /* fdctrl_t *floppy_controller; */
627 MaltaFPGAState
*malta_fpga
;
631 register_savevm("cpu", 0, 3, cpu_save
, cpu_load
, env
);
632 qemu_register_reset(main_cpu_reset
, env
);
635 cpu_register_physical_memory(0, ram_size
, IO_MEM_RAM
);
637 /* Map the bios at two physical locations, as on the real board */
638 bios_offset
= ram_size
+ vga_ram_size
;
639 cpu_register_physical_memory(0x1e000000LL
,
640 BIOS_SIZE
, bios_offset
| IO_MEM_ROM
);
641 cpu_register_physical_memory(0x1fc00000LL
,
642 BIOS_SIZE
, bios_offset
| IO_MEM_ROM
);
644 /* Load a BIOS image except if a kernel image has been specified. In
645 the later case, just write a small bootloader to the flash
647 if (kernel_filename
) {
648 env
->ram_size
= ram_size
;
649 env
->kernel_filename
= kernel_filename
;
650 env
->kernel_cmdline
= kernel_cmdline
;
651 env
->initrd_filename
= initrd_filename
;
652 kernel_addr
= load_kernel(env
);
653 write_bootloader(env
, bios_offset
, kernel_addr
);
655 snprintf(buf
, sizeof(buf
), "%s/%s", bios_dir
, BIOS_FILENAME
);
656 ret
= load_image(buf
, phys_ram_base
+ bios_offset
);
657 if (ret
< 0 || ret
> BIOS_SIZE
) {
658 fprintf(stderr
, "qemu: Warning, could not load MIPS bios '%s'\n",
664 /* Board ID = 0x420 (Malta Board with CoreLV)
665 XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
666 map to the board ID. */
667 stl_raw(phys_ram_base
+ bios_offset
+ 0x10, 0x00000420);
669 /* Init internal devices */
670 cpu_mips_clock_init(env
);
671 cpu_mips_irqctrl_init();
674 malta_fpga
= malta_fpga_init(0x1f000000LL
);
676 /* Interrupt controller */
677 isa_pic
= pic_init(pic_irq_request
, env
);
680 pci_bus
= pci_gt64120_init(isa_pic
);
683 piix4_init(pci_bus
, 80);
684 pci_piix3_ide_init(pci_bus
, bs_table
, 81);
685 usb_uhci_init(pci_bus
, 82);
686 piix4_pm_init(pci_bus
, 83);
687 pit
= pit_init(0x40, 0);
692 rtc_state
= rtc_init(0x70, 8);
694 serial_init(&pic_set_irq_new
, isa_pic
, 0x3f8, 4, serial_hds
[0]);
696 serial_init(&pic_set_irq_new
, isa_pic
, 0x2f8, 3, serial_hds
[1]);
698 parallel_init(0x378, 7, parallel_hds
[0]);
699 /* XXX: The floppy controller does not work correctly, something is
701 floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); */
709 network_init(pci_bus
);
712 QEMUMachine mips_malta_machine
= {
714 "MIPS Malta Core LV",