Commit | Line | Data |
---|---|---|
6f14cc18 | 1 | /* Copyright (C) 2010 - 2015 UNISYS CORPORATION |
12e364b9 KC |
2 | * All rights reserved. |
3 | * | |
6f14cc18 BR |
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. | |
12e364b9 KC |
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 | */ | |
77190cfc DK |
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; | |
12e364b9 | 29 | |
77190cfc DK |
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 | } | |
12e364b9 KC |
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 */ | |
a8d7f21d | 62 | #define MDS_APPOS 0x4000000000000000L /* subsystem = 62 - AppOS */ |
753541cc | 63 | enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ |
12e364b9 KC |
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 | */ | |
195b5787 EA |
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 | |
753541cc | 83 | }; |
12e364b9 KC |
84 | |
85 | #define VMCALL_SUCCESS 0 | |
86 | #define VMCALL_SUCCESSFUL(result) (result == 0) | |
87 | ||
12e364b9 KC |
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) | |
d835a90c BR |
92 | #define ISSUE_IO_VMCALL(method, param, result) \ |
93 | (result = unisys_vmcall(method, (param) & 0xFFFFFFFF, \ | |
12e364b9 | 94 | (param) >> 32)) |
2e81513b SM |
95 | #define ISSUE_IO_EXTENDED_VMCALL(method, param1, param2, param3) \ |
96 | unisys_extended_vmcall(method, param1, param2, param3) | |
12e364b9 KC |
97 | |
98 | /* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently | |
195b5787 EA |
99 | * not used much |
100 | */ | |
12e364b9 | 101 | #define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity) \ |
12e364b9 | 102 | ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity, \ |
512a67bc | 103 | MDS_APPOS, postcode) |
12e364b9 KC |
104 | |
105 | /* Structures for IO VMCALLs */ | |
106 | ||
12e364b9 | 107 | /* Parameters to VMCALL_IO_CONTROLVM_ADDR interface */ |
f42aea3c | 108 | struct vmcall_io_controlvm_addr_params { |
195b5787 EA |
109 | /* The Guest-relative physical address of the ControlVm channel. */ |
110 | /* This VMCall fills this in with the appropriate address. */ | |
f42aea3c | 111 | u64 address; /* contents provided by this VMCALL (OUT) */ |
195b5787 EA |
112 | /* the size of the ControlVm channel in bytes This VMCall fills this */ |
113 | /* in with the appropriate address. */ | |
f42aea3c BR |
114 | u32 channel_bytes; /* contents provided by this VMCALL (OUT) */ |
115 | u8 unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */ | |
c3248fef | 116 | } __packed; |
12e364b9 | 117 | |
4f3f0c3d DK |
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 | ||
12e364b9 | 270 | #endif /* __IOMONINTF_H__ */ |