blob: 8dcbcaac7ad302ce45a759afa82a43389567b70a [file] [log] [blame]
// Copyright 2022, The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! PSCI calls.
const PSCI_SYSTEM_OFF: u32 = 0x84000008;
const PSCI_SYSTEM_RESET: u32 = 0x84000009;
const PSCI_SYSTEM_RESET2: u32 = 0x84000012;
pub fn system_off() -> u32 {
hvc32(PSCI_SYSTEM_OFF, 0, 0, 0, 0, 0, 0, 0)[0]
}
pub fn system_reset() -> u32 {
hvc32(PSCI_SYSTEM_RESET, 0, 0, 0, 0, 0, 0, 0)[0]
}
#[allow(unused)]
pub fn system_reset2(reset_type: u32, cookie: u32) -> u32 {
hvc32(PSCI_SYSTEM_RESET2, reset_type, cookie, 0, 0, 0, 0, 0)[0]
}
/// Make an HVC32 call to the hypervisor, following the SMC Calling Convention version 1.3.
#[inline(always)]
#[allow(clippy::too_many_arguments)]
fn hvc32(
function: u32,
arg1: u32,
arg2: u32,
arg3: u32,
arg4: u32,
arg5: u32,
arg6: u32,
arg7: u32,
) -> [u32; 8] {
let mut ret = [0; 8];
#[cfg(target_arch = "aarch64")]
unsafe {
core::arch::asm!(
"hvc #0",
inout("w0") function => ret[0],
inout("w1") arg1 => ret[1],
inout("w2") arg2 => ret[2],
inout("w3") arg3 => ret[3],
inout("w4") arg4 => ret[4],
inout("w5") arg5 => ret[5],
inout("w6") arg6 => ret[6],
inout("w7") arg7 => ret[7],
options(nomem, nostack)
)
}
#[cfg(not(target_arch = "aarch64"))]
unimplemented!();
ret
}