source: EcnlProtoTool/trunk/asp3_dcre/arch/arm_gcc/common/arm_insn.h@ 321

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

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr;charset=UTF-8
File size: 13.2 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-2016 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
109/*
110 * ステータスレジスタ(CPSR)の現在値の読出し
111 */
112extern uint32_t current_cpsr(void);
113
114/*
115 * ステータスレジスタ(CPSR)の現在値の変更
116 */
117extern void set_cpsr(uint32_t cpsr);
118
119#endif /* __thumb__ */
120
121/*
122 * 割込み禁止/許可関数
123 *
124 * ARMv6から追加されたシステム状態を変更する命令を使った割込み禁止/許
125 * 可のための関数.
126 */
127#if __TARGET_ARCH_ARM >= 6
128
129/*
130 * IRQの禁止
131 */
132Inline void
133disable_irq(void)
134{
135 Asm("cpsid i");
136}
137
138/*
139 * IRQの許可
140 */
141Inline void
142enable_irq(void)
143{
144 Asm("cpsie i");
145}
146
147/*
148 * FIQの禁止
149 */
150Inline void
151disable_fiq(void)
152{
153 Asm("cpsid f");
154}
155
156/*
157 * FIQの許可
158 */
159Inline void
160enable_fiq(void)
161{
162 Asm("cpsie f");
163}
164
165/*
166 * FIQとIRQの禁止
167 */
168Inline void
169disable_fiq_irq(void)
170{
171 Asm("cpsid fi");
172}
173
174/*
175 * FIQとIRQの許可
176 */
177Inline void
178enable_fiq_irq(void)
179{
180 Asm("cpsie fi");
181}
182
183#endif /* __TARGET_ARCH_ARM >= 6 */
184
185/*
186 * CP15のIDレジスタ操作マクロ
187 */
188
189/* メインIDレジスタ */
190#define CP15_READ_MIDR(reg) Asm("mrc p15, 0, %0, c0, c0, 0":"=r"(reg))
191
192/* マルチプロセッサアフィニティレジスタ(ARMv6以降)*/
193#if __TARGET_ARCH_ARM >= 6
194#define CP15_READ_MPIDR(reg) Asm("mrc p15, 0, %0, c0, c0, 5":"=r"(reg))
195#endif /* __TARGET_ARCH_ARM >= 6 */
196
197/* キャッシュタイプレジスタ */
198#define CP15_READ_CTR(reg) Asm("mrc p15, 0, %0, c0, c0, 1":"=r"(reg))
199
200#if __TARGET_ARCH_ARM == 7
201/* キャッシュレベルIDレジスタ(ARMv7) */
202#define CP15_READ_CLIDR(reg) Asm("mrc p15, 1, %0, c0, c0, 1":"=r"(reg))
203
204/* キャッシュサイズ選択レジスタ(ARMv7)*/
205#define CP15_WRITE_CSSELR(reg) Asm("mcr p15, 2, %0, c0, c0, 0"::"r"(reg))
206
207/* キャッシュサイズIDレジスタ(ARMv7)*/
208#define CP15_READ_CCSIDR(reg) Asm("mrc p15, 1, %0, c0, c0, 0":"=r"(reg))
209#endif /* __TARGET_ARCH_ARM == 7 */
210
211/*
212 * CP15のシステム制御レジスタ操作マクロ
213 */
214
215/* システム制御レジスタ */
216#define CP15_READ_SCTLR(reg) Asm("mrc p15, 0, %0, c1, c0, 0":"=r"(reg))
217#define CP15_WRITE_SCTLR(reg) Asm("mcr p15, 0, %0, c1, c0, 0"::"r"(reg))
218
219/* 補助制御レジスタ(機能はチップ依存)*/
220#define CP15_READ_ACTLR(reg) Asm("mrc p15, 0, %0, c1, c0, 1":"=r"(reg))
221#define CP15_WRITE_ACTLR(reg) Asm("mcr p15, 0, %0, c1, c0, 1"::"r"(reg))
222
223/*
224 * CP15によるキャッシュ操作マクロ
225 */
226
227/* 命令キャッシュ全体の無効化 */
228#define CP15_INVALIDATE_ICACHE() \
229 Asm("mcr p15, 0, %0, c7, c5, 0"::"r"(0))
230
231/* 分岐予測全体の無効化 */
232#define CP15_INVALIDATE_BP() Asm("mcr p15, 0, %0, c7, c5, 6"::"r"(0))
233
234/* データキャッシュ全体の無効化(ARMv6以前)*/
235#if __TARGET_ARCH_ARM <= 6
236#define CP15_INVALIDATE_DCACHE() Asm("mcr p15, 0, %0, c7, c6, 0"::"r"(0))
237#endif /* __TARGET_ARCH_ARM <= 6 */
238
239/* 統合キャッシュ全体の無効化(ARMv6以前)*/
240#if __TARGET_ARCH_ARM <= 6
241#define CP15_INVALIDATE_UCACHE() Asm("mcr p15, 0, %0, c7, c7, 0"::"r"(0))
242#endif /* __TARGET_ARCH_ARM <= 6 */
243
244/* データキャッシュ全体のクリーンと無効化(ARMv5のみ)*/
245#if __TARGET_ARCH_ARM <= 5
246#define ARMV5_CLEAN_AND_INVALIDATE_DCACHE() \
247 Asm("1: mrc p15, 0, apsr_nzcv, c7, c14, 3; bne 1b")
248#endif /* __TARGET_ARCH_ARM <= 5 */
249
250/* データキャッシュ全体のクリーンと無効化(ARMv6のみ)*/
251#if __TARGET_ARCH_ARM == 6
252#define CP15_CLEAN_AND_INVALIDATE_DCACHE() \
253 Asm("mcr p15, 0, %0, c7, c14, 0"::"r"(0))
254#endif /* __TARGET_ARCH_ARM == 6 */
255
256/* 統合キャッシュ全体のクリーンと無効化(ARMv6のみ)*/
257#if __TARGET_ARCH_ARM == 6
258#define CP15_CLEAN_AND_INVALIDATE_UCACHE() \
259 Asm("mcr p15, 0, %0, c7, c15, 0"::"r"(0))
260#endif /* __TARGET_ARCH_ARM == 6 */
261
262/* データキャッシュのセット/ウェイ単位の無効化 */
263#define CP15_WRITE_DCISW(reg) Asm("mcr p15, 0, %0, c7, c6, 2"::"r"(reg))
264
265/* データキャッシュのセット/ウェイ単位のクリーンと無効化 */
266#define CP15_WRITE_DCCISW(reg) Asm("mcr p15, 0, %0, c7, c14, 2"::"r"(reg))
267
268/*
269 * CP15のフォールト状態/アドレスの操作マクロ
270 */
271#if __TARGET_ARCH_ARM >= 6
272#define CP15_READ_DFSR(reg) Asm("mrc p15, 0, %0, c5, c0, 0":"=r"(reg))
273#define CP15_READ_DFAR(reg) Asm("mrc p15, 0, %0, c6, c0, 0":"=r"(reg))
274#define CP15_READ_IFSR(reg) Asm("mrc p15, 0, %0, c5, c0, 1":"=r"(reg))
275#define CP15_READ_IFAR(reg) Asm("mrc p15, 0, %0, c6, c0, 2":"=r"(reg))
276#else /* __TARGET_ARCH_ARM >= 6 */
277#define CP15_READ_FSR(reg) Asm("mrc p15, 0, %0, c5, c0, 0":"=r"(reg))
278#define CP15_READ_FAR(reg) Asm("mrc p15, 0, %0, c6, c0, 0":"=r"(reg))
279#endif /* __TARGET_ARCH_ARM >= 6 */
280
281/*
282 * CP15によるMMUの操作マクロ(VMSA)
283 */
284
285/* 変換テーブルベース制御レジスタ(ARMv6以降)*/
286#if __TARGET_ARCH_ARM >= 6
287#define CP15_WRITE_TTBCR(reg) Asm("mcr p15, 0, %0, c2, c0, 2"::"r"(reg))
288#endif /* __TARGET_ARCH_ARM >= 6 */
289
290/* 変換テーブルベースレジスタ0 */
291#define CP15_READ_TTBR0(reg) Asm("mrc p15, 0, %0, c2, c0, 0":"=r"(reg))
292#define CP15_WRITE_TTBR0(reg) Asm("mcr p15, 0, %0, c2, c0, 0"::"r"(reg))
293
294/* ドメインアクセス制御レジスタ */
295#define CP15_WRITE_DACR(reg) Asm("mcr p15, 0, %0, c3, c0, 0":: "r"(reg))
296
297/* コンテキストIDレジスタ(ARMv6以降)*/
298#if __TARGET_ARCH_ARM >= 6
299#define CP15_WRITE_CONTEXTIDR(reg) Asm("mcr p15, 0, %0, c13, c0, 1" ::"r"(reg))
300#endif /* __TARGET_ARCH_ARM >= 6 */
301
302/*
303 * CP15によるTLB操作マクロ(VMSA)
304 */
305
306/* TLB全体の無効化 */
307#define CP15_INVALIDATE_TLB() Asm("mcr p15, 0, %0, c8, c7, 0"::"r"(0))
308
309/*
310 * CP15のパフォーマンスモニタ操作マクロ(ARMv7のみ)
311 */
312#if __TARGET_ARCH_ARM == 7
313
314/* パフォーマンスモニタ制御レジスタ */
315#define CP15_READ_PMCR(reg) Asm("mrc p15, 0, %0, c9, c12, 0":"=r"(reg))
316#define CP15_WRITE_PMCR(reg) Asm("mcr p15, 0, %0, c9, c12, 0"::"r"(reg))
317
318/* パフォーマンスモニタカウントイネーブルセットレジスタ */
319#define CP15_READ_PMCNTENSET(reg) Asm("mrc p15, 0, %0, c9, c12, 1":"=r"(reg))
320#define CP15_WRITE_PMCNTENSET(reg) Asm("mcr p15, 0, %0, c9, c12, 1"::"r"(reg))
321
322/* パフォーマンスモニタカウンタサイクルレジスタ */
323#define CP15_READ_PMCCNTR(reg) Asm("mrc p15, 0, %0, c9, c13, 0":"=r"(reg))
324#define CP15_WRITE_PMCCNTR(reg) Asm("mcr p15, 0, %0, c9, c13, 0"::"r"(reg))
325
326#endif /* __TARGET_ARCH_ARM == 7 */
327
328/*
329 * CP15によるメモリバリア操作マクロ
330 */
331#define CP15_INST_SYNC_BARRIER() \
332 Asm("mcr p15, 0, %0, c7, c5, 4"::"r"(0):"memory")
333#define CP15_DATA_SYNC_BARRIER() \
334 Asm("mcr p15, 0, %0, c7, c10, 4"::"r"(0):"memory")
335#define CP15_DATA_MEMORY_BARRIER() \
336 Asm("mcr p15, 0, %0, c7, c10, 5"::"r"(0):"memory")
337
338/*
339 * メモリバリア
340 *
341 * ARMv6とARMv7が持つ3つのメモリバリア機能を使用するための関数.メモリ
342 * バリアは,ARMv7では専用命令,ARMv6ではCP15への書込みで実現される.
343 * ARMv7のメモリバリア命令は,同期を取る範囲を指定できるが,以下の関数
344 * では最大範囲(システム全体,リード/ライトの両方)で同期を取る.
345 *
346 * ARMv5以前では,メモリバリア機能は実装依存であるため,それぞれ,
347 * DATA_MEMORY_BARRIER,DATA_SYNC_BARRIER,INST_SYNC_BARRIERを定義する
348 * ことによって,関数の内容を入れ換えられるようにしている.
349 */
350
351/*
352 * データメモリバリア
353 *
354 * このバリアの前後で,メモリアクセスの順序が入れ換わらないようにする.
355 * マルチコア(厳密にはマルチマスタ)での使用を想定した命令.
356 */
357Inline void
358data_memory_barrier(void)
359{
360#ifdef DATA_MEMORY_BARRIER
361 DATA_MEMORY_BARRIER();
362#elif __TARGET_ARCH_ARM <= 6
363 CP15_DATA_MEMORY_BARRIER();
364#else /* __TARGET_ARCH_ARM <= 6 */
365 Asm("dmb":::"memory");
366#endif
367}
368
369/*
370 * データ同期バリア
371 *
372 * 先行するメモリアクセスが完了するのを待つ.メモリアクセスが副作用を
373 * 持つ時に,その副作用が起こるのを待つための使用を想定した命令.
374 */
375Inline void
376data_sync_barrier(void)
377{
378#ifdef DATA_SYNC_BARRIER
379 DATA_SYNC_BARRIER();
380#elif __TARGET_ARCH_ARM <= 6
381 CP15_DATA_SYNC_BARRIER();
382#else /* __TARGET_ARCH_ARM <= 6 */
383 Asm("dsb":::"memory");
384#endif
385}
386
387/*
388 * 命令同期バリア
389 *
390 * プログラムが書き換えられた(または,システム状態の変化により実行す
391 * べきプログラムが変わった)時に,パイプラインをフラッシュするなど,
392 * 新しいプログラムを読み込むようにする.ARMv6では,プリフェッチフラッ
393 * シュと呼ばれている.
394 */
395Inline void
396inst_sync_barrier(void)
397{
398#ifdef INST_SYNC_BARRIER
399 INST_SYNC_BARRIER();
400#elif __TARGET_ARCH_ARM <= 6
401 CP15_INST_SYNC_BARRIER();
402#else /* __TARGET_ARCH_ARM <= 6 */
403 Asm("isb":::"memory");
404#endif
405}
406
407/*
408 * CP15のセキュリティ拡張レジスタ操作マクロ(ARMv7のみ)
409 */
410#if __TARGET_ARCH_ARM == 7
411
412/* ベクタベースアドレスレジスタ */
413#define CP15_READ_VBAR(reg) Asm("mrc p15, 0, %0, c12, c0, 0":"=r"(reg))
414#define CP15_WRITE_VBAR(reg) Asm("mcr p15, 0, %0, c12, c0, 0"::"r"(reg))
415
416#endif /* __TARGET_ARCH_ARM == 7 */
417#endif /* TOPPERS_ARM_INSN_H */
Note: See TracBrowser for help on using the repository browser.