source: azure_iot_hub_riscv/trunk/asp_baseplatform/arch/riscv_gcc/prc_config.h@ 453

Last change on this file since 453 was 453, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr;charset=UTF-8
File size: 15.2 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 * Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
11 *
12 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * の無保証規定を掲載すること.
22 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * と.
25 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
27 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * 報告すること.
29 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
32 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
33 * 免責すること.
34 *
35 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
36 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
37 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
38 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
39 * の責任を負わない.
40 *
41 * $Id$
42 */
43
44/*
45 * プロセッサ依存モジュール(RISC-V用)
46 *
47 * このインクルードファイルは,target_config.h(または,そこからインク
48 * ルードされるファイル)のみからインクルードされる.他のファイルから
49 * 直接インクルードしてはならない.
50 */
51
52#ifndef TOPPERS_PRC_CONFIG_H
53#define TOPPERS_PRC_CONFIG_H
54
55#ifndef TOPPERS_MACRO_ONLY
56
57/*
58 * プロセッサの特殊命令のインライン関数定義
59 */
60#include "encoding.h"
61
62/*
63 * MCAUSE REGISTER定義
64 */
65#define MCAUSE_CAUSE 0x7FFFFFFF
66
67/*
68 * 使用するシリアルポートID
69 */
70#ifndef SIO_PORTID
71#define SIO_PORTID (1)
72#endif /* SIO_PORTID */
73
74/*
75 * MACHINEの最大割込み数を定義
76 */
77#define TMAX_MACHNE_INTNO 32
78
79/*
80 * タスクコンテキストブロックの定義
81 */
82typedef struct task_context_block {
83 void *sp; /* スタックポインタ */
84 FP pc; /* プログラムカウンタ */
85} TSKCTXB;
86
87#endif /* TOPPERS_MACRO_ONLY */
88
89/*
90 * 割込み優先度マスク操作ライブラリ
91 *
92 * RISCV/32では,PLICの割込みスレッシュホールドで割込みレベルを管理する.
93 */
94
95/*
96 * 割込み優先度マスクの外部表現と内部表現の変換
97 */
98#define EXT_IPM(iipm) (-CAST(PRI, (iipm))) /* 外部表現に変換 */
99#define INT_IPM(ipm) CAST(uint16_t, -(ipm)) /* 内部表現に変換 */
100
101/*
102 * カーネル割込み設定定義
103 */
104#define KERNEL_MIE (MIP_MTIP | MIP_MEIP)
105
106
107#ifndef TOPPERS_MACRO_ONLY
108
109/*
110 * CPUロックフラグ実現のための変数
111 *
112 * これらの変数は,CPUロック状態の時のみ書き換えてよいものとする.
113 */
114extern volatile bool_t lock_flag; /* CPUロックフラグの値を保持する変数 */
115extern volatile uint16_t inest_lvl; /* 割込みネストを保存する変数 */
116extern volatile unsigned long kernel_mie; /* デフォルトのMIE値を保存する変数 */
117
118/*
119 * TOPPERS標準割込み処理モデルの実現
120 *
121 * 割込み優先度マスクとしては,mie(MACHINE割込みイネーブルレジスタ)を
122 * 用いる.全割込みを禁止する機能として,mstatusのMIEやPLICの割込みスレ
123 * ッドが,カーネル管理外の割込みをサポートするため,これらはCPUロック
124 * のために用いない.
125 * PLICの割込みスレッドでは、MITの割込みロックができないことも、
126 * この選択とした理由である.
127 *
128 * CPUロック状態を管理すための変数(lock_flag)を用意する.
129 * システムスタックのネスト管理の変数(inest_lvl)を用意する.
130 * 外部割込みの制御はPLICを用いるが、この制御はPRCでは管理せず
131 * ターゲットレベルで管理を行う.
132 */
133
134/*
135 * コンテキストの参照
136 *
137 * RISCVでは,割込みネストレベルでコンテキストを判定する.
138 */
139Inline bool_t
140sense_context(void)
141{
142 return inest_lvl != 0;
143}
144
145#endif /* TOPPERS_MACRO_ONLY */
146
147/*
148 * 例外フレームのオフセット
149 */
150#define P_EXCINF_OFFSET_MSTATUS 0x00
151#define P_EXCINF_OFFSET_PC 0x01
152#define P_EXCINF_OFFSET_MCAUSE 0x02
153#define P_EXCONF_OFFSET_MIE 0x03
154#define P_EXCONF_OFFSET_SP 0x04
155
156
157#ifndef TOPPERS_MACRO_ONLY
158
159/*
160 * MACHINE割込みの禁止
161 *
162 * 割込み制御で使用するため作成.
163 */
164Inline void
165dis_intm(void)
166{
167 clear_csr(mstatus, MSTATUS_MIE);
168}
169
170/*
171 * MACHINE割込みの許可
172 *
173 * 割込み制御で使用するため作成.
174 */
175Inline void
176ena_intm(void)
177{
178 set_csr(mstatus, MSTATUS_MIE);
179}
180
181/*
182 * CPUロック状態への移行
183 *
184 * mie(MACHINE割込みイネーブルレジスタ)を,カーネル管理割込み設
185 * 定をマスクすることでCPUロック状態を設定する.
186 * また,lock_flagをtrueにする.
187 *
188 * この関数は,CPUロック状態(lock_flagがtrueの状態)で呼ばれることは
189 * ないものと想定している.
190 */
191Inline void
192x_lock_cpu(void)
193{
194 clear_csr(mie, KERNEL_MIE);
195 lock_flag = true;
196}
197
198#define t_lock_cpu() x_lock_cpu()
199#define i_lock_cpu() x_lock_cpu()
200
201/*
202 * CPUロック状態の解除
203 *
204 * lock_flagをfalseにし,mie(MACHINE割込みイネーブルレジスタ)中の,
205 * イネーブル設定を行う.
206 *
207 * この関数は,CPUロック状態(lock_flagがtrueの状態)でのみ呼ばれるも
208 * のと想定している.
209 */
210Inline void
211x_unlock_cpu(void)
212{
213 lock_flag = false;
214 set_csr(mie, kernel_mie);
215}
216
217#define t_unlock_cpu() x_unlock_cpu()
218#define i_unlock_cpu() x_unlock_cpu()
219
220/*
221 * CPUロック状態の参照
222 */
223Inline bool_t
224x_sense_lock(void)
225{
226 return(lock_flag);
227}
228
229#define t_sense_lock() x_sense_lock()
230#define i_sense_lock() x_sense_lock()
231
232/*
233 * chg_ipmで有効な割込み優先度の範囲の判定
234 */
235#define VALID_INTPRI_CHGIPM(intpri) \
236 (TMIN_INTPRI <= (intpri) && (intpri) <= TMAX_INTPRI)
237
238/*
239 * (モデル上の)割込み優先度マスクの設定
240 *
241 * CPUロックフラグがクリアされている時は,ハードウェアの割込み優先度マ
242 * スクを設定する.(mitは想定していない)
243 */
244Inline void
245x_set_ipm(PRI intpri)
246{
247 set_ithreshold(INT_IPM(intpri));
248}
249
250#define t_set_ipm(intpri) x_set_ipm(intpri)
251#define i_set_ipm(intpri) x_set_ipm(intpri)
252
253/*
254 * (モデル上の)割込み優先度マスクの参照
255 *
256 * CPUロックフラグがクリアされている時はハードウェアの割込み優先度マ
257 * スクを参照する.
258 */
259Inline PRI
260x_get_ipm(void)
261{
262 return(EXT_IPM(current_ithreshold()));
263}
264
265#define t_get_ipm() x_get_ipm()
266#define i_get_ipm() x_get_ipm()
267
268/*
269 * 最高優先順位タスクへのディスパッチ(prc_support.S)
270 *
271 * dispatchは,タスクコンテキストから呼び出されたサービスコール処理か
272 * ら呼び出すべきもので,タスクコンテキスト・CPUロック状態・ディスパッ
273 * チ許可状態・(モデル上の)割込み優先度マスク全解除状態で呼び出さな
274 * ければならない.
275 */
276extern void dispatch(void);
277
278/*
279 * ディスパッチャの動作開始(prc_support.S)
280 *
281 * start_dispatchは,カーネル起動時に呼び出すべきもので,すべての割込
282 * みを禁止した状態(割込みロック状態と同等の状態)で呼び出さなければ
283 * ならない.
284 */
285extern void start_dispatch(void) NoReturn;
286
287/*
288 * 現在のコンテキストを捨ててディスパッチ(prc_support.S)
289 *
290 * exit_and_dispatchは,ext_tskから呼び出すべきもので,タスクコンテキ
291 * スト・CPUロック状態・ディスパッチ許可状態・(モデル上の)割込み優先
292 * 度マスク全解除状態で呼び出さなければならない.
293 */
294extern void exit_and_dispatch(void) NoReturn;
295
296/*
297 * カーネルの終了処理の呼出し(prc_support.S)
298 *
299 * call_exit_kernelは,カーネルの終了時に呼び出すべきもので,非タスク
300 * コンテキストに切り換えて,カーネルの終了処理(exit_kernel)を呼び出
301 * す.
302 */
303extern void call_exit_kernel(void) NoReturn;
304
305/*
306 * MACHINE割込みトラップ関数 (prc_support.S)
307 *
308 * trap_entryは最初のMACHINE割込みを処理する関数.
309 */
310extern void trap_entry(void);
311
312/*
313 * MACHINE割込みネストトラップ関数 (prc_support.S)
314 *
315 * trap_entryはネスト時のMACHINE割込みを処理する関数.
316 */
317extern void trap_nest(void);
318
319
320/*
321 * タスクコンテキストの初期化
322 *
323 * タスクが休止状態から実行できる状態に移行する時に呼ばれる.この時点
324 * でスタック領域を使ってはならない.
325 *
326 * activate_contextを,インライン関数ではなくマクロ定義としているのは,
327 * この時点ではTCBが定義されていないためである.
328 */
329extern void start_r(void);
330
331#define activate_context(p_tcb) \
332{ \
333 (p_tcb)->tskctxb.sp = (void *)((char *)((p_tcb)->p_tinib->stk) \
334 + (p_tcb)->p_tinib->stksz); \
335 (p_tcb)->tskctxb.pc = (void *) start_r; \
336}
337
338/*
339 * calltexは使用しない
340 */
341#define OMIT_CALLTEX
342
343/*
344 * 例外ベクタテーブルの構造の定義
345 */
346typedef struct exc_vector_entry {
347 FP exc_handler; /* 例外ハンドラの起動番地 */
348} EXCVE;
349
350/*
351 * MACHINE割込みハンドラ領域のテーブル
352 */
353extern volatile EXCVE m_interrupt_handlers[TMAX_MACHNE_INTNO];
354
355/*
356 * CPU例外ハンドラの設定
357 *
358 * ベクトル番号excnoのCPU例外ハンドラの出入口処理の番地をexc_entryに設
359 * 定する.
360 */
361Inline void
362x_define_exc(EXCNO excno, FP exc_entry)
363{
364 m_interrupt_handlers[excno].exc_handler = exc_entry;
365}
366
367/*
368 * MACHINE割込みハンドラの設定
369 */
370Inline void
371x_machine_inh(INHNO inhno, FP int_entry)
372{
373 m_interrupt_handlers[inhno+16].exc_handler = int_entry;
374}
375
376/*
377 * CPU例外ハンドラの出入口処理の生成
378 *
379 * CPU例外ハンドラの番地をA1に,CPU例外ハンドラ番号をD1に入れて,
380 * exchdr_entryに分岐する.割込みハンドラの出入口処理と同様に,CPU例外
381 * ハンドラ毎にCPU例外ハンドラを呼び出す処理を展開する方法もあるが,展
382 * 開する処理内容が複雑であるため,採用していない.
383 */
384
385/*
386 * CPU例外ハンドラの出入口処理のラベルを作るマクロ
387 */
388#define EXC_ENTRY(excno, exchdr) _kernel_##exchdr##_##excno
389
390/*
391 * CPU例外ハンドラの出入口処理
392 */
393#if defined(__riscv64)
394#define EXCHDR_ENTRY(excno, excno_num, exchdr) \
395extern void _kernel_##exchdr##_##excno(void *sp); \
396asm(".text \n" \
397"_kernel_" #exchdr "_" #excno ": \n" \
398" addi sp, sp, -32 \n" /* 保存領域を確保 */ \
399" sd ra, 24(sp) \n" /* return addressをセーブ */ \
400" csrsi mstatus, 8 \n" /* 割込みを許可(MSTATUS_MIE) */ \
401" mv a0, a1 \n" /* stack pointerをa0に */ \
402" jal " #exchdr " \n" /* exchdrに分岐 */ \
403" ld ra, 24(sp) \n" /* return addressをリストア */ \
404" csrci mstatus, 8 \n" /* 割込みを禁止(MSTATUS_MIE) */ \
405" addi sp, sp, 32 \n" /* 保存領域を開放 */ \
406" ret \n");/* リターン */
407#else
408#define EXCHDR_ENTRY(excno, excno_num, exchdr) \
409extern void _kernel_##exchdr##_##excno(void *sp); \
410asm(".text \n" \
411"_kernel_" #exchdr "_" #excno ": \n" \
412" addi sp, sp, -16 \n" /* 保存領域を確保 */ \
413" sw ra, 12(sp) \n" /* return addressをセーブ */ \
414" csrsi mstatus, 8 \n" /* 割込みを許可(MSTATUS_MIE) */ \
415" mv a0, a1 \n" /* stack pointerをa0に */ \
416" jal " #exchdr " \n" /* exchdrに分岐 */ \
417" lw ra, 12(sp) \n" /* return addressをリストア */ \
418" csrci mstatus, 8 \n" /* 割込みを禁止(MSTATUS_MIE) */ \
419" addi sp, sp, 16 \n" /* 保存領域を開放 */ \
420" ret \n");/* リターン */
421#endif
422
423/*
424 * CPU例外の発生した時のコンテキストの参照
425 *
426 * CPU例外の発生した時のコンテキストが,タスクコンテキストの時にfalse,
427 * そうでない時にtrueを返す.
428 */
429Inline bool_t
430exc_sense_context(void *p_excinf)
431{
432 return inest_lvl > 1;
433}
434
435/*
436 * CPU例外の発生した時のコンテキストと割込みのマスク状態の参照
437 *
438 * CPU例外の発生した時のシステム状態が,カーネル実行中でなく,タスクコ
439 * ンテキストであり,全割込みロック状態でなく,CPUロック状態でなく,割
440 * 込み優先度マスク全解除状態である時にtrue,そうでない時にfalseを返す
441 * (CPU例外がカーネル管理外の割込み処理中で発生した場合にもfalseを返
442 * す).
443 *
444 * CPU例外の発生した時のmie(MACHINE割込みイネーブルレジスタ)が初期設
445 * 定でないで,カーネル実行中でないこと,全割込みロック状態でないこと
446 * ,CPUロック状態でないこと,割込み優先度マスク全解除状態であることの
447 * 4つの条件をチェックすることができる(CPU例外が発生した時のlock_flag
448 * を参照する必要はない).
449 */
450Inline bool_t
451exc_sense_intmask(void *p_excinf)
452{
453 return(!exc_sense_context(p_excinf)
454 && ((read_csr(mie) & KERNEL_MIE) != 0));
455}
456
457
458/*
459 * プロセッサ依存の初期化
460 */
461extern void prc_initialize(void);
462
463/*
464 * プロセッサ依存の終了時処理
465 */
466extern void prc_terminate(void);
467
468/*
469 * C言語レベル MACHINE割込みハンドラ
470 */
471extern uint32_t handle_trap(unsigned long mcause, void *p_excinf);
472
473#endif /* TOPPERS_MACRO_ONLY */
474#endif /* TOPPERS_PRC_CONFIG_H */
Note: See TracBrowser for help on using the repository browser.