source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/arm_insn.h

Last change on this file 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-chdr;charset=UTF-8
File size: 14.1 KB
Line 
1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
6 * Toyohashi Univ. of Technology, JAPAN
7 * Copyright (C) 2006-2018 by Embedded and Real-Time Systems Laboratory
8 * Graduate School of Information Science, Nagoya Univ., JAPAN
9 *
10 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
11 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
13 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15 * スコード中に含まれていること.
16 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
18 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
19 * の無保証規定を掲載すること.
20 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
21 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
22 * と.
23 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
24 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
25 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
26 * 報告すること.
27 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
28 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
29 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
30 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
31 * 免責すること.
32 *
33 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
34 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
35 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
36 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
37 * の責任を負わない.
38 *
39 * $Id$
40 */
41
42/*
43 * ARMコアの特殊命令のインライン関数定義
44 *
45 * このヘッダファイルは,arm.hからインクルードされる.arm.hから分離し
46 * ているのは,コンパイラによるインラインアセンブラの記述方法の違いを
47 * 吸収するために,このファイルのみを置き換えればよいようにするためで
48 * ある.
49 */
50
51#ifndef TOPPERS_ARM_INSN_H
52#define TOPPERS_ARM_INSN_H
53
54#include <t_stddef.h>
55
56/*
57 * CLZ(Count Leading Zero)命令
58 */
59#if __TARGET_ARCH_ARM >= 6
60
61Inline uint32_t
62count_leading_zero(uint32_t val)
63{
64 uint32_t count;
65
66 Asm("clz %0, %1" : "=r"(count) : "r"(val));
67 return(count);
68}
69
70#endif /* __TARGET_ARCH_ARM >= 6 */
71
72/*
73 * メモリが変更されることをコンパイラに伝えるためのマクロ
74 */
75#define ARM_MEMORY_CHANGED Asm("":::"memory")
76
77/*
78 * ステータスレジスタの操作関数
79 */
80#ifndef __thumb__
81
82/*
83 * ステータスレジスタ(CPSR)の現在値の読出し
84 */
85Inline uint32_t
86current_cpsr(void)
87{
88 uint32_t cpsr;
89
90 Asm("mrs %0, cpsr" : "=r"(cpsr));
91 return(cpsr);
92}
93
94/*
95 * ステータスレジスタ(CPSR)の現在値の変更
96 */
97Inline void
98set_cpsr(uint32_t cpsr)
99{
100 Asm("msr cpsr_cxsf, %0" : : "r"(cpsr) : "memory","cc");
101}
102
103#else /* __thumb__ */
104/*
105 * Thumbモードではmrs/msr命令が使用できないため,関数として実現して,
106 * ARMモードに移行して実行する.
107 *
108 * current_cpsrとset_cpsrは,__thumb__が定義されない場合にはヘッダファ
109 * イル中で定義されるインライン関数になるため,core_rename.defに登録
110 * せず,先頭の_kernel_を手書きしている.
111 */
112
113/*
114 * ステータスレジスタ(CPSR)の現在値の読出し
115 */
116extern uint32_t _kernel_current_cpsr(void);
117#define current_cpsr() _kernel_current_cpsr()
118
119/*
120 * ステータスレジスタ(CPSR)の現在値の変更
121 */
122extern void _kernel_set_cpsr(uint32_t cpsr);
123#define set_cpsr(cpsr) _kernel_set_cpsr(cpsr)
124
125#endif /* __thumb__ */
126
127/*
128 * 割込み禁止/許可関数
129 *
130 * ARMv6から追加されたシステム状態を変更する命令を使った割込み禁止/許
131 * 可のための関数.
132 */
133#if __TARGET_ARCH_ARM >= 6
134
135/*
136 * IRQの禁止
137 */
138Inline void
139disable_irq(void)
140{
141 Asm("cpsid i");
142}
143
144/*
145 * IRQの許可
146 */
147Inline void
148enable_irq(void)
149{
150 Asm("cpsie i");
151}
152
153/*
154 * FIQの禁止
155 */
156Inline void
157disable_fiq(void)
158{
159 Asm("cpsid f");
160}
161
162/*
163 * FIQの許可
164 */
165Inline void
166enable_fiq(void)
167{
168 Asm("cpsie f");
169}
170
171/*
172 * FIQとIRQの禁止
173 */
174Inline void
175disable_fiq_irq(void)
176{
177 Asm("cpsid fi");
178}
179
180/*
181 * FIQとIRQの許可
182 */
183Inline void
184enable_fiq_irq(void)
185{
186 Asm("cpsie fi");
187}
188
189#endif /* __TARGET_ARCH_ARM >= 6 */
190
191/*
192 * CP15のIDレジスタ操作マクロ
193 */
194
195/* メインIDレジスタ */
196#define CP15_READ_MIDR(reg) Asm("mrc p15, 0, %0, c0, c0, 0":"=r"(reg))
197
198/* マルチプロセッサアフィニティレジスタ(ARMv6以降)*/
199#if __TARGET_ARCH_ARM >= 6
200#define CP15_READ_MPIDR(reg) Asm("mrc p15, 0, %0, c0, c0, 5":"=r"(reg))
201#endif /* __TARGET_ARCH_ARM >= 6 */
202
203/* キャッシュタイプレジスタ */
204#define CP15_READ_CTR(reg) Asm("mrc p15, 0, %0, c0, c0, 1":"=r"(reg))
205
206#if __TARGET_ARCH_ARM == 7
207/* キャッシュレベルIDレジスタ(ARMv7) */
208#define CP15_READ_CLIDR(reg) Asm("mrc p15, 1, %0, c0, c0, 1":"=r"(reg))
209
210/* キャッシュサイズ選択レジスタ(ARMv7)*/
211#define CP15_WRITE_CSSELR(reg) Asm("mcr p15, 2, %0, c0, c0, 0"::"r"(reg))
212
213/* キャッシュサイズIDレジスタ(ARMv7)*/
214#define CP15_READ_CCSIDR(reg) Asm("mrc p15, 1, %0, c0, c0, 0":"=r"(reg))
215#endif /* __TARGET_ARCH_ARM == 7 */
216
217/*
218 * CP15のシステム制御レジスタ操作マクロ
219 */
220
221/* システム制御レジスタ */
222#define CP15_READ_SCTLR(reg) Asm("mrc p15, 0, %0, c1, c0, 0":"=r"(reg))
223#define CP15_WRITE_SCTLR(reg) Asm("mcr p15, 0, %0, c1, c0, 0"::"r"(reg))
224
225/* 補助制御レジスタ(機能はチップ依存)*/
226#define CP15_READ_ACTLR(reg) Asm("mrc p15, 0, %0, c1, c0, 1":"=r"(reg))
227#define CP15_WRITE_ACTLR(reg) Asm("mcr p15, 0, %0, c1, c0, 1"::"r"(reg))
228
229/* コプロセッサアクセス制御レジスタ */
230#define CP15_READ_CPACR(reg) Asm("mrc p15, 0, %0, c1, c0, 2":"=r"(reg))
231#define CP15_WRITE_CPACR(reg) Asm("mcr p15, 0, %0, c1, c0, 2"::"r"(reg))
232
233/*
234 * CP15によるキャッシュ操作マクロ
235 */
236
237/* 命令キャッシュ全体の無効化 */
238#define CP15_INVALIDATE_ICACHE() \
239 Asm("mcr p15, 0, %0, c7, c5, 0"::"r"(0))
240
241/* 分岐予測全体の無効化 */
242#define CP15_INVALIDATE_BP() Asm("mcr p15, 0, %0, c7, c5, 6"::"r"(0))
243
244/* データキャッシュ全体の無効化(ARMv6以前)*/
245#if __TARGET_ARCH_ARM <= 6
246#define CP15_INVALIDATE_DCACHE() Asm("mcr p15, 0, %0, c7, c6, 0"::"r"(0))
247#endif /* __TARGET_ARCH_ARM <= 6 */
248
249/* 統合キャッシュ全体の無効化(ARMv6以前)*/
250#if __TARGET_ARCH_ARM <= 6
251#define CP15_INVALIDATE_UCACHE() Asm("mcr p15, 0, %0, c7, c7, 0"::"r"(0))
252#endif /* __TARGET_ARCH_ARM <= 6 */
253
254/* データキャッシュ全体のクリーンと無効化(ARMv5のみ)*/
255#if __TARGET_ARCH_ARM <= 5
256#define ARMV5_CLEAN_AND_INVALIDATE_DCACHE() \
257 Asm("1: mrc p15, 0, apsr_nzcv, c7, c14, 3; bne 1b")
258#endif /* __TARGET_ARCH_ARM <= 5 */
259
260/* データキャッシュ全体のクリーンと無効化(ARMv6のみ)*/
261#if __TARGET_ARCH_ARM == 6
262#define CP15_CLEAN_AND_INVALIDATE_DCACHE() \
263 Asm("mcr p15, 0, %0, c7, c14, 0"::"r"(0))
264#endif /* __TARGET_ARCH_ARM == 6 */
265
266/* 統合キャッシュ全体のクリーンと無効化(ARMv6のみ)*/
267#if __TARGET_ARCH_ARM == 6
268#define CP15_CLEAN_AND_INVALIDATE_UCACHE() \
269 Asm("mcr p15, 0, %0, c7, c15, 0"::"r"(0))
270#endif /* __TARGET_ARCH_ARM == 6 */
271
272/* データキャッシュのセット/ウェイ単位の無効化 */
273#define CP15_WRITE_DCISW(reg) Asm("mcr p15, 0, %0, c7, c6, 2"::"r"(reg))
274
275/* データキャッシュのセット/ウェイ単位のクリーンと無効化 */
276#define CP15_WRITE_DCCISW(reg) Asm("mcr p15, 0, %0, c7, c14, 2"::"r"(reg))
277
278/*
279 * CP15のフォールト状態/アドレスの操作マクロ
280 */
281#if __TARGET_ARCH_ARM >= 6
282#define CP15_READ_DFSR(reg) Asm("mrc p15, 0, %0, c5, c0, 0":"=r"(reg))
283#define CP15_READ_DFAR(reg) Asm("mrc p15, 0, %0, c6, c0, 0":"=r"(reg))
284#define CP15_READ_IFSR(reg) Asm("mrc p15, 0, %0, c5, c0, 1":"=r"(reg))
285#define CP15_READ_IFAR(reg) Asm("mrc p15, 0, %0, c6, c0, 2":"=r"(reg))
286#else /* __TARGET_ARCH_ARM >= 6 */
287#define CP15_READ_FSR(reg) Asm("mrc p15, 0, %0, c5, c0, 0":"=r"(reg))
288#define CP15_READ_FAR(reg) Asm("mrc p15, 0, %0, c6, c0, 0":"=r"(reg))
289#endif /* __TARGET_ARCH_ARM >= 6 */
290
291/*
292 * CP15によるMMUの操作マクロ(VMSA)
293 */
294
295/* 変換テーブルベース制御レジスタ(ARMv6以降)*/
296#if __TARGET_ARCH_ARM >= 6
297#define CP15_WRITE_TTBCR(reg) Asm("mcr p15, 0, %0, c2, c0, 2"::"r"(reg))
298#endif /* __TARGET_ARCH_ARM >= 6 */
299
300/* 変換テーブルベースレジスタ0 */
301#define CP15_READ_TTBR0(reg) Asm("mrc p15, 0, %0, c2, c0, 0":"=r"(reg))
302#define CP15_WRITE_TTBR0(reg) Asm("mcr p15, 0, %0, c2, c0, 0"::"r"(reg))
303
304/* ドメインアクセス制御レジスタ */
305#define CP15_WRITE_DACR(reg) Asm("mcr p15, 0, %0, c3, c0, 0":: "r"(reg))
306
307/* コンテキストIDレジスタ(ARMv6以降)*/
308#if __TARGET_ARCH_ARM >= 6
309#define CP15_WRITE_CONTEXTIDR(reg) Asm("mcr p15, 0, %0, c13, c0, 1" ::"r"(reg))
310#endif /* __TARGET_ARCH_ARM >= 6 */
311
312/*
313 * CP15によるTLB操作マクロ(VMSA)
314 */
315
316/* TLB全体の無効化 */
317#define CP15_INVALIDATE_TLB() Asm("mcr p15, 0, %0, c8, c7, 0"::"r"(0))
318
319/*
320 * CP15のパフォーマンスモニタ操作マクロ(ARMv7のみ)
321 */
322#if __TARGET_ARCH_ARM == 7
323
324/* パフォーマンスモニタ制御レジスタ */
325#define CP15_READ_PMCR(reg) Asm("mrc p15, 0, %0, c9, c12, 0":"=r"(reg))
326#define CP15_WRITE_PMCR(reg) Asm("mcr p15, 0, %0, c9, c12, 0"::"r"(reg))
327
328/* パフォーマンスモニタカウントイネーブルセットレジスタ */
329#define CP15_READ_PMCNTENSET(reg) Asm("mrc p15, 0, %0, c9, c12, 1":"=r"(reg))
330#define CP15_WRITE_PMCNTENSET(reg) Asm("mcr p15, 0, %0, c9, c12, 1"::"r"(reg))
331
332/* パフォーマンスモニタカウンタサイクルレジスタ */
333#define CP15_READ_PMCCNTR(reg) Asm("mrc p15, 0, %0, c9, c13, 0":"=r"(reg))
334#define CP15_WRITE_PMCCNTR(reg) Asm("mcr p15, 0, %0, c9, c13, 0"::"r"(reg))
335
336#endif /* __TARGET_ARCH_ARM == 7 */
337
338/*
339 * CP15によるメモリバリア操作マクロ
340 */
341#define CP15_INST_SYNC_BARRIER() \
342 Asm("mcr p15, 0, %0, c7, c5, 4"::"r"(0):"memory")
343#define CP15_DATA_SYNC_BARRIER() \
344 Asm("mcr p15, 0, %0, c7, c10, 4"::"r"(0):"memory")
345#define CP15_DATA_MEMORY_BARRIER() \
346 Asm("mcr p15, 0, %0, c7, c10, 5"::"r"(0):"memory")
347
348/*
349 * メモリバリア
350 *
351 * ARMv6とARMv7が持つ3つのメモリバリア機能を使用するための関数.メモリ
352 * バリアは,ARMv7では専用命令,ARMv6ではCP15への書込みで実現される.
353 * ARMv7のメモリバリア命令は,同期を取る範囲を指定できるが,以下の関数
354 * では最大範囲(システム全体,リード/ライトの両方)で同期を取る.
355 *
356 * ARMv5以前では,メモリバリア機能は実装依存であるため,それぞれ,
357 * DATA_MEMORY_BARRIER,DATA_SYNC_BARRIER,INST_SYNC_BARRIERを定義する
358 * ことによって,関数の内容を入れ換えられるようにしている.
359 */
360
361/*
362 * データメモリバリア
363 *
364 * このバリアの前後で,メモリアクセスの順序が入れ換わらないようにする.
365 * マルチコア(厳密にはマルチマスタ)での使用を想定した命令.
366 */
367Inline void
368data_memory_barrier(void)
369{
370#ifdef DATA_MEMORY_BARRIER
371 DATA_MEMORY_BARRIER();
372#elif __TARGET_ARCH_ARM <= 6
373 CP15_DATA_MEMORY_BARRIER();
374#else /* __TARGET_ARCH_ARM <= 6 */
375 Asm("dmb":::"memory");
376#endif
377}
378
379/*
380 * データ同期バリア
381 *
382 * 先行するメモリアクセスが完了するのを待つ.メモリアクセスが副作用を
383 * 持つ時に,その副作用が起こるのを待つための使用を想定した命令.
384 */
385Inline void
386data_sync_barrier(void)
387{
388#ifdef DATA_SYNC_BARRIER
389 DATA_SYNC_BARRIER();
390#elif __TARGET_ARCH_ARM <= 6
391 CP15_DATA_SYNC_BARRIER();
392#else /* __TARGET_ARCH_ARM <= 6 */
393 Asm("dsb":::"memory");
394#endif
395}
396
397/*
398 * 命令同期バリア
399 *
400 * プログラムが書き換えられた(または,システム状態の変化により実行す
401 * べきプログラムが変わった)時に,パイプラインをフラッシュするなど,
402 * 新しいプログラムを読み込むようにする.ARMv6では,プリフェッチフラッ
403 * シュと呼ばれている.
404 */
405Inline void
406inst_sync_barrier(void)
407{
408#ifdef INST_SYNC_BARRIER
409 INST_SYNC_BARRIER();
410#elif __TARGET_ARCH_ARM <= 6
411 CP15_INST_SYNC_BARRIER();
412#else /* __TARGET_ARCH_ARM <= 6 */
413 Asm("isb":::"memory");
414#endif
415}
416
417/*
418 * CP15のセキュリティ拡張レジスタ操作マクロ(ARMv7のみ)
419 */
420#if __TARGET_ARCH_ARM == 7
421
422/* ベクタベースアドレスレジスタ */
423#define CP15_READ_VBAR(reg) Asm("mrc p15, 0, %0, c12, c0, 0":"=r"(reg))
424#define CP15_WRITE_VBAR(reg) Asm("mcr p15, 0, %0, c12, c0, 0"::"r"(reg))
425
426#endif /* __TARGET_ARCH_ARM == 7 */
427
428/*
429 * 浮動小数点例外制御レジスタ(FPEXC)の現在値の読出し
430 */
431Inline uint32_t
432current_fpexc(void)
433{
434 uint32_t fpexc;
435
436 Asm("vmrs %0, fpexc" : "=r"(fpexc));
437 return(fpexc);
438}
439
440/*
441 * 浮動小数点例外制御レジスタ(FPEXC)の現在値の変更
442 */
443Inline void
444set_fpexc(uint32_t fpexc)
445{
446 Asm("vmsr fpexc, %0" : : "r"(fpexc));
447}
448
449#endif /* TOPPERS_ARM_INSN_H */
Note: See TracBrowser for help on using the repository browser.