patch-2.2.16 linux/arch/s390/kernel/debug.c
Next file: linux/arch/s390/kernel/debug.h
Previous file: linux/arch/s390/kernel/cpcmd.c
Back to the patch index
Back to the overall index
- Lines: 284
- Date:
Wed Jun 7 14:26:42 2000
- Orig file:
v2.2.15/linux/arch/s390/kernel/debug.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -urN v2.2.15/linux/arch/s390/kernel/debug.c linux/arch/s390/kernel/debug.c
@@ -0,0 +1,283 @@
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/malloc.h>
+#include <asm/ebcdic.h>
+
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
+#include <asm/ebcdic.h>
+
+#include "debug.h"
+
+debug_info_t debug_areas[MAX_DEBUG_AREAS];
+debug_info_t *free_area = 0;
+static int initialized = 0;
+
+static spinlock_t debug_lock = SPIN_LOCK_UNLOCKED;
+
+debug_info_t *
+debug_register (char *name, int page_order, int nr_areas)
+{
+ debug_info_t *rc = 0;
+ int i;
+ long flags;
+
+ if ( ! initialized ){
+ debug_init();
+ initialized = 1;
+ }
+ if (!free_area)
+ {
+ printk (KERN_WARNING "No free debug area\n");
+ return NULL;
+ }
+ spin_lock_irqsave (&debug_lock, flags);
+ rc = free_area;
+ free_area = *((debug_info_t **) rc);
+
+ rc->areas = (debug_entry_t **) kmalloc (nr_areas *
+ sizeof (debug_entry_t *),
+ GFP_ATOMIC);
+ if (!rc->areas)
+ {
+ goto noareas;
+ }
+
+ for (i = 0; i < nr_areas; i++)
+ {
+ rc->areas[i] = (debug_entry_t *) __get_free_pages (GFP_ATOMIC,
+ page_order);
+ if (!rc->areas[i])
+ {
+ for (i--; i >= 0; i--)
+ {
+ free_pages ((unsigned long) rc->areas[i], page_order);
+ }
+ goto nopages;
+ }
+ }
+
+ rc->page_order = page_order;
+ rc->nr_areas = nr_areas;
+ rc->name = kmalloc (strlen (name) + 1, GFP_ATOMIC);
+ strncpy (rc->name, name, strlen (name));
+ rc->name[strlen (name)] = 0;
+ rc->active_entry = kmalloc (nr_areas, GFP_ATOMIC);
+ memset(rc->active_entry, 0, nr_areas * sizeof(int));
+ printk (KERN_INFO "reserved %d areas of %d pages for debugging %s\n",
+ nr_areas, 1 << page_order, name);
+ goto exit;
+
+nopages:
+noareas:
+ free_area = rc;
+exit:
+ spin_unlock_irqrestore (&debug_lock, flags);
+ return rc;
+}
+
+void
+debug_unregister (debug_info_t * id, char *name)
+{
+ int i = id->nr_areas;
+ long flags;
+ spin_lock_irqsave (&debug_lock, flags);
+ printk (KERN_INFO "freeing debug area %p named '%s'\n", id, name);
+ if (strncmp (name, id->name, strlen (name)))
+ {
+ printk (KERN_ERR "name '%s' does not match against '%s'\n",
+ name, id->name);
+ }
+ for (i--; i >= 0; i--)
+ {
+ free_pages ((unsigned long) id->areas[i], id->page_order);
+ }
+ kfree (id->areas);
+ kfree (id->name);
+ *((debug_info_t **) id) = free_area;
+ free_area = id;
+ spin_unlock_irqrestore (&debug_lock, flags);
+ return;
+}
+
+static inline void
+proceed_active_entry (debug_info_t * id)
+{
+ id->active_entry[id->active_area] =
+ (id->active_entry[id->active_area]++) %
+ ((PAGE_SIZE / sizeof (debug_entry_t)) << (id->page_order));
+}
+
+static inline void
+proceed_active_area (debug_info_t * id)
+{
+ id->active_area = (id->active_area++) % id->nr_areas;
+}
+
+static inline debug_entry_t *
+get_active_entry (debug_info_t * id)
+{
+ return &id->areas[id->active_area][id->active_entry[id->active_area]];
+}
+
+static inline debug_entry_t *
+debug_common ( debug_info_t * id )
+{
+ debug_entry_t * active;
+ proceed_active_entry (id);
+ active = get_active_entry (id);
+ STCK (active->id.stck);
+ active->id.stck = active->id.stck >> 4;
+ active->id.fields.cpuid = smp_processor_id ();
+ active->caller = __builtin_return_address (0);
+ return active;
+}
+
+void
+debug_event (debug_info_t * id, int level, unsigned int tag)
+{
+ long flags;
+ debug_entry_t *active;
+ if (!id)
+ {
+ return;
+ }
+ if (level < id->level)
+ {
+ return;
+ }
+ spin_lock_irqsave (&id->lock, flags);
+ active = debug_common(id);
+ active->tag.tag = tag;
+ spin_unlock_irqrestore (&id->lock, flags);
+ return;
+}
+
+void
+debug_text_event (debug_info_t * id, int level, char tag[4])
+{
+ long flags;
+ debug_entry_t *active;
+ if (!id)
+ {
+ return;
+ }
+ if (level < id->level)
+ {
+ return;
+ }
+ spin_lock_irqsave (&id->lock, flags);
+ active = debug_common(id);
+ strncpy ( active->tag.text, tag, 4);
+ ASCEBC (active->tag.text, 4 );
+ spin_unlock_irqrestore (&id->lock, flags);
+ return;
+}
+
+void
+debug_exception (debug_info_t * id, int level, unsigned int tag)
+{
+ long flags;
+ debug_entry_t *active;
+ if (!id)
+ {
+ return;
+ }
+ if (level < id->level)
+ {
+ return;
+ }
+ spin_lock_irqsave (&id->lock, flags);
+ active = debug_common(id);
+ active->tag.tag = tag;
+ proceed_active_area (id);
+ spin_unlock_irqrestore (&id->lock, flags);
+
+ return;
+}
+
+void
+debug_text_exception (debug_info_t * id, int level, char tag[4])
+{
+ long flags;
+ debug_entry_t *active;
+ if (!id)
+ {
+ return;
+ }
+ if (level < id->level)
+ {
+ return;
+ }
+ spin_lock_irqsave (&id->lock, flags);
+ active = debug_common(id);
+ strncpy ( active->tag.text, tag, 4);
+ ASCEBC (active->tag.text, 4 );
+ proceed_active_area (id);
+ spin_unlock_irqrestore (&id->lock, flags);
+ return;
+}
+
+int
+debug_init (void)
+{
+ int rc = 0;
+ int i;
+ for (i = 0; i < MAX_DEBUG_AREAS - 1; i++)
+ {
+ *(debug_info_t **) (&debug_areas[i]) =
+ (debug_info_t *) (&debug_areas[i + 1]);
+ }
+ *(debug_info_t **) (&debug_areas[i]) = (debug_info_t *) NULL;
+ free_area = &(debug_areas[0]);
+ printk (KERN_INFO "%d areas reserved for debugging information\n",
+ MAX_DEBUG_AREAS);
+ return rc;
+}
+
+#ifdef MODULE
+int
+init_module (void)
+{
+ int rc = 0;
+ rc = debug_init ();
+ if (rc)
+ {
+ printk (KERN_INFO "An error occurred with debug_init\n");
+ }
+
+ { /* test section */
+ debug_info_t *a[4];
+ printk (KERN_INFO "registering 1, %p\n", a[0] =
+ debug_register ("debug1", 1, 1));
+ printk (KERN_INFO "registering 2, %p\n", a[1] =
+ debug_register ("debug2", 1, 2));
+ printk (KERN_INFO "registering 3, %p\n", a[2] =
+ debug_register ("debug3", 2, 1));
+ printk (KERN_INFO "registering 4, %p\n", a[3] =
+ debug_register ("debug4", 2, 2));
+ debug_unregister (a[0], "debug1");
+ debug_unregister (a[1], "debug3");
+ printk (KERN_INFO "registering 1, %p\n", a[0] =
+ debug_register ("debug5", 1, 1));
+ printk (KERN_INFO "registering 2, %p\n", a[1] =
+ debug_register ("debug6", 1, 2));
+ debug_unregister (a[2], "debug2");
+ debug_unregister (a[3], "debug4");
+ debug_unregister (a[0], "debug5");
+ debug_unregister (a[1], "debug6");
+ }
+ return rc;
+}
+
+void
+cleanup_module (void)
+{
+
+ return;
+}
+
+#endif /* MODULE */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)