[BACK]Return to kdb.h CVS log [TXT][DIR] Up to [Development] / linux-2.6-xfs / include / asm-ia64

File: [Development] / linux-2.6-xfs / include / asm-ia64 / Attic / kdb.h (download)

Revision 1.5, Tue Dec 20 14:26:22 2005 UTC (11 years, 9 months ago) by nathans.longdrop.melbourne.sgi.com
Branch: MAIN
Changes since 1.4: +0 -0 lines

Merge up to 2.6.15-rc6
Merge of 2.6.x-xfs-melb:linux:24891a by kenmcd.

#ifndef _ASM_KDB_H
#define _ASM_KDB_H

/*
 * Kernel Debugger Architecture Dependent Global Headers
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
 */

/*
 * KDB_ENTER() is a macro which causes entry into the kernel
 * debugger from any point in the kernel code stream.  If it
 * is intended to be used from interrupt level, it must use
 * a non-maskable entry method.
 */
#include <asm/kdb_break.h>		/* break numbers are separated for CONFIG_KDB_LOCK */
#define __KDB_ENTER2(b)	asm("\tbreak.m "#b"\n")
#define __KDB_ENTER1(b)	__KDB_ENTER2(b)
#define KDB_ENTER()		do {if (kdb_on && !KDB_IS_RUNNING()) { __KDB_ENTER1(KDB_BREAK_ENTER); }} while(0)
#define KDB_ENTER_SLAVE()	do {if (kdb_on) { __KDB_ENTER1(KDB_BREAK_ENTER_SLAVE); }} while(0)

	/*
	 * Needed for exported symbols.
	 */
typedef unsigned long kdb_machreg_t;

#define kdb_machreg_fmt		"0x%lx"
#define kdb_machreg_fmt0	"0x%016lx"
#define kdb_bfd_vma_fmt		"0x%lx"
#define kdb_bfd_vma_fmt0	"0x%016lx"
#define kdb_elfw_addr_fmt	"0x%lx"
#define kdb_elfw_addr_fmt0	"0x%016lx"

/*
 * Functions to safely read and write kernel areas.  The {to,from}_xxx
 * addresses are not necessarily valid, these functions must check for
 * validity.  If the arch already supports get and put routines with
 * suitable validation and/or recovery on invalid addresses then use
 * those routines, otherwise check it yourself.
 */

/*
 * asm-ia64 uaccess.h supplies __copy_to_user which relies on MMU to
 * trap invalid addresses in the _xxx fields.  Verify the other address
 * of the pair is valid by accessing the first and last byte ourselves,
 * then any access violations should only be caused by the _xxx
 * addresses,
 */

#include <asm/uaccess.h>

static inline int
__kdba_putarea_size(unsigned long to_xxx, void *from, size_t size)
{
	mm_segment_t oldfs = get_fs();
	int r;
	char c;
	c = *((volatile char *)from);
	c = *((volatile char *)from + size - 1);

	if (to_xxx >> 61 <= 4) {
		return kdb_putuserarea_size(to_xxx, from, size);
	}

#ifdef VPERNODE_BASE /* if present, the new CONFIG_NUMA code */
	if (to_xxx >= VPERNODE_BASE && to_xxx < VGLOBAL_BASE) {
		to_xxx = ia64_imva(to_xxx);
	}
#endif
	set_fs(KERNEL_DS);
	r = __copy_to_user_inatomic((void *)to_xxx, from, size);
	set_fs(oldfs);
	return r;
}

static inline int
__kdba_getarea_size(void *to, unsigned long from_xxx, size_t size)
{
	mm_segment_t oldfs = get_fs();
	int r;
	*((volatile char *)to) = '\0';
	*((volatile char *)to + size - 1) = '\0';

	if (from_xxx >> 61 <= 4) {
		return kdb_getuserarea_size(to, from_xxx, size);
	}

	set_fs(KERNEL_DS);
	switch (size) {
	case 1:
		r = __copy_to_user_inatomic(to, (void *)from_xxx, 1);
		break;
	case 2:
		r = __copy_to_user_inatomic(to, (void *)from_xxx, 2);
		break;
	case 4:
		r = __copy_to_user_inatomic(to, (void *)from_xxx, 4);
		break;
	case 8:
		r = __copy_to_user_inatomic(to, (void *)from_xxx, 8);
		break;
	default:
		r = __copy_to_user_inatomic(to, (void *)from_xxx, size);
		break;
	}
	set_fs(oldfs);
	return r;
}

/* For numa with replicated code/data, the platform must supply its own
 * kdba_putarea_size and kdba_getarea_size routines.  Without replication kdb
 * uses the standard architecture routines.
 */
#ifdef CONFIG_NUMA_REPLICATE
extern int kdba_putarea_size(unsigned long to_xxx, void *from, size_t size);
extern int kdba_getarea_size(void *to, unsigned long from_xxx, size_t size);
#else
#define kdba_putarea_size __kdba_putarea_size
#define kdba_getarea_size __kdba_getarea_size
#endif

static inline int
kdba_verify_rw(unsigned long addr, size_t size)
{
	unsigned char data[size];
	return(kdba_getarea_size(data, addr, size) || kdba_putarea_size(addr, data, size));
}

static inline unsigned long
kdba_funcptr_value(void *fp)
{
	/* ia64 function descriptor, first word is address of code */
	return *(unsigned long *)fp;
}

#endif	/* !_ASM_KDB_H */