Index: kernel/generic/include/debug.h
===================================================================
--- kernel/generic/include/debug.h	(revision 5c8de0094cb7b5654ab7058bd709cece3f6feafa)
+++ kernel/generic/include/debug.h	(revision ac11ac7ebb0e25fa0031a251504c104ca9341786)
@@ -55,5 +55,5 @@
 	do { \
 		if (!(expr)) \
-			panic("Assertion failed (%s)", #expr); \
+			panic_assert("%s", #expr); \
 	} while (0)
 
@@ -72,5 +72,5 @@
 	do { \
 		if (!(expr)) \
-			panic("Assertion failed (%s, %s)", #expr, msg); \
+			panic_assert("%s, %s", #expr, msg); \
 	} while (0)
 
Index: kernel/generic/include/panic.h
===================================================================
--- kernel/generic/include/panic.h	(revision 5c8de0094cb7b5654ab7058bd709cece3f6feafa)
+++ kernel/generic/include/panic.h	(revision ac11ac7ebb0e25fa0031a251504c104ca9341786)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2010 Jakub Jermar
  * All rights reserved.
  *
@@ -37,33 +37,30 @@
 
 #include <typedefs.h>
-#include <stacktrace.h>
-#include <print.h>
 
-#ifdef CONFIG_DEBUG
+#define panic(fmt, ...) \
+	panic_common(PANIC_OTHER, NULL, 0, 0, fmt, ##__VA_ARGS__)
 
-#define panic(format, ...) \
-	do { \
-		silent = false; \
-		printf("Kernel panic in %s() at %s:%u\n", \
-		    __func__, __FILE__, __LINE__); \
-		stack_trace(); \
-		panic_printf("Panic message: " format "\n", \
-		    ##__VA_ARGS__);\
-	} while (0)
+#define panic_assert(fmt, ...) \
+	panic_common(PANIC_ASSERT, NULL, 0, 0, fmt, ##__VA_ARGS__)
 
-#else /* CONFIG_DEBUG */
+#define panic_badtrap(istate, n, fmt, ...) \
+	panic_common(PANIC_BADTRAP, istate, 0, n, fmt, ##__VA_ARGS__)
 
-#define panic(format, ...) \
-	do { \
-		silent = false; \
-		panic_printf("Kernel panic: " format "\n", ##__VA_ARGS__); \
-		stack_trace(); \
-	} while (0)
+#define panic_memtrap(istate, access, addr, fmt, ...) \
+	panic_common(PANIC_MEMTRAP, istate, access, addr, fmt, ##__VA_ARGS__)
 
-#endif /* CONFIG_DEBUG */
+typedef enum {
+	PANIC_OTHER,
+	PANIC_ASSERT,
+	PANIC_BADTRAP,
+	PANIC_MEMTRAP
+} panic_category_t;
+
+struct istate;
 
 extern bool silent;
 
-extern void panic_printf(const char *fmt, ...) __attribute__((noreturn));
+extern void panic_common(panic_category_t, struct istate *, int,
+    uintptr_t, const char *, ...) __attribute__ ((noreturn));
 
 #endif
Index: kernel/generic/src/debug/panic.c
===================================================================
--- kernel/generic/src/debug/panic.c	(revision ac11ac7ebb0e25fa0031a251504c104ca9341786)
+++ kernel/generic/src/debug/panic.c	(revision ac11ac7ebb0e25fa0031a251504c104ca9341786)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genericdebug
+ * @{
+ */
+/** @file
+ */
+
+#include <panic.h>
+#include <print.h>
+#include <stacktrace.h>
+#include <func.h>
+#include <typedefs.h>
+#include <mm/as.h>
+#include <stdarg.h>
+#include <interrupt.h>
+
+void panic_common(panic_category_t cat, istate_t *istate, int access,
+    uintptr_t address, const char *fmt, ...)
+{
+	va_list args;
+
+	silent = false;
+
+	printf("\nKERNEL PANIC ON cpu%d DUE TO ", CPU->id);
+	va_start(args, fmt);
+	if (cat == PANIC_ASSERT) {
+		printf("A FAILED ASSERTION:\n");
+		vprintf(fmt, args);
+		printf("\n");
+	} else if (cat == PANIC_BADTRAP) {
+		printf("BAD TRAP %ld.\n", address);
+	} else if (cat == PANIC_MEMTRAP) {
+		printf("A BAD MEMORY ACCESS WHILE ");
+		if (access == PF_ACCESS_READ)
+			printf("LOADING FROM");
+		else if (access == PF_ACCESS_WRITE)
+			printf("STORING TO");
+		else if (access == PF_ACCESS_EXEC)
+			printf("BRANCHING TO");
+		else
+			printf("REFERENCING");
+		printf(" ADDRESS %p.\n", address); 
+	} else {
+		printf("THE FOLLOWING REASON:\n");
+		vprintf(fmt, args);
+	}
+	va_end(args);
+
+	printf("\n");
+
+	if (istate) {
+		decode_istate(istate);
+		printf("\n");
+	}
+
+	stack_trace();
+	halt();
+}
+
+/** @}
+ */
