linux/arch/powerpc/include/asm/epapr_hcalls.h
<<
>>
Prefs
   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 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
 105extern bool epapr_paravirt_enabled;
 106extern u32 epapr_hypercall_start[];
 107
 108#ifdef CONFIG_EPAPR_PARAVIRT
 109int __init epapr_paravirt_early_init(void);
 110#else
 111static inline int epapr_paravirt_early_init(void) { return 0; }
 112#endif
 113
 114/*
 115 * We use "uintptr_t" to define a register because it's guaranteed to be a
 116 * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit
 117 * platform.
 118 *
 119 * All registers are either input/output or output only.  Registers that are
 120 * initialized before making the hypercall are input/output.  All
 121 * input/output registers are represented with "+r".  Output-only registers
 122 * are represented with "=r".  Do not specify any unused registers.  The
 123 * clobber list will tell the compiler that the hypercall modifies those
 124 * registers, which is good enough.
 125 */
 126
 127/**
 128 * ev_int_set_config - configure the specified interrupt
 129 * @interrupt: the interrupt number
 130 * @config: configuration for this interrupt
 131 * @priority: interrupt priority
 132 * @destination: destination CPU number
 133 *
 134 * Returns 0 for success, or an error code.
 135 */
 136static inline unsigned int ev_int_set_config(unsigned int interrupt,
 137        uint32_t config, unsigned int priority, uint32_t destination)
 138{
 139        register uintptr_t r11 __asm__("r11");
 140        register uintptr_t r3 __asm__("r3");
 141        register uintptr_t r4 __asm__("r4");
 142        register uintptr_t r5 __asm__("r5");
 143        register uintptr_t r6 __asm__("r6");
 144
 145        r11 = EV_HCALL_TOKEN(EV_INT_SET_CONFIG);
 146        r3  = interrupt;
 147        r4  = config;
 148        r5  = priority;
 149        r6  = destination;
 150
 151        asm volatile("bl        epapr_hypercall_start"
 152                : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6)
 153                : : EV_HCALL_CLOBBERS4
 154        );
 155
 156        return r3;
 157}
 158
 159/**
 160 * ev_int_get_config - return the config of the specified interrupt
 161 * @interrupt: the interrupt number
 162 * @config: returned configuration for this interrupt
 163 * @priority: returned interrupt priority
 164 * @destination: returned destination CPU number
 165 *
 166 * Returns 0 for success, or an error code.
 167 */
 168static inline unsigned int ev_int_get_config(unsigned int interrupt,
 169        uint32_t *config, unsigned int *priority, uint32_t *destination)
 170{
 171        register uintptr_t r11 __asm__("r11");
 172        register uintptr_t r3 __asm__("r3");
 173        register uintptr_t r4 __asm__("r4");
 174        register uintptr_t r5 __asm__("r5");
 175        register uintptr_t r6 __asm__("r6");
 176
 177        r11 = EV_HCALL_TOKEN(EV_INT_GET_CONFIG);
 178        r3 = interrupt;
 179
 180        asm volatile("bl        epapr_hypercall_start"
 181                : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5), "=r" (r6)
 182                : : EV_HCALL_CLOBBERS4
 183        );
 184
 185        *config = r4;
 186        *priority = r5;
 187        *destination = r6;
 188
 189        return r3;
 190}
 191
 192/**
 193 * ev_int_set_mask - sets the mask for the specified interrupt source
 194 * @interrupt: the interrupt number
 195 * @mask: 0=enable interrupts, 1=disable interrupts
 196 *
 197 * Returns 0 for success, or an error code.
 198 */
 199static inline unsigned int ev_int_set_mask(unsigned int interrupt,
 200        unsigned int mask)
 201{
 202        register uintptr_t r11 __asm__("r11");
 203        register uintptr_t r3 __asm__("r3");
 204        register uintptr_t r4 __asm__("r4");
 205
 206        r11 = EV_HCALL_TOKEN(EV_INT_SET_MASK);
 207        r3 = interrupt;
 208        r4 = mask;
 209
 210        asm volatile("bl        epapr_hypercall_start"
 211                : "+r" (r11), "+r" (r3), "+r" (r4)
 212                : : EV_HCALL_CLOBBERS2
 213        );
 214
 215        return r3;
 216}
 217
 218/**
 219 * ev_int_get_mask - returns the mask for the specified interrupt source
 220 * @interrupt: the interrupt number
 221 * @mask: returned mask for this interrupt (0=enabled, 1=disabled)
 222 *
 223 * Returns 0 for success, or an error code.
 224 */
 225static inline unsigned int ev_int_get_mask(unsigned int interrupt,
 226        unsigned int *mask)
 227{
 228        register uintptr_t r11 __asm__("r11");
 229        register uintptr_t r3 __asm__("r3");
 230        register uintptr_t r4 __asm__("r4");
 231
 232        r11 = EV_HCALL_TOKEN(EV_INT_GET_MASK);
 233        r3 = interrupt;
 234
 235        asm volatile("bl        epapr_hypercall_start"
 236                : "+r" (r11), "+r" (r3), "=r" (r4)
 237                : : EV_HCALL_CLOBBERS2
 238        );
 239
 240        *mask = r4;
 241
 242        return r3;
 243}
 244
 245/**
 246 * ev_int_eoi - signal the end of interrupt processing
 247 * @interrupt: the interrupt number
 248 *
 249 * This function signals the end of processing for the specified
 250 * interrupt, which must be the interrupt currently in service. By
 251 * definition, this is also the highest-priority interrupt.
 252 *
 253 * Returns 0 for success, or an error code.
 254 */
 255static inline unsigned int ev_int_eoi(unsigned int interrupt)
 256{
 257        register uintptr_t r11 __asm__("r11");
 258        register uintptr_t r3 __asm__("r3");
 259
 260        r11 = EV_HCALL_TOKEN(EV_INT_EOI);
 261        r3 = interrupt;
 262
 263        asm volatile("bl        epapr_hypercall_start"
 264                : "+r" (r11), "+r" (r3)
 265                : : EV_HCALL_CLOBBERS1
 266        );
 267
 268        return r3;
 269}
 270
 271/**
 272 * ev_byte_channel_send - send characters to a byte stream
 273 * @handle: byte stream handle
 274 * @count: (input) num of chars to send, (output) num chars sent
 275 * @buffer: pointer to a 16-byte buffer
 276 *
 277 * @buffer must be at least 16 bytes long, because all 16 bytes will be
 278 * read from memory into registers, even if count < 16.
 279 *
 280 * Returns 0 for success, or an error code.
 281 */
 282static inline unsigned int ev_byte_channel_send(unsigned int handle,
 283        unsigned int *count, const char buffer[EV_BYTE_CHANNEL_MAX_BYTES])
 284{
 285        register uintptr_t r11 __asm__("r11");
 286        register uintptr_t r3 __asm__("r3");
 287        register uintptr_t r4 __asm__("r4");
 288        register uintptr_t r5 __asm__("r5");
 289        register uintptr_t r6 __asm__("r6");
 290        register uintptr_t r7 __asm__("r7");
 291        register uintptr_t r8 __asm__("r8");
 292        const uint32_t *p = (const uint32_t *) buffer;
 293
 294        r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_SEND);
 295        r3 = handle;
 296        r4 = *count;
 297        r5 = be32_to_cpu(p[0]);
 298        r6 = be32_to_cpu(p[1]);
 299        r7 = be32_to_cpu(p[2]);
 300        r8 = be32_to_cpu(p[3]);
 301
 302        asm volatile("bl        epapr_hypercall_start"
 303                : "+r" (r11), "+r" (r3),
 304                  "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), "+r" (r8)
 305                : : EV_HCALL_CLOBBERS6
 306        );
 307
 308        *count = r4;
 309
 310        return r3;
 311}
 312
 313/**
 314 * ev_byte_channel_receive - fetch characters from a byte channel
 315 * @handle: byte channel handle
 316 * @count: (input) max num of chars to receive, (output) num chars received
 317 * @buffer: pointer to a 16-byte buffer
 318 *
 319 * The size of @buffer must be at least 16 bytes, even if you request fewer
 320 * than 16 characters, because we always write 16 bytes to @buffer.  This is
 321 * for performance reasons.
 322 *
 323 * Returns 0 for success, or an error code.
 324 */
 325static inline unsigned int ev_byte_channel_receive(unsigned int handle,
 326        unsigned int *count, char buffer[EV_BYTE_CHANNEL_MAX_BYTES])
 327{
 328        register uintptr_t r11 __asm__("r11");
 329        register uintptr_t r3 __asm__("r3");
 330        register uintptr_t r4 __asm__("r4");
 331        register uintptr_t r5 __asm__("r5");
 332        register uintptr_t r6 __asm__("r6");
 333        register uintptr_t r7 __asm__("r7");
 334        register uintptr_t r8 __asm__("r8");
 335        uint32_t *p = (uint32_t *) buffer;
 336
 337        r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_RECEIVE);
 338        r3 = handle;
 339        r4 = *count;
 340
 341        asm volatile("bl        epapr_hypercall_start"
 342                : "+r" (r11), "+r" (r3), "+r" (r4),
 343                  "=r" (r5), "=r" (r6), "=r" (r7), "=r" (r8)
 344                : : EV_HCALL_CLOBBERS6
 345        );
 346
 347        *count = r4;
 348        p[0] = cpu_to_be32(r5);
 349        p[1] = cpu_to_be32(r6);
 350        p[2] = cpu_to_be32(r7);
 351        p[3] = cpu_to_be32(r8);
 352
 353        return r3;
 354}
 355
 356/**
 357 * ev_byte_channel_poll - returns the status of the byte channel buffers
 358 * @handle: byte channel handle
 359 * @rx_count: returned count of bytes in receive queue
 360 * @tx_count: returned count of free space in transmit queue
 361 *
 362 * This function reports the amount of data in the receive queue (i.e. the
 363 * number of bytes you can read), and the amount of free space in the transmit
 364 * queue (i.e. the number of bytes you can write).
 365 *
 366 * Returns 0 for success, or an error code.
 367 */
 368static inline unsigned int ev_byte_channel_poll(unsigned int handle,
 369        unsigned int *rx_count, unsigned int *tx_count)
 370{
 371        register uintptr_t r11 __asm__("r11");
 372        register uintptr_t r3 __asm__("r3");
 373        register uintptr_t r4 __asm__("r4");
 374        register uintptr_t r5 __asm__("r5");
 375
 376        r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_POLL);
 377        r3 = handle;
 378
 379        asm volatile("bl        epapr_hypercall_start"
 380                : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5)
 381                : : EV_HCALL_CLOBBERS3
 382        );
 383
 384        *rx_count = r4;
 385        *tx_count = r5;
 386
 387        return r3;
 388}
 389
 390/**
 391 * ev_int_iack - acknowledge an interrupt
 392 * @handle: handle to the target interrupt controller
 393 * @vector: returned interrupt vector
 394 *
 395 * If handle is zero, the function returns the next interrupt source
 396 * number to be handled irrespective of the hierarchy or cascading
 397 * of interrupt controllers. If non-zero, specifies a handle to the
 398 * interrupt controller that is the target of the acknowledge.
 399 *
 400 * Returns 0 for success, or an error code.
 401 */
 402static inline unsigned int ev_int_iack(unsigned int handle,
 403        unsigned int *vector)
 404{
 405        register uintptr_t r11 __asm__("r11");
 406        register uintptr_t r3 __asm__("r3");
 407        register uintptr_t r4 __asm__("r4");
 408
 409        r11 = EV_HCALL_TOKEN(EV_INT_IACK);
 410        r3 = handle;
 411
 412        asm volatile("bl        epapr_hypercall_start"
 413                : "+r" (r11), "+r" (r3), "=r" (r4)
 414                : : EV_HCALL_CLOBBERS2
 415        );
 416
 417        *vector = r4;
 418
 419        return r3;
 420}
 421
 422/**
 423 * ev_doorbell_send - send a doorbell to another partition
 424 * @handle: doorbell send handle
 425 *
 426 * Returns 0 for success, or an error code.
 427 */
 428static inline unsigned int ev_doorbell_send(unsigned int handle)
 429{
 430        register uintptr_t r11 __asm__("r11");
 431        register uintptr_t r3 __asm__("r3");
 432
 433        r11 = EV_HCALL_TOKEN(EV_DOORBELL_SEND);
 434        r3 = handle;
 435
 436        asm volatile("bl        epapr_hypercall_start"
 437                : "+r" (r11), "+r" (r3)
 438                : : EV_HCALL_CLOBBERS1
 439        );
 440
 441        return r3;
 442}
 443
 444/**
 445 * ev_idle -- wait for next interrupt on this core
 446 *
 447 * Returns 0 for success, or an error code.
 448 */
 449static inline unsigned int ev_idle(void)
 450{
 451        register uintptr_t r11 __asm__("r11");
 452        register uintptr_t r3 __asm__("r3");
 453
 454        r11 = EV_HCALL_TOKEN(EV_IDLE);
 455
 456        asm volatile("bl        epapr_hypercall_start"
 457                : "+r" (r11), "=r" (r3)
 458                : : EV_HCALL_CLOBBERS1
 459        );
 460
 461        return r3;
 462}
 463
 464#ifdef CONFIG_EPAPR_PARAVIRT
 465static inline unsigned long epapr_hypercall(unsigned long *in,
 466                            unsigned long *out,
 467                            unsigned long nr)
 468{
 469        register unsigned long r0 asm("r0");
 470        register unsigned long r3 asm("r3") = in[0];
 471        register unsigned long r4 asm("r4") = in[1];
 472        register unsigned long r5 asm("r5") = in[2];
 473        register unsigned long r6 asm("r6") = in[3];
 474        register unsigned long r7 asm("r7") = in[4];
 475        register unsigned long r8 asm("r8") = in[5];
 476        register unsigned long r9 asm("r9") = in[6];
 477        register unsigned long r10 asm("r10") = in[7];
 478        register unsigned long r11 asm("r11") = nr;
 479        register unsigned long r12 asm("r12");
 480
 481        asm volatile("bl        epapr_hypercall_start"
 482                     : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6),
 483                       "=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11),
 484                       "=r"(r12)
 485                     : "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "r"(r8),
 486                       "r"(r9), "r"(r10), "r"(r11)
 487                     : "memory", "cc", "xer", "ctr", "lr");
 488
 489        out[0] = r4;
 490        out[1] = r5;
 491        out[2] = r6;
 492        out[3] = r7;
 493        out[4] = r8;
 494        out[5] = r9;
 495        out[6] = r10;
 496        out[7] = r11;
 497
 498        return r3;
 499}
 500#else
 501static unsigned long epapr_hypercall(unsigned long *in,
 502                                   unsigned long *out,
 503                                   unsigned long nr)
 504{
 505        return EV_UNIMPLEMENTED;
 506}
 507#endif
 508
 509static inline long epapr_hypercall0_1(unsigned int nr, unsigned long *r2)
 510{
 511        unsigned long in[8] = {0};
 512        unsigned long out[8];
 513        unsigned long r;
 514
 515        r = epapr_hypercall(in, out, nr);
 516        *r2 = out[0];
 517
 518        return r;
 519}
 520
 521static inline long epapr_hypercall0(unsigned int nr)
 522{
 523        unsigned long in[8] = {0};
 524        unsigned long out[8];
 525
 526        return epapr_hypercall(in, out, nr);
 527}
 528
 529static inline long epapr_hypercall1(unsigned int nr, unsigned long p1)
 530{
 531        unsigned long in[8] = {0};
 532        unsigned long out[8];
 533
 534        in[0] = p1;
 535        return epapr_hypercall(in, out, nr);
 536}
 537
 538static inline long epapr_hypercall2(unsigned int nr, unsigned long p1,
 539                                    unsigned long p2)
 540{
 541        unsigned long in[8] = {0};
 542        unsigned long out[8];
 543
 544        in[0] = p1;
 545        in[1] = p2;
 546        return epapr_hypercall(in, out, nr);
 547}
 548
 549static inline long epapr_hypercall3(unsigned int nr, unsigned long p1,
 550                                    unsigned long p2, unsigned long p3)
 551{
 552        unsigned long in[8] = {0};
 553        unsigned long out[8];
 554
 555        in[0] = p1;
 556        in[1] = p2;
 557        in[2] = p3;
 558        return epapr_hypercall(in, out, nr);
 559}
 560
 561static inline long epapr_hypercall4(unsigned int nr, unsigned long p1,
 562                                    unsigned long p2, unsigned long p3,
 563                                    unsigned long p4)
 564{
 565        unsigned long in[8] = {0};
 566        unsigned long out[8];
 567
 568        in[0] = p1;
 569        in[1] = p2;
 570        in[2] = p3;
 571        in[3] = p4;
 572        return epapr_hypercall(in, out, nr);
 573}
 574#endif /* !__ASSEMBLY__ */
 575#endif /* _EPAPR_HCALLS_H */
 576