2 * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 #include <linux/acpi.h>
29 * Note: Only for GVT-g virtual VBT generation, other usage must
32 #define _INTEL_BIOS_PRIVATE
33 #include "intel_vbt_defs.h"
35 #define OPREGION_SIGNATURE "IntelGraphicsMem"
36 #define MBOX_VBT (1<<3)
39 #define DEVICE_TYPE_CRT 0x01
40 #define DEVICE_TYPE_EFP1 0x04
41 #define DEVICE_TYPE_EFP2 0x40
42 #define DEVICE_TYPE_EFP3 0x20
43 #define DEVICE_TYPE_EFP4 0x10
45 struct opregion_header
{
59 struct bdb_data_header
{
61 u16 size
; /* data size */
64 /* For supporting windows guest with opregion, here hardcode the emulated
65 * bdb header version as '186', and the corresponding child_device_config
66 * length should be '33' but not '38'.
68 struct efp_child_device_config
{
73 u8 dp_onboard_redriver
; /* 158 */
74 u8 dp_ondock_redriver
; /* 158 */
75 u8 hdmi_level_shifter_value
:4; /* 169 */
76 u8 hdmi_max_data_rate
:4; /* 204 */
77 u16 dtd_buf_ptr
; /* 161 */
78 u8 edidless_efp
:1; /* 161 */
79 u8 compression_enable
:1; /* 198 */
80 u8 compression_method
:1; /* 198 */
81 u8 ganged_edp
:1; /* 202 */
83 u8 compression_structure_index
:4; /* 198 */
85 u8 slave_port
; /* 202 */
88 u8 i2c_pin
; /* for add-in card */
89 u8 slave_addr
; /* for add-in card */
93 u8 efp_docked_port
:1; /* 158 */
94 u8 lane_reversal
:1; /* 184 */
95 u8 onboard_lspcon
:1; /* 192 */
96 u8 iboost_enable
:1; /* 196 */
97 u8 hpd_invert
:1; /* BXT 196 */
106 u8 sdvo_stall
:1; /* 158 */
108 u8 integrated_encoder
:1;
111 u8 mipi_bridge_type
; /* 171 */
112 u16 device_class_ext
;
117 /* header->bdb_offset point to bdb_header offset */
118 struct vbt_header header
;
119 struct bdb_header bdb_header
;
121 struct bdb_data_header general_features_header
;
122 struct bdb_general_features general_features
;
124 struct bdb_data_header general_definitions_header
;
125 struct bdb_general_definitions general_definitions
;
127 struct efp_child_device_config child0
;
128 struct efp_child_device_config child1
;
129 struct efp_child_device_config child2
;
130 struct efp_child_device_config child3
;
132 struct bdb_data_header driver_features_header
;
133 struct bdb_driver_features driver_features
;
136 static void virt_vbt_generation(struct vbt
*v
)
140 memset(v
, 0, sizeof(struct vbt
));
142 v
->header
.signature
[0] = '$';
143 v
->header
.signature
[1] = 'V';
144 v
->header
.signature
[2] = 'B';
145 v
->header
.signature
[3] = 'T';
147 /* there's features depending on version! */
148 v
->header
.version
= 155;
149 v
->header
.header_size
= sizeof(v
->header
);
150 v
->header
.vbt_size
= sizeof(struct vbt
) - sizeof(v
->header
);
151 v
->header
.bdb_offset
= offsetof(struct vbt
, bdb_header
);
153 strcpy(&v
->bdb_header
.signature
[0], "BIOS_DATA_BLOCK");
154 v
->bdb_header
.version
= 186; /* child_dev_size = 33 */
155 v
->bdb_header
.header_size
= sizeof(v
->bdb_header
);
157 v
->bdb_header
.bdb_size
= sizeof(struct vbt
) - sizeof(struct vbt_header
)
158 - sizeof(struct bdb_header
);
160 /* general features */
161 v
->general_features_header
.id
= BDB_GENERAL_FEATURES
;
162 v
->general_features_header
.size
= sizeof(struct bdb_general_features
);
163 v
->general_features
.int_crt_support
= 0;
164 v
->general_features
.int_tv_support
= 0;
167 num_child
= 4; /* each port has one child */
168 v
->general_definitions
.child_dev_size
=
169 sizeof(struct efp_child_device_config
);
170 v
->general_definitions_header
.id
= BDB_GENERAL_DEFINITIONS
;
171 /* size will include child devices */
172 v
->general_definitions_header
.size
=
173 sizeof(struct bdb_general_definitions
) +
174 num_child
* v
->general_definitions
.child_dev_size
;
177 v
->child0
.handle
= DEVICE_TYPE_EFP1
;
178 v
->child0
.device_type
= DEVICE_TYPE_DP
;
179 v
->child0
.dvo_port
= DVO_PORT_DPA
;
180 v
->child0
.aux_channel
= DP_AUX_A
;
181 v
->child0
.dp_compat
= true;
182 v
->child0
.integrated_encoder
= true;
185 v
->child1
.handle
= DEVICE_TYPE_EFP2
;
186 v
->child1
.device_type
= DEVICE_TYPE_DP
;
187 v
->child1
.dvo_port
= DVO_PORT_DPB
;
188 v
->child1
.aux_channel
= DP_AUX_B
;
189 v
->child1
.dp_compat
= true;
190 v
->child1
.integrated_encoder
= true;
193 v
->child2
.handle
= DEVICE_TYPE_EFP3
;
194 v
->child2
.device_type
= DEVICE_TYPE_DP
;
195 v
->child2
.dvo_port
= DVO_PORT_DPC
;
196 v
->child2
.aux_channel
= DP_AUX_C
;
197 v
->child2
.dp_compat
= true;
198 v
->child2
.integrated_encoder
= true;
201 v
->child3
.handle
= DEVICE_TYPE_EFP4
;
202 v
->child3
.device_type
= DEVICE_TYPE_DP
;
203 v
->child3
.dvo_port
= DVO_PORT_DPD
;
204 v
->child3
.aux_channel
= DP_AUX_D
;
205 v
->child3
.dp_compat
= true;
206 v
->child3
.integrated_encoder
= true;
208 /* driver features */
209 v
->driver_features_header
.id
= BDB_DRIVER_FEATURES
;
210 v
->driver_features_header
.size
= sizeof(struct bdb_driver_features
);
211 v
->driver_features
.lvds_config
= BDB_DRIVER_FEATURE_NO_LVDS
;
215 * intel_vgpu_init_opregion - initialize the stuff used to emulate opregion
217 * @gpa: guest physical address of opregion
220 * Zero on success, negative error code if failed.
222 int intel_vgpu_init_opregion(struct intel_vgpu
*vgpu
)
225 struct opregion_header
*header
;
227 const char opregion_signature
[16] = OPREGION_SIGNATURE
;
229 gvt_dbg_core("init vgpu%d opregion\n", vgpu
->id
);
230 vgpu_opregion(vgpu
)->va
= (void *)__get_free_pages(GFP_KERNEL
|
232 get_order(INTEL_GVT_OPREGION_SIZE
));
233 if (!vgpu_opregion(vgpu
)->va
) {
234 gvt_err("fail to get memory for vgpu virt opregion\n");
238 /* emulated opregion with VBT mailbox only */
239 buf
= (u8
*)vgpu_opregion(vgpu
)->va
;
240 header
= (struct opregion_header
*)buf
;
241 memcpy(header
->signature
, opregion_signature
,
242 sizeof(opregion_signature
));
244 header
->opregion_ver
= 0x02000000;
245 header
->mboxes
= MBOX_VBT
;
247 /* for unknown reason, the value in LID field is incorrect
248 * which block the windows guest, so workaround it by force
249 * setting it to "OPEN"
251 buf
[INTEL_GVT_OPREGION_CLID
] = 0x3;
253 /* emulated vbt from virt vbt generation */
254 virt_vbt_generation(&v
);
255 memcpy(buf
+ INTEL_GVT_OPREGION_VBT_OFFSET
, &v
, sizeof(struct vbt
));
260 static int map_vgpu_opregion(struct intel_vgpu
*vgpu
, bool map
)
265 for (i
= 0; i
< INTEL_GVT_OPREGION_PAGES
; i
++) {
266 mfn
= intel_gvt_hypervisor_virt_to_mfn(vgpu_opregion(vgpu
)->va
268 if (mfn
== INTEL_GVT_INVALID_ADDR
) {
269 gvt_vgpu_err("fail to get MFN from VA\n");
272 ret
= intel_gvt_hypervisor_map_gfn_to_mfn(vgpu
,
273 vgpu_opregion(vgpu
)->gfn
[i
],
276 gvt_vgpu_err("fail to map GFN to MFN, errno: %d\n",
282 vgpu_opregion(vgpu
)->mapped
= map
;
288 * intel_vgpu_opregion_base_write_handler - Opregion base register write handler
291 * @gpa: guest physical address of opregion
294 * Zero on success, negative error code if failed.
296 int intel_vgpu_opregion_base_write_handler(struct intel_vgpu
*vgpu
, u32 gpa
)
301 gvt_dbg_core("emulate opregion from kernel\n");
303 switch (intel_gvt_host
.hypervisor_type
) {
304 case INTEL_GVT_HYPERVISOR_KVM
:
305 for (i
= 0; i
< INTEL_GVT_OPREGION_PAGES
; i
++)
306 vgpu_opregion(vgpu
)->gfn
[i
] = (gpa
>> PAGE_SHIFT
) + i
;
308 case INTEL_GVT_HYPERVISOR_XEN
:
310 * Wins guest on Xengt will write this register twice: xen
311 * hvmloader and windows graphic driver.
313 if (vgpu_opregion(vgpu
)->mapped
)
314 map_vgpu_opregion(vgpu
, false);
316 for (i
= 0; i
< INTEL_GVT_OPREGION_PAGES
; i
++)
317 vgpu_opregion(vgpu
)->gfn
[i
] = (gpa
>> PAGE_SHIFT
) + i
;
319 ret
= map_vgpu_opregion(vgpu
, true);
323 gvt_vgpu_err("not supported hypervisor\n");
330 * intel_vgpu_clean_opregion - clean the stuff used to emulate opregion
334 void intel_vgpu_clean_opregion(struct intel_vgpu
*vgpu
)
336 gvt_dbg_core("vgpu%d: clean vgpu opregion\n", vgpu
->id
);
338 if (!vgpu_opregion(vgpu
)->va
)
341 if (intel_gvt_host
.hypervisor_type
== INTEL_GVT_HYPERVISOR_XEN
) {
342 if (vgpu_opregion(vgpu
)->mapped
)
343 map_vgpu_opregion(vgpu
, false);
344 } else if (intel_gvt_host
.hypervisor_type
== INTEL_GVT_HYPERVISOR_KVM
) {
345 /* Guest opregion is released by VFIO */
347 free_pages((unsigned long)vgpu_opregion(vgpu
)->va
,
348 get_order(INTEL_GVT_OPREGION_SIZE
));
350 vgpu_opregion(vgpu
)->va
= NULL
;
355 #define GVT_OPREGION_FUNC(scic) \
358 __ret = (scic & OPREGION_SCIC_FUNC_MASK) >> \
359 OPREGION_SCIC_FUNC_SHIFT; \
363 #define GVT_OPREGION_SUBFUNC(scic) \
366 __ret = (scic & OPREGION_SCIC_SUBFUNC_MASK) >> \
367 OPREGION_SCIC_SUBFUNC_SHIFT; \
371 static const char *opregion_func_name(u32 func
)
373 const char *name
= NULL
;
383 name
= "Get BIOS Data";
387 name
= "System BIOS Callbacks";
397 static const char *opregion_subfunc_name(u32 subfunc
)
399 const char *name
= NULL
;
403 name
= "Supported Calls";
407 name
= "Requested Callbacks";
416 name
= "Boot Display";
420 name
= "TV-Standard/Video-Connector";
424 name
= "Internal Graphics";
428 name
= "Spread Spectrum Clocks";
442 static bool querying_capabilities(u32 scic
)
446 func
= GVT_OPREGION_FUNC(scic
);
447 subfunc
= GVT_OPREGION_SUBFUNC(scic
);
449 if ((func
== INTEL_GVT_OPREGION_SCIC_F_GETBIOSDATA
&&
450 subfunc
== INTEL_GVT_OPREGION_SCIC_SF_SUPPRTEDCALLS
)
451 || (func
== INTEL_GVT_OPREGION_SCIC_F_GETBIOSDATA
&&
452 subfunc
== INTEL_GVT_OPREGION_SCIC_SF_REQEUSTEDCALLBACKS
)
453 || (func
== INTEL_GVT_OPREGION_SCIC_F_GETBIOSCALLBACKS
&&
454 subfunc
== INTEL_GVT_OPREGION_SCIC_SF_SUPPRTEDCALLS
)) {
461 * intel_vgpu_emulate_opregion_request - emulating OpRegion request
463 * @swsci: SWSCI request
466 * Zero on success, negative error code if failed
468 int intel_vgpu_emulate_opregion_request(struct intel_vgpu
*vgpu
, u32 swsci
)
472 u64 scic_pa
= 0, parm_pa
= 0;
475 switch (intel_gvt_host
.hypervisor_type
) {
476 case INTEL_GVT_HYPERVISOR_XEN
:
477 scic
= *((u32
*)vgpu_opregion(vgpu
)->va
+
478 INTEL_GVT_OPREGION_SCIC
);
479 parm
= *((u32
*)vgpu_opregion(vgpu
)->va
+
480 INTEL_GVT_OPREGION_PARM
);
482 case INTEL_GVT_HYPERVISOR_KVM
:
483 scic_pa
= (vgpu_opregion(vgpu
)->gfn
[0] << PAGE_SHIFT
) +
484 INTEL_GVT_OPREGION_SCIC
;
485 parm_pa
= (vgpu_opregion(vgpu
)->gfn
[0] << PAGE_SHIFT
) +
486 INTEL_GVT_OPREGION_PARM
;
488 ret
= intel_gvt_hypervisor_read_gpa(vgpu
, scic_pa
,
489 &scic
, sizeof(scic
));
491 gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
492 ret
, scic_pa
, sizeof(scic
));
496 ret
= intel_gvt_hypervisor_read_gpa(vgpu
, parm_pa
,
497 &parm
, sizeof(parm
));
499 gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
500 ret
, scic_pa
, sizeof(scic
));
506 gvt_vgpu_err("not supported hypervisor\n");
510 if (!(swsci
& SWSCI_SCI_SELECT
)) {
511 gvt_vgpu_err("requesting SMI service\n");
514 /* ignore non 0->1 trasitions */
515 if ((vgpu_cfg_space(vgpu
)[INTEL_GVT_PCI_SWSCI
]
516 & SWSCI_SCI_TRIGGER
) ||
517 !(swsci
& SWSCI_SCI_TRIGGER
)) {
521 func
= GVT_OPREGION_FUNC(scic
);
522 subfunc
= GVT_OPREGION_SUBFUNC(scic
);
523 if (!querying_capabilities(scic
)) {
524 gvt_vgpu_err("requesting runtime service: func \"%s\","
526 opregion_func_name(func
),
527 opregion_subfunc_name(subfunc
));
529 * emulate exit status of function call, '0' means
530 * "failure, generic, unsupported or unknown cause"
532 scic
&= ~OPREGION_SCIC_EXIT_MASK
;
540 switch (intel_gvt_host
.hypervisor_type
) {
541 case INTEL_GVT_HYPERVISOR_XEN
:
542 *((u32
*)vgpu_opregion(vgpu
)->va
+
543 INTEL_GVT_OPREGION_SCIC
) = scic
;
544 *((u32
*)vgpu_opregion(vgpu
)->va
+
545 INTEL_GVT_OPREGION_PARM
) = parm
;
547 case INTEL_GVT_HYPERVISOR_KVM
:
548 ret
= intel_gvt_hypervisor_write_gpa(vgpu
, scic_pa
,
549 &scic
, sizeof(scic
));
551 gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
552 ret
, scic_pa
, sizeof(scic
));
556 ret
= intel_gvt_hypervisor_write_gpa(vgpu
, parm_pa
,
557 &parm
, sizeof(parm
));
559 gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
560 ret
, scic_pa
, sizeof(scic
));
566 gvt_vgpu_err("not supported hypervisor\n");