Browse Source

Plan 9 from Bell Labs 2009-11-25

David du Colombier 10 years ago
parent
commit
74fa9dc6ab

+ 2 - 0
arm/bin/ape/psh

@@ -0,0 +1,2 @@
+#!/bin/rc
+exec /rc/bin/ape/psh $*

+ 2 - 81
sys/src/9/ip/ip.c

@@ -7,87 +7,8 @@
 
 #include	"ip.h"
 
-typedef struct IP		IP;
-typedef struct Fragment4	Fragment4;
-typedef struct Fragment6	Fragment6;
-typedef struct Ipfrag		Ipfrag;
-
 #define BLKIPVER(xp)	(((Ip4hdr*)((xp)->rp))->vihl&0xF0)
 
-/* MIB II counters */
-enum
-{
-	Forwarding,
-	DefaultTTL,
-	InReceives,
-	InHdrErrors,
-	InAddrErrors,
-	ForwDatagrams,
-	InUnknownProtos,
-	InDiscards,
-	InDelivers,
-	OutRequests,
-	OutDiscards,
-	OutNoRoutes,
-	ReasmTimeout,
-	ReasmReqds,
-	ReasmOKs,
-	ReasmFails,
-	FragOKs,
-	FragFails,
-	FragCreates,
-
-	Nstats,
-};
-
-struct Fragment4
-{
-	Block*	blist;
-	Fragment4*	next;
-	ulong 	src;
-	ulong 	dst;
-	ushort	id;
-	ulong 	age;
-};
-
-struct Fragment6
-{
-	Block*	blist;
-	Fragment6*	next;
-	uchar 	src[IPaddrlen];
-	uchar 	dst[IPaddrlen];
-	uint	id;
-	ulong 	age;
-};
-
-struct Ipfrag
-{
-	ushort	foff;
-	ushort	flen;
-
-	uchar	payload[];
-};
-
-#define IPFRAGSZ offsetof(Ipfrag, payload[0])
-
-/* an instance of IP */
-struct IP
-{
-	ulong		stats[Nstats];
-
-	QLock		fraglock4;
-	Fragment4*	flisthead4;
-	Fragment4*	fragfree4;
-	Ref		id4;
-
-	QLock		fraglock6;
-	Fragment6*	flisthead6;
-	Fragment6*	fragfree6;
-	Ref		id6;
-
-	int		iprouting;	/* true if we route like a gateway */
-};
-
 static char *statnames[] =
 {
 [Forwarding]	"Forwarding",
@@ -542,8 +463,8 @@ ipstats(Fs *f, char *buf, int len)
 
 	p = buf;
 	e = p+len;
-	for(i = 0; i < Nstats; i++)
-		p = seprint(p, e, "%s: %lud\n", statnames[i], ip->stats[i]);
+	for(i = 0; i < Nipstats; i++)
+		p = seprint(p, e, "%s: %llud\n", statnames[i], ip->stats[i]);
 	return p - buf;
 }
 

+ 78 - 1
sys/src/9/ip/ip.h

@@ -1,8 +1,12 @@
 typedef struct	Conv	Conv;
+typedef struct	Fragment4 Fragment4;
+typedef struct	Fragment6 Fragment6;
 typedef struct	Fs	Fs;
 typedef union	Hwaddr	Hwaddr;
 typedef struct	IP	IP;
 typedef struct	IPaux	IPaux;
+typedef struct	Ip4hdr	Ip4hdr;
+typedef struct	Ipfrag	Ipfrag;
 typedef struct	Ipself	Ipself;
 typedef struct	Ipselftab	Ipselftab;
 typedef struct	Iplink	Iplink;
@@ -72,8 +76,81 @@ enum
 	Connected=	4,
 };
 
+/* MIB II counters */
+enum
+{
+	Forwarding,
+	DefaultTTL,
+	InReceives,
+	InHdrErrors,
+	InAddrErrors,
+	ForwDatagrams,
+	InUnknownProtos,
+	InDiscards,
+	InDelivers,
+	OutRequests,
+	OutDiscards,
+	OutNoRoutes,
+	ReasmTimeout,
+	ReasmReqds,
+	ReasmOKs,
+	ReasmFails,
+	FragOKs,
+	FragFails,
+	FragCreates,
+
+	Nipstats,
+};
+
+struct Fragment4
+{
+	Block*	blist;
+	Fragment4*	next;
+	ulong 	src;
+	ulong 	dst;
+	ushort	id;
+	ulong 	age;
+};
+
+struct Fragment6
+{
+	Block*	blist;
+	Fragment6*	next;
+	uchar 	src[IPaddrlen];
+	uchar 	dst[IPaddrlen];
+	uint	id;
+	ulong 	age;
+};
+
+struct Ipfrag
+{
+	ushort	foff;
+	ushort	flen;
+
+	uchar	payload[];
+};
+
+#define IPFRAGSZ offsetof(Ipfrag, payload[0])
+
+/* an instance of IP */
+struct IP
+{
+	uvlong		stats[Nipstats];
+
+	QLock		fraglock4;
+	Fragment4*	flisthead4;
+	Fragment4*	fragfree4;
+	Ref		id4;
+
+	QLock		fraglock6;
+	Fragment6*	flisthead6;
+	Fragment6*	fragfree6;
+	Ref		id6;
+
+	int		iprouting;	/* true if we route like a gateway */
+};
+
 /* on the wire packet header */
-typedef struct Ip4hdr		Ip4hdr;
 struct Ip4hdr
 {
 	uchar	vihl;		/* Version and header length */

+ 0 - 102
sys/src/9/ip/ipv6.c

@@ -20,11 +20,6 @@ enum
  */
 #define BKFG(xp)	((Ipfrag*)((xp)->base))
 
-typedef struct	IP	IP;
-typedef struct	Fragment4	Fragment4;
-typedef struct	Fragment6	Fragment6;
-typedef struct	Ipfrag	Ipfrag;
-
 Block*		ip6reassemble(IP*, int, Block*, Ip6hdr*);
 Fragment6*	ipfragallo6(IP*);
 void		ipfragfree6(IP*, Fragment6*);
@@ -32,103 +27,6 @@ Block*		procopts(Block *bp);
 static Block*	procxtns(IP *ip, Block *bp, int doreasm);
 int		unfraglen(Block *bp, uchar *nexthdr, int setfh);
 
-/* MIB II counters */
-enum
-{
-	Forwarding,
-	DefaultTTL,
-	InReceives,
-	InHdrErrors,
-	InAddrErrors,
-	ForwDatagrams,
-	InUnknownProtos,
-	InDiscards,
-	InDelivers,
-	OutRequests,
-	OutDiscards,
-	OutNoRoutes,
-	ReasmTimeout,
-	ReasmReqds,
-	ReasmOKs,
-	ReasmFails,
-	FragOKs,
-	FragFails,
-	FragCreates,
-
-	Nstats,
-};
-
-static char *statnames[] =
-{
-[Forwarding]	"Forwarding",
-[DefaultTTL]	"DefaultTTL",
-[InReceives]	"InReceives",
-[InHdrErrors]	"InHdrErrors",
-[InAddrErrors]	"InAddrErrors",
-[ForwDatagrams]	"ForwDatagrams",
-[InUnknownProtos]	"InUnknownProtos",
-[InDiscards]	"InDiscards",
-[InDelivers]	"InDelivers",
-[OutRequests]	"OutRequests",
-[OutDiscards]	"OutDiscards",
-[OutNoRoutes]	"OutNoRoutes",
-[ReasmTimeout]	"ReasmTimeout",
-[ReasmReqds]	"ReasmReqds",
-[ReasmOKs]	"ReasmOKs",
-[ReasmFails]	"ReasmFails",
-[FragOKs]	"FragOKs",
-[FragFails]	"FragFails",
-[FragCreates]	"FragCreates",
-};
-
-struct Fragment4
-{
-	Block*	blist;
-	Fragment4*	next;
-	ulong 	src;
-	ulong 	dst;
-	ushort	id;
-	ulong 	age;
-};
-
-struct Fragment6
-{
-	Block*	blist;
-	Fragment6*	next;
-	uchar 	src[IPaddrlen];
-	uchar 	dst[IPaddrlen];
-	uint	id;
-	ulong 	age;
-};
-
-struct Ipfrag
-{
-	ushort	foff;
-	ushort	flen;
-
-	uchar	payload[];
-};
-
-#define IPFRAGSZ offsetof(Ipfrag, payload[0])
-
-/* an instance of IP */
-struct IP
-{
-	ulong		stats[Nstats];
-
-	QLock		fraglock4;
-	Fragment4*	flisthead4;
-	Fragment4*	fragfree4;
-	Ref		id4;
-
-	QLock		fraglock6;
-	Fragment6*	flisthead6;
-	Fragment6*	fragfree6;
-	Ref		id6;
-
-	int		iprouting;	/* true if we route like a gateway */
-};
-
 int
 ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c)
 {

+ 2 - 2
sys/src/9/ip/tcp.c

@@ -349,7 +349,7 @@ struct Tcppriv
 	QLock	apl;
 	int	ackprocstarted;
 
-	ulong	stats[Nstats];
+	uvlong	stats[Nstats];
 };
 
 /*
@@ -3124,7 +3124,7 @@ tcpstats(Proto *tcp, char *buf, int len)
 	p = buf;
 	e = p+len;
 	for(i = 0; i < Nstats; i++)
-		p = seprint(p, e, "%s: %lud\n", statnames[i], priv->stats[i]);
+		p = seprint(p, e, "%s: %llud\n", statnames[i], priv->stats[i]);
 	return p - buf;
 }
 

+ 4 - 3
sys/src/9/ip/udp.c

@@ -72,10 +72,10 @@ struct Udp6hdr {
 typedef struct Udpstats Udpstats;
 struct Udpstats
 {
-	ulong	udpInDatagrams;
+	uvlong	udpInDatagrams;
 	ulong	udpNoPorts;
 	ulong	udpInErrors;
-	ulong	udpOutDatagrams;
+	uvlong	udpOutDatagrams;
 };
 
 typedef struct Udppriv Udppriv;
@@ -587,7 +587,8 @@ udpstats(Proto *udp, char *buf, int len)
 	Udppriv *upriv;
 
 	upriv = udp->priv;
-	return snprint(buf, len, "InDatagrams: %lud\nNoPorts: %lud\nInErrors: %lud\nOutDatagrams: %lud\n",
+	return snprint(buf, len, "InDatagrams: %llud\nNoPorts: %lud\n"
+		"InErrors: %lud\nOutDatagrams: %llud\n",
 		upriv->ustats.udpInDatagrams,
 		upriv->ustats.udpNoPorts,
 		upriv->ustats.udpInErrors,

+ 25 - 11
sys/src/9/kw/archkw.c

@@ -173,30 +173,43 @@ archether(unsigned ctlno, Ether *ether)
 }
 
 /* LED/USB gpios */
-enum
-{
-	SheevaOEValLow	= 1<<29,        /* USB_PWEN low */
-	SheevaOEValHigh	= 1<<17,        /* LED pin high */
-	SheevaOELow	= ~0,
-	SheevaOEHigh	= ~0,
+enum {
+	/*
+	 * the bit assignments are MPP pin numbers from the last page of the
+	 * sheevaplug 6.0.1 schematic.
+	 */
+	KWOEValHigh	= 1<<(49-32),	/* pin 49: LED pin */
+	KWOEValLow	= 1<<29,	/* pin 29: USB_PWEN, pin 28: usb_pwerr */
+	KWOELow		= ~0,
+	KWOEHigh	= ~0,
 };
 
 /* called early in main */
 void
 archreset(void)
 {
+	ulong clocks;
+	CpucsReg *cpu;
+
 	/* watchdog disabled */
 	TIMERREG->ctl = 0;
 
 	/* configure gpios */
-	((GpioReg*)AddrGpio0)->dataout = SheevaOEValLow;
-	((GpioReg*)AddrGpio0)->dataoutena = SheevaOELow;
+	((GpioReg*)AddrGpio0)->dataout = KWOEValLow;
+	((GpioReg*)AddrGpio0)->dataoutena = KWOELow;
 
-	((GpioReg*)AddrGpio1)->dataout = SheevaOEValHigh;
-	((GpioReg*)AddrGpio1)->dataoutena = SheevaOEHigh;
+	((GpioReg*)AddrGpio1)->dataout = KWOEValHigh;
+	((GpioReg*)AddrGpio1)->dataoutena = KWOEHigh;
 	coherence();
 
-	CPUCSREG->l2cfg &= ~L2on;
+	cpu = CPUCSREG;
+	cpu->mempm = 0;			/* turn everything on */
+	coherence();
+	clocks = (1<<10) - 1;
+	clocks |= ((1<<21) - 1) & ~((1<<14) - 1);
+	clocks &= ~(1<<18 | 1<<1);	/* reserved bits */
+	cpu->clockgate |= clocks;	/* enable all the clocks */
+	cpu->l2cfg &= ~L2on;
 	coherence();
 }
 
@@ -209,6 +222,7 @@ archreboot(void)
 	CPUCSREG->rstout = RstoutSoft;
 	CPUCSREG->softreset = ResetSystem;
 	CPUCSREG->cpucsr = Reset;
+	coherence();
 	delay(500);
 
 	splhi();

+ 5 - 1
sys/src/9/kw/clock.c

@@ -1,5 +1,5 @@
 /*
- * sheevaplug clock
+ * kirkwood clock
  */
 #include "u.h"
 #include "../port/lib.h"
@@ -30,6 +30,7 @@ clockinit(void)
 	TimerReg *tmr = TIMERREG;
 
 	tmr->ctl = 0;
+	coherence();
 	intrenable(Irqbridge, IRQcputimer0, clockintr, nil, "clock");
 
 	s = spllo();			/* risky */
@@ -42,6 +43,7 @@ clockinit(void)
 
 	tmr->timer0 = Tcycles;
 	tmr->ctl = Tmr0enable;		/* just once */
+	coherence();
 
 	s = spllo();			/* risky */
 	/* one iteration seems to take about 40 ns. */
@@ -60,9 +62,11 @@ clockinit(void)
 	}
 
 	tmr->ctl = 0;
+	coherence();
 	tmr->timer0  = Tcycles;
 	tmr->reload0 = Tcycles;
 	tmr->ctl = Tmr0enable | Tmr0periodic;
+	coherence();
 }
 
 void

+ 1 - 0
sys/src/9/kw/dat.h

@@ -80,6 +80,7 @@ struct Conf
 {
 	ulong	nmach;		/* processors */
 	ulong	nproc;		/* processes */
+	ulong	monitor;	/* has monitor? */
 	Confmem	mem[1];		/* physical memory */
 	ulong	npage;		/* total physical pages of memory */
 	usize	upages;		/* user page pool */

+ 0 - 1
sys/src/9/kw/etherif.h

@@ -28,7 +28,6 @@ struct Ether {
 	int	pcmslot;		/* PCMCIA */
 	int	fullduplex;		/* non-zero if full duplex */
 	int	linkchg;		/* link status changed? */
-	int	mcaston;		/* multicast ever enabled? */
 	uvlong	starttime;		/* last activity time */
 
 	Queue*	oq;

+ 69 - 43
sys/src/9/kw/etherkw.c

@@ -1,7 +1,8 @@
 /*
  * marvell kirkwood ethernet (88e1116) driver
  * (as found in the sheevaplug & openrd).
- * from /public/doc/marvell/sheeva/88f61xx.kirkwood.pdf
+ * from /public/doc/marvell/88f61xx.kirkwood.pdf
+ * and  /public/doc/marvell/88e1116.pdf.
  */
 
 #include "u.h"
@@ -832,7 +833,7 @@ interrupt(Ureg*, void *arg)
 			iprint("etherkw: interrupt cause unknown; "
 				"irq %#lux irqe %#lux\n", irq, irqe);
 	}
-	intrclear(Irqlo, IRQ0gbe0sum);
+	intrclear(Irqlo, ether->irq);
 }
 
 void
@@ -872,6 +873,7 @@ shutdown(Ether *ether)
 	reg->psc0 = 0;			/* no PSC0porton */
 	reg->psc1 |= PSC1portreset;
 	iunlock(ctlr);
+	coherence();
 	delay(100);
 }
 
@@ -955,19 +957,16 @@ miird(Mii *mii, int pa, int ra)
 	ctlr = (Ctlr*)mii->ctlr;
 	reg = ctlr->reg;
 
-	/* check to read params */
-	if (pa == 0xEE && ra == 0xEE)
-		return reg->phy & 0xff;
-
 	/* check params */
-	if (((pa<<Physmiaddroff) & ~Physmiaddrmask) ||
-	    ((ra<<SmiRegaddroff) & ~SmiRegaddrmask))
+	if ((pa<<Physmiaddroff) & ~Physmiaddrmask ||
+	    (ra<<SmiRegaddroff) & ~SmiRegaddrmask)
 		return -1;
 
 	smibusywait(reg, PhysmiBusy);
 
-	/* fill the phy address and regiser offset and read opcode */
+	/* fill the phy address and register offset and read opcode */
 	reg->smi = pa << Physmiaddroff | ra << SmiRegaddroff | PhysmiopRd;
+	coherence();
 
 	/* wait til read value is ready */
 //	if (smibusywait(reg, PhysmiReadok) < 0)
@@ -979,7 +978,6 @@ miird(Mii *mii, int pa, int ra)
 			MIIDBG("SMI read-valid timeout\n");
 			return -1;
 		}
-//		delay(1);
 	} while (!(smi_reg & PhysmiReadok));
 
 	/* Wait for the data to update in the SMI register */
@@ -1007,8 +1005,8 @@ miiwr(Mii *mii, int pa, int ra, int v)
 
 	/* fill the phy address and register offset and read opcode */
 	smi_reg = v << Physmidataoff | pa << Physmiaddroff | ra << SmiRegaddroff;
-	smi_reg &= ~PhysmiopRd;
-	reg->smi = smi_reg;
+	reg->smi = smi_reg & ~PhysmiopRd;
+	coherence();
 	return 0;
 }
 
@@ -1027,21 +1025,15 @@ kirkwoodmii(Ether *ether)
 	ctlr->mii->mir = miird;
 	ctlr->mii->miw = miiwr;
 
-	phy = nil;
 	if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
-		iprint("#l%d: etherkw: init mii failure\n", ether->ctlrno);
-		if (phy)
-			iprint("#l%d: etherkw: mii(...,~0) failed\n",
-				ether->ctlrno);
-		else
-			iprint("#l%d: etherkw: nil ctlr->mii->curphy\n",
-				ether->ctlrno);
+		print("#l%d: etherkw: init mii failure\n", ether->ctlrno);
 		free(ctlr->mii);
 		ctlr->mii = nil;
 		return -1;
 	}
 
-	MIIDBG("oui %X phyno %d\n", phy->oui, phy->phyno);
+	/* oui 005043 is marvell */
+	MIIDBG("oui %#X phyno %d\n", phy->oui, phy->phyno);
 	if(miistatus(ctlr->mii) < 0){
 		miireset(ctlr->mii);
 		MIIDBG("miireset\n");
@@ -1070,34 +1062,58 @@ kirkwoodmii(Ether *ether)
 	}
 
 	ether->mbps = phy->speed;
-//	iprint("etherkw: mii: fd=%d speed=%d tfc=%d rfc=%d\n",
+//	iprint("#l%d: kirkwoodmii: 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;
 }
 
+enum {						/* PHY register pages */
+	Pagcopper,
+	Pagfiber,
+	Pagrgmii,
+	Pagled,
+	Pagrsvd1,
+	Pagvct,
+	Pagtest,
+	Pagrsvd2,
+	Pagfactest,
+};
+
+static void
+miiregpage(Mii *mii, ulong dev, ulong page)
+{
+	miiwr(mii, dev, Eadr, page);
+}
+
 static int
-miiphyinit(Mii *mii)			/* magic numbers 'r' us */
+miiphyinit(Mii *mii)
 {
 	ulong dev;
+	Ctlr *ctlr;
+	Gbereg *reg;
 
-	/* select mii phy */
-	dev = miird(mii, 0xEE, 0xEE);		/* device address */
-//	print("dev %lux\n", dev);
-	if (dev == -1) {
-		print("etherkw: can't read PHY dev address\n");
-		return -1;
-	}
+	ctlr = (Ctlr*)mii->ctlr;
+	reg = ctlr->reg;
+	dev = reg->phy;
+	MIIDBG("phy dev addr %lux\n", dev);
 
 	/* leds link & activity */
-	miiwr(mii, dev, 22, 0x3);
-	miiwr(mii, dev, 10, (miird(mii, dev, 10) & ~0xf) | 1);	/* magic */
-	miiwr(mii, dev, 22, 0);
+	miiregpage(mii, dev, Pagled);
+	/* low 4 bits == 1: on - link, blink - activity, off - no link */
+	miiwr(mii, dev, Scr, (miird(mii, dev, Scr) & ~0xf) | 1);
+
+	miiregpage(mii, dev, Pagrgmii);
+	miiwr(mii, dev, Scr, miird(mii, dev, Scr) | Rgmiipwrup);
+	/* must now do a software reset, sez the manual */
 
 	/* enable RGMII delay on Tx and Rx for CPU port */
-	miiwr(mii, dev, 22, 2);
-	miiwr(mii, dev, 21, miird(mii, dev, 21) | 1<<5 | 1<<4);	/* magic */
-	miiwr(mii, dev, 22, 0);
+	miiwr(mii, dev, Recr, miird(mii, dev, Recr) | Rxtiming | Rxtiming);
+
+	miiregpage(mii, dev, Pagcopper);
+	miiwr(mii, dev, Scr,
+		(miird(mii, dev, Scr) & ~(Pwrdown|Endetect)) | Mdix);
+
 	return 0;
 }
 
@@ -1129,6 +1145,7 @@ portreset(Gbereg *reg)
 	quiesce(reg);
 	reg->psc0 &= ~PSC0porton;		/* disable port */
 	reg->psc1 &= ~(PSC1rgmii|PSC1portreset); /* set port & MII active */
+	coherence();
 	for (i = 0; i < 4000; i++)		/* magic delay */
 		;
 }
@@ -1175,6 +1192,7 @@ archetheraddr(Ether *ether, Gbereg *reg, int rxqno)
 	/* accept all multicast too.  set up special & other tables. */
 	memset(reg->dfsmt, Qno<<1 | Pass, sizeof reg->dfsmt);
 	memset(reg->dfomt, Qno<<1 | Pass, sizeof reg->dfomt);
+	coherence();
 }
 
 static void
@@ -1285,6 +1303,7 @@ ctlrinit(Ether *ether)
 	reg->pmtu = 0;
 
 	reg->rqc = Rxqon(Qno);
+	coherence();
 	etheractive(ether);
 
 	snprint(name, sizeof name, "#l%drproc", ether->ctlrno);
@@ -1362,7 +1381,6 @@ ifstat(Ether *ether, void *a, long n, ulong off)
 	e = p + READSTR;
 
 	ilock(ctlr);
-
 	getmibstats(ctlr);
 
 	ctlr->intrs += ctlr->newintrs;
@@ -1427,16 +1445,17 @@ static int
 reset(Ether *ether)
 {
 	Ctlr *ctlr;
+	static uchar zeroea[Eaddrlen];
 
-	ctlr = malloc(sizeof *ctlr);
-	memset(ctlr, 0, sizeof *ctlr);
-	ether->ctlr = ctlr;
+	ether->ctlr = ctlr = malloc(sizeof *ctlr);
 	switch(ether->ctlrno) {
 	case 0:
 		ctlr->reg = (Gbereg*)Gbe0regs;
+		ether->irq = IRQ0gbe0sum;
 		break;
 	case 1:
 		ctlr->reg = (Gbereg*)Gbe1regs;
+		ether->irq = IRQ0gbe1sum;
 		break;
 	default:
 		panic("etherkw: bad ether ctlr #%d", ether->ctlrno);
@@ -1446,21 +1465,28 @@ reset(Ether *ether)
 //	*(ulong *)0xf10100e0 |= 1 << 7 | 1 << 15;
 
 	portreset(ctlr->reg);
+	/* ensure that both interfaces are set to RGMII before calling mii */
+	((Gbereg*)Gbe0regs)->psc1 |= PSC1rgmii;
+	((Gbereg*)Gbe1regs)->psc1 |= PSC1rgmii;
 
 	/* Set phy address of the port */
 	ctlr->port = ether->ctlrno;
 	ctlr->reg->phy = ether->ctlrno;
+	coherence();
 	ether->port = (uintptr)ctlr->reg;
-	ether->irq = IRQ0gbe0sum;
 
 	if(kirkwoodmii(ether) < 0){
 		free(ctlr);
 		ether->ctlr = nil;
 		return -1;
 	}
-	miiphyinit(ctlr->mii);			/* commented-out in inferno */
+	miiphyinit(ctlr->mii);
 	archetheraddr(ether, ctlr->reg, Qno);	/* original location */
-
+	if (memcmp(ether->ea, zeroea, sizeof zeroea) == 0){
+		free(ctlr);
+		ether->ctlr = nil;
+		return -1;			/* no rj45 for this ether */
+	}
 	ether->attach = attach;
 	ether->transmit = transmit;
 	ether->interrupt = interrupt;

+ 11 - 1
sys/src/9/kw/ethermii.c

@@ -10,6 +10,10 @@
 #include "etherif.h"
 #include "ethermii.h"
 
+/*
+ * on kirkwood (or openrd at least), ether0's phy has address 8,
+ * ether1's is 18.
+ */
 int
 mii(Mii* mii, int mask)
 {
@@ -37,8 +41,14 @@ mii(Mii* mii, int mask)
 		oui = (r & 0x3FFF)<<6;
 		r = mii->mir(mii, phyno, Phyidr2);
 		oui |= r>>10;
+		/*
+		 * for some reason, phyno 18 (ether1's) doesn't report an
+		 * oui of 0x005043 (Marvell), but rather 0xFFFFF.
+		 * for now, workaround it by knowing that 18 is a valid PHY.
+		 */
 		if(oui == 0xFFFFF || oui == 0)
-			continue;
+			if (phyno != 18)
+				continue;
 
 		if((miiphy = malloc(sizeof(MiiPhy))) == nil)
 			continue;

+ 39 - 12
sys/src/9/kw/ethermii.h

@@ -2,18 +2,31 @@ typedef struct Mii Mii;
 typedef struct MiiPhy MiiPhy;
 
 enum {					/* registers */
-	Bmcr		= 0x00,		/* Basic Mode Control */
-	Bmsr		= 0x01,		/* Basic Mode Status */
-	Phyidr1		= 0x02,		/* PHY Identifier #1 */
-	Phyidr2		= 0x03,		/* PHY Identifier #2 */
-	Anar		= 0x04,		/* Auto-Negotiation Advertisement */
-	Anlpar		= 0x05,		/* AN Link Partner Ability */
-	Aner		= 0x06,		/* AN Expansion */
-	Annptr		= 0x07,		/* AN Next Page TX */
-	Annprr		= 0x08,		/* AN Next Page RX */
-	Mscr		= 0x09,		/* MASTER-SLAVE Control */
-	Mssr		= 0x0A,		/* MASTER-SLAVE Status */
-	Esr		= 0x0F,		/* Extended Status */
+	Bmcr		= 0,		/* Basic Mode Control */
+	Bmsr		= 1,		/* Basic Mode Status */
+	Phyidr1		= 2,		/* PHY Identifier #1 */
+	Phyidr2		= 3,		/* PHY Identifier #2 */
+	Anar		= 4,		/* Auto-Negotiation Advertisement */
+	Anlpar		= 5,		/* AN Link Partner Ability */
+	Aner		= 6,		/* AN Expansion */
+	Annptr		= 7,		/* AN Next Page TX */
+	Annprr		= 8,		/* AN Next Page RX */
+	Mscr		= 9,		/* Gb Control */
+	Mssr		= 10,		/* Gb Status */
+	Esr		= 15,		/* Extended Status */
+
+	/* 88e1116-specific paged registers */
+	Scr		= 16,		/* special control register */
+	Ssr		= 17,		/* special status register */
+	Ier		= 18,		/* interrupt enable reg */
+	Isr		= 19,		/* interrupt status reg */
+	Escr		= 20,		/* extended special control reg */
+	Recr		= 21,		/* RX error counter reg */
+	Eadr		= 22,		/* extended address reg (page select) */
+	Globsts		= 23,		/* global status */
+	Impover		= 24,	/* RGMII output impedance override (page 2) */
+	Imptarg		= 25,	/* RGMII output impedance target (page 2) */
+	Scr2		= 26,		/* special control register 2 */
 
 	NMiiPhyr	= 32,
 	NMiiPhy		= 32,
@@ -80,6 +93,20 @@ enum {					/* Esr */
 	Esr1000XFD	= 0x8000,	/* 1000BASE-X FD Capable */
 };
 
+enum {					/* Scr page 0 */
+	Pwrdown		= 0x0004,	/* power down */
+	Mdix		= 0x0060,	/* MDI crossover mode */
+	Endetect	= 0x0300,	/* energy detect */
+};
+enum {					/* Scr page 2 */
+	Rgmiipwrup	= 0x0008,	/* RGMII power up: must sw reset after */
+};
+
+enum {					/* Recr page 2 */
+	Txtiming	= 1<<4,
+	Rxtiming	= 1<<5,
+};
+
 typedef struct Mii {
 	Lock;
 	int	nphy;

+ 1 - 1
sys/src/9/kw/fns.h

@@ -62,7 +62,7 @@ void	procsetup(Proc*);
 extern void _reset(void);
 extern void setr13(int, u32int*);
 #define tas _tas
-extern int _tas(ulong *);
+extern int _tas(void *);
 extern u32int ttbget(void);
 extern void ttbput(u32int);
 

+ 18 - 19
sys/src/9/kw/io.h

@@ -195,7 +195,7 @@ struct Pcidev
 #define ISAWADDR(va)	(PADDR(va)+ISAWINDOW)
 
 /*
- * Sheevaplug stuff
+ * Kirkwood stuff
  */
 
 /* weird padding macro */
@@ -242,18 +242,6 @@ enum {
 	PciINTL		= Addrpci + 0x3c,	/* interrupt line */
 	PciINTP		= PciINTL + 1,	/* interrupt pin */
 };
-enum {
-	/* rstout bits */
-	RstoutPex	= 1<<0,
-	RstoutWatchdog	= 1<<1,
-	RstoutSoft	= 1<<2,
-
-	/* softreset bits */
-	ResetSystem	= 1<<0,
-
-	/* cpucsr bits */
-	Reset		= 1<<1,
-};
 
 /*
  * interrupt stuff
@@ -347,7 +335,7 @@ struct IntrReg
 
 
 /*
- * CPU control & status (archkirkwood.c and trap.c)
+ * CPU control & status (archkw.c and trap.c)
  */
 #define CPUCSREG	((CpucsReg*)AddrCpucsr)
 
@@ -358,10 +346,10 @@ struct CpucsReg
 	ulong	cpucsr;
 	ulong	rstout;
 	ulong	softreset;
-	ulong	irq;
-	ulong	irqmask;
-	ulong	mempm;
-	ulong	clockgate;
+	ulong	irq;		/* mbus(-l) bridge interrupt cause */
+	ulong	irqmask;	/* ⋯ mask */
+	ulong	mempm;		/* memory power mgmt. control */
+	ulong	clockgate;	/* clock enable bits */
 	ulong	biu;
 	ulong	pad0;
 	ulong	l2cfg;		/* turn l2 cache on or off, set coherency */
@@ -381,6 +369,17 @@ enum {
 	Cfgvecinithi	= 1<<1,	/* boot at 0xffff0000, not 0; default 1 */
 	Cfgbigendreset	= 3<<1,	/* init. as big-endian at reset; default 0 */
 
+	/* cpucsr bits */
+	Reset		= 1<<1,
+
+	/* rstout bits */
+	RstoutPex	= 1<<0,
+	RstoutWatchdog	= 1<<1,
+	RstoutSoft	= 1<<2,
+
+	/* softreset bits */
+	ResetSystem	= 1<<0,
+
 	/* l2cfg bits */
 	L2ecc		= 1<<2,
 	L2on		= 1<<3,
@@ -388,7 +387,7 @@ enum {
 };
 
 /*
- * clocks (clock.c and archkirkwood.c)
+ * clocks (clock.c and archkw.c)
  */
 
 enum {

+ 1 - 1
sys/src/9/kw/main.c

@@ -83,7 +83,7 @@ getenv(char* name, char* buf, int n)
 	return nil;
 }
 
-#include <io.h>
+#include "io.h"
 
 typedef struct Spiregs Spiregs;
 struct Spiregs {

+ 1 - 1
sys/src/9/kw/plug.words

@@ -8,7 +8,7 @@ i & d caches 16K each, associativity 4, 32-byte lines, 128 sets
 16550 uart for console
 see http://www.marvell.com/files/products/embedded_processors/kirkwood/\
 	FS_88F6180_9x_6281_OpenSource.pdf, stored locally as
-	/public/doc/marvell/sheeva/88f61xx.kirkwood.pdf
+	/public/doc/marvell/88f61xx.kirkwood.pdf
 
 this plan 9 port is based on the port of native inferno to the
 sheevaplug by Salva Peiró (saoret.one@gmail.com) and Mechiel Lukkien

+ 2 - 2
sys/src/9/port/portmkfile

@@ -35,10 +35,10 @@ clean:V:
 		mk $i.clean
 
 %.clean:V:
-	rm -f $stem.c [9bz]$stem [9bz]$stem.gz boot$stem.* *.acid
+	rm -f $stem.c [9bz]$stem [9bz]$stem.gz s[9bz]$stem boot$stem.* *.acid
 
 nuke:V:	clean
-	rm -f ../boot/libboot.a$O *.elf *.rr s$p$CONF
+	rm -f ../boot/libboot.a$O *.elf *.rr
 
 %.$O:	/$objtype/include/u.h ../port/lib.h mem.h dat.h fns.h io.h ../port/error.h ../port/portdat.h ../port/portfns.h
 

+ 6 - 1
sys/src/ape/cmd/mkfile

@@ -22,7 +22,7 @@ CFLAGS=-c -D_POSIX_SOURCE
 
 all:V:	$DIRS
 
-install:V:	install.dir
+install:V:	install.dir install.rc
 
 installall:V:	installall.dir
 
@@ -49,3 +49,8 @@ cc.$O: cc.c
 
 $O.cc: cc.$O
 	mk -f /sys/src/cmd/mkfile $O.cc
+
+install.rc:V: $BIN/psh
+
+$BIN/%: %.rc
+	cp -x $stem.rc $BIN/$stem

+ 2 - 0
sys/src/ape/cmd/psh.rc

@@ -0,0 +1,2 @@
+#!/bin/rc
+exec /rc/bin/ape/psh $*