plan 9 kernel history: overview | file list | diff list

1993/1124/pc/clock.c (diff list | history)

pc/clock.c on 1991/0704
1991/0704    
#include	"u.h" 
1992/0321    
#include	"../port/lib.h" 
1991/0704    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"io.h" 
1991/0706    
#include	"ureg.h" 
1991/0704    
 
1991/0705    
/* 
 *  8253 timer 
 */ 
enum 
{ 
1991/0709    
	T0cntr=	0x40,		/* counter ports */ 
	T1cntr=	0x41,		/* ... */ 
	T2cntr=	0x42,		/* ... */ 
	Tmode=	0x43,		/* mode port */ 
1991/0705    
 
1992/0923    
	/* commands */ 
	Latch0=	0x00,		/* latch counter 0's value */ 
	Load0=	0x30,		/* load counter 0 with 2 bytes */ 
 
	/* modes */ 
	Square=	0x36,		/* perioic square wave */ 
 
	Freq=	1193182,	/* Real clock frequency */ 
1991/0705    
}; 
 
1992/0923    
static ulong delayloop = 1000; 
 
1991/0719    
/* 
1992/0923    
 *  delay for l milliseconds more or less.  delayloop is set by 
 *  clockinit() to match the actual CPU speed. 
1991/0719    
 */ 
void 
delay(int l) 
{ 
1992/0923    
	ulong i; 
1991/0719    
 
1992/0923    
	while(l-- > 0) 
		for(i=0; i < delayloop; i++) 
1991/0719    
			; 
} 
 
1993/1124    
static void 
clock(Ureg *ur, void *arg) 
{ 
	Proc *p; 
	int nrun = 0; 
 
	USED(arg); 
 
	m->ticks++; 
 
	checkalarms(); 
	mouseclock(); 
 
	/* 
	 *  process time accounting 
	 */ 
	p = m->proc; 
	if(p){ 
		nrun = 1; 
		p->pc = ur->pc; 
		if (p->state==Running) 
			p->time[p->insyscall]++; 
	} 
	nrun = (nrdy+nrun)*1000; 
	MACHP(0)->load = (MACHP(0)->load*19+nrun)/20; 
 
	if(up == 0 || (ur->cs&0xffff) != UESEL || up->state != Running) 
		return; 
 
	if(anyready()) 
		sched(); 
 
	/* user profiling clock */ 
	spllo();		/* in case we fault */ 
	(*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); 
	splhi(); 
} 
 
1991/0704    
void 
clockinit(void) 
{ 
1992/0923    
	ulong x, y;	/* change in counter */ 
1992/0922    
 
1991/0709    
	/* 
	 *  set vector for clock interrupts 
	 */ 
1993/1124    
	setvec(Clockvec, clock, 0); 
1991/0709    
 
	/* 
	 *  make clock output a square wave with a 1/HZ period 
	 */ 
1992/0923    
	outb(Tmode, Load0|Square); 
1991/0709    
	outb(T0cntr, (Freq/HZ));	/* low byte */ 
	outb(T0cntr, (Freq/HZ)>>8);	/* high byte */ 
1992/0922    
 
	/* 
1992/0923    
	 *  measure time for delay(10) with current delayloop count 
1992/0922    
	 */ 
	outb(Tmode, Latch0); 
1992/0923    
	x = inb(T0cntr); 
	x |= inb(T0cntr)<<8; 
	delay(10); 
	outb(Tmode, Latch0); 
	y = inb(T0cntr); 
	y |= inb(T0cntr)<<8; 
	x -= y; 
 
	/* 
1993/0915    
	 *  fix count 
1992/0923    
	 */ 
	delayloop = (delayloop*1193*10)/x; 
	if(delayloop == 0) 
		delayloop = 1; 
1991/0808    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)