/*
 * $Header: /smsa/bsd:include/arm/xcb.h:bsd  1.11  $
 * $Source: /smsa/bsd:include/arm/xcb.h: $
 *
 * Copyright (c) 1989 Acorn Computers Ltd., Cambridge, England
 *
 */
/* xcb.h
 *
 * Definitions for expansion card bus (XCB, formerly known
 * as "podule") device access.
 */
#ifndef  __arm_xcb_h
#define  __arm_xcb_h
#define  __machine_xcb_h	"arm"

typedef struct
{
    volatile unsigned char
 	id0,		_pad0[3],
	flags,		_pad1[3],
	unused,		_pad2[3],
	product_lo,	_pad3[3],
	product_hi,	_pad4[3],
	company_lo,	_pad5[3],
	company_hi,	_pad6[3],
	country,	_pad7[3];
    union
    {
	volatile char		d_char[4];
	volatile unsigned char	d_uchar[4];
	volatile short		d_short[2];
	volatile unsigned short	d_ushort[2];
	volatile int		d_int;
	volatile unsigned int	d_uint;
    } data[1024-8];
} XCBID, *XCBIDRef;
/* bits in c_id0 field: */
#define XCB_ID0_IRQ		(1   << 0)	/* set if IRQ outstanding */
#define XCB_ID0_NOT_PRESENT	(1   << 1)	/* pull-up gives 1 if slot empty */
#define XCB_ID0_FIQ		(1   << 2)	/* set if FIQ outstanding */
#define XCB_ID0_EXTRA		(0xF8)		/* remaining 5 bits (normally 0) */
#define XCB_ID0_SHORT_ID_MASK	(0xF << 3)	/* short ID bits (normally 0) */
#define XCB_ID0_SHORT_ID__SHIFT		3	/* shift for same */
#define XCB_ID0_NOT_CONFORMANT	(1   << 7)	/* doesn't conform to spec (i.e. unusable) */


/* expansion card source country codes */

#define XCB_COUNTRY_UK		0
#define XCB_COUNTRY_ITALY	4
#define XCB_COUNTRY_SPAIN	5
#define XCB_COUNTRY_FRANCE	6
#define XCB_COUNTRY_GERMANY	7
#define XCB_COUNTRY_PORTUGAL	8
#define XCB_COUNTRY_GREECE	10
#define XCB_COUNTRY_SWEDEN	11
#define XCB_COUNTRY_FINLAND	12
#define XCB_COUNTRY_DENMARK	14
#define XCB_COUNTRY_NORWAY	15
#define XCB_COUNTRY_ICELAND	16
#define XCB_COUNTRY_CANADA	17
#define XCB_COUNTRY_TURKEY	20
#define XCB_COUNTRY_IRELAND	22
#define XCB_COUNTRY_HONGKONG	23

/* expansion card manufacturing company codes */

#define XCB_COMPANY_ACORNUK			0
#define XCB_COMPANY_ACORNUSA			1
#define XCB_COMPANY_OLIVETTI			2
#define XCB_COMPANY_WATFORD			3
#define XCB_COMPANY_COMPUTERCONCEPTS		4
#define XCB_COMPANY_INTELIGENTINTERFACES	5
#define XCB_COMPANY_CAMAN			6
#define XCB_COMPANY_ARMADILLO			7
#define XCB_COMPANY_SOFTOPTION			8
#define XCB_COMPANY_WILDVISION			9
#define XCB_COMPANY_ANGLOCOMPUTERS		10
#define XCB_COMPANY_RESOURCE			11
#define XCB_COMPANY_ALLIEDINTERACTIVE		12
#define XCB_COMPANY_MSBURYCONSULTANTS		13
#define XCB_COMPANY_GNOME			14
#define XCB_COMPANY_AANDGELECTRONICS		15
#define XCB_COMPANY_SPACETECH			16
#define XCB_COMPANY_ATOMWIDELTD			17
#define XCB_COMPANY_SYNTEC			18
#define XCB_COMPANY_ELECTROMUSICRESEARCH	19
#define XCB_COMPANY_MILLIPEDE			20
#define XCB_COMPANY_VIDEOELECTRONICSLTD		21
#define XCB_COMPANY_BRAINSOFT			22
#define XCB_COMPANY_ASP				23
#define XCB_COMPANY_LENDACDATASYSTEMS		24
#define XCB_COMPANY_CAMBRIDGEMICROSYSTEMS	25
#define XCB_COMPANY_JOHNBALANCECOMPUTING	26
#define XCB_COMPANY_SIPLANELECTRONICSRESEARCH	27
#define XCB_COMPANY_SCIENCEFRONTIERS		28
#define XCB_COMPANY_PINEAPPLESOFTWARE		29
#define XCB_COMPANY_TECHNOMATIC			30
#define XCB_COMPANY_IRLAMENTERPRISE		31
#define XCB_COMPANY_NEXUSELECTRONICS		32
#define XCB_COMPANY_OAKCOMPUTERS		33
#define XCB_COMPANY_HUGHSYMONS			34
#define XCB_COMPANY_BEEBUG			35

/* expansion card product type codes */
#define XCB_PRODUCT_HOSTTUBE			0 /* To a BBC */
#define XCB_PRODUCT_PARASITETUBE		1 /* To a second processor */
#define XCB_PRODUCT_SCSI			2
#define XCB_PRODUCT_ETHERNET			3
#define XCB_PRODUCT_IBMDISC			4
#define XCB_PRODUCT_RAMROM			5
#define XCB_PRODUCT_BBCIO			6
#define XCB_PRODUCT_MODEM			7
#define XCB_PRODUCT_TELETEXT			8
#define XCB_PRODUCT_CDROM			9
#define XCB_PRODUCT_IEEE488			10
#define XCB_PRODUCT_WINCHESTER			11
#define XCB_PRODUCT_ESDI			12
#define XCB_PRODUCT_SMD				13
#define XCB_PRODUCT_LASERPRINTER		14
#define XCB_PRODUCT_SCANNER			15
#define XCB_PRODUCT_FASTRING			16
#define XCB_PRODUCT_FASTRING2			17
#define XCB_PRODUCT_PROMPROGRAMMER		18
#define XCB_PRODUCT_MIDI			19
#define XCB_PRODUCT_MONOVPU			20
#define XCB_PRODUCT_FRAMEGRABBER		21
#define XCB_PRODUCT_SOUNDSAMPLER		22
#define XCB_PRODUCT_VIDEODIGITISER		23
#define XCB_PRODUCT_GENLOCK			24
#define XCB_PRODUCT_CODECSAMPLER		25
#define XCB_PRODUCT_IMAGEANALYSER		26
#define XCB_PRODUCT_ANALOGUEINPUT		27
#define XCB_PRODUCT_CDSOUNDSAMPLER		28
#define XCB_PRODUCT_6MIPSSIGPROC		29
#define XCB_PRODUCT_12MIPSSIGPROC		30
#define XCB_PRODUCT_33MIPSSIGPROC		31
#define XCB_PRODUCT_TOUCHSCREEN			32
#define XCB_PRODUCT_TRANSPUTERLINK		33
#define XCB_PRODUCT_INTERACTIVEVIDEO		34
#define XCB_PRODUCT_LASERSCANNER		35
#define XCB_PRODUCT_TRANSPUTERLINKADAPTER	36 /* Gnome version */
#define XCB_PRODUCT_VMEBUS			37
#define XCB_PRODUCT_TAPESTREAMER		38
#define XCB_PRODUCT_LASERTEST			39
#define XCB_PRODUCT_COLOURDIGITISER		40
#define XCB_PRODUCT_WEATHERSATELLITE		41
#define XCB_PRODUCT_AUTOCUE			42
#define XCB_PRODUCT_PARALLELIO16BIT		43
#define XCB_PRODUCT_12BITATOD			44
#define XCB_PRODUCT_SERIALPORTRS423		45
#define XCB_PRODUCT_MINI			46
#define XCB_PRODUCT_FRAMEGRABBER2		47
#define XCB_PRODUCT_INTERACTIVEVIDEO2		48
#define XCB_PRODUCT_WILDATOD			49
#define XCB_PRODUCT_WILDDTOA			50
#define XCB_PRODUCT_EMRMIDI4			51
#define XCB_PRODUCT_FLOATINGPOINTCP		52
#define XCB_PRODUCT_PRISMA3			53
#define XCB_PRODUCT_ARVIS			54
#define XCB_PRODUCT_4BY4MIDI			55
#define XCB_PRODUCT_BISERIALPARALLEL		56
#define XCB_PRODUCT_CHROMA300GENLOCK		57
#define XCB_PRODUCT_CHROMA400GENLOCK		58
#define XCB_PRODUCT_COLOURCONVERTER		59
#define XCB_PRODUCT_8BITSAMPLER			60
#define XCB_PRODUCT_PLUTOINTERFACE		61
#define XCB_PRODUCT_LOGICANALYSER		62
#define XCB_PRODUCT_USERPORTANDMIDI		63
#define XCB_PRODUCT_JBCOMPUTINGSCSI		64
#define XCB_PRODUCT_SIPLANADCANDDAC		65
#define XCB_PRODUCT_DUALUSERPORT		66
#define XCB_PRODUCT_EMRSAMPLER8			67
#define XCB_PRODUCT_EMRSMTP			68
#define XCB_PRODUCT_EMRMIDI2			69
#define XCB_PRODUCT_PINEAPPLEDIGITISER		70
#define XCB_PRODUCT_VIDEOFRAMECAPTURE		71
#define XCB_PRODUCT_MONOOVERLAYFRSTORE		72
#define XCB_PRODUCT_MARKETBUFFER		73
#define XCB_PRODUCT_PAGESTORE			74
#define XCB_PRODUCT_TRAMMMOTHERBOARD		75
#define XCB_PRODUCT_TRANSPUTER			76
#define XCB_PRODUCT_OPTICALSCANNER		77
#define XCB_PRODUCT_DIGITISINGTABLET		78
#define XCB_PRODUCT_200DPISCANNER		79
#define XCB_PRODUCT_DIGITALIO			80
#define XCB_PRODUCT_PRESENTERGENLOCK		81
#define XCB_PRODUCT_COLOURFRAMEGRABBER		82
#define XCB_PRODUCT_CHROMA200GENLOCK		83
#define XCB_PRODUCT_WVSOUNDSAMPLER		84
#define XCB_PRODUCT_SMTPEINTERFACE		85
#define XCB_PRODUCT_8BITATOD			86
#define XCB_PRODUCT_MFMHDCONTROLLER		87
#define XCB_PRODUCT_OAKSCSI			88
#define XCB_PRODUCT_QUADSERIAL			89
#define XCB_PRODUCT_PALPROGRAMMER		90
#define XCB_PRODUCT_I2CBUS			91
#define XCB_PRODUCT_BEEBUGSCANNER		92
#define XCB_PRODUCT_ETHERNET2			97


/*
 * Hard limit on the number of Ethernet (XCB_PRODUCT_ETHERNET{,2})
 * cards which it is safe to run in an R140 or similar system.  The
 * limit arises out of of backplane power supply limitations: both
 * types of Ethernet card can optionally (i.e. when driving "thick"
 * Ethernet) supply a tap box with power at 12V.  However the maximum
 * current such a box may draw (0.5 amp) is in fact twice the nominal
 * allocation of 12V supply for each XCB slot, so two Ethernet cards,
 * both running with thick Ethernet, will swallow all the available
 * 12V power (and hence if any other card also uses 12V then overload
 * can occur).  Ideally we should sum at boot time the nominal power
 * requirements (both 5V and 12V) of all cards found, so that a
 * warning can be issued if either supply would be exceeded.  However
 * this scheme would require all driver writers to know hardware
 * specs, is overcautious (since e.g. the Ethernet driver cannot tell
 * whether thick Ethernet is in fact being used - very little 12V
 * current is drawn if not), and does not cope when cards are fitted
 * which the system does not recognise, but which still draw power
 * when idle.  For now, we just handle the case we know, i.e. the two
 * types of Ethernet card.  Each ethernet driver notifies the xcb
 * manager (using xcb_add_ethernet_card ()) for each of its own cards
 * found: if the number recorded exceeds XCB_MAX_ETHERNET_CARDS+1, a
 * warning is issued about the power limits, but the driver can
 * continue to support up to XCB_MAX_ETHERNET_CARDS of its own type.
 * Hence it is possible (but highly unwise) to use all interfaces on a
 * system with the ridiculous configuration of two Ethernet I and two
 * Ethernet II cards.
 */

#define XCB_MAX_ETHERNET_CARDS	2

#ifdef	_KERNEL
/*
 * xcb_add_ethernet_card issues a warning at boot time if the total
 * number of Ethernet cards installed is too high, and also issues a
 * diagnostic on behalf of the driver if too many (more than
 * XCB_MAX_ETHERNET_CARDS) cards of a particular type are found.  It
 * returns 0 for the latter situation, 1 otherwise.
 */
extern int xcb_add_ethernet_card (int /*driver_count*/, int /*slot*/);
#endif/*_KERNEL*/


/* Hardware addressing (via IOC) */

#define XCB_SPEED_SLOW		0
#define XCB_SPEED_MEDIUM	1
#define XCB_SPEED_FAST		2
#define XCB_SPEED_SYNC		3		/* slowest of all...(!) */

#define XCB_SLOT_OFF(slot)	((slot) << 14)
#define XCB_ADDRESS(speed, slot) \
	(0x03240000 + (XCB_SPEED_/**/speed << 19) + \
	 XCB_SLOT_OFF(slot))

#define XCB_IDx(speed, slot) ((XCBIDRef)(XCB_ADDRESS (speed, slot)))
#define XCB_ID(slot)	     XCB_IDx (SYNC, slot)	/* recommended speed */


/* XCB manager interface details */

#define XCB_SLOTS	4


/*
 * The XCBInfo structure contains card-identification information, as 
 * stored in ARM memory.  Each expansion card must also contain these
 * codes, in a standard format and location, so that the XCB manager 
 * can read the card ID and hence match cards to drivers.
 */
typedef struct xcb_info
{
    unsigned short product, company;
    unsigned char  country;
} XCBInfo, *XCBInfoRef;

    
/*
 * Expansion Card type record.  This is the means whereby an XCB
 * device driver is linked with the XCB manager, in a fashion
 * analogous to the normal cdevsw and bdevsw tables (note that most
 * expansion card drivers will also have entries in one or both of
 * those tables).  The file "xcbconf.c" in the kernel build directory
 * contains a table, xcb_type[], of expansion card type structures,
 * one for each supported card type; the count of entries is set in
 * the external int nxcb_type.  Adding an XCB device driver requires
 * the inclusion in xcb_type of an entry for the card type.  At boot
 * time, the expansion card bus is scanned for expansion cards; the ID
 * of each installed card is determined by reading the first few bytes
 * of XCB ID space for the slot the card resides in.  Only those cards
 * with IDs matching entries in xcb_type will be considered valid as
 * far as RISC iX is concerned.  For all valid cards, a sequence of
 * initialisation is then performed, as follows:
 * 
 *    {cpu priority level still at MAX_SPL}
 *    for each valid card		{round 1}
 * 	 if (card_type->init_high != NULL)
 * 	     (*card_type->init_high) (card_slot);
 *
 *    {cpu priority reduced to 0, but xcb interrupts disabled}
 *    for each valid card		{round 2}
 * 	 if (card_type->init_low != NULL)
 * 	     (*card_type->init_low) (card_slot, 0);
 *    enable interrupts from expansion card bus
 *    for each valid card		{round 3}
 * 	 if (card_type->init_low != NULL)
 * 	     (*card_type->init_low) (card_slot, 1);
 * 
 * The first round of calls is designed to allow a driver to bring its
 * hardware to a stable, non-interrupting, initialised state, before the
 * processor interrupt priority is dropped from its initial maximum
 * and interrupts are allowed in.  The "init_high" function must not
 * reduce the processor priority.
 *
 * The second round of calls, via the "init_low" field, permits
 * further initialisation if required, with general interrupts
 * enabled, but no interrupts from expansion cards (marked by the
 * second parameter being 0).  The standard Ethernet card uses this
 * call to perform a test routine during which each configured card is
 * checked for correct functionality: if the card is OK then it is
 * added to the driver's tables and an interrupt handler is declared
 * for it using the function decl_xcb_interrupt().
 *
 * During either of the first two initialisation calls to a driver,
 * the driver may call the function decl_xcb_interrupt(), to declare
 * to the interrupt manager the existence of an interrupt handler for
 * IRQs from a specific card.  At most one call may be made, for each
 * slot in which a valid card has been found.  In the case that the
 * hardware configuration does not include a full-spec backplane, as
 * indicated by (xcb_regs == (XCBRegsRef)0), any call to this function
 * (and to the function decl_xcb_irq_sense, for non-standard card
 * interrupt indication) MUST happen at this time: an attempt to call
 * it later will cause a panic.
 *
 * The third and last round of initialisation calls uses the same
 * entry point as the second round, but with a second parameter of 1,
 * marking the fact that by this point interrupts from expansion cards
 * have been enabled, and all declared xcb interrupt handlers can
 * potentially be called.  Again the processor priority level is 0.
 * The Ethernet driver uses this call to perform final setup for each
 * configured working Ethernet card, during which time the Ethernet
 * interrupt handler is functioning normally.
 *
 * During the second and third calls, the driver may raise and lower
 * priority as required, using the normal splnnn calls, but should
 * return with the SPL restored to 0.
 *
 * The finally xcb driver entry point is used when the system reboot
 * or halt mechanism is invoked (e.g. via the "reboot" or "halt"
 * programs); the function specified in the shutdown field will be
 * called, as follows:
 *
 *    {cpu priority at maximum}
 *    foreach valid card:
 * 	 if (card_type->shutdown != NULL)
 * 	     (*card_type->shutdown) (card_slot);
 *
 * This function should arrange to close off any activity on the
 * device and bring the card to a stable quiescent state such that
 * when the kernel passes control to RISC OS, the card (a) will not
 * generate any interrupts, and (b) is in a condition equivalent to
 * the hardware reset state, such that the ID bytes used to identify
 * the card are readable at the standard address.
 *
 * In all cases, the called function is passed the physical slot
 * number of the expansion card as its first only parameter; from this
 * the device address may be derived.  Multiple instances of the same
 * card type on the bus will cause multiple calls on the function, one
 * for each slot in which a card of the given type is found.
 */

typedef struct xcb_type
{
    XCBInfo id;					/* ROM ID values */
    int flags;					/* for various purposes */
#define	XCB_TYPE_FLAGS_SHORT_ID   (1 << 0)	/* card has 1-byte id (id.product) */
    void (*init_high) (/*int slot*/);		/* init function 1, max prio */
    void (*init_low) (/*int slot*/);		/* init function 2, prio 0 */
    void (*shutdown) (/*int slot*/);		/* reboot shutdown function */
    struct scavenge *scavenge;			/* for memory reclaim */
} XCBType, *XCBTypeRef;

#ifdef _KERNEL
extern XCBType xcb_type[];
extern int nxcb_type;
#endif



#ifdef _KERNEL
/*
 * decl_xcb_interrupt
 *
 * The parameters to decl_xcb_interrupt have the following meanings:
 *
 * slot:	0..(XCB_SLOTS-1) - the card's physical slot number.
 * handler:	the address of a statically allocated interrupt handler
 *		record.  The ih_fn field should be set to the address of
 *		the interrupt handling function, and the ih_farg field 
 *		should contain a value to be passed to this function on
 *		interrupt; the ih_mask and ih_next fields must be left 
 *		entirely alone by the driver.
 * priority:	the interrupt level at which IRQs from the expansion card
 *		should be serviced (i.e. a PRIO_xxxx value).  Normally,
 *		interrupts from the slot will actually arrive at this spl;
 *		however on those few systems configured without a proper
 *		backplane but with multiple expansion cards running at 
 *		different priorities, the lowest specified priority will
 *		be used for the single hardware interrupt level, but the
 *		handler function will be called with the spl level set to
 *		the requested level.
 *
 * This requests that whenever an expansion card in the specified slot
 * generates an IRQ, handler->ih_fn will be called, with argument
 * handler->ih_farg, with spl set to priority.
 */

extern void decl_xcb_interrupt (/* int slot, 
				   struct int_hndlr *handler,
				   int priority */);
#endif _KERNEL

/*
 * Structure describing the way in which an interrupt from a non-
 * standard expansion card may be detected by the XCB manager.  On
 * systems with a proper backplane this mechanism is not used: the
 * backplane registers give indication of individual XCB interrupts.
 * On systems (regretably there still are a number) without a proper
 * backplane, we need to cope with XCB devices where the "standard"
 * IRQ flag is not used (ID byte 0, bit 0, positive logic).  Such
 * devices include the winchester expansion card (which has a separate
 * register) and early (pre-issue 1) ethernet cards, where the ID byte
 * must be read at FAST speed as opposed to SYNC.  This mechanism
 * assumes that an interrupting card may be identified by reading a
 * flag word from a (slot-adjusted) address and testing it against a
 * mask, the result indicating IRQ presence (!=0) or absence (==0).
 */
typedef struct xcb_irq_sense
{
    volatile int *flag;	/* Note: slot address bits set by xcb manager */
    int mask;
} XCBIRQSense, *XCBIRQSenseRef;

#ifdef _KERNEL
/*
 * decl_xcb_irq_sense need be called only for non-standard cards
 * in systems where the full-spec backplane hardware is not fitted.
 * This can be tested by checking the contents of the external
 * variable xcb_regs (see xcbregs.h).  See the comment above about
 * the meaning of the XCBIRQSense structure.  Note that the slot-
 * specific part of the device address (bits 14,15) is controlled
 * by the XCB manager, and should be left 0 in the flag field of
 * the structure passed in.
 */
extern void decl_xcb_irq_sense (/*int slot, XCBIRQSenseRef sense*/);
#endif _KERNEL


#endif/*__arm_xcb_h*/

/* EOF xcb.h */

