ecall
Environment call
This instruction is defined by:
Synopsis
The ECALL instruction is used to make a request to the supporting execution environment. When executed in U-mode, S-mode, or M-mode, it generates an environment-call-from-U-mode exception, environment-call-from-S-mode exception, or environment-call-from-M-mode exception, respectively, and performs no other operation.
ECALL generates a different exception for each originating privilege mode so that environment call exceptions can be selectively delegated. A typical use case for Unix-like operating systems is to delegate to S-mode the environment-call-from-U-mode exception but not the others. |
ECALL causes the receiving privilege mode’s epc register to be set to the address of the ECALL instruction itself, not the address of the following instruction. As ECALL causes a synchronous exception, it is not considered to retire, and should not increment the minstret CSR.
Execution
-
Pruned, XLEN == 64
-
Original
if (%%LINK%func;mode;mode%%() == PrivilegeMode::M) {
if (TRAP_ON_ECALL_FROM_M) {
%%LINK%func;raise_precise;raise_precise%%(ExceptionCode::Mcall, PrivilegeMode::M, 0);
} else {
%%LINK%func;eei_ecall_from_m;eei_ecall_from_m%%();
}
} else if (%%LINK%func;mode;mode%%() == PrivilegeMode::S) {
if (TRAP_ON_ECALL_FROM_S) {
%%LINK%func;raise_precise;raise_precise%%(ExceptionCode::Scall, PrivilegeMode::S, 0);
} else {
%%LINK%func;eei_ecall_from_s;eei_ecall_from_s%%();
}
} else if (%%LINK%func;mode;mode%%() == PrivilegeMode::U || %%LINK%func;mode;mode%%() == PrivilegeMode::VU) {
if (TRAP_ON_ECALL_FROM_U) {
%%LINK%func;raise_precise;raise_precise%%(ExceptionCode::Ucall, %%LINK%func;mode;mode%%(), 0);
} else {
%%LINK%func;eei_ecall_from_u;eei_ecall_from_u%%();
}
} else if (%%LINK%func;mode;mode%%() == PrivilegeMode::VS) {
if (TRAP_ON_ECALL_FROM_VS) {
%%LINK%func;raise_precise;raise_precise%%(ExceptionCode::VScall, PrivilegeMode::VS, 0);
} else {
%%LINK%func;eei_ecall_from_vs;eei_ecall_from_vs%%();
}
}
if (%%LINK%func;mode;mode%%() == PrivilegeMode::M) {
if (TRAP_ON_ECALL_FROM_M) {
%%LINK%func;raise_precise;raise_precise%%(ExceptionCode::Mcall, PrivilegeMode::M, 0);
} else {
%%LINK%func;eei_ecall_from_m;eei_ecall_from_m%%();
}
} else if (%%LINK%func;mode;mode%%() == PrivilegeMode::S) {
if (TRAP_ON_ECALL_FROM_S) {
%%LINK%func;raise_precise;raise_precise%%(ExceptionCode::Scall, PrivilegeMode::S, 0);
} else {
%%LINK%func;eei_ecall_from_s;eei_ecall_from_s%%();
}
} else if (%%LINK%func;mode;mode%%() == PrivilegeMode::U || %%LINK%func;mode;mode%%() == PrivilegeMode::VU) {
if (TRAP_ON_ECALL_FROM_U) {
%%LINK%func;raise_precise;raise_precise%%(ExceptionCode::Ucall, %%LINK%func;mode;mode%%(), 0);
} else {
%%LINK%func;eei_ecall_from_u;eei_ecall_from_u%%();
}
} else if (%%LINK%func;mode;mode%%() == PrivilegeMode::VS) {
if (TRAP_ON_ECALL_FROM_VS) {
%%LINK%func;raise_precise;raise_precise%%(ExceptionCode::VScall, PrivilegeMode::VS, 0);
} else {
%%LINK%func;eei_ecall_from_vs;eei_ecall_from_vs%%();
}
}