source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel_impl.c@ 374

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

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 9.7 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) 2006-2016 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., 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 * $Id$
41 */
42
43/*
44 * カーネルのコア依存部(ARM用)
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "arm.h"
51
52/*
53 * コンテキスト参照のための変数
54 */
55uint32_t excpt_nest_count; /* 例外ネストカウント */
56
57/*
58 * MMU関連の操作(VMSA)
59 */
60#ifdef USE_ARM_MMU
61
62#define CP15_DACR_D0_CLIENT 0x01U /* 変換テーブルに従いドメイン0にアクセス */
63#define DEFAULT_ASID 1 /* 使用するASID */
64
65/*
66 * セクションテーブル
67 */
68static uint32_t section_table[ARM_SECTION_TABLE_ENTRY]
69 __attribute__((aligned(ARM_SECTION_TABLE_ALIGN)));
70
71/*
72 * MMUのセクションテーブルエントリの設定
73 */
74Inline void
75config_section_entry(ARM_MMU_CONFIG *p_ammuc)
76{
77 uint32_t vaddr = p_ammuc->vaddr;
78 uint32_t paddr = p_ammuc->paddr;
79 uint32_t size = p_ammuc->size;
80 uint_t i;
81
82 while (size > 0) {
83#ifdef USE_ARM_SSECTION
84 if (size >= ARM_SSECTION_SIZE && (vaddr % ARM_SSECTION_SIZE) == 0) {
85 for (i = 0; i < 16; i++) {
86 section_table[vaddr / ARM_SECTION_SIZE] = paddr
87 |ARM_MMU_DSCR1_SSECTION|p_ammuc->attr;
88 vaddr += ARM_SECTION_SIZE;
89 }
90 paddr += ARM_SSECTION_SIZE;
91 size -= ARM_SSECTION_SIZE;
92 }
93 else {
94#endif /* USE_ARM_SSECTION */
95 section_table[vaddr / ARM_SECTION_SIZE] = paddr
96 |ARM_MMU_DSCR1_SECTION|p_ammuc->attr;
97 vaddr += ARM_SECTION_SIZE;
98 paddr += ARM_SECTION_SIZE;
99 size -= ARM_SECTION_SIZE;
100#ifdef USE_ARM_SSECTION
101 }
102#endif /* USE_ARM_SSECTION */
103 }
104}
105
106/*
107 * MMUの初期化
108 */
109void
110arm_mmu_initialize(void)
111{
112 uint32_t reg;
113 uint_t i;
114
115 /*
116 * MMUのセクションテーブルの設定
117 */
118 for (i = 0; i < ARM_SECTION_TABLE_ENTRY; i++) {
119 section_table[i] = ARM_MMU_DSCR1_FAULT;
120 }
121 for (i = 0; i < arm_tnum_memory_area; i++) {
122 config_section_entry(&(arm_memory_area[i]));
123 }
124
125 /*
126 * TTBR0を用いるように指定(ARMv6以降)
127 */
128#if __TARGET_ARCH_ARM >= 6
129 CP15_WRITE_TTBCR(0U);
130#endif /* __TARGET_ARCH_ARM >= 6 */
131
132 /*
133 * 変換テーブルとして,section_tableを使用する.
134 */
135 reg = ((uint32_t) &(section_table[0])) | TTBR_CONFIG;
136 CP15_WRITE_TTBR0(reg);
137
138 /*
139 * ドメインアクセス制御の設定
140 */
141 CP15_WRITE_DACR(CP15_DACR_D0_CLIENT);
142
143 /*
144 * ASIDの設定
145 */
146#if __TARGET_ARCH_ARM >= 6
147 CP15_WRITE_CONTEXTIDR(DEFAULT_ASID);
148#endif /* __TARGET_ARCH_ARM >= 6 */
149
150 /*
151 * TLB全体の無効化
152 */
153 arm_invalidate_tlb();
154
155 /*
156 * MMUを有効にする.ARMv6では,拡張ページテーブル設定を使う(サブ
157 * ページは使わない)ように設定する.
158 */
159 CP15_READ_SCTLR(reg);
160#if __TARGET_ARCH_ARM == 6
161 reg |= (CP15_SCTLR_MMU|CP15_SCTLR_EXTPAGE);
162#else /* __TARGET_ARCH_ARM == 6 */
163 reg |= CP15_SCTLR_MMU;
164#endif /* __TARGET_ARCH_ARM == 6 */
165 CP15_WRITE_SCTLR(reg);
166 inst_sync_barrier();
167}
168
169#endif /* USE_ARM_MMU */
170
171/*
172 * FPUの初期化
173 */
174#ifdef USE_ARM_FPU
175
176void
177arm_fpu_initialize(void)
178{
179 uint32_t reg;
180
181 /*
182 * CP10とCP11をアクセス可能に設定する.
183 */
184 CP15_READ_CPACR(reg);
185 reg |= (CP15_CPACR_CP10_FULLACCESS | CP15_CPACR_CP11_FULLACCESS);
186 CP15_WRITE_CPACR(reg);
187
188 /*
189 * FPUをディスエーブルする.
190 */
191 set_fpexc(current_fpexc() & ~FPEXC_ENABLE);
192}
193
194#endif /* USE_ARM_FPU */
195
196/*
197 * コア依存の初期化
198 */
199void
200core_initialize(void)
201{
202 /*
203 * カーネル起動時は非タスクコンテキストとして動作させるために,例外
204 * のネスト回数を1に初期化する.
205 */
206 excpt_nest_count = 1U;
207
208 /*
209 * MMUを有効に
210 */
211#ifdef USE_ARM_MMU
212 arm_mmu_initialize();
213#endif /* USE_ARM_MMU */
214
215 /*
216 * FPUの初期化
217 */
218#ifdef USE_ARM_FPU
219 arm_fpu_initialize();
220#endif /* USE_ARM_FPU */
221
222 /*
223 * パフォーマンスモニタの初期化
224 */
225#if defined(USE_ARM_PM_HIST) && __TARGET_ARCH_ARM == 7
226 arm_init_pmcnt();
227#endif /* defined(USE_ARM_PM_HIST) && __TARGET_ARCH_ARM == 7 */
228}
229
230/*
231 * コア依存の終了処理
232 */
233void
234core_terminate(void)
235{
236}
237
238/*
239 * CPU例外の発生状況のログ出力
240 */
241#ifndef OMIT_XLOG_SYS
242
243/*
244 * CPU例外ハンドラの中から,CPU例外情報ポインタ(p_excinf)を引数とし
245 * て呼び出すことで,CPU例外の発生状況をシステムログに出力する.
246 */
247void
248xlog_sys(void *p_excinf)
249{
250 syslog_4(LOG_EMERG, "pc = %08x, cpsr = %08x, lr = %08x, r12 = %08x",
251 ((T_EXCINF *)(p_excinf))->pc, ((T_EXCINF *)(p_excinf))->cpsr,
252 ((T_EXCINF *)(p_excinf))->lr, ((T_EXCINF *)(p_excinf))->r12);
253 syslog_4(LOG_EMERG, "r0 = %08x, r1 = %08x, r2 = %08x, r3 = %08x",
254 ((T_EXCINF *)(p_excinf))->r0, ((T_EXCINF *)(p_excinf))->r1,
255 ((T_EXCINF *)(p_excinf))->r2, ((T_EXCINF *)(p_excinf))->r3);
256 syslog_2(LOG_EMERG, "nest_count = %d, intpri = %d",
257 ((T_EXCINF *)(p_excinf))->nest_count,
258 ((T_EXCINF *)(p_excinf))->intpri);
259}
260
261/*
262 * プリフェッチ/データアボートが発生した状況(状態とアドレス)をシス
263 * テムログに出力する.
264 */
265void
266xlog_fsr(uint32_t fsr, uint32_t far)
267{
268 char *status;
269
270 switch (fsr & CP15_FSR_FS_MASK) {
271 case CP15_FSR_FS_ALIGNMENT:
272 status = "alignment fault";
273 break;
274 case CP15_FSR_FS_TRANSLATION1:
275 status = "translation fault (1st level)";
276 break;
277 case CP15_FSR_FS_TRANSLATION2:
278 status = "translation fault (2nd level)";
279 break;
280 case CP15_FSR_FS_PERMISSION1:
281 status = "permission fault (1st level)";
282 break;
283 case CP15_FSR_FS_PERMISSION2:
284 status = "permission fault (2nd level)";
285 break;
286 default:
287 status = "other fault";
288 break;
289 }
290 syslog_2(LOG_EMERG, "Fault status: 0x%04x (%s)", fsr, status);
291 syslog_1(LOG_EMERG, "Fault address: 0x%08x", far);
292}
293
294#endif /* OMIT_XLOG_SYS */
295
296/*
297 * 未定義の割込みが入った場合の処理
298 */
299#ifndef OMIT_DEFAULT_INT_HANDLER
300
301void
302default_int_handler(void)
303{
304 syslog_0(LOG_EMERG, "Unregistered interrupt occurs.");
305 ext_ker();
306}
307
308#endif /* OMIT_DEFAULT_INT_HANDLER */
309
310/*
311 * 未定義の例外が入った場合の処理
312 */
313#ifndef OMIT_DEFAULT_EXC_HANDLER
314
315void
316default_exc_handler(void *p_excinf, EXCNO excno)
317{
318#ifdef OMIT_XLOG_SYS
319 syslog_1(LOG_EMERG, "Unregistered exception %d occurs.", excno);
320#else /* OMIT_XLOG_SYS */
321 switch (excno) {
322 case EXCNO_UNDEF:
323 syslog_0(LOG_EMERG, "Undefined Instruction exception occurs.");
324 break;
325 case EXCNO_SVC:
326 syslog_0(LOG_EMERG, "Supervisor Call exception occurs.");
327 break;
328 case EXCNO_PABORT:
329 syslog_0(LOG_EMERG, "Prefetch Abort exception occurs.");
330 break;
331 case EXCNO_DABORT:
332 syslog_0(LOG_EMERG, "Data Abort exception occurs.");
333 break;
334 case EXCNO_IRQ:
335 syslog_0(LOG_EMERG, "IRQ exception occurs.");
336 break;
337 case EXCNO_FIQ:
338 syslog_0(LOG_EMERG, "FIQ exception occurs.");
339 break;
340 }
341 xlog_sys(p_excinf);
342
343 if (excno == EXCNO_PABORT || excno == EXCNO_DABORT) {
344 uint32_t fsr, far;
345
346#if __TARGET_ARCH_ARM >= 6
347 if (excno == EXCNO_PABORT) {
348 CP15_READ_IFSR(fsr);
349 CP15_READ_IFAR(far);
350 }
351 else {
352 CP15_READ_DFSR(fsr);
353 CP15_READ_DFAR(far);
354 }
355#else /* __TARGET_ARCH_ARM >= 6 */
356 CP15_READ_FSR(fsr);
357 CP15_READ_FAR(far);
358#endif /* __TARGET_ARCH_ARM >= 6 */
359
360 xlog_fsr(fsr, far);
361 }
362#endif /* OMIT_XLOG_SYS */
363 ext_ker();
364}
365
366#endif /* OMIT_DEFAULT_EXC_HANDLER */
Note: See TracBrowser for help on using the repository browser.