ifeq ($(TARGET_ARCH), sparc64)
VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o
VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
-VL_OBJS+= cirrus_vga.o parallel.o
+VL_OBJS+= cirrus_vga.o parallel.o ptimer.o
else
VL_OBJS+= sun4m.o tcx.o pcnet.o iommu.o m48t59.o slavio_intctl.o
VL_OBJS+= slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o sparc32_dma.o
static void main_cpu_reset(void *opaque)
{
CPUState *env = opaque;
+
cpu_reset(env);
+ ptimer_set_limit(env->tick, 0x7fffffffffffffffULL, 1);
+ ptimer_run(env->tick, 0);
+ ptimer_set_limit(env->stick, 0x7fffffffffffffffULL, 1);
+ ptimer_run(env->stick, 0);
+ ptimer_set_limit(env->hstick, 0x7fffffffffffffffULL, 1);
+ ptimer_run(env->hstick, 0);
+}
+
+void tick_irq(void *opaque)
+{
+ CPUState *env = opaque;
+
+ cpu_interrupt(env, CPU_INTERRUPT_TIMER);
+}
+
+void stick_irq(void *opaque)
+{
+ CPUState *env = opaque;
+
+ cpu_interrupt(env, CPU_INTERRUPT_TIMER);
+}
+
+void hstick_irq(void *opaque)
+{
+ CPUState *env = opaque;
+
+ cpu_interrupt(env, CPU_INTERRUPT_TIMER);
}
static const int ide_iobase[2] = { 0x1f0, 0x170 };
long prom_offset, initrd_size, kernel_size;
PCIBus *pci_bus;
const sparc_def_t *def;
+ QEMUBH *bh;
linux_boot = (kernel_filename != NULL);
}
env = cpu_init();
cpu_sparc_register(env, def);
+ bh = qemu_bh_new(tick_irq, env);
+ env->tick = ptimer_init(bh);
+ ptimer_set_period(env->tick, 1ULL);
+
+ bh = qemu_bh_new(stick_irq, env);
+ env->stick = ptimer_init(bh);
+ ptimer_set_period(env->stick, 1ULL);
+
+ bh = qemu_bh_new(hstick_irq, env);
+ env->hstick = ptimer_init(bh);
+ ptimer_set_period(env->hstick, 1ULL);
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
qemu_register_reset(main_cpu_reset, env);
+ main_cpu_reset(env);
/* allocate RAM */
cpu_register_physical_memory(0, ram_size, 0);
uint64_t mgregs[8]; /* mmu general registers */
uint64_t fprs;
uint64_t tick_cmpr, stick_cmpr;
+ void *tick, *stick;
uint64_t gsr;
uint32_t gl; // UA2005
/* UA 2005 hyperprivileged registers */
uint64_t hpstate, htstate[MAXTL], hintp, htba, hver, hstick_cmpr, ssr;
+ void *hstick; // UA 2005
#endif
#if !defined(TARGET_SPARC64) && !defined(reg_T2)
target_ulong t2;
void raise_exception(int tt);
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
int is_asi);
+void do_tick_set_count(void *opaque, uint64_t count);
+uint64_t do_tick_get_count(void *opaque);
+void do_tick_set_limit(void *opaque, uint64_t limit);
#include "cpu-all.h"
void OPPROTO op_rdtick(void)
{
- T0 = 0; // XXX read cycle counter and bit 31
+ T0 = do_tick_get_count(env->tick);
}
void OPPROTO op_wrtick(void)
{
- T0 = 0; // XXX write cycle counter and bit 31
+ do_tick_set_count(env->tick, T0);
+}
+
+void OPPROTO op_wrtick_cmpr(void)
+{
+ do_tick_set_limit(env->tick, T0);
+}
+
+void OPPROTO op_rdstick(void)
+{
+ T0 = do_tick_get_count(env->stick);
+}
+
+void OPPROTO op_wrstick(void)
+{
+ do_tick_set_count(env->stick, T0);
+ do_tick_set_count(env->hstick, T0);
+}
+
+void OPPROTO op_wrstick_cmpr(void)
+{
+ do_tick_set_limit(env->stick, T0);
+}
+
+void OPPROTO op_wrhstick_cmpr(void)
+{
+ do_tick_set_limit(env->hstick, T0);
}
void OPPROTO op_rdtpc(void)
raise_exception(TT_DATA_ACCESS);
}
#endif
+
+#ifdef TARGET_SPARC64
+void do_tick_set_count(void *opaque, uint64_t count)
+{
+ ptimer_set_count(opaque, -count);
+}
+
+uint64_t do_tick_get_count(void *opaque)
+{
+ return -ptimer_get_count(opaque);
+}
+
+void do_tick_set_limit(void *opaque, uint64_t limit)
+{
+ ptimer_set_limit(opaque, -limit, 0);
+}
+#endif
gen_movl_T0_reg(rd);
break;
case 0x18: /* System tick */
- gen_op_rdtick(); // XXX
+ gen_op_rdstick();
gen_movl_T0_reg(rd);
break;
case 0x19: /* System tick compare */
if (!supervisor(dc))
goto illegal_insn;
#endif
- gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
+ gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
+ gen_op_wrtick_cmpr();
break;
case 0x18: /* System tick */
#if !defined(CONFIG_USER_ONLY)
if (!supervisor(dc))
goto illegal_insn;
#endif
- gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
+ gen_op_wrstick();
break;
case 0x19: /* System tick compare */
#if !defined(CONFIG_USER_ONLY)
if (!supervisor(dc))
goto illegal_insn;
#endif
- gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
+ gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
+ gen_op_wrstick_cmpr();
break;
case 0x10: /* Performance Control */
gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
break;
case 31: // hstick_cmpr
- gen_op_movl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
+ gen_op_movtl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
+ gen_op_wrhstick_cmpr();
break;
case 6: // hver readonly
default: