M bitsy/fns.h => bitsy/fns.h +2 -0
@@ 43,6 43,8 @@ ulong getsp(void);
void gpiointrenable(ulong, int, void (*)(Ureg*, void*), void*, char*);
void h3650uartsetup(void);
int havetimer(void);
+void _hibernate(void);
+void (*hibernate)(void);
void icacheinvalidate(void);
void idle(void);
void idlehands(void);
M bitsy/l.s => bitsy/l.s +24 -1
@@ 722,15 722,38 @@ l14: SUB $1,R0
MOVW 0x2c(R3),R2
AND $(~0x00030003),R2
MOVW R2,0x2c(R3)
- MOVW R0,R0 /* filler */
+ 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
+ MOVW $1,R2
+ MOVW R4,0x1c(R3)
+ MOVW R6,0x1c(R3)
+ MOVW R12,0x0(R3)
+ MOVW R11,0x1c(R3)
+ MOVW R2,0x0(R5)
slloop:
B slloop /* loop waiting for sleep */
M bitsy/trap.c => bitsy/trap.c +7 -2
@@ 31,9 31,10 @@ typedef struct Vpage0 {
Vpage0 *vpage0;
/*
- * An cached line for the doze code
+ * A cached line for the doze and hibernate code
*/
void (*doze)(void);
+void (*hibernate)(void);
static void irq(Ureg*);
static void gpiointr(Ureg*, void*);
@@ 65,9 66,13 @@ trapinit(void)
memmove(vpage0->vectors, vectors, sizeof(vpage0->vectors));
memmove(vpage0->vtable, vtable, sizeof(vpage0->vtable));
- /* relocate the doze routine to a cache line boundary in cached mem */
+ /* relocate the doze and hibernate routines
+ * to a cache line boundary in cached mem
+ */
doze = xspanalloc(12*sizeof(long), 16, 0);
memmove(doze, _doze, 12*sizeof(long));
+ hibernate = xspanalloc(8*sizeof(long), 16, 0);
+ memmove(hibernate, _hibernate, 8*sizeof(long));
wbflush();
/* use exception vectors at 0xFFFF0000 */
M pc/devvga.c => pc/devvga.c +4 -4
@@ 97,7 97,7 @@ vgaopen(Chan* c, int omode)
scr = &vgascreen[0];
if ((ulong)c->qid.path == Qvgaovlctl) {
- if (scr->dev->ovlctl)
+ if (scr->dev && scr->dev->ovlctl)
scr->dev->ovlctl(scr, c, openctl, strlen(openctl));
else
error(Enonexist);
@@ 113,7 113,7 @@ vgaclose(Chan* c)
scr = &vgascreen[0];
if((ulong)c->qid.path == Qvgaovlctl)
- if(scr->dev->ovlctl){
+ if(scr->dev && scr->dev->ovlctl){
if(waserror()){
print("ovlctl error: %s\n", up->errstr);
return;
@@ 418,7 418,7 @@ vgawrite(Chan* c, void* a, long n, vlong off)
case Qvgaovl:
scr = &vgascreen[0];
- if (scr->dev->ovlwrite == nil) {
+ if (scr->dev == nil || scr->dev->ovlwrite == nil) {
error(Enooverlay);
break;
}
@@ 426,7 426,7 @@ vgawrite(Chan* c, void* a, long n, vlong off)
case Qvgaovlctl:
scr = &vgascreen[0];
- if (scr->dev->ovlctl == nil) {
+ if (scr->dev == nil || scr->dev->ovlctl == nil) {
error(Enooverlay);
break;
}
M pc/mmu.c => pc/mmu.c +1 -0
@@ 56,6 56,7 @@ memglobal(void)
int i, j;
ulong *pde, *pte;
+return;
/* only need to do this once, on bootstrap processor */
if(m->machno != 0)
return;
M port/devproc.c => port/devproc.c +3 -0
@@ 556,6 556,9 @@ procread(Chan *c, void *va, long n, vlong off)
|| (offset >= USTKTOP-USTKSIZE && offset < USTKTOP))
return procctlmemio(p, offset, n, va, 1);
+ if(!iseve())
+ error(Eperm);
+
/* validate kernel addresses */
if(offset < (ulong)end) {
if(offset+n > (ulong)end)