/*
 * $Header: /smsa/bsd:include/arm/int_hndlr.h:bsd  1.14  $
 * $Source: /smsa/bsd:include/arm/int_hndlr.h: $
 *
 * Copyright (c) 1988 Acorn Computers Ltd., Cambridge, England
 *

 */

#ifndef	__arm_int_hndlr_h
#define	__arm_int_hndlr_h
#define	__machine_int_hndlr_h	"arm"

/*
 *	ARM Interrupt interface - interrupt control structures
 *
 *	Author: J.M. Collins, Xi Software Ltd 1986.
 *	Revised: Mark Taunton, Acorn Computers Ltd, 1988.
 */

/*
 * Interrupt source types: one byte is allocated in the mask values
 * for each type.  The order here matches ordering from least-sig
 * byte to most-sig byte.  One of these values is passed to
 * decl_interrupt (), along with a bit-mask for that source.
 */
#define INT_IRQA 	0
#define INT_IRQB 	1
#define INT_XCB  	2
#define INT_SOFT	3

#define INT_BIT(mask,type) ((mask) << ((type) * 8))
#define SINT_SHIFT	(INT_SOFT * 8)

/* Define hardware force-interrupt bit (needs ioc.h)  */
#define SOFTINT_BIT	INT_BIT(IRQA_FORCE,INT_IRQA)

/*
 * At most 8 soft-ints can be defined as things currently 
 * stand: 1 << 7 would be the last.  This could be modified
 * by using some spare XCB type bits for soft-ints, and
 * adjusting the INT_xxx and SOFTINT_BIT macros above.
 */
#define	SOFTCLOCKMASK	(1 << 0)
#define	SOFTNETMASK	(1 << 1)
#define	SOFTFDCMASK	(1 << 2)
#define	SOFTVTEOUTPUT	(1 << 3)
#define SOFTSERIAL	(1 << 4)
#define SOFTSCSIMASK    (1 << 5)

/*
 * To declare an interrupt, the routine
 *
 *	decl_interrupt(&thing, level, type)
 *
 * is called with the following structure as 'thing'.
 */

struct int_hndlr
{
    unsigned int	ih_mask;		/* Mask (gets mangled) */
    void		(*ih_fn)();		/* Function to call */
    int			ih_farg;		/* Argument to pass */
    struct int_hndlr   *ih_next;		/* Next one */
};

/*
 *	This is the vector of masks or-ed from each of the declared
 *	interrupts for each priority level.
 */

struct int_prio_tbl
{
    struct int_prio_tbl	*ip_next;	/* link to next lower active level */
    unsigned int	ip_this_level;	/* bits for this level only */
    unsigned int	ip_cum_bits;	/* bits for all levels < this */
    struct int_hndlr	*ip_chain;	/* handler chain */
};

/* Head of chain of active int levels */
extern struct int_prio_tbl  *first_irq;

/* Hardware int priority table */
extern struct int_prio_tbl  int_prio_tbl[];

/* Or of bits for pending software interrupts. This is unshifted. */
extern unsigned int  sint_pending;

#define  PRIO_0		0x00			/* rock bottom: user level */
#define  PRIO_SOFTVTE	0x07			/* VC driver soft-irqs */
#define	 PRIO_SOFTCLOCK	0x08			/* clock soft-irqs */
#define  PRIO_FDC	0x09			/* floppy low-priority */
#define  PRIO_SOFTNET   0x0b			/* network soft-irq work */
#define  PRIO_SOFTSCSI	0x0d			/* scsi soft-irq machine */
#define  PRIO_I2C	0x0f			/* I2C i/o activities */
#define  PRIO_ET	0x10			/* Ethernet hardware i/f */
#define  PRIO_BIO	0x14			/* normal disc I/O */
#define  PRIO_TTY	0x16			/* normal tty processing */
#define  PRIO_SOUND	0x18			/* sound dma channel irq */
#define  PRIO_VFLY	0x19			/* vertical fly back (video) */
#define  PRIO_SCAN	0x1b			/* serial i/f to scanner */
#define  PRIO_HITTY	0x1b			/* high priority serial i/f */
#define  PRIO_CLOCK	0x1d			/* hardware clock */
#define  PRIO_HIGH	0x1f			/* maximum priority */
#define  MAX_SPL	0x1f			/* defined maximum */

#if 0 /* no slip support for now -- MT */
/*
 * PRIO_IMP = max net h/ware priority: note that whereas previously
 * this was only the same as PRIO_ET (0x10), SLIP assumes that
 * PRIO_IMP is at least PRIO_TTY, not unreasonably since it turns a
 * tty into a networking device.
 */
#define  PRIO_IMP	PRIO_TTY
#else
#define  PRIO_IMP	PRIO_ET
#endif

/* Treat the parallel (Centronics) port like a tty for interrupt prio. */
#define  PRIO_CENT	PRIO_TTY
/* Specific block-devices have their own PRIO_xxx definitions... */
#define  PRIO_SCSI	PRIO_BIO
#define  PRIO_WINC	PRIO_BIO

#endif/*__arm_int_hndlr_h*/

/* EOF int_hndlr.h */
