GNU Linux-libre 4.9.332-gnu1
[releases.git] / drivers / staging / unisys / visorbus / vmcallinterface.h
1 /* Copyright (C) 2010 - 2015 UNISYS CORPORATION
2  * All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11  * NON INFRINGEMENT.  See the GNU General Public License for more
12  * details.
13  */
14
15 #ifndef __IOMONINTF_H__
16 #define __IOMONINTF_H__
17
18 /*
19 * This file contains all structures needed to support the VMCALLs for IO
20 * Virtualization.  The VMCALLs are provided by Monitor and used by IO code
21 * running on IO Partitions.
22 */
23 static inline unsigned long
24 __unisys_vmcall_gnuc(unsigned long tuple, unsigned long reg_ebx,
25                      unsigned long reg_ecx)
26 {
27         unsigned long result = 0;
28         unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
29
30         cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
31         if (!(cpuid_ecx & 0x80000000))
32                 return -EPERM;
33
34         __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
35                 "a"(tuple), "b"(reg_ebx), "c"(reg_ecx));
36         return result;
37 }
38
39 static inline unsigned long
40 __unisys_extended_vmcall_gnuc(unsigned long long tuple,
41                               unsigned long long reg_ebx,
42                               unsigned long long reg_ecx,
43                               unsigned long long reg_edx)
44 {
45         unsigned long result = 0;
46         unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
47
48         cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
49         if (!(cpuid_ecx & 0x80000000))
50                 return -EPERM;
51
52         __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
53                 "a"(tuple), "b"(reg_ebx), "c"(reg_ecx), "d"(reg_edx));
54         return result;
55 }
56
57 #ifdef VMCALL_IO_CONTROLVM_ADDR
58 #undef VMCALL_IO_CONTROLVM_ADDR
59 #endif  /*  */
60
61 /* define subsystem number for AppOS, used in uislib driver  */
62 #define MDS_APPOS 0x4000000000000000L   /* subsystem = 62 - AppOS */
63 enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples  */
64             /* Note: when a new VMCALL is added:
65              * - the 1st 2 hex digits correspond to one of the
66              *   VMCALL_MONITOR_INTERFACE types and
67              * - the next 2 hex digits are the nth relative instance of within a
68              *   type
69              * E.G. for VMCALL_VIRTPART_RECYCLE_PART,
70              * - the 0x02 identifies it as a VMCALL_VIRTPART type and
71              * - the 0x01 identifies it as the 1st instance of a VMCALL_VIRTPART
72              *   type of VMCALL
73              */
74         /* used by all Guests, not just IO */
75         VMCALL_IO_CONTROLVM_ADDR = 0x0501,
76         /* Allow caller to query virtual time offset */
77         VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET = 0x0708,
78         /* LOGEVENT Post Code (RDX) with specified subsystem mask */
79         /* (RCX - monitor_subsystems.h) and severity (RDX) */
80         VMCALL_POST_CODE_LOGEVENT = 0x070B,
81         /* Allow ULTRA_SERVICE_CAPABILITY_TIME capable guest to make VMCALL */
82         VMCALL_UPDATE_PHYSICAL_TIME = 0x0a02
83 };
84
85 #define VMCALL_SUCCESS 0
86 #define VMCALL_SUCCESSFUL(result)       (result == 0)
87
88 #define unisys_vmcall(tuple, reg_ebx, reg_ecx) \
89         __unisys_vmcall_gnuc(tuple, reg_ebx, reg_ecx)
90 #define unisys_extended_vmcall(tuple, reg_ebx, reg_ecx, reg_edx) \
91         __unisys_extended_vmcall_gnuc(tuple, reg_ebx, reg_ecx, reg_edx)
92 #define ISSUE_IO_VMCALL(method, param, result) \
93         (result = unisys_vmcall(method, (param) & 0xFFFFFFFF,   \
94                                 (param) >> 32))
95 #define ISSUE_IO_EXTENDED_VMCALL(method, param1, param2, param3) \
96         unisys_extended_vmcall(method, param1, param2, param3)
97
98     /* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently
99      * not used much
100      */
101 #define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity)           \
102         ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity,   \
103                                  MDS_APPOS, postcode)
104
105 /* Structures for IO VMCALLs */
106
107 /* Parameters to VMCALL_IO_CONTROLVM_ADDR interface */
108 struct vmcall_io_controlvm_addr_params {
109         /* The Guest-relative physical address of the ControlVm channel. */
110         /* This VMCall fills this in with the appropriate address. */
111         u64 address;    /* contents provided by this VMCALL (OUT) */
112         /* the size of the ControlVm channel in bytes This VMCall fills this */
113         /* in with the appropriate address. */
114         u32 channel_bytes;      /* contents provided by this VMCALL (OUT) */
115         u8 unused[4];           /* Unused Bytes in the 64-Bit Aligned Struct */
116 } __packed;
117
118 /******* INFO ON ISSUE_POSTCODE_LINUX() BELOW *******/
119 enum driver_pc {                /* POSTCODE driver identifier tuples */
120         /* visorchipset driver files */
121         VISOR_CHIPSET_PC = 0xA0,
122         VISOR_CHIPSET_PC_controlvm_c = 0xA1,
123         VISOR_CHIPSET_PC_controlvm_cm2 = 0xA2,
124         VISOR_CHIPSET_PC_controlvm_direct_c = 0xA3,
125         VISOR_CHIPSET_PC_file_c = 0xA4,
126         VISOR_CHIPSET_PC_parser_c = 0xA5,
127         VISOR_CHIPSET_PC_testing_c = 0xA6,
128         VISOR_CHIPSET_PC_visorchipset_main_c = 0xA7,
129         VISOR_CHIPSET_PC_visorswitchbus_c = 0xA8,
130         /* visorbus driver files */
131         VISOR_BUS_PC = 0xB0,
132         VISOR_BUS_PC_businst_attr_c = 0xB1,
133         VISOR_BUS_PC_channel_attr_c = 0xB2,
134         VISOR_BUS_PC_devmajorminor_attr_c = 0xB3,
135         VISOR_BUS_PC_visorbus_main_c = 0xB4,
136         /* visorclientbus driver files */
137         VISOR_CLIENT_BUS_PC = 0xC0,
138         VISOR_CLIENT_BUS_PC_visorclientbus_main_c = 0xC1,
139         /* virt hba driver files */
140         VIRT_HBA_PC = 0xC2,
141         VIRT_HBA_PC_virthba_c = 0xC3,
142         /* virtpci driver files */
143         VIRT_PCI_PC = 0xC4,
144         VIRT_PCI_PC_virtpci_c = 0xC5,
145         /* virtnic driver files */
146         VIRT_NIC_PC = 0xC6,
147         VIRT_NIC_P_virtnic_c = 0xC7,
148         /* uislib driver files */
149         UISLIB_PC = 0xD0,
150         UISLIB_PC_uislib_c = 0xD1,
151         UISLIB_PC_uisqueue_c = 0xD2,
152         /* 0xD3 RESERVED */
153         UISLIB_PC_uisutils_c = 0xD4,
154 };
155
156 enum event_pc {                 /* POSTCODE event identifier tuples */
157         ATTACH_PORT_ENTRY_PC = 0x001,
158         ATTACH_PORT_FAILURE_PC = 0x002,
159         ATTACH_PORT_SUCCESS_PC = 0x003,
160         BUS_FAILURE_PC = 0x004,
161         BUS_CREATE_ENTRY_PC = 0x005,
162         BUS_CREATE_FAILURE_PC = 0x006,
163         BUS_CREATE_EXIT_PC = 0x007,
164         BUS_CONFIGURE_ENTRY_PC = 0x008,
165         BUS_CONFIGURE_FAILURE_PC = 0x009,
166         BUS_CONFIGURE_EXIT_PC = 0x00A,
167         CHIPSET_INIT_ENTRY_PC = 0x00B,
168         CHIPSET_INIT_SUCCESS_PC = 0x00C,
169         CHIPSET_INIT_FAILURE_PC = 0x00D,
170         CHIPSET_INIT_EXIT_PC = 0x00E,
171         CREATE_WORKQUEUE_PC = 0x00F,
172         CREATE_WORKQUEUE_FAILED_PC = 0x0A0,
173         CONTROLVM_INIT_FAILURE_PC = 0x0A1,
174         DEVICE_CREATE_ENTRY_PC = 0x0A2,
175         DEVICE_CREATE_FAILURE_PC = 0x0A3,
176         DEVICE_CREATE_SUCCESS_PC = 0x0A4,
177         DEVICE_CREATE_EXIT_PC = 0x0A5,
178         DEVICE_ADD_PC = 0x0A6,
179         DEVICE_REGISTER_FAILURE_PC = 0x0A7,
180         DEVICE_CHANGESTATE_ENTRY_PC = 0x0A8,
181         DEVICE_CHANGESTATE_FAILURE_PC = 0x0A9,
182         DEVICE_CHANGESTATE_EXIT_PC = 0x0AA,
183         DRIVER_ENTRY_PC = 0x0AB,
184         DRIVER_EXIT_PC = 0x0AC,
185         MALLOC_FAILURE_PC = 0x0AD,
186         QUEUE_DELAYED_WORK_PC = 0x0AE,
187         /* 0x0B7 RESERVED */
188         VBUS_CHANNEL_ENTRY_PC = 0x0B8,
189         VBUS_CHANNEL_FAILURE_PC = 0x0B9,
190         VBUS_CHANNEL_EXIT_PC = 0x0BA,
191         VHBA_CREATE_ENTRY_PC = 0x0BB,
192         VHBA_CREATE_FAILURE_PC = 0x0BC,
193         VHBA_CREATE_EXIT_PC = 0x0BD,
194         VHBA_CREATE_SUCCESS_PC = 0x0BE,
195         VHBA_COMMAND_HANDLER_PC = 0x0BF,
196         VHBA_PROBE_ENTRY_PC = 0x0C0,
197         VHBA_PROBE_FAILURE_PC = 0x0C1,
198         VHBA_PROBE_EXIT_PC = 0x0C2,
199         VNIC_CREATE_ENTRY_PC = 0x0C3,
200         VNIC_CREATE_FAILURE_PC = 0x0C4,
201         VNIC_CREATE_SUCCESS_PC = 0x0C5,
202         VNIC_PROBE_ENTRY_PC = 0x0C6,
203         VNIC_PROBE_FAILURE_PC = 0x0C7,
204         VNIC_PROBE_EXIT_PC = 0x0C8,
205         VPCI_CREATE_ENTRY_PC = 0x0C9,
206         VPCI_CREATE_FAILURE_PC = 0x0CA,
207         VPCI_CREATE_EXIT_PC = 0x0CB,
208         VPCI_PROBE_ENTRY_PC = 0x0CC,
209         VPCI_PROBE_FAILURE_PC = 0x0CD,
210         VPCI_PROBE_EXIT_PC = 0x0CE,
211         CRASH_DEV_ENTRY_PC = 0x0CF,
212         CRASH_DEV_EXIT_PC = 0x0D0,
213         CRASH_DEV_HADDR_NULL = 0x0D1,
214         CRASH_DEV_CONTROLVM_NULL = 0x0D2,
215         CRASH_DEV_RD_BUS_FAIULRE_PC = 0x0D3,
216         CRASH_DEV_RD_DEV_FAIULRE_PC = 0x0D4,
217         CRASH_DEV_BUS_NULL_FAILURE_PC = 0x0D5,
218         CRASH_DEV_DEV_NULL_FAILURE_PC = 0x0D6,
219         CRASH_DEV_CTRL_RD_FAILURE_PC = 0x0D7,
220         CRASH_DEV_COUNT_FAILURE_PC = 0x0D8,
221         SAVE_MSG_BUS_FAILURE_PC = 0x0D9,
222         SAVE_MSG_DEV_FAILURE_PC = 0x0DA,
223         CALLHOME_INIT_FAILURE_PC = 0x0DB
224 };
225
226 #define POSTCODE_SEVERITY_ERR DIAG_SEVERITY_ERR
227 #define POSTCODE_SEVERITY_WARNING DIAG_SEVERITY_WARNING
228 /* TODO-> Info currently doesn't show, so we set info=warning */
229 #define POSTCODE_SEVERITY_INFO DIAG_SEVERITY_PRINT
230
231 /* example call of POSTCODE_LINUX_2(VISOR_CHIPSET_PC, POSTCODE_SEVERITY_ERR);
232  * Please also note that the resulting postcode is in hex, so if you are
233  * searching for the __LINE__ number, convert it first to decimal.  The line
234  * number combined with driver and type of call, will allow you to track down
235  * exactly what line an error occurred on, or where the last driver
236  * entered/exited from.
237  */
238
239 /* BASE FUNCTIONS */
240 #define POSTCODE_LINUX_A(DRIVER_PC, EVENT_PC, pc32bit, severity)        \
241 do {                                                                    \
242         unsigned long long post_code_temp;                              \
243         post_code_temp = (((u64)DRIVER_PC) << 56) | (((u64)EVENT_PC) << 44) | \
244                 ((((u64)__LINE__) & 0xFFF) << 32) |                     \
245                 (((u64)pc32bit) & 0xFFFFFFFF);                          \
246         ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity);    \
247 } while (0)
248
249 #define POSTCODE_LINUX_B(DRIVER_PC, EVENT_PC, pc16bit1, pc16bit2, severity) \
250 do {                                                                    \
251         unsigned long long post_code_temp;                              \
252         post_code_temp = (((u64)DRIVER_PC) << 56) | (((u64)EVENT_PC) << 44) | \
253                 ((((u64)__LINE__) & 0xFFF) << 32) |                     \
254                 ((((u64)pc16bit1) & 0xFFFF) << 16) |                    \
255                 (((u64)pc16bit2) & 0xFFFF);                             \
256         ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity);    \
257 } while (0)
258
259 /* MOST COMMON */
260 #define POSTCODE_LINUX_2(EVENT_PC, severity)                            \
261         POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, 0x0000, severity)
262
263 #define POSTCODE_LINUX_3(EVENT_PC, pc32bit, severity)                   \
264         POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, pc32bit, severity)
265
266 #define POSTCODE_LINUX_4(EVENT_PC, pc16bit1, pc16bit2, severity)        \
267         POSTCODE_LINUX_B(CURRENT_FILE_PC, EVENT_PC, pc16bit1,           \
268                          pc16bit2, severity)
269
270 #endif /* __IOMONINTF_H__ */