OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.18.0/] [newlib/] [libc/] [machine/] [or32/] [or1k-support-asm.S] - Blame information for rev 551

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 517 julius
/* or1k-support - OR1K CPU support functions
2
 
3
   Copyright (C) 2011, ORSoC AB
4
 
5
   Contributor Julius Baxter  
6
 
7
   This file is part of Newlib.
8
 
9
   This program is free software; you can redistribute it and/or modify it
10
   under the terms of the GNU General Public License as published by the Free
11
   Software Foundation; either version 3 of the License, or (at your option)
12
   any later version.
13
 
14
   This program is distributed in the hope that it will be useful, but WITHOUT
15
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17
   more details.
18
 
19
   You should have received a copy of the GNU General Public License along
20
   with this program.  If not, see .            */
21
 
22
#include "spr-defs.h"
23
 
24
/* -------------------------------------------------------------------------- */
25
/*!Function to control MMU
26
                                                                              */
27
/* -------------------------------------------------------------------------- */
28
 
29
/* MMU control functions always switch MMU control with a l.rfe to return
30
   from function */
31
        .section .text
32
 
33
        .global or1k_dmmu_enable
34
or1k_dmmu_enable:
35
        l.mfspr r3,r0,SPR_SR
36
        l.ori   r3,r3,SPR_SR_DME
37
        l.mtspr r0,r3,SPR_ESR_BASE
38
        l.mtspr r0,r9,SPR_EPCR_BASE
39
        l.rfe
40
        l.nop
41
 
42
 
43
        .global or1k_dmmu_disable
44
or1k_dmmu_disable:
45
        l.ori   r3,r0,SPR_SR_DME
46
        l.xori  r4,r3,0xffff
47
        l.mfspr r3,r0,SPR_SR
48
        l.and   r3,r4,r3
49
        l.mtspr r0,r3,SPR_ESR_BASE
50
        l.mtspr r0,r9,SPR_EPCR_BASE
51
        l.rfe
52
        l.nop
53
 
54
 
55
        .global or1k_immu_enable
56
or1k_immu_enable:
57
        l.mfspr r3,r0,SPR_SR
58
        l.ori   r3,r3,SPR_SR_IME
59
        l.mtspr r0,r3,SPR_ESR_BASE
60
        l.mtspr r0,r9,SPR_EPCR_BASE
61
        l.rfe
62
        l.nop
63
 
64
        .global or1k_immu_disable
65
or1k_immu_disable:
66
        l.ori   r3,r0,SPR_SR_IME
67
        l.xori  r4,r3,0xffff
68
        l.mfspr r3,r0,SPR_SR
69
        l.and   r3,r4,r3
70
        l.mtspr r0,r3,SPR_ESR_BASE
71
        l.mtspr r0,r9,SPR_EPCR_BASE
72
        l.rfe
73
        l.nop
74
 
75
 
76
 
77
 
78
/* -------------------------------------------------------------------------- */
79
/*!Function used at reset to clear and enable all caches
80
                                                                              */
81
/* -------------------------------------------------------------------------- */
82
        .global or1k_cache_init
83
        .type   or1k_cache_init,@function
84
 
85
or1k_cache_init:
86
        /* Instruction cache enable */
87
        /* Check if IC present and skip enabling otherwise */
88
.L6:    l.mfspr r3,r0,SPR_UPR
89
        l.andi  r4,r3,SPR_UPR_ICP
90
        l.sfeq  r4,r0
91
        l.bf    .L8
92
        l.nop
93
 
94
        /* Disable IC */
95
        l.mfspr r6,r0,SPR_SR
96
        l.addi  r5,r0,-1
97
        l.xori  r5,r5,SPR_SR_ICE
98
        l.and   r5,r6,r5
99
        l.mtspr r0,r5,SPR_SR
100
 
101
        /* Establish cache block size
102
        If BS=0, 16;
103
        If BS=1, 32;
104
        r14 contain block size
105
        */
106
        l.mfspr r3,r0,SPR_ICCFGR
107
        l.andi  r4,r3,SPR_ICCFGR_CBS
108
        l.srli  r7,r4,7
109
        l.ori   r8,r0,16
110
        l.sll   r14,r8,r7
111
 
112
        /* Establish number of cache sets
113
        r13 contains number of cache sets
114
        r7 contains log(# of cache sets)
115
        */
116
        l.andi  r4,r3,SPR_ICCFGR_NCS
117
        l.srli  r7,r4,3
118
        l.ori   r8,r0,1
119
        l.sll   r13,r8,r7
120
 
121
        /* Invalidate IC */
122
        l.addi  r6,r0,0
123
        l.sll   r5,r14,r7
124
 
125
.L7:    l.mtspr r0,r6,SPR_ICBIR
126
        l.sfne  r6,r5
127
        l.bf    .L7
128
        l.add   r6,r6,r14
129
 
130
        /* Enable IC */
131
        l.mfspr r6,r0,SPR_SR
132
        l.ori   r6,r6,SPR_SR_ICE
133
        l.mtspr r0,r6,SPR_SR
134
        l.nop
135
        l.nop
136
        l.nop
137
        l.nop
138
        l.nop
139
        l.nop
140
        l.nop
141
        l.nop
142
 
143
        /* Data cache enable */
144
        /* Check if DC present and skip enabling otherwise */
145
.L8:    l.mfspr r3,r0,SPR_UPR
146
        l.andi  r4,r3,SPR_UPR_DCP
147
        l.sfeq  r4,r0
148
        l.bf    .L10
149
        l.nop
150
        /* Disable DC */
151
        l.mfspr r6,r0,SPR_SR
152
        l.addi  r5,r0,-1
153
        l.xori  r5,r5,SPR_SR_DCE
154
        l.and   r5,r6,r5
155
        l.mtspr r0,r5,SPR_SR
156
        /* Establish cache block size
157
           If BS=0, 16;
158
           If BS=1, 32;
159
           r14 contain block size
160
        */
161
        l.mfspr r3,r0,SPR_DCCFGR
162
        l.andi  r4,r3,SPR_DCCFGR_CBS
163
        l.srli  r7,r4,7
164
        l.ori   r8,r0,16
165
        l.sll   r14,r8,r7
166
        /* Establish number of cache sets
167
           r13 contains number of cache sets
168
           r7 contains log(# of cache sets)
169
        */
170
        l.andi  r4,r3,SPR_DCCFGR_NCS
171
        l.srli  r7,r4,3
172
        l.ori   r8,r0,1
173
        l.sll   r13,r8,r7
174
        /* Invalidate DC */
175
        l.addi  r6,r0,0
176
        l.sll   r5,r14,r7
177
 
178
.L9:    l.mtspr r0,r6,SPR_DCBIR
179
        l.sfne  r6,r5
180
        l.bf    .L9
181
        l.add   r6,r6,r14
182
        /* Enable DC */
183
        l.mfspr r6,r0,SPR_SR
184
        l.ori   r6,r6,SPR_SR_DCE
185
        l.mtspr r0,r6,SPR_SR
186
 
187
.L10:
188
        /* Return */
189
        l.jr    r9
190
        l.nop
191
 
192
/* -------------------------------------------------------------------------- */
193
/*!Function to enable instruction cache
194
                                                                              */
195
/* -------------------------------------------------------------------------- */
196
 
197
        .global or1k_icache_enable
198
        .type   or1k_icache_enable,@function
199
 
200
or1k_icache_enable:
201
        /* Enable IC */
202
        l.mfspr r13,r0,SPR_SR
203
        l.ori   r13,r13,SPR_SR_ICE
204
        l.mtspr r0,r13,SPR_SR
205
        l.nop
206
        l.nop
207
        l.nop
208
        l.nop
209
        l.nop
210
        l.jr    r9
211
        l.nop
212
 
213
/* -------------------------------------------------------------------------- */
214
/*!Function to disable instruction cache
215
                                                                              */
216
/* -------------------------------------------------------------------------- */
217
        .global or1k_icache_disable
218
        .type   or1k_icache_disable,@function
219
 
220 551 yannv
or1k_icache_disable:
221 517 julius
        /* Disable IC */
222
        l.mfspr r13,r0,SPR_SR
223
        l.addi  r12,r0,-1
224
        l.xori  r12,r12,SPR_SR_ICE
225
        l.and   r12,r13,r12
226
        l.mtspr r0,r12,SPR_SR
227
        l.jr    r9
228
        l.nop
229
 
230
/* -------------------------------------------------------------------------- */
231
/*!Function to flush address of instruction cache
232
                                                                              */
233
/* -------------------------------------------------------------------------- */
234
        .global or1k_icache_flush
235
        .type   or1k_icache_flush,@function
236
 
237
or1k_icache_flush:
238
        /* Push r3 into IC invalidate reg */
239
        l.jr    r9
240
        l.mtspr r0,r3,SPR_ICBIR
241
 
242
 
243
/* -------------------------------------------------------------------------- */
244
/*!Function to enable data cache
245
                                                                              */
246
/* -------------------------------------------------------------------------- */
247
        .global or1k_dcache_enable
248
        .type   or1k_dcache_enable,@function
249
 
250
or1k_dcache_enable:
251
        /* Enable DC */
252
        l.mfspr r13,r0,SPR_SR
253
        l.ori   r13,r13,SPR_SR_DCE
254
        l.mtspr r0,r13,SPR_SR
255
        l.nop
256
        l.nop
257
        l.nop
258
        l.nop
259
        l.nop
260
        l.jr    r9
261
        l.nop
262
 
263
/* -------------------------------------------------------------------------- */
264
/*!Function to disable data cache
265
                                                                              */
266
/* -------------------------------------------------------------------------- */
267
        .global or1k_dcache_disable
268
        .type   or1k_dcache_disable,@function
269
 
270 551 yannv
or1k_dcache_disable:
271 517 julius
        /* Disable DC */
272
        l.mfspr r13,r0,SPR_SR
273
        l.addi  r12,r0,-1
274
        l.xori  r12,r12,SPR_SR_DCE
275
        l.and   r12,r13,r12
276
        l.mtspr r0,r12,SPR_SR
277
        l.jr    r9
278
        l.nop
279
 
280
/* -------------------------------------------------------------------------- */
281
/*!Function to flush address of data cache
282
                                                                              */
283
/* -------------------------------------------------------------------------- */
284
        .global or1k_dcache_flush
285
        .type   or1k_dcache_flush,@function
286
 
287
or1k_dcache_flush:
288
        /* Push r3 into DC invalidate reg */
289
        l.jr    r9
290
        l.mtspr r0,r3,SPR_DCBIR
291
 
292
 
293
 
294
 
295
/* -------------------------------------------------------------------------- */
296
/*!Generic interrupt handler function for or1k
297
                                                                              */
298
/* -------------------------------------------------------------------------- */
299
 
300
#define INTERRUPT_HANDLER_NOT_SET -1
301
 
302
        .data
303
        .align 4
304
        .global or1k_interrupt_handler_table
305
or1k_interrupt_handler_table:
306
or1k_interrupt_handler0:        .long   INTERRUPT_HANDLER_NOT_SET
307
or1k_interrupt_handler1:        .long   INTERRUPT_HANDLER_NOT_SET
308
or1k_interrupt_handler2:        .long   INTERRUPT_HANDLER_NOT_SET
309
or1k_interrupt_handler3:        .long   INTERRUPT_HANDLER_NOT_SET
310
or1k_interrupt_handler4:        .long   INTERRUPT_HANDLER_NOT_SET
311
or1k_interrupt_handler5:        .long   INTERRUPT_HANDLER_NOT_SET
312
or1k_interrupt_handler6:        .long   INTERRUPT_HANDLER_NOT_SET
313
or1k_interrupt_handler7:        .long   INTERRUPT_HANDLER_NOT_SET
314
or1k_interrupt_handler8:        .long   INTERRUPT_HANDLER_NOT_SET
315
or1k_interrupt_handler9:        .long   INTERRUPT_HANDLER_NOT_SET
316
or1k_interrupt_handler10:       .long   INTERRUPT_HANDLER_NOT_SET
317
or1k_interrupt_handler11:       .long   INTERRUPT_HANDLER_NOT_SET
318
or1k_interrupt_handler12:       .long   INTERRUPT_HANDLER_NOT_SET
319
or1k_interrupt_handler13:       .long   INTERRUPT_HANDLER_NOT_SET
320
or1k_interrupt_handler14:       .long   INTERRUPT_HANDLER_NOT_SET
321
or1k_interrupt_handler15:       .long   INTERRUPT_HANDLER_NOT_SET
322
or1k_interrupt_handler16:       .long   INTERRUPT_HANDLER_NOT_SET
323
or1k_interrupt_handler17:       .long   INTERRUPT_HANDLER_NOT_SET
324
or1k_interrupt_handler18:       .long   INTERRUPT_HANDLER_NOT_SET
325
or1k_interrupt_handler19:       .long   INTERRUPT_HANDLER_NOT_SET
326
or1k_interrupt_handler20:       .long   INTERRUPT_HANDLER_NOT_SET
327
or1k_interrupt_handler21:       .long   INTERRUPT_HANDLER_NOT_SET
328
or1k_interrupt_handler22:       .long   INTERRUPT_HANDLER_NOT_SET
329
or1k_interrupt_handler23:       .long   INTERRUPT_HANDLER_NOT_SET
330
or1k_interrupt_handler24:       .long   INTERRUPT_HANDLER_NOT_SET
331
or1k_interrupt_handler25:       .long   INTERRUPT_HANDLER_NOT_SET
332
or1k_interrupt_handler26:       .long   INTERRUPT_HANDLER_NOT_SET
333
or1k_interrupt_handler27:       .long   INTERRUPT_HANDLER_NOT_SET
334
or1k_interrupt_handler28:       .long   INTERRUPT_HANDLER_NOT_SET
335
or1k_interrupt_handler29:       .long   INTERRUPT_HANDLER_NOT_SET
336
or1k_interrupt_handler30:       .long   INTERRUPT_HANDLER_NOT_SET
337
or1k_interrupt_handler31:       .long   INTERRUPT_HANDLER_NOT_SET
338
 
339
        .global or1k_interrupt_handler_data_ptr_table
340
or1k_interrupt_handler_data_ptr_table:
341
or1k_interrupt_handler_data_ptr0:       .long   INTERRUPT_HANDLER_NOT_SET
342
or1k_interrupt_handler_data_ptr1:       .long   INTERRUPT_HANDLER_NOT_SET
343
or1k_interrupt_handler_data_ptr2:       .long   INTERRUPT_HANDLER_NOT_SET
344
or1k_interrupt_handler_data_ptr3:       .long   INTERRUPT_HANDLER_NOT_SET
345
or1k_interrupt_handler_data_ptr4:       .long   INTERRUPT_HANDLER_NOT_SET
346
or1k_interrupt_handler_data_ptr5:       .long   INTERRUPT_HANDLER_NOT_SET
347
or1k_interrupt_handler_data_ptr6:       .long   INTERRUPT_HANDLER_NOT_SET
348
or1k_interrupt_handler_data_ptr7:       .long   INTERRUPT_HANDLER_NOT_SET
349
or1k_interrupt_handler_data_ptr8:       .long   INTERRUPT_HANDLER_NOT_SET
350
or1k_interrupt_handler_data_ptr9:       .long   INTERRUPT_HANDLER_NOT_SET
351
or1k_interrupt_handler_data_ptr10:      .long   INTERRUPT_HANDLER_NOT_SET
352
or1k_interrupt_handler_data_ptr11:      .long   INTERRUPT_HANDLER_NOT_SET
353
or1k_interrupt_handler_data_ptr12:      .long   INTERRUPT_HANDLER_NOT_SET
354
or1k_interrupt_handler_data_ptr13:      .long   INTERRUPT_HANDLER_NOT_SET
355
or1k_interrupt_handler_data_ptr14:      .long   INTERRUPT_HANDLER_NOT_SET
356
or1k_interrupt_handler_data_ptr15:      .long   INTERRUPT_HANDLER_NOT_SET
357
or1k_interrupt_handler_data_ptr16:      .long   INTERRUPT_HANDLER_NOT_SET
358
or1k_interrupt_handler_data_ptr17:      .long   INTERRUPT_HANDLER_NOT_SET
359
or1k_interrupt_handler_data_ptr18:      .long   INTERRUPT_HANDLER_NOT_SET
360
or1k_interrupt_handler_data_ptr19:      .long   INTERRUPT_HANDLER_NOT_SET
361
or1k_interrupt_handler_data_ptr20:      .long   INTERRUPT_HANDLER_NOT_SET
362
or1k_interrupt_handler_data_ptr21:      .long   INTERRUPT_HANDLER_NOT_SET
363
or1k_interrupt_handler_data_ptr22:      .long   INTERRUPT_HANDLER_NOT_SET
364
or1k_interrupt_handler_data_ptr23:      .long   INTERRUPT_HANDLER_NOT_SET
365
or1k_interrupt_handler_data_ptr24:      .long   INTERRUPT_HANDLER_NOT_SET
366
or1k_interrupt_handler_data_ptr25:      .long   INTERRUPT_HANDLER_NOT_SET
367
or1k_interrupt_handler_data_ptr26:      .long   INTERRUPT_HANDLER_NOT_SET
368
or1k_interrupt_handler_data_ptr27:      .long   INTERRUPT_HANDLER_NOT_SET
369
or1k_interrupt_handler_data_ptr28:      .long   INTERRUPT_HANDLER_NOT_SET
370
or1k_interrupt_handler_data_ptr29:      .long   INTERRUPT_HANDLER_NOT_SET
371
or1k_interrupt_handler_data_ptr30:      .long   INTERRUPT_HANDLER_NOT_SET
372
or1k_interrupt_handler_data_ptr31:      .long   INTERRUPT_HANDLER_NOT_SET
373
 
374
 
375
/* -------------------------------------------------------------------------- */
376
/*!Function to call appropriate interrupt handler
377
                                                                              */
378
/* -------------------------------------------------------------------------- */
379
 
380
        .section .text
381
        .global or1k_interrupt_handler
382
        .type   or1k_interrupt_handler,@function
383
 
384
or1k_interrupt_handler:
385
        /* Make room on stack, save link register */
386
        l.addi  r1,r1,-12
387
        l.sw    0(r1),r9
388
 
389
        /* Read PICSR */
390
        l.mfspr r3,r0,SPR_PICSR
391
 
392
        /* Load handler table base address */
393
        l.movhi r7,hi(or1k_interrupt_handler_table)
394
        l.ori   r7,r7,lo(or1k_interrupt_handler_table)
395
        /* Check to see if this handler has been set yet */
396
        l.movhi r8,hi(INTERRUPT_HANDLER_NOT_SET)
397
        l.ori   r8,r8,lo(INTERRUPT_HANDLER_NOT_SET)
398
        /* Load data pointer table base address */
399
        l.movhi r12,hi(or1k_interrupt_handler_data_ptr_table)
400
        l.ori   r12,r12,lo(or1k_interrupt_handler_data_ptr_table)
401
 
402
.L0:
403
        /* Find first set bit in PICSR */
404
        l.ff1   r4,r3
405
        /* Any bits set? */
406
        l.sfne  r4,r0
407
        /* If none, finish */
408
        l.bnf   .L2
409
        l.nop
410
        /* What is IRQ function table offset? */
411
        l.addi  r5,r4,-1
412
        l.slli  r6,r5,2
413
        /* Add this to table bases */
414
        l.add   r6,r6,r7
415
        l.add   r13,r6,r12
416
 
417
        /* Fetch handler function address */
418
        l.lwz   r6,0(r6)
419
 
420
        /* Double check it's valid, compare against INTERRUPT_HANDLER_NOT_SET */
421
        l.sfne  r6,r8
422
        /* Skip if no handler: TODO: Indicate interrupt fired but no handler*/
423
        l.bnf .L1
424
        l.nop
425
 
426
        /* Pull out data pointer from table, save r3, we'll write over it */
427
        l.sw    4(r1),r3
428
        l.lwz   r3,0(r13)
429
        /* Call handler, save r5 in delay slot */
430
        l.jalr  r5
431
        l.sw    8(r1),r5
432
 
433
        /* Reload r3,r5 */
434
        l.lwz   r3,4(r1)
435
        l.lwz   r5,8(r1)
436
.L1:
437
        /* Clear bit from PICSR, return to start of checking loop */
438
        l.ori   r6,r0,1
439
        l.sll   r6,r6,r5
440
        l.j     .L0
441
        l.xor   r3,r3,r6
442
 
443
.L2:
444
        /* Finish up - write PICSR back, restore r9*/
445
        l.lwz   r9,0(r1)
446
        l.mtspr r0,r3,SPR_PICSR
447
        l.jr    r9
448
        l.addi  r1,r1,12
449
 
450
 
451
 
452
/* -------------------------------------------------------------------------- */
453
/*!Function to add handler to table
454
                                                                              */
455
/* -------------------------------------------------------------------------- */
456
        .global or1k_interrupt_handler_add
457
        .type   or1k_interrupt_handler_add,@function
458
 
459
        /* r3 should have IRQ line for peripheral */
460
        /* r4 should have handler function address */
461
or1k_interrupt_handler_add:
462
        l.addi  r1,r1,-4
463
        l.sw    0(r1),r6
464
        /* Convert interrupt number into word address */
465
        l.slli  r3,r3,2
466
        l.addi  r3,r3,-4
467
        /* Get address of interrupt handler table */
468
        l.movhi r6,hi(or1k_interrupt_handler_table)
469
        l.ori   r6,r6,lo(or1k_interrupt_handler_table)
470
        /* Add handler offset to table base */
471
        l.add   r6,r6,r3
472
        /* Store handler function address */
473
        l.sw    0(r6),r4
474
        /* Get address of interrupt handler data ptr table */
475
        l.movhi r6,hi(or1k_interrupt_handler_data_ptr_table)
476
        l.ori   r6,r6,lo(or1k_interrupt_handler_data_ptr_table)
477
        /* Add handler offset to table base */
478
        l.add   r6,r6,r3
479
        /* Store handler data pointer address */
480
        l.sw    0(r6),r5
481
        /* Restore r6 */
482
        l.lwz   r6,0(r1)
483
        /* Return via link register */
484
        l.jr    r9
485
        /* Restore stack value */
486
        l.addi  r1,r1,4
487
 
488
 
489
/* -------------------------------------------------------------------------- */
490
/*!Function to enable an interrupt handler in the PICMR
491
                                                                              */
492
/* -------------------------------------------------------------------------- */
493
        .global or1k_interrupt_enable
494
        .type   or1k_interrupt_enable,@function
495
 
496
        /* r3 should have IRQ line for peripheral */
497
or1k_interrupt_enable:
498
        l.addi  r1,r1,-4
499
        l.sw    0(r1),r4
500
        l.ori   r4,r0,0x1
501
        l.sll   r4,r4,r3
502
        l.mfspr r3,r0,SPR_PICMR
503
        l.or    r3,r3,r4
504
        l.mtspr r0,r3,SPR_PICMR
505
        l.lwz   r4,0(r1)
506
        l.jr    r9
507
        l.addi  r1,r1,4
508
 
509
/* -------------------------------------------------------------------------- */
510
/*!Function to disable an interrupt handler in the PICMR
511
                                                                              */
512
/* -------------------------------------------------------------------------- */
513
        .global or1k_interrupt_disable
514
        .type   or1k_interrupt_disable,@function
515
 
516
        /* r3 should have IRQ line for peripheral */
517
or1k_interrupt_disable:
518
        l.addi  r1,r1,-4
519
        l.sw    0(r1),r4
520
        l.ori   r4,r0,0x1
521
        l.sll   r4,r4,r3
522
        l.xori  r4,r4,0xffff
523
        l.mfspr r3,r0,SPR_PICMR
524
        l.and   r3,r3,r4
525
        l.mtspr r0,r3,SPR_PICMR
526
        l.lwz   r4,0(r1)
527
        l.jr    r9
528
        l.addi  r1,r1,4
529
 
530
 
531
/* -------------------------------------------------------------------------- */
532
/*!Generic exception handler function
533
                                                                              */
534
/* -------------------------------------------------------------------------- */
535
// Warning - this must be the same as specified in crt0.S
536
#define EXCEPTION_STACK_SIZE 128+128
537
 
538
// Value handler addresses are initialised to
539
#define EXCEPTION_HANDLER_NOT_SET -1
540
 
541
 
542
        .data
543
        .align 4
544
        .global or1k_exception_handler_table
545
        .extern _interrupt_handler
546
or1k_exception_handler_table:
547
or1k_exception_handler_buserr:          .long   EXCEPTION_HANDLER_NOT_SET
548
or1k_exception_handler_dpfault:         .long   EXCEPTION_HANDLER_NOT_SET
549
or1k_exception_handler_ipfault:         .long   EXCEPTION_HANDLER_NOT_SET
550
or1k_exception_handler_tick:            .long   EXCEPTION_HANDLER_NOT_SET
551
or1k_exception_handler_align:           .long   EXCEPTION_HANDLER_NOT_SET
552
or1k_exception_handler_illegal:         .long   EXCEPTION_HANDLER_NOT_SET
553
or1k_exception_handler_interrupt:       .long   EXCEPTION_HANDLER_NOT_SET
554
or1k_exception_handler_dtlbmiss:        .long   EXCEPTION_HANDLER_NOT_SET
555
or1k_exception_handler_itlbmiss:        .long   EXCEPTION_HANDLER_NOT_SET
556
or1k_exception_handler_range:           .long   EXCEPTION_HANDLER_NOT_SET
557
or1k_exception_handler_systemcall:      .long   EXCEPTION_HANDLER_NOT_SET
558
or1k_exception_handler_float:           .long   EXCEPTION_HANDLER_NOT_SET
559
or1k_exception_handler_trap:            .long   EXCEPTION_HANDLER_NOT_SET
560
or1k_exception_handler_reserved0:       .long   EXCEPTION_HANDLER_NOT_SET
561
or1k_exception_handler_reserved1:       .long   EXCEPTION_HANDLER_NOT_SET
562
or1k_exception_handler_reserved2:       .long   EXCEPTION_HANDLER_NOT_SET
563
or1k_exception_handler_reserved3:       .long   EXCEPTION_HANDLER_NOT_SET
564
or1k_exception_handler_reserved4:       .long   EXCEPTION_HANDLER_NOT_SET
565
or1k_exception_handler_reserved5:       .long   EXCEPTION_HANDLER_NOT_SET
566
or1k_exception_handler_reserved6:       .long   EXCEPTION_HANDLER_NOT_SET
567
or1k_exception_handler_reserved7:       .long   EXCEPTION_HANDLER_NOT_SET
568
or1k_exception_handler_reserved8:       .long   EXCEPTION_HANDLER_NOT_SET
569
or1k_exception_handler_reserved9:       .long   EXCEPTION_HANDLER_NOT_SET
570
or1k_exception_handler_reserved10:      .long   EXCEPTION_HANDLER_NOT_SET
571
or1k_exception_handler_reserved11:      .long   EXCEPTION_HANDLER_NOT_SET
572
or1k_exception_handler_reserved12:      .long   EXCEPTION_HANDLER_NOT_SET
573
or1k_exception_handler_reserved13:      .long   EXCEPTION_HANDLER_NOT_SET
574
or1k_exception_handler_reserved14:      .long   EXCEPTION_HANDLER_NOT_SET
575
or1k_exception_handler_reserved15:      .long   EXCEPTION_HANDLER_NOT_SET
576
 
577
/* -------------------------------------------------------------------------- */
578
/*!Function to call appropriate exception handler
579
                                                                              */
580
/* -------------------------------------------------------------------------- */
581
        .section .text
582
        .global or1k_exception_handler
583
        .type   or1k_exception_handler,@function
584
 
585
        /*
586
        r3 = address of exception vector
587
        r4 = address where exception occurred
588
        */
589
 
590
or1k_exception_handler:
591
        /* Store remainder of state (r3,r4 stored in vector entry)*/
592
        l.sw    0x00(r1), r2
593
        l.sw    0x0c(r1), r5
594
        l.sw    0x10(r1), r6
595
        l.sw    0x14(r1), r7
596
        l.sw    0x18(r1), r8
597
        l.sw    0x1c(r1), r9
598
        l.sw    0x20(r1), r10
599
        l.sw    0x24(r1), r11
600
        l.sw    0x28(r1), r12
601
        l.sw    0x2c(r1), r13
602
        l.sw    0x30(r1), r14
603
        l.sw    0x34(r1), r15
604
        l.sw    0x38(r1), r16
605
        l.sw    0x3c(r1), r17
606
        l.sw    0x40(r1), r18
607
        l.sw    0x44(r1), r19
608
        l.sw    0x48(r1), r20
609
        l.sw    0x4c(r1), r21
610
        l.sw    0x50(r1), r22
611
        l.sw    0x54(r1), r23
612
        l.sw    0x58(r1), r24
613
        l.sw    0x5c(r1), r25
614
        l.sw    0x60(r1), r26
615
        l.sw    0x64(r1), r27
616
        l.sw    0x68(r1), r28
617
        l.sw    0x6c(r1), r29
618
        l.sw    0x70(r1), r30
619
        l.sw    0x74(r1), r31
620
 
621
        /* Determine offset in table of exception handler using r3*/
622
        l.andi  r13,r3,0xffff
623
        l.srli  r13,r13,6
624
        /* Substract 2 words, as we have no vector at 0 and no reset handler */
625
        l.addi  r13,r13,-8
626
        /* r13 now contains offset in or1k_exception_handler_table for
627
           function
628
        */
629
        /* Get or1k_exception_handler_table address */
630
        l.movhi r14,hi(or1k_exception_handler_table)
631
        l.ori   r14,r14,lo(or1k_exception_handler_table)
632
        /* r14 now contains base of exception handler table */
633
        l.add   r14,r14,r13
634
        l.lwz   r13, 0(r14)
635
 
636
        /* Check to see if this handler has been set yet */
637
        l.movhi r15,hi(EXCEPTION_HANDLER_NOT_SET)
638
        l.ori   r15,r15,lo(EXCEPTION_HANDLER_NOT_SET)
639
        l.sfne  r13,r15
640
        l.bnf   exception_exit
641
        l.nop
642
 
643
        /* Call exception handler, copy EPCR to r3 */
644
        l.jalr  r13
645
        l.or    r3,r4,r4
646
 
647
        /* Restore state */
648
        l.lwz    r2, 0x00(r1)
649
        l.lwz    r3, 0x04(r1)
650
        l.lwz    r4, 0x08(r1)
651
        l.lwz    r5, 0x0c(r1)
652
        l.lwz    r6, 0x10(r1)
653
        l.lwz    r7, 0x14(r1)
654
        l.lwz    r8, 0x18(r1)
655
        l.lwz    r9, 0x1c(r1)
656
        l.lwz    r10, 0x20(r1)
657
        l.lwz    r11, 0x24(r1)
658
        l.lwz    r12, 0x28(r1)
659
        l.lwz    r13, 0x2c(r1)
660
        l.lwz    r14, 0x30(r1)
661
        l.lwz    r15, 0x34(r1)
662
        l.lwz    r16, 0x38(r1)
663
        l.lwz    r17, 0x3c(r1)
664
        l.lwz    r18, 0x40(r1)
665
        l.lwz    r19, 0x44(r1)
666
        l.lwz    r20, 0x48(r1)
667
        l.lwz    r21, 0x4c(r1)
668
        l.lwz    r22, 0x50(r1)
669
        l.lwz    r23, 0x54(r1)
670
        l.lwz    r24, 0x58(r1)
671
        l.lwz    r25, 0x5c(r1)
672
        l.lwz    r26, 0x60(r1)
673
        l.lwz    r27, 0x64(r1)
674
        l.lwz    r28, 0x68(r1)
675
        l.lwz    r29, 0x6c(r1)
676
        l.lwz    r30, 0x70(r1)
677
        l.lwz    r31, 0x74(r1)
678
 
679
        l.addi  r1, r1, EXCEPTION_STACK_SIZE
680
 
681
        l.rfe
682
        l.nop
683
 
684
exception_exit:
685
        /* Exception handler not set, exit */
686
        l.jal   exit
687
        l.or    r3,r4,r4
688
 
689
 
690
 
691
/* -------------------------------------------------------------------------- */
692
/*!Function to add handler to table
693
                                                                              */
694
/* -------------------------------------------------------------------------- */
695
        .global or1k_exception_handler_add
696
        .type   or1k_exception_handler_add,@function
697
 
698
        .extern or1k_exception_handler_table
699
 
700
        /* r3 should have exception number (2 for buserr, 5 for tick, etc.) */
701
        /* r4 should have handler function address */
702
or1k_exception_handler_add:
703
        l.addi  r1,r1,-4
704
        l.sw    0(r1),r5
705
        /* Convert exception number into word address */
706
        l.slli  r3,r3,2
707
        l.addi  r3,r3,-8
708
        /* Get address of exception handler table */
709
        l.movhi r5,hi(or1k_exception_handler_table)
710
        l.ori   r5,r5,lo(or1k_exception_handler_table)
711
        /* Add handler offset to table base */
712
        l.add   r5,r5,r3
713
        /* Store handler function address */
714
        l.sw    0(r5),r4
715
        /* Restore r5 */
716
        l.lwz   r5,0(r1)
717
        /* Return via link register */
718
        l.jr    r9
719
        /* Restore stack value */
720
        l.addi  r1,r1,4
721
 

powered by: WebSVN 2.1.0

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