1 /* 2 * ICSWX api 3 * 4 * Copyright (C) 2015 IBM Corp. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 * 11 * This provides the Initiate Coprocessor Store Word Indexed (ICSWX) 12 * instruction. This instruction is used to communicate with PowerPC 13 * coprocessors. This also provides definitions of the structures used 14 * to communicate with the coprocessor. 15 * 16 * The RFC02130: Coprocessor Architecture document is the reference for 17 * everything in this file unless otherwise noted. 18 */ 19 #ifndef _ARCH_POWERPC_INCLUDE_ASM_ICSWX_H_ 20 #define _ARCH_POWERPC_INCLUDE_ASM_ICSWX_H_ 21 22 #include <asm/ppc-opcode.h> /* for PPC_ICSWX */ 23 24 /* Chapter 6.5.8 Coprocessor-Completion Block (CCB) */ 25 26 #define CCB_VALUE (0x3fffffffffffffff) 27 #define CCB_ADDRESS (0xfffffffffffffff8) 28 #define CCB_CM (0x0000000000000007) 29 #define CCB_CM0 (0x0000000000000004) 30 #define CCB_CM12 (0x0000000000000003) 31 32 #define CCB_CM0_ALL_COMPLETIONS (0x0) 33 #define CCB_CM0_LAST_IN_CHAIN (0x4) 34 #define CCB_CM12_STORE (0x0) 35 #define CCB_CM12_INTERRUPT (0x1) 36 37 #define CCB_SIZE (0x10) 38 #define CCB_ALIGN CCB_SIZE 39 40 struct coprocessor_completion_block { 41 __be64 value; 42 __be64 address; 43 } __packed __aligned(CCB_ALIGN); 44 45 46 /* Chapter 6.5.7 Coprocessor-Status Block (CSB) */ 47 48 #define CSB_V (0x80) 49 #define CSB_F (0x04) 50 #define CSB_CH (0x03) 51 #define CSB_CE_INCOMPLETE (0x80) 52 #define CSB_CE_TERMINATION (0x40) 53 #define CSB_CE_TPBC (0x20) 54 55 #define CSB_CC_SUCCESS (0) 56 #define CSB_CC_INVALID_ALIGN (1) 57 #define CSB_CC_OPERAND_OVERLAP (2) 58 #define CSB_CC_DATA_LENGTH (3) 59 #define CSB_CC_TRANSLATION (5) 60 #define CSB_CC_PROTECTION (6) 61 #define CSB_CC_RD_EXTERNAL (7) 62 #define CSB_CC_INVALID_OPERAND (8) 63 #define CSB_CC_PRIVILEGE (9) 64 #define CSB_CC_INTERNAL (10) 65 #define CSB_CC_WR_EXTERNAL (12) 66 #define CSB_CC_NOSPC (13) 67 #define CSB_CC_EXCESSIVE_DDE (14) 68 #define CSB_CC_WR_TRANSLATION (15) 69 #define CSB_CC_WR_PROTECTION (16) 70 #define CSB_CC_UNKNOWN_CODE (17) 71 #define CSB_CC_ABORT (18) 72 #define CSB_CC_EXCEED_BYTE_COUNT (19) /* P9 or later */ 73 #define CSB_CC_TRANSPORT (20) 74 #define CSB_CC_INVALID_CRB (21) /* P9 or later */ 75 #define CSB_CC_INVALID_DDE (30) /* P9 or later */ 76 #define CSB_CC_SEGMENTED_DDL (31) 77 #define CSB_CC_PROGRESS_POINT (32) 78 #define CSB_CC_DDE_OVERFLOW (33) 79 #define CSB_CC_SESSION (34) 80 #define CSB_CC_PROVISION (36) 81 #define CSB_CC_CHAIN (37) 82 #define CSB_CC_SEQUENCE (38) 83 #define CSB_CC_HW (39) 84 85 #define CSB_SIZE (0x10) 86 #define CSB_ALIGN CSB_SIZE 87 88 struct coprocessor_status_block { 89 u8 flags; 90 u8 cs; 91 u8 cc; 92 u8 ce; 93 __be32 count; 94 __be64 address; 95 } __packed __aligned(CSB_ALIGN); 96 97 98 /* Chapter 6.5.10 Data-Descriptor List (DDL) 99 * each list contains one or more Data-Descriptor Entries (DDE) 100 */ 101 102 #define DDE_P (0x8000) 103 104 #define DDE_SIZE (0x10) 105 #define DDE_ALIGN DDE_SIZE 106 107 struct data_descriptor_entry { 108 __be16 flags; 109 u8 count; 110 u8 index; 111 __be32 length; 112 __be64 address; 113 } __packed __aligned(DDE_ALIGN); 114 115 116 /* Chapter 6.5.2 Coprocessor-Request Block (CRB) */ 117 118 #define CRB_SIZE (0x80) 119 #define CRB_ALIGN (0x100) /* Errata: requires 256 alignment */ 120 121 /* Coprocessor Status Block field 122 * ADDRESS address of CSB 123 * C CCB is valid 124 * AT 0 = addrs are virtual, 1 = addrs are phys 125 * M enable perf monitor 126 */ 127 #define CRB_CSB_ADDRESS (0xfffffffffffffff0) 128 #define CRB_CSB_C (0x0000000000000008) 129 #define CRB_CSB_AT (0x0000000000000002) 130 #define CRB_CSB_M (0x0000000000000001) 131 132 struct coprocessor_request_block { 133 __be32 ccw; 134 __be32 flags; 135 __be64 csb_addr; 136 137 struct data_descriptor_entry source; 138 struct data_descriptor_entry target; 139 140 struct coprocessor_completion_block ccb; 141 142 u8 reserved[48]; 143 144 struct coprocessor_status_block csb; 145 } __packed __aligned(CRB_ALIGN); 146 147 148 /* RFC02167 Initiate Coprocessor Instructions document 149 * Chapter 8.2.1.1.1 RS 150 * Chapter 8.2.3 Coprocessor Directive 151 * Chapter 8.2.4 Execution 152 * 153 * The CCW must be converted to BE before passing to icswx() 154 */ 155 156 #define CCW_PS (0xff000000) 157 #define CCW_CT (0x00ff0000) 158 #define CCW_CD (0x0000ffff) 159 #define CCW_CL (0x0000c000) 160 161 162 /* RFC02167 Initiate Coprocessor Instructions document 163 * Chapter 8.2.1 Initiate Coprocessor Store Word Indexed (ICSWX) 164 * Chapter 8.2.4.1 Condition Register 0 165 */ 166 167 #define ICSWX_INITIATED (0x8) 168 #define ICSWX_BUSY (0x4) 169 #define ICSWX_REJECTED (0x2) 170 #define ICSWX_XERS0 (0x1) /* undefined or set from XERSO. */ 171 172 static inline int icswx(__be32 ccw, struct coprocessor_request_block *crb) 173 { 174 __be64 ccw_reg = ccw; 175 u32 cr; 176 177 __asm__ __volatile__( 178 PPC_ICSWX(%1,0,%2) "\n" 179 "mfcr %0\n" 180 : "=r" (cr) 181 : "r" (ccw_reg), "r" (crb) 182 : "cr0", "memory"); 183 184 return (int)((cr >> 28) & 0xf); 185 } 186 187 188 #endif /* _ARCH_POWERPC_INCLUDE_ASM_ICSWX_H_ */ 189