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

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

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr;charset=UTF-8
File size: 13.6 KB
RevLine 
[352]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-2017 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 * CP15によるキャッシュ操作マクロ
231 */
232
233/* 命令キャッシュ全体の無効化 */
234#define CP15_INVALIDATE_ICACHE() \
235 Asm("mcr p15, 0, %0, c7, c5, 0"::"r"(0))
236
237/* 分岐予測全体の無効化 */
238#define CP15_INVALIDATE_BP() Asm("mcr p15, 0, %0, c7, c5, 6"::"r"(0))
239
240/* データキャッシュ全体の無効化(ARMv6以前)*/
241#if __TARGET_ARCH_ARM <= 6
242#define CP15_INVALIDATE_DCACHE() Asm("mcr p15, 0, %0, c7, c6, 0"::"r"(0))
243#endif /* __TARGET_ARCH_ARM <= 6 */
244
245/* 統合キャッシュ全体の無効化(ARMv6以前)*/
246#if __TARGET_ARCH_ARM <= 6
247#define CP15_INVALIDATE_UCACHE() Asm("mcr p15, 0, %0, c7, c7, 0"::"r"(0))
248#endif /* __TARGET_ARCH_ARM <= 6 */
249
250/* データキャッシュ全体のクリーンと無効化(ARMv5のみ)*/
251#if __TARGET_ARCH_ARM <= 5
252#define ARMV5_CLEAN_AND_INVALIDATE_DCACHE() \
253 Asm("1: mrc p15, 0, apsr_nzcv, c7, c14, 3; bne 1b")
254#endif /* __TARGET_ARCH_ARM <= 5 */
255
256/* データキャッシュ全体のクリーンと無効化(ARMv6のみ)*/
257#if __TARGET_ARCH_ARM == 6
258#define CP15_CLEAN_AND_INVALIDATE_DCACHE() \
259 Asm("mcr p15, 0, %0, c7, c14, 0"::"r"(0))
260#endif /* __TARGET_ARCH_ARM == 6 */
261
262/* 統合キャッシュ全体のクリーンと無効化(ARMv6のみ)*/
263#if __TARGET_ARCH_ARM == 6
264#define CP15_CLEAN_AND_INVALIDATE_UCACHE() \
265 Asm("mcr p15, 0, %0, c7, c15, 0"::"r"(0))
266#endif /* __TARGET_ARCH_ARM == 6 */
267
268/* データキャッシュのセット/ウェイ単位の無効化 */
269#define CP15_WRITE_DCISW(reg) Asm("mcr p15, 0, %0, c7, c6, 2"::"r"(reg))
270
271/* データキャッシュのセット/ウェイ単位のクリーンと無効化 */
272#define CP15_WRITE_DCCISW(reg) Asm("mcr p15, 0, %0, c7, c14, 2"::"r"(reg))
273
274/*
275 * CP15のフォールト状態/アドレスの操作マクロ
276 */
277#if __TARGET_ARCH_ARM >= 6
278#define CP15_READ_DFSR(reg) Asm("mrc p15, 0, %0, c5, c0, 0":"=r"(reg))
279#define CP15_READ_DFAR(reg) Asm("mrc p15, 0, %0, c6, c0, 0":"=r"(reg))
280#define CP15_READ_IFSR(reg) Asm("mrc p15, 0, %0, c5, c0, 1":"=r"(reg))
281#define CP15_READ_IFAR(reg) Asm("mrc p15, 0, %0, c6, c0, 2":"=r"(reg))
282#else /* __TARGET_ARCH_ARM >= 6 */
283#define CP15_READ_FSR(reg) Asm("mrc p15, 0, %0, c5, c0, 0":"=r"(reg))
284#define CP15_READ_FAR(reg) Asm("mrc p15, 0, %0, c6, c0, 0":"=r"(reg))
285#endif /* __TARGET_ARCH_ARM >= 6 */
286
287/*
288 * CP15によるMMUの操作マクロ(VMSA)
289 */
290
291/* 変換テーブルベース制御レジスタ(ARMv6以降)*/
292#if __TARGET_ARCH_ARM >= 6
293#define CP15_WRITE_TTBCR(reg) Asm("mcr p15, 0, %0, c2, c0, 2"::"r"(reg))
294#endif /* __TARGET_ARCH_ARM >= 6 */
295
296/* 変換テーブルベースレジスタ0 */
297#define CP15_READ_TTBR0(reg) Asm("mrc p15, 0, %0, c2, c0, 0":"=r"(reg))
298#define CP15_WRITE_TTBR0(reg) Asm("mcr p15, 0, %0, c2, c0, 0"::"r"(reg))
299
300/* ドメインアクセス制御レジスタ */
301#define CP15_WRITE_DACR(reg) Asm("mcr p15, 0, %0, c3, c0, 0":: "r"(reg))
302
303/* コンテキストIDレジスタ(ARMv6以降)*/
304#if __TARGET_ARCH_ARM >= 6
305#define CP15_WRITE_CONTEXTIDR(reg) Asm("mcr p15, 0, %0, c13, c0, 1" ::"r"(reg))
306#endif /* __TARGET_ARCH_ARM >= 6 */
307
308/*
309 * CP15によるTLB操作マクロ(VMSA)
310 */
311
312/* TLB全体の無効化 */
313#define CP15_INVALIDATE_TLB() Asm("mcr p15, 0, %0, c8, c7, 0"::"r"(0))
314
315/*
316 * CP15のパフォーマンスモニタ操作マクロ(ARMv7のみ)
317 */
318#if __TARGET_ARCH_ARM == 7
319
320/* パフォーマンスモニタ制御レジスタ */
321#define CP15_READ_PMCR(reg) Asm("mrc p15, 0, %0, c9, c12, 0":"=r"(reg))
322#define CP15_WRITE_PMCR(reg) Asm("mcr p15, 0, %0, c9, c12, 0"::"r"(reg))
323
324/* パフォーマンスモニタカウントイネーブルセットレジスタ */
325#define CP15_READ_PMCNTENSET(reg) Asm("mrc p15, 0, %0, c9, c12, 1":"=r"(reg))
326#define CP15_WRITE_PMCNTENSET(reg) Asm("mcr p15, 0, %0, c9, c12, 1"::"r"(reg))
327
328/* パフォーマンスモニタカウンタサイクルレジスタ */
329#define CP15_READ_PMCCNTR(reg) Asm("mrc p15, 0, %0, c9, c13, 0":"=r"(reg))
330#define CP15_WRITE_PMCCNTR(reg) Asm("mcr p15, 0, %0, c9, c13, 0"::"r"(reg))
331
332#endif /* __TARGET_ARCH_ARM == 7 */
333
334/*
335 * CP15によるメモリバリア操作マクロ
336 */
337#define CP15_INST_SYNC_BARRIER() \
338 Asm("mcr p15, 0, %0, c7, c5, 4"::"r"(0):"memory")
339#define CP15_DATA_SYNC_BARRIER() \
340 Asm("mcr p15, 0, %0, c7, c10, 4"::"r"(0):"memory")
341#define CP15_DATA_MEMORY_BARRIER() \
342 Asm("mcr p15, 0, %0, c7, c10, 5"::"r"(0):"memory")
343
344/*
345 * メモリバリア
346 *
347 * ARMv6とARMv7が持つ3つのメモリバリア機能を使用するための関数.メモリ
348 * バリアは,ARMv7では専用命令,ARMv6ではCP15への書込みで実現される.
349 * ARMv7のメモリバリア命令は,同期を取る範囲を指定できるが,以下の関数
350 * では最大範囲(システム全体,リード/ライトの両方)で同期を取る.
351 *
352 * ARMv5以前では,メモリバリア機能は実装依存であるため,それぞれ,
353 * DATA_MEMORY_BARRIER,DATA_SYNC_BARRIER,INST_SYNC_BARRIERを定義する
354 * ことによって,関数の内容を入れ換えられるようにしている.
355 */
356
357/*
358 * データメモリバリア
359 *
360 * このバリアの前後で,メモリアクセスの順序が入れ換わらないようにする.
361 * マルチコア(厳密にはマルチマスタ)での使用を想定した命令.
362 */
363Inline void
364data_memory_barrier(void)
365{
366#ifdef DATA_MEMORY_BARRIER
367 DATA_MEMORY_BARRIER();
368#elif __TARGET_ARCH_ARM <= 6
369 CP15_DATA_MEMORY_BARRIER();
370#else /* __TARGET_ARCH_ARM <= 6 */
371 Asm("dmb":::"memory");
372#endif
373}
374
375/*
376 * データ同期バリア
377 *
378 * 先行するメモリアクセスが完了するのを待つ.メモリアクセスが副作用を
379 * 持つ時に,その副作用が起こるのを待つための使用を想定した命令.
380 */
381Inline void
382data_sync_barrier(void)
383{
384#ifdef DATA_SYNC_BARRIER
385 DATA_SYNC_BARRIER();
386#elif __TARGET_ARCH_ARM <= 6
387 CP15_DATA_SYNC_BARRIER();
388#else /* __TARGET_ARCH_ARM <= 6 */
389 Asm("dsb":::"memory");
390#endif
391}
392
393/*
394 * 命令同期バリア
395 *
396 * プログラムが書き換えられた(または,システム状態の変化により実行す
397 * べきプログラムが変わった)時に,パイプラインをフラッシュするなど,
398 * 新しいプログラムを読み込むようにする.ARMv6では,プリフェッチフラッ
399 * シュと呼ばれている.
400 */
401Inline void
402inst_sync_barrier(void)
403{
404#ifdef INST_SYNC_BARRIER
405 INST_SYNC_BARRIER();
406#elif __TARGET_ARCH_ARM <= 6
407 CP15_INST_SYNC_BARRIER();
408#else /* __TARGET_ARCH_ARM <= 6 */
409 Asm("isb":::"memory");
410#endif
411}
412
413/*
414 * CP15のセキュリティ拡張レジスタ操作マクロ(ARMv7のみ)
415 */
416#if __TARGET_ARCH_ARM == 7
417
418/* ベクタベースアドレスレジスタ */
419#define CP15_READ_VBAR(reg) Asm("mrc p15, 0, %0, c12, c0, 0":"=r"(reg))
420#define CP15_WRITE_VBAR(reg) Asm("mcr p15, 0, %0, c12, c0, 0"::"r"(reg))
421
422#endif /* __TARGET_ARCH_ARM == 7 */
423#endif /* TOPPERS_ARM_INSN_H */
Note: See TracBrowser for help on using the repository browser.