- Timestamp:
- Aug 27, 2007 2:26:05 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/mm.h
r4071 r4388 39 39 * @{ 40 40 */ 41 /** Reserved - No RAM, but can be used for MMIO or ROM.41 /** Reserved - Not RAM, ROM nor MMIO2. 42 42 * If this bit is cleared the memory is assumed to be some kind of RAM. 43 * MMIO2 will for instance not set this flag, neither will ROM (wrong it's set :/). Normal MMIO44 * may set it but that depends on whether the RAM range was created specially45 * for the MMIO or not.46 * N.B. The current implementation will always reserve backing memory for reserved47 * ranges to simplify things.43 * Normal MMIO may set it but that depends on whether the RAM range was 44 * created specially for the MMIO or not. 45 * 46 * @remarks The current implementation will always reserve backing 47 * memory for reserved ranges to simplify things. 48 48 */ 49 49 #define MM_RAM_FLAGS_RESERVED BIT(0) … … 51 51 * The page have a HC physical address which contains the BIOS code. All write 52 52 * access is trapped and ignored. 53 * 54 * HACK: Writable shadow ROM is indicated by both ROM and MMIO2 being 55 * set. (We're out of bits.) 53 56 */ 54 57 #define MM_RAM_FLAGS_ROM BIT(1) … … 61 64 * The virtualization is performed using real memory and only catching 62 65 * a few accesses for like keeping track for dirty pages. 66 * @remark Involved in the shadow ROM hack. 63 67 */ 64 68 #define MM_RAM_FLAGS_MMIO2 BIT(3) … … 659 663 660 664 /** 665 * Reset notification. 666 * 667 * MM will reload shadow ROMs into RAM at this point and make 668 * the ROM writable. 669 * 670 * @param pVM The VM handle. 671 */ 672 MMR3DECL(void) MMR3Reset(PVM pVM); 673 674 /** 661 675 * Convert HC Physical address to HC Virtual address. 662 676 * … … 920 934 * This must be cbRange bytes big. 921 935 * It will be copied and doesn't have to stick around. 936 * It will be copied and doesn't have to stick around if fShadow is clear. 937 * @param fShadow Whether to emulate ROM shadowing. This involves leaving 938 * the ROM writable for a while during the POST and refreshing 939 * it at reset. When this flag is set, the memory pointed to by 940 * pvBinary has to stick around for the lifespan of the VM. 922 941 * @param pszDesc Pointer to description string. This must not be freed. 923 942 * @remark There is no way to remove the rom, automatically on device cleanup or … … 925 944 * @thread The Emulation Thread. 926 945 */ 927 MMR3DECL(int) MMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const void *pvBinary, const char *pszDesc); 946 MMR3DECL(int) MMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc); 947 948 /** 949 * Write-protects a shadow ROM range. 950 * 951 * This is called late in the POST for shadow ROM ranges. 952 * 953 * @returns VBox status code. 954 * @param pVM The VM handle. 955 * @param GCPhys Start of the registered shadow ROM range 956 * @param cbRange The length of the registered shadow ROM range. 957 * This can be NULL (not sure about the BIOS interface yet). 958 */ 959 MMR3DECL(int) MMR3PhysRomProtect(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange); 928 960 929 961 /** -
trunk/include/VBox/rem.h
r4071 r4388 297 297 * @param cb The size of the ROM. 298 298 * @param pvCopy Pointer to the ROM copy. 299 */ 300 REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvCopy); 299 * @param fShadow Whether it's currently writable shadow ROM or normal readonly ROM. 300 * This function will be called when ever the protection of the 301 * shadow ROM changes (at reset and end of POST). 302 */ 303 REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvCopy, bool fShadow); 301 304 302 305 /** -
trunk/src/VBox/VMM/MM.cpp
r4071 r4388 336 336 337 337 /** 338 * Reset notification. 339 * 340 * MM will reload shadow ROMs into RAM at this point and make 341 * the ROM writable. 342 * 343 * @param pVM The VM handle. 344 */ 345 MMR3DECL(void) MMR3Reset(PVM pVM) 346 { 347 mmR3PhysRomReset(pVM); 348 } 349 350 351 /** 338 352 * Execute state save operation. 339 353 * -
trunk/src/VBox/VMM/MMInternal.h
r4071 r4388 503 503 504 504 /** 505 * A registered Rom range. 506 * 507 * This is used to track ROM registrations both for debug reasons 508 * and for resetting shadow ROM at reset. 509 * 510 * This is allocated of the MMR3Heap and thus only accessibel from ring-3. 511 */ 512 typedef struct MMROMRANGE 513 { 514 /** Pointer to the next */ 515 struct MMROMRANGE *pNext; 516 /** Address of the range. */ 517 RTGCPHYS GCPhys; 518 /** Size of the range. */ 519 uint32_t cbRange; 520 /** Shadow ROM? */ 521 bool fShadow; 522 /** Is the shadow ROM currently wriable? */ 523 bool fWritable; 524 /** The address of the virgin ROM image for shadow ROM. */ 525 const void *pvBinary; 526 /** The address of the guest RAM that's shadowing the ROM. (lazy bird) */ 527 void *pvCopy; 528 /** The ROM description. */ 529 const char *pszDesc; 530 } MMROMRANGE; 531 /** Pointer to a ROM range. */ 532 typedef MMROMRANGE *PMMROMRANGE; 533 534 535 /** 505 536 * Hypervisor memory mapping type. 506 537 */ … … 636 667 /** Pointer to the base RAM. */ 637 668 HCPTRTYPE(void *) pvRamBaseHC; 669 /** The head of the ROM ranges. */ 670 R3PTRTYPE(PMMROMRANGE) pRomHead; 638 671 639 672 /** Pointer to the MM R3 Heap. */ … … 660 693 661 694 const char *mmR3GetTagName(MMTAG enmTag); 695 696 void mmR3PhysRomReset(PVM pVM); 662 697 663 698 /** -
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 -
trunk/src/VBox/VMM/PDMDevice.cpp
r4382 r4388 1488 1488 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc, pszDesc)); 1489 1489 1490 AssertReturn(!fShadow, VERR_NOT_IMPLEMENTED); /* be patient. */ 1491 int rc = MMR3PhysRomRegister(pDevIns->Internal.s.pVMHC, pDevIns, GCPhysStart, cbRange, pvBinary, pszDesc); 1490 int rc = MMR3PhysRomRegister(pDevIns->Internal.s.pVMHC, pDevIns, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc); 1492 1491 1493 1492 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); … … 3598 3597 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange)); 3599 3598 3600 AssertFailed(); /* be patient. */ 3601 int rc = VERR_NOT_IMPLEMENTED; 3599 int rc = MMR3PhysRomProtect(pDevIns->Internal.s.pVMHC, GCPhysStart, cbRange); 3602 3600 3603 3601 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); -
trunk/src/VBox/VMM/PGM.cpp
r4187 r4388 1282 1282 if (pRam->aHCPhys[iPage] & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2)) 1283 1283 { 1284 /* shadow ram is reloaded elsewhere. */ 1284 1285 Log4(("PGMR3Reset: not clearing phys page %RGp due to flags %RHp\n", pRam->GCPhys + (iPage << PAGE_SHIFT), pRam->aHCPhys[iPage] & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_MMIO))); 1285 1286 continue; -
trunk/src/VBox/VMM/VM.cpp
r4296 r4388 1744 1744 PGMR3Reset(pVM); /* We clear VM RAM in PGMR3Reset. It's vital PDMR3Reset is executed 1745 1745 * _afterwards_. E.g. ACPI sets up RAM tables during init/reset. */ 1746 MMR3Reset(pVM); 1746 1747 PDMR3Reset(pVM); 1747 1748 SELMR3Reset(pVM); -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r4071 r4388 21 21 * Since this flag is currently incorrectly kept set for ROM regions we will 22 22 * have to ignore it for now so we don't break stuff. 23 * 24 * @todo this has been fixed now I believe, remove this hack. 23 25 */ 24 26 #define PGM_IGNORE_RAM_FLAGS_RESERVED … … 736 738 case MM_RAM_FLAGS_ROM: 737 739 case MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_RESERVED: 740 //case MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_MMIO2: /* = shadow */ - //MMIO2 isn't in the mask. 738 741 case MM_RAM_FLAGS_PHYSICAL_WRITE: 739 case MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_PHYSICAL_WRITE: 742 case MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_PHYSICAL_WRITE: // MMIO2 isn't in the mask. 740 743 case MM_RAM_FLAGS_VIRTUAL_WRITE: 741 744 { … … 1000 1003 { 1001 1004 /* 1002 * Normal memory .1005 * Normal memory, MMIO2 or writable shadow ROM. 1003 1006 */ 1004 1007 case 0: 1005 1008 case MM_RAM_FLAGS_MMIO2: 1009 case MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_MMIO2: /* shadow rom */ 1006 1010 { 1007 1011 #ifdef IN_GC -
trunk/src/recompiler/VBoxREMWrapper.cpp
r4071 r4388 338 338 static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysRamChunkRegister)(PVM, RTGCPHYS, RTUINT, RTHCUINTPTR, unsigned); 339 339 static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysReserve)(PVM, RTGCPHYS, RTUINT); 340 static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysRomRegister)(PVM, RTGCPHYS, RTUINT, void * );340 static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysRomRegister)(PVM, RTGCPHYS, RTUINT, void *, bool); 341 341 static DECLCALLBACKPTR(void, pfnREMR3NotifyHandlerPhysicalModify)(PVM, PGMPHYSHANDLERTYPE, RTGCPHYS, RTGCPHYS, RTGCPHYS, bool, void *); 342 342 static DECLCALLBACKPTR(void, pfnREMR3NotifyHandlerPhysicalRegister)(PVM, PGMPHYSHANDLERTYPE, RTGCPHYS, RTGCPHYS, bool); … … 411 411 { REMPARMDESC_FLAGS_INT, sizeof(RTUINT), NULL }, 412 412 { REMPARMDESC_FLAGS_INT, sizeof(void *), NULL } 413 { REMPARMDESC_FLAGS_INT, sizeof(bool), NULL } 413 414 }; 414 415 static const REMPARMDESC g_aArgsNotifyHandlerPhysicalModify[] = … … 1982 1983 } 1983 1984 1984 REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvCopy )1985 REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvCopy, bool fShadow) 1985 1986 { 1986 1987 #ifndef USE_REM_STUBS 1987 1988 Assert(VALID_PTR(pfnREMR3NotifyPhysRomRegister)); 1988 pfnREMR3NotifyPhysRomRegister(pVM, GCPhys, cb, pvCopy );1989 pfnREMR3NotifyPhysRomRegister(pVM, GCPhys, cb, pvCopy, fShadow); 1989 1990 #endif 1990 1991 } -
trunk/src/recompiler/VBoxRecompiler.c
r4381 r4388 2790 2790 * @param cb The size of the ROM. 2791 2791 * @param pvCopy Pointer to the ROM copy. 2792 */ 2793 REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvCopy) 2792 * @param fShadow Whether it's currently writable shadow ROM or normal readonly ROM. 2793 * This function will be called when ever the protection of the 2794 * shadow ROM changes (at reset and end of POST). 2795 */ 2796 REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvCopy, bool fShadow) 2794 2797 { 2795 2798 #if defined(PGM_DYNAMIC_RAM_ALLOC) && !defined(REM_PHYS_ADDR_IN_TLB) 2796 2799 uint32_t i; 2797 2800 #endif 2798 Log(("REMR3NotifyPhysRomRegister: GCPhys=%VGp cb=%d pvCopy=%p \n", GCPhys, cb, pvCopy));2801 Log(("REMR3NotifyPhysRomRegister: GCPhys=%VGp cb=%d pvCopy=%p fShadow=%RTbool\n", GCPhys, cb, pvCopy, fShadow)); 2799 2802 VM_ASSERT_EMT(pVM); 2800 2803 … … 2815 2818 2816 2819 #ifdef REM_PHYS_ADDR_IN_TLB 2817 cpu_register_physical_memory(GCPhys, cb, GCPhys | IO_MEM_ROM);2820 cpu_register_physical_memory(GCPhys, cb, GCPhys | (fShadow ? 0 : IO_MEM_ROM)); 2818 2821 #elif defined(PGM_DYNAMIC_RAM_ALLOC) 2819 cpu_register_physical_memory(GCPhys, cb, GCPhys | IO_MEM_ROM);2822 cpu_register_physical_memory(GCPhys, cb, GCPhys | (fShadow ? 0 : IO_MEM_ROM)); 2820 2823 AssertRelease(pVM->rem.s.cPhysRegistrations < REM_MAX_PHYS_REGISTRATIONS); 2821 2824 for (i = 0; i < pVM->rem.s.cPhysRegistrations; i++) … … 2837 2840 #else 2838 2841 AssertRelease(phys_ram_base); 2839 cpu_register_physical_memory(GCPhys, cb, ((uintptr_t)pvCopy - (uintptr_t)phys_ram_base) | IO_MEM_ROM);2842 cpu_register_physical_memory(GCPhys, cb, ((uintptr_t)pvCopy - (uintptr_t)phys_ram_base) | (fShadow ? 0 : IO_MEM_ROM)); 2840 2843 #endif 2841 2844
Note:
See TracChangeset
for help on using the changeset viewer.