/*
 * Written by: Garry Forsgren, Unisys Corporation
 *             Natalie Protasevich, Unisys Corporation
 * This file contains the code to configure and interface 
 * with Unisys ES7000 series hardware system manager (MIP)
 *
 * Copyright (c) 2002 Unisys Corporation.  All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 * Contact information: Unisys Corporation, Township Line & Union Meeting 
 * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
 *
 * http://www.unisys.com
 */

#define MAXCPU             	32
#define MIP_MAILBOX             1
#define CMP_PARTITION           2
#define CMP_SHARED_MEMORY       3
#define PSAI                    4
#define MTRR                    5
#define TEST_EXEC               6
#define EXT_SHM                 7

#define ES7000_MAX_MEM_UNIT     32
#define OEM_VER(VALUE)          (VALUE & 0xff)                  /* OEM table version */
#define OEM_CSUM(VALUE)         ((VALUE >> 8) & 0xff)           /* OEM table checksum */
#define OEM_SIZE(VALUE)         ((VALUE >> 16) & 0xffff)        /* OEM table size in bytes */
#define OEM_ENTRIES(VALUE)      ((VALUE >> 32) & 0xffff)        /* OEM table entry count */
#define HOST_CMD_MAX            0x29                            /* Maximum number of MIP cmds */
#define BUSY                    1
#define PAGEOFFSET(p)  ((UINT64)p & (PAGESIZE-1))

/* Mailbox Macros */
#define STATUS(VALUE)   (VALUE >> 40 & 0xffff)
#define FUNC(VALUE)     (VALUE & 0xff)       
#define SEQ(VALUE)      (VALUE >> 32 & 0xffffffff)
#define DIRECT(VALUE)   (VALUE >> 31 & 0x1)
#define BUF(VALUE)      (VALUE >> 30 & 0x1)
#define HOSTROUTE(VALUE)(VALUE >> 8 & 0xff)
#define MIPROUTE(VALUE) (VALUE >> 16 & 0xff)
#define OSTYPE(VALUE)   (VALUE >> 16 & 0xff)
#define PSTATE(VALUE)   (VALUE >> 32 & 0x3)
#define INST(VALUE)     (VALUE & 0xffff)  
#define BCOUNT(VALUE)   (VALUE & 0xffff) 
#define PID(VALUE)      ((VALUE & 0x3000) >> 7)\
                         | ((VALUE & 0x100) >> 4)\
                         | (1 << (VALUE & 0x3)) 

/*
 * Maintenance Interface operations
 */

#define MIP_IV(VALUE)           ((VALUE >> 48) & 0xffff)
#define MIP_PORT(VALUE)         ((VALUE >> 32) & 0xffff)
#define MIP_VER(VALUE)          ((VALUE >> 16) & 0xffff)
#define MIP_TYPE(VALUE)         (VALUE & 0xff)       
#define MIP_DID(VALUE)          (VALUE & 0xff)      
#define MIP_EDID(VALUE)         ((VALUE >> 8) & 0xff)
#define MIP_DMODE(VALUE)        ((VALUE >> 16) & 0xff)
#define MIP_MIN(VALUE)          ((VALUE >> 32) & 0xffff)
#define MIP_MAX(VALUE)          ((VALUE >> 48) & 0xffff)
#define MIP_MBOX_SIZE           (sizeof(char) * 64)
#define MIP_RD_LO(VALUE)        (VALUE & 0xffffffff)   
#define MIP_BUF_LEN             0x1000                
#define MIP_CMD_MAX             0xd                  


#define 	DEBUG 1
#define 	CURRENT_REV     ("1.0")
#define 	VALID   0x0100000000000000
#define         UIS_IPI         0xF1
#define         OFF_0   0
#define         OFF_8   1
#define         OFF_10  2
#define         OFF_18  3
#define         OFF_38  4

#define bcopy(src, dest, n) memcpy ((dest), (src), (n))
#define bzero(d, n) memset((d), 0, (n))

typedef struct mip_mailbox {
        u8           EntryType;
        u8           Length;
        u16          MailboxVersion;
        u16          MipIOPort;
        u16          MipInterruptVector;
        u8           DestID;
        u8           DestEID;
        u8           DeliveryMode;
        u8           reserved;
        u16          MinMailboxVer;
        u16          MaxMailboxVer;
        u64          Host2MipMailbox;
        u64          Mip2HostMailbox;
} mip_mailbox_t;

typedef struct cmp_pif {
        u8           EntryType;
        u8           Length;
        u8           PID;
        u32          reserved;
} cmp_pif_t;

typedef struct {
        u64          StartAddress;
        u64          Size;
} memory_region_t;

typedef struct cmp_smif {
        u8           EntryType;
        u8           Length;
        u8           EntryCnt;
        u32          reserved;
        memory_region_t Region[1];
} cmp_smif_t;

typedef struct start_address {
        u8           EntryType;
        u8           Length;
        u8           reserved[6];
        u64          StartAddress;
} start_address_t;

struct mip_mailbox_info {
        unsigned long long mip_info;
        unsigned long long delivery_info;
        unsigned long long host_mip_mail_addr;
        unsigned long long mip_host_mail_addr;
};

/*
 * Partition Information Format
 */

struct part_info {
        unsigned char   type;   
        unsigned char   length;
        unsigned char   part_id;
        unsigned char   apic_mode;
        unsigned long   snum;    
        char            ptype[16];
        char            sname[64];
        char            pname[64];
};

struct psai {
        unsigned long long              entry_type;
        unsigned long long              addr;           /* Start Address */
        unsigned long long              bep_addr;  /* BIOS Entry Point Addr */
};

/*
 * MTRR Information structure
 */

struct mtrr_info {
        unsigned long long entry_type;
        unsigned long long mtrr_dev_type;
        unsigned long long mtrrfix64k_00000;
        unsigned long long mtrrfix16k_80000;
        unsigned long long mtrrfix16k_a0000;
        unsigned long long mtrrfix4k_c0000;
        unsigned long long mtrrfix4k_c8000;
        unsigned long long mtrrfix4k_d0000;
        unsigned long long mtrrfix4k_d8000;
        unsigned long long mtrrfix4k_e0000;
        unsigned long long mtrrfix4k_e8000;
        unsigned long long mtrrfix4k_f0000;
        unsigned long long mtrrfix4k_f8000;
        unsigned long long mtrrphysbase0;
        unsigned long long mtrrphysmask0;
        unsigned long long mtrrphysbase1;
        unsigned long long mtrrphysmask1;
        unsigned long long mtrrphysbase2;
        unsigned long long mtrrphysmask2;
        unsigned long long mtrrphysbase3;
        unsigned long long mtrrphysmask3;
        unsigned long long mtrrphysbase4;
        unsigned long long mtrrphysmask4;
        unsigned long long mtrrphysbase5;
        unsigned long long mtrrphysmask5;
        unsigned long long mtrrphysbase6;
        unsigned long long mtrrphysmask6;
        unsigned long long mtrrphysbase7;
        unsigned long long mtrrphysmask7;
};

typedef struct {
        u8           EntryType;
        u8           Length;
        u8           reserved[6];
        u64          StartAddress;
} test_exec_t;

struct test_exec_data {
        unsigned long long entry_type;
        unsigned long long teda;
};

struct es7000_mem_info {
        unsigned char       type;   
        unsigned char       length;
        unsigned char       resv[6];
        unsigned long long  start; 
        unsigned long long  size; 
};

/*
 * ES7000 OEM table structure
 */

struct es7000_oem_table {
        unsigned long long              hdr;
        struct mip_mailbox_info         mip;
        struct part_info                pif;
        struct es7000_mem_info          shm;
        struct psai                     psai;
        struct mtrr_info                mtrr;
        struct test_exec_data           ted;
        struct es7000_mem_info          exm;
};

typedef struct mbox {
        unsigned long long off_0;                 /* offset 0x0 */
        unsigned long long off_8;                 /* offset 0x8 */
        unsigned long long off_10;                /* offset 0x10 */
        unsigned long long off_18;                /* offset 0x18 */
        unsigned long long off_20;                /* offset 0x20 */
        unsigned long long off_28;                /* offset 0x28 */
        unsigned long long off_30;                /* offset 0x30 */
        unsigned long long off_38;                /* offset 0x38 */
} mbox_t;

typedef struct mip_rqst {
        mbox_t  host_mip;
        mbox_t  mip_host;
        int     state;  
        int     (*cb_func)(void); 
        void    *cb_args;
} mip_rqst_t;

typedef struct hsrf {
        unsigned long long type;          /* Data Area Type 2 */
        char    msg[80];        /* Error message */
} hsrf_t;

/* Host to MAP Functions */

#define NOP                     0x30000
#define SAVE_CMOS               0x40020101
#define BIOS_OS_TRANS           0x20102
#define RELEASE_AP              0x20103
#define SW_PART_MB              0x30104
#define LOAD_CODE               0x40000105
#define MAP_MEMORY              0x40010106
#define CLUST_CHK_COMP          0x40010108
#define REPORT_FAULT_BIOS       0x40020109
#define WP_BIOS                 0x1010a
#define SW_APIC                 0x1020b
#define EN_UNS_MSG              0x2020c
#define EN_MIP_INT              0x3020d
#define HEARTBEAT               0x2020e
#define HB_ENABLE               0x2020f
#define REPORT_FAULT_OS         0x40020209
#define MOD_MIP_IO              0x10212
#define SEL_SP_LP               0x10213
#define SHUTDOWN                0x20226
#define REPORT_FAULT_PROC       0x40020309
#define CHG_PAR_ST_PROC         0x40020314
#define REQ_UNIT_ST_PROC        0x40xx0315
#define REPORT_FAULT_IO         0x40020409
#define CHG_PAR_ST_IO           0x40xx0414
#define REQ_UNIT_ST_IO          0x40xx0415
#define REPORT_FAULT_XMEM       0x40020509
#define CHG_PAR_ST_XMEM         0x40xx0514
#define REQ_UNIT_ST_XMEM        0x40xx0515
#define REPORT_FAULT_SMEM       0x40020609
#define CHG_PAR_ST_SMEM         0x20614
#define REQ_UNIT_ST_SMEM        0x40020615
#define REQ_ATTRB_SMEM          0x40040616
#define MOVE_MAILBOX            0x30720
#define NEG_MB_VER              0x30721
#define REQ_CONF_DATA           0x40020822
#define REQ_NEW_CONF_DATA       0x40020823
#define SAV_PART_DATA           0x20824
#define REQ_PART_DATA           0x20825
#define RPT_EVNT_MIP            0x40xx0a27
#define FUNC(VALUE) (VALUE & 0xff)

/*
 * Intel MP OEM table parsing routine on ES7000:
 */
extern void __init parse_unisys_oem (struct mp_config_oemtable *);
extern int es7000_mipintr_attach(void (*func)(int, void *, struct pt_regs *));
extern void es7000_mipintr_release(void);
extern int es7000_service_attach(void (*func)(int, void *, struct pt_regs *));
extern void es7000_register_crash(void);
extern int es7000_get_eng(int);
extern int es7000_mailit(mip_rqst_t *);
extern void es7000_cur_version(char *);
extern int es7000_set_status(unsigned long long , int , int );
extern int es7000_read_mailbox(mbox_t *, int );
extern void es7000_ipi_send(int , int );
extern int es7000_crash(struct notifier_block *, unsigned long , void *);
extern int es7000_get_vect(int *);
extern int es7000_start_cpu(int cpu);


extern mbox_t			es7000_mbox;
extern int			es7000_plat;
extern int			es7000_mipsend(struct mbox *mbox);
extern unsigned long long	mip_sequence;
extern unsigned char 		*es7000_trampoline_base;
