1#include "context.h" 2#define SPRG0 0x110 /* Special Purpose Register General 0 */ 3#define SPRG1 0x111 /* Special Purpose Register General 1 */ 4 5 .globl rt_hw_interrupt_disable 6 .globl rt_hw_interrupt_enable 7 .globl rt_hw_context_switch 8 .globl rt_hw_context_switch_to 9 .globl rt_hw_context_switch_interrupt 10 .globl rt_hw_systemcall_entry 11 12/* 13 * rt_base_t rt_hw_interrupt_disable(); 14 * return the interrupt status and disable interrupt 15 */ 16#if 0 17rt_hw_interrupt_disable: 18 mfmsr r3 /* Disable interrupts */ 19 li r4,0 20 ori r4,r4,MSR_EE 21 andc r4,r4,r3 22 SYNC /* Some chip revs need this... */ 23 mtmsr r4 24 SYNC 25 blr 26#else 27rt_hw_interrupt_disable: 28 addis r4, r0, 0xFFFD 29 ori r4, r4, 0x7FFF 30 mfmsr r3 31 and r4, r4, 3 /* Clear bits 14 and 16, corresponding to... */ 32 mtmsr r4 /* ...critical and non-critical interrupts */ 33 blr 34#endif 35 36/* 37 * void rt_hw_interrupt_enable(rt_base_t level); 38 * restore interrupt 39 */ 40rt_hw_interrupt_enable: 41 mtmsr r3 42 SYNC 43 blr 44 45/* 46 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); 47 * r3 --> from 48 * r4 --> to 49 * 50 * r1: stack pointer 51 */ 52rt_hw_systemcall_entry: 53 mtspr SPRG0,r3 /* save r3 to SPRG0 */ 54 mtspr SPRG1,r4 /* save r4 to SPRG1 */ 55 56 lis r3,rt_thread_switch_interrput_flag@h 57 ori r3,r3,rt_thread_switch_interrput_flag@l 58 lwz r4,0(r3) 59 cmpi cr0,0,r4,0x0 /* whether is 0 */ 60 beq _no_switch /* no switch, exit */ 61 li r4,0x0 /* set rt_thread_switch_interrput_flag to 0 */ 62 stw r4,0(r3) 63 64 /* load from thread to r3 */ 65 lis r3,rt_interrupt_from_thread@h /* set rt_interrupt_from_thread */ 66 ori r3,r3,rt_interrupt_from_thread@l 67 lwz r3,0(r3) 68 69 cmpi cr0,0,r3,0x0 /* whether is 0 */ 70 beq _restore /* it's first switch, goto _restore */ 71 72 /* save r1:sp to thread[from] stack pointer */ 73 subi r1, r1, STACK_FRAME_SIZE 74 stw r1, 0(r3) 75 76 /* restore r3, r4 from SPRG */ 77 mfspr r3,SPRG0 78 mfspr r4,SPRG0 79 80 /* save registers */ 81 stw r0,GPR0(r1) /* save general purpose registers 0 */ 82 stmw r2,GPR2(r1) /* save general purpose registers 2-31 */ 83 84 mfusprg0 r0 /* save usprg0 */ 85 stw r0,USPRG0(r1) 86 mfcr r0, /* save cr */ 87 stw r0,CR(r1) 88 mfxer r0 /* save xer */ 89 stw r0,XER(r1) 90 mfctr r0 /* save ctr */ 91 stw r0,CTR(r1) 92 mflr r0 /* save lr */ 93 stw r0, LR(r1) 94 95 mfsrr0 r0 /* save SRR0 and SRR1 */ 96 stw r0,SRR0(r1) 97 mfsrr1 r0 98 stw r0,SRR1(r1) 99 100_restore: 101 /* get thread[to] stack pointer */ 102 lis r4,rt_interrupt_to_thread@h 103 ori r4,r4,rt_interrupt_to_thread@l 104 lwz r1,0(r4) 105 lwz r1,0(r1) 106 107 lwz r0,SRR1(r1) /* restore SRR1 and SRR0 */ 108 mtsrr1 r0 109 lwz r0,SRR0(r1) 110 mtsrr0 r0 111 112 lwz r0,LR(r1) /* restore lr */ 113 mtlr r0 114 lwz r0,CTR(r1) /* restore ctr */ 115 mtctr r0 116 lwz r0,XER(r1) /* restore xer */ 117 mtxer r0 118 lwz r0,CR(r1) /* restore cr */ 119 mtcr r0 120 lwz r0,USPRG0(r1) /* restore usprg0 */ 121 // mtusprg0 r0 122 123 lmw r2, GPR2(r1) /* restore general register */ 124 lwz r0,GPR0(r1) 125 addi r1, r1, STACK_FRAME_SIZE 126 /* RFI will restore status register and thus the correct priority*/ 127 rfi 128 129_no_switch: 130 /* restore r3, r4 from SPRG */ 131 mfspr r3,SPRG0 132 mfspr r4,SPRG0 133 rfi 134 135 /* void rt_hw_context_switch_to(to); */ 136 .globl rt_hw_context_switch_to 137rt_hw_context_switch_to: 138 /* set rt_thread_switch_interrput_flag = 1 */ 139 lis r5,rt_thread_switch_interrput_flag@h 140 ori r5,r5,rt_thread_switch_interrput_flag@l 141 li r6, 0x01 142 stw r6,0(r5) 143 144 /* set rt_interrupt_from_thread = 0 */ 145 lis r5,rt_interrupt_from_thread@h 146 ori r5,r5,rt_interrupt_from_thread@l 147 li r6, 0x00 148 stw r6,0(r5) 149 150 /* set rt_interrupt_from_thread = to */ 151 lis r5,rt_interrupt_to_thread@h 152 ori r5,r5,rt_interrupt_to_thread@l 153 stw r3,0(r5) 154 155 /* trigger a system call */ 156 sc 157 158 blr 159 160 /* void rt_hw_context_switch(from, to); */ 161 .globl rt_hw_context_switch 162rt_hw_context_switch: 163 /* compare rt_thread_switch_interrupt_flag and set it */ 164 lis r5,rt_thread_switch_interrput_flag@h 165 ori r5,r5,rt_thread_switch_interrput_flag@l 166 lwz r6,0(r5) 167 cmpi cr0,0,r6,0x1 /* whether is 1 */ 168 beq _reswitch /* set already, goto _reswitch */ 169 li r6,0x1 /* set rt_thread_switch_interrput_flag to 1*/ 170 stw r6,0(r5) 171 172 /* set rt_interrupt_from_thread to 'from' */ 173 lis r5,rt_interrupt_from_thread@h 174 ori r5,r5,rt_interrupt_from_thread@l 175 stw r3,0(r5) 176 177_reswitch: 178 /* set rt_interrupt_to_thread to 'to' */ 179 lis r6,rt_interrupt_to_thread@h 180 ori r6,r6,rt_interrupt_to_thread@l 181 stw r4,0(r6) 182 183 /* trigger a system call */ 184 sc 185 186 blr 187 188 .globl rt_hw_context_switch_interrupt 189rt_hw_context_switch_interrupt: 190 /* compare rt_thread_switch_interrupt_flag and set it */ 191 lis r5,rt_thread_switch_interrput_flag@h 192 ori r5,r5,rt_thread_switch_interrput_flag@l 193 lwz r6,0(r5) 194 cmpi cr0,0,r6,0x1 /* whether is 1 */ 195 beq _int_reswitch /* set already, goto _reswitch */ 196 li r6,0x1 /* set rt_thread_switch_interrput_flag to 1*/ 197 stw r6,0(r5) 198 199 /* set rt_interrupt_from_thread to 'from' */ 200 lis r5,rt_interrupt_from_thread@h 201 ori r5,r5,rt_interrupt_from_thread@l 202 stw r3,0(r5) 203 204_int_reswitch: 205 /* set rt_interrupt_to_thread to 'to' */ 206 lis r6,rt_interrupt_to_thread@h 207 ori r6,r6,rt_interrupt_to_thread@l 208 stw r4,0(r6) 209 210 blr 211