wfi
Wait for interrupt
This instruction is defined by:
-
Sm, version >= Sm@1.11.0
This instruction is included in the following profiles:
-
RVA23M64 (Mandatory)
-
RVB23M64 (Mandatory)
Synopsis
Can causes the processor to enter a low-power state until the next interrupt occurs.
<%- if ext?(:H) -%> The behavior of wfi is affected by the mstatus.TW and hstatus.VTW bits, as summarized below.
wfi behavior |
|||||
HS-mode |
U-mode |
VS-mode |
in VU-mode |
||
---|---|---|---|---|---|
0 |
0 |
Wait |
Trap (I) |
Wait |
Trap (V) |
0 |
1 |
Wait |
Trap (I) |
Trap (V) |
Trap (V) |
1 |
- |
Trap (I) |
Trap (I) |
Trap (I) |
Trap (I) |
Trap (I) - Trap with |
<%- else -%> The wfi instruction is also affected by mstatus.TW, as shown below:
wfi behavior |
||
S-mode |
U-mode |
|
---|---|---|
0 |
Wait |
Trap (I) |
1 |
Trap (I) |
Trap (I) |
Trap (I) - Trap with |
<%- end -%>
Access
M | HS | U | VS | VU |
---|---|---|---|---|
Always |
Sometimes |
Sometimes |
Sometimes |
Sometimes |
<%- if ext?(:H) -%> The behavior of wfi is affected by the mstatus.TW and hstatus.VTW bits, as summarized below.
wfi behavior |
|||||
HS-mode |
U-mode |
VS-mode |
in VU-mode |
||
---|---|---|---|---|---|
0 |
0 |
Wait |
Trap (I) |
Wait |
Trap (V) |
0 |
1 |
Wait |
Trap (I) |
Trap (V) |
Trap (V) |
1 |
- |
Trap (I) |
Trap (I) |
Trap (I) |
Trap (I) |
Trap (I) - Trap with |
<%- else -%> The wfi instruction is also affected by mstatus.TW, as shown below:
wfi behavior |
||
S-mode |
U-mode |
|
---|---|---|
0 |
Wait |
Trap (I) |
1 |
Trap (I) |
Trap (I) |
Trap (I) - Trap with |
<%- end -%>
Execution
-
IDL
-
Sail
if (%%LINK%func;mode;mode%%() == PrivilegeMode::U) {
%%LINK%func;raise;raise%%(ExceptionCode::IllegalInstruction, %%LINK%func;mode;mode%%(), $encoding);
}
if ((%%LINK%csr_field;misa.S;CSR[misa].S%% == 1) && (%%LINK%csr_field;mstatus.TW;CSR[mstatus].TW%% == 1'b1)) {
if (%%LINK%func;mode;mode%%() != PrivilegeMode::M) {
%%LINK%func;raise;raise%%(ExceptionCode::IllegalInstruction, %%LINK%func;mode;mode%%(), $encoding);
}
}
if (%%LINK%csr_field;misa.H;CSR[misa].H%% == 1) {
if (%%LINK%csr_field;hstatus.VTW;CSR[hstatus].VTW%% == 1'b0) {
if (%%LINK%func;mode;mode%%() == PrivilegeMode::VU) {
%%LINK%func;raise;raise%%(ExceptionCode::VirtualInstruction, %%LINK%func;mode;mode%%(), $encoding);
}
} else if (%%LINK%csr_field;hstatus.VTW;CSR[hstatus].VTW%% == 1'b1) {
if ((%%LINK%func;mode;mode%%() == PrivilegeMode::VS) || (%%LINK%func;mode;mode%%() == PrivilegeMode::VU)) {
%%LINK%func;raise;raise%%(ExceptionCode::VirtualInstruction, %%LINK%func;mode;mode%%(), $encoding);
}
}
}
%%LINK%func;wfi;wfi%%();
match cur_privilege {
Machine => { platform_wfi(); RETIRE_SUCCESS },
Supervisor => if mstatus.TW() == 0b1
then { handle_illegal(); RETIRE_FAIL }
else { platform_wfi(); RETIRE_SUCCESS },
User => { handle_illegal(); RETIRE_FAIL }
}