1/* 2 * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <arch.h> 8#include <assert_macros.S> 9#include <asm_macros.S> 10 11 .globl amu_group0_cnt_read_internal 12 .globl amu_group0_cnt_write_internal 13 .globl amu_group1_cnt_read_internal 14 .globl amu_group1_cnt_write_internal 15 .globl amu_group1_set_evtype_internal 16 17/* 18 * uint64_t amu_group0_cnt_read_internal(int idx); 19 * 20 * Given `idx`, read the corresponding AMU counter 21 * and return it in `x0`. 22 */ 23func amu_group0_cnt_read_internal 24 adr x1, 1f 25#if ENABLE_ASSERTIONS 26 /* 27 * It can be dangerous to call this function with an 28 * out of bounds index. Ensure `idx` is valid. 29 */ 30 tst x0, #~3 31 ASM_ASSERT(eq) 32#endif 33 /* 34 * Given `idx` calculate address of mrs/ret instruction pair 35 * in the table below. 36 */ 37 add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */ 38#if ENABLE_BTI 39 add x1, x1, x0, lsl #2 /* + "bti j" instruction */ 40#endif 41 br x1 42 431: read AMEVCNTR00_EL0 /* index 0 */ 44 read AMEVCNTR01_EL0 /* index 1 */ 45 read AMEVCNTR02_EL0 /* index 2 */ 46 read AMEVCNTR03_EL0 /* index 3 */ 47endfunc amu_group0_cnt_read_internal 48 49/* 50 * void amu_group0_cnt_write_internal(int idx, uint64_t val); 51 * 52 * Given `idx`, write `val` to the corresponding AMU counter. 53 */ 54func amu_group0_cnt_write_internal 55 adr x2, 1f 56#if ENABLE_ASSERTIONS 57 /* 58 * It can be dangerous to call this function with an 59 * out of bounds index. Ensure `idx` is valid. 60 */ 61 tst x0, #~3 62 ASM_ASSERT(eq) 63#endif 64 /* 65 * Given `idx` calculate address of mrs/ret instruction pair 66 * in the table below. 67 */ 68 add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */ 69#if ENABLE_BTI 70 add x2, x2, x0, lsl #2 /* + "bti j" instruction */ 71#endif 72 br x2 73 741: write AMEVCNTR00_EL0 /* index 0 */ 75 write AMEVCNTR01_EL0 /* index 1 */ 76 write AMEVCNTR02_EL0 /* index 2 */ 77 write AMEVCNTR03_EL0 /* index 3 */ 78endfunc amu_group0_cnt_write_internal 79 80/* 81 * uint64_t amu_group1_cnt_read_internal(int idx); 82 * 83 * Given `idx`, read the corresponding AMU counter 84 * and return it in `x0`. 85 */ 86func amu_group1_cnt_read_internal 87 adr x1, 1f 88#if ENABLE_ASSERTIONS 89 /* 90 * It can be dangerous to call this function with an 91 * out of bounds index. Ensure `idx` is valid. 92 */ 93 tst x0, #~0xF 94 ASM_ASSERT(eq) 95#endif 96 /* 97 * Given `idx` calculate address of mrs/ret instruction pair 98 * in the table below. 99 */ 100 add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */ 101#if ENABLE_BTI 102 add x1, x1, x0, lsl #2 /* + "bti j" instruction */ 103#endif 104 br x1 105 1061: read AMEVCNTR10_EL0 /* index 0 */ 107 read AMEVCNTR11_EL0 /* index 1 */ 108 read AMEVCNTR12_EL0 /* index 2 */ 109 read AMEVCNTR13_EL0 /* index 3 */ 110 read AMEVCNTR14_EL0 /* index 4 */ 111 read AMEVCNTR15_EL0 /* index 5 */ 112 read AMEVCNTR16_EL0 /* index 6 */ 113 read AMEVCNTR17_EL0 /* index 7 */ 114 read AMEVCNTR18_EL0 /* index 8 */ 115 read AMEVCNTR19_EL0 /* index 9 */ 116 read AMEVCNTR1A_EL0 /* index 10 */ 117 read AMEVCNTR1B_EL0 /* index 11 */ 118 read AMEVCNTR1C_EL0 /* index 12 */ 119 read AMEVCNTR1D_EL0 /* index 13 */ 120 read AMEVCNTR1E_EL0 /* index 14 */ 121 read AMEVCNTR1F_EL0 /* index 15 */ 122endfunc amu_group1_cnt_read_internal 123 124/* 125 * void amu_group1_cnt_write_internal(int idx, uint64_t val); 126 * 127 * Given `idx`, write `val` to the corresponding AMU counter. 128 */ 129func amu_group1_cnt_write_internal 130 adr x2, 1f 131#if ENABLE_ASSERTIONS 132 /* 133 * It can be dangerous to call this function with an 134 * out of bounds index. Ensure `idx` is valid. 135 */ 136 tst x0, #~0xF 137 ASM_ASSERT(eq) 138#endif 139 /* 140 * Given `idx` calculate address of mrs/ret instruction pair 141 * in the table below. 142 */ 143 add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */ 144#if ENABLE_BTI 145 add x2, x2, x0, lsl #2 /* + "bti j" instruction */ 146#endif 147 br x2 148 1491: write AMEVCNTR10_EL0 /* index 0 */ 150 write AMEVCNTR11_EL0 /* index 1 */ 151 write AMEVCNTR12_EL0 /* index 2 */ 152 write AMEVCNTR13_EL0 /* index 3 */ 153 write AMEVCNTR14_EL0 /* index 4 */ 154 write AMEVCNTR15_EL0 /* index 5 */ 155 write AMEVCNTR16_EL0 /* index 6 */ 156 write AMEVCNTR17_EL0 /* index 7 */ 157 write AMEVCNTR18_EL0 /* index 8 */ 158 write AMEVCNTR19_EL0 /* index 9 */ 159 write AMEVCNTR1A_EL0 /* index 10 */ 160 write AMEVCNTR1B_EL0 /* index 11 */ 161 write AMEVCNTR1C_EL0 /* index 12 */ 162 write AMEVCNTR1D_EL0 /* index 13 */ 163 write AMEVCNTR1E_EL0 /* index 14 */ 164 write AMEVCNTR1F_EL0 /* index 15 */ 165endfunc amu_group1_cnt_write_internal 166 167/* 168 * void amu_group1_set_evtype_internal(int idx, unsigned int val); 169 * 170 * Program the AMU event type register indexed by `idx` 171 * with the value `val`. 172 */ 173func amu_group1_set_evtype_internal 174 adr x2, 1f 175#if ENABLE_ASSERTIONS 176 /* 177 * It can be dangerous to call this function with an 178 * out of bounds index. Ensure `idx` is valid. 179 */ 180 tst x0, #~0xF 181 ASM_ASSERT(eq) 182 183 /* val should be between [0, 65535] */ 184 tst x1, #~0xFFFF 185 ASM_ASSERT(eq) 186#endif 187 /* 188 * Given `idx` calculate address of msr/ret instruction pair 189 * in the table below. 190 */ 191 add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */ 192#if ENABLE_BTI 193 add x2, x2, x0, lsl #2 /* + "bti j" instruction */ 194#endif 195 br x2 196 1971: write AMEVTYPER10_EL0 /* index 0 */ 198 write AMEVTYPER11_EL0 /* index 1 */ 199 write AMEVTYPER12_EL0 /* index 2 */ 200 write AMEVTYPER13_EL0 /* index 3 */ 201 write AMEVTYPER14_EL0 /* index 4 */ 202 write AMEVTYPER15_EL0 /* index 5 */ 203 write AMEVTYPER16_EL0 /* index 6 */ 204 write AMEVTYPER17_EL0 /* index 7 */ 205 write AMEVTYPER18_EL0 /* index 8 */ 206 write AMEVTYPER19_EL0 /* index 9 */ 207 write AMEVTYPER1A_EL0 /* index 10 */ 208 write AMEVTYPER1B_EL0 /* index 11 */ 209 write AMEVTYPER1C_EL0 /* index 12 */ 210 write AMEVTYPER1D_EL0 /* index 13 */ 211 write AMEVTYPER1E_EL0 /* index 14 */ 212 write AMEVTYPER1F_EL0 /* index 15 */ 213endfunc amu_group1_set_evtype_internal 214