Changeset 4388 in vbox for trunk/src/VBox/VMM/MMPhys.cpp
- Timestamp:
- Aug 27, 2007 2:26:05 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/MMPhys.cpp
r4071 r4388 278 278 * This must be cbRange bytes big. 279 279 * It will be copied and doesn't have to stick around. 280 * It will be copied and doesn't have to stick around if fShadow is clear. 281 * @param fShadow Whether to emulate ROM shadowing. This involves leaving 282 * the ROM writable for a while during the POST and refreshing 283 * it at reset. When this flag is set, the memory pointed to by 284 * pvBinary has to stick around for the lifespan of the VM. 280 285 * @param pszDesc Pointer to description string. This must not be freed. 281 286 * @remark There is no way to remove the rom, automatically on device cleanup or 282 287 * manually from the device yet. At present I doubt we need such features... 283 288 */ 284 MMR3DECL(int) MMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const void *pvBinary, const char *pszDesc) 289 MMR3DECL(int) MMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const void *pvBinary, 290 bool fShadow, const char *pszDesc) 285 291 { 286 292 /* … … 340 346 memcpy(pvCopy, pvBinary, cbRange); 341 347 342 /** @note we rely on the MM_RAM_FLAGS_ROM flag in PGMPhysRead now. Don't change to reserved! */ 343 /** @todo r=bird: Noone ever talked about changing *to* _RESERVED. The question is whether 344 * we should *clear* _RESERVED. I've no idea what the state of that flag is for ROM areas right 345 * now, but I will find out later. */ 348 const unsigned fSet = fShadow ? MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_MMIO2 : MM_RAM_FLAGS_ROM; 346 349 for (; iPage < iPageEnd; iPage++) 347 pCur->aPhysPages[iPage].Phys |= MM_RAM_FLAGS_ROM; /** @todo should be clearing _RESERVED? */ 348 int rc = PGMR3PhysSetFlags(pVM, GCPhys, cbRange, MM_RAM_FLAGS_ROM, ~0); /** @todo should be clearing _RESERVED? */ 350 { 351 pCur->aPhysPages[iPage].Phys &= ~MM_RAM_FLAGS_RESERVED; 352 pCur->aPhysPages[iPage].Phys |= fSet; 353 } 354 int rc = PGMR3PhysSetFlags(pVM, GCPhys, cbRange, fSet, ~MM_RAM_FLAGS_RESERVED); 349 355 AssertRC(rc); 350 356 if (VBOX_SUCCESS(rc)) 351 357 { 352 358 /* 353 * Prevent changes to the ROM memory when executing in raw mode by 354 * registering a GC only write access handler. 359 * To prevent the shadow page table mappings from being RW in raw-mode, we 360 * must currently employ a little hack. We register an write access handler 361 * and thereby ensures a RO mapping of the pages. This is NOT very nice, 362 * and wasn't really my intention when writing the code, consider it a PGM bug. 355 363 * 356 364 * ASSUMES that REMR3NotifyPhysRomRegister doesn't call cpu_register_physical_memory … … 360 368 NULL, NULL, 361 369 NULL, "pgmGuestROMWriteHandler", 0, 362 NULL, "pgmGuestROMWriteHandler", 0, "ROM Write Access Handler");370 NULL, "pgmGuestROMWriteHandler", 0, pszDesc); 363 371 AssertRC(rc); 364 372 } 365 373 366 REMR3NotifyPhysRomRegister(pVM, GCPhys, cbRange, pvCopy); 374 /* 375 * Create a ROM range it so we can make a 'info rom' thingy and more importantly 376 * reload and protect/unprotect shadow ROM correctly. 377 */ 378 if (VBOX_SUCCESS(rc)) 379 { 380 PMMROMRANGE pRomRange = (PMMROMRANGE)MMR3HeapAlloc(pVM, MM_TAG_MM, sizeof(*pRomRange)); 381 AssertReturn(pRomRange, VERR_NO_MEMORY); 382 pRomRange->GCPhys = GCPhys; 383 pRomRange->cbRange = cbRange; 384 pRomRange->pszDesc = pszDesc; 385 pRomRange->fShadow = fShadow; 386 pRomRange->fWritable = fShadow; 387 pRomRange->pvBinary = fShadow ? pvBinary : NULL; 388 pRomRange->pvCopy = pvCopy; 389 390 /* sort it for 'info rom' readability. */ 391 PMMROMRANGE pPrev = NULL; 392 PMMROMRANGE pCur = pVM->mm.s.pRomHead; 393 while (pCur && pCur->GCPhys < GCPhys) 394 { 395 pPrev = pCur; 396 pCur = pCur->pNext; 397 } 398 pRomRange->pNext = pCur; 399 if (pPrev) 400 pPrev->pNext = pRomRange; 401 else 402 pVM->mm.s.pRomHead = pRomRange; 403 } 404 405 REMR3NotifyPhysRomRegister(pVM, GCPhys, cbRange, pvCopy, fShadow); 367 406 return rc; /* we're sloppy with error cleanup here, but we're toast anyway if this fails. */ 368 407 } … … 438 477 * This usually means the size of the first contigous block of physical memory. 439 478 * 440 * @returns 441 * @param pVM 479 * @returns The guest base RAM size. 480 * @param pVM The VM handle. 442 481 * @thread Any. 443 482 */ … … 447 486 } 448 487 488 489 /** 490 * Called by MMR3Reset to reset the shadow ROM. 491 * 492 * Resetting involves reloading the ROM into RAM and make it 493 * wriable again (as it was made read only at the end of the POST). 494 * 495 * @param pVM The VM handle. 496 */ 497 void mmR3PhysRomReset(PVM pVM) 498 { 499 for (PMMROMRANGE pCur = pVM->mm.s.pRomHead; pCur; pCur = pCur->pNext) 500 if (pCur->fShadow) 501 { 502 memcpy(pCur->pvCopy, pCur->pvBinary, pCur->cbRange); 503 if (!pCur->fWritable) 504 { 505 int rc = PGMHandlerPhysicalDeregister(pVM, pCur->GCPhys); 506 AssertRC(rc); 507 pCur->fWritable = true; 508 509 rc = PGMR3PhysSetFlags(pVM, pCur->GCPhys, pCur->cbRange, MM_RAM_FLAGS_MMIO2, ~0); /* ROM -> ROM + MMIO2 */ 510 AssertRC(rc); 511 512 REMR3NotifyPhysRomRegister(pVM, pCur->GCPhys, pCur->cbRange, pCur->pvCopy, true /* read-write now */); 513 } 514 } 515 } 516 517 518 /** 519 * Write-protects a shadow ROM range. 520 * 521 * This is called late in the POST for shadow ROM ranges. 522 * 523 * @returns VBox status code. 524 * @param pVM The VM handle. 525 * @param GCPhys Start of the registered shadow ROM range 526 * @param cbRange The length of the registered shadow ROM range. 527 * This can be NULL (not sure about the BIOS interface yet). 528 */ 529 MMR3DECL(int) MMR3PhysRomProtect(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange) 530 { 531 for (PMMROMRANGE pCur = pVM->mm.s.pRomHead; pCur; pCur = pCur->pNext) 532 if ( pCur->GCPhys == GCPhys 533 && ( pCur->cbRange == cbRange 534 || !cbRange)) 535 { 536 if (pCur->fWritable) 537 { 538 cbRange = pCur->cbRange; 539 int rc = PGMR3HandlerPhysicalRegister(pVM, PGMPHYSHANDLERTYPE_PHYSICAL_WRITE, GCPhys, GCPhys + cbRange - 1, 540 NULL, NULL, 541 NULL, "pgmGuestROMWriteHandler", 0, 542 NULL, "pgmGuestROMWriteHandler", 0, pCur->pszDesc); 543 AssertRCReturn(rc, rc); 544 pCur->fWritable = false; 545 546 rc = PGMR3PhysSetFlags(pVM, GCPhys, cbRange, 0, ~MM_RAM_FLAGS_MMIO2); /* ROM + MMIO2 -> ROM */ 547 AssertRCReturn(rc, rc); 548 /* Don't bother with the MM page flags here because I don't think they are 549 really used beyond conflict checking at ROM, RAM, Reservation, etc. */ 550 551 REMR3NotifyPhysRomRegister(pVM, GCPhys, cbRange, pCur->pvCopy, false /* read-only now */); 552 } 553 return VINF_SUCCESS; 554 } 555 AssertMsgFailed(("GCPhys=%VGp cbRange=%#x\n", GCPhys, cbRange)); 556 return VERR_INVALID_PARAMETER; 557 } 558
Note:
See TracChangeset
for help on using the changeset viewer.