#include <asm/byteorder.h>
#include <asm/atomic.h>
#include <asm/system.h>
+#include <asm/unaligned.h>
static int kgdb_break_asap;
int err_code;
int cpu;
int pass_exception;
- long threadid;
+ unsigned long threadid;
long kgdb_usethreadid;
struct pt_regs *linux_regs;
};
* the other CPUs might interfere with your debugging context, so
* use this with care:
*/
-int kgdb_do_roundup = 1;
+static int kgdb_do_roundup = 1;
static int __init opt_nokgdbroundup(char *str)
{
return 0;
}
+int __weak kgdb_skipexception(int exception, struct pt_regs *regs)
+{
+ return 0;
+}
+
+void __weak
+kgdb_post_primary_code(struct pt_regs *regs, int e_vector, int err_code)
+{
+ return;
+}
+
/**
* kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb.
* @regs: Current &struct pt_regs.
* GDB remote protocol parser:
*/
-static const char hexchars[] = "0123456789abcdef";
-
static int hex(char ch)
{
if ((ch >= 'a') && (ch <= 'f'))
}
kgdb_io_ops->write_char('#');
- kgdb_io_ops->write_char(hexchars[checksum >> 4]);
- kgdb_io_ops->write_char(hexchars[checksum & 0xf]);
+ kgdb_io_ops->write_char(hex_asc_hi(checksum));
+ kgdb_io_ops->write_char(hex_asc_lo(checksum));
if (kgdb_io_ops->flush)
kgdb_io_ops->flush();
}
}
-static char *pack_hex_byte(char *pkt, u8 byte)
-{
- *pkt++ = hexchars[byte >> 4];
- *pkt++ = hexchars[byte & 0xf];
-
- return pkt;
-}
-
/*
* Convert the memory pointed to by mem into hex, placing result in buf.
* Return a pointer to the last char put in buf (null). May return an error.
* While we find nice hex chars, build a long_val.
* Return number of chars processed.
*/
-int kgdb_hex2long(char **ptr, long *long_val)
+int kgdb_hex2long(char **ptr, unsigned long *long_val)
{
int hex_val;
int num = 0;
{
error = -error;
pkt[0] = 'E';
- pkt[1] = hexchars[(error / 10)];
- pkt[2] = hexchars[(error % 10)];
+ pkt[1] = hex_asc[(error / 10)];
+ pkt[2] = hex_asc[(error % 10)];
pkt[3] = '\0';
}
scan = (unsigned char *)id;
while (i--)
*scan++ = 0;
- *scan++ = (value >> 24) & 0xff;
- *scan++ = (value >> 16) & 0xff;
- *scan++ = (value >> 8) & 0xff;
- *scan++ = (value & 0xff);
+ put_unaligned_be32(value, scan);
}
static struct task_struct *getthread(struct pt_regs *regs, int tid)
smp_wmb();
atomic_set(&cpu_in_kgdb[cpu], 1);
- /*
- * The primary CPU must be active to enter here, but this is
- * guard in case the primary CPU had not been selected if
- * this was an entry via nmi.
- */
- while (atomic_read(&kgdb_active) == -1)
- cpu_relax();
-
- /* Wait till primary CPU goes completely into the debugger. */
- while (!atomic_read(&cpu_in_kgdb[atomic_read(&kgdb_active)]))
- cpu_relax();
-
/* Wait till primary CPU is done with debugging */
while (atomic_read(&passive_cpu_wait[cpu]))
cpu_relax();
if (!CACHE_FLUSH_IS_SAFE)
return;
- if (current->mm) {
+ if (current->mm && current->mm->mmap_cache) {
flush_cache_range(current->mm->mmap_cache,
addr, addr + BREAK_INSTR_SIZE);
- } else {
- flush_icache_range(addr, addr + BREAK_INSTR_SIZE);
}
+ /* Force flush instruction cache if it was outside the mm */
+ flush_icache_range(addr, addr + BREAK_INSTR_SIZE);
}
/*
return 0;
}
-int remove_all_break(void)
+static int remove_all_break(void)
{
unsigned long addr;
int error;
/* Clear memory breakpoints. */
for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
- if (kgdb_break[i].state != BP_SET)
- continue;
+ if (kgdb_break[i].state != BP_ACTIVE)
+ goto setundefined;
addr = kgdb_break[i].bpt_addr;
error = kgdb_arch_remove_breakpoint(addr,
kgdb_break[i].saved_instr);
if (error)
- return error;
- kgdb_break[i].state = BP_REMOVED;
+ printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n",
+ addr);
+setundefined:
+ kgdb_break[i].state = BP_UNDEFINED;
}
/* Clear hardware breakpoints. */
atomic_set(&passive_cpu_wait[i], 1);
}
-#ifdef CONFIG_SMP
- /* Signal the other CPUs to enter kgdb_wait() */
- if ((!kgdb_single_step || !kgdb_contthread) && kgdb_do_roundup)
- kgdb_roundup_cpus(flags);
-#endif
-
/*
* spin_lock code is good enough as a barrier so we don't
* need one here:
*/
atomic_set(&cpu_in_kgdb[ks->cpu], 1);
+#ifdef CONFIG_SMP
+ /* Signal the other CPUs to enter kgdb_wait() */
+ if ((!kgdb_single_step || !kgdb_contthread) && kgdb_do_roundup)
+ kgdb_roundup_cpus(flags);
+#endif
+
/*
* Wait for the other CPUs to be notified and be waiting for us:
*/
{
#ifdef CONFIG_SMP
if (!atomic_read(&cpu_in_kgdb[cpu]) &&
- atomic_read(&kgdb_active) != cpu) {
+ atomic_read(&kgdb_active) != cpu &&
+ atomic_read(&cpu_in_kgdb[atomic_read(&kgdb_active)])) {
kgdb_wait((struct pt_regs *)regs);
return 0;
}
}
/**
- * kkgdb_register_io_module - register KGDB IO module
+ * kgdb_register_io_module - register KGDB IO module
* @new_kgdb_io_ops: the io ops vector
*
* Register it with the KGDB core.