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 "display/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
219 * Zero on success, negative error code if failed.
221 int intel_vgpu_init_opregion(struct intel_vgpu
*vgpu
)
224 struct opregion_header
*header
;
226 const char opregion_signature
[16] = OPREGION_SIGNATURE
;
228 gvt_dbg_core("init vgpu%d opregion\n", vgpu
->id
);
229 vgpu_opregion(vgpu
)->va
= (void *)__get_free_pages(GFP_KERNEL
|
231 get_order(INTEL_GVT_OPREGION_SIZE
));
232 if (!vgpu_opregion(vgpu
)->va
) {
233 gvt_err("fail to get memory for vgpu virt opregion\n");
237 /* emulated opregion with VBT mailbox only */
238 buf
= (u8
*)vgpu_opregion(vgpu
)->va
;
239 header
= (struct opregion_header
*)buf
;
240 memcpy(header
->signature
, opregion_signature
,
241 sizeof(opregion_signature
));
243 header
->opregion_ver
= 0x02000000;
244 header
->mboxes
= MBOX_VBT
;
246 /* for unknown reason, the value in LID field is incorrect
247 * which block the windows guest, so workaround it by force
248 * setting it to "OPEN"
250 buf
[INTEL_GVT_OPREGION_CLID
] = 0x3;
252 /* emulated vbt from virt vbt generation */
253 virt_vbt_generation(&v
);
254 memcpy(buf
+ INTEL_GVT_OPREGION_VBT_OFFSET
, &v
, sizeof(struct vbt
));
259 static int map_vgpu_opregion(struct intel_vgpu
*vgpu
, bool map
)
264 for (i
= 0; i
< INTEL_GVT_OPREGION_PAGES
; i
++) {
265 mfn
= intel_gvt_hypervisor_virt_to_mfn(vgpu_opregion(vgpu
)->va
267 if (mfn
== INTEL_GVT_INVALID_ADDR
) {
268 gvt_vgpu_err("fail to get MFN from VA\n");
271 ret
= intel_gvt_hypervisor_map_gfn_to_mfn(vgpu
,
272 vgpu_opregion(vgpu
)->gfn
[i
],
275 gvt_vgpu_err("fail to map GFN to MFN, errno: %d\n",
281 vgpu_opregion(vgpu
)->mapped
= map
;
287 * intel_vgpu_opregion_base_write_handler - Opregion base register write handler
290 * @gpa: guest physical address of opregion
293 * Zero on success, negative error code if failed.
295 int intel_vgpu_opregion_base_write_handler(struct intel_vgpu
*vgpu
, u32 gpa
)
300 gvt_dbg_core("emulate opregion from kernel\n");
302 switch (intel_gvt_host
.hypervisor_type
) {
303 case INTEL_GVT_HYPERVISOR_KVM
:
304 for (i
= 0; i
< INTEL_GVT_OPREGION_PAGES
; i
++)
305 vgpu_opregion(vgpu
)->gfn
[i
] = (gpa
>> PAGE_SHIFT
) + i
;
307 case INTEL_GVT_HYPERVISOR_XEN
:
309 * Wins guest on Xengt will write this register twice: xen
310 * hvmloader and windows graphic driver.
312 if (vgpu_opregion(vgpu
)->mapped
)
313 map_vgpu_opregion(vgpu
, false);
315 for (i
= 0; i
< INTEL_GVT_OPREGION_PAGES
; i
++)
316 vgpu_opregion(vgpu
)->gfn
[i
] = (gpa
>> PAGE_SHIFT
) + i
;
318 ret
= map_vgpu_opregion(vgpu
, true);
322 gvt_vgpu_err("not supported hypervisor\n");
329 * intel_vgpu_clean_opregion - clean the stuff used to emulate opregion
333 void intel_vgpu_clean_opregion(struct intel_vgpu
*vgpu
)
335 gvt_dbg_core("vgpu%d: clean vgpu opregion\n", vgpu
->id
);
337 if (!vgpu_opregion(vgpu
)->va
)
340 if (intel_gvt_host
.hypervisor_type
== INTEL_GVT_HYPERVISOR_XEN
) {
341 if (vgpu_opregion(vgpu
)->mapped
)
342 map_vgpu_opregion(vgpu
, false);
343 } else if (intel_gvt_host
.hypervisor_type
== INTEL_GVT_HYPERVISOR_KVM
) {
344 /* Guest opregion is released by VFIO */
346 free_pages((unsigned long)vgpu_opregion(vgpu
)->va
,
347 get_order(INTEL_GVT_OPREGION_SIZE
));
349 vgpu_opregion(vgpu
)->va
= NULL
;
354 #define GVT_OPREGION_FUNC(scic) \
357 __ret = (scic & OPREGION_SCIC_FUNC_MASK) >> \
358 OPREGION_SCIC_FUNC_SHIFT; \
362 #define GVT_OPREGION_SUBFUNC(scic) \
365 __ret = (scic & OPREGION_SCIC_SUBFUNC_MASK) >> \
366 OPREGION_SCIC_SUBFUNC_SHIFT; \
370 static const char *opregion_func_name(u32 func
)
372 const char *name
= NULL
;
382 name
= "Get BIOS Data";
386 name
= "System BIOS Callbacks";
396 static const char *opregion_subfunc_name(u32 subfunc
)
398 const char *name
= NULL
;
402 name
= "Supported Calls";
406 name
= "Requested Callbacks";
415 name
= "Boot Display";
419 name
= "TV-Standard/Video-Connector";
423 name
= "Internal Graphics";
427 name
= "Spread Spectrum Clocks";
441 static bool querying_capabilities(u32 scic
)
445 func
= GVT_OPREGION_FUNC(scic
);
446 subfunc
= GVT_OPREGION_SUBFUNC(scic
);
448 if ((func
== INTEL_GVT_OPREGION_SCIC_F_GETBIOSDATA
&&
449 subfunc
== INTEL_GVT_OPREGION_SCIC_SF_SUPPRTEDCALLS
)
450 || (func
== INTEL_GVT_OPREGION_SCIC_F_GETBIOSDATA
&&
451 subfunc
== INTEL_GVT_OPREGION_SCIC_SF_REQEUSTEDCALLBACKS
)
452 || (func
== INTEL_GVT_OPREGION_SCIC_F_GETBIOSCALLBACKS
&&
453 subfunc
== INTEL_GVT_OPREGION_SCIC_SF_SUPPRTEDCALLS
)) {
460 * intel_vgpu_emulate_opregion_request - emulating OpRegion request
462 * @swsci: SWSCI request
465 * Zero on success, negative error code if failed
467 int intel_vgpu_emulate_opregion_request(struct intel_vgpu
*vgpu
, u32 swsci
)
471 u64 scic_pa
= 0, parm_pa
= 0;
474 switch (intel_gvt_host
.hypervisor_type
) {
475 case INTEL_GVT_HYPERVISOR_XEN
:
476 scic
= *((u32
*)vgpu_opregion(vgpu
)->va
+
477 INTEL_GVT_OPREGION_SCIC
);
478 parm
= *((u32
*)vgpu_opregion(vgpu
)->va
+
479 INTEL_GVT_OPREGION_PARM
);
481 case INTEL_GVT_HYPERVISOR_KVM
:
482 scic_pa
= (vgpu_opregion(vgpu
)->gfn
[0] << PAGE_SHIFT
) +
483 INTEL_GVT_OPREGION_SCIC
;
484 parm_pa
= (vgpu_opregion(vgpu
)->gfn
[0] << PAGE_SHIFT
) +
485 INTEL_GVT_OPREGION_PARM
;
487 ret
= intel_gvt_hypervisor_read_gpa(vgpu
, scic_pa
,
488 &scic
, sizeof(scic
));
490 gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
491 ret
, scic_pa
, sizeof(scic
));
495 ret
= intel_gvt_hypervisor_read_gpa(vgpu
, parm_pa
,
496 &parm
, sizeof(parm
));
498 gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
499 ret
, scic_pa
, sizeof(scic
));
505 gvt_vgpu_err("not supported hypervisor\n");
509 if (!(swsci
& SWSCI_SCI_SELECT
)) {
510 gvt_vgpu_err("requesting SMI service\n");
513 /* ignore non 0->1 trasitions */
514 if ((vgpu_cfg_space(vgpu
)[INTEL_GVT_PCI_SWSCI
]
515 & SWSCI_SCI_TRIGGER
) ||
516 !(swsci
& SWSCI_SCI_TRIGGER
)) {
520 func
= GVT_OPREGION_FUNC(scic
);
521 subfunc
= GVT_OPREGION_SUBFUNC(scic
);
522 if (!querying_capabilities(scic
)) {
523 gvt_vgpu_err("requesting runtime service: func \"%s\","
525 opregion_func_name(func
),
526 opregion_subfunc_name(subfunc
));
528 * emulate exit status of function call, '0' means
529 * "failure, generic, unsupported or unknown cause"
531 scic
&= ~OPREGION_SCIC_EXIT_MASK
;
539 switch (intel_gvt_host
.hypervisor_type
) {
540 case INTEL_GVT_HYPERVISOR_XEN
:
541 *((u32
*)vgpu_opregion(vgpu
)->va
+
542 INTEL_GVT_OPREGION_SCIC
) = scic
;
543 *((u32
*)vgpu_opregion(vgpu
)->va
+
544 INTEL_GVT_OPREGION_PARM
) = parm
;
546 case INTEL_GVT_HYPERVISOR_KVM
:
547 ret
= intel_gvt_hypervisor_write_gpa(vgpu
, scic_pa
,
548 &scic
, sizeof(scic
));
550 gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
551 ret
, scic_pa
, sizeof(scic
));
555 ret
= intel_gvt_hypervisor_write_gpa(vgpu
, parm_pa
,
556 &parm
, sizeof(parm
));
558 gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
559 ret
, scic_pa
, sizeof(scic
));
565 gvt_vgpu_err("not supported hypervisor\n");