1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #include "etherboot.h"
- #include "timer.h"
- #include "sal.h"
- #include "pal.h"
- #include "init.h"
-
- static inline unsigned long get_cycles(void)
- {
- unsigned long result;
- __asm__ __volatile__(";;mov %0=ar.itc;;" : "=r"(result));
- return result;
- }
-
- /* ------ Calibrate the TSC -------
- * Time how long it takes to excute a loop that runs in known time.
- * And find the convertion needed to get to CLOCK_TICK_RATE
- */
-
- static unsigned long calibrate_cycles(void)
- {
- unsigned long platform_ticks_per_second, drift_info;
- struct pal_freq_ratio itc_ratio;
- long result;
- result = sal_freq_base(SAL_FREQ_BASE_PLATFORM, &platform_ticks_per_second, &drift_info);
- if (result != 0) {
- printf("sal_freq_base failed: %lx\n",result);
- exit(1);
- } else {
- result = pal_freq_ratios(0,0,&itc_ratio);
- if (result != 0) {
- printf("pal_freq_ratios failed: %lx\n", result);
- exit(1);
- }
- }
- /* Avoid division by zero */
- if (itc_ratio.den == 0)
- itc_ratio.den = 1;
-
- return (platform_ticks_per_second *itc_ratio.num)/(itc_ratio.den*TICKS_PER_SEC);
- }
-
- static unsigned long clocks_per_tick;
- static void setup_timers(void)
- {
- if (!clocks_per_tick) {
- clocks_per_tick = calibrate_cycles();
- /* Display the CPU Mhz to easily test if the calibration was bad */
- printf("ITC %ld Mhz\n", (clocks_per_tick/1000 * TICKS_PER_SEC)/1000);
- }
- }
-
- unsigned long currticks(void)
- {
- return get_cycles()/clocks_per_tick;
- }
-
- static unsigned long timer_timeout;
- static int __timer_running(void)
- {
- return get_cycles() < timer_timeout;
- }
-
- void udelay(unsigned int usecs)
- {
- unsigned long now;
- now = get_cycles();
- timer_timeout = now + usecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000));
- while(__timer_running());
- }
- void ndelay(unsigned int nsecs)
- {
- unsigned long now;
- now = get_cycles();
- timer_timeout = now + nsecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000*1000));
- while(__timer_running());
- }
-
- void load_timer2(unsigned int timer2_ticks)
- {
- unsigned long now;
- unsigned long clocks;
- now = get_cycles();
- clocks = timer2_ticks * ((clocks_per_tick * TICKS_PER_SEC)/CLOCK_TICK_RATE);
- timer_timeout = now + clocks;
- }
-
- int timer2_running(void)
- {
- return __timer_running();
- }
-
- INIT_FN ( INIT_TIMERS, setup_timers, NULL, NULL );
|