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;
64 static void malta_fpga_update_display(void *opaque)
68 MaltaFPGAState *s = opaque;
70 for (i = 7 ; i >= 0 ; i--) {
71 if (s->leds & (1 << i))
78 qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
79 qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
83 * EEPROM 24C01 / 24C02 emulation.
85 * Emulation for serial EEPROMs:
86 * 24C01 - 1024 bit (128 x 8)
87 * 24C02 - 2048 bit (256 x 8)
89 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
95 # define logout(fmt, args...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ##args)
97 # define logout(fmt, args...) ((void)0)
100 struct _eeprom24c0x_t {
109 uint8_t contents[256];
112 typedef struct _eeprom24c0x_t eeprom24c0x_t;
114 static eeprom24c0x_t eeprom = {
116 /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
117 /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
118 /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
119 /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
120 /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
121 /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
122 /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
123 /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
124 /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
125 /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
126 /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
127 /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128 /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
129 /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130 /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131 /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
135 static uint8_t eeprom24c0x_read()
137 logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
138 eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
142 static void eeprom24c0x_write(int scl, int sda)
144 if (eeprom.scl && scl && (eeprom.sda != sda)) {
145 logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
146 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda, sda ? "stop" : "start");
151 } else if (eeprom.tick == 0 && !eeprom.ack) {
152 /* Waiting for start. */
153 logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
154 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
155 } else if (!eeprom.scl && scl) {
156 logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
157 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
159 logout("\ti2c ack bit = 0\n");
162 } else if (eeprom.sda == sda) {
163 uint8_t bit = (sda != 0);
164 logout("\ti2c bit = %d\n", bit);
165 if (eeprom.tick < 9) {
166 eeprom.command <<= 1;
167 eeprom.command += bit;
169 if (eeprom.tick == 9) {
170 logout("\tcommand 0x%04x, %s\n", eeprom.command, bit ? "read" : "write");
173 } else if (eeprom.tick < 17) {
174 if (eeprom.command & 1) {
175 sda = ((eeprom.data & 0x80) != 0);
177 eeprom.address <<= 1;
178 eeprom.address += bit;
181 if (eeprom.tick == 17) {
182 eeprom.data = eeprom.contents[eeprom.address];
183 logout("\taddress 0x%04x, data 0x%02x\n", eeprom.address, eeprom.data);
187 } else if (eeprom.tick >= 17) {
191 logout("\tsda changed with raising scl\n");
194 logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
200 static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
202 MaltaFPGAState *s = opaque;
206 saddr = (addr & 0xfffff);
210 /* SWITCH Register */
212 val = 0x00000000; /* All switches closed */
215 /* STATUS Register */
217 #ifdef TARGET_WORDS_BIGENDIAN
229 /* LEDBAR Register */
234 /* BRKRES Register */
239 /* UART Registers are handled directly by the serial device */
246 /* XXX: implement a real I2C controller */
250 /* IN = OUT until a real I2C control is implemented */
257 /* I2CINP Register */
259 val = ((s->i2cin & ~1) | eeprom24c0x_read());
267 /* I2COUT Register */
272 /* I2CSEL Register */
279 printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
287 static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
290 MaltaFPGAState *s = opaque;
293 saddr = (addr & 0xfffff);
297 /* SWITCH Register */
305 /* LEDBAR Register */
306 /* XXX: implement a 8-LED array */
308 s->leds = val & 0xff;
311 /* ASCIIWORD Register */
313 snprintf(s->display_text, 9, "%08X", val);
314 malta_fpga_update_display(s);
317 /* ASCIIPOS0 to ASCIIPOS7 Registers */
326 s->display_text[(saddr - 0x00418) >> 3] = (char) val;
327 malta_fpga_update_display(s);
330 /* SOFTRES Register */
333 qemu_system_reset_request ();
336 /* BRKRES Register */
341 /* UART Registers are handled directly by the serial device */
345 s->gpout = val & 0xff;
350 s->i2coe = val & 0x03;
353 /* I2COUT Register */
355 eeprom24c0x_write(val & 0x02, val & 0x01);
359 /* I2CSEL Register */
361 s->i2csel = val & 0x01;
366 printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
373 static CPUReadMemoryFunc *malta_fpga_read[] = {
379 static CPUWriteMemoryFunc *malta_fpga_write[] = {
385 void malta_fpga_reset(void *opaque)
387 MaltaFPGAState *s = opaque;
397 s->display_text[8] = '\0';
398 snprintf(s->display_text, 9, " ");
399 malta_fpga_update_display(s);
402 MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, CPUState *env)
405 CharDriverState *uart_chr;
408 s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
410 malta = cpu_register_io_memory(0, malta_fpga_read,
411 malta_fpga_write, s);
413 cpu_register_physical_memory(base, 0x900, malta);
414 cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
416 s->display = qemu_chr_open("vc");
417 qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
418 qemu_chr_printf(s->display, "+--------+\r\n");
419 qemu_chr_printf(s->display, "+ +\r\n");
420 qemu_chr_printf(s->display, "+--------+\r\n");
421 qemu_chr_printf(s->display, "\n");
422 qemu_chr_printf(s->display, "Malta ASCII\r\n");
423 qemu_chr_printf(s->display, "+--------+\r\n");
424 qemu_chr_printf(s->display, "+ +\r\n");
425 qemu_chr_printf(s->display, "+--------+\r\n");
427 uart_chr = qemu_chr_open("vc");
428 qemu_chr_printf(uart_chr, "CBUS UART\r\n");
429 s->uart = serial_mm_init(base + 0x900, 3, env->irq[2], uart_chr, 1);
432 qemu_register_reset(malta_fpga_reset, s);
439 static void audio_init (PCIBus *pci_bus)
442 int audio_enabled = 0;
444 for (c = soundhw; !audio_enabled && c->name; ++c) {
445 audio_enabled = c->enabled;
453 for (c = soundhw; c->name; ++c) {
455 c->init.init_pci (pci_bus, s);
462 /* Network support */
463 static void network_init (PCIBus *pci_bus)
468 for(i = 0; i < nb_nics; i++) {
473 if (i == 0 && strcmp(nd->model, "pcnet") == 0) {
474 /* The malta board has a PCNet card using PCI SLOT 11 */
475 pci_nic_init(pci_bus, nd, 88);
477 pci_nic_init(pci_bus, nd, -1);
482 /* ROM and pseudo bootloader
484 The following code implements a very very simple bootloader. It first
485 loads the registers a0 to a3 to the values expected by the OS, and
486 then jump at the kernel address.
488 The bootloader should pass the locations of the kernel arguments and
489 environment variables tables. Those tables contain the 32-bit address
490 of NULL terminated strings. The environment variables table should be
491 terminated by a NULL address.
493 For a simpler implementation, the number of kernel arguments is fixed
494 to two (the name of the kernel and the command line), and the two
495 tables are actually the same one.
497 The registers a0 to a3 should contain the following values:
498 a0 - number of kernel arguments
499 a1 - 32-bit address of the kernel arguments table
500 a2 - 32-bit address of the environment variables table
501 a3 - RAM size in bytes
504 static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t kernel_entry)
508 /* Small bootloader */
509 p = (uint32_t *) (phys_ram_base + bios_offset);
510 stl_raw(p++, 0x0bf00160); /* j 0x1fc00580 */
511 stl_raw(p++, 0x00000000); /* nop */
513 /* YAMON service vector */
514 stl_raw(phys_ram_base + bios_offset + 0x500, 0xbfc00580); /* start: */
515 stl_raw(phys_ram_base + bios_offset + 0x504, 0xbfc0083c); /* print_count: */
516 stl_raw(phys_ram_base + bios_offset + 0x520, 0xbfc00580); /* start: */
517 stl_raw(phys_ram_base + bios_offset + 0x52c, 0xbfc00800); /* flush_cache: */
518 stl_raw(phys_ram_base + bios_offset + 0x534, 0xbfc00808); /* print: */
519 stl_raw(phys_ram_base + bios_offset + 0x538, 0xbfc00800); /* reg_cpu_isr: */
520 stl_raw(phys_ram_base + bios_offset + 0x53c, 0xbfc00800); /* unred_cpu_isr: */
521 stl_raw(phys_ram_base + bios_offset + 0x540, 0xbfc00800); /* reg_ic_isr: */
522 stl_raw(phys_ram_base + bios_offset + 0x544, 0xbfc00800); /* unred_ic_isr: */
523 stl_raw(phys_ram_base + bios_offset + 0x548, 0xbfc00800); /* reg_esr: */
524 stl_raw(phys_ram_base + bios_offset + 0x54c, 0xbfc00800); /* unreg_esr: */
525 stl_raw(phys_ram_base + bios_offset + 0x550, 0xbfc00800); /* getchar: */
526 stl_raw(phys_ram_base + bios_offset + 0x554, 0xbfc00800); /* syscon_read: */
529 /* Second part of the bootloader */
530 p = (uint32_t *) (phys_ram_base + bios_offset + 0x580);
531 stl_raw(p++, 0x24040002); /* addiu a0, zero, 2 */
532 stl_raw(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
533 stl_raw(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff)); /* ori sp, sp, low(ENVP_ADDR) */
534 stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
535 stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a1, low(ENVP_ADDR) */
536 stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
537 stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */
538 stl_raw(p++, 0x3c070000 | (env->ram_size >> 16)); /* lui a3, high(env->ram_size) */
539 stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff)); /* ori a3, a3, low(env->ram_size) */
541 /* Load BAR registers as done by YAMON */
542 stl_raw(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */
544 #ifdef TARGET_WORDS_BIGENDIAN
545 stl_raw(p++, 0x3c08c000); /* lui t0, 0xc000 */
547 stl_raw(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */
549 stl_raw(p++, 0xad280048); /* sw t0, 0x0048(t1) */
550 #ifdef TARGET_WORDS_BIGENDIAN
551 stl_raw(p++, 0x3c084000); /* lui t0, 0x4000 */
553 stl_raw(p++, 0x34080040); /* ori t0, r0, 0x0040 */
555 stl_raw(p++, 0xad280050); /* sw t0, 0x0050(t1) */
557 #ifdef TARGET_WORDS_BIGENDIAN
558 stl_raw(p++, 0x3c088000); /* lui t0, 0x8000 */
560 stl_raw(p++, 0x34080080); /* ori t0, r0, 0x0080 */
562 stl_raw(p++, 0xad280058); /* sw t0, 0x0058(t1) */
563 #ifdef TARGET_WORDS_BIGENDIAN
564 stl_raw(p++, 0x3c083f00); /* lui t0, 0x3f00 */
566 stl_raw(p++, 0x3408003f); /* ori t0, r0, 0x003f */
568 stl_raw(p++, 0xad280060); /* sw t0, 0x0060(t1) */
570 #ifdef TARGET_WORDS_BIGENDIAN
571 stl_raw(p++, 0x3c08c100); /* lui t0, 0xc100 */
573 stl_raw(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */
575 stl_raw(p++, 0xad280080); /* sw t0, 0x0080(t1) */
576 #ifdef TARGET_WORDS_BIGENDIAN
577 stl_raw(p++, 0x3c085e00); /* lui t0, 0x5e00 */
579 stl_raw(p++, 0x3408005e); /* ori t0, r0, 0x005e */
581 stl_raw(p++, 0xad280088); /* sw t0, 0x0088(t1) */
583 /* Jump to kernel code */
584 stl_raw(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */
585 stl_raw(p++, 0x37ff0000 | (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */
586 stl_raw(p++, 0x03e00008); /* jr ra */
587 stl_raw(p++, 0x00000000); /* nop */
589 /* YAMON subroutines */
590 p = (uint32_t *) (phys_ram_base + bios_offset + 0x800);
591 stl_raw(p++, 0x03e00008); /* jr ra */
592 stl_raw(p++, 0x24020000); /* li v0,0 */
593 /* 808 YAMON print */
594 stl_raw(p++, 0x03e06821); /* move t5,ra */
595 stl_raw(p++, 0x00805821); /* move t3,a0 */
596 stl_raw(p++, 0x00a05021); /* move t2,a1 */
597 stl_raw(p++, 0x91440000); /* lbu a0,0(t2) */
598 stl_raw(p++, 0x254a0001); /* addiu t2,t2,1 */
599 stl_raw(p++, 0x10800005); /* beqz a0,834 */
600 stl_raw(p++, 0x00000000); /* nop */
601 stl_raw(p++, 0x0ff0021c); /* jal 870 */
602 stl_raw(p++, 0x00000000); /* nop */
603 stl_raw(p++, 0x08000205); /* j 814 */
604 stl_raw(p++, 0x00000000); /* nop */
605 stl_raw(p++, 0x01a00008); /* jr t5 */
606 stl_raw(p++, 0x01602021); /* move a0,t3 */
607 /* 0x83c YAMON print_count */
608 stl_raw(p++, 0x03e06821); /* move t5,ra */
609 stl_raw(p++, 0x00805821); /* move t3,a0 */
610 stl_raw(p++, 0x00a05021); /* move t2,a1 */
611 stl_raw(p++, 0x00c06021); /* move t4,a2 */
612 stl_raw(p++, 0x91440000); /* lbu a0,0(t2) */
613 stl_raw(p++, 0x0ff0021c); /* jal 870 */
614 stl_raw(p++, 0x00000000); /* nop */
615 stl_raw(p++, 0x254a0001); /* addiu t2,t2,1 */
616 stl_raw(p++, 0x258cffff); /* addiu t4,t4,-1 */
617 stl_raw(p++, 0x1580fffa); /* bnez t4,84c */
618 stl_raw(p++, 0x00000000); /* nop */
619 stl_raw(p++, 0x01a00008); /* jr t5 */
620 stl_raw(p++, 0x01602021); /* move a0,t3 */
622 stl_raw(p++, 0x3c08b800); /* lui t0,0xb400 */
623 stl_raw(p++, 0x350803f8); /* ori t0,t0,0x3f8 */
624 stl_raw(p++, 0x91090005); /* lbu t1,5(t0) */
625 stl_raw(p++, 0x00000000); /* nop */
626 stl_raw(p++, 0x31290040); /* andi t1,t1,0x40 */
627 stl_raw(p++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */
628 stl_raw(p++, 0x00000000); /* nop */
629 stl_raw(p++, 0x03e00008); /* jr ra */
630 stl_raw(p++, 0xa1040000); /* sb a0,0(t0) */
634 static void prom_set(int index, const char *string, ...)
641 if (index >= ENVP_NB_ENTRIES)
644 p = (int32_t *) (phys_ram_base + ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
647 if (string == NULL) {
652 table_addr = ENVP_ADDR + sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
653 s = (char *) (phys_ram_base + VIRT_TO_PHYS_ADDEND + table_addr);
655 stl_raw(p, table_addr);
657 va_start(ap, string);
658 vsnprintf (s, ENVP_ENTRY_SIZE, string, ap);
663 static int64_t load_kernel (CPUState *env)
665 int64_t kernel_entry, kernel_low, kernel_high;
668 ram_addr_t initrd_offset;
670 if (load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND,
671 &kernel_entry, &kernel_low, &kernel_high) < 0) {
672 fprintf(stderr, "qemu: could not load kernel '%s'\n",
673 env->kernel_filename);
680 if (env->initrd_filename) {
681 initrd_size = get_image_size (env->initrd_filename);
682 if (initrd_size > 0) {
683 initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
684 if (initrd_offset + initrd_size > env->ram_size) {
686 "qemu: memory too small for initial ram disk '%s'\n",
687 env->initrd_filename);
690 initrd_size = load_image(env->initrd_filename,
691 phys_ram_base + initrd_offset);
693 if (initrd_size == (target_ulong) -1) {
694 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
695 env->initrd_filename);
700 /* Store command line. */
701 prom_set(index++, env->kernel_filename);
703 prom_set(index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s",
704 PHYS_TO_VIRT(initrd_offset), initrd_size,
705 env->kernel_cmdline);
707 prom_set(index++, env->kernel_cmdline);
709 /* Setup minimum environment variables */
710 prom_set(index++, "memsize");
711 prom_set(index++, "%i", env->ram_size);
712 prom_set(index++, "modetty0");
713 prom_set(index++, "38400n8r");
714 prom_set(index++, NULL);
719 static void main_cpu_reset(void *opaque)
721 CPUState *env = opaque;
723 cpu_mips_register(env, NULL);
725 /* The bootload does not need to be rewritten as it is located in a
726 read only location. The kernel location and the arguments table
727 location does not change. */
728 if (env->kernel_filename) {
729 env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
735 void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
736 DisplayState *ds, const char **fd_filename, int snapshot,
737 const char *kernel_filename, const char *kernel_cmdline,
738 const char *initrd_filename, const char *cpu_model)
741 unsigned long bios_offset;
742 int64_t kernel_entry;
746 /* fdctrl_t *floppy_controller; */
747 MaltaFPGAState *malta_fpga;
757 if (cpu_model == NULL) {
764 if (mips_find_by_name(cpu_model, &def) != 0)
767 cpu_mips_register(env, def);
768 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
769 qemu_register_reset(main_cpu_reset, env);
772 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
774 /* Map the bios at two physical locations, as on the real board */
775 bios_offset = ram_size + vga_ram_size;
776 cpu_register_physical_memory(0x1e000000LL,
777 BIOS_SIZE, bios_offset | IO_MEM_ROM);
778 cpu_register_physical_memory(0x1fc00000LL,
779 BIOS_SIZE, bios_offset | IO_MEM_ROM);
781 /* Load a BIOS image except if a kernel image has been specified. In
782 the later case, just write a small bootloader to the flash
784 if (kernel_filename) {
785 env->ram_size = ram_size;
786 env->kernel_filename = kernel_filename;
787 env->kernel_cmdline = kernel_cmdline;
788 env->initrd_filename = initrd_filename;
789 kernel_entry = load_kernel(env);
790 env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
791 write_bootloader(env, bios_offset, kernel_entry);
793 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
794 ret = load_image(buf, phys_ram_base + bios_offset);
795 if (ret < 0 || ret > BIOS_SIZE) {
796 fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
802 /* Board ID = 0x420 (Malta Board with CoreLV)
803 XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
804 map to the board ID. */
805 stl_raw(phys_ram_base + bios_offset + 0x10, 0x00000420);
807 /* Init internal devices */
808 cpu_mips_irq_init_cpu(env);
809 cpu_mips_clock_init(env);
810 cpu_mips_irqctrl_init();
813 malta_fpga = malta_fpga_init(0x1f000000LL, env);
815 /* Interrupt controller */
816 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
817 i8259 = i8259_init(env->irq[2]);
820 pci_bus = pci_gt64120_init(i8259);
823 piix4_devfn = piix4_init(pci_bus, 80);
824 pci_piix4_ide_init(pci_bus, bs_table, piix4_devfn + 1, i8259);
825 usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
826 smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100);
827 eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
828 for (i = 0; i < 8; i++) {
829 /* TODO: Populate SPD eeprom data. */
830 smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256));
832 pit = pit_init(0x40, i8259[0]);
836 i8042_init(i8259[1], i8259[12], 0x60);
837 rtc_state = rtc_init(0x70, i8259[8]);
839 serial_init(0x3f8, i8259[4], serial_hds[0]);
841 serial_init(0x2f8, i8259[3], serial_hds[1]);
843 parallel_init(0x378, i8259[7], parallel_hds[0]);
844 /* XXX: The floppy controller does not work correctly, something is
846 floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table); */
854 network_init(pci_bus);
856 /* Optional PCI video card */
857 pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + ram_size,
858 ram_size, vga_ram_size);
861 QEMUMachine mips_malta_machine = {
863 "MIPS Malta Core LV",