Commit 2392c8c8 authored by Sukadev Bhattiprolu's avatar Sukadev Bhattiprolu Committed by Michael Ellerman

powerpc/powernv/vas: Define copy/paste interfaces

Define interfaces (wrappers) to the 'copy' and 'paste'
instructions (which are new in PowerISA 3.0). These are intended to be
used to by NX driver(s) to submit Coprocessor Request Blocks (CRBs) to
the NX hardware engines.
Signed-off-by: default avatarSukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 5239af67
...@@ -6434,6 +6434,7 @@ M: Sukadev Bhattiprolu ...@@ -6434,6 +6434,7 @@ M: Sukadev Bhattiprolu
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
S: Supported S: Supported
F: arch/powerpc/platforms/powernv/vas* F: arch/powerpc/platforms/powernv/vas*
F: arch/powerpc/platforms/powernv/copy-paste.h
F: arch/powerpc/include/asm/vas.h F: arch/powerpc/include/asm/vas.h
F: arch/powerpc/include/uapi/asm/vas.h F: arch/powerpc/include/uapi/asm/vas.h
......
...@@ -418,6 +418,8 @@ ...@@ -418,6 +418,8 @@
___PPC_RB(b)) ___PPC_RB(b))
#define PPC_MSGCLRP(b) stringify_in_c(.long PPC_INST_MSGCLRP | \ #define PPC_MSGCLRP(b) stringify_in_c(.long PPC_INST_MSGCLRP | \
___PPC_RB(b)) ___PPC_RB(b))
#define PPC_PASTE(a, b) stringify_in_c(.long PPC_INST_PASTE | \
___PPC_RA(a) | ___PPC_RB(b))
#define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \ #define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \
__PPC_RA(a) | __PPC_RS(s)) __PPC_RA(a) | __PPC_RS(s))
#define PPC_POPCNTD(a, s) stringify_in_c(.long PPC_INST_POPCNTD | \ #define PPC_POPCNTD(a, s) stringify_in_c(.long PPC_INST_POPCNTD | \
......
...@@ -144,4 +144,16 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, ...@@ -144,4 +144,16 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
*/ */
int vas_win_close(struct vas_window *win); int vas_win_close(struct vas_window *win);
/*
* Copy the co-processor request block (CRB) @crb into the local L2 cache.
*/
int vas_copy_crb(void *crb, int offset);
/*
* Paste a previously copied CRB (see vas_copy_crb()) from the L2 cache to
* the hardware address associated with the window @win. @re is expected/
* assumed to be true for NX windows.
*/
int vas_paste_crb(struct vas_window *win, int offset, bool re);
#endif /* __ASM_POWERPC_VAS_H */ #endif /* __ASM_POWERPC_VAS_H */
/*
* Copyright 2016-17 IBM Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <asm/ppc-opcode.h>
#define CR0_SHIFT 28
#define CR0_MASK 0xF
/*
* Copy/paste instructions:
*
* copy RA,RB
* Copy contents of address (RA) + effective_address(RB)
* to internal copy-buffer.
*
* paste RA,RB
* Paste contents of internal copy-buffer to the address
* (RA) + effective_address(RB)
*/
static inline int vas_copy(void *crb, int offset)
{
asm volatile(PPC_COPY(%0, %1)";"
:
: "b" (offset), "b" (crb)
: "memory");
return 0;
}
static inline int vas_paste(void *paste_address, int offset)
{
u32 cr;
cr = 0;
asm volatile(PPC_PASTE(%1, %2)";"
"mfocrf %0, 0x80;"
: "=r" (cr)
: "b" (offset), "b" (paste_address)
: "memory", "cr0");
return (cr >> CR0_SHIFT) & CR0_MASK;
}
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/cred.h> #include <linux/cred.h>
#include "vas.h" #include "vas.h"
#include "copy-paste.h"
/* /*
* Compute the paste address region for the window @window using the * Compute the paste address region for the window @window using the
...@@ -997,6 +998,52 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, ...@@ -997,6 +998,52 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
} }
EXPORT_SYMBOL_GPL(vas_tx_win_open); EXPORT_SYMBOL_GPL(vas_tx_win_open);
int vas_copy_crb(void *crb, int offset)
{
return vas_copy(crb, offset);
}
EXPORT_SYMBOL_GPL(vas_copy_crb);
#define RMA_LSMP_REPORT_ENABLE PPC_BIT(53)
int vas_paste_crb(struct vas_window *txwin, int offset, bool re)
{
int rc;
void *addr;
uint64_t val;
/*
* Only NX windows are supported for now and hardware assumes
* report-enable flag is set for NX windows. Ensure software
* complies too.
*/
WARN_ON_ONCE(txwin->nx_win && !re);
addr = txwin->paste_kaddr;
if (re) {
/*
* Set the REPORT_ENABLE bit (equivalent to writing
* to 1K offset of the paste address)
*/
val = SET_FIELD(RMA_LSMP_REPORT_ENABLE, 0ULL, 1);
addr += val;
}
/*
* Map the raw CR value from vas_paste() to an error code (there
* is just pass or fail for now though).
*/
rc = vas_paste(addr, offset);
if (rc == 2)
rc = 0;
else
rc = -EINVAL;
print_fifo_msg_count(txwin);
return rc;
}
EXPORT_SYMBOL_GPL(vas_paste_crb);
static void poll_window_busy_state(struct vas_window *window) static void poll_window_busy_state(struct vas_window *window)
{ {
int busy; int busy;
......
...@@ -398,11 +398,11 @@ extern struct vas_instance *find_vas_instance(int vasid); ...@@ -398,11 +398,11 @@ extern struct vas_instance *find_vas_instance(int vasid);
#ifdef vas_debug #ifdef vas_debug
static inline void dump_rx_win_attr(struct vas_rx_win_attr *attr) static inline void dump_rx_win_attr(struct vas_rx_win_attr *attr)
{ {
pr_err("VAS: fault %d, notify %d, intr %d early %d\n", pr_err("fault %d, notify %d, intr %d early %d\n",
attr->fault_win, attr->notify_disable, attr->fault_win, attr->notify_disable,
attr->intr_disable, attr->notify_early); attr->intr_disable, attr->notify_early);
pr_err("VAS: rx_fifo_size %d, max value %d\n", pr_err("rx_fifo_size %d, max value %d\n",
attr->rx_fifo_size, VAS_RX_FIFO_SIZE_MAX); attr->rx_fifo_size, VAS_RX_FIFO_SIZE_MAX);
} }
...@@ -450,4 +450,18 @@ static inline u64 read_hvwc_reg(struct vas_window *win, ...@@ -450,4 +450,18 @@ static inline u64 read_hvwc_reg(struct vas_window *win,
return in_be64(win->hvwc_map+reg); return in_be64(win->hvwc_map+reg);
} }
#ifdef vas_debug
static void print_fifo_msg_count(struct vas_window *txwin)
{
uint64_t read_hvwc_reg(struct vas_window *w, char *n, uint64_t o);
pr_devel("Winid %d, Msg count %llu\n", txwin->winid,
(uint64_t)read_hvwc_reg(txwin, VREG(LRFIFO_PUSH)));
}
#else /* vas_debug */
#define print_fifo_msg_count(window)
#endif /* vas_debug */
#endif /* _VAS_H */ #endif /* _VAS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment