blob: 768b13dcaebafa3d67908b2f8cc3cd4df344b12e [file] [edit]
// Copyright 2026 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
//
// Ported from zircon/kernel/dev/pdev/power/power.cc
#include <zircon/errors.h>
#include <zircon/types.h>
#include <dev/power.h>
#include <kernel/ffi.h>
#include <pdev/power.h>
extern "C" {
void rust_power_reboot(power_reboot_flags flags);
void rust_power_shutdown();
zx_status_t rust_power_cpu_off();
zx_status_t rust_power_cpu_on(uint64_t hw_cpu_id, paddr_t entry, uint64_t context);
zx_status_t rust_power_get_cpu_state(uint64_t hw_cpu_id, power_cpu_state* out_state);
zx_status_t rust_power_opp_set(uint32_t domain_id, uint64_t opp);
zx_status_t rust_power_opp_get(uint32_t domain_id, uint64_t* out_opp);
zx_status_t rust_power_opp_get_domain_count(size_t* out_count);
void rust_pdev_register_power(const pdev_power_ops* ops);
const pdev_power_ops* rust_pdev_swap_power_for_test(const pdev_power_ops* ops);
} // extern "C"
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
FFI_ALWAYS_INLINE void power_reboot(power_reboot_flags flags) { rust_power_reboot(flags); }
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
FFI_ALWAYS_INLINE void power_shutdown() { rust_power_shutdown(); }
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
FFI_ALWAYS_INLINE zx_status_t power_cpu_off() { return rust_power_cpu_off(); }
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
FFI_ALWAYS_INLINE zx_status_t power_cpu_on(uint64_t hw_cpu_id, paddr_t entry, uint64_t context) {
return rust_power_cpu_on(hw_cpu_id, entry, context);
}
zx::result<power_cpu_state> power_get_cpu_state(uint64_t hw_cpu_id) {
power_cpu_state state = power_cpu_state::OFF;
zx_status_t status = rust_power_get_cpu_state(hw_cpu_id, &state);
if (status != ZX_OK) {
return zx::error(status);
}
return zx::ok(state);
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
FFI_ALWAYS_INLINE zx_status_t power_opp_set(uint32_t domain_id, uint64_t opp) {
return rust_power_opp_set(domain_id, opp);
}
zx::result<uint64_t> power_opp_get(uint32_t domain_id) {
uint64_t opp = 0;
zx_status_t status = rust_power_opp_get(domain_id, &opp);
if (status != ZX_OK) {
return zx::error(status);
}
return zx::ok(opp);
}
zx::result<size_t> power_opp_get_domain_count() {
size_t count = 0;
zx_status_t status = rust_power_opp_get_domain_count(&count);
if (status != ZX_OK) {
return zx::error(status);
}
return zx::ok(count);
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
FFI_ALWAYS_INLINE void pdev_register_power(const pdev_power_ops* ops) {
rust_pdev_register_power(ops);
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
FFI_ALWAYS_INLINE const pdev_power_ops* pdev_swap_power_for_test(const pdev_power_ops* ops) {
return rust_pdev_swap_power_for_test(ops);
}