162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * File: mca.h 462306a36Sopenharmony_ci * Purpose: Machine check handling specific defines 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 1999, 2004 Silicon Graphics, Inc. 762306a36Sopenharmony_ci * Copyright (C) Vijay Chander <vijay@engr.sgi.com> 862306a36Sopenharmony_ci * Copyright (C) Srinivasa Thirumalachar <sprasad@engr.sgi.com> 962306a36Sopenharmony_ci * Copyright (C) Russ Anderson <rja@sgi.com> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#ifndef _ASM_IA64_MCA_H 1362306a36Sopenharmony_ci#define _ASM_IA64_MCA_H 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#if !defined(__ASSEMBLY__) 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include <linux/percpu.h> 1862306a36Sopenharmony_ci#include <linux/threads.h> 1962306a36Sopenharmony_ci#include <linux/types.h> 2062306a36Sopenharmony_ci#include <asm/ptrace.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define IA64_MCA_RENDEZ_TIMEOUT (20 * 1000) /* value in milliseconds - 20 seconds */ 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_citypedef struct ia64_fptr { 2562306a36Sopenharmony_ci unsigned long fp; 2662306a36Sopenharmony_ci unsigned long gp; 2762306a36Sopenharmony_ci} ia64_fptr_t; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_citypedef union cmcv_reg_u { 3062306a36Sopenharmony_ci u64 cmcv_regval; 3162306a36Sopenharmony_ci struct { 3262306a36Sopenharmony_ci u64 cmcr_vector : 8; 3362306a36Sopenharmony_ci u64 cmcr_reserved1 : 4; 3462306a36Sopenharmony_ci u64 cmcr_ignored1 : 1; 3562306a36Sopenharmony_ci u64 cmcr_reserved2 : 3; 3662306a36Sopenharmony_ci u64 cmcr_mask : 1; 3762306a36Sopenharmony_ci u64 cmcr_ignored2 : 47; 3862306a36Sopenharmony_ci } cmcv_reg_s; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci} cmcv_reg_t; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define cmcv_mask cmcv_reg_s.cmcr_mask 4362306a36Sopenharmony_ci#define cmcv_vector cmcv_reg_s.cmcr_vector 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cienum { 4662306a36Sopenharmony_ci IA64_MCA_RENDEZ_CHECKIN_NOTDONE = 0x0, 4762306a36Sopenharmony_ci IA64_MCA_RENDEZ_CHECKIN_DONE = 0x1, 4862306a36Sopenharmony_ci IA64_MCA_RENDEZ_CHECKIN_INIT = 0x2, 4962306a36Sopenharmony_ci IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA = 0x3, 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* Information maintained by the MC infrastructure */ 5362306a36Sopenharmony_citypedef struct ia64_mc_info_s { 5462306a36Sopenharmony_ci u64 imi_mca_handler; 5562306a36Sopenharmony_ci size_t imi_mca_handler_size; 5662306a36Sopenharmony_ci u64 imi_monarch_init_handler; 5762306a36Sopenharmony_ci size_t imi_monarch_init_handler_size; 5862306a36Sopenharmony_ci u64 imi_slave_init_handler; 5962306a36Sopenharmony_ci size_t imi_slave_init_handler_size; 6062306a36Sopenharmony_ci u8 imi_rendez_checkin[NR_CPUS]; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci} ia64_mc_info_t; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/* Handover state from SAL to OS and vice versa, for both MCA and INIT events. 6562306a36Sopenharmony_ci * Besides the handover state, it also contains some saved registers from the 6662306a36Sopenharmony_ci * time of the event. 6762306a36Sopenharmony_ci * Note: mca_asm.S depends on the precise layout of this structure. 6862306a36Sopenharmony_ci */ 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistruct ia64_sal_os_state { 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci /* SAL to OS */ 7362306a36Sopenharmony_ci unsigned long os_gp; /* GP of the os registered with the SAL, physical */ 7462306a36Sopenharmony_ci unsigned long pal_proc; /* PAL_PROC entry point, physical */ 7562306a36Sopenharmony_ci unsigned long sal_proc; /* SAL_PROC entry point, physical */ 7662306a36Sopenharmony_ci unsigned long rv_rc; /* MCA - Rendezvous state, INIT - reason code */ 7762306a36Sopenharmony_ci unsigned long proc_state_param; /* from R18 */ 7862306a36Sopenharmony_ci unsigned long monarch; /* 1 for a monarch event, 0 for a slave */ 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci /* common */ 8162306a36Sopenharmony_ci unsigned long sal_ra; /* Return address in SAL, physical */ 8262306a36Sopenharmony_ci unsigned long sal_gp; /* GP of the SAL - physical */ 8362306a36Sopenharmony_ci struct pal_min_state_area *pal_min_state; /* from R17. physical in asm, virtual in C */ 8462306a36Sopenharmony_ci /* Previous values of IA64_KR(CURRENT) and IA64_KR(CURRENT_STACK). 8562306a36Sopenharmony_ci * Note: if the MCA/INIT recovery code wants to resume to a new context 8662306a36Sopenharmony_ci * then it must change these values to reflect the new kernel stack. 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_ci unsigned long prev_IA64_KR_CURRENT; /* previous value of IA64_KR(CURRENT) */ 8962306a36Sopenharmony_ci unsigned long prev_IA64_KR_CURRENT_STACK; 9062306a36Sopenharmony_ci struct task_struct *prev_task; /* previous task, NULL if it is not useful */ 9162306a36Sopenharmony_ci /* Some interrupt registers are not saved in minstate, pt_regs or 9262306a36Sopenharmony_ci * switch_stack. Because MCA/INIT can occur when interrupts are 9362306a36Sopenharmony_ci * disabled, we need to save the additional interrupt registers over 9462306a36Sopenharmony_ci * MCA/INIT and resume. 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_ci unsigned long isr; 9762306a36Sopenharmony_ci unsigned long ifa; 9862306a36Sopenharmony_ci unsigned long itir; 9962306a36Sopenharmony_ci unsigned long iipa; 10062306a36Sopenharmony_ci unsigned long iim; 10162306a36Sopenharmony_ci unsigned long iha; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci /* OS to SAL */ 10462306a36Sopenharmony_ci unsigned long os_status; /* OS status to SAL, enum below */ 10562306a36Sopenharmony_ci unsigned long context; /* 0 if return to same context 10662306a36Sopenharmony_ci 1 if return to new context */ 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci /* I-resources */ 10962306a36Sopenharmony_ci unsigned long iip; 11062306a36Sopenharmony_ci unsigned long ipsr; 11162306a36Sopenharmony_ci unsigned long ifs; 11262306a36Sopenharmony_ci}; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cienum { 11562306a36Sopenharmony_ci IA64_MCA_CORRECTED = 0x0, /* Error has been corrected by OS_MCA */ 11662306a36Sopenharmony_ci IA64_MCA_WARM_BOOT = -1, /* Warm boot of the system need from SAL */ 11762306a36Sopenharmony_ci IA64_MCA_COLD_BOOT = -2, /* Cold boot of the system need from SAL */ 11862306a36Sopenharmony_ci IA64_MCA_HALT = -3 /* System to be halted by SAL */ 11962306a36Sopenharmony_ci}; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cienum { 12262306a36Sopenharmony_ci IA64_INIT_RESUME = 0x0, /* Resume after return from INIT */ 12362306a36Sopenharmony_ci IA64_INIT_WARM_BOOT = -1, /* Warm boot of the system need from SAL */ 12462306a36Sopenharmony_ci}; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cienum { 12762306a36Sopenharmony_ci IA64_MCA_SAME_CONTEXT = 0x0, /* SAL to return to same context */ 12862306a36Sopenharmony_ci IA64_MCA_NEW_CONTEXT = -1 /* SAL to return to new context */ 12962306a36Sopenharmony_ci}; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci/* Per-CPU MCA state that is too big for normal per-CPU variables. */ 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistruct ia64_mca_cpu { 13462306a36Sopenharmony_ci u64 mca_stack[KERNEL_STACK_SIZE/8]; 13562306a36Sopenharmony_ci u64 init_stack[KERNEL_STACK_SIZE/8]; 13662306a36Sopenharmony_ci}; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci/* Array of physical addresses of each CPU's MCA area. */ 13962306a36Sopenharmony_ciextern unsigned long __per_cpu_mca[NR_CPUS]; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ciextern int cpe_vector; 14262306a36Sopenharmony_ciextern int ia64_cpe_irq; 14362306a36Sopenharmony_ciextern void ia64_mca_init(void); 14462306a36Sopenharmony_ciextern void ia64_mca_irq_init(void); 14562306a36Sopenharmony_ciextern void ia64_mca_cpu_init(void *); 14662306a36Sopenharmony_ciextern void ia64_os_mca_dispatch(void); 14762306a36Sopenharmony_ciextern void ia64_os_mca_dispatch_end(void); 14862306a36Sopenharmony_ciextern void ia64_mca_ucmc_handler(struct pt_regs *, struct ia64_sal_os_state *); 14962306a36Sopenharmony_ciextern void ia64_init_handler(struct pt_regs *, 15062306a36Sopenharmony_ci struct switch_stack *, 15162306a36Sopenharmony_ci struct ia64_sal_os_state *); 15262306a36Sopenharmony_ciextern void ia64_os_init_on_kdump(void); 15362306a36Sopenharmony_ciextern void ia64_monarch_init_handler(void); 15462306a36Sopenharmony_ciextern void ia64_slave_init_handler(void); 15562306a36Sopenharmony_ciextern void ia64_mca_cmc_vector_setup(void); 15662306a36Sopenharmony_ciextern int ia64_reg_MCA_extension(int (*fn)(void *, struct ia64_sal_os_state *)); 15762306a36Sopenharmony_ciextern void ia64_unreg_MCA_extension(void); 15862306a36Sopenharmony_ciextern unsigned long ia64_get_rnat(unsigned long *); 15962306a36Sopenharmony_ciextern void ia64_set_psr_mc(void); 16062306a36Sopenharmony_ciextern void ia64_mca_printk(const char * fmt, ...) 16162306a36Sopenharmony_ci __attribute__ ((format (printf, 1, 2))); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistruct ia64_mca_notify_die { 16462306a36Sopenharmony_ci struct ia64_sal_os_state *sos; 16562306a36Sopenharmony_ci int *monarch_cpu; 16662306a36Sopenharmony_ci int *data; 16762306a36Sopenharmony_ci}; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ciDECLARE_PER_CPU(u64, ia64_mca_pal_base); 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci#else /* __ASSEMBLY__ */ 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci#define IA64_MCA_CORRECTED 0x0 /* Error has been corrected by OS_MCA */ 17462306a36Sopenharmony_ci#define IA64_MCA_WARM_BOOT -1 /* Warm boot of the system need from SAL */ 17562306a36Sopenharmony_ci#define IA64_MCA_COLD_BOOT -2 /* Cold boot of the system need from SAL */ 17662306a36Sopenharmony_ci#define IA64_MCA_HALT -3 /* System to be halted by SAL */ 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci#define IA64_INIT_RESUME 0x0 /* Resume after return from INIT */ 17962306a36Sopenharmony_ci#define IA64_INIT_WARM_BOOT -1 /* Warm boot of the system need from SAL */ 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci#define IA64_MCA_SAME_CONTEXT 0x0 /* SAL to return to same context */ 18262306a36Sopenharmony_ci#define IA64_MCA_NEW_CONTEXT -1 /* SAL to return to new context */ 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 18562306a36Sopenharmony_ci#endif /* _ASM_IA64_MCA_H */ 186