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,7 +445,7 @@ ifeq ($(TARGET_BASE_ARCH), sparc)
445 ifeq ($(TARGET_ARCH), sparc64) 445 ifeq ($(TARGET_ARCH), sparc64)
446 VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o 446 VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o
447 VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o 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 else 449 else
450 VL_OBJS+= sun4m.o tcx.o pcnet.o iommu.o m48t59.o slavio_intctl.o 450 VL_OBJS+= sun4m.o tcx.o pcnet.o iommu.o m48t59.o slavio_intctl.o
451 VL_OBJS+= slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o sparc32_dma.o 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,7 +282,35 @@ void qemu_system_powerdown(void)
282 static void main_cpu_reset(void *opaque) 282 static void main_cpu_reset(void *opaque)
283 { 283 {
284 CPUState *env = opaque; 284 CPUState *env = opaque;
  285 +
285 cpu_reset(env); 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 static const int ide_iobase[2] = { 0x1f0, 0x170 }; 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,6 +339,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
311 long prom_offset, initrd_size, kernel_size; 339 long prom_offset, initrd_size, kernel_size;
312 PCIBus *pci_bus; 340 PCIBus *pci_bus;
313 const sparc_def_t *def; 341 const sparc_def_t *def;
  342 + QEMUBH *bh;
314 343
315 linux_boot = (kernel_filename != NULL); 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,8 +353,20 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
324 } 353 }
325 env = cpu_init(); 354 env = cpu_init();
326 cpu_sparc_register(env, def); 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 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); 367 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
328 qemu_register_reset(main_cpu_reset, env); 368 qemu_register_reset(main_cpu_reset, env);
  369 + main_cpu_reset(env);
329 370
330 /* allocate RAM */ 371 /* allocate RAM */
331 cpu_register_physical_memory(0, ram_size, 0); 372 cpu_register_physical_memory(0, ram_size, 0);
target-sparc/cpu.h
@@ -226,10 +226,12 @@ typedef struct CPUSPARCState { @@ -226,10 +226,12 @@ typedef struct CPUSPARCState {
226 uint64_t mgregs[8]; /* mmu general registers */ 226 uint64_t mgregs[8]; /* mmu general registers */
227 uint64_t fprs; 227 uint64_t fprs;
228 uint64_t tick_cmpr, stick_cmpr; 228 uint64_t tick_cmpr, stick_cmpr;
  229 + void *tick, *stick;
229 uint64_t gsr; 230 uint64_t gsr;
230 uint32_t gl; // UA2005 231 uint32_t gl; // UA2005
231 /* UA 2005 hyperprivileged registers */ 232 /* UA 2005 hyperprivileged registers */
232 uint64_t hpstate, htstate[MAXTL], hintp, htba, hver, hstick_cmpr, ssr; 233 uint64_t hpstate, htstate[MAXTL], hintp, htba, hver, hstick_cmpr, ssr;
  234 + void *hstick; // UA 2005
233 #endif 235 #endif
234 #if !defined(TARGET_SPARC64) && !defined(reg_T2) 236 #if !defined(TARGET_SPARC64) && !defined(reg_T2)
235 target_ulong t2; 237 target_ulong t2;
@@ -292,6 +294,9 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); @@ -292,6 +294,9 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
292 void raise_exception(int tt); 294 void raise_exception(int tt);
293 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, 295 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
294 int is_asi); 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 #include "cpu-all.h" 301 #include "cpu-all.h"
297 302
target-sparc/op.c
@@ -1096,12 +1096,38 @@ void OPPROTO op_wrccr(void) @@ -1096,12 +1096,38 @@ void OPPROTO op_wrccr(void)
1096 1096
1097 void OPPROTO op_rdtick(void) 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 void OPPROTO op_wrtick(void) 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 void OPPROTO op_rdtpc(void) 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,3 +1133,20 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
1133 raise_exception(TT_DATA_ACCESS); 1133 raise_exception(TT_DATA_ACCESS);
1134 } 1134 }
1135 #endif 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,7 +1202,7 @@ static void disas_sparc_insn(DisasContext * dc)
1202 gen_movl_T0_reg(rd); 1202 gen_movl_T0_reg(rd);
1203 break; 1203 break;
1204 case 0x18: /* System tick */ 1204 case 0x18: /* System tick */
1205 - gen_op_rdtick(); // XXX 1205 + gen_op_rdstick();
1206 gen_movl_T0_reg(rd); 1206 gen_movl_T0_reg(rd);
1207 break; 1207 break;
1208 case 0x19: /* System tick compare */ 1208 case 0x19: /* System tick compare */
@@ -1991,21 +1991,23 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1991,21 +1991,23 @@ static void disas_sparc_insn(DisasContext * dc)
1991 if (!supervisor(dc)) 1991 if (!supervisor(dc))
1992 goto illegal_insn; 1992 goto illegal_insn;
1993 #endif 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 break; 1996 break;
1996 case 0x18: /* System tick */ 1997 case 0x18: /* System tick */
1997 #if !defined(CONFIG_USER_ONLY) 1998 #if !defined(CONFIG_USER_ONLY)
1998 if (!supervisor(dc)) 1999 if (!supervisor(dc))
1999 goto illegal_insn; 2000 goto illegal_insn;
2000 #endif 2001 #endif
2001 - gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr)); 2002 + gen_op_wrstick();
2002 break; 2003 break;
2003 case 0x19: /* System tick compare */ 2004 case 0x19: /* System tick compare */
2004 #if !defined(CONFIG_USER_ONLY) 2005 #if !defined(CONFIG_USER_ONLY)
2005 if (!supervisor(dc)) 2006 if (!supervisor(dc))
2006 goto illegal_insn; 2007 goto illegal_insn;
2007 #endif 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 break; 2011 break;
2010 2012
2011 case 0x10: /* Performance Control */ 2013 case 0x10: /* Performance Control */
@@ -2155,7 +2157,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2155,7 +2157,8 @@ static void disas_sparc_insn(DisasContext * dc)
2155 gen_op_movl_env_T0(offsetof(CPUSPARCState, htba)); 2157 gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
2156 break; 2158 break;
2157 case 31: // hstick_cmpr 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 break; 2162 break;
2160 case 6: // hver readonly 2163 case 6: // hver readonly
2161 default: 2164 default: