Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Kernel Debugger Architecture Independent Breakpoint Handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyright (c) 2009 Wind River Systems, Inc.  All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/kdb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/kgdb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "kdb_private.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * Table of kdb_breakpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) kdb_bp_t kdb_breakpoints[KDB_MAXBPT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static void kdb_setsinglestep(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	KDB_STATE_SET(DOING_SS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) static char *kdb_rwtypes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	"Instruction(i)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	"Instruction(Register)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	"Data Write",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	"I/O",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	"Data Access"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static char *kdb_bptype(kdb_bp_t *bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	if (bp->bp_type < 0 || bp->bp_type > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		return "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	return kdb_rwtypes[bp->bp_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static int kdb_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	int nextarg = *nextargp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	int diag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	bp->bph_length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	if ((argc + 1) != nextarg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		if (strncasecmp(argv[nextarg], "datar", sizeof("datar")) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			bp->bp_type = BP_ACCESS_WATCHPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		else if (strncasecmp(argv[nextarg], "dataw", sizeof("dataw")) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			bp->bp_type = BP_WRITE_WATCHPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		else if (strncasecmp(argv[nextarg], "inst", sizeof("inst")) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			bp->bp_type = BP_HARDWARE_BREAKPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			return KDB_ARGCOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		bp->bph_length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		nextarg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		if ((argc + 1) != nextarg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			unsigned long len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			diag = kdbgetularg((char *)argv[nextarg],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 					   &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			if (diag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				return diag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			if (len > 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 				return KDB_BADLENGTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			bp->bph_length = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			nextarg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		if ((argc + 1) != nextarg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			return KDB_ARGCOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	*nextargp = nextarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) static int _kdb_bp_remove(kdb_bp_t *bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	int ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (!bp->bp_installed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (!bp->bp_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		ret = dbg_remove_sw_break(bp->bp_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		ret = arch_kgdb_ops.remove_hw_breakpoint(bp->bp_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			 bp->bph_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			 bp->bp_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		bp->bp_installed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void kdb_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	if (KDB_DEBUG(BP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		kdb_printf("regs->ip = 0x%lx\n", instruction_pointer(regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	 * Setup single step
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	kdb_setsinglestep(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	 * Reset delay attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	bp->bp_delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	bp->bp_delayed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int _kdb_bp_install(struct pt_regs *regs, kdb_bp_t *bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	 * Install the breakpoint, if it is not already installed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	if (KDB_DEBUG(BP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		kdb_printf("%s: bp_installed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			   __func__, bp->bp_installed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	if (!KDB_STATE(SSBPT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		bp->bp_delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if (bp->bp_installed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if (bp->bp_delay || (bp->bp_delayed && KDB_STATE(DOING_SS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		if (KDB_DEBUG(BP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 			kdb_printf("%s: delayed bp\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		kdb_handle_bp(regs, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (!bp->bp_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		ret = dbg_set_sw_break(bp->bp_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		ret = arch_kgdb_ops.set_hw_breakpoint(bp->bp_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			 bp->bph_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			 bp->bp_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		bp->bp_installed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		kdb_printf("%s: failed to set breakpoint at 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			   __func__, bp->bp_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		if (!bp->bp_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			kdb_printf("Software breakpoints are unavailable.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 				   "  Boot the kernel with rodata=off\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 				   "  OR use hw breaks: help bph\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  * kdb_bp_install
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  *	Install kdb_breakpoints prior to returning from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  *	kernel debugger.  This allows the kdb_breakpoints to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  *	upon functions that are used internally by kdb, such as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  *	printk().  This function is only called once per kdb session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) void kdb_bp_install(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	for (i = 0; i < KDB_MAXBPT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		kdb_bp_t *bp = &kdb_breakpoints[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		if (KDB_DEBUG(BP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 			kdb_printf("%s: bp %d bp_enabled %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 				   __func__, i, bp->bp_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		if (bp->bp_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			_kdb_bp_install(regs, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * kdb_bp_remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  *	Remove kdb_breakpoints upon entry to the kernel debugger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * Parameters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  * Outputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)  * Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * Remarks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) void kdb_bp_remove(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	for (i = KDB_MAXBPT - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		kdb_bp_t *bp = &kdb_breakpoints[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		if (KDB_DEBUG(BP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			kdb_printf("%s: bp %d bp_enabled %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 				   __func__, i, bp->bp_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		if (bp->bp_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			_kdb_bp_remove(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  * kdb_printbp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  *	Internal function to format and print a breakpoint entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  * Parameters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * Outputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  * Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  * Remarks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void kdb_printbp(kdb_bp_t *bp, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	kdb_printf("%s ", kdb_bptype(bp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	kdb_printf("BP #%d at ", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	kdb_symbol_print(bp->bp_addr, NULL, KDB_SP_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	if (bp->bp_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		kdb_printf("\n    is enabled ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		kdb_printf("\n    is disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	kdb_printf("  addr at %016lx, hardtype=%d installed=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		   bp->bp_addr, bp->bp_type, bp->bp_installed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	kdb_printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  * kdb_bp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  *	Handle the bp commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)  *	[bp|bph] <addr-expression> [DATAR|DATAW]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)  * Parameters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  *	argc	Count of arguments in argv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  *	argv	Space delimited command line arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)  * Outputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  *	Zero for success, a kdb diagnostic if failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  * Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  * Remarks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  *	bp	Set breakpoint on all cpus.  Only use hardware assist if need.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  *	bph	Set breakpoint on all cpus.  Force hardware register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static int kdb_bp(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	int i, bpno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	kdb_bp_t *bp, *bp_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	int diag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	char *symname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	long offset = 0ul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	int nextarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	kdb_bp_t template = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (argc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		 * Display breakpoint table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		for (bpno = 0, bp = kdb_breakpoints; bpno < KDB_MAXBPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		     bpno++, bp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			if (bp->bp_free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			kdb_printbp(bp, bpno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	nextarg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	diag = kdbgetaddrarg(argc, argv, &nextarg, &template.bp_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			     &offset, &symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	if (diag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		return diag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	if (!template.bp_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		return KDB_BADINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	 * This check is redundant (since the breakpoint machinery should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	 * be doing the same check during kdb_bp_install) but gives the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	 * user immediate feedback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	diag = kgdb_validate_break_address(template.bp_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (diag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		return diag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	 * Find an empty bp structure to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	for (bpno = 0, bp = kdb_breakpoints; bpno < KDB_MAXBPT; bpno++, bp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		if (bp->bp_free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	if (bpno == KDB_MAXBPT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		return KDB_TOOMANYBPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (strcmp(argv[0], "bph") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		template.bp_type = BP_HARDWARE_BREAKPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		diag = kdb_parsebp(argc, argv, &nextarg, &template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		if (diag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			return diag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		template.bp_type = BP_BREAKPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	 * Check for clashing breakpoints.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	 * Note, in this design we can't have hardware breakpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	 * enabled for both read and write on the same address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	for (i = 0, bp_check = kdb_breakpoints; i < KDB_MAXBPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	     i++, bp_check++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		if (!bp_check->bp_free &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		    bp_check->bp_addr == template.bp_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			kdb_printf("You already have a breakpoint at "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 				   kdb_bfd_vma_fmt0 "\n", template.bp_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 			return KDB_DUPBPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	template.bp_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	 * Actually allocate the breakpoint found earlier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	*bp = template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	bp->bp_free = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	kdb_printbp(bp, bpno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)  * kdb_bc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)  *	Handles the 'bc', 'be', and 'bd' commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)  *	[bd|bc|be] <breakpoint-number>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)  *	[bd|bc|be] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)  * Parameters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)  *	argc	Count of arguments in argv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)  *	argv	Space delimited command line arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)  * Outputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  *	Zero for success, a kdb diagnostic for failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)  * Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  * Remarks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static int kdb_bc(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	kdb_bp_t *bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	int lowbp = KDB_MAXBPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	int highbp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	int done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	int diag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	int cmd;			/* KDBCMD_B? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) #define KDBCMD_BC	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) #define KDBCMD_BE	1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) #define KDBCMD_BD	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	if (strcmp(argv[0], "be") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		cmd = KDBCMD_BE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	else if (strcmp(argv[0], "bd") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		cmd = KDBCMD_BD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		cmd = KDBCMD_BC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	if (argc != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		return KDB_ARGCOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	if (strcmp(argv[1], "*") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		lowbp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		highbp = KDB_MAXBPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		diag = kdbgetularg(argv[1], &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		if (diag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			return diag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		 * For addresses less than the maximum breakpoint number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		 * assume that the breakpoint number is desired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		if (addr < KDB_MAXBPT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			lowbp = highbp = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			highbp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			    i++, bp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 				if (bp->bp_addr == addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 					lowbp = highbp = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 					highbp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	 * Now operate on the set of breakpoints matching the input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	 * criteria (either '*' for all, or an individual breakpoint).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	for (bp = &kdb_breakpoints[lowbp], i = lowbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	    i < highbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	    i++, bp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		if (bp->bp_free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		done++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		case KDBCMD_BC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			bp->bp_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 			kdb_printf("Breakpoint %d at "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 				   kdb_bfd_vma_fmt " cleared\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 				   i, bp->bp_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 			bp->bp_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			bp->bp_free = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		case KDBCMD_BE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			bp->bp_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			kdb_printf("Breakpoint %d at "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 				   kdb_bfd_vma_fmt " enabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 				   i, bp->bp_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 			kdb_printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		case KDBCMD_BD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			if (!bp->bp_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 			bp->bp_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 			kdb_printf("Breakpoint %d at "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 				   kdb_bfd_vma_fmt " disabled\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 				   i, bp->bp_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		if (bp->bp_delay && (cmd == KDBCMD_BC || cmd == KDBCMD_BD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			bp->bp_delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			KDB_STATE_CLEAR(SSBPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	return (!done) ? KDB_BPTNOTFOUND : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)  * kdb_ss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)  *	Process the 'ss' (Single Step) command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)  *	ss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)  * Parameters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)  *	argc	Argument count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)  *	argv	Argument vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)  * Outputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)  *	KDB_CMD_SS for success, a kdb error if failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)  * Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)  *	None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)  * Remarks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)  *	Set the arch specific option to trigger a debug trap after the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)  *	instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static int kdb_ss(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	if (argc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		return KDB_ARGCOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	 * Set trace flag and go.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	KDB_STATE_SET(DOING_SS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	return KDB_CMD_SS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* Initialize the breakpoint table and register	breakpoint commands. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) void __init kdb_initbptab(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	kdb_bp_t *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	 * First time initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	memset(&kdb_breakpoints, '\0', sizeof(kdb_breakpoints));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		bp->bp_free = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	kdb_register_flags("bp", kdb_bp, "[<vaddr>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		"Set/Display breakpoints", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	kdb_register_flags("bl", kdb_bp, "[<vaddr>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		"Display breakpoints", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		kdb_register_flags("bph", kdb_bp, "[<vaddr>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		"[datar [length]|dataw [length]]   Set hw brk", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	kdb_register_flags("bc", kdb_bc, "<bpnum>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		"Clear Breakpoint", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		KDB_ENABLE_FLOW_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	kdb_register_flags("be", kdb_bc, "<bpnum>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		"Enable Breakpoint", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		KDB_ENABLE_FLOW_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	kdb_register_flags("bd", kdb_bc, "<bpnum>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		"Disable Breakpoint", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		KDB_ENABLE_FLOW_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	kdb_register_flags("ss", kdb_ss, "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		"Single Step", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	 * Architecture dependent initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }