Merge branch 'for-2.6.31' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[pandora-kernel.git] / drivers / misc / sgi-gru / gruhandles.h
1 /*
2  * SN Platform GRU Driver
3  *
4  *              GRU HANDLE DEFINITION
5  *
6  *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #ifndef __GRUHANDLES_H__
24 #define __GRUHANDLES_H__
25 #include "gru_instructions.h"
26
27 /*
28  * Manifest constants for GRU Memory Map
29  */
30 #define GRU_GSEG0_BASE          0
31 #define GRU_MCS_BASE            (64 * 1024 * 1024)
32 #define GRU_SIZE                (128UL * 1024 * 1024)
33
34 /* Handle & resource counts */
35 #define GRU_NUM_CB              128
36 #define GRU_NUM_DSR_BYTES       (32 * 1024)
37 #define GRU_NUM_TFM             16
38 #define GRU_NUM_TGH             24
39 #define GRU_NUM_CBE             128
40 #define GRU_NUM_TFH             128
41 #define GRU_NUM_CCH             16
42
43 /* Maximum resource counts that can be reserved by user programs */
44 #define GRU_NUM_USER_CBR        GRU_NUM_CBE
45 #define GRU_NUM_USER_DSR_BYTES  GRU_NUM_DSR_BYTES
46
47 /* Bytes per handle & handle stride. Code assumes all cb, tfh, cbe handles
48  * are the same */
49 #define GRU_HANDLE_BYTES        64
50 #define GRU_HANDLE_STRIDE       256
51
52 /* Base addresses of handles */
53 #define GRU_TFM_BASE            (GRU_MCS_BASE + 0x00000)
54 #define GRU_TGH_BASE            (GRU_MCS_BASE + 0x08000)
55 #define GRU_CBE_BASE            (GRU_MCS_BASE + 0x10000)
56 #define GRU_TFH_BASE            (GRU_MCS_BASE + 0x18000)
57 #define GRU_CCH_BASE            (GRU_MCS_BASE + 0x20000)
58
59 /* User gseg constants */
60 #define GRU_GSEG_STRIDE         (4 * 1024 * 1024)
61 #define GSEG_BASE(a)            ((a) & ~(GRU_GSEG_PAGESIZE - 1))
62
63 /* Data segment constants */
64 #define GRU_DSR_AU_BYTES        1024
65 #define GRU_DSR_CL              (GRU_NUM_DSR_BYTES / GRU_CACHE_LINE_BYTES)
66 #define GRU_DSR_AU_CL           (GRU_DSR_AU_BYTES / GRU_CACHE_LINE_BYTES)
67 #define GRU_DSR_AU              (GRU_NUM_DSR_BYTES / GRU_DSR_AU_BYTES)
68
69 /* Control block constants */
70 #define GRU_CBR_AU_SIZE         2
71 #define GRU_CBR_AU              (GRU_NUM_CBE / GRU_CBR_AU_SIZE)
72
73 /* Convert resource counts to the number of AU */
74 #define GRU_DS_BYTES_TO_AU(n)   DIV_ROUND_UP(n, GRU_DSR_AU_BYTES)
75 #define GRU_CB_COUNT_TO_AU(n)   DIV_ROUND_UP(n, GRU_CBR_AU_SIZE)
76
77 /* UV limits */
78 #define GRU_CHIPLETS_PER_HUB    2
79 #define GRU_HUBS_PER_BLADE      1
80 #define GRU_CHIPLETS_PER_BLADE  (GRU_HUBS_PER_BLADE * GRU_CHIPLETS_PER_HUB)
81
82 /* User GRU Gseg offsets */
83 #define GRU_CB_BASE             0
84 #define GRU_CB_LIMIT            (GRU_CB_BASE + GRU_HANDLE_STRIDE * GRU_NUM_CBE)
85 #define GRU_DS_BASE             0x20000
86 #define GRU_DS_LIMIT            (GRU_DS_BASE + GRU_NUM_DSR_BYTES)
87
88 /* Convert a GRU physical address to the chiplet offset */
89 #define GSEGPOFF(h)             ((h) & (GRU_SIZE - 1))
90
91 /* Convert an arbitrary handle address to the beginning of the GRU segment */
92 #define GRUBASE(h)              ((void *)((unsigned long)(h) & ~(GRU_SIZE - 1)))
93
94 /* General addressing macros. */
95 static inline void *get_gseg_base_address(void *base, int ctxnum)
96 {
97         return (void *)(base + GRU_GSEG0_BASE + GRU_GSEG_STRIDE * ctxnum);
98 }
99
100 static inline void *get_gseg_base_address_cb(void *base, int ctxnum, int line)
101 {
102         return (void *)(get_gseg_base_address(base, ctxnum) +
103                         GRU_CB_BASE + GRU_HANDLE_STRIDE * line);
104 }
105
106 static inline void *get_gseg_base_address_ds(void *base, int ctxnum, int line)
107 {
108         return (void *)(get_gseg_base_address(base, ctxnum) + GRU_DS_BASE +
109                         GRU_CACHE_LINE_BYTES * line);
110 }
111
112 static inline struct gru_tlb_fault_map *get_tfm(void *base, int ctxnum)
113 {
114         return (struct gru_tlb_fault_map *)(base + GRU_TFM_BASE +
115                                         ctxnum * GRU_HANDLE_STRIDE);
116 }
117
118 static inline struct gru_tlb_global_handle *get_tgh(void *base, int ctxnum)
119 {
120         return (struct gru_tlb_global_handle *)(base + GRU_TGH_BASE +
121                                         ctxnum * GRU_HANDLE_STRIDE);
122 }
123
124 static inline struct gru_control_block_extended *get_cbe(void *base, int ctxnum)
125 {
126         return (struct gru_control_block_extended *)(base + GRU_CBE_BASE +
127                                         ctxnum * GRU_HANDLE_STRIDE);
128 }
129
130 static inline struct gru_tlb_fault_handle *get_tfh(void *base, int ctxnum)
131 {
132         return (struct gru_tlb_fault_handle *)(base + GRU_TFH_BASE +
133                                         ctxnum * GRU_HANDLE_STRIDE);
134 }
135
136 static inline struct gru_context_configuration_handle *get_cch(void *base,
137                                         int ctxnum)
138 {
139         return (struct gru_context_configuration_handle *)(base +
140                                 GRU_CCH_BASE + ctxnum * GRU_HANDLE_STRIDE);
141 }
142
143 static inline unsigned long get_cb_number(void *cb)
144 {
145         return (((unsigned long)cb - GRU_CB_BASE) % GRU_GSEG_PAGESIZE) /
146                                         GRU_HANDLE_STRIDE;
147 }
148
149 /* byte offset to a specific GRU chiplet. (p=pnode, c=chiplet (0 or 1)*/
150 static inline unsigned long gru_chiplet_paddr(unsigned long paddr, int pnode,
151                                                         int chiplet)
152 {
153         return paddr + GRU_SIZE * (2 * pnode  + chiplet);
154 }
155
156 static inline void *gru_chiplet_vaddr(void *vaddr, int pnode, int chiplet)
157 {
158         return vaddr + GRU_SIZE * (2 * pnode  + chiplet);
159 }
160
161
162
163 /*
164  * Global TLB Fault Map
165  *      Bitmap of outstanding TLB misses needing interrupt/polling service.
166  *
167  */
168 struct gru_tlb_fault_map {
169         unsigned long fault_bits[BITS_TO_LONGS(GRU_NUM_CBE)];
170         unsigned long fill0[2];
171         unsigned long done_bits[BITS_TO_LONGS(GRU_NUM_CBE)];
172         unsigned long fill1[2];
173 };
174
175 /*
176  * TGH - TLB Global Handle
177  *      Used for TLB flushing.
178  *
179  */
180 struct gru_tlb_global_handle {
181         unsigned int cmd:1;             /* DW 0 */
182         unsigned int delresp:1;
183         unsigned int opc:1;
184         unsigned int fill1:5;
185
186         unsigned int fill2:8;
187
188         unsigned int status:2;
189         unsigned long fill3:2;
190         unsigned int state:3;
191         unsigned long fill4:1;
192
193         unsigned int cause:3;
194         unsigned long fill5:37;
195
196         unsigned long vaddr:64;         /* DW 1 */
197
198         unsigned int asid:24;           /* DW 2 */
199         unsigned int fill6:8;
200
201         unsigned int pagesize:5;
202         unsigned int fill7:11;
203
204         unsigned int global:1;
205         unsigned int fill8:15;
206
207         unsigned long vaddrmask:39;     /* DW 3 */
208         unsigned int fill9:9;
209         unsigned int n:10;
210         unsigned int fill10:6;
211
212         unsigned int ctxbitmap:16;      /* DW4 */
213         unsigned long fill11[3];
214 };
215
216 enum gru_tgh_cmd {
217         TGHCMD_START
218 };
219
220 enum gru_tgh_opc {
221         TGHOP_TLBNOP,
222         TGHOP_TLBINV
223 };
224
225 enum gru_tgh_status {
226         TGHSTATUS_IDLE,
227         TGHSTATUS_EXCEPTION,
228         TGHSTATUS_ACTIVE
229 };
230
231 enum gru_tgh_state {
232         TGHSTATE_IDLE,
233         TGHSTATE_PE_INVAL,
234         TGHSTATE_INTERRUPT_INVAL,
235         TGHSTATE_WAITDONE,
236         TGHSTATE_RESTART_CTX,
237 };
238
239 /*
240  * TFH - TLB Global Handle
241  *      Used for TLB dropins into the GRU TLB.
242  *
243  */
244 struct gru_tlb_fault_handle {
245         unsigned int cmd:1;             /* DW 0 - low 32*/
246         unsigned int delresp:1;
247         unsigned int fill0:2;
248         unsigned int opc:3;
249         unsigned int fill1:9;
250
251         unsigned int status:2;
252         unsigned int fill2:2;
253         unsigned int state:3;
254         unsigned int fill3:1;
255
256         unsigned int cause:6;
257         unsigned int cb_int:1;
258         unsigned int fill4:1;
259
260         unsigned int indexway:12;       /* DW 0 - high 32 */
261         unsigned int fill5:4;
262
263         unsigned int ctxnum:4;
264         unsigned int fill6:12;
265
266         unsigned long missvaddr:64;     /* DW 1 */
267
268         unsigned int missasid:24;       /* DW 2 */
269         unsigned int fill7:8;
270         unsigned int fillasid:24;
271         unsigned int dirty:1;
272         unsigned int gaa:2;
273         unsigned long fill8:5;
274
275         unsigned long pfn:41;           /* DW 3 */
276         unsigned int fill9:7;
277         unsigned int pagesize:5;
278         unsigned int fill10:11;
279
280         unsigned long fillvaddr:64;     /* DW 4 */
281
282         unsigned long fill11[3];
283 };
284
285 enum gru_tfh_opc {
286         TFHOP_NOOP,
287         TFHOP_RESTART,
288         TFHOP_WRITE_ONLY,
289         TFHOP_WRITE_RESTART,
290         TFHOP_EXCEPTION,
291         TFHOP_USER_POLLING_MODE = 7,
292 };
293
294 enum tfh_status {
295         TFHSTATUS_IDLE,
296         TFHSTATUS_EXCEPTION,
297         TFHSTATUS_ACTIVE,
298 };
299
300 enum tfh_state {
301         TFHSTATE_INACTIVE,
302         TFHSTATE_IDLE,
303         TFHSTATE_MISS_UPM,
304         TFHSTATE_MISS_FMM,
305         TFHSTATE_HW_ERR,
306         TFHSTATE_WRITE_TLB,
307         TFHSTATE_RESTART_CBR,
308 };
309
310 /* TFH cause bits */
311 enum tfh_cause {
312         TFHCAUSE_NONE,
313         TFHCAUSE_TLB_MISS,
314         TFHCAUSE_TLB_MOD,
315         TFHCAUSE_HW_ERROR_RR,
316         TFHCAUSE_HW_ERROR_MAIN_ARRAY,
317         TFHCAUSE_HW_ERROR_VALID,
318         TFHCAUSE_HW_ERROR_PAGESIZE,
319         TFHCAUSE_INSTRUCTION_EXCEPTION,
320         TFHCAUSE_UNCORRECTIBLE_ERROR,
321 };
322
323 /* GAA values */
324 #define GAA_RAM                         0x0
325 #define GAA_NCRAM                       0x2
326 #define GAA_MMIO                        0x1
327 #define GAA_REGISTER                    0x3
328
329 /* GRU paddr shift for pfn. (NOTE: shift is NOT by actual pagesize) */
330 #define GRU_PADDR_SHIFT                 12
331
332 /*
333  * Context Configuration handle
334  *      Used to allocate resources to a GSEG context.
335  *
336  */
337 struct gru_context_configuration_handle {
338         unsigned int cmd:1;                     /* DW0 */
339         unsigned int delresp:1;
340         unsigned int opc:3;
341         unsigned int unmap_enable:1;
342         unsigned int req_slice_set_enable:1;
343         unsigned int req_slice:2;
344         unsigned int cb_int_enable:1;
345         unsigned int tlb_int_enable:1;
346         unsigned int tfm_fault_bit_enable:1;
347         unsigned int tlb_int_select:4;
348
349         unsigned int status:2;
350         unsigned int state:2;
351         unsigned int reserved2:4;
352
353         unsigned int cause:4;
354         unsigned int tfm_done_bit_enable:1;
355         unsigned int unused:3;
356
357         unsigned int dsr_allocation_map;
358
359         unsigned long cbr_allocation_map;       /* DW1 */
360
361         unsigned int asid[8];                   /* DW 2 - 5 */
362         unsigned short sizeavail[8];            /* DW 6 - 7 */
363 } __attribute__ ((packed));
364
365 enum gru_cch_opc {
366         CCHOP_START = 1,
367         CCHOP_ALLOCATE,
368         CCHOP_INTERRUPT,
369         CCHOP_DEALLOCATE,
370         CCHOP_INTERRUPT_SYNC,
371 };
372
373 enum gru_cch_status {
374         CCHSTATUS_IDLE,
375         CCHSTATUS_EXCEPTION,
376         CCHSTATUS_ACTIVE,
377 };
378
379 enum gru_cch_state {
380         CCHSTATE_INACTIVE,
381         CCHSTATE_MAPPED,
382         CCHSTATE_ACTIVE,
383         CCHSTATE_INTERRUPTED,
384 };
385
386 /* CCH Exception cause */
387 enum gru_cch_cause {
388         CCHCAUSE_REGION_REGISTER_WRITE_ERROR = 1,
389         CCHCAUSE_ILLEGAL_OPCODE = 2,
390         CCHCAUSE_INVALID_START_REQUEST = 3,
391         CCHCAUSE_INVALID_ALLOCATION_REQUEST = 4,
392         CCHCAUSE_INVALID_DEALLOCATION_REQUEST = 5,
393         CCHCAUSE_INVALID_INTERRUPT_REQUEST = 6,
394         CCHCAUSE_CCH_BUSY = 7,
395         CCHCAUSE_NO_CBRS_TO_ALLOCATE = 8,
396         CCHCAUSE_BAD_TFM_CONFIG = 9,
397         CCHCAUSE_CBR_RESOURCES_OVERSUBSCRIPED = 10,
398         CCHCAUSE_DSR_RESOURCES_OVERSUBSCRIPED = 11,
399         CCHCAUSE_CBR_DEALLOCATION_ERROR = 12,
400 };
401 /*
402  * CBE - Control Block Extended
403  *      Maintains internal GRU state for active CBs.
404  *
405  */
406 struct gru_control_block_extended {
407         unsigned int reserved0:1;       /* DW 0  - low */
408         unsigned int imacpy:3;
409         unsigned int reserved1:4;
410         unsigned int xtypecpy:3;
411         unsigned int iaa0cpy:2;
412         unsigned int iaa1cpy:2;
413         unsigned int reserved2:1;
414         unsigned int opccpy:8;
415         unsigned int exopccpy:8;
416
417         unsigned int idef2cpy:22;       /* DW 0  - high */
418         unsigned int reserved3:10;
419
420         unsigned int idef4cpy:22;       /* DW 1 */
421         unsigned int reserved4:10;
422         unsigned int idef4upd:22;
423         unsigned int reserved5:10;
424
425         unsigned long idef1upd:64;      /* DW 2 */
426
427         unsigned long idef5cpy:64;      /* DW 3 */
428
429         unsigned long idef6cpy:64;      /* DW 4 */
430
431         unsigned long idef3upd:64;      /* DW 5 */
432
433         unsigned long idef5upd:64;      /* DW 6 */
434
435         unsigned int idef2upd:22;       /* DW 7 */
436         unsigned int reserved6:10;
437
438         unsigned int ecause:20;
439         unsigned int cbrstate:4;
440         unsigned int cbrexecstatus:8;
441 };
442
443 enum gru_cbr_state {
444         CBRSTATE_INACTIVE,
445         CBRSTATE_IDLE,
446         CBRSTATE_PE_CHECK,
447         CBRSTATE_QUEUED,
448         CBRSTATE_WAIT_RESPONSE,
449         CBRSTATE_INTERRUPTED,
450         CBRSTATE_INTERRUPTED_MISS_FMM,
451         CBRSTATE_BUSY_INTERRUPT_MISS_FMM,
452         CBRSTATE_INTERRUPTED_MISS_UPM,
453         CBRSTATE_BUSY_INTERRUPTED_MISS_UPM,
454         CBRSTATE_REQUEST_ISSUE,
455         CBRSTATE_BUSY_INTERRUPT,
456 };
457
458 /* CBE cbrexecstatus bits  - defined in gru_instructions.h*/
459 /* CBE ecause bits  - defined in gru_instructions.h */
460
461 /*
462  * Convert a processor pagesize into the strange encoded pagesize used by the
463  * GRU. Processor pagesize is encoded as log of bytes per page. (or PAGE_SHIFT)
464  *      pagesize        log pagesize    grupagesize
465  *        4k                    12      0
466  *       16k                    14      1
467  *       64k                    16      2
468  *      256k                    18      3
469  *        1m                    20      4
470  *        2m                    21      5
471  *        4m                    22      6
472  *       16m                    24      7
473  *       64m                    26      8
474  *      ...
475  */
476 #define GRU_PAGESIZE(sh)        ((((sh) > 20 ? (sh) + 2 : (sh)) >> 1) - 6)
477 #define GRU_SIZEAVAIL(sh)       (1UL << GRU_PAGESIZE(sh))
478
479 /* minimum TLB purge count to ensure a full purge */
480 #define GRUMAXINVAL             1024UL
481
482 int cch_allocate(struct gru_context_configuration_handle *cch);
483 int cch_start(struct gru_context_configuration_handle *cch);
484 int cch_interrupt(struct gru_context_configuration_handle *cch);
485 int cch_deallocate(struct gru_context_configuration_handle *cch);
486 int cch_interrupt_sync(struct gru_context_configuration_handle *cch);
487 int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr,
488         unsigned long vaddrmask, int asid, int pagesize, int global, int n,
489         unsigned short ctxbitmap);
490 void tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long pfn,
491         unsigned long vaddr, int asid, int dirty, int pagesize);
492 void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
493         int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
494 void tfh_restart(struct gru_tlb_fault_handle *tfh);
495 void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh);
496 void tfh_exception(struct gru_tlb_fault_handle *tfh);
497
498 #endif /* __GRUHANDLES_H__ */