diff options
Diffstat (limited to 'qemu/hw/sparc64/sun4u.c')
-rw-r--r-- | qemu/hw/sparc64/sun4u.c | 192 |
1 files changed, 97 insertions, 95 deletions
diff --git a/qemu/hw/sparc64/sun4u.c b/qemu/hw/sparc64/sun4u.c index 30cfa0e0a..3165e18eb 100644 --- a/qemu/hw/sparc64/sun4u.c +++ b/qemu/hw/sparc64/sun4u.c @@ -21,6 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/pci/pci.h" #include "hw/pci-host/apb.h" @@ -40,6 +44,7 @@ #include "elf.h" #include "sysemu/block-backend.h" #include "exec/address-spaces.h" +#include "qemu/cutils.h" //#define DEBUG_IRQ //#define DEBUG_EBUS @@ -98,29 +103,7 @@ typedef struct EbusState { MemoryRegion bar1; } EbusState; -int DMA_get_channel_mode (int nchan) -{ - return 0; -} -int DMA_read_memory (int nchan, void *buf, int pos, int size) -{ - return 0; -} -int DMA_write_memory (int nchan, void *buf, int pos, int size) -{ - return 0; -} -void DMA_hold_DREQ (int nchan) {} -void DMA_release_DREQ (int nchan) {} -void DMA_schedule(int nchan) {} - -void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit) -{ -} - -void DMA_register_channel (int nchan, - DMA_transfer_handler transfer_handler, - void *opaque) +void DMA_init(ISABus *bus, int high_page_enable) { } @@ -208,7 +191,7 @@ static uint64_t sun4u_load_kernel(const char *kernel_filename, bswap_needed = 0; #endif kernel_size = load_elf(kernel_filename, NULL, NULL, kernel_entry, - kernel_addr, &kernel_top, 1, ELF_MACHINE, 0); + kernel_addr, &kernel_top, 1, EM_SPARCV9, 0, 0); if (kernel_size < 0) { *kernel_addr = KERNEL_LOAD_ADDR; *kernel_entry = KERNEL_LOAD_ADDR; @@ -358,37 +341,19 @@ typedef struct ResetData { uint64_t prom_addr; } ResetData; -void cpu_put_timer(QEMUFile *f, CPUTimer *s) -{ - qemu_put_be32s(f, &s->frequency); - qemu_put_be32s(f, &s->disabled); - qemu_put_be64s(f, &s->disabled_mask); - qemu_put_sbe64s(f, &s->clock_offset); - - timer_put(f, s->qtimer); -} - -void cpu_get_timer(QEMUFile *f, CPUTimer *s) -{ - qemu_get_be32s(f, &s->frequency); - qemu_get_be32s(f, &s->disabled); - qemu_get_be64s(f, &s->disabled_mask); - qemu_get_sbe64s(f, &s->clock_offset); - - timer_get(f, s->qtimer); -} - static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu, QEMUBHFunc *cb, uint32_t frequency, - uint64_t disabled_mask) + uint64_t disabled_mask, uint64_t npt_mask) { CPUTimer *timer = g_malloc0(sizeof (CPUTimer)); timer->name = name; timer->frequency = frequency; timer->disabled_mask = disabled_mask; + timer->npt_mask = npt_mask; timer->disabled = 1; + timer->npt = 1; timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); timer->qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cb, cpu); @@ -484,27 +449,27 @@ static void hstick_irq(void *opaque) static int64_t cpu_to_timer_ticks(int64_t cpu_ticks, uint32_t frequency) { - return muldiv64(cpu_ticks, get_ticks_per_sec(), frequency); + return muldiv64(cpu_ticks, NANOSECONDS_PER_SECOND, frequency); } static uint64_t timer_to_cpu_ticks(int64_t timer_ticks, uint32_t frequency) { - return muldiv64(timer_ticks, frequency, get_ticks_per_sec()); + return muldiv64(timer_ticks, frequency, NANOSECONDS_PER_SECOND); } void cpu_tick_set_count(CPUTimer *timer, uint64_t count) { - uint64_t real_count = count & ~timer->disabled_mask; - uint64_t disabled_bit = count & timer->disabled_mask; + uint64_t real_count = count & ~timer->npt_mask; + uint64_t npt_bit = count & timer->npt_mask; int64_t vm_clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - cpu_to_timer_ticks(real_count, timer->frequency); - TIMER_DPRINTF("%s set_count count=0x%016lx (%s) p=%p\n", + TIMER_DPRINTF("%s set_count count=0x%016lx (npt %s) p=%p\n", timer->name, real_count, - timer->disabled?"disabled":"enabled", timer); + timer->npt ? "disabled" : "enabled", timer); - timer->disabled = disabled_bit ? 1 : 0; + timer->npt = npt_bit ? 1 : 0; timer->clock_offset = vm_clock_offset; } @@ -514,12 +479,13 @@ uint64_t cpu_tick_get_count(CPUTimer *timer) qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->clock_offset, timer->frequency); - TIMER_DPRINTF("%s get_count count=0x%016lx (%s) p=%p\n", + TIMER_DPRINTF("%s get_count count=0x%016lx (npt %s) p=%p\n", timer->name, real_count, - timer->disabled?"disabled":"enabled", timer); + timer->npt ? "disabled" : "enabled", timer); - if (timer->disabled) - real_count |= timer->disabled_mask; + if (timer->npt) { + real_count |= timer->npt_mask; + } return real_count; } @@ -593,13 +559,14 @@ pci_ebus_init(PCIBus *bus, int devfn, qemu_irq *irqs) return isa_bus; } -static int -pci_ebus_init1(PCIDevice *pci_dev) +static void pci_ebus_realize(PCIDevice *pci_dev, Error **errp) { EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev); - isa_bus_new(DEVICE(pci_dev), get_system_memory(), - pci_address_space_io(pci_dev)); + if (!isa_bus_new(DEVICE(pci_dev), get_system_memory(), + pci_address_space_io(pci_dev), errp)) { + return; + } pci_dev->config[0x04] = 0x06; // command = bus master, pci mem pci_dev->config[0x05] = 0x00; @@ -614,14 +581,13 @@ pci_ebus_init1(PCIDevice *pci_dev) memory_region_init_alias(&s->bar1, OBJECT(s), "bar1", get_system_io(), 0, 0x4000); pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->bar1); - return 0; } static void ebus_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->init = pci_ebus_init1; + k->realize = pci_ebus_realize; k->vendor_id = PCI_VENDOR_ID_SUN; k->device_id = PCI_DEVICE_ID_SUN_EBUS; k->revision = 0x01; @@ -671,7 +637,7 @@ static void prom_init(hwaddr addr, const char *bios_name) filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { ret = load_elf(filename, translate_prom_address, &addr, - NULL, NULL, NULL, 1, ELF_MACHINE, 0); + NULL, NULL, NULL, 1, EM_SPARCV9, 0, 0); if (ret < 0 || ret > PROM_SIZE_MAX) { ret = load_image_targphys(filename, addr, PROM_SIZE_MAX); } @@ -690,7 +656,7 @@ static int prom_init1(SysBusDevice *dev) PROMState *s = OPENPROM(dev); memory_region_init_ram(&s->prom, OBJECT(s), "sun4u.prom", PROM_SIZE_MAX, - &error_abort); + &error_fatal); vmstate_register_ram_global(&s->prom); memory_region_set_readonly(&s->prom, true); sysbus_init_mmio(dev, &s->prom); @@ -734,7 +700,7 @@ static int ram_init1(SysBusDevice *dev) RamDevice *d = SUN4U_RAM(dev); memory_region_init_ram(&d->ram, OBJECT(d), "sun4u.ram", d->size, - &error_abort); + &error_fatal); vmstate_register_ram_global(&d->ram); sysbus_init_mmio(dev, &d->ram); return 0; @@ -799,13 +765,16 @@ static SPARCCPU *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef) env = &cpu->env; env->tick = cpu_timer_create("tick", cpu, tick_irq, - tick_frequency, TICK_NPT_MASK); + tick_frequency, TICK_INT_DIS, + TICK_NPT_MASK); env->stick = cpu_timer_create("stick", cpu, stick_irq, - stick_frequency, TICK_INT_DIS); + stick_frequency, TICK_INT_DIS, + TICK_NPT_MASK); env->hstick = cpu_timer_create("hstick", cpu, hstick_irq, - hstick_frequency, TICK_INT_DIS); + hstick_frequency, TICK_INT_DIS, + TICK_NPT_MASK); reset_info = g_malloc0(sizeof(ResetData)); reset_info->cpu = cpu; @@ -829,6 +798,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, qemu_irq *ivec_irqs, *pbm_irqs; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *fd[MAX_FD]; + DeviceState *dev; FWCfgState *fw_cfg; /* init CPUs */ @@ -865,10 +835,22 @@ static void sun4uv_init(MemoryRegion *address_space_mem, pci_cmd646_ide_init(pci_bus, hd, 1); isa_create_simple(isa_bus, "i8042"); + + /* Floppy */ for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } - fdctrl_init_isa(isa_bus, fd); + dev = DEVICE(isa_create(isa_bus, TYPE_ISA_FDC)); + if (fd[0]) { + qdev_prop_set_drive(dev, "driveA", blk_by_legacy_dinfo(fd[0]), + &error_abort); + } + if (fd[1]) { + qdev_prop_set_drive(dev, "driveB", blk_by_legacy_dinfo(fd[1]), + &error_abort); + } + qdev_prop_set_uint32(dev, "dma", -1); + qdev_init_nofail(dev); /* Map NVRAM into I/O (ebus) space */ nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59); @@ -965,29 +947,53 @@ static void niagara_init(MachineState *machine) sun4uv_init(get_system_memory(), machine, &hwdefs[2]); } -static QEMUMachine sun4u_machine = { - .name = "sun4u", - .desc = "Sun4u platform", - .init = sun4u_init, - .max_cpus = 1, // XXX for now - .is_default = 1, - .default_boot_order = "c", +static void sun4u_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "Sun4u platform"; + mc->init = sun4u_init; + mc->max_cpus = 1; /* XXX for now */ + mc->is_default = 1; + mc->default_boot_order = "c"; +} + +static const TypeInfo sun4u_type = { + .name = MACHINE_TYPE_NAME("sun4u"), + .parent = TYPE_MACHINE, + .class_init = sun4u_class_init, }; -static QEMUMachine sun4v_machine = { - .name = "sun4v", - .desc = "Sun4v platform", - .init = sun4v_init, - .max_cpus = 1, // XXX for now - .default_boot_order = "c", +static void sun4v_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "Sun4v platform"; + mc->init = sun4v_init; + mc->max_cpus = 1; /* XXX for now */ + mc->default_boot_order = "c"; +} + +static const TypeInfo sun4v_type = { + .name = MACHINE_TYPE_NAME("sun4v"), + .parent = TYPE_MACHINE, + .class_init = sun4v_class_init, }; -static QEMUMachine niagara_machine = { - .name = "Niagara", - .desc = "Sun4v platform, Niagara", - .init = niagara_init, - .max_cpus = 1, // XXX for now - .default_boot_order = "c", +static void niagara_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "Sun4v platform, Niagara"; + mc->init = niagara_init; + mc->max_cpus = 1; /* XXX for now */ + mc->default_boot_order = "c"; +} + +static const TypeInfo niagara_type = { + .name = MACHINE_TYPE_NAME("Niagara"), + .parent = TYPE_MACHINE, + .class_init = niagara_class_init, }; static void sun4u_register_types(void) @@ -995,14 +1001,10 @@ static void sun4u_register_types(void) type_register_static(&ebus_info); type_register_static(&prom_info); type_register_static(&ram_info); -} -static void sun4u_machine_init(void) -{ - qemu_register_machine(&sun4u_machine); - qemu_register_machine(&sun4v_machine); - qemu_register_machine(&niagara_machine); + type_register_static(&sun4u_type); + type_register_static(&sun4v_type); + type_register_static(&niagara_type); } type_init(sun4u_register_types) -machine_init(sun4u_machine_init); |