1 /* 2 * Copyright (c) 2014-2018, Intel Corporation 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * * Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * * Neither the name of Intel Corporation nor the names of its contributors 13 * may be used to endorse or promote products derived from this software 14 * without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "pt_time.h" 30 31 #include "intel-pt.h" 32 33 #include "ptunit.h" 34 35 36 /* A time unit test fixture. */ 37 38 struct time_fixture { 39 /* The configuration to use. */ 40 struct pt_config config; 41 42 /* The calibration to use. */ 43 struct pt_time_cal tcal; 44 45 /* The time struct to update. */ 46 struct pt_time time; 47 48 /* The test fixture initialization and finalization functions. */ 49 struct ptunit_result (*init)(struct time_fixture *); 50 struct ptunit_result (*fini)(struct time_fixture *); 51 }; 52 53 static struct ptunit_result tfix_init(struct time_fixture *tfix) 54 { 55 memset(&tfix->config, 0, sizeof(tfix->config)); 56 tfix->config.size = sizeof(tfix->config); 57 tfix->config.cpuid_0x15_eax = 2; 58 tfix->config.cpuid_0x15_ebx = 1; 59 tfix->config.mtc_freq = 4; 60 61 pt_tcal_init(&tfix->tcal); 62 pt_tcal_set_fcr(&tfix->tcal, 0x2ull << pt_tcal_fcr_shr); 63 64 pt_time_init(&tfix->time); 65 66 return ptu_passed(); 67 } 68 69 70 static struct ptunit_result tsc_null(struct time_fixture *tfix) 71 { 72 struct pt_packet_tsc packet; 73 int errcode; 74 75 errcode = pt_time_update_tsc(NULL, &packet, &tfix->config); 76 ptu_int_eq(errcode, -pte_internal); 77 78 errcode = pt_time_update_tsc(&tfix->time, NULL, &tfix->config); 79 ptu_int_eq(errcode, -pte_internal); 80 81 return ptu_passed(); 82 } 83 84 static struct ptunit_result cbr_null(struct time_fixture *tfix) 85 { 86 struct pt_packet_cbr packet; 87 int errcode; 88 89 errcode = pt_time_update_cbr(NULL, &packet, &tfix->config); 90 ptu_int_eq(errcode, -pte_internal); 91 92 errcode = pt_time_update_cbr(&tfix->time, NULL, &tfix->config); 93 ptu_int_eq(errcode, -pte_internal); 94 95 return ptu_passed(); 96 } 97 98 static struct ptunit_result tma_null(struct time_fixture *tfix) 99 { 100 struct pt_packet_tma packet; 101 int errcode; 102 103 errcode = pt_time_update_tma(NULL, &packet, &tfix->config); 104 ptu_int_eq(errcode, -pte_internal); 105 106 errcode = pt_time_update_tma(&tfix->time, NULL, &tfix->config); 107 ptu_int_eq(errcode, -pte_internal); 108 109 errcode = pt_time_update_tma(&tfix->time, &packet, NULL); 110 ptu_int_eq(errcode, -pte_internal); 111 112 return ptu_passed(); 113 } 114 115 static struct ptunit_result mtc_null(struct time_fixture *tfix) 116 { 117 struct pt_packet_mtc packet; 118 int errcode; 119 120 errcode = pt_time_update_mtc(NULL, &packet, &tfix->config); 121 ptu_int_eq(errcode, -pte_internal); 122 123 errcode = pt_time_update_mtc(&tfix->time, NULL, &tfix->config); 124 ptu_int_eq(errcode, -pte_internal); 125 126 errcode = pt_time_update_mtc(&tfix->time, &packet, NULL); 127 ptu_int_eq(errcode, -pte_internal); 128 129 return ptu_passed(); 130 } 131 132 static struct ptunit_result cyc_null(struct time_fixture *tfix) 133 { 134 struct pt_packet_cyc packet; 135 int errcode; 136 137 errcode = pt_time_update_cyc(NULL, &packet, &tfix->config, 0ull); 138 ptu_int_eq(errcode, -pte_internal); 139 140 errcode = pt_time_update_cyc(&tfix->time, NULL, &tfix->config, 0ull); 141 ptu_int_eq(errcode, -pte_internal); 142 143 errcode = pt_time_update_cyc(&tfix->time, &packet, NULL, 0ull); 144 ptu_int_eq(errcode, -pte_internal); 145 146 return ptu_passed(); 147 } 148 149 static struct ptunit_result query_tsc_null(struct time_fixture *tfix) 150 { 151 uint64_t tsc; 152 int errcode; 153 154 errcode = pt_time_query_tsc(NULL, NULL, NULL, &tfix->time); 155 ptu_int_eq(errcode, -pte_internal); 156 157 errcode = pt_time_query_tsc(&tsc, NULL, NULL, NULL); 158 ptu_int_eq(errcode, -pte_internal); 159 160 return ptu_passed(); 161 } 162 163 static struct ptunit_result query_tsc_none(struct time_fixture *tfix) 164 { 165 uint64_t tsc; 166 int errcode; 167 168 errcode = pt_time_query_tsc(&tsc, NULL, NULL, &tfix->time); 169 ptu_int_eq(errcode, -pte_no_time); 170 171 return ptu_passed(); 172 } 173 174 static struct ptunit_result query_cbr_null(struct time_fixture *tfix) 175 { 176 uint32_t cbr; 177 int errcode; 178 179 errcode = pt_time_query_cbr(NULL, &tfix->time); 180 ptu_int_eq(errcode, -pte_internal); 181 182 errcode = pt_time_query_cbr(&cbr, NULL); 183 ptu_int_eq(errcode, -pte_internal); 184 185 return ptu_passed(); 186 } 187 188 static struct ptunit_result query_cbr_none(struct time_fixture *tfix) 189 { 190 uint32_t cbr; 191 int errcode; 192 193 errcode = pt_time_query_cbr(&cbr, &tfix->time); 194 ptu_int_eq(errcode, -pte_no_cbr); 195 196 return ptu_passed(); 197 } 198 199 static struct ptunit_result tcal_cbr_null(struct time_fixture *tfix) 200 { 201 struct pt_packet_cbr packet; 202 int errcode; 203 204 errcode = pt_tcal_update_cbr(NULL, &packet, &tfix->config); 205 ptu_int_eq(errcode, -pte_internal); 206 207 return ptu_passed(); 208 } 209 210 static struct ptunit_result tcal_mtc_null(struct time_fixture *tfix) 211 { 212 struct pt_packet_mtc packet; 213 int errcode; 214 215 errcode = pt_tcal_update_mtc(NULL, &packet, &tfix->config); 216 ptu_int_eq(errcode, -pte_internal); 217 218 errcode = pt_tcal_update_mtc(&tfix->tcal, NULL, &tfix->config); 219 ptu_int_eq(errcode, -pte_internal); 220 221 errcode = pt_tcal_update_mtc(&tfix->tcal, &packet, NULL); 222 ptu_int_eq(errcode, -pte_internal); 223 224 return ptu_passed(); 225 } 226 227 static struct ptunit_result tcal_cyc_null(struct time_fixture *tfix) 228 { 229 struct pt_packet_cyc packet; 230 int errcode; 231 232 errcode = pt_tcal_update_cyc(NULL, &packet, &tfix->config); 233 ptu_int_eq(errcode, -pte_internal); 234 235 errcode = pt_tcal_update_cyc(&tfix->tcal, NULL, &tfix->config); 236 ptu_int_eq(errcode, -pte_internal); 237 238 return ptu_passed(); 239 } 240 241 static struct ptunit_result tsc(struct time_fixture *tfix) 242 { 243 struct pt_packet_tsc packet; 244 uint64_t tsc; 245 uint32_t lost_mtc, lost_cyc; 246 int errcode; 247 248 packet.tsc = 0xdedededeull; 249 250 errcode = pt_time_update_tsc(&tfix->time, &packet, &tfix->config); 251 ptu_int_eq(errcode, 0); 252 253 errcode = pt_time_query_tsc(&tsc, &lost_mtc, &lost_cyc, &tfix->time); 254 ptu_int_eq(errcode, 0); 255 256 ptu_uint_eq(tsc, 0xdedededeull); 257 ptu_uint_eq(lost_mtc, 0); 258 ptu_uint_eq(lost_cyc, 0); 259 260 return ptu_passed(); 261 } 262 263 static struct ptunit_result cbr(struct time_fixture *tfix) 264 { 265 struct pt_packet_cbr packet; 266 uint32_t cbr; 267 int errcode; 268 269 packet.ratio = 0x38; 270 271 errcode = pt_time_update_cbr(&tfix->time, &packet, &tfix->config); 272 ptu_int_eq(errcode, 0); 273 274 errcode = pt_time_query_cbr(&cbr, &tfix->time); 275 ptu_int_eq(errcode, 0); 276 277 ptu_uint_eq(cbr, 0x38); 278 279 return ptu_passed(); 280 } 281 282 static struct ptunit_result tma(struct time_fixture *tfix) 283 { 284 struct pt_packet_tma packet; 285 int errcode; 286 287 packet.ctc = 0xdc; 288 packet.fc = 0xf; 289 290 errcode = pt_time_update_tma(&tfix->time, &packet, &tfix->config); 291 ptu_int_eq(errcode, -pte_bad_context); 292 293 return ptu_passed(); 294 } 295 296 static struct ptunit_result mtc(struct time_fixture *tfix) 297 { 298 struct pt_packet_mtc packet; 299 uint64_t tsc; 300 int errcode; 301 302 packet.ctc = 0xdc; 303 304 errcode = pt_time_update_mtc(&tfix->time, &packet, &tfix->config); 305 ptu_int_eq(errcode, 0); 306 307 errcode = pt_time_query_tsc(&tsc, NULL, NULL, &tfix->time); 308 ptu_int_eq(errcode, -pte_no_time); 309 310 return ptu_passed(); 311 } 312 313 static struct ptunit_result cyc(struct time_fixture *tfix) 314 { 315 struct pt_packet_cyc packet; 316 uint64_t fcr, tsc; 317 int errcode; 318 319 errcode = pt_tcal_fcr(&fcr, &tfix->tcal); 320 ptu_int_eq(errcode, 0); 321 322 packet.value = 0xdc; 323 324 errcode = pt_time_update_cyc(&tfix->time, &packet, &tfix->config, fcr); 325 ptu_int_eq(errcode, 0); 326 327 errcode = pt_time_query_tsc(&tsc, NULL, NULL, &tfix->time); 328 ptu_int_eq(errcode, -pte_no_time); 329 330 return ptu_passed(); 331 } 332 333 334 int main(int argc, char **argv) 335 { 336 struct ptunit_suite suite; 337 struct time_fixture tfix; 338 339 suite = ptunit_mk_suite(argc, argv); 340 341 tfix.init = tfix_init; 342 tfix.fini = NULL; 343 344 ptu_run_f(suite, tsc_null, tfix); 345 ptu_run_f(suite, cbr_null, tfix); 346 ptu_run_f(suite, tma_null, tfix); 347 ptu_run_f(suite, mtc_null, tfix); 348 ptu_run_f(suite, cyc_null, tfix); 349 350 ptu_run_f(suite, query_tsc_null, tfix); 351 ptu_run_f(suite, query_tsc_none, tfix); 352 ptu_run_f(suite, query_cbr_null, tfix); 353 ptu_run_f(suite, query_cbr_none, tfix); 354 355 ptu_run_f(suite, tcal_cbr_null, tfix); 356 ptu_run_f(suite, tcal_mtc_null, tfix); 357 ptu_run_f(suite, tcal_cyc_null, tfix); 358 359 ptu_run_f(suite, tsc, tfix); 360 ptu_run_f(suite, cbr, tfix); 361 ptu_run_f(suite, tma, tfix); 362 ptu_run_f(suite, mtc, tfix); 363 ptu_run_f(suite, cyc, tfix); 364 365 /* The bulk is covered in ptt tests. */ 366 367 return ptunit_report(&suite); 368 } 369