#include "loader.h"
#include "elf.h"
#include "blockdev.h"
-
-//#define DEBUG_IRQ
+#include "trace.h"
/*
* Sun4m architecture was used in the following machines:
* See for example: http://www.sunhelp.org/faq/sunref1.html
*/
-#ifdef DEBUG_IRQ
-#define DPRINTF(fmt, ...) \
- do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
#define KERNEL_LOAD_ADDR 0x00004000
#define CMDLINE_ADDR 0x007ff000
#define INITRD_LOAD_ADDR 0x00800000
target_phys_addr_t reg_base, vram_base;
} vsimm[MAX_VSIMMS];
target_phys_addr_t ecc_base;
- uint32_t ecc_version;
- uint8_t nvram_machine_id;
- uint16_t machine_id;
- uint32_t iommu_version;
uint64_t max_mem;
const char * const default_cpu_model;
+ uint32_t ecc_version;
+ uint32_t iommu_version;
+ uint16_t machine_id;
+ uint8_t nvram_machine_id;
};
#define MAX_IOUNITS 5
target_phys_addr_t ledma_base, le_base;
target_phys_addr_t tcx_base;
target_phys_addr_t sbi_base;
- uint8_t nvram_machine_id;
- uint16_t machine_id;
- uint32_t iounit_version;
uint64_t max_mem;
const char * const default_cpu_model;
+ uint32_t iounit_version;
+ uint16_t machine_id;
+ uint8_t nvram_machine_id;
};
struct sun4c_hwdef {
target_phys_addr_t serial_base, fd_base;
target_phys_addr_t idreg_base, dma_base, esp_base, le_base;
target_phys_addr_t tcx_base, aux1_base;
- uint8_t nvram_machine_id;
- uint16_t machine_id;
- uint32_t iommu_version;
uint64_t max_mem;
const char * const default_cpu_model;
+ uint32_t iommu_version;
+ uint16_t machine_id;
+ uint8_t nvram_machine_id;
};
int DMA_get_channel_mode (int nchan)
static DeviceState *slavio_intctl;
-void pic_info(Monitor *mon)
+void sun4m_pic_info(Monitor *mon)
{
if (slavio_intctl)
slavio_pic_info(mon, slavio_intctl);
}
-void irq_info(Monitor *mon)
+void sun4m_irq_info(Monitor *mon)
{
if (slavio_intctl)
slavio_irq_info(mon, slavio_intctl);
env->interrupt_index = TT_EXTINT | i;
if (old_interrupt != env->interrupt_index) {
- DPRINTF("Set CPU IRQ %d\n", i);
+ trace_sun4m_cpu_interrupt(i);
cpu_interrupt(env, CPU_INTERRUPT_HARD);
}
break;
}
}
} else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
- DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
+ trace_sun4m_cpu_reset_interrupt(env->interrupt_index & 15);
env->interrupt_index = 0;
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
}
}
+static void cpu_kick_irq(CPUState *env)
+{
+ env->halted = 0;
+ cpu_check_irqs(env);
+ qemu_cpu_kick(env);
+}
+
static void cpu_set_irq(void *opaque, int irq, int level)
{
CPUState *env = opaque;
if (level) {
- DPRINTF("Raise CPU IRQ %d\n", irq);
- env->halted = 0;
+ trace_sun4m_cpu_set_irq_raise(irq);
env->pil_in |= 1 << irq;
- cpu_check_irqs(env);
+ cpu_kick_irq(env);
} else {
- DPRINTF("Lower CPU IRQ %d\n", irq);
+ trace_sun4m_cpu_set_irq_lower(irq);
env->pil_in &= ~(1 << irq);
cpu_check_irqs(env);
}
}
static void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq parent_irq,
- void *iommu, qemu_irq *dev_irq)
+ void *iommu, qemu_irq *dev_irq, int is_ledma)
{
DeviceState *dev;
SysBusDevice *s;
dev = qdev_create(NULL, "sparc32_dma");
qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
+ qdev_prop_set_uint32(dev, "is_ledma", is_ledma);
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
sysbus_connect_irq(s, 0, parent_irq);
cpu_physical_memory_write_rom(addr, idreg_data, sizeof(idreg_data));
}
+typedef struct IDRegState {
+ SysBusDevice busdev;
+ MemoryRegion mem;
+} IDRegState;
+
static int idreg_init1(SysBusDevice *dev)
{
- ram_addr_t idreg_offset;
+ IDRegState *s = FROM_SYSBUS(IDRegState, dev);
- idreg_offset = qemu_ram_alloc(NULL, "sun4m.idreg", sizeof(idreg_data));
- sysbus_init_mmio(dev, sizeof(idreg_data), idreg_offset | IO_MEM_ROM);
+ memory_region_init_ram(&s->mem, NULL, "sun4m.idreg", sizeof(idreg_data));
+ memory_region_set_readonly(&s->mem, true);
+ sysbus_init_mmio_region(dev, &s->mem);
return 0;
}
static SysBusDeviceInfo idreg_info = {
.init = idreg_init1,
.qdev.name = "macio_idreg",
- .qdev.size = sizeof(SysBusDevice),
+ .qdev.size = sizeof(IDRegState),
};
static void idreg_register_devices(void)
device_init(idreg_register_devices);
+typedef struct AFXState {
+ SysBusDevice busdev;
+ MemoryRegion mem;
+} AFXState;
+
/* SS-5 TCX AFX register */
static void afx_init(target_phys_addr_t addr)
{
static int afx_init1(SysBusDevice *dev)
{
- ram_addr_t afx_offset;
+ AFXState *s = FROM_SYSBUS(AFXState, dev);
- afx_offset = qemu_ram_alloc(NULL, "sun4m.afx", 4);
- sysbus_init_mmio(dev, 4, afx_offset | IO_MEM_RAM);
+ memory_region_init_ram(&s->mem, NULL, "sun4m.afx", 4);
+ sysbus_init_mmio_region(dev, &s->mem);
return 0;
}
static SysBusDeviceInfo afx_info = {
.init = afx_init1,
.qdev.name = "tcx_afx",
- .qdev.size = sizeof(SysBusDevice),
+ .qdev.size = sizeof(AFXState),
};
static void afx_register_devices(void)
device_init(afx_register_devices);
+typedef struct PROMState {
+ SysBusDevice busdev;
+ MemoryRegion prom;
+} PROMState;
+
/* Boot PROM (OpenBIOS) */
static uint64_t translate_prom_address(void *opaque, uint64_t addr)
{
if (ret < 0 || ret > PROM_SIZE_MAX) {
ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
}
- qemu_free(filename);
+ g_free(filename);
} else {
ret = -1;
}
static int prom_init1(SysBusDevice *dev)
{
- ram_addr_t prom_offset;
+ PROMState *s = FROM_SYSBUS(PROMState, dev);
- prom_offset = qemu_ram_alloc(NULL, "sun4m.prom", PROM_SIZE_MAX);
- sysbus_init_mmio(dev, PROM_SIZE_MAX, prom_offset | IO_MEM_ROM);
+ memory_region_init_ram(&s->prom, NULL, "sun4m.prom", PROM_SIZE_MAX);
+ memory_region_set_readonly(&s->prom, true);
+ sysbus_init_mmio_region(dev, &s->prom);
return 0;
}
static SysBusDeviceInfo prom_info = {
.init = prom_init1,
.qdev.name = "openprom",
- .qdev.size = sizeof(SysBusDevice),
+ .qdev.size = sizeof(PROMState),
.qdev.props = (Property[]) {
{/* end of property list */}
}
typedef struct RamDevice
{
SysBusDevice busdev;
+ MemoryRegion ram;
uint64_t size;
} RamDevice;
/* System RAM */
static int ram_init1(SysBusDevice *dev)
{
- ram_addr_t RAM_size, ram_offset;
RamDevice *d = FROM_SYSBUS(RamDevice, dev);
- RAM_size = d->size;
-
- ram_offset = qemu_ram_alloc(NULL, "sun4m.ram", RAM_size);
- sysbus_init_mmio(dev, RAM_size, ram_offset);
+ memory_region_init_ram(&d->ram, NULL, "sun4m.ram", d->size);
+ sysbus_init_mmio_region(dev, &d->ram);
return 0;
}
}
espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[18],
- iommu, &espdma_irq);
+ iommu, &espdma_irq, 0);
ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
- slavio_irq[16], iommu, &ledma_irq);
+ slavio_irq[16], iommu, &ledma_irq, 1);
if (graphic_depth != 8 && graphic_depth != 24) {
fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
sbi_irq[0]);
espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[3],
- iounits[0], &espdma_irq);
+ iounits[0], &espdma_irq, 0);
+ /* should be lebuffer instead */
ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[4],
- iounits[0], &ledma_irq);
+ iounits[0], &ledma_irq, 0);
if (graphic_depth != 8 && graphic_depth != 24) {
fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
slavio_irq[1]);
espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[2],
- iommu, &espdma_irq);
+ iommu, &espdma_irq, 0);
ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
- slavio_irq[3], iommu, &ledma_irq);
+ slavio_irq[3], iommu, &ledma_irq, 1);
if (graphic_depth != 8 && graphic_depth != 24) {
fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);