From e0713310098dcaefec6f6f18683381b39464558b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 21 Jun 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-06-21 --- "bitsy/dev\302\265c.c" | 12 ++ bitsy/l.s | 166 ++++++++++---------- bitsy/power.c | 54 ++++--- bitsy/screen.c | 334 +---------------------------------------- bitsy/trap.c | 6 +- port/lib.h | 3 + 6 files changed, 132 insertions(+), 443 deletions(-) diff --git "a/bitsy/dev\302\265c.c" "b/bitsy/dev\302\265c.c" index a5b0a084efc328cd7078fd1d3756656a3a628334..7d58d3894966f0b56059085fab6a47ee74e2db4e 100644 --- "a/bitsy/dev\302\265c.c" +++ "b/bitsy/dev\302\265c.c" @@ -15,6 +15,7 @@ enum{ Qkbdin, Qled, Qversion, + Qsuspend, /* command types */ BLversion= 0, @@ -57,6 +58,7 @@ Dirtab µcdir[]={ "kbdin", { Qkbdin, 0 }, 0, 0664, "led", { Qled, 0 }, 0, 0664, "version", { Qversion, 0 }, 0, 0664, + "suspend", { Qsuspend, 0 }, 0, 0222, }; static struct µcontroller @@ -344,6 +346,8 @@ static long char str[64]; int i, j; Rune r; + extern Rendez powerr; + extern ulong powerflag; if(c->qid.path == Qkbdin){ if(n >= sizeof(str)) @@ -356,6 +360,14 @@ static long } return n; } + if(c->qid.path == Qsuspend){ + if(!iseve()) + error(Eperm); + if(strncmp(a, "suspend", 7) != 0) + error(Ebadarg); + powerflag = 1; + wakeup(&powerr); + } cmd = parsecmd(a, n); if(cmd->nf > 15) diff --git a/bitsy/l.s b/bitsy/l.s index ebfb100919a38e15756ae7b5de405d2a701e4ffe..ac10173ac52cee5ec8ea325c52610eba07e766bb 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -48,20 +48,20 @@ TEXT mmuinvalidateaddr(SB), $-4 TEXT cacheflush(SB), $-4 /* splhi */ MOVW CPSR, R3 - ORR $(PsrDirq), R3, R1 + ORR $(PsrDirq), R3, R1 MOVW R1, CPSR /* write back any dirty data */ MOVW $0xe0000000,R0 - ADD $(8*1024),R0,R1 + ADD $(8*1024),R0,R1 _cfloop: MOVW.P 32(R0),R2 CMP.S R0,R1 BGE _cfloop /* drain write buffer and invalidate i cache contents */ - MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 - MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x5), 0 + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x5), 0 /* drain prefetch */ MOVW R0,R0 @@ -78,12 +78,12 @@ TEXT cachewb(SB), $-4 /* write back any dirty data */ _cachewb: MOVW $0xe0000000,R0 - ADD $(8*1024),R0,R1 + ADD $(8*1024),R0,R1 _cwbloop: MOVW.P 32(R0),R2 CMP.S R0,R1 BGE _cwbloop - + /* drain write buffer */ MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 RET @@ -413,6 +413,14 @@ TEXT spsrr(SB), $-4 MOVW SPSR, R0 RET +TEXT getsp(SB), $-4 + MOVW R13, R0 + RET + +TEXT getlink(SB), $-4 + MOVW R14, R0 + RET + TEXT getcallerpc(SB), $-4 MOVW 0(R13), R0 RET @@ -448,81 +456,81 @@ TEXT gotolabel(SB), $-4 TEXT setpowerlabel(SB), $-4 MOVW $power_resume+0(SB), R0 /* svc */ /* power_resume[]: what */ - MOVW R1, 0(R0) - MOVW R2, 4(R0) - MOVW R3, 8(R0) - MOVW R4, 12(R0) - MOVW R5, 16(R0) - MOVW R6, 20(R0) - MOVW R7, 24(R0) - MOVW R8, 28(R0) - MOVW R9, 32(R0) - MOVW R10,36(R0) - MOVW R11,40(R0) - MOVW R12,44(R0) - MOVW R13,48(R0) - MOVW R14,52(R0) - MOVW SPSR, R1 - MOVW R1, 56(R0) - MOVW CPSR, R2 - MOVW R2, 60(R0) + MOVW R1, 0(R0) + MOVW R2, 4(R0) + MOVW R3, 8(R0) + MOVW R4, 12(R0) + MOVW R5, 16(R0) + MOVW R6, 20(R0) + MOVW R7, 24(R0) + MOVW R8, 28(R0) + MOVW R9, 32(R0) + MOVW R10,36(R0) + MOVW R11,40(R0) + MOVW R12,44(R0) + MOVW R13,48(R0) + MOVW R14,52(R0) + MOVW SPSR, R1 + MOVW R1, 56(R0) + MOVW CPSR, R2 + MOVW R2, 60(R0) /* copro */ MRC CpMMU, 0, R3, C(CpDAC), C(0x0) - MOVW R3, 144(R0) + MOVW R3, 144(R0) MRC CpMMU, 0, R3, C(CpTTB), C(0x0) - MOVW R3, 148(R0) + MOVW R3, 148(R0) MRC CpMMU, 0, R3, C(CpControl), C(0x0) - MOVW R3, 152(R0) + MOVW R3, 152(R0) MRC CpMMU, 0, R3, C(CpFSR), C(0x0) - MOVW R3, 156(R0) + MOVW R3, 156(R0) MRC CpMMU, 0, R3, C(CpFAR), C(0x0) - MOVW R3, 160(R0) + MOVW R3, 160(R0) MRC CpMMU, 0, R3, C(CpPID), C(0x0) - MOVW R3, 164(R0) + MOVW R3, 164(R0) /* irq */ BIC $(PsrMask), R2, R3 ORR $(PsrDirq|PsrMirq), R3 - MOVW R3, CPSR - MOVW SPSR, R11 - MOVW R11, 64(R0) - MOVW R12, 68(R0) - MOVW R13, 72(R0) - MOVW R14, 76(R0) + MOVW R3, CPSR + MOVW SPSR, R11 + MOVW R11, 64(R0) + MOVW R12, 68(R0) + MOVW R13, 72(R0) + MOVW R14, 76(R0) /* und */ BIC $(PsrMask), R2, R3 ORR $(PsrDirq|PsrMund), R3 - MOVW R3, CPSR - MOVW SPSR, R11 - MOVW R11, 80(R0) - MOVW R12, 84(R0) - MOVW R13, 88(R0) - MOVW R14, 92(R0) + MOVW R3, CPSR + MOVW SPSR, R11 + MOVW R11, 80(R0) + MOVW R12, 84(R0) + MOVW R13, 88(R0) + MOVW R14, 92(R0) /* abt */ BIC $(PsrMask), R2, R3 ORR $(PsrDirq|PsrMabt), R3 - MOVW R3, CPSR - MOVW SPSR, R11 - MOVW R11, 96(R0) - MOVW R12, 100(R0) - MOVW R13, 104(R0) - MOVW R14, 108(R0) + MOVW R3, CPSR + MOVW SPSR, R11 + MOVW R11, 96(R0) + MOVW R12, 100(R0) + MOVW R13, 104(R0) + MOVW R14, 108(R0) /* fiq */ BIC $(PsrMask), R2, R3 ORR $(PsrDirq|PsrMfiq), R3 - MOVW R3, CPSR - MOVW SPSR, R7 - MOVW R7, 112(R0) - MOVW R8, 116(R0) - MOVW R9, 120(R0) - MOVW R10,124(R0) - MOVW R11,128(R0) - MOVW R12,132(R0) - MOVW R13,136(R0) - MOVW R14,140(R0) + MOVW R3, CPSR + MOVW SPSR, R7 + MOVW R7, 112(R0) + MOVW R8, 116(R0) + MOVW R9, 120(R0) + MOVW R10,124(R0) + MOVW R11,128(R0) + MOVW R12,132(R0) + MOVW R13,136(R0) + MOVW R14,140(R0) /* done */ - MOVW R2, CPSR - MOVW R1, SPSR - MOVW $0, R0 + MOVW R2, CPSR + MOVW R1, SPSR + MOVW $0, R0 RET /* Entered after a resume from suspend state. @@ -534,7 +542,7 @@ TEXT sa1100_power_resume(SB), $-4 MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 MOVW R1, CPSR /* flush caches */ - MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0 + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0 /* drain prefetch */ MOVW R0,R0 MOVW R0,R0 @@ -548,22 +556,22 @@ TEXT sa1100_power_resume(SB), $-4 MOVW 56(R0), R1 /* R1: SPSR, R2: CPSR */ MOVW 60(R0), R2 /* copro */ - MOVW 148(R0), R3 + MOVW 148(R0), R3 MCR CpMMU, 0, R3, C(CpTTB), C(0x0) - MOVW 144(R0), R3 + MOVW 144(R0), R3 MCR CpMMU, 0, R3, C(CpDAC), C(0x0) - MOVW 152(R0), R3 + MOVW 152(R0), R3 MCR CpMMU, 0, R3, C(CpControl), C(0x0) - MOVW 156(R0), R3 + MOVW 156(R0), R3 MCR CpMMU, 0, R3, C(CpFSR), C(0x0) - MOVW 160(R0), R3 + MOVW 160(R0), R3 MCR CpMMU, 0, R3, C(CpFAR), C(0x0) - MOVW 164(R0), R3 + MOVW 164(R0), R3 MCR CpMMU, 0, R3, C(CpPID), C(0x0) MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x7) /* irq */ - BIC $(PsrMask), R2, R3 - ORR $(PsrDirq|PsrMirq), R3 + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMirq), R3 MOVW R3, CPSR MOVW 64(R0), R11 MOVW 68(R0), R12 @@ -571,8 +579,8 @@ TEXT sa1100_power_resume(SB), $-4 MOVW 76(R0), R14 MOVW R11, SPSR /* und */ - BIC $(PsrMask), R2, R3 - ORR $(PsrDirq|PsrMund), R3 + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMund), R3 MOVW R3, CPSR MOVW 80(R0), R11 MOVW 84(R0), R12 @@ -580,8 +588,8 @@ TEXT sa1100_power_resume(SB), $-4 MOVW 92(R0), R14 MOVW R11, SPSR /* abt */ - BIC $(PsrMask), R2, R3 - ORR $(PsrDirq|PsrMabt), R3 + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMabt), R3 MOVW R3, CPSR MOVW 96(R0), R11 MOVW 100(R0), R12 @@ -589,8 +597,8 @@ TEXT sa1100_power_resume(SB), $-4 MOVW 108(R0), R14 MOVW R11, SPSR /* fiq */ - BIC $(PsrMask), R2, R3 - ORR $(PsrDirq|PsrMfiq), R3 + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMfiq), R3 MOVW R3, CPSR MOVW 112(R0), R7 MOVW 116(R0), R8 @@ -622,7 +630,7 @@ TEXT sa1100_power_resume(SB), $-4 MOVW 52(R0),R14 RET loop: - B loop + B loop /* The first MCR instruction of this function needs to be on a cache-line * boundary; to make this happen, it will be copied (in trap.c). @@ -639,7 +647,7 @@ TEXT _doze(SB), $-4 MOVW R0,R0 MOVW R0,R0 MOVW R0,R0 - MCR CpPWR, 0, R0, C(CpTest), C(0x2), 2 + MCR CpPWR, 0, R0, C(CpTest), C(0x2), 2 MOVW (R1), R0 - MCR CpPWR, 0, R0, C(CpTest), C(0x8), 2 + MCR CpPWR, 0, R0, C(CpTest), C(0x8), 2 RET diff --git a/bitsy/power.c b/bitsy/power.c index d5853e7827af4691a0190f399ec367d6d8df26be..830ac66a4a11717df522e806f552acd17db16887 100644 --- a/bitsy/power.c +++ b/bitsy/power.c @@ -142,18 +142,17 @@ 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); + irpower(1); + audiopower(1); + clockpower(1); gpclkregs->r0 = 1<<0; gpiocpy(gpioregs, &savedgpioregs); intrcpy(intrregs, &savedintrregs); @@ -162,15 +161,27 @@ deepsleep(void) { gpioregs->edgestatus = (1<icip = (1<lccr0 &= ~(0<lcsr & LDD) == 0) - delay(10); - lcdpower(0); -} - -static void -lcdinit(void) -{ - /* the following line works because main memory is direct mapped */ - lcd->dbar1 = framebuf->palette; - lcd->lccr3 = pcd<lccr2 = (Wid-1)<lccr1 = (Ht-16)<lccr0 = 1<r = Rect(0, 0, Ht, Wid); - gscreen->clipr = gscreen->r; - xgdata.bdata = (uchar *)framebuf->pixel; - } else { - gscreen->r = Rect(0, 0, Wid, Ht); - gscreen->clipr = gscreen->r; - xgdata.bdata = (uchar *)vscreen; - } - landscape = ls; -} - -void -lcdtweak(Cmdbuf *cmd) -{ - if(cmd->nf < 4) - return; - if(*cmd->f[0] == 'h') - lcd->lccr1 = ((Ht-16)<f[1])<f[2])<f[3])<f[0] == 'v') - lcd->lccr2 = ((Wid-1)<f[1])<f[2])<f[3])<palette, sizeof framebuf->palette); - blankscreen(1); - } else { - memmove(framebuf->palette, savedpalette, sizeof framebuf->palette); - blankscreen(0); - } -} - -void -screeninit(void) -{ - int i; - - /* map the lcd regs into the kernel's virtual space */ - lcd = (struct sa1110regs*)mapspecial(LCDREGS, sizeof(struct sa1110regs));; - - framebuf = xspanalloc(sizeof *framebuf, 0x100, 0); - - vscreen = xalloc(sizeof(ushort)*Wid*Ht); - - framebuf->palette[0] = Pal0; - - lcdpower(1); - lcdinit(); - - gscreen = &xgscreen; - xgdata.ref = 1; - i = 0; - if (landscape) { - xgdata.bdata = (uchar *)framebuf->pixel; - while (i < Wid*Ht*1/3) framebuf->pixel[i++] = 0xf800; /* red */ - while (i < Wid*Ht*2/3) framebuf->pixel[i++] = 0xffff; /* white */ - while (i < Wid*Ht*3/3) framebuf->pixel[i++] = 0x001f; /* blue */ - } else { - xgdata.bdata = (uchar *)vscreen; - while (i < Wid*Ht*1/3) vscreen[i++] = 0xf800; /* red */ - while (i < Wid*Ht*2/3) vscreen[i++] = 0xffff; /* white */ - while (i < Wid*Ht*3/3) vscreen[i++] = 0x001f; /* blue */ - flushmemscreen(gscreen->r); - } - memimageinit(); - memdefont = getmemdefont(); - - out.pos.x = MINX; - out.pos.y = 0; - out.bwid = memdefont->info[' '].width; - - blanktime = 3; /* minutes */ - - screenwin(); - screenputs = bitsyscreenputs; -} - -void -flushmemscreen(Rectangle r) -{ - int x, y; - ulong start, end; - - if (landscape == 0) { - if (r.min.x < 0) r.min.x = 0; - if (r.max.x > Wid) r.max.x = Wid; - if (r.min.y < 0) r.min.y = 0; - if (r.max.y > Ht) r.max.y = Ht; - for (x = r.min.x; x < r.max.x; x++) - for (y = r.min.y; y < r.max.y; y++) - framebuf->pixel[(x+1)*Ht-1-y] = gamma[vscreen[y*Wid+x]]; - start = (ulong)&framebuf->pixel[(r.min.x+1)*Ht-1-(r.max.y-1)]; - end = (ulong)&framebuf->pixel[(r.max.x-1+1)*Ht-1-(r.min.y)]; - } else { - start = (ulong)&framebuf->pixel[r.min.y*Ht + r.min.x]; - end = (ulong)&framebuf->pixel[(r.max.y-1)*Ht + r.max.x - 1]; - } - cachewbregion(start, end-start); -} - -/* - * export screen to devdraw - */ -uchar* -attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen) -{ - *r = gscreen->r; - *d = gscreen->depth; - *chan = gscreen->chan; - *width = gscreen->width; - *softscreen = (landscape == 0); - - return (uchar*)gscreen->data->bdata; -} - -void -getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb) -{ - USED(p, pr, pg, pb); -} - -int -setcolor(ulong p, ulong r, ulong g, ulong b) -{ - USED(p,r,g,b); - return 0; -} - -void -blankscreen(int blank) -{ - if (blank) { - lcdpower(0); - } else { - lcdpower(1); - lcdinit(); - } -} - -static void -bitsyscreenputs(char *s, int n) -{ - int i; - Rune r; - char buf[4]; - - if(!islo()) { - /* don't deadlock trying to print in interrupt */ - if(!canlock(&screenlock)) - return; - } - else - lock(&screenlock); - - while(n > 0){ - i = chartorune(&r, s); - if(i == 0){ - s++; - --n; - continue; - } - memmove(buf, s, i); - buf[i] = 0; - n -= i; - s += i; - screenputc(buf); - } - unlock(&screenlock); -} - -static void -screenwin(void) -{ - Point p, q; - char *greet; - Memimage *orange; - Rectangle r; - - memsetchan(gscreen, RGB16); - - back = memwhite; - conscol = memblack; - - orange = allocmemimage(Rect(0,0,1,1), RGB16); - orange->flags |= Frepl; - orange->clipr = gscreen->r; - orange->data->bdata[0] = 0x40; - orange->data->bdata[1] = 0xfd; - - w = memdefont->info[' '].width; - h = memdefont->height; - - r = insetrect(gscreen->r, 4); - - memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP); - window = insetrect(r, 4); - memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP); - - memimagedraw(gscreen, Rect(window.min.x, window.min.y, - window.max.x, window.min.y+h+5+6), orange, ZP, nil, ZP); - freememimage(orange); - window = insetrect(window, 5); - - greet = " Plan 9 Console "; - p = addpt(window.min, Pt(10, 0)); - q = memsubfontwidth(memdefont, greet); - memimagestring(gscreen, p, conscol, ZP, memdefont, greet); - flushmemscreen(r); - window.min.y += h+6; - curpos = window.min; - window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; -} - -static void -screenputc(char *buf) -{ - Point p; - int w, pos; - Rectangle r; - static int *xp; - static int xbuf[256]; - - if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) - xp = xbuf; - - switch(buf[0]) { - case '\n': - if(curpos.y+h >= window.max.y) - scroll(); - curpos.y += h; - screenputc("\r"); - break; - case '\r': - xp = xbuf; - curpos.x = window.min.x; - break; - case '\t': - p = memsubfontwidth(memdefont, " "); - w = p.x; - if(curpos.x >= window.max.x-4*w) - screenputc("\n"); - - pos = (curpos.x-window.min.x)/w; - pos = 4-(pos%4); - *xp++ = curpos.x; - r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h); - memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); - flushmemscreen(r); - curpos.x += pos*w; - break; - case '\b': - if(xp <= xbuf) - break; - xp--; - r = Rect(*xp, curpos.y, curpos.x, curpos.y + h); - memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); - flushmemscreen(r); - curpos.x = *xp; - break; - case '\0': - break; - default: - p = memsubfontwidth(memdefont, buf); - w = p.x; - - if(curpos.x >= window.max.x-w) - screenputc("\n"); - - *xp++ = curpos.x; - r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h); - memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); - memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf); - flushmemscreen(r); - curpos.x += w; - } -} - -static void -scroll(void) -{ - int o; - Point p; - Rectangle r; - - o = 8*h; - r = Rpt(window.min, Pt(window.max.x, window.max.y-o)); - p = Pt(window.min.x, window.min.y+o); - memimagedraw(gscreen, r, gscreen, p, nil, p); - flushmemscreen(r); - r = Rpt(Pt(window.min.x, window.max.y-o), window.max); - memimagedraw(gscreen, r, back, ZP, nil, ZP); - flushmemscreen(r); - - curpos.y -= o; -} +static ulong rep(u diff --git a/bitsy/trap.c b/bitsy/trap.c index 5611665c2ad937892979dad9f25d8e762aa85fa9..b676075b7dbd460dda00a3b29eee3c9b5262cfb9 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -98,7 +98,7 @@ trapinit(void) void trapdump(char *tag) { - print("%s: icip %lux icmr %lux iclr %lux iccr %lux icfp %lux\n", + iprint("%s: icip %lux icmr %lux iclr %lux iccr %lux icfp %lux\n", tag, intrregs->icip, intrregs->icmr, intrregs->iclr, intrregs->iccr, intrregs->icfp); } @@ -121,7 +121,7 @@ warnregs(Ureg *ur, char *tag) ur->r8, ur->r9, ur->r10, ur->r11); seprint(p, e, "r12 0x%.8lux r13 0x%.8lux r14 0x%.8lux\n", ur->r12, ur->r13, ur->r14); - print("%s", buf); + iprint("%s", buf); } /* @@ -764,7 +764,7 @@ _dumpstack(Ureg *ureg) return; } - print("ktrace /kernel/path %.8lux %.8lux %.8lux\n", ureg->pc, ureg->sp, ureg->r14); + iprint("ktrace /kernel/path %.8lux %.8lux %.8lux\n", ureg->pc, ureg->sp, ureg->r14); i = 0; for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){ v = *(ulong*)l; diff --git a/port/lib.h b/port/lib.h index 2ca7a0c649795f8af18990498c80271f98e9afa8..ddf6d32a68d35aa92ce4e19d547306bbecd83bda 100644 --- a/port/lib.h +++ b/port/lib.h @@ -74,6 +74,9 @@ extern int print(char*, ...); */ extern char* cleanname(char*); extern ulong getcallerpc(void*); +extern void* getsp(void); +extern void* getlink(void); + extern long strtol(char*, char**, int); extern ulong strtoul(char*, char**, int); extern vlong strtoll(char*, char**, int);