sparc: Move of_set_property_mutex acquisition outside of devtree_lock grab.
[safe/jmp/linux-2.6] / arch / blackfin / kernel / kgdb.c
index c5362b2..cce79d0 100644 (file)
@@ -34,15 +34,6 @@ int gdb_bfin_vector = -1;
 #error change the definition of slavecpulocks
 #endif
 
-#define IN_MEM(addr, size, l1_addr, l1_size) \
-({ \
-       unsigned long __addr = (unsigned long)(addr); \
-       (l1_size && __addr >= l1_addr && __addr + (size) <= l1_addr + l1_size); \
-})
-#define ASYNC_BANK_SIZE \
-       (ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
-        ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE)
-
 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
        gdb_regs[BFIN_R0] = regs->r0;
@@ -463,41 +454,88 @@ static int hex(char ch)
 
 static int validate_memory_access_address(unsigned long addr, int size)
 {
-       int cpu = raw_smp_processor_id();
-
-       if (size < 0)
+       if (size < 0 || addr == 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 bfin_mem_access_type(addr, size);
+}
+
+static int bfin_probe_kernel_read(char *dst, char *src, int size)
+{
+       unsigned long lsrc = (unsigned long)src;
+       int mem_type;
+
+       mem_type = validate_memory_access_address(lsrc, size);
+       if (mem_type < 0)
+               return mem_type;
+
+       if (lsrc >= SYSMMR_BASE) {
+               if (size == 2 && lsrc % 2 == 0) {
+                       u16 mmr = bfin_read16(src);
+                       memcpy(dst, &mmr, sizeof(mmr));
                        return 0;
-               if (IN_MEM(addr, size, COREB_L1_CODE_START, L1_CODE_LENGTH))
+               } else if (size == 4 && lsrc % 4 == 0) {
+                       u32 mmr = bfin_read32(src);
+                       memcpy(dst, &mmr, sizeof(mmr));
                        return 0;
-               if (IN_MEM(addr, size, COREB_L1_DATA_A_START, L1_DATA_A_LENGTH))
+               }
+       } else {
+               switch (mem_type) {
+                       case BFIN_MEM_ACCESS_CORE:
+                       case BFIN_MEM_ACCESS_CORE_ONLY:
+                               return probe_kernel_read(dst, src, size);
+                       /* XXX: should support IDMA here with SMP */
+                       case BFIN_MEM_ACCESS_DMA:
+                               if (dma_memcpy(dst, src, size))
+                                       return 0;
+                               break;
+                       case BFIN_MEM_ACCESS_ITEST:
+                               if (isram_memcpy(dst, src, size))
+                                       return 0;
+                               break;
+               }
+       }
+
+       return -EFAULT;
+}
+
+static int bfin_probe_kernel_write(char *dst, char *src, int size)
+{
+       unsigned long ldst = (unsigned long)dst;
+       int mem_type;
+
+       mem_type = validate_memory_access_address(ldst, size);
+       if (mem_type < 0)
+               return mem_type;
+
+       if (ldst >= SYSMMR_BASE) {
+               if (size == 2 && ldst % 2 == 0) {
+                       u16 mmr;
+                       memcpy(&mmr, src, sizeof(mmr));
+                       bfin_write16(dst, mmr);
                        return 0;
-               if (IN_MEM(addr, size, COREB_L1_DATA_B_START, L1_DATA_B_LENGTH))
+               } else if (size == 4 && ldst % 4 == 0) {
+                       u32 mmr;
+                       memcpy(&mmr, src, sizeof(mmr));
+                       bfin_write32(dst, mmr);
                        return 0;
-#endif
+               }
+       } else {
+               switch (mem_type) {
+                       case BFIN_MEM_ACCESS_CORE:
+                       case BFIN_MEM_ACCESS_CORE_ONLY:
+                               return probe_kernel_write(dst, src, size);
+                       /* XXX: should support IDMA here with SMP */
+                       case BFIN_MEM_ACCESS_DMA:
+                               if (dma_memcpy(dst, src, size))
+                                       return 0;
+                               break;
+                       case BFIN_MEM_ACCESS_ITEST:
+                               if (isram_memcpy(dst, src, size))
+                                       return 0;
+                               break;
+               }
        }
 
-       if (IN_MEM(addr, size, L2_START, L2_LENGTH))
-               return 0;
-
        return -EFAULT;
 }
 
@@ -509,14 +547,6 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
 {
        char *tmp;
        int err;
-       unsigned char *pch;
-       unsigned short mmr16;
-       unsigned long mmr32;
-       int cpu = raw_smp_processor_id();
-
-       err = validate_memory_access_address((unsigned long)mem, count);
-       if (err)
-               return err;
 
        /*
         * We use the upper half of buf as an intermediate buffer for the
@@ -524,44 +554,7 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
         */
        tmp = buf + count;
 
-       if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/
-               switch (count) {
-               case 2:
-                       if ((unsigned int)mem % 2 == 0) {
-                               mmr16 = *(unsigned short *)mem;
-                               pch = (unsigned char *)&mmr16;
-                               *tmp++ = *pch++;
-                               *tmp++ = *pch++;
-                               tmp -= 2;
-                       } else
-                               err = -EFAULT;
-                       break;
-               case 4:
-                       if ((unsigned int)mem % 4 == 0) {
-                               mmr32 = *(unsigned long *)mem;
-                               pch = (unsigned char *)&mmr32;
-                               *tmp++ = *pch++;
-                               *tmp++ = *pch++;
-                               *tmp++ = *pch++;
-                               *tmp++ = *pch++;
-                               tmp -= 4;
-                       } else
-                               err = -EFAULT;
-                       break;
-               default:
-                       err = -EFAULT;
-               }
-       } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
-#ifdef CONFIG_SMP
-               || (cpu == 1 && IN_MEM(mem, count, COREB_L1_CODE_START, L1_CODE_LENGTH))
-#endif
-               ) {
-               /* access L1 instruction SRAM*/
-               if (dma_memcpy(tmp, mem, count) == NULL)
-                       err = -EFAULT;
-       } else
-               err = probe_kernel_read(tmp, mem, count);
-
+       err = bfin_probe_kernel_read(tmp, mem, count);
        if (!err) {
                while (count > 0) {
                        buf = pack_hex_byte(buf, *tmp);
@@ -582,61 +575,21 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
  */
 int kgdb_ebin2mem(char *buf, char *mem, int count)
 {
-       char *tmp_old;
-       char *tmp_new;
-       unsigned short *mmr16;
-       unsigned long *mmr32;
-       int err;
-       int size = 0;
-       int cpu = raw_smp_processor_id();
+       char *tmp_old, *tmp_new;
+       int size;
 
        tmp_old = tmp_new = buf;
 
-       while (count-- > 0) {
+       for (size = 0; size < count; ++size) {
                if (*tmp_old == 0x7d)
                        *tmp_new = *(++tmp_old) ^ 0x20;
                else
                        *tmp_new = *tmp_old;
                tmp_new++;
                tmp_old++;
-               size++;
        }
 
-       err = validate_memory_access_address((unsigned long)mem, size);
-       if (err)
-               return 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
-                               err = -EFAULT;
-                       break;
-               case 4:
-                       if ((unsigned int)mem % 4 == 0) {
-                               mmr32 = (unsigned long *)buf;
-                               *(unsigned long *)mem = *mmr32;
-                       } else
-                               err = -EFAULT;
-                       break;
-               default:
-                       err = -EFAULT;
-               }
-       } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
-#ifdef CONFIG_SMP
-               || (cpu == 1 && IN_MEM(mem, count, COREB_L1_CODE_START, L1_CODE_LENGTH))
-#endif
-               ) {
-               /* access L1 instruction SRAM */
-               if (dma_memcpy(mem, buf, size) == NULL)
-                       err = -EFAULT;
-       } else
-               err = probe_kernel_write(mem, buf, size);
-
-       return err;
+       return bfin_probe_kernel_write(mem, buf, count);
 }
 
 /*
@@ -646,16 +599,7 @@ int kgdb_ebin2mem(char *buf, char *mem, int count)
  */
 int kgdb_hex2mem(char *buf, char *mem, int count)
 {
-       char *tmp_raw;
-       char *tmp_hex;
-       unsigned short *mmr16;
-       unsigned long *mmr32;
-       int err;
-       int cpu = raw_smp_processor_id();
-
-       err = validate_memory_access_address((unsigned long)mem, count);
-       if (err)
-               return err;
+       char *tmp_raw, *tmp_hex;
 
        /*
         * We use the upper half of buf as an intermediate buffer for the
@@ -670,39 +614,18 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
                *tmp_raw |= hex(*tmp_hex--) << 4;
        }
 
-       if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/
-               switch (count) {
-               case 2:
-                       if ((unsigned int)mem % 2 == 0) {
-                               mmr16 = (unsigned short *)tmp_raw;
-                               *(unsigned short *)mem = *mmr16;
-                       } else
-                               err = -EFAULT;
-                       break;
-               case 4:
-                       if ((unsigned int)mem % 4 == 0) {
-                               mmr32 = (unsigned long *)tmp_raw;
-                               *(unsigned long *)mem = *mmr32;
-                       } else
-                               err = -EFAULT;
-                       break;
-               default:
-                       err = -EFAULT;
-               }
-       } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
-#ifdef CONFIG_SMP
-               || (cpu == 1 && IN_MEM(mem, count, COREB_L1_CODE_START, L1_CODE_LENGTH))
-#endif
-               ) {
-               /* access L1 instruction SRAM */
-               if (dma_memcpy(mem, tmp_raw, count) == NULL)
-                       err = -EFAULT;
-       } else
-               err = probe_kernel_write(mem, tmp_raw, count);
-
-       return err;
+       return bfin_probe_kernel_write(mem, tmp_raw, count);
 }
 
+#define IN_MEM(addr, size, l1_addr, l1_size) \
+({ \
+       unsigned long __addr = (unsigned long)(addr); \
+       (l1_size && __addr >= l1_addr && __addr + (size) <= l1_addr + l1_size); \
+})
+#define ASYNC_BANK_SIZE \
+       (ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
+        ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE)
+
 int kgdb_validate_break_address(unsigned long addr)
 {
        int cpu = raw_smp_processor_id();
@@ -725,46 +648,17 @@ int kgdb_validate_break_address(unsigned long addr)
 
 int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
 {
-       int err;
-       int cpu = raw_smp_processor_id();
-
-       if ((cpu == 0 && IN_MEM(addr, BREAK_INSTR_SIZE, L1_CODE_START, L1_CODE_LENGTH))
-#ifdef CONFIG_SMP
-               || (cpu == 1 && IN_MEM(addr, BREAK_INSTR_SIZE, COREB_L1_CODE_START, L1_CODE_LENGTH))
-#endif
-               ) {
-               /* access L1 instruction SRAM */
-               if (dma_memcpy(saved_instr, (void *)addr, BREAK_INSTR_SIZE)
-                       == NULL)
-                       return -EFAULT;
-
-               if (dma_memcpy((void *)addr, arch_kgdb_ops.gdb_bpt_instr,
-                       BREAK_INSTR_SIZE) == NULL)
-                       return -EFAULT;
-
-               return 0;
-       } else {
-               err = probe_kernel_read(saved_instr, (char *)addr,
-                       BREAK_INSTR_SIZE);
-               if (err)
-                       return err;
-
-               return probe_kernel_write((char *)addr,
-                       arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
-       }
+       int err = bfin_probe_kernel_read(saved_instr, (char *)addr,
+                                        BREAK_INSTR_SIZE);
+       if (err)
+               return err;
+       return bfin_probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr,
+                                      BREAK_INSTR_SIZE);
 }
 
 int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)
 {
-       if (IN_MEM(addr, BREAK_INSTR_SIZE, L1_CODE_START, L1_CODE_LENGTH)) {
-               /* access L1 instruction SRAM */
-               if (dma_memcpy((void *)addr, bundle, BREAK_INSTR_SIZE) == NULL)
-                       return -EFAULT;
-
-               return 0;
-       } else
-               return probe_kernel_write((char *)addr,
-                               (char *)bundle, BREAK_INSTR_SIZE);
+       return bfin_probe_kernel_write((char *)addr, bundle, BREAK_INSTR_SIZE);
 }
 
 int kgdb_arch_init(void)