blob: 091c741941ea14f261814b89e9f501eeff843f2c [file] [log] [blame]
// 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 <fuchsia/kernel/c/fidl.h>
#include <lib/fidl-async/bind.h>
#include <lib/kcounter/provider.h>
#include <lib/zx/vmo.h>
#include <string.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include "kcounter.h"
namespace {
zx_status_t GetInspectVMO(void* ctx, fidl_txn_t* txn) {
zx::vmo vmo;
fuchsia_mem_Buffer buffer{.vmo = ZX_HANDLE_INVALID, .size = 0};
auto status = static_cast<kcounter::VmoToInspectMapper*>(ctx)->GetInspectVMO(&vmo);
if (status == ZX_OK) {
buffer.vmo = vmo.get();
auto size_status = vmo.get_size(&buffer.size);
if (size_status != ZX_OK) {
return size_status;
}
}
return fuchsia_kernel_CounterGetInspectVmo_reply(txn, status, &buffer);
}
zx_status_t UpdateInspectVMO(void* ctx, fidl_txn_t* txn) {
auto status = static_cast<kcounter::VmoToInspectMapper*>(ctx)->UpdateInspectVMO();
return fuchsia_kernel_CounterUpdateInspectVmo_reply(txn, status);
}
constexpr fuchsia_kernel_Counter_ops_t kFidlOps = {
.GetInspectVmo = GetInspectVMO,
.UpdateInspectVmo = UpdateInspectVMO,
};
zx_status_t Connect(void* ctx, async_dispatcher_t* dispatcher, const char* service_name,
zx_handle_t request) {
if (strcmp(service_name, fuchsia_kernel_Counter_Name) == 0) {
return fidl_bind(dispatcher, request,
reinterpret_cast<fidl_dispatch_t*>(fuchsia_kernel_Counter_dispatch), ctx,
&kFidlOps);
}
zx_handle_close(request);
return ZX_ERR_NOT_SUPPORTED;
}
zx_status_t Init(void** out_ctx) {
*out_ctx = new kcounter::VmoToInspectMapper;
return ZX_OK;
}
void Release(void* ctx) { delete static_cast<kcounter::VmoToInspectMapper*>(ctx); }
constexpr const char* kKcounterServices[] = {
fuchsia_kernel_Counter_Name,
nullptr,
};
constexpr zx_service_ops_t kKcounterOps = {
.init = Init,
.connect = Connect,
.release = Release,
};
constexpr zx_service_provider_t kcounter_service_provider = {
.version = SERVICE_PROVIDER_VERSION,
.services = kKcounterServices,
.ops = &kKcounterOps,
};
} // namespace
const zx_service_provider_t* kcounter_get_service_provider() { return &kcounter_service_provider; }