machinevec -> timervec
This commit is contained in:
parent
fa2e2e3c81
commit
c714e3e35c
|
@ -88,9 +88,9 @@ kernelvec:
|
||||||
#
|
#
|
||||||
# machine-mode timer interrupt.
|
# machine-mode timer interrupt.
|
||||||
#
|
#
|
||||||
.globl machinevec
|
.globl timervec
|
||||||
.align 4
|
.align 4
|
||||||
machinevec:
|
timervec:
|
||||||
# start.c has set up the memory that mscratch points to:
|
# start.c has set up the memory that mscratch points to:
|
||||||
# scratch[0,8,16] : register save area.
|
# scratch[0,8,16] : register save area.
|
||||||
# scratch[32] : address of CLINT's MTIMECMP register.
|
# scratch[32] : address of CLINT's MTIMECMP register.
|
||||||
|
|
|
@ -257,7 +257,7 @@ r_time()
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable interrupts
|
// enable device interrupts
|
||||||
static inline void
|
static inline void
|
||||||
intr_on()
|
intr_on()
|
||||||
{
|
{
|
||||||
|
@ -265,14 +265,14 @@ intr_on()
|
||||||
w_sstatus(r_sstatus() | SSTATUS_SIE);
|
w_sstatus(r_sstatus() | SSTATUS_SIE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable interrupts
|
// disable device interrupts
|
||||||
static inline void
|
static inline void
|
||||||
intr_off()
|
intr_off()
|
||||||
{
|
{
|
||||||
w_sstatus(r_sstatus() & ~SSTATUS_SIE);
|
w_sstatus(r_sstatus() & ~SSTATUS_SIE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// are interrupts enabled?
|
// are device interrupts enabled?
|
||||||
static inline int
|
static inline int
|
||||||
intr_get()
|
intr_get()
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,8 +12,8 @@ __attribute__ ((aligned (16))) char stack0[4096 * NCPU];
|
||||||
// scratch area for timer interrupt, one per CPU.
|
// scratch area for timer interrupt, one per CPU.
|
||||||
uint64 mscratch0[NCPU * 32];
|
uint64 mscratch0[NCPU * 32];
|
||||||
|
|
||||||
// assembly code in kernelvec for machine-mode timer interrupt.
|
// assembly code in kernelvec.S for machine-mode timer interrupt.
|
||||||
extern void machinevec();
|
extern void timervec();
|
||||||
|
|
||||||
// entry.S jumps here in machine mode on stack0.
|
// entry.S jumps here in machine mode on stack0.
|
||||||
void
|
void
|
||||||
|
@ -36,16 +36,17 @@ start()
|
||||||
w_medeleg(0xffff);
|
w_medeleg(0xffff);
|
||||||
w_mideleg(0xffff);
|
w_mideleg(0xffff);
|
||||||
|
|
||||||
|
int id = r_mhartid();
|
||||||
|
|
||||||
// set up to receive timer interrupts in machine mode,
|
// set up to receive timer interrupts in machine mode,
|
||||||
// which arrive at machinevec in kernelvec.S,
|
// which arrive at timervec in kernelvec.S,
|
||||||
// which turns them into software interrupts for
|
// which turns them into software interrupts for
|
||||||
// devintr() in trap.c.
|
// devintr() in trap.c.
|
||||||
int id = r_mhartid();
|
|
||||||
// ask the CLINT for a timer interrupt.
|
// ask the CLINT for a timer interrupt.
|
||||||
int interval = 1000000; // cycles; about 1/10th second in qemu.
|
int interval = 1000000; // cycles; about 1/10th second in qemu.
|
||||||
*(uint64*)CLINT_MTIMECMP(id) = *(uint64*)CLINT_MTIME + interval;
|
*(uint64*)CLINT_MTIMECMP(id) = *(uint64*)CLINT_MTIME + interval;
|
||||||
// prepare information in scratch[] for machinevec.
|
// prepare information in scratch[] for timervec.
|
||||||
// scratch[0..3] : space for machinevec to save registers.
|
// scratch[0..3] : space for timervec to save registers.
|
||||||
// scratch[4] : address of CLINT MTIMECMP register.
|
// scratch[4] : address of CLINT MTIMECMP register.
|
||||||
// scratch[5] : desired interval (in cycles) between timer interrupts.
|
// scratch[5] : desired interval (in cycles) between timer interrupts.
|
||||||
uint64 *scratch = &mscratch0[32 * id];
|
uint64 *scratch = &mscratch0[32 * id];
|
||||||
|
@ -53,7 +54,7 @@ start()
|
||||||
scratch[5] = interval;
|
scratch[5] = interval;
|
||||||
w_mscratch((uint64)scratch);
|
w_mscratch((uint64)scratch);
|
||||||
// set the machine-mode trap handler.
|
// set the machine-mode trap handler.
|
||||||
w_mtvec((uint64)machinevec);
|
w_mtvec((uint64)timervec);
|
||||||
// enable machine-mode interrupts.
|
// enable machine-mode interrupts.
|
||||||
w_mstatus(r_mstatus() | MSTATUS_MIE);
|
w_mstatus(r_mstatus() | MSTATUS_MIE);
|
||||||
// enable machine-mode timer interrupts.
|
// enable machine-mode timer interrupts.
|
||||||
|
|
|
@ -25,10 +25,10 @@ uservec:
|
||||||
#
|
#
|
||||||
|
|
||||||
# swap a0 and sscratch
|
# swap a0 and sscratch
|
||||||
# so that a0 is p->tf
|
# so that a0 is TRAPFRAME
|
||||||
csrrw a0, sscratch, a0
|
csrrw a0, sscratch, a0
|
||||||
|
|
||||||
# save the user registers in p->tf
|
# save the user registers in TRAPFRAME
|
||||||
sd ra, 40(a0)
|
sd ra, 40(a0)
|
||||||
sd sp, 48(a0)
|
sd sp, 48(a0)
|
||||||
sd gp, 56(a0)
|
sd gp, 56(a0)
|
||||||
|
@ -86,22 +86,22 @@ uservec:
|
||||||
|
|
||||||
.globl userret
|
.globl userret
|
||||||
userret:
|
userret:
|
||||||
# userret(trapframe, pagetable)
|
# userret(TRAPFRAME, pagetable)
|
||||||
# switch from kernel to user.
|
# switch from kernel to user.
|
||||||
# usertrapret() calls here.
|
# usertrapret() calls here.
|
||||||
# a0: p->tf in user page table
|
# a0: TRAPFRAME, in user page table
|
||||||
# a1: new value for satp, for user page table
|
# a1: user page table, for satp
|
||||||
|
|
||||||
# switch to the user page table.
|
# switch to the user page table.
|
||||||
sfence.vma zero, zero
|
sfence.vma zero, zero
|
||||||
csrw satp, a1
|
csrw satp, a1
|
||||||
|
|
||||||
# put the saved user a0 in sscratch, so we
|
# put the saved user a0 in sscratch, so we
|
||||||
# can swap it with our a0 (p->tf) in the last step.
|
# can swap it with our a0 (TRAPFRAME) in the last step.
|
||||||
ld t0, 112(a0)
|
ld t0, 112(a0)
|
||||||
csrw sscratch, t0
|
csrw sscratch, t0
|
||||||
|
|
||||||
# restore all but a0 from p->tf
|
# restore all but a0 from TRAPFRAME
|
||||||
ld ra, 40(a0)
|
ld ra, 40(a0)
|
||||||
ld sp, 48(a0)
|
ld sp, 48(a0)
|
||||||
ld gp, 56(a0)
|
ld gp, 56(a0)
|
||||||
|
@ -133,7 +133,7 @@ userret:
|
||||||
ld t5, 272(a0)
|
ld t5, 272(a0)
|
||||||
ld t6, 280(a0)
|
ld t6, 280(a0)
|
||||||
|
|
||||||
# restore user a0, and save p->tf in sscratch
|
# restore user a0, and save TRAPFRAME in sscratch
|
||||||
csrrw a0, sscratch, a0
|
csrrw a0, sscratch, a0
|
||||||
|
|
||||||
# return to user mode and user pc.
|
# return to user mode and user pc.
|
||||||
|
|
|
@ -98,12 +98,12 @@ usertrapret(void)
|
||||||
// send interrupts and exceptions to trampoline.S
|
// send interrupts and exceptions to trampoline.S
|
||||||
w_stvec(TRAMPOLINE + (uservec - trampoline));
|
w_stvec(TRAMPOLINE + (uservec - trampoline));
|
||||||
|
|
||||||
// set up values that trampoline.S will need when
|
// set up values that uservec will need when
|
||||||
// the process next re-enters the kernel.
|
// the process next re-enters the kernel.
|
||||||
p->tf->kernel_satp = r_satp();
|
p->tf->kernel_satp = r_satp(); // kernel page table
|
||||||
p->tf->kernel_sp = p->kstack + PGSIZE;
|
p->tf->kernel_sp = p->kstack + PGSIZE; // process's kernel stack
|
||||||
p->tf->kernel_trap = (uint64)usertrap;
|
p->tf->kernel_trap = (uint64)usertrap;
|
||||||
p->tf->kernel_hartid = r_tp();
|
p->tf->kernel_hartid = r_tp(); // hartid for cpuid()
|
||||||
|
|
||||||
// set up the registers that trampoline.S's sret will use
|
// set up the registers that trampoline.S's sret will use
|
||||||
// to get to user space.
|
// to get to user space.
|
||||||
|
@ -193,7 +193,7 @@ devintr()
|
||||||
return 1;
|
return 1;
|
||||||
} else if(scause == 0x8000000000000001){
|
} else if(scause == 0x8000000000000001){
|
||||||
// software interrupt from a machine-mode timer interrupt,
|
// software interrupt from a machine-mode timer interrupt,
|
||||||
// forwarded by machinevec in kernelvec.S.
|
// forwarded by timervec in kernelvec.S.
|
||||||
|
|
||||||
if(cpuid() == 0){
|
if(cpuid() == 0){
|
||||||
clockintr();
|
clockintr();
|
||||||
|
|
Loading…
Reference in a new issue