~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/ia64/include/asm/sn/sn_sal.h

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef _ASM_IA64_SN_SN_SAL_H
 
2
#define _ASM_IA64_SN_SN_SAL_H
 
3
 
 
4
/*
 
5
 * System Abstraction Layer definitions for IA64
 
6
 *
 
7
 * This file is subject to the terms and conditions of the GNU General Public
 
8
 * License.  See the file "COPYING" in the main directory of this archive
 
9
 * for more details.
 
10
 *
 
11
 * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All rights reserved.
 
12
 */
 
13
 
 
14
 
 
15
#include <asm/sal.h>
 
16
#include <asm/sn/sn_cpuid.h>
 
17
#include <asm/sn/arch.h>
 
18
#include <asm/sn/geo.h>
 
19
#include <asm/sn/nodepda.h>
 
20
#include <asm/sn/shub_mmr.h>
 
21
 
 
22
// SGI Specific Calls
 
23
#define  SN_SAL_POD_MODE                           0x02000001
 
24
#define  SN_SAL_SYSTEM_RESET                       0x02000002
 
25
#define  SN_SAL_PROBE                              0x02000003
 
26
#define  SN_SAL_GET_MASTER_NASID                   0x02000004
 
27
#define  SN_SAL_GET_KLCONFIG_ADDR                  0x02000005
 
28
#define  SN_SAL_LOG_CE                             0x02000006
 
29
#define  SN_SAL_REGISTER_CE                        0x02000007
 
30
#define  SN_SAL_GET_PARTITION_ADDR                 0x02000009
 
31
#define  SN_SAL_XP_ADDR_REGION                     0x0200000f
 
32
#define  SN_SAL_NO_FAULT_ZONE_VIRTUAL              0x02000010
 
33
#define  SN_SAL_NO_FAULT_ZONE_PHYSICAL             0x02000011
 
34
#define  SN_SAL_PRINT_ERROR                        0x02000012
 
35
#define  SN_SAL_REGISTER_PMI_HANDLER               0x02000014
 
36
#define  SN_SAL_SET_ERROR_HANDLING_FEATURES        0x0200001a   // reentrant
 
37
#define  SN_SAL_GET_FIT_COMPT                      0x0200001b   // reentrant
 
38
#define  SN_SAL_GET_SAPIC_INFO                     0x0200001d
 
39
#define  SN_SAL_GET_SN_INFO                        0x0200001e
 
40
#define  SN_SAL_CONSOLE_PUTC                       0x02000021
 
41
#define  SN_SAL_CONSOLE_GETC                       0x02000022
 
42
#define  SN_SAL_CONSOLE_PUTS                       0x02000023
 
43
#define  SN_SAL_CONSOLE_GETS                       0x02000024
 
44
#define  SN_SAL_CONSOLE_GETS_TIMEOUT               0x02000025
 
45
#define  SN_SAL_CONSOLE_POLL                       0x02000026
 
46
#define  SN_SAL_CONSOLE_INTR                       0x02000027
 
47
#define  SN_SAL_CONSOLE_PUTB                       0x02000028
 
48
#define  SN_SAL_CONSOLE_XMIT_CHARS                 0x0200002a
 
49
#define  SN_SAL_CONSOLE_READC                      0x0200002b
 
50
#define  SN_SAL_SYSCTL_OP                          0x02000030
 
51
#define  SN_SAL_SYSCTL_MODID_GET                   0x02000031
 
52
#define  SN_SAL_SYSCTL_GET                         0x02000032
 
53
#define  SN_SAL_SYSCTL_IOBRICK_MODULE_GET          0x02000033
 
54
#define  SN_SAL_SYSCTL_IO_PORTSPEED_GET            0x02000035
 
55
#define  SN_SAL_SYSCTL_SLAB_GET                    0x02000036
 
56
#define  SN_SAL_BUS_CONFIG                         0x02000037
 
57
#define  SN_SAL_SYS_SERIAL_GET                     0x02000038
 
58
#define  SN_SAL_PARTITION_SERIAL_GET               0x02000039
 
59
#define  SN_SAL_SYSCTL_PARTITION_GET               0x0200003a
 
60
#define  SN_SAL_SYSTEM_POWER_DOWN                  0x0200003b
 
61
#define  SN_SAL_GET_MASTER_BASEIO_NASID            0x0200003c
 
62
#define  SN_SAL_COHERENCE                          0x0200003d
 
63
#define  SN_SAL_MEMPROTECT                         0x0200003e
 
64
#define  SN_SAL_SYSCTL_FRU_CAPTURE                 0x0200003f
 
65
 
 
66
#define  SN_SAL_SYSCTL_IOBRICK_PCI_OP              0x02000042   // reentrant
 
67
#define  SN_SAL_IROUTER_OP                         0x02000043
 
68
#define  SN_SAL_SYSCTL_EVENT                       0x02000044
 
69
#define  SN_SAL_IOIF_INTERRUPT                     0x0200004a
 
70
#define  SN_SAL_HWPERF_OP                          0x02000050   // lock
 
71
#define  SN_SAL_IOIF_ERROR_INTERRUPT               0x02000051
 
72
#define  SN_SAL_IOIF_PCI_SAFE                      0x02000052
 
73
#define  SN_SAL_IOIF_SLOT_ENABLE                   0x02000053
 
74
#define  SN_SAL_IOIF_SLOT_DISABLE                  0x02000054
 
75
#define  SN_SAL_IOIF_GET_HUBDEV_INFO               0x02000055
 
76
#define  SN_SAL_IOIF_GET_PCIBUS_INFO               0x02000056
 
77
#define  SN_SAL_IOIF_GET_PCIDEV_INFO               0x02000057
 
78
#define  SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST      0x02000058   // deprecated
 
79
#define  SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST      0x0200005a
 
80
 
 
81
#define SN_SAL_IOIF_INIT                           0x0200005f
 
82
#define SN_SAL_HUB_ERROR_INTERRUPT                 0x02000060
 
83
#define SN_SAL_BTE_RECOVER                         0x02000061
 
84
#define SN_SAL_RESERVED_DO_NOT_USE                 0x02000062
 
85
#define SN_SAL_IOIF_GET_PCI_TOPOLOGY               0x02000064
 
86
 
 
87
#define  SN_SAL_GET_PROM_FEATURE_SET               0x02000065
 
88
#define  SN_SAL_SET_OS_FEATURE_SET                 0x02000066
 
89
#define  SN_SAL_INJECT_ERROR                       0x02000067
 
90
#define  SN_SAL_SET_CPU_NUMBER                     0x02000068
 
91
 
 
92
#define  SN_SAL_KERNEL_LAUNCH_EVENT                0x02000069
 
93
#define  SN_SAL_WATCHLIST_ALLOC                    0x02000070
 
94
#define  SN_SAL_WATCHLIST_FREE                     0x02000071
 
95
 
 
96
/*
 
97
 * Service-specific constants
 
98
 */
 
99
 
 
100
/* Console interrupt manipulation */
 
101
        /* action codes */
 
102
#define SAL_CONSOLE_INTR_OFF    0       /* turn the interrupt off */
 
103
#define SAL_CONSOLE_INTR_ON     1       /* turn the interrupt on */
 
104
#define SAL_CONSOLE_INTR_STATUS 2       /* retrieve the interrupt status */
 
105
        /* interrupt specification & status return codes */
 
106
#define SAL_CONSOLE_INTR_XMIT   1       /* output interrupt */
 
107
#define SAL_CONSOLE_INTR_RECV   2       /* input interrupt */
 
108
 
 
109
/* interrupt handling */
 
110
#define SAL_INTR_ALLOC          1
 
111
#define SAL_INTR_FREE           2
 
112
#define SAL_INTR_REDIRECT       3
 
113
 
 
114
/*
 
115
 * operations available on the generic SN_SAL_SYSCTL_OP
 
116
 * runtime service
 
117
 */
 
118
#define SAL_SYSCTL_OP_IOBOARD           0x0001  /*  retrieve board type */
 
119
#define SAL_SYSCTL_OP_TIO_JLCK_RST      0x0002  /* issue TIO clock reset */
 
120
 
 
121
/*
 
122
 * IRouter (i.e. generalized system controller) operations
 
123
 */
 
124
#define SAL_IROUTER_OPEN        0       /* open a subchannel */
 
125
#define SAL_IROUTER_CLOSE       1       /* close a subchannel */
 
126
#define SAL_IROUTER_SEND        2       /* send part of an IRouter packet */
 
127
#define SAL_IROUTER_RECV        3       /* receive part of an IRouter packet */
 
128
#define SAL_IROUTER_INTR_STATUS 4       /* check the interrupt status for
 
129
                                         * an open subchannel
 
130
                                         */
 
131
#define SAL_IROUTER_INTR_ON     5       /* enable an interrupt */
 
132
#define SAL_IROUTER_INTR_OFF    6       /* disable an interrupt */
 
133
#define SAL_IROUTER_INIT        7       /* initialize IRouter driver */
 
134
 
 
135
/* IRouter interrupt mask bits */
 
136
#define SAL_IROUTER_INTR_XMIT   SAL_CONSOLE_INTR_XMIT
 
137
#define SAL_IROUTER_INTR_RECV   SAL_CONSOLE_INTR_RECV
 
138
 
 
139
/*
 
140
 * Error Handling Features
 
141
 */
 
142
#define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV     0x1     // obsolete
 
143
#define SAL_ERR_FEAT_LOG_SBES                   0x2     // obsolete
 
144
#define SAL_ERR_FEAT_MFR_OVERRIDE               0x4
 
145
#define SAL_ERR_FEAT_SBE_THRESHOLD              0xffff0000
 
146
 
 
147
/*
 
148
 * SAL Error Codes
 
149
 */
 
150
#define SALRET_MORE_PASSES      1
 
151
#define SALRET_OK               0
 
152
#define SALRET_NOT_IMPLEMENTED  (-1)
 
153
#define SALRET_INVALID_ARG      (-2)
 
154
#define SALRET_ERROR            (-3)
 
155
 
 
156
#define SN_SAL_FAKE_PROM                           0x02009999
 
157
 
 
158
/**
 
159
  * sn_sal_revision - get the SGI SAL revision number
 
160
  *
 
161
  * The SGI PROM stores its version in the sal_[ab]_rev_(major|minor).
 
162
  * This routine simply extracts the major and minor values and
 
163
  * presents them in a u32 format.
 
164
  *
 
165
  * For example, version 4.05 would be represented at 0x0405.
 
166
  */
 
167
static inline u32
 
168
sn_sal_rev(void)
 
169
{
 
170
        struct ia64_sal_systab *systab = __va(efi.sal_systab);
 
171
 
 
172
        return (u32)(systab->sal_b_rev_major << 8 | systab->sal_b_rev_minor);
 
173
}
 
174
 
 
175
/*
 
176
 * Returns the master console nasid, if the call fails, return an illegal
 
177
 * value.
 
178
 */
 
179
static inline u64
 
180
ia64_sn_get_console_nasid(void)
 
181
{
 
182
        struct ia64_sal_retval ret_stuff;
 
183
 
 
184
        ret_stuff.status = 0;
 
185
        ret_stuff.v0 = 0;
 
186
        ret_stuff.v1 = 0;
 
187
        ret_stuff.v2 = 0;
 
188
        SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_NASID, 0, 0, 0, 0, 0, 0, 0);
 
189
 
 
190
        if (ret_stuff.status < 0)
 
191
                return ret_stuff.status;
 
192
 
 
193
        /* Master console nasid is in 'v0' */
 
194
        return ret_stuff.v0;
 
195
}
 
196
 
 
197
/*
 
198
 * Returns the master baseio nasid, if the call fails, return an illegal
 
199
 * value.
 
200
 */
 
201
static inline u64
 
202
ia64_sn_get_master_baseio_nasid(void)
 
203
{
 
204
        struct ia64_sal_retval ret_stuff;
 
205
 
 
206
        ret_stuff.status = 0;
 
207
        ret_stuff.v0 = 0;
 
208
        ret_stuff.v1 = 0;
 
209
        ret_stuff.v2 = 0;
 
210
        SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_BASEIO_NASID, 0, 0, 0, 0, 0, 0, 0);
 
211
 
 
212
        if (ret_stuff.status < 0)
 
213
                return ret_stuff.status;
 
214
 
 
215
        /* Master baseio nasid is in 'v0' */
 
216
        return ret_stuff.v0;
 
217
}
 
218
 
 
219
static inline void *
 
220
ia64_sn_get_klconfig_addr(nasid_t nasid)
 
221
{
 
222
        struct ia64_sal_retval ret_stuff;
 
223
 
 
224
        ret_stuff.status = 0;
 
225
        ret_stuff.v0 = 0;
 
226
        ret_stuff.v1 = 0;
 
227
        ret_stuff.v2 = 0;
 
228
        SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0);
 
229
        return ret_stuff.v0 ? __va(ret_stuff.v0) : NULL;
 
230
}
 
231
 
 
232
/*
 
233
 * Returns the next console character.
 
234
 */
 
235
static inline u64
 
236
ia64_sn_console_getc(int *ch)
 
237
{
 
238
        struct ia64_sal_retval ret_stuff;
 
239
 
 
240
        ret_stuff.status = 0;
 
241
        ret_stuff.v0 = 0;
 
242
        ret_stuff.v1 = 0;
 
243
        ret_stuff.v2 = 0;
 
244
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_GETC, 0, 0, 0, 0, 0, 0, 0);
 
245
 
 
246
        /* character is in 'v0' */
 
247
        *ch = (int)ret_stuff.v0;
 
248
 
 
249
        return ret_stuff.status;
 
250
}
 
251
 
 
252
/*
 
253
 * Read a character from the SAL console device, after a previous interrupt
 
254
 * or poll operation has given us to know that a character is available
 
255
 * to be read.
 
256
 */
 
257
static inline u64
 
258
ia64_sn_console_readc(void)
 
259
{
 
260
        struct ia64_sal_retval ret_stuff;
 
261
 
 
262
        ret_stuff.status = 0;
 
263
        ret_stuff.v0 = 0;
 
264
        ret_stuff.v1 = 0;
 
265
        ret_stuff.v2 = 0;
 
266
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_READC, 0, 0, 0, 0, 0, 0, 0);
 
267
 
 
268
        /* character is in 'v0' */
 
269
        return ret_stuff.v0;
 
270
}
 
271
 
 
272
/*
 
273
 * Sends the given character to the console.
 
274
 */
 
275
static inline u64
 
276
ia64_sn_console_putc(char ch)
 
277
{
 
278
        struct ia64_sal_retval ret_stuff;
 
279
 
 
280
        ret_stuff.status = 0;
 
281
        ret_stuff.v0 = 0;
 
282
        ret_stuff.v1 = 0;
 
283
        ret_stuff.v2 = 0;
 
284
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTC, (u64)ch, 0, 0, 0, 0, 0, 0);
 
285
 
 
286
        return ret_stuff.status;
 
287
}
 
288
 
 
289
/*
 
290
 * Sends the given buffer to the console.
 
291
 */
 
292
static inline u64
 
293
ia64_sn_console_putb(const char *buf, int len)
 
294
{
 
295
        struct ia64_sal_retval ret_stuff;
 
296
 
 
297
        ret_stuff.status = 0;
 
298
        ret_stuff.v0 = 0; 
 
299
        ret_stuff.v1 = 0;
 
300
        ret_stuff.v2 = 0;
 
301
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTB, (u64)buf, (u64)len, 0, 0, 0, 0, 0);
 
302
 
 
303
        if ( ret_stuff.status == 0 ) {
 
304
                return ret_stuff.v0;
 
305
        }
 
306
        return (u64)0;
 
307
}
 
308
 
 
309
/*
 
310
 * Print a platform error record
 
311
 */
 
312
static inline u64
 
313
ia64_sn_plat_specific_err_print(int (*hook)(const char*, ...), char *rec)
 
314
{
 
315
        struct ia64_sal_retval ret_stuff;
 
316
 
 
317
        ret_stuff.status = 0;
 
318
        ret_stuff.v0 = 0;
 
319
        ret_stuff.v1 = 0;
 
320
        ret_stuff.v2 = 0;
 
321
        SAL_CALL_REENTRANT(ret_stuff, SN_SAL_PRINT_ERROR, (u64)hook, (u64)rec, 0, 0, 0, 0, 0);
 
322
 
 
323
        return ret_stuff.status;
 
324
}
 
325
 
 
326
/*
 
327
 * Check for Platform errors
 
328
 */
 
329
static inline u64
 
330
ia64_sn_plat_cpei_handler(void)
 
331
{
 
332
        struct ia64_sal_retval ret_stuff;
 
333
 
 
334
        ret_stuff.status = 0;
 
335
        ret_stuff.v0 = 0;
 
336
        ret_stuff.v1 = 0;
 
337
        ret_stuff.v2 = 0;
 
338
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_LOG_CE, 0, 0, 0, 0, 0, 0, 0);
 
339
 
 
340
        return ret_stuff.status;
 
341
}
 
342
 
 
343
/*
 
344
 * Set Error Handling Features  (Obsolete)
 
345
 */
 
346
static inline u64
 
347
ia64_sn_plat_set_error_handling_features(void)
 
348
{
 
349
        struct ia64_sal_retval ret_stuff;
 
350
 
 
351
        ret_stuff.status = 0;
 
352
        ret_stuff.v0 = 0;
 
353
        ret_stuff.v1 = 0;
 
354
        ret_stuff.v2 = 0;
 
355
        SAL_CALL_REENTRANT(ret_stuff, SN_SAL_SET_ERROR_HANDLING_FEATURES,
 
356
                SAL_ERR_FEAT_LOG_SBES,
 
357
                0, 0, 0, 0, 0, 0);
 
358
 
 
359
        return ret_stuff.status;
 
360
}
 
361
 
 
362
/*
 
363
 * Checks for console input.
 
364
 */
 
365
static inline u64
 
366
ia64_sn_console_check(int *result)
 
367
{
 
368
        struct ia64_sal_retval ret_stuff;
 
369
 
 
370
        ret_stuff.status = 0;
 
371
        ret_stuff.v0 = 0;
 
372
        ret_stuff.v1 = 0;
 
373
        ret_stuff.v2 = 0;
 
374
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_POLL, 0, 0, 0, 0, 0, 0, 0);
 
375
 
 
376
        /* result is in 'v0' */
 
377
        *result = (int)ret_stuff.v0;
 
378
 
 
379
        return ret_stuff.status;
 
380
}
 
381
 
 
382
/*
 
383
 * Checks console interrupt status
 
384
 */
 
385
static inline u64
 
386
ia64_sn_console_intr_status(void)
 
387
{
 
388
        struct ia64_sal_retval ret_stuff;
 
389
 
 
390
        ret_stuff.status = 0;
 
391
        ret_stuff.v0 = 0;
 
392
        ret_stuff.v1 = 0;
 
393
        ret_stuff.v2 = 0;
 
394
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
 
395
                 0, SAL_CONSOLE_INTR_STATUS,
 
396
                 0, 0, 0, 0, 0);
 
397
 
 
398
        if (ret_stuff.status == 0) {
 
399
            return ret_stuff.v0;
 
400
        }
 
401
        
 
402
        return 0;
 
403
}
 
404
 
 
405
/*
 
406
 * Enable an interrupt on the SAL console device.
 
407
 */
 
408
static inline void
 
409
ia64_sn_console_intr_enable(u64 intr)
 
410
{
 
411
        struct ia64_sal_retval ret_stuff;
 
412
 
 
413
        ret_stuff.status = 0;
 
414
        ret_stuff.v0 = 0;
 
415
        ret_stuff.v1 = 0;
 
416
        ret_stuff.v2 = 0;
 
417
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
 
418
                 intr, SAL_CONSOLE_INTR_ON,
 
419
                 0, 0, 0, 0, 0);
 
420
}
 
421
 
 
422
/*
 
423
 * Disable an interrupt on the SAL console device.
 
424
 */
 
425
static inline void
 
426
ia64_sn_console_intr_disable(u64 intr)
 
427
{
 
428
        struct ia64_sal_retval ret_stuff;
 
429
 
 
430
        ret_stuff.status = 0;
 
431
        ret_stuff.v0 = 0;
 
432
        ret_stuff.v1 = 0;
 
433
        ret_stuff.v2 = 0;
 
434
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
 
435
                 intr, SAL_CONSOLE_INTR_OFF,
 
436
                 0, 0, 0, 0, 0);
 
437
}
 
438
 
 
439
/*
 
440
 * Sends a character buffer to the console asynchronously.
 
441
 */
 
442
static inline u64
 
443
ia64_sn_console_xmit_chars(char *buf, int len)
 
444
{
 
445
        struct ia64_sal_retval ret_stuff;
 
446
 
 
447
        ret_stuff.status = 0;
 
448
        ret_stuff.v0 = 0;
 
449
        ret_stuff.v1 = 0;
 
450
        ret_stuff.v2 = 0;
 
451
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_XMIT_CHARS,
 
452
                 (u64)buf, (u64)len,
 
453
                 0, 0, 0, 0, 0);
 
454
 
 
455
        if (ret_stuff.status == 0) {
 
456
            return ret_stuff.v0;
 
457
        }
 
458
 
 
459
        return 0;
 
460
}
 
461
 
 
462
/*
 
463
 * Returns the iobrick module Id
 
464
 */
 
465
static inline u64
 
466
ia64_sn_sysctl_iobrick_module_get(nasid_t nasid, int *result)
 
467
{
 
468
        struct ia64_sal_retval ret_stuff;
 
469
 
 
470
        ret_stuff.status = 0;
 
471
        ret_stuff.v0 = 0;
 
472
        ret_stuff.v1 = 0;
 
473
        ret_stuff.v2 = 0;
 
474
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYSCTL_IOBRICK_MODULE_GET, nasid, 0, 0, 0, 0, 0, 0);
 
475
 
 
476
        /* result is in 'v0' */
 
477
        *result = (int)ret_stuff.v0;
 
478
 
 
479
        return ret_stuff.status;
 
480
}
 
481
 
 
482
/**
 
483
 * ia64_sn_pod_mode - call the SN_SAL_POD_MODE function
 
484
 *
 
485
 * SN_SAL_POD_MODE actually takes an argument, but it's always
 
486
 * 0 when we call it from the kernel, so we don't have to expose
 
487
 * it to the caller.
 
488
 */
 
489
static inline u64
 
490
ia64_sn_pod_mode(void)
 
491
{
 
492
        struct ia64_sal_retval isrv;
 
493
        SAL_CALL_REENTRANT(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0);
 
494
        if (isrv.status)
 
495
                return 0;
 
496
        return isrv.v0;
 
497
}
 
498
 
 
499
/**
 
500
 * ia64_sn_probe_mem - read from memory safely
 
501
 * @addr: address to probe
 
502
 * @size: number bytes to read (1,2,4,8)
 
503
 * @data_ptr: address to store value read by probe (-1 returned if probe fails)
 
504
 *
 
505
 * Call into the SAL to do a memory read.  If the read generates a machine
 
506
 * check, this routine will recover gracefully and return -1 to the caller.
 
507
 * @addr is usually a kernel virtual address in uncached space (i.e. the
 
508
 * address starts with 0xc), but if called in physical mode, @addr should
 
509
 * be a physical address.
 
510
 *
 
511
 * Return values:
 
512
 *  0 - probe successful
 
513
 *  1 - probe failed (generated MCA)
 
514
 *  2 - Bad arg
 
515
 * <0 - PAL error
 
516
 */
 
517
static inline u64
 
518
ia64_sn_probe_mem(long addr, long size, void *data_ptr)
 
519
{
 
520
        struct ia64_sal_retval isrv;
 
521
 
 
522
        SAL_CALL(isrv, SN_SAL_PROBE, addr, size, 0, 0, 0, 0, 0);
 
523
 
 
524
        if (data_ptr) {
 
525
                switch (size) {
 
526
                case 1:
 
527
                        *((u8*)data_ptr) = (u8)isrv.v0;
 
528
                        break;
 
529
                case 2:
 
530
                        *((u16*)data_ptr) = (u16)isrv.v0;
 
531
                        break;
 
532
                case 4:
 
533
                        *((u32*)data_ptr) = (u32)isrv.v0;
 
534
                        break;
 
535
                case 8:
 
536
                        *((u64*)data_ptr) = (u64)isrv.v0;
 
537
                        break;
 
538
                default:
 
539
                        isrv.status = 2;
 
540
                }
 
541
        }
 
542
        return isrv.status;
 
543
}
 
544
 
 
545
/*
 
546
 * Retrieve the system serial number as an ASCII string.
 
547
 */
 
548
static inline u64
 
549
ia64_sn_sys_serial_get(char *buf)
 
550
{
 
551
        struct ia64_sal_retval ret_stuff;
 
552
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
 
553
        return ret_stuff.status;
 
554
}
 
555
 
 
556
extern char sn_system_serial_number_string[];
 
557
extern u64 sn_partition_serial_number;
 
558
 
 
559
static inline char *
 
560
sn_system_serial_number(void) {
 
561
        if (sn_system_serial_number_string[0]) {
 
562
                return(sn_system_serial_number_string);
 
563
        } else {
 
564
                ia64_sn_sys_serial_get(sn_system_serial_number_string);
 
565
                return(sn_system_serial_number_string);
 
566
        }
 
567
}
 
568
        
 
569
 
 
570
/*
 
571
 * Returns a unique id number for this system and partition (suitable for
 
572
 * use with license managers), based in part on the system serial number.
 
573
 */
 
574
static inline u64
 
575
ia64_sn_partition_serial_get(void)
 
576
{
 
577
        struct ia64_sal_retval ret_stuff;
 
578
        ia64_sal_oemcall_reentrant(&ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0,
 
579
                                   0, 0, 0, 0, 0, 0);
 
580
        if (ret_stuff.status != 0)
 
581
            return 0;
 
582
        return ret_stuff.v0;
 
583
}
 
584
 
 
585
static inline u64
 
586
sn_partition_serial_number_val(void) {
 
587
        if (unlikely(sn_partition_serial_number == 0)) {
 
588
                sn_partition_serial_number = ia64_sn_partition_serial_get();
 
589
        }
 
590
        return sn_partition_serial_number;
 
591
}
 
592
 
 
593
/*
 
594
 * Returns the partition id of the nasid passed in as an argument,
 
595
 * or INVALID_PARTID if the partition id cannot be retrieved.
 
596
 */
 
597
static inline partid_t
 
598
ia64_sn_sysctl_partition_get(nasid_t nasid)
 
599
{
 
600
        struct ia64_sal_retval ret_stuff;
 
601
        SAL_CALL(ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid,
 
602
                0, 0, 0, 0, 0, 0);
 
603
        if (ret_stuff.status != 0)
 
604
            return -1;
 
605
        return ((partid_t)ret_stuff.v0);
 
606
}
 
607
 
 
608
/*
 
609
 * Returns the physical address of the partition's reserved page through
 
610
 * an iterative number of calls.
 
611
 *
 
612
 * On first call, 'cookie' and 'len' should be set to 0, and 'addr'
 
613
 * set to the nasid of the partition whose reserved page's address is
 
614
 * being sought.
 
615
 * On subsequent calls, pass the values, that were passed back on the
 
616
 * previous call.
 
617
 *
 
618
 * While the return status equals SALRET_MORE_PASSES, keep calling
 
619
 * this function after first copying 'len' bytes starting at 'addr'
 
620
 * into 'buf'. Once the return status equals SALRET_OK, 'addr' will
 
621
 * be the physical address of the partition's reserved page. If the
 
622
 * return status equals neither of these, an error as occurred.
 
623
 */
 
624
static inline s64
 
625
sn_partition_reserved_page_pa(u64 buf, u64 *cookie, u64 *addr, u64 *len)
 
626
{
 
627
        struct ia64_sal_retval rv;
 
628
        ia64_sal_oemcall_reentrant(&rv, SN_SAL_GET_PARTITION_ADDR, *cookie,
 
629
                                   *addr, buf, *len, 0, 0, 0);
 
630
        *cookie = rv.v0;
 
631
        *addr = rv.v1;
 
632
        *len = rv.v2;
 
633
        return rv.status;
 
634
}
 
635
 
 
636
/*
 
637
 * Register or unregister a physical address range being referenced across
 
638
 * a partition boundary for which certain SAL errors should be scanned for,
 
639
 * cleaned up and ignored.  This is of value for kernel partitioning code only.
 
640
 * Values for the operation argument:
 
641
 *      1 = register this address range with SAL
 
642
 *      0 = unregister this address range with SAL
 
643
 * 
 
644
 * SAL maintains a reference count on an address range in case it is registered
 
645
 * multiple times.
 
646
 * 
 
647
 * On success, returns the reference count of the address range after the SAL
 
648
 * call has performed the current registration/unregistration.  Returns a
 
649
 * negative value if an error occurred.
 
650
 */
 
651
static inline int
 
652
sn_register_xp_addr_region(u64 paddr, u64 len, int operation)
 
653
{
 
654
        struct ia64_sal_retval ret_stuff;
 
655
        ia64_sal_oemcall(&ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len,
 
656
                         (u64)operation, 0, 0, 0, 0);
 
657
        return ret_stuff.status;
 
658
}
 
659
 
 
660
/*
 
661
 * Register or unregister an instruction range for which SAL errors should
 
662
 * be ignored.  If an error occurs while in the registered range, SAL jumps
 
663
 * to return_addr after ignoring the error.  Values for the operation argument:
 
664
 *      1 = register this instruction range with SAL
 
665
 *      0 = unregister this instruction range with SAL
 
666
 *
 
667
 * Returns 0 on success, or a negative value if an error occurred.
 
668
 */
 
669
static inline int
 
670
sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
 
671
                         int virtual, int operation)
 
672
{
 
673
        struct ia64_sal_retval ret_stuff;
 
674
        u64 call;
 
675
        if (virtual) {
 
676
                call = SN_SAL_NO_FAULT_ZONE_VIRTUAL;
 
677
        } else {
 
678
                call = SN_SAL_NO_FAULT_ZONE_PHYSICAL;
 
679
        }
 
680
        ia64_sal_oemcall(&ret_stuff, call, start_addr, end_addr, return_addr,
 
681
                         (u64)1, 0, 0, 0);
 
682
        return ret_stuff.status;
 
683
}
 
684
 
 
685
/*
 
686
 * Register or unregister a function to handle a PMI received by a CPU.
 
687
 * Before calling the registered handler, SAL sets r1 to the value that
 
688
 * was passed in as the global_pointer.
 
689
 *
 
690
 * If the handler pointer is NULL, then the currently registered handler
 
691
 * will be unregistered.
 
692
 *
 
693
 * Returns 0 on success, or a negative value if an error occurred.
 
694
 */
 
695
static inline int
 
696
sn_register_pmi_handler(u64 handler, u64 global_pointer)
 
697
{
 
698
        struct ia64_sal_retval ret_stuff;
 
699
        ia64_sal_oemcall(&ret_stuff, SN_SAL_REGISTER_PMI_HANDLER, handler,
 
700
                         global_pointer, 0, 0, 0, 0, 0);
 
701
        return ret_stuff.status;
 
702
}
 
703
 
 
704
/*
 
705
 * Change or query the coherence domain for this partition. Each cpu-based
 
706
 * nasid is represented by a bit in an array of 64-bit words:
 
707
 *      0 = not in this partition's coherency domain
 
708
 *      1 = in this partition's coherency domain
 
709
 *
 
710
 * It is not possible for the local system's nasids to be removed from
 
711
 * the coherency domain.  Purpose of the domain arguments:
 
712
 *      new_domain = set the coherence domain to the given nasids
 
713
 *      old_domain = return the current coherence domain
 
714
 *
 
715
 * Returns 0 on success, or a negative value if an error occurred.
 
716
 */
 
717
static inline int
 
718
sn_change_coherence(u64 *new_domain, u64 *old_domain)
 
719
{
 
720
        struct ia64_sal_retval ret_stuff;
 
721
        ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_COHERENCE, (u64)new_domain,
 
722
                                (u64)old_domain, 0, 0, 0, 0, 0);
 
723
        return ret_stuff.status;
 
724
}
 
725
 
 
726
/*
 
727
 * Change memory access protections for a physical address range.
 
728
 * nasid_array is not used on Altix, but may be in future architectures.
 
729
 * Available memory protection access classes are defined after the function.
 
730
 */
 
731
static inline int
 
732
sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
 
733
{
 
734
        struct ia64_sal_retval ret_stuff;
 
735
 
 
736
        ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_MEMPROTECT, paddr, len,
 
737
                                (u64)nasid_array, perms, 0, 0, 0);
 
738
        return ret_stuff.status;
 
739
}
 
740
#define SN_MEMPROT_ACCESS_CLASS_0               0x14a080
 
741
#define SN_MEMPROT_ACCESS_CLASS_1               0x2520c2
 
742
#define SN_MEMPROT_ACCESS_CLASS_2               0x14a1ca
 
743
#define SN_MEMPROT_ACCESS_CLASS_3               0x14a290
 
744
#define SN_MEMPROT_ACCESS_CLASS_6               0x084080
 
745
#define SN_MEMPROT_ACCESS_CLASS_7               0x021080
 
746
 
 
747
/*
 
748
 * Turns off system power.
 
749
 */
 
750
static inline void
 
751
ia64_sn_power_down(void)
 
752
{
 
753
        struct ia64_sal_retval ret_stuff;
 
754
        SAL_CALL(ret_stuff, SN_SAL_SYSTEM_POWER_DOWN, 0, 0, 0, 0, 0, 0, 0);
 
755
        while(1)
 
756
                cpu_relax();
 
757
        /* never returns */
 
758
}
 
759
 
 
760
/**
 
761
 * ia64_sn_fru_capture - tell the system controller to capture hw state
 
762
 *
 
763
 * This routine will call the SAL which will tell the system controller(s)
 
764
 * to capture hw mmr information from each SHub in the system.
 
765
 */
 
766
static inline u64
 
767
ia64_sn_fru_capture(void)
 
768
{
 
769
        struct ia64_sal_retval isrv;
 
770
        SAL_CALL(isrv, SN_SAL_SYSCTL_FRU_CAPTURE, 0, 0, 0, 0, 0, 0, 0);
 
771
        if (isrv.status)
 
772
                return 0;
 
773
        return isrv.v0;
 
774
}
 
775
 
 
776
/*
 
777
 * Performs an operation on a PCI bus or slot -- power up, power down
 
778
 * or reset.
 
779
 */
 
780
static inline u64
 
781
ia64_sn_sysctl_iobrick_pci_op(nasid_t n, u64 connection_type, 
 
782
                              u64 bus, char slot, 
 
783
                              u64 action)
 
784
{
 
785
        struct ia64_sal_retval rv = {0, 0, 0, 0};
 
786
 
 
787
        SAL_CALL_NOLOCK(rv, SN_SAL_SYSCTL_IOBRICK_PCI_OP, connection_type, n, action,
 
788
                 bus, (u64) slot, 0, 0);
 
789
        if (rv.status)
 
790
                return rv.v0;
 
791
        return 0;
 
792
}
 
793
 
 
794
 
 
795
/*
 
796
 * Open a subchannel for sending arbitrary data to the system
 
797
 * controller network via the system controller device associated with
 
798
 * 'nasid'.  Return the subchannel number or a negative error code.
 
799
 */
 
800
static inline int
 
801
ia64_sn_irtr_open(nasid_t nasid)
 
802
{
 
803
        struct ia64_sal_retval rv;
 
804
        SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_OPEN, nasid,
 
805
                           0, 0, 0, 0, 0);
 
806
        return (int) rv.v0;
 
807
}
 
808
 
 
809
/*
 
810
 * Close system controller subchannel 'subch' previously opened on 'nasid'.
 
811
 */
 
812
static inline int
 
813
ia64_sn_irtr_close(nasid_t nasid, int subch)
 
814
{
 
815
        struct ia64_sal_retval rv;
 
816
        SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_CLOSE,
 
817
                           (u64) nasid, (u64) subch, 0, 0, 0, 0);
 
818
        return (int) rv.status;
 
819
}
 
820
 
 
821
/*
 
822
 * Read data from system controller associated with 'nasid' on
 
823
 * subchannel 'subch'.  The buffer to be filled is pointed to by
 
824
 * 'buf', and its capacity is in the integer pointed to by 'len'.  The
 
825
 * referent of 'len' is set to the number of bytes read by the SAL
 
826
 * call.  The return value is either SALRET_OK (for bytes read) or
 
827
 * SALRET_ERROR (for error or "no data available").
 
828
 */
 
829
static inline int
 
830
ia64_sn_irtr_recv(nasid_t nasid, int subch, char *buf, int *len)
 
831
{
 
832
        struct ia64_sal_retval rv;
 
833
        SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_RECV,
 
834
                           (u64) nasid, (u64) subch, (u64) buf, (u64) len,
 
835
                           0, 0);
 
836
        return (int) rv.status;
 
837
}
 
838
 
 
839
/*
 
840
 * Write data to the system controller network via the system
 
841
 * controller associated with 'nasid' on suchannel 'subch'.  The
 
842
 * buffer to be written out is pointed to by 'buf', and 'len' is the
 
843
 * number of bytes to be written.  The return value is either the
 
844
 * number of bytes written (which could be zero) or a negative error
 
845
 * code.
 
846
 */
 
847
static inline int
 
848
ia64_sn_irtr_send(nasid_t nasid, int subch, char *buf, int len)
 
849
{
 
850
        struct ia64_sal_retval rv;
 
851
        SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_SEND,
 
852
                           (u64) nasid, (u64) subch, (u64) buf, (u64) len,
 
853
                           0, 0);
 
854
        return (int) rv.v0;
 
855
}
 
856
 
 
857
/*
 
858
 * Check whether any interrupts are pending for the system controller
 
859
 * associated with 'nasid' and its subchannel 'subch'.  The return
 
860
 * value is a mask of pending interrupts (SAL_IROUTER_INTR_XMIT and/or
 
861
 * SAL_IROUTER_INTR_RECV).
 
862
 */
 
863
static inline int
 
864
ia64_sn_irtr_intr(nasid_t nasid, int subch)
 
865
{
 
866
        struct ia64_sal_retval rv;
 
867
        SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_INTR_STATUS,
 
868
                           (u64) nasid, (u64) subch, 0, 0, 0, 0);
 
869
        return (int) rv.v0;
 
870
}
 
871
 
 
872
/*
 
873
 * Enable the interrupt indicated by the intr parameter (either
 
874
 * SAL_IROUTER_INTR_XMIT or SAL_IROUTER_INTR_RECV).
 
875
 */
 
876
static inline int
 
877
ia64_sn_irtr_intr_enable(nasid_t nasid, int subch, u64 intr)
 
878
{
 
879
        struct ia64_sal_retval rv;
 
880
        SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_INTR_ON,
 
881
                           (u64) nasid, (u64) subch, intr, 0, 0, 0);
 
882
        return (int) rv.v0;
 
883
}
 
884
 
 
885
/*
 
886
 * Disable the interrupt indicated by the intr parameter (either
 
887
 * SAL_IROUTER_INTR_XMIT or SAL_IROUTER_INTR_RECV).
 
888
 */
 
889
static inline int
 
890
ia64_sn_irtr_intr_disable(nasid_t nasid, int subch, u64 intr)
 
891
{
 
892
        struct ia64_sal_retval rv;
 
893
        SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_INTR_OFF,
 
894
                           (u64) nasid, (u64) subch, intr, 0, 0, 0);
 
895
        return (int) rv.v0;
 
896
}
 
897
 
 
898
/*
 
899
 * Set up a node as the point of contact for system controller
 
900
 * environmental event delivery.
 
901
 */
 
902
static inline int
 
903
ia64_sn_sysctl_event_init(nasid_t nasid)
 
904
{
 
905
        struct ia64_sal_retval rv;
 
906
        SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_EVENT, (u64) nasid,
 
907
                           0, 0, 0, 0, 0, 0);
 
908
        return (int) rv.v0;
 
909
}
 
910
 
 
911
/*
 
912
 * Ask the system controller on the specified nasid to reset
 
913
 * the CX corelet clock.  Only valid on TIO nodes.
 
914
 */
 
915
static inline int
 
916
ia64_sn_sysctl_tio_clock_reset(nasid_t nasid)
 
917
{
 
918
        struct ia64_sal_retval rv;
 
919
        SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_TIO_JLCK_RST,
 
920
                        nasid, 0, 0, 0, 0, 0);
 
921
        if (rv.status != 0)
 
922
                return (int)rv.status;
 
923
        if (rv.v0 != 0)
 
924
                return (int)rv.v0;
 
925
 
 
926
        return 0;
 
927
}
 
928
 
 
929
/*
 
930
 * Get the associated ioboard type for a given nasid.
 
931
 */
 
932
static inline long
 
933
ia64_sn_sysctl_ioboard_get(nasid_t nasid, u16 *ioboard)
 
934
{
 
935
        struct ia64_sal_retval isrv;
 
936
        SAL_CALL_REENTRANT(isrv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_IOBOARD,
 
937
                           nasid, 0, 0, 0, 0, 0);
 
938
        if (isrv.v0 != 0) {
 
939
                *ioboard = isrv.v0;
 
940
                return isrv.status;
 
941
        }
 
942
        if (isrv.v1 != 0) {
 
943
                *ioboard = isrv.v1;
 
944
                return isrv.status;
 
945
        }
 
946
 
 
947
        return isrv.status;
 
948
}
 
949
 
 
950
/**
 
951
 * ia64_sn_get_fit_compt - read a FIT entry from the PROM header
 
952
 * @nasid: NASID of node to read
 
953
 * @index: FIT entry index to be retrieved (0..n)
 
954
 * @fitentry: 16 byte buffer where FIT entry will be stored.
 
955
 * @banbuf: optional buffer for retrieving banner
 
956
 * @banlen: length of banner buffer
 
957
 *
 
958
 * Access to the physical PROM chips needs to be serialized since reads and
 
959
 * writes can't occur at the same time, so we need to call into the SAL when
 
960
 * we want to look at the FIT entries on the chips.
 
961
 *
 
962
 * Returns:
 
963
 *      %SALRET_OK if ok
 
964
 *      %SALRET_INVALID_ARG if index too big
 
965
 *      %SALRET_NOT_IMPLEMENTED if running on older PROM
 
966
 *      ??? if nasid invalid OR banner buffer not large enough
 
967
 */
 
968
static inline int
 
969
ia64_sn_get_fit_compt(u64 nasid, u64 index, void *fitentry, void *banbuf,
 
970
                      u64 banlen)
 
971
{
 
972
        struct ia64_sal_retval rv;
 
973
        SAL_CALL_NOLOCK(rv, SN_SAL_GET_FIT_COMPT, nasid, index, fitentry,
 
974
                        banbuf, banlen, 0, 0);
 
975
        return (int) rv.status;
 
976
}
 
977
 
 
978
/*
 
979
 * Initialize the SAL components of the system controller
 
980
 * communication driver; specifically pass in a sizable buffer that
 
981
 * can be used for allocation of subchannel queues as new subchannels
 
982
 * are opened.  "buf" points to the buffer, and "len" specifies its
 
983
 * length.
 
984
 */
 
985
static inline int
 
986
ia64_sn_irtr_init(nasid_t nasid, void *buf, int len)
 
987
{
 
988
        struct ia64_sal_retval rv;
 
989
        SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_INIT,
 
990
                           (u64) nasid, (u64) buf, (u64) len, 0, 0, 0);
 
991
        return (int) rv.status;
 
992
}
 
993
 
 
994
/*
 
995
 * Returns the nasid, subnode & slice corresponding to a SAPIC ID
 
996
 *
 
997
 *  In:
 
998
 *      arg0 - SN_SAL_GET_SAPIC_INFO
 
999
 *      arg1 - sapicid (lid >> 16) 
 
1000
 *  Out:
 
1001
 *      v0 - nasid
 
1002
 *      v1 - subnode
 
1003
 *      v2 - slice
 
1004
 */
 
1005
static inline u64
 
1006
ia64_sn_get_sapic_info(int sapicid, int *nasid, int *subnode, int *slice)
 
1007
{
 
1008
        struct ia64_sal_retval ret_stuff;
 
1009
 
 
1010
        ret_stuff.status = 0;
 
1011
        ret_stuff.v0 = 0;
 
1012
        ret_stuff.v1 = 0;
 
1013
        ret_stuff.v2 = 0;
 
1014
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SAPIC_INFO, sapicid, 0, 0, 0, 0, 0, 0);
 
1015
 
 
1016
/***** BEGIN HACK - temp til old proms no longer supported ********/
 
1017
        if (ret_stuff.status == SALRET_NOT_IMPLEMENTED) {
 
1018
                if (nasid) *nasid = sapicid & 0xfff;
 
1019
                if (subnode) *subnode = (sapicid >> 13) & 1;
 
1020
                if (slice) *slice = (sapicid >> 12) & 3;
 
1021
                return 0;
 
1022
        }
 
1023
/***** END HACK *******/
 
1024
 
 
1025
        if (ret_stuff.status < 0)
 
1026
                return ret_stuff.status;
 
1027
 
 
1028
        if (nasid) *nasid = (int) ret_stuff.v0;
 
1029
        if (subnode) *subnode = (int) ret_stuff.v1;
 
1030
        if (slice) *slice = (int) ret_stuff.v2;
 
1031
        return 0;
 
1032
}
 
1033
 
 
1034
/*
 
1035
 * Returns information about the HUB/SHUB.
 
1036
 *  In:
 
1037
 *      arg0 - SN_SAL_GET_SN_INFO
 
1038
 *      arg1 - 0 (other values reserved for future use)
 
1039
 *  Out:
 
1040
 *      v0 
 
1041
 *              [7:0]   - shub type (0=shub1, 1=shub2)
 
1042
 *              [15:8]  - Log2 max number of nodes in entire system (includes
 
1043
 *                        C-bricks, I-bricks, etc)
 
1044
 *              [23:16] - Log2 of nodes per sharing domain                       
 
1045
 *              [31:24] - partition ID
 
1046
 *              [39:32] - coherency_id
 
1047
 *              [47:40] - regionsize
 
1048
 *      v1 
 
1049
 *              [15:0]  - nasid mask (ex., 0x7ff for 11 bit nasid)
 
1050
 *              [23:15] - bit position of low nasid bit
 
1051
 */
 
1052
static inline u64
 
1053
ia64_sn_get_sn_info(int fc, u8 *shubtype, u16 *nasid_bitmask, u8 *nasid_shift, 
 
1054
                u8 *systemsize, u8 *sharing_domain_size, u8 *partid, u8 *coher, u8 *reg)
 
1055
{
 
1056
        struct ia64_sal_retval ret_stuff;
 
1057
 
 
1058
        ret_stuff.status = 0;
 
1059
        ret_stuff.v0 = 0;
 
1060
        ret_stuff.v1 = 0;
 
1061
        ret_stuff.v2 = 0;
 
1062
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SN_INFO, fc, 0, 0, 0, 0, 0, 0);
 
1063
 
 
1064
/***** BEGIN HACK - temp til old proms no longer supported ********/
 
1065
        if (ret_stuff.status == SALRET_NOT_IMPLEMENTED) {
 
1066
                int nasid = get_sapicid() & 0xfff;
 
1067
#define SH_SHUB_ID_NODES_PER_BIT_MASK 0x001f000000000000UL
 
1068
#define SH_SHUB_ID_NODES_PER_BIT_SHFT 48
 
1069
                if (shubtype) *shubtype = 0;
 
1070
                if (nasid_bitmask) *nasid_bitmask = 0x7ff;
 
1071
                if (nasid_shift) *nasid_shift = 38;
 
1072
                if (systemsize) *systemsize = 10;
 
1073
                if (sharing_domain_size) *sharing_domain_size = 8;
 
1074
                if (partid) *partid = ia64_sn_sysctl_partition_get(nasid);
 
1075
                if (coher) *coher = nasid >> 9;
 
1076
                if (reg) *reg = (HUB_L((u64 *) LOCAL_MMR_ADDR(SH1_SHUB_ID)) & SH_SHUB_ID_NODES_PER_BIT_MASK) >>
 
1077
                        SH_SHUB_ID_NODES_PER_BIT_SHFT;
 
1078
                return 0;
 
1079
        }
 
1080
/***** END HACK *******/
 
1081
 
 
1082
        if (ret_stuff.status < 0)
 
1083
                return ret_stuff.status;
 
1084
 
 
1085
        if (shubtype) *shubtype = ret_stuff.v0 & 0xff;
 
1086
        if (systemsize) *systemsize = (ret_stuff.v0 >> 8) & 0xff;
 
1087
        if (sharing_domain_size) *sharing_domain_size = (ret_stuff.v0 >> 16) & 0xff;
 
1088
        if (partid) *partid = (ret_stuff.v0 >> 24) & 0xff;
 
1089
        if (coher) *coher = (ret_stuff.v0 >> 32) & 0xff;
 
1090
        if (reg) *reg = (ret_stuff.v0 >> 40) & 0xff;
 
1091
        if (nasid_bitmask) *nasid_bitmask = (ret_stuff.v1 & 0xffff);
 
1092
        if (nasid_shift) *nasid_shift = (ret_stuff.v1 >> 16) & 0xff;
 
1093
        return 0;
 
1094
}
 
1095
 
 
1096
/*
 
1097
 * This is the access point to the Altix PROM hardware performance
 
1098
 * and status monitoring interface. For info on using this, see
 
1099
 * arch/ia64/include/asm/sn/sn2/sn_hwperf.h
 
1100
 */
 
1101
static inline int
 
1102
ia64_sn_hwperf_op(nasid_t nasid, u64 opcode, u64 a0, u64 a1, u64 a2,
 
1103
                  u64 a3, u64 a4, int *v0)
 
1104
{
 
1105
        struct ia64_sal_retval rv;
 
1106
        SAL_CALL_NOLOCK(rv, SN_SAL_HWPERF_OP, (u64)nasid,
 
1107
                opcode, a0, a1, a2, a3, a4);
 
1108
        if (v0)
 
1109
                *v0 = (int) rv.v0;
 
1110
        return (int) rv.status;
 
1111
}
 
1112
 
 
1113
static inline int
 
1114
ia64_sn_ioif_get_pci_topology(u64 buf, u64 len)
 
1115
{
 
1116
        struct ia64_sal_retval rv;
 
1117
        SAL_CALL_NOLOCK(rv, SN_SAL_IOIF_GET_PCI_TOPOLOGY, buf, len, 0, 0, 0, 0, 0);
 
1118
        return (int) rv.status;
 
1119
}
 
1120
 
 
1121
/*
 
1122
 * BTE error recovery is implemented in SAL
 
1123
 */
 
1124
static inline int
 
1125
ia64_sn_bte_recovery(nasid_t nasid)
 
1126
{
 
1127
        struct ia64_sal_retval rv;
 
1128
 
 
1129
        rv.status = 0;
 
1130
        SAL_CALL_NOLOCK(rv, SN_SAL_BTE_RECOVER, (u64)nasid, 0, 0, 0, 0, 0, 0);
 
1131
        if (rv.status == SALRET_NOT_IMPLEMENTED)
 
1132
                return 0;
 
1133
        return (int) rv.status;
 
1134
}
 
1135
 
 
1136
static inline int
 
1137
ia64_sn_is_fake_prom(void)
 
1138
{
 
1139
        struct ia64_sal_retval rv;
 
1140
        SAL_CALL_NOLOCK(rv, SN_SAL_FAKE_PROM, 0, 0, 0, 0, 0, 0, 0);
 
1141
        return (rv.status == 0);
 
1142
}
 
1143
 
 
1144
static inline int
 
1145
ia64_sn_get_prom_feature_set(int set, unsigned long *feature_set)
 
1146
{
 
1147
        struct ia64_sal_retval rv;
 
1148
 
 
1149
        SAL_CALL_NOLOCK(rv, SN_SAL_GET_PROM_FEATURE_SET, set, 0, 0, 0, 0, 0, 0);
 
1150
        if (rv.status != 0)
 
1151
                return rv.status;
 
1152
        *feature_set = rv.v0;
 
1153
        return 0;
 
1154
}
 
1155
 
 
1156
static inline int
 
1157
ia64_sn_set_os_feature(int feature)
 
1158
{
 
1159
        struct ia64_sal_retval rv;
 
1160
 
 
1161
        SAL_CALL_NOLOCK(rv, SN_SAL_SET_OS_FEATURE_SET, feature, 0, 0, 0, 0, 0, 0);
 
1162
        return rv.status;
 
1163
}
 
1164
 
 
1165
static inline int
 
1166
sn_inject_error(u64 paddr, u64 *data, u64 *ecc)
 
1167
{
 
1168
        struct ia64_sal_retval ret_stuff;
 
1169
 
 
1170
        ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_INJECT_ERROR, paddr, (u64)data,
 
1171
                                (u64)ecc, 0, 0, 0, 0);
 
1172
        return ret_stuff.status;
 
1173
}
 
1174
 
 
1175
static inline int
 
1176
ia64_sn_set_cpu_number(int cpu)
 
1177
{
 
1178
        struct ia64_sal_retval rv;
 
1179
 
 
1180
        SAL_CALL_NOLOCK(rv, SN_SAL_SET_CPU_NUMBER, cpu, 0, 0, 0, 0, 0, 0);
 
1181
        return rv.status;
 
1182
}
 
1183
static inline int
 
1184
ia64_sn_kernel_launch_event(void)
 
1185
{
 
1186
        struct ia64_sal_retval rv;
 
1187
        SAL_CALL_NOLOCK(rv, SN_SAL_KERNEL_LAUNCH_EVENT, 0, 0, 0, 0, 0, 0, 0);
 
1188
        return rv.status;
 
1189
}
 
1190
 
 
1191
union sn_watchlist_u {
 
1192
        u64     val;
 
1193
        struct {
 
1194
                u64     blade   : 16,
 
1195
                        size    : 32,
 
1196
                        filler  : 16;
 
1197
        };
 
1198
};
 
1199
 
 
1200
static inline int
 
1201
sn_mq_watchlist_alloc(int blade, void *mq, unsigned int mq_size,
 
1202
                                unsigned long *intr_mmr_offset)
 
1203
{
 
1204
        struct ia64_sal_retval rv;
 
1205
        unsigned long addr;
 
1206
        union sn_watchlist_u size_blade;
 
1207
        int watchlist;
 
1208
 
 
1209
        addr = (unsigned long)mq;
 
1210
        size_blade.size = mq_size;
 
1211
        size_blade.blade = blade;
 
1212
 
 
1213
        /*
 
1214
         * bios returns watchlist number or negative error number.
 
1215
         */
 
1216
        ia64_sal_oemcall_nolock(&rv, SN_SAL_WATCHLIST_ALLOC, addr,
 
1217
                        size_blade.val, (u64)intr_mmr_offset,
 
1218
                        (u64)&watchlist, 0, 0, 0);
 
1219
        if (rv.status < 0)
 
1220
                return rv.status;
 
1221
 
 
1222
        return watchlist;
 
1223
}
 
1224
 
 
1225
static inline int
 
1226
sn_mq_watchlist_free(int blade, int watchlist_num)
 
1227
{
 
1228
        struct ia64_sal_retval rv;
 
1229
        ia64_sal_oemcall_nolock(&rv, SN_SAL_WATCHLIST_FREE, blade,
 
1230
                        watchlist_num, 0, 0, 0, 0, 0);
 
1231
        return rv.status;
 
1232
}
 
1233
#endif /* _ASM_IA64_SN_SN_SAL_H */