mirror of
				https://git.proxmox.com/git/qemu
				synced 2025-10-31 07:39:44 +00:00 
			
		
		
		
	Implement Sparc64 CPU timers using ptimers
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2860 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									8d05ea8a33
								
							
						
					
					
						commit
						20c9f095c4
					
				| @ -445,7 +445,7 @@ ifeq ($(TARGET_BASE_ARCH), sparc) | ||||
| 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 | ||||
|  | ||||
							
								
								
									
										41
									
								
								hw/sun4u.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								hw/sun4u.c
									
									
									
									
									
								
							| @ -282,7 +282,35 @@ void qemu_system_powerdown(void) | ||||
| 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 }; | ||||
| @ -311,6 +339,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, | ||||
|     long prom_offset, initrd_size, kernel_size; | ||||
|     PCIBus *pci_bus; | ||||
|     const sparc_def_t *def; | ||||
|     QEMUBH *bh; | ||||
| 
 | ||||
|     linux_boot = (kernel_filename != NULL); | ||||
| 
 | ||||
| @ -324,8 +353,20 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, | ||||
|     } | ||||
|     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); | ||||
|  | ||||
| @ -226,10 +226,12 @@ typedef struct CPUSPARCState { | ||||
|     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; | ||||
| @ -292,6 +294,9 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); | ||||
| 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" | ||||
| 
 | ||||
|  | ||||
| @ -1096,12 +1096,38 @@ void OPPROTO op_wrccr(void) | ||||
| 
 | ||||
| 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) | ||||
|  | ||||
| @ -1133,3 +1133,20 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, | ||||
|     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 | ||||
|  | ||||
| @ -1202,7 +1202,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
|                     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 */ | ||||
| @ -1991,21 +1991,23 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
| 				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 */ | ||||
| @ -2155,7 +2157,8 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
|                                 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: | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 blueswir1
						blueswir1