diff options
Diffstat (limited to 'hw/mips_malta.c')
-rw-r--r-- | hw/mips_malta.c | 115 |
1 files changed, 79 insertions, 36 deletions
diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 3b37596d1..6af5e52dc 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -22,7 +22,18 @@ * THE SOFTWARE. */ -#include "vl.h" +#include "hw.h" +#include "pc.h" +#include "fdc.h" +#include "net.h" +#include "boards.h" +#include "smbus.h" +#include "mips.h" +#include "pci.h" +#include "qemu-char.h" +#include "sysemu.h" +#include "audio/audio.h" +#include "boards.h" #ifdef TARGET_WORDS_BIGENDIAN #define BIOS_FILENAME "mips_bios.bin" @@ -42,6 +53,8 @@ #define ENVP_NB_ENTRIES 16 #define ENVP_ENTRY_SIZE 256 +#define MAX_IDE_BUS 2 + extern FILE *logfile; typedef struct { @@ -59,6 +72,13 @@ typedef struct { static PITState *pit; +static struct _loaderparams { + int ram_size; + const char *kernel_filename; + const char *kernel_cmdline; + const char *initrd_filename; +} loaderparams; + /* Malta FPGA */ static void malta_fpga_update_display(void *opaque) { @@ -381,7 +401,7 @@ static CPUWriteMemoryFunc *malta_fpga_write[] = { malta_fpga_writel }; -void malta_fpga_reset(void *opaque) +static void malta_fpga_reset(void *opaque) { MaltaFPGAState *s = opaque; @@ -398,7 +418,7 @@ void malta_fpga_reset(void *opaque) malta_fpga_update_display(s); } -MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, CPUState *env) +static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, CPUState *env) { MaltaFPGAState *s; CharDriverState *uart_chr; @@ -534,8 +554,8 @@ static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a1, low(ENVP_ADDR) */ stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */ stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */ - stl_raw(p++, 0x3c070000 | (env->ram_size >> 16)); /* lui a3, high(env->ram_size) */ - stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff)); /* ori a3, a3, low(env->ram_size) */ + stl_raw(p++, 0x3c070000 | (loaderparams.ram_size >> 16)); /* lui a3, high(ram_size) */ + stl_raw(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff)); /* ori a3, a3, low(ram_size) */ /* Load BAR registers as done by YAMON */ stl_raw(p++, 0x3c09b400); /* lui t1, 0xb400 */ @@ -675,48 +695,48 @@ static int64_t load_kernel (CPUState *env) long initrd_size; ram_addr_t initrd_offset; - if (load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND, + if (load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND, &kernel_entry, &kernel_low, &kernel_high) < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", - env->kernel_filename); + loaderparams.kernel_filename); exit(1); } /* load initrd */ initrd_size = 0; initrd_offset = 0; - if (env->initrd_filename) { - initrd_size = get_image_size (env->initrd_filename); + if (loaderparams.initrd_filename) { + initrd_size = get_image_size (loaderparams.initrd_filename); if (initrd_size > 0) { initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK; - if (initrd_offset + initrd_size > env->ram_size) { + if (initrd_offset + initrd_size > ram_size) { fprintf(stderr, "qemu: memory too small for initial ram disk '%s'\n", - env->initrd_filename); + loaderparams.initrd_filename); exit(1); } - initrd_size = load_image(env->initrd_filename, + initrd_size = load_image(loaderparams.initrd_filename, phys_ram_base + initrd_offset); } if (initrd_size == (target_ulong) -1) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", - env->initrd_filename); + loaderparams.initrd_filename); exit(1); } } /* Store command line. */ - prom_set(index++, env->kernel_filename); + prom_set(index++, loaderparams.kernel_filename); if (initrd_size > 0) prom_set(index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s", PHYS_TO_VIRT(initrd_offset), initrd_size, - env->kernel_cmdline); + loaderparams.kernel_cmdline); else - prom_set(index++, env->kernel_cmdline); + prom_set(index++, loaderparams.kernel_cmdline); /* Setup minimum environment variables */ prom_set(index++, "memsize"); - prom_set(index++, "%i", env->ram_size); + prom_set(index++, "%i", loaderparams.ram_size); prom_set(index++, "modetty0"); prom_set(index++, "38400n8r"); prom_set(index++, NULL); @@ -728,20 +748,19 @@ static void main_cpu_reset(void *opaque) { CPUState *env = opaque; cpu_reset(env); - cpu_mips_register(env, NULL); /* The bootload does not need to be rewritten as it is located in a read only location. The kernel location and the arguments table location does not change. */ - if (env->kernel_filename) { + if (loaderparams.kernel_filename) { env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL)); load_kernel (env); } } static -void mips_malta_init (int ram_size, int vga_ram_size, int boot_device, - DisplayState *ds, const char **fd_filename, int snapshot, +void mips_malta_init (int ram_size, int vga_ram_size, + const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { @@ -751,15 +770,17 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device, PCIBus *pci_bus; CPUState *env; RTCState *rtc_state; - /* fdctrl_t *floppy_controller; */ + fdctrl_t *floppy_controller; MaltaFPGAState *malta_fpga; int ret; - mips_def_t *def; qemu_irq *i8259; int piix4_devfn; uint8_t *eeprom_buf; i2c_bus *smbus; int i; + int index; + BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; + BlockDriverState *fd[MAX_FD]; /* init CPUs */ if (cpu_model == NULL) { @@ -769,10 +790,11 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device, cpu_model = "24Kf"; #endif } - if (mips_find_by_name(cpu_model, &def) != 0) - def = NULL; - env = cpu_init(); - cpu_mips_register(env, def); + env = cpu_init(cpu_model); + if (!env) { + fprintf(stderr, "Unable to find CPU definition\n"); + exit(1); + } register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); qemu_register_reset(main_cpu_reset, env); @@ -791,7 +813,9 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device, /* Load a BIOS image unless a kernel image has been specified. */ if (!kernel_filename) { - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME); + if (bios_name == NULL) + bios_name = BIOS_FILENAME; + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); ret = load_image(buf, phys_ram_base + bios_offset); if (ret < 0 || ret > BIOS_SIZE) { fprintf(stderr, @@ -816,10 +840,10 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device, /* If a kernel image has been specified, write a small bootloader to the flash location. */ if (kernel_filename) { - env->ram_size = ram_size; - env->kernel_filename = kernel_filename; - env->kernel_cmdline = kernel_cmdline; - env->initrd_filename = initrd_filename; + loaderparams.ram_size = ram_size; + loaderparams.kernel_filename = kernel_filename; + loaderparams.kernel_cmdline = kernel_cmdline; + loaderparams.initrd_filename = initrd_filename; kernel_entry = load_kernel(env); env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL)); write_bootloader(env, bios_offset, kernel_entry); @@ -843,8 +867,22 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device, pci_bus = pci_gt64120_init(i8259); /* Southbridge */ + + if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { + fprintf(stderr, "qemu: too many IDE bus\n"); + exit(1); + } + + for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { + index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); + if (index != -1) + hd[i] = drives_table[index].bdrv; + else + hd[i] = NULL; + } + piix4_devfn = piix4_init(pci_bus, 80); - pci_piix4_ide_init(pci_bus, bs_table, piix4_devfn + 1, i8259); + pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1, i8259); usb_uhci_piix4_init(pci_bus, piix4_devfn + 2); smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100); eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ @@ -864,9 +902,14 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device, serial_init(0x2f8, i8259[3], serial_hds[1]); if (parallel_hds[0]) parallel_init(0x378, i8259[7], parallel_hds[0]); - /* XXX: The floppy controller does not work correctly, something is - probably wrong. - floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table); */ + for(i = 0; i < MAX_FD; i++) { + index = drive_get_index(IF_FLOPPY, 0, i); + if (index != -1) + fd[i] = drives_table[index].bdrv; + else + fd[i] = NULL; + } + floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd); /* Sound card */ #ifdef HAS_AUDIO |