Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
b63bb0fd
提交
b63bb0fd
8月 27, 2007
创建
作者:
rsc
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Clean up lapic code.
One initialization function now, not three. Use #defines instead of enums (consistent with other code, but sigh). Still boots in Bochs in SMP mode.
上级
112873bc
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
123 行增加
和
177 行删除
+123
-177
defs.h
defs.h
+2
-2
lapic.c
lapic.c
+120
-168
main.c
main.c
+1
-7
没有找到文件。
defs.h
浏览文件 @
b63bb0fd
...
@@ -69,12 +69,12 @@ void kinit(void);
...
@@ -69,12 +69,12 @@ void kinit(void);
// lapic.c
// lapic.c
int
cpu
(
void
);
int
cpu
(
void
);
extern
uint
*
lapicaddr
;
extern
volatile
uint
*
lapic
;
void
lapic_disableintr
(
void
);
void
lapic_disableintr
(
void
);
void
lapic_enableintr
(
void
);
void
lapic_enableintr
(
void
);
void
lapic_eoi
(
void
);
void
lapic_eoi
(
void
);
void
lapic_init
(
int
);
void
lapic_init
(
int
);
void
lapic_startap
(
uchar
,
int
);
void
lapic_startap
(
uchar
,
u
int
);
void
lapic_timerinit
(
void
);
void
lapic_timerinit
(
void
);
void
lapic_timerintr
(
void
);
void
lapic_timerintr
(
void
);
...
...
lapic.c
浏览文件 @
b63bb0fd
...
@@ -6,210 +6,162 @@
...
@@ -6,210 +6,162 @@
#include "traps.h"
#include "traps.h"
#include "mmu.h"
#include "mmu.h"
#include "proc.h"
#include "proc.h"
#include "lapic.h"
enum
{
// Local APIC registers
LAPIC_ID
=
0x0020
,
// ID
// Local APIC registers, divided by 4 for use as uint[] indices.
LAPIC_VER
=
0x0030
,
// Version
#define ID (0x0020/4) // ID
LAPIC_TPR
=
0x0080
,
// Task Priority
#define VER (0x0030/4) // Version
LAPIC_APR
=
0x0090
,
// Arbitration Priority
#define TPR (0x0080/4) // Task Priority
LAPIC_PPR
=
0x00A0
,
// Processor Priority
#define APR (0x0090/4) // Arbitration Priority
LAPIC_EOI
=
0x00B0
,
// EOI
#define PPR (0x00A0/4) // Processor Priority
LAPIC_LDR
=
0x00D0
,
// Logical Destination
#define EOI (0x00B0/4) // EOI
LAPIC_DFR
=
0x00E0
,
// Destination Format
#define LDR (0x00D0/4) // Logical Destination
LAPIC_SVR
=
0x00F0
,
// Spurious Interrupt Vector
#define DFR (0x00E0/4) // Destination Format
LAPIC_ISR
=
0x0100
,
// Interrupt Status (8 registers)
#define SVR (0x00F0/4) // Spurious Interrupt Vector
LAPIC_TMR
=
0x0180
,
// Trigger Mode (8 registers)
#define ISR (0x0100/4) // Interrupt Status (8 registers)
LAPIC_IRR
=
0x0200
,
// Interrupt Request (8 registers)
#define TMR (0x0180/4) // Trigger Mode (8 registers)
LAPIC_ESR
=
0x0280
,
// Error Status
#define IRR (0x0200/4) // Interrupt Request (8 registers)
LAPIC_ICRLO
=
0x0300
,
// Interrupt Command
#define ESR (0x0280/4) // Error Status
LAPIC_ICRHI
=
0x0310
,
// Interrupt Command [63:32]
#define ICRLO (0x0300/4) // Interrupt Command
LAPIC_TIMER
=
0x0320
,
// Local Vector Table 0 (TIMER)
#define ICRHI (0x0310/4) // Interrupt Command [63:32]
LAPIC_PCINT
=
0x0340
,
// Performance Counter LVT
#define TIMER (0x0320/4) // Local Vector Table 0 (TIMER)
LAPIC_LINT0
=
0x0350
,
// Local Vector Table 1 (LINT0)
#define PCINT (0x0340/4) // Performance Counter LVT
LAPIC_LINT1
=
0x0360
,
// Local Vector Table 2 (LINT1)
#define LINT0 (0x0350/4) // Local Vector Table 1 (LINT0)
LAPIC_ERROR
=
0x0370
,
// Local Vector Table 3 (ERROR)
#define LINT1 (0x0360/4) // Local Vector Table 2 (LINT1)
LAPIC_TICR
=
0x0380
,
// Timer Initial Count
#define ERROR (0x0370/4) // Local Vector Table 3 (ERROR)
LAPIC_TCCR
=
0x0390
,
// Timer Current Count
#define TICR (0x0380/4) // Timer Initial Count
LAPIC_TDCR
=
0x03E0
,
// Timer Divide Configuration
#define TCCR (0x0390/4) // Timer Current Count
};
#define TDCR (0x03E0/4) // Timer Divide Configuration
enum
{
// LAPIC_SVR
// SVR
LAPIC_ENABLE
=
0x00000100
,
// Unit Enable
#define ENABLE 0x00000100 // Unit Enable
LAPIC_FOCUS
=
0x00000200
,
// Focus Processor Checking Disable
#define FOCUS 0x00000200 // Focus Processor Checking Disable
};
// ICRLO
enum
{
// LAPIC_ICRLO
// [14] IPI Trigger Mode Level (RW)
// [14] IPI Trigger Mode Level (RW)
#define DEASSERT 0x00000000 // Deassert level-sensitive interrupt
LAPIC_DEASSERT
=
0x00000000
,
// Deassert level-sensitive interrupt
#define ASSERT 0x00004000 // Assert level-sensitive interrupt
LAPIC_ASSERT
=
0x00004000
,
// Assert level-sensitive interrupt
// [17:16] Remote Read Status
// [17:16] Remote Read Status
#define INVALID 0x00000000 // Invalid
LAPIC_INVALID
=
0x00000000
,
// Invalid
#define WAIT 0x00010000 // In-Progress
LAPIC_WAIT
=
0x00010000
,
// In-Progress
#define VALID 0x00020000 // Valid
LAPIC_VALID
=
0x00020000
,
// Valid
// [19:18] Destination Shorthand
// [19:18] Destination Shorthand
#define FIELD 0x00000000 // No shorthand
LAPIC_FIELD
=
0x00000000
,
// No shorthand
#define SELF 0x00040000 // Self is single destination
LAPIC_SELF
=
0x00040000
,
// Self is single destination
#define ALLINC 0x00080000 // All including self
LAPIC_ALLINC
=
0x00080000
,
// All including self
#define ALLEXC 0x000C0000 // All Excluding self
LAPIC_ALLEXC
=
0x000C0000
,
// All Excluding self
};
// ESR
#define SENDCS 0x00000001 // Send CS Error
enum
{
// LAPIC_ESR
#define RCVCS 0x00000002 // Receive CS Error
LAPIC_SENDCS
=
0x00000001
,
// Send CS Error
#define SENDACCEPT 0x00000004 // Send Accept Error
LAPIC_RCVCS
=
0x00000002
,
// Receive CS Error
#define RCVACCEPT 0x00000008 // Receive Accept Error
LAPIC_SENDACCEPT
=
0x00000004
,
// Send Accept Error
#define SENDVECTOR 0x00000020 // Send Illegal Vector
LAPIC_RCVACCEPT
=
0x00000008
,
// Receive Accept Error
#define RCVVECTOR 0x00000040 // Receive Illegal Vector
LAPIC_SENDVECTOR
=
0x00000020
,
// Send Illegal Vector
#define REGISTER 0x00000080 // Illegal Register Address
LAPIC_RCVVECTOR
=
0x00000040
,
// Receive Illegal Vector
LAPIC_REGISTER
=
0x00000080
,
// Illegal Register Address
// [17] Timer Mode (RW)
};
#define ONESHOT 0x00000000 // One-shot
#define PERIODIC 0x00020000 // Periodic
enum
{
// LAPIC_TIMER
// [17] Timer Mode (RW)
// [19:18] Timer Base (RW)
LAPIC_ONESHOT
=
0x00000000
,
// One-shot
#define CLKIN 0x00000000 // use CLKIN as input
LAPIC_PERIODIC
=
0x00020000
,
// Periodic
#define TMBASE 0x00040000 // use TMBASE
#define DIVIDER 0x00080000 // use output of the divider
// [19:18] Timer Base (RW)
LAPIC_CLKIN
=
0x00000000
,
// use CLKIN as input
#define X2 0x00000000 // divide by 2
LAPIC_TMBASE
=
0x00040000
,
// use TMBASE
#define X4 0x00000001 // divide by 4
LAPIC_DIVIDER
=
0x00080000
,
// use output of the divider
#define X8 0x00000002 // divide by 8
};
#define X16 0x00000003 // divide by 16
#define X32 0x00000008 // divide by 32
enum
{
// LAPIC_TDCR
#define X64 0x00000009 // divide by 64
LAPIC_X2
=
0x00000000
,
// divide by 2
#define X128 0x0000000A // divide by 128
LAPIC_X4
=
0x00000001
,
// divide by 4
#define X1 0x0000000B // divide by 1
LAPIC_X8
=
0x00000002
,
// divide by 8
LAPIC_X16
=
0x00000003
,
// divide by 16
//PAGEBREAK!
LAPIC_X32
=
0x00000008
,
// divide by 32
volatile
uint
*
lapic
;
// Initialized in mp.c
LAPIC_X64
=
0x00000009
,
// divide by 64
LAPIC_X128
=
0x0000000A
,
// divide by 128
LAPIC_X1
=
0x0000000B
,
// divide by 1
};
uint
*
lapicaddr
;
static
int
lapic_read
(
int
r
)
{
return
*
(
lapicaddr
+
(
r
/
sizeof
(
*
lapicaddr
)));
}
static
void
lapic_write
(
int
r
,
int
data
)
{
*
(
lapicaddr
+
(
r
/
sizeof
(
*
lapicaddr
)))
=
data
;
}
void
lapic_timerinit
(
void
)
{
if
(
!
lapicaddr
)
return
;
lapic_write
(
LAPIC_TDCR
,
LAPIC_X1
);
lapic_write
(
LAPIC_TIMER
,
LAPIC_CLKIN
|
LAPIC_PERIODIC
|
(
IRQ_OFFSET
+
IRQ_TIMER
));
lapic_write
(
LAPIC_TCCR
,
10000000
);
lapic_write
(
LAPIC_TICR
,
10000000
);
}
void
lapic_timerintr
(
void
)
{
if
(
lapicaddr
)
lapic_write
(
LAPIC_EOI
,
0
);
}
void
void
lapic_init
(
int
c
)
lapic_init
(
int
c
)
{
{
uint
r
,
lvt
;
uint
r
,
lvt
;
if
(
!
lapic
addr
)
if
(
!
lapic
)
return
;
return
;
lapic
_write
(
LAPIC_DFR
,
0xFFFFFFFF
)
;
// Set dst format register
lapic
[
DFR
]
=
0xFFFFFFFF
;
// Set dst format register
r
=
(
lapic
_read
(
LAPIC_ID
)
>>
24
)
&
0xFF
;
// Read APIC ID
r
=
(
lapic
[
ID
]
>>
24
)
&
0xFF
;
// Read APIC ID
lapic
_write
(
LAPIC_LDR
,
(
1
<<
r
)
<<
24
);
// Set logical dst register to r
lapic
[
LDR
]
=
(
1
<<
r
)
<<
24
;
lapic
_write
(
LAPIC_TPR
,
0xFF
)
;
// No interrupts for now
lapic
[
TPR
]
=
0xFF
;
// No interrupts for now
// Enable APIC
// Enable APIC
lapic
_write
(
LAPIC_SVR
,
LAPIC_ENABLE
|
(
IRQ_OFFSET
+
IRQ_SPURIOUS
)
);
lapic
[
SVR
]
=
ENABLE
|
(
IRQ_OFFSET
+
IRQ_SPURIOUS
);
// In virtual wire mode, set up the LINT0 and LINT1 as follows:
// In virtual wire mode, set up the LINT0 and LINT1 as follows:
lapic
_write
(
LAPIC_LINT0
,
APIC_IMASK
|
APIC_EXTINT
)
;
lapic
[
LINT0
]
=
APIC_IMASK
|
APIC_EXTINT
;
lapic
_write
(
LAPIC_LINT1
,
APIC_IMASK
|
APIC_NMI
)
;
lapic
[
LINT1
]
=
APIC_IMASK
|
APIC_NMI
;
lapic
_write
(
LAPIC_EOI
,
0
)
;
// Ack any outstanding interrupts.
lapic
[
EOI
]
=
0
;
// Ack any outstanding interrupts.
lvt
=
(
lapic
_read
(
LAPIC_VER
)
>>
16
)
&
0xFF
;
lvt
=
(
lapic
[
VER
]
>>
16
)
&
0xFF
;
if
(
lvt
>=
4
)
if
(
lvt
>=
4
)
lapic
_write
(
LAPIC_PCINT
,
APIC_IMASK
)
;
lapic
[
PCINT
]
=
APIC_IMASK
;
lapic
_write
(
LAPIC_ERROR
,
IRQ_OFFSET
+
IRQ_ERROR
)
;
lapic
[
ERROR
]
=
IRQ_OFFSET
+
IRQ_ERROR
;
lapic
_write
(
LAPIC_ESR
,
0
)
;
lapic
[
ESR
]
=
0
;
lapic
_read
(
LAPIC_ESR
)
;
lapic
[
ESR
]
;
// Issue an INIT Level De-Assert to synchronise arbitration ID's.
// Issue an INIT Level De-Assert to synchronise arbitration ID's.
lapic
_write
(
LAPIC_ICRHI
,
0
)
;
lapic
[
ICRHI
]
=
0
;
lapic
_write
(
LAPIC_ICRLO
,
LAPIC_ALLINC
|
APIC_LEVEL
|
lapic
[
ICRLO
]
=
ALLINC
|
APIC_LEVEL
|
LAPIC_DEASSERT
|
APIC_INIT
)
;
DEASSERT
|
APIC_INIT
;
while
(
lapic
_read
(
LAPIC_ICRLO
)
&
APIC_DELIVS
)
while
(
lapic
[
ICRLO
]
&
APIC_DELIVS
)
;
;
}
void
// Initialize the interrupt timer.
lapic_enableintr
(
void
)
// On real hardware would need to do more XXX.
{
lapic
[
TDCR
]
=
X1
;
if
(
lapicaddr
)
lapic
[
TIMER
]
=
CLKIN
|
PERIODIC
|
(
IRQ_OFFSET
+
IRQ_TIMER
);
lapic_write
(
LAPIC_TPR
,
0
);
lapic
[
TCCR
]
=
10000000
;
lapic
[
TICR
]
=
10000000
;
// Enable interrupts on the APIC (but not on processor).
lapic
[
TPR
]
=
0
;
}
}
void
int
lapic_disableintr
(
void
)
cpu
(
void
)
{
{
if
(
lapicaddr
)
if
(
lapic
)
lapic_write
(
LAPIC_TPR
,
0xFF
);
return
lapic
[
ID
]
>>
24
;
return
0
;
}
}
// Acknowledge interrupt.
void
void
lapic_eoi
(
void
)
lapic_eoi
(
void
)
{
{
if
(
lapicaddr
)
if
(
lapic
)
lapic_write
(
LAPIC_EOI
,
0
);
lapic
[
EOI
]
=
0
;
}
int
cpu
(
void
)
{
int
x
;
if
(
lapicaddr
)
x
=
(
lapic_read
(
LAPIC_ID
)
>>
24
)
&
0xFF
;
else
x
=
0
;
return
x
;
}
}
// Start additional processor running bootstrap code at addr.
void
void
lapic_startap
(
uchar
apicid
,
int
v
)
lapic_startap
(
uchar
apicid
,
uint
addr
)
{
{
int
crhi
,
i
;
int
i
;
volatile
int
j
=
0
;
volatile
int
j
=
0
;
crhi
=
apicid
<<
24
;
lapic
[
ICRHI
]
=
apicid
<<
24
;
lapic_write
(
LAPIC_ICRHI
,
crhi
);
lapic
[
ICRLO
]
=
FIELD
|
APIC_LEVEL
|
ASSERT
|
APIC_INIT
;
lapic_write
(
LAPIC_ICRLO
,
LAPIC_FIELD
|
APIC_LEVEL
|
LAPIC_ASSERT
|
APIC_INIT
);
for
(
j
=
0
;
j
<
10000
;
j
++
);
// 200us
for
(
j
=
0
;
j
<
10000
;
j
++
);
// 200us
lapic_write
(
LAPIC_ICRLO
,
LAPIC_FIELD
|
APIC_LEVEL
|
lapic
[
ICRLO
]
=
FIELD
|
APIC_LEVEL
|
DEASSERT
|
APIC_INIT
;
LAPIC_DEASSERT
|
APIC_INIT
);
for
(
j
=
0
;
j
<
1000000
;
j
++
);
// 10ms
for
(
j
=
0
;
j
<
1000000
;
j
++
);
// 10ms
// in p9 code, this was i < 2, which is what the spec says on page B-3
for
(
i
=
0
;
i
<
2
;
i
++
){
for
(
i
=
0
;
i
<
1
;
i
++
){
lapic
[
ICRHI
]
=
apicid
<<
24
;
lapic_write
(
LAPIC_ICRHI
,
crhi
);
lapic
[
ICRLO
]
=
FIELD
|
APIC_EDGE
|
APIC_STARTUP
|
(
addr
/
4096
);
lapic_write
(
LAPIC_ICRLO
,
LAPIC_FIELD
|
APIC_EDGE
|
APIC_STARTUP
|
(
v
/
4096
));
for
(
j
=
0
;
j
<
10000
;
j
++
);
// 200us
for
(
j
=
0
;
j
<
10000
;
j
++
);
// 200us
}
}
}
}
main.c
浏览文件 @
b63bb0fd
...
@@ -37,7 +37,6 @@ main0(void)
...
@@ -37,7 +37,6 @@ main0(void)
asm
volatile
(
"movl %0, %%ebp"
:
:
"r"
(
cpus
[
bcpu
].
mpstack
+
MPSTACK
));
asm
volatile
(
"movl %0, %%ebp"
:
:
"r"
(
cpus
[
bcpu
].
mpstack
+
MPSTACK
));
lapic_init
(
bcpu
);
lapic_init
(
bcpu
);
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpu
());
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpu
());
pinit
();
// process table
pinit
();
// process table
...
@@ -53,10 +52,7 @@ main0(void)
...
@@ -53,10 +52,7 @@ main0(void)
console_init
();
// I/O devices & their interrupts
console_init
();
// I/O devices & their interrupts
ide_init
();
// disk
ide_init
();
// disk
mp_startthem
();
// other CPUs
mp_startthem
();
// other CPUs
if
(
ismp
){
if
(
!
ismp
)
lapic_timerinit
();
// smp timer
lapic_enableintr
();
// local interrupts
}
else
pit8253_timerinit
();
// uniprocessor timer
pit8253_timerinit
();
// uniprocessor timer
userinit
();
// first user process
userinit
();
// first user process
...
@@ -74,8 +70,6 @@ mpmain(void)
...
@@ -74,8 +70,6 @@ mpmain(void)
cprintf
(
"cpu%d: starting
\n
"
,
cpu
());
cprintf
(
"cpu%d: starting
\n
"
,
cpu
());
idtinit
();
idtinit
();
lapic_init
(
cpu
());
lapic_init
(
cpu
());
lapic_timerinit
();
lapic_enableintr
();
setupsegs
(
0
);
setupsegs
(
0
);
cpuid
(
0
,
0
,
0
,
0
,
0
);
// memory barrier
cpuid
(
0
,
0
,
0
,
0
,
0
);
// memory barrier
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论