VirtualBox

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

Last change on this file since 49098 was 49098, checked in by vboxsync, 11 years ago

EFI: Found a likely value for APPLE_GETVAR_PROTOCOL::u64Magic as well as number of parameters for the unknown methods. Some cleanups.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1/* $Id: VBoxAppleSim.c 49098 2013-10-15 01:30:53Z vboxsync $ */
2/** @file
3 * VBoxAppleSim.c - VirtualBox Apple Firmware simulation support
4 */
5
6/*
7 * Copyright (C) 2010-2011 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 "VBoxPkg.h"
48#include "DevEFI.h"
49#include "iprt/asm.h"
50
51
52/*
53 * External functions
54 */
55EFI_STATUS EFIAPI
56CpuUpdateDataHub(EFI_BOOT_SERVICES * bs,
57 UINT64 FSBFrequency,
58 UINT64 TSCFrequency,
59 UINT64 CPUFrequency);
60
61EFI_STATUS EFIAPI
62InitializeConsoleSim (IN EFI_HANDLE ImageHandle,
63 IN EFI_SYSTEM_TABLE *SystemTable);
64
65
66/*
67 * Internal Functions
68 */
69static UINT32
70GetVmVariable(UINT32 Variable, CHAR8 *pbBuf, UINT32 cbBuf)
71{
72 UINT32 cbVar, offBuf;
73
74 ASMOutU32(EFI_INFO_PORT, Variable);
75 cbVar = ASMInU32(EFI_INFO_PORT);
76
77 for (offBuf = 0; offBuf < cbVar && offBuf < cbBuf; offBuf++)
78 pbBuf[offBuf] = ASMInU8(EFI_INFO_PORT);
79
80 return cbVar;
81}
82
83/*
84 * GUIDs
85 */
86/** The EFI variable GUID for the 'FirmwareFeatures' and friends.
87 * Also known as AppleFirmwareVariableGuid in other sources. */
88EFI_GUID gEfiAppleNvramGuid = {
89 0x4D1EDE05, 0x38C7, 0x4A6A, {0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x8C, 0x14 }
90};
91
92/** The EFI variable GUID for the 'boot-args' variable and others.
93 * Also known as AppleNVRAMVariableGuid in other sources. */
94EFI_GUID gEfiAppleBootGuid = {
95 0x7C436110, 0xAB2A, 0x4BBB, {0xA8, 0x80, 0xFE, 0x41, 0x99, 0x5C, 0x9F, 0x82}
96};
97
98
99/*
100 * Device Properoty protocol implementation hack.
101 */
102
103/** gEfiAppleVarGuid is aka AppleDevicePropertyProtocolGuid in other sources. */
104EFI_GUID gEfiAppleVarGuid = {
105 0x91BD12FE, 0xF6C3, 0x44FB, {0xA5, 0xB7, 0x51, 0x22, 0xAB, 0x30, 0x3A, 0xE0}
106};
107
108/** APPLE_GETVAR_PROTOCOL is aka APPLE_DEVICE_PROPERTY_PROTOCOL in other sources. */
109typedef struct _APPLE_GETVAR_PROTOCOL APPLE_GETVAR_PROTOCOL;
110
111struct _APPLE_GETVAR_PROTOCOL
112{
113 /** Magic value or some version thingy. boot.efi doesn't check this, I think. */
114 UINT64 u64Magic;
115
116 EFI_STATUS (EFIAPI *pfnUnknown0)(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2,
117 IN VOID *pvArg3, IN VOID *pvArg4);
118 EFI_STATUS (EFIAPI *pfnUnknown1)(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2,
119 IN VOID *pvArg3, IN VOID *pvArg4);
120 EFI_STATUS (EFIAPI *pfnUnknown2)(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2);
121
122 EFI_STATUS (EFIAPI *pfnGetDevProps)(IN APPLE_GETVAR_PROTOCOL *This, IN CHAR8 *pbBuf, IN OUT UINT32 *pcbBuf);
123};
124/** The value of APPLE_GETVAR_PROTOCOL::u64Magic. */
125#define APPLE_GETVAR_PROTOCOL_MAGIC 0x10000
126
127EFI_STATUS EFIAPI
128AppleGetVar_Unknown0(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2,
129 IN VOID *pvArg3, IN VOID *pvArg4)
130{
131 CHAR8 szMsg[128];
132 AsciiSPrint(szMsg, sizeof(szMsg), "AppleGetVar_Unknown0: pvArg1=%p pvArg2=%p pvArg3=%p pvArg4=%p",
133 pvArg1, pvArg2, pvArg3, pvArg4);
134 DebugAssert(__FILE__, __LINE__, szMsg);
135 return EFI_UNSUPPORTED;
136}
137
138EFI_STATUS EFIAPI
139AppleGetVar_Unknown1(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2,
140 IN VOID *pvArg3, IN VOID *pvArg4)
141{
142 CHAR8 szMsg[128];
143 AsciiSPrint(szMsg, sizeof(szMsg), "AppleGetVar_Unknown1: pvArg1=%p pvArg2=%p pvArg3=%p pvArg4=%p",
144 pvArg1, pvArg2, pvArg3, pvArg4);
145 DebugAssert(__FILE__, __LINE__, szMsg);
146 return EFI_UNSUPPORTED;
147}
148
149EFI_STATUS EFIAPI
150AppleGetVar_Unknown2(IN APPLE_GETVAR_PROTOCOL *This, IN VOID *pvArg1, IN VOID *pvArg2)
151{
152 CHAR8 szMsg[80];
153 AsciiSPrint(szMsg, sizeof(szMsg), "AppleGetVar_Unknown2: pvArg1=%p pvArg2=%p", pvArg1, pvArg2);
154 DebugAssert(__FILE__, __LINE__, szMsg);
155 return EFI_UNSUPPORTED;
156}
157
158
159/**
160 * This method obtains the 'device-properties' that get exposed by
161 * AppleEFIFirmware and parsed by AppleACPIPlatform.
162 *
163 * Check out the data in the IORegisteryExplorer, the device-properties property
164 * under IODeviceTree:/efi.
165 *
166 * @retval EFI_SUCCESS, check *pcbBuf or the number of bytes actually returned.
167 * @retval EFI_BUFFER_TOO_SMALL, check *pcbBuf for the necessary buffer size.
168 * @param pThis Not used.
169 * @param pbBuf The output buffer.
170 * @param pcbBuf On input, the varible pointed to contains the size of the
171 * buffer. The size is generally 4KB from what we've observed.
172 * On output, it contains the amount of data available, this
173 * is always set.
174 */
175EFI_STATUS EFIAPI
176AppleGetVar_GetDeviceProps(IN APPLE_GETVAR_PROTOCOL *pThis, OUT CHAR8 *pbBuf, IN OUT UINT32 *pcbBuf)
177{
178 UINT32 cbBuf = *pcbBuf;
179 UINT32 cbActual;
180
181 cbActual = GetVmVariable(EFI_INFO_INDEX_DEVICE_PROPS, pbBuf, cbBuf);
182 *pcbBuf = cbActual;
183
184 if (cbActual > cbBuf)
185 return EFI_BUFFER_TOO_SMALL;
186
187 return EFI_SUCCESS;
188}
189
190APPLE_GETVAR_PROTOCOL gPrivateVarHandler =
191{
192 /* Magic = */ APPLE_GETVAR_PROTOCOL_MAGIC,
193 AppleGetVar_Unknown0,
194 AppleGetVar_Unknown1,
195 AppleGetVar_Unknown2,
196 AppleGetVar_GetDeviceProps
197};
198
199
200/*
201 * Unknown Protocol #1.
202 */
203
204/** This seems to be related to graphics/display... */
205EFI_GUID gEfiUnknown1ProtocolGuid =
206{
207 0xDD8E06AC, 0x00E2, 0x49A9, {0x88, 0x8F, 0xFA, 0x46, 0xDE, 0xD4, 0x0A, 0x52}
208};
209
210EFI_STATUS EFIAPI
211UnknownHandlerImpl()
212{
213#ifdef DEBUG
214 ASSERT(0);
215#endif
216 Print(L"Unknown called\n");
217 return EFI_SUCCESS;
218}
219
220/* array of pointers to function */
221EFI_STATUS (EFIAPI *gUnknownProtoHandler[])() =
222{
223 UnknownHandlerImpl,
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};
242
243EFI_STATUS EFIAPI
244SetProperVariables(IN EFI_HANDLE ImageHandle, EFI_RUNTIME_SERVICES * rs)
245{
246 EFI_STATUS rc;
247 UINT32 vBackgroundClear = 0x00000000;
248 UINT32 vFwFeatures = 0x80000015;
249 UINT32 vFwFeaturesMask = 0x800003ff;
250
251 // -legacy acpi=0xffffffff acpi_debug=0xfffffff panic_io_port=0xef11 io=0xfffffffe trace=4096 io=0xffffffef -v serial=2 serialbaud=9600
252 // 0x10 makes kdb default, thus 0x15e for kdb, 0x14e for gdb
253
254 //static const CHAR8 vBootArgs[] = "debug=0x15e keepsyms=1 acpi=0xffffffff acpi_debug=0xff acpi_level=7 -v -x32 -s"; // or just "debug=0x8 -legacy"
255 // 0x14e for serial output
256 //static const CHAR8 vDefBootArgs[] = "debug=0x146 keepsyms=1 -v -serial=0x1";
257 static const CHAR8 vDefBootArgs[] = "keepsyms=1 -v -serial=0x1";
258 CHAR8 vBootArgs[256];
259 UINT32 BootArgsLen;
260
261 BootArgsLen = GetVmVariable(EFI_INFO_INDEX_BOOT_ARGS, vBootArgs, sizeof vBootArgs);
262 if (BootArgsLen <= 1)
263 {
264 BootArgsLen = sizeof vDefBootArgs;
265 CopyMem(vBootArgs, vDefBootArgs, BootArgsLen);
266 }
267 rc = rs->SetVariable(L"BackgroundClear",
268 &gEfiAppleNvramGuid,
269 /* EFI_VARIABLE_NON_VOLATILE | */ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
270 sizeof(vBackgroundClear), &vBackgroundClear);
271
272 rc = rs->SetVariable(L"FirmwareFeatures",
273 &gEfiAppleNvramGuid,
274 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
275 sizeof(vFwFeatures), &vFwFeatures);
276
277 rc = rs->SetVariable(L"FirmwareFeaturesMask",
278 &gEfiAppleNvramGuid,
279 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
280 sizeof(vFwFeaturesMask), &vFwFeaturesMask);
281
282 rc = rs->SetVariable(L"boot-args",
283 &gEfiAppleBootGuid,
284 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
285 BootArgsLen, &vBootArgs);
286
287 return EFI_SUCCESS;
288}
289
290/**
291 * VBoxInitAppleSim entry point.
292 *
293 * @returns EFI status code.
294 *
295 * @param ImageHandle The image handle.
296 * @param SystemTable The system table pointer.
297 */
298EFI_STATUS EFIAPI
299VBoxInitAppleSim(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
300{
301 EFI_STATUS rc;
302 UINT64 FSBFrequency;
303 UINT64 TSCFrequency;
304 UINT64 CPUFrequency;
305
306 rc = SetProperVariables(ImageHandle, SystemTable->RuntimeServices);
307 ASSERT_EFI_ERROR(rc);
308
309 rc = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gEfiAppleVarGuid, &gPrivateVarHandler, NULL);
310 ASSERT_EFI_ERROR(rc);
311
312 GetVmVariable(EFI_INFO_INDEX_FSB_FREQUENCY, (CHAR8 *)&FSBFrequency, sizeof(FSBFrequency));
313 GetVmVariable(EFI_INFO_INDEX_TSC_FREQUENCY, (CHAR8 *)&TSCFrequency, sizeof(TSCFrequency));
314 GetVmVariable(EFI_INFO_INDEX_CPU_FREQUENCY, (CHAR8 *)&CPUFrequency, sizeof(CPUFrequency));
315
316 rc = CpuUpdateDataHub(gBS, FSBFrequency, TSCFrequency, CPUFrequency);
317 ASSERT_EFI_ERROR(rc);
318
319 rc = InitializeConsoleSim(ImageHandle, SystemTable);
320 ASSERT_EFI_ERROR(rc);
321
322 rc = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gEfiUnknown1ProtocolGuid, gUnknownProtoHandler, NULL);
323 ASSERT_EFI_ERROR(rc);
324
325 return EFI_SUCCESS;
326}
327
328EFI_STATUS EFIAPI
329VBoxDeinitAppleSim(IN EFI_HANDLE ImageHandle)
330{
331 return EFI_SUCCESS;
332}
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