// PE_Determine_Clock_Speeds is called by the via driver in IOKit
// It uses the numbers generated by pe_do_clock_test and reports
// the cleaned up values to the rest of the OS.
void PE_Determine_Clock_Speeds(unsigned int via_addr, int num_speeds,
			       unsigned long *speed_list)
{
  boolean_t          oldLevel;
  unsigned long      tmp_bus_speed, tmp_cpu_speed;
  unsigned long long tmp;
  
  oldLevel = ml_set_interrupts_enabled(FALSE);
  pe_do_clock_test(via_addr, num_speeds, speed_list);
  ml_set_interrupts_enabled(oldLevel);
  
  tmp_bus_speed = bus_freq_num / bus_freq_den;
  tmp = ((unsigned long long)bus_freq_num * cpu_pll) / (bus_freq_den * 2);
  tmp_cpu_speed = (unsigned long)tmp;
  
  // Report the bus clock rate as is.
  gPEClockFrequencyInfo.bus_clock_rate_num = bus_freq_num;
  gPEClockFrequencyInfo.bus_clock_rate_den = bus_freq_den;
  
  // pll multipliers are in halfs so set the denominator to 2.
  gPEClockFrequencyInfo.bus_to_cpu_rate_num = cpu_pll;
  gPEClockFrequencyInfo.bus_to_cpu_rate_den = 2;
  
  // The decrementer rate is one fourth the bus rate.
  gPEClockFrequencyInfo.bus_to_dec_rate_num = 1;
  gPEClockFrequencyInfo.bus_to_dec_rate_den = 4;
  
  // Assume that the timebase frequency is derived from the bus clock.
  gPEClockFrequencyInfo.timebase_frequency_num = bus_freq_num;
  gPEClockFrequencyInfo.timebase_frequency_den = bus_freq_den * 4;
  
  // Set the truncated numbers in gPEClockFrequencyInfo.
  gPEClockFrequencyInfo.bus_clock_rate_hz = tmp_bus_speed;
  gPEClockFrequencyInfo.cpu_clock_rate_hz = tmp_cpu_speed;
  gPEClockFrequencyInfo.dec_clock_rate_hz = tmp_bus_speed / 4;
  gPEClockFrequencyInfo.timebase_frequency_hz = tmp_bus_speed / 4;
  
  gPEClockFrequencyInfo.bus_frequency_hz = tmp_bus_speed;
  gPEClockFrequencyInfo.bus_frequency_min_hz = tmp_bus_speed;
  gPEClockFrequencyInfo.bus_frequency_max_hz = tmp_bus_speed;
  gPEClockFrequencyInfo.cpu_frequency_hz = tmp_cpu_speed;
  gPEClockFrequencyInfo.cpu_frequency_min_hz = tmp_cpu_speed;
  gPEClockFrequencyInfo.cpu_frequency_max_hz = tmp_cpu_speed;
  
  PE_call_timebase_callback();
}
Beispiel #2
0
void PE_register_timebase_callback(timebase_callback_func callback)
{
    gTimebaseCallback = callback;
  
    PE_call_timebase_callback();
}