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

📄 power.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"u.h"#include	"../port/lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"io.h"#include	"ureg.h"#include	"pool.h"/* Power management for the bitsy */#define TODFREQ	1000000000LL/* saved state during power down.  * it's only used up to 164/4. * it's only used by routines in l.s */ulong	power_state[200/4];ulong	resumeaddr[1];Rendez	powerr;ulong	powerflag = 0;	/* set to start power-off sequence */extern void	power_resume(void);extern int		setpowerlabel(void);extern void	_start(void);extern Uart	sa1110uart[];GPIOregs savedgpioregs;Intrregs savedintrregs;#define R(p) ((Uartregs*)((p)->regs))uchar *savedtext;static voidcheckflash(void){	ulong *p;	ulong s;	s = 0;	for (p = (ulong*)FLASHZERO; p < (ulong*)(FLASHZERO+8*1024*1024); p++)		s += *p;	iprint("flash checksum is 0x%lux\n", s);}static voidcheckktext(void){	ulong *p;	ulong s;	s = 0;	for (p = (ulong*)_start; p < (ulong*)etext; p++){		if(*p == 0)			iprint("0x%lux->0\n", p);		if (((ulong)p & 0x1fff) == 0){			iprint("page 0x%lux checksum 0x%lux\n",				(ulong)(p-1)&~0x1fff, s);			s = 0;		}		s += *p;	}	iprint("page 0x%lux checksum 0x%lux\n", (ulong)(p-1)&~0x1fff, s);}static voidcheckpagetab(void){	extern ulong l1table;	ulong *p;	ulong s;	s = 0;	for (p = (ulong*)l1table; p < (ulong*)(l1table+16*1024); p++)		s += *p;	iprint("page table checksum is 0x%lux\n", s);}static voiddumpitall(void){	extern ulong l1table;	iprint("intr: icip %lux iclr %lux iccr %lux icmr %lux\n",		intrregs->icip,		intrregs->iclr, intrregs->iccr, intrregs->icmr );	iprint("gpio: lvl %lux dir %lux, re %lux, fe %lux sts %lux alt %lux\n",		gpioregs->level,		gpioregs->direction, gpioregs->rising, gpioregs->falling,		gpioregs->edgestatus, gpioregs->altfunc);	iprint("uart1: %lux %lux %lux \nuart3: %lux %lux %lux\n", 		R(&sa1110uart[0])->ctl[0], R(&sa1110uart[0])->status[0], R(&sa1110uart[0])->status[1], 		R(&sa1110uart[1])->ctl[0], R(&sa1110uart[1])->status[0], R(&sa1110uart[1])->status[1]); 	iprint("tmr: osmr %lux %lux %lux %lux oscr %lux ossr %lux oier %lux\n",		timerregs->osmr[0], timerregs->osmr[1],		timerregs->osmr[2], timerregs->osmr[3],		timerregs->oscr, timerregs->ossr, timerregs->oier);	iprint("dram: mdcnfg %lux mdrefr %lux cas %lux %lux %lux %lux %lux %lux\n",		memconfregs->mdcnfg, memconfregs->mdrefr,		memconfregs->mdcas00, memconfregs->mdcas01,memconfregs->mdcas02,		memconfregs->mdcas20, memconfregs->mdcas21,memconfregs->mdcas22); 	iprint("dram: mdcnfg msc %lux %lux %lux mecr %lux\n",		memconfregs->msc0, memconfregs->msc1,memconfregs->msc2,		memconfregs->mecr);	iprint("mmu: CpControl %lux CpTTB %lux CpDAC %lux l1table 0x%lux\n",		getcontrol(), getttb(), getdac(), l1table);	iprint("powerregs: pmcr %lux pssr %lux pcfr %lux ppcr %lux pwer %lux pspr %lux pgsr %lux posr %lux\n",		powerregs->pmcr, powerregs->pssr, powerregs->pcfr, powerregs->ppcr,		powerregs->pwer, powerregs->pspr, powerregs->pgsr, powerregs->posr);	checkpagetab();	checkflash();	checkktext();	iprint("\n\n");}static voidintrcpy(Intrregs *to, Intrregs *from){	to->iclr = from->iclr;	to->iccr = from->iccr;	to->icmr = from->icmr;	// interrupts enabled}static voidgpiosave(GPIOregs *to, GPIOregs *from){	to->level = from->level;	to->rising = from->rising;		// gpio intrs enabled	to->falling= from->falling;		// gpio intrs enabled	to->altfunc = from->altfunc;	to->direction = from->direction;}static voidgpiorestore(GPIOregs *to, GPIOregs *from){	to->direction = from->direction;	to->altfunc = from->altfunc;	to->set = from->level & 0x0fffffff;	to->clear = ~from->level & 0x0fffffff;	to->rising = from->rising;		// gpio intrs enabled	to->falling= from->falling;		// gpio intrs enabled}void	(*restart)(void) = nil;static intbitno(ulong x){	int i;	for(i = 0; i < 8*sizeof(x); i++)		if((1<<i) & x)			break;	return i;}intpowerdown(void *){	return powerflag;}voiddeepsleep(void) {	static int power_pl;	ulong xsp, xlink;//	ulong mecr;	ulong clkd;	vlong savedtod;	extern void power_resume(void);	power_pl = splhi();	xlink = getcallerpc(&xlink);	/* Power down */	pcmciapower(0);	irpower(0);	audiopower(0);	screenpower(0);	µcpower(0);	iprint("entering suspend mode, sp = 0x%lux, pc = 0x%lux, psw = 0x%ux\n", &xsp, xlink, power_pl);//	dumpitall();	delay(1000);	uartpower(0);	rs232power(0);	clockpower(0);	gpiosave(&savedgpioregs, gpioregs);	intrcpy(&savedintrregs, intrregs);	cacheflush();	delay(50);	if(setpowerlabel()){		/* return here with mmu back on */		trapresume();		gpiorestore(gpioregs, &savedgpioregs);		delay(50);		intrcpy(intrregs, &savedintrregs);		if(intrregs->icip & (1<<IRQgpio0)){			// don't want to sleep now. clear on/off irq.			gpioregs->edgestatus = (1<<IRQgpio0);			intrregs->icip = (1<<IRQgpio0);		}		clkd = clockpower(1);		gpclkregs->r0 = 1<<0;		todset(savedtod + clkd * TODFREQ, 0LL, 0);		resetsuspendtimer();		rs232power(1);		uartpower(1);		delay(100);		xlink = getcallerpc(&xlink);		iprint("\nresuming execution, sp = 0x%lux, pc = 0x%lux, psw = 0x%ux\n", &xsp, xlink, splhi());//		dumpitall();		delay(1000);//		irpower(1);		audiopower(1);		µcpower(1);		screenpower(1);		pcmciapower(1);		splx(power_pl);		return;	}	cacheflush();	delay(100);	savedtod = todget(nil);	power_down();	/* no return */}voidpowerkproc(void*){	ulong xlink, xlink1;	for(;;){		while(powerflag == 0)			sleep(&powerr, powerdown, 0);		xlink = getcallerpc(&xlink);//		iprint("call deepsleep, pc = 0x%lux, sp = 0x%lux\n", xlink, &xlink);		deepsleep();		xlink1 = getcallerpc(&xlink1);		delay(2000);//		iprint("deepsleep returned, pc = 0x%lux, sp = 0x%lux\n", xlink1, &xlink);		powerflag = 0;	}}voidonoffintr(Ureg* , void*){	int i;	/* Power down interrupt comes on power button release.	 * Act only after button has been released a full 100 ms	 */	if (powerflag)		return;	for (i = 0; i < 100; i++) {		delay(1);		if ((gpioregs->level & GPIO_PWR_ON_i) == 0)			return;	/* bounced */	}	powerflag = 1;	wakeup(&powerr);}static voidblanktimer(void){	drawactive(0);}static ulong suspendtime = 120 * HZ;static int lastsuspend;voidresetsuspendtimer(void){	suspendtime = 60 * HZ;}static voidsuspendtimer(void){	uvlong	now;	return;	// does not work well.	if (suspendtime > 0)		suspendtime--;	if (suspendtime == 0){		now = seconds();		if (now < lastsuspend + 10){			resetsuspendtimer();			return;		}		lastsuspend = seconds();		deepsleep();		lastsuspend = seconds();		return;	}}voidpowerinit(void){	extern ulong power_magic;	extern ulong power_code;	extern ulong doze_code;	ulong *p, *q, i;	p = (ulong*)(((ulong)&power_magic + 0x1f) & ~0x1f);	q = &power_code;	for (i = 0; i < 8; i++)		*p++ = *q++;	p = (ulong*)(((ulong)doze + 0x3f) & ~0x1f);	q = &doze_code;	for (i = 0; i < 3; i++)		*p++ = *q++;	*resumeaddr = (ulong) power_resume;	addclock0link(blanktimer, 1000/HZ);	addclock0link(suspendtimer, 1000/HZ);	intrenable(GPIOrising, bitno(GPIO_PWR_ON_i), onoffintr, nil, "on/off");}voididlehands(void){	char *msgb = "idlehands called with splhi\n";	char *msga = "doze returns with splhi\n";	if(!islo()){		uartputs(msga, strlen(msga));		spllo();	}	doze();	if(!islo()){		uartputs(msgb, strlen(msgb));		spllo();	}}

⌨️ 快捷键说明

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