XINU
intr.S
Go to the documentation of this file.
1 /* intr.S - enable, disable, restore, halt, pause, irq_except (ARM) */
2 
3 #include <armv7a.h>
4 
5  .text
6  .globl disable
7  .globl restore
8  .globl enable
9  .globl pause
10  .globl halt
11  .globl irq_except
12  .globl irq_dispatch
13  .globl initevec
14  .globl expjmpinstr
15 
16 /*------------------------------------------------------------------------
17  * disable - Disable interrupts and return the previous state
18  *------------------------------------------------------------------------
19  */
20 disable:
21  mrs r0, cpsr /* Copy the CPSR into r0 */
22  cpsid i /* Disable interrupts */
23  mov pc, lr /* Return the CPSR */
24 
25 /*------------------------------------------------------------------------
26  * restore - Restore interrupts to value given by mask argument
27  *------------------------------------------------------------------------
28  */
29 restore:
30  push {r1, r2} /* Save r1, r2 on stack */
31  mrs r1, cpsr /* Copy CPSR into r1 */
32  ldr r2, =0x01F00220
33  and r1, r1, r2 /* Extract flags and other important */
34  bic r0, r0, r2 /* bits from the mask */
35  orr r1, r1, r0
36  msr cpsr_cfsx, r1 /* Restore the CPSR */
37  pop {r1, r2} /* Restore r1, r2 */
38  mov pc, lr /* Return to caller */
39 
40 /*------------------------------------------------------------------------
41  * enable - Enable interrupts
42  *------------------------------------------------------------------------
43  */
44 enable:
45  cpsie i /* Enable interrupts */
46  mov pc, lr /* Return */
47 
48 /*------------------------------------------------------------------------
49  * pause or halt - Place the processor in a hard loop
50  *------------------------------------------------------------------------
51  */
52 halt:
53 pause:
54  cpsid i /* Disable interrupts */
55 dloop: b dloop /* Dead loop */
56 
57 /*------------------------------------------------------------------------
58  * irq_except - Dispatch an IRQ exception to higher level IRQ dispatcher
59  *------------------------------------------------------------------------
60  */
61 irq_except:
62  sub lr, lr, #4 /* Correct the return address */
63  srsdb sp!, #19 /* Save return state on the supervisor */
64  /* mode stack */
65  cps #19 /* Change to supervisor mode */
66  push {r0-r12, lr} /* Save all registers */
67  bl irq_dispatch /* Call IRQ dispatch */
68  pop {r0-r12, lr} /* Restore all registers */
69  rfeia sp! /* Return from the exception using info */
70  /* stored on the stack */
71 
72 /*------------------------------------------------------------------------
73  * defexp_handler - Default Exception handler
74  *------------------------------------------------------------------------
75  */
76 defexp_handler:
77  ldr r0, =expmsg1
78  mov r1, lr
79  bl kprintf
80  ldr r0, =expmsg2
81  bl panic
82 
83 /*------------------------------------------------------------------------
84  * initevec - Initialize the exception vector
85  *------------------------------------------------------------------------
86  */
87 initevec:
88  mrc p15, 0, r0, c1, c0, 0 /* Read the c1-control register */
89  bic r0, r0, #ARMV7A_C1CTL_V/* V bit = 0, normal exp. base */
90  mcr p15, 0, r0, c1, c0, 0 /* Write the c1-control register */
91  ldr r0, =ARMV7A_EV_START /* Exception base address */
92  mcr p15, 0, r0, c12, c0, 0/* Store excp. base addr. in c12 */
93  ldr r0, =ARMV7A_EV_START /* Start address of exp. vector */
94  ldr r1, =ARMV7A_EV_END /* End address of exp. vector */
95  ldr r2, =expjmpinstr /* Copy the exp jump instr */
96  ldr r2, [r2] /* into register r2 */
97 expvec: str r2, [r0] /* Store the jump instruction */
98  add r0, r0, #4 /* in the exception vector */
99  cmp r0, r1
100  bne expvec
101  ldr r0, =ARMV7A_EH_START /* Install the default exception */
102  ldr r1, =ARMV7A_EH_END /* handler for all exceptions */
103  ldr r2, =defexp_handler
104 exphnd: str r2, [r0]
105  add r0, r0, #4
106  cmp r0, r1
107  bne exphnd
108  ldr r0, =ARMV7A_IRQH_ADDR /* Install the IRQ handler to */
109  ldr r1, =irq_except /* override the default */
110  str r1, [r0] /* exception handler */
111  mov pc, lr
112 
113 /*------------------------------------------------------------------------
114  * expjmpinstr - A PC relative jump instruction, copied into exp. vector
115  *------------------------------------------------------------------------
116  */
117 expjmpinstr:
118  ldr pc, [pc, #24]