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 PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
36 #define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
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_readb(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_writeb(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_entry)
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_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */
559 stl_raw(p++, 0x37ff0000 | (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */
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_entry, kernel_low, kernel_high;
598 ram_addr_t initrd_offset;
600 if (load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND,
601 &kernel_entry, &kernel_low, &kernel_high) < 0) {
602 fprintf(stderr, "qemu: could not load kernel '%s'\n",
603 env->kernel_filename);
610 if (env->initrd_filename) {
611 initrd_size = get_image_size (env->initrd_filename);
612 if (initrd_size > 0) {
613 initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
614 if (initrd_offset + initrd_size > env->ram_size) {
616 "qemu: memory too small for initial ram disk '%s'\n",
617 env->initrd_filename);
620 initrd_size = load_image(env->initrd_filename,
621 phys_ram_base + initrd_offset);
623 if (initrd_size == (target_ulong) -1) {
624 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
625 env->initrd_filename);
630 /* Store command line. */
631 prom_set(index++, env->kernel_filename);
633 prom_set(index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s",
634 PHYS_TO_VIRT(initrd_offset), initrd_size,
635 env->kernel_cmdline);
637 prom_set(index++, env->kernel_cmdline);
639 /* Setup minimum environment variables */
640 prom_set(index++, "memsize");
641 prom_set(index++, "%i", env->ram_size);
642 prom_set(index++, "modetty0");
643 prom_set(index++, "38400n8r");
644 prom_set(index++, NULL);
649 static void main_cpu_reset(void *opaque)
651 CPUState *env = opaque;
654 /* The bootload does not need to be rewritten as it is located in a
655 read only location. The kernel location and the arguments table
656 location does not change. */
657 if (env->kernel_filename) {
658 env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
664 void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
665 DisplayState *ds, const char **fd_filename, int snapshot,
666 const char *kernel_filename, const char *kernel_cmdline,
667 const char *initrd_filename, const char *cpu_model)
670 unsigned long bios_offset;
671 int64_t kernel_entry;
675 /* fdctrl_t *floppy_controller; */
676 MaltaFPGAState *malta_fpga;
681 if (cpu_model == NULL) {
688 if (mips_find_by_name(cpu_model, &def) != 0)
691 cpu_mips_register(env, def);
692 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
693 qemu_register_reset(main_cpu_reset, env);
696 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
698 /* Map the bios at two physical locations, as on the real board */
699 bios_offset = ram_size + vga_ram_size;
700 cpu_register_physical_memory(0x1e000000LL,
701 BIOS_SIZE, bios_offset | IO_MEM_ROM);
702 cpu_register_physical_memory(0x1fc00000LL,
703 BIOS_SIZE, bios_offset | IO_MEM_ROM);
705 /* Load a BIOS image except if a kernel image has been specified. In
706 the later case, just write a small bootloader to the flash
708 if (kernel_filename) {
709 env->ram_size = ram_size;
710 env->kernel_filename = kernel_filename;
711 env->kernel_cmdline = kernel_cmdline;
712 env->initrd_filename = initrd_filename;
713 kernel_entry = load_kernel(env);
714 env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
715 write_bootloader(env, bios_offset, kernel_entry);
717 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
718 ret = load_image(buf, phys_ram_base + bios_offset);
719 if (ret < 0 || ret > BIOS_SIZE) {
720 fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
726 /* Board ID = 0x420 (Malta Board with CoreLV)
727 XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
728 map to the board ID. */
729 stl_raw(phys_ram_base + bios_offset + 0x10, 0x00000420);
731 /* Init internal devices */
732 cpu_mips_clock_init(env);
733 cpu_mips_irqctrl_init();
736 malta_fpga = malta_fpga_init(0x1f000000LL, env);
738 /* Interrupt controller */
739 isa_pic = pic_init(pic_irq_request, env);
742 pci_bus = pci_gt64120_init(isa_pic);
745 piix4_init(pci_bus, 80);
746 pci_piix3_ide_init(pci_bus, bs_table, 81);
747 usb_uhci_init(pci_bus, 82);
748 piix4_pm_init(pci_bus, 83);
749 pit = pit_init(0x40, 0);
754 rtc_state = rtc_init(0x70, 8);
756 serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
758 serial_init(&pic_set_irq_new, isa_pic, 0x2f8, 3, serial_hds[1]);
760 parallel_init(0x378, 7, parallel_hds[0]);
761 /* XXX: The floppy controller does not work correctly, something is
763 floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); */
771 network_init(pci_bus);
773 /* Optional PCI video card */
774 pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size,
775 ram_size, vga_ram_size);
778 QEMUMachine mips_malta_machine = {
780 "MIPS Malta Core LV",