From ac3b56b991691d9838a05b806cc525ae115aae18 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 5 Dec 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-12-05 --- bitsy/clock.c | 2 +- bitsy/dat.h | 30 ++++-- bitsy/devether.c | 187 +++++++++++++++++----------------- bitsy/devpcmcia.c | 248 +++++++++++++++++++++++++++++++++------------ bitsy/etherif.h | 3 + bitsy/fns.h | 12 ++- bitsy/io.h | 3 +- bitsy/l.s | 2 +- bitsy/main.c | 47 +++++++++ bitsy/sa1110dma.c | 2 +- bitsy/sa1110uart.c | 4 +- bitsy/trap.c | 57 +++++------ port/cis.c | 10 +- port/portdat.h | 2 + 14 files changed, 393 insertions(+), 216 deletions(-) diff --git a/bitsy/clock.c b/bitsy/clock.c index 19a740a4f4fc4ddf170c6c095c730a395393823c..b0963f41cc07848226431642d8e88fa140bef127 100644 --- a/bitsy/clock.c +++ b/bitsy/clock.c @@ -31,7 +31,7 @@ clockinit(void) /* enable interrupts on match register 0, turn off all others */ timerregs->ossr |= 1<<0; - intrenable(IRQtimer0, clockintr, nil, "clock"); + intrenable(IRQ, IRQtimer0, clockintr, nil, "clock"); timerregs->oier = 1<<0; /* figure out processor frequency */ diff --git a/bitsy/dat.h b/bitsy/dat.h index 83206807ced526888417d304bcabe4cb1b0d0a00..644e14b1d136d311cbfa97597ffeb571309233dc 100644 --- a/bitsy/dat.h +++ b/bitsy/dat.h @@ -4,6 +4,7 @@ typedef struct Cycintr Cycintr; typedef struct FPU FPU; typedef struct FPenv FPenv; typedef struct FPsave FPsave; +typedef struct DevConf DevConf; typedef struct Label Label; typedef struct Lock Lock; typedef struct MMU MMU; @@ -21,6 +22,8 @@ typedef struct Ureg Ureg; typedef struct Vctl Vctl; typedef struct Uart Uart; +typedef void IntrHandler(Ureg*, void*); + /* * parameters for sysproc.c */ @@ -316,6 +319,8 @@ struct Cisdat */ struct PCMslot { + RWlock; + Ref ref; long memlen; /* memory length */ @@ -325,19 +330,11 @@ struct PCMslot void *attr; /* attribute memory */ /* status */ - uchar special; /* in use for a special device */ - uchar already; /* already inited */ - uchar occupied; - uchar battery; - uchar wrprot; - uchar powered; - uchar configed; - uchar enabled; - uchar busy; + uchar occupied; /* card in the slot */ + uchar configed; /* card configured */ /* cis info */ int cisread; /* set when the cis has been read */ - ulong msec; /* time of last slotinfo call */ char verstr[512]; /* version string */ uchar cpresent; /* config registers present */ ulong caddr; /* relative address of config registers */ @@ -352,3 +349,16 @@ struct PCMslot PCMmap memmap; PCMmap attrmap; }; + +/* + * hardware info about a device + */ +struct DevConf +{ + ulong mem; /* mapped memory address */ + ulong port; /* mapped i/o regs */ + int size; /* access size */ + int itype; /* type of interrupt */ + ulong interrupt; /* interrupt number */ + char type[NAMELEN]; /* card type */ +}; diff --git a/bitsy/devether.c b/bitsy/devether.c index 7d22cebd62170d1fb45851f43f2cea4bf65168fb..aef2478165aa41ad36ca63eabfccab26664454aa 100644 --- a/bitsy/devether.c +++ b/bitsy/devether.c @@ -12,6 +12,97 @@ static Ether *etherxx[MaxEther]; +static struct { + char* type; + int (*reset)(Ether*); +} cards[MaxEther+1]; + +void +addethercard(char* t, int (*r)(Ether*)) +{ + static int ncard; + + if(ncard == MaxEther) + panic("too many ether cards"); + cards[ncard].type = t; + cards[ncard].reset = r; + ncard++; +} + +int +etherconfig(int on, char *spec, DevConf *cf) +{ + Ether *ether; + int n, ctlrno; + char name[NAMELEN], buf[128]; + char *p, *e; + + /* can't unconfigure yet */ + if(on == 0) + return -1; + + ctlrno = atoi(spec); + if(etherxx[ctlrno] != nil) + return -1; + + ether = malloc(sizeof(Ether)); + if(ether == nil) + panic("etherconfig"); + memset(ether, 0, sizeof(Ether)); + *(DevConf*)ether = *cf; + +print("looking for card type %s\n", ether->type); + for(n = 0; cards[n].type; n++){ + if(strcmp(cards[n].type, ether->type) != 0) + continue; +print("found card type %s\n", ether->type); + if(cards[n].reset(ether)) + break; + sprint(name, "ether%d", ctlrno); + + if(ether->mbps >= 100){ + netifinit(ether, name, Ntypes, 256*1024); + if(ether->oq == 0) + ether->oq = qopen(256*1024, 1, 0, 0); + } + else{ + netifinit(ether, name, Ntypes, 65*1024); + if(ether->oq == 0) + ether->oq = qopen(65*1024, 1, 0, 0); + } + if(ether->oq == 0) + panic("etherreset %s", name); + ether->alen = Eaddrlen; + memmove(ether->addr, ether->ea, Eaddrlen); + memset(ether->bcast, 0xFF, Eaddrlen); + + if(ether->interrupt != nil) + intrenable(cf->itype, cf->interrupt, ether->interrupt, ether, name); + + p = buf; + e = buf+sizeof(buf); + p = seprint(p, e, "#l%d: %s: %dMbps port 0x%luX", + ctlrno, ether->type, ether->mbps, ether->port); + if(ether->mem) + p = seprint(p, e, " addr 0x%luX", PADDR(ether->mem)); + if(ether->size) + p = seprint(p, e, " size 0x%luX", ether->size); + p = seprint(p, e, ": %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX", + ether->ea[0], ether->ea[1], ether->ea[2], + ether->ea[3], ether->ea[4], ether->ea[5]); + seprint(p, e, "\n"); + print(buf); + + etherxx[ctlrno] = ether; + return 0; + } + + free(ether); + return -1; +} + + + Chan* etherattach(char* spec) { @@ -302,23 +393,6 @@ etherbwrite(Chan* chan, Block* bp, ulong) return etheroq(ether, bp); } -static struct { - char* type; - int (*reset)(Ether*); -} cards[MaxEther+1]; - -void -addethercard(char* t, int (*r)(Ether*)) -{ - static int ncard; - - if(ncard == MaxEther) - panic("too many ether cards"); - cards[ncard].type = t; - cards[ncard].reset = r; - ncard++; -} - int parseether(uchar *to, char *from) { @@ -345,83 +419,6 @@ parseether(uchar *to, char *from) static void etherreset(void) { - Ether *ether; - int i, n, ctlrno; - char name[NAMELEN], buf[128]; - - for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){ - if(ether == 0) - ether = malloc(sizeof(Ether)); - memset(ether, 0, sizeof(Ether)); - ether->ctlrno = ctlrno; - ether->tbdf = BUSUNKNOWN; - ether->mbps = 10; - ether->minmtu = ETHERMINTU; - ether->maxmtu = ETHERMAXTU; - if(isaconfig("ether", ctlrno, ether) == 0) - continue; - for(n = 0; cards[n].type; n++){ - if(cistrcmp(cards[n].type, ether->type)) - continue; - for(i = 0; i < ether->nopt; i++){ - if(strncmp(ether->opt[i], "ea=", 3)) - continue; - if(parseether(ether->ea, ðer->opt[i][3]) == -1) - memset(ether->ea, 0, Eaddrlen); - } - if(cards[n].reset(ether)) - break; - - /* - * IRQ2 doesn't really exist, it's used to gang the interrupt - * controllers together. A device set to IRQ2 will appear on - * the second interrupt controller as IRQ9. - */ - if(ether->irq == 2) - ether->irq = 9; - snprint(name, sizeof(name), "ether%d", ctlrno); - - /* If ether->irq is less than 0, it is a hack to indicate no interrupt - * used for the second logical ethernet for the wavelan card - */ - if(ether->irq >= 0) - intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name); - - i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %lud", - ctlrno, ether->type, ether->mbps, ether->port, ether->irq); - if(ether->mem) - i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem)); - if(ether->size) - i += sprint(buf+i, " size 0x%luX", ether->size); - i += sprint(buf+i, ": %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX", - ether->ea[0], ether->ea[1], ether->ea[2], - ether->ea[3], ether->ea[4], ether->ea[5]); - sprint(buf+i, "\n"); - print(buf); - - if(ether->mbps >= 100){ - netifinit(ether, name, Ntypes, 256*1024); - if(ether->oq == 0) - ether->oq = qopen(256*1024, 1, 0, 0); - } - else{ - netifinit(ether, name, Ntypes, 65*1024); - if(ether->oq == 0) - ether->oq = qopen(65*1024, 1, 0, 0); - } - if(ether->oq == 0) - panic("etherreset %s", name); - ether->alen = Eaddrlen; - memmove(ether->addr, ether->ea, Eaddrlen); - memset(ether->bcast, 0xFF, Eaddrlen); - - etherxx[ctlrno] = ether; - ether = 0; - break; - } - } - if(ether) - free(ether); } #define POLY 0xedb88320 @@ -463,4 +460,6 @@ Dev etherdevtab = { etherbwrite, etherremove, etherwstat, + nil, /* no power management */ + etherconfig, }; diff --git a/bitsy/devpcmcia.c b/bitsy/devpcmcia.c index 94b92af394ed0421dd78f9c985795cfa25d58307..9be4df36238a94ca54bcad7c024929f08c7ee8db 100644 --- a/bitsy/devpcmcia.c +++ b/bitsy/devpcmcia.c @@ -23,6 +23,17 @@ enum Nents = 3, }; +enum +{ + /* + * configuration registers - they start at an offset in attribute + * memory found in the CIS. + */ + Rconfig= 0, + Creset= (1<<7), /* reset device */ + Clevel= (1<<6), /* level sensitive interrupt line */ +}; + #define SLOTNO(c) ((c->qid.path>>8)&0xff) #define TYPE(c) (c->qid.path&0xff) #define QID(s,t) (((s)<<8)|(t)) @@ -39,7 +50,7 @@ pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp) int slotno; Qid qid; long len; - PCMslot *pp; + PCMslot *sp; char name[NAMELEN]; if(i == DEVDOTDOT){ @@ -51,18 +62,18 @@ pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp) return -1; slotno = i/Nents; - pp = slot + slotno; + sp = slot + slotno; len = 0; switch(i%Nents){ case 0: qid.path = QID(slotno, Qmem); sprint(name, "pcm%dmem", slotno); - len = pp->memlen; + len = sp->memlen; break; case 1: qid.path = QID(slotno, Qattr); sprint(name, "pcm%dattr", slotno); - len = pp->memlen; + len = sp->memlen; break; case 2: qid.path = QID(slotno, Qctl); @@ -74,6 +85,17 @@ pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp) return 1; } +static int +bitno(ulong x) +{ + int i; + + for(i = 0; i < 8*sizeof(x); i++) + if((1<level & GPIO_OPT_IND_i) + return; + + /* sleave there, interrupt on card removal */ + intrenable(GPIOrising, bitno(GPIO_CARD_IND1_i), slotinfo, nil, "pcmcia slot1 status"); + intrenable(GPIOrising, bitno(GPIO_CARD_IND0_i), slotinfo, nil, "pcmcia slot0 status"); } static Chan* @@ -160,18 +186,25 @@ memmoves(uchar *to, uchar *from, int n) } static long -pcmread(void *a, long n, ulong off, uchar *start, ulong len) +pcmread(void *a, long n, ulong off, PCMslot *sp, uchar *start, ulong len) { + rlock(sp); + if(waserror()){ + runlock(sp); + nexterror(); + } if(off > len) return 0; if(off + n > len) n = len - off; memmoveb(a, start+off, n); + runlock(sp); + poperror(); return n; } static long -pcmctlread(void *a, long n, ulong off, PCMslot *pp) +pcmctlread(void *a, long n, ulong off, PCMslot *sp) { char *p, *buf, *e; @@ -183,10 +216,10 @@ pcmctlread(void *a, long n, ulong off, PCMslot *pp) e = p + READSTR; buf[0] = 0; - if(pp->occupied){ + if(sp->occupied){ p = seprint(p, e, "occupied\n"); - if(pp->verstr[0]) - p = seprint(p, e, "version %s\n", pp->verstr); + if(sp->verstr[0]) + p = seprint(p, e, "version %s\n", sp->verstr); } USED(p); @@ -199,70 +232,137 @@ pcmctlread(void *a, long n, ulong off, PCMslot *pp) static long pcmciaread(Chan *c, void *a, long n, vlong off) { - PCMslot *pp; + PCMslot *sp; ulong offset = off; - pp = slot + SLOTNO(c); + sp = slot + SLOTNO(c); switch(TYPE(c)){ case Qdir: return devdirread(c, a, n, 0, 0, pcmgen); case Qmem: - if(!pp->occupied) + if(!sp->occupied) error(Eio); - return pcmread(a, n, offset, pp->mem, 64*OneMeg); + return pcmread(a, n, offset, sp, sp->mem, 64*OneMeg); case Qattr: - if(!pp->occupied) + if(!sp->occupied) error(Eio); - return pcmread(a, n, offset, pp->attr, OneMeg); + return pcmread(a, n, offset, sp, sp->attr, OneMeg); case Qctl: - return pcmctlread(a, n, offset, pp); + return pcmctlread(a, n, offset, sp); } error(Ebadarg); return -1; /* not reached */ } static long -pcmwrite(void *a, long n, ulong off, uchar *start, ulong len) +pcmwrite(void *a, long n, ulong off, PCMslot *sp, uchar *start, ulong len) { + rlock(sp); + if(waserror()){ + runlock(sp); + nexterror(); + } if(off > len) error(Eio); if(off + n > len) error(Eio); memmoveb(start+off, a, n); + poperror(); + runlock(sp); return n; } static long -pcmctlwrite(char *p, long n, ulong off, PCMslot *pp) +pcmctlwrite(char *p, long n, ulong, PCMslot *sp) { - /* nothing yet */ - USED(p, n, off, pp); - error(Ebadarg); + Cmdbuf *cmd; + uchar *cp; + int index, i, dtx; + Rune r; + DevConf cf; + + cmd = parsecmd(p, n); + if(strcmp(cmd->f[0], "configure") == 0){ + wlock(sp); + if(waserror()){ + wunlock(sp); + nexterror(); + } + + /* see if driver exists and is configurable */ + if(cmd->nf < 3) + error(Ebadarg); + p = cmd->f[1]; + if(*p++ != '#') + error(Ebadarg); + p += chartorune(&r, p); + dtx = devno(r, 1); + if(dtx < 0) + error("no such device type"); + if(devtab[dtx]->config == nil) + error("not a dynamicly configurable device"); + + /* set pcmcia card configuration */ + index = 0; + if(sp->def != nil) + index = sp->def->index; + if(cmd->nf > 3){ + i = atoi(cmd->f[3]); + if(i < 0 || i >= sp->nctab) + error("bad configuration index"); + index = i; + } + if(sp->cpresent & (1<attr; + cp += sp->caddr + Rconfig; +print("writing configuration register (%lux) with index %d\n", cp, index); + *cp = index; + } + + /* configure device */ + strncpy(cf.type, cmd->f[2], sizeof(cf.type)-1); + cf.type[sizeof(cf.type)-1] = 0; + cf.mem = (ulong)sp->mem; + cf.port = (ulong)sp->regs; + cf.itype = GPIOfalling; + cf.interrupt = bitno(sp == slot ? GPIO_CARD_IRQ0_i : GPIO_CARD_IRQ1_i); + cf.size = 0; + if(devtab[dtx]->config(1, p, &cf) < 0) + error("couldn't configure device"); + + wunlock(sp); + poperror(); + + /* don't let the power turn off */ + increfp(sp); + } + free(cmd); + return 0; } static long pcmciawrite(Chan *c, void *a, long n, vlong off) { - PCMslot *pp; + PCMslot *sp; ulong offset = off; - pp = slot + SLOTNO(c); + sp = slot + SLOTNO(c); switch(TYPE(c)){ case Qmem: - if(!pp->occupied) + if(!sp->occupied) error(Eio); - return pcmwrite(a, n, offset, pp->mem, 64*OneMeg); + return pcmwrite(a, n, offset, sp, sp->mem, 64*OneMeg); case Qattr: - if(!pp->occupied) + if(!sp->occupied) error(Eio); - return pcmwrite(a, n, offset, pp->attr, OneMeg); + return pcmwrite(a, n, offset, sp, sp->attr, OneMeg); case Qctl: - if(!pp->occupied) + if(!sp->occupied) error(Eio); - return pcmctlwrite(a, n, offset, pp); + return pcmctlwrite(a, n, offset, sp); } error(Ebadarg); return -1; /* not reached */ @@ -303,71 +403,85 @@ slotinfo(Ureg*, void*) if(x & GPIO_CARD_IND0_i){ slot[0].occupied = 0; slot[0].cisread = 0; - } else if(slot[0].occupied == 0){ + } else { + if(slot[0].occupied == 0) + slot[0].cisread = 0; slot[0].occupied = 1; - slot[0].cisread = 0; } if(x & GPIO_CARD_IND1_i){ slot[1].occupied = 0; slot[1].cisread = 0; - } else if(slot[1].occupied == 0){ + } else { + if(slot[1].occupied == 0) + slot[1].cisread = 0; slot[1].occupied = 1; - slot[1].cisread = 0; } } } /* use reference card to turn cards on and off */ static void -increfp(PCMslot *pp) +increfp(PCMslot *sp) { + wlock(sp); + if(waserror()){ + wunlock(sp); + nexterror(); + } + if(incref(&pcmcia) == 1){ egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 1); + delay(200); + egpiobits(EGPIO_pcmcia_reset, 1); + delay(100); egpiobits(EGPIO_pcmcia_reset, 0); - delay(200); /* time to power up */ + delay(500); } - incref(&pp->ref); - if(pp->occupied && pp->cisread == 0) - pcmcisread(pp); + incref(&sp->ref); + slotinfo(nil, nil); + if(sp->occupied && sp->cisread == 0) + pcmcisread(sp); + + wunlock(sp); + poperror(); } static void -decrefp(PCMslot *pp) +decrefp(PCMslot *sp) { - decref(&pp->ref); + decref(&sp->ref); if(decref(&pcmcia) == 0) egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 0); } /* - * the regions are staticly mapped + * the regions are staticly masped */ static void slotmap(int slotno, ulong regs, ulong attr, ulong mem) { - PCMslot *pp; - - pp = &slot[slotno]; - pp->slotno = slotno; - pp->memlen = 64*OneMeg; - pp->msec = ~0; - pp->verstr[0] = 0; - - pp->mem = mapmem(mem, 64*OneMeg, 0); - pp->memmap.ca = 0; - pp->memmap.cea = 64*MB; - pp->memmap.isa = (ulong)mem; - pp->memmap.len = 64*OneMeg; - pp->memmap.attr = 0; - - pp->attr = mapmem(attr, OneMeg, 0); - pp->attrmap.ca = 0; - pp->attrmap.cea = MB; - pp->attrmap.isa = (ulong)attr; - pp->attrmap.len = OneMeg; - pp->attrmap.attr = 1; - - pp->regs = mapspecial(regs, 32*1024); + PCMslot *sp; + + sp = &slot[slotno]; + sp->slotno = slotno; + sp->memlen = 64*OneMeg; + sp->verstr[0] = 0; + + sp->mem = mapmem(mem, 64*OneMeg, 0); + sp->memmap.ca = 0; + sp->memmap.cea = 64*MB; + sp->memmap.isa = (ulong)mem; + sp->memmap.len = 64*OneMeg; + sp->memmap.attr = 0; + + sp->attr = mapmem(attr, OneMeg, 0); + sp->attrmap.ca = 0; + sp->attrmap.cea = MB; + sp->attrmap.isa = (ulong)attr; + sp->attrmap.len = OneMeg; + sp->attrmap.attr = 1; + + sp->regs = mapspecial(regs, 32*1024); } PCMmap* pcmmap(int slotno, ulong, int, int attr) diff --git a/bitsy/etherif.h b/bitsy/etherif.h index 0d29294f973cc65a20e5e268c3ddca0e3b655648..4ec82d303c0694d12fd985ab7933b6e07872f4e7 100644 --- a/bitsy/etherif.h +++ b/bitsy/etherif.h @@ -5,7 +5,10 @@ enum { typedef struct Ether Ether; struct Ether { + DevConf; + int ctlrno; + int tbdf; /* type+busno+devno+funcno */ int mbps; /* Mbps */ int minmtu; int maxmtu; diff --git a/bitsy/fns.h b/bitsy/fns.h index ecf005e2911ec4479da20b2cfa1dd9801db07cde..bc6417dfa1fc8aca73daedf45597a5c7682eedb0 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -10,6 +10,7 @@ int cistrcmp(char*, char*); int cistrncmp(char*, char*, int); void clockinit(void); #define coherence() +#define dcflush(a, b) void delay(int); void µdelay(int); void dmainit(void); @@ -30,7 +31,10 @@ void h3650uartsetup(void); void icacheinvalidate(void); void idle(void); void idlehands(void); -void intrenable(int, void (*)(Ureg*, void*), void*, char*); +uchar inb(ulong); +ushort ins(ulong); +ulong inl(ulong); +void intrenable(int, int, void (*)(Ureg*, void*), void*, char*); int iprint(char*, ...); void irpower(int); void lcdpower(int); @@ -49,6 +53,9 @@ ulong mmu_paddr(ulong); int µcputc(Queue*, int); void noted(Ureg*, ulong); int notify(Ureg*); +void outb(ulong, uchar); +void outs(ulong, ushort); +void outl(ulong, ulong); void pcmcisread(PCMslot*); int pcmcistuple(int, int, int, void*, int); PCMmap* pcmmap(int, ulong, int, int); @@ -62,7 +69,6 @@ void putdac(ulong); void putttb(ulong); void putpid(ulong); void qpanic(char *, ...); -void reset(void); void rs232power(int); Uart* uartsetup(PhysUart*, void*, ulong, char*); void uartspecial(Uart*, int, Queue**, Queue**, int (*)(Queue*, int)); @@ -89,5 +95,3 @@ void wbflush(void); #define PADDR(a) mmu_paddr((ulong)(a)) #define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1])) - -#define dcflush(a, b) diff --git a/bitsy/io.h b/bitsy/io.h index 15abcd2d4ead0ae64f0e76fc8edb50b50dd9ed36..6791a662535d5dea396d08019bdd38719638b7b8 100644 --- a/bitsy/io.h +++ b/bitsy/io.h @@ -110,13 +110,14 @@ enum }; /* - * edge argument for gpiointrenable + * types of interrupts */ enum { GPIOrising, GPIOfalling, GPIOboth, + IRQ, }; /* hardware registers */ diff --git a/bitsy/l.s b/bitsy/l.s index 5a009316c8254be251adb3f30ec3c313eb9b8519..0afdb8bafe088fc8f377d16e3b8d48806a22a481 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -222,7 +222,7 @@ TEXT vtable(SB), $-4 WORD $_vfiq(SB) /* FIQ, switch to svc mode */ TEXT _vrst(SB), $-4 - BL reset(SB) + BL resettrap(SB) TEXT _vsvc(SB), $-4 /* SWI */ MOVW.W R14, -4(R13) /* ureg->pc = interupted PC */ diff --git a/bitsy/main.c b/bitsy/main.c index 11572dd4e4835a94a2aeb215b989ae6990bf4339..a86c81bbb59a0963a760ab0839948a6007271828 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -43,6 +43,7 @@ main(void) clockinit(); procinit0(); initseg(); + links(); chandevreset(); pageinit(); swapinit(); @@ -430,3 +431,49 @@ flashprogpower(int on) { egpiobits(EGPIO_prog_flash, on); } + +/* here on hardware reset */ +void +resettrap(void) +{ +} + +/* + * for drivers that used to run on x86's + */ +void +outb(ulong a, uchar v) +{ + *(uchar*)a = v; + µdelay(2); +} +void +outs(ulong a, ushort v) +{ + *(ushort*)a = v; + µdelay(2); +} +void +outl(ulong a, ulong v) +{ + *(ulong*)a = v; + µdelay(2); +} +uchar +inb(ulong a) +{ + µdelay(2); + return *(uchar*)a; +} +ushort +ins(ulong a) +{ + µdelay(2); + return *(ushort*)a; +} +ulong +inl(ulong a) +{ + µdelay(2); + return *(ulong*)a; +} diff --git a/bitsy/sa1110dma.c b/bitsy/sa1110dma.c index 3d545b6220ca3e95becfd50a16b607ceb7a27f7c..1a5352f8beb27062e0e694a7cfdcbc4efe79fd1d 100644 --- a/bitsy/sa1110dma.c +++ b/bitsy/sa1110dma.c @@ -74,7 +74,7 @@ dmainit(void) { if (debug) print("dma: dmaalloc registers 0x%ux mapped at 0x%p\n", DMAREGS, dmaregs); for (i = 0; i < NDMA; i++) { - intrenable(IRQdma0+i, dmaintr, &dmaregs[i], "DMA"); + intrenable(IRQ, IRQdma0+i, dmaintr, &dmaregs[i], "DMA"); } } diff --git a/bitsy/sa1110uart.c b/bitsy/sa1110uart.c index 0c2e285df6cb2b0d73f2ef295e2565007280b9bd..68ecec5443f9769c65cf9ab855ee31da6bd18111 100644 --- a/bitsy/sa1110uart.c +++ b/bitsy/sa1110uart.c @@ -424,7 +424,7 @@ sa1100_uartsetup(int console) /* external serial port (eia0) */ uart3regs = mapspecial(UART3REGS, 64); p = uartsetup(&sa1100_uart, uart3regs, ClockFreq, "serialport3"); - intrenable(IRQuart3, sa1100_uartintr, p, p->name); + intrenable(IRQ, IRQuart3, sa1100_uartintr, p, p->name); /* set eia0 up as a console */ if(console) @@ -436,5 +436,5 @@ sa1100_uartsetup(int console) uart1regs = mapspecial(UART1REGS, 64); p = uartsetup(&sa1100_uart, uart1regs, ClockFreq, "serialport1"); uartspecial(p, 115200, 0, 0, µcputc); - intrenable(IRQuart1b, sa1100_uartintr, p, p->name); + intrenable(IRQ, IRQuart1b, sa1100_uartintr, p, p->name); } diff --git a/bitsy/trap.c b/bitsy/trap.c index 3adfcdf8f15730b03cf00f7bc821248c8ef05d4d..c80ce294d2aeb64deee1c9cd380ce5d97e37b504 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -114,10 +114,10 @@ warnregs(Ureg *ur, char *tag) } /* - * enable an interrupt and attach a function to it + * enable an irq interrupt */ void -intrenable(int irq, void (*f)(Ureg*, void*), void* a, char *name) +irqenable(int irq, IntrHandler *f, void* a, char *name) { Vctl *v; @@ -138,28 +138,29 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, char *name) } /* - * enable an interrupt on gpio line. edge is encoded as follows + * enable an interrupt */ void -gpiointrenable(ulong mask, int edge, void (*f)(Ureg*, void*), void* a, char *name) +intrenable(int type, int which, IntrHandler *f, void* a, char *name) { - int irq, bit; + int irq; Vctl *v; - /* figure out which bit */ - for(bit = 0; bit < 32; bit++) - if((1<= nelem(gpiovctl) || bit < 0) + /* from here down, it must be a GPIO edge interrupt */ + irq = which; + if(which >= nelem(gpiovctl) || which < 0) panic("gpiointrenable"); - if(bit > 11) + if(which > 11) irq = 11; /* the pin had better be configured as input */ - if((1<direction) - panic("gpiointrenable of output pin %d", bit); + if((1<direction) + panic("gpiointrenable of output pin %d", which); /* create a second level vctl for the gpio edge interrupt */ v = xalloc(sizeof(Vctl)); @@ -169,26 +170,27 @@ gpiointrenable(ulong mask, int edge, void (*f)(Ureg*, void*), void* a, char *nam v->name[NAMELEN-1] = 0; lock(&vctllock); - v->next = gpiovctl[bit]; - gpiovctl[bit] = v; + v->next = gpiovctl[which]; + gpiovctl[which] = v; unlock(&vctllock); /* set edge register to enable interrupt */ - switch(edge){ + switch(type){ case GPIOboth: - gpioregs->rising |= mask; - gpioregs->falling |= mask; + gpioregs->rising |= 1<falling |= 1<falling |= mask; + gpioregs->falling |= 1<rising |= mask; + gpioregs->rising |= 1<edgestatus; gpioregs->edgestatus = va; -iprint("gpio intr %lux\n", va); - for(i = 0; i < 27; i++){ if(((1<verstr)-1; i++){ if(readc(cis, &c) != 1) return; if(c == 0) - c = '\n'; + c = ';'; + if(c == '\n') + c = ';'; if(c == 0xff) break; + if(c == ';' && last == ';') + continue; pp->verstr[i] = c; + last = c; } pp->verstr[i] = 0; } diff --git a/port/portdat.h b/port/portdat.h index 6e95d788e738788c7bdbec1f026cf48d3e1fff3f..ea8c51d10620b846e0edcb0474836808224c5f92 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -9,6 +9,7 @@ typedef struct Dirtab Dirtab; typedef struct Egrp Egrp; typedef struct Evalue Evalue; typedef struct Fgrp Fgrp; +typedef struct DevConf DevConf; typedef struct Image Image; typedef struct List List; typedef struct Log Log; @@ -194,6 +195,7 @@ struct Dev void (*remove)(Chan*); void (*wstat)(Chan*, char*); void (*power)(int); /* power mgt: power(1) → on, power (0) → off */ + int (*config)(int, char*, DevConf*); }; struct Dirtab