From 78ee7d5717807e6ac779293d0d3c78341de6130a Mon Sep 17 00:00:00 2001 From: "Konstantin Kirik (snegovick)" Date: Sun, 28 Dec 2025 12:27:31 +0300 Subject: Move existing boards into subdits split per arch --- os/cerf405/README | 45 -- os/cerf405/cerf | 142 ------- os/cerf405/clock.c | 159 ------- os/cerf405/compile.c | 34 -- os/cerf405/dat.h | 159 ------- os/cerf405/devboot.c | 132 ------ os/cerf405/devether.c | 617 --------------------------- os/cerf405/devrtc.c | 369 ---------------- os/cerf405/devuart.c | 1064 ----------------------------------------------- os/cerf405/etheremac.c | 829 ------------------------------------ os/cerf405/etherif.h | 37 -- os/cerf405/fns.h | 147 ------- os/cerf405/fpi.h | 61 --- os/cerf405/fpipower.c | 970 ------------------------------------------ os/cerf405/gpio.c | 106 ----- os/cerf405/iic.c | 605 --------------------------- os/cerf405/inb.s | 127 ------ os/cerf405/io.h | 301 -------------- os/cerf405/l.s | 795 ----------------------------------- os/cerf405/main.c | 719 -------------------------------- os/cerf405/mal.c | 334 --------------- os/cerf405/mem.h | 147 ------- os/cerf405/mkfile | 104 ----- os/cerf405/mmu.c | 122 ------ os/cerf405/nand.c | 96 ----- os/cerf405/nofp.s | 31 -- os/cerf405/pci.c | 981 ------------------------------------------- os/cerf405/physmem.h | 22 - os/cerf405/powerbreak.c | 123 ------ os/cerf405/rmap.c | 106 ----- os/cerf405/tlb.s | 30 -- os/cerf405/trap.c | 581 -------------------------- os/cerf405/uart.c | 139 ------- os/cerf405/uart.h | 101 ----- 34 files changed, 10335 deletions(-) delete mode 100644 os/cerf405/README delete mode 100644 os/cerf405/cerf delete mode 100644 os/cerf405/clock.c delete mode 100644 os/cerf405/compile.c delete mode 100644 os/cerf405/dat.h delete mode 100644 os/cerf405/devboot.c delete mode 100644 os/cerf405/devether.c delete mode 100644 os/cerf405/devrtc.c delete mode 100644 os/cerf405/devuart.c delete mode 100644 os/cerf405/etheremac.c delete mode 100644 os/cerf405/etherif.h delete mode 100644 os/cerf405/fns.h delete mode 100644 os/cerf405/fpi.h delete mode 100644 os/cerf405/fpipower.c delete mode 100644 os/cerf405/gpio.c delete mode 100644 os/cerf405/iic.c delete mode 100644 os/cerf405/inb.s delete mode 100644 os/cerf405/io.h delete mode 100644 os/cerf405/l.s delete mode 100644 os/cerf405/main.c delete mode 100644 os/cerf405/mal.c delete mode 100644 os/cerf405/mem.h delete mode 100644 os/cerf405/mkfile delete mode 100644 os/cerf405/mmu.c delete mode 100644 os/cerf405/nand.c delete mode 100644 os/cerf405/nofp.s delete mode 100644 os/cerf405/pci.c delete mode 100644 os/cerf405/physmem.h delete mode 100644 os/cerf405/powerbreak.c delete mode 100644 os/cerf405/rmap.c delete mode 100644 os/cerf405/tlb.s delete mode 100644 os/cerf405/trap.c delete mode 100644 os/cerf405/uart.c delete mode 100644 os/cerf405/uart.h (limited to 'os/cerf405') diff --git a/os/cerf405/README b/os/cerf405/README deleted file mode 100644 index c526927b..00000000 --- a/os/cerf405/README +++ /dev/null @@ -1,45 +0,0 @@ -Cerfcube 405EP - -This is the basis of a port to a range of IBM PowerPC 405 devices. -At some point all the common code will move to ../ppc, as is done -for SA1110, MPC8xx, and others. - -Currently untested: - - both EMAC0 and EMAC1 are initialised, but EMAC1 hasn't been tested (i need to get a cable made); - the PHY for it is detected and initialised, so i think it should work - - pci has not been tested since i haven't yet got the mini-PCI card i need - -Will change: - - devuart.c/uart.h will be replaced by ../port/devuart.c and uart405.c eventually - - power control will be extended - -mk in this directory should produce a file `icerfhd', which is icerf parcelled as ppcboot/uboot expects it. -put it where your tftp server can find it. - -on the machine to be used as file server, run inferno and start svc/net -to serve Styx - -To boot Inferno: - 1. set up a dhcp/tftp server for the EMAC0 MAC address, referring to the icerfhd file as the bootfile. - 2. connect a b115200 l8 pn serial port to talk to the ppcboot/uboot bootstrap - 3. reset the 405, and interrupt the automatic boot to get to the bootstrap's prompt - 4. type - bootp - 5. if dhcp is set correctly, that should load the Inferno boot image into memory at 0x300000 - 6. type - bootm - to boot that image. - -To put Inferno kernel image (icerfhd) on NAND flash: - - the boot area is 0 to 0x100000 on NAND (perhaps a bit more, but 0x100000 is currently fine) - 1. get to the bootstrap's prompt. - 2. nand erase 0 0x100000 - 3. bootp # loads the image to 0x300000 by tftp - 4. nand write 0x300000 0 0x100000 - 5. a subsequent {nand; bootm} (as for auto boot) should run that kernel. - -To initialise a file system on the NAND flash: - 1. set logfsformat=yes in the environment - 2. boot inferno - 3. choose remote file system or kernel file system when offered - 4. the empty flash file system should be in /n/local diff --git a/os/cerf405/cerf b/os/cerf405/cerf deleted file mode 100644 index e5b302a8..00000000 --- a/os/cerf405/cerf +++ /dev/null @@ -1,142 +0,0 @@ -# Intrinsyc Cerf Cube 405EP -dev - root - cons - env - mnt - pipe - prog - rtc iic - srv - dup - ssl - cap -# sign - - ip ip ipv6 ipaux iproute arp netlog ptclbsum iprouter plan9 nullmedium pktmedium netaux - ether netif netaux - uart - flash - - logfs - i2c iic - pci pci inb - - -ip - il - tcp - udp -# rudp -# igmp - ipifc - icmp - icmp6 - ipmux - -lib - interp - keyring - sec - mp - math - kern - logfs - nandfs - -link - etheremac ethermii - flashamd29f0x0 - flashnand nand - ethermedium - -mod - math - sys - keyring - crypt - ipints - - -port - alarm - alloc - allocb - chan - dev - dial - dis - discall - exception - exportfs - inferno - latin1 - nocache - nodynld - parse - pgrp - print - proc - qio - qlock - random - sysfile - taslock - xalloc - -code - int cflag = 0; - int consoleprint = 1; - int panicreset = 0; - int main_pool_pcnt = 50; - int heap_pool_pcnt = 50; - int image_pool_pcnt = 0; - void screeninit(void){} - -init - cerf405 - -root - /chan / - /dev / - /boot / - /env / - /fd / - /net / - /prog / - /root / - /nvfs / - /osinit.dis - /tmp / - -# files used by osinit.dis during bootstrap - /boot/n / - /boot/n/local / - /boot/n/remote / -# authentication - /boot/nvfs/default /usr/inferno/keyring/default - /boot/dis/lib/auth.dis /dis/lib/auth.dis - /boot/dis/lib/ssl.dis /dis/lib/ssl.dis -# dhcp - /boot/dis/lib/dhcpclient.dis /dis/lib/dhcpclient.dis - /boot/dis/lib/ip.dis /dis/lib/ip.dis - -# and other files used to poke round during development - /boot/dis/cat.dis /dis/cat.dis - /boot/dis/echo.dis /dis/echo.dis - /boot/dis/lib/arg.dis /dis/lib/arg.dis - - /boot/dis/sh.dis /dis/sh.dis - /boot/dis/lib/bufio.dis /dis/lib/bufio.dis - /boot/dis/lib/filepat.dis /dis/lib/filepat.dis - /boot/dis/lib/readdir.dis /dis/lib/readdir.dis - /boot/dis/lib/string.dis /dis/lib/string.dis - - /boot/dis/cd.dis /dis/cd.dis - /boot/dis/bind.dis /dis/bind.dis - /boot/dis/dd.dis /dis/dd.dis - /boot/dis/p.dis /dis/p.dis - /boot/dis/ls.dis /dis/ls.dis - /boot/dis/lib/daytime.dis /dis/lib/daytime.dis - /boot/dis/time.dis /dis/time.dis - /boot/dis/xd.dis /dis/xd.dis diff --git a/os/cerf405/clock.c b/os/cerf405/clock.c deleted file mode 100644 index d830c18c..00000000 --- a/os/cerf405/clock.c +++ /dev/null @@ -1,159 +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 -#include - -typedef struct Clock0link Clock0link; -typedef struct Clock0link { - void (*clock)(void); - Clock0link* link; -} Clock0link; - -static Clock0link *clock0link; -static Lock clock0lock; -ulong clkrelinq; -void (*kproftick)(ulong); /* set by devkprof.c when active */ -void (*archclocktick)(void); /* set by arch*.c when desired */ - -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; -} - -void -delay(int l) -{ - ulong i, j; - - j = m->delayloop; - while(l-- > 0) - for(i=0; i < j; i++) - ; -} - -void -microdelay(int l) -{ - ulong i; - - l *= m->delayloop; - l /= 1000; - if(l <= 0) - l = 1; - for(i = 0; i < l; i++) - ; -} - -enum { - Timebase = 1, /* system clock cycles per time base cycle */ - - Wp17= 0<<30, /* watchdog period (2^x clocks) */ - Wp21= 1<<30, - Wp25= 2<<30, - Wp29= 3<<30, - Wrnone= 0<<28, /* no watchdog reset */ - Wrcore= 1<<28, /* core reset */ - Wrchip= 2<<28, /* chip reset */ - Wrsys= 3<<28, /* system reset */ - Wie= 1<<27, /* watchdog interrupt enable */ - Pie= 1<<26, /* enable PIT interrupt */ - Fit9= 0<<24, /* fit period (2^x clocks) */ - Fit13= 1<<24, - Fit17= 2<<24, - Fit21= 3<<24, - Fie= 1<<23, /* fit interrupt enable */ - Are= 1<<22, /* auto reload enable */ - - /* dcr */ - Boot= 0x0F1, - Epctl= 0x0F3, - Pllmr0= 0x0F0, - Pllmr1= 0x0F4, - Ucr= 0x0F5, -}; - -void -clockinit(void) -{ - long x; - - m->delayloop = m->cpuhz/1000; /* initial estimate */ - do { - x = gettbl(); - delay(10); - x = gettbl() - x; - } while(x < 0); - - /* - * fix count - */ - m->delayloop = ((vlong)m->delayloop*(10*(vlong)m->clockgen/1000))/(x*Timebase); - if((int)m->delayloop <= 0) - m->delayloop = 20000; - - x = (m->clockgen/Timebase)/HZ; - putpit(x); -iprint("pit value=%.8lux [%lud]\n", x, x); - puttsr(~0); - puttcr(Pie|Are); -iprint("boot=%.8lux epctl=%.8lux pllmr0=%.8lux pllmr1=%.8lux ucr=%.8lux\n", - getdcr(Boot), getdcr(Epctl), getdcr(Pllmr0), getdcr(Pllmr1), getdcr(Ucr)); -} - -void -clockintr(Ureg *ur) -{ - Clock0link *lp; - - /* PIT was set to reload automatically */ - puttsr(~0); - m->ticks++; - - if(up) - up->pc = ur->pc; - - if(archclocktick != nil) - archclocktick(); - checkalarms(); - if(m->machno == 0) { - if(kproftick != nil) - (*kproftick)(ur->pc); - lock(&clock0lock); - for(lp = clock0link; lp; lp = lp->link) - lp->clock(); - unlock(&clock0lock); - } - - if(up && up->state == Running){ - if(cflag && up->type == Interp && tready(nil)) - ur->cr |= 1; /* set flag in condition register for ../../interp/comp-power.c:/^schedcheck */ - if(anyready()) - sched(); - } -} - -uvlong -fastticks(uvlong *hz) -{ - if(hz) - *hz = HZ; - return m->ticks; -} diff --git a/os/cerf405/compile.c b/os/cerf405/compile.c deleted file mode 100644 index da9976f2..00000000 --- a/os/cerf405/compile.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -#define MAXDCR 0x220 - -#define DCRF(n) ((((n)>>5)&0x1F)|(((n)&0x1F)<<5)) -#define MTDCR(s,n) ((31<<26)|((s)<<21)|(DCRF(n)<<11)|(451<<1)) -#define MFDCR(n,t) ((31<<26)|((t)<<21)|(DCRF(n)<<11)|(323<<1)) -#define RETURN 0x4e800020 -ulong _getdcr[MAXDCR][2]; -ulong _putdcr[MAXDCR][2]; - -void -compiledcr(void) -{ - ulong *p; - int i; - - for(i=0; imachno (unused) */ - - /* ordering from here on irrelevant */ - ulong ticks; /* of the clock since boot time */ - Proc *proc; /* current process on this processor */ - Label sched; /* scheduler wakeup */ - Lock alarmlock; /* access to alarm list */ - void *alarm; /* alarms bound to this clock */ - int nrdy; - int speed; /* general system clock in MHz */ - long oscclk; /* oscillator frequency (MHz) */ - long cpuhz; /* general system clock (cycles) */ - long clockgen; /* clock generator frequency (cycles) */ - long vcohz; - long pllhz; - long plbhz; - long opbhz; - long epbhz; - long pcihz; - int cputype; - ulong delayloop; - - /* MUST BE LAST */ - int stack[1]; -}; -extern Mach mach0; - - -/* - * a parsed .ini line - */ -#define NISAOPT 8 - -struct ISAConf { - char* type; - ulong port; - ulong irq; - ulong mem; - int dma; - ulong size; - ulong freq; - uchar bus; - - int nopt; - char* opt[NISAOPT]; -}; - -struct Map { - int size; - ulong addr; -}; - -struct RMap { - char* name; - Map* map; - Map* mapend; - - Lock; -}; - -struct Power { - Dev* dev; - int (*powerdown)(Power*); - int (*powerup)(Power*); - int state; - void* arg; -}; - -extern register Mach *m; -extern register Proc *up; diff --git a/os/cerf405/devboot.c b/os/cerf405/devboot.c deleted file mode 100644 index 126fe6e6..00000000 --- a/os/cerf405/devboot.c +++ /dev/null @@ -1,132 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -enum{ - Qdir, - Qboot, - Qmem, -}; - -Dirtab bootdir[]={ - ".", {Qdir,0,QTDIR}, 0, 0555, - "boot", {Qboot}, 0, 0666, - "mem", {Qmem}, 0, 0666, -}; - -#define NBOOT (sizeof bootdir/sizeof(Dirtab)) - -static void -bootreset(void) -{ -} - -static Chan* -bootattach(char *spec) -{ - return devattach('B', spec); -} - -static Walkqid* -bootwalk(Chan *c, Chan *nc, char **name, int nname) -{ - return devwalk(c, nc, name, nname, bootdir, NBOOT, devgen); -} - -static int -bootstat(Chan *c, uchar *dp, int n) -{ - return devstat(c, dp, n, bootdir, NBOOT, devgen); -} - -static Chan* -bootopen(Chan *c, int omode) -{ - return devopen(c, omode, bootdir, NBOOT, devgen); -} - -static void -bootclose(Chan*) -{ -} - -static long -bootread(Chan *c, void *buf, long n, vlong off) -{ - ulong offset = off; - - switch((ulong)c->qid.path){ - - case Qdir: - return devdirread(c, buf, n, bootdir, NBOOT, devgen); - - case Qmem: - /* kernel memory */ - if(offset>=KZERO && offset KZERO+conf.npage*BY2PG) - n = KZERO+conf.npage*BY2PG - offset; - memmove(buf, (char*)offset, n); - return n; - } - error(Ebadarg); - } - - error(Egreg); - return 0; /* not reached */ -} - -static long -bootwrite(Chan *c, void *buf, long n, vlong off) -{ - ulong offset = off; - ulong pc; - uchar *p; - - switch((ulong)c->qid.path){ - case Qmem: - /* kernel memory */ - if(offset>=KZERO && offset KZERO+conf.npage*BY2PG) - n = KZERO+conf.npage*BY2PG - offset; - memmove((char*)offset, buf, n); - segflush((void*)offset, n); - return n; - } - error(Ebadarg); - - case Qboot: - p = (uchar*)buf; - pc = (((((p[0]<<8)|p[1])<<8)|p[2])<<8)|p[3]; - if(pc < KZERO || pc >= KZERO+conf.npage*BY2PG) - error(Ebadarg); - splhi(); - segflush((void*)pc, 64*1024); - gotopc(pc); - } - error(Ebadarg); - return 0; /* not reached */ -} - -Dev bootdevtab = { - 'B', - "boot", - - bootreset, - devinit, - devshutdown, - bootattach, - bootwalk, - bootstat, - bootopen, - devcreate, - bootclose, - bootread, - devbread, - bootwrite, - devbwrite, - devremove, - devwstat, -}; diff --git a/os/cerf405/devether.c b/os/cerf405/devether.c deleted file mode 100644 index eb4ed283..00000000 --- a/os/cerf405/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; idetach != 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 = ðer->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->tbdf = BUSUNKNOWN; - - 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, ðer->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->irq, ether->interrupt, ether, ether->tbdf, name); - - i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %lud", - ctlrno, ether->type, ether->mbps, ether->port, ether->irq); - if(ether->mem) - i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem)); - if(ether->size) - i += sprint(buf+i, " size 0x%luX", ether->size); - i += sprint(buf+i, ": %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX", - ether->ea[0], ether->ea[1], ether->ea[2], - ether->ea[3], ether->ea[4], ether->ea[5]); - sprint(buf+i, "\n"); - print(buf); - - if(ether->mbps == 100){ - netifinit(ether, name, Ntypes, 256*1024); - if(ether->oq == 0) - ether->oq = qopen(256*1024, 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/cerf405/devrtc.c b/os/cerf405/devrtc.c deleted file mode 100644 index f743f1e0..00000000 --- a/os/cerf405/devrtc.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * DS1339 Timekeeper (on I2C) - */ - -#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 Rtc Rtc; -typedef struct Rtcreg Rtcreg; - -struct Rtc -{ - int sec; - int min; - int hour; - int wday; - int mday; - int mon; - int year; -}; - -struct Rtcreg -{ - uchar sec; - uchar min; - uchar hour; - uchar wday; /* 1=Sun */ - uchar mday; /* 00-31 */ - uchar mon; /* 1-12 */ - uchar year; -}; - -enum{ - Qdir = 0, - Qrtc, - - Rtclen= 7, /* bytes read and written to timekeeper */ -}; - -static QLock rtclock; /* mutex on nvram operations */ -static I2Cdev rtdev; - -static Dirtab rtcdir[]={ - ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, - "rtc", {Qrtc, 0}, 0, 0664, -}; - -static ulong rtc2sec(Rtc*); -static void sec2rtc(ulong, Rtc*); -static void setrtc(Rtc*); - -static void -rtcreset(void) -{ - rtdev.addr = 0x68; - rtdev.salen = 1; - i2csetup(1); -} - -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, nelem(rtcdir), devgen); -} - -static int -rtcstat(Chan *c, uchar *dp, int n) -{ - return devstat(c, dp, n, rtcdir, nelem(rtcdir), devgen); -} - -static Chan* -rtcopen(Chan *c, int omode) -{ - omode = openmode(omode); - switch((ulong)c->qid.path){ - case Qrtc: - if(strcmp(up->env->user, eve)!=0 && omode!=OREAD) - error(Eperm); - break; - } - return devopen(c, omode, rtcdir, nelem(rtcdir), devgen); -} - -static void -rtcclose(Chan*) -{ -} - -static long -rtcread(Chan *c, void *buf, long n, vlong offset) -{ - ulong t, ot; - - if(c->qid.type & QTDIR) - return devdirread(c, buf, n, rtcdir, nelem(rtcdir), devgen); - - switch((ulong)c->qid.path){ - case Qrtc: - qlock(&rtclock); - t = rtctime(); - do{ - ot = t; - t = rtctime(); /* make sure there's no skew */ - }while(t != ot); - qunlock(&rtclock); - return readnum(offset, buf, n, t, 12); - } - error(Egreg); - return -1; /* never reached */ -} - -static long -rtcwrite(Chan *c, void *buf, long n, vlong off) -{ - Rtc rtc; - ulong secs; - char *cp, sbuf[32]; - ulong offset = off; - - switch((ulong)c->qid.path){ - case Qrtc: - if(offset!=0 || n >= sizeof(sbuf)-1) - error(Ebadarg); - memmove(sbuf, buf, n); - sbuf[n] = '\0'; - /* - * read the time - */ - cp = sbuf; - while(*cp){ - if(*cp>='0' && *cp<='9') - break; - cp++; - } - secs = strtoul(cp, 0, 0); - /* - * convert to bcd - */ - sec2rtc(secs, &rtc); - /* - * write it - */ - setrtc(&rtc); - return n; - } - error(Egreg); - return -1; /* never reached */ -} - -Dev rtcdevtab = { - 'r', - "rtc", - - rtcreset, - devinit, - devshutdown, - rtcattach, - rtcwalk, - rtcstat, - rtcopen, - devcreate, - rtcclose, - rtcread, - devbread, - rtcwrite, - devbwrite, - devremove, - devwstat, -}; - -static int -getbcd(int bcd) -{ - return (bcd&0x0f) + 10 * (bcd>>4); -} - -static int -putbcd(int val) -{ - return (val % 10) | (((val/10) % 10) << 4); -} - -long -rtctime(void) -{ - Rtc rtc; - Rtcreg d; - int h; - - if(waserror()){ - iprint("rtc: err %s\n", up->env->errstr); - return 0; - } - if(i2crecv(&rtdev, &d, Rtclen, 0) != Rtclen) - return 0; - poperror(); - rtc.sec = getbcd(d.sec); - rtc.min = getbcd(d.min); - if(d.hour & (1<<6)){ /* 12 hour clock */ - h = d.hour & 0x1F; - if(d.hour & (1<<5)) - h += 0x12; - rtc.hour = getbcd(h); - }else - rtc.hour = getbcd(d.hour); - rtc.mday = getbcd(d.mday); - rtc.mon = getbcd(d.mon & 0x7f); - rtc.year = getbcd(d.year); - if(rtc.mon < 1 || rtc.mon > 12) - return 0; - if(d.mon & (1<<7)) - rtc.year += 2000; - else - rtc.year += 1900; - return rtc2sec(&rtc); -} - -static void -setrtc(Rtc *rtc) -{ - Rtcreg d; - - memset(&d, 0, sizeof(d)); - d.year = putbcd(rtc->year % 100); - d.mon = putbcd(rtc->mon); - if(rtc->year >= 2000) - d.mon |= 1<<7; - d.wday = rtc->wday+1; - d.mday = putbcd(rtc->mday); - d.hour = putbcd(rtc->hour); - d.min = putbcd(rtc->min); - d.sec = putbcd(rtc->sec); - i2csend(&rtdev, &d, Rtclen, 0); -} - -#define SEC2MIN 60L -#define SEC2HOUR (60L*SEC2MIN) -#define SEC2DAY (24L*SEC2HOUR) - -/* - * days per month plus days/year - */ -static int dmsize[] = -{ - 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; -static int ldmsize[] = -{ - 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -/* - * return the days/month for the given year - */ -static int * -yrsize(int y) -{ - - if((y%4) == 0 && ((y%100) != 0 || (y%400) == 0)) - return ldmsize; - else - return dmsize; -} - -/* - * compute seconds since Jan 1 1970 - */ -static ulong -rtc2sec(Rtc *rtc) -{ - ulong secs; - int i; - int *d2m; - - secs = 0; - - /* - * seconds per year - */ - for(i = 1970; i < rtc->year; i++){ - d2m = yrsize(i); - secs += d2m[0] * SEC2DAY; - } - - /* - * seconds per month - */ - d2m = yrsize(rtc->year); - for(i = 1; i < rtc->mon; i++) - secs += d2m[i] * SEC2DAY; - - secs += (rtc->mday-1) * SEC2DAY; - secs += rtc->hour * SEC2HOUR; - secs += rtc->min * SEC2MIN; - secs += rtc->sec; - - return secs; -} - -/* - * compute rtc from seconds since Jan 1 1970 - */ -static void -sec2rtc(ulong secs, Rtc *rtc) -{ - int d; - long hms, day; - int *d2m; - - /* - * break initial number into days - */ - hms = secs % SEC2DAY; - day = secs / SEC2DAY; - if(hms < 0) { - hms += SEC2DAY; - day -= 1; - } - - /* - * day is the day number. - * generate day of the week. - * The addend is 4 mod 7 (1/1/1970 was Thursday) - */ - - rtc->wday = (day + 7340036L) % 7; - - /* - * generate hours:minutes:seconds - */ - rtc->sec = hms % 60; - d = hms / 60; - rtc->min = d % 60; - d /= 60; - rtc->hour = d; - - /* - * year number - */ - if(day >= 0) - for(d = 1970; day >= *yrsize(d); d++) - day -= *yrsize(d); - else - for (d = 1970; day < 0; d--) - day += *yrsize(d-1); - rtc->year = d; - - /* - * generate month - */ - d2m = yrsize(rtc->year); - for(d = 1; day >= d2m[d]; d++) - day -= d2m[d]; - rtc->mday = day + 1; - rtc->mon = d; -} diff --git a/os/cerf405/devuart.c b/os/cerf405/devuart.c deleted file mode 100644 index eba92cba..00000000 --- a/os/cerf405/devuart.c +++ /dev/null @@ -1,1064 +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. - */ -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 */ - 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= 2, /* max per machine */ -}; - -typedef struct Uart Uart; -struct Uart -{ - QLock; - int opens; - - int enabled; - Uart *elist; /* next enabled interface */ - char name[KNAMELEN]; - - uchar 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; - 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] = 0; - 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); - - 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; - } -} - -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/cerf405/etheremac.c b/os/cerf405/etheremac.c deleted file mode 100644 index 484c4205..00000000 --- a/os/cerf405/etheremac.c +++ /dev/null @@ -1,829 +0,0 @@ -/* - * ethernet - */ - -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" -#include "../port/netif.h" - -#include "ethermii.h" -#include "etherif.h" -#include "ureg.h" - -/* - * TO DO: - * - test EMAC1 - */ - -#define DBG if(0)iprint -#define MIIDBG if(0)iprint - -enum { - Nrdre = 64, /* receive descriptor ring entries */ - Ntdre = 32, /* transmit descriptor ring entries */ - Nrxchan = 2, - Ntxchan = 2, /* there are actually 4 but we only use 2 now */ - - Rbsize = ETHERMAXTU, /* ring buffer size */ - Bufsize = (Rbsize+CACHELINESZ-1)&~(CACHELINESZ-1), /* aligned */ -}; - -enum { - /* emac-specific Rx BD bits */ - RxOverrun= 1<<9, /* not enough empty space in FIFO */ - RxPause= 1<<8, /* control pause packet */ - RxBad= 1<<7, /* packet error */ - RxRunt= 1<<6, - RxShort= 1<<5, - RxAlign= 1<<4, - RxFCS= 1<<3, - RxLong= 1<<2, - RxRange= 1<<1, /* out of range error */ - RxInRange= 1<<0, /* in range error */ - RxError= (0x3FF & ~RxPause), /* error flags */ - - /* emac-specific Tx BD bits */ - /* write access */ - TxFCS= 1<<9, /* generate FCS */ - TxPad= 1<<8, /* pad short frames */ - TxInsSA= 1<<7, /* insert source address */ - TxRepSA= 1<<6, /* replace source address */ - TxInsVLAN= 1<<5, /* insert VLAN tag */ - TxRepVLAN= 1<<4, /* replace VLAN tag */ - - /* read access (status) */ - TxBadFCS= 1<<9, - TxBadPrev= 1<<8, /* bad previous packet in dependent mode */ - TxLostCarrier= 1<<7, - TxEDef= 1<<6, /* excessive deferral */ - TxECol= 1<<5, /* excessive collisions */ - TxLateCol= 1<<4, /* late collision (half-duplex only) */ - TxManyCol= 1<<3, /* more than 1 but less than 16 collisions */ - TxCollision= 1<<2, /* single collision */ - TxUnderrun= 1<<1, /* didn't fill FIFO in time */ - TxSQE= 1<<0, /* signal quality test failed (10mbit half-duplex only) */ - TxError= 0x3FF, /* error flags */ -}; - -typedef struct Emac Emac; -struct Emac { - ulong mr0; /* mode register 0 [see 19-48] */ - ulong mr1; /* mode register 1 [Reset] */ - ulong tmr0; /* transmit mode register 0 [see 19-28] */ - ulong tmr1; /* transmit mode register 1 [see 19-28] */ - ulong rmr; /* receive mode register [Reset] */ - ulong isr; /* interrupt status register [Always] */ - ulong iser; /* interrupt status enable register [Reset] */ - ulong iahr; /* individual address high [Reset, R, T]*/ - ulong ialr; /* individual address low [Reset, R, T] */ - ulong vtpid; /* VLAN Tag Protocol Identifier [Reset, R, T] */ - ulong vtci; /* VLAN Tag Control Information [Reset, R, T] */ - ulong ptr; /* pause timer [Reset, T] */ - ulong iaht[4]; /* individual address hash table [Reset, R] */ - ulong gaht[4]; /* group address hash table [Reset, R] */ - ulong lsah; /* last source address high */ - ulong lsal; /* last source address low */ - ulong ipgvr; /* inter-packet gap value [Reset, T] */ - ulong stacr; /* STA control register [see 19-41] */ - ulong trtr; /* transmit request threshold register [see 19-42] */ - ulong rwmr; /* receive low/high water mark [Reset] */ - ulong octx; /* bytes transmitted */ - ulong ocrx; /* bytes received */ -}; - -enum { - /* mode register 0 */ - Mr0Rxi= 1<<31, /* receive MAC idle */ - Mr0Txi= 1<<30, /* transmit MAC idle */ - Mr0Srst= 1<<29, /* soft reset; soft reset in progress */ - Mr0Txe= 1<<28, /* tx MAC enable */ - Mr0Rxe= 1<<27, /* rx MAC enable */ - Mr0Wke= 1<<26, /* enable wake-up packets */ - - /* mode register 1 */ - Mr1Fde= 1<<31, /* full-duplex enable */ - Mr1Ile= 1<<30, /* internal loop-back enable */ - Mr1Vle= 1<<29, /* VLAN enable */ - Mr1Eifc= 1<<28, /* enable integrated flow control */ - Mr1App= 1<<27, /* allow pause packets */ - Mr1Ist= 1<<24, /* ignore sqe test (all but half-duplex 10m/bit) */ - Mr1Mf10= 0<<22, /* medium [MII] frequency is 10 mbps */ - Mr1Mf100= 1<<22, /* medium frequency is 100 mbps */ - Mr1Rfs512= 0<<20, /* RX FIFO size (512 bytes) */ - Mr1Rfs1024= 1<<20, - Mr1Rfs2048= 2<<20, - Mr1Rfs4096= 3<<20, - Mr1Tfs1024= 1<<18, /* TX FIFO size (1024 bytes) */ - Mr1Tfs2048= 2<<18, - Mr1Tr0sp= 0<<15, /* transmit request 0: single packet */ - Mr1Tr0mp= 1<<15, /* multiple packets */ - Mr1Tr0dm= 2<<15, /* dependent mode */ - Mr1Tr1sp= 0<<13, /* transmit request 1: single packet */ - Mr1Tr1mp= 1<<13, /* multiple packets */ - Mr1Tr1dm= 2<<13, /* dependent mode */ - - /* transmit mode register 0 */ - Tmr0Gnp0= 1<<31, /* get new packet channel 0 */ - Tmr0Gnp1= 1<<30, /* get new packet channel 1 */ - Tmr0Gnpd= 1<<29, /* get new packet dependent mode */ - Tmr0Fc= 1<<28, /* first channel (dependent mode) */ - - /* transmit mode register 1 */ - Tmr1Trl_s= 27, /* transmit low request (shift) */ - Tmr1Tur_s= 16, /* transmit urgent request (shift) */ - - /* receive mode register */ - RmrSp= 1<<31, /* strip pad/FCS bytes */ - RmrSfcs= 1<<30, /* strip FCS */ - RmrRrp= 1<<29, /* receive runt packets */ - RmrRfp= 1<<28, /* receive packets with FCS error */ - RmrRop= 1<<27, /* receive oversize packets */ - RmrRpir= 1<<26, /* receive packets with in range error */ - RmrPpp= 1<<25, /* propagate pause packet */ - RmrPme= 1<<24, /* promiscuous mode enable */ - RmrPmme= 1<<23, /* promiscuous mode multicast enable */ - RmrIae= 1<<22, /* individual address enable */ - RmrMiae= 1<<21, /* multiple individual address enable */ - RmrBae= 1<<20, /* broadcast address enable */ - RmrMae= 1<<19, /* multicast address enable */ - - /* interrupt status register */ - IsrOvr= 1<<25, /* overrun error */ - IsrPp= 1<<24, /* pause packet */ - IsrBp= 1<<23, /* bad packet */ - IsrRp= 1<<22, /* runt packet */ - IsrSe= 1<<21, /* short event */ - IsrAle= 1<<20, /* alignment error */ - IsrBfcs= 1<<19, /* bad FCS */ - IsrPtle= 1<<18, /* packet too long error */ - IsrOre= 1<<17, /* out of range error */ - IsrIre= 1<<16, /* in range error */ - IsrDbdm= 1<<9, /* dead bit dependent mode */ - IsrDb0= 1<<8, /* dead bit 0 */ - IsrSe0= 1<<7, /* sqe 0 */ - IsrTe0= 1<<6, /* tx error 0 */ - IsrDb1= 1<<5, /* dead bit 1 */ - IsrSe1= 1<<4, /* sqe 1 */ - IsrTe1= 1<<3, /* tx error 1 */ - IsrMos= 1<<1, /* MMA operation succeeded */ - IsrMof= 1<<0, /* MMA operation failed */ - - /* STA control register */ - StaOc= 1<<15, /* operation complete */ - StaPhye= 1<<14, /* PHY error */ - StaRead= 1<<12, /* STA read */ - StaWrite= 2<<12, /* STA write */ - StaOpb50= 0<<10, /* OPB frequency */ - StaOpb66= 1<<10, - StaOpb83= 2<<10, - StaOpb100= 3<<10, - - /* transmit request threshold */ - TrtrTrt_s= 27, /* threshold (shift) -- and the value is (threshold/64)-1 */ - - /* receive low/high water mark register */ - RwmrRlwm_s= 23, /* low water mark (shift) */ - RwmrRhwm_s= 7, /* high water mark (shift) */ -}; - -typedef struct { - Lock; - int port; - int init; - int active; - Emac *regs; - Emac *miiregs; - Mal* rx; - Mal* tx; - - Mii *mii; - - Ring; - - ulong interrupts; /* statistics */ - ulong deferred; - ulong heartbeat; - ulong latecoll; - ulong retrylim; - ulong underrun; - ulong overrun; - ulong carrierlost; - ulong retrycount; -} Ctlr; - -static void dumpemac(Emac*); - -static void -attach(Ether *ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - ilock(ctlr); - if(!ctlr->active){ - malrxenable(ctlr->rx); - maltxenable(ctlr->tx); - eieio(); - ctlr->regs->mr0 = Mr0Txe | Mr0Rxe; - eieio(); - ctlr->active = 1; - } - iunlock(ctlr); -} - -static void -closed(Ether *ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - if(ctlr->active){ - ilock(ctlr); -iprint("ether closed\n"); - ctlr->regs->mr0 &= ~(Mr0Txe | Mr0Rxe); /* reset enable bits */ - /* TO DO: reset ring */ - /* TO DO: could wait */ - ctlr->active = 0; - iunlock(ctlr); - } -} - -static void -promiscuous(void* arg, int on) -{ - Ether *ether; - Ctlr *ctlr; - - ether = (Ether*)arg; - ctlr = ether->ctlr; - - ilock(ctlr); - if(on || ether->nmaddr) - ctlr->regs->rmr |= RmrPme | RmrPmme; - else - ctlr->regs->rmr &= ~(RmrPme | RmrPmme); - iunlock(ctlr); -} - -static void -multicast(void* arg, uchar *addr, int on) -{ - Ether *ether; - Ctlr *ctlr; - - USED(addr, on); /* if on, could SetGroupAddress; if !on, it's hard */ - - ether = (Ether*)arg; - ctlr = ether->ctlr; - - ilock(ctlr); - if(ether->prom || ether->nmaddr) - ctlr->regs->rmr |= RmrPmme; - else - ctlr->regs->rmr &= ~RmrPmme; - iunlock(ctlr); -} - -static void -txstart(Ether *ether) -{ - int len; - Ctlr *ctlr; - Block *b; - BD *dre; - - ctlr = ether->ctlr; - while(ctlr->ntq < ctlr->ntdre-1){ - b = qget(ether->oq); - if(b == 0) - break; - - dre = &ctlr->tdr[ctlr->tdrh]; - if(dre->status & BDReady) - panic("ether: txstart"); - - /* - * Give ownership of the descriptor to the chip, increment the - * software ring descriptor pointer and tell the chip to poll. - */ - len = BLEN(b); - if(ctlr->txb[ctlr->tdrh] != nil) - panic("etheremac: txstart"); - ctlr->txb[ctlr->tdrh] = b; - dre->addr = PADDR(b->rp); - dre->length = len; - dcflush(b->rp, len); - eieio(); - dre->status = (dre->status & BDWrap) | BDReady|BDInt|BDLast|TxFCS|TxPad; - eieio(); - ctlr->regs->tmr0 = Tmr0Gnp0; /* TO DO: several channels */ - eieio(); - ctlr->ntq++; - ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdre); - } -} - -static void -transmit(Ether* ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - ilock(ctlr); - txstart(ether); - iunlock(ctlr); -} - -/* - * allocate receive buffer space on cache-line boundaries - */ -static Block* -clallocb(void) -{ - Block *b; - - b = iallocb(Bufsize+CACHELINESZ-1); - if(b == nil) - return b; - dcflush(b->base, BALLOC(b)); - b->wp = b->rp = (uchar*)(((ulong)b->base + CACHELINESZ - 1) & ~(CACHELINESZ-1)); - return b; -} - - -static void -rxring(Ureg*, void *arg) -{ - Ether *ether; - ulong status; - Ctlr *ctlr; - BD *dre; - Block *b, *rb; - - ether = arg; - ctlr = ether->ctlr; - ctlr->interrupts++; - - /* - * Receiver interrupt: run round the descriptor ring logging - * errors and passing valid receive data up to the higher levels - * until we encounter a descriptor still owned by the chip. - * We rely on the descriptor accesses being uncached. - */ - dre = &ctlr->rdr[ctlr->rdrx]; - while(((status = dre->status) & BDEmpty) == 0){ - if(status & RxError || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){ - if(status & (RxShort|RxLong)) - ether->buffs++; - if(status & (RxBad|RxAlign|RxRange|RxInRange)) - ether->frames++; - if(status & RxFCS) - ether->crcs++; - if(status & RxOverrun) - ether->overflows++; - iprint("eth rx: %lux\n", status); - }else if((status & RxPause) == 0){ - /* - * We have a packet. Read it in. - */ - b = clallocb(); - if(b != nil){ - rb = ctlr->rxb[ctlr->rdrx]; - rb->wp += dre->length; - ctlr->rxb[ctlr->rdrx] = b; - ctlr->rdr[ctlr->rdrx].addr = PADDR(b->wp); - etheriq(ether, rb, 1); - }else - ether->soverflows++; - } - - /* - * Finished with this descriptor, reinitialise it, - * give it back to the chip, then on to the next... - */ - dre->status = (status & BDWrap) | BDEmpty | BDInt; - eieio(); - - ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdre); - dre = &ctlr->rdr[ctlr->rdrx]; - } -} - -static void -txring(Ureg*, void *arg) -{ - Ether *ether; - ulong status; - Ctlr *ctlr; - BD *dre; - Block *b; - - ether = arg; - ctlr = ether->ctlr; - ctlr->interrupts++; - - /* - * Transmitter interrupt: handle anything queued for a free descriptor. - */ - lock(ctlr); - while(ctlr->ntq){ - dre = &ctlr->tdr[ctlr->tdri]; - status = dre->status; - if(status & BDReady) - break; - if(status & TxEDef) - ctlr->deferred++; - if(status & TxLateCol) - ctlr->latecoll++; - if(status & TxECol) - ctlr->retrylim++; - if(status & TxUnderrun) - ctlr->underrun++; - if(status & (TxManyCol|TxCollision)) - ctlr->retrycount++; - b = ctlr->txb[ctlr->tdri]; - if(b == nil) - panic("etheremac: bufp"); - ctlr->txb[ctlr->tdri] = nil; - freeb(b); - ctlr->ntq--; - ctlr->tdri = NEXT(ctlr->tdri, ctlr->ntdre); - } - txstart(ether); - unlock(ctlr); -} - -static void -interrupt(Ureg*, void *arg) -{ - Ether *ether; - ulong events; - Ctlr *ctlr; - - ether = arg; - ctlr = ether->ctlr; - - events = ctlr->regs->isr; - eieio(); - ctlr->regs->isr = events; - eieio(); - ctlr->interrupts++; -//iprint("eth: %8.8lux\n", events); - if(!ctlr->active || events == 0) - return; - - if(events & IsrOvr) - ctlr->overrun++; - if(events & (IsrTe0|IsrTe1)) - ether->oerrs++; - - rxring(nil, arg); - txring(nil, arg); - ctlr->interrupts -= 2; - - /* TO DO: restart tx/rx on error */ -} - -static long -ifstat(Ether* ether, void* a, long n, ulong offset) -{ - char *p; - int len; - Ctlr *ctlr; - - if(n == 0) - return 0; - - ctlr = ether->ctlr; - - p = malloc(READSTR); - len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts); - len += snprint(p+len, READSTR-len, "carrierlost: %lud\n", ctlr->carrierlost); - len += snprint(p+len, READSTR-len, "heartbeat: %lud\n", ctlr->heartbeat); - len += snprint(p+len, READSTR-len, "retrylimit: %lud\n", ctlr->retrylim); - len += snprint(p+len, READSTR-len, "retrycount: %lud\n", ctlr->retrycount); - len += snprint(p+len, READSTR-len, "latecollisions: %lud\n", ctlr->latecoll); - len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n", ctlr->overrun); - len += snprint(p+len, READSTR-len, "txunderruns: %lud\n", ctlr->underrun); - snprint(p+len, READSTR-len, "framesdeferred: %lud\n", ctlr->deferred); - n = readstr(offset, a, n, p); - free(p); - - return n; -} - -static QLock miilock; /* the PHY are both on EMAC0's MII bus */ - -static int -miird(Mii *mii, int pa, int ra) -{ - Ctlr *ctlr; - Emac *em; - ulong r; - int i; - - if(up) - qlock(&miilock); - ctlr = mii->ctlr; - em = ctlr->miiregs; - MIIDBG("r: %x.%x:", pa, ra); - if((em->stacr & StaOc) == 0) - iprint("mii-not oc\n"); - em->stacr = StaRead | StaOpb66 | (pa<<5) | ra; - for(i=0; i<100 && (em->stacr & StaOc) == 0; i++) - microdelay(1); - r = em->stacr; - if(up) - qunlock(&miilock); - if((r & StaOc) == 0) - iprint("mii'-not oc\n"); - if(r & StaPhye) - return -1; - MIIDBG(" %8.8lux\n", r); - return r >> 16; -} - -static int -miiwr(Mii *mii, int pa, int ra, int v) -{ - Ctlr *ctlr; - Emac *em; - ulong r; - int i; - - if(up) - qlock(&miilock); - ctlr = mii->ctlr; - em = ctlr->miiregs; - if((em->stacr & StaOc) == 0) - iprint("miiw-not oc\n"); - em->stacr = (v<<16) | StaWrite | StaOpb66 | (pa<<5) | ra; - for(i=0; i<100 && (em->stacr & StaOc) == 0; i++) - microdelay(1); - r = em->stacr; - if(up) - qunlock(&miilock); - if((r & StaOc) == 0) - iprint("miiw'-not oc\n"); - if(r & StaPhye) - return -1; - MIIDBG("w: %x.%x: %8.8lux\n", pa, ra, r); - return 0; -} - -static int -emacmii(Ctlr *ctlr) -{ - MiiPhy *phy; - int i; - - MIIDBG("mii\n"); - if((ctlr->mii = malloc(sizeof(Mii))) == nil) - return -1; - ctlr->mii->ctlr = ctlr; - ctlr->mii->mir = miird; - ctlr->mii->miw = miiwr; - - if(mii(ctlr->mii, 1<<(ctlr->port+1)) == 0 || (phy = ctlr->mii->curphy) == nil){ - free(ctlr->mii); - ctlr->mii = nil; - return -1; - } - - iprint("oui %X phyno %d\n", phy->oui, phy->phyno); - if(miistatus(ctlr->mii) < 0){ - - miireset(ctlr->mii); - MIIDBG("miireset\n"); - if(miiane(ctlr->mii, ~0, 0, ~0) < 0){ - iprint("miiane failed\n"); - return -1; - } - MIIDBG("miistatus...\n"); - miistatus(ctlr->mii); - if(miird(ctlr->mii, phy->phyno, Bmsr) & BmsrLs){ - for(i=0;; i++){ - if(i > 600){ - iprint("emac%d: autonegotiation failed\n", ctlr->port); - break; - } - if(miird(ctlr->mii, phy->phyno, Bmsr) & BmsrAnc) - break; - delay(10); - } - if(miistatus(ctlr->mii) < 0) - iprint("miistatus failed\n"); - }else{ - iprint("emac%d: no link\n", ctlr->port); - phy->speed = 10; /* simple default */ - } - } - - iprint("emac%d mii: fd=%d speed=%d tfc=%d rfc=%d\n", ctlr->port, phy->fd, phy->speed, phy->tfc, phy->rfc); - - MIIDBG("mii done\n"); - - return 0; -} - -static void -emacsetup(Ctlr *ctlr, Ether *ether) -{ - int i; - Emac *em; - ulong mode; - MiiPhy *phy; - - /* apparently don't need to set any Alt1 in GPIO */ - - em = ctlr->regs; - - /* errata emac_8 */ - if(em->mr0 & Mr0Rxe){ /* probably never happens in our config */ - em->mr0 &= ~Mr0Rxe; - eieio(); - for(i=0; (em->mr0 & Mr0Rxi) == 0; i++){ - if(i > 100){ - iprint("ethermac: Rxe->Rxi timed out\n"); - break; /* we'll try soft reset anyway */ - } - microdelay(100); - } - } - - /* soft reset */ - em->mr0 = Mr0Srst; - eieio(); - for(i=0; em->mr0 & Mr0Srst; i++){ - if(i > 20){ - iprint("ethermac: reset (PHY clocks not running?)"); - i=0; - } - microdelay(100); - } -iprint("%d: rx=%8.8lux tx=%8.8lux\n", ctlr->port, PADDR(ctlr->rdr), PADDR(ctlr->tdr)); -//if(ctlr->port)return; - - malrxinit(ctlr->rx, ctlr, Bufsize/16); - maltxinit(ctlr->tx, ctlr); - malrxreset(ctlr->rx); - maltxreset(ctlr->tx); - - em->mr0 = 0; - mode = Mr1Rfs4096 | Mr1Tfs2048 | Mr1Tr0mp; - if(ctlr->mii != nil && (phy = ctlr->mii->curphy) != nil){ - if(phy->speed == 10){ - mode |= Mr1Mf10; - if(phy->fd) - mode |= Mr1Ist; - }else - mode |= Mr1Mf100 | Mr1Ist; - if(phy->fd) - mode |= Mr1Fde; - /* errata emac_9 suggests not using integrated flow control (it's broken); so don't negotiate it */ - if(0 && (phy->rfc || phy->tfc)) - mode |= Mr1App | Mr1Eifc; - ether->mbps = phy->speed; - ether->fullduplex = phy->fd; - }else{ - iprint("mii: didn't work: default 100FD\n"); - mode |= Mr1Mf100 | Mr1Ist | Mr1Fde; - ether->mbps = 100; - ether->fullduplex = 1; - } - - em->mr1 = mode; - em->tmr1 = (9<rmr = RmrSp | RmrSfcs | RmrIae | RmrBae; - em->iahr = (ether->ea[0]<<8) | ether->ea[1]; - em->ialr = (ether->ea[2]<<24) | (ether->ea[3]<<16) | (ether->ea[4]<<8) | ether->ea[5]; - em->vtpid = 0; - em->vtci = 0; - em->ptr = 1; /* pause timer [Reset, T] */ - for(i=0; i<4; i++){ - em->iaht[i] = 0; /* individual address hash table */ - em->gaht[i] = 0; /* group address hash table */ - } - em->ipgvr = (96/8)/3; /* minimise bit times between packets */ - em->trtr = ((256/64)-1)<rwmr = (32<isr = em->isr; /* clear all events */ - eieio(); - em->iser = IsrOvr | IsrBp | IsrSe | IsrSe0 | IsrTe0 | IsrSe1 | IsrTe1; /* enable various error interrupts */ - /* packet tx/rx interrupts come from MAL */ - eieio(); - - /* tx/rx enable is deferred until attach */ -} - -static int -reset(Ether* ether) -{ - uchar ea[Eaddrlen]; - Ctlr *ctlr; - int i; - - ioringreserve(Nrxchan, Nrdre, Ntxchan, Ntdre); - - /* - * Insist that the platform-specific code provide the Ethernet address - */ - memset(ea, 0, Eaddrlen); - if(memcmp(ea, ether->ea, Eaddrlen) == 0){ - print("no ether address"); - return -1; - } - - ctlr = malloc(sizeof(*ctlr)); - ctlr->port = ether->port; - - switch(ether->port){ - case 0: - ctlr->regs = KADDR(PHYSEMAC0); - ctlr->miiregs = ctlr->regs; - ctlr->rx = malchannel(0, 0, rxring, ether); - ctlr->tx = malchannel(0, 1, txring, ether); - ether->irq = VectorEMAC0; - break; - case 1: - ctlr->regs = KADDR(PHYSEMAC1); - ctlr->miiregs = KADDR(PHYSEMAC0); /* p. 19-41: ``only the MDIO interface for EMAC0 is pinned out'' */ - ctlr->rx = malchannel(1, 0, rxring, ether); - ctlr->tx = malchannel(2, 1, txring, ether); - ether->irq = VectorEMAC1; - break; - default: - print("%s ether: no port %lud\n", ether->type, ether->port); - free(ctlr); - return -1; - } - - if(emacmii(ctlr) < 0){ - free(ctlr); - return -1; - } - - ether->ctlr = ctlr; - - if(ioringinit(ctlr, Nrdre, Ntdre) < 0) /* TO DO: there are two transmit rings*/ - panic("etheremac initring"); - - for(i = 0; i < ctlr->nrdre; i++){ - ctlr->rxb[i] = clallocb(); - ctlr->rdr[i].addr = PADDR(ctlr->rxb[i]->wp); - } - - emacsetup(ctlr, ether); - - ether->attach = attach; - ether->closed = closed; - ether->transmit = transmit; - ether->interrupt = interrupt; /* oddly, it's only error interrupts; see malchannel call above for tx/rx */ - ether->ifstat = ifstat; - - ether->arg = ether; - ether->promiscuous = promiscuous; - ether->multicast = multicast; - - return 0; -} - -void -etheremaclink(void) -{ - addethercard("EMAC", reset); -} - -static void -dumpemac(Emac *r) -{ - iprint("mr0=%8.8lux\n", r->mr0); /* mode register 0 [see 19-48] */ - iprint("mr1=%8.8lux\n", r->mr1); /* mode register 1 [Reset] */ - iprint("tmr0=%8.8lux\n", r->tmr0); /* transmit mode register 0 [see 19-28] */ - iprint("tmr1=%8.8lux\n", r->tmr1); /* transmit mode register 1 [see 19-28] */ - iprint("rmr=%8.8lux\n", r->rmr); /* receive mode register [Reset] */ - iprint("isr=%8.8lux\n", r->isr); /* interrupt status register [Always] */ - iprint("iser=%8.8lux\n", r->iser); /* interrupt status enable register [Reset] */ - iprint("iahr=%8.8lux\n", r->iahr); /* individual address high [Reset, R, T]*/ - iprint("ialr=%8.8lux\n", r->ialr); /* individual address low [Reset, R, T] */ - iprint("vtpid=%8.8lux\n", r->vtpid); /* VLAN Tag Protocol Identifier [Reset, R, T] */ - iprint("vtci=%8.8lux\n", r->vtci); /* VLAN Tag Control Information [Reset, R, T] */ - iprint("ptr=%8.8lux\n", r->ptr); /* pause timer [Reset, T] */ - iprint("lsah=%8.8lux\n", r->lsah); /* last source address high */ - iprint("lsal=%8.8lux\n", r->lsal); /* last source address low */ - iprint("ipgvr=%8.8lux\n", r->ipgvr); /* inter-packet gap value [Reset, T] */ - iprint("stacr=%8.8lux\n", r->stacr); /* STA control register [see 19-41] */ - iprint("trtr=%8.8lux\n", r->trtr); /* transmit request threshold register [see 19-42] */ - iprint("rwmr=%8.8lux\n", r->rwmr); /* receive low/high water mark [Reset] */ - iprint("octx=%8.8lux\n", r->octx); /* bytes transmitted */ - iprint("ocrx=%8.8lux\n", r->ocrx); /* bytes received */ -} diff --git a/os/cerf405/etherif.h b/os/cerf405/etherif.h deleted file mode 100644 index 26f0a764..00000000 --- a/os/cerf405/etherif.h +++ /dev/null @@ -1,37 +0,0 @@ -enum { - MaxEther = 4, - Ntypes = 8, -}; - -typedef struct Ether Ether; -struct Ether { -RWlock; /* TO DO */ - ISAConf; /* hardware info */ - int ctlrno; - int tbdf; /* type+busno+devno+funcno */ - 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*); diff --git a/os/cerf405/fns.h b/os/cerf405/fns.h deleted file mode 100644 index 4c6a3fa1..00000000 --- a/os/cerf405/fns.h +++ /dev/null @@ -1,147 +0,0 @@ -#include "../port/portfns.h" - -void addpower(Power*); -void archbacklight(int); -void archconfinit(void); -int archconfval(char**, char**, int); -void archdisableuart(int); -void archdisableusb(void); -void archdisablevideo(void); -void archenableuart(int, int); -void archenableusb(int, int); -void archenablevideo(void); -void archkbdinit(void); -void archresetvideo(void); -void archinit(void); -int archoptionsw(void); -void archreboot(void); -ulong archuartclock(int, int); -void archuartdma(int, int); -void clockcheck(void); -void clockinit(void); -void clockintr(Ureg*); -void clrfptrap(void); -#define coherence() /* nothing needed for uniprocessor */ -void compiledcr(void); -void cpuidprint(void); -void* dcflush(void*, ulong); -void dcinval(void*, ulong); -void delay(int); -void dtlbmiss(void); -void dumplongs(char*, ulong*, int); -void dumpregs(Ureg*); -void eieio(void); -void firmware(int); -void fpinit(void); -int fpipower(Ureg*); -void fpoff(void); -void fprestore(FPU*); -void fpsave(FPU*); -ulong fpstatus(void); -char* getconf(char*); -ulong getccr0(void); -ulong getdar(void); -ulong getdcr(int); -ulong getdear(void); -ulong getdepn(void); -ulong getdsisr(void); -ulong getesr(void); -ulong getimmr(void); -ulong getmsr(void); -ulong getpit(void); -ulong getpvr(void); -ulong gettbl(void); -ulong gettbu(void); -ulong gettsr(void); -void gotopc(ulong); -void icflush(void*, ulong); -void idle(void); -void idlehands(void); -int inb(int); -ulong inl(int); -int ins(int); -void insb(int, void*, int); -void insl(int, void*, int); -void inss(int, void*, int); -void intr(Ureg*); -void intrenable(int, void (*)(Ureg*, void*), void*, int, char*); -void intrdisable(int, void (*)(Ureg*, void*), void*, int, char*); -int intrstats(char*, int); -void intrvec(void); -void intrcvec(void); -void ioinit(void); -void ioreset(void); -int isaconfig(char*, int, ISAConf*); -int isvalid_va(void*); -void itlbmiss(void); -void kbdinit(void); -void kbdreset(void); -void* kmapphys(void*, ulong, ulong, ulong, ulong); -void lcdpanel(int); -void links(void); -void mapfree(RMap*, ulong, int); -void mapinit(RMap*, Map*, int); -void mathinit(void); -void mmuinit(void); -void* mmucacheinhib(void*, ulong); -ulong mmumapsize(ulong); -void pcimapinit(void); -int pciscan(int, Pcidev **); -ulong pcibarsize(Pcidev *, int); -int pcicfgr8(Pcidev*, int); -int pcicfgr16(Pcidev*, int); -int pcicfgr32(Pcidev*, int); -void pcicfgw8(Pcidev*, int, int); -void pcicfgw16(Pcidev*, int, int); -void pcicfgw32(Pcidev*, int, int); -void pciclrbme(Pcidev*); -void pcihinv(Pcidev*); -uchar pciipin(Pcidev *, uchar); -Pcidev* pcimatch(Pcidev*, int, int); -Pcidev* pcimatchtbdf(int); -void pcireset(void); -void pcisetbme(Pcidev*); -void procsave(Proc*); -void procsetup(Proc*); -void putdcr(int, ulong); -void putesr(ulong); -void putevpr(ulong); -void putmsr(ulong); -void putpit(ulong); -void puttcr(ulong); -void puttsr(ulong); -void puttwb(ulong); -ulong rmapalloc(RMap*, ulong, int, int); -long rtctime(void); -void screeninit(void); -int screenprint(char*, ...); /* debugging */ -void (*screenputs)(char*, int); -int segflush(void*, ulong); -void toggleled(int); -void setpanic(void); -ulong _tas(ulong*); -ulong tlbrehi(int); -ulong tlbrelo(int); -int tlbsxcc(void*); -void tlbwehi(int, ulong); -void tlbwelo(int, ulong); -void trapinit(void); -void trapvec(void); -void trapcvec(void); -void uartinstall(void); -void uartspecial(int, int, Queue**, Queue**, int (*)(Queue*, int)); -void uartwait(void); /* debugging */ -void wbflush(void); - -#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1])) -ulong getcallerpc(void*); - -#define isphys(a) (((ulong)(a)&KSEGM)!=KSEG0 && ((ulong)(a)&KSEGM)!=KSEG1) -#define KADDR(a) ((void*)((ulong)(a)|KZERO)) -#define PADDR(a) (isphys(a)?(ulong)(a):((ulong)(a)&~KSEGM)) - -/* IBM bit field order */ -#define IBIT(b) (((ulong)(1<<31))>>(b)) -#define SIBIT(n) ((ushort)1<<(15-(n))) -#define CIBIT(n) ((uchar)1<<(7-(n))) - diff --git a/os/cerf405/fpi.h b/os/cerf405/fpi.h deleted file mode 100644 index dfb9b1df..00000000 --- a/os/cerf405/fpi.h +++ /dev/null @@ -1,61 +0,0 @@ -typedef long Word; -typedef unsigned long Single; -typedef struct { - unsigned long h; - unsigned long l; -} Double; - -enum { - FractBits = 28, - CarryBit = 0x10000000, - HiddenBit = 0x08000000, - MsBit = HiddenBit, - NGuardBits = 3, - GuardMask = 0x07, - LsBit = (1<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/cerf405/fpipower.c b/os/cerf405/fpipower.c deleted file mode 100644 index ec4363b2..00000000 --- a/os/cerf405/fpipower.c +++ /dev/null @@ -1,970 +0,0 @@ -/* - * this doesn't attempt to implement Power architecture 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 REG(x) (*(long*)(((char*)em->ur)+roff[(x)])) -#define FR(x) (*(Internal*)em->fr[(x)&0x1F]) -#define REGSP 1 /* stack pointer */ - -/* BUG: check fetch (not worthwhile in Inferno) */ -#define getulong(a) (*(ulong*)(a)) - -enum { - CRLT = 1<<31, - CRGT = 1<<30, - CREQ = 1<<29, - CRSO = 1<<28, - CRFU = CRSO, - - CRFX = 1<<27, - CRFEX = 1<<26, - CRVX = 1<<25, - CROX = 1<<24, -}; - -#define getCR(x,w) (((w)>>(28-(x*4)))&0xF) -#define mkCR(x,v) (((v)&0xF)<<(28-(x*4))) - -#define simm(xx, ii) xx = (short)(ii&0xFFFF); -#define getairr(i) rd = (i>>21)&0x1f; ra = (i>>16)&0x1f; simm(imm,i) -#define getarrr(i) rd = (i>>21)&0x1f; ra = (i>>16)&0x1f; rb = (i>>11)&0x1f; -#define getop(i) ((i>>26)&0x3F) -#define getxo(i) ((i>>1)&0x3FF) - -#define FPS_FX (1<<31) /* exception summary (sticky) */ -#define FPS_EX (1<<30) /* enabled exception summary */ -#define FPS_VX (1<<29) /* invalid operation exception summary */ -#define FPS_OX (1<<28) /* overflow exception OX (sticky) */ -#define FPS_UX (1<<27) /* underflow exception UX (sticky) */ -#define FPS_ZX (1<<26) /* zero divide exception ZX (sticky) */ -#define FPS_XX (1<<25) /* inexact exception XX (sticky) */ -#define FPS_VXSNAN (1<<24) /* invalid operation exception for SNaN (sticky) */ -#define FPS_VXISI (1<<23) /* invalid operation exception for ∞-∞ (sticky) */ -#define FPS_VXIDI (1<<22) /* invalid operation exception for ∞/∞ (sticky) */ -#define FPS_VXZDZ (1<<21) /* invalid operation exception for 0/0 (sticky) */ -#define FPS_VXIMZ (1<<20) /* invalid operation exception for ∞*0 (sticky) */ -#define FPS_VXVC (1<<19) /* invalid operation exception for invalid compare (sticky) */ -#define FPS_FR (1<<18) /* fraction rounded */ -#define FPS_FI (1<<17) /* fraction inexact */ -#define FPS_FPRF (1<<16) /* floating point result class */ -#define FPS_FPCC (0xF<<12) /* <, >, =, unordered */ -#define FPS_VXCVI (1<<8) /* enable exception for invalid integer convert (sticky) */ -#define FPS_VE (1<<7) /* invalid operation exception enable */ -#define FPS_OE (1<<6) /* enable overflow exceptions */ -#define FPS_UE (1<<5) /* enable underflow */ -#define FPS_ZE (1<<4) /* enable zero divide */ -#define FPS_XE (1<<3) /* enable inexact exceptions */ -#define FPS_RN (3<<0) /* rounding mode */ - -typedef struct Emreg Emreg; - -struct Emreg { - Ureg* ur; - ulong (*fr)[3]; - FPenv* ufp; - ulong ir; - char* name; -}; - -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), - OFR(r12), OFR(r13), OFR(r14), OFR(r15), - OFR(r16), OFR(r17), OFR(r18), OFR(r19), - OFR(r20), OFR(r21), OFR(r22), OFR(r23), - OFR(r24), OFR(r25), OFR(r26), OFR(r27), - OFR(r28), OFR(r29), OFR(r30), OFR(r31), -}; - -/* - * initial FP register values assumed by qc's code - */ -static Internal fpreginit[] = { - /* s, e, l, h */ - {0, 0x400, 0x00000000, 0x08000000}, /* F31=2.0 */ - {0, 0x3FF, 0x00000000, 0x08000000}, /* F30=1.0 */ - {0, 0x3FE, 0x00000000, 0x08000000}, /* F29=0.5 */ - {0, 0x1, 0x00000000, 0x00000000}, /* F28=0.0 */ - {0, 0x433, 0x00000000, 0x08000040}, /* F27=FREGCVI */ -}; - -static void -fadd(Emreg *em, Internal *d, int ra, int rb) -{ - Internal a, b; - - a = FR(ra); - b = FR(rb); - (a.s == b.s? fpiadd: fpisub)(&b, &a, d); -} - -static void -fsub(Emreg *em, Internal *d, int ra, int rb) -{ - Internal a, b; - - a = FR(ra); - b = FR(rb); - b.s ^= 1; - (b.s == a.s? fpiadd: fpisub)(&b, &a, d); -} - -static void -fmul(Emreg *em, Internal *d, int ra, int rb) -{ - Internal a, b; - - a = FR(ra); - b = FR(rb); - fpimul(&b, &a, d); -} - -static void -fdiv(Emreg *em, Internal *d, int ra, int rb) -{ - Internal a, b; - - a = FR(ra); - b = FR(rb); - fpidiv(&b, &a, d); -} - -static void -fmsub(Emreg *em, Internal *d, int ra, int rc, int rb) -{ - Internal a, c, b, t; - - a = FR(ra); - c = FR(rc); - b = FR(rb); - fpimul(&a, &c, &t); - b.s ^= 1; - (b.s == t.s? fpiadd: fpisub)(&b, &t, d); -} - -static void -fmadd(Emreg *em, Internal *d, int ra, int rc, int rb) -{ - Internal a, c, b, t; - - a = FR(ra); - c = FR(rc); - b = FR(rb); - fpimul(&a, &c, &t); - (t.s == b.s? fpiadd: fpisub)(&b, &t, d); -} - -static ulong setfpscr(Emreg*); -static void setfpcc(Emreg*, int); - -static void -unimp(Emreg *em, ulong op) -{ - char buf[60]; - - snprint(buf, sizeof(buf), "sys: fp: pc=%lux unimp fp 0x%.8lux", em->ur->pc, op); - if(fpemudebug) - print("FPE: %s\n", buf); - error(buf); - /* no return */ -} - -/* - * floating load/store - */ - -static void -fpeairr(Emreg *em, ulong ir, void **eap, int *rdp) -{ - ulong ea; - long imm; - int ra, rd, upd; - - getairr(ir); - ea = imm; - upd = (ir&(1L<<26))!=0; - if(ra) { - ea += REG(ra); - if(upd){ - if(ra == REGSP) - panic("fpemu: r1 update"); /* can't do it because we're running on the same stack */ - REG(ra) = ea; - } - } else { - if(upd) - unimp(em, ir); - } - *rdp = rd; - *eap = (void*)ea; - if(fpemudebug) - print("%8.8lux %s\tf%d,%ld(r%d) ea=%lux upd=%d\n", em->ur->pc, em->name, rd, imm, ra, ea, upd); -} - -static void -fpearrr(Emreg *em, ulong ir, int upd, void **eap, int *rdp) -{ - ulong ea; - int ra, rb, rd; - - getarrr(ir); - ea = REG(rb); - if(ra){ - ea += REG(ra); - if(upd){ - if(ra == REGSP) - panic("fpemu: r1 update"); - REG(ra) = ea; - } - if(fpemudebug) - print("%8.8lux %s\tf%d,(r%d+r%d) ea=%lux upd=%d\n", em->ur->pc, em->name, rd, ra, rb, ea, upd); - } else { - if(upd) - unimp(em, ir); - if(fpemudebug) - print("%8.8lux %s\tf%d,(r%d) ea=%lux\n", em->ur->pc, em->name, rd, rb, ea); - } - *eap = (void*)ea; - *rdp = rd; -} - -static void -lfs(Emreg *em, ulong ir) -{ - void *ea; - int rd; - - em->name = "lfs"; - fpeairr(em, ir, &ea, &rd); - fpis2i(&FR(rd), (void*)ea); -} - -static void -lfsx(Emreg *em, ulong ir) -{ - void *ea; - int rd; - - em->name = "lfsx"; - fpearrr(em, ir, ((ir>>1)&0x3FF)==567, &ea, &rd); - fpis2i(&FR(rd), (void*)ea); -} - -static void -lfd(Emreg *em, ulong ir) -{ - void *ea; - int rd; - - em->name = "lfd"; - fpeairr(em, ir, &ea, &rd); - fpid2i(&FR(rd), (void*)ea); -} - -static void -lfdx(Emreg *em, ulong ir) -{ - void *ea; - int rd; - - em->name = "lfdx"; - fpearrr(em, ir, ((ir>>1)&0x3FF)==631, &ea, &rd); - fpid2i(&FR(rd), (void*)ea); -} - -static void -stfs(Emreg *em, ulong ir) -{ - void *ea; - int rd; - Internal tmp; - - em->name = "stfs"; - fpeairr(em, ir, &ea, &rd); - tmp = FR(rd); - fpii2s(ea, &tmp); -} - -static void -stfsx(Emreg *em, ulong ir) -{ - void *ea; - int rd; - Internal tmp; - - em->name = "stfsx"; - fpearrr(em, ir, getxo(ir)==695, &ea, &rd); - tmp = FR(rd); - fpii2s(ea, &tmp); -} - -static void -stfd(Emreg *em, ulong ir) -{ - void *ea; - int rd; - Internal tmp; - - em->name = "stfd"; - fpeairr(em, ir, &ea, &rd); - tmp = FR(rd); - fpii2d(ea, &tmp); -} - -static void -stfdx(Emreg *em, ulong ir) -{ - void *ea; - int rd; - Internal tmp; - - em->name = "stfdx"; - fpearrr(em, ir, ((ir>>1)&0x3FF)==759, &ea, &rd); - tmp = FR(rd); - fpii2d(ea, &tmp); -} - -static void -mcrfs(Emreg *em, ulong ir) -{ - int rd, ra, rb; - static ulong fpscr0[] ={ - FPS_FX|FPS_OX, - FPS_UX|FPS_ZX|FPS_XX|FPS_VXSNAN, - FPS_VXISI|FPS_VXIDI|FPS_VXZDZ|FPS_VXIMZ, - FPS_VXVC, - 0, - FPS_VXCVI, - }; - - getarrr(ir); - if(rb || ra&3 || rd&3) - unimp(em, ir); - ra >>= 2; - rd >>= 2; - em->ur->cr = (em->ur->cr & ~mkCR(rd, 0xF)) | mkCR(rd, getCR(ra, em->ufp->fpscr)); - em->ufp->fpscr &= ~fpscr0[ra]; - if(fpemudebug) - print("%8.8lux mcrfs\tcrf%d,crf%d\n", em->ur->pc, rd, ra); -} - -static void -mffs(Emreg *em, ulong ir) -{ - int rd, ra, rb; - Double dw; - - getarrr(ir); - if(ra || rb) - unimp(em, ir); - dw.h = 0; - dw.l = ((uvlong)0xFFF8000L<<16)|em->ufp->fpscr; - fpid2i(&FR(rd), &dw); - /* it's anyone's guess how CR1 should be set when ir&1 */ - em->ur->cr &= ~mkCR(1, 0xE); /* leave SO, reset others */ - if(fpemudebug) - print("%8.8lux mffs%s\tfr%d\n", em->ur->pc, ir&1?".":"", rd); -} - -static void -mtfsb1(Emreg *em, ulong ir) -{ - int rd, ra, rb; - - getarrr(ir); - if(ra || rb) - unimp(em, ir); - em->ufp->fpscr |= (1L << (31-rd)); - /* BUG: should set summary bits */ - if(ir & 1) - em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */ - if(fpemudebug) - print("%8.8lux mtfsb1%s\tfr%d\n", em->ur->pc, ir&1?".":"", rd); -} - -static void -mtfsb0(Emreg *em, ulong ir) -{ - int rd, ra, rb; - - getarrr(ir); - if(ra || rb) - unimp(em, ir); - em->ufp->fpscr &= ~(1L << (31-rd)); - if(ir & 1) - em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */ - if(fpemudebug) - print("%8.8lux mtfsb0%s\tfr%d\n", em->ur->pc, ir&1?".":"", rd); -} - -static void -mtfsf(Emreg *em, ulong ir) -{ - int fm, rb, i; - ulong v; - Internal b; - Double db; - - if(ir & ((1L << 25)|(1L << 16))) - unimp(em, ir); - rb = (ir >> 11) & 0x1F; - fm = (ir >> 17) & 0xFF; - b = FR(rb); - fpii2d(&db, &b); /* reconstruct hi/lo format to recover low word */ - v = db.l; - for(i=0; i<8; i++) - if(fm & (1 << (7-i))) - em->ufp->fpscr = (em->ufp->fpscr & ~mkCR(i, 0xF)) | mkCR(i, getCR(i, v)); - /* BUG: should set FEX and VX `according to the usual rule' */ - if(ir & 1) - em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */ - if(fpemudebug) - print("%8.8lux mtfsf%s\t#%.2x,fr%d\n", em->ur->pc, ir&1?".":"", fm, rb); -} - -static void -mtfsfi(Emreg *em, ulong ir) -{ - int imm, rd; - - if(ir & ((0x7F << 16)|(1L << 11))) - unimp(em, ir); - rd = (ir >> 23) & 0xF; - imm = (ir >> 12) & 0xF; - em->ufp->fpscr = (em->ufp->fpscr & ~mkCR(rd, 0xF)) | mkCR(rd, imm); - /* BUG: should set FEX and VX `according to the usual rule' */ - if(ir & 1) - em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */ - if(fpemudebug) - print("%8.8lux mtfsfi%s\tcrf%d,#%x\n", em->ur->pc, ir&1?".":"", rd, imm); -} - -static void -fcmp(Emreg *em, ulong ir) -{ - int fc, rd, ra, rb, sig, i; - - getarrr(ir); - if(rd & 3) - unimp(em, ir); - rd >>= 2; - sig = 0; - switch(getxo(ir)) { - default: - unimp(em, ir); - case 32: - if(fpemudebug) - print("%8.8lux fcmpo\tcr%d,f%d,f%d\n", em->ur->pc, rd, ra, rb); - sig = 1; - break; - case 0: - if(fpemudebug) - print("%8.8lux fcmpu\tcr%d,f%d,f%d\n", em->ur->pc, rd, ra, rb); - break; - } - if(IsWeird(&FR(ra)) || IsWeird(&FR(rb))) { - if(sig){ - ; /* BUG: should trap if not masked ... */ - } - fc = CRFU; - } else { - i = fpicmp(&FR(ra), &FR(rb)); - if(i > 0) - fc = CRGT; - else if(i == 0) - fc = CREQ; - else - fc = CRLT; - } - fc >>= 28; - em->ur->cr = (em->ur->cr & ~mkCR(rd,~0)) | mkCR(rd, fc); - em->ufp->fpscr = (em->ufp->fpscr & ~0xF800) | (fc<<11); - /* BUG: update FX, VXSNAN, VXVC */ -} - -static void -fariths(Emreg *em, ulong ir) -{ - int rd, ra, rb, rc, fmt; - char *cc, *n; - ulong fpscr; - Internal *d; - - fmt = 0; - rc = (ir>>6)&0x1F; - getarrr(ir); - d = &FR(rd); - switch(getxo(ir)&0x1F) { /* partial XO decode */ - case 22: /* fsqrts */ - case 24: /* fres */ - default: - unimp(em, ir); - return; - case 18: - if(IsZero(&FR(rb))) { - em->ufp->fpscr |= FPS_ZX | FPS_FX; - error("sys: fp: zero divide"); - } - fdiv(em, d, ra, rb); - n = "fdivs"; - break; - case 20: - fsub(em, d, ra, rb); - n = "fsubs"; - break; - case 21: - fadd(em, d, ra, rb); - n = "fadds"; - break; - case 25: - fmul(em, d, ra, rc); - rb = rc; - n = "fmuls"; - break; - case 28: - fmsub(em, d, ra, rc, rb); - fmt = 2; - n = "fmsubs"; - break; - case 29: - fmadd(em, d, ra, rc, rb); - fmt = 2; - n = "fmadds"; - break; - case 30: - fmsub(em, d, ra, rc, rb); - d->s ^= 1; - fmt = 2; - n = "fnmsubs"; - break; - case 31: - fmadd(em, d, ra, rc, rb); - d->s ^= 1; - fmt = 2; - n = "fnmadds"; - break; - } - if(fmt==1 && ra) - unimp(em, ir); - fpscr = setfpscr(em); - setfpcc(em, rd); - cc = ""; - if(ir & 1) { - cc = "."; - em->ur->cr = (em->ur->cr & ~mkCR(1, ~0)) | mkCR(1, (fpscr>>28)); - } - if(fpemudebug) { - switch(fmt) { - case 0: - print("%8.8lux %s%s\tfr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rb); - break; - case 1: - print("%8.8lux %s%s\tfr%d,fr%d\n", em->ur->pc, n, cc, rd, rb); - break; - case 2: - print("%8.8lux %s%s\tfr%d,fr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rc, rb); - break; - } - } -} - -static void -farith(Emreg *em, ulong ir) -{ - Word w; - Double dv; - int rd, ra, rb, rc, fmt; - char *cc, *n; - ulong fpscr; - int nocc; - Internal *d; - - fmt = 0; - nocc = 0; - rc = (ir>>6)&0x1F; - getarrr(ir); - d = &FR(rd); - switch(getxo(ir)&0x1F) { /* partial XO decode */ - case 22: /* frsqrt */ - case 23: /* fsel */ - case 26: /* fsqrte */ - default: - unimp(em, ir); - return; - case 12: /* frsp */ - *d = FR(rb); /* BUG: doesn't round to single precision */ - fmt = 1; - n = "frsp"; - break; - case 14: /* fctiw */ /* BUG: ignores rounding mode */ - case 15: /* fctiwz */ - fpii2w(&w, &FR(rb)); - dv.h = 0; - dv.l = w; - fpid2i(d, &dv); - fmt = 1; - nocc = 1; - n = "fctiw"; - break; - case 18: - if(IsZero(&FR(rb))) { - em->ufp->fpscr |= FPS_ZX | FPS_FX; - error("sys: fp: zero divide"); - } - fdiv(em, d, ra, rb); - n = "fdiv"; - break; - case 20: - fsub(em, d, ra, rb); - n = "fsub"; - break; - case 21: - fadd(em, d, ra, rb); - n = "fadd"; - break; - case 25: - fmul(em, d, ra, rc); - rb = rc; - n = "fmul"; - break; - case 28: - fmsub(em, d, ra, rc, rb); - fmt = 2; - n = "fmsub"; - break; - case 29: - fmadd(em, d, ra, rc, rb); - fmt = 2; - n = "fmadd"; - break; - case 30: - fmsub(em, d, ra, rc, rb); - d->s ^= 1; - fmt = 2; - n = "fnmsub"; - break; - case 31: - fmadd(em, d, ra, rc, rb); - d->s ^= 1; - fmt = 2; - n = "fnmadd"; - break; - } - if(fmt==1 && ra) - unimp(em, ir); - fpscr = setfpscr(em); - if(nocc == 0) - setfpcc(em, rd); - cc = ""; - if(ir & 1) { - cc = "."; - em->ur->cr = (em->ur->cr & ~mkCR(1, ~0)) | mkCR(1, (fpscr>>28)); - } - if(fpemudebug) { - switch(fmt) { - case 0: - print("%8.8lux %s%s\tfr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rb); - break; - case 1: - print("%8.8lux %s%s\tfr%d,fr%d\n", em->ur->pc, n, cc, rd, rb); - break; - case 2: - print("%8.8lux %s%s\tfr%d,fr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rc, rb); - break; - } - } -} - -static void -farith2(Emreg *em, ulong ir) -{ - int rd, ra, rb; - char *cc, *n; - ulong fpscr; - Internal *d, *b; - - getarrr(ir); - if(ra) - unimp(em, ir); - d = &FR(rd); - b = &FR(rb); - switch(getxo(ir)) { /* full XO decode */ - default: - unimp(em, ir); - case 40: - *d = *b; - d->s ^= 1; - n = "fneg"; - break; - case 72: - *d = *b; - n = "fmr"; - break; - case 136: - *d = *b; - d->s = 1; - n = "fnabs"; - break; - case 264: - *d = *b; - d->s = 0; - n = "fabs"; - break; - } - fpscr = setfpscr(em); - setfpcc(em, rd); - cc = ""; - if(ir & 1) { - cc = "."; - em->ur->cr = (em->ur->cr & ~mkCR(1, ~0)) | mkCR(1, (fpscr>>28)); - } - if(fpemudebug) - print("%8.8lux %s%s\tfr%d,fr%d\n", em->ur->pc, n, cc, rd, rb); -} - -static ulong -setfpscr(Emreg *em) -{ - ulong fps, fpscr; - - fps = 0; /* BUG: getfsr() */ - fpscr = em->ufp->fpscr; - if(fps & FPAOVFL) - fpscr |= FPS_OX; - if(fps & FPAINEX) - fpscr |= FPS_XX; - if(fps & FPAUNFL) - fpscr |= FPS_UX; - if(fps & FPAZDIV) - fpscr |= FPS_ZX; - if(fpscr != em->ufp->fpscr) { - fpscr |= FPS_FX; - em->ufp->fpscr = fpscr; - } - return fpscr; -} - -static void -setfpcc(Emreg *em, int r) -{ - int c; - Internal *d; - - d = &FR(r); - c = 0; - if(IsZero(d)) - c |= 2; - else if(d->s == 1) - c |= 4; - else - c |= 8; - if(IsNaN(d)) - c |= 1; - em->ufp->fpscr = (em->ufp->fpscr & ~0xF800) | (0<<15) | (c<<11); /* unsure about class bit */ -} - -static uchar op63flag[32] = { -[12] 1, [14] 1, [15] 1, [18] 1, [20] 1, [21] 1, [22] 1, -[23] 1, [25] 1, [26] 1, [28] 1, [29] 1, [30] 1, [31] 1, -}; - -/* - * returns the number of FP instructions emulated - */ -int -fpipower(Ureg *ur) -{ - ulong op; - int xo; - Emreg emreg, *em; - FPenv *ufp; - int n; - - ufp = &up->env->fpu; /* because all the state is in Osenv, it need not be saved/restored */ - em = &emreg; - em->ur = ur; - em->fr = ufp->emreg; - em->ufp = ufp; - em->name = nil; - if(em->ufp->fpistate != FPACTIVE) { - em->ufp->fpistate = FPACTIVE; - em->ufp->fpscr = 0; /* TO DO */ - for(n = 0; n < nelem(fpreginit); n++) - FR(31-n) = fpreginit[n]; - } - for(n=0;;n++){ - op = getulong(ur->pc); - em->ir = op; - if(fpemudebug > 1) - print("%8.8lux %8.8lux: ", ur->pc, op); - switch(op>>26){ - default: - return n; - case 48: /* lfs */ - case 49: /* lfsu */ - lfs(em, op); - break; - case 50: /* lfd */ - case 51: /* lfdu */ - lfd(em, op); - break; - case 52: /* stfs */ - case 53: /* stfsu */ - stfs(em, op); - break; - case 54: /* stfd */ - case 55: /* stfdu */ - stfd(em, op); - break; - case 31: /* indexed load/store */ - xo = getxo(op); - if((xo & 0x300) != 0x200) - return n; - switch(xo){ - default: - return n; - case 535: /* lfsx */ - case 567: /* lfsux */ - lfsx(em, op); - break; - case 599: /* lfdx */ - case 631: /* lfdux */ - lfdx(em, op); - break; - case 663: /* stfsx */ - case 695: /* stfsux */ - stfsx(em, op); - break; - case 727: /* stfdx */ - case 759: /* stfdux */ - stfdx(em, op); - break; - } - break; - case 63: /* double precision */ - xo = getxo(op); - if(op63flag[xo & 0x1F]){ - farith(em, op); - break; - } - switch(xo){ - default: - return n; - case 0: /* fcmpu */ - case 32: /* fcmpo */ - fcmp(em, op); - break; - case 40: /* fneg */ - case 72: /* fmr */ - case 136: /* fnabs */ - case 264: /* fabs */ - farith2(em, op); - break; - case 38: - mtfsb1(em, op); - break; - case 64: - mcrfs(em, op); - break; - case 70: - mtfsb0(em, op); - break; - case 134: - mtfsfi(em, op); - break; - case 583: - mffs(em, op); - break; - case 711: - mtfsf(em, op); - break; - } - break; - case 59: /* single precision */ - fariths(em, op); - break; - } - ur->pc += 4; - if(anyhigher()) - sched(); - } - return n; -} - -/* -50: lfd frD,d(rA) -51: lfdu frD,d(rA) -31,631: lfdux frD,rA,rB -31,599: lfdx frD,rA,rB -48: lfs frD,d(rA) -49: lfsu frD,d(rA) -31,567: lfsux frD,rA,rB -31,535: lfsx frD,rA,rB - -54: stfd frS,d(rA) -55: stfdu frS,d(rA) -31,759: stfdux frS,rA,rB -31,727: stfdx frS,rA,rB -52: stfs frS,d(rA) -53: stfsu frS,d(rA) -31,695: stfsux frS,rA,rB -31,663: stfsx frS,rA,rB - -63,64: mcrfs crfD,crfS -63,583: mffs[.] frD -63,70: mtfsb0[.] crbD -63,38: mtfsb1[.] crbD -63,711: mtfsf[.] FM,frB -63,134: mtfsfi[.] crfD,IMM -*/ - -/* -float to int: - FMOVD g+0(SB),F1 - FCTIWZ F1,F4 - FMOVD F4,.rathole+0(SB) - MOVW .rathole+4(SB),R7 - MOVW R7,l+0(SB) -*/ - -/* -int to float: - MOVW $1127219200,R9 - MOVW l+0(SB),R7 - MOVW R9,.rathole+0(SB) - XOR $-2147483648,R7,R6 - MOVW R6,.rathole+4(SB) - FMOVD .rathole+0(SB),F0 - FSUB F27,F0 - -unsigned to float: - MOVW ul+0(SB),R5 - MOVW R9,.rathole+0(SB) - XOR $-2147483648,R5,R4 - MOVW R4,.rathole+4(SB) - FMOVD .rathole+0(SB),F3 - FSUB F27,F3 - FCMPU F3,F28 - BGE ,3(PC) - FMOVD $4.29496729600000000e+09,F2 - FADD F2,F3 - FMOVD F3,g+0(SB) -*/ diff --git a/os/cerf405/gpio.c b/os/cerf405/gpio.c deleted file mode 100644 index a4821b1c..00000000 --- a/os/cerf405/gpio.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "u.h" -#include "mem.h" -#include "../port/lib.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -#define GPIOREGS ((Gpioregs*)KADDR(PHYSGPIO)) - -static ulong gpioreserved; -static Lock gpiolock; - -void -gpioreserve(ulong mask) -{ - ilock(&gpiolock); - if(gpioreserved & mask) - panic("gpioreserve: duplicate use of 0x%.8lux", gpioreserved & mask); - gpioreserved |= mask; - iunlock(&gpiolock); -} - -/* - * expand each of the bottom 16 bits into a two bit field - * with the bit as low order bit in the field - */ -static ulong -inflate(ulong m) -{ - m = ((m & 0xFF00) << 8) | (m & 0x00FF); - m = ((m << 4) | m) & 0x0F0F0F0F; - m = ((m << 2) | m) & 0x33333333; - return ((m << 1) | m) & 0x55555555; -} - -/* - * set tcr, osr[hl], tsr[hl], odr, isr1[hl] for gpio bits in m, - * following the configuration bits in cfg. when setting - * a gpio pin as output, set the right output value in OR first. - */ -void -gpioconfig(ulong m, ulong cfg) -{ - Gpioregs *g; - ulong h, hm, l, lm; - - h = inflate(m>>16); - hm = h | (h<<1); - l = inflate(m); - lm = l | (l<<1); - ilock(&gpiolock); - g = GPIOREGS; - /* - * tsr has a setting ``Alt1 three-state source'' but - * table 23-7 sets it to zero (use TCR) and sets TCR. - * thus, it seems never really to be needed. - */ - g->tsrh &= ~hm; - g->tsrl &= ~lm; - /* always select pin input (don't care for outputs) */ - g->isr1h = (g->isr1h & ~hm) | h; - g->isr1l = (g->isr1l & ~lm) | l; - if(cfg & Gpio_Alt1){ /* table 23-7 */ - g->osrh = (g->osrh & ~hm) | h; /* alt1 source */ - g->osrl = (g->osrl & ~lm) | l; - }else{ - g->osrh &= ~hm; /* GPIO_OR source */ - g->osrl &= ~lm; - } - if(cfg & Gpio_OD) - g->odr |= m; - else - g->odr &= ~m; - if(cfg & Gpio_in || cfg & Gpio_Tri) - g->tcr &= ~m; - else - g->tcr |= m; - iunlock(&gpiolock); -} - -ulong -gpioget(ulong mask) -{ - return GPIOREGS->ir & mask; -} - -void -gpioset(ulong mask, ulong out) -{ - Gpioregs *g; - - ilock(&gpiolock); - g = GPIOREGS; - g->or = (g->or & ~mask) | (out & mask); - iunlock(&gpiolock); -} - -void -gpiorelease(ulong mask) -{ - ilock(&gpiolock); - if((gpioreserved & mask) != mask) - panic("gpiorelease: unexpected release of 0x%.8lux", ~gpioreserved & mask); - gpioreserved &= ~mask; - iunlock(&gpiolock); -} diff --git a/os/cerf405/iic.c b/os/cerf405/iic.c deleted file mode 100644 index 22d5e51f..00000000 --- a/os/cerf405/iic.c +++ /dev/null @@ -1,605 +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" - -/* - * basic read/write interface to 4xx IIC bus (master mode) - * ``referred to as IIC to distinguish it from the Phillips IâČC bus [itself]'' - * - * TO DO: - * power management ref count - * power up/power down on timer? - */ - -typedef struct Ctlr Ctlr; -typedef struct IICregs IICregs; - -struct IICregs { - uchar mdbuf; /* master data buffer */ - uchar rsvd0; - uchar sdbuf; /* slave data buffer */ - uchar rsvd1; - uchar lmadr; /* low master address */ - uchar hmadr; /* high master address */ - uchar cntl; /* control */ - uchar mdcntl; /* mode control */ - uchar sts; /* status */ - uchar extsts; /* extended status */ - uchar lsadr; /* low slave address */ - uchar hsadr; /* high slave address */ - uchar clkdiv; /* clock divide */ - uchar intrmsk; /* interrupt mask */ - uchar xfrcnt; /* transfer count */ - uchar xtcntlss; /* extended control and slave status */ - uchar directcntl; /* direct control */ -}; - -enum { - /* cntl */ - Hmt= 1<<7, /* halt master transfer */ - Amd10= 1<<6, /* =0, 7-bit; =1, 10-bit addressing */ - /* 5,4: two bit transfer count (n-1)&3 bytes */ - Rpst= 1<<3, /* =0, normal start; =1, repeated Start, transfer should be followed by another start */ - Cht= 1<<2, /* chain transfer; not the last */ - Write= 0<<1, /* transfer is a write */ - Read= 1<<1, /* transfer is a read */ - Pt= 1<<0, /* =0, most recent transfer complete; =1, start transfer if bus free */ - - /* mdcntl */ - Fsdb= 1<<7, /* flush slave data buffer */ - Fmdb= 1<<6, /* flush master data buffer */ - Fsm= 1<<4, /* =0, 100 kHz standard mode; =1, 400 Khz fast mode */ - Esm= 1<<3, /* enable slave mode */ - Eint= 1<<2, /* enable interrupt */ - Eubs= 1<<1, /* exit unknown bus state */ - Hscl= 1<<0, /* hold IIC serial clock low */ - - /* sts */ - Sss= 1<<7, /* slave status set (slave operation in progress) */ - Slpr= 1<<6, /* sleep mode */ - Mdbs= 1<<5, /* master data buffer has data */ - Mdbf= 1<<4, /* master data buffer is full */ - Scmp= 1<<3, /* stop complete */ - Err= 1<<2, /* error set in extsts */ - Irqa= 1<<1, /* IRQ active */ - /* Pt as above */ - - /* extsts */ - Irqp= 1<<7, /* IRQ pending */ - Bcs= 7<<4, - Bcs_ssel= 1<<4, /* slave-selected state */ - Bcs_sio= 2<<4, /* slave transfer state */ - Bcs_mio= 3<<4, /* master transfer state */ - Bcs_free= 4<<4, /* bus is free */ - Bcs_busy= 5<<4, /* bus is busy */ - Bcs_gok= 6<<4, /* unknown state */ - Irqd= 1<<3, /* IRQ on deck */ - La= 1<<2, /* lost arbitration */ - Ict= 1<<1, /* incomplete transfer */ - Xfra= 1<<0, /* transfer aborted */ - - /* intrmsk */ - Eirc= 1<<7, /* slave read complete */ - Eirs= 1<<6, /* slave read needs service */ - Eiwc= 1<<5, /* slave write complete */ - Eiws= 1<<4, /* slave write needs service */ - Eihe= 1<<3, /* halt executed */ - Eiic= 1<<2, /* incomplete transfer */ - Eita= 1<<1, /* transfer aborted */ - Eimtc= 1<<0, /* master transfer complete */ - - /* xtcntlss */ - Src= 1<<7, /* slave read complete; =1, NAK or Stop, or repeated Start ended op */ - Srs= 1<<6, /* slave read needs service */ - Swc= 1<<5, /* slave write complete */ - Sws= 1<<4, /* slave write needs service */ - Sdbd= 1<<3, /* slave buffer has data */ - Sdbf= 1<<2, /* slave buffer is full */ - Epi= 1<<1, /* enable pulsed IRQ on transfer aborted */ - Srst= 1<<0, /* soft reset */ - - /* directcntl */ - Sdac= 1<<3, /* SDA output */ - Scc= 1<<2, /* SCL output */ - Msda= 1<<1, /* SDA input */ - Msc= 1<<0, /* SCL input */ - - /* others */ - Rbit = 1<<0, /* bit in address byte denoting read */ - FIFOsize= 4, /* most to be written at once */ - - 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 = 100000, - I2Ctimeout = 125, /* msec (can change) */ - - 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 */ - IICregs* regs; /* hardware registers */ - - /* controller state (see below) */ - int status; - int phase; - Rendez r; - - /* transfer parameters */ - int cntl; /* everything but transfer length */ - int rdcount; /* requested read transfer size */ - Block* b; -}; - -enum { - /* Ctlr.state */ - Idle, - Done, - Failed, - Busy, - Halting, -}; - -static Ctlr iicctlr[1]; - -static void interrupt(Ureg*, void*); -static int readyxfer(Ctlr*); -static void rxstart(Ctlr*); -static void txstart(Ctlr*); -static void stopxfer(Ctlr*); -static void txoffset(Ctlr*, ulong, int); -static int idlectlr(Ctlr*); - -static void -iicdump(char *t, IICregs *iic) -{ - iprint("iic %s: lma=%.2ux hma=%.2ux im=%.2ux mdcntl=%.2ux sts=%.2ux ests=%.2ux cntl=%.2ux\n", - t, iic->lmadr, iic->hmadr, iic->intrmsk, iic->mdcntl, iic->sts, iic->extsts, iic->cntl); -} - -static void -initialise(IICregs *iic, int intrmsk) -{ - int d; - - d = (m->opbhz-1000000)/10000000; - if(d <= 0) - d = 1; /* just in case OPB freq < 20 Mhz */ - /* initialisation (see 22.4, p. 22-23) */ - iic->lmadr = 0; - iic->hmadr = 0; - iic->sts = Scmp|Irqa; - iic->extsts = Irqp | Irqd | La | Ict | Xfra; - iic->clkdiv = d; - iic->intrmsk = 0; /* see below */ - iic->xfrcnt = 0; - iic->xtcntlss = Src | Srs | Swc | Sws; - iic->mdcntl = Fsdb | Fmdb | Eubs; /* reset; standard mode */ - iic->cntl = 0; - eieio(); - iic->mdcntl = 0; - eieio(); - if(intrmsk){ - iic->intrmsk = intrmsk; - iic->mdcntl = Eint; - } -} - -/* - * called by the reset routine of any driver using the IIC - */ -void -i2csetup(int polling) -{ - IICregs *iic; - Ctlr *ctlr; - - ctlr = iicctlr; - ctlr->polling = polling; - iic = (IICregs*)KADDR(PHYSIIC); - ctlr->regs = iic; - if(!polling){ - if(ctlr->init == 0){ - initialise(iic, Eihe | Eiic | Eita | Eimtc); - ctlr->init = 1; - intrenable(VectorIIC, interrupt, iicctlr, BUSUNKNOWN, "iic"); - } - }else - initialise(iic, 0); -} - -static void -interrupt(Ureg*, void *arg) -{ - int sts, nb, ext, avail; - Ctlr *ctlr; - Block *b; - IICregs *iic; - - ctlr = arg; - iic = ctlr->regs; - if(0) - iicdump("intr", iic); - sts = iic->sts; - if(sts & Pt) - iprint("iic: unexpected status: %.2ux", iic->sts); - ext = iic->extsts; - if(sts & Mdbs) - nb = iic->xfrcnt & 7; - else - nb = 0; - eieio(); - iic->sts = sts; - if(sts & Err && (ext & (La|Xfra)) != 0) - iprint("iic: s=%.2ux es=%.2ux (IO)\n", sts, ext); - ctlr->status = ext; - switch(ctlr->phase){ - default: - iprint("iic: unexpected interrupt: p-%d s=%.2ux es=%.2ux\n", ctlr->phase, sts, ext); - break; - - case Halting: - ctlr->phase = Idle; - break; - - case Busy: - b = ctlr->b; - if(b == nil) - panic("iic: no buffer"); - if(ctlr->cntl & Read){ - /* copy data in from FIFO */ - avail = b->lim - b->wp; - if(nb > avail) - nb = avail; - while(--nb >= 0) - *b->wp++ = iic->mdbuf; /* ``the IIC interface handles the [FIFO] latency'' (22-4) */ - if(sts & Err || ctlr->rdcount <= 0){ - ctlr->phase = Done; - wakeup(&ctlr->r); - break; - } - rxstart(ctlr); - }else{ - /* account for data transmitted */ - if((b->rp += nb) > b->wp) - b->rp = b->wp; - if(sts & Err || BLEN(b) <= 0){ - ctlr->phase = Done; - wakeup(&ctlr->r); - break; - } - txstart(ctlr); - } - } -} - -static int -done(void *a) -{ - return ((Ctlr*)a)->phase < Busy; -} - -static int -i2cerror(char *s) -{ - DPRINT("iic error: %s\n", s); - if(up) - error(s); - /* no current process, don't call error */ - return -1; -} - -static char* -startxfer(I2Cdev *d, int op, void (*xfer)(Ctlr*), Block *b, int n, ulong offset) -{ - IICregs *iic; - Ctlr *ctlr; - int i, cntl, p, s; - - ctlr = iicctlr; - 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("iic: ctlr busy"); - cntl = op | Pt; - if(d->tenbit) - cntl |= Amd10; - ctlr->cntl = cntl; - ctlr->b = b; - ctlr->rdcount = n; - ctlr->phase = Busy; - iic = ctlr->regs; - if(d->tenbit){ - iic->hmadr = 0xF0 | (d->addr>>7); /* 2 higher bits of address, LSB don't care */ - iic->lmadr = d->addr; - }else{ - iic->hmadr = 0; - iic->lmadr = d->addr<<1; /* 7-bit address */ - } - if(d->salen) - txoffset(ctlr, offset, d->salen); - else - (*xfer)(ctlr); - iunlock(ctlr); - - /* wait for it */ - if(ctlr->polling){ - for(i=0; !done(ctlr); i++){ - delay(2); - interrupt(nil, ctlr); - } - }else - tsleep(&ctlr->r, done, 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 & (La|Xfra)){ /* CHECK; time out */ - if(s & La) - return "iic lost arbitration"; - if(s & Xfra) - return "iic transfer aborted"; - if(p != Done) - return "iic timed out"; - sprint(up->genbuf, "iic error: phase=%d estatus=%.2ux", 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, Write, txstart, 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, Read, rxstart, 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) -{ - IICregs *iic; - - iic = ctlr->regs; - iic->sts = Scmp | Err; - if((iic->sts & Pt) != 0){ - ctlr->phase = Failed; - wakeup(&ctlr->r); - return 0; - } - iic->mdcntl |= Fmdb; - return 1; -} - -/* - * start a master transfer to receive the next chunk of data - */ -static void -rxstart(Ctlr *ctlr) -{ - Block *b; - int cntl; - long nb; - - b = ctlr->b; - if(b == nil || (nb = ctlr->rdcount) <= 0){ - ctlr->phase = Done; - wakeup(&ctlr->r); - return; - } - if(!readyxfer(ctlr)) - return; - cntl = ctlr->cntl; - if(nb > FIFOsize){ - nb = FIFOsize; - cntl |= Cht; /* more to come */ - } - ctlr->rdcount -= nb; - ctlr->regs->cntl = cntl | ((nb-1)<<4); -} - -/* - * start a master transfer to send the next chunk of data - */ -static void -txstart(Ctlr *ctlr) -{ - Block *b; - int cntl, i; - long nb; - IICregs *iic; - - b = ctlr->b; - if(b == nil || (nb = BLEN(b)) <= 0){ - ctlr->phase = Done; - wakeup(&ctlr->r); - return; - } - if(!readyxfer(ctlr)) - return; - cntl = ctlr->cntl; - if(nb > FIFOsize){ - nb = FIFOsize; - cntl |= Cht; /* more to come */ - } - iic = ctlr->regs; - for(i=0; imdbuf = *b->rp++; /* load the FIFO */ - iic->cntl = cntl | ((nb-1)<<4); -} - -/* - * start a master transfer to send a sub-addressing offset; - * if subsequently receiving, use Rpst to cause the next transfer to include a Start; - * if subsequently sending, use Cht to chain the transfer without a Start. - */ -static void -txoffset(Ctlr *ctlr, ulong offset, int len) -{ - int i, cntl; - IICregs *iic; - - if(!readyxfer(ctlr)) - return; - iic = ctlr->regs; - for(i=len*8; (i -= 8) >= 0;) - iic->mdbuf = offset>>i; /* load offset bytes into FIFO */ - cntl = ctlr->cntl & Amd10; - if(ctlr->cntl & Read) - cntl |= Rpst; - else - cntl |= Cht; - iic->cntl = cntl | ((len-1)<<4) | Write | Pt; -} - -/* - * stop a transfer if one is in progress - */ -static void -stopxfer(Ctlr *ctlr) -{ - IICregs *iic; - int ext; - - iic = ctlr->regs; - ext = iic->extsts; - eieio(); - iic->sts = Scmp | Irqa; - eieio(); - if((iic->sts & Pt) == 0){ - ctlr->phase = Idle; - return; - } - if((ext & Bcs) == Bcs_mio && ctlr->phase != Halting){ - ctlr->phase = Halting; /* interrupt will clear the state */ - iic->cntl = Hmt; - } -} - -static int -idlectlr(Ctlr *ctlr) -{ - IICregs *iic; - - iic = ctlr->regs; - if((iic->extsts & Bcs) == Bcs_free){ - if((iic->sts & Pt) == 0){ - ctlr->phase = Idle; - return 1; - } - iprint("iic: bus free, ctlr busy: s=%.2ux es=%.2ux\n", iic->sts, iic->extsts); - } - /* hit it with the hammer, soft reset */ - iprint("iic: soft reset\n"); - iic->xtcntlss = Srst; - iunlock(ctlr); - delay(1); - ilock(ctlr); - initialise(iic, Eihe | Eiic | Eita | Eimtc); - ctlr->phase = Idle; - return (iic->extsts & Bcs) == Bcs_free && (iic->sts & Pt) == 0; -} diff --git a/os/cerf405/inb.s b/os/cerf405/inb.s deleted file mode 100644 index b664f85e..00000000 --- a/os/cerf405/inb.s +++ /dev/null @@ -1,127 +0,0 @@ -#include "mem.h" - -/* - * the tlb entry is configured for little-endian access, - * so byte-reversing loads aren't needed - */ - -#define ISAIO PHYSPCIIO0 - -#define BDNZ BC 16,0, - -TEXT inb(SB), $0 - OR $ISAIO, R3 - EIEIO - MOVBZ (R3), R3 - RETURN - -TEXT insb(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $1, R4 -insb1: - EIEIO - MOVBZ (R3), R7 - MOVBU R7, 1(R4) - BDNZ insb1 - RETURN - -TEXT outb(SB), $0 - MOVW v+4(FP), R4 - OR $ISAIO, R3 - EIEIO - MOVB R4, (R3) - RETURN - -TEXT outsb(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $1, R4 -outsb1: - EIEIO - MOVBZU 1(R4), R7 - MOVB R7, (R3) - BDNZ outsb1 - RETURN - -TEXT ins(SB), $0 - OR $ISAIO, R3 - EIEIO - MOVHZ (R3), R3 - RETURN - -TEXT inss(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $2, R4 -inss1: - EIEIO - MOVHZ (R3), R7 - MOVHU R7, 2(R4) - BDNZ inss1 - RETURN - -TEXT outs(SB), $0 - MOVW v+4(FP), R4 - OR $ISAIO, R3 - EIEIO - MOVH R4, (R3) - RETURN - -TEXT outss(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $2, R4 -outss1: - EIEIO - MOVHZU 2(R4), R7 - MOVH R7, (R3) - BDNZ outss1 - RETURN - -TEXT inl(SB), $0 - OR $ISAIO, R3 - EIEIO - MOVW (R3), R3 - RETURN - -TEXT insl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $4, R4 -insl1: - EIEIO - MOVW (R3), R7 - MOVWU R7, 4(R4) - BDNZ insl1 - RETURN - -TEXT outl(SB), $0 - MOVW v+4(FP), R4 - OR $ISAIO, R3 - EIEIO - MOVW R4, (R3) - RETURN - -TEXT outsl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $4, R4 -outsl1: - EIEIO - MOVWU 4(R4), R7 - MOVW R7, (R3) - BDNZ outsl1 - RETURN diff --git a/os/cerf405/io.h b/os/cerf405/io.h deleted file mode 100644 index 1f779dfc..00000000 --- a/os/cerf405/io.h +++ /dev/null @@ -1,301 +0,0 @@ -typedef struct BD BD; -typedef struct Ring Ring; -typedef struct MALdev MALdev; -typedef struct I2Cdev I2Cdev; - -enum -{ - /* 405EP UIC interrupt vectors (IBM bit numbering) */ - VectorUIC= 0, - VectorUART0=VectorUIC, - VectorUART1, - VectorIIC, - VectorPCIECW, - VectorRsvd1, - VectorDMA0, - VectorDMA1, - VectorDMA2, - VectorDMA3, - VectorEtherwake, - VectorMALSERR, - VectorMALTXEOB, - VectorMALRXEOB, - VectorMALTXDE, - VectorMALRXDE, - VectorEMAC0, - VectorPCISERR, - VectorEMAC1, - VectorPCIPM, - VectorGPT0, - VectorGPT1, - VectorGPT2, - VectorGPT3, - VectorGPT4, - /* 1 reserved */ - VectorIRQ= VectorUIC+25, /* IRQ0 to IRQ6 */ - MaxVector= VectorIRQ+7, - - /* some flags to change polarity and sensitivity */ - IRQmask= 0xFF, /* actual vector address */ - IRQactivelow= 1<<8, - IRQedge= 1<<9, - IRQcritical= 1<<10, -}; - -/* - * these are defined to keep the interface compatible with other - * architectures, but only BUSUNKNOWN is currently used - */ -#define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8)) -#define BUSFNO(tbdf) (((tbdf)>>8)&0x07) -#define BUSDNO(tbdf) (((tbdf)>>11)&0x1F) -#define BUSBNO(tbdf) (((tbdf)>>16)&0xFF) -#define BUSTYPE(tbdf) ((tbdf)>>24) -#define BUSBDF(tbdf) ((tbdf)&0x00FFFF00) -#define BUSUNKNOWN (-1) - -enum { - BusOPB, - BusPLB, - BusPCI, - MaxBus -}; - -/* - * MAL Buffer Descriptors and IO Rings - */ - -struct BD { - ushort status; - ushort length; - ulong addr; -}; -#define MAXIORING 256 /* hardware limit to ring size */ -#define BDBUFLIM (4096-16) /* no MAL buffer larger than this */ - -BD* bdalloc(ulong); -void bdfree(BD*, int); -void dumpbd(char*, BD*, int); - -enum { - /* Rx BDs, bits common to all protocols */ - BDEmpty= 1<<15, - BDWrap= 1<<14, /* end of ring */ - BDContin= 1<<13, /* continuous mode */ - BDLast= 1<<12, /* last buffer in current packet */ - BDFirst= 1<<11, /* first buffer in current packet (set by MAL) */ - BDInt= 1<<10, /* interrupt when done */ - - /* Tx BDs */ - BDReady= 1<<15, /* ready to transmit; set by driver, cleared by MAL */ - /* BDWrap, BDInt, BDLast as above */ -}; - -struct Ring { - BD* rdr; /* receive descriptor ring */ - Block** rxb; /* receive ring buffers */ - int rdrx; /* index into rdr */ - int nrdre; /* length of rdr */ - - BD* tdr; /* transmit descriptor ring */ - Block** txb; /* transmit ring buffers */ - int tdrh; /* host index into tdr */ - int tdri; /* interface index into tdr */ - int ntdre; /* length of tdr */ - int ntq; /* pending transmit requests */ -}; - -#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)) - -/* - * one per mal channel - */ -typedef struct Mal Mal; -struct Mal { - int n; - int len; - int tx; - ulong mask; - - void* arg; - void (*interrupt)(Ureg*, void*); -}; - -Mal* malchannel(int, int, void (*)(Ureg*, void*), void*); -void maltxreset(Mal*); -void maltxinit(Mal*, Ring*); -void maltxenable(Mal*); -void malrxreset(Mal*); -void malrxinit(Mal*, Ring*, ulong); -void malrxenable(Mal*); -void ioringreserve(int, ulong, int, ulong); -int ioringinit(Ring*, int, int); - -typedef struct Gpioregs Gpioregs; -struct Gpioregs { - ulong or; /* output register */ - ulong tcr; /* tristate control */ - ulong osrh; /* output select high (0-15) */ - ulong osrl; /* output select low (16-31) */ - ulong tsrh; /* tristate select high (0-15) */ - ulong tsrl; /* tristate select low (16-31) */ - ulong odr; /* open drain */ - ulong ir; /* input */ - ulong rr1; /* receive register */ - ulong pad[3]; - ulong isr1h; /* input select 1 high (0-15) */ - ulong isr1l; /* input select 1 low (16-31) */ -}; - -enum { - /* software configuration bits for gpioconfig */ - Gpio_Alt1= 1<<0, /* implies specific settings of all the others, but include in or out */ - Gpio_OD= 1<<1, - Gpio_Tri= 1<<2, - Gpio_in= 1<<4, - Gpio_out= 1<<5, -}; - -void gpioreserve(ulong); -void gpioconfig(ulong, ulong); -ulong gpioget(ulong); -void gpioset(ulong, ulong); -void gpiorelease(ulong); - -/* - * 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); - -/* - * PCI support code. - */ -enum { /* type 0 and type 1 pre-defined header */ - PciVID = 0x00, /* vendor ID */ - PciDID = 0x02, /* device ID */ - PciPCR = 0x04, /* command */ - PciPSR = 0x06, /* status */ - PciRID = 0x08, /* revision ID */ - PciCCRp = 0x09, /* programming interface class code */ - PciCCRu = 0x0A, /* sub-class code */ - PciCCRb = 0x0B, /* base class code */ - PciCLS = 0x0C, /* cache line size */ - PciLTR = 0x0D, /* latency timer */ - PciHDT = 0x0E, /* header type */ - PciBST = 0x0F, /* BIST */ - - PciBAR0 = 0x10, /* base address */ - PciBAR1 = 0x14, - - PciINTL = 0x3C, /* interrupt line */ - PciINTP = 0x3D, /* interrupt pin */ -}; - -enum { /* type 0 pre-defined header */ - PciBAR2 = 0x18, - PciBAR3 = 0x1C, - PciBAR4 = 0x20, - PciBAR5 = 0x24, - PciCIS = 0x28, /* cardbus CIS pointer */ - PciSVID = 0x2C, /* subsystem vendor ID */ - PciSID = 0x2E, /* cardbus CIS pointer */ - PciEBAR0 = 0x30, /* expansion ROM base address */ - PciMGNT = 0x3E, /* burst period length */ - PciMLT = 0x3F, /* maximum latency between bursts */ -}; - -enum { /* type 1 pre-defined header */ - PciPBN = 0x18, /* primary bus number */ - PciSBN = 0x19, /* secondary bus number */ - PciUBN = 0x1A, /* subordinate bus number */ - PciSLTR = 0x1B, /* secondary latency timer */ - PciIBR = 0x1C, /* I/O base */ - PciILR = 0x1D, /* I/O limit */ - PciSPSR = 0x1E, /* secondary status */ - PciMBR = 0x20, /* memory base */ - PciMLR = 0x22, /* memory limit */ - PciPMBR = 0x24, /* prefetchable memory base */ - PciPMLR = 0x26, /* prefetchable memory limit */ - PciPUBR = 0x28, /* prefetchable base upper 32 bits */ - PciPULR = 0x2C, /* prefetchable limit upper 32 bits */ - PciIUBR = 0x30, /* I/O base upper 16 bits */ - PciIULR = 0x32, /* I/O limit upper 16 bits */ - PciEBAR1 = 0x28, /* expansion ROM base address */ - PciBCR = 0x3E, /* bridge control register */ -}; - -enum { /* type 2 pre-defined header */ - PciCBExCA = 0x10, - PciCBSPSR = 0x16, - PciCBPBN = 0x18, /* primary bus number */ - PciCBSBN = 0x19, /* secondary bus number */ - PciCBUBN = 0x1A, /* subordinate bus number */ - PciCBSLTR = 0x1B, /* secondary latency timer */ - PciCBMBR0 = 0x1C, - PciCBMLR0 = 0x20, - PciCBMBR1 = 0x24, - PciCBMLR1 = 0x28, - PciCBIBR0 = 0x2C, /* I/O base */ - PciCBILR0 = 0x30, /* I/O limit */ - PciCBIBR1 = 0x34, /* I/O base */ - PciCBILR1 = 0x38, /* I/O limit */ - PciCBSVID = 0x40, /* subsystem vendor ID */ - PciCBSID = 0x42, /* subsystem ID */ - PciCBLMBAR = 0x44, /* legacy mode base address */ -}; - -typedef struct Pcisiz Pcisiz; -struct Pcisiz -{ - Pcidev* dev; - int siz; - int bar; -}; - -typedef struct Pcidev Pcidev; -struct Pcidev -{ - int tbdf; /* type+bus+device+function */ - ushort vid; /* vendor ID */ - ushort did; /* device ID */ - - uchar rid; - uchar ccrp; - uchar ccru; - uchar ccrb; - - struct { - ulong bar; /* base address */ - int size; - } mem[6]; - - struct { - ulong bar; - int size; - } rom; - uchar intl; /* interrupt line */ - - Pcidev* list; - Pcidev* link; /* next device on this bno */ - - Pcidev* bridge; /* down a bus */ - struct { - ulong bar; - int size; - } ioa, mema; - ulong pcr; -}; - -#define PCIWINDOW 0x80000000 -#define PCIWADDR(va) (PADDR(va)+PCIWINDOW) diff --git a/os/cerf405/l.s b/os/cerf405/l.s deleted file mode 100644 index 28990ef6..00000000 --- a/os/cerf405/l.s +++ /dev/null @@ -1,795 +0,0 @@ -#include "mem.h" - -#define MB (1024*1024) - -/* - * common ppc special purpose registers - */ -#define DSISR 18 -#define SRR0 26 /* Saved Registers (exception) */ -#define SRR1 27 -#define SPRG0 272 /* Supervisor Private Registers */ -#define SPRG1 273 -#define SPRG2 274 -#define SPRG3 275 -#define TBRU 269 /* Time base Upper/Lower (Reading) */ -#define TBRL 268 -#define TBWU 285 /* Time base Upper/Lower (Writing) */ -#define TBWL 284 -#define PVR 287 /* Processor Version */ - -/* - * 4xx-specific special purpose registers of interest here - */ -#define ICCR 1019 /* instruction cache control */ -#define DCCR 1018 /* data cache control */ -#define DBCR0 1010 /* debug control register 0 */ -#define DCWR 964 /* data cache write-through */ -#define PID 945 /* TLB process ID */ -#define CCR0 947 /* core configuration register 0 */ -#define SLER 955 /* storage little-endian */ -#define SU0R 956 /* storage user-defined 0 */ -#define SRR2 990 -#define SRR3 991 -/* SPRGn up to 7, if needed, on the 400 series */ -#define DEAR 961 /* data error address */ -#define ESR 980 /* exception syndrome */ -#define EVPR 982 /* exception vector prefix */ -#define PIT 987 /* interval timer */ -#define SGR 953 /* storage guarded */ -#define TCR 986 /* timer control */ -#define TSR 984 /* timer status */ -#define ZPR 944 /* zone protection */ - -/* - * 4xx-specific(?) device control registers - */ -#define OCM0_DSCNTL 0x1B /* OCM data-side control register */ - -/* use of SPRG registers in save/restore */ -#define SAVER0 SPRG0 -#define SAVER1 SPRG1 -#define SAVELR SPRG2 -#define SAVEXX SPRG3 - -/* special instruction definitions */ -#define BDNZ BC 16,0, -#define BDNE BC 0,2, -#define TLBIA WORD $((31<<26)|(370<<1)) -#define TLBSYNC WORD $((31<<26)|(566<<1)) -#define MFTB(tbr,d) WORD $((31<<26)|((d)<<21)|((tbr&0x1f)<<16)|(((tbr>>5)&0x1f)<<11)|(371<<1)) - -/* 603/603e specific: load tlb entries */ -#define TLBLD(x) WORD $((31<<26)|(978<<1)|((x&0x1F)<<11)) -#define TLBLI(x) WORD $((31<<26)|(1010<<1)|((x&0x1F)<<11)) - -/* 400 models; perhaps others */ -#define ICCCI(a,b) WORD $((31<<26)|((a)<<16)|((b)<<11)|(966<<1)) -#define DCCCI(a,b) WORD $((31<<26)|((a)<<16)|((b)<<11)|(454<<1)) -/* these follow the source -> dest ordering */ -#define DCREAD(s,t) WORD $((31<<26)|((t)<<21)|((s)<<11)|(486<<1)) -#define DCRF(n) ((((n)>>5)&0x1F)|(((n)&0x1F)<<5)) -#define MTDCR(s,n) WORD $((31<<26)|((s)<<21)|(DCRF(n)<<11)|(451<<1)) -#define MFDCR(n,t) WORD $((31<<26)|((t)<<21)|(DCRF(n)<<11)|(323<<1)) -#define TLBRELO(a,t) WORD $((31<<26)|((t)<<21)|((a)<<16)|(1<<11)|(946<<1)) -#define TLBREHI(a,t) WORD $((31<<26)|((t)<<21)|((a)<<16)|(0<<11)|(946<<1)) -#define TLBWELO(s,a) WORD $((31<<26)|((s)<<21)|((a)<<16)|(1<<11)|(978<<1)) -#define TLBWEHI(s,a) WORD $((31<<26)|((s)<<21)|((a)<<16)|(0<<11)|(978<<1)) -#define TLBSX(a,b,t) WORD $((31<<26)|((t)<<21)|((a)<<16)|((b)<<11)|(914<<1)) -#define TLBSXCC(a,b,t) WORD $((31<<26)|((t)<<21)|((a)<<16)|((b)<<11)|(914<<1)|1) -#define WRTMSR_EE(s) WORD $((31<<26)|((s)<<21)|(131<<1)) -#define WRTMSR_EEI(e) WORD $((31<<26)|((e)<<16)|(163<<1)) - -/* on some models mtmsr doesn't synchronise enough (eg, 603e) */ -#define MSRSYNC SYNC; ISYNC - -/* on the 400 series, the prefetcher madly fetches across RFI, sys call, and others; use BR 0(PC) to stop */ -#define RFI WORD $((19<<26)|(50<<1)); BR 0(PC) -#define RFCI WORD $((19<<26)|(51<<1)); BR 0(PC) - -#define UREGSPACE (UREGSIZE+8) - -/* could define STEP to set an LED to mark progress */ -#define STEP(x) - -/* - * Boot first processor - */ - TEXT start(SB), $-4 - - MOVW MSR, R3 - RLWNM $0, R3, $~MSR_EE, R3 - OR $MSR_ME, R3 - ISYNC - MOVW R3, MSR /* turn off interrupts but enable traps */ - MSRSYNC - MOVW $0, R0 /* except during trap handling, R0 is zero from now on */ - MOVW R0, CR - - MOVW $setSB-KZERO(SB), R2 /* SB until mmu on */ - -/* - * reset the caches and disable them until mmu on - */ - MOVW R0, SPR(ICCR) - ICCCI(0, 2) /* the errata reveals that EA is used; we'll use SB */ - ISYNC - - MOVW $((CACHEWAYSIZE/CACHELINESZ)-1), R3 - MOVW R3, CTR - MOVW R0, R3 -dcinv: - DCCCI(0,3) - ADD $32, R3 - BDNZ dcinv - - /* cache is copy-back, disabled; no user-defined 0; big endian throughout */ - MOVW R0, SPR(DCWR) - MOVW R0, SPR(DCCR) - MOVW R0, SPR(SU0R) - MOVW R0, SPR(SLER) - ISYNC - - /* guard everything above 0x20000000 */ - MOVW $~(0xF000<<16), R3 - MOVW R3, SPR(SGR) - ISYNC - - /* set access to LED */ - MOVW $PHYSGPIO, R4 - MOVW $(1<<31), R6 - MOVW $(0xC000<<16), R5 - MOVW 4(R4), R3 - OR R6, R3 - MOVW R3, 4(R4) /* tcr set */ - MOVW 0x18(R4), R3 - ANDN R6, R3 - MOVW R3, 0x18(R4) /* odr reset */ - MOVW 8(R4), R3 - ANDN R5, R3 - MOVW R3, 8(R4) /* osrh uses or */ - MOVW 0x10(R4), R3 - ANDN R5, R3 - MOVW R3, 0x10(R4) /* tsr uses tcr */ - - MOVW $(1<<31), R4 /* reset MAL */ - MTDCR(0x180, 4) - -/* - MOVW $'H', R3 - BL uartputc(SB) - MOVW $'\n', R3 - BL uartputc(SB) -*/ - -/* - * set other system configuration values - */ - MOVW R0, SPR(PIT) - MOVW $~0, R3 - MOVW R3, SPR(TSR) - -STEP(1) - - BL kernelmmu(SB) - /* now running with correct addresses, mmu on */ - - MOVW $setSB(SB), R2 - - /* enable caches for kernel 128mb in real mode; data is copy-back */ - MOVW R0, SPR(DCWR) - MOVW $(1<<31), R3 - MOVW R3, SPR(DCCR) - MOVW R3, SPR(ICCR) - -/* - BL ledoff(SB) - - MOVW $0x800, R8 - MOVW R8, LR - BL (LR) - BR 0(PC) -*/ - -STEP(2) - /* no kfpinit on 4xx */ - - MOVW $mach0(SB), R(MACH) - ADD $(MACHSIZE-8), R(MACH), R1 - SUB $4, R(MACH), R3 - ADD $4, R1, R4 -clrmach: - MOVWU R0, 4(R3) - CMP R3, R4 - BNE clrmach - - MOVW R0, R(USER) - MOVW R0, 0(R(MACH)) - - MOVW $edata(SB), R3 - MOVW $end(SB), R4 - ADD $4, R4 - SUB $4, R3 -clrbss: - MOVWU R0, 4(R3) - CMP R3, R4 - BNE clrbss - -STEP(3) - BL main(SB) - BR 0(PC) - -TEXT kernelmmu(SB), $-4 - TLBIA - ISYNC - SYNC - - /* make following TLB entries shared, TID=PID=0 */ - MOVW R0, SPR(PID) - - /* all zones are supervisor, access controlled by TLB */ - MOVW R0, SPR(ZPR) - - /* map various things 1:1 */ - MOVW $tlbtab-KZERO(SB), R4 - MOVW $tlbtabe-KZERO(SB), R5 - SUB R4, R5 - MOVW $(2*4), R6 - DIVW R6, R5 - SUB $4, R4 - MOVW R5, CTR - MOVW R0, R3 -ltlb: - MOVWU 4(R4), R5 /* TLBHI */ - TLBWEHI(5,3) - MOVWU 4(R4), R5 /* TLBLO */ - TLBWELO(5,3) - ADD $1, R3 - BDNZ ltlb - - MOVW LR, R3 - OR $KZERO, R3 - MOVW R3, SPR(SRR0) - MOVW MSR, R4 - OR $(MSR_IR|MSR_DR), R4 - MOVW R4, SPR(SRR1) - - RFI /* resume in kernel mode in caller */ - -TEXT ledoff(SB), $0 - MOVW $PHYSGPIO, R4 - MOVW 0(R4), R3 - RLWNM $0, R3, $~(1<<31), R3 /* LED off */ - MOVW R3, 0(R4) - RETURN - -TEXT splhi(SB), $0 - MOVW MSR, R3 - RLWNM $0, R3, $~MSR_EE, R4 - SYNC - MOVW R4, MSR - MSRSYNC - MOVW LR, R31 - MOVW R31, 4(R(MACH)) /* save PC in m->splpc */ - RETURN - -TEXT splx(SB), $0 - MOVW MSR, R4 - RLWMI $0, R3, $MSR_EE, R4 - RLWNMCC $0, R3, $MSR_EE, R5 - BNE splx0 - MOVW LR, R31 - MOVW R31, 4(R(MACH)) /* save PC in m->splpc */ -splx0: - SYNC - MOVW R4, MSR - MSRSYNC - RETURN - -TEXT splxpc(SB), $0 - MOVW MSR, R4 - RLWMI $0, R3, $MSR_EE, R4 - RLWNMCC $0, R3, $MSR_EE, R5 - SYNC - MOVW R4, MSR - MSRSYNC - RETURN - -TEXT spllo(SB), $0 - MFTB(TBRL, 3) - MOVW R3, spltbl(SB) - MOVW MSR, R3 - OR $MSR_EE, R3, R4 - SYNC - MOVW R4, MSR - MSRSYNC - RETURN - -TEXT spldone(SB), $0 - RETURN - -TEXT islo(SB), $0 - MOVW MSR, R3 - RLWNM $0, R3, $MSR_EE, R3 - RETURN - -TEXT setlabel(SB), $-4 - MOVW LR, R31 - MOVW R1, 0(R3) - MOVW R31, 4(R3) - MOVW $0, R3 - RETURN - -TEXT gotolabel(SB), $-4 - MOVW 4(R3), R31 - MOVW R31, LR - MOVW 0(R3), R1 - MOVW $1, R3 - RETURN - -TEXT tlbwelo(SB), $-4 - MOVW v+4(FP), R5 - SYNC - TLBWELO(5, 3) - ISYNC - SYNC - RETURN - -TEXT tlbwehi(SB), $-4 - MOVW v+4(FP), R5 - SYNC - TLBWEHI(5, 3) - ISYNC - SYNC - RETURN - -TEXT tlbrehi(SB), $-4 - TLBREHI(3, 3) - RETURN - -TEXT tlbrelo(SB), $-4 - TLBRELO(3, 3) - RETURN - -TEXT tlbsxcc(SB), $-4 - TLBSXCC(0, 3, 3) - BEQ tlbsxcc0 - MOVW $-1, R3 /* not found */ -tlbsxcc0: - RETURN - -/* - * enter with stack set and mapped. - * on return, SB (R2) has been set, and R3 has the Ureg*, - * the MMU has been re-enabled, kernel text and PC are in KSEG, - * R(MACH) has been set, and R0 contains 0. - * - * this can be simplified in the Inferno regime - */ -TEXT saveureg(SB), $-4 -/* - * save state - */ - MOVMW R2, 48(R1) /* r2:r31 */ - MOVW $setSB(SB), R2 - MOVW SPR(SAVER1), R4 - MOVW R4, 44(R1) - MOVW SPR(SAVER0), R5 - MOVW R5, 40(R1) - MOVW CTR, R6 - MOVW R6, 36(R1) - MOVW XER, R4 - MOVW R4, 32(R1) - MOVW CR, R5 - MOVW R5, 28(R1) - MOVW SPR(SAVELR), R6 /* LR */ - MOVW R6, 24(R1) - /* pad at 20(R1) */ - /* old PC(16) and status(12) saved earlier */ - MOVW SPR(SAVEXX), R0 - MOVW R0, 8(R1) /* cause/vector */ - ADD $8, R1, R3 /* Ureg* */ - STWCCC R3, (R1) /* break any pending reservations */ - MOVW $0, R0 /* compiler/linker expect R0 to be zero */ - - MOVW MSR, R5 - OR $(MSR_IR|MSR_DR), R5 /* enable MMU */ - MOVW R5, SPR(SRR1) - MOVW LR, R31 - OR $KZERO, R31 /* return PC in KSEG0 */ - MOVW R31, SPR(SRR0) - SYNC - ISYNC - RFI /* returns to trap handler */ - -TEXT icflush(SB), $-4 /* icflush(virtaddr, count) */ - MOVW n+4(FP), R4 - CMP R4, R0 - BLE icf1 - RLWNM $0, R3, $~(CACHELINESZ-1), R5 - SUB R5, R3 - ADD R3, R4 - ADD $(CACHELINESZ-1), R4 - SRAW $CACHELINELOG, R4 - MOVW R4, CTR -icf0: ICBI (R5) - ADD $CACHELINESZ, R5 - BDNZ icf0 -icf1: - ISYNC - RETURN - -/* - * flush to store and invalidate globally - */ -TEXT dcflush(SB), $-4 /* dcflush(virtaddr, count) */ - SYNC - MOVW n+4(FP), R4 - RLWNM $0, R3, $~(CACHELINESZ-1), R5 - CMP R4, $0 - BLE dcf1 - SUB R5, R3 - ADD R3, R4 - ADD $(CACHELINESZ-1), R4 - SRAW $CACHELINELOG, R4 - MOVW R4, CTR -dcf0: DCBF (R5) - ADD $CACHELINESZ, R5 - BDNZ dcf0 - SYNC -dcf1: - ISYNC - MOVW R5, R3 /* check its operation */ - RETURN - -/* - * invalidate without flush, globally - */ -TEXT dcinval(SB), $-4 /* dcinval(virtaddr, count) */ - SYNC - MOVW n+4(FP), R4 - RLWNM $0, R3, $~(CACHELINESZ-1), R5 - CMP R4, $0 - BLE dci1 - SUB R5, R3 - ADD R3, R4 - ADD $(CACHELINESZ-1), R4 - SRAW $CACHELINELOG, R4 - MOVW R4, CTR -dci0: DCBI (R5) - ADD $CACHELINESZ, R5 - BDNZ dci0 - SYNC - ISYNC -dci1: - RETURN - -TEXT dccci(SB), $-4 - SYNC - DCCCI(0, 3) - ISYNC - RETURN - -TEXT _tas(SB), $0 - SYNC - MOVW R3, R4 - MOVW $0xdeaddead,R5 -tas1: - DCBF (R4) /* fix for 603x bug */ - LWAR (R4), R3 - CMP R3, $0 - BNE tas0 - STWCCC R5, (R4) - BNE tas1 -tas0: - SYNC - ISYNC - RETURN - -TEXT gettbl(SB), $0 - MFTB(TBRL, 3) - RETURN - -TEXT gettbu(SB), $0 - MFTB(TBRU, 3) - RETURN - -TEXT getpvr(SB), $0 - MOVW SPR(PVR), R3 - RETURN - -TEXT getcallerpc(SB), $-4 - MOVW 0(R1), R3 - RETURN - -TEXT getdear(SB), $0 - MOVW SPR(DEAR), R3 - RETURN - -TEXT getdsisr(SB), $0 - MOVW SPR(DSISR), R3 - RETURN - -TEXT getmsr(SB), $0 - MOVW MSR, R3 - RETURN - -TEXT putmsr(SB), $0 - SYNC - MOVW R3, MSR - MSRSYNC - RETURN - -TEXT putevpr(SB), $0 - MOVW R3, SPR(EVPR) - RETURN - -TEXT getesr(SB), $0 - MOVW SPR(ESR), R3 - RETURN - -TEXT putesr(SB), $0 - MOVW R3, SPR(ESR) - RETURN - -TEXT getpit(SB), $0 - MOVW SPR(PIT), R3 - RETURN - -TEXT putpit(SB), $0 - MOVW R3, SPR(PIT) - RETURN - -TEXT gettsr(SB), $0 - MOVW SPR(TSR), R3 - RETURN - -TEXT puttsr(SB), $0 - MOVW R3, SPR(TSR) - RETURN - -TEXT puttcr(SB), $0 - MOVW R3, SPR(TCR) - RETURN - -TEXT eieio(SB), $0 - EIEIO - RETURN - -TEXT gotopc(SB), $0 - MOVW R3, CTR - MOVW LR, R31 /* for trace back */ - BR (CTR) - -TEXT getccr0(SB), $-4 - MOVW SPR(CCR0), R3 - RETURN - -TEXT dcread(SB), $-4 - MOVW 4(FP), R4 - MOVW SPR(CCR0), R5 - RLWNM $0, R5, $~0xFF, R5 - OR R4, R5 - MOVW R5, SPR(CCR0) - SYNC - ISYNC - DCREAD(3, 3) - RETURN - -TEXT getdcr(SB), $-4 - MOVW $_getdcr(SB), R5 - SLW $3, R3 - ADD R3, R5 - MOVW R5, CTR - BR (CTR) - -TEXT putdcr(SB), $-4 - MOVW $_putdcr(SB), R5 - SLW $3, R3 - ADD R3, R5 - MOVW R5, CTR - MOVW 8(R1), R3 - BR (CTR) - -TEXT firmware(SB), $0 - MOVW $(3<<28), R3 - MOVW R3, SPR(DBCR0) /* system reset */ - BR 0(PC) - -/* - * byte swapping of arrays of long and short; - * could possibly be avoided with more changes to drivers - */ -TEXT swabl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - SRAW $2, R5, R5 - MOVW R5, CTR - SUB $4, R4 - SUB $4, R3 -swabl1: - ADD $4, R3 - MOVWU 4(R4), R7 - MOVWBR R7, (R3) - BDNZ swabl1 - RETURN - -TEXT swabs(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - SRAW $1, R5, R5 - MOVW R5, CTR - SUB $2, R4 - SUB $2, R3 -swabs1: - ADD $2, R3 - MOVHZU 2(R4), R7 - MOVHBR R7, (R3) - BDNZ swabs1 - RETURN - -TEXT legetl(SB), $0 - MOVWBR (R3), R3 - RETURN - -TEXT lesetl(SB), $0 - MOVW v+4(FP), R4 - MOVWBR R4, (R3) - RETURN - -TEXT legets(SB), $0 - MOVHBR (R3), R3 - RETURN - -TEXT lesets(SB), $0 - MOVW v+4(FP), R4 - MOVHBR R4, (R3) - RETURN - -TEXT itlbmiss(SB), $-4 - BR traps - -TEXT dtlbmiss(SB), $-4 - BR traps - -/* - * traps force memory mapping off. - * this code goes to much effort to restore it; - * (a little more effort than needed for the Inferno environment) - */ -TEXT trapvec(SB), $-4 -traps: - MOVW LR, R0 - -pagefault: - -/* - * map data virtually and make space to save - */ - MOVW R0, SPR(SAVEXX) /* vector */ -trapcomm: - MOVW R1, SPR(SAVER1) - SYNC - ISYNC - MOVW MSR, R0 - OR $(MSR_DR|MSR_ME), R0 /* make data space usable */ - SYNC - MOVW R0, MSR - MSRSYNC - SUB $UREGSPACE, R1 - - MOVW SPR(SRR0), R0 /* save SRR0/SRR1 now, since DLTB might be missing stack page */ - MOVW R0, LR - MOVW SPR(SRR1), R0 - RLWNM $0, R0, $~MSR_WE, R0 /* remove wait state */ - MOVW R0, 12(R1) /* save status: could take DLTB miss here */ - MOVW LR, R0 - MOVW R0, 16(R1) /* old PC */ - BL saveureg(SB) - BL trap(SB) - BR restoreureg - -/* - * critical trap/interrupt - */ -TEXT trapcvec(SB), $-4 - MOVW LR, R0 - /* for now we'll just restore the state to the conventions that trap expects, since we don't use critical intrs yet */ - MOVW R0, SPR(SAVEXX) - MOVW SPR(SRR2), R0 - MOVW R0, SPR(SRR0) - MOVW SPR(SRR3), R0 - MOVW R0, SPR(SRR1) - BR trapcomm - -TEXT intrvec(SB), $-4 - MOVW LR, R0 - -/* - * map data virtually and make space to save - */ - MOVW R0, SPR(SAVEXX) /* vector */ - MOVW R1, SPR(SAVER1) - SYNC - ISYNC - MOVW MSR, R0 - OR $MSR_DR, R0 /* make data space usable */ - SYNC - MOVW R0, MSR - MSRSYNC - SUB $UREGSPACE, R1 - - MFTB(TBRL, 0) - MOVW R0, intrtbl(SB) - - MOVW SPR(SRR0), R0 - MOVW R0, LR - MOVW SPR(SRR1), R0 - RLWNM $0, R0, $~MSR_WE, R0 /* remove wait state */ - MOVW R0, 12(R1) - MOVW LR, R0 - MOVW R0, 16(R1) - BL saveureg(SB) - - MFTB(TBRL, 5) - MOVW R5, isavetbl(SB) - - BL intr(SB) - -/* - * restore state from Ureg and return from trap/interrupt - */ -restoreureg: - MOVMW 48(R1), R2 /* r2:r31 */ - /* defer R1 */ - MOVW 40(R1), R0 - MOVW R0, SPR(SAVER0) - MOVW 36(R1), R0 - MOVW R0, CTR - MOVW 32(R1), R0 - MOVW R0, XER - MOVW 28(R1), R0 - MOVW R0, CR /* CR */ - MOVW 24(R1), R0 - MOVW R0, SPR(SAVELR) /* LR */ - /* pad, skip */ - MOVW 16(R1), R0 - MOVW R0, SPR(SRR0) /* old PC */ - MOVW 12(R1), R0 - MOVW R0, SPR(SRR1) /* old MSR */ - /* cause, skip */ - MOVW 44(R1), R1 /* old SP */ - MOVW SPR(SAVELR), R0 - MOVW R0, LR - MOVW SPR(SAVER0), R0 - RFI - -TEXT mul64fract(SB), $0 - MOVW a0+8(FP), R9 - MOVW a1+4(FP), R10 - MOVW b0+16(FP), R4 - MOVW b1+12(FP), R5 - - MULLW R10, R5, R13 /* c2 = lo(a1*b1) */ - - MULLW R10, R4, R12 /* c1 = lo(a1*b0) */ - MULHWU R10, R4, R7 /* hi(a1*b0) */ - ADD R7, R13 /* c2 += hi(a1*b0) */ - - MULLW R9, R5, R6 /* lo(a0*b1) */ - MULHWU R9, R5, R7 /* hi(a0*b1) */ - ADDC R6, R12 /* c1 += lo(a0*b1) */ - ADDE R7, R13 /* c2 += hi(a0*b1) + carry */ - - MULHWU R9, R4, R7 /* hi(a0*b0) */ - ADDC R7, R12 /* c1 += hi(a0*b0) */ - ADDE R0, R13 /* c2 += carry */ - - MOVW R12, 4(R3) - MOVW R13, 0(R3) - RETURN - -GLOBL mach0+0(SB), $MACHSIZE -GLOBL spltbl+0(SB), $4 -GLOBL intrtbl+0(SB), $4 -GLOBL isavetbl+0(SB), $4 diff --git a/os/cerf405/main.c b/os/cerf405/main.c deleted file mode 100644 index 11e172fc..00000000 --- a/os/cerf405/main.c +++ /dev/null @@ -1,719 +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 "../ip/ip.h" -#include "version.h" - -#define MAXCONF 32 - -extern ulong kerndate; -extern int cflag; -int remotedebug; - -extern int main_pool_pcnt; -extern int heap_pool_pcnt; -extern int image_pool_pcnt; - -char *confname[MAXCONF]; -char *confval[MAXCONF]; -int nconf; - -void addconf(char *, char *); -void eepromscan(void); - -static void -options(void) -{ -// nconf = archconfval(confname, confval, sizeof(confname)); -} - -void -doc(char *m) -{ - USED(m); - iprint("%s...\n", m); -} - -void -idoc(char *m) -{ - uartputs(m, strlen(m)); -} - -static void -poolsizeinit(void) -{ - ulong nb; - - nb = conf.npage*BY2PG; - poolsize(mainmem, (nb*main_pool_pcnt)/100, 0); - poolsize(heapmem, (nb*heap_pool_pcnt)/100, 0); - poolsize(imagmem, (nb*image_pool_pcnt)/100, 1); -} - -static void -serialconsole(void) -{ - char *p; - int port, baud; - - p = getconf("console"); - if(p == nil) - p = "0"; - if(p != nil && !remotedebug){ - port = strtol(p, nil, 0); - baud = 115200; - p = getconf("baud"); - if(p != nil){ - baud = strtol(p, nil, 0); - if(baud < 9600) - baud = 9600; - } - uartspecial(port, baud, &kbdq, &printq, kbdcr2nl); - } -} - -void -main(void) -{ - idoc("machinit...\n"); - machinit(); - idoc("options...\n"); - compiledcr(); - options(); -// archinit(); - quotefmtinstall(); - idoc("confinit...\n"); - confinit(); - xinit(); - poolsizeinit(); - poolinit(); - idoc("trapinit...\n"); - trapinit(); - mmuinit(); - ioinit(); - printinit(); - uartinstall(); - serialconsole(); - pcimapinit(); - eepromscan(); - doc("clockinit"); - clockinit(); - doc("procinit"); - procinit(); - cpuidprint(); - doc("links"); - links(); - doc("chandevreset"); - chandevreset(); - - eve = strdup("inferno"); - - print("\nInferno %s\n", VERSION); - print("Vita Nuova\n"); - print("conf %s (%lud) jit %d\n\n",conffile, kerndate, cflag); - - doc("userinit"); - userinit(); - doc("schedinit"); - schedinit(); -} - -//ccdv=1 cbdv=2 opdv=2 epdv=3 mpdv=1 ppdv=2 - -void -machinit(void) -{ - int n; - - n = m->machno; - memset(m, 0, sizeof(Mach)); - m->machno = n; - m->mmask = 1<machno; - m->cputype = getpvr()>>16; - m->delayloop = 20000; /* initial estimate only; set by clockinit */ - m->speed = 266; /* initial estimate only; set by archinit */ - m->cpuhz = 266333333; - m->vcohz = 799000000; - m->pllhz = 266333333; - m->plbhz = 133166666; - m->opbhz = 66600000; - m->epbhz = 44*MHz; - m->pcihz = 66600000; - m->clockgen = m->cpuhz; /* it's the internal cpu clock */ -} - -void -init0(void) -{ - Osenv *o; - int i; - char buf[2*KNAMELEN]; - - up->nerrlab = 0; - - spllo(); - - if(waserror()) - panic("init0"); - /* - * These are o.k. because rootinit is null. - * Then early kproc's will have a root and dot. - */ - o = up->env; - o->pgrp->slash = namec("#/", Atodir, 0, 0); - cnameclose(o->pgrp->slash->name); - o->pgrp->slash->name = newcname("/"); - o->pgrp->dot = cclone(o->pgrp->slash); - - chandevinit(); - - if(!waserror()){ - ksetenv("cputype", "power", 0); - snprint(buf, sizeof(buf), "power %s", conffile); - ksetenv("terminal", buf, 0); - poperror(); - } - for(i = 0; i < nconf; i++) - if(confname[i][0] != '*'){ - if(!waserror()){ - ksetenv(confname[i], confval[i], 0); - poperror(); - } - } - - poperror(); - disinit("/osinit.dis"); -} - -void -userinit(void) -{ - Proc *p; - Osenv *o; - - p = newproc(); - o = p->env; - - o->fgrp = newfgrp(nil); - o->pgrp = newpgrp(); - o->egrp = newegrp(); - kstrdup(&o->user, eve); - - strcpy(p->text, "interp"); - - /* - * Kernel Stack - */ - p->sched.pc = (ulong)init0; - p->sched.sp = (ulong)p->kstack+KSTACK; - - ready(p); -} - -Conf conf; - -void -addconf(char *name, char *val) -{ - if(nconf >= MAXCONF) - return; - confname[nconf] = name; - confval[nconf] = val; - nconf++; -} - -char* -getconf(char *name) -{ - int i; - - for(i = 0; i < nconf; i++) - if(cistrcmp(confname[i], name) == 0) - return confval[i]; - return 0; -} - -void -confinit(void) -{ - char *p; - int pcnt; - - - if(p = getconf("*kernelpercent")) - pcnt = 100 - strtol(p, 0, 0); - else - pcnt = 0; - - archconfinit(); - - conf.npage = conf.npage0 + conf.npage1; - if(pcnt < 10) - pcnt = 70; - conf.ialloc = (((conf.npage*(100-pcnt))/100)/2)*BY2PG; - - conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5; - conf.nmach = MAXMACH; - -} - -static void -twinkle(void) -{ - if(m->ticks%MS2TK(1000) == 0) - ((Gpioregs*)PHYSGPIO)->or ^= 1<<31; -} - -void (*archclocktick)(void) = twinkle; - -void -exit(int ispanic) -{ - up = 0; - spllo(); - print("cpu %d exiting\n", m->machno); - - /* Shutdown running devices */ - chandevshutdown(); - - delay(1000); - splhi(); - if(ispanic) - for(;;); - archreboot(); -} - -void -reboot(void) -{ - exit(0); -} - -void -halt(void) -{ - print("cpu halted\n"); - microdelay(1000); - for(;;) - ; -} - -/* - * kept in case it's needed for PCI/ISA devices - */ -int -isaconfig(char *class, int ctlrno, ISAConf *isa) -{ - char cc[KNAMELEN], *p; - int i; - - snprint(cc, sizeof cc, "%s%d", class, ctlrno); - p = getconf(cc); - if(p == nil) - return 0; - - isa->nopt = tokenize(p, isa->opt, NISAOPT); - for(i = 0; i < isa->nopt; i++){ - p = isa->opt[i]; - if(cistrncmp(p, "type=", 5) == 0) - isa->type = p + 5; - else if(cistrncmp(p, "port=", 5) == 0) - isa->port = strtoul(p+5, &p, 0); - else if(cistrncmp(p, "irq=", 4) == 0) - isa->irq = strtoul(p+4, &p, 0); - else if(cistrncmp(p, "mem=", 4) == 0) - isa->mem = strtoul(p+4, &p, 0); - else if(cistrncmp(p, "size=", 5) == 0) - isa->size = strtoul(p+5, &p, 0); - else if(cistrncmp(p, "freq=", 5) == 0) - isa->freq = strtoul(p+5, &p, 0); - else if(cistrncmp(p, "dma=", 4) == 0) - isa->dma = strtoul(p+4, &p, 0); - } - return 1; -} - -/* - * Save the mach dependent part of the process state. - */ -void -procsave(Proc*) -{ -} - -void -idlehands(void) -{ - putmsr(getmsr() | MSR_WE | MSR_EE | MSR_CE); /* MSR_DE as well? */ -} - -/* stubs */ -void -setfsr(ulong) -{ -} - -ulong -getfsr() -{ - return 0; -} - -void -setfcr(ulong) -{ -} - -ulong -getfcr() -{ - return 0; -} - -/* - * some of this is possibly ice-cube specific - */ - -enum { - Cpc0Pllmr0= 0xF0, /* PLL mode register 0 */ - Cpc0Boot= 0xF1, /* clock status */ - Cpc0Pllmr1= 0xF4, /* PLL mode register 1 */ - Cpc0Srr= 0xF6, /* PCI soft reset */ - Cpc0PCI= 0xF9, /* PCI control */ -}; -/* -00f0 = 00011101 -00f1 = 00000025 -00f2 = 00000000 -00f3 = 00000000 -00f4 = 8085523e -00f5 = 00000017 -00f6 = 00000000 -ccdv=1 cbdv=2 opdv=2 epdv=3 mpdv=1 ppdv=2 -fbmul=8 fwdva=5 fwdvb=5 tun=257 m=40 -*/ -void -archconfinit(void) -{ - ulong ktop; - - conf.npage0 = (32*1024*1024)/BY2PG; - conf.base0 = 0; - ktop = PGROUND((ulong)end); - ktop = PADDR(ktop) - conf.base0; - conf.npage0 -= ktop/BY2PG; - conf.base0 += ktop; - - {int i; for(i=0xF0; i<=0xF6; i++){iprint("%.4ux = %.8lux\n", i, getdcr(i));}} - { - int ccdv, cbdv, opdv, epdv, mpdv, ppdv; - int fbmul, fwdva, fwdvb, tun; - ulong mr0, mr1; - - mr0 = getdcr(Cpc0Pllmr0); - ccdv = ((mr0>>20)&3)+1; - cbdv = ((mr0>>16)&3)+1; - opdv = ((mr0>>12)&3)+1; - epdv = ((mr0>>8)&3)+2; - mpdv = ((mr0>>4)&3)+1; - ppdv = (mr0&3)+1; - iprint("ccdv=%d cbdv=%d opdv=%d epdv=%d mpdv=%d ppdv=%d\n", - ccdv, cbdv, opdv, epdv, mpdv, ppdv); - mr1 = getdcr(Cpc0Pllmr1); - fbmul = (mr1>>20) & 0xF; - if(fbmul == 0) - fbmul = 16; - fwdva = (mr1>>16) & 7; - if(fwdva == 0) - fwdva = 8; - fwdvb = (mr1>>12) & 7; - if(fwdvb == 0) - fwdvb = 8; - tun = mr0 & 0x3FF; - iprint("fbmul=%d fwdva=%d fwdvb=%d tun=%d m=%d\n", - fbmul, fwdva, fwdvb, tun, fbmul*fwdva); - } -} - -void -archreboot(void) -{ - putevpr(~0); - firmware(0); - for(;;); -} - -void -clockcheck(void) -{ -} - -void -cpuidprint(void) -{ - iprint("PowerPC 405EP pvr=%8.8lux\n", getpvr()); - /* TO DO */ -} - -#include "../port/flashif.h" - -/* - * for devflash.c:/^flashreset - * retrieve flash type, virtual base and length and return 0; - * return -1 on error (no flash) - */ -int -archflashreset(int bank, Flash *f) -{ - switch(bank){ - case 0: - f->type = "AMD29F0x0"; /* not right, but will do for now */ - f->addr = (void*)PHYSFLASH; - f->size = FLASHSIZE; - f->width = 2; - return 0; - case 1: - f->type = "nand"; - f->addr = (void*)PHYSNAND; - f->size = 0; /* done by probe */ - f->width = 1; - return 0; - default: - return -1; - } -} - -void -archflashwp(Flash*, int) -{ -} - -#include "../port/netif.h" -#include "etherif.h" - -enum { - /* EMAC-PHY control, tucked away in CPC0 */ - Cpc0Epctl= 0xF3, /* EMAC-PHY ctl */ - - E0Nf= 1<<31, /* Emac0 noise filter enable */ - E1Nf= 1<<30, /* Emac1 noise filter enable */ - E1pr= 1<<7, /* Emac1 packet reject is active high */ - E0pr= 1<<6, /* Emac 0 packet reject is active high */ - E1rm= 1<<5, /* enable Emac 1 packet removal */ - E0rm= 1<<4, /* enable Emac 0 packet removal */ - E1pci= 1<<1, /* Emac 1 clock source is Tx clock output (loopback) */ - E0pci= 1<<0, /* Emac 0 clock source is Tx clock output (loopback) */ -}; - -int -archether(int ctlno, Ether *ether) -{ - char name[KNAMELEN], *p; - int s; - - if(ctlno > 1) - return -1; - ether->type = "EMAC"; - ether->port = ctlno; - if(ctlno != 0) - snprint(name, sizeof(name), "eth%daddr", ctlno); - else - strcpy(name, "ethaddr"); - p = getconf(name); - if(p == 0){ - iprint("ether%d: no %s in EEPROM env\n", ctlno, name); - return -1; - } - parsemac(ether->ea, p, Eaddrlen); - s = splhi(); - putdcr(Cpc0Epctl, getdcr(Cpc0Epctl) | (ctlno?E1Nf:E0Nf)); - splx(s); - return 1; -} - -enum { - /* UART control */ - Cpc0Ucr= 0xF5, /* UART control register */ - - U0Dc= 1<<21, /* UART0 DMA clear enable */ - U0Dt= 1<<20, /* enable UART0 DMA transmit channel */ - U0Dr= 1<<19, /* enable UART0 DMA receive channel */ - U1Dc= 1<<18, /* UART1 DMA clear enable */ - U1Dt= 1<<17, /* enable UART1 DMA transmit channel */ - U1Dr= 1<<16, /* enable UART1 DMA receive channel */ - U1Div_s= 8, /* UART1 serial clock divisor (shift) */ - U1Stop= 1<<8, - U0Div_s= 0, /* UART0 serial clock divisor (shift) */ - U0Stop= 1<<0, - UDiv_m= 0x7F, /* UARTx divisor mask */ -}; - -static ulong -findserialclock(int rate, ulong *freq) -{ - ulong d, b; - ulong serialclock; - int actual, e, beste, bestd; - - *freq = 0; - if(rate == 0) - return 0; - d = ((m->pllhz+m->opbhz-1)/m->opbhz)*2; /* double to allow for later rounding */ - beste = 0; - bestd = -1; - for(; d<=128; d++){ - serialclock = (2*m->pllhz)/d; - b = ((serialclock+8*rate-1)/(rate*16))>>1; - actual = ((serialclock+8*b-1)/(b*16))>>1; - e = rate-actual; - if(e < 0) - e = -e; - if(bestd < 0 || e < beste || e == beste && (bestd&1) && (d&1)==0){ - beste = e; - bestd = d; - } - } - if(bestd > 0) - *freq = m->pllhz/bestd; - return bestd; -} - -/* - * return a value for UARTn's baud rate generator, and - * set a corresponding divsor in the UARTn clock generator - * (between 2 and 128) - */ -ulong -archuartclock(int n, int rate) -{ - int d, s; - ulong m, freq; - - d = findserialclock(rate, &freq); - if(d <= 0) - d = U0Stop; - m = UDiv_m; - if(n){ - d <<= U1Div_s; - m <<= U1Div_s; - } - s = splhi(); - putdcr(Cpc0Ucr, (getdcr(Cpc0Ucr) & ~m) | d); - splx(s); - return freq; -} - -void -archuartdma(int n, int on) -{ - ulong r; - int s; - - r = n? (U1Dc|U1Dt|U1Dr): (U0Dc|U0Dt|U0Dr); - if(on){ - s = splhi(); - putdcr(Cpc0Ucr, getdcr(Cpc0Ucr) | r); - splx(s); - }else{ - s = splhi(); - putdcr(Cpc0Ucr, getdcr(Cpc0Ucr) & ~r); - splx(s); - } -} - -/* - * boot environment in eeprom - */ - -enum { - EEpromHdr= 8, /* bytes */ - Envsize= 0x400, -}; - -static I2Cdev eedev; -static struct { - uchar buf[Envsize]; - int size; -} bootenv; - -static int -eepromitem(uchar *buf, int lim, ulong *off) -{ - int l; - uchar b; - - if(i2crecv(&eedev, &b, 1, (*off)++) != 1) - return -1; - l = b; - if(l & 0x80){ - if(i2crecv(&eedev, &b, 1, (*off)++) != 1) - return -1; - l = ((l & 0x7F)<<8) | b; - } - if(buf == nil) - return l; - if(l > lim) - l = lim; - return i2crecv(&eedev, buf, l, *off); -} - -void -eepromscan(void) -{ - int n, l; - ulong off; - uchar buf[2]; - char *p, *ep, *v; - - eedev.addr = 0x50; - eedev.salen = 2; - i2csetup(1); - n = i2crecv(&eedev, buf, sizeof(buf), 0); - if(n <= 0){ - iprint("eepromscan: %d\n", n); - return; - } - if(buf[0] != 0xEF || buf[1] != 0xBE){ - iprint("eeprom invalid\n"); - return; - } - bootenv.size = 0; - for(off = EEpromHdr; off < 16384;){ - l = eepromitem(bootenv.buf, sizeof(bootenv.buf), &off); /* key */ - if(l <= 0) - break; - off += l; - if(l == 7 && memcmp(bootenv.buf, "PPCBOOT", 7) == 0){ /* intrinsyc key */ - bootenv.size = eepromitem(bootenv.buf, sizeof(bootenv.buf), &off); - break; - } - l = eepromitem(nil, 0, &off); /* skip value */ - if(l < 0) - break; - off += l+2; /* 2 byte crc */ - } - p = (char*)bootenv.buf+4; /* skip crc */ - ep = p+bootenv.size; - for(; p < ep && *p; p += l){ - l = strlen(p)+1; - v = strchr(p, '='); - if(v != nil) - *v++ = 0; - else - v = ""; - addconf(p, v); - if(0) - iprint("%q = %q\n", p, v); - } -} - -ulong -logfsnow(void) -{ - return rtctime(); -} diff --git a/os/cerf405/mal.c b/os/cerf405/mal.c deleted file mode 100644 index 8a5018d3..00000000 --- a/os/cerf405/mal.c +++ /dev/null @@ -1,334 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -/* - * on the 405EP the MAL is used only by the Ethernet - * but we keep it separate even so - */ - -enum { - Nrxchan= 2, - Ntxchan= 4, - Maxchan = 4 -}; - -enum { - /* device control registers */ - Cfg= 0x180, /* configuration register */ - Esr= 0x181, /* error status register */ - Ier= 0x182, /* interrupt enable register */ - Txcasr= 0x184, /* transmit channel active set register */ - Txcarr= 0x185, /* transmit channel active reset register */ - Txeobisr= 0x186, /* transmit end of buffer interrupt status register */ - Txdeir= 0x187, /* transmit descriptor error interrupt register */ - Rxcasr= 0x190, /* receive channel active set register */ - Rxcarr= 0x191, /* receive channel active reset register */ - Rxeobisr= 0x192, /* receive channel descriptor error interrupt register */ - Rxdeir= 0x193, /* receive descriptor error interrupt register */ -}; - -#define TXCTPR(n) (0x1A0+(n)) /* transmit channel table pointer register */ -#define RXCTPR(n) (0x1C0+(n)) /* receive channel table pointer register */ -#define RCBS(n) (0x1E0+(n)) /* receive channel buffer size register */ - -enum { - /* configuration */ - CfgSr= 1<<31, /* software reset */ - CfgPlbp0= 0<<22, /* PLB priority (0=lowest) */ - CfgPlbp1= 1<<22, - CfgPlbp2= 2<<22, - CfgPlbp3= 3<<22, - CfgGa= 1<<21, /* guarded */ - CfgOa= 1<<20, /* ordered */ - CfgPlble= 1<<19, /* lock error */ - CfgPlbt_f= 0xF<<15, /* latency timer field */ - CfgPlbt_s= 15, /* latency timer (shift) */ - CfgPlbb= 1<<14, /* burst enable */ - CfgOpbbl= 1<<7, /* OPB locked */ - CfgOepie= 1<<2, /* interrupt on every end of packet */ - CfgLea= 1<<1, /* locked error active */ - CfgSd= 1<<0, /* scroll to next packet on early termination */ - - /* error status */ - EsrEvb= 1<<31, /* error valid bit */ - EsrCid_f= 0x7F<<25, /* field: channel ID causing lock error */ - EsrDe= 1<<20, /* descriptor error */ - EsrOne= 1<<19, /* OPB non-fullword error */ - EsrOte= 1<<18, /* OPB timeout error */ - EsrOse= 1<<17, /* OPB slave error */ - EsrPein= 1<<16, /* PLB bus error indication */ - EsrDei= 1<<4, /* descriptor error interrupt */ - EsrOnei= 1<<3, /* OPB non-fulword error interrupt */ - EsrOtei= 1<<2, /* OPB timeout error interrupt */ - EsrOsei= 1<<1, /* OPB slave error interrupt */ - EsrPbei= 1<<0, /* OPB bus error interrupt */ - -}; - -typedef struct Malmem Malmem; -struct Malmem { - Lock; - BD* base; - BD* limit; - BD* avail; -}; - -static Malmem malmem; - -static Mal* malchans[2][Maxchan]; - -static void -errorintr(Ureg*, void*) -{ - ulong esr, rxdeir, txdeir; - - /* mal de tĂȘte */ - esr = getdcr(Esr); - txdeir = getdcr(Txdeir); - rxdeir = getdcr(Rxdeir); - iprint("mal: esr=%8.8lux txdeir=%8.8lux rxdeir=%8.8lux\n", esr, txdeir, rxdeir); - putdcr(Rxdeir, rxdeir); - putdcr(Txdeir, txdeir); - putdcr(Esr, esr); -} - -static void -scanintr(Ureg *ur, ulong ir, Mal *chans[]) -{ - Mal *ml; - int i; - - for(i=0; ir != 0 && i < Maxchan; i++) - if(ir & IBIT(i)){ - ir &= ~IBIT(i); - ml = chans[i]; - if(ml != nil && ml->interrupt != nil) - ml->interrupt(ur, ml->arg); - /* unexpected interrupt otherwise */ - } -} - -static void -txinterrupt(Ureg *ur, void*) -{ - ulong ir; - - ir = getdcr(Txeobisr); - putdcr(Txeobisr, ir); - scanintr(ur, ir, malchans[1]); -} - -static void -rxinterrupt(Ureg *ur, void*) -{ - ulong ir; - - ir = getdcr(Rxeobisr); - putdcr(Rxeobisr, ir); - scanintr(ur, ir, malchans[0]); -} - -void -ioinit(void) -{ - int i; - - putdcr(Txcarr, ~0); - putdcr(Rxcarr, ~0); - - /* reset */ - putdcr(Cfg, CfgSr); - while(getdcr(Cfg) & CfgSr) - ; /* at most one system clock */ - - /* clear these out whilst we're at it */ - for(i=0; in = n; - ml->tx = tx; - ml->len = 1; - ml->arg = arg; - ml->interrupt = intr; - return ml; -} - -void -maltxreset(Mal *ml) -{ - putdcr(Txcarr, IBIT(ml->n)); -} - -void -maltxinit(Mal *ml, Ring *r) -{ - putdcr(TXCTPR(ml->n), PADDR(r->tdr)); -} - -void -maltxenable(Mal *ml) -{ - putdcr(Txcasr, getdcr(Txcasr) | IBIT(ml->n)); -} - -void -malrxreset(Mal *ml) -{ - putdcr(Rxcarr, IBIT(ml->n)); -} - -void -malrxinit(Mal *ml, Ring *r, ulong limit) -{ - putdcr(RXCTPR(ml->n), PADDR(r->rdr)); - putdcr(RCBS(ml->n), limit); -} - -void -malrxenable(Mal *ml) -{ - putdcr(Rxcasr, getdcr(Rxcasr) | IBIT(ml->n)); -} - -/* - * initialise receive and transmit buffer rings - * to use both Emacs, or two channels per emac, we'll need - * to allocate all rx descriptors at once, and all tx descriptors at once, - * in a region where all addresses have the same bits 0-12(!); - * see p 20-34. of the MAL chapter. - * - * the ring entries must be aligned on sizeof(BD) boundaries - * rings must be uncached, and buffers must align with cache lines since the cache doesn't snoop - * - * thus, we initialise it once for all, then hand it out as requested. - */ -void -ioringreserve(int nrx, ulong nrb, int ntx, ulong ntb) -{ - ulong nb, nbd; - - lock(&malmem); - if(malmem.base == nil){ - nbd = nrx*nrb + ntx*ntb; - nb = mmumapsize(nbd*sizeof(BD)); - /* - * the data sheet says in the description of buffer tables that they must be on a 4k boundary, - * but the pointer register descriptions say 8 bytes; it seems to be the latter. - */ - malmem.base = mmucacheinhib(xspanalloc(nb, nb, 1<<19), nb); - malmem.limit = malmem.base + nbd; - malmem.avail = malmem.base; - if((PADDR(malmem.base)&~0x7FFFF) != (PADDR(malmem.base)&~0x7FFFF)) - print("mal: trouble ahead?\n"); - } - unlock(&malmem); - if(malmem.base == nil) - panic("ioringreserve"); -} - -BD* -bdalloc(ulong nd) -{ - BD *b; - - lock(&malmem); - b = malmem.avail; - if(b+nd > malmem.limit) - b = nil; - else - malmem.avail = b+nd; - unlock(&malmem); - return b; -} - -int -ioringinit(Ring* r, int nrdre, int ntdre) -{ - int i; - - /* buffers must align with cache lines since the cache doesn't snoop */ - r->nrdre = nrdre; - if(r->rdr == nil) - r->rdr = bdalloc(nrdre); - if(r->rxb == nil) - r->rxb = malloc(nrdre*sizeof(Block*)); - if(r->rdr == nil || r->rxb == nil) - return -1; - for(i = 0; i < nrdre; i++){ - r->rxb[i] = nil; - r->rdr[i].length = 0; - r->rdr[i].addr = 0; - r->rdr[i].status = BDEmpty|BDInt; - } - r->rdr[i-1].status |= BDWrap; - r->rdrx = 0; - - r->ntdre = ntdre; - if(r->tdr == nil) - r->tdr = bdalloc(ntdre); - if(r->txb == nil) - r->txb = malloc(ntdre*sizeof(Block*)); - if(r->tdr == nil || r->txb == nil) - return -1; - for(i = 0; i < ntdre; i++){ - r->txb[i] = nil; - r->tdr[i].addr = 0; - r->tdr[i].length = 0; - r->tdr[i].status = 0; - } - r->tdr[i-1].status |= BDWrap; - r->tdrh = 0; - r->tdri = 0; - r->ntq = 0; - return 0; -} - -void -dumpmal(void) -{ - int i; - - iprint("Cfg=%8.8lux\n", getdcr(Cfg)); - iprint("Esr=%8.8lux\n", getdcr(Esr)); - iprint("Ier=%8.8lux\n", getdcr(Ier)); - iprint("Txcasr=%8.8lux\n", getdcr(Txcasr)); - iprint("Txcarr=%8.8lux\n", getdcr(Txcarr)); - iprint("Txeobisr=%8.8lux\n", getdcr(Txeobisr)); - iprint("Txdeir=%8.8lux\n", getdcr(Txdeir)); - iprint("Rxcasr=%8.8lux\n", getdcr(Rxcasr)); - iprint("Rxcarr=%8.8lux\n", getdcr(Rxcarr)); - iprint("Rxeobisr=%8.8lux\n", getdcr(Rxeobisr)); - iprint("Rxdeir=%8.8lux\n", getdcr(Rxdeir)); - for(i=0; i */ -#define USER 29 /* R29 is up-> */ - -/* - * Fundamental addresses - */ - -#define UREGSIZE ((8+32)*4) - -/* - * MMU - */ - -/* TLBHI */ -#define TLBEPN(x) ((x) & ~0x3FF) -#define TLB1K (0<<7) -#define TLB4K (1<<7) -#define TLB16K (2<<7) -#define TLB64K (3<<7) -#define TLB256K (4<<7) -#define TLB1MB (5<<7) -#define TLB4MB (6<<7) -#define TLB16MB (7<<7) -#define TLBVALID (1<<6) -#define TLBLE (1<<5) /* little-endian */ -#define TLBU0 (1<<4) /* user-defined attribute */ - -/* TLBLO */ -#define TLBRPN(x) ((x) & ~0x3FF) -#define TLBEX (1<<9) /* execute enable */ -#define TLBWR (1<<8) /* write enable */ -#define TLBZONE(x) ((x)<<4) -#define TLBW (1<<3) /* write-through */ -#define TLBI (1<<2) /* cache inhibit */ -#define TLBM (1<<1) /* memory coherent */ -#define TLBG (1<<0) /* guarded */ - -/* - * Address spaces - */ - -#define KUSEG 0x00000000 -#define KSEG0 0x20000000 -#define KSEG1 0x60000000 /* uncached alias for KSEG0 */ -#define KSEGM 0xE0000000 /* mask to check which seg */ - -#define KZERO KSEG0 /* base of kernel address space */ -#define KTZERO (KZERO+0x3000) /* first address in kernel text */ -#define KSTACK 8192 /* Size of kernel stack */ - -#define OCMZERO 0x40000000 /* on-chip memory (virtual and physical--see p 5-1) */ - -/* - * Exception codes (trap vectors) - */ -#define CRESET 0x01 -#define CMCHECK 0x02 -#define CDSI 0x03 -#define CISI 0x04 -#define CEI 0x05 -#define CALIGN 0x06 -#define CPROG 0x07 -/* 0x08 (fpu) not used */ -/* 0x09 (dec) not used */ -#define CSYSCALL 0x0C -/* 0x0D (trace) not used */ -/* 0x0E (fpa) not used */ -#define CPIT 0x10 -/* FIT is 0x1010 */ -/* WDT is 0x1020 */ -#define CDMISS 0x11 -#define CIMISS 0x12 -#define CDEBUG 0x20 - -/* - * exception syndrome register - */ -#define ESR_MCI 0x80000000 /* instruction machine check */ -#define ESR_PIL 0x08000000 /* program interrupt: illegal instruction */ -#define ESR_PPR 0x04000000 /* program interrupt: privileged */ -#define ESR_PTR 0x02000000 /* program intterupt: trap with successful compare */ -#define ESR_DST 0x00800000 /* data storage interrupt: store fault */ -#define ESR_DIZ 0x00400000 /* data/instruction storage interrupt: zone fault */ -#define ESR_U0F 0x00008000 /* data storage interrupt: u0 fault */ - -#include "physmem.h" - -/* cerf-cube specific */ -#define PHYSDRAM 0 -#define PHYSFLASH 0xFFE00000 -#define FLASHSIZE 0x200000 -#define PHYSNAND 0x60000000 diff --git a/os/cerf405/mkfile b/os/cerf405/mkfile deleted file mode 100644 index f43b9232..00000000 --- a/os/cerf405/mkfile +++ /dev/null @@ -1,104 +0,0 @@ -SYSTARG=Inferno -OBJTYPE=power -<../../mkconfig - -#Configurable parameters - -CONF=cerf #default configuration -CONFLIST=cerf -KZERO=0x20003020 - -SYSTARG=$OSTARG -OBJTYPE=power -INSTALLDIR=$ROOT/Inferno/$OBJTYPE/bin #path of directory where kernel is installed -#INSTALLDIR=/$OBJTYPE - -#end configurable parameters - -<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE #set vars based on target system - -<| $SHELLNAME ../port/mkdevlist $CONF #sets $IP, $DEVS, $ETHERS, $VGAS, $PORT, $MISC, $LIBS, $OTHERS - -OBJ=\ - l.$O\ - tlb.$O\ - nofp.$O\ - clock.$O\ - compile.$O\ - fpi.$O\ - fpimem.$O\ - fpipower.$O\ - gpio.$O\ - main.$O\ - mal.$O\ - mmu.$O\ - rmap.$O\ - trap.$O\ - $CONF.root.$O\ - $IP\ - $DEVS\ - $ETHERS\ - $LINKS\ - $VGAS\ - $PORT\ - $MISC\ - $OTHERS\ - -LIBNAMES=${LIBS:%=lib%.a} - -HFILES=\ - mem.h\ - physmem.h\ - dat.h\ - fns.h\ - io.h\ - -CFLAGS=-wFV -I. -I../port -I$ROOT/Inferno/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp -KERNDATE=`{$NDATE} - -#default:V: i$CONF.sq -default:V: i${CONF}hd - -i$CONF: $OBJ $CONF.c $CONF.root.h $LIBNAMES - $CC $CFLAGS '-DKERNDATE='$KERNDATE $CONF.c - $LD -o $target -T$KZERO -l -R4 $OBJ $CONF.$O $LIBFILES - $KSIZE $target - -i$CONF.sq: i$CONF - sqz -w i$CONF >$target - -out=i${CONF}hd - -i${CONF}hd: i$CONF - mkppcimage i$CONF $out - -install:V: i$CONF # i$CONF.sq - cp i$CONF $INSTALLDIR/i$CONF - #cp i$CONF.sq $INSTALLDIR/i$CONF.sq - -uninstall:V: - rm -f $ROOT/$OBJDIR/bin/i$CONF - rm -f $ROOT/$OBJDIR/bin/i$CONF.sq - -<../port/portmkfile - -../init/$INIT.dis: ../init/$INIT.b - cd ../init; mk $INIT.dis - -clock.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h -devether.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h -faultpower.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h -main.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h -trap.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h - -devether.$O $ETHERS: etherif.h ../port/netif.h -archipe.$O: screen.h archipe.h - -#$VGAS: screen.h vga.h -$IP devip.$O: ../ip/ip.h - -devboot.$O: devboot.c - $CC $CFLAGS devboot.c - -devuart.$O: devuart.c - $CC $CFLAGS devuart.c diff --git a/os/cerf405/mmu.c b/os/cerf405/mmu.c deleted file mode 100644 index ae0e0be9..00000000 --- a/os/cerf405/mmu.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" - -extern ulong tlbtab[], tlbtabe[]; -static int tlbx; /* index of next free entry in TLB */ - -enum -{ - /* on-chip memory dcr */ - Isarc= 0x018, /* instruction-side address range compare */ - Iscntl= 0x019, /* instruction-side control register */ - Isen= 1<<31, /* enable */ - Dsarc= 0x01A, /* data-side address range compare register */ - Dscntl= 0x01B, /* data-side control register */ - Dsen= 1<<31, /* enable */ - Dof= 1<<30, /* must be one (p. 5-7) */ -}; - -void -mmuinit(void) -{ - int i; - - /* - * the l.s initial TLB settings do nearly all that is needed initially. - * clear invalid entries (just for clarity) and record the address - * of the first available - */ - tlbx = -1; - for(i = 0; i < 64; i++) - if((tlbrehi(i) & TLBVALID) == 0){ - if(tlbx < 0) - tlbx = i; - tlbwelo(i, 0); - tlbwehi(i, 0); - } - - iprint("ccr0=%8.8lux\n", getccr0()); - - /* - * set OCM mapping, assuming: - * caches were invalidated earlier; - * and we aren't currently using it - * must also set a tlb entry that validates the virtual address but - * the translation is not used (see p. 5-2) - */ - putdcr(Isarc, OCMZERO); - putdcr(Dsarc, OCMZERO); - putdcr(Iscntl, Isen); - putdcr(Iscntl, Dsen|Dof); - tlbwelo(tlbx, OCMZERO|TLBZONE(0)|TLBWR|TLBEX|TLBI); - tlbwehi(tlbx, OCMZERO|TLB4K|TLBVALID); - tlbx++; -} - -int -segflush(void *a, ulong n) -{ - /* flush dcache then invalidate icache */ - dcflush(a, n); - icflush(a, n); - return 0; -} - -/* - * return required size and alignment to map n bytes in a tlb entry - */ -ulong -mmumapsize(ulong n) -{ - ulong size; - int i; - - size = 1024; - for(i = 0; i < 8 && size < n; i++) - size <<= 2; - return size; -} - -/* - * map a physical addresses at pa to va, with the given attributes. - * the virtual address must not be mapped already. - * if va is nil, map it at pa in virtual space. - */ -void* -kmapphys(void *va, ulong pa, ulong nb, ulong attr, ulong le) -{ - int s, i; - ulong size; - - if(va == nil) - va = (void*)pa; /* simplest is to use a 1-1 map */ - size = 1024; - for(i = 0; i < 8 && size < nb; i++) - size <<= 2; - if(i >= 8) - return nil; - s = splhi(); - tlbwelo(tlbx, pa | TLBZONE(0) | attr); - tlbwehi(tlbx, (ulong)va | (i<<7) | TLBVALID | le); - tlbx++; - splx(s); - return va; -} - -/* - * return an uncached alias for the memory at a - */ -void* -mmucacheinhib(void *a, ulong nb) -{ - ulong p; - - if(a == nil) - return nil; - dcflush(a, nb); - p = PADDR(a); - return kmapphys((void*)(KSEG1|p), p, nb, TLBWR | TLBI | TLBG, 0); -} diff --git a/os/cerf405/nand.c b/os/cerf405/nand.c deleted file mode 100644 index 5567574c..00000000 --- a/os/cerf405/nand.c +++ /dev/null @@ -1,96 +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 "flashif.h" - -/* - * Cerf405-specific NAND flash interface - */ - -#define BE(n) (1<<(31-(n))) /* big-endian bit numbering */ - -enum { - /* GPIO lines */ - Gpio_CLE_o_b= 31, - Gpio_ALE_o_b= 30, - Gpio_NCE_o_b= 24, /* CE#, active low */ - Gpio_RDY_i_b= 23, - - /* bit masks */ - Gpio_CLE_o= BE(Gpio_CLE_o_b), - Gpio_ALE_o= BE(Gpio_ALE_o_b), - Gpio_NCE_o= BE(Gpio_NCE_o_b), - Gpio_RDY_i= BE(Gpio_RDY_i_b), - - Gpio_NAND_o= Gpio_CLE_o | Gpio_ALE_o | Gpio_NCE_o, - - CS_NAND= 1, - Gpio_PerCS1_o= BE(10), -}; - -void -archnand_init(Flash*) -{ - gpioreserve(Gpio_NAND_o | Gpio_RDY_i); - gpioset(Gpio_NAND_o, Gpio_NCE_o); - gpioconfig(Gpio_NAND_o, Gpio_out); - gpioconfig(Gpio_RDY_i, Gpio_in); -} - -void -archnand_claim(Flash*, int claim) -{ - gpioset(Gpio_NCE_o, claim? 0: Gpio_NCE_o); -} - -void -archnand_setCLEandALE(Flash*, int cle, int ale) -{ - ulong v; - - v = 0; - if(cle) - v |= Gpio_CLE_o; - if(ale) - v |= Gpio_ALE_o; - gpioset(Gpio_CLE_o | Gpio_ALE_o, v); -} - -/* - * could unroll the loops - */ - -void -archnand_read(Flash *f, void *buf, int len) -{ - uchar *p, *bp; - - p = f->addr; - if(buf != nil){ - bp = buf; - while(--len >= 0) - *bp++ = *p; - }else{ - int junk; - while(--len >= 0){ - junk = *p; - USED(junk); - } - } -} - -void -archnand_write(Flash *f, void *buf, int len) -{ - uchar *p, *bp; - - p = f->addr; - bp = buf; - while(--len >= 0) - *p = *bp++; -} diff --git a/os/cerf405/nofp.s b/os/cerf405/nofp.s deleted file mode 100644 index f23d49b0..00000000 --- a/os/cerf405/nofp.s +++ /dev/null @@ -1,31 +0,0 @@ -/* - * stubs when no floating-point hardware - */ - -TEXT kfpinit(SB), $0 - RETURN - -TEXT getfpscr(SB), $8 - MOVW $0, R3 - RETURN - -TEXT fpsave(SB), $0 - RETURN - -TEXT fprestore(SB), $0 - RETURN - -TEXT clrfptrap(SB), $0 - RETURN - -TEXT fpinit(SB), $0 - RETURN - -TEXT fpoff(SB), $0 - RETURN - -TEXT FPsave(SB), 1, $0 - RETURN - -TEXT FPrestore(SB), 1, $0 - RETURN diff --git a/os/cerf405/pci.c b/os/cerf405/pci.c deleted file mode 100644 index 30908dc0..00000000 --- a/os/cerf405/pci.c +++ /dev/null @@ -1,981 +0,0 @@ -/* - * PCI support code. - */ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#define DBG if(0) pcilog - -typedef struct Pcicfg Pcicfg; -struct Pcicfg { - ulong addr; - union { - ulong l; - uchar b[4]; - ushort s[2]; - } data; -}; - -static Pcicfg* pcicfg; -static ulong* pciack; -static ulong* pcimem; - -struct -{ - char output[16384]; - int ptr; -}PCICONS; - -int -pcilog(char *fmt, ...) -{ - int n; - va_list arg; - char buf[PRINTSIZE]; - - va_start(arg, fmt); - n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; - va_end(arg); - - memmove(PCICONS.output+PCICONS.ptr, buf, n); - PCICONS.ptr += n; - return n; -} - -enum -{ /* configuration mechanism #1 */ - MaxFNO = 7, - MaxUBN = 255, -}; - -enum -{ /* command register */ - IOen = (1<<0), - MEMen = (1<<1), - MASen = (1<<2), - MemWrInv = (1<<4), - PErrEn = (1<<6), - SErrEn = (1<<8), -}; - -static Lock pcicfglock; -static QLock pcicfginitlock; -static int pcicfgmode = -1; -static int pcimaxbno = 7; -static int pcimaxdno; -static Pcidev* pciroot; -static Pcidev* pcilist; -static Pcidev* pcitail; - -static int pcicfgrw32(int, int, int, int); -static int pcicfgrw8(int, int, int, int); - -static char* bustypes[] = { -[BusOPB] "OPB", -[BusPLB] "PLB", -[BusPCI] "PCI", -}; - -#pragma varargck type "T" int - -static int -tbdffmt(Fmt* fmt) -{ - char *p; - int l, r, type, tbdf; - - if((p = malloc(READSTR)) == nil) - return fmtstrcpy(fmt, "(tbdfconv)"); - - switch(fmt->r){ - case 'T': - tbdf = va_arg(fmt->args, int); - type = BUSTYPE(tbdf); - if(type < nelem(bustypes)) - l = snprint(p, READSTR, bustypes[type]); - else - l = snprint(p, READSTR, "%d", type); - snprint(p+l, READSTR-l, ".%d.%d.%d", - BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf)); - break; - - default: - snprint(p, READSTR, "(tbdfconv)"); - break; - } - r = fmtstrcpy(fmt, p); - free(p); - - return r; -} - -ulong -pcibarsize(Pcidev *p, int rno) -{ - ulong v, size; - - v = pcicfgrw32(p->tbdf, rno, 0, 1); - pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0); - size = pcicfgrw32(p->tbdf, rno, 0, 1); - if(v & 1) - size |= 0xFFFF0000; - pcicfgrw32(p->tbdf, rno, v, 0); - - return -(size & ~0x0F); -} - -static int -pcisizcmp(void *a, void *b) -{ - Pcisiz *aa, *bb; - - aa = a; - bb = b; - return aa->siz - bb->siz; -} - -static ulong -pcimask(ulong v) -{ - ulong m; - - m = BI2BY*sizeof(v); - for(m = 1<<(m-1); m != 0; m >>= 1) { - if(m & v) - break; - } - - m--; - if((v & m) == 0) - return v; - - v |= m; - return v+1; -} - -static void -pcibusmap(Pcidev *root, ulong *pmema, ulong *pioa, int wrreg) -{ - Pcidev *p; - int ntb, i, size, rno, hole; - ulong v, mema, ioa, sioa, smema, base, limit; - Pcisiz *table, *tptr, *mtb, *itb; - extern void qsort(void*, long, long, int (*)(void*, void*)); - - ioa = *pioa; - mema = *pmema; - - DBG("pcibusmap wr=%d %T mem=%luX io=%luX\n", - wrreg, root->tbdf, mema, ioa); - - ntb = 0; - for(p = root; p != nil; p = p->link) - ntb++; - - ntb *= (PciCIS-PciBAR0)/4; - table = malloc(2*ntb*sizeof(Pcisiz)); - itb = table; - mtb = table+ntb; - - /* - * Build a table of sizes - */ - for(p = root; p != nil; p = p->link) { - if(p->ccrb == 0x06) { - if(p->ccru == 0x04 && p->bridge != nil) { - sioa = ioa; - smema = mema; - pcibusmap(p->bridge, &smema, &sioa, 0); - - hole = pcimask(smema-mema); - if(hole < (1<<20)) - hole = 1<<20; - p->mema.size = hole; - - hole = pcimask(sioa-ioa); - if(hole < (1<<12)) - hole = 1<<12; - - p->ioa.size = hole; - - itb->dev = p; - itb->bar = -1; - itb->siz = p->ioa.size; - itb++; - - mtb->dev = p; - mtb->bar = -1; - mtb->siz = p->mema.size; - mtb++; - } - if((pcicfgr8(p, PciHDT)&0x7f) != 0) - continue; - } - - for(i = 0; i <= 5; i++) { - rno = PciBAR0 + i*4; - v = pcicfgrw32(p->tbdf, rno, 0, 1); - size = pcibarsize(p, rno); - if(size == 0) - continue; - - if(v & 1) { - itb->dev = p; - itb->bar = i; - itb->siz = size; - itb++; - } - else { - mtb->dev = p; - mtb->bar = i; - mtb->siz = size; - mtb++; - } - - p->mem[i].size = size; - } - } - - /* - * Sort both tables IO smallest first, Memory largest - */ - qsort(table, itb-table, sizeof(Pcisiz), pcisizcmp); - tptr = table+ntb; - qsort(tptr, mtb-tptr, sizeof(Pcisiz), pcisizcmp); - - /* - * Allocate IO address space on this bus - */ - for(tptr = table; tptr < itb; tptr++) { - hole = tptr->siz; - if(tptr->bar == -1) - hole = 1<<12; - ioa = (ioa+hole-1) & ~(hole-1); - - p = tptr->dev; - if(tptr->bar == -1) - p->ioa.bar = ioa; - else { - p->pcr |= IOen; - p->mem[tptr->bar].bar = ioa|1; - if(wrreg) - pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), ioa|1, 0); - } - - ioa += tptr->siz; - } - - /* - * Allocate Memory address space on this bus - */ - for(tptr = table+ntb; tptr < mtb; tptr++) { - hole = tptr->siz; - if(tptr->bar == -1) - hole = 1<<20; - mema = (mema+hole-1) & ~(hole-1); - - p = tptr->dev; - if(tptr->bar == -1) - p->mema.bar = mema; - else { - p->pcr |= MEMen; - p->mem[tptr->bar].bar = mema; - if(wrreg) - pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), mema, 0); - } - mema += tptr->siz; - } - - *pmema = mema; - *pioa = ioa; - free(table); - - if(wrreg == 0) - return; - - /* - * Finally set all the bridge addresses & registers - */ - for(p = root; p != nil; p = p->link) { - if(p->bridge == nil) { - pcicfgrw8(p->tbdf, PciLTR, 64, 0); - - p->pcr |= MASen; - pcicfgrw32(p->tbdf, PciPCR, p->pcr, 0); - continue; - } - - base = p->ioa.bar; - limit = base+p->ioa.size-1; - v = pcicfgrw32(p->tbdf, PciBAR3, 0, 1); - v = (v&0xFFFF0000)|(limit & 0xF000)|((base & 0xF000)>>8); - pcicfgrw32(p->tbdf, PciBAR3, v, 0); - v = (limit & 0xFFFF0000)|(base>>16); - pcicfgrw32(p->tbdf, 0x30, v, 0); - - base = p->mema.bar; - limit = base+p->mema.size-1; - v = (limit & 0xFFF00000)|((base & 0xFFF00000)>>16); - pcicfgrw32(p->tbdf, PciBAR4, v, 0); - - /* - * Disable memory prefetch - */ - pcicfgrw32(p->tbdf, PciBAR5, 0x0000FFFF, 0); - pcicfgrw8(p->tbdf, PciLTR, 64, 0); - - /* - * Enable the bridge - */ - v = 0xFFFF0000 | IOen | MEMen | MASen; - pcicfgrw32(p->tbdf, PciPCR, v, 0); - - sioa = p->ioa.bar; - smema = p->mema.bar; - pcibusmap(p->bridge, &smema, &sioa, 1); - } -} - -static int -pcilscan(int bno, Pcidev** list) -{ - Pcidev *p, *head, *tail; - int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn; - - maxubn = bno; - head = nil; - tail = nil; - for(dno = 0; dno <= pcimaxdno; dno++){ - maxfno = 0; - for(fno = 0; fno <= maxfno; fno++){ - /* - * For this possible device, form the - * bus+device+function triplet needed to address it - * and try to read the vendor and device ID. - * If successful, allocate a device struct and - * start to fill it in with some useful information - * from the device's configuration space. - */ - tbdf = MKBUS(BusPCI, bno, dno, fno); - l = pcicfgrw32(tbdf, PciVID, 0, 1); - if(l == 0xFFFFFFFF || l == 0) - continue; - p = malloc(sizeof(*p)); - p->tbdf = tbdf; - p->vid = l; - p->did = l>>16; - - if(pcilist != nil) - pcitail->list = p; - else - pcilist = p; - pcitail = p; - - p->rid = pcicfgr8(p, PciRID); - p->ccrp = pcicfgr8(p, PciCCRp); - p->ccru = pcicfgr8(p, PciCCRu); - p->ccrb = pcicfgr8(p, PciCCRb); - p->pcr = pcicfgr32(p, PciPCR); - - p->intl = pcicfgr8(p, PciINTL); - - /* - * If the device is a multi-function device adjust the - * loop count so all possible functions are checked. - */ - hdt = pcicfgr8(p, PciHDT); - if(hdt & 0x80) - maxfno = MaxFNO; - - /* - * If appropriate, read the base address registers - * and work out the sizes. - */ - switch(p->ccrb) { - case 0x01: /* mass storage controller */ - case 0x02: /* network controller */ - case 0x03: /* display controller */ - case 0x04: /* multimedia device */ - case 0x06: /* bridge device */ - case 0x07: /* simple comm. controllers */ - case 0x08: /* base system peripherals */ - case 0x09: /* input devices */ - case 0x0A: /* docking stations */ - case 0x0B: /* processors */ - case 0x0C: /* serial bus controllers */ - if((hdt & 0x7F) != 0) - break; - rno = PciBAR0 - 4; - for(i = 0; i < nelem(p->mem); i++) { - rno += 4; - p->mem[i].bar = pcicfgr32(p, rno); - p->mem[i].size = pcibarsize(p, rno); - } - break; - - case 0x00: - case 0x05: /* memory controller */ - default: - break; - } - - if(head != nil) - tail->link = p; - else - head = p; - tail = p; - } - } - - *list = head; - for(p = head; p != nil; p = p->link){ - /* - * Find PCI-PCI bridges and recursively descend the tree. - */ - if(p->ccrb != 0x06 || p->ccru != 0x04) - continue; - - /* - * If the secondary or subordinate bus number is not - * initialised try to do what the PCI BIOS should have - * done and fill in the numbers as the tree is descended. - * On the way down the subordinate bus number is set to - * the maximum as it's not known how many buses are behind - * this one; the final value is set on the way back up. - */ - sbn = pcicfgr8(p, PciSBN); - ubn = pcicfgr8(p, PciUBN); - - if(sbn == 0 || ubn == 0) { - sbn = maxubn+1; - /* - * Make sure memory, I/O and master enables are - * off, set the primary, secondary and subordinate - * bus numbers and clear the secondary status before - * attempting to scan the secondary bus. - * - * Initialisation of the bridge should be done here. - */ - pcicfgw32(p, PciPCR, 0xFFFF0000); - l = (MaxUBN<<16)|(sbn<<8)|bno; - pcicfgw32(p, PciPBN, l); - pcicfgw16(p, PciSPSR, 0xFFFF); - maxubn = pcilscan(sbn, &p->bridge); - l = (maxubn<<16)|(sbn<<8)|bno; - - pcicfgw32(p, PciPBN, l); - } - else { - maxubn = ubn; - pcilscan(sbn, &p->bridge); - } - } - - return maxubn; -} - -int -pciscan(int bno, Pcidev **list) -{ - int ubn; - - qlock(&pcicfginitlock); - ubn = pcilscan(bno, list); - qunlock(&pcicfginitlock); - return ubn; -} - -static void -pcicfginit(void) -{ - char *p; - int bno; - Pcidev **list; - ulong mema, ioa; - - qlock(&pcicfginitlock); - if(pcicfgmode != -1) - goto out; - - //pcimmap(); - - pcicfgmode = 1; - pcimaxdno = 31; - -// fmtinstall('T', tbdffmt); - - if(p = getconf("*pcimaxbno")) - pcimaxbno = strtoul(p, 0, 0); - if(p = getconf("*pcimaxdno")) - pcimaxdno = strtoul(p, 0, 0); - - - list = &pciroot; - for(bno = 0; bno <= pcimaxbno; bno++) { - int sbno = bno; - bno = pcilscan(bno, list); - - while(*list) - list = &(*list)->link; - - if (sbno == 0) { - Pcidev *pci; - - /* - * If we have found a PCI-to-Cardbus bridge, make sure - * it has no valid mappings anymore. - */ - pci = pciroot; - while (pci) { - if (pci->ccrb == 6 && pci->ccru == 7) { - ushort bcr; - - /* reset the cardbus */ - bcr = pcicfgr16(pci, PciBCR); - pcicfgw16(pci, PciBCR, 0x40 | bcr); - delay(50); - } - pci = pci->link; - } - } - } - - if(pciroot == nil) - goto out; - - /* - * Work out how big the top bus is - */ - mema = 0; - ioa = 0; - pcibusmap(pciroot, &mema, &ioa, 0); - - DBG("Sizes: mem=%8.8lux size=%8.8lux io=%8.8lux\n", - mema, pcimask(mema), ioa); - - /* - * Align the windows and map it - */ - ioa = 0x1000; - mema = 0; - - pcilog("Mask sizes: mem=%lux io=%lux\n", mema, ioa); - - pcibusmap(pciroot, &mema, &ioa, 1); - DBG("Sizes2: mem=%lux io=%lux\n", mema, ioa); - -out: - qunlock(&pcicfginitlock); -} - -static int -pcicfgrw8(int tbdf, int rno, int data, int read) -{ - int o, x; - - if(pcicfgmode == -1) - pcicfginit(); - - x = -1; - if(BUSDNO(tbdf) > pcimaxdno) - return x; - - lock(&pcicfglock); - o = rno & 0x03; - rno &= ~0x03; - pcicfg->addr = 0x80000000|BUSBDF(tbdf)|rno; - eieio(); - if(read) - x = pcicfg->data.b[o]; /* TO DO: perhaps o^3 */ - else - pcicfg->data.b[o] = data; - eieio(); - pcicfg->addr = 0; - unlock(&pcicfglock); - - return x; -} - -int -pcicfgr8(Pcidev* pcidev, int rno) -{ - return pcicfgrw8(pcidev->tbdf, rno, 0, 1); -} - -void -pcicfgw8(Pcidev* pcidev, int rno, int data) -{ - pcicfgrw8(pcidev->tbdf, rno, data, 0); -} - -static int -pcicfgrw16(int tbdf, int rno, int data, int read) -{ - int o, x; - - if(pcicfgmode == -1) - pcicfginit(); - - x = -1; - if(BUSDNO(tbdf) > pcimaxdno) - return x; - - lock(&pcicfglock); - o = (rno >> 1) & 1; - rno &= ~0x03; - pcicfg->addr = 0x80000000|BUSBDF(tbdf)|rno; - eieio(); - if(read) - x = pcicfg->data.s[o]; - else - pcicfg->data.s[o] = data; - eieio(); - pcicfg->addr = 0; - unlock(&pcicfglock); - - return x; -} - -int -pcicfgr16(Pcidev* pcidev, int rno) -{ - return pcicfgrw16(pcidev->tbdf, rno, 0, 1); -} - -void -pcicfgw16(Pcidev* pcidev, int rno, int data) -{ - pcicfgrw16(pcidev->tbdf, rno, data, 0); -} - -static int -pcicfgrw32(int tbdf, int rno, int data, int read) -{ - int x; - - if(pcicfgmode == -1) - pcicfginit(); - - x = -1; - if(BUSDNO(tbdf) > pcimaxdno) - return x; - - lock(&pcicfglock); - rno &= ~0x03; - pcicfg->addr = 0x80000000|BUSBDF(tbdf)|rno; - eieio(); - if(read) - x = pcicfg->data.l; - else - pcicfg->data.l = data; - eieio(); - pcicfg->addr = 0; - unlock(&pcicfglock); - - return x; -} - -int -pcicfgr32(Pcidev* pcidev, int rno) -{ - return pcicfgrw32(pcidev->tbdf, rno, 0, 1); -} - -void -pcicfgw32(Pcidev* pcidev, int rno, int data) -{ - pcicfgrw32(pcidev->tbdf, rno, data, 0); -} - -Pcidev* -pcimatch(Pcidev* prev, int vid, int did) -{ - if(pcicfgmode == -1) - pcicfginit(); - - if(prev == nil) - prev = pcilist; - else - prev = prev->list; - - while(prev != nil){ - if((vid == 0 || prev->vid == vid) - && (did == 0 || prev->did == did)) - break; - prev = prev->list; - } - return prev; -} - -Pcidev* -pcimatchtbdf(int tbdf) -{ - Pcidev *pcidev; - - if(pcicfgmode == -1) - pcicfginit(); - - for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) { - if(pcidev->tbdf == tbdf) - break; - } - return pcidev; -} - -uchar -pciipin(Pcidev *pci, uchar pin) -{ - if (pci == nil) - pci = pcilist; - - while (pci) { - uchar intl; - - if (pcicfgr8(pci, PciINTP) == pin && pci->intl != 0 && pci->intl != 0xff) - return pci->intl; - - if (pci->bridge && (intl = pciipin(pci->bridge, pin)) != 0) - return intl; - - pci = pci->list; - } - return 0; -} - -static void -pcilhinv(Pcidev* p) -{ - int i; - Pcidev *t; - - if(p == nil) { - putstrn(PCICONS.output, PCICONS.ptr); - p = pciroot; - print("bus dev type vid did intl memory\n"); - } - for(t = p; t != nil; t = t->link) { - print("%d %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %3d ", - BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf), - t->ccrb, t->ccru, t->ccrp, t->vid, t->did, t->intl); - - for(i = 0; i < nelem(p->mem); i++) { - if(t->mem[i].size == 0) - continue; - print("%d:%.8lux %d ", i, - t->mem[i].bar, t->mem[i].size); - } - if(t->ioa.bar || t->ioa.size) - print("ioa:%.8lux %d ", t->ioa.bar, t->ioa.size); - if(t->mema.bar || t->mema.size) - print("mema:%.8lux %d ", t->mema.bar, t->mema.size); - if(t->bridge) - print("->%d", BUSBNO(t->bridge->tbdf)); - print("\n"); - } - while(p != nil) { - if(p->bridge != nil) - pcilhinv(p->bridge); - p = p->link; - } -} - -void -pcihinv(Pcidev* p) -{ - if(pcicfgmode == -1) - pcicfginit(); - qlock(&pcicfginitlock); - pcilhinv(p); - qunlock(&pcicfginitlock); -} - -void -pcishutdown(void) -{ - Pcidev *p; - - if(pcicfgmode == -1) - pcicfginit(); - - for(p = pcilist; p != nil; p = p->list){ - /* don't mess with the bridges */ - if(p->ccrb == 0x06) - continue; - pciclrbme(p); - } -} - -void -pcisetbme(Pcidev* p) -{ - int pcr; - - pcr = pcicfgr16(p, PciPCR); - pcr |= MASen; - pcicfgw16(p, PciPCR, pcr); -} - -void -pciclrbme(Pcidev* p) -{ - int pcr; - - pcr = pcicfgr16(p, PciPCR); - pcr &= ~MASen; - pcicfgw16(p, PciPCR, pcr); -} - -/* - * 405EP specific - */ - -typedef struct Pciplbregs Pciplbregs; -struct Pciplbregs { - struct { - ulong la; - ulong ma; - ulong pcila; - ulong pciha; - } pmm[3]; - struct { - ulong ms; - ulong la; - } ptm[2]; -}; - -enum { /* mask/attribute registers */ - Pre= 1<<1, /* enable prefetching (PMM only) */ - Ena= 1<<0, /* enable PLB to PCI map (PMM); enable PCI to PLB (PTM) */ -}; - -enum { /* DCR */ - Cpc0Srr= 0xF6, /* PCI soft reset */ - Rpci= 1<<18, /* reset PCI bridge */ - Cpc0PCI= 0xF9, /* PCI control */ - Spe= 1<<4, /* PCIINT/WE select */ - Hostcfgen= 1<<3, /* enable host config */ - Arben= 1<<1, /* enable internal arbiter */ -}; - -enum { - /* PciPCR */ - Se= 1<<8, /* enable PCISErr# when parity error detected as target */ - Per= 1<<6, /* enable PERR# on parity errors */ - Me= 1<<2, /* enable bridge-to-master cycles */ - Ma= 1<<1, /* enable memory access (when PCI memory target) */ - - /* PciPSR */ - Depe= 1<<15, /* parity error */ - Sse= 1<<14, /* signalled system error */ - Rma= 1<<13, /* received master abort */ - Rta= 1<<12, /* received target abort */ - Sta= 1<<11, /* signalled target abort */ - Dpe= 1<<8, /* data parity error */ - F66C= 1<<5, /* 66MHz capable */ - - /* PciBARn */ - Pf= 1<<3, /* prefetchable */ -}; - -/* -pmm 0: la=00000080 ma=010000c0 pcila=00000080 pciha=00000000 -pmm 1: la=00000000 ma=00000000 pcila=00000000 pciha=00000000 -pmm 2: la=00000000 ma=00000000 pcila=00000000 pciha=00000000 -ptm 0: ms=01000080 la=00000000 -ptm 1: ms=00000000 la=00000000 -*/ - -static void -pcidumpdev(ulong tbdf) -{ - int i; - - for(i=0; i<0x68; i+=4) - iprint("[%.2x]=%.8ux\n", i, pcicfgrw32(tbdf, i, 0, 1)); -} - -void -pcimapinit(void) -{ - Pciplbregs *pm; - int i, bridge, psr; - - pm = kmapphys(nil, PHYSPCIBCFG, sizeof(Pciplbregs), TLBWR | TLBI | TLBG, TLBLE); - if(0){ - /* see what the bootstrap left */ - iprint("PCI:\n"); - for(i=0; i<3; i++) - iprint("pmm %d: la=%.8lux ma=%.8lux pcila=%.8lux pciha=%.8lux\n", - i, pm->pmm[i].la, pm->pmm[i].ma, pm->pmm[i].pcila, pm->pmm[i].pciha); - for(i=0; i<2; i++) - iprint("ptm %d: ms=%.8lux la=%.8lux\n", - i, pm->ptm[i].ms, pm->ptm[i].la); - } - putdcr(Cpc0Srr, Rpci); - delay(1); - putdcr(Cpc0Srr, 0); - - kmapphys((void*)PHYSPCIIO0, PHYSPCIIO0, 64*1024, TLBWR | TLBI | TLBG, TLBLE); - pcicfg = kmapphys(nil, PHYSPCIADDR, sizeof(Pcicfg), TLBWR | TLBI | TLBG, TLBLE); - pciack = kmapphys(nil, PHYSPCIACK, sizeof(ulong), TLBWR | TLBI | TLBG, TLBLE); - eieio(); - - /* - * PLB addresses between PHYSPCIBRIDGE and PHYSPCIBRIDGE+64Mb - * are mapped to PCI memory at 0. - */ - pm->pmm[0].ma = 0; /* disable during update */ - eieio(); - pm->pmm[0].la = PHYSPCIBRIDGE; - pm->pmm[0].pcila = 0; - pm->pmm[0].pciha = 0; - eieio(); - pm->pmm[0].ma = 0xFC000000 | Ena; /* enable prefetch? */ - for(i=1; i<3; i++) - pm->pmm[i].ma = 0; /* disable the others */ - eieio(); - pcimem = kmapphys((void*)PHYSPCIBRIDGE, PHYSPCIBRIDGE, 0x4000000, TLBWR | TLBI | TLBG, TLBLE); - - /* - * addresses presented by a PCI device between PCIWINDOW and PCIWINDOW+1Gb - * are mapped to physical memory. - */ - pm->ptm[0].ms = 0; - eieio(); - pm->ptm[0].la = PCIWINDOW; - eieio(); - pm->ptm[0].ms = 0xC0000000 | Ena; /* always enabled by hardware */ - pm->ptm[1].ms = 0; - eieio(); - - iprint("cpc0pci=%.8lux\n", getdcr(Cpc0PCI)); - - /* - * the 405ep's pci bridge contains IBM vendor & devid, but - * ppcboot rather annoyingly clears them; put them back. - */ - pcicfgmode = 1; - pcimaxdno = 31; - - bridge = MKBUS(BusPCI, 0, 0, 0); - pcicfgrw16(bridge, PciPCR, Me | Ma, 0); - pcicfgrw16(bridge, PciVID, 0x1014, 0); - pcicfgrw16(bridge, PciDID, 0x0156, 0); - pcicfgrw8(bridge, PciCCRb, 0x06, 0); /* bridge */ - pcicfgrw32(bridge, PciBAR1, Pf, 0); - psr = pcicfgrw16(bridge, PciPSR, 0, 1); - if(m->pcihz >= 66000000) - psr |= F66C; /* 66 MHz */ - pcicfgrw16(bridge, PciPSR, psr, 0); /* reset error status */ - if(0){ - iprint("pci bridge':\n"); - pcidumpdev(bridge); - } - - pcicfgmode = -1; -} diff --git a/os/cerf405/physmem.h b/os/cerf405/physmem.h deleted file mode 100644 index 9fde7920..00000000 --- a/os/cerf405/physmem.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Memory-mapped IO - */ - -#define PHYSPCIBRIDGE 0x80000000 -#define PHYSMMIO 0xEF600000 -#define MMIO(i) (PHYSMMIO+(i)*0x100) -#define PHYSGPT MMIO(0) -#define PHYSUART0 MMIO(3) -#define PHYSUART1 MMIO(4) -#define PHYSIIC MMIO(5) -#define PHYSOPB MMIO(6) -#define PHYSGPIO MMIO(7) -#define PHYSEMAC0 MMIO(8) -#define PHYSEMAC1 MMIO(9) - -#define PHYSPCIIO0 0xE8000000 /* for 64M */ -#define PHYSPCIMEM 0x80000000 -#define PHYSPCIADDR 0xEEC00000 /* for 8 bytes */ -#define PHYSPCIDATA 0xEEC00004 -#define PHYSPCIACK 0xEED00000 /* interrupt acknowledge */ -#define PHYSPCIBCFG 0xEF400000 /* bridge configuration registers */ diff --git a/os/cerf405/powerbreak.c b/os/cerf405/powerbreak.c deleted file mode 100644 index fc5970ef..00000000 --- a/os/cerf405/powerbreak.c +++ /dev/null @@ -1,123 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "ureg.h" - -extern int (*breakhandler)(Ureg *ur, Proc*); /* trap.c */ -extern Instr BREAK; /* trap.c */ -extern void portbreakinit(void); - -#define getop(i) ((i>>26)&0x3F) -#define getxo(i) ((i>>1)&0x3FF) -#define getbobi(i) bo = (i>>21)&0x1f; bi = (i>>16)&0x1f; xx = (i>>11)&0x1f; - -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)); -} - -static int -condok(Ureg *ur, ulong ir, int ctrok) -{ - int bo, bi, xx; - ulong ctrval; - - ctrval = ur->ctr; - getbobi(ir); - if(xx) - return 0; /* illegal */ - if((bo & 0x4) == 0) { - if(!ctrok) - return 0; /* illegal */ - ctrval--; - } - if(bo & 0x4 || (ctrval!=0)^((bo>>1)&1)) { - if(bo & 0x10 || (((ur->cr & (1L<<(31-bi))!=0)==((bo>>3)&1)))) - return 1; - } - return 0; -} - -/* - * Return the address of the instruction that will be executed after the - * instruction at ur->pc, accounting for current branch conditions. - */ -ulong -machnextaddr(Ureg *ur) -{ - long imm; - ulong ir; - - ir = *(ulong*)ur->pc; - switch(getop(ir)) { - case 18: /* branch */ - imm = ir & 0x03FFFFFC; - if(ir & 0x02000000) - imm |= 0xFC000000; /* sign extended */ - if((ir & 2) == 0) /* relative address */ - return ur->pc + imm; - return imm; - - case 16: /* conditional branch */ - if(condok(ur, ir&0xFFFF0000, 1)){ - imm = ir & 0xFFFC; - if(ir & 0x08000) - imm |= 0xFFFF0000; /* sign extended */ - if((ir & 2) == 0) /* relative address */ - return ur->pc + imm; - return imm; - } - break; - - case 19: /* conditional branch to register */ - switch(getxo(ir)){ - case 528: /* bcctr */ - if(condok(ur, ir, 0)) - return ur->ctr & ~3; - break; - case 16: /* bclr */ - if(condok(ur, ir, 1)) - return ur->lr & ~3; - break; - } - break; - } - return ur->pc+4; /* next instruction */ -} - -int -isvalid_va(void *v) -{ - return (ulong)v >= KTZERO; -} diff --git a/os/cerf405/rmap.c b/os/cerf405/rmap.c deleted file mode 100644 index f521c24d..00000000 --- a/os/cerf405/rmap.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" - -void -mapinit(RMap *rmap, Map *map, int size) -{ - lock(rmap); - rmap->map = map; - rmap->mapend = map+(size/sizeof(Map)); - unlock(rmap); -} - -void -mapfree(RMap* rmap, ulong addr, int size) -{ - Map *mp; - ulong t; - - if(size <= 0) - return; - - lock(rmap); - for(mp = rmap->map; mp->addr <= addr && mp->size; mp++) - ; - - if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){ - (mp-1)->size += size; - if(addr+size == mp->addr){ - (mp-1)->size += mp->size; - while(mp->size){ - mp++; - (mp-1)->addr = mp->addr; - (mp-1)->size = mp->size; - } - } - } - else{ - if(addr+size == mp->addr && mp->size){ - mp->addr -= size; - mp->size += size; - } - else do{ - if(mp >= rmap->mapend){ - print("mapfree: %s: losing 0x%luX, %d\n", - rmap->name, addr, size); - break; - } - t = mp->addr; - mp->addr = addr; - addr = t; - t = mp->size; - mp->size = size; - mp++; - }while(size = t); - } - unlock(rmap); -} - -ulong -rmapalloc(RMap* rmap, ulong addr, int size, int align) -{ - Map *mp; - ulong maddr, oaddr; - - lock(rmap); - for(mp = rmap->map; mp->size; mp++){ - maddr = mp->addr; - - if(addr){ - if(maddr > addr) - break; - if(maddr+mp->size < addr) - continue; - if(addr+size > maddr+mp->size) - break; - maddr = addr; - } - - if(align > 0) - maddr = ((maddr+align-1)/align)*align; - if(mp->addr+mp->size-maddr < size) - continue; - - oaddr = mp->addr; - mp->addr = maddr+size; - mp->size -= maddr-oaddr+size; - if(mp->size == 0){ - do{ - mp++; - (mp-1)->addr = mp->addr; - }while((mp-1)->size = mp->size); - } - - unlock(rmap); - if(oaddr != maddr) - mapfree(rmap, oaddr, maddr-oaddr); - - return maddr; - } - unlock(rmap); - - return 0; -} diff --git a/os/cerf405/tlb.s b/os/cerf405/tlb.s deleted file mode 100644 index 98abd3fd..00000000 --- a/os/cerf405/tlb.s +++ /dev/null @@ -1,30 +0,0 @@ -#include "mem.h" -#define MB (1024*1024) - -/* - * TLB prototype entries, loaded once-for-all at startup, - * remaining unchanged thereafter. - * Limit the table size to ensure it fits in small TLBs. - */ -#define TLBE(hi, lo) WORD $(hi); WORD $(lo) - -TEXT tlbtab(SB), $-4 - - /* tlbhi tlblo */ - - /* DRAM, 32MB */ - TLBE(KZERO|PHYSDRAM|TLB16MB|TLBVALID, PHYSDRAM|TLBZONE(0)|TLBWR|TLBEX) - TLBE(KZERO|(PHYSDRAM+16*MB)|TLB16MB|TLBVALID, (PHYSDRAM+16*MB)|TLBZONE(0)|TLBWR|TLBEX) - - /* memory-mapped IO, 4K */ - TLBE(PHYSMMIO|TLB4K|TLBVALID, PHYSMMIO|TLBZONE(0)|TLBWR|TLBI|TLBG) - - /* NAND flash access (4K?) */ - TLBE(PHYSNAND|TLB4K|TLBVALID, PHYSNAND|TLBZONE(0)|TLBWR|TLBI|TLBG) - - /* NOR flash, 2MB */ - TLBE(PHYSFLASH|TLB1MB|TLBVALID, PHYSFLASH|TLBZONE(0)|TLBWR|TLBEX) - TLBE((PHYSFLASH+MB)|TLB1MB|TLBVALID, (PHYSFLASH+MB)|TLBZONE(0)|TLBWR|TLBEX) - -TEXT tlbtabe(SB), $-4 - RETURN diff --git a/os/cerf405/trap.c b/os/cerf405/trap.c deleted file mode 100644 index 846cc097..00000000 --- a/os/cerf405/trap.c +++ /dev/null @@ -1,581 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "ureg.h" -#include "io.h" -#include "../port/error.h" - -enum -{ - Maxhandler= MaxVector /* max number of interrupt handlers, assuming none shared */ -}; - -enum { - /* UIC registers (p. 10-4) */ - Usr = 0xC0, /* status */ - Uer = 0xC2, /* enable */ - Ucr = 0xC3, /* critical interrupts */ - Upr = 0xC4, /* priority */ - Utr = 0xC5, /* trigger */ - Umsr = 0xC6, /* masked status */ - Uvr = 0xC7, /* vector */ - Uvcr = 0xC8, /* vector configuration */ -}; - -typedef struct Handler Handler; -struct Handler -{ - void (*r)(Ureg*, void*); - void *arg; - char name[KNAMELEN]; - Handler *next; - int edge; - ulong nintr; - ulong ticks; - int maxtick; -}; - -static Lock veclock; - -static struct -{ - Handler *ivec[MaxVector]; - Handler h[Maxhandler]; - int free; - Handler* freelist; -} halloc; - -Instr BREAK = 0x7fe00008; -int (*breakhandler)(Ureg*, Proc*); - -void kernfault(Ureg*, int); - -char *excname[] = -{ - "reserved 0", - "system reset", - "machine check", - "data access", - "instruction access", - "external interrupt", - "alignment", - "program exception", - "floating-point unavailable", - "decrementer", - "i/o controller interface error", - "reserved B", - "system call", - "trace trap", - "floating point assist", - "reserved F", - "software emulation", - "ITLB miss", - "DTLB miss", - "ITLB error", - "DTLB error", - "reserved 15", - "reserved 16", - "reserved 17", - "reserved 18", - "reserved 19", - "reserved 1A", - "reserved 1B", - "data breakpoint", - "instruction breakpoint", - "peripheral breakpoint", - "development port", - /* the following are made up on a program exception */ - "floating point exception", /* 20: FPEXC */ - "illegal instruction", /* 21 */ - "privileged instruction", /* 22 */ - "trap", /* 23 */ - "illegal operation", /* 24 */ - "breakpoint", /* 25 */ -}; - -char *fpcause[] = -{ - "inexact operation", - "division by zero", - "underflow", - "overflow", - "invalid operation", -}; -char *fpexcname(Ureg*, ulong, char*); -#define FPEXPMASK 0xfff80300 /* Floating exception bits in fpscr */ - -char *regname[]={ - "CAUSE", "SRR1", - "PC", "GOK", - "LR", "CR", - "XER", "CTR", - "R0", "R1", - "R2", "R3", - "R4", "R5", - "R6", "R7", - "R8", "R9", - "R10", "R11", - "R12", "R13", - "R14", "R15", - "R16", "R17", - "R18", "R19", - "R20", "R21", - "R22", "R23", - "R24", "R25", - "R26", "R27", - "R28", "R29", - "R30", "R31", -}; - -void -sethvec(int v, void (*r)(void)) -{ - ulong *vp, pa, o; - - vp = (ulong*)KADDR(v); - vp[0] = 0x7c1043a6; /* MOVW R0, SPR(SPRG0) */ - vp[1] = 0x7c0802a6; /* MOVW LR, R0 */ - vp[2] = 0x7c1243a6; /* MOVW R0, SPR(SPRG2) */ - pa = PADDR(r); - o = pa >> 25; - if(o != 0 && o != 0x7F){ - /* a branch too far: running from ROM */ - vp[3] = (15<<26)|(pa>>16); /* MOVW $r&~0xFFFF, R0 */ - vp[4] = (24<<26)|(pa&0xFFFF); /* OR $r&0xFFFF, R0 */ - vp[5] = 0x7c0803a6; /* MOVW R0, LR */ - vp[6] = 0x4e800021; /* BL (LR) */ - }else - vp[3] = (18<<26)|(pa&0x3FFFFFC)|3; /* bla */ - dcflush(vp, 8*sizeof(ulong)); -} - -void -sethvec2(int v, void (*r)(void)) -{ - ulong *vp; - - vp = (ulong*)KADDR(v); - vp[0] = (18<<26)|((ulong)r&~KSEGM)|2; /* ba */ - dcflush(vp, sizeof(*vp)); -} - -static void -faultpower(Ureg *ur, ulong addr, int read) -{ - char buf[ERRMAX]; - - if(up == nil){ - dumpregs(ur); - panic("kernel fault"); - } - - up->dbgreg = ur; /* For remote ACID */ - spllo(); - - sprint(buf, "trap: fault %s pc=0x%lux addr=0x%lux", - read? "read": "write", ur->pc, addr); - if(up->type == Interp){ - if(addr == ~0) - disfault(ur, "dereference of nil"); - disfault(ur, buf); - } - dumpregs(ur); - panic("fault: %s\n", buf); -} - -void -trap(Ureg *ur) -{ - int ecode, s; - ulong w, esr; - char buf[ERRMAX]; - - ecode = ur->cause >> 8; - if(ecode < 0 || ecode >= 0x1F) - ecode = 0x1F; - esr = getesr(); - putesr(0); - switch(ecode){ - case CPIT: - clockintr(ur); - preemption(1); - break; - - case CMCHECK: - if(esr & ESR_MCI){ - faultpower(ur, ur->pc, 1); - break; - } - /* FALL THROUGH */ - case CDSI: - faultpower(ur, getdear(), !(esr&ESR_DST)); - break; - - case CDMISS: - faultpower(ur, getdear(), 1); - break; - - case CISI: - case CIMISS: - faultpower(ur, ur->pc, 1); - break; - - case CPROG: - if(esr & ESR_PIL){ - if(up == nil) - goto Default; - if((ulong)(ur+1) != ur->r1) - panic("fp emu stack"); - spllo(); - if(waserror()){ - if(up->type == Interp) - disfault(ur, up->env->errstr); - panic("%s", up->env->errstr); - } - if(fpipower(ur) == 0){ - splhi(); - poperror(); - print("pc=#%lux op=#%8.8lux\n", ur->pc, *(ulong*)ur->pc); /* temporary */ - goto Default; - } - poperror(); - break; - } - /* TO DO: 4xx variant for the following */ - if(ur->status & (1<<19)) { - ecode = 0x20; - w = ur->pc; - if(ur->status & (1<<16)) - w += 4; - if(*(ulong*)w == 0x7fe00008){ /* tw 31,0,0 */ - if(breakhandler){ - s = (*breakhandler)(ur, up); - if(s == BrkSched){ - if(up){ - up->preempted = 0; - sched(); - splhi(); - } - }else if(s == BrkNoSched){ - if(up){ - up->preempted = 1; /* stop it being preempted until next instruction */ - up->dbgreg = 0; - } - } - break; - } - ecode = 0x1D; /* breakpoint */ - } - } - if(ur->status & (1<<18)) - ecode = 0x21; - if(ur->status & (1<<17)) - ecode = 0x22; - /* FALL THROUGH */ - - Default: - default: - if(up && up->type == Interp) { - spllo(); - snprint(buf, sizeof buf, "sys: trap: %s pc=0x%lux", excname[ecode], ur->pc); - error(buf); - break; - } - print("kernel %s pc=0x%lux\n", excname[ecode], ur->pc); - dumpregs(ur); - dumpstack(); - if(m->machno == 0) - spllo(); - exit(1); - } - - splhi(); -} - -void -trapinit(void) -{ - int i; - - putdcr(Uer, 0); /* none enabled */ - putdcr(Ucr, 0); /* none are critical by default */ - putdcr(Upr, ~IBIT(VectorPCISERR)); /* default is active high (except PCISERR) */ - putdcr(Utr, 0); /* all are level sensitive by default */ - putdcr(Usr, getdcr(Usr)); /* reset interrupts */ - putdcr(Uvcr, 0); /* 31 is highest priority */ - eieio(); - - /* - * set all exceptions to trap - */ - for(i = 0x0; i < 0x3000; i += 0x100) - sethvec(i, trapvec); - - /* on the 405, several traps are critical interrupts with different SRRs */ - sethvec(0x0100, trapcvec); - sethvec(0x0200, trapcvec); - - sethvec(CEI<<8, intrvec); - /* TO DO: FIT and WDT */ - //sethvec2(CIMISS<<8, itlbmiss); - //sethvec2(CDMISS<<8, dtlbmiss); - - putevpr(0); /* use our vectors */ -} - -void -intrenable(int v, void (*r)(Ureg*, void*), void *arg, int, char *name) -{ - Handler *h; - ulong w, f, bit; - - f = v; - v &= IRQmask; - bit = IBIT(v); - if(v < 0 || v >= nelem(halloc.ivec)) - panic("intrenable(%d)", v); - ilock(&veclock); - if((h = halloc.freelist) == nil){ - if(halloc.free >= Maxhandler){ - iunlock(&veclock); - panic("out of interrupt handlers"); - } - h = &halloc.h[halloc.free++]; - }else - halloc.freelist = h->next; - h->r = r; - h->arg = arg; - strncpy(h->name, name, KNAMELEN-1); - h->name[KNAMELEN-1] = 0; - h->next = halloc.ivec[v]; - halloc.ivec[v] = h; - - /* - * enable corresponding interrupt in UIC - */ - w = getdcr(Ucr); - if(f & IRQcritical) - putdcr(Ucr, w | bit); - else - putdcr(Ucr, w & ~bit); - if(v >= VectorIRQ){ - /* (only) these have got choice of polarity, etc. */ - w = getdcr(Utr); - h->edge = (f & IRQedge) != 0; - if(h->edge) - putdcr(Utr, w | bit); - else - putdcr(Utr, w & ~bit); - w = getdcr(Upr); - if(f & IRQactivelow) - putdcr(Upr, w | bit); - else - putdcr(Upr, w & ~bit); - } - eieio(); - putdcr(Uer, getdcr(Uer) | bit); - eieio(); - iunlock(&veclock); -} - -static void -irqdisable(int v) -{ - putdcr(Uer, getdcr(Uer) & ~IBIT(v)); -} - -void -intrdisable(int v, void (*r)(Ureg*, void*), void *arg, int, char *name) -{ - Handler *h, **hp; - - v &= IRQmask; - if(v < 0 || v >= nelem(halloc.ivec)) - panic("intrdisable(%d)", v); - ilock(&veclock); - for(hp = &halloc.ivec[v]; (h = *hp) != nil; hp = &h->next) - if(h->r == r && h->arg == arg && strcmp(h->name, name) == 0){ - *hp = h->next; - h->next = halloc.freelist; - halloc.freelist = h; - break; - } - if(halloc.ivec[v] == nil) - irqdisable(v); - iunlock(&veclock); -} - -/* - * called directly by l.s:/intrvec. on a multiprocessor we'd need to lock veclock. - */ -void -intr(Ureg *ur) -{ - ulong msr, b; - int v; - Handler *h; - long t0; - Proc *oup; - - oup = up; - up = nil; /* no process at interrupt level */ - while((msr = getdcr(Umsr)) != 0){ - for(v=0; msr!=0 && v<32; v++){ - b = IBIT(v); - if((msr & b) == 0) - continue; - msr &= ~b; - ur->cause = (CEI<<8) | v; - h = halloc.ivec[v]; - if(h == nil){ - iprint("unknown interrupt %d pc=0x%lux\n", v, ur->pc); - irqdisable(v); - continue; - } - - /* - * call the interrupt handlers - */ - do { - if(h->edge) - putdcr(Usr, b); - h->nintr++; - t0 = getpit(); - (*h->r)(ur, h->arg); - t0 -= getpit(); - h->ticks += t0; - if(h->maxtick < t0) - h->maxtick = t0; - if(!h->edge) - putdcr(Usr, b); - h = h->next; - } while(h != nil); - } - } - up = oup; - preemption(0); -} - -int -intrstats(char *buf, int bsize) -{ - Handler *h; - int i, n; - - n = 0; - for(i=0; inintr) - n += snprint(buf+n, bsize-n, "%3d %lud %lud %ud\n", i, h->nintr, h->ticks, h->maxtick); - return n; -} - -char* -fpexcname(Ureg *ur, ulong fpscr, char *buf) -{ - int i; - char *s; - ulong fppc; - - fppc = ur->pc; - s = 0; - fpscr >>= 3; /* trap enable bits */ - fpscr &= (fpscr>>22); /* anded with exceptions */ - for(i=0; i<5; i++) - if(fpscr & (1<status, ur->pc, ur->sp); - dumpregs(ur); - l.sp = ur->sp; - l.pc = ur->pc; - dumpstack(); - setpri(PriBackground); /* Let the debugger in */ - for(;;) - sched(); -} - -void -dumpstack(void) -{ - ulong l, v; - int i; - - if(up == 0) - return; - i = 0; - for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){ - v = *(ulong*)l; - if(KTZERO < v && v < (ulong)etext){ - print("%lux=%lux, ", l, v); - if(i++ == 4){ - print("\n"); - i = 0; - } - } - } -} - -void -dumpregs(Ureg *ur) -{ - int i; - ulong *l; - if(up) { - print("registers for %s %ld\n", up->text, up->pid); - if(ur->usp < (ulong)up->kstack || - ur->usp > (ulong)up->kstack+KSTACK) - print("invalid stack ptr\n"); - } - else - print("registers for kernel\n"); - - l = &ur->cause; - for(i=0; ikpfun)(up->arg); - pexit("", 0); -} - -void -kprocchild(Proc *p, void (*func)(void*), void *arg) -{ - p->sched.pc = (ulong)linkproc; - p->sched.sp = (ulong)p->kstack+KSTACK; - - p->kpfun = func; - p->arg = arg; -} - -void -setpanic(void) -{ - consoleprint = 1; -iprint("panic\n"); -} - -void -dumplongs(char*, ulong*, int) -{ -} diff --git a/os/cerf405/uart.c b/os/cerf405/uart.c deleted file mode 100644 index 3d90f5ad..00000000 --- a/os/cerf405/uart.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" - -/* - * uart for initial port - */ - -typedef struct Uartregs Uartregs; -struct Uartregs { - uchar rbr; -#define thr rbr -#define dll rbr - uchar ier; -#define dlm ier - uchar fcr; -#define iir fcr - uchar lcr; - uchar mcr; - uchar lsr; - uchar msr; - uchar scr; -}; - -#define UARTREGS(n) ((Uartregs*)(PHYSUART0+(n)*0x100)) - -enum { - /* ier */ - Edssi= 1<<3, - Elsi= 1<<2, - Etbei= 1<<1, - Erbfi= 1<<0, - - /* iir */ - Fci0= 0<<4, - Fci3= 3<<4, - Ipl= 7<<1, - Ip= 1<<0, - - /* fcr */ - Rftl1= 0<<6, /* receiver trigger level 1, 16, 32, 56 */ - Rftl16= 1<<6, - Rftl32= 2<<6, - Rftl56= 3<<6, - Dms= 1<<3, /* =0, single transfer; =1, multiple transfers */ - Tfr= 1<<2, /* transmitter fifo reset */ - Rfr= 1<<1, /* receiver fifo reset */ - Fifoe= 1<<0, /* =0, disable fifos; =1, enable fifos */ - - /* lcr */ - Dlab= 1<<7, /* =0, normal; =1, dll/dlm visible */ - Sb= 1<<6, /* set break */ - Sp= 1<<5, /* =1, enable sticky parity */ - Eps= 1<<4, /* =1, generate even parity */ - Pen= 1<<3, /* =1, enable parity checking */ - Sbs= 1<<2, /* =0, 1 stop bit; =1, 1.5 or 2 stop bits (see Wls) */ - Wls= 3<<0, /* set to nbit-5 for nbit characters */ - - /* mcr */ - Afc= 1<<5, /* =1, auto flow control enabled */ - Loop= 1<<4, /* =1, loop back mode enabled */ - Out2= 1<<3, /* =0, OUT2# active */ - Out1= 1<<2, /* =0, OUT1# active */ - Rts= 1<<1, /* =0, RTS# inactive (1); =1, RTS# active (0) */ - Dtr= 1<<0, /* =0, DTS# inactive; =1, DTS# active */ - - /* lsr */ - Rfe= 1<<7, /* error instances in fifo */ - Temt= 1<<6, /* transmitter empty */ - Thre= 1<<5, /* transmitter holding register/fifo empty */ - Be= 1<<4, /* break (interrupt) */ - Fe= 1<<3, /* framing error */ - Pe= 1<<2, /* parity error */ - Oe= 1<<1, /* overrun error */ - Dr= 1<<0, /* receiver data ready */ - - /* msr */ - Dcd= 1<<7, /* follows Out2 */ - Ri= 1<<6, /* follows Out1 */ - Dsr= 1<<5, /* follows Dtr */ - Cts= 1<<4, /* follows Rts */ - Ddcd= 1<<3, /* Dcd input changed */ - Teri= 1<<2, /* Ri changed from 0 to 1 */ - Ddsr= 1<<1, /* Dsr input changed */ - Dcts= 1<<0, /* Cts input changed */ -}; - -void (*serwrite)(char*, int) = uartputs; - -void -uartinstall(void) -{ -} - -void -uartspecial(int, int, Queue**, Queue**, int (*)(Queue*, int)) -{ -} - -void -uartputc(int c) -{ - Uartregs *r; - - if(c == 0) - return; - r = UARTREGS(0); - while((r->lsr & Thre) == 0) - {} - r->thr = c; - if(c == '\n') - while((r->lsr & Thre) == 0) /* flush xmit fifo */ - {} -} - -void -uartputs(char *data, int len) -{ - int s; - -// if(!uartspcl && !redirectconsole) -// return; - s = splhi(); - while(--len >= 0){ - if(*data == '\n') - uartputc('\r'); - uartputc(*data++); - } - splx(s); -} - -void -uartwait(void) -{ -} diff --git a/os/cerf405/uart.h b/os/cerf405/uart.h deleted file mode 100644 index 28037473..00000000 --- a/os/cerf405/uart.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 405EP specific code for its uart. - */ - -#define UR(p,r) ((uchar*)(p))[r] -#define uartwr(u,r,v) (UR(u->regs,r) = (v)) -#define uartwrreg(u,r,v) (UR(u->regs,r)= (u)->sticky[r] | (v)) -#define uartrdreg(u,r) UR(u->regs,r) - -extern void uartsetup(ulong, void*, ulong, char*); -extern void uartclock(void); - -static void -uartportpower(Uart*, int) -{ - /* TO DO: power control */ -} - -/* - * handle an interrupt to a single uart - */ -static void -uartintrx(Ureg*, void* arg) -{ - uartintr(arg); -} - -/* - * install the uarts (called by reset) - */ -void -uartinstall(void) -{ - static int already; - - if(already) - return; - already = 1; - - /* first two ports are always there */ - uartsetup(0, (void*)PHYSUART0, 0, "eia0"); - intrenable(VectorUART0, uartintrx, uart[0], BUSUNKNOWN, "uart0"); - uartsetup(1, (void*)PHYSUART1, 0, "eia1"); - intrenable(VectorUART1, uartintrx, uart[1], BUSUNKNOWN, "uart1"); - addclock0link(uartclock, 22); -} - -/* - * If the UART's receiver can be connected to a DMA channel, - * this function does what is necessary to create the - * connection and returns the DMA channel number. - * If the UART's receiver cannot be connected to a DMA channel, - * a -1 is returned. - */ -char -uartdmarcv(int dev) -{ - - USED(dev); - return -1; -} - -void -uartputc(int c) -{ - uchar *p; - - if(c == 0) - return; - p = (uchar*)PHYSUART0; - while((UR(p,Lstat) & Outready) == 0){ - ; - } - UR(p,Data) = c; - eieio(); - if(c == '\n') - while((UR(p,Lstat) & Outready) == 0){ /* let fifo drain */ - ; - } -} - -void -uartputs(char *data, int len) -{ - int s; - -// if(!uartspcl && !redirectconsole) -// return; - s = splhi(); - while(--len >= 0){ - if(*data == '\n') - uartputc('\r'); - uartputc(*data++); - } - splx(s); -} - -void -uartwait(void) -{ -} -- cgit v1.2.3