diff options
Diffstat (limited to 'hw/alpha/dp264.c')
-rw-r--r-- | hw/alpha/dp264.c | 104 |
1 files changed, 67 insertions, 37 deletions
diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c index dd62f2a405..52a1fa310b 100644 --- a/hw/alpha/dp264.c +++ b/hw/alpha/dp264.c @@ -7,23 +7,17 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" #include "cpu.h" -#include "hw/hw.h" #include "elf.h" #include "hw/loader.h" -#include "hw/boards.h" #include "alpha_sys.h" #include "qemu/error-report.h" -#include "sysemu/sysemu.h" -#include "hw/timer/mc146818rtc.h" -#include "hw/ide.h" -#include "hw/timer/i8254.h" +#include "hw/rtc/mc146818rtc.h" +#include "hw/ide/pci.h" #include "hw/isa/superio.h" -#include "hw/dma/i8257.h" +#include "net/net.h" #include "qemu/cutils.h" - -#define MAX_IDE_BUS 2 +#include "qemu/datadir.h" static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr) { @@ -55,14 +49,19 @@ static void clipper_init(MachineState *machine) const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; + MachineClass *mc = MACHINE_GET_CLASS(machine); AlphaCPU *cpus[4]; PCIBus *pci_bus; + PCIDevice *pci_dev; + DeviceState *i82378_dev; ISABus *isa_bus; qemu_irq rtc_irq; + qemu_irq isa_irq; long size, i; char *palcode_filename; - uint64_t palcode_entry, palcode_low, palcode_high; - uint64_t kernel_entry, kernel_low, kernel_high; + uint64_t palcode_entry; + uint64_t kernel_entry, kernel_low; + unsigned int smp_cpus = machine->smp.cpus; /* Create up to 4 cpus. */ memset(cpus, 0, sizeof(cpus)); @@ -70,52 +69,81 @@ static void clipper_init(MachineState *machine) cpus[i] = ALPHA_CPU(cpu_create(machine->cpu_type)); } + /* + * arg0 -> memory size + * arg1 -> kernel entry point + * arg2 -> config word + * + * Config word: bits 0-5 -> ncpus + * bit 6 -> nographics option (for HWRPB CTB) + * + * See init_hwrpb() in the PALcode. + */ cpus[0]->env.trap_arg0 = ram_size; cpus[0]->env.trap_arg1 = 0; - cpus[0]->env.trap_arg2 = smp_cpus; - - /* Init the chipset. */ - pci_bus = typhoon_init(ram_size, &isa_bus, &rtc_irq, cpus, - clipper_pci_map_irq); + cpus[0]->env.trap_arg2 = smp_cpus | (!machine->enable_graphics << 6); + + /* + * Init the chipset. Because we're using CLIPPER IRQ mappings, + * the minimum PCI device IdSel is 1. + */ + pci_bus = typhoon_init(machine->ram, &isa_irq, &rtc_irq, cpus, + clipper_pci_map_irq, PCI_DEVFN(1, 0)); + + /* + * Init the PCI -> ISA bridge. + * + * Technically, PCI-based Alphas shipped with one of three different + * PCI-ISA bridges: + * + * - Intel i82378 SIO + * - Cypress CY82c693UB + * - ALI M1533 + * + * (An Intel i82375 PCI-EISA bridge was also used on some models.) + * + * For simplicity, we model an i82378 here, even though it wouldn't + * have been on any Tsunami/Typhoon systems; it's close enough, and + * we don't want to deal with modelling the CY82c693UB (which has + * incompatible edge/level control registers, plus other peripherals + * like IDE and USB) or the M1533 (which also has IDE and USB). + * + * Importantly, we need to provide a PCI device node for it, otherwise + * some operating systems won't notice there's an ISA bus to configure. + */ + i82378_dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(7, 0), "i82378")); + isa_bus = ISA_BUS(qdev_get_child_bus(i82378_dev, "isa.0")); + + /* Connect the ISA PIC to the Typhoon IRQ used for ISA interrupts. */ + qdev_connect_gpio_out(i82378_dev, 0, isa_irq); /* Since we have an SRM-compatible PALcode, use the SRM epoch. */ mc146818_rtc_init(isa_bus, 1900, rtc_irq); - i8254_pit_init(isa_bus, 0x40, 0, NULL); - /* VGA setup. Don't bother loading the bios. */ pci_vga_init(pci_bus); /* Network setup. e1000 is good enough, failing Tulip support. */ - for (i = 0; i < nb_nics; i++) { - pci_nic_init_nofail(&nd_table[i], pci_bus, "e1000", NULL); - } - - /* 2 82C37 (dma) */ - isa_create_simple(isa_bus, "i82374"); + pci_init_nic_devices(pci_bus, mc->default_nic); /* Super I/O */ isa_create_simple(isa_bus, TYPE_SMC37C669_SUPERIO); /* IDE disk setup. */ - { - DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; - ide_drive_get(hd, ARRAY_SIZE(hd)); - - pci_cmd646_ide_init(pci_bus, hd, 0); - } + pci_dev = pci_create_simple(pci_bus, -1, "cmd646-ide"); + pci_ide_create_devs(pci_dev); /* Load PALcode. Given that this is not "real" cpu palcode, but one explicitly written for the emulation, we might as well load it directly from and ELF image. */ palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, - bios_name ? bios_name : "palcode-clipper"); + machine->firmware ?: "palcode-clipper"); if (palcode_filename == NULL) { error_report("no palcode provided"); exit(1); } - size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys, - NULL, &palcode_entry, &palcode_low, &palcode_high, + size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys, + NULL, &palcode_entry, NULL, NULL, NULL, 0, EM_ALPHA, 0, 0); if (size < 0) { error_report("could not load palcode '%s'", palcode_filename); @@ -133,8 +161,8 @@ static void clipper_init(MachineState *machine) if (kernel_filename) { uint64_t param_offset; - size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys, - NULL, &kernel_entry, &kernel_low, &kernel_high, + size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys, + NULL, &kernel_entry, &kernel_low, NULL, NULL, 0, EM_ALPHA, 0, 0); if (size < 0) { error_report("could not load kernel '%s'", kernel_filename); @@ -181,8 +209,10 @@ static void clipper_machine_init(MachineClass *mc) mc->init = clipper_init; mc->block_default_type = IF_IDE; mc->max_cpus = 4; - mc->is_default = 1; + mc->is_default = true; mc->default_cpu_type = ALPHA_CPU_TYPE_NAME("ev67"); + mc->default_ram_id = "ram"; + mc->default_nic = "e1000"; } DEFINE_MACHINE("clipper", clipper_machine_init) |