~kris/9p

9hist

e0b34aa50f0cbc3a9b1ef9e9b9023619c7d0676c — David du Colombier 24 years ago 59959c4
Plan 9 from Bell Labs 2002-05-18
5 files changed, 156 insertions(+), 100 deletions(-)

M bitsy/io.h
M bitsy/l.s
M bitsy/mem.h
M bitsy/power.c
M bitsy/trap.c
M bitsy/io.h => bitsy/io.h +8 -17
@@ 254,26 254,18 @@ extern MemConfRegs *memconfregs;
 */

/* Power management ops */
enum {
	PCFR_suspend	= 1,

	PCFR_opde	= 1,
	PCFR_fp		= 2,
	PCFR_fs		= 4,
	PCFR_fo		= 8,
};

typedef struct PowerRegs PowerRegs;
struct PowerRegs
{
	ulong	pmcr;	/* Power manager control register */
	ulong	pssr;	/* Power manager sleep status register */
	ulong	pspr;	/* Power manager scratch pad register */
	ulong	pwer;	/* Power manager wakeup enable register */
	ulong	pcfr;	/* Power manager general configuration register */
	ulong	ppcr;	/* Power manager PPL configuration register */
	ulong	pgsr;	/* Power manager GPIO sleep state register */
	ulong	posr;	/* Power manager oscillator status register */
	ulong	pmcr;	/* 0x0 Power manager control register */
	ulong	pssr;	/* 0x4 Power manager sleep status register */
	ulong	pspr;	/* 0x8 Power manager scratch pad register */
	ulong	pwer;	/* 0xc Power manager wakeup enable register */
	ulong	pcfr;	/* 0x10 Power manager general configuration register */
	ulong	ppcr;	/* 0x14 Power manager PPL configuration register */
	ulong	pgsr;	/* 0x18 Power manager GPIO sleep state register */
	ulong	posr;	/* 0x1c Power manager oscillator status register */
};
extern PowerRegs *powerregs;



@@ 287,7 279,6 @@ enum
	RCSR_swr = 0x00000002,	/* sw reset */
	RCSR_wdr = 0x00000004,	/* watch dog */
	RCSR_smr = 0x00000008,	/* sleep mode reset */
	RCSR_all = 0x0000000f,
};

typedef struct ResetRegs ResetRegs;

M bitsy/l.s => bitsy/l.s +111 -78
@@ 509,9 509,18 @@ TEXT setpowerlabel(SB), $-4
	MOVW	R3, 160(R0)
	MRC		CpMMU, 0, R3, C(CpPID), C(0x0)
	MOVW	R3, 164(R0)
	/* usr */
	BIC		$(PsrMask), R2, R3
	ORR		$(0xdf), R3
	MOVW		R3, CPSR
	MOVW		SPSR, R11
	MOVW		R11, 168(R0)
	MOVW		R12, 172(R0)
	MOVW		R13, 176(R0)
	MOVW		R14, 180(R0)
	/* irq */
	BIC		$(PsrMask), R2, R3
	ORR		$(PsrDirq|PsrMirq), R3
	ORR		$(0xd2), R3
	MOVW	R3, CPSR
	MOVW	SPSR, R11
	MOVW	R11, 64(R0)


@@ 520,7 529,7 @@ TEXT setpowerlabel(SB), $-4
	MOVW	R14, 76(R0)
	/* und */
	BIC		$(PsrMask), R2, R3
	ORR		$(PsrDirq|PsrMund), R3
	ORR		$(0xdb), R3
	MOVW	R3, CPSR
	MOVW	SPSR, R11
	MOVW	R11, 80(R0)


@@ 529,7 538,7 @@ TEXT setpowerlabel(SB), $-4
	MOVW	R14, 92(R0)
	/* abt */
	BIC		$(PsrMask), R2, R3
	ORR		$(PsrDirq|PsrMabt), R3
	ORR		$(0xd7), R3
	MOVW	R3, CPSR
	MOVW	SPSR, R11
	MOVW	R11, 96(R0)


@@ 538,7 547,7 @@ TEXT setpowerlabel(SB), $-4
	MOVW	R14, 108(R0)
	/* fiq */
	BIC		$(PsrMask), R2, R3
	ORR		$(PsrDirq|PsrMfiq), R3
	ORR		$(0xd1), R3
	MOVW	R3, CPSR
	MOVW	SPSR, R7
	MOVW	R7, 112(R0)


@@ 607,9 616,17 @@ TEXT power_resume(SB), $-4
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	/* usr */
	BIC		$(PsrMask), R2, R3
	ORR		$(0xdf), R3
	MOVW		168(R0), R11
	MOVW		172(R0), R12
	MOVW		176(R0), R13
	MOVW		180(R0), R14
	MOVW		R11, SPSR
	/* irq */
	BIC		$(PsrMask), R2, R3
	ORR		$(PsrDirq|PsrMirq), R3
	ORR		$(0xd2), R3
	MOVW	R3, CPSR
	MOVW	64(R0), R11
	MOVW	68(R0), R12


@@ 618,7 635,7 @@ TEXT power_resume(SB), $-4
	MOVW	R11, SPSR
	/* und */
	BIC		$(PsrMask), R2, R3
	ORR		$(PsrDirq|PsrMund), R3
	ORR		$(0xdb), R3
	MOVW	R3, CPSR
	MOVW	80(R0), R11
	MOVW	84(R0), R12


@@ 627,7 644,7 @@ TEXT power_resume(SB), $-4
	MOVW	R11, SPSR
	/* abt */
	BIC		$(PsrMask), R2, R3
	ORR		$(PsrDirq|PsrMabt), R3
	ORR		$(0xd7), R3
	MOVW	R3, CPSR
	MOVW	96(R0), R11
	MOVW	100(R0), R12


@@ 636,7 653,7 @@ TEXT power_resume(SB), $-4
	MOVW	R11, SPSR
	/* fiq */
	BIC		$(PsrMask), R2, R3
	ORR		$(PsrDirq|PsrMfiq), R3
	ORR		$(0xd1), R3
	MOVW	R3, CPSR
	MOVW	112(R0), R7
	MOVW	116(R0), R8


@@ 677,83 694,99 @@ TEXT power_down(SB), $-4
	MOVW	gpioregs+0(SB),R6
	MOVW	memconfregs+0(SB),R5
	MOVW	powerregs+0(SB),R3
	MOVW	0x1c(R5),R4
	ORR		$0x30400000,R4
	AND		$(~0xfff0),R4
	MOVW	$0x80000003,R2


	/* wakeup on power | rtc */
	MOVW	$(PWR_rtc|PWR_gpio0),R2
	MOVW	R2,0xc(R3)
	MOVW	$15,R2
	MOVW	R2,0x4(R7)
	MOVW	$7,R2

	/* clear reset status */
	MOVW	$(RCSR_all), R2
	MOVW	R2, 0x4(R7)
	/* float */
	MOVW	$(PCFR_opde|PCFR_fp|PCFR_fs), R2
	MOVW	R2,0x10(R3)
	/* sleep state */
	MOVW	$0,R2
	MOVW	R2,0x18(R3)
	MOVW	$power_resume+0(SB),R2
/*	MOVW	$0,R2	*/
	/* set resume address (pspr)*/
	MOVW	$resumeaddr+0(SB),R1
	MOVW	0x0(R1), R2
	MOVW	R2,0x8(R3)
	MOVW	$0,R2
	MOVW	R2,0x4(R6)
	MOVW	0x1c(R5),R2
	ORR		$0x400000,R2
	MOVW	R2,0x1c(R5)
	MOVW	$(90*206),R0
l13:	SUB		$1,R0
	BGT		l13
	MOVW	powerregs+0(SB),R3
	MOVW	$0,R2
	MOVW	R2,20(R3)
	MOVW	$(90*206),R0
l14:	SUB		$1,R0
	BGT		l14
	MOVW	powerregs+0(SB),R5
	ORR		$0x80000000,R4,R6
	AND		$(~0x80100000),R6,R11

	MOVW	memconfregs+0(SB),R3
	MOVW	0x0(R3),R12
	AND		$(~0x30003),R12

	MOVW	0x10(R3),R2
	AND		$(~0x00030003),R2
	MOVW	R2,0x10(R3)
	MOVW	0x14(R3),R2
	AND		$(~0x00030003),R2
	MOVW	R2,0x14(R3)
	MOVW	0x2c(R3),R2
	AND		$(~0x00030003),R2
	MOVW	R2,0x2c(R3)

	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0
	/* align this on a cache-line boundary */
	MOVW	$1,R2
	MOVW	R4,0x1c(R3)
	MOVW	R6,0x1c(R3)
	MOVW	R12,0x0(R3)
	MOVW	R11,0x1c(R3)
	MOVW	R2,0x0(R5)
xlloop:
	B		xlloop			/* loop waiting for sleep */

/* The first instruction of this function needs to be on a cache-line
 * boundary; to make this happen, it will be copied (in trap.c).
 *
 * Hibernate puts the machine into hibernation.
 */
TEXT _hibernate(SB), $-4
	BL	cacheflush(SB)

	/* disable clock switching */
	MCR   	CpPWR, 0, R1, C(CpTest), C(0x2), 2

	/* adjust mem timing */
	MOVW	memconfregs+0(SB),R5
	MOVW	0x1c(R5), R2
	ORR	$(MDREFR_k1db2), R2
	MOVW	R2, 0x1c(R5)

	/* set PLL to lower speed w/ delay (ppcr = 0)*/
	MOVW	powerregs+0(SB),R3
	MOVW	$(120*206),R0
l11:	SUB	$1,R0
	BGT	l11
	MOVW	$0, R2
	MOVW	R2, 0x14(R3)
	MOVW	$(120*206),R0
l12:	SUB	$1,R0
	BGT	l12

	/* setup registers for suspend procedure:
	 * 1. clear RT in mscx (R1, R7, R8)
	 * 2. clear DRI in mdrefr (R4)
	 * 3. set slfrsh in mdrefr (R6)
	 * 4. clear DE in mdcnfg (R9)
	 * 5. clear dram refresh (R10)
	 * 6. force sleep (R2)
	 */
	/* 1 */
	MOVW	0x10(R5), R2
	BIC	$(MSC_rt), R2
	MOVW	R2, R1
	MOVW	0x14(R5), R2
	BIC	$(MSC_rt), R2
	MOVW	R2, R7
	MOVW	0x2c(R5), R2
	BIC	$(MSC_rt), R2
	MOVW	R2, R8
	/* 2 */
	MOVW	0x1c(R5), R2
	BIC	$(0xff00), R2
	BIC	$(0x00f0), R2
	MOVW	R2, R4
	/* 3 */
	ORR	$(MDREFR_slfrsh), R2, R6
	/* 4 */
	MOVW	0x0(R5), R9
	BIC	$(MDCFNG_de), R9, R9
	/* 5 */
	MOVW	R4, R2
	BIC	$(MDREFR_slfrsh), R2, R2
	BIC	$(MDREFR_e1pin), R2, R2
	MOVW	R2, R10
	/* 6 */
	MOVW	$1,R2
	MOVW	R4,0x1c(R3)
	MOVW	R6,0x1c(R3)
	MOVW	R12,0x0(R3)
	MOVW	R11,0x1c(R3)
	MOVW	R2,0x0(R5)

	/* Follow the procedure */
	/* 1 */
	MOVW	R1, 0x10(R5)
	MOVW	R7, 0x14(R5)
	MOVW	R8, 0x2c(R5)
	/* 2 */
	MOVW	R4, 0x1c(R5)
	/* 3 */
	MOVW	R6, 0x1c(R5)
	/* 4 */
	MOVW	R9, 0x0(R5)
	/* 5 */
	MOVW	R10, 0x1c(R5)
	/* 6 */
	MOVW	R2, 0x0(R3)
slloop:
	B		slloop			/* loop waiting for sleep */


M bitsy/mem.h => bitsy/mem.h +24 -0
@@ 210,3 210,27 @@
 *  H3650 specific definitions
 */
#define EGPIOREGS	0x49000000	/* Additional GPIO register */

/* Power management */

#define PWR_rtc		0x80000000	/* resume on RTC */
#define	PWR_gpio0	0x00000001	/* resume on power button */

#define RCSR_all	0x0000000f
#define PCFR_opde	0x00000001	/* oscillator power-down enable */
#define PCFR_suspend	0x00000001
#define PCFR_fp		0x00000002	/* float pcmcia */
#define PCFR_fs		0x00000004	/* float static memory */
#define PCFR_fo		0x00000008

#define MDREFR_k1db2	(1 << 22)
#define MDREFR_slfrsh	0x80000000	/* self refresh */
#define MDREFR_e1pin	(1 << 20)
#define MSC_rt		0x00030003

#define MDCNFG_de0	0x00000001	/* dram enable */
#define MDCNFG_de1	0x00000002
#define MDCNFG_de2	0x00000004
#define MDCNFG_de3	0x00000008
#define MDCFNG_de	0x0000000f
#define PMCR_sf		1

M bitsy/power.c => bitsy/power.c +11 -5
@@ 14,6 14,7 @@
 * 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 */



@@ 29,6 30,7 @@ Intrregs savedintrregs;

uchar *savedtext;


static void
checkflash(void)
{


@@ 164,16 166,20 @@ void
deepsleep(void) {
	static int power_pl;
	ulong xsp, xlink, mecr;
	extern void power_resume(void);

	power_pl = splhi();
	xlink = getcallerpc(&xlink);

	*resumeaddr = (ulong) power_resume;
//	*resumeaddr = nil;
	/* Power down */
	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();
//	dumpitall();
	delay(1000);
	uartpower(0);
	rs232power(0);


@@ 189,7 195,7 @@ deepsleep(void) {

		/* Turn off memory auto power */
//		memconfregs->mdrefr &= ~0x30000000;
		memconfregs->mecr = mecr;
//		memconfregs->mecr = mecr;

		gpiorestore(gpioregs, &savedgpioregs);
		delay(50);


@@ 206,10 212,10 @@ deepsleep(void) {
		delay(100);
		xlink = getcallerpc(&xlink);
		iprint("\nresuming execution, sp = 0x%lux, pc = 0x%lux, psw = 0x%ux\n", &xsp, xlink, splhi());
		dumpitall();
//		dumpitall();
		delay(1000);
//		irpower(1);
		audiopower(1);
//		audiopower(1);
		µcpower(1);
		screenpower(1);
		splx(power_pl);


@@ 236,10 242,10 @@ powerkproc(void*)
		deepsleep();
		xlink1 = getcallerpc(&xlink1);

//		iprint("deepsleep returned, pc = 0x%lux, sp = 0x%lux\n", xlink1, &xlink);

		delay(2000);

//		iprint("deepsleep returned, pc = 0x%lux, sp = 0x%lux\n", xlink1, &xlink);
		powerflag = 0;
	}
}

M bitsy/trap.c => bitsy/trap.c +2 -0
@@ 71,8 71,10 @@ trapinit(void)
	 */
	doze = xspanalloc(12*sizeof(long), 16, 0);
	memmove(doze, _doze, 12*sizeof(long));
#ifdef notdef
	hibernate = xspanalloc(8*sizeof(long), 16, 0);
	memmove(hibernate, _hibernate, 8*sizeof(long));
#endif
	wbflush();

	/* use exception vectors at 0xFFFF0000 */