···11+/*22+ * ePAPR hcall interface33+ *44+ * Copyright 2008-2011 Freescale Semiconductor, Inc.55+ *66+ * Author: Timur Tabi <timur@freescale.com>77+ *88+ * This file is provided under a dual BSD/GPL license. When using or99+ * redistributing this file, you may do so under either license.1010+ *1111+ * Redistribution and use in source and binary forms, with or without1212+ * modification, are permitted provided that the following conditions are met:1313+ * * Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions and the following disclaimer.1515+ * * Redistributions in binary form must reproduce the above copyright1616+ * notice, this list of conditions and the following disclaimer in the1717+ * documentation and/or other materials provided with the distribution.1818+ * * Neither the name of Freescale Semiconductor nor the1919+ * names of its contributors may be used to endorse or promote products2020+ * derived from this software without specific prior written permission.2121+ *2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") as published by the Free Software2525+ * Foundation, either version 2 of that License or (at your option) any2626+ * later version.2727+ *2828+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY2929+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED3030+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE3131+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY3232+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES3333+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;3434+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND3535+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT3636+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+/* A "hypercall" is an "sc 1" instruction. This header file file provides C4141+ * wrapper functions for the ePAPR hypervisor interface. It is inteded4242+ * for use by Linux device drivers and other operating systems.4343+ *4444+ * The hypercalls are implemented as inline assembly, rather than assembly4545+ * language functions in a .S file, for optimization. It allows4646+ * the caller to issue the hypercall instruction directly, improving both4747+ * performance and memory footprint.4848+ */4949+5050+#ifndef _EPAPR_HCALLS_H5151+#define _EPAPR_HCALLS_H5252+5353+#include <uapi/asm/epapr_hcalls.h>5454+5555+#ifndef __ASSEMBLY__5656+#include <linux/types.h>5757+#include <linux/errno.h>5858+#include <asm/byteorder.h>5959+6060+/*6161+ * Hypercall register clobber list6262+ *6363+ * These macros are used to define the list of clobbered registers during a6464+ * hypercall. Technically, registers r0 and r3-r12 are always clobbered,6565+ * but the gcc inline assembly syntax does not allow us to specify registers6666+ * on the clobber list that are also on the input/output list. Therefore,6767+ * the lists of clobbered registers depends on the number of register6868+ * parmeters ("+r" and "=r") passed to the hypercall.6969+ *7070+ * Each assembly block should use one of the HCALL_CLOBBERSx macros. As a7171+ * general rule, 'x' is the number of parameters passed to the assembly7272+ * block *except* for r11.7373+ *7474+ * If you're not sure, just use the smallest value of 'x' that does not7575+ * generate a compilation error. Because these are static inline functions,7676+ * the compiler will only check the clobber list for a function if you7777+ * compile code that calls that function.7878+ *7979+ * r3 and r11 are not included in any clobbers list because they are always8080+ * listed as output registers.8181+ *8282+ * XER, CTR, and LR are currently listed as clobbers because it's uncertain8383+ * whether they will be clobbered.8484+ *8585+ * Note that r11 can be used as an output parameter.8686+ *8787+ * The "memory" clobber is only necessary for hcalls where the Hypervisor8888+ * will read or write guest memory. However, we add it to all hcalls because8989+ * the impact is minimal, and we want to ensure that it's present for the9090+ * hcalls that need it.9191+*/9292+9393+/* List of common clobbered registers. Do not use this macro. */9494+#define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc", "memory"9595+9696+#define EV_HCALL_CLOBBERS8 EV_HCALL_CLOBBERS9797+#define EV_HCALL_CLOBBERS7 EV_HCALL_CLOBBERS8, "r10"9898+#define EV_HCALL_CLOBBERS6 EV_HCALL_CLOBBERS7, "r9"9999+#define EV_HCALL_CLOBBERS5 EV_HCALL_CLOBBERS6, "r8"100100+#define EV_HCALL_CLOBBERS4 EV_HCALL_CLOBBERS5, "r7"101101+#define EV_HCALL_CLOBBERS3 EV_HCALL_CLOBBERS4, "r6"102102+#define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"103103+#define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"104104+105105+extern bool epapr_paravirt_enabled;106106+extern u32 epapr_hypercall_start[];107107+108108+/*109109+ * We use "uintptr_t" to define a register because it's guaranteed to be a110110+ * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit111111+ * platform.112112+ *113113+ * All registers are either input/output or output only. Registers that are114114+ * initialized before making the hypercall are input/output. All115115+ * input/output registers are represented with "+r". Output-only registers116116+ * are represented with "=r". Do not specify any unused registers. The117117+ * clobber list will tell the compiler that the hypercall modifies those118118+ * registers, which is good enough.119119+ */120120+121121+/**122122+ * ev_int_set_config - configure the specified interrupt123123+ * @interrupt: the interrupt number124124+ * @config: configuration for this interrupt125125+ * @priority: interrupt priority126126+ * @destination: destination CPU number127127+ *128128+ * Returns 0 for success, or an error code.129129+ */130130+static inline unsigned int ev_int_set_config(unsigned int interrupt,131131+ uint32_t config, unsigned int priority, uint32_t destination)132132+{133133+ register uintptr_t r11 __asm__("r11");134134+ register uintptr_t r3 __asm__("r3");135135+ register uintptr_t r4 __asm__("r4");136136+ register uintptr_t r5 __asm__("r5");137137+ register uintptr_t r6 __asm__("r6");138138+139139+ r11 = EV_HCALL_TOKEN(EV_INT_SET_CONFIG);140140+ r3 = interrupt;141141+ r4 = config;142142+ r5 = priority;143143+ r6 = destination;144144+145145+ asm volatile("bl epapr_hypercall_start"146146+ : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6)147147+ : : EV_HCALL_CLOBBERS4148148+ );149149+150150+ return r3;151151+}152152+153153+/**154154+ * ev_int_get_config - return the config of the specified interrupt155155+ * @interrupt: the interrupt number156156+ * @config: returned configuration for this interrupt157157+ * @priority: returned interrupt priority158158+ * @destination: returned destination CPU number159159+ *160160+ * Returns 0 for success, or an error code.161161+ */162162+static inline unsigned int ev_int_get_config(unsigned int interrupt,163163+ uint32_t *config, unsigned int *priority, uint32_t *destination)164164+{165165+ register uintptr_t r11 __asm__("r11");166166+ register uintptr_t r3 __asm__("r3");167167+ register uintptr_t r4 __asm__("r4");168168+ register uintptr_t r5 __asm__("r5");169169+ register uintptr_t r6 __asm__("r6");170170+171171+ r11 = EV_HCALL_TOKEN(EV_INT_GET_CONFIG);172172+ r3 = interrupt;173173+174174+ asm volatile("bl epapr_hypercall_start"175175+ : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5), "=r" (r6)176176+ : : EV_HCALL_CLOBBERS4177177+ );178178+179179+ *config = r4;180180+ *priority = r5;181181+ *destination = r6;182182+183183+ return r3;184184+}185185+186186+/**187187+ * ev_int_set_mask - sets the mask for the specified interrupt source188188+ * @interrupt: the interrupt number189189+ * @mask: 0=enable interrupts, 1=disable interrupts190190+ *191191+ * Returns 0 for success, or an error code.192192+ */193193+static inline unsigned int ev_int_set_mask(unsigned int interrupt,194194+ unsigned int mask)195195+{196196+ register uintptr_t r11 __asm__("r11");197197+ register uintptr_t r3 __asm__("r3");198198+ register uintptr_t r4 __asm__("r4");199199+200200+ r11 = EV_HCALL_TOKEN(EV_INT_SET_MASK);201201+ r3 = interrupt;202202+ r4 = mask;203203+204204+ asm volatile("bl epapr_hypercall_start"205205+ : "+r" (r11), "+r" (r3), "+r" (r4)206206+ : : EV_HCALL_CLOBBERS2207207+ );208208+209209+ return r3;210210+}211211+212212+/**213213+ * ev_int_get_mask - returns the mask for the specified interrupt source214214+ * @interrupt: the interrupt number215215+ * @mask: returned mask for this interrupt (0=enabled, 1=disabled)216216+ *217217+ * Returns 0 for success, or an error code.218218+ */219219+static inline unsigned int ev_int_get_mask(unsigned int interrupt,220220+ unsigned int *mask)221221+{222222+ register uintptr_t r11 __asm__("r11");223223+ register uintptr_t r3 __asm__("r3");224224+ register uintptr_t r4 __asm__("r4");225225+226226+ r11 = EV_HCALL_TOKEN(EV_INT_GET_MASK);227227+ r3 = interrupt;228228+229229+ asm volatile("bl epapr_hypercall_start"230230+ : "+r" (r11), "+r" (r3), "=r" (r4)231231+ : : EV_HCALL_CLOBBERS2232232+ );233233+234234+ *mask = r4;235235+236236+ return r3;237237+}238238+239239+/**240240+ * ev_int_eoi - signal the end of interrupt processing241241+ * @interrupt: the interrupt number242242+ *243243+ * This function signals the end of processing for the the specified244244+ * interrupt, which must be the interrupt currently in service. By245245+ * definition, this is also the highest-priority interrupt.246246+ *247247+ * Returns 0 for success, or an error code.248248+ */249249+static inline unsigned int ev_int_eoi(unsigned int interrupt)250250+{251251+ register uintptr_t r11 __asm__("r11");252252+ register uintptr_t r3 __asm__("r3");253253+254254+ r11 = EV_HCALL_TOKEN(EV_INT_EOI);255255+ r3 = interrupt;256256+257257+ asm volatile("bl epapr_hypercall_start"258258+ : "+r" (r11), "+r" (r3)259259+ : : EV_HCALL_CLOBBERS1260260+ );261261+262262+ return r3;263263+}264264+265265+/**266266+ * ev_byte_channel_send - send characters to a byte stream267267+ * @handle: byte stream handle268268+ * @count: (input) num of chars to send, (output) num chars sent269269+ * @buffer: pointer to a 16-byte buffer270270+ *271271+ * @buffer must be at least 16 bytes long, because all 16 bytes will be272272+ * read from memory into registers, even if count < 16.273273+ *274274+ * Returns 0 for success, or an error code.275275+ */276276+static inline unsigned int ev_byte_channel_send(unsigned int handle,277277+ unsigned int *count, const char buffer[EV_BYTE_CHANNEL_MAX_BYTES])278278+{279279+ register uintptr_t r11 __asm__("r11");280280+ register uintptr_t r3 __asm__("r3");281281+ register uintptr_t r4 __asm__("r4");282282+ register uintptr_t r5 __asm__("r5");283283+ register uintptr_t r6 __asm__("r6");284284+ register uintptr_t r7 __asm__("r7");285285+ register uintptr_t r8 __asm__("r8");286286+ const uint32_t *p = (const uint32_t *) buffer;287287+288288+ r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_SEND);289289+ r3 = handle;290290+ r4 = *count;291291+ r5 = be32_to_cpu(p[0]);292292+ r6 = be32_to_cpu(p[1]);293293+ r7 = be32_to_cpu(p[2]);294294+ r8 = be32_to_cpu(p[3]);295295+296296+ asm volatile("bl epapr_hypercall_start"297297+ : "+r" (r11), "+r" (r3),298298+ "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), "+r" (r8)299299+ : : EV_HCALL_CLOBBERS6300300+ );301301+302302+ *count = r4;303303+304304+ return r3;305305+}306306+307307+/**308308+ * ev_byte_channel_receive - fetch characters from a byte channel309309+ * @handle: byte channel handle310310+ * @count: (input) max num of chars to receive, (output) num chars received311311+ * @buffer: pointer to a 16-byte buffer312312+ *313313+ * The size of @buffer must be at least 16 bytes, even if you request fewer314314+ * than 16 characters, because we always write 16 bytes to @buffer. This is315315+ * for performance reasons.316316+ *317317+ * Returns 0 for success, or an error code.318318+ */319319+static inline unsigned int ev_byte_channel_receive(unsigned int handle,320320+ unsigned int *count, char buffer[EV_BYTE_CHANNEL_MAX_BYTES])321321+{322322+ register uintptr_t r11 __asm__("r11");323323+ register uintptr_t r3 __asm__("r3");324324+ register uintptr_t r4 __asm__("r4");325325+ register uintptr_t r5 __asm__("r5");326326+ register uintptr_t r6 __asm__("r6");327327+ register uintptr_t r7 __asm__("r7");328328+ register uintptr_t r8 __asm__("r8");329329+ uint32_t *p = (uint32_t *) buffer;330330+331331+ r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_RECEIVE);332332+ r3 = handle;333333+ r4 = *count;334334+335335+ asm volatile("bl epapr_hypercall_start"336336+ : "+r" (r11), "+r" (r3), "+r" (r4),337337+ "=r" (r5), "=r" (r6), "=r" (r7), "=r" (r8)338338+ : : EV_HCALL_CLOBBERS6339339+ );340340+341341+ *count = r4;342342+ p[0] = cpu_to_be32(r5);343343+ p[1] = cpu_to_be32(r6);344344+ p[2] = cpu_to_be32(r7);345345+ p[3] = cpu_to_be32(r8);346346+347347+ return r3;348348+}349349+350350+/**351351+ * ev_byte_channel_poll - returns the status of the byte channel buffers352352+ * @handle: byte channel handle353353+ * @rx_count: returned count of bytes in receive queue354354+ * @tx_count: returned count of free space in transmit queue355355+ *356356+ * This function reports the amount of data in the receive queue (i.e. the357357+ * number of bytes you can read), and the amount of free space in the transmit358358+ * queue (i.e. the number of bytes you can write).359359+ *360360+ * Returns 0 for success, or an error code.361361+ */362362+static inline unsigned int ev_byte_channel_poll(unsigned int handle,363363+ unsigned int *rx_count, unsigned int *tx_count)364364+{365365+ register uintptr_t r11 __asm__("r11");366366+ register uintptr_t r3 __asm__("r3");367367+ register uintptr_t r4 __asm__("r4");368368+ register uintptr_t r5 __asm__("r5");369369+370370+ r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_POLL);371371+ r3 = handle;372372+373373+ asm volatile("bl epapr_hypercall_start"374374+ : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5)375375+ : : EV_HCALL_CLOBBERS3376376+ );377377+378378+ *rx_count = r4;379379+ *tx_count = r5;380380+381381+ return r3;382382+}383383+384384+/**385385+ * ev_int_iack - acknowledge an interrupt386386+ * @handle: handle to the target interrupt controller387387+ * @vector: returned interrupt vector388388+ *389389+ * If handle is zero, the function returns the next interrupt source390390+ * number to be handled irrespective of the hierarchy or cascading391391+ * of interrupt controllers. If non-zero, specifies a handle to the392392+ * interrupt controller that is the target of the acknowledge.393393+ *394394+ * Returns 0 for success, or an error code.395395+ */396396+static inline unsigned int ev_int_iack(unsigned int handle,397397+ unsigned int *vector)398398+{399399+ register uintptr_t r11 __asm__("r11");400400+ register uintptr_t r3 __asm__("r3");401401+ register uintptr_t r4 __asm__("r4");402402+403403+ r11 = EV_HCALL_TOKEN(EV_INT_IACK);404404+ r3 = handle;405405+406406+ asm volatile("bl epapr_hypercall_start"407407+ : "+r" (r11), "+r" (r3), "=r" (r4)408408+ : : EV_HCALL_CLOBBERS2409409+ );410410+411411+ *vector = r4;412412+413413+ return r3;414414+}415415+416416+/**417417+ * ev_doorbell_send - send a doorbell to another partition418418+ * @handle: doorbell send handle419419+ *420420+ * Returns 0 for success, or an error code.421421+ */422422+static inline unsigned int ev_doorbell_send(unsigned int handle)423423+{424424+ register uintptr_t r11 __asm__("r11");425425+ register uintptr_t r3 __asm__("r3");426426+427427+ r11 = EV_HCALL_TOKEN(EV_DOORBELL_SEND);428428+ r3 = handle;429429+430430+ asm volatile("bl epapr_hypercall_start"431431+ : "+r" (r11), "+r" (r3)432432+ : : EV_HCALL_CLOBBERS1433433+ );434434+435435+ return r3;436436+}437437+438438+/**439439+ * ev_idle -- wait for next interrupt on this core440440+ *441441+ * Returns 0 for success, or an error code.442442+ */443443+static inline unsigned int ev_idle(void)444444+{445445+ register uintptr_t r11 __asm__("r11");446446+ register uintptr_t r3 __asm__("r3");447447+448448+ r11 = EV_HCALL_TOKEN(EV_IDLE);449449+450450+ asm volatile("bl epapr_hypercall_start"451451+ : "+r" (r11), "=r" (r3)452452+ : : EV_HCALL_CLOBBERS1453453+ );454454+455455+ return r3;456456+}457457+#endif /* !__ASSEMBLY__ */458458+#endif /* _EPAPR_HCALLS_H */
+52-412
arch/powerpc/include/uapi/asm/epapr_hcalls.h
···3737 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838 */39394040-/* A "hypercall" is an "sc 1" instruction. This header file file provides C4141- * wrapper functions for the ePAPR hypervisor interface. It is inteded4242- * for use by Linux device drivers and other operating systems.4343- *4444- * The hypercalls are implemented as inline assembly, rather than assembly4545- * language functions in a .S file, for optimization. It allows4646- * the caller to issue the hypercall instruction directly, improving both4747- * performance and memory footprint.4848- */4040+#ifndef _UAPI_ASM_POWERPC_EPAPR_HCALLS_H4141+#define _UAPI_ASM_POWERPC_EPAPR_HCALLS_H49425050-#ifndef _EPAPR_HCALLS_H5151-#define _EPAPR_HCALLS_H4343+#define EV_BYTE_CHANNEL_SEND 14444+#define EV_BYTE_CHANNEL_RECEIVE 24545+#define EV_BYTE_CHANNEL_POLL 34646+#define EV_INT_SET_CONFIG 44747+#define EV_INT_GET_CONFIG 54848+#define EV_INT_SET_MASK 64949+#define EV_INT_GET_MASK 75050+#define EV_INT_IACK 95151+#define EV_INT_EOI 105252+#define EV_INT_SEND_IPI 115353+#define EV_INT_SET_TASK_PRIORITY 125454+#define EV_INT_GET_TASK_PRIORITY 135555+#define EV_DOORBELL_SEND 145656+#define EV_MSGSND 155757+#define EV_IDLE 1652585353-#include <uapi/asm/epapr_hcalls.h>5959+/* vendor ID: epapr */6060+#define EV_LOCAL_VENDOR_ID 0 /* for private use */6161+#define EV_EPAPR_VENDOR_ID 16262+#define EV_FSL_VENDOR_ID 2 /* Freescale Semiconductor */6363+#define EV_IBM_VENDOR_ID 3 /* IBM */6464+#define EV_GHS_VENDOR_ID 4 /* Green Hills Software */6565+#define EV_ENEA_VENDOR_ID 5 /* Enea */6666+#define EV_WR_VENDOR_ID 6 /* Wind River Systems */6767+#define EV_AMCC_VENDOR_ID 7 /* Applied Micro Circuits */6868+#define EV_KVM_VENDOR_ID 42 /* KVM */54695555-#ifndef __ASSEMBLY__5656-#include <linux/types.h>5757-#include <linux/errno.h>5858-#include <asm/byteorder.h>7070+/* The max number of bytes that a byte channel can send or receive per call */7171+#define EV_BYTE_CHANNEL_MAX_BYTES 1659726060-/*6161- * Hypercall register clobber list6262- *6363- * These macros are used to define the list of clobbered registers during a6464- * hypercall. Technically, registers r0 and r3-r12 are always clobbered,6565- * but the gcc inline assembly syntax does not allow us to specify registers6666- * on the clobber list that are also on the input/output list. Therefore,6767- * the lists of clobbered registers depends on the number of register6868- * parmeters ("+r" and "=r") passed to the hypercall.6969- *7070- * Each assembly block should use one of the HCALL_CLOBBERSx macros. As a7171- * general rule, 'x' is the number of parameters passed to the assembly7272- * block *except* for r11.7373- *7474- * If you're not sure, just use the smallest value of 'x' that does not7575- * generate a compilation error. Because these are static inline functions,7676- * the compiler will only check the clobber list for a function if you7777- * compile code that calls that function.7878- *7979- * r3 and r11 are not included in any clobbers list because they are always8080- * listed as output registers.8181- *8282- * XER, CTR, and LR are currently listed as clobbers because it's uncertain8383- * whether they will be clobbered.8484- *8585- * Note that r11 can be used as an output parameter.8686- *8787- * The "memory" clobber is only necessary for hcalls where the Hypervisor8888- * will read or write guest memory. However, we add it to all hcalls because8989- * the impact is minimal, and we want to ensure that it's present for the9090- * hcalls that need it.9191-*/92739393-/* List of common clobbered registers. Do not use this macro. */9494-#define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc", "memory"7474+#define _EV_HCALL_TOKEN(id, num) (((id) << 16) | (num))7575+#define EV_HCALL_TOKEN(hcall_num) _EV_HCALL_TOKEN(EV_EPAPR_VENDOR_ID, hcall_num)95769696-#define EV_HCALL_CLOBBERS8 EV_HCALL_CLOBBERS9797-#define EV_HCALL_CLOBBERS7 EV_HCALL_CLOBBERS8, "r10"9898-#define EV_HCALL_CLOBBERS6 EV_HCALL_CLOBBERS7, "r9"9999-#define EV_HCALL_CLOBBERS5 EV_HCALL_CLOBBERS6, "r8"100100-#define EV_HCALL_CLOBBERS4 EV_HCALL_CLOBBERS5, "r7"101101-#define EV_HCALL_CLOBBERS3 EV_HCALL_CLOBBERS4, "r6"102102-#define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"103103-#define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"7777+/* epapr return codes */7878+#define EV_SUCCESS 07979+#define EV_EPERM 1 /* Operation not permitted */8080+#define EV_ENOENT 2 /* Entry Not Found */8181+#define EV_EIO 3 /* I/O error occured */8282+#define EV_EAGAIN 4 /* The operation had insufficient8383+ * resources to complete and should be8484+ * retried8585+ */8686+#define EV_ENOMEM 5 /* There was insufficient memory to8787+ * complete the operation */8888+#define EV_EFAULT 6 /* Bad guest address */8989+#define EV_ENODEV 7 /* No such device */9090+#define EV_EINVAL 8 /* An argument supplied to the hcall9191+ was out of range or invalid */9292+#define EV_INTERNAL 9 /* An internal error occured */9393+#define EV_CONFIG 10 /* A configuration error was detected */9494+#define EV_INVALID_STATE 11 /* The object is in an invalid state */9595+#define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */9696+#define EV_BUFFER_OVERFLOW 13 /* Caller-supplied buffer too small */10497105105-extern bool epapr_paravirt_enabled;106106-extern u32 epapr_hypercall_start[];107107-108108-/*109109- * We use "uintptr_t" to define a register because it's guaranteed to be a110110- * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit111111- * platform.112112- *113113- * All registers are either input/output or output only. Registers that are114114- * initialized before making the hypercall are input/output. All115115- * input/output registers are represented with "+r". Output-only registers116116- * are represented with "=r". Do not specify any unused registers. The117117- * clobber list will tell the compiler that the hypercall modifies those118118- * registers, which is good enough.119119- */120120-121121-/**122122- * ev_int_set_config - configure the specified interrupt123123- * @interrupt: the interrupt number124124- * @config: configuration for this interrupt125125- * @priority: interrupt priority126126- * @destination: destination CPU number127127- *128128- * Returns 0 for success, or an error code.129129- */130130-static inline unsigned int ev_int_set_config(unsigned int interrupt,131131- uint32_t config, unsigned int priority, uint32_t destination)132132-{133133- register uintptr_t r11 __asm__("r11");134134- register uintptr_t r3 __asm__("r3");135135- register uintptr_t r4 __asm__("r4");136136- register uintptr_t r5 __asm__("r5");137137- register uintptr_t r6 __asm__("r6");138138-139139- r11 = EV_HCALL_TOKEN(EV_INT_SET_CONFIG);140140- r3 = interrupt;141141- r4 = config;142142- r5 = priority;143143- r6 = destination;144144-145145- asm volatile("bl epapr_hypercall_start"146146- : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6)147147- : : EV_HCALL_CLOBBERS4148148- );149149-150150- return r3;151151-}152152-153153-/**154154- * ev_int_get_config - return the config of the specified interrupt155155- * @interrupt: the interrupt number156156- * @config: returned configuration for this interrupt157157- * @priority: returned interrupt priority158158- * @destination: returned destination CPU number159159- *160160- * Returns 0 for success, or an error code.161161- */162162-static inline unsigned int ev_int_get_config(unsigned int interrupt,163163- uint32_t *config, unsigned int *priority, uint32_t *destination)164164-{165165- register uintptr_t r11 __asm__("r11");166166- register uintptr_t r3 __asm__("r3");167167- register uintptr_t r4 __asm__("r4");168168- register uintptr_t r5 __asm__("r5");169169- register uintptr_t r6 __asm__("r6");170170-171171- r11 = EV_HCALL_TOKEN(EV_INT_GET_CONFIG);172172- r3 = interrupt;173173-174174- asm volatile("bl epapr_hypercall_start"175175- : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5), "=r" (r6)176176- : : EV_HCALL_CLOBBERS4177177- );178178-179179- *config = r4;180180- *priority = r5;181181- *destination = r6;182182-183183- return r3;184184-}185185-186186-/**187187- * ev_int_set_mask - sets the mask for the specified interrupt source188188- * @interrupt: the interrupt number189189- * @mask: 0=enable interrupts, 1=disable interrupts190190- *191191- * Returns 0 for success, or an error code.192192- */193193-static inline unsigned int ev_int_set_mask(unsigned int interrupt,194194- unsigned int mask)195195-{196196- register uintptr_t r11 __asm__("r11");197197- register uintptr_t r3 __asm__("r3");198198- register uintptr_t r4 __asm__("r4");199199-200200- r11 = EV_HCALL_TOKEN(EV_INT_SET_MASK);201201- r3 = interrupt;202202- r4 = mask;203203-204204- asm volatile("bl epapr_hypercall_start"205205- : "+r" (r11), "+r" (r3), "+r" (r4)206206- : : EV_HCALL_CLOBBERS2207207- );208208-209209- return r3;210210-}211211-212212-/**213213- * ev_int_get_mask - returns the mask for the specified interrupt source214214- * @interrupt: the interrupt number215215- * @mask: returned mask for this interrupt (0=enabled, 1=disabled)216216- *217217- * Returns 0 for success, or an error code.218218- */219219-static inline unsigned int ev_int_get_mask(unsigned int interrupt,220220- unsigned int *mask)221221-{222222- register uintptr_t r11 __asm__("r11");223223- register uintptr_t r3 __asm__("r3");224224- register uintptr_t r4 __asm__("r4");225225-226226- r11 = EV_HCALL_TOKEN(EV_INT_GET_MASK);227227- r3 = interrupt;228228-229229- asm volatile("bl epapr_hypercall_start"230230- : "+r" (r11), "+r" (r3), "=r" (r4)231231- : : EV_HCALL_CLOBBERS2232232- );233233-234234- *mask = r4;235235-236236- return r3;237237-}238238-239239-/**240240- * ev_int_eoi - signal the end of interrupt processing241241- * @interrupt: the interrupt number242242- *243243- * This function signals the end of processing for the the specified244244- * interrupt, which must be the interrupt currently in service. By245245- * definition, this is also the highest-priority interrupt.246246- *247247- * Returns 0 for success, or an error code.248248- */249249-static inline unsigned int ev_int_eoi(unsigned int interrupt)250250-{251251- register uintptr_t r11 __asm__("r11");252252- register uintptr_t r3 __asm__("r3");253253-254254- r11 = EV_HCALL_TOKEN(EV_INT_EOI);255255- r3 = interrupt;256256-257257- asm volatile("bl epapr_hypercall_start"258258- : "+r" (r11), "+r" (r3)259259- : : EV_HCALL_CLOBBERS1260260- );261261-262262- return r3;263263-}264264-265265-/**266266- * ev_byte_channel_send - send characters to a byte stream267267- * @handle: byte stream handle268268- * @count: (input) num of chars to send, (output) num chars sent269269- * @buffer: pointer to a 16-byte buffer270270- *271271- * @buffer must be at least 16 bytes long, because all 16 bytes will be272272- * read from memory into registers, even if count < 16.273273- *274274- * Returns 0 for success, or an error code.275275- */276276-static inline unsigned int ev_byte_channel_send(unsigned int handle,277277- unsigned int *count, const char buffer[EV_BYTE_CHANNEL_MAX_BYTES])278278-{279279- register uintptr_t r11 __asm__("r11");280280- register uintptr_t r3 __asm__("r3");281281- register uintptr_t r4 __asm__("r4");282282- register uintptr_t r5 __asm__("r5");283283- register uintptr_t r6 __asm__("r6");284284- register uintptr_t r7 __asm__("r7");285285- register uintptr_t r8 __asm__("r8");286286- const uint32_t *p = (const uint32_t *) buffer;287287-288288- r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_SEND);289289- r3 = handle;290290- r4 = *count;291291- r5 = be32_to_cpu(p[0]);292292- r6 = be32_to_cpu(p[1]);293293- r7 = be32_to_cpu(p[2]);294294- r8 = be32_to_cpu(p[3]);295295-296296- asm volatile("bl epapr_hypercall_start"297297- : "+r" (r11), "+r" (r3),298298- "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), "+r" (r8)299299- : : EV_HCALL_CLOBBERS6300300- );301301-302302- *count = r4;303303-304304- return r3;305305-}306306-307307-/**308308- * ev_byte_channel_receive - fetch characters from a byte channel309309- * @handle: byte channel handle310310- * @count: (input) max num of chars to receive, (output) num chars received311311- * @buffer: pointer to a 16-byte buffer312312- *313313- * The size of @buffer must be at least 16 bytes, even if you request fewer314314- * than 16 characters, because we always write 16 bytes to @buffer. This is315315- * for performance reasons.316316- *317317- * Returns 0 for success, or an error code.318318- */319319-static inline unsigned int ev_byte_channel_receive(unsigned int handle,320320- unsigned int *count, char buffer[EV_BYTE_CHANNEL_MAX_BYTES])321321-{322322- register uintptr_t r11 __asm__("r11");323323- register uintptr_t r3 __asm__("r3");324324- register uintptr_t r4 __asm__("r4");325325- register uintptr_t r5 __asm__("r5");326326- register uintptr_t r6 __asm__("r6");327327- register uintptr_t r7 __asm__("r7");328328- register uintptr_t r8 __asm__("r8");329329- uint32_t *p = (uint32_t *) buffer;330330-331331- r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_RECEIVE);332332- r3 = handle;333333- r4 = *count;334334-335335- asm volatile("bl epapr_hypercall_start"336336- : "+r" (r11), "+r" (r3), "+r" (r4),337337- "=r" (r5), "=r" (r6), "=r" (r7), "=r" (r8)338338- : : EV_HCALL_CLOBBERS6339339- );340340-341341- *count = r4;342342- p[0] = cpu_to_be32(r5);343343- p[1] = cpu_to_be32(r6);344344- p[2] = cpu_to_be32(r7);345345- p[3] = cpu_to_be32(r8);346346-347347- return r3;348348-}349349-350350-/**351351- * ev_byte_channel_poll - returns the status of the byte channel buffers352352- * @handle: byte channel handle353353- * @rx_count: returned count of bytes in receive queue354354- * @tx_count: returned count of free space in transmit queue355355- *356356- * This function reports the amount of data in the receive queue (i.e. the357357- * number of bytes you can read), and the amount of free space in the transmit358358- * queue (i.e. the number of bytes you can write).359359- *360360- * Returns 0 for success, or an error code.361361- */362362-static inline unsigned int ev_byte_channel_poll(unsigned int handle,363363- unsigned int *rx_count, unsigned int *tx_count)364364-{365365- register uintptr_t r11 __asm__("r11");366366- register uintptr_t r3 __asm__("r3");367367- register uintptr_t r4 __asm__("r4");368368- register uintptr_t r5 __asm__("r5");369369-370370- r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_POLL);371371- r3 = handle;372372-373373- asm volatile("bl epapr_hypercall_start"374374- : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5)375375- : : EV_HCALL_CLOBBERS3376376- );377377-378378- *rx_count = r4;379379- *tx_count = r5;380380-381381- return r3;382382-}383383-384384-/**385385- * ev_int_iack - acknowledge an interrupt386386- * @handle: handle to the target interrupt controller387387- * @vector: returned interrupt vector388388- *389389- * If handle is zero, the function returns the next interrupt source390390- * number to be handled irrespective of the hierarchy or cascading391391- * of interrupt controllers. If non-zero, specifies a handle to the392392- * interrupt controller that is the target of the acknowledge.393393- *394394- * Returns 0 for success, or an error code.395395- */396396-static inline unsigned int ev_int_iack(unsigned int handle,397397- unsigned int *vector)398398-{399399- register uintptr_t r11 __asm__("r11");400400- register uintptr_t r3 __asm__("r3");401401- register uintptr_t r4 __asm__("r4");402402-403403- r11 = EV_HCALL_TOKEN(EV_INT_IACK);404404- r3 = handle;405405-406406- asm volatile("bl epapr_hypercall_start"407407- : "+r" (r11), "+r" (r3), "=r" (r4)408408- : : EV_HCALL_CLOBBERS2409409- );410410-411411- *vector = r4;412412-413413- return r3;414414-}415415-416416-/**417417- * ev_doorbell_send - send a doorbell to another partition418418- * @handle: doorbell send handle419419- *420420- * Returns 0 for success, or an error code.421421- */422422-static inline unsigned int ev_doorbell_send(unsigned int handle)423423-{424424- register uintptr_t r11 __asm__("r11");425425- register uintptr_t r3 __asm__("r3");426426-427427- r11 = EV_HCALL_TOKEN(EV_DOORBELL_SEND);428428- r3 = handle;429429-430430- asm volatile("bl epapr_hypercall_start"431431- : "+r" (r11), "+r" (r3)432432- : : EV_HCALL_CLOBBERS1433433- );434434-435435- return r3;436436-}437437-438438-/**439439- * ev_idle -- wait for next interrupt on this core440440- *441441- * Returns 0 for success, or an error code.442442- */443443-static inline unsigned int ev_idle(void)444444-{445445- register uintptr_t r11 __asm__("r11");446446- register uintptr_t r3 __asm__("r3");447447-448448- r11 = EV_HCALL_TOKEN(EV_IDLE);449449-450450- asm volatile("bl epapr_hypercall_start"451451- : "+r" (r11), "=r" (r3)452452- : : EV_HCALL_CLOBBERS1453453- );454454-455455- return r3;456456-}457457-#endif /* !__ASSEMBLY__ */458458-#endif9898+#endif /* _UAPI_ASM_POWERPC_EPAPR_HCALLS_H */