Changeset 99943 in vbox
- Timestamp:
- May 23, 2023 8:34:46 PM (20 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Misc/DevFlashCFI.cpp
r99542 r99943 41 41 #include <iprt/string.h> 42 42 #include <iprt/file.h> 43 #include <iprt/uuid.h> 43 44 44 45 #include "VBoxDD.h" … … 80 81 /** @} */ 81 82 83 /** The namespace the NVRAM content is stored under (historical reasons). */ 84 #define FLASH_CFI_VFS_NAMESPACE "efi" 85 82 86 83 87 /********************************************************************************************************************************* … … 118 122 /** The handle to the MMIO region. */ 119 123 IOMMMIOHANDLE hMmio; 124 125 /** The offset of the block to write. */ 126 uint32_t offBlock; 127 /** Number of bytes to write. */ 128 uint32_t cbWrite; 129 /** The word buffer for the buffered program command (32 16-bit words for each emulated chip). */ 130 uint8_t abProgramBuf[2 * 32 * sizeof(uint16_t)]; 131 132 /** 133 * NVRAM port - LUN\#0. 134 */ 135 struct 136 { 137 /** The base interface we provide the NVRAM driver. */ 138 PDMIBASE IBase; 139 /** The NVRAM driver base interface. */ 140 PPDMIBASE pDrvBase; 141 /** The VFS interface of the driver below for NVRAM state loading and storing. */ 142 PPDMIVFSCONNECTOR pDrvVfs; 143 } Lun0; 120 144 } DEVFLASHCFI; 121 145 /** Pointer to the Flash device state. */ … … 158 182 case FLASH_CFI_CMD_BUFFERED_PROGRAM_SETUP: 159 183 Assert(pThis->bStatus & FLASH_CFI_SR_PROGRAM_ERASE); 160 pThis->u16Cmd = u32Val; 184 pThis->u16Cmd = u32Val; 185 pThis->offBlock = (uint32_t)off; 161 186 pThis->cBusCycle++; 162 187 break; … … 178 203 pThis->u16Cmd = FLASH_CFI_CMD_READ_STATUS_REG; 179 204 pThis->cBusCycle = 0; 205 memset(pThis->pbFlash + off, 0xff, RT_MIN(pThis->cbFlashSize - off, pThis->cbBlockSize)); 180 206 break; 181 207 } … … 183 209 { 184 210 /* Receives the number of words to be transfered. */ 185 pThis->cWordsTransfered = u32Val & 0xffff; 186 pThis->cBusCycle++; 211 pThis->cWordsTransfered = (u32Val & 0xffff) + 1; 212 pThis->cbWrite = pThis->cWordsTransfered * 2 * sizeof(uint16_t); 213 if (pThis->cbWrite <= sizeof(pThis->abProgramBuf)) 214 pThis->cBusCycle++; 215 else 216 AssertReleaseFailed(); 187 217 break; 188 218 } … … 201 231 if ((u32Val & 0xffff) == FLASH_CFI_CMD_BUFFERED_PROGRAM_CONFIRM) 202 232 { 203 /** @todo Write out data to flash. */ 233 if (pThis->offBlock + pThis->cbWrite <= pThis->cbFlashSize) 234 memcpy(pThis->pbFlash + pThis->offBlock, &pThis->abProgramBuf[0], pThis->cbWrite); 204 235 /* Reset to read array. */ 205 236 pThis->cBusCycle = 0; 206 237 pThis->u16Cmd = FLASH_CFI_CMD_ARRAY_READ; 207 238 } 239 else 240 AssertReleaseFailed(); 208 241 } 209 242 else 243 { 244 if ( off >= pThis->offBlock 245 && (off + cb >= pThis->offBlock) 246 && ((off + cb) - pThis->offBlock) <= sizeof(pThis->abProgramBuf)) 247 memcpy(&pThis->abProgramBuf[off - pThis->offBlock], pv, cb); 248 else 249 AssertReleaseFailed(); 210 250 pThis->cWordsTransfered--; 251 } 211 252 break; 212 253 } … … 265 306 266 307 308 /** 309 * @copydoc(PDMIBASE::pfnQueryInterface) 310 */ 311 static DECLCALLBACK(void *) flashR3QueryInterface(PPDMIBASE pInterface, const char *pszIID) 312 { 313 LogFlowFunc(("ENTER: pIBase=%p pszIID=%p\n", pInterface, pszIID)); 314 PDEVFLASHCFI pThis = RT_FROM_MEMBER(pInterface, DEVFLASHCFI, Lun0.IBase); 315 316 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->Lun0.IBase); 317 return NULL; 318 } 319 320 267 321 #if 0 /** @todo Later */ 268 322 /** … … 305 359 pThis->bStatus = FLASH_CFI_SR_PROGRAM_ERASE; /* Prgram/Erase controller is inactive. */ 306 360 pThis->cBusCycle = 0; 361 } 362 363 364 /** 365 * @interface_method_impl{PDMDEVREG,pfnPowerOff} 366 */ 367 static DECLCALLBACK(void) flashR3PowerOff(PPDMDEVINS pDevIns) 368 { 369 PDEVFLASHCFI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVFLASHCFI); 370 371 if (pThis->Lun0.pDrvVfs) 372 { 373 AssertPtr(pThis->pszFlashFile); 374 int rc = pThis->Lun0.pDrvVfs->pfnWriteAll(pThis->Lun0.pDrvVfs, FLASH_CFI_VFS_NAMESPACE, pThis->pszFlashFile, 375 pThis->pbFlash, pThis->cbFlashSize); 376 if (RT_FAILURE(rc)) 377 LogRel(("EFI: Failed to save flash file to NVRAM store: %Rrc\n", rc)); 378 } 379 else if (pThis->pszFlashFile) 380 { 381 RTFILE hFlashFile = NIL_RTFILE; 382 383 int rc = RTFileOpen(&hFlashFile, pThis->pszFlashFile, RTFILE_O_READWRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE); 384 if (RT_SUCCESS(rc)) 385 { 386 rc = RTFileWrite(hFlashFile, pThis->pbFlash, pThis->cbFlashSize, NULL); 387 RTFileClose(hFlashFile); 388 if (RT_FAILURE(rc)) 389 PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to write flash file")); 390 } 391 else 392 PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to open flash file")); 393 } 307 394 } 308 395 … … 353 440 354 441 Assert(iInstance == 0); RT_NOREF1(iInstance); 442 443 /* 444 * Initalize the basic variables so that the destructor always works. 445 */ 446 pThis->Lun0.IBase.pfnQueryInterface = flashR3QueryInterface; 447 355 448 356 449 /* … … 376 469 377 470 /* The default flash device size is 128K. */ 378 uint 32_t cbFlash = 0;379 rc = pHlp->pfnCFGMQueryU 32Def(pCfg, "Size", &cbFlash, 128 * _1K);471 uint64_t cbFlash = 0; 472 rc = pHlp->pfnCFGMQueryU64Def(pCfg, "Size", &cbFlash, 128 * _1K); 380 473 if (RT_FAILURE(rc)) 381 474 return PDMDEV_SET_ERROR(pDevIns, rc, … … 412 505 flashR3Reset(pDevIns); 413 506 414 RTFILE hFlashFile = NIL_RTFILE; 415 rc = RTFileOpen(&hFlashFile, pThis->pszFlashFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 416 if (RT_FAILURE(rc)) 417 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to open flash file")); 418 419 size_t cbRead = 0; 420 rc = RTFileRead(hFlashFile, pThis->pbFlash, pThis->cbFlashSize, &cbRead); 421 RTFileClose(hFlashFile); 422 if (RT_FAILURE(rc)) 423 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to read flash file")); 424 LogRel(("flash-cfi#%u: Read %zu bytes from file (asked for %u)\n.", cbRead, pThis->cbFlashSize, iInstance)); 425 507 /* 508 * NVRAM storage. 509 */ 510 rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->Lun0.IBase, &pThis->Lun0.pDrvBase, "NvramStorage"); 511 if (RT_SUCCESS(rc)) 512 { 513 pThis->Lun0.pDrvVfs = PDMIBASE_QUERY_INTERFACE(pThis->Lun0.pDrvBase, PDMIVFSCONNECTOR); 514 if (!pThis->Lun0.pDrvVfs) 515 return PDMDevHlpVMSetError(pDevIns, VERR_PDM_MISSING_INTERFACE_BELOW, RT_SRC_POS, N_("NVRAM storage driver is missing VFS interface below")); 516 } 517 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 518 rc = VINF_SUCCESS; /* Missing driver is no error condition. */ 519 else 520 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Can't attach Nvram Storage driver")); 521 522 if (pThis->Lun0.pDrvVfs) 523 { 524 AssertPtr(pThis->pszFlashFile); 525 rc = pThis->Lun0.pDrvVfs->pfnQuerySize(pThis->Lun0.pDrvVfs, FLASH_CFI_VFS_NAMESPACE, pThis->pszFlashFile, &cbFlash); 526 if (RT_SUCCESS(rc)) 527 { 528 if (cbFlash <= pThis->cbFlashSize) 529 rc = pThis->Lun0.pDrvVfs->pfnReadAll(pThis->Lun0.pDrvVfs, FLASH_CFI_VFS_NAMESPACE, pThis->pszFlashFile, 530 pThis->pbFlash, pThis->cbFlashSize); 531 else 532 return PDMDEV_SET_ERROR(pDevIns, VERR_BUFFER_OVERFLOW, N_("Configured flash size is too small to fit the saved NVRAM content")); 533 } 534 } 535 else if (pThis->pszFlashFile) 536 { 537 RTFILE hFlashFile = NIL_RTFILE; 538 rc = RTFileOpen(&hFlashFile, pThis->pszFlashFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 539 if (RT_FAILURE(rc)) 540 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to open flash file")); 541 542 size_t cbRead = 0; 543 rc = RTFileRead(hFlashFile, pThis->pbFlash, pThis->cbFlashSize, &cbRead); 544 RTFileClose(hFlashFile); 545 if (RT_FAILURE(rc)) 546 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to read flash file")); 547 548 LogRel(("flash-cfi#%u: Read %zu bytes from file (asked for %u)\n.", cbRead, pThis->cbFlashSize, iInstance)); 549 } 426 550 427 551 /* … … 479 603 /* .pfnQueryInterface = */ NULL, 480 604 /* .pfnInitComplete = */ NULL, 481 /* .pfnPowerOff = */ NULL,605 /* .pfnPowerOff = */ flashR3PowerOff, 482 606 /* .pfnSoftReset = */ NULL, 483 607 /* .pfnReserved0 = */ NULL,
Note:
See TracChangeset
for help on using the changeset viewer.