diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-24 10:55:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-24 10:55:54 -0400 |
commit | c76397e9303f2c9ac3c2b9d94834ff241d2b2bd4 (patch) | |
tree | 5d8aa13edd611fc2ae29e36678b5cef02408b8d6 /arch/arc | |
parent | 860448cf76c0878b83d3cf343a0436188b396b8e (diff) | |
parent | d8f6ad85cbb740b7e8ca5275b12838fab685540c (diff) |
Merge tag 'arc-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
Pull ARC updates from Vineet Gupta:
- perf fixes/improvements
- misc cleanups
* tag 'arc-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
ARC: perf: don't add code for impossible case
ARC: perf: Rename DT binding to not confuse with power mgmt
ARC: perf: add user space attribution in callchains
ARC: perf: Add kernel callchain support
ARC: perf: support cache hit/miss ratio
ARC: perf: Add some comments/debug stuff
ARC: perf: make @arc_pmu static global
ARC: mem init spring cleaning - No functional changes
ARC: Fix RTT boot printing
ARC: fold __builtin_constant_p() into test_bit()
ARC: rename unhandled exception handler
ARC: cosmetic: Remove unused ECR bitfield masks
ARC: Fix WRITE_BCR
ARC: [nsimosci] Update defconfig
arc: copy_thread(): rename 'arg' argument to 'kthread_arg'
Diffstat (limited to 'arch/arc')
-rw-r--r-- | arch/arc/boot/dts/angel4.dts | 2 | ||||
-rw-r--r-- | arch/arc/configs/nsimosci_defconfig | 19 | ||||
-rw-r--r-- | arch/arc/include/asm/arcregs.h | 14 | ||||
-rw-r--r-- | arch/arc/include/asm/bitops.h | 31 | ||||
-rw-r--r-- | arch/arc/include/asm/perf_event.h | 70 | ||||
-rw-r--r-- | arch/arc/kernel/perf_event.c | 73 | ||||
-rw-r--r-- | arch/arc/kernel/process.c | 9 | ||||
-rw-r--r-- | arch/arc/kernel/setup.c | 5 | ||||
-rw-r--r-- | arch/arc/kernel/traps.c | 4 | ||||
-rw-r--r-- | arch/arc/mm/init.c | 9 |
10 files changed, 144 insertions, 92 deletions
diff --git a/arch/arc/boot/dts/angel4.dts b/arch/arc/boot/dts/angel4.dts index 757e0c62c4f9..3b076fbd8366 100644 --- a/arch/arc/boot/dts/angel4.dts +++ b/arch/arc/boot/dts/angel4.dts | |||
@@ -64,7 +64,7 @@ | |||
64 | }; | 64 | }; |
65 | 65 | ||
66 | arcpmu0: pmu { | 66 | arcpmu0: pmu { |
67 | compatible = "snps,arc700-pmu"; | 67 | compatible = "snps,arc700-pct"; |
68 | }; | 68 | }; |
69 | }; | 69 | }; |
70 | }; | 70 | }; |
diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig index 278dacf2a3f9..d2ac4e56ba1d 100644 --- a/arch/arc/configs/nsimosci_defconfig +++ b/arch/arc/configs/nsimosci_defconfig | |||
@@ -2,6 +2,9 @@ CONFIG_CROSS_COMPILE="arc-linux-uclibc-" | |||
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_DEFAULT_HOSTNAME="ARCLinux" | 3 | CONFIG_DEFAULT_HOSTNAME="ARCLinux" |
4 | # CONFIG_SWAP is not set | 4 | # CONFIG_SWAP is not set |
5 | CONFIG_SYSVIPC=y | ||
6 | # CONFIG_CROSS_MEMORY_ATTACH is not set | ||
7 | CONFIG_NO_HZ=y | ||
5 | CONFIG_HIGH_RES_TIMERS=y | 8 | CONFIG_HIGH_RES_TIMERS=y |
6 | CONFIG_IKCONFIG=y | 9 | CONFIG_IKCONFIG=y |
7 | CONFIG_IKCONFIG_PROC=y | 10 | CONFIG_IKCONFIG_PROC=y |
@@ -9,7 +12,7 @@ CONFIG_NAMESPACES=y | |||
9 | # CONFIG_UTS_NS is not set | 12 | # CONFIG_UTS_NS is not set |
10 | # CONFIG_PID_NS is not set | 13 | # CONFIG_PID_NS is not set |
11 | CONFIG_BLK_DEV_INITRD=y | 14 | CONFIG_BLK_DEV_INITRD=y |
12 | CONFIG_INITRAMFS_SOURCE="../arc_initramfs" | 15 | CONFIG_INITRAMFS_SOURCE="../arc_initramfs/" |
13 | CONFIG_KALLSYMS_ALL=y | 16 | CONFIG_KALLSYMS_ALL=y |
14 | CONFIG_EMBEDDED=y | 17 | CONFIG_EMBEDDED=y |
15 | # CONFIG_SLUB_DEBUG is not set | 18 | # CONFIG_SLUB_DEBUG is not set |
@@ -21,12 +24,9 @@ CONFIG_MODULES=y | |||
21 | # CONFIG_IOSCHED_DEADLINE is not set | 24 | # CONFIG_IOSCHED_DEADLINE is not set |
22 | # CONFIG_IOSCHED_CFQ is not set | 25 | # CONFIG_IOSCHED_CFQ is not set |
23 | CONFIG_ARC_PLAT_FPGA_LEGACY=y | 26 | CONFIG_ARC_PLAT_FPGA_LEGACY=y |
24 | # CONFIG_ARC_IDE is not set | ||
25 | # CONFIG_ARCTANGENT_EMAC is not set | ||
26 | # CONFIG_ARC_HAS_RTSC is not set | 27 | # CONFIG_ARC_HAS_RTSC is not set |
27 | CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci" | 28 | CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci" |
28 | # CONFIG_COMPACTION is not set | 29 | # CONFIG_COMPACTION is not set |
29 | # CONFIG_CROSS_MEMORY_ATTACH is not set | ||
30 | CONFIG_NET=y | 30 | CONFIG_NET=y |
31 | CONFIG_PACKET=y | 31 | CONFIG_PACKET=y |
32 | CONFIG_UNIX=y | 32 | CONFIG_UNIX=y |
@@ -39,23 +39,23 @@ CONFIG_INET=y | |||
39 | # CONFIG_FIRMWARE_IN_KERNEL is not set | 39 | # CONFIG_FIRMWARE_IN_KERNEL is not set |
40 | # CONFIG_BLK_DEV is not set | 40 | # CONFIG_BLK_DEV is not set |
41 | CONFIG_NETDEVICES=y | 41 | CONFIG_NETDEVICES=y |
42 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | 42 | # CONFIG_INPUT_MOUSEDEV is not set |
43 | CONFIG_INPUT_EVDEV=y | ||
43 | # CONFIG_MOUSE_PS2_ALPS is not set | 44 | # CONFIG_MOUSE_PS2_ALPS is not set |
44 | # CONFIG_MOUSE_PS2_LOGIPS2PP is not set | 45 | # CONFIG_MOUSE_PS2_LOGIPS2PP is not set |
45 | # CONFIG_MOUSE_PS2_SYNAPTICS is not set | 46 | # CONFIG_MOUSE_PS2_SYNAPTICS is not set |
47 | # CONFIG_MOUSE_PS2_CYPRESS is not set | ||
46 | # CONFIG_MOUSE_PS2_TRACKPOINT is not set | 48 | # CONFIG_MOUSE_PS2_TRACKPOINT is not set |
47 | CONFIG_MOUSE_PS2_TOUCHKIT=y | 49 | CONFIG_MOUSE_PS2_TOUCHKIT=y |
48 | # CONFIG_SERIO_I8042 is not set | ||
49 | # CONFIG_SERIO_SERPORT is not set | 50 | # CONFIG_SERIO_SERPORT is not set |
50 | CONFIG_SERIO_ARC_PS2=y | 51 | CONFIG_SERIO_ARC_PS2=y |
51 | # CONFIG_LEGACY_PTYS is not set | 52 | # CONFIG_LEGACY_PTYS is not set |
52 | # CONFIG_DEVKMEM is not set | 53 | # CONFIG_DEVKMEM is not set |
53 | CONFIG_SERIAL_8250=y | 54 | CONFIG_SERIAL_8250=y |
54 | CONFIG_SERIAL_8250_CONSOLE=y | 55 | CONFIG_SERIAL_8250_CONSOLE=y |
55 | CONFIG_SERIAL_8250_DW=y | 56 | CONFIG_SERIAL_8250_NR_UARTS=1 |
57 | CONFIG_SERIAL_8250_RUNTIME_UARTS=1 | ||
56 | CONFIG_SERIAL_OF_PLATFORM=y | 58 | CONFIG_SERIAL_OF_PLATFORM=y |
57 | CONFIG_SERIAL_ARC=y | ||
58 | CONFIG_SERIAL_ARC_CONSOLE=y | ||
59 | # CONFIG_HW_RANDOM is not set | 59 | # CONFIG_HW_RANDOM is not set |
60 | # CONFIG_HWMON is not set | 60 | # CONFIG_HWMON is not set |
61 | CONFIG_FB=y | 61 | CONFIG_FB=y |
@@ -72,4 +72,3 @@ CONFIG_TMPFS=y | |||
72 | CONFIG_NFS_FS=y | 72 | CONFIG_NFS_FS=y |
73 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | 73 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
74 | # CONFIG_ENABLE_MUST_CHECK is not set | 74 | # CONFIG_ENABLE_MUST_CHECK is not set |
75 | CONFIG_XZ_DEC=y | ||
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index be33db8a2ee3..e2b1b1211b0d 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #define ARC_REG_D_UNCACH_BCR 0x6A | 30 | #define ARC_REG_D_UNCACH_BCR 0x6A |
31 | #define ARC_REG_BPU_BCR 0xc0 | 31 | #define ARC_REG_BPU_BCR 0xc0 |
32 | #define ARC_REG_ISA_CFG_BCR 0xc1 | 32 | #define ARC_REG_ISA_CFG_BCR 0xc1 |
33 | #define ARC_REG_RTT_BCR 0xF2 | ||
33 | #define ARC_REG_SMART_BCR 0xFF | 34 | #define ARC_REG_SMART_BCR 0xFF |
34 | 35 | ||
35 | /* status32 Bits Positions */ | 36 | /* status32 Bits Positions */ |
@@ -50,11 +51,7 @@ | |||
50 | * [15: 8] = Exception Cause Code | 51 | * [15: 8] = Exception Cause Code |
51 | * [ 7: 0] = Exception Parameters (for certain types only) | 52 | * [ 7: 0] = Exception Parameters (for certain types only) |
52 | */ | 53 | */ |
53 | #define ECR_VEC_MASK 0xff0000 | 54 | #define ECR_V_MEM_ERR 0x01 |
54 | #define ECR_CODE_MASK 0x00ff00 | ||
55 | #define ECR_PARAM_MASK 0x0000ff | ||
56 | |||
57 | /* Exception Cause Vector Values */ | ||
58 | #define ECR_V_INSN_ERR 0x02 | 55 | #define ECR_V_INSN_ERR 0x02 |
59 | #define ECR_V_MACH_CHK 0x20 | 56 | #define ECR_V_MACH_CHK 0x20 |
60 | #define ECR_V_ITLB_MISS 0x21 | 57 | #define ECR_V_ITLB_MISS 0x21 |
@@ -62,7 +59,8 @@ | |||
62 | #define ECR_V_PROTV 0x23 | 59 | #define ECR_V_PROTV 0x23 |
63 | #define ECR_V_TRAP 0x25 | 60 | #define ECR_V_TRAP 0x25 |
64 | 61 | ||
65 | /* Protection Violation Exception Cause Code Values */ | 62 | /* DTLB Miss and Protection Violation Cause Codes */ |
63 | |||
66 | #define ECR_C_PROTV_INST_FETCH 0x00 | 64 | #define ECR_C_PROTV_INST_FETCH 0x00 |
67 | #define ECR_C_PROTV_LOAD 0x01 | 65 | #define ECR_C_PROTV_LOAD 0x01 |
68 | #define ECR_C_PROTV_STORE 0x02 | 66 | #define ECR_C_PROTV_STORE 0x02 |
@@ -173,11 +171,11 @@ | |||
173 | } \ | 171 | } \ |
174 | } | 172 | } |
175 | 173 | ||
176 | #define WRITE_BCR(reg, into) \ | 174 | #define WRITE_AUX(reg, into) \ |
177 | { \ | 175 | { \ |
178 | unsigned int tmp; \ | 176 | unsigned int tmp; \ |
179 | if (sizeof(tmp) == sizeof(into)) { \ | 177 | if (sizeof(tmp) == sizeof(into)) { \ |
180 | tmp = (*(unsigned int *)(into)); \ | 178 | tmp = (*(unsigned int *)&(into)); \ |
181 | write_aux_reg(reg, tmp); \ | 179 | write_aux_reg(reg, tmp); \ |
182 | } else { \ | 180 | } else { \ |
183 | extern void bogus_undefined(void); \ | 181 | extern void bogus_undefined(void); \ |
diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h index 1a5bf07eefe2..4051e9525939 100644 --- a/arch/arc/include/asm/bitops.h +++ b/arch/arc/include/asm/bitops.h | |||
@@ -32,6 +32,20 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *m) | |||
32 | 32 | ||
33 | m += nr >> 5; | 33 | m += nr >> 5; |
34 | 34 | ||
35 | /* | ||
36 | * ARC ISA micro-optimization: | ||
37 | * | ||
38 | * Instructions dealing with bitpos only consider lower 5 bits (0-31) | ||
39 | * e.g (x << 33) is handled like (x << 1) by ASL instruction | ||
40 | * (mem pointer still needs adjustment to point to next word) | ||
41 | * | ||
42 | * Hence the masking to clamp @nr arg can be elided in general. | ||
43 | * | ||
44 | * However if @nr is a constant (above assumed it in a register), | ||
45 | * and greater than 31, gcc can optimize away (x << 33) to 0, | ||
46 | * as overflow, given the 32-bit ISA. Thus masking needs to be done | ||
47 | * for constant @nr, but no code is generated due to const prop. | ||
48 | */ | ||
35 | if (__builtin_constant_p(nr)) | 49 | if (__builtin_constant_p(nr)) |
36 | nr &= 0x1f; | 50 | nr &= 0x1f; |
37 | 51 | ||
@@ -374,29 +388,20 @@ __test_and_change_bit(unsigned long nr, volatile unsigned long *m) | |||
374 | * This routine doesn't need to be atomic. | 388 | * This routine doesn't need to be atomic. |
375 | */ | 389 | */ |
376 | static inline int | 390 | static inline int |
377 | __constant_test_bit(unsigned int nr, const volatile unsigned long *addr) | 391 | test_bit(unsigned int nr, const volatile unsigned long *addr) |
378 | { | ||
379 | return ((1UL << (nr & 31)) & | ||
380 | (((const volatile unsigned int *)addr)[nr >> 5])) != 0; | ||
381 | } | ||
382 | |||
383 | static inline int | ||
384 | __test_bit(unsigned int nr, const volatile unsigned long *addr) | ||
385 | { | 392 | { |
386 | unsigned long mask; | 393 | unsigned long mask; |
387 | 394 | ||
388 | addr += nr >> 5; | 395 | addr += nr >> 5; |
389 | 396 | ||
390 | /* ARC700 only considers 5 bits in bit-fiddling insn */ | 397 | if (__builtin_constant_p(nr)) |
398 | nr &= 0x1f; | ||
399 | |||
391 | mask = 1 << nr; | 400 | mask = 1 << nr; |
392 | 401 | ||
393 | return ((mask & *addr) != 0); | 402 | return ((mask & *addr) != 0); |
394 | } | 403 | } |
395 | 404 | ||
396 | #define test_bit(nr, addr) (__builtin_constant_p(nr) ? \ | ||
397 | __constant_test_bit((nr), (addr)) : \ | ||
398 | __test_bit((nr), (addr))) | ||
399 | |||
400 | /* | 405 | /* |
401 | * Count the number of zeros, starting from MSB | 406 | * Count the number of zeros, starting from MSB |
402 | * Helper for fls( ) friends | 407 | * Helper for fls( ) friends |
diff --git a/arch/arc/include/asm/perf_event.h b/arch/arc/include/asm/perf_event.h index cbf755e32a03..2b8880e953a2 100644 --- a/arch/arc/include/asm/perf_event.h +++ b/arch/arc/include/asm/perf_event.h | |||
@@ -54,29 +54,13 @@ struct arc_reg_cc_build { | |||
54 | #define PERF_COUNT_ARC_BPOK (PERF_COUNT_HW_MAX + 3) | 54 | #define PERF_COUNT_ARC_BPOK (PERF_COUNT_HW_MAX + 3) |
55 | #define PERF_COUNT_ARC_EDTLB (PERF_COUNT_HW_MAX + 4) | 55 | #define PERF_COUNT_ARC_EDTLB (PERF_COUNT_HW_MAX + 4) |
56 | #define PERF_COUNT_ARC_EITLB (PERF_COUNT_HW_MAX + 5) | 56 | #define PERF_COUNT_ARC_EITLB (PERF_COUNT_HW_MAX + 5) |
57 | #define PERF_COUNT_ARC_HW_MAX (PERF_COUNT_HW_MAX + 6) | 57 | #define PERF_COUNT_ARC_LDC (PERF_COUNT_HW_MAX + 6) |
58 | #define PERF_COUNT_ARC_STC (PERF_COUNT_HW_MAX + 7) | ||
59 | |||
60 | #define PERF_COUNT_ARC_HW_MAX (PERF_COUNT_HW_MAX + 8) | ||
58 | 61 | ||
59 | /* | 62 | /* |
60 | * The "generalized" performance events seem to really be a copy | 63 | * Some ARC pct quirks: |
61 | * of the available events on x86 processors; the mapping to ARC | ||
62 | * events is not always possible 1-to-1. Fortunately, there doesn't | ||
63 | * seem to be an exact definition for these events, so we can cheat | ||
64 | * a bit where necessary. | ||
65 | * | ||
66 | * In particular, the following PERF events may behave a bit differently | ||
67 | * compared to other architectures: | ||
68 | * | ||
69 | * PERF_COUNT_HW_CPU_CYCLES | ||
70 | * Cycles not in halted state | ||
71 | * | ||
72 | * PERF_COUNT_HW_REF_CPU_CYCLES | ||
73 | * Reference cycles not in halted state, same as PERF_COUNT_HW_CPU_CYCLES | ||
74 | * for now as we don't do Dynamic Voltage/Frequency Scaling (yet) | ||
75 | * | ||
76 | * PERF_COUNT_HW_BUS_CYCLES | ||
77 | * Unclear what this means, Intel uses 0x013c, which according to | ||
78 | * their datasheet means "unhalted reference cycles". It sounds similar | ||
79 | * to PERF_COUNT_HW_REF_CPU_CYCLES, and we use the same counter for it. | ||
80 | * | 64 | * |
81 | * PERF_COUNT_HW_STALLED_CYCLES_BACKEND | 65 | * PERF_COUNT_HW_STALLED_CYCLES_BACKEND |
82 | * PERF_COUNT_HW_STALLED_CYCLES_FRONTEND | 66 | * PERF_COUNT_HW_STALLED_CYCLES_FRONTEND |
@@ -91,21 +75,38 @@ struct arc_reg_cc_build { | |||
91 | * Note that I$ cache misses aren't counted by either of the two! | 75 | * Note that I$ cache misses aren't counted by either of the two! |
92 | */ | 76 | */ |
93 | 77 | ||
78 | /* | ||
79 | * ARC PCT has hardware conditions with fixed "names" but variable "indexes" | ||
80 | * (based on a specific RTL build) | ||
81 | * Below is the static map between perf generic/arc specific event_id and | ||
82 | * h/w condition names. | ||
83 | * At the time of probe, we loop thru each index and find it's name to | ||
84 | * complete the mapping of perf event_id to h/w index as latter is needed | ||
85 | * to program the counter really | ||
86 | */ | ||
94 | static const char * const arc_pmu_ev_hw_map[] = { | 87 | static const char * const arc_pmu_ev_hw_map[] = { |
88 | /* count cycles */ | ||
95 | [PERF_COUNT_HW_CPU_CYCLES] = "crun", | 89 | [PERF_COUNT_HW_CPU_CYCLES] = "crun", |
96 | [PERF_COUNT_HW_REF_CPU_CYCLES] = "crun", | 90 | [PERF_COUNT_HW_REF_CPU_CYCLES] = "crun", |
97 | [PERF_COUNT_HW_BUS_CYCLES] = "crun", | 91 | [PERF_COUNT_HW_BUS_CYCLES] = "crun", |
98 | [PERF_COUNT_HW_INSTRUCTIONS] = "iall", | 92 | |
99 | [PERF_COUNT_HW_BRANCH_MISSES] = "bpfail", | ||
100 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmp", | ||
101 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "bflush", | 93 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "bflush", |
102 | [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "bstall", | 94 | [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "bstall", |
103 | [PERF_COUNT_ARC_DCLM] = "dclm", | 95 | |
104 | [PERF_COUNT_ARC_DCSM] = "dcsm", | 96 | /* counts condition */ |
105 | [PERF_COUNT_ARC_ICM] = "icm", | 97 | [PERF_COUNT_HW_INSTRUCTIONS] = "iall", |
106 | [PERF_COUNT_ARC_BPOK] = "bpok", | 98 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmp", |
107 | [PERF_COUNT_ARC_EDTLB] = "edtlb", | 99 | [PERF_COUNT_ARC_BPOK] = "bpok", /* NP-NT, PT-T, PNT-NT */ |
108 | [PERF_COUNT_ARC_EITLB] = "eitlb", | 100 | [PERF_COUNT_HW_BRANCH_MISSES] = "bpfail", /* NP-T, PT-NT, PNT-T */ |
101 | |||
102 | [PERF_COUNT_ARC_LDC] = "imemrdc", /* Instr: mem read cached */ | ||
103 | [PERF_COUNT_ARC_STC] = "imemwrc", /* Instr: mem write cached */ | ||
104 | |||
105 | [PERF_COUNT_ARC_DCLM] = "dclm", /* D-cache Load Miss */ | ||
106 | [PERF_COUNT_ARC_DCSM] = "dcsm", /* D-cache Store Miss */ | ||
107 | [PERF_COUNT_ARC_ICM] = "icm", /* I-cache Miss */ | ||
108 | [PERF_COUNT_ARC_EDTLB] = "edtlb", /* D-TLB Miss */ | ||
109 | [PERF_COUNT_ARC_EITLB] = "eitlb", /* I-TLB Miss */ | ||
109 | }; | 110 | }; |
110 | 111 | ||
111 | #define C(_x) PERF_COUNT_HW_CACHE_##_x | 112 | #define C(_x) PERF_COUNT_HW_CACHE_##_x |
@@ -114,11 +115,11 @@ static const char * const arc_pmu_ev_hw_map[] = { | |||
114 | static const unsigned arc_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | 115 | static const unsigned arc_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { |
115 | [C(L1D)] = { | 116 | [C(L1D)] = { |
116 | [C(OP_READ)] = { | 117 | [C(OP_READ)] = { |
117 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 118 | [C(RESULT_ACCESS)] = PERF_COUNT_ARC_LDC, |
118 | [C(RESULT_MISS)] = PERF_COUNT_ARC_DCLM, | 119 | [C(RESULT_MISS)] = PERF_COUNT_ARC_DCLM, |
119 | }, | 120 | }, |
120 | [C(OP_WRITE)] = { | 121 | [C(OP_WRITE)] = { |
121 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 122 | [C(RESULT_ACCESS)] = PERF_COUNT_ARC_STC, |
122 | [C(RESULT_MISS)] = PERF_COUNT_ARC_DCSM, | 123 | [C(RESULT_MISS)] = PERF_COUNT_ARC_DCSM, |
123 | }, | 124 | }, |
124 | [C(OP_PREFETCH)] = { | 125 | [C(OP_PREFETCH)] = { |
@@ -128,7 +129,7 @@ static const unsigned arc_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | |||
128 | }, | 129 | }, |
129 | [C(L1I)] = { | 130 | [C(L1I)] = { |
130 | [C(OP_READ)] = { | 131 | [C(OP_READ)] = { |
131 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 132 | [C(RESULT_ACCESS)] = PERF_COUNT_HW_INSTRUCTIONS, |
132 | [C(RESULT_MISS)] = PERF_COUNT_ARC_ICM, | 133 | [C(RESULT_MISS)] = PERF_COUNT_ARC_ICM, |
133 | }, | 134 | }, |
134 | [C(OP_WRITE)] = { | 135 | [C(OP_WRITE)] = { |
@@ -156,9 +157,10 @@ static const unsigned arc_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | |||
156 | }, | 157 | }, |
157 | [C(DTLB)] = { | 158 | [C(DTLB)] = { |
158 | [C(OP_READ)] = { | 159 | [C(OP_READ)] = { |
159 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 160 | [C(RESULT_ACCESS)] = PERF_COUNT_ARC_LDC, |
160 | [C(RESULT_MISS)] = PERF_COUNT_ARC_EDTLB, | 161 | [C(RESULT_MISS)] = PERF_COUNT_ARC_EDTLB, |
161 | }, | 162 | }, |
163 | /* DTLB LD/ST Miss not segregated by h/w*/ | ||
162 | [C(OP_WRITE)] = { | 164 | [C(OP_WRITE)] = { |
163 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 165 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
164 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | 166 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, |
diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c index ae1c485cbc68..fd2ec50102f2 100644 --- a/arch/arc/kernel/perf_event.c +++ b/arch/arc/kernel/perf_event.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/perf_event.h> | 16 | #include <linux/perf_event.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <asm/arcregs.h> | 18 | #include <asm/arcregs.h> |
19 | #include <asm/stacktrace.h> | ||
19 | 20 | ||
20 | struct arc_pmu { | 21 | struct arc_pmu { |
21 | struct pmu pmu; | 22 | struct pmu pmu; |
@@ -25,6 +26,46 @@ struct arc_pmu { | |||
25 | int ev_hw_idx[PERF_COUNT_ARC_HW_MAX]; | 26 | int ev_hw_idx[PERF_COUNT_ARC_HW_MAX]; |
26 | }; | 27 | }; |
27 | 28 | ||
29 | struct arc_callchain_trace { | ||
30 | int depth; | ||
31 | void *perf_stuff; | ||
32 | }; | ||
33 | |||
34 | static int callchain_trace(unsigned int addr, void *data) | ||
35 | { | ||
36 | struct arc_callchain_trace *ctrl = data; | ||
37 | struct perf_callchain_entry *entry = ctrl->perf_stuff; | ||
38 | perf_callchain_store(entry, addr); | ||
39 | |||
40 | if (ctrl->depth++ < 3) | ||
41 | return 0; | ||
42 | |||
43 | return -1; | ||
44 | } | ||
45 | |||
46 | void | ||
47 | perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) | ||
48 | { | ||
49 | struct arc_callchain_trace ctrl = { | ||
50 | .depth = 0, | ||
51 | .perf_stuff = entry, | ||
52 | }; | ||
53 | |||
54 | arc_unwind_core(NULL, regs, callchain_trace, &ctrl); | ||
55 | } | ||
56 | |||
57 | void | ||
58 | perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) | ||
59 | { | ||
60 | /* | ||
61 | * User stack can't be unwound trivially with kernel dwarf unwinder | ||
62 | * So for now just record the user PC | ||
63 | */ | ||
64 | perf_callchain_store(entry, instruction_pointer(regs)); | ||
65 | } | ||
66 | |||
67 | static struct arc_pmu *arc_pmu; | ||
68 | |||
28 | /* read counter #idx; note that counter# != event# on ARC! */ | 69 | /* read counter #idx; note that counter# != event# on ARC! */ |
29 | static uint64_t arc_pmu_read_counter(int idx) | 70 | static uint64_t arc_pmu_read_counter(int idx) |
30 | { | 71 | { |
@@ -47,7 +88,6 @@ static uint64_t arc_pmu_read_counter(int idx) | |||
47 | static void arc_perf_event_update(struct perf_event *event, | 88 | static void arc_perf_event_update(struct perf_event *event, |
48 | struct hw_perf_event *hwc, int idx) | 89 | struct hw_perf_event *hwc, int idx) |
49 | { | 90 | { |
50 | struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu); | ||
51 | uint64_t prev_raw_count, new_raw_count; | 91 | uint64_t prev_raw_count, new_raw_count; |
52 | int64_t delta; | 92 | int64_t delta; |
53 | 93 | ||
@@ -89,13 +129,16 @@ static int arc_pmu_cache_event(u64 config) | |||
89 | if (ret == CACHE_OP_UNSUPPORTED) | 129 | if (ret == CACHE_OP_UNSUPPORTED) |
90 | return -ENOENT; | 130 | return -ENOENT; |
91 | 131 | ||
132 | pr_debug("init cache event: type/op/result %d/%d/%d with h/w %d \'%s\'\n", | ||
133 | cache_type, cache_op, cache_result, ret, | ||
134 | arc_pmu_ev_hw_map[ret]); | ||
135 | |||
92 | return ret; | 136 | return ret; |
93 | } | 137 | } |
94 | 138 | ||
95 | /* initializes hw_perf_event structure if event is supported */ | 139 | /* initializes hw_perf_event structure if event is supported */ |
96 | static int arc_pmu_event_init(struct perf_event *event) | 140 | static int arc_pmu_event_init(struct perf_event *event) |
97 | { | 141 | { |
98 | struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu); | ||
99 | struct hw_perf_event *hwc = &event->hw; | 142 | struct hw_perf_event *hwc = &event->hw; |
100 | int ret; | 143 | int ret; |
101 | 144 | ||
@@ -106,8 +149,9 @@ static int arc_pmu_event_init(struct perf_event *event) | |||
106 | if (arc_pmu->ev_hw_idx[event->attr.config] < 0) | 149 | if (arc_pmu->ev_hw_idx[event->attr.config] < 0) |
107 | return -ENOENT; | 150 | return -ENOENT; |
108 | hwc->config = arc_pmu->ev_hw_idx[event->attr.config]; | 151 | hwc->config = arc_pmu->ev_hw_idx[event->attr.config]; |
109 | pr_debug("initializing event %d with cfg %d\n", | 152 | pr_debug("init event %d with h/w %d \'%s\'\n", |
110 | (int) event->attr.config, (int) hwc->config); | 153 | (int) event->attr.config, (int) hwc->config, |
154 | arc_pmu_ev_hw_map[event->attr.config]); | ||
111 | return 0; | 155 | return 0; |
112 | case PERF_TYPE_HW_CACHE: | 156 | case PERF_TYPE_HW_CACHE: |
113 | ret = arc_pmu_cache_event(event->attr.config); | 157 | ret = arc_pmu_cache_event(event->attr.config); |
@@ -183,8 +227,6 @@ static void arc_pmu_stop(struct perf_event *event, int flags) | |||
183 | 227 | ||
184 | static void arc_pmu_del(struct perf_event *event, int flags) | 228 | static void arc_pmu_del(struct perf_event *event, int flags) |
185 | { | 229 | { |
186 | struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu); | ||
187 | |||
188 | arc_pmu_stop(event, PERF_EF_UPDATE); | 230 | arc_pmu_stop(event, PERF_EF_UPDATE); |
189 | __clear_bit(event->hw.idx, arc_pmu->used_mask); | 231 | __clear_bit(event->hw.idx, arc_pmu->used_mask); |
190 | 232 | ||
@@ -194,7 +236,6 @@ static void arc_pmu_del(struct perf_event *event, int flags) | |||
194 | /* allocate hardware counter and optionally start counting */ | 236 | /* allocate hardware counter and optionally start counting */ |
195 | static int arc_pmu_add(struct perf_event *event, int flags) | 237 | static int arc_pmu_add(struct perf_event *event, int flags) |
196 | { | 238 | { |
197 | struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu); | ||
198 | struct hw_perf_event *hwc = &event->hw; | 239 | struct hw_perf_event *hwc = &event->hw; |
199 | int idx = hwc->idx; | 240 | int idx = hwc->idx; |
200 | 241 | ||
@@ -247,10 +288,7 @@ static int arc_pmu_device_probe(struct platform_device *pdev) | |||
247 | BUG_ON(pct_bcr.c > ARC_PMU_MAX_HWEVENTS); | 288 | BUG_ON(pct_bcr.c > ARC_PMU_MAX_HWEVENTS); |
248 | 289 | ||
249 | READ_BCR(ARC_REG_CC_BUILD, cc_bcr); | 290 | READ_BCR(ARC_REG_CC_BUILD, cc_bcr); |
250 | if (!cc_bcr.v) { | 291 | BUG_ON(!cc_bcr.v); /* Counters exist but No countable conditions ? */ |
251 | pr_err("Performance counters exist, but no countable conditions?\n"); | ||
252 | return -ENODEV; | ||
253 | } | ||
254 | 292 | ||
255 | arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), GFP_KERNEL); | 293 | arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), GFP_KERNEL); |
256 | if (!arc_pmu) | 294 | if (!arc_pmu) |
@@ -263,19 +301,22 @@ static int arc_pmu_device_probe(struct platform_device *pdev) | |||
263 | arc_pmu->n_counters, arc_pmu->counter_size, cc_bcr.c); | 301 | arc_pmu->n_counters, arc_pmu->counter_size, cc_bcr.c); |
264 | 302 | ||
265 | cc_name.str[8] = 0; | 303 | cc_name.str[8] = 0; |
266 | for (i = 0; i < PERF_COUNT_HW_MAX; i++) | 304 | for (i = 0; i < PERF_COUNT_ARC_HW_MAX; i++) |
267 | arc_pmu->ev_hw_idx[i] = -1; | 305 | arc_pmu->ev_hw_idx[i] = -1; |
268 | 306 | ||
307 | /* loop thru all available h/w condition indexes */ | ||
269 | for (j = 0; j < cc_bcr.c; j++) { | 308 | for (j = 0; j < cc_bcr.c; j++) { |
270 | write_aux_reg(ARC_REG_CC_INDEX, j); | 309 | write_aux_reg(ARC_REG_CC_INDEX, j); |
271 | cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0); | 310 | cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0); |
272 | cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1); | 311 | cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1); |
312 | |||
313 | /* See if it has been mapped to a perf event_id */ | ||
273 | for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) { | 314 | for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) { |
274 | if (arc_pmu_ev_hw_map[i] && | 315 | if (arc_pmu_ev_hw_map[i] && |
275 | !strcmp(arc_pmu_ev_hw_map[i], cc_name.str) && | 316 | !strcmp(arc_pmu_ev_hw_map[i], cc_name.str) && |
276 | strlen(arc_pmu_ev_hw_map[i])) { | 317 | strlen(arc_pmu_ev_hw_map[i])) { |
277 | pr_debug("mapping %d to idx %d with name %s\n", | 318 | pr_debug("mapping perf event %2d to h/w event \'%8s\' (idx %d)\n", |
278 | i, j, cc_name.str); | 319 | i, cc_name.str, j); |
279 | arc_pmu->ev_hw_idx[i] = j; | 320 | arc_pmu->ev_hw_idx[i] = j; |
280 | } | 321 | } |
281 | } | 322 | } |
@@ -302,7 +343,7 @@ static int arc_pmu_device_probe(struct platform_device *pdev) | |||
302 | 343 | ||
303 | #ifdef CONFIG_OF | 344 | #ifdef CONFIG_OF |
304 | static const struct of_device_id arc_pmu_match[] = { | 345 | static const struct of_device_id arc_pmu_match[] = { |
305 | { .compatible = "snps,arc700-pmu" }, | 346 | { .compatible = "snps,arc700-pct" }, |
306 | {}, | 347 | {}, |
307 | }; | 348 | }; |
308 | MODULE_DEVICE_TABLE(of, arc_pmu_match); | 349 | MODULE_DEVICE_TABLE(of, arc_pmu_match); |
@@ -310,7 +351,7 @@ MODULE_DEVICE_TABLE(of, arc_pmu_match); | |||
310 | 351 | ||
311 | static struct platform_driver arc_pmu_driver = { | 352 | static struct platform_driver arc_pmu_driver = { |
312 | .driver = { | 353 | .driver = { |
313 | .name = "arc700-pmu", | 354 | .name = "arc700-pct", |
314 | .of_match_table = of_match_ptr(arc_pmu_match), | 355 | .of_match_table = of_match_ptr(arc_pmu_match), |
315 | }, | 356 | }, |
316 | .probe = arc_pmu_device_probe, | 357 | .probe = arc_pmu_device_probe, |
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index f46efd14059d..e095c557afdd 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c | |||
@@ -49,7 +49,10 @@ void arch_cpu_idle(void) | |||
49 | 49 | ||
50 | asmlinkage void ret_from_fork(void); | 50 | asmlinkage void ret_from_fork(void); |
51 | 51 | ||
52 | /* Layout of Child kernel mode stack as setup at the end of this function is | 52 | /* |
53 | * Copy architecture-specific thread state | ||
54 | * | ||
55 | * Layout of Child kernel mode stack as setup at the end of this function is | ||
53 | * | 56 | * |
54 | * | ... | | 57 | * | ... | |
55 | * | ... | | 58 | * | ... | |
@@ -81,7 +84,7 @@ asmlinkage void ret_from_fork(void); | |||
81 | * ------------------ <===== END of PAGE | 84 | * ------------------ <===== END of PAGE |
82 | */ | 85 | */ |
83 | int copy_thread(unsigned long clone_flags, | 86 | int copy_thread(unsigned long clone_flags, |
84 | unsigned long usp, unsigned long arg, | 87 | unsigned long usp, unsigned long kthread_arg, |
85 | struct task_struct *p) | 88 | struct task_struct *p) |
86 | { | 89 | { |
87 | struct pt_regs *c_regs; /* child's pt_regs */ | 90 | struct pt_regs *c_regs; /* child's pt_regs */ |
@@ -112,7 +115,7 @@ int copy_thread(unsigned long clone_flags, | |||
112 | if (unlikely(p->flags & PF_KTHREAD)) { | 115 | if (unlikely(p->flags & PF_KTHREAD)) { |
113 | memset(c_regs, 0, sizeof(struct pt_regs)); | 116 | memset(c_regs, 0, sizeof(struct pt_regs)); |
114 | 117 | ||
115 | c_callee->r13 = arg; /* argument to kernel thread */ | 118 | c_callee->r13 = kthread_arg; |
116 | c_callee->r14 = usp; /* function */ | 119 | c_callee->r14 = usp; /* function */ |
117 | 120 | ||
118 | return 0; | 121 | return 0; |
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 900f68a70088..1d167c6df8ca 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c | |||
@@ -120,7 +120,10 @@ static void read_arc_build_cfg_regs(void) | |||
120 | READ_BCR(ARC_REG_SMART_BCR, bcr); | 120 | READ_BCR(ARC_REG_SMART_BCR, bcr); |
121 | cpu->extn.smart = bcr.ver ? 1 : 0; | 121 | cpu->extn.smart = bcr.ver ? 1 : 0; |
122 | 122 | ||
123 | cpu->extn.debug = cpu->extn.ap | cpu->extn.smart; | 123 | READ_BCR(ARC_REG_RTT_BCR, bcr); |
124 | cpu->extn.rtt = bcr.ver ? 1 : 0; | ||
125 | |||
126 | cpu->extn.debug = cpu->extn.ap | cpu->extn.smart | cpu->extn.rtt; | ||
124 | } | 127 | } |
125 | 128 | ||
126 | static const struct cpuinfo_data arc_cpu_tbl[] = { | 129 | static const struct cpuinfo_data arc_cpu_tbl[] = { |
diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c index 3eadfdabc322..c927aa84e652 100644 --- a/arch/arc/kernel/traps.c +++ b/arch/arc/kernel/traps.c | |||
@@ -42,7 +42,7 @@ void die(const char *str, struct pt_regs *regs, unsigned long address) | |||
42 | * -for kernel, chk if due to copy_(to|from)_user, otherwise die() | 42 | * -for kernel, chk if due to copy_(to|from)_user, otherwise die() |
43 | */ | 43 | */ |
44 | static noinline int | 44 | static noinline int |
45 | handle_exception(const char *str, struct pt_regs *regs, siginfo_t *info) | 45 | unhandled_exception(const char *str, struct pt_regs *regs, siginfo_t *info) |
46 | { | 46 | { |
47 | if (user_mode(regs)) { | 47 | if (user_mode(regs)) { |
48 | struct task_struct *tsk = current; | 48 | struct task_struct *tsk = current; |
@@ -71,7 +71,7 @@ int name(unsigned long address, struct pt_regs *regs) \ | |||
71 | .si_code = sicode, \ | 71 | .si_code = sicode, \ |
72 | .si_addr = (void __user *)address, \ | 72 | .si_addr = (void __user *)address, \ |
73 | }; \ | 73 | }; \ |
74 | return handle_exception(str, regs, &info);\ | 74 | return unhandled_exception(str, regs, &info);\ |
75 | } | 75 | } |
76 | 76 | ||
77 | /* | 77 | /* |
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c index 523412369f70..d44eedd8c322 100644 --- a/arch/arc/mm/init.c +++ b/arch/arc/mm/init.c | |||
@@ -71,7 +71,7 @@ early_param("initrd", early_initrd); | |||
71 | */ | 71 | */ |
72 | void __init setup_arch_memory(void) | 72 | void __init setup_arch_memory(void) |
73 | { | 73 | { |
74 | unsigned long zones_size[MAX_NR_ZONES] = { 0, 0 }; | 74 | unsigned long zones_size[MAX_NR_ZONES]; |
75 | unsigned long end_mem = CONFIG_LINUX_LINK_BASE + arc_mem_sz; | 75 | unsigned long end_mem = CONFIG_LINUX_LINK_BASE + arc_mem_sz; |
76 | 76 | ||
77 | init_mm.start_code = (unsigned long)_text; | 77 | init_mm.start_code = (unsigned long)_text; |
@@ -90,7 +90,7 @@ void __init setup_arch_memory(void) | |||
90 | /*------------- externs in mm need setting up ---------------*/ | 90 | /*------------- externs in mm need setting up ---------------*/ |
91 | 91 | ||
92 | /* first page of system - kernel .vector starts here */ | 92 | /* first page of system - kernel .vector starts here */ |
93 | min_low_pfn = PFN_DOWN(CONFIG_LINUX_LINK_BASE); | 93 | min_low_pfn = ARCH_PFN_OFFSET; |
94 | 94 | ||
95 | /* Last usable page of low mem (no HIGHMEM yet for ARC port) */ | 95 | /* Last usable page of low mem (no HIGHMEM yet for ARC port) */ |
96 | max_low_pfn = max_pfn = PFN_DOWN(end_mem); | 96 | max_low_pfn = max_pfn = PFN_DOWN(end_mem); |
@@ -111,7 +111,7 @@ void __init setup_arch_memory(void) | |||
111 | 111 | ||
112 | /*-------------- node setup --------------------------------*/ | 112 | /*-------------- node setup --------------------------------*/ |
113 | memset(zones_size, 0, sizeof(zones_size)); | 113 | memset(zones_size, 0, sizeof(zones_size)); |
114 | zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn; | 114 | zones_size[ZONE_NORMAL] = max_mapnr; |
115 | 115 | ||
116 | /* | 116 | /* |
117 | * We can't use the helper free_area_init(zones[]) because it uses | 117 | * We can't use the helper free_area_init(zones[]) because it uses |
@@ -123,6 +123,8 @@ void __init setup_arch_memory(void) | |||
123 | zones_size, /* num pages per zone */ | 123 | zones_size, /* num pages per zone */ |
124 | min_low_pfn, /* first pfn of node */ | 124 | min_low_pfn, /* first pfn of node */ |
125 | NULL); /* NO holes */ | 125 | NULL); /* NO holes */ |
126 | |||
127 | high_memory = (void *)end_mem; | ||
126 | } | 128 | } |
127 | 129 | ||
128 | /* | 130 | /* |
@@ -133,7 +135,6 @@ void __init setup_arch_memory(void) | |||
133 | */ | 135 | */ |
134 | void __init mem_init(void) | 136 | void __init mem_init(void) |
135 | { | 137 | { |
136 | high_memory = (void *)(CONFIG_LINUX_LINK_BASE + arc_mem_sz); | ||
137 | free_all_bootmem(); | 138 | free_all_bootmem(); |
138 | mem_init_print_info(NULL); | 139 | mem_init_print_info(NULL); |
139 | } | 140 | } |