Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
3.7 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. ixthrotl.c
  5. Abstract:
  6. This module implements the code for throttling the processors
  7. Author:
  8. Jake Oshins (jakeo) 17-July-1997
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. --*/
  13. #include "halp.h"
  14. #include "acpitabl.h"
  15. #include "xxacpi.h"
  16. #include "pci.h"
  17. VOID
  18. FASTCALL
  19. HalProcessorThrottle (
  20. IN UCHAR Throttle
  21. )
  22. /*++
  23. Routine Description:
  24. This function limits the speed of the processor.
  25. Arguments:
  26. (ecx) = Throttle setting
  27. Return Value:
  28. none
  29. --*/
  30. {
  31. PKPRCB PrcB;
  32. PHALPMPRCB HalPrcB;
  33. ULONG ThrottleSetting;
  34. ULONG Addr;
  35. ULONG Mask;
  36. ULONG i;
  37. ULONG PblkAddr;
  38. #if DBG
  39. // debug
  40. WRITE_PORT_UCHAR ((PUCHAR) 0x80, Throttle);
  41. #endif
  42. PrcB = KeGetPcr()->Prcb;
  43. HalPrcB = (PHALPMPRCB) PrcB->HalReserved;
  44. PblkAddr = HalPrcB->PBlk.Addr;
  45. ThrottleSetting = READ_PORT_ULONG ((PULONG) PblkAddr);
  46. if (Throttle == HalpThrottleScale) {
  47. //
  48. // If this is a piix4 and we're no longer going to
  49. // throttle, set the break events (a piix4 thing) to
  50. // get any interrupt to wake a C2 to C3 stopped
  51. // processor. (note that piix4 can only be set on a
  52. // UP system). Then clear the bit to allow C2 and C3
  53. // idle handlers to work again.
  54. //
  55. if (HalpPiix4 == 1) {
  56. HalSetBusDataByOffset (
  57. PCIConfiguration,
  58. HalpPiix4BusNumber,
  59. HalpPiix4SlotNumber,
  60. &HalpPiix4DevActB,
  61. 0x58,
  62. sizeof (ULONG)
  63. );
  64. HalPrcB->PBlk.AddrAndFlags &= ~PIIX4_THROTTLE_FIX;
  65. }
  66. //
  67. // Throttling is off
  68. //
  69. ThrottleSetting &= ~PBLK_THT_EN;
  70. WRITE_PORT_ULONG ((PULONG) PblkAddr, ThrottleSetting);
  71. } else {
  72. //
  73. // Throttling is on.
  74. //
  75. if (HalpPiix4 == 1) {
  76. //
  77. // These piix4's have the thottle setting backwards, so
  78. // invert the value
  79. //
  80. Throttle = (UCHAR) HalpThrottleScale - Throttle;
  81. //
  82. // Piix4 will hang on a high throttle setting, so make
  83. // sure we don't do that
  84. //
  85. if (Throttle < 3) {
  86. Throttle = 3;
  87. }
  88. }
  89. //
  90. // Shift the throttle and build a mask to be in the proper location
  91. // for this platform
  92. //
  93. Throttle = Throttle << HalpFixedAcpiDescTable.duty_offset;
  94. Mask = (HalpThrottleScale - 1) << HalpFixedAcpiDescTable.duty_offset;
  95. //
  96. // Set the rate
  97. //
  98. ThrottleSetting &= ~Mask;
  99. ThrottleSetting |= Throttle | PBLK_THT_EN;
  100. WRITE_PORT_ULONG ((PULONG) PblkAddr, ThrottleSetting);
  101. //
  102. // If this is a piix4 we need to disable all the break events
  103. // (a piix4 thing) and then read the level2 processor stop
  104. // register to get it to start throttling. Oh yes, also set
  105. // the bit in the Paddr to stop doing C2 & C3 stops at the
  106. // same time.
  107. //
  108. if (HalpPiix4 == 1) {
  109. HalPrcB->PBlk.AddrAndFlags |= PIIX4_THROTTLE_FIX;
  110. i = HalpPiix4DevActB & ~0x23;
  111. HalSetBusDataByOffset (
  112. PCIConfiguration,
  113. HalpPiix4BusNumber,
  114. HalpPiix4SlotNumber,
  115. &i,
  116. 0x58,
  117. sizeof(ULONG)
  118. );
  119. READ_PORT_UCHAR ((PUCHAR) PblkAddr + P_LVL2);
  120. }
  121. }
  122. }