zoukankan      html  css  js  c++  java
  • miniriscvos 05Preemptive

    void timer_init()
    {
      // each CPU has a separate source of timer interrupts.
      int id = r_mhartid();
    
      // ask the CLINT for a timer interrupt.
      // int interval = 1000000; // cycles; about 1/10th second in qemu.
    
      *(reg_t *)CLINT_MTIMECMP(id) = *(reg_t *)CLINT_MTIME + interval;
    
      // prepare information in scratch[] for timervec.
      // scratch[0..2] : space for timervec to save registers.
      // scratch[3] : address of CLINT MTIMECMP register.
      // scratch[4] : desired interval (in cycles) between timer interrupts.
      reg_t *scratch = &timer_scratch[id][0];
      scratch[3] = CLINT_MTIMECMP(id);
      scratch[4] = interval;
      w_mscratch((reg_t)scratch);
    
      // enable machine-mode timer interrupts.
      w_mie(r_mie() | MIE_MTIE);
    }
    qemu-system-riscv64 -M virt -kernel kernel.img -bios none -serial stdio -display none
    OS start
    OS start loop 
    OS: Activate next task
    Task0: Created!
    Task0: Running...
    Task0: Running...
    Task0: Running...
    Task0: Running...
    Task0: Running...
    Task0: Running...
    Task0: Running...
    Task0: Running...
    Task0: Running...
    Task0: Running...
    Sync exceptions! ,  code = 7
    OOPS! What can I do!
    reg_t trap_handler(reg_t epc, reg_t cause)
    {
      reg_t return_pc = epc;
      reg_t cause_code = cause & 0xfff;
    
      if (cause & 0x80000000)
      {
        /* Asynchronous trap - interrupt */
        switch (cause_code)
        {
        case 3:
          lib_puts("software interruption!\n");
          break;
        case 7:
          lib_puts("timer interruption!\n");
          // disable machine-mode timer interrupts.
          w_mie(~((~r_mie()) | (1 << 7)));
          timer_handler();
          return_pc = (reg_t)&os_kernel;
          // enable machine-mode timer interrupts.
          w_mie(r_mie() | MIE_MTIE);
          break;
        case 11:
          lib_puts("external interruption!\n");
          break;
        default:
          lib_puts("unknown async exception!\n");
          break;
        }
      }
      else
      {
        /* Synchronous trap - exception */
        // https://juejin.cn/post/7006347707144994853
        lib_printf("Sync exceptions! ,  code = %d\n", cause_code);
        lib_puts("OOPS! What can I do!");
        while (1)
        {
          /* code */
        }
      }
      return return_pc;
    }

     原来是trap_vector 处理有问题

    .globl trap_vector
    # the trap vector base address must always be aligned on a 4-byte boundary
    .align 4
    trap_vector:
            # save context(registers).
            csrrw   t6, mscratch, t6        # swap t6 and mscratch
            reg_save t6
            csrw    mscratch, t6
            # call the C trap handler in trap.c
            csrr    a0, mepc
            csrr    a1, mcause
            call    trap_handler
    
            # trap_handler will return the return address via a0.
            csrw    mepc, a0
    
            # load context(registers).
            csrr    t6, mscratch
            reg_load t6
            mret

     更改timervec

    #include "timer.h"
    #include "lib.h"
    
    // a scratch area per CPU for machine-mode timer interrupts.
    reg_t timer_scratch[NCPU][5];
    
    #define interval 20000000 // cycles; about 2 second in qemu.
    // assembly code in kernelvec.S for machine-mode timer interrupt.
    extern void timervec();
    void timer_init()
    {
      // each CPU has a separate source of timer interrupts.
      int id = r_mhartid();
    
      // ask the CLINT for a timer interrupt.
      // int interval = 1000000; // cycles; about 1/10th second in qemu.
    
      *(reg_t *)CLINT_MTIMECMP(id) = *(reg_t *)CLINT_MTIME + interval;
    
      // prepare information in scratch[] for timervec.
      // scratch[0..2] : space for timervec to save registers.
      // scratch[3] : address of CLINT MTIMECMP register.
      // scratch[4] : desired interval (in cycles) between timer interrupts.
      reg_t *scratch = &timer_scratch[id][0];
      scratch[3] = CLINT_MTIMECMP(id);
      scratch[4] = interval;
      w_mscratch((reg_t)scratch);
    
      //set the machine-mode trap handler.
      w_mtvec((reg_t)timervec);
        //
        //     // enable machine-mode interrupts.
      w_mstatus(r_mstatus() | MSTATUS_MIE);
      // enable machine-mode timer interrupts.
      w_mie(r_mie() | MIE_MTIE);
    }
    
    static int timer_count = 0;
    
    void timer_handler()
    {
      lib_printf("timer_handler: %d\n", ++timer_count);
      int id = r_mhartid();
      *(reg_t *)CLINT_MTIMECMP(id) = *(reg_t *)CLINT_MTIME + interval;
    }
  • 相关阅读:
    关于响应式框架的定位不了元素的坑
    pychrom 中文版
    firebug定位工具很强大
    查询数据中所有表名
    java解析Json中获取Array字段值及嵌套Json对象
    mysql表操作
    集合框架(二)
    集合框架
    Java API(二)
    JDBC入门
  • 原文地址:https://www.cnblogs.com/dream397/p/15720260.html
Copyright © 2011-2022 走看看