machinevec -> timervec
This commit is contained in:
		
							parent
							
								
									fa2e2e3c81
								
							
						
					
					
						commit
						c714e3e35c
					
				
					 5 changed files with 26 additions and 25 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		
		Reference in a new issue