Title: [5245] trunk: Task[#3428] Hardware breakpoint and set binary data to memroy.
Revision
5245
Author
sonicz
Date
2008-09-05 04:24:42 -0500 (Fri, 05 Sep 2008)

Log Message

Task[#3428] Hardware breakpoint and set binary data to memroy.
1. Fix hardware breakpoint failure. 
2. Proper set binary data to L1 and MMR.
3. Clean up.

Modified Paths

Diff

Modified: trunk/arch/blackfin/kernel/kgdb.c (5244 => 5245)


--- trunk/arch/blackfin/kernel/kgdb.c	2008-09-04 10:03:55 UTC (rev 5244)
+++ trunk/arch/blackfin/kernel/kgdb.c	2008-09-05 09:24:42 UTC (rev 5245)
@@ -263,12 +263,13 @@
 	default:
 		return 0;
 	};
-
 	for (breakno = 0; breakno < HW_WATCHPOINT_NUM; breakno++)
 		if (bfin_type == breakinfo[breakno].type
 			&& breakinfo[breakno].occupied
-			&& breakinfo[breakno].addr == addr)
+			&& breakinfo[breakno].addr == addr) {
 			breakinfo[breakno].occupied = 0;
+			breakinfo[breakno].enabled = 0;
+		}
 
 	return 0;
 }
@@ -289,68 +290,56 @@
 		breakinfo[breakno].type = TYPE_DATA_WATCHPOINT;
 }
 
-/*
-void kgdb_show_info(void)
-{
-	printk(KERN_DEBUG "hwd: wpia0=0x%x, wpiacnt0=%d, wpiactl=0x%x, wpstat=0x%x\n",
-		bfin_read_WPIA0(), bfin_read_WPIACNT0(),
-		bfin_read_WPIACTL(), bfin_read_WPSTAT());
-}
-*/
-
 void bfin_correct_hw_break(void)
 {
 	int breakno;
 	unsigned int wpiactl = 0;
 	unsigned int wpdactl = 0;
+	int enable_wp = 0;
 
 	for (breakno = 0; breakno < HW_WATCHPOINT_NUM; breakno++)
-		if (breakinfo[breakno].enabled)
+		if (breakinfo[breakno].enabled) {
+			enable_wp = 1;
+
 			switch (breakno) {
 			case 0:
 				wpiactl |= WPIAEN0|WPICNTEN0;
-				wpiactl |= WPPWR;
 				bfin_write_WPIA0(breakinfo[breakno].addr);
 				bfin_write_WPIACNT0(breakinfo[breakno].count
 					+ breakinfo->skip);
 				break;
 			case 1:
 				wpiactl |= WPIAEN1|WPICNTEN1;
-				wpiactl |= WPPWR;
 				bfin_write_WPIA1(breakinfo[breakno].addr);
 				bfin_write_WPIACNT1(breakinfo[breakno].count
 					+ breakinfo->skip);
 				break;
 			case 2:
 				wpiactl |= WPIAEN2|WPICNTEN2;
-				wpiactl |= WPPWR;
 				bfin_write_WPIA2(breakinfo[breakno].addr);
 				bfin_write_WPIACNT2(breakinfo[breakno].count
 					+ breakinfo->skip);
 				break;
 			case 3:
 				wpiactl |= WPIAEN3|WPICNTEN3;
-				wpiactl |= WPPWR;
 				bfin_write_WPIA3(breakinfo[breakno].addr);
 				bfin_write_WPIACNT3(breakinfo[breakno].count
 					+ breakinfo->skip);
 				break;
 			case 4:
 				wpiactl |= WPIAEN4|WPICNTEN4;
-				wpiactl |= WPPWR;
 				bfin_write_WPIA4(breakinfo[breakno].addr);
 				bfin_write_WPIACNT4(breakinfo[breakno].count
 					+ breakinfo->skip);
 				break;
 			case 5:
 				wpiactl |= WPIAEN5|WPICNTEN5;
-				wpiactl |= WPPWR;
 				bfin_write_WPIA5(breakinfo[breakno].addr);
 				bfin_write_WPIACNT5(breakinfo[breakno].count
 					+ breakinfo->skip);
 				break;
 			case 6:
-				wpdactl |= WPDAEN0|WPDCNTEN0;
+				wpdactl |= WPDAEN0|WPDCNTEN0|WPDSRC0;
 				wpdactl |= breakinfo[breakno].dataacc
 					<< WPDACC0_OFFSET;
 				bfin_write_WPDA0(breakinfo[breakno].addr);
@@ -358,7 +347,7 @@
 					+ breakinfo->skip);
 				break;
 			case 7:
-				wpdactl |= WPDAEN1|WPDCNTEN1;
+				wpdactl |= WPDAEN1|WPDCNTEN1|WPDSRC1;
 				wpdactl |= breakinfo[breakno].dataacc
 					<< WPDACC1_OFFSET;
 				bfin_write_WPDA1(breakinfo[breakno].addr);
@@ -366,12 +355,17 @@
 					+ breakinfo->skip);
 				break;
 			};
+		}
 
-	/*printk("correct_hw_break: wpdactl=0x%x\n", wpdactl);*/
-	bfin_write_WPIACTL(wpiactl);
+	/* Should enable WPPWR bit first before set any other
+	 * WPIACTL and WPDACTL bits */
+	if (enable_wp) {
+		bfin_write_WPIACTL(WPPWR);
+		CSYNC();
+	}
+	bfin_write_WPIACTL(wpiactl|WPPWR);
 	bfin_write_WPDACTL(wpdactl);
 	CSYNC();
-	/*kgdb_show_info();*/
 }
 
 void kgdb_disable_hw_debug(struct pt_regs *regs)
@@ -594,34 +588,55 @@
  */
 int kgdb_ebin2mem(char *buf, char *mem, int count)
 {
+	char *tmp_old;
+	char *tmp_new;
+	unsigned short *mmr16;
+	unsigned long *mmr32;
 	int err = 0;
-	char c;
+	int size = 0;
 
-	if (validate_memory_access_address((unsigned long)mem, count))
-		return EFAULT;
+	tmp_old = tmp_new = buf;
 
 	while (count-- > 0) {
-		c = *buf++;
-		if (c == 0x7d)
-			c = *buf++ ^ 0x20;
+		if (*tmp_old == 0x7d)
+			*tmp_new = *(++tmp_old) ^ 0x20;
+		else
+			*tmp_new = *tmp_old;
+		tmp_new++;
+		tmp_old++;
+		size++;
+	}
 
-		if ((unsigned int)mem >= SYSMMR_BASE) {
-			/*access MMR registers*/
-			err = EFAULT;
-		} else if ((unsigned int)mem >= L1_CODE_START &&
-			(unsigned int)mem < L1_CODE_START + L1_CODE_LENGTH) {
-			/* access L1 instruction SRAM */
-			if (dma_memcpy(mem, &c, 1) == NULL)
-				err = EFAULT;
-		} else
-			err = probe_kernel_write(mem, &c, 1);
+	if (validate_memory_access_address((unsigned long)mem, size))
+		return EFAULT;
 
-		if (err)
+	if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/
+		switch (size) {
+		case 2:
+			if ((unsigned int)mem % 2 == 0) {
+				mmr16 = (unsigned short *)buf;
+				*(unsigned short *)mem = *mmr16;
+			} else
+				return EFAULT;
 			break;
+		case 4:
+			if ((unsigned int)mem % 4 == 0) {
+				mmr32 = (unsigned long *)buf;
+				*(unsigned long *)mem = *mmr32;
+			} else
+				return EFAULT;
+			break;
+		default:
+			return EFAULT;
+		}
+	} else if ((unsigned int)mem >= L1_CODE_START &&
+		(unsigned int)mem < L1_CODE_START + L1_CODE_LENGTH) {
+		/* access L1 instruction SRAM */
+		if (dma_memcpy(mem, buf, size) == NULL)
+			err = EFAULT;
+	} else
+		err = probe_kernel_write(mem, buf, size);
 
-		mem++;
-	}
-
 	return err;
 }
 

Modified: trunk/include/asm-blackfin/kgdb.h (5244 => 5245)


--- trunk/include/asm-blackfin/kgdb.h	2008-09-04 10:03:55 UTC (rev 5244)
+++ trunk/include/asm-blackfin/kgdb.h	2008-09-05 09:24:42 UTC (rev 5245)
@@ -132,8 +132,8 @@
 #define CACHE_FLUSH_IS_SAFE	1
 #define HW_INST_WATCHPOINT_NUM	6
 #define HW_WATCHPOINT_NUM	8
-#define TYPE_INST_WATCHPOINT	1
-#define TYPE_DATA_WATCHPOINT	2
+#define TYPE_INST_WATCHPOINT	0
+#define TYPE_DATA_WATCHPOINT	1
 
 /* Instruction watchpoint address control register bits mask */
 #define WPPWR		0x1
@@ -171,9 +171,9 @@
 #define WPDCNTEN0	0x10
 #define WPDCNTEN1	0x20
 
-#define WPDSRC0_OFFSET	6
+#define WPDSRC0		0xc0
 #define WPDACC0_OFFSET	8
-#define WPDSRC1_OFFSET	10
+#define WPDSRC1		0xc00
 #define WPDACC1_OFFSET	12
 
 /* Watchpoint status register bits mask */
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
http://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to