1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2a88b5ba8SSam Ravnborg #ifndef _ENTRY_H 3a88b5ba8SSam Ravnborg #define _ENTRY_H 4a88b5ba8SSam Ravnborg 5a88b5ba8SSam Ravnborg #include <linux/kernel.h> 6a88b5ba8SSam Ravnborg #include <linux/types.h> 7a88b5ba8SSam Ravnborg #include <linux/init.h> 8a88b5ba8SSam Ravnborg 981265fd9SSam Ravnborg /* irq */ 102e74a74fSSam Ravnborg void handler_irq(int irq, struct pt_regs *regs); 1181265fd9SSam Ravnborg 128d74e32aSSam Ravnborg #ifdef CONFIG_SPARC32 138d74e32aSSam Ravnborg /* traps */ 142e74a74fSSam Ravnborg void do_hw_interrupt(struct pt_regs *regs, unsigned long type); 152e74a74fSSam Ravnborg void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, 168d74e32aSSam Ravnborg unsigned long npc, unsigned long psr); 178d74e32aSSam Ravnborg 182e74a74fSSam Ravnborg void do_priv_instruction(struct pt_regs *regs, unsigned long pc, 198d74e32aSSam Ravnborg unsigned long npc, unsigned long psr); 202e74a74fSSam Ravnborg void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, 218d74e32aSSam Ravnborg unsigned long npc, unsigned long psr); 222e74a74fSSam Ravnborg void do_fpd_trap(struct pt_regs *regs, unsigned long pc, 238d74e32aSSam Ravnborg unsigned long npc, unsigned long psr); 242e74a74fSSam Ravnborg void do_fpe_trap(struct pt_regs *regs, unsigned long pc, 258d74e32aSSam Ravnborg unsigned long npc, unsigned long psr); 262e74a74fSSam Ravnborg void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, 278d74e32aSSam Ravnborg unsigned long npc, unsigned long psr); 282e74a74fSSam Ravnborg void handle_watchpoint(struct pt_regs *regs, unsigned long pc, 298d74e32aSSam Ravnborg unsigned long npc, unsigned long psr); 302e74a74fSSam Ravnborg void handle_reg_access(struct pt_regs *regs, unsigned long pc, 318d74e32aSSam Ravnborg unsigned long npc, unsigned long psr); 322e74a74fSSam Ravnborg void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, 332e74a74fSSam Ravnborg unsigned long npc, unsigned long psr); 342e74a74fSSam Ravnborg void handle_cp_exception(struct pt_regs *regs, unsigned long pc, 358d74e32aSSam Ravnborg unsigned long npc, unsigned long psr); 368d74e32aSSam Ravnborg 378d74e32aSSam Ravnborg 388d74e32aSSam Ravnborg 398d74e32aSSam Ravnborg /* entry.S */ 402e74a74fSSam Ravnborg void fpsave(unsigned long *fpregs, unsigned long *fsr, 418d74e32aSSam Ravnborg void *fpqueue, unsigned long *fpqdepth); 422e74a74fSSam Ravnborg void fpload(unsigned long *fpregs, unsigned long *fsr); 438d74e32aSSam Ravnborg 448d74e32aSSam Ravnborg #else /* CONFIG_SPARC32 */ 450b64120cSDavid S. Miller 460b64120cSDavid S. Miller #include <asm/trap_block.h> 470b64120cSDavid S. Miller 48ef7c4d46SDavid S. Miller struct popc_3insn_patch_entry { 49ef7c4d46SDavid S. Miller unsigned int addr; 50ef7c4d46SDavid S. Miller unsigned int insns[3]; 51ef7c4d46SDavid S. Miller }; 52ef7c4d46SDavid S. Miller extern struct popc_3insn_patch_entry __popc_3insn_patch, 53ef7c4d46SDavid S. Miller __popc_3insn_patch_end; 54ef7c4d46SDavid S. Miller 5556d205ccSDavid S. Miller struct popc_6insn_patch_entry { 5656d205ccSDavid S. Miller unsigned int addr; 5756d205ccSDavid S. Miller unsigned int insns[6]; 5856d205ccSDavid S. Miller }; 5956d205ccSDavid S. Miller extern struct popc_6insn_patch_entry __popc_6insn_patch, 6056d205ccSDavid S. Miller __popc_6insn_patch_end; 6156d205ccSDavid S. Miller 62e9b9eb59SDavid S. Miller struct pause_patch_entry { 63e9b9eb59SDavid S. Miller unsigned int addr; 64e9b9eb59SDavid S. Miller unsigned int insns[3]; 65e9b9eb59SDavid S. Miller }; 66187818cdSDavid S. Miller extern struct pause_patch_entry __pause_3insn_patch, 67187818cdSDavid S. Miller __pause_3insn_patch_end; 68e9b9eb59SDavid S. Miller 692e74a74fSSam Ravnborg void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, 700b64120cSDavid S. Miller struct sun4v_1insn_patch_entry *); 712e74a74fSSam Ravnborg void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, 720b64120cSDavid S. Miller struct sun4v_2insn_patch_entry *); 73494e5b6fSKhalid Aziz void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *, 74494e5b6fSKhalid Aziz struct sun4v_2insn_patch_entry *); 75a88b5ba8SSam Ravnborg extern unsigned int dcache_parity_tl1_occurred; 76a88b5ba8SSam Ravnborg extern unsigned int icache_parity_tl1_occurred; 77a88b5ba8SSam Ravnborg 782e74a74fSSam Ravnborg asmlinkage void sparc_breakpoint(struct pt_regs *regs); 792e74a74fSSam Ravnborg void timer_interrupt(int irq, struct pt_regs *regs); 80a88b5ba8SSam Ravnborg 812e74a74fSSam Ravnborg void do_notify_resume(struct pt_regs *regs, 82a88b5ba8SSam Ravnborg unsigned long orig_i0, 83a88b5ba8SSam Ravnborg unsigned long thread_info_flags); 84a88b5ba8SSam Ravnborg 852e74a74fSSam Ravnborg asmlinkage int syscall_trace_enter(struct pt_regs *regs); 862e74a74fSSam Ravnborg asmlinkage void syscall_trace_leave(struct pt_regs *regs); 87a88b5ba8SSam Ravnborg 882e74a74fSSam Ravnborg void bad_trap_tl1(struct pt_regs *regs, long lvl); 89a88b5ba8SSam Ravnborg 902e74a74fSSam Ravnborg void do_fpieee(struct pt_regs *regs); 912e74a74fSSam Ravnborg void do_fpother(struct pt_regs *regs); 922e74a74fSSam Ravnborg void do_tof(struct pt_regs *regs); 932e74a74fSSam Ravnborg void do_div0(struct pt_regs *regs); 942e74a74fSSam Ravnborg void do_illegal_instruction(struct pt_regs *regs); 952e74a74fSSam Ravnborg void mem_address_unaligned(struct pt_regs *regs, 96a88b5ba8SSam Ravnborg unsigned long sfar, 97a88b5ba8SSam Ravnborg unsigned long sfsr); 982e74a74fSSam Ravnborg void sun4v_do_mna(struct pt_regs *regs, 99a88b5ba8SSam Ravnborg unsigned long addr, 100a88b5ba8SSam Ravnborg unsigned long type_ctx); 1012e74a74fSSam Ravnborg void do_privop(struct pt_regs *regs); 1022e74a74fSSam Ravnborg void do_privact(struct pt_regs *regs); 1032e74a74fSSam Ravnborg void do_cee(struct pt_regs *regs); 1042e74a74fSSam Ravnborg void do_div0_tl1(struct pt_regs *regs); 1052e74a74fSSam Ravnborg void do_fpieee_tl1(struct pt_regs *regs); 1062e74a74fSSam Ravnborg void do_fpother_tl1(struct pt_regs *regs); 1072e74a74fSSam Ravnborg void do_ill_tl1(struct pt_regs *regs); 1082e74a74fSSam Ravnborg void do_irq_tl1(struct pt_regs *regs); 1092e74a74fSSam Ravnborg void do_lddfmna_tl1(struct pt_regs *regs); 1102e74a74fSSam Ravnborg void do_stdfmna_tl1(struct pt_regs *regs); 1112e74a74fSSam Ravnborg void do_paw(struct pt_regs *regs); 1122e74a74fSSam Ravnborg void do_paw_tl1(struct pt_regs *regs); 1132e74a74fSSam Ravnborg void do_vaw(struct pt_regs *regs); 1142e74a74fSSam Ravnborg void do_vaw_tl1(struct pt_regs *regs); 1152e74a74fSSam Ravnborg void do_tof_tl1(struct pt_regs *regs); 1162e74a74fSSam Ravnborg void do_getpsr(struct pt_regs *regs); 117a88b5ba8SSam Ravnborg 1182e74a74fSSam Ravnborg void spitfire_insn_access_exception(struct pt_regs *regs, 119a88b5ba8SSam Ravnborg unsigned long sfsr, 120a88b5ba8SSam Ravnborg unsigned long sfar); 1212e74a74fSSam Ravnborg void spitfire_insn_access_exception_tl1(struct pt_regs *regs, 122a88b5ba8SSam Ravnborg unsigned long sfsr, 123a88b5ba8SSam Ravnborg unsigned long sfar); 1242e74a74fSSam Ravnborg void spitfire_data_access_exception(struct pt_regs *regs, 125a88b5ba8SSam Ravnborg unsigned long sfsr, 126a88b5ba8SSam Ravnborg unsigned long sfar); 1272e74a74fSSam Ravnborg void spitfire_data_access_exception_tl1(struct pt_regs *regs, 128a88b5ba8SSam Ravnborg unsigned long sfsr, 129a88b5ba8SSam Ravnborg unsigned long sfar); 1302e74a74fSSam Ravnborg void spitfire_access_error(struct pt_regs *regs, 131a88b5ba8SSam Ravnborg unsigned long status_encoded, 132a88b5ba8SSam Ravnborg unsigned long afar); 133a88b5ba8SSam Ravnborg 1342e74a74fSSam Ravnborg void cheetah_fecc_handler(struct pt_regs *regs, 135a88b5ba8SSam Ravnborg unsigned long afsr, 136a88b5ba8SSam Ravnborg unsigned long afar); 1372e74a74fSSam Ravnborg void cheetah_cee_handler(struct pt_regs *regs, 138a88b5ba8SSam Ravnborg unsigned long afsr, 139a88b5ba8SSam Ravnborg unsigned long afar); 1402e74a74fSSam Ravnborg void cheetah_deferred_handler(struct pt_regs *regs, 141a88b5ba8SSam Ravnborg unsigned long afsr, 142a88b5ba8SSam Ravnborg unsigned long afar); 1432e74a74fSSam Ravnborg void cheetah_plus_parity_error(int type, struct pt_regs *regs); 144a88b5ba8SSam Ravnborg 1452e74a74fSSam Ravnborg void sun4v_insn_access_exception(struct pt_regs *regs, 146a88b5ba8SSam Ravnborg unsigned long addr, 147a88b5ba8SSam Ravnborg unsigned long type_ctx); 1482e74a74fSSam Ravnborg void sun4v_insn_access_exception_tl1(struct pt_regs *regs, 149a88b5ba8SSam Ravnborg unsigned long addr, 150a88b5ba8SSam Ravnborg unsigned long type_ctx); 1512e74a74fSSam Ravnborg void sun4v_data_access_exception(struct pt_regs *regs, 152a88b5ba8SSam Ravnborg unsigned long addr, 153a88b5ba8SSam Ravnborg unsigned long type_ctx); 1542e74a74fSSam Ravnborg void sun4v_data_access_exception_tl1(struct pt_regs *regs, 155a88b5ba8SSam Ravnborg unsigned long addr, 156a88b5ba8SSam Ravnborg unsigned long type_ctx); 1572e74a74fSSam Ravnborg void sun4v_resum_error(struct pt_regs *regs, 158a88b5ba8SSam Ravnborg unsigned long offset); 1592e74a74fSSam Ravnborg void sun4v_resum_overflow(struct pt_regs *regs); 1602e74a74fSSam Ravnborg void sun4v_nonresum_error(struct pt_regs *regs, 161a88b5ba8SSam Ravnborg unsigned long offset); 1622e74a74fSSam Ravnborg void sun4v_nonresum_overflow(struct pt_regs *regs); 163*75037500SKhalid Aziz void sun4v_mem_corrupt_detect_precise(struct pt_regs *regs, 164*75037500SKhalid Aziz unsigned long addr, 165*75037500SKhalid Aziz unsigned long context); 166a88b5ba8SSam Ravnborg 167a88b5ba8SSam Ravnborg extern unsigned long sun4v_err_itlb_vaddr; 168a88b5ba8SSam Ravnborg extern unsigned long sun4v_err_itlb_ctx; 169a88b5ba8SSam Ravnborg extern unsigned long sun4v_err_itlb_pte; 170a88b5ba8SSam Ravnborg extern unsigned long sun4v_err_itlb_error; 171a88b5ba8SSam Ravnborg 1722e74a74fSSam Ravnborg void sun4v_itlb_error_report(struct pt_regs *regs, int tl); 173a88b5ba8SSam Ravnborg 174a88b5ba8SSam Ravnborg extern unsigned long sun4v_err_dtlb_vaddr; 175a88b5ba8SSam Ravnborg extern unsigned long sun4v_err_dtlb_ctx; 176a88b5ba8SSam Ravnborg extern unsigned long sun4v_err_dtlb_pte; 177a88b5ba8SSam Ravnborg extern unsigned long sun4v_err_dtlb_error; 178a88b5ba8SSam Ravnborg 1792e74a74fSSam Ravnborg void sun4v_dtlb_error_report(struct pt_regs *regs, int tl); 1802e74a74fSSam Ravnborg void hypervisor_tlbop_error(unsigned long err, 181a88b5ba8SSam Ravnborg unsigned long op); 1822e74a74fSSam Ravnborg void hypervisor_tlbop_error_xcall(unsigned long err, 183a88b5ba8SSam Ravnborg unsigned long op); 184a88b5ba8SSam Ravnborg 185a88b5ba8SSam Ravnborg /* WARNING: The error trap handlers in assembly know the precise 186a88b5ba8SSam Ravnborg * layout of the following structure. 187a88b5ba8SSam Ravnborg * 188a88b5ba8SSam Ravnborg * C-level handlers in traps.c use this information to log the 189a88b5ba8SSam Ravnborg * error and then determine how to recover (if possible). 190a88b5ba8SSam Ravnborg */ 191a88b5ba8SSam Ravnborg struct cheetah_err_info { 192a88b5ba8SSam Ravnborg /*0x00*/u64 afsr; 193a88b5ba8SSam Ravnborg /*0x08*/u64 afar; 194a88b5ba8SSam Ravnborg 195a88b5ba8SSam Ravnborg /* D-cache state */ 196a88b5ba8SSam Ravnborg /*0x10*/u64 dcache_data[4]; /* The actual data */ 197a88b5ba8SSam Ravnborg /*0x30*/u64 dcache_index; /* D-cache index */ 198a88b5ba8SSam Ravnborg /*0x38*/u64 dcache_tag; /* D-cache tag/valid */ 199a88b5ba8SSam Ravnborg /*0x40*/u64 dcache_utag; /* D-cache microtag */ 200a88b5ba8SSam Ravnborg /*0x48*/u64 dcache_stag; /* D-cache snooptag */ 201a88b5ba8SSam Ravnborg 202a88b5ba8SSam Ravnborg /* I-cache state */ 203a88b5ba8SSam Ravnborg /*0x50*/u64 icache_data[8]; /* The actual insns + predecode */ 204a88b5ba8SSam Ravnborg /*0x90*/u64 icache_index; /* I-cache index */ 205a88b5ba8SSam Ravnborg /*0x98*/u64 icache_tag; /* I-cache phys tag */ 206a88b5ba8SSam Ravnborg /*0xa0*/u64 icache_utag; /* I-cache microtag */ 207a88b5ba8SSam Ravnborg /*0xa8*/u64 icache_stag; /* I-cache snooptag */ 208a88b5ba8SSam Ravnborg /*0xb0*/u64 icache_upper; /* I-cache upper-tag */ 209a88b5ba8SSam Ravnborg /*0xb8*/u64 icache_lower; /* I-cache lower-tag */ 210a88b5ba8SSam Ravnborg 211a88b5ba8SSam Ravnborg /* E-cache state */ 212a88b5ba8SSam Ravnborg /*0xc0*/u64 ecache_data[4]; /* 32 bytes from staging registers */ 213a88b5ba8SSam Ravnborg /*0xe0*/u64 ecache_index; /* E-cache index */ 214a88b5ba8SSam Ravnborg /*0xe8*/u64 ecache_tag; /* E-cache tag/state */ 215a88b5ba8SSam Ravnborg 216a88b5ba8SSam Ravnborg /*0xf0*/u64 __pad[32 - 30]; 217a88b5ba8SSam Ravnborg }; 218a88b5ba8SSam Ravnborg #define CHAFSR_INVALID ((u64)-1L) 219a88b5ba8SSam Ravnborg 220a88b5ba8SSam Ravnborg /* This is allocated at boot time based upon the largest hardware 221a88b5ba8SSam Ravnborg * cpu ID in the system. We allocate two entries per cpu, one for 222a88b5ba8SSam Ravnborg * TL==0 logging and one for TL >= 1 logging. 223a88b5ba8SSam Ravnborg */ 224a88b5ba8SSam Ravnborg extern struct cheetah_err_info *cheetah_error_log; 225a88b5ba8SSam Ravnborg 226a88b5ba8SSam Ravnborg /* UPA nodes send interrupt packet to UltraSparc with first data reg 227a88b5ba8SSam Ravnborg * value low 5 (7 on Starfire) bits holding the IRQ identifier being 228a88b5ba8SSam Ravnborg * delivered. We must translate this into a non-vector IRQ so we can 229a88b5ba8SSam Ravnborg * set the softint on this cpu. 230a88b5ba8SSam Ravnborg * 231a88b5ba8SSam Ravnborg * To make processing these packets efficient and race free we use 232a88b5ba8SSam Ravnborg * an array of irq buckets below. The interrupt vector handler in 233a88b5ba8SSam Ravnborg * entry.S feeds incoming packets into per-cpu pil-indexed lists. 234a88b5ba8SSam Ravnborg * 235a88b5ba8SSam Ravnborg * If you make changes to ino_bucket, please update hand coded assembler 236a88b5ba8SSam Ravnborg * of the vectored interrupt trap handler(s) in entry.S and sun4v_ivec.S 237a88b5ba8SSam Ravnborg */ 238a88b5ba8SSam Ravnborg struct ino_bucket { 239a88b5ba8SSam Ravnborg /*0x00*/unsigned long __irq_chain_pa; 240a88b5ba8SSam Ravnborg 241fe41493fSSam Ravnborg /* Interrupt number assigned to this INO. */ 242fe41493fSSam Ravnborg /*0x08*/unsigned int __irq; 243a88b5ba8SSam Ravnborg /*0x0c*/unsigned int __pad; 244a88b5ba8SSam Ravnborg }; 245a88b5ba8SSam Ravnborg 246a88b5ba8SSam Ravnborg extern struct ino_bucket *ivector_table; 247a88b5ba8SSam Ravnborg extern unsigned long ivector_table_pa; 248a88b5ba8SSam Ravnborg 2492e74a74fSSam Ravnborg void init_irqwork_curcpu(void); 2502e74a74fSSam Ravnborg void sun4v_register_mondo_queues(int this_cpu); 251a88b5ba8SSam Ravnborg 2528d74e32aSSam Ravnborg #endif /* CONFIG_SPARC32 */ 253a88b5ba8SSam Ravnborg #endif /* _ENTRY_H */ 254