X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=hw%2Fmips_malta.c;h=0571d58908b6fa5d47a9eb88cc4e8656d4e11e75;hb=626c7a171e644fbe1579516b8b794d611c295d2f;hp=bb497495695810e14aed15cd9dbb068e480085d8;hpb=9f047b8948f43dddb0ee2a391939999fab13eaf4;p=qemu.git diff --git a/hw/mips_malta.c b/hw/mips_malta.c index bb4974956..0571d5890 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -24,6 +24,7 @@ #include "hw.h" #include "pc.h" +#include "serial.h" #include "fdc.h" #include "net.h" #include "boards.h" @@ -33,8 +34,6 @@ #include "mips.h" #include "mips_cpudevs.h" #include "pci.h" -#include "usb-uhci.h" -#include "vmware_vga.h" #include "qemu-char.h" #include "sysemu.h" #include "arch_init.h" @@ -45,8 +44,10 @@ #include "loader.h" #include "elf.h" #include "mc146818rtc.h" +#include "i8254.h" #include "blockdev.h" #include "exec-memory.h" +#include "sysbus.h" /* SysBusDevice */ //#define DEBUG_BOARD_INIT @@ -54,6 +55,13 @@ #define ENVP_NB_ENTRIES 16 #define ENVP_ENTRY_SIZE 256 +/* Hardware addresses */ +#define FLASH_ADDRESS 0x1e000000ULL +#define FPGA_ADDRESS 0x1f000000ULL +#define RESET_ADDRESS 0x1fc00000ULL + +#define FLASH_SIZE 0x400000 + #define MAX_IDE_BUS 2 typedef struct { @@ -72,6 +80,11 @@ typedef struct { SerialState *uart; } MaltaFPGAState; +typedef struct { + SysBusDevice busdev; + qemu_irq *i8259; +} MaltaState; + static ISADevice *pit; static struct _loaderparams { @@ -218,7 +231,7 @@ static void eeprom24c0x_write(int scl, int sda) eeprom.sda = sda; } -static uint64_t malta_fpga_read(void *opaque, target_phys_addr_t addr, +static uint64_t malta_fpga_read(void *opaque, hwaddr addr, unsigned size) { MaltaFPGAState *s = opaque; @@ -306,7 +319,7 @@ static uint64_t malta_fpga_read(void *opaque, target_phys_addr_t addr, return val; } -static void malta_fpga_write(void *opaque, target_phys_addr_t addr, +static void malta_fpga_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { MaltaFPGAState *s = opaque; @@ -325,9 +338,9 @@ static void malta_fpga_write(void *opaque, target_phys_addr_t addr, break; /* LEDBAR Register */ - /* XXX: implement a 8-LED array */ case 0x00408: s->leds = val & 0xff; + malta_fpga_update_display(s); break; /* ASCIIWORD Register */ @@ -428,7 +441,7 @@ static void malta_fpga_led_init(CharDriverState *chr) } static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space, - target_phys_addr_t base, qemu_irq uart_irq, CharDriverState *uart_chr) + hwaddr base, qemu_irq uart_irq, CharDriverState *uart_chr) { MaltaFPGAState *s; @@ -494,7 +507,7 @@ static void network_init(void) a3 - RAM size in bytes */ -static void write_bootloader (CPUState *env, uint8_t *base, +static void write_bootloader (CPUMIPSState *env, uint8_t *base, int64_t kernel_entry) { uint32_t *p; @@ -730,7 +743,7 @@ static int64_t load_kernel (void) return kernel_entry; } -static void malta_mips_config(CPUState *env) +static void malta_mips_config(CPUMIPSState *env) { env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) | ((smp_cpus * env->nr_threads - 1) << CP0MVPC0_PTC); @@ -738,8 +751,10 @@ static void malta_mips_config(CPUState *env) static void main_cpu_reset(void *opaque) { - CPUState *env = opaque; - cpu_reset(env); + MIPSCPU *cpu = opaque; + CPUMIPSState *env = &cpu->env; + + cpu_reset(CPU(cpu)); /* The bootloader does not need to be rewritten as it is located in a read only location. The kernel location and the arguments table @@ -753,7 +768,7 @@ static void main_cpu_reset(void *opaque) static void cpu_request_exit(void *opaque, int irq, int level) { - CPUState *env = cpu_single_env; + CPUMIPSState *env = cpu_single_env; if (env && level) { cpu_exit(env); @@ -761,21 +776,25 @@ static void cpu_request_exit(void *opaque, int irq, int level) } static -void mips_malta_init (ram_addr_t ram_size, - const char *boot_device, - const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename, const char *cpu_model) +void mips_malta_init(QEMUMachineInitArgs *args) { + ram_addr_t ram_size = args->ram_size; + const char *cpu_model = args->cpu_model; + const char *kernel_filename = args->kernel_filename; + const char *kernel_cmdline = args->kernel_cmdline; + const char *initrd_filename = args->initrd_filename; char *filename; pflash_t *fl; MemoryRegion *system_memory = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1); - target_long bios_size; + target_long bios_size = FLASH_SIZE; int64_t kernel_entry; PCIBus *pci_bus; - CPUState *env; - qemu_irq *i8259 = NULL, *isa_irq; + ISABus *isa_bus; + MIPSCPU *cpu; + CPUMIPSState *env; + qemu_irq *isa_irq; qemu_irq *cpu_exit_irq; int piix4_devfn; i2c_bus *smbus; @@ -784,9 +803,14 @@ void mips_malta_init (ram_addr_t ram_size, DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *fd[MAX_FD]; int fl_idx = 0; - int fl_sectors = 0; + int fl_sectors = bios_size >> 16; int be; + DeviceState *dev = qdev_create(NULL, "mips-malta"); + MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev); + + qdev_init_nofail(dev); + /* Make sure the first 3 serial ports are associated with a device. */ for(i = 0; i < 3; i++) { if (!serial_hds[i]) { @@ -806,15 +830,17 @@ void mips_malta_init (ram_addr_t ram_size, } for (i = 0; i < smp_cpus; i++) { - env = cpu_init(cpu_model); - if (!env) { + cpu = cpu_mips_init(cpu_model); + if (cpu == NULL) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } + env = &cpu->env; + /* Init internal devices */ cpu_mips_irq_init_cpu(env); cpu_mips_clock_init(env); - qemu_register_reset(main_cpu_reset, env); + qemu_register_reset(main_cpu_reset, cpu); } env = first_cpu; @@ -825,7 +851,8 @@ void mips_malta_init (ram_addr_t ram_size, ((unsigned int)ram_size / (1 << 20))); exit(1); } - memory_region_init_ram(ram, NULL, "mips_malta.ram", ram_size); + memory_region_init_ram(ram, "mips_malta.ram", ram_size); + vmstate_register_ram_global(ram); memory_region_add_subregion(system_memory, 0, ram); #ifdef TARGET_WORDS_BIGENDIAN @@ -834,18 +861,26 @@ void mips_malta_init (ram_addr_t ram_size, be = 0; #endif /* FPGA */ - malta_fpga_init(system_memory, 0x1f000000LL, env->irq[2], serial_hds[2]); + malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[2], serial_hds[2]); - /* Load firmware in flash / BIOS unless we boot directly into a kernel. */ + /* Load firmware in flash / BIOS. */ + dinfo = drive_get(IF_PFLASH, 0, fl_idx); +#ifdef DEBUG_BOARD_INIT + if (dinfo) { + printf("Register parallel flash %d size " TARGET_FMT_lx " at " + "addr %08llx '%s' %x\n", + fl_idx, bios_size, FLASH_ADDRESS, + bdrv_get_device_name(dinfo->bdrv), fl_sectors); + } +#endif + fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios", + BIOS_SIZE, dinfo ? dinfo->bdrv : NULL, + 65536, fl_sectors, + 4, 0x0000, 0x0000, 0x0000, 0x0000, be); + bios = pflash_cfi01_get_memory(fl); + fl_idx++; if (kernel_filename) { /* Write a small bootloader to the flash location. */ - bios = g_new(MemoryRegion, 1); - memory_region_init_ram(bios, NULL, "mips_malta.bios", BIOS_SIZE); - memory_region_set_readonly(bios, true); - memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE); - /* Map the bios at two physical locations, as on the real board. */ - memory_region_add_subregion(system_memory, 0x1e000000LL, bios); - memory_region_add_subregion(system_memory, 0x1fc00000LL, bios_alias); loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; @@ -853,44 +888,15 @@ void mips_malta_init (ram_addr_t ram_size, kernel_entry = load_kernel(); write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry); } else { - dinfo = drive_get(IF_PFLASH, 0, fl_idx); - if (dinfo) { - /* Load firmware from flash. */ - bios_size = 0x400000; - fl_sectors = bios_size >> 16; -#ifdef DEBUG_BOARD_INIT - printf("Register parallel flash %d size " TARGET_FMT_lx " at " - "addr %08llx '%s' %x\n", - fl_idx, bios_size, 0x1e000000LL, - bdrv_get_device_name(dinfo->bdrv), fl_sectors); -#endif - fl = pflash_cfi01_register(0x1e000000LL, - NULL, "mips_malta.bios", BIOS_SIZE, - dinfo->bdrv, 65536, fl_sectors, - 4, 0x0000, 0x0000, 0x0000, 0x0000, be); - bios = pflash_cfi01_get_memory(fl); - /* Map the bios at two physical locations, as on the real board. */ - memory_region_init_alias(bios_alias, "bios.1fc", - bios, 0, BIOS_SIZE); - memory_region_add_subregion(system_memory, 0x1fc00000LL, - bios_alias); - fl_idx++; - } else { - bios = g_new(MemoryRegion, 1); - memory_region_init_ram(bios, NULL, "mips_malta.bios", BIOS_SIZE); - memory_region_set_readonly(bios, true); - memory_region_init_alias(bios_alias, "bios.1fc", - bios, 0, BIOS_SIZE); - /* Map the bios at two physical locations, as on the real board. */ - memory_region_add_subregion(system_memory, 0x1e000000LL, bios); - memory_region_add_subregion(system_memory, 0x1fc00000LL, - bios_alias); + /* Load firmware from flash. */ + if (!dinfo) { /* Load a BIOS image. */ - if (bios_name == NULL) + if (bios_name == NULL) { bios_name = BIOS_FILENAME; + } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - bios_size = load_image_targphys(filename, 0x1fc00000LL, + bios_size = load_image_targphys(filename, FLASH_ADDRESS, BIOS_SIZE); g_free(filename); } else { @@ -911,11 +917,16 @@ void mips_malta_init (ram_addr_t ram_size, uint32_t *end = addr + bios_size; while (addr < end) { bswap32s(addr); + addr++; } } #endif } + /* Map the BIOS at a 2nd physical location, as on the real board. */ + memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE); + memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_alias); + /* Board ID = 0x420 (Malta Board with CoreLV) XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should map to the board ID. */ @@ -932,7 +943,7 @@ void mips_malta_init (ram_addr_t ram_size, * qemu_irq_proxy() adds an extra bit of indirection, allowing us * to resolve the isa_irq -> i8259 dependency after i8259 is initialized. */ - isa_irq = qemu_irq_proxy(&i8259, 16); + isa_irq = qemu_irq_proxy(&s->i8259, 16); /* Northbridge */ pci_bus = gt64120_register(isa_irq); @@ -940,56 +951,65 @@ void mips_malta_init (ram_addr_t ram_size, /* Southbridge */ ide_drive_get(hd, MAX_IDE_BUS); - piix4_devfn = piix4_init(pci_bus, 80); + piix4_devfn = piix4_init(pci_bus, &isa_bus, 80); /* Interrupt controller */ /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */ - i8259 = i8259_init(env->irq[2]); + s->i8259 = i8259_init(isa_bus, env->irq[2]); - isa_bus_irqs(i8259); + isa_bus_irqs(isa_bus, s->i8259); pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1); - usb_uhci_piix4_init(pci_bus, piix4_devfn + 2); - smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_get_irq(9), - NULL, NULL, 0); + pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci"); + smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, + isa_get_irq(NULL, 9), NULL, 0, NULL); /* TODO: Populate SPD eeprom data. */ smbus_eeprom_init(smbus, 8, NULL, 0); - pit = pit_init(0x40, 0); + pit = pit_init(isa_bus, 0x40, 0, NULL); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); DMA_init(0, cpu_exit_irq); /* Super I/O */ - isa_create_simple("i8042"); + isa_create_simple(isa_bus, "i8042"); - rtc_init(2000, NULL); - serial_isa_init(0, serial_hds[0]); - serial_isa_init(1, serial_hds[1]); + rtc_init(isa_bus, 2000, NULL); + serial_isa_init(isa_bus, 0, serial_hds[0]); + serial_isa_init(isa_bus, 1, serial_hds[1]); if (parallel_hds[0]) - parallel_init(0, parallel_hds[0]); + parallel_init(isa_bus, 0, parallel_hds[0]); for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } - fdctrl_init_isa(fd); + fdctrl_init_isa(isa_bus, fd); /* Sound card */ - audio_init(NULL, pci_bus); + audio_init(isa_bus, pci_bus); /* Network card */ network_init(); /* Optional PCI video card */ - if (cirrus_vga_enabled) { - pci_cirrus_vga_init(pci_bus); - } else if (vmsvga_enabled) { - if (!pci_vmsvga_init(pci_bus)) { - fprintf(stderr, "Warning: vmware_vga not available," - " using standard VGA instead\n"); - pci_vga_init(pci_bus); - } - } else if (std_vga_enabled) { - pci_vga_init(pci_bus); - } + pci_vga_init(pci_bus); +} + +static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev) +{ + return 0; } +static void mips_malta_class_init(ObjectClass *klass, void *data) +{ + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = mips_malta_sysbus_device_init; +} + +static TypeInfo mips_malta_device = { + .name = "mips-malta", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(MaltaState), + .class_init = mips_malta_class_init, +}; + static QEMUMachine mips_malta_machine = { .name = "malta", .desc = "MIPS Malta Core LV", @@ -998,9 +1018,15 @@ static QEMUMachine mips_malta_machine = { .is_default = 1, }; +static void mips_malta_register_types(void) +{ + type_register_static(&mips_malta_device); +} + static void mips_malta_machine_init(void) { qemu_register_machine(&mips_malta_machine); } +type_init(mips_malta_register_types) machine_init(mips_malta_machine_init);