M bitsy/devuda1341.c => bitsy/devuda1341.c +1 -2
@@ 939,9 939,9 @@ audioopen(Chan *c, int mode)
outenable();
}
mxvolume();
- qunlock(&audio);
if (audio.amode & Aread)
sendaudio(&audio.o);
+ qunlock(&audio);
if (debug) print("open done\n");
break;
@@ 1084,7 1084,6 @@ audioread(Chan *c, void *v, long n, vlong off)
poperror();
qunlock(s);
break;
- break;
case Qstatus:
buf[0] = 0;
M bitsy/fns.h => bitsy/fns.h +1 -0
@@ 70,6 70,7 @@ void pcmunmap(int, PCMmap*);
void penbutton(int, int);
void pentrackxy(int x, int y);
void powerinit(void);
+void powerkproc(void*);
#define procrestore(p)
void procsave(Proc*);
void procsetup(Proc*);
M bitsy/l.s => bitsy/l.s +1 -1
@@ 527,7 527,7 @@ TEXT setpowerlabel(SB), $-4
/* Entered after a resume from suspend state.
* The bootldr jumps here after a processor reset.
- */
+ */
TEXT sa1100_power_resume(SB), $-4
MOVW $setR12(SB), R12 /* load the SB */
/* SVC mode, interrupts disabled */
M bitsy/main.c => bitsy/main.c +2 -1
@@ 37,7 37,6 @@ main(void)
trapinit();
sa1110_uartsetup(1);
rs232power(1);
- powerinit();
dmainit();
screeninit();
printinit(); /* from here on, print works, before this we need iprint */
@@ 49,6 48,7 @@ main(void)
pageinit();
swapinit();
userinit();
+ powerinit();
schedinit();
}
@@ 104,6 104,7 @@ init0(void)
poperror();
}
kproc("alarm", alarmkproc, 0);
+ kproc("power", powerkproc, 0);
touser(sp);
}
M bitsy/power.c => bitsy/power.c +76 -32
@@ 13,7 13,9 @@
* it's only used up to 164/4.
* it's only used by routines in l.s
*/
-ulong power_resume[200/4];
+ulong power_resume[200/4];
+Rendez powerr;
+ulong powerflag = 0; /* set to start power-off sequence */
extern void sa1100_power_resume(void);
extern int setpowerlabel(void);
@@ 72,10 74,8 @@ gpiocpy(GPIOregs *to, GPIOregs *from)
static void
sa1100_power_off(void)
{
- iprint("11..");
/* enable wakeup by µcontroller, on/off switch or real-time clock alarm */
powerregs->pwer = 1 << IRQrtc | 1 << IRQgpio0 | 1 << IRQgpio1;
- iprint("12..");
/* clear previous reset status */
resetregs->rcsr = RCSR_all;
@@ 98,26 98,62 @@ sa1100_power_off(void)
for(;;);
}
+static int
+bitno(ulong x)
+{
+ int i;
+
+ for(i = 0; i < 8*sizeof(x); i++)
+ if((1<<i) & x)
+ break;
+ return i;
+}
+
void
onoffintr(Ureg* , void*)
{
- static int power_pl;
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);
+}
+
+int
+powerdown(void *)
+{
+ return powerflag;
+}
+
+void
+deepsleep(void) {
+ static int power_pl;
+
power_pl = splhi();
+
+ /* flush cache */
cachewb();
delay(500);
+
+ /* Save state and setjmp */
if (setpowerlabel()) {
+ /* return from longjmp, turn everything back on */
mmuinvalidate();
mmuenable();
cacheflush();
trapresume();
- rs232power(1);
- clockpower(1);
gpclkregs->r0 = 1<<0;
gpiocpy(gpioregs, &savedgpioregs);
intrcpy(intrregs, &savedintrregs);
@@ 126,46 162,56 @@ onoffintr(Ureg* , void*)
gpioregs->edgestatus = (1<<IRQgpio0);
intrregs->icip = (1<<IRQgpio0);
}
- uartpower(1);
- µcpower(1);
- screenpower(1);
- irpower(1);
- audiopower(1);
- iprint("\nresuming execution\n");
// dumpitall();
delay(800);
splx(power_pl);
return;
}
/* Power down */
- iprint("\nentering suspend mode\n");
gpiocpy(&savedgpioregs, gpioregs);
intrcpy(&savedintrregs, intrregs);
delay(400);
- clockpower(0);
- irpower(0);
- audiopower(0);
- screenpower(0);
- µcpower(0);
- uartpower(0);
- iprint("rs\n");
- rs232power(0);
- iprint("10..");
sa1100_power_off();
/* no return */
}
+void
+powerkproc(void*)
+{
+ static int power_pl;
+ for(;;){
+ while(powerflag == 0)
+ sleep(&powerr, powerdown, 0);
+ iprint("starting power down\n");
+ powerflag = 0;
-static int
-bitno(ulong x)
-{
- int i;
+ power_pl = splhi();
- for(i = 0; i < 8*sizeof(x); i++)
- if((1<<i) & x)
- break;
- return i;
+// irpower(0);
+// audiopower(0);
+ screenpower(0);
+ µcpower(0);
+ clockpower(0);
+
+ rs232power(0);
+ uartpower(0);
+
+ deepsleep();
+
+ rs232power(1);
+ uartpower(1);
+
+ clockpower(1);
+ µcpower(1);
+ screenpower(1);
+// audiopower(1);
+// irpower(1);
+
+ splx(power_pl);
+
+ iprint("power restored\n");
+ }
}
void
@@ 174,8 220,6 @@ powerinit(void)
intrenable(GPIOrising, bitno(GPIO_PWR_ON_i), onoffintr, (void*)0x12344321, "on/off");
}
-
-
void
idlehands(void)
{
M bitsy/trap.c => bitsy/trap.c +12 -9
@@ 262,8 262,11 @@ trap(Ureg *ureg)
rem = ((char*)ureg)-up->kstack;
else
rem = ((char*)ureg)-((char*)(MACHADDR+sizeof(Mach)));
- if(rem < 256)
- panic("trap %d bytes remaining", rem);
+ if(rem < 256) {
+ dumpstack();
+ panic("trap %d bytes remaining, up = 0x%lux, ureg = 0x%lux, at pc 0x%lux",
+ rem, up, ureg, ureg->pc);
+ }
user = (ureg->psr & PsrMask) == PsrMusr;
@@ 338,8 341,8 @@ trap(Ureg *ureg)
}
break;
case PsrMund: /* undefined instruction */
- /* start of Inferno code [SJM] */
if (user) {
+ /* look for floating point instructions to interpret */
x = spllo();
rv = fpiarm(ureg);
splx(x);
@@ 351,7 354,6 @@ trap(Ureg *ureg)
warnregs(ureg, "undefined instruction");
panic("undefined instruction");
}
- /* end of Inferno code [SJM] */
break;
}
@@ 424,8 426,9 @@ syscall(Ureg* ureg)
long ret;
int i, scallnr;
- if((ureg->psr & PsrMask) != PsrMusr)
+ if((ureg->psr & PsrMask) != PsrMusr) {
panic("syscall: pc 0x%lux r14 0x%lux cs 0x%ux\n", ureg->pc, ureg->r14, ureg->psr);
+ }
m->syscall++;
up->insyscall = 1;
@@ 757,7 760,7 @@ _dumpstack(Ureg *ureg)
extern ulong etext;
if(up == 0){
- print("no current proc\n");
+ iprint("no current proc\n");
return;
}
@@ 769,17 772,17 @@ _dumpstack(Ureg *ureg)
v -= 4;
p = (ulong*)v;
if((*p & 0x0f000000) == 0x0b000000){
- print("%.8lux=%.8lux ", l, v);
+ iprint("%.8lux=%.8lux ", l, v);
i++;
}
}
if(i == 4){
i = 0;
- print("\n");
+ iprint("\n");
}
}
if(i)
- print("\n");
+ iprint("\n");
}
void