1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 3 /* 4 * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. 5 */ 6 #ifndef __GRU_KSERVICES_H_ 7 #define __GRU_KSERVICES_H_ 8 9 10 /* 11 * Message queues using the GRU to send/receive messages. 12 * 13 * These function allow the user to create a message queue for 14 * sending/receiving 1 or 2 cacheline messages using the GRU. 15 * 16 * Processes SENDING messages will use a kernel CBR/DSR to send 17 * the message. This is transparent to the caller. 18 * 19 * The receiver does not use any GRU resources. 20 * 21 * The functions support: 22 * - single receiver 23 * - multiple senders 24 * - cross partition message 25 * 26 * Missing features ZZZ: 27 * - user options for dealing with timeouts, queue full, etc. 28 * - gru_create_message_queue() needs interrupt vector info 29 */ 30 31 struct gru_message_queue_desc { 32 void *mq; /* message queue vaddress */ 33 unsigned long mq_gpa; /* global address of mq */ 34 int qlines; /* queue size in CL */ 35 int interrupt_vector; /* interrupt vector */ 36 int interrupt_pnode; /* pnode for interrupt */ 37 int interrupt_apicid; /* lapicid for interrupt */ 38 }; 39 40 /* 41 * Initialize a user allocated chunk of memory to be used as 42 * a message queue. The caller must ensure that the queue is 43 * in contiguous physical memory and is cacheline aligned. 44 * 45 * Message queue size is the total number of bytes allocated 46 * to the queue including a 2 cacheline header that is used 47 * to manage the queue. 48 * 49 * Input: 50 * mqd pointer to message queue descriptor 51 * p pointer to user allocated mesq memory. 52 * bytes size of message queue in bytes 53 * vector interrupt vector (zero if no interrupts) 54 * nasid nasid of blade where interrupt is delivered 55 * apicid apicid of cpu for interrupt 56 * 57 * Errors: 58 * 0 OK 59 * >0 error 60 */ 61 extern int gru_create_message_queue(struct gru_message_queue_desc *mqd, 62 void *p, unsigned int bytes, int nasid, int vector, int apicid); 63 64 /* 65 * Send a message to a message queue. 66 * 67 * Note: The message queue transport mechanism uses the first 32 68 * bits of the message. Users should avoid using these bits. 69 * 70 * 71 * Input: 72 * mqd pointer to message queue descriptor 73 * mesg pointer to message. Must be 64-bit aligned 74 * bytes size of message in bytes 75 * 76 * Output: 77 * 0 message sent 78 * >0 Send failure - see error codes below 79 * 80 */ 81 extern int gru_send_message_gpa(struct gru_message_queue_desc *mqd, 82 void *mesg, unsigned int bytes); 83 84 /* Status values for gru_send_message() */ 85 #define MQE_OK 0 /* message sent successfully */ 86 #define MQE_CONGESTION 1 /* temporary congestion, try again */ 87 #define MQE_QUEUE_FULL 2 /* queue is full */ 88 #define MQE_UNEXPECTED_CB_ERR 3 /* unexpected CB error */ 89 #define MQE_PAGE_OVERFLOW 10 /* BUG - queue overflowed a page */ 90 #define MQE_BUG_NO_RESOURCES 11 /* BUG - could not alloc GRU cb/dsr */ 91 92 /* 93 * Advance the receive pointer for the message queue to the next message. 94 * Note: current API requires messages to be gotten & freed in order. Future 95 * API extensions may allow for out-of-order freeing. 96 * 97 * Input 98 * mqd pointer to message queue descriptor 99 * mesq message being freed 100 */ 101 extern void gru_free_message(struct gru_message_queue_desc *mqd, 102 void *mesq); 103 104 /* 105 * Get next message from message queue. Returns pointer to 106 * message OR NULL if no message present. 107 * User must call gru_free_message() after message is processed 108 * in order to move the queue pointers to next message. 109 * 110 * Input 111 * mqd pointer to message queue descriptor 112 * 113 * Output: 114 * p pointer to message 115 * NULL no message available 116 */ 117 extern void *gru_get_next_message(struct gru_message_queue_desc *mqd); 118 119 120 /* 121 * Read a GRU global GPA. Source can be located in a remote partition. 122 * 123 * Input: 124 * value memory address where MMR value is returned 125 * gpa source numalink physical address of GPA 126 * 127 * Output: 128 * 0 OK 129 * >0 error 130 */ 131 int gru_read_gpa(unsigned long *value, unsigned long gpa); 132 133 134 /* 135 * Copy data using the GRU. Source or destination can be located in a remote 136 * partition. 137 * 138 * Input: 139 * dest_gpa destination global physical address 140 * src_gpa source global physical address 141 * bytes number of bytes to copy 142 * 143 * Output: 144 * 0 OK 145 * >0 error 146 */ 147 extern int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa, 148 unsigned int bytes); 149 150 /* 151 * Reserve GRU resources to be used asynchronously. 152 * 153 * input: 154 * blade_id - blade on which resources should be reserved 155 * cbrs - number of CBRs 156 * dsr_bytes - number of DSR bytes needed 157 * cmp - completion structure for waiting for 158 * async completions 159 * output: 160 * handle to identify resource 161 * (0 = no resources) 162 */ 163 extern unsigned long gru_reserve_async_resources(int blade_id, int cbrs, int dsr_bytes, 164 struct completion *cmp); 165 166 /* 167 * Release async resources previously reserved. 168 * 169 * input: 170 * han - handle to identify resources 171 */ 172 extern void gru_release_async_resources(unsigned long han); 173 174 /* 175 * Wait for async GRU instructions to complete. 176 * 177 * input: 178 * han - handle to identify resources 179 */ 180 extern void gru_wait_async_cbr(unsigned long han); 181 182 /* 183 * Lock previous reserved async GRU resources 184 * 185 * input: 186 * han - handle to identify resources 187 * output: 188 * cb - pointer to first CBR 189 * dsr - pointer to first DSR 190 */ 191 extern void gru_lock_async_resource(unsigned long han, void **cb, void **dsr); 192 193 /* 194 * Unlock previous reserved async GRU resources 195 * 196 * input: 197 * han - handle to identify resources 198 */ 199 extern void gru_unlock_async_resource(unsigned long han); 200 201 #endif /* __GRU_KSERVICES_H_ */ 202