Re: [PATCH v3 05/10] VAS: Define helpers to init window context
> > > + val = 0ULL; > > > + if (user_win) { > > > + val = SET_FIELD(VAS_XLATE_MSR_DR, val, true); > > > + val = SET_FIELD(VAS_XLATE_MSR_TA, val, false); > > > + val = SET_FIELD(VAS_XLATE_MSR_PR, val, true); > > > + val = SET_FIELD(VAS_XLATE_MSR_US, val, false); > > > + val = SET_FIELD(VAS_XLATE_MSR_HV, val, true); > > > + val = SET_FIELD(VAS_XLATE_MSR_SF, val, true); > > > + val = SET_FIELD(VAS_XLATE_MSR_UV, val, false); > > > + } else { > > > + val = SET_FIELD(VAS_XLATE_MSR_DR, val, false); > > > > kernel contexts don't go through the nestmmu? > > I think so, but will check with Alistair/Ben. Well it's kinda up to you. Do you want to use the kernel mapping or not? I probably would unless there are issues. Mikey
Re: [PATCH v3 05/10] VAS: Define helpers to init window context
Michael Neuling [mi...@neuling.org] wrote: > On Thu, 2017-03-16 at 20:33 -0700, Sukadev Bhattiprolu wrote: > > #ifdef CONFIG_PPC_4K_PAGES > > @@ -336,9 +337,6 @@ struct vas_window { > > /* Feilds applicable only to receive windows */ > > enum vas_cop_type cop; > > atomic_t num_txwins; > > - > > - int32_t hwirq; > > - uint64_t irq_port; > > We are removing things already? :-) :-) They are needed when we add support for user windows will remove them in the earlier patch. > > > }; > > > > /* > > @@ -392,4 +390,59 @@ struct vas_winctx { > > extern int vas_initialized; > > extern int vas_window_reset(struct vas_instance *vinst, int winid); > > extern struct vas_instance *find_vas_instance(int vasid); > > + > > +/* > > + * VREG(x): > > + * Expand a register's short name (eg: LPID) into two parameters: > > + * - the register's short name in string form ("LPID"), and > > + * - the name of the macro (eg: VAS_LPID_OFFSET), defining the > > + * register's offset in the window context > > + */ > > +#define VREG_SFX(n, s) __stringify(n), VAS_##n##s > > +#define VREG(r)VREG_SFX(r, _OFFSET) > > + > > +#ifndef vas_debug > > +static inline void vas_log_write(struct vas_window *win, char *name, > > + void *regptr, uint64_t val) > > +{ > > + if (val) > > + pr_err("%swin #%d: %s reg %p, val 0x%llx\n", > > + win->tx_win ? "Tx" : "Rx", win->winid, name, > > + regptr, val); > > +} > > + > > +#else /* vas_debug */ > > + > > +#define vas_log_write(win, name, reg, val) > > + > > +#endif /* vas_debug */ > > + > > +static inline void write_uwc_reg(struct vas_window *win, char *name, > > + int32_t reg, uint64_t val) > > +{ > > + void *regptr; > > + > > + regptr = win->uwc_map + reg; > > + vas_log_write(win, name, regptr, val); > > + > > + out_be64(regptr, val); > > +} > > + > > +static inline void write_hvwc_reg(struct vas_window *win, char *name, > > + int32_t reg, uint64_t val) > > +{ > > + void *regptr; > > + > > + regptr = win->hvwc_map + reg; > > + vas_log_write(win, name, regptr, val); > > + > > + out_be64(regptr, val); > > +} > > + > > +static inline uint64_t read_hvwc_reg(struct vas_window *win, > > + char *name __maybe_unused, int32_t reg) > > +{ > > + return in_be64(win->hvwc_map+reg); > > +} > > + > > #endif > > diff --git a/drivers/misc/vas/vas-window.c b/drivers/misc/vas/vas-window.c > > index 32dd1d0..edf5c9f 100644 > > --- a/drivers/misc/vas/vas-window.c > > +++ b/drivers/misc/vas/vas-window.c > > @@ -14,6 +14,8 @@ > > #include > > #include "vas-internal.h" > > > > +static int fault_winid; > > + > > /* > > * Compute the paste address region for the window @window using the > > * ->win_base_addr and ->win_id_shift we got from device tree. > > @@ -138,6 +140,338 @@ int map_wc_mmio_bars(struct vas_window *window) > > return 0; > > } > > > > +/* > > + * Reset all valid registers in the HV and OS/User Window Contexts for > > + * the window identified by @window. > > + * > > + * 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?). > > + */ > > +void reset_window_regs(struct vas_window *window) > > +{ > > + write_hvwc_reg(window, VREG(LPID), 0ULL); > > + write_hvwc_reg(window, VREG(PID), 0ULL); > > + write_hvwc_reg(window, VREG(XLATE_MSR), 0ULL); > > + write_hvwc_reg(window, VREG(XLATE_LPCR), 0ULL); > > + write_hvwc_reg(window, VREG(XLATE_CTL), 0ULL); > > + write_hvwc_reg(window, VREG(AMR), 0ULL); > > + write_hvwc_reg(window, VREG(SEIDR), 0ULL); > > + write_hvwc_reg(window, VREG(FAULT_TX_WIN), 0ULL); > > + 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); > > + write_hvwc_reg(window, VREG(LRFIFO_PUSH), 0ULL); > > + write_hvwc_reg(window, VREG(CURR_MSG_COUNT), 0ULL); > > + write_hvwc_reg(window, VREG(LNOTIFY_AFTER_COUNT), 0ULL); > > + write_hvwc_reg(window, VREG(LRX_WCRED), 0ULL); > > + write_hvwc_reg(window, VREG(LRX_WCRED_ADDER), 0ULL); > > + write_hvwc_reg(window, VREG(TX_WCRED), 0ULL); > > + write_hvwc_reg(window, VREG(TX_WCRED_ADDER), 0ULL); > > + write_hvwc
Re: [PATCH v3 05/10] VAS: Define helpers to init window context
On Thu, 2017-03-16 at 20:33 -0700, Sukadev Bhattiprolu wrote: > Define helpers to initialize window context registers of the VAS > hardware. These will be used in follow-on patches when opening/closing > VAS windows. > > Signed-off-by: Sukadev Bhattiprolu > --- > Changelog[v3] > - Have caller, rather than init_xlate_regs() reset window regs > so we don't reset any settings caller may already have set. > - Translation mode should be 0x3 (0b11) not 0x11. > - Skip initilaizing read-only registers NX_UTIL and NX_UTIL_SE > - Skip initializing adder registers from UWC - they are already > initialized from the HVWC. > - Check winctx->user_win when setting translation registers > --- > drivers/misc/vas/vas-internal.h | 59 ++- > drivers/misc/vas/vas-window.c | 334 > > 2 files changed, 390 insertions(+), 3 deletions(-) > > diff --git a/drivers/misc/vas/vas-internal.h b/drivers/misc/vas/vas-internal.h > index 15b62e0..8e721df 100644 > --- a/drivers/misc/vas/vas-internal.h > +++ b/drivers/misc/vas/vas-internal.h > @@ -11,6 +11,7 @@ > #define VAS_INTERNAL_H > #include > #include > +#include > #include > > #ifdef CONFIG_PPC_4K_PAGES > @@ -336,9 +337,6 @@ struct vas_window { > /* Feilds applicable only to receive windows */ > enum vas_cop_type cop; > atomic_t num_txwins; > - > - int32_t hwirq; > - uint64_t irq_port; We are removing things already? :-) > }; > > /* > @@ -392,4 +390,59 @@ struct vas_winctx { > extern int vas_initialized; > extern int vas_window_reset(struct vas_instance *vinst, int winid); > extern struct vas_instance *find_vas_instance(int vasid); > + > +/* > + * VREG(x): > + * Expand a register's short name (eg: LPID) into two parameters: > + * - the register's short name in string form ("LPID"), and > + * - the name of the macro (eg: VAS_LPID_OFFSET), defining the > + * register's offset in the window context > + */ > +#define VREG_SFX(n, s) __stringify(n), VAS_##n##s > +#define VREG(r) VREG_SFX(r, _OFFSET) > + > +#ifndef vas_debug > +static inline void vas_log_write(struct vas_window *win, char *name, > + void *regptr, uint64_t val) > +{ > + if (val) > + pr_err("%swin #%d: %s reg %p, val 0x%llx\n", > + win->tx_win ? "Tx" : "Rx", win->winid, name, > + regptr, val); > +} > + > +#else/* vas_debug */ > + > +#define vas_log_write(win, name, reg, val) > + > +#endif /* vas_debug */ > + > +static inline void write_uwc_reg(struct vas_window *win, char *name, > + int32_t reg, uint64_t val) > +{ > + void *regptr; > + > + regptr = win->uwc_map + reg; > + vas_log_write(win, name, regptr, val); > + > + out_be64(regptr, val); > +} > + > +static inline void write_hvwc_reg(struct vas_window *win, char *name, > + int32_t reg, uint64_t val) > +{ > + void *regptr; > + > + regptr = win->hvwc_map + reg; > + vas_log_write(win, name, regptr, val); > + > + out_be64(regptr, val); > +} > + > +static inline uint64_t read_hvwc_reg(struct vas_window *win, > + char *name __maybe_unused, int32_t reg) > +{ > + return in_be64(win->hvwc_map+reg); > +} > + > #endif > diff --git a/drivers/misc/vas/vas-window.c b/drivers/misc/vas/vas-window.c > index 32dd1d0..edf5c9f 100644 > --- a/drivers/misc/vas/vas-window.c > +++ b/drivers/misc/vas/vas-window.c > @@ -14,6 +14,8 @@ > #include > #include "vas-internal.h" > > +static int fault_winid; > + > /* > * Compute the paste address region for the window @window using the > * ->win_base_addr and ->win_id_shift we got from device tree. > @@ -138,6 +140,338 @@ int map_wc_mmio_bars(struct vas_window *window) > return 0; > } > > +/* > + * Reset all valid registers in the HV and OS/User Window Contexts for > + * the window identified by @window. > + * > + * 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?). > + */ > +void reset_window_regs(struct vas_window *window) > +{ > + write_hvwc_reg(window, VREG(LPID), 0ULL); > + write_hvwc_reg(window, VREG(PID), 0ULL); > + write_hvwc_reg(window, VREG(XLATE_MSR), 0ULL); > + write_hvwc_reg(window, VREG(XLATE_LPCR), 0ULL); > + write_hvwc_reg(window, VREG(XLATE_CTL), 0ULL); > + write_hvwc_reg(window, VREG(AMR), 0ULL); > + write_hvwc_reg(window, VREG(SEIDR), 0ULL); > + write_hvwc_reg(window, VREG(FAULT_TX_WIN), 0ULL); > + 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),
[PATCH v3 05/10] VAS: Define helpers to init window context
Define helpers to initialize window context registers of the VAS hardware. These will be used in follow-on patches when opening/closing VAS windows. Signed-off-by: Sukadev Bhattiprolu --- Changelog[v3] - Have caller, rather than init_xlate_regs() reset window regs so we don't reset any settings caller may already have set. - Translation mode should be 0x3 (0b11) not 0x11. - Skip initilaizing read-only registers NX_UTIL and NX_UTIL_SE - Skip initializing adder registers from UWC - they are already initialized from the HVWC. - Check winctx->user_win when setting translation registers --- drivers/misc/vas/vas-internal.h | 59 ++- drivers/misc/vas/vas-window.c | 334 2 files changed, 390 insertions(+), 3 deletions(-) diff --git a/drivers/misc/vas/vas-internal.h b/drivers/misc/vas/vas-internal.h index 15b62e0..8e721df 100644 --- a/drivers/misc/vas/vas-internal.h +++ b/drivers/misc/vas/vas-internal.h @@ -11,6 +11,7 @@ #define VAS_INTERNAL_H #include #include +#include #include #ifdef CONFIG_PPC_4K_PAGES @@ -336,9 +337,6 @@ struct vas_window { /* Feilds applicable only to receive windows */ enum vas_cop_type cop; atomic_t num_txwins; - - int32_t hwirq; - uint64_t irq_port; }; /* @@ -392,4 +390,59 @@ struct vas_winctx { extern int vas_initialized; extern int vas_window_reset(struct vas_instance *vinst, int winid); extern struct vas_instance *find_vas_instance(int vasid); + +/* + * VREG(x): + * Expand a register's short name (eg: LPID) into two parameters: + * - the register's short name in string form ("LPID"), and + * - the name of the macro (eg: VAS_LPID_OFFSET), defining the + * register's offset in the window context + */ +#define VREG_SFX(n, s) __stringify(n), VAS_##n##s +#define VREG(r)VREG_SFX(r, _OFFSET) + +#ifndef vas_debug +static inline void vas_log_write(struct vas_window *win, char *name, + void *regptr, uint64_t val) +{ + if (val) + pr_err("%swin #%d: %s reg %p, val 0x%llx\n", + win->tx_win ? "Tx" : "Rx", win->winid, name, + regptr, val); +} + +#else /* vas_debug */ + +#define vas_log_write(win, name, reg, val) + +#endif /* vas_debug */ + +static inline void write_uwc_reg(struct vas_window *win, char *name, + int32_t reg, uint64_t val) +{ + void *regptr; + + regptr = win->uwc_map + reg; + vas_log_write(win, name, regptr, val); + + out_be64(regptr, val); +} + +static inline void write_hvwc_reg(struct vas_window *win, char *name, + int32_t reg, uint64_t val) +{ + void *regptr; + + regptr = win->hvwc_map + reg; + vas_log_write(win, name, regptr, val); + + out_be64(regptr, val); +} + +static inline uint64_t read_hvwc_reg(struct vas_window *win, + char *name __maybe_unused, int32_t reg) +{ + return in_be64(win->hvwc_map+reg); +} + #endif diff --git a/drivers/misc/vas/vas-window.c b/drivers/misc/vas/vas-window.c index 32dd1d0..edf5c9f 100644 --- a/drivers/misc/vas/vas-window.c +++ b/drivers/misc/vas/vas-window.c @@ -14,6 +14,8 @@ #include #include "vas-internal.h" +static int fault_winid; + /* * Compute the paste address region for the window @window using the * ->win_base_addr and ->win_id_shift we got from device tree. @@ -138,6 +140,338 @@ int map_wc_mmio_bars(struct vas_window *window) return 0; } +/* + * Reset all valid registers in the HV and OS/User Window Contexts for + * the window identified by @window. + * + * 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?). + */ +void reset_window_regs(struct vas_window *window) +{ + write_hvwc_reg(window, VREG(LPID), 0ULL); + write_hvwc_reg(window, VREG(PID), 0ULL); + write_hvwc_reg(window, VREG(XLATE_MSR), 0ULL); + write_hvwc_reg(window, VREG(XLATE_LPCR), 0ULL); + write_hvwc_reg(window, VREG(XLATE_CTL), 0ULL); + write_hvwc_reg(window, VREG(AMR), 0ULL); + write_hvwc_reg(window, VREG(SEIDR), 0ULL); + write_hvwc_reg(window, VREG(FAULT_TX_WIN), 0ULL); + 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(