From 868e661a0eeffb9ebbe4d79a844bb8fbc80ef7b5 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 30 Nov 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-11-30 --- bitsy/clock.c | 1 + bitsy/devpcmcia.c | 1 - bitsy/devpenmouse.c | 1 + bitsy/devuda1341.c | 10 +-- bitsy/fns.h | 4 +- bitsy/l.s | 21 ++++++ bitsy/mem.h | 5 +- bitsy/mmu.c | 5 ++ bitsy/power.c | 14 +++- bitsy/screen.c | 9 ++- bitsy/screen.h | 2 + bitsy/trap.c | 161 ++++++++++++++++++++++++++++++-------------- port/proc.c | 2 +- 13 files changed, 175 insertions(+), 61 deletions(-) diff --git a/bitsy/clock.c b/bitsy/clock.c index de5006504084fb67d939d9a83513646cbbc5b308..19a740a4f4fc4ddf170c6c095c730a395393823c 100644 --- a/bitsy/clock.c +++ b/bitsy/clock.c @@ -64,6 +64,7 @@ clockintr(Ureg *ureg, void*) /* post interrupt 1/HZ secs from now */ timerregs->osmr[0] = timerregs->oscr + ClockFreq/HZ; + drawactive(0); /* screen saver */ portclock(ureg); } diff --git a/bitsy/devpcmcia.c b/bitsy/devpcmcia.c index b8aad3079a946deaa507de8d822edcc39a89f8be..4f3c5ec8b37282ee11401bd942c108fd781072bb 100644 --- a/bitsy/devpcmcia.c +++ b/bitsy/devpcmcia.c @@ -315,7 +315,6 @@ slotinfo(Ureg*, void*) static void increfp(PCMslot *pp) { - slotinfo(nil, nil); if(incref(&pcmcia) == 1){ egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 1); egpiobits(EGPIO_pcmcia_reset, 0); diff --git a/bitsy/devpenmouse.c b/bitsy/devpenmouse.c index a95f77838544bcdd98dc57bcaaf1ffb61d3beff8..24d60803ba74fcf605a25bb0b75a90f9e9ef499a 100644 --- a/bitsy/devpenmouse.c +++ b/bitsy/devpenmouse.c @@ -425,6 +425,7 @@ penmousetrack(int b, int x, int y) mouse.qfull = 1; } wakeup(&mouse.r); + drawactive(1); } int diff --git a/bitsy/devuda1341.c b/bitsy/devuda1341.c index c692600390b35e9a7820c99e96672c80b3771ebf..e91134243f4dc6773c80f8b4d647c9b9d8349a4f 100644 --- a/bitsy/devuda1341.c +++ b/bitsy/devuda1341.c @@ -922,10 +922,12 @@ audioclose(Chan *c) } qunlock(&audio); poperror(); - print("total dmas: %lud\n", iostats.totaldma); - print("dmas while idle: %lud\n", iostats.idledma); - print("dmas while busy: %lud\n", iostats.faildma); - print("out of order dma: %lud\n", iostats.samedma); + if (debug) { + print("total dmas: %lud\n", iostats.totaldma); + print("dmas while idle: %lud\n", iostats.idledma); + print("dmas while busy: %lud\n", iostats.faildma); + print("out of order dma: %lud\n", iostats.samedma); + } } break; } diff --git a/bitsy/fns.h b/bitsy/fns.h index e7fd383729fb4c3ace9be77eaf17d3dc7d05b50d..ecf005e2911ec4479da20b2cfa1dd9801db07cde 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -13,6 +13,8 @@ void clockinit(void); void delay(int); void µdelay(int); void dmainit(void); +void _doze(void); +void (*doze)(void); void egpiobits(ulong, int); void evenaddr(ulong); void exppackpower(int); @@ -27,7 +29,7 @@ void gpiointrenable(ulong, int, void (*)(Ureg*, void*), void*, char*); void h3650uartsetup(void); void icacheinvalidate(void); void idle(void); -#define idlehands() /* nothing to do in the runproc */ +void idlehands(void); void intrenable(int, void (*)(Ureg*, void*), void*, char*); int iprint(char*, ...); void irpower(int); diff --git a/bitsy/l.s b/bitsy/l.s index f61ecec698fd2d0beec359e742bef965599d42a8..5a009316c8254be251adb3f30ec3c313eb9b8519 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -431,3 +431,24 @@ TEXT gotolabel(SB), $-4 MOVW 4(R0), R14 /* pc */ MOVW $1, R0 RET + + +/* 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). + * + * Doze puts the machine into idle mode. Any interrupt will get it out + * at the next instruction (the RET, to be precise). + */ +TEXT _doze(SB), $-4 + MOVW $UCDRAMZERO, R1 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MCR CpPWR, 0, R0, C(CpTest), C(0x2), 2 + MOVW (R1), R0 + MCR CpPWR, 0, R0, C(CpTest), C(0x8), 2 + RET diff --git a/bitsy/mem.h b/bitsy/mem.h index f3bd62df684a3e0dfe5ca1041050fdd605cd5664..2be6e705cf9aefade4cfcc8593656738da13beb9 100644 --- a/bitsy/mem.h +++ b/bitsy/mem.h @@ -51,8 +51,10 @@ #define REGTOP 0xA8000000 /* ... */ #define FLASHZERO 0xB0000000 /* 128 meg for flash */ #define FLASHTOP 0xB8000000 /* ... */ -#define DRAMZERO 0xC0000000 /* 128 meg for memory */ +#define DRAMZERO 0xC0000000 /* 128 meg for dram */ #define DRAMTOP 0xC8000000 /* ... */ +#define UCDRAMZERO 0xC8000000 /* 128 meg for dram (uncached/unbuffered) */ +#define UCDRAMTOP 0xD0000000 /* ... */ #define NULLZERO 0xE0000000 /* 128 meg for cache flush zeroes */ #define NULLTOP 0xE8000000 /* ... */ #define USTKTOP 0x2000000 /* byte just beyond user stack */ @@ -143,6 +145,7 @@ * Coprocessors */ #define CpMMU 15 +#define CpPWR 15 /* * Internal MMU coprocessor registers diff --git a/bitsy/mmu.c b/bitsy/mmu.c index 2399b81ddc194f81df415bf30744b0e7a398118a..5d9050c3a2f141d45599696639f0d325c3987f92 100644 --- a/bitsy/mmu.c +++ b/bitsy/mmu.c @@ -79,6 +79,11 @@ mmuinit(void) | L1Cached | L1Buffered | ((PHYSDRAM0+o)&L1SectBaseMask); + /* uncached DRAM */ + for(o = 0; o < UCDRAMTOP-UCDRAMZERO; o += OneMeg) + l1table[(UCDRAMZERO+o)>>20] = L1Section | L1KernelRW| L1Domain0 + | ((PHYSDRAM0+o)&L1SectBaseMask); + /* map zeros area */ for(o = 0; o < NULLTOP-NULLZERO; o += OneMeg) l1table[(NULLZERO+o)>>20] = L1Section | L1KernelRW | L1Domain0 diff --git a/bitsy/power.c b/bitsy/power.c index 288a015551a82f6b7eb8842ed1cf8a687456f526..f44db8995b515f331585f22af89c16443b242996 100644 --- a/bitsy/power.c +++ b/bitsy/power.c @@ -5,11 +5,11 @@ #include "fns.h" #include "io.h" #include "ureg.h" -#include "init.h" #include "pool.h" /* Power management for the bitsy */ +#ifdef NOTDEF enum { pmcr_sf = 0, @@ -66,3 +66,15 @@ sa1100_power_off(void) /* enter sleep mode */ powerregs->pmcr = 1<info[' '].width; + blanktime = 3; /* minutes */ + screenwin(); } @@ -301,7 +303,12 @@ setcolor(ulong p, ulong r, ulong g, ulong b) void blankscreen(int blank) { - USED(blank); + if (blank) { + lcdpower(0); + } else { + lcdpower(1); + lcdinit(); + } } void diff --git a/bitsy/screen.h b/bitsy/screen.h index 09e6ef90babd6a70bed4466e16b7f579bf7519fc..7ae57fadeb00da4e6423b0cc37f6f9ac1337e889 100644 --- a/bitsy/screen.h +++ b/bitsy/screen.h @@ -1,6 +1,8 @@ typedef struct Cursorinfo Cursorinfo; typedef struct Cursor Cursor; +extern ulong blanktime; + struct Cursorinfo { Lock; }; diff --git a/bitsy/trap.c b/bitsy/trap.c index d0492405a33063bdd7316a3eb87997b51aaab75e..3adfcdf8f15730b03cf00f7bc821248c8ef05d4d 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -22,17 +22,15 @@ struct Intrregs *intrregs; typedef struct Vctl { Vctl* next; /* handlers on this vector */ - char name[NAMELEN]; /* of driver */ - int irq; - ulong irqbit; - void (*f)(Ureg*, void*); /* handler to call */ void* a; /* argument to call it with */ } Vctl; -static Lock vctllock; -static Vctl *vctl; +static Lock vctllock; +static Vctl *vctl[32]; +static Vctl *gpiovctl[27]; +static int gpioirqref[12]; /* * Layout at virtual address 0. @@ -41,10 +39,16 @@ typedef struct Vpage0 { void (*vectors[8])(void); ulong vtable[8]; - ulong hole[16]; + /* Doze goes here because it needs to be on a cache-line boundary */ + ulong doze[16]; } Vpage0; Vpage0 *vpage0; +void (*doze)(void); + +static void irq(Ureg*); +static void gpiointr(Ureg*, void*); + /* * set up for exceptioons */ @@ -55,8 +59,13 @@ trapinit(void) vpage0 = (Vpage0*)EVECTORS; memmove(vpage0->vectors, vectors, sizeof(vpage0->vectors)); memmove(vpage0->vtable, vtable, sizeof(vpage0->vtable)); - memset(vpage0->hole, 0, sizeof(vpage0->hole)); + + /* Move the twelve instructions of doze() to a cache-line boundary: */ + memmove(vpage0->doze, _doze, 12*sizeof(long)); wbflush(); + + /* Set the doze function pointer to the moved _doze() routine */ + doze = (void(*)(void))vpage0->doze; /* use exception vectors at 0xFFFF0000 */ mappedIvecEnable(); @@ -112,18 +121,19 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, char *name) { Vctl *v; + if(irq >= nelem(vctl) || irq < 0) + panic("intrenable"); + v = xalloc(sizeof(Vctl)); - v->irq = irq; - v->irqbit = 1<f = f; v->a = a; strncpy(v->name, name, NAMELEN-1); v->name[NAMELEN-1] = 0; lock(&vctllock); - v->next = vctl; - vctl = v; - intrregs->icmr |= v->irqbit; + v->next = vctl[irq]; + vctl[irq] = v; + intrregs->icmr |= 1<= 28) - panic("gpiointrenable %lux", bit); - if(irq > 11) + + irq = bit; + if(bit >= nelem(gpiovctl) || bit < 0) + panic("gpiointrenable"); + if(bit > 11) irq = 11; - /* it had better be input */ - if(bit & gpioregs->direction) - panic("gpiointrenable %lux of output pin", bit); + /* the pin had better be configured as input */ + if((1<direction) + panic("gpiointrenable of output pin %d", bit); - /* set edge register */ + /* create a second level vctl for the gpio edge interrupt */ + v = xalloc(sizeof(Vctl)); + v->f = f; + v->a = a; + strncpy(v->name, name, NAMELEN-1); + v->name[NAMELEN-1] = 0; + + lock(&vctllock); + v->next = gpiovctl[bit]; + gpiovctl[bit] = v; + unlock(&vctllock); + + /* set edge register to enable interrupt */ switch(edge){ case GPIOboth: - gpioregs->rising |= bit; - gpioregs->falling |= bit; + gpioregs->rising |= mask; + gpioregs->falling |= mask; break; case GPIOfalling: - gpioregs->falling |= bit; + gpioregs->falling |= mask; break; case GPIOrising: - gpioregs->rising |= bit; + gpioregs->rising |= mask; break; } - intrenable(irq, f, a, name); + if(gpioirqref[irq]++ == 0) + intrenable(irq, gpiointr, nil, "gpio edge"); } /* @@ -214,8 +240,6 @@ void trap(Ureg *ureg) { ulong inst; - int found; - Vctl *v; int user, x, rv; ulong va, fsr; char buf[ERRLEN]; @@ -231,28 +255,13 @@ trap(Ureg *ureg) else ureg->pc -= 4; - if(ureg->type == PsrMirq){ - found = 0; - va = intrregs->icip; - - /* clear any gpio edge interrupt */ - gpioregs->edgestatus = va & 0xFFF; - - for(v = vctl; v != nil; v = v->next){ - if(v->irqbit & va){ - v->f(ureg, v->a); - found = 1; - } - } - if(!found) - print("unknown interrupt: %lux\n", intrregs->icip); - goto out; - } - switch(ureg->type){ default: panic("unknown trap"); break; + case PsrMirq: + irq(ureg); + break; case PsrMabt: /* prefetch fault */ faultarm(ureg, ureg->pc, user, 1); break; @@ -325,12 +334,62 @@ trap(Ureg *ureg) break; } -out: splhi(); if(user && (up->procctl || up->nnote)) notify(ureg); } +/* + * here on irq's + */ +static void +irq(Ureg *ur) +{ + ulong va; + int i; + Vctl *v; + + va = intrregs->icip; + + for(i = 0; i < 32; i++){ + if(((1<next){ + v->f(ur, v->a); + va &= ~(1<edgestatus; + gpioregs->edgestatus = va; + +iprint("gpio intr %lux\n", va); + + for(i = 0; i < 27; i++){ + if(((1<next){ + v->f(ur, v->a); + va &= ~(1<fairness) & 0x3) == 0){ /* * once in a while, run process that's been waiting longest @@ -240,6 +239,7 @@ loop: } } } + idlehands(); } found: