machinevec -> timervec

This commit is contained in:
Robert Morris 2019-07-26 10:17:02 -04:00
parent fa2e2e3c81
commit c714e3e35c
5 changed files with 26 additions and 25 deletions

View file

@ -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.

View file

@ -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()
{

View file

@ -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.

View file

@ -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.

View file

@ -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();