Пример #1
0
        internal void CalibrateTimerWithHpet(Hpet hpet, ulong tsc_delay)
        {
            /* set up the hpet */
            ulong init_hpet = 0x0;

            hpet.SetMainCounter(init_hpet);
            init_hpet = hpet.ReadMainCounter();

            /* set up the lapic timer as masked, one shot, divisor of 1 */
            uint lapic_val = 0xffffffff;
            //uint lapic_div = 11; /* bits 0, 1 and 3 set the divisor */
            uint lapic_reg = 0x00010000; /* masked, one-shot, vector 0 */

            WriteConfDword(LVT_timer_offset, lapic_reg);
            //WriteConfDword(Divide_Conf_offset, lapic_div);
            WriteConfDword(Initial_Count_offset, lapic_val);

            /* start the hpet */
            hpet.EnableMainCounter();

            /* perform a delay using the tsc */
            ulong init_tsc = libsupcs.x86_64.Cpu.Tsc;
            ulong cur_tsc  = init_tsc;

            while (cur_tsc < (init_tsc + tsc_delay))
            {
                cur_tsc = libsupcs.x86_64.Cpu.Tsc;
            }

            /* get the final values of the timers */
            ulong lapic_final_val = ReadConfDword(Current_Count_offset);

            hpet.DisableMainCounter();
            ulong hpet_final_val = hpet.ReadMainCounter();

            ulong delta_hpet  = hpet_final_val - init_hpet;
            ulong delta_lapic = lapic_val - lapic_final_val;

            /* At this point:
             *
             * actual time delay = delta_hpet / hpet_frequency _or_ delta_hpet * hpet_cycle_length
             * bus_cycles = delta_lapic * lapic_divisor
             *
             * bus_frequency = bus_cycles / actual time delay
             */

            double actual_time_delay = Convert.ToDouble((long)delta_hpet) * hpet.MainCounterCycleLength;
            ulong  bus_cycles        = delta_lapic * LApicTimerDivisor;
            double bus_frequency     = Convert.ToDouble((long)bus_cycles) / actual_time_delay;
            double bus_frequency_mhz = bus_frequency * 0.000001;

            Program.arch.DebugOutput.Write("Bus frequency " + bus_frequency_mhz.ToString() + " Mhz\n");

            Formatter.Write("  delta_tsc: ", Program.arch.DebugOutput);
            Formatter.Write(cur_tsc - init_tsc, "X", Program.arch.DebugOutput);
            Formatter.Write("  init_hpet: ", Program.arch.DebugOutput);
            Formatter.Write(init_hpet, "X", Program.arch.DebugOutput);
            Formatter.Write("  final_hpet: ", Program.arch.DebugOutput);
            Formatter.Write(hpet_final_val, "X", Program.arch.DebugOutput);
            Formatter.Write("  delta_hpet: ", Program.arch.DebugOutput);
            Formatter.Write(delta_hpet, "d", Program.arch.DebugOutput);
            Formatter.Write("  delta_lapic: ", Program.arch.DebugOutput);
            Formatter.Write(delta_lapic, "d", Program.arch.DebugOutput);
            Formatter.WriteLine(Program.arch.DebugOutput);

            lapic_base_freq = bus_frequency;
            calibrated      = true;
        }
Пример #2
0
 internal void CalibrateTimerWithHpet(Hpet hpet)
 {
     CalibrateTimerWithHpet(hpet, 0x1000000);
 }