| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved. | 
 | 3 |  * | 
 | 4 |  *  This program is free software; you can redistribute it and/or modify | 
 | 5 |  *  it under the terms of the GNU Lesser General Public License as published by | 
 | 6 |  *  the Free Software Foundation; either version 2.1 of the License, or | 
 | 7 |  *  (at your option) any later version. | 
 | 8 |  * | 
 | 9 |  *  This program is distributed in the hope that it will be useful, | 
 | 10 |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | 11 |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 | 12 |  *  GNU Lesser General Public License for more details. | 
 | 13 |  * | 
 | 14 |  *  You should have received a copy of the GNU Lesser General Public License | 
 | 15 |  *  along with this program; if not, write to the Free Software | 
 | 16 |  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA | 
 | 17 |  */ | 
 | 18 |  | 
 | 19 | #ifndef __GRU_INSTRUCTIONS_H__ | 
 | 20 | #define __GRU_INSTRUCTIONS_H__ | 
 | 21 |  | 
| Jack Steiner | fe5bb6b | 2009-04-02 16:59:04 -0700 | [diff] [blame] | 22 | extern int gru_check_status_proc(void *cb); | 
 | 23 | extern int gru_wait_proc(void *cb); | 
 | 24 | extern void gru_wait_abort_proc(void *cb); | 
 | 25 |  | 
 | 26 |  | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 27 |  | 
 | 28 | /* | 
 | 29 |  * Architecture dependent functions | 
 | 30 |  */ | 
 | 31 |  | 
| Jack Steiner | 923f7f6 | 2008-10-15 22:05:13 -0700 | [diff] [blame] | 32 | #if defined(CONFIG_IA64) | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 33 | #include <linux/compiler.h> | 
 | 34 | #include <asm/intrinsics.h> | 
| Jack Steiner | fe5bb6b | 2009-04-02 16:59:04 -0700 | [diff] [blame] | 35 | #define __flush_cache(p)		ia64_fc((unsigned long)p) | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 36 | /* Use volatile on IA64 to ensure ordering via st4.rel */ | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 37 | #define gru_ordered_store_ulong(p, v)					\ | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 38 | 		do {							\ | 
 | 39 | 			barrier();					\ | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 40 | 			*((volatile unsigned long *)(p)) = v; /* force st.rel */	\ | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 41 | 		} while (0) | 
| Jack Steiner | 923f7f6 | 2008-10-15 22:05:13 -0700 | [diff] [blame] | 42 | #elif defined(CONFIG_X86_64) | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 43 | #define __flush_cache(p)		clflush(p) | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 44 | #define gru_ordered_store_ulong(p, v)					\ | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 45 | 		do {							\ | 
 | 46 | 			barrier();					\ | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 47 | 			*(unsigned long *)p = v;			\ | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 48 | 		} while (0) | 
 | 49 | #else | 
 | 50 | #error "Unsupported architecture" | 
 | 51 | #endif | 
 | 52 |  | 
 | 53 | /* | 
 | 54 |  * Control block status and exception codes | 
 | 55 |  */ | 
 | 56 | #define CBS_IDLE			0 | 
 | 57 | #define CBS_EXCEPTION			1 | 
 | 58 | #define CBS_ACTIVE			2 | 
 | 59 | #define CBS_CALL_OS			3 | 
 | 60 |  | 
 | 61 | /* CB substatus bitmasks */ | 
 | 62 | #define CBSS_MSG_QUEUE_MASK		7 | 
 | 63 | #define CBSS_IMPLICIT_ABORT_ACTIVE_MASK	8 | 
 | 64 |  | 
 | 65 | /* CB substatus message queue values (low 3 bits of substatus) */ | 
 | 66 | #define CBSS_NO_ERROR			0 | 
 | 67 | #define CBSS_LB_OVERFLOWED		1 | 
 | 68 | #define CBSS_QLIMIT_REACHED		2 | 
 | 69 | #define CBSS_PAGE_OVERFLOW		3 | 
 | 70 | #define CBSS_AMO_NACKED			4 | 
 | 71 | #define CBSS_PUT_NACKED			5 | 
 | 72 |  | 
 | 73 | /* | 
 | 74 |  * Structure used to fetch exception detail for CBs that terminate with | 
 | 75 |  * CBS_EXCEPTION | 
 | 76 |  */ | 
 | 77 | struct control_block_extended_exc_detail { | 
 | 78 | 	unsigned long	cb; | 
 | 79 | 	int		opc; | 
 | 80 | 	int		ecause; | 
 | 81 | 	int		exopc; | 
 | 82 | 	long		exceptdet0; | 
 | 83 | 	int		exceptdet1; | 
| Jack Steiner | cd1334f | 2009-06-17 16:28:19 -0700 | [diff] [blame] | 84 | 	int		cbrstate; | 
 | 85 | 	int		cbrexecstatus; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 86 | }; | 
 | 87 |  | 
 | 88 | /* | 
 | 89 |  * Instruction formats | 
 | 90 |  */ | 
 | 91 |  | 
 | 92 | /* | 
 | 93 |  * Generic instruction format. | 
 | 94 |  * This definition has precise bit field definitions. | 
 | 95 |  */ | 
 | 96 | struct gru_instruction_bits { | 
 | 97 |     /* DW 0  - low */ | 
 | 98 |     unsigned int		icmd:      1; | 
 | 99 |     unsigned char		ima:	   3;	/* CB_DelRep, unmapped mode */ | 
 | 100 |     unsigned char		reserved0: 4; | 
 | 101 |     unsigned int		xtype:     3; | 
 | 102 |     unsigned int		iaa0:      2; | 
 | 103 |     unsigned int		iaa1:      2; | 
 | 104 |     unsigned char		reserved1: 1; | 
 | 105 |     unsigned char		opc:       8;	/* opcode */ | 
 | 106 |     unsigned char		exopc:     8;	/* extended opcode */ | 
 | 107 |     /* DW 0  - high */ | 
 | 108 |     unsigned int		idef2:    22;	/* TRi0 */ | 
 | 109 |     unsigned char		reserved2: 2; | 
 | 110 |     unsigned char		istatus:   2; | 
 | 111 |     unsigned char		isubstatus:4; | 
| Jack Steiner | cd1334f | 2009-06-17 16:28:19 -0700 | [diff] [blame] | 112 |     unsigned char		reserved3: 1; | 
 | 113 |     unsigned char		tlb_fault_color: 1; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 114 |     /* DW 1 */ | 
 | 115 |     unsigned long		idef4;		/* 42 bits: TRi1, BufSize */ | 
 | 116 |     /* DW 2-6 */ | 
 | 117 |     unsigned long		idef1;		/* BAddr0 */ | 
 | 118 |     unsigned long		idef5;		/* Nelem */ | 
 | 119 |     unsigned long		idef6;		/* Stride, Operand1 */ | 
 | 120 |     unsigned long		idef3;		/* BAddr1, Value, Operand2 */ | 
 | 121 |     unsigned long		reserved4; | 
 | 122 |     /* DW 7 */ | 
 | 123 |     unsigned long		avalue;		 /* AValue */ | 
 | 124 | }; | 
 | 125 |  | 
 | 126 | /* | 
 | 127 |  * Generic instruction with friendlier names. This format is used | 
 | 128 |  * for inline instructions. | 
 | 129 |  */ | 
 | 130 | struct gru_instruction { | 
 | 131 |     /* DW 0 */ | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 132 |     union { | 
 | 133 |     	unsigned long		op64;    /* icmd,xtype,iaa0,ima,opc,tri0 */ | 
 | 134 | 	struct { | 
 | 135 | 		unsigned int	op32; | 
 | 136 | 		unsigned int	tri0; | 
 | 137 | 	}; | 
 | 138 |     }; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 139 |     unsigned long		tri1_bufsize;		/* DW 1 */ | 
 | 140 |     unsigned long		baddr0;			/* DW 2 */ | 
 | 141 |     unsigned long		nelem;			/* DW 3 */ | 
 | 142 |     unsigned long		op1_stride;		/* DW 4 */ | 
 | 143 |     unsigned long		op2_value_baddr1;	/* DW 5 */ | 
 | 144 |     unsigned long		reserved0;		/* DW 6 */ | 
 | 145 |     unsigned long		avalue;			/* DW 7 */ | 
 | 146 | }; | 
 | 147 |  | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 148 | /* Some shifts and masks for the low 64 bits of a GRU command */ | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 149 | #define GRU_CB_ICMD_SHFT	0 | 
 | 150 | #define GRU_CB_ICMD_MASK	0x1 | 
 | 151 | #define GRU_CB_XTYPE_SHFT	8 | 
 | 152 | #define GRU_CB_XTYPE_MASK	0x7 | 
 | 153 | #define GRU_CB_IAA0_SHFT	11 | 
 | 154 | #define GRU_CB_IAA0_MASK	0x3 | 
 | 155 | #define GRU_CB_IAA1_SHFT	13 | 
 | 156 | #define GRU_CB_IAA1_MASK	0x3 | 
 | 157 | #define GRU_CB_IMA_SHFT		1 | 
 | 158 | #define GRU_CB_IMA_MASK		0x3 | 
 | 159 | #define GRU_CB_OPC_SHFT		16 | 
 | 160 | #define GRU_CB_OPC_MASK		0xff | 
 | 161 | #define GRU_CB_EXOPC_SHFT	24 | 
 | 162 | #define GRU_CB_EXOPC_MASK	0xff | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 163 | #define GRU_IDEF2_SHFT		32 | 
 | 164 | #define GRU_IDEF2_MASK		0x3ffff | 
 | 165 | #define GRU_ISTATUS_SHFT	56 | 
 | 166 | #define GRU_ISTATUS_MASK	0x3 | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 167 |  | 
 | 168 | /* GRU instruction opcodes (opc field) */ | 
 | 169 | #define OP_NOP		0x00 | 
 | 170 | #define OP_BCOPY	0x01 | 
 | 171 | #define OP_VLOAD	0x02 | 
 | 172 | #define OP_IVLOAD	0x03 | 
 | 173 | #define OP_VSTORE	0x04 | 
 | 174 | #define OP_IVSTORE	0x05 | 
 | 175 | #define OP_VSET		0x06 | 
 | 176 | #define OP_IVSET	0x07 | 
 | 177 | #define OP_MESQ		0x08 | 
 | 178 | #define OP_GAMXR	0x09 | 
 | 179 | #define OP_GAMIR	0x0a | 
 | 180 | #define OP_GAMIRR	0x0b | 
 | 181 | #define OP_GAMER	0x0c | 
 | 182 | #define OP_GAMERR	0x0d | 
 | 183 | #define OP_BSTORE	0x0e | 
 | 184 | #define OP_VFLUSH	0x0f | 
 | 185 |  | 
 | 186 |  | 
 | 187 | /* Extended opcodes values (exopc field) */ | 
 | 188 |  | 
 | 189 | /* GAMIR - AMOs with implicit operands */ | 
 | 190 | #define EOP_IR_FETCH	0x01 /* Plain fetch of memory */ | 
 | 191 | #define EOP_IR_CLR	0x02 /* Fetch and clear */ | 
 | 192 | #define EOP_IR_INC	0x05 /* Fetch and increment */ | 
 | 193 | #define EOP_IR_DEC	0x07 /* Fetch and decrement */ | 
 | 194 | #define EOP_IR_QCHK1	0x0d /* Queue check, 64 byte msg */ | 
 | 195 | #define EOP_IR_QCHK2	0x0e /* Queue check, 128 byte msg */ | 
 | 196 |  | 
 | 197 | /* GAMIRR - Registered AMOs with implicit operands */ | 
 | 198 | #define EOP_IRR_FETCH	0x01 /* Registered fetch of memory */ | 
 | 199 | #define EOP_IRR_CLR	0x02 /* Registered fetch and clear */ | 
 | 200 | #define EOP_IRR_INC	0x05 /* Registered fetch and increment */ | 
 | 201 | #define EOP_IRR_DEC	0x07 /* Registered fetch and decrement */ | 
 | 202 | #define EOP_IRR_DECZ	0x0f /* Registered fetch and decrement, update on zero*/ | 
 | 203 |  | 
 | 204 | /* GAMER - AMOs with explicit operands */ | 
 | 205 | #define EOP_ER_SWAP	0x00 /* Exchange argument and memory */ | 
 | 206 | #define EOP_ER_OR	0x01 /* Logical OR with memory */ | 
 | 207 | #define EOP_ER_AND	0x02 /* Logical AND with memory */ | 
 | 208 | #define EOP_ER_XOR	0x03 /* Logical XOR with memory */ | 
 | 209 | #define EOP_ER_ADD	0x04 /* Add value to memory */ | 
 | 210 | #define EOP_ER_CSWAP	0x08 /* Compare with operand2, write operand1 if match*/ | 
 | 211 | #define EOP_ER_CADD	0x0c /* Queue check, operand1*64 byte msg */ | 
 | 212 |  | 
 | 213 | /* GAMERR - Registered AMOs with explicit operands */ | 
 | 214 | #define EOP_ERR_SWAP	0x00 /* Exchange argument and memory */ | 
 | 215 | #define EOP_ERR_OR	0x01 /* Logical OR with memory */ | 
 | 216 | #define EOP_ERR_AND	0x02 /* Logical AND with memory */ | 
 | 217 | #define EOP_ERR_XOR	0x03 /* Logical XOR with memory */ | 
 | 218 | #define EOP_ERR_ADD	0x04 /* Add value to memory */ | 
 | 219 | #define EOP_ERR_CSWAP	0x08 /* Compare with operand2, write operand1 if match*/ | 
 | 220 | #define EOP_ERR_EPOLL	0x09 /* Poll for equality */ | 
 | 221 | #define EOP_ERR_NPOLL	0x0a /* Poll for inequality */ | 
 | 222 |  | 
 | 223 | /* GAMXR - SGI Arithmetic unit */ | 
 | 224 | #define EOP_XR_CSWAP	0x0b /* Masked compare exchange */ | 
 | 225 |  | 
 | 226 |  | 
 | 227 | /* Transfer types (xtype field) */ | 
 | 228 | #define XTYPE_B		0x0	/* byte */ | 
 | 229 | #define XTYPE_S		0x1	/* short (2-byte) */ | 
 | 230 | #define XTYPE_W		0x2	/* word (4-byte) */ | 
 | 231 | #define XTYPE_DW	0x3	/* doubleword (8-byte) */ | 
 | 232 | #define XTYPE_CL	0x6	/* cacheline (64-byte) */ | 
 | 233 |  | 
 | 234 |  | 
 | 235 | /* Instruction access attributes (iaa0, iaa1 fields) */ | 
 | 236 | #define IAA_RAM		0x0	/* normal cached RAM access */ | 
 | 237 | #define IAA_NCRAM	0x2	/* noncoherent RAM access */ | 
 | 238 | #define IAA_MMIO	0x1	/* noncoherent memory-mapped I/O space */ | 
 | 239 | #define IAA_REGISTER	0x3	/* memory-mapped registers, etc. */ | 
 | 240 |  | 
 | 241 |  | 
 | 242 | /* Instruction mode attributes (ima field) */ | 
 | 243 | #define IMA_MAPPED	0x0	/* Virtual mode  */ | 
 | 244 | #define IMA_CB_DELAY	0x1	/* hold read responses until status changes */ | 
 | 245 | #define IMA_UNMAPPED	0x2	/* bypass the TLBs (OS only) */ | 
 | 246 | #define IMA_INTERRUPT	0x4	/* Interrupt when instruction completes */ | 
 | 247 |  | 
 | 248 | /* CBE ecause bits */ | 
 | 249 | #define CBE_CAUSE_RI				(1 << 0) | 
 | 250 | #define CBE_CAUSE_INVALID_INSTRUCTION		(1 << 1) | 
 | 251 | #define CBE_CAUSE_UNMAPPED_MODE_FORBIDDEN	(1 << 2) | 
 | 252 | #define CBE_CAUSE_PE_CHECK_DATA_ERROR		(1 << 3) | 
 | 253 | #define CBE_CAUSE_IAA_GAA_MISMATCH		(1 << 4) | 
 | 254 | #define CBE_CAUSE_DATA_SEGMENT_LIMIT_EXCEPTION	(1 << 5) | 
 | 255 | #define CBE_CAUSE_OS_FATAL_TLB_FAULT		(1 << 6) | 
 | 256 | #define CBE_CAUSE_EXECUTION_HW_ERROR		(1 << 7) | 
 | 257 | #define CBE_CAUSE_TLBHW_ERROR			(1 << 8) | 
 | 258 | #define CBE_CAUSE_RA_REQUEST_TIMEOUT		(1 << 9) | 
 | 259 | #define CBE_CAUSE_HA_REQUEST_TIMEOUT		(1 << 10) | 
 | 260 | #define CBE_CAUSE_RA_RESPONSE_FATAL		(1 << 11) | 
 | 261 | #define CBE_CAUSE_RA_RESPONSE_NON_FATAL		(1 << 12) | 
 | 262 | #define CBE_CAUSE_HA_RESPONSE_FATAL		(1 << 13) | 
 | 263 | #define CBE_CAUSE_HA_RESPONSE_NON_FATAL		(1 << 14) | 
 | 264 | #define CBE_CAUSE_ADDRESS_SPACE_DECODE_ERROR	(1 << 15) | 
| Jack Steiner | 270952a | 2009-06-17 16:28:27 -0700 | [diff] [blame] | 265 | #define CBE_CAUSE_PROTOCOL_STATE_DATA_ERROR	(1 << 16) | 
 | 266 | #define CBE_CAUSE_RA_RESPONSE_DATA_ERROR	(1 << 17) | 
 | 267 | #define CBE_CAUSE_HA_RESPONSE_DATA_ERROR	(1 << 18) | 
| Jack Steiner | 5658366 | 2009-12-15 16:48:16 -0800 | [diff] [blame] | 268 | #define CBE_CAUSE_FORCED_ERROR			(1 << 19) | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 269 |  | 
| Jack Steiner | cd1334f | 2009-06-17 16:28:19 -0700 | [diff] [blame] | 270 | /* CBE cbrexecstatus bits */ | 
 | 271 | #define CBR_EXS_ABORT_OCC_BIT			0 | 
 | 272 | #define CBR_EXS_INT_OCC_BIT			1 | 
 | 273 | #define CBR_EXS_PENDING_BIT			2 | 
 | 274 | #define CBR_EXS_QUEUED_BIT			3 | 
| Jack Steiner | 270952a | 2009-06-17 16:28:27 -0700 | [diff] [blame] | 275 | #define CBR_EXS_TLB_INVAL_BIT			4 | 
| Jack Steiner | cd1334f | 2009-06-17 16:28:19 -0700 | [diff] [blame] | 276 | #define CBR_EXS_EXCEPTION_BIT			5 | 
| Jack Steiner | 5658366 | 2009-12-15 16:48:16 -0800 | [diff] [blame] | 277 | #define CBR_EXS_CB_INT_PENDING_BIT		6 | 
| Jack Steiner | cd1334f | 2009-06-17 16:28:19 -0700 | [diff] [blame] | 278 |  | 
 | 279 | #define CBR_EXS_ABORT_OCC			(1 << CBR_EXS_ABORT_OCC_BIT) | 
 | 280 | #define CBR_EXS_INT_OCC				(1 << CBR_EXS_INT_OCC_BIT) | 
 | 281 | #define CBR_EXS_PENDING				(1 << CBR_EXS_PENDING_BIT) | 
 | 282 | #define CBR_EXS_QUEUED				(1 << CBR_EXS_QUEUED_BIT) | 
| Jack Steiner | 5658366 | 2009-12-15 16:48:16 -0800 | [diff] [blame] | 283 | #define CBR_EXS_TLB_INVAL			(1 << CBR_EXS_TLB_INVAL_BIT) | 
| Jack Steiner | cd1334f | 2009-06-17 16:28:19 -0700 | [diff] [blame] | 284 | #define CBR_EXS_EXCEPTION			(1 << CBR_EXS_EXCEPTION_BIT) | 
| Jack Steiner | 5658366 | 2009-12-15 16:48:16 -0800 | [diff] [blame] | 285 | #define CBR_EXS_CB_INT_PENDING			(1 << CBR_EXS_CB_INT_PENDING_BIT) | 
| Jack Steiner | cd1334f | 2009-06-17 16:28:19 -0700 | [diff] [blame] | 286 |  | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 287 | /* | 
 | 288 |  * Exceptions are retried for the following cases. If any OTHER bits are set | 
 | 289 |  * in ecause, the exception is not retryable. | 
 | 290 |  */ | 
| Jack Steiner | 270952a | 2009-06-17 16:28:27 -0700 | [diff] [blame] | 291 | #define EXCEPTION_RETRY_BITS (CBE_CAUSE_EXECUTION_HW_ERROR |		\ | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 292 | 			      CBE_CAUSE_TLBHW_ERROR |			\ | 
| Jack Steiner | 270952a | 2009-06-17 16:28:27 -0700 | [diff] [blame] | 293 | 			      CBE_CAUSE_RA_REQUEST_TIMEOUT |		\ | 
 | 294 | 			      CBE_CAUSE_RA_RESPONSE_NON_FATAL |		\ | 
 | 295 | 			      CBE_CAUSE_HA_RESPONSE_NON_FATAL |		\ | 
 | 296 | 			      CBE_CAUSE_RA_RESPONSE_DATA_ERROR |	\ | 
 | 297 | 			      CBE_CAUSE_HA_RESPONSE_DATA_ERROR		\ | 
 | 298 | 			      ) | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 299 |  | 
 | 300 | /* Message queue head structure */ | 
 | 301 | union gru_mesqhead { | 
 | 302 | 	unsigned long	val; | 
 | 303 | 	struct { | 
 | 304 | 		unsigned int	head; | 
 | 305 | 		unsigned int	limit; | 
 | 306 | 	}; | 
 | 307 | }; | 
 | 308 |  | 
 | 309 |  | 
 | 310 | /* Generate the low word of a GRU instruction */ | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 311 | static inline unsigned long | 
 | 312 | __opdword(unsigned char opcode, unsigned char exopc, unsigned char xtype, | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 313 |        unsigned char iaa0, unsigned char iaa1, | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 314 |        unsigned long idef2, unsigned char ima) | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 315 | { | 
 | 316 |     return (1 << GRU_CB_ICMD_SHFT) | | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 317 | 	   ((unsigned long)CBS_ACTIVE << GRU_ISTATUS_SHFT) | | 
 | 318 | 	   (idef2<< GRU_IDEF2_SHFT) | | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 319 | 	   (iaa0 << GRU_CB_IAA0_SHFT) | | 
 | 320 | 	   (iaa1 << GRU_CB_IAA1_SHFT) | | 
 | 321 | 	   (ima << GRU_CB_IMA_SHFT) | | 
 | 322 | 	   (xtype << GRU_CB_XTYPE_SHFT) | | 
 | 323 | 	   (opcode << GRU_CB_OPC_SHFT) | | 
 | 324 | 	   (exopc << GRU_CB_EXOPC_SHFT); | 
 | 325 | } | 
 | 326 |  | 
 | 327 | /* | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 328 |  * Architecture specific intrinsics | 
 | 329 |  */ | 
 | 330 | static inline void gru_flush_cache(void *p) | 
 | 331 | { | 
 | 332 | 	__flush_cache(p); | 
 | 333 | } | 
 | 334 |  | 
 | 335 | /* | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 336 |  * Store the lower 64 bits of the command including the "start" bit. Then | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 337 |  * start the instruction executing. | 
 | 338 |  */ | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 339 | static inline void gru_start_instruction(struct gru_instruction *ins, unsigned long op64) | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 340 | { | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 341 | 	gru_ordered_store_ulong(ins, op64); | 
| Jack Steiner | 67bf04a | 2009-12-15 16:48:11 -0800 | [diff] [blame] | 342 | 	mb(); | 
| Jack Steiner | 923f7f6 | 2008-10-15 22:05:13 -0700 | [diff] [blame] | 343 | 	gru_flush_cache(ins); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 344 | } | 
 | 345 |  | 
 | 346 |  | 
 | 347 | /* Convert "hints" to IMA */ | 
 | 348 | #define CB_IMA(h)		((h) | IMA_UNMAPPED) | 
 | 349 |  | 
 | 350 | /* Convert data segment cache line index into TRI0 / TRI1 value */ | 
 | 351 | #define GRU_DINDEX(i)		((i) * GRU_CACHE_LINE_BYTES) | 
 | 352 |  | 
 | 353 | /* Inline functions for GRU instructions. | 
 | 354 |  *     Note: | 
 | 355 |  *     	- nelem and stride are in elements | 
 | 356 |  *     	- tri0/tri1 is in bytes for the beginning of the data segment. | 
 | 357 |  */ | 
| Robin Holt | 289750d | 2009-12-15 16:47:55 -0800 | [diff] [blame] | 358 | static inline void gru_vload_phys(void *cb, unsigned long gpa, | 
 | 359 | 		unsigned int tri0, int iaa, unsigned long hints) | 
 | 360 | { | 
 | 361 | 	struct gru_instruction *ins = (struct gru_instruction *)cb; | 
 | 362 |  | 
 | 363 | 	ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62); | 
 | 364 | 	ins->nelem = 1; | 
| Robin Holt | 289750d | 2009-12-15 16:47:55 -0800 | [diff] [blame] | 365 | 	ins->op1_stride = 1; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 366 | 	gru_start_instruction(ins, __opdword(OP_VLOAD, 0, XTYPE_DW, iaa, 0, | 
 | 367 | 					(unsigned long)tri0, CB_IMA(hints))); | 
| Robin Holt | 289750d | 2009-12-15 16:47:55 -0800 | [diff] [blame] | 368 | } | 
 | 369 |  | 
| Jack Steiner | 76148df | 2009-12-15 16:48:21 -0800 | [diff] [blame] | 370 | static inline void gru_vstore_phys(void *cb, unsigned long gpa, | 
 | 371 | 		unsigned int tri0, int iaa, unsigned long hints) | 
 | 372 | { | 
 | 373 | 	struct gru_instruction *ins = (struct gru_instruction *)cb; | 
 | 374 |  | 
 | 375 | 	ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62); | 
 | 376 | 	ins->nelem = 1; | 
 | 377 | 	ins->op1_stride = 1; | 
 | 378 | 	gru_start_instruction(ins, __opdword(OP_VSTORE, 0, XTYPE_DW, iaa, 0, | 
 | 379 | 					(unsigned long)tri0, CB_IMA(hints))); | 
 | 380 | } | 
 | 381 |  | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 382 | static inline void gru_vload(void *cb, unsigned long mem_addr, | 
 | 383 | 		unsigned int tri0, unsigned char xtype, unsigned long nelem, | 
 | 384 | 		unsigned long stride, unsigned long hints) | 
 | 385 | { | 
 | 386 | 	struct gru_instruction *ins = (struct gru_instruction *)cb; | 
 | 387 |  | 
 | 388 | 	ins->baddr0 = (long)mem_addr; | 
 | 389 | 	ins->nelem = nelem; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 390 | 	ins->op1_stride = stride; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 391 | 	gru_start_instruction(ins, __opdword(OP_VLOAD, 0, xtype, IAA_RAM, 0, | 
 | 392 | 					(unsigned long)tri0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 393 | } | 
 | 394 |  | 
 | 395 | static inline void gru_vstore(void *cb, unsigned long mem_addr, | 
 | 396 | 		unsigned int tri0, unsigned char xtype, unsigned long nelem, | 
 | 397 | 		unsigned long stride, unsigned long hints) | 
 | 398 | { | 
 | 399 | 	struct gru_instruction *ins = (void *)cb; | 
 | 400 |  | 
 | 401 | 	ins->baddr0 = (long)mem_addr; | 
 | 402 | 	ins->nelem = nelem; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 403 | 	ins->op1_stride = stride; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 404 | 	gru_start_instruction(ins, __opdword(OP_VSTORE, 0, xtype, IAA_RAM, 0, | 
 | 405 | 					tri0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 406 | } | 
 | 407 |  | 
 | 408 | static inline void gru_ivload(void *cb, unsigned long mem_addr, | 
 | 409 | 		unsigned int tri0, unsigned int tri1, unsigned char xtype, | 
 | 410 | 		unsigned long nelem, unsigned long hints) | 
 | 411 | { | 
 | 412 | 	struct gru_instruction *ins = (void *)cb; | 
 | 413 |  | 
 | 414 | 	ins->baddr0 = (long)mem_addr; | 
 | 415 | 	ins->nelem = nelem; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 416 | 	ins->tri1_bufsize = tri1; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 417 | 	gru_start_instruction(ins, __opdword(OP_IVLOAD, 0, xtype, IAA_RAM, 0, | 
 | 418 | 					tri0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 419 | } | 
 | 420 |  | 
 | 421 | static inline void gru_ivstore(void *cb, unsigned long mem_addr, | 
 | 422 | 		unsigned int tri0, unsigned int tri1, | 
 | 423 | 		unsigned char xtype, unsigned long nelem, unsigned long hints) | 
 | 424 | { | 
 | 425 | 	struct gru_instruction *ins = (void *)cb; | 
 | 426 |  | 
 | 427 | 	ins->baddr0 = (long)mem_addr; | 
 | 428 | 	ins->nelem = nelem; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 429 | 	ins->tri1_bufsize = tri1; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 430 | 	gru_start_instruction(ins, __opdword(OP_IVSTORE, 0, xtype, IAA_RAM, 0, | 
 | 431 | 					tri0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 432 | } | 
 | 433 |  | 
 | 434 | static inline void gru_vset(void *cb, unsigned long mem_addr, | 
 | 435 | 		unsigned long value, unsigned char xtype, unsigned long nelem, | 
 | 436 | 		unsigned long stride, unsigned long hints) | 
 | 437 | { | 
 | 438 | 	struct gru_instruction *ins = (void *)cb; | 
 | 439 |  | 
 | 440 | 	ins->baddr0 = (long)mem_addr; | 
 | 441 | 	ins->op2_value_baddr1 = value; | 
 | 442 | 	ins->nelem = nelem; | 
 | 443 | 	ins->op1_stride = stride; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 444 | 	gru_start_instruction(ins, __opdword(OP_VSET, 0, xtype, IAA_RAM, 0, | 
 | 445 | 					 0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 446 | } | 
 | 447 |  | 
 | 448 | static inline void gru_ivset(void *cb, unsigned long mem_addr, | 
 | 449 | 		unsigned int tri1, unsigned long value, unsigned char xtype, | 
 | 450 | 		unsigned long nelem, unsigned long hints) | 
 | 451 | { | 
 | 452 | 	struct gru_instruction *ins = (void *)cb; | 
 | 453 |  | 
 | 454 | 	ins->baddr0 = (long)mem_addr; | 
 | 455 | 	ins->op2_value_baddr1 = value; | 
 | 456 | 	ins->nelem = nelem; | 
 | 457 | 	ins->tri1_bufsize = tri1; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 458 | 	gru_start_instruction(ins, __opdword(OP_IVSET, 0, xtype, IAA_RAM, 0, | 
 | 459 | 					0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 460 | } | 
 | 461 |  | 
 | 462 | static inline void gru_vflush(void *cb, unsigned long mem_addr, | 
 | 463 | 		unsigned long nelem, unsigned char xtype, unsigned long stride, | 
 | 464 | 		unsigned long hints) | 
 | 465 | { | 
 | 466 | 	struct gru_instruction *ins = (void *)cb; | 
 | 467 |  | 
 | 468 | 	ins->baddr0 = (long)mem_addr; | 
 | 469 | 	ins->op1_stride = stride; | 
 | 470 | 	ins->nelem = nelem; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 471 | 	gru_start_instruction(ins, __opdword(OP_VFLUSH, 0, xtype, IAA_RAM, 0, | 
 | 472 | 					0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 473 | } | 
 | 474 |  | 
 | 475 | static inline void gru_nop(void *cb, int hints) | 
 | 476 | { | 
 | 477 | 	struct gru_instruction *ins = (void *)cb; | 
 | 478 |  | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 479 | 	gru_start_instruction(ins, __opdword(OP_NOP, 0, 0, 0, 0, 0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 480 | } | 
 | 481 |  | 
 | 482 |  | 
 | 483 | static inline void gru_bcopy(void *cb, const unsigned long src, | 
 | 484 | 		unsigned long dest, | 
 | 485 | 		unsigned int tri0, unsigned int xtype, unsigned long nelem, | 
 | 486 | 		unsigned int bufsize, unsigned long hints) | 
 | 487 | { | 
 | 488 | 	struct gru_instruction *ins = (void *)cb; | 
 | 489 |  | 
 | 490 | 	ins->baddr0 = (long)src; | 
 | 491 | 	ins->op2_value_baddr1 = (long)dest; | 
 | 492 | 	ins->nelem = nelem; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 493 | 	ins->tri1_bufsize = bufsize; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 494 | 	gru_start_instruction(ins, __opdword(OP_BCOPY, 0, xtype, IAA_RAM, | 
 | 495 | 					IAA_RAM, tri0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 496 | } | 
 | 497 |  | 
 | 498 | static inline void gru_bstore(void *cb, const unsigned long src, | 
 | 499 | 		unsigned long dest, unsigned int tri0, unsigned int xtype, | 
 | 500 | 		unsigned long nelem, unsigned long hints) | 
 | 501 | { | 
 | 502 | 	struct gru_instruction *ins = (void *)cb; | 
 | 503 |  | 
 | 504 | 	ins->baddr0 = (long)src; | 
 | 505 | 	ins->op2_value_baddr1 = (long)dest; | 
 | 506 | 	ins->nelem = nelem; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 507 | 	gru_start_instruction(ins, __opdword(OP_BSTORE, 0, xtype, 0, IAA_RAM, | 
 | 508 | 					tri0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 509 | } | 
 | 510 |  | 
 | 511 | static inline void gru_gamir(void *cb, int exopc, unsigned long src, | 
 | 512 | 		unsigned int xtype, unsigned long hints) | 
 | 513 | { | 
 | 514 | 	struct gru_instruction *ins = (void *)cb; | 
 | 515 |  | 
 | 516 | 	ins->baddr0 = (long)src; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 517 | 	gru_start_instruction(ins, __opdword(OP_GAMIR, exopc, xtype, IAA_RAM, 0, | 
 | 518 | 					0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 519 | } | 
 | 520 |  | 
 | 521 | static inline void gru_gamirr(void *cb, int exopc, unsigned long src, | 
 | 522 | 		unsigned int xtype, unsigned long hints) | 
 | 523 | { | 
 | 524 | 	struct gru_instruction *ins = (void *)cb; | 
 | 525 |  | 
 | 526 | 	ins->baddr0 = (long)src; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 527 | 	gru_start_instruction(ins, __opdword(OP_GAMIRR, exopc, xtype, IAA_RAM, 0, | 
 | 528 | 					0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 529 | } | 
 | 530 |  | 
 | 531 | static inline void gru_gamer(void *cb, int exopc, unsigned long src, | 
 | 532 | 		unsigned int xtype, | 
 | 533 | 		unsigned long operand1, unsigned long operand2, | 
 | 534 | 		unsigned long hints) | 
 | 535 | { | 
 | 536 | 	struct gru_instruction *ins = (void *)cb; | 
 | 537 |  | 
 | 538 | 	ins->baddr0 = (long)src; | 
 | 539 | 	ins->op1_stride = operand1; | 
 | 540 | 	ins->op2_value_baddr1 = operand2; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 541 | 	gru_start_instruction(ins, __opdword(OP_GAMER, exopc, xtype, IAA_RAM, 0, | 
 | 542 | 					0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 543 | } | 
 | 544 |  | 
 | 545 | static inline void gru_gamerr(void *cb, int exopc, unsigned long src, | 
 | 546 | 		unsigned int xtype, unsigned long operand1, | 
 | 547 | 		unsigned long operand2, unsigned long hints) | 
 | 548 | { | 
 | 549 | 	struct gru_instruction *ins = (void *)cb; | 
 | 550 |  | 
 | 551 | 	ins->baddr0 = (long)src; | 
 | 552 | 	ins->op1_stride = operand1; | 
 | 553 | 	ins->op2_value_baddr1 = operand2; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 554 | 	gru_start_instruction(ins, __opdword(OP_GAMERR, exopc, xtype, IAA_RAM, 0, | 
 | 555 | 					0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 556 | } | 
 | 557 |  | 
 | 558 | static inline void gru_gamxr(void *cb, unsigned long src, | 
 | 559 | 		unsigned int tri0, unsigned long hints) | 
 | 560 | { | 
 | 561 | 	struct gru_instruction *ins = (void *)cb; | 
 | 562 |  | 
 | 563 | 	ins->baddr0 = (long)src; | 
 | 564 | 	ins->nelem = 4; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 565 | 	gru_start_instruction(ins, __opdword(OP_GAMXR, EOP_XR_CSWAP, XTYPE_DW, | 
 | 566 | 				 IAA_RAM, 0, 0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 567 | } | 
 | 568 |  | 
 | 569 | static inline void gru_mesq(void *cb, unsigned long queue, | 
 | 570 | 		unsigned long tri0, unsigned long nelem, | 
 | 571 | 		unsigned long hints) | 
 | 572 | { | 
 | 573 | 	struct gru_instruction *ins = (void *)cb; | 
 | 574 |  | 
 | 575 | 	ins->baddr0 = (long)queue; | 
 | 576 | 	ins->nelem = nelem; | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 577 | 	gru_start_instruction(ins, __opdword(OP_MESQ, 0, XTYPE_CL, IAA_RAM, 0, | 
 | 578 | 					tri0, CB_IMA(hints))); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 579 | } | 
 | 580 |  | 
 | 581 | static inline unsigned long gru_get_amo_value(void *cb) | 
 | 582 | { | 
 | 583 | 	struct gru_instruction *ins = (void *)cb; | 
 | 584 |  | 
 | 585 | 	return ins->avalue; | 
 | 586 | } | 
 | 587 |  | 
 | 588 | static inline int gru_get_amo_value_head(void *cb) | 
 | 589 | { | 
 | 590 | 	struct gru_instruction *ins = (void *)cb; | 
 | 591 |  | 
 | 592 | 	return ins->avalue & 0xffffffff; | 
 | 593 | } | 
 | 594 |  | 
 | 595 | static inline int gru_get_amo_value_limit(void *cb) | 
 | 596 | { | 
 | 597 | 	struct gru_instruction *ins = (void *)cb; | 
 | 598 |  | 
 | 599 | 	return ins->avalue >> 32; | 
 | 600 | } | 
 | 601 |  | 
 | 602 | static inline union gru_mesqhead  gru_mesq_head(int head, int limit) | 
 | 603 | { | 
 | 604 | 	union gru_mesqhead mqh; | 
 | 605 |  | 
 | 606 | 	mqh.head = head; | 
 | 607 | 	mqh.limit = limit; | 
 | 608 | 	return mqh; | 
 | 609 | } | 
 | 610 |  | 
 | 611 | /* | 
 | 612 |  * Get struct control_block_extended_exc_detail for CB. | 
 | 613 |  */ | 
 | 614 | extern int gru_get_cb_exception_detail(void *cb, | 
 | 615 | 		       struct control_block_extended_exc_detail *excdet); | 
 | 616 |  | 
 | 617 | #define GRU_EXC_STR_SIZE		256 | 
 | 618 |  | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 619 |  | 
 | 620 | /* | 
 | 621 |  * Control block definition for checking status | 
 | 622 |  */ | 
 | 623 | struct gru_control_block_status { | 
 | 624 | 	unsigned int	icmd		:1; | 
| Jack Steiner | fe5bb6b | 2009-04-02 16:59:04 -0700 | [diff] [blame] | 625 | 	unsigned int	ima		:3; | 
 | 626 | 	unsigned int	reserved0	:4; | 
 | 627 | 	unsigned int	unused1		:24; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 628 | 	unsigned int	unused2		:24; | 
 | 629 | 	unsigned int	istatus		:2; | 
 | 630 | 	unsigned int	isubstatus	:4; | 
| Jack Steiner | fe5bb6b | 2009-04-02 16:59:04 -0700 | [diff] [blame] | 631 | 	unsigned int	unused3		:2; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 632 | }; | 
 | 633 |  | 
 | 634 | /* Get CB status */ | 
 | 635 | static inline int gru_get_cb_status(void *cb) | 
 | 636 | { | 
 | 637 | 	struct gru_control_block_status *cbs = (void *)cb; | 
 | 638 |  | 
 | 639 | 	return cbs->istatus; | 
 | 640 | } | 
 | 641 |  | 
 | 642 | /* Get CB message queue substatus */ | 
 | 643 | static inline int gru_get_cb_message_queue_substatus(void *cb) | 
 | 644 | { | 
 | 645 | 	struct gru_control_block_status *cbs = (void *)cb; | 
 | 646 |  | 
 | 647 | 	return cbs->isubstatus & CBSS_MSG_QUEUE_MASK; | 
 | 648 | } | 
 | 649 |  | 
 | 650 | /* Get CB substatus */ | 
 | 651 | static inline int gru_get_cb_substatus(void *cb) | 
 | 652 | { | 
 | 653 | 	struct gru_control_block_status *cbs = (void *)cb; | 
 | 654 |  | 
 | 655 | 	return cbs->isubstatus; | 
 | 656 | } | 
 | 657 |  | 
| Jack Steiner | 9f25011 | 2009-06-17 16:28:31 -0700 | [diff] [blame] | 658 | /* | 
 | 659 |  * User interface to check an instruction status. UPM and exceptions | 
 | 660 |  * are handled automatically. However, this function does NOT wait | 
 | 661 |  * for an active instruction to complete. | 
 | 662 |  * | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 663 |  */ | 
 | 664 | static inline int gru_check_status(void *cb) | 
 | 665 | { | 
 | 666 | 	struct gru_control_block_status *cbs = (void *)cb; | 
| Jack Steiner | 923f7f6 | 2008-10-15 22:05:13 -0700 | [diff] [blame] | 667 | 	int ret; | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 668 |  | 
| Jack Steiner | 923f7f6 | 2008-10-15 22:05:13 -0700 | [diff] [blame] | 669 | 	ret = cbs->istatus; | 
| Jack Steiner | 9f25011 | 2009-06-17 16:28:31 -0700 | [diff] [blame] | 670 | 	if (ret != CBS_ACTIVE) | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 671 | 		ret = gru_check_status_proc(cb); | 
 | 672 | 	return ret; | 
 | 673 | } | 
 | 674 |  | 
| Jack Steiner | 9f25011 | 2009-06-17 16:28:31 -0700 | [diff] [blame] | 675 | /* | 
 | 676 |  * User interface (via inline function) to wait for an instruction | 
 | 677 |  * to complete. Completion status (IDLE or EXCEPTION is returned | 
 | 678 |  * to the user. Exception due to hardware errors are automatically | 
 | 679 |  * retried before returning an exception. | 
 | 680 |  * | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 681 |  */ | 
 | 682 | static inline int gru_wait(void *cb) | 
 | 683 | { | 
| Jack Steiner | 9f25011 | 2009-06-17 16:28:31 -0700 | [diff] [blame] | 684 | 	return gru_wait_proc(cb); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 685 | } | 
 | 686 |  | 
| Jack Steiner | 9f25011 | 2009-06-17 16:28:31 -0700 | [diff] [blame] | 687 | /* | 
 | 688 |  * Wait for CB to complete. Aborts program if error. (Note: error does NOT | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 689 |  * mean TLB mis - only fatal errors such as memory parity error or user | 
 | 690 |  * bugs will cause termination. | 
 | 691 |  */ | 
 | 692 | static inline void gru_wait_abort(void *cb) | 
 | 693 | { | 
| Jack Steiner | 9f25011 | 2009-06-17 16:28:31 -0700 | [diff] [blame] | 694 | 	gru_wait_abort_proc(cb); | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 695 | } | 
 | 696 |  | 
| Jack Steiner | 57ebb03 | 2009-12-15 16:48:12 -0800 | [diff] [blame] | 697 | /* | 
 | 698 |  * Get a pointer to the start of a gseg | 
 | 699 |  * 	p	- Any valid pointer within the gseg | 
 | 700 |  */ | 
 | 701 | static inline void *gru_get_gseg_pointer (void *p) | 
 | 702 | { | 
 | 703 | 	return (void *)((unsigned long)p & ~(GRU_GSEG_PAGESIZE - 1)); | 
 | 704 | } | 
| Jack Steiner | 4c921d4 | 2008-07-29 22:33:54 -0700 | [diff] [blame] | 705 |  | 
 | 706 | /* | 
 | 707 |  * Get a pointer to a control block | 
 | 708 |  * 	gseg	- GSeg address returned from gru_get_thread_gru_segment() | 
 | 709 |  * 	index	- index of desired CB | 
 | 710 |  */ | 
 | 711 | static inline void *gru_get_cb_pointer(void *gseg, | 
 | 712 | 						      int index) | 
 | 713 | { | 
 | 714 | 	return gseg + GRU_CB_BASE + index * GRU_HANDLE_STRIDE; | 
 | 715 | } | 
 | 716 |  | 
 | 717 | /* | 
 | 718 |  * Get a pointer to a cacheline in the data segment portion of a GSeg | 
 | 719 |  * 	gseg	- GSeg address returned from gru_get_thread_gru_segment() | 
 | 720 |  * 	index	- index of desired cache line | 
 | 721 |  */ | 
 | 722 | static inline void *gru_get_data_pointer(void *gseg, int index) | 
 | 723 | { | 
 | 724 | 	return gseg + GRU_DS_BASE + index * GRU_CACHE_LINE_BYTES; | 
 | 725 | } | 
 | 726 |  | 
 | 727 | /* | 
 | 728 |  * Convert a vaddr into the tri index within the GSEG | 
 | 729 |  * 	vaddr		- virtual address of within gseg | 
 | 730 |  */ | 
 | 731 | static inline int gru_get_tri(void *vaddr) | 
 | 732 | { | 
 | 733 | 	return ((unsigned long)vaddr & (GRU_GSEG_PAGESIZE - 1)) - GRU_DS_BASE; | 
 | 734 | } | 
 | 735 | #endif		/* __GRU_INSTRUCTIONS_H__ */ |