Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 908787db authored by Dean Nelson's avatar Dean Nelson Committed by Linus Torvalds
Browse files

sgi-xp: create a common xp_remote_memcpy() function



Create a common remote memcpy function that maps to what the hardware
booted supports.

Signed-off-by: default avatarDean Nelson <dcn@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent bc63d387
Loading
Loading
Loading
Loading
+2 −41
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
#include <linux/hardirq.h>
#include <linux/mutex.h>
#include <asm/sn/types.h>
#include <asm/sn/bte.h>
#ifdef CONFIG_IA64
#include <asm/sn/arch.h>
#endif
@@ -71,46 +70,6 @@
#define XP_NASID_MASK_BYTES	((XP_MAX_PHYSNODE_ID + 7) / 8)
#define XP_NASID_MASK_WORDS	((XP_MAX_PHYSNODE_ID + 63) / 64)

/*
 * Wrapper for bte_copy() that should it return a failure status will retry
 * the bte_copy() once in the hope that the failure was due to a temporary
 * aberration (i.e., the link going down temporarily).
 *
 * 	src - physical address of the source of the transfer.
 *	vdst - virtual address of the destination of the transfer.
 *	len - number of bytes to transfer from source to destination.
 *	mode - see bte_copy() for definition.
 *	notification - see bte_copy() for definition.
 *
 * Note: xp_bte_copy() should never be called while holding a spinlock.
 */
static inline bte_result_t
xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
{
	bte_result_t ret;
	u64 pdst = ia64_tpa(vdst);

	/*
	 * Ensure that the physically mapped memory is contiguous.
	 *
	 * We do this by ensuring that the memory is from region 7 only.
	 * If the need should arise to use memory from one of the other
	 * regions, then modify the BUG_ON() statement to ensure that the
	 * memory from that region is always physically contiguous.
	 */
	BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL);

	ret = bte_copy(src, pdst, len, mode, notification);
	if ((ret != BTE_SUCCESS) && BTE_ERROR_RETRY(ret)) {
		if (!in_interrupt())
			cond_resched();

		ret = bte_copy(src, pdst, len, mode, notification);
	}

	return ret;
}

/*
 * XPC establishes channel connections between the local partition and any
 * other partition that is currently up. Over these channels, kernel-level
@@ -408,6 +367,8 @@ xpc_partid_to_nasids(short partid, void *nasids)

extern short xp_max_npartitions;

extern enum xp_retval (*xp_remote_memcpy) (void *, const void *, size_t);

extern u64 xp_nofault_PIOR_target;
extern int xp_nofault_PIOR(void *);
extern int xp_error_PIOR(void);
+3 −0
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@ struct device *xp = &xp_dbg_subname;
short xp_max_npartitions;
EXPORT_SYMBOL_GPL(xp_max_npartitions);

enum xp_retval (*xp_remote_memcpy) (void *dst, const void *src, size_t len);
EXPORT_SYMBOL_GPL(xp_remote_memcpy);

/*
 * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
 * users of XPC.
+46 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
 */

#include <linux/device.h>
#include <asm/sn/bte.h>
#include <asm/sn/sn_sal.h>
#include "xp.h"

@@ -72,6 +73,49 @@ xp_unregister_nofault_code_sn2(void)
				       err_func_addr, 1, 0);
}

/*
 * Wrapper for bte_copy().
 *
 *	vdst - virtual address of the destination of the transfer.
 *	psrc - physical address of the source of the transfer.
 *	len - number of bytes to transfer from source to destination.
 *
 * Note: xp_remote_memcpy_sn2() should never be called while holding a spinlock.
 */
static enum xp_retval
xp_remote_memcpy_sn2(void *vdst, const void *psrc, size_t len)
{
	bte_result_t ret;
	u64 pdst = ia64_tpa(vdst);
	/* >>> What are the rules governing the src and dst addresses passed in?
	 * >>> Currently we're assuming that dst is a virtual address and src
	 * >>> is a physical address, is this appropriate? Can we allow them to
	 * >>> be whatever and we make the change here without damaging the
	 * >>> addresses?
	 */

	/*
	 * Ensure that the physically mapped memory is contiguous.
	 *
	 * We do this by ensuring that the memory is from region 7 only.
	 * If the need should arise to use memory from one of the other
	 * regions, then modify the BUG_ON() statement to ensure that the
	 * memory from that region is always physically contiguous.
	 */
	BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL);

	ret = bte_copy((u64)psrc, pdst, len, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
	if (ret == BTE_SUCCESS)
		return xpSuccess;

	if (is_shub2())
		dev_err(xp, "bte_copy() on shub2 failed, error=0x%x\n", ret);
	else
		dev_err(xp, "bte_copy() failed, error=%d\n", ret);

	return xpBteCopyError;
}

enum xp_retval
xp_init_sn2(void)
{
@@ -79,6 +123,8 @@ xp_init_sn2(void)

	xp_max_npartitions = XP_MAX_NPARTITIONS_SN2;

	xp_remote_memcpy = xp_remote_memcpy_sn2;

	return xp_register_nofault_code_sn2();
}

+11 −0
Original line number Diff line number Diff line
@@ -15,12 +15,23 @@

#include "xp.h"

static enum xp_retval
xp_remote_memcpy_uv(void *vdst, const void *psrc, size_t len)
{
	/* >>> this function needs fleshing out */
	return xpUnsupported;
}

enum xp_retval
xp_init_uv(void)
{
	BUG_ON(!is_uv());

	xp_max_npartitions = XP_MAX_NPARTITIONS_UV;

	xp_remote_memcpy = xp_remote_memcpy_uv;

	return xpSuccess;
}

void
+0 −7
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@
#include <linux/completion.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/sn/bte.h>
#include <asm/sn/clksupport.h>
#include <asm/sn/addrs.h>
#include <asm/sn/mspec.h>
@@ -1125,12 +1124,6 @@ xpc_IPI_init(int index)
	return amo;
}

static inline enum xp_retval
xpc_map_bte_errors(bte_result_t error)
{
	return ((error == BTE_SUCCESS) ? xpSuccess : xpBteCopyError);
}

/*
 * Check to see if there is any channel activity to/from the specified
 * partition.
Loading