aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-24 10:55:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-24 10:55:54 -0400
commitc76397e9303f2c9ac3c2b9d94834ff241d2b2bd4 (patch)
tree5d8aa13edd611fc2ae29e36678b5cef02408b8d6 /arch/arc
parent860448cf76c0878b83d3cf343a0436188b396b8e (diff)
parentd8f6ad85cbb740b7e8ca5275b12838fab685540c (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.dts2
-rw-r--r--arch/arc/configs/nsimosci_defconfig19
-rw-r--r--arch/arc/include/asm/arcregs.h14
-rw-r--r--arch/arc/include/asm/bitops.h31
-rw-r--r--arch/arc/include/asm/perf_event.h70
-rw-r--r--arch/arc/kernel/perf_event.c73
-rw-r--r--arch/arc/kernel/process.c9
-rw-r--r--arch/arc/kernel/setup.c5
-rw-r--r--arch/arc/kernel/traps.c4
-rw-r--r--arch/arc/mm/init.c9
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
3CONFIG_DEFAULT_HOSTNAME="ARCLinux" 3CONFIG_DEFAULT_HOSTNAME="ARCLinux"
4# CONFIG_SWAP is not set 4# CONFIG_SWAP is not set
5CONFIG_SYSVIPC=y
6# CONFIG_CROSS_MEMORY_ATTACH is not set
7CONFIG_NO_HZ=y
5CONFIG_HIGH_RES_TIMERS=y 8CONFIG_HIGH_RES_TIMERS=y
6CONFIG_IKCONFIG=y 9CONFIG_IKCONFIG=y
7CONFIG_IKCONFIG_PROC=y 10CONFIG_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
11CONFIG_BLK_DEV_INITRD=y 14CONFIG_BLK_DEV_INITRD=y
12CONFIG_INITRAMFS_SOURCE="../arc_initramfs" 15CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
13CONFIG_KALLSYMS_ALL=y 16CONFIG_KALLSYMS_ALL=y
14CONFIG_EMBEDDED=y 17CONFIG_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
23CONFIG_ARC_PLAT_FPGA_LEGACY=y 26CONFIG_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
27CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci" 28CONFIG_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
30CONFIG_NET=y 30CONFIG_NET=y
31CONFIG_PACKET=y 31CONFIG_PACKET=y
32CONFIG_UNIX=y 32CONFIG_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
41CONFIG_NETDEVICES=y 41CONFIG_NETDEVICES=y
42# CONFIG_INPUT_MOUSEDEV_PSAUX is not set 42# CONFIG_INPUT_MOUSEDEV is not set
43CONFIG_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
47CONFIG_MOUSE_PS2_TOUCHKIT=y 49CONFIG_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
50CONFIG_SERIO_ARC_PS2=y 51CONFIG_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
53CONFIG_SERIAL_8250=y 54CONFIG_SERIAL_8250=y
54CONFIG_SERIAL_8250_CONSOLE=y 55CONFIG_SERIAL_8250_CONSOLE=y
55CONFIG_SERIAL_8250_DW=y 56CONFIG_SERIAL_8250_NR_UARTS=1
57CONFIG_SERIAL_8250_RUNTIME_UARTS=1
56CONFIG_SERIAL_OF_PLATFORM=y 58CONFIG_SERIAL_OF_PLATFORM=y
57CONFIG_SERIAL_ARC=y
58CONFIG_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
61CONFIG_FB=y 61CONFIG_FB=y
@@ -72,4 +72,3 @@ CONFIG_TMPFS=y
72CONFIG_NFS_FS=y 72CONFIG_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
75CONFIG_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 */
376static inline int 390static inline int
377__constant_test_bit(unsigned int nr, const volatile unsigned long *addr) 391test_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
383static 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 */
94static const char * const arc_pmu_ev_hw_map[] = { 87static 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[] = {
114static const unsigned arc_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { 115static 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
20struct arc_pmu { 21struct 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
29struct arc_callchain_trace {
30 int depth;
31 void *perf_stuff;
32};
33
34static 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
46void
47perf_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
57void
58perf_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
67static 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! */
29static uint64_t arc_pmu_read_counter(int idx) 70static uint64_t arc_pmu_read_counter(int idx)
30{ 71{
@@ -47,7 +88,6 @@ static uint64_t arc_pmu_read_counter(int idx)
47static void arc_perf_event_update(struct perf_event *event, 88static 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 */
96static int arc_pmu_event_init(struct perf_event *event) 140static 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
184static void arc_pmu_del(struct perf_event *event, int flags) 228static 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 */
195static int arc_pmu_add(struct perf_event *event, int flags) 237static 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
304static const struct of_device_id arc_pmu_match[] = { 345static const struct of_device_id arc_pmu_match[] = {
305 { .compatible = "snps,arc700-pmu" }, 346 { .compatible = "snps,arc700-pct" },
306 {}, 347 {},
307}; 348};
308MODULE_DEVICE_TABLE(of, arc_pmu_match); 349MODULE_DEVICE_TABLE(of, arc_pmu_match);
@@ -310,7 +351,7 @@ MODULE_DEVICE_TABLE(of, arc_pmu_match);
310 351
311static struct platform_driver arc_pmu_driver = { 352static 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
50asmlinkage void ret_from_fork(void); 50asmlinkage 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 */
83int copy_thread(unsigned long clone_flags, 86int 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
126static const struct cpuinfo_data arc_cpu_tbl[] = { 129static 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 */
44static noinline int 44static noinline int
45handle_exception(const char *str, struct pt_regs *regs, siginfo_t *info) 45unhandled_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 */
72void __init setup_arch_memory(void) 72void __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 */
134void __init mem_init(void) 136void __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}