18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * SN Platform GRU Driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * GRU DRIVER TABLES, MACROS, externs, etc 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef __GRUTABLES_H__ 118c2ecf20Sopenharmony_ci#define __GRUTABLES_H__ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* 148c2ecf20Sopenharmony_ci * GRU Chiplet: 158c2ecf20Sopenharmony_ci * The GRU is a user addressible memory accelerator. It provides 168c2ecf20Sopenharmony_ci * several forms of load, store, memset, bcopy instructions. In addition, it 178c2ecf20Sopenharmony_ci * contains special instructions for AMOs, sending messages to message 188c2ecf20Sopenharmony_ci * queues, etc. 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * The GRU is an integral part of the node controller. It connects 218c2ecf20Sopenharmony_ci * directly to the cpu socket. In its current implementation, there are 2 228c2ecf20Sopenharmony_ci * GRU chiplets in the node controller on each blade (~node). 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * The entire GRU memory space is fully coherent and cacheable by the cpus. 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * Each GRU chiplet has a physical memory map that looks like the following: 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * +-----------------+ 298c2ecf20Sopenharmony_ci * |/////////////////| 308c2ecf20Sopenharmony_ci * |/////////////////| 318c2ecf20Sopenharmony_ci * |/////////////////| 328c2ecf20Sopenharmony_ci * |/////////////////| 338c2ecf20Sopenharmony_ci * |/////////////////| 348c2ecf20Sopenharmony_ci * |/////////////////| 358c2ecf20Sopenharmony_ci * |/////////////////| 368c2ecf20Sopenharmony_ci * |/////////////////| 378c2ecf20Sopenharmony_ci * +-----------------+ 388c2ecf20Sopenharmony_ci * | system control | 398c2ecf20Sopenharmony_ci * +-----------------+ _______ +-------------+ 408c2ecf20Sopenharmony_ci * |/////////////////| / | | 418c2ecf20Sopenharmony_ci * |/////////////////| / | | 428c2ecf20Sopenharmony_ci * |/////////////////| / | instructions| 438c2ecf20Sopenharmony_ci * |/////////////////| / | | 448c2ecf20Sopenharmony_ci * |/////////////////| / | | 458c2ecf20Sopenharmony_ci * |/////////////////| / |-------------| 468c2ecf20Sopenharmony_ci * |/////////////////| / | | 478c2ecf20Sopenharmony_ci * +-----------------+ | | 488c2ecf20Sopenharmony_ci * | context 15 | | data | 498c2ecf20Sopenharmony_ci * +-----------------+ | | 508c2ecf20Sopenharmony_ci * | ...... | \ | | 518c2ecf20Sopenharmony_ci * +-----------------+ \____________ +-------------+ 528c2ecf20Sopenharmony_ci * | context 1 | 538c2ecf20Sopenharmony_ci * +-----------------+ 548c2ecf20Sopenharmony_ci * | context 0 | 558c2ecf20Sopenharmony_ci * +-----------------+ 568c2ecf20Sopenharmony_ci * 578c2ecf20Sopenharmony_ci * Each of the "contexts" is a chunk of memory that can be mmaped into user 588c2ecf20Sopenharmony_ci * space. The context consists of 2 parts: 598c2ecf20Sopenharmony_ci * 608c2ecf20Sopenharmony_ci * - an instruction space that can be directly accessed by the user 618c2ecf20Sopenharmony_ci * to issue GRU instructions and to check instruction status. 628c2ecf20Sopenharmony_ci * 638c2ecf20Sopenharmony_ci * - a data area that acts as normal RAM. 648c2ecf20Sopenharmony_ci * 658c2ecf20Sopenharmony_ci * User instructions contain virtual addresses of data to be accessed by the 668c2ecf20Sopenharmony_ci * GRU. The GRU contains a TLB that is used to convert these user virtual 678c2ecf20Sopenharmony_ci * addresses to physical addresses. 688c2ecf20Sopenharmony_ci * 698c2ecf20Sopenharmony_ci * The "system control" area of the GRU chiplet is used by the kernel driver 708c2ecf20Sopenharmony_ci * to manage user contexts and to perform functions such as TLB dropin and 718c2ecf20Sopenharmony_ci * purging. 728c2ecf20Sopenharmony_ci * 738c2ecf20Sopenharmony_ci * One context may be reserved for the kernel and used for cross-partition 748c2ecf20Sopenharmony_ci * communication. The GRU will also be used to asynchronously zero out 758c2ecf20Sopenharmony_ci * large blocks of memory (not currently implemented). 768c2ecf20Sopenharmony_ci * 778c2ecf20Sopenharmony_ci * 788c2ecf20Sopenharmony_ci * Tables: 798c2ecf20Sopenharmony_ci * 808c2ecf20Sopenharmony_ci * VDATA-VMA Data - Holds a few parameters. Head of linked list of 818c2ecf20Sopenharmony_ci * GTS tables for threads using the GSEG 828c2ecf20Sopenharmony_ci * GTS - Gru Thread State - contains info for managing a GSEG context. A 838c2ecf20Sopenharmony_ci * GTS is allocated for each thread accessing a 848c2ecf20Sopenharmony_ci * GSEG. 858c2ecf20Sopenharmony_ci * GTD - GRU Thread Data - contains shadow copy of GRU data when GSEG is 868c2ecf20Sopenharmony_ci * not loaded into a GRU 878c2ecf20Sopenharmony_ci * GMS - GRU Memory Struct - Used to manage TLB shootdowns. Tracks GRUs 888c2ecf20Sopenharmony_ci * where a GSEG has been loaded. Similar to 898c2ecf20Sopenharmony_ci * an mm_struct but for GRU. 908c2ecf20Sopenharmony_ci * 918c2ecf20Sopenharmony_ci * GS - GRU State - Used to manage the state of a GRU chiplet 928c2ecf20Sopenharmony_ci * BS - Blade State - Used to manage state of all GRU chiplets 938c2ecf20Sopenharmony_ci * on a blade 948c2ecf20Sopenharmony_ci * 958c2ecf20Sopenharmony_ci * 968c2ecf20Sopenharmony_ci * Normal task tables for task using GRU. 978c2ecf20Sopenharmony_ci * - 2 threads in process 988c2ecf20Sopenharmony_ci * - 2 GSEGs open in process 998c2ecf20Sopenharmony_ci * - GSEG1 is being used by both threads 1008c2ecf20Sopenharmony_ci * - GSEG2 is used only by thread 2 1018c2ecf20Sopenharmony_ci * 1028c2ecf20Sopenharmony_ci * task -->| 1038c2ecf20Sopenharmony_ci * task ---+---> mm ->------ (notifier) -------+-> gms 1048c2ecf20Sopenharmony_ci * | | 1058c2ecf20Sopenharmony_ci * |--> vma -> vdata ---> gts--->| GSEG1 (thread1) 1068c2ecf20Sopenharmony_ci * | | | 1078c2ecf20Sopenharmony_ci * | +-> gts--->| GSEG1 (thread2) 1088c2ecf20Sopenharmony_ci * | | 1098c2ecf20Sopenharmony_ci * |--> vma -> vdata ---> gts--->| GSEG2 (thread2) 1108c2ecf20Sopenharmony_ci * . 1118c2ecf20Sopenharmony_ci * . 1128c2ecf20Sopenharmony_ci * 1138c2ecf20Sopenharmony_ci * GSEGs are marked DONTCOPY on fork 1148c2ecf20Sopenharmony_ci * 1158c2ecf20Sopenharmony_ci * At open 1168c2ecf20Sopenharmony_ci * file.private_data -> NULL 1178c2ecf20Sopenharmony_ci * 1188c2ecf20Sopenharmony_ci * At mmap, 1198c2ecf20Sopenharmony_ci * vma -> vdata 1208c2ecf20Sopenharmony_ci * 1218c2ecf20Sopenharmony_ci * After gseg reference 1228c2ecf20Sopenharmony_ci * vma -> vdata ->gts 1238c2ecf20Sopenharmony_ci * 1248c2ecf20Sopenharmony_ci * After fork 1258c2ecf20Sopenharmony_ci * parent 1268c2ecf20Sopenharmony_ci * vma -> vdata -> gts 1278c2ecf20Sopenharmony_ci * child 1288c2ecf20Sopenharmony_ci * (vma is not copied) 1298c2ecf20Sopenharmony_ci * 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci#include <linux/rmap.h> 1338c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 1348c2ecf20Sopenharmony_ci#include <linux/mutex.h> 1358c2ecf20Sopenharmony_ci#include <linux/wait.h> 1368c2ecf20Sopenharmony_ci#include <linux/mmu_notifier.h> 1378c2ecf20Sopenharmony_ci#include <linux/mm_types.h> 1388c2ecf20Sopenharmony_ci#include "gru.h" 1398c2ecf20Sopenharmony_ci#include "grulib.h" 1408c2ecf20Sopenharmony_ci#include "gruhandles.h" 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ciextern struct gru_stats_s gru_stats; 1438c2ecf20Sopenharmony_ciextern struct gru_blade_state *gru_base[]; 1448c2ecf20Sopenharmony_ciextern unsigned long gru_start_paddr, gru_end_paddr; 1458c2ecf20Sopenharmony_ciextern void *gru_start_vaddr; 1468c2ecf20Sopenharmony_ciextern unsigned int gru_max_gids; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci#define GRU_MAX_BLADES MAX_NUMNODES 1498c2ecf20Sopenharmony_ci#define GRU_MAX_GRUS (GRU_MAX_BLADES * GRU_CHIPLETS_PER_BLADE) 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci#define GRU_DRIVER_ID_STR "SGI GRU Device Driver" 1528c2ecf20Sopenharmony_ci#define GRU_DRIVER_VERSION_STR "0.85" 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci/* 1558c2ecf20Sopenharmony_ci * GRU statistics. 1568c2ecf20Sopenharmony_ci */ 1578c2ecf20Sopenharmony_cistruct gru_stats_s { 1588c2ecf20Sopenharmony_ci atomic_long_t vdata_alloc; 1598c2ecf20Sopenharmony_ci atomic_long_t vdata_free; 1608c2ecf20Sopenharmony_ci atomic_long_t gts_alloc; 1618c2ecf20Sopenharmony_ci atomic_long_t gts_free; 1628c2ecf20Sopenharmony_ci atomic_long_t gms_alloc; 1638c2ecf20Sopenharmony_ci atomic_long_t gms_free; 1648c2ecf20Sopenharmony_ci atomic_long_t gts_double_allocate; 1658c2ecf20Sopenharmony_ci atomic_long_t assign_context; 1668c2ecf20Sopenharmony_ci atomic_long_t assign_context_failed; 1678c2ecf20Sopenharmony_ci atomic_long_t free_context; 1688c2ecf20Sopenharmony_ci atomic_long_t load_user_context; 1698c2ecf20Sopenharmony_ci atomic_long_t load_kernel_context; 1708c2ecf20Sopenharmony_ci atomic_long_t lock_kernel_context; 1718c2ecf20Sopenharmony_ci atomic_long_t unlock_kernel_context; 1728c2ecf20Sopenharmony_ci atomic_long_t steal_user_context; 1738c2ecf20Sopenharmony_ci atomic_long_t steal_kernel_context; 1748c2ecf20Sopenharmony_ci atomic_long_t steal_context_failed; 1758c2ecf20Sopenharmony_ci atomic_long_t nopfn; 1768c2ecf20Sopenharmony_ci atomic_long_t asid_new; 1778c2ecf20Sopenharmony_ci atomic_long_t asid_next; 1788c2ecf20Sopenharmony_ci atomic_long_t asid_wrap; 1798c2ecf20Sopenharmony_ci atomic_long_t asid_reuse; 1808c2ecf20Sopenharmony_ci atomic_long_t intr; 1818c2ecf20Sopenharmony_ci atomic_long_t intr_cbr; 1828c2ecf20Sopenharmony_ci atomic_long_t intr_tfh; 1838c2ecf20Sopenharmony_ci atomic_long_t intr_spurious; 1848c2ecf20Sopenharmony_ci atomic_long_t intr_mm_lock_failed; 1858c2ecf20Sopenharmony_ci atomic_long_t call_os; 1868c2ecf20Sopenharmony_ci atomic_long_t call_os_wait_queue; 1878c2ecf20Sopenharmony_ci atomic_long_t user_flush_tlb; 1888c2ecf20Sopenharmony_ci atomic_long_t user_unload_context; 1898c2ecf20Sopenharmony_ci atomic_long_t user_exception; 1908c2ecf20Sopenharmony_ci atomic_long_t set_context_option; 1918c2ecf20Sopenharmony_ci atomic_long_t check_context_retarget_intr; 1928c2ecf20Sopenharmony_ci atomic_long_t check_context_unload; 1938c2ecf20Sopenharmony_ci atomic_long_t tlb_dropin; 1948c2ecf20Sopenharmony_ci atomic_long_t tlb_preload_page; 1958c2ecf20Sopenharmony_ci atomic_long_t tlb_dropin_fail_no_asid; 1968c2ecf20Sopenharmony_ci atomic_long_t tlb_dropin_fail_upm; 1978c2ecf20Sopenharmony_ci atomic_long_t tlb_dropin_fail_invalid; 1988c2ecf20Sopenharmony_ci atomic_long_t tlb_dropin_fail_range_active; 1998c2ecf20Sopenharmony_ci atomic_long_t tlb_dropin_fail_idle; 2008c2ecf20Sopenharmony_ci atomic_long_t tlb_dropin_fail_fmm; 2018c2ecf20Sopenharmony_ci atomic_long_t tlb_dropin_fail_no_exception; 2028c2ecf20Sopenharmony_ci atomic_long_t tfh_stale_on_fault; 2038c2ecf20Sopenharmony_ci atomic_long_t mmu_invalidate_range; 2048c2ecf20Sopenharmony_ci atomic_long_t mmu_invalidate_page; 2058c2ecf20Sopenharmony_ci atomic_long_t flush_tlb; 2068c2ecf20Sopenharmony_ci atomic_long_t flush_tlb_gru; 2078c2ecf20Sopenharmony_ci atomic_long_t flush_tlb_gru_tgh; 2088c2ecf20Sopenharmony_ci atomic_long_t flush_tlb_gru_zero_asid; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci atomic_long_t copy_gpa; 2118c2ecf20Sopenharmony_ci atomic_long_t read_gpa; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci atomic_long_t mesq_receive; 2148c2ecf20Sopenharmony_ci atomic_long_t mesq_receive_none; 2158c2ecf20Sopenharmony_ci atomic_long_t mesq_send; 2168c2ecf20Sopenharmony_ci atomic_long_t mesq_send_failed; 2178c2ecf20Sopenharmony_ci atomic_long_t mesq_noop; 2188c2ecf20Sopenharmony_ci atomic_long_t mesq_send_unexpected_error; 2198c2ecf20Sopenharmony_ci atomic_long_t mesq_send_lb_overflow; 2208c2ecf20Sopenharmony_ci atomic_long_t mesq_send_qlimit_reached; 2218c2ecf20Sopenharmony_ci atomic_long_t mesq_send_amo_nacked; 2228c2ecf20Sopenharmony_ci atomic_long_t mesq_send_put_nacked; 2238c2ecf20Sopenharmony_ci atomic_long_t mesq_page_overflow; 2248c2ecf20Sopenharmony_ci atomic_long_t mesq_qf_locked; 2258c2ecf20Sopenharmony_ci atomic_long_t mesq_qf_noop_not_full; 2268c2ecf20Sopenharmony_ci atomic_long_t mesq_qf_switch_head_failed; 2278c2ecf20Sopenharmony_ci atomic_long_t mesq_qf_unexpected_error; 2288c2ecf20Sopenharmony_ci atomic_long_t mesq_noop_unexpected_error; 2298c2ecf20Sopenharmony_ci atomic_long_t mesq_noop_lb_overflow; 2308c2ecf20Sopenharmony_ci atomic_long_t mesq_noop_qlimit_reached; 2318c2ecf20Sopenharmony_ci atomic_long_t mesq_noop_amo_nacked; 2328c2ecf20Sopenharmony_ci atomic_long_t mesq_noop_put_nacked; 2338c2ecf20Sopenharmony_ci atomic_long_t mesq_noop_page_overflow; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci}; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_cienum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync, 2388c2ecf20Sopenharmony_ci cchop_deallocate, tfhop_write_only, tfhop_write_restart, 2398c2ecf20Sopenharmony_ci tghop_invalidate, mcsop_last}; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_cistruct mcs_op_statistic { 2428c2ecf20Sopenharmony_ci atomic_long_t count; 2438c2ecf20Sopenharmony_ci atomic_long_t total; 2448c2ecf20Sopenharmony_ci unsigned long max; 2458c2ecf20Sopenharmony_ci}; 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ciextern struct mcs_op_statistic mcs_op_statistics[mcsop_last]; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci#define OPT_DPRINT 1 2508c2ecf20Sopenharmony_ci#define OPT_STATS 2 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci#define IRQ_GRU 110 /* Starting IRQ number for interrupts */ 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci/* Delay in jiffies between attempts to assign a GRU context */ 2568c2ecf20Sopenharmony_ci#define GRU_ASSIGN_DELAY ((HZ * 20) / 1000) 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci/* 2598c2ecf20Sopenharmony_ci * If a process has it's context stolen, min delay in jiffies before trying to 2608c2ecf20Sopenharmony_ci * steal a context from another process. 2618c2ecf20Sopenharmony_ci */ 2628c2ecf20Sopenharmony_ci#define GRU_STEAL_DELAY ((HZ * 200) / 1000) 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci#define STAT(id) do { \ 2658c2ecf20Sopenharmony_ci if (gru_options & OPT_STATS) \ 2668c2ecf20Sopenharmony_ci atomic_long_inc(&gru_stats.id); \ 2678c2ecf20Sopenharmony_ci } while (0) 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci#ifdef CONFIG_SGI_GRU_DEBUG 2708c2ecf20Sopenharmony_ci#define gru_dbg(dev, fmt, x...) \ 2718c2ecf20Sopenharmony_ci do { \ 2728c2ecf20Sopenharmony_ci if (gru_options & OPT_DPRINT) \ 2738c2ecf20Sopenharmony_ci printk(KERN_DEBUG "GRU:%d %s: " fmt, smp_processor_id(), __func__, x);\ 2748c2ecf20Sopenharmony_ci } while (0) 2758c2ecf20Sopenharmony_ci#else 2768c2ecf20Sopenharmony_ci#define gru_dbg(x...) 2778c2ecf20Sopenharmony_ci#endif 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------------- 2808c2ecf20Sopenharmony_ci * ASID management 2818c2ecf20Sopenharmony_ci */ 2828c2ecf20Sopenharmony_ci#define MAX_ASID 0xfffff0 2838c2ecf20Sopenharmony_ci#define MIN_ASID 8 2848c2ecf20Sopenharmony_ci#define ASID_INC 8 /* number of regions */ 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci/* Generate a GRU asid value from a GRU base asid & a virtual address. */ 2878c2ecf20Sopenharmony_ci#define VADDR_HI_BIT 64 2888c2ecf20Sopenharmony_ci#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3) 2898c2ecf20Sopenharmony_ci#define GRUASID(asid, addr) ((asid) + GRUREGION(addr)) 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci/*------------------------------------------------------------------------------ 2928c2ecf20Sopenharmony_ci * File & VMS Tables 2938c2ecf20Sopenharmony_ci */ 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_cistruct gru_state; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci/* 2988c2ecf20Sopenharmony_ci * This structure is pointed to from the mmstruct via the notifier pointer. 2998c2ecf20Sopenharmony_ci * There is one of these per address space. 3008c2ecf20Sopenharmony_ci */ 3018c2ecf20Sopenharmony_cistruct gru_mm_tracker { /* pack to reduce size */ 3028c2ecf20Sopenharmony_ci unsigned int mt_asid_gen:24; /* ASID wrap count */ 3038c2ecf20Sopenharmony_ci unsigned int mt_asid:24; /* current base ASID for gru */ 3048c2ecf20Sopenharmony_ci unsigned short mt_ctxbitmap:16;/* bitmap of contexts using 3058c2ecf20Sopenharmony_ci asid */ 3068c2ecf20Sopenharmony_ci} __attribute__ ((packed)); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_cistruct gru_mm_struct { 3098c2ecf20Sopenharmony_ci struct mmu_notifier ms_notifier; 3108c2ecf20Sopenharmony_ci spinlock_t ms_asid_lock; /* protects ASID assignment */ 3118c2ecf20Sopenharmony_ci atomic_t ms_range_active;/* num range_invals active */ 3128c2ecf20Sopenharmony_ci wait_queue_head_t ms_wait_queue; 3138c2ecf20Sopenharmony_ci DECLARE_BITMAP(ms_asidmap, GRU_MAX_GRUS); 3148c2ecf20Sopenharmony_ci struct gru_mm_tracker ms_asids[GRU_MAX_GRUS]; 3158c2ecf20Sopenharmony_ci}; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci/* 3188c2ecf20Sopenharmony_ci * One of these structures is allocated when a GSEG is mmaped. The 3198c2ecf20Sopenharmony_ci * structure is pointed to by the vma->vm_private_data field in the vma struct. 3208c2ecf20Sopenharmony_ci */ 3218c2ecf20Sopenharmony_cistruct gru_vma_data { 3228c2ecf20Sopenharmony_ci spinlock_t vd_lock; /* Serialize access to vma */ 3238c2ecf20Sopenharmony_ci struct list_head vd_head; /* head of linked list of gts */ 3248c2ecf20Sopenharmony_ci long vd_user_options;/* misc user option flags */ 3258c2ecf20Sopenharmony_ci int vd_cbr_au_count; 3268c2ecf20Sopenharmony_ci int vd_dsr_au_count; 3278c2ecf20Sopenharmony_ci unsigned char vd_tlb_preload_count; 3288c2ecf20Sopenharmony_ci}; 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci/* 3318c2ecf20Sopenharmony_ci * One of these is allocated for each thread accessing a mmaped GRU. A linked 3328c2ecf20Sopenharmony_ci * list of these structure is hung off the struct gru_vma_data in the mm_struct. 3338c2ecf20Sopenharmony_ci */ 3348c2ecf20Sopenharmony_cistruct gru_thread_state { 3358c2ecf20Sopenharmony_ci struct list_head ts_next; /* list - head at vma-private */ 3368c2ecf20Sopenharmony_ci struct mutex ts_ctxlock; /* load/unload CTX lock */ 3378c2ecf20Sopenharmony_ci struct mm_struct *ts_mm; /* mm currently mapped to 3388c2ecf20Sopenharmony_ci context */ 3398c2ecf20Sopenharmony_ci struct vm_area_struct *ts_vma; /* vma of GRU context */ 3408c2ecf20Sopenharmony_ci struct gru_state *ts_gru; /* GRU where the context is 3418c2ecf20Sopenharmony_ci loaded */ 3428c2ecf20Sopenharmony_ci struct gru_mm_struct *ts_gms; /* asid & ioproc struct */ 3438c2ecf20Sopenharmony_ci unsigned char ts_tlb_preload_count; /* TLB preload pages */ 3448c2ecf20Sopenharmony_ci unsigned long ts_cbr_map; /* map of allocated CBRs */ 3458c2ecf20Sopenharmony_ci unsigned long ts_dsr_map; /* map of allocated DATA 3468c2ecf20Sopenharmony_ci resources */ 3478c2ecf20Sopenharmony_ci unsigned long ts_steal_jiffies;/* jiffies when context last 3488c2ecf20Sopenharmony_ci stolen */ 3498c2ecf20Sopenharmony_ci long ts_user_options;/* misc user option flags */ 3508c2ecf20Sopenharmony_ci pid_t ts_tgid_owner; /* task that is using the 3518c2ecf20Sopenharmony_ci context - for migration */ 3528c2ecf20Sopenharmony_ci short ts_user_blade_id;/* user selected blade */ 3538c2ecf20Sopenharmony_ci char ts_user_chiplet_id;/* user selected chiplet */ 3548c2ecf20Sopenharmony_ci unsigned short ts_sizeavail; /* Pagesizes in use */ 3558c2ecf20Sopenharmony_ci int ts_tsid; /* thread that owns the 3568c2ecf20Sopenharmony_ci structure */ 3578c2ecf20Sopenharmony_ci int ts_tlb_int_select;/* target cpu if interrupts 3588c2ecf20Sopenharmony_ci enabled */ 3598c2ecf20Sopenharmony_ci int ts_ctxnum; /* context number where the 3608c2ecf20Sopenharmony_ci context is loaded */ 3618c2ecf20Sopenharmony_ci atomic_t ts_refcnt; /* reference count GTS */ 3628c2ecf20Sopenharmony_ci unsigned char ts_dsr_au_count;/* Number of DSR resources 3638c2ecf20Sopenharmony_ci required for contest */ 3648c2ecf20Sopenharmony_ci unsigned char ts_cbr_au_count;/* Number of CBR resources 3658c2ecf20Sopenharmony_ci required for contest */ 3668c2ecf20Sopenharmony_ci char ts_cch_req_slice;/* CCH packet slice */ 3678c2ecf20Sopenharmony_ci char ts_blade; /* If >= 0, migrate context if 3688c2ecf20Sopenharmony_ci ref from different blade */ 3698c2ecf20Sopenharmony_ci char ts_force_cch_reload; 3708c2ecf20Sopenharmony_ci char ts_cbr_idx[GRU_CBR_AU];/* CBR numbers of each 3718c2ecf20Sopenharmony_ci allocated CB */ 3728c2ecf20Sopenharmony_ci int ts_data_valid; /* Indicates if ts_gdata has 3738c2ecf20Sopenharmony_ci valid data */ 3748c2ecf20Sopenharmony_ci struct gru_gseg_statistics ustats; /* User statistics */ 3758c2ecf20Sopenharmony_ci unsigned long ts_gdata[]; /* save area for GRU data (CB, 3768c2ecf20Sopenharmony_ci DS, CBE) */ 3778c2ecf20Sopenharmony_ci}; 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci/* 3808c2ecf20Sopenharmony_ci * Threaded programs actually allocate an array of GSEGs when a context is 3818c2ecf20Sopenharmony_ci * created. Each thread uses a separate GSEG. TSID is the index into the GSEG 3828c2ecf20Sopenharmony_ci * array. 3838c2ecf20Sopenharmony_ci */ 3848c2ecf20Sopenharmony_ci#define TSID(a, v) (((a) - (v)->vm_start) / GRU_GSEG_PAGESIZE) 3858c2ecf20Sopenharmony_ci#define UGRUADDR(gts) ((gts)->ts_vma->vm_start + \ 3868c2ecf20Sopenharmony_ci (gts)->ts_tsid * GRU_GSEG_PAGESIZE) 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci#define NULLCTX (-1) /* if context not loaded into GRU */ 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------------- 3918c2ecf20Sopenharmony_ci * GRU State Tables 3928c2ecf20Sopenharmony_ci */ 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci/* 3958c2ecf20Sopenharmony_ci * One of these exists for each GRU chiplet. 3968c2ecf20Sopenharmony_ci */ 3978c2ecf20Sopenharmony_cistruct gru_state { 3988c2ecf20Sopenharmony_ci struct gru_blade_state *gs_blade; /* GRU state for entire 3998c2ecf20Sopenharmony_ci blade */ 4008c2ecf20Sopenharmony_ci unsigned long gs_gru_base_paddr; /* Physical address of 4018c2ecf20Sopenharmony_ci gru segments (64) */ 4028c2ecf20Sopenharmony_ci void *gs_gru_base_vaddr; /* Virtual address of 4038c2ecf20Sopenharmony_ci gru segments (64) */ 4048c2ecf20Sopenharmony_ci unsigned short gs_gid; /* unique GRU number */ 4058c2ecf20Sopenharmony_ci unsigned short gs_blade_id; /* blade of GRU */ 4068c2ecf20Sopenharmony_ci unsigned char gs_chiplet_id; /* blade chiplet of GRU */ 4078c2ecf20Sopenharmony_ci unsigned char gs_tgh_local_shift; /* used to pick TGH for 4088c2ecf20Sopenharmony_ci local flush */ 4098c2ecf20Sopenharmony_ci unsigned char gs_tgh_first_remote; /* starting TGH# for 4108c2ecf20Sopenharmony_ci remote flush */ 4118c2ecf20Sopenharmony_ci spinlock_t gs_asid_lock; /* lock used for 4128c2ecf20Sopenharmony_ci assigning asids */ 4138c2ecf20Sopenharmony_ci spinlock_t gs_lock; /* lock used for 4148c2ecf20Sopenharmony_ci assigning contexts */ 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci /* -- the following are protected by the gs_asid_lock spinlock ---- */ 4178c2ecf20Sopenharmony_ci unsigned int gs_asid; /* Next availe ASID */ 4188c2ecf20Sopenharmony_ci unsigned int gs_asid_limit; /* Limit of available 4198c2ecf20Sopenharmony_ci ASIDs */ 4208c2ecf20Sopenharmony_ci unsigned int gs_asid_gen; /* asid generation. 4218c2ecf20Sopenharmony_ci Inc on wrap */ 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci /* --- the following fields are protected by the gs_lock spinlock --- */ 4248c2ecf20Sopenharmony_ci unsigned long gs_context_map; /* bitmap to manage 4258c2ecf20Sopenharmony_ci contexts in use */ 4268c2ecf20Sopenharmony_ci unsigned long gs_cbr_map; /* bitmap to manage CB 4278c2ecf20Sopenharmony_ci resources */ 4288c2ecf20Sopenharmony_ci unsigned long gs_dsr_map; /* bitmap used to manage 4298c2ecf20Sopenharmony_ci DATA resources */ 4308c2ecf20Sopenharmony_ci unsigned int gs_reserved_cbrs; /* Number of kernel- 4318c2ecf20Sopenharmony_ci reserved cbrs */ 4328c2ecf20Sopenharmony_ci unsigned int gs_reserved_dsr_bytes; /* Bytes of kernel- 4338c2ecf20Sopenharmony_ci reserved dsrs */ 4348c2ecf20Sopenharmony_ci unsigned short gs_active_contexts; /* number of contexts 4358c2ecf20Sopenharmony_ci in use */ 4368c2ecf20Sopenharmony_ci struct gru_thread_state *gs_gts[GRU_NUM_CCH]; /* GTS currently using 4378c2ecf20Sopenharmony_ci the context */ 4388c2ecf20Sopenharmony_ci int gs_irq[GRU_NUM_TFM]; /* Interrupt irqs */ 4398c2ecf20Sopenharmony_ci}; 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci/* 4428c2ecf20Sopenharmony_ci * This structure contains the GRU state for all the GRUs on a blade. 4438c2ecf20Sopenharmony_ci */ 4448c2ecf20Sopenharmony_cistruct gru_blade_state { 4458c2ecf20Sopenharmony_ci void *kernel_cb; /* First kernel 4468c2ecf20Sopenharmony_ci reserved cb */ 4478c2ecf20Sopenharmony_ci void *kernel_dsr; /* First kernel 4488c2ecf20Sopenharmony_ci reserved DSR */ 4498c2ecf20Sopenharmony_ci struct rw_semaphore bs_kgts_sema; /* lock for kgts */ 4508c2ecf20Sopenharmony_ci struct gru_thread_state *bs_kgts; /* GTS for kernel use */ 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci /* ---- the following are used for managing kernel async GRU CBRs --- */ 4538c2ecf20Sopenharmony_ci int bs_async_dsr_bytes; /* DSRs for async */ 4548c2ecf20Sopenharmony_ci int bs_async_cbrs; /* CBRs AU for async */ 4558c2ecf20Sopenharmony_ci struct completion *bs_async_wq; 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ci /* ---- the following are protected by the bs_lock spinlock ---- */ 4588c2ecf20Sopenharmony_ci spinlock_t bs_lock; /* lock used for 4598c2ecf20Sopenharmony_ci stealing contexts */ 4608c2ecf20Sopenharmony_ci int bs_lru_ctxnum; /* STEAL - last context 4618c2ecf20Sopenharmony_ci stolen */ 4628c2ecf20Sopenharmony_ci struct gru_state *bs_lru_gru; /* STEAL - last gru 4638c2ecf20Sopenharmony_ci stolen */ 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci struct gru_state bs_grus[GRU_CHIPLETS_PER_BLADE]; 4668c2ecf20Sopenharmony_ci}; 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------------- 4698c2ecf20Sopenharmony_ci * Address Primitives 4708c2ecf20Sopenharmony_ci */ 4718c2ecf20Sopenharmony_ci#define get_tfm_for_cpu(g, c) \ 4728c2ecf20Sopenharmony_ci ((struct gru_tlb_fault_map *)get_tfm((g)->gs_gru_base_vaddr, (c))) 4738c2ecf20Sopenharmony_ci#define get_tfh_by_index(g, i) \ 4748c2ecf20Sopenharmony_ci ((struct gru_tlb_fault_handle *)get_tfh((g)->gs_gru_base_vaddr, (i))) 4758c2ecf20Sopenharmony_ci#define get_tgh_by_index(g, i) \ 4768c2ecf20Sopenharmony_ci ((struct gru_tlb_global_handle *)get_tgh((g)->gs_gru_base_vaddr, (i))) 4778c2ecf20Sopenharmony_ci#define get_cbe_by_index(g, i) \ 4788c2ecf20Sopenharmony_ci ((struct gru_control_block_extended *)get_cbe((g)->gs_gru_base_vaddr,\ 4798c2ecf20Sopenharmony_ci (i))) 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------------- 4828c2ecf20Sopenharmony_ci * Useful Macros 4838c2ecf20Sopenharmony_ci */ 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci/* Given a blade# & chiplet#, get a pointer to the GRU */ 4868c2ecf20Sopenharmony_ci#define get_gru(b, c) (&gru_base[b]->bs_grus[c]) 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci/* Number of bytes to save/restore when unloading/loading GRU contexts */ 4898c2ecf20Sopenharmony_ci#define DSR_BYTES(dsr) ((dsr) * GRU_DSR_AU_BYTES) 4908c2ecf20Sopenharmony_ci#define CBR_BYTES(cbr) ((cbr) * GRU_HANDLE_BYTES * GRU_CBR_AU_SIZE * 2) 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci/* Convert a user CB number to the actual CBRNUM */ 4938c2ecf20Sopenharmony_ci#define thread_cbr_number(gts, n) ((gts)->ts_cbr_idx[(n) / GRU_CBR_AU_SIZE] \ 4948c2ecf20Sopenharmony_ci * GRU_CBR_AU_SIZE + (n) % GRU_CBR_AU_SIZE) 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci/* Convert a gid to a pointer to the GRU */ 4978c2ecf20Sopenharmony_ci#define GID_TO_GRU(gid) \ 4988c2ecf20Sopenharmony_ci (gru_base[(gid) / GRU_CHIPLETS_PER_BLADE] ? \ 4998c2ecf20Sopenharmony_ci (&gru_base[(gid) / GRU_CHIPLETS_PER_BLADE]-> \ 5008c2ecf20Sopenharmony_ci bs_grus[(gid) % GRU_CHIPLETS_PER_BLADE]) : \ 5018c2ecf20Sopenharmony_ci NULL) 5028c2ecf20Sopenharmony_ci 5038c2ecf20Sopenharmony_ci/* Scan all active GRUs in a GRU bitmap */ 5048c2ecf20Sopenharmony_ci#define for_each_gru_in_bitmap(gid, map) \ 5058c2ecf20Sopenharmony_ci for_each_set_bit((gid), (map), GRU_MAX_GRUS) 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci/* Scan all active GRUs on a specific blade */ 5088c2ecf20Sopenharmony_ci#define for_each_gru_on_blade(gru, nid, i) \ 5098c2ecf20Sopenharmony_ci for ((gru) = gru_base[nid]->bs_grus, (i) = 0; \ 5108c2ecf20Sopenharmony_ci (i) < GRU_CHIPLETS_PER_BLADE; \ 5118c2ecf20Sopenharmony_ci (i)++, (gru)++) 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci/* Scan all GRUs */ 5148c2ecf20Sopenharmony_ci#define foreach_gid(gid) \ 5158c2ecf20Sopenharmony_ci for ((gid) = 0; (gid) < gru_max_gids; (gid)++) 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci/* Scan all active GTSs on a gru. Note: must hold ss_lock to use this macro. */ 5188c2ecf20Sopenharmony_ci#define for_each_gts_on_gru(gts, gru, ctxnum) \ 5198c2ecf20Sopenharmony_ci for ((ctxnum) = 0; (ctxnum) < GRU_NUM_CCH; (ctxnum)++) \ 5208c2ecf20Sopenharmony_ci if (((gts) = (gru)->gs_gts[ctxnum])) 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci/* Scan each CBR whose bit is set in a TFM (or copy of) */ 5238c2ecf20Sopenharmony_ci#define for_each_cbr_in_tfm(i, map) \ 5248c2ecf20Sopenharmony_ci for_each_set_bit((i), (map), GRU_NUM_CBE) 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci/* Scan each CBR in a CBR bitmap. Note: multiple CBRs in an allocation unit */ 5278c2ecf20Sopenharmony_ci#define for_each_cbr_in_allocation_map(i, map, k) \ 5288c2ecf20Sopenharmony_ci for_each_set_bit((k), (map), GRU_CBR_AU) \ 5298c2ecf20Sopenharmony_ci for ((i) = (k)*GRU_CBR_AU_SIZE; \ 5308c2ecf20Sopenharmony_ci (i) < ((k) + 1) * GRU_CBR_AU_SIZE; (i)++) 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci/* Scan each DSR in a DSR bitmap. Note: multiple DSRs in an allocation unit */ 5338c2ecf20Sopenharmony_ci#define for_each_dsr_in_allocation_map(i, map, k) \ 5348c2ecf20Sopenharmony_ci for_each_set_bit((k), (const unsigned long *)(map), GRU_DSR_AU) \ 5358c2ecf20Sopenharmony_ci for ((i) = (k) * GRU_DSR_AU_CL; \ 5368c2ecf20Sopenharmony_ci (i) < ((k) + 1) * GRU_DSR_AU_CL; (i)++) 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci#define gseg_physical_address(gru, ctxnum) \ 5398c2ecf20Sopenharmony_ci ((gru)->gs_gru_base_paddr + ctxnum * GRU_GSEG_STRIDE) 5408c2ecf20Sopenharmony_ci#define gseg_virtual_address(gru, ctxnum) \ 5418c2ecf20Sopenharmony_ci ((gru)->gs_gru_base_vaddr + ctxnum * GRU_GSEG_STRIDE) 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------------- 5448c2ecf20Sopenharmony_ci * Lock / Unlock GRU handles 5458c2ecf20Sopenharmony_ci * Use the "delresp" bit in the handle as a "lock" bit. 5468c2ecf20Sopenharmony_ci */ 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ci/* Lock hierarchy checking enabled only in emulator */ 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci/* 0 = lock failed, 1 = locked */ 5518c2ecf20Sopenharmony_cistatic inline int __trylock_handle(void *h) 5528c2ecf20Sopenharmony_ci{ 5538c2ecf20Sopenharmony_ci return !test_and_set_bit(1, h); 5548c2ecf20Sopenharmony_ci} 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_cistatic inline void __lock_handle(void *h) 5578c2ecf20Sopenharmony_ci{ 5588c2ecf20Sopenharmony_ci while (test_and_set_bit(1, h)) 5598c2ecf20Sopenharmony_ci cpu_relax(); 5608c2ecf20Sopenharmony_ci} 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_cistatic inline void __unlock_handle(void *h) 5638c2ecf20Sopenharmony_ci{ 5648c2ecf20Sopenharmony_ci clear_bit(1, h); 5658c2ecf20Sopenharmony_ci} 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_cistatic inline int trylock_cch_handle(struct gru_context_configuration_handle *cch) 5688c2ecf20Sopenharmony_ci{ 5698c2ecf20Sopenharmony_ci return __trylock_handle(cch); 5708c2ecf20Sopenharmony_ci} 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_cistatic inline void lock_cch_handle(struct gru_context_configuration_handle *cch) 5738c2ecf20Sopenharmony_ci{ 5748c2ecf20Sopenharmony_ci __lock_handle(cch); 5758c2ecf20Sopenharmony_ci} 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_cistatic inline void unlock_cch_handle(struct gru_context_configuration_handle 5788c2ecf20Sopenharmony_ci *cch) 5798c2ecf20Sopenharmony_ci{ 5808c2ecf20Sopenharmony_ci __unlock_handle(cch); 5818c2ecf20Sopenharmony_ci} 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_cistatic inline void lock_tgh_handle(struct gru_tlb_global_handle *tgh) 5848c2ecf20Sopenharmony_ci{ 5858c2ecf20Sopenharmony_ci __lock_handle(tgh); 5868c2ecf20Sopenharmony_ci} 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_cistatic inline void unlock_tgh_handle(struct gru_tlb_global_handle *tgh) 5898c2ecf20Sopenharmony_ci{ 5908c2ecf20Sopenharmony_ci __unlock_handle(tgh); 5918c2ecf20Sopenharmony_ci} 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_cistatic inline int is_kernel_context(struct gru_thread_state *gts) 5948c2ecf20Sopenharmony_ci{ 5958c2ecf20Sopenharmony_ci return !gts->ts_mm; 5968c2ecf20Sopenharmony_ci} 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci/* 5998c2ecf20Sopenharmony_ci * The following are for Nehelem-EX. A more general scheme is needed for 6008c2ecf20Sopenharmony_ci * future processors. 6018c2ecf20Sopenharmony_ci */ 6028c2ecf20Sopenharmony_ci#define UV_MAX_INT_CORES 8 6038c2ecf20Sopenharmony_ci#define uv_cpu_socket_number(p) ((cpu_physical_id(p) >> 5) & 1) 6048c2ecf20Sopenharmony_ci#define uv_cpu_ht_number(p) (cpu_physical_id(p) & 1) 6058c2ecf20Sopenharmony_ci#define uv_cpu_core_number(p) (((cpu_physical_id(p) >> 2) & 4) | \ 6068c2ecf20Sopenharmony_ci ((cpu_physical_id(p) >> 1) & 3)) 6078c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------------- 6088c2ecf20Sopenharmony_ci * Function prototypes & externs 6098c2ecf20Sopenharmony_ci */ 6108c2ecf20Sopenharmony_cistruct gru_unload_context_req; 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_ciextern const struct vm_operations_struct gru_vm_ops; 6138c2ecf20Sopenharmony_ciextern struct device *grudev; 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ciextern struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma, 6168c2ecf20Sopenharmony_ci int tsid); 6178c2ecf20Sopenharmony_ciextern struct gru_thread_state *gru_find_thread_state(struct vm_area_struct 6188c2ecf20Sopenharmony_ci *vma, int tsid); 6198c2ecf20Sopenharmony_ciextern struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct 6208c2ecf20Sopenharmony_ci *vma, int tsid); 6218c2ecf20Sopenharmony_ciextern struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts); 6228c2ecf20Sopenharmony_ciextern void gru_load_context(struct gru_thread_state *gts); 6238c2ecf20Sopenharmony_ciextern void gru_steal_context(struct gru_thread_state *gts); 6248c2ecf20Sopenharmony_ciextern void gru_unload_context(struct gru_thread_state *gts, int savestate); 6258c2ecf20Sopenharmony_ciextern int gru_update_cch(struct gru_thread_state *gts); 6268c2ecf20Sopenharmony_ciextern void gts_drop(struct gru_thread_state *gts); 6278c2ecf20Sopenharmony_ciextern void gru_tgh_flush_init(struct gru_state *gru); 6288c2ecf20Sopenharmony_ciextern int gru_kservices_init(void); 6298c2ecf20Sopenharmony_ciextern void gru_kservices_exit(void); 6308c2ecf20Sopenharmony_ciextern irqreturn_t gru0_intr(int irq, void *dev_id); 6318c2ecf20Sopenharmony_ciextern irqreturn_t gru1_intr(int irq, void *dev_id); 6328c2ecf20Sopenharmony_ciextern irqreturn_t gru_intr_mblade(int irq, void *dev_id); 6338c2ecf20Sopenharmony_ciextern int gru_dump_chiplet_request(unsigned long arg); 6348c2ecf20Sopenharmony_ciextern long gru_get_gseg_statistics(unsigned long arg); 6358c2ecf20Sopenharmony_ciextern int gru_handle_user_call_os(unsigned long address); 6368c2ecf20Sopenharmony_ciextern int gru_user_flush_tlb(unsigned long arg); 6378c2ecf20Sopenharmony_ciextern int gru_user_unload_context(unsigned long arg); 6388c2ecf20Sopenharmony_ciextern int gru_get_exception_detail(unsigned long arg); 6398c2ecf20Sopenharmony_ciextern int gru_set_context_option(unsigned long address); 6408c2ecf20Sopenharmony_ciextern int gru_check_context_placement(struct gru_thread_state *gts); 6418c2ecf20Sopenharmony_ciextern int gru_cpu_fault_map_id(void); 6428c2ecf20Sopenharmony_ciextern struct vm_area_struct *gru_find_vma(unsigned long vaddr); 6438c2ecf20Sopenharmony_ciextern void gru_flush_all_tlb(struct gru_state *gru); 6448c2ecf20Sopenharmony_ciextern int gru_proc_init(void); 6458c2ecf20Sopenharmony_ciextern void gru_proc_exit(void); 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ciextern struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma, 6488c2ecf20Sopenharmony_ci int cbr_au_count, int dsr_au_count, 6498c2ecf20Sopenharmony_ci unsigned char tlb_preload_count, int options, int tsid); 6508c2ecf20Sopenharmony_ciextern unsigned long gru_reserve_cb_resources(struct gru_state *gru, 6518c2ecf20Sopenharmony_ci int cbr_au_count, char *cbmap); 6528c2ecf20Sopenharmony_ciextern unsigned long gru_reserve_ds_resources(struct gru_state *gru, 6538c2ecf20Sopenharmony_ci int dsr_au_count, char *dsmap); 6548c2ecf20Sopenharmony_ciextern vm_fault_t gru_fault(struct vm_fault *vmf); 6558c2ecf20Sopenharmony_ciextern struct gru_mm_struct *gru_register_mmu_notifier(void); 6568c2ecf20Sopenharmony_ciextern void gru_drop_mmu_notifier(struct gru_mm_struct *gms); 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ciextern int gru_ktest(unsigned long arg); 6598c2ecf20Sopenharmony_ciextern void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start, 6608c2ecf20Sopenharmony_ci unsigned long len); 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ciextern unsigned long gru_options; 6638c2ecf20Sopenharmony_ci 6648c2ecf20Sopenharmony_ci#endif /* __GRUTABLES_H__ */ 665