Skip to content

Commit

Permalink
sgi-xp: add usage of GRU driver by xpc_remote_memcpy()
Browse files Browse the repository at this point in the history
Add UV support to xpc_remote_memcpy(), which involves interfacing to the
GRU driver.

Signed-off-by: Dean Nelson <[email protected]>
Cc: Jack Steiner <[email protected]>
Cc: "Luck, Tony" <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Dean Nelson authored and torvalds committed Jul 30, 2008
1 parent 261f3b4 commit a812dcc
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 127 deletions.
8 changes: 6 additions & 2 deletions drivers/misc/sgi-xp/xp.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,9 @@ enum xp_retval {
xpUnsupported, /* 56: unsupported functionality or resource */
xpNeedMoreInfo, /* 57: more info is needed by SAL */

xpUnknownReason /* 58: unknown reason - must be last in enum */
xpGruCopyError, /* 58: gru_copy_gru() returned error */

xpUnknownReason /* 59: unknown reason - must be last in enum */
};

/*
Expand Down Expand Up @@ -349,7 +351,9 @@ extern short xp_max_npartitions;
extern short xp_partition_id;
extern u8 xp_region_size;

extern enum xp_retval (*xp_remote_memcpy) (void *, const void *, size_t);
extern unsigned long (*xp_pa) (void *);
extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
size_t);
extern int (*xp_cpu_to_nasid) (int);

extern u64 xp_nofault_PIOR_target;
Expand Down
6 changes: 5 additions & 1 deletion drivers/misc/sgi-xp/xp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ EXPORT_SYMBOL_GPL(xp_partition_id);
u8 xp_region_size;
EXPORT_SYMBOL_GPL(xp_region_size);

enum xp_retval (*xp_remote_memcpy) (void *dst, const void *src, size_t len);
unsigned long (*xp_pa) (void *addr);
EXPORT_SYMBOL_GPL(xp_pa);

enum xp_retval (*xp_remote_memcpy) (unsigned long dst_gpa,
const unsigned long src_gpa, size_t len);
EXPORT_SYMBOL_GPL(xp_remote_memcpy);

int (*xp_cpu_to_nasid) (int cpuid);
Expand Down
50 changes: 24 additions & 26 deletions drivers/misc/sgi-xp/xp_sn2.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ xp_register_nofault_code_sn2(void)
return xpSuccess;
}

void
static void
xp_unregister_nofault_code_sn2(void)
{
u64 func_addr = *(u64 *)xp_nofault_PIOR;
Expand All @@ -74,45 +74,42 @@ xp_unregister_nofault_code_sn2(void)
err_func_addr, 1, 0);
}

/*
* Convert a virtual memory address to a physical memory address.
*/
static unsigned long
xp_pa_sn2(void *addr)
{
return __pa(addr);
}

/*
* Wrapper for bte_copy().
*
* vdst - virtual address of the destination of the transfer.
* psrc - physical address of the source of the transfer.
* dst_pa - physical address of the destination of the transfer.
* src_pa - 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)
xp_remote_memcpy_sn2(unsigned long dst_pa, const unsigned long src_pa,
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);
ret = bte_copy(src_pa, dst_pa, 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);
if (is_shub2()) {
dev_err(xp, "bte_copy() on shub2 failed, error=0x%x dst_pa="
"0x%016lx src_pa=0x%016lx len=%ld\\n", ret, dst_pa,
src_pa, len);
} else {
dev_err(xp, "bte_copy() failed, error=%d dst_pa=0x%016lx "
"src_pa=0x%016lx len=%ld\\n", ret, dst_pa, src_pa, len);
}

return xpBteCopyError;
}
Expand All @@ -132,6 +129,7 @@ xp_init_sn2(void)
xp_partition_id = sn_partition_id;
xp_region_size = sn_region_size;

xp_pa = xp_pa_sn2;
xp_remote_memcpy = xp_remote_memcpy_sn2;
xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;

Expand Down
27 changes: 24 additions & 3 deletions drivers/misc/sgi-xp/xp_uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,33 @@
*
*/

#include <linux/device.h>
#include <asm/uv/uv_hub.h>
#include "../sgi-gru/grukservices.h"
#include "xp.h"

/*
* Convert a virtual memory address to a physical memory address.
*/
static unsigned long
xp_pa_uv(void *addr)
{
return uv_gpa(addr);
}

static enum xp_retval
xp_remote_memcpy_uv(void *vdst, const void *psrc, size_t len)
xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
size_t len)
{
/* !!! this function needs fleshing out */
return xpUnsupported;
int ret;

ret = gru_copy_gpa(dst_gpa, src_gpa, len);
if (ret == 0)
return xpSuccess;

dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
"len=%ld\n", dst_gpa, src_gpa, len);
return xpGruCopyError;
}

enum xp_retval
Expand All @@ -29,6 +49,7 @@ xp_init_uv(void)

xp_max_npartitions = XP_MAX_NPARTITIONS_UV;

xp_pa = xp_pa_uv;
xp_remote_memcpy = xp_remote_memcpy_uv;

return xpSuccess;
Expand Down
44 changes: 23 additions & 21 deletions drivers/misc/sgi-xp/xpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ struct xpc_rsvd_page {
u8 version;
u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */
union {
u64 vars_pa; /* physical address of struct xpc_vars */
u64 activate_mq_gpa; /* global phys address of activate_mq */
unsigned long vars_pa; /* phys address of struct xpc_vars */
unsigned long activate_mq_gpa; /* gru phy addr of activate_mq */
} sn;
unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
u64 pad2[10]; /* align to last u64 in 2nd 64-byte cacheline */
Expand Down Expand Up @@ -122,8 +122,8 @@ struct xpc_vars_sn2 {
u64 heartbeat_offline; /* if 0, heartbeat should be changing */
int activate_IRQ_nasid;
int activate_IRQ_phys_cpuid;
u64 vars_part_pa;
u64 amos_page_pa; /* paddr of page of amos from MSPEC driver */
unsigned long vars_part_pa;
unsigned long amos_page_pa;/* paddr of page of amos from MSPEC driver */
struct amo *amos_page; /* vaddr of page of amos from MSPEC driver */
};

Expand All @@ -142,10 +142,10 @@ struct xpc_vars_sn2 {
struct xpc_vars_part_sn2 {
u64 magic;

u64 openclose_args_pa; /* physical address of open and close args */
u64 GPs_pa; /* physical address of Get/Put values */
unsigned long openclose_args_pa; /* phys addr of open and close args */
unsigned long GPs_pa; /* physical address of Get/Put values */

u64 chctl_amo_pa; /* physical address of chctl flags' amo */
unsigned long chctl_amo_pa; /* physical address of chctl flags' amo */

int notify_IRQ_nasid; /* nasid of where to send notify IRQs */
int notify_IRQ_phys_cpuid; /* CPUID of where to send notify IRQs */
Expand Down Expand Up @@ -213,7 +213,7 @@ struct xpc_openclose_args {
u16 msg_size; /* sizeof each message entry */
u16 remote_nentries; /* #of message entries in remote msg queue */
u16 local_nentries; /* #of message entries in local msg queue */
u64 local_msgqueue_pa; /* physical address of local message queue */
unsigned long local_msgqueue_pa; /* phys addr of local message queue */
};

#define XPC_OPENCLOSE_ARGS_SIZE \
Expand Down Expand Up @@ -366,8 +366,8 @@ struct xpc_channel {
void *remote_msgqueue_base; /* base address of kmalloc'd space */
struct xpc_msg *remote_msgqueue; /* cached copy of remote partition's */
/* local message queue */
u64 remote_msgqueue_pa; /* phys addr of remote partition's */
/* local message queue */
unsigned long remote_msgqueue_pa; /* phys addr of remote partition's */
/* local message queue */

atomic_t references; /* #of external references to queues */

Expand Down Expand Up @@ -491,23 +491,23 @@ xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
*/

struct xpc_partition_sn2 {
u64 remote_amos_page_pa; /* phys addr of partition's amos page */
unsigned long remote_amos_page_pa; /* paddr of partition's amos page */
int activate_IRQ_nasid; /* active partition's act/deact nasid */
int activate_IRQ_phys_cpuid; /* active part's act/deact phys cpuid */

u64 remote_vars_pa; /* phys addr of partition's vars */
u64 remote_vars_part_pa; /* phys addr of partition's vars part */
unsigned long remote_vars_pa; /* phys addr of partition's vars */
unsigned long remote_vars_part_pa; /* paddr of partition's vars part */
u8 remote_vars_version; /* version# of partition's vars */

void *local_GPs_base; /* base address of kmalloc'd space */
struct xpc_gp_sn2 *local_GPs; /* local Get/Put values */
void *remote_GPs_base; /* base address of kmalloc'd space */
struct xpc_gp_sn2 *remote_GPs; /* copy of remote partition's local */
/* Get/Put values */
u64 remote_GPs_pa; /* phys address of remote partition's local */
/* Get/Put values */
unsigned long remote_GPs_pa; /* phys addr of remote partition's local */
/* Get/Put values */

u64 remote_openclose_args_pa; /* phys addr of remote's args */
unsigned long remote_openclose_args_pa; /* phys addr of remote's args */

int notify_IRQ_nasid; /* nasid of where to send notify IRQs */
int notify_IRQ_phys_cpuid; /* CPUID of where to send notify IRQs */
Expand All @@ -529,7 +529,7 @@ struct xpc_partition {

u8 remote_rp_version; /* version# of partition's rsvd pg */
unsigned long remote_rp_ts_jiffies; /* timestamp when rsvd pg setup */
u64 remote_rp_pa; /* phys addr of partition's rsvd pg */
unsigned long remote_rp_pa; /* phys addr of partition's rsvd pg */
u64 last_heartbeat; /* HB at last read */
u32 activate_IRQ_rcvd; /* IRQs since activation */
spinlock_t act_lock; /* protect updating of act_state */
Expand Down Expand Up @@ -623,7 +623,8 @@ extern void xpc_activate_partition(struct xpc_partition *);
extern void xpc_activate_kthreads(struct xpc_channel *, int);
extern void xpc_create_kthreads(struct xpc_channel *, int, int);
extern void xpc_disconnect_wait(int);
extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (u64, u64 *, u64 *,
extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
unsigned long *,
size_t *);
extern enum xp_retval (*xpc_rsvd_page_init) (struct xpc_rsvd_page *);
extern void (*xpc_heartbeat_init) (void);
Expand All @@ -640,8 +641,8 @@ extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
extern int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *);
extern struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *);
extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *, u64,
int);
extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *,
unsigned long, int);
extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
extern void (*xpc_cancel_partition_deactivation_request) (
Expand Down Expand Up @@ -690,7 +691,8 @@ extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
extern void xpc_mark_partition_inactive(struct xpc_partition *);
extern void xpc_discovery(void);
extern enum xp_retval xpc_get_remote_rp(int, unsigned long *,
struct xpc_rsvd_page *, u64 *);
struct xpc_rsvd_page *,
unsigned long *);
extern void xpc_deactivate_partition(const int, struct xpc_partition *,
enum xp_retval);
extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
Expand Down
5 changes: 2 additions & 3 deletions drivers/misc/sgi-xp/xpc_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,8 @@ xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number,
dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY (local_msgqueue_pa="
"0x%lx, local_nentries=%d, remote_nentries=%d) "
"received from partid=%d, channel=%d\n",
(unsigned long)args->local_msgqueue_pa,
args->local_nentries, args->remote_nentries,
ch->partid, ch->number);
args->local_msgqueue_pa, args->local_nentries,
args->remote_nentries, ch->partid, ch->number);

if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
spin_unlock_irqrestore(&ch->lock, irq_flags);
Expand Down
8 changes: 5 additions & 3 deletions drivers/misc/sgi-xp/xpc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ static struct notifier_block xpc_die_notifier = {
.notifier_call = xpc_system_die,
};

enum xp_retval (*xpc_get_partition_rsvd_page_pa) (u64 buf, u64 *cookie,
u64 *paddr, size_t *len);
enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *buf, u64 *cookie,
unsigned long *rp_pa,
size_t *len);
enum xp_retval (*xpc_rsvd_page_init) (struct xpc_rsvd_page *rp);
void (*xpc_heartbeat_init) (void);
void (*xpc_heartbeat_exit) (void);
Expand All @@ -189,7 +190,8 @@ int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *ch);
struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *ch);

void (*xpc_request_partition_activation) (struct xpc_rsvd_page *remote_rp,
u64 remote_rp_pa, int nasid);
unsigned long remote_rp_pa,
int nasid);
void (*xpc_request_partition_reactivation) (struct xpc_partition *part);
void (*xpc_request_partition_deactivation) (struct xpc_partition *part);
void (*xpc_cancel_partition_deactivation_request) (struct xpc_partition *part);
Expand Down
Loading

0 comments on commit a812dcc

Please sign in to comment.