Changeset 91497 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Sep 30, 2021 11:34:59 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/efi/efivarstorevfs.cpp
r90343 r91497 34 34 #include <iprt/asm.h> 35 35 #include <iprt/assert.h> 36 #include <iprt/crc.h> 36 37 #include <iprt/file.h> 37 38 #include <iprt/err.h> … … 2336 2337 2337 2338 2339 /** 2340 * Fills the given range with 0xff to match what a real NAND flash device would return for 2341 * unwritten storage. 2342 * 2343 * @returns IPRT status code. 2344 * @param hVfsFile The VFS file handle to write to. 2345 * @param offStart The start offset to fill. 2346 * @param offEnd Offset to fill up to (exclusive). 2347 */ 2348 static int rtEfiVarStoreFillWithFF(RTVFSFILE hVfsFile, uint64_t offStart, uint64_t offEnd) 2349 { 2350 int rc = VINF_SUCCESS; 2351 uint8_t abFF[512]; 2352 memset(&abFF[0], 0xff, sizeof(abFF)); 2353 2354 while ( offStart < offEnd 2355 && RT_SUCCESS(rc)) 2356 { 2357 size_t cbThisWrite = RT_MIN(sizeof(abFF), offEnd - offStart); 2358 rc = RTVfsFileWriteAt(hVfsFile, offStart, &abFF[0], cbThisWrite, NULL); 2359 offStart += cbThisWrite; 2360 } 2361 2362 return rc; 2363 } 2364 2365 2338 2366 RTDECL(int) RTEfiVarStoreOpenAsVfs(RTVFSFILE hVfsFileIn, uint32_t fMntFlags, uint32_t fVarStoreFlags, PRTVFS phVfs, PRTERRINFO pErrInfo) 2339 2367 { … … 2402 2430 cbStore = cbFile - offStore; 2403 2431 } 2432 2433 uint32_t cbFtw = 0; 2434 uint32_t offFtw = 0; 2435 uint32_t cbVarStore = cbStore; 2436 uint32_t cbNvEventLog = 0; 2437 uint32_t offNvEventLog = 0; 2438 if (!(fFlags & RTEFIVARSTORE_CREATE_F_NO_FTW_WORKING_SPACE)) 2439 { 2440 /* Split the available space in half for the fault tolerant working area. */ 2441 /** @todo Don't fully understand how these values come together right now but 2442 * we want to create NVRAM files matching the default OVMF_VARS.fd for now, see 2443 * https://github.com/tianocore/edk2/commit/b24fca05751f8222acf264853709012e0ab7bf49 2444 * for the layout. 2445 * Probably have toadd more arguments to control the different parameters. 2446 */ 2447 cbNvEventLog = _4K; 2448 cbVarStore = cbStore / 2 - cbNvEventLog - _4K; 2449 cbFtw = cbVarStore + _4K; 2450 offNvEventLog = cbVarStore; 2451 offFtw = offNvEventLog + cbNvEventLog; 2452 } 2453 2404 2454 uint32_t const cBlocks = (uint32_t)(cbStore / cbBlock); 2405 2455 … … 2407 2457 EFI_GUID GuidVarAuth = EFI_VARSTORE_HEADER_GUID_AUTHENTICATED_VARIABLE; 2408 2458 EFI_FIRMWARE_VOLUME_HEADER FvHdr; RT_ZERO(FvHdr); 2409 EFI_FW_BLOCK_MAP BlockMap; RT_ZERO(BlockMap);2459 EFI_FW_BLOCK_MAP aBlockMap[2]; RT_ZERO(aBlockMap); 2410 2460 EFI_VARSTORE_HEADER VarStoreHdr; RT_ZERO(VarStoreHdr); 2411 2461 … … 2415 2465 FvHdr.u32Signature = RT_H2LE_U32(EFI_FIRMWARE_VOLUME_HEADER_SIGNATURE); 2416 2466 FvHdr.fAttr = RT_H2LE_U32(0x4feff); /** @todo */ 2417 FvHdr.cbFvHdr = RT_H2LE_U16(sizeof(FvHdr) + sizeof( BlockMap));2467 FvHdr.cbFvHdr = RT_H2LE_U16(sizeof(FvHdr) + sizeof(aBlockMap)); 2418 2468 FvHdr.bRevision = EFI_FIRMWARE_VOLUME_HEADER_REVISION; 2419 2469 … … 2424 2474 u16Chksum += RT_LE2H_U16(*pu16++); 2425 2475 2426 /* Block map . */2427 BlockMap.cbBlock = RT_H2LE_U32(cbBlock);2428 BlockMap.cBlocks = RT_H2LE_U32(cBlocks);2429 2430 pu16 = (const uint16_t *)& BlockMap;2431 while (pu16 < (const uint16_t *)& BlockMap + (sizeof(BlockMap) / sizeof(uint16_t)))2476 /* Block map, the second entry remains 0 as it serves the delimiter. */ 2477 aBlockMap[0].cbBlock = RT_H2LE_U32(cbBlock); 2478 aBlockMap[0].cBlocks = RT_H2LE_U32(cBlocks); 2479 2480 pu16 = (const uint16_t *)&aBlockMap[0]; 2481 while (pu16 < (const uint16_t *)&aBlockMap[0] + (sizeof(aBlockMap) / sizeof(uint16_t))) 2432 2482 u16Chksum += RT_LE2H_U16(*pu16++); 2433 2483 2434 FvHdr.u16Chksum = RT_H2LE_U16(u16Chksum);2484 FvHdr.u16Chksum = RT_H2LE_U16(UINT16_MAX - u16Chksum + 1); 2435 2485 2436 2486 /* Variable store header. */ 2437 2487 memcpy(&VarStoreHdr.GuidVarStore, &GuidVarAuth, sizeof(GuidVarAuth)); 2438 VarStoreHdr.cbVarStore = cbStore - sizeof(FvHdr) - sizeof(BlockMap);2488 VarStoreHdr.cbVarStore = RT_H2LE_U32(cbVarStore - sizeof(FvHdr) - sizeof(aBlockMap)); 2439 2489 VarStoreHdr.bFmt = EFI_VARSTORE_HEADER_FMT_FORMATTED; 2440 2490 VarStoreHdr.bState = EFI_VARSTORE_HEADER_STATE_HEALTHY; … … 2443 2493 int rc = RTVfsFileWriteAt(hVfsFile, offStore, &FvHdr, sizeof(FvHdr), NULL); 2444 2494 if (RT_SUCCESS(rc)) 2445 rc = RTVfsFileWriteAt(hVfsFile, offStore + sizeof(FvHdr), & BlockMap, sizeof(BlockMap), NULL);2495 rc = RTVfsFileWriteAt(hVfsFile, offStore + sizeof(FvHdr), &aBlockMap[0], sizeof(aBlockMap), NULL); 2446 2496 if (RT_SUCCESS(rc)) 2447 rc = RTVfsFileWriteAt(hVfsFile, offStore + sizeof(FvHdr) + sizeof( BlockMap), &VarStoreHdr, sizeof(VarStoreHdr), NULL);2497 rc = RTVfsFileWriteAt(hVfsFile, offStore + sizeof(FvHdr) + sizeof(aBlockMap), &VarStoreHdr, sizeof(VarStoreHdr), NULL); 2448 2498 if (RT_SUCCESS(rc)) 2449 2499 { 2450 2500 /* Fill the remainder with 0xff as it would be the case for a real NAND flash device. */ 2451 uint8_t abFF[512]; 2452 memset(&abFF[0], 0xff, sizeof(abFF)); 2453 2454 uint64_t offStart = offStore + sizeof(FvHdr) + sizeof(BlockMap) + sizeof(VarStoreHdr); 2455 uint64_t offEnd = offStore + cbStore; 2456 while ( offStart < offEnd 2457 && RT_SUCCESS(rc)) 2458 { 2459 size_t cbThisWrite = RT_MIN(sizeof(abFF), offEnd - offStart); 2460 rc = RTVfsFileWriteAt(hVfsFile, offStart, &abFF[0], cbThisWrite, NULL); 2461 offStart += cbThisWrite; 2462 } 2463 } 2464 2465 /** @todo FTW region. */ 2501 uint64_t offStart = offStore + sizeof(FvHdr) + sizeof(aBlockMap) + sizeof(VarStoreHdr); 2502 uint64_t offEnd = offStore + cbVarStore; 2503 2504 rc = rtEfiVarStoreFillWithFF(hVfsFile, offStart, offEnd); 2505 } 2506 2507 if ( RT_SUCCESS(rc) 2508 && !(fFlags & RTEFIVARSTORE_CREATE_F_NO_FTW_WORKING_SPACE)) 2509 { 2510 EFI_GUID GuidFtwArea = EFI_WORKING_BLOCK_SIGNATURE_GUID; 2511 EFI_FTW_BLOCK_HEADER FtwHdr; RT_ZERO(FtwHdr); 2512 2513 memcpy(&FtwHdr.GuidSignature, &GuidFtwArea, sizeof(GuidFtwArea)); 2514 FtwHdr.fWorkingBlockValid = RT_H2LE_U32(0xfffffffe); /** @todo */ 2515 FtwHdr.cbWriteQueue = RT_H2LE_U64(0xfe0); /* This comes from the default OVMF variable volume. */ 2516 FtwHdr.u32Chksum = RTCrc32(&FtwHdr, sizeof(FtwHdr)); 2517 2518 /* The area starts with the event log which defaults to 0xff. */ 2519 rc = rtEfiVarStoreFillWithFF(hVfsFile, offNvEventLog, offNvEventLog + cbNvEventLog); 2520 if (RT_SUCCESS(rc)) 2521 { 2522 /* Write the FTW header. */ 2523 rc = RTVfsFileWriteAt(hVfsFile, offFtw, &FtwHdr, sizeof(FtwHdr), NULL); 2524 if (RT_SUCCESS(rc)) 2525 rc = rtEfiVarStoreFillWithFF(hVfsFile, offFtw + sizeof(FtwHdr), offFtw + cbFtw); 2526 } 2527 } 2466 2528 2467 2529 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.