use super::{
AffinityState, LowestAffinityLevel, MigrateType, PSCI_AFFINITY_INFO_32, PSCI_AFFINITY_INFO_64,
PSCI_CPU_DEFAULT_SUSPEND_32, PSCI_CPU_DEFAULT_SUSPEND_64, PSCI_CPU_FREEZE, PSCI_CPU_OFF,
PSCI_CPU_ON_32, PSCI_CPU_ON_64, PSCI_CPU_SUSPEND_32, PSCI_CPU_SUSPEND_64, PSCI_FEATURES,
PSCI_MEM_PROTECT, PSCI_MEM_PROTECT_CHECK_RANGE_32, PSCI_MEM_PROTECT_CHECK_RANGE_64,
PSCI_MIGRATE_32, PSCI_MIGRATE_64, PSCI_MIGRATE_INFO_TYPE, PSCI_MIGRATE_INFO_UP_CPU_32,
PSCI_MIGRATE_INFO_UP_CPU_64, PSCI_NODE_HW_STATE_32, PSCI_NODE_HW_STATE_64,
PSCI_SET_SUSPEND_MODE, PSCI_STAT_COUNT_32, PSCI_STAT_COUNT_64, PSCI_STAT_RESIDENCY_32,
PSCI_STAT_RESIDENCY_64, PSCI_SYSTEM_OFF, PSCI_SYSTEM_RESET, PSCI_SYSTEM_RESET2_32,
PSCI_SYSTEM_RESET2_64, PSCI_SYSTEM_SUSPEND_32, PSCI_SYSTEM_SUSPEND_64, PSCI_VERSION,
PowerState, SuspendMode, Version, error::Error,
};
use crate::{
Call,
error::{positive_or_error_32, success_or_error_32, success_or_error_64},
};
pub fn version<C: Call>() -> Result<Version, Error> {
(C::call32(PSCI_VERSION, [0; 7])[0] as i32).try_into()
}
pub fn cpu_suspend<C: Call>(
power_state: u32,
entry_point_address: u64,
context_id: u64,
) -> Result<(), Error> {
success_or_error_64(
C::call64(
PSCI_CPU_SUSPEND_64,
[
power_state.into(),
entry_point_address,
context_id,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
)[0],
)
}
pub fn cpu_suspend_32<C: Call>(
power_state: u32,
entry_point_address: u32,
context_id: u32,
) -> Result<(), Error> {
success_or_error_32(
C::call32(
PSCI_CPU_SUSPEND_32,
[power_state, entry_point_address, context_id, 0, 0, 0, 0],
)[0],
)
}
pub fn cpu_off<C: Call>() -> Result<(), Error> {
success_or_error_32(C::call32(PSCI_CPU_OFF, [0; 7])[0])
}
pub fn cpu_on<C: Call>(
target_cpu: u64,
entry_point_address: u64,
context_id: u64,
) -> Result<(), Error> {
success_or_error_64(
C::call64(
PSCI_CPU_ON_64,
[
target_cpu,
entry_point_address,
context_id,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
)[0],
)
}
pub fn cpu_on_32<C: Call>(
target_cpu: u32,
entry_point_address: u32,
context_id: u32,
) -> Result<(), Error> {
success_or_error_32(
C::call32(
PSCI_CPU_ON_32,
[target_cpu, entry_point_address, context_id, 0, 0, 0, 0],
)[0],
)
}
pub fn affinity_info<C: Call>(
target_affinity: u64,
lowest_affinity_level: LowestAffinityLevel,
) -> Result<AffinityState, Error> {
(C::call64(
PSCI_AFFINITY_INFO_64,
[
target_affinity,
lowest_affinity_level as u64,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
)[0] as i32)
.try_into()
}
pub fn affinity_info_32<C: Call>(
target_affinity: u32,
lowest_affinity_level: LowestAffinityLevel,
) -> Result<AffinityState, Error> {
(C::call32(
PSCI_AFFINITY_INFO_32,
[target_affinity, lowest_affinity_level as u32, 0, 0, 0, 0, 0],
)[0] as i32)
.try_into()
}
pub fn migrate<C: Call>(target_cpu: u64) -> Result<(), Error> {
success_or_error_64(
C::call64(
PSCI_MIGRATE_64,
[target_cpu, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
)[0],
)
}
pub fn migrate_32<C: Call>(target_cpu: u32) -> Result<(), Error> {
success_or_error_32(C::call32(PSCI_MIGRATE_32, [target_cpu, 0, 0, 0, 0, 0, 0])[0])
}
pub fn migrate_info_type<C: Call>() -> Result<MigrateType, Error> {
(C::call32(PSCI_MIGRATE_INFO_TYPE, [0; 7])[0] as i32).try_into()
}
pub fn migrate_info_up_cpu<C: Call>() -> u64 {
C::call64(PSCI_MIGRATE_INFO_UP_CPU_64, [0; 17])[0]
}
pub fn migrate_info_up_cpu_32<C: Call>() -> u32 {
C::call32(PSCI_MIGRATE_INFO_UP_CPU_32, [0; 7])[0]
}
pub fn system_off<C: Call>() -> Result<(), Error> {
success_or_error_32(C::call32(PSCI_SYSTEM_OFF, [0; 7])[0])
}
pub fn system_reset<C: Call>() -> Result<(), Error> {
success_or_error_32(C::call32(PSCI_SYSTEM_RESET, [0; 7])[0])
}
pub fn system_reset2<C: Call>(reset_type: u32, cookie: u64) -> Result<(), Error> {
success_or_error_64(
C::call64(
PSCI_SYSTEM_RESET2_64,
[
reset_type.into(),
cookie,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
)[0],
)
}
pub fn system_reset2_32<C: Call>(reset_type: u32, cookie: u32) -> Result<(), Error> {
success_or_error_32(C::call32(PSCI_SYSTEM_RESET2_32, [reset_type, cookie, 0, 0, 0, 0, 0])[0])
}
pub fn mem_protect<C: Call>(enable: bool) -> Result<bool, Error> {
match C::call32(PSCI_MEM_PROTECT, [enable as u32, 0, 0, 0, 0, 0, 0])[0] as i32 {
0 => Ok(false),
1 => Ok(true),
error => Err(error.into()),
}
}
pub fn mem_protect_check_range<C: Call>(base: u64, length: u64) -> Result<(), Error> {
success_or_error_64(
C::call64(
PSCI_MEM_PROTECT_CHECK_RANGE_64,
[base, length, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
)[0],
)
}
pub fn mem_protect_check_range_32<C: Call>(base: u32, length: u32) -> Result<(), Error> {
success_or_error_32(
C::call32(
PSCI_MEM_PROTECT_CHECK_RANGE_32,
[base, length, 0, 0, 0, 0, 0],
)[0],
)
}
pub fn psci_features<C: Call>(psci_function_id: u32) -> Result<u32, Error> {
positive_or_error_32(C::call32(PSCI_FEATURES, [psci_function_id, 0, 0, 0, 0, 0, 0])[0])
}
pub fn cpu_freeze<C: Call>() -> Result<(), Error> {
success_or_error_32(C::call32(PSCI_CPU_FREEZE, [0; 7])[0])
}
pub fn cpu_default_suspend<C: Call>(
entry_point_address: u64,
context_id: u64,
) -> Result<(), Error> {
success_or_error_64(
C::call64(
PSCI_CPU_DEFAULT_SUSPEND_64,
[
entry_point_address,
context_id,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
)[0],
)
}
pub fn cpu_default_suspend_32<C: Call>(
entry_point_address: u32,
context_id: u32,
) -> Result<(), Error> {
success_or_error_32(
C::call32(
PSCI_CPU_DEFAULT_SUSPEND_32,
[entry_point_address, context_id, 0, 0, 0, 0, 0],
)[0],
)
}
pub fn node_hw_state<C: Call>(target_cpu: u64, power_level: u32) -> Result<PowerState, Error> {
(C::call64(
PSCI_NODE_HW_STATE_64,
[
target_cpu,
power_level.into(),
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
)[0] as i32)
.try_into()
}
pub fn node_hw_state_32<C: Call>(target_cpu: u32, power_level: u32) -> Result<PowerState, Error> {
(C::call32(
PSCI_NODE_HW_STATE_32,
[target_cpu, power_level, 0, 0, 0, 0, 0],
)[0] as i32)
.try_into()
}
pub fn system_suspend<C: Call>(entry_point_address: u64, context_id: u64) -> Result<(), Error> {
success_or_error_64(
C::call64(
PSCI_SYSTEM_SUSPEND_64,
[
entry_point_address,
context_id,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
)[0],
)
}
pub fn system_suspend_32<C: Call>(entry_point_address: u32, context_id: u32) -> Result<(), Error> {
success_or_error_32(
C::call32(
PSCI_SYSTEM_SUSPEND_32,
[entry_point_address, context_id, 0, 0, 0, 0, 0],
)[0],
)
}
pub fn set_suspend_mode<C: Call>(mode: SuspendMode) -> Result<(), Error> {
success_or_error_32(C::call32(PSCI_SET_SUSPEND_MODE, [mode.into(), 0, 0, 0, 0, 0, 0])[0])
}
pub fn stat_residency<C: Call>(target_cpu: u64, power_state: u32) -> u64 {
C::call64(
PSCI_STAT_RESIDENCY_64,
[
target_cpu,
power_state.into(),
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
)[0]
}
pub fn stat_residency_32<C: Call>(target_cpu: u32, power_state: u32) -> u32 {
C::call32(
PSCI_STAT_RESIDENCY_32,
[target_cpu, power_state, 0, 0, 0, 0, 0],
)[0]
}
pub fn stat_count<C: Call>(target_cpu: u64, power_state: u32) -> u64 {
C::call64(
PSCI_STAT_COUNT_64,
[
target_cpu,
power_state.into(),
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
)[0]
}
pub fn stat_count_32<C: Call>(target_cpu: u32, power_state: u32) -> u32 {
C::call32(PSCI_STAT_COUNT_32, [target_cpu, power_state, 0, 0, 0, 0, 0])[0]
}