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 7

Go to most recent revision | 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
        // reset the simulation counters
855
        l.nop 5
856
 
857
 
858
hw_breakpoint:
859
#if 0
860
        /* set effective address */
861
        LOAD_SYMBOL_2_GPR(r3,SPR_DVR(0))
862
        LOAD_SYMBOL_2_GPR(r4,_start_kernel)
863
        l.mtspr r3,r4,0x0
864
 
865
        /* control register: present, equal to, instruction fetch EA */
866
        LOAD_SYMBOL_2_GPR(r3,SPR_DCR(0))
867
        LOAD_SYMBOL_2_GPR(r4,0x23)
868
        l.mtspr r3,r4,0x0
869
 
870
        /* control register: present, equal to, store/load EA */
871
//      LOAD_SYMBOL_2_GPR(r3,SPR_DCR(0))
872
//      LOAD_SYMBOL_2_GPR(r4,0xc3)
873
//      l.mtspr r3,r4,0x0
874
 
875
        /* ext watchpoint | watchpoint 0 */
876
        LOAD_SYMBOL_2_GPR(r3,SPR_DMR1)
877
        LOAD_SYMBOL_2_GPR(r4,0x2)
878
        l.mtspr r3,r4,0x0
879
 
880
        /* watchpoint 0 triggers trap instruction, enable counter 0 */
881
        LOAD_SYMBOL_2_GPR(r3,SPR_DMR2)
882
        LOAD_SYMBOL_2_GPR(r4,0x1001)
883
        l.mtspr r3,r4,0x0
884
#endif
885
 
886
#if 0
887
        // this will not work due to trap handler jumping
888
        LOAD_SYMBOL_2_GPR(r3,SPR_DMR1)
889
        LOAD_SYMBOL_2_GPR(r4,0x800000)
890
        l.mtspr r3,r4,0x0
891
#endif
892
 
893
#if 0
894
        /* set effective address */
895
        LOAD_SYMBOL_2_GPR(r3,SPR_DVR(0))
896
        LOAD_SYMBOL_2_GPR(r4,0x100)
897
        l.mtspr r3,r4,0x0
898
 
899
        /* control register: present, not equal to, store/load EA */
900
        LOAD_SYMBOL_2_GPR(r3,SPR_DCR(0))
901
        LOAD_SYMBOL_2_GPR(r4,0xcd)
902
        l.mtspr r3,r4,0x0
903
 
904
        /* ext watchpoint | watchpoint 0 */
905
        LOAD_SYMBOL_2_GPR(r3,SPR_DMR1)
906
        LOAD_SYMBOL_2_GPR(r4,0x2)
907
        l.mtspr r3,r4,0x0
908
 
909
        /* watchpoint 0 triggers trap instruction, enable counter 0 */
910
        LOAD_SYMBOL_2_GPR(r3,SPR_DMR2)
911
        LOAD_SYMBOL_2_GPR(r4,0x1001)
912
        l.mtspr r3,r4,0x0
913
#endif
914
 
915
clear_regs:
916
        /*
917
         * clear all GPRS to increase determinism
918
         */
919
        CLEAR_GPR(r2)
920
        CLEAR_GPR(r3)
921
        CLEAR_GPR(r4)
922
        CLEAR_GPR(r5)
923
        CLEAR_GPR(r6)
924
        CLEAR_GPR(r7)
925
        CLEAR_GPR(r8)
926
        CLEAR_GPR(r9)
927
        CLEAR_GPR(r11)
928
        CLEAR_GPR(r12)
929
        CLEAR_GPR(r13)
930
        CLEAR_GPR(r14)
931
        CLEAR_GPR(r15)
932
        CLEAR_GPR(r16)
933
        CLEAR_GPR(r17)
934
        CLEAR_GPR(r18)
935
        CLEAR_GPR(r19)
936
        CLEAR_GPR(r20)
937
        CLEAR_GPR(r21)
938
        CLEAR_GPR(r22)
939
        CLEAR_GPR(r23)
940
        CLEAR_GPR(r24)
941
        CLEAR_GPR(r25)
942
        CLEAR_GPR(r26)
943
        CLEAR_GPR(r27)
944
        CLEAR_GPR(r28)
945
        CLEAR_GPR(r29)
946
        CLEAR_GPR(r30)
947
        CLEAR_GPR(r31)
948
 
949
jump_start_kernel:
950
        /*
951
         * jump to kernel entry (start_kernel)
952
         */
953
        LOAD_SYMBOL_2_GPR(r30, _start_kernel)
954
        l.jr    r30
955
        l.nop
956
 
957
/* ========================================[ memory controler, cache ]=== */
958
 
959
ENTRY(_mc_init_1)
960
#if   CONFIG_OR32_MC_VERSION==1 && defined CONFIG_OR32_MC_INIT
961
        l.movhi r3,hi(MC_BASE_ADD)
962
        l.ori   r3,r3,lo(MC_BASE_ADD)
963
 
964
        l.addi  r4,r3,MC_CSC(0)
965
        l.movhi r5,hi(FLASH_BASE_ADD)
966
        l.srai  r5,r5,6
967
        l.ori   r5,r5,0x0025
968
        l.sw    0(r4),r5
969
 
970
        l.addi  r4,r3,MC_TMS(0)
971
        l.movhi r5,hi(FLASH_TMS_VAL)
972
        l.ori   r5,r5,lo(FLASH_TMS_VAL)
973
        l.sw    0(r4),r5
974
 
975
        l.addi  r4,r3,MC_BA_MASK
976
        l.addi  r5,r0,MC_MASK_VAL
977
        l.sw    0(r4),r5
978
 
979
        l.addi  r4,r3,MC_CSR
980
        l.movhi r5,hi(MC_CSR_VAL)
981
        l.ori   r5,r5,lo(MC_CSR_VAL)
982
        l.sw    0(r4),r5
983
 
984
        l.addi  r4,r3,MC_TMS(1)
985
        l.movhi r5,hi(SDRAM_TMS_VAL)
986
        l.ori   r5,r5,lo(SDRAM_TMS_VAL)
987
        l.sw    0(r4),r5
988
 
989
        l.addi  r4,r3,MC_CSC(1)
990
        l.movhi r5,hi(SDRAM_BASE_ADD)
991
        l.srai  r5,r5,6
992
        l.ori   r5,r5,0x0411
993
        l.sw    0(r4),r5
994
 
995
#ifdef FBMEM_BASE_ADD
996
        l.addi  r4,r3,MC_CSC(2)
997
        l.movhi r5,hi(FBMEM_BASE_ADD)
998
        l.srai  r5,r5,6
999
        l.ori   r5,r5,0x0005
1000
        l.sw    0(r4),r5
1001
 
1002
        l.addi  r4,r3,MC_TMS(2)
1003
        l.movhi r5,0xffff
1004
        l.ori   r5,r5,0xffff
1005
        l.sw    0(r4),r5
1006
#endif /* FBMEM_BASE_ADD */
1007
#endif /* CONFIG_OR32_MC_VERSION==1 && defined CONFIG_OR32_MC_INIT */
1008
        l.jr    r9
1009
        l.nop
1010
 
1011
ENTRY(_mc_init_2)
1012
#if   CONFIG_OR32_MC_VERSION==2 && defined CONFIG_OR32_MC_INIT
1013
        l.movhi r3,hi(MC_BASE_ADD)
1014
        l.ori   r3,r3,lo(MC_BASE_ADD)
1015
 
1016
        l.addi  r4,r3,MC_BAR_0
1017
        l.movhi r5,hi(FLASH_BAR_VAL)
1018
        l.sw    0(r4),r5
1019
 
1020
        l.addi  r4,r3,MC_AMR_0
1021
        l.movhi r5,hi(FLASH_AMR_VAL)
1022
        l.sw    0(r4),r5
1023
 
1024
        l.addi  r4,r3,MC_WTR_0
1025
        l.movhi r5,hi(FLASH_WTR_VAL)
1026
        l.ori   r5,r5,lo(FLASH_WTR_VAL)
1027
        l.sw    0(r4),r5
1028
 
1029
        l.addi  r4,r3,MC_RTR_0
1030
        l.movhi r5,hi(FLASH_RTR_VAL)
1031
        l.ori   r5,r5,lo(FLASH_RTR_VAL)
1032
        l.sw    0(r4),r5
1033
 
1034
        l.addi  r4,r3,MC_OSR
1035
        l.movhi r5,hi(0x40000000)
1036
        l.ori   r5,r5,lo(0x40000000)
1037
        l.sw    0(r4),r5
1038
 
1039
        l.addi  r4,r3,MC_BAR_4
1040
        l.movhi r5,hi(SDRAM_BAR_VAL)
1041
        l.sw    0(r4),r5
1042
 
1043
        l.addi  r4,r3,MC_AMR_4
1044
        l.movhi r5,hi(SDRAM_AMR_VAL)
1045
        l.sw    0(r4),r5
1046
 
1047
        l.addi  r4,r3,MC_CCR_4
1048
        l.movhi r5,hi(MC_CCR_4_VAL_DISABLED)
1049
        l.ori   r5,r5,lo(MC_CCR_4_VAL_DISABLED)
1050
        l.sw    0(r4),r5
1051
 
1052
        l.addi  r4,r3,MC_RATR
1053
        l.movhi r5,hi(SDRAM_RATR_VAL)
1054
        l.ori   r5,r5,lo(SDRAM_RATR_VAL)
1055
        l.sw    0(r4),r5
1056
 
1057
        l.addi  r4,r3,MC_RCDR
1058
        l.movhi r5,hi(SDRAM_RCDR_VAL)
1059
        l.ori   r5,r5,lo(SDRAM_RCDR_VAL)
1060
        l.sw    0(r4),r5
1061
 
1062
        l.addi  r4,r3,MC_RCTR
1063
        l.movhi r5,hi(SDRAM_RCTR_VAL)
1064
        l.ori   r5,r5,lo(SDRAM_RCTR_VAL)
1065
        l.sw    0(r4),r5
1066
 
1067
        l.addi  r4,r3,MC_REFCTR
1068
        l.movhi r5,hi(SDRAM_REFCTR_VAL)
1069
        l.ori   r5,r5,lo(SDRAM_REFCTR_VAL)
1070
        l.sw    0(r4),r5
1071
 
1072
        l.addi  r4,r3,MC_PTR
1073
        l.movhi r5,hi(SDRAM_PTR_VAL)
1074
        l.ori   r5,r5,lo(SDRAM_PTR_VAL)
1075
        l.sw    0(r4),r5
1076
 
1077
        l.addi  r4,r3,MC_RRDR
1078
        l.movhi r5,hi(SDRAM_RRDR_VAL)
1079
        l.ori   r5,r5,lo(SDRAM_RRDR_VAL)
1080
        l.sw    0(r4),r5
1081
 
1082
        l.addi  r4,r3,MC_WRTR
1083
        l.movhi r5,hi(SDRAM_WRTR_VAL)
1084
        l.ori   r5,r5,lo(SDRAM_WRTR_VAL)
1085
        l.sw    0(r4),r5
1086
 
1087
        l.addi  r4,r3,MC_RIR
1088
        l.movhi r5,hi(SDRAM_RIR_VAL)
1089
        l.ori   r5,r5,lo(SDRAM_RIR_VAL)
1090
        l.sw    0(r4),r5
1091
 
1092
        l.addi  r4,r3,MC_OSR
1093
        l.movhi r5,hi(0x5e000000)
1094
        l.ori   r5,r5,lo(0x5e000000)
1095
        l.sw    0(r4),r5
1096
 
1097
        l.addi  r4,r3,MC_ORR
1098
        l.sw    0(r4),r5
1099
 
1100
        l.addi  r4,r3,MC_OSR
1101
        l.movhi r5,hi(0x6e000000)
1102
        l.ori   r5,r5,lo(0x6e000000)
1103
        l.sw    0(r4),r5
1104
 
1105
        l.addi  r4,r3,MC_ORR
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
        l.sw    0(r4),r5
1111
        l.sw    0(r4),r5
1112
        l.sw    0(r4),r5
1113
        l.sw    0(r4),r5
1114
 
1115
        l.addi  r4,r3,MC_OSR
1116
        l.movhi r5,hi(MC_OSR_VAL)
1117
        l.ori   r5,r5,lo(MC_OSR_VAL)
1118
        l.sw    0(r4),r5
1119
 
1120
        l.addi  r4,r3,MC_ORR
1121
        l.sw    0(r4),r5
1122
 
1123
        l.addi  r4,r3,MC_CCR_4
1124
        l.movhi r5,hi(MC_CCR_4_VAL_ENABLED)
1125
        l.ori   r5,r5,lo(MC_CCR_4_VAL_ENABLED)
1126
        l.sw    0(r4),r5
1127
#endif /* CONFIG_OR32_MC_VERSION==2 && defined CONFIG_OR32_MC_INIT */
1128
 
1129
        l.jr    r9
1130
        l.nop
1131
 
1132
        /* aligment here so we don't change memory offsets with
1133
         * memory controler defined
1134
         */
1135
        .align 0x2000
1136
 
1137
#ifdef CONFIG_OR32_CACHE_DEBUG
1138
ENTRY(_ic_enable)
1139
        SF_DISABLED(r6,INIT_IC_ADDR)
1140
        l.bf    9f
1141
        l.nop
1142
 
1143
        EMERGENCY_PRINT_STORE_GPR9
1144
        LOAD_SYMBOL_2_GPR(r4,_string_icache_clean)
1145
        tophys  (r3,r4)
1146
        l.jal   _emergency_print
1147
        l.nop
1148
 
1149
        /* Disable IC */
1150
        l.mfspr r6,r0,SPR_SR
1151
        l.addi  r5,r0,-1
1152
        l.xori  r5,r5,SPR_SR_ICE
1153
        l.and   r5,r6,r5
1154
        l.mtspr r0,r5,SPR_SR
1155
 
1156
        /* Invalidate IC */
1157
        l.addi  r6,r0,0
1158
        l.addi  r5,r0,IC_SIZE
1159
1:
1160
#if 0
1161
        LOAD_SYMBOL_2_GPR(r4,_string_ic_invalidate)
1162
        tophys  (r3,r4)
1163
        l.jal   _emergency_print
1164
        l.nop
1165
 
1166
        l.jal   _emergency_print_nr
1167
        l.addi  r3,r6,0
1168
#endif
1169
        l.mtspr r0,r6,SPR_ICBIR
1170
        l.sfne  r6,r5
1171
        l.bf    1b
1172
        l.addi  r6,r6,IC_LINE
1173
 
1174
        LOAD_SYMBOL_2_GPR(r4,_string_ic_enable)
1175
        tophys  (r3,r4)
1176
        l.jal   _emergency_print
1177
        l.nop
1178
 
1179
        /* Enable IC */
1180
        l.mfspr r6,r0,SPR_SR
1181
        l.ori   r6,r6,SPR_SR_ICE
1182
        l.mtspr r0,r6,SPR_SR
1183
        l.nop
1184
        l.nop
1185
        l.nop
1186
        l.nop
1187
        l.nop
1188
        l.nop
1189
        l.nop
1190
        l.nop
1191
        l.nop
1192
        l.nop
1193
        EMERGENCY_PRINT_LOAD_GPR9
1194
9:
1195
        l.jr    r9
1196
        l.nop
1197
#else
1198
ENTRY(_ic_enable)
1199
        SF_DISABLED(r6,INIT_IC_ADDR)
1200
        l.bf    9f
1201
        l.nop
1202
 
1203
        /* Disable IC */
1204
        l.mfspr r6,r0,SPR_SR
1205
        l.addi  r5,r0,-1
1206
        l.xori  r5,r5,SPR_SR_ICE
1207
        l.and   r5,r6,r5
1208
        l.mtspr r0,r5,SPR_SR
1209
 
1210
        /* Invalidate IC */
1211
        l.addi  r6,r0,0
1212
        l.addi  r5,r0,IC_SIZE
1213
1:
1214
        l.mtspr r0,r6,SPR_ICBIR
1215
        l.sfne  r6,r5
1216
        l.bf    1b
1217
        l.addi  r6,r6,IC_LINE
1218
 
1219
        /* Enable IC */
1220
        l.mfspr r6,r0,SPR_SR
1221
        l.ori   r6,r6,SPR_SR_ICE
1222
        l.mtspr r0,r6,SPR_SR
1223
        l.nop
1224
        l.nop
1225
        l.nop
1226
        l.nop
1227
        l.nop
1228
        l.nop
1229
        l.nop
1230
        l.nop
1231
        l.nop
1232
        l.nop
1233
9:
1234
        l.jr    r9
1235
        l.nop
1236
#endif
1237
 
1238
#ifdef CONFIG_OR32_CACHE_DEBUG
1239
ENTRY(_dc_enable)
1240
        SF_DISABLED(r6,INIT_DC_ADDR)
1241
        l.bf    9f
1242
        l.nop
1243
 
1244
        EMERGENCY_PRINT_STORE_GPR9
1245
        LOAD_SYMBOL_2_GPR(r4,_string_dcache_clean)
1246
        tophys  (r3,r4)
1247
        l.jal   _emergency_print
1248
        l.nop
1249
 
1250
        /* Disable DC */
1251
        l.mfspr r6,r0,SPR_SR
1252
        l.addi  r5,r0,-1
1253
        l.xori  r5,r5,SPR_SR_DCE
1254
        l.and   r5,r6,r5
1255
        l.mtspr r0,r5,SPR_SR
1256
 
1257
        /* Flush DC */
1258
        l.addi  r6,r0,0
1259
        l.addi  r5,r0,DC_SIZE
1260
1:
1261
#ifdef CONFIG_OR32_CACHE_DEBUG
1262
        LOAD_SYMBOL_2_GPR(r4,_string_dc_invalidate)
1263
        tophys  (r3,r4)
1264
        l.jal   _emergency_print
1265
        l.nop
1266
 
1267
        l.jal   _emergency_print_nr
1268
        l.addi  r3,r6,0
1269
#endif
1270
 
1271
        l.mtspr r0,r6,SPR_DCBIR
1272
        l.sfne  r6,r5
1273
        l.bf    1b
1274
        l.addi  r6,r6,DC_LINE
1275
 
1276
        LOAD_SYMBOL_2_GPR(r4,_string_dc_enable)
1277
        tophys  (r3,r4)
1278
        l.jal   _emergency_print
1279
        l.nop
1280
 
1281
        /* Enable DC */
1282
        l.mfspr r6,r0,SPR_SR
1283
        l.ori   r6,r6,SPR_SR_DCE
1284
        l.mtspr r0,r6,SPR_SR
1285
        EMERGENCY_PRINT_LOAD_GPR9
1286
9:
1287
        l.jr    r9
1288
        l.nop
1289
#else
1290
ENTRY(_dc_enable)
1291
        SF_DISABLED(r6,INIT_DC_ADDR)
1292
        l.bf    9f
1293
        l.nop
1294
 
1295
        /* Disable DC */
1296
        l.mfspr r6,r0,SPR_SR
1297
        l.addi  r5,r0,-1
1298
        l.xori  r5,r5,SPR_SR_DCE
1299
        l.and   r5,r6,r5
1300
        l.mtspr r0,r5,SPR_SR
1301
 
1302
        /* Flush DC */
1303
        l.addi  r6,r0,0
1304
        l.addi  r5,r0,DC_SIZE
1305
1:
1306
        l.mtspr r0,r6,SPR_DCBIR
1307
        l.sfne  r6,r5
1308
        l.bf    1b
1309
        l.addi  r6,r6,DC_LINE
1310
 
1311
        /* Enable DC */
1312
        l.mfspr r6,r0,SPR_SR
1313
        l.ori   r6,r6,SPR_SR_DCE
1314
        l.mtspr r0,r6,SPR_SR
1315
9:
1316
        l.jr    r9
1317
        l.nop
1318
#endif
1319
 
1320
/* ===============================================[ page table masks ]=== */
1321
 
1322
/* bit 4 is used in hardware as write back cache bit. we never use this bit
1323
 * explicitly, so we can reuse it as _PAGE_FILE bit and mask it out when
1324
 * writing into hardware pte's
1325
 */
1326
 
1327
#define DTLB_UP_CONVERT_MASK  0x3fa
1328
#define ITLB_UP_CONVERT_MASK  0x3a
1329
 
1330
/* for SMP we'd have (this is a bit subtle, CC must be always set
1331
 * for SMP, but since we have _PAGE_PRESENT bit always defined
1332
 * we can just modify the mask)
1333
 */
1334
#define DTLB_SMP_CONVERT_MASK  0x3fb
1335
#define ITLB_SMP_CONVERT_MASK  0x3b
1336
 
1337
/* ==============================================[ DTLB miss handler ]=== */
1338
 
1339
        .global _dtlb_miss_handler
1340
_dtlb_miss_handler:
1341
        EXCEPTION_DEBUG_VALUE_ER(0x900)
1342
 
1343
        EXCEPTION_STORE_GPR2
1344
        EXCEPTION_STORE_GPR3
1345
        EXCEPTION_STORE_GPR4
1346
        EXCEPTION_STORE_GPR5
1347
        /*
1348
         * get EA of the miss
1349
         */
1350
        l.mfspr r2,r0,SPR_EEAR_BASE
1351
        /*
1352
         * pmd = (pmd_t *)(current_pgd + pgd_index(daddr));
1353
         */
1354
        GET_CURRENT_PGD(r3,r5)          // r3 is current_pgd, r5 is temp
1355
        l.srli  r4,r2,0x18              // >> PAGE_SHIFT + (PAGE_SHIFT - 2)
1356
        l.slli  r4,r4,0x2               // to get address << 2
1357
        l.add   r5,r4,r3                // r4 is pgd_index(daddr)
1358
        /*
1359
         * if (pmd_none(*pmd))
1360
         *   goto pmd_none:
1361
         */
1362
        tophys  (r4,r5)
1363
        l.lwz   r3,0x0(r4)              // get *pmd value
1364
        l.sfne  r3,r0
1365
        l.bnf   d_pmd_none
1366
        l.andi  r3,r3,0x1fff            // ~PAGE_MASK
1367
        /*
1368
         * if (pmd_bad(*pmd))
1369
         *   pmd_clear(pmd)
1370
         *   goto pmd_bad:
1371
         */
1372
//      l.sfeq  r3,r0                   // check *pmd value
1373
//      l.bf    d_pmd_good
1374
        l.addi  r3,r0,0xffffe000        // PAGE_MASK
1375
//      l.j     d_pmd_bad
1376
//      l.sw    0x0(r4),r0              // clear pmd
1377
d_pmd_good:
1378
        /*
1379
         * pte = *pte_offset(pmd, daddr);
1380
         */
1381
        l.lwz   r4,0x0(r4)              // get **pmd value
1382
        l.and   r4,r4,r3                // & PAGE_MASK
1383
        l.srli  r5,r2,0xd               // >> PAGE_SHIFT, r2 == EEAR
1384
        l.andi  r3,r5,0x7ff             // (1UL << PAGE_SHIFT - 2) - 1
1385
        l.slli  r3,r3,0x2               // to get address << 2
1386
        l.add   r3,r3,r4
1387
        l.lwz   r2,0x0(r3)              // this is pte at last
1388
        /*
1389
         * if (!pte_present(pte))
1390
         */
1391
        l.andi  r4,r2,0x1
1392
        l.sfne  r4,r0                   // is pte present
1393
        l.bnf   d_pte_not_present
1394
        l.addi  r3,r0,0xffffe3fa        // PAGE_MASK | DTLB_UP_CONVERT_MASK
1395
        /*
1396
         * fill DTLB TR register
1397
         */
1398
        l.and   r4,r2,r3                // apply the mask
1399
        l.andi  r5,r5,0x3f              // calc offset:  & (NUM_TLB_ENTRIES-1), NUM_TLB_ENTRIES == 64
1400
        l.mtspr r5,r4,SPR_DTLBTR_BASE(0)
1401
        /*
1402
         * fill DTLB MR register
1403
         */
1404
        l.mfspr r2,r0,SPR_EEAR_BASE
1405
        l.addi  r3,r0,0xffffe000        // PAGE_MASK
1406
        l.and   r4,r2,r3                // apply PAGE_MASK to EA (__PHX__ do we really need this?)
1407
        l.ori   r4,r4,0x1               // set hardware valid bit: DTBL_MR entry
1408
        l.mtspr r5,r4,SPR_DTLBMR_BASE(0)
1409
 
1410
#ifndef CONFIG_DMMU_WORKS
1411
        l.addi  r5,r5,1
1412
        l.andi  r5,r5,0x3f
1413
        l.mtspr r5,r0,SPR_DTLBMR_BASE(0)
1414
        l.addi  r5,r5,-2
1415
        l.andi  r5,r5,0x3f
1416
        l.mtspr r5,r0,SPR_DTLBMR_BASE(0)
1417
#endif
1418
        EXCEPTION_LOAD_GPR2
1419
        EXCEPTION_LOAD_GPR3
1420
        EXCEPTION_LOAD_GPR4
1421
        EXCEPTION_LOAD_GPR5
1422
        l.rfe
1423
d_pmd_bad:
1424
        l.nop   1
1425
        EXCEPTION_LOAD_GPR2
1426
        EXCEPTION_LOAD_GPR3
1427
        EXCEPTION_LOAD_GPR4
1428
        EXCEPTION_LOAD_GPR5
1429
        l.rfe
1430
d_pmd_none:
1431
d_pte_not_present:
1432
        EXCEPTION_LOAD_GPR2
1433
        EXCEPTION_LOAD_GPR3
1434
        EXCEPTION_LOAD_GPR4
1435
        EXCEPTION_LOAD_GPR5
1436
        // __PHX__ for debugging purposes
1437
        DEBUG_TLB_PROBE(0x903)
1438
        l.j     _dispatch_do_dpage_fault
1439
        l.nop
1440
 
1441
/* ==============================================[ ITLB miss handler ]=== */
1442
        .global _itlb_miss_handler
1443
_itlb_miss_handler:
1444
        EXCEPTION_DEBUG_VALUE_ER(0xa00)
1445
 
1446
        EXCEPTION_STORE_GPR2
1447
        EXCEPTION_STORE_GPR3
1448
        EXCEPTION_STORE_GPR4
1449
        EXCEPTION_STORE_GPR5
1450
        /*
1451
         * get EA of the miss
1452
         */
1453
        l.mfspr r2,r0,SPR_EEAR_BASE
1454
 
1455
#ifndef CONFIG_IMMU_WORKS
1456
        // check for exception in delay slot and on page boundry
1457
        l.andi  r3,r2,0x1fff            // PAGE_SIZE - 1
1458
        l.sfeqi r3,0
1459
        l.bnf   1f
1460
        l.nop                           // we are on page boundry
1461
        l.mfspr r4,r0,SPR_EPCR_BASE
1462
        l.sfeq  r4,r2
1463
        l.bf    1f                      // EPC and EEA are equal -> not in delay slot
1464
        l.nop
1465
 
1466
        l.mfspr r5,r0,SPR_ESR_BASE      // are we in user mode
1467
        l.andi  r5,r5,SPR_SR_SM
1468
        l.sfeqi r5,0
1469
        l.bnf   2f                      // kernel mode
1470
        l.nop
1471
 
1472
        // user mode: no fixup
1473
        EXCEPTION_STORE_GPR9
1474
        l.jal   _emergency_print
1475
        l.ori   r3,r0,lo(_string_pbjds) // page boundry, jump, delay slot
1476
        l.nop   0x1
1477
        l.j     1f
1478
        EXCEPTION_LOAD_GPR9
1479
 
1480
2:
1481
        EXCEPTION_STORE_GPR6
1482
        EXCEPTION_STORE_GPR9
1483
 
1484
        // ok, we are in trouble...
1485
        l.jal   _immu_trampoline_workaround
1486
        l.nop
1487
 
1488
        EXCEPTION_LOAD_GPR2
1489
        EXCEPTION_LOAD_GPR3
1490
        EXCEPTION_LOAD_GPR4
1491
        EXCEPTION_LOAD_GPR5
1492
        EXCEPTION_LOAD_GPR6
1493
        EXCEPTION_LOAD_GPR9
1494
        l.rfe
1495
 
1496
1:      // this is not delay slot exception of the page boundry
1497
#endif
1498
 
1499
        /*
1500
         * pmd = (pmd_t *)(current_pgd + pgd_index(daddr));
1501
         *
1502
         */
1503
        GET_CURRENT_PGD(r3,r5)          // r3 is current_pgd, r5 is temp
1504
        l.srli  r4,r2,0x18              // >> PAGE_SHIFT + (PAGE_SHIFT - 2)
1505
        l.slli  r4,r4,0x2               // to get address << 2
1506
        l.add   r5,r4,r3                // r4 is pgd_index(daddr)
1507
        /*
1508
         * if (pmd_none(*pmd))
1509
         *   goto pmd_none:
1510
         */
1511
        tophys  (r4,r5)
1512
        l.lwz   r3,0x0(r4)              // get *pmd value
1513
        l.sfne  r3,r0
1514
        l.bnf   i_pmd_none
1515
        l.andi  r3,r3,0x1fff            // ~PAGE_MASK
1516
        /*
1517
         * if (pmd_bad(*pmd))
1518
         *   pmd_clear(pmd)
1519
         *   goto pmd_bad:
1520
         */
1521
 
1522
//      l.sfeq  r3,r0                   // check *pmd value
1523
//      l.bf    i_pmd_good
1524
        l.addi  r3,r0,0xffffe000        // PAGE_MASK
1525
//      l.j     i_pmd_bad
1526
//      l.sw    0x0(r4),r0              // clear pmd
1527
 
1528
i_pmd_good:
1529
        /*
1530
         * pte = *pte_offset(pmd, iaddr);
1531
         *
1532
         */
1533
        l.lwz   r4,0x0(r4)              // get **pmd value
1534
        l.and   r4,r4,r3                // & PAGE_MASK
1535
        l.srli  r5,r2,0xd               // >> PAGE_SHIFT, r2 == EEAR
1536
        l.andi  r3,r5,0x7ff             // (1UL << PAGE_SHIFT - 2) - 1
1537
        l.slli  r3,r3,0x2               // to get address << 2
1538
        l.add   r3,r3,r4
1539
        l.lwz   r2,0x0(r3)              // this is pte at last
1540
        /*
1541
         * if (!pte_present(pte))
1542
         *
1543
         */
1544
        l.andi  r4,r2,0x1
1545
        l.sfne  r4,r0                   // is pte present
1546
        l.bnf   i_pte_not_present
1547
        l.addi  r3,r0,0xffffe03a        // PAGE_MASK | ITLB_UP_CONVERT_MASK
1548
        /*
1549
         * fill ITLB TR register
1550
         */
1551
        l.and   r4,r2,r3                // apply the mask
1552
        l.andi  r3,r2,0x7c0             // _PAGE_EXEC | _PAGE_SRE | _PAGE_SWE |  _PAGE_URE | _PAGE_UWE
1553
//      l.andi  r3,r2,0x400             // _PAGE_EXEC
1554
        l.sfeq  r3,r0
1555
        l.bf    itlb_tr_fill //_workaround
1556
        l.andi  r5,r5,0x3f              // calc offset:  & (NUM_TLB_ENTRIES-1), NUM_TLB_ENTRIES == 64
1557
/*
1558
 * __PHX__ :: fixme
1559
 * we should not just blindly set executable flags,
1560
 * but it does help with ping. the clean way would be to find out
1561
 * (and fix it) why stack doesn't have execution permissions
1562
 */
1563
 
1564
itlb_tr_fill_workaround:
1565
        l.ori   r4,r4,0xc0              // | (SPR_ITLBTR_UXE | ITLBTR_SXE)
1566
itlb_tr_fill:
1567
        l.mtspr r5,r4,SPR_ITLBTR_BASE(0)
1568
        /*
1569
         * fill DTLB MR register
1570
         */
1571
        l.mfspr r2,r0,SPR_EEAR_BASE
1572
        l.addi  r3,r0,0xffffe000        // PAGE_MASK
1573
        l.and   r4,r2,r3                // apply PAGE_MASK to EA (__PHX__ do we really need this?)
1574
        l.ori   r4,r4,0x1               // set hardware valid bit: DTBL_MR entry
1575
        l.mtspr r5,r4,SPR_ITLBMR_BASE(0)
1576
 
1577
#ifndef CONFIG_IMMU_WORKS
1578
        l.addi  r5,r5,1
1579
        l.andi  r5,r5,0x3f
1580
        l.mtspr r5,r0,SPR_ITLBMR_BASE(0)
1581
        l.addi  r5,r5,-2
1582
        l.andi  r5,r5,0x3f
1583
        l.mtspr r5,r0,SPR_ITLBMR_BASE(0)
1584
#endif
1585
        EXCEPTION_LOAD_GPR2
1586
        EXCEPTION_LOAD_GPR3
1587
        EXCEPTION_LOAD_GPR4
1588
        EXCEPTION_LOAD_GPR5
1589
        l.rfe
1590
 
1591
i_pmd_bad:
1592
        l.nop   1
1593
        EXCEPTION_LOAD_GPR2
1594
        EXCEPTION_LOAD_GPR3
1595
        EXCEPTION_LOAD_GPR4
1596
        EXCEPTION_LOAD_GPR5
1597
        l.rfe
1598
i_pmd_none:
1599
i_pte_not_present:
1600
        EXCEPTION_LOAD_GPR2
1601
        EXCEPTION_LOAD_GPR3
1602
        EXCEPTION_LOAD_GPR4
1603
        EXCEPTION_LOAD_GPR5
1604
        // __PHX__ for debugging purposes
1605
        DEBUG_TLB_PROBE(0xa04)
1606
        l.j     _dispatch_do_ipage_fault
1607
        l.nop
1608
 
1609
/* ==============================================[ boot tlb handlers ]=== */
1610
/* ---[ boot dtlb miss handler ]----------------------------------------- */
1611
 
1612
boot_dtlb_miss_handler:
1613
 
1614
/* mask for DTLB_MR register: - (0) sets V (valid) bit,
1615
 *                            - (31-12) sets bits belonging to VPN (31-12)
1616
 */
1617
#define DTLB_MR_MASK 0xfffff001
1618
 
1619
/* mask for DTLB_TR register: - (2) sets CI (cache inhibit) bit,
1620
 *                            - (4) sets A (access) bit,
1621
 *                            - (5) sets D (dirty) bit,
1622
 *                            - (8) sets SRE (superuser read) bit
1623
 *                            - (9) sets SWE (superuser write) bit
1624
 *                            - (31-12) sets bits belonging to VPN (31-12)
1625
 */
1626
#define DTLB_TR_MASK 0xfffff332
1627
 
1628
#define VPN_MASK 0xfffff000
1629
#define PPN_MASK 0xfffff000
1630
 
1631
/*
1632
 * a % 64 = a & MOD_64_MASK
1633
 */
1634
#define MOD_64_MASK 0x3f
1635
 
1636
#define MOD_64(dest,src)          \
1637
        l.andi  dest,src,MOD_64_MASK
1638
 
1639
        EXCEPTION_DEBUG_VALUE_ER(0x9b0)
1640
        EXCEPTION_STORE_GPR6
1641
 
1642
        l.mfspr r6,r0,SPR_ESR_BASE         //
1643
        l.andi  r6,r6,SPR_SR_SM            // are we in kernel mode ?
1644
        l.sfeqi r6,0                       // r6 == 0x1 --> SM
1645
        l.bf    exit_with_no_dtranslation  //
1646
        l.nop
1647
 
1648
        /* this could be optimized by moving storing of
1649
         * non r6 registers here, and jumping r6 restore
1650
         * if not in supervisor mode
1651
         */
1652
 
1653
        EXCEPTION_STORE_GPR2
1654
        EXCEPTION_STORE_GPR3
1655
        EXCEPTION_STORE_GPR4
1656
        EXCEPTION_STORE_GPR5
1657
 
1658
        l.mfspr r4,r0,SPR_EEAR_BASE        // get the offending EA
1659
 
1660
        /* do not do any translation if EA is above DRAM_END */
1661
        LOAD_SYMBOL_2_GPR(r6,DRAM_END)
1662
        l.sfgtu r4,r6                      // flag if EA larger than DRAM_END
1663
        l.bf    exit_with_no_dtranslation
1664
        /* delay slot */
1665
 
1666
 
1667
immediate_translation:
1668
        CLEAR_GPR(r6)
1669
 
1670
        l.srli  r3,r4,0xd                  // r3 <- r4 / 8192 (sets are relative to page size (8Kb) NOT VPN size (4Kb)
1671
        l.andi  r2,r3,MOD_64_MASK          // r2 <- r3 % 64: ok this is SET
1672
        l.or    r6,r6,r4                   // r6 <- r4
1673
        l.ori   r6,r6,~(VPN_MASK)          // r6 <- VPN :VPN .xfff - clear up lo(r6) to 0x**** *fff
1674
        l.movhi r5,hi(DTLB_MR_MASK)        // r5 <- ffff:0000.x000
1675
        l.ori   r5,r5,lo(DTLB_MR_MASK)     // r5 <- ffff:1111.x001 - apply DTLB_MR_MASK
1676
        l.and   r5,r5,r6                   // r5 <- VPN :VPN .x001 - we have DTLBMR entry
1677
        l.mtspr r2,r5,SPR_DTLBMR_BASE(0)   // set DTLBMR
1678
 
1679
        /* set up DTLB with no translation for EA <= 0xbfffffff */
1680
        LOAD_SYMBOL_2_GPR(r6,0xbfffffff)
1681
        l.sfgeu  r6,r4                     // flag if r6 >= r4 (if 0xbfffffff >= EA)
1682
        l.bf     1f                        // goto out
1683
        l.and    r3,r4,r4                  // delay slot :: 24 <- r4 (if flag==1)
1684
 
1685
        tophys(r3,r4)                      // r3 <- PA
1686
1:
1687
        l.ori   r3,r3,~(PPN_MASK)          // r3 <- PPN :PPN .xfff - clear up lo(r6) to 0x**** *fff
1688
        l.movhi r5,hi(DTLB_TR_MASK)        // r5 <- ffff:0000.x000
1689
        l.ori   r5,r5,lo(DTLB_TR_MASK)     // r5 <- ffff:1111.x330 - apply DTLB_MR_MASK
1690
        l.and   r5,r5,r3                   // r5 <- PPN :PPN .x330 - we have DTLBTR entry
1691
        l.mtspr r2,r5,SPR_DTLBTR_BASE(0)   // set DTLBTR
1692
 
1693
#ifndef CONFIG_DMMU_WORKS
1694
        l.addi  r2,r2,1
1695
        l.andi  r2,r2,0x3f
1696
        l.mtspr r2,r0,SPR_DTLBMR_BASE(0)
1697
        l.addi  r2,r2,-2
1698
        l.andi  r2,r2,0x3f
1699
        l.mtspr r2,r0,SPR_DTLBMR_BASE(0)
1700
#endif
1701
 
1702
        EXCEPTION_LOAD_GPR6
1703
        EXCEPTION_LOAD_GPR5
1704
        EXCEPTION_LOAD_GPR4
1705
        EXCEPTION_LOAD_GPR3
1706
        EXCEPTION_LOAD_GPR2
1707
 
1708
        l.rfe                              // SR <- ESR, PC <- EPC
1709
 
1710
exit_with_no_dtranslation:
1711
        /* EA out of memory or not in supervisor mode */
1712
        EXCEPTION_LOAD_GPR6
1713
        EXCEPTION_LOAD_GPR4
1714
        l.j     _dispatch_bus_fault
1715
 
1716
/* ---[ boot itlb miss handler ]----------------------------------------- */
1717
 
1718
boot_itlb_miss_handler:
1719
 
1720
/* mask for ITLB_MR register: - sets V (valid) bit,
1721
 *                            - sets bits belonging to VPN (15-12)
1722
 */
1723
#define ITLB_MR_MASK 0xfffff001
1724
 
1725
/* mask for ITLB_TR register: - sets A (access) bit,
1726
 *                            - sets SXE (superuser execute) bit
1727
 *                            - sets bits belonging to VPN (15-12)
1728
 */
1729
#define ITLB_TR_MASK 0xfffff050
1730
 
1731
#define VPN_MASK 0xfffff000
1732
#define PPN_MASK 0xfffff000
1733
 
1734
/*
1735
 * a % 64 = a & MOD_64_MASK
1736
 */
1737
#define MOD_64_MASK 0x3f
1738
 
1739
#define MOD_64(dest,src)          \
1740
        l.andi  dest,src,MOD_64_MASK
1741
 
1742
        EXCEPTION_DEBUG_VALUE_ER(0xab0)
1743
 
1744
        EXCEPTION_STORE_GPR2
1745
        EXCEPTION_STORE_GPR3
1746
        EXCEPTION_STORE_GPR4
1747
        EXCEPTION_STORE_GPR5
1748
        EXCEPTION_STORE_GPR6
1749
 
1750
        l.mfspr r6,r0,SPR_ESR_BASE         //
1751
        l.andi  r6,r6,SPR_SR_SM            // are we in kernel mode ?
1752
        l.sfeqi r6,0                       // r6 == 0x1 --> SM
1753
        l.bf    exit_with_no_itranslation
1754
        l.nop
1755
 
1756
#ifndef CONFIG_IMMU_WORKS
1757
        l.mfspr r2,r0,SPR_EEAR_BASE
1758
 
1759
        // check for exception in delay slot and on page boundry
1760
        l.andi  r3,r2,0x1fff            // PAGE_SIZE - 1
1761
        l.sfeqi r3,0
1762
        l.bnf   1f
1763
        l.nop                           // we are on page boundry
1764
        l.mfspr r4,r0,SPR_EPCR_BASE
1765
        l.sfeq  r4,r2
1766
        l.bf    1f                      // EPC and EEA are equal -> not in delay slot
1767
        l.nop
1768
 
1769
        EXCEPTION_STORE_GPR6
1770
        EXCEPTION_STORE_GPR9
1771
        // ok, we are in trouble...
1772
        l.jal   _immu_trampoline_workaround
1773
        l.nop
1774
 
1775
        EXCEPTION_LOAD_GPR2
1776
        EXCEPTION_LOAD_GPR3
1777
        EXCEPTION_LOAD_GPR4
1778
        EXCEPTION_LOAD_GPR5
1779
        EXCEPTION_LOAD_GPR6
1780
        EXCEPTION_LOAD_GPR9
1781
        l.rfe
1782
 
1783
1:      // this is not delay slot exception of the page boundry
1784
#endif
1785
 
1786
 
1787
        l.mfspr r4,r0,SPR_EEAR_BASE        // get the offending EA
1788
 
1789
        /* do not do any translation if EA is above DRAM_END */
1790
        LOAD_SYMBOL_2_GPR(r6,DRAM_END)
1791
        l.sfgtu  r4,r6                     // flag if EA larger than DRAM_END
1792
        l.bf     exit_with_no_itranslation
1793
        l.nop
1794
 
1795
        CLEAR_GPR(r6)
1796
 
1797
        l.srli  r3,r4,0xd                  // r3 <- r4 / 8192 (sets are relative to page size (8Kb) NOT VPN size (4Kb)
1798
        l.andi  r2,r3,MOD_64_MASK          // r2 <- r3 % 64: ok this is SET
1799
        l.or    r6,r6,r4                   // r6 <- r4
1800
        l.ori   r6,r6,~(VPN_MASK)          // r6 <- VPN :VPN .xfff - clear up lo(r6) to 0x**** *fff
1801
        l.movhi r5,hi(ITLB_MR_MASK)        // r5 <- ffff:0000.x000
1802
        l.ori   r5,r5,lo(ITLB_MR_MASK)     // r5 <- ffff:1111.x001 - apply ITLB_MR_MASK
1803
        l.and   r5,r5,r6                   // r5 <- VPN :VPN .x001 - we have ITLBMR entry
1804
        l.mtspr r2,r5,SPR_ITLBMR_BASE(0)   // set ITLBMR
1805
 
1806
        /*
1807
         * set up ITLB with no translation for EA <= 0x0fffffff
1808
         *
1809
         * we need this for head.S mapping (EA = PA). if we move all functions
1810
         * which run with mmu enabled into entry.S, we might be able to eliminate this.
1811
         *
1812
         */
1813
        LOAD_SYMBOL_2_GPR(r6,0x0fffffff)
1814
        l.sfgeu  r6,r4                     // flag if r6 >= r4 (if 0xb0ffffff >= EA)
1815
        l.bf     1f                        // goto out
1816
        l.and    r3,r4,r4                  // delay slot :: 24 <- r4 (if flag==1)
1817
 
1818
        tophys(r3,r4)                      // r3 <- PA
1819
1:
1820
        l.ori   r3,r3,~(PPN_MASK)          // r3 <- PPN :PPN .xfff - clear up lo(r6) to 0x**** *fff
1821
        l.movhi r5,hi(ITLB_TR_MASK)        // r5 <- ffff:0000.x000
1822
        l.ori   r5,r5,lo(ITLB_TR_MASK)     // r5 <- ffff:1111.x050 - apply ITLB_MR_MASK
1823
        l.and   r5,r5,r3                   // r5 <- PPN :PPN .x050 - we have ITLBTR entry
1824
        l.mtspr r2,r5,SPR_ITLBTR_BASE(0)   // set ITLBTR
1825
 
1826
#ifndef CONFIG_IMMU_WORKS
1827
        l.addi  r2,r2,1
1828
        l.andi  r2,r2,0x3f
1829
        l.mtspr r2,r0,SPR_ITLBMR_BASE(0)
1830
        l.addi  r2,r2,-2
1831
        l.andi  r2,r2,0x3f
1832
        l.mtspr r2,r0,SPR_ITLBMR_BASE(0)
1833
#endif
1834
 
1835
        EXCEPTION_LOAD_GPR6
1836
        EXCEPTION_LOAD_GPR5
1837
        EXCEPTION_LOAD_GPR4
1838
        EXCEPTION_LOAD_GPR3
1839
        EXCEPTION_LOAD_GPR2
1840
 
1841
        l.rfe                              // SR <- ESR, PC <- EPC
1842
 
1843
exit_with_no_itranslation:
1844
        EXCEPTION_LOAD_GPR4
1845
        EXCEPTION_LOAD_GPR6
1846
        l.j    _dispatch_bus_fault
1847
        l.nop
1848
 
1849
/* =================================================[ debugging aids ]=== */
1850
 
1851
        .align 64
1852
_immu_trampoline:
1853
        .space 64
1854
_immu_trampoline_top:
1855
 
1856
#define TRAMP_SLOT_0            (0x0)
1857
#define TRAMP_SLOT_1            (0x4)
1858
#define TRAMP_SLOT_2            (0x8)
1859
#define TRAMP_SLOT_3            (0xc)
1860
#define TRAMP_SLOT_4            (0x10)
1861
#define TRAMP_SLOT_5            (0x14)
1862
#define TRAMP_FRAME_SIZE        (0x18)
1863
 
1864
ENTRY(_immu_trampoline_workaround)
1865
        // r2 EEA
1866
        // r6 is physical EEA
1867
        tophys(r6,r2)
1868
 
1869
        LOAD_SYMBOL_2_GPR(r5,_immu_trampoline)
1870
        tophys  (r3,r5)                 // r3 is trampoline (physical)
1871
 
1872
        LOAD_SYMBOL_2_GPR(r4,0x15000000)
1873
        l.sw    TRAMP_SLOT_0(r3),r4
1874
        l.sw    TRAMP_SLOT_1(r3),r4
1875
        l.sw    TRAMP_SLOT_4(r3),r4
1876
        l.sw    TRAMP_SLOT_5(r3),r4
1877
 
1878
                                        // EPC = EEA - 0x4
1879
        l.lwz   r4,0x0(r6)              // load op @ EEA + 0x0 (fc address)
1880
        l.sw    TRAMP_SLOT_3(r3),r4     // store it to _immu_trampoline_data
1881
        l.lwz   r4,-0x4(r6)             // load op @ EEA - 0x4 (f8 address)
1882
        l.sw    TRAMP_SLOT_2(r3),r4     // store it to _immu_trampoline_data
1883
 
1884
        l.srli  r5,r4,26                // check opcode for write access
1885
        l.sfeqi r5,0                    // l.j
1886
        l.bf    0f
1887
        l.sfeqi r5,0x11                 // l.jr
1888
        l.bf    1f
1889
        l.sfeqi r5,1                    // l.jal
1890
        l.bf    2f
1891
        l.sfeqi r5,0x12                 // l.jalr
1892
        l.bf    3f
1893
        l.sfeqi r5,3                    // l.bnf
1894
        l.bf    4f
1895
        l.sfeqi r5,4                    // l.bf
1896
        l.bf    5f
1897
99:
1898
        l.nop
1899
        l.j     99b                     // should never happen
1900
        l.nop   1
1901
 
1902
        // r2 is EEA
1903
        // r3 is trampoline address (physical)
1904
        // r4 is instruction
1905
        // r6 is physical(EEA)
1906
        //
1907
        // r5
1908
 
1909
2:      // l.jal
1910
 
1911
        /* 19 20 aa aa  l.movhi r9,0xaaaa
1912
         * a9 29 bb bb  l.ori   r9,0xbbbb
1913
         *
1914
         * where 0xaaaabbbb is EEA + 0x4 shifted right 2
1915
         */
1916
 
1917
        l.addi  r6,r2,0x4               // this is 0xaaaabbbb
1918
 
1919
                                        // l.movhi r9,0xaaaa
1920
        l.ori   r5,r0,0x1920            // 0x1920 == l.movhi r9
1921
        l.sh    (TRAMP_SLOT_0+0x0)(r3),r5
1922
        l.srli  r5,r6,16
1923
        l.sh    (TRAMP_SLOT_0+0x2)(r3),r5
1924
 
1925
                                        // l.ori   r9,0xbbbb
1926
        l.ori   r5,r0,0xa929            // 0xa929 == l.ori r9
1927
        l.sh    (TRAMP_SLOT_1+0x0)(r3),r5
1928
        l.andi  r5,r6,0xffff
1929
        l.sh    (TRAMP_SLOT_1+0x2)(r3),r5
1930
 
1931
        /* falthrough, need to set up new jump offset */
1932
 
1933
 
1934
0:      // l.j
1935
        l.slli  r6,r4,6                 // original offset shifted left 6 - 2
1936
//      l.srli  r6,r6,6                 // original offset shifted right 2
1937
 
1938
        l.slli  r4,r2,4                 // old jump position: EEA shifted left 4
1939
//      l.srli  r4,r4,6                 // old jump position: shifted right 2
1940
 
1941
        l.addi  r5,r3,0xc               // new jump position (physical)
1942
        l.slli  r5,r5,4                 // new jump position: shifted left 4
1943
 
1944
        // calculate new jump offset
1945
        // new_off = old_off + (old_jump - new_jump)
1946
 
1947
        l.sub   r5,r4,r5                // old_jump - new_jump
1948
        l.add   r5,r6,r5                // orig_off + (old_jump - new_jump)
1949
        l.srli  r5,r5,6                 // new offset shifted right 2
1950
 
1951
        // r5 is new jump offset
1952
                                        // l.j has opcode 0x0...
1953
        l.sw    TRAMP_SLOT_2(r3),r5     // write it back
1954
 
1955
        l.j     trampoline_out
1956
        l.nop
1957
 
1958
/* ----------------------------- */
1959
 
1960
3:      // l.jalr
1961
 
1962
        /* 19 20 aa aa  l.movhi r9,0xaaaa
1963
         * a9 29 bb bb  l.ori   r9,0xbbbb
1964
         *
1965
         * where 0xaaaabbbb is EEA + 0x4 shifted right 2
1966
         */
1967
 
1968
        l.addi  r6,r2,0x4               // this is 0xaaaabbbb
1969
 
1970
                                        // l.movhi r9,0xaaaa
1971
        l.ori   r5,r0,0x1920            // 0x1920 == l.movhi r9
1972
        l.sh    (TRAMP_SLOT_0+0x0)(r3),r5
1973
        l.srli  r5,r6,16
1974
        l.sh    (TRAMP_SLOT_0+0x2)(r3),r5
1975
 
1976
                                        // l.ori   r9,0xbbbb
1977
        l.ori   r5,r0,0xa929            // 0xa929 == l.ori r9
1978
        l.sh    (TRAMP_SLOT_1+0x0)(r3),r5
1979
        l.andi  r5,r6,0xffff
1980
        l.sh    (TRAMP_SLOT_1+0x2)(r3),r5
1981
 
1982
        l.lhz   r5,(TRAMP_SLOT_2+0x0)(r3)       // load hi part of jump instruction
1983
        l.andi  r5,r5,0x3ff             // clear out opcode part
1984
        l.ori   r5,r5,0x4400            // opcode changed from l.jalr -> l.jr
1985
        l.sh    (TRAMP_SLOT_2+0x0)(r3),r5 // write it back
1986
 
1987
        /* falthrough */
1988
 
1989
1:      // l.jr
1990
        l.j     trampoline_out
1991
        l.nop
1992
 
1993
/* ----------------------------- */
1994
 
1995
4:      // l.bnf
1996
5:      // l.bf
1997
        l.slli  r6,r4,6                 // original offset shifted left 6 - 2
1998
//      l.srli  r6,r6,6                 // original offset shifted right 2
1999
 
2000
        l.slli  r4,r2,4                 // old jump position: EEA shifted left 4
2001
//      l.srli  r4,r4,6                 // old jump position: shifted right 2
2002
 
2003
        l.addi  r5,r3,0xc               // new jump position (physical)
2004
        l.slli  r5,r5,4                 // new jump position: shifted left 4
2005
 
2006
        // calculate new jump offset
2007
        // new_off = old_off + (old_jump - new_jump)
2008
 
2009
        l.add   r6,r6,r4                // (orig_off + old_jump)
2010
        l.sub   r6,r6,r5                // (orig_off + old_jump) - new_jump
2011
        l.srli  r6,r6,6                 // new offset shifted right 2
2012
 
2013
        // r6 is new jump offset
2014
        l.lwz   r4,(TRAMP_SLOT_2+0x0)(r3)       // load jump instruction
2015
        l.srli  r4,r4,16
2016
        l.andi  r4,r4,0xfc00            // get opcode part
2017
        l.slli  r4,r4,16
2018
        l.or    r6,r4,r6                // l.b(n)f new offset
2019
        l.sw    TRAMP_SLOT_2(r3),r6     // write it back
2020
 
2021
        /* we need to add l.j to EEA + 0x8 */
2022
        tophys  (r4,r2)                 // may not be needed (due to shifts down_
2023
        l.addi  r4,r4,(0x8 - 0x8)       // jump target = r2 + 0x8 (compensate for 0x8)
2024
                                        // jump position = r5 + 0x8 (0x8 compensated)
2025
        l.sub   r4,r4,r5                // jump offset = target - new_position + 0x8
2026
 
2027
        l.slli  r4,r4,4                 // the amount of info in imediate of jump
2028
        l.srli  r4,r4,6                 // jump instruction with offset
2029
        l.sw    TRAMP_SLOT_4(r3),r4     // write it to 4th slot
2030
 
2031
        /* fallthrough */
2032
 
2033
trampoline_out:
2034
        // set up new EPC to point to our trampoline code
2035
        LOAD_SYMBOL_2_GPR(r5,_immu_trampoline)
2036
        l.mtspr r0,r5,SPR_EPCR_BASE
2037
 
2038
        // immu_trampoline is (4x) CACHE_LINE aligned
2039
        // and only 6 instructions long,
2040
        // so we need to invalidate only 2 lines
2041
        l.mtspr r0,r5,SPR_ICBIR
2042
        l.addi  r5,r5,IC_LINE
2043
        l.mtspr r0,r5,SPR_ICBIR
2044
 
2045
        l.jr    r9
2046
        l.nop
2047
 
2048
/*
2049
 * dumping processor state without mmu
2050
 * (not yet finnished)
2051
 */
2052
 
2053
ENTRY(_debug_tng)
2054
        l.addi  r1,r1,-16
2055
        l.sw    0(r1),r3
2056
        l.sw    4(r1),r4
2057
        l.mfspr r3,r0,SPR_SR
2058
        l.sw    8(r1),r3
2059
        l.mfspr r3,r0,SPR_PC
2060
        l.sw    12(r1),r3
2061
 
2062
        l.ori   r3,r0,0x8001
2063
        l.mtspr r0,r3,SPR_ESR_BASE
2064
        LOAD_SYMBOL_2_GPR(r3,nommu_entry)
2065
        tophys  (r4,r3)
2066
        l.mtspr r0,r4,SPR_EPCR_BASE
2067
 
2068
        l.lwz   r3,0(r1)
2069
        l.lwz   r4,4(r1)
2070
        l.addi  r1,r1,8
2071
        l.rfe
2072
 
2073
nommu_entry:
2074
        EXCEPTION_T_STORE_GPR31
2075
        EXCEPTION_T_STORE_GPR10
2076
        EXCEPTION_T_STORE_SP
2077
        /* temporary store r3, r9 into r1, r10 */
2078
        l.addi  r1,r3,0x0
2079
        l.addi  r10,r9,0x0
2080
        /* the string referenced by r3 must be low enough */
2081
        l.jal   _emergency_print
2082
        l.ori   r3,r0,lo(_string_ed)
2083
        l.mfspr r3,r0,SPR_PC
2084
        l.jal   _emergency_print_nr
2085
        l.andi  r3,r3,0x1f00
2086
        /* the string referenced by r3 must be low enough */
2087
        l.jal   _emergency_print
2088
        l.ori   r3,r0,lo(_string_epc_prefix)
2089
        l.jal   _emergency_print_nr
2090
        l.mfspr r3,r0,SPR_EPCR_BASE
2091
        l.jal   _emergency_print
2092
        l.ori   r3,r0,lo(_string_nl)
2093
        /* end of printing */
2094
        l.addi  r3,r1,0x0
2095
        l.addi  r9,r10,0x0
2096
        /* extract current, ksp from current_set */
2097
        LOAD_SYMBOL_2_GPR(r1,_unhandled_stack_top)
2098
        /* create new stack frame, save only needed gprs */
2099
        /* r1: KSP, r10: current, r31: __pa(KSP) */
2100
        /* r12: temp, syscall indicator, r13 temp */
2101
        l.addi  r1,r1,-(INT_FRAME_SIZE)
2102
        /* r1 is KSP, r31 is __pa(KSP) */
2103
        tophys  (r31,r1)
2104
        l.sw    GPR12(r31),r12
2105
        l.mfspr r12,r0,SPR_EPCR_BASE
2106
        l.sw    PC(r31),r12
2107
        l.mfspr r12,r0,SPR_ESR_BASE
2108
        l.sw    SR(r31),r12
2109
        /* save r31 */
2110
        EXCEPTION_T_LOAD_GPR31(r12)
2111
        l.sw    GPR31(r31),r12
2112
        /* save r10 as was prior to exception */
2113
        EXCEPTION_T_LOAD_GPR10(r12)
2114
        l.sw    GPR10(r31),r12
2115
        /* save SP as was prior to exception */
2116
        EXCEPTION_T_LOAD_SP(r12)
2117
        l.sw    SP(r31),r12
2118
        l.sw    GPR13(r31),r13
2119
        /* --> */
2120
        /* save exception r4, set r4 = EA */
2121
        l.sw    GPR4(r31),r4
2122
        l.mfspr r4,r0,SPR_EEAR_BASE
2123
        /* r31 is __pa(r1), r1 <- r31 */
2124
        l.addi  r1,r31,0x0
2125
        /* r1, r10, EPCR, ESR a already saved */
2126
        l.sw    GPR2(r1),r2
2127
        l.sw    GPR3(r1),r3
2128
        l.sw    ORIG_GPR3(r1),r3
2129
        l.sw    GPR5(r1),r5
2130
        l.sw    GPR6(r1),r6
2131
        l.sw    GPR7(r1),r7
2132
        l.sw    GPR8(r1),r8
2133
        l.sw    GPR9(r1),r9
2134
        /* r10 already saved */
2135
        l.sw    GPR11(r1),r11
2136
        /* r12,r13 already saved */
2137
        l.sw    GPR14(r1),r14
2138
        l.sw    GPR15(r1),r15
2139
        l.sw    GPR16(r1),r16
2140
        l.sw    GPR17(r1),r17
2141
        l.sw    GPR18(r1),r18
2142
        l.sw    GPR19(r1),r19
2143
        l.sw    GPR20(r1),r20
2144
        l.sw    GPR21(r1),r21
2145
        l.sw    GPR22(r1),r22
2146
        l.sw    GPR23(r1),r23
2147
        l.sw    GPR24(r1),r24
2148
        l.sw    GPR25(r1),r25
2149
        l.sw    GPR26(r1),r26
2150
        l.sw    GPR27(r1),r27
2151
        l.sw    GPR28(r1),r28
2152
        l.sw    GPR29(r1),r29
2153
        l.sw    GPR30(r1),r30
2154
        /* r31 already saved */
2155
        l.sw    RESULT(r1),r0
2156
        l.addi  r3,r1,0
2157
        /* r4 is exception EA */
2158
        l.addi  r5,r0,0xdead
2159
        l.jal   _nommu_dump_state
2160
        l.nop
2161
 
2162
 
2163
/* ========================================[ standard debugging aids ]=== */
2164
 
2165
// this HAS to be atomic. also disable interrupts beetwen to entries
2166
// may use gpr4
2167
ENTRY(_exception_regenerate)
2168
        E_REGEN_LOAD_STATUS(r4)         // were we in this exception yet
2169
        l.sfeqi r4,0x0
2170
        l.bnf   1f
2171
        l.nop
2172
 
2173
0:                                      // first entry into this exception
2174
                                        // patch the ESR, reenter exception
2175
 
2176
        l.mfspr r4,r0,SPR_ESR_BASE      // get original ESR
2177
        E_REGEN_STORE_STATUS(r4)        // save original ESR
2178
 
2179
        SPR_DISABLE_LO_BITS(SPR_ESR_BASE,
2180
                (SPR_SR_ICE | SPR_SR_DCE | SPR_SR_IEE | SPR_SR_TEE),r4)
2181
        SPR_DISABLE_LO_BITS(SPR_SR,
2182
                (SPR_SR_ICE | SPR_SR_DCE | SPR_SR_IEE | SPR_SR_TEE),r4)
2183
 
2184
        EXCEPTION_DEBUG_LOAD_GPR4
2185
        EXCEPTION_DEBUG_LOAD_F_GPR9
2186
 
2187
        l.rfe                           // this will regenerate exception
2188
 
2189
1:                                      // second entry into this exception
2190
                                        // patch ESR, invalidate the caches
2191
 
2192
        // we already loaded previous ESR into r4
2193
        l.mtspr r0,r4,SPR_ESR_BASE
2194
 
2195
        l.ori   r4,r0,0x0               // next time is fresh entry
2196
        E_REGEN_STORE_STATUS(r4)        // prepare for next exception
2197
 
2198
        E_REGEN_STORE_GPR3
2199
        E_REGEN_STORE_GPR4
2200
        E_REGEN_STORE_GPR5
2201
        E_REGEN_STORE_GPR6
2202
        E_REGEN_STORE_GPR9
2203
        l.jal   _dc_enable
2204
        l.nop
2205
        l.jal   _ic_enable
2206
        l.nop
2207
        E_REGEN_LOAD_GPR3
2208
        E_REGEN_LOAD_GPR4
2209
        E_REGEN_LOAD_GPR5
2210
        E_REGEN_LOAD_GPR6
2211
        E_REGEN_LOAD_GPR9
2212
 
2213
        l.jr    r9
2214
        l.nop
2215
 
2216
ENTRY(_exception_debug)
2217
        EXCEPTION_DEBUG_STORE_GPR3
2218
        EXCEPTION_DEBUG_STORE_GPR9
2219
 
2220
        // disable tick timer
2221
        l.mfspr r3,r0,SPR_TTMR
2222
        LOAD_SYMBOL_2_GPR(r9,~(0x30000003))
2223
        l.and   r3,r3,r9
2224
        l.mtspr r0,r3,SPR_TTMR
2225
 
2226
        l.jal   _emergency_print
2227
        l.ori   r3,r0,lo(_string_debug_exception)
2228
        l.jal   _emergency_print_nr
2229
        l.andi  r3,r4,0x1ff0
2230
        /* the string referenced by r3 must be low enough */
2231
        l.jal   _emergency_print
2232
        l.ori   r3,r0,lo(_string_epc_prefix)
2233
 
2234
        l.jal   _emergency_print_nr
2235
        l.mfspr r3,r0,SPR_EPCR_BASE
2236
 
2237
        l.jal   _emergency_print
2238
        l.ori   r3,r0,lo(_string_debug_esr_prefix)
2239
 
2240
        l.jal   _emergency_print_nr
2241
        l.mfspr r3,r0,SPR_ESR_BASE
2242
 
2243
        l.jal   _emergency_print
2244
        l.ori   r3,r0,lo(_string_debug_eear_prefix)
2245
 
2246
        l.jal   _emergency_print_nr
2247
        l.mfspr r3,r0,SPR_EEAR_BASE
2248
 
2249
        l.jal   _emergency_print
2250
        l.ori   r3,r0,lo(_string_nl)
2251
 
2252
        // enable tick timer
2253
        l.mfspr r3,r0,SPR_TTMR
2254
        LOAD_SYMBOL_2_GPR(r9,0x20000001)
2255
        l.or    r3,r3,r9
2256
        l.mtspr r0,r3,SPR_TTMR
2257
 
2258
        EXCEPTION_DEBUG_LOAD_GPR3
2259
        EXCEPTION_DEBUG_LOAD_GPR9
2260
        l.jr    r9
2261
        l.nop
2262
 
2263
/*
2264
 * DSCR: prints a string referenced by r3.
2265
 *
2266
 * PRMS: r3             - address of the first character of null
2267
 *                      terminated string to be printed
2268
 *
2269
 * PREQ: UART at UART_BASE_ADD has to be initialized
2270
 *
2271
 * POST: caller should be aware that r3, r9 are changed
2272
 */
2273
ENTRY(_emergency_print)
2274
        EMERGENCY_PRINT_STORE_GPR4
2275
        EMERGENCY_PRINT_STORE_GPR5
2276
        EMERGENCY_PRINT_STORE_GPR6
2277
        EMERGENCY_PRINT_STORE_GPR7
2278
2:
2279
        l.lbz   r7,0(r3)
2280
        l.sfeq  r7,r0
2281
        l.bf    9f
2282
        l.nop
2283
 
2284
// putc:
2285
        l.movhi r4,hi(UART_BASE_ADD)
2286
 
2287
        l.addi  r6,r0,0x20
2288
1:      l.lbz   r5,5(r4)
2289
        l.andi  r5,r5,0x20
2290
        l.sfeq  r5,r6
2291
        l.bnf   1b
2292
        l.nop
2293
 
2294
        l.sb    0(r4),r7
2295
 
2296
        l.addi  r6,r0,0x60
2297
1:      l.lbz   r5,5(r4)
2298
        l.andi  r5,r5,0x60
2299
        l.sfeq  r5,r6
2300
        l.bnf   1b
2301
        l.nop
2302
 
2303
        /* next character */
2304
        l.j     2b
2305
        l.addi  r3,r3,0x1
2306
 
2307
9:
2308
        EMERGENCY_PRINT_LOAD_GPR7
2309
        EMERGENCY_PRINT_LOAD_GPR6
2310
        EMERGENCY_PRINT_LOAD_GPR5
2311
        EMERGENCY_PRINT_LOAD_GPR4
2312
        l.jr    r9
2313
        l.nop
2314
 
2315
ENTRY(_emergency_print_nr)
2316
        EMERGENCY_PRINT_STORE_GPR4
2317
        EMERGENCY_PRINT_STORE_GPR5
2318
        EMERGENCY_PRINT_STORE_GPR6
2319
        EMERGENCY_PRINT_STORE_GPR7
2320
        EMERGENCY_PRINT_STORE_GPR8
2321
 
2322
        l.addi  r8,r0,32                // shift register
2323
 
2324
1:      /* remove leading zeros */
2325
        l.addi  r8,r8,-0x4
2326
        l.srl   r7,r3,r8
2327
        l.andi  r7,r7,0xf
2328
 
2329
        /* don't skip the last zero if number == 0x0 */
2330
        l.sfeqi r8,0x4
2331
        l.bf    2f
2332
        l.nop
2333
 
2334
        l.sfeq  r7,r0
2335
        l.bf    1b
2336
        l.nop
2337
 
2338
2:
2339
        l.srl   r7,r3,r8
2340
 
2341
        l.andi  r7,r7,0xf
2342
        l.sflts r8,r0
2343
        l.bf    9f
2344
 
2345
        l.sfgtui r7,0x9
2346
        l.bnf   8f
2347
        l.nop
2348
        l.addi  r7,r7,0x27
2349
 
2350
8:
2351
        l.addi  r7,r7,0x30
2352
// putc:
2353
        l.movhi r4,hi(UART_BASE_ADD)
2354
 
2355
        l.addi  r6,r0,0x20
2356
1:      l.lbz   r5,5(r4)
2357
        l.andi  r5,r5,0x20
2358
        l.sfeq  r5,r6
2359
        l.bnf   1b
2360
        l.nop
2361
 
2362
        l.sb    0(r4),r7
2363
 
2364
        l.addi  r6,r0,0x60
2365
1:      l.lbz   r5,5(r4)
2366
        l.andi  r5,r5,0x60
2367
        l.sfeq  r5,r6
2368
        l.bnf   1b
2369
        l.nop
2370
 
2371
        /* next character */
2372
        l.j     2b
2373
        l.addi  r8,r8,-0x4
2374
 
2375
9:
2376
        EMERGENCY_PRINT_LOAD_GPR8
2377
        EMERGENCY_PRINT_LOAD_GPR7
2378
        EMERGENCY_PRINT_LOAD_GPR6
2379
        EMERGENCY_PRINT_LOAD_GPR5
2380
        EMERGENCY_PRINT_LOAD_GPR4
2381
        l.jr    r9
2382
        l.nop
2383
 
2384
 
2385
ENTRY(_early_uart_init)
2386
        l.movhi r3,hi(UART_BASE_ADD)
2387
 
2388
        l.addi  r4,r0,0x7
2389
        l.sb    0x2(r3),r4
2390
 
2391
        l.addi  r4,r0,0x0
2392
        l.sb    0x1(r3),r4
2393
 
2394
        l.addi  r4,r0,0x3
2395
        l.sb    0x3(r3),r4
2396
 
2397
        l.lbz   r5,3(r3)
2398
        l.ori   r4,r5,0x80
2399
        l.sb    0x3(r3),r4
2400
        l.addi  r4,r0,((UART_DEVISOR>>8) & 0x000000ff)
2401
        l.sb    UART_DLM(r3),r4
2402
        l.addi  r4,r0,((UART_DEVISOR) & 0x000000ff)
2403
        l.sb    UART_DLL(r3),r4
2404
        l.sb    0x3(r3),r5
2405
 
2406
        l.jr    r9
2407
        l.nop
2408
 
2409
_string_copying_linux:
2410
        .string "\n\n\n\n\n\rCopying Linux... \0"
2411
 
2412
_string_ok_booting:
2413
        .string "Ok, booting the kernel.\n\r\0"
2414
 
2415
_string_unhandled_exception:
2416
        .string "\n\rRunarunaround: Unhandled exception 0x\0"
2417
 
2418
_string_epc_prefix:
2419
        .string ": EPC=0x\0"
2420
 
2421
_string_nl:
2422
        .string "\n\r\0"
2423
 
2424
_string_debug_exception:
2425
        .string "\n\r\tDebug: exception 0x\0"
2426
 
2427
_string_debug_esr_prefix:
2428
        .string ", ESR=0x\0"
2429
 
2430
_string_debug_eear_prefix:
2431
        .string ", EEAR=0x\0"
2432
 
2433
_string_dcache_clean:
2434
        .string "dcache cleaning\n\r\0"
2435
 
2436
_string_icache_clean:
2437
        .string "icache cleaning\n\r\0"
2438
 
2439
_string_ic_invalidate:
2440
        .string "\n\r\tic invalidate:  \0"
2441
 
2442
_string_ic_enable:
2443
        .string "\n\ricache enabling\n\r\0"
2444
 
2445
_string_dc_invalidate:
2446
        .string "\n\r\tdc invalidate:  \0"
2447
 
2448
_string_dc_enable:
2449
        .string "\n\rdcache enabling\n\r\0"
2450
 
2451
_string_pbjds:
2452
        .string "[jd]"
2453
 
2454
_string_ed:
2455
        .string "\n\r[debug] "
2456
 
2457
        .global _string_esr_irq_bug
2458
_string_esr_irq_bug:
2459
        .string "\n\rESR external interrupt bug, for details look into entry.S\n\r\0"
2460
 
2461
 
2462
 
2463
/* ========================================[ page aligned structures ]=== */
2464
 
2465
/*
2466
 * .data section should be page aligned
2467
 *      (look into arch/or32/kernel/vmlinux.lds)
2468
 */
2469
        .data
2470
        .global  _sdata
2471
_sdata:
2472
        .align  8192
2473
        .global  _empty_zero_page
2474
_empty_zero_page:
2475
        .space  8192
2476
 
2477
        .global  _swapper_pg_dir
2478
_swapper_pg_dir:
2479
        .space  8192
2480
 
2481
        .global _unhandled_stack
2482
_unhandled_stack:
2483
        .space  8192
2484
_unhandled_stack_top:
2485
 
2486
/* ============================================================[ EOF ]=== */

powered by: WebSVN 2.1.0

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