Rev 431 | Rev 438 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 431 | Rev 435 | ||
---|---|---|---|
Line 25... | Line 25... | ||
25 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | # |
27 | # |
28 | 28 | ||
29 | 29 | ||
- | 30 | /* |
|
- | 31 | * This macro roughly follows steps from 1 to 19 described in |
|
- | 32 | * Intel Itanium Architecture Software Developer's Manual, Chapter 3.4.2. |
|
- | 33 | * |
|
- | 34 | * Some steps are skipped (enabling and disabling interrupts). |
|
- | 35 | * Some steps are not fully supported yet (e.g. interruptions |
|
- | 36 | * from user space and floating-point context). |
|
- | 37 | */ |
|
- | 38 | .macro HEAVYWEIGHT_HANDLER offs handler |
|
- | 39 | .org IVT + \offs |
|
- | 40 | SAVE_INTERRUPTED_CONTEXT /* steps 1 - 9 */ |
|
- | 41 | br.call.sptk.many rp = \handler /* steps 10 - 11 */ |
|
- | 42 | br restore_interrupted_context /* steps 12 - 19 */ |
|
- | 43 | .endm |
|
- | 44 | ||
- | 45 | .macro SAVE_INTERRUPTED_CONTEXT |
|
- | 46 | /* 1. copy interrupt registers into bank 0 */ |
|
- | 47 | mov r24 = cr.iip |
|
- | 48 | mov r25 = cr.ipsr |
|
- | 49 | mov r26 = cr.iipa |
|
- | 50 | mov r27 = cr.isr |
|
- | 51 | mov r28 = cr.ifa |
|
- | 52 | ||
- | 53 | /* 2. preserve predicate register into bank 0 */ |
|
- | 54 | mov r29 = pr ;; |
|
- | 55 | ||
- | 56 | /* 3. switch to kernel memory stack */ |
|
- | 57 | /* TODO: support interruptions from userspace */ |
|
- | 58 | /* assume kernel stack */ |
|
- | 59 | ||
- | 60 | /* 4. allocate memory stack for registers saved in bank 0 */ |
|
- | 61 | st8 [r12] = r29, -8 ;; /* save predicate registers */ |
|
- | 62 | st8 [r12] = r28, -8 ;; /* save cr.ifa */ |
|
- | 63 | st8 [r12] = r27, -8 ;; /* save cr.isr */ |
|
- | 64 | st8 [r12] = r26, -8 ;; /* save cr.iipa */ |
|
- | 65 | st8 [r12] = r25, -8 ;; /* save cr.ipsr */ |
|
- | 66 | st8 [r12] = r24, -8 ;; /* save cr.iip */ |
|
- | 67 | ||
- | 68 | /* 5. RSE switch */ |
|
- | 69 | .auto |
|
- | 70 | mov r24 = ar.rsc |
|
- | 71 | mov r25 = ar.pfs |
|
- | 72 | cover |
|
- | 73 | mov r26 = cr.ifs |
|
- | 74 | ||
- | 75 | st8 [r12] = r24, -8 /* save ar.rsc */ |
|
- | 76 | st8 [r12] = r25, -8 /* save ar.pfs */ |
|
- | 77 | st8 [r12] = r26, -8 /* save ar.ifs */ |
|
- | 78 | ||
- | 79 | and r30 = ~3, r24 |
|
- | 80 | mov ar.rsc = r30 /* place RSE in enforced lazy mode */ |
|
- | 81 | ||
- | 82 | mov r27 = ar.rnat |
|
- | 83 | mov r28 = ar.bspstore |
|
- | 84 | ||
- | 85 | /* assume kernel backing store */ |
|
- | 86 | mov ar.bspstore = r28 |
|
- | 87 | ||
- | 88 | mov r29 = ar.bsp |
|
- | 89 | ||
- | 90 | st8 [r12] = r27, -8 /* save ar.rnat */ |
|
- | 91 | st8 [r12] = r28, -8 /* save ar.bspstore */ |
|
- | 92 | st8 [r12] = r29, -8 /* save ar.bsp */ |
|
- | 93 | ||
- | 94 | mov ar.rsc = r24 /* restore RSE's setting */ |
|
- | 95 | .explicit |
|
- | 96 | ||
- | 97 | /* 6. switch to bank 1 and reenable PSR.ic */ |
|
- | 98 | ssm 0x2000 |
|
- | 99 | bsw.1 ;; |
|
- | 100 | srlz.d |
|
- | 101 | ||
- | 102 | /* 7. preserve branch and application registers */ |
|
- | 103 | ||
- | 104 | /* 8. preserve general and floating-point registers */ |
|
- | 105 | /* TODO: save floating-point context */ |
|
- | 106 | ||
- | 107 | /* 9. skipped (will not enable interrupts) */ |
|
- | 108 | .endm |
|
- | 109 | ||
- | 110 | .macro RESTORE_INTERRUPTED_CONTEXT |
|
- | 111 | /* 12. skipped (will not disable interrupts) */ |
|
- | 112 | ||
- | 113 | /* 13. restore general and floating-point registers */ |
|
- | 114 | /* TODO: restore floating-point context */ |
|
- | 115 | ||
- | 116 | /* 14. restore branch and application registers */ |
|
- | 117 | ||
- | 118 | /* 15. disable PSR.ic and switch to bank 0 */ |
|
- | 119 | rsm 0x2000 |
|
- | 120 | bsw.0 ;; |
|
- | 121 | srlz.d |
|
- | 122 | ||
- | 123 | /* 16. RSE switch */ |
|
- | 124 | ||
- | 125 | /* 17. restore interruption state from memory stack */ |
|
- | 126 | ||
- | 127 | /* 18. restore predicate registers from memory stack */ |
|
- | 128 | ||
- | 129 | /* 19. return from interruption */ |
|
- | 130 | rfi |
|
- | 131 | .endm |
|
30 | 132 | ||
- | 133 | .global restore_interrupted_context |
|
- | 134 | restore_interrupted_context: |
|
- | 135 | RESTORE_INTERRUPTED_CONTEXT |
|
- | 136 | /* not reached */ |
|
31 | 137 | ||
32 | dump_gregs: |
138 | dump_gregs: |
33 | mov r16 = REG_DUMP;; |
139 | mov r16 = REG_DUMP;; |
34 | st8 [r16] = r0;; |
140 | st8 [r16] = r0;; |
35 | add r16 = 8,r16 ;; |
141 | add r16 = 8,r16 ;; |
Line 383... | Line 489... | ||
383 | Handler2 0x1c00 |
489 | Handler2 0x1c00 |
384 | Handler2 0x2000 |
490 | Handler2 0x2000 |
385 | Handler2 0x2400 |
491 | Handler2 0x2400 |
386 | Handler2 0x2800 |
492 | Handler2 0x2800 |
387 | Handler 0x2c00 break_instruction |
493 | Handler 0x2c00 break_instruction |
388 | Handler 0x3000 external_interrupt |
494 | HEAVYWEIGHT_HANDLER 0x3000 external_interrupt /* For external interrupt, heavyweight handler is used. */ |
389 | Handler2 0x3400 |
495 | Handler2 0x3400 |
390 | Handler2 0x3800 |
496 | Handler2 0x3800 |
391 | Handler2 0x3c00 |
497 | Handler2 0x3c00 |
392 | Handler2 0x4000 |
498 | Handler2 0x4000 |
393 | Handler2 0x4400 |
499 | Handler2 0x4400 |