linux/drivers/misc/sgi-gru/gru_instructions.h
<<
>>
Prefs
   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
  22extern int gru_check_status_proc(void *cb);
  23extern int gru_wait_proc(void *cb);
  24extern void gru_wait_abort_proc(void *cb);
  25
  26
  27
  28/*
  29 * Architecture dependent functions
  30 */
  31
  32#if defined(CONFIG_IA64)
  33#include <linux/compiler.h>
  34#include <asm/intrinsics.h>
  35#define __flush_cache(p)                ia64_fc((unsigned long)p)
  36/* Use volatile on IA64 to ensure ordering via st4.rel */
  37#define gru_ordered_store_ulong(p, v)                                   \
  38                do {                                                    \
  39                        barrier();                                      \
  40                        *((volatile unsigned long *)(p)) = v; /* force st.rel */        \
  41                } while (0)
  42#elif defined(CONFIG_X86_64)
  43#include <asm/cacheflush.h>
  44#define __flush_cache(p)                clflush(p)
  45#define gru_ordered_store_ulong(p, v)                                   \
  46                do {                                                    \
  47                        barrier();                                      \
  48                        *(unsigned long *)p = v;                        \
  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 */
  78struct control_block_extended_exc_detail {
  79        unsigned long   cb;
  80        int             opc;
  81        int             ecause;
  82        int             exopc;
  83        long            exceptdet0;
  84        int             exceptdet1;
  85        int             cbrstate;
  86        int             cbrexecstatus;
  87};
  88
  89/*
  90 * Instruction formats
  91 */
  92
  93/*
  94 * Generic instruction format.
  95 * This definition has precise bit field definitions.
  96 */
  97struct 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;
 113    unsigned char               reserved3: 1;
 114    unsigned char               tlb_fault_color: 1;
 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 */
 131struct gru_instruction {
 132    /* DW 0 */
 133    union {
 134        unsigned long           op64;    /* icmd,xtype,iaa0,ima,opc,tri0 */
 135        struct {
 136                unsigned int    op32;
 137                unsigned int    tri0;
 138        };
 139    };
 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
 149/* Some shifts and masks for the low 64 bits of a GRU command */
 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
 164#define GRU_IDEF2_SHFT          32
 165#define GRU_IDEF2_MASK          0x3ffff
 166#define GRU_ISTATUS_SHFT        56
 167#define GRU_ISTATUS_MASK        0x3
 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)
 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)
 269#define CBE_CAUSE_FORCED_ERROR                  (1 << 19)
 270
 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
 276#define CBR_EXS_TLB_INVAL_BIT                   4
 277#define CBR_EXS_EXCEPTION_BIT                   5
 278#define CBR_EXS_CB_INT_PENDING_BIT              6
 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)
 284#define CBR_EXS_TLB_INVAL                       (1 << CBR_EXS_TLB_INVAL_BIT)
 285#define CBR_EXS_EXCEPTION                       (1 << CBR_EXS_EXCEPTION_BIT)
 286#define CBR_EXS_CB_INT_PENDING                  (1 << CBR_EXS_CB_INT_PENDING_BIT)
 287
 288/*
 289 * Exceptions are retried for the following cases. If any OTHER bits are set
 290 * in ecause, the exception is not retryable.
 291 */
 292#define EXCEPTION_RETRY_BITS (CBE_CAUSE_EXECUTION_HW_ERROR |            \
 293                              CBE_CAUSE_TLBHW_ERROR |                   \
 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                              )
 300
 301/* Message queue head structure */
 302union 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 */
 312static inline unsigned long
 313__opdword(unsigned char opcode, unsigned char exopc, unsigned char xtype,
 314       unsigned char iaa0, unsigned char iaa1,
 315       unsigned long idef2, unsigned char ima)
 316{
 317    return (1 << GRU_CB_ICMD_SHFT) |
 318           ((unsigned long)CBS_ACTIVE << GRU_ISTATUS_SHFT) |
 319           (idef2<< GRU_IDEF2_SHFT) |
 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/*
 329 * Architecture specific intrinsics
 330 */
 331static inline void gru_flush_cache(void *p)
 332{
 333        __flush_cache(p);
 334}
 335
 336/*
 337 * Store the lower 64 bits of the command including the "start" bit. Then
 338 * start the instruction executing.
 339 */
 340static inline void gru_start_instruction(struct gru_instruction *ins, unsigned long op64)
 341{
 342        gru_ordered_store_ulong(ins, op64);
 343        mb();
 344        gru_flush_cache(ins);
 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 */
 359static 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;
 366        ins->op1_stride = 1;
 367        gru_start_instruction(ins, __opdword(OP_VLOAD, 0, XTYPE_DW, iaa, 0,
 368                                        (unsigned long)tri0, CB_IMA(hints)));
 369}
 370
 371static 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
 383static 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;
 391        ins->op1_stride = stride;
 392        gru_start_instruction(ins, __opdword(OP_VLOAD, 0, xtype, IAA_RAM, 0,
 393                                        (unsigned long)tri0, CB_IMA(hints)));
 394}
 395
 396static 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;
 404        ins->op1_stride = stride;
 405        gru_start_instruction(ins, __opdword(OP_VSTORE, 0, xtype, IAA_RAM, 0,
 406                                        tri0, CB_IMA(hints)));
 407}
 408
 409static 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;
 417        ins->tri1_bufsize = tri1;
 418        gru_start_instruction(ins, __opdword(OP_IVLOAD, 0, xtype, IAA_RAM, 0,
 419                                        tri0, CB_IMA(hints)));
 420}
 421
 422static 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;
 430        ins->tri1_bufsize = tri1;
 431        gru_start_instruction(ins, __opdword(OP_IVSTORE, 0, xtype, IAA_RAM, 0,
 432                                        tri0, CB_IMA(hints)));
 433}
 434
 435static 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;
 445        gru_start_instruction(ins, __opdword(OP_VSET, 0, xtype, IAA_RAM, 0,
 446                                         0, CB_IMA(hints)));
 447}
 448
 449static 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;
 459        gru_start_instruction(ins, __opdword(OP_IVSET, 0, xtype, IAA_RAM, 0,
 460                                        0, CB_IMA(hints)));
 461}
 462
 463static 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;
 472        gru_start_instruction(ins, __opdword(OP_VFLUSH, 0, xtype, IAA_RAM, 0,
 473                                        0, CB_IMA(hints)));
 474}
 475
 476static inline void gru_nop(void *cb, int hints)
 477{
 478        struct gru_instruction *ins = (void *)cb;
 479
 480        gru_start_instruction(ins, __opdword(OP_NOP, 0, 0, 0, 0, 0, CB_IMA(hints)));
 481}
 482
 483
 484static 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;
 494        ins->tri1_bufsize = bufsize;
 495        gru_start_instruction(ins, __opdword(OP_BCOPY, 0, xtype, IAA_RAM,
 496                                        IAA_RAM, tri0, CB_IMA(hints)));
 497}
 498
 499static 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;
 508        gru_start_instruction(ins, __opdword(OP_BSTORE, 0, xtype, 0, IAA_RAM,
 509                                        tri0, CB_IMA(hints)));
 510}
 511
 512static 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;
 518        gru_start_instruction(ins, __opdword(OP_GAMIR, exopc, xtype, IAA_RAM, 0,
 519                                        0, CB_IMA(hints)));
 520}
 521
 522static 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;
 528        gru_start_instruction(ins, __opdword(OP_GAMIRR, exopc, xtype, IAA_RAM, 0,
 529                                        0, CB_IMA(hints)));
 530}
 531
 532static 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;
 542        gru_start_instruction(ins, __opdword(OP_GAMER, exopc, xtype, IAA_RAM, 0,
 543                                        0, CB_IMA(hints)));
 544}
 545
 546static 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;
 555        gru_start_instruction(ins, __opdword(OP_GAMERR, exopc, xtype, IAA_RAM, 0,
 556                                        0, CB_IMA(hints)));
 557}
 558
 559static 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;
 566        gru_start_instruction(ins, __opdword(OP_GAMXR, EOP_XR_CSWAP, XTYPE_DW,
 567                                 IAA_RAM, 0, 0, CB_IMA(hints)));
 568}
 569
 570static 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;
 578        gru_start_instruction(ins, __opdword(OP_MESQ, 0, XTYPE_CL, IAA_RAM, 0,
 579                                        tri0, CB_IMA(hints)));
 580}
 581
 582static inline unsigned long gru_get_amo_value(void *cb)
 583{
 584        struct gru_instruction *ins = (void *)cb;
 585
 586        return ins->avalue;
 587}
 588
 589static 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
 596static 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
 603static 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 */
 615extern 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
 620
 621/*
 622 * Control block definition for checking status
 623 */
 624struct gru_control_block_status {
 625        unsigned int    icmd            :1;
 626        unsigned int    ima             :3;
 627        unsigned int    reserved0       :4;
 628        unsigned int    unused1         :24;
 629        unsigned int    unused2         :24;
 630        unsigned int    istatus         :2;
 631        unsigned int    isubstatus      :4;
 632        unsigned int    unused3         :2;
 633};
 634
 635/* Get CB status */
 636static 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 */
 644static 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 */
 652static 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
 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 *
 664 */
 665static inline int gru_check_status(void *cb)
 666{
 667        struct gru_control_block_status *cbs = (void *)cb;
 668        int ret;
 669
 670        ret = cbs->istatus;
 671        if (ret != CBS_ACTIVE)
 672                ret = gru_check_status_proc(cb);
 673        return ret;
 674}
 675
 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 *
 682 */
 683static inline int gru_wait(void *cb)
 684{
 685        return gru_wait_proc(cb);
 686}
 687
 688/*
 689 * Wait for CB to complete. Aborts program if error. (Note: error does NOT
 690 * mean TLB mis - only fatal errors such as memory parity error or user
 691 * bugs will cause termination.
 692 */
 693static inline void gru_wait_abort(void *cb)
 694{
 695        gru_wait_abort_proc(cb);
 696}
 697
 698/*
 699 * Get a pointer to the start of a gseg
 700 *      p       - Any valid pointer within the gseg
 701 */
 702static inline void *gru_get_gseg_pointer (void *p)
 703{
 704        return (void *)((unsigned long)p & ~(GRU_GSEG_PAGESIZE - 1));
 705}
 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 */
 712static 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 */
 723static 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 */
 732static 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__ */
 737