2.6.11內核CPU頻率(khz)的計算

CPU頻率的計算使用了兩個函數init_cpu_khz()和calibrate_tsc()

 

 

----------------------------arch/i386/kernel/timers/Common.c--------------------

//tsc_quotient中保存通過calibrate_tsc()計算得出(CPU單個時鐘週期的微秒數)*(2^32)的值,然後用1毫秒的微秒數即1000乘以2^32,再除以tsc_quotient,

//分子分母中的2^32抵消,最後的結果是1毫秒內的時鐘週期數,即cpu頻率的khz數

 

/* calculate cpu_khz */
void __init init_cpu_khz(void)
{
 if (cpu_has_tsc) {
  unsigned long tsc_quotient = calibrate_tsc();
  if (tsc_quotient) {
   /* report CPU clock rate in Hz.
    * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
    * clock/second. Our precision is about 100 ppm.
    */
   { unsigned long eax=0, edx=1000;
    __asm__("divl %2"
           :"=a" (cpu_khz), "=d" (edx)
                  :"r" (tsc_quotient),
                  "0" (eax), "1" (edx));
    printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
   }
  }
 }
}


 

----------------------------arch/i386/kernel/timers/Common.c--------------------

//計算並返回(CPU單個時鐘週期的微秒數)*(2^32)的值

unsigned long __init calibrate_tsc(void)
{
 mach_prepare_counter();//設置5ms的計數器

 {
  unsigned long startlow, starthigh;
  unsigned long endlow, endhigh;
  unsigned long count;

  rdtsc(startlow,starthigh);//讀取起始時間戳
  mach_countup(&count);//等待5ms
  rdtsc(endlow,endhigh);//讀取結束時間戳


  /* Error: ECTCNEVERSET */
  if (count <= 1)
   goto bad_ctc;

//計算時間戳的計數差值,即5ms中CPU收到的時鐘脈衝數

  /* 64-bit subtract - gcc just messes up with long longs */
  __asm__("subl %2,%0\n\t"
   "sbbl %3,%1"
   :"=a" (endlow), "=d" (endhigh)
   :"g" (startlow), "g" (starthigh),
    "0" (endlow), "1" (endhigh));

  /* Error: ECPUTOOFAST */
  if (endhigh)
   goto bad_ctc;

  /* Error: ECPUTOOSLOW */
  if (endlow <= CALIBRATE_TIME)
   goto bad_ctc;

 

//計算出(每個clock的微秒數)*(2^32)的值並返回

 

  __asm__("divl %2"
   :"=a" (endlow), "=d" (endhigh)
   :"r" (endlow), "0" (0), "1" (CALIBRATE_TIME));

  return endlow;
 }

 /*
  * The CTC wasn't reliable: we got a hit on the very first read,
  * or the CPU was so fast/slow that the quotient wouldn't fit in
  * 32 bits..
  */
bad_ctc:
 return 0;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章