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

View file

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

View file

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

View file

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

View file

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