Benjamin Romer | 6f14cc1 | 2015-07-16 12:40:48 -0400 | [diff] [blame] | 1 | /* Copyright (C) 2010 - 2015 UNISYS CORPORATION |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 2 | * All rights reserved. |
| 3 | * |
Benjamin Romer | 6f14cc1 | 2015-07-16 12:40:48 -0400 | [diff] [blame] | 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. |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 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 | */ |
David Kershner | 77190cf | 2016-09-02 16:41:40 -0400 | [diff] [blame] | 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; |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 29 | |
David Kershner | 77190cf | 2016-09-02 16:41:40 -0400 | [diff] [blame] | 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 | } |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 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 */ |
Ken Cox | a8d7f21 | 2014-03-13 15:39:19 -0500 | [diff] [blame] | 62 | #define MDS_APPOS 0x4000000000000000L /* subsystem = 62 - AppOS */ |
Benjamin Romer | 753541c | 2014-10-23 14:29:44 -0400 | [diff] [blame] | 63 | enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 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 | */ |
Erik Arfvidson | 195b578 | 2015-11-17 13:34:56 -0500 | [diff] [blame] | 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 |
Benjamin Romer | 753541c | 2014-10-23 14:29:44 -0400 | [diff] [blame] | 83 | }; |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 84 | |
| 85 | #define VMCALL_SUCCESS 0 |
| 86 | #define VMCALL_SUCCESSFUL(result) (result == 0) |
| 87 | |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 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) |
Benjamin Romer | d835a90 | 2014-10-23 14:29:45 -0400 | [diff] [blame] | 92 | #define ISSUE_IO_VMCALL(method, param, result) \ |
| 93 | (result = unisys_vmcall(method, (param) & 0xFFFFFFFF, \ |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 94 | (param) >> 32)) |
Sudip Mukherjee | 2e81513 | 2015-02-10 17:09:43 +0530 | [diff] [blame] | 95 | #define ISSUE_IO_EXTENDED_VMCALL(method, param1, param2, param3) \ |
| 96 | unisys_extended_vmcall(method, param1, param2, param3) |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 97 | |
| 98 | /* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently |
Erik Arfvidson | 195b578 | 2015-11-17 13:34:56 -0500 | [diff] [blame] | 99 | * not used much |
| 100 | */ |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 101 | #define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity) \ |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 102 | ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity, \ |
David Kershner | 512a67b | 2015-05-13 13:22:02 -0400 | [diff] [blame] | 103 | MDS_APPOS, postcode) |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 104 | |
| 105 | /* Structures for IO VMCALLs */ |
| 106 | |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 107 | /* Parameters to VMCALL_IO_CONTROLVM_ADDR interface */ |
Benjamin Romer | f42aea3 | 2014-10-03 14:09:13 -0400 | [diff] [blame] | 108 | struct vmcall_io_controlvm_addr_params { |
Erik Arfvidson | 195b578 | 2015-11-17 13:34:56 -0500 | [diff] [blame] | 109 | /* The Guest-relative physical address of the ControlVm channel. */ |
| 110 | /* This VMCall fills this in with the appropriate address. */ |
Benjamin Romer | f42aea3 | 2014-10-03 14:09:13 -0400 | [diff] [blame] | 111 | u64 address; /* contents provided by this VMCALL (OUT) */ |
Erik Arfvidson | 195b578 | 2015-11-17 13:34:56 -0500 | [diff] [blame] | 112 | /* the size of the ControlVm channel in bytes This VMCall fills this */ |
| 113 | /* in with the appropriate address. */ |
Benjamin Romer | f42aea3 | 2014-10-03 14:09:13 -0400 | [diff] [blame] | 114 | u32 channel_bytes; /* contents provided by this VMCALL (OUT) */ |
| 115 | u8 unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */ |
David Kershner | c3248fe | 2015-10-13 11:37:23 -0400 | [diff] [blame] | 116 | } __packed; |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 117 | |
David Kershner | 4f3f0c3 | 2016-09-02 16:41:44 -0400 | [diff] [blame] | 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 | |
Ken Cox | 12e364b | 2014-03-04 07:58:07 -0600 | [diff] [blame] | 270 | #endif /* __IOMONINTF_H__ */ |