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 | /* |