Changeset 53430 in vbox for trunk/include/VBox
- Timestamp:
- Dec 3, 2014 1:18:41 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 97118
- Location:
- trunk/include/VBox
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/sup.h
r53269 r53430 4 4 5 5 /* 6 * Copyright (C) 2006-201 2Oracle Corporation6 * Copyright (C) 2006-2014 Oracle Corporation 7 7 * 8 8 * This file is part of VirtualBox Open Source Edition (OSE), as … … 339 339 * This is index by ApicId via the aiCpuFromApicId table. 340 340 * 341 * The clock and frequency information is updated for all CPUs if u32Mode 342 * is SUPGIPMODE_ASYNC_TSC, otherwise (SUPGIPMODE_SYNC_TSC) only the first 343 * entry is updated. */ 341 * The clock and frequency information is updated for all CPUs if @c u32Mode 342 * is SUPGIPMODE_ASYNC_TSC. If @c u32Mode is SUPGIPMODE_SYNC_TSC only the first 343 * entry is updated. If @c u32Mode is SUPGIPMODE_SYNC_TSC the TSC frequency in 344 * @c u64CpuHz is copied to all CPUs. */ 344 345 SUPGIPCPU aCPUs[1]; 345 346 } SUPGLOBALINFOPAGE; … … 374 375 /** Each core has it's own TSC. */ 375 376 SUPGIPMODE_ASYNC_TSC, 377 /** The TSC of the cores are non-stop and have a constant frequency. */ 378 SUPGIPMODE_INVARIANT_TSC, 376 379 /** The usual 32-bit hack. */ 377 380 SUPGIPMODE_32BIT_HACK = 0x7fffffff … … 424 427 SUPDECL(PSUPGLOBALINFOPAGE) SUPGetGIP(void); 425 428 426 #ifdef ___iprt_asm_amd64_x86_h 429 427 430 /** 428 431 * Gets the TSC frequency of the calling CPU. … … 435 438 unsigned iCpu; 436 439 437 if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC ))440 if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC || !pGip->u64CpuHz)) 438 441 return UINT64_MAX; 439 442 440 if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC) 443 if ( pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC 444 || pGip->u32Mode == SUPGIPMODE_SYNC_TSC) 441 445 iCpu = 0; 442 446 else 443 447 { 448 Assert(pGip->u32Mode == SUPGIPMODE_ASYNC_TSC); 444 449 iCpu = pGip->aiCpuFromApicId[ASMGetApicId()]; 445 450 if (iCpu >= pGip->cCpus) … … 449 454 return pGip->aCPUs[iCpu].u64CpuHz; 450 455 } 451 #endif 456 452 457 453 458 /** … … 1468 1473 1469 1474 /** 1470 * Gets the GIP mode name given the GIP mode.1471 * 1472 * @returns The name 1473 * @param enmGipMode The GIP mode.1475 * Gets the descriptive GIP mode name. 1476 * 1477 * @returns The name. 1478 * @param pGip Pointer to the GIP. 1474 1479 */ 1475 1480 DECLINLINE(const char *) SUPGetGIPModeName(PSUPGLOBALINFOPAGE pGip) 1476 1481 { 1477 Assert (pGip);1482 AssertReturn(pGip, NULL); 1478 1483 switch (pGip->u32Mode) 1479 1484 { 1480 /* case SUPGIPMODE_INVARIANT_TSC: return "Invariant"; */1481 case SUPGIPMODE_SYNC_TSC: 1482 case SUPGIPMODE_ASYNC_TSC: 1483 case SUPGIPMODE_INVALID: 1484 default: 1485 case SUPGIPMODE_INVARIANT_TSC: return "Invariant"; 1486 case SUPGIPMODE_SYNC_TSC: return "Synchronous"; 1487 case SUPGIPMODE_ASYNC_TSC: return "Asynchronous"; 1488 case SUPGIPMODE_INVALID: return "Invalid"; 1489 default: return "???"; 1485 1490 } 1486 1491 } … … 1497 1502 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 1498 1503 if ( pGip 1499 && pGip->u32Mode == SUPGIPMODE_ SYNC_TSC) /** @todo use INVARIANT_TSC */1504 && pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC) 1500 1505 { 1501 1506 uint64_t uLo; … … 1506 1511 1507 1512 /* Arbitrary tolerance threshold, tweak later if required, perhaps 1508 more tolerance on higher frequencies and less tolerance on lower. */1513 more tolerance on lower frequencies and less tolerance on higher. */ 1509 1514 uLo = (pGip->u64CpuHz << 10) / 1025; 1510 1515 uHi = pGip->u64CpuHz + (pGip->u64CpuHz - uLo); 1511 1516 if ( u64CpuHz < uLo 1512 1517 || u64CpuHz > uHi) 1513 {1514 1518 return false; 1515 }1516 1519 return true; 1517 1520 } 1518 1521 return false; 1519 1522 } 1520 1521 1523 1522 1524 … … 1531 1533 * applied or not (optional, can be NULL). 1532 1534 * 1533 * @remarks Maybe called with interrupts disabled! 1535 * @note If you change the delta calculation made here, make sure to update the 1536 * assembly version in sup.mac! Also update supdrvGipMpEvent() while 1537 * re-adjusting deltas while choosing a new GIP master. 1538 * @remarks Maybe called with interrupts disabled in ring-0! 1534 1539 */ 1535 1540 DECLINLINE(int) SUPTscDeltaApply(PSUPGLOBALINFOPAGE pGip, uint64_t *puTsc, uint16_t idApic, bool *pfDeltaApplied) … … 1562 1567 1563 1568 /** 1564 * Reads the delta-adjusted TSC. 1569 * Gets the delta-adjusted TSC, must only be called when GIP mode is invariant 1570 * (i.e. when TSC deltas are likely to be computed and available). 1571 * 1572 * In other GIP modes, like async, we don't bother with computing TSC deltas and 1573 * therefore it is meaningless to call this function, use SUPReadTSC() instead. 1565 1574 * 1566 1575 * @returns VBox status code. … … 1572 1581 * updated for other failures. 1573 1582 * 1574 * @remarks May be called with interrupts disabled !1575 */ 1576 DECLINLINE(int) SUP ReadTsc(uint64_t *puTsc, uint16_t *pidApic)1583 * @remarks May be called with interrupts disabled in ring-0! 1584 */ 1585 DECLINLINE(int) SUPGetTsc(uint64_t *puTsc, uint16_t *pidApic) 1577 1586 { 1578 1587 #ifdef IN_RING3 … … 1599 1608 return fDeltaApplied ? VINF_SUCCESS : VERR_SUPDRV_TSC_READ_FAILED; 1600 1609 #endif 1610 } 1611 1612 1613 /** 1614 * Reads the host TSC value. 1615 * If applicable, normalizes the host TSC value with intercpu TSC deltas. 1616 * 1617 * @returns the TSC value. 1618 * 1619 * @remarks Requires GIP to be initialized. 1620 */ 1621 DECLINLINE(uint64_t) SUPReadTsc(void) 1622 { 1623 if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC) 1624 { 1625 uint64_t u64Tsc = UINT64_MAX; 1626 int rc = SUPGetTsc(&u64Tsc, NULL /* pidApic */); 1627 AssertRC(rc); 1628 return u64Tsc; 1629 } 1630 else 1631 return ASMReadTSC(); 1601 1632 } 1602 1633 -
trunk/include/VBox/sup.mac
r53269 r53430 123 123 endstruc 124 124 125 ;; 126 ; Macro to apply per-CPU TSC delta to the TSC value read in through rdtsc. 127 ; 128 ; @param %1 The pSupGipCpu pointer 129 ; @remarks edx:eax contains the 64-bit TSC value to apply the delta to. 130 %macro SUPTscDeltaApply 1 131 ; Check if we have a valid TSC-delta, i.e. != INT64_MAX. 132 cmp dword [%1 + SUPGIPCPU.i64TSCDelta + 4], 0xffffffff 133 jne %%valid_delta 134 cmp dword [%1 + SUPGIPCPU.i64TSCDelta], 0x7fffffff 135 je %%done 136 %%valid_delta: 137 ; Subtract the delta from edx:eax 138 sub eax, dword [%1 + SUPGIPCPU.i64TSCDelta + 4] 139 sbb edx, dword [%1 + SUPGIPCPU.i64TSCDelta] 140 %%done: 141 %endmacro 125 142 126 143 %endif
Note:
See TracChangeset
for help on using the changeset viewer.