~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arc/kernel/kgdb.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/arc/kernel/kgdb.c (Version linux-6.12-rc7) and /arch/ppc/kernel/kgdb.c (Version linux-4.4.302)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * kgdb support for ARC                           
  4  *                                                
  5  * Copyright (C) 2012 Synopsys, Inc. (www.syno    
  6  */                                               
  7                                                   
  8 #include <linux/kgdb.h>                           
  9 #include <linux/sched.h>                          
 10 #include <linux/sched/task_stack.h>               
 11 #include <asm/disasm.h>                           
 12 #include <asm/cacheflush.h>                       
 13                                                   
 14 static void to_gdb_regs(unsigned long *gdb_reg    
 15                         struct callee_regs *cr    
 16 {                                                 
 17         int regno;                                
 18                                                   
 19         for (regno = 0; regno <= 26; regno++)     
 20                 gdb_regs[_R0 + regno] = get_re    
 21                                                   
 22         for (regno = 27; regno < GDB_MAX_REGS;    
 23                 gdb_regs[regno] = 0;              
 24                                                   
 25         gdb_regs[_FP]           = kernel_regs-    
 26         gdb_regs[__SP]          = kernel_regs-    
 27         gdb_regs[_BLINK]        = kernel_regs-    
 28         gdb_regs[_RET]          = kernel_regs-    
 29         gdb_regs[_STATUS32]     = kernel_regs-    
 30         gdb_regs[_LP_COUNT]     = kernel_regs-    
 31         gdb_regs[_LP_END]       = kernel_regs-    
 32         gdb_regs[_LP_START]     = kernel_regs-    
 33         gdb_regs[_BTA]          = kernel_regs-    
 34         gdb_regs[_STOP_PC]      = kernel_regs-    
 35 }                                                 
 36                                                   
 37 static void from_gdb_regs(unsigned long *gdb_r    
 38                         struct callee_regs *cr    
 39 {                                                 
 40         int regno;                                
 41                                                   
 42         for (regno = 0; regno <= 26; regno++)     
 43                 set_reg(regno, gdb_regs[regno     
 44                                                   
 45         kernel_regs->fp         = gdb_regs[_FP    
 46         kernel_regs->sp         = gdb_regs[__S    
 47         kernel_regs->blink      = gdb_regs[_BL    
 48         kernel_regs->ret        = gdb_regs[_RE    
 49         kernel_regs->status32   = gdb_regs[_ST    
 50         kernel_regs->lp_count   = gdb_regs[_LP    
 51         kernel_regs->lp_end     = gdb_regs[_LP    
 52         kernel_regs->lp_start   = gdb_regs[_LP    
 53         kernel_regs->bta        = gdb_regs[_BT    
 54 }                                                 
 55                                                   
 56                                                   
 57 void pt_regs_to_gdb_regs(unsigned long *gdb_re    
 58 {                                                 
 59         to_gdb_regs(gdb_regs, kernel_regs, (st    
 60                 current->thread.callee_reg);      
 61 }                                                 
 62                                                   
 63 void gdb_regs_to_pt_regs(unsigned long *gdb_re    
 64 {                                                 
 65         from_gdb_regs(gdb_regs, kernel_regs, (    
 66                 current->thread.callee_reg);      
 67 }                                                 
 68                                                   
 69 void sleeping_thread_to_gdb_regs(unsigned long    
 70                                  struct task_s    
 71 {                                                 
 72         if (task)                                 
 73                 to_gdb_regs(gdb_regs, task_pt_    
 74                         (struct callee_regs *)    
 75 }                                                 
 76                                                   
 77 struct single_step_data_t {                       
 78         uint16_t opcode[2];                       
 79         unsigned long address[2];                 
 80         int is_branch;                            
 81         int armed;                                
 82 } single_step_data;                               
 83                                                   
 84 static void undo_single_step(struct pt_regs *r    
 85 {                                                 
 86         if (single_step_data.armed) {             
 87                 int i;                            
 88                                                   
 89                 for (i = 0; i < (single_step_d    
 90                         memcpy((void *) single    
 91                                 &single_step_d    
 92                                 BREAK_INSTR_SI    
 93                                                   
 94                         flush_icache_range(sin    
 95                                 single_step_da    
 96                                 BREAK_INSTR_SI    
 97                 }                                 
 98                 single_step_data.armed = 0;       
 99         }                                         
100 }                                                 
101                                                   
102 static void place_trap(unsigned long address,     
103 {                                                 
104         memcpy(save, (void *) address, BREAK_I    
105         memcpy((void *) address, &arch_kgdb_op    
106                 BREAK_INSTR_SIZE);                
107         flush_icache_range(address, address +     
108 }                                                 
109                                                   
110 static void do_single_step(struct pt_regs *reg    
111 {                                                 
112         single_step_data.is_branch = disasm_ne    
113                 regs->ret, regs, (struct calle    
114                 current->thread.callee_reg,       
115                 &single_step_data.address[0],     
116                 &single_step_data.address[1]);    
117                                                   
118         place_trap(single_step_data.address[0]    
119                                                   
120         if (single_step_data.is_branch) {         
121                 place_trap(single_step_data.ad    
122                         &single_step_data.opco    
123         }                                         
124                                                   
125         single_step_data.armed++;                 
126 }                                                 
127                                                   
128 int kgdb_arch_handle_exception(int e_vector, i    
129                                char *remcomInB    
130                                struct pt_regs     
131 {                                                 
132         unsigned long addr;                       
133         char *ptr;                                
134                                                   
135         undo_single_step(regs);                   
136                                                   
137         switch (remcomInBuffer[0]) {              
138         case 's':                                 
139         case 'c':                                 
140                 ptr = &remcomInBuffer[1];         
141                 if (kgdb_hex2long(&ptr, &addr)    
142                         regs->ret = addr;         
143                 fallthrough;                      
144                                                   
145         case 'D':                                 
146         case 'k':                                 
147                 atomic_set(&kgdb_cpu_doing_sin    
148                                                   
149                 if (remcomInBuffer[0] == 's')     
150                         do_single_step(regs);     
151                         atomic_set(&kgdb_cpu_d    
152                                    smp_process    
153                 }                                 
154                                                   
155                 return 0;                         
156         }                                         
157         return -1;                                
158 }                                                 
159                                                   
160 int kgdb_arch_init(void)                          
161 {                                                 
162         single_step_data.armed = 0;               
163         return 0;                                 
164 }                                                 
165                                                   
166 void kgdb_trap(struct pt_regs *regs)              
167 {                                                 
168         /* trap_s 3 is used for breakpoints th    
169          * instructions, while trap_s 4 is use    
170          *                                        
171          * with trap_s 3 breakpoints the origi    
172          * restored and continuation needs to     
173          * breakpoint.                            
174          *                                        
175          * with trap_s 4 (compiled) breakpoint    
176          * start after the breakpoint.            
177          */                                       
178         if (regs->ecr.param == 3)                 
179                 instruction_pointer(regs) -= B    
180                                                   
181         kgdb_handle_exception(1, SIGTRAP, 0, r    
182 }                                                 
183                                                   
184 void kgdb_arch_exit(void)                         
185 {                                                 
186 }                                                 
187                                                   
188 void kgdb_arch_set_pc(struct pt_regs *regs, un    
189 {                                                 
190         instruction_pointer(regs) = ip;           
191 }                                                 
192                                                   
193 void kgdb_call_nmi_hook(void *ignored)            
194 {                                                 
195         /* Default implementation passes get_i    
196         kgdb_nmicallback(raw_smp_processor_id(    
197 }                                                 
198                                                   
199 const struct kgdb_arch arch_kgdb_ops = {          
200         /* breakpoint instruction: TRAP_S 0x3     
201 #ifdef CONFIG_CPU_BIG_ENDIAN                      
202         .gdb_bpt_instr          = {0x78, 0x7e}    
203 #else                                             
204         .gdb_bpt_instr          = {0x7e, 0x78}    
205 #endif                                            
206 };                                                
207                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php