1 /* 2 * Copyright (c) 2014-2019, 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_cbr_zero(struct time_fixture *tfix) 211 { 212 struct pt_packet_cbr packet; 213 struct pt_config config; 214 int errcode; 215 216 config = tfix->config; 217 config.nom_freq = 1; 218 packet.ratio = 0; 219 220 errcode = pt_tcal_update_cbr(&tfix->tcal, &packet, &config); 221 ptu_int_eq(errcode, -pte_bad_packet); 222 223 return ptu_passed(); 224 } 225 226 static struct ptunit_result tcal_mtc_null(struct time_fixture *tfix) 227 { 228 struct pt_packet_mtc packet; 229 int errcode; 230 231 errcode = pt_tcal_update_mtc(NULL, &packet, &tfix->config); 232 ptu_int_eq(errcode, -pte_internal); 233 234 errcode = pt_tcal_update_mtc(&tfix->tcal, NULL, &tfix->config); 235 ptu_int_eq(errcode, -pte_internal); 236 237 errcode = pt_tcal_update_mtc(&tfix->tcal, &packet, NULL); 238 ptu_int_eq(errcode, -pte_internal); 239 240 return ptu_passed(); 241 } 242 243 static struct ptunit_result tcal_cyc_null(struct time_fixture *tfix) 244 { 245 struct pt_packet_cyc packet; 246 int errcode; 247 248 errcode = pt_tcal_update_cyc(NULL, &packet, &tfix->config); 249 ptu_int_eq(errcode, -pte_internal); 250 251 errcode = pt_tcal_update_cyc(&tfix->tcal, NULL, &tfix->config); 252 ptu_int_eq(errcode, -pte_internal); 253 254 return ptu_passed(); 255 } 256 257 static struct ptunit_result tsc(struct time_fixture *tfix) 258 { 259 struct pt_packet_tsc packet; 260 uint64_t tsc; 261 uint32_t lost_mtc, lost_cyc; 262 int errcode; 263 264 packet.tsc = 0xdedededeull; 265 266 errcode = pt_time_update_tsc(&tfix->time, &packet, &tfix->config); 267 ptu_int_eq(errcode, 0); 268 269 errcode = pt_time_query_tsc(&tsc, &lost_mtc, &lost_cyc, &tfix->time); 270 ptu_int_eq(errcode, 0); 271 272 ptu_uint_eq(tsc, 0xdedededeull); 273 ptu_uint_eq(lost_mtc, 0); 274 ptu_uint_eq(lost_cyc, 0); 275 276 return ptu_passed(); 277 } 278 279 static struct ptunit_result cbr(struct time_fixture *tfix) 280 { 281 struct pt_packet_cbr packet; 282 uint32_t cbr; 283 int errcode; 284 285 packet.ratio = 0x38; 286 287 errcode = pt_time_update_cbr(&tfix->time, &packet, &tfix->config); 288 ptu_int_eq(errcode, 0); 289 290 errcode = pt_time_query_cbr(&cbr, &tfix->time); 291 ptu_int_eq(errcode, 0); 292 293 ptu_uint_eq(cbr, 0x38); 294 295 return ptu_passed(); 296 } 297 298 static struct ptunit_result cbr_zero(struct time_fixture *tfix) 299 { 300 struct pt_packet_cbr packet; 301 int errcode; 302 303 packet.ratio = 0; 304 305 errcode = pt_time_update_cbr(&tfix->time, &packet, &tfix->config); 306 ptu_int_eq(errcode, -pte_bad_packet); 307 308 return ptu_passed(); 309 } 310 311 static struct ptunit_result tma(struct time_fixture *tfix) 312 { 313 struct pt_packet_tma packet; 314 int errcode; 315 316 packet.ctc = 0xdc; 317 packet.fc = 0xf; 318 319 errcode = pt_time_update_tma(&tfix->time, &packet, &tfix->config); 320 ptu_int_eq(errcode, -pte_bad_context); 321 322 return ptu_passed(); 323 } 324 325 static struct ptunit_result mtc(struct time_fixture *tfix) 326 { 327 struct pt_packet_mtc packet; 328 uint64_t tsc; 329 int errcode; 330 331 packet.ctc = 0xdc; 332 333 errcode = pt_time_update_mtc(&tfix->time, &packet, &tfix->config); 334 ptu_int_eq(errcode, 0); 335 336 errcode = pt_time_query_tsc(&tsc, NULL, NULL, &tfix->time); 337 ptu_int_eq(errcode, -pte_no_time); 338 339 return ptu_passed(); 340 } 341 342 static struct ptunit_result cyc(struct time_fixture *tfix) 343 { 344 struct pt_packet_cyc packet; 345 uint64_t fcr, tsc; 346 int errcode; 347 348 errcode = pt_tcal_fcr(&fcr, &tfix->tcal); 349 ptu_int_eq(errcode, 0); 350 351 packet.value = 0xdc; 352 353 errcode = pt_time_update_cyc(&tfix->time, &packet, &tfix->config, fcr); 354 ptu_int_eq(errcode, 0); 355 356 errcode = pt_time_query_tsc(&tsc, NULL, NULL, &tfix->time); 357 ptu_int_eq(errcode, -pte_no_time); 358 359 return ptu_passed(); 360 } 361 362 363 int main(int argc, char **argv) 364 { 365 struct ptunit_suite suite; 366 struct time_fixture tfix; 367 368 suite = ptunit_mk_suite(argc, argv); 369 370 tfix.init = tfix_init; 371 tfix.fini = NULL; 372 373 ptu_run_f(suite, tsc_null, tfix); 374 ptu_run_f(suite, cbr_null, tfix); 375 ptu_run_f(suite, tma_null, tfix); 376 ptu_run_f(suite, mtc_null, tfix); 377 ptu_run_f(suite, cyc_null, tfix); 378 379 ptu_run_f(suite, query_tsc_null, tfix); 380 ptu_run_f(suite, query_tsc_none, tfix); 381 ptu_run_f(suite, query_cbr_null, tfix); 382 ptu_run_f(suite, query_cbr_none, tfix); 383 384 ptu_run_f(suite, tcal_cbr_null, tfix); 385 ptu_run_f(suite, tcal_cbr_zero, tfix); 386 ptu_run_f(suite, tcal_mtc_null, tfix); 387 ptu_run_f(suite, tcal_cyc_null, tfix); 388 389 ptu_run_f(suite, tsc, tfix); 390 ptu_run_f(suite, cbr, tfix); 391 ptu_run_f(suite, cbr_zero, tfix); 392 ptu_run_f(suite, tma, tfix); 393 ptu_run_f(suite, mtc, tfix); 394 ptu_run_f(suite, cyc, tfix); 395 396 /* The bulk is covered in ptt tests. */ 397 398 return ptunit_report(&suite); 399 } 400