OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [or32/] [kernel/] [head.S] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 xianfeng
/*
2
 *  linux/arch/or32/kernel/head.S
3
 *
4
 *  or32 version
5
 *    author(s): Matjaz Breskvar (phoenix@bsemi.com)
6
 *
7
 *  changes:
8
 *  18. 11. 2003: Matjaz Breskvar (phoenix@bsemi.com)
9
 *    initial port to or32 architecture
10
 *  06. 12. 2003: Matjaz Breskvar (phoenix@bsemi.com)
11
 *    major changes in handling exceptions
12
 *    physical addresses used only by code in head.S
13
 *    cleand exception handlers and moved them to entry.S
14
 */
15
 
16
#include 
17
#include 
18
#include 
19
#include 
20
#include 
21
#include 
22
#include 
23
#include 
24
#include 
25
#include 
26
#include 
27
#include 
28
 
29
/* some defines to ease or32 assembly programming */
30
#include "or32_funcs.S"
31
 
32
#define DRAM_END (PAGE_OFFSET+CONFIG_OR32_MEMORY_SIZE)
33
 
34
#if defined(CONFIG_OR32_ICACHE_ENABLED) && defined(CONFIG_OR32_DCACHE_ENABLED)
35
#  define EXCEPTION_SR  (SPR_SR_DME | SPR_SR_IME | SPR_SR_DCE | SPR_SR_ICE | SPR_SR_SM)
36
#elif defined(CONFIG_OR32_ICACHE_ENABLED) && !defined(CONFIG_OR32_DCACHE_ENABLED)
37
#  define EXCEPTION_SR  (SPR_SR_DME | SPR_SR_IME |              SPR_SR_ICE | SPR_SR_SM)
38
#elif defined(CONFIG_OR32_DCACHE_ENABLED) && !defined(CONFIG_OR32_ICACHE_ENABLED)
39
#  define EXCEPTION_SR  (SPR_SR_DME | SPR_SR_IME | SPR_SR_DCE              | SPR_SR_SM)
40
#else
41
#  define EXCEPTION_SR  (SPR_SR_DME | SPR_SR_IME | SPR_SR_SM)
42
#endif
43
 
44
#undef  CONFIG_DMMU_WORKS
45
#define CONFIG_DMMU_WORKS 1
46
#undef  CONFIG_IMMU_WORKS
47
#define CONFIG_IMMU_WORKS 1
48
 
49
 
50
#undef  CONFIG_OR32_EXCEPTION_REGENERATE
51
//#define       CONFIG_OR32_EXCEPTION_REGENERATE 1
52
#undef  CONFIG_OR32_EXCEPTION_DEBUG
53
//#define       CONFIG_OR32_EXCEPTION_DEBUG 1
54
 
55
#undef  DEBUG_TLB_EXCEPTIONS
56
//#define       DEBUG_TLB_EXCEPTIONS 1
57
 
58
/* ============================================[ tmp store locations ]=== */
59
 
60
/*
61
 * workaround for passing next open ethernet tx buffer descriptor number
62
 * when used prior linux. for details look into drivers/net/open_eth.[ch]
63
 */
64
#define INIT_OETH_TX_NEXT               0x0
65
 
66
/*
67
 * inital configuration
68
 */
69
#define INIT_IC_ADDR                    0x4
70
#define INIT_DC_ADDR                    0x8
71
 
72
#define SF_DISABLED(reg,ADDR)           l.lwz   reg,ADDR(r0)    ;\
73
                                        l.sfeqi reg,0x0
74
 
75
#ifdef CONFIG_OR32_ICACHE_ENABLED
76
#  define INIT_CONFIG_ICACHE(reg)       l.ori   reg,r0,1        ;\
77
                                        l.sw    INIT_IC_ADDR(r0),reg
78
#else
79
#  define INIT_CONFIG_ICACHE(reg)       l.ori   reg,r0,0        ;\
80
                                        l.sw    INIT_IC_ADDR(r0),reg
81
#endif
82
 
83
#ifdef CONFIG_OR32_DCACHE_ENABLED
84
#  define INIT_CONFIG_DCACHE(reg)       l.ori   reg,r0,1        ;\
85
                                        l.sw    INIT_DC_ADDR(r0),reg
86
#else
87
#  define INIT_CONFIG_DCACHE(reg)       l.ori   reg,r0,0        ;\
88
                                        l.sw    INIT_DC_ADDR(r0),reg
89
#endif
90
 
91
/*
92
 * emergency_print temporary stores
93
 */
94
#define EMERGENCY_PRINT_STORE_GPR4      l.sw    0x20(r0),r4
95
#define EMERGENCY_PRINT_LOAD_GPR4       l.lwz   r4,0x20(r0)
96
 
97
#define EMERGENCY_PRINT_STORE_GPR5      l.sw    0x24(r0),r5
98
#define EMERGENCY_PRINT_LOAD_GPR5       l.lwz   r5,0x24(r0)
99
 
100
#define EMERGENCY_PRINT_STORE_GPR6      l.sw    0x28(r0),r6
101
#define EMERGENCY_PRINT_LOAD_GPR6       l.lwz   r6,0x28(r0)
102
 
103
#define EMERGENCY_PRINT_STORE_GPR7      l.sw    0x2c(r0),r7
104
#define EMERGENCY_PRINT_LOAD_GPR7       l.lwz   r7,0x2c(r0)
105
 
106
#define EMERGENCY_PRINT_STORE_GPR8      l.sw    0x30(r0),r8
107
#define EMERGENCY_PRINT_LOAD_GPR8       l.lwz   r8,0x30(r0)
108
 
109
#define EMERGENCY_PRINT_STORE_GPR9      l.sw    0x34(r0),r9
110
#define EMERGENCY_PRINT_LOAD_GPR9       l.lwz   r9,0x34(r0)
111
 
112
/*
113
 * EXCEPTION_DEBUG temporary stores
114
 */
115
#define EXCEPTION_DEBUG_STORE_GPR3      l.sw    0x40(r0),r3
116
#define EXCEPTION_DEBUG_LOAD_GPR3       l.lwz   r3,0x40(r0)
117
 
118
#define EXCEPTION_DEBUG_STORE_GPR4      l.sw    0x44(r0),r4
119
#define EXCEPTION_DEBUG_LOAD_GPR4       l.lwz   r4,0x44(r0)
120
 
121
#define EXCEPTION_DEBUG_STORE_GPR9      l.sw    0x48(r0),r9
122
#define EXCEPTION_DEBUG_LOAD_GPR9       l.lwz   r9,0x48(r0)
123
 
124
#define EXCEPTION_DEBUG_STORE_F_GPR9    l.sw    0x4c(r0),r9
125
#define EXCEPTION_DEBUG_LOAD_F_GPR9     l.lwz   r9,0x4c(r0)
126
 
127
/*
128
 * EXCEPTION_REGENERATE temporary stores
129
 */
130
#define E_REGEN_STORE_STATUS(reg)       l.sw    0x50(r0),reg
131
#define E_REGEN_LOAD_STATUS(reg)        l.lwz   reg,0x50(r0)
132
 
133
#define E_REGEN_STORE_GPR3              l.sw    0x54(r0),r3
134
#define E_REGEN_LOAD_GPR3               l.lwz   r3,0x54(r0)
135
 
136
#define E_REGEN_STORE_GPR4              l.sw    0x58(r0),r4
137
#define E_REGEN_LOAD_GPR4               l.lwz   r4,0x58(r0)
138
 
139
#define E_REGEN_STORE_GPR5              l.sw    0x5c(r0),r5
140
#define E_REGEN_LOAD_GPR5               l.lwz   r5,0x5c(r0)
141
 
142
#define E_REGEN_STORE_GPR6              l.sw    0x60(r0),r6
143
#define E_REGEN_LOAD_GPR6               l.lwz   r6,0x60(r0)
144
 
145
#define E_REGEN_STORE_GPR9              l.sw    0x14(r0),r9
146
#define E_REGEN_LOAD_GPR9               l.lwz   r9,0x14(r0)
147
 
148
 
149
/*
150
 * TLB miss handlers temorary stores
151
 */
152
#define EXCEPTION_STORE_GPR9            l.sw    0x10(r0),r9
153
#define EXCEPTION_LOAD_GPR9             l.lwz   r9,0x10(r0)
154
 
155
#define EXCEPTION_STORE_GPR2            l.sw    0x64(r0),r2
156
#define EXCEPTION_LOAD_GPR2             l.lwz   r2,0x64(r0)
157
 
158
#define EXCEPTION_STORE_GPR3            l.sw    0x68(r0),r3
159
#define EXCEPTION_LOAD_GPR3             l.lwz   r3,0x68(r0)
160
 
161
#define EXCEPTION_STORE_GPR4            l.sw    0x6c(r0),r4
162
#define EXCEPTION_LOAD_GPR4             l.lwz   r4,0x6c(r0)
163
 
164
#define EXCEPTION_STORE_GPR5            l.sw    0x70(r0),r5
165
#define EXCEPTION_LOAD_GPR5             l.lwz   r5,0x70(r0)
166
 
167
#define EXCEPTION_STORE_GPR6            l.sw    0x74(r0),r6
168
#define EXCEPTION_LOAD_GPR6             l.lwz   r6,0x74(r0)
169
 
170
 
171
/*
172
 * EXCEPTION_HANDLE temporary stores
173
 */
174
#define EXCEPTION_T_STORE_GPR31         l.sw    0x78(r0),r31
175
#define EXCEPTION_T_LOAD_GPR31(reg)     l.lwz   reg,0x78(r0)
176
 
177
#define EXCEPTION_T_STORE_GPR10         l.sw    0x7c(r0),r10
178
#define EXCEPTION_T_LOAD_GPR10(reg)     l.lwz   reg,0x7c(r0)
179
 
180
#define EXCEPTION_T_STORE_SP            l.sw    0x80(r0),r1
181
#define EXCEPTION_T_LOAD_SP(reg)        l.lwz   reg,0x80(r0)
182
 
183
/*
184
 * UNHANDLED_EXCEPTION temporary stores
185
 */
186
#define UNH_EXCEPTION_T_STORE_GPR31     l.sw    0x84(r0),r31
187
#define UNH_EXCEPTION_T_LOAD_GPR31(reg) l.lwz   reg,0x84(r0)
188
 
189
#define UNH_EXCEPTION_T_STORE_GPR2      l.sw    0x88(r0),r2
190
#define UNH_EXCEPTION_T_LOAD_GPR2(reg)  l.lwz   reg,0x88(r0)
191
 
192
#define UNH_EXCEPTION_T_STORE_SP        l.sw    0x8c(r0),r1
193
#define UNH_EXCEPTION_T_LOAD_SP(reg)    l.lwz   reg,0x8c(r0)
194
 
195
/* =========================================================[ macros ]=== */
196
 
197
 
198
#define LOAD_CURRENT_THREAD_INFO(reg,t1)                        \
199
        LOAD_SYMBOL_2_GPR(reg,_current_thread_info_set)         ;\
200
        tophys  (t1,reg)                                        ;\
201
        l.lwz   reg,0(t1)
202
 
203
#define GET_CURRENT_THREAD_INFO(reg,ksp)                        \
204
        l.srli  reg,ksp,PAGE_SHIFT                              ;\
205
        l.slli  reg,reg,PAGE_SHIFT
206
 
207
#define GET_CURRENT_PGD(reg,t1)                                 \
208
        LOAD_SYMBOL_2_GPR(reg,_current_pgd)                     ;\
209
        tophys  (t1,reg)                                        ;\
210
        l.lwz   reg,0(t1)
211
 
212
#if defined(CONFIG_OR32_EXCEPTION_DEBUG) && defined(CONFIG_OR32_EXCEPTION_REGENERATE)
213
#  define EXCEPTION_DEBUG                                       \
214
          EXCEPTION_DEBUG_STORE_GPR4                            ;\
215
          EXCEPTION_DEBUG_STORE_F_GPR9                          ;\
216
          l.jal _exception_debug                                ;\
217
          l.mfspr       r4,r0,SPR_PC                            ;\
218
          EXCEPTION_DEBUG_LOAD_GPR4                             ;\
219
          EXCEPTION_DEBUG_LOAD_F_GPR9
220
 
221
#  define EXCEPTION_DEBUG_VALUE(value)                          \
222
          EXCEPTION_DEBUG_STORE_GPR4                            ;\
223
          EXCEPTION_DEBUG_STORE_F_GPR9                          ;\
224
          l.jal _exception_debug                                ;\
225
          l.addi        r4,r0,value                             ;\
226
          EXCEPTION_DEBUG_LOAD_GPR4                             ;\
227
          EXCEPTION_DEBUG_LOAD_F_GPR9
228
 
229
#  define EXCEPTION_DEBUG_ER                                    \
230
          EXCEPTION_DEBUG_STORE_GPR4                            ;\
231
          EXCEPTION_DEBUG_STORE_F_GPR9                          ;\
232
          l.jal _exception_debug                                ;\
233
          l.mfspr       r4,r0,SPR_PC                            ;\
234
          l.jal _exception_regenerate                           ;\
235
          l.nop                                                 ;\
236
          EXCEPTION_DEBUG_LOAD_GPR4                             ;\
237
          EXCEPTION_DEBUG_LOAD_F_GPR9
238
 
239
#  define EXCEPTION_DEBUG_VALUE_ER(value)                       \
240
          EXCEPTION_DEBUG_STORE_GPR4                            ;\
241
          EXCEPTION_DEBUG_STORE_F_GPR9                          ;\
242
          l.jal _exception_debug                                ;\
243
          l.addi        r4,r0,value                             ;\
244
          l.jal _exception_regenerate                           ;\
245
          l.nop                                                 ;\
246
          EXCEPTION_DEBUG_LOAD_GPR4                             ;\
247
          EXCEPTION_DEBUG_LOAD_F_GPR9
248
#elif !defined(CONFIG_OR32_EXCEPTION_DEBUG) && defined(CONFIG_OR32_EXCEPTION_REGENERATE)
249
#  define EXCEPTION_DEBUG
250
#  define EXCEPTION_DEBUG_VALUE(value)
251
 
252
#  define EXCEPTION_DEBUG_ER                                    \
253
          EXCEPTION_DEBUG_STORE_GPR4                            ;\
254
          EXCEPTION_DEBUG_STORE_F_GPR9                          ;\
255
          l.jal    _exception_regenerate                        ;\
256
          l.nop                                                 ;\
257
          EXCEPTION_DEBUG_LOAD_GPR4                             ;\
258
          EXCEPTION_DEBUG_LOAD_F_GPR9
259
 
260
#  define EXCEPTION_DEBUG_VALUE_ER(value)                       \
261
          EXCEPTION_DEBUG_STORE_GPR4                            ;\
262
          EXCEPTION_DEBUG_STORE_F_GPR9                          ;\
263
          l.jal    _exception_regenerate                        ;\
264
          l.nop                                                 ;\
265
          EXCEPTION_DEBUG_LOAD_GPR4                             ;\
266
          EXCEPTION_DEBUG_LOAD_F_GPR9
267
#elif defined(CONFIG_OR32_EXCEPTION_DEBUG) && !defined(CONFIG_OR32_EXCEPTION_REGENERATE)
268
#  define EXCEPTION_DEBUG                                       \
269
          EXCEPTION_DEBUG_STORE_GPR4                            ;\
270
          EXCEPTION_DEBUG_STORE_F_GPR9                          ;\
271
          l.jal    _exception_debug                             ;\
272
          l.mfspr  r4,r0,SPR_PC                                 ;\
273
          EXCEPTION_DEBUG_LOAD_GPR4                             ;\
274
          EXCEPTION_DEBUG_LOAD_F_GPR9
275
#  define EXCEPTION_DEBUG_VALUE(value)                          \
276
          EXCEPTION_DEBUG_STORE_GPR4                            ;\
277
          EXCEPTION_DEBUG_STORE_F_GPR9                          ;\
278
          l.jal    _exception_debug                             ;\
279
          l.addi   r4,r0,value                                  ;\
280
          EXCEPTION_DEBUG_LOAD_GPR4                             ;\
281
          EXCEPTION_DEBUG_LOAD_F_GPR9
282
#  define EXCEPTION_DEBUG_ER                                    \
283
          EXCEPTION_DEBUG
284
#  define EXCEPTION_DEBUG_VALUE_ER(value)                       \
285
          EXCEPTION_DEBUG_VALUE(value)
286
#else
287
#  define EXCEPTION_DEBUG
288
#  define EXCEPTION_DEBUG_VALUE(value)
289
#  define EXCEPTION_DEBUG_ER
290
#  define EXCEPTION_DEBUG_VALUE_ER(value)
291
#endif
292
 
293
#  define EXCEPTION_DEBUG_VALUE_ER_ENABLED(value)               \
294
          EXCEPTION_DEBUG_STORE_GPR4                            ;\
295
          EXCEPTION_DEBUG_STORE_F_GPR9                          ;\
296
          l.jal _exception_debug                                ;\
297
          l.addi        r4,r0,value                             ;\
298
          l.jal _exception_regenerate                           ;\
299
          l.nop                                                 ;\
300
          EXCEPTION_DEBUG_LOAD_GPR4                             ;\
301
          EXCEPTION_DEBUG_LOAD_F_GPR9
302
 
303
#  define EXCEPTION_DEBUG_VALUE_ENABLED(value)                  \
304
          EXCEPTION_DEBUG_STORE_GPR4                            ;\
305
          EXCEPTION_DEBUG_STORE_F_GPR9                          ;\
306
          l.jal    _exception_debug                             ;\
307
          l.addi   r4,r0,value                                  ;\
308
          EXCEPTION_DEBUG_LOAD_GPR4                             ;\
309
          EXCEPTION_DEBUG_LOAD_F_GPR9
310
 
311
#ifdef DEBUG_TLB_EXCEPTIONS
312
#  define DEBUG_TLB_PROBE(value)                                \
313
          EXCEPTION_DEBUG_VALUE_ENABLED(value)
314
#else
315
#  define DEBUG_TLB_PROBE(value)
316
#endif
317
 
318
 
319
/*
320
 * DSCR: this is a common hook for handling exceptions. it will save
321
 *       the needed registers, set up stack and pointer to current
322
 *       then jump to the handler while enabling MMU
323
 *
324
 * PRMS: handler        - a function to jump to. it has to save the
325
 *                      remaining registers to kernel stack, call
326
 *                      appropriate arch-independant exception handler
327
 *                      and finaly jump to ret_from_except
328
 *
329
 * PREQ: unchanged state from the time exception happened
330
 *
331
 * POST: SAVED the following registers original value
332
 *             to the new created exception frame pointed to by r1
333
 *
334
 *       r1  - ksp      pointing to the new (exception) frame
335
 *       r4  - EEAR     exception EA
336
 *       r10 - current  pointing to current_thread_info struct
337
 *       r12 - syscall  0, since we didn't come from syscall
338
 *       r13 - temp     it actually contains new SR, not needed anymore
339
 *       r31 - handler  address of the handler we'll jump to
340
 *
341
 *       handler has to save remaining registers to the exception
342
 *       ksp frame *before* tainting them!
343
 *
344
 * NOTE: this function is not reentrant per se. reentrancy is guaranteed
345
 *       by processor disabling all exceptions/interrupts when exception
346
 *       accours.
347
 *
348
 * OPTM: no need to make it so wasteful to extract ksp when in user mode
349
 */
350
#define EXCEPTION_HANDLE(handler)                               \
351
        EXCEPTION_DEBUG                                         ;\
352
        EXCEPTION_T_STORE_GPR31                                 ;\
353
        EXCEPTION_T_STORE_GPR10                                 ;\
354
        EXCEPTION_T_STORE_SP                                    ;\
355
        l.mfspr r31,r0,SPR_ESR_BASE                             ;\
356
        l.andi  r31,r31,SPR_SR_SM                               ;\
357
        l.sfeqi r31,0                                           ;\
358
        l.bnf   2f /* kernel_mode */                            ;\
359
        l.nop                                                   ;\
360
1: /* user_mode:   */                                           ;\
361
        LOAD_SYMBOL_2_GPR(r1,_current_thread_info_set)          ;\
362
        tophys  (r31,r1)                                        ;\
363
        /* r10: current_thread_info  */                         ;\
364
        l.lwz   r10,0(r31)                                      ;\
365
        tophys  (r31,r10)                                       ;\
366
        l.lwz   r1,(TI_KSP)(r31)                                ;\
367
        /* fall through */                                      ;\
368
2: /* kernel_mode: */                                           ;\
369
        /* create new stack frame, save only needed gprs */     ;\
370
        /* r1: KSP, r10: current, r4: EEAR, r31: __pa(KSP) */   ;\
371
        /* r12: temp, syscall indicator, r13 temp */            ;\
372
        l.addi  r1,r1,-(INT_FRAME_SIZE)                         ;\
373
        /* r1 is KSP, r31 is __pa(KSP) */                       ;\
374
        tophys  (r31,r1)                                        ;\
375
        l.sw    GPR12(r31),r12                                  ;\
376
        l.mfspr r12,r0,SPR_EPCR_BASE                            ;\
377
        l.sw    PC(r31),r12                                     ;\
378
        l.mfspr r12,r0,SPR_ESR_BASE                             ;\
379
        l.sw    SR(r31),r12                                     ;\
380
        /* save r31 */                                          ;\
381
        EXCEPTION_T_LOAD_GPR31(r12)                             ;\
382
        l.sw    GPR31(r31),r12                                  ;\
383
        /* save r10 as was prior to exception */                ;\
384
        EXCEPTION_T_LOAD_GPR10(r12)                             ;\
385
        l.sw    GPR10(r31),r12                                  ;\
386
        /* save SP as was prior to exception */                 ;\
387
        EXCEPTION_T_LOAD_SP(r12)                                ;\
388
        l.sw    SP(r31),r12                                     ;\
389
        l.sw    GPR13(r31),r13                                  ;\
390
        /* save exception r4, set r4 = EA */                    ;\
391
        l.sw    GPR4(r31),r4                                    ;\
392
        l.mfspr r4,r0,SPR_EEAR_BASE                             ;\
393
        /* r12 == 1 if we come from syscall */                  ;\
394
        CLEAR_GPR(r12)                                          ;\
395
        /* ----- turn on MMU ----- */                           ;\
396
        l.ori   r31,r0,(EXCEPTION_SR)                           ;\
397
        l.mtspr r0,r31,SPR_ESR_BASE                             ;\
398
        /* r31: EA address of handler */                        ;\
399
        LOAD_SYMBOL_2_GPR(r31,handler)                          ;\
400
        l.mtspr r0,r31,SPR_EPCR_BASE                            ;\
401
        l.rfe
402
 
403
/*
404
 * this doesn't work
405
 *
406
 *
407
 * #ifdef CONFIG_JUMP_UPON_UNHANDLED_EXCEPTION
408
 * #define UNHANDLED_EXCEPTION(handler)                         \
409
 *      l.ori   r3,r0,0x1                                       ;\
410
 *      l.mtspr r0,r3,SPR_SR                                    ;\
411
 *      l.movhi r3,hi(0xf0000100)                               ;\
412
 *      l.ori   r3,r3,lo(0xf0000100)                            ;\
413
 *      l.jr    r3                                              ;\
414
 *      l.nop   1
415
 *
416
 * #endif
417
 */
418
 
419
/* DSCR: this is the same as EXCEPTION_HANDLE(), we are just
420
 *       a bit more carefull (if we have a SP or current pointer
421
 *       corruption) and set them up from 'current_set'
422
 *
423
 */
424
#define UNHANDLED_EXCEPTION(handler)                            \
425
        EXCEPTION_DEBUG                                         ;\
426
        EXCEPTION_T_STORE_GPR31                                 ;\
427
        EXCEPTION_T_STORE_GPR10                                 ;\
428
        EXCEPTION_T_STORE_SP                                    ;\
429
        /* temporary store r3, r9 into r1, r10 */               ;\
430
        l.addi  r1,r3,0x0                                       ;\
431
        l.addi  r10,r9,0x0                                      ;\
432
        /* the string referenced by r3 must be low enough */    ;\
433
        l.jal   _emergency_print                                ;\
434
        l.ori   r3,r0,lo(_string_unhandled_exception)           ;\
435
        l.mfspr r3,r0,SPR_PC                                    ;\
436
        l.jal   _emergency_print_nr                             ;\
437
        l.andi  r3,r3,0x1f00                                    ;\
438
        /* the string referenced by r3 must be low enough */    ;\
439
        l.jal   _emergency_print                                ;\
440
        l.ori   r3,r0,lo(_string_epc_prefix)                    ;\
441
        l.jal   _emergency_print_nr                             ;\
442
        l.mfspr r3,r0,SPR_EPCR_BASE                             ;\
443
        l.jal   _emergency_print                                ;\
444
        l.ori   r3,r0,lo(_string_nl)                            ;\
445
        /* end of printing */                                   ;\
446
        l.addi  r3,r1,0x0                                       ;\
447
        l.addi  r9,r10,0x0                                      ;\
448
        /* extract current, ksp from current_set */             ;\
449
        LOAD_SYMBOL_2_GPR(r1,_unhandled_stack_top)              ;\
450
        LOAD_SYMBOL_2_GPR(r10,_init_thread_union)               ;\
451
        /* create new stack frame, save only needed gprs */     ;\
452
        /* r1: KSP, r10: current, r31: __pa(KSP) */             ;\
453
        /* r12: temp, syscall indicator, r13 temp */            ;\
454
        l.addi  r1,r1,-(INT_FRAME_SIZE)                         ;\
455
        /* r1 is KSP, r31 is __pa(KSP) */                       ;\
456
        tophys  (r31,r1)                                        ;\
457
        l.sw    GPR12(r31),r12                                  ;\
458
        l.mfspr r12,r0,SPR_EPCR_BASE                            ;\
459
        l.sw    PC(r31),r12                                     ;\
460
        l.mfspr r12,r0,SPR_ESR_BASE                             ;\
461
        l.sw    SR(r31),r12                                     ;\
462
        /* save r31 */                                          ;\
463
        EXCEPTION_T_LOAD_GPR31(r12)                             ;\
464
        l.sw    GPR31(r31),r12                                  ;\
465
        /* save r10 as was prior to exception */                ;\
466
        EXCEPTION_T_LOAD_GPR10(r12)                             ;\
467
        l.sw    GPR10(r31),r12                                  ;\
468
        /* save SP as was prior to exception */                 ;\
469
        EXCEPTION_T_LOAD_SP(r12)                                ;\
470
        l.sw    SP(r31),r12                                     ;\
471
        l.sw    GPR13(r31),r13                                  ;\
472
        /* --> */                                               ;\
473
        /* save exception r4, set r4 = EA */                    ;\
474
        l.sw    GPR4(r31),r4                                    ;\
475
        l.mfspr r4,r0,SPR_EEAR_BASE                             ;\
476
        /* r12 == 1 if we come from syscall */                  ;\
477
        CLEAR_GPR(r12)                                          ;\
478
        /* ----- play a MMU trick ----- */                      ;\
479
        l.ori   r31,r0,(EXCEPTION_SR)                           ;\
480
        l.mtspr r0,r31,SPR_ESR_BASE                             ;\
481
        /* r31: EA address of handler */                        ;\
482
        LOAD_SYMBOL_2_GPR(r31,handler)                          ;\
483
        l.mtspr r0,r31,SPR_EPCR_BASE                            ;\
484
        l.rfe
485
 
486
/* =====================================================[ exceptions] === */
487
 
488
/* ---[ 0x100: RESET exception ]----------------------------------------- */
489
    .org 0x100
490
 
491
        /* make sure R0=0 */
492
        l.movhi r0,hi(0x0)
493
        l.andi r0,r0,0x0
494
 
495
        l.ori   r3,r0,0x1
496
        l.mtspr r0,r3,SPR_SR
497
 
498
#ifdef CONFIG_OR32_FLASH_BOOT
499
        LOAD_SYMBOL_2_GPR(r3,0xf0000120)        // jumps to the 'reset_start'
500
        l.jr    r3
501
        l.nop
502
 
503
reset_start:
504
#if   CONFIG_OR32_MC_VERSION==1 && defined CONFIG_OR32_MC_INIT
505
        l.jal   _mc_init_1
506
        l.nop
507
#elif CONFIG_OR32_MC_VERSION==2 && defined CONFIG_OR32_MC_INIT
508
        l.jal   _mc_init_2
509
        l.nop
510
#elif !defined CONFIG_OR32_MC_INIT
511
        l.nop
512
        l.nop
513
#else
514
#  error "no configuration for given memory controler type"
515
#endif
516
 
517
        l.jal   _early_uart_init
518
        l.nop
519
 
520
        LOAD_SYMBOL_2_GPR(r4,_string_copying_linux)
521
        l.movhi r3,hi(0x30000000)
522
        l.add   r3,r3,r4
523
        l.jal   _emergency_print
524
        l.nop
525
 
526
        /*
527
         * copy linux kernel image from flash to sdram
528
         */
529
        LOAD_SYMBOL_2_GPR(r3,0xf0000000)        // source
530
        LOAD_SYMBOL_2_GPR(r4,0x0)               // destination
531
        LOAD_SYMBOL_2_GPR(r6,__end)             // last destination
532
        tophys  (r5,r6)                         // last destination
533
 
534
        /*
535
         * copy %r3 to %r4 until %r4 == %r5
536
         */
537
2:
538
        l.sfgeu r4,r5
539
        l.bf    1f
540
        l.nop
541
        l.lwz   r8,0(r3)
542
        l.sw    0(r4),r8
543
        l.addi  r3,r3,4
544
        l.j     2b
545
        l.addi  r4,r4,4
546
1:
547
 
548
#else /* CONFIG_OR32_FLASH_BOOT */
549
#if   CONFIG_OR32_MC_VERSION==1 && defined CONFIG_OR32_MC_INIT
550
        l.jal   _mc_init_1
551
        l.nop
552
#elif CONFIG_OR32_MC_VERSION==2 && defined CONFIG_OR32_MC_INIT
553
        l.jal   _mc_init_2
554
        l.nop
555
#elif !defined CONFIG_OR32_MC_INIT
556
        l.nop
557
        l.nop
558
#else
559
#  error "no configuration for given memory controler type"
560
#endif
561
 
562
        l.jal   _early_uart_init
563
        l.nop
564
 
565
#endif /* CONFIG_OR32_FLASH_BOOT */
566
#if 1
567
        LOAD_SYMBOL_2_GPR(r4,_string_ok_booting)
568
        tophys  (r3,r4)
569
        l.jal   _emergency_print
570
        l.nop
571
#endif
572
        LOAD_SYMBOL_2_GPR(r4, _start)
573
        tophys  (r3,r4)                         // physical address
574
        l.jr    r3
575
        l.nop
576
 
577
/* ---[ 0x200: BUS exception ]------------------------------------------- */
578
    .org 0x200
579
_dispatch_bus_fault:
580
        UNHANDLED_EXCEPTION(_vector_0x200)
581
 
582
/* ---[ 0x300: Data Page Fault exception ]------------------------------- */
583
    .org 0x300
584
_dispatch_do_dpage_fault:
585
//      totaly disable timer interrupt
586
//      l.mtspr r0,r0,SPR_TTMR
587
//      DEBUG_TLB_PROBE(0x300)
588
//      EXCEPTION_DEBUG_VALUE_ER_ENABLED(0x300)
589
        EXCEPTION_HANDLE(_data_page_fault_handler)
590
 
591
/* ---[ 0x400: Insn Page Fault exception ]------------------------------- */
592
    .org 0x400
593
_dispatch_do_ipage_fault:
594
//      totaly disable timer interrupt
595
//      l.mtspr r0,r0,SPR_TTMR
596
//      DEBUG_TLB_PROBE(0x400)
597
//      EXCEPTION_DEBUG_VALUE_ER_ENABLED(0x400)
598
        EXCEPTION_HANDLE(_insn_page_fault_handler)
599
 
600
/* ---[ 0x500: Timer exception ]----------------------------------------- */
601
    .org 0x500
602
        EXCEPTION_HANDLE(_timer_handler)
603
 
604
/* ---[ 0x600: Aligment exception ]-------------------------------------- */
605
    .org 0x600
606
        UNHANDLED_EXCEPTION(_vector_0x600)
607
//      EXCEPTION_HANDLE(_aligment_handler)
608
 
609
/* ---[ 0x700: Illegal insn exception ]---------------------------------- */
610
    .org 0x700
611
        UNHANDLED_EXCEPTION(_vector_0x700)
612
 
613
/* ---[ 0x800: External interrupt exception ]---------------------------- */
614
    .org 0x800
615
        EXCEPTION_HANDLE(_external_irq_handler)
616
 
617
/* ---[ 0x900: DTLB miss exception ]------------------------------------- */
618
    .org 0x900
619
        l.j     boot_dtlb_miss_handler
620
        l.nop
621
 
622
/* ---[ 0xa00: ITLB miss exception ]------------------------------------- */
623
    .org 0xa00
624
        l.j     boot_itlb_miss_handler
625
        l.nop
626
 
627
/* ---[ 0xb00: Range exception ]----------------------------------------- */
628
    .org 0xb00
629
        UNHANDLED_EXCEPTION(_vector_0xb00)
630
 
631
/* ---[ 0xc00: Syscall exception ]--------------------------------------- */
632
    .org 0xc00
633
        EXCEPTION_HANDLE(_sys_call_handler)
634
 
635
/* ---[ 0xd00: Trap exception ]------------------------------------------ */
636
    .org 0xd00
637
        UNHANDLED_EXCEPTION(_vector_0xd00)
638
 
639
/* ---[ 0xe00: Trap exception ]------------------------------------------ */
640
    .org 0xe00
641
        UNHANDLED_EXCEPTION(_vector_0xe00)
642
 
643
/* ---[ 0xf00: Reserved exception ]-------------------------------------- */
644
    .org 0xf00
645
        UNHANDLED_EXCEPTION(_vector_0xf00)
646
 
647
/* ---[ 0x1000: Reserved exception ]------------------------------------- */
648
    .org 0x1000
649
        UNHANDLED_EXCEPTION(_vector_0x1000)
650
 
651
/* ---[ 0x1100: Reserved exception ]------------------------------------- */
652
    .org 0x1100
653
        UNHANDLED_EXCEPTION(_vector_0x1100)
654
 
655
/* ---[ 0x1200: Reserved exception ]------------------------------------- */
656
    .org 0x1200
657
        UNHANDLED_EXCEPTION(_vector_0x1200)
658
 
659
/* ---[ 0x1300: Reserved exception ]------------------------------------- */
660
    .org 0x1300
661
        UNHANDLED_EXCEPTION(_vector_0x1300)
662
 
663
/* ---[ 0x1400: Reserved exception ]------------------------------------- */
664
    .org 0x1400
665
        UNHANDLED_EXCEPTION(_vector_0x1400)
666
 
667
/* ---[ 0x1500: Reserved exception ]------------------------------------- */
668
    .org 0x1500
669
        UNHANDLED_EXCEPTION(_vector_0x1500)
670
 
671
/* ---[ 0x1600: Reserved exception ]------------------------------------- */
672
    .org 0x1600
673
        UNHANDLED_EXCEPTION(_vector_0x1600)
674
 
675
/* ---[ 0x1700: Reserved exception ]------------------------------------- */
676
    .org 0x1700
677
        UNHANDLED_EXCEPTION(_vector_0x1700)
678
 
679
/* ---[ 0x1800: Reserved exception ]------------------------------------- */
680
    .org 0x1800
681
        UNHANDLED_EXCEPTION(_vector_0x1800)
682
 
683
/* ---[ 0x1900: Reserved exception ]------------------------------------- */
684
    .org 0x1900
685
        UNHANDLED_EXCEPTION(_vector_0x1900)
686
 
687
/* ---[ 0x1a00: Reserved exception ]------------------------------------- */
688
    .org 0x1a00
689
        UNHANDLED_EXCEPTION(_vector_0x1a00)
690
 
691
/* ---[ 0x1b00: Reserved exception ]------------------------------------- */
692
    .org 0x1b00
693
        UNHANDLED_EXCEPTION(_vector_0x1b00)
694
 
695
/* ---[ 0x1c00: Reserved exception ]------------------------------------- */
696
    .org 0x1c00
697
        UNHANDLED_EXCEPTION(_vector_0x1c00)
698
 
699
/* ---[ 0x1d00: Reserved exception ]------------------------------------- */
700
    .org 0x1d00
701
        UNHANDLED_EXCEPTION(_vector_0x1d00)
702
 
703
/* ---[ 0x1e00: Reserved exception ]------------------------------------- */
704
    .org 0x1e00
705
        UNHANDLED_EXCEPTION(_vector_0x1e00)
706
 
707
/* ---[ 0x1f00: Reserved exception ]------------------------------------- */
708
    .org 0x1f00
709
        UNHANDLED_EXCEPTION(_vector_0x1f00)
710
 
711
    .org 0x2000
712
/* ===================================================[ kernel start ]=== */
713
 
714
    .text
715
    .global _stext
716
_stext:
717
 
718
    .global _start
719
_start:
720
        /*
721
         * ensure a deterministic start
722
         */
723
 
724
        l.ori   r3,r0,0x1
725
        l.mtspr r0,r3,SPR_SR
726
 
727
        CLEAR_GPR(r1)
728
        CLEAR_GPR(r2)
729
        CLEAR_GPR(r3)
730
        CLEAR_GPR(r4)
731
        CLEAR_GPR(r5)
732
        CLEAR_GPR(r6)
733
        CLEAR_GPR(r7)
734
        CLEAR_GPR(r8)
735
        CLEAR_GPR(r9)
736
        CLEAR_GPR(r10)
737
        CLEAR_GPR(r11)
738
        CLEAR_GPR(r12)
739
        CLEAR_GPR(r13)
740
        CLEAR_GPR(r14)
741
        CLEAR_GPR(r15)
742
        CLEAR_GPR(r16)
743
        CLEAR_GPR(r17)
744
        CLEAR_GPR(r18)
745
        CLEAR_GPR(r19)
746
        CLEAR_GPR(r20)
747
        CLEAR_GPR(r21)
748
        CLEAR_GPR(r22)
749
        CLEAR_GPR(r23)
750
        CLEAR_GPR(r24)
751
        CLEAR_GPR(r25)
752
        CLEAR_GPR(r26)
753
        CLEAR_GPR(r27)
754
        CLEAR_GPR(r28)
755
        CLEAR_GPR(r29)
756
        CLEAR_GPR(r30)
757
        CLEAR_GPR(r31)
758
 
759
        /*
760
         * set up initial ksp and current
761
         */
762
        LOAD_SYMBOL_2_GPR(r1,_init_thread_union+0x2000) // setup kernel stack
763
        LOAD_SYMBOL_2_GPR(r10,_init_thread_union)       // setup current
764
        tophys  (r31,r10)
765
        l.sw    TI_KSP(r31), r1
766
 
767
write_config:
768
        INIT_CONFIG_ICACHE(r3)
769
        INIT_CONFIG_DCACHE(r3)
770
 
771
        l.ori   r4,r0,0x0
772
        E_REGEN_STORE_STATUS(r4)                        //
773
 
774
 
775
        /*
776
         * .data contains initialized data,
777
         * .bss contains uninitialized data - clear it up
778
         */
779
clear_bss:
780
        LOAD_SYMBOL_2_GPR(r24, ___bss_start)
781
        LOAD_SYMBOL_2_GPR(r26, __end)
782
        tophys(r28,r24)
783
        tophys(r30,r26)
784
        CLEAR_GPR(r24)
785
        CLEAR_GPR(r26)
786
1:
787
        l.sw    (0)(r28),r0
788
        l.sfltu r28,r30
789
        l.bf    1b
790
        l.addi  r28,r28,4
791
 
792
enable_ic:
793
        l.jal   _ic_enable
794
        l.nop
795
 
796
 
797
enable_dc:
798
        l.jal   _dc_enable
799
        l.nop
800
 
801
flush_tlb:
802
        /*
803
         *  I N V A L I D A T E   T L B   e n t r i e s
804
         */
805
        LOAD_SYMBOL_2_GPR(r5,SPR_DTLBMR_BASE(0))
806
        LOAD_SYMBOL_2_GPR(r6,SPR_ITLBMR_BASE(0))
807
        l.addi  r7,r0,64
808
1:
809
        l.mtspr r5,r0,0x0
810
        l.mtspr r6,r0,0x0
811
 
812
        l.addi  r5,r5,1
813
        l.addi  r6,r6,1
814
        l.sfeq  r7,r0
815
        l.bnf   1b
816
        l.addi  r7,r7,-1
817
 
818
        LOAD_SYMBOL_2_GPR(r5,SPR_DTLBTR_BASE(0))
819
        LOAD_SYMBOL_2_GPR(r6,SPR_ITLBTR_BASE(0))
820
        l.addi  r7,r0,64
821
1:
822
        l.mtspr r5,r0,0x0
823
        l.mtspr r6,r0,0x0
824
 
825
        l.addi  r5,r5,1
826
        l.addi  r6,r6,1
827
        l.sfeq  r7,r0
828
        l.bnf   1b
829
        l.addi  r7,r7,-1
830
 
831
enable_mmu:
832
        /*
833
         * enable dmmu & immu
834
         * SR[5] = 0, SR[6] = 0, 6th and 7th bit of SR set to 0
835
         */
836
        SR_ENABLE_BITS((SPR_SR_DME | SPR_SR_IME),r28,r30)
837
        l.nop
838
        l.nop
839
        l.nop
840
        l.nop
841
        l.nop
842
        l.nop
843
        l.nop
844
        l.nop
845
        l.nop
846
        l.nop
847
        l.nop
848
        l.nop
849
        l.nop
850
        l.nop
851
        l.nop
852
        l.nop
853
 
854
hw_breakpoint:
855
#if 0
856
        /* set effective address */
857
        LOAD_SYMBOL_2_GPR(r3,SPR_DVR(0))
858
        LOAD_SYMBOL_2_GPR(r4,_start_kernel)
859
        l.mtspr r3,r4,0x0
860
 
861
        /* control register: present, equal to, instruction fetch EA */
862
        LOAD_SYMBOL_2_GPR(r3,SPR_DCR(0))
863
        LOAD_SYMBOL_2_GPR(r4,0x23)
864
        l.mtspr r3,r4,0x0
865
 
866
        /* control register: present, equal to, store/load EA */
867
//      LOAD_SYMBOL_2_GPR(r3,SPR_DCR(0))
868
//      LOAD_SYMBOL_2_GPR(r4,0xc3)
869
//      l.mtspr r3,r4,0x0
870
 
871
        /* ext watchpoint | watchpoint 0 */
872
        LOAD_SYMBOL_2_GPR(r3,SPR_DMR1)
873
        LOAD_SYMBOL_2_GPR(r4,0x2)
874
        l.mtspr r3,r4,0x0
875
 
876
        /* watchpoint 0 triggers trap instruction, enable counter 0 */
877
        LOAD_SYMBOL_2_GPR(r3,SPR_DMR2)
878
        LOAD_SYMBOL_2_GPR(r4,0x1001)
879
        l.mtspr r3,r4,0x0
880
#endif
881
 
882
#if 0
883
        // this will not work due to trap handler jumping
884
        LOAD_SYMBOL_2_GPR(r3,SPR_DMR1)
885
        LOAD_SYMBOL_2_GPR(r4,0x800000)
886
        l.mtspr r3,r4,0x0
887
#endif
888
 
889
#if 0
890
        /* set effective address */
891
        LOAD_SYMBOL_2_GPR(r3,SPR_DVR(0))
892
        LOAD_SYMBOL_2_GPR(r4,0x100)
893
        l.mtspr r3,r4,0x0
894
 
895
        /* control register: present, not equal to, store/load EA */
896
        LOAD_SYMBOL_2_GPR(r3,SPR_DCR(0))
897
        LOAD_SYMBOL_2_GPR(r4,0xcd)
898
        l.mtspr r3,r4,0x0
899
 
900
        /* ext watchpoint | watchpoint 0 */
901
        LOAD_SYMBOL_2_GPR(r3,SPR_DMR1)
902
        LOAD_SYMBOL_2_GPR(r4,0x2)
903
        l.mtspr r3,r4,0x0
904
 
905
        /* watchpoint 0 triggers trap instruction, enable counter 0 */
906
        LOAD_SYMBOL_2_GPR(r3,SPR_DMR2)
907
        LOAD_SYMBOL_2_GPR(r4,0x1001)
908
        l.mtspr r3,r4,0x0
909
#endif
910
 
911
clear_regs:
912
        /*
913
         * clear all GPRS to increase determinism
914
         */
915
        CLEAR_GPR(r2)
916
        CLEAR_GPR(r3)
917
        CLEAR_GPR(r4)
918
        CLEAR_GPR(r5)
919
        CLEAR_GPR(r6)
920
        CLEAR_GPR(r7)
921
        CLEAR_GPR(r8)
922
        CLEAR_GPR(r9)
923
        CLEAR_GPR(r11)
924
        CLEAR_GPR(r12)
925
        CLEAR_GPR(r13)
926
        CLEAR_GPR(r14)
927
        CLEAR_GPR(r15)
928
        CLEAR_GPR(r16)
929
        CLEAR_GPR(r17)
930
        CLEAR_GPR(r18)
931
        CLEAR_GPR(r19)
932
        CLEAR_GPR(r20)
933
        CLEAR_GPR(r21)
934
        CLEAR_GPR(r22)
935
        CLEAR_GPR(r23)
936
        CLEAR_GPR(r24)
937
        CLEAR_GPR(r25)
938
        CLEAR_GPR(r26)
939
        CLEAR_GPR(r27)
940
        CLEAR_GPR(r28)
941
        CLEAR_GPR(r29)
942
        CLEAR_GPR(r30)
943
        CLEAR_GPR(r31)
944
 
945
jump_start_kernel:
946
        /*
947
         * jump to kernel entry (start_kernel)
948
         */
949
        LOAD_SYMBOL_2_GPR(r30, _start_kernel)
950
        l.jr    r30
951
        l.nop
952
 
953
/* ========================================[ memory controler, cache ]=== */
954
 
955
ENTRY(_mc_init_1)
956
#if   CONFIG_OR32_MC_VERSION==1 && defined CONFIG_OR32_MC_INIT
957
        l.movhi r3,hi(MC_BASE_ADD)
958
        l.ori   r3,r3,lo(MC_BASE_ADD)
959
 
960
        l.addi  r4,r3,MC_CSC(0)
961
        l.movhi r5,hi(FLASH_BASE_ADD)
962
        l.srai  r5,r5,6
963
        l.ori   r5,r5,0x0025
964
        l.sw    0(r4),r5
965
 
966
        l.addi  r4,r3,MC_TMS(0)
967
        l.movhi r5,hi(FLASH_TMS_VAL)
968
        l.ori   r5,r5,lo(FLASH_TMS_VAL)
969
        l.sw    0(r4),r5
970
 
971
        l.addi  r4,r3,MC_BA_MASK
972
        l.addi  r5,r0,MC_MASK_VAL
973
        l.sw    0(r4),r5
974
 
975
        l.addi  r4,r3,MC_CSR
976
        l.movhi r5,hi(MC_CSR_VAL)
977
        l.ori   r5,r5,lo(MC_CSR_VAL)
978
        l.sw    0(r4),r5
979
 
980
        l.addi  r4,r3,MC_TMS(1)
981
        l.movhi r5,hi(SDRAM_TMS_VAL)
982
        l.ori   r5,r5,lo(SDRAM_TMS_VAL)
983
        l.sw    0(r4),r5
984
 
985
        l.addi  r4,r3,MC_CSC(1)
986
        l.movhi r5,hi(SDRAM_BASE_ADD)
987
        l.srai  r5,r5,6
988
        l.ori   r5,r5,0x0411
989
        l.sw    0(r4),r5
990
 
991
#ifdef FBMEM_BASE_ADD
992
        l.addi  r4,r3,MC_CSC(2)
993
        l.movhi r5,hi(FBMEM_BASE_ADD)
994
        l.srai  r5,r5,6
995
        l.ori   r5,r5,0x0005
996
        l.sw    0(r4),r5
997
 
998
        l.addi  r4,r3,MC_TMS(2)
999
        l.movhi r5,0xffff
1000
        l.ori   r5,r5,0xffff
1001
        l.sw    0(r4),r5
1002
#endif /* FBMEM_BASE_ADD */
1003
#endif /* CONFIG_OR32_MC_VERSION==1 && defined CONFIG_OR32_MC_INIT */
1004
        l.jr    r9
1005
        l.nop
1006
 
1007
ENTRY(_mc_init_2)
1008
#if   CONFIG_OR32_MC_VERSION==2 && defined CONFIG_OR32_MC_INIT
1009
        l.movhi r3,hi(MC_BASE_ADD)
1010
        l.ori   r3,r3,lo(MC_BASE_ADD)
1011
 
1012
        l.addi  r4,r3,MC_BAR_0
1013
        l.movhi r5,hi(FLASH_BAR_VAL)
1014
        l.sw    0(r4),r5
1015
 
1016
        l.addi  r4,r3,MC_AMR_0
1017
        l.movhi r5,hi(FLASH_AMR_VAL)
1018
        l.sw    0(r4),r5
1019
 
1020
        l.addi  r4,r3,MC_WTR_0
1021
        l.movhi r5,hi(FLASH_WTR_VAL)
1022
        l.ori   r5,r5,lo(FLASH_WTR_VAL)
1023
        l.sw    0(r4),r5
1024
 
1025
        l.addi  r4,r3,MC_RTR_0
1026
        l.movhi r5,hi(FLASH_RTR_VAL)
1027
        l.ori   r5,r5,lo(FLASH_RTR_VAL)
1028
        l.sw    0(r4),r5
1029
 
1030
        l.addi  r4,r3,MC_OSR
1031
        l.movhi r5,hi(0x40000000)
1032
        l.ori   r5,r5,lo(0x40000000)
1033
        l.sw    0(r4),r5
1034
 
1035
        l.addi  r4,r3,MC_BAR_4
1036
        l.movhi r5,hi(SDRAM_BAR_VAL)
1037
        l.sw    0(r4),r5
1038
 
1039
        l.addi  r4,r3,MC_AMR_4
1040
        l.movhi r5,hi(SDRAM_AMR_VAL)
1041
        l.sw    0(r4),r5
1042
 
1043
        l.addi  r4,r3,MC_CCR_4
1044
        l.movhi r5,hi(MC_CCR_4_VAL_DISABLED)
1045
        l.ori   r5,r5,lo(MC_CCR_4_VAL_DISABLED)
1046
        l.sw    0(r4),r5
1047
 
1048
        l.addi  r4,r3,MC_RATR
1049
        l.movhi r5,hi(SDRAM_RATR_VAL)
1050
        l.ori   r5,r5,lo(SDRAM_RATR_VAL)
1051
        l.sw    0(r4),r5
1052
 
1053
        l.addi  r4,r3,MC_RCDR
1054
        l.movhi r5,hi(SDRAM_RCDR_VAL)
1055
        l.ori   r5,r5,lo(SDRAM_RCDR_VAL)
1056
        l.sw    0(r4),r5
1057
 
1058
        l.addi  r4,r3,MC_RCTR
1059
        l.movhi r5,hi(SDRAM_RCTR_VAL)
1060
        l.ori   r5,r5,lo(SDRAM_RCTR_VAL)
1061
        l.sw    0(r4),r5
1062
 
1063
        l.addi  r4,r3,MC_REFCTR
1064
        l.movhi r5,hi(SDRAM_REFCTR_VAL)
1065
        l.ori   r5,r5,lo(SDRAM_REFCTR_VAL)
1066
        l.sw    0(r4),r5
1067
 
1068
        l.addi  r4,r3,MC_PTR
1069
        l.movhi r5,hi(SDRAM_PTR_VAL)
1070
        l.ori   r5,r5,lo(SDRAM_PTR_VAL)
1071
        l.sw    0(r4),r5
1072
 
1073
        l.addi  r4,r3,MC_RRDR
1074
        l.movhi r5,hi(SDRAM_RRDR_VAL)
1075
        l.ori   r5,r5,lo(SDRAM_RRDR_VAL)
1076
        l.sw    0(r4),r5
1077
 
1078
        l.addi  r4,r3,MC_WRTR
1079
        l.movhi r5,hi(SDRAM_WRTR_VAL)
1080
        l.ori   r5,r5,lo(SDRAM_WRTR_VAL)
1081
        l.sw    0(r4),r5
1082
 
1083
        l.addi  r4,r3,MC_RIR
1084
        l.movhi r5,hi(SDRAM_RIR_VAL)
1085
        l.ori   r5,r5,lo(SDRAM_RIR_VAL)
1086
        l.sw    0(r4),r5
1087
 
1088
        l.addi  r4,r3,MC_OSR
1089
        l.movhi r5,hi(0x5e000000)
1090
        l.ori   r5,r5,lo(0x5e000000)
1091
        l.sw    0(r4),r5
1092
 
1093
        l.addi  r4,r3,MC_ORR
1094
        l.sw    0(r4),r5
1095
 
1096
        l.addi  r4,r3,MC_OSR
1097
        l.movhi r5,hi(0x6e000000)
1098
        l.ori   r5,r5,lo(0x6e000000)
1099
        l.sw    0(r4),r5
1100
 
1101
        l.addi  r4,r3,MC_ORR
1102
        l.sw    0(r4),r5
1103
        l.sw    0(r4),r5
1104
        l.sw    0(r4),r5
1105
        l.sw    0(r4),r5
1106
        l.sw    0(r4),r5
1107
        l.sw    0(r4),r5
1108
        l.sw    0(r4),r5
1109
        l.sw    0(r4),r5
1110
 
1111
        l.addi  r4,r3,MC_OSR
1112
        l.movhi r5,hi(MC_OSR_VAL)
1113
        l.ori   r5,r5,lo(MC_OSR_VAL)
1114
        l.sw    0(r4),r5
1115
 
1116
        l.addi  r4,r3,MC_ORR
1117
        l.sw    0(r4),r5
1118
 
1119
        l.addi  r4,r3,MC_CCR_4
1120
        l.movhi r5,hi(MC_CCR_4_VAL_ENABLED)
1121
        l.ori   r5,r5,lo(MC_CCR_4_VAL_ENABLED)
1122
        l.sw    0(r4),r5
1123
#endif /* CONFIG_OR32_MC_VERSION==2 && defined CONFIG_OR32_MC_INIT */
1124
 
1125
        l.jr    r9
1126
        l.nop
1127
 
1128
        /* aligment here so we don't change memory offsets with
1129
         * memory controler defined
1130
         */
1131
        .align 0x2000
1132
 
1133
#ifdef CONFIG_OR32_CACHE_DEBUG
1134
ENTRY(_ic_enable)
1135
        SF_DISABLED(r6,INIT_IC_ADDR)
1136
        l.bf    9f
1137
        l.nop
1138
 
1139
        EMERGENCY_PRINT_STORE_GPR9
1140
        LOAD_SYMBOL_2_GPR(r4,_string_icache_clean)
1141
        tophys  (r3,r4)
1142
        l.jal   _emergency_print
1143
        l.nop
1144
 
1145
        /* Disable IC */
1146
        l.mfspr r6,r0,SPR_SR
1147
        l.addi  r5,r0,-1
1148
        l.xori  r5,r5,SPR_SR_ICE
1149
        l.and   r5,r6,r5
1150
        l.mtspr r0,r5,SPR_SR
1151
 
1152
        /* Invalidate IC */
1153
        l.addi  r6,r0,0
1154
        l.addi  r5,r0,IC_SIZE
1155
1:
1156
#if 0
1157
        LOAD_SYMBOL_2_GPR(r4,_string_ic_invalidate)
1158
        tophys  (r3,r4)
1159
        l.jal   _emergency_print
1160
        l.nop
1161
 
1162
        l.jal   _emergency_print_nr
1163
        l.addi  r3,r6,0
1164
#endif
1165
        l.mtspr r0,r6,SPR_ICBIR
1166
        l.sfne  r6,r5
1167
        l.bf    1b
1168
        l.addi  r6,r6,IC_LINE
1169
 
1170
        LOAD_SYMBOL_2_GPR(r4,_string_ic_enable)
1171
        tophys  (r3,r4)
1172
        l.jal   _emergency_print
1173
        l.nop
1174
 
1175
        /* Enable IC */
1176
        l.mfspr r6,r0,SPR_SR
1177
        l.ori   r6,r6,SPR_SR_ICE
1178
        l.mtspr r0,r6,SPR_SR
1179
        l.nop
1180
        l.nop
1181
        l.nop
1182
        l.nop
1183
        l.nop
1184
        l.nop
1185
        l.nop
1186
        l.nop
1187
        l.nop
1188
        l.nop
1189
        EMERGENCY_PRINT_LOAD_GPR9
1190
9:
1191
        l.jr    r9
1192
        l.nop
1193
#else
1194
ENTRY(_ic_enable)
1195
        SF_DISABLED(r6,INIT_IC_ADDR)
1196
        l.bf    9f
1197
        l.nop
1198
 
1199
        /* Disable IC */
1200
        l.mfspr r6,r0,SPR_SR
1201
        l.addi  r5,r0,-1
1202
        l.xori  r5,r5,SPR_SR_ICE
1203
        l.and   r5,r6,r5
1204
        l.mtspr r0,r5,SPR_SR
1205
 
1206
        /* Invalidate IC */
1207
        l.addi  r6,r0,0
1208
        l.addi  r5,r0,IC_SIZE
1209
1:
1210
        l.mtspr r0,r6,SPR_ICBIR
1211
        l.sfne  r6,r5
1212
        l.bf    1b
1213
        l.addi  r6,r6,IC_LINE
1214
 
1215
        /* Enable IC */
1216
        l.mfspr r6,r0,SPR_SR
1217
        l.ori   r6,r6,SPR_SR_ICE
1218
        l.mtspr r0,r6,SPR_SR
1219
        l.nop
1220
        l.nop
1221
        l.nop
1222
        l.nop
1223
        l.nop
1224
        l.nop
1225
        l.nop
1226
        l.nop
1227
        l.nop
1228
        l.nop
1229
9:
1230
        l.jr    r9
1231
        l.nop
1232
#endif
1233
 
1234
#ifdef CONFIG_OR32_CACHE_DEBUG
1235
ENTRY(_dc_enable)
1236
        SF_DISABLED(r6,INIT_DC_ADDR)
1237
        l.bf    9f
1238
        l.nop
1239
 
1240
        EMERGENCY_PRINT_STORE_GPR9
1241
        LOAD_SYMBOL_2_GPR(r4,_string_dcache_clean)
1242
        tophys  (r3,r4)
1243
        l.jal   _emergency_print
1244
        l.nop
1245
 
1246
        /* Disable DC */
1247
        l.mfspr r6,r0,SPR_SR
1248
        l.addi  r5,r0,-1
1249
        l.xori  r5,r5,SPR_SR_DCE
1250
        l.and   r5,r6,r5
1251
        l.mtspr r0,r5,SPR_SR
1252
 
1253
        /* Flush DC */
1254
        l.addi  r6,r0,0
1255
        l.addi  r5,r0,DC_SIZE
1256
1:
1257
#ifdef CONFIG_OR32_CACHE_DEBUG
1258
        LOAD_SYMBOL_2_GPR(r4,_string_dc_invalidate)
1259
        tophys  (r3,r4)
1260
        l.jal   _emergency_print
1261
        l.nop
1262
 
1263
        l.jal   _emergency_print_nr
1264
        l.addi  r3,r6,0
1265
#endif
1266
 
1267
        l.mtspr r0,r6,SPR_DCBIR
1268
        l.sfne  r6,r5
1269
        l.bf    1b
1270
        l.addi  r6,r6,DC_LINE
1271
 
1272
        LOAD_SYMBOL_2_GPR(r4,_string_dc_enable)
1273
        tophys  (r3,r4)
1274
        l.jal   _emergency_print
1275
        l.nop
1276
 
1277
        /* Enable DC */
1278
        l.mfspr r6,r0,SPR_SR
1279
        l.ori   r6,r6,SPR_SR_DCE
1280
        l.mtspr r0,r6,SPR_SR
1281
        EMERGENCY_PRINT_LOAD_GPR9
1282
9:
1283
        l.jr    r9
1284
        l.nop
1285
#else
1286
ENTRY(_dc_enable)
1287
        SF_DISABLED(r6,INIT_DC_ADDR)
1288
        l.bf    9f
1289
        l.nop
1290
 
1291
        /* Disable DC */
1292
        l.mfspr r6,r0,SPR_SR
1293
        l.addi  r5,r0,-1
1294
        l.xori  r5,r5,SPR_SR_DCE
1295
        l.and   r5,r6,r5
1296
        l.mtspr r0,r5,SPR_SR
1297
 
1298
        /* Flush DC */
1299
        l.addi  r6,r0,0
1300
        l.addi  r5,r0,DC_SIZE
1301
1:
1302
        l.mtspr r0,r6,SPR_DCBIR
1303
        l.sfne  r6,r5
1304
        l.bf    1b
1305
        l.addi  r6,r6,DC_LINE
1306
 
1307
        /* Enable DC */
1308
        l.mfspr r6,r0,SPR_SR
1309
        l.ori   r6,r6,SPR_SR_DCE
1310
        l.mtspr r0,r6,SPR_SR
1311
9:
1312
        l.jr    r9
1313
        l.nop
1314
#endif
1315
 
1316
/* ===============================================[ page table masks ]=== */
1317
 
1318
/* bit 4 is used in hardware as write back cache bit. we never use this bit
1319
 * explicitly, so we can reuse it as _PAGE_FILE bit and mask it out when
1320
 * writing into hardware pte's
1321
 */
1322
 
1323
#define DTLB_UP_CONVERT_MASK  0x3fa
1324
#define ITLB_UP_CONVERT_MASK  0x3a
1325
 
1326
/* for SMP we'd have (this is a bit subtle, CC must be always set
1327
 * for SMP, but since we have _PAGE_PRESENT bit always defined
1328
 * we can just modify the mask)
1329
 */
1330
#define DTLB_SMP_CONVERT_MASK  0x3fb
1331
#define ITLB_SMP_CONVERT_MASK  0x3b
1332
 
1333
/* ==============================================[ DTLB miss handler ]=== */
1334
 
1335
        .global _dtlb_miss_handler
1336
_dtlb_miss_handler:
1337
        EXCEPTION_DEBUG_VALUE_ER(0x900)
1338
 
1339
        EXCEPTION_STORE_GPR2
1340
        EXCEPTION_STORE_GPR3
1341
        EXCEPTION_STORE_GPR4
1342
        EXCEPTION_STORE_GPR5
1343
        /*
1344
         * get EA of the miss
1345
         */
1346
        l.mfspr r2,r0,SPR_EEAR_BASE
1347
        /*
1348
         * pmd = (pmd_t *)(current_pgd + pgd_index(daddr));
1349
         */
1350
        GET_CURRENT_PGD(r3,r5)          // r3 is current_pgd, r5 is temp
1351
        l.srli  r4,r2,0x18              // >> PAGE_SHIFT + (PAGE_SHIFT - 2)
1352
        l.slli  r4,r4,0x2               // to get address << 2
1353
        l.add   r5,r4,r3                // r4 is pgd_index(daddr)
1354
        /*
1355
         * if (pmd_none(*pmd))
1356
         *   goto pmd_none:
1357
         */
1358
        tophys  (r4,r5)
1359
        l.lwz   r3,0x0(r4)              // get *pmd value
1360
        l.sfne  r3,r0
1361
        l.bnf   d_pmd_none
1362
        l.andi  r3,r3,0x1fff            // ~PAGE_MASK
1363
        /*
1364
         * if (pmd_bad(*pmd))
1365
         *   pmd_clear(pmd)
1366
         *   goto pmd_bad:
1367
         */
1368
//      l.sfeq  r3,r0                   // check *pmd value
1369
//      l.bf    d_pmd_good
1370
        l.addi  r3,r0,0xffffe000        // PAGE_MASK
1371
//      l.j     d_pmd_bad
1372
//      l.sw    0x0(r4),r0              // clear pmd
1373
d_pmd_good:
1374
        /*
1375
         * pte = *pte_offset(pmd, daddr);
1376
         */
1377
        l.lwz   r4,0x0(r4)              // get **pmd value
1378
        l.and   r4,r4,r3                // & PAGE_MASK
1379
        l.srli  r5,r2,0xd               // >> PAGE_SHIFT, r2 == EEAR
1380
        l.andi  r3,r5,0x7ff             // (1UL << PAGE_SHIFT - 2) - 1
1381
        l.slli  r3,r3,0x2               // to get address << 2
1382
        l.add   r3,r3,r4
1383
        l.lwz   r2,0x0(r3)              // this is pte at last
1384
        /*
1385
         * if (!pte_present(pte))
1386
         */
1387
        l.andi  r4,r2,0x1
1388
        l.sfne  r4,r0                   // is pte present
1389
        l.bnf   d_pte_not_present
1390
        l.addi  r3,r0,0xffffe3fa        // PAGE_MASK | DTLB_UP_CONVERT_MASK
1391
        /*
1392
         * fill DTLB TR register
1393
         */
1394
        l.and   r4,r2,r3                // apply the mask
1395
        l.andi  r5,r5,0x3f              // calc offset:  & (NUM_TLB_ENTRIES-1), NUM_TLB_ENTRIES == 64
1396
        l.mtspr r5,r4,SPR_DTLBTR_BASE(0)
1397
        /*
1398
         * fill DTLB MR register
1399
         */
1400
        l.mfspr r2,r0,SPR_EEAR_BASE
1401
        l.addi  r3,r0,0xffffe000        // PAGE_MASK
1402
        l.and   r4,r2,r3                // apply PAGE_MASK to EA (__PHX__ do we really need this?)
1403
        l.ori   r4,r4,0x1               // set hardware valid bit: DTBL_MR entry
1404
        l.mtspr r5,r4,SPR_DTLBMR_BASE(0)
1405
 
1406
#ifndef CONFIG_DMMU_WORKS
1407
        l.addi  r5,r5,1
1408
        l.andi  r5,r5,0x3f
1409
        l.mtspr r5,r0,SPR_DTLBMR_BASE(0)
1410
        l.addi  r5,r5,-2
1411
        l.andi  r5,r5,0x3f
1412
        l.mtspr r5,r0,SPR_DTLBMR_BASE(0)
1413
#endif
1414
        EXCEPTION_LOAD_GPR2
1415
        EXCEPTION_LOAD_GPR3
1416
        EXCEPTION_LOAD_GPR4
1417
        EXCEPTION_LOAD_GPR5
1418
        l.rfe
1419
d_pmd_bad:
1420
        l.nop   1
1421
        EXCEPTION_LOAD_GPR2
1422
        EXCEPTION_LOAD_GPR3
1423
        EXCEPTION_LOAD_GPR4
1424
        EXCEPTION_LOAD_GPR5
1425
        l.rfe
1426
d_pmd_none:
1427
d_pte_not_present:
1428
        EXCEPTION_LOAD_GPR2
1429
        EXCEPTION_LOAD_GPR3
1430
        EXCEPTION_LOAD_GPR4
1431
        EXCEPTION_LOAD_GPR5
1432
        // __PHX__ for debugging purposes
1433
        DEBUG_TLB_PROBE(0x903)
1434
        l.j     _dispatch_do_dpage_fault
1435
        l.nop
1436
 
1437
/* ==============================================[ ITLB miss handler ]=== */
1438
        .global _itlb_miss_handler
1439
_itlb_miss_handler:
1440
        EXCEPTION_DEBUG_VALUE_ER(0xa00)
1441
 
1442
        EXCEPTION_STORE_GPR2
1443
        EXCEPTION_STORE_GPR3
1444
        EXCEPTION_STORE_GPR4
1445
        EXCEPTION_STORE_GPR5
1446
        /*
1447
         * get EA of the miss
1448
         */
1449
        l.mfspr r2,r0,SPR_EEAR_BASE
1450
 
1451
#ifndef CONFIG_IMMU_WORKS
1452
        // check for exception in delay slot and on page boundry
1453
        l.andi  r3,r2,0x1fff            // PAGE_SIZE - 1
1454
        l.sfeqi r3,0
1455
        l.bnf   1f
1456
        l.nop                           // we are on page boundry
1457
        l.mfspr r4,r0,SPR_EPCR_BASE
1458
        l.sfeq  r4,r2
1459
        l.bf    1f                      // EPC and EEA are equal -> not in delay slot
1460
        l.nop
1461
 
1462
        l.mfspr r5,r0,SPR_ESR_BASE      // are we in user mode
1463
        l.andi  r5,r5,SPR_SR_SM
1464
        l.sfeqi r5,0
1465
        l.bnf   2f                      // kernel mode
1466
        l.nop
1467
 
1468
        // user mode: no fixup
1469
        EXCEPTION_STORE_GPR9
1470
        l.jal   _emergency_print
1471
        l.ori   r3,r0,lo(_string_pbjds) // page boundry, jump, delay slot
1472
        l.nop   0x1
1473
        l.j     1f
1474
        EXCEPTION_LOAD_GPR9
1475
 
1476
2:
1477
        EXCEPTION_STORE_GPR6
1478
        EXCEPTION_STORE_GPR9
1479
 
1480
        // ok, we are in trouble...
1481
        l.jal   _immu_trampoline_workaround
1482
        l.nop
1483
 
1484
        EXCEPTION_LOAD_GPR2
1485
        EXCEPTION_LOAD_GPR3
1486
        EXCEPTION_LOAD_GPR4
1487
        EXCEPTION_LOAD_GPR5
1488
        EXCEPTION_LOAD_GPR6
1489
        EXCEPTION_LOAD_GPR9
1490
        l.rfe
1491
 
1492
1:      // this is not delay slot exception of the page boundry
1493
#endif
1494
 
1495
        /*
1496
         * pmd = (pmd_t *)(current_pgd + pgd_index(daddr));
1497
         *
1498
         */
1499
        GET_CURRENT_PGD(r3,r5)          // r3 is current_pgd, r5 is temp
1500
        l.srli  r4,r2,0x18              // >> PAGE_SHIFT + (PAGE_SHIFT - 2)
1501
        l.slli  r4,r4,0x2               // to get address << 2
1502
        l.add   r5,r4,r3                // r4 is pgd_index(daddr)
1503
        /*
1504
         * if (pmd_none(*pmd))
1505
         *   goto pmd_none:
1506
         */
1507
        tophys  (r4,r5)
1508
        l.lwz   r3,0x0(r4)              // get *pmd value
1509
        l.sfne  r3,r0
1510
        l.bnf   i_pmd_none
1511
        l.andi  r3,r3,0x1fff            // ~PAGE_MASK
1512
        /*
1513
         * if (pmd_bad(*pmd))
1514
         *   pmd_clear(pmd)
1515
         *   goto pmd_bad:
1516
         */
1517
 
1518
//      l.sfeq  r3,r0                   // check *pmd value
1519
//      l.bf    i_pmd_good
1520
        l.addi  r3,r0,0xffffe000        // PAGE_MASK
1521
//      l.j     i_pmd_bad
1522
//      l.sw    0x0(r4),r0              // clear pmd
1523
 
1524
i_pmd_good:
1525
        /*
1526
         * pte = *pte_offset(pmd, iaddr);
1527
         *
1528
         */
1529
        l.lwz   r4,0x0(r4)              // get **pmd value
1530
        l.and   r4,r4,r3                // & PAGE_MASK
1531
        l.srli  r5,r2,0xd               // >> PAGE_SHIFT, r2 == EEAR
1532
        l.andi  r3,r5,0x7ff             // (1UL << PAGE_SHIFT - 2) - 1
1533
        l.slli  r3,r3,0x2               // to get address << 2
1534
        l.add   r3,r3,r4
1535
        l.lwz   r2,0x0(r3)              // this is pte at last
1536
        /*
1537
         * if (!pte_present(pte))
1538
         *
1539
         */
1540
        l.andi  r4,r2,0x1
1541
        l.sfne  r4,r0                   // is pte present
1542
        l.bnf   i_pte_not_present
1543
        l.addi  r3,r0,0xffffe03a        // PAGE_MASK | ITLB_UP_CONVERT_MASK
1544
        /*
1545
         * fill ITLB TR register
1546
         */
1547
        l.and   r4,r2,r3                // apply the mask
1548
        l.andi  r3,r2,0x7c0             // _PAGE_EXEC | _PAGE_SRE | _PAGE_SWE |  _PAGE_URE | _PAGE_UWE
1549
//      l.andi  r3,r2,0x400             // _PAGE_EXEC
1550
        l.sfeq  r3,r0
1551
        l.bf    itlb_tr_fill //_workaround
1552
        l.andi  r5,r5,0x3f              // calc offset:  & (NUM_TLB_ENTRIES-1), NUM_TLB_ENTRIES == 64
1553
/*
1554
 * __PHX__ :: fixme
1555
 * we should not just blindly set executable flags,
1556
 * but it does help with ping. the clean way would be to find out
1557
 * (and fix it) why stack doesn't have execution permissions
1558
 */
1559
 
1560
itlb_tr_fill_workaround:
1561
        l.ori   r4,r4,0xc0              // | (SPR_ITLBTR_UXE | ITLBTR_SXE)
1562
itlb_tr_fill:
1563
        l.mtspr r5,r4,SPR_ITLBTR_BASE(0)
1564
        /*
1565
         * fill DTLB MR register
1566
         */
1567
        l.mfspr r2,r0,SPR_EEAR_BASE
1568
        l.addi  r3,r0,0xffffe000        // PAGE_MASK
1569
        l.and   r4,r2,r3                // apply PAGE_MASK to EA (__PHX__ do we really need this?)
1570
        l.ori   r4,r4,0x1               // set hardware valid bit: DTBL_MR entry
1571
        l.mtspr r5,r4,SPR_ITLBMR_BASE(0)
1572
 
1573
#ifndef CONFIG_IMMU_WORKS
1574
        l.addi  r5,r5,1
1575
        l.andi  r5,r5,0x3f
1576
        l.mtspr r5,r0,SPR_ITLBMR_BASE(0)
1577
        l.addi  r5,r5,-2
1578
        l.andi  r5,r5,0x3f
1579
        l.mtspr r5,r0,SPR_ITLBMR_BASE(0)
1580
#endif
1581
        EXCEPTION_LOAD_GPR2
1582
        EXCEPTION_LOAD_GPR3
1583
        EXCEPTION_LOAD_GPR4
1584
        EXCEPTION_LOAD_GPR5
1585
        l.rfe
1586
 
1587
i_pmd_bad:
1588
        l.nop   1
1589
        EXCEPTION_LOAD_GPR2
1590
        EXCEPTION_LOAD_GPR3
1591
        EXCEPTION_LOAD_GPR4
1592
        EXCEPTION_LOAD_GPR5
1593
        l.rfe
1594
i_pmd_none:
1595
i_pte_not_present:
1596
        EXCEPTION_LOAD_GPR2
1597
        EXCEPTION_LOAD_GPR3
1598
        EXCEPTION_LOAD_GPR4
1599
        EXCEPTION_LOAD_GPR5
1600
        // __PHX__ for debugging purposes
1601
        DEBUG_TLB_PROBE(0xa04)
1602
        l.j     _dispatch_do_ipage_fault
1603
        l.nop
1604
 
1605
/* ==============================================[ boot tlb handlers ]=== */
1606
/* ---[ boot dtlb miss handler ]----------------------------------------- */
1607
 
1608
boot_dtlb_miss_handler:
1609
 
1610
/* mask for DTLB_MR register: - (0) sets V (valid) bit,
1611
 *                            - (31-12) sets bits belonging to VPN (31-12)
1612
 */
1613
#define DTLB_MR_MASK 0xfffff001
1614
 
1615
/* mask for DTLB_TR register: - (2) sets CI (cache inhibit) bit,
1616
 *                            - (4) sets A (access) bit,
1617
 *                            - (5) sets D (dirty) bit,
1618
 *                            - (8) sets SRE (superuser read) bit
1619
 *                            - (9) sets SWE (superuser write) bit
1620
 *                            - (31-12) sets bits belonging to VPN (31-12)
1621
 */
1622
#define DTLB_TR_MASK 0xfffff332
1623
 
1624
#define VPN_MASK 0xfffff000
1625
#define PPN_MASK 0xfffff000
1626
 
1627
/*
1628
 * a % 64 = a & MOD_64_MASK
1629
 */
1630
#define MOD_64_MASK 0x3f
1631
 
1632
#define MOD_64(dest,src)          \
1633
        l.andi  dest,src,MOD_64_MASK
1634
 
1635
        EXCEPTION_DEBUG_VALUE_ER(0x9b0)
1636
        EXCEPTION_STORE_GPR6
1637
 
1638
        l.mfspr r6,r0,SPR_ESR_BASE         //
1639
        l.andi  r6,r6,SPR_SR_SM            // are we in kernel mode ?
1640
        l.sfeqi r6,0                       // r6 == 0x1 --> SM
1641
        l.bf    exit_with_no_dtranslation  //
1642
        l.nop
1643
 
1644
        /* this could be optimized by moving storing of
1645
         * non r6 registers here, and jumping r6 restore
1646
         * if not in supervisor mode
1647
         */
1648
 
1649
        EXCEPTION_STORE_GPR2
1650
        EXCEPTION_STORE_GPR3
1651
        EXCEPTION_STORE_GPR4
1652
        EXCEPTION_STORE_GPR5
1653
 
1654
        l.mfspr r4,r0,SPR_EEAR_BASE        // get the offending EA
1655
 
1656
        /* do not do any translation if EA is above DRAM_END */
1657
        LOAD_SYMBOL_2_GPR(r6,DRAM_END)
1658
        l.sfgtu r4,r6                      // flag if EA larger than DRAM_END
1659
        l.bf    exit_with_no_dtranslation
1660
        /* delay slot */
1661
 
1662
 
1663
immediate_translation:
1664
        CLEAR_GPR(r6)
1665
 
1666
        l.srli  r3,r4,0xd                  // r3 <- r4 / 8192 (sets are relative to page size (8Kb) NOT VPN size (4Kb)
1667
        l.andi  r2,r3,MOD_64_MASK          // r2 <- r3 % 64: ok this is SET
1668
        l.or    r6,r6,r4                   // r6 <- r4
1669
        l.ori   r6,r6,~(VPN_MASK)          // r6 <- VPN :VPN .xfff - clear up lo(r6) to 0x**** *fff
1670
        l.movhi r5,hi(DTLB_MR_MASK)        // r5 <- ffff:0000.x000
1671
        l.ori   r5,r5,lo(DTLB_MR_MASK)     // r5 <- ffff:1111.x001 - apply DTLB_MR_MASK
1672
        l.and   r5,r5,r6                   // r5 <- VPN :VPN .x001 - we have DTLBMR entry
1673
        l.mtspr r2,r5,SPR_DTLBMR_BASE(0)   // set DTLBMR
1674
 
1675
        /* set up DTLB with no translation for EA <= 0xbfffffff */
1676
        LOAD_SYMBOL_2_GPR(r6,0xbfffffff)
1677
        l.sfgeu  r6,r4                     // flag if r6 >= r4 (if 0xbfffffff >= EA)
1678
        l.bf     1f                        // goto out
1679
        l.and    r3,r4,r4                  // delay slot :: 24 <- r4 (if flag==1)
1680
 
1681
        tophys(r3,r4)                      // r3 <- PA
1682
1:
1683
        l.ori   r3,r3,~(PPN_MASK)          // r3 <- PPN :PPN .xfff - clear up lo(r6) to 0x**** *fff
1684
        l.movhi r5,hi(DTLB_TR_MASK)        // r5 <- ffff:0000.x000
1685
        l.ori   r5,r5,lo(DTLB_TR_MASK)     // r5 <- ffff:1111.x330 - apply DTLB_MR_MASK
1686
        l.and   r5,r5,r3                   // r5 <- PPN :PPN .x330 - we have DTLBTR entry
1687
        l.mtspr r2,r5,SPR_DTLBTR_BASE(0)   // set DTLBTR
1688
 
1689
#ifndef CONFIG_DMMU_WORKS
1690
        l.addi  r2,r2,1
1691
        l.andi  r2,r2,0x3f
1692
        l.mtspr r2,r0,SPR_DTLBMR_BASE(0)
1693
        l.addi  r2,r2,-2
1694
        l.andi  r2,r2,0x3f
1695
        l.mtspr r2,r0,SPR_DTLBMR_BASE(0)
1696
#endif
1697
 
1698
        EXCEPTION_LOAD_GPR6
1699
        EXCEPTION_LOAD_GPR5
1700
        EXCEPTION_LOAD_GPR4
1701
        EXCEPTION_LOAD_GPR3
1702
        EXCEPTION_LOAD_GPR2
1703
 
1704
        l.rfe                              // SR <- ESR, PC <- EPC
1705
 
1706
exit_with_no_dtranslation:
1707
        /* EA out of memory or not in supervisor mode */
1708
        EXCEPTION_LOAD_GPR6
1709
        EXCEPTION_LOAD_GPR4
1710
        l.j     _dispatch_bus_fault
1711
 
1712
/* ---[ boot itlb miss handler ]----------------------------------------- */
1713
 
1714
boot_itlb_miss_handler:
1715
 
1716
/* mask for ITLB_MR register: - sets V (valid) bit,
1717
 *                            - sets bits belonging to VPN (15-12)
1718
 */
1719
#define ITLB_MR_MASK 0xfffff001
1720
 
1721
/* mask for ITLB_TR register: - sets A (access) bit,
1722
 *                            - sets SXE (superuser execute) bit
1723
 *                            - sets bits belonging to VPN (15-12)
1724
 */
1725
#define ITLB_TR_MASK 0xfffff050
1726
 
1727
#define VPN_MASK 0xfffff000
1728
#define PPN_MASK 0xfffff000
1729
 
1730
/*
1731
 * a % 64 = a & MOD_64_MASK
1732
 */
1733
#define MOD_64_MASK 0x3f
1734
 
1735
#define MOD_64(dest,src)          \
1736
        l.andi  dest,src,MOD_64_MASK
1737
 
1738
        EXCEPTION_DEBUG_VALUE_ER(0xab0)
1739
 
1740
        EXCEPTION_STORE_GPR2
1741
        EXCEPTION_STORE_GPR3
1742
        EXCEPTION_STORE_GPR4
1743
        EXCEPTION_STORE_GPR5
1744
        EXCEPTION_STORE_GPR6
1745
 
1746
        l.mfspr r6,r0,SPR_ESR_BASE         //
1747
        l.andi  r6,r6,SPR_SR_SM            // are we in kernel mode ?
1748
        l.sfeqi r6,0                       // r6 == 0x1 --> SM
1749
        l.bf    exit_with_no_itranslation
1750
        l.nop
1751
 
1752
#ifndef CONFIG_IMMU_WORKS
1753
        l.mfspr r2,r0,SPR_EEAR_BASE
1754
 
1755
        // check for exception in delay slot and on page boundry
1756
        l.andi  r3,r2,0x1fff            // PAGE_SIZE - 1
1757
        l.sfeqi r3,0
1758
        l.bnf   1f
1759
        l.nop                           // we are on page boundry
1760
        l.mfspr r4,r0,SPR_EPCR_BASE
1761
        l.sfeq  r4,r2
1762
        l.bf    1f                      // EPC and EEA are equal -> not in delay slot
1763
        l.nop
1764
 
1765
        EXCEPTION_STORE_GPR6
1766
        EXCEPTION_STORE_GPR9
1767
        // ok, we are in trouble...
1768
        l.jal   _immu_trampoline_workaround
1769
        l.nop
1770
 
1771
        EXCEPTION_LOAD_GPR2
1772
        EXCEPTION_LOAD_GPR3
1773
        EXCEPTION_LOAD_GPR4
1774
        EXCEPTION_LOAD_GPR5
1775
        EXCEPTION_LOAD_GPR6
1776
        EXCEPTION_LOAD_GPR9
1777
        l.rfe
1778
 
1779
1:      // this is not delay slot exception of the page boundry
1780
#endif
1781
 
1782
 
1783
        l.mfspr r4,r0,SPR_EEAR_BASE        // get the offending EA
1784
 
1785
        /* do not do any translation if EA is above DRAM_END */
1786
        LOAD_SYMBOL_2_GPR(r6,DRAM_END)
1787
        l.sfgtu  r4,r6                     // flag if EA larger than DRAM_END
1788
        l.bf     exit_with_no_itranslation
1789
        l.nop
1790
 
1791
        CLEAR_GPR(r6)
1792
 
1793
        l.srli  r3,r4,0xd                  // r3 <- r4 / 8192 (sets are relative to page size (8Kb) NOT VPN size (4Kb)
1794
        l.andi  r2,r3,MOD_64_MASK          // r2 <- r3 % 64: ok this is SET
1795
        l.or    r6,r6,r4                   // r6 <- r4
1796
        l.ori   r6,r6,~(VPN_MASK)          // r6 <- VPN :VPN .xfff - clear up lo(r6) to 0x**** *fff
1797
        l.movhi r5,hi(ITLB_MR_MASK)        // r5 <- ffff:0000.x000
1798
        l.ori   r5,r5,lo(ITLB_MR_MASK)     // r5 <- ffff:1111.x001 - apply ITLB_MR_MASK
1799
        l.and   r5,r5,r6                   // r5 <- VPN :VPN .x001 - we have ITLBMR entry
1800
        l.mtspr r2,r5,SPR_ITLBMR_BASE(0)   // set ITLBMR
1801
 
1802
        /*
1803
         * set up ITLB with no translation for EA <= 0x0fffffff
1804
         *
1805
         * we need this for head.S mapping (EA = PA). if we move all functions
1806
         * which run with mmu enabled into entry.S, we might be able to eliminate this.
1807
         *
1808
         */
1809
        LOAD_SYMBOL_2_GPR(r6,0x0fffffff)
1810
        l.sfgeu  r6,r4                     // flag if r6 >= r4 (if 0xb0ffffff >= EA)
1811
        l.bf     1f                        // goto out
1812
        l.and    r3,r4,r4                  // delay slot :: 24 <- r4 (if flag==1)
1813
 
1814
        tophys(r3,r4)                      // r3 <- PA
1815
1:
1816
        l.ori   r3,r3,~(PPN_MASK)          // r3 <- PPN :PPN .xfff - clear up lo(r6) to 0x**** *fff
1817
        l.movhi r5,hi(ITLB_TR_MASK)        // r5 <- ffff:0000.x000
1818
        l.ori   r5,r5,lo(ITLB_TR_MASK)     // r5 <- ffff:1111.x050 - apply ITLB_MR_MASK
1819
        l.and   r5,r5,r3                   // r5 <- PPN :PPN .x050 - we have ITLBTR entry
1820
        l.mtspr r2,r5,SPR_ITLBTR_BASE(0)   // set ITLBTR
1821
 
1822
#ifndef CONFIG_IMMU_WORKS
1823
        l.addi  r2,r2,1
1824
        l.andi  r2,r2,0x3f
1825
        l.mtspr r2,r0,SPR_ITLBMR_BASE(0)
1826
        l.addi  r2,r2,-2
1827
        l.andi  r2,r2,0x3f
1828
        l.mtspr r2,r0,SPR_ITLBMR_BASE(0)
1829
#endif
1830
 
1831
        EXCEPTION_LOAD_GPR6
1832
        EXCEPTION_LOAD_GPR5
1833
        EXCEPTION_LOAD_GPR4
1834
        EXCEPTION_LOAD_GPR3
1835
        EXCEPTION_LOAD_GPR2
1836
 
1837
        l.rfe                              // SR <- ESR, PC <- EPC
1838
 
1839
exit_with_no_itranslation:
1840
        EXCEPTION_LOAD_GPR4
1841
        EXCEPTION_LOAD_GPR6
1842
        l.j    _dispatch_bus_fault
1843
        l.nop
1844
 
1845
/* =================================================[ debugging aids ]=== */
1846
 
1847
        .align 64
1848
_immu_trampoline:
1849
        .space 64
1850
_immu_trampoline_top:
1851
 
1852
#define TRAMP_SLOT_0            (0x0)
1853
#define TRAMP_SLOT_1            (0x4)
1854
#define TRAMP_SLOT_2            (0x8)
1855
#define TRAMP_SLOT_3            (0xc)
1856
#define TRAMP_SLOT_4            (0x10)
1857
#define TRAMP_SLOT_5            (0x14)
1858
#define TRAMP_FRAME_SIZE        (0x18)
1859
 
1860
ENTRY(_immu_trampoline_workaround)
1861
        // r2 EEA
1862
        // r6 is physical EEA
1863
        tophys(r6,r2)
1864
 
1865
        LOAD_SYMBOL_2_GPR(r5,_immu_trampoline)
1866
        tophys  (r3,r5)                 // r3 is trampoline (physical)
1867
 
1868
        LOAD_SYMBOL_2_GPR(r4,0x15000000)
1869
        l.sw    TRAMP_SLOT_0(r3),r4
1870
        l.sw    TRAMP_SLOT_1(r3),r4
1871
        l.sw    TRAMP_SLOT_4(r3),r4
1872
        l.sw    TRAMP_SLOT_5(r3),r4
1873
 
1874
                                        // EPC = EEA - 0x4
1875
        l.lwz   r4,0x0(r6)              // load op @ EEA + 0x0 (fc address)
1876
        l.sw    TRAMP_SLOT_3(r3),r4     // store it to _immu_trampoline_data
1877
        l.lwz   r4,-0x4(r6)             // load op @ EEA - 0x4 (f8 address)
1878
        l.sw    TRAMP_SLOT_2(r3),r4     // store it to _immu_trampoline_data
1879
 
1880
        l.srli  r5,r4,26                // check opcode for write access
1881
        l.sfeqi r5,0                    // l.j
1882
        l.bf    0f
1883
        l.sfeqi r5,0x11                 // l.jr
1884
        l.bf    1f
1885
        l.sfeqi r5,1                    // l.jal
1886
        l.bf    2f
1887
        l.sfeqi r5,0x12                 // l.jalr
1888
        l.bf    3f
1889
        l.sfeqi r5,3                    // l.bnf
1890
        l.bf    4f
1891
        l.sfeqi r5,4                    // l.bf
1892
        l.bf    5f
1893
99:
1894
        l.nop
1895
        l.j     99b                     // should never happen
1896
        l.nop   1
1897
 
1898
        // r2 is EEA
1899
        // r3 is trampoline address (physical)
1900
        // r4 is instruction
1901
        // r6 is physical(EEA)
1902
        //
1903
        // r5
1904
 
1905
2:      // l.jal
1906
 
1907
        /* 19 20 aa aa  l.movhi r9,0xaaaa
1908
         * a9 29 bb bb  l.ori   r9,0xbbbb
1909
         *
1910
         * where 0xaaaabbbb is EEA + 0x4 shifted right 2
1911
         */
1912
 
1913
        l.addi  r6,r2,0x4               // this is 0xaaaabbbb
1914
 
1915
                                        // l.movhi r9,0xaaaa
1916
        l.ori   r5,r0,0x1920            // 0x1920 == l.movhi r9
1917
        l.sh    (TRAMP_SLOT_0+0x0)(r3),r5
1918
        l.srli  r5,r6,16
1919
        l.sh    (TRAMP_SLOT_0+0x2)(r3),r5
1920
 
1921
                                        // l.ori   r9,0xbbbb
1922
        l.ori   r5,r0,0xa929            // 0xa929 == l.ori r9
1923
        l.sh    (TRAMP_SLOT_1+0x0)(r3),r5
1924
        l.andi  r5,r6,0xffff
1925
        l.sh    (TRAMP_SLOT_1+0x2)(r3),r5
1926
 
1927
        /* falthrough, need to set up new jump offset */
1928
 
1929
 
1930
0:      // l.j
1931
        l.slli  r6,r4,6                 // original offset shifted left 6 - 2
1932
//      l.srli  r6,r6,6                 // original offset shifted right 2
1933
 
1934
        l.slli  r4,r2,4                 // old jump position: EEA shifted left 4
1935
//      l.srli  r4,r4,6                 // old jump position: shifted right 2
1936
 
1937
        l.addi  r5,r3,0xc               // new jump position (physical)
1938
        l.slli  r5,r5,4                 // new jump position: shifted left 4
1939
 
1940
        // calculate new jump offset
1941
        // new_off = old_off + (old_jump - new_jump)
1942
 
1943
        l.sub   r5,r4,r5                // old_jump - new_jump
1944
        l.add   r5,r6,r5                // orig_off + (old_jump - new_jump)
1945
        l.srli  r5,r5,6                 // new offset shifted right 2
1946
 
1947
        // r5 is new jump offset
1948
                                        // l.j has opcode 0x0...
1949
        l.sw    TRAMP_SLOT_2(r3),r5     // write it back
1950
 
1951
        l.j     trampoline_out
1952
        l.nop
1953
 
1954
/* ----------------------------- */
1955
 
1956
3:      // l.jalr
1957
 
1958
        /* 19 20 aa aa  l.movhi r9,0xaaaa
1959
         * a9 29 bb bb  l.ori   r9,0xbbbb
1960
         *
1961
         * where 0xaaaabbbb is EEA + 0x4 shifted right 2
1962
         */
1963
 
1964
        l.addi  r6,r2,0x4               // this is 0xaaaabbbb
1965
 
1966
                                        // l.movhi r9,0xaaaa
1967
        l.ori   r5,r0,0x1920            // 0x1920 == l.movhi r9
1968
        l.sh    (TRAMP_SLOT_0+0x0)(r3),r5
1969
        l.srli  r5,r6,16
1970
        l.sh    (TRAMP_SLOT_0+0x2)(r3),r5
1971
 
1972
                                        // l.ori   r9,0xbbbb
1973
        l.ori   r5,r0,0xa929            // 0xa929 == l.ori r9
1974
        l.sh    (TRAMP_SLOT_1+0x0)(r3),r5
1975
        l.andi  r5,r6,0xffff
1976
        l.sh    (TRAMP_SLOT_1+0x2)(r3),r5
1977
 
1978
        l.lhz   r5,(TRAMP_SLOT_2+0x0)(r3)       // load hi part of jump instruction
1979
        l.andi  r5,r5,0x3ff             // clear out opcode part
1980
        l.ori   r5,r5,0x4400            // opcode changed from l.jalr -> l.jr
1981
        l.sh    (TRAMP_SLOT_2+0x0)(r3),r5 // write it back
1982
 
1983
        /* falthrough */
1984
 
1985
1:      // l.jr
1986
        l.j     trampoline_out
1987
        l.nop
1988
 
1989
/* ----------------------------- */
1990
 
1991
4:      // l.bnf
1992
5:      // l.bf
1993
        l.slli  r6,r4,6                 // original offset shifted left 6 - 2
1994
//      l.srli  r6,r6,6                 // original offset shifted right 2
1995
 
1996
        l.slli  r4,r2,4                 // old jump position: EEA shifted left 4
1997
//      l.srli  r4,r4,6                 // old jump position: shifted right 2
1998
 
1999
        l.addi  r5,r3,0xc               // new jump position (physical)
2000
        l.slli  r5,r5,4                 // new jump position: shifted left 4
2001
 
2002
        // calculate new jump offset
2003
        // new_off = old_off + (old_jump - new_jump)
2004
 
2005
        l.add   r6,r6,r4                // (orig_off + old_jump)
2006
        l.sub   r6,r6,r5                // (orig_off + old_jump) - new_jump
2007
        l.srli  r6,r6,6                 // new offset shifted right 2
2008
 
2009
        // r6 is new jump offset
2010
        l.lwz   r4,(TRAMP_SLOT_2+0x0)(r3)       // load jump instruction
2011
        l.srli  r4,r4,16
2012
        l.andi  r4,r4,0xfc00            // get opcode part
2013
        l.slli  r4,r4,16
2014
        l.or    r6,r4,r6                // l.b(n)f new offset
2015
        l.sw    TRAMP_SLOT_2(r3),r6     // write it back
2016
 
2017
        /* we need to add l.j to EEA + 0x8 */
2018
        tophys  (r4,r2)                 // may not be needed (due to shifts down_
2019
        l.addi  r4,r4,(0x8 - 0x8)       // jump target = r2 + 0x8 (compensate for 0x8)
2020
                                        // jump position = r5 + 0x8 (0x8 compensated)
2021
        l.sub   r4,r4,r5                // jump offset = target - new_position + 0x8
2022
 
2023
        l.slli  r4,r4,4                 // the amount of info in imediate of jump
2024
        l.srli  r4,r4,6                 // jump instruction with offset
2025
        l.sw    TRAMP_SLOT_4(r3),r4     // write it to 4th slot
2026
 
2027
        /* fallthrough */
2028
 
2029
trampoline_out:
2030
        // set up new EPC to point to our trampoline code
2031
        LOAD_SYMBOL_2_GPR(r5,_immu_trampoline)
2032
        l.mtspr r0,r5,SPR_EPCR_BASE
2033
 
2034
        // immu_trampoline is (4x) CACHE_LINE aligned
2035
        // and only 6 instructions long,
2036
        // so we need to invalidate only 2 lines
2037
        l.mtspr r0,r5,SPR_ICBIR
2038
        l.addi  r5,r5,IC_LINE
2039
        l.mtspr r0,r5,SPR_ICBIR
2040
 
2041
        l.jr    r9
2042
        l.nop
2043
 
2044
/*
2045
 * dumping processor state without mmu
2046
 * (not yet finnished)
2047
 */
2048
 
2049
ENTRY(_debug_tng)
2050
        l.addi  r1,r1,-16
2051
        l.sw    0(r1),r3
2052
        l.sw    4(r1),r4
2053
        l.mfspr r3,r0,SPR_SR
2054
        l.sw    8(r1),r3
2055
        l.mfspr r3,r0,SPR_PC
2056
        l.sw    12(r1),r3
2057
 
2058
        l.ori   r3,r0,0x8001
2059
        l.mtspr r0,r3,SPR_ESR_BASE
2060
        LOAD_SYMBOL_2_GPR(r3,nommu_entry)
2061
        tophys  (r4,r3)
2062
        l.mtspr r0,r4,SPR_EPCR_BASE
2063
 
2064
        l.lwz   r3,0(r1)
2065
        l.lwz   r4,4(r1)
2066
        l.addi  r1,r1,8
2067
        l.rfe
2068
 
2069
nommu_entry:
2070
        EXCEPTION_T_STORE_GPR31
2071
        EXCEPTION_T_STORE_GPR10
2072
        EXCEPTION_T_STORE_SP
2073
        /* temporary store r3, r9 into r1, r10 */
2074
        l.addi  r1,r3,0x0
2075
        l.addi  r10,r9,0x0
2076
        /* the string referenced by r3 must be low enough */
2077
        l.jal   _emergency_print
2078
        l.ori   r3,r0,lo(_string_ed)
2079
        l.mfspr r3,r0,SPR_PC
2080
        l.jal   _emergency_print_nr
2081
        l.andi  r3,r3,0x1f00
2082
        /* the string referenced by r3 must be low enough */
2083
        l.jal   _emergency_print
2084
        l.ori   r3,r0,lo(_string_epc_prefix)
2085
        l.jal   _emergency_print_nr
2086
        l.mfspr r3,r0,SPR_EPCR_BASE
2087
        l.jal   _emergency_print
2088
        l.ori   r3,r0,lo(_string_nl)
2089
        /* end of printing */
2090
        l.addi  r3,r1,0x0
2091
        l.addi  r9,r10,0x0
2092
        /* extract current, ksp from current_set */
2093
        LOAD_SYMBOL_2_GPR(r1,_unhandled_stack_top)
2094
        /* create new stack frame, save only needed gprs */
2095
        /* r1: KSP, r10: current, r31: __pa(KSP) */
2096
        /* r12: temp, syscall indicator, r13 temp */
2097
        l.addi  r1,r1,-(INT_FRAME_SIZE)
2098
        /* r1 is KSP, r31 is __pa(KSP) */
2099
        tophys  (r31,r1)
2100
        l.sw    GPR12(r31),r12
2101
        l.mfspr r12,r0,SPR_EPCR_BASE
2102
        l.sw    PC(r31),r12
2103
        l.mfspr r12,r0,SPR_ESR_BASE
2104
        l.sw    SR(r31),r12
2105
        /* save r31 */
2106
        EXCEPTION_T_LOAD_GPR31(r12)
2107
        l.sw    GPR31(r31),r12
2108
        /* save r10 as was prior to exception */
2109
        EXCEPTION_T_LOAD_GPR10(r12)
2110
        l.sw    GPR10(r31),r12
2111
        /* save SP as was prior to exception */
2112
        EXCEPTION_T_LOAD_SP(r12)
2113
        l.sw    SP(r31),r12
2114
        l.sw    GPR13(r31),r13
2115
        /* --> */
2116
        /* save exception r4, set r4 = EA */
2117
        l.sw    GPR4(r31),r4
2118
        l.mfspr r4,r0,SPR_EEAR_BASE
2119
        /* r31 is __pa(r1), r1 <- r31 */
2120
        l.addi  r1,r31,0x0
2121
        /* r1, r10, EPCR, ESR a already saved */
2122
        l.sw    GPR2(r1),r2
2123
        l.sw    GPR3(r1),r3
2124
        l.sw    ORIG_GPR3(r1),r3
2125
        l.sw    GPR5(r1),r5
2126
        l.sw    GPR6(r1),r6
2127
        l.sw    GPR7(r1),r7
2128
        l.sw    GPR8(r1),r8
2129
        l.sw    GPR9(r1),r9
2130
        /* r10 already saved */
2131
        l.sw    GPR11(r1),r11
2132
        /* r12,r13 already saved */
2133
        l.sw    GPR14(r1),r14
2134
        l.sw    GPR15(r1),r15
2135
        l.sw    GPR16(r1),r16
2136
        l.sw    GPR17(r1),r17
2137
        l.sw    GPR18(r1),r18
2138
        l.sw    GPR19(r1),r19
2139
        l.sw    GPR20(r1),r20
2140
        l.sw    GPR21(r1),r21
2141
        l.sw    GPR22(r1),r22
2142
        l.sw    GPR23(r1),r23
2143
        l.sw    GPR24(r1),r24
2144
        l.sw    GPR25(r1),r25
2145
        l.sw    GPR26(r1),r26
2146
        l.sw    GPR27(r1),r27
2147
        l.sw    GPR28(r1),r28
2148
        l.sw    GPR29(r1),r29
2149
        l.sw    GPR30(r1),r30
2150
        /* r31 already saved */
2151
        l.sw    RESULT(r1),r0
2152
        l.addi  r3,r1,0
2153
        /* r4 is exception EA */
2154
        l.addi  r5,r0,0xdead
2155
        l.jal   _nommu_dump_state
2156
        l.nop
2157
 
2158
 
2159
/* ========================================[ standard debugging aids ]=== */
2160
 
2161
// this HAS to be atomic. also disable interrupts beetwen to entries
2162
// may use gpr4
2163
ENTRY(_exception_regenerate)
2164
        E_REGEN_LOAD_STATUS(r4)         // were we in this exception yet
2165
        l.sfeqi r4,0x0
2166
        l.bnf   1f
2167
        l.nop
2168
 
2169
0:                                      // first entry into this exception
2170
                                        // patch the ESR, reenter exception
2171
 
2172
        l.mfspr r4,r0,SPR_ESR_BASE      // get original ESR
2173
        E_REGEN_STORE_STATUS(r4)        // save original ESR
2174
 
2175
        SPR_DISABLE_LO_BITS(SPR_ESR_BASE,
2176
                (SPR_SR_ICE | SPR_SR_DCE | SPR_SR_IEE | SPR_SR_TEE),r4)
2177
        SPR_DISABLE_LO_BITS(SPR_SR,
2178
                (SPR_SR_ICE | SPR_SR_DCE | SPR_SR_IEE | SPR_SR_TEE),r4)
2179
 
2180
        EXCEPTION_DEBUG_LOAD_GPR4
2181
        EXCEPTION_DEBUG_LOAD_F_GPR9
2182
 
2183
        l.rfe                           // this will regenerate exception
2184
 
2185
1:                                      // second entry into this exception
2186
                                        // patch ESR, invalidate the caches
2187
 
2188
        // we already loaded previous ESR into r4
2189
        l.mtspr r0,r4,SPR_ESR_BASE
2190
 
2191
        l.ori   r4,r0,0x0               // next time is fresh entry
2192
        E_REGEN_STORE_STATUS(r4)        // prepare for next exception
2193
 
2194
        E_REGEN_STORE_GPR3
2195
        E_REGEN_STORE_GPR4
2196
        E_REGEN_STORE_GPR5
2197
        E_REGEN_STORE_GPR6
2198
        E_REGEN_STORE_GPR9
2199
        l.jal   _dc_enable
2200
        l.nop
2201
        l.jal   _ic_enable
2202
        l.nop
2203
        E_REGEN_LOAD_GPR3
2204
        E_REGEN_LOAD_GPR4
2205
        E_REGEN_LOAD_GPR5
2206
        E_REGEN_LOAD_GPR6
2207
        E_REGEN_LOAD_GPR9
2208
 
2209
        l.jr    r9
2210
        l.nop
2211
 
2212
ENTRY(_exception_debug)
2213
        EXCEPTION_DEBUG_STORE_GPR3
2214
        EXCEPTION_DEBUG_STORE_GPR9
2215
 
2216
        // disable tick timer
2217
        l.mfspr r3,r0,SPR_TTMR
2218
        LOAD_SYMBOL_2_GPR(r9,~(0x30000003))
2219
        l.and   r3,r3,r9
2220
        l.mtspr r0,r3,SPR_TTMR
2221
 
2222
        l.jal   _emergency_print
2223
        l.ori   r3,r0,lo(_string_debug_exception)
2224
        l.jal   _emergency_print_nr
2225
        l.andi  r3,r4,0x1ff0
2226
        /* the string referenced by r3 must be low enough */
2227
        l.jal   _emergency_print
2228
        l.ori   r3,r0,lo(_string_epc_prefix)
2229
 
2230
        l.jal   _emergency_print_nr
2231
        l.mfspr r3,r0,SPR_EPCR_BASE
2232
 
2233
        l.jal   _emergency_print
2234
        l.ori   r3,r0,lo(_string_debug_esr_prefix)
2235
 
2236
        l.jal   _emergency_print_nr
2237
        l.mfspr r3,r0,SPR_ESR_BASE
2238
 
2239
        l.jal   _emergency_print
2240
        l.ori   r3,r0,lo(_string_debug_eear_prefix)
2241
 
2242
        l.jal   _emergency_print_nr
2243
        l.mfspr r3,r0,SPR_EEAR_BASE
2244
 
2245
        l.jal   _emergency_print
2246
        l.ori   r3,r0,lo(_string_nl)
2247
 
2248
        // enable tick timer
2249
        l.mfspr r3,r0,SPR_TTMR
2250
        LOAD_SYMBOL_2_GPR(r9,0x20000001)
2251
        l.or    r3,r3,r9
2252
        l.mtspr r0,r3,SPR_TTMR
2253
 
2254
        EXCEPTION_DEBUG_LOAD_GPR3
2255
        EXCEPTION_DEBUG_LOAD_GPR9
2256
        l.jr    r9
2257
        l.nop
2258
 
2259
/*
2260
 * DSCR: prints a string referenced by r3.
2261
 *
2262
 * PRMS: r3             - address of the first character of null
2263
 *                      terminated string to be printed
2264
 *
2265
 * PREQ: UART at UART_BASE_ADD has to be initialized
2266
 *
2267
 * POST: caller should be aware that r3, r9 are changed
2268
 */
2269
ENTRY(_emergency_print)
2270
        EMERGENCY_PRINT_STORE_GPR4
2271
        EMERGENCY_PRINT_STORE_GPR5
2272
        EMERGENCY_PRINT_STORE_GPR6
2273
        EMERGENCY_PRINT_STORE_GPR7
2274
2:
2275
        l.lbz   r7,0(r3)
2276
        l.sfeq  r7,r0
2277
        l.bf    9f
2278
        l.nop
2279
 
2280
// putc:
2281
        l.movhi r4,hi(UART_BASE_ADD)
2282
 
2283
        l.addi  r6,r0,0x20
2284
1:      l.lbz   r5,5(r4)
2285
        l.andi  r5,r5,0x20
2286
        l.sfeq  r5,r6
2287
        l.bnf   1b
2288
        l.nop
2289
 
2290
        l.sb    0(r4),r7
2291
 
2292
        l.addi  r6,r0,0x60
2293
1:      l.lbz   r5,5(r4)
2294
        l.andi  r5,r5,0x60
2295
        l.sfeq  r5,r6
2296
        l.bnf   1b
2297
        l.nop
2298
 
2299
        /* next character */
2300
        l.j     2b
2301
        l.addi  r3,r3,0x1
2302
 
2303
9:
2304
        EMERGENCY_PRINT_LOAD_GPR7
2305
        EMERGENCY_PRINT_LOAD_GPR6
2306
        EMERGENCY_PRINT_LOAD_GPR5
2307
        EMERGENCY_PRINT_LOAD_GPR4
2308
        l.jr    r9
2309
        l.nop
2310
 
2311
ENTRY(_emergency_print_nr)
2312
        EMERGENCY_PRINT_STORE_GPR4
2313
        EMERGENCY_PRINT_STORE_GPR5
2314
        EMERGENCY_PRINT_STORE_GPR6
2315
        EMERGENCY_PRINT_STORE_GPR7
2316
        EMERGENCY_PRINT_STORE_GPR8
2317
 
2318
        l.addi  r8,r0,32                // shift register
2319
 
2320
1:      /* remove leading zeros */
2321
        l.addi  r8,r8,-0x4
2322
        l.srl   r7,r3,r8
2323
        l.andi  r7,r7,0xf
2324
 
2325
        /* don't skip the last zero if number == 0x0 */
2326
        l.sfeqi r8,0x4
2327
        l.bf    2f
2328
        l.nop
2329
 
2330
        l.sfeq  r7,r0
2331
        l.bf    1b
2332
        l.nop
2333
 
2334
2:
2335
        l.srl   r7,r3,r8
2336
 
2337
        l.andi  r7,r7,0xf
2338
        l.sflts r8,r0
2339
        l.bf    9f
2340
 
2341
        l.sfgtui r7,0x9
2342
        l.bnf   8f
2343
        l.nop
2344
        l.addi  r7,r7,0x27
2345
 
2346
8:
2347
        l.addi  r7,r7,0x30
2348
// putc:
2349
        l.movhi r4,hi(UART_BASE_ADD)
2350
 
2351
        l.addi  r6,r0,0x20
2352
1:      l.lbz   r5,5(r4)
2353
        l.andi  r5,r5,0x20
2354
        l.sfeq  r5,r6
2355
        l.bnf   1b
2356
        l.nop
2357
 
2358
        l.sb    0(r4),r7
2359
 
2360
        l.addi  r6,r0,0x60
2361
1:      l.lbz   r5,5(r4)
2362
        l.andi  r5,r5,0x60
2363
        l.sfeq  r5,r6
2364
        l.bnf   1b
2365
        l.nop
2366
 
2367
        /* next character */
2368
        l.j     2b
2369
        l.addi  r8,r8,-0x4
2370
 
2371
9:
2372
        EMERGENCY_PRINT_LOAD_GPR8
2373
        EMERGENCY_PRINT_LOAD_GPR7
2374
        EMERGENCY_PRINT_LOAD_GPR6
2375
        EMERGENCY_PRINT_LOAD_GPR5
2376
        EMERGENCY_PRINT_LOAD_GPR4
2377
        l.jr    r9
2378
        l.nop
2379
 
2380
 
2381
ENTRY(_early_uart_init)
2382
        l.movhi r3,hi(UART_BASE_ADD)
2383
 
2384
        l.addi  r4,r0,0x7
2385
        l.sb    0x2(r3),r4
2386
 
2387
        l.addi  r4,r0,0x0
2388
        l.sb    0x1(r3),r4
2389
 
2390
        l.addi  r4,r0,0x3
2391
        l.sb    0x3(r3),r4
2392
 
2393
        l.lbz   r5,3(r3)
2394
        l.ori   r4,r5,0x80
2395
        l.sb    0x3(r3),r4
2396
        l.addi  r4,r0,((UART_DEVISOR>>8) & 0x000000ff)
2397
        l.sb    UART_DLM(r3),r4
2398
        l.addi  r4,r0,((UART_DEVISOR) & 0x000000ff)
2399
        l.sb    UART_DLL(r3),r4
2400
        l.sb    0x3(r3),r5
2401
 
2402
        l.jr    r9
2403
        l.nop
2404
 
2405
_string_copying_linux:
2406
        .string "\n\n\n\n\n\rCopying Linux... \0"
2407
 
2408
_string_ok_booting:
2409
        .string "Ok, booting the kernel.\n\r\0"
2410
 
2411
_string_unhandled_exception:
2412
        .string "\n\rRunarunaround: Unhandled exception 0x\0"
2413
 
2414
_string_epc_prefix:
2415
        .string ": EPC=0x\0"
2416
 
2417
_string_nl:
2418
        .string "\n\r\0"
2419
 
2420
_string_debug_exception:
2421
        .string "\n\r\tDebug: exception 0x\0"
2422
 
2423
_string_debug_esr_prefix:
2424
        .string ", ESR=0x\0"
2425
 
2426
_string_debug_eear_prefix:
2427
        .string ", EEAR=0x\0"
2428
 
2429
_string_dcache_clean:
2430
        .string "dcache cleaning\n\r\0"
2431
 
2432
_string_icache_clean:
2433
        .string "icache cleaning\n\r\0"
2434
 
2435
_string_ic_invalidate:
2436
        .string "\n\r\tic invalidate:  \0"
2437
 
2438
_string_ic_enable:
2439
        .string "\n\ricache enabling\n\r\0"
2440
 
2441
_string_dc_invalidate:
2442
        .string "\n\r\tdc invalidate:  \0"
2443
 
2444
_string_dc_enable:
2445
        .string "\n\rdcache enabling\n\r\0"
2446
 
2447
_string_pbjds:
2448
        .string "[jd]"
2449
 
2450
_string_ed:
2451
        .string "\n\r[debug] "
2452
 
2453
        .global _string_esr_irq_bug
2454
_string_esr_irq_bug:
2455
        .string "\n\rESR external interrupt bug, for details look into entry.S\n\r\0"
2456
 
2457
 
2458
 
2459
/* ========================================[ page aligned structures ]=== */
2460
 
2461
/*
2462
 * .data section should be page aligned
2463
 *      (look into arch/or32/kernel/vmlinux.lds)
2464
 */
2465
        .data
2466
        .global  _sdata
2467
_sdata:
2468
        .align  8192
2469
        .global  _empty_zero_page
2470
_empty_zero_page:
2471
        .space  8192
2472
 
2473
        .global  _swapper_pg_dir
2474
_swapper_pg_dir:
2475
        .space  8192
2476
 
2477
        .global _unhandled_stack
2478
_unhandled_stack:
2479
        .space  8192
2480
_unhandled_stack_top:
2481
 
2482
/* ============================================================[ EOF ]=== */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.