1 | #ifndef _ASM_IA64_SAL_H |
---|
2 | #define _ASM_IA64_SAL_H |
---|
3 | |
---|
4 | /* |
---|
5 | * System Abstraction Layer definitions. |
---|
6 | * |
---|
7 | * This is based on version 2.5 of the manual "IA-64 System |
---|
8 | * Abstraction Layer". |
---|
9 | * |
---|
10 | * Copyright (C) 2001 Intel |
---|
11 | * Copyright (C) 2002 Jenna Hall <jenna.s.hall@intel.com> |
---|
12 | * Copyright (C) 2001 Fred Lewis <frederick.v.lewis@intel.com> |
---|
13 | * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co |
---|
14 | * David Mosberger-Tang <davidm@hpl.hp.com> |
---|
15 | * Copyright (C) 1999 Srinivasa Prasad Thirumalachar <sprasad@sprasad.engr.sgi.com> |
---|
16 | * |
---|
17 | * 02/01/04 J. Hall Updated Error Record Structures to conform to July 2001 |
---|
18 | * revision of the SAL spec. |
---|
19 | * 01/01/03 fvlewis Updated Error Record Structures to conform with Nov. 2000 |
---|
20 | * revision of the SAL spec. |
---|
21 | * 99/09/29 davidm Updated for SAL 2.6. |
---|
22 | * 00/03/29 cfleck Updated SAL Error Logging info for processor (SAL 2.6) |
---|
23 | * (plus examples of platform error info structures from smariset @ Intel) |
---|
24 | */ |
---|
25 | |
---|
26 | #define IA64_SAL_PLATFORM_FEATURE_BUS_LOCK_BIT 0 |
---|
27 | #define IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT_BIT 1 |
---|
28 | #define IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT_BIT 2 |
---|
29 | #define IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT 3 |
---|
30 | |
---|
31 | #define IA64_SAL_PLATFORM_FEATURE_BUS_LOCK (1<<IA64_SAL_PLATFORM_FEATURE_BUS_LOCK_BIT) |
---|
32 | #define IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT (1<<IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT_BIT) |
---|
33 | #define IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT (1<<IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT_BIT) |
---|
34 | #define IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT (1<<IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT) |
---|
35 | |
---|
36 | #ifndef __ASSEMBLY__ |
---|
37 | |
---|
38 | #include <linux/bcd.h> |
---|
39 | #include <linux/spinlock.h> |
---|
40 | #include <linux/efi.h> |
---|
41 | |
---|
42 | #include <asm/pal.h> |
---|
43 | #include <asm/system.h> |
---|
44 | #include <asm/fpu.h> |
---|
45 | #ifdef CONFIG_XEN |
---|
46 | #include <asm/xen/xencomm.h> |
---|
47 | #endif |
---|
48 | |
---|
49 | extern spinlock_t sal_lock; |
---|
50 | |
---|
51 | /* SAL spec _requires_ eight args for each call. */ |
---|
52 | #define __SAL_CALL(result,a0,a1,a2,a3,a4,a5,a6,a7) \ |
---|
53 | result = (*ia64_sal)(a0,a1,a2,a3,a4,a5,a6,a7) |
---|
54 | |
---|
55 | # define SAL_CALL(result,args...) do { \ |
---|
56 | unsigned long __ia64_sc_flags; \ |
---|
57 | struct ia64_fpreg __ia64_sc_fr[6]; \ |
---|
58 | ia64_save_scratch_fpregs(__ia64_sc_fr); \ |
---|
59 | spin_lock_irqsave(&sal_lock, __ia64_sc_flags); \ |
---|
60 | __SAL_CALL(result, args); \ |
---|
61 | spin_unlock_irqrestore(&sal_lock, __ia64_sc_flags); \ |
---|
62 | ia64_load_scratch_fpregs(__ia64_sc_fr); \ |
---|
63 | } while (0) |
---|
64 | |
---|
65 | # define SAL_CALL_NOLOCK(result,args...) do { \ |
---|
66 | unsigned long __ia64_scn_flags; \ |
---|
67 | struct ia64_fpreg __ia64_scn_fr[6]; \ |
---|
68 | ia64_save_scratch_fpregs(__ia64_scn_fr); \ |
---|
69 | local_irq_save(__ia64_scn_flags); \ |
---|
70 | __SAL_CALL(result, args); \ |
---|
71 | local_irq_restore(__ia64_scn_flags); \ |
---|
72 | ia64_load_scratch_fpregs(__ia64_scn_fr); \ |
---|
73 | } while (0) |
---|
74 | |
---|
75 | # define SAL_CALL_REENTRANT(result,args...) do { \ |
---|
76 | struct ia64_fpreg __ia64_scs_fr[6]; \ |
---|
77 | ia64_save_scratch_fpregs(__ia64_scs_fr); \ |
---|
78 | preempt_disable(); \ |
---|
79 | __SAL_CALL(result, args); \ |
---|
80 | preempt_enable(); \ |
---|
81 | ia64_load_scratch_fpregs(__ia64_scs_fr); \ |
---|
82 | } while (0) |
---|
83 | |
---|
84 | #define SAL_SET_VECTORS 0x01000000 |
---|
85 | #define SAL_GET_STATE_INFO 0x01000001 |
---|
86 | #define SAL_GET_STATE_INFO_SIZE 0x01000002 |
---|
87 | #define SAL_CLEAR_STATE_INFO 0x01000003 |
---|
88 | #define SAL_MC_RENDEZ 0x01000004 |
---|
89 | #define SAL_MC_SET_PARAMS 0x01000005 |
---|
90 | #define SAL_REGISTER_PHYSICAL_ADDR 0x01000006 |
---|
91 | |
---|
92 | #define SAL_CACHE_FLUSH 0x01000008 |
---|
93 | #define SAL_CACHE_INIT 0x01000009 |
---|
94 | #define SAL_PCI_CONFIG_READ 0x01000010 |
---|
95 | #define SAL_PCI_CONFIG_WRITE 0x01000011 |
---|
96 | #define SAL_FREQ_BASE 0x01000012 |
---|
97 | #define SAL_PHYSICAL_ID_INFO 0x01000013 |
---|
98 | |
---|
99 | #define SAL_UPDATE_PAL 0x01000020 |
---|
100 | |
---|
101 | struct ia64_sal_retval { |
---|
102 | /* |
---|
103 | * A zero status value indicates call completed without error. |
---|
104 | * A negative status value indicates reason of call failure. |
---|
105 | * A positive status value indicates success but an |
---|
106 | * informational value should be printed (e.g., "reboot for |
---|
107 | * change to take effect"). |
---|
108 | */ |
---|
109 | s64 status; |
---|
110 | u64 v0; |
---|
111 | u64 v1; |
---|
112 | u64 v2; |
---|
113 | }; |
---|
114 | |
---|
115 | typedef struct ia64_sal_retval (*ia64_sal_handler) (u64, ...); |
---|
116 | |
---|
117 | enum { |
---|
118 | SAL_FREQ_BASE_PLATFORM = 0, |
---|
119 | SAL_FREQ_BASE_INTERVAL_TIMER = 1, |
---|
120 | SAL_FREQ_BASE_REALTIME_CLOCK = 2 |
---|
121 | }; |
---|
122 | |
---|
123 | /* |
---|
124 | * The SAL system table is followed by a variable number of variable |
---|
125 | * length descriptors. The structure of these descriptors follows |
---|
126 | * below. |
---|
127 | * The defininition follows SAL specs from July 2000 |
---|
128 | */ |
---|
129 | struct ia64_sal_systab { |
---|
130 | u8 signature[4]; /* should be "SST_" */ |
---|
131 | u32 size; /* size of this table in bytes */ |
---|
132 | u8 sal_rev_minor; |
---|
133 | u8 sal_rev_major; |
---|
134 | u16 entry_count; /* # of entries in variable portion */ |
---|
135 | u8 checksum; |
---|
136 | u8 reserved1[7]; |
---|
137 | u8 sal_a_rev_minor; |
---|
138 | u8 sal_a_rev_major; |
---|
139 | u8 sal_b_rev_minor; |
---|
140 | u8 sal_b_rev_major; |
---|
141 | /* oem_id & product_id: terminating NUL is missing if string is exactly 32 bytes long. */ |
---|
142 | u8 oem_id[32]; |
---|
143 | u8 product_id[32]; /* ASCII product id */ |
---|
144 | u8 reserved2[8]; |
---|
145 | }; |
---|
146 | |
---|
147 | enum sal_systab_entry_type { |
---|
148 | SAL_DESC_ENTRY_POINT = 0, |
---|
149 | SAL_DESC_MEMORY = 1, |
---|
150 | SAL_DESC_PLATFORM_FEATURE = 2, |
---|
151 | SAL_DESC_TR = 3, |
---|
152 | SAL_DESC_PTC = 4, |
---|
153 | SAL_DESC_AP_WAKEUP = 5 |
---|
154 | }; |
---|
155 | |
---|
156 | /* |
---|
157 | * Entry type: Size: |
---|
158 | * 0 48 |
---|
159 | * 1 32 |
---|
160 | * 2 16 |
---|
161 | * 3 32 |
---|
162 | * 4 16 |
---|
163 | * 5 16 |
---|
164 | */ |
---|
165 | #define SAL_DESC_SIZE(type) "\060\040\020\040\020\020"[(unsigned) type] |
---|
166 | |
---|
167 | typedef struct ia64_sal_desc_entry_point { |
---|
168 | u8 type; |
---|
169 | u8 reserved1[7]; |
---|
170 | u64 pal_proc; |
---|
171 | u64 sal_proc; |
---|
172 | u64 gp; |
---|
173 | u8 reserved2[16]; |
---|
174 | }ia64_sal_desc_entry_point_t; |
---|
175 | |
---|
176 | typedef struct ia64_sal_desc_memory { |
---|
177 | u8 type; |
---|
178 | u8 used_by_sal; /* needs to be mapped for SAL? */ |
---|
179 | u8 mem_attr; /* current memory attribute setting */ |
---|
180 | u8 access_rights; /* access rights set up by SAL */ |
---|
181 | u8 mem_attr_mask; /* mask of supported memory attributes */ |
---|
182 | u8 reserved1; |
---|
183 | u8 mem_type; /* memory type */ |
---|
184 | u8 mem_usage; /* memory usage */ |
---|
185 | u64 addr; /* physical address of memory */ |
---|
186 | u32 length; /* length (multiple of 4KB pages) */ |
---|
187 | u32 reserved2; |
---|
188 | u8 oem_reserved[8]; |
---|
189 | } ia64_sal_desc_memory_t; |
---|
190 | |
---|
191 | typedef struct ia64_sal_desc_platform_feature { |
---|
192 | u8 type; |
---|
193 | u8 feature_mask; |
---|
194 | u8 reserved1[14]; |
---|
195 | } ia64_sal_desc_platform_feature_t; |
---|
196 | |
---|
197 | typedef struct ia64_sal_desc_tr { |
---|
198 | u8 type; |
---|
199 | u8 tr_type; /* 0 == instruction, 1 == data */ |
---|
200 | u8 regnum; /* translation register number */ |
---|
201 | u8 reserved1[5]; |
---|
202 | u64 addr; /* virtual address of area covered */ |
---|
203 | u64 page_size; /* encoded page size */ |
---|
204 | u8 reserved2[8]; |
---|
205 | } ia64_sal_desc_tr_t; |
---|
206 | |
---|
207 | typedef struct ia64_sal_desc_ptc { |
---|
208 | u8 type; |
---|
209 | u8 reserved1[3]; |
---|
210 | u32 num_domains; /* # of coherence domains */ |
---|
211 | u64 domain_info; /* physical address of domain info table */ |
---|
212 | } ia64_sal_desc_ptc_t; |
---|
213 | |
---|
214 | typedef struct ia64_sal_ptc_domain_info { |
---|
215 | u64 proc_count; /* number of processors in domain */ |
---|
216 | u64 proc_list; /* physical address of LID array */ |
---|
217 | } ia64_sal_ptc_domain_info_t; |
---|
218 | |
---|
219 | typedef struct ia64_sal_ptc_domain_proc_entry { |
---|
220 | u64 id : 8; /* id of processor */ |
---|
221 | u64 eid : 8; /* eid of processor */ |
---|
222 | } ia64_sal_ptc_domain_proc_entry_t; |
---|
223 | |
---|
224 | |
---|
225 | #define IA64_SAL_AP_EXTERNAL_INT 0 |
---|
226 | |
---|
227 | typedef struct ia64_sal_desc_ap_wakeup { |
---|
228 | u8 type; |
---|
229 | u8 mechanism; /* 0 == external interrupt */ |
---|
230 | u8 reserved1[6]; |
---|
231 | u64 vector; /* interrupt vector in range 0x10-0xff */ |
---|
232 | } ia64_sal_desc_ap_wakeup_t ; |
---|
233 | |
---|
234 | extern ia64_sal_handler ia64_sal; |
---|
235 | extern struct ia64_sal_desc_ptc *ia64_ptc_domain_info; |
---|
236 | |
---|
237 | extern unsigned short sal_revision; /* supported SAL spec revision */ |
---|
238 | extern unsigned short sal_version; /* SAL version; OEM dependent */ |
---|
239 | #define SAL_VERSION_CODE(major, minor) ((BIN2BCD(major) << 8) | BIN2BCD(minor)) |
---|
240 | |
---|
241 | extern const char *ia64_sal_strerror (long status); |
---|
242 | extern void ia64_sal_init (struct ia64_sal_systab *sal_systab); |
---|
243 | |
---|
244 | /* SAL information type encodings */ |
---|
245 | enum { |
---|
246 | SAL_INFO_TYPE_MCA = 0, /* Machine check abort information */ |
---|
247 | SAL_INFO_TYPE_INIT = 1, /* Init information */ |
---|
248 | SAL_INFO_TYPE_CMC = 2, /* Corrected machine check information */ |
---|
249 | SAL_INFO_TYPE_CPE = 3 /* Corrected platform error information */ |
---|
250 | }; |
---|
251 | |
---|
252 | /* Encodings for machine check parameter types */ |
---|
253 | enum { |
---|
254 | SAL_MC_PARAM_RENDEZ_INT = 1, /* Rendezvous interrupt */ |
---|
255 | SAL_MC_PARAM_RENDEZ_WAKEUP = 2, /* Wakeup */ |
---|
256 | SAL_MC_PARAM_CPE_INT = 3 /* Corrected Platform Error Int */ |
---|
257 | }; |
---|
258 | |
---|
259 | /* Encodings for rendezvous mechanisms */ |
---|
260 | enum { |
---|
261 | SAL_MC_PARAM_MECHANISM_INT = 1, /* Use interrupt */ |
---|
262 | SAL_MC_PARAM_MECHANISM_MEM = 2 /* Use memory synchronization variable*/ |
---|
263 | }; |
---|
264 | |
---|
265 | /* Encodings for vectors which can be registered by the OS with SAL */ |
---|
266 | enum { |
---|
267 | SAL_VECTOR_OS_MCA = 0, |
---|
268 | SAL_VECTOR_OS_INIT = 1, |
---|
269 | SAL_VECTOR_OS_BOOT_RENDEZ = 2 |
---|
270 | }; |
---|
271 | |
---|
272 | /* Encodings for mca_opt parameter sent to SAL_MC_SET_PARAMS */ |
---|
273 | #define SAL_MC_PARAM_RZ_ALWAYS 0x1 |
---|
274 | #define SAL_MC_PARAM_BINIT_ESCALATE 0x10 |
---|
275 | |
---|
276 | /* |
---|
277 | * Definition of the SAL Error Log from the SAL spec |
---|
278 | */ |
---|
279 | |
---|
280 | /* SAL Error Record Section GUID Definitions */ |
---|
281 | #define SAL_PROC_DEV_ERR_SECT_GUID \ |
---|
282 | EFI_GUID(0xe429faf1, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81) |
---|
283 | #define SAL_PLAT_MEM_DEV_ERR_SECT_GUID \ |
---|
284 | EFI_GUID(0xe429faf2, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81) |
---|
285 | #define SAL_PLAT_SEL_DEV_ERR_SECT_GUID \ |
---|
286 | EFI_GUID(0xe429faf3, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81) |
---|
287 | #define SAL_PLAT_PCI_BUS_ERR_SECT_GUID \ |
---|
288 | EFI_GUID(0xe429faf4, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81) |
---|
289 | #define SAL_PLAT_SMBIOS_DEV_ERR_SECT_GUID \ |
---|
290 | EFI_GUID(0xe429faf5, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81) |
---|
291 | #define SAL_PLAT_PCI_COMP_ERR_SECT_GUID \ |
---|
292 | EFI_GUID(0xe429faf6, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81) |
---|
293 | #define SAL_PLAT_SPECIFIC_ERR_SECT_GUID \ |
---|
294 | EFI_GUID(0xe429faf7, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81) |
---|
295 | #define SAL_PLAT_HOST_CTLR_ERR_SECT_GUID \ |
---|
296 | EFI_GUID(0xe429faf8, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81) |
---|
297 | #define SAL_PLAT_BUS_ERR_SECT_GUID \ |
---|
298 | EFI_GUID(0xe429faf9, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81) |
---|
299 | |
---|
300 | #define MAX_CACHE_ERRORS 6 |
---|
301 | #define MAX_TLB_ERRORS 6 |
---|
302 | #define MAX_BUS_ERRORS 1 |
---|
303 | |
---|
304 | /* Definition of version according to SAL spec for logging purposes */ |
---|
305 | typedef struct sal_log_revision { |
---|
306 | u8 minor; /* BCD (0..99) */ |
---|
307 | u8 major; /* BCD (0..99) */ |
---|
308 | } sal_log_revision_t; |
---|
309 | |
---|
310 | /* Definition of timestamp according to SAL spec for logging purposes */ |
---|
311 | typedef struct sal_log_timestamp { |
---|
312 | u8 slh_second; /* Second (0..59) */ |
---|
313 | u8 slh_minute; /* Minute (0..59) */ |
---|
314 | u8 slh_hour; /* Hour (0..23) */ |
---|
315 | u8 slh_reserved; |
---|
316 | u8 slh_day; /* Day (1..31) */ |
---|
317 | u8 slh_month; /* Month (1..12) */ |
---|
318 | u8 slh_year; /* Year (00..99) */ |
---|
319 | u8 slh_century; /* Century (19, 20, 21, ...) */ |
---|
320 | } sal_log_timestamp_t; |
---|
321 | |
---|
322 | /* Definition of log record header structures */ |
---|
323 | typedef struct sal_log_record_header { |
---|
324 | u64 id; /* Unique monotonically increasing ID */ |
---|
325 | sal_log_revision_t revision; /* Major and Minor revision of header */ |
---|
326 | u8 severity; /* Error Severity */ |
---|
327 | u8 validation_bits; /* 0: platform_guid, 1: !timestamp */ |
---|
328 | u32 len; /* Length of this error log in bytes */ |
---|
329 | sal_log_timestamp_t timestamp; /* Timestamp */ |
---|
330 | efi_guid_t platform_guid; /* Unique OEM Platform ID */ |
---|
331 | } sal_log_record_header_t; |
---|
332 | |
---|
333 | #define sal_log_severity_recoverable 0 |
---|
334 | #define sal_log_severity_fatal 1 |
---|
335 | #define sal_log_severity_corrected 2 |
---|
336 | |
---|
337 | /* Definition of log section header structures */ |
---|
338 | typedef struct sal_log_sec_header { |
---|
339 | efi_guid_t guid; /* Unique Section ID */ |
---|
340 | sal_log_revision_t revision; /* Major and Minor revision of Section */ |
---|
341 | u16 reserved; |
---|
342 | u32 len; /* Section length */ |
---|
343 | } sal_log_section_hdr_t; |
---|
344 | |
---|
345 | typedef struct sal_log_mod_error_info { |
---|
346 | struct { |
---|
347 | u64 check_info : 1, |
---|
348 | requestor_identifier : 1, |
---|
349 | responder_identifier : 1, |
---|
350 | target_identifier : 1, |
---|
351 | precise_ip : 1, |
---|
352 | reserved : 59; |
---|
353 | } valid; |
---|
354 | u64 check_info; |
---|
355 | u64 requestor_identifier; |
---|
356 | u64 responder_identifier; |
---|
357 | u64 target_identifier; |
---|
358 | u64 precise_ip; |
---|
359 | } sal_log_mod_error_info_t; |
---|
360 | |
---|
361 | typedef struct sal_processor_static_info { |
---|
362 | struct { |
---|
363 | u64 minstate : 1, |
---|
364 | br : 1, |
---|
365 | cr : 1, |
---|
366 | ar : 1, |
---|
367 | rr : 1, |
---|
368 | fr : 1, |
---|
369 | reserved : 58; |
---|
370 | } valid; |
---|
371 | pal_min_state_area_t min_state_area; |
---|
372 | u64 br[8]; |
---|
373 | u64 cr[128]; |
---|
374 | u64 ar[128]; |
---|
375 | u64 rr[8]; |
---|
376 | struct ia64_fpreg __attribute__ ((packed)) fr[128]; |
---|
377 | } sal_processor_static_info_t; |
---|
378 | |
---|
379 | struct sal_cpuid_info { |
---|
380 | u64 regs[5]; |
---|
381 | u64 reserved; |
---|
382 | }; |
---|
383 | |
---|
384 | typedef struct sal_log_processor_info { |
---|
385 | sal_log_section_hdr_t header; |
---|
386 | struct { |
---|
387 | u64 proc_error_map : 1, |
---|
388 | proc_state_param : 1, |
---|
389 | proc_cr_lid : 1, |
---|
390 | psi_static_struct : 1, |
---|
391 | num_cache_check : 4, |
---|
392 | num_tlb_check : 4, |
---|
393 | num_bus_check : 4, |
---|
394 | num_reg_file_check : 4, |
---|
395 | num_ms_check : 4, |
---|
396 | cpuid_info : 1, |
---|
397 | reserved1 : 39; |
---|
398 | } valid; |
---|
399 | u64 proc_error_map; |
---|
400 | u64 proc_state_parameter; |
---|
401 | u64 proc_cr_lid; |
---|
402 | /* |
---|
403 | * The rest of this structure consists of variable-length arrays, which can't be |
---|
404 | * expressed in C. |
---|
405 | */ |
---|
406 | sal_log_mod_error_info_t info[0]; |
---|
407 | /* |
---|
408 | * This is what the rest looked like if C supported variable-length arrays: |
---|
409 | * |
---|
410 | * sal_log_mod_error_info_t cache_check_info[.valid.num_cache_check]; |
---|
411 | * sal_log_mod_error_info_t tlb_check_info[.valid.num_tlb_check]; |
---|
412 | * sal_log_mod_error_info_t bus_check_info[.valid.num_bus_check]; |
---|
413 | * sal_log_mod_error_info_t reg_file_check_info[.valid.num_reg_file_check]; |
---|
414 | * sal_log_mod_error_info_t ms_check_info[.valid.num_ms_check]; |
---|
415 | * struct sal_cpuid_info cpuid_info; |
---|
416 | * sal_processor_static_info_t processor_static_info; |
---|
417 | */ |
---|
418 | } sal_log_processor_info_t; |
---|
419 | |
---|
420 | /* Given a sal_log_processor_info_t pointer, return a pointer to the processor_static_info: */ |
---|
421 | #define SAL_LPI_PSI_INFO(l) \ |
---|
422 | ({ sal_log_processor_info_t *_l = (l); \ |
---|
423 | ((sal_processor_static_info_t *) \ |
---|
424 | ((char *) _l->info + ((_l->valid.num_cache_check + _l->valid.num_tlb_check \ |
---|
425 | + _l->valid.num_bus_check + _l->valid.num_reg_file_check \ |
---|
426 | + _l->valid.num_ms_check) * sizeof(sal_log_mod_error_info_t) \ |
---|
427 | + sizeof(struct sal_cpuid_info)))); \ |
---|
428 | }) |
---|
429 | |
---|
430 | /* platform error log structures */ |
---|
431 | |
---|
432 | typedef struct sal_log_mem_dev_err_info { |
---|
433 | sal_log_section_hdr_t header; |
---|
434 | struct { |
---|
435 | u64 error_status : 1, |
---|
436 | physical_addr : 1, |
---|
437 | addr_mask : 1, |
---|
438 | node : 1, |
---|
439 | card : 1, |
---|
440 | module : 1, |
---|
441 | bank : 1, |
---|
442 | device : 1, |
---|
443 | row : 1, |
---|
444 | column : 1, |
---|
445 | bit_position : 1, |
---|
446 | requestor_id : 1, |
---|
447 | responder_id : 1, |
---|
448 | target_id : 1, |
---|
449 | bus_spec_data : 1, |
---|
450 | oem_id : 1, |
---|
451 | oem_data : 1, |
---|
452 | reserved : 47; |
---|
453 | } valid; |
---|
454 | u64 error_status; |
---|
455 | u64 physical_addr; |
---|
456 | u64 addr_mask; |
---|
457 | u16 node; |
---|
458 | u16 card; |
---|
459 | u16 module; |
---|
460 | u16 bank; |
---|
461 | u16 device; |
---|
462 | u16 row; |
---|
463 | u16 column; |
---|
464 | u16 bit_position; |
---|
465 | u64 requestor_id; |
---|
466 | u64 responder_id; |
---|
467 | u64 target_id; |
---|
468 | u64 bus_spec_data; |
---|
469 | u8 oem_id[16]; |
---|
470 | u8 oem_data[1]; /* Variable length data */ |
---|
471 | } sal_log_mem_dev_err_info_t; |
---|
472 | |
---|
473 | typedef struct sal_log_sel_dev_err_info { |
---|
474 | sal_log_section_hdr_t header; |
---|
475 | struct { |
---|
476 | u64 record_id : 1, |
---|
477 | record_type : 1, |
---|
478 | generator_id : 1, |
---|
479 | evm_rev : 1, |
---|
480 | sensor_type : 1, |
---|
481 | sensor_num : 1, |
---|
482 | event_dir : 1, |
---|
483 | event_data1 : 1, |
---|
484 | event_data2 : 1, |
---|
485 | event_data3 : 1, |
---|
486 | reserved : 54; |
---|
487 | } valid; |
---|
488 | u16 record_id; |
---|
489 | u8 record_type; |
---|
490 | u8 timestamp[4]; |
---|
491 | u16 generator_id; |
---|
492 | u8 evm_rev; |
---|
493 | u8 sensor_type; |
---|
494 | u8 sensor_num; |
---|
495 | u8 event_dir; |
---|
496 | u8 event_data1; |
---|
497 | u8 event_data2; |
---|
498 | u8 event_data3; |
---|
499 | } sal_log_sel_dev_err_info_t; |
---|
500 | |
---|
501 | typedef struct sal_log_pci_bus_err_info { |
---|
502 | sal_log_section_hdr_t header; |
---|
503 | struct { |
---|
504 | u64 err_status : 1, |
---|
505 | err_type : 1, |
---|
506 | bus_id : 1, |
---|
507 | bus_address : 1, |
---|
508 | bus_data : 1, |
---|
509 | bus_cmd : 1, |
---|
510 | requestor_id : 1, |
---|
511 | responder_id : 1, |
---|
512 | target_id : 1, |
---|
513 | oem_data : 1, |
---|
514 | reserved : 54; |
---|
515 | } valid; |
---|
516 | u64 err_status; |
---|
517 | u16 err_type; |
---|
518 | u16 bus_id; |
---|
519 | u32 reserved; |
---|
520 | u64 bus_address; |
---|
521 | u64 bus_data; |
---|
522 | u64 bus_cmd; |
---|
523 | u64 requestor_id; |
---|
524 | u64 responder_id; |
---|
525 | u64 target_id; |
---|
526 | u8 oem_data[1]; /* Variable length data */ |
---|
527 | } sal_log_pci_bus_err_info_t; |
---|
528 | |
---|
529 | typedef struct sal_log_smbios_dev_err_info { |
---|
530 | sal_log_section_hdr_t header; |
---|
531 | struct { |
---|
532 | u64 event_type : 1, |
---|
533 | length : 1, |
---|
534 | time_stamp : 1, |
---|
535 | data : 1, |
---|
536 | reserved1 : 60; |
---|
537 | } valid; |
---|
538 | u8 event_type; |
---|
539 | u8 length; |
---|
540 | u8 time_stamp[6]; |
---|
541 | u8 data[1]; /* data of variable length, length == slsmb_length */ |
---|
542 | } sal_log_smbios_dev_err_info_t; |
---|
543 | |
---|
544 | typedef struct sal_log_pci_comp_err_info { |
---|
545 | sal_log_section_hdr_t header; |
---|
546 | struct { |
---|
547 | u64 err_status : 1, |
---|
548 | comp_info : 1, |
---|
549 | num_mem_regs : 1, |
---|
550 | num_io_regs : 1, |
---|
551 | reg_data_pairs : 1, |
---|
552 | oem_data : 1, |
---|
553 | reserved : 58; |
---|
554 | } valid; |
---|
555 | u64 err_status; |
---|
556 | struct { |
---|
557 | u16 vendor_id; |
---|
558 | u16 device_id; |
---|
559 | u8 class_code[3]; |
---|
560 | u8 func_num; |
---|
561 | u8 dev_num; |
---|
562 | u8 bus_num; |
---|
563 | u8 seg_num; |
---|
564 | u8 reserved[5]; |
---|
565 | } comp_info; |
---|
566 | u32 num_mem_regs; |
---|
567 | u32 num_io_regs; |
---|
568 | u64 reg_data_pairs[1]; |
---|
569 | /* |
---|
570 | * array of address/data register pairs is num_mem_regs + num_io_regs elements |
---|
571 | * long. Each array element consists of a u64 address followed by a u64 data |
---|
572 | * value. The oem_data array immediately follows the reg_data_pairs array |
---|
573 | */ |
---|
574 | u8 oem_data[1]; /* Variable length data */ |
---|
575 | } sal_log_pci_comp_err_info_t; |
---|
576 | |
---|
577 | typedef struct sal_log_plat_specific_err_info { |
---|
578 | sal_log_section_hdr_t header; |
---|
579 | struct { |
---|
580 | u64 err_status : 1, |
---|
581 | guid : 1, |
---|
582 | oem_data : 1, |
---|
583 | reserved : 61; |
---|
584 | } valid; |
---|
585 | u64 err_status; |
---|
586 | efi_guid_t guid; |
---|
587 | u8 oem_data[1]; /* platform specific variable length data */ |
---|
588 | } sal_log_plat_specific_err_info_t; |
---|
589 | |
---|
590 | typedef struct sal_log_host_ctlr_err_info { |
---|
591 | sal_log_section_hdr_t header; |
---|
592 | struct { |
---|
593 | u64 err_status : 1, |
---|
594 | requestor_id : 1, |
---|
595 | responder_id : 1, |
---|
596 | target_id : 1, |
---|
597 | bus_spec_data : 1, |
---|
598 | oem_data : 1, |
---|
599 | reserved : 58; |
---|
600 | } valid; |
---|
601 | u64 err_status; |
---|
602 | u64 requestor_id; |
---|
603 | u64 responder_id; |
---|
604 | u64 target_id; |
---|
605 | u64 bus_spec_data; |
---|
606 | u8 oem_data[1]; /* Variable length OEM data */ |
---|
607 | } sal_log_host_ctlr_err_info_t; |
---|
608 | |
---|
609 | typedef struct sal_log_plat_bus_err_info { |
---|
610 | sal_log_section_hdr_t header; |
---|
611 | struct { |
---|
612 | u64 err_status : 1, |
---|
613 | requestor_id : 1, |
---|
614 | responder_id : 1, |
---|
615 | target_id : 1, |
---|
616 | bus_spec_data : 1, |
---|
617 | oem_data : 1, |
---|
618 | reserved : 58; |
---|
619 | } valid; |
---|
620 | u64 err_status; |
---|
621 | u64 requestor_id; |
---|
622 | u64 responder_id; |
---|
623 | u64 target_id; |
---|
624 | u64 bus_spec_data; |
---|
625 | u8 oem_data[1]; /* Variable length OEM data */ |
---|
626 | } sal_log_plat_bus_err_info_t; |
---|
627 | |
---|
628 | /* Overall platform error section structure */ |
---|
629 | typedef union sal_log_platform_err_info { |
---|
630 | sal_log_mem_dev_err_info_t mem_dev_err; |
---|
631 | sal_log_sel_dev_err_info_t sel_dev_err; |
---|
632 | sal_log_pci_bus_err_info_t pci_bus_err; |
---|
633 | sal_log_smbios_dev_err_info_t smbios_dev_err; |
---|
634 | sal_log_pci_comp_err_info_t pci_comp_err; |
---|
635 | sal_log_plat_specific_err_info_t plat_specific_err; |
---|
636 | sal_log_host_ctlr_err_info_t host_ctlr_err; |
---|
637 | sal_log_plat_bus_err_info_t plat_bus_err; |
---|
638 | } sal_log_platform_err_info_t; |
---|
639 | |
---|
640 | /* SAL log over-all, multi-section error record structure (processor+platform) */ |
---|
641 | typedef struct err_rec { |
---|
642 | sal_log_record_header_t sal_elog_header; |
---|
643 | sal_log_processor_info_t proc_err; |
---|
644 | sal_log_platform_err_info_t plat_err; |
---|
645 | u8 oem_data_pad[1024]; |
---|
646 | } ia64_err_rec_t; |
---|
647 | |
---|
648 | /* |
---|
649 | * Now define a couple of inline functions for improved type checking |
---|
650 | * and convenience. |
---|
651 | */ |
---|
652 | static inline long |
---|
653 | ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second, |
---|
654 | unsigned long *drift_info) |
---|
655 | { |
---|
656 | struct ia64_sal_retval isrv; |
---|
657 | |
---|
658 | SAL_CALL(isrv, SAL_FREQ_BASE, which, 0, 0, 0, 0, 0, 0); |
---|
659 | *ticks_per_second = isrv.v0; |
---|
660 | *drift_info = isrv.v1; |
---|
661 | return isrv.status; |
---|
662 | } |
---|
663 | |
---|
664 | extern s64 ia64_sal_cache_flush (u64 cache_type); |
---|
665 | |
---|
666 | /* Initialize all the processor and platform level instruction and data caches */ |
---|
667 | static inline s64 |
---|
668 | ia64_sal_cache_init (void) |
---|
669 | { |
---|
670 | struct ia64_sal_retval isrv; |
---|
671 | SAL_CALL(isrv, SAL_CACHE_INIT, 0, 0, 0, 0, 0, 0, 0); |
---|
672 | return isrv.status; |
---|
673 | } |
---|
674 | |
---|
675 | /* |
---|
676 | * Clear the processor and platform information logged by SAL with respect to the machine |
---|
677 | * state at the time of MCA's, INITs, CMCs, or CPEs. |
---|
678 | */ |
---|
679 | static inline s64 |
---|
680 | ia64_sal_clear_state_info (u64 sal_info_type) |
---|
681 | { |
---|
682 | struct ia64_sal_retval isrv; |
---|
683 | SAL_CALL_REENTRANT(isrv, SAL_CLEAR_STATE_INFO, sal_info_type, 0, |
---|
684 | 0, 0, 0, 0, 0); |
---|
685 | return isrv.status; |
---|
686 | } |
---|
687 | |
---|
688 | |
---|
689 | /* Get the processor and platform information logged by SAL with respect to the machine |
---|
690 | * state at the time of the MCAs, INITs, CMCs, or CPEs. |
---|
691 | */ |
---|
692 | #ifdef CONFIG_XEN |
---|
693 | static inline u64 ia64_sal_get_state_info_size (u64 sal_info_type); |
---|
694 | #endif |
---|
695 | |
---|
696 | static inline u64 |
---|
697 | ia64_sal_get_state_info (u64 sal_info_type, u64 *sal_info) |
---|
698 | { |
---|
699 | struct ia64_sal_retval isrv; |
---|
700 | #ifdef CONFIG_XEN |
---|
701 | if (is_running_on_xen()) { |
---|
702 | struct xencomm_handle *desc; |
---|
703 | |
---|
704 | if (xencomm_create(sal_info, |
---|
705 | ia64_sal_get_state_info_size(sal_info_type), |
---|
706 | &desc, GFP_KERNEL)) |
---|
707 | return 0; |
---|
708 | |
---|
709 | SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO, sal_info_type, 0, |
---|
710 | desc, 0, 0, 0, 0); |
---|
711 | xencomm_free(desc); |
---|
712 | } else |
---|
713 | #endif |
---|
714 | SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO, sal_info_type, 0, |
---|
715 | sal_info, 0, 0, 0, 0); |
---|
716 | if (isrv.status) |
---|
717 | return 0; |
---|
718 | |
---|
719 | return isrv.v0; |
---|
720 | } |
---|
721 | |
---|
722 | /* |
---|
723 | * Get the maximum size of the information logged by SAL with respect to the machine state |
---|
724 | * at the time of MCAs, INITs, CMCs, or CPEs. |
---|
725 | */ |
---|
726 | static inline u64 |
---|
727 | ia64_sal_get_state_info_size (u64 sal_info_type) |
---|
728 | { |
---|
729 | struct ia64_sal_retval isrv; |
---|
730 | SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO_SIZE, sal_info_type, 0, |
---|
731 | 0, 0, 0, 0, 0); |
---|
732 | if (isrv.status) |
---|
733 | return 0; |
---|
734 | return isrv.v0; |
---|
735 | } |
---|
736 | |
---|
737 | /* |
---|
738 | * Causes the processor to go into a spin loop within SAL where SAL awaits a wakeup from |
---|
739 | * the monarch processor. Must not lock, because it will not return on any cpu until the |
---|
740 | * monarch processor sends a wake up. |
---|
741 | */ |
---|
742 | static inline s64 |
---|
743 | ia64_sal_mc_rendez (void) |
---|
744 | { |
---|
745 | struct ia64_sal_retval isrv; |
---|
746 | SAL_CALL_NOLOCK(isrv, SAL_MC_RENDEZ, 0, 0, 0, 0, 0, 0, 0); |
---|
747 | return isrv.status; |
---|
748 | } |
---|
749 | |
---|
750 | /* |
---|
751 | * Allow the OS to specify the interrupt number to be used by SAL to interrupt OS during |
---|
752 | * the machine check rendezvous sequence as well as the mechanism to wake up the |
---|
753 | * non-monarch processor at the end of machine check processing. |
---|
754 | * Returns the complete ia64_sal_retval because some calls return more than just a status |
---|
755 | * value. |
---|
756 | */ |
---|
757 | static inline struct ia64_sal_retval |
---|
758 | ia64_sal_mc_set_params (u64 param_type, u64 i_or_m, u64 i_or_m_val, u64 timeout, u64 rz_always) |
---|
759 | { |
---|
760 | struct ia64_sal_retval isrv; |
---|
761 | SAL_CALL(isrv, SAL_MC_SET_PARAMS, param_type, i_or_m, i_or_m_val, |
---|
762 | timeout, rz_always, 0, 0); |
---|
763 | return isrv; |
---|
764 | } |
---|
765 | |
---|
766 | /* Read from PCI configuration space */ |
---|
767 | static inline s64 |
---|
768 | ia64_sal_pci_config_read (u64 pci_config_addr, int type, u64 size, u64 *value) |
---|
769 | { |
---|
770 | struct ia64_sal_retval isrv; |
---|
771 | SAL_CALL(isrv, SAL_PCI_CONFIG_READ, pci_config_addr, size, type, 0, 0, 0, 0); |
---|
772 | if (value) |
---|
773 | *value = isrv.v0; |
---|
774 | return isrv.status; |
---|
775 | } |
---|
776 | |
---|
777 | /* Write to PCI configuration space */ |
---|
778 | static inline s64 |
---|
779 | ia64_sal_pci_config_write (u64 pci_config_addr, int type, u64 size, u64 value) |
---|
780 | { |
---|
781 | struct ia64_sal_retval isrv; |
---|
782 | SAL_CALL(isrv, SAL_PCI_CONFIG_WRITE, pci_config_addr, size, value, |
---|
783 | type, 0, 0, 0); |
---|
784 | return isrv.status; |
---|
785 | } |
---|
786 | |
---|
787 | /* |
---|
788 | * Register physical addresses of locations needed by SAL when SAL procedures are invoked |
---|
789 | * in virtual mode. |
---|
790 | */ |
---|
791 | static inline s64 |
---|
792 | ia64_sal_register_physical_addr (u64 phys_entry, u64 phys_addr) |
---|
793 | { |
---|
794 | struct ia64_sal_retval isrv; |
---|
795 | SAL_CALL(isrv, SAL_REGISTER_PHYSICAL_ADDR, phys_entry, phys_addr, |
---|
796 | 0, 0, 0, 0, 0); |
---|
797 | return isrv.status; |
---|
798 | } |
---|
799 | |
---|
800 | /* |
---|
801 | * Register software dependent code locations within SAL. These locations are handlers or |
---|
802 | * entry points where SAL will pass control for the specified event. These event handlers |
---|
803 | * are for the bott rendezvous, MCAs and INIT scenarios. |
---|
804 | */ |
---|
805 | static inline s64 |
---|
806 | ia64_sal_set_vectors (u64 vector_type, |
---|
807 | u64 handler_addr1, u64 gp1, u64 handler_len1, |
---|
808 | u64 handler_addr2, u64 gp2, u64 handler_len2) |
---|
809 | { |
---|
810 | struct ia64_sal_retval isrv; |
---|
811 | SAL_CALL(isrv, SAL_SET_VECTORS, vector_type, |
---|
812 | handler_addr1, gp1, handler_len1, |
---|
813 | handler_addr2, gp2, handler_len2); |
---|
814 | |
---|
815 | return isrv.status; |
---|
816 | } |
---|
817 | |
---|
818 | /* Update the contents of PAL block in the non-volatile storage device */ |
---|
819 | static inline s64 |
---|
820 | ia64_sal_update_pal (u64 param_buf, u64 scratch_buf, u64 scratch_buf_size, |
---|
821 | u64 *error_code, u64 *scratch_buf_size_needed) |
---|
822 | { |
---|
823 | struct ia64_sal_retval isrv; |
---|
824 | SAL_CALL(isrv, SAL_UPDATE_PAL, param_buf, scratch_buf, scratch_buf_size, |
---|
825 | 0, 0, 0, 0); |
---|
826 | if (error_code) |
---|
827 | *error_code = isrv.v0; |
---|
828 | if (scratch_buf_size_needed) |
---|
829 | *scratch_buf_size_needed = isrv.v1; |
---|
830 | return isrv.status; |
---|
831 | } |
---|
832 | |
---|
833 | /* Get physical processor die mapping in the platform. */ |
---|
834 | static inline s64 |
---|
835 | ia64_sal_physical_id_info(u16 *splid) |
---|
836 | { |
---|
837 | struct ia64_sal_retval isrv; |
---|
838 | SAL_CALL(isrv, SAL_PHYSICAL_ID_INFO, 0, 0, 0, 0, 0, 0, 0); |
---|
839 | if (splid) |
---|
840 | *splid = isrv.v0; |
---|
841 | return isrv.status; |
---|
842 | } |
---|
843 | |
---|
844 | extern unsigned long sal_platform_features; |
---|
845 | |
---|
846 | extern int (*salinfo_platform_oemdata)(const u8 *, u8 **, u64 *); |
---|
847 | |
---|
848 | struct sal_ret_values { |
---|
849 | long r8; long r9; long r10; long r11; |
---|
850 | }; |
---|
851 | |
---|
852 | #define IA64_SAL_OEMFUNC_MIN 0x02000000 |
---|
853 | #define IA64_SAL_OEMFUNC_MAX 0x03ffffff |
---|
854 | |
---|
855 | extern int ia64_sal_oemcall(struct ia64_sal_retval *, u64, u64, u64, u64, u64, |
---|
856 | u64, u64, u64); |
---|
857 | extern int ia64_sal_oemcall_nolock(struct ia64_sal_retval *, u64, u64, u64, |
---|
858 | u64, u64, u64, u64, u64); |
---|
859 | extern int ia64_sal_oemcall_reentrant(struct ia64_sal_retval *, u64, u64, u64, |
---|
860 | u64, u64, u64, u64, u64); |
---|
861 | #ifdef CONFIG_HOTPLUG_CPU |
---|
862 | /* |
---|
863 | * System Abstraction Layer Specification |
---|
864 | * Section 3.2.5.1: OS_BOOT_RENDEZ to SAL return State. |
---|
865 | * Note: region regs are stored first in head.S _start. Hence they must |
---|
866 | * stay up front. |
---|
867 | */ |
---|
868 | struct sal_to_os_boot { |
---|
869 | u64 rr[8]; /* Region Registers */ |
---|
870 | u64 br[6]; /* br0: return addr into SAL boot rendez routine */ |
---|
871 | u64 gr1; /* SAL:GP */ |
---|
872 | u64 gr12; /* SAL:SP */ |
---|
873 | u64 gr13; /* SAL: Task Pointer */ |
---|
874 | u64 fpsr; |
---|
875 | u64 pfs; |
---|
876 | u64 rnat; |
---|
877 | u64 unat; |
---|
878 | u64 bspstore; |
---|
879 | u64 dcr; /* Default Control Register */ |
---|
880 | u64 iva; |
---|
881 | u64 pta; |
---|
882 | u64 itv; |
---|
883 | u64 pmv; |
---|
884 | u64 cmcv; |
---|
885 | u64 lrr[2]; |
---|
886 | u64 gr[4]; |
---|
887 | u64 pr; /* Predicate registers */ |
---|
888 | u64 lc; /* Loop Count */ |
---|
889 | struct ia64_fpreg fp[20]; |
---|
890 | }; |
---|
891 | |
---|
892 | /* |
---|
893 | * Global array allocated for NR_CPUS at boot time |
---|
894 | */ |
---|
895 | extern struct sal_to_os_boot sal_boot_rendez_state[NR_CPUS]; |
---|
896 | |
---|
897 | extern void ia64_jump_to_sal(struct sal_to_os_boot *); |
---|
898 | #endif |
---|
899 | |
---|
900 | extern void ia64_sal_handler_init(void *entry_point, void *gpval); |
---|
901 | |
---|
902 | #endif /* __ASSEMBLY__ */ |
---|
903 | |
---|
904 | #endif /* _ASM_IA64_SAL_H */ |
---|