Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
btwise
OpenCorePKG_MOD
提交
a62cdf2e
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,发现更多精彩内容 >>
提交
a62cdf2e
编写于
2月 14, 2021
作者:
V
vit9696
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
OcCpuLib: Implement ASM CPU frequency calculation for HSW and lower
上级
cd5bd939
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
223 addition
and
55 deletion
+223
-55
Changelog.md
Changelog.md
+1
-0
Library/OcCpuLib/FrequencyDetect.c
Library/OcCpuLib/FrequencyDetect.c
+14
-55
Library/OcCpuLib/Ia32/MeasureTicks.c
Library/OcCpuLib/Ia32/MeasureTicks.c
+77
-0
Library/OcCpuLib/OcCpuInternals.h
Library/OcCpuLib/OcCpuInternals.h
+17
-0
Library/OcCpuLib/OcCpuLib.inf
Library/OcCpuLib/OcCpuLib.inf
+2
-0
Library/OcCpuLib/X64/MeasureTicks.nasm
Library/OcCpuLib/X64/MeasureTicks.nasm
+112
-0
未找到文件。
Changelog.md
浏览文件 @
a62cdf2e
...
...
@@ -3,6 +3,7 @@ OpenCore Changelog
#### v0.6.7
-
Fixed ocvalidate return code to be non-zero when issues are found
-
Added
`OEM`
values to
`PlatformInfo`
in
`Automatic`
mode
-
Improved CPU frequency calculation on Haswell and earlier
#### v0.6.6
-
Added keyboard and pointer entry scroll support in OpenCanopy
...
...
Library/OcCpuLib/FrequencyDetect.c
浏览文件 @
a62cdf2e
...
...
@@ -129,15 +129,14 @@ InternalCalculateTSCFromPMTimer (
//
STATIC
UINT64
TSCFrequency
=
0
;
UINT
N
TimerAddr
;
UINT
16
TimerAddr
;
UINTN
VariableSize
;
UINT64
Tsc0
;
UINT64
Tsc1
;
UINT64
TscTicksDelta
;
UINT32
AcpiTick0
;
UINT32
AcpiTick1
;
UINT32
AcpiTicksDelta
;
UINT32
AcpiTicks
Target
;
UINT32
TimerResolution
;
UINT32
AcpiTicks
Duration
;
BOOLEAN
HasInterrupts
;
EFI_TPL
PrevTpl
;
EFI_STATUS
Status
;
...
...
@@ -169,8 +168,7 @@ InternalCalculateTSCFromPMTimer (
}
if
(
TSCFrequency
==
0
)
{
TimerAddr
=
InternalGetPmTimerAddr
(
NULL
);
TimerResolution
=
10
;
TimerAddr
=
(
UINT16
)
InternalGetPmTimerAddr
(
NULL
);
if
(
TimerAddr
!=
0
)
{
//
...
...
@@ -187,63 +185,24 @@ InternalCalculateTSCFromPMTimer (
// 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 (
1
00ms)
// 357954 clocks of ACPI timer (
2
00ms)
//
AcpiTicks
Target
=
V_ACPI_TMR_FREQUENCY
/
TimerResolution
;
AcpiTicks
Duration
=
V_ACPI_TMR_FREQUENCY
/
10
;
//
// Disable all events to ensure that nobody interrupts us.
//
PrevTpl
=
gBS
->
RaiseTPL
(
TPL_HIGH_LEVEL
);
HasInterrupts
=
SaveAndDisableInterrupts
();
AsmMeasureTicks
(
AcpiTicksDuration
,
TimerAddr
,
&
AcpiTicksDelta
,
&
TscTicksDelta
);
if
(
HasInterrupts
)
{
EnableInterrupts
();
}
gBS
->
RestoreTPL
(
PrevTpl
);
AcpiTick0
=
IoRead32
(
TimerAddr
);
Tsc0
=
AsmReadTsc
();
do
{
CpuPause
();
//
// Check how many AcpiTicks have passed since we started.
//
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
;
}
//
// Keep checking AcpiTicks until target is reached.
//
}
while
(
AcpiTicksDelta
<
AcpiTicksTarget
);
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.
//
TSCFrequency
=
DivU64x32
(
MultU64x32
(
Tsc
1
-
Tsc0
,
V_ACPI_TMR_FREQUENCY
),
AcpiTicksDelta
MultU64x32
(
Tsc
TicksDelta
,
V_ACPI_TMR_FREQUENCY
),
AcpiTicksDelta
);
//
// Restore to normal TPL.
//
gBS
->
RestoreTPL
(
PrevTpl
);
}
}
...
...
Library/OcCpuLib/Ia32/MeasureTicks.c
0 → 100644
浏览文件 @
a62cdf2e
/** @file
Copyright (C) 2020, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "OcCpuInternals.h"
#include <Library/BaseLib.h>
#include <Library/IoLib.h>
VOID
EFIAPI
AsmMeasureTicks
(
IN
UINT32
AcpiTicksDuration
,
IN
UINT16
TimerAddr
,
OUT
UINT32
*
AcpiTicksDelta
,
OUT
UINT64
*
TscTicksDelta
)
{
UINT32
AcpiTick0
;
UINT32
AcpiTick1
;
UINT32
AcpiCurrentDelta
;
UINT64
Tsc0
;
UINT64
Tsc1
;
AcpiTick0
=
IoRead32
(
TimerAddr
);
Tsc0
=
AsmReadTsc
();
do
{
CpuPause
();
//
// Check how many AcpiTicks have passed since we started.
//
AcpiTick1
=
IoRead32
(
TimerAddr
);
if
(
AcpiTick0
<=
AcpiTick1
)
{
//
// No overflow.
//
AcpiCurrentDelta
=
AcpiTick1
-
AcpiTick0
;
}
else
if
(
AcpiTick0
-
AcpiTick1
<=
0x00FFFFFF
)
{
//
// Overflow, 24-bit timer.
//
AcpiCurrentDelta
=
0x00FFFFFF
-
AcpiTick0
+
AcpiTick1
;
}
else
{
//
// Overflow, 32-bit timer.
//
AcpiCurrentDelta
=
MAX_UINT32
-
AcpiTick0
+
AcpiTick1
;
}
//
// Keep checking AcpiTicks until target is reached.
//
}
while
(
AcpiCurrentDelta
<
AcpiTicksDuration
);
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.
//
*
TscTicksDelta
=
Tsc1
-
Tsc0
;
*
AcpiTicksDelta
=
AcpiCurrentDelta
;
}
Library/OcCpuLib/OcCpuInternals.h
浏览文件 @
a62cdf2e
...
...
@@ -41,6 +41,23 @@ AsmReadIntelMicrocodeRevision (
VOID
);
/**
Measures TSC and ACPI ticks over specified ACPI tick amount.
@param[in] AcpiTicksDuration Number of ACPI ticks for calculation.
@param[in] TimerAddr ACPI timer address.
@param[out] AcpiTicksDelta Reported ACPI ticks delta.
@param[out] TscTicksDelta Reported TSC ticks delta.
**/
VOID
EFIAPI
AsmMeasureTicks
(
IN
UINT32
AcpiTicksDuration
,
IN
UINT16
TimerAddr
,
OUT
UINT32
*
AcpiTicksDelta
,
OUT
UINT64
*
TscTicksDelta
);
/**
Detect Apple CPU major type.
...
...
Library/OcCpuLib/OcCpuLib.inf
浏览文件 @
a62cdf2e
...
...
@@ -52,8 +52,10 @@
[Sources.Ia32]
Ia32/Atomic.nasm
Ia32/MeasureTicks.c
Ia32/Microcode.nasm
[Sources.X64]
X64/Atomic.nasm
X64/MeasureTicks.nasm
X64/Microcode.nasm
Library/OcCpuLib/X64/MeasureTicks.nasm
0 → 100644
浏览文件 @
a62cdf2e
;------------------------------------------------------------------------------
; @file
; Copyright (C) 2020, vit9696. All rights reserved.
;
; All rights reserved.
;
; This program and the accompanying materials
; are licensed and made available under the terms and conditions of the BSD License
; which accompanies this distribution. The full text of the license may be found at
; http://opensource.org/licenses/bsd-license.php
;
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
;------------------------------------------------------------------------------
BITS 64
DEFAULT REL
SECTION .text
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; AsmMeasureTicks (
; IN UINT32 AcpiTicksDuration, ///< ecx
; IN UINT16 TimerAddr, ///< dx
; OUT UINT32 *AcpiTicksDelta, ///< r8
; OUT UINT64 *TscTicksDelta ///< r9
; );
;------------------------------------------------------------------------------
global ASM_PFX(AsmMeasureTicks)
ASM_PFX(AsmMeasureTicks):
; Push preserved registers.
push rsi
push rdi
push rbp
push rbx
; Preserve TimerAddr in r11d as rdtsc overrides edx.
mov r11d, edx
; Read AcpiTicks0 into ebx.
in eax, dx
mov ebx, eax
; Read Tsc0 into r10.
rdtsc
shl rdx, 32
or rax, rdx
mov r10, rax
; Store MAX_UINT32 - AcpiTick0 into ebp.
mov ebp, ebx
not ebp
; Store MAX_UINT24 - AcpiTick0 into edi.
mov edi, 0x00ffffff
sub edi, ebx
CalculationLoop:
nop ; or pause.
; Read AcpiTicks1 into esi.
mov edx, r11d
in eax, dx
mov esi, eax
; Calculate AcpiTicks0 - AcpiTicks1 into eax.
mov eax, ebx
sub eax, esi
jbe NoOverflow
; Check for 32-bit overflow.
cmp eax, 0x00ffffff
ja Overflow32
Overflow24:
; AcpiCurrentDelta (esi) = AcpiTicks1 (esi) + MAX_UINT24 - AcpiTick0 (edi)
add esi, edi
jmp ContinueLoop
NoOverflow:
; AcpiCurrentDelta (esi) = AcpiTicks1 (esi) - AcpiTicks0 (ebx)
sub esi, ebx
jmp ContinueLoop
Overflow32:
; AcpiCurrentDelta (esi) = AcpiTicks1 (esi) + MAX_UINT32 - AcpiTick0 (ebp)
add esi, ebp
ContinueLoop:
cmp esi, ecx
jb CalculationLoop
; Read Tsc1 into rax.
rdtsc
shl rdx, 32
or rax, rdx
; Calculate TscDelta into rax.
sub rax, r10
; Store TscDelta and AcpiDelta.
mov qword [r9], rax
mov dword [r8], esi
; Pop preserved registers & return.
pop rbx
pop rbp
pop rdi
pop rsi
ret
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录