import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / mt_dbg.c
1 #include <linux/device.h>
2 #include <linux/module.h>
3 #include <linux/uaccess.h>
4 #ifdef CONFIG_SMP
5 #include <mach/hotplug.h>
6 #include <linux/cpu.h>
7 #endif
8
9 #define UNLOCK_KEY 0xC5ACCE55
10 #define HDBGEN (1 << 14)
11 #define MDBGEN (1 << 15)
12 #define DBGLAR 0xF0170FB0
13 #define DBGOSLAR 0xF0170300
14 #define DBGDSCR 0xF0170088
15 #define DBGWVR_BASE 0xF0170180
16 #define DBGWCR_BASE 0xF01701C0
17 #define DBGBVR_BASE 0xF0170100
18 #define DBGBCR_BASE 0xF0170140
19
20 #define DBGWFAR 0xF0170018
21 #define MAX_NR_WATCH_POINT 4
22 #define MAX_NR_BREAK_POINT 6
23 extern void save_dbg_regs(unsigned int data[]);
24 extern void restore_dbg_regs(unsigned int data[]);
25
26 void save_dbg_regs(unsigned int data[])
27 {
28 register unsigned int cpu_id;
29 int i;
30 __asm__ __volatile__ ("MRC p15, 0, %0, c0, c0, 5" :"=r"(cpu_id) );
31 cpu_id &= 0xf;
32
33 data[0] = *(volatile unsigned int *)(DBGDSCR + cpu_id * 0x2000);
34 for(i = 0; i < MAX_NR_WATCH_POINT; i++) {
35 data[i*2+1] = *(((volatile unsigned int *)(DBGWVR_BASE + cpu_id * 0x2000)) + i);
36 data[i*2+2] = *(((volatile unsigned int *)(DBGWCR_BASE + cpu_id * 0x2000)) + i);
37 }
38
39 for(i = 0; i < MAX_NR_BREAK_POINT; i++) {
40 data[i*2+9] = *(((volatile unsigned int *)(DBGBVR_BASE + cpu_id * 0x2000)) + i);
41 data[i*2+10] = *(((volatile unsigned int *)(DBGBCR_BASE+ cpu_id * 0x2000)) + i);
42 }
43 }
44
45 void restore_dbg_regs(unsigned int data[])
46 {
47 register unsigned int cpu_id;
48 int i;
49 __asm__ __volatile__ ("MRC p15, 0, %0, c0, c0, 5" :"=r"(cpu_id) );
50 cpu_id &= 0xf;
51
52 *(volatile unsigned int *)(DBGLAR + cpu_id * 0x2000) = UNLOCK_KEY;
53 *(volatile unsigned int *)(DBGOSLAR + cpu_id * 0x2000) = ~UNLOCK_KEY;
54 *(volatile unsigned int *)(DBGDSCR + cpu_id * 0x2000) = data[0];
55
56 for(i = 0; i < MAX_NR_WATCH_POINT; i++) {
57 *(((volatile unsigned int *)(DBGWVR_BASE + cpu_id * 0x2000)) + i) = data[i*2+1];
58 *(((volatile unsigned int *)(DBGWCR_BASE + cpu_id * 0x2000)) + i) = data[i*2+2];
59 }
60
61 for(i = 0; i < MAX_NR_BREAK_POINT; i++) {
62 *(((volatile unsigned int *)(DBGBVR_BASE + cpu_id * 0x2000)) + i) = data[i*2+9];
63 *(((volatile unsigned int *)(DBGBCR_BASE + cpu_id * 0x2000)) + i) = data[i*2+10];
64 }
65 }
66
67 #ifdef CONFIG_SMP
68 static int __cpuinit
69 regs_hotplug_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
70 {
71 // printk(KERN_ALERT "In hotplug callback\n");
72 int i;
73 unsigned int cpu = (unsigned int) hcpu;
74 printk("regs_hotplug_callback cpu = %d\n", cpu);
75 switch (action) {
76 case CPU_ONLINE:
77 case CPU_ONLINE_FROZEN:
78
79 *(volatile unsigned int *)(DBGLAR + cpu *0x2000) = UNLOCK_KEY;
80 *(volatile unsigned int *)(DBGOSLAR + cpu * 0x2000) = ~UNLOCK_KEY;
81 *(volatile unsigned int *)(DBGDSCR + cpu * 0x2000) |= *(volatile unsigned int *)(DBGDSCR);
82
83 for(i = 0; i < MAX_NR_WATCH_POINT; i++) {
84 *(((volatile unsigned int *)(DBGWVR_BASE + cpu * 0x2000)) + i) = *(((volatile unsigned int *)DBGWVR_BASE) + i);
85 *(((volatile unsigned int *)(DBGWCR_BASE + cpu * 0x2000)) + i) = *(((volatile unsigned int *)DBGWCR_BASE) + i);
86 }
87
88 for(i = 0; i < MAX_NR_BREAK_POINT; i++) {
89 *(((volatile unsigned int *)(DBGBVR_BASE + cpu * 0x2000)) + i) = *(((volatile unsigned int *)DBGBVR_BASE) + i);
90 *(((volatile unsigned int *)(DBGBCR_BASE + cpu * 0x2000)) + i) = *(((volatile unsigned int *)DBGBCR_BASE) + i);
91 }
92
93 break;
94
95 default:
96 break;
97 }
98
99 return NOTIFY_OK;
100 }
101
102 static struct notifier_block __cpuinitdata cpu_nfb = {
103 .notifier_call = regs_hotplug_callback
104 };
105
106 static int __init regs_backup(void)
107 {
108
109 register_cpu_notifier(&cpu_nfb);
110
111 return 0;
112 }
113
114 module_init(regs_backup);
115 #endif
116
117
118