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

Subversion Repositories openrisc

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

Go to most recent revision | 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 812 stekern
        l.add   r14,r6,r7
415 517 julius
        l.add   r13,r6,r12
416
 
417
        /* Fetch handler function address */
418 812 stekern
        l.lwz   r14,0(r14)
419 517 julius
 
420
        /* Double check it's valid, compare against INTERRUPT_HANDLER_NOT_SET */
421 812 stekern
        l.sfne  r14,r8
422 517 julius
        /* 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 812 stekern
        l.jalr  r14
431 517 julius
        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
        /* Get address of interrupt handler table */
467
        l.movhi r6,hi(or1k_interrupt_handler_table)
468
        l.ori   r6,r6,lo(or1k_interrupt_handler_table)
469
        /* Add handler offset to table base */
470
        l.add   r6,r6,r3
471
        /* Store handler function address */
472
        l.sw    0(r6),r4
473
        /* Get address of interrupt handler data ptr table */
474
        l.movhi r6,hi(or1k_interrupt_handler_data_ptr_table)
475
        l.ori   r6,r6,lo(or1k_interrupt_handler_data_ptr_table)
476
        /* Add handler offset to table base */
477
        l.add   r6,r6,r3
478
        /* Store handler data pointer address */
479
        l.sw    0(r6),r5
480
        /* Restore r6 */
481
        l.lwz   r6,0(r1)
482
        /* Return via link register */
483
        l.jr    r9
484
        /* Restore stack value */
485
        l.addi  r1,r1,4
486
 
487
 
488
/* -------------------------------------------------------------------------- */
489
/*!Function to enable an interrupt handler in the PICMR
490
                                                                              */
491
/* -------------------------------------------------------------------------- */
492
        .global or1k_interrupt_enable
493
        .type   or1k_interrupt_enable,@function
494
 
495
        /* r3 should have IRQ line for peripheral */
496
or1k_interrupt_enable:
497
        l.addi  r1,r1,-4
498
        l.sw    0(r1),r4
499
        l.ori   r4,r0,0x1
500
        l.sll   r4,r4,r3
501
        l.mfspr r3,r0,SPR_PICMR
502
        l.or    r3,r3,r4
503
        l.mtspr r0,r3,SPR_PICMR
504
        l.lwz   r4,0(r1)
505
        l.jr    r9
506
        l.addi  r1,r1,4
507
 
508
/* -------------------------------------------------------------------------- */
509
/*!Function to disable an interrupt handler in the PICMR
510
                                                                              */
511
/* -------------------------------------------------------------------------- */
512
        .global or1k_interrupt_disable
513
        .type   or1k_interrupt_disable,@function
514
 
515
        /* r3 should have IRQ line for peripheral */
516
or1k_interrupt_disable:
517
        l.addi  r1,r1,-4
518
        l.sw    0(r1),r4
519
        l.ori   r4,r0,0x1
520
        l.sll   r4,r4,r3
521
        l.xori  r4,r4,0xffff
522
        l.mfspr r3,r0,SPR_PICMR
523
        l.and   r3,r3,r4
524
        l.mtspr r0,r3,SPR_PICMR
525
        l.lwz   r4,0(r1)
526
        l.jr    r9
527
        l.addi  r1,r1,4
528
 
529
 
530
/* -------------------------------------------------------------------------- */
531
/*!Generic exception handler function
532
                                                                              */
533
/* -------------------------------------------------------------------------- */
534
// Warning - this must be the same as specified in crt0.S
535
#define EXCEPTION_STACK_SIZE 128+128
536
 
537
// Value handler addresses are initialised to
538
#define EXCEPTION_HANDLER_NOT_SET -1
539
 
540
 
541
        .data
542
        .align 4
543
        .global or1k_exception_handler_table
544
        .extern _interrupt_handler
545
or1k_exception_handler_table:
546
or1k_exception_handler_buserr:          .long   EXCEPTION_HANDLER_NOT_SET
547
or1k_exception_handler_dpfault:         .long   EXCEPTION_HANDLER_NOT_SET
548
or1k_exception_handler_ipfault:         .long   EXCEPTION_HANDLER_NOT_SET
549
or1k_exception_handler_tick:            .long   EXCEPTION_HANDLER_NOT_SET
550
or1k_exception_handler_align:           .long   EXCEPTION_HANDLER_NOT_SET
551
or1k_exception_handler_illegal:         .long   EXCEPTION_HANDLER_NOT_SET
552
or1k_exception_handler_interrupt:       .long   EXCEPTION_HANDLER_NOT_SET
553
or1k_exception_handler_dtlbmiss:        .long   EXCEPTION_HANDLER_NOT_SET
554
or1k_exception_handler_itlbmiss:        .long   EXCEPTION_HANDLER_NOT_SET
555
or1k_exception_handler_range:           .long   EXCEPTION_HANDLER_NOT_SET
556
or1k_exception_handler_systemcall:      .long   EXCEPTION_HANDLER_NOT_SET
557
or1k_exception_handler_float:           .long   EXCEPTION_HANDLER_NOT_SET
558
or1k_exception_handler_trap:            .long   EXCEPTION_HANDLER_NOT_SET
559
or1k_exception_handler_reserved0:       .long   EXCEPTION_HANDLER_NOT_SET
560
or1k_exception_handler_reserved1:       .long   EXCEPTION_HANDLER_NOT_SET
561
or1k_exception_handler_reserved2:       .long   EXCEPTION_HANDLER_NOT_SET
562
or1k_exception_handler_reserved3:       .long   EXCEPTION_HANDLER_NOT_SET
563
or1k_exception_handler_reserved4:       .long   EXCEPTION_HANDLER_NOT_SET
564
or1k_exception_handler_reserved5:       .long   EXCEPTION_HANDLER_NOT_SET
565
or1k_exception_handler_reserved6:       .long   EXCEPTION_HANDLER_NOT_SET
566
or1k_exception_handler_reserved7:       .long   EXCEPTION_HANDLER_NOT_SET
567
or1k_exception_handler_reserved8:       .long   EXCEPTION_HANDLER_NOT_SET
568
or1k_exception_handler_reserved9:       .long   EXCEPTION_HANDLER_NOT_SET
569
or1k_exception_handler_reserved10:      .long   EXCEPTION_HANDLER_NOT_SET
570
or1k_exception_handler_reserved11:      .long   EXCEPTION_HANDLER_NOT_SET
571
or1k_exception_handler_reserved12:      .long   EXCEPTION_HANDLER_NOT_SET
572
or1k_exception_handler_reserved13:      .long   EXCEPTION_HANDLER_NOT_SET
573
or1k_exception_handler_reserved14:      .long   EXCEPTION_HANDLER_NOT_SET
574
or1k_exception_handler_reserved15:      .long   EXCEPTION_HANDLER_NOT_SET
575
 
576
/* -------------------------------------------------------------------------- */
577
/*!Function to call appropriate exception handler
578
                                                                              */
579
/* -------------------------------------------------------------------------- */
580
        .section .text
581
        .global or1k_exception_handler
582
        .type   or1k_exception_handler,@function
583
 
584
        /*
585
        r3 = address of exception vector
586
        r4 = address where exception occurred
587
        */
588
 
589
or1k_exception_handler:
590
        /* Store remainder of state (r3,r4 stored in vector entry)*/
591
        l.sw    0x00(r1), r2
592
        l.sw    0x0c(r1), r5
593
        l.sw    0x10(r1), r6
594
        l.sw    0x14(r1), r7
595
        l.sw    0x18(r1), r8
596
        l.sw    0x1c(r1), r9
597
        l.sw    0x20(r1), r10
598
        l.sw    0x24(r1), r11
599
        l.sw    0x28(r1), r12
600
        l.sw    0x2c(r1), r13
601
        l.sw    0x30(r1), r14
602
        l.sw    0x34(r1), r15
603
        l.sw    0x38(r1), r16
604
        l.sw    0x3c(r1), r17
605
        l.sw    0x40(r1), r18
606
        l.sw    0x44(r1), r19
607
        l.sw    0x48(r1), r20
608
        l.sw    0x4c(r1), r21
609
        l.sw    0x50(r1), r22
610
        l.sw    0x54(r1), r23
611
        l.sw    0x58(r1), r24
612
        l.sw    0x5c(r1), r25
613
        l.sw    0x60(r1), r26
614
        l.sw    0x64(r1), r27
615
        l.sw    0x68(r1), r28
616
        l.sw    0x6c(r1), r29
617
        l.sw    0x70(r1), r30
618
        l.sw    0x74(r1), r31
619
 
620
        /* Determine offset in table of exception handler using r3*/
621
        l.andi  r13,r3,0xffff
622
        l.srli  r13,r13,6
623
        /* Substract 2 words, as we have no vector at 0 and no reset handler */
624
        l.addi  r13,r13,-8
625
        /* r13 now contains offset in or1k_exception_handler_table for
626
           function
627
        */
628
        /* Get or1k_exception_handler_table address */
629
        l.movhi r14,hi(or1k_exception_handler_table)
630
        l.ori   r14,r14,lo(or1k_exception_handler_table)
631
        /* r14 now contains base of exception handler table */
632
        l.add   r14,r14,r13
633
        l.lwz   r13, 0(r14)
634
 
635
        /* Check to see if this handler has been set yet */
636
        l.movhi r15,hi(EXCEPTION_HANDLER_NOT_SET)
637
        l.ori   r15,r15,lo(EXCEPTION_HANDLER_NOT_SET)
638
        l.sfne  r13,r15
639
        l.bnf   exception_exit
640
        l.nop
641
 
642
        /* Call exception handler, copy EPCR to r3 */
643
        l.jalr  r13
644
        l.or    r3,r4,r4
645
 
646
        /* Restore state */
647
        l.lwz    r2, 0x00(r1)
648
        l.lwz    r3, 0x04(r1)
649
        l.lwz    r4, 0x08(r1)
650
        l.lwz    r5, 0x0c(r1)
651
        l.lwz    r6, 0x10(r1)
652
        l.lwz    r7, 0x14(r1)
653
        l.lwz    r8, 0x18(r1)
654
        l.lwz    r9, 0x1c(r1)
655
        l.lwz    r10, 0x20(r1)
656
        l.lwz    r11, 0x24(r1)
657
        l.lwz    r12, 0x28(r1)
658
        l.lwz    r13, 0x2c(r1)
659
        l.lwz    r14, 0x30(r1)
660
        l.lwz    r15, 0x34(r1)
661
        l.lwz    r16, 0x38(r1)
662
        l.lwz    r17, 0x3c(r1)
663
        l.lwz    r18, 0x40(r1)
664
        l.lwz    r19, 0x44(r1)
665
        l.lwz    r20, 0x48(r1)
666
        l.lwz    r21, 0x4c(r1)
667
        l.lwz    r22, 0x50(r1)
668
        l.lwz    r23, 0x54(r1)
669
        l.lwz    r24, 0x58(r1)
670
        l.lwz    r25, 0x5c(r1)
671
        l.lwz    r26, 0x60(r1)
672
        l.lwz    r27, 0x64(r1)
673
        l.lwz    r28, 0x68(r1)
674
        l.lwz    r29, 0x6c(r1)
675
        l.lwz    r30, 0x70(r1)
676
        l.lwz    r31, 0x74(r1)
677
 
678
        l.addi  r1, r1, EXCEPTION_STACK_SIZE
679
 
680
        l.rfe
681
        l.nop
682
 
683
exception_exit:
684
        /* Exception handler not set, exit */
685
        l.jal   exit
686
        l.or    r3,r4,r4
687
 
688
 
689
 
690
/* -------------------------------------------------------------------------- */
691
/*!Function to add handler to table
692
                                                                              */
693
/* -------------------------------------------------------------------------- */
694
        .global or1k_exception_handler_add
695
        .type   or1k_exception_handler_add,@function
696
 
697
        .extern or1k_exception_handler_table
698
 
699
        /* r3 should have exception number (2 for buserr, 5 for tick, etc.) */
700
        /* r4 should have handler function address */
701
or1k_exception_handler_add:
702
        l.addi  r1,r1,-4
703
        l.sw    0(r1),r5
704
        /* Convert exception number into word address */
705
        l.slli  r3,r3,2
706
        l.addi  r3,r3,-8
707
        /* Get address of exception handler table */
708
        l.movhi r5,hi(or1k_exception_handler_table)
709
        l.ori   r5,r5,lo(or1k_exception_handler_table)
710
        /* Add handler offset to table base */
711
        l.add   r5,r5,r3
712
        /* Store handler function address */
713
        l.sw    0(r5),r4
714
        /* Restore r5 */
715
        l.lwz   r5,0(r1)
716
        /* Return via link register */
717
        l.jr    r9
718
        /* Restore stack value */
719
        l.addi  r1,r1,4
720 812 stekern
 

powered by: WebSVN 2.1.0

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