The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pc/archmp.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include "u.h"
    2 #include "../port/lib.h"
    3 #include "mem.h"
    4 #include "dat.h"
    5 #include "fns.h"
    6 #include "io.h"
    7 
    8 #include "mp.h"
    9 
   10 _MP_ *_mp_;
   11 
   12 static _MP_*
   13 mpscan(uchar *addr, int len)
   14 {
   15         uchar *e, *p, sum;
   16         int i;
   17 
   18         e = addr+len;
   19         for(p = addr; p < e; p += sizeof(_MP_)){
   20                 if(memcmp(p, "_MP_", 4))
   21                         continue;
   22                 sum = 0;
   23                 for(i = 0; i < sizeof(_MP_); i++)
   24                         sum += p[i];
   25                 if(sum == 0)
   26                         return (_MP_*)p;
   27         }
   28         return 0;
   29 }
   30 
   31 static _MP_*
   32 mpsearch(void)
   33 {
   34         uchar *bda;
   35         ulong p;
   36         _MP_ *mp;
   37 
   38         /*
   39          * Search for the MP Floating Pointer Structure:
   40          * 1) in the first KB of the EBDA;
   41          * 2) in the last KB of system base memory;
   42          * 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
   43          */
   44         bda = KADDR(0x400);
   45         if((p = (bda[0x0F]<<8)|bda[0x0E])){
   46                 if(mp = mpscan(KADDR(p<<4), 1024))
   47                         return mp;
   48         }
   49         else{
   50                 p = ((bda[0x14]<<8)|bda[0x13])*1024;
   51                 if(mp = mpscan(KADDR(p-1024), 1024))
   52                         return mp;
   53         }
   54         return mpscan(KADDR(0xF0000), 0x10000);
   55 }
   56 
   57 static int identify(void);
   58 
   59 PCArch archmp = {
   60 .id=            "_MP_", 
   61 .ident=         identify,
   62 .reset=         mpshutdown,
   63 .intrinit=      mpinit,
   64 .intrenable=    mpintrenable,
   65 .intron=        lapicintron,
   66 .introff=       lapicintroff,
   67 .fastclock=     i8253read,
   68 .timerset=      lapictimerset,
   69 };
   70 
   71 static int
   72 identify(void)
   73 {
   74         char *cp;
   75         PCMP *pcmp;
   76         uchar *p, sum;
   77         ulong length;
   78 
   79         if((cp = getconf("*nomp")) != nil && strtol(cp, 0, 0) != 0)
   80                 return 1;
   81 
   82         /*
   83          * Search for an MP configuration table. For now,
   84          * don't accept the default configurations (physaddr == 0).
   85          * Check for correct signature, calculate the checksum and,
   86          * if correct, check the version.
   87          * To do: check extended table checksum.
   88          */
   89         if((_mp_ = mpsearch()) == 0 || _mp_->physaddr == 0)
   90                 return 1;
   91 
   92         pcmp = KADDR(_mp_->physaddr);
   93         if(memcmp(pcmp, "PCMP", 4))
   94                 return 1;
   95 
   96         length = pcmp->length;
   97         sum = 0;
   98         for(p = (uchar*)pcmp; length; length--)
   99                 sum += *p++;
  100 
  101         if(sum || (pcmp->version != 1 && pcmp->version != 4))
  102                 return 1;
  103 
  104         if(cpuserver && m->havetsc)
  105                 archmp.fastclock = tscticks;
  106         return 0;
  107 }
  108 
  109 Lock mpsynclock;
  110 
  111 void
  112 syncclock(void)
  113 {
  114         uvlong x;
  115 
  116         if(arch->fastclock != tscticks)
  117                 return;
  118 
  119         if(m->machno == 0){
  120                 wrmsr(0x10, 0);
  121                 m->tscticks = 0;
  122         } else {
  123                 x = MACHP(0)->tscticks;
  124                 while(x == MACHP(0)->tscticks)
  125                         ;
  126                 wrmsr(0x10, MACHP(0)->tscticks);
  127                 cycles(&m->tscticks);
  128         }
  129 }
  130 
  131 uvlong
  132 tscticks(uvlong *hz)
  133 {
  134         if(hz != nil)
  135                 *hz = m->cpuhz;
  136 
  137         cycles(&m->tscticks);   /* Uses the rdtsc instruction */
  138         return m->tscticks;
  139 }

Cache object: 4d2fa4f6b34fd972fe017bb625477835


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.