Title: [6603] trunk/arch/blackfin: Blackfin: unify memory region checks between kgdb and traps
Revision
6603
Author
vapier
Date
2009-06-07 16:21:31 -0500 (Sun, 07 Jun 2009)

Log Message

Blackfin: unify memory region checks between kgdb and traps

The kgdb and traps code developed pretty much identical checks for how to
access different regions of the Blackfin memory map, but each wasn't 100%,
so unify them to avoid duplication/bitrot.

Modified Paths

Diff

Modified: trunk/arch/blackfin/include/asm/uaccess.h (6602 => 6603)


--- trunk/arch/blackfin/include/asm/uaccess.h	2009-06-07 19:11:50 UTC (rev 6602)
+++ trunk/arch/blackfin/include/asm/uaccess.h	2009-06-07 21:21:31 UTC (rev 6603)
@@ -265,4 +265,12 @@
 
 #define clear_user(to, n) __clear_user(to, n)
 
+/**
+ *	bfin_mem_access_type() - what kind of memory access is required
+ *	@addr:   the address to check
+ *	@size:   number of bytes needed
+ *	@return: <0 is error, 0 is core read, 1 is dma read
+ */
+int bfin_mem_access_type(unsigned long addr, unsigned long size);
+
 #endif				/* _BLACKFIN_UACCESS_H */

Modified: trunk/arch/blackfin/kernel/kgdb.c (6602 => 6603)


--- trunk/arch/blackfin/kernel/kgdb.c	2009-06-07 19:11:50 UTC (rev 6602)
+++ trunk/arch/blackfin/kernel/kgdb.c	2009-06-07 21:21:31 UTC (rev 6603)
@@ -463,42 +463,9 @@
 
 static int validate_memory_access_address(unsigned long addr, int size)
 {
-	int cpu = raw_smp_processor_id();
-
 	if (size < 0)
 		return -EFAULT;
-	if (addr >= 0x1000 && (addr + size) <= physical_mem_end)
-		return 0;
-	if (addr >= SYSMMR_BASE)
-		return 0;
-	if (IN_MEM(addr, size, ASYNC_BANK0_BASE, ASYNC_BANK_SIZE))
-		return 0;
-	if (cpu == 0) {
-		if (IN_MEM(addr, size, L1_SCRATCH_START, L1_SCRATCH_LENGTH))
-			return 0;
-		if (IN_MEM(addr, size, L1_CODE_START, L1_CODE_LENGTH))
-			return 0;
-		if (IN_MEM(addr, size, L1_DATA_A_START, L1_DATA_A_LENGTH))
-			return 0;
-		if (IN_MEM(addr, size, L1_DATA_B_START, L1_DATA_B_LENGTH))
-			return 0;
-#ifdef CONFIG_SMP
-	} else if (cpu == 1) {
-		if (IN_MEM(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH))
-			return 0;
-		if (IN_MEM(addr, size, COREB_L1_CODE_START, L1_CODE_LENGTH))
-			return 0;
-		if (IN_MEM(addr, size, COREB_L1_DATA_A_START, L1_DATA_A_LENGTH))
-			return 0;
-		if (IN_MEM(addr, size, COREB_L1_DATA_B_START, L1_DATA_B_LENGTH))
-			return 0;
-#endif
-	}
-
-	if (IN_MEM(addr, size, L2_START, L2_LENGTH))
-		return 0;
-
-	return -EFAULT;
+	return bfin_mem_access_type(addr, size) < 0 ? -EFAULT : 0;
 }
 
 /*

Modified: trunk/arch/blackfin/kernel/process.c (6602 => 6603)


--- trunk/arch/blackfin/kernel/process.c	2009-06-07 19:11:50 UTC (rev 6602)
+++ trunk/arch/blackfin/kernel/process.c	2009-06-07 21:21:31 UTC (rev 6603)
@@ -321,6 +321,57 @@
 	}
 }
 
+#define IN_MEM(addr, size, const_addr, const_size) \
+({ \
+	unsigned long __addr = (unsigned long)(addr); \
+	(const_size && \
+	 __addr >= const_addr && \
+	 __addr + (size) <= const_addr + const_size); \
+})
+#define IN_ASYNC(bnum, bctlnum) \
+({ \
+	(bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? -EFAULT : \
+	bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? -EFAULT : 0; \
+})
+int bfin_mem_access_type(unsigned long addr, unsigned long size)
+{
+	/* Check that things do not wrap around */
+	if (addr > ULONG_MAX - size)
+		return -EFAULT;
+
+	if (addr >= FIXED_CODE_START && (addr + size) <= physical_mem_end)
+		return 0;
+
+	if (IN_MEM(addr, size, get_l1_code_start(), L1_CODE_LENGTH))
+		return 1;
+
+	if (IN_MEM(addr, size, get_l1_scratch_start(), L1_SCRATCH_LENGTH))
+		return 0;
+	if (IN_MEM(addr, size, get_l1_data_a_start(), L1_DATA_A_LENGTH))
+		return 0;
+	if (IN_MEM(addr, size, get_l1_data_b_start(), L1_DATA_B_LENGTH))
+		return 0;
+	if (IN_MEM(addr, size, L2_START, L2_LENGTH))
+		return 0;
+
+	if (addr >= SYSMMR_BASE)
+		return 0;
+
+	/* We can't read EBIU banks that aren't enabled or we end up hanging
+	 * on the access to the async space.
+	 */
+	if (IN_MEM(addr, size, ASYNC_BANK0_BASE, ASYNC_BANK0_SIZE))
+		return IN_ASYNC(0, 0);
+	if (IN_MEM(addr, size, ASYNC_BANK1_BASE, ASYNC_BANK1_SIZE))
+		return IN_ASYNC(1, 0);
+	if (IN_MEM(addr, size, ASYNC_BANK2_BASE, ASYNC_BANK2_SIZE))
+		return IN_ASYNC(2, 1);
+	if (IN_MEM(addr, size, ASYNC_BANK3_BASE, ASYNC_BANK3_SIZE))
+		return IN_ASYNC(3, 1);
+
+	return -EFAULT;
+}
+
 #if defined(CONFIG_ACCESS_CHECK)
 #ifdef CONFIG_ACCESS_OK_L1
 __attribute__((l1_text))

Modified: trunk/arch/blackfin/kernel/traps.c (6602 => 6603)


--- trunk/arch/blackfin/kernel/traps.c	2009-06-07 19:11:50 UTC (rev 6602)
+++ trunk/arch/blackfin/kernel/traps.c	2009-06-07 21:21:31 UTC (rev 6603)
@@ -617,57 +617,26 @@
  */
 static bool get_instruction(unsigned short *val, unsigned short *address)
 {
+	unsigned long addr = (unsigned long)address;
 
-	unsigned long addr;
-
-	addr = (unsigned long)address;
-
 	/* Check for odd addresses */
 	if (addr & 0x1)
 		return false;
 
-	/* Check that things do not wrap around */
-	if (addr > (addr + 2))
+	/* MMR region will never have instructions */
+	if (addr >= SYSMMR_BASE)
 		return false;
 
-	/*
-	 * Since we are in exception context, we need to do a little address checking
-	 * We need to make sure we are only accessing valid memory, and
-	 * we don't read something in the async space that can hang forever
-	 */
-	if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) ||
-#if L2_LENGTH != 0
-	    (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) ||
-#endif
-	    (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) ||
-#if L1_DATA_A_LENGTH != 0
-	    (addr >= L1_DATA_A_START && (addr + 2) <= (L1_DATA_A_START + L1_DATA_A_LENGTH)) ||
-#endif
-#if L1_DATA_B_LENGTH != 0
-	    (addr >= L1_DATA_B_START && (addr + 2) <= (L1_DATA_B_START + L1_DATA_B_LENGTH)) ||
-#endif
-	    (addr >= L1_SCRATCH_START && (addr + 2) <= (L1_SCRATCH_START + L1_SCRATCH_LENGTH)) ||
-	    (!(bfin_read_EBIU_AMBCTL0() & B0RDYEN) &&
-	       addr >= ASYNC_BANK0_BASE && (addr + 2) <= (ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE)) ||
-	    (!(bfin_read_EBIU_AMBCTL0() & B1RDYEN) &&
-	       addr >= ASYNC_BANK1_BASE && (addr + 2) <= (ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE)) ||
-	    (!(bfin_read_EBIU_AMBCTL1() & B2RDYEN) &&
-	       addr >= ASYNC_BANK2_BASE && (addr + 2) <= (ASYNC_BANK2_BASE + ASYNC_BANK1_SIZE)) ||
-	    (!(bfin_read_EBIU_AMBCTL1() & B3RDYEN) &&
-	      addr >= ASYNC_BANK3_BASE && (addr + 2) <= (ASYNC_BANK3_BASE + ASYNC_BANK1_SIZE))) {
-		*val = *address;
-		return true;
+	switch (bfin_mem_access_type(addr, 2)) {
+		case 0:  /* core access */
+			*val = *address;
+			return true;
+		case 1:  /* L1 inst (dma access) */
+			isram_memcpy(val, address, 2);
+			return true;
+		default: /* invalid access */
+			return false;
 	}
-
-#if L1_CODE_LENGTH != 0
-	if (addr >= L1_CODE_START && (addr + 2) <= (L1_CODE_START + L1_CODE_LENGTH)) {
-		isram_memcpy(val, address, 2);
-		return true;
-	}
-#endif
-
-
-	return false;
 }
 
 /*
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to