Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
btwise
OpenCorePKG_MOD
提交
d7662157
O
OpenCorePKG_MOD
项目概览
btwise
/
OpenCorePKG_MOD
通知
26
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
OpenCorePKG_MOD
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d7662157
编写于
6月 04, 2019
作者:
V
vit9696
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
OcTimerLib: Support AMD ACPI PowerManagement timer
closes acidanthera/bugtracker#353
上级
f82cb159
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
97 addition
and
70 deletion
+97
-70
Include/IndustryStandard/CpuId.h
Include/IndustryStandard/CpuId.h
+6
-3
Include/IndustryStandard/GenericIch.h
Include/IndustryStandard/GenericIch.h
+8
-3
Include/ProcessorInfo.h
Include/ProcessorInfo.h
+3
-6
Library/OcTimerLib/OcTimerLib.c
Library/OcTimerLib/OcTimerLib.c
+79
-58
Library/OcTimerLib/OcTimerLib.inf
Library/OcTimerLib/OcTimerLib.inf
+1
-0
未找到文件。
Include/IndustryStandard/CpuId.h
浏览文件 @
d7662157
...
...
@@ -12,8 +12,8 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef CPUID_H
_
#define CPUID_H
_
#ifndef CPUID_H
#define CPUID_H
#include <Register/Cpuid.h>
...
...
@@ -212,4 +212,7 @@ enum {
CpuIdCachePrefetch128
=
0xF1
,
///< 128-Byte Prefetching
};
#endif // CPUID_H_
#define CPUID_VENDOR_INTEL 0x756E6547
#define CPUID_VENDOR_AMD 0x68747541
#endif // CPUID_H
Include/IndustryStandard/GenericIch.h
浏览文件 @
d7662157
...
...
@@ -12,8 +12,8 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef GENERIC_ICH_H
_
#define GENERIC_ICH_H
_
#ifndef GENERIC_ICH_H
#define GENERIC_ICH_H
// GenericIchDefs Generic ICH Definitions.
//
...
...
@@ -50,6 +50,11 @@
#define R_ICH_SMBUS_ACPI_CNT R_ICH_ACPI_CNT
#define B_ICH_SMBUS_ACPI_CNT_ACPI_EN B_ICH_ACPI_CNT_ACPI_EN
// AMD Bolton (AMD Bolton Register Reference Guide 3.03)
#define R_AMD_ACPI_MMIO_BASE 0xFED80000 ///< AcpiMMioAddr (3-268)
#define R_AMD_ACPI_MMIO_PMIO_BASE 0x300 ///< PMIO (3-268)
#define R_AMD_ACPI_PM_TMR_BLOCK 0x64 ///< AcpiPmTmrBlk (3-289)
// IchAcpiTimer The ICH's ACPI Timer.
...
...
@@ -67,4 +72,4 @@
#define PCI_ICH_SMBUS_ADDRESS(Register) \
((UINTN)(PCI_LIB_ADDRESS (PCI_BUS_NUMBER_ICH, PCI_DEVICE_NUMBER_ICH, PCI_FUNCTION_NUMBER_ICH_SMBUS, (Register))))
#endif // GENERIC_ICH_H
_
#endif // GENERIC_ICH_H
Include/ProcessorInfo.h
浏览文件 @
d7662157
...
...
@@ -12,11 +12,8 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_PROCESSOR_INFO_H_
#define OC_PROCESSOR_INFO_H_
#define CPUID_VENDOR_INTEL 0x756E6547
#define CPUID_VENDOR_AMD 0x68747541
#ifndef OC_PROCESSOR_INFO_H
#define OC_PROCESSOR_INFO_H
// SandyBridge/IvyBridge bus clock is fixed at 100MHz
...
...
@@ -207,4 +204,4 @@ typedef enum {
CpuPStateCoordinationHardwareAll
=
0xFE
}
CPU_P_STATE_COORDINATION
;
#endif // OC_PROCESSOR_INFO_H
_
#endif // OC_PROCESSOR_INFO_H
Library/OcTimerLib/OcTimerLib.c
浏览文件 @
d7662157
...
...
@@ -16,6 +16,7 @@
#include <IndustryStandard/GenericIch.h>
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/CpuId.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
...
...
@@ -37,6 +38,7 @@ RecalculateTSC (
)
{
UINT32
TimerAddr
;
UINT32
CpuVendor
;
UINT64
Tsc0
;
UINT64
Tsc1
;
UINT32
AcpiTick0
;
...
...
@@ -46,6 +48,8 @@ RecalculateTSC (
UINT32
TimerResolution
;
EFI_TPL
PrevTpl
;
TimerAddr
=
0
;
//
// Intel timer support.
//
...
...
@@ -72,82 +76,99 @@ RecalculateTSC (
DEBUG
((
DEBUG_VERBOSE
,
"Acpi Timer Addr 0x%0x (SMB)
\n
"
,
TimerAddr
));
}
}
}
//
// AMD timer support.
//
if
(
TimerAddr
==
0
)
{
//
// In an ideal world I believe we should detect AMD SMBus controller...
//
CpuVendor
=
0
;
AsmCpuid
(
CPUID_SIGNATURE
,
NULL
,
&
CpuVendor
,
NULL
,
NULL
);
if
(
CpuVendor
==
CPUID_VENDOR_AMD
)
{
TimerAddr
=
IoRead32
(
R_AMD_ACPI_MMIO_BASE
+
R_AMD_ACPI_MMIO_PMIO_BASE
+
R_AMD_ACPI_PM_TMR_BLOCK
);
}
}
if
(
TimerAddr
!=
0
)
{
mPerformanceCounterFrequency
=
0
;
if
(
TimerAddr
!=
0
)
{
mPerformanceCounterFrequency
=
0
;
//
// Check that timer is advancing (it does not on some virtual machines).
//
AcpiTick0
=
IoRead32
(
TimerAddr
);
gBS
->
Stall
(
500
);
AcpiTick1
=
IoRead32
(
TimerAddr
);
if
(
AcpiTick0
!=
AcpiTick1
)
{
//
// ACPI PM timers are usually of 24-bit length, but there are some less common cases of 32-bit length also.
// When the maximal number is reached, it overflows.
// The code below can handle overflow with AcpiTicksTarget of up to 24-bit size,
// on both available sizes of ACPI PM Timers (24-bit and 32-bit).
//
//
Check that timer is advancing (it does not on some virtual machines).
//
357954 clocks of ACPI timer (100ms)
//
AcpiTicksTarget
=
V_ACPI_TMR_FREQUENCY
/
TimerResolution
;
//
// Disable all events to ensure that nobody interrupts us.
//
PrevTpl
=
gBS
->
RaiseTPL
(
TPL_HIGH_LEVEL
);
AcpiTick0
=
IoRead32
(
TimerAddr
);
gBS
->
Stall
(
500
);
AcpiTick1
=
IoRead32
(
TimerAddr
);
Tsc0
=
AsmReadTsc
();
if
(
AcpiTick0
!=
AcpiTick1
)
{
//
// ACPI PM timers are usually of 24-bit length, but there are some less common cases of 32-bit length also.
// When the maximal number is reached, it overflows.
// The code below can handle overflow with AcpiTicksTarget of up to 24-bit size,
// on both available sizes of ACPI PM Timers (24-bit and 32-bit).
//
// 357954 clocks of ACPI timer (100ms)
//
AcpiTicksTarget
=
V_ACPI_TMR_FREQUENCY
/
TimerResolution
;
do
{
CpuPause
();
//
//
Disable all events to ensure that nobody interrupts us
.
//
Check how many AcpiTicks have passed since we started
.
//
PrevTpl
=
gBS
->
RaiseTPL
(
TPL_HIGH_LEVEL
);
AcpiTick0
=
IoRead32
(
TimerAddr
);
Tsc0
=
AsmReadTsc
();
do
{
CpuPause
();
AcpiTick1
=
IoRead32
(
TimerAddr
);
if
(
AcpiTick0
<=
AcpiTick1
)
{
//
//
Check how many AcpiTicks have passed since we started
.
//
No overflow
.
//
AcpiTick1
=
IoRead32
(
TimerAddr
);
if
(
AcpiTick0
<=
AcpiTick1
)
{
//
// No overflow.
//
AcpiTicksDelta
=
AcpiTick1
-
AcpiTick0
;
}
else
if
(
AcpiTick0
-
AcpiTick1
<=
0x00FFFFFF
)
{
//
// Overflow, 24-bit timer.
//
AcpiTicksDelta
=
0x00FFFFFF
-
AcpiTick0
+
AcpiTick1
;
}
else
{
//
// Overflow, 32-bit timer.
//
AcpiTicksDelta
=
MAX_UINT32
-
AcpiTick0
+
AcpiTick1
;
}
AcpiTicksDelta
=
AcpiTick1
-
AcpiTick0
;
}
else
if
(
AcpiTick0
-
AcpiTick1
<=
0x00FFFFFF
)
{
//
//
Keep checking AcpiTicks until target is reached
.
//
Overflow, 24-bit timer
.
//
}
while
(
AcpiTicksDelta
<
AcpiTicksTarget
);
Tsc1
=
AsmReadTsc
();
AcpiTicksDelta
=
0x00FFFFFF
-
AcpiTick0
+
AcpiTick1
;
}
else
{
//
// Overflow, 32-bit timer.
//
AcpiTicksDelta
=
MAX_UINT32
-
AcpiTick0
+
AcpiTick1
;
}
//
// On some systems we may end up waiting for notably longer than 100ms,
// despite disabling all events. Divide by actual time passed as suggested
// by asava's Clover patch r2668.
// Keep checking AcpiTicks until target is reached.
//
mPerformanceCounterFrequency
=
DivU64x32
(
MultU64x32
(
Tsc1
-
Tsc0
,
V_ACPI_TMR_FREQUENCY
),
AcpiTicksDelta
);
}
while
(
AcpiTicksDelta
<
AcpiTicksTarget
);
//
// Restore to normal TPL.
//
gBS
->
RestoreTPL
(
PrevTpl
);
}
Tsc1
=
AsmReadTsc
();
//
// On some systems we may end up waiting for notably longer than 100ms,
// despite disabling all events. Divide by actual time passed as suggested
// by asava's Clover patch r2668.
//
mPerformanceCounterFrequency
=
DivU64x32
(
MultU64x32
(
Tsc1
-
Tsc0
,
V_ACPI_TMR_FREQUENCY
),
AcpiTicksDelta
);
//
// Restore to normal TPL.
//
gBS
->
RestoreTPL
(
PrevTpl
);
}
}
...
...
Library/OcTimerLib/OcTimerLib.inf
浏览文件 @
d7662157
...
...
@@ -37,6 +37,7 @@
[Packages]
OcSupportPkg/OcSupportPkg.dec
MdePkg/MdePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
[LibraryClasses]
PciLib
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录