VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/VBoxAppleSim/VBoxAppleSim.c@ 80934

Last change on this file since 80934 was 80934, checked in by vboxsync, 5 years ago

EFI/Firmware: Some compi8les fixes when gcc is used (preparation to make the gcc build working again)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.5 KB
Line 
1/* $Id: VBoxAppleSim.c 80934 2019-09-22 15:37:49Z vboxsync $ */
2/** @file
3 * VBoxAppleSim.c - VirtualBox Apple Firmware simulation support
4 */
5
6/*
7 * Copyright (C) 2010-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <Library/BaseMemoryLib.h>
32#include <Library/DebugLib.h>
33#include <Library/UefiBootServicesTableLib.h>
34#include <Library/UefiLib.h>
35#include <Library/PrintLib.h>
36
37#include <Protocol/DevicePathToText.h>
38
39#include <IndustryStandard/Acpi10.h>
40#include <IndustryStandard/Acpi20.h>
41#include <IndustryStandard/SmBios.h>
42
43#include <Guid/SmBios.h>
44#include <Guid/Acpi.h>
45#include <Guid/Mps.h>
46
47#include "DataHub.h"
48#include "VBoxPkg.h"
49#include "DevEFI.h"
50#include "iprt/asm.h"
51
52
53/*
54 * External functions
55 */
56EFI_STATUS EFIAPI
57CpuUpdateDataHub(EFI_BOOT_SERVICES * bs,
58 UINT64 FSBFrequency,
59 UINT64 TSCFrequency,
60 UINT64 CPUFrequency);
61
62EFI_STATUS EFIAPI
63InitializeConsoleSim (IN EFI_HANDLE ImageHandle,
64 IN EFI_SYSTEM_TABLE *SystemTable);
65
66
67/*
68 * Internal Functions
69 */
70static UINT32
71GetVmVariable(UINT32 Variable, CHAR8 *pbBuf, UINT32 cbBuf)
72{
73 UINT32 cbVar, offBuf;
74
75 ASMOutU32(EFI_INFO_PORT, Variable);
76 cbVar = ASMInU32(EFI_INFO_PORT);
77
78 for (offBuf = 0; offBuf < cbVar && offBuf < cbBuf; offBuf++)
79 pbBuf[offBuf] = ASMInU8(EFI_INFO_PORT);
80
81 return cbVar;
82}
83
84/*
85 * GUIDs
86 */
87/** The EFI variable GUID for the 'FirmwareFeatures' and friends.
88 * Also known as AppleFirmwareVariableGuid in other sources. */
89EFI_GUID gEfiAppleNvramGuid = {
90 0x4D1EDE05, 0x38C7, 0x4A6A, {0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x8C, 0x14 }
91};
92
93/** The EFI variable GUID for the 'boot-args' variable and others.
94 * Also known as AppleNVRAMVariableGuid in other sources. */
95EFI_GUID gEfiAppleBootGuid = {
96 0x7C436110, 0xAB2A, 0x4BBB, {0xA8, 0x80, 0xFE, 0x41, 0x99, 0x5C, 0x9F, 0x82}
97};
98
99
100/*
101 * Device Properoty protocol implementation hack.
102 */
103
104/** gEfiAppleVarGuid is aka AppleDevicePropertyProtocolGuid in other sources. */
105EFI_GUID gEfiAppleVarGuid = {
106 0x91BD12FE, 0xF6C3, 0x44FB, {0xA5, 0xB7, 0x51, 0x22, 0xAB, 0x30, 0x3A, 0xE0}
107};
108
109/** APPLE_GETVAR_PROTOCOL is aka APPLE_DEVICE_PROPERTY_PROTOCOL in other sources. */
110typedef struct _APPLE_GETVAR_PROTOCOL APPLE_GETVAR_PROTOCOL;
111
112struct _APPLE_GETVAR_PROTOCOL
113{
114 /** Magic value or some version thingy. boot.efi doesn't check this, I think. */
115 UINT64 u64Magic;
116
117 EFI_STATUS (EFIAPI *pfnUnknown0)(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2,
118 IN VOID *pvArg3, IN VOID *pvArg4);
119 EFI_STATUS (EFIAPI *pfnUnknown1)(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2,
120 IN VOID *pvArg3, IN VOID *pvArg4);
121 EFI_STATUS (EFIAPI *pfnUnknown2)(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2);
122
123 EFI_STATUS (EFIAPI *pfnGetDevProps)(IN APPLE_GETVAR_PROTOCOL *This, IN CHAR8 *pbBuf, IN OUT UINT32 *pcbBuf);
124};
125/** The value of APPLE_GETVAR_PROTOCOL::u64Magic. */
126#define APPLE_GETVAR_PROTOCOL_MAGIC 0x10000
127
128EFI_STATUS EFIAPI
129AppleGetVar_Unknown0(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2,
130 IN VOID *pvArg3, IN VOID *pvArg4)
131{
132 CHAR8 szMsg[128];
133 AsciiSPrint(szMsg, sizeof(szMsg), "AppleGetVar_Unknown0: pvArg1=%p pvArg2=%p pvArg3=%p pvArg4=%p",
134 pvArg1, pvArg2, pvArg3, pvArg4);
135 DebugAssert(__FILE__, __LINE__, szMsg);
136 return EFI_UNSUPPORTED;
137}
138
139EFI_STATUS EFIAPI
140AppleGetVar_Unknown1(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2,
141 IN VOID *pvArg3, IN VOID *pvArg4)
142{
143 CHAR8 szMsg[128];
144 AsciiSPrint(szMsg, sizeof(szMsg), "AppleGetVar_Unknown1: pvArg1=%p pvArg2=%p pvArg3=%p pvArg4=%p",
145 pvArg1, pvArg2, pvArg3, pvArg4);
146 DebugAssert(__FILE__, __LINE__, szMsg);
147 return EFI_UNSUPPORTED;
148}
149
150EFI_STATUS EFIAPI
151AppleGetVar_Unknown2(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2)
152{
153 CHAR8 szMsg[80];
154 AsciiSPrint(szMsg, sizeof(szMsg), "AppleGetVar_Unknown2: pvArg1=%p pvArg2=%p", pvArg1, pvArg2);
155 DebugAssert(__FILE__, __LINE__, szMsg);
156 return EFI_UNSUPPORTED;
157}
158
159
160/**
161 * This method obtains the 'device-properties' that get exposed by
162 * AppleEFIFirmware and parsed by AppleACPIPlatform.
163 *
164 * Check out the data in the IORegisteryExplorer, the device-properties property
165 * under IODeviceTree:/efi.
166 *
167 * @retval EFI_SUCCESS, check *pcbBuf or the number of bytes actually returned.
168 * @retval EFI_BUFFER_TOO_SMALL, check *pcbBuf for the necessary buffer size.
169 * @param pThis Not used.
170 * @param pbBuf The output buffer.
171 * @param pcbBuf On input, the varible pointed to contains the size of the
172 * buffer. The size is generally 4KB from what we've observed.
173 * On output, it contains the amount of data available, this
174 * is always set.
175 */
176EFI_STATUS EFIAPI
177AppleGetVar_GetDeviceProps(IN APPLE_GETVAR_PROTOCOL *pThis, OUT CHAR8 *pbBuf, IN OUT UINT32 *pcbBuf)
178{
179 UINT32 cbBuf = *pcbBuf;
180 UINT32 cbActual;
181
182 cbActual = GetVmVariable(EFI_INFO_INDEX_DEVICE_PROPS, pbBuf, cbBuf);
183 *pcbBuf = cbActual;
184
185 if (cbActual > cbBuf)
186 return EFI_BUFFER_TOO_SMALL;
187
188 return EFI_SUCCESS;
189}
190
191APPLE_GETVAR_PROTOCOL gPrivateVarHandler =
192{
193 /* Magic = */ APPLE_GETVAR_PROTOCOL_MAGIC,
194 AppleGetVar_Unknown0,
195 AppleGetVar_Unknown1,
196 AppleGetVar_Unknown2,
197 AppleGetVar_GetDeviceProps
198};
199
200
201/*
202 * Unknown Protocol #1.
203 */
204
205/** This seems to be related to graphics/display... */
206EFI_GUID gEfiUnknown1ProtocolGuid =
207{
208 0xDD8E06AC, 0x00E2, 0x49A9, {0x88, 0x8F, 0xFA, 0x46, 0xDE, 0xD4, 0x0A, 0x52}
209};
210
211EFI_STATUS EFIAPI
212UnknownHandlerImpl()
213{
214#ifdef DEBUG
215 ASSERT(0);
216#endif
217 Print(L"Unknown called\n");
218 return EFI_SUCCESS;
219}
220
221/* array of pointers to function */
222EFI_STATUS (EFIAPI *gUnknownProtoHandler[])() =
223{
224 UnknownHandlerImpl,
225 UnknownHandlerImpl,
226 UnknownHandlerImpl,
227 UnknownHandlerImpl,
228 UnknownHandlerImpl,
229 UnknownHandlerImpl,
230 UnknownHandlerImpl,
231 UnknownHandlerImpl,
232 UnknownHandlerImpl,
233 UnknownHandlerImpl,
234 UnknownHandlerImpl,
235 UnknownHandlerImpl,
236 UnknownHandlerImpl,
237 UnknownHandlerImpl,
238 UnknownHandlerImpl,
239 UnknownHandlerImpl,
240 UnknownHandlerImpl,
241 UnknownHandlerImpl
242};
243
244EFI_STATUS EFIAPI
245SetProperVariables(IN EFI_HANDLE ImageHandle, EFI_RUNTIME_SERVICES * rs)
246{
247 EFI_STATUS rc;
248 UINT32 vBackgroundClear = 0x00000000;
249 UINT32 vFwFeatures = 0x80000015;
250 UINT32 vFwFeaturesMask = 0x800003ff;
251
252 // -legacy acpi=0xffffffff acpi_debug=0xfffffff panic_io_port=0xef11 io=0xfffffffe trace=4096 io=0xffffffef -v serial=2 serialbaud=9600
253 // 0x10 makes kdb default, thus 0x15e for kdb, 0x14e for gdb
254 // usb=0x800 is required to work around default behavior of the Apple xHCI driver which rejects high-speed
255 // USB devices and tries to force them to EHCI when running on the Intel Panther Point chipset.
256
257 //static const CHAR8 vBootArgs[] = "debug=0x15e keepsyms=1 acpi=0xffffffff acpi_debug=0xff acpi_level=7 -v -x32 -s"; // or just "debug=0x8 -legacy"
258 // 0x14e for serial output
259 //static const CHAR8 vDefBootArgs[] = "debug=0x146 usb=0x800 keepsyms=1 -v -serial=0x1";
260 static const CHAR8 vDefBootArgs[] = "usb=0x800 keepsyms=1 -v -serial=0x1";
261 CHAR8 vBootArgs[256];
262 UINT32 BootArgsLen;
263
264 BootArgsLen = GetVmVariable(EFI_INFO_INDEX_BOOT_ARGS, vBootArgs, sizeof vBootArgs);
265 if (BootArgsLen <= 1)
266 {
267 BootArgsLen = sizeof vDefBootArgs;
268 CopyMem(vBootArgs, vDefBootArgs, BootArgsLen);
269 }
270 rc = rs->SetVariable(L"BackgroundClear",
271 &gEfiAppleNvramGuid,
272 /* EFI_VARIABLE_NON_VOLATILE | */ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
273 sizeof(vBackgroundClear), &vBackgroundClear);
274 ASSERT_EFI_ERROR (rc);
275
276 rc = rs->SetVariable(L"FirmwareFeatures",
277 &gEfiAppleNvramGuid,
278 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
279 sizeof(vFwFeatures), &vFwFeatures);
280 ASSERT_EFI_ERROR (rc);
281
282 rc = rs->SetVariable(L"FirmwareFeaturesMask",
283 &gEfiAppleNvramGuid,
284 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
285 sizeof(vFwFeaturesMask), &vFwFeaturesMask);
286 ASSERT_EFI_ERROR (rc);
287
288 rc = rs->SetVariable(L"boot-args",
289 &gEfiAppleBootGuid,
290 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
291 BootArgsLen, &vBootArgs);
292 ASSERT_EFI_ERROR (rc);
293
294 return EFI_SUCCESS;
295}
296
297/**
298 * VBoxInitAppleSim entry point.
299 *
300 * @returns EFI status code.
301 *
302 * @param ImageHandle The image handle.
303 * @param SystemTable The system table pointer.
304 */
305EFI_STATUS EFIAPI
306VBoxInitAppleSim(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
307{
308 EFI_STATUS rc;
309 UINT64 FSBFrequency;
310 UINT64 TSCFrequency;
311 UINT64 CPUFrequency;
312
313 rc = SetProperVariables(ImageHandle, SystemTable->RuntimeServices);
314 ASSERT_EFI_ERROR(rc);
315
316 rc = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gEfiAppleVarGuid, &gPrivateVarHandler, NULL);
317 ASSERT_EFI_ERROR(rc);
318
319 rc = InitializeDataHub(ImageHandle, SystemTable);
320 ASSERT_EFI_ERROR(rc);
321
322 GetVmVariable(EFI_INFO_INDEX_FSB_FREQUENCY, (CHAR8 *)&FSBFrequency, sizeof(FSBFrequency));
323 GetVmVariable(EFI_INFO_INDEX_TSC_FREQUENCY, (CHAR8 *)&TSCFrequency, sizeof(TSCFrequency));
324 GetVmVariable(EFI_INFO_INDEX_CPU_FREQUENCY, (CHAR8 *)&CPUFrequency, sizeof(CPUFrequency));
325
326 rc = CpuUpdateDataHub(gBS, FSBFrequency, TSCFrequency, CPUFrequency);
327 ASSERT_EFI_ERROR(rc);
328
329 rc = InitializeConsoleSim(ImageHandle, SystemTable);
330 ASSERT_EFI_ERROR(rc);
331
332 rc = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gEfiUnknown1ProtocolGuid, gUnknownProtoHandler, NULL);
333 ASSERT_EFI_ERROR(rc);
334
335 return EFI_SUCCESS;
336}
337
338EFI_STATUS EFIAPI
339VBoxDeinitAppleSim(IN EFI_HANDLE ImageHandle)
340{
341 return EFI_SUCCESS;
342}
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