Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751760AbaBLIqk (ORCPT ); Wed, 12 Feb 2014 03:46:40 -0500 Received: from mail-vb0-f49.google.com ([209.85.212.49]:47084 "EHLO mail-vb0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751119AbaBLIqj (ORCPT ); Wed, 12 Feb 2014 03:46:39 -0500 MIME-Version: 1.0 In-Reply-To: <1391451427-31221-1-git-send-email-jean.pihet@linaro.org> References: <1391451427-31221-1-git-send-email-jean.pihet@linaro.org> Date: Wed, 12 Feb 2014 09:46:38 +0100 Message-ID: Subject: Re: [PATCH] perf: ARM64: wire up perf_regs and unwind support From: Jean Pihet To: "linux-kernel@vger.kernel.org" , "linaro-kernel@lists.linaro.org" , "linux-arm-kernel@lists.infradead.org" , Arnaldo , Ingo Molnar , Jiri Olsa , Will Deacon Cc: Patch Tracking , Jean Pihet Content-Type: text/plain; charset=ISO-8859-1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Arnaldo, Will, Ping on this patch. Regards, Jean On 3 February 2014 19:17, Jean Pihet wrote: > This patch hooks in the perf_regs and libunwind code for ARM64. > The tools/perf/arch/arm64 is created; it contains the arch specific > code for DWARF unwinding. > > Signed-off-by: Jean Pihet > Acked-by: Will Deacon > --- > tools/perf/arch/arm64/Makefile | 7 +++ > tools/perf/arch/arm64/include/perf_regs.h | 88 +++++++++++++++++++++++++++++++ > tools/perf/arch/arm64/util/dwarf-regs.c | 80 ++++++++++++++++++++++++++++ > tools/perf/arch/arm64/util/unwind.c | 82 ++++++++++++++++++++++++++++ > tools/perf/config/Makefile | 8 ++- > 5 files changed, 264 insertions(+), 1 deletion(-) > create mode 100644 tools/perf/arch/arm64/Makefile > create mode 100644 tools/perf/arch/arm64/include/perf_regs.h > create mode 100644 tools/perf/arch/arm64/util/dwarf-regs.c > create mode 100644 tools/perf/arch/arm64/util/unwind.c > > diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile > new file mode 100644 > index 0000000..fe9b61e > --- /dev/null > +++ b/tools/perf/arch/arm64/Makefile > @@ -0,0 +1,7 @@ > +ifndef NO_DWARF > +PERF_HAVE_DWARF_REGS := 1 > +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o > +endif > +ifndef NO_LIBUNWIND > +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind.o > +endif > diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h > new file mode 100644 > index 0000000..2359546 > --- /dev/null > +++ b/tools/perf/arch/arm64/include/perf_regs.h > @@ -0,0 +1,88 @@ > +#ifndef ARCH_PERF_REGS_H > +#define ARCH_PERF_REGS_H > + > +#include > +#include "../../util/types.h" > +#include > + > +#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM64_MAX) - 1) > +#define PERF_REG_IP PERF_REG_ARM64_PC > +#define PERF_REG_SP PERF_REG_ARM64_SP > + > +static inline const char *perf_reg_name(int id) > +{ > + switch (id) { > + case PERF_REG_ARM64_X0: > + return "x0"; > + case PERF_REG_ARM64_X1: > + return "x1"; > + case PERF_REG_ARM64_X2: > + return "x2"; > + case PERF_REG_ARM64_X3: > + return "x3"; > + case PERF_REG_ARM64_X4: > + return "x4"; > + case PERF_REG_ARM64_X5: > + return "x5"; > + case PERF_REG_ARM64_X6: > + return "x6"; > + case PERF_REG_ARM64_X7: > + return "x7"; > + case PERF_REG_ARM64_X8: > + return "x8"; > + case PERF_REG_ARM64_X9: > + return "x9"; > + case PERF_REG_ARM64_X10: > + return "x10"; > + case PERF_REG_ARM64_X11: > + return "x11"; > + case PERF_REG_ARM64_X12: > + return "x12"; > + case PERF_REG_ARM64_X13: > + return "x13"; > + case PERF_REG_ARM64_X14: > + return "x14"; > + case PERF_REG_ARM64_X15: > + return "x15"; > + case PERF_REG_ARM64_X16: > + return "x16"; > + case PERF_REG_ARM64_X17: > + return "x17"; > + case PERF_REG_ARM64_X18: > + return "x18"; > + case PERF_REG_ARM64_X19: > + return "x19"; > + case PERF_REG_ARM64_X20: > + return "x20"; > + case PERF_REG_ARM64_X21: > + return "x21"; > + case PERF_REG_ARM64_X22: > + return "x22"; > + case PERF_REG_ARM64_X23: > + return "x23"; > + case PERF_REG_ARM64_X24: > + return "x24"; > + case PERF_REG_ARM64_X25: > + return "x25"; > + case PERF_REG_ARM64_X26: > + return "x26"; > + case PERF_REG_ARM64_X27: > + return "x27"; > + case PERF_REG_ARM64_X28: > + return "x28"; > + case PERF_REG_ARM64_X29: > + return "x29"; > + case PERF_REG_ARM64_SP: > + return "sp"; > + case PERF_REG_ARM64_LR: > + return "lr"; > + case PERF_REG_ARM64_PC: > + return "pc"; > + default: > + return NULL; > + } > + > + return NULL; > +} > + > +#endif /* ARCH_PERF_REGS_H */ > diff --git a/tools/perf/arch/arm64/util/dwarf-regs.c b/tools/perf/arch/arm64/util/dwarf-regs.c > new file mode 100644 > index 0000000..d49efeb > --- /dev/null > +++ b/tools/perf/arch/arm64/util/dwarf-regs.c > @@ -0,0 +1,80 @@ > +/* > + * Mapping of DWARF debug register numbers into register names. > + * > + * Copyright (C) 2010 Will Deacon, ARM Ltd. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > + > +#include > +#include > + > +struct pt_regs_dwarfnum { > + const char *name; > + unsigned int dwarfnum; > +}; > + > +#define STR(s) #s > +#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num} > +#define GPR_DWARFNUM_NAME(num) \ > + {.name = STR(%x##num), .dwarfnum = num} > +#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0} > + > +/* > + * Reference: > + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0057b/IHI0057B_aadwarf64.pdf > + */ > +static const struct pt_regs_dwarfnum regdwarfnum_table[] = { > + GPR_DWARFNUM_NAME(0), > + GPR_DWARFNUM_NAME(1), > + GPR_DWARFNUM_NAME(2), > + GPR_DWARFNUM_NAME(3), > + GPR_DWARFNUM_NAME(4), > + GPR_DWARFNUM_NAME(5), > + GPR_DWARFNUM_NAME(6), > + GPR_DWARFNUM_NAME(7), > + GPR_DWARFNUM_NAME(8), > + GPR_DWARFNUM_NAME(9), > + GPR_DWARFNUM_NAME(10), > + GPR_DWARFNUM_NAME(11), > + GPR_DWARFNUM_NAME(12), > + GPR_DWARFNUM_NAME(13), > + GPR_DWARFNUM_NAME(14), > + GPR_DWARFNUM_NAME(15), > + GPR_DWARFNUM_NAME(16), > + GPR_DWARFNUM_NAME(17), > + GPR_DWARFNUM_NAME(18), > + GPR_DWARFNUM_NAME(19), > + GPR_DWARFNUM_NAME(20), > + GPR_DWARFNUM_NAME(21), > + GPR_DWARFNUM_NAME(22), > + GPR_DWARFNUM_NAME(23), > + GPR_DWARFNUM_NAME(24), > + GPR_DWARFNUM_NAME(25), > + GPR_DWARFNUM_NAME(26), > + GPR_DWARFNUM_NAME(27), > + GPR_DWARFNUM_NAME(28), > + GPR_DWARFNUM_NAME(29), > + REG_DWARFNUM_NAME("%lr", 30), > + REG_DWARFNUM_NAME("%sp", 31), > + REG_DWARFNUM_END, > +}; > + > +/** > + * get_arch_regstr() - lookup register name from it's DWARF register number > + * @n: the DWARF register number > + * > + * get_arch_regstr() returns the name of the register in struct > + * regdwarfnum_table from it's DWARF register number. If the register is not > + * found in the table, this returns NULL; > + */ > +const char *get_arch_regstr(unsigned int n) > +{ > + const struct pt_regs_dwarfnum *roff; > + for (roff = regdwarfnum_table; roff->name != NULL; roff++) > + if (roff->dwarfnum == n) > + return roff->name; > + return NULL; > +} > diff --git a/tools/perf/arch/arm64/util/unwind.c b/tools/perf/arch/arm64/util/unwind.c > new file mode 100644 > index 0000000..8d37a4c > --- /dev/null > +++ b/tools/perf/arch/arm64/util/unwind.c > @@ -0,0 +1,82 @@ > + > +#include > +#include > +#include "perf_regs.h" > +#include "../../util/unwind.h" > + > +int unwind__arch_reg_id(int regnum) > +{ > + switch (regnum) { > + case UNW_AARCH64_X0: > + return PERF_REG_ARM64_X0; > + case UNW_AARCH64_X1: > + return PERF_REG_ARM64_X1; > + case UNW_AARCH64_X2: > + return PERF_REG_ARM64_X2; > + case UNW_AARCH64_X3: > + return PERF_REG_ARM64_X3; > + case UNW_AARCH64_X4: > + return PERF_REG_ARM64_X4; > + case UNW_AARCH64_X5: > + return PERF_REG_ARM64_X5; > + case UNW_AARCH64_X6: > + return PERF_REG_ARM64_X6; > + case UNW_AARCH64_X7: > + return PERF_REG_ARM64_X7; > + case UNW_AARCH64_X8: > + return PERF_REG_ARM64_X8; > + case UNW_AARCH64_X9: > + return PERF_REG_ARM64_X9; > + case UNW_AARCH64_X10: > + return PERF_REG_ARM64_X10; > + case UNW_AARCH64_X11: > + return PERF_REG_ARM64_X11; > + case UNW_AARCH64_X12: > + return PERF_REG_ARM64_X12; > + case UNW_AARCH64_X13: > + return PERF_REG_ARM64_X13; > + case UNW_AARCH64_X14: > + return PERF_REG_ARM64_X14; > + case UNW_AARCH64_X15: > + return PERF_REG_ARM64_X15; > + case UNW_AARCH64_X16: > + return PERF_REG_ARM64_X16; > + case UNW_AARCH64_X17: > + return PERF_REG_ARM64_X17; > + case UNW_AARCH64_X18: > + return PERF_REG_ARM64_X18; > + case UNW_AARCH64_X19: > + return PERF_REG_ARM64_X19; > + case UNW_AARCH64_X20: > + return PERF_REG_ARM64_X20; > + case UNW_AARCH64_X21: > + return PERF_REG_ARM64_X21; > + case UNW_AARCH64_X22: > + return PERF_REG_ARM64_X22; > + case UNW_AARCH64_X23: > + return PERF_REG_ARM64_X23; > + case UNW_AARCH64_X24: > + return PERF_REG_ARM64_X24; > + case UNW_AARCH64_X25: > + return PERF_REG_ARM64_X25; > + case UNW_AARCH64_X26: > + return PERF_REG_ARM64_X26; > + case UNW_AARCH64_X27: > + return PERF_REG_ARM64_X27; > + case UNW_AARCH64_X28: > + return PERF_REG_ARM64_X28; > + case UNW_AARCH64_X29: > + return PERF_REG_ARM64_X29; > + case UNW_AARCH64_X30: > + return PERF_REG_ARM64_LR; > + case UNW_AARCH64_SP: > + return PERF_REG_ARM64_SP; > + case UNW_AARCH64_PC: > + return PERF_REG_ARM64_PC; > + default: > + pr_err("unwind: invalid reg id %d\n", regnum); > + return -EINVAL; > + } > + > + return -EINVAL; > +} > diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile > index c48d449..5c0a6ed 100644 > --- a/tools/perf/config/Makefile > +++ b/tools/perf/config/Makefile > @@ -29,11 +29,17 @@ ifeq ($(ARCH),x86) > endif > NO_PERF_REGS := 0 > endif > + > ifeq ($(ARCH),arm) > NO_PERF_REGS := 0 > LIBUNWIND_LIBS = -lunwind -lunwind-arm > endif > > +ifeq ($(ARCH),arm64) > + NO_PERF_REGS := 0 > + LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 > +endif > + > ifeq ($(LIBUNWIND_LIBS),) > NO_LIBUNWIND := 1 > else > @@ -327,7 +333,7 @@ ifndef NO_LIBUNWIND > msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1); > NO_LIBUNWIND := 1 > else > - ifeq ($(ARCH),arm) > + ifeq ($(ARCH),$(filter $(ARCH),arm arm64)) > $(call feature_check,libunwind-debug-frame) > ifneq ($(feature-libunwind-debug-frame), 1) > msg := $(warning No debug_frame support found in libunwind); > -- > 1.7.11.7 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/