|
8 | 8 |
|
9 | 9 | .extern vTaskSwitchContext |
10 | 10 |
|
| 11 | +/* |
| 12 | + * A normal C interrupt body is called through one of these wrappers. QingKe |
| 13 | + * HWSTK preserves the caller-saved integer registers and interrupt return |
| 14 | + * state. The C ABI preserves the callee-saved integer/FPU registers. Save |
| 15 | + * the remaining caller-saved FPU state here. |
| 16 | + * |
| 17 | + * The 96-byte frame is 16-byte aligned and contains: |
| 18 | + * 0..76 f0-f7, f10-f17, f28-f31 |
| 19 | + * 80 fcsr |
| 20 | + * 84 interrupted SP when switching from a task stack, otherwise zero |
| 21 | + * 88..95 alignment padding |
| 22 | + * |
| 23 | + * Test the actual SP against the IRQ-stack bounds instead of relying on PFIC |
| 24 | + * nesting state. This also handles a higher-priority interrupt arriving at |
| 25 | + * any instruction in another wrapper's stack-switch or restore sequence. |
| 26 | + * No SP-relative store is performed until the stack choice is complete. |
| 27 | + */ |
| 28 | +.macro portIRQ_WRAPPER vector, body |
| 29 | +.extern \body |
| 30 | +.global \vector |
| 31 | +.type \vector, @function |
| 32 | +.section .text.\vector, "ax", @progbits |
| 33 | +.p2align 2 |
| 34 | +\vector: |
| 35 | + la t0, __freertos_irq_stack_bottom |
| 36 | + la t1, __freertos_irq_stack_top |
| 37 | + mv t2, sp |
| 38 | + bltu sp, t0, .Lirq_use_top_\@ |
| 39 | + bgeu sp, t1, .Lirq_use_top_\@ |
| 40 | + li t2, 0 |
| 41 | + j .Lirq_frame_\@ |
| 42 | + |
| 43 | +.Lirq_use_top_\@: |
| 44 | + mv sp, t1 |
| 45 | + |
| 46 | +.Lirq_frame_\@: |
| 47 | + addi sp, sp, -96 |
| 48 | + sw t2, 84(sp) |
| 49 | + |
| 50 | + fsw f0, 0(sp) |
| 51 | + fsw f1, 4(sp) |
| 52 | + fsw f2, 8(sp) |
| 53 | + fsw f3, 12(sp) |
| 54 | + fsw f4, 16(sp) |
| 55 | + fsw f5, 20(sp) |
| 56 | + fsw f6, 24(sp) |
| 57 | + fsw f7, 28(sp) |
| 58 | + fsw f10, 32(sp) |
| 59 | + fsw f11, 36(sp) |
| 60 | + fsw f12, 40(sp) |
| 61 | + fsw f13, 44(sp) |
| 62 | + fsw f14, 48(sp) |
| 63 | + fsw f15, 52(sp) |
| 64 | + fsw f16, 56(sp) |
| 65 | + fsw f17, 60(sp) |
| 66 | + fsw f28, 64(sp) |
| 67 | + fsw f29, 68(sp) |
| 68 | + fsw f30, 72(sp) |
| 69 | + fsw f31, 76(sp) |
| 70 | + csrr t0, fcsr |
| 71 | + sw t0, 80(sp) |
| 72 | + |
| 73 | + call \body |
| 74 | + |
| 75 | + flw f0, 0(sp) |
| 76 | + flw f1, 4(sp) |
| 77 | + flw f2, 8(sp) |
| 78 | + flw f3, 12(sp) |
| 79 | + flw f4, 16(sp) |
| 80 | + flw f5, 20(sp) |
| 81 | + flw f6, 24(sp) |
| 82 | + flw f7, 28(sp) |
| 83 | + flw f10, 32(sp) |
| 84 | + flw f11, 36(sp) |
| 85 | + flw f12, 40(sp) |
| 86 | + flw f13, 44(sp) |
| 87 | + flw f14, 48(sp) |
| 88 | + flw f15, 52(sp) |
| 89 | + flw f16, 56(sp) |
| 90 | + flw f17, 60(sp) |
| 91 | + flw f28, 64(sp) |
| 92 | + flw f29, 68(sp) |
| 93 | + flw f30, 72(sp) |
| 94 | + flw f31, 76(sp) |
| 95 | + lw t0, 80(sp) |
| 96 | + csrw fcsr, t0 |
| 97 | + |
| 98 | + lw t2, 84(sp) |
| 99 | + addi sp, sp, 96 |
| 100 | + beqz t2, .Lirq_return_\@ |
| 101 | + mv sp, t2 |
| 102 | + |
| 103 | +.Lirq_return_\@: |
| 104 | + mret |
| 105 | +.size \vector, .-\vector |
| 106 | +.endm |
| 107 | + |
| 108 | +portIRQ_WRAPPER SysTick_Handler, SysTick_Handler_Body |
| 109 | +portIRQ_WRAPPER USBHS_IRQHandler, USBHS_IRQHandler_Body |
| 110 | +portIRQ_WRAPPER DMA1_Channel4_IRQHandler, DMA1_Channel4_IRQHandler_Body |
| 111 | +portIRQ_WRAPPER DMA2_Channel2_IRQHandler, DMA2_Channel2_IRQHandler_Body |
| 112 | +portIRQ_WRAPPER EXTI15_10_IRQHandler, EXTI15_10_IRQHandler_Body |
| 113 | +portIRQ_WRAPPER TIM10_CC_IRQHandler, TIM10_CC_IRQHandler_Body |
| 114 | +portIRQ_WRAPPER TIM6_IRQHandler, TIM6_IRQHandler_Body |
| 115 | + |
11 | 116 | .global SW_Handler |
12 | 117 | .type SW_Handler, @function |
13 | 118 | .section .text.SW_Handler, "ax", @progbits |
|
0 commit comments