Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
89d00095
提交
89d00095
10月 22, 2011
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Start of mp.c, console.c, and spinlock.c 64-bitification.
上级
0f218772
隐藏空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
334 行增加
和
377 行删除
+334
-377
Makefile
Makefile
+5
-2
bits.h
bits.h
+22
-0
cga.c
cga.c
+21
-31
console.c
console.c
+34
-246
cpu.h
cpu.h
+32
-0
kernel.h
kernel.h
+35
-7
main.c
main.c
+11
-0
mp.c
mp.c
+24
-30
mp.h
mp.h
+32
-32
param.h
param.h
+2
-1
spinlock.c
spinlock.c
+15
-19
spinlock.h
spinlock.h
+2
-2
trap.c
trap.c
+54
-4
types.h
types.h
+4
-0
uart.c
uart.c
+3
-2
x86.h
x86.h
+33
-0
xv6-mtrace.h
xv6-mtrace.h
+5
-1
没有找到文件。
Makefile
浏览文件 @
89d00095
...
...
@@ -3,7 +3,10 @@
OBJS
=
\
asm.o
\
cga.o
\
console.o
\
main.o
\
mp.o
\
spinlock.o
\
string.o
\
uart.o
\
trap.o
...
...
@@ -15,7 +18,7 @@ TOOLPREFIX ?= x86_64-jos-elf-
QEMU
=
qemu-system-x86_64
NM
=
$(TOOLPREFIX)
nm
CC
=
$(TOOLPREFIX)
clang
CC
=
$(TOOLPREFIX)
gcc
AS
=
$(TOOLPREFIX)
gas
LD
=
$(TOOLPREFIX)
ld
OBJCOPY
=
$(TOOLPREFIX)
objcopy
...
...
@@ -50,4 +53,4 @@ endif
QEMUOPTS
=
-smp
$(CPUS)
-m
512
qemu
:
kernel
$(QEMU)
$(QEMUOPTS)
-kernel
kernel
$(QEMU)
$(QEMUOPTS)
-kernel
kernel
-nographic
bits.h
0 → 100644
浏览文件 @
89d00095
// Rflags register
#define FL_CF 0x00000001 // Carry Flag
#define FL_PF 0x00000004 // Parity Flag
#define FL_AF 0x00000010 // Auxiliary carry Flag
#define FL_ZF 0x00000040 // Zero Flag
#define FL_SF 0x00000080 // Sign Flag
#define FL_TF 0x00000100 // Trap Flag
#define FL_IF 0x00000200 // Interrupt Enable
#define FL_DF 0x00000400 // Direction Flag
#define FL_OF 0x00000800 // Overflow Flag
#define FL_IOPL_MASK 0x00003000 // I/O Privilege Level bitmask
#define FL_IOPL_0 0x00000000 // IOPL == 0
#define FL_IOPL_1 0x00001000 // IOPL == 1
#define FL_IOPL_2 0x00002000 // IOPL == 2
#define FL_IOPL_3 0x00003000 // IOPL == 3
#define FL_NT 0x00004000 // Nested Task
#define FL_RF 0x00010000 // Resume Flag
#define FL_VM 0x00020000 // Virtual 8086 mode
#define FL_AC 0x00040000 // Alignment Check
#define FL_VIF 0x00080000 // Virtual Interrupt Flag
#define FL_VIP 0x00100000 // Virtual Interrupt Pending
#define FL_ID 0x00200000 // ID flag
cga.c
浏览文件 @
89d00095
...
...
@@ -8,45 +8,35 @@ static int cursor;
extern
void
setcursor
(
int
);
void
putsn
(
const
char
*
s
,
int
n
)
static
void
cgaputs
(
const
char
*
s
)
{
int
i
;
uint8
*
p
,
*
ep
;
p
=
(
uint8
*
)
s
;
ep
=
p
+
n
;
for
(;
p
<
ep
;
p
++
)
{
if
(
*
p
==
'\n'
)
{
cursor
+=
80
-
cursor
%
80
;
}
else
{
screen
[
cursor
]
=
color
|
*
p
;
cursor
++
;
}
if
(
cursor
==
25
*
80
)
{
memmove
((
void
*
)
screen
+
80
*
2
,
(
void
*
)
screen
+
80
*
3
,
80
*
(
25
-
3
)
*
2
);
for
(
i
=
0
;
i
<
80
;
i
++
)
screen
[(
24
*
80
+
i
)]
=
color
|
' '
&
0xff
;
cursor
-=
80
;
}
}
}
ep
=
p
+
strlen
(
s
);
static
void
cgaputs
(
const
char
*
s
)
{
putsn
(
s
,
strlen
(
s
));
for
(;
p
<
ep
;
p
++
)
cgaputc
(
*
p
);
}
void
panic
(
const
char
*
s
)
cgaputc
(
char
c
)
{
cgaputs
(
"panic: "
);
cgaputs
(
s
);
cgaputs
(
"
\n
"
);
setcursor
(
cursor
);
for
(;;)
screen
[
0
]
=
screen
[
0
];
int
i
;
if
(
c
==
'\n'
)
{
cursor
+=
80
-
cursor
%
80
;
}
else
{
screen
[
cursor
]
=
color
|
c
;
cursor
++
;
}
if
(
cursor
==
25
*
80
)
{
memmove
((
void
*
)
screen
+
80
*
2
,
(
void
*
)
screen
+
80
*
3
,
80
*
(
25
-
3
)
*
2
);
for
(
i
=
0
;
i
<
80
;
i
++
)
screen
[(
24
*
80
+
i
)]
=
color
|
(
' '
&
0xff
);
cursor
-=
80
;
}
}
void
...
...
@@ -57,6 +47,6 @@ initcga(void)
cursor
=
2
*
80
;
setcursor
(
cursor
);
cgaputs
(
"
booting
...
\n
"
);
cgaputs
(
"
cga
...
\n
"
);
setcursor
(
cursor
);
}
console.c
浏览文件 @
89d00095
...
...
@@ -2,26 +2,14 @@
// Input is from the keyboard or serial port.
// Output is written to the screen and serial port.
#include "types.h"
#include "defs.h"
#include "param.h"
#include "traps.h"
#include "types.h"
#include "cpu.h"
#include "kernel.h"
#include "spinlock.h"
#include "condvar.h"
#include "fs.h"
#include "file.h"
#include "memlayout.h"
#include "mmu.h"
#include "queue.h"
#include "proc.h"
#include "x86.h"
#include <stdarg.h>
static
void
consputc
(
int
);
static
int
panicked
=
0
;
static
struct
{
struct
spinlock
lock
;
int
locking
;
...
...
@@ -34,7 +22,7 @@ printint(void (*putch) (void*, char), void *putarg,
static
char
digits
[]
=
"0123456789abcdef"
;
char
buf
[
16
];
int
i
;
u
int
x
;
u
32
x
;
if
(
sign
&&
(
sign
=
xx
<
0
))
x
=
-
xx
;
...
...
@@ -53,11 +41,18 @@ printint(void (*putch) (void*, char), void *putarg,
putch
(
putarg
,
buf
[
i
]);
}
//PAGEBREAK: 50
// Only understands %d, %x, %p, %s.
// Print to the console.
static
void
writecons
(
void
*
arg
,
char
c
)
{
uartputc
(
c
);
cgaputc
(
c
);
}
// Only understands %d, %x, %s.
void
vprintfmt
(
void
(
*
putch
)
(
void
*
,
char
),
void
*
putarg
,
char
*
fmt
,
va_list
ap
)
c
onst
c
har
*
fmt
,
va_list
ap
)
{
char
*
s
;
int
c
,
i
,
state
;
...
...
@@ -73,9 +68,9 @@ vprintfmt(void (*putch) (void*, char), void *putarg,
}
}
else
if
(
state
==
'%'
){
if
(
c
==
'd'
){
printint
(
putch
,
putarg
,
va_arg
(
ap
,
u
int
),
10
,
1
);
}
else
if
(
c
==
'x'
||
c
==
'p'
)
{
printint
(
putch
,
putarg
,
va_arg
(
ap
,
u
int
),
16
,
0
);
printint
(
putch
,
putarg
,
va_arg
(
ap
,
u
32
),
10
,
1
);
}
else
if
(
c
==
'x'
)
{
printint
(
putch
,
putarg
,
va_arg
(
ap
,
u
32
),
16
,
0
);
}
else
if
(
c
==
's'
){
s
=
(
char
*
)
va_arg
(
ap
,
char
*
);
if
(
s
==
0
)
...
...
@@ -85,7 +80,7 @@ vprintfmt(void (*putch) (void*, char), void *putarg,
s
++
;
}
}
else
if
(
c
==
'c'
){
putch
(
putarg
,
va_arg
(
ap
,
u
int
));
putch
(
putarg
,
va_arg
(
ap
,
u
32
));
}
else
if
(
c
==
'%'
){
putch
(
putarg
,
c
);
}
else
{
...
...
@@ -98,15 +93,8 @@ vprintfmt(void (*putch) (void*, char), void *putarg,
}
}
// Print to the console.
static
void
writecons
(
void
*
arg
,
char
c
)
{
consputc
(
c
);
}
void
cprintf
(
char
*
fmt
,
...)
cprintf
(
c
onst
c
har
*
fmt
,
...)
{
va_list
ap
;
...
...
@@ -122,233 +110,33 @@ cprintf(char *fmt, ...)
release
(
&
cons
.
lock
);
}
// Print to a buffer.
struct
bufstate
{
char
*
p
;
char
*
e
;
};
static
void
writebuf
(
void
*
arg
,
char
c
)
{
struct
bufstate
*
bs
=
arg
;
if
(
bs
->
p
<
bs
->
e
)
{
bs
->
p
[
0
]
=
c
;
bs
->
p
++
;
}
}
void
vsnprintf
(
char
*
buf
,
uint
n
,
char
*
fmt
,
va_list
ap
)
{
struct
bufstate
bs
=
{
buf
,
buf
+
n
-
1
};
vprintfmt
(
writebuf
,
(
void
*
)
&
bs
,
fmt
,
ap
);
bs
.
p
[
0
]
=
'\0'
;
}
void
snprintf
(
char
*
buf
,
uint
n
,
char
*
fmt
,
...)
{
va_list
ap
;
va_start
(
ap
,
fmt
);
vsnprintf
(
buf
,
n
,
fmt
,
ap
);
va_end
(
ap
);
}
void
panic
(
char
*
s
)
{
int
i
;
uint
pcs
[
10
];
cli
();
cons
.
locking
=
0
;
cprintf
(
"cpu%d: panic: "
,
cpu
->
id
);
cprintf
(
s
);
cprintf
(
"
\n
"
);
getcallerpcs
(
&
s
,
pcs
);
for
(
i
=
0
;
i
<
10
;
i
++
)
cprintf
(
" %p"
,
pcs
[
i
]);
cprintf
(
"
\n
"
);
panicked
=
1
;
// freeze other CPU
extern
void
sys_halt
();
sys_halt
();
for
(;;)
;
}
//PAGEBREAK: 50
#define BACKSPACE 0x100
#define CRTPORT 0x3d4
static
ushort
*
crt
=
(
ushort
*
)
P2V
(
0xb8000
);
// CGA memory
static
void
cgaputc
(
int
c
)
{
int
pos
;
// Cursor position: col + 80*row.
outb
(
CRTPORT
,
14
);
pos
=
inb
(
CRTPORT
+
1
)
<<
8
;
outb
(
CRTPORT
,
15
);
pos
|=
inb
(
CRTPORT
+
1
);
if
(
c
==
'\n'
)
pos
+=
80
-
pos
%
80
;
else
if
(
c
==
BACKSPACE
){
if
(
pos
>
0
)
--
pos
;
}
else
crt
[
pos
++
]
=
(
c
&
0xff
)
|
0x0700
;
// black on white
if
((
pos
/
80
)
>=
24
){
// Scroll up.
memmove
(
crt
,
crt
+
80
,
sizeof
(
crt
[
0
])
*
23
*
80
);
pos
-=
80
;
memset
(
crt
+
pos
,
0
,
sizeof
(
crt
[
0
])
*
(
24
*
80
-
pos
));
}
outb
(
CRTPORT
,
14
);
outb
(
CRTPORT
+
1
,
pos
>>
8
);
outb
(
CRTPORT
,
15
);
outb
(
CRTPORT
+
1
,
pos
);
crt
[
pos
]
=
' '
|
0x0700
;
}
void
consputc
(
int
c
)
{
if
(
panicked
){
cli
();
for
(;;)
;
}
if
(
c
==
BACKSPACE
){
uartputc
(
'\b'
);
uartputc
(
' '
);
uartputc
(
'\b'
);
}
else
uartputc
(
c
);
cgaputc
(
c
);
}
#define INPUT_BUF 128
struct
{
struct
spinlock
lock
;
struct
condvar
cv
;
char
buf
[
INPUT_BUF
];
uint
r
;
// Read index
uint
w
;
// Write index
uint
e
;
// Edit index
}
input
;
#define C(x) ((x)-'@') // Control-x
void
consoleintr
(
int
(
*
getc
)(
void
)
)
puts
(
const
char
*
s
)
{
int
c
;
uint8
*
p
,
*
ep
;
acquire
(
&
input
.
lock
);
while
((
c
=
getc
())
>=
0
){
switch
(
c
){
case
C
(
'P'
):
// Process listing.
procdumpall
();
break
;
case
C
(
'U'
):
// Kill line.
while
(
input
.
e
!=
input
.
w
&&
input
.
buf
[(
input
.
e
-
1
)
%
INPUT_BUF
]
!=
'\n'
){
input
.
e
--
;
consputc
(
BACKSPACE
);
}
break
;
case
C
(
'H'
):
case
'\x7f'
:
// Backspace
if
(
input
.
e
!=
input
.
w
){
input
.
e
--
;
consputc
(
BACKSPACE
);
}
break
;
default:
if
(
c
!=
0
&&
input
.
e
-
input
.
r
<
INPUT_BUF
){
c
=
(
c
==
'\r'
)
?
'\n'
:
c
;
input
.
buf
[
input
.
e
++
%
INPUT_BUF
]
=
c
;
consputc
(
c
);
if
(
c
==
'\n'
||
c
==
C
(
'D'
)
||
input
.
e
==
input
.
r
+
INPUT_BUF
){
input
.
w
=
input
.
e
;
cv_wakeup
(
&
input
.
cv
);
}
}
break
;
}
}
release
(
&
input
.
lock
);
}
p
=
(
uint8
*
)
s
;
ep
=
p
+
strlen
(
s
);
int
consoleread
(
struct
inode
*
ip
,
char
*
dst
,
int
n
)
{
uint
target
;
int
c
;
iunlock
(
ip
);
target
=
n
;
acquire
(
&
input
.
lock
);
while
(
n
>
0
){
while
(
input
.
r
==
input
.
w
){
if
(
proc
->
killed
){
release
(
&
input
.
lock
);
ilock
(
ip
,
1
);
return
-
1
;
}
cv_sleep
(
&
input
.
cv
,
&
input
.
lock
);
}
c
=
input
.
buf
[
input
.
r
++
%
INPUT_BUF
];
if
(
c
==
C
(
'D'
)){
// EOF
if
(
n
<
target
){
// Save ^D for next time, to make sure
// caller gets a 0-byte result.
input
.
r
--
;
}
break
;
}
*
dst
++
=
c
;
--
n
;
if
(
c
==
'\n'
)
break
;
}
release
(
&
input
.
lock
);
ilock
(
ip
,
1
);
for
(;
p
<
ep
;
p
++
)
writecons
(
NULL
,
*
p
);
return
target
-
n
;
}
int
consolewrite
(
struct
inode
*
ip
,
char
*
buf
,
int
n
)
void
__attribute__
((
noreturn
))
panic
(
const
char
*
s
)
{
int
i
;
puts
(
"panic: "
);
puts
(
s
);
puts
(
"
\n
"
);
iunlock
(
ip
);
acquire
(
&
cons
.
lock
);
for
(
i
=
0
;
i
<
n
;
i
++
)
consputc
(
buf
[
i
]
&
0xff
);
release
(
&
cons
.
lock
);
ilock
(
ip
,
1
);
return
n
;
for
(;;);
}
void
consoleinit
(
void
)
initconsole
(
void
)
{
initlock
(
&
cons
.
lock
,
"console"
);
initlock
(
&
input
.
lock
,
"input"
);
initcondvar
(
&
input
.
cv
,
"input"
);
devsw
[
CONSOLE
].
write
=
consolewrite
;
devsw
[
CONSOLE
].
read
=
consoleread
;
cons
.
locking
=
1
;
picenable
(
IRQ_KBD
);
ioapicenable
(
IRQ_KBD
,
0
);
// XXX(sbw) enable once we setup %gs
cons
.
locking
=
0
;
}
cpu.h
0 → 100644
浏览文件 @
89d00095
// Per-CPU state
struct
cpu
{
u8
id
;
// Local APIC ID; index into cpus[] below
int
ncli
;
// Depth of pushcli nesting.
int
intena
;
// Were interrupts enabled before pushcli?
#if 0
struct context *scheduler; // swtch() here to enter scheduler
struct taskstate ts; // Used by x86 to find stack for interrupt
struct segdesc gdt[NSEGS]; // x86 global descriptor table
volatile uint booted; // Has the CPU started?
int last_rcu_gc_ticks;
// Cpu-local storage variables; see below
struct cpu *cpu;
struct proc *proc; // The currently-running process.
struct kmem *kmem; // The per-core memory table
#endif
}
__mpalign__
;
// Per-CPU variables, holding pointers to the
// current cpu and to the current process.
// The asm suffix tells gcc to use "%gs:0" to refer to cpu
// and "%gs:4" to refer to proc. seginit sets up the
// %gs segment register so that %gs refers to the memory
// holding those two variables in the local cpu's struct cpu.
// This is similar to how thread-local variables are implemented
// in thread libraries such as Linux pthreads.
extern
struct
cpu
*
cpu
__asm
(
"%gs:0"
);
// &cpus[cpunum()].cpu
extern
struct
proc
*
proc
__asm
(
"%gs:8"
);
// cpus[cpunum()].proc
extern
struct
kmem
*
kmem
__asm
(
"%gs:16"
);
// &cpu[cpunum()].kmem
kernel.h
浏览文件 @
89d00095
#include "types.h"
#define KBASE 0xFFFFFFFF80000000ull
#define KADDR(x) ((void*)(KBASE+(uintptr)(x)))
#define PADDR(x) ((uintptr)(x) - KBASE)
#define PGSIZE (2*1024*1024ull)
#define KCSEG (2<<3)
/* kernel code segment */
#define KDSEG (3<<3)
/* kernel data segment */
#define nil ((void*)0)
#define NULL ((void *)0)
static
inline
uptr
v2p
(
void
*
a
)
{
return
(
uptr
)
a
-
KBASE
;
}
static
inline
void
*
p2v
(
uptr
a
)
{
return
(
void
*
)
a
+
KBASE
;
}
struct
spinlock
;
// console.c
void
cprintf
(
const
char
*
,
...);
void
panic
(
const
char
*
)
__attribute__
((
noreturn
));
// string.c
int
memcmp
(
const
void
*
,
const
void
*
,
u32
);
void
*
memmove
(
void
*
,
const
void
*
,
u32
);
void
*
memset
(
void
*
,
int
,
u32
);
char
*
safestrcpy
(
char
*
,
const
char
*
,
int
);
int
strlen
(
const
char
*
);
int
strncmp
(
const
char
*
,
const
char
*
,
u32
);
char
*
strncpy
(
char
*
,
const
char
*
,
int
);
int
strcmp
(
const
char
*
p
,
const
char
*
q
);
// spinlock.c
void
acquire
(
struct
spinlock
*
);
void
getcallerpcs
(
void
*
,
uptr
*
);
int
holding
(
struct
spinlock
*
);
void
initlock
(
struct
spinlock
*
,
char
*
);
void
release
(
struct
spinlock
*
);
void
pushcli
(
void
);
void
popcli
(
void
);
// cga.c
void
cgaputc
(
char
c
);
// uart.c
void
uartputc
(
char
c
);
void
memmove
(
void
*
dst
,
void
*
src
,
int64
n
);
int
strlen
(
const
char
*
);
main.c
浏览文件 @
89d00095
#include "types.h"
#include "multiboot.h"
#include "kernel.h"
extern
void
inituart
(
void
);
extern
void
initcga
(
void
);
extern
void
initconsole
(
void
);
extern
void
initmp
(
void
);
extern
void
inittrap
(
void
);
void
cmain
(
void
)
{
inituart
();
initcga
();
initconsole
();
#if 0
initmp();
inittrap();
#endif
panic
(
"end"
);
}
mp.c
浏览文件 @
89d00095
...
...
@@ -3,22 +3,17 @@
// http://developer.intel.com/design/pentium/datashts/24201606.pdf
#include "types.h"
#include "defs.h"
#include "param.h"
#include "memlayout.h"
#include "mp.h"
#include "x86.h"
#include "mmu.h"
#include "spinlock.h"
#include "condvar.h"
#include "queue.h"
#include "proc.h"
#include "mp.h"
#include "kernel.h"
#include "cpu.h"
struct
cpu
cpus
[
NCPU
];
static
struct
cpu
*
bcpu
__
attribute__
((
aligned
(
CACHELINE
)))
;
int
ismp
__
attribute__
((
aligned
(
CACHELINE
)))
;
int
ncpu
__
attribute__
((
aligned
(
CACHELINE
)))
;
u
char
ioapicid
__attribute__
((
aligned
(
CACHELINE
)))
;
static
struct
cpu
*
bcpu
__
mpalign__
;
int
ismp
__
mpalign__
;
int
ncpu
__
mpalign__
;
u
8
ioapicid
__mpalign__
;
int
mpbcpu
(
void
)
...
...
@@ -26,8 +21,8 @@ mpbcpu(void)
return
bcpu
-
cpus
;
}
static
u
char
sum
(
u
char
*
addr
,
int
len
)
static
u
8
sum
(
u
8
*
addr
,
int
len
)
{
int
i
,
sum
;
...
...
@@ -39,11 +34,11 @@ sum(uchar *addr, int len)
// Look for an MP structure in the len bytes at addr.
static
struct
mp
*
mpsearch1
(
u
char
*
addr
,
int
len
)
mpsearch1
(
u
8
*
addr
,
int
len
)
{
u
char
*
e
,
*
p
;
u
8
*
e
,
*
p
;
addr
=
p2v
((
u
int
)
addr
);
addr
=
p2v
((
u
ptr
)
addr
);
e
=
addr
+
len
;
for
(
p
=
addr
;
p
<
e
;
p
+=
sizeof
(
struct
mp
))
if
(
memcmp
(
p
,
"_MP_"
,
4
)
==
0
&&
sum
(
p
,
sizeof
(
struct
mp
))
==
0
)
...
...
@@ -59,20 +54,20 @@ mpsearch1(uchar *addr, int len)
static
struct
mp
*
mpsearch
(
void
)
{
u
char
*
bda
;
uint
p
;
u
8
*
bda
;
paddr
p
;
struct
mp
*
mp
;
bda
=
(
u
char
*
)
0x400
;
bda
=
(
u
8
*
)
0x400
;
if
((
p
=
((
bda
[
0x0F
]
<<
8
)
|
bda
[
0x0E
])
<<
4
)){
if
((
mp
=
mpsearch1
((
u
char
*
)
p
,
1024
)))
if
((
mp
=
mpsearch1
((
u
8
*
)
p
,
1024
)))
return
mp
;
}
else
{
p
=
((
bda
[
0x14
]
<<
8
)
|
bda
[
0x13
])
*
1024
;
if
((
mp
=
mpsearch1
((
u
char
*
)
p
-
1024
,
1024
)))
if
((
mp
=
mpsearch1
((
u
8
*
)
p
-
1024
,
1024
)))
return
mp
;
}
return
mpsearch1
((
u
char
*
)
0xF0000
,
0x10000
);
return
mpsearch1
((
u
8
*
)
0xF0000
,
0x10000
);
}
// Search for an MP configuration table. For now,
...
...
@@ -88,21 +83,21 @@ mpconfig(struct mp **pmp)
if
((
mp
=
mpsearch
())
==
0
||
mp
->
physaddr
==
0
)
return
0
;
conf
=
(
struct
mpconf
*
)
p2v
((
u
int
)
mp
->
physaddr
);
conf
=
(
struct
mpconf
*
)
p2v
((
u
ptr
)
mp
->
physaddr
);
if
(
memcmp
(
conf
,
"PCMP"
,
4
)
!=
0
)
return
0
;
if
(
conf
->
version
!=
1
&&
conf
->
version
!=
4
)
return
0
;
if
(
sum
((
u
char
*
)
conf
,
conf
->
length
)
!=
0
)
if
(
sum
((
u
8
*
)
conf
,
conf
->
length
)
!=
0
)
return
0
;
*
pmp
=
mp
;
return
conf
;
}
void
mpinit
(
void
)
initmp
(
void
)
{
u
char
*
p
,
*
e
;
u
8
*
p
,
*
e
;
struct
mp
*
mp
;
struct
mpconf
*
conf
;
struct
mpproc
*
proc
;
...
...
@@ -112,8 +107,8 @@ mpinit(void)
if
((
conf
=
mpconfig
(
&
mp
))
==
0
)
return
;
ismp
=
1
;
lapic
=
(
uint
*
)
conf
->
lapicaddr
;
for
(
p
=
(
u
char
*
)(
conf
+
1
),
e
=
(
uchar
*
)
conf
+
conf
->
length
;
p
<
e
;
){
for
(
p
=
(
u
8
*
)(
conf
+
1
),
e
=
(
u8
*
)
conf
+
conf
->
length
;
p
<
e
;
){
switch
(
*
p
){
case
MPPROC
:
proc
=
(
struct
mpproc
*
)
p
;
...
...
@@ -145,7 +140,6 @@ mpinit(void)
if
(
!
ismp
){
// Didn't like what we found; fall back to no MP.
ncpu
=
1
;
lapic
=
0
;
ioapicid
=
0
;
return
;
}
...
...
mp.h
浏览文件 @
89d00095
// See MultiProcessor Specification Version 1.[14]
struct
mp
{
// floating pointer
u
char
signature
[
4
];
// "_MP_"
void
*
physaddr
;
// phys addr of MP config table
u
char
length
;
// 1
u
char
specrev
;
// [14]
u
char
checksum
;
// all bytes must add up to 0
u
char
type
;
// MP system config type
u
char
imcrp
;
u
char
reserved
[
3
];
u
8
signature
[
4
];
// "_MP_"
u32
physaddr
;
// phys addr of MP config table
u
8
length
;
// 1
u
8
specrev
;
// [14]
u
8
checksum
;
// all bytes must add up to 0
u
8
type
;
// MP system config type
u
8
imcrp
;
u
8
reserved
[
3
];
};
struct
mpconf
{
// configuration table header
u
char
signature
[
4
];
// "PCMP"
u
short
length
;
// total table length
u
char
version
;
// [14]
u
char
checksum
;
// all bytes must add up to 0
u
char
product
[
20
];
// product id
u
int
*
oemtable
;
// OEM table pointer
u
short
oemlength
;
// OEM table length
u
short
entry
;
// entry count
u
int
*
lapicaddr
;
// address of local APIC
u
short
xlength
;
// extended table length
u
char
xchecksum
;
// extended table checksum
u
char
reserved
;
u
8
signature
[
4
];
// "PCMP"
u
16
length
;
// total table length
u
8
version
;
// [14]
u
8
checksum
;
// all bytes must add up to 0
u
8
product
[
20
];
// product id
u
32
oemtable
;
// OEM table pointer
u
16
oemlength
;
// OEM table length
u
16
entry
;
// entry count
u
32
lapicaddr
;
// address of local APIC
u
16
xlength
;
// extended table length
u
8
xchecksum
;
// extended table checksum
u
8
reserved
;
};
struct
mpproc
{
// processor table entry
u
char
type
;
// entry type (0)
u
char
apicid
;
// local APIC id
u
char
version
;
// local APIC verison
u
char
flags
;
// CPU flags
u
8
type
;
// entry type (0)
u
8
apicid
;
// local APIC id
u
8
version
;
// local APIC verison
u
8
flags
;
// CPU flags
#define MPBOOT 0x02 // This proc is the bootstrap processor.
u
char
signature
[
4
];
// CPU signature
u
int
feature
;
// feature flags from CPUID instruction
u
char
reserved
[
8
];
u
8
signature
[
4
];
// CPU signature
u
32
feature
;
// feature flags from CPUID instruction
u
8
reserved
[
8
];
};
struct
mpioapic
{
// I/O APIC table entry
u
char
type
;
// entry type (2)
u
char
apicno
;
// I/O APIC id
u
char
version
;
// I/O APIC version
u
char
flags
;
// I/O APIC flags
u
int
*
addr
;
// I/O APIC address
u
8
type
;
// entry type (2)
u
8
apicno
;
// I/O APIC id
u
8
version
;
// I/O APIC version
u
8
flags
;
// I/O APIC flags
u
32
addr
;
// I/O APIC address
};
// Table entry types
...
...
param.h
浏览文件 @
89d00095
...
...
@@ -10,5 +10,6 @@
#define MAXARG 32 // max exec arguments
#define MAXNAME 16 // max string names
#define MINCYCTHRESH 1000000 // min cycles a proc executes on a core before allowed to be stolen
#define INF
0xFFFFFFFF
#define INF
(~0UL)
#define CACHELINE 64 // cache line size
#define MTRACE 0
spinlock.c
浏览文件 @
89d00095
// Mutual exclusion spin locks.
#include "types.h"
#include "
defs
.h"
#include "
kernel
.h"
#include "param.h"
#include "x86.h"
#include "
memlayout
.h"
#include "
mmu
.h"
#include "
cpu
.h"
#include "
bits
.h"
#include "spinlock.h"
#include "condvar.h"
#include "queue.h"
#include "proc.h"
#include "xv6-mtrace.h"
void
...
...
@@ -49,7 +46,7 @@ acquire(struct spinlock *lk)
// The xchg is atomic.
// It also serializes, so that reads after acquire are not
// reordered before it.
while
(
xchg
(
&
lk
->
locked
,
1
)
!=
0
)
while
(
xchg
32
(
&
lk
->
locked
,
1
)
!=
0
)
;
mtrace_lock_register
(
RET_EIP
(),
...
...
@@ -104,24 +101,24 @@ release(struct spinlock *lk)
// after a store. So lock->locked = 0 would work here.
// The xchg being asm volatile ensures gcc emits it after
// the above assignments (and after the critical section).
xchg
(
&
lk
->
locked
,
0
);
xchg
32
(
&
lk
->
locked
,
0
);
popcli
();
}
// Record the current call stack in pcs[] by following the %ebp chain.
void
getcallerpcs
(
void
*
v
,
u
int
pcs
[])
getcallerpcs
(
void
*
v
,
u
ptr
pcs
[])
{
u
int
*
e
bp
;
u
ptr
*
r
bp
;
int
i
;
ebp
=
(
uint
*
)
v
-
2
;
rbp
=
(
uptr
*
)
v
-
2
;
for
(
i
=
0
;
i
<
10
;
i
++
){
if
(
ebp
==
0
||
ebp
<
(
uint
*
)
KERNBASE
||
ebp
==
(
uint
*
)
0xffffffff
)
if
(
rbp
==
0
||
rbp
<
(
uptr
*
)
KBASE
||
rbp
==
(
uptr
*
)(
~
0UL
)
)
break
;
pcs
[
i
]
=
ebp
[
1
];
// saved %e
ip
ebp
=
(
uint
*
)
ebp
[
0
];
// saved %e
bp
pcs
[
i
]
=
rbp
[
1
];
// saved %r
ip
rbp
=
(
uptr
*
)
rbp
[
0
];
// saved %r
bp
}
for
(;
i
<
10
;
i
++
)
pcs
[
i
]
=
0
;
...
...
@@ -144,22 +141,21 @@ holding(struct spinlock *lock)
void
pushcli
(
void
)
{
int
e
flags
;
u64
r
flags
;
eflags
=
reade
flags
();
rflags
=
readr
flags
();
cli
();
if
(
cpu
->
ncli
++
==
0
)
cpu
->
intena
=
e
flags
&
FL_IF
;
cpu
->
intena
=
r
flags
&
FL_IF
;
}
void
popcli
(
void
)
{
if
(
read
e
flags
()
&
FL_IF
)
if
(
read
r
flags
()
&
FL_IF
)
panic
(
"popcli - interruptible"
);
if
(
--
cpu
->
ncli
<
0
)
panic
(
"popcli"
);
if
(
cpu
->
ncli
==
0
&&
cpu
->
intena
)
sti
();
}
spinlock.h
浏览文件 @
89d00095
...
...
@@ -4,13 +4,13 @@
// Mutual exclusion lock.
struct
spinlock
{
u
int
locked
;
// Is the lock held?
u
32
locked
;
// Is the lock held?
#if SPINLOCK_DEBUG
// For debugging:
char
*
name
;
// Name of lock.
struct
cpu
*
cpu
;
// The cpu holding the lock.
u
int
pcs
[
10
];
// The call stack (an array of program counters)
u
ptr
pcs
[
10
];
// The call stack (an array of program counters)
// that locked the lock.
#endif
};
...
...
trap.c
浏览文件 @
89d00095
...
...
@@ -3,11 +3,61 @@
extern
Segdesc
bootgdt
[
NUMSEG
];
void
inittrap
(
void
)
{
}
// Bootstrap GDT. Used by boot.S but defined in C
// so we can use the data structure macros in amd64.h.
Segdesc
bootgdt
[
NUMSEG
]
=
{
SEGDESC
(
0
,
0
,
0
),
// null
SEGDESC
(
0
,
0xfffff
,
SEG_R
|
SEG_CODE
|
SEG_S
|
SEG_DPL
(
0
)
|
SEG_P
|
SEG_D
|
SEG_G
),
// 32-bit kernel code
SEGDESC
(
0
,
0
,
SEG_R
|
SEG_CODE
|
SEG_S
|
SEG_DPL
(
0
)
|
SEG_P
|
SEG_L
|
SEG_G
),
// 64-bit kernel code
SEGDESC
(
0
,
0xfffff
,
SEG_W
|
SEG_S
|
SEG_DPL
(
0
)
|
SEG_P
|
SEG_D
|
SEG_G
),
// kernel data
SEGDESC
(
0
,
0
,
0
),
// null
SEGDESC
(
0
,
0xfffff
,
SEG_R
|
SEG_CODE
|
SEG_S
|
SEG_DPL
(
0
)
|
SEG_P
|
SEG_D
|
SEG_G
),
// 32-bit kernel code
SEGDESC
(
0
,
0
,
SEG_R
|
SEG_CODE
|
SEG_S
|
SEG_DPL
(
0
)
|
SEG_P
|
SEG_L
|
SEG_G
),
// 64-bit kernel code
SEGDESC
(
0
,
0xfffff
,
SEG_W
|
SEG_S
|
SEG_DPL
(
0
)
|
SEG_P
|
SEG_D
|
SEG_G
),
// kernel data
};
#if 0
Intdesc idt[256];
Segdesc gdt[NUMSEG];
extern Segdesc bootgdt[NUMSEG];
extern uint64 trapentry[];
static Taskseg ts;
static char istack[8192];
void
inittrap(void)
{
int i;
uint32 bits;
uint64 base, entry;
bits = INT_P | SEG_INTR64; // present, interrupt gate
for(i=0; i<256; i++) {
entry = trapentry[i];
idt[i] = INTDESC(KCSEG, entry, bits);
}
memmove(gdt, bootgdt, sizeof gdt);
base = (uintptr)&ts;
gdt[TSSSEG>>3] = SEGDESC(base, (sizeof ts-1), SEG_P|SEG_TSS64A);
gdt[(TSSSEG>>3)+1] = SEGDESCHI(base);
ts.rsp0 = (uintptr)istack+sizeof istack;
lidt(idt, sizeof idt);
lgdt(gdt, sizeof gdt);
ltr(TSSSEG);
}
void
trap(void)
{
panic("trap");
}
#endif
types.h
浏览文件 @
89d00095
...
...
@@ -10,3 +10,7 @@ typedef uint16 u16;
typedef
uint32
u32
;
typedef
int64
s64
;
typedef
uint64
u64
;
typedef
uint64
uptr
;
typedef
uptr
paddr
;
#define __mpalign__ __attribute__((aligned(CACHELINE)))
uart.c
浏览文件 @
89d00095
// Intel 8250 serial port (UART).
#include "types.h"
#include "kernel.h"
#include "x86.h"
...
...
@@ -7,7 +8,7 @@
static
int
uart
;
// is there a uart?
void
uartputc
(
int
c
)
uartputc
(
char
c
)
{
int
i
;
...
...
@@ -45,6 +46,6 @@ inituart(void)
inb
(
COM1
+
0
);
// Announce that we're here.
for
(
p
=
"
xv6
...
\n
"
;
*
p
;
p
++
)
for
(
p
=
"
uart
...
\n
"
;
*
p
;
p
++
)
uartputc
(
*
p
);
}
x86.h
浏览文件 @
89d00095
...
...
@@ -30,3 +30,36 @@ microdelay(u32 delay)
{
}
static
inline
u32
xchg32
(
volatile
u32
*
addr
,
u32
newval
)
{
u32
result
;
// The + in "+m" denotes a read-modify-write operand.
__asm
volatile
(
"lock; xchgl %0, %1"
:
"+m"
(
*
addr
),
"=a"
(
result
)
:
"1"
(
newval
)
:
"cc"
);
return
result
;
}
static
inline
u64
readrflags
(
void
)
{
u64
rflags
;
__asm
volatile
(
"pushfq; popq %0"
:
"=r"
(
rflags
));
return
rflags
;
}
static
inline
void
cli
(
void
)
{
__asm
volatile
(
"cli"
);
}
static
inline
void
sti
(
void
)
{
__asm
volatile
(
"sti"
);
}
xv6-mtrace.h
浏览文件 @
89d00095
#if MTRACE
typedef
__signed
char
int8_t
;
typedef
unsigned
char
uint8_t
;
typedef
short
int16_t
;
...
...
@@ -10,9 +11,12 @@ typedef unsigned long long uint64_t;
typedef
__PTRDIFF_TYPE__
intptr_t
;
typedef
unsigned
__PTRDIFF_TYPE__
uintptr_t
;
void
*
memcpy
(
void
*
dst
,
const
void
*
src
,
u
int
n
);
void
*
memcpy
(
void
*
dst
,
const
void
*
src
,
u
32
n
);
char
*
strncpy
(
char
*
s
,
const
char
*
t
,
int
n
);
#define RET_EIP() ((unsigned long)__builtin_return_address(0))
#include "mtrace-magic.h"
#else
#define mtrace_lock_register(ip, x, name, op, y)
#endif
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论