Annotation of lucent/sys/src/9/pc/clock.c, revision 1.1

1.1     ! root        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: #include       "ureg.h"
        !             8: 
        !             9: /*
        !            10:  *  8253 timer
        !            11:  */
        !            12: enum
        !            13: {
        !            14:        T0cntr= 0x40,           /* counter ports */
        !            15:        T1cntr= 0x41,           /* ... */
        !            16:        T2cntr= 0x42,           /* ... */
        !            17:        Tmode=  0x43,           /* mode port */
        !            18: 
        !            19:        /* commands */
        !            20:        Latch0= 0x00,           /* latch counter 0's value */
        !            21:        Load0=  0x30,           /* load counter 0 with 2 bytes */
        !            22: 
        !            23:        /* modes */
        !            24:        Square= 0x36,           /* perioic square wave */
        !            25:        Trigger= 0x30,          /* interrupt on terminal count */
        !            26: 
        !            27:        Freq=   1193182,        /* Real clock frequency */
        !            28: };
        !            29: 
        !            30: static int cpufreq = 66000000;
        !            31: static int cpumhz = 66;
        !            32: static int loopconst = 100;
        !            33: static int cpuidax, cpuiddx;
        !            34: 
        !            35: static void
        !            36: clock(Ureg *ur, void *arg)
        !            37: {
        !            38:        Proc *p;
        !            39:        int nrun = 0;
        !            40: 
        !            41:        USED(arg);
        !            42: 
        !            43:        m->ticks++;
        !            44: 
        !            45:        checkalarms();
        !            46:        uartclock();
        !            47:        hardclock();
        !            48: 
        !            49:        /*
        !            50:         *  process time accounting
        !            51:         */
        !            52:        p = m->proc;
        !            53:        if(p){
        !            54:                nrun = 1;
        !            55:                p->pc = ur->pc;
        !            56:                if (p->state==Running)
        !            57:                        p->time[p->insyscall]++;
        !            58:        }
        !            59:        nrun = (nrdy+nrun)*1000;
        !            60:        MACHP(0)->load = (MACHP(0)->load*19+nrun)/20;
        !            61: 
        !            62:        if(u && p && p->state==Running){
        !            63:                /*
        !            64:                 *  preemption
        !            65:                 */
        !            66:                if(anyready()){
        !            67:                        if(p->hasspin)
        !            68:                                p->hasspin = 0;
        !            69:                        else
        !            70:                                sched();
        !            71:                }
        !            72:                if((ur->cs&0xffff) == UESEL){
        !            73:                        spllo();                /* in case we fault */
        !            74:                        (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); /* profiling clock */
        !            75:                        splhi();
        !            76:                }
        !            77:        }
        !            78: 
        !            79:        /* last because it goes spllo() */
        !            80:        mouseclock();
        !            81: }
        !            82: 
        !            83: #define STEPPING(x)    ((x)&0xf)
        !            84: #define MODEL(x)       (((x)>>4)&0xf)
        !            85: #define FAMILY(x)      (((x)>>8)&0xf)
        !            86: 
        !            87: enum
        !            88: {
        !            89:        /* flags */
        !            90:        CpuidFPU        = 0x001,        /* on-chip floating point unit */
        !            91:        CpuidMCE        = 0x080,        /* machine check exception */
        !            92:        CpuidCX8        = 0x100,        /* CMPXCHG8B instruction */
        !            93: };
        !            94: 
        !            95: typedef struct
        !            96: {
        !            97:        int family;
        !            98:        int model;
        !            99:        int aalcycles;
        !           100:        char *name;
        !           101: } X86type;
        !           102: 
        !           103: X86type x86type[] =
        !           104: {
        !           105:        /* from the cpuid instruction */
        !           106:        { 4,    0,      22,     "Intel486DX", },
        !           107:        { 4,    1,      22,     "Intel486DX", },
        !           108:        { 4,    2,      22,     "Intel486SX", },
        !           109:        { 4,    3,      22,     "Intel486DX2", },
        !           110:        { 4,    4,      22,     "Intel486DX2", },
        !           111:        { 4,    5,      22,     "Intel486SL", },
        !           112:        { 4,    8,      22,     "IntelDX4", },
        !           113:        { 5,    1,      23,     "Pentium510", },
        !           114:        { 5,    2,      23,     "Pentium735", },
        !           115: 
        !           116:        /* family defaults */
        !           117:        { 3,    -1,     32,     "Intel386", },
        !           118:        { 4,    -1,     22,     "Intel486", },
        !           119:        { 5,    -1,     23,     "Pentium", },
        !           120: 
        !           121:        /* total default */
        !           122:        { -1,   -1,     23,     "unknown", },
        !           123: };
        !           124: 
        !           125: static X86type *cputype;
        !           126: 
        !           127: /*
        !           128:  *  delay for l milliseconds more or less.  delayloop is set by
        !           129:  *  clockinit() to match the actual CPU speed.
        !           130:  */
        !           131: void
        !           132: delay(int l)
        !           133: {
        !           134:        l *= loopconst;
        !           135:        if(l <= 0)
        !           136:                l = 1;
        !           137:        aamloop(l);
        !           138: }
        !           139: 
        !           140: /*
        !           141:  *  microsecond delay
        !           142:  */
        !           143: void
        !           144: microdelay(int l)
        !           145: {
        !           146:        l *= loopconst;
        !           147:        l /= 1000;
        !           148:        if(l <= 0)
        !           149:                l = 1;
        !           150:        aamloop(l);
        !           151: }
        !           152: 
        !           153: void
        !           154: printcpufreq(void)
        !           155: {
        !           156:        print("CPU is a %d MHz %s (cpuid: ax %lux dx %lux)\n",
        !           157:                cpumhz, cputype->name, cpuidax, cpuiddx);
        !           158: }
        !           159: 
        !           160: int
        !           161: x86(void)
        !           162: {
        !           163:        return cputype->family;
        !           164: }
        !           165: 
        !           166: void
        !           167: clockinit(void)
        !           168: {
        !           169:        int x, y;       /* change in counter */
        !           170:        int family, model, loops, incr;
        !           171:        X86type *t;
        !           172: 
        !           173:        /*
        !           174:         *  set vector for clock interrupts
        !           175:         */
        !           176:        setvec(Clockvec, clock, 0);
        !           177: 
        !           178:        /*
        !           179:         *  figure out what we are
        !           180:         */
        !           181:        x86cpuid(&cpuidax, &cpuiddx);
        !           182:        family = FAMILY(cpuidax);
        !           183:        model = MODEL(cpuidax);
        !           184:        for(t = x86type; t->name; t++)
        !           185:                if((t->family == family && t->model == model)
        !           186:                || (t->family == family && t->model == -1)
        !           187:                || (t->family == -1))
        !           188:                        break;
        !           189:        cputype = t;
        !           190: 
        !           191:        /*
        !           192:         *  set clock for 1/HZ seconds
        !           193:         */
        !           194:        outb(Tmode, Load0|Square);
        !           195:        outb(T0cntr, (Freq/HZ));        /* low byte */
        !           196:        outb(T0cntr, (Freq/HZ)>>8);     /* high byte */
        !           197: 
        !           198:        /* find biggest loop that doesn't wrap */
        !           199:        incr = 16000000/(t->aalcycles*HZ*2);
        !           200:        x = 2000;
        !           201:        for(loops = incr; loops < 64*1024; loops += incr) {
        !           202:        
        !           203:                /*
        !           204:                 *  measure time for the loop
        !           205:                 *
        !           206:                 *                      MOVL    loops,CX
        !           207:                 *      aaml1:          AAM
        !           208:                 *                      LOOP    aaml1
        !           209:                 *
        !           210:                 *  the time for the loop should be independent of external
        !           211:                 *  cache and memory system since it fits in the execution
        !           212:                 *  prefetch buffer.
        !           213:                 *
        !           214:                 */
        !           215:                outb(Tmode, Latch0);
        !           216:                x = inb(T0cntr);
        !           217:                x |= inb(T0cntr)<<8;
        !           218:                aamloop(loops);
        !           219:                outb(Tmode, Latch0);
        !           220:                y = inb(T0cntr);
        !           221:                y |= inb(T0cntr)<<8;
        !           222:                x -= y;
        !           223:        
        !           224:                if(x < 0)
        !           225:                        x += Freq/HZ;
        !           226: 
        !           227:                if(x > Freq/(3*HZ))
        !           228:                        break;
        !           229:        }
        !           230: 
        !           231:        /*
        !           232:         *  counter  goes at twice the frequency, once per transition,
        !           233:         *  i.e., twice per square wave
        !           234:         */
        !           235:        x >>= 1;
        !           236: 
        !           237:        /*
        !           238:         *  figure out clock frequency and a loop multiplier for delay().
        !           239:         */
        !           240:        cpufreq = loops*((t->aalcycles*Freq)/x);
        !           241:        loopconst = (cpufreq/1000)/t->aalcycles;        /* AAM+LOOP's for 1 ms */
        !           242: 
        !           243:        /*
        !           244:         *  add in possible .2% error and convert to MHz
        !           245:         */
        !           246:        cpumhz = (cpufreq + cpufreq/500)/1000000;
        !           247: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.