| #include <arch/time.h> | 
 | #include <ros/common.h> | 
 | #include <trap.h> | 
 | #include <arch/arch.h> | 
 | #include <stdio.h> | 
 | #include <assert.h> | 
 | #include <ros/procinfo.h> | 
 |  | 
 | void | 
 | timer_init(void) | 
 | { | 
 | 	__proc_global_info.tsc_freq = TSC_HZ; | 
 | 	cprintf("TSC Frequency: %llu\n", __proc_global_info.tsc_freq); | 
 | } | 
 |  | 
 | void | 
 | set_core_timer(uint32_t usec, bool periodic) | 
 | { | 
 | 	// we could implement periodic timers using one-shot timers, | 
 | 	// but for now we only support one-shot | 
 | 	assert(!periodic); | 
 |  | 
 | 	if (usec) | 
 | 	{ | 
 | 		uint32_t clocks =  (uint64_t)usec*TSC_HZ/1000000; | 
 |  | 
 | 		int8_t irq_state = 0; | 
 | 		disable_irqsave(&irq_state); | 
 |  | 
 | 		mtpcr(PCR_COUNT, 0); | 
 | 		mtpcr(PCR_COMPARE, clocks); | 
 | 		mtpcr(PCR_SR, mfpcr(PCR_SR) | (1 << (IRQ_TIMER+SR_IM_SHIFT))); | 
 |  | 
 | 		enable_irqsave(&irq_state); | 
 | 	} | 
 | 	else | 
 | 	{ | 
 | 		mtpcr(PCR_SR, mfpcr(PCR_SR) & ~(1 << (IRQ_TIMER+SR_IM_SHIFT))); | 
 | 	} | 
 | } | 
 |  | 
 | void | 
 | udelay(uint64_t usec) | 
 | { | 
 | 	if (__proc_global_info.tsc_freq != 0) | 
 | 	{ | 
 | 		uint64_t start, end, now; | 
 |  | 
 | 		start = read_tsc(); | 
 | 		end = start + (__proc_global_info.tsc_freq * usec) / 1000000; | 
 |  | 
 | 		do | 
 | 		{ | 
 | 			cpu_relax(); | 
 | 			now = read_tsc(); | 
 | 		} while (now < end || (now > start && end < start)); | 
 | 	} | 
 | 	else panic("udelay() was called before timer_init(), moron!"); | 
 | } | 
 |  | 
 | uint64_t read_persistent_clock(void) | 
 | { | 
 | 	return 1242129600 * 1000000000UL; /* nanwan's birthday */ | 
 | } |