18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *  This program is free software; you can redistribute it and/or modify
58c2ecf20Sopenharmony_ci *  it under the terms of the GNU Lesser General Public License as published by
68c2ecf20Sopenharmony_ci *  the Free Software Foundation; either version 2.1 of the License, or
78c2ecf20Sopenharmony_ci *  (at your option) any later version.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci *  This program is distributed in the hope that it will be useful,
108c2ecf20Sopenharmony_ci *  but WITHOUT ANY WARRANTY; without even the implied warranty of
118c2ecf20Sopenharmony_ci *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
128c2ecf20Sopenharmony_ci *  GNU Lesser General Public License for more details.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci *  You should have received a copy of the GNU Lesser General Public License
158c2ecf20Sopenharmony_ci *  along with this program; if not, write to the Free Software
168c2ecf20Sopenharmony_ci *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
178c2ecf20Sopenharmony_ci */
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#ifndef __GRU_INSTRUCTIONS_H__
208c2ecf20Sopenharmony_ci#define __GRU_INSTRUCTIONS_H__
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ciextern int gru_check_status_proc(void *cb);
238c2ecf20Sopenharmony_ciextern int gru_wait_proc(void *cb);
248c2ecf20Sopenharmony_ciextern void gru_wait_abort_proc(void *cb);
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/*
298c2ecf20Sopenharmony_ci * Architecture dependent functions
308c2ecf20Sopenharmony_ci */
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci#if defined(CONFIG_IA64)
338c2ecf20Sopenharmony_ci#include <linux/compiler.h>
348c2ecf20Sopenharmony_ci#include <asm/intrinsics.h>
358c2ecf20Sopenharmony_ci#define __flush_cache(p)		ia64_fc((unsigned long)p)
368c2ecf20Sopenharmony_ci/* Use volatile on IA64 to ensure ordering via st4.rel */
378c2ecf20Sopenharmony_ci#define gru_ordered_store_ulong(p, v)					\
388c2ecf20Sopenharmony_ci		do {							\
398c2ecf20Sopenharmony_ci			barrier();					\
408c2ecf20Sopenharmony_ci			*((volatile unsigned long *)(p)) = v; /* force st.rel */	\
418c2ecf20Sopenharmony_ci		} while (0)
428c2ecf20Sopenharmony_ci#elif defined(CONFIG_X86_64)
438c2ecf20Sopenharmony_ci#include <asm/cacheflush.h>
448c2ecf20Sopenharmony_ci#define __flush_cache(p)		clflush(p)
458c2ecf20Sopenharmony_ci#define gru_ordered_store_ulong(p, v)					\
468c2ecf20Sopenharmony_ci		do {							\
478c2ecf20Sopenharmony_ci			barrier();					\
488c2ecf20Sopenharmony_ci			*(unsigned long *)p = v;			\
498c2ecf20Sopenharmony_ci		} while (0)
508c2ecf20Sopenharmony_ci#else
518c2ecf20Sopenharmony_ci#error "Unsupported architecture"
528c2ecf20Sopenharmony_ci#endif
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/*
558c2ecf20Sopenharmony_ci * Control block status and exception codes
568c2ecf20Sopenharmony_ci */
578c2ecf20Sopenharmony_ci#define CBS_IDLE			0
588c2ecf20Sopenharmony_ci#define CBS_EXCEPTION			1
598c2ecf20Sopenharmony_ci#define CBS_ACTIVE			2
608c2ecf20Sopenharmony_ci#define CBS_CALL_OS			3
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci/* CB substatus bitmasks */
638c2ecf20Sopenharmony_ci#define CBSS_MSG_QUEUE_MASK		7
648c2ecf20Sopenharmony_ci#define CBSS_IMPLICIT_ABORT_ACTIVE_MASK	8
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci/* CB substatus message queue values (low 3 bits of substatus) */
678c2ecf20Sopenharmony_ci#define CBSS_NO_ERROR			0
688c2ecf20Sopenharmony_ci#define CBSS_LB_OVERFLOWED		1
698c2ecf20Sopenharmony_ci#define CBSS_QLIMIT_REACHED		2
708c2ecf20Sopenharmony_ci#define CBSS_PAGE_OVERFLOW		3
718c2ecf20Sopenharmony_ci#define CBSS_AMO_NACKED			4
728c2ecf20Sopenharmony_ci#define CBSS_PUT_NACKED			5
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci/*
758c2ecf20Sopenharmony_ci * Structure used to fetch exception detail for CBs that terminate with
768c2ecf20Sopenharmony_ci * CBS_EXCEPTION
778c2ecf20Sopenharmony_ci */
788c2ecf20Sopenharmony_cistruct control_block_extended_exc_detail {
798c2ecf20Sopenharmony_ci	unsigned long	cb;
808c2ecf20Sopenharmony_ci	int		opc;
818c2ecf20Sopenharmony_ci	int		ecause;
828c2ecf20Sopenharmony_ci	int		exopc;
838c2ecf20Sopenharmony_ci	long		exceptdet0;
848c2ecf20Sopenharmony_ci	int		exceptdet1;
858c2ecf20Sopenharmony_ci	int		cbrstate;
868c2ecf20Sopenharmony_ci	int		cbrexecstatus;
878c2ecf20Sopenharmony_ci};
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci/*
908c2ecf20Sopenharmony_ci * Instruction formats
918c2ecf20Sopenharmony_ci */
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci/*
948c2ecf20Sopenharmony_ci * Generic instruction format.
958c2ecf20Sopenharmony_ci * This definition has precise bit field definitions.
968c2ecf20Sopenharmony_ci */
978c2ecf20Sopenharmony_cistruct gru_instruction_bits {
988c2ecf20Sopenharmony_ci    /* DW 0  - low */
998c2ecf20Sopenharmony_ci    unsigned int		icmd:      1;
1008c2ecf20Sopenharmony_ci    unsigned char		ima:	   3;	/* CB_DelRep, unmapped mode */
1018c2ecf20Sopenharmony_ci    unsigned char		reserved0: 4;
1028c2ecf20Sopenharmony_ci    unsigned int		xtype:     3;
1038c2ecf20Sopenharmony_ci    unsigned int		iaa0:      2;
1048c2ecf20Sopenharmony_ci    unsigned int		iaa1:      2;
1058c2ecf20Sopenharmony_ci    unsigned char		reserved1: 1;
1068c2ecf20Sopenharmony_ci    unsigned char		opc:       8;	/* opcode */
1078c2ecf20Sopenharmony_ci    unsigned char		exopc:     8;	/* extended opcode */
1088c2ecf20Sopenharmony_ci    /* DW 0  - high */
1098c2ecf20Sopenharmony_ci    unsigned int		idef2:    22;	/* TRi0 */
1108c2ecf20Sopenharmony_ci    unsigned char		reserved2: 2;
1118c2ecf20Sopenharmony_ci    unsigned char		istatus:   2;
1128c2ecf20Sopenharmony_ci    unsigned char		isubstatus:4;
1138c2ecf20Sopenharmony_ci    unsigned char		reserved3: 1;
1148c2ecf20Sopenharmony_ci    unsigned char		tlb_fault_color: 1;
1158c2ecf20Sopenharmony_ci    /* DW 1 */
1168c2ecf20Sopenharmony_ci    unsigned long		idef4;		/* 42 bits: TRi1, BufSize */
1178c2ecf20Sopenharmony_ci    /* DW 2-6 */
1188c2ecf20Sopenharmony_ci    unsigned long		idef1;		/* BAddr0 */
1198c2ecf20Sopenharmony_ci    unsigned long		idef5;		/* Nelem */
1208c2ecf20Sopenharmony_ci    unsigned long		idef6;		/* Stride, Operand1 */
1218c2ecf20Sopenharmony_ci    unsigned long		idef3;		/* BAddr1, Value, Operand2 */
1228c2ecf20Sopenharmony_ci    unsigned long		reserved4;
1238c2ecf20Sopenharmony_ci    /* DW 7 */
1248c2ecf20Sopenharmony_ci    unsigned long		avalue;		 /* AValue */
1258c2ecf20Sopenharmony_ci};
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci/*
1288c2ecf20Sopenharmony_ci * Generic instruction with friendlier names. This format is used
1298c2ecf20Sopenharmony_ci * for inline instructions.
1308c2ecf20Sopenharmony_ci */
1318c2ecf20Sopenharmony_cistruct gru_instruction {
1328c2ecf20Sopenharmony_ci    /* DW 0 */
1338c2ecf20Sopenharmony_ci    union {
1348c2ecf20Sopenharmony_ci    	unsigned long		op64;    /* icmd,xtype,iaa0,ima,opc,tri0 */
1358c2ecf20Sopenharmony_ci	struct {
1368c2ecf20Sopenharmony_ci		unsigned int	op32;
1378c2ecf20Sopenharmony_ci		unsigned int	tri0;
1388c2ecf20Sopenharmony_ci	};
1398c2ecf20Sopenharmony_ci    };
1408c2ecf20Sopenharmony_ci    unsigned long		tri1_bufsize;		/* DW 1 */
1418c2ecf20Sopenharmony_ci    unsigned long		baddr0;			/* DW 2 */
1428c2ecf20Sopenharmony_ci    unsigned long		nelem;			/* DW 3 */
1438c2ecf20Sopenharmony_ci    unsigned long		op1_stride;		/* DW 4 */
1448c2ecf20Sopenharmony_ci    unsigned long		op2_value_baddr1;	/* DW 5 */
1458c2ecf20Sopenharmony_ci    unsigned long		reserved0;		/* DW 6 */
1468c2ecf20Sopenharmony_ci    unsigned long		avalue;			/* DW 7 */
1478c2ecf20Sopenharmony_ci};
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci/* Some shifts and masks for the low 64 bits of a GRU command */
1508c2ecf20Sopenharmony_ci#define GRU_CB_ICMD_SHFT	0
1518c2ecf20Sopenharmony_ci#define GRU_CB_ICMD_MASK	0x1
1528c2ecf20Sopenharmony_ci#define GRU_CB_XTYPE_SHFT	8
1538c2ecf20Sopenharmony_ci#define GRU_CB_XTYPE_MASK	0x7
1548c2ecf20Sopenharmony_ci#define GRU_CB_IAA0_SHFT	11
1558c2ecf20Sopenharmony_ci#define GRU_CB_IAA0_MASK	0x3
1568c2ecf20Sopenharmony_ci#define GRU_CB_IAA1_SHFT	13
1578c2ecf20Sopenharmony_ci#define GRU_CB_IAA1_MASK	0x3
1588c2ecf20Sopenharmony_ci#define GRU_CB_IMA_SHFT		1
1598c2ecf20Sopenharmony_ci#define GRU_CB_IMA_MASK		0x3
1608c2ecf20Sopenharmony_ci#define GRU_CB_OPC_SHFT		16
1618c2ecf20Sopenharmony_ci#define GRU_CB_OPC_MASK		0xff
1628c2ecf20Sopenharmony_ci#define GRU_CB_EXOPC_SHFT	24
1638c2ecf20Sopenharmony_ci#define GRU_CB_EXOPC_MASK	0xff
1648c2ecf20Sopenharmony_ci#define GRU_IDEF2_SHFT		32
1658c2ecf20Sopenharmony_ci#define GRU_IDEF2_MASK		0x3ffff
1668c2ecf20Sopenharmony_ci#define GRU_ISTATUS_SHFT	56
1678c2ecf20Sopenharmony_ci#define GRU_ISTATUS_MASK	0x3
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci/* GRU instruction opcodes (opc field) */
1708c2ecf20Sopenharmony_ci#define OP_NOP		0x00
1718c2ecf20Sopenharmony_ci#define OP_BCOPY	0x01
1728c2ecf20Sopenharmony_ci#define OP_VLOAD	0x02
1738c2ecf20Sopenharmony_ci#define OP_IVLOAD	0x03
1748c2ecf20Sopenharmony_ci#define OP_VSTORE	0x04
1758c2ecf20Sopenharmony_ci#define OP_IVSTORE	0x05
1768c2ecf20Sopenharmony_ci#define OP_VSET		0x06
1778c2ecf20Sopenharmony_ci#define OP_IVSET	0x07
1788c2ecf20Sopenharmony_ci#define OP_MESQ		0x08
1798c2ecf20Sopenharmony_ci#define OP_GAMXR	0x09
1808c2ecf20Sopenharmony_ci#define OP_GAMIR	0x0a
1818c2ecf20Sopenharmony_ci#define OP_GAMIRR	0x0b
1828c2ecf20Sopenharmony_ci#define OP_GAMER	0x0c
1838c2ecf20Sopenharmony_ci#define OP_GAMERR	0x0d
1848c2ecf20Sopenharmony_ci#define OP_BSTORE	0x0e
1858c2ecf20Sopenharmony_ci#define OP_VFLUSH	0x0f
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci/* Extended opcodes values (exopc field) */
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci/* GAMIR - AMOs with implicit operands */
1918c2ecf20Sopenharmony_ci#define EOP_IR_FETCH	0x01 /* Plain fetch of memory */
1928c2ecf20Sopenharmony_ci#define EOP_IR_CLR	0x02 /* Fetch and clear */
1938c2ecf20Sopenharmony_ci#define EOP_IR_INC	0x05 /* Fetch and increment */
1948c2ecf20Sopenharmony_ci#define EOP_IR_DEC	0x07 /* Fetch and decrement */
1958c2ecf20Sopenharmony_ci#define EOP_IR_QCHK1	0x0d /* Queue check, 64 byte msg */
1968c2ecf20Sopenharmony_ci#define EOP_IR_QCHK2	0x0e /* Queue check, 128 byte msg */
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci/* GAMIRR - Registered AMOs with implicit operands */
1998c2ecf20Sopenharmony_ci#define EOP_IRR_FETCH	0x01 /* Registered fetch of memory */
2008c2ecf20Sopenharmony_ci#define EOP_IRR_CLR	0x02 /* Registered fetch and clear */
2018c2ecf20Sopenharmony_ci#define EOP_IRR_INC	0x05 /* Registered fetch and increment */
2028c2ecf20Sopenharmony_ci#define EOP_IRR_DEC	0x07 /* Registered fetch and decrement */
2038c2ecf20Sopenharmony_ci#define EOP_IRR_DECZ	0x0f /* Registered fetch and decrement, update on zero*/
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci/* GAMER - AMOs with explicit operands */
2068c2ecf20Sopenharmony_ci#define EOP_ER_SWAP	0x00 /* Exchange argument and memory */
2078c2ecf20Sopenharmony_ci#define EOP_ER_OR	0x01 /* Logical OR with memory */
2088c2ecf20Sopenharmony_ci#define EOP_ER_AND	0x02 /* Logical AND with memory */
2098c2ecf20Sopenharmony_ci#define EOP_ER_XOR	0x03 /* Logical XOR with memory */
2108c2ecf20Sopenharmony_ci#define EOP_ER_ADD	0x04 /* Add value to memory */
2118c2ecf20Sopenharmony_ci#define EOP_ER_CSWAP	0x08 /* Compare with operand2, write operand1 if match*/
2128c2ecf20Sopenharmony_ci#define EOP_ER_CADD	0x0c /* Queue check, operand1*64 byte msg */
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci/* GAMERR - Registered AMOs with explicit operands */
2158c2ecf20Sopenharmony_ci#define EOP_ERR_SWAP	0x00 /* Exchange argument and memory */
2168c2ecf20Sopenharmony_ci#define EOP_ERR_OR	0x01 /* Logical OR with memory */
2178c2ecf20Sopenharmony_ci#define EOP_ERR_AND	0x02 /* Logical AND with memory */
2188c2ecf20Sopenharmony_ci#define EOP_ERR_XOR	0x03 /* Logical XOR with memory */
2198c2ecf20Sopenharmony_ci#define EOP_ERR_ADD	0x04 /* Add value to memory */
2208c2ecf20Sopenharmony_ci#define EOP_ERR_CSWAP	0x08 /* Compare with operand2, write operand1 if match*/
2218c2ecf20Sopenharmony_ci#define EOP_ERR_EPOLL	0x09 /* Poll for equality */
2228c2ecf20Sopenharmony_ci#define EOP_ERR_NPOLL	0x0a /* Poll for inequality */
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci/* GAMXR - SGI Arithmetic unit */
2258c2ecf20Sopenharmony_ci#define EOP_XR_CSWAP	0x0b /* Masked compare exchange */
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci/* Transfer types (xtype field) */
2298c2ecf20Sopenharmony_ci#define XTYPE_B		0x0	/* byte */
2308c2ecf20Sopenharmony_ci#define XTYPE_S		0x1	/* short (2-byte) */
2318c2ecf20Sopenharmony_ci#define XTYPE_W		0x2	/* word (4-byte) */
2328c2ecf20Sopenharmony_ci#define XTYPE_DW	0x3	/* doubleword (8-byte) */
2338c2ecf20Sopenharmony_ci#define XTYPE_CL	0x6	/* cacheline (64-byte) */
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci/* Instruction access attributes (iaa0, iaa1 fields) */
2378c2ecf20Sopenharmony_ci#define IAA_RAM		0x0	/* normal cached RAM access */
2388c2ecf20Sopenharmony_ci#define IAA_NCRAM	0x2	/* noncoherent RAM access */
2398c2ecf20Sopenharmony_ci#define IAA_MMIO	0x1	/* noncoherent memory-mapped I/O space */
2408c2ecf20Sopenharmony_ci#define IAA_REGISTER	0x3	/* memory-mapped registers, etc. */
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci/* Instruction mode attributes (ima field) */
2448c2ecf20Sopenharmony_ci#define IMA_MAPPED	0x0	/* Virtual mode  */
2458c2ecf20Sopenharmony_ci#define IMA_CB_DELAY	0x1	/* hold read responses until status changes */
2468c2ecf20Sopenharmony_ci#define IMA_UNMAPPED	0x2	/* bypass the TLBs (OS only) */
2478c2ecf20Sopenharmony_ci#define IMA_INTERRUPT	0x4	/* Interrupt when instruction completes */
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci/* CBE ecause bits */
2508c2ecf20Sopenharmony_ci#define CBE_CAUSE_RI				(1 << 0)
2518c2ecf20Sopenharmony_ci#define CBE_CAUSE_INVALID_INSTRUCTION		(1 << 1)
2528c2ecf20Sopenharmony_ci#define CBE_CAUSE_UNMAPPED_MODE_FORBIDDEN	(1 << 2)
2538c2ecf20Sopenharmony_ci#define CBE_CAUSE_PE_CHECK_DATA_ERROR		(1 << 3)
2548c2ecf20Sopenharmony_ci#define CBE_CAUSE_IAA_GAA_MISMATCH		(1 << 4)
2558c2ecf20Sopenharmony_ci#define CBE_CAUSE_DATA_SEGMENT_LIMIT_EXCEPTION	(1 << 5)
2568c2ecf20Sopenharmony_ci#define CBE_CAUSE_OS_FATAL_TLB_FAULT		(1 << 6)
2578c2ecf20Sopenharmony_ci#define CBE_CAUSE_EXECUTION_HW_ERROR		(1 << 7)
2588c2ecf20Sopenharmony_ci#define CBE_CAUSE_TLBHW_ERROR			(1 << 8)
2598c2ecf20Sopenharmony_ci#define CBE_CAUSE_RA_REQUEST_TIMEOUT		(1 << 9)
2608c2ecf20Sopenharmony_ci#define CBE_CAUSE_HA_REQUEST_TIMEOUT		(1 << 10)
2618c2ecf20Sopenharmony_ci#define CBE_CAUSE_RA_RESPONSE_FATAL		(1 << 11)
2628c2ecf20Sopenharmony_ci#define CBE_CAUSE_RA_RESPONSE_NON_FATAL		(1 << 12)
2638c2ecf20Sopenharmony_ci#define CBE_CAUSE_HA_RESPONSE_FATAL		(1 << 13)
2648c2ecf20Sopenharmony_ci#define CBE_CAUSE_HA_RESPONSE_NON_FATAL		(1 << 14)
2658c2ecf20Sopenharmony_ci#define CBE_CAUSE_ADDRESS_SPACE_DECODE_ERROR	(1 << 15)
2668c2ecf20Sopenharmony_ci#define CBE_CAUSE_PROTOCOL_STATE_DATA_ERROR	(1 << 16)
2678c2ecf20Sopenharmony_ci#define CBE_CAUSE_RA_RESPONSE_DATA_ERROR	(1 << 17)
2688c2ecf20Sopenharmony_ci#define CBE_CAUSE_HA_RESPONSE_DATA_ERROR	(1 << 18)
2698c2ecf20Sopenharmony_ci#define CBE_CAUSE_FORCED_ERROR			(1 << 19)
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci/* CBE cbrexecstatus bits */
2728c2ecf20Sopenharmony_ci#define CBR_EXS_ABORT_OCC_BIT			0
2738c2ecf20Sopenharmony_ci#define CBR_EXS_INT_OCC_BIT			1
2748c2ecf20Sopenharmony_ci#define CBR_EXS_PENDING_BIT			2
2758c2ecf20Sopenharmony_ci#define CBR_EXS_QUEUED_BIT			3
2768c2ecf20Sopenharmony_ci#define CBR_EXS_TLB_INVAL_BIT			4
2778c2ecf20Sopenharmony_ci#define CBR_EXS_EXCEPTION_BIT			5
2788c2ecf20Sopenharmony_ci#define CBR_EXS_CB_INT_PENDING_BIT		6
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci#define CBR_EXS_ABORT_OCC			(1 << CBR_EXS_ABORT_OCC_BIT)
2818c2ecf20Sopenharmony_ci#define CBR_EXS_INT_OCC				(1 << CBR_EXS_INT_OCC_BIT)
2828c2ecf20Sopenharmony_ci#define CBR_EXS_PENDING				(1 << CBR_EXS_PENDING_BIT)
2838c2ecf20Sopenharmony_ci#define CBR_EXS_QUEUED				(1 << CBR_EXS_QUEUED_BIT)
2848c2ecf20Sopenharmony_ci#define CBR_EXS_TLB_INVAL			(1 << CBR_EXS_TLB_INVAL_BIT)
2858c2ecf20Sopenharmony_ci#define CBR_EXS_EXCEPTION			(1 << CBR_EXS_EXCEPTION_BIT)
2868c2ecf20Sopenharmony_ci#define CBR_EXS_CB_INT_PENDING			(1 << CBR_EXS_CB_INT_PENDING_BIT)
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci/*
2898c2ecf20Sopenharmony_ci * Exceptions are retried for the following cases. If any OTHER bits are set
2908c2ecf20Sopenharmony_ci * in ecause, the exception is not retryable.
2918c2ecf20Sopenharmony_ci */
2928c2ecf20Sopenharmony_ci#define EXCEPTION_RETRY_BITS (CBE_CAUSE_EXECUTION_HW_ERROR |		\
2938c2ecf20Sopenharmony_ci			      CBE_CAUSE_TLBHW_ERROR |			\
2948c2ecf20Sopenharmony_ci			      CBE_CAUSE_RA_REQUEST_TIMEOUT |		\
2958c2ecf20Sopenharmony_ci			      CBE_CAUSE_RA_RESPONSE_NON_FATAL |		\
2968c2ecf20Sopenharmony_ci			      CBE_CAUSE_HA_RESPONSE_NON_FATAL |		\
2978c2ecf20Sopenharmony_ci			      CBE_CAUSE_RA_RESPONSE_DATA_ERROR |	\
2988c2ecf20Sopenharmony_ci			      CBE_CAUSE_HA_RESPONSE_DATA_ERROR		\
2998c2ecf20Sopenharmony_ci			      )
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci/* Message queue head structure */
3028c2ecf20Sopenharmony_ciunion gru_mesqhead {
3038c2ecf20Sopenharmony_ci	unsigned long	val;
3048c2ecf20Sopenharmony_ci	struct {
3058c2ecf20Sopenharmony_ci		unsigned int	head;
3068c2ecf20Sopenharmony_ci		unsigned int	limit;
3078c2ecf20Sopenharmony_ci	};
3088c2ecf20Sopenharmony_ci};
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci/* Generate the low word of a GRU instruction */
3128c2ecf20Sopenharmony_cistatic inline unsigned long
3138c2ecf20Sopenharmony_ci__opdword(unsigned char opcode, unsigned char exopc, unsigned char xtype,
3148c2ecf20Sopenharmony_ci       unsigned char iaa0, unsigned char iaa1,
3158c2ecf20Sopenharmony_ci       unsigned long idef2, unsigned char ima)
3168c2ecf20Sopenharmony_ci{
3178c2ecf20Sopenharmony_ci    return (1 << GRU_CB_ICMD_SHFT) |
3188c2ecf20Sopenharmony_ci	   ((unsigned long)CBS_ACTIVE << GRU_ISTATUS_SHFT) |
3198c2ecf20Sopenharmony_ci	   (idef2<< GRU_IDEF2_SHFT) |
3208c2ecf20Sopenharmony_ci	   (iaa0 << GRU_CB_IAA0_SHFT) |
3218c2ecf20Sopenharmony_ci	   (iaa1 << GRU_CB_IAA1_SHFT) |
3228c2ecf20Sopenharmony_ci	   (ima << GRU_CB_IMA_SHFT) |
3238c2ecf20Sopenharmony_ci	   (xtype << GRU_CB_XTYPE_SHFT) |
3248c2ecf20Sopenharmony_ci	   (opcode << GRU_CB_OPC_SHFT) |
3258c2ecf20Sopenharmony_ci	   (exopc << GRU_CB_EXOPC_SHFT);
3268c2ecf20Sopenharmony_ci}
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci/*
3298c2ecf20Sopenharmony_ci * Architecture specific intrinsics
3308c2ecf20Sopenharmony_ci */
3318c2ecf20Sopenharmony_cistatic inline void gru_flush_cache(void *p)
3328c2ecf20Sopenharmony_ci{
3338c2ecf20Sopenharmony_ci	__flush_cache(p);
3348c2ecf20Sopenharmony_ci}
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci/*
3378c2ecf20Sopenharmony_ci * Store the lower 64 bits of the command including the "start" bit. Then
3388c2ecf20Sopenharmony_ci * start the instruction executing.
3398c2ecf20Sopenharmony_ci */
3408c2ecf20Sopenharmony_cistatic inline void gru_start_instruction(struct gru_instruction *ins, unsigned long op64)
3418c2ecf20Sopenharmony_ci{
3428c2ecf20Sopenharmony_ci	gru_ordered_store_ulong(ins, op64);
3438c2ecf20Sopenharmony_ci	mb();
3448c2ecf20Sopenharmony_ci	gru_flush_cache(ins);
3458c2ecf20Sopenharmony_ci}
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_ci/* Convert "hints" to IMA */
3498c2ecf20Sopenharmony_ci#define CB_IMA(h)		((h) | IMA_UNMAPPED)
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci/* Convert data segment cache line index into TRI0 / TRI1 value */
3528c2ecf20Sopenharmony_ci#define GRU_DINDEX(i)		((i) * GRU_CACHE_LINE_BYTES)
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci/* Inline functions for GRU instructions.
3558c2ecf20Sopenharmony_ci *     Note:
3568c2ecf20Sopenharmony_ci *     	- nelem and stride are in elements
3578c2ecf20Sopenharmony_ci *     	- tri0/tri1 is in bytes for the beginning of the data segment.
3588c2ecf20Sopenharmony_ci */
3598c2ecf20Sopenharmony_cistatic inline void gru_vload_phys(void *cb, unsigned long gpa,
3608c2ecf20Sopenharmony_ci		unsigned int tri0, int iaa, unsigned long hints)
3618c2ecf20Sopenharmony_ci{
3628c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (struct gru_instruction *)cb;
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ci	ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
3658c2ecf20Sopenharmony_ci	ins->nelem = 1;
3668c2ecf20Sopenharmony_ci	ins->op1_stride = 1;
3678c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_VLOAD, 0, XTYPE_DW, iaa, 0,
3688c2ecf20Sopenharmony_ci					(unsigned long)tri0, CB_IMA(hints)));
3698c2ecf20Sopenharmony_ci}
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_cistatic inline void gru_vstore_phys(void *cb, unsigned long gpa,
3728c2ecf20Sopenharmony_ci		unsigned int tri0, int iaa, unsigned long hints)
3738c2ecf20Sopenharmony_ci{
3748c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (struct gru_instruction *)cb;
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci	ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
3778c2ecf20Sopenharmony_ci	ins->nelem = 1;
3788c2ecf20Sopenharmony_ci	ins->op1_stride = 1;
3798c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_VSTORE, 0, XTYPE_DW, iaa, 0,
3808c2ecf20Sopenharmony_ci					(unsigned long)tri0, CB_IMA(hints)));
3818c2ecf20Sopenharmony_ci}
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_cistatic inline void gru_vload(void *cb, unsigned long mem_addr,
3848c2ecf20Sopenharmony_ci		unsigned int tri0, unsigned char xtype, unsigned long nelem,
3858c2ecf20Sopenharmony_ci		unsigned long stride, unsigned long hints)
3868c2ecf20Sopenharmony_ci{
3878c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (struct gru_instruction *)cb;
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci	ins->baddr0 = (long)mem_addr;
3908c2ecf20Sopenharmony_ci	ins->nelem = nelem;
3918c2ecf20Sopenharmony_ci	ins->op1_stride = stride;
3928c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_VLOAD, 0, xtype, IAA_RAM, 0,
3938c2ecf20Sopenharmony_ci					(unsigned long)tri0, CB_IMA(hints)));
3948c2ecf20Sopenharmony_ci}
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_cistatic inline void gru_vstore(void *cb, unsigned long mem_addr,
3978c2ecf20Sopenharmony_ci		unsigned int tri0, unsigned char xtype, unsigned long nelem,
3988c2ecf20Sopenharmony_ci		unsigned long stride, unsigned long hints)
3998c2ecf20Sopenharmony_ci{
4008c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	ins->baddr0 = (long)mem_addr;
4038c2ecf20Sopenharmony_ci	ins->nelem = nelem;
4048c2ecf20Sopenharmony_ci	ins->op1_stride = stride;
4058c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_VSTORE, 0, xtype, IAA_RAM, 0,
4068c2ecf20Sopenharmony_ci					tri0, CB_IMA(hints)));
4078c2ecf20Sopenharmony_ci}
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_cistatic inline void gru_ivload(void *cb, unsigned long mem_addr,
4108c2ecf20Sopenharmony_ci		unsigned int tri0, unsigned int tri1, unsigned char xtype,
4118c2ecf20Sopenharmony_ci		unsigned long nelem, unsigned long hints)
4128c2ecf20Sopenharmony_ci{
4138c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
4148c2ecf20Sopenharmony_ci
4158c2ecf20Sopenharmony_ci	ins->baddr0 = (long)mem_addr;
4168c2ecf20Sopenharmony_ci	ins->nelem = nelem;
4178c2ecf20Sopenharmony_ci	ins->tri1_bufsize = tri1;
4188c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_IVLOAD, 0, xtype, IAA_RAM, 0,
4198c2ecf20Sopenharmony_ci					tri0, CB_IMA(hints)));
4208c2ecf20Sopenharmony_ci}
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_cistatic inline void gru_ivstore(void *cb, unsigned long mem_addr,
4238c2ecf20Sopenharmony_ci		unsigned int tri0, unsigned int tri1,
4248c2ecf20Sopenharmony_ci		unsigned char xtype, unsigned long nelem, unsigned long hints)
4258c2ecf20Sopenharmony_ci{
4268c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci	ins->baddr0 = (long)mem_addr;
4298c2ecf20Sopenharmony_ci	ins->nelem = nelem;
4308c2ecf20Sopenharmony_ci	ins->tri1_bufsize = tri1;
4318c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_IVSTORE, 0, xtype, IAA_RAM, 0,
4328c2ecf20Sopenharmony_ci					tri0, CB_IMA(hints)));
4338c2ecf20Sopenharmony_ci}
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_cistatic inline void gru_vset(void *cb, unsigned long mem_addr,
4368c2ecf20Sopenharmony_ci		unsigned long value, unsigned char xtype, unsigned long nelem,
4378c2ecf20Sopenharmony_ci		unsigned long stride, unsigned long hints)
4388c2ecf20Sopenharmony_ci{
4398c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_ci	ins->baddr0 = (long)mem_addr;
4428c2ecf20Sopenharmony_ci	ins->op2_value_baddr1 = value;
4438c2ecf20Sopenharmony_ci	ins->nelem = nelem;
4448c2ecf20Sopenharmony_ci	ins->op1_stride = stride;
4458c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_VSET, 0, xtype, IAA_RAM, 0,
4468c2ecf20Sopenharmony_ci					 0, CB_IMA(hints)));
4478c2ecf20Sopenharmony_ci}
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_cistatic inline void gru_ivset(void *cb, unsigned long mem_addr,
4508c2ecf20Sopenharmony_ci		unsigned int tri1, unsigned long value, unsigned char xtype,
4518c2ecf20Sopenharmony_ci		unsigned long nelem, unsigned long hints)
4528c2ecf20Sopenharmony_ci{
4538c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci	ins->baddr0 = (long)mem_addr;
4568c2ecf20Sopenharmony_ci	ins->op2_value_baddr1 = value;
4578c2ecf20Sopenharmony_ci	ins->nelem = nelem;
4588c2ecf20Sopenharmony_ci	ins->tri1_bufsize = tri1;
4598c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_IVSET, 0, xtype, IAA_RAM, 0,
4608c2ecf20Sopenharmony_ci					0, CB_IMA(hints)));
4618c2ecf20Sopenharmony_ci}
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_cistatic inline void gru_vflush(void *cb, unsigned long mem_addr,
4648c2ecf20Sopenharmony_ci		unsigned long nelem, unsigned char xtype, unsigned long stride,
4658c2ecf20Sopenharmony_ci		unsigned long hints)
4668c2ecf20Sopenharmony_ci{
4678c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci	ins->baddr0 = (long)mem_addr;
4708c2ecf20Sopenharmony_ci	ins->op1_stride = stride;
4718c2ecf20Sopenharmony_ci	ins->nelem = nelem;
4728c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_VFLUSH, 0, xtype, IAA_RAM, 0,
4738c2ecf20Sopenharmony_ci					0, CB_IMA(hints)));
4748c2ecf20Sopenharmony_ci}
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_cistatic inline void gru_nop(void *cb, int hints)
4778c2ecf20Sopenharmony_ci{
4788c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_NOP, 0, 0, 0, 0, 0, CB_IMA(hints)));
4818c2ecf20Sopenharmony_ci}
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_cistatic inline void gru_bcopy(void *cb, const unsigned long src,
4858c2ecf20Sopenharmony_ci		unsigned long dest,
4868c2ecf20Sopenharmony_ci		unsigned int tri0, unsigned int xtype, unsigned long nelem,
4878c2ecf20Sopenharmony_ci		unsigned int bufsize, unsigned long hints)
4888c2ecf20Sopenharmony_ci{
4898c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci	ins->baddr0 = (long)src;
4928c2ecf20Sopenharmony_ci	ins->op2_value_baddr1 = (long)dest;
4938c2ecf20Sopenharmony_ci	ins->nelem = nelem;
4948c2ecf20Sopenharmony_ci	ins->tri1_bufsize = bufsize;
4958c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_BCOPY, 0, xtype, IAA_RAM,
4968c2ecf20Sopenharmony_ci					IAA_RAM, tri0, CB_IMA(hints)));
4978c2ecf20Sopenharmony_ci}
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_cistatic inline void gru_bstore(void *cb, const unsigned long src,
5008c2ecf20Sopenharmony_ci		unsigned long dest, unsigned int tri0, unsigned int xtype,
5018c2ecf20Sopenharmony_ci		unsigned long nelem, unsigned long hints)
5028c2ecf20Sopenharmony_ci{
5038c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	ins->baddr0 = (long)src;
5068c2ecf20Sopenharmony_ci	ins->op2_value_baddr1 = (long)dest;
5078c2ecf20Sopenharmony_ci	ins->nelem = nelem;
5088c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_BSTORE, 0, xtype, 0, IAA_RAM,
5098c2ecf20Sopenharmony_ci					tri0, CB_IMA(hints)));
5108c2ecf20Sopenharmony_ci}
5118c2ecf20Sopenharmony_ci
5128c2ecf20Sopenharmony_cistatic inline void gru_gamir(void *cb, int exopc, unsigned long src,
5138c2ecf20Sopenharmony_ci		unsigned int xtype, unsigned long hints)
5148c2ecf20Sopenharmony_ci{
5158c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci	ins->baddr0 = (long)src;
5188c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_GAMIR, exopc, xtype, IAA_RAM, 0,
5198c2ecf20Sopenharmony_ci					0, CB_IMA(hints)));
5208c2ecf20Sopenharmony_ci}
5218c2ecf20Sopenharmony_ci
5228c2ecf20Sopenharmony_cistatic inline void gru_gamirr(void *cb, int exopc, unsigned long src,
5238c2ecf20Sopenharmony_ci		unsigned int xtype, unsigned long hints)
5248c2ecf20Sopenharmony_ci{
5258c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
5268c2ecf20Sopenharmony_ci
5278c2ecf20Sopenharmony_ci	ins->baddr0 = (long)src;
5288c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_GAMIRR, exopc, xtype, IAA_RAM, 0,
5298c2ecf20Sopenharmony_ci					0, CB_IMA(hints)));
5308c2ecf20Sopenharmony_ci}
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_cistatic inline void gru_gamer(void *cb, int exopc, unsigned long src,
5338c2ecf20Sopenharmony_ci		unsigned int xtype,
5348c2ecf20Sopenharmony_ci		unsigned long operand1, unsigned long operand2,
5358c2ecf20Sopenharmony_ci		unsigned long hints)
5368c2ecf20Sopenharmony_ci{
5378c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci	ins->baddr0 = (long)src;
5408c2ecf20Sopenharmony_ci	ins->op1_stride = operand1;
5418c2ecf20Sopenharmony_ci	ins->op2_value_baddr1 = operand2;
5428c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_GAMER, exopc, xtype, IAA_RAM, 0,
5438c2ecf20Sopenharmony_ci					0, CB_IMA(hints)));
5448c2ecf20Sopenharmony_ci}
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_cistatic inline void gru_gamerr(void *cb, int exopc, unsigned long src,
5478c2ecf20Sopenharmony_ci		unsigned int xtype, unsigned long operand1,
5488c2ecf20Sopenharmony_ci		unsigned long operand2, unsigned long hints)
5498c2ecf20Sopenharmony_ci{
5508c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	ins->baddr0 = (long)src;
5538c2ecf20Sopenharmony_ci	ins->op1_stride = operand1;
5548c2ecf20Sopenharmony_ci	ins->op2_value_baddr1 = operand2;
5558c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_GAMERR, exopc, xtype, IAA_RAM, 0,
5568c2ecf20Sopenharmony_ci					0, CB_IMA(hints)));
5578c2ecf20Sopenharmony_ci}
5588c2ecf20Sopenharmony_ci
5598c2ecf20Sopenharmony_cistatic inline void gru_gamxr(void *cb, unsigned long src,
5608c2ecf20Sopenharmony_ci		unsigned int tri0, unsigned long hints)
5618c2ecf20Sopenharmony_ci{
5628c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_ci	ins->baddr0 = (long)src;
5658c2ecf20Sopenharmony_ci	ins->nelem = 4;
5668c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_GAMXR, EOP_XR_CSWAP, XTYPE_DW,
5678c2ecf20Sopenharmony_ci				 IAA_RAM, 0, 0, CB_IMA(hints)));
5688c2ecf20Sopenharmony_ci}
5698c2ecf20Sopenharmony_ci
5708c2ecf20Sopenharmony_cistatic inline void gru_mesq(void *cb, unsigned long queue,
5718c2ecf20Sopenharmony_ci		unsigned long tri0, unsigned long nelem,
5728c2ecf20Sopenharmony_ci		unsigned long hints)
5738c2ecf20Sopenharmony_ci{
5748c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
5758c2ecf20Sopenharmony_ci
5768c2ecf20Sopenharmony_ci	ins->baddr0 = (long)queue;
5778c2ecf20Sopenharmony_ci	ins->nelem = nelem;
5788c2ecf20Sopenharmony_ci	gru_start_instruction(ins, __opdword(OP_MESQ, 0, XTYPE_CL, IAA_RAM, 0,
5798c2ecf20Sopenharmony_ci					tri0, CB_IMA(hints)));
5808c2ecf20Sopenharmony_ci}
5818c2ecf20Sopenharmony_ci
5828c2ecf20Sopenharmony_cistatic inline unsigned long gru_get_amo_value(void *cb)
5838c2ecf20Sopenharmony_ci{
5848c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_ci	return ins->avalue;
5878c2ecf20Sopenharmony_ci}
5888c2ecf20Sopenharmony_ci
5898c2ecf20Sopenharmony_cistatic inline int gru_get_amo_value_head(void *cb)
5908c2ecf20Sopenharmony_ci{
5918c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_ci	return ins->avalue & 0xffffffff;
5948c2ecf20Sopenharmony_ci}
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_cistatic inline int gru_get_amo_value_limit(void *cb)
5978c2ecf20Sopenharmony_ci{
5988c2ecf20Sopenharmony_ci	struct gru_instruction *ins = (void *)cb;
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ci	return ins->avalue >> 32;
6018c2ecf20Sopenharmony_ci}
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_cistatic inline union gru_mesqhead  gru_mesq_head(int head, int limit)
6048c2ecf20Sopenharmony_ci{
6058c2ecf20Sopenharmony_ci	union gru_mesqhead mqh;
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci	mqh.head = head;
6088c2ecf20Sopenharmony_ci	mqh.limit = limit;
6098c2ecf20Sopenharmony_ci	return mqh;
6108c2ecf20Sopenharmony_ci}
6118c2ecf20Sopenharmony_ci
6128c2ecf20Sopenharmony_ci/*
6138c2ecf20Sopenharmony_ci * Get struct control_block_extended_exc_detail for CB.
6148c2ecf20Sopenharmony_ci */
6158c2ecf20Sopenharmony_ciextern int gru_get_cb_exception_detail(void *cb,
6168c2ecf20Sopenharmony_ci		       struct control_block_extended_exc_detail *excdet);
6178c2ecf20Sopenharmony_ci
6188c2ecf20Sopenharmony_ci#define GRU_EXC_STR_SIZE		256
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_ci
6218c2ecf20Sopenharmony_ci/*
6228c2ecf20Sopenharmony_ci * Control block definition for checking status
6238c2ecf20Sopenharmony_ci */
6248c2ecf20Sopenharmony_cistruct gru_control_block_status {
6258c2ecf20Sopenharmony_ci	unsigned int	icmd		:1;
6268c2ecf20Sopenharmony_ci	unsigned int	ima		:3;
6278c2ecf20Sopenharmony_ci	unsigned int	reserved0	:4;
6288c2ecf20Sopenharmony_ci	unsigned int	unused1		:24;
6298c2ecf20Sopenharmony_ci	unsigned int	unused2		:24;
6308c2ecf20Sopenharmony_ci	unsigned int	istatus		:2;
6318c2ecf20Sopenharmony_ci	unsigned int	isubstatus	:4;
6328c2ecf20Sopenharmony_ci	unsigned int	unused3		:2;
6338c2ecf20Sopenharmony_ci};
6348c2ecf20Sopenharmony_ci
6358c2ecf20Sopenharmony_ci/* Get CB status */
6368c2ecf20Sopenharmony_cistatic inline int gru_get_cb_status(void *cb)
6378c2ecf20Sopenharmony_ci{
6388c2ecf20Sopenharmony_ci	struct gru_control_block_status *cbs = (void *)cb;
6398c2ecf20Sopenharmony_ci
6408c2ecf20Sopenharmony_ci	return cbs->istatus;
6418c2ecf20Sopenharmony_ci}
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci/* Get CB message queue substatus */
6448c2ecf20Sopenharmony_cistatic inline int gru_get_cb_message_queue_substatus(void *cb)
6458c2ecf20Sopenharmony_ci{
6468c2ecf20Sopenharmony_ci	struct gru_control_block_status *cbs = (void *)cb;
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci	return cbs->isubstatus & CBSS_MSG_QUEUE_MASK;
6498c2ecf20Sopenharmony_ci}
6508c2ecf20Sopenharmony_ci
6518c2ecf20Sopenharmony_ci/* Get CB substatus */
6528c2ecf20Sopenharmony_cistatic inline int gru_get_cb_substatus(void *cb)
6538c2ecf20Sopenharmony_ci{
6548c2ecf20Sopenharmony_ci	struct gru_control_block_status *cbs = (void *)cb;
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci	return cbs->isubstatus;
6578c2ecf20Sopenharmony_ci}
6588c2ecf20Sopenharmony_ci
6598c2ecf20Sopenharmony_ci/*
6608c2ecf20Sopenharmony_ci * User interface to check an instruction status. UPM and exceptions
6618c2ecf20Sopenharmony_ci * are handled automatically. However, this function does NOT wait
6628c2ecf20Sopenharmony_ci * for an active instruction to complete.
6638c2ecf20Sopenharmony_ci *
6648c2ecf20Sopenharmony_ci */
6658c2ecf20Sopenharmony_cistatic inline int gru_check_status(void *cb)
6668c2ecf20Sopenharmony_ci{
6678c2ecf20Sopenharmony_ci	struct gru_control_block_status *cbs = (void *)cb;
6688c2ecf20Sopenharmony_ci	int ret;
6698c2ecf20Sopenharmony_ci
6708c2ecf20Sopenharmony_ci	ret = cbs->istatus;
6718c2ecf20Sopenharmony_ci	if (ret != CBS_ACTIVE)
6728c2ecf20Sopenharmony_ci		ret = gru_check_status_proc(cb);
6738c2ecf20Sopenharmony_ci	return ret;
6748c2ecf20Sopenharmony_ci}
6758c2ecf20Sopenharmony_ci
6768c2ecf20Sopenharmony_ci/*
6778c2ecf20Sopenharmony_ci * User interface (via inline function) to wait for an instruction
6788c2ecf20Sopenharmony_ci * to complete. Completion status (IDLE or EXCEPTION is returned
6798c2ecf20Sopenharmony_ci * to the user. Exception due to hardware errors are automatically
6808c2ecf20Sopenharmony_ci * retried before returning an exception.
6818c2ecf20Sopenharmony_ci *
6828c2ecf20Sopenharmony_ci */
6838c2ecf20Sopenharmony_cistatic inline int gru_wait(void *cb)
6848c2ecf20Sopenharmony_ci{
6858c2ecf20Sopenharmony_ci	return gru_wait_proc(cb);
6868c2ecf20Sopenharmony_ci}
6878c2ecf20Sopenharmony_ci
6888c2ecf20Sopenharmony_ci/*
6898c2ecf20Sopenharmony_ci * Wait for CB to complete. Aborts program if error. (Note: error does NOT
6908c2ecf20Sopenharmony_ci * mean TLB mis - only fatal errors such as memory parity error or user
6918c2ecf20Sopenharmony_ci * bugs will cause termination.
6928c2ecf20Sopenharmony_ci */
6938c2ecf20Sopenharmony_cistatic inline void gru_wait_abort(void *cb)
6948c2ecf20Sopenharmony_ci{
6958c2ecf20Sopenharmony_ci	gru_wait_abort_proc(cb);
6968c2ecf20Sopenharmony_ci}
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci/*
6998c2ecf20Sopenharmony_ci * Get a pointer to the start of a gseg
7008c2ecf20Sopenharmony_ci * 	p	- Any valid pointer within the gseg
7018c2ecf20Sopenharmony_ci */
7028c2ecf20Sopenharmony_cistatic inline void *gru_get_gseg_pointer (void *p)
7038c2ecf20Sopenharmony_ci{
7048c2ecf20Sopenharmony_ci	return (void *)((unsigned long)p & ~(GRU_GSEG_PAGESIZE - 1));
7058c2ecf20Sopenharmony_ci}
7068c2ecf20Sopenharmony_ci
7078c2ecf20Sopenharmony_ci/*
7088c2ecf20Sopenharmony_ci * Get a pointer to a control block
7098c2ecf20Sopenharmony_ci * 	gseg	- GSeg address returned from gru_get_thread_gru_segment()
7108c2ecf20Sopenharmony_ci * 	index	- index of desired CB
7118c2ecf20Sopenharmony_ci */
7128c2ecf20Sopenharmony_cistatic inline void *gru_get_cb_pointer(void *gseg,
7138c2ecf20Sopenharmony_ci						      int index)
7148c2ecf20Sopenharmony_ci{
7158c2ecf20Sopenharmony_ci	return gseg + GRU_CB_BASE + index * GRU_HANDLE_STRIDE;
7168c2ecf20Sopenharmony_ci}
7178c2ecf20Sopenharmony_ci
7188c2ecf20Sopenharmony_ci/*
7198c2ecf20Sopenharmony_ci * Get a pointer to a cacheline in the data segment portion of a GSeg
7208c2ecf20Sopenharmony_ci * 	gseg	- GSeg address returned from gru_get_thread_gru_segment()
7218c2ecf20Sopenharmony_ci * 	index	- index of desired cache line
7228c2ecf20Sopenharmony_ci */
7238c2ecf20Sopenharmony_cistatic inline void *gru_get_data_pointer(void *gseg, int index)
7248c2ecf20Sopenharmony_ci{
7258c2ecf20Sopenharmony_ci	return gseg + GRU_DS_BASE + index * GRU_CACHE_LINE_BYTES;
7268c2ecf20Sopenharmony_ci}
7278c2ecf20Sopenharmony_ci
7288c2ecf20Sopenharmony_ci/*
7298c2ecf20Sopenharmony_ci * Convert a vaddr into the tri index within the GSEG
7308c2ecf20Sopenharmony_ci * 	vaddr		- virtual address of within gseg
7318c2ecf20Sopenharmony_ci */
7328c2ecf20Sopenharmony_cistatic inline int gru_get_tri(void *vaddr)
7338c2ecf20Sopenharmony_ci{
7348c2ecf20Sopenharmony_ci	return ((unsigned long)vaddr & (GRU_GSEG_PAGESIZE - 1)) - GRU_DS_BASE;
7358c2ecf20Sopenharmony_ci}
7368c2ecf20Sopenharmony_ci#endif		/* __GRU_INSTRUCTIONS_H__ */
737