Rev 911 | Rev 915 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 911 | Rev 912 | ||
---|---|---|---|
Line 27... | Line 27... | ||
27 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | # |
28 | # |
29 | 29 | ||
30 | #include <arch/stack.h> |
30 | #include <arch/stack.h> |
31 | #include <arch/register.h> |
31 | #include <arch/register.h> |
- | 32 | #include <arch/mm/page.h> |
|
- | 33 | #include <align.h> |
|
32 | 34 | ||
33 | #define STACK_ITEMS 12 |
35 | #define STACK_ITEMS 13 |
34 | #define STACK_FRAME_SIZE ((STACK_ITEMS*STACK_ITEM_SIZE) + STACK_SCRATCH_AREA_SIZE) |
36 | #define STACK_FRAME_SIZE ALIGN_UP((STACK_ITEMS*STACK_ITEM_SIZE) + STACK_SCRATCH_AREA_SIZE, STACK_ALIGNMENT) |
35 | 37 | ||
36 | #if (STACK_FRAME_SIZE % STACK_ALIGNMENT != 0) |
38 | #if (STACK_ITEMS % 2 == 0) |
- | 39 | # define STACK_FRAME_BIAS 8 |
|
- | 40 | #else |
|
37 | #error Memory stack must be 16-byte aligned. |
41 | # define STACK_FRAME_BIAS 16 |
38 | #endif |
42 | #endif |
39 | 43 | ||
40 | /** Partitioning of bank 0 registers. */ |
44 | /** Partitioning of bank 0 registers. */ |
41 | #define R_OFFS r16 |
45 | #define R_OFFS r16 |
42 | #define R_HANDLER r17 |
46 | #define R_HANDLER r17 |
Line 68... | Line 72... | ||
68 | .global heavyweight_handler |
72 | .global heavyweight_handler |
69 | heavyweight_handler: |
73 | heavyweight_handler: |
70 | /* 1. copy interrupt registers into bank 0 */ |
74 | /* 1. copy interrupt registers into bank 0 */ |
71 | 75 | ||
72 | /* |
76 | /* |
73 | * Note that r24-r31 from bank0 can be used only as long as PSR.ic = 0. |
77 | * Note that r24-r31 from bank 0 can be used only as long as PSR.ic = 0. |
74 | */ |
78 | */ |
75 | mov r24 = cr.iip |
79 | mov r24 = cr.iip |
76 | mov r25 = cr.ipsr |
80 | mov r25 = cr.ipsr |
77 | mov r26 = cr.iipa |
81 | mov r26 = cr.iipa |
78 | mov r27 = cr.isr |
82 | mov r27 = cr.isr |
Line 80... | Line 84... | ||
80 | 84 | ||
81 | /* 2. preserve predicate register into bank 0 */ |
85 | /* 2. preserve predicate register into bank 0 */ |
82 | mov r29 = pr ;; |
86 | mov r29 = pr ;; |
83 | 87 | ||
84 | /* 3. switch to kernel memory stack */ |
88 | /* 3. switch to kernel memory stack */ |
- | 89 | mov r30 = cr.ipsr |
|
- | 90 | shr.u r31 = r12, VRN_SHIFT ;; |
|
- | 91 | ||
- | 92 | /* |
|
85 | /* TODO: support interruptions from userspace */ |
93 | * Set p6 to true if the stack register references kernel address space. |
- | 94 | * Set p7 to false if the stack register doesn't reference kernel address space. |
|
- | 95 | */ |
|
86 | /* assume kernel stack */ |
96 | cmp.eq p6, p7 = VRN_KERNEL, r31 ;; |
87 | 97 | ||
- | 98 | (p6) shr.u r30 = r30, PSR_CPL_SHIFT ;; |
|
- | 99 | (p6) and r30 = PSR_CPL_MASK_SHIFTED, r30 ;; |
|
- | 100 | ||
- | 101 | /* |
|
- | 102 | * Set p6 to true if the interrupted context executed in kernel mode. |
|
- | 103 | * Set p7 to false if the interrupted context didn't execute in kernel mode. |
|
- | 104 | */ |
|
- | 105 | (p6) cmp.eq p6, p7 = r30, r0 ;; |
|
- | 106 | ||
- | 107 | /* |
|
- | 108 | * Now, p7 is true iff the stack needs to be switched to kernel stack. |
|
- | 109 | */ |
|
- | 110 | mov r30 = r12 |
|
- | 111 | (p7) mov r12 = R_KSTACK ;; |
|
- | 112 | ||
88 | add r31 = -8, r12 ;; |
113 | add r31 = -STACK_FRAME_BIAS, r12 ;; |
89 | add r12 = -STACK_FRAME_SIZE, r12 |
114 | add r12 = -STACK_FRAME_SIZE, r12 |
90 | 115 | ||
91 | /* 4. save registers in bank 0 into memory stack */ |
116 | /* 4. save registers in bank 0 into memory stack */ |
- | 117 | st8 [r31] = r30, -8 ;; /* save old stack pointer */ |
|
- | 118 | ||
92 | st8 [r31] = r29, -8 ;; /* save predicate registers */ |
119 | st8 [r31] = r29, -8 ;; /* save predicate registers */ |
93 | 120 | ||
94 | st8 [r31] = r24, -8 ;; /* save cr.iip */ |
121 | st8 [r31] = r24, -8 ;; /* save cr.iip */ |
95 | st8 [r31] = r25, -8 ;; /* save cr.ipsr */ |
122 | st8 [r31] = r25, -8 ;; /* save cr.ipsr */ |
96 | st8 [r31] = r26, -8 ;; /* save cr.iipa */ |
123 | st8 [r31] = r26, -8 ;; /* save cr.iipa */ |
97 | st8 [r31] = r27, -8 ;; /* save cr.isr */ |
124 | st8 [r31] = r27, -8 ;; /* save cr.isr */ |
98 | st8 [r31] = r28, -8 /* save cr.ifa */ |
125 | st8 [r31] = r28, -8 ;; /* save cr.ifa */ |
99 | 126 | ||
100 | /* 5. RSE switch from interrupted context */ |
127 | /* 5. RSE switch from interrupted context */ |
101 | mov r24 = ar.rsc |
128 | mov r24 = ar.rsc |
102 | mov r25 = ar.pfs |
129 | mov r25 = ar.pfs |
103 | cover |
130 | cover |
104 | mov r26 = cr.ifs |
131 | mov r26 = cr.ifs |
105 | 132 | ||
106 | st8 [r31] = r24, -8;; /* save ar.rsc */ |
133 | st8 [r31] = r24, -8 ;; /* save ar.rsc */ |
107 | st8 [r31] = r25, -8;; /* save ar.pfs */ |
134 | st8 [r31] = r25, -8 ;; /* save ar.pfs */ |
108 | st8 [r31] = r26, -8 /* save ar.ifs */ |
135 | st8 [r31] = r26, -8 /* save ar.ifs */ |
109 | 136 | ||
110 | and r30 = ~3, r24 ;; |
137 | and r30 = ~3, r24 ;; |
111 | mov ar.rsc = r30 ;; /* place RSE in enforced lazy mode */ |
138 | mov ar.rsc = r30 ;; /* place RSE in enforced lazy mode */ |
112 | 139 | ||
Line 118... | Line 145... | ||
118 | 145 | ||
119 | mov r29 = ar.bsp |
146 | mov r29 = ar.bsp |
120 | 147 | ||
121 | st8 [r31] = r27, -8 ;; /* save ar.rnat */ |
148 | st8 [r31] = r27, -8 ;; /* save ar.rnat */ |
122 | st8 [r31] = r28, -8 ;; /* save ar.bspstore */ |
149 | st8 [r31] = r28, -8 ;; /* save ar.bspstore */ |
123 | st8 [r31] = r29, -8 /* save ar.bsp */ |
150 | st8 [r31] = r29, -8 /* save ar.bsp */ |
124 | 151 | ||
125 | mov ar.rsc = r24 /* restore RSE's setting */ |
152 | mov ar.rsc = r24 /* restore RSE's setting */ |
126 | 153 | ||
127 | /* steps 6 - 15 are done by heavyweight_handler_inner() */ |
154 | /* steps 6 - 15 are done by heavyweight_handler_inner() */ |
128 | mov R_RET = b0 /* save b0 belonging to interrupted context */ |
155 | mov R_RET = b0 /* save b0 belonging to interrupted context */ |
Line 172... | Line 199... | ||
172 | mov cr.iipa = r26 |
199 | mov cr.iipa = r26 |
173 | mov cr.isr = r27 |
200 | mov cr.isr = r27 |
174 | mov cr.ifa = r28 |
201 | mov cr.ifa = r28 |
175 | 202 | ||
176 | /* 18. restore predicate registers from memory stack */ |
203 | /* 18. restore predicate registers from memory stack */ |
177 | ld8 r29 = [r31] , -8 ;; /* load predicate registers */ |
204 | ld8 r29 = [r31], +8 ;; /* load predicate registers */ |
178 | mov pr = r29 |
205 | mov pr = r29 |
179 | 206 | ||
180 | /* 19. return from interruption */ |
207 | /* 19. return from interruption */ |
181 | add r12 = STACK_FRAME_SIZE, r12 |
208 | ld8 r12 = [r31] /* load stack pointer */ |
182 | rfi ;; |
209 | rfi ;; |
183 | 210 | ||
184 | .global heavyweight_handler_inner |
211 | .global heavyweight_handler_inner |
185 | heavyweight_handler_inner: |
212 | heavyweight_handler_inner: |
186 | /* |
213 | /* |