/*

    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:

    cbus1.h

Abstract:

    Cbus1 architecture definitions for the Corollary C-bus I
    multiprocessor PSD modules.  This is really split into 2
    sections: Cbus1 hardware architecture and APIC characteristics.

Author:

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

#ifndef _CBUS1_
#define _CBUS1_

/*
 *
 *
 *              FIRST, THE CBUS1 HARDWARE ARCHITECTURE DEFINITIONS
 *
 *
 */

#define CBUS1_CACHE_LINE        16              /* 16 byte lines */
#define CBUS1_CACHE_SHIFT       4               /* byte size to line size */
#define CBUS1_CACHE_SIZE        0x100000        /* 1 Mb caches */

#define ATB_STATREG             (PUCHAR)0xf1    /* EISA bridge status register */
#define BS_ARBVALUE             0xf             /* arbitration value */

#define LOWCPUID                0x1             /* lowest arbitration slot id */
#define HICPUID                 0xf             /* highest arbitration slot id */

#define CBUS1_SHADOW_REGISTER   0xB0            /* offset of shadow register */

#define DISABLE_BIOS_SHADOWING  0x0             /* disable ROM BIOS shadowing */

/*
 *
 * defines for the Cbus1 ecc control register
 *
 */
#define CBUS1_EDAC_SAEN         0x80
#define CBUS1_EDAC_1MB          0x40
#define CBUS1_EDAC_WDIS         0x20
#define CBUS1_EDAC_EN           0x10
#define CBUS1_EDAC_SAMASK       0xf

/*
 *
 *
 *              THE APIC HARDWARE ARCHITECTURE DEFINITIONS
 *
 *
 */

#define LOCAL_APIC_ENABLE       0x100   /* all APIC intrs now enabled */

#define APIC_INTR_UNMASKED      0x0     /* this interrupt now enabled */
#define APIC_INTR_MASKED        0x1     /* this interrupt now disabled */

#define APIC_INTR_FIXED         0x0     /* this interrupt is tied to a CPU */
#define APIC_INTR_LIG           0x1     /* this interrupt is lowest-in-group */
#define APIC_INTR_NMI           0x4     /* this interrupt is an NMI */

#define APIC_INTR_FIXED_DWORD	0x0     /* this interrupt tied in dword format */
#define APIC_INTR_LIG_DWORD	0x100	/* this interrupt LIG in dword format */

#define APIC_EDGE               0x0     /* this interrupt is edge-triggered */
#define APIC_LEVEL              0x1     /* this interrupt is level-triggered */

#define APIC_LOGICAL_MODE       0x1     /* only logical mode is being used */
#define APIC_LOGICAL_MODE_DWORD	0x800	/* bit to set in dword format */

#define APIC_DEASSERT_RESET	0x500	/* sending a DEASSERT-RESET command */

#define APIC_ALLINCLSELF	0x80000	/* sending a DEASSERT-RESET command */

#define APIC_TRIGGER_LEVEL	0x08000	/* generate a level interrupt */

#define APIC_FULL_DRESET	(APIC_ALLINCLSELF || \
				 APIC_TRIGGER_LEVEL || \
				 APIC_LOGICAL_MODE_DWORD || \
				 APIC_DEASSERT_RESET)

#define APIC_ALL_PROCESSORS     (ULONG)-1  /* Destination format reg default */

/*
 * left shift needed to convert processor_bit to Intel APIC ID.
 * this applies to the:
 *
 *              I/O unit ID register
 *              I/O unit ID redirection entry destination registers
 *              local unit ID register
 *              local unit logical destination register
 */

#define APIC_BIT_TO_ID          24

/*
 * Physical address of the local APIC
 */
#define LOCAL_APIC_LOCATION     0xFEE00000

/*
 * Physical address of the I/O APIC
 */
#define IO_APIC_LOCATION        0xFEE00000

#define LOCAL_APIC_SIZE         0x400
#define IO_APIC_SIZE            0x11

/*
 * I/O APIC registers.  note only register select & window register are
 * directly accessible in the address space.  other I/O registers are
 * reached via these two registers, similar to the CMOS access method.
 */
#define IO_APIC_REGSEL          0x00
#define IO_APIC_WINREG          0x10

#define IO_APIC_ID_OFFSET       0x00
#define IO_APIC_VERSION         0x01
#define IO_APIC_REDIRLO         0x10
#define IO_APIC_REDIRHI         0x11

typedef struct _ioapic_registers_t {
        ULONG                   register_select;
	ULONG			fill[3];
        ULONG                   window_register;
} IOAPIC_REGISTERS_T, *PIOAPIC_REGISTERS;

/*
 * Each I/O APIC has one redirection entry for each interrupt it handles.
 * note that since it is not directly accessible (instead the window register
 * must be used), consecutive entries are byte aligned, not 16 byte aligned.
 */
typedef union _redirection_t {
        struct {
                ULONG   Vector : 8;
                ULONG   Delivery_mode : 3;
                ULONG   Dest_mode : 1;
                ULONG   Delivery_status : 1;            /* read-only */
                ULONG   Reserved0 : 1;
                ULONG   Remote_irr : 1;
                ULONG   Trigger : 1;
                ULONG   Mask : 1;
                ULONG   Reserved1 : 15;
                ULONG   Destination;
        } ra;
        struct {
                ULONG   dword1;
                ULONG   dword2;
        } rb;
} REDIRECTION_T;

/*
 * The Interrupt Command register format is used for IPIs.
 */
typedef union _intrcommand_t {
	struct {
		ULONG           vector : 8;
		ULONG           delivery_mode : 3;
		ULONG           dest_mode : 1;
		ULONG           delivery_status : 1;            /* read-only */
		ULONG           reserved0 : 1;
		ULONG           level : 1;
		ULONG           trigger : 1;
		ULONG           remote_read_status : 2;
		ULONG           destination_shorthand : 2;
		ULONG           reserved1 : 12;
		ULONG           pad[3];
		ULONG           destination;
	} ra;
        struct {
                ULONG   	dword1;
        } rb;
} INTRCOMMAND_T, *PINTRCOMMAND;

typedef struct _apic_registers_t {
        UCHAR                   fill0[0x20];

        ULONG                   LocalUnitID;                    /* 0x20 */
        UCHAR                   fill1[0x80 - 0x20 - sizeof(ULONG)];

        TASKPRI_T               ApicTaskPriority;               /* 0x80 */
        UCHAR                   fill2[0xB0 - 0x80 - sizeof(TASKPRI_T)];

        ULONG                   ApicEOI;                        /* 0xB0 */
        UCHAR                   fill3[0xD0 - 0xB0 - sizeof(ULONG)];

        ULONG                   ApicLogicalDestination;         /* 0xD0 */
        UCHAR                   fill4[0xE0 - 0xD0 - sizeof(ULONG)];

        ULONG                   ApicDestinationFormat;          /* 0xE0 */
        UCHAR                   fill5[0xF0 - 0xE0 - sizeof(ULONG)];

        ULONG                   ApicSpuriousVector;             /* 0xF0 */
        UCHAR                   fill6[0x100 - 0xF0 - sizeof(ULONG)];

        ULONG                   ApicISR;             		/* 0x100 */
        UCHAR                   fill7[0x200 - 0x100 - sizeof(ULONG)];

        ULONG                   ApicIRR;             		/* 0x200 */
        UCHAR                   fill8[0x300 - 0x200 - sizeof(ULONG)];

        INTRCOMMAND_T           ApicICR;                        /* 0x300 */
        UCHAR                   fill9[0x320 - 0x300 - sizeof(INTRCOMMAND_T)];

        ULONG			TimerVector;			/* 0x320 */
        UCHAR                   fillA[0x360 - 0x320 - sizeof(ULONG)];

        REDIRECTION_T           ApicLocalInt1;                  /* 0x360 */
        UCHAR                   fillB[0x380 - 0x360 - sizeof(REDIRECTION_T)];

        ULONG           	InitialCount;                  /* 0x380 */
        UCHAR                   fillC[0x390 - 0x380 - sizeof(ULONG)];

        REDIRECTION_T           ApicTimer;			/* 0x390 */
        UCHAR                   fillD[0x4D0 - 0x390 - sizeof(REDIRECTION_T)];

	/*
         * Note that APMode is also the PolarityPortLow register
	 */
        UCHAR                   APMode;                         /* 0x4D0 */
        UCHAR                   PolarityPortHigh;               /* 0x4D1 */

} APIC_REGISTERS_T, *PAPIC_REGISTERS;

/*
 * this structure is used for
 * communications between processors modifying the I/O APIC.
 */
typedef struct _redirport_t {
	volatile ULONG		Status;
	ULONG			RedirectionAddress;
	ULONG			Destination;
	ULONG			Control;
} REDIR_PORT_T;

#define REDIR_NO_REQUEST		0x0
#define REDIR_ACTIVE_REQUEST		0x1

#endif      /* _CBUS1_ */
