summaryrefslogtreecommitdiffstats
path: root/qemu/hw/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/sparc64')
-rw-r--r--qemu/hw/sparc64/sun4u.c192
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);