// 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(); }
void PE_register_timebase_callback(timebase_callback_func callback) { gTimebaseCallback = callback; PE_call_timebase_callback(); }