Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libperf: Implement riscv mmap support

riscv now supports mmaping hardware counters so add what's needed to
take advantage of that in libperf.

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Anup Patel <anup@brainfault.org>
Cc: Atish Patra <atishp@atishpatra.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Rémi Denis-Courmont <remi@remlab.net>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-doc@vger.kernel.org
Cc: linux-riscv@lists.infradead.org
Link: https://lore.kernel.org/r/20230802080328.1213905-10-alexghiti@rivosinc.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Alexandre Ghiti and committed by
Arnaldo Carvalho de Melo
159a8bb0 ff382c1c

+66
+66
tools/lib/perf/mmap.c
··· 392 392 393 393 static u64 read_timestamp(void) { return read_sysreg(cntvct_el0); } 394 394 395 + /* __riscv_xlen contains the witdh of the native base integer, here 64-bit */ 396 + #elif defined(__riscv) && __riscv_xlen == 64 397 + 398 + /* TODO: implement rv32 support */ 399 + 400 + #define CSR_CYCLE 0xc00 401 + #define CSR_TIME 0xc01 402 + 403 + #define csr_read(csr) \ 404 + ({ \ 405 + register unsigned long __v; \ 406 + __asm__ __volatile__ ("csrr %0, %1" \ 407 + : "=r" (__v) \ 408 + : "i" (csr) : ); \ 409 + __v; \ 410 + }) 411 + 412 + static unsigned long csr_read_num(int csr_num) 413 + { 414 + #define switchcase_csr_read(__csr_num, __val) {\ 415 + case __csr_num: \ 416 + __val = csr_read(__csr_num); \ 417 + break; } 418 + #define switchcase_csr_read_2(__csr_num, __val) {\ 419 + switchcase_csr_read(__csr_num + 0, __val) \ 420 + switchcase_csr_read(__csr_num + 1, __val)} 421 + #define switchcase_csr_read_4(__csr_num, __val) {\ 422 + switchcase_csr_read_2(__csr_num + 0, __val) \ 423 + switchcase_csr_read_2(__csr_num + 2, __val)} 424 + #define switchcase_csr_read_8(__csr_num, __val) {\ 425 + switchcase_csr_read_4(__csr_num + 0, __val) \ 426 + switchcase_csr_read_4(__csr_num + 4, __val)} 427 + #define switchcase_csr_read_16(__csr_num, __val) {\ 428 + switchcase_csr_read_8(__csr_num + 0, __val) \ 429 + switchcase_csr_read_8(__csr_num + 8, __val)} 430 + #define switchcase_csr_read_32(__csr_num, __val) {\ 431 + switchcase_csr_read_16(__csr_num + 0, __val) \ 432 + switchcase_csr_read_16(__csr_num + 16, __val)} 433 + 434 + unsigned long ret = 0; 435 + 436 + switch (csr_num) { 437 + switchcase_csr_read_32(CSR_CYCLE, ret) 438 + default: 439 + break; 440 + } 441 + 442 + return ret; 443 + #undef switchcase_csr_read_32 444 + #undef switchcase_csr_read_16 445 + #undef switchcase_csr_read_8 446 + #undef switchcase_csr_read_4 447 + #undef switchcase_csr_read_2 448 + #undef switchcase_csr_read 449 + } 450 + 451 + static u64 read_perf_counter(unsigned int counter) 452 + { 453 + return csr_read_num(CSR_CYCLE + counter); 454 + } 455 + 456 + static u64 read_timestamp(void) 457 + { 458 + return csr_read_num(CSR_TIME); 459 + } 460 + 395 461 #else 396 462 static u64 read_perf_counter(unsigned int counter __maybe_unused) { return 0; } 397 463 static u64 read_timestamp(void) { return 0; }