VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/DevEFI.h@ 95294

Last change on this file since 95294 was 94465, checked in by vboxsync, 3 years ago

Devices/EFI: Fix possible triple fault with SMP configurations during reset

During initialization UEFI enumerates the available CPUs by issuing an IPI to all APs
and waiting a fixed amount of time (50ms by default) for all APs to serve the request.
The timeout is far too low for a hypervisor due to host scheduling interference resulting in the
timed wait to expire before the APs could startup. The BSP will then free the wakeup buffer which
the APs use to startup (switching from real mode to the final execution mode) and overwrite it with 0.
This causes the APs to execute garbage when the respective EMTs get finally scheduled causing all sorts
of weird behavior.

Because it is impossible to set a sane upper timeout without causing execessive delay this change
makes the plartform code query the maximum and current number of CPUs present for the guest so
it can exactly wait for the amount of available CPUs without using any fixed timeouts.

(I'm still puzzled why this only happens when the VM is reset and not during startup...)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1/* $Id: DevEFI.h 94465 2022-04-05 11:43:09Z vboxsync $ */
2/** @file
3 * EFI for VirtualBox Common Definitions.
4 *
5 * WARNING: This header is used by both firmware and VBox device,
6 * thus don't put anything here but numeric constants or helper
7 * inline functions.
8 */
9
10/*
11 * Copyright (C) 2009-2022 Oracle Corporation
12 *
13 * This file is part of VirtualBox Open Source Edition (OSE), as
14 * available from http://www.virtualbox.org. This file is free software;
15 * you can redistribute it and/or modify it under the terms of the GNU
16 * General Public License (GPL) as published by the Free Software
17 * Foundation, in version 2 as it comes in the "COPYING" file of the
18 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20 *
21 * The contents of this file may alternatively be used under the terms
22 * of the Common Development and Distribution License Version 1.0
23 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
24 * VirtualBox OSE distribution, in which case the provisions of the
25 * CDDL are applicable instead of those of the GPL.
26 *
27 * You may elect to license modified versions of this file under the
28 * terms and conditions of either the GPL or the CDDL or both.
29 */
30
31#ifndef VBOX_INCLUDED_SRC_EFI_DevEFI_h
32#define VBOX_INCLUDED_SRC_EFI_DevEFI_h
33#ifndef RT_WITHOUT_PRAGMA_ONCE
34# pragma once
35#endif
36
37/** @defgroup grp_devefi DevEFI <-> Firmware Interfaces
38 * @{
39 */
40
41/** The base of the I/O ports used for interaction between the EFI firmware and DevEFI. */
42#define EFI_PORT_BASE 0xEF10 /**< @todo r=klaus stupid choice which causes trouble with PCI resource allocation in complex bridge setups, change to 0x0400 with appropriate saved state and reset handling */
43/** The number of ports. */
44#define EFI_PORT_COUNT 0x0008
45
46
47/** Information querying.
48 * 32-bit write sets the info index and resets the reading, see EfiInfoIndex.
49 * 32-bit read returns the size of the info (in bytes).
50 * 8-bit reads returns the info as a byte sequence. */
51#define EFI_INFO_PORT (EFI_PORT_BASE+0x0)
52/**
53 * Information requests.
54 */
55typedef enum
56{
57 EFI_INFO_INDEX_INVALID = 0,
58 EFI_INFO_INDEX_VOLUME_BASE,
59 EFI_INFO_INDEX_VOLUME_SIZE,
60 EFI_INFO_INDEX_TEMPMEM_BASE,
61 EFI_INFO_INDEX_TEMPMEM_SIZE,
62 EFI_INFO_INDEX_STACK_BASE,
63 EFI_INFO_INDEX_STACK_SIZE,
64 EFI_INFO_INDEX_BOOT_ARGS,
65 EFI_INFO_INDEX_DEVICE_PROPS,
66 EFI_INFO_INDEX_FSB_FREQUENCY,
67 EFI_INFO_INDEX_CPU_FREQUENCY,
68 EFI_INFO_INDEX_TSC_FREQUENCY,
69 EFI_INFO_INDEX_GRAPHICS_MODE,
70 EFI_INFO_INDEX_HORIZONTAL_RESOLUTION,
71 EFI_INFO_INDEX_VERTICAL_RESOLUTION,
72 EFI_INFO_INDEX_MCFG_BASE,
73 EFI_INFO_INDEX_MCFG_SIZE,
74 EFI_INFO_INDEX_APIC_MODE,
75 EFI_INFO_INDEX_CPU_COUNT_CURRENT,
76 EFI_INFO_INDEX_CPU_COUNT_MAX,
77 EFI_INFO_INDEX_END
78} EfiInfoIndex;
79
80/** @name APIC mode defines as returned by EFI_INFO_INDEX_APIC_MODE
81 * @{ */
82#define EFI_APIC_MODE_DISABLED 0
83#define EFI_APIC_MODE_APIC 1
84#define EFI_APIC_MODE_X2APIC 2
85/** @} */
86
87/** Panic port.
88 * Write causes action to be taken according to the value written,
89 * see the EFI_PANIC_CMD_* defines below.
90 * Reading from the port has no effect. */
91#define EFI_PANIC_PORT (EFI_PORT_BASE+0x1)
92
93/** @defgroup grp_devefi_panic_cmd Panic Commands for EFI_PANIC_PORT
94 * @{ */
95/** Used by the EfiThunk.asm to signal ORG inconsistency. */
96#define EFI_PANIC_CMD_BAD_ORG 1
97/** Used by the EfiThunk.asm to signal unexpected trap or interrupt. */
98#define EFI_PANIC_CMD_THUNK_TRAP 2
99/** Starts a panic message.
100 * Makes sure the panic message buffer is empty. */
101#define EFI_PANIC_CMD_START_MSG 3
102/** Ends a panic message and enters guru meditation state. */
103#define EFI_PANIC_CMD_END_MSG 4
104/** The first panic message command.
105 * The low byte of the command is the char to be added to the panic message. */
106#define EFI_PANIC_CMD_MSG_FIRST 0x4201
107/** The last panic message command. */
108#define EFI_PANIC_CMD_MSG_LAST 0x427f
109/** Makes a panic message command from a char. */
110#define EFI_PANIC_CMD_MSG_FROM_CHAR(ch) (0x4200 | ((ch) & 0x7f) )
111/** Extracts the char from a panic message command. */
112#define EFI_PANIC_CMD_MSG_GET_CHAR(u32) ((u32) & 0x7f)
113/** @} */
114
115/** Undefined port. */
116#define EFI_PORT_UNDEFINED (EFI_PORT_BASE+0x2)
117
118/** Debug logging.
119 * The chars written goes to the log.
120 * Reading has no effect.
121 * @remarks The port number is the same as on of those used by the PC BIOS. */
122#define EFI_DEBUG_PORT (EFI_PORT_BASE+0x3)
123
124#define VBOX_EFI_DEBUG_BUFFER 512
125/** The top of the EFI stack.
126 * The firmware expects a 128KB stack.
127 * @todo Move this to 1MB + 128KB and drop the stack relocation the firmware
128 * does. It expects the stack to be within the temporary memory that
129 * SEC hands to PEI and the VBoxAutoScan PEIM reports. */
130#define VBOX_EFI_TOP_OF_STACK 0x300000
131
132#define EFI_PORT_VARIABLE_OP (EFI_PORT_BASE+0x4)
133#define EFI_PORT_VARIABLE_PARAM (EFI_PORT_BASE+0x5)
134
135#define EFI_VARIABLE_OP_QUERY 0xdead0001
136#define EFI_VARIABLE_OP_QUERY_NEXT 0xdead0002
137#define EFI_VARIABLE_OP_QUERY_REWIND 0xdead0003
138#define EFI_VARIABLE_OP_ADD 0xdead0010
139
140#define EFI_VARIABLE_OP_STATUS_OK 0xcafe0000
141#define EFI_VARIABLE_OP_STATUS_ERROR 0xcafe0001
142#define EFI_VARIABLE_OP_STATUS_NOT_FOUND 0xcafe0002
143#define EFI_VARIABLE_OP_STATUS_WP 0xcafe0003
144#define EFI_VARIABLE_OP_STATUS_BSY 0xcafe0010
145
146/** The max number of variables allowed. */
147#define EFI_VARIABLE_MAX 128
148/** The max variable name length (in bytes, including the zero terminator). */
149#define EFI_VARIABLE_NAME_MAX 1024
150/** The max value length (in bytes). */
151#define EFI_VARIABLE_VALUE_MAX 1024
152
153typedef enum
154{
155 EFI_VM_VARIABLE_OP_START = 0,
156 EFI_VM_VARIABLE_OP_RESERVED_USED_TO_BE_END,
157 EFI_VM_VARIABLE_OP_RESERVED_USED_TO_BE_INDEX,
158 EFI_VM_VARIABLE_OP_GUID,
159 EFI_VM_VARIABLE_OP_ATTRIBUTE,
160 EFI_VM_VARIABLE_OP_NAME,
161 EFI_VM_VARIABLE_OP_NAME_LENGTH,
162 EFI_VM_VARIABLE_OP_VALUE,
163 EFI_VM_VARIABLE_OP_VALUE_LENGTH,
164 EFI_VM_VARIABLE_OP_ERROR,
165 EFI_VM_VARIABLE_OP_NAME_UTF16,
166 EFI_VM_VARIABLE_OP_NAME_LENGTH_UTF16,
167 EFI_VM_VARIABLE_OP_MAX,
168 EFI_VM_VARIABLE_OP_32BIT_HACK = 0x7fffffff
169} EFIVAROP;
170
171
172/** Debug point. */
173#define EFI_PORT_DEBUG_POINT (EFI_PORT_BASE + 0x6)
174
175/**
176 * EFI debug points.
177 */
178typedef enum EFIDBGPOINT
179{
180 /** Invalid. */
181 EFIDBGPOINT_INVALID = 0,
182 /** DEBUG_AGENT_INIT_PREMEM_SEC. */
183 EFIDBGPOINT_SEC_PREMEM = 1,
184 /** DEBUG_AGENT_INIT_POST_SEC. */
185 EFIDBGPOINT_SEC_POSTMEM,
186 /** DEBUG_AGENT_INIT_DXE_CORE. */
187 EFIDBGPOINT_DXE_CORE,
188 /** DEBUG_AGENT_INIT_. */
189 EFIDBGPOINT_SMM,
190 /** DEBUG_AGENT_INIT_ENTER_SMI. */
191 EFIDBGPOINT_SMI_ENTER,
192 /** DEBUG_AGENT_INIT_EXIT_SMI. */
193 EFIDBGPOINT_SMI_EXIT,
194 /** DEBUG_AGENT_INIT_S3. */
195 EFIDBGPOINT_GRAPHICS,
196 /** DEBUG_AGENT_INIT_DXE_AP. */
197 EFIDBGPOINT_DXE_AP,
198 /** End of valid points. */
199 EFIDBGPOINT_END,
200 /** Blow up the type to 32-bits. */
201 EFIDBGPOINT_32BIT_HACK = 0x7fffffff
202} EFIDBGPOINT;
203
204
205/** EFI image load or unload event. All writes are 32-bit writes. */
206#define EFI_PORT_IMAGE_EVENT (EFI_PORT_BASE + 0x7)
207
208/** @defgroup grp_devefi_image_evt EFI Image Events (EFI_PORT_IMAGE_EVENT).
209 *
210 * The lower 8-bit of the values written to EFI_PORT_IMAGE_EVENT can be seen as
211 * the command. The start and complete commands does not have any additional
212 * payload. The other commands uses bit 8 thru 23 or 8 thru 15 to pass a value.
213 *
214 * @{ */
215
216/** The command mask. */
217#define EFI_IMAGE_EVT_CMD_MASK UINT32_C(0x000000ff)
218/** Get the payload value. */
219#define EFI_IMAGE_EVT_GET_PAYLOAD(a_u32) ((a_u32) >> 8)
220/** Get the payload value as unsigned 16-bit. */
221#define EFI_IMAGE_EVT_GET_PAYLOAD_U16(a_u32) ( EFI_IMAGE_EVT_GET_PAYLOAD(a_u32) & UINT16_MAX )
222/** Get the payload value as unsigned 8-bit. */
223#define EFI_IMAGE_EVT_GET_PAYLOAD_U8(a_u32) ( EFI_IMAGE_EVT_GET_PAYLOAD(a_u32) & UINT8_MAX )
224/** Combines a command and a payload value. */
225#define EFI_IMAGE_EVT_MAKE(a_uCmd, a_uPayload) ( ((a_uCmd) & UINT32_C(0xff)) | (uint32_t)((a_uPayload) << 8) )
226
227/** Invalid. */
228#define EFI_IMAGE_EVT_CMD_INVALID UINT32_C(0x00000000)
229/** The event is complete. */
230#define EFI_IMAGE_EVT_CMD_COMPLETE UINT32_C(0x00000001)
231/** Starts a 32-bit load event. Requires name and address, size is optional. */
232#define EFI_IMAGE_EVT_CMD_START_LOAD32 UINT32_C(0x00000002)
233/** Starts a 64-bit load event. Requires name and address, size is optional. */
234#define EFI_IMAGE_EVT_CMD_START_LOAD64 UINT32_C(0x00000003)
235/** Starts a 32-bit unload event. Requires name and address. */
236#define EFI_IMAGE_EVT_CMD_START_UNLOAD32 UINT32_C(0x00000004)
237/** Starts a 64-bit unload event. Requires name and address. */
238#define EFI_IMAGE_EVT_CMD_START_UNLOAD64 UINT32_C(0x00000005)
239/** Starts a 32-bit relocation event. RRequires new and old base address. */
240#define EFI_IMAGE_EVT_CMD_START_RELOC32 UINT32_C(0x0000000A)
241/** Starts a 64-bit relocation event. Requires new and old base address. */
242#define EFI_IMAGE_EVT_CMD_START_RELOC64 UINT32_C(0x0000000B)
243
244/** The command for writing to the second address register (64-bit).
245 * Takes a 16-bit payload value. The register value is shifted 16-bits
246 * to the left and then the payload is ORed in. */
247#define EFI_IMAGE_EVT_CMD_ADDR0 UINT32_C(0x00000006)
248/** The command for writing to the second address register (64-bit).
249 * Takes a 16-bit payload value. The register value is shifted 16-bits
250 * to the left and then the payload is ORed in. */
251#define EFI_IMAGE_EVT_CMD_ADDR1 UINT32_C(0x00000007)
252/** The command for writing to the first size register (64-bit).
253 * Takes a 16-bit payload value. The register value is shifted 16-bits
254 * to the left and then the payload is ORed in. */
255#define EFI_IMAGE_EVT_CMD_SIZE0 UINT32_C(0x00000008)
256/** The command for appending a character to the module name.
257 * Takes a 7-bit payload value that. The value is appended to the field if
258 * there is room. */
259#define EFI_IMAGE_EVT_CMD_NAME UINT32_C(0x00000009)
260
261/** @} */
262
263
264/** @} */
265
266#endif /* !VBOX_INCLUDED_SRC_EFI_DevEFI_h */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette