Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
X
Xv6 Riscv Tp
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Chaumont Aymeric
Xv6 Riscv Tp
Commits
9be72339
Commit
9be72339
authored
8 months ago
by
Chaumont Aymeric
Browse files
Options
Downloads
Patches
Plain Diff
completed activity 7.2
parent
20f00294
Branches
tp2-a-7-2
Branches containing commit
Tags
tp2-act-7-2
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
kernel/trap.c
+133
-92
133 additions, 92 deletions
kernel/trap.c
with
133 additions
and
92 deletions
kernel/trap.c
+
133
−
92
View file @
9be72339
...
...
@@ -20,36 +20,45 @@ extern int devintr();
static
const
char
*
scause_desc
(
uint64
stval
);
void
trapinit
(
void
)
void
trapinit
(
void
)
{
initlock
(
&
tickslock
,
"time"
);
}
// set up to take exceptions and traps while in the kernel.
void
trapinithart
(
void
)
void
trapinithart
(
void
)
{
w_stvec
((
uint64
)
kernelvec
);
}
int
handle_page_fault
(
struct
proc
*
p
,
uint64
scause
,
uint64
stval
,
uint64
sepc
){
int
handle_page_fault
(
struct
proc
*
p
,
uint64
scause
,
uint64
stval
,
uint64
sepc
)
{
uint64
addr
=
PGROUNDDOWN
(
stval
);
acquire
(
&
p
->
vma_lock
);
printf
(
"handle_page_fault pid=%d (%s), scause=%p, stval=%p, sepc=%p
\n
"
,
p
->
pid
,
p
->
name
,
scause
,
stval
,
sepc
);
// proc_vmprint(p);
int
flags
=
do_allocate
(
p
->
pagetable
,
p
,
addr
,
CAUSE_R
);
release
(
&
p
->
vma_lock
);
if
(
flags
<
0
){
if
(
flags
==
ENOVMA
){
if
(
flags
<
0
)
{
if
(
flags
==
ENOVMA
)
{
printf
(
"Could not find VMA associated with addr=%p
\n
"
,
addr
);
}
else
if
(
flags
==
ENOMEM
){
}
else
if
(
flags
==
ENOMEM
)
{
printf
(
"No more memory could be allocated from the kernel
\n
"
);
}
else
if
(
flags
==
ENOFILE
){
}
else
if
(
flags
==
ENOFILE
)
{
printf
(
"Could not read file associated with memory area
\n
"
);
}
else
if
(
flags
==
EMAPFAILED
){
}
else
if
(
flags
==
EMAPFAILED
)
{
printf
(
"mappages failed for an unknown reason
\n
"
);
}
else
if
(
flags
==
EBADPERM
){
}
else
if
(
flags
==
EBADPERM
)
{
printf
(
"Bad permission addr=%p, scause=%p
\n
"
,
addr
,
scause
);
}
...
...
@@ -66,12 +75,11 @@ int handle_page_fault(struct proc* p, uint64 scause, uint64 stval, uint64 sepc){
// handle an interrupt, exception, or system call from user space.
// called from trampoline.S
//
void
usertrap
(
void
)
void
usertrap
(
void
)
{
int
which_dev
=
0
;
if
((
r_sstatus
()
&
SSTATUS_SPP
)
!=
0
)
if
((
r_sstatus
()
&
SSTATUS_SPP
)
!=
0
)
panic
(
"usertrap: not from user mode"
);
// send interrupts and exceptions to kerneltrap(),
...
...
@@ -79,16 +87,17 @@ usertrap(void)
w_stvec
((
uint64
)
kernelvec
);
struct
proc
*
p
=
myproc
();
// save user program counter.
p
->
tf
->
epc
=
r_sepc
();
uint64
scause
=
r_scause
();
if
(
scause
==
8
){
if
(
scause
==
8
)
{
// system call
if
(
p
->
killed
)
if
(
p
->
killed
)
exit
(
-
1
);
// sepc points to the ecall instruction,
...
...
@@ -100,21 +109,27 @@ usertrap(void)
intr_on
();
syscall
();
}
else
if
(
scause
==
0xf
||
scause
==
0xd
)
{
}
else
if
(
scause
==
0xf
||
scause
==
0xd
||
scause
==
0xc
)
{
handle_page_fault
(
p
,
scause
,
r_stval
(),
r_sepc
());
}
else
if
((
which_dev
=
devintr
())
!=
0
){
}
else
if
((
which_dev
=
devintr
())
!=
0
)
{
// ok
}
else
{
}
else
{
printf
(
"usertrap(): unexpected scause %p (%s) pid=%d
\n
"
,
r_scause
(),
scause_desc
(
r_scause
()),
p
->
pid
);
printf
(
" sepc=%p stval=%p
\n
"
,
r_sepc
(),
r_stval
());
p
->
killed
=
1
;
}
if
(
p
->
killed
)
if
(
p
->
killed
)
exit
(
-
1
);
// give up the CPU if this is a timer interrupt.
if
(
which_dev
==
2
)
if
(
which_dev
==
2
)
yield
();
usertrapret
();
...
...
@@ -123,8 +138,7 @@ usertrap(void)
//
// return to user space
//
void
usertrapret
(
void
)
void
usertrapret
(
void
)
{
struct
proc
*
p
=
myproc
();
...
...
@@ -140,11 +154,11 @@ usertrapret(void)
p
->
tf
->
kernel_satp
=
r_satp
();
// kernel page table
p
->
tf
->
kernel_sp
=
p
->
kstack
+
PGSIZE
;
// process's kernel stack
p
->
tf
->
kernel_trap
=
(
uint64
)
usertrap
;
p
->
tf
->
kernel_hartid
=
r_tp
();
// hartid for cpuid()
p
->
tf
->
kernel_hartid
=
r_tp
();
// hartid for cpuid()
// set up the registers that trampoline.S's sret will use
// to get to user space.
// set S Previous Privilege mode to User.
unsigned
long
x
=
r_sstatus
();
x
&=
~
SSTATUS_SPP
;
// clear SPP to 0 for user mode
...
...
@@ -157,36 +171,36 @@ usertrapret(void)
// tell trampoline.S the user page table to switch to.
uint64
satp
=
MAKE_SATP
(
p
->
pagetable
);
// jump to trampoline.S at the top of memory, which
// jump to trampoline.S at the top of memory, which
// switches to the user page table, restores user registers,
// and switches to user mode with sret.
uint64
fn
=
TRAMPOLINE
+
(
userret
-
trampoline
);
((
void
(
*
)(
uint64
,
uint64
))
fn
)(
TRAPFRAME
,
satp
);
((
void
(
*
)(
uint64
,
uint64
))
fn
)(
TRAPFRAME
,
satp
);
}
// interrupts and exceptions from kernel code go here via kernelvec,
// on whatever the current kernel stack is.
void
kerneltrap
()
void
kerneltrap
()
{
int
which_dev
=
0
;
uint64
sepc
=
r_sepc
();
uint64
sstatus
=
r_sstatus
();
uint64
scause
=
r_scause
();
if
((
sstatus
&
SSTATUS_SPP
)
==
0
)
if
((
sstatus
&
SSTATUS_SPP
)
==
0
)
panic
(
"kerneltrap: not from supervisor mode"
);
if
(
intr_get
()
!=
0
)
if
(
intr_get
()
!=
0
)
panic
(
"kerneltrap: interrupts enabled"
);
if
((
which_dev
=
devintr
())
==
0
){
if
((
which_dev
=
devintr
())
==
0
)
{
printf
(
"scause %p (%s)
\n
"
,
scause
,
scause_desc
(
scause
));
printf
(
"sepc=%p stval=%p
\n
"
,
r_sepc
(),
r_stval
());
panic
(
"kerneltrap"
);
}
// give up the CPU if this is a timer interrupt.
if
(
which_dev
==
2
&&
myproc
()
!=
0
&&
myproc
()
->
state
==
RUNNING
)
if
(
which_dev
==
2
&&
myproc
()
!=
0
&&
myproc
()
->
state
==
RUNNING
)
yield
();
// the yield() may have caused some traps to occur,
...
...
@@ -195,12 +209,12 @@ kerneltrap()
w_sstatus
(
sstatus
);
}
void
clockintr
()
void
clockintr
()
{
acquire
(
&
watchdog_lock
);
acquire
(
&
tickslock
);
if
(
watchdog_time
&&
ticks
-
watchdog_value
>
watchdog_time
){
if
(
watchdog_time
&&
ticks
-
watchdog_value
>
watchdog_time
)
{
panic
(
"watchdog !!!"
);
}
ticks
++
;
...
...
@@ -214,45 +228,55 @@ clockintr()
// returns 2 if timer interrupt,
// 1 if other device,
// 0 if not recognized.
int
devintr
()
int
devintr
()
{
uint64
scause
=
r_scause
();
if
((
scause
&
0x8000000000000000L
)
&&
(
scause
&
0xff
)
==
9
){
if
((
scause
&
0x8000000000000000L
)
&&
(
scause
&
0xff
)
==
9
)
{
// this is a supervisor external interrupt, via PLIC.
// irq indicates which device interrupted.
int
irq
=
plic_claim
();
if
(
irq
==
UART0_IRQ
){
if
(
irq
==
UART0_IRQ
)
{
uartintr
();
}
else
if
(
irq
==
VIRTIO0_IRQ
||
irq
==
VIRTIO1_IRQ
){
}
else
if
(
irq
==
VIRTIO0_IRQ
||
irq
==
VIRTIO1_IRQ
)
{
virtio_disk_intr
(
irq
-
VIRTIO0_IRQ
);
}
else
{
}
else
{
// the PLIC sends each device interrupt to every core,
// which generates a lot of interrupts with irq==0.
}
if
(
irq
)
if
(
irq
)
plic_complete
(
irq
);
return
1
;
}
else
if
(
scause
==
0x8000000000000001L
){
}
else
if
(
scause
==
0x8000000000000001L
)
{
// software interrupt from a machine-mode timer interrupt,
// forwarded by timervec in kernelvec.S.
if
(
cpuid
()
==
0
){
if
(
cpuid
()
==
0
)
{
clockintr
();
}
// acknowledge the software interrupt by clearing
// the SSIP bit in sip.
w_sip
(
r_sip
()
&
~
2
);
return
2
;
}
else
{
}
else
{
return
0
;
}
}
...
...
@@ -261,61 +285,78 @@ static const char *
scause_desc
(
uint64
stval
)
{
static
const
char
*
intr_desc
[
16
]
=
{
[
0
]
"user software interrupt"
,
[
1
]
"supervisor software interrupt"
,
[
2
]
"<reserved for future standard use>"
,
[
3
]
"<reserved for future standard use>"
,
[
4
]
"user timer interrupt"
,
[
5
]
"supervisor timer interrupt"
,
[
6
]
"<reserved for future standard use>"
,
[
7
]
"<reserved for future standard use>"
,
[
8
]
"user external interrupt"
,
[
9
]
"supervisor external interrupt"
,
[
10
]
"<reserved for future standard use>"
,
[
11
]
"<reserved for future standard use>"
,
[
12
]
"<reserved for future standard use>"
,
[
13
]
"<reserved for future standard use>"
,
[
14
]
"<reserved for future standard use>"
,
[
15
]
"<reserved for future standard use>"
,
[
0
]
"user software interrupt"
,
[
1
]
"supervisor software interrupt"
,
[
2
]
"<reserved for future standard use>"
,
[
3
]
"<reserved for future standard use>"
,
[
4
]
"user timer interrupt"
,
[
5
]
"supervisor timer interrupt"
,
[
6
]
"<reserved for future standard use>"
,
[
7
]
"<reserved for future standard use>"
,
[
8
]
"user external interrupt"
,
[
9
]
"supervisor external interrupt"
,
[
10
]
"<reserved for future standard use>"
,
[
11
]
"<reserved for future standard use>"
,
[
12
]
"<reserved for future standard use>"
,
[
13
]
"<reserved for future standard use>"
,
[
14
]
"<reserved for future standard use>"
,
[
15
]
"<reserved for future standard use>"
,
};
static
const
char
*
nointr_desc
[
16
]
=
{
[
0
]
"instruction address misaligned"
,
[
1
]
"instruction access fault"
,
[
2
]
"illegal instruction"
,
[
3
]
"breakpoint"
,
[
4
]
"load address misaligned"
,
[
5
]
"load access fault"
,
[
6
]
"store/AMO address misaligned"
,
[
7
]
"store/AMO access fault"
,
[
8
]
"environment call from U-mode"
,
[
9
]
"environment call from S-mode"
,
[
10
]
"<reserved for future standard use>"
,
[
11
]
"<reserved for future standard use>"
,
[
12
]
"instruction page fault"
,
[
13
]
"load page fault"
,
[
14
]
"<reserved for future standard use>"
,
[
15
]
"store/AMO page fault"
,
[
0
]
"instruction address misaligned"
,
[
1
]
"instruction access fault"
,
[
2
]
"illegal instruction"
,
[
3
]
"breakpoint"
,
[
4
]
"load address misaligned"
,
[
5
]
"load access fault"
,
[
6
]
"store/AMO address misaligned"
,
[
7
]
"store/AMO access fault"
,
[
8
]
"environment call from U-mode"
,
[
9
]
"environment call from S-mode"
,
[
10
]
"<reserved for future standard use>"
,
[
11
]
"<reserved for future standard use>"
,
[
12
]
"instruction page fault"
,
[
13
]
"load page fault"
,
[
14
]
"<reserved for future standard use>"
,
[
15
]
"store/AMO page fault"
,
};
uint64
interrupt
=
stval
&
0x8000000000000000L
;
uint64
code
=
stval
&
~
0x8000000000000000L
;
if
(
interrupt
)
{
if
(
code
<
NELEM
(
intr_desc
))
{
if
(
interrupt
)
{
if
(
code
<
NELEM
(
intr_desc
))
{
return
intr_desc
[
code
];
}
else
{
}
else
{
return
"<reserved for platform use>"
;
}
}
else
{
if
(
code
<
NELEM
(
nointr_desc
))
{
}
else
{
if
(
code
<
NELEM
(
nointr_desc
))
{
return
nointr_desc
[
code
];
}
else
if
(
code
<=
23
)
{
}
else
if
(
code
<=
23
)
{
return
"<reserved for future standard use>"
;
}
else
if
(
code
<=
31
)
{
}
else
if
(
code
<=
31
)
{
return
"<reserved for custom use>"
;
}
else
if
(
code
<=
47
)
{
}
else
if
(
code
<=
47
)
{
return
"<reserved for future standard use>"
;
}
else
if
(
code
<=
63
)
{
}
else
if
(
code
<=
63
)
{
return
"<reserved for custom use>"
;
}
else
{
}
else
{
return
"<reserved for future standard use>"
;
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment