Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
b22d8982
提交
b22d8982
7月 05, 2006
创建
作者:
kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
timer interrupts
disk interrupts (assuming bochs has a bug)
上级
8b4e2a08
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
198 行增加
和
151 行删除
+198
-151
defs.h
defs.h
+6
-0
ide.c
ide.c
+67
-60
main.c
main.c
+4
-2
mp.c
mp.c
+42
-19
picirq.c
picirq.c
+68
-63
proc.h
proc.h
+0
-1
string.c
string.c
+11
-0
trap.c
trap.c
+0
-1
x86.h
x86.h
+0
-5
没有找到文件。
defs.h
浏览文件 @
b22d8982
...
...
@@ -25,11 +25,13 @@ void * memcpy(void *dst, void *src, unsigned n);
void
*
memset
(
void
*
dst
,
int
c
,
unsigned
n
);
int
memcmp
(
const
void
*
v1
,
const
void
*
v2
,
unsigned
n
);
void
*
memmove
(
void
*
dst
,
const
void
*
src
,
unsigned
n
);
int
strncmp
(
const
char
*
p
,
const
char
*
q
,
unsigned
n
);
// syscall.c
void
syscall
(
void
);
// picirq.c
extern
uint16_t
irq_mask_8259A
;
void
irq_setmask_8259A
(
uint16_t
mask
);
void
pic_init
(
void
);
...
...
@@ -66,3 +68,7 @@ struct fd * fd_alloc();
void
fd_close
(
struct
fd
*
);
int
fd_read
(
struct
fd
*
fd
,
char
*
addr
,
int
n
);
int
fd_write
(
struct
fd
*
fd
,
char
*
addr
,
int
n
);
// ide.c
void
ide_init
(
void
);
int
ide_read
(
uint32_t
secno
,
void
*
dst
,
unsigned
nsecs
);
ide.c
浏览文件 @
b22d8982
...
...
@@ -21,97 +21,104 @@ static int diskno = 0;
static
int
ide_wait_ready
(
int
check_error
)
{
int
r
;
int
r
;
while
(((
r
=
inb
(
0x1F7
))
&
(
IDE_BSY
|
IDE_DRDY
))
!=
IDE_DRDY
)
/* do nothing */
;
while
(((
r
=
inb
(
0x1F7
))
&
(
IDE_BSY
|
IDE_DRDY
))
!=
IDE_DRDY
)
/* do nothing */
;
if
(
check_error
&&
(
r
&
(
IDE_DF
|
IDE_ERR
))
!=
0
)
return
-
1
;
return
0
;
if
(
check_error
&&
(
r
&
(
IDE_DF
|
IDE_ERR
))
!=
0
)
return
-
1
;
return
0
;
}
void
ide_init
(
void
)
{
cprintf
(
"ide_init: enable IRQ 14
\n
"
);
irq_setmask_8259A
(
irq_mask_8259A
&
~
(
1
<<
14
));
ide_wait_ready
(
0
);
}
int
ide_probe_disk1
(
void
)
{
int
r
,
x
;
int
r
,
x
;
// wait for Device 0 to be ready
ide_wait_ready
(
0
);
// wait for Device 0 to be ready
ide_wait_ready
(
0
);
// switch to Device 1
outb
(
0x1F6
,
0xE0
|
(
1
<<
4
));
// switch to Device 1
outb
(
0x1F6
,
0xE0
|
(
1
<<
4
));
// check for Device 1 to be ready for a while
for
(
x
=
0
;
x
<
1000
&&
(
r
=
inb
(
0x1F7
))
==
0
;
x
++
)
/* do nothing */
;
// check for Device 1 to be ready for a while
for
(
x
=
0
;
x
<
1000
&&
(
r
=
inb
(
0x1F7
))
==
0
;
x
++
)
/* do nothing */
;
// switch back to Device 0
outb
(
0x1F6
,
0xE0
|
(
0
<<
4
));
// switch back to Device 0
outb
(
0x1F6
,
0xE0
|
(
0
<<
4
));
cprintf
(
"Device 1 presence: %d
\n
"
,
(
x
<
1000
));
return
(
x
<
1000
);
cprintf
(
"Device 1 presence: %d
\n
"
,
(
x
<
1000
));
return
(
x
<
1000
);
}
void
ide_set_disk
(
int
d
)
{
if
(
d
!=
0
&&
d
!=
1
)
panic
(
"bad disk number"
);
diskno
=
d
;
if
(
d
!=
0
&&
d
!=
1
)
panic
(
"bad disk number"
);
diskno
=
d
;
}
int
ide_read
(
uint32_t
secno
,
void
*
dst
,
unsigned
nsecs
)
{
int
r
;
if
(
nsecs
>
256
)
panic
(
"ide_read"
);
ide_wait_ready
(
0
);
outb
(
0x3f6
,
0
);
outb
(
0x1F2
,
nsecs
);
outb
(
0x1F3
,
secno
&
0xFF
);
outb
(
0x1F4
,
(
secno
>>
8
)
&
0xFF
);
outb
(
0x1F5
,
(
secno
>>
16
)
&
0xFF
);
outb
(
0x1F6
,
0xE0
|
((
diskno
&
1
)
<<
4
)
|
((
secno
>>
24
)
&
0x0F
));
outb
(
0x1F7
,
0x20
);
// CMD 0x20 means read sector
sleep
(
0
);
for
(;
nsecs
>
0
;
nsecs
--
,
dst
+=
512
)
{
if
((
r
=
ide_wait_ready
(
1
))
<
0
)
return
r
;
insl
(
0x1F0
,
dst
,
512
/
4
);
}
int
r
;
if
(
nsecs
>
256
)
panic
(
"ide_read"
);
ide_wait_ready
(
0
);
outb
(
0x3f6
,
0
);
outb
(
0x1F2
,
nsecs
);
outb
(
0x1F3
,
secno
&
0xFF
);
outb
(
0x1F4
,
(
secno
>>
8
)
&
0xFF
);
outb
(
0x1F5
,
(
secno
>>
16
)
&
0xFF
);
outb
(
0x1F6
,
0xE0
|
((
diskno
&
1
)
<<
4
)
|
((
secno
>>
24
)
&
0x0F
));
outb
(
0x1F7
,
0x20
);
// CMD 0x20 means read sector
for
(;
nsecs
>
0
;
nsecs
--
,
dst
+=
512
)
{
if
((
r
=
ide_wait_ready
(
1
))
<
0
)
return
r
;
insl
(
0x1F0
,
dst
,
512
/
4
);
}
return
0
;
return
0
;
}
int
ide_write
(
uint32_t
secno
,
const
void
*
src
,
unsigned
nsecs
)
{
int
r
;
int
r
;
if
(
nsecs
>
256
)
panic
(
"ide_write"
);
if
(
nsecs
>
256
)
panic
(
"ide_write"
);
ide_wait_ready
(
0
);
ide_wait_ready
(
0
);
outb
(
0x1F2
,
nsecs
);
outb
(
0x1F3
,
secno
&
0xFF
);
outb
(
0x1F4
,
(
secno
>>
8
)
&
0xFF
);
outb
(
0x1F5
,
(
secno
>>
16
)
&
0xFF
);
outb
(
0x1F6
,
0xE0
|
((
diskno
&
1
)
<<
4
)
|
((
secno
>>
24
)
&
0x0F
));
outb
(
0x1F7
,
0x30
);
// CMD 0x30 means write sector
outb
(
0x1F2
,
nsecs
);
outb
(
0x1F3
,
secno
&
0xFF
);
outb
(
0x1F4
,
(
secno
>>
8
)
&
0xFF
);
outb
(
0x1F5
,
(
secno
>>
16
)
&
0xFF
);
outb
(
0x1F6
,
0xE0
|
((
diskno
&
1
)
<<
4
)
|
((
secno
>>
24
)
&
0x0F
));
outb
(
0x1F7
,
0x30
);
// CMD 0x30 means write sector
for
(;
nsecs
>
0
;
nsecs
--
,
src
+=
512
)
{
if
((
r
=
ide_wait_ready
(
1
))
<
0
)
return
r
;
outsl
(
0x1F0
,
src
,
512
/
4
);
}
for
(;
nsecs
>
0
;
nsecs
--
,
src
+=
512
)
{
if
((
r
=
ide_wait_ready
(
1
))
<
0
)
return
r
;
outsl
(
0x1F0
,
src
,
512
/
4
);
}
return
0
;
return
0
;
}
main.c
浏览文件 @
b22d8982
...
...
@@ -36,7 +36,7 @@ main()
cprintf
(
"
\n
xV6
\n\n
"
);
pic_init
();
// initialize PIC
---not clear why
pic_init
();
// initialize PIC
mp_init
();
// multiprocessor
kinit
();
// physical memory allocator
tvinit
();
// trap vectors
...
...
@@ -59,12 +59,14 @@ main()
p
->
ppid
=
0
;
setupsegs
(
p
);
write_eflags
(
read_eflags
()
|
FL_IF
);
// turn on interrupts on boot processor
lapic_timerinit
();
lapic_enableintr
();
write_eflags
(
read_eflags
()
|
FL_IF
);
#if 0
ide_init();
ide_read(0, buf, 1);
cprintf("sec0.0 %x\n", buf[0] & 0xff);
#endif
...
...
mp.c
浏览文件 @
b22d8982
...
...
@@ -92,6 +92,28 @@ enum { /* LAPIC_TDCR */
LAPIC_X1
=
0x0000000B
,
/* divide by 1 */
};
static
char
*
buses
[]
=
{
"CBUSI "
,
"CBUSII"
,
"EISA "
,
"FUTURE"
,
"INTERN"
,
"ISA "
,
"MBI "
,
"MBII "
,
"MCA "
,
"MPI "
,
"MPSA "
,
"NUBUS "
,
"PCI "
,
"PCMCIA"
,
"TC "
,
"VL "
,
"VME "
,
"XPRESS"
,
0
,
};
#define APBOOTCODE 0x7000 // XXX hack
static
struct
MP
*
mp
;
// The MP floating point structure
...
...
@@ -126,7 +148,7 @@ lapic_timerinit()
void
lapic_timerintr
()
{
//
cprintf("%d: timer interrupt!\n", cpu());
cprintf
(
"%d: timer interrupt!
\n
"
,
cpu
());
lapic_write
(
LAPIC_EOI
,
0
);
}
...
...
@@ -137,23 +159,17 @@ lapic_init(int c)
cprintf
(
"lapic_init %d
\n
"
,
c
);
irq_setmask_8259A
(
0xFFFF
);
lapic_write
(
LAPIC_DFR
,
0xFFFFFFFF
);
// set destination format register
r
=
(
lapic_read
(
LAPIC_ID
)
>>
24
)
&
0xFF
;
// read APIC ID
lapic_write
(
LAPIC_LDR
,
(
1
<<
r
)
<<
24
);
// set logical destination register to r
lapic_write
(
LAPIC_TPR
,
0xFF
);
// no interrupts for now
lapic_write
(
LAPIC_SVR
,
LAPIC_ENABLE
|
(
IRQ_OFFSET
+
IRQ_SPURIOUS
));
// enable APIC
lapic_write
(
LAPIC_DFR
,
0xFFFFFFFF
);
r
=
(
lapic_read
(
LAPIC_ID
)
>>
24
)
&
0xFF
;
lapic_write
(
LAPIC_LDR
,
(
1
<<
r
)
<<
24
);
lapic_write
(
LAPIC_TPR
,
0xFF
);
lapic_write
(
LAPIC_SVR
,
LAPIC_ENABLE
|
(
IRQ_OFFSET
+
IRQ_SPURIOUS
));
// in virtual wire mode, set up the LINT0 and LINT1 as follows:
lapic_write
(
LAPIC_LINT0
,
APIC_IMASK
|
APIC_EXTINT
);
lapic_write
(
LAPIC_LINT1
,
APIC_IMASK
|
APIC_NMI
);
/*
* Set the local interrupts. It's likely these should just be
* masked off for SMP mode as some Pentium Pros have problems if
* LINT[01] are set to ExtINT.
* Acknowledge any outstanding interrupts.
*/
lapic_write
(
LAPIC_LINT0
,
cpus
[
c
].
lintr
[
0
]);
lapic_write
(
LAPIC_LINT1
,
cpus
[
c
].
lintr
[
1
]);
lapic_write
(
LAPIC_EOI
,
0
);
lapic_write
(
LAPIC_EOI
,
0
);
// acknowledge any outstanding interrupts.
lvt
=
(
lapic_read
(
LAPIC_VER
)
>>
16
)
&
0xFF
;
if
(
lvt
>=
4
)
...
...
@@ -290,7 +306,7 @@ mp_detect(void)
if
(
sum
||
(
pcmp
->
version
!=
1
&&
pcmp
->
version
!=
4
))
return
3
;
cprintf
(
"Mp spec rev #: %x
\n
"
,
mp
->
specrev
);
cprintf
(
"Mp spec rev #: %x
imcrp 0x%x
\n
"
,
mp
->
specrev
,
mp
->
imcrp
);
return
0
;
}
...
...
@@ -308,8 +324,10 @@ mp_init()
uint8_t
*
p
,
*
e
;
struct
MPCTB
*
mpctb
;
struct
MPPE
*
proc
;
struct
MPBE
*
bus
;
int
c
;
extern
int
main
();
int
i
;
ncpu
=
0
;
if
((
r
=
mp_detect
())
!=
0
)
return
;
...
...
@@ -332,8 +350,6 @@ mp_init()
case
MPPROCESSOR
:
proc
=
(
struct
MPPE
*
)
p
;
cpus
[
ncpu
].
apicid
=
proc
->
apicid
;
cpus
[
ncpu
].
lintr
[
0
]
=
APIC_IMASK
;
cpus
[
ncpu
].
lintr
[
1
]
=
APIC_IMASK
;
cprintf
(
"a processor %x
\n
"
,
cpus
[
ncpu
].
apicid
);
if
(
proc
->
flags
&
MPBP
)
{
bcpu
=
&
cpus
[
ncpu
];
...
...
@@ -342,6 +358,12 @@ mp_init()
p
+=
sizeof
(
struct
MPPE
);
continue
;
case
MPBUS
:
bus
=
(
struct
MPBE
*
)
p
;
for
(
i
=
0
;
buses
[
i
];
i
++
){
if
(
strncmp
(
buses
[
i
],
bus
->
string
,
sizeof
(
bus
->
string
))
==
0
)
break
;
}
cprintf
(
"a bus %d
\n
"
,
i
);
p
+=
sizeof
(
struct
MPBE
);
continue
;
case
MPIOAPIC
:
...
...
@@ -349,6 +371,7 @@ mp_init()
p
+=
sizeof
(
struct
MPIOAPIC
);
continue
;
case
MPIOINTR
:
cprintf
(
"an I/O intr
\n
"
);
p
+=
sizeof
(
struct
MPIE
);
continue
;
default:
...
...
picirq.c
浏览文件 @
b22d8982
...
...
@@ -4,80 +4,85 @@
#include "x86.h"
#include "defs.h"
// I/O Addresses of the two 8259A programmable interrupt controllers
#define IO_PIC1 0x20 // Master (IRQs 0-7)
#define IO_PIC2 0xA0 // Slave (IRQs 8-15)
#define IRQ_SLAVE 2 // IRQ at which slave connects to master
// Current IRQ mask.
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
uint16_t
irq_mask_8259A
=
0xFFFF
&
~
(
1
<<
IRQ_SLAVE
);
static
int
didinit
;
/* Initialize the 8259A interrupt controllers. */
void
pic_init
(
void
)
{
didinit
=
1
;
// mask all interrupts
outb
(
IO_PIC1
+
1
,
0xFF
);
outb
(
IO_PIC2
+
1
,
0xFF
);
// Set up master (8259A-1)
// ICW1: 0001g0hi
// g: 0 = edge triggering, 1 = level triggering
// h: 0 = cascaded PICs, 1 = master only
// i: 0 = no ICW4, 1 = ICW4 required
outb
(
IO_PIC1
,
0x11
);
// ICW2: Vector offset
outb
(
IO_PIC1
+
1
,
IRQ_OFFSET
);
// ICW3: bit mask of IR lines connected to slave PICs (master PIC),
// 3-bit No of IR line at which slave connects to master(slave PIC).
outb
(
IO_PIC1
+
1
,
1
<<
IRQ_SLAVE
);
// ICW4: 000nbmap
// n: 1 = special fully nested mode
// b: 1 = buffered mode
// m: 0 = slave PIC, 1 = master PIC
// (ignored when b is 0, as the master/slave role
// can be hardwired).
// a: 1 = Automatic EOI mode
// p: 0 = MCS-80/85 mode, 1 = intel x86 mode
outb
(
IO_PIC1
+
1
,
0x3
);
// Set up slave (8259A-2)
outb
(
IO_PIC2
,
0x11
);
// ICW1
outb
(
IO_PIC2
+
1
,
IRQ_OFFSET
+
8
);
// ICW2
outb
(
IO_PIC2
+
1
,
IRQ_SLAVE
);
// ICW3
// NB Automatic EOI mode doesn't tend to work on the slave.
// Linux source code says it's "to be investigated".
outb
(
IO_PIC2
+
1
,
0x01
);
// ICW4
// OCW3: 0ef01prs
// ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask
// p: 0 = no polling, 1 = polling mode
// rs: 0x = NOP, 10 = read IRR, 11 = read ISR
outb
(
IO_PIC1
,
0x68
);
/* clear specific mask */
outb
(
IO_PIC1
,
0x0a
);
/* read IRR by default */
outb
(
IO_PIC2
,
0x68
);
/* OCW3 */
outb
(
IO_PIC2
,
0x0a
);
/* OCW3 */
if
(
irq_mask_8259A
!=
0xFFFF
)
irq_setmask_8259A
(
irq_mask_8259A
);
// mask all interrupts
outb
(
IO_PIC1
+
1
,
0xFF
);
outb
(
IO_PIC2
+
1
,
0xFF
);
// Set up master (8259A-1)
// ICW1: 0001g0hi
// g: 0 = edge triggering, 1 = level triggering
// h: 0 = cascaded PICs, 1 = master only
// i: 0 = no ICW4, 1 = ICW4 required
outb
(
IO_PIC1
,
0x11
);
// ICW2: Vector offset
outb
(
IO_PIC1
+
1
,
IRQ_OFFSET
);
// ICW3: bit mask of IR lines connected to slave PICs (master PIC),
// 3-bit No of IR line at which slave connects to master(slave PIC).
outb
(
IO_PIC1
+
1
,
1
<<
IRQ_SLAVE
);
// ICW4: 000nbmap
// n: 1 = special fully nested mode
// b: 1 = buffered mode
// m: 0 = slave PIC, 1 = master PIC
// (ignored when b is 0, as the master/slave role
// can be hardwired).
// a: 1 = Automatic EOI mode
// p: 0 = MCS-80/85 mode, 1 = intel x86 mode
outb
(
IO_PIC1
+
1
,
0x3
);
// Set up slave (8259A-2)
outb
(
IO_PIC2
,
0x11
);
// ICW1
outb
(
IO_PIC2
+
1
,
IRQ_OFFSET
+
8
);
// ICW2
outb
(
IO_PIC2
+
1
,
IRQ_SLAVE
);
// ICW3
// NB Automatic EOI mode doesn't tend to work on the slave.
// Linux source code says it's "to be investigated".
outb
(
IO_PIC2
+
1
,
0x3
);
// ICW4
// OCW3: 0ef01prs
// ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask
// p: 0 = no polling, 1 = polling mode
// rs: 0x = NOP, 10 = read IRR, 11 = read ISR
outb
(
IO_PIC1
,
0x68
);
/* clear specific mask */
outb
(
IO_PIC1
,
0x0a
);
/* read IRR by default */
outb
(
IO_PIC2
,
0x68
);
/* OCW3 */
outb
(
IO_PIC2
,
0x0a
);
/* OCW3 */
if
(
irq_mask_8259A
!=
0xFFFF
)
irq_setmask_8259A
(
irq_mask_8259A
);
}
void
irq_setmask_8259A
(
uint16_t
mask
)
{
int
i
;
irq_mask_8259A
=
mask
;
if
(
!
didinit
)
return
;
outb
(
IO_PIC1
+
1
,
(
char
)
mask
);
outb
(
IO_PIC2
+
1
,
(
char
)(
mask
>>
8
));
cprintf
(
"enabled interrupts:"
);
for
(
i
=
0
;
i
<
16
;
i
++
)
if
(
~
mask
&
(
1
<<
i
))
cprintf
(
" %d"
,
i
);
cprintf
(
"
\n
"
);
int
i
;
irq_mask_8259A
=
mask
;
outb
(
IO_PIC1
+
1
,
(
char
)
mask
);
outb
(
IO_PIC2
+
1
,
(
char
)(
mask
>>
8
));
cprintf
(
"%d: enabled interrupts:"
,
cpu
());
for
(
i
=
0
;
i
<
16
;
i
++
)
if
(
~
mask
&
(
1
<<
i
))
cprintf
(
" %d"
,
i
);
cprintf
(
"
\n
"
);
}
proc.h
浏览文件 @
b22d8982
...
...
@@ -42,7 +42,6 @@ extern struct proc *curproc[NCPU];
struct
cpu
{
uint8_t
apicid
;
// Local APIC ID
int
lintr
[
2
];
// Local APIC
char
mpstack
[
MPSTACK
];
// per-cpu start-up stack, only used to get into main()
};
...
...
string.c
浏览文件 @
b22d8982
...
...
@@ -58,3 +58,14 @@ memmove(void *dst, const void *src, unsigned n)
return
dst
;
}
int
strncmp
(
const
char
*
p
,
const
char
*
q
,
unsigned
n
)
{
while
(
n
>
0
&&
*
p
&&
*
p
==
*
q
)
n
--
,
p
++
,
q
++
;
if
(
n
==
0
)
return
0
;
else
return
(
int
)
((
unsigned
char
)
*
p
-
(
unsigned
char
)
*
q
);
}
trap.c
浏览文件 @
b22d8982
...
...
@@ -61,7 +61,6 @@ trap(struct Trapframe *tf)
return
;
}
cprintf
(
"trap %d eip %x:%x
\n
"
,
tf
->
tf_trapno
,
tf
->
tf_cs
,
tf
->
tf_eip
);
// XXX probably ought to lgdt on trap return
...
...
x86.h
浏览文件 @
b22d8982
...
...
@@ -352,11 +352,6 @@ struct Trapframe {
#define MAX_IRQS 16 // Number of IRQs
// I/O Addresses of the two 8259A programmable interrupt controllers
#define IO_PIC1 0x20 // Master (IRQs 0-7)
#define IO_PIC2 0xA0 // Slave (IRQs 8-15)
#define IRQ_SLAVE 2 // IRQ at which slave connects to master
#define IRQ_OFFSET 32 // IRQ 0 corresponds to int IRQ_OFFSET
#define IRQ_ERROR 19
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论