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
55 CharDriverState *display;
61 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
62 static void pic_irq_request(void *opaque, int level)
64 cpu_mips_irq_request(opaque, 2, level);
68 static void malta_fpga_update_display(void *opaque)
72 MaltaFPGAState *s = opaque;
74 for (i = 7 ; i >= 0 ; i--) {
75 if (s->leds & (1 << i))
82 qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
83 qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
86 static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
88 MaltaFPGAState *s = opaque;
92 saddr = (addr & 0xfffff);
98 val = 0x00000000; /* All switches closed */
101 /* STATUS Register */
103 #ifdef TARGET_WORDS_BIGENDIAN
115 /* LEDBAR Register */
120 /* BRKRES Register */
130 /* XXX: implement a real I2C controller */
134 /* IN = OUT until a real I2C control is implemented */
141 /* I2CINP Register */
151 /* I2COUT Register */
156 /* I2CSEL Register */
163 printf ("malta_fpga_read: Bad register offset 0x" TLSZ "\n",
171 static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
174 MaltaFPGAState *s = opaque;
177 saddr = (addr & 0xfffff);
181 /* SWITCH Register */
189 /* LEDBAR Register */
190 /* XXX: implement a 8-LED array */
192 s->leds = val & 0xff;
195 /* ASCIIWORD Register */
197 snprintf(s->display_text, 9, "%08X", val);
198 malta_fpga_update_display(s);
201 /* ASCIIPOS0 to ASCIIPOS7 Registers */
210 s->display_text[(saddr - 0x00418) >> 3] = (char) val;
211 malta_fpga_update_display(s);
214 /* SOFTRES Register */
217 qemu_system_reset_request ();
220 /* BRKRES Register */
227 s->gpout = val & 0xff;
232 s->i2coe = val & 0x03;
235 /* I2COUT Register */
237 s->i2cout = val & 0x03;
240 /* I2CSEL Register */
242 s->i2cout = val & 0x01;
247 printf ("malta_fpga_write: Bad register offset 0x" TLSZ "\n",
254 static CPUReadMemoryFunc *malta_fpga_read[] = {
260 static CPUWriteMemoryFunc *malta_fpga_write[] = {
266 void malta_fpga_reset(void *opaque)
268 MaltaFPGAState *s = opaque;
277 s->display_text[8] = '\0';
278 snprintf(s->display_text, 9, " ");
279 malta_fpga_update_display(s);
282 MaltaFPGAState *malta_fpga_init(target_phys_addr_t base)
287 s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
289 malta = cpu_register_io_memory(0, malta_fpga_read,
290 malta_fpga_write, s);
291 cpu_register_physical_memory(base, 0x100000, malta);
293 s->display = qemu_chr_open("vc");
294 qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
295 qemu_chr_printf(s->display, "+--------+\r\n");
296 qemu_chr_printf(s->display, "+ +\r\n");
297 qemu_chr_printf(s->display, "+--------+\r\n");
298 qemu_chr_printf(s->display, "\n");
299 qemu_chr_printf(s->display, "Malta ASCII\r\n");
300 qemu_chr_printf(s->display, "+--------+\r\n");
301 qemu_chr_printf(s->display, "+ +\r\n");
302 qemu_chr_printf(s->display, "+--------+\r\n");
305 qemu_register_reset(malta_fpga_reset, s);
312 static void audio_init (PCIBus *pci_bus)
315 int audio_enabled = 0;
317 for (c = soundhw; !audio_enabled && c->name; ++c) {
318 audio_enabled = c->enabled;
326 for (c = soundhw; c->name; ++c) {
329 fprintf(stderr, "qemu: Unsupported Sound Card: %s\n", c->name);
334 c->init.init_pci (pci_bus, s);
344 /* Network support */
345 static void network_init (PCIBus *pci_bus)
350 for(i = 0; i < nb_nics; i++) {
355 if (i == 0 && strcmp(nd->model, "pcnet") == 0) {
356 /* The malta board has a PCNet card using PCI SLOT 11 */
357 pci_nic_init(pci_bus, nd, 88);
359 pci_nic_init(pci_bus, nd, -1);
364 /* ROM and pseudo bootloader
366 The following code implements a very very simple bootloader. It first
367 loads the registers a0 to a3 to the values expected by the OS, and
368 then jump at the kernel address.
370 The bootloader should pass the locations of the kernel arguments and
371 environment variables tables. Those tables contain the 32-bit address
372 of NULL terminated strings. The environment variables table should be
373 terminated by a NULL address.
375 For a simpler implementation, the number of kernel arguments is fixed
376 to two (the name of the kernel and the command line), and the two
377 tables are actually the same one.
379 The registers a0 to a3 should contain the following values:
380 a0 - number of kernel arguments
381 a1 - 32-bit address of the kernel arguments table
382 a2 - 32-bit address of the environment variables table
383 a3 - RAM size in bytes
386 static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t kernel_addr)
390 /* Small bootloader */
391 p = (uint32_t *) (phys_ram_base + bios_offset);
392 stl_raw(p++, 0x0bf00010); /* j 0x1fc00040 */
393 stl_raw(p++, 0x00000000); /* nop */
395 /* Second part of the bootloader */
396 p = (uint32_t *) (phys_ram_base + bios_offset + 0x040);
397 stl_raw(p++, 0x3c040000); /* lui a0, 0 */
398 stl_raw(p++, 0x34840002); /* ori a0, a0, 2 */
399 stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
400 stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a0, low(ENVP_ADDR) */
401 stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
402 stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */
403 stl_raw(p++, 0x3c070000 | (env->ram_size >> 16)); /* lui a3, high(env->ram_size) */
404 stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff)); /* ori a3, a3, low(env->ram_size) */
405 stl_raw(p++, 0x3c1f0000 | ((kernel_addr >> 16) & 0xffff)); /* lui ra, high(kernel_addr) */;
406 stl_raw(p++, 0x37ff0000 | (kernel_addr & 0xffff)); /* ori ra, ra, low(kernel_addr) */
407 stl_raw(p++, 0x03e00008); /* jr ra */
408 stl_raw(p++, 0x00000000); /* nop */
411 static void prom_set(int index, const char *string, ...)
418 if (index >= ENVP_NB_ENTRIES)
421 p = (int32_t *) (phys_ram_base + ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
424 if (string == NULL) {
429 table_addr = ENVP_ADDR + sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
430 s = (char *) (phys_ram_base + VIRT_TO_PHYS_ADDEND + table_addr);
432 stl_raw(p, table_addr);
434 va_start(ap, string);
435 vsnprintf (s, ENVP_ENTRY_SIZE, string, ap);
440 static int64_t load_kernel (CPUState *env)
442 int64_t kernel_addr = 0;
446 if (load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND, &kernel_addr) < 0) {
447 fprintf(stderr, "qemu: could not load kernel '%s'\n",
448 env->kernel_filename);
454 if (env->initrd_filename) {
455 initrd_size = load_image(env->initrd_filename,
456 phys_ram_base + INITRD_LOAD_ADDR + VIRT_TO_PHYS_ADDEND);
457 if (initrd_size == (target_ulong) -1) {
458 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
459 env->initrd_filename);
464 /* Store command line. */
465 prom_set(index++, env->kernel_filename);
467 prom_set(index++, "rd_start=0x" TLSZ " rd_size=%li %s", INITRD_LOAD_ADDR, initrd_size, env->kernel_cmdline);
469 prom_set(index++, env->kernel_cmdline);
471 /* Setup minimum environment variables */
472 prom_set(index++, "memsize");
473 prom_set(index++, "%i", env->ram_size);
474 prom_set(index++, "modetty0");
475 prom_set(index++, "38400n8r");
476 prom_set(index++, NULL);
481 static void main_cpu_reset(void *opaque)
483 CPUState *env = opaque;
486 /* The bootload does not need to be rewritten as it is located in a
487 read only location. The kernel location and the arguments table
488 location does not change. */
489 if (env->kernel_filename)
494 void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
495 DisplayState *ds, const char **fd_filename, int snapshot,
496 const char *kernel_filename, const char *kernel_cmdline,
497 const char *initrd_filename)
500 unsigned long bios_offset;
505 /* fdctrl_t *floppy_controller; */
506 MaltaFPGAState *malta_fpga;
510 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
511 qemu_register_reset(main_cpu_reset, env);
514 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
516 /* Map the bios at two physical locations, as on the real board */
517 bios_offset = ram_size + vga_ram_size;
518 cpu_register_physical_memory(0x1e000000LL,
519 BIOS_SIZE, bios_offset | IO_MEM_ROM);
520 cpu_register_physical_memory(0x1fc00000LL,
521 BIOS_SIZE, bios_offset | IO_MEM_ROM);
523 /* Load a BIOS image except if a kernel image has been specified. In
524 the later case, just write a small bootloader to the flash
526 if (kernel_filename) {
527 env->ram_size = ram_size;
528 env->kernel_filename = kernel_filename;
529 env->kernel_cmdline = kernel_cmdline;
530 env->initrd_filename = initrd_filename;
531 kernel_addr = load_kernel(env);
532 write_bootloader(env, bios_offset, kernel_addr);
534 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
535 ret = load_image(buf, phys_ram_base + bios_offset);
536 if (ret != BIOS_SIZE) {
537 fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
543 /* Board ID = 0x420 (Malta Board with CoreLV)
544 XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
545 map to the board ID. */
546 stl_raw(phys_ram_base + bios_offset + 0x10, 0x00000420);
548 /* Init internal devices */
549 cpu_mips_clock_init(env);
550 cpu_mips_irqctrl_init();
553 malta_fpga = malta_fpga_init(0x1f000000LL);
555 /* Interrupt controller */
556 isa_pic = pic_init(pic_irq_request, env);
559 pci_bus = pci_gt64120_init(isa_pic);
562 piix4_init(pci_bus, 80);
563 pci_piix3_ide_init(pci_bus, bs_table, 81);
564 usb_uhci_init(pci_bus, 82);
565 piix4_pm_init(pci_bus, 83);
566 pit = pit_init(0x40, 0);
571 rtc_state = rtc_init(0x70, 8);
572 serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
573 parallel_init(0x378, 7, parallel_hds[0]);
574 /* XXX: The floppy controller does not work correctly, something is
576 floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); */
584 network_init(pci_bus);
587 QEMUMachine mips_malta_machine = {
589 "MIPS Malta Core LV",