Changeset 58466 in vbox for trunk/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/HpetTimerDxe/HpetTimer.c
- Timestamp:
- Oct 29, 2015 4:30:44 AM (9 years ago)
- Location:
- trunk/src/VBox/Devices/EFI/Firmware
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/Firmware
- Property svn:mergeinfo changed
/vendor/edk2/current merged: 103769-103776
- Property svn:mergeinfo changed
-
trunk/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/HpetTimerDxe/HpetTimer.c
r58459 r58466 53 53 54 54 @param This The EFI_TIMER_ARCH_PROTOCOL instance. 55 @param NotifyFunction The function to call when a timer interrupt fires. 56 This function executes at TPL_HIGH_LEVEL. The DXE 57 Core will register a handler for the timer interrupt, 58 so it can know how much time has passed. This 59 information is used to signal timer based events. 55 @param NotifyFunction The function to call when a timer interrupt fires. 56 This function executes at TPL_HIGH_LEVEL. The DXE 57 Core will register a handler for the timer interrupt, 58 so it can know how much time has passed. This 59 information is used to signal timer based events. 60 60 NULL will unregister the handler. 61 61 … … 91 91 @param This The EFI_TIMER_ARCH_PROTOCOL instance. 92 92 @param TimerPeriod The rate to program the timer interrupt in 100 nS units. 93 If the timer hardware is not programmable, then 94 EFI_UNSUPPORTED is returned. If the timer is programmable, 95 then the timer period will be rounded up to the nearest 96 timer period that is supported by the timer hardware. 97 If TimerPeriod is set to 0, then the timer interrupts 93 If the timer hardware is not programmable, then 94 EFI_UNSUPPORTED is returned. If the timer is programmable, 95 then the timer period will be rounded up to the nearest 96 timer period that is supported by the timer hardware. 97 If TimerPeriod is set to 0, then the timer interrupts 98 98 will be disabled. 99 99 … … 143 143 144 144 @retval EFI_SUCCESS The soft timer interrupt was generated. 145 @retval EFI_UNSUPPORTEDT The platform does not support the generation of soft 145 @retval EFI_UNSUPPORTEDT The platform does not support the generation of soft 146 146 timer interrupts. 147 147 … … 152 152 IN EFI_TIMER_ARCH_PROTOCOL *This 153 153 ); 154 154 155 155 /// 156 156 /// The handle onto which the Timer Architectural Protocol will be installed. … … 223 223 224 224 /// 225 /// Cached state of the Configuration register for the HPET Timer managed by 225 /// Cached state of the Configuration register for the HPET Timer managed by 226 226 /// this driver. Caching the state reduces the number of times the configuration 227 227 /// register is read. … … 278 278 ) 279 279 { 280 mHpetGeneralConfiguration.Bits.MainCounterEnable = Enable ? 1 : 0; 280 mHpetGeneralConfiguration.Bits.MainCounterEnable = Enable ? 1 : 0; 281 281 HpetWrite (HPET_GENERAL_CONFIGURATION_OFFSET, mHpetGeneralConfiguration.Uint64); 282 282 } … … 287 287 If a notification function is registered, then the amount of time since the last 288 288 HPET interrupt is passed to that notification function in 100 ns units. The HPET 289 time is updated to generate another interrupt in the required time period. 289 time is updated to generate another interrupt in the required time period. 290 290 291 291 @param InterruptType The type of interrupt that occured. … … 323 323 // 324 324 HpetEnable (FALSE); 325 325 326 326 // 327 327 // Capture main counter value … … 364 364 // 365 365 HpetEnable (TRUE); 366 366 367 367 // 368 368 // Check to see if there is a registered notification function … … 370 370 if (mTimerNotifyFunction != NULL) { 371 371 // 372 // Compute time since last notification in 100 ns units (10 ^ -7) 372 // Compute time since last notification in 100 ns units (10 ^ -7) 373 373 // 374 374 if (MainCounter > mPreviousMainCounter) { … … 387 387 Delta & mCounterMask, 388 388 mHpetGeneralCapabilities.Bits.CounterClockPeriod 389 ), 389 ), 390 390 100000000 391 391 ); 392 392 393 393 // 394 394 // Call registered notification function passing in the time since the last 395 395 // interrupt in 100 ns units. 396 // 396 // 397 397 mTimerNotifyFunction (TimerPeriod); 398 398 } 399 399 400 400 // 401 401 // Save main counter value … … 418 418 419 419 @param This The EFI_TIMER_ARCH_PROTOCOL instance. 420 @param NotifyFunction The function to call when a timer interrupt fires. 421 This function executes at TPL_HIGH_LEVEL. The DXE 422 Core will register a handler for the timer interrupt, 423 so it can know how much time has passed. This 424 information is used to signal timer based events. 420 @param NotifyFunction The function to call when a timer interrupt fires. 421 This function executes at TPL_HIGH_LEVEL. The DXE 422 Core will register a handler for the timer interrupt, 423 so it can know how much time has passed. This 424 information is used to signal timer based events. 425 425 NULL will unregister the handler. 426 426 … … 474 474 @param This The EFI_TIMER_ARCH_PROTOCOL instance. 475 475 @param TimerPeriod The rate to program the timer interrupt in 100 nS units. 476 If the timer hardware is not programmable, then 477 EFI_UNSUPPORTED is returned. If the timer is programmable, 478 then the timer period will be rounded up to the nearest 479 timer period that is supported by the timer hardware. 480 If TimerPeriod is set to 0, then the timer interrupts 476 If the timer hardware is not programmable, then 477 EFI_UNSUPPORTED is returned. If the timer is programmable, 478 then the timer period will be rounded up to the nearest 479 timer period that is supported by the timer hardware. 480 If TimerPeriod is set to 0, then the timer interrupts 481 481 will be disabled. 482 482 … … 497 497 UINT64 CurrentComparator; 498 498 HPET_TIMER_MSI_ROUTE_REGISTER HpetTimerMsiRoute; 499 499 500 500 // 501 501 // Disable HPET timer when adjusting the timer period 502 502 // 503 503 HpetEnable (FALSE); 504 504 505 505 if (TimerPeriod == 0) { 506 506 if (mTimerPeriod != 0) { … … 511 511 if (MainCounter < mPreviousMainCounter) { 512 512 Delta = (mCounterMask - mPreviousMainCounter) + MainCounter; 513 } else { 513 } else { 514 514 Delta = MainCounter - mPreviousMainCounter; 515 515 } … … 530 530 // If TimerPeriod is 0, then mask HPET Timer interrupts 531 531 // 532 532 533 533 if (mTimerConfiguration.Bits.MsiInterruptCapablity != 0 && FeaturePcdGet (PcdHpetMsiEnable)) { 534 534 // … … 542 542 IoApicEnableInterrupt (mTimerIrq, FALSE); 543 543 } 544 545 // 546 // Disable HPET timer interrupt 544 545 // 546 // Disable HPET timer interrupt 547 547 // 548 548 mTimerConfiguration.Bits.InterruptEnable = 0; … … 550 550 } else { 551 551 // 552 // Convert TimerPeriod to femtoseconds and divide by the number if femtoseconds 552 // Convert TimerPeriod to femtoseconds and divide by the number if femtoseconds 553 553 // per tick of the HPET counter to determine the number of HPET counter ticks 554 554 // in TimerPeriod 100 ns units. 555 // 555 // 556 556 mTimerCount = DivU64x32 ( 557 557 MultU64x32 (TimerPeriod, 100000000), … … 565 565 if (MainCounter > mPreviousMainCounter) { 566 566 Delta = MainCounter - mPreviousMainCounter; 567 } else { 567 } else { 568 568 Delta = (mCounterMask - mPreviousMainCounter) + MainCounter; 569 569 } 570 570 if ((Delta & mCounterMask) >= mTimerCount) { 571 571 HpetWrite (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, (MainCounter + 1) & mCounterMask); 572 } else { 572 } else { 573 573 HpetWrite (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, (mPreviousMainCounter + mTimerCount) & mCounterMask); 574 574 } 575 575 576 576 // 577 577 // Enable HPET Timer interrupt generation … … 604 604 HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, mTimerConfiguration.Uint64); 605 605 } 606 606 607 607 // 608 608 // Save the new timer period … … 617 617 // 618 618 HpetEnable (TRUE); 619 619 620 620 return EFI_SUCCESS; 621 621 } … … 663 663 664 664 @retval EFI_SUCCESS The soft timer interrupt was generated. 665 @retval EFI_UNSUPPORTEDT The platform does not support the generation of soft 665 @retval EFI_UNSUPPORTEDT The platform does not support the generation of soft 666 666 timer interrupts. 667 667 … … 680 680 // 681 681 // Disable interrupts 682 // 682 // 683 683 Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); 684 684 685 685 // 686 686 // Capture main counter value … … 693 693 if (mTimerNotifyFunction != NULL) { 694 694 // 695 // Compute time since last interrupt in 100 ns units (10 ^ -7) 695 // Compute time since last interrupt in 100 ns units (10 ^ -7) 696 696 // 697 697 if (MainCounter > mPreviousMainCounter) { … … 711 711 Delta & mCounterMask, 712 712 mHpetGeneralCapabilities.Bits.CounterClockPeriod 713 ), 713 ), 714 714 100000000 715 715 ); 716 716 717 717 // 718 718 // Call registered notification function passing in the time since the last 719 719 // interrupt in 100 ns units. 720 // 720 // 721 721 mTimerNotifyFunction (TimerPeriod); 722 722 } … … 726 726 // 727 727 mPreviousMainCounter = MainCounter; 728 728 729 729 // 730 730 // Restore interrupts 731 // 731 // 732 732 gBS->RestoreTPL (Tpl); 733 733 734 734 return EFI_SUCCESS; 735 735 } … … 773 773 // 774 774 // Retrieve HPET Capabilities and Configuration Information 775 // 775 // 776 776 mHpetGeneralCapabilities.Uint64 = HpetRead (HPET_GENERAL_CAPABILITIES_ID_OFFSET); 777 777 mHpetGeneralConfiguration.Uint64 = HpetRead (HPET_GENERAL_CONFIGURATION_OFFSET); 778 779 // 780 // If Revision is not valid, then ASSERT() and unload the driver because the HPET 778 779 // 780 // If Revision is not valid, then ASSERT() and unload the driver because the HPET 781 781 // device is not present. 782 // 782 // 783 783 ASSERT (mHpetGeneralCapabilities.Uint64 != 0); 784 784 ASSERT (mHpetGeneralCapabilities.Uint64 != 0xFFFFFFFFFFFFFFFFULL); … … 795 795 // 796 796 // Dump HPET Configuration Information 797 // 797 // 798 798 DEBUG_CODE ( 799 799 DEBUG ((DEBUG_INFO, "HPET Base Address = 0x%08x\n", PcdGet32 (PcdHpetBaseAddress))); … … 809 809 } 810 810 ); 811 811 812 812 // 813 813 // Capture the current HPET main counter value. 814 814 // 815 815 mPreviousMainCounter = HpetRead (HPET_MAIN_COUNTER_OFFSET); 816 817 // 818 // Determine the interrupt mode to use for the HPET Timer. 816 817 // 818 // Determine the interrupt mode to use for the HPET Timer. 819 819 // Look for MSI first, then unused PIC mode interrupt, then I/O APIC mode interrupt 820 // 820 // 821 821 MsiTimerIndex = HPET_INVALID_TIMER_INDEX; 822 822 mTimerIndex = HPET_INVALID_TIMER_INDEX; … … 826 826 // 827 827 mTimerConfiguration.Uint64 = HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + TimerIndex * HPET_TIMER_STRIDE); 828 829 // 830 // Check to see if this HPET Timer supports MSI 828 829 // 830 // Check to see if this HPET Timer supports MSI 831 831 // 832 832 if (mTimerConfiguration.Bits.MsiInterruptCapablity != 0) { … … 838 838 } 839 839 } 840 840 841 841 // 842 842 // Check to see if this HPET Timer supports I/O APIC interrupts … … 881 881 return EFI_DEVICE_ERROR; 882 882 } 883 883 884 884 // 885 885 // Initialize I/O APIC entry for HPET Timer Interrupt … … 901 901 // 902 902 // Configure the selected HPET Timer with settings common to both MSI mode and I/O APIC mode 903 // Clear InterruptEnable to keep interrupts disabled until full init is complete 904 // Clear PeriodicInterruptEnable to use one-shot mode 905 // Configure as a 32-bit counter 903 // Clear InterruptEnable to keep interrupts disabled until full init is complete 904 // Clear PeriodicInterruptEnable to use one-shot mode 905 // Configure as a 32-bit counter 906 906 // 907 907 mTimerConfiguration.Bits.InterruptEnable = 0; … … 909 909 mTimerConfiguration.Bits.CounterSizeEnable = 1; 910 910 HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, mTimerConfiguration.Uint64); 911 911 912 912 // 913 913 // Read the HPET Timer Capabilities and Configuration register back again. … … 960 960 DEBUG ((DEBUG_INFO, "HPET Interrupt Mode I/O APIC\n")); 961 961 DEBUG ((DEBUG_INFO, "HPET I/O APIC IRQ = 0x%02x\n", mTimerIrq)); 962 } 962 } 963 963 DEBUG ((DEBUG_INFO, "HPET Interrupt Vector = 0x%02x\n", PcdGet8 (PcdHpetLocalApicVector))); 964 964 DEBUG ((DEBUG_INFO, "HPET Counter Mask = 0x%016lx\n", mCounterMask)); … … 971 971 // 972 972 // Wait for a few timer interrupts to fire before continuing 973 // 973 // 974 974 while (mNumTicks < 10); 975 975 ); 976 976 977 977 // 978 978 // Install the Timer Architectural Protocol onto a new handle
Note:
See TracChangeset
for help on using the changeset viewer.