blob: 7e4f1f10326e4497a0178f11a0ad4d56a03d1c0c [file]
// Copyright 2017 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
#include <align.h>
#include <debug.h>
#include <lib/arch/asm.h>
#include <lib/boot-options/boot-options.h>
#include <lib/debuglog.h>
#include <lib/fit/defer.h>
#include <lib/instrumentation/asan.h>
#include <lib/page/size.h>
#include <lib/syscalls/forward.h>
#include <lib/wake-vector.h>
#include <lib/zbi-format/kernel.h>
#include <lib/zbi-format/zbi.h>
#include <lib/zbitl/checking.h>
#include <lib/zbitl/view.h>
#include <lib/zircon-internal/macros.h>
#include <platform.h>
#include <string.h>
#include <sys/types.h>
#include <trace.h>
#include <zircon/boot/crash-reason.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/rights.h>
#include <zircon/status.h>
#include <zircon/syscalls/resource.h>
#include <zircon/time.h>
#include <zircon/types.h>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <arch/arch_ops.h>
#include <arch/mp.h>
#include <arch/ops.h>
#include <dev/hw_watchdog.h>
#include <dev/interrupt.h>
#include <fbl/alloc_checker.h>
#include <fbl/ref_ptr.h>
#include <kernel/cpu.h>
#include <kernel/ffi.h>
#include <kernel/idle_power_thread.h>
#include <kernel/mp.h>
#include <kernel/percpu.h>
#include <kernel/range_check.h>
#include <kernel/scheduler.h>
#include <kernel/thread.h>
#include <ktl/byte.h>
#include <ktl/span.h>
#include <ktl/unique_ptr.h>
#include <object/event_dispatcher.h>
#include <object/handle.h>
#include <object/job_dispatcher.h>
#include <object/process_dispatcher.h>
#include <object/resource.h>
#include <object/resource_dispatcher.h>
#include <object/vm_object_dispatcher.h>
#include <phys/handoff.h>
#include <platform/halt_helper.h>
#include <platform/halt_token.h>
#include <platform/mexec.h>
#include <vm/handoff-end.h>
#include <vm/physmap.h>
#include <vm/pmm.h>
#include <vm/vm.h>
#include <vm/vm_aspace.h>
#include "system_priv.h"
#include <ktl/enforce.h>
#define LOCAL_TRACE 0
extern "C" zx_status_t cpp_system_mexec_payload_get_helper(uint8_t* buffer, size_t buffer_size,
size_t* out_zbi_size);
extern "C" NO_ASAN zx_status_t cpp_system_mexec_core(zx_handle_t resource, zx_handle_t kernel_vmo,
zx_handle_t data_zbi_vmo);
extern "C" zx_status_t cpp_system_mexec_payload_get_helper(uint8_t* buffer, size_t buffer_size,
size_t* out_zbi_size) {
if (auto result = WriteMexecData({reinterpret_cast<ktl::byte*>(buffer), buffer_size});
result.is_error()) {
return result.error_value();
} else {
*out_zbi_size = ktl::move(result).value();
return ZX_OK;
}
}
extern "C" NO_ASAN zx_status_t cpp_system_mexec_core(zx_handle_t resource, zx_handle_t kernel_vmo,
zx_handle_t data_zbi_vmo) {
return system_mexec_core(resource, kernel_vmo, data_zbi_vmo);
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE void cpp_scheduler_update_processing_rates(
zx_cpu_performance_info_t* info, size_t count) {
Scheduler::UpdateProcessingRates(ktl::span{info, count});
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE void cpp_scheduler_update_processing_limits(zx_cpu_perf_limit_t* info,
size_t count) {
Scheduler::UpdateProcessingLimits(ktl::span{info, count});
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE void cpp_scheduler_get_performance_scales(
zx_cpu_performance_info_t* info, size_t count) {
Scheduler::GetPerformanceScales(ktl::span{info, count});
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE void cpp_scheduler_get_default_performance_scales(
zx_cpu_performance_info_t* info, size_t count) {
Scheduler::GetDefaultPerformanceScales(ktl::span{info, count});
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE void cpp_scheduler_get_processing_limits(zx_cpu_perf_limit_t* info,
size_t count) {
Scheduler::GetProcessingLimits(ktl::span{info, count});
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE size_t cpp_percpu_processor_count() {
return percpu::processor_count();
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE zx_status_t cpp_mp_hotplug_cpu_mask_all() {
cpu_mask_t all_cpus = ((cpu_mask_t)1u << arch_max_num_cpus()) - 1;
return mp_hotplug_cpu_mask(~mp_get_online_mask() & all_cpus);
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE zx_status_t cpp_mp_unplug_cpu_mask_all_but_primary() {
cpu_mask_t primary = cpu_num_to_mask(0);
return mp_unplug_cpu_mask(mp_get_online_mask() & ~primary, ZX_TIME_INFINITE);
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE void cpp_platform_graceful_halt_helper(uint32_t action) {
platform_graceful_halt_helper(static_cast<platform_halt_action>(action),
ZirconCrashReason::NoCrash, ZX_TIME_INFINITE);
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE zx_status_t cpp_halt_token_ack_pending_halt() {
return HaltToken::Get().AckPendingHalt();
}
#if defined(__x86_64__)
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE zx_status_t
cpp_system_powerctl_x86_set_pkg_pl1(const zx_system_powerctl_arg_t* arg) {
MsrAccess msr;
return arch_system_powerctl(ZX_SYSTEM_POWERCTL_X86_SET_PKG_PL1, arg, &msr);
}
#endif
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE void cpp_wake_vector_discard_wake_event_report() {
wake_vector::WakeEvent::DiscardWakeEventReport();
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE zx_instant_boot_t
cpp_idle_power_thread_transition_all_active_to_suspend(zx_instant_boot_t resume_deadline) {
return IdlePowerThread::TransitionAllActiveToSuspend(resume_deadline);
}
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" FFI_ALWAYS_INLINE zx_status_t cpp_wake_vector_generate_wake_event_report(
zx_instant_boot_t start_time, zx_wake_source_report_header_t* out_header,
zx_wake_source_report_entry_t* out_entries, uint32_t num_entries, uint32_t* actual_entries) {
return wake_vector::WakeEvent::GenerateWakeEventReport(
start_time, make_user_out_ptr(out_header), make_user_out_ptr(out_entries), num_entries,
make_user_out_ptr(actual_entries));
}