Revision 20c9f095

b/Makefile.target
445 445
ifeq ($(TARGET_ARCH), sparc64)
446 446
VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o
447 447
VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
448
VL_OBJS+= cirrus_vga.o parallel.o
448
VL_OBJS+= cirrus_vga.o parallel.o ptimer.o
449 449
else
450 450
VL_OBJS+= sun4m.o tcx.o pcnet.o iommu.o m48t59.o slavio_intctl.o
451 451
VL_OBJS+= slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o sparc32_dma.o
b/hw/sun4u.c
282 282
static void main_cpu_reset(void *opaque)
283 283
{
284 284
    CPUState *env = opaque;
285

  
285 286
    cpu_reset(env);
287
    ptimer_set_limit(env->tick, 0x7fffffffffffffffULL, 1);
288
    ptimer_run(env->tick, 0);
289
    ptimer_set_limit(env->stick, 0x7fffffffffffffffULL, 1);
290
    ptimer_run(env->stick, 0);
291
    ptimer_set_limit(env->hstick, 0x7fffffffffffffffULL, 1);
292
    ptimer_run(env->hstick, 0);
293
}
294

  
295
void tick_irq(void *opaque)
296
{
297
    CPUState *env = opaque;
298

  
299
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
300
}
301

  
302
void stick_irq(void *opaque)
303
{
304
    CPUState *env = opaque;
305

  
306
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
307
}
308

  
309
void hstick_irq(void *opaque)
310
{
311
    CPUState *env = opaque;
312

  
313
    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
286 314
}
287 315

  
288 316
static const int ide_iobase[2] = { 0x1f0, 0x170 };
......
311 339
    long prom_offset, initrd_size, kernel_size;
312 340
    PCIBus *pci_bus;
313 341
    const sparc_def_t *def;
342
    QEMUBH *bh;
314 343

  
315 344
    linux_boot = (kernel_filename != NULL);
316 345

  
......
324 353
    }
325 354
    env = cpu_init();
326 355
    cpu_sparc_register(env, def);
356
    bh = qemu_bh_new(tick_irq, env);
357
    env->tick = ptimer_init(bh);
358
    ptimer_set_period(env->tick, 1ULL);
359

  
360
    bh = qemu_bh_new(stick_irq, env);
361
    env->stick = ptimer_init(bh);
362
    ptimer_set_period(env->stick, 1ULL);
363

  
364
    bh = qemu_bh_new(hstick_irq, env);
365
    env->hstick = ptimer_init(bh);
366
    ptimer_set_period(env->hstick, 1ULL);
327 367
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
328 368
    qemu_register_reset(main_cpu_reset, env);
369
    main_cpu_reset(env);
329 370

  
330 371
    /* allocate RAM */
331 372
    cpu_register_physical_memory(0, ram_size, 0);
b/target-sparc/cpu.h
226 226
    uint64_t mgregs[8]; /* mmu general registers */
227 227
    uint64_t fprs;
228 228
    uint64_t tick_cmpr, stick_cmpr;
229
    void *tick, *stick;
229 230
    uint64_t gsr;
230 231
    uint32_t gl; // UA2005
231 232
    /* UA 2005 hyperprivileged registers */
232 233
    uint64_t hpstate, htstate[MAXTL], hintp, htba, hver, hstick_cmpr, ssr;
234
    void *hstick; // UA 2005
233 235
#endif
234 236
#if !defined(TARGET_SPARC64) && !defined(reg_T2)
235 237
    target_ulong t2;
......
292 294
void raise_exception(int tt);
293 295
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
294 296
                          int is_asi);
297
void do_tick_set_count(void *opaque, uint64_t count);
298
uint64_t do_tick_get_count(void *opaque);
299
void do_tick_set_limit(void *opaque, uint64_t limit);
295 300

  
296 301
#include "cpu-all.h"
297 302

  
b/target-sparc/op.c
1096 1096

  
1097 1097
void OPPROTO op_rdtick(void)
1098 1098
{
1099
    T0 = 0; // XXX read cycle counter and bit 31
1099
    T0 = do_tick_get_count(env->tick);
1100 1100
}
1101 1101

  
1102 1102
void OPPROTO op_wrtick(void)
1103 1103
{
1104
    T0 = 0; // XXX write cycle counter and bit 31
1104
    do_tick_set_count(env->tick, T0);
1105
}
1106

  
1107
void OPPROTO op_wrtick_cmpr(void)
1108
{
1109
    do_tick_set_limit(env->tick, T0);
1110
}
1111

  
1112
void OPPROTO op_rdstick(void)
1113
{
1114
    T0 = do_tick_get_count(env->stick);
1115
}
1116

  
1117
void OPPROTO op_wrstick(void)
1118
{
1119
    do_tick_set_count(env->stick, T0);
1120
    do_tick_set_count(env->hstick, T0);
1121
}
1122

  
1123
void OPPROTO op_wrstick_cmpr(void)
1124
{
1125
    do_tick_set_limit(env->stick, T0);
1126
}
1127

  
1128
void OPPROTO op_wrhstick_cmpr(void)
1129
{
1130
    do_tick_set_limit(env->hstick, T0);
1105 1131
}
1106 1132

  
1107 1133
void OPPROTO op_rdtpc(void)
b/target-sparc/op_helper.c
1133 1133
    raise_exception(TT_DATA_ACCESS);
1134 1134
}
1135 1135
#endif
1136

  
1137
#ifdef TARGET_SPARC64
1138
void do_tick_set_count(void *opaque, uint64_t count)
1139
{
1140
    ptimer_set_count(opaque, -count);
1141
}
1142

  
1143
uint64_t do_tick_get_count(void *opaque)
1144
{
1145
    return -ptimer_get_count(opaque);
1146
}
1147

  
1148
void do_tick_set_limit(void *opaque, uint64_t limit)
1149
{
1150
    ptimer_set_limit(opaque, -limit, 0);
1151
}
1152
#endif
b/target-sparc/translate.c
1202 1202
                    gen_movl_T0_reg(rd);
1203 1203
                    break;
1204 1204
		case 0x18: /* System tick */
1205
                    gen_op_rdtick(); // XXX
1205
                    gen_op_rdstick();
1206 1206
                    gen_movl_T0_reg(rd);
1207 1207
                    break;
1208 1208
		case 0x19: /* System tick compare */
......
1991 1991
				if (!supervisor(dc))
1992 1992
				    goto illegal_insn;
1993 1993
#endif
1994
				gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
1994
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
1995
                                gen_op_wrtick_cmpr();
1995 1996
				break;
1996 1997
			    case 0x18: /* System tick */
1997 1998
#if !defined(CONFIG_USER_ONLY)
1998 1999
				if (!supervisor(dc))
1999 2000
				    goto illegal_insn;
2000 2001
#endif
2001
				gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
2002
                                gen_op_wrstick();
2002 2003
				break;
2003 2004
			    case 0x19: /* System tick compare */
2004 2005
#if !defined(CONFIG_USER_ONLY)
2005 2006
				if (!supervisor(dc))
2006 2007
				    goto illegal_insn;
2007 2008
#endif
2008
				gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
2009
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
2010
                                gen_op_wrstick_cmpr();
2009 2011
				break;
2010 2012

  
2011 2013
			    case 0x10: /* Performance Control */
......
2155 2157
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
2156 2158
                                break;
2157 2159
                            case 31: // hstick_cmpr
2158
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
2160
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
2161
                                gen_op_wrhstick_cmpr();
2159 2162
                                break;
2160 2163
                            case 6: // hver readonly
2161 2164
                            default:

Also available in: Unified diff