xref: /rk3399_rockchip-uboot/arch/powerpc/cpu/mpc83xx/traps.c (revision 0819450fdd1160462f7a67af055618029857e204)
1a47a12beSStefan Roese /*
2a47a12beSStefan Roese  * (C) Copyright 2000
3a47a12beSStefan Roese  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4a47a12beSStefan Roese  *
5a47a12beSStefan Roese  * Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
6a47a12beSStefan Roese  *
7*1a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
8a47a12beSStefan Roese  */
9a47a12beSStefan Roese 
10a47a12beSStefan Roese /*
11a47a12beSStefan Roese  * This file handles the architecture-dependent parts of hardware
12a47a12beSStefan Roese  * exceptions
13a47a12beSStefan Roese  */
14a47a12beSStefan Roese 
15a47a12beSStefan Roese #include <common.h>
16a47a12beSStefan Roese #include <command.h>
17a47a12beSStefan Roese #include <kgdb.h>
18a47a12beSStefan Roese #include <asm/processor.h>
19a47a12beSStefan Roese #include <asm/mpc8349_pci.h>
20a47a12beSStefan Roese 
21a47a12beSStefan Roese DECLARE_GLOBAL_DATA_PTR;
22a47a12beSStefan Roese 
23a47a12beSStefan Roese /* Returns 0 if exception not found and fixup otherwise.  */
24a47a12beSStefan Roese extern unsigned long search_exception_table(unsigned long);
25a47a12beSStefan Roese 
26a47a12beSStefan Roese #define END_OF_MEM	(gd->bd->bi_memstart + gd->bd->bi_memsize)
27a47a12beSStefan Roese 
28a47a12beSStefan Roese /*
29a47a12beSStefan Roese  * Trap & Exception support
30a47a12beSStefan Roese  */
31a47a12beSStefan Roese 
print_backtrace(unsigned long * sp)3220051f2aSKim Phillips static void print_backtrace(unsigned long *sp)
33a47a12beSStefan Roese {
34a47a12beSStefan Roese 	int cnt = 0;
35a47a12beSStefan Roese 	unsigned long i;
36a47a12beSStefan Roese 
37a47a12beSStefan Roese 	puts ("Call backtrace: ");
38a47a12beSStefan Roese 	while (sp) {
39a47a12beSStefan Roese 		if ((uint)sp > END_OF_MEM)
40a47a12beSStefan Roese 			break;
41a47a12beSStefan Roese 
42a47a12beSStefan Roese 		i = sp[1];
43a47a12beSStefan Roese 		if (cnt++ % 7 == 0)
44a47a12beSStefan Roese 			putc ('\n');
45a47a12beSStefan Roese 		printf("%08lX ", i);
46a47a12beSStefan Roese 		if (cnt > 32) break;
47a47a12beSStefan Roese 		sp = (unsigned long *)*sp;
48a47a12beSStefan Roese 	}
49a47a12beSStefan Roese 	putc ('\n');
50a47a12beSStefan Roese }
51a47a12beSStefan Roese 
show_regs(struct pt_regs * regs)52a47a12beSStefan Roese void show_regs(struct pt_regs *regs)
53a47a12beSStefan Roese {
54a47a12beSStefan Roese 	int i;
55a47a12beSStefan Roese 
56a47a12beSStefan Roese 	printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
57a47a12beSStefan Roese 	       regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
58a47a12beSStefan Roese 	printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
59a47a12beSStefan Roese 	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
60a47a12beSStefan Roese 	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
61a47a12beSStefan Roese 	       regs->msr&MSR_IR ? 1 : 0,
62a47a12beSStefan Roese 	       regs->msr&MSR_DR ? 1 : 0);
63a47a12beSStefan Roese 
64a47a12beSStefan Roese 	putc ('\n');
65a47a12beSStefan Roese 	for (i = 0;  i < 32;  i++) {
66a47a12beSStefan Roese 		if ((i % 8) == 0) {
67a47a12beSStefan Roese 			printf("GPR%02d: ", i);
68a47a12beSStefan Roese 		}
69a47a12beSStefan Roese 
70a47a12beSStefan Roese 		printf("%08lX ", regs->gpr[i]);
71a47a12beSStefan Roese 		if ((i % 8) == 7) {
72a47a12beSStefan Roese 			putc ('\n');
73a47a12beSStefan Roese 		}
74a47a12beSStefan Roese 	}
75a47a12beSStefan Roese }
76a47a12beSStefan Roese 
77a47a12beSStefan Roese 
_exception(int signr,struct pt_regs * regs)7820051f2aSKim Phillips static void _exception(int signr, struct pt_regs *regs)
79a47a12beSStefan Roese {
80a47a12beSStefan Roese 	show_regs(regs);
81a47a12beSStefan Roese 	print_backtrace((unsigned long *)regs->gpr[1]);
82a47a12beSStefan Roese 	panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
83a47a12beSStefan Roese }
84a47a12beSStefan Roese 
85a47a12beSStefan Roese #ifdef CONFIG_PCI
dump_pci(void)86a47a12beSStefan Roese void dump_pci (void)
87a47a12beSStefan Roese {
88a47a12beSStefan Roese /*
89a47a12beSStefan Roese 	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
90a47a12beSStefan Roese 	printf ("PCI: err status %x err mask %x err ctrl %x\n",
91a47a12beSStefan Roese 		le32_to_cpu (immap->im_pci.pci_esr),
92a47a12beSStefan Roese 		le32_to_cpu (immap->im_pci.pci_emr),
93a47a12beSStefan Roese 		le32_to_cpu (immap->im_pci.pci_ecr));
94a47a12beSStefan Roese 	printf ("     error address %x error data %x ctrl %x\n",
95a47a12beSStefan Roese 		le32_to_cpu (immap->im_pci.pci_eacr),
96a47a12beSStefan Roese 		le32_to_cpu (immap->im_pci.pci_edcr),
97a47a12beSStefan Roese 		le32_to_cpu (immap->im_pci.pci_eccr));
98a47a12beSStefan Roese */
99a47a12beSStefan Roese }
100a47a12beSStefan Roese #endif
101a47a12beSStefan Roese 
MachineCheckException(struct pt_regs * regs)10220051f2aSKim Phillips void MachineCheckException(struct pt_regs *regs)
103a47a12beSStefan Roese {
104a47a12beSStefan Roese 	unsigned long fixup;
105a47a12beSStefan Roese 
106a47a12beSStefan Roese 	/* Probing PCI using config cycles cause this exception
107a47a12beSStefan Roese 	 * when a device is not present.  Catch it and return to
108a47a12beSStefan Roese 	 * the PCI exception handler.
109a47a12beSStefan Roese 	 */
110a47a12beSStefan Roese #ifdef CONFIG_PCI
111a47a12beSStefan Roese #if 0
112a47a12beSStefan Roese 	volatile immap_t *immap  = (immap_t *)CONFIG_SYS_IMMR;
113a47a12beSStefan Roese #ifdef DEBUG
114a47a12beSStefan Roese 	dump_pci();
115a47a12beSStefan Roese #endif
116a47a12beSStefan Roese 	/* clear the error in the error status register */
117a47a12beSStefan Roese 	if(immap->im_pci.pci_esr & cpu_to_le32(PCI_ERROR_PCI_NO_RSP)) {
118a47a12beSStefan Roese 		immap->im_pci.pci_esr = cpu_to_le32(PCI_ERROR_PCI_NO_RSP);
119a47a12beSStefan Roese 		return;
120a47a12beSStefan Roese 	}
121a47a12beSStefan Roese #endif
122a47a12beSStefan Roese #endif /* CONFIG_PCI */
123a47a12beSStefan Roese 	if ((fixup = search_exception_table(regs->nip)) != 0) {
124a47a12beSStefan Roese 		regs->nip = fixup;
125a47a12beSStefan Roese 		return;
126a47a12beSStefan Roese 	}
127a47a12beSStefan Roese 
128a47a12beSStefan Roese #if defined(CONFIG_CMD_KGDB)
129a47a12beSStefan Roese 	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
130a47a12beSStefan Roese 		return;
131a47a12beSStefan Roese #endif
132a47a12beSStefan Roese 
133a47a12beSStefan Roese 	puts ("Machine check in kernel mode.\n"
134a47a12beSStefan Roese 		"Caused by (from msr): ");
135a47a12beSStefan Roese 	printf("regs %p ",regs);
136a47a12beSStefan Roese 	switch( regs->msr & 0x000F0000) {
137a47a12beSStefan Roese 	case (0x80000000>>12):
138a47a12beSStefan Roese 		puts ("Machine check signal - probably due to mm fault\n"
139a47a12beSStefan Roese 			"with mmu off\n");
140a47a12beSStefan Roese 		break;
141a47a12beSStefan Roese 	case (0x80000000>>13):
142a47a12beSStefan Roese 		puts ("Transfer error ack signal\n");
143a47a12beSStefan Roese 		break;
144a47a12beSStefan Roese 	case (0x80000000>>14):
145a47a12beSStefan Roese 		puts ("Data parity signal\n");
146a47a12beSStefan Roese 		break;
147a47a12beSStefan Roese 	case (0x80000000>>15):
148a47a12beSStefan Roese 		puts ("Address parity signal\n");
149a47a12beSStefan Roese 		break;
150a47a12beSStefan Roese 	default:
151a47a12beSStefan Roese 		puts ("Unknown values in msr\n");
152a47a12beSStefan Roese 	}
153a47a12beSStefan Roese 	show_regs(regs);
154a47a12beSStefan Roese 	print_backtrace((unsigned long *)regs->gpr[1]);
155a47a12beSStefan Roese #ifdef CONFIG_PCI
156a47a12beSStefan Roese 	dump_pci();
157a47a12beSStefan Roese #endif
158a47a12beSStefan Roese 	panic("machine check");
159a47a12beSStefan Roese }
160a47a12beSStefan Roese 
AlignmentException(struct pt_regs * regs)16120051f2aSKim Phillips void AlignmentException(struct pt_regs *regs)
162a47a12beSStefan Roese {
163a47a12beSStefan Roese #if defined(CONFIG_CMD_KGDB)
164a47a12beSStefan Roese 	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
165a47a12beSStefan Roese 		return;
166a47a12beSStefan Roese #endif
167a47a12beSStefan Roese 	show_regs(regs);
168a47a12beSStefan Roese 	print_backtrace((unsigned long *)regs->gpr[1]);
169a47a12beSStefan Roese 	panic("Alignment Exception");
170a47a12beSStefan Roese }
171a47a12beSStefan Roese 
ProgramCheckException(struct pt_regs * regs)17220051f2aSKim Phillips void ProgramCheckException(struct pt_regs *regs)
173a47a12beSStefan Roese {
174a47a12beSStefan Roese #if defined(CONFIG_CMD_KGDB)
175a47a12beSStefan Roese 	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
176a47a12beSStefan Roese 		return;
177a47a12beSStefan Roese #endif
178a47a12beSStefan Roese 	show_regs(regs);
179a47a12beSStefan Roese 	print_backtrace((unsigned long *)regs->gpr[1]);
180a47a12beSStefan Roese 	panic("Program Check Exception");
181a47a12beSStefan Roese }
182a47a12beSStefan Roese 
SoftEmuException(struct pt_regs * regs)18320051f2aSKim Phillips void SoftEmuException(struct pt_regs *regs)
184a47a12beSStefan Roese {
185a47a12beSStefan Roese #if defined(CONFIG_CMD_KGDB)
186a47a12beSStefan Roese 	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
187a47a12beSStefan Roese 		return;
188a47a12beSStefan Roese #endif
189a47a12beSStefan Roese 	show_regs(regs);
190a47a12beSStefan Roese 	print_backtrace((unsigned long *)regs->gpr[1]);
191a47a12beSStefan Roese 	panic("Software Emulation Exception");
192a47a12beSStefan Roese }
193a47a12beSStefan Roese 
194a47a12beSStefan Roese 
UnknownException(struct pt_regs * regs)19520051f2aSKim Phillips void UnknownException(struct pt_regs *regs)
196a47a12beSStefan Roese {
197a47a12beSStefan Roese #if defined(CONFIG_CMD_KGDB)
198a47a12beSStefan Roese 	if (debugger_exception_handler && (*debugger_exception_handler)(regs))
199a47a12beSStefan Roese 		return;
200a47a12beSStefan Roese #endif
201a47a12beSStefan Roese 	printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
202a47a12beSStefan Roese 	       regs->nip, regs->msr, regs->trap);
203a47a12beSStefan Roese 	_exception(0, regs);
204a47a12beSStefan Roese }
205a47a12beSStefan Roese 
206a47a12beSStefan Roese #if defined(CONFIG_CMD_BEDBUG)
207a47a12beSStefan Roese extern void do_bedbug_breakpoint(struct pt_regs *);
208a47a12beSStefan Roese #endif
209a47a12beSStefan Roese 
DebugException(struct pt_regs * regs)21020051f2aSKim Phillips void DebugException(struct pt_regs *regs)
211a47a12beSStefan Roese {
212a47a12beSStefan Roese 	printf("Debugger trap at @ %lx\n", regs->nip );
213a47a12beSStefan Roese 	show_regs(regs);
214a47a12beSStefan Roese #if defined(CONFIG_CMD_BEDBUG)
215a47a12beSStefan Roese 	do_bedbug_breakpoint( regs );
216a47a12beSStefan Roese #endif
217a47a12beSStefan Roese }
218