zoukankan      html  css  js  c++  java
  • enter_supervisor_mode

    204     void enter_supervisor_mode(void (*fn)(uintptr_t), uintptr_t arg0, uintptr_t arg1)
    205   {
    206         uintptr_t mstatus = read_csr(mstatus);
    207      mstatus = INSERT_FIELD(mstatus, MSTATUS_MPP, PRV_S);
    208      mstatus = INSERT_FIELD(mstatus, MSTATUS_MPIE, 0);
    209         write_csr(mstatus, mstatus);
    210      write_csr(mscratch, MACHINE_STACK_TOP() - MENTRY_FRAME_SIZE);
    211        #ifndef __riscv_flen
    212      uintptr_t *p_fcsr = MACHINE_STACK_TOP() - MENTRY_FRAME_SIZE; // the x0's save slot
    213      *p_fcsr = 0;
    214       #endif
    215      write_csr(mepc, fn);
    216
    217         register uintptr_t a0 asm ("a0") = arg0;
    218         register uintptr_t a1 asm ("a1") = arg1;
    219       asm volatile ("mret" : : "r" (a0), "r" (a1));
    220      __builtin_unreachable();
    221     }

    The relevant bits of the code disassembled:

    80004300 <enter_supervisor_mode>:
    
    void enter_supervisor_mode(void (*fn)(uintptr_t), uintptr_t arg0, uintptr_t arg1)
    {
    ...
     write_csr(mepc, fn);
    800043a4:    fdc42783              lw    a5,-36(s0)
    800043a8:    34179073              csrw    mepc,a5
    
     register uintptr_t a0 asm ("a0") = arg0;
    800043ac:    fd842503              lw    a0,-40(s0)
     register uintptr_t a1 asm ("a1") = arg1;
    800043b0:    fd442583              lw    a1,-44(s0)
     asm volatile ("mret" : : "r" (a0), "r" (a1));
    800043b4:    30200073              mret
    
    800043b8 <enter_machine_mode>:
     __builtin_unreachable();
    }

    在enter_supervisor_mode函数中,将 mstatus的MPP域设置为1,表示中断发生之前的模式是Supervisor,将mstatus的MPIE域设置为0,表示中段发生前MIE的值为0。随即将机器模式的内核栈顶写入mscratch寄存器中,设置mepc为rest_of_boot_loader的地址,并将kernel_stack_top与0作为参数存入a0和a1。

    ​最后,执行mret指令,该指令执行时,程序从机器模式的异常返回,将程序计数器pc设置为mepc,即rest_of_boot_loader的地址;将特权级设置为mstatus寄存器的MPP域,即方才所设置的代表Supervisor的1,MPP设置为0;将mstatus寄存器的MIE域设置为MPIE,即方才所设置的表示中断关闭的0,MPIE设置为1。

    ​于是,当mret指令执行完毕.

    This means that by setting up the MSTATUS_MPP, MSTATUS_MPIE fields

    For comparison, the enter_machine_mode counterpart is simpler as the bootloader code is already running in the machine mode:

      uintptr_t mstatus = read_csr(mstatus);
      mstatus = INSERT_FIELD(mstatus, MSTATUS_MPIE, 0);
      write_csr(mstatus, mstatus);
      write_csr(mscratch, MACHINE_STACK_TOP() - MENTRY_FRAME_SIZE);
    
      /* Jump to the payload's entry point */
      fn(arg0, arg1);
    
      __builtin_unreachable();
    }
  • 相关阅读:
    RabbitMQ入门-Topic模式
    RabbitMQ入门-路由-有选择的接受消息
    RabbitMQ入门-发布订阅模式
    RabbitMQ入门-竞争消费者模式
    RabbitMQ入门-队列
    Windows下安装RabbitMQ
    ThymeLeaf的eclipse插件安装
    Freemarker 的 Eclipse 插件 安装
    MySQL基础学习笔记
    我是不是一个不愿意自己多努力,还老是跟别人吐槽公司这不好那不好的人
  • 原文地址:https://www.cnblogs.com/dream397/p/15716665.html
Copyright © 2011-2022 走看看