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