Skip to content

Commit

Permalink
Introduce SUSP extension
Browse files Browse the repository at this point in the history
The SUSP extension provides a system suspend function with a single
standard "Suspend to RAM" type.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
  • Loading branch information
jones-drew committed Feb 27, 2023
1 parent 79e8500 commit 0a7ddb1
Showing 1 changed file with 120 additions and 0 deletions.
120 changes: 120 additions & 0 deletions riscv-sbi.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ https://creativecommons.org/licenses/by/4.0/.
* Relaxed the counter width requirement on SBI PMU firmware counters
* Added sbi_pmu_counter_fw_read_hi() in SBI PMU extension
* Reserved space for SBI implementation specific firmware events
* Added SBI system suspend extension

=== Version 1.0.0

Expand Down Expand Up @@ -1889,6 +1890,125 @@ below.
| sbi_debug_console_write_byte | 2.0 | 2 | 0x4442434E
|===

== SBI System Suspend Extension (EID #0x53555350 "SUSP")

The system suspend extension defines a set of system-level sleep states and a
function which allows the supervisor-mode software to request that the system
transitions to a sleep state. Sleep states are identified with a 32-bit wide
identifier (`sleep_type`). The possible values for the identifier are shown in
<<table_susp_sleep_types>>.

The term "system" refers to the world-view of supervisor software. The
underlying SBI implementation may be provided by machine mode firmware or a
hypervisor.

The system suspend extension does not provide any way for supported sleep types
to be probed. Platforms are expected to specify their supported system sleep
types and per-type wake up devices in their hardware descriptions. The
`SUSPEND_TO_RAM` sleep type is the one exception, and its presence is implied
by that of the extension.

[#table_susp_sleep_types]
.SUSP System Sleep Types
[cols="1,1,2", width=90%, align="center", options="header"]
|===
| Type | Name | Description
| 0 | SUSPEND_TO_RAM | This is a “suspend to RAM”
sleep type, similar to ACPI’s
S2 or S3. Entry requires all
but the calling hart be in the
HSM `STOPPED` state and all hart
registers and CSRs saved to RAM.
| 0x00000001 - 0x7fffffff | | Reserved for future use
| 0x80000000 - 0xffffffff | | Platform-specific system sleep
types
| > 0xffffffff | | Reserved
|===

=== Function: System Suspend (FID #0)

[source, C]
----
struct sbiret sbi_system_suspend(uint32_t sleep_type,
unsigned long resume_addr,
unsigned long opaque)
----

A return from a `sbi_system_suspend()` call implies an error and an error code
from <<table_susp_errors>> will be in `sbiret.error`. A successful suspend and
wake up, results in the hart which initiated the suspend, resuming from the
`STOPPED` state. To resume, the hart will jump to supervisor-mode, at the
address specified by `resume_addr`, with the specific register values described
in <<table_susp_resume_state>>.

[#table_susp_resume_state]
.SUSP System Resume Register State
[cols=",", width=80%, align="center", options="header"]
|===
| Register Name | Register Value
| satp | 0
| sstatus.SIE | 0
| a0 | hartid
| a1 | `opaque` parameter
2+|All other registers remain in an undefined state.
|===

*NOTE:* A single `unsigned long` parameter is sufficient for `resume_addr`,
because the hart will resume execution in supervisor-mode with the MMU off,
hence `resume_addr` must be less than XLEN bits wide.

The `resume_addr` parameter points to a runtime-specified physical address,
where the hart can resume execution in supervisor-mode after a system suspend.

The `opaque` parameter is an XLEN-bit value which will be set in the `a1`
register when the hart resumes execution at `resume_addr` after a system
suspend.

Besides ensuring all entry criteria for the selected sleep type is met, such as
ensuring other harts are in the `STOPPED` state, the caller must ensure all
power units and domains are in a state compatible with the selected sleep type.
The preparation of the power units, power domains, and wake-up devices used for
resumption from the system sleep state is platform specific and beyond the
scope of this specification.

When supervisor software is running inside a virtual machine, the SBI
implementation is provided by a hypervisor. The system suspend will behave
functionally the same as the native case, but might not result in any physical
power changes.

The possible error codes returned in `sbiret.error` are shown in
<<table_susp_errors>>.

[#table_susp_errors]
.SUSP System Suspend Errors
[cols="1,2", width=100%, align="center", options="header"]
|===
| Error code | Description
| SBI_SUCCESS | System has suspended and resumed successfully.
| SBI_ERR_INVALID_PARAM | `sleep_type` is reserved or is platform-specific
and unimplemented.
| SBI_ERR_NOT_SUPPORTED | `sleep_type` is not reserved and is implemented,
but the platform does not support it.
| SBI_ERR_INVALID_ADDRESS | `resume_addr` is not valid, possibly due to the
following reasons: +
* It is not a valid physical address. +
* Executable access to the address is prohibited by
a physical memory protection mechanism or
H-extension G-stage for supervisor mode.
| SBI_ERR_FAILED | The suspend request failed for unspecified or
unknown other reasons.
|===

=== Function Listing

[#table_susp_function_list]
.SUSP Function List
[cols="3,2,1,2", width=80%, align="center", options="header"]
|===
| Function Name | SBI Version | FID | EID
| sbi_system_suspend | 2.0 | 0 | 0x53555350
|===

== Experimental SBI Extension Space (EIDs #0x08000000 - #0x08FFFFFF)

No management.
Expand Down

0 comments on commit 0a7ddb1

Please sign in to comment.