M bitsy/clock.c => bitsy/clock.c +9 -0
@@ 24,6 24,8 @@ static void clockintr(Ureg*, void*);
void
clockinit(void)
{
+ ulong x;
+
/* map the clock registers */
timerregs = mapspecial(OSTIMERREGS, 32);
@@ 32,6 34,13 @@ clockinit(void)
intrenable(IRQtimer0, clockintr, nil, "clock");
timerregs->oier = 1<<0;
+ /* figure out processor frequency */
+ x = powerregs->ppcr & 0x1f;
+ conf.hz = ClockFreq*(x*4+16);
+ conf.mhz = (conf.hz+499999)/1000000;
+
+ print("%lud MHZ WeakARM\n", conf.mhz);
+
/* post interrupt 1/HZ secs from now */
timerregs->osmr[0] = timerregs->oscr + ClockFreq/HZ;
M bitsy/dat.h => bitsy/dat.h +190 -18
@@ 1,19 1,25 @@
-typedef struct Conf Conf;
-typedef struct FPU FPU;
-typedef struct FPenv FPenv;
-typedef struct FPsave FPsave;
-typedef struct Label Label;
-typedef struct Lock Lock;
-typedef struct MMU MMU;
-typedef struct Mach Mach;
-typedef struct Notsave Notsave;
-typedef struct Page Page;
-typedef struct PMMU PMMU;
-typedef struct Proc Proc;
-typedef struct Ureg Ureg;
-typedef struct Vctl Vctl;
-typedef struct PhysUart PhysUart;
-typedef struct Uart Uart;
+typedef struct Cisdat Cisdat;
+typedef struct Conf Conf;
+typedef struct Cycintr Cycintr;
+typedef struct FPU FPU;
+typedef struct FPenv FPenv;
+typedef struct FPsave FPsave;
+typedef struct Label Label;
+typedef struct Lock Lock;
+typedef struct MMU MMU;
+typedef struct Mach Mach;
+typedef struct Notsave Notsave;
+typedef struct Page Page;
+typedef struct PCMmap PCMmap;
+typedef struct PCMslot PCMslot;
+typedef struct PCMconftab PCMconftab;
+typedef struct PhysUart PhysUart;
+typedef struct PMMU PMMU;
+typedef struct Proc Proc;
+typedef struct Uart Uart;
+typedef struct Ureg Ureg;
+typedef struct Vctl Vctl;
+typedef struct Uart Uart;
/*
* parameters for sysproc.c
@@ 68,6 74,8 @@ struct Conf
int monitor;
ulong ialloc; /* bytes available for interrupt time allocation */
ulong pipeqsize; /* size in bytes of pipe queues */
+ ulong hz; /* processor cycle freq */
+ ulong mhz;
};
/*
@@ 141,8 149,6 @@ struct Mach
int stack[1];
};
-typedef struct Cycintr Cycintr;
-
/*
* fasttick timer interrupts
*/
@@ 179,3 185,169 @@ enum
{
OneMeg= 1024*1024,
};
+
+/*
+ * routines to access UART hardware
+ */
+struct PhysUart
+{
+ void (*enable)(Uart*, int);
+ void (*disable)(Uart*);
+ void (*kick)(Uart*);
+ void (*intr)(Ureg*, void*);
+ void (*dobreak)(Uart*, int);
+ void (*baud)(Uart*, int);
+ void (*bits)(Uart*, int);
+ void (*stop)(Uart*, int);
+ void (*parity)(Uart*, int);
+ void (*modemctl)(Uart*, int);
+ void (*rts)(Uart*, int);
+ void (*dtr)(Uart*, int);
+ long (*status)(Uart*, void*, long, long);
+};
+
+enum {
+ Stagesize= 1024
+};
+
+/*
+ * software UART
+ */
+struct Uart
+{
+ QLock;
+ int type;
+ int dev;
+ int opens;
+ void *regs;
+ PhysUart *phys;
+
+ int enabled;
+ Uart *elist; /* next enabled interface */
+ char name[NAMELEN];
+
+ uchar sticky[4]; /* sticky write register values */
+ ulong freq; /* clock frequency */
+ uchar mask; /* bits/char */
+ int baud; /* baud rate */
+
+ int parity; /* parity errors */
+ int frame; /* framing errors */
+ int overrun; /* rcvr overruns */
+
+ /* buffers */
+ int (*putc)(Queue*, int);
+ Queue *iq;
+ Queue *oq;
+
+ uchar istage[Stagesize];
+ uchar *iw;
+ uchar *ir;
+ uchar *ie;
+
+ Lock tlock; /* transmit */
+ uchar ostage[Stagesize];
+ uchar *op;
+ uchar *oe;
+
+ int modem; /* hardware flow control on */
+ int xonoff; /* software flow control on */
+ int blocked;
+ int cts, dsr, dcd, dcdts; /* keep track of modem status */
+ int ctsbackoff;
+ int hup_dsr, hup_dcd; /* send hangup upstream? */
+ int dohup;
+
+ int kinuse; /* device in use by kernel */
+
+ Rendez r;
+};
+
+/*
+ * PCMCIA structures known by both port/cis.c and the pcmcia driver
+ */
+
+/*
+ * Map between ISA memory space and PCMCIA card memory space.
+ */
+struct PCMmap {
+ ulong ca; /* card address */
+ ulong cea; /* card end address */
+ ulong isa; /* local virtual address */
+ int len; /* length of the ISA area */
+ int attr; /* attribute memory */
+};
+
+/*
+ * a PCMCIA configuration entry
+ */
+struct PCMconftab
+{
+ int index;
+ ushort irqs; /* legal irqs */
+ uchar irqtype;
+ uchar bit16; /* true for 16 bit access */
+ struct {
+ ulong start;
+ ulong len;
+ } io[16];
+ int nio;
+ uchar vpp1;
+ uchar vpp2;
+ uchar memwait;
+ ulong maxwait;
+ ulong readywait;
+ ulong otherwait;
+};
+
+/*
+ * For walking a PCMCIA card's information structure
+ */
+struct Cisdat
+{
+ uchar *cisbase;
+ int cispos;
+ int cisskip;
+ int cislen;
+};
+
+/*
+ * PCMCIA card slot
+ */
+struct PCMslot
+{
+ Ref;
+
+ long memlen; /* memory length */
+ uchar slotno; /* slot number */
+ void *regs; /* i/o registers */
+ void *mem; /* memory */
+ 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;
+
+ /* cis info */
+ ulong msec; /* time of last slotinfo call */
+ char verstr[512]; /* version string */
+ uchar cpresent; /* config registers present */
+ ulong caddr; /* relative address of config registers */
+ int nctab; /* number of config table entries */
+ PCMconftab ctab[8];
+ PCMconftab *def; /* default conftab */
+
+ /* for walking through cis */
+ Cisdat;
+
+ /* maps are fixed */
+ PCMmap memmap;
+ PCMmap attrmap;
+};
M bitsy/devpcmcia.c => bitsy/devpcmcia.c +142 -83
@@ 27,6 27,11 @@ enum
#define TYPE(c) (c->qid.path&0xff)
#define QID(s,t) (((s)<<8)|(t))
+static void increfp(PCMslot*);
+static void decrefp(PCMslot*);
+static void slotmap(int, ulong, ulong, ulong);
+static void slottiming(int, int, int, int, int);
+
static int
pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp)
{
@@ 68,94 73,19 @@ pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp)
return 1;
}
-static void
-slotinfo(void)
-{
- ulong x = gpioregs->level;
-
- if(x & GPIO_OPT_IND_i){
- /* no expansion pack */
- slot[0].occupied = 0;
- slot[1].occupied = 0;
- } else {
- slot[0].occupied = (x & GPIO_CARD_IND0_i) == 0;
- slot[1].occupied = (x & GPIO_CARD_IND1_i) == 0;
- }
-}
-
-static void
-increfp(PCMslot *pp)
-{
- if(incref(&pcmcia) == 1)
- exppackpower(1);
- lock(pp);
- if(pp->ref++ == 0)
- ;
- unlock(pp);
- slotinfo();
-}
-static void
-decrefp(PCMslot *pp)
-{
- slotinfo();
- lock(pp);
- if(pp->ref-- == 1)
- ;
- unlock(pp);
- if(decref(&pcmcia) == 0)
- exppackpower(0);
-}
-
-/*
- * get a map for pc card region, return corrected len
- */
-PCMmap*
-pcmmap(int slotno, ulong, int, int attr)
-{
- if(slotno > nslot)
- panic("pcmmap");
- if(attr)
- return &slot[slotno].attrmap;
- else
- return &slot[slotno].memmap;
-}
-void
-pcmunmap(int, PCMmap*)
-{
-}
-
/*
- * map in the space for the cards
+ * set up the cards, default timing is 300 ns
*/
static void
pcmciareset(void)
{
- int j;
- PCMslot *pp;
+ /* staticly map the whole area */
+ slotmap(0, PHYSPCM0REGS, PYHSPCM0ATTR, PYHSPCM0MEM);
+ slotmap(1, PHYSPCM1REGS, PYHSPCM1ATTR, PYHSPCM1MEM);
- for(j = 0; j < nslot; j++){
- pp = &slot[j];
- pp->slotno = j;
- pp->memlen = 64*OneMeg;
- pp->msec = ~0;
- pp->verstr[0] = 0;
-
- pp->mem = mapmem(j == 0 ? PYHSPCM0MEM : PYHSPCM1MEM, 64*OneMeg);
- pp->memmap.ca = 0;
- pp->memmap.cea = 64*MB;
- pp->memmap.isa = (ulong)pp->mem;
- pp->memmap.len = 64*OneMeg;
- pp->memmap.attr = 0;
-
- pp->attr = mapmem(j == 0 ? PYHSPCM0ATTR : PYHSPCM1ATTR, OneMeg);
- pp->attrmap.ca = 0;
- pp->attrmap.cea = 64*MB;
- pp->attrmap.isa = (ulong)pp->attr;
- pp->attrmap.len = OneMeg;
- pp->attrmap.attr = 1;
-
- pp->regs = mapspecial(j == 0 ? PHYSPCM0REGS : PHYSPCM1REGS, 32*1024);
- }
+ /* set timing to the default, 300 */
+ slottiming(0, 300, 300, 300, 0);
+ slottiming(1, 300, 300, 300, 0);
}
static Chan*
@@ 231,7 161,7 @@ pcmread(void *a, long n, ulong off, uchar *start, ulong len)
return 0;
if(off + n > len)
n = len - off;
- memmoves(a, start+off, n);
+ memmoveb(a, start+off, n);
return n;
}
@@ 353,3 283,132 @@ Dev pcmciadevtab = {
devremove,
devwstat,
};
+
+/* see what's there */
+static void
+slotinfo(void)
+{
+ ulong x = gpioregs->level;
+
+ if(x & GPIO_OPT_IND_i){
+ /* no expansion pack */
+ slot[0].occupied = 0;
+ slot[1].occupied = 0;
+ } else {
+ slot[0].occupied = (x & GPIO_CARD_IND0_i) == 0;
+ slot[1].occupied = (x & GPIO_CARD_IND1_i) == 0;
+ }
+}
+
+/* use reference card to turn cards on and off */
+static void
+increfp(PCMslot *pp)
+{
+ if(incref(&pcmcia) == 1){
+ egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 1);
+ egpiobits(EGPIO_pcmcia_reset, 0);
+ delay(100); /* time to power up */
+ }
+
+ incref(pp);
+
+ slotinfo();
+}
+
+static void
+decrefp(PCMslot *pp)
+{
+ slotinfo();
+ decref(pp);
+ if(decref(&pcmcia) == 0)
+ egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 0);
+}
+
+/*
+ * the regions are staticly mapped
+ */
+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)pp->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)pp->attr;
+ pp->attrmap.len = OneMeg;
+ pp->attrmap.attr = 1;
+
+ pp->regs = mapspecial(regs, 32*1024);
+}
+PCMmap*
+pcmmap(int slotno, ulong, int, int attr)
+{
+ if(slotno > nslot)
+ panic("pcmmap");
+ if(attr)
+ return &slot[slotno].attrmap;
+ else
+ return &slot[slotno].memmap;
+}
+void
+pcmunmap(int, PCMmap*)
+{
+}
+
+/*
+ * setup card timings
+ * times are in ns
+ * count = ceiling[access-time/(2*3*T)] - 1, where T is a processor cycle
+ *
+ */
+static int
+ns2count(int ns)
+{
+ ulong y;
+
+ /* get 100 times cycle time */
+ y = 100000000/(conf.hz/1000);
+
+ /* get 10 times ns/(cycle*6) */
+ y = (1000*ns)/(6*y);
+
+ /* round up */
+ y += 9;
+ y /= 10;
+
+ /* subtract 1 */
+ return y-1;
+}
+static void
+slottiming(int slotno, int tio, int tattr, int tmem, int fast)
+{
+ ulong x;
+
+ x = 0;
+ if(fast)
+ x |= 1<<MECR_fast0;
+ x |= ns2count(tio) << MECR_io0;
+ x |= ns2count(tattr) << MECR_attr0;
+ x |= ns2count(tmem) << MECR_mem0;
+ if(slotno == 0){
+ x |= memconfregs->mecr & 0xffff0000;
+ } else {
+ x <<= 16;
+ x |= memconfregs->mecr & 0xffff;
+ }
+ memconfregs->mecr = x;
+}
M bitsy/devuart.c => bitsy/devuart.c +8 -0
@@ 8,6 8,14 @@
#include "../port/netif.h"
+enum
+{
+ Nuart = 4,
+
+ /* soft flow control chars */
+ CTLS= 023,
+ CTLQ= 021,
+};
static Uart* uart[Nuart];
static int nuart;
M bitsy/devuda1341.c => bitsy/devuda1341.c +39 -40
@@ 19,7 19,7 @@
#include "io.h"
#include "sa1110dma.h"
-static int debug = 0;
+static int debug = 2;
/*
* GPIO based L3 bus support.
@@ 417,7 417,7 @@ audioqnotempty(void *x)
{
IOstate *s = x;
- return dmaidle(s->dma) || s->emptying != s->next;
+ return dmaidle(s->dma) || s->emptying != s->current;
}
static int
@@ 428,10 428,17 @@ audioqnotfull(void *x)
return dmaidle(s->dma) || s->filling != s->current;
}
+SSPregs *sspregs;
+MCPregs *mcpregs;
+
static void
audioinit(void)
{
- /* do nothing */
+ /* Turn MCP operations off */
+ mcpregs = mapspecial(MCPREGS, 0x34);
+ mcpregs->status &= ~(1<<16);
+
+ sspregs = mapspecial(SSPREGS, 32);
}
uchar status0 = 0x22;
@@ 464,8 471,6 @@ enable(void)
/* Enable the audio power */
audiopower(1);
- amplifierpower(1);
- audiomute(0);
/* external clock configured for 44100 samples/sec */
gpioregs->set = GPIO_CLK_SET0_o;
@@ 577,6 582,8 @@ mxvolume(void) {
static void
outenable(void) {
/* turn on DAC, set output gain switch */
+ amplifierpower(1);
+ audiomute(0);
status1 |= 0x41;
L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1);
/* set volume */
@@ 591,6 598,8 @@ outenable(void) {
static void
outdisable(void) {
/* turn off DAC, clear output gain switch */
+ audiomute(1);
+ amplifierpower(0);
status1 &= ~0x41;
L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1);
if (debug) {
@@ 683,22 692,15 @@ static void
audiointr(void *x, ulong ndma) {
IOstate *s = x;
- if (s == &audio.o) {
- /* Only interrupt routine touches s->current */
- if (debug > 1) iprint("#A: audio interrupt @%p\n", s->current);
- s->current++;
- if (s->current == &s->buf[Nbuf])
- s->current = &s->buf[0];
- if (ndma > 0)
+ if (debug > 1) iprint("#A: audio interrupt @%p\n", s->current);
+ /* Only interrupt routine touches s->current */
+ s->current++;
+ if (s->current == &s->buf[Nbuf])
+ s->current = &s->buf[0];
+ if (ndma > 0) {
+ if (s == &audio.o)
sendaudio(s);
- } else if (s == &audio.i) {
- /* Only interrupt routine touches s->current */
- if (debug > 1) iprint("#A: audio interrupt @%p\n", s->current);
- s->current->nbytes = Bufsize;
- s->current++;
- if (s->current == &s->buf[Nbuf])
- s->current = &s->buf[0];
- if (ndma > 0)
+ else if (s == &audio.i)
recvaudio(s);
}
wakeup(&s->vous);
@@ 723,9 725,10 @@ audiostat(Chan *c, char *db)
}
static Chan*
-audioopen(Chan *c, int omode)
+audioopen(Chan *c, int mode)
{
IOstate *s;
+ int omode = mode;
switch(c->qid.path & ~CHDIR) {
default:
@@ 741,8 744,7 @@ audioopen(Chan *c, int omode)
case Qaudio:
omode = (omode & 0x7) + 1;
-// if (omode & ~(Aread | Awrite))
- if (omode & ~(Awrite))
+ if (omode & ~(Aread | Awrite))
error(Ebadarg);
qlock(&audio);
if(audio.amode & omode){
@@ 754,20 756,17 @@ audioopen(Chan *c, int omode)
if (omode & Aread) {
inenable();
s = &audio.i;
- /* read */
audio.amode |= Aread;
- if(audio.i.bufinit == 0)
+ if(s->bufinit == 0)
bufinit(s);
setempty(s);
+ s->emptying = &s->buf[Nbuf-1];
s->chan = c;
s->dma = dmaalloc(0, 0, 4, 2, SSPRecvDMA, Port4SSP, audiointr, (void*)s);
}
- if (omode & 0x2) {
+ if (omode & Awrite) {
outenable();
s = &audio.o;
- /* write */
-// amplifierpower(1);
-// audiomute(0);
audio.amode |= Awrite;
if(s->bufinit == 0)
bufinit(s);
@@ 781,8 780,8 @@ audioopen(Chan *c, int omode)
if (debug) print("#A: open done\n");
break;
}
- c = devopen(c, omode, audiodir, nelem(audiodir), devgen);
- c->mode = openmode(omode);
+ c = devopen(c, mode, audiodir, nelem(audiodir), devgen);
+ c->mode = openmode(mode);
c->flag |= COPEN;
c->offset = 0;
@@ 892,15 891,22 @@ audioread(Chan *c, void *v, long n, vlong off)
if (debug > 1) print("#A: read %ld\n", n);
if((audio.amode & Aread) == 0)
error(Emode);
- s = &audio.o;
+ s = &audio.i;
qlock(s);
if(waserror()){
qunlock(s);
nexterror();
}
while(n > 0) {
+ if(s->emptying->nbytes == 0) {
+ if (debug > 1) print("#A: emptied @%p\n", s->emptying);
+ recvaudio(s);
+ s->emptying++;
+ if (s->emptying == &s->buf[Nbuf])
+ s->emptying = s->buf;
+ }
/* wait if dma in progress */
- while (!dmaidle(s->dma) && s->emptying == s->next) {
+ while (!dmaidle(s->dma) && s->emptying == s->current) {
if (debug > 1) print("#A: sleep\n");
sleep(&s->vous, audioqnotempty, s);
}
@@ 913,13 919,6 @@ audioread(Chan *c, void *v, long n, vlong off)
s->emptying->nbytes -= m;
n -= m;
p += m;
- if(s->emptying->nbytes == 0) {
- if (debug > 1) print("#A: emptied @%p\n", s->emptying);
- s->emptying++;
- if (s->emptying == &s->buf[Nbuf])
- s->emptying = s->buf;
- recvaudio(s);
- }
}
poperror();
qunlock(s);
M bitsy/fns.h => bitsy/fns.h +1 -1
@@ 33,7 33,7 @@ void intrenable(int, void (*)(Ureg*, void*), void*, char*);
int iprint(char*, ...);
void irpower(int);
void lcdpower(int);
-void* mapmem(ulong, int);
+void* mapmem(ulong, int, int);
void mappedIvecEnable(void);
void mappedIvecDisable(void);
void* mapspecial(ulong, int);
M bitsy/io.h => bitsy/io.h +56 -161
@@ 1,8 1,12 @@
/*
* Definitions for IO devices. Used only in C.
*/
-typedef struct Uartregs Uartregs;
-Uartregs *uart3regs;
+
+enum
+{
+ /* hardware counter frequency */
+ ClockFreq= 3686400,
+};
/*
* IRQ's defined by SA1100
@@ 105,89 109,17 @@ enum
GPIO_32_768kHz_o= 1<<27, /* 32.768 kHz clock (O, RTC) */
};
-enum
-{
- /* hardware counter frequency */
- ClockFreq= 3686400,
- Stagesize= 1024,
- Nuart = 4,
-
- /* soft flow control chars */
- CTLS= 023,
- CTLQ= 021,
-};
-
-typedef struct PhysUart PhysUart;
-typedef struct Uart Uart;
-
-/* link twixt hardware and software */
-struct PhysUart
-{
- void (*enable)(Uart*, int);
- void (*disable)(Uart*);
- void (*kick)(Uart*);
- void (*intr)(Ureg*, void*);
- void (*dobreak)(Uart*, int);
- void (*baud)(Uart*, int);
- void (*bits)(Uart*, int);
- void (*stop)(Uart*, int);
- void (*parity)(Uart*, int);
- void (*modemctl)(Uart*, int);
- void (*rts)(Uart*, int);
- void (*dtr)(Uart*, int);
- long (*status)(Uart*, void*, long, long);
-};
-
-/* software representation */
-struct Uart
+/* hardware registers */
+typedef struct Uartregs Uartregs;
+struct Uartregs
{
- QLock;
- int type;
- int dev;
- int opens;
- void *regs;
- PhysUart *phys;
-
- int enabled;
- Uart *elist; /* next enabled interface */
- char name[NAMELEN];
-
- uchar sticky[4]; /* sticky write register values */
- ulong freq; /* clock frequency */
- uchar mask; /* bits/char */
- int baud; /* baud rate */
-
- int parity; /* parity errors */
- int frame; /* framing errors */
- int overrun; /* rcvr overruns */
-
- /* buffers */
- int (*putc)(Queue*, int);
- Queue *iq;
- Queue *oq;
-
- uchar istage[Stagesize];
- uchar *iw;
- uchar *ir;
- uchar *ie;
-
- Lock tlock; /* transmit */
- uchar ostage[Stagesize];
- uchar *op;
- uchar *oe;
-
- int modem; /* hardware flow control on */
- int xonoff; /* software flow control on */
- int blocked;
- int cts, dsr, dcd, dcdts; /* keep track of modem status */
- int ctsbackoff;
- int hup_dsr, hup_dcd; /* send hangup upstream? */
- int dohup;
-
- int kinuse; /* device in use by kernel */
-
- Rendez r;
+ ulong ctl[4];
+ ulong dummya;
+ ulong data;
+ ulong dummyb;
+ ulong status[2];
};
+Uartregs *uart3regs;
/* general purpose I/O lines control registers */
typedef struct GPIOregs GPIOregs;
@@ 266,90 198,53 @@ struct MCPregs {
extern MCPregs *mcpregs;
/*
- * PCMCIA support code.
- */
-
-typedef struct PCMmap PCMmap;
-typedef struct PCMslot PCMslot;
-typedef struct PCMconftab PCMconftab;
-typedef struct Cisdat Cisdat;
-
-/*
- * Map between ISA memory space and PCMCIA card memory space.
+ * memory configuration
*/
-struct PCMmap {
- ulong ca; /* card address */
- ulong cea; /* card end address */
- ulong isa; /* local virtual address */
- int len; /* length of the ISA area */
- int attr; /* attribute memory */
-};
-
-/* configuration table entry */
-struct PCMconftab
+enum
{
- int index;
- ushort irqs; /* legal irqs */
- uchar irqtype;
- uchar bit16; /* true for 16 bit access */
- struct {
- ulong start;
- ulong len;
- } io[16];
- int nio;
- uchar vpp1;
- uchar vpp2;
- uchar memwait;
- ulong maxwait;
- ulong readywait;
- ulong otherwait;
+ /* bit shifts for pcmcia access time counters */
+ MECR_io0= 0,
+ MECR_attr0= 5,
+ MECR_mem0= 10,
+ MECR_fast0= 11,
+ MECR_io1= MECR_io0+16,
+ MECR_attr1= MECR_attr0+16,
+ MECR_mem1= MECR_mem0+16,
+ MECR_fast1= MECR_fast0+16,
};
-/* cis memory walking */
-struct Cisdat
+typedef struct MemConfRegs MemConfRegs;
+struct MemConfRegs
{
- uchar *cisbase;
- int cispos;
- int cisskip;
- int cislen;
+ ulong mdcnfg; /* dram */
+ ulong mdcas00; /* dram banks 0/1 */
+ ulong mdcas01;
+ ulong mdcas02;
+ ulong msc0; /* static */
+ ulong msc1;
+ ulong mecr; /* pcmcia */
+ ulong mdrefr; /* dram refresh */
+ ulong mdcas20; /* dram banks 2/3 */
+ ulong mdcas21;
+ ulong mdcas22;
+ ulong msc2; /* static */
+ ulong smcnfg; /* SMROM config */
};
+extern MemConfRegs *memconfregs;
-/* a card slot */
-struct PCMslot
+/*
+ * power management
+ */
+typedef struct PowerRegs PowerRegs;
+struct PowerRegs
{
- Lock;
- int ref;
-
- long memlen; /* memory length */
- uchar slotno; /* slot number */
- void *regs; /* i/o registers */
- void *mem; /* memory */
- 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;
-
- /* cis info */
- ulong msec; /* time of last slotinfo call */
- char verstr[512]; /* version string */
- uchar cpresent; /* config registers present */
- ulong caddr; /* relative address of config registers */
- int nctab; /* number of config table entries */
- PCMconftab ctab[8];
- PCMconftab *def; /* default conftab */
-
- /* for walking through cis */
- Cisdat;
-
- /* maps are fixed */
- PCMmap memmap;
- PCMmap attrmap;
+ ulong pmcr;
+ ulong pssr;
+ ulong pspr;
+ ulong pwer;
+ ulong pcfr;
+ ulong ppcr;
+ ulong pgsr;
+ ulong posr;
};
+extern PowerRegs *powerregs;
M bitsy/main.c => bitsy/main.c +19 -37
@@ 13,11 13,6 @@ Proc *up;
Conf conf;
int noprint;
-static void gpioinit(void);
-static void ppcinit(void);
-static void sspinit(void);
-static void mcpinit(void);
-
void
main(void)
{
@@ 38,10 33,7 @@ main(void)
confinit();
xinit();
mmuinit();
- gpioinit();
- ppcinit();
- mcpinit();
- sspinit();
+ machinit();
trapinit();
sa1100_uartsetup(1);
rs232power(1);
@@ 361,10 353,17 @@ confinit(void)
GPIOregs *gpioregs;
ulong *egpioreg = (ulong*)EGPIOREGS;
+PPCregs *ppcregs;
+MemConfRegs *memconfregs;
+PowerRegs *powerregs;
-static void
-gpioinit(void)
+/*
+ * configure the machine
+ */
+void
+machinit(void)
{
+ /* set direction of SA1110 io pins and select alternate functions for some */
gpioregs = mapspecial(GPIOREGS, 32);
gpioregs->direction =
GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
@@ 379,32 378,23 @@ gpioinit(void)
|GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
|GPIO_SSP_CLK_i;
+ /* map in special H3650 io pins */
egpioreg = mapspecial(EGPIOREGS, 4);
-}
-
-PPCregs *ppcregs;
-static void
-ppcinit(void) {
+ /* map in peripheral pin controller (ssp will need it) */
ppcregs = mapspecial(PPCREGS, 32);
-}
-MCPregs *mcpregs;
+ /* SA1110 power management */
+ powerregs = mapspecial(POWERREGS, 32);
-static void
-mcpinit(void) {
- mcpregs = mapspecial(MCPREGS, 0x34);
- mcpregs->status &= ~(1<<16);
- /* Turn MCP operations off */
+ /* memory configuraton */
+ memconfregs = mapspecial(MEMCONFREGS, 32);
}
-SSPregs *sspregs;
-
-static void
-sspinit(void) {
- sspregs = mapspecial(SSPREGS, 32);
-}
+/*
+ * manage egpio bits
+ */
static ulong egpiosticky;
void
@@ 458,11 448,3 @@ flashprogpower(int on)
{
egpiobits(EGPIO_prog_flash, on);
}
-
-void
-exppackpower(int on)
-{
- egpiobits(EGPIO_exp_full_power|EGPIO_exp_nvram_power, on);
- if(on)
- delay(100);
-}
M bitsy/mem.h => bitsy/mem.h +5 -3
@@ 94,7 94,6 @@
/*
* peripheral control module physical addresses
*/
-#define LCDREGS 0xB0100000 /* display */
#define USBREGS 0x80000000 /* serial port 0 - USB */
#define UART1REGS 0x80010000 /* serial port 1 - UART */
#define GPCLKREGS 0x80020060 /* serial port 1 - general purpose clock */
@@ 103,10 102,13 @@
#define UART3REGS 0x80050000 /* serial port 3 - RS232 UART */
#define MCPREGS 0x80060000 /* serial port 4 - multimedia comm port */
#define SSPREGS 0x80070060 /* serial port 4 - synchronous serial port */
-#define PPCREGS 0x90060000 /* peripheral pin controller */
+#define OSTIMERREGS 0x90000000 /* operating system timer registers */
+#define POWERREGS 0x90020000 /* power management */
#define GPIOREGS 0x90040000 /* 28 general purpose IO pins */
#define INTRREGS 0x90050000 /* interrupt registers */
-#define OSTIMERREGS 0x90000000 /* operating system timer registers */
+#define PPCREGS 0x90060000 /* peripheral pin controller */
+#define MEMCONFREGS 0xA0000000 /* memory configuration */
+#define LCDREGS 0xB0100000 /* display */
/*
* PCMCIA addresses
M bitsy/mmu.c => bitsy/mmu.c +11 -3
@@ 211,10 211,18 @@ mapspecial(ulong pa, int len)
/* map add on memory */
void*
-mapmem(ulong pa, int len)
+mapmem(ulong pa, int len, int cached)
{
- return _map(pa, len, EMEMZERO, EMEMTOP, L1KernelRW|L1Cached|L1Buffered,
- L2KernelRW|L2Cached|L2Buffered);
+ ulong l1, l2;
+
+ if(cached){
+ l1 = L1KernelRW|L1Cached|L1Buffered;
+ l2 = L2KernelRW|L2Cached|L2Buffered;
+ } else {
+ l1 = L1KernelRW;
+ l2 = L2KernelRW;
+ }
+ return _map(pa, len, EMEMZERO, EMEMTOP, l1, l2);
}
/* map a virtual address to a physical one */
M bitsy/sa1110uart.c => bitsy/sa1110uart.c +0 -11
@@ 10,17 10,6 @@
/* this isn't strictly a sa1100 driver. The rts/cts stuff is h3650 specific */
-/* hardware registers */
-typedef struct Uartregs Uartregs;
-struct Uartregs
-{
- ulong ctl[4];
- ulong dummya;
- ulong data;
- ulong dummyb;
- ulong status[2];
-};
-
enum
{
/* ctl[0] bits */
M bitsy/trap.c => bitsy/trap.c +4 -3
@@ 179,7 179,7 @@ trap(Ureg *ureg)
int found;
Vctl *v;
int user, x, rv;
- ulong va;
+ ulong va, fsr;
char buf[ERRLEN];
user = (ureg->psr & PsrMask) == PsrMusr;
@@ 217,7 217,8 @@ trap(Ureg *ureg)
case PsrMabt+1: /* data fault */
va = getfar();
inst = *(ulong*)(ureg->pc);
- switch(getfsr() & 0xf){
+ fsr = getfsr() & 0xf;
+ switch(fsr){
case 0x0:
panic("vector exception at %lux\n", ureg->pc);
break;
@@ 239,7 240,7 @@ trap(Ureg *ureg)
case 0xa:
case 0xc:
case 0xe:
- panic("external abort at %lux\n", ureg->pc);
+ panic("external abort 0x%ux pc 0x%lux addr 0x%lux\n", fsr, ureg->pc, va);
break;
case 0x5:
case 0x7:
M ip/il.c => ip/il.c +1 -1
@@ 58,7 58,7 @@ enum
AckDelay = 2*Iltickms, /* max time twixt message rcvd & ack sent */
MaxTimeout = 30*Seconds, /* max time between rexmit */
QueryTime = 10*Seconds, /* time between subsequent queries */
- DeathTime = 5*QueryTime,
+ DeathTime = 30*QueryTime,
MaxRexmit = 16, /* max retransmissions before hangup */
Defaultwin = 20,