=====================================================================
                         ARM-Mプロセッサ依存部
                                  Last Modified:2016 Jan 11 10:44:12
=====================================================================


(1) 対応しているターゲットシステムの種類・構成

ARM-M依存部は，ARMvx-Mアーキテクチャをターゲットとしている．ARMvx-Mは，
ARMとは異なり，ARM命令を実行できないため，ARM依存部と分けている．現状
サポートしているコアは次の通りである．

・Cortex-M0
・Cortex-M0+
・Cortex-M3
・Cortex-M4

(2) 使用する開発環境と動作検証した条件（バージョン，オプション等）

カーネルはGCCを用いてコンパイルする．動作確認したバージョンは各ターゲ
ット依存部のドキュメントに記載する．


(3) ターゲット定義事項の規定

(3-1) データ型に関する規定

データ型は arch/gcc/tool_stddef.h で定義されている内容で，float型と
double型は，それぞれIEEE754準拠の単精度浮動小数点数と倍精度浮動小数点
数である．

(3-2) 割込み処理に関する規定

○割込みハンドラ番号と割込み番号の割当て，両者の対応

割込みハンドラ番号と割込み番号は，例外発生時にIPSRにセットされる例外番
号を用いる．SYSTICKは15番で，外部割込みは16番からの番号が割り付けられ
ている．

○割込み優先度の段階数とTMIN_INTPRIの値

割込み優先度の段階数は，SoC毎にハードウェア的にサポートする割込み優先
度ビット幅が異なるので，ターゲット依存部毎に異なる．ターゲット依存部で
は，割込み優先度のビット幅（TBITW_IPRI）とその割込み優先度中のサブ優先
度のビット幅（TBITW_SUBPRI）を定義する．

各ビット幅の値とCFG_INTで使用可能な割込み優先度の範囲は次の通りである．

   -(2^(TBIW_IPRI)) + (2^TBITW_SUBIPRI) ～ -1

例えば優先度のビット幅(TBITW_IPRI)が8bit，サブ優先度のビット幅
(TBITW_SUBIPRI) が1bitの場合は，-254 ～ -1 の範囲である．

優先度のビット幅(TBITW_IPRI)が3bit，サブ優先度のビット幅(TBITW_SUBIPRI) 
が0bitの場合は，-8 ～ -1 の範囲である．

最大優先度(3bitの例では-8)は，内部優先度としては"0x00"となる．この優先
度はCPUロックで用いるBASEPRIレジスタではマスクできないため，カーネル管
理内の割込みの最高優先度（TMIN_INTPRI）は，最大値より1つ優先度が低い値
以下の値を指定する．

この範囲で，カーネル管理内の割込みの最高優先度（TMIN_INTPRI）をターゲ
ット依存部で設定する．

○dis_intとena_intのサポートの有無，その制限事項

dis_intとena_intをサポートする．制限事項は特にない．

○CFG_INTの制限事項と拡張（ターゲット定義で使用できる割込み属性）

CFG_INTの制限事項はなく，ターゲット定義で使用可能な割込み属性は特にな
い．

○カーネル管理外の割込み

ARMv7-Mでは，カーネル管理外の割込みをサポートする．指定方法は，割込み
優先度の段階数で指定した，サポートする割込み優先度の最高値（最小値）よ
り，TMIN_INTPRIの値を大きく（優先度を低く）設定すると，TMIN_INTPRIより
値が小い（高優先度）な割込み優先度を設定した割込みを割込み優先度として
扱う．

カーネル管理外の割込みはOS実行中も禁止になることはなく（厳密には割込み
の出口でごく短い区間禁止される），割込み発生時は，カーネルのコードを経
由せずに呼び出される．

カーネル管理外の割込みに対する，DEF_INH,CFG_INTはサポートする．

(3-3) CPU例外処理に関する規定

○CPU例外ハンドラ番号

CPU例外ハンドラ番号としては，例外発生時にIPSRにセットされる，例外番号
を用いる．各例外の例外番号は以下の通りである．

        例外              例外番号
  Reset                      1
  Non-makable Interrupt      2
  Hard Fault                 3
  Memory Management          4
  Bus Fault                  5
  Usage Fault                6
  SVCall                    11
  Debug Monitor             12
  PendSV                    14

なお，Resetと，SVCall(ARMv7-M)，PendSV(ARMv6-M)については，カーネルが
使用するため，ユーザーは使用することができない．

ARM-MアーキテクチャではCPU例外に優先度を設定することが可能である．
ARM-M依存部では，全てのCPU例外の優先度をCPUロックではマスクできないマ
スク出来ない値（内部優先度0）に初期化している．

(3-4) CPUロック・割込みロック

ARMv7-Mでは，CPUロックは，basepriをTMIN_INTPRIの優先度の割込みを禁止す
る値に設定する．割込みロックは，FAULTMASKを'1'に設定することで実現してい
る．

ARMv6-Mでは，CPUロック/割込みロック共にPRIMASKにより実現している．

(3-5) 性能評価用システム時刻の参照に関する規定

get_utmをサポートする．精度に関しては，ターゲット毎に異なる．

(3-6) スタートアップルーチンでの初期化内容

スタートアップルーチンは，Threadモードで呼び出されることを前提としてい
る．実行後，割込みロック状態とする．割込みロック状態は，カーネルの初期
化終了時に許可する．スタートアップルーチンで，MSPをアクティブなスタッ
クとし，MSPの内容を初期化するためには，INIT_MSPをターゲット依存部で定
義する．

(3-7) ベクタテーブルオフセットの初期化

プロセッサ依存の初期化処理で，Vector Table Offset Register をターゲッ
ト依存部の初期化ルーチンで設定する．なお，ベクターテーブルは，.vector
のセクション属性が付加されているため，リンカスクリプトでこのセクション
を指定して配置する．


(4) タイマドライバ関連の情報

カーネルのタイムティックとして，SYSTICを使用する場合は，core_config.c 
をコンパイル対象とし，コンフィギュレーションファイルに core_config.cfg 
を指定すること．

周期の基本は1msecとする．周期をCALIBRATIONレジスタの設定内容を元に計算
する場合は，SYSTIC_USE_CALIBRATION を定義する．CALIBRATIONレジスタを用
いない場合は，1msec周期分のカウント値を TIMER_CLOCK に設定する．クロッ
クソースとして，外部クロックを用いる場合は，SYSTIC_USE_STCLK を用いる．


(5) ターゲット依存部での設定項目

ターゲット依存部では以下のマクロを定義する必要がある．

   ･TMAX_INTNO     : 割込み番号の最大値(通常の割込み番号 + 15)
   ･TBITW_IPRI     : 割込み優先度のビット幅
   ･TBITW_SUBIPRI  : 割込み優先度のビット幅中のサブ優先度のビット幅
   ･TMIN_INTPRI    : 割込み優先度の最小値（最高値）
   ･TIC_NUME       : タイムティックの周期の分子
   ･TIC_DENO       : タイムティックの周期の分母
   ･TIMER_CLOCK    : タイマ値の内部表現とミリ秒単位との変換
   ･INTPRI_TIMER   : タイマ割込み割込み優先度
   ･INTATR_TIMER   : タイマ割込みの割込み属性
   ･INIT_MSP       : スタートアップルーチンでMSPを初期化する場合は定義
   ･DEFAULT_ISTKSZ : スタックサイズ（8byte単位で指定）
   ･SIL_DLY_TIM1   : 微少時間待ちのための定義
   ･SIL_DLY_TIM2   : 微少時間待ちのための定義

ターゲット依存部のMakefileでは以下を定義する必要がある．

   ・CORE_TYPE     : コアの種類
                     CORTEX_M4/CORTEX_M3/CORTEX_M0/CORTEX_M0PLUS/
   ・FPU_USAGE     : FPUを使用する場合にいずれかに定義．
                     FPU_NO_PRESERV      : コンテキスト保存なし
                     FPU_NO_LAZYSTACKING : コンテキスト保存あり
                     FPU_LAZYSTACKING    : コンテキスト保存あり(Lazy stacking)                  
   ・FPU_ABI       : FPU使用時のABIいずれかを指定
                     softfp : float/dobuleの引数の受け渡しに一般レジスタを使用
                     hard   : float/dobuleの引数の受け渡しにFPUレジスタを使用
                     
(6) その他

(6-1) Configureation and Control Register(CCR)のSTKALIGNの制限

システム起動後（正確にはOSの初期化終了後）はCCRのSTKALIGNの設定は，変
更しないこと．


(7) ディレクトリ構成・ファイル構成
  ./arch/arm_m_gcc/common
    ./Makefile.core
    ./arm_m.h
    ./makeoffset.c
    ./core.tf
    ./core_cfg1_out.h
    ./core_check.tf
    ./core_config.c
    ./core_config.h
    ./core_def.csv
    ./core_insn.h
    ./core_kernel.h
    ./core_rename.def
    ./core_rename.h
    ./core_sil.h
    ./core_stddef.h
    ./core_support.S
    ./core_test.h
    ./core_timer.c
    ./core_timer.cfg
    ./core_timer.h
    ./core_unrename.h
    ./core_user.txt
    ./start.S

(8)ARMCC共有コードの記述方法

ARMCCと共有するコードは，次のルールに従ってコードを記述する必要がある．

1.メモリバリア命令(Asm("":::"memory"))のマクロ化

ターゲット依存部 ポーティングガイドの(1-6-2)(c)には，次のように記述さ
れている．

-----
(c) クリティカルセクションの出入処理の本質的な部分が，マクロやインライ
	ン関数呼出しで実現している場合には，クリティカルセクションに入る処
	理の最後と出る処理の先頭に，Asm("":::"memory")という記述を入れる．
-----

メモリバリア命令(Asm("":::"memory"))は，ARMCCと互換性がないため，この
記述をする箇所は，次のマクロで記述すると，コンパイル時に適切なメモリバ
リア命令に置き換えられる．

  ARM_MEMORY_CHANGED

2.インクルード方法

ターゲット依存部 ポーティングガイドの1.5には，次のように記述されている．

-----
その他のヘッダファイルは，「#include "..."」によりインクルードする．ヘッ
ダファイルが，カレントディレクトリやインクルードするファイルと同じディ
レクトリ以外のディレクトリに置かれている場合には，次のようにパス指定を
行う．
-----

GCC依存部とARMCC依存部でヘッダファイルを共有できない場合には，それぞれ
で同じ名前のファイルを持つ．そして，コンパイルオプションでインクルード
すべきファイルを先に指定している．そのため，ARMCCと共有するファイルで
これらのファイルをインクルードする場合には，「#include "..."」ではなく，
「#include <...>」で記述し，相対パスではなくファイル名のみを記載するこ
と．

3.アセンブラディレクティブ

GCCとARMCCのアセンブラディレクティブは互換性がない．そのため，ARMCCと
共有するファイルは次に示すマクロディレクティブで記述すること．

マクロディレクティブ     GCCディレクティブ
 ASECTION(name)          .section name,"a"
 ATEXT                   .text
 AGLOBAL(name)           .global name
 AALIGN(x)               .align x
 ALONG                   .long
 ALABEL(label)           label:
 AOR                       |
 ATHUMB(name)            __athumb name


(9)アイドル処理

実行するべきタスクがない場合は，ディスパッチャーで割込みを許可して，割
込みを待つ（dispatcher_2）．ARM-M依存部のコードでは，次のようになって
いる．

    PRIMASK をセット
    全割込み許可
    wfi
    PRIMASK をクリア（割込みを受け付ける）
    CPUロック状態へ

ターゲット依存で，上記の処理の代わりに，省電力モード等に移行する処理を
記述したい場合には，ターゲット依存部で，TOPPERS_CUSTOM_IDLEを定義し，
代わりに実行した処理を toppers_asm_custom_idle というアセンブラマクロ
として記述する．

なお，toppers_asm_custom_idle の記述にあたっては，次のレジスタは
oppers_asm_custom_idleの前後で使用するため，oppers_asm_custom_idle 内
で使用する場合は，前後で保存復帰すること．これらのレジスタは Calee 
saved レジスタであるため， oppers_asm_custom_idle として関数呼び出しを
した場合は，呼び出した関数で自動的に保存復帰されるため，アセンブラレベ
ルでの保存復帰は必要ない．

レジスタ : 内容
r4      : '0'
r5      : 'IIPM_LOCK'
r6      : reqflgのアドレス
r7      : lock_flgのアドレス
sp      : 非タスクコンテキスト用のスタックの先頭アドレス(msp)

アセンブラマクロはC言語記述中に展開するとエラーとなる．core_support.S で
は，TOPPERS_ASM_MACRO というマクロを定義しているため，ターゲット依存部
で toppers_asm_custom_idle アセンブラマクロを定義する際には，
TOPPERS_ASM_MACRO を条件コンパイルの条件として用いること．

(10)FPU
Cortex-M4FのFPUをサポートしている．FPUの使用方法は次の3種類から選択可
能である．それぞれMakefile内でFPU_USAGEマクロを定義して指定する．指定
がない場合はFPUを無効とする．

FPU_NO_PRESERV       
ディスパッチャ等ではFPUコンテキストの保存復帰を行わない．
FPUを使用可能なタスクは1個もしくは，システム中の最高優先度のISR群で使
用可能．

FPU_NO_LAZYSTACKING 
ディスパッチャ等ではFPUコンテキストの保存復帰を行う．Lazy stacking は
使用しない．全てのタスク/ISRでFPUを使用可能．

FPU_LAZYSTACKING
ディスパッチャ等ではFPUコンテキストの保存復帰を行う．Lazy stacking を
使用する．全てのタスク/ISRでFPUを使用可能．

(11)その他

1. ベクターテーブルのセクション指定

core.tf で以下の _kernel_vector_table の配列の変数の宣言の生成の際に，
GEN_VECTOR_TABLE_VARNAME という関数が定義されていれば，core.tf では変
数の宣言は行わず，GEN_VECTOR_TABLE_VARNAME を呼び出す．

const FP _kernel_vector_table[] = 

GEN_VECTOR_TABLE_VARNAME が宣言されている場合でも，配列の本体の生成は，
core.tfで行う．

2. ARMv6-Mでの割込みロック(SIL_LOC_INT())

CPUロック・割込みロックにPRIMASKを使用しているため，CPUロック・割込み
ロック中にHardwareFault以外の例外が発生して受け付けられなくなるという
制約がある．

(12) バージョン履歴
2016/01/10
・NVICを操作して割り込み禁止，優先度変更をした直後には，同期命令を実行
  するよう変更(SCS_SYNCマクロを呼び出す)．

2016/01/05
・core_config.h
  ・動的生成パッケージ向けに VALID_INTNO_CREISR(intno) を追加．

2015/11/22
・Cortex-M4FのFPUのサポートを追加．

2015/11/14
・ARMv7-M
  ・core_sil.h
    ・割込みロック(SIL_LOC_INT())をBASEPRIを使用するように変更．
    ・元のFAULTMASKだとFAULTMASKをセットした状態で例外が発生すると例外
      が発生しないため．

2015/11/04
・ARMv6-M対応に関する変更
 ・ARMv7-Mに影響を及ぼす変更
  ・例外フレームのフォーマットを変更(basepriとEXC_RETURNの順序を変更)
  ・エントリポイント(_start)をリネームの対象に変更．
    ・Cライブラリの_startと名前が重複するため．
  ・Makefile.coreで -nostdlib を付けないように変更．
    ・ターゲット依存部で指定する
  
2014/12/01
・core_support.S
  2013/08/20 の修正でPSP上への割込み優先度マスク(r2)とEXC_RETURN(lr)の
  保存をstfmdで行うにしたが，スタックへの積み方がlr,r2となっているため
  ，割込み・例外出口のコードとの整合性がとれていなかった．r2,lrと保存
  するようにlrをr0に一旦コピーしてr0(lr),r2とstmfdに指定するよう変更．
    
2014/07/23
・target_timer_probe_int()において，SYSTIC_CONTROL_STATUS を一度読み込
  むとクリアされるため，割込み等で複数回読み込む使い方には適応しない．
  そのため，NVICのペンディングレジスタを読み込むように変更．

2012/10/17
・1.8.0対応のため，char_t の箇所を他の型に変更．

2013/08/20
・core_support.S
 例外/割込み例外発生時のPSP上への割込み優先度マスク(r2)とEXC_RETURN(lr)
 の保存をstmfd1命令で実施するように変更．

2013/03/10
・core_support.S
  sub/addはアセンブラにより32bit命令ｎsub.w/add.wと変換される．16bit命
  令のsubs/addsでも問題ないため，変更．

2012/06/18
・xxx_stddef.h を相対パスではなくファイル名のみで指定するように変更．
  どのファイルを用いるかは他のファイルと同様にコンパイラへのインクルー
  ド指定の順序とする．
・core.tf で _kernel_vector_table の配列の変数の宣言部分を生成する際に，
  GEN_VECTOR_TABLE_VARNAME という関数が定義されていれば，呼び出すよう
  に変更．
  セクション指定方法がコンパイラ毎に異なるため用意．
    
2012/02/29
・Makefile.core
  ・CDEFSにTOPPERS_LABEL_ASMを指定していたが，ARM用のgccではアセンブラ
    のシンボルの前に_を付けないため削除．
  
2012/02/02
・core_config.h
  ・x_set_ipm()で，iipmが'0'(IIPM_ENAALL)の時の問題を修正．
・core_support.S
  ・toppers_asm_custom_idleの前後で使用するレジスタを変更．この変更に
    より，toppers_asm_custom_idle で関数呼び出しをする場合は，アセンブ
    ラレベルでのレジスタの保存が必要なくなった．
    
2012/02/23
・core_support.S
  ・core_exc_entryでbasepriを読み込んだあと，全割込みロック状態のチェ
    ックために上書きしていた問題を修正
  ・call_texrtnとcall_texrtnの呼び出しをb命令で記述すると，16bit命令と
    して解釈するコンパイラがあるため，メモリ配置によってはレンジが足り
    なくなる．bx命令に変更することで問題を修正．

2012/01/31
・core_timer.c
 ・タイマ割込みハンドラにて，probe_int のため，COUNTFLAGをクリアするた
   めに読み込んでいたレジスタが誤っていた問題を修正．
 
2011/12/03
・core_test.h の多重インクルード防止マクロの名称修正
 ・CHIP を CORE に修正．

・ARMCC対応に伴う変更
  ・core_asm.inc(追加)
    ・GCCのアセンブラのディレクティブの定義を記述したファイルを追加．
  ・core_config.h(変更)
    ・core_insn.h のインクルード方法を""から<>に変更して，コンパイラの
      引数で指定された順でインクルードファイルをサーチするよう変更．
   ・メモリバリア命令(Asm("":::"memory"))をマクロ化してcore_insn.h に
     定義を使用するよう変更．     
  ・core_insn.h(変更)
   ・メモリバリア命令(Asm("":::"memory"))のマクロ定義を追加
  ・core_support.S(変更)
   ・ARMCCとファイルを共有するため，ディレクティブをマクロに書き換え．      
  ・start.S(変更)
   ・ARMCCとファイルを共有するため，ディレクティブをマクロに書き換え．  
   
2011/07/26
・CCRのSTKALIGNが'1'の場合への対応
  割込み・例外の出入口処理では，スタックは常に8byte境界となるように変
  更．
  
2011/07/25
・CPU例外の優先度の初期化
  CPUロックでマスクできない優先度（内部優先度0）に初期化する処理を追加．
  
・CFG_INTで使用できる割込み優先度の最大値の修正(core.tf)
  ・最大値が1つ大きな値となっていた．
  
・カーネル管理外の割込みの扱いの変更
  ・共通部での扱いの変更に伴う変更．
  
・タイマ割込みハンドラでのCOUNTFLAGのクリア処理の修正
  SYSTIC_CONTROL_STATUSレジスタのCOUNTFLAGをクリアするには，
  SYSTIC_CURRENT_VALUEレジスタを読み込む必要があるが，誤って
  SYSTIC_CONTROL_STATUSレジスタを読み込んでいた．

・core_int_entryにおけるbasepriの設定
  NVIC優先度マスクが自動的に設定されるため優先度マスクの点では必要な
  いが，x_get_ipm()がbasepriを参照するため，basepriも更新するよう変更．

2011/07/24
・_ret_int_2/svc_handler の変更
  割込み優先度マスクが全解除状態でしかタスク例外を呼び出さないように
  仕様が変更されたため，_ret_int_2では，割込み優先度マスクを，全解除
  状態（TIPM_ENAALL）に設定するよう変更．
  svc_handlerはタスクにリターンする時にbasepriをIIPM_ENAALLにするよう
  に変更．
  
・x_config_int()/set_exc_int_priority()の修正  
  x_config_int()から，set_exc_int_priority()に対して外部優先度を引数に
  して呼び出しいたため，内部優先度を引数で呼び出すよう修正．
  set_exc_int_priority()も受け取った引数を内部優先度として優先度を設定
  するように修正．

2011/07/23
・共通部を1.4.0にupdate.

・arm依存部と同様にチップ依存部を置けるようにディレクトリ構造を変更

・arm依存部と同様にファイル名のプリフィックスをcoreに変更．

・call_atexitの削除
  software_term_hook の呼び出しは，core_terminate()に移動．
  
・共通部を1.7.0にupdate.  

・タスクコンテキストブロックの型名の変更
  CTXB型をTSKCTXB型に名称変更．

・ターゲット依存部でサポートする機能を示すマクロの変更
  TOPPERS_SUPPORT_DIS_INTをTOPPERS_TARGET_SUPPORT_DIS_INTに，
  TOPPERS_SUPPORT_ENA_INTをTOPPERS_TARGET_SUPPORT_ENA_INTに，
  変更．
  
・exc_sense_unlockの定義を削除．  
  
・オフセットファイルをコンフィギュレータで生成する方法への対応

・CHECK_FUNC_ALIGN，CHECK_FUNC_NONNULL，CHECK_STACK_ALIGN，
  CHECK_STACK_NONNULL，CHECK_MPF_ALIGN，CHECK_MPF_NONNULLの定義を，タ
  ーゲット依存部のテンプレートファイル（パス3）からヘッダファイルに移
  動．

・割込みと例外の入り口処理の名前を変更
  int_entryをcore_int_entryへexc_entryをcore_exc_entryに変更．
  オフセットの取得方法が変更となったため，元の名前のままだとcfg1_out.c
  がコンパイルエラーとなるために変更．
  
・ターゲット依存部で定義する名称のリネームの追加

・call_texrtnを呼び出す条件に「ipmflgがtrue」を追加
 
・カーネル管理外のCPU例外の扱いの変更

2011/07/22
・x_disable_int() : prc_config.h の修正   
 割込み禁止レジスタのアドレスを取得する際に，ベースの値をuint32_tの
 ポインタにキャストしていなったため，正しいアドレスが生成できていな
 かった問題を修正．
 
・非タスクコンテキスト用のスタックの初期値マクロ(TOPPERS_ISTKPT)の修正 
  : prc_config.h
 バイト単位で取得するように，(char_t *) にキャストして掲載するように修
 正．
  
・LOG_INH_ENTRYとLOG_INH_LEAVEの誤記 : prc_support.S
  LOG_INH_ENTRYとLOG_INH_LEAVEであるべき箇所が LOG_EXC_ENTRYと
  LOG_EXC_ENTRYになっている問題を修正．

・TOPPERS_CUSTOM_IDLE のtypoの修正 : prc_support.S

・svn_hanlderの修正 :  prc_support.S
  一律EXC_FRAME_SIZE分のスタックを捨てていたが，Configureation and 
  Control Register(CCR)のSTKALIGNが'1'の場  合は，8byte境界にアライン
  されるため，捨てるサイズが異なる．アラインされたかは，xPSRの9ビッ
  トをチェックすることにより判定する．
  
・prc.tfの修正
  boostのバージョンによって変わる挙動を吸収．
  http://www.toppers.jp/TOPPERS-USERS/201004/msg00034.html
  
・_kernel_istkpt の削除 : prc_cfg1_out.h
  _kernel_istkpt が必要ないターゲットが存在するため，必要なら，ターゲ
  ット依存部で定義するように変更．

2008/08/22
・prc_user.txt/prc_design.txt
  ・2008/8/21の技術検討会での議論結果を反映．
  
・prc_support.S/prc_config.c/prc_config.h/arm_m.h
  ・コンテキスト判定をexc_ncntからアクティブなスタックに変更
  
・prc_config.c
  ・set_exc_int_priority() でサポート可能なIRQの上限を239に拡張．
  
・start.S 
  ・起動時はThreadモードを前提としていることを明記．
  ・ブートローダー等から起動される場合を想定し，MSPを有効にするように
    変更．
    
・prc_timer.c
  ・コメントを修正
  ・デバッグ用コードを削除

2008/07/11
・最初のリリース
