VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxSysTables/TableConversion.c@ 33540

Last change on this file since 33540 was 33540, checked in by vboxsync, 14 years ago

*: spelling fixes, thanks Timeless!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/* $Id: TableConversion.c 33540 2010-10-28 09:27:05Z vboxsync $ */
2/** @file
3 * TableConversion.c
4 */
5
6/*
7 * Copyright (C) 2009-2010 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
18/*++
19
20 This code is baed on:
21
22 Copyright (c) 2006 - 2007, Intel Corporation
23 All rights reserved. This program and the accompanying materials
24 are licensed and made available under the terms and conditions of the BSD License
25 which accompanies this distribution. The full text of the license may be found at
26 http://opensource.org/licenses/bsd-license.php
27
28 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
29 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
30 --*/
31
32#include <IndustryStandard/Pci.h>
33#include <IndustryStandard/Acpi.h>
34#include <IndustryStandard/SmBios.h>
35#include "LegacyBiosMpTable.h"
36
37#include <Library/DebugLib.h>
38#include <Library/BaseMemoryLib.h>
39#include <Library/UefiBootServicesTableLib.h>
40#include <Library/MemoryAllocationLib.h>
41#include <Library/BaseLib.h>
42
43#include <Guid/Acpi.h>
44#include <Guid/SmBios.h>
45#include <Guid/Mps.h>
46#include <Guid/HobList.h>
47#include <Guid/GlobalVariable.h>
48
49#define SYS_TABLE_PAD(ptr) (((~ptr) +1) & 0x07 )
50#define EFI_SYSTEM_TABLE_MAX_ADDRESS 0xFFFFFFFF
51
52EFI_STATUS
53ConvertAcpiTable (
54 IN UINTN TableLen,
55 IN OUT VOID **Table
56 )
57/*++
58
59 Routine Description:
60 Convert RSDP of ACPI Table if its location is lower than Address:0x100000
61 Assumption here:
62 As in legacy Bios, ACPI table is required to place in E/F Seg,
63 So here we just check if the range is E/F seg,
64 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS
65
66 Arguments:
67 TableLen - Acpi RSDP length
68 Table - pointer to the table
69
70 Returns:
71 EFI_SUCCESS - Convert Table successfully
72 Other - Failed
73
74 --*/
75{
76 VOID *AcpiTableOri;
77 VOID *AcpiTableNew;
78 EFI_STATUS Status;
79 EFI_PHYSICAL_ADDRESS BufferPtr;
80
81
82 AcpiTableOri = (VOID *)(UINTN)((*Table));
83
84 BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;
85 Status = gBS->AllocatePages (
86 AllocateMaxAddress,
87 EfiACPIMemoryNVS,
88 EFI_SIZE_TO_PAGES(TableLen),
89 &BufferPtr
90 );
91 ASSERT_EFI_ERROR (Status);
92 AcpiTableNew = (VOID *)(UINTN)BufferPtr;
93 CopyMem (AcpiTableNew, AcpiTableOri, TableLen);
94
95 //
96 // Change configuration table Pointer
97 //
98 *Table = AcpiTableNew;
99
100 return EFI_SUCCESS;
101}
102
103EFI_STATUS
104ConvertSmbiosTable (
105 IN OUT VOID **Table
106 )
107/*++
108
109 Routine Description:
110
111 Convert Smbios Table if the Location of the SMBios Table is lower than Address 0x100000
112 Assumption here:
113 As in legacy Bios, Smbios table is required to place in E/F Seg,
114 So here we just check if the range is F seg,
115 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
116 Arguments:
117 Table - pointer to the table
118
119 Returns:
120 EFI_SUCCESS - Convert Table successfully
121 Other - Failed
122
123 --*/
124{
125 SMBIOS_TABLE_ENTRY_POINT *SmbiosTableNew;
126 SMBIOS_TABLE_ENTRY_POINT *SmbiosTableOri;
127 EFI_STATUS Status;
128 UINT32 SmbiosEntryLen;
129 UINT32 BufferLen;
130 EFI_PHYSICAL_ADDRESS BufferPtr;
131
132 SmbiosTableNew = NULL;
133 SmbiosTableOri = NULL;
134
135 //
136 // Get Smibos configuration Table
137 //
138 SmbiosTableOri = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)((*Table));
139
140
141 ASSERT(CalculateSum8((UINT8*)SmbiosTableOri, sizeof(SMBIOS_TABLE_ENTRY_POINT)) == 0);
142 //
143 // Relocate the Smibos memory
144 //
145 BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;
146 if (SmbiosTableOri->SmbiosBcdRevision != 0x21) {
147 SmbiosEntryLen = SmbiosTableOri->EntryPointLength;
148 } else {
149 //
150 // According to Smbios Spec 2.4, we should set entry point length as 0x1F if version is 2.1
151 //
152 SmbiosEntryLen = 0x1F;
153 }
154 BufferLen = SmbiosEntryLen + SYS_TABLE_PAD(SmbiosEntryLen) + SmbiosTableOri->TableLength;
155 Status = gBS->AllocatePages (
156 AllocateMaxAddress,
157 EfiACPIMemoryNVS,
158 EFI_SIZE_TO_PAGES(BufferLen),
159 &BufferPtr
160 );
161 ASSERT_EFI_ERROR (Status);
162 SmbiosTableNew = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)BufferPtr;
163 CopyMem (
164 SmbiosTableNew,
165 SmbiosTableOri,
166 SmbiosEntryLen
167 );
168 //
169 // Get Smbios Structure table address, and make sure the start address is 32-bit align
170 //
171 BufferPtr += SmbiosEntryLen + SYS_TABLE_PAD(SmbiosEntryLen);
172 CopyMem (
173 (VOID *)(UINTN)BufferPtr,
174 (VOID *)(UINTN)(SmbiosTableOri->TableAddress),
175 SmbiosTableOri->TableLength
176 );
177 SmbiosTableNew->TableAddress = (UINT32)BufferPtr;
178 SmbiosTableNew->IntermediateChecksum = 0;
179 SmbiosTableNew->IntermediateChecksum =
180 CalculateCheckSum8 ((UINT8*)SmbiosTableNew + 0x10, SmbiosEntryLen -0x10);
181 //
182 // Change the SMBIOS pointer
183 //
184 *Table = SmbiosTableNew;
185
186 return EFI_SUCCESS;
187}
188
189EFI_STATUS
190ConvertMpsTable (
191 IN OUT VOID **Table
192 )
193/*++
194
195 Routine Description:
196
197 Convert MP Table if the Location of the SMBios Table is lower than Address 0x100000
198 Assumption here:
199 As in legacy Bios, MP table is required to place in E/F Seg,
200 So here we just check if the range is E/F seg,
201 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
202 Arguments:
203 Table - pointer to the table
204
205 Returns:
206 EFI_SUCCESS - Convert Table successfully
207 Other - Failed
208
209 --*/
210{
211 UINT32 Data32;
212 UINT32 FPLength;
213 EFI_LEGACY_MP_TABLE_FLOATING_POINTER *MpsFloatingPointerOri;
214 EFI_LEGACY_MP_TABLE_FLOATING_POINTER *MpsFloatingPointerNew;
215 EFI_LEGACY_MP_TABLE_HEADER *MpsTableOri;
216 EFI_LEGACY_MP_TABLE_HEADER *MpsTableNew;
217 VOID *OemTableOri;
218 VOID *OemTableNew;
219 EFI_STATUS Status;
220 EFI_PHYSICAL_ADDRESS BufferPtr;
221
222 //
223 // Get MP configuration Table
224 //
225 MpsFloatingPointerOri = (EFI_LEGACY_MP_TABLE_FLOATING_POINTER *)(UINTN)(*Table);
226 //
227 // Get Floating pointer structure length
228 //
229 FPLength = MpsFloatingPointerOri->Length * 16;
230 ASSERT(CalculateSum8((UINT8*)MpsFloatingPointerOri, FPLength) == 0);
231 Data32 = FPLength + SYS_TABLE_PAD (FPLength);
232 MpsTableOri = (EFI_LEGACY_MP_TABLE_HEADER *)(UINTN)(MpsFloatingPointerOri->PhysicalAddress);
233 ASSERT(MpsTableOri != NULL);
234 ASSERT(CalculateSum8((UINT8*)MpsTableOri, MpsTableOri->BaseTableLength) == 0);
235
236 Data32 += MpsTableOri->BaseTableLength;
237 Data32 += MpsTableOri->ExtendedTableLength;
238 if (MpsTableOri->OemTablePointer != 0x00) {
239 Data32 += SYS_TABLE_PAD (Data32);
240 Data32 += MpsTableOri->OemTableSize;
241 }
242
243 //
244 // Relocate memory
245 //
246 BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;
247 Status = gBS->AllocatePages (
248 AllocateMaxAddress,
249 EfiACPIMemoryNVS,
250 EFI_SIZE_TO_PAGES(Data32),
251 &BufferPtr
252 );
253 ASSERT_EFI_ERROR (Status);
254 MpsFloatingPointerNew = (EFI_LEGACY_MP_TABLE_FLOATING_POINTER *)(UINTN)BufferPtr;
255 CopyMem (MpsFloatingPointerNew, MpsFloatingPointerOri, FPLength);
256 //
257 // If Mp Table exists
258 //
259 if (MpsTableOri != NULL) {
260 //
261 // Get Mps table length, including Ext table
262 //
263 BufferPtr = BufferPtr + FPLength + SYS_TABLE_PAD (FPLength);
264 MpsTableNew = (EFI_LEGACY_MP_TABLE_HEADER *)(UINTN)BufferPtr;
265 CopyMem (MpsTableNew, MpsTableOri, MpsTableOri->BaseTableLength + MpsTableOri->ExtendedTableLength);
266
267 if ((MpsTableOri->OemTableSize != 0x0000) && (MpsTableOri->OemTablePointer != 0x0000)){
268 BufferPtr += MpsTableOri->BaseTableLength + MpsTableOri->ExtendedTableLength;
269 BufferPtr += SYS_TABLE_PAD (BufferPtr);
270 OemTableNew = (VOID *)(UINTN)BufferPtr;
271 OemTableOri = (VOID *)(UINTN)MpsTableOri->OemTablePointer;
272 CopyMem (OemTableNew, OemTableOri, MpsTableOri->OemTableSize);
273 MpsTableNew->OemTablePointer = (UINT32)(UINTN)OemTableNew;
274 }
275 MpsTableNew->Checksum = 0;
276 MpsTableNew->Checksum = CalculateCheckSum8 ((UINT8*)MpsTableNew, MpsTableOri->BaseTableLength);
277 MpsFloatingPointerNew->PhysicalAddress = (UINT32)(UINTN)MpsTableNew;
278 MpsFloatingPointerNew->Checksum = 0;
279 MpsFloatingPointerNew->Checksum = CalculateCheckSum8 ((UINT8*)MpsFloatingPointerNew, FPLength);
280 }
281 //
282 // Change the pointer
283 //
284 *Table = MpsFloatingPointerNew;
285
286 return EFI_SUCCESS;
287}
288
289EFI_STATUS
290ConvertSystemTable (
291 IN EFI_GUID *TableGuid,
292 IN OUT VOID **Table
293 )
294/*++
295
296 Routine Description:
297 Convert ACPI Table /Smbios Table /MP Table if its location is lower than Address:0x100000
298 Assumption here:
299 As in legacy Bios, ACPI/Smbios/MP table is required to place in E/F Seg,
300 So here we just check if the range is E/F seg,
301 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS
302
303 Arguments:
304 TableGuid - Guid of the table
305 Table - pointer to the table
306
307 Returns:
308 EFI_SUCCESS - Convert Table successfully
309 Other - Failed
310
311 --*/
312{
313 EFI_STATUS Status = EFI_SUCCESS;
314 VOID *AcpiHeader;
315 UINTN AcpiTableLen;
316
317 //
318 // If match acpi guid (1.0, 2.0, or later), Convert ACPI table according to version.
319 //
320
321 if (CompareGuid(TableGuid, &gEfiAcpiTableGuid) || CompareGuid(TableGuid, &gEfiAcpi20TableGuid)){
322 AcpiHeader = (VOID*)(UINTN)(*Table);
323
324 if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Reserved == 0x00){
325 //
326 // If Acpi 1.0 Table, then RSDP structure doesn't contain Length field, use structure size
327 //
328 AcpiTableLen = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
329 } else if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Reserved >= 0x02){
330 //
331 // If Acpi 2.0 or later, use RSDP Length fied.
332 //
333 AcpiTableLen = ((EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Length;
334 } else {
335 //
336 // Invalid Acpi Version, return
337 //
338 return EFI_UNSUPPORTED;
339 }
340 Status = ConvertAcpiTable (AcpiTableLen, Table);
341 return Status;
342 }
343
344 //
345 // If matches smbios guid, convert Smbios table.
346 //
347 if (CompareGuid(TableGuid, &gEfiSmbiosTableGuid)){
348 Status = ConvertSmbiosTable (Table);
349 return Status;
350 }
351
352 //
353 // If the table is MP table?
354 //
355 if (CompareGuid(TableGuid, &gEfiMpsTableGuid)){
356 Status = ConvertMpsTable (Table);
357 return Status;
358 }
359
360 return EFI_UNSUPPORTED;
361}
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