summaryrefslogtreecommitdiff
path: root/os/pxa
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/pxa
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/pxa')
-rw-r--r--os/pxa/clock.c318
-rw-r--r--os/pxa/devether.c617
-rw-r--r--os/pxa/devrtc.c169
-rw-r--r--os/pxa/devuart.c1073
-rw-r--r--os/pxa/dma.c244
-rw-r--r--os/pxa/etherif.h41
-rw-r--r--os/pxa/fpi.h61
-rw-r--r--os/pxa/fpiarm.c483
-rw-r--r--os/pxa/gpio.c88
-rw-r--r--os/pxa/i2c.c561
-rw-r--r--os/pxa/l.s548
-rw-r--r--os/pxa/mmu.c252
-rw-r--r--os/pxa/pxaio.h383
-rw-r--r--os/pxa/sa1110break.c360
-rw-r--r--os/pxa/trap.c587
15 files changed, 0 insertions, 5785 deletions
diff --git a/os/pxa/clock.c b/os/pxa/clock.c
deleted file mode 100644
index 2fd6eba6..00000000
--- a/os/pxa/clock.c
+++ /dev/null
@@ -1,318 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "ureg.h"
-
-static ulong timer_incr[4] = { 0, 0, 0, -1 };
-
-typedef struct Clock0link Clock0link;
-typedef struct Clock0link {
- void (*clock)(void);
- Clock0link* link;
-} Clock0link;
-
-static Clock0link *clock0link;
-static Lock clock0lock;
-static void (*prof_fcn)(Ureg *, int);
-
-Timer*
-addclock0link(void (*clock)(void), int)
-{
- Clock0link *lp;
-
- if((lp = malloc(sizeof(Clock0link))) == 0){
- print("addclock0link: too many links\n");
- return nil;
- }
- ilock(&clock0lock);
- lp->clock = clock;
- lp->link = clock0link;
- clock0link = lp;
- iunlock(&clock0lock);
- return nil;
-}
-
-static void
-profintr(Ureg *ur, void*)
-{
- OstmrReg *ost = OSTMRREG;
- int t;
-
- if((ost->osmr[3] - ost->oscr) < 2*CLOCKFREQ) {
- /* less than 2 seconds before reset, say something */
- setpanic();
- clockpoll();
- dumpregs(ur);
- panic("Watchdog timer will expire");
- }
-
- /* advance the profile clock tick */
- ost->osmr[2] += timer_incr[2];
- ost->ossr = (1 << 2); /* Clear the SR */
- t = 1;
- while((ost->osmr[2] - ost->oscr) > 0x80000000) {
- ost->osmr[2] += timer_incr[2];
- t++;
- }
- if(prof_fcn)
- prof_fcn(ur, t);
-}
-
-static void
-clockintr(Ureg*, void*)
-{
- Clock0link *lp;
- int losttick = 0;
- OstmrReg *ost = OSTMRREG;
-
-{static int tag, led; if(++tag >= HZ){ledset(led ^= 1);tag=0;}}
- m->ticks++;
-// ost->osmr[3] = ost->oscr + timer_incr[3]; /* restart the watchdog */
- ost->osmr[0] += timer_incr[0]; /* advance the clock tick */
- ost->ossr = (1<<0); /* Clear the SR */
-
- while((ost->osmr[0] - ost->oscr) >= 0x80000000) {
- ost->osmr[0] += timer_incr[0];
- losttick++;
- m->ticks++;
- }
-
- checkalarms();
-
- if(canlock(&clock0lock)){
- for(lp = clock0link; lp; lp = lp->link)
- if(lp->clock)
- lp->clock();
- unlock(&clock0lock);
- }
-
- /* round robin time slice is done by trap.c and proc.c */
-}
-
-void
-timerenable( int timer, int Hz, void (*f)(Ureg *, void*), void* a)
-{
- OstmrReg *ost = OSTMRREG;
- char name[KNAMELEN];
-
- if(timer < 0 || timer > 3)
- return;
- timer_incr[timer] = CLOCKFREQ/Hz; /* set up freq */
- ost->osmr[timer] = ost->oscr+timer_incr[timer];
- snprint(name, sizeof(name), "timer%d", timer);
- intrenable(IRQ, IRQtimer0+timer, f, a, name);
- ost->ossr = (1 << timer); /* clear any pending interrupt */
- ost->oier |= (1 << timer); /* enable interrupt */
-}
-
-void
-timerdisable( int timer )
-{
- OstmrReg *ost = OSTMRREG;
-
- if(timer < 0 || timer > 3)
- return;
- ost->osmr[timer] = 0; /* clear freq */
- ost->oier &= ~(1 << timer); /* disable interrupt */
-}
-
-void
-installprof(void (*pf)(Ureg *, int))
-{
- int s;
-
- s = splfhi();
- prof_fcn = pf;
- timerenable( 2, HZ+1, profintr, 0);
- timer_incr[2] = timer_incr[0]+63; /* fine tuning */
- splx(s);
-}
-
-void
-clockinit(void)
-{
- OstmrReg *ost = OSTMRREG;
- m->ticks = 0;
- /* Set up timer registers */
- ost->ossr = 0xf; /* clear all four OSSR trigger bits */
- ost->oier = 0;
- ost->osmr[0] = 0;
- ost->osmr[1] = 0;
- ost->osmr[2] = 0;
- // ost->osmr[3] = 0;
- timerenable( 0, HZ, clockintr, 0);
-// timer_incr[3] = CLOCKFREQ*10; /* 10 second watchdog */
-// timer_setwatchdog(timer_incr[3]);
-// timerenable( 2, 1, profintr, 0); /* watch the watchdog */
-}
-
-void
-clockpoll(void)
-{
- OstmrReg *ost = OSTMRREG;
-// ost->osmr[3] = ost->oscr + timer_incr[3]; /* restart the watchdog */
-}
-
-void
-clockcheck(void)
-{
- OstmrReg *ost = OSTMRREG;
-
- if((ost->osmr[3] - ost->oscr) < CLOCKFREQ) {
- setpanic();
- clockpoll();
- dumpstack();
- panic("Watchdog timer will expire");
- }
-}
-
-// macros for fixed-point math
-
-ulong _mularsv(ulong m0, ulong m1, ulong a, ulong s);
-
-/* truncated: */
-#define FXDPTDIV(a,b,n) ((ulong)(((uvlong)(a) << (n)) / (b)))
-#define MAXMUL(a,n) ((ulong)((((uvlong)1<<(n))-1)/(a)))
-#define MULDIV(x,a,b,n) (((x)*FXDPTDIV(a,b,n)) >> (n))
-#define MULDIV64(x,a,b,n) ((ulong)_mularsv(x, FXDPTDIV(a,b,n), 0, (n)))
-
-/* rounded: */
-#define FXDPTDIVR(a,b,n) ((ulong)((((uvlong)(a) << (n))+((b)/2)) / (b)))
-#define MAXMULR(a,n) ((ulong)((((uvlong)1<<(n))-1)/(a)))
-#define MULDIVR(x,a,b,n) (((x)*FXDPTDIVR(a,b,n)+(1<<((n)-1))) >> (n))
-#define MULDIVR64(x,a,b,n) ((ulong)_mularsv(x, FXDPTDIVR(a,b,n), 1<<((n)-1), (n)))
-
-
-// these routines are all limited to a maximum of 1165 seconds,
-// due to the wrap-around of the OSTIMER
-
-ulong
-timer_start(void)
-{
- return OSTMRREG->oscr;
-}
-
-ulong
-timer_ticks(ulong t0)
-{
- return OSTMRREG->oscr - t0;
-}
-
-int
-timer_devwait(ulong *adr, ulong mask, ulong val, int ost)
-{
- int i;
- ulong t0 = timer_start();
- while((*adr & mask) != val)
- if(timer_ticks(t0) > ost)
- return ((*adr & mask) == val) ? 0 : -1;
- else
- for(i = 0; i < 10; i++); /* don't pound OSCR too hard! (why not?) */
- return 0;
-}
-
-void
-timer_setwatchdog(int t)
-{
- OstmrReg *ost = OSTMRREG;
- ost->osmr[3] = ost->oscr + t;
- if(t) {
- ost->ossr = (1<<3);
- ost->oier |= (1<<3);
- ost->ower = 1;
- } else
- ost->oier &= ~(1<<3);
-}
-
-void
-timer_delay(int t)
-{
- ulong t0 = timer_start();
- while(timer_ticks(t0) < t)
- ;
-}
-
-
-ulong
-us2tmr(int us)
-{
- return MULDIV64(us, CLOCKFREQ, 1000000, 24);
-}
-
-int
-tmr2us(ulong t)
-{
- return MULDIV64(t, 1000000, CLOCKFREQ, 24);
-}
-
-void
-microdelay(int us)
-{
- ulong t0 = timer_start();
- ulong t = us2tmr(us);
- while(timer_ticks(t0) <= t)
- ;
-}
-
-ulong
-ms2tmr(int ms)
-{
- return MULDIV64(ms, CLOCKFREQ, 1000, 20);
-}
-
-int
-tmr2ms(ulong t)
-{
- return MULDIV64(t, 1000, CLOCKFREQ, 32);
-}
-
-void
-delay(int ms)
-{
- ulong t0 = timer_start();
- ulong t = ms2tmr(ms);
- while(timer_ticks(t0) <= t)
- clockpoll();
-}
-
-/*
- * for devbench.c
- */
-vlong
-archrdtsc(void)
-{
- return OSTMRREG->oscr;
-}
-
-ulong
-archrdtsc32(void)
-{
- return OSTMRREG->oscr;
-}
-
-/*
- * for devkprof.c
- */
-long
-archkprofmicrosecondspertick(void)
-{
- return MS2HZ*1000;
-}
-
-void
-archkprofenable(int)
-{
- /* TO DO */
-}
-
-uvlong
-fastticks(uvlong *hz)
-{
- if(hz)
- *hz = HZ;
- return m->ticks;
-}
diff --git a/os/pxa/devether.c b/os/pxa/devether.c
deleted file mode 100644
index 4b9da104..00000000
--- a/os/pxa/devether.c
+++ /dev/null
@@ -1,617 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-
-#include "etherif.h"
-
-static Ether *etherxx[MaxEther];
-
-Chan*
-etherattach(char* spec)
-{
- ulong ctlrno;
- char *p;
- Chan *chan;
- Ether *ether;
-
- ctlrno = 0;
- if(spec && *spec){
- ctlrno = strtoul(spec, &p, 0);
- if((ctlrno == 0 && p == spec) || *p || (ctlrno >= MaxEther))
- error(Ebadarg);
- }
- if((ether = etherxx[ctlrno]) == 0)
- error(Enodev);
- rlock(ether);
- if(waserror()){
- runlock(ether);
- nexterror();
- }
- chan = devattach('l', spec);
- chan->dev = ctlrno;
- if(ether->attach)
- ether->attach(etherxx[ctlrno]);
- poperror();
- runlock(ether);
- return chan;
-}
-
-static void
-ethershutdown(void)
-{
- Ether *ether;
- int i;
-
- for(i=0; i<MaxEther; i++){
- ether = etherxx[i];
- if(ether != nil && ether->detach != nil)
- ether->detach(ether);
- }
-}
-
-static Walkqid*
-etherwalk(Chan* chan, Chan *nchan, char **name, int nname)
-{
- Walkqid *wq;
- Ether *ether;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- wq = netifwalk(etherxx[chan->dev], chan, nchan, name, nname);
- poperror();
- runlock(ether);
- return wq;
-}
-
-static int
-etherstat(Chan* chan, uchar* dp, int n)
-{
- int s;
- Ether *ether;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- s = netifstat(ether, chan, dp, n);
- poperror();
- runlock(ether);
- return s;
-}
-
-static Chan*
-etheropen(Chan* chan, int omode)
-{
- Chan *c;
- Ether *ether;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- c = netifopen(ether, chan, omode);
- poperror();
- runlock(ether);
- return c;
-}
-
-static void
-ethercreate(Chan*, char*, int, ulong)
-{
-}
-
-static void
-etherclose(Chan* chan)
-{
- Ether *ether;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- netifclose(ether, chan);
- poperror();
- runlock(ether);
-}
-
-static long
-etherread(Chan* chan, void* buf, long n, vlong off)
-{
- Ether *ether;
- ulong offset = off;
- long r;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- if((chan->qid.type & QTDIR) == 0 && ether->ifstat){
- /*
- * With some controllers it is necessary to reach
- * into the chip to extract statistics.
- */
- if(NETTYPE(chan->qid.path) == Nifstatqid){
- r = ether->ifstat(ether, buf, n, offset);
- goto out;
- }
- if(NETTYPE(chan->qid.path) == Nstatqid)
- ether->ifstat(ether, buf, 0, offset);
- }
- r = netifread(ether, chan, buf, n, offset);
-out:
- poperror();
- runlock(ether);
- return r;
-}
-
-static Block*
-etherbread(Chan* chan, long n, ulong offset)
-{
- Block *b;
- Ether *ether;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- b = netifbread(ether, chan, n, offset);
- poperror();
- runlock(ether);
- return b;
-}
-
-static int
-etherwstat(Chan* chan, uchar* dp, int n)
-{
- Ether *ether;
- int r;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- r = netifwstat(ether, chan, dp, n);
- poperror();
- runlock(ether);
- return r;
-}
-
-static void
-etherrtrace(Netfile* f, Etherpkt* pkt, int len)
-{
- int i, n;
- Block *bp;
-
- if(qwindow(f->in) <= 0)
- return;
- if(len > 58)
- n = 58;
- else
- n = len;
- bp = iallocb(64);
- if(bp == nil)
- return;
- memmove(bp->wp, pkt->d, n);
- i = TK2MS(MACHP(0)->ticks);
- bp->wp[58] = len>>8;
- bp->wp[59] = len;
- bp->wp[60] = i>>24;
- bp->wp[61] = i>>16;
- bp->wp[62] = i>>8;
- bp->wp[63] = i;
- bp->wp += 64;
- qpass(f->in, bp);
-}
-
-Block*
-etheriq(Ether* ether, Block* bp, int fromwire)
-{
- Etherpkt *pkt;
- ushort type;
- int len, multi, tome, fromme;
- Netfile **ep, *f, **fp, *fx;
- Block *xbp;
-
- ether->inpackets++;
-
- pkt = (Etherpkt*)bp->rp;
- len = BLEN(bp);
- type = (pkt->type[0]<<8)|pkt->type[1];
- fx = 0;
- ep = &ether->f[Ntypes];
-
- multi = pkt->d[0] & 1;
- /* check for valid multcast addresses */
- if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) != 0 && ether->prom == 0){
- if(!activemulti(ether, pkt->d, sizeof(pkt->d))){
- if(fromwire){
- freeb(bp);
- bp = 0;
- }
- return bp;
- }
- }
-
- /* is it for me? */
- tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
- fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
-
- /*
- * Multiplex the packet to all the connections which want it.
- * If the packet is not to be used subsequently (fromwire != 0),
- * attempt to simply pass it into one of the connections, thereby
- * saving a copy of the data (usual case hopefully).
- */
- for(fp = ether->f; fp < ep; fp++){
- if((f = *fp) && (f->type == type || f->type < 0))
- if(tome || multi || f->prom){
- /* Don't want to hear bridged packets */
- if(f->bridge && !fromwire && !fromme)
- continue;
- if(!f->headersonly){
- if(fromwire && fx == 0)
- fx = f;
- else if(xbp = iallocb(len)){
- memmove(xbp->wp, pkt, len);
- xbp->wp += len;
- if(qpass(f->in, xbp) < 0)
- ether->soverflows++;
- }
- else
- ether->soverflows++;
- }
- else
- etherrtrace(f, pkt, len);
- }
- }
-
- if(fx){
- if(qpass(fx->in, bp) < 0)
- ether->soverflows++;
- return 0;
- }
- if(fromwire){
- freeb(bp);
- return 0;
- }
-
- return bp;
-}
-
-static int
-etheroq(Ether* ether, Block* bp)
-{
- int len, loopback, s;
- Etherpkt *pkt;
-
- ether->outpackets++;
-
- /*
- * Check if the packet has to be placed back onto the input queue,
- * i.e. if it's a loopback or broadcast packet or the interface is
- * in promiscuous mode.
- * If it's a loopback packet indicate to etheriq that the data isn't
- * needed and return, etheriq will pass-on or free the block.
- * To enable bridging to work, only packets that were originated
- * by this interface are fed back.
- */
- pkt = (Etherpkt*)bp->rp;
- len = BLEN(bp);
- loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
- if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){
- s = splhi();
- etheriq(ether, bp, 0);
- splx(s);
- }
-
- if(!loopback){
- qbwrite(ether->oq, bp);
- if(ether->transmit != nil)
- ether->transmit(ether);
- }else
- freeb(bp);
-
- return len;
-}
-
-static long
-etherwrite(Chan* chan, void* buf, long n, vlong)
-{
- Ether *ether;
- Block *bp;
- int onoff;
- Cmdbuf *cb;
- long l;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- if(NETTYPE(chan->qid.path) != Ndataqid) {
- l = netifwrite(ether, chan, buf, n);
- if(l >= 0)
- goto out;
- cb = parsecmd(buf, n);
- if(strcmp(cb->f[0], "nonblocking") == 0){
- if(cb->nf <= 1)
- onoff = 1;
- else
- onoff = atoi(cb->f[1]);
- qnoblock(ether->oq, onoff);
- free(cb);
- goto out;
- }
- free(cb);
- if(ether->ctl!=nil){
- l = ether->ctl(ether,buf,n);
- goto out;
- }
- error(Ebadctl);
- }
-
- if(n > ether->maxmtu)
- error(Etoobig);
- if(n < ether->minmtu)
- error(Etoosmall);
- bp = allocb(n);
- if(waserror()){
- freeb(bp);
- nexterror();
- }
- memmove(bp->rp, buf, n);
- memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen);
- bp->wp += n;
- poperror();
-
- l = etheroq(ether, bp);
-out:
- poperror();
- runlock(ether);
- return l;
-}
-
-static long
-etherbwrite(Chan* chan, Block* bp, ulong)
-{
- Ether *ether;
- long n;
-
- n = BLEN(bp);
- if(NETTYPE(chan->qid.path) != Ndataqid){
- if(waserror()) {
- freeb(bp);
- nexterror();
- }
- n = etherwrite(chan, bp->rp, n, 0);
- poperror();
- freeb(bp);
- return n;
- }
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- if(n > ether->maxmtu){
- freeb(bp);
- error(Etoobig);
- }
- if(n < ether->minmtu){
- freeb(bp);
- error(Etoosmall);
- }
- n = etheroq(ether, bp);
- poperror();
- runlock(ether);
- return n;
-}
-
-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)
-{
- char nip[4];
- char *p;
- int i;
-
- p = from;
- for(i = 0; i < Eaddrlen; i++){
- if(*p == 0)
- return -1;
- nip[0] = *p++;
- if(*p == 0)
- return -1;
- nip[1] = *p++;
- nip[2] = 0;
- to[i] = strtoul(nip, 0, 16);
- if(*p == ':')
- p++;
- }
- return 0;
-}
-
-static void
-etherreset(void)
-{
- Ether *ether;
- int i, n, ctlrno;
- char name[KNAMELEN], 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->mbps = 10;
- ether->minmtu = ETHERMINTU;
- ether->maxmtu = ETHERMAXTU;
- ether->itype = -1;
-
- if(archether(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(cistrncmp(ether->opt[i], "ea=", 3) == 0){
- if(parseether(ether->ea, &ether->opt[i][3]) == -1)
- memset(ether->ea, 0, Eaddrlen);
- }else if(cistrcmp(ether->opt[i], "fullduplex") == 0 ||
- cistrcmp(ether->opt[i], "10BASE-TFD") == 0)
- ether->fullduplex = 1;
- else if(cistrcmp(ether->opt[i], "100BASE-TXFD") == 0)
- ether->mbps = 100;
- }
- if(cards[n].reset(ether))
- break;
- snprint(name, sizeof(name), "ether%d", ctlrno);
-
- if(ether->interrupt != nil)
- intrenable(ether->itype, ether->irq, ether->interrupt, ether, 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");
- iprint(buf);
-
- if(ether->mbps == 100){
- netifinit(ether, name, Ntypes, 256*1024);
- if(ether->oq == 0)
- ether->oq = qopen(256*1024, Qmsg, 0, 0);
- }
- else{
- netifinit(ether, name, Ntypes, 64*1024);
- if(ether->oq == 0)
- ether->oq = qopen(64*1024, Qmsg, 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);
-}
-
-static void
-etherpower(int on)
-{
- int i;
- Ether *ether;
-
- for(i = 0; i < MaxEther; i++){
- if((ether = etherxx[i]) == nil || ether->power == nil)
- continue;
- if(on){
- if(canrlock(ether))
- continue;
- if(ether->power != nil)
- ether->power(ether, on);
- wunlock(ether);
- }else{
- if(!canrlock(ether))
- continue;
- wlock(ether);
- if(ether->power != nil)
- ether->power(ether, on);
- /* Keep locked until power goes back on */
- }
- }
-}
-
-#define POLY 0xedb88320
-
-/* really slow 32 bit crc for ethers */
-ulong
-ethercrc(uchar *p, int len)
-{
- int i, j;
- ulong crc, b;
-
- crc = 0xffffffff;
- for(i = 0; i < len; i++){
- b = *p++;
- for(j = 0; j < 8; j++){
- crc = (crc>>1) ^ (((crc^b) & 1) ? POLY : 0);
- b >>= 1;
- }
- }
- return crc;
-}
-
-Dev etherdevtab = {
- 'l',
- "ether",
-
- etherreset,
- devinit,
- ethershutdown,
- etherattach,
- etherwalk,
- etherstat,
- etheropen,
- ethercreate,
- etherclose,
- etherread,
- etherbread,
- etherwrite,
- etherbwrite,
- devremove,
- etherwstat,
- etherpower,
-};
diff --git a/os/pxa/devrtc.c b/os/pxa/devrtc.c
deleted file mode 100644
index ace6cc82..00000000
--- a/os/pxa/devrtc.c
+++ /dev/null
@@ -1,169 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#include "io.h"
-
-/*
- * SA11x0 real time clock
- * TO DO: alarms, wakeup, allow trim setting(?)
- */
-
-enum{
- Qdir,
- Qrtc,
- Qrtctrim,
-};
-
-static Dirtab rtcdir[]={
- ".", {Qdir,0,QTDIR}, 0, 0555,
- "rtc", {Qrtc}, NUMSIZE, 0664,
- "rtctrim", {Qrtctrim}, 0, 0664,
-};
-#define NRTC (sizeof(rtcdir)/sizeof(rtcdir[0]))
-
-extern ulong boottime;
-
-enum {
- RTSR_al= 1<<0, /* RTC alarm detected */
- RTSR_hz= 1<<1, /* 1-Hz rising-edge detected */
- RTSR_ale= 1<<2, /* RTC alarm interrupt enabled */
- RTSR_hze= 1<<3, /* 1-Hz interrupt enable */
-};
-
-static void
-rtcreset(void)
-{
- RTCreg *r;
-
- r = RTCREG;
- if((r->rttr & 0xFFFF) == 0){ /* reset state */
- r->rttr = 32768-1;
- r->rcnr = boottime; /* typically zero */
- }
- r->rtar = ~0;
- r->rtsr = RTSR_al | RTSR_hz;
-}
-
-static Chan*
-rtcattach(char *spec)
-{
- return devattach('r', spec);
-}
-
-static Walkqid*
-rtcwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, rtcdir, NRTC, devgen);
-}
-
-static int
-rtcstat(Chan *c, uchar *dp, int n)
-{
- return devstat(c, dp, n, rtcdir, NRTC, devgen);
-}
-
-static Chan*
-rtcopen(Chan *c, int omode)
-{
- return devopen(c, omode, rtcdir, NRTC, devgen);
-}
-
-static void
-rtcclose(Chan*)
-{
-}
-
-static long
-rtcread(Chan *c, void *buf, long n, vlong off)
-{
- if(c->qid.type & QTDIR)
- return devdirread(c, buf, n, rtcdir, NRTC, devgen);
-
- switch((ulong)c->qid.path){
- case Qrtc:
- return readnum(off, buf, n, RTCREG->rcnr, NUMSIZE);
- case Qrtctrim:
- return readnum(off, buf, n, RTCREG->rttr, NUMSIZE);
- }
- error(Egreg);
- return 0; /* not reached */
-}
-
-static long
-rtcwrite(Chan *c, void *buf, long n, vlong off)
-{
- ulong offset = off;
- ulong secs;
- char *cp, sbuf[32];
-
- switch((ulong)c->qid.path){
- case Qrtc:
- /*
- * write the time
- */
- if(offset != 0 || n >= sizeof(sbuf)-1)
- error(Ebadarg);
- memmove(sbuf, buf, n);
- sbuf[n] = '\0';
- cp = sbuf;
- while(*cp){
- if(*cp>='0' && *cp<='9')
- break;
- cp++;
- }
- secs = strtoul(cp, 0, 0);
- RTCREG->rcnr = secs;
- return n;
-
- case Qrtctrim:
- if(offset != 0 || n >= sizeof(sbuf)-1)
- error(Ebadarg);
- memmove(sbuf, buf, n);
- sbuf[n] = '\0';
- RTCREG->rttr = strtoul(sbuf, 0, 0);
- return n;
- }
- error(Egreg);
- return 0; /* not reached */
-}
-
-static void
-rtcpower(int on)
-{
- if(on)
- boottime = RTCREG->rcnr - TK2SEC(MACHP(0)->ticks);
- else
- RTCREG->rcnr = seconds();
-}
-
-long
-rtctime(void)
-{
- return RTCREG->rcnr;
-}
-
-Dev rtcdevtab = {
- 'r',
- "rtc",
-
- rtcreset,
- devinit,
- devshutdown,
- rtcattach,
- rtcwalk,
- rtcstat,
- rtcopen,
- devcreate,
- rtcclose,
- rtcread,
- devbread,
- rtcwrite,
- devbwrite,
- devremove,
- devwstat,
- rtcpower,
-};
diff --git a/os/pxa/devuart.c b/os/pxa/devuart.c
deleted file mode 100644
index 13b2107a..00000000
--- a/os/pxa/devuart.c
+++ /dev/null
@@ -1,1073 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-#include "../port/netif.h"
-
-/*
- * Driver for the uart.
- * TO DO: replace by uartpxa.c
- */
-enum
-{
- /*
- * register numbers
- */
- Data= 0, /* xmit/rcv buffer */
- Iena= 1, /* interrupt enable */
- Ircv= (1<<0), /* for char rcv'd */
- Ixmt= (1<<1), /* for xmit buffer empty */
- Irstat=(1<<2), /* for change in rcv'er status */
- Imstat=(1<<3), /* for change in modem status */
- Rtoie= 1<<4, /* character timeout indication */
- Nrze= 1<<5, /* NRZ encoding enabled */
- Uue= 1<<6, /* Uart unit enabled */
- Dmae= 1<<7, /* DMA requests enabled */
- Istat= 2, /* interrupt flag (read) */
- Ipend= 1, /* interrupt pending (not) */
- Fenabd=(3<<6), /* on if fifo's enabled */
- Fifoctl=2, /* fifo control (write) */
- Fena= (1<<0), /* enable xmit/rcv fifos */
- Fdma= (1<<3), /* dma on */
- Ftrig= (1<<6), /* trigger after 4 input characters */
- Fclear=(3<<1), /* clear xmit & rcv fifos */
- Format= 3, /* byte format */
- Bits8= (3<<0), /* 8 bits/byte */
- Stop2= (1<<2), /* 2 stop bits */
- Pena= (1<<3), /* generate parity */
- Peven= (1<<4), /* even parity */
- Pforce=(1<<5), /* force parity */
- Break= (1<<6), /* generate a break */
- Dra= (1<<7), /* address the divisor */
- Mctl= 4, /* modem control */
- Dtr= (1<<0), /* data terminal ready */
- Rts= (1<<1), /* request to send */
- Ri= (1<<2), /* ring */
- Inton= (1<<3), /* turn on interrupts */
- Loop= (1<<4), /* loop back */
- Lstat= 5, /* line status */
- Inready=(1<<0), /* receive buffer full */
- Oerror=(1<<1), /* receiver overrun */
- Perror=(1<<2), /* receiver parity error */
- Ferror=(1<<3), /* rcv framing error */
- Berror=(1<<4), /* break alarm */
- Outready=(1<<5), /* output buffer full */
- Mstat= 6, /* modem status */
- Ctsc= (1<<0), /* clear to send changed */
- Dsrc= (1<<1), /* data set ready changed */
- Rire= (1<<2), /* rising edge of ring indicator */
- Dcdc= (1<<3), /* data carrier detect changed */
- Cts= (1<<4), /* complement of clear to send line */
- Dsr= (1<<5), /* complement of data set ready line */
- Ringl= (1<<6), /* complement of ring indicator line */
- Dcd= (1<<7), /* complement of data carrier detect line */
- Scratch=7, /* scratchpad */
- Dlsb= 0, /* divisor lsb */
- Dmsb= 1, /* divisor msb */
-
- CTLS= 023,
- CTLQ= 021,
-
- Stagesize= 1024,
- Nuart= 4, /* max per machine */
-};
-
-typedef struct Uart Uart;
-struct Uart
-{
- QLock;
- int opens;
-
- int enabled;
- Uart *elist; /* next enabled interface */
- char name[KNAMELEN];
-
- ulong sticky[8]; /* sticky write register values */
- void* regs;
- ulong port;
- ulong freq; /* clock frequency */
- uchar mask; /* bits/char */
- int dev;
- int baud; /* baud rate */
-
- uchar istat; /* last istat read */
- int frame; /* framing errors */
- int overrun; /* rcvr overruns */
-
- /* buffers */
- int (*putc)(Queue*, int);
- Queue *iq;
- Queue *oq;
-
- Lock flock; /* fifo */
- uchar fifoon; /* fifo's enabled */
- uchar nofifo; /* earlier chip version with nofifo */
-
- Lock rlock; /* receive */
- uchar istage[Stagesize];
- uchar *ip;
- uchar *ie;
-
- int haveinput;
-
- 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; /* keep track of modem status */
- int ctsbackoff;
- int hup_dsr, hup_dcd; /* send hangup upstream? */
- int dohup;
-
- Rendez r;
-};
-
-static Uart *uart[Nuart];
-static int nuart;
-
-struct Uartalloc {
- Lock;
- Uart *elist; /* list of enabled interfaces */
-} uartalloc;
-
-static void uartintr(Uart*);
-
-/*
- * pick up architecture specific routines and definitions
- */
-#include "uart.h"
-
-/*
- * set the baud rate by calculating and setting the baudrate
- * generator constant. This will work with fairly non-standard
- * baud rates.
- */
-static void
-uartsetbaud(Uart *p, int rate)
-{
- ulong brconst;
-
- if(rate <= 0)
- return;
-
- p->freq = archuartclock(p->port, rate);
- if(p->freq == 0)
- return;
-
- brconst = (p->freq+8*rate-1)/(16*rate);
-
- uartwrreg(p, Format, Dra);
- uartwr(p, Dmsb, (brconst>>8) & 0xff);
- uartwr(p, Dlsb, brconst & 0xff);
- uartwrreg(p, Format, 0);
-
- p->baud = rate;
-}
-
-/*
- * decide if we should hangup when dsr or dcd drops.
- */
-static void
-uartdsrhup(Uart *p, int n)
-{
- p->hup_dsr = n;
-}
-
-static void
-uartdcdhup(Uart *p, int n)
-{
- p->hup_dcd = n;
-}
-
-static void
-uartparity(Uart *p, char type)
-{
- switch(type){
- case 'e':
- p->sticky[Format] |= Pena|Peven;
- break;
- case 'o':
- p->sticky[Format] &= ~Peven;
- p->sticky[Format] |= Pena;
- break;
- default:
- p->sticky[Format] &= ~(Pena|Peven);
- break;
- }
- uartwrreg(p, Format, 0);
-}
-
-/*
- * set bits/character, default 8
- */
-void
-uartbits(Uart *p, int bits)
-{
- if(bits < 5 || bits > 8)
- error(Ebadarg);
-
- p->sticky[Format] &= ~3;
- p->sticky[Format] |= bits-5;
-
- uartwrreg(p, Format, 0);
-}
-
-
-/*
- * toggle DTR
- */
-void
-uartdtr(Uart *p, int n)
-{
- if(n)
- p->sticky[Mctl] |= Dtr;
- else
- p->sticky[Mctl] &= ~Dtr;
-
- uartwrreg(p, Mctl, 0);
-}
-
-/*
- * toggle RTS
- */
-void
-uartrts(Uart *p, int n)
-{
- if(n)
- p->sticky[Mctl] |= Rts;
- else
- p->sticky[Mctl] &= ~Rts;
-
- uartwrreg(p, Mctl, 0);
-}
-
-/*
- * send break
- */
-static void
-uartbreak(Uart *p, int ms)
-{
- if(ms == 0)
- ms = 200;
-
- uartwrreg(p, Format, Break);
- tsleep(&up->sleep, return0, 0, ms);
- uartwrreg(p, Format, 0);
-}
-
-static void
-uartfifoon(Uart *p)
-{
- ulong i, x;
-
- if(p->nofifo || uartrdreg(p, Istat) & Fenabd)
- return;
-
- x = splhi();
-
- /* reset fifos */
- p->sticky[Fifoctl] = 0;
- uartwrreg(p, Fifoctl, Fclear);
-
- /* empty buffer and interrupt conditions */
- for(i = 0; i < 16; i++){
- if(uartrdreg(p, Istat)){
- /* nothing to do */
- }
- if(uartrdreg(p, Data)){
- /* nothing to do */
- }
- }
-
- /* turn on fifo */
- p->fifoon = 1;
- p->sticky[Fifoctl] = Fena|Ftrig;
- uartwrreg(p, Fifoctl, 0);
- p->istat = uartrdreg(p, Istat);
- if((p->istat & Fenabd) == 0) {
- /* didn't work, must be an earlier chip type */
- p->nofifo = 1;
- }
-
- splx(x);
-}
-
-/*
- * modem flow control on/off (rts/cts)
- */
-static void
-uartmflow(Uart *p, int n)
-{
- ilock(&p->tlock);
- if(n){
- p->sticky[Iena] |= Imstat;
- uartwrreg(p, Iena, 0);
- p->modem = 1;
- p->cts = uartrdreg(p, Mstat) & Cts;
- } else {
- p->sticky[Iena] &= ~Imstat;
- uartwrreg(p, Iena, 0);
- p->modem = 0;
- p->cts = 1;
- }
- iunlock(&p->tlock);
-
-// ilock(&p->flock);
-// if(1)
-// /* turn on fifo's */
-// uartfifoon(p);
-// else {
-// /* turn off fifo's */
-// p->fifoon = 0;
-// p->sticky[Fifoctl] = 0;
-// uartwrreg(p, Fifoctl, Fclear);
-// }
-// iunlock(&p->flock);
-}
-
-/*
- * turn on a port's interrupts. set DTR and RTS
- */
-static void
-uartenable(Uart *p)
-{
- Uart **l;
-
- if(p->enabled)
- return;
-
- uartportpower(p, 1);
-
- p->hup_dsr = p->hup_dcd = 0;
- p->cts = p->dsr = p->dcd = 0;
-
- /*
- * turn on interrupts
- */
- p->sticky[Iena] = Ircv | Ixmt | Irstat | Uue;
- uartwrreg(p, Iena, 0);
-
- /*
- * turn on DTR and RTS
- */
- uartdtr(p, 1);
- uartrts(p, 1);
-
- uartfifoon(p);
-
- /*
- * assume we can send
- */
- ilock(&p->tlock);
- p->cts = 1;
- p->blocked = 0;
- iunlock(&p->tlock);
-
- /*
- * set baud rate to the last used
- */
- uartsetbaud(p, p->baud);
-
- lock(&uartalloc);
- for(l = &uartalloc.elist; *l; l = &(*l)->elist){
- if(*l == p)
- break;
- }
- if(*l == 0){
- p->elist = uartalloc.elist;
- uartalloc.elist = p;
- }
- p->enabled = 1;
- unlock(&uartalloc);
-}
-
-/*
- * turn off a port's interrupts. reset DTR and RTS
- */
-static void
-uartdisable(Uart *p)
-{
- Uart **l;
-
- /*
- * turn off interrupts
- */
- p->sticky[Iena] = Uue;
- uartwrreg(p, Iena, 0);
-
- /*
- * revert to default settings
- */
- p->sticky[Format] = Bits8;
- uartwrreg(p, Format, 0);
-
- /*
- * turn off DTR, RTS, hardware flow control & fifo's
- */
- uartdtr(p, 0);
- uartrts(p, 0);
- uartmflow(p, 0);
- ilock(&p->tlock);
- p->xonoff = p->blocked = 0;
- iunlock(&p->tlock);
-
- uartportpower(p, 0);
-
- lock(&uartalloc);
- for(l = &uartalloc.elist; *l; l = &(*l)->elist){
- if(*l == p){
- *l = p->elist;
- break;
- }
- }
- p->enabled = 0;
- unlock(&uartalloc);
-}
-
-/*
- * put some bytes into the local queue to avoid calling
- * qconsume for every character
- */
-static int
-stageoutput(Uart *p)
-{
- int n;
-
- n = qconsume(p->oq, p->ostage, Stagesize);
- if(n <= 0)
- return 0;
- p->op = p->ostage;
- p->oe = p->ostage + n;
- return n;
-}
-
-/*
- * (re)start output
- */
-static void
-uartkick0(Uart *p)
-{
- int i;
- if((p->modem && (p->cts == 0)) || p->blocked)
- return;
-
- /*
- * 128 here is an arbitrary limit to make sure
- * we don't stay in this loop too long. If the
- * chips output queue is longer than 128, too
- * bad -- presotto
- */
- for(i = 0; i < 128; i++){
- if(!(uartrdreg(p, Lstat) & Outready))
- break;
- if(p->op >= p->oe && stageoutput(p) == 0)
- break;
- uartwr(p, Data, *p->op++);
- }
-}
-
-static void
-uartkick(void *v)
-{
- Uart *p;
-
- p = v;
- ilock(&p->tlock);
- uartkick0(p);
- iunlock(&p->tlock);
-}
-
-/*
- * restart input if it's off
- */
-static void
-uartflow(void *v)
-{
- Uart *p;
-
- p = v;
- if(p->modem)
- uartrts(p, 1);
- ilock(&p->rlock);
- p->haveinput = 1;
- iunlock(&p->rlock);
-}
-
-/*
- * default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts,
- * transmit and receive enabled, interrupts disabled.
- */
-static void
-uartsetup0(Uart *p)
-{
- memset(p->sticky, 0, sizeof(p->sticky));
- /*
- * set rate to 9600 baud.
- * 8 bits/character.
- * 1 stop bit.
- * interrupts enabled.
- */
- p->sticky[Format] = Bits8;
- uartwrreg(p, Format, 0);
- p->sticky[Mctl] |= Inton;
- uartwrreg(p, Mctl, 0x0);
-
-// uartsetbaud(p, 9600);
- uartsetbaud(p, 38400);
-
- p->iq = qopen(4*1024, 0, uartflow, p);
- p->oq = qopen(4*1024, 0, uartkick, p);
- if(p->iq == nil || p->oq == nil)
- panic("uartsetup0");
-
- p->ip = p->istage;
- p->ie = &p->istage[Stagesize];
- p->op = p->ostage;
- p->oe = p->ostage;
-}
-
-/*
- * called by uartinstall() to create a new duart
- */
-void
-uartsetup(ulong port, void *regs, ulong freq, char *name)
-{
- Uart *p;
-
- if(nuart >= Nuart)
- return;
-
- p = xalloc(sizeof(Uart));
- uart[nuart] = p;
- strcpy(p->name, name);
- p->dev = nuart;
- nuart++;
- p->port = port;
- p->regs = regs;
- p->freq = freq;
- uartsetup0(p);
-}
-
-/*
- * called by main() to configure a duart port as a console or a mouse
- */
-void
-uartspecial(int port, int baud, Queue **in, Queue **out, int (*putc)(Queue*, int))
-{
- Uart *p = uart[port];
- uartenable(p);
- if(baud)
- uartsetbaud(p, baud);
- p->putc = putc;
- if(in)
- *in = p->iq;
- if(out)
- *out = p->oq;
- p->opens++;
-}
-
-/*
- * handle an interrupt to a single uart
- */
-static void
-uartintr(Uart *p)
-{
- uchar ch;
- int s, l;
-
- for (s = uartrdreg(p, Istat); !(s&Ipend); s = uartrdreg(p, Istat)) {
- switch(s&0x3f){
- case 4: /* received data available */
- case 6: /* receiver line status (alarm or error) */
- case 12: /* character timeout indication */
- while ((l = uartrdreg(p, Lstat)) & Inready) {
- if(l & Ferror)
- p->frame++;
- if(l & Oerror)
- p->overrun++;
- ch = uartrdreg(p, Data) & 0xff;
- if (l & (Berror|Perror|Ferror)) {
- /* ch came with break, parity or framing error - consume */
- continue;
- }
- if (ch == CTLS || ch == CTLQ) {
- ilock(&p->tlock);
- if(p->xonoff){
- if(ch == CTLS)
- p->blocked = 1;
- else
- p->blocked = 0; /* clock gets output going again */
- }
- iunlock(&p->tlock);
- }
- if(p->putc)
- p->putc(p->iq, ch);
- else {
- ilock(&p->rlock);
- if(p->ip < p->ie)
- *p->ip++ = ch;
- else
- p->overrun++;
- p->haveinput = 1;
- iunlock(&p->rlock);
- }
- }
- break;
-
- case 2: /* transmitter not full */
- uartkick(p);
- break;
-
- case 0: /* modem status */
- ch = uartrdreg(p, Mstat);
- if(ch & Ctsc){
- ilock(&p->tlock);
- l = p->cts;
- p->cts = ch & Cts;
- if(l == 0 && p->cts)
- p->ctsbackoff = 2; /* clock gets output going again */
- iunlock(&p->tlock);
- }
- if (ch & Dsrc) {
- l = ch & Dsr;
- if(p->hup_dsr && p->dsr && !l){
- ilock(&p->rlock);
- p->dohup = 1;
- iunlock(&p->rlock);
- }
- p->dsr = l;
- }
- if (ch & Dcdc) {
- l = ch & Dcd;
- if(p->hup_dcd && p->dcd && !l){
- ilock(&p->rlock);
- p->dohup = 1;
- iunlock(&p->rlock);
- }
- p->dcd = l;
- }
- break;
-
- default:
- iprint("weird uart interrupt #%2.2ux\n", s);
- break;
- }
- }
- p->istat = s;
-}
-
-/*
- * we save up input characters till clock time
- *
- * There's also a bit of code to get a stalled print going.
- * It shouldn't happen, but it does. Obviously I don't
- * understand something. Since it was there, I bundled a
- * restart after flow control with it to give some hysteresis
- * to the hardware flow control. This makes compressing
- * modems happier but will probably bother something else.
- * -- presotto
- */
-void
-uartclock(void)
-{
- int n;
- Uart *p;
-
- for(p = uartalloc.elist; p; p = p->elist){
-
- /* this amortizes cost of qproduce to many chars */
- if(p->haveinput){
- ilock(&p->rlock);
- if(p->haveinput){
- n = p->ip - p->istage;
- if(n > 0 && p->iq){
- if(n > Stagesize)
- panic("uartclock");
- if(qproduce(p->iq, p->istage, n) < 0)
- uartrts(p, 0);
- else
- p->ip = p->istage;
- }
- p->haveinput = 0;
- }
- iunlock(&p->rlock);
- }
- if(p->dohup){
- ilock(&p->rlock);
- if(p->dohup){
- qhangup(p->iq, 0);
- qhangup(p->oq, 0);
- }
- p->dohup = 0;
- iunlock(&p->rlock);
- }
-
- /* this adds hysteresis to hardware flow control */
- if(p->ctsbackoff){
- ilock(&p->tlock);
- if(p->ctsbackoff){
- if(--(p->ctsbackoff) == 0)
- uartkick0(p);
- }
- iunlock(&p->tlock);
- }
- }
-}
-
-Dirtab *uartdir;
-int ndir;
-
-static void
-setlength(int i)
-{
- Uart *p;
-
- if(i >= 0){
- p = uart[i];
- if(p && p->opens && p->iq)
- uartdir[1+3*i].length = qlen(p->iq);
- } else for(i = 0; i < nuart; i++){
- p = uart[i];
- if(p && p->opens && p->iq)
- uartdir[1+3*i].length = qlen(p->iq);
- }
-}
-
-/*
- * all uarts must be uartsetup() by this point or inside of uartinstall()
- */
-static void
-uartreset(void)
-{
- int i;
- Dirtab *dp;
- uartinstall(); /* architecture specific */
-
- ndir = 1+3*nuart;
- uartdir = xalloc(ndir * sizeof(Dirtab));
- dp = uartdir;
- strcpy(dp->name, ".");
- mkqid(&dp->qid, 0, 0, QTDIR);
- dp->length = 0;
- dp->perm = DMDIR|0555;
- dp++;
- for(i = 0; i < nuart; i++){
- /* 3 directory entries per port */
- strcpy(dp->name, uart[i]->name);
- dp->qid.path = NETQID(i, Ndataqid);
- dp->perm = 0666;
- dp++;
- sprint(dp->name, "%sctl", uart[i]->name);
- dp->qid.path = NETQID(i, Nctlqid);
- dp->perm = 0666;
- dp++;
- sprint(dp->name, "%sstatus", uart[i]->name);
- dp->qid.path = NETQID(i, Nstatqid);
- dp->perm = 0444;
- dp++;
- }
-}
-
-static Chan*
-uartattach(char *spec)
-{
- return devattach('t', spec);
-}
-
-static Walkqid*
-uartwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, uartdir, ndir, devgen);
-}
-
-static int
-uartstat(Chan *c, uchar *dp, int n)
-{
- if(NETTYPE(c->qid.path) == Ndataqid)
- setlength(NETID(c->qid.path));
- return devstat(c, dp, n, uartdir, ndir, devgen);
-}
-
-static Chan*
-uartopen(Chan *c, int omode)
-{
- Uart *p;
-
- c = devopen(c, omode, uartdir, ndir, devgen);
-
- switch(NETTYPE(c->qid.path)){
- case Nctlqid:
- case Ndataqid:
- p = uart[NETID(c->qid.path)];
- qlock(p);
- if(p->opens++ == 0){
- uartenable(p);
- qreopen(p->iq);
- qreopen(p->oq);
- }
- qunlock(p);
- break;
- }
-
- return c;
-}
-
-static void
-uartclose(Chan *c)
-{
- Uart *p;
-
- if(c->qid.type & QTDIR)
- return;
- if((c->flag & COPEN) == 0)
- return;
- switch(NETTYPE(c->qid.path)){
- case Ndataqid:
- case Nctlqid:
- p = uart[NETID(c->qid.path)];
- qlock(p);
- if(--(p->opens) == 0){
- uartdisable(p);
- qclose(p->iq);
- qclose(p->oq);
- p->ip = p->istage;
- p->dcd = p->dsr = p->dohup = 0;
- }
- qunlock(p);
- break;
- }
-}
-
-static long
-uartstatus(Chan*, Uart *p, void *buf, long n, long offset)
-{
- uchar mstat, fstat, istat, tstat;
- char str[256];
-
- str[0] = 0;
- tstat = p->sticky[Mctl];
- mstat = uartrdreg(p, Mstat);
- istat = p->sticky[Iena];
- fstat = p->sticky[Format];
- snprint(str, sizeof str,
- "b%d c%d d%d e%d l%d m%d p%c r%d s%d\n"
- "%d %d %d%s%s%s%s%s\n",
-
- p->baud,
- p->hup_dcd,
- (tstat & Dtr) != 0,
- p->hup_dsr,
- (fstat & Bits8) + 5,
- (istat & Imstat) != 0,
- (fstat & Pena) ? ((fstat & Peven) ? 'e' : 'o') : 'n',
- (tstat & Rts) != 0,
- (fstat & Stop2) ? 2 : 1,
-
- p->dev,
- p->frame,
- p->overrun,
- uartrdreg(p, Istat) & Fenabd ? " fifo" : "",
- (mstat & Cts) ? " cts" : "",
- (mstat & Dsr) ? " dsr" : "",
- (mstat & Dcd) ? " dcd" : "",
- (mstat & Ringl) ? " ring" : ""
- );
- return readstr(offset, buf, n, str);
-}
-
-static long
-uartread(Chan *c, void *buf, long n, vlong off)
-{
- Uart *p;
- ulong offset = off;
-
- if(c->qid.type & QTDIR){
- setlength(-1);
- return devdirread(c, buf, n, uartdir, ndir, devgen);
- }
-
- p = uart[NETID(c->qid.path)];
- switch(NETTYPE(c->qid.path)){
- case Ndataqid:
- return qread(p->iq, buf, n);
- case Nctlqid:
- return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE);
- case Nstatqid:
- return uartstatus(c, p, buf, n, offset);
- }
-
- return 0;
-}
-
-static void
-uartctl(Uart *p, char *cmd)
-{
- int i, n;
-
- /* let output drain for a while */
- for(i = 0; i < 16 && qlen(p->oq); i++)
- tsleep(&p->r, (int(*)(void*))qlen, p->oq, 125);
-
- if(strncmp(cmd, "break", 5) == 0){
- uartbreak(p, 0);
- return;
- }
-
-
- n = atoi(cmd+1);
- switch(*cmd){
- case 'B':
- case 'b':
- uartsetbaud(p, n);
- break;
- case 'C':
- case 'c':
- uartdcdhup(p, n);
- break;
- case 'D':
- case 'd':
- uartdtr(p, n);
- break;
- case 'E':
- case 'e':
- uartdsrhup(p, n);
- break;
- case 'f':
- case 'F':
- qflush(p->oq);
- break;
- case 'H':
- case 'h':
- qhangup(p->iq, 0);
- qhangup(p->oq, 0);
- break;
- case 'L':
- case 'l':
- uartbits(p, n);
- break;
- case 'm':
- case 'M':
- uartmflow(p, n);
- break;
- case 'n':
- case 'N':
- qnoblock(p->oq, n);
- break;
- case 'P':
- case 'p':
- uartparity(p, *(cmd+1));
- break;
- case 'K':
- case 'k':
- uartbreak(p, n);
- break;
- case 'R':
- case 'r':
- uartrts(p, n);
- break;
- case 'Q':
- case 'q':
- qsetlimit(p->iq, n);
- qsetlimit(p->oq, n);
- break;
- case 'W':
- case 'w':
- /* obsolete */
- break;
- case 'X':
- case 'x':
- ilock(&p->tlock);
- p->xonoff = n;
- iunlock(&p->tlock);
- break;
- }
-}
-
-static long
-uartwrite(Chan *c, void *buf, long n, vlong)
-{
- Uart *p;
- char cmd[32];
-
- if(c->qid.type & QTDIR)
- error(Eperm);
-
- p = uart[NETID(c->qid.path)];
-
- /*
- * The fifo's turn themselves off sometimes.
- * It must be something I don't understand. -- presotto
- */
- lock(&p->flock);
- if((p->istat & Fenabd) == 0 && p->fifoon && p->nofifo == 0)
- uartfifoon(p);
- unlock(&p->flock);
-
- switch(NETTYPE(c->qid.path)){
- case Ndataqid:
- return qwrite(p->oq, buf, n);
- case Nctlqid:
- if(n >= sizeof(cmd))
- n = sizeof(cmd)-1;
- memmove(cmd, buf, n);
- cmd[n] = 0;
- uartctl(p, cmd);
- return n;
- default:
- error(Egreg);
- return n;
- }
-}
-
-static int
-uartwstat(Chan *c, uchar *dp, int n)
-{
- Dir d;
- Dirtab *dt;
-
- if(!iseve())
- error(Eperm);
- if(c->qid.type & QTDIR)
- error(Eperm);
- if(NETTYPE(c->qid.path) == Nstatqid)
- error(Eperm);
-
- dt = &uartdir[1+3 * NETID(c->qid.path)];
- n = convM2D(dp, n, &d, nil);
- if(n == 0)
- error(Eshortstat);
- if(d.mode != ~0UL){
- d.mode &= 0666;
- dt[0].perm = dt[1].perm = d.mode;
- }
- return n;
-}
-
-Dev uartdevtab = {
- 't',
- "uart",
-
- uartreset,
- devinit,
- devshutdown,
- uartattach,
- uartwalk,
- uartstat,
- uartopen,
- devcreate,
- uartclose,
- uartread,
- devbread,
- uartwrite,
- devbwrite,
- devremove,
- uartwstat,
-};
diff --git a/os/pxa/dma.c b/os/pxa/dma.c
deleted file mode 100644
index 9fcdbb4f..00000000
--- a/os/pxa/dma.c
+++ /dev/null
@@ -1,244 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "io.h"
-
-#define DMAREGS ((Dmaregs*)PHYSDMA)
-typedef struct Dmadesc Dmadesc;
-typedef struct Dmaregs Dmaregs;
-
-struct Dmadesc {
- ulong ddadr; /* next descriptor address (0 mod 16) */
- ulong dsadr; /* source address (0 mod 8 if external, 0 mod 4 internal) */
- ulong dtadr; /* target address (same) */
- ulong dcmd; /* command */
-};
-
-struct Dmaregs {
- ulong dcsr[16]; /* control and status */
- uchar pad0[0xF0-0x40];
- ulong dint; /* mask of interrupting channels: 0 is bit 0 */
- uchar pad1[0x100-0xF4];
- ulong drcmr[40];
- Dmadesc chan[16]; /* offset 0x200 */
-};
-
-enum {
- /* dcsr */
- DcsRun= 1<<31, /* start the channel */
- DcsNodesc= 1<<30, /* set if channel is in no-descriptor fetch mode */
- DcsStopirq= 1<<29, /* enable interrupt if channel is uninitialised or stopped */
- DcsReqpend= 1<<8, /* channel has pending request */
- DcsStopstate= 1<<3, /* channel is uninitialised or stopped */
- DcsEndintr= 1<<2, /* transaction complete, length now 0 */
- DcsStartintr= 1<<1, /* successful descriptor fetch */
- DcsBuserr= 1<<0, /* bus error */
-
- /* drcmr */
- DmrValid= 1<<7, /* mapped to channel given by bits 0-3 */
- DmrChan= 0xF, /* channel number mask */
-
- /* ddadr */
- DdaStop= 1<<1, /* =0, run channel; =1, stop channel after this descriptor */
-
- /* dcmd */
- DcmIncsrc= 1<<31, /* increment source address after use */
- DcmIncdest= 1<<30, /* increment destination address after use */
- DcmFlowsrc= 1<<29, /* enable flow control on source */
- DcmFlowdest= 1<<28, /* enable flow control on target */
- DcmStartirq= 1<<22, /* interrupt when descriptor loaded (fetch mode) */
- DcmEndirq= 1<<21, /* interrupt when transfer complete */
- DcmEndian= 1<<18, /* must be zero (little endian) */
- DcmBurst8= 1<<16, /* burst size in bytes */
- DcmBurst16= 2<<16,
- DcmBurst32= 3<<16,
- DcmWidth0= 0<<14, /* width for external memory */
- DcmWidth1= 1<<14, /* width of on-chip peripheral */
- DcmWidth2= 2<<14,
- DcmWidth4= 3<<14,
- DcmLength= (1<<13)-1,
-
- Ndma= 16, /* number of dma channels */
- MaxDMAbytes= 8192-1, /* annoyingly small limit */
-};
-
-struct Dma {
- int chan;
- Dmadesc* desc;
- Dmadesc stop;
- ulong *csr;
- void (*interrupt)(void*, ulong);
- void* arg;
- Rendez r;
- ulong attrs; /* transfer attributes: flow control, burst size, width */
-};
-
-static struct {
- Lock;
- ulong avail;
- Dma dma[Ndma];
-} dmachans;
-
-static void dmaintr(Ureg*, void*);
-
-void
-dmareset(void)
-{
- int i;
- Dma *d;
-
- for(i=0; i<Ndma; i++){
- dmachans.avail |= 1<<i;
- d = &dmachans.dma[i];
- d->chan = i;
- d->csr = &DMAREGS->dcsr[i];
- d->desc = &DMAREGS->chan[i];
- d->stop.ddadr = (ulong)&d->stop | DdaStop;
- d->stop.dcmd = 0;
- }
- intrenable(IRQ, IRQdma, dmaintr, nil, "dma");
-}
-
-/*
- * allocate a DMA channel, reset it, and configure it for the given device
- */
-Dma*
-dmasetup(int owner, void (*interrupt)(void*, ulong), void *arg, ulong attrs)
-{
- Dma *d;
- Dmadesc *dc;
- int i;
-
- ilock(&dmachans);
- for(i=0; (dmachans.avail & (1<<i)) == 0; i++)
- if(i >= Ndma){
- iunlock(&dmachans);
- return nil;
- }
- dmachans.avail &= ~(1<<i);
- iunlock(&dmachans);
-
- d = &dmachans.dma[i];
- d->owner = owner;
- d->interrupt = interrupt;
- d->arg = arg;
- d->attrs = attrs;
- dc = d->desc;
- dc->ddadr = (ulong)&d->stop | DdaStop; /* empty list */
- dc->dcmd = 0;
- *d->csr = DcsEndintr | DcsStartintr | DcsBuserr; /* clear status, stopped */
- DMAREGS->drcmr[owner] = DmrValid | i;
- return d;
-}
-
-void
-dmafree(Dma *dma)
-{
- dmastop(dma);
- DMAREGS->drcmr[d->owner] = 0;
- ilock(&dmachans);
- dmachans.avail |= 1<<dma->chan;
- dma->interrupt = nil;
- iunlock(&dmachans);
-}
-
-/*
- * simple dma transfer on a channel, using `no fetch descriptor' mode.
- * virtual buffer addresses are assumed to refer to contiguous physical addresses.
- */
-int
-dmastart(Dma *dma, void *from, void *to, int nbytes)
-{
- Dmadesc *dc;
-
- if((ulong)nbytes > MaxDMAbytes)
- panic("dmastart");
- if((*dma->csr & DcsStopstate) == 0)
- return 0; /* busy */
- dc = dma->desc;
- dc->ddadr = DdaStop;
- dc->dsadr = PADDR(from);
- dc->dtadr = PADDR(to);
- dc->dcmd = dma->attrs | DcmEndirq | nbytes;
- *dma->csr = DcsRun | DcsNodesc | DcsEndintr | DcsStartintr | DcsBuserr;
- return 1;
-}
-
-/*
- * stop dma on a channel
- */
-void
-dmastop(Dma *dma)
-{
- *dma->csr = 0;
- while((*dma->csr & DcsStopstate) == 0)
- ;
- *dma->csr = DcsStopstate;
-}
-
-/*
- * return nonzero if there was a memory error during DMA,
- * and clear the error state
- */
-int
-dmaerror(Dma *dma)
-{
- ulong e;
-
- e = *dma->csr & DcsBuserr;
- *dma->csr |= e;
- return e;
-}
-
-/*
- * return nonzero if the DMA channel is not busy
- */
-int
-dmaidle(Dma *d)
-{
- return (*d->csr & DcsStopstate) == 0;
-}
-
-static int
-dmaidlep(void *a)
-{
- return dmaidle((Dma*)a);
-}
-
-void
-dmawait(Dma *d)
-{
- while(!dmaidle(d))
- sleep(&d->r, dmaidlep, d);
-}
-
-/*
- * this interface really only copes with one buffer at once
- */
-static void
-dmaintr(Ureg*, void*)
-{
- Dma *d;
- Dmaregs *dr;
- int i;
- ulong s, csr;
-
- dr = DMAREGS;
- s = dr->dint;
- dr->dint = s;
- for(i=0; i<Ndma && s != 0; i++)
- if(s & (1<<i)){
- d = &dmachans.dma[i];
- csr = *d->csr;
- if(csr & DcsBuserr)
- iprint("DMA error, chan %d status #%8.8lux\n", d->chan, csr);
- *d->csr = csr & (DcsRun | DcsNodesc | DcsEndintr | DcsStartintr | DcsBuserr);
- if(d->interrupt != nil)
- d->interrupt(d->arg, csr);
- else
- wakeup(&d->r);
- }
-}
diff --git a/os/pxa/etherif.h b/os/pxa/etherif.h
deleted file mode 100644
index 5c5c679b..00000000
--- a/os/pxa/etherif.h
+++ /dev/null
@@ -1,41 +0,0 @@
-enum {
- MaxEther = 3,
- Ntypes = 8,
-};
-
-typedef struct Ether Ether;
-struct Ether {
-RWlock; /* TO DO */
- ISAConf; /* hardware info */
- int ctlrno;
- int minmtu;
- int maxmtu;
- uchar ea[Eaddrlen];
- int encry;
-
- void (*attach)(Ether*); /* filled in by reset routine */
- void (*closed)(Ether*);
- void (*detach)(Ether*);
- void (*transmit)(Ether*);
- void (*interrupt)(Ureg*, void*);
- long (*ifstat)(Ether*, void*, long, ulong);
- long (*ctl)(Ether*, void*, long); /* custom ctl messages */
- void (*power)(Ether*, int); /* power on/off */
- void (*shutdown)(Ether*); /* shutdown hardware before reboot */
- void *ctlr;
- int pcmslot; /* PCMCIA */
- int fullduplex; /* non-zero if full duplex */
-
- Queue* oq;
-
- Netif;
-};
-
-extern Block* etheriq(Ether*, Block*, int);
-extern void addethercard(char*, int(*)(Ether*));
-extern int archether(int, Ether*);
-
-#define NEXT(x, l) (((x)+1)%(l))
-#define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1)
-#define HOWMANY(x, y) (((x)+((y)-1))/(y))
-#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y))
diff --git a/os/pxa/fpi.h b/os/pxa/fpi.h
deleted file mode 100644
index abaa7c12..00000000
--- a/os/pxa/fpi.h
+++ /dev/null
@@ -1,61 +0,0 @@
-typedef long Word;
-typedef unsigned long Single;
-typedef struct {
- unsigned long l;
- unsigned long h;
-} Double;
-
-enum {
- FractBits = 28,
- CarryBit = 0x10000000,
- HiddenBit = 0x08000000,
- MsBit = HiddenBit,
- NGuardBits = 3,
- GuardMask = 0x07,
- LsBit = (1<<NGuardBits),
-
- SingleExpBias = 127,
- SingleExpMax = 255,
- DoubleExpBias = 1023,
- DoubleExpMax = 2047,
-
- ExpBias = DoubleExpBias,
- ExpInfinity = DoubleExpMax,
-};
-
-typedef struct {
- unsigned char s;
- short e;
- long l; /* 0000FFFFFFFFFFFFFFFFFFFFFFFFFGGG */
- long h; /* 0000HFFFFFFFFFFFFFFFFFFFFFFFFFFF */
-} Internal;
-
-#define IsWeird(n) ((n)->e >= ExpInfinity)
-#define IsInfinity(n) (IsWeird(n) && (n)->h == HiddenBit && (n)->l == 0)
-#define SetInfinity(n) ((n)->e = ExpInfinity, (n)->h = HiddenBit, (n)->l = 0)
-#define IsNaN(n) (IsWeird(n) && (((n)->h & ~HiddenBit) || (n)->l))
-#define SetQNaN(n) ((n)->s = 0, (n)->e = ExpInfinity, \
- (n)->h = HiddenBit|(LsBit<<1), (n)->l = 0)
-#define IsZero(n) ((n)->e == 1 && (n)->h == 0 && (n)->l == 0)
-#define SetZero(n) ((n)->e = 1, (n)->h = 0, (n)->l = 0)
-
-/*
- * fpi.c
- */
-extern void fpiround(Internal *);
-extern void fpiadd(Internal *, Internal *, Internal *);
-extern void fpisub(Internal *, Internal *, Internal *);
-extern void fpimul(Internal *, Internal *, Internal *);
-extern void fpidiv(Internal *, Internal *, Internal *);
-extern int fpicmp(Internal *, Internal *);
-extern void fpinormalise(Internal*);
-
-/*
- * fpimem.c
- */
-extern void fpis2i(Internal *, void *);
-extern void fpid2i(Internal *, void *);
-extern void fpiw2i(Internal *, void *);
-extern void fpii2s(void *, Internal *);
-extern void fpii2d(void *, Internal *);
-extern void fpii2w(Word *, Internal *);
diff --git a/os/pxa/fpiarm.c b/os/pxa/fpiarm.c
deleted file mode 100644
index 4acfcd1d..00000000
--- a/os/pxa/fpiarm.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * this doesn't attempt to implement ARM floating-point properties
- * that aren't visible in the Inferno environment.
- * all arithmetic is done in double precision.
- * the FP trap status isn't updated.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "ureg.h"
-
-#include "fpi.h"
-
-// #define R13OK undef this if correct kernel r13 isn't in Ureg; check calculation in fpiarm below
-
-#define REG(x) (*(long*)(((char*)(ur))+roff[(x)]))
-#define FPENV (*(ufp))
-#define FR(x) (*(Internal*)(ufp)->regs[(x)&7])
-
-/* BUG: check fetch (not worthwhile in Inferno) */
-#define getubyte(a) (*(uchar*)(a))
-#define getuword(a) (*(ushort*)(a))
-#define getulong(a) (*(ulong*)(a))
-
-typedef struct FP2 FP2;
-typedef struct FP1 FP1;
-
-struct FP2 {
- char* name;
- void (*f)(Internal, Internal, Internal*);
-};
-
-struct FP1 {
- char* name;
- void (*f)(Internal*, Internal*);
-};
-
-enum {
- N = 1<<31,
- Z = 1<<30,
- C = 1<<29,
- V = 1<<28,
- REGPC = 15,
-};
-
-int fpemudebug = 0;
-
-#undef OFR
-#define OFR(X) ((ulong)&((Ureg*)0)->X)
-
-static int roff[] = {
- OFR(r0), OFR(r1), OFR(r2), OFR(r3),
- OFR(r4), OFR(r5), OFR(r6), OFR(r7),
- OFR(r8), OFR(r9), OFR(r10), OFR(r11),
-#ifdef R13OK
- OFR(r12), OFR(r13), OFR(r14), OFR(pc),
-#else
- OFR(r12), OFR(type), OFR(r14), OFR(pc),
-#endif
-};
-
-static Internal fpconst[8] = { /* indexed by op&7 */
- /* s, e, l, h */
- {0, 0x1, 0x00000000, 0x00000000}, /* 0.0 */
- {0, 0x3FF, 0x00000000, 0x08000000}, /* 1.0 */
- {0, 0x400, 0x00000000, 0x08000000}, /* 2.0 */
- {0, 0x400, 0x00000000, 0x0C000000}, /* 3.0 */
- {0, 0x401, 0x00000000, 0x08000000}, /* 4.0 */
- {0, 0x401, 0x00000000, 0x0A000000}, /* 5.0 */
- {0, 0x3FE, 0x00000000, 0x08000000}, /* 0.5 */
- {0, 0x402, 0x00000000, 0x0A000000}, /* 10.0 */
-};
-
-/*
- * arm binary operations
- */
-
-static void
-fadd(Internal m, Internal n, Internal *d)
-{
- (m.s == n.s? fpiadd: fpisub)(&m, &n, d);
-}
-
-static void
-fsub(Internal m, Internal n, Internal *d)
-{
- m.s ^= 1;
- (m.s == n.s? fpiadd: fpisub)(&m, &n, d);
-}
-
-static void
-fsubr(Internal m, Internal n, Internal *d)
-{
- n.s ^= 1;
- (n.s == m.s? fpiadd: fpisub)(&n, &m, d);
-}
-
-static void
-fmul(Internal m, Internal n, Internal *d)
-{
- fpimul(&m, &n, d);
-}
-
-static void
-fdiv(Internal m, Internal n, Internal *d)
-{
- fpidiv(&m, &n, d);
-}
-
-static void
-fdivr(Internal m, Internal n, Internal *d)
-{
- fpidiv(&n, &m, d);
-}
-
-/*
- * arm unary operations
- */
-
-static void
-fmov(Internal *m, Internal *d)
-{
- *d = *m;
-}
-
-static void
-fmovn(Internal *m, Internal *d)
-{
- *d = *m;
- d->s ^= 1;
-}
-
-static void
-fabsf(Internal *m, Internal *d)
-{
- *d = *m;
- d->s = 0;
-}
-
-static void
-frnd(Internal *m, Internal *d)
-{
- short e;
-
- (m->s? fsub: fadd)(fpconst[6], *m, d);
- if(IsWeird(d))
- return;
- fpiround(d);
- e = (d->e - ExpBias) + 1;
- if(e <= 0)
- SetZero(d);
- else if(e > FractBits){
- if(e < 2*FractBits)
- d->l &= ~((1<<(2*FractBits - e))-1);
- }else{
- d->l = 0;
- if(e < FractBits)
- d->h &= ~((1<<(FractBits-e))-1);
- }
-}
-
-static FP1 optab1[16] = { /* Fd := OP Fm */
-[0] {"MOVF", fmov},
-[1] {"NEGF", fmovn},
-[2] {"ABSF", fabsf},
-[3] {"RNDF", frnd},
-[4] {"SQTF", /*fsqt*/0},
-/* LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN all `deprecated' */
-/* URD and NRM aren't implemented */
-};
-
-static FP2 optab2[16] = { /* Fd := Fn OP Fm */
-[0] {"ADDF", fadd},
-[1] {"MULF", fmul},
-[2] {"SUBF", fsub},
-[3] {"RSUBF", fsubr},
-[4] {"DIVF", fdiv},
-[5] {"RDIVF", fdivr},
-/* POW, RPW deprecated */
-[8] {"REMF", /*frem*/0},
-[9] {"FMF", fmul}, /* fast multiply */
-[10] {"FDV", fdiv}, /* fast divide */
-[11] {"FRD", fdivr}, /* fast reverse divide */
-/* POL deprecated */
-};
-
-static ulong
-fcmp(Internal *n, Internal *m)
-{
- int i;
-
- if(IsWeird(m) || IsWeird(n)){
- /* BUG: should trap if not masked */
- return V|C;
- }
- i = fpicmp(n, m);
- if(i > 0)
- return C;
- else if(i == 0)
- return C|Z;
- else
- return N;
-}
-
-static void
-fld(void (*f)(Internal*, void*), int d, ulong ea, int n, FPenv *ufp)
-{
- void *mem;
-
- mem = (void*)ea;
- (*f)(&FR(d), mem);
- if(fpemudebug)
- print("MOV%c #%lux, F%d\n", n==8? 'D': 'F', ea, d);
-}
-
-static void
-fst(void (*f)(void*, Internal*), ulong ea, int s, int n, FPenv *ufp)
-{
- Internal tmp;
- void *mem;
-
- mem = (void*)ea;
- tmp = FR(s);
- if(fpemudebug)
- print("MOV%c F%d,#%lux\n", n==8? 'D': 'F', s, ea);
- (*f)(mem, &tmp);
-}
-
-static int
-condok(int cc, int c)
-{
- switch(c){
- case 0: /* Z set */
- return cc&Z;
- case 1: /* Z clear */
- return (cc&Z) == 0;
- case 2: /* C set */
- return cc&C;
- case 3: /* C clear */
- return (cc&C) == 0;
- case 4: /* N set */
- return cc&N;
- case 5: /* N clear */
- return (cc&N) == 0;
- case 6: /* V set */
- return cc&V;
- case 7: /* V clear */
- return (cc&V) == 0;
- case 8: /* C set and Z clear */
- return cc&C && (cc&Z) == 0;
- case 9: /* C clear or Z set */
- return (cc&C) == 0 || cc&Z;
- case 10: /* N set and V set, or N clear and V clear */
- return (~cc&(N|V))==0 || (cc&(N|V)) == 0;
- case 11: /* N set and V clear, or N clear and V set */
- return (cc&(N|V))==N || (cc&(N|V))==V;
- case 12: /* Z clear, and either N set and V set or N clear and V clear */
- return (cc&Z) == 0 && ((~cc&(N|V))==0 || (cc&(N|V))==0);
- case 13: /* Z set, or N set and V clear or N clear and V set */
- return (cc&Z) || (cc&(N|V))==N || (cc&(N|V))==V;
- case 14: /* always */
- return 1;
- case 15: /* never (reserved) */
- return 0;
- }
- return 0; /* not reached */
-}
-
-static void
-unimp(ulong pc, ulong op)
-{
- char buf[60];
-
- snprint(buf, sizeof(buf), "sys: fp: pc=%lux unimp fp 0x%.8lux", pc, op);
- if(fpemudebug)
- print("FPE: %s\n", buf);
- error(buf);
- /* no return */
-}
-
-static void
-fpemu(ulong pc, ulong op, Ureg *ur, FPenv *ufp)
-{
- int rn, rd, tag, o;
- long off;
- ulong ea;
- Internal tmp, *fm, *fn;
-
- /* note: would update fault status here if we noted numeric exceptions */
-
- /*
- * LDF, STF; 10.1.1
- */
- if(((op>>25)&7) == 6){
- if(op & (1<<22))
- unimp(pc, op); /* packed or extended */
- rn = (op>>16)&0xF;
- off = (op&0xFF)<<2;
- if((op & (1<<23)) == 0)
- off = -off;
- ea = REG(rn);
- if(rn == REGPC)
- ea += 8;
- if(op & (1<<24))
- ea += off;
- rd = (op>>12)&7;
- if(op & (1<<20)){
- if(op & (1<<15))
- fld(fpid2i, rd, ea, 8, ufp);
- else
- fld(fpis2i, rd, ea, 4, ufp);
- }else{
- if(op & (1<<15))
- fst(fpii2d, ea, rd, 8, ufp);
- else
- fst(fpii2s, ea, rd, 4, ufp);
- }
- if((op & (1<<24)) == 0)
- ea += off;
- if(op & (1<<21))
- REG(rn) = ea;
- return;
- }
-
- /*
- * CPRT/transfer, 10.3
- */
- if(op & (1<<4)){
- rd = (op>>12) & 0xF;
-
- /*
- * compare, 10.3.1
- */
- if(rd == 15 && op & (1<<20)){
- rn = (op>>16)&7;
- fn = &FR(rn);
- if(op & (1<<3)){
- fm = &fpconst[op&7];
- tag = 'C';
- }else{
- fm = &FR(op&7);
- tag = 'F';
- }
- switch((op>>21)&7){
- default:
- unimp(pc, op);
- case 4: /* CMF: Fn :: Fm */
- case 6: /* CMFE: Fn :: Fm (with exception) */
- ur->psr &= ~(N|C|Z|V);
- ur->psr |= fcmp(fn, fm);
- break;
- case 5: /* CNF: Fn :: -Fm */
- case 7: /* CNFE: Fn :: -Fm (with exception) */
- tmp = *fm;
- tmp.s ^= 1;
- ur->psr &= ~(N|C|Z|V);
- ur->psr |= fcmp(fn, &tmp);
- break;
- }
- if(fpemudebug)
- print("CMPF %c%d,F%ld =%x\n", tag, rn, op&7, ur->psr>>28);
- return;
- }
-
- /*
- * other transfer, 10.3
- */
- switch((op>>20)&0xF){
- default:
- unimp(pc, op);
- case 0: /* FLT */
- rn = (op>>16) & 7;
- fpiw2i(&FR(rn), &REG(rd));
- if(fpemudebug)
- print("MOVW[FD] R%d, F%d\n", rd, rn);
- break;
- case 1: /* FIX */
- if(op & (1<<3))
- unimp(pc, op);
- rn = op & 7;
- tmp = FR(rn);
- fpii2w(&REG(rd), &tmp);
- if(fpemudebug)
- print("MOV[FD]W F%d, R%d =%ld\n", rn, rd, REG(rd));
- break;
- case 2: /* FPSR := Rd */
- FPENV.status = REG(rd);
- if(fpemudebug)
- print("MOVW R%d, FPSR\n", rd);
- break;
- case 3: /* Rd := FPSR */
- REG(rd) = FPENV.status;
- if(fpemudebug)
- print("MOVW FPSR, R%d\n", rd);
- break;
- case 4: /* FPCR := Rd */
- FPENV.control = REG(rd);
- if(fpemudebug)
- print("MOVW R%d, FPCR\n", rd);
- break;
- case 5: /* Rd := FPCR */
- REG(rd) = FPENV.control;
- if(fpemudebug)
- print("MOVW FPCR, R%d\n", rd);
- break;
- }
- return;
- }
-
- /*
- * arithmetic
- */
-
- if(op & (1<<3)){ /* constant */
- fm = &fpconst[op&7];
- tag = 'C';
- }else{
- fm = &FR(op&7);
- tag = 'F';
- }
- rd = (op>>12)&7;
- o = (op>>20)&0xF;
- if(op & (1<<15)){ /* monadic */
- FP1 *fp;
- fp = &optab1[o];
- if(fp->f == nil)
- unimp(pc, op);
- if(fpemudebug)
- print("%s %c%ld,F%d\n", fp->name, tag, op&7, rd);
- (*fp->f)(fm, &FR(rd));
- } else {
- FP2 *fp;
- fp = &optab2[o];
- if(fp->f == nil)
- unimp(pc, op);
- rn = (op>>16)&7;
- if(fpemudebug)
- print("%s %c%ld,F%d,F%d\n", fp->name, tag, op&7, rn, rd);
- (*fp->f)(*fm, FR(rn), &FR(rd));
- }
-}
-
-/*
- * returns the number of FP instructions emulated
- */
-int
-fpiarm(Ureg *ur)
-{
- ulong op, o;
- FPenv *ufp;
- int n;
-
-#ifndef R13OK
-/* ur->type = &ur->pc+1; /* calculate kernel sp/R13 and put it here for roff[13] */
- ur->type = (ulong)(ur + 1);
-#endif
- if (up == nil)
- panic("fpiarm not in a process");
- ufp = &up->env->fpu; /* because all the state is in Osenv, it need not be saved/restored */
- if(ufp->fpistate != FPACTIVE) {
- ufp->fpistate = FPACTIVE;
- ufp->control = 0;
- ufp->status = (0x01<<28)|(1<<12); /* software emulation, alternative C flag */
- for(n = 0; n < 8; n++)
- FR(n) = fpconst[0];
- }
- for(n=0;;n++){
- op = getulong(ur->pc);
- o = (op>>24) & 0xF;
- if(((op>>8) & 0xF) != 1 || o != 0xE && (o&~1) != 0xC)
- break;
- if(condok(ur->psr, op>>28))
- fpemu(ur->pc, op, ur, ufp);
- ur->pc += 4;
- if(anyhigher())
- sched();
- }
- return n;
-}
diff --git a/os/pxa/gpio.c b/os/pxa/gpio.c
deleted file mode 100644
index 5914f8c4..00000000
--- a/os/pxa/gpio.c
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "u.h"
-#include "mem.h"
-#include "../port/lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-static ulong gpioreserved[3];
-static Lock gpiolock;
-
-void
-gpioreserve(int n)
-{
- ulong mask, *r;
-
- r = &gpioreserved[GPR(n)];
- mask = GPB(n);
- ilock(&gpiolock);
- if(*r & mask)
- panic("gpioreserve: duplicate use of GPIO %d", n);
- *r |= mask;
- iunlock(&gpiolock);
-}
-
-/*
- * set direction and alternative function bits in the GPIO control register,
- * following the configuration bits in cfg.
- */
-void
-gpioconfig(int n, ulong cfg)
-{
- GpioReg *g;
- ulong o, m, *r;
-
- m = GPB(n);
- o = n>>5;
- ilock(&gpiolock);
- g = GPIOREG;
- r = &g->gpdr[o];
- if(cfg & Gpio_out)
- *r |= m;
- else
- *r &= ~m;
- r = &g->gafr[o*2];
- *r = (*r & ~GPAF(n, 3)) | GPAF(n, cfg&3);
- iunlock(&gpiolock);
-}
-
-ulong
-gpioget(int n)
-{
- ulong mask, o;
-
- mask = GPB(n);
- o = GPR(n);
- return GPIOREG->gplr[o] & mask;
-}
-
-void
-gpioset(int n, int v)
-{
- GpioReg *g;
- ulong mask, o;
-
- g = GPIOREG;
- mask = GPB(n);
- o = GPR(n);
- ilock(&gpiolock);
- if(v)
- g->gpsr[o] = mask;
- else
- g->gpcr[o] = mask;
- iunlock(&gpiolock);
-}
-
-void
-gpiorelease(int n)
-{
- ulong mask, *r;
-
- mask = GPB(n);
- r = &gpioreserved[GPR(n)];
- ilock(&gpiolock);
- if((*r & mask) != mask)
- panic("gpiorelease: unexpected release of GPIO %d", n);
- *r &= ~mask;
- iunlock(&gpiolock);
-}
diff --git a/os/pxa/i2c.c b/os/pxa/i2c.c
deleted file mode 100644
index b45542ae..00000000
--- a/os/pxa/i2c.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * basic read/write interface to PXA25x I⁲C bus (master mode)
- * 7 bit addressing only.
- * TO DO:
- * - enable unit clock
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "io.h"
-
-typedef struct Ctlr Ctlr;
-typedef struct I2Cregs I2Cregs;
-struct I2Cregs {
- ulong ibmr; /* bus monitor */
- ulong pad0;
- ulong idbr; /* data buffer */
- ulong pad1;
- ulong icr; /* control */
- ulong pad2;
- ulong isr; /* status */
- ulong pad3;
- ulong isar; /* slave address */
-};
-
-enum {
- /* ibmr */
- Scls= 1<<1, /* SCL pin status */
- Sdas= 1<<0, /* SDA pin status */
-
- /* icr */
- Fm= 1<<15, /* =0, 100 kb/sec; =1, 400 kb/sec */
- Ur= 1<<14, /* reset the i2c unit only */
- Sadie= 1<<13, /* slave address detected interrupt enable */
- Aldie= 1<<12, /* arbitration loss detected interrupt enable (master mode) */
- Ssdie= 1<<11, /* stop detected interrupt enable (slave mode) */
- Beie= 1<<10, /* bus error interrupt enable */
- Irfie= 1<<9, /* idbr receive full, interrupt enable */
- Iteie= 1<<8, /* idbr transmit empty interrupt enable */
- Gcd= 1<<7, /* disable response to general call message (slave); must be set if master uses g.c. */
- Scle= 1<<6, /* SCL enable: enable clock output for master mode */
- Iue= 1<<5, /* enable i2c (default: slave) */
- Ma= 1<<4, /* master abort (send STOP without data) */
- Tb= 1<<3, /* transfer byte on i2c bus */
- Ack= 0<<2,
- Nak= 1<<2,
- Stop= 1<<1, /* send a stop */
- Start= 1<<0, /* send a stop */
-
- /* isr */
- Bed= 1<<10, /* bus error detected */
- Sad= 1<<9, /* slave address detected */
- Gcad= 1<<8, /* general call address detected */
- Irf= 1<<7, /* idbr receive full */
- Ite= 1<<6, /* idbr transmit empty */
- Ald= 1<<5, /* arbitration loss detected (multi-master) */
- Ssd= 1<<4, /* slave stop detected */
- Ibb= 1<<3, /* i2c bus is busy */
- Ub= 1<<2, /* unit is busy (between start and stop) */
- Nakrcv= 1<<1, /* nak received or sent a NAK */
- Rwm= 1<<0, /* =0, master transmit (or slave receive); =1, master receive (or slave transmit) */
- Err= Bed | Ssd,
-
- /* isar address (0x7F bits) */
-
- /* others */
- Rbit = 1<<0, /* bit in address byte denoting read */
- Wbit= 0<<0,
-
- MaxIO = 8192, /* largest transfer done at once (can change) */
- MaxSA= 2, /* largest subaddress; could be FIFOsize */
- Bufsize = MaxIO, /* subaddress bytes don't go in buffer */
- Freq = 0, /* set to Fm for high-speed */
-// I2Ctimeout = 125, /* msec (can change) */
- I2Ctimeout = 10000, /* msec when Chatty */
-
- Chatty = 0,
-};
-
-#define DPRINT if(Chatty)print
-
-/*
- * I2C software structures
- */
-
-struct Ctlr {
- Lock;
- QLock io;
- int init;
- int polling; /* eg, when running before system set up */
- I2Cregs* regs; /* hardware registers */
-
- /* controller state (see below) */
- int status;
- int phase;
- Rendez r;
-
- /* transfer parameters */
- int addr;
- int salen; /* bytes remaining of subaddress */
- int offset; /* sub-addressed offset */
- int cntl; /* everything but transfer length */
- int rdcount; /* requested read transfer size */
- Block* b;
-};
-
-enum {
- /* Ctlr.state */
- Idle,
- Done,
- Failed,
- Busy,
- Address,
- Subaddress,
- Read,
- Write,
- Halting,
-};
-
-static Ctlr i2cctlr[1];
-
-static void interrupt(Ureg*, void*);
-static int readyxfer(Ctlr*, int);
-static void rxstart(Ctlr*);
-static void txstart(Ctlr*);
-static void stopxfer(Ctlr*);
-static void txoffset(Ctlr*, ulong, int);
-static int idlectlr(Ctlr*);
-
-static void
-i2cdump(char *t, I2Cregs *i2c)
-{
- iprint("i2c %s: ibmr=%.4lux icr=%.4lux isr=%.4lux\n", t, i2c->ibmr, i2c->icr, i2c->isr);
-}
-
-static void
-initialise(I2Cregs *i2c, int eintr)
-{
- int ctl;
-
- /* initialisation (see p. 9-11 on) */
- i2c->isar = 0;
- ctl = Freq | Gcd | Scle | Iue;
- if(eintr)
- ctl |= Beie | Irfie; /* Iteie set by txstart */
- i2c->icr = ctl;
- if(Chatty)
- iprint("ctl=%4.4ux icr=%4.4lux\n", ctl, i2c->icr);
-}
-
-/*
- * called by the reset routine of any driver using the IIC
- */
-void
-i2csetup(int polling)
-{
- I2Cregs *i2c;
- Ctlr *ctlr;
-
- ctlr = i2cctlr;
- ctlr->polling = polling;
- i2c = KADDR(PHYSI2C);
- ctlr->regs = i2c;
- if(!polling){
- if(ctlr->init == 0){
- initialise(i2c, 1);
- ctlr->init = 1;
- intrenable(IRQ, IRQi2c, interrupt, i2cctlr, "i2c");
- if(Chatty)
- i2cdump("init", i2c);
- }
- }else
- initialise(i2c, 0);
-}
-
-static void
-done(Ctlr *ctlr)
-{
- ctlr->phase = Done;
- wakeup(&ctlr->r);
-}
-
-static void
-failed(Ctlr *ctlr)
-{
- ctlr->phase = Failed;
- wakeup(&ctlr->r);
-}
-
-static void
-interrupt(Ureg*, void *arg)
-{
- int sts, idl;
- Ctlr *ctlr;
- Block *b;
- I2Cregs *i2c;
- char xx[12];
-
- ctlr = arg;
- i2c = ctlr->regs;
- idl = (i2c->ibmr & 3) == 3;
- if(Chatty && ctlr->phase != Read && ctlr->phase != Write){
- snprint(xx, sizeof(xx), "intr %d", ctlr->phase);
- i2cdump(xx, i2c);
- }
- sts = i2c->isr;
- if(sts & (Bed | Sad | Gcad | Ald))
- iprint("i2c: unexpected status: %.4ux", sts);
- i2c->isr = sts;
- ctlr->status = sts;
- i2c->icr &= ~(Start | Stop | Nak | Ma | Iteie);
- if(sts & Err){
- failed(ctlr);
- return;
- }
- switch(ctlr->phase){
- default:
- iprint("i2c: unexpected interrupt: p-%d s=%.4ux\n", ctlr->phase, sts);
- break;
-
- case Halting:
- ctlr->phase = Idle;
- break;
-
- case Subaddress:
- if(ctlr->salen){
- /* push out next byte of subaddress */
- ctlr->salen -= 8;
- i2c->idbr = ctlr->offset >> ctlr->salen;
- i2c->icr |= Aldie | Tb | Iteie;
- break;
- }
- /* subaddress finished */
- if(ctlr->cntl & Rbit){
- /* must readdress if reading to change mode */
- i2c->idbr = (ctlr->addr << 1) | Rbit;
- i2c->icr |= Start | Tb | Iteie;
- ctlr->phase = Address; /* readdress */
- break;
- }
- /* FALL THROUGH if writing */
- case Address:
- /* if not sub-addressed, rxstart/txstart */
- if(ctlr->cntl & Rbit)
- rxstart(ctlr);
- else
- txstart(ctlr);
- break;
-
- case Read:
- b = ctlr->b;
- if(b == nil)
- panic("i2c: no buffer");
- /* master receive: next byte */
- if(sts & Irf){
- ctlr->rdcount--;
- if(b->wp < b->lim)
- *b->wp++ = i2c->idbr;
- }
- if(ctlr->rdcount <= 0 || sts & Nakrcv || idl){
- if(Chatty)
- iprint("done: %.4ux\n", sts);
- done(ctlr);
- break;
- }
- rxstart(ctlr);
- break;
-
- case Write:
- b = ctlr->b;
- if(b == nil)
- panic("i2c: no buffer");
- /* account for data transmitted */
- if(BLEN(b) <= 0 || sts & Nakrcv){
- done(ctlr);
- break;
- }
- txstart(ctlr);
- break;
- }
-}
-
-static int
-isdone(void *a)
-{
- return ((Ctlr*)a)->phase < Busy;
-}
-
-static int
-i2cerror(char *s)
-{
- DPRINT("i2c error: %s\n", s);
- if(up)
- error(s);
- /* no current process, don't call error */
- return -1;
-}
-
-static char*
-startxfer(I2Cdev *d, int op, Block *b, int n, ulong offset)
-{
- I2Cregs *i2c;
- Ctlr *ctlr;
- int i, p, s;
-
- ctlr = i2cctlr;
- if(up){
- qlock(&ctlr->io);
- if(waserror()){
- qunlock(&ctlr->io);
- nexterror();
- }
- }
- ilock(ctlr);
- if(!idlectlr(ctlr)){
- iunlock(ctlr);
- if(up)
- error("bus confused");
- return "bus confused";
- }
- if(ctlr->phase >= Busy)
- panic("i2c: ctlr busy");
- ctlr->cntl = op;
- ctlr->b = b;
- ctlr->rdcount = n;
- ctlr->addr = d->addr;
- i2c = ctlr->regs;
- ctlr->salen = d->salen*8;
- ctlr->offset = offset;
- if(ctlr->salen){
- ctlr->phase = Subaddress;
- op = Wbit;
- }else
- ctlr->phase = Address;
- i2c->idbr = (d->addr<<1) | op; /* 7-bit address + R/nW */
- i2c->icr |= Start | Tb | Iteie;
- if(Chatty)
- i2cdump("start", i2c);
- iunlock(ctlr);
-
- /* wait for it */
- if(ctlr->polling){
- for(i=0; !isdone(ctlr); i++){
- delay(2);
- interrupt(nil, ctlr);
- }
- }else
- tsleep(&ctlr->r, isdone, ctlr, I2Ctimeout);
-
- ilock(ctlr);
- p = ctlr->phase;
- s = ctlr->status;
- ctlr->b = nil;
- if(ctlr->phase != Done && ctlr->phase != Idle)
- stopxfer(ctlr);
- iunlock(ctlr);
-
- if(up){
- poperror();
- qunlock(&ctlr->io);
- }
- if(p != Done || s & (Bed|Ald)){ /* CHECK; time out */
- if(s & Ald)
- return "i2c lost arbitration";
- if(s & Bed)
- return "i2c bus error";
- if(s & Ssd)
- return "i2c transfer aborted"; /* ?? */
- if(0 && p != Done)
- return "i2c timed out";
- sprint(up->genbuf, "i2c error: phase=%d status=%.4ux", p, s);
- return up->genbuf;
- }
- return nil;
-}
-
-long
-i2csend(I2Cdev *d, void *buf, long n, ulong offset)
-{
- Block *b;
- char *e;
-
- if(n <= 0)
- return 0;
- if(n > MaxIO)
- n = MaxIO;
-
- if(up){
- b = allocb(n);
- if(b == nil)
- error(Enomem);
- if(waserror()){
- freeb(b);
- nexterror();
- }
- }else{
- b = iallocb(n);
- if(b == nil)
- return -1;
- }
- memmove(b->wp, buf, n);
- b->wp += n;
- e = startxfer(d, 0, b, 0, offset);
- if(up)
- poperror();
- n -= BLEN(b); /* residue */
- freeb(b);
- if(e)
- return i2cerror(e);
- return n;
-}
-
-long
-i2crecv(I2Cdev *d, void *buf, long n, ulong offset)
-{
- Block *b;
- long nr;
- char *e;
-
- if(n <= 0)
- return 0;
- if(n > MaxIO)
- n = MaxIO;
-
- if(up){
- b = allocb(n);
- if(b == nil)
- error(Enomem);
- if(waserror()){
- freeb(b);
- nexterror();
- }
- }else{
- b = iallocb(n);
- if(b == nil)
- return -1;
- }
- e = startxfer(d, Rbit, b, n, offset);
- nr = BLEN(b);
- if(nr > 0)
- memmove(buf, b->rp, nr);
- if(up)
- poperror();
- freeb(b);
- if(e)
- return i2cerror(e);
- return nr;
-}
-
-/*
- * the controller must be locked for the following functions
- */
-
-static int
-readyxfer(Ctlr *ctlr, int phase)
-{
- I2Cregs *i2c;
-
- i2c = ctlr->regs;
- if((i2c->isr & Bed) != 0){
- failed(ctlr);
- return 0;
- }
- ctlr->phase = phase;
- return 1;
-}
-
-/*
- * start a master transfer to receive the next byte of data
- */
-static void
-rxstart(Ctlr *ctlr)
-{
- Block *b;
- int cntl;
-
- b = ctlr->b;
- if(b == nil || ctlr->rdcount<= 0){
- done(ctlr);
- return;
- }
- if(!readyxfer(ctlr, Read))
- return;
- cntl = Aldie | Tb;
- if(ctlr->rdcount == 1)
- cntl |= Stop | Nak | Iteie; /* last byte of transfer */
- ctlr->regs->icr |= cntl;
-}
-
-/*
- * start a master transfer to send the next chunk of data
- */
-static void
-txstart(Ctlr *ctlr)
-{
- Block *b;
- int cntl;
- long nb;
- I2Cregs *i2c;
-
- b = ctlr->b;
- if(b == nil || (nb = BLEN(b)) <= 0){
- done(ctlr);
- return;
- }
- if(!readyxfer(ctlr, Write))
- return;
- i2c = ctlr->regs;
- i2c->idbr = *b->rp++;
- cntl = Aldie | Tb | Iteie;
- if(nb == 1)
- cntl |= Stop;
- i2c->icr |= cntl;
-}
-
-/*
- * stop a transfer if one is in progress
- */
-static void
-stopxfer(Ctlr *ctlr)
-{
- I2Cregs *i2c;
-
- i2c = ctlr->regs;
- if((i2c->isr & Ub) == 0){
- ctlr->phase = Idle;
- return;
- }
- if((i2c->isr & Ibb) == 0 && ctlr->phase != Halting){
- ctlr->phase = Halting; /* interrupt will clear the state */
- i2c->icr |= Ma;
- }
- /* if that doesn't clear it by the next operation, idlectlr will do so below */
-}
-
-static int
-idlectlr(Ctlr *ctlr)
-{
- I2Cregs *i2c;
-
- i2c = ctlr->regs;
- if((i2c->isr & Ibb) == 0){
- if((i2c->isr & Ub) == 0){
- ctlr->phase = Idle;
- return 1;
- }
- iprint("i2c: bus free, ctlr busy: isr=%.4lux icr=%.4lux\n", i2c->isr, i2c->icr);
- }
- /* hit it with the hammer, soft reset */
- iprint("i2c: soft reset\n");
- i2c->icr = Ur;
- iunlock(ctlr);
- delay(1);
- ilock(ctlr);
- initialise(i2c, !ctlr->polling);
- ctlr->phase = Idle;
- return (i2c->isr & (Ibb | Ub)) == 0;
-}
diff --git a/os/pxa/l.s b/os/pxa/l.s
deleted file mode 100644
index df246a04..00000000
--- a/os/pxa/l.s
+++ /dev/null
@@ -1,548 +0,0 @@
-#include "mem.h"
-
-#define CPWAIT MRC CpMMU, 0, R2, C(2), C(0), 0; MOVW R2, R2; SUB $4, R15
-
-/*
- * Entered here from the boot loader with
- * supervisor mode, interrupts disabled;
- * MMU, IDC and WB disabled.
- */
-
-TEXT _startup(SB), $-4
- MOVW $setR12(SB), R12 /* static base (SB) */
- MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 /* ensure SVC mode with interrupts disabled */
- MOVW R1, CPSR
- MOVW $(MACHADDR+BY2PG-4), R13 /* stack; 4 bytes for link */
-
- BL main(SB)
-dead:
- B dead
- BL _div(SB) /* hack to get _div etc loaded */
-
-TEXT getcpuid(SB), $-4
- MRC CpMMU, 0, R0, C(CpCPUID), C(0)
- RET
-
-TEXT mmugetctl(SB), $-4
- MRC CpMMU, 0, R0, C(CpControl), C(0)
- RET
-
-TEXT mmugetdac(SB), $-4
- MRC CpMMU, 0, R0, C(CpDAC), C(0)
- RET
-
-TEXT mmugetfar(SB), $-4
- MRC CpMMU, 0, R0, C(CpFAR), C(0)
- RET
-
-TEXT mmugetfsr(SB), $-4
- MRC CpMMU, 0, R0, C(CpFSR), C(0)
- RET
-
-TEXT mmuputdac(SB), $-4
- MCR CpMMU, 0, R0, C(CpDAC), C(0)
- CPWAIT
- RET
-
-TEXT mmuputfsr(SB), $-4
- MCR CpMMU, 0, R0, C(CpFSR), C(0)
- CPWAIT
- RET
-
-TEXT mmuputttb(SB), $-4
- MCR CpMMU, 0, R0, C(CpTTB), C(0)
- CPWAIT
- RET
-
-TEXT mmuputctl(SB), $-4
- MCR CpMMU, 0, R0, C(CpControl), C(0)
- CPWAIT
- RET
-
-TEXT tlbinvalidateall(SB), $-4
- MCR CpMMU, 0, R0, C(CpTLBops), C(7)
- CPWAIT
- RET
-
-TEXT itlbinvalidate(SB), $-4
- MCR CpMMU, 0, R0, C(CpTLBops), C(5), 1
- CPWAIT
- RET
-
-TEXT dtlbinvalidate(SB), $-4
- MCR CpMMU, 0, R0, C(CpTLBops), C(6), 1
- CPWAIT
- RET
-
-TEXT mmuenable(SB), $-4
-
- MOVW $1, R1
- MCR CpMMU, 0, R1, C(CpDAC), C(3) /* set domain 0 to client */
-
- /* disable and invalidate all caches and TLB's before (re-)enabling MMU */
- MOVW $(CpCwpd | CpCsystem), R1
- MRC CpMMU, 0, R1, C(CpControl), C(0)
- CPWAIT
-
- MOVW $0, R1 /* disable everything */
- MCR CpMMU, 0, R1, C(CpCacheCtl), C(7), 0 /* invalidate I&D Caches and BTB */
- MCR CpMMU, 0, R1, C(CpCacheCtl), C(10), 4 /* drain write and fill buffer */
- MCR CpMMU, 0, R1, C(CpTLBops), C(7), 0 /* invalidate I&D TLB */
-
- /* enable desired mmu mode (R0) */
- MCR CpMMU, 0, R0, C(1), C(0)
- CPWAIT
- RET /* start running in remapped area */
-
-TEXT setr13(SB), $-4
- MOVW 4(FP), R1
-
- MOVW CPSR, R2
- BIC $PsrMask, R2, R3
- ORR R0, R3
- MOVW R3, CPSR
-
- MOVW R13, R0
- MOVW R1, R13
-
- MOVW R2, CPSR
- RET
-
-TEXT vectors(SB), $-4
- MOVW 0x18(R15), R15 /* reset */
- MOVW 0x18(R15), R15 /* undefined */
- MOVW 0x18(R15), R15 /* SWI */
- MOVW 0x18(R15), R15 /* prefetch abort */
- MOVW 0x18(R15), R15 /* data abort */
- MOVW 0x18(R15), R15 /* reserved */
- MOVW 0x18(R15), R15 /* IRQ */
- MOVW 0x18(R15), R15 /* FIQ */
-
-TEXT vtable(SB), $-4
- WORD $_vsvc(SB) /* reset, in svc mode already */
- WORD $_vund(SB) /* undefined, switch to svc mode */
- WORD $_vsvc(SB) /* swi, in svc mode already */
- WORD $_vpab(SB) /* prefetch abort, switch to svc mode */
- WORD $_vdab(SB) /* data abort, switch to svc mode */
- WORD $_vsvc(SB) /* reserved */
- WORD $_virq(SB) /* IRQ, switch to svc mode */
- WORD $_vfiq(SB) /* FIQ, switch to svc mode */
-
-TEXT _vund(SB), $-4
- MOVM.DB [R0-R3], (R13)
- MOVW $PsrMund, R0
- B _vswitch
-
-TEXT _vsvc(SB), $-4
- MOVW.W R14, -4(R13)
- MOVW CPSR, R14
- MOVW.W R14, -4(R13)
- BIC $PsrMask, R14
- ORR $(PsrDirq|PsrDfiq|PsrMsvc), R14
- MOVW R14, CPSR
- MOVW $PsrMsvc, R14
- MOVW.W R14, -4(R13)
- B _vsaveu
-
-TEXT _vpab(SB), $-4
- MOVM.DB [R0-R3], (R13)
- MOVW $PsrMabt, R0
- B _vswitch
-
-TEXT _vdab(SB), $-4
- MOVM.DB [R0-R3], (R13)
- MOVW $(PsrMabt+1), R0
- B _vswitch
-
-TEXT _vfiq(SB), $-4 /* FIQ */
- MOVM.DB [R0-R3], (R13)
- MOVW $PsrMfiq, R0
- B _vswitch
-
-TEXT _virq(SB), $-4 /* IRQ */
- MOVM.DB [R0-R3], (R13)
- MOVW $PsrMirq, R0
-
-_vswitch: /* switch to svc mode */
- MOVW SPSR, R1
- MOVW R14, R2
- MOVW R13, R3
-
- MOVW CPSR, R14
- BIC $PsrMask, R14
- ORR $(PsrDirq|PsrDfiq|PsrMsvc), R14
- MOVW R14, CPSR
-
- MOVM.DB.W [R0-R2], (R13)
- MOVM.DB (R3), [R0-R3]
-
-_vsaveu: /* Save Registers */
- MOVW.W R14, -4(R13) /* save link */
- MCR CpMMU, 0, R0, C(0), C(0), 0
-
- SUB $8, R13
- MOVM.DB.W [R0-R12], (R13)
-
- MOVW R0, R0 /* gratuitous noop */
-
- MOVW $setR12(SB), R12 /* static base (SB) */
- MOVW R13, R0 /* argument is ureg */
- SUB $8, R13 /* space for arg+lnk*/
- BL trap(SB)
-
-_vrfe: /* Restore Regs */
- MOVW CPSR, R0 /* splhi on return */
- ORR $(PsrDirq|PsrDfiq), R0, R1
- MOVW R1, CPSR
- ADD $(8+4*15), R13 /* [r0-R14]+argument+link */
- MOVW (R13), R14 /* restore link */
- MOVW 8(R13), R0
- MOVW R0, SPSR
- MOVM.DB.S (R13), [R0-R14] /* restore user registers */
- MOVW R0, R0 /* gratuitous nop */
- ADD $12, R13 /* skip saved link+type+SPSR*/
- RFE /* MOVM.IA.S.W (R13), [R15] */
-
-TEXT splhi(SB), $-4
- MOVW CPSR, R0
- ORR $(PsrDirq), R0, R1
- MOVW R1, CPSR
- MOVW $(MACHADDR), R6
- MOVW R14, (R6) /* m->splpc */
- RET
-
-TEXT spllo(SB), $-4
- MOVW CPSR, R0
- BIC $(PsrDirq|PsrDfiq), R0, R1
- MOVW R1, CPSR
- RET
-
-TEXT splx(SB), $-4
- MOVW $(MACHADDR), R6
- MOVW R14, (R6) /* m->splpc */
-
-TEXT splxpc(SB), $-4
- MOVW R0, R1
- MOVW CPSR, R0
- MOVW R1, CPSR
- RET
-
-TEXT spldone(SB), $-4
- RET
-
-TEXT islo(SB), $-4
- MOVW CPSR, R0
- AND $(PsrDirq), R0
- EOR $(PsrDirq), R0
- RET
-
-TEXT splfhi(SB), $-4
- MOVW CPSR, R0
- ORR $(PsrDfiq|PsrDirq), R0, R1
- MOVW R1, CPSR
- RET
-
-TEXT splflo(SB), $-4
- MOVW CPSR, R0
- BIC $(PsrDfiq), R0, R1
- MOVW R1, CPSR
- RET
-
-TEXT getcpsr(SB), $-4
- MOVW CPSR, R0
- RET
-
-TEXT getspsr(SB), $-4
- MOVW SPSR, R0
- RET
-
-TEXT getcallerpc(SB), $-4
- MOVW 0(R13), R0
- RET
-
-TEXT _tas(SB), $-4
- MOVW R0, R1
- MOVW $0xDEADDEAD, R2
- SWPW R2, (R1), R0
- RET
-
-TEXT setlabel(SB), $-4
- MOVW R13, 0(R0) /* sp */
- MOVW R14, 4(R0) /* pc */
- MOVW $0, R0
- RET
-
-TEXT gotolabel(SB), $-4
- MOVW 0(R0), R13 /* sp */
- MOVW 4(R0), R14 /* pc */
- MOVW $1, R0
- RET
-
-/*
- * flush (invalidate) the whole icache
- */
-TEXT icflushall(SB), $-4
-_icflushall:
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(5), 0 /* clean i-cache and branch buffer */
- CPWAIT
- RET
-
-/*
- * invalidate part of i-cache and invalidate branch target buffer
- */
-TEXT icflush(SB), $-4
- MOVW 4(FP), R1
- CMP $(CACHESIZE/2), R1
- BGE _icflushall
- ADD R0, R1
- BIC $(CACHELINESZ-1), R0
-icflush1:
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(5), 1 /* clean entry */
- ADD $CACHELINESZ, R0
- CMP R1, R0
- BLO icflush1
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(5), 6 /* invalidate branch target buffer */
- CPWAIT
- RET
-
-/*
- * write back whole data cache and drain write buffer
- */
-TEXT dcflushall(SB), $-4
-_dcflushall:
- MOVW $(DCFADDR), R0
- ADD $CACHESIZE, R0, R1
-dcflushall1:
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(2), 5 /* allocate line */
- ADD $CACHELINESZ, R0
- CMP R1,R0
- BNE dcflushall1
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 4 /* drain write buffer */
- CPWAIT
- RET
-
-/*
- * write back a given region and drain write buffer
- */
-TEXT dcflush(SB), $-4
- MOVW 4(FP), R1
- CMP $(CACHESIZE/2), R1
- BGE _dcflushall
- ADD R0, R1
- BIC $(CACHELINESZ-1), R0
-dcflush1:
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 1 /* clean entry */
- ADD $CACHELINESZ, R0
- CMP R1, R0
- BLO dcflush1
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 4 /* drain write buffer */
- CPWAIT
- RET
-
-#ifdef NOTYET
-/*
- * write back mini data cache
- * TO DO: need to allocate pair of unused 2k blocks and read them alternately
- */
-TEXT minidcflush(SB), $-4
- MOVW $(MCFADDR), R0
- ADD $(16*CACHELINESZ), R0, R1
-
-wbbflush:
- MOVW.P CACHELINESZ(R0), R2
- CMP R1,R0
- BNE wbbflush
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 4 /* drain write buffer */
- CPWAIT
- RET
-#endif
-
-/*
- * invalidate data caches (main and mini)
- */
-TEXT dcinval(SB), $-4
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(6), 0
- CPWAIT
- RET
-
-/* for devboot */
-TEXT gotopc(SB), $-4
- MOVW R0, R1
- MOVW $0, R0
- MOVW R1, PC
- RET
-
-TEXT idle(SB), $-4
- MOVW $1, R0 /* idle mode */
- MCR CpPWR, 0, R0, C(7), C(0), 0
- RET
-
-TEXT getcclkcfg(SB), $-4
- MRC CpPWR, 0, R0, C(6), C(0), 0
- RET
-
-TEXT putcclkcfg(SB), $-4
- MCR CpPWR, 0, R0, C(6), C(0), 0
- RET
-
-#ifdef NOTYET
-/*
- * the following code is considerably modified from the
- * sleep code by nemo@gsyc.escet.urjc.es for Plan 9, but that's
- * where it started. in particular, there's no need to save regs in all modes,
- * since here we're called from kernel main level (a kproc) so nothing is live;
- * the only regs needed are the various R13s, but we have trap restore them on resume.
- * similarly there's no need to save SPSR, CPSR, etc. (even CpPID isn't really needed here).
- */
-
-#define MDREFR_k1db2 (1<<22)
-#define MDREFR_slfrsh (1<<31) /* self refresh */
-#define MDREFR_e1pin (1<<20)
-#define MSC_rt ((3<<16)|(3<<0))
-#define MDCFNG_de ((3<<16)|(3<<0)) /* dram enable, banks (3 2), (1 0) */
-
-TEXT suspenditall(SB), $-4
- MOVW.W R14, -4(R13)
- /* push mmu state on stack */
- MRC CpMMU, 0, R1, C(CpDAC), C(0)
- MRC CpMMU, 0, R2, C(CpTTB), C(0)
- MRC CpMMU, 0, R3, C(CpPID), C(0)
- MRC CpMMU, 0, R4, C(CpControl), C(0)
- MOVM.DB.W [R1-R4], (R13)
- /* if pspr by convention held a stack pointer pointing to a pc we wouldn't need power_state */
- MOVW R13, power_state+0(SB)
-
- BL dcflushall(SB)
- /* don't write DRAM after this */
-
- MOVW $PHYSPOWER, R3
-
- /* put resume address in scratchpad for boot loader */
- MOVW $power_resume+0(SB), R2
- MOVW R2, 0x8(R3) /* pspr */
-
- /* disable clock switching */
- MCR CpPWR, 0, R1, C(CpTest), C(0x2), 2
-
- /* adjust mem timing first to avoid processor bug causing hang */
- MOVW $MDCNFG, R5
- MOVW 0x1c(R5), R2
- ORR $(MDREFR_k1db2), R2
- MOVW R2, 0x1c(R5)
-
- /* set PLL to lower speed w/ delay */
- MOVW $(120*206),R0
-l11: SUB $1,R0
- BGT l11
- MOVW $0, R2
- MOVW R2, 0x14(R3) /* ppcr */
- MOVW $(120*206),R0
-l12: SUB $1,R0
- BGT l12
-
- /*
- * SA1110 fix for various suspend bugs in pre-B4 chips (err. 14-16, 18):
- * set up register values here for use in code below that is at most
- * one cache line (32 bytes) long, to run without DRAM.
- */
- /* 1. clear RT in MSCx (R1, R7, R8) without changing other bits */
- MOVW 0x10(R5), R1 /* MSC0 */
- BIC $(MSC_rt), R1
- MOVW 0x14(R5), R7 /* MSC1 */
- BIC $(MSC_rt), R7
- MOVW 0x2c(R5), R8 /* MSC2 */
- BIC $(MSC_rt), R8
- /* 2. clear DRI0-11 in MDREFR (R4) without changing other bits */
- MOVW 0x1c(R5), R4
- BIC $(0xfff0), R4
- /* 3. set SLFRSH in MDREFR (R6) without changing other bits */
- ORR $(MDREFR_slfrsh), R4, R6
- /* 4. clear DE in MDCNFG (R9), and any other bits desired */
- MOVW 0x0(R5), R9
- BIC $(MDCFNG_de), R9
- /* 5. clear SLFRSH and E1PIN (R10), without changing other bits */
- BIC $(MDREFR_slfrsh), R4, R10
- BIC $(MDREFR_e1pin), R10
- /* 6. force sleep mode in PMCR (R2) */
- MOVW $1,R2
- MOVW suspendcode+0(SB), R0
- B (R0) /* off to do it */
-
-/*
- * the following is copied by trap.c to a cache-aligned area (suspendcode),
- * so that it can all run during disabling of DRAM
- */
-TEXT _suspendcode(SB), $-4
- /* 1: clear RT field of all MSCx registers */
- MOVW R1, 0x10(R5)
- MOVW R7, 0x14(R5)
- MOVW R8, 0x2c(R5)
- /* 2: clear DRI field in MDREFR */
- MOVW R4, 0x1c(R5)
- /* 3: set SLFRSH bit in MDREFR */
- MOVW R6, 0x1c(R5)
- /* 4: clear DE bits in MDCFNG */
- MOVW R9, 0x0(R5)
- /* 5: clear SLFRSH and E1PIN in MDREFR */
- MOVW R10, 0x1c(R5)
- /* 6: suspend request */
- MOVW R2, 0x0(R3) /* pmcr */
- B 0(PC) /* wait for it */
-
-/*
- * The boot loader comes here after the resume.
- */
-TEXT power_resume(SB), $-4
- MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R0
- MOVW R0, CPSR /* svc mode, interrupts off */
- MOVW $setR12(SB), R12
-
- /* flush caches */
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(7), 0
- /* drain prefetch */
- MOVW R0,R0
- MOVW R0,R0
- MOVW R0,R0
- MOVW R0,R0
- /* drain write buffer */
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 4
- /* flush tlb */
- MCR CpMMU, 0, R0, C(CpTLBops), C(7)
-
- /* restore state */
- MOVW power_state+0(SB), R13
- MOVM.IA.W (R13), [R1-R4]
- MOVW.P 4(R13), R14
-
- MCR CpMMU, 0, R1, C(CpDAC), C(0x0)
- MCR CpMMU, 0, R2, C(CpTTB), C(0x0)
- MCR CpMMU, 0, R3, C(CpPID), C(0x0)
- MCR CpMMU, 0, R4, C(CpControl), C(0x0) /* enable cache and mmu */
- MOVW R0,R0
- MOVW R0,R0
- MOVW R0,R0
- MOVW R0,R0
- /* flush i&d caches */
- MCR CpMMU, 0, R0, C(CpCacheCtl), C(7)
- /* flush tlb */
- MCR CpMMU, 0, R0, C(CpTLBops), C(7)
- /* drain prefetch */
- MOVW R0,R0
- MOVW R0,R0
- MOVW R0,R0
- MOVW R0,R0
- /* enable clock switching */
- MCR CpPWR, 0, R1, C(CpTest), C(1), 2
- RET
-#endif
-
- GLOBL power_state+0(SB), $4
-
-#ifdef YYY
-/* for debugging sleep code: */
-TEXT fastreset(SB), $-4
- MOVW $PHYSRESET, R7
- MOVW $1, R1
- MOVW R1, (R7)
- RET
-#endif
diff --git a/os/pxa/mmu.c b/os/pxa/mmu.c
deleted file mode 100644
index 52326237..00000000
--- a/os/pxa/mmu.c
+++ /dev/null
@@ -1,252 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-/*
- * Small pages:
- * L1: 12-bit index -> 4096 descriptors -> 16Kb
- * L2: 8-bit index -> 256 descriptors -> 1Kb
- * Each L2 descriptor has access permissions for 4 1Kb sub-pages.
- *
- * TTB + L1Tx gives address of L1 descriptor
- * L1 descriptor gives PTBA
- * PTBA + L2Tx gives address of L2 descriptor
- * L2 descriptor gives PBA
- *
- * on the Xscale, X, C & B are interpreted as follows:
- * X = 0:
- * C=0 B=0 uncached, unbuffered, stall until data access complete
- * C=0 B=1 uncached, buffered (different from Strongarm)
- * C=1 B=0 cached, buffered, write through, read allocate (different from Strongarm)
- * C=1 B=1 cached, buffered, write back, read allocate
- * X = 1:
- * C=0 B=0 undefined
- * C=0 B=1 uncached, buffered, writes will not coalesce
- * C=1 B=0 mini data cache (policy set by auxiliary control reg)
- * C=1 B=1 cached, buffered, write back, read/write allocate
- * and the i-cache uses only the C bit (cached if non-zero).
- */
-#define TTB(pa) ((pa) & ~0x3FFF) /* translation table base */
-#define L1x(pa) (((pa)>>20) & 0xFFF) /* L1 table index */
-#define PTBA(pa) ((pa) & ~0x3FF) /* page table base address */
-#define L2x(pa) (((pa)>>12) & 0xFF) /* L2 table index */
-#define PBA(pa) ((pa) & ~0xFFF) /* page base address */
-#define SBA(pa) ((pa) & ~0xFFFFF) /* section base address */
-
-enum {
- /* sizes */
- Section= 1<<20,
- LargePage= 1<<16,
- SmallPage= 1<<12,
- EsmallPage= 1<<10,
- SectionPages = Section/SmallPage,
- PtAlign = 1<<10,
-
- /* L1 descriptor format */
- L1type= 3<<0, /* mask for type */
- L1page= 1<<0, /* descriptor is for L2 pages */
- L1section= 2<<0, /* descriptor is for section */
- L1fpage= 3<<0, /* descriptor is for fine (1k) L2 pages */
- L1buffered= 1<<2,
- L1cached= 1<<3,
- L1P= 1<<9, /* application-processor specific */
- L1sectionX= 1<<12, /* X bit in section descriptor */
- L1minicache= (L1sectionX | L1cached),
-
- /* L2 descriptor format for coarse page table */
- L2type= 3<<0, /* mask for type */
- L2invalid= 0<<0,
- L2large= 1<<0, /* large page */
- L2small= 2<<0, /* small page */
- L2esmall= 3<<0, /* extended small page */
- L2buffered= 1<<2,
- L2cached= 1<<3,
- /* then access permissions */
- L2smallX= 1<<6,
- L2largeX= 1<<12,
-
- /* domains */
- Dnone= 0,
- Dclient= 1,
- Dmanager= 3,
-
- /* access permissions */
- APsro= 0, /* supervisor ro if S|R */
- APsrw= 1, /* supervisor rw */
- APuro= 2, /* supervisor rw + user ro */
- APurw= 3, /* supervisor rw + user rw */
-
- MINICACHED = 0x10000000,
-};
-
-#define L1dom(d) (((d) & 0xF)<<5) /* L1 domain */
-#define AP(i, v) ((v)<<(((i)*2)+4)) /* access permissions */
-#define L1AP(v) AP(3, (v))
-#define L2AP(v) AP(3, (v))|AP(2, (v))|AP(1, (v))|AP(0, (v))
-
-#define L1krw (L1AP(APsrw) | L1dom(0))
-
-/*
- * return physical address corresponding to a given virtual address,
- * or 0 if there is no such address
- */
-ulong
-va2pa(void *v)
-{
- int idx;
- ulong pte, ste, *ttb;
-
- idx = L1x((ulong)v);
- ttb = (ulong*)KTTB;
- ste = ttb[idx];
- switch(ste & L1type) {
- case L1section:
- return SBA(ste)|((ulong)v & 0x000fffff);
- case L1page:
- pte = ((ulong *)PTBA(ste))[L2x((ulong)v)];
- switch(pte & 3) {
- case L2large:
- return (pte & 0xffff0000)|((ulong)v & 0x0000ffff);
- case L2small:
- return (pte & 0xfffff000)|((ulong)v & 0x00000fff);
- }
- }
- return 0;
-}
-
-/* for debugging */
-void
-prs(char *s)
-{
- for(; *s; s++)
- uartputc(*s);
-}
-
-void
-pr16(ulong n)
-{
- int i, c;
-
- for(i=28; i>=0; i-=4){
- c = (n>>i) & 0xF;
- if(c >= 0 && c <= 9)
- c += '0';
- else
- c += 'A'-10;
- uartputc(c);
- }
-}
-
-void
-xdelay(int n)
-{
- int j;
-
- for(j=0; j<1000000/4; j++)
- n++;
- USED(n);
-}
-
-void*
-mmuphysmap(ulong phys, ulong)
-{
- ulong *ttb;
- void *va;
-
- ttb = (ulong*)KTTB;
- va = KADDR(phys);
- ttb[L1x((ulong)va)] = phys | L1krw | L1section;
- return va;
-}
-
-/*
- * Set a 1-1 map of virtual to physical memory, except:
- * doubly-map page0 at the alternative interrupt vector address,
- * doubly-map physical memory at KZERO+256*MB as uncached but buffered,
- * map flash to virtual space away from 0,
- * disable access to 0 (nil pointers).
- *
- * Other section maps are added later as required by mmuphysmap.
- */
-void
-mmuinit(void)
-{
- int i;
- ulong *ttb, *ptable, va;
-
- ttb = (ulong*)KTTB;
- for(i=0; i<L1x(0x10000000); i++)
- ttb[i] = 0;
- for(; i < 0x1000; i++)
- ttb[i] = (i<<20) | L1krw | L1section;
-
- /* cached dram at normal kernel addresses */
- for(va = KZERO; va < KZERO+64*MB; va += MB)
- ttb[L1x(va)] = va | L1krw | L1section | L1cached | L1buffered;
-
- /* aliases for uncached dram */
- for(i = 0; i < 64*MB; i += MB)
- ttb[L1x(UCDRAMZERO+i)] = (PHYSMEM0+i) | L1krw | L1section;
-
- /* TO DO: make the text read only */
-
- /* minicached region; used for frame buffer (if present) */
- if(0)
- for(va = KZERO; va < KZERO+64*MB; va += MB)
- ttb[L1x(va|MINICACHED)] = va | L1krw | L1minicache | L1section;
-
- ttb[L1x(DCFADDR)] |= L1cached | L1buffered; /* cached and buffered for cache writeback */
-
-#ifdef NOTYET
- /* TO DO: mini cache writeback */
- ttb[L1x(MCFADDR)] |= L1minicache; /* cached and unbuffered for minicache writeback */
-#endif
-
- /* remap flash */
- for(i=0; i<32*MB; i+=MB)
- ttb[L1x(FLASHMEM+i)] = (PHYSFLASH0+i) | L1krw | L1section; /* we'll make flash uncached for now */
-
- /*
- * build page table for alternative vector page, mapping trap vectors in *page0
- */
- ptable = xspanalloc(SectionPages*sizeof(*ptable), PtAlign, 0);
- ptable[L2x(AIVECADDR)] = PADDR(page0) | L2AP(APsrw) | L2cached | L2buffered | L2small;
- ttb[L1x(AIVECADDR)] = PADDR(ptable) | L1page;
- mmuputttb(KTTB);
- mmuputdac(Dclient);
- mmuenable(CpCaltivec | CpCIcache | CpCsystem | CpCwpd | CpCDcache | CpCmmu);
-}
-
-/*
- * flush data in a given address range to memory
- * and invalidate the region in the instruction cache.
- */
-int
-segflush(void *a, ulong n)
-{
- dcflush(a, n);
- icflush(a, n);
- return 0;
-}
-
-#ifdef NOTYET
-/*
- * map an address to cached but unbuffered memory
- * forcing load allocations to the mini data cache.
- * the address a must be in a region that is cache line aligned
- * with a length that is a multiple of the cache line size
- */
-void *
-minicached(void *a)
-{
- if(conf.useminicache == 0)
- return a;
- /* must flush and invalidate any data lingering in main cache */
- dcflushall();
- minidcflush();
- dcinval();
- return (void*)((ulong)a | MINICACHED);
-}
-#endif
diff --git a/os/pxa/pxaio.h b/os/pxa/pxaio.h
deleted file mode 100644
index d7f40a34..00000000
--- a/os/pxa/pxaio.h
+++ /dev/null
@@ -1,383 +0,0 @@
-typedef struct I2Cdev I2Cdev;
-typedef struct PCMconftab PCMconftab;
-typedef struct PCMmap PCMmap;
-typedef struct PCMslot PCMslot;
-
-#define INTRREG ((IntrReg*)PHYSINTR)
-typedef struct IntrReg IntrReg;
-struct IntrReg {
- ulong icip; /* IRQ pending */
- ulong icmr; /* mask */
- ulong iclr; /* level */
- ulong icfp; /* FIQ pending */
- ulong icpr; /* pending */
- ulong iccr; /* control */
-};
-
-/*
- * types of interrupts
- */
-enum
-{
- GPIOrising,
- GPIOfalling,
- GPIOboth,
- IRQ,
-};
-
-enum {
- /* first-level interrupts (table 4-36) */
- IRQrtc= 31,
- IRQhz= 30,
- IRQtimer3= 29,
- IRQtimer2= 28,
- IRQtimer1= 27,
- IRQtimer0= 26,
- IRQdma= 25,
- IRQssp= 24,
- IRQmmc= 23,
- IRQffuart= 22,
- IRQbtuart= 21,
- IRQstuart= 20,
- IRQicp= 19,
- IRQi2c= 18,
- IRQlcd= 17,
- IRQnssp= 16,
- IRQac97= 14,
- IRQi2s= 13,
- IRQpmu= 12,
- IRQusb= 11,
- IRQgpio= 10,
- IRQgpio1= 9,
- IRQgpio0= 8,
- IRQhwuart= 7,
-};
-
-#define GPIOREG ((GpioReg*)PHYSGPIO)
-typedef struct GpioReg GpioReg;
-struct GpioReg {
- ulong gplr[3];
- ulong gpdr[3];
- ulong gpsr[3];
- ulong gpcr[3];
- ulong grer[3];
- ulong gfer[3];
- ulong gedr[3];
- ulong gafr[6];
-};
-
-enum {
- /* GPIO alternative functions if gafr bits set (see table 4-1, pp. 4-3 to 4-6) */
- GPIO_GP_RST_1_i= 1, /* active low GP_reset */
- GPIO_FFRXD_1_i= 34, /* FFUART receive */
- GPIO_FFTXD_2_o= 39, /* FFUART transmit */
-
- MaxGPIObit= 84,
- MaxGPIOIRQ= 1,
-};
-#define GPB(n) (1<<((n)&31))
-#define GPR(n) ((n)>>5)
-#define GPAF(n,v) ((v)<<(((n)&15)*2))
-
-void gpioreserve(int);
-void gpioconfig(int, ulong);
-ulong gpioget(int);
-void gpioset(int, int);
-void gpiorelease(int);
-
-enum {
- /* software configuration bits for gpioconfig */
- Gpio_gpio= 0<<0,
- Gpio_Alt1= 1<<0,
- Gpio_Alt2= 2<<0,
- Gpio_Alt3= 3<<0,
- Gpio_in= 1<<2,
- Gpio_out= 1<<3,
-};
-
-/*
- * software structures used by ../port/devi2c.c and iic.c
- */
-struct I2Cdev {
- int addr;
- int salen; /* length in bytes of subaddress, if used; 0 otherwise */
- int tenbit; /* 10-bit addresses */
-};
-
-long i2crecv(I2Cdev*, void*, long, ulong);
-long i2csend(I2Cdev*, void*, long, ulong);
-void i2csetup(int);
-
-#define COREREG ((Coreregs*)PHYSCORE)
-typedef struct Coreregs Coreregs;
-struct Coreregs {
- ulong cccr; /* core clock config */
- ulong cken; /* clock enable */
- ulong oscc; /* oscillator configuration */
-};
-
-#define RTCREG ((RTCreg*)PHYSRTC)
-typedef struct RTCreg RTCreg;
-struct RTCreg {
- ulong rcnr; /* count */
- ulong rtar; /* alarm */
- ulong rtsr; /* status */
- ulong rttr; /* trim */
-};
-
-#define OSTMRREG ((OstmrReg*)PHYSOSTMR)
-typedef struct OstmrReg OstmrReg;
-struct OstmrReg {
- ulong osmr[4]; /* match */
- ulong oscr; /* counter */
- ulong ossr; /* status */
- ulong ower; /* watchdog */
- ulong oier; /* interrupt enable */
-};
-
-#define PMGRREG ((PmgrReg*)PHYSPOWER)
-typedef struct PmgrReg PmgrReg;
-struct PmgrReg {
- ulong pmcr; /* ctl register */
- ulong pssr; /* sleep status */
- ulong pspr; /* scratch pad */
- ulong pwer; /* wakeup enable */
- ulong prer; /* rising-edge detect enable */
- ulong pfer; /* falling-edge detect enable */
- ulong pedr; /* GPIO edge detect status */
- ulong pcfr; /* general configuration */
- ulong pgsr[3]; /* GPIO sleep state */
- ulong rsvd;
- ulong rcsr; /* reset controller status register */
-};
-
-enum {
- /* pp. 3-25 to 3-31 */
- PWER_rtc = 1<<31, /* wakeup by RTC alarm */
- PWER_we0 = 1<<0, /* wake-up on GP0 edge detect */
-
- PSSR_sss = 1<<0, /* software sleep status */
- PSSR_bfs = 1<<1, /* battery fault status */
- PSSR_vfs = 1<<2, /* VDD fault status */
- PSSR_ph = 1<<4, /* peripheral control hold */
- PSSR_rdh = 1<<5, /* read disable hold */
-
- PMFW_fwake= 1<<1, /* fast wakeup enable (no power stabilisation delay) */
-
- RSCR_gpr= 1<<3, /* gpio reset has occurred */
- RSCR_smr= 1<<2, /* sleep mode has occurred */
- RSCR_wdr= 1<<1, /* watchdog reset has occurred */
- RSCR_hwr= 1<<0, /* hardware reset has occurred */
-};
-
-#define MEMCFGREG ((MemcfgReg*)PHYSMEMCFG)
-typedef struct MemcfgReg MemcfgReg;
-struct MemcfgReg {
- ulong mdcnfg; /* SDRAM config */
- ulong mdrefr; /* dram refresh */
- ulong msc0; /* static memory or devices */
- ulong msc1;
- ulong msc2; /* static memory or devices */
- ulong mecr; /* expansion bus (pcmcia, CF) */
- ulong sxcnfg; /* synchronous static memory control */
- ulong sxmrs; /* MRS value to write to SMROM */
- ulong mcmem0; /* card interface socket 0 memory timing */
- ulong mcmem1; /* card interface socket 1 memory timing */
- ulong mcatt0; /* socket 0 attribute memory timing */
- ulong mcatt1; /* socket 1 attribute memory timing */
- ulong mcio0; /* socket 0 i/o timing */
- ulong mcio1; /* socket 1 i/o timing */
- ulong mdmrs; /* MRS value to write to SDRAM */
- ulong boot_def; /* read-only boot-time register */
- ulong mdmrslp; /* low-power SDRAM mode register set config */
- ulong sa1111cr; /* SA1111 compatibility */
-};
-
-#define LCDREG ((LcdReg*)PHYSLCD)
-typedef struct LcdReg LcdReg;
-struct LcdReg {
- ulong lccr0; /* control 0 */
- ulong lccr1; /* control 1 */
- ulong lccr2; /* control 2 */
- ulong lccr3; /* control 3 */
- struct {
- ulong fdadr; /* dma frame descriptor address register */
- ulong fsadr; /* dma frame source address register */
- ulong fidr; /* dma frame ID register */
- ulong ldcmd; /* dma command */
- } frame[2];
- ulong fbr[2]; /* frame branch register */
- ulong lcsr; /* status */
- ulong liidr; /* interrupt ID register */
- ulong trgbr; /* TMED RGB seed register */
- ulong tcr; /* TMED control register */
-};
-
-#define USBREG ((UsbReg*)PHYSUSB)
-typedef struct UsbReg UsbReg;
-struct UsbReg {
- ulong udccr; /* control */
- ulong udccs[16]; /* endpoint control/status */
- ulong ufnrh; /* frame number high */
- ulong ufnrl; /* frame number low */
- ulong udbcr2;
- ulong udbcr4;
- ulong udbcr7;
- ulong udbcr9;
- ulong udbcr12;
- ulong udbcr14;
- ulong uddr[16]; /* endpoint data */
- ulong uicr0;
- ulong uicr1;
- ulong usir0;
- ulong usir1;
-};
-
-enum {
- /* DMA configuration parameters */
-
- /* DMA Direction */
- DmaOut= 0,
- DmaIn= 1,
-
- /* dma devices */
- DmaDREQ0= 0,
- DmaDREQ1,
- DmaI2S_i,
- DmaI2S_o,
- DmaBTUART_i,
- DmaBTUART_o,
- DmaFFUART_i,
- DmaFFUART_o,
- DmaAC97mic,
- DmaAC97modem_i,
- DmaAC97modem_o,
- DmaAC97audio_i,
- DmaAC97audio_o,
- DmaSSP_i,
- DmaSSP_o,
- DmaNSSP_i,
- DmaNSSP_o,
- DmaICP_i,
- DmaICP_o,
- DmaSTUART_i,
- DmaSTUART_o,
- DmaMMC_i,
- DmaMMC_o,
- DmaRsvd0,
- DmaRsvd1,
- DmaUSB1,
- DmaUSB2,
- DmaUSB3,
- DmaUSB4,
- DmaHWUART_i,
- DmaUSB6,
- DmaUSB7,
- DmaUSB8,
- DmaUSB9,
- DmaHWUART_o,
- DmaUSB11,
- DmaUSB12,
- DmaUSB13,
- DmaUSB14,
- DmaRsvd2,
-};
-
-/*
- * Interface to platform-specific PCMCIA signals, in arch*.c
- */
-enum {
- /* argument to pcmpin() */
- PCMready,
- PCMeject,
- PCMstschng,
-};
-
-/*
- * physical device addresses are mapped to the same virtual ones,
- * allowing the same addresses to be used with or without mmu.
- */
-
-#define PCMCIAcard(n) (PHYSPCMCIA0+((n)*PCMCIASIZE))
-#define PCMCIAIO(n) (PCMCIAcard(n)+0x0) /* I/O space */
-#define PCMCIAAttr(n) (PCMCIAcard(n)+0x8000000) /* Attribute space*/
-#define PCMCIAMem(n) (PCMCIAcard(n)+0xC000000) /* Memory space */
-
-/*
- * 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 */
- uchar nlines;
- struct {
- ulong start;
- ulong len;
- } io[16];
- int nio;
- uchar vcc;
- uchar vpp1;
- uchar vpp2;
- uchar memwait;
- ulong maxwait;
- ulong readywait;
- ulong otherwait;
-};
-
-/*
- * PCMCIA card slot
- */
-struct PCMslot
-{
- RWlock;
-
- Ref ref;
-
- long memlen; /* memory length */
- uchar slotno; /* slot number */
- void *regs; /* i/o registers */
- void *mem; /* memory */
- void *attr; /* attribute memory */
-
- /* status */
- uchar occupied; /* card in the slot */
- uchar configed; /* card configured */
- uchar busy;
- uchar powered;
- uchar battery;
- uchar wrprot;
- uchar enabled;
- uchar special;
- uchar dsize;
-
- /* cis info */
- int cisread; /* set when the cis has been read */
- 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 */
-
- /* maps are fixed */
- PCMmap memmap;
- PCMmap attrmap;
-};
diff --git a/os/pxa/sa1110break.c b/os/pxa/sa1110break.c
deleted file mode 100644
index 3ab87b06..00000000
--- a/os/pxa/sa1110break.c
+++ /dev/null
@@ -1,360 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-//
-// from trap.c
-//
-extern int (*breakhandler)(Ureg *ur, Proc*);
-extern Instr BREAK;
-extern void portbreakinit(void);
-
-//
-// Instructions that can have the PC as a destination register
-//
-enum {
- IADD = 1,
- IBRANCH,
- ILDM,
- ILDR,
- IMOV,
-
- //
- // These should eventually be implemented
- //
- IADC,
- IAND,
- IBIC,
- IEOR,
- ILDRT,
- IMRS,
- IMVN,
- IORR,
- IRSB,
- IRSC,
- ISBC,
- ISUB,
-};
-
-static int instrtype(Instr i);
-static ulong iadd(Ureg *ur, Instr i);
-static ulong ibranch(Ureg *ur, Instr i);
-static ulong ildm(Ureg *ur, Instr i);
-static ulong ildr(Ureg *ur, Instr i);
-static ulong imov(Ureg *ur, Instr i);
-static ulong shifterval(Ureg *ur, Instr i);
-static int condpass(Instr i, ulong psr);
-static ulong *address(Ureg *ur, Instr i);
-static ulong* multiaddr(Ureg *ur, Instr i);
-static int nbits(ulong v);
-
-#define COND_N(psr) (((psr) >> 31) & 1)
-#define COND_Z(psr) (((psr) >> 30) & 1)
-#define COND_C(psr) (((psr) >> 29) & 1)
-#define COND_V(psr) (((psr) >> 28) & 1)
-#define REG(i, a, b) (((i) & BITS((a), (b))) >> (a))
-#define REGVAL(ur, r) (*((ulong*)(ur) + (r)))
-#define LSR(v, s) ((ulong)(v) >> (s))
-#define ASR(v, s) ((long)(v) >> (s))
-#define ROR(v, s) (LSR((v), (s)) | (((v) & ((1 << (s))-1)) << (32 - (s))))
-
-void
-machbreakinit(void)
-{
- portbreakinit();
- breakhandler = breakhit;
-}
-
-Instr
-machinstr(ulong addr)
-{
- if (addr < KTZERO)
- error(Ebadarg);
- return *(Instr*)addr;
-}
-
-void
-machbreakset(ulong addr)
-{
- if (addr < KTZERO)
- error(Ebadarg);
- *(Instr*)addr = BREAK;
- segflush((void*)addr, sizeof(Instr));
-}
-
-void
-machbreakclear(ulong addr, Instr i)
-{
- if (addr < KTZERO)
- error(Ebadarg);
- *(Instr*)addr = i;
- segflush((void*)addr, sizeof(Instr));
-}
-
-//
-// Return the address of the instruction that will be executed after the
-// instruction at address ur->pc.
-//
-// This means decoding the instruction at ur->pc.
-//
-// In the simple case, the PC will simply be the address of the next
-// sequential instruction following ur->pc.
-//
-// In the complex case, the instruction is a branch of some sort, so the
-// value of the PC after the instruction must be computed by decoding
-// and simulating the instruction enough to determine the PC.
-//
-
-ulong
-machnextaddr(Ureg *ur)
-{
- Instr i;
- i = machinstr(ur->pc);
- switch(instrtype(i)) {
- case IADD: return iadd(ur,i);
- case IBRANCH: return ibranch(ur,i);
- case ILDM: return ildm(ur,i);
- case ILDR: return ildr(ur,i);
- case IMOV: return imov(ur,i);
-
- case IADC:
- case IAND:
- case IBIC:
- case IEOR:
- case ILDRT:
- case IMRS:
- case IMVN:
- case IORR:
- case IRSB:
- case IRSC:
- case ISBC:
- case ISUB:
- // XXX - Tad: unimplemented
- //
- // any of these instructions could possibly have the
- // PC as Rd. Eventually, these should all be
- // checked just like the others.
- default:
- return ur->pc+4;
- }
-
- return 0;
-}
-
-static int
-instrtype(Instr i)
-{
- if(i & BITS(26,27) == 0) {
- switch((i >> 21) & 0xF) {
- case 0: return IAND;
- case 1: return IEOR;
- case 2: return ISUB;
- case 3: return IRSB;
- case 4: return IADD;
- case 5: return IADC;
- case 6: return ISBC;
- case 7: return IRSC;
- case 0xD: return IMOV;
- case 0xC: return IORR;
- case 0xE: return IBIC;
- case 0xF: return IMVN;
- }
- if(((i & BIT(25)|BITS(23,24)|BITS(20,21))) >> 20 == 0x10)
- return IMRS;
- return 0;
- }
-
- if(((i & BITS(27,25)|BIT(20)) >> 20) == 0x81) return ILDM;
- if(((i & BITS(26,27)|BIT(22)|BIT(20)) >> 20) == 0x41) return ILDR;
- if(((i & BITS(25,27)) >> 25) == 5) return IBRANCH;
-
- return 0;
-}
-
-static ulong
-iadd(Ureg *ur, Instr i)
-{
- ulong Rd = REG(i, 12, 15);
- ulong Rn = REG(i, 16, 19);
-
- if(Rd != 15 || !condpass(i, ur->psr))
- return ur->pc+4;
-
- return REGVAL(ur, Rn) + shifterval(ur, i);
-}
-
-static ulong
-ibranch(Ureg *ur, Instr i)
-{
- if(!condpass(i, ur->psr))
- return ur->pc+4;
- return ur->pc + ((signed long)(i << 8) >> 6) + 8;
-}
-
-static ulong
-ildm(Ureg *ur, Instr i)
-{
- if((i & BIT(15)) == 0)
- return ur->pc+4;
-
- return *(multiaddr(ur, i) + nbits(i & BITS(15, 0)));
-}
-
-static ulong
-ildr(Ureg *ur, Instr i)
-{
- if(REG(i, 12, 19) != 15 || !condpass(i, ur->psr))
- return ur->pc+4;
-
- return *address(ur, i);
-}
-
-static ulong
-imov(Ureg *ur, Instr i)
-{
- if(REG(i, 12, 15) != 15 || !condpass(i, ur->psr))
- return ur->pc+4;
-
- return shifterval(ur, i);
-}
-
-static int
-condpass(Instr i, ulong psr)
-{
- uchar n = COND_N(psr);
- uchar z = COND_Z(psr);
- uchar c = COND_C(psr);
- uchar v = COND_V(psr);
-
- switch(LSR(i,28)) {
- case 0: return z;
- case 1: return !z;
- case 2: return c;
- case 3: return !c;
- case 4: return n;
- case 5: return !n;
- case 6: return v;
- case 7: return !v;
- case 8: return c && !z;
- case 9: return !c || z;
- case 10: return n == v;
- case 11: return n != v;
- case 12: return !z && (n == v);
- case 13: return z && (n != v);
- case 14: return 1;
- case 15: return 0;
- }
-}
-
-static ulong
-shifterval(Ureg *ur, Instr i)
-{
- if(i & BIT(25)) { // IMMEDIATE
- ulong imm = i & BITS(0,7);
- ulong s = (i & BITS(8,11)) >> 7; // this contains the * 2
- return ROR(imm, s);
- } else {
- ulong Rm = REGVAL(ur, REG(i, 0, 3));
- ulong s = (i & BITS(7,11)) >> 7;
-
- switch((i & BITS(6,4)) >> 4) {
- case 0: // LSL
- return Rm << s;
- case 1: // LSLREG
- s = REGVAL(ur, s >> 1) & 0xFF;
- if(s >= 32) return 0;
- return Rm << s;
- case 2: // LSRIMM
- return LSR(Rm, s);
- case 3: // LSRREG
- s = REGVAL(ur, s >> 1) & 0xFF;
- if(s >= 32) return 0;
- return LSR(Rm, s);
- case 4: // ASRIMM
- if(s == 0) {
- if(Rm & BIT(31) == 0)
- return 0;
- return 0xFFFFFFFF;
- }
- return ASR(Rm, s);
- case 5: // ASRREG
- s = REGVAL(ur, s >> 1) & 0xFF;
- if(s >= 32) {
- if(Rm & BIT(31) == 0)
- return 0;
- return 0xFFFFFFFF;
- }
- return ASR(Rm, s);
- case 6: // RORIMM
- if(s == 0)
- return (COND_C(ur->psr) << 31) | LSR(Rm, 1);
- return ROR(Rm, s);
- case 7: // RORREG
- s = REGVAL(ur, s >> 1) & 0xFF;
- if(s == 0 || (s & 0xF) == 0)
- return Rm;
- return ROR(Rm, s & 0xF);
- }
- }
-}
-
-static ulong*
-address(Ureg *ur, Instr i)
-{
- ulong Rn = REGVAL(ur, REG(i, 16, 19));
-
- if(i & BIT(24) == 0) // POSTIDX
- return (ulong*)REGVAL(ur, Rn);
- if(i & BIT(25) == 0) { // OFFSET
- if(i & BIT(23))
- return (ulong*)(REGVAL(ur, Rn) + (i & BITS(0, 11)));
- return (ulong*)(REGVAL(ur, Rn) - (i & BITS(0, 11)));
- } else { // REGOFF
- ulong Rm = REGVAL(ur, REG(i, 0, 3));
- ulong index = 0;
- switch(i & BITS(5,6) >> 5) {
- case 0: index = Rm << ((i & BITS(7, 11)) >> 7); break;
- case 1: index = LSR(Rm, ((i & BITS(7, 11)) >> 7)); break;
- case 2: index = ASR(Rm, ((i & BITS(7, 11)) >> 7)); break;
- case 3:
- if(i & BITS(7, 11) == 0)
- index = (COND_C(ur->psr) << 31) | LSR(Rm, 1);
- else
- index = ROR(Rm, (i & BITS(7, 11)) >> 7);
- break;
- }
- if(i & BIT(23))
- return (ulong*)(Rn + index);
- return (ulong*)(Rn - index);
- }
-}
-
-static ulong*
-multiaddr(Ureg *ur, Instr i)
-{
- ulong Rn = REGVAL(ur, REG(i, 16, 19));
-
- switch((i >> 23) & 3) {
- case 0: return (ulong*)(Rn - (nbits(i & BITS(0,15))*4)+4);
- case 1: return (ulong*)Rn;
- case 2: return (ulong*)(Rn - (nbits(i & BITS(0,15))*4));
- case 3: return (ulong*)(Rn + 4);
- }
-}
-
-static int
-nbits(ulong v)
-{
- int n = 0;
- int i;
- for(i = 0; i < 32; i++) {
- if(v & 1)
- ++n;
- v = LSR(v, 1);
- }
- return n;
-}
diff --git a/os/pxa/trap.c b/os/pxa/trap.c
deleted file mode 100644
index 43117330..00000000
--- a/os/pxa/trap.c
+++ /dev/null
@@ -1,587 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-#define waslo(sr) (!((sr) & (PsrDirq|PsrDfiq)))
-
-typedef struct Handler Handler;
-struct Handler {
- void (*r)(Ureg*, void*);
- void *a;
- char name[KNAMELEN];
- Handler *next;
-};
-
-static Handler irqvec[32];
-static Handler gpiovec[MaxGPIObit+1];
-static Lock veclock;
-
-Instr BREAK = 0xE6BAD010;
-
-int (*breakhandler)(Ureg*, Proc*);
-int (*catchdbg)(Ureg *, uint);
-void (*suspendcode)(void);
-
-extern void (*serwrite)(char *, int);
-
-/*
- * Interrupt sources not masked by splhi(): special
- * interrupt handlers (eg, profiler or watchdog), not allowed
- * to share regular kernel data structures. All interrupts are
- * masked by splfhi(), which should only be used sparingly.
- * splflo enables FIQ but no others.
- */
-enum {
- IRQ_NONMASK = (1 << IRQtimer3) | (1 << IRQtimer2),
-};
-
-void
-intrenable(int sort, int v, void (*f)(Ureg*, void*), void* a, char *name)
-{
- int x, o;
- ulong m;
- GpioReg *g;
- Handler *ie;
-
- ilock(&veclock);
- switch(sort) {
- case GPIOfalling:
- case GPIOrising:
- case GPIOboth:
- if(v < 0 || v > MaxGPIObit)
- panic("intrenable: gpio %d out of range", v);
- g = GPIOREG;
- o = GPR(v);
- m = GPB(v);
- switch(sort){
- case GPIOfalling:
- g->gfer[o] |= m;
- g->grer[o] &= ~m;
- break;
- case GPIOrising:
- g->grer[o] |= m;
- g->gfer[o] &= ~m;
- break;
- case GPIOboth:
- g->grer[o] |= m;
- g->gfer[o] |= m;
- break;
- }
- g->gpdr[o] &= ~m; /* must be input */
- if(v > MaxGPIOIRQ) {
- ie = &gpiovec[v];
- if(ie->r != nil)
- iprint("duplicate gpio irq: %d (%s)\n", v, ie->name);
- ie->r = f;
- ie->a = a;
- strncpy(ie->name, name, KNAMELEN-1);
- ie->name[KNAMELEN-1] = 0;
- iunlock(&veclock);
- return;
- }
- v += IRQgpio0;
- /*FALLTHROUGH for GPIO sources 0-MaxGPIOIRQ */
- case IRQ:
- if(v < 0 || v > 31)
- panic("intrenable: irq source %d out of range", v);
- ie = &irqvec[v];
- if(ie->r != nil)
- iprint("duplicate irq: %d (%s)\n", v, ie->name);
- ie->r = f;
- ie->a = a;
- strncpy(ie->name, name, KNAMELEN-1);
- ie->name[KNAMELEN-1] = 0;
-
- x = splfhi();
- /* Enable the interrupt by setting the mask bit */
- INTRREG->icmr |= 1 << v;
- splx(x);
- break;
- default:
- panic("intrenable: unknown irq bus %d", sort);
- }
- iunlock(&veclock);
-}
-
-void
-intrdisable(int sort, int v, void (*f)(Ureg*, void*), void* a, char *name)
-{
- int x, o;
- GpioReg *g;
- Handler *ie;
- ulong m;
-
- ilock(&veclock);
- switch(sort) {
- case GPIOfalling:
- case GPIOrising:
- case GPIOboth:
- if(v < 0 || v > MaxGPIObit)
- panic("intrdisable: gpio source %d out of range", v);
- if(v > MaxGPIOIRQ)
- ie = &gpiovec[v];
- else
- ie = &irqvec[v];
- if(ie->r != f || ie->a != a || strcmp(ie->name, name) != 0)
- break;
- ie->r = nil;
- if(v <= MaxGPIOIRQ){
- v += IRQgpio0;
- x = splfhi();
- INTRREG->icmr &= ~(1<<v);
- splx(x);
- }
- g = GPIOREG;
- o = GPR(v);
- m = GPB(v);
- switch(sort){
- case GPIOfalling:
- g->gfer[o] &= ~m;
- break;
- case GPIOrising:
- g->grer[o] &= ~m;
- break;
- case GPIOboth:
- g->grer[o] &= ~m;
- g->gfer[o] &= ~m;
- break;
- }
- break;
- case IRQ:
- if(v < 0 || v > 31)
- panic("intrdisable: irq source %d out of range", v);
- ie = &irqvec[v];
- if(ie->r != f || ie->a != a || strcmp(ie->name, name) != 0)
- break;
- ie->r = nil;
- x = splfhi();
- INTRREG->icmr &= ~(1<<v);
- splx(x);
- break;
- default:
- panic("intrdisable: unknown irq bus %d", sort);
- }
- iunlock(&veclock);
-}
-
-static void
-gpiointr(Ureg *ur, void*)
-{
- Handler *cur;
- ulong e;
- int i, o;
-
- for(o=0; o<3; o++){
- e = GPIOREG->gedr[o];
- GPIOREG->gedr[o] = e;
- for(i = 0; i < 32 && e != 0; i++){
- if(e & (1<<i)){
- cur = &gpiovec[(o<<5)+i];
- if(cur->r != nil){
- cur->r(ur, cur->a);
- e &= ~(1<<i);
- }
- }
- }
- if(e != 0){
- GPIOREG->gfer[o] &= ~e;
- GPIOREG->grer[o] &= ~e;
- iprint("spurious GPIO[%d] %8.8lux interrupt\n", o,e);
- }
- }
-}
-
-static void
-intrs(Ureg *ur, ulong ibits)
-{
- Handler *cur;
- int i, s;
-
- for(i=0; i<nelem(irqvec) && ibits; i++)
- if(ibits & (1<<i)){
- cur = &irqvec[i];
- if(cur->r != nil){
- cur->r(ur, cur->a);
- ibits &= ~(1<<i);
- }
- }
- if(ibits != 0){
- iprint("spurious irq interrupt: %8.8lux\n", ibits);
- s = splfhi();
- INTRREG->icmr &= ~ibits;
- splx(s);
- }
-}
-
-/*
- * initialise R13 in each trap mode, at the start and after suspend reset.
- */
-void
-trapstacks(void)
-{
- setr13(PsrMfiq, m->fiqstack+nelem(m->fiqstack));
- setr13(PsrMirq, m->irqstack+nelem(m->irqstack));
- setr13(PsrMabt, m->abtstack+nelem(m->abtstack));
- setr13(PsrMund, m->undstack+nelem(m->undstack));
-}
-
-void
-trapinit(void)
-{
- IntrReg *intr = INTRREG;
-
- intr->icmr = 0; /* mask everything */
- intr->iccr = 1; /* only enabled and unmasked interrupts wake us */
- intr->iclr = IRQ_NONMASK;
-
- trapstacks();
-
- memmove(page0->vectors, vectors, sizeof(page0->vectors));
- memmove(page0->vtable, vtable, sizeof(page0->vtable));
- dcflush(page0, sizeof(*page0));
-
-#ifdef NOTYET
- suspendcode = xspanalloc(16*sizeof(ulong), CACHELINESZ, 0);
- memmove(suspendcode, _suspendcode, 16*sizeof(ulong));
- dcflush(suspendcode, 8*sizeof(ulong));
-#endif
-
- icflushall();
-
- intrenable(IRQ, IRQgpio, gpiointr, nil, "gpio");
-}
-
-static char *trapnames[PsrMask+1] = {
- [ PsrMfiq ] "Fiq interrupt",
- [ PsrMirq ] "Mirq interrupt",
- [ PsrMsvc ] "SVC/SWI Exception",
- [ PsrMabt ] "Prefetch Abort/Data Abort",
- [ PsrMabt+1 ] "Data Abort",
- [ PsrMund ] "Undefined instruction",
- [ PsrMsys ] "Sys trap"
-};
-
-static char *
-trapname(int psr)
-{
- char *s;
-
- s = trapnames[psr & PsrMask];
- if(s == nil)
- s = "Undefined trap";
- return s;
-}
-
-static void
-sys_trap_error(int type)
-{
- char errbuf[ERRMAX];
- sprint(errbuf, "sys: trap: %s\n", trapname(type));
- error(errbuf);
-}
-
-static void
-faultarm(Ureg *ureg, ulong far)
-{
- char buf[ERRMAX];
-
- sprint(buf, "sys: trap: fault pc=%8.8lux addr=0x%lux", (ulong)ureg->pc, far);
- if(1){
- iprint("%s\n", buf);
- dumpregs(ureg);
- }
- if(far == ~0)
- disfault(ureg, "dereference of nil");
- disfault(ureg, buf);
-}
-
-/*
- * All traps come here. It might be slightly slower to have all traps call trap
- * rather than directly vectoring the handler.
- * However, this avoids a lot of code duplication and possible bugs.
- * trap is called splfhi().
- */
-void
-trap(Ureg* ureg)
-{
- ulong far, fsr;
- int rem, t, itype;
- Proc *oup;
-
- if(up != nil)
- rem = ((char*)ureg)-up->kstack;
- else
- rem = ((char*)ureg)-(char*)m->stack;
- if(ureg->type != PsrMfiq && rem < 256)
- panic("trap %d bytes remaining (%s), up=#%8.8lux ureg=#%8.8lux pc=#%8.8ux",
- rem, up?up->text:"", up, ureg, ureg->pc);
-
- /*
- * All interrupts/exceptions should be resumed at ureg->pc-4,
- * except for Data Abort which resumes at ureg->pc-8.
- */
- itype = ureg->type;
- if(itype == PsrMabt+1)
- ureg->pc -= 8;
- else
- ureg->pc -= 4;
- ureg->sp = (ulong)(ureg+1);
- if(itype == PsrMfiq){ /* fast interrupt (eg, profiler) */
- oup = up;
- up = nil;
- intrs(ureg, INTRREG->icfp);
- up = oup;
- return;
- }
-
- /* All other traps */
-
- if(0 && ureg->psr & PsrDfiq)
- panic("FIQ disabled");
-
- if(up){
- up->pc = ureg->pc;
- up->dbgreg = ureg;
- }
- switch(itype) {
- case PsrMirq:
- t = m->ticks; /* CPU time per proc */
- up = nil; /* no process at interrupt level */
- splflo(); /* allow fast interrupts */
- intrs(ureg, INTRREG->icip);
- up = m->proc;
- preemption(m->ticks - t);
- break;
-
- case PsrMund: /* Undefined instruction */
- if(*(ulong*)ureg->pc == BREAK && breakhandler) {
- int s;
- Proc *p;
-
- p = up;
- /* if(!waslo(ureg->psr) || ureg->pc >= (ulong)splhi && ureg->pc < (ulong)islo)
- p = 0; */
- s = breakhandler(ureg, p);
- if(s == BrkSched) {
- p->preempted = 0;
- sched();
- } else if(s == BrkNoSched) {
- p->preempted = 1; /* stop it being preempted until next instruction */
- if(up)
- up->dbgreg = 0;
- return;
- }
- break;
- }
- if(up == nil)
- goto faultpanic;
- spllo();
- if(waserror()) {
- if(waslo(ureg->psr) && up->type == Interp)
- disfault(ureg, up->env->errstr);
- setpanic();
- dumpregs(ureg);
- panic("%s", up->env->errstr);
- }
- if(!fpiarm(ureg)) {
- dumpregs(ureg);
- sys_trap_error(ureg->type);
- }
- poperror();
- break;
-
- case PsrMsvc: /* Jump through 0 or SWI */
- if(waslo(ureg->psr) && up && up->type == Interp) {
- spllo();
- dumpregs(ureg);
- sys_trap_error(ureg->type);
- }
- setpanic();
- dumpregs(ureg);
- panic("SVC/SWI exception");
- break;
-
- case PsrMabt: /* Prefetch abort */
- if(catchdbg && catchdbg(ureg, 0))
- break;
- /* FALL THROUGH */
- case PsrMabt+1: /* Data abort */
- fsr = mmugetfsr();
- far = mmugetfar();
- if(fsr & (1<<9)) {
- mmuputfsr(fsr & ~(1<<9));
- if(catchdbg && catchdbg(ureg, fsr))
- break;
- print("Debug/");
- }
- if(waslo(ureg->psr) && up && up->type == Interp) {
- spllo();
- faultarm(ureg, far);
- }
- iprint("Data Abort: FSR %8.8luX FAR %8.8luX\n", fsr, far); xdelay(1);
- /* FALL THROUGH */
-
- default: /* ??? */
-faultpanic:
- setpanic();
- dumpregs(ureg);
- panic("exception %uX %s\n", ureg->type, trapname(ureg->type));
- break;
- }
-
- splhi();
- if(up)
- up->dbgreg = 0; /* becomes invalid after return from trap */
-}
-
-void
-setpanic(void)
-{
- if(breakhandler != 0) /* don't mess up debugger */
- return;
- INTRREG->icmr = 0;
- spllo();
- consoleprint = 1;
- serwrite = uartputs;
-}
-
-int
-isvalid_wa(void *v)
-{
- return (ulong)v >= KZERO && (ulong)v < conf.topofmem && !((ulong)v & 3);
-}
-
-int
-isvalid_va(void *v)
-{
- return (ulong)v >= KZERO && (ulong)v < conf.topofmem;
-}
-
-void
-dumplongs(char *msg, ulong *v, int n)
-{
- int i, l;
-
- l = 0;
- iprint("%s at %.8p: ", msg, v);
- for(i=0; i<n; i++){
- if(l >= 4){
- iprint("\n %.8p: ", v);
- l = 0;
- }
- if(isvalid_va(v)){
- iprint(" %.8lux", *v++);
- l++;
- }else{
- iprint(" invalid");
- break;
- }
- }
- iprint("\n");
-}
-
-static void
-_dumpstack(Ureg *ureg)
-{
- ulong *v, *l;
- ulong inst;
- ulong *estack;
- int i;
-
- l = (ulong*)(ureg+1);
- if(!isvalid_wa(l)){
- iprint("invalid ureg/stack: %.8p\n", l);
- return;
- }
- print("ktrace /kernel/path %.8ux %.8ux %.8ux\n", ureg->pc, ureg->sp, ureg->r14);
- if(up != nil && l >= (ulong*)up->kstack && l <= (ulong*)(up->kstack+KSTACK-4))
- estack = (ulong*)(up->kstack+KSTACK);
- else if(l >= (ulong*)m->stack && l <= (ulong*)((ulong)m+BY2PG-4))
- estack = (ulong*)((ulong)m+BY2PG-4);
- else{
- iprint("unknown stack\n");
- return;
- }
- i = 0;
- for(; l<estack; l++) {
- if(!isvalid_wa(l)) {
- iprint("invalid(%8.8p)", l);
- break;
- }
- v = (ulong*)*l;
- if(isvalid_wa(v)) {
- inst = v[-1];
- if((inst & 0x0ff0f000) == 0x0280f000 &&
- (*(v-2) & 0x0ffff000) == 0x028fe000 ||
- (inst & 0x0f000000) == 0x0b000000) {
- iprint("%8.8p=%8.8lux ", l, v);
- i++;
- }
- }
- if(i == 4){
- iprint("\n");
- i = 0;
- }
- }
- if(i)
- print("\n");
-}
-
-void
-dumpregs(Ureg* ureg)
-{
- print("TRAP: %s", trapname(ureg->type));
- if((ureg->psr & PsrMask) != PsrMsvc)
- print(" in %s", trapname(ureg->psr));
- print("\n");
- print("PSR %8.8uX type %2.2uX PC %8.8uX LINK %8.8uX\n",
- ureg->psr, ureg->type, ureg->pc, ureg->link);
- print("R14 %8.8uX R13 %8.8uX R12 %8.8uX R11 %8.8uX R10 %8.8uX\n",
- ureg->r14, ureg->r13, ureg->r12, ureg->r11, ureg->r10);
- print("R9 %8.8uX R8 %8.8uX R7 %8.8uX R6 %8.8uX R5 %8.8uX\n",
- ureg->r9, ureg->r8, ureg->r7, ureg->r6, ureg->r5);
- print("R4 %8.8uX R3 %8.8uX R2 %8.8uX R1 %8.8uX R0 %8.8uX\n",
- ureg->r4, ureg->r3, ureg->r2, ureg->r1, ureg->r0);
- print("Stack is at: %8.8luX\n", ureg);
- print("PC %8.8lux LINK %8.8lux\n", (ulong)ureg->pc, (ulong)ureg->link);
-
- if(up)
- print("Process stack: %8.8lux-%8.8lux\n",
- up->kstack, up->kstack+KSTACK-4);
- else
- print("System stack: %8.8lux-%8.8lux\n",
- (ulong)(m+1), (ulong)m+BY2PG-4);
- dumplongs("stack", (ulong *)(ureg + 1), 16);
- _dumpstack(ureg);
-}
-
-/*
- * Fill in enough of Ureg to get a stack trace, and call a function.
- * Used by debugging interface rdb.
- */
-void
-callwithureg(void (*fn)(Ureg*))
-{
- Ureg ureg;
- ureg.pc = getcallerpc(&fn);
- ureg.sp = (ulong)&fn;
- ureg.r14 = 0;
- fn(&ureg);
-}
-
-void
-dumpstack(void)
-{
- callwithureg(_dumpstack);
-}
-
-void
-trapspecial(int (*f)(Ureg *, uint))
-{
- catchdbg = f;
-}