// 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 #include #include #include #include #include #include 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; }