| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <lib/kernel-debug/kernel-debug.h> |
| |
| #include <fuchsia/kernel/c/fidl.h> |
| #include <lib/fidl-async/bind.h> |
| #include <lib/zircon-internal/ktrace.h> |
| #include <string.h> |
| #include <zircon/assert.h> |
| #include <zircon/syscalls.h> |
| |
| namespace { |
| |
| zx_status_t HandleSendDebugCommand(void* ctx, const char* command, size_t command_size, |
| fidl_txn_t* txn) { |
| const zx_handle_t root_resource = static_cast<zx_handle_t>(reinterpret_cast<uintptr_t>(ctx)); |
| const auto status = zx_debug_send_command(root_resource, command, command_size); |
| return fuchsia_kernel_DebugBrokerSendDebugCommand_reply(txn, status); |
| } |
| |
| zx_status_t HandleSetTracingEnabled(void* ctx, bool enabled, fidl_txn_t* txn) { |
| const zx_handle_t root_resource = static_cast<zx_handle_t>(reinterpret_cast<uintptr_t>(ctx)); |
| zx_status_t status; |
| if (enabled) { |
| status = zx_ktrace_control(root_resource, KTRACE_ACTION_START, KTRACE_GRP_ALL, nullptr); |
| } else { |
| status = zx_ktrace_control(root_resource, KTRACE_ACTION_STOP, 0, nullptr); |
| if (status == ZX_OK) { |
| status = zx_ktrace_control(root_resource, KTRACE_ACTION_REWIND, 0, nullptr); |
| } |
| } |
| return fuchsia_kernel_DebugBrokerSendDebugCommand_reply(txn, status); |
| } |
| |
| constexpr const fuchsia_kernel_DebugBroker_ops_t kInterfaceOps = { |
| .SendDebugCommand = HandleSendDebugCommand, |
| .SetTracingEnabled = HandleSetTracingEnabled, |
| }; |
| |
| zx_status_t Connect(void* ctx, async_dispatcher_t* dispatcher, const char* service_name, |
| zx_handle_t request) { |
| if (!strcmp(service_name, fuchsia_kernel_DebugBroker_Name)) { |
| return fidl_bind(dispatcher, request, (fidl_dispatch_t*)fuchsia_kernel_DebugBroker_dispatch, |
| ctx, &kInterfaceOps); |
| } |
| |
| zx_handle_close(request); |
| return ZX_ERR_NOT_SUPPORTED; |
| } |
| |
| constexpr const char* kServices[] = { |
| fuchsia_kernel_DebugBroker_Name, |
| nullptr, |
| }; |
| |
| constexpr zx_service_ops_t kServiceOps = { |
| .init = nullptr, |
| .connect = Connect, |
| .release = nullptr, |
| }; |
| |
| constexpr zx_service_provider_t kDebugBrokerServiceProvider = { |
| .version = SERVICE_PROVIDER_VERSION, |
| .services = kServices, |
| .ops = &kServiceOps, |
| }; |
| |
| } // namespace |
| |
| const zx_service_provider_t* kernel_debug_get_service_provider() { |
| return &kDebugBrokerServiceProvider; |
| } |