code: purgatorio

ref: 76f5318cbd58fbe2bfc8cb51856bfa217c673bb7
dir: /os/boot/mpc/io.h/

View raw version
enum
{
	/* software interrupt vectors (SIU and CPM) */
	VectorPIC= 0,	/* level 0 to level 7, assigned by software */
		CPIClevel=	4,
	VectorIRQ=	VectorPIC+8,	/* IRQ0 to IRQ7 */
	VectorCPIC=	VectorIRQ+8,	/* 32 CPM interrupts: 0 (error) to 0x1F (PC15) */
};

enum
{
	BUSUNKNOWN = 0,
};

/*
 * Buffer Descriptors and IO Rings
 */

typedef struct BD BD;
struct BD {
	ushort	status;
	ushort	length;
	ulong	addr;
};

BD*	bdalloc(int);
void	bdfree(BD*, int);

enum {
	/* Rx BDs, bits common to all protocols */
	BDEmpty=	1<<15,
	BDWrap=		1<<13,
	BDInt=		1<<12,
	BDLast=		1<<11,
	BDFirst=		1<<10,

	/* Tx BDs */
	BDReady=		1<<15,
	/* BDWrap, BDInt, BDLast */
};

typedef struct Ring Ring;
struct Ring {
	BD*	rdr;				/* receive descriptor ring */
	void*	rrb;				/* receive ring buffers */
	int	rdrx;				/* index into rdr */
	int	nrdre;			/* length of rdr */

	BD*	tdr;				/* transmit descriptor ring */
	Block**	txb;				/* corresponding 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))

int	ioringinit(Ring*, int, int, int);

/*
 * CPM
 */
enum {
	/* commands */
	InitRxTx =	0,
	InitRx =		1,
	InitTx =		2,
	EnterHunt=	3,
	StopTx=		4,
	GracefulStopTx = 5,
	InitIDMA =	5,
	RestartTx =	6,
	CloseRxBD =	7,
	SetGroupAddr = 8,
	SetTimer =	8,
	GCITimeout =	9,
	GCIAbort =	10,
	StopIDMA =	11,
	StartDSP = 	12,
	ArmIDMA =	13,
	InitDSP =		13,
	USBCmd =	15,

	/* channel IDs */
	SCC1ID=	0,
	USBID=	0,
	I2CID=	1,
	IDMA1ID= 1,
	SCC2ID=	4,
	SPIID=	5,
	IDMA2ID= 5,
	TIMERID=	5,
	SCC3ID=	8,
	SMC1ID=	9,
	DSP1ID=9,
	SCC4ID=	12,
	SMC2ID=	13,
	DSP2ID=	13,

	BaudEnable = 1<<16,

	/* sicr */
	CLK1 = 4,		/* SCC1,2 */
	CLK2 = 5,
	CLK3 = 6,
	CLK4 = 7,
	CLK5 = CLK1,	/* SCC3,4 */
	CLK6 = CLK2,
	CLK7 = CLK3,
	CLK8 = CLK4,
};

void	cpmop(int, int, int);
#define	ioplock()	(m->iomem)
#define	iopunlock()

/*
 * the structures below follow hardware/firmware layouts in the 8xx manuals:
 * mind the data types, offsets and alignment
 */

/*
 * basic IO controller parameters (SMC and SCC)
 */
typedef struct IOCparam IOCparam;
struct IOCparam {
	ushort	rbase;
	ushort	tbase;
	uchar	rfcr;
	uchar	tfcr;
	ushort	mrblr;
	ulong	rstate;
	ulong	rptr;
	ushort	rbptr;
	ushort	rcnt;
	ulong	rtmp;
	ulong	tstate;
	ulong	tptr;
	ushort	tbptr;
	ushort	tcnt;
	ulong	ttmp;
};

typedef struct SCCparam SCCparam;
struct SCCparam {
	IOCparam;
	ulong	rcrc;
	ulong	tcrc;
};

typedef struct SCC SCC;
struct SCC {
	ulong	gsmrl;
	ulong	gsmrh;
	ushort	psmr;
	uchar	rsvscc0[2];
	ushort	todr;
	ushort	dsr;
	ushort	scce;
	uchar	rsvscc1[2];
	ushort	sccm;
	uchar	rsvscc3;
	uchar	sccs;
	ushort	irmode;
	ushort	irsip;
};

typedef struct SMC SMC;
struct SMC {
	uchar	pad1[2];
	ushort	smcmr;
	uchar	pad2[2];
	uchar	smce;
	uchar	pad3[3];
	uchar	smcm;
	uchar	pad4[5];
};

typedef struct SPI SPI;
struct SPI {
	ushort	spmode;
	uchar	res1[4];
	uchar	spie;
	uchar	res2[3];
	uchar	spim;
	uchar	res3[2];
	uchar	spcom;
	uchar	res4[10];
};

typedef struct USB USB;
struct USB {	/* 823 only */
	uchar	usmod;
	uchar	usadr;
	uchar	uscom;
	uchar	rsvu1;
	ushort	usep[4];
	uchar	rsvu2[4];
	ushort	usber;
	uchar	rsvu3[2];
	ushort	usbmr;
	uchar	rsvu4;
	uchar	usbs;
	uchar	rsvu5[8];
};

typedef struct IMM IMM;
struct IMM {
	struct {	/* general SIU */
		ulong	siumcr;
		ulong	sypcr;
		uchar	rsv0[0xE-0x8];
		ushort	swsr;
		ulong	sipend;
		ulong	simask;
		ulong	siel;
		uchar	sivec;
		uchar	padv[3];
		ulong	tesr;
		uchar	rsv1[0x30-0x24];
		ulong	sdcr;
		uchar	rsv2[0x80-0x34];
	};
	struct {	/* PCMCIA */
		struct {
			ulong	base;
			ulong	option;
		} pcmr[8];
		uchar	rsv3[0xe0-0xc0];
		ulong	pgcra;
		ulong	pgcrb;
		ulong	pscr;
		uchar	rsv4[0xf0-0xec];
		ulong	pipr;
		uchar	rsv5[4];
		ulong	per;
		uchar	rsv6[4];
	};
	struct {	/* MEMC */
		struct {
			ulong	base;
			ulong	option;
		} memc[8];
		uchar	rsv7a[0x24];
		ulong	mar;
		ulong	mcr;
		uchar	rsv7b[4];
		ulong	mamr;
		ulong	mbmr;
		ushort	mstat;
		ushort	mptpr;
		ulong	mdr;
		uchar	rsv7c[0x80];
	};
	struct {	/* system integration timers */
		ushort	tbscr;
		uchar	rsv8a[2];
		ulong	tbrefu;
		ulong	tbrefl;
		uchar	rsv8b[0x14];
		ushort	rtcsc;
		uchar	rsv8c[2];
		ulong	rtc;
		ulong	rtsec;
		ulong	rtcal;
		uchar	rsv8d[0x10];
		ushort	piscr;
		ushort	rsv8e;
		ulong	pitc;
		ulong	pitr;
		uchar	rsv8f[0x34];
	};
	struct {	/* 280: clocks and resets */
		ulong	sccr;
		ulong	plprcr;
		ulong	rsr;
		uchar	rsv9[0x300-0x28c];
	};
	struct {	/* 300: system integration timers keys */
		ulong	tbscrk;
		ulong	tbrefuk;
		ulong	tbreflk;
		ulong	tbk;
		uchar	rsv10a[0x10];
		ulong	rtcsck;
		ulong	rtck;
		ulong	rtseck;
		ulong	rtcalk;
		uchar	rsv10b[0x10];
		ulong	piscrk;
		ulong	pitck;
		uchar	rsv10c[0x38];
	};
	struct {	/* 380: clocks and resets keys */
		ulong	sccrk;
		ulong	plprcrk;
		ulong	rsrk;
		uchar	rsv11[0x800-0x38C];
	};
	struct {	/* 800: video controller */
		ushort	vccr;
		ushort	pad11a;
		uchar	vsr;
		uchar	pad11b;
		uchar	vcmr;
		uchar	pad11c;
		ulong	vbcb;
		ulong	pad11d;
		ulong	vfcr0;
		ulong	vfaa0;
		ulong	vfba0;
		ulong	vfcr1;
		ulong	vfaa1;
		ulong	vfba1;
		uchar	rsv11a[0x840-0x828];
	};
	struct {	/* 840: LCD */
		ulong	lccr;
		ulong	lchcr;
		ulong	lcvcr;
		ulong	rsv11b;
		ulong	lcfaa;
		ulong	lcfba;
		uchar	lcsr;
		uchar	rsv11c[0x860-0x859];
	};
	struct {	/* 860: I2C */
		uchar	i2mod;
		uchar	rsv12a[3];
		uchar	i2add;
		uchar	rsv12b[3];
		uchar	i2brg;
		uchar	rsv12c[3];
		uchar	i2com;
		uchar	rsv12d[3];
		uchar	i2cer;
		uchar	rsv12e[3];
		uchar	i2cmr;
		uchar	rsv12[0x900-0x875];
	};
	struct {	/* 900: DMA */
		uchar	rsv13[4];
		ulong	sdar;
		uchar	sdsr;
		uchar	pad1[3];
		uchar	sdmr;
		uchar	pad2[3];
		uchar	idsr1;
		uchar	pad3[3];
		uchar	idmr1;
		uchar	pad4[3];
		uchar	idsr2;
		uchar	pad5[3];
		uchar	idmr2;
		uchar	pad6[0x930-0x91D];
	};
	struct {	/* CPM interrupt control */
		ushort	civr;
		uchar	pad7[0x940-0x932];
		ulong	cicr;
		ulong	cipr;
		ulong	cimr;
		ulong	cisr;
	};
	struct {	/* input/output port */
		ushort	padir;
		ushort	papar;
		ushort	paodr;
		ushort	padat;
		uchar	pad8[8];
		ushort	pcdir;
		ushort	pcpar;
		ushort	pcso;
		ushort	pcdat;
		ushort	pcint;
		uchar	pad9[6];
		ushort	pddir;
		ushort	pdpar;
		ushort	rsv14a;
		ushort	pddat;
		uchar	rsv14[0x980-0x978];
	};
	struct {	/* CPM timers */
		ushort	tgcr;
		uchar	rsv15a[0x990-0x982];
		ushort	tmr1;
		ushort	tmr2;
		ushort	trr1;
		ushort	trr2;
		ushort	tcr1;
		ushort	tcr2;
		ushort	tcn1;
		ushort	tcn2;
		ushort	tmr3;
		ushort	tmr4;
		ushort	trr3;
		ushort	trr4;
		ushort	tcr3;
		ushort	tcr4;
		ushort	tcn3;
		ushort	tcn4;
		ushort	ter1;
		ushort	ter2;
		ushort	ter3;
		ushort	ter4;
		uchar	rsv15[0x9C0-0x9B8];
	};
	struct {	/* CPM */
		ushort	cpcr;
		uchar	res0[2];
		ushort	rccr;
		uchar	res1;
		uchar	rmds;
		uchar	res2a[4];
		ushort	rctr1;
		ushort	rctr2;
		ushort	rctr3;
		ushort	rctr4;
		uchar	res2[2];
		ushort	rter;
		uchar	res3[2];
		ushort	rtmr;
		uchar	rsv16[0x9F0-0x9DC];
	};
	union {	/* BRG */
		struct {
			ulong	brgc1;
			ulong	brgc2;
			ulong	brgc3;
			ulong	brgc4;
		};
		ulong	brgc[4];
	};
	uchar	skip0[0xAB2-0xA00];	/* USB, SCC, SMC, SPI: address using cpmdev(CP...)->regs */
	struct {	/* PIP */
		ushort	pipc;		/* not 823 */
		ushort	ptpr;		/* not 823 */
		ulong	pbdir;
		ulong	pbpar;
		uchar	pad10[2];
		ushort	pbodr;
		ulong	pbdat;
		uchar	pad11[0xAE0-0xAC8];
	};
	struct {	/* SI */
		ulong	simode;
		uchar	sigmr;
		uchar	pad12;
		uchar	sistr;
		uchar	sicmr;
		uchar	pad13[4];
		ulong	sicr;
		ulong	sirp;
		uchar	pad14[0xB00-0xAF4];
	};
	ulong	vcram[64];
	ushort	siram[256];
	ushort	lcdmap[256];
};