Main Page | Directories | File List | Globals

bogo.c

Go to the documentation of this file.
00001 /*
00002  * kernel_arch/i386/kernel/cpu/bogo.c
00003  *
00004  * Copyright (c) 2003-2004 Lukasz Dembinski <dembol@nasa.com.pl>
00005  * All Rights Reserved
00006  * 
00007  * Date:        2004/01
00008  * Author:      Lukasz Dembinski
00009  * Info:        bogo.c core file
00010  * Contact:     mailto: <dembol@nasa.com.pl>
00011  *
00012  */
00013 
00014 #include <agnix/agnix.h>
00015 #include <agnix/console.h>
00016 #include <agnix/counters.h>
00017 #include <agnix/timer.h>
00018 #include <agnix/adi/adi.h>
00019 #include <asm/cpu_ops.h>
00020 
00021 #define MOD_NAME        "BOGO: "
00022 
00023 extern struct chip_s cpu_chip;
00024 extern int counter_jiffies_desc;
00025 
00026 unsigned long loops_per_jiffy = (1<<12);
00027 
00028 #define LPS_PREC 8
00029 
00030 void __tsc_delay(unsigned long loops)
00031 {
00032     u32 tsc_s[2];
00033     u32 tsc_c[2];
00034 
00035     rdtsc(tsc_s[0], tsc_s[1]);
00036     
00037     do {
00038         rdtsc(tsc_c[0], tsc_c[1]);
00039     } while ((tsc_c[0] - tsc_s[0]) < loops);
00040 }
00041 
00042 void __normal_delay(unsigned long loops)
00043 {
00044     __asm__ __volatile__ (
00045     "jmp 1f\n\t"
00046     ".align 16\n\t"
00047     "1: jmp 2f\n\t"
00048     ".align 16\n\t"
00049     "2: decl %%eax\t\n"
00050     "jns 2b"
00051     :
00052     :"a"(loops)
00053     );
00054 }
00055 
00056 void __delay(unsigned long loops)
00057 {
00058     if (!(read_cr4() & CPU_CR4_TSD))
00059         __tsc_delay(loops);
00060     else
00061         __normal_delay(loops);
00062 }
00063 
00064 void __init _cpu_calibrate_delay(void (*delay_routine)(unsigned long), const char *text)
00065 {
00066     struct cpu_parm_s *cpu_parm = cpu_parm(&cpu_chip);
00067     u32 ticks, ticks_cur, loopbit;
00068     u32 jiffies_latch[2];
00069     int lps_precision = LPS_PREC;
00070 
00071     loops_per_jiffy = (1<<12);
00072 
00073     printk("CPU_0: Calibrating delay loop...");
00074     while (loops_per_jiffy <<= 1) {
00075         /* wait for "start" of clock tick */
00076         counter_read(counter_jiffies_desc, jiffies_latch);
00077         ticks = jiffies_latch[0];
00078 
00079         do {
00080             counter_read(counter_jiffies_desc, jiffies_latch);
00081             ticks_cur = jiffies_latch[0];
00082         } while(ticks_cur == ticks);
00083                         
00084         counter_read(counter_jiffies_desc, jiffies_latch);
00085         ticks = jiffies_latch[0];
00086         delay_routine(loops_per_jiffy);
00087 
00088         counter_read(counter_jiffies_desc, jiffies_latch);
00089         ticks = jiffies_latch[0] - ticks;
00090         if (ticks)
00091                 break;
00092     }
00093 
00094     loops_per_jiffy >>= 1;
00095     loopbit = loops_per_jiffy;
00096     while ( lps_precision-- && (loopbit >>= 1) ) {
00097         loops_per_jiffy |= loopbit;
00098         
00099         counter_read(counter_jiffies_desc, jiffies_latch);
00100         ticks = jiffies_latch[0];
00101 
00102         do {
00103             counter_read(counter_jiffies_desc, jiffies_latch);
00104             ticks_cur = jiffies_latch[0];
00105         } while(ticks_cur == ticks);
00106 
00107         counter_read(counter_jiffies_desc, jiffies_latch);
00108         ticks = jiffies_latch[0];
00109         delay_routine(loops_per_jiffy);
00110         
00111         counter_read(counter_jiffies_desc, jiffies_latch);
00112         if (jiffies_latch[0] != ticks)  /* longer than 1 tick */
00113                 loops_per_jiffy &= ~loopbit;
00114     }
00115 
00116     cpu_parm->cpu_bogomips = loops_per_jiffy;
00117 
00118     printk(" %d.%02d BogoMIPS (%s)\n", loops_per_jiffy/(500000/TIMER_HZ),
00119             (loops_per_jiffy/(5000/TIMER_HZ)) % 100, text);
00120 }
00121 
00122 void __init cpu_calibrate_delay(void)
00123 {
00124     _cpu_calibrate_delay(__tsc_delay, "fake");
00125     _cpu_calibrate_delay(__normal_delay, "true");
00126 }
Dokumentacje wygenerowano programem Doxygen 1.4.2 dla projektu Agnix