QP/C  5.9.7
ARM7/ARM9
under_construction.jpg

Preemptive QK Kernel

1 ;-----------------------------------------------------------------------------
2 ; Product: QK port to ARM7/9, IAR-ARM Assembler
3 ; Last Updated for Version: 5.7.2
4 ; Date of the Last Update: 2016-09-26
5 ;
6 ; Q u a n t u m L e a P s
7 ; ---------------------------
8 ; innovating embedded systems
9 ;
10 ; Copyright (C) Quantum Leaps, LLC. All rights reserved.
11 ;
12 ; This program is open source software: you can redistribute it and/or
13 ; modify it under the terms of the GNU General Public License as published
14 ; by the Free Software Foundation, either version 3 of the License, or
15 ; (at your option) any later version.
16 ;
17 ; Alternatively, this program may be distributed and modified under the
18 ; terms of Quantum Leaps commercial licenses, which expressly supersede
19 ; the GNU General Public License and are specifically designed for
20 ; licensees interested in retaining the proprietary status of their code.
21 ;
22 ; This program is distributed in the hope that it will be useful,
23 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
24 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 ; GNU General Public License for more details.
26 ;
27 ; You should have received a copy of the GNU General Public License
28 ; along with this program. If not, see <http://www.gnu.org/licenses/>.
29 ;
30 ; Contact information:
31 ; https://state-machine.com
32 ; mailto:info@state-machine.com
33 ;-----------------------------------------------------------------------------
34 
35 NO_IRQ DEFINE 0x80 ; mask to disable interrupts (FIQ and IRQ)
36 NO_FIQ DEFINE 0x40 ; mask to disable interrupts (FIQ and IRQ)
37 FIQ_MODE DEFINE 0x11
38 IRQ_MODE DEFINE 0x12
39 SYS_MODE DEFINE 0x1F
40 
41  ; NOTE: keep in synch with the QK_Attr struct in "qk.h" !!!
42 QK_INT_NEST DEFINE 16
43 
44 ;-----------------------------------------------------------------------------
45 ; Interrupt disabling/enabling and QK initialization
46 ;-----------------------------------------------------------------------------
47 
48  SECTION .textrw:DATA:NOROOT(2)
49  PUBLIC QF_int_disable_SYS, QF_int_enable_SYS, QK_init
50  CODE32
51 
52 QF_int_disable_SYS:
53  MRS r0,cpsr ; get the original CPSR in r0 to return
54  MSR cpsr_c,#(SYS_MODE | NO_IRQ) ; disable IRQ only, FIQ enabled!
55  BX lr ; return the original CPSR in r0
56 
57 
58 QF_int_enable_SYS:
59  MSR cpsr_c,r0 ; restore the original CPSR from r0
60  BX lr ; return to ARM or THUMB
61 
62 
63 QK_init:
64  BX lr ; return to ARM or THUMB
65 
66 
67 ;-----------------------------------------------------------------------------
68 ; IRQ assembly wrapper
69 ;-----------------------------------------------------------------------------
70 
71  SECTION .textrw:DATA:NOROOT(2)
72  PUBLIC QK_irq
73  EXTERN BSP_irq
74  EXTERN QK_attr_, QK_sched_, QK_activate_
75  CODE32
76 
77 QK_irq:
78 ; IRQ entry {{{
79  MOV r13,r0 ; save r0 in r13_IRQ
80  SUB r0,lr,#4 ; put return address in r0_SYS
81  MOV lr,r1 ; save r1 in r14_IRQ (lr)
82  MRS r1,spsr ; put the SPSR in r1_SYS
83 
84  MSR cpsr_c,#(SYS_MODE | NO_IRQ) ; SYSTEM, no IRQ, but FIQ enabled!
85  STMFD sp!,{r0,r1} ; save SPSR and PC on SYS stack
86  STMFD sp!,{r2-r3,r12,lr} ; save APCS-clobbered regs on SYS stack
87  MOV r0,sp ; make the sp_SYS visible to IRQ mode
88  SUB sp,sp,#(2*4) ; make room for stacking (r0_SYS, r1_SYS)
89 
90  MSR cpsr_c,#(IRQ_MODE | NO_IRQ) ; IRQ mode, IRQ disabled
91  STMFD r0!,{r13,r14} ; finish saving the context (r0_SYS,r1_SYS)
92 
93  MSR cpsr_c,#(SYS_MODE | NO_IRQ) ; SYSTEM mode, IRQ disabled
94 ; IRQ entry }}}
95 
96  LDR r0,=QK_attr_ ; load address in already saved r0
97  LDR r12,[r0,#QK_INT_NEST] ; load QK_attr_.intNest into saved r12
98  ADD r12,r12,#1 ; increment the nesting level
99  STR r12,[r0,#QK_INT_NEST] ; store the value in QK_attr_.intNest
100 
101  ; MSR cpsr_c,#(SYS_MODE | NO_IRQ) ; enable FIQ
102  ; NOTE: BSP_irq might re-enable IRQ interrupts (the FIQ is enabled
103  ; already), if IRQs are prioritized by the interrupt controller.
104 
105  LDR r12,=BSP_irq
106  MOV lr,pc ; copy the return address to link register
107  BX r12 ; call the C IRQ-handler (ARM/THUMB)
108 
109 
110  MSR cpsr_c,#(SYS_MODE | NO_IRQ) ; make sure IRQs are disabled
111  LDR r0,=QK_attr_ ; load address
112  LDR r12,[r0,#QK_INT_NEST] ; load QK_attr_.intNest into saved r12
113  SUBS r12,r12,#1 ; decrement the nesting level
114  STR r12,[r0,#QK_INT_NEST] ; store the value in QK_attr_.intNest
115  BNE QK_irq_exit ; branch if interrupt nesting not zero
116 
117  LDR r12,=QK_sched_
118  MOV lr,pc ; copy the return address to link register
119  BX r12 ; call QK_sched_ (ARM/THUMB)
120  CMP r0,#0 ; check the returned priority
121  BEQ QK_irq_exit ; branch if priority zero
122 
123  LDR r12,=QK_activate_
124  MOV lr,pc ; copy the return address to link register
125  BX r12 ; call QK_activate_ (ARM/THUMB)
126 
127 QK_irq_exit:
128 ; IRQ exit {{{ ; IRQ/FIQ disabled--return from scheduler
129  MOV r0,sp ; make sp_SYS visible to IRQ mode
130  ADD sp,sp,#(8*4) ; fake unstacking 8 registers from sp_SYS
131 
132  MSR cpsr_c,#(IRQ_MODE | NO_IRQ) ; IRQ mode, IRQ disabled
133  MOV sp,r0 ; copy sp_SYS to sp_IRQ
134  LDR r0,[sp,#(7*4)] ; load the saved SPSR from the stack
135  MSR spsr_cxsf,r0 ; copy it into spsr_IRQ
136 
137  LDMFD sp,{r0-r3,r12,lr}^ ; unstack all saved USER/SYSTEM registers
138  NOP ; can't access banked reg immediately
139  LDR lr,[sp,#(6*4)] ; load return address from the SYS stack
140  MOVS pc,lr ; return restoring CPSR from SPSR
141 ; IRQ exit }}}
142 
143 
144 ;-----------------------------------------------------------------------------
145 ; Exception assembler wrappers
146 ;-----------------------------------------------------------------------------
147 
148  PUBLIC QF_reset
149  PUBLIC QF_undef
150  PUBLIC QF_swi
151  PUBLIC QF_pAbort
152  PUBLIC QF_dAbort
153  PUBLIC QF_reserved
154 
155  EXTERN Q_onAssert
156 
157  SECTION .text:CODE:NOROOT(2)
158  CODE32
159 
160 QF_reset:
161  LDR r0,=Csting_reset
162  B QF_except
163 QF_undef:
164  LDR r0,=Csting_undef
165  B QF_except
166 QF_swi:
167  LDR r0,=Csting_swi
168  B QF_except
169 QF_pAbort:
170  LDR r0,=Csting_pAbort
171  B QF_except
172 QF_dAbort:
173  LDR r0,=Csting_dAbort
174  B QF_except
175 QF_reserved:
176  LDR r0,=Csting_reserved
177  B QF_except
178 QF_except:
179  ; r0 is set to the string with the exception name
180  SUB r1,lr,#4 ; set line number to the exception address
181  MSR cpsr_c,#(SYS_MODE | NO_IRQ | NO_FIQ) ; SYSTEM, IRQ/FIQ disabled
182  LDR r12,=Q_onAssert
183  MOV lr,pc ; store the return address
184  BX r12 ; call the assertion-handler (ARM/THUMB)
185  ; the assertion handler should not return, but in case it does
186  ; hang up the machine in this endless loop
187  B .
188 
189 
190  LTORG ; strings enclosed in "" are zero-terminated
191 Csting_reset: DC8 "Reset"
192 Csting_undef: DC8 "Undefined"
193 Csting_swi: DC8 "Software Int"
194 Csting_pAbort: DC8 "Prefetch Abort"
195 Csting_dAbort: DC8 "Data Abort"
196 Csting_reserved: DC8 "Reserved"
197 
198 
199  END

Cooperative QV Kernel