/*

    Copyright (C) Corollary, Inc., 1993, 1994.
    All Rights Reserved.
    This Module contains Proprietary Information of
    Corollary, Inc., and should be treated as Confidential.

Module Name:

    cbus2.h

Abstract:

    Cbus2 hardware architecture definitions for the
    Corollary C-bus II multiprocessor PSD modules.

Author:

    Landy Wang (landy@corollary.com) 11-Jan-1994
 */

#ifndef _CBUS2_
#define _CBUS2_

/*
 * General notes:
 *
 *	- ALL reserved fields must be zero filled on writes to
 *	  ensure future compatibility.
 *
 *	- general CSR register length is 64 bits.
 */



typedef struct _csr_register_t {

	ULONG	LowDword : 32;
	ULONG	HighDword : 32;

} CSR_REGISTER_T, *PCSR_REG;




typedef union _elementid_t {
	struct {
		ULONG	ElementID : 4;
		ULONG	Reserved0 : 28;
		ULONG	Reserved1 : 32;
	} ra;
	CSR_REGISTER_T rb;
} ELEMENTID_T, *PELEMENTID;




typedef union _spurious_t {
	struct {
		ULONG	Vector : 8;
		ULONG	Reserved0 : 24;
		ULONG	Reserved1 : 32;
	} ra;
	CSR_REGISTER_T rb;
} SPURIOUS_T;

/*
 * The hardware interrupt map table (16 entries) is indexed by irq.
 * Lower numerical irq lines will receive higher interrupt (IRQL) priority.
 *
 * Each CBC has its own hardware interrupt map registers .  note that
 * each processor gets his own CBC, but it need only be used in this
 * mode if there is an I/O card attached to its CBC.  each EISA bridge
 * will have a CBC, which is used to access any devices on that EISA bus.
 */
typedef union _hwintrmap_t {
	struct {
		ULONG	Vector : 8;
		ULONG	Mode : 2;
		ULONG	Level : 1;
		ULONG	Reserved0 : 21;
		ULONG	Reserved1 : 32;
	} ra;
	CSR_REGISTER_T rb;
} HWINTRMAP_T, *PHWINTRMAP;

#define HW_MODE_DISABLED	0x0
#define HW_MODE_RISING		0x100		/* ie: ISA card interrupts */
#define HW_MODE_FALLING		0x200
#define HWINTR_MAP_ENTRIES	0x10

/*
 * 256 intrconfig registers for vectors 0 to 255.  this determines how
 * a given processor will react to each of these vectors.  each processor
 * has his own intrconfig table in his element space.
 */
typedef union _intrconfig_t {
	struct {
		ULONG	Imode : 2;
		ULONG	Reserved0 : 30;
		ULONG	Reserved1 : 32;
	} ra;
	CSR_REGISTER_T rb;
} INTRCONFIG_T, *PINTRCONFIG;

#define HW_IMODE_DISABLED	0x0
#define HW_IMODE_ALLINGROUP	0x1
#define HW_IMODE_LIG		0x2
#define INTR_CONFIG_ENTRIES	0x100

/*
 * 256 interrupt request registers for vectors 0 to 255.
 * parallel to the interrupt config register set above.
 * This is used to send the corresponding interrupt vector.
 * which processor gets it is determined by which element's
 * address space you write to.
 *
 * The irq field should always be set when accessed by software.
 * only hardware LIG arbitration will clear it.
 */
typedef union _intrreq_t {
	struct {
		ULONG	Irq : 1;
		ULONG	Reserved0 : 31;
		ULONG	Reserved1 : 32;
	} ra;
	CSR_REGISTER_T rb;
} INTRREQ_T, *PINTRREQ;

/*
 * interrupt control register (64 bit wide) bit field definitions in use.
 */
#define	PC_INTERRUPT_ENABLE	0x40

/*
 * the Cbus2 task priority register bit layout and
 * minimum/maximum values are defined in cbus.h, as
 * they need to be shared with the symmetric Cbus1.
 */

/*
 * Offsets of various distributed interrupt registers within the CSR space.
 * WARNING: some of these offsets are hardcoded in assembly as well.
 */
typedef struct _csr {
	CHAR		pad0[0x28];

	ELEMENTID_T	ElementID;			      /* 0x0028 */

	CHAR		pad1[0x200 - 0x28 - sizeof (ELEMENTID_T)];

	TASKPRI_T	TaskPriority;			      /* 0x0200 */

	CHAR		pad2[0x220 - 0x200 - sizeof (TASKPRI_T)];

	CSR_REGISTER_T	Icontrol;			      /* 0x0220 */

	CHAR		pad3[0x240 - 0x220 - sizeof (CSR_REGISTER_T)];

	SPURIOUS_T	SpuriousVector;			      /* 0x0240 */

	CSR_REGISTER_T	WriteOnly;			      /* 0x0248 */

	CHAR		pad4[0x600 - 0x248 - sizeof (CSR_REGISTER_T)];

	HWINTRMAP_T	HardwareInterruptMap[HWINTR_MAP_ENTRIES];   /* 0x0600 */

	CHAR		pad5[0x800 - 0x600 -
				HWINTR_MAP_ENTRIES * sizeof (HWINTRMAP_T)];

	INTRCONFIG_T	InterruptConfiguration[INTR_CONFIG_ENTRIES];/* 0x0800 */
	INTRREQ_T	InterruptRequest[INTR_CONFIG_ENTRIES];	    /* 0x1000 */
	INTRREQ_T	InterruptPending[INTR_CONFIG_ENTRIES];	    /* 0x1800 */

	CSR_REGISTER_T	SystemTimer;				    /* 0x2000 */

	CHAR		pad6[0x3000 - 0x2000 - sizeof(CSR_REGISTER_T)];

	CSR_REGISTER_T	EccClear;				    /* 0x3000 */
	CSR_REGISTER_T	EccSyndrome;				    /* 0x3008 */
	CSR_REGISTER_T	EccWriteAddress;			    /* 0x3010 */
	CSR_REGISTER_T	EccReadAddress;				    /* 0x3018 */

} CSR_T, *PCSR;

/*
 * RRD will provide an entry for every Cbus2 element.  To avoid
 * using an exorbitant number of PTEs, this entry will specify
 * only the CSR space within each Cbus2 element's space.  And only
 * a subset of that, as well, usually on the order of 4 pages.
 * Code wishing to access other portions of the cbus_element
 * space will need to subtract down from the RRD-specified CSR
 * address and map according to their particular needs.
 */
#define MAX_CSR_BYTES		0x10000

#define csr_register		rb.LowDword

#define InterruptControl	Icontrol.LowDword

#if 0
/*
 * the full layout of a cbus_element is immaterial to the PSD and is
 * here for reference only.  Ditto the offset of the CSR within it.
 */
struct cbus_element {
	CHAR	DeviceReserved	[60 * 1024 * 1024];
	CHAR	ControlIO	[0x10000];
	CHAR	PCbusIO		[0x10000];
	CHAR	Csr		[MAX_CSR_BYTES];
	CHAR	Reserved	[0x1D0000];
	CHAR	Ram		[0x100000];
	CHAR	Prom		[0x100000];
};

/*
 * offset of CSR within any element's I/O space.
 */
#define CBUS_CSR_OFFSET		0x3C20000
#endif

#endif	    /* _CBUS2_ */
