blob: 15553f2c28dd846cdf4377a6fda62eec4e192ace [file] [log] [blame]
// Copyright 2018 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 <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/platform/device.h>
#include <stdlib.h>
#include <string.h>
typedef struct cpu_trace_dev {
zx_device_t* zxdev;
zx_handle_t bti;
} cpu_trace_dev_t;
static const pdev_device_info_t cpu_trace_pdev_device_info = {
.vid = PDEV_VID_INTEL,
.pid = PDEV_PID_GENERIC,
.did = PDEV_DID_INTEL_CPU_TRACE,
.bti_count = 1,
};
static zx_status_t cpu_trace_get_bti(void* ctx, uint32_t index, zx_handle_t* out_handle) {
cpu_trace_dev_t* dev = ctx;
if (index >= cpu_trace_pdev_device_info.bti_count || out_handle == NULL) {
return ZX_ERR_INVALID_ARGS;
}
return zx_handle_duplicate(dev->bti, ZX_RIGHT_SAME_RIGHTS, out_handle);
}
static zx_status_t cpu_trace_get_device_info(void* ctx, pdev_device_info_t* out_info) {
memcpy(out_info, &cpu_trace_pdev_device_info, sizeof(*out_info));
return ZX_OK;
}
static zx_status_t cpu_trace_get_mmio(void* ctx, uint32_t index, pdev_mmio_t* mmio) {
return ZX_ERR_NOT_SUPPORTED;
}
static zx_status_t cpu_trace_get_interrupt(void* ctx, uint32_t index, uint32_t flags, zx_handle_t* out_handle) {
return ZX_ERR_NOT_SUPPORTED;
}
static pdev_protocol_ops_t cpu_trace_proto_ops = {
.get_mmio = cpu_trace_get_mmio,
.get_interrupt = cpu_trace_get_interrupt,
.get_bti = cpu_trace_get_bti,
.get_device_info = cpu_trace_get_device_info,
};
static void cpu_trace_release(void* ctx) {
cpu_trace_dev_t* dev = ctx;
zx_handle_close(dev->bti);
free(dev);
}
static zx_protocol_device_t cpu_trace_dev_proto = {
.version = DEVICE_OPS_VERSION,
.release = cpu_trace_release,
};
zx_status_t publish_cpu_trace(zx_handle_t bti, zx_device_t* sys_root) {
cpu_trace_dev_t* dev = calloc(1, sizeof(*dev));
if (dev == NULL) {
return ZX_ERR_NO_MEMORY;
}
dev->bti = bti;
zx_device_prop_t props[] = {
{BIND_PLATFORM_DEV_VID, 0, cpu_trace_pdev_device_info.vid},
{BIND_PLATFORM_DEV_PID, 0, cpu_trace_pdev_device_info.pid},
{BIND_PLATFORM_DEV_DID, 0, cpu_trace_pdev_device_info.did},
};
device_add_args_t args = {
.version = DEVICE_ADD_ARGS_VERSION,
.name = "cpu-trace",
.ctx = dev,
.ops = &cpu_trace_dev_proto,
.proto_id = ZX_PROTOCOL_PDEV,
.proto_ops = &cpu_trace_proto_ops,
.props = props,
.prop_count = countof(props),
.proxy_args = NULL,
.flags = 0,
};
// add as a child of the sysroot
zx_status_t status = device_add(sys_root, &args, &dev->zxdev);
if (status != ZX_OK) {
zxlogf(ERROR, "acpi-bus: error %d in device_add(sys/cpu-trace)\n", status);
cpu_trace_release(dev);
return status;
}
return ZX_OK;
}