| /* Copyright (c) 2015 Google Inc |
| * Davide Libenzi <dlibenzi@google.com> |
| * See LICENSE for details. |
| */ |
| |
| #pragma once |
| |
| #include <sys/types.h> |
| #include <ros/common.h> |
| #include <ros/arch/perfmon.h> |
| #include <arch/x86.h> |
| #include <atomic.h> |
| #include <core_set.h> |
| #include <stdint.h> |
| #include <kthread.h> |
| |
| #define MAX_VAR_COUNTERS 32 |
| #define MAX_FIX_COUNTERS 16 |
| #define MAX_PERFMON_COUNTERS (MAX_VAR_COUNTERS + MAX_FIX_COUNTERS) |
| #define INVALID_COUNTER INT32_MIN |
| |
| struct hw_trapframe; |
| |
| typedef int32_t counter_t; |
| |
| struct perfmon_cpu_caps { |
| uint32_t perfmon_version; |
| uint32_t proc_arch_events; |
| uint32_t bits_x_counter; |
| uint32_t counters_x_proc; |
| uint32_t bits_x_fix_counter; |
| uint32_t fix_counters_x_proc; |
| }; |
| |
| struct perfmon_alloc { |
| struct perfmon_event ev; |
| counter_t cores_counters[0]; |
| }; |
| |
| struct perfmon_session { |
| qlock_t qlock; |
| struct perfmon_alloc *allocs[MAX_PERFMON_COUNTERS]; |
| }; |
| |
| struct perfmon_status { |
| struct perfmon_event ev; |
| uint64_t cores_values[0]; |
| }; |
| |
| bool perfmon_supported(void); |
| void perfmon_global_init(void); |
| void perfmon_pcpu_init(void); |
| void perfmon_snapshot_hwtf(struct hw_trapframe *hw_tf); |
| void perfmon_snapshot_vmtf(struct vm_trapframe *vm_tf); |
| void perfmon_interrupt(struct hw_trapframe *hw_tf, void *data); |
| void perfmon_get_cpu_caps(struct perfmon_cpu_caps *pcc); |
| int perfmon_open_event(const struct core_set *cset, struct perfmon_session *ps, |
| const struct perfmon_event *pev); |
| void perfmon_close_event(struct perfmon_session *ps, int ped); |
| struct perfmon_status *perfmon_get_event_status(struct perfmon_session *ps, |
| int ped); |
| void perfmon_free_event_status(struct perfmon_status *pef); |
| struct perfmon_session *perfmon_create_session(void); |
| void perfmon_close_session(struct perfmon_session *ps); |
| |
| static inline uint64_t read_pmc(uint32_t index) |
| { |
| uint32_t edx, eax; |
| |
| asm volatile("rdpmc" : "=d"(edx), "=a"(eax) : "c"(index)); |
| return ((uint64_t) edx << 32) | eax; |
| } |