Index: arch/amd64/include/debugger.h
===================================================================
--- arch/amd64/include/debugger.h	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
+++ arch/amd64/include/debugger.h	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
@@ -43,5 +43,5 @@
 
 extern void debugger_init(void);
-extern int breakpoint_add(void * where, int flags);
+extern int breakpoint_add(void * where, int flags, int curidx);
 extern void breakpoint_del(int slot);
 
Index: arch/amd64/include/interrupt.h
===================================================================
--- arch/amd64/include/interrupt.h	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
+++ arch/amd64/include/interrupt.h	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
@@ -61,4 +61,5 @@
 #define VECTOR_TLB_SHOOTDOWN_IPI	(IVT_FREEBASE+0)
 #define VECTOR_WAKEUP_IPI		(IVT_FREEBASE+1)
+#define VECTOR_DEBUG_IPI                (IVT_FREEBASE+2)
 
 /** This is passed to interrupt handlers */
Index: arch/amd64/src/debugger.c
===================================================================
--- arch/amd64/src/debugger.c	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
+++ arch/amd64/src/debugger.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
@@ -38,4 +38,5 @@
 #include <debug.h>
 #include <func.h>
+#include <smp/ipi.h>
 
 typedef struct  {
@@ -56,4 +57,6 @@
 };
 
+#ifndef CONFIG_DEBUG_AS_WATCHPOINT
+
 static int cmd_del_breakpoint(cmd_arg_t *argv);
 static cmd_arg_t del_argv = {
@@ -91,4 +94,5 @@
 };
 
+#endif
 
 /** Print table of active breakpoints */
@@ -110,4 +114,56 @@
 }
 
+/* Setup DR register according to table */
+static void setup_dr(int curidx)
+{
+	__native dr7;
+	bpinfo_t *cur = &breakpoints[curidx];
+	int flags = breakpoints[curidx].flags;
+
+	/* Disable breakpoint in DR7 */
+	dr7 = read_dr7();
+	dr7 &= ~(0x2 << (curidx*2));
+
+	if (cur->address) { /* Setup DR register */
+		/* Set breakpoint to debug registers */
+		switch (curidx) {
+		case 0:
+			write_dr0(cur->address);
+			break;
+		case 1:
+			write_dr1(cur->address);
+			break;
+		case 2:
+			write_dr2(cur->address);
+			break;
+		case 3:
+			write_dr3(cur->address);
+			break;
+		}
+		/* Set type to requested breakpoint & length*/
+		dr7 &= ~ (0x3 << (16 + 4*curidx));
+		dr7 &= ~ (0x3 << (18 + 4*curidx));
+		if ((flags & BKPOINT_INSTR)) {
+			;
+		} else {
+			if (sizeof(int) == 4)
+				dr7 |= ((__native) 0x3) << (18 + 4*curidx);
+			else /* 8 */
+				dr7 |= ((__native) 0x2) << (18 + 4*curidx);
+			
+			if ((flags & BKPOINT_WRITE))
+				dr7 |= ((__native) 0x1) << (16 + 4*curidx);
+			else if ((flags & BKPOINT_READ_WRITE))
+				dr7 |= ((__native) 0x3) << (16 + 4*curidx);
+		}
+
+		/* Enable global breakpoint */
+		dr7 |= 0x2 << (curidx*2);
+
+		write_dr7(dr7);
+		
+	} 
+}
+	
 /** Enable hardware breakpoint
  *
@@ -117,11 +173,9 @@
  * @return Debug slot on success, -1 - no available HW breakpoint
  */
-int breakpoint_add(void * where, int flags)
-{
-	bpinfo_t *cur = NULL;
-	int curidx;
+int breakpoint_add(void * where, int flags, int curidx)
+{
 	ipl_t ipl;
 	int i;
-	__native dr7;
+	bpinfo_t *cur;
 
 	ASSERT( flags & (BKPOINT_INSTR | BKPOINT_WRITE | BKPOINT_READ_WRITE));
@@ -130,62 +184,33 @@
 	spinlock_lock(&bkpoint_lock);
 	
-	/* Find free space in slots */
-	for (i=0; i<BKPOINTS_MAX; i++)
-		if (!breakpoints[i].address) {
-			cur = &breakpoints[i];
-			curidx = i;
-			break;
-		}
-	if (!cur) {
-		/* Too many breakpoints */
-		spinlock_unlock(&bkpoint_lock);
-		interrupts_restore(ipl);
-		return -1;
-	}
+	if (curidx == -1) {
+		/* Find free space in slots */
+		for (i=0; i<BKPOINTS_MAX; i++)
+			if (!breakpoints[i].address) {
+				curidx = i;
+				break;
+			}
+		if (curidx == -1) {
+			/* Too many breakpoints */
+			spinlock_unlock(&bkpoint_lock);
+			interrupts_restore(ipl);
+			return -1;
+		}
+	}
+	cur = &breakpoints[curidx];
+
 	cur->address = (__address) where;
 	cur->flags = flags;
 	cur->counter = 0;
 
-	/* Set breakpoint to debug registers */
-	switch (curidx) {
-	case 0:
-		write_dr0(cur->address);
-		break;
-	case 1:
-		write_dr1(cur->address);
-		break;
-	case 2:
-		write_dr2(cur->address);
-		break;
-	case 3:
-		write_dr3(cur->address);
-		break;
-	}
-	dr7 = read_dr7();
-	/* Set type to requested breakpoint & length*/
-	dr7 &= ~ (0x3 << (16 + 4*curidx));
-	dr7 &= ~ (0x3 << (18 + 4*curidx));
-	if ((flags & BKPOINT_INSTR)) {
-		printf("Instr breakpoint\n");
-		;
-	} else {
-		if (sizeof(int) == 4)
-			dr7 |= 0x3 << (18 + 4*curidx);
-		else /* 8 */
-			dr7 |= 0x2 << (18 + 4*curidx);
-			
-		if ((flags & BKPOINT_WRITE))
-			dr7 |= 0x1 << (16 + 4*curidx);
-		else if ((flags & BKPOINT_READ_WRITE))
-			dr7 |= 0x3 << (16 + 4*curidx);
-	}
-
-	/* Enable global breakpoint */
-	dr7 |= 0x2 << (curidx*2);
-
-	write_dr7(dr7);
+	setup_dr(curidx);
 
 	spinlock_unlock(&bkpoint_lock);
 	interrupts_restore(ipl);
+
+	/* Send IPI */
+#ifdef CONFIG_SMP
+//	ipi_broadcast(VECTOR_DEBUG_IPI);	
+#endif	
 
 	return curidx;
@@ -222,4 +247,65 @@
 }
 
+void breakpoint_del(int slot)
+{
+	bpinfo_t *cur;
+	ipl_t ipl;
+
+	ipl = interrupts_disable();
+	spinlock_lock(&bkpoint_lock);
+
+	cur = &breakpoints[slot];
+	if (!cur->address) {
+		spinlock_unlock(&bkpoint_lock);
+		interrupts_restore(ipl);
+		return;
+	}
+
+	cur->address = NULL;
+
+	setup_dr(slot);
+
+	spinlock_unlock(&bkpoint_lock);
+	interrupts_restore(ipl);
+#ifdef CONFIG_SMP
+//	ipi_broadcast(VECTOR_DEBUG_IPI);	
+#endif
+}
+
+#ifndef CONFIG_DEBUG_AS_WATCHPOINT
+
+/** Remove breakpoint from table */
+int cmd_del_breakpoint(cmd_arg_t *argv)
+{
+	if (argv->intval < 0 || argv->intval > BKPOINTS_MAX) {
+		printf("Invalid breakpoint number.\n");
+		return 0;
+	}
+	breakpoint_del(argv->intval);
+	return 1;
+}
+
+/** Add new breakpoint to table */
+static int cmd_add_breakpoint(cmd_arg_t *argv)
+{
+	int flags;
+	int id;
+
+	if (argv == &add_argv) {
+		flags = BKPOINT_INSTR;
+	} else { /* addwatchp */
+		flags = BKPOINT_WRITE;
+	}
+	printf("Adding breakpoint on address: %p\n", argv->intval);
+	id = breakpoint_add((void *)argv->intval, flags, -1);
+	if (id < 0)
+		printf("Add breakpoint failed.\n");
+	else
+		printf("Added breakpoint %d.\n", id);
+	
+	return 1;
+}
+#endif
+
 static void debug_exception(int n, istate_t *istate)
 {
@@ -245,58 +331,15 @@
 }
 
-void breakpoint_del(int slot)
-{
-	bpinfo_t *cur;
-	ipl_t ipl;
-	__native dr7;
-
-	ipl = interrupts_disable();
+#ifdef CONFIG_SMP
+static void debug_ipi(int n, istate_t *istate)
+{
+	int i;
+
 	spinlock_lock(&bkpoint_lock);
-
-	cur = &breakpoints[slot];
-	if (!cur->address) {
-		spinlock_unlock(&bkpoint_lock);
-		interrupts_restore(ipl);
-		return;
-	}
-
-	cur->address = NULL;
-
-	/* Disable breakpoint in DR7 */
-	dr7 = read_dr7();
-	dr7 &= ~(0x2 << (slot*2));
-	write_dr7(dr7);
-
+	for (i=0; i < BKPOINTS_MAX; i++)
+		setup_dr(i);
 	spinlock_unlock(&bkpoint_lock);
-	interrupts_restore(ipl);
-}
-
-/** Remove breakpoint from table */
-int cmd_del_breakpoint(cmd_arg_t *argv)
-{
-	if (argv->intval < 0 || argv->intval > BKPOINTS_MAX) {
-		printf("Invalid breakpoint number.\n");
-		return 0;
-	}
-	breakpoint_del(argv->intval);
-	return 1;
-}
-
-/** Add new breakpoint to table */
-static int cmd_add_breakpoint(cmd_arg_t *argv)
-{
-	int flags;
-
-	if (argv == &add_argv) {
-		flags = BKPOINT_INSTR;
-	} else { /* addwatchp */
-		flags = BKPOINT_WRITE;
-	}
-	printf("Adding breakpoint on address: %p\n", argv->intval);
-	if (breakpoint_add((void *)argv->intval, flags))
-		printf("Add breakpoint failed.\n");
-	
-	return 1;
-}
+}
+#endif
 
 /** Initialize debugger */
@@ -312,4 +355,5 @@
 		panic("could not register command %s\n", bkpts_info.name);
 
+#ifndef CONFIG_DEBUG_AS_WATCHPOINT
 	cmd_initialize(&delbkpt_info);
 	if (!cmd_register(&delbkpt_info))
@@ -323,6 +367,11 @@
 	if (!cmd_register(&addwatchp_info))
 		panic("could not register command %s\n", addwatchp_info.name);
+#endif
 	
 	exc_register(VECTOR_DEBUG, "debugger",
 		     debug_exception);
-}
+#ifdef CONFIG_SMP
+	exc_register(VECTOR_DEBUG_IPI, "debugger_smp",
+		     debug_ipi);
+#endif
+}
Index: arch/amd64/src/proc/scheduler.c
===================================================================
--- arch/amd64/src/proc/scheduler.c	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
+++ arch/amd64/src/proc/scheduler.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
@@ -35,4 +35,5 @@
 #include <arch/debugger.h>
 
+#include <print.h>
 void before_thread_runs_arch(void)
 {
@@ -45,12 +46,10 @@
 	swapgs();
 
-
 #ifdef CONFIG_DEBUG_AS_WATCHPOINT
 	/* Set watchpoint on AS to ensure that nobody sets it to zero */
-	static int old_slot = -1;
-	if (old_slot >=0)
-		breakpoint_del(old_slot);
-	old_slot = breakpoint_add(&((the_t *) THREAD->kstack)->as, 
-				  BKPOINT_WRITE | BKPOINT_CHECK_ZERO);
+	if (CPU->id < BKPOINTS_MAX)
+		breakpoint_add(&((the_t *) THREAD->kstack)->as, 
+			       BKPOINT_WRITE | BKPOINT_CHECK_ZERO,
+			       CPU->id);
 #endif
 }
Index: arch/ia32/include/interrupt.h
===================================================================
--- arch/ia32/include/interrupt.h	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
+++ arch/ia32/include/interrupt.h	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
@@ -61,4 +61,5 @@
 #define VECTOR_SYSCALL			(IVT_FREEBASE+0)
 #define VECTOR_TLB_SHOOTDOWN_IPI	(IVT_FREEBASE+1)
+#define VECTOR_DEBUG_IPI                (IVT_FREEBASE+2)
 
 struct istate {
Index: arch/ia32/src/proc/scheduler.c
===================================================================
--- arch/ia32/src/proc/scheduler.c	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
+++ arch/ia32/src/proc/scheduler.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
@@ -41,11 +41,9 @@
 #ifdef CONFIG_DEBUG_AS_WATCHPOINT
 	/* Set watchpoint on AS to ensure that nobody sets it to zero */
-	static int old_slot = -1;
-	if (old_slot >=0)
-		breakpoint_del(old_slot);
-	old_slot = breakpoint_add(&((the_t *) THREAD->kstack)->as, 
-				  BKPOINT_WRITE | BKPOINT_CHECK_ZERO);
+	if (CPU->id < BKPOINTS_MAX)
+		breakpoint_add(&((the_t *) THREAD->kstack)->as, 
+			       BKPOINT_WRITE | BKPOINT_CHECK_ZERO,
+			       CPU->id);
 #endif
-
 }
 
Index: test/thread/thread1/test.c
===================================================================
--- test/thread/thread1/test.c	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
+++ test/thread/thread1/test.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
@@ -42,9 +42,11 @@
 static void threadtest(void *data)
 {
-    while(1)
-    {
-        printf("%d\n",(int)(THREAD->tid));
-	scheduler();
-    }
+	while(1)
+	{
+		while (1)
+			;
+		printf("%d\n",(int)(THREAD->tid));
+		scheduler();
+	}
 }
 
