proc.s (3048B)
1 .align 1 2 .section .proc0, "a" 3 .global proc0 4 proc0: 5 ldr r0, =msg0 6 bl puts 7 mov r0, #0 8 mov r1, #1 9 cmp r0, r1 10 sub sp, #4 11 wfi 12 add sp, #4 13 b proc0 14 15 .align 2 16 .global msg0 17 msg0: 18 .asciz "proc0" 19 20 .section .proc1, "a" 21 .global proc1 22 proc1: 23 ldr r0, =msg1 24 bl puts 25 wfi 26 b proc1 27 28 .align 2 29 .global msg1 30 msg1: 31 .asciz "proc1" 32 33 .align 1 34 .global print_sp 35 print_sp: 36 mov r4, lr 37 mov r0, sp 38 bl printh 39 bx r4 40 41 .global isr_alarm 42 isr_alarm: 43 push {lr} 44 45 // debug: 46 ldr r0, =alarm_msg 47 bl puts 48 49 sub sp, sp, #(17*4) // unsigned int r[17]; 50 mov r1, sp 51 52 mrs r2, psp 53 mov r3, #0 54 ldr r0, [r2, #0] // r0 55 str r0, [r1, r3] 56 add r2, r2, #4 57 add r3, r3, #4 58 ldr r0, [r2, #0] // r1 59 str r0, [r1, r3] 60 add r2, r2, #4 61 add r3, r3, #4 62 ldr r0, [r2, #0] // r2 63 str r0, [r1, r3] 64 add r2, r2, #4 65 add r3, r3, #4 66 ldr r0, [r2, #0] // r3 67 str r0, [r1, r3] 68 69 add r3, r3, #4 70 str r4, [r1, r3] // r4 71 add r3, r3, #4 72 str r5, [r1, r3] // r5 73 add r3, r3, #4 74 str r6, [r1, r3] // r6 75 add r3, r3, #4 76 str r7, [r1, r3] // r7 77 78 add r3, r3, #4 79 mov r0, r8 80 str r0, [r1, r3] // r8 81 add r3, r3, #4 82 mov r0, r9 83 str r0, [r1, r3] // r9 84 add r3, r3, #4 85 mov r0, r10 86 str r0, [r1, r3] // r10 87 add r3, r3, #4 88 mov r0, r11 89 str r0, [r1, r3] // r11 90 91 add r2, r2, #4 92 add r3, r3, #4 93 ldr r0, [r2, #0] 94 str r0, [r1, r3] // r12 95 96 add r3, r3, #4 97 mrs r0, psp 98 str r0, [r1, r3] // sp ??? 99 100 add r2, r2, #4 101 add r3, r3, #4 102 ldr r0, [r2, #0] 103 str r0, [r1, r3] // lr 104 105 add r2, r2, #4 106 add r3, r3, #4 107 ldr r0, [r2, #0] 108 str r0, [r1, r3] // ReturnAddress(ExceptionType): The next pc at interrupt. 109 110 add r2, r2, #4 111 add r3, r3, #4 112 ldr r0, [r2, #0] // xpsr 113 str r0, [r1, r3] 114 115 mov r0, r1 116 bl switch_context // r0 is the r[17] of the next task. 117 add sp, sp, #(17*4) 118 mrs r2, psp 119 ldr r1, [r0, #(0 * 4)] // r0 120 str r1, [r2, #0] 121 ldr r1, [r0, #(1 * 4)] // r1 122 str r1, [r2, #0x4] 123 ldr r1, [r0, #(2 * 4)] // r2 124 str r1, [r2, #0x8] 125 ldr r1, [r0, #(3 * 4)] // r3 126 str r1, [r2, #0xc] 127 ldr r1, [r0, #(12 * 4)] // r12 128 str r1, [r2, #0x10] 129 ldr r1, [r0, #(13 * 4)] // psp 130 msr psp, r1 // hard fault 131 ldr r1, [r0, #(14 * 4)] // lr 132 str r1, [r2, #0x14] 133 ldr r1, [r0, #(15 * 4)] // ReturnAddress 134 str r1, [r2, #0x18] 135 ldr r1, [r0, #(16 * 4)] // xpsr 136 str r1, [r2, #0x1c] 137 138 ldr r0, =(1000 * 1000) 139 bl set_alarm 140 141 pop {pc} 142 143 .align 2 144 alarm_msg: 145 .asciz "alarm" 146 147 .align 1 148 // void restore_context(unsigned int r[17]); 149 // This function does not return, and needs not to save any registers. 150 // How to restore all of the registers? 151 // At least one is needed to branch back to the process to be restored. 152 .global restore_context 153 restore_context: 154 ldr r1, [r0, #48] 155 mov r12, r1 156 ldr r1, [r0, #52] 157 mov sp, r1 158 ldr r1, [r0, #56] 159 mov lr, r1 160 ldr r1, [r0, #60] 161 mov r8, r1 // The next instruction to execute after restoring the context. 162 ldr r1, [r0, #64] // xpsr 163 msr xpsr, r1 164 ldm r0, {r0-r7} 165 bx r8 166 167 // void set_psp(void); 168 // Set_psp changes the stack to use to psp and set it to 0x20000100 169 // TODO: ISB barrier? 170 .global set_psp 171 set_psp: 172 mov r0, #2 173 msr control, r0 174 ldr r0, =0x20000100 175 mov sp, r0 176 bx lr