source: ssp_armv6_m_gcc/trunk/armv6_m_gcc/prc_support.S@ 421

Last change on this file since 421 was 421, checked in by nmir-saito, 4 years ago

Merge branch 'rubycfg' to trunk

  • Property svn:mime-type set to text/plain; charset=utf-8
File size: 12.3 KB
Line 
1/*
2 * TOPPERS/SSP Kernel
3 * Smallest Set Profile Kernel
4 *
5 * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
6 * Graduate School of Information Science, Nagoya Univ., JAPAN
7 * Copyright (C) 2010 by Meika Sugimoto
8 * Copyright (C) 2013 by Naoki Saito
9 * Nagoya Municipal Industrial Research Institute, JAPAN
10 *
11 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23 * と.
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27 * 報告すること.
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32 * 免責すること.
33 *
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38 * の責任を負わない.
39 *
40 */
41
42/*
43 * プロセッサ依存モジュール アセンブリ言語部(ARM-M用)
44 */
45
46#define TOPPERS_MACRO_ONLY
47#define UINT_C(val) (val) /* uint_t型の定数を作るマクロ */
48#define ULONG_C(val) (val) /* ulong_t型の定数を作るマクロ */
49#define CAST(type, val) (val) /* 型キャストを行うマクロ */
50
51#include "kernel_impl.h"
52#include "arm_m.h"
53
54
55 .text
56
57/*
58 * 外部参照
59 */
60 .global intnest
61
62/*
63 * CPU例外エントリ
64 *
65 * 割込みエントリと処理の内容は同等だが,ログの種類が異なるため,
66 * 分けている.
67 */
68 .align 2
69 .syntax unified
70 .code 16
71 .global exc_entry
72 .type exc_entry, function
73 /*
74 * 例外/割込みが発生すると,スタック(MSP)にスクラッチレジスタ等が保存される.
75 * この内容に加えて,CPU例外ハンドラへの情報として,
76 * EXC_RETURNの情報を保存する.
77 *
78 * ----------- <----- p_excinf
79 * | EXC_RETURN|
80 * -----------
81 * | R0 |
82 * -----------
83 * | R1 |
84 * -----------
85 * | R2 |
86 * -----------
87 * | R3 |
88 * -----------
89 * | R12 |
90 * -----------
91 * | LR |
92 * -----------
93 * | PC |
94 * -----------
95 * | xPSR |
96 * -----------
97 *
98 */
99exc_entry:
100 cpsid i /* 外部割込み禁止 */
101 push {lr} /* EXC_RETURN を積む */
102 mov r0, sp /* CPU例外ハンドラへの引数となる */
103
104 /* 割込みネスト数の加算 */
105 ldr r1 , =intnest
106 ldr r3 , [r1]
107 adds r3 , #1
108 str r3 , [r1]
109
110 /*
111 * 共通処理
112 */
113exc_entry_2:
114 /* ハンドラアドレスを取得 */
115 mrs r2, ipsr // r2: 例外番号
116 ldr r1, =_kernel_exc_tbl
117 lsls r3, r2 , #2 // r3 = r2 * 4 (r3:テーブル先頭からのオフセット)
118 adds r3, r3, r1 // r3 = r3 + r1 (r3:要素の格納アドレス)
119 ldr r1, [r3] // r1:ハンドラ起動アドレス
120
121#ifdef LOG_EXC_ENTER
122 push {r0, r2, r3}
123 mov r0, r2 /* 例外番号をパラメータに */
124 bl log_exc_enter /* log_exc_enterを呼び出す */
125 pop {r0, r2, r3} // r0:SP, r2:割込み番号
126#endif /* LOG_EXC_ENTER */
127
128#ifdef LOG_EXC_LEAVE
129 push { r2 } /* 例外番号をスタックへ */
130#endif /* LOG_EXC_LEAVE */
131
132 /*
133 * CPU例外ハンドラの呼び出し
134 */
135 cpsie i /* ロック解除 */
136 blx r1
137 cpsid i /* ロック */
138
139#ifdef LOG_EXC_LEAVE
140 pop { r0 } /* 例外番号を引数に */
141 bl log_exc_leave /* log_exc_leaveを呼び出す */
142#endif /* LOG_EXC_LEAVE */
143
144 b ret_exc
145
146
147/*
148 * 割込みエントリ
149 */
150 .align 2
151 .syntax unified
152 .code 16
153 .global int_entry
154 .type int_entry, function
155int_entry:
156 cpsid i /* 外部割込み禁止 */
157 push {lr} /* EXC_RETURN を積む */
158 mov r0, sp /* 未定義の割込みが発生した場合の情報とする */
159
160 /*
161 * 共通処理
162 */
163int_entry_2:
164 /* 割込みネスト数の加算 */
165 ldr r1 , =intnest
166 ldr r3 , [r1]
167 adds r3 , #1
168 str r3 , [r1]
169
170 /* ハンドラアドレスを取得 */
171 mrs r2, ipsr // r2: 割込み番号
172 ldr r1, =_kernel_exc_tbl
173 lsls r3, r2 , #2 // r3 = r2 * 4 (r3:テーブル先頭からのオフセット)
174 adds r3, r3, r1 // r3 = r3 + r1 (r3:要素の格納アドレス)
175 ldr r1, [r3] // r1:ハンドラ起動アドレス
176
177#ifdef LOG_INH_ENTER
178 push {r0,r2,r3}
179 mov r0, r2 /* 割込み番号をパラメータに */
180 bl log_inh_enter /* log_inh_enterを呼び出す */
181 pop { r0,r2,r3 } /* r0:SP, r2:割込み番号 */
182#endif /* LOG_INH_ENTER */
183
184#ifdef LOG_INH_LEAVE
185 push { r2 } /* 割込み番号をスタックへ */
186#endif /* LOG_INH_LEAVE */
187
188 /*
189 * 割込みハンドラの呼び出し
190 */
191 cpsie i /* ロック解除 */
192 blx r1
193 cpsid i /* ロック */
194
195#ifdef LOG_INH_LEAVE
196 pop { r0 } /* 割込み番号を引数に */
197 bl log_inh_leave /* log_inh_leaveを呼び出す */
198#endif /* LOG_INH_LEAVE */
199
200/*
201 * 割込み/例外出口
202 *
203 * ret_exc/ret_intは,CPU例外/割込みハンドラから戻った直後に実行する
204 * ルーチンである.
205 */
206ret_exc:
207ret_int:
208 /*
209 * ここで割込みロック状態とするが,すでにPRIMASK.PMをセットしており
210 * ここで特別に行うことはない
211 */
212 /*
213 * 戻り先のコンテキストの判定
214 *
215 * intnestが0かどうかで判断する
216 *
217 */
218 /* 割込みネスト数の減算 */
219 ldr r1 , =intnest
220 ldr r3 , [r1]
221 adds r3 , #-1
222 str r3 , [r1]
223
224 cmp r3 , #0
225 beq ret_int_2
226
227 /*
228 * 割込み出口(ディスパッチなし)
229 *
230 * 単純に,割込み発生元へ戻る
231 */
232ret_int_1:
233 /*
234 * CPUロック状態(PRIMASKがセットされた状態),Handlerモードでくる.
235 * ThreadモードへのリターンによりPRIMASKの状態が変化しないため
236 * リターン前に解除する.
237 */
238 pop { r2 } /* EXC_RETURN --> r2 */
239 cpsie i
240 bx r2 /* 割込み(or 例外)発生元リターン */
241
242 /*
243 * タスクコンテキストからの割込みの場合
244 */
245ret_int_2:
246 ldr r0, =reqflg /* reqflgがfalseならそのまま戻る */
247 ldr r1, [r0]
248 cmp r1 , #0
249 beq ret_int_1 /* falseならret_int_1へ(そのままリターン) */
250
251 /*
252 * ディスパッチする場合
253 */
254ret_int_3:
255 movs r1, #0 /* reqflgをfalseに */
256 str r1, [r0]
257
258 /*
259 * Threadモードへ移行する.
260 *
261 * search_schedtsk や run_taskを呼び出す場合は,
262 * Threadモード,CPUロック状態である必要がある.
263 * CPUロック状態については既にCPUロックのため,特に行うことはない.
264 *
265 * Threadモードへの移行には(MSP)スタック上にダミーの例外フレームを置いて,
266 * 擬似的に割込みハンドラからリターンする.
267 */
268 pop {r2} /* EXC_RETURN --> r2 */
269 ldr r0, =ret_int_4 /* PC */
270 ldr r1, =EPSR_T /* xPSR(Tビットが'1'である必要がある) */
271 stm sp!, {r0-r1} /* ダミーフレームをスタック上に積む */
272 sub sp, #(EXC_FRAME_SIZE - (4*2)) /* r0-r3,r12,lrの内容は設定する必要がない */
273 cpsie i
274 bx r2 /* Threadモードへ移行 */
275
276 /*
277 * ここは Thread モードで動作
278 * 割込み発生時にpushされたレジスタの内容を復帰してリターンする
279 */
280ret_int_4:
281 bl search_schedtsk /* 割込み中で起動されたタスクを実行 */
282 bl run_task
283ret_int_r:
284 ldr r0, [sp, #(EXC_FRAME_SIZE-(4*4))] // R12
285 mov r12, r0
286 ldr r0, [sp, #(EXC_FRAME_SIZE-(4*3))] // LR
287 mov lr, r0
288 ldr r0, [sp, #(EXC_FRAME_SIZE-(4*2))] // PC
289 movs r1, #1 // フラグに影響があるので,xpsrを戻す前に先に処理する
290 orrs r0, r0, r1 // bit0を1にする(ARMv6-Mは常にThumb実行状態で動作)
291 ldr r2, [sp, #(EXC_FRAME_SIZE-(4*1))] // xPSR
292 msr xpsr_nzcvq, r2
293 str r0, [sp, #(EXC_FRAME_SIZE-(4*1))] // 元xPSRの位置にPCの値を置く
294 ldmfd sp!, {r0-r3}
295 add sp, sp, #(4*3) // sp += (4*3)
296 cpsie i
297 pop {pc} // リターン
298
299/*
300 * SVCコールハンドラ(ここは本来不要なので,削除予定)
301 */
302 .align 2
303 .thumb
304 .thumb_func
305 .globl kernel_svc_handler
306 .type kernel_svc_handler, function
307kernel_svc_handler:
308 cpsie i /* CPUロック解除状態へ */
309 bx lr /* リターン */
310
311/*
312 * ディスパッチャの動作開始
313 */
314 .align 2
315 .thumb
316 .thumb_func
317 .globl start_dispatch
318 .type start_dispatch, function
319start_dispatch:
320 /*
321 * このルーチンは,カーネル起動時に,すべての割込みを禁止した状態
322 * (割込みロック状態と同等)で呼び出される.
323 * また,Threadモードで呼び出されることを想定している.
324 *
325 * ここでは,システムの状態をCPUロック状態,割込み優先度マスク全解除状態,
326 * ディスパッチ許可状態に移行させ,スタックポインタを初期化し,
327 * dispatcher(task.c) へジャンプする.
328 *
329 * CPUロック状態と割込みロック状態は共にPRIMASKで制御するよう定義しているため
330 * すでにシステムはCPUロック状態になっている.
331 * 割込み優先度マスクについては,システム起動時には(プロセッサの)実行優先度が
332 * 最低レベルの優先度であるため,(割込み処理モデルの)割込み優先度マスク全解除状態と
333 * 同等の状態になっている.
334 * さらに,task_initializeでdisdspをfalseに初期化しているため,
335 * ディスパッチ許可状態になっている.
336 */
337 ldr r0,=istkpt /* MSPを初期化 */
338 ldr r1,[r0] /* start_dispatch呼び出し時に呼び出し用に */
339 msr msp, r1 /* 使用しているため初期化する */
340 b dispatcher
341
342/*
343 * カーネルの終了処理の呼出し
344 *
345 * スタックを初期化
346 *
347 */
348 .text
349 .syntax unified
350 .code 16
351 .globl call_exit_kernel
352 .type call_exit_kernel, function
353call_exit_kernel:
354 ldr r0,=istkpt /* MSPを初期化 */
355 ldr r1,[r0] /* start_dispatch呼び出し時に呼び出し用に */
356 msr msp, r1 /* 使用しているため初期化する */
357 b exit_kernel /* カーネルの終了処理を呼ぶ */
358
359
360/*
361 * 微少時間待ち(定数値 SIL_DLY_TIMx については未検証)
362 */
363 .text
364 .syntax unified
365 .code 16
366 .globl sil_dly_nse
367 .type sil_dly_nse, function
368sil_dly_nse:
369 subs r0, r0, #SIL_DLY_TIM1
370 cmp r0, #0
371 bgt sil_dly_nse1
372 mov pc, lr
373sil_dly_nse1:
374 subs r0, r0, #SIL_DLY_TIM2
375 cmp r0, #0
376 bgt sil_dly_nse1
377 mov pc, lr
Note: See TracBrowser for help on using the repository browser.