Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
7a34e712
提交
7a34e712
4月 21, 2012
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
x2apic stuff from Linux
上级
70faa117
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
58 行增加
和
22 行删除
+58
-22
x2apic.cc
kernel/x2apic.cc
+58
-22
没有找到文件。
kernel/x2apic.cc
浏览文件 @
7a34e712
...
...
@@ -26,6 +26,7 @@
#define LINT1 0x836 // Local Vector Table 2 (LINT1)
#define ERROR 0x837 // Local Vector Table 3 (ERROR)
#define MASKED 0x00010000 // Interrupt masked
#define MT_EXTINT 0x00000500
#define MT_NMI 0x00000400 // NMI message type
#define MT_FIX 0x00000000 // Fixed message type
#define TICR 0x838 // Timer Initial Count
...
...
@@ -36,6 +37,30 @@
static
u64
x2apichz
;
static
int
x2apicmaxlvt
(
void
)
{
unsigned
int
v
;
v
=
readmsr
(
VER
);
return
(((
v
)
>>
16
)
&
0xFFu
);
}
void
x2apiceoi
(
void
)
{
writemsr
(
EOI
,
0
);
}
static
int
x2apicwait
(
void
)
{
// Do nothing on x2apic
return
0
;
}
// Code closely follows native_cpu_up, do_boot_cpu,
// and wakeup_secondary_cpu_via_init in Linux v3.3
void
x2apicstartap
(
hwid_t
id
,
u32
addr
)
{
...
...
@@ -51,36 +76,52 @@ x2apicstartap(hwid_t id, u32 addr)
wrv
[
0
]
=
0
;
wrv
[
1
]
=
addr
>>
4
;
// Be paranoid about clearing APIC errors
writemsr
(
ESR
,
0
);
readmsr
(
ESR
);
unsigned
long
accept_status
;
int
maxlvt
=
x2apicmaxlvt
();
if
(
maxlvt
>
3
)
writemsr
(
ESR
,
0
);
readmsr
(
ESR
);
// "Universal startup algorithm."
// Send INIT (level-triggered) interrupt to reset other CPU.
// Asserting INIT
writemsr
(
ICR
,
(((
u64
)
id
.
num
)
<<
32
)
|
INIT
|
LEVEL
|
ASSERT
);
//xapicwait();
microdelay
(
10000
);
// Deasserting INIT
writemsr
(
ICR
,
(((
u64
)
id
.
num
)
<<
32
)
|
INIT
|
LEVEL
);
//xapicw(ICRLO, hwid.num |INIT | LEVEL);
//xapicwait();
microdelay
(
10000
);
// should be 10ms, but too slow in Bochs!
x2apicwait
();
// Send startup IPI (twice!) to enter bootstrap code.
// Regular hardware is supposed to only accept a STARTUP
// when it is in the halted state due to an INIT. So the second
// should be ignored, but it is part of the official Intel algorithm.
// Bochs complains about the second one. Too bad for Bochs.
for
(
i
=
0
;
i
<
2
;
i
++
){
//xapicw(ICRHI, hwid.num<<24);
//xapicw(ICRLO, STARTUP | (addr>>12));
if
(
maxlvt
>
3
)
writemsr
(
ESR
,
0
);
readmsr
(
ESR
);
// Kick the target chip
writemsr
(
ICR
,
(((
u64
)
id
.
num
)
<<
32
)
|
STARTUP
|
(
addr
>>
12
));
// Linux gives 300 usecs to accept the IPI..
microdelay
(
300
);
x2apicwait
();
// ..then it gives some more time
microdelay
(
200
);
}
}
void
x2apiceoi
(
void
)
{
writemsr
(
EOI
,
0
);
if
(
maxlvt
>
3
)
writemsr
(
ESR
,
0
);
accept_status
=
(
readmsr
(
ESR
)
&
0xEF
);
if
(
accept_status
)
panic
(
"x2apicstartap: accept status %lx"
,
accept_status
);
}
}
void
...
...
@@ -128,7 +169,7 @@ initx2apic(void)
count
=
(
QUANTUM
*
x2apichz
)
/
1000
;
if
(
count
>
0xffffffff
)
panic
(
"initxapic: QUANTUM too large"
);
panic
(
"initx
2
apic: QUANTUM too large"
);
// The timer repeatedly counts down at bus frequency
// from xapic[TICR] and then issues an interrupt.
...
...
@@ -140,8 +181,7 @@ initx2apic(void)
writemsr
(
LINT0
,
MASKED
);
writemsr
(
LINT1
,
MASKED
);
// Disable performance counter overflow interrupts
// on machines that provide that interrupt entry.
// Enable performance counter overflow interrupts for sampler.cc
if
(((
readmsr
(
VER
)
>>
16
)
&
0xFF
)
>=
4
)
x2apicpc
(
0
);
...
...
@@ -157,10 +197,6 @@ initx2apic(void)
// Send an Init Level De-Assert to synchronise arbitration ID's.
writemsr
(
ICR
,
BCAST
|
INIT
|
LEVEL
);
#if 0 // XXX(sbw) now need to poll anymore
while (readmsr(ICR) & DELIVS)
;
#endif
// Enable interrupts on the APIC (but not on the processor).
writemsr
(
TPR
,
0
);
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论