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