1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#ifndef __GRUTABLES_H__
24#define __GRUTABLES_H__
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145#include <linux/rmap.h>
146#include <linux/interrupt.h>
147#include <linux/mutex.h>
148#include <linux/wait.h>
149#include <linux/mmu_notifier.h>
150#include "gru.h"
151#include "grulib.h"
152#include "gruhandles.h"
153
154extern struct gru_stats_s gru_stats;
155extern struct gru_blade_state *gru_base[];
156extern unsigned long gru_start_paddr, gru_end_paddr;
157extern void *gru_start_vaddr;
158extern unsigned int gru_max_gids;
159
160#define GRU_MAX_BLADES MAX_NUMNODES
161#define GRU_MAX_GRUS (GRU_MAX_BLADES * GRU_CHIPLETS_PER_BLADE)
162
163#define GRU_DRIVER_ID_STR "SGI GRU Device Driver"
164#define GRU_DRIVER_VERSION_STR "0.85"
165
166
167
168
169struct gru_stats_s {
170 atomic_long_t vdata_alloc;
171 atomic_long_t vdata_free;
172 atomic_long_t gts_alloc;
173 atomic_long_t gts_free;
174 atomic_long_t gms_alloc;
175 atomic_long_t gms_free;
176 atomic_long_t gts_double_allocate;
177 atomic_long_t assign_context;
178 atomic_long_t assign_context_failed;
179 atomic_long_t free_context;
180 atomic_long_t load_user_context;
181 atomic_long_t load_kernel_context;
182 atomic_long_t lock_kernel_context;
183 atomic_long_t unlock_kernel_context;
184 atomic_long_t steal_user_context;
185 atomic_long_t steal_kernel_context;
186 atomic_long_t steal_context_failed;
187 atomic_long_t nopfn;
188 atomic_long_t asid_new;
189 atomic_long_t asid_next;
190 atomic_long_t asid_wrap;
191 atomic_long_t asid_reuse;
192 atomic_long_t intr;
193 atomic_long_t intr_cbr;
194 atomic_long_t intr_tfh;
195 atomic_long_t intr_spurious;
196 atomic_long_t intr_mm_lock_failed;
197 atomic_long_t call_os;
198 atomic_long_t call_os_wait_queue;
199 atomic_long_t user_flush_tlb;
200 atomic_long_t user_unload_context;
201 atomic_long_t user_exception;
202 atomic_long_t set_context_option;
203 atomic_long_t check_context_retarget_intr;
204 atomic_long_t check_context_unload;
205 atomic_long_t tlb_dropin;
206 atomic_long_t tlb_preload_page;
207 atomic_long_t tlb_dropin_fail_no_asid;
208 atomic_long_t tlb_dropin_fail_upm;
209 atomic_long_t tlb_dropin_fail_invalid;
210 atomic_long_t tlb_dropin_fail_range_active;
211 atomic_long_t tlb_dropin_fail_idle;
212 atomic_long_t tlb_dropin_fail_fmm;
213 atomic_long_t tlb_dropin_fail_no_exception;
214 atomic_long_t tfh_stale_on_fault;
215 atomic_long_t mmu_invalidate_range;
216 atomic_long_t mmu_invalidate_page;
217 atomic_long_t flush_tlb;
218 atomic_long_t flush_tlb_gru;
219 atomic_long_t flush_tlb_gru_tgh;
220 atomic_long_t flush_tlb_gru_zero_asid;
221
222 atomic_long_t copy_gpa;
223 atomic_long_t read_gpa;
224
225 atomic_long_t mesq_receive;
226 atomic_long_t mesq_receive_none;
227 atomic_long_t mesq_send;
228 atomic_long_t mesq_send_failed;
229 atomic_long_t mesq_noop;
230 atomic_long_t mesq_send_unexpected_error;
231 atomic_long_t mesq_send_lb_overflow;
232 atomic_long_t mesq_send_qlimit_reached;
233 atomic_long_t mesq_send_amo_nacked;
234 atomic_long_t mesq_send_put_nacked;
235 atomic_long_t mesq_page_overflow;
236 atomic_long_t mesq_qf_locked;
237 atomic_long_t mesq_qf_noop_not_full;
238 atomic_long_t mesq_qf_switch_head_failed;
239 atomic_long_t mesq_qf_unexpected_error;
240 atomic_long_t mesq_noop_unexpected_error;
241 atomic_long_t mesq_noop_lb_overflow;
242 atomic_long_t mesq_noop_qlimit_reached;
243 atomic_long_t mesq_noop_amo_nacked;
244 atomic_long_t mesq_noop_put_nacked;
245 atomic_long_t mesq_noop_page_overflow;
246
247};
248
249enum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync,
250 cchop_deallocate, tfhop_write_only, tfhop_write_restart,
251 tghop_invalidate, mcsop_last};
252
253struct mcs_op_statistic {
254 atomic_long_t count;
255 atomic_long_t total;
256 unsigned long max;
257};
258
259extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
260
261#define OPT_DPRINT 1
262#define OPT_STATS 2
263
264
265#define IRQ_GRU 110
266
267
268#define GRU_ASSIGN_DELAY ((HZ * 20) / 1000)
269
270
271
272
273
274#define GRU_STEAL_DELAY ((HZ * 200) / 1000)
275
276#define STAT(id) do { \
277 if (gru_options & OPT_STATS) \
278 atomic_long_inc(&gru_stats.id); \
279 } while (0)
280
281#ifdef CONFIG_SGI_GRU_DEBUG
282#define gru_dbg(dev, fmt, x...) \
283 do { \
284 if (gru_options & OPT_DPRINT) \
285 printk(KERN_DEBUG "GRU:%d %s: " fmt, smp_processor_id(), __func__, x);\
286 } while (0)
287#else
288#define gru_dbg(x...)
289#endif
290
291
292
293
294#define MAX_ASID 0xfffff0
295#define MIN_ASID 8
296#define ASID_INC 8
297
298
299#define VADDR_HI_BIT 64
300#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3)
301#define GRUASID(asid, addr) ((asid) + GRUREGION(addr))
302
303
304
305
306
307struct gru_state;
308
309
310
311
312
313struct gru_mm_tracker {
314 unsigned int mt_asid_gen:24;
315 unsigned int mt_asid:24;
316 unsigned short mt_ctxbitmap:16;
317
318} __attribute__ ((packed));
319
320struct gru_mm_struct {
321 struct mmu_notifier ms_notifier;
322 atomic_t ms_refcnt;
323 spinlock_t ms_asid_lock;
324 atomic_t ms_range_active;
325 char ms_released;
326 wait_queue_head_t ms_wait_queue;
327 DECLARE_BITMAP(ms_asidmap, GRU_MAX_GRUS);
328 struct gru_mm_tracker ms_asids[GRU_MAX_GRUS];
329};
330
331
332
333
334
335struct gru_vma_data {
336 spinlock_t vd_lock;
337 struct list_head vd_head;
338 long vd_user_options;
339 int vd_cbr_au_count;
340 int vd_dsr_au_count;
341 unsigned char vd_tlb_preload_count;
342};
343
344
345
346
347
348struct gru_thread_state {
349 struct list_head ts_next;
350 struct mutex ts_ctxlock;
351 struct mm_struct *ts_mm;
352
353 struct vm_area_struct *ts_vma;
354 struct gru_state *ts_gru;
355
356 struct gru_mm_struct *ts_gms;
357 unsigned char ts_tlb_preload_count;
358 unsigned long ts_cbr_map;
359 unsigned long ts_dsr_map;
360
361 unsigned long ts_steal_jiffies;
362
363 long ts_user_options;
364 pid_t ts_tgid_owner;
365
366 short ts_user_blade_id;
367 char ts_user_chiplet_id;
368 unsigned short ts_sizeavail;
369 int ts_tsid;
370
371 int ts_tlb_int_select;
372
373 int ts_ctxnum;
374
375 atomic_t ts_refcnt;
376 unsigned char ts_dsr_au_count;
377
378 unsigned char ts_cbr_au_count;
379
380 char ts_cch_req_slice;
381 char ts_blade;
382
383 char ts_force_cch_reload;
384 char ts_cbr_idx[GRU_CBR_AU];
385
386 int ts_data_valid;
387
388 struct gru_gseg_statistics ustats;
389 unsigned long ts_gdata[0];
390
391};
392
393
394
395
396
397
398#define TSID(a, v) (((a) - (v)->vm_start) / GRU_GSEG_PAGESIZE)
399#define UGRUADDR(gts) ((gts)->ts_vma->vm_start + \
400 (gts)->ts_tsid * GRU_GSEG_PAGESIZE)
401
402#define NULLCTX (-1)
403
404
405
406
407
408
409
410
411struct gru_state {
412 struct gru_blade_state *gs_blade;
413
414 unsigned long gs_gru_base_paddr;
415
416 void *gs_gru_base_vaddr;
417
418 unsigned short gs_gid;
419 unsigned short gs_blade_id;
420 unsigned char gs_chiplet_id;
421 unsigned char gs_tgh_local_shift;
422
423 unsigned char gs_tgh_first_remote;
424
425 spinlock_t gs_asid_lock;
426
427 spinlock_t gs_lock;
428
429
430
431 unsigned int gs_asid;
432 unsigned int gs_asid_limit;
433
434 unsigned int gs_asid_gen;
435
436
437
438 unsigned long gs_context_map;
439
440 unsigned long gs_cbr_map;
441
442 unsigned long gs_dsr_map;
443
444 unsigned int gs_reserved_cbrs;
445
446 unsigned int gs_reserved_dsr_bytes;
447
448 unsigned short gs_active_contexts;
449
450 struct gru_thread_state *gs_gts[GRU_NUM_CCH];
451
452 int gs_irq[GRU_NUM_TFM];
453};
454
455
456
457
458struct gru_blade_state {
459 void *kernel_cb;
460
461 void *kernel_dsr;
462
463 struct rw_semaphore bs_kgts_sema;
464 struct gru_thread_state *bs_kgts;
465
466
467 int bs_async_dsr_bytes;
468 int bs_async_cbrs;
469 struct completion *bs_async_wq;
470
471
472 spinlock_t bs_lock;
473
474 int bs_lru_ctxnum;
475
476 struct gru_state *bs_lru_gru;
477
478
479 struct gru_state bs_grus[GRU_CHIPLETS_PER_BLADE];
480};
481
482
483
484
485#define get_tfm_for_cpu(g, c) \
486 ((struct gru_tlb_fault_map *)get_tfm((g)->gs_gru_base_vaddr, (c)))
487#define get_tfh_by_index(g, i) \
488 ((struct gru_tlb_fault_handle *)get_tfh((g)->gs_gru_base_vaddr, (i)))
489#define get_tgh_by_index(g, i) \
490 ((struct gru_tlb_global_handle *)get_tgh((g)->gs_gru_base_vaddr, (i)))
491#define get_cbe_by_index(g, i) \
492 ((struct gru_control_block_extended *)get_cbe((g)->gs_gru_base_vaddr,\
493 (i)))
494
495
496
497
498
499
500#define get_gru(b, c) (&gru_base[b]->bs_grus[c])
501
502
503#define DSR_BYTES(dsr) ((dsr) * GRU_DSR_AU_BYTES)
504#define CBR_BYTES(cbr) ((cbr) * GRU_HANDLE_BYTES * GRU_CBR_AU_SIZE * 2)
505
506
507#define thread_cbr_number(gts, n) ((gts)->ts_cbr_idx[(n) / GRU_CBR_AU_SIZE] \
508 * GRU_CBR_AU_SIZE + (n) % GRU_CBR_AU_SIZE)
509
510
511#define GID_TO_GRU(gid) \
512 (gru_base[(gid) / GRU_CHIPLETS_PER_BLADE] ? \
513 (&gru_base[(gid) / GRU_CHIPLETS_PER_BLADE]-> \
514 bs_grus[(gid) % GRU_CHIPLETS_PER_BLADE]) : \
515 NULL)
516
517
518#define for_each_gru_in_bitmap(gid, map) \
519 for_each_set_bit((gid), (map), GRU_MAX_GRUS)
520
521
522#define for_each_gru_on_blade(gru, nid, i) \
523 for ((gru) = gru_base[nid]->bs_grus, (i) = 0; \
524 (i) < GRU_CHIPLETS_PER_BLADE; \
525 (i)++, (gru)++)
526
527
528#define foreach_gid(gid) \
529 for ((gid) = 0; (gid) < gru_max_gids; (gid)++)
530
531
532#define for_each_gts_on_gru(gts, gru, ctxnum) \
533 for ((ctxnum) = 0; (ctxnum) < GRU_NUM_CCH; (ctxnum)++) \
534 if (((gts) = (gru)->gs_gts[ctxnum]))
535
536
537#define for_each_cbr_in_tfm(i, map) \
538 for_each_set_bit((i), (map), GRU_NUM_CBE)
539
540
541#define for_each_cbr_in_allocation_map(i, map, k) \
542 for_each_set_bit((k), (map), GRU_CBR_AU) \
543 for ((i) = (k)*GRU_CBR_AU_SIZE; \
544 (i) < ((k) + 1) * GRU_CBR_AU_SIZE; (i)++)
545
546
547#define for_each_dsr_in_allocation_map(i, map, k) \
548 for_each_set_bit((k), (const unsigned long *)(map), GRU_DSR_AU) \
549 for ((i) = (k) * GRU_DSR_AU_CL; \
550 (i) < ((k) + 1) * GRU_DSR_AU_CL; (i)++)
551
552#define gseg_physical_address(gru, ctxnum) \
553 ((gru)->gs_gru_base_paddr + ctxnum * GRU_GSEG_STRIDE)
554#define gseg_virtual_address(gru, ctxnum) \
555 ((gru)->gs_gru_base_vaddr + ctxnum * GRU_GSEG_STRIDE)
556
557
558
559
560
561
562
563
564
565static inline int __trylock_handle(void *h)
566{
567 return !test_and_set_bit(1, h);
568}
569
570static inline void __lock_handle(void *h)
571{
572 while (test_and_set_bit(1, h))
573 cpu_relax();
574}
575
576static inline void __unlock_handle(void *h)
577{
578 clear_bit(1, h);
579}
580
581static inline int trylock_cch_handle(struct gru_context_configuration_handle *cch)
582{
583 return __trylock_handle(cch);
584}
585
586static inline void lock_cch_handle(struct gru_context_configuration_handle *cch)
587{
588 __lock_handle(cch);
589}
590
591static inline void unlock_cch_handle(struct gru_context_configuration_handle
592 *cch)
593{
594 __unlock_handle(cch);
595}
596
597static inline void lock_tgh_handle(struct gru_tlb_global_handle *tgh)
598{
599 __lock_handle(tgh);
600}
601
602static inline void unlock_tgh_handle(struct gru_tlb_global_handle *tgh)
603{
604 __unlock_handle(tgh);
605}
606
607static inline int is_kernel_context(struct gru_thread_state *gts)
608{
609 return !gts->ts_mm;
610}
611
612
613
614
615
616#define UV_MAX_INT_CORES 8
617#define uv_cpu_socket_number(p) ((cpu_physical_id(p) >> 5) & 1)
618#define uv_cpu_ht_number(p) (cpu_physical_id(p) & 1)
619#define uv_cpu_core_number(p) (((cpu_physical_id(p) >> 2) & 4) | \
620 ((cpu_physical_id(p) >> 1) & 3))
621
622
623
624struct gru_unload_context_req;
625
626extern const struct vm_operations_struct gru_vm_ops;
627extern struct device *grudev;
628
629extern struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma,
630 int tsid);
631extern struct gru_thread_state *gru_find_thread_state(struct vm_area_struct
632 *vma, int tsid);
633extern struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct
634 *vma, int tsid);
635extern struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts);
636extern void gru_load_context(struct gru_thread_state *gts);
637extern void gru_steal_context(struct gru_thread_state *gts);
638extern void gru_unload_context(struct gru_thread_state *gts, int savestate);
639extern int gru_update_cch(struct gru_thread_state *gts);
640extern void gts_drop(struct gru_thread_state *gts);
641extern void gru_tgh_flush_init(struct gru_state *gru);
642extern int gru_kservices_init(void);
643extern void gru_kservices_exit(void);
644extern irqreturn_t gru0_intr(int irq, void *dev_id);
645extern irqreturn_t gru1_intr(int irq, void *dev_id);
646extern irqreturn_t gru_intr_mblade(int irq, void *dev_id);
647extern int gru_dump_chiplet_request(unsigned long arg);
648extern long gru_get_gseg_statistics(unsigned long arg);
649extern int gru_handle_user_call_os(unsigned long address);
650extern int gru_user_flush_tlb(unsigned long arg);
651extern int gru_user_unload_context(unsigned long arg);
652extern int gru_get_exception_detail(unsigned long arg);
653extern int gru_set_context_option(unsigned long address);
654extern void gru_check_context_placement(struct gru_thread_state *gts);
655extern int gru_cpu_fault_map_id(void);
656extern struct vm_area_struct *gru_find_vma(unsigned long vaddr);
657extern void gru_flush_all_tlb(struct gru_state *gru);
658extern int gru_proc_init(void);
659extern void gru_proc_exit(void);
660
661extern struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
662 int cbr_au_count, int dsr_au_count,
663 unsigned char tlb_preload_count, int options, int tsid);
664extern unsigned long gru_reserve_cb_resources(struct gru_state *gru,
665 int cbr_au_count, char *cbmap);
666extern unsigned long gru_reserve_ds_resources(struct gru_state *gru,
667 int dsr_au_count, char *dsmap);
668extern int gru_fault(struct vm_area_struct *, struct vm_fault *vmf);
669extern struct gru_mm_struct *gru_register_mmu_notifier(void);
670extern void gru_drop_mmu_notifier(struct gru_mm_struct *gms);
671
672extern int gru_ktest(unsigned long arg);
673extern void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start,
674 unsigned long len);
675
676extern unsigned long gru_options;
677
678#endif
679