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"
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
;
63 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
64 static void pic_irq_request(void *opaque
, int level
)
66 cpu_mips_irq_request(opaque
, 2, level
);
70 static void malta_fpga_update_display(void *opaque
)
74 MaltaFPGAState
*s
= opaque
;
76 for (i
= 7 ; i
>= 0 ; i
--) {
77 if (s
->leds
& (1 << i
))
84 qemu_chr_printf(s
->display
, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text
);
85 qemu_chr_printf(s
->display
, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s
->display_text
);
89 * EEPROM 24C01 / 24C02 emulation.
91 * Emulation for serial EEPROMs:
92 * 24C01 - 1024 bit (128 x 8)
93 * 24C02 - 2048 bit (256 x 8)
95 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
101 # define logout(fmt, args...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ##args)
103 # define logout(fmt, args...) ((void)0)
106 struct _eeprom24c0x_t
{
115 uint8_t contents
[256];
118 typedef struct _eeprom24c0x_t eeprom24c0x_t
;
120 static eeprom24c0x_t eeprom
= {
122 /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
123 /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
124 /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
125 /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
126 /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
127 /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128 /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
129 /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
130 /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131 /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132 /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133 /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134 /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135 /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
136 /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
137 /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
141 static uint8_t eeprom24c0x_read()
143 logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
144 eeprom
.tick
, eeprom
.scl
, eeprom
.sda
, eeprom
.data
);
148 static void eeprom24c0x_write(int scl
, int sda
)
150 if (eeprom
.scl
&& scl
&& (eeprom
.sda
!= sda
)) {
151 logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
152 eeprom
.tick
, eeprom
.scl
, scl
, eeprom
.sda
, sda
, sda
? "stop" : "start");
157 } else if (eeprom
.tick
== 0 && !eeprom
.ack
) {
158 /* Waiting for start. */
159 logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
160 eeprom
.tick
, eeprom
.scl
, scl
, eeprom
.sda
, sda
);
161 } else if (!eeprom
.scl
&& scl
) {
162 logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
163 eeprom
.tick
, eeprom
.scl
, scl
, eeprom
.sda
, sda
);
165 logout("\ti2c ack bit = 0\n");
168 } else if (eeprom
.sda
== sda
) {
169 uint8_t bit
= (sda
!= 0);
170 logout("\ti2c bit = %d\n", bit
);
171 if (eeprom
.tick
< 9) {
172 eeprom
.command
<<= 1;
173 eeprom
.command
+= bit
;
175 if (eeprom
.tick
== 9) {
176 logout("\tcommand 0x%04x, %s\n", eeprom
.command
, bit
? "read" : "write");
179 } else if (eeprom
.tick
< 17) {
180 if (eeprom
.command
& 1) {
181 sda
= ((eeprom
.data
& 0x80) != 0);
183 eeprom
.address
<<= 1;
184 eeprom
.address
+= bit
;
187 if (eeprom
.tick
== 17) {
188 eeprom
.data
= eeprom
.contents
[eeprom
.address
];
189 logout("\taddress 0x%04x, data 0x%02x\n", eeprom
.address
, eeprom
.data
);
193 } else if (eeprom
.tick
>= 17) {
197 logout("\tsda changed with raising scl\n");
200 logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom
.tick
, eeprom
.scl
, scl
, eeprom
.sda
, sda
);
206 static uint32_t malta_fpga_readl(void *opaque
, target_phys_addr_t addr
)
208 MaltaFPGAState
*s
= opaque
;
212 saddr
= (addr
& 0xfffff);
216 /* SWITCH Register */
218 val
= 0x00000000; /* All switches closed */
221 /* STATUS Register */
223 #ifdef TARGET_WORDS_BIGENDIAN
235 /* LEDBAR Register */
240 /* BRKRES Register */
254 val
= serial_mm_readl(s
->uart
, addr
);
262 /* XXX: implement a real I2C controller */
266 /* IN = OUT until a real I2C control is implemented */
273 /* I2CINP Register */
275 val
= ((s
->i2cin
& ~1) | eeprom24c0x_read());
283 /* I2COUT Register */
288 /* I2CSEL Register */
295 printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx
"\n",
303 static void malta_fpga_writel(void *opaque
, target_phys_addr_t addr
,
306 MaltaFPGAState
*s
= opaque
;
309 saddr
= (addr
& 0xfffff);
313 /* SWITCH Register */
321 /* LEDBAR Register */
322 /* XXX: implement a 8-LED array */
324 s
->leds
= val
& 0xff;
327 /* ASCIIWORD Register */
329 snprintf(s
->display_text
, 9, "%08X", val
);
330 malta_fpga_update_display(s
);
333 /* ASCIIPOS0 to ASCIIPOS7 Registers */
342 s
->display_text
[(saddr
- 0x00418) >> 3] = (char) val
;
343 malta_fpga_update_display(s
);
346 /* SOFTRES Register */
349 qemu_system_reset_request ();
352 /* BRKRES Register */
366 serial_mm_writel(s
->uart
, addr
, val
);
371 s
->gpout
= val
& 0xff;
376 s
->i2coe
= val
& 0x03;
379 /* I2COUT Register */
381 eeprom24c0x_write(val
& 0x02, val
& 0x01);
385 /* I2CSEL Register */
387 s
->i2csel
= val
& 0x01;
392 printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx
"\n",
399 static CPUReadMemoryFunc
*malta_fpga_read
[] = {
405 static CPUWriteMemoryFunc
*malta_fpga_write
[] = {
411 void malta_fpga_reset(void *opaque
)
413 MaltaFPGAState
*s
= opaque
;
423 s
->display_text
[8] = '\0';
424 snprintf(s
->display_text
, 9, " ");
425 malta_fpga_update_display(s
);
428 MaltaFPGAState
*malta_fpga_init(target_phys_addr_t base
, CPUState
*env
)
431 CharDriverState
*uart_chr
;
434 s
= (MaltaFPGAState
*)qemu_mallocz(sizeof(MaltaFPGAState
));
436 malta
= cpu_register_io_memory(0, malta_fpga_read
,
437 malta_fpga_write
, s
);
439 cpu_register_physical_memory(base
, 0x100000, malta
);
441 s
->display
= qemu_chr_open("vc");
442 qemu_chr_printf(s
->display
, "\e[HMalta LEDBAR\r\n");
443 qemu_chr_printf(s
->display
, "+--------+\r\n");
444 qemu_chr_printf(s
->display
, "+ +\r\n");
445 qemu_chr_printf(s
->display
, "+--------+\r\n");
446 qemu_chr_printf(s
->display
, "\n");
447 qemu_chr_printf(s
->display
, "Malta ASCII\r\n");
448 qemu_chr_printf(s
->display
, "+--------+\r\n");
449 qemu_chr_printf(s
->display
, "+ +\r\n");
450 qemu_chr_printf(s
->display
, "+--------+\r\n");
452 uart_chr
= qemu_chr_open("vc");
453 qemu_chr_printf(uart_chr
, "CBUS UART\r\n");
454 s
->uart
= serial_mm_init(&cpu_mips_irq_request
, env
, base
, 3, 2,
458 qemu_register_reset(malta_fpga_reset
, s
);
465 static void audio_init (PCIBus
*pci_bus
)
468 int audio_enabled
= 0;
470 for (c
= soundhw
; !audio_enabled
&& c
->name
; ++c
) {
471 audio_enabled
= c
->enabled
;
479 for (c
= soundhw
; c
->name
; ++c
) {
482 fprintf(stderr
, "qemu: Unsupported Sound Card: %s\n", c
->name
);
487 c
->init
.init_pci (pci_bus
, s
);
497 /* Network support */
498 static void network_init (PCIBus
*pci_bus
)
503 for(i
= 0; i
< nb_nics
; i
++) {
508 if (i
== 0 && strcmp(nd
->model
, "pcnet") == 0) {
509 /* The malta board has a PCNet card using PCI SLOT 11 */
510 pci_nic_init(pci_bus
, nd
, 88);
512 pci_nic_init(pci_bus
, nd
, -1);
517 /* ROM and pseudo bootloader
519 The following code implements a very very simple bootloader. It first
520 loads the registers a0 to a3 to the values expected by the OS, and
521 then jump at the kernel address.
523 The bootloader should pass the locations of the kernel arguments and
524 environment variables tables. Those tables contain the 32-bit address
525 of NULL terminated strings. The environment variables table should be
526 terminated by a NULL address.
528 For a simpler implementation, the number of kernel arguments is fixed
529 to two (the name of the kernel and the command line), and the two
530 tables are actually the same one.
532 The registers a0 to a3 should contain the following values:
533 a0 - number of kernel arguments
534 a1 - 32-bit address of the kernel arguments table
535 a2 - 32-bit address of the environment variables table
536 a3 - RAM size in bytes
539 static void write_bootloader (CPUState
*env
, unsigned long bios_offset
, int64_t kernel_addr
)
543 /* Small bootloader */
544 p
= (uint32_t *) (phys_ram_base
+ bios_offset
);
545 stl_raw(p
++, 0x0bf00010); /* j 0x1fc00040 */
546 stl_raw(p
++, 0x00000000); /* nop */
548 /* Second part of the bootloader */
549 p
= (uint32_t *) (phys_ram_base
+ bios_offset
+ 0x040);
550 stl_raw(p
++, 0x3c040000); /* lui a0, 0 */
551 stl_raw(p
++, 0x34840002); /* ori a0, a0, 2 */
552 stl_raw(p
++, 0x3c050000 | ((ENVP_ADDR
>> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
553 stl_raw(p
++, 0x34a50000 | (ENVP_ADDR
& 0xffff)); /* ori a1, a0, low(ENVP_ADDR) */
554 stl_raw(p
++, 0x3c060000 | (((ENVP_ADDR
+ 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
555 stl_raw(p
++, 0x34c60000 | ((ENVP_ADDR
+ 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */
556 stl_raw(p
++, 0x3c070000 | (env
->ram_size
>> 16)); /* lui a3, high(env->ram_size) */
557 stl_raw(p
++, 0x34e70000 | (env
->ram_size
& 0xffff)); /* ori a3, a3, low(env->ram_size) */
558 stl_raw(p
++, 0x3c1f0000 | ((kernel_addr
>> 16) & 0xffff)); /* lui ra, high(kernel_addr) */;
559 stl_raw(p
++, 0x37ff0000 | (kernel_addr
& 0xffff)); /* ori ra, ra, low(kernel_addr) */
560 stl_raw(p
++, 0x03e00008); /* jr ra */
561 stl_raw(p
++, 0x00000000); /* nop */
564 static void prom_set(int index
, const char *string
, ...)
571 if (index
>= ENVP_NB_ENTRIES
)
574 p
= (int32_t *) (phys_ram_base
+ ENVP_ADDR
+ VIRT_TO_PHYS_ADDEND
);
577 if (string
== NULL
) {
582 table_addr
= ENVP_ADDR
+ sizeof(int32_t) * ENVP_NB_ENTRIES
+ index
* ENVP_ENTRY_SIZE
;
583 s
= (char *) (phys_ram_base
+ VIRT_TO_PHYS_ADDEND
+ table_addr
);
585 stl_raw(p
, table_addr
);
587 va_start(ap
, string
);
588 vsnprintf (s
, ENVP_ENTRY_SIZE
, string
, ap
);
593 static int64_t load_kernel (CPUState
*env
)
595 int64_t kernel_addr
= 0;
599 if (load_elf(env
->kernel_filename
, VIRT_TO_PHYS_ADDEND
, &kernel_addr
) < 0) {
600 fprintf(stderr
, "qemu: could not load kernel '%s'\n",
601 env
->kernel_filename
);
607 if (env
->initrd_filename
) {
608 initrd_size
= load_image(env
->initrd_filename
,
609 phys_ram_base
+ INITRD_LOAD_ADDR
+ VIRT_TO_PHYS_ADDEND
);
610 if (initrd_size
== (target_ulong
) -1) {
611 fprintf(stderr
, "qemu: could not load initial ram disk '%s'\n",
612 env
->initrd_filename
);
617 /* Store command line. */
618 prom_set(index
++, env
->kernel_filename
);
620 prom_set(index
++, "rd_start=0x" TARGET_FMT_lx
" rd_size=%li %s", INITRD_LOAD_ADDR
, initrd_size
, env
->kernel_cmdline
);
622 prom_set(index
++, env
->kernel_cmdline
);
624 /* Setup minimum environment variables */
625 prom_set(index
++, "memsize");
626 prom_set(index
++, "%i", env
->ram_size
);
627 prom_set(index
++, "modetty0");
628 prom_set(index
++, "38400n8r");
629 prom_set(index
++, NULL
);
634 static void main_cpu_reset(void *opaque
)
636 CPUState
*env
= opaque
;
639 /* The bootload does not need to be rewritten as it is located in a
640 read only location. The kernel location and the arguments table
641 location does not change. */
642 if (env
->kernel_filename
)
647 void mips_malta_init (int ram_size
, int vga_ram_size
, int boot_device
,
648 DisplayState
*ds
, const char **fd_filename
, int snapshot
,
649 const char *kernel_filename
, const char *kernel_cmdline
,
650 const char *initrd_filename
, const char *cpu_model
)
653 unsigned long bios_offset
;
658 /* fdctrl_t *floppy_controller; */
659 MaltaFPGAState
*malta_fpga
;
664 if (cpu_model
== NULL
) {
671 if (mips_find_by_name(cpu_model
, &def
) != 0)
674 cpu_mips_register(env
, def
);
675 register_savevm("cpu", 0, 3, cpu_save
, cpu_load
, env
);
676 qemu_register_reset(main_cpu_reset
, env
);
679 cpu_register_physical_memory(0, ram_size
, IO_MEM_RAM
);
681 /* Map the bios at two physical locations, as on the real board */
682 bios_offset
= ram_size
+ vga_ram_size
;
683 cpu_register_physical_memory(0x1e000000LL
,
684 BIOS_SIZE
, bios_offset
| IO_MEM_ROM
);
685 cpu_register_physical_memory(0x1fc00000LL
,
686 BIOS_SIZE
, bios_offset
| IO_MEM_ROM
);
688 /* Load a BIOS image except if a kernel image has been specified. In
689 the later case, just write a small bootloader to the flash
691 if (kernel_filename
) {
692 env
->ram_size
= ram_size
;
693 env
->kernel_filename
= kernel_filename
;
694 env
->kernel_cmdline
= kernel_cmdline
;
695 env
->initrd_filename
= initrd_filename
;
696 kernel_addr
= load_kernel(env
);
697 write_bootloader(env
, bios_offset
, kernel_addr
);
699 snprintf(buf
, sizeof(buf
), "%s/%s", bios_dir
, BIOS_FILENAME
);
700 ret
= load_image(buf
, phys_ram_base
+ bios_offset
);
701 if (ret
< 0 || ret
> BIOS_SIZE
) {
702 fprintf(stderr
, "qemu: Warning, could not load MIPS bios '%s'\n",
708 /* Board ID = 0x420 (Malta Board with CoreLV)
709 XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
710 map to the board ID. */
711 stl_raw(phys_ram_base
+ bios_offset
+ 0x10, 0x00000420);
713 /* Init internal devices */
714 cpu_mips_clock_init(env
);
715 cpu_mips_irqctrl_init();
718 malta_fpga
= malta_fpga_init(0x1f000000LL
, env
);
720 /* Interrupt controller */
721 isa_pic
= pic_init(pic_irq_request
, env
);
724 pci_bus
= pci_gt64120_init(isa_pic
);
727 piix4_init(pci_bus
, 80);
728 pci_piix3_ide_init(pci_bus
, bs_table
, 81);
729 usb_uhci_init(pci_bus
, 82);
730 piix4_pm_init(pci_bus
, 83);
731 pit
= pit_init(0x40, 0);
736 rtc_state
= rtc_init(0x70, 8);
738 serial_init(&pic_set_irq_new
, isa_pic
, 0x3f8, 4, serial_hds
[0]);
740 serial_init(&pic_set_irq_new
, isa_pic
, 0x2f8, 3, serial_hds
[1]);
742 parallel_init(0x378, 7, parallel_hds
[0]);
743 /* XXX: The floppy controller does not work correctly, something is
745 floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); */
753 network_init(pci_bus
);
755 /* Optional PCI video card */
756 pci_cirrus_vga_init(pci_bus
, ds
, phys_ram_base
+ ram_size
,
757 ram_size
, vga_ram_size
);
760 QEMUMachine mips_malta_machine
= {
762 "MIPS Malta Core LV",