⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i8253.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
字号:
#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"/* *  8253 timer */enum{	T0cntr=	0x40,		/* counter ports */	T1cntr=	0x41,		/* ... */	T2cntr=	0x42,		/* ... */	Tmode=	0x43,		/* mode port */	/* commands */	Latch0=	0x00,		/* latch counter 0's value */	Load0=	0x30,		/* load counter 0 with 2 bytes */	/* modes */	Square=	0x36,		/* periodic square wave */	Trigger= 0x30,		/* interrupt on terminal count */	Freq=	1193182,	/* Real clock frequency */};voidi8253init(int aalcycles, int havecycleclock){	int cpufreq, loops, incr, x, y;	vlong a, b;	static int initialised;	if(initialised == 0){		initialised = 1;		ioalloc(T0cntr, 4, 0, "i8253");		/*		 *  set clock for 1/HZ seconds		 */		outb(Tmode, Load0|Square);		outb(T0cntr, (Freq/HZ));	/* low byte */		outb(T0cntr, (Freq/HZ)>>8);	/* high byte */		/*		 * Introduce a little delay to make sure the count is		 * latched and the timer is counting down; with a fast		 * enough processor this may not be the case.		 * The i8254 (which this probably is) has a read-back		 * command which can be used to make sure the counting		 * register has been written into the counting element.		 */		x = (Freq/HZ);		for(loops = 0; loops < 100000 && x >= (Freq/HZ); loops++){			outb(Tmode, Latch0);			x = inb(T0cntr);			x |= inb(T0cntr)<<8;		}	}	/* find biggest loop that doesn't wrap */	incr = 16000000/(aalcycles*HZ*2);	x = 2000;	for(loops = incr; loops < 64*1024; loops += incr) {			/*		 *  measure time for the loop		 *		 *			MOVL	loops,CX		 *	aaml1:	 	AAM		 *			LOOP	aaml1		 *		 *  the time for the loop should be independent of external		 *  cache and memory system since it fits in the execution		 *  prefetch buffer.		 *		 */		outb(Tmode, Latch0);		if(havecycleclock)			rdmsr(0x10, &a);		x = inb(T0cntr);		x |= inb(T0cntr)<<8;		aamloop(loops);		outb(Tmode, Latch0);		if(havecycleclock)			rdmsr(0x10, &b);		y = inb(T0cntr);		y |= inb(T0cntr)<<8;		x -= y;			if(x < 0)			x += Freq/HZ;		if(x > Freq/(3*HZ))			break;	}	/* 	 *  figure out clock frequency and a loop multiplier for delay().	 *  n.b. counter goes up by 2*Freq	 */	cpufreq = loops*((aalcycles*2*Freq)/x);	m->loopconst = (cpufreq/1000)/aalcycles;	/* AAM+LOOP's for 1 ms */	if(havecycleclock){		/* counter goes up by 2*Freq */		b = (b-a)<<1;		b *= Freq;		b /= x;		/*		 *  round to the nearest megahz		 */		m->cpumhz = (b+500000)/1000000L;		m->cpuhz = b;	} else {		/*		 *  add in possible 0.5% error and convert to MHz		 */		m->cpumhz = (cpufreq + cpufreq/200)/1000000;		m->cpuhz = cpufreq;	}}voidi8253enable(void){	intrenable(IrqCLOCK, clockintr, 0, BUSUNKNOWN, "clock");}/* *  return time elapsed since clock start in *  100 times hz */uvlongi8253read(uvlong *hz){	if(hz)		*hz = HZ*100;	return m->ticks*100;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -