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