blob: 61be5bb90caa37788a26b9ba92069cd3c798dfab [file] [log] [blame]
Wolfgang Denk8e7b7032006-03-12 02:55:22 +01001/* Copyright (C) 2003 Analog Devices, Inc. All Rights Reserved.
Wolfgang Denk6cb142f2006-03-12 02:12:27 +01002 *
3 * This file is subject to the terms and conditions of the GNU General Public
Wolfgang Denk8e7b7032006-03-12 02:55:22 +01004 * License.
Wolfgang Denk6cb142f2006-03-12 02:12:27 +01005 *
Wolfgang Denk8e7b7032006-03-12 02:55:22 +01006 * Blackfin BF533/2.6 support : LG Soft India
Wolfgang Denk6cb142f2006-03-12 02:12:27 +01007 */
8
9
10/* Include an exception handler to invoke the CPLB manager
11 */
12
13#include <asm-blackfin/linkage.h>
14#include <asm/cplb.h>
15#include <asm/entry.h>
16
17
18.text
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010019
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010020.globl _cplb_hdr;
21.type _cplb_hdr, STT_FUNC;
22.extern _cplb_mgr;
23.type _cplb_mgr, STT_FUNC;
24.extern __unknown_exception_occurred;
25.type __unknown_exception_occurred, STT_FUNC;
26.extern __cplb_miss_all_locked;
27.type __cplb_miss_all_locked, STT_FUNC;
28.extern __cplb_miss_without_replacement;
29.type __cplb_miss_without_replacement, STT_FUNC;
30.extern __cplb_protection_violation;
31.type __cplb_protection_violation, STT_FUNC;
32.extern panic_pv;
33
34.align 2;
35
36ENTRY(_cplb_hdr)
37 SSYNC;
38 [--SP] = ( R7:0, P5:0 );
39 [--SP] = ASTAT;
40 [--SP] = SEQSTAT;
41 [--SP] = I0;
42 [--SP] = I1;
43 [--SP] = I2;
44 [--SP] = I3;
45 [--SP] = LT0;
46 [--SP] = LB0;
47 [--SP] = LC0;
48 [--SP] = LT1;
49 [--SP] = LB1;
50 [--SP] = LC1;
51 R2 = SEQSTAT;
52
53 /*Mask the contents of SEQSTAT and leave only EXCAUSE in R2*/
54 R2 <<= 26;
55 R2 >>= 26;
56
57 R1 = 0x23; /* Data access CPLB protection violation */
58 CC = R2 == R1;
59 IF !CC JUMP not_data_write;
60 R0 = 2; /* is a write to data space*/
61 JUMP is_icplb_miss;
62
63not_data_write:
64 R1 = 0x2C; /* CPLB miss on an instruction fetch */
65 CC = R2 == R1;
66 R0 = 0; /* is_data_miss == False*/
67 IF CC JUMP is_icplb_miss;
68
69 R1 = 0x26;
70 CC = R2 == R1;
71 IF !CC JUMP unknown;
72
73 R0 = 1; /* is_data_miss == True*/
74
75is_icplb_miss:
76
77#if ( defined (CONFIG_BLKFIN_CACHE) || defined (CONFIG_BLKFIN_DCACHE))
78#if ( defined (CONFIG_BLKFIN_CACHE) && !defined (CONFIG_BLKFIN_DCACHE))
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010079 R1 = CPLB_ENABLE_ICACHE;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010080#endif
81#if ( !defined (CONFIG_BLKFIN_CACHE) && defined (CONFIG_BLKFIN_DCACHE))
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010082 R1 = CPLB_ENABLE_DCACHE;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010083#endif
84#if ( defined (CONFIG_BLKFIN_CACHE) && defined (CONFIG_BLKFIN_DCACHE))
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010085 R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010086#endif
87#else
88 R1 = 0;
89#endif
90
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010091 [--SP] = RETS;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010092 CALL _cplb_mgr;
93 RETS = [SP++];
94 CC = R0 == 0;
95 IF !CC JUMP not_replaced;
96 LC1 = [SP++];
97 LB1 = [SP++];
98 LT1 = [SP++];
99 LC0 = [SP++];
100 LB0 = [SP++];
101 LT0 = [SP++];
102 I3 = [SP++];
103 I2 = [SP++];
104 I1 = [SP++];
105 I0 = [SP++];
106 SEQSTAT = [SP++];
107 ASTAT = [SP++];
108 ( R7:0, P5:0 ) = [SP++];
109 RTS;
110
111unknown:
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100112 [--SP] = RETS;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100113 CALL __unknown_exception_occurred;
114 RETS = [SP++];
115 JUMP unknown;
116not_replaced:
117 CC = R0 == CPLB_NO_UNLOCKED;
118 IF !CC JUMP next_check;
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100119 [--SP] = RETS;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100120 CALL __cplb_miss_all_locked;
121 RETS = [SP++];
122next_check:
123 CC = R0 == CPLB_NO_ADDR_MATCH;
124 IF !CC JUMP next_check2;
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100125 [--SP] = RETS;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100126 CALL __cplb_miss_without_replacement;
127 RETS = [SP++];
128 JUMP not_replaced;
129next_check2:
130 CC = R0 == CPLB_PROT_VIOL;
131 IF !CC JUMP strange_return_from_cplb_mgr;
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100132 [--SP] = RETS;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100133 CALL __cplb_protection_violation;
134 RETS = [SP++];
135 JUMP not_replaced;
136strange_return_from_cplb_mgr:
137 IDLE;
138 CSYNC;
139 JUMP strange_return_from_cplb_mgr;
140
141/************************************
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100142 * Diagnostic exception handlers
143 */
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100144
145__cplb_miss_all_locked:
146 sp += -12;
147 R0 = CPLB_NO_UNLOCKED;
148 call panic_bfin;
149 SP += 12;
150 RTS;
151
152 __cplb_miss_without_replacement:
153 sp += -12;
154 R0 = CPLB_NO_ADDR_MATCH;
155 call panic_bfin;
156 SP += 12;
157 RTS;
158
159__cplb_protection_violation:
160 sp += -12;
161 R0 = CPLB_PROT_VIOL;
162 call panic_bfin;
163 SP += 12;
164 RTS;
165
166__unknown_exception_occurred:
167
168 /* This function is invoked by the default exception
169 * handler, if it does not recognise the kind of
170 * exception that has occurred. In other words, the
171 * default handler only handles some of the system's
172 * exception types, and it does not expect any others
173 * to occur. If your application is going to be using
174 * other kinds of exceptions, you must replace the
175 * default handler with your own, that handles all the
176 * exceptions you will use.
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100177 *
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100178 * Since there's nothing we can do, we just loop here
179 * at what we hope is a suitably informative label.
180 */
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100181
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100182 IDLE;
183do_not_know_what_to_do:
184 CSYNC;
185 JUMP __unknown_exception_occurred;
186
187 RTS;
188.__unknown_exception_occurred.end:
189.global __unknown_exception_occurred;
190.type __unknown_exception_occurred, STT_FUNC;
191
192panic_bfin:
193 RTS;