--- v5
+++ v8
@@ -4,6 +4,14 @@
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
---
+Changelog[v8]:
+ - Update comments (ISA references and some cleanup)
+ - Use 0 or 1 when setting boolean fields with SET_FIELD()
+ - Don't write to spare/unused registers.
+ - Use kernel integer types (u64/u32/s32)
+Changelog[v6]
+ - Add support for FTW windows and drop the fault window id
+ code since it is not needed for FTW/kernel windows.
Changelog[v5]
- Fix: Copy the FIFO address into LFIFO_BAR register as is (don't
shift address into bits 8:53).
@@ -23,15 +31,15 @@
initialized from the HVWC.
- Check winctx->user_win when setting translation registers
---
- arch/powerpc/platforms/powernv/vas-window.c | 306 ++++++++++++++++++++++++++++
+ arch/powerpc/platforms/powernv/vas-window.c | 299 ++++++++++++++++++++++++++++
arch/powerpc/platforms/powernv/vas.h | 55 +++++
- 2 files changed, 361 insertions(+)
+ 2 files changed, 354 insertions(+)
diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c
-index 588aad7..4135ab0 100644
+index 642814a2..68dfe53 100644
--- a/arch/powerpc/platforms/powernv/vas-window.c
+++ b/arch/powerpc/platforms/powernv/vas-window.c
-@@ -11,9 +11,12 @@
+@@ -13,6 +13,7 @@
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/io.h>
@@ -39,12 +47,7 @@
#include "vas.h"
-+static int fault_winid;
-+
- /*
- * Compute the paste address region for the window @window using the
- * ->paste_base_addr and ->paste_win_id_shift we got from device tree.
-@@ -138,6 +141,309 @@ int map_winctx_mmio_bars(struct vas_window *window)
+@@ -186,6 +187,304 @@ int map_winctx_mmio_bars(struct vas_window *window)
return 0;
}
@@ -55,7 +58,7 @@
+ * NOTE: We cannot really use a for loop to reset window context. Not all
+ * offsets in a window context are valid registers and the valid
+ * registers are not sequential. And, we can only write to offsets
-+ * with valid registers (or is that only in Simics?).
++ * with valid registers.
+ */
+void reset_window_regs(struct vas_window *window)
+{
@@ -70,12 +73,6 @@
+ write_hvwc_reg(window, VREG(OSU_INTR_SRC_RA), 0ULL);
+ write_hvwc_reg(window, VREG(HV_INTR_SRC_RA), 0ULL);
+ write_hvwc_reg(window, VREG(PSWID), 0ULL);
-+ write_hvwc_reg(window, VREG(SPARE1), 0ULL);
-+ write_hvwc_reg(window, VREG(SPARE2), 0ULL);
-+ write_hvwc_reg(window, VREG(SPARE3), 0ULL);
-+ write_hvwc_reg(window, VREG(SPARE4), 0ULL);
-+ write_hvwc_reg(window, VREG(SPARE5), 0ULL);
-+ write_hvwc_reg(window, VREG(SPARE6), 0ULL);
+ write_hvwc_reg(window, VREG(LFIFO_BAR), 0ULL);
+ write_hvwc_reg(window, VREG(LDATA_STAMP_CTL), 0ULL);
+ write_hvwc_reg(window, VREG(LDMA_CACHE_CTL), 0ULL);
@@ -121,26 +118,26 @@
+ */
+static void init_xlate_regs(struct vas_window *window, bool user_win)
+{
-+ uint64_t lpcr, val;
++ u64 lpcr, val;
+
+ /*
+ * MSR_TA, MSR_US are false for both kernel and user.
+ * MSR_DR and MSR_PR are false for kernel.
+ */
+ val = 0ULL;
-+ val = SET_FIELD(VAS_XLATE_MSR_HV, val, true);
-+ val = SET_FIELD(VAS_XLATE_MSR_SF, val, true);
++ val = SET_FIELD(VAS_XLATE_MSR_HV, val, 1);
++ val = SET_FIELD(VAS_XLATE_MSR_SF, val, 1);
+ if (user_win) {
-+ val = SET_FIELD(VAS_XLATE_MSR_DR, val, true);
-+ val = SET_FIELD(VAS_XLATE_MSR_PR, val, true);
++ val = SET_FIELD(VAS_XLATE_MSR_DR, val, 1);
++ val = SET_FIELD(VAS_XLATE_MSR_PR, val, 1);
+ }
+ write_hvwc_reg(window, VREG(XLATE_MSR), val);
+
+ lpcr = mfspr(SPRN_LPCR);
+ val = 0ULL;
+ /*
-+ * NOTE: From Section 5.7.6.1 Segment Lookaside Buffer of the
-+ * Power ISA, v2.07, Page size encoding is 0 = 4KB, 5 = 64KB.
++ * NOTE: From Section 5.7.8.1 Segment Lookaside Buffer of the
++ * Power ISA, v3.0B, Page size encoding is 0 = 4KB, 5 = 64KB.
+ *
+ * NOTE: From Section 1.3.1, Address Translation Context of the
+ * Nest MMU Workbook, LPCR_SC should be 0 for Power9.
@@ -208,7 +205,7 @@
+ */
+int init_winctx_regs(struct vas_window *window, struct vas_winctx *winctx)
+{
-+ uint64_t val;
++ u64 val;
+ int fifo_size;
+
+ reset_window_regs(window);
@@ -224,7 +221,7 @@
+ init_xlate_regs(window, winctx->user_win);
+
+ val = 0ULL;
-+ val = SET_FIELD(VAS_FAULT_TX_WIN, val, fault_winid);
++ val = SET_FIELD(VAS_FAULT_TX_WIN, val, 0);
+ write_hvwc_reg(window, VREG(FAULT_TX_WIN), val);
+
+ /* In PowerNV, interrupts go to HV. */
@@ -242,12 +239,12 @@
+ write_hvwc_reg(window, VREG(SPARE2), 0ULL);
+ write_hvwc_reg(window, VREG(SPARE3), 0ULL);
+
-+ /*
++ /*
+ * NOTE: VAS expects the FIFO address to be copied into the LFIFO_BAR
-+ * register as is - do NOT shift the address into VAS_LFIFO_BAR
-+ * bit fields! Ok to set the page migration select fields -
-+ * VAS ignores the lower 10+ bits in the address anyway, because
-+ * the minimum FIFO size is 1K?
++ * register as is - do NOT shift the address into VAS_LFIFO_BAR
++ * bit fields! Ok to set the page migration select fields -
++ * VAS ignores the lower 10+ bits in the address anyway, because
++ * the minimum FIFO size is 1K?
+ *
+ * See also: Design note in function header.
+ */
@@ -261,6 +258,7 @@
+
+ val = 0ULL;
+ val = SET_FIELD(VAS_LDMA_TYPE, val, winctx->dma_type);
++ val = SET_FIELD(VAS_LDMA_FIFO_DISABLE, val, winctx->fifo_disable);
+ write_hvwc_reg(window, VREG(LDMA_CACHE_CTL), val);
+
+ write_hvwc_reg(window, VREG(LRFIFO_PUSH), 0ULL);
@@ -355,7 +353,7 @@
int vas_win_close(struct vas_window *window)
{
diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h
-index 12c6380..895bdec 100644
+index 650805d..60a3c3c 100644
--- a/arch/powerpc/platforms/powernv/vas.h
+++ b/arch/powerpc/platforms/powernv/vas.h
@@ -12,6 +12,7 @@
@@ -366,8 +364,8 @@
/*
* Overview of Virtual Accelerator Switchboard (VAS).
-@@ -382,4 +383,58 @@ struct vas_winctx {
- extern bool vas_initialized(void);
+@@ -381,4 +382,58 @@ struct vas_winctx {
+
extern struct vas_instance *find_vas_instance(int vasid);
+/*
@@ -380,9 +378,9 @@
+#define VREG_SFX(n, s) __stringify(n), VAS_##n##s
+#define VREG(r) VREG_SFX(r, _OFFSET)
+
-+#ifndef vas_debug
++#ifdef vas_debug
+static inline void vas_log_write(struct vas_window *win, char *name,
-+ void *regptr, uint64_t val)
++ void *regptr, u64 val)
+{
+ if (val)
+ pr_err("%swin #%d: %s reg %p, val 0x%016llx\n",
@@ -397,7 +395,7 @@
+#endif /* vas_debug */
+
+static inline void write_uwc_reg(struct vas_window *win, char *name,
-+ int32_t reg, uint64_t val)
++ s32 reg, u64 val)
+{
+ void *regptr;
+
@@ -408,7 +406,7 @@
+}
+
+static inline void write_hvwc_reg(struct vas_window *win, char *name,
-+ int32_t reg, uint64_t val)
++ s32 reg, u64 val)
+{
+ void *regptr;
+
@@ -418,8 +416,8 @@
+ out_be64(regptr, val);
+}
+
-+static inline uint64_t read_hvwc_reg(struct vas_window *win,
-+ char *name __maybe_unused, int32_t reg)
++static inline u64 read_hvwc_reg(struct vas_window *win,
++ char *name __maybe_unused, s32 reg)
+{
+ return in_be64(win->hvwc_map+reg);
+}