Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-2.6-mn10300

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-2.6-mn10300:
MN10300: gcc 4.6 vs am33 inline assembly
MN10300: Deprecate gdbstub
MN10300: Allow KGDB to use the MN10300 serial ports
MN10300: Emulate single stepping in KGDB on MN10300
MN10300: Generalise kernel debugger kernel halt, reboot or power off hook
KGDB: Notify GDB of machine halt, reboot or power off
MN10300: Use KGDB
MN10300: Create generic kernel debugger hooks
MN10300: Create general kernel debugger cache flushing
MN10300: Introduce a general config option for kernel debugger hooks
MN10300: The icache invalidate functions should disable the icache first
MN10300: gdbstub: Restrict single-stepping to non-preemptable non-SMP configs

+1919 -497
+6 -4
arch/mn10300/Kconfig
··· 3 3 select HAVE_OPROFILE 4 4 select HAVE_GENERIC_HARDIRQS 5 5 select GENERIC_HARDIRQS_NO_DEPRECATED 6 + select HAVE_ARCH_TRACEHOOK 7 + select HAVE_ARCH_KGDB 6 8 7 9 config AM33_2 8 10 def_bool n ··· 403 401 comment "____Non-maskable interrupt levels____" 404 402 comment "The following must be set to a higher priority than local_irq_disable() and on-chip serial" 405 403 406 - config GDBSTUB_IRQ_LEVEL 407 - int "GDBSTUB interrupt priority" 408 - depends on GDBSTUB 404 + config DEBUGGER_IRQ_LEVEL 405 + int "DEBUGGER interrupt priority" 406 + depends on KERNEL_DEBUGGER 409 407 range 0 1 if LINUX_CLI_LEVEL = 2 410 408 range 0 2 if LINUX_CLI_LEVEL = 3 411 409 range 0 3 if LINUX_CLI_LEVEL = 4 ··· 439 437 EPSW.IM from 7. Any interrupt is permitted for which the level is 440 438 lower than EPSW.IM. 441 439 442 - Certain interrupts, such as GDBSTUB and virtual MN10300 on-chip 440 + Certain interrupts, such as DEBUGGER and virtual MN10300 on-chip 443 441 serial DMA interrupts are allowed to interrupt normal disabled 444 442 sections. 445 443
+16 -1
arch/mn10300/Kconfig.debug
··· 36 36 37 37 config GDBSTUB 38 38 bool "Remote GDB kernel debugging" 39 - depends on DEBUG_KERNEL 39 + depends on DEBUG_KERNEL && DEPRECATED 40 40 select DEBUG_INFO 41 41 select FRAME_POINTER 42 42 help ··· 46 46 RAM to avoid excessive linking time. This is only useful for kernel 47 47 hackers. If unsure, say N. 48 48 49 + This is deprecated in favour of KGDB and will be removed in a later 50 + version. 51 + 49 52 config GDBSTUB_IMMEDIATE 50 53 bool "Break into GDB stub immediately" 51 54 depends on GDBSTUB ··· 56 53 If you say Y here, GDB stub will break into the program as soon as 57 54 possible, leaving the program counter at the beginning of 58 55 start_kernel() in init/main.c. 56 + 57 + config GDBSTUB_ALLOW_SINGLE_STEP 58 + bool "Allow software single-stepping in GDB stub" 59 + depends on GDBSTUB && !SMP && !PREEMPT 60 + help 61 + Allow GDB stub to perform software single-stepping through the 62 + kernel. This doesn't work very well on SMP or preemptible kernels as 63 + it uses temporary breakpoints to emulate single-stepping. 59 64 60 65 config GDB_CONSOLE 61 66 bool "Console output to GDB" ··· 153 142 default y 154 143 155 144 endmenu 145 + 146 + config KERNEL_DEBUGGER 147 + def_bool y 148 + depends on GDBSTUB || KGDB
+43
arch/mn10300/include/asm/debugger.h
··· 1 + /* Kernel debugger for MN10300 2 + * 3 + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #ifndef _ASM_DEBUGGER_H 13 + #define _ASM_DEBUGGER_H 14 + 15 + #if defined(CONFIG_KERNEL_DEBUGGER) 16 + 17 + extern int debugger_intercept(enum exception_code, int, int, struct pt_regs *); 18 + extern int at_debugger_breakpoint(struct pt_regs *); 19 + 20 + #ifndef CONFIG_MN10300_DEBUGGER_CACHE_NO_FLUSH 21 + extern void debugger_local_cache_flushinv(void); 22 + extern void debugger_local_cache_flushinv_one(u8 *); 23 + #else 24 + static inline void debugger_local_cache_flushinv(void) {} 25 + static inline void debugger_local_cache_flushinv_one(u8 *addr) {} 26 + #endif 27 + 28 + #else /* CONFIG_KERNEL_DEBUGGER */ 29 + 30 + static inline int debugger_intercept(enum exception_code excep, 31 + int signo, int si_code, 32 + struct pt_regs *regs) 33 + { 34 + return 0; 35 + } 36 + 37 + static inline int at_debugger_breakpoint(struct pt_regs *regs) 38 + { 39 + return 0; 40 + } 41 + 42 + #endif /* CONFIG_KERNEL_DEBUGGER */ 43 + #endif /* _ASM_DEBUGGER_H */
+17 -4
arch/mn10300/include/asm/div64.h
··· 16 16 extern void ____unhandled_size_in_do_div___(void); 17 17 18 18 /* 19 + * Beginning with gcc 4.6, the MDR register is represented explicitly. We 20 + * must, therefore, at least explicitly clobber the register when we make 21 + * changes to it. The following assembly fragments *could* be rearranged in 22 + * order to leave the moves to/from the MDR register to the compiler, but the 23 + * gains would be minimal at best. 24 + */ 25 + #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 26 + # define CLOBBER_MDR_CC "mdr", "cc" 27 + #else 28 + # define CLOBBER_MDR_CC "cc" 29 + #endif 30 + 31 + /* 19 32 * divide n by base, leaving the result in n and returning the remainder 20 33 * - we can do this quite efficiently on the MN10300 by cascading the divides 21 34 * through the MDR register ··· 42 29 "mov mdr,%1 \n" \ 43 30 : "+r"(n), "=d"(__rem) \ 44 31 : "r"(base), "1"(__rem) \ 45 - : "cc" \ 32 + : CLOBBER_MDR_CC \ 46 33 ); \ 47 34 } else if (sizeof(n) <= 8) { \ 48 35 union { \ ··· 61 48 : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \ 62 49 : "r"(base), "0"(__rem), "1"(__quot.w[1]), \ 63 50 "2"(__quot.w[0]) \ 64 - : "cc" \ 51 + : CLOBBER_MDR_CC \ 65 52 ); \ 66 53 n = __quot.l; \ 67 54 } else { \ ··· 85 72 * MDR = MDR:val%div */ 86 73 : "=r"(result) 87 74 : "0"(val), "ir"(mult), "r"(div) 88 - : "cc" 75 + : CLOBBER_MDR_CC 89 76 ); 90 77 91 78 return result; ··· 106 93 * MDR = MDR:val%div */ 107 94 : "=r"(result) 108 95 : "0"(val), "ir"(mult), "r"(div) 109 - : "cc" 96 + : CLOBBER_MDR_CC 110 97 ); 111 98 112 99 return result;
-2
arch/mn10300/include/asm/fpu.h
··· 55 55 56 56 extern asmlinkage void fpu_kill_state(struct task_struct *); 57 57 extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code); 58 - extern asmlinkage void fpu_invalid_op(struct pt_regs *, enum exception_code); 59 58 extern asmlinkage void fpu_init_state(void); 60 59 extern asmlinkage void fpu_save(struct fpu_state_struct *); 61 60 extern int fpu_setup_sigcontext(struct fpucontext *buf); ··· 112 113 113 114 extern asmlinkage 114 115 void unexpected_fpu_exception(struct pt_regs *, enum exception_code); 115 - #define fpu_invalid_op unexpected_fpu_exception 116 116 #define fpu_exception unexpected_fpu_exception 117 117 118 118 struct task_struct;
+1 -1
arch/mn10300/include/asm/irqflags.h
··· 20 20 /* 21 21 * interrupt control 22 22 * - "disabled": run in IM1/2 23 - * - level 0 - GDB stub 23 + * - level 0 - kernel debugger 24 24 * - level 1 - virtual serial DMA (if present) 25 25 * - level 5 - normal interrupt priority 26 26 * - level 6 - timer interrupt
+81
arch/mn10300/include/asm/kgdb.h
··· 1 + /* Kernel debugger for MN10300 2 + * 3 + * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #ifndef _ASM_KGDB_H 13 + #define _ASM_KGDB_H 14 + 15 + /* 16 + * BUFMAX defines the maximum number of characters in inbound/outbound 17 + * buffers at least NUMREGBYTES*2 are needed for register packets 18 + * Longer buffer is needed to list all threads 19 + */ 20 + #define BUFMAX 1024 21 + 22 + /* 23 + * Note that this register image is in a different order than the register 24 + * image that Linux produces at interrupt time. 25 + */ 26 + enum regnames { 27 + GDB_FR_D0 = 0, 28 + GDB_FR_D1 = 1, 29 + GDB_FR_D2 = 2, 30 + GDB_FR_D3 = 3, 31 + GDB_FR_A0 = 4, 32 + GDB_FR_A1 = 5, 33 + GDB_FR_A2 = 6, 34 + GDB_FR_A3 = 7, 35 + 36 + GDB_FR_SP = 8, 37 + GDB_FR_PC = 9, 38 + GDB_FR_MDR = 10, 39 + GDB_FR_EPSW = 11, 40 + GDB_FR_LIR = 12, 41 + GDB_FR_LAR = 13, 42 + GDB_FR_MDRQ = 14, 43 + 44 + GDB_FR_E0 = 15, 45 + GDB_FR_E1 = 16, 46 + GDB_FR_E2 = 17, 47 + GDB_FR_E3 = 18, 48 + GDB_FR_E4 = 19, 49 + GDB_FR_E5 = 20, 50 + GDB_FR_E6 = 21, 51 + GDB_FR_E7 = 22, 52 + 53 + GDB_FR_SSP = 23, 54 + GDB_FR_MSP = 24, 55 + GDB_FR_USP = 25, 56 + GDB_FR_MCRH = 26, 57 + GDB_FR_MCRL = 27, 58 + GDB_FR_MCVF = 28, 59 + 60 + GDB_FR_FPCR = 29, 61 + GDB_FR_DUMMY0 = 30, 62 + GDB_FR_DUMMY1 = 31, 63 + 64 + GDB_FR_FS0 = 32, 65 + 66 + GDB_FR_SIZE = 64, 67 + }; 68 + 69 + #define GDB_ORIG_D0 41 70 + #define NUMREGBYTES (GDB_FR_SIZE*4) 71 + 72 + static inline void arch_kgdb_breakpoint(void) 73 + { 74 + asm(".globl __arch_kgdb_breakpoint; __arch_kgdb_breakpoint: break"); 75 + } 76 + extern u8 __arch_kgdb_breakpoint; 77 + 78 + #define BREAK_INSTR_SIZE 1 79 + #define CACHE_FLUSH_IS_SAFE 1 80 + 81 + #endif /* _ASM_KGDB_H */
+4 -2
arch/mn10300/include/asm/smp.h
··· 34 34 #define LOCAL_TIMER_IPI 193 35 35 #define FLUSH_CACHE_IPI 194 36 36 #define CALL_FUNCTION_NMI_IPI 195 37 - #define GDB_NMI_IPI 196 37 + #define DEBUGGER_NMI_IPI 196 38 38 39 39 #define SMP_BOOT_IRQ 195 40 40 ··· 43 43 #define LOCAL_TIMER_GxICR_LV GxICR_LEVEL_4 44 44 #define FLUSH_CACHE_GxICR_LV GxICR_LEVEL_0 45 45 #define SMP_BOOT_GxICR_LV GxICR_LEVEL_0 46 + #define DEBUGGER_GxICR_LV CONFIG_DEBUGGER_IRQ_LEVEL 46 47 47 48 #define TIME_OUT_COUNT_BOOT_IPI 100 48 49 #define DELAY_TIME_BOOT_IPI 75000 ··· 62 61 * An alternate way of dealing with this could be to use the EPSW.S bits to 63 62 * cache this information for systems with up to four CPUs. 64 63 */ 64 + #define arch_smp_processor_id() (CPUID) 65 65 #if 0 66 - #define raw_smp_processor_id() (CPUID) 66 + #define raw_smp_processor_id() (arch_smp_processor_id()) 67 67 #else 68 68 #define raw_smp_processor_id() (current_thread_info()->cpu) 69 69 #endif
+4
arch/mn10300/include/asm/thread_info.h
··· 131 131 kmalloc_node(THREAD_SIZE, GFP_KERNEL, node) 132 132 #endif 133 133 134 + #ifndef CONFIG_KGDB 134 135 #define free_thread_info(ti) kfree((ti)) 136 + #else 137 + extern void free_thread_info(struct thread_info *); 138 + #endif 135 139 #define get_thread_info(ti) get_task_struct((ti)->task) 136 140 #define put_thread_info(ti) put_task_struct((ti)->task) 137 141
+1 -4
arch/mn10300/kernel/Makefile
··· 21 21 obj-$(CONFIG_GDBSTUB_ON_TTYSx) += gdb-io-serial.o gdb-io-serial-low.o 22 22 obj-$(CONFIG_GDBSTUB_ON_TTYSMx) += gdb-io-ttysm.o gdb-io-ttysm-low.o 23 23 24 - ifeq ($(CONFIG_MN10300_CACHE_ENABLED),y) 25 - obj-$(CONFIG_GDBSTUB) += gdb-cache.o 26 - endif 27 - 28 24 obj-$(CONFIG_MN10300_RTC) += rtc.o 29 25 obj-$(CONFIG_PROFILE) += profile.o profile-low.o 30 26 obj-$(CONFIG_MODULES) += module.o 31 27 obj-$(CONFIG_KPROBES) += kprobes.o 28 + obj-$(CONFIG_KGDB) += kgdb.o
+24 -41
arch/mn10300/kernel/entry.S
··· 266 266 267 267 ############################################################################### 268 268 # 269 - # Miscellaneous exception entry points 269 + # NMI exception entry points 270 + # 271 + # This is used by ordinary interrupt channels that have the GxICR_NMI bit set 272 + # in addition to the main NMI and Watchdog channels. SMP NMI IPIs use this 273 + # facility. 270 274 # 271 275 ############################################################################### 272 276 ENTRY(nmi_handler) ··· 285 281 and NMIAGR_GN,d0 286 282 lsr 0x2,d0 287 283 cmp CALL_FUNCTION_NMI_IPI,d0 288 - bne 5f # if not call function, jump 284 + bne nmi_not_smp_callfunc # if not call function, jump 289 285 290 286 # function call nmi ipi 291 287 add 4,sp # no need to store TBR ··· 299 295 call smp_nmi_call_function_interrupt[],0 300 296 RESTORE_ALL 301 297 302 - 5: 303 - #ifdef CONFIG_GDBSTUB 304 - cmp GDB_NMI_IPI,d0 305 - bne 3f # if not gdb nmi ipi, jump 298 + nmi_not_smp_callfunc: 299 + #ifdef CONFIG_KERNEL_DEBUGGER 300 + cmp DEBUGGER_NMI_IPI,d0 301 + bne nmi_not_debugger # if not kernel debugger NMI IPI, jump 306 302 307 - # gdb nmi ipi 303 + # kernel debugger NMI IPI 308 304 add 4,sp # no need to store TBR 309 305 mov GxICR_DETECT,d0 # clear NMI 310 - movbu d0,(GxICR(GDB_NMI_IPI)) 311 - movhu (GxICR(GDB_NMI_IPI)),d0 306 + movbu d0,(GxICR(DEBUGGER_NMI_IPI)) 307 + movhu (GxICR(DEBUGGER_NMI_IPI)),d0 312 308 and ~EPSW_NMID,epsw # enable NMI 313 - #ifdef CONFIG_MN10300_CACHE_ENABLED 314 - mov (gdbstub_nmi_opr_type),d0 315 - cmp GDBSTUB_NMI_CACHE_PURGE,d0 316 - bne 4f # if not gdb cache purge, jump 317 309 318 - # gdb cache purge nmi ipi 319 - add -20,sp 320 - mov d1,(4,sp) 321 - mov a0,(8,sp) 322 - mov a1,(12,sp) 323 - mov mdr,d0 324 - mov d0,(16,sp) 325 - call gdbstub_local_purge_cache[],0 326 - mov 0x1,d0 327 - mov (CPUID),d1 328 - asl d1,d0 329 - mov gdbstub_nmi_cpumask,a0 330 - bclr d0,(a0) 331 - mov (4,sp),d1 332 - mov (8,sp),a0 333 - mov (12,sp),a1 334 - mov (16,sp),d0 335 - mov d0,mdr 336 - add 20,sp 337 - mov (sp),d0 338 - add 4,sp 339 - rti 340 - 4: 341 - #endif /* CONFIG_MN10300_CACHE_ENABLED */ 342 - # gdb wait nmi ipi 343 310 mov (sp),d0 344 311 SAVE_ALL 345 - call gdbstub_nmi_wait[],0 312 + mov fp,d0 # arg 0: stacked register file 313 + mov a2,d1 # arg 1: exception number 314 + call debugger_nmi_interrupt[],0 346 315 RESTORE_ALL 347 - 3: 348 - #endif /* CONFIG_GDBSTUB */ 316 + 317 + nmi_not_debugger: 318 + #endif /* CONFIG_KERNEL_DEBUGGER */ 349 319 mov (sp),d0 # restore TBR to d0 350 320 add 4,sp 351 321 #endif /* CONFIG_SMP */ 352 322 353 323 bra __common_exception_nonmi 354 324 325 + ############################################################################### 326 + # 327 + # General exception entry point 328 + # 329 + ############################################################################### 355 330 ENTRY(__common_exception) 356 331 add -4,sp 357 332 mov d0,(sp)
-18
arch/mn10300/kernel/fpu.c
··· 70 70 } 71 71 72 72 /* 73 - * handle an FPU invalid_op exception 74 - * - Derived from DO_EINFO() macro in arch/mn10300/kernel/traps.c 75 - */ 76 - asmlinkage void fpu_invalid_op(struct pt_regs *regs, enum exception_code code) 77 - { 78 - siginfo_t info; 79 - 80 - if (!user_mode(regs)) 81 - die_if_no_fixup("FPU invalid opcode", regs, code); 82 - 83 - info.si_signo = SIGILL; 84 - info.si_errno = 0; 85 - info.si_code = ILL_COPROC; 86 - info.si_addr = (void *) regs->pc; 87 - force_sig_info(info.si_signo, &info, current); 88 - } 89 - 90 - /* 91 73 * save the FPU state to a signal context 92 74 */ 93 75 int fpu_setup_sigcontext(struct fpucontext *fpucontext)
-105
arch/mn10300/kernel/gdb-cache.S
··· 1 - ############################################################################### 2 - # 3 - # MN10300 Low-level cache purging routines for gdbstub 4 - # 5 - # Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 6 - # Written by David Howells (dhowells@redhat.com) 7 - # 8 - # This program is free software; you can redistribute it and/or 9 - # modify it under the terms of the GNU General Public Licence 10 - # as published by the Free Software Foundation; either version 11 - # 2 of the Licence, or (at your option) any later version. 12 - # 13 - ############################################################################### 14 - #include <linux/sys.h> 15 - #include <linux/linkage.h> 16 - #include <asm/smp.h> 17 - #include <asm/cache.h> 18 - #include <asm/cpu-regs.h> 19 - #include <asm/exceptions.h> 20 - #include <asm/frame.inc> 21 - #include <asm/serial-regs.h> 22 - 23 - .text 24 - 25 - ############################################################################### 26 - # 27 - # GDB stub cache purge 28 - # 29 - ############################################################################### 30 - .type gdbstub_purge_cache,@function 31 - ENTRY(gdbstub_purge_cache) 32 - ####################################################################### 33 - # read the addresses tagged in the cache's tag RAM and attempt to flush 34 - # those addresses specifically 35 - # - we rely on the hardware to filter out invalid tag entry addresses 36 - mov DCACHE_TAG(0,0),a0 # dcache tag RAM access address 37 - mov DCACHE_PURGE(0,0),a1 # dcache purge request address 38 - mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries 39 - 40 - mn10300_dcache_flush_loop: 41 - mov (a0),d0 42 - and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 43 - or L1_CACHE_TAG_VALID,d0 # retain valid entries in the 44 - # cache 45 - mov d0,(a1) # conditional purge 46 - 47 - mn10300_dcache_flush_skip: 48 - add L1_CACHE_BYTES,a0 49 - add L1_CACHE_BYTES,a1 50 - add -1,d1 51 - bne mn10300_dcache_flush_loop 52 - 53 - ;; # unconditionally flush and invalidate the dcache 54 - ;; mov DCACHE_PURGE(0,0),a1 # dcache purge request address 55 - ;; mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of 56 - ;; # entries 57 - ;; 58 - ;; gdbstub_purge_cache__dcache_loop: 59 - ;; mov (a1),d0 # unconditional purge 60 - ;; 61 - ;; add L1_CACHE_BYTES,a1 62 - ;; add -1,d1 63 - ;; bne gdbstub_purge_cache__dcache_loop 64 - 65 - ####################################################################### 66 - # now invalidate the icache 67 - mov CHCTR,a0 68 - movhu (a0),a1 69 - 70 - mov epsw,d1 71 - and ~EPSW_IE,epsw 72 - nop 73 - nop 74 - 75 - # disable the icache 76 - and ~CHCTR_ICEN,d0 77 - movhu d0,(a0) 78 - 79 - # and wait for it to calm down 80 - setlb 81 - movhu (a0),d0 82 - btst CHCTR_ICBUSY,d0 83 - lne 84 - 85 - # invalidate 86 - or CHCTR_ICINV,d0 87 - movhu d0,(a0) 88 - 89 - # wait for the cache to finish 90 - mov CHCTR,a0 91 - setlb 92 - movhu (a0),d0 93 - btst CHCTR_ICBUSY,d0 94 - lne 95 - 96 - # and reenable it 97 - movhu a1,(a0) 98 - movhu (a0),d0 # read back to flush 99 - # (SIGILLs all over without this) 100 - 101 - mov d1,epsw 102 - 103 - ret [],0 104 - 105 - .size gdbstub_purge_cache,.-gdbstub_purge_cache
+4 -4
arch/mn10300/kernel/gdb-io-ttysm.c
··· 59 59 60 60 /* we want to get serial receive interrupts */ 61 61 set_intr_level(gdbstub_port->rx_irq, 62 - NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL)); 62 + NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL)); 63 63 set_intr_level(gdbstub_port->tx_irq, 64 - NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL)); 65 - set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL), 64 + NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL)); 65 + set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL), 66 66 gdbstub_io_rx_handler); 67 67 68 68 *gdbstub_port->rx_icr |= GxICR_ENABLE; ··· 88 88 89 89 /* permit level 0 IRQs only */ 90 90 arch_local_change_intr_mask_level( 91 - NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); 91 + NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1)); 92 92 } 93 93 94 94 /*
+29 -12
arch/mn10300/kernel/gdb-stub.c
··· 133 133 #include <asm/system.h> 134 134 #include <asm/gdb-stub.h> 135 135 #include <asm/exceptions.h> 136 - #include <asm/cacheflush.h> 136 + #include <asm/debugger.h> 137 137 #include <asm/serial-regs.h> 138 138 #include <asm/busctl-regs.h> 139 139 #include <unit/leds.h> ··· 405 405 return (numChars); 406 406 } 407 407 408 + #ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP 408 409 /* 409 410 * We single-step by setting breakpoints. When an exception 410 411 * is handled, we need to restore the instructions hoisted ··· 730 729 __gdbstub_restore_bp(); 731 730 return -EFAULT; 732 731 } 732 + #endif /* CONFIG_GDBSTUB_ALLOW_SINGLE_STEP */ 733 733 734 734 #ifdef CONFIG_GDBSTUB_CONSOLE 735 735 ··· 1173 1171 1174 1172 /* 1175 1173 * This function does all command processing for interfacing to gdb 1176 - * - returns 1 if the exception should be skipped, 0 otherwise. 1174 + * - returns 0 if the exception should be skipped, -ERROR otherwise. 1177 1175 */ 1178 1176 static int gdbstub(struct pt_regs *regs, enum exception_code excep) 1179 1177 { ··· 1188 1186 int loop; 1189 1187 1190 1188 if (excep == EXCEP_FPU_DISABLED) 1191 - return 0; 1189 + return -ENOTSUPP; 1192 1190 1193 1191 gdbstub_flush_caches = 0; 1194 1192 ··· 1197 1195 asm volatile("mov mdr,%0" : "=d"(mdr)); 1198 1196 local_save_flags(epsw); 1199 1197 arch_local_change_intr_mask_level( 1200 - NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); 1198 + NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1)); 1201 1199 1202 1200 gdbstub_store_fpu(); 1203 1201 ··· 1210 1208 /* if we were single stepping, restore the opcodes hoisted for the 1211 1209 * breakpoint[s] */ 1212 1210 broke = 0; 1211 + #ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP 1213 1212 if ((step_bp[0].addr && step_bp[0].addr == (u8 *) regs->pc) || 1214 1213 (step_bp[1].addr && step_bp[1].addr == (u8 *) regs->pc)) 1215 1214 broke = 1; 1216 1215 1217 1216 __gdbstub_restore_bp(); 1217 + #endif 1218 1218 1219 1219 if (gdbstub_rx_unget) { 1220 1220 sigval = SIGINT; ··· 1552 1548 * Step to next instruction 1553 1549 */ 1554 1550 case 's': 1555 - /* 1556 - * using the T flag doesn't seem to perform single 1551 + /* Using the T flag doesn't seem to perform single 1557 1552 * stepping (it seems to wind up being caught by the 1558 1553 * JTAG unit), so we have to use breakpoints and 1559 1554 * continue instead. 1560 1555 */ 1556 + #ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP 1561 1557 if (gdbstub_single_step(regs) < 0) 1562 1558 /* ignore any fault error for now */ 1563 1559 gdbstub_printk("unable to set single-step" 1564 1560 " bp\n"); 1565 1561 goto done; 1562 + #else 1563 + gdbstub_strcpy(output_buffer, "E01"); 1564 + break; 1565 + #endif 1566 1566 1567 1567 /* 1568 1568 * Set baud rate (bBB) ··· 1665 1657 * NB: We flush both caches, just to be sure... 1666 1658 */ 1667 1659 if (gdbstub_flush_caches) 1668 - gdbstub_purge_cache(); 1660 + debugger_local_cache_flushinv(); 1669 1661 1670 1662 gdbstub_load_fpu(); 1671 1663 mn10300_set_gdbleds(0); ··· 1675 1667 touch_softlockup_watchdog(); 1676 1668 1677 1669 local_irq_restore(epsw); 1678 - return 1; 1670 + return 0; 1671 + } 1672 + 1673 + /* 1674 + * Determine if we hit a debugger special breakpoint that needs skipping over 1675 + * automatically. 1676 + */ 1677 + int at_debugger_breakpoint(struct pt_regs *regs) 1678 + { 1679 + return 0; 1679 1680 } 1680 1681 1681 1682 /* 1682 1683 * handle event interception 1683 1684 */ 1684 - asmlinkage int gdbstub_intercept(struct pt_regs *regs, 1685 - enum exception_code excep) 1685 + asmlinkage int debugger_intercept(enum exception_code excep, 1686 + int signo, int si_code, struct pt_regs *regs) 1686 1687 { 1687 1688 static u8 notfirst = 1; 1688 1689 int ret; ··· 1705 1688 asm("mov mdr,%0" : "=d"(mdr)); 1706 1689 1707 1690 gdbstub_entry( 1708 - "--> gdbstub_intercept(%p,%04x) [MDR=%lx PC=%lx]\n", 1691 + "--> debugger_intercept(%p,%04x) [MDR=%lx PC=%lx]\n", 1709 1692 regs, excep, mdr, regs->pc); 1710 1693 1711 1694 gdbstub_entry( ··· 1739 1722 1740 1723 ret = gdbstub(regs, excep); 1741 1724 1742 - gdbstub_entry("<-- gdbstub_intercept()\n"); 1725 + gdbstub_entry("<-- debugger_intercept()\n"); 1743 1726 gdbstub_busy = 0; 1744 1727 return ret; 1745 1728 }
+7
arch/mn10300/kernel/internal.h
··· 30 30 #endif 31 31 32 32 /* 33 + * smp.c 34 + */ 35 + #ifdef CONFIG_SMP 36 + extern void smp_jump_to_debugger(void); 37 + #endif 38 + 39 + /* 33 40 * time.c 34 41 */ 35 42 extern irqreturn_t local_timer_interrupt(void);
+1 -1
arch/mn10300/kernel/irq.c
··· 153 153 case LOCAL_TIMER_IPI: 154 154 case FLUSH_CACHE_IPI: 155 155 case CALL_FUNCTION_NMI_IPI: 156 - case GDB_NMI_IPI: 156 + case DEBUGGER_NMI_IPI: 157 157 #ifdef CONFIG_MN10300_TTYSM0 158 158 case SC0RXIRQ: 159 159 case SC0TXIRQ:
+502
arch/mn10300/kernel/kgdb.c
··· 1 + /* kgdb support for MN10300 2 + * 3 + * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #include <linux/slab.h> 13 + #include <linux/ptrace.h> 14 + #include <linux/kgdb.h> 15 + #include <linux/uaccess.h> 16 + #include <unit/leds.h> 17 + #include <unit/serial.h> 18 + #include <asm/debugger.h> 19 + #include <asm/serial-regs.h> 20 + #include "internal.h" 21 + 22 + /* 23 + * Software single-stepping breakpoint save (used by __switch_to()) 24 + */ 25 + static struct thread_info *kgdb_sstep_thread; 26 + u8 *kgdb_sstep_bp_addr[2]; 27 + u8 kgdb_sstep_bp[2]; 28 + 29 + /* 30 + * Copy kernel exception frame registers to the GDB register file 31 + */ 32 + void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) 33 + { 34 + unsigned long ssp = (unsigned long) (regs + 1); 35 + 36 + gdb_regs[GDB_FR_D0] = regs->d0; 37 + gdb_regs[GDB_FR_D1] = regs->d1; 38 + gdb_regs[GDB_FR_D2] = regs->d2; 39 + gdb_regs[GDB_FR_D3] = regs->d3; 40 + gdb_regs[GDB_FR_A0] = regs->a0; 41 + gdb_regs[GDB_FR_A1] = regs->a1; 42 + gdb_regs[GDB_FR_A2] = regs->a2; 43 + gdb_regs[GDB_FR_A3] = regs->a3; 44 + gdb_regs[GDB_FR_SP] = (regs->epsw & EPSW_nSL) ? regs->sp : ssp; 45 + gdb_regs[GDB_FR_PC] = regs->pc; 46 + gdb_regs[GDB_FR_MDR] = regs->mdr; 47 + gdb_regs[GDB_FR_EPSW] = regs->epsw; 48 + gdb_regs[GDB_FR_LIR] = regs->lir; 49 + gdb_regs[GDB_FR_LAR] = regs->lar; 50 + gdb_regs[GDB_FR_MDRQ] = regs->mdrq; 51 + gdb_regs[GDB_FR_E0] = regs->e0; 52 + gdb_regs[GDB_FR_E1] = regs->e1; 53 + gdb_regs[GDB_FR_E2] = regs->e2; 54 + gdb_regs[GDB_FR_E3] = regs->e3; 55 + gdb_regs[GDB_FR_E4] = regs->e4; 56 + gdb_regs[GDB_FR_E5] = regs->e5; 57 + gdb_regs[GDB_FR_E6] = regs->e6; 58 + gdb_regs[GDB_FR_E7] = regs->e7; 59 + gdb_regs[GDB_FR_SSP] = ssp; 60 + gdb_regs[GDB_FR_MSP] = 0; 61 + gdb_regs[GDB_FR_USP] = regs->sp; 62 + gdb_regs[GDB_FR_MCRH] = regs->mcrh; 63 + gdb_regs[GDB_FR_MCRL] = regs->mcrl; 64 + gdb_regs[GDB_FR_MCVF] = regs->mcvf; 65 + gdb_regs[GDB_FR_DUMMY0] = 0; 66 + gdb_regs[GDB_FR_DUMMY1] = 0; 67 + gdb_regs[GDB_FR_FS0] = 0; 68 + } 69 + 70 + /* 71 + * Extracts kernel SP/PC values understandable by gdb from the values 72 + * saved by switch_to(). 73 + */ 74 + void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) 75 + { 76 + gdb_regs[GDB_FR_SSP] = p->thread.sp; 77 + gdb_regs[GDB_FR_PC] = p->thread.pc; 78 + gdb_regs[GDB_FR_A3] = p->thread.a3; 79 + gdb_regs[GDB_FR_USP] = p->thread.usp; 80 + gdb_regs[GDB_FR_FPCR] = p->thread.fpu_state.fpcr; 81 + } 82 + 83 + /* 84 + * Fill kernel exception frame registers from the GDB register file 85 + */ 86 + void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) 87 + { 88 + regs->d0 = gdb_regs[GDB_FR_D0]; 89 + regs->d1 = gdb_regs[GDB_FR_D1]; 90 + regs->d2 = gdb_regs[GDB_FR_D2]; 91 + regs->d3 = gdb_regs[GDB_FR_D3]; 92 + regs->a0 = gdb_regs[GDB_FR_A0]; 93 + regs->a1 = gdb_regs[GDB_FR_A1]; 94 + regs->a2 = gdb_regs[GDB_FR_A2]; 95 + regs->a3 = gdb_regs[GDB_FR_A3]; 96 + regs->sp = gdb_regs[GDB_FR_SP]; 97 + regs->pc = gdb_regs[GDB_FR_PC]; 98 + regs->mdr = gdb_regs[GDB_FR_MDR]; 99 + regs->epsw = gdb_regs[GDB_FR_EPSW]; 100 + regs->lir = gdb_regs[GDB_FR_LIR]; 101 + regs->lar = gdb_regs[GDB_FR_LAR]; 102 + regs->mdrq = gdb_regs[GDB_FR_MDRQ]; 103 + regs->e0 = gdb_regs[GDB_FR_E0]; 104 + regs->e1 = gdb_regs[GDB_FR_E1]; 105 + regs->e2 = gdb_regs[GDB_FR_E2]; 106 + regs->e3 = gdb_regs[GDB_FR_E3]; 107 + regs->e4 = gdb_regs[GDB_FR_E4]; 108 + regs->e5 = gdb_regs[GDB_FR_E5]; 109 + regs->e6 = gdb_regs[GDB_FR_E6]; 110 + regs->e7 = gdb_regs[GDB_FR_E7]; 111 + regs->sp = gdb_regs[GDB_FR_SSP]; 112 + /* gdb_regs[GDB_FR_MSP]; */ 113 + // regs->usp = gdb_regs[GDB_FR_USP]; 114 + regs->mcrh = gdb_regs[GDB_FR_MCRH]; 115 + regs->mcrl = gdb_regs[GDB_FR_MCRL]; 116 + regs->mcvf = gdb_regs[GDB_FR_MCVF]; 117 + /* gdb_regs[GDB_FR_DUMMY0]; */ 118 + /* gdb_regs[GDB_FR_DUMMY1]; */ 119 + 120 + // regs->fpcr = gdb_regs[GDB_FR_FPCR]; 121 + // regs->fs0 = gdb_regs[GDB_FR_FS0]; 122 + } 123 + 124 + struct kgdb_arch arch_kgdb_ops = { 125 + .gdb_bpt_instr = { 0xff }, 126 + .flags = KGDB_HW_BREAKPOINT, 127 + }; 128 + 129 + static const unsigned char mn10300_kgdb_insn_sizes[256] = 130 + { 131 + /* 1 2 3 4 5 6 7 8 9 a b c d e f */ 132 + 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, /* 0 */ 133 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */ 134 + 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, /* 2 */ 135 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, /* 3 */ 136 + 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, /* 4 */ 137 + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, /* 5 */ 138 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ 139 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */ 140 + 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 8 */ 141 + 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 9 */ 142 + 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* a */ 143 + 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* b */ 144 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, /* c */ 145 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */ 146 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */ 147 + 0, 2, 2, 2, 2, 2, 2, 4, 0, 3, 0, 4, 0, 6, 7, 1 /* f */ 148 + }; 149 + 150 + /* 151 + * Attempt to emulate single stepping by means of breakpoint instructions. 152 + * Although there is a single-step trace flag in EPSW, its use is not 153 + * sufficiently documented and is only intended for use with the JTAG debugger. 154 + */ 155 + static int kgdb_arch_do_singlestep(struct pt_regs *regs) 156 + { 157 + unsigned long arg; 158 + unsigned size; 159 + u8 *pc = (u8 *)regs->pc, *sp = (u8 *)(regs + 1), cur; 160 + u8 *x = NULL, *y = NULL; 161 + int ret; 162 + 163 + ret = probe_kernel_read(&cur, pc, 1); 164 + if (ret < 0) 165 + return ret; 166 + 167 + size = mn10300_kgdb_insn_sizes[cur]; 168 + if (size > 0) { 169 + x = pc + size; 170 + goto set_x; 171 + } 172 + 173 + switch (cur) { 174 + /* Bxx (d8,PC) */ 175 + case 0xc0 ... 0xca: 176 + ret = probe_kernel_read(&arg, pc + 1, 1); 177 + if (ret < 0) 178 + return ret; 179 + x = pc + 2; 180 + if (arg >= 0 && arg <= 2) 181 + goto set_x; 182 + y = pc + (s8)arg; 183 + goto set_x_and_y; 184 + 185 + /* LXX (d8,PC) */ 186 + case 0xd0 ... 0xda: 187 + x = pc + 1; 188 + if (regs->pc == regs->lar) 189 + goto set_x; 190 + y = (u8 *)regs->lar; 191 + goto set_x_and_y; 192 + 193 + /* SETLB - loads the next four bytes into the LIR register 194 + * (which mustn't include a breakpoint instruction) */ 195 + case 0xdb: 196 + x = pc + 5; 197 + goto set_x; 198 + 199 + /* JMP (d16,PC) or CALL (d16,PC) */ 200 + case 0xcc: 201 + case 0xcd: 202 + ret = probe_kernel_read(&arg, pc + 1, 2); 203 + if (ret < 0) 204 + return ret; 205 + x = pc + (s16)arg; 206 + goto set_x; 207 + 208 + /* JMP (d32,PC) or CALL (d32,PC) */ 209 + case 0xdc: 210 + case 0xdd: 211 + ret = probe_kernel_read(&arg, pc + 1, 4); 212 + if (ret < 0) 213 + return ret; 214 + x = pc + (s32)arg; 215 + goto set_x; 216 + 217 + /* RETF */ 218 + case 0xde: 219 + x = (u8 *)regs->mdr; 220 + goto set_x; 221 + 222 + /* RET */ 223 + case 0xdf: 224 + ret = probe_kernel_read(&arg, pc + 2, 1); 225 + if (ret < 0) 226 + return ret; 227 + ret = probe_kernel_read(&x, sp + (s8)arg, 4); 228 + if (ret < 0) 229 + return ret; 230 + goto set_x; 231 + 232 + case 0xf0: 233 + ret = probe_kernel_read(&cur, pc + 1, 1); 234 + if (ret < 0) 235 + return ret; 236 + 237 + if (cur >= 0xf0 && cur <= 0xf7) { 238 + /* JMP (An) / CALLS (An) */ 239 + switch (cur & 3) { 240 + case 0: x = (u8 *)regs->a0; break; 241 + case 1: x = (u8 *)regs->a1; break; 242 + case 2: x = (u8 *)regs->a2; break; 243 + case 3: x = (u8 *)regs->a3; break; 244 + } 245 + goto set_x; 246 + } else if (cur == 0xfc) { 247 + /* RETS */ 248 + ret = probe_kernel_read(&x, sp, 4); 249 + if (ret < 0) 250 + return ret; 251 + goto set_x; 252 + } else if (cur == 0xfd) { 253 + /* RTI */ 254 + ret = probe_kernel_read(&x, sp + 4, 4); 255 + if (ret < 0) 256 + return ret; 257 + goto set_x; 258 + } else { 259 + x = pc + 2; 260 + goto set_x; 261 + } 262 + break; 263 + 264 + /* potential 3-byte conditional branches */ 265 + case 0xf8: 266 + ret = probe_kernel_read(&cur, pc + 1, 1); 267 + if (ret < 0) 268 + return ret; 269 + x = pc + 3; 270 + 271 + if (cur >= 0xe8 && cur <= 0xeb) { 272 + ret = probe_kernel_read(&arg, pc + 2, 1); 273 + if (ret < 0) 274 + return ret; 275 + if (arg >= 0 && arg <= 3) 276 + goto set_x; 277 + y = pc + (s8)arg; 278 + goto set_x_and_y; 279 + } 280 + goto set_x; 281 + 282 + case 0xfa: 283 + ret = probe_kernel_read(&cur, pc + 1, 1); 284 + if (ret < 0) 285 + return ret; 286 + 287 + if (cur == 0xff) { 288 + /* CALLS (d16,PC) */ 289 + ret = probe_kernel_read(&arg, pc + 2, 2); 290 + if (ret < 0) 291 + return ret; 292 + x = pc + (s16)arg; 293 + goto set_x; 294 + } 295 + 296 + x = pc + 4; 297 + goto set_x; 298 + 299 + case 0xfc: 300 + ret = probe_kernel_read(&cur, pc + 1, 1); 301 + if (ret < 0) 302 + return ret; 303 + 304 + if (cur == 0xff) { 305 + /* CALLS (d32,PC) */ 306 + ret = probe_kernel_read(&arg, pc + 2, 4); 307 + if (ret < 0) 308 + return ret; 309 + x = pc + (s32)arg; 310 + goto set_x; 311 + } 312 + 313 + x = pc + 6; 314 + goto set_x; 315 + } 316 + 317 + return 0; 318 + 319 + set_x: 320 + kgdb_sstep_bp_addr[0] = x; 321 + kgdb_sstep_bp_addr[1] = NULL; 322 + ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1); 323 + if (ret < 0) 324 + return ret; 325 + ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1); 326 + if (ret < 0) 327 + return ret; 328 + kgdb_sstep_thread = current_thread_info(); 329 + debugger_local_cache_flushinv_one(x); 330 + return ret; 331 + 332 + set_x_and_y: 333 + kgdb_sstep_bp_addr[0] = x; 334 + kgdb_sstep_bp_addr[1] = y; 335 + ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1); 336 + if (ret < 0) 337 + return ret; 338 + ret = probe_kernel_read(&kgdb_sstep_bp[1], y, 1); 339 + if (ret < 0) 340 + return ret; 341 + ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1); 342 + if (ret < 0) 343 + return ret; 344 + ret = probe_kernel_write(y, &arch_kgdb_ops.gdb_bpt_instr, 1); 345 + if (ret < 0) { 346 + probe_kernel_write(kgdb_sstep_bp_addr[0], 347 + &kgdb_sstep_bp[0], 1); 348 + } else { 349 + kgdb_sstep_thread = current_thread_info(); 350 + } 351 + debugger_local_cache_flushinv_one(x); 352 + debugger_local_cache_flushinv_one(y); 353 + return ret; 354 + } 355 + 356 + /* 357 + * Remove emplaced single-step breakpoints, returning true if we hit one of 358 + * them. 359 + */ 360 + static bool kgdb_arch_undo_singlestep(struct pt_regs *regs) 361 + { 362 + bool hit = false; 363 + u8 *x = kgdb_sstep_bp_addr[0], *y = kgdb_sstep_bp_addr[1]; 364 + u8 opcode; 365 + 366 + if (kgdb_sstep_thread == current_thread_info()) { 367 + if (x) { 368 + if (x == (u8 *)regs->pc) 369 + hit = true; 370 + if (probe_kernel_read(&opcode, x, 371 + 1) < 0 || 372 + opcode != 0xff) 373 + BUG(); 374 + probe_kernel_write(x, &kgdb_sstep_bp[0], 1); 375 + debugger_local_cache_flushinv_one(x); 376 + } 377 + if (y) { 378 + if (y == (u8 *)regs->pc) 379 + hit = true; 380 + if (probe_kernel_read(&opcode, y, 381 + 1) < 0 || 382 + opcode != 0xff) 383 + BUG(); 384 + probe_kernel_write(y, &kgdb_sstep_bp[1], 1); 385 + debugger_local_cache_flushinv_one(y); 386 + } 387 + } 388 + 389 + kgdb_sstep_bp_addr[0] = NULL; 390 + kgdb_sstep_bp_addr[1] = NULL; 391 + kgdb_sstep_thread = NULL; 392 + return hit; 393 + } 394 + 395 + /* 396 + * Catch a single-step-pending thread being deleted and make sure the global 397 + * single-step state is cleared. At this point the breakpoints should have 398 + * been removed by __switch_to(). 399 + */ 400 + void free_thread_info(struct thread_info *ti) 401 + { 402 + if (kgdb_sstep_thread == ti) { 403 + kgdb_sstep_thread = NULL; 404 + 405 + /* However, we may now be running in degraded mode, with most 406 + * of the CPUs disabled until such a time as KGDB is reentered, 407 + * so force immediate reentry */ 408 + kgdb_breakpoint(); 409 + } 410 + kfree(ti); 411 + } 412 + 413 + /* 414 + * Handle unknown packets and [CcsDk] packets 415 + * - at this point breakpoints have been installed 416 + */ 417 + int kgdb_arch_handle_exception(int vector, int signo, int err_code, 418 + char *remcom_in_buffer, char *remcom_out_buffer, 419 + struct pt_regs *regs) 420 + { 421 + long addr; 422 + char *ptr; 423 + 424 + switch (remcom_in_buffer[0]) { 425 + case 'c': 426 + case 's': 427 + /* try to read optional parameter, pc unchanged if no parm */ 428 + ptr = &remcom_in_buffer[1]; 429 + if (kgdb_hex2long(&ptr, &addr)) 430 + regs->pc = addr; 431 + case 'D': 432 + case 'k': 433 + atomic_set(&kgdb_cpu_doing_single_step, -1); 434 + 435 + if (remcom_in_buffer[0] == 's') { 436 + kgdb_arch_do_singlestep(regs); 437 + kgdb_single_step = 1; 438 + atomic_set(&kgdb_cpu_doing_single_step, 439 + raw_smp_processor_id()); 440 + } 441 + return 0; 442 + } 443 + return -1; /* this means that we do not want to exit from the handler */ 444 + } 445 + 446 + /* 447 + * Handle event interception 448 + * - returns 0 if the exception should be skipped, -ERROR otherwise. 449 + */ 450 + int debugger_intercept(enum exception_code excep, int signo, int si_code, 451 + struct pt_regs *regs) 452 + { 453 + int ret; 454 + 455 + if (kgdb_arch_undo_singlestep(regs)) { 456 + excep = EXCEP_TRAP; 457 + signo = SIGTRAP; 458 + si_code = TRAP_TRACE; 459 + } 460 + 461 + ret = kgdb_handle_exception(excep, signo, si_code, regs); 462 + 463 + debugger_local_cache_flushinv(); 464 + 465 + return ret; 466 + } 467 + 468 + /* 469 + * Determine if we've hit a debugger special breakpoint 470 + */ 471 + int at_debugger_breakpoint(struct pt_regs *regs) 472 + { 473 + return regs->pc == (unsigned long)&__arch_kgdb_breakpoint; 474 + } 475 + 476 + /* 477 + * Initialise kgdb 478 + */ 479 + int kgdb_arch_init(void) 480 + { 481 + return 0; 482 + } 483 + 484 + /* 485 + * Do something, perhaps, but don't know what. 486 + */ 487 + void kgdb_arch_exit(void) 488 + { 489 + } 490 + 491 + #ifdef CONFIG_SMP 492 + void debugger_nmi_interrupt(struct pt_regs *regs, enum exception_code code) 493 + { 494 + kgdb_nmicallback(arch_smp_processor_id(), regs); 495 + debugger_local_cache_flushinv(); 496 + } 497 + 498 + void kgdb_roundup_cpus(unsigned long flags) 499 + { 500 + smp_jump_to_debugger(); 501 + } 502 + #endif
+75
arch/mn10300/kernel/mn10300-serial.c
··· 119 119 static void mn10300_serial_config_port(struct uart_port *, int); 120 120 static int mn10300_serial_verify_port(struct uart_port *, 121 121 struct serial_struct *); 122 + #ifdef CONFIG_CONSOLE_POLL 123 + static void mn10300_serial_poll_put_char(struct uart_port *, unsigned char); 124 + static int mn10300_serial_poll_get_char(struct uart_port *); 125 + #endif 122 126 123 127 static const struct uart_ops mn10300_serial_ops = { 124 128 .tx_empty = mn10300_serial_tx_empty, ··· 142 138 .request_port = mn10300_serial_request_port, 143 139 .config_port = mn10300_serial_config_port, 144 140 .verify_port = mn10300_serial_verify_port, 141 + #ifdef CONFIG_CONSOLE_POLL 142 + .poll_put_char = mn10300_serial_poll_put_char, 143 + .poll_get_char = mn10300_serial_poll_get_char, 144 + #endif 145 145 }; 146 146 147 147 static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id); ··· 1642 1634 1643 1635 console_initcall(mn10300_serial_console_init); 1644 1636 #endif 1637 + 1638 + #ifdef CONFIG_CONSOLE_POLL 1639 + /* 1640 + * Polled character reception for the kernel debugger 1641 + */ 1642 + static int mn10300_serial_poll_get_char(struct uart_port *_port) 1643 + { 1644 + struct mn10300_serial_port *port = 1645 + container_of(_port, struct mn10300_serial_port, uart); 1646 + unsigned ix; 1647 + u8 st, ch; 1648 + 1649 + _enter("%s", port->name); 1650 + 1651 + do { 1652 + /* pull chars out of the hat */ 1653 + ix = port->rx_outp; 1654 + if (ix == port->rx_inp) 1655 + return NO_POLL_CHAR; 1656 + 1657 + ch = port->rx_buffer[ix++]; 1658 + st = port->rx_buffer[ix++]; 1659 + smp_rmb(); 1660 + port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); 1661 + 1662 + } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF)); 1663 + 1664 + return ch; 1665 + } 1666 + 1667 + 1668 + /* 1669 + * Polled character transmission for the kernel debugger 1670 + */ 1671 + static void mn10300_serial_poll_put_char(struct uart_port *_port, 1672 + unsigned char ch) 1673 + { 1674 + struct mn10300_serial_port *port = 1675 + container_of(_port, struct mn10300_serial_port, uart); 1676 + u8 intr, tmp; 1677 + 1678 + /* wait for the transmitter to finish anything it might be doing (and 1679 + * this includes the virtual DMA handler, so it might take a while) */ 1680 + while (*port->_status & (SC01STR_TBF | SC01STR_TXF)) 1681 + continue; 1682 + 1683 + /* disable the Tx ready interrupt */ 1684 + intr = *port->_intr; 1685 + *port->_intr = intr & ~SC01ICR_TI; 1686 + tmp = *port->_intr; 1687 + 1688 + if (ch == 0x0a) { 1689 + *(u8 *) port->_txb = 0x0d; 1690 + while (*port->_status & SC01STR_TBF) 1691 + continue; 1692 + } 1693 + 1694 + *(u8 *) port->_txb = ch; 1695 + while (*port->_status & SC01STR_TBF) 1696 + continue; 1697 + 1698 + /* restore the Tx interrupt flag */ 1699 + *port->_intr = intr; 1700 + tmp = *port->_intr; 1701 + } 1702 + 1703 + #endif /* CONFIG_CONSOLE_POLL */
+3 -3
arch/mn10300/kernel/process.c
··· 135 135 136 136 void machine_restart(char *cmd) 137 137 { 138 - #ifdef CONFIG_GDBSTUB 138 + #ifdef CONFIG_KERNEL_DEBUGGER 139 139 gdbstub_exit(0); 140 140 #endif 141 141 ··· 148 148 149 149 void machine_halt(void) 150 150 { 151 - #ifdef CONFIG_GDBSTUB 151 + #ifdef CONFIG_KERNEL_DEBUGGER 152 152 gdbstub_exit(0); 153 153 #endif 154 154 } 155 155 156 156 void machine_power_off(void) 157 157 { 158 - #ifdef CONFIG_GDBSTUB 158 + #ifdef CONFIG_KERNEL_DEBUGGER 159 159 gdbstub_exit(0); 160 160 #endif 161 161 }
+21 -5
arch/mn10300/kernel/smp.c
··· 440 440 } 441 441 442 442 /** 443 + * smp_jump_to_debugger - Make other CPUs enter the debugger by sending an IPI 444 + * 445 + * Send a non-maskable request to all other CPUs in the system, instructing 446 + * them to jump into the debugger. The caller is responsible for checking that 447 + * the other CPUs responded to the instruction. 448 + * 449 + * The caller should make sure that this CPU's debugger IPI is disabled. 450 + */ 451 + void smp_jump_to_debugger(void) 452 + { 453 + if (num_online_cpus() > 1) 454 + /* Send a message to all other CPUs */ 455 + send_IPI_allbutself(DEBUGGER_NMI_IPI); 456 + } 457 + 458 + /** 443 459 * stop_this_cpu - Callback to stop a CPU. 444 460 * @unused: Callback context (ignored). 445 461 */ ··· 619 603 /** 620 604 * smp_prepare_cpu_init - Initialise CPU in startup_secondary 621 605 * 622 - * Set interrupt level 0-6 setting and init ICR of gdbstub. 606 + * Set interrupt level 0-6 setting and init ICR of the kernel debugger. 623 607 */ 624 608 void smp_prepare_cpu_init(void) 625 609 { ··· 638 622 for (loop = 0; loop < GxICR_NUM_IRQS; loop++) 639 623 GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT; 640 624 641 - #ifdef CONFIG_GDBSTUB 642 - /* initialise GDB-stub */ 625 + #ifdef CONFIG_KERNEL_DEBUGGER 626 + /* initialise the kernel debugger interrupt */ 643 627 do { 644 628 unsigned long flags; 645 629 u16 tmp16; 646 630 647 631 flags = arch_local_cli_save(); 648 - GxICR(GDB_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT; 649 - tmp16 = GxICR(GDB_NMI_IPI); 632 + GxICR(DEBUGGER_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT; 633 + tmp16 = GxICR(DEBUGGER_NMI_IPI); 650 634 arch_local_irq_restore(flags); 651 635 } while (0); 652 636 #endif
+110 -1
arch/mn10300/kernel/switch_to.S
··· 39 39 40 40 # save prev context 41 41 mov __switch_back,d0 42 - mov d0,(THREAD_PC,a0) 43 42 mov sp,a2 44 43 mov a2,(THREAD_SP,a0) 45 44 mov a3,(THREAD_A3,a0) 45 + 46 + #ifdef CONFIG_KGDB 47 + btst 0xff,(kgdb_single_step) 48 + bne __switch_to__lift_sstep_bp 49 + __switch_to__continue: 50 + #endif 51 + mov d0,(THREAD_PC,a0) 46 52 47 53 mov (THREAD_A3,a1),a3 48 54 mov (THREAD_SP,a1),a2 ··· 74 68 __switch_back: 75 69 and ~EPSW_NMID,epsw 76 70 ret [d2,d3,a2,a3,exreg1],32 71 + 72 + #ifdef CONFIG_KGDB 73 + ############################################################################### 74 + # 75 + # Lift the single-step breakpoints when the task being traced is switched out 76 + # A0 = prev 77 + # A1 = next 78 + # 79 + ############################################################################### 80 + __switch_to__lift_sstep_bp: 81 + add -12,sp 82 + mov a0,e4 83 + mov a1,e5 84 + 85 + # Clear the single-step flag to prevent us coming this way until we get 86 + # switched back in 87 + bclr 0xff,(kgdb_single_step) 88 + 89 + # Remove first breakpoint 90 + mov (kgdb_sstep_bp_addr),a2 91 + cmp 0,a2 92 + beq 1f 93 + movbu (kgdb_sstep_bp),d0 94 + movbu d0,(a2) 95 + #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE) 96 + mov a2,d0 97 + mov a2,d1 98 + add 1,d1 99 + calls flush_icache_range 100 + #endif 101 + 1: 102 + 103 + # Remove second breakpoint 104 + mov (kgdb_sstep_bp_addr+4),a2 105 + cmp 0,a2 106 + beq 2f 107 + movbu (kgdb_sstep_bp+1),d0 108 + movbu d0,(a2) 109 + #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE) 110 + mov a2,d0 111 + mov a2,d1 112 + add 1,d1 113 + calls flush_icache_range 114 + #endif 115 + 2: 116 + 117 + # Change the resumption address and return 118 + mov __switch_back__reinstall_sstep_bp,d0 119 + mov e4,a0 120 + mov e5,a1 121 + add 12,sp 122 + bra __switch_to__continue 123 + 124 + ############################################################################### 125 + # 126 + # Reinstall the single-step breakpoints when the task being traced is switched 127 + # back in (A1 points to the new thread_struct). 128 + # 129 + ############################################################################### 130 + __switch_back__reinstall_sstep_bp: 131 + add -12,sp 132 + mov a0,e4 # save the return value 133 + mov 0xff,d3 134 + 135 + # Reinstall first breakpoint 136 + mov (kgdb_sstep_bp_addr),a2 137 + cmp 0,a2 138 + beq 1f 139 + movbu (a2),d0 140 + movbu d0,(kgdb_sstep_bp) 141 + movbu d3,(a2) 142 + #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE) 143 + mov a2,d0 144 + mov a2,d1 145 + add 1,d1 146 + calls flush_icache_range 147 + #endif 148 + 1: 149 + 150 + # Reinstall second breakpoint 151 + mov (kgdb_sstep_bp_addr+4),a2 152 + cmp 0,a2 153 + beq 2f 154 + movbu (a2),d0 155 + movbu d0,(kgdb_sstep_bp+1) 156 + movbu d3,(a2) 157 + #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE) 158 + mov a2,d0 159 + mov a2,d1 160 + add 1,d1 161 + calls flush_icache_range 162 + #endif 163 + 2: 164 + 165 + mov d3,(kgdb_single_step) 166 + 167 + # Restore the return value (the previous thread_struct pointer) 168 + mov e4,a0 169 + mov a0,d0 170 + add 12,sp 171 + bra __switch_back 172 + 173 + #endif /* CONFIG_KGDB */
+214 -184
arch/mn10300/kernel/traps.c
··· 38 38 #include <asm/busctl-regs.h> 39 39 #include <unit/leds.h> 40 40 #include <asm/fpu.h> 41 - #include <asm/gdb-stub.h> 42 41 #include <asm/sections.h> 42 + #include <asm/debugger.h> 43 + #include "internal.h" 43 44 44 45 #if (CONFIG_INTERRUPT_VECTOR_BASE & 0xffffff) 45 46 #error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!" ··· 50 49 51 50 spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock); 52 51 53 - ATOMIC_NOTIFIER_HEAD(mn10300_die_chain); 52 + struct exception_to_signal_map { 53 + u8 signo; 54 + u32 si_code; 55 + }; 56 + 57 + static const struct exception_to_signal_map exception_to_signal_map[256] = { 58 + /* MMU exceptions */ 59 + [EXCEP_ITLBMISS >> 3] = { 0, 0 }, 60 + [EXCEP_DTLBMISS >> 3] = { 0, 0 }, 61 + [EXCEP_IAERROR >> 3] = { 0, 0 }, 62 + [EXCEP_DAERROR >> 3] = { 0, 0 }, 63 + 64 + /* system exceptions */ 65 + [EXCEP_TRAP >> 3] = { SIGTRAP, TRAP_BRKPT }, 66 + [EXCEP_ISTEP >> 3] = { SIGTRAP, TRAP_TRACE }, /* Monitor */ 67 + [EXCEP_IBREAK >> 3] = { SIGTRAP, TRAP_HWBKPT }, /* Monitor */ 68 + [EXCEP_OBREAK >> 3] = { SIGTRAP, TRAP_HWBKPT }, /* Monitor */ 69 + [EXCEP_PRIVINS >> 3] = { SIGILL, ILL_PRVOPC }, 70 + [EXCEP_UNIMPINS >> 3] = { SIGILL, ILL_ILLOPC }, 71 + [EXCEP_UNIMPEXINS >> 3] = { SIGILL, ILL_ILLOPC }, 72 + [EXCEP_MEMERR >> 3] = { SIGSEGV, SEGV_ACCERR }, 73 + [EXCEP_MISALIGN >> 3] = { SIGBUS, BUS_ADRALN }, 74 + [EXCEP_BUSERROR >> 3] = { SIGBUS, BUS_ADRERR }, 75 + [EXCEP_ILLINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, 76 + [EXCEP_ILLDATACC >> 3] = { SIGSEGV, SEGV_ACCERR }, 77 + [EXCEP_IOINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, 78 + [EXCEP_PRIVINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, /* userspace */ 79 + [EXCEP_PRIVDATACC >> 3] = { SIGSEGV, SEGV_ACCERR }, /* userspace */ 80 + [EXCEP_DATINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, 81 + [EXCEP_DOUBLE_FAULT >> 3] = { SIGILL, ILL_BADSTK }, 82 + 83 + /* FPU exceptions */ 84 + [EXCEP_FPU_DISABLED >> 3] = { SIGILL, ILL_COPROC }, 85 + [EXCEP_FPU_UNIMPINS >> 3] = { SIGILL, ILL_COPROC }, 86 + [EXCEP_FPU_OPERATION >> 3] = { SIGFPE, FPE_INTDIV }, 87 + 88 + /* interrupts */ 89 + [EXCEP_WDT >> 3] = { SIGALRM, 0 }, 90 + [EXCEP_NMI >> 3] = { SIGQUIT, 0 }, 91 + [EXCEP_IRQ_LEVEL0 >> 3] = { SIGINT, 0 }, 92 + [EXCEP_IRQ_LEVEL1 >> 3] = { 0, 0 }, 93 + [EXCEP_IRQ_LEVEL2 >> 3] = { 0, 0 }, 94 + [EXCEP_IRQ_LEVEL3 >> 3] = { 0, 0 }, 95 + [EXCEP_IRQ_LEVEL4 >> 3] = { 0, 0 }, 96 + [EXCEP_IRQ_LEVEL5 >> 3] = { 0, 0 }, 97 + [EXCEP_IRQ_LEVEL6 >> 3] = { 0, 0 }, 98 + 99 + /* system calls */ 100 + [EXCEP_SYSCALL0 >> 3] = { 0, 0 }, 101 + [EXCEP_SYSCALL1 >> 3] = { SIGILL, ILL_ILLTRP }, 102 + [EXCEP_SYSCALL2 >> 3] = { SIGILL, ILL_ILLTRP }, 103 + [EXCEP_SYSCALL3 >> 3] = { SIGILL, ILL_ILLTRP }, 104 + [EXCEP_SYSCALL4 >> 3] = { SIGILL, ILL_ILLTRP }, 105 + [EXCEP_SYSCALL5 >> 3] = { SIGILL, ILL_ILLTRP }, 106 + [EXCEP_SYSCALL6 >> 3] = { SIGILL, ILL_ILLTRP }, 107 + [EXCEP_SYSCALL7 >> 3] = { SIGILL, ILL_ILLTRP }, 108 + [EXCEP_SYSCALL8 >> 3] = { SIGILL, ILL_ILLTRP }, 109 + [EXCEP_SYSCALL9 >> 3] = { SIGILL, ILL_ILLTRP }, 110 + [EXCEP_SYSCALL10 >> 3] = { SIGILL, ILL_ILLTRP }, 111 + [EXCEP_SYSCALL11 >> 3] = { SIGILL, ILL_ILLTRP }, 112 + [EXCEP_SYSCALL12 >> 3] = { SIGILL, ILL_ILLTRP }, 113 + [EXCEP_SYSCALL13 >> 3] = { SIGILL, ILL_ILLTRP }, 114 + [EXCEP_SYSCALL14 >> 3] = { SIGILL, ILL_ILLTRP }, 115 + [EXCEP_SYSCALL15 >> 3] = { SIGABRT, 0 }, 116 + }; 54 117 55 118 /* 56 - * These constants are for searching for possible module text 57 - * segments. MODULE_RANGE is a guess of how much space is likely 58 - * to be vmalloced. 119 + * Handle kernel exceptions. 120 + * 121 + * See if there's a fixup handler we can force a jump to when an exception 122 + * happens due to something kernel code did 59 123 */ 60 - #define MODULE_RANGE (8 * 1024 * 1024) 124 + int die_if_no_fixup(const char *str, struct pt_regs *regs, 125 + enum exception_code code) 126 + { 127 + u8 opcode; 128 + int signo, si_code; 61 129 62 - #define DO_ERROR(signr, prologue, str, name) \ 63 - asmlinkage void name(struct pt_regs *regs, u32 intcode) \ 64 - { \ 65 - prologue; \ 66 - if (die_if_no_fixup(str, regs, intcode)) \ 67 - return; \ 68 - force_sig(signr, current); \ 130 + if (user_mode(regs)) 131 + return 0; 132 + 133 + peripheral_leds_display_exception(code); 134 + 135 + signo = exception_to_signal_map[code >> 3].signo; 136 + si_code = exception_to_signal_map[code >> 3].si_code; 137 + 138 + switch (code) { 139 + /* see if we can fixup the kernel accessing memory */ 140 + case EXCEP_ITLBMISS: 141 + case EXCEP_DTLBMISS: 142 + case EXCEP_IAERROR: 143 + case EXCEP_DAERROR: 144 + case EXCEP_MEMERR: 145 + case EXCEP_MISALIGN: 146 + case EXCEP_BUSERROR: 147 + case EXCEP_ILLDATACC: 148 + case EXCEP_IOINSACC: 149 + case EXCEP_PRIVINSACC: 150 + case EXCEP_PRIVDATACC: 151 + case EXCEP_DATINSACC: 152 + if (fixup_exception(regs)) 153 + return 1; 154 + break; 155 + 156 + case EXCEP_TRAP: 157 + case EXCEP_UNIMPINS: 158 + if (get_user(opcode, (uint8_t __user *)regs->pc) != 0) 159 + break; 160 + if (opcode == 0xff) { 161 + if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0)) 162 + return 1; 163 + if (at_debugger_breakpoint(regs)) 164 + regs->pc++; 165 + signo = SIGTRAP; 166 + si_code = TRAP_BRKPT; 167 + } 168 + break; 169 + 170 + case EXCEP_SYSCALL1 ... EXCEP_SYSCALL14: 171 + /* syscall return addr is _after_ the instruction */ 172 + regs->pc -= 2; 173 + break; 174 + 175 + case EXCEP_SYSCALL15: 176 + if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_WARN) 177 + return 1; 178 + 179 + /* syscall return addr is _after_ the instruction */ 180 + regs->pc -= 2; 181 + break; 182 + 183 + default: 184 + break; 185 + } 186 + 187 + if (debugger_intercept(code, signo, si_code, regs) == 0) 188 + return 1; 189 + 190 + if (notify_die(DIE_GPF, str, regs, code, 0, 0)) 191 + return 1; 192 + 193 + /* make the process die as the last resort */ 194 + die(str, regs, code); 69 195 } 70 196 71 - #define DO_EINFO(signr, prologue, str, name, sicode) \ 72 - asmlinkage void name(struct pt_regs *regs, u32 intcode) \ 73 - { \ 74 - siginfo_t info; \ 75 - prologue; \ 76 - if (die_if_no_fixup(str, regs, intcode)) \ 77 - return; \ 78 - info.si_signo = signr; \ 79 - if (signr == SIGILL && sicode == ILL_ILLOPC) { \ 80 - uint8_t opcode; \ 81 - if (get_user(opcode, (uint8_t __user *)regs->pc) == 0) \ 82 - if (opcode == 0xff) \ 83 - info.si_signo = SIGTRAP; \ 84 - } \ 85 - info.si_errno = 0; \ 86 - info.si_code = sicode; \ 87 - info.si_addr = (void *) regs->pc; \ 88 - force_sig_info(info.si_signo, &info, current); \ 197 + /* 198 + * General exception handler 199 + */ 200 + asmlinkage void handle_exception(struct pt_regs *regs, u32 intcode) 201 + { 202 + siginfo_t info; 203 + 204 + /* deal with kernel exceptions here */ 205 + if (die_if_no_fixup(NULL, regs, intcode)) 206 + return; 207 + 208 + /* otherwise it's a userspace exception */ 209 + info.si_signo = exception_to_signal_map[intcode >> 3].signo; 210 + info.si_code = exception_to_signal_map[intcode >> 3].si_code; 211 + info.si_errno = 0; 212 + info.si_addr = (void *) regs->pc; 213 + force_sig_info(info.si_signo, &info, current); 89 214 } 90 - 91 - DO_ERROR(SIGTRAP, {}, "trap", trap); 92 - DO_ERROR(SIGSEGV, {}, "ibreak", ibreak); 93 - DO_ERROR(SIGSEGV, {}, "obreak", obreak); 94 - DO_EINFO(SIGSEGV, {}, "access error", access_error, SEGV_ACCERR); 95 - DO_EINFO(SIGSEGV, {}, "insn access error", insn_acc_error, SEGV_ACCERR); 96 - DO_EINFO(SIGSEGV, {}, "data access error", data_acc_error, SEGV_ACCERR); 97 - DO_EINFO(SIGILL, {}, "privileged opcode", priv_op, ILL_PRVOPC); 98 - DO_EINFO(SIGILL, {}, "invalid opcode", invalid_op, ILL_ILLOPC); 99 - DO_EINFO(SIGILL, {}, "invalid ex opcode", invalid_exop, ILL_ILLOPC); 100 - DO_EINFO(SIGBUS, {}, "invalid address", mem_error, BUS_ADRERR); 101 - DO_EINFO(SIGBUS, {}, "bus error", bus_error, BUS_ADRERR); 102 - 103 - DO_ERROR(SIGTRAP, 104 - #ifndef CONFIG_MN10300_USING_JTAG 105 - DCR &= ~0x0001, 106 - #else 107 - {}, 108 - #endif 109 - "single step", istep); 110 215 111 216 /* 112 217 * handle NMI ··· 220 113 asmlinkage void nmi(struct pt_regs *regs, enum exception_code code) 221 114 { 222 115 /* see if gdbstub wants to deal with it */ 223 - #ifdef CONFIG_GDBSTUB 224 - if (gdbstub_intercept(regs, code)) 116 + if (debugger_intercept(code, SIGQUIT, 0, regs)) 225 117 return; 226 - #endif 227 118 228 119 printk(KERN_WARNING "--- Register Dump ---\n"); 229 120 show_registers(regs); ··· 233 128 */ 234 129 void show_trace(unsigned long *sp) 235 130 { 236 - unsigned long *stack, addr, module_start, module_end; 237 - int i; 131 + unsigned long bottom, stack, addr, fp, raslot; 238 132 239 - printk(KERN_EMERG "\nCall Trace:"); 133 + printk(KERN_EMERG "\nCall Trace:\n"); 240 134 241 - stack = sp; 242 - i = 0; 243 - module_start = VMALLOC_START; 244 - module_end = VMALLOC_END; 135 + //stack = (unsigned long)sp; 136 + asm("mov sp,%0" : "=a"(stack)); 137 + asm("mov a3,%0" : "=r"(fp)); 245 138 246 - while (((long) stack & (THREAD_SIZE - 1)) != 0) { 247 - addr = *stack++; 139 + raslot = ULONG_MAX; 140 + bottom = (stack + THREAD_SIZE) & ~(THREAD_SIZE - 1); 141 + for (; stack < bottom; stack += sizeof(addr)) { 142 + addr = *(unsigned long *)stack; 143 + if (stack == fp) { 144 + if (addr > stack && addr < bottom) { 145 + fp = addr; 146 + raslot = stack + sizeof(addr); 147 + continue; 148 + } 149 + fp = 0; 150 + raslot = ULONG_MAX; 151 + } 152 + 248 153 if (__kernel_text_address(addr)) { 249 - #if 1 250 154 printk(" [<%08lx>]", addr); 155 + if (stack >= raslot) 156 + raslot = ULONG_MAX; 157 + else 158 + printk(" ?"); 251 159 print_symbol(" %s", addr); 252 160 printk("\n"); 253 - #else 254 - if ((i % 6) == 0) 255 - printk(KERN_EMERG " "); 256 - printk("[<%08lx>] ", addr); 257 - i++; 258 - #endif 259 161 } 260 162 } 261 163 ··· 435 323 } 436 324 437 325 /* 438 - * see if there's a fixup handler we can force a jump to when an exception 439 - * happens due to something kernel code did 440 - */ 441 - int die_if_no_fixup(const char *str, struct pt_regs *regs, 442 - enum exception_code code) 443 - { 444 - if (user_mode(regs)) 445 - return 0; 446 - 447 - peripheral_leds_display_exception(code); 448 - 449 - switch (code) { 450 - /* see if we can fixup the kernel accessing memory */ 451 - case EXCEP_ITLBMISS: 452 - case EXCEP_DTLBMISS: 453 - case EXCEP_IAERROR: 454 - case EXCEP_DAERROR: 455 - case EXCEP_MEMERR: 456 - case EXCEP_MISALIGN: 457 - case EXCEP_BUSERROR: 458 - case EXCEP_ILLDATACC: 459 - case EXCEP_IOINSACC: 460 - case EXCEP_PRIVINSACC: 461 - case EXCEP_PRIVDATACC: 462 - case EXCEP_DATINSACC: 463 - if (fixup_exception(regs)) 464 - return 1; 465 - case EXCEP_UNIMPINS: 466 - if (regs->pc && *(uint8_t *)regs->pc == 0xff) 467 - if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0)) 468 - return 1; 469 - break; 470 - default: 471 - break; 472 - } 473 - 474 - /* see if gdbstub wants to deal with it */ 475 - #ifdef CONFIG_GDBSTUB 476 - if (gdbstub_intercept(regs, code)) 477 - return 1; 478 - #endif 479 - 480 - if (notify_die(DIE_GPF, str, regs, code, 0, 0)) 481 - return 1; 482 - 483 - /* make the process die as the last resort */ 484 - die(str, regs, code); 485 - } 486 - 487 - /* 488 - * handle unsupported syscall instructions (syscall 1-15) 489 - */ 490 - static asmlinkage void unsupported_syscall(struct pt_regs *regs, 491 - enum exception_code code) 492 - { 493 - struct task_struct *tsk = current; 494 - siginfo_t info; 495 - 496 - /* catch a kernel BUG() */ 497 - if (code == EXCEP_SYSCALL15 && !user_mode(regs)) { 498 - if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_BUG) { 499 - #ifdef CONFIG_GDBSTUB 500 - gdbstub_intercept(regs, code); 501 - #endif 502 - } 503 - } 504 - 505 - regs->pc -= 2; /* syscall return addr is _after_ the instruction */ 506 - 507 - die_if_no_fixup("An unsupported syscall insn was used by the kernel\n", 508 - regs, code); 509 - 510 - info.si_signo = SIGILL; 511 - info.si_errno = ENOSYS; 512 - info.si_code = ILL_ILLTRP; 513 - info.si_addr = (void *) regs->pc; 514 - force_sig_info(SIGILL, &info, tsk); 515 - } 516 - 517 - /* 518 326 * display the register file when the stack pointer gets clobbered 519 327 */ 520 328 asmlinkage void do_double_fault(struct pt_regs *regs) ··· 513 481 { 514 482 515 483 /* see if gdbstub wants to deal with it */ 516 - #ifdef CONFIG_GDBSTUB 517 - if (gdbstub_intercept(regs, code)) 484 + if (debugger_intercept(code, SIGSYS, 0, regs) == 0) 518 485 return; 519 - #endif 520 486 521 487 peripheral_leds_display_exception(code); 522 488 printk(KERN_EMERG "Uninitialised Exception 0x%04x\n", code & 0xFFFF); ··· 579 549 */ 580 550 void __init trap_init(void) 581 551 { 582 - set_excp_vector(EXCEP_TRAP, trap); 583 - set_excp_vector(EXCEP_ISTEP, istep); 584 - set_excp_vector(EXCEP_IBREAK, ibreak); 585 - set_excp_vector(EXCEP_OBREAK, obreak); 552 + set_excp_vector(EXCEP_TRAP, handle_exception); 553 + set_excp_vector(EXCEP_ISTEP, handle_exception); 554 + set_excp_vector(EXCEP_IBREAK, handle_exception); 555 + set_excp_vector(EXCEP_OBREAK, handle_exception); 586 556 587 - set_excp_vector(EXCEP_PRIVINS, priv_op); 588 - set_excp_vector(EXCEP_UNIMPINS, invalid_op); 589 - set_excp_vector(EXCEP_UNIMPEXINS, invalid_exop); 590 - set_excp_vector(EXCEP_MEMERR, mem_error); 557 + set_excp_vector(EXCEP_PRIVINS, handle_exception); 558 + set_excp_vector(EXCEP_UNIMPINS, handle_exception); 559 + set_excp_vector(EXCEP_UNIMPEXINS, handle_exception); 560 + set_excp_vector(EXCEP_MEMERR, handle_exception); 591 561 set_excp_vector(EXCEP_MISALIGN, misalignment); 592 - set_excp_vector(EXCEP_BUSERROR, bus_error); 593 - set_excp_vector(EXCEP_ILLINSACC, insn_acc_error); 594 - set_excp_vector(EXCEP_ILLDATACC, data_acc_error); 595 - set_excp_vector(EXCEP_IOINSACC, insn_acc_error); 596 - set_excp_vector(EXCEP_PRIVINSACC, insn_acc_error); 597 - set_excp_vector(EXCEP_PRIVDATACC, data_acc_error); 598 - set_excp_vector(EXCEP_DATINSACC, insn_acc_error); 599 - set_excp_vector(EXCEP_FPU_UNIMPINS, fpu_invalid_op); 562 + set_excp_vector(EXCEP_BUSERROR, handle_exception); 563 + set_excp_vector(EXCEP_ILLINSACC, handle_exception); 564 + set_excp_vector(EXCEP_ILLDATACC, handle_exception); 565 + set_excp_vector(EXCEP_IOINSACC, handle_exception); 566 + set_excp_vector(EXCEP_PRIVINSACC, handle_exception); 567 + set_excp_vector(EXCEP_PRIVDATACC, handle_exception); 568 + set_excp_vector(EXCEP_DATINSACC, handle_exception); 569 + set_excp_vector(EXCEP_FPU_UNIMPINS, handle_exception); 600 570 set_excp_vector(EXCEP_FPU_OPERATION, fpu_exception); 601 571 602 572 set_excp_vector(EXCEP_NMI, nmi); 603 573 604 - set_excp_vector(EXCEP_SYSCALL1, unsupported_syscall); 605 - set_excp_vector(EXCEP_SYSCALL2, unsupported_syscall); 606 - set_excp_vector(EXCEP_SYSCALL3, unsupported_syscall); 607 - set_excp_vector(EXCEP_SYSCALL4, unsupported_syscall); 608 - set_excp_vector(EXCEP_SYSCALL5, unsupported_syscall); 609 - set_excp_vector(EXCEP_SYSCALL6, unsupported_syscall); 610 - set_excp_vector(EXCEP_SYSCALL7, unsupported_syscall); 611 - set_excp_vector(EXCEP_SYSCALL8, unsupported_syscall); 612 - set_excp_vector(EXCEP_SYSCALL9, unsupported_syscall); 613 - set_excp_vector(EXCEP_SYSCALL10, unsupported_syscall); 614 - set_excp_vector(EXCEP_SYSCALL11, unsupported_syscall); 615 - set_excp_vector(EXCEP_SYSCALL12, unsupported_syscall); 616 - set_excp_vector(EXCEP_SYSCALL13, unsupported_syscall); 617 - set_excp_vector(EXCEP_SYSCALL14, unsupported_syscall); 618 - set_excp_vector(EXCEP_SYSCALL15, unsupported_syscall); 574 + set_excp_vector(EXCEP_SYSCALL1, handle_exception); 575 + set_excp_vector(EXCEP_SYSCALL2, handle_exception); 576 + set_excp_vector(EXCEP_SYSCALL3, handle_exception); 577 + set_excp_vector(EXCEP_SYSCALL4, handle_exception); 578 + set_excp_vector(EXCEP_SYSCALL5, handle_exception); 579 + set_excp_vector(EXCEP_SYSCALL6, handle_exception); 580 + set_excp_vector(EXCEP_SYSCALL7, handle_exception); 581 + set_excp_vector(EXCEP_SYSCALL8, handle_exception); 582 + set_excp_vector(EXCEP_SYSCALL9, handle_exception); 583 + set_excp_vector(EXCEP_SYSCALL10, handle_exception); 584 + set_excp_vector(EXCEP_SYSCALL11, handle_exception); 585 + set_excp_vector(EXCEP_SYSCALL12, handle_exception); 586 + set_excp_vector(EXCEP_SYSCALL13, handle_exception); 587 + set_excp_vector(EXCEP_SYSCALL14, handle_exception); 588 + set_excp_vector(EXCEP_SYSCALL15, handle_exception); 619 589 } 620 590 621 591 /*
+46
arch/mn10300/mm/Kconfig.cache
··· 99 99 help 100 100 Set if we need the icache to be invalidated, even if the dcache is in 101 101 write-through mode and doesn't need flushing. 102 + 103 + # 104 + # The kernel debugger gets its own separate cache flushing functions 105 + # 106 + config MN10300_DEBUGGER_CACHE_FLUSH_BY_TAG 107 + def_bool y if KERNEL_DEBUGGER && \ 108 + MN10300_CACHE_WBACK && \ 109 + !MN10300_CACHE_SNOOP && \ 110 + MN10300_CACHE_MANAGE_BY_TAG 111 + help 112 + Set if the debugger needs to flush the dcache and invalidate the 113 + icache using the cache tag registers to make breakpoints work. 114 + 115 + config MN10300_DEBUGGER_CACHE_FLUSH_BY_REG 116 + def_bool y if KERNEL_DEBUGGER && \ 117 + MN10300_CACHE_WBACK && \ 118 + !MN10300_CACHE_SNOOP && \ 119 + MN10300_CACHE_MANAGE_BY_REG 120 + help 121 + Set if the debugger needs to flush the dcache and invalidate the 122 + icache using automatic purge registers to make breakpoints work. 123 + 124 + config MN10300_DEBUGGER_CACHE_INV_BY_TAG 125 + def_bool y if KERNEL_DEBUGGER && \ 126 + MN10300_CACHE_WTHRU && \ 127 + !MN10300_CACHE_SNOOP && \ 128 + MN10300_CACHE_MANAGE_BY_TAG 129 + help 130 + Set if the debugger needs to invalidate the icache using the cache 131 + tag registers to make breakpoints work. 132 + 133 + config MN10300_DEBUGGER_CACHE_INV_BY_REG 134 + def_bool y if KERNEL_DEBUGGER && \ 135 + MN10300_CACHE_WTHRU && \ 136 + !MN10300_CACHE_SNOOP && \ 137 + MN10300_CACHE_MANAGE_BY_REG 138 + help 139 + Set if the debugger needs to invalidate the icache using automatic 140 + purge registers to make breakpoints work. 141 + 142 + config MN10300_DEBUGGER_CACHE_NO_FLUSH 143 + def_bool y if KERNEL_DEBUGGER && \ 144 + (MN10300_CACHE_DISABLED || MN10300_CACHE_SNOOP) 145 + help 146 + Set if the debugger does not need to flush the dcache and/or 147 + invalidate the icache to make breakpoints work.
+9
arch/mn10300/mm/Makefile
··· 13 13 cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_TAG) += cache-flush-by-tag.o 14 14 cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_REG) += cache-flush-by-reg.o 15 15 16 + cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_FLUSH_BY_TAG) += \ 17 + cache-dbg-flush-by-tag.o cache-dbg-inv-by-tag.o 18 + cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_FLUSH_BY_REG) += \ 19 + cache-dbg-flush-by-reg.o 20 + cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_INV_BY_TAG) += \ 21 + cache-dbg-inv-by-tag.o cache-dbg-inv.o 22 + cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_INV_BY_REG) += \ 23 + cache-dbg-inv-by-reg.o cache-dbg-inv.o 24 + 16 25 cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o 17 26 18 27 obj-y := \
+160
arch/mn10300/mm/cache-dbg-flush-by-reg.S
··· 1 + /* MN10300 CPU cache invalidation routines, using automatic purge registers 2 + * 3 + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + #include <linux/sys.h> 12 + #include <linux/linkage.h> 13 + #include <asm/smp.h> 14 + #include <asm/page.h> 15 + #include <asm/cache.h> 16 + #include <asm/irqflags.h> 17 + #include <asm/cacheflush.h> 18 + #include "cache.inc" 19 + 20 + .am33_2 21 + 22 + ############################################################################### 23 + # 24 + # void debugger_local_cache_flushinv(void) 25 + # Flush the entire data cache back to RAM and invalidate the icache 26 + # 27 + ############################################################################### 28 + ALIGN 29 + .globl debugger_local_cache_flushinv 30 + .type debugger_local_cache_flushinv,@function 31 + debugger_local_cache_flushinv: 32 + # 33 + # firstly flush the dcache 34 + # 35 + movhu (CHCTR),d0 36 + btst CHCTR_DCEN|CHCTR_ICEN,d0 37 + beq debugger_local_cache_flushinv_end 38 + 39 + mov DCPGCR,a0 40 + 41 + mov epsw,d1 42 + and ~EPSW_IE,epsw 43 + or EPSW_NMID,epsw 44 + nop 45 + 46 + btst CHCTR_DCEN,d0 47 + beq debugger_local_cache_flushinv_no_dcache 48 + 49 + # wait for busy bit of area purge 50 + setlb 51 + mov (a0),d0 52 + btst DCPGCR_DCPGBSY,d0 53 + lne 54 + 55 + # set mask 56 + clr d0 57 + mov d0,(DCPGMR) 58 + 59 + # area purge 60 + # 61 + # DCPGCR = DCPGCR_DCP 62 + # 63 + mov DCPGCR_DCP,d0 64 + mov d0,(a0) 65 + 66 + # wait for busy bit of area purge 67 + setlb 68 + mov (a0),d0 69 + btst DCPGCR_DCPGBSY,d0 70 + lne 71 + 72 + debugger_local_cache_flushinv_no_dcache: 73 + # 74 + # secondly, invalidate the icache if it is enabled 75 + # 76 + mov CHCTR,a0 77 + movhu (a0),d0 78 + btst CHCTR_ICEN,d0 79 + beq debugger_local_cache_flushinv_done 80 + 81 + invalidate_icache 0 82 + 83 + debugger_local_cache_flushinv_done: 84 + mov d1,epsw 85 + 86 + debugger_local_cache_flushinv_end: 87 + ret [],0 88 + .size debugger_local_cache_flushinv,.-debugger_local_cache_flushinv 89 + 90 + ############################################################################### 91 + # 92 + # void debugger_local_cache_flushinv_one(u8 *addr) 93 + # 94 + # Invalidate one particular cacheline if it's in the icache 95 + # 96 + ############################################################################### 97 + ALIGN 98 + .globl debugger_local_cache_flushinv_one 99 + .type debugger_local_cache_flushinv_one,@function 100 + debugger_local_cache_flushinv_one: 101 + movhu (CHCTR),d1 102 + btst CHCTR_DCEN|CHCTR_ICEN,d1 103 + beq debugger_local_cache_flushinv_one_end 104 + btst CHCTR_DCEN,d1 105 + beq debugger_local_cache_flushinv_one_no_dcache 106 + 107 + # round cacheline addr down 108 + and L1_CACHE_TAG_MASK,d0 109 + mov d0,a1 110 + mov d0,d1 111 + 112 + # determine the dcache purge control reg address 113 + mov DCACHE_PURGE(0,0),a0 114 + and L1_CACHE_TAG_ENTRY,d0 115 + add d0,a0 116 + 117 + # retain valid entries in the cache 118 + or L1_CACHE_TAG_VALID,d1 119 + 120 + # conditionally purge this line in all ways 121 + mov d1,(L1_CACHE_WAYDISP*0,a0) 122 + 123 + debugger_local_cache_flushinv_no_dcache: 124 + # 125 + # now try to flush the icache 126 + # 127 + mov CHCTR,a0 128 + movhu (a0),d0 129 + btst CHCTR_ICEN,d0 130 + beq mn10300_local_icache_inv_range_reg_end 131 + 132 + LOCAL_CLI_SAVE(d1) 133 + 134 + mov ICIVCR,a0 135 + 136 + # wait for the invalidator to quiesce 137 + setlb 138 + mov (a0),d0 139 + btst ICIVCR_ICIVBSY,d0 140 + lne 141 + 142 + # set the mask 143 + mov L1_CACHE_TAG_MASK,d0 144 + mov d0,(ICIVMR) 145 + 146 + # invalidate the cache line at the given address 147 + or ICIVCR_ICI,a1 148 + mov a1,(a0) 149 + 150 + # wait for the invalidator to quiesce again 151 + setlb 152 + mov (a0),d0 153 + btst ICIVCR_ICIVBSY,d0 154 + lne 155 + 156 + LOCAL_IRQ_RESTORE(d1) 157 + 158 + debugger_local_cache_flushinv_one_end: 159 + ret [],0 160 + .size debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one
+114
arch/mn10300/mm/cache-dbg-flush-by-tag.S
··· 1 + /* MN10300 CPU cache invalidation routines, using direct tag flushing 2 + * 3 + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + #include <linux/sys.h> 12 + #include <linux/linkage.h> 13 + #include <asm/smp.h> 14 + #include <asm/page.h> 15 + #include <asm/cache.h> 16 + #include <asm/irqflags.h> 17 + #include <asm/cacheflush.h> 18 + #include "cache.inc" 19 + 20 + .am33_2 21 + 22 + ############################################################################### 23 + # 24 + # void debugger_local_cache_flushinv(void) 25 + # 26 + # Flush the entire data cache back to RAM and invalidate the icache 27 + # 28 + ############################################################################### 29 + ALIGN 30 + .globl debugger_local_cache_flushinv 31 + .type debugger_local_cache_flushinv,@function 32 + debugger_local_cache_flushinv: 33 + # 34 + # firstly flush the dcache 35 + # 36 + movhu (CHCTR),d0 37 + btst CHCTR_DCEN|CHCTR_ICEN,d0 38 + beq debugger_local_cache_flushinv_end 39 + 40 + btst CHCTR_DCEN,d0 41 + beq debugger_local_cache_flushinv_no_dcache 42 + 43 + # read the addresses tagged in the cache's tag RAM and attempt to flush 44 + # those addresses specifically 45 + # - we rely on the hardware to filter out invalid tag entry addresses 46 + mov DCACHE_TAG(0,0),a0 # dcache tag RAM access address 47 + mov DCACHE_PURGE(0,0),a1 # dcache purge request address 48 + mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,e0 # total number of entries 49 + 50 + mn10300_local_dcache_flush_loop: 51 + mov (a0),d0 52 + and L1_CACHE_TAG_MASK,d0 53 + or L1_CACHE_TAG_VALID,d0 # retain valid entries in the 54 + # cache 55 + mov d0,(a1) # conditional purge 56 + 57 + add L1_CACHE_BYTES,a0 58 + add L1_CACHE_BYTES,a1 59 + add -1,e0 60 + bne mn10300_local_dcache_flush_loop 61 + 62 + debugger_local_cache_flushinv_no_dcache: 63 + # 64 + # secondly, invalidate the icache if it is enabled 65 + # 66 + mov CHCTR,a0 67 + movhu (a0),d0 68 + btst CHCTR_ICEN,d0 69 + beq debugger_local_cache_flushinv_end 70 + 71 + invalidate_icache 1 72 + 73 + debugger_local_cache_flushinv_end: 74 + ret [],0 75 + .size debugger_local_cache_flushinv,.-debugger_local_cache_flushinv 76 + 77 + ############################################################################### 78 + # 79 + # void debugger_local_cache_flushinv_one(u8 *addr) 80 + # 81 + # Invalidate one particular cacheline if it's in the icache 82 + # 83 + ############################################################################### 84 + ALIGN 85 + .globl debugger_local_cache_flushinv_one 86 + .type debugger_local_cache_flushinv_one,@function 87 + debugger_local_cache_flushinv_one: 88 + movhu (CHCTR),d1 89 + btst CHCTR_DCEN|CHCTR_ICEN,d1 90 + beq debugger_local_cache_flushinv_one_end 91 + btst CHCTR_DCEN,d1 92 + beq debugger_local_cache_flushinv_one_icache 93 + 94 + # round cacheline addr down 95 + and L1_CACHE_TAG_MASK,d0 96 + mov d0,a1 97 + 98 + # determine the dcache purge control reg address 99 + mov DCACHE_PURGE(0,0),a0 100 + and L1_CACHE_TAG_ENTRY,d0 101 + add d0,a0 102 + 103 + # retain valid entries in the cache 104 + or L1_CACHE_TAG_VALID,a1 105 + 106 + # conditionally purge this line in all ways 107 + mov a1,(L1_CACHE_WAYDISP*0,a0) 108 + 109 + # now go and do the icache 110 + bra debugger_local_cache_flushinv_one_icache 111 + 112 + debugger_local_cache_flushinv_one_end: 113 + ret [],0 114 + .size debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one
+69
arch/mn10300/mm/cache-dbg-inv-by-reg.S
··· 1 + /* MN10300 CPU cache invalidation routines, using automatic purge registers 2 + * 3 + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + #include <linux/sys.h> 12 + #include <linux/linkage.h> 13 + #include <asm/cache.h> 14 + #include <asm/irqflags.h> 15 + #include <asm/cacheflush.h> 16 + #include "cache.inc" 17 + 18 + .am33_2 19 + 20 + .globl debugger_local_cache_flushinv_one 21 + 22 + ############################################################################### 23 + # 24 + # void debugger_local_cache_flushinv_one(u8 *addr) 25 + # 26 + # Invalidate one particular cacheline if it's in the icache 27 + # 28 + ############################################################################### 29 + ALIGN 30 + .globl debugger_local_cache_flushinv_one 31 + .type debugger_local_cache_flushinv_one,@function 32 + debugger_local_cache_flushinv_one: 33 + mov d0,a1 34 + 35 + mov CHCTR,a0 36 + movhu (a0),d0 37 + btst CHCTR_ICEN,d0 38 + beq mn10300_local_icache_inv_range_reg_end 39 + 40 + LOCAL_CLI_SAVE(d1) 41 + 42 + mov ICIVCR,a0 43 + 44 + # wait for the invalidator to quiesce 45 + setlb 46 + mov (a0),d0 47 + btst ICIVCR_ICIVBSY,d0 48 + lne 49 + 50 + # set the mask 51 + mov ~L1_CACHE_TAG_MASK,d0 52 + mov d0,(ICIVMR) 53 + 54 + # invalidate the cache line at the given address 55 + and ~L1_CACHE_TAG_MASK,a1 56 + or ICIVCR_ICI,a1 57 + mov a1,(a0) 58 + 59 + # wait for the invalidator to quiesce again 60 + setlb 61 + mov (a0),d0 62 + btst ICIVCR_ICIVBSY,d0 63 + lne 64 + 65 + LOCAL_IRQ_RESTORE(d1) 66 + 67 + mn10300_local_icache_inv_range_reg_end: 68 + ret [],0 69 + .size debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one
+120
arch/mn10300/mm/cache-dbg-inv-by-tag.S
··· 1 + /* MN10300 CPU cache invalidation routines, using direct tag flushing 2 + * 3 + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + #include <linux/sys.h> 12 + #include <linux/linkage.h> 13 + #include <asm/smp.h> 14 + #include <asm/page.h> 15 + #include <asm/cache.h> 16 + #include <asm/irqflags.h> 17 + #include <asm/cacheflush.h> 18 + #include "cache.inc" 19 + 20 + .am33_2 21 + 22 + .globl debugger_local_cache_flushinv_one_icache 23 + 24 + ############################################################################### 25 + # 26 + # void debugger_local_cache_flushinv_one(u8 *addr) 27 + # 28 + # Invalidate one particular cacheline if it's in the icache 29 + # 30 + ############################################################################### 31 + ALIGN 32 + .globl debugger_local_cache_flushinv_one_icache 33 + .type debugger_local_cache_flushinv_one_icache,@function 34 + debugger_local_cache_flushinv_one_icache: 35 + movm [d3,a2],(sp) 36 + 37 + mov CHCTR,a2 38 + movhu (a2),d0 39 + btst CHCTR_ICEN,d0 40 + beq debugger_local_cache_flushinv_one_icache_end 41 + 42 + mov d0,a1 43 + and L1_CACHE_TAG_MASK,a1 44 + 45 + # read the tags from the tag RAM, and if they indicate a matching valid 46 + # cache line then we invalidate that line 47 + mov ICACHE_TAG(0,0),a0 48 + mov a1,d0 49 + and L1_CACHE_TAG_ENTRY,d0 50 + add d0,a0 # starting icache tag RAM 51 + # access address 52 + 53 + and ~(L1_CACHE_DISPARITY-1),a1 # determine comparator base 54 + or L1_CACHE_TAG_VALID,a1 55 + mov L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_VALID,d1 56 + 57 + LOCAL_CLI_SAVE(d3) 58 + 59 + # disable the icache 60 + movhu (a2),d0 61 + and ~CHCTR_ICEN,d0 62 + movhu d0,(a2) 63 + 64 + # and wait for it to calm down 65 + setlb 66 + movhu (a2),d0 67 + btst CHCTR_ICBUSY,d0 68 + lne 69 + 70 + # check all the way tags for this cache entry 71 + mov (a0),d0 # read the tag in the way 0 slot 72 + xor a1,d0 73 + and d1,d0 74 + beq debugger_local_icache_kill # jump if matched 75 + 76 + add L1_CACHE_WAYDISP,a0 77 + mov (a0),d0 # read the tag in the way 1 slot 78 + xor a1,d0 79 + and d1,d0 80 + beq debugger_local_icache_kill # jump if matched 81 + 82 + add L1_CACHE_WAYDISP,a0 83 + mov (a0),d0 # read the tag in the way 2 slot 84 + xor a1,d0 85 + and d1,d0 86 + beq debugger_local_icache_kill # jump if matched 87 + 88 + add L1_CACHE_WAYDISP,a0 89 + mov (a0),d0 # read the tag in the way 3 slot 90 + xor a1,d0 91 + and d1,d0 92 + bne debugger_local_icache_finish # jump if not matched 93 + 94 + debugger_local_icache_kill: 95 + mov d0,(a0) # kill the tag (D0 is 0 at this point) 96 + 97 + debugger_local_icache_finish: 98 + # wait for the cache to finish what it's doing 99 + setlb 100 + movhu (a2),d0 101 + btst CHCTR_ICBUSY,d0 102 + lne 103 + 104 + # and reenable it 105 + or CHCTR_ICEN,d0 106 + movhu d0,(a2) 107 + movhu (a2),d0 108 + 109 + # re-enable interrupts 110 + LOCAL_IRQ_RESTORE(d3) 111 + 112 + debugger_local_cache_flushinv_one_icache_end: 113 + ret [d3,a2],8 114 + .size debugger_local_cache_flushinv_one_icache,.-debugger_local_cache_flushinv_one_icache 115 + 116 + #ifdef CONFIG_MN10300_DEBUGGER_CACHE_INV_BY_TAG 117 + .globl debugger_local_cache_flushinv_one 118 + .type debugger_local_cache_flushinv_one,@function 119 + debugger_local_cache_flushinv_one = debugger_local_cache_flushinv_one_icache 120 + #endif
+47
arch/mn10300/mm/cache-dbg-inv.S
··· 1 + /* MN10300 CPU cache invalidation routines 2 + * 3 + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + #include <linux/sys.h> 12 + #include <linux/linkage.h> 13 + #include <asm/smp.h> 14 + #include <asm/page.h> 15 + #include <asm/cache.h> 16 + #include <asm/irqflags.h> 17 + #include <asm/cacheflush.h> 18 + #include "cache.inc" 19 + 20 + .am33_2 21 + 22 + .globl debugger_local_cache_flushinv 23 + 24 + ############################################################################### 25 + # 26 + # void debugger_local_cache_flushinv(void) 27 + # 28 + # Invalidate the entire icache 29 + # 30 + ############################################################################### 31 + ALIGN 32 + .globl debugger_local_cache_flushinv 33 + .type debugger_local_cache_flushinv,@function 34 + debugger_local_cache_flushinv: 35 + # 36 + # we only need to invalidate the icache in this cache mode 37 + # 38 + mov CHCTR,a0 39 + movhu (a0),d0 40 + btst CHCTR_ICEN,d0 41 + beq debugger_local_cache_flushinv_end 42 + 43 + invalidate_icache 1 44 + 45 + debugger_local_cache_flushinv_end: 46 + ret [],0 47 + .size debugger_local_cache_flushinv,.-debugger_local_cache_flushinv
+6 -7
arch/mn10300/mm/cache-flush-by-tag.S
··· 62 62 63 63 mn10300_local_dcache_flush_loop: 64 64 mov (a0),d0 65 - and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 65 + and L1_CACHE_TAG_MASK,d0 66 66 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the 67 67 # cache 68 68 mov d0,(a1) # conditional purge ··· 112 112 1: 113 113 114 114 # round start addr down 115 - and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 115 + and L1_CACHE_TAG_MASK,d0 116 116 mov d0,a1 117 117 118 118 add L1_CACHE_BYTES,d1 # round end addr up 119 - and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 119 + and L1_CACHE_TAG_MASK,d1 120 120 121 121 # write a request to flush all instances of an address from the cache 122 122 mov DCACHE_PURGE(0,0),a0 ··· 215 215 bra mn10300_local_dcache_flush_inv 216 216 1: 217 217 218 - and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start 219 - # addr down 218 + and L1_CACHE_TAG_MASK,d0 # round start addr down 220 219 mov d0,a1 221 220 222 - add L1_CACHE_BYTES,d1 # round end addr up 223 - and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 221 + add L1_CACHE_BYTES,d1 # round end addr up 222 + and L1_CACHE_TAG_MASK,d1 224 223 225 224 # write a request to flush and invalidate all instances of an address 226 225 # from the cache
+8 -14
arch/mn10300/mm/cache-inv-by-reg.S
··· 15 15 #include <asm/cache.h> 16 16 #include <asm/irqflags.h> 17 17 #include <asm/cacheflush.h> 18 + #include "cache.inc" 18 19 19 20 #define mn10300_local_dcache_inv_range_intr_interval \ 20 21 +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1) ··· 63 62 btst CHCTR_ICEN,d0 64 63 beq mn10300_local_icache_inv_end 65 64 66 - # invalidate 67 - or CHCTR_ICINV,d0 68 - movhu d0,(a0) 69 - movhu (a0),d0 65 + invalidate_icache 1 70 66 71 67 mn10300_local_icache_inv_end: 72 68 ret [],0 ··· 85 87 btst CHCTR_DCEN,d0 86 88 beq mn10300_local_dcache_inv_end 87 89 88 - # invalidate 89 - or CHCTR_DCINV,d0 90 - movhu d0,(a0) 91 - movhu (a0),d0 92 - 90 + invalidate_dcache 1 91 + 93 92 mn10300_local_dcache_inv_end: 94 93 ret [],0 95 94 .size mn10300_local_dcache_inv,.-mn10300_local_dcache_inv ··· 116 121 # and if they're not cacheline-aligned, we must flush any bits outside 117 122 # the range that share cachelines with stuff inside the range 118 123 #ifdef CONFIG_MN10300_CACHE_WBACK 119 - btst ~(L1_CACHE_BYTES-1),d0 124 + btst ~L1_CACHE_TAG_MASK,d0 120 125 bne 1f 121 - btst ~(L1_CACHE_BYTES-1),d1 126 + btst ~L1_CACHE_TAG_MASK,d1 122 127 beq 2f 123 128 1: 124 129 bra mn10300_local_dcache_flush_inv_range ··· 136 141 # writeback mode, in which case we would be in flush and invalidate by 137 142 # now 138 143 #ifndef CONFIG_MN10300_CACHE_WBACK 139 - and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start 140 - # addr down 144 + and L1_CACHE_TAG_MASK,d0 # round start addr down 141 145 142 146 mov L1_CACHE_BYTES-1,d2 143 147 add d2,d1 144 - and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 # round end addr up 148 + and L1_CACHE_TAG_MASK,d1 # round end addr up 145 149 #endif /* !CONFIG_MN10300_CACHE_WBACK */ 146 150 147 151 sub d0,d1,d2 # calculate the total size
+7 -79
arch/mn10300/mm/cache-inv-by-tag.S
··· 15 15 #include <asm/cache.h> 16 16 #include <asm/irqflags.h> 17 17 #include <asm/cacheflush.h> 18 + #include "cache.inc" 18 19 19 20 #define mn10300_local_dcache_inv_range_intr_interval \ 20 21 +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1) ··· 71 70 btst CHCTR_ICEN,d0 72 71 beq mn10300_local_icache_inv_end 73 72 74 - #if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) 75 - LOCAL_CLI_SAVE(d1) 76 - 77 - # disable the icache 78 - and ~CHCTR_ICEN,d0 79 - movhu d0,(a0) 80 - 81 - # and wait for it to calm down 82 - setlb 83 - movhu (a0),d0 84 - btst CHCTR_ICBUSY,d0 85 - lne 86 - 87 - # invalidate 88 - or CHCTR_ICINV,d0 89 - movhu d0,(a0) 90 - 91 - # wait for the cache to finish 92 - mov CHCTR,a0 93 - setlb 94 - movhu (a0),d0 95 - btst CHCTR_ICBUSY,d0 96 - lne 97 - 98 - # and reenable it 99 - and ~CHCTR_ICINV,d0 100 - or CHCTR_ICEN,d0 101 - movhu d0,(a0) 102 - movhu (a0),d0 103 - 104 - LOCAL_IRQ_RESTORE(d1) 105 - #else /* CONFIG_AM33_2 || CONFIG_AM33_3 */ 106 - # invalidate 107 - or CHCTR_ICINV,d0 108 - movhu d0,(a0) 109 - movhu (a0),d0 110 - #endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */ 73 + invalidate_icache 1 111 74 112 75 mn10300_local_icache_inv_end: 113 76 ret [],0 ··· 93 128 btst CHCTR_DCEN,d0 94 129 beq mn10300_local_dcache_inv_end 95 130 96 - #if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) 97 - LOCAL_CLI_SAVE(d1) 98 - 99 - # disable the dcache 100 - and ~CHCTR_DCEN,d0 101 - movhu d0,(a0) 102 - 103 - # and wait for it to calm down 104 - setlb 105 - movhu (a0),d0 106 - btst CHCTR_DCBUSY,d0 107 - lne 108 - 109 - # invalidate 110 - or CHCTR_DCINV,d0 111 - movhu d0,(a0) 112 - 113 - # wait for the cache to finish 114 - mov CHCTR,a0 115 - setlb 116 - movhu (a0),d0 117 - btst CHCTR_DCBUSY,d0 118 - lne 119 - 120 - # and reenable it 121 - and ~CHCTR_DCINV,d0 122 - or CHCTR_DCEN,d0 123 - movhu d0,(a0) 124 - movhu (a0),d0 125 - 126 - LOCAL_IRQ_RESTORE(d1) 127 - #else /* CONFIG_AM33_2 || CONFIG_AM33_3 */ 128 - # invalidate 129 - or CHCTR_DCINV,d0 130 - movhu d0,(a0) 131 - movhu (a0),d0 132 - #endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */ 131 + invalidate_dcache 1 133 132 134 133 mn10300_local_dcache_inv_end: 135 134 ret [],0 ··· 124 195 # and if they're not cacheline-aligned, we must flush any bits outside 125 196 # the range that share cachelines with stuff inside the range 126 197 #ifdef CONFIG_MN10300_CACHE_WBACK 127 - btst ~(L1_CACHE_BYTES-1),d0 198 + btst ~L1_CACHE_TAG_MASK,d0 128 199 bne 1f 129 - btst ~(L1_CACHE_BYTES-1),d1 200 + btst ~L1_CACHE_TAG_MASK,d1 130 201 beq 2f 131 202 1: 132 203 bra mn10300_local_dcache_flush_inv_range ··· 141 212 beq mn10300_local_dcache_inv_range_end 142 213 143 214 #ifndef CONFIG_MN10300_CACHE_WBACK 144 - and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start 145 - # addr down 215 + and L1_CACHE_TAG_MASK,d0 # round start addr down 146 216 147 217 add L1_CACHE_BYTES,d1 # round end addr up 148 - and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 218 + and L1_CACHE_TAG_MASK,d1 149 219 #endif /* !CONFIG_MN10300_CACHE_WBACK */ 150 220 mov d0,a1 151 221
+133
arch/mn10300/mm/cache.inc
··· 1 + /* MN10300 CPU core caching macros -*- asm -*- 2 + * 3 + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + 13 + ############################################################################### 14 + # 15 + # Invalidate the instruction cache. 16 + # A0: Should hold CHCTR 17 + # D0: Should have been read from CHCTR 18 + # D1: Will be clobbered 19 + # 20 + # On some cores it is necessary to disable the icache whilst we do this. 21 + # 22 + ############################################################################### 23 + .macro invalidate_icache,disable_irq 24 + 25 + #if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) 26 + .if \disable_irq 27 + # don't want an interrupt routine seeing a disabled cache 28 + mov epsw,d1 29 + and ~EPSW_IE,epsw 30 + or EPSW_NMID,epsw 31 + nop 32 + nop 33 + .endif 34 + 35 + # disable the icache 36 + and ~CHCTR_ICEN,d0 37 + movhu d0,(a0) 38 + 39 + # and wait for it to calm down 40 + setlb 41 + movhu (a0),d0 42 + btst CHCTR_ICBUSY,d0 43 + lne 44 + 45 + # invalidate 46 + or CHCTR_ICINV,d0 47 + movhu d0,(a0) 48 + 49 + # wait for the cache to finish 50 + setlb 51 + movhu (a0),d0 52 + btst CHCTR_ICBUSY,d0 53 + lne 54 + 55 + # and reenable it 56 + or CHCTR_ICEN,d0 57 + movhu d0,(a0) 58 + movhu (a0),d0 59 + 60 + .if \disable_irq 61 + LOCAL_IRQ_RESTORE(d1) 62 + .endif 63 + 64 + #else /* CONFIG_AM33_2 || CONFIG_AM33_3 */ 65 + 66 + # invalidate 67 + or CHCTR_ICINV,d0 68 + movhu d0,(a0) 69 + movhu (a0),d0 70 + 71 + #endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */ 72 + .endm 73 + 74 + ############################################################################### 75 + # 76 + # Invalidate the data cache. 77 + # A0: Should hold CHCTR 78 + # D0: Should have been read from CHCTR 79 + # D1: Will be clobbered 80 + # 81 + # On some cores it is necessary to disable the dcache whilst we do this. 82 + # 83 + ############################################################################### 84 + .macro invalidate_dcache,disable_irq 85 + 86 + #if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) 87 + .if \disable_irq 88 + # don't want an interrupt routine seeing a disabled cache 89 + mov epsw,d1 90 + and ~EPSW_IE,epsw 91 + or EPSW_NMID,epsw 92 + nop 93 + nop 94 + .endif 95 + 96 + # disable the dcache 97 + and ~CHCTR_DCEN,d0 98 + movhu d0,(a0) 99 + 100 + # and wait for it to calm down 101 + setlb 102 + movhu (a0),d0 103 + btst CHCTR_DCBUSY,d0 104 + lne 105 + 106 + # invalidate 107 + or CHCTR_DCINV,d0 108 + movhu d0,(a0) 109 + 110 + # wait for the cache to finish 111 + setlb 112 + movhu (a0),d0 113 + btst CHCTR_DCBUSY,d0 114 + lne 115 + 116 + # and reenable it 117 + or CHCTR_DCEN,d0 118 + movhu d0,(a0) 119 + movhu (a0),d0 120 + 121 + .if \disable_irq 122 + LOCAL_IRQ_RESTORE(d1) 123 + .endif 124 + 125 + #else /* CONFIG_AM33_2 || CONFIG_AM33_3 */ 126 + 127 + # invalidate 128 + or CHCTR_DCINV,d0 129 + movhu d0,(a0) 130 + movhu (a0),d0 131 + 132 + #endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */ 133 + .endm
+4 -5
arch/mn10300/mm/fault.c
··· 28 28 #include <asm/uaccess.h> 29 29 #include <asm/pgalloc.h> 30 30 #include <asm/hardirq.h> 31 - #include <asm/gdb-stub.h> 32 31 #include <asm/cpu-regs.h> 32 + #include <asm/debugger.h> 33 + #include <asm/gdb-stub.h> 33 34 34 35 /* 35 36 * Unlock any spinlocks which will prevent us from getting the ··· 307 306 printk(" printing pc:\n"); 308 307 printk(KERN_ALERT "%08lx\n", regs->pc); 309 308 310 - #ifdef CONFIG_GDBSTUB 311 - gdbstub_intercept( 312 - regs, fault_code & 0x00010000 ? EXCEP_IAERROR : EXCEP_DAERROR); 313 - #endif 309 + debugger_intercept(fault_code & 0x00010000 ? EXCEP_IAERROR : EXCEP_DAERROR, 310 + SIGSEGV, SEGV_ACCERR, regs); 314 311 315 312 page = PTBR; 316 313 page = ((unsigned long *) __va(page))[address >> 22];
+1
arch/mn10300/proc-mn103e010/include/proc/cache.h
··· 23 23 #define L1_CACHE_TAG_DIRTY 0x00000008 /* data cache tag dirty bit */ 24 24 #define L1_CACHE_TAG_ENTRY 0x00000ff0 /* cache tag entry address mask */ 25 25 #define L1_CACHE_TAG_ADDRESS 0xfffff000 /* cache tag line address mask */ 26 + #define L1_CACHE_TAG_MASK +(L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY) 26 27 27 28 /* 28 29 * specification of the interval between interrupt checking intervals whilst
+1
arch/mn10300/proc-mn2ws0050/include/proc/cache.h
··· 29 29 #define L1_CACHE_TAG_DIRTY 0x00000008 /* data cache tag dirty bit */ 30 30 #define L1_CACHE_TAG_ENTRY 0x00000fe0 /* cache tag entry address mask */ 31 31 #define L1_CACHE_TAG_ADDRESS 0xfffff000 /* cache tag line address mask */ 32 + #define L1_CACHE_TAG_MASK +(L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY) 32 33 33 34 /* 34 35 * specification of the interval between interrupt checking intervals whilst
+1
include/linux/kgdb.h
··· 297 297 kgdb_handle_exception(int ex_vector, int signo, int err_code, 298 298 struct pt_regs *regs); 299 299 extern int kgdb_nmicallback(int cpu, void *regs); 300 + extern void gdbstub_exit(int status); 300 301 301 302 extern int kgdb_single_step; 302 303 extern atomic_t kgdb_active;
+30
kernel/debug/gdbstub.c
··· 1093 1093 put_packet(remcom_out_buffer); 1094 1094 return 0; 1095 1095 } 1096 + 1097 + /** 1098 + * gdbstub_exit - Send an exit message to GDB 1099 + * @status: The exit code to report. 1100 + */ 1101 + void gdbstub_exit(int status) 1102 + { 1103 + unsigned char checksum, ch, buffer[3]; 1104 + int loop; 1105 + 1106 + buffer[0] = 'W'; 1107 + buffer[1] = hex_asc_hi(status); 1108 + buffer[2] = hex_asc_lo(status); 1109 + 1110 + dbg_io_ops->write_char('$'); 1111 + checksum = 0; 1112 + 1113 + for (loop = 0; loop < 3; loop++) { 1114 + ch = buffer[loop]; 1115 + checksum += ch; 1116 + dbg_io_ops->write_char(ch); 1117 + } 1118 + 1119 + dbg_io_ops->write_char('#'); 1120 + dbg_io_ops->write_char(hex_asc_hi(checksum)); 1121 + dbg_io_ops->write_char(hex_asc_lo(checksum)); 1122 + 1123 + /* make sure the output is flushed, lest the bootloader clobber it */ 1124 + dbg_io_ops->flush(); 1125 + }