summaryrefslogtreecommitdiff
path: root/os/cerf405
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/cerf405
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/cerf405')
-rw-r--r--os/cerf405/README45
-rw-r--r--os/cerf405/cerf142
-rw-r--r--os/cerf405/clock.c159
-rw-r--r--os/cerf405/compile.c34
-rw-r--r--os/cerf405/dat.h159
-rw-r--r--os/cerf405/devboot.c132
-rw-r--r--os/cerf405/devether.c617
-rw-r--r--os/cerf405/devrtc.c369
-rw-r--r--os/cerf405/devuart.c1064
-rw-r--r--os/cerf405/etheremac.c829
-rw-r--r--os/cerf405/etherif.h37
-rw-r--r--os/cerf405/fns.h147
-rw-r--r--os/cerf405/fpi.h61
-rw-r--r--os/cerf405/fpipower.c970
-rw-r--r--os/cerf405/gpio.c106
-rw-r--r--os/cerf405/iic.c605
-rw-r--r--os/cerf405/inb.s127
-rw-r--r--os/cerf405/io.h301
-rw-r--r--os/cerf405/l.s795
-rw-r--r--os/cerf405/main.c719
-rw-r--r--os/cerf405/mal.c334
-rw-r--r--os/cerf405/mem.h147
-rw-r--r--os/cerf405/mkfile104
-rw-r--r--os/cerf405/mmu.c122
-rw-r--r--os/cerf405/nand.c96
-rw-r--r--os/cerf405/nofp.s31
-rw-r--r--os/cerf405/pci.c981
-rw-r--r--os/cerf405/physmem.h22
-rw-r--r--os/cerf405/powerbreak.c123
-rw-r--r--os/cerf405/rmap.c106
-rw-r--r--os/cerf405/tlb.s30
-rw-r--r--os/cerf405/trap.c581
-rw-r--r--os/cerf405/uart.c139
-rw-r--r--os/cerf405/uart.h101
34 files changed, 0 insertions, 10335 deletions
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 <isa.h>
-#include <interp.h>
-
-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; i<MAXDCR; i++){
- p = _getdcr[i];
- p[0] = MFDCR(i, 3);
- p[1] = RETURN;
- p = _putdcr[i];
- p[0] = MTDCR(3, i);
- p[1] = RETURN;
- }
- dcflush(_getdcr, sizeof(_getdcr));
- dcflush(_putdcr, sizeof(_putdcr));
- /* no need to flush icache since they won't be there */
-}
diff --git a/os/cerf405/dat.h b/os/cerf405/dat.h
deleted file mode 100644
index 12af446e..00000000
--- a/os/cerf405/dat.h
+++ /dev/null
@@ -1,159 +0,0 @@
-typedef struct Conf Conf;
-typedef struct FPU FPU;
-typedef struct FPenv FPenv;
-typedef struct Irqctl Irqctl;
-typedef struct ISAConf ISAConf;
-typedef struct Label Label;
-typedef struct Lock Lock;
-typedef struct Mach Mach;
-typedef struct Map Map;
-typedef struct Pcidev Pcidev;
-typedef struct Power Power;
-typedef struct RMap RMap;
-typedef struct Ureg Ureg;
-
-typedef ulong Instr;
-
-#define MACHP(n) (n==0? &mach0 : *(Mach**)0)
-
-struct Lock
-{
- ulong key;
- ulong pc;
- ulong sr;
- int pri;
-};
-
-struct Label
-{
- ulong sp;
- ulong pc;
-};
-
-/*
- * Proc.fpstate
- */
-enum
-{
- FPINIT,
- FPACTIVE,
- FPINACTIVE,
-};
-
-/*
- * This structure must agree with FPsave and FPrestore asm routines
- */
-struct FPenv
-{
- union {
- double fpscrd;
- struct {
- ulong pad;
- ulong fpscr;
- };
- };
- int fpistate; /* emulated fp */
- ulong emreg[32][3]; /* emulated fp */
-};
-/*
- * This structure must agree with fpsave and fprestore asm routines
- */
-struct FPU
-{
- double fpreg[32];
- FPenv env;
-};
-
-struct Conf
-{
- ulong nmach; /* processors */
- ulong nproc; /* processes */
- ulong npage0; /* total physical pages of memory */
- ulong npage1; /* total physical pages of memory */
- ulong npage; /* total physical pages of memory */
- ulong base0; /* base of bank 0 */
- ulong base1; /* base of bank 1 */
- ulong ialloc; /* max interrupt time allocation in bytes */
-};
-
-#include "../port/portdat.h"
-
-/*
- * machine dependent definitions not used by ../port/dat.h
- */
-
-struct Mach
-{
- /* OFFSETS OF THE FOLLOWING KNOWN BY l.s */
- int machno; /* physical id of processor (unused) */
- ulong splpc; /* pc of last caller to splhi (unused) */
- int mmask; /* 1<<m->machno (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){
- if(offset+n > 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){
- if(offset+n > 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; i<MaxEther; i++){
- ether = etherxx[i];
- if(ether != nil && ether->detach != nil)
- ether->detach(ether);
- }
-}
-
-static Walkqid*
-etherwalk(Chan* chan, Chan *nchan, char **name, int nname)
-{
- Walkqid *wq;
- Ether *ether;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- wq = netifwalk(etherxx[chan->dev], chan, nchan, name, nname);
- poperror();
- runlock(ether);
- return wq;
-}
-
-static int
-etherstat(Chan* chan, uchar* dp, int n)
-{
- int s;
- Ether *ether;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- s = netifstat(ether, chan, dp, n);
- poperror();
- runlock(ether);
- return s;
-}
-
-static Chan*
-etheropen(Chan* chan, int omode)
-{
- Chan *c;
- Ether *ether;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- c = netifopen(ether, chan, omode);
- poperror();
- runlock(ether);
- return c;
-}
-
-static void
-ethercreate(Chan*, char*, int, ulong)
-{
-}
-
-static void
-etherclose(Chan* chan)
-{
- Ether *ether;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- netifclose(ether, chan);
- poperror();
- runlock(ether);
-}
-
-static long
-etherread(Chan* chan, void* buf, long n, vlong off)
-{
- Ether *ether;
- ulong offset = off;
- long r;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- if((chan->qid.type & QTDIR) == 0 && ether->ifstat){
- /*
- * With some controllers it is necessary to reach
- * into the chip to extract statistics.
- */
- if(NETTYPE(chan->qid.path) == Nifstatqid){
- r = ether->ifstat(ether, buf, n, offset);
- goto out;
- }
- if(NETTYPE(chan->qid.path) == Nstatqid)
- ether->ifstat(ether, buf, 0, offset);
- }
- r = netifread(ether, chan, buf, n, offset);
-out:
- poperror();
- runlock(ether);
- return r;
-}
-
-static Block*
-etherbread(Chan* chan, long n, ulong offset)
-{
- Block *b;
- Ether *ether;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- b = netifbread(ether, chan, n, offset);
- poperror();
- runlock(ether);
- return b;
-}
-
-static int
-etherwstat(Chan* chan, uchar* dp, int n)
-{
- Ether *ether;
- int r;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- r = netifwstat(ether, chan, dp, n);
- poperror();
- runlock(ether);
- return r;
-}
-
-static void
-etherrtrace(Netfile* f, Etherpkt* pkt, int len)
-{
- int i, n;
- Block *bp;
-
- if(qwindow(f->in) <= 0)
- return;
- if(len > 58)
- n = 58;
- else
- n = len;
- bp = iallocb(64);
- if(bp == nil)
- return;
- memmove(bp->wp, pkt->d, n);
- i = TK2MS(MACHP(0)->ticks);
- bp->wp[58] = len>>8;
- bp->wp[59] = len;
- bp->wp[60] = i>>24;
- bp->wp[61] = i>>16;
- bp->wp[62] = i>>8;
- bp->wp[63] = i;
- bp->wp += 64;
- qpass(f->in, bp);
-}
-
-Block*
-etheriq(Ether* ether, Block* bp, int fromwire)
-{
- Etherpkt *pkt;
- ushort type;
- int len, multi, tome, fromme;
- Netfile **ep, *f, **fp, *fx;
- Block *xbp;
-
- ether->inpackets++;
-
- pkt = (Etherpkt*)bp->rp;
- len = BLEN(bp);
- type = (pkt->type[0]<<8)|pkt->type[1];
- fx = 0;
- ep = &ether->f[Ntypes];
-
- multi = pkt->d[0] & 1;
- /* check for valid multcast addresses */
- if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) != 0 && ether->prom == 0){
- if(!activemulti(ether, pkt->d, sizeof(pkt->d))){
- if(fromwire){
- freeb(bp);
- bp = 0;
- }
- return bp;
- }
- }
-
- /* is it for me? */
- tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
- fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
-
- /*
- * Multiplex the packet to all the connections which want it.
- * If the packet is not to be used subsequently (fromwire != 0),
- * attempt to simply pass it into one of the connections, thereby
- * saving a copy of the data (usual case hopefully).
- */
- for(fp = ether->f; fp < ep; fp++){
- if((f = *fp) && (f->type == type || f->type < 0))
- if(tome || multi || f->prom){
- /* Don't want to hear bridged packets */
- if(f->bridge && !fromwire && !fromme)
- continue;
- if(!f->headersonly){
- if(fromwire && fx == 0)
- fx = f;
- else if(xbp = iallocb(len)){
- memmove(xbp->wp, pkt, len);
- xbp->wp += len;
- if(qpass(f->in, xbp) < 0)
- ether->soverflows++;
- }
- else
- ether->soverflows++;
- }
- else
- etherrtrace(f, pkt, len);
- }
- }
-
- if(fx){
- if(qpass(fx->in, bp) < 0)
- ether->soverflows++;
- return 0;
- }
- if(fromwire){
- freeb(bp);
- return 0;
- }
-
- return bp;
-}
-
-static int
-etheroq(Ether* ether, Block* bp)
-{
- int len, loopback, s;
- Etherpkt *pkt;
-
- ether->outpackets++;
-
- /*
- * Check if the packet has to be placed back onto the input queue,
- * i.e. if it's a loopback or broadcast packet or the interface is
- * in promiscuous mode.
- * If it's a loopback packet indicate to etheriq that the data isn't
- * needed and return, etheriq will pass-on or free the block.
- * To enable bridging to work, only packets that were originated
- * by this interface are fed back.
- */
- pkt = (Etherpkt*)bp->rp;
- len = BLEN(bp);
- loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
- if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){
- s = splhi();
- etheriq(ether, bp, 0);
- splx(s);
- }
-
- if(!loopback){
- qbwrite(ether->oq, bp);
- if(ether->transmit != nil)
- ether->transmit(ether);
- }else
- freeb(bp);
-
- return len;
-}
-
-static long
-etherwrite(Chan* chan, void* buf, long n, vlong)
-{
- Ether *ether;
- Block *bp;
- int onoff;
- Cmdbuf *cb;
- long l;
-
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- if(NETTYPE(chan->qid.path) != Ndataqid) {
- l = netifwrite(ether, chan, buf, n);
- if(l >= 0)
- goto out;
- cb = parsecmd(buf, n);
- if(strcmp(cb->f[0], "nonblocking") == 0){
- if(cb->nf <= 1)
- onoff = 1;
- else
- onoff = atoi(cb->f[1]);
- qnoblock(ether->oq, onoff);
- free(cb);
- goto out;
- }
- free(cb);
- if(ether->ctl!=nil){
- l = ether->ctl(ether,buf,n);
- goto out;
- }
- error(Ebadctl);
- }
-
- if(n > ether->maxmtu)
- error(Etoobig);
- if(n < ether->minmtu)
- error(Etoosmall);
- bp = allocb(n);
- if(waserror()){
- freeb(bp);
- nexterror();
- }
- memmove(bp->rp, buf, n);
- memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen);
- bp->wp += n;
- poperror();
-
- l = etheroq(ether, bp);
-out:
- poperror();
- runlock(ether);
- return l;
-}
-
-static long
-etherbwrite(Chan* chan, Block* bp, ulong)
-{
- Ether *ether;
- long n;
-
- n = BLEN(bp);
- if(NETTYPE(chan->qid.path) != Ndataqid){
- if(waserror()) {
- freeb(bp);
- nexterror();
- }
- n = etherwrite(chan, bp->rp, n, 0);
- poperror();
- freeb(bp);
- return n;
- }
- ether = etherxx[chan->dev];
- rlock(ether);
- if(waserror()) {
- runlock(ether);
- nexterror();
- }
- if(n > ether->maxmtu){
- freeb(bp);
- error(Etoobig);
- }
- if(n < ether->minmtu){
- freeb(bp);
- error(Etoosmall);
- }
- n = etheroq(ether, bp);
- poperror();
- runlock(ether);
- return n;
-}
-
-static struct {
- char* type;
- int (*reset)(Ether*);
-} cards[MaxEther+1];
-
-void
-addethercard(char* t, int (*r)(Ether*))
-{
- static int ncard;
-
- if(ncard == MaxEther)
- panic("too many ether cards");
- cards[ncard].type = t;
- cards[ncard].reset = r;
- ncard++;
-}
-
-int
-parseether(uchar *to, char *from)
-{
- char nip[4];
- char *p;
- int i;
-
- p = from;
- for(i = 0; i < Eaddrlen; i++){
- if(*p == 0)
- return -1;
- nip[0] = *p++;
- if(*p == 0)
- return -1;
- nip[1] = *p++;
- nip[2] = 0;
- to[i] = strtoul(nip, 0, 16);
- if(*p == ':')
- p++;
- }
- return 0;
-}
-
-static void
-etherreset(void)
-{
- Ether *ether;
- int i, n, ctlrno;
- char name[KNAMELEN], buf[128];
-
- for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){
- if(ether == 0)
- ether = malloc(sizeof(Ether));
- memset(ether, 0, sizeof(Ether));
- ether->ctlrno = ctlrno;
- ether->mbps = 10;
- ether->minmtu = ETHERMINTU;
- ether->maxmtu = ETHERMAXTU;
- ether->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, &ether->opt[i][3]) == -1)
- memset(ether->ea, 0, Eaddrlen);
- }else if(cistrcmp(ether->opt[i], "fullduplex") == 0 ||
- cistrcmp(ether->opt[i], "10BASE-TFD") == 0)
- ether->fullduplex = 1;
- else if(cistrcmp(ether->opt[i], "100BASE-TXFD") == 0)
- ether->mbps = 100;
- }
- if(cards[n].reset(ether))
- break;
- snprint(name, sizeof(name), "ether%d", ctlrno);
-
- if(ether->interrupt != nil)
- intrenable(ether->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<<Tmr1Trl_s) | (256<<Tmr1Tur_s); /* TO DO: validate these sizes */
- em->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)<<TrtrTrt_s; /* transmission threshold (probably could be smaller) */
- em->rwmr = (32<<RwmrRlwm_s) | (128<<RwmrRhwm_s); /* receive low/high water mark (TO DO: check) */
- /* 0x0f002000? */
- //dumpemac(em);
- //dumpmal();
- eieio();
- em->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<<NGuardBits),
-
- SingleExpBias = 127,
- SingleExpMax = 255,
- DoubleExpBias = 1023,
- DoubleExpMax = 2047,
-
- ExpBias = DoubleExpBias,
- ExpInfinity = DoubleExpMax,
-};
-
-typedef struct {
- unsigned char s;
- short e;
- long l; /* 0000FFFFFFFFFFFFFFFFFFFFFFFFFGGG */
- long h; /* 0000HFFFFFFFFFFFFFFFFFFFFFFFFFFF */
-} Internal;
-
-#define IsWeird(n) ((n)->e >= ExpInfinity)
-#define IsInfinity(n) (IsWeird(n) && (n)->h == HiddenBit && (n)->l == 0)
-#define SetInfinity(n) ((n)->e = ExpInfinity, (n)->h = HiddenBit, (n)->l = 0)
-#define IsNaN(n) (IsWeird(n) && (((n)->h & ~HiddenBit) || (n)->l))
-#define SetQNaN(n) ((n)->s = 0, (n)->e = ExpInfinity, \
- (n)->h = HiddenBit|(LsBit<<1), (n)->l = 0)
-#define IsZero(n) ((n)->e == 1 && (n)->h == 0 && (n)->l == 0)
-#define SetZero(n) ((n)->e = 1, (n)->h = 0, (n)->l = 0)
-
-/*
- * fpi.c
- */
-extern void fpiround(Internal *);
-extern void fpiadd(Internal *, Internal *, Internal *);
-extern void fpisub(Internal *, Internal *, Internal *);
-extern void fpimul(Internal *, Internal *, Internal *);
-extern void fpidiv(Internal *, Internal *, Internal *);
-extern int fpicmp(Internal *, Internal *);
-extern void fpinormalise(Internal*);
-
-/*
- * fpimem.c
- */
-extern void fpis2i(Internal *, void *);
-extern void fpid2i(Internal *, void *);
-extern void fpiw2i(Internal *, void *);
-extern void fpii2s(void *, Internal *);
-extern void fpii2d(void *, Internal *);
-extern void fpii2w(Word *, Internal *);
diff --git a/os/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; i<nb; i++)
- iic->mdbuf = *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<<m->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; i<Nrxchan; i++){
- putdcr(RCBS(i), 0);
- putdcr(RXCTPR(i), 0);
- }
- for(i=0; i<Ntxchan; i++)
- putdcr(TXCTPR(i), 0);
-
- putdcr(Cfg, (0xF<<CfgPlbt_s)|CfgPlbb); /* TO DO: check */
-
- /* Ier */
- intrenable(VectorMALSERR, errorintr, nil, BUSUNKNOWN, "malserr");
- intrenable(VectorMALTXDE, errorintr, nil, BUSUNKNOWN, "maltxde");
- intrenable(VectorMALRXDE, errorintr, nil, BUSUNKNOWN, "malrxde");
- intrenable(VectorMALTXEOB, txinterrupt, nil, BUSUNKNOWN, "maltxeob");
- intrenable(VectorMALRXEOB, rxinterrupt, nil, BUSUNKNOWN, "malrxeob");
- putdcr(Ier, EsrDei | EsrOnei | EsrOtei | EsrOsei | EsrPbei);
-}
-
-Mal*
-malchannel(int n, int tx, void (*intr)(Ureg*, void*), void *arg)
-{
- Mal *ml;
-
- if((ml = malchans[tx][n]) == nil){
- ml = malloc(sizeof(*m));
- malchans[tx][n] = ml;
- }
- ml->n = 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<Nrxchan; i++)
- iprint("Rxctpr[%d]=%8.8lux Rcbs[%d]=%8.8lux\n", i, getdcr(RXCTPR(i)), i, getdcr(RCBS(i)));
- for(i=0;i<Ntxchan; i++)
- iprint("Txctpr[%d]=%8.8lux\n", i, getdcr(TXCTPR(i)));
-}
diff --git a/os/cerf405/mem.h b/os/cerf405/mem.h
deleted file mode 100644
index fa0aa82b..00000000
--- a/os/cerf405/mem.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Memory and machine-specific definitions. Used in C and assembler.
- */
-
-/*
- * Sizes
- */
-
-#define BI2BY 8 /* bits per byte */
-#define BI2WD 32 /* bits per word */
-#define BY2WD 4 /* bytes per word */
-#define BY2V 8 /* bytes per double word */
-#define BY2PG 4096 /* bytes per page */
-#define WD2PG (BY2PG/BY2WD) /* words per page */
-#define PGSHIFT 12 /* log(BY2PG) */
-#define ROUND(s, sz) (((s)+(sz-1))&~(sz-1))
-#define PGROUND(s) ROUND(s, BY2PG)
-#define CACHELINELOG 5
-#define CACHELINESZ (1<<CACHELINELOG)
-#define CACHESIZE 16384
-#define CACHEWAYSIZE (CACHESIZE/2) /* 2-way set associative */
-
-#define MAXMACH 1 /* max # cpus system can run */
-#define MACHSIZE BY2PG
-
-/*
- * Time
- */
-#define HZ 100 /* clock frequency */
-#define MS2HZ (1000/HZ) /* millisec per clock tick */
-#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
-#define MS2TK(t) ((t)/MS2HZ) /* milliseconds to ticks */
-#define MHz 1000000
-
-/*
- * 4xx MSR bits
- */
-
-#define MSR_WE 0x40000 /* wait state enable */
-#define MSR_CE 0x20000 /* critical interrupt enable */
-#define MSR_EE 0x08000 /* enable external/decrementer interrupts */
-#define MSR_PR 0x04000 /* =1, user mode */
-#define MSR_ME 0x01000 /* enable machine check exceptions */
-#define MSR_DWE 0x00400 /* debug wait enable */
-#define MSR_DE 0x00200 /* debug interrupts enable */
-#define MSR_IR 0x00020 /* enable instruction address translation */
-#define MSR_DR 0x00010 /* enable data address translation */
-
-#define KMSR (MSR_ME)
-#define UMSR (MSR_PR|MSR_DE|MSR_CE|MSR_EE|MSR_IR|MSR_DR)
-
-/*
- * Magic registers
- */
-
-#define MACH 30 /* R30 is m-> */
-#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; i<nelem(halloc.ivec) && n < bsize; i++)
- if((h = halloc.ivec[i]) != nil && h->nintr)
- 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<<i))
- s = fpcause[i];
- if(s == 0)
- return "no floating point exception";
- sprint(buf, "%s fppc=0x%lux", s, fppc);
- return buf;
-}
-
-#define KERNPC(x) (KTZERO<(ulong)(x)&&(ulong)(x)<(ulong)etext)
-
-void
-kernfault(Ureg *ur, int code)
-{
- Label l;
-
- print("panic: kfault %s dear=0x%lux esr=0x%8.8lux\n", excname[code], getdear(), getesr());
- print("u=0x%lux status=0x%lux pc=0x%lux sp=0x%lux\n",
- up, ur->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; i<sizeof regname/sizeof(char*); i+=2, l+=2)
- print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
-}
-
-static void
-linkproc(void)
-{
- spllo();
- (*up->kpfun)(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)
-{
-}