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