Skip to content

SwitchPrivilegeSolver.cc has an error

In riscv-priv-isa, ecall from s_mode can delegate to s_mode. But in force-riscv/riscv/src/SwitchPrivilegeSolver.cc, ecall from s_mode are handled in m_mode dircetly without checking the value of medeleg. This operation is inconsistent with riscv-priv-isa, is there any error in the implementation of force-riscv?

switch` (mResult.mInstrSeqCode) {
    case 1:
      if (mCurrentPrivLevel == 0) {
        const RegisterFile* reg_file = mpGenerator->GetRegisterFile();
        Register* medeleg_reg = reg_file->RegisterLookup("medeleg");

        uint64 medeleg_val = medeleg_reg->Value();
        if ((medeleg_val & 0x100) == 0x100) {
          // Environment calls from U mode are delegated to S mode
          mResult.mDataBlockPrivLevel = 1;
        }
        else {
          // Environment calls from U mode are handled in M mode
          mResult.mDataBlockPrivLevel = 3;
        }
      }
      else {
        mResult.mDataBlockPrivLevel = 3;
      }
      break;
    case 2:
      mResult.mDataBlockPrivLevel = mCurrentPrivLevel;
      break;
    case 3:
      mResult.mDataBlockPrivLevel = 3;
      break;
    default:
      LOG(fail) << "{SwitchPrivilegeSolver::ValidateAndGenerateSwitchScheme} unexpected instruction sequence code " << dec << mResult.mInstrSeqCode << endl;
      FAIL("unexpected-instr-seq-code");
  }
    LOG(notice) << "{SwitchPrivilegeSolver::ValidateAndGenerateSwitchScheme} instruction sequence code " << dec << mResult.mInstrSeqCode << endl;
    return true;
  }