1 /* 2 * ePAPR hcall interface 3 * 4 * Copyright 2008-2011 Freescale Semiconductor, Inc. 5 * 6 * Author: Timur Tabi <timur@freescale.com> 7 * 8 * This file is provided under a dual BSD/GPL license. When using or 9 * redistributing this file, you may do so under either license. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions are met: 13 * * Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * * Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * * Neither the name of Freescale Semiconductor nor the 19 * names of its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * 23 * ALTERNATIVELY, this software may be distributed under the terms of the 24 * GNU General Public License ("GPL") as published by the Free Software 25 * Foundation, either version 2 of that License or (at your option) any 26 * later version. 27 * 28 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 29 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 33 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 34 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 35 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* A "hypercall" is an "sc 1" instruction. This header file file provides C 41 * wrapper functions for the ePAPR hypervisor interface. It is inteded 42 * for use by Linux device drivers and other operating systems. 43 * 44 * The hypercalls are implemented as inline assembly, rather than assembly 45 * language functions in a .S file, for optimization. It allows 46 * the caller to issue the hypercall instruction directly, improving both 47 * performance and memory footprint. 48 */ 49 50 #ifndef _EPAPR_HCALLS_H 51 #define _EPAPR_HCALLS_H 52 53 #include <uapi/asm/epapr_hcalls.h> 54 55 #ifndef __ASSEMBLY__ 56 #include <linux/types.h> 57 #include <linux/errno.h> 58 #include <asm/byteorder.h> 59 60 /* 61 * Hypercall register clobber list 62 * 63 * These macros are used to define the list of clobbered registers during a 64 * hypercall. Technically, registers r0 and r3-r12 are always clobbered, 65 * but the gcc inline assembly syntax does not allow us to specify registers 66 * on the clobber list that are also on the input/output list. Therefore, 67 * the lists of clobbered registers depends on the number of register 68 * parmeters ("+r" and "=r") passed to the hypercall. 69 * 70 * Each assembly block should use one of the HCALL_CLOBBERSx macros. As a 71 * general rule, 'x' is the number of parameters passed to the assembly 72 * block *except* for r11. 73 * 74 * If you're not sure, just use the smallest value of 'x' that does not 75 * generate a compilation error. Because these are static inline functions, 76 * the compiler will only check the clobber list for a function if you 77 * compile code that calls that function. 78 * 79 * r3 and r11 are not included in any clobbers list because they are always 80 * listed as output registers. 81 * 82 * XER, CTR, and LR are currently listed as clobbers because it's uncertain 83 * whether they will be clobbered. 84 * 85 * Note that r11 can be used as an output parameter. 86 * 87 * The "memory" clobber is only necessary for hcalls where the Hypervisor 88 * will read or write guest memory. However, we add it to all hcalls because 89 * the impact is minimal, and we want to ensure that it's present for the 90 * hcalls that need it. 91 */ 92 93 /* List of common clobbered registers. Do not use this macro. */ 94 #define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc", "memory" 95 96 #define EV_HCALL_CLOBBERS8 EV_HCALL_CLOBBERS 97 #define EV_HCALL_CLOBBERS7 EV_HCALL_CLOBBERS8, "r10" 98 #define EV_HCALL_CLOBBERS6 EV_HCALL_CLOBBERS7, "r9" 99 #define EV_HCALL_CLOBBERS5 EV_HCALL_CLOBBERS6, "r8" 100 #define EV_HCALL_CLOBBERS4 EV_HCALL_CLOBBERS5, "r7" 101 #define EV_HCALL_CLOBBERS3 EV_HCALL_CLOBBERS4, "r6" 102 #define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5" 103 #define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4" 104 105 extern bool epapr_paravirt_enabled; 106 extern u32 epapr_hypercall_start[]; 107 108 /* 109 * We use "uintptr_t" to define a register because it's guaranteed to be a 110 * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit 111 * platform. 112 * 113 * All registers are either input/output or output only. Registers that are 114 * initialized before making the hypercall are input/output. All 115 * input/output registers are represented with "+r". Output-only registers 116 * are represented with "=r". Do not specify any unused registers. The 117 * clobber list will tell the compiler that the hypercall modifies those 118 * registers, which is good enough. 119 */ 120 121 /** 122 * ev_int_set_config - configure the specified interrupt 123 * @interrupt: the interrupt number 124 * @config: configuration for this interrupt 125 * @priority: interrupt priority 126 * @destination: destination CPU number 127 * 128 * Returns 0 for success, or an error code. 129 */ 130 static inline unsigned int ev_int_set_config(unsigned int interrupt, 131 uint32_t config, unsigned int priority, uint32_t destination) 132 { 133 register uintptr_t r11 __asm__("r11"); 134 register uintptr_t r3 __asm__("r3"); 135 register uintptr_t r4 __asm__("r4"); 136 register uintptr_t r5 __asm__("r5"); 137 register uintptr_t r6 __asm__("r6"); 138 139 r11 = EV_HCALL_TOKEN(EV_INT_SET_CONFIG); 140 r3 = interrupt; 141 r4 = config; 142 r5 = priority; 143 r6 = destination; 144 145 asm volatile("bl epapr_hypercall_start" 146 : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6) 147 : : EV_HCALL_CLOBBERS4 148 ); 149 150 return r3; 151 } 152 153 /** 154 * ev_int_get_config - return the config of the specified interrupt 155 * @interrupt: the interrupt number 156 * @config: returned configuration for this interrupt 157 * @priority: returned interrupt priority 158 * @destination: returned destination CPU number 159 * 160 * Returns 0 for success, or an error code. 161 */ 162 static inline unsigned int ev_int_get_config(unsigned int interrupt, 163 uint32_t *config, unsigned int *priority, uint32_t *destination) 164 { 165 register uintptr_t r11 __asm__("r11"); 166 register uintptr_t r3 __asm__("r3"); 167 register uintptr_t r4 __asm__("r4"); 168 register uintptr_t r5 __asm__("r5"); 169 register uintptr_t r6 __asm__("r6"); 170 171 r11 = EV_HCALL_TOKEN(EV_INT_GET_CONFIG); 172 r3 = interrupt; 173 174 asm volatile("bl epapr_hypercall_start" 175 : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5), "=r" (r6) 176 : : EV_HCALL_CLOBBERS4 177 ); 178 179 *config = r4; 180 *priority = r5; 181 *destination = r6; 182 183 return r3; 184 } 185 186 /** 187 * ev_int_set_mask - sets the mask for the specified interrupt source 188 * @interrupt: the interrupt number 189 * @mask: 0=enable interrupts, 1=disable interrupts 190 * 191 * Returns 0 for success, or an error code. 192 */ 193 static inline unsigned int ev_int_set_mask(unsigned int interrupt, 194 unsigned int mask) 195 { 196 register uintptr_t r11 __asm__("r11"); 197 register uintptr_t r3 __asm__("r3"); 198 register uintptr_t r4 __asm__("r4"); 199 200 r11 = EV_HCALL_TOKEN(EV_INT_SET_MASK); 201 r3 = interrupt; 202 r4 = mask; 203 204 asm volatile("bl epapr_hypercall_start" 205 : "+r" (r11), "+r" (r3), "+r" (r4) 206 : : EV_HCALL_CLOBBERS2 207 ); 208 209 return r3; 210 } 211 212 /** 213 * ev_int_get_mask - returns the mask for the specified interrupt source 214 * @interrupt: the interrupt number 215 * @mask: returned mask for this interrupt (0=enabled, 1=disabled) 216 * 217 * Returns 0 for success, or an error code. 218 */ 219 static inline unsigned int ev_int_get_mask(unsigned int interrupt, 220 unsigned int *mask) 221 { 222 register uintptr_t r11 __asm__("r11"); 223 register uintptr_t r3 __asm__("r3"); 224 register uintptr_t r4 __asm__("r4"); 225 226 r11 = EV_HCALL_TOKEN(EV_INT_GET_MASK); 227 r3 = interrupt; 228 229 asm volatile("bl epapr_hypercall_start" 230 : "+r" (r11), "+r" (r3), "=r" (r4) 231 : : EV_HCALL_CLOBBERS2 232 ); 233 234 *mask = r4; 235 236 return r3; 237 } 238 239 /** 240 * ev_int_eoi - signal the end of interrupt processing 241 * @interrupt: the interrupt number 242 * 243 * This function signals the end of processing for the the specified 244 * interrupt, which must be the interrupt currently in service. By 245 * definition, this is also the highest-priority interrupt. 246 * 247 * Returns 0 for success, or an error code. 248 */ 249 static inline unsigned int ev_int_eoi(unsigned int interrupt) 250 { 251 register uintptr_t r11 __asm__("r11"); 252 register uintptr_t r3 __asm__("r3"); 253 254 r11 = EV_HCALL_TOKEN(EV_INT_EOI); 255 r3 = interrupt; 256 257 asm volatile("bl epapr_hypercall_start" 258 : "+r" (r11), "+r" (r3) 259 : : EV_HCALL_CLOBBERS1 260 ); 261 262 return r3; 263 } 264 265 /** 266 * ev_byte_channel_send - send characters to a byte stream 267 * @handle: byte stream handle 268 * @count: (input) num of chars to send, (output) num chars sent 269 * @buffer: pointer to a 16-byte buffer 270 * 271 * @buffer must be at least 16 bytes long, because all 16 bytes will be 272 * read from memory into registers, even if count < 16. 273 * 274 * Returns 0 for success, or an error code. 275 */ 276 static inline unsigned int ev_byte_channel_send(unsigned int handle, 277 unsigned int *count, const char buffer[EV_BYTE_CHANNEL_MAX_BYTES]) 278 { 279 register uintptr_t r11 __asm__("r11"); 280 register uintptr_t r3 __asm__("r3"); 281 register uintptr_t r4 __asm__("r4"); 282 register uintptr_t r5 __asm__("r5"); 283 register uintptr_t r6 __asm__("r6"); 284 register uintptr_t r7 __asm__("r7"); 285 register uintptr_t r8 __asm__("r8"); 286 const uint32_t *p = (const uint32_t *) buffer; 287 288 r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_SEND); 289 r3 = handle; 290 r4 = *count; 291 r5 = be32_to_cpu(p[0]); 292 r6 = be32_to_cpu(p[1]); 293 r7 = be32_to_cpu(p[2]); 294 r8 = be32_to_cpu(p[3]); 295 296 asm volatile("bl epapr_hypercall_start" 297 : "+r" (r11), "+r" (r3), 298 "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), "+r" (r8) 299 : : EV_HCALL_CLOBBERS6 300 ); 301 302 *count = r4; 303 304 return r3; 305 } 306 307 /** 308 * ev_byte_channel_receive - fetch characters from a byte channel 309 * @handle: byte channel handle 310 * @count: (input) max num of chars to receive, (output) num chars received 311 * @buffer: pointer to a 16-byte buffer 312 * 313 * The size of @buffer must be at least 16 bytes, even if you request fewer 314 * than 16 characters, because we always write 16 bytes to @buffer. This is 315 * for performance reasons. 316 * 317 * Returns 0 for success, or an error code. 318 */ 319 static inline unsigned int ev_byte_channel_receive(unsigned int handle, 320 unsigned int *count, char buffer[EV_BYTE_CHANNEL_MAX_BYTES]) 321 { 322 register uintptr_t r11 __asm__("r11"); 323 register uintptr_t r3 __asm__("r3"); 324 register uintptr_t r4 __asm__("r4"); 325 register uintptr_t r5 __asm__("r5"); 326 register uintptr_t r6 __asm__("r6"); 327 register uintptr_t r7 __asm__("r7"); 328 register uintptr_t r8 __asm__("r8"); 329 uint32_t *p = (uint32_t *) buffer; 330 331 r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_RECEIVE); 332 r3 = handle; 333 r4 = *count; 334 335 asm volatile("bl epapr_hypercall_start" 336 : "+r" (r11), "+r" (r3), "+r" (r4), 337 "=r" (r5), "=r" (r6), "=r" (r7), "=r" (r8) 338 : : EV_HCALL_CLOBBERS6 339 ); 340 341 *count = r4; 342 p[0] = cpu_to_be32(r5); 343 p[1] = cpu_to_be32(r6); 344 p[2] = cpu_to_be32(r7); 345 p[3] = cpu_to_be32(r8); 346 347 return r3; 348 } 349 350 /** 351 * ev_byte_channel_poll - returns the status of the byte channel buffers 352 * @handle: byte channel handle 353 * @rx_count: returned count of bytes in receive queue 354 * @tx_count: returned count of free space in transmit queue 355 * 356 * This function reports the amount of data in the receive queue (i.e. the 357 * number of bytes you can read), and the amount of free space in the transmit 358 * queue (i.e. the number of bytes you can write). 359 * 360 * Returns 0 for success, or an error code. 361 */ 362 static inline unsigned int ev_byte_channel_poll(unsigned int handle, 363 unsigned int *rx_count, unsigned int *tx_count) 364 { 365 register uintptr_t r11 __asm__("r11"); 366 register uintptr_t r3 __asm__("r3"); 367 register uintptr_t r4 __asm__("r4"); 368 register uintptr_t r5 __asm__("r5"); 369 370 r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_POLL); 371 r3 = handle; 372 373 asm volatile("bl epapr_hypercall_start" 374 : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5) 375 : : EV_HCALL_CLOBBERS3 376 ); 377 378 *rx_count = r4; 379 *tx_count = r5; 380 381 return r3; 382 } 383 384 /** 385 * ev_int_iack - acknowledge an interrupt 386 * @handle: handle to the target interrupt controller 387 * @vector: returned interrupt vector 388 * 389 * If handle is zero, the function returns the next interrupt source 390 * number to be handled irrespective of the hierarchy or cascading 391 * of interrupt controllers. If non-zero, specifies a handle to the 392 * interrupt controller that is the target of the acknowledge. 393 * 394 * Returns 0 for success, or an error code. 395 */ 396 static inline unsigned int ev_int_iack(unsigned int handle, 397 unsigned int *vector) 398 { 399 register uintptr_t r11 __asm__("r11"); 400 register uintptr_t r3 __asm__("r3"); 401 register uintptr_t r4 __asm__("r4"); 402 403 r11 = EV_HCALL_TOKEN(EV_INT_IACK); 404 r3 = handle; 405 406 asm volatile("bl epapr_hypercall_start" 407 : "+r" (r11), "+r" (r3), "=r" (r4) 408 : : EV_HCALL_CLOBBERS2 409 ); 410 411 *vector = r4; 412 413 return r3; 414 } 415 416 /** 417 * ev_doorbell_send - send a doorbell to another partition 418 * @handle: doorbell send handle 419 * 420 * Returns 0 for success, or an error code. 421 */ 422 static inline unsigned int ev_doorbell_send(unsigned int handle) 423 { 424 register uintptr_t r11 __asm__("r11"); 425 register uintptr_t r3 __asm__("r3"); 426 427 r11 = EV_HCALL_TOKEN(EV_DOORBELL_SEND); 428 r3 = handle; 429 430 asm volatile("bl epapr_hypercall_start" 431 : "+r" (r11), "+r" (r3) 432 : : EV_HCALL_CLOBBERS1 433 ); 434 435 return r3; 436 } 437 438 /** 439 * ev_idle -- wait for next interrupt on this core 440 * 441 * Returns 0 for success, or an error code. 442 */ 443 static inline unsigned int ev_idle(void) 444 { 445 register uintptr_t r11 __asm__("r11"); 446 register uintptr_t r3 __asm__("r3"); 447 448 r11 = EV_HCALL_TOKEN(EV_IDLE); 449 450 asm volatile("bl epapr_hypercall_start" 451 : "+r" (r11), "=r" (r3) 452 : : EV_HCALL_CLOBBERS1 453 ); 454 455 return r3; 456 } 457 #endif /* !__ASSEMBLY__ */ 458 #endif /* _EPAPR_HCALLS_H */ 459