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