[BACK]Return to lapic.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / x86 / x86

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/x86/x86/lapic.c between version 1.20 and 1.20.22.5

version 1.20, 2007/02/09 21:55:14 version 1.20.22.5, 2007/09/06 00:55:03
Line 67  __KERNEL_RCSID(0, "$NetBSD$");
Line 67  __KERNEL_RCSID(0, "$NetBSD$");
 #include <machine/pcb.h>  #include <machine/pcb.h>
 #include <machine/specialreg.h>  #include <machine/specialreg.h>
 #include <machine/segments.h>  #include <machine/segments.h>
 #ifdef _HAVE_TIMECOUNTER  
 #include <x86/x86/tsc.h>  #include <x86/x86/tsc.h>
 #endif  
   
 #include <machine/apicvar.h>  #include <machine/apicvar.h>
 #include <machine/i82489reg.h>  #include <machine/i82489reg.h>
Line 77  __KERNEL_RCSID(0, "$NetBSD$");
Line 75  __KERNEL_RCSID(0, "$NetBSD$");
   
 void            lapic_delay(int);  void            lapic_delay(int);
 void            lapic_microtime(struct timeval *);  void            lapic_microtime(struct timeval *);
 static u_int32_t lapic_gettick(void);  static uint32_t lapic_gettick(void);
 void            lapic_clockintr(void *, struct intrframe *);  void            lapic_clockintr(void *, struct intrframe *);
 static void     lapic_map(paddr_t);  static void     lapic_map(paddr_t);
   
Line 85  static void lapic_hwmask(struct pic *, i
Line 83  static void lapic_hwmask(struct pic *, i
 static void lapic_hwunmask(struct pic *, int);  static void lapic_hwunmask(struct pic *, int);
 static void lapic_setup(struct pic *, struct cpu_info *, int, int, int);  static void lapic_setup(struct pic *, struct cpu_info *, int, int, int);
   
   static const struct lapic_state {
           uint32_t        id,
                           tpri,
                           ldr,
                           dfr,
                           svr;
   } lapic_state;
   
 extern char idt_allocmap[];  extern char idt_allocmap[];
   
 struct pic local_pic = {  struct pic local_pic = {
Line 100  struct pic local_pic = {
Line 106  struct pic local_pic = {
 };  };
   
 static void  static void
 lapic_map(lapic_base)  lapic_map(paddr_t lapic_base)
         paddr_t lapic_base;  
 {  {
         int s;          int s;
         pt_entry_t *pte;          pt_entry_t *pte;
Line 135  lapic_map(lapic_base)
Line 140  lapic_map(lapic_base)
  * enable local apic   * enable local apic
  */   */
 void  void
 lapic_enable()  lapic_enable(void)
 {  {
         i82489_writereg(LAPIC_SVR, LAPIC_SVR_ENABLE | LAPIC_SPURIOUS_VECTOR);          i82489_writereg(LAPIC_SVR, LAPIC_SVR_ENABLE | LAPIC_SPURIOUS_VECTOR);
 }  }
   
 void  void
 lapic_set_lvt()  lapic_suspend(void)
   {
   }
   
   void
   lapic_set_lvt(void)
 {  {
         struct cpu_info *ci = curcpu();          struct cpu_info *ci = curcpu();
         int i;          int i;
Line 203  lapic_set_lvt()
Line 213  lapic_set_lvt()
  * Initialize fixed idt vectors for use by local apic.   * Initialize fixed idt vectors for use by local apic.
  */   */
 void  void
 lapic_boot_init(lapic_base)  lapic_boot_init(paddr_t lapic_base)
         paddr_t lapic_base;  
 {  {
         lapic_map(lapic_base);          lapic_map(lapic_base);
   
 #ifdef MULTIPROCESSOR  #ifdef MULTIPROCESSOR
         idt_allocmap[LAPIC_IPI_VECTOR] = 1;          idt_allocmap[LAPIC_IPI_VECTOR] = 1;
         idt_vec_set(LAPIC_IPI_VECTOR, Xintr_lapic_ipi);          idt_vec_set(LAPIC_IPI_VECTOR, Xintr_lapic_ipi);
           idt_allocmap[LAPIC_TLB_MCAST_VECTOR] = 1;
           idt_vec_set(LAPIC_TLB_MCAST_VECTOR, Xintr_lapic_tlb_mcast);
           idt_allocmap[LAPIC_TLB_BCAST_VECTOR] = 1;
           idt_vec_set(LAPIC_TLB_BCAST_VECTOR, Xintr_lapic_tlb_bcast);
 #endif  #endif
         idt_allocmap[LAPIC_SPURIOUS_VECTOR] = 1;          idt_allocmap[LAPIC_SPURIOUS_VECTOR] = 1;
         idt_vec_set(LAPIC_SPURIOUS_VECTOR, Xintrspurious);          idt_vec_set(LAPIC_SPURIOUS_VECTOR, Xintrspurious);
Line 219  lapic_boot_init(lapic_base)
Line 232  lapic_boot_init(lapic_base)
         idt_vec_set(LAPIC_TIMER_VECTOR, Xintr_lapic_ltimer);          idt_vec_set(LAPIC_TIMER_VECTOR, Xintr_lapic_ltimer);
 }  }
   
 static inline u_int32_t lapic_gettick()  static uint32_t
   lapic_gettick(void)
 {  {
         return i82489_readreg(LAPIC_CCR_TIMER);          return i82489_readreg(LAPIC_CCR_TIMER);
 }  }
Line 227  static inline u_int32_t lapic_gettick()
Line 241  static inline u_int32_t lapic_gettick()
 #include <sys/kernel.h>         /* for hz */  #include <sys/kernel.h>         /* for hz */
   
 int lapic_timer = 0;  int lapic_timer = 0;
 u_int32_t lapic_tval;  uint32_t lapic_tval;
   
 /*  /*
  * this gets us up to a 4GHz busclock....   * this gets us up to a 4GHz busclock....
  */   */
 u_int32_t lapic_per_second;  uint32_t lapic_per_second;
 u_int32_t lapic_frac_usec_per_cycle;  uint32_t lapic_frac_usec_per_cycle;
 u_int64_t lapic_frac_cycle_per_usec;  uint64_t lapic_frac_cycle_per_usec;
 u_int32_t lapic_delaytab[26];  uint32_t lapic_delaytab[26];
   
   extern u_int i8254_get_timecount(struct timecounter *);
   
 void  void
 lapic_clockintr(void *arg, struct intrframe *frame)  lapic_clockintr(void *arg, struct intrframe *frame)
 {  {
 #if defined(I586_CPU) || defined(I686_CPU) || defined(__x86_64__)  #if defined(I586_CPU) || defined(I686_CPU) || defined(__x86_64__)
 #ifndef __HAVE_TIMECOUNTER  #if defined(TIMECOUNTER_DEBUG)
         static int microset_iter; /* call cc_microset once/sec */  
 #endif /* __HAVE_TIMECOUNTER */  
 #if defined(TIMECOUNTER_DEBUG) && defined(__HAVE_TIMECOUNTER)  
         static u_int last_count[X86_MAXPROCS],          static u_int last_count[X86_MAXPROCS],
                      last_delta[X86_MAXPROCS],                       last_delta[X86_MAXPROCS],
                      last_tsc[X86_MAXPROCS],                       last_tsc[X86_MAXPROCS],
                      last_tscdelta[X86_MAXPROCS],                       last_tscdelta[X86_MAXPROCS],
                      last_factor[X86_MAXPROCS];                       last_factor[X86_MAXPROCS];
 #endif /* TIMECOUNTER_DEBUG && __HAVE_TIMECOUNTER */  #endif /* TIMECOUNTER_DEBUG */
         struct cpu_info *ci = curcpu();          struct cpu_info *ci = curcpu();
   
         ci->ci_isources[LIR_TIMER]->is_evcnt.ev_count++;          ci->ci_isources[LIR_TIMER]->is_evcnt.ev_count++;
   
 #if defined(TIMECOUNTER_DEBUG) && defined(__HAVE_TIMECOUNTER)  #if defined(TIMECOUNTER_DEBUG)
         {          {
                 int cid = ci->ci_cpuid;                  int cid = ci->ci_cpuid;
                 extern u_int i8254_get_timecount(struct timecounter *);  
                 u_int c_count = i8254_get_timecount(NULL);                  u_int c_count = i8254_get_timecount(NULL);
                 u_int c_tsc = cpu_counter32();                  u_int c_tsc = cpu_counter32();
                 u_int delta, ddelta, tsc_delta, factor = 0;                  u_int delta, ddelta, tsc_delta, factor = 0;
Line 314  lapic_clockintr(void *arg, struct intrfr
Line 326  lapic_clockintr(void *arg, struct intrfr
                 last_tsc[cid]      = c_tsc;                  last_tsc[cid]      = c_tsc;
                 last_tscdelta[cid] = tsc_delta;                  last_tscdelta[cid] = tsc_delta;
         }          }
 #endif /* TIMECOUNTER_DEBUG && __HAVE_TIMECOUNTER */  #endif /* TIMECOUNTER_DEBUG */
   
 #ifndef __HAVE_TIMECOUNTER  
         /*  
          * If we have a cycle counter, do the microset thing.  
          */  
         if (ci->ci_feature_flags & CPUID_TSC) {  
                 if (CPU_IS_PRIMARY(ci) && (microset_iter--) == 0) {  
                         microset_iter = hz - 1;  
                         cc_microset_time = time;  
 #if defined(MULTIPROCESSOR)  
                         x86_broadcast_ipi(X86_IPI_MICROSET);  
 #endif  
                         cc_microset(ci);  
                 }  
         }  
 #endif /* !__HAVE_TIMECOUNTER */  
 #endif /* I586_CPU || I686_CPU || __x86_64__ */  #endif /* I586_CPU || I686_CPU || __x86_64__ */
   
         hardclock((struct clockframe *)frame);          hardclock((struct clockframe *)frame);
 }  }
   
 #if !defined(__HAVE_TIMECOUNTER) && defined(NTP)  
 extern int fixtick;  
 #endif /* !__HAVE_TIMECOUNTER && NTP */  
   
 void  void
 lapic_initclocks()  lapic_initclocks(void)
 {  {
   
 #if !defined(__HAVE_TIMECOUNTER) && defined(NTP)  
         /*  
          * we'll actually get (lapic_per_second/lapic_tval) interrupts/sec.  
          */  
         fixtick = 1000000 -  
             ((int64_t)tick * lapic_per_second + lapic_tval / 2) / lapic_tval;  
 #endif /* !__HAVE_TIMECOUNTER && NTP */  
   
         /*          /*
          * Start local apic countdown timer running, in repeated mode.           * Start local apic countdown timer running, in repeated mode.
          *           *
Line 381  extern void (*initclock_func)(void); /* 
Line 365  extern void (*initclock_func)(void); /* 
  * We're actually using the IRQ0 timer.  Hmm.   * We're actually using the IRQ0 timer.  Hmm.
  */   */
 void  void
 lapic_calibrate_timer(ci)  lapic_calibrate_timer(struct cpu_info *ci)
         struct cpu_info *ci;  
 {  {
         unsigned int starttick, tick1, tick2, endtick;          unsigned int starttick, tick1, tick2, endtick;
         unsigned int startapic, apic1, apic2, endapic;          unsigned int startapic, apic1, apic2, endapic;
         u_int64_t dtick, dapic, tmp;          uint64_t dtick, dapic, tmp;
         int i;          int i;
         char tbuf[9];          char tbuf[9];
   
Line 474  lapic_calibrate_timer(ci)
Line 457  lapic_calibrate_timer(ci)
                  */                   */
                 delay_func = lapic_delay;                  delay_func = lapic_delay;
                 initclock_func = lapic_initclocks;                  initclock_func = lapic_initclocks;
 #ifdef __HAVE_TIMECOUNTER  
                 initrtclock(0);                  initrtclock(0);
 #else  
                 initrtclock();  
 #endif  
         }          }
 }  }
   
Line 486  lapic_calibrate_timer(ci)
Line 465  lapic_calibrate_timer(ci)
  * delay for N usec.   * delay for N usec.
  */   */
   
 void lapic_delay(usec)  void
         int usec;  lapic_delay(int usec)
 {  {
         int32_t xtick, otick;          int32_t xtick, otick;
         int64_t deltat;         /* XXX may want to be 64bit */          int64_t deltat;         /* XXX may want to be 64bit */
Line 517  void lapic_delay(usec)
Line 496  void lapic_delay(usec)
  * XXX the following belong mostly or partly elsewhere..   * XXX the following belong mostly or partly elsewhere..
  */   */
   
 static inline void i82489_icr_wait(void);  static void
   i82489_icr_wait(void)
 static inline void  
 i82489_icr_wait()  
 {  {
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         unsigned j = 100000;          unsigned j = 100000;
Line 537  i82489_icr_wait()
Line 514  i82489_icr_wait()
 }  }
   
 int  int
 x86_ipi_init(target)  x86_ipi_init(int target)
         int target;  
 {  {
   
         if ((target&LAPIC_DEST_MASK)==0) {          if ((target&LAPIC_DEST_MASK)==0) {
Line 561  x86_ipi_init(target)
Line 537  x86_ipi_init(target)
 }  }
   
 int  int
 x86_ipi(vec,target,dl)  x86_ipi(int vec, int target, int dl)
         int vec,target,dl;  
 {  {
         int result, s;          int result, s;
   
Line 576  x86_ipi(vec,target,dl)
Line 551  x86_ipi(vec,target,dl)
         i82489_writereg(LAPIC_ICRLO,          i82489_writereg(LAPIC_ICRLO,
             (target & LAPIC_DEST_MASK) | vec | dl | LAPIC_LVL_ASSERT);              (target & LAPIC_DEST_MASK) | vec | dl | LAPIC_LVL_ASSERT);
   
   #ifdef DIAGNOSTIC
         i82489_icr_wait();          i82489_icr_wait();
   
         result = (i82489_readreg(LAPIC_ICRLO) & LAPIC_DLSTAT_BUSY) ? EBUSY : 0;          result = (i82489_readreg(LAPIC_ICRLO) & LAPIC_DLSTAT_BUSY) ? EBUSY : 0;
   #else
           /* Don't wait - if it doesn't go, we're in big trouble anyway. */
           result = 0;
   #endif
         splx(s);          splx(s);
   
         return result;          return result;

Legend:
Removed from v.1.20  
changed lines
  Added in v.1.20.22.5

CVSweb <webmaster@jp.NetBSD.org>