xref: /openbmc/linux/arch/sparc/kernel/entry.h (revision c13aca79ff3c4af5fd31a5b2743a90eba6e36a26)
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