Lines Matching full:window
26 * Compute the paste address region for the window @window using the
29 void vas_win_paste_addr(struct vas_window *window, u64 *addr, int *len) in vas_win_paste_addr() argument
34 base = window->vinst->paste_base_addr; in vas_win_paste_addr()
35 shift = window->vinst->paste_win_id_shift; in vas_win_paste_addr()
36 winid = window->winid; in vas_win_paste_addr()
45 static inline void get_hvwc_mmio_bar(struct vas_window *window, in get_hvwc_mmio_bar() argument
50 pbaddr = window->vinst->hvwc_bar_start; in get_hvwc_mmio_bar()
51 *start = pbaddr + window->winid * VAS_HVWC_SIZE; in get_hvwc_mmio_bar()
55 static inline void get_uwc_mmio_bar(struct vas_window *window, in get_uwc_mmio_bar() argument
60 pbaddr = window->vinst->uwc_bar_start; in get_uwc_mmio_bar()
61 *start = pbaddr + window->winid * VAS_UWC_SIZE; in get_uwc_mmio_bar()
66 * Map the paste bus address of the given send window into kernel address
77 name = kasprintf(GFP_KERNEL, "window-v%d-w%d", txwin->vinst->vas_id, in map_paste_region()
133 * Unmap the paste address region for a window.
135 static void unmap_paste_region(struct vas_window *window) in unmap_paste_region() argument
140 if (window->paste_kaddr) { in unmap_paste_region()
141 vas_win_paste_addr(window, &busaddr_start, &len); in unmap_paste_region()
142 unmap_region(window->paste_kaddr, busaddr_start, len); in unmap_paste_region()
143 window->paste_kaddr = NULL; in unmap_paste_region()
144 kfree(window->paste_addr_name); in unmap_paste_region()
145 window->paste_addr_name = NULL; in unmap_paste_region()
150 * Unmap the MMIO regions for a window. Hold the vas_mutex so we don't
151 * unmap when the window's debugfs dir is in use. This serializes close
152 * of a window even on another VAS instance but since its not a critical
156 static void unmap_winctx_mmio_bars(struct vas_window *window) in unmap_winctx_mmio_bars() argument
165 hvwc_map = window->hvwc_map; in unmap_winctx_mmio_bars()
166 window->hvwc_map = NULL; in unmap_winctx_mmio_bars()
168 uwc_map = window->uwc_map; in unmap_winctx_mmio_bars()
169 window->uwc_map = NULL; in unmap_winctx_mmio_bars()
174 get_hvwc_mmio_bar(window, &busaddr_start, &len); in unmap_winctx_mmio_bars()
179 get_uwc_mmio_bar(window, &busaddr_start, &len); in unmap_winctx_mmio_bars()
185 * Find the Hypervisor Window Context (HVWC) MMIO Base Address Region and the
186 * OS/User Window Context (UWC) MMIO Base Address Region for the given window.
187 * Map these bus addresses and save the mapped kernel addresses in @window.
189 static int map_winctx_mmio_bars(struct vas_window *window) in map_winctx_mmio_bars() argument
194 get_hvwc_mmio_bar(window, &start, &len); in map_winctx_mmio_bars()
195 window->hvwc_map = map_mmio_region("HVWCM_Window", start, len); in map_winctx_mmio_bars()
197 get_uwc_mmio_bar(window, &start, &len); in map_winctx_mmio_bars()
198 window->uwc_map = map_mmio_region("UWCM_Window", start, len); in map_winctx_mmio_bars()
200 if (!window->hvwc_map || !window->uwc_map) { in map_winctx_mmio_bars()
201 unmap_winctx_mmio_bars(window); in map_winctx_mmio_bars()
209 * Reset all valid registers in the HV and OS/User Window Contexts for
210 * the window identified by @window.
212 * NOTE: We cannot really use a for loop to reset window context. Not all
213 * offsets in a window context are valid registers and the valid
217 static void reset_window_regs(struct vas_window *window) in reset_window_regs() argument
219 write_hvwc_reg(window, VREG(LPID), 0ULL); in reset_window_regs()
220 write_hvwc_reg(window, VREG(PID), 0ULL); in reset_window_regs()
221 write_hvwc_reg(window, VREG(XLATE_MSR), 0ULL); in reset_window_regs()
222 write_hvwc_reg(window, VREG(XLATE_LPCR), 0ULL); in reset_window_regs()
223 write_hvwc_reg(window, VREG(XLATE_CTL), 0ULL); in reset_window_regs()
224 write_hvwc_reg(window, VREG(AMR), 0ULL); in reset_window_regs()
225 write_hvwc_reg(window, VREG(SEIDR), 0ULL); in reset_window_regs()
226 write_hvwc_reg(window, VREG(FAULT_TX_WIN), 0ULL); in reset_window_regs()
227 write_hvwc_reg(window, VREG(OSU_INTR_SRC_RA), 0ULL); in reset_window_regs()
228 write_hvwc_reg(window, VREG(HV_INTR_SRC_RA), 0ULL); in reset_window_regs()
229 write_hvwc_reg(window, VREG(PSWID), 0ULL); in reset_window_regs()
230 write_hvwc_reg(window, VREG(LFIFO_BAR), 0ULL); in reset_window_regs()
231 write_hvwc_reg(window, VREG(LDATA_STAMP_CTL), 0ULL); in reset_window_regs()
232 write_hvwc_reg(window, VREG(LDMA_CACHE_CTL), 0ULL); in reset_window_regs()
233 write_hvwc_reg(window, VREG(LRFIFO_PUSH), 0ULL); in reset_window_regs()
234 write_hvwc_reg(window, VREG(CURR_MSG_COUNT), 0ULL); in reset_window_regs()
235 write_hvwc_reg(window, VREG(LNOTIFY_AFTER_COUNT), 0ULL); in reset_window_regs()
236 write_hvwc_reg(window, VREG(LRX_WCRED), 0ULL); in reset_window_regs()
237 write_hvwc_reg(window, VREG(LRX_WCRED_ADDER), 0ULL); in reset_window_regs()
238 write_hvwc_reg(window, VREG(TX_WCRED), 0ULL); in reset_window_regs()
239 write_hvwc_reg(window, VREG(TX_WCRED_ADDER), 0ULL); in reset_window_regs()
240 write_hvwc_reg(window, VREG(LFIFO_SIZE), 0ULL); in reset_window_regs()
241 write_hvwc_reg(window, VREG(WINCTL), 0ULL); in reset_window_regs()
242 write_hvwc_reg(window, VREG(WIN_STATUS), 0ULL); in reset_window_regs()
243 write_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL), 0ULL); in reset_window_regs()
244 write_hvwc_reg(window, VREG(TX_RSVD_BUF_COUNT), 0ULL); in reset_window_regs()
245 write_hvwc_reg(window, VREG(LRFIFO_WIN_PTR), 0ULL); in reset_window_regs()
246 write_hvwc_reg(window, VREG(LNOTIFY_CTL), 0ULL); in reset_window_regs()
247 write_hvwc_reg(window, VREG(LNOTIFY_PID), 0ULL); in reset_window_regs()
248 write_hvwc_reg(window, VREG(LNOTIFY_LPID), 0ULL); in reset_window_regs()
249 write_hvwc_reg(window, VREG(LNOTIFY_TID), 0ULL); in reset_window_regs()
250 write_hvwc_reg(window, VREG(LNOTIFY_SCOPE), 0ULL); in reset_window_regs()
251 write_hvwc_reg(window, VREG(NX_UTIL_ADDER), 0ULL); in reset_window_regs()
256 * The send and receive window credit adder registers are also in reset_window_regs()
258 * need to initialize from the OS/User Window Context, so skip in reset_window_regs()
261 * write_uwc_reg(window, VREG(TX_WCRED_ADDER), 0ULL); in reset_window_regs()
262 * write_uwc_reg(window, VREG(LRX_WCRED_ADDER), 0ULL); in reset_window_regs()
267 * Initialize window context registers related to Address Translation.
273 static void init_xlate_regs(struct vas_window *window, bool user_win) in init_xlate_regs() argument
288 write_hvwc_reg(window, VREG(XLATE_MSR), val); in init_xlate_regs()
303 write_hvwc_reg(window, VREG(XLATE_LPCR), val); in init_xlate_regs()
314 write_hvwc_reg(window, VREG(XLATE_CTL), val); in init_xlate_regs()
321 write_hvwc_reg(window, VREG(AMR), val); in init_xlate_regs()
325 write_hvwc_reg(window, VREG(SEIDR), val); in init_xlate_regs()
329 * Initialize Reserved Send Buffer Count for the send window. It involves
346 * Initialize window context registers for a receive window.
347 * Except for caching control and marking window open, the registers
348 * are initialized in the order listed in Section 3.1.4 (Window Context
360 static void init_winctx_regs(struct vas_window *window, in init_winctx_regs() argument
366 reset_window_regs(window); in init_winctx_regs()
370 write_hvwc_reg(window, VREG(LPID), val); in init_winctx_regs()
374 write_hvwc_reg(window, VREG(PID), val); in init_winctx_regs()
376 init_xlate_regs(window, winctx->user_win); in init_winctx_regs()
380 write_hvwc_reg(window, VREG(FAULT_TX_WIN), val); in init_winctx_regs()
383 write_hvwc_reg(window, VREG(OSU_INTR_SRC_RA), 0ULL); in init_winctx_regs()
387 write_hvwc_reg(window, VREG(HV_INTR_SRC_RA), val); in init_winctx_regs()
391 write_hvwc_reg(window, VREG(PSWID), val); in init_winctx_regs()
393 write_hvwc_reg(window, VREG(SPARE1), 0ULL); in init_winctx_regs()
394 write_hvwc_reg(window, VREG(SPARE2), 0ULL); in init_winctx_regs()
395 write_hvwc_reg(window, VREG(SPARE3), 0ULL); in init_winctx_regs()
408 write_hvwc_reg(window, VREG(LFIFO_BAR), val); in init_winctx_regs()
412 write_hvwc_reg(window, VREG(LDATA_STAMP_CTL), val); in init_winctx_regs()
417 write_hvwc_reg(window, VREG(LDMA_CACHE_CTL), val); in init_winctx_regs()
419 write_hvwc_reg(window, VREG(LRFIFO_PUSH), 0ULL); in init_winctx_regs()
420 write_hvwc_reg(window, VREG(CURR_MSG_COUNT), 0ULL); in init_winctx_regs()
421 write_hvwc_reg(window, VREG(LNOTIFY_AFTER_COUNT), 0ULL); in init_winctx_regs()
425 write_hvwc_reg(window, VREG(LRX_WCRED), val); in init_winctx_regs()
429 write_hvwc_reg(window, VREG(TX_WCRED), val); in init_winctx_regs()
431 write_hvwc_reg(window, VREG(LRX_WCRED_ADDER), 0ULL); in init_winctx_regs()
432 write_hvwc_reg(window, VREG(TX_WCRED_ADDER), 0ULL); in init_winctx_regs()
438 write_hvwc_reg(window, VREG(LFIFO_SIZE), val); in init_winctx_regs()
440 /* Update window control and caching control registers last so in init_winctx_regs()
441 * we mark the window open only after fully initializing it and in init_winctx_regs()
445 write_hvwc_reg(window, VREG(WIN_STATUS), 0ULL); in init_winctx_regs()
447 init_rsvd_tx_buf_count(window, winctx); in init_winctx_regs()
449 /* for a send window, point to the matching receive window */ in init_winctx_regs()
452 write_hvwc_reg(window, VREG(LRFIFO_WIN_PTR), val); in init_winctx_regs()
454 write_hvwc_reg(window, VREG(SPARE4), 0ULL); in init_winctx_regs()
461 write_hvwc_reg(window, VREG(LNOTIFY_CTL), val); in init_winctx_regs()
465 write_hvwc_reg(window, VREG(LNOTIFY_PID), val); in init_winctx_regs()
469 write_hvwc_reg(window, VREG(LNOTIFY_LPID), val); in init_winctx_regs()
473 write_hvwc_reg(window, VREG(LNOTIFY_TID), val); in init_winctx_regs()
478 write_hvwc_reg(window, VREG(LNOTIFY_SCOPE), val); in init_winctx_regs()
482 write_hvwc_reg(window, VREG(SPARE5), 0ULL); in init_winctx_regs()
483 write_hvwc_reg(window, VREG(NX_UTIL_ADDER), 0ULL); in init_winctx_regs()
484 write_hvwc_reg(window, VREG(SPARE6), 0ULL); in init_winctx_regs()
486 /* Finally, push window context to memory and... */ in init_winctx_regs()
489 write_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL), val); in init_winctx_regs()
491 /* ... mark the window open for business */ in init_winctx_regs()
502 write_hvwc_reg(window, VREG(WINCTL), val); in init_winctx_regs()
522 static void vas_window_free(struct vas_window *window) in vas_window_free() argument
524 int winid = window->winid; in vas_window_free()
525 struct vas_instance *vinst = window->vinst; in vas_window_free()
527 unmap_winctx_mmio_bars(window); in vas_window_free()
529 vas_window_free_dbgdir(window); in vas_window_free()
531 kfree(window); in vas_window_free()
539 struct vas_window *window; in vas_window_alloc() local
545 window = kzalloc(sizeof(*window), GFP_KERNEL); in vas_window_alloc()
546 if (!window) in vas_window_alloc()
549 window->vinst = vinst; in vas_window_alloc()
550 window->winid = winid; in vas_window_alloc()
552 if (map_winctx_mmio_bars(window)) in vas_window_alloc()
555 vas_window_init_dbgdir(window); in vas_window_alloc()
557 return window; in vas_window_alloc()
560 kfree(window); in vas_window_alloc()
567 /* Better not be a send window! */ in put_rx_win()
574 * Find the user space receive window given the @pswid.
577 * - The window must refer to an OPEN, FTW, RECEIVE window.
600 * Get the VAS receive window associated with NX engine identified
628 * looking up a window by its id. It is used to look up send windows
634 * entries and is used to look up a receive window by its
637 * Here, we save @window in the ->windows[] table. If it is a receive
638 * window, we also save the window in the ->rxwin[] table.
641 struct vas_window *window) in set_vinst_win() argument
643 int id = window->winid; in set_vinst_win()
648 * There should only be one receive window for a coprocessor type in set_vinst_win()
649 * unless its a user (FTW) window. in set_vinst_win()
651 if (!window->user_win && !window->tx_win) { in set_vinst_win()
652 WARN_ON_ONCE(vinst->rxwin[window->cop]); in set_vinst_win()
653 vinst->rxwin[window->cop] = window; in set_vinst_win()
657 vinst->windows[id] = window; in set_vinst_win()
663 * Clear this window from the table(s) of windows for this VAS instance.
666 static void clear_vinst_win(struct vas_window *window) in clear_vinst_win() argument
668 int id = window->winid; in clear_vinst_win()
669 struct vas_instance *vinst = window->vinst; in clear_vinst_win()
673 if (!window->user_win && !window->tx_win) { in clear_vinst_win()
674 WARN_ON_ONCE(!vinst->rxwin[window->cop]); in clear_vinst_win()
675 vinst->rxwin[window->cop] = NULL; in clear_vinst_win()
678 WARN_ON_ONCE(vinst->windows[id] != window); in clear_vinst_win()
778 /* cannot be fault or user window if it is nx */ in rx_win_args_valid()
789 /* cannot be both fault and user window */ in rx_win_args_valid()
808 /* Rx window must be one of NX or Fault or User window. */ in rx_win_args_valid()
872 pr_devel("Unable to allocate memory for Rx window\n"); in vas_rx_win_open()
951 * IRQ and fault window setup is successful. Set fault window in init_winctx_for_txwin()
952 * for the send window so that ready to handle faults. in init_winctx_for_txwin()
1008 * receive window (applicable only to FTW windows), use the vasid in vas_tx_win_open()
1009 * from that receive window. in vas_tx_win_open()
1044 * If its a kernel send window, map the window address into the in vas_tx_win_open()
1046 * mmap() to map the window into their address space. in vas_tx_win_open()
1059 * Interrupt hanlder or fault window setup failed. Means in vas_tx_win_open()
1061 * opening for user space tx window. in vas_tx_win_open()
1069 * Window opened by a child thread may not be closed when in vas_tx_win_open()
1071 * when the window is free by parent thread. in vas_tx_win_open()
1094 * Process closes window during exit. In the case of in vas_tx_win_open()
1096 * window and can exit without closing it. Expects parent in vas_tx_win_open()
1097 * thread to use and close the window. So do not need in vas_tx_win_open()
1108 * if process / thread has any open VAS window (Use in vas_tx_win_open()
1178 * If credit checking is enabled for this window, poll for the return
1179 * of window credits (i.e for NX engines to process any outstanding CRBs).
1181 * window, we should not have to wait for too long.
1190 static void poll_window_credits(struct vas_window *window) in poll_window_credits() argument
1196 val = read_hvwc_reg(window, VREG(WINCTL)); in poll_window_credits()
1197 if (window->tx_win) in poll_window_credits()
1205 if (window->tx_win) { in poll_window_credits()
1206 val = read_hvwc_reg(window, VREG(TX_WCRED)); in poll_window_credits()
1209 val = read_hvwc_reg(window, VREG(LRX_WCRED)); in poll_window_credits()
1216 * TODO: Scan fault FIFO and invalidate CRBs points to this window in poll_window_credits()
1220 if (creds < window->wcreds_max) { in poll_window_credits()
1226 * Process can not close send window until all credits are in poll_window_credits()
1230 …pr_warn_ratelimited("VAS: pid %d stuck. Waiting for credits returned for Window(%d). creds %d, Ret… in poll_window_credits()
1231 vas_window_pid(window), window->winid, in poll_window_credits()
1239 * Wait for the window to go to "not-busy" state. It should only take a
1240 * short time to queue a CRB, so window should not be busy for too long.
1243 static void poll_window_busy_state(struct vas_window *window) in poll_window_busy_state() argument
1250 val = read_hvwc_reg(window, VREG(WIN_STATUS)); in poll_window_busy_state()
1262 pr_warn_ratelimited("VAS: pid %d stuck. Window (ID=%d) is in busy state. Retries %d\n", in poll_window_busy_state()
1263 vas_window_pid(window), window->winid, count); in poll_window_busy_state()
1270 * Have the hardware cast a window out of cache and wait for it to
1273 * NOTE: It can take a relatively long time to cast the window context
1276 * - we clear the "Pin Window" bit (so hardware is free to evict)
1278 * - we re-initialize the window context when it is reassigned.
1283 * job to a worker thread, so the window close can proceed quickly.
1285 static void poll_window_castout(struct vas_window *window) in poll_window_castout() argument
1291 * Unpin and close a window so no new requests are accepted and the
1292 * hardware can evict this window from cache if necessary.
1294 static void unpin_close_window(struct vas_window *window) in unpin_close_window() argument
1298 val = read_hvwc_reg(window, VREG(WINCTL)); in unpin_close_window()
1301 write_hvwc_reg(window, VREG(WINCTL), val); in unpin_close_window()
1305 * Close a window.
1307 * See Section 1.12.1 of VAS workbook v1.05 for details on closing window:
1309 * - Poll for the "Window Busy" bit to be cleared
1310 * - Clear the Open/Enable bit for the Window.
1311 * - Poll for return of window Credits (implies FIFO empty for Rx win?)
1312 * - Unpin and cast window context out of cache
1316 int vas_win_close(struct vas_window *window) in vas_win_close() argument
1318 if (!window) in vas_win_close()
1321 if (!window->tx_win && atomic_read(&window->num_txwins) != 0) { in vas_win_close()
1322 pr_devel("Attempting to close an active Rx window!\n"); in vas_win_close()
1327 unmap_paste_region(window); in vas_win_close()
1329 poll_window_busy_state(window); in vas_win_close()
1331 unpin_close_window(window); in vas_win_close()
1333 poll_window_credits(window); in vas_win_close()
1335 clear_vinst_win(window); in vas_win_close()
1337 poll_window_castout(window); in vas_win_close()
1339 /* if send window, drop reference to matching receive window */ in vas_win_close()
1340 if (window->tx_win) { in vas_win_close()
1341 if (window->user_win) { in vas_win_close()
1343 put_pid(window->pid); in vas_win_close()
1344 if (window->mm) { in vas_win_close()
1345 mm_context_remove_vas_window(window->mm); in vas_win_close()
1346 mmdrop(window->mm); in vas_win_close()
1349 put_rx_win(window->rxwin); in vas_win_close()
1352 vas_window_free(window); in vas_win_close()
1359 * Return credit for the given window.
1360 * Send windows and fault window uses credit mechanism as follows:
1363 * - The default number of credits available for each send window is
1370 * credit on the specific send window after processing the fault CRB.
1372 * Fault window:
1377 * - The kernel with return credit on fault window after reading entry
1380 void vas_return_credit(struct vas_window *window, bool tx) in vas_return_credit() argument
1385 if (tx) { /* send window */ in vas_return_credit()
1387 write_hvwc_reg(window, VREG(TX_WCRED_ADDER), val); in vas_return_credit()
1390 write_hvwc_reg(window, VREG(LRX_WCRED_ADDER), val); in vas_return_credit()
1397 struct vas_window *window; in vas_pswid_to_window() local
1411 * If application closes the window before the hardware in vas_pswid_to_window()
1413 * for the pending requests. so the window must be active in vas_pswid_to_window()
1419 window = vinst->windows[winid]; in vas_pswid_to_window()
1421 if (!window) { in vas_pswid_to_window()
1422 pr_err("PSWID decode: Could not find window for winid %d pswid %d vinst 0x%p\n", in vas_pswid_to_window()
1428 * Do some sanity checks on the decoded window. Window should be in vas_pswid_to_window()
1429 * NX GZIP user send window. FTW windows should not incur faults in vas_pswid_to_window()
1433 if (!window->tx_win || !window->user_win || !window->nx_win || in vas_pswid_to_window()
1434 window->cop == VAS_COP_TYPE_FAULT || in vas_pswid_to_window()
1435 window->cop == VAS_COP_TYPE_FTW) { in vas_pswid_to_window()
1437 winid, window->tx_win, window->user_win, in vas_pswid_to_window()
1438 window->nx_win, window->cop); in vas_pswid_to_window()
1442 return window; in vas_pswid_to_window()