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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [armnommu/] [kernel/] [entry-armv.S] - Blame information for rev 199

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * linux/arch/arm/lib/traps-arm6.S
3
 *
4
 * Copyright (C) 1996 Russell King.
5
 * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk)
6
 *
7
 * Low-level vector interface routines
8
 *
9
 * Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes
10
 * it to save wrong values...  Be aware!
11
 */
12
#include 
13
#include 
14
#include 
15
#include 
16
 
17
#define current current_set
18
 
19
#ifdef IOC_BASE
20
/* IOC / IOMD based hardware */
21
                .equ    ioc_base_high, IOC_BASE & 0xff000000
22
                .equ    ioc_base_low, IOC_BASE & 0x00ff0000
23
                .macro  disable_fiq
24
                mov     r12, #ioc_base_high
25
                .if     ioc_base_low
26
                orr     r12, r12, #ioc_base_low
27
                .endif
28
                strb    r12, [r12, #0x38]       @ Disable FIQ register
29
                .endm
30
 
31
                .macro  get_irqnr_and_base, irqnr, base
32
                mov     r4, #ioc_base_high              @ point at IOC
33
                .if     ioc_base_low
34
                orr     r4, r4, #ioc_base_low
35
                .endif
36
                ldrb    \irqnr, [r4, #0x24]             @ get high priority first
37
                adr     \base, irq_prio_h
38
                teq     \irqnr, #0
39
#ifdef IOMD_BASE
40
                ldreqb  \irqnr, [r4, #0x1f4]            @ get dma
41
                adreq   \base, irq_prio_d
42
                teqeq   \irqnr, #0
43
#endif
44
                ldreqb  \irqnr, [r4, #0x14]             @ get low priority
45
                adreq   \base, irq_prio_l
46
                .endm
47
 
48
/*
49
 * Interrupt table (incorporates priority)
50
 */
51
                .macro  irq_prio_table
52
irq_prio_l:     .byte    0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
53
                .byte    4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
54
                .byte    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
55
                .byte    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
56
                .byte    6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
57
                .byte    6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
58
                .byte    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
59
                .byte    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
60
                .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
61
                .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
62
                .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
63
                .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
64
                .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
65
                .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
66
                .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
67
                .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
68
#ifdef IOMD_BASE
69
irq_prio_d:     .byte    0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
70
                .byte   20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
71
                .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
72
                .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
73
                .byte   22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
74
                .byte   22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
75
                .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
76
                .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
77
                .byte   23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
78
                .byte   23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
79
                .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
80
                .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
81
                .byte   22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
82
                .byte   22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
83
                .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
84
                .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
85
#endif
86
irq_prio_h:     .byte    0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
87
                .byte   12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
88
                .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
89
                .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
90
                .byte   14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
91
                .byte   14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
92
                .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
93
                .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
94
                .byte   15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
95
                .byte   15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
96
                .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
97
                .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
98
                .byte   15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
99
                .byte   15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
100
                .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
101
                .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
102
                .endm
103
 
104
#elif defined(CONFIG_ARCH_EBSA110)
105
 
106
                .macro  disable_fiq
107
                .endm
108
 
109
                .macro  get_irqnr_and_base, irqnr, base
110
                mov     r4, #0xf3000000
111
                ldrb    \irqnr, [r4]                    @ get interrupts
112
                adr     \base, irq_prio_ebsa110
113
                .endm
114
 
115
                .macro  irq_prio_table
116
irq_prio_ebsa110:
117
                .byte    0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
118
                .byte    4, 4, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
119
                .byte    5, 5, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
120
                .byte    5, 5, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
121
 
122
                .byte    6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
123
                .byte    6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
124
                .byte    6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
125
                .byte    6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
126
 
127
                .byte    7, 0, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
128
                .byte    4, 4, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
129
                .byte    5, 5, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
130
                .byte    5, 5, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2
131
 
132
                .byte    6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
133
                .byte    6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
134
                .byte    6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
135
                .byte    6, 6, 6, 6, 2, 2, 2, 2, 3, 3, 6, 6, 2, 2, 2, 2
136
                .endm
137
 
138
#elif defined(CONFIG_ARCH_TRIO)
139
 
140
                .macro  disable_fiq
141
                .endm
142
 
143
                .macro  get_irqnr_and_base, irqnr, base
144
                ldr r4, =AIC_IVR
145
                ldr             \irqnr, [r4]                    @ get interrupts
146
                bic             \irqnr, \irqnr, #0xffffffe0
147
                adr     \base, irq_prio_trio
148
                .endm
149
 
150
                .macro  irq_prio_table
151
irq_prio_trio:
152
                .byte   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
153
                .endm
154
 
155
#else
156
#error Unknown architecture
157
#endif
158
 
159
                .text
160
 
161
@ Offsets into task structure
162
@ ---------------------------
163
@
164
#define STATE           0
165
#define COUNTER         4
166
#define PRIORITY        8
167
#define SIGNAL          12
168
#define BLOCKED         16
169
#define FLAGS           20
170
#define ERRNO           24
171
 
172
#define PF_TRACESYS     0x20
173
 
174
@ Bad Abort numbers
175
@ -----------------
176
@
177
#define BAD_PREFETCH    0
178
#define BAD_DATA        1
179
#define BAD_ADDREXCPTN  2
180
#define BAD_IRQ         3
181
#define BAD_UNDEFINSTR  4
182
 
183
@ Number of syscalls accepted
184
@
185
#define NSYS_CALL       142
186
 
187
@ OS version number used in SWIs
188
@  RISC OS is 0
189
@  RISC iX is 8
190
@
191
#define OS_NUMBER       9
192
 
193
@
194
@ Stack format (ensured by USER_* and SVC_*)
195
@
196
#define S_FRAME_SIZE    72
197
#define S_OLD_R0        68
198
#define S_PSR           64
199
#define S_PC            60
200
#define S_LR            56
201
#define S_SP            52
202
#define S_IP            48
203
#define S_FP            44
204
#define S_R10           40
205
#define S_R9            36
206
#define S_R8            32
207
#define S_R7            28
208
#define S_R6            24
209
#define S_R5            20
210
#define S_R4            16
211
#define S_R3            12
212
#define S_R2            8
213
#define S_R1            4
214
#define S_R0            0
215
 
216
#include "../lib/constants.h"
217
 
218
                .global _ret_from_sys_call,ret_from_sys_call
219
 
220
/*
221
 *================================================================================================
222
 *              Low-level interface code
223
 *------------------------------------------------------------------------------------------------
224
 *              Trap initialisation
225
 *------------------------------------------------------------------------------------------------
226
 *
227
 * Note - FIQ code has changed.  The default is a couple of words in 0x1c, 0x20
228
 * that call _unexp_fiq.  Nowever, we now copy the FIQ routine to 0x1c (removes
229
 * some excess cycles).
230
 *
231
 * What we need to put into 0-0x1c are ldrs to branch to 0xC0000000
232
 * (the kernel).
233
 * 0x1c onwards is reserved for FIQ, so I think that I will allocate 0xe0 onwards for
234
 * the actuall address to jump to.
235
 */
236
/*
237
 * these go into 0x00
238
 */
239
Lbranches:      swi     SYS_ERROR0
240
                ldr     pc, Lbranches + 0xe4
241
                ldr     pc, Lbranches + 0xe8
242
                ldr     pc, Lbranches + 0xec
243
                ldr     pc, Lbranches + 0xf0
244
                ldr     pc, Lbranches + 0xf4
245
                ldr     pc, Lbranches + 0xf8
246
                ldr     pc, . + 4
247
                .word   _unexp_fiq
248
/*
249
 * this is put into 0xe0 and above
250
 */
251
jump_addresses: .word   0
252
                .word   vector_undefinstr
253
                .word   vector_swi
254
                .word   vector_prefetch
255
                .word   vector_data
256
                .word   vector_addrexcptn
257
                .word   vector_IRQ
258
/*
259
 * initialise the trap system
260
 */
261
                .global _trap_init,trap_init
262
 
263
trap_init:
264
_trap_init:     stmfd   sp !,{r4 - r9, lr}              @ Save link register
265
                mrs     r0, cpsr
266
                bic     r0, r0, #31
267
                orr     r0, r0, #0xd3
268
                msr     cpsr, r0
269
                mov     r0, #0xe0
270
                adr     r1, jump_addresses
271
                ldmia   r1, {r1 - r7}
272
                stmia   r0, {r1 - r7}
273
                mov     r0, #0                          @ Lowest location
274
                adr     r1, Lbranches
275
                ldmia   r1, {r1 - r9}
276
                stmia   r0, {r1 - r9}                   @ Save all into page 0 ram
277
                ldmfd   sp!, {r4 - r9, pc}
278
/*
279
 *------------------------------------------------------------------------------------------------
280
 * Undefined FIQs
281
 *------------------------------------------------------------------------------------------------
282
 * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
283
 * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
284
 * Basically to switch modes, we *HAVE* to clobber one register...  brain damage alert!
285
 * I don't think that we can execute any code in here in any other mode than FIQ...  Ok
286
 * you can switch to another mode, but you can't get out of that mode without clobbering one
287
 * register.
288
 */
289
_unexp_fiq:     disable_fiq
290
                subs    pc, lr, #4
291
/*
292
 *------------------------------------------------------------------------------------------------
293
 * Interrupt entry dispatcher - dispatches it to the correct handler for the processor mode
294
 *------------------------------------------------------------------------------------------------
295
 * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
296
 */
297
                .global vector_IRQ,vector_undefinstr,vector_data,vector_prefetch,vector_swi
298
 
299
 
300
LCirq:          .word   __temp_irq
301
vector_IRQ:     @
302
                @ save mode specific registers
303
                @
304
                ldr     r13, LCirq
305
                sub     lr, lr, #4
306
                str     lr, [r13]                       @ save lr_IRQ
307
                mrs     lr, spsr
308
                str     lr, [r13, #4]                   @ save spsr_IRQ
309
                @
310
                @ now branch to the relevent MODE handling routine
311
                @
312
                mrs     sp, cpsr                        @ switch to SVC mode
313
                bic     sp, sp, #31
314
                orr     sp, sp, #0x13
315
                msr     spsr, sp
316
                and     lr, lr, #15
317
                cmp     lr, #4
318
                addlts  pc, pc, lr, lsl #2              @ Changes mode and branches
319
                b       __irq_invalid                   @  4 - 15
320
                b       __irq_usr                       @  0  (USR_26 / USR_32)
321
                b       __irq_invalid                   @  1  (FIQ_26 / FIQ_32)
322
                b       __irq_invalid                   @  2  (IRQ_26 / IRQ_32)
323
                b       __irq_svc                       @  3  (SVC_26 / SVC_32)
324
/*
325
 *------------------------------------------------------------------------------------------------
326
 * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode
327
 *------------------------------------------------------------------------------------------------
328
 * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
329
 */
330
LCund:          .word   __temp_und
331
vector_undefinstr:
332
                @
333
                @ save mode specific registers
334
                @
335
                ldr     r13, [pc, #LCund - . - 8]
336
                str     lr, [r13]
337
                mrs     lr, spsr
338
                str     lr, [r13, #4]
339
                @
340
                @ now branch to the relevent MODE handling routine
341
                @
342
                mrs     sp, cpsr
343
                bic     sp, sp, #31
344
                orr     sp, sp, #0x13
345
                msr     spsr, sp
346
                and     lr, lr, #15
347
                cmp     lr, #4
348
                addlts  pc, pc, lr, lsl #2              @ Changes mode and branches
349
                b       __und_invalid                   @  4 - 15
350
                b       __und_usr                       @  0 (USR_26 / USR_32)
351
                b       __und_invalid                   @  1 (FIQ_26 / FIQ_32)
352
                b       __und_invalid                   @  2 (IRQ_26 / IRQ_32)
353
                b       __und_svc                       @  3 (SVC_26 / SVC_32)
354
/*
355
 *------------------------------------------------------------------------------------------------
356
 * Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode
357
 *------------------------------------------------------------------------------------------------
358
 * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
359
 */
360
LCabt:          .word   __temp_abt
361
vector_prefetch:
362
                @
363
                @ save mode specific registers
364
                @
365
                sub     lr, lr, #4
366
                ldr     r13, LCabt
367
                str     lr, [r13]
368
                mrs     lr, spsr
369
                str     lr, [r13, #4]
370
                @
371
                @ now branch to the relevent MODE handling routine
372
                @
373
                mrs     sp, cpsr
374
                bic     sp, sp, #31
375
                orr     sp, sp, #0x13
376
                msr     spsr, sp
377
                and     lr, lr, #15
378
                cmp     lr, #4
379
                addlts  pc, pc, lr, lsl #2              @ Changes mode and branches
380
                b       __pabt_invalid                  @  4 - 15
381
                b       __pabt_usr                      @  0  (USR_26 / USR_32)
382
                b       __pabt_invalid                  @  1  (FIQ_26 / FIQ_32)
383
                b       __pabt_invalid                  @  2  (IRQ_26 / IRQ_32)
384
                b       __pabt_invalid                  @  3  (SVC_26 / SVC_32)
385
/*
386
 *------------------------------------------------------------------------------------------------
387
 * Data abort dispatcher - dispatches it to the correct handler for the processor mode
388
 *------------------------------------------------------------------------------------------------
389
 * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
390
 */
391
vector_data:    @
392
                @ save mode specific registers
393
                @
394
                sub     lr, lr, #8
395
                ldr     r13, LCabt
396
                str     lr, [r13]
397
                mrs     lr, spsr
398
                str     lr, [r13, #4]
399
                @
400
                @ now branch to the relevent MODE handling routine
401
                @
402
                mrs     sp, cpsr
403
                bic     sp, sp, #31
404
                orr     sp, sp, #0x13
405
                msr     spsr, sp
406
                and     lr, lr, #15
407
                cmp     lr, #4
408
                addlts  pc, pc, lr, lsl #2              @ Changes mode & branches
409
                b       __dabt_invalid                  @  4 - 15
410
                b       __dabt_usr                      @  0  (USR_26 / USR_32)
411
                b       __dabt_invalid                  @  1  (FIQ_26 / FIQ_32)
412
                b       __dabt_invalid                  @  2  (IRQ_26 / IRQ_32)
413
                b       __dabt_svc                      @  3  (SVC_26 / SVC_32)
414
/*
415
 *===============================================================================
416
 * SWI handler
417
 *-------------------------------------------------------------------------------
418
 *
419
 * We now handle sys-call tracing, and the errno in the task structure.
420
 * Still have a problem with >4 arguments for functions.  Theres only
421
 * a couple of functions in the code that have 5 arguments, so Im not
422
 * too worried.
423
 */
424
 
425
#include "calls.S"
426
 
427
LC1:            .word   current
428
/*
429
 * Enter in SVC mode, spsr_all = OLD_USER_cpsr_all, R14 = OLD_USER_PC
430
 */
431
vector_swi:     sub     sp, sp, #S_FRAME_SIZE
432
                stmia   sp, {r0 - r12}                  @ Calling r0 - r12
433
                add     r8, sp, #S_PC
434
                stmdb   r8, {sp, lr}^                   @ Calling sp, lr
435
                mov     r7, r0
436
                mrs     r6, spsr
437
                mov     r5, lr
438
                stmia   r8, {r5, r6, r7}                @ Save calling PC, CPSR, OLD_R0
439
                mov     fp, #0
440
                ldr     r6, [lr, #-4]!                  @ get swi instruction
441
                and     r5, r6, #0x0f000000
442
                teq     r5, #0x0f000000
443
                bne     Larm700bug
444
                mrs     r5, cpsr                        @ enable irqs
445
                bic     r5, r5, #I_BIT
446
                msr     cpsr, r5
447
                bic     r6, r6, #0xff000000             @ mask off swi op code
448
                eor     r6, r6, #OS_NUMBER << 20        @ check OS number
449
Lretry:         cmp     r6, #NR_SYSCALLS                @ check upper syscall limit
450
                bcs     Lswi_bad_call
451
 
452
                ldr     r5, [pc, #LC1 - . - 8]
453
                ldr     r5, [r5]
454
                mov     ip, #0                          @ zero errno
455
                str     ip, [r5, #ERRNO]
456
 
457
                ldr     ip, [r5, #FLAGS]                @ check for syscall tracing
458
                tst     ip, #PF_TRACESYS
459
                bne     Ltrace_this_syscall
460
 
461
                adr     ip, _sys_call_table
462
                mov     r9, sp                          @ hack for routines needing > 4 values
463
                str     r4, [sp, #-4]!                  @ new-style: (r0 = arg1, r4 = arg5)
464
                mov     lr, pc
465
                ldr     pc, [ip, r6, lsl #2]            @ call sys routine
466
                add     sp, sp, #4
467
 
468
                ldr     ip, [r5, #ERRNO]                @ check errno
469
                rsbs    ip, ip, #0
470
                movne   r0, ip
471
                str     r0, [sp, #S_R0]                 @ returned r0
472
                b       _ret_from_sys_call
473
 
474
Ltrace_this_syscall:
475
                ldr     r7, [sp, #S_IP]
476
                mov     r0, #0
477
                str     r0, [sp, #S_IP]
478
                bl      syscall_trace                   @ trace entry [IP must = 0]
479
                str     r7, [sp, #S_IP]
480
                ldmia   sp, {r0 - r3}                   @ have to reload r0 - r3
481
 
482
                adr     ip, _sys_call_table
483
                mov     r9, sp                          @ hack for routines needing > 4 values
484
                str     r4, [sp, #-4]!                  @ new-style: (r0 = arg1, r4 = arg5)
485
                mov     lr, pc
486
                ldr     pc, [ip, r6, lsl #2]            @ call sys routine
487
                add     sp, sp, #4
488
 
489
                ldr     ip, [r5, #ERRNO]
490
                rsbs    ip, ip, #0
491
                movne   r0, ip
492
                str     r0, [sp, #S_R0]                 @ returned r0
493
 
494
                mov     r0, #1
495
                str     r0, [sp, #S_IP]
496
                bl      syscall_trace                   @ trace exit [IP must != 0]
497
                str     r7, [sp, #S_IP]
498
                b       _ret_from_sys_call
499
 
500
Lswi_bad_call:  tst     r6, #0x00f00000
501
                bne     Lbad
502
                cmp     r6, #(KSWI_SYS_BASE - KSWI_BASE) @ check for arm private syscalls
503
                bcs     Larm_sys_call
504
                bl      sys_ni_syscall
505
                str     r0, [sp, #0]                    @ returned r0
506
                b       _ret_from_sys_call
507
 
508
Lbad:           eor     r0, r6, #OS_NUMBER << 20        @ Put OS number back
509
                mov     r1, sp
510
                bl      deferred
511
                ldmfd   sp, {r0 - r3}
512
                b       _ret_from_sys_call
513
 
514
Larm_sys_call:  bic     r0, r6, #0x000f0000
515
                mov     r1, sp
516
                bl      arm_syscall
517
                b       _ret_from_sys_call
518
 
519
@ r0 = syscall number
520
@ r1 = syscall r0
521
@ r5 = syscall r4
522
@ ip = syscall table
523
sys_syscall:    mov     r6, r0
524
                eor     r6, r6, #OS_NUMBER << 20
525
                cmp     r6, #NR_SYSCALLS                @ check range
526
                movgt   r0, #-ENOSYS
527
                movgt   pc, lr
528
                add     sp, sp, #4                      @ take of the save of our r4
529
                ldmib   sp, {r0 - r4}                   @ get our args
530
                str     r4, [sp, #-4]!                  @ Put our arg on the stack
531
                ldr     pc, [ip, r6, lsl #2]
532
 
533
Larm700bug:     str     lr, [r8]
534
                ldr     r0, [sp, #S_PSR]                @ Get calling cpsr
535
                msr     spsr, r0
536
                ldmia   sp, {r0 - lr}^                  @ Get calling r0 - lr
537
                mov     r0, r0
538
                add     sp, sp, #S_PC
539
                ldr     lr, [sp], #S_FRAME_SIZE - S_PC  @ Get PC and jump over PC, PSR, OLD_R0
540
                movs    pc, lr
541
 
542
                .globl  _sys_call_table,sys_call_table
543
sys_call_table:
544
_sys_call_table:
545
#include "calls.S"
546
 
547
/*
548
 *================================================================================================
549
 * Undefined instruction handler
550
 *------------------------------------------------------------------------------------------------
551
 */
552
LC2:            .word   last_task_used_math
553
                .word   current
554
                .word   fp_enter
555
 
556
__und_usr:      sub     sp, sp, #S_FRAME_SIZE           @ Allocate frame size in one go
557
                stmia   sp, {r0 - r12}                  @ Save r0 - r12
558
                add     r8, sp, #S_PC
559
                stmdb   r8, {sp, lr}^                   @ Save user r0 - r12
560
                ldr     r4, [pc, #LCund - . - 8]
561
                ldmia   r4, {r5 - r7}
562
                stmia   r8, {r5 - r7}                   @ Save USR pc, cpsr, old_r0
563
 
564
                adr     r1, LC2
565
                ldmia   r1, {r1, r2, r4}
566
                ldr     r1, [r1]
567
                ldr     r2, [r2]
568
                teq     r1, r2
569
                blne    math_state_restore
570
                adr     r9, _fpreturn
571
                adr     lr, _fpundefinstr
572
                ldr     pc, [r4]                        @ Call FP module USR entry point
573
 
574
                .global _fpreturn,fpreturn
575
                .global _fpundefinstr,fpundefinstr
576
fpundefinstr:
577
_fpundefinstr:  mov     r0, lr                          @ Called by FP module on undefined instr
578
                mov     r1, sp
579
                mrs     r4, cpsr                        @ Enable interrupts
580
                bic     r4, r4, #I_BIT
581
                msr     cpsr, r4
582
                bl      do_undefinstr
583
fpreturn:
584
_fpreturn:      b       _ret_from_sys_call              @ Normal FP exit
585
 
586
__und_svc:      sub     sp, sp, #S_FRAME_SIZE
587
                stmia   sp, {r0 - r12}                  @ save r0 - r12
588
                mov     r6, lr
589
                mov     fp, #0
590
                ldr     r7, [pc, #LCund - . - 8]
591
                ldmia   r7, {r7 - r9}
592
                add     r5, sp, #S_FRAME_SIZE
593
                add     r4, sp, #S_SP
594
                stmia   r4, {r5 - r9}                   @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
595
 
596
                adr     r1, LC2
597
                ldmia   r1, {r1, r2, r4}
598
                ldr     r1, [r1]
599
                ldr     r2, [r2]
600
                teq     r1, r2
601
                blne    math_state_restore
602
                adr     r9, _fpreturnsvc
603
                adr     lr, _fpundefinstrsvc
604
                ldr     pc, [r4]                        @ Call FP module SVC entry point
605
 
606
                .globl  _fpreturnsvc,fpreturnsvc
607
                .globl  _fpundefinstrsvc,fpundefinstrsvc
608
 
609
fpundefinstrsvc:
610
_fpundefinstrsvc:
611
                mov     r0, r5                          @ unsigned long pc
612
                mov     r1, sp                          @ struct pt_regs *regs
613
                bl      do_undefinstr
614
fpreturnsvc:
615
_fpreturnsvc:   ldr     lr, [sp, #S_PSR]                @ Get SVC cpsr
616
                msr     spsr, lr
617
                ldmia   sp, {r0 - pc}^                  @ Restore SVC registers
618
 
619
/* We get here if an undefined instruction happens and the floating
620
 * point emulator is not present.  If the offending instruction was
621
 * a WFS, we just perform a normal return as if we had emulated the
622
 * operation.  This is a hack to allow some basic userland binaries
623
 * to run so that the emulator module proper can be loaded. --philb
624
 */
625
fpe_not_present:
626
                adr     r10, wfs_mask_data
627
                ldmia   r10, {r4, r5, r6, r7, r8}
628
                ldr     r10, [sp, #S_PC]                @ Load PC
629
                sub     r10, r10, #4
630
                ldrt    r10, [r10]                      @ get instruction
631
                and     r5, r10, r5
632
                teq     r5, r4                          @ Is it WFS?
633
                moveq   pc, r9
634
                and     r5, r10, r8
635
                teq     r5, r6                          @ Is it LDF/STF on sp or fp?
636
                teqne   r5, r7
637
                movne   pc, lr
638
                tst     r10, #0x00200000                @ Does it have WB
639
                moveq   pc, r9
640
                and     r4, r10, #255                   @ get offset
641
                and     r6, r10, #0x000f0000
642
                tst     r10, #0x00800000                @ +/-
643
                rsbeq   r4, r4, #0
644
                ldr     r5, [sp, r6, lsr #14]           @ Load reg
645
                add     r5, r5, r4, lsl #2
646
                str     r5, [sp, r6, lsr #14]           @ Save reg
647
                mov     pc, r9
648
 
649
wfs_mask_data:  .word   0x0e200110                      @ WFS
650
                .word   0x0fff0fff
651
                .word   0x0d0d0100                      @ LDF [sp]/STF [sp]
652
                .word   0x0d0b0100                      @ LDF [fp]/STF [fp]
653
                .word   0x0f0f0f00
654
 
655
 
656
LC3:            .word   _fp_save
657
                    .word       _fp_restore
658
 
659
 
660
/*
661
 * Function to call when switching tasks to save FP state
662
 */
663
                .global _fpe_save,fpe_save
664
fpe_save:
665
_fpe_save:      ldr     r1, [pc, #LC3 - . - 8]
666
                ldr     pc, [r1]
667
 
668
/*
669
 * Function to call when switching tasks to restore FP state
670
 */
671
                .global _fpe_restore,fpe_restore
672
fpe_restore:
673
_fpe_restore:   ldr     r1, [pc, #LC3 - . - 4]
674
                ldr     pc, [r1]
675
 
676
__und_invalid:  sub     sp, sp, #S_FRAME_SIZE
677
                stmia   sp, {r0 - lr}
678
                mov     r7, r0
679
                ldr     r4, [pc, #LCund - . - 8]
680
                ldmia   r4, {r5, r6}                    @ Get UND/IRQ/FIQ/ABT pc, cpsr
681
                add     r4, sp, #S_PC
682
                stmia   r4, {r5, r6, r7}                @ Save UND/IRQ/FIQ/ABT pc, cpsr, old_r0
683
                mov     r0, sp                          @ struct pt_regs *regs
684
                mov     r1, #BAD_UNDEFINSTR             @ int reason
685
                and     r2, r6, #31                     @ int mode
686
                b       bad_mode                        @ Does not ever return...
687
/*
688
 *================================================================================================
689
 * Prefetch abort handler
690
 *------------------------------------------------------------------------------------------------
691
 */
692
pabtmsg:        .ascii  "Pabt: %08lX\n\0"
693
                .align
694
__pabt_usr:     sub     sp, sp, #S_FRAME_SIZE           @ Allocate frame size in one go
695
                stmia   sp, {r0 - r12}                  @ Save r0 - r12
696
                add     r8, sp, #S_PC
697
                stmdb   r8, {sp, lr}^                   @ Save sp_usr lr_usr
698
                ldr     r4, [pc, #LCabt - . - 8]
699
                ldmia   r4, {r5 - r7}                   @ Get USR pc, cpsr
700
                stmia   r8, {r5 - r7}                   @ Save USR pc, cpsr, old_r0
701
 
702
                mrs     r7, cpsr                        @ Enable interrupts if they were
703
                bic     r7, r7, #I_BIT                  @ previously
704
                msr     cpsr, r7
705
                mov     r0, r5                          @ address (pc)
706
                mov     r1, sp                          @ regs
707
                bl      do_PrefetchAbort                @ call abort handler
708
                teq     r0, #0                          @ Does this still apply???
709
                bne     _ret_from_sys_call              @ Return from sys call
710
#ifdef DEBUG_UNDEF
711
                adr     r0, t
712
                bl      _printk
713
#endif
714
                mov     r0, r5
715
                mov     r1, sp
716
                and     r2, r6, #31
717
                bl      do_undefinstr
718
                ldr     lr, [sp, #S_PSR]                @ Get USR cpsr
719
                msr     spsr, lr
720
                ldmia   sp, {r0 - pc}^                  @ Restore USR registers
721
 
722
__pabt_invalid: sub     sp, sp, #S_FRAME_SIZE           @ Allocate frame size in one go
723
                stmia   sp, {r0 - lr}                   @ Save XXX r0 - lr
724
                mov     r7, r0                          @ OLD R0
725
                ldr     r4, [pc, #LCabt - . - 8]
726
                ldmia   r4, {r5 - r7}                   @ Get XXX pc, cpsr
727
                add     r4, sp, #S_PC
728
                stmia   r4, {r5 - r7}                   @ Save XXX pc, cpsr, old_r0
729
                mov     r0, sp                          @ Prefetch aborts are definitely *not*
730
                mov     r1, #BAD_PREFETCH               @ allowed in non-user modes.  We cant
731
                and     r2, r6, #31                     @ recover from this problem.
732
                b       bad_mode
733
 
734
#ifdef DEBUG_UNDEF
735
t:      .ascii "*** undef ***\r\n\0"
736
        .align
737
#endif
738
/*
739
 *================================================================================================
740
 * Address exception handler
741
 *------------------------------------------------------------------------------------------------
742
 * These aren't too critical. (they're not supposed to happen, and won't happen in 32-bit mode).
743
 */
744
 
745
vector_addrexcptn:
746
                b       vector_addrexcptn
747
 
748
/*
749
 *================================================================================================
750
 * Interrupt (IRQ) handler (r13 points to irq temp save area)
751
 * MOD: if in user mode, then *no* kernel routine is running, so dont have to
752
 *      save svc lr
753
 *------------------------------------------------------------------------------------------------
754
 */
755
LC4:            .word   irqjump
756
__irq_usr:      sub     sp, sp, #S_FRAME_SIZE
757
                stmia   sp, {r0 - r12}                  @ save r0 - r12
758
                add     r8, sp, #S_PC
759
                stmdb   r8, {sp, lr}^
760
                ldr     r4, [pc, #LCirq - . - 8]
761
                ldmia   r4, {r5 - r7}                   @ get saved PC, SPSR
762
                stmia   r8, {r5 - r7}                   @ save pc, psr, old_r0
763
urepeat:        get_irqnr_and_base r6, r5
764
#if defined(CONFIG_ARCH_TRIO)
765
                teq     r6, #0x1f
766
                bne     has_irq_usr
767
                ldr     r4,=AIC_EOICR
768
                eor     r6,r6,r6
769
                str     r6,[r4]
770
#else
771
                teq     r6, #0
772
                bne has_irq_usr
773
#endif
774
                b _ret_from_sys_call
775
has_irq_usr:
776
                ldrb    r0, [r5, r6]                    @ Get IRQ number
777
                ldr     r2, [pc, #LC4 - . - 8]
778
                mov     r1, sp
779
                mov     lr, pc
780
                @
781
                @ routine gets called with r0 = interrupt number, r1 = struct pt_regs *
782
                @
783
                ldr     pc, [r2, r0, lsl#2]
784
                mov     r2, #0
785
                teq     r0, #0                          @ Check to see if it is a fast IRQ
786
                beq     _ret_from_sys_call
787
                ldr     r0, [sp, #S_PSR]                @ Get saved SPSR
788
                msr     spsr, r0                        @ restore SPSR
789
                ldmia   sp, {r0 - lr}^                  @ Get calling r0 - lr
790
                mov     r0, r0
791
                add     sp, sp, #S_PC
792
                ldr     lr, [sp], #S_FRAME_SIZE - S_PC
793
                movs    pc, lr
794
 
795
                irq_prio_table
796
 
797
LC5:            .word   intr_count                      @ -8
798
                .word   bh_mask                 @ -4
799
                .word   bh_active                       @ -0
800
 
801
__irq_svc:      sub     sp, sp, #S_FRAME_SIZE
802
                stmia   sp, {r0 - r12}                  @ save r0 - r12
803
                mov     r6, lr
804
                mov     fp, #0
805
                ldr     r7, [pc, #LCirq - . - 8]
806
                ldmia   r7, {r7 - r9}
807
                add     r5, sp, #S_FRAME_SIZE
808
                add     r4, sp, #S_SP
809
                stmia   r4, {r5, r6, r7, r8, r9}        @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
810
srepeat:        get_irqnr_and_base r6, r5
811
#if defined(CONFIG_ARCH_TRIO)
812
                teq     r6, #0x1f
813
#else
814
                teq     r6, #0
815
#endif
816
                beq     no_irq2
817
                ldrb    r0, [r5, r6]                    @ Get IRQ number
818
                ldr     r2, [pc, #LC4 - . - 8]
819
                mov     r1, sp
820
                mov     lr, pc
821
                @
822
                @ routine gets called with r0 = interrupt number, r1 = struct pt_regs *
823
                @
824
                ldr     pc, [r2, r0, lsl #2]
825
                teq     r0, #0                          @ Check to see if it was a fast IRQ
826
                bne     srepeat
827
                ldr     r4, [pc, #LC5 - . - 8]
828
                ldr     r5, [r4]
829
                teq     r5, #0
830
                bne     srepeat
831
                ldr     r6, [pc, #LC5 - . - 4]
832
                ldr     r7, [pc, #LC5 - . - 0]
833
recheck_bh2:    ldr     r0, [r6]
834
                ldr     r1, [r7]
835
                tst     r0, r1
836
                beq     srepeat
837
                add     r0, r5, #1
838
                str     r0, [r4]
839
                mrs     r8, cpsr                        @ Enable interrupts
840
                bic     lr, r8, #I_BIT
841
                msr     cpsr, lr
842
                bl      do_bottom_half
843
                msr     cpsr, r8                        @ Restore interrupt state
844
                str     r5, [r4]
845
                b       recheck_bh2
846
no_irq2:
847
#if defined(CONFIG_ARCH_TRIO)
848
                ldr     r4, =AIC_EOICR
849
                eor     r6,r6,r6
850
                str r6,[r4]
851
#endif
852
        ldr     r0, [sp, #S_PSR]
853
                msr     spsr, r0
854
                ldmia   sp, {r0 - pc}^                  @ load r0 - pc, cpsr
855
 
856
__irq_invalid:  sub     sp, sp, #S_FRAME_SIZE   @ Allocate space on stack for frame
857
                stmfd   sp, {r0 - lr}           @ Save r0 - lr
858
                mov     r7, #-1
859
                ldr     r4, [pc, #LCirq - . - 8]
860
                ldmia   r4, {r5, r6}            @ get saved pc, psr
861
                add     r4, sp, #S_PC
862
                stmia   r4, {r5, r6, r7}
863
                mov     fp, #0
864
                mov     r0, sp
865
                mov     r1, #BAD_IRQ
866
                b       bad_mode
867
/*
868
 *================================================================================================
869
 * Data abort handler code
870
 *------------------------------------------------------------------------------------------------
871
 */
872
LCprocfns:      .word   processor
873
 
874
__dabt_usr:     sub     sp, sp, #S_FRAME_SIZE           @ Allocate frame size in one go
875
                stmia   sp, {r0 - r12}                  @ save r0 - r12
876
                add     r3, sp, #S_PC
877
                stmdb   r3, {sp, lr}^
878
                ldr     r0, [pc, #LCabt - . - 8]
879
                ldmia   r0, {r0 - r2}                   @ Get USR pc, cpsr
880
                stmia   r3, {r0 - r2}                   @ Save USR pc, cpsr, old_r0
881
                mov     fp, #0
882
                mrs     r2, cpsr                        @ Enable interrupts if they were
883
                bic     r2, r2, #I_BIT                  @ previously
884
                msr     cpsr, r2
885
                ldr     r2, LCprocfns
886
                mov     lr, pc
887
                ldr     pc, [r2, #8]                    @ call processor specific code
888
                mov     r3, sp
889
                bl      do_DataAbort
890
                b       _ret_from_sys_call
891
 
892
__dabt_svc:     sub     sp, sp, #S_FRAME_SIZE
893
                stmia   sp, {r0 - r12}                  @ save r0 - r12
894
                ldr     r2, [pc, #LCabt - . - 8]
895
                add     r0, sp, #S_FRAME_SIZE
896
                add     r5, sp, #S_SP
897
                mov     r1, lr
898
                ldmia   r2, {r2 - r4}                   @ get pc, cpsr
899
                stmia   r5, {r0 - r4}                   @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
900
                tst     r3, #I_BIT
901
                mrseq   r0, cpsr                        @ Enable interrupts if they were
902
                biceq   r0, r0, #I_BIT                  @ previously
903
                msreq   cpsr, r0
904
                mov     r0, r2
905
                ldr     r2, LCprocfns
906
                mov     lr, pc
907
                ldr     pc, [r2, #8]                    @ call processor specific code
908
                mov     r3, sp
909
                bl      do_DataAbort
910
                ldr     r0, [sp, #S_PSR]
911
                msr     spsr, r0
912
                ldmia   sp, {r0 - pc}^                  @ load r0 - pc, cpsr
913
 
914
__dabt_invalid: sub     sp, sp, #S_FRAME_SIZE
915
                stmia   sp, {r0 - lr}                   @ Save SVC r0 - lr [lr *should* be intact]
916
                mov     r7, r0
917
                ldr     r4, [pc, #LCabt - . - 8]
918
                ldmia   r4, {r5, r6}                    @ Get SVC pc, cpsr
919
                add     r4, sp, #S_PC
920
                stmia   r4, {r5, r6, r7}                @ Save SVC pc, cpsr, old_r0
921
                mov     r0, sp
922
                mov     r1, #BAD_DATA
923
                and     r2, r6, #31
924
                b       bad_mode
925
 
926
/*
927
 *================================================================================================
928
 * All exits to user mode from the kernel go through this code.
929
 */
930
 
931
LC6:
932
                .word   intr_count              @ -8
933
                .word   bh_mask         @ -4
934
                .word   bh_active               @ -0
935
                .word   need_resched            @ +4
936
                .word   current         @ +8
937
                .word   init_task               @ +12
938
 
939
Lreschedule:    bl      schedule
940
 
941
ret_from_sys_call:
942
_ret_from_sys_call:
943
                adr     r9, LC6
944
                ldmia   r9!, {r4, r6, r7}
945
                ldr     r5, [r4]
946
                teq     r5, #0
947
                bne     Lret_no_check
948
Lrecheck_bh:    ldr     r0, [r6]
949
                ldr     r1, [r7]
950
                tst     r0, r1
951
                bne     Lhandle_bottom_half
952
                ldr     r0, [sp, #S_PSR]
953
                tst     r0, #3
954
                bne     Lret_no_check
955
                ldmia   r9, {r5, r6, r7}
956
                ldr     r0, [r5]
957
                teq     r0, #0
958
                bne     Lreschedule
959
                ldr     r0, [r6]
960
                teq     r0, r7
961
                beq     Lret_no_check
962
 
963
                ldr     r1, [r0, #SIGNAL]
964
                ldr     r0, [r0, #BLOCKED]
965
                bics    r1, r1, r0
966
                movne   r1, sp
967
                blne    do_signal
968
Lret_no_check:  mrs     r0, cpsr                        @ disable IRQs
969
                orr     r0, r0, #I_BIT
970
                msr     cpsr, r0
971
                ldr     r0, [sp, #S_PSR]                @ Get calling cpsr
972
                msr     spsr, r0
973
                ldmia   sp, {r0 - lr}^                  @ Get calling r0 - lr
974
                mov     r0, r0
975
                add     sp, sp, #S_PC
976
                ldr     lr, [sp], #S_FRAME_SIZE - S_PC  @ Get PC and jump over PC, PSR, OLD_R0
977
                movs    pc, lr
978
 
979
Lhandle_bottom_half:
980
                add     r0, r5, #1
981
                str     r0, [r4]
982
                mrs     r8, cpsr
983
                bic     lr, r8, #I_BIT
984
                msr     cpsr, lr
985
                bl      do_bottom_half
986
                msr     cpsr, r8
987
                str     r5, [r4]
988
                b       Lrecheck_bh
989
 
990
_fpnull:        mov     pc, lr
991
 
992
                .data
993
 
994
                .global _fp_enter,fp_enter
995
                .global _fp_save,fp_save
996
                .global _fp_restore,fp_restore
997
 
998
fp_enter:
999
_fp_enter:      .word   fpe_not_present
1000
                .word   fpe_not_present
1001
fp_save:
1002
_fp_save:       .word   _fpnull
1003
fp_restore:
1004
_fp_restore:    .word   _fpnull
1005
 
1006
__temp_irq:     .word   0                                @ saved lr_irq
1007
                .word   0                                @ saved spsr_irq
1008
                .word   -1                              @ old_r0
1009
__temp_und:     .word   0                                @ Saved lr_und
1010
                .word   0                                @ Saved spsr_und
1011
                .word   -1                              @ old_r0
1012
__temp_abt:     .word   0                                @ Saved lr_abt
1013
                .word   0                                @ Saved spsr_abt
1014
                .word   -1                              @ old_r0

powered by: WebSVN 2.1.0

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