162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Machine check exception header file. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2013 IBM Corporation 662306a36Sopenharmony_ci * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef __ASM_PPC64_MCE_H__ 1062306a36Sopenharmony_ci#define __ASM_PPC64_MCE_H__ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/bitops.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cienum MCE_Version { 1562306a36Sopenharmony_ci MCE_V1 = 1, 1662306a36Sopenharmony_ci}; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cienum MCE_Severity { 1962306a36Sopenharmony_ci MCE_SEV_NO_ERROR = 0, 2062306a36Sopenharmony_ci MCE_SEV_WARNING = 1, 2162306a36Sopenharmony_ci MCE_SEV_SEVERE = 2, 2262306a36Sopenharmony_ci MCE_SEV_FATAL = 3, 2362306a36Sopenharmony_ci}; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cienum MCE_Disposition { 2662306a36Sopenharmony_ci MCE_DISPOSITION_RECOVERED = 0, 2762306a36Sopenharmony_ci MCE_DISPOSITION_NOT_RECOVERED = 1, 2862306a36Sopenharmony_ci}; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cienum MCE_Initiator { 3162306a36Sopenharmony_ci MCE_INITIATOR_UNKNOWN = 0, 3262306a36Sopenharmony_ci MCE_INITIATOR_CPU = 1, 3362306a36Sopenharmony_ci MCE_INITIATOR_PCI = 2, 3462306a36Sopenharmony_ci MCE_INITIATOR_ISA = 3, 3562306a36Sopenharmony_ci MCE_INITIATOR_MEMORY= 4, 3662306a36Sopenharmony_ci MCE_INITIATOR_POWERMGM = 5, 3762306a36Sopenharmony_ci}; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cienum MCE_ErrorType { 4062306a36Sopenharmony_ci MCE_ERROR_TYPE_UNKNOWN = 0, 4162306a36Sopenharmony_ci MCE_ERROR_TYPE_UE = 1, 4262306a36Sopenharmony_ci MCE_ERROR_TYPE_SLB = 2, 4362306a36Sopenharmony_ci MCE_ERROR_TYPE_ERAT = 3, 4462306a36Sopenharmony_ci MCE_ERROR_TYPE_TLB = 4, 4562306a36Sopenharmony_ci MCE_ERROR_TYPE_USER = 5, 4662306a36Sopenharmony_ci MCE_ERROR_TYPE_RA = 6, 4762306a36Sopenharmony_ci MCE_ERROR_TYPE_LINK = 7, 4862306a36Sopenharmony_ci MCE_ERROR_TYPE_DCACHE = 8, 4962306a36Sopenharmony_ci MCE_ERROR_TYPE_ICACHE = 9, 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cienum MCE_ErrorClass { 5362306a36Sopenharmony_ci MCE_ECLASS_UNKNOWN = 0, 5462306a36Sopenharmony_ci MCE_ECLASS_HARDWARE, 5562306a36Sopenharmony_ci MCE_ECLASS_HARD_INDETERMINATE, 5662306a36Sopenharmony_ci MCE_ECLASS_SOFTWARE, 5762306a36Sopenharmony_ci MCE_ECLASS_SOFT_INDETERMINATE, 5862306a36Sopenharmony_ci}; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cienum MCE_UeErrorType { 6162306a36Sopenharmony_ci MCE_UE_ERROR_INDETERMINATE = 0, 6262306a36Sopenharmony_ci MCE_UE_ERROR_IFETCH = 1, 6362306a36Sopenharmony_ci MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH = 2, 6462306a36Sopenharmony_ci MCE_UE_ERROR_LOAD_STORE = 3, 6562306a36Sopenharmony_ci MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE = 4, 6662306a36Sopenharmony_ci}; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cienum MCE_SlbErrorType { 6962306a36Sopenharmony_ci MCE_SLB_ERROR_INDETERMINATE = 0, 7062306a36Sopenharmony_ci MCE_SLB_ERROR_PARITY = 1, 7162306a36Sopenharmony_ci MCE_SLB_ERROR_MULTIHIT = 2, 7262306a36Sopenharmony_ci}; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cienum MCE_EratErrorType { 7562306a36Sopenharmony_ci MCE_ERAT_ERROR_INDETERMINATE = 0, 7662306a36Sopenharmony_ci MCE_ERAT_ERROR_PARITY = 1, 7762306a36Sopenharmony_ci MCE_ERAT_ERROR_MULTIHIT = 2, 7862306a36Sopenharmony_ci}; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cienum MCE_TlbErrorType { 8162306a36Sopenharmony_ci MCE_TLB_ERROR_INDETERMINATE = 0, 8262306a36Sopenharmony_ci MCE_TLB_ERROR_PARITY = 1, 8362306a36Sopenharmony_ci MCE_TLB_ERROR_MULTIHIT = 2, 8462306a36Sopenharmony_ci}; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cienum MCE_UserErrorType { 8762306a36Sopenharmony_ci MCE_USER_ERROR_INDETERMINATE = 0, 8862306a36Sopenharmony_ci MCE_USER_ERROR_TLBIE = 1, 8962306a36Sopenharmony_ci MCE_USER_ERROR_SCV = 2, 9062306a36Sopenharmony_ci}; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cienum MCE_RaErrorType { 9362306a36Sopenharmony_ci MCE_RA_ERROR_INDETERMINATE = 0, 9462306a36Sopenharmony_ci MCE_RA_ERROR_IFETCH = 1, 9562306a36Sopenharmony_ci MCE_RA_ERROR_IFETCH_FOREIGN = 2, 9662306a36Sopenharmony_ci MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH = 3, 9762306a36Sopenharmony_ci MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH_FOREIGN = 4, 9862306a36Sopenharmony_ci MCE_RA_ERROR_LOAD = 5, 9962306a36Sopenharmony_ci MCE_RA_ERROR_STORE = 6, 10062306a36Sopenharmony_ci MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE = 7, 10162306a36Sopenharmony_ci MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE_FOREIGN = 8, 10262306a36Sopenharmony_ci MCE_RA_ERROR_LOAD_STORE_FOREIGN = 9, 10362306a36Sopenharmony_ci}; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cienum MCE_LinkErrorType { 10662306a36Sopenharmony_ci MCE_LINK_ERROR_INDETERMINATE = 0, 10762306a36Sopenharmony_ci MCE_LINK_ERROR_IFETCH_TIMEOUT = 1, 10862306a36Sopenharmony_ci MCE_LINK_ERROR_PAGE_TABLE_WALK_IFETCH_TIMEOUT = 2, 10962306a36Sopenharmony_ci MCE_LINK_ERROR_LOAD_TIMEOUT = 3, 11062306a36Sopenharmony_ci MCE_LINK_ERROR_STORE_TIMEOUT = 4, 11162306a36Sopenharmony_ci MCE_LINK_ERROR_PAGE_TABLE_WALK_LOAD_STORE_TIMEOUT = 5, 11262306a36Sopenharmony_ci}; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistruct machine_check_event { 11562306a36Sopenharmony_ci enum MCE_Version version:8; 11662306a36Sopenharmony_ci u8 in_use; 11762306a36Sopenharmony_ci enum MCE_Severity severity:8; 11862306a36Sopenharmony_ci enum MCE_Initiator initiator:8; 11962306a36Sopenharmony_ci enum MCE_ErrorType error_type:8; 12062306a36Sopenharmony_ci enum MCE_ErrorClass error_class:8; 12162306a36Sopenharmony_ci enum MCE_Disposition disposition:8; 12262306a36Sopenharmony_ci bool sync_error; 12362306a36Sopenharmony_ci u16 cpu; 12462306a36Sopenharmony_ci u64 gpr3; 12562306a36Sopenharmony_ci u64 srr0; 12662306a36Sopenharmony_ci u64 srr1; 12762306a36Sopenharmony_ci union { 12862306a36Sopenharmony_ci struct { 12962306a36Sopenharmony_ci enum MCE_UeErrorType ue_error_type:8; 13062306a36Sopenharmony_ci u8 effective_address_provided; 13162306a36Sopenharmony_ci u8 physical_address_provided; 13262306a36Sopenharmony_ci u8 ignore_event; 13362306a36Sopenharmony_ci u8 reserved_1[4]; 13462306a36Sopenharmony_ci u64 effective_address; 13562306a36Sopenharmony_ci u64 physical_address; 13662306a36Sopenharmony_ci u8 reserved_2[8]; 13762306a36Sopenharmony_ci } ue_error; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci struct { 14062306a36Sopenharmony_ci enum MCE_SlbErrorType slb_error_type:8; 14162306a36Sopenharmony_ci u8 effective_address_provided; 14262306a36Sopenharmony_ci u8 reserved_1[6]; 14362306a36Sopenharmony_ci u64 effective_address; 14462306a36Sopenharmony_ci u8 reserved_2[16]; 14562306a36Sopenharmony_ci } slb_error; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci struct { 14862306a36Sopenharmony_ci enum MCE_EratErrorType erat_error_type:8; 14962306a36Sopenharmony_ci u8 effective_address_provided; 15062306a36Sopenharmony_ci u8 reserved_1[6]; 15162306a36Sopenharmony_ci u64 effective_address; 15262306a36Sopenharmony_ci u8 reserved_2[16]; 15362306a36Sopenharmony_ci } erat_error; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci struct { 15662306a36Sopenharmony_ci enum MCE_TlbErrorType tlb_error_type:8; 15762306a36Sopenharmony_ci u8 effective_address_provided; 15862306a36Sopenharmony_ci u8 reserved_1[6]; 15962306a36Sopenharmony_ci u64 effective_address; 16062306a36Sopenharmony_ci u8 reserved_2[16]; 16162306a36Sopenharmony_ci } tlb_error; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci struct { 16462306a36Sopenharmony_ci enum MCE_UserErrorType user_error_type:8; 16562306a36Sopenharmony_ci u8 effective_address_provided; 16662306a36Sopenharmony_ci u8 reserved_1[6]; 16762306a36Sopenharmony_ci u64 effective_address; 16862306a36Sopenharmony_ci u8 reserved_2[16]; 16962306a36Sopenharmony_ci } user_error; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci struct { 17262306a36Sopenharmony_ci enum MCE_RaErrorType ra_error_type:8; 17362306a36Sopenharmony_ci u8 effective_address_provided; 17462306a36Sopenharmony_ci u8 reserved_1[6]; 17562306a36Sopenharmony_ci u64 effective_address; 17662306a36Sopenharmony_ci u8 reserved_2[16]; 17762306a36Sopenharmony_ci } ra_error; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci struct { 18062306a36Sopenharmony_ci enum MCE_LinkErrorType link_error_type:8; 18162306a36Sopenharmony_ci u8 effective_address_provided; 18262306a36Sopenharmony_ci u8 reserved_1[6]; 18362306a36Sopenharmony_ci u64 effective_address; 18462306a36Sopenharmony_ci u8 reserved_2[16]; 18562306a36Sopenharmony_ci } link_error; 18662306a36Sopenharmony_ci } u; 18762306a36Sopenharmony_ci}; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistruct mce_error_info { 19062306a36Sopenharmony_ci enum MCE_ErrorType error_type:8; 19162306a36Sopenharmony_ci union { 19262306a36Sopenharmony_ci enum MCE_UeErrorType ue_error_type:8; 19362306a36Sopenharmony_ci enum MCE_SlbErrorType slb_error_type:8; 19462306a36Sopenharmony_ci enum MCE_EratErrorType erat_error_type:8; 19562306a36Sopenharmony_ci enum MCE_TlbErrorType tlb_error_type:8; 19662306a36Sopenharmony_ci enum MCE_UserErrorType user_error_type:8; 19762306a36Sopenharmony_ci enum MCE_RaErrorType ra_error_type:8; 19862306a36Sopenharmony_ci enum MCE_LinkErrorType link_error_type:8; 19962306a36Sopenharmony_ci } u; 20062306a36Sopenharmony_ci enum MCE_Severity severity:8; 20162306a36Sopenharmony_ci enum MCE_Initiator initiator:8; 20262306a36Sopenharmony_ci enum MCE_ErrorClass error_class:8; 20362306a36Sopenharmony_ci bool sync_error; 20462306a36Sopenharmony_ci bool ignore_event; 20562306a36Sopenharmony_ci}; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci#define MAX_MC_EVT 10 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_cistruct mce_info { 21062306a36Sopenharmony_ci int mce_nest_count; 21162306a36Sopenharmony_ci struct machine_check_event mce_event[MAX_MC_EVT]; 21262306a36Sopenharmony_ci /* Queue for delayed MCE events. */ 21362306a36Sopenharmony_ci int mce_queue_count; 21462306a36Sopenharmony_ci struct machine_check_event mce_event_queue[MAX_MC_EVT]; 21562306a36Sopenharmony_ci /* Queue for delayed MCE UE events. */ 21662306a36Sopenharmony_ci int mce_ue_count; 21762306a36Sopenharmony_ci struct machine_check_event mce_ue_event_queue[MAX_MC_EVT]; 21862306a36Sopenharmony_ci}; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci/* Release flags for get_mce_event() */ 22162306a36Sopenharmony_ci#define MCE_EVENT_RELEASE true 22262306a36Sopenharmony_ci#define MCE_EVENT_DONTRELEASE false 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cistruct pt_regs; 22562306a36Sopenharmony_cistruct notifier_block; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ciextern void save_mce_event(struct pt_regs *regs, long handled, 22862306a36Sopenharmony_ci struct mce_error_info *mce_err, uint64_t nip, 22962306a36Sopenharmony_ci uint64_t addr, uint64_t phys_addr); 23062306a36Sopenharmony_ciextern int get_mce_event(struct machine_check_event *mce, bool release); 23162306a36Sopenharmony_ciextern void release_mce_event(void); 23262306a36Sopenharmony_ciextern void machine_check_queue_event(void); 23362306a36Sopenharmony_ciextern void machine_check_print_event_info(struct machine_check_event *evt, 23462306a36Sopenharmony_ci bool user_mode, bool in_guest); 23562306a36Sopenharmony_ciunsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr); 23662306a36Sopenharmony_ciextern void mce_common_process_ue(struct pt_regs *regs, 23762306a36Sopenharmony_ci struct mce_error_info *mce_err); 23862306a36Sopenharmony_civoid mce_irq_work_queue(void); 23962306a36Sopenharmony_ciint mce_register_notifier(struct notifier_block *nb); 24062306a36Sopenharmony_ciint mce_unregister_notifier(struct notifier_block *nb); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64 24362306a36Sopenharmony_civoid mce_run_irq_context_handlers(void); 24462306a36Sopenharmony_ci#else 24562306a36Sopenharmony_cistatic inline void mce_run_irq_context_handlers(void) { }; 24662306a36Sopenharmony_ci#endif /* CONFIG_PPC_BOOK3S_64 */ 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64 24962306a36Sopenharmony_civoid set_mce_pending_irq_work(void); 25062306a36Sopenharmony_civoid clear_mce_pending_irq_work(void); 25162306a36Sopenharmony_ci#endif /* CONFIG_PPC_BOOK3S_64 */ 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64 25462306a36Sopenharmony_civoid flush_and_reload_slb(void); 25562306a36Sopenharmony_civoid flush_erat(void); 25662306a36Sopenharmony_cilong __machine_check_early_realmode_p7(struct pt_regs *regs); 25762306a36Sopenharmony_cilong __machine_check_early_realmode_p8(struct pt_regs *regs); 25862306a36Sopenharmony_cilong __machine_check_early_realmode_p9(struct pt_regs *regs); 25962306a36Sopenharmony_cilong __machine_check_early_realmode_p10(struct pt_regs *regs); 26062306a36Sopenharmony_ci#endif /* CONFIG_PPC_BOOK3S_64 */ 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64 26362306a36Sopenharmony_civoid mce_init(void); 26462306a36Sopenharmony_ci#else 26562306a36Sopenharmony_cistatic inline void mce_init(void) { }; 26662306a36Sopenharmony_ci#endif /* CONFIG_PPC_BOOK3S_64 */ 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci#endif /* __ASM_PPC64_MCE_H__ */ 269