Commit 20c9f095c4536e64e60432a5c72fce38e8306cbb

Authored by blueswir1
1 parent 8d05ea8a

Implement Sparc64 CPU timers using ptimers


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2860 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -445,7 +445,7 @@ ifeq ($(TARGET_BASE_ARCH), sparc)
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
... ...
hw/sun4u.c
... ... @@ -282,7 +282,35 @@ void qemu_system_powerdown(void)
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,6 +339,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
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,8 +353,20 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
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);
... ...
target-sparc/cpu.h
... ... @@ -226,10 +226,12 @@ typedef struct CPUSPARCState {
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,6 +294,9 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
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  
... ...
target-sparc/op.c
... ... @@ -1096,12 +1096,38 @@ void OPPROTO op_wrccr(void)
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)
... ...
target-sparc/op_helper.c
... ... @@ -1133,3 +1133,20 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
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
... ...
target-sparc/translate.c
... ... @@ -1202,7 +1202,7 @@ static void disas_sparc_insn(DisasContext * dc)
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,21 +1991,23 @@ static void disas_sparc_insn(DisasContext * dc)
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,7 +2157,8 @@ static void disas_sparc_insn(DisasContext * dc)
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:
... ...