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