source: EcnlProtoTool/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel_impl.c

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

ASP3, TINET, mbed を更新

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