- Timestamp:
- Feb 7, 2013 11:53:04 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/DevOVMF.cpp
r43712 r44581 5 5 6 6 /* 7 * Copyright (C) 20 12Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 45 45 #endif 46 46 47 #define VBOX_WITH_OVMF48 47 #include "Firmware2/VBoxPkg/Include/DevEFI.h" 49 48 #include "VBoxDD.h" … … 57 56 #include <Common/PiFirmwareFile.h> 58 57 59 #define EFI_SSM_VERSION 1 58 60 59 /******************************************************************************* 61 60 * Structures and Typedefs * … … 106 105 /** Thunk page pointer. */ 107 106 uint8_t *pu8EfiThunk; 108 /** First entry point of the EFI firmware */107 /** First entry point of the EFI firmware. */ 109 108 RTGCPHYS GCEntryPoint0; 110 /* Second Entry Point (PeiCore)*/109 /** Second Entry Point (PeiCore)*/ 111 110 RTGCPHYS GCEntryPoint1; 112 /** EFI firmware physical load address */111 /** EFI firmware physical load address. */ 113 112 RTGCPHYS GCLoadAddress; 114 /** Current info selector */113 /** Current info selector. */ 115 114 uint32_t iInfoSelector; 116 /** Current info position */117 int32_t iInfoPosition;115 /** Current info position. */ 116 int32_t offInfo; 118 117 119 118 /** Number of virtual CPUs. (Config) */ … … 123 122 /** RAM above 4GB (in bytes). (Config) */ 124 123 uint64_t cbAbove4GB; 125 124 /** The total amount of memory. */ 126 125 uint64_t cbRam; 127 126 /** The size of the RAM hole below 4GB. */ 128 127 uint64_t cbRamHole; 129 128 130 /** The size of the DMI tables */129 /** The size of the DMI tables. */ 131 130 uint16_t cbDmiTables; 132 131 /** The DMI tables. */ … … 136 135 uint8_t u8IOAPIC; 137 136 138 /* Boot parameters passed to the firmware*/137 /** Boot parameters passed to the firmware. */ 139 138 char szBootArgs[256]; 140 139 141 /* Host UUID (for DMI)*/140 /** Host UUID (for DMI). */ 142 141 RTUUID aUuid; 143 142 144 /* Device properties buffer */ 145 uint8_t* pu8DeviceProps; 146 /* Device properties buffer size */ 147 uint32_t u32DevicePropsLen; 148 149 /* Virtual machine front side bus frequency */ 150 uint64_t u64FsbFrequency; 151 /* Virtual machine time stamp counter frequency */ 152 uint64_t u64TscFrequency; 153 /* Virtual machine CPU frequency */ 154 uint64_t u64CpuFrequency; 155 /* GOP mode */ 156 uint32_t u32GopMode; 157 /* Uga mode resolutions */ 158 uint32_t u32UgaHorisontal; 159 uint32_t u32UgaVertical; 143 /** Device properties buffer. */ 144 R3PTRTYPE(uint8_t *) pbDeviceProps; 145 /** Device properties buffer size. */ 146 uint32_t cbDeviceProps; 147 148 /** Virtual machine front side bus frequency. */ 149 uint64_t u64FsbFrequency; 150 /** Virtual machine time stamp counter frequency. */ 151 uint64_t u64TscFrequency; 152 /** Virtual machine CPU frequency. */ 153 uint64_t u64CpuFrequency; 154 /** GOP mode. */ 155 uint32_t u32GopMode; 156 /** Uga mode horisontal resolution. */ 157 uint32_t cxUgaResolution; 158 /** Uga mode vertical resolution. */ 159 uint32_t cyUgaResolution; 160 160 161 NVRAMDESC NVRAM; 161 162 struct … … 168 169 typedef DEVEFI *PDEVEFI; 169 170 171 172 /******************************************************************************* 173 * Defined Constants And Macros * 174 *******************************************************************************/ 175 /** The saved state version. */ 176 #define EFI_SSM_VERSION 1 177 178 179 /******************************************************************************* 180 * Global Variables * 181 *******************************************************************************/ 182 /** Saved state NVRAMDESC field descriptors. */ 170 183 static SSMFIELD const g_aEfiNvramDescField[] = 171 184 { … … 182 195 }; 183 196 197 /** Saved state EFIVAR field descriptors. */ 184 198 static SSMFIELD const g_aEfiVariableDescFields[] = 185 199 { … … 194 208 SSMFIELD_ENTRY_TERM() 195 209 }; 210 211 196 212 197 213 /** … … 306 322 } 307 323 324 325 /** 326 * Gets the info item size. 327 * 328 * @returns Size in bytes, UINT32_MAX on error. 329 * @param pThis . 330 */ 308 331 static uint32_t efiInfoSize(PDEVEFI pThis) 309 332 { … … 321 344 return 4; 322 345 case EFI_INFO_INDEX_BOOT_ARGS: 323 return (uint32_t)RTStrNLen(pThis->szBootArgs, 324 sizeof pThis->szBootArgs) + 1; 346 return (uint32_t)RTStrNLen(pThis->szBootArgs, sizeof(pThis->szBootArgs)) + 1; 325 347 case EFI_INFO_INDEX_DEVICE_PROPS: 326 return pThis-> u32DevicePropsLen;348 return pThis->cbDeviceProps; 327 349 case EFI_INFO_INDEX_FSB_FREQUENCY: 328 350 case EFI_INFO_INDEX_CPU_FREQUENCY: … … 330 352 return 8; 331 353 } 332 Assert(false); 333 return 0; 334 } 335 354 return UINT32_MAX; 355 } 356 357 358 /** 359 * efiInfoNextByte for a uint64_t value. 360 * 361 * @returns Next (current) byte. 362 * @param pThis The EFI instance data. 363 * @param u64 The value. 364 */ 365 static uint8_t efiInfoNextByteU64(PDEVEFI pThis, uint64_t u64) 366 { 367 uint64_t off = pThis->offInfo; 368 if (off >= 4) 369 return 0; 370 return (uint8_t)(off >> (off * 8)); 371 } 372 373 /** 374 * efiInfoNextByte for a uint32_t value. 375 * 376 * @returns Next (current) byte. 377 * @param pThis The EFI instance data. 378 * @param u32 The value. 379 */ 380 static uint8_t efiInfoNextByteU32(PDEVEFI pThis, uint32_t u32) 381 { 382 uint32_t off = pThis->offInfo; 383 if (off >= 4) 384 return 0; 385 return (uint8_t)(off >> (off * 8)); 386 } 387 388 /** 389 * efiInfoNextByte for a buffer. 390 * 391 * @returns Next (current) byte. 392 * @param pThis The EFI instance data. 393 * @param pvBuf The buffer. 394 * @param cbBuf The buffer size. 395 */ 396 static uint8_t efiInfoNextByteBuf(PDEVEFI pThis, void const *pvBuf, size_t cbBuf) 397 { 398 uint32_t off = pThis->offInfo; 399 if (off >= cbBuf) 400 return 0; 401 return ((uint8_t const *)pvBuf)[off]; 402 } 403 404 /** 405 * Gets the next info byte. 406 * 407 * @returns Next (current) byte. 408 * @param pThis The EFI instance data. 409 */ 336 410 static uint8_t efiInfoNextByte(PDEVEFI pThis) 337 411 { 338 union339 {340 uint32_t u32;341 uint64_t u64;342 } value;343 344 412 switch (pThis->iInfoSelector) 345 413 { 346 case EFI_INFO_INDEX_VOLUME_BASE: 347 value.u32 = pThis->GCLoadAddress; 348 break; 349 case EFI_INFO_INDEX_VOLUME_SIZE: 350 value.u32 = pThis->cbEfiRom; 351 break; 352 case EFI_INFO_INDEX_TEMPMEM_BASE: 353 value.u32 = VBOX_EFI_TOP_OF_STACK; /* just after stack */ 354 break; 355 case EFI_INFO_INDEX_TEMPMEM_SIZE: 356 value.u32 = 512 * 1024; /* 512 K */ 357 break; 358 case EFI_INFO_INDEX_STACK_BASE: 359 /* Keep in sync with value in EfiThunk.asm */ 360 value.u32 = VBOX_EFI_TOP_OF_STACK - 128*1024; /* 2M - 128 K */ 361 break; 362 case EFI_INFO_INDEX_STACK_SIZE: 363 value.u32 = 128*1024; /* 128 K */ 364 break; 365 case EFI_INFO_INDEX_FSB_FREQUENCY: 366 value.u64 = pThis->u64FsbFrequency; 367 break; 368 case EFI_INFO_INDEX_TSC_FREQUENCY: 369 value.u64 = pThis->u64TscFrequency; 370 break; 371 case EFI_INFO_INDEX_CPU_FREQUENCY: 372 value.u64 = pThis->u64CpuFrequency; 373 break; 374 case EFI_INFO_INDEX_BOOT_ARGS: 375 return pThis->szBootArgs[pThis->iInfoPosition]; 376 case EFI_INFO_INDEX_DEVICE_PROPS: 377 return pThis->pu8DeviceProps[pThis->iInfoPosition]; 378 case EFI_INFO_INDEX_GOP_MODE: 379 value.u32 = pThis->u32GopMode; 380 break; 381 case EFI_INFO_INDEX_UGA_HORISONTAL_RESOLUTION: 382 value.u32 = pThis->u32UgaHorisontal; 383 break; 384 case EFI_INFO_INDEX_UGA_VERTICAL_RESOLUTION: 385 value.u32 = pThis->u32UgaVertical; 386 break; 414 415 case EFI_INFO_INDEX_VOLUME_BASE: return efiInfoNextByteU64(pThis, pThis->GCLoadAddress); 416 case EFI_INFO_INDEX_VOLUME_SIZE: return efiInfoNextByteU64(pThis, pThis->cbEfiRom); 417 case EFI_INFO_INDEX_TEMPMEM_BASE: return efiInfoNextByteU32(pThis, VBOX_EFI_TOP_OF_STACK); /* just after stack */ 418 case EFI_INFO_INDEX_TEMPMEM_SIZE: return efiInfoNextByteU32(pThis, _512K); 419 case EFI_INFO_INDEX_FSB_FREQUENCY: return efiInfoNextByteU64(pThis, pThis->u64FsbFrequency); 420 case EFI_INFO_INDEX_TSC_FREQUENCY: return efiInfoNextByteU64(pThis, pThis->u64TscFrequency); 421 case EFI_INFO_INDEX_CPU_FREQUENCY: return efiInfoNextByteU64(pThis, pThis->u64CpuFrequency); 422 case EFI_INFO_INDEX_BOOT_ARGS: return efiInfoNextByteBuf(pThis, pThis->szBootArgs, sizeof(pThis->szBootArgs)); 423 case EFI_INFO_INDEX_DEVICE_PROPS: return efiInfoNextByteBuf(pThis, pThis->pbDeviceProps, pThis->cbDeviceProps); 424 case EFI_INFO_INDEX_GOP_MODE: return efiInfoNextByteU32(pThis, pThis->u32GopMode); 425 case EFI_INFO_INDEX_UGA_HORISONTAL_RESOLUTION: return efiInfoNextByteU32(pThis, pThis->cxUgaResolution); 426 case EFI_INFO_INDEX_UGA_VERTICAL_RESOLUTION: return efiInfoNextByteU32(pThis, pThis->cyUgaResolution); 427 428 /* Keep in sync with value in EfiThunk.asm */ 429 case EFI_INFO_INDEX_STACK_BASE: return efiInfoNextByteU32(pThis, VBOX_EFI_TOP_OF_STACK - _128K); /* 2M - 128 K */ 430 case EFI_INFO_INDEX_STACK_SIZE: return efiInfoNextByteU32(pThis, _128K); 431 387 432 default: 388 Assert(false); 389 value.u64 = 0; 390 break; 391 } 392 393 return *((uint8_t*)&value+pThis->iInfoPosition); 433 PDMDevHlpDBGFStop(pThis->pDevIns, RT_SRC_POS, "%#x", pThis->iInfoSelector); 434 return 0; 435 } 394 436 } 395 437 … … 487 529 { 488 530 case EFI_INFO_PORT: 489 if (pThis-> iInfoPosition== -1 && cb == 4)531 if (pThis->offInfo == -1 && cb == 4) 490 532 { 491 *pu32 = efiInfoSize(pThis); 492 pThis->iInfoPosition = 0; 533 pThis->offInfo = 0; 534 uint32_t cbInfo = *pu32 = efiInfoSize(pThis); 535 if (cbInfo == UINT32_MAX) 536 return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "iInfoSelector=%#x (%d)\n", 537 pThis->iInfoSelector, pThis->iInfoSelector); 493 538 } 494 539 else 495 540 { 496 /* So far */497 541 if (cb != 1) 498 542 return VERR_IOM_IOPORT_UNUSED; 499 543 *pu32 = efiInfoNextByte(pThis); 500 pThis-> iInfoPosition++;544 pThis->offInfo++; 501 545 } 502 546 return VINF_SUCCESS; … … 504 548 case EFI_PANIC_PORT: 505 549 #ifdef IN_RING3 506 LogRel((" Panic port read!\n"));550 LogRel(("EFI panic port read!\n")); 507 551 /* Insert special code here on panic reads */ 508 552 return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "EFI Panic: panic port read!\n"); … … 578 622 case EFI_INFO_PORT: 579 623 pThis->iInfoSelector = u32; 580 pThis-> iInfoPosition= -1;624 pThis->offInfo = -1; 581 625 break; 582 626 case EFI_DEBUG_PORT: … … 634 678 switch (u32) 635 679 { 636 case EFI_PANIC_CMD_BAD_ORG: 680 case EFI_PANIC_CMD_BAD_ORG: /* Legacy */ 637 681 case EFI_PANIC_CMD_THUNK_TRAP: 638 682 LogRel(("EFI Panic: Unexpected trap!!\n")); … … 899 943 900 944 pThis->iInfoSelector = 0; 901 pThis-> iInfoPosition= -1;945 pThis->offInfo = -1; 902 946 903 947 pThis->iMsg = 0; … … 979 1023 } 980 1024 981 if (pThis->p u8DeviceProps)982 { 983 MMR3HeapFree(pThis->p u8DeviceProps);984 pThis->p u8DeviceProps = NULL;985 pThis-> u32DevicePropsLen= 0;1025 if (pThis->pbDeviceProps) 1026 { 1027 MMR3HeapFree(pThis->pbDeviceProps); 1028 pThis->pbDeviceProps = NULL; 1029 pThis->cbDeviceProps = 0; 986 1030 } 987 1031 … … 1153 1197 1154 1198 1155 static int efiParseDeviceString(PDEVEFI pThis, char *pszDeviceProps)1199 static int efiParseDeviceString(PDEVEFI pThis, char *pszDeviceProps) 1156 1200 { 1157 1201 int rc = 0; … … 1162 1206 u32OutLen = (uint32_t)RTStrNLen(pszDeviceProps, RTSTR_MAX) / 2 + 1; 1163 1207 1164 pThis->pu8DeviceProps = 1165 (uint8_t*)PDMDevHlpMMHeapAlloc(pThis->pDevIns, u32OutLen); 1166 if (!pThis->pu8DeviceProps) 1208 pThis->pbDeviceProps = (uint8_t *)PDMDevHlpMMHeapAlloc(pThis->pDevIns, u32OutLen); 1209 if (!pThis->pbDeviceProps) 1167 1210 return VERR_NO_MEMORY; 1168 1211 … … 1176 1219 u8Value = u8Hb << 4; 1177 1220 else 1178 pThis->p u8DeviceProps[iHex++] = u8Hb | u8Value;1221 pThis->pbDeviceProps[iHex++] = u8Hb | u8Value; 1179 1222 1180 1223 Assert(iHex < u32OutLen); … … 1183 1226 1184 1227 Assert(iHex == 0 || fUpper); 1185 pThis-> u32DevicePropsLen= iHex;1228 pThis->cbDeviceProps = iHex; 1186 1229 1187 1230 return rc; … … 1191 1234 * @copydoc(PDMIBASE::pfnQueryInterface) 1192 1235 */ 1193 static DECLCALLBACK(void *) devEfi _pfnQueryInterface(PPDMIBASE pInterface, const char *pszIID)1236 static DECLCALLBACK(void *) devEfiQueryInterface(PPDMIBASE pInterface, const char *pszIID) 1194 1237 { 1195 1238 LogFlowFunc(("ENTER: pIBase: %p, pszIID:%p\n", __FUNCTION__, pInterface, pszIID)); … … 1326 1369 } 1327 1370 1328 /* NVRAM processing */ 1329 pThis->Lun0.IBase.pfnQueryInterface = devEfi_pfnQueryInterface; 1371 /* 1372 * NVRAM processing. 1373 */ 1374 pThis->Lun0.IBase.pfnQueryInterface = devEfiQueryInterface; 1330 1375 1331 1376 #if 0 … … 1347 1392 1348 1393 nvramLoad(pThis); 1394 1349 1395 /* 1350 1396 * Get boot args. … … 1387 1433 else 1388 1434 { 1389 pThis->p u8DeviceProps= NULL;1390 pThis-> u32DevicePropsLen= 0;1435 pThis->pbDeviceProps = NULL; 1436 pThis->cbDeviceProps = 0; 1391 1437 } 1392 1438 … … 1394 1440 * CPU frequencies 1395 1441 */ 1396 // @todo: we need to have VMM API to access TSC increase speed, for now provide reasonable default1442 /// @todo: we need to have VMM API to access TSC increase speed, for now provide reasonable default 1397 1443 pThis->u64TscFrequency = RTMpGetMaxFrequency(0) * 1000 * 1000;// TMCpuTicksPerSecond(PDMDevHlpGetVM(pDevIns)); 1398 1444 if (pThis->u64TscFrequency == 0) … … 1415 1461 * Uga graphics 1416 1462 */ 1417 rc = CFGMR3QueryU32(pCfg, "UgaHorizontalResolution", &pThis->u32UgaHorisontal); 1418 AssertRC(rc); 1419 if (pThis->u32UgaHorisontal == 0) 1420 { 1421 pThis->u32UgaHorisontal = 1024; /* 1024x768 */ 1422 } 1423 rc = CFGMR3QueryU32(pCfg, "UgaVerticalResolution", &pThis->u32UgaVertical); 1424 AssertRC(rc); 1425 if (pThis->u32UgaVertical == 0) 1426 { 1427 pThis->u32UgaVertical = 768; /* 1024x768 */ 1428 } 1463 rc = CFGMR3QueryU32Def(pCfg, "UgaHorizontalResolution", &pThis->cxUgaResolution, 0); AssertRC(rc); 1464 if (pThis->cxUgaResolution == 0) 1465 pThis->cxUgaResolution = 1024; /* 1024x768 */ 1466 rc = CFGMR3QueryU32Def(pCfg, "UgaVerticalResolution", &pThis->cyUgaResolution, 0); AssertRC(rc); 1467 if (pThis->cyUgaResolution == 0) 1468 pThis->cyUgaResolution = 768; /* 1024x768 */ 1429 1469 1430 1470 #ifdef DEVEFI_WITH_VBOXDBG_SCRIPT … … 1453 1493 /* 1454 1494 * Plant DMI and MPS tables 1455 * XXX I wonder if we really need these tables as there is no SMBIOS header... 1456 */ 1457 uint16_t cbDmiTablesDummy; 1495 */ 1496 /** @todo XXX I wonder if we really need these tables as there is no SMBIOS header... */ 1458 1497 rc = FwCommonPlantDMITable(pDevIns, pThis->au8DMIPage, VBOX_DMI_TABLE_SIZE, &pThis->aUuid, 1459 1498 pDevIns->pCfg, pThis->cCpus, &pThis->cbDmiTables);
Note:
See TracChangeset
for help on using the changeset viewer.