1 #include <linux/device.h>
2 #include <linux/module.h>
3 #include <linux/uaccess.h>
5 #include <mach/hotplug.h>
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
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
[]);
26 void save_dbg_regs(unsigned int data
[])
28 register unsigned int cpu_id
;
30 __asm__
__volatile__ ("MRC p15, 0, %0, c0, c0, 5" :"=r"(cpu_id
) );
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
);
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
);
45 void restore_dbg_regs(unsigned int data
[])
47 register unsigned int cpu_id
;
49 __asm__
__volatile__ ("MRC p15, 0, %0, c0, c0, 5" :"=r"(cpu_id
) );
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];
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];
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];
69 regs_hotplug_callback(struct notifier_block
*nfb
, unsigned long action
, void *hcpu
)
71 // printk(KERN_ALERT "In hotplug callback\n");
73 unsigned int cpu
= (unsigned int) hcpu
;
74 printk("regs_hotplug_callback cpu = %d\n", cpu
);
77 case CPU_ONLINE_FROZEN
:
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
);
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
);
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
);
102 static struct notifier_block __cpuinitdata cpu_nfb
= {
103 .notifier_call
= regs_hotplug_callback
106 static int __init
regs_backup(void)
109 register_cpu_notifier(&cpu_nfb
);
114 module_init(regs_backup
);