summaryrefslogtreecommitdiff
path: root/include/sbi/sbi_pmu.h
blob: 53f27003a9ef0a92f1197c1df297e4802feaf1be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (c) 2021 Western Digital Corporation or its affiliates.
 *
 * Authors:
 *   Atish Patra <atish.patra@wdc.com>
 */

#ifndef __SBI_PMU_H__
#define __SBI_PMU_H__

#include <sbi/sbi_types.h>

struct sbi_scratch;

/* Event related macros */
/* Maximum number of hardware events that can mapped by OpenSBI */
#define SBI_PMU_HW_EVENT_MAX 256

/* Counter related macros */
#define SBI_PMU_FW_CTR_MAX 16
#define SBI_PMU_HW_CTR_MAX 32
#define SBI_PMU_CTR_MAX	   (SBI_PMU_HW_CTR_MAX + SBI_PMU_FW_CTR_MAX)
#define SBI_PMU_FIXED_CTR_MASK 0x07

struct sbi_pmu_device {
	/** Name of the PMU platform device */
	char name[32];

	/**
	 * Validate event code of custom firmware event
	 */
	int (*fw_event_validate_encoding)(uint64_t event_data);

	/**
	 * Match custom firmware counter with custom firmware event
	 * Note: 0 <= counter_index < SBI_PMU_FW_CTR_MAX
	 */
	bool (*fw_counter_match_encoding)(uint32_t counter_index,
					  uint64_t event_data);

	/**
	 * Fetch the max width of this counter in number of bits.
	 */
	int (*fw_counter_width)(void);

	/**
	 * Read value of custom firmware counter
	 * Note: 0 <= counter_index < SBI_PMU_FW_CTR_MAX
	 */
	uint64_t (*fw_counter_read_value)(uint32_t counter_index);

	/**
	 * Write value to custom firmware counter
	 * Note: 0 <= counter_index < SBI_PMU_FW_CTR_MAX
	 */
	void (*fw_counter_write_value)(uint32_t counter_index,
				       uint64_t value);

	/**
	 * Start custom firmware counter
	 * Note: 0 <= counter_index < SBI_PMU_FW_CTR_MAX
	 */
	int (*fw_counter_start)(uint32_t counter_index,
				uint64_t event_data);

	/**
	 * Stop custom firmware counter
	 * Note: 0 <= counter_index < SBI_PMU_FW_CTR_MAX
	 */
	int (*fw_counter_stop)(uint32_t counter_index);

	/**
	 * Custom enable irq for hardware counter
	 * Note: 0 <= counter_index < SBI_PMU_HW_CTR_MAX
	 */
	void (*hw_counter_enable_irq)(uint32_t counter_index);

	/**
	 * Custom disable irq for hardware counter
	 * Note: 0 <= counter_index < SBI_PMU_HW_CTR_MAX
	 */
	void (*hw_counter_disable_irq)(uint32_t counter_index);

	/**
	 * Custom function returning the machine-specific irq-bit.
	 */
	int (*hw_counter_irq_bit)(void);
};

/** Get the PMU platform device */
const struct sbi_pmu_device *sbi_pmu_get_device(void);

/** Set the PMU platform device */
void sbi_pmu_set_device(const struct sbi_pmu_device *dev);

/** Initialize PMU */
int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot);

/** Reset PMU during hart exit */
void sbi_pmu_exit(struct sbi_scratch *scratch);

/** Return the pmu irq bit depending on extension existence */
int sbi_pmu_irq_bit(void);

/**
 * Add the hardware event to counter mapping information. This should be called
 * from the platform code to update the mapping table.
 * @param eidx_start Start of the event idx range for supported counters
 * @param eidx_end   End of the event idx range for supported counters
 * @param cmap       A bitmap representing counters supporting the event range
 * @return 0 on success, error otherwise.
 */
int sbi_pmu_add_hw_event_counter_map(u32 eidx_start, u32 eidx_end, u32 cmap);

/**
 * Add the raw hardware event selector and supported counter information. This
 * should be called from the platform code to update the mapping table.
 * @param info  a pointer to the hardware event info
 * @return 0 on success, error otherwise.
 */

int sbi_pmu_add_raw_event_counter_map(uint64_t select, uint64_t select_mask, u32 cmap);

int sbi_pmu_ctr_fw_read(uint32_t cidx, uint64_t *cval);

int sbi_pmu_ctr_stop(unsigned long cidx_base, unsigned long cidx_mask,
		     unsigned long flag);

int sbi_pmu_ctr_start(unsigned long cidx_base, unsigned long cidx_mask,
		      unsigned long flags, uint64_t ival);

int sbi_pmu_ctr_get_info(uint32_t cidx, unsigned long *ctr_info);

unsigned long sbi_pmu_num_ctr(void);

int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask,
			  unsigned long flags, unsigned long event_idx,
			  uint64_t event_data);

int sbi_pmu_ctr_incr_fw(enum sbi_pmu_fw_event_code_id fw_id);

#endif