1: ==============================================================================
2: T-Kernel 2.0 (tef_em1d) 実装仕様書
3: ==============================================================================
4: Version 1.00.00
5: 1. 概要
6:
7: 本書は、T-Monitor、T-Kernel およびデバイスドライバーに関する T-Engine リファレ
8: ンスボード(以後 tef_em1d と表記) 固有の実装に関する仕様書である。
9:
10: 2. 全体の実装仕様
11:
12: 2.1 レジスタ名称
13:
14: ARM プロセッサのレジスタ名称は、概ね「ARM アーキテクチャリファレンスマニ
15: ュアル (ARM DDI 0406)」にしたがうが、特にシステム制御コプロセッサのレジ
16: スタは、下記のような形式のレジスタ指定により示す場合がある。
17:
18: CPn.CRn.opc1.CRm.opc2
19:
20: CPn コプロセッサ番号
21: CRn プロセッサレジスタ指定
22: CRm 追加のコプロセッサレジスタ指定
23: opc1 オペコード1
24: opc2 オペコード2
25:
26: 以下にいくつかの例を挙げる。
27:
28: SCTLR (CP15.c1.0.c0.0) システム制御レジスタ
29: CPACR (CP15.c1.0.c0.2) コプロセッサアクセス制御レジスタ
30: TTBR0 (CP15.c2.0.c0.0) 変換テーブルベースレジスタ0
31: TTBR1 (CP15.c2.0.c0.1) 変換テーブルベースレジスタ1
32: TTBCR (CP15.c2.0.c0.2) 変換テーブルベース制御レジスタ
33: PRRR (CP15.c10.0.c2.0) 一次領域再マップレジスタ
34: NMRR (CP15.c10.0.c2.1) ノーマルメモリ再マップレジスタ
35:
36: 2.2 プロセッサの設定
37:
38: (1) MMU
39:
40: MMU は以下の設定とする。
41: この設定は、システム起動時に T-Monitor により設定され、以後変更されない
42: (変更してはならない)。
43:
44: (a) SCTLR.AFE [29] = 1
45:
46: ページテーブルのアクセスフラグを有効にする。
47:
48: (b) SCTLR.TRE [28] = 1
49:
50: メモリー属性 TEX の再マップを有効にする。
51:
52: (c) PRRR = 0x000a8aa4
53:
54: (d) NMRR = 0x44e048e0
55:
56: メモリー属性の再マップを、以下のように割り当てる。
57:
58: TEX[0] C B メモリータイプ 内部キャッシュ 外部キャッシュ
59: 0 0 0 Strongly-order None None
60: 0 0 1 Device None None
61: 0 1 0 Normal WT-NA WT-NA
62: 0 1 1 Normal WB-NA WB-NA
63: 1 0 0 Normal None None
64: 1 0 1 Normal WT-NA WB-A
65: 1 1 0 (未使用)
66: 1 1 1 Normal WB-A WB-A
67:
68: WT-NA Write-through, no allocate on write
69: WB-NA Write-back, no allocate on write
70: WB-A Write-back, allocate on write
71:
72: (2) セキュリティ
73:
74: 常にセキュア状態で動作するものとし、非セキュア状態は使用しない(非セキュ
75: ア状態になることはない)。よって、ARM プロセッサモードのモニターモードも
76: 使用されない。
77:
78: 非セキュア状態の各種レジスタの初期設定も特に行わない。
79:
80: 2.3 メモリーマップ
81:
82: (1) 全体
83:
84: 論理アドレス モード
85: 0x00000000 +=======================+ --
86: |タスク固有空間 | | 仮想メモリー (予約)
87: 0x10000000 +=======================+ --
88: |周辺デバイス | D RW-
89: |(未使用領域含む) |
90: 0x30000000 +-----------------------+
91: |RAM (64MB) | C RWX
92: |(未使用領域含む) |
93: 0x40000000 +-----------------------+
94: |周辺デバイス | D RW-
95: |(未使用領域含む) | 物理アドレス
96: 0x70000000 +-----------------------+ -- 0x00000000
97: |ROM (32MB) | C R-X | NOR Flash を写像(*1)
98: 0x72000000 +-----------------------+ -- 0x02000000
99: |(予約) |
100: 0x80000000 +=======================+ --
101: |プログラムマップ用 | ↑
102: 0x90000000 +-----------------------+ | 仮想メモリー (予約)
103: |メモリーマップ用 | ↓
104: 0xa0000000 +=======================+ --
105: |内蔵 SRAM (128KB) | N RWX
106: |(未使用領域含む) |
107: 0xb0000000 +-----------------------+
108: |辺デバイス | D RW-
109: |(未使用領域含む) |
110: 0xd0000000 +=======================+ --
111: |共有メモリー空間 | | 仮想メモリー (予約)
112: 0xf0000000 +=======================+ --
113: |内蔵 Boot ROM | N R--
114: |(未使用領域含む) |
115: 0xffffffff +-----------------------+
116:
117: モード
118: メモリータイプ/キャッシュ属性
119: C キャッシュ ON Normal memory / Write-back cache, Write allocate
120: N キャッシュ OFF Normal memory / Non-cacheable
121: D デバイス Device memory / Non-cacheable
122:
123: アクセス属性 ( - はその属性がオフ)
124: R リード可
125: W ライト可
126: X プログラム実行可
127:
128: ・仮想メモリーとなっている領域は現在未使用であり、予約されている。
129: それ以外の領域は、論理アドレス=物理アドレスとしてマッピングし、動的に
130: 変化しない。
131:
132: (*1) ただし、タスク固有空間に隠れてしまう NOR Flash の領域は、論理
133: アドレス=物理アドレスとはならず、上記メモリーマップのように移
134: 動してマッピングする。このマッピングは動的に変化しない。
135:
136: 本書中のアドレスは、特に記述がない限り論理アドレスで表記されている。
137:
138: ・仮想メモリーの領域を除く他の領域は、起動時(初期化時)に T-Monitor によ
139: りマッピングを行い、MMU およびキャッシュをイネーブルする。
140: 未使用の領域および仮想メモリーの領域はマップせず、アクセス不可とする。
141: それ以外の領域は、上記の図に示したモードのように設定する。
142: これらのマッピングは、セクション(1MB単位)で行う。なお、ドメインはすべ
143: て 0 とする。ユーザーレベルからのアクセスはすべて不可とする。
144:
145: ・内蔵 SRAM および内蔵 Boot ROM は、システム起動時(ブート時)に使用される
146: が、システム起動後は使用されず、OS による管理もされない。
147: システム起動後、内蔵 SRAM は、任意の用途に使用可能である。
148:
149: (2) ROM 詳細
150:
151: 0x70000000 +-----------------------+
152: |例外分岐処理 |
153: |T-Monitor |
154: 0x70020000 +-----------------------+
155: |ROM 情報 |
156: 0x70020080 +-----------------------+
157: |(予約) |
158: 0x70030000 +-----------------------+
159: |ROM ディスク | 初期状態では割り当てなし
160: 0x70030000 +-----------------------+
161: |T-Kernel |
162: +-----------------------+
163: |(ユーザーエリア) |
164: 0x72000000 +-----------------------+
165:
166: ・ROM ディスクの領域は、ROM 情報の設定により変更可能である。
167:
168: (3) RAM 詳細
169:
170: 0x30000000 +-----------------------+
171: |第1レベル |
172: |ページテーブル |
173: 0x30004000 +-----------------------+
174: |例外ベクターテーブル |
175: 0x30004400 +-----------------------+
176: |システム共有情報 |
177: 0x30004440 +-----------------------+
178: |T-Monitor |
179: |データ/スタック |
180: 0x30006000 +-----------------------+ ← RAM_TOP
181: |OS 用 |
182: 0x34000000 +-----------------------+ ← RAM_END
183:
184: ・システム起動時に T-Monitor により次のように設定され、以後変更されない
185: (変更してはならない)。
186:
187: VBAR (CP15.c12.0.c0.0) = 0x70000000 ベクターベースアドレスレジスタ
188: TTBR1 (CP15.c2.0.c0.1) = 0x30000009 変換テーブルベースレジスタ1
189: TTBCR (CP15.c2.0.c0.2) = 0x00000004 変換テーブルベース制御レジスタ
190:
191: これらの設定されるレジスタはセキュア状態のレジスタであり、非セキュア状
192: 態のレジスタは設定されない。また、モニターモードのベクターベースアドレ
193: スレジスタである MVBAR(CP15.c12.0.c0.1) も設定されない。
194:
195: ・RAM_TOP/RAM_END は T-Monitor が管理し、システム共有情報に設定する。
196: RAM_TOP〜RAM_END の間の領域は、OS が管理する。OS はこれらのアドレスを
197: システム共有情報から取得する。
198:
199: 2.4 例外ベクターテーブル
200:
201: ベクター番号
202: 0x30004000 +-----------------------+
203: |デフォルトハンドラ | 0
204: |未定義命令 | 1
205: |プリフェッチアボート | 2
206: |データアボート | 3
207: 0x30004010 +-----------------------+
208: |スーパーバイザ SVC 4 | 4
209: |コール : | |
210: | SVC 28 | 28
211: 0x30004074 +-----------------------+
212: |デバッグアボート 命令| 29
213: | データ| 30
214: 0x3000407c +-----------------------+
215: |高速割込 FIQ | 31
216: 0x30004080 +-----------------------+
217: |割込 IRQ 0 | 32
218: | : | |
219: | IRQ 95 | 127
220: 0x30004200 +-----------------------+
221: |GPIO 割込 port 0 | 128
222: | : | |
223: | port 127| 255
224: 0x30004400 +-----------------------+
225:
226: ・デフォルトハンドラは、ハンドラが登録されていない例外・割込が発生した場
227: 合に呼び出されるハンドラ。NULL を未登録とする。
228: ・ベクター番号は、tk_def_int() の割込定義番号(dintno)として使用する。
229: ・ベクター番号は、SVC 命令の番号(イミディエート値)として使用する。
230: ・IRQ 0〜95 は、割込コントローラ(AINT)の INT 0〜95 に対応する。
231:
232: 2.5 ROM 情報
233:
234: typedef struct {
235: FP kernel; /* OS 起動アドレス */
236: UB *sysconf; /* SYSCONF 先頭 */
237: UB *devconf; /* DEVCONF 先頭 */
238: void *userarea; /* RAM ユーザーエリア先頭 */
239: FP userinit; /* ユーザー初期化プログラムアドレス */
240: FP resetinit; /* リセット初期化プログラムアドレス */
241: VW rsv[10]; /* 予約 (常に0) */
242: UW rd_type; /* ROM ディスク種別 */
243: UW rd_blksz; /* ROM ディスクブロックサイズ */
244: UW rd_saddr; /* ROM ディスク開始アドレス */
245: UW rd_eaddr; /* ROM ディスク終了アドレス */
246: VW rsv2[12]; /* 予約 (常に0) */
247: } RomInfo;
248:
249: kernel T-Kernel の起動アドレスを指定する。
250: T-Monitor はこのアドレスへジャンプして OS を起動する。
251: T-Kernel を ROM に格納していない場合は NULL を指定する。
252:
253: sysconf SYSCONF を格納した ROM のアドレスを指定する。
254: ROM に格納していない場合は NULL を指定する。
255:
256: devconf DEVCONF を格納した ROM のアドレスを指定する。
257: ROM に格納していない場合は NULL を指定する。
258:
259: userarea RAM の内、OS の管理から外すユーザーエリアの先頭アドレス
260: を指定する。通常は RAM 用予約領域の終端である 0x40000000
261: を指定する。
262: このアドレスと実際に RAM が実装されている領域の終端(上位)
263: アドレスの内のいずれか下位側のアドレスが RAM_END となる。
264:
265: userinit ユーザー作成の初期化プログラムのエントリーアドレスを指定
266: する。
267: OS 起動後、ここへ登録されたプログラムを実行する。
268: NULL を指定した場合は、ユーザー初期化プログラムは実行し
269: ない。
270: 一般的にはユーザー初期化プログラムを使用する必要はないた
271: め、NULL を指定する。
272:
273: resetinit ユーザー作成のリセット初期化プログラムのエントリーアドレ
274: スを指定する。
275: リセット処理後、ここへ登録されたプログラムを実行する。
276: NULL を指定した場合は、リセット初期化プログラムは実行し
277: ない。
278: 拡張ボードなどのハードウェア初期化処理が OS 起動以前に必
279: 要な場合に指定する。
280:
281: rd_xxxx では、ROM 上に置かれた ROM ディスクに関する指定を行う。ROM ディ
282: スクが存在しないときは、すべて 0 とする。
283:
284: rd_type ディスクタイプ (1 : ROM ディスク (書き込み不可))
285: rd_blksz ディスクブロックサイズ (通常は 512)
286: rd_saddr ROM ディスク領域の開始アドレス
287: rd_eaddr ROM ディスク領域の終了アドレス(+1)
288:
289: 2.6 システム共有情報
290:
291: typedef struct {
292: (*2) void *ramtop; /* RAM 空き領域先頭 (RAM_TOP) */
293: (*2) void *ramend; /* RAM 空き領域終端(+1) (RAM_END) */
294: UB *sysconf; /* SYSCONF 先頭 */
295: UB *devconf; /* DEVCONF 先頭 */
296: W taskindp; /* タスク独立部フラグ */
297: UW taskmode; /* タスクモードフラグ */
298: VW osrsv[4]; /* OS 使用 */
299: VW rsv[6]; /* 予約 */
300: } SysCommonInfo;
301:
302: (*2) は、T-Monitor で設定する情報。
303:
304: taskindp T-Kernel/OS によってタスク独立部フラグとして使用される。
305: = 0 : タスク部
306: > 0 : タスク独立部
307:
308: taskmode T-Kernel/OS によってタスクモードフラグとして使用される。
309:
310: 31 18 17 16 15 2 1 0
311: +---------+-----+---------+-----+
312: | 予約(0) | PPL | 予約(0) | CPL |
313: +---------+-----+---------+-----+
314: CPL 現在の保護レベル
315: PPL 一つ前の保護レベル
316:
317: (1) T-Monitor
318:
319: システム起動時およびブート開始時に、システム共有情報を初期化する。
320:
321: ramtop,ramend RAM の空き領域の先頭と終端のアドレスを設定する。ramend -
322: ramtop が空き領域のサイズとなる。
323:
324: これら以外のシステム共有情報はすべて0クリアする。
325:
326: (2) T-Kernel 起動処理
327:
328: 起動処理の最初に下記のように設定する。
329:
330: sysconf ROM 情報から取得した SYSCONF の先頭アドレス
331: devconf ROM 情報から取得した DEVCONF の先頭アドレス
332: ramtop T-Kernel のデータ領域で消費した領域を除く RAM の先頭アドレス
333:
334: 2.7 システム構成定義(SYSCONF)
335:
336: 各例外モード用のスタックサイズ(バイト数)を SYSCONF で指定する。
337: これらの例外モード用スタックは、通常はハンドラの入り口と出口においてのみ
338: 使用するため、大きな容量は必要とされない。
339:
340: 標準設定値
341: AbtStkSz 64 # アボート(MMU)
342: UndStkSz 64 # 未定義命令例外
343: IrqStkSz 512 # 割込(IRQ)
344: FiqStkSz 128 # 高速割込(FIQ)
345:
346: これらのスタックは OS によって割り当てられる。スーパーバイザー(SVC)スタ
347: ックは、システムスタックとなるため、ここでは指定しない。
348:
349: T-Monitor ではこれらのスタックは使用しない。T-Monitor 内の専用スタックを
350: 使用する。
351:
352: T-Monitor は、起動時(初期化時)に各例外モードのスタックポインタ R13 に、
353: 例外分岐処理で使用される最小限のサイズ(4ワード)分のスタックを設定する。
354: これらは、OS が起動するまでの間のみ使用される。
355:
356: 2.8 スーパーバイザーコールの割り当て
357:
358: SVC 4 T-Monitor サービスコール (T-Monitor)
359: SVC 5 予備
360: SVC 6 T-Kernel システムコール・拡張 SVC (T-Kernel)
361: SVC 7 tk_ret_int() システムコール (T-Kernel)
362: SVC 8 タスクディスパッチャ (T-Kernel)
363: SVC 9 デバッガサポート機能 (T-Kernel)
364: SVC 10 タスク例外からの復帰 (T-Kernel)
365: SVC 11 プロセス強制終了要求 (Extension)
366: SVC 12〜27 予備
367:
368: 2.9 保護レベル
369:
370: 保護レベル プロセッサモード
371: 0 SVC:スーパーバイザーモード、および USR,SYS 以外のすべて
372: のモード
373: 1 SYS:システムモード
374: 2 SYS:システムモード
375: 3 USR:ユーザーモード
376:
377: システムモード(SYS)の時、保護レベル 1〜2 の区別は実質的にはない。
378: また、MMU によるメモリー保護は、特権とユーザーの2レベルであるため、保護
379: レベル 0〜2 はすべて特権モードとなり、MMU による保護に差異はない。
380:
381: 2.10 スタック
382:
383: (1) ユーザースタック/システムスタック
384:
385: ユーザーモード(USR)およびシステムモード(SYS)のスタックをユーザースタック
386: とし、スーパーバイザーモード(SVC)のスタックをシステムスタックとする。
387:
388: ユーザースタック R13_usr
389: システムスタック R13_svc
390:
391: (2) 割込スタック
392:
393: ユーザースタック/システムスタックとは別に、タスクと独立した割込スタック
394: がある。スーパーバイザーモード(SVC)を除くすべての例外モードのスタックを
395: 割込スタックとする。これらには、それぞれ独立したスタック領域が割り当てら
396: れる。
397:
398: 割込スタック R13_abt, R13_und, R13_irq, R13_fiq
399:
400: 2.11 例外・割込ハンドラ
401:
402: ベクターテーブルを参照して各々のハンドラへジャンプするための、例外分岐処
403: 理ルーチンを用意する。高速割込(FIQ)の場合を除き、この分岐ルーチンでは、
404: レジスタやスタックに情報を設定してから、各ハンドラへジャンプする。設定さ
405: れる内容は、各例外ごとに異なる。ただし、ip (R12) レジスタには、すべての
406: 例外に共通してベクターテーブルアドレスが設定される。このベクターテーブル
407: アドレスによって、発生した例外のベクター番号を知ることができる。
408:
409: (ip - 0x30004000) / 4 = ベクター番号
410:
411: デフォルトハンドラへジャンプする場合、ip はデフォルトハンドラのベクター
412: テーブルアドレスではなく、発生した例外のベクターテーブルアドレスとなる。
413:
414: 例外ハンドラへは、割込禁止状態のまま(CPSR.I,F,A は例外発生直後の状態のま
415: ま)でジャンプする。
416: また、BX 命令によりハンドラへジャンプするので、ベクターテーブルへ設定す
417: るハンドラアドレスの最下位ビットが 1 の場合は Thumb モードへ切り替わる。
418: そうでなければ、ARM モードのままでジャンプする。
419:
420: 分岐ルーチンでは、分岐処理のためにいくつかのレジスタを使用する。それらの
421: レジスタは、下記に示すようにスタックへ保存される。分岐ルーチンでは、これ
422: らのレジスタ以外は保存しないので、その他のレジスタは各ハンドラで必要に応
423: じて保存する必要がある。また、ハンドラから戻るときには、分岐ルーチンで保
424: 存したレジスタを含めて復帰する必要がある。
425:
426: (1) 高速割込(FIQ)
427:
428: FIQ の割込ベクターに設定されたハンドラを無条件に呼び出す。
429: 要因ごとの独立したベクターはなく、すべて同じハンドラを呼び出す。
430: デフォルトハンドラの呼出もない。したがって、FIQ の割込を使用する場合は、
431: 必ずハンドラを定義しておかなければならない。
432:
433: ハンドラ呼出時のレジスタの保存等は一切行われない。
434: ハンドラの呼出処理において R12_fiq レジスタを使用するため、R12_fiq レジ
435: スタは破壊される。
436:
437: ハンドラ呼出時のプロセッサ状態
438: CPSR.F = 1 高速割込禁止
439: CPSR.I = 1 割込禁止
440: CPSR.A = 1 アボート例外禁止
441: CPSR.M = 17 FIQ:高速割込モード
442:
443: (2) 割込(IRQ)
444:
445: 割込コントローラ(AINT)の ACPU 割込マスク・ステータス・レジスタ(IT0_MST0,1,
446: 2)によって取得した割込要因から割込優先度を判定し、最も優先度の高い割込の
447: ハンドラへ分岐してハンドラを呼び出す。
448: 割込優先度は割込要因番号(INT 0〜95)の降順で、INT 95 (IRQ95) が最高優先度、
449: INT 0 (IRQ0) が最低優先度となる。
450: 割込要因がないときは、INT 95 (IRQ95) のハンドラを呼び出す。
451:
452: GPIO 割込(下記)の場合は、更に GPIO ポートからの割込要因によって分岐する。
453:
454: IRQ26 GIO6 Interrupt (GPIO port 96〜111)
455: IRQ27 GIO7 Interrupt (GPIO port 112〜127)
456: IRQ50 GIO0 Interrupt (GPIO port 0〜 15)
457: IRQ51 GIO1 Interrupt (GPIO port 16〜 31)
458: IRQ52 GIO2 Interrupt (GPIO port 32〜 47)
459: IRQ53 GIO3 Interrupt (GPIO port 48〜 63)
460: IRQ79 GIO4 Interrupt (GPIO port 64〜 79)
461: IRQ80 GIO5 Interrupt (GPIO port 80〜 95)
462:
463: 入力ポート割込マスカブル・ステータス・レジスタ(GIO_MST)によって取得した
464: 割込要因から割込優先度を判定し、最も優先度の高い割込のハンドラへ分岐して
465: ハンドラを呼び出す。
466: 割込優先度は入力ポート番号(port 0〜127)の降順で、port 127 が最高優先度、
467: port 0 が最低優先度となる。GPIO 割込は上記のように、16本ずつのグループに
468: 分かれているため、各グループ内で優先度判定される。
469: 割込要因がないときは、IRQ95 のハンドラを呼び出す。
470: なお、GPIO の各ポートを割込入力として使用するか否かは、GPIO の設定による。
471:
472: ハンドラ呼出時のスタック
473: +---------------+
474: sp -> |R3 |
475: |R12=ip |
476: |R14=lr | <- 割込からの復帰アドレス
477: |SPSR |
478: +---------------+
479:
480: ハンドラ呼出時のレジスタ
481: ip = ベクターテーブルアドレス
482: lr, r3 = 不定
483:
484: ハンドラ呼出時のプロセッサ状態
485: CPSR.F = ? 割り込まれた時の状態のまま
486: CPSR.I = 1 割込禁止
487: CPSR.A = 1 アボート例外禁止
488: CPSR.M = 18 IRQ:割込モード
489:
490: (3) その他の例外(SVC,ABT,UND)
491:
492: ハンドラ呼出時のスタック
493: +---------------+
494: sp -> |R12=ip |
495: |R14=lr | <- 復帰アドレス
496: |SPSR |
497: +---------------+
498:
499: 復帰アドレス
500: SVC の時 SVC 命令の次の命令への復帰アドレス
501: ABT の時 アボートした命令への復帰アドレス
502: UND の時 未定義命令の次の命令への復帰アドレス
503:
504: ハンドラ呼出時のレジスタ
505: ip = ベクターテーブルアドレス
506: lr = 不定
507:
508: ハンドラ呼出時のプロセッサ状態
509: CPSR.F = ? 例外発生時の状態のまま
510: CPSR.I = 1 割込禁止
511: CPSR.A = ? SVC,UND: 例外発生時の状態のまま
512: 1 ABT: アボート例外禁止
513: CPSR.M = 19 SVC:スーパーバイザーモード
514: 23 ABT:アボートモード
515: 27 UND:未定義命令例外モード
516:
517: (a) アボート例外(ABT)
518:
519: プリフェッチアボートおよびデータアボートでは、フォルトステータスレジスタ
520: (IFSR,DFSR)によりデバッグイベントが示されている場合は、デバッグアボート
521: (命令またはデータ)ハンドラを呼び出す。
522: それ以外の場合は、プリフェッチアボートまたはデータアボートハンドラを呼び
523: 出す。
524:
525: 2.12 システムコール
526:
527: レジスタの保存規則や引数の受け渡しは、C の関数呼出の形式に準拠する。
528: C 言語における、基本的なレジスタの割り当て規則は次の通り。
529:
530: R0〜R3, R12=ip テンポラリレジスタ
531: R4〜R10 パーマネントレジスタ
532: R11 = fp フレームポインタ
533: R13 = sp スタックポインタ
534: R14 = lr リンクレジスタ(関数戻りアドレス)
535: R15 = pc プログラムカウンタ
536:
537: 引数 R0〜R3
538: 戻り値 R0
539:
540: テンポラリレジスタが関数の呼出によって破壊される。それ以外のレジスタは保
541: 存される。
542: スタックは FD(Full Descending) 方式。
543:
544: USR:ユーザーモード、SYS:システムモード以外のモードで SVC 命令を実行する
545: 場合、SVC 命令の実行により R14_svc レジスタが破壊されるので、あらかじめ
546: R14_svc を保存しなければならない。
547: 原則として、次のモードでのみ SVC 命令を使用できる。
548:
549: USR:ユーザーモード
550: SYS:システムモード
551: SVC:スーパーバイザーモード
552:
553: このとき、SVC 命令は次のように実行する必要がある。
554:
555: stmfd sp!, {lr}
556: svc #
557: ldmfd sp!, {lr}
558:
559: USR, SYS モードでは、lr の保存は必ずしも必要ないが、モードに関係なく同じ
560: 手順で呼び出すために、上記の手順を標準とする。
561:
562: USR, SYS, SVC モード以外で SVC 命令を使用する場合は、何らかの方法で
563: R14_svc を保存する必要がある。
564:
565: (1) T-Monitor サービスコール
566:
567: R12=ip 機能コード
568: R0 第1引数
569: R1 第2引数
570: R2 第3引数
571: R3 第4引数
572: SVC 4
573: R0 戻り値
574:
575: 引数の最大数は4となる。
576: 上記のようにレジスタに引数と機能コードを設定して、SVC 4 により呼び出す。
577:
578: (2) T-Kernel システムコール
579:
580: R12=ip 機能コード (<0)
581: R0 第1引数
582: R1 第2引数
583: R2 第3引数
584: R3 第4引数
585: R4 第5引数以降が格納された領域へのポインタ
586: 第5引数以降はスタック
587: +---------------+
588: R4 -> |第5引数 |
589: +---------------+
590: SVC 6
591: R0 戻り値
592:
593: 第4引数まではレジスタに設定し、第5引数以降はスタックに積んで、SVC 6 に
594: より呼び出す。
595: T-Kernel/DS のシステムコールも同様だが、SVC 9 を使用する。
596:
597: (3) 拡張 SVC
598:
599: R12=ip 機能コード (≧0)
600: R0 引数パケットへのポインタ
601: SVC 6
602: R0 戻り値
603:
604: 引数はすべてパケット化し、パケットの先頭アドレスを R0 レジスタに設定して、
605: SVC 6 により呼び出す。
606: パケットは通常スタックに作成するが、他の場所でもよい。引数はパケット化す
607: るため、数や型に制限はない。
608:
609: 2.13 ブート
610:
611: 起動は次の手順で行う。
612:
613: 1.T-Monitor が、ハードウエアの初期化を行う。
614: 2.T-Monitor が、例外ベクターテーブルおよびシステム共有情報を初期化する。
615: 3.T-Monitor が ROM 情報の kernel に指定された OS 起動アドレスへジャンプ
616: して制御を移し、システムを起動する。
617:
618: (1) T-Monitor のブート処理
619:
620: (a) 例外ベクターテーブルの設定
621:
622: 以下のベクターを T-Monitor 自身が処理するように設定する。これら以外は、
623: デフォルトハンドラが起動されるように NULL に設定する。
624:
625: ベクター番号
626: 0 デフォルトハンドラ
627: 4 T-Monitor サービスコール (SVC 4)
628: 29 デバッグアボート (命令)
629: 30 デバッグアボート (データ)
630: 136 アボートスイッチ (SW1) (GPIO port 8)
631:
632: 58 GIO6: GPIO 割込分岐処理 (IRQ26)
633: 59 GIO7: GPIO 割込分岐処理 (IRQ27)
634: 82 GIO0: GPIO 割込分岐処理 (IRQ50)
635: 83 GIO1: GPIO 割込分岐処理 (IRQ51)
636: 84 GIO2: GPIO 割込分岐処理 (IRQ52)
637: 85 GIO3: GPIO 割込分岐処理 (IRQ53)
638: 111 GIO4: GPIO 割込分岐処理 (IRQ79)
639: 112 GIO5: GPIO 割込分岐処理 (IRQ80)
640:
641: デフォルトハンドラは、例外情報を表示したあと、T-Monitor のプロンプトを表
642: 示してコマンド入力状態とする。
643:
644: (b) OS の起動
645:
646: ROM 情報の kernel に格納された OS 起動アドレスを参照し、そのアドレスが
647: NULL でなければ、そのアドレスへジャンプすることで OS を起動する。
648: OS 起動アドレスが NULL であれば ROM 起動は行われず、T-Monitor のコマンド
649: 入力待ち状態となる。
650:
651: OS へ制御を移すときの CPU の状態は次の通りで、T-Monitor サービスコールを
652: 使用できる状態とする。
653:
654: CPSR.I = 1 割込禁止
655: CPSR.F = 1 高速割込禁止
656: CPSR.A = 0 アボート例外許可
657: CPSR.T = 0 ARM モード
658: CPSR.M = 19 SVC:スーパーバイザーモード
659: R13_svc (sp) モニタスタック
660: R0 0 (ROM 起動であることを示す)
661: その他の汎用レジスタは不定
662:
663: キャッシュメモリー
664: ・キャッシュはオフ (SCTLR.C=0, I=0, Z=0)
665: ・キャッシュの内容はすべて無効状態
666:
667: スタックポインタ R13_svc (sp) は、T-Monitor のスタック領域(モニタスタック)
668: を指している。OS 起動処理中このモニタスタックが使用される。sp がモニタス
669: タックを指した状態で、T-Monitor サービスコールが呼び出される。
670: なお、OS 起動処理によって使用されるモニタスタックは 2KB 以内とする。
671:
672: 2.14 ユーザー初期化プログラム
673:
674: ユーザー初期化プログラムは、ユーザー作成のプログラムなどを起動/終了する
675: ための ROM に置かれたユーザー定義のルーチンである。ユーザー初期化プログ
676: ラムは、初期起動タスクから次の形式で呼び出される。
677:
678: INT userinit( INT ac, UB **av )
679:
680: ac = 0 起動時呼出
681: = -1 終了時呼出
682:
683: 戻値 1 usermain を起動
684: 0 システム終了(電源オフ)
685: -1 リセット(再起動)
686:
687: システム起動時に ac = 0 で呼び出され、システム終了時に ac = -1 で呼び
688: 出される。終了時の呼出(ac = -1)では、戻値は無視される。
689: 処理の概略は次のようになる。
690:
691: fin = userinit(0, NULL);
692: if ( fin > 0 ){
693: fin = usermain();
694: }
695: userinit(-1, NULL);
696:
697: ユーザー初期化プログラムは、初期起動タスクのコンテキストで実行される。
698: タスク優先度は 138 である。また、ユーザー初期化プログラムでのスタックの
699: 消費は 4KB 以内とする。
700:
701: ユーザープログラムの起動処理を行った後は、2種類の選択がある。
702: (A) ユーザープログラムが終了するまで待った後、userinit() からリターン
703: する。
704: (B) ユーザープログラムの終了を待たずに userinit() からリターンする。
705:
706: いずれの場合も、userinit() からの戻り値によって、その後の処理を選択できる。
707:
708: 2.15 リセット初期化プログラム
709:
710: リセット初期化プログラムは、拡張ボードなどのハードウェアの初期化処理を、
711: リセット直後に行うための ROM に置かれたユーザー定義のルーチンである。リ
712: セット初期化プログラムは、T-Monitor のリセット処理の最後に次の形式で呼び
713: 出される。
714:
715: void resetinit( void )
716:
717: リセット初期化プログラムでのスタックの消費は 2KB 以内とする。
718:
719: 2.16 例外・割込ハンドラのエントリールーチン
720:
721: ソースプログラム中の以下のファイルを参照のこと。
722:
723: monitor/hwdepend/tef_em1d/src/eitent.S
724: include/tk/sysdepend/tef_em1d/sysdef_depend.h
725: include/tk/sysdepend/tef_em1d/asm_depend.h
726:
727: 3. T-Monitor 実装仕様
728:
729: 3.1 Register コマンド
730:
731: Register コマンドでは、以下のレジスタに対応する。
732:
733: (a) 汎用レジスタ (G)
734:
735: R0, R1, R2, R3, R4, R5, R6, R7,
736: R8, R9, R10/SL, R11/FP, R12/IP, R13/SP, R14/LR, R15/PC
737: R8_USR, R9_USR, R10_USR, R11_USR, R12_USR, R13_USR, R14_USR
738: R8_FIQ, R9_FIQ, R10_FIQ, R11_FIQ, R12_FIQ, R13_FIQ, R14_FIQ
739: R13_IRQ, R14_IRQ
740: R13_SVC, R14_SVC
741: R13_ABT, R14_ABT
742: R13_UND, R14_UND
743:
744: ※モニタモード用レジスタ(R13_MON, R14_MON)への対応は行わない
745:
746: (b) 制御/システムレジスタ (C)
747:
748: CPSR, SPSR
749: SPSR_FIQ, SPSR_IRQ, SPSR_SVC, SPSR_ABT, SPSR_UND
750: SCTLR, TTBR0, TTBR1, TTBCR, DACR, DFSR, IFSR, DFAR, IFAR, CTXIDR
751:
752: ※以下のシステム制御コプロセッサレジスタ (CP15.CRn.opc1.CRm.opc2)
753: に対応する。
754:
755: SCTLR (CP15.c1.0.c0.0) システム制御レジスタ
756: TTBR0 (CP15.c2.0.c0.0) 変換テーブルベースレジスタ0
757: TTBR1 (CP15.c2.0.c0.1) 変換テーブルベースレジスタ1
758: TTBCR (CP15.c2.0.c0.2) 変換テーブルベース制御レジスタ
759: DACR (CP15.c3.0.c0.0) ドメインアクセス制御レジスタ
760: DFSR (CP15.c5.0.c0.0) データフォルトステータスレジスタ
761: IFSR (CP15.c5.0.c0.1) 命令フォルトステータスレジスタ
762: DFAR (CP15.c6.0.c0.0) データフォルトアドレスレジスタ
763: IFAR (CP15.c6.0.c0.2) 命令フォルトアドレスレジスタ
764: CTXIDR (CP15.c13.0.c0.1) コンテキスト ID レジスタ
765:
766: ※モニタモード用レジスタ(SPSR_MON)への対応は行わない
767:
768: 3.2 Break Point コマンド
769:
770: 以下のブレーク属性に対応する。
771:
772: S : ソフトウェアブレークポイント
773: <ブレークアドレス>の命令を実行する直前にブレーク。
774:
775: ・ソフトウェアブレークポイントは最大 8 点まで
776: ・奇数アドレスへのブレークポイント設定は Thumb 命令とみなす。なお、Thumb-2
777: 命令への対応は行わない。
778: ・ICE を接続した場合は、ブレークポイントの動作は保証しない
779:
780: 3.3 Trace(Step/Next) コマンド
781:
782: トレース実行中はすべてのブレークポイントは無効となる。
783: トレース実行中に SVC 命令があった場合は、SVC 先はトレースしない。
784: 次に実行する命令の逆アセンブルは行わず、メモリ内容のダンプを表示する。
785:
786: 3.4 Back Trace, Disassemble コマンド
787:
788: 対応しない。
789:
790: 3.5 Disk コマンド
791:
792: ディスクデバイスには対応しないため、使用できない。
793:
794: 3.6 Kill コマンド
795:
796: モニタを終了して、SVC 11 を実行する。
797: SVC 11 のハンドラが設定されていないときは何もしない。
798:
799: ・SVC 11 は T-Kernel Extension で使用 (ハンドラを設定) することを前提とし
800: ている。
801:
802: 3.7 WriteROM コマンド
803:
804: 以下の WriteROM コマンドにより、RAM 上の内容を NOR Flash ROM に書き込む
805: ことができる。
806:
807: WriteROM(WROM) rom_addr, data_ram_addr, block_count : Write Flash ROM
808: blocks
809: rom_addr : 0x70000000 - 0x71FE0000
810: data_ram_addr : 0x30020000 - 0x33FE0000
811: block_count : 1 - 0x100 (1 block = 128KB)
812:
813: ・書き込みは、128 KB ブロック単位で行い、Flash ROM アドレスは 128 KB 境界
814: でなくてはいけない。
815: ・T-Monitor 領域(0x70000000 〜 0x7001FFFF)を指定すると、確認のメッセージを
816: 表示し、書き換え後はリセット起動となる。
817:
818: 3.8 FlashLoad コマンド
819:
820: 以下の FlashLoad コマンドにより、S-Format データをロードして、NOR Flash
821: ROM に書き込むことができる。
822:
823: FlashLoad(FLLO) [attr] : Load S-Format Data & Write Flash ROM
824: attr: X Use XMODEM protocol
825: E Fill write blocks with 0xFF
826: Default : Overwrite original Flash ROM Image
827:
828: ・X を指定した場合、S-Format データのロードは、XMODEM プロトコルで行い、指
829: 定しない場合は、無手順で行う。
830: ・E を指定した場合、128 KB ブロック内のロードしなかった部分には、0xFF が書
831: き込まれ、指定しない場合は、もとの内容のままとなる。
832:
833: 3.9 DIP スイッチ
834:
835: OFF ON
836: --------------------------------------------------------------------
837: SW-1 BOOTSEL0 OFF -
838: SW-2 BOOTSEL1 OFF -
839: SW-3 BOOTSEL2 OFF -
840: SW-4 起動選択 自動ブート モニタ起動
841:
842: SW-4 は、OFF で自動ブート (OS 起動)、 ON でブートせずにモニタ起動となる。
843:
844: 他のスイッチの設定は、上記の設定に従うこと。
845:
846: 3.10 起動対象となるデバイスの検索順序
847:
848: DIP スイッチの SW-4 が ON の状態で起動した場合は、T-Monitor を起動する。
849: SW-4 が OFF の場合は、ROM上のプログラム (RomInfo.kernel) が設定されてい
850: る場合はこれを起動する。設定されていない場合は T-Monitor を起動する。
851:
852: 3.11 コンソール
853:
854: T-Monitor のコンソールとして使用するシリアルポートは、UART0 を使用する。
855: 通信仕様は以下の通りとする。
856:
857: 通信速度 115,200 bps
858: データ長 8 bit
859: ストップビット 1 bit
860: パリティ なし
861: フロー制御 XON/XOFF
862:
863: 3.12 T-Monitor のサービスコール
864:
865: レジスタの保存規則や引数の受け渡しは、C の関数呼び出し形式に準拠する。引
866: 数の最大数は 4 となる。
867:
868: R12/IP に機能コードを設定して SVC 4 により T-Monitor のサービスコールを
869: 呼び出す。
870:
871: サービスコールの実行中は全ての割り込みはマスクされる。また、スタックは T
872: -Monitor 内の専用スタック領域を使用する。
873:
874: R12/IP 機能コード
875: R0 第1引数
876: R1 第2引数
877: R2 第3引数
878: R3 第4引数
879: SVC 4
880: R0 戻り値
881:
882: 機能コード
883: 0 Enter T-Monitor モニタへ入る
884: 1 Get Character コンソールから 1 文字入力
885: 2 Put Character コンソールへ 1 文字出力
886: 3 Get Line コンソールから 1 行入力
887: 4 Put String コンソールへ文字列出力
888: 5 Execute Command モニタコマンドの実行
889: 6 (予約)
890: 7 (予約)
891: 8 (予約)
892: 9 System Exit システム終了
893: 255 Extension SVC 拡張サービス機能
894:
895: 3.13 T-Monitor の拡張サービスコール
896:
897: tm_extsvc(INT fno, INT p1, INT p2, INT p3)
898:
899: fno 機能
900: -----------------------------------------------------------------
901: 0x00 デバッグポートの通信速度の取り出し
902: p1〜p3: 未使用
903: リターン値: 115200
904:
905: 0x01 ROM ディスク情報の取り出し
906: p1: ROM ディスク情報ポインタを格納する領域
907: p2〜p3: 未使用
908: リターン値: 0: OK, < 0: エラー
909:
910: p1 には、以下の ROM 上のアドレスが格納される。
911:
912: p1 --> UW rd_type; /* ROM ディスク種別 */
913: UW rd_blksz; /* ROM ディスクブロックサイズ */
914: UW rd_saddr; /* ROM ディスク開始アドレス */
915: UW rd_eaddr; /* ROM ディスク終了アドレス */
916:
917: 0x04 (予約)
918:
919: 0x10 DIP SW 状態の取り出し
920: p1〜p3: 未使用
921: リターン値: bit 0〜4 : 不定
922: bit 5 : SW-4 起動選択 (0:OFF 1:ON)
923: bit 6〜31 : 不定
924:
925: 0x11 (予約)
926:
927: 0x20 NOR Flash ROM への書き込み
928: p1: Flash ROM アドレス(書き込み先)
929: 0x7###0000, ### = 000 - 1FE
930: p2: RAM アドレス(書き込みデータ)
931: 0x3###0000, ### = 002 - 3FE
932: p3: 書き込みブロック数 (1ブロック = 128 KB)
933: 0x01 〜 0x100
934: リターン値: 0: OK、< 0 エラー
935:
936: ・書き込みは、128 KB ブロック単位で行い、Flash ROM アドレスは
937: 128 KB 境界でなくてはいけない。
938: ・T-Monitor 領域(0x70000000 〜 0x7001FFFF)を指定すると、確認のメ
939: ッセージを表示し、書き換え後はリセット起動となる。
940:
941: 3.14 各種クロックの初期化
942:
943: T-Monitor は起動時に、以下の EM1-D512 の ASMU レジスタを設定する。
944:
945: レジスタ 設定値
946: AUTO_FRQ_CHANGE 0x00000000
947: PLL1CTRL0 0x00000079
948: PLL1CTRL1 0x00000000
949: PLL2CTRL0 0x00000061
950: PLL2CTRL1 0x00000000
951: CLK_MODE_SEL 0x00000001
952: NORMALA_DIV 0x00244200
953: DIVU70SCLK 0x00000000
954: DIVU71SCLK 0x00000000
955: DIVU72SCLK 0x00000000
956: DIVLCDLCLK 0x00000004
957: DIVIICSCLK 0x00530053
958: DIVTIMTIN 0x00000003
959: DIVSP0SCLK 0x00000074
960: TI0TIN_SEL 0x00000000
961: TI1TIN_SEL 0x00000000
962: TI2TIN_SEL 0x00000000
963: TI3TIN_SEL 0x00000000
964: TIGnTIN_SEL 0x00000000
965: AHBCLKCTRL0 0x00000000
966: AHBCLKCTRL1 0x00000000
967: APBCLKCTRL0 0x00000000
968: APBCLKCTRL1 0x00000000
969: CLKCTRL 0x00000000
970: GCLKCTRL0ENA 0xffffffff (GCLKCTRL0 設定後は 0x00000000)
971: GCLKCTRL0 0xffffffff
972: GCLKCTRL1ENA 0xffffffff (GCLKCTRL1 設定後は 0x00000000)
973: GCLKCTRL1 0xffffffff
974: GCLKCTRL2ENA 0xffffffff (GCLKCTRL2 設定後は 0x00000000)
975: GCLKCTRL2 0xffffffff
976: GCLKCTRL3ENA 0xffffffff (GCLKCTRL3 設定後は 0x00000000)
977: GCLKCTRL3 0xffffffff
978: RESETREQ0ENA 0xffffffff (RESETREQ0 設定後は 0x00000000)
979: RESETREQ0 0xffffffe7
980: RESETREQ1ENA 0xffffffff (RESETREQ1 設定後は 0x00000000)
981: RESETREQ1 0xffffffff
982: RESETREQ2ENA 0xffffffff (RESETREQ2 設定後は 0x00000000)
983: RESETREQ2 0xffffffff
984: RESETREQ3ENA 0xffffffff (RESETREQ3 設定後は 0x00000000)
985: RESETREQ3 0xffffffff
986:
987: これらの設定値により、各種クロックは以下の値となる。全てのモジュールに対
988: してクロックを供給し、DSP 以外の全モジュールのリセットを解除する。
989:
990: PLL1: 499.712MHz
991: ACPU: PLL1/1 499.712MHz
992: ADSP: PLL1/1 499.712MHz
993: HBUS: PLL1/3 166.571MHz
994: LBUS: PLL1/6 83.285MHz
995: FLASH: PLL1/6 83.285MHz
996: MEMC: PLL1/3 166.571MHz
997:
998: PLL2: 401.408MHz
999: LCD_LCLK: PLL2/16 25.088MHz
1000:
1001: PLL3: 229.376MHz
1002: U70_SCLK: PLL3/1 229.376MHz
1003: U71_SCLK: PLL3/1 229.376MHz
1004: U72_SCLK: PLL3/1 229.376MHz
1005: Txx_TIN: PLL3/8 28.672MHz
1006: IIC_SCLK: PLL3/48 4.779MHz
1007: SP0_SCLK: PLL3/128 1.792MHz
1008:
1009: クロックモードは常に Normal Mode A で動作し、他のモードへの対応は行わな
1010: い。周波数自動切換機能は使用せず、この機能には対応しない。
1011:
1012: デバイスドライバ等は必要に応じ、モジュール電源およびリセットの操作、モジ
1013: ュールの使用するクロックの分周比およびクロックゲートの設定を行う必要があ
1014: る。
1015:
1016: 3.15 ピンマルチプレクサの初期化
1017:
1018: T-Monitor は起動時に、以下の EM1-D512 のピンマルチプレクサを設定する。
1019:
1020: レジスタ 設定値
1021: CHG_L1_HOLD 0x00000000
1022: CHG_CTRL_AB0_BOOT 0x00000001
1023: CHG_PINSEL_G0 0x55400C00
1024: CHG_PINSEL_G16 0x55555555
1025: CHG_PINSEL_G32 0x54555055
1026: CHG_PINSEL_G48 0x55555555
1027: CHG_PINSEL_G64 0xffc05555
1028: CHG_PINSEL_G80 0x06556940
1029: CHG_PINSEL_G96 0x55555555
1030: CHG_PINSEL_G112 0x00000555
1031: CHG_PINSEL_SP0 0x00000000
1032: CHG_PINSEL_DTV 0x00000001
1033: CHG_PINSEL_SD0 0x00000000
1034: CHG_PINSEL_SD1 0x00000002
1035: CHG_PINSEL_IIC2 0x00000000
1036: CHG_PULL_G0 0x55055005
1037: CHG_PULL_G8 0x00000005
1038: CHG_PULL_G16 0x00000000
1039: CHG_PULL_G24 0x00000000
1040: CHG_PULL_G32 0x00550000
1041: CHG_PULL_G40 0x00050000
1042: CHG_PULL_G48 0x11111111
1043: CHG_PULL_G56 0x11111111
1044: CHG_PULL_G64 0x11111111
1045: CHG_PULL_G72 0x00000005
1046: CHG_PULL_G80 0x00400050
1047: CHG_PULL_G88 0x55000444
1048: CHG_PULL_G96 0x44444444
1049: CHG_PULL_G104 0x04044444
1050: CHG_PULL_G112 0x00000000
1051: CHG_PULL_G120 0x00000000
1052: CHG_PULL0 0x50000004
1053: CHG_PULL1 0x15110600
1054: CHG_PULL2 0x60000661
1055: CHG_PULL3 0x00000000
1056: GIO_E0_L 0x000001d9
1057: GIO_E1_L 0x00000604
1058: GIO_E0_H 0x00001030
1059: GIO_E1_H 0x00000000
1060: GIO_E0_HH 0xc0020100
1061: GIO_E1_HH 0x00040200
1062: GIO_OL_L 0x06040000
1063: GIO_OL_HH 0x02000000
1064: GIO_OH_HH 0x00040000
1065:
1066: これらにより、以下のモジュールに対応したピン設定となる。
1067:
1068: AB0(AsyncBus0)
1069: LCD
1070: SD0
1071: PM0
1072: UART0, UART1
1073: IIC
1074: USB
1075: GPIO
1076: P0 In DA9052(nIRQ)
1077: P2 Out/0 ML7037(/PDN)
1078: P3 In microSD(CD)
1079: P4 In Push-SW(SW4)
1080: P6 In Push-SW(SW3)
1081: P7 In Push-SW(SW2)
1082: P8 In Push-SW(SW1)
1083: P9 Out/0 ML7037(PDN)
1084: P10 Out/0 カメラモジュール(STBY)
1085: P36 In MKY36(/INT0)
1086: P37 In MKY36(/INT1)
1087: P44 In LAN9221(IRQ)
1088: P72 In MAX7324(/INT)
1089: P73 Out/0 LM4876(/SHUTDOWN)
1090: P81 In LAN9221(PME)
1091: P82 Out/0 LCD
1092: P94 In RTC(/TIRQ)
1093: P95 In RTC(/AIRQ)
1094:
1095: 3.16 LED の操作およびディップスイッチ状態の取得
1096:
1097: LED5〜8 の操作およびディップスイッチ SW-4 の状態を取得には、IIC2 および
1098: これに接続したポートエキスパンダ (MAX7324) を使用する。
1099:
1100: ポートエキスパンダには LED の他にフォトカプラが接続されているが、こちら
1101: は T-Monitor の操作対象とはしない。
1102:
1103: 4. T-Kernel 実装仕様
1104:
1105: 4.1 Thumb 命令セットの使用
1106:
1107: Thumb 命令セットを使用する場合は、「ARM / Thumb Interworking」にしたがっ
1108: てプログラムされている必要がある。
1109: C 言語の場合は、コンパイル時に -mthumb-interwork -mthumb オプションを指
1110: 定する。
1111:
1112: タスクやハンドラとして Thumb 命令セットで書かれたものを指定する場合、そ
1113: のアドレスの最下位ビットに 1 を設定する。ARM 命令セットの場合は 0 を設定
1114: する。これは、通常リンカが自動的に行うため、プログラマは特に意識する必要
1115: はない。
1116:
1117: 4.2 システム状態判定
1118:
1119: (1) タスク独立部 (例外・割込ハンドラ・タイムイベントハンドラ)
1120:
1121: システム共有情報(SysCommonInfo)内のフラグ taskindp を使用して判定する。
1122:
1123: taskindp = 0 タスク部
1124: taskindp > 0 タスク独立部
1125:
1126: このフラグの設定は、T-Kernel/OS によって行われる。
1127:
1128: (2) 準タスク部 (拡張 SVC ハンドラ)
1129:
1130: T-Kernel/OS 内にソフトウエア的なフラグを設けて判定する。
1131:
1132: 4.3 T-Kernel/OS で使用する例外・割込
1133:
1134: スーパーバイザーコール (SVC 命令)
1135: ・T-Kernel システムコール・拡張 SVC SVC 6
1136: ・tk_ret_int() システムコール SVC 7
1137: ・タスクディスパッチャ SVC 8
1138: ・デバッガサポート機能 SVC 9
1139: ・タスク例外からの復帰 SVC 10
1140:
1141: 割込
1142: ・TI0 タイマー割込 IRQ 54
1143:
1144: 4.4 システムコール
1145:
1146: 呼び出し側は、C 言語の関数の呼び出し形式で、インターフェースライブラリを
1147: 呼び出す。インターフェースライブラリは、下記のようになる。
1148:
1149: システムコールの呼出は、次のモードからのみ可能である。
1150:
1151: USR:ユーザーモード
1152: SYS:システムモード
1153: SVC:スーパーバイザーモード
1154:
1155: これら以外のモードからシステムコールを呼び出す場合は、SVC モードに切り替
1156: えてから呼び出すか、R14_svc を保存してから呼び出す(システムコールから戻
1157: ったあとに R14_svc を元の値に復帰する)必要がある。
1158: なお、USR モードおよび SYS モードに切り替えてはいけない。
1159:
1160: アセンブリ言語のプログラムから呼び出す場合も、C 言語と同様に関数形式によ
1161: りインターフェースライブラリを経由して呼び出すこととするが、下記のインタ
1162: ーフェースライブラリ相当のことを行い、直接 SVC 命令で呼び出してもよい。
1163: レジスタの保存規則は C 言語の規則にしたがうので、アセンブリ言語のプログ
1164: ラムから呼び出す場合も、C 言語の規則にしたがってレジスタの保存を行う必要
1165: がある。
1166:
1167: (1) T-Kernel/OS システムコール
1168:
1169: ER tk_xxx_yyy(p1, p2, p3, p4, p5)
1170:
1171: 引数は整数またはポインタで、C 言語の関数の引数渡しと同じ形式。
1172:
1173: // r0 = p1
1174: // r1 = p2
1175: // r2 = p3
1176: // r3 = p4
1177: // +---------------+
1178: // sp ->| p5 |
1179: // | : |
1180: // +---------------+
1181: tk_xxx_yyy:
1182: stmfd sp!, {r4} // r4 保存
1183: add r4, sp, #4 // r4 = スタック上のパラメータの位置
1184: stmfd sp!, {lr} // lr 保存
1185: ldr ip, =機能コード
1186: svc 6
1187: ldmfd sp!, {lr} // lr 復帰
1188: ldmfd sp!, {r4} // r4 復帰
1189: bx lr
1190:
1191: (2) 拡張 SVC
1192:
1193: INT zxxx_yyy( .... )
1194:
1195: 引数は呼出側でパケット化し、パケットの先頭アドレスを R0 レジスタに設定す
1196: る。
1197:
1198: zxxx_yyy:
1199: stmfd sp!, {r0-r3} // レジスタ上の引数をスタックに積みパケ
1200: ット化
1201: mov r0, sp // R0 = 引数パケットのアドレス
1202: stmfd sp!, {lr} // lr 保存
1203: ldr ip, =機能コード
1204: svc 6
1205: ldmfd sp!, {lr} // lr 復帰
1206: add sp, sp, #4*4 // スタックに積んだ引数を捨てる
1207: bx lr
1208:
1209: ここに示した引数のパケット化の方法は例である。引数の数や型によって適切に
1210: パケット化する必要がある。
1211:
1212: (3) T-Kernel/DS サービスコール
1213:
1214: ER td_xxx_yyy(p1, p2, p3, p4)
1215:
1216: 引数は4個以下の整数またはポインタで、C 言語の関数の引数渡しと同じ形式。
1217:
1218: // r0 = p1
1219: // r1 = p2
1220: // r2 = p3
1221: // r3 = p4
1222: td_xxx_yyy:
1223: stmfd sp!, {lr} // lr 保存
1224: ldr ip, =機能コード
1225: svc 9
1226: ldmfd sp!, {lr} // lr 復帰
1227: bx lr
1228:
1229: 4.5 例外・割込ハンドラ
1230:
1231: ER tk_def_int( UINT dintno, T_DINT *pk_dint )
1232:
1233: typedef struct t_dint {
1234: ATR intatr; /* 割込ハンドラ属性 */
1235: FP inthdr; /* 割込ハンドラアドレス */
1236: } T_DINT;
1237:
1238: dintno には、ベクターテーブルのインデックス番号(0〜255)を指定する。
1239:
1240: FIQ 高速割込は他の例外・割込とは異なる特殊な扱いとなる。後述の FIQ 高速
1241: 割込の説明を参照のこと。
1242:
1243: T-Kernel/OS では割込コントローラに対する処理は何も行わない。割込のクリア
1244: 等は、割込ハンドラが処理しなければならない。
1245:
1246: 多重割込を許可する場合、割込コントローラ(または GPIO コントローラ)の割込
1247: マスクレジスタを操作して、多重割込を許可する割込以外を禁止するように設定
1248: しなければならない。特に、自身の割込が再入しないようにする必要がある。
1249: 割込コントローラ(または GPIO コントローラ)の割込マスクを変更した場合は、
1250: 割込ハンドラから戻る前に元に戻す必要がある。
1251:
1252: 例外・割込ハンドラは、発生した例外・割込の種類に応じて、以下のプロセッサ
1253: モードの内のいずれかとなる。
1254:
1255: SVC:スーパーバイザーモード
1256: ABT:アボートモード
1257: UND:未定義命令例外モード
1258: IRQ:割込モード
1259: FIQ:高速割込モード
1260:
1261: ただし、TA_HLNG が指定されたハンドラの場合、高級言語対応ルーチンによって
1262: SVC モードへ自動的に変更される。したがって、どのタイプの例外・割込が発生
1263: しても、TA_HLNG 指定の場合にはユーザーの割込ハンドラに入った時点で SVC
1264: モードとなっている。
1265:
1266: (1) TA_HLNG の場合
1267:
1268: 例外・割込ハンドラは、次の形式となる。
1269:
1270: void inthdr( UINT dintno, void *sp )
1271:
1272: dintno 発生した例外・割込のベクターテーブルのインデックス番号
1273: なお、デフォルトハンドラの場合、デフォルトハンドラのインデックス
1274: 番号ではなく、発生した例外・割込のインデックス番号となる。
1275:
1276: sp スタックに保存された以下の情報へのポインタ
1277:
1278: +---------------+
1279: sp -> | R12=ip |
1280: | R14=lr | <- 復帰アドレス
1281: | SPSR |
1282: +---------------+
1283:
1284: 復帰アドレス
1285: IRQ の時 割込からの復帰アドレス
1286: SVC の時 SVC 命令の次の命令への復帰アドレス
1287: ABT の時 アボートした命令への復帰アドレス
1288: UND の時 未定義命令の次の命令への復帰アドレス
1289:
1290: ・例外・割込ハンドラに入ったときの CPU の状態は次のようになる。
1291:
1292: CPSR.F = ? 割込・例外発生時の状態のまま
1293: CPSR.I = 1 割込禁止
1294: CPSR.A = 1 アボート例外禁止
1295: CPSR.M = 19 SVC:スーパーバイザーモード
1296:
1297: 多重割込は禁止されている。CPSR.I を 0 とすることで、多重割込を許可するこ
1298: とはできるが、その場合割込コントローラの設定を適切に変更しておく必要があ
1299: る。
1300:
1301: ・例外・割込ハンドラからの復帰は、関数からの return で行う。
1302:
1303: ・ベクターテーブルには、T-Kernel/OS 内の高級言語対応ルーチンのアドレスが設
1304: 定され、高級言語対応ルーチンから指定されたハンドラを呼び出す。
1305:
1306: (2) TA_ASM の場合
1307:
1308: ・ベクターテーブルへ指定された例外・割込ハンドラのアドレスを直接設定する。
1309: したがって、T-Kernel/OS を経由せずに直接ハンドラが呼び出される。
1310:
1311: ・T-Kernel/OS を経由しないため、タスク独立部判定のためのフラグが更新されな
1312: い。そのため、タスク独立部として判定されないので、次のような点に注意が必
1313: 要である。
1314:
1315: ・割込を許可(CPSR.I=0 かつ A=0)すると、タスクディスパッチが発生する可能
1316: 性がある。SVC 命令によるスーパーバイザーコール例外の場合を除き、タスク
1317: ディスパッチが起きるとその後の動作が異常になる。
1318: ・システムコールを呼び出した場合、タスク部から呼び出したものとして処理さ
1319: れる。
1320:
1321: したがって、ハンドラ内でシステムコールを発行する必要がある場合や割込を許
1322: 可する場合には、必要に応じてタスク独立部判定フラグを設定しなければならな
1323: い。
1324: また、システムコールを発行するためには SVC モードに切り替えておくことが
1325: 望ましい。(前述のシステムコールの説明を参照)
1326:
1327: タスク独立部判定フラグの設定は、システム共有情報内の taskindp フラグを操
1328: 作することで行う。ただし、割込禁止状態(CPSR.I=1 かつ A=1)で行わなければ
1329: ならない。また、割込ハンドラを終了する前にフラグを必ず戻さなければならな
1330: い。
1331:
1332: taskindp++; /* タスク独立部に入る */
1333:
1334: taskindp--; /* タスク独立部を出る */
1335:
1336: 多重割込の場合などもあるため、taskindp は必ずインクリメント/デクリメン
1337: トによって設定する必要がある。taskindp = 0 のような設定を行ってはいけな
1338: い。
1339:
1340: ・例外・割込ハンドラからの復帰は、tk_ret_int() システムコールを使用するか、
1341: EIT_RETURN マクロ(またはプロセッサモードに応じた INT_RETURN, EXC_RETURN
1342: のいずれかのマクロ)を使用する。マクロを使用した場合、遅延ディスパッチは
1343: 起こらない。
1344: なお、マクロを使用する代わりに、独自にマクロに相当する処理を行ってもよい。
1345:
1346: ・tk_ret_int() システムコールは、他のシステムコールとは異なる専用のトラッ
1347: プにより呼び出す。他のシステムコールのような関数形式の呼び出しはできない。
1348:
1349: SVC 7 // tk_ret_int() 呼び出し (戻らない)
1350:
1351: tk_ret_int() を呼び出す前に、スタックを以下のような状態にしておく必要が
1352: ある。また、スタックに格納されているレジスタ以外(R0〜R11)は、すべて復帰
1353: しておく必要がある。
1354: 例外モードは、発生した例外・割込のモード(ハンドラに入ったときのモード)に
1355: 戻しておく必要がある。sp は、発生した例外・割込のモードのスタックポイン
1356: タ(R13)である。
1357:
1358: +---------------+
1359: sp -> | R14_svc |
1360: | R12=ip |
1361: | R14=lr | <- 復帰アドレス
1362: | SPSR |
1363: +---------------+
1364:
1365: 上記スタックの R14_svc には、ハンドラに入ったときの SVC モードの R14 レ
1366: ジスタの値を保存する。その他は、T-Monitor の例外分岐処理ルーチンによって
1367: 保存されたものである。
1368:
1369: 例外・割込ハンドラ以外から tk_ret_int() を呼び出した場合の動作は保証され
1370: ない。
1371:
1372: SVC モードへ切り替えるマクロ ENTER_SVC_MODE と、tk_ret_int() を呼び出す
1373: マクロ TK_RET_INT が用意されている。
1374:
1375: (3) FIQ 高速割込
1376:
1377: FIQ 高速割込ハンドラは、OS の管理外で実行される。
1378: FIQ は高速なデータ転送などの用途に使用され、OS のサポートを必要としない
1379: 用途で使用する。
1380:
1381: ・FIQ 高速割込ハンドラとして、TA_HLNG 属性を指定することはできない。
1382: ・FIQ 高速割込ハンドラの終了に、tk_ret_int() システムコールを呼び出すこ
1383: とはできない。
1384: ・FIQ 高速割込ハンドラ内では、すべてのシステムコールおよび拡張 SVC を呼
1385: び出すことはできない。
1386: ・FIQ 高速割込ハンドラ内では、IRQ 通常割込およびアボート例外を許可しては
1387: ならない。
1388:
1389: FIQ 高速割込ハンドラ以外においても、CPSR.F フラグにより FIQ 高速割込を禁
1390: 止する場合には、同時に IRQ 割込およびアボート例外も禁止する必要がある。
1391: つまり、CPSR.F=1 かつ CPSR.I=1 かつ CPSR.A=1 としなければならず、FIQ を
1392: 禁止している状態で IRQ またはアボート例外のいずれかまたは両方を許可して
1393: はいけない。また、FIQ 割込の禁止中は、すべてのシステムコールおよび拡張
1394: SVC を呼び出すことはできない。
1395:
1396: OS においても FIQ を禁止することは避けており、これにより IRQ に比べより
1397: 高速な割込応答が実現されている。高速な割込応答の代償として上記のような制
1398: 限があり、これらが守られない場合 OS が誤動作する可能性がある。
1399:
1400: 4.6 タスク
1401:
1402: ER tk_cre_tsk( T_CTSK *ctsk )
1403:
1404: typedef struct t_ctsk {
1405: void *exinf; /* 拡張情報 */
1406: ATR tskatr; /* タスク属性 */
1407: FP task; /* タスク起動アドレス */
1408: PRI itskpri; /* タスク起動時優先度 */
1409: INT stksz; /* ユーザスタックサイズ(バイト) */
1410: INT sstksz; /* システムスタックサイズ(バイト) */
1411: void *stkptr; /* ユーザースタックポインタ */
1412: void *uatb; /* タスク固有空間ページテーブル */
1413: INT lsid; /* 論理空間ID */
1414: ID resid; /* リソースID */
1415: } T_CTSK;
1416:
1417: (1) オプション指定
1418:
1419: tskatr := (TA_ASM ‖ TA_HLNG)
1420: | [TA_SSTKSZ] | [TA_USERSTACK] | [TA_TASKSPACE] | [TA_RESID]
1421: | (TA_RNG0 ‖ TA_RNG1 ‖ TA_RNG2 ‖ TA_RNG3)
1422: | [TA_FPU]
1423:
1424: ・TA_COPn は使用しない。FPU(VFP) には対応していないため、TA_FPU = 0 となる。
1425:
1426: ・lsid は、CONTEXTIDR(CP15.c13.0.c0.1)コンテキストIDレジスタに設定される。
1427: lsid の有効範囲は 0〜255 となる。
1428: uatb は、TTBR0(CP15.c2.0.c0.0)変換テーブルベースレジスタ0に設定される。
1429:
1430: (2) タスクの形式
1431:
1432: タスクは次の形式で、TA_HLNG, TA_ASM のどちらを指定しても同じで違いはない。
1433:
1434: void task( INT stacd, void *exinf )
1435:
1436: タスク起動時のレジスタの状態は下記のようになる。
1437:
1438: CPSR.F = 0 高速割込許可
1439: CPSR.I = 0 割込許可
1440: CPSR.A = 0 アボート例外許可
1441: CPSR.T,J = 0,0 ARM モード タスク起動アドレスの最下位ビットが 0 の
1442: 場合
1443: 1,0 Thumb モード タスク起動アドレスの最下位ビットが 1 の
1444: 場合
1445: CPSR.M = 16 USR:ユーザーモード TA_RNG3 指定時
1446: 31 SYS:システムモード TA_RNG1〜2 指定時
1447: 19 SVC:スーパーバイザーモード TA_RNG0 指定時
1448:
1449: R0 = stacd タスク起動パラメータ
1450: R1 = exinf タスク拡張情報
1451: R13(sp) スタックポインタ
1452:
1453: その他のレジスタは不定である。
1454:
1455: タスクの終了は、tk_ext_tsk() または tk_exd_tsk() を用いなければならない。
1456: 単に return してもタスクの終了とはならない。return した場合の動作は保証
1457: されない。
1458:
1459: 4.7 タスクのレジスタの設定/参照
1460:
1461: ER tk_set_reg( ID tskid, T_REGS *regs, T_EIT *eit, T_CREGS *cregs )
1462: ER tk_get_reg( ID tskid, T_REGS *regs, T_EIT *eit, T_CREGS *cregs )
1463:
1464: typedef struct t_regs {
1465: VW r[13]; /* 汎用レジスタ R0〜R12 */
1466: void *lr; /* リンクレジスタ R14 */
1467: } T_REGS;
1468:
1469: typedef struct t_eit {
1470: void *pc; /* プログラムカウンタ R15 */
1471: UW cpsr; /* プログラムステータスレジスタ */
1472: UW taskmode; /* タスクモードフラグ */
1473: } T_EIT;
1474:
1475: typedef struct t_cregs {
1476: void *ssp; /* システムスタックポインタ R13_svc */
1477: void *usp; /* ユーザースタックポインタ R13_usr */
1478: void *uatb; /* タスク固有空間ページテーブルのアドレ
1479: ス */
1480: UW lsid; /* タスク論理空間 ID */
1481: } T_CREGS;
1482:
1483: ・CPSR は、フラグフィールド(J,IT ビットを除く)(ビット31〜27)以外は変更でき
1484: ない。他のフィールド(ビット26〜0)への設定は無視される。
1485:
1486: ・taskmode は、システム共有情報にあるタスクモードフラグと同じ。メモリーの
1487: アクセス権情報を保持するレジスタとして扱われる。
1488:
1489: ・DORMANT 状態のタスクに対してレジスタの設定を行ったとき、R0, R1 は
1490: tk_sta_tsk() によってタスク起動パラメータ/拡張情報が設定されるため、
1491: tk_set_reg() で設定した値は捨てられることになる。
1492:
1493: 4.8 タスク例外ハンドラ
1494:
1495: タスク例外ハンドラは、レジスタの保存・復帰を行う専用のエントリールーチン
1496: を持つ必要がある。エントリールーチンには、マクロ TEXHDR_ENTRY を使用する。
1497: または、これに相当する処理を独自に行ってもよい。
1498:
1499: タスク例外ハンドラに入るときのスタックの状態
1500:
1501: +---------------+
1502: sp -> |texcd | 例外コード
1503: |PC | ハンドラからの戻りアドレス
1504: |CPSR | ハンドラからの戻り時に復帰する CPSR
1505: +---------------+
1506:
1507: 4.9 システムコール・拡張 SVC 呼び出し元情報
1508:
1509: td_hok_svc() によるフックルーチンに渡される、システムコール・拡張 SVC 呼
1510: び出し元情報の形式は次のようになる。
1511:
1512: typedef struct td_calinf {
1513: void *ssp; /* システムスタックポインタ */
1514: void *r11; /* 呼出時のフレームポインタ */
1515: } TD_CALINF;
1516:
1517: ssp は T-Monitor の例外分岐ルーチンを抜けた直後のスタック位置を示してお
1518: り、スタックは次のような内容になっている。
1519:
1520: +---------------+
1521: ssp -> |R12=ip |
1522: |R14_svc=lr | SVC からの戻りアドレス
1523: |SPSR | 呼出元のプロセッサモード
1524: +---------------+
1525: +---------------+
1526: R13_xxx -> |R14_xxx=lr | インターフェースライブラリからの
1527: +---------------+ 戻りアドレス
1528:
1529: システムコール・拡張 SVC からの戻り番地は R14_svc である。しかし、通常は
1530: インターフェースライブラリを利用して呼び出すため、R14_svc はインターフェ
1531: ースライブラリの番地を指している。
1532:
1533: インターフェースライブラリからの戻り番地は R14_xxx となる。R13_xxx は呼
1534: 出元のプロセッサモードにしたがったスタックポインタであり、呼出元のプロセ
1535: ッサモードは SPSR で知ることができる。呼出元のプロセッサモードが SVC の
1536: 場合、ssp + 12 が R13_xxx に相当する。
1537: なお、標準のインターフェースライブラリを使用していない場合は、この限りで
1538: はない。
1539:
1540: 4.10 CPU 割込制御
1541:
1542: 以下の CPU 割込制御マクロ関数は、CPSR.I および A フラグを禁止・許可する。
1543: CPSR.F フラグは変更しない。つまり、IRQ 通常割込とアボート例外の割込制御
1544: であり、FIQ 高速割込には影響しない。
1545:
1546: DI( UINT intsts ) IRQ 割込禁止
1547: EI( UINT intsts ) IRQ 割込許可(以前の状態へ復帰)
1548:
1549: 4.11 割込コントローラ
1550:
1551: 割込コントローラの操作に関しては下記のライブラリ関数がある。
1552:
1553: (1) 割込ベクター(INTVEC)の値
1554:
1555: #define IV_IRQ(n) ( 32 + (n) ) /* IRQ 割込 0〜95 */
1556: #define IV_GPIO(n) ( 128 + (n) ) /* GPIO 割込 0〜127 */
1557:
1558: 割込コントローラの操作関数で intvec として指定可能な値は、これら IRQ,
1559: GPIO の各割込の範囲である。
1560: 有効範囲外を指定した場合の動作は保証されない。
1561:
1562: (2) 割込モード設定
1563:
1564: void SetIntMode( INTVEC intvec, UINT mode )
1565:
1566: intvec で指定した割込を mode で指定したモードに設定する。
1567: 不正な mode を指定した場合の動作は保証されない。
1568:
1569: #define IM_ENA 0x0001 /* 割込線有効 */
1570: #define IM_DIS 0x0000 /* 割込線無効 */
1571: #define IM_INV 0x0002 /* 極性反転 */
1572: #define IM_LEVEL 0x0200 /* レベル */
1573: #define IM_EDGE 0x0000 /* エッジ */
1574: #define IM_HI 0x0000 /* ハイレベル/立ち上がりエッジ */
1575: #define IM_LOW 0x0100 /* ローレベル/立ち下がりエッジ */
1576: #define IM_BOTH 0x0400 /* 両エッジ */
1577: #define IM_ASYN 0x0800 /* 非同期 */
1578:
1579: IRQ の場合
1580: mode := IM_ENA | IM_INV
1581: または IM_DIS
1582:
1583: GPIO の場合
1584: mode := IM_ENA | IM_LEVEL | (IM_HI ‖ IM_LOW) | IM_ASYN
1585: または IM_ENA | IM_EDGE | (IM_HI ‖ IM_LOW ‖ IM_BOTH) | IM_ASYN
1586: または IM_DIS
1587:
1588: IM_ENA が指定されると、指定されたモード設定を行った後、割込禁止
1589: (DisableInt)に設定した上で、割込線を有効にする。
1590: IM_DIS が指定されると割込線を無効にする。無効になった割込線は、割込許可
1591: (EnableInt)しても割込は発生しない。
1592: 初期状態では、割込線無効(IM_DIS)である。
1593:
1594: なお、下記の GPIO 割込に対応する割込コントローラ側の設定は、システム起動
1595: 時に IM_ENA に設定され、割込許可(EnableInt)状態となっている。
1596:
1597: IRQ26 GIO6 Interrupt (GPIO port 96〜111)
1598: IRQ27 GIO7 Interrupt (GPIO port 112〜127)
1599: IRQ50 GIO0 Interrupt (GPIO port 0〜 15)
1600: IRQ51 GIO1 Interrupt (GPIO port 16〜 31)
1601: IRQ52 GIO2 Interrupt (GPIO port 32〜 47)
1602: IRQ53 GIO3 Interrupt (GPIO port 48〜 63)
1603: IRQ79 GIO4 Interrupt (GPIO port 64〜 79)
1604: IRQ80 GIO5 Interrupt (GPIO port 80〜 95)
1605:
1606: (3) 割込許可
1607:
1608: void EnableInt( INTVEC intvec )
1609:
1610: intvec で指定した割込を許可する。
1611:
1612: (4) 割込禁止
1613:
1614: void DisableInt( INTVEC intvec )
1615:
1616: intvec で指定した割込を禁止する。
1617:
1618: (5) 割込要求のクリア
1619:
1620: void ClearInt( INTVEC intvec )
1621:
1622: intvec の割込要求をクリアする。
1623:
1624: エッジトリガーの割込のみクリアする必要がある。
1625:
1626: (6) 割込要求の有無の確認
1627:
1628: BOOL CheckInt( INTVEC intvec )
1629:
1630: intvec の割込要求があるか調べる。
1631: 割込要求があれば TRUE (0 以外) を返す。
1632:
1633: 割込要求の有無は、raw ステータスレジスタにより検査する。
1634:
1635: 4.12 その他
1636:
1637: (1) 周辺デバイス領域に対するI/Oポートアクセス
1638:
1639: 周辺デバイス領域に対するメモリータイプのモード設定を Device としている。
1640: そのため、周辺デバイス領域に対して out_b(), out_h(), out_w(), out_d() を
1641: 実行した場合でも、これらのAPIの処理はドレイン(データの書き出し)の完了を
1642: 待たずに終了する。(周辺デバイス領域については「2.3 メモリーマップ」を参照)
1643:
1644: 5. デバイスドライバ実装仕様
1645:
1646: 5.1 システムディスクドライバ
1647:
1648: (1) 操作対象となるデバイス
1649:
1650: 以下のシステムディスクを対象とする。
1651:
1652: - microSD カードスロットに挿入した microSD カード
1653: - ROM ディスク (NOR Flash)
1654:
1655: デバイス名 デバイス
1656: pcb microSD カード
1657: rda ROM ディスク (NOR Flash)
1658:
1659: サブユニットは以下のデバイスでのみサポートする。
1660:
1661: microSD カード
1662: ※サブユニットは最大 4 個
1663:
1664: microSD カードへのアクセスは、EM1-D512 の以下のリソースを使用する。
1665:
1666: メディア コントローラ カード検出用 GPIO
1667: microSD SDIA(SD0) GPIO P3
1668:
1669: SDIA の各種割込 (SDIx_SD_INT, SDIx_CC_INT) は使用しない。
1670: SDIA, GPIO を使用するために必要な I/O ピンの設定およびクロックの設定は、
1671: 適切に行われていることを前提とする。
1672:
1673: FlashROM (NOR) を使用した ROM ディスクは、RomInfo に定義した領域をディス
1674: クとして使用する。
1675:
1676: (2) 機種依存事項 (システムディスクドライバ)
1677:
1678: (a) DEVCONF エントリ
1679:
1680: システムディスクドライバは、以下の DEVCONF エントリを参照する。
1681:
1682: HdSpec HD 仕様
1683: xxNI xxxx xxxx xxxx xxxx
1684: [デフォルト: 0x00010000]
1685:
1686: I : イジェクト可能ディスクのメディア挿入自動チェック
1687: N : イジェクト可能ディスクのメディア自動イジェクト禁止
1688:
1689: HdChkPeriod 周期 (msec)
1690: イジェクト可能ディスクのチェック周期
1691: [デフォルト: 3000]
1692:
1693: (b) マスターブートレコードのアクセス機能
1694:
1695: サブユニットに対応したデバイスに対し、マスターブートレコードのアクセスの
1696: ための特殊機能が用意されている (物理ユニットのみ)。
1697:
1698: 属性レコード番号: -999999 (R)
1699:
1700: data: UW magic;
1701: DiskBlock0 mboot;
1702:
1703: magic = CH4toW('M','B','R','R') : マスターブートレコードの読み込み
1704: CH4toW('M','B','R','W') : マスターブートレコードの書き込み (読み
1705: 込み処理で書き込む)
1706:
1707: ※ CH4toW(c1, c2, c3, c4) は、( ((c4)<<24)|((c3)<<16)|((c2)<<8)|(c1) )。
1708:
1709: ☆ マスターブートレコードの書き込みにより、使用中の区画が変更された場合
1710: の動作は保証しない。
1711:
1712: (c) 区画 (サブユニット) の扱い
1713:
1714: サブユニットに対応したデバイスに対しては、区画情報の動的変更に対応するた
1715: め、常に 4 つの区画 (サブユニット) が登録される。なお、空の区画に対して
1716: オープンした場合は、E_NOMDA のエラーとなる。
1717:
1718: (d) CHS 情報の算出方法
1719:
1720: 一般に、CHS から計算した全体容量は本来のディスク全体の容量より小さくなる。
1721:
1722: シリンダ (C) 最大 1023
1723: ヘッド (H) 最大 255
1724: セクタ (S) 最大 63
1725:
1726: ・C は最大 1024 であるが、通常は最終シリンダは使用しない。
1727: ・H は最大 256 であるが、通常は 255 としている。
1728:
1729: CHS 情報は以下のように決定している。
1730:
1731: 1.物理 CHS 情報から、上記制限に入るような CHS 情報を以下の方式で計算する
1732: (pC, pH, pS : 物理 CHS 情報)。
1733: T = pC * pH * pS; C = pC; H = pH; S = pS;
1734: while (C > 1024) {C >>= 1; H <<= 1;}
1735: if (S > 63) S = 63;
1736: if (H > 255) H = 255;
1737: C = T / H / S;
1738: if (C > 1023) C = 1023;
1739:
1740: 2.区画が設定済みのときは、区画情報から CHS 情報を計算する。
1741: S = 区画の終了セクタ;
1742: H = 区画の終了ヘッド + 1;
1743: C = T / H / S - 1;
1744:
1745: 5.2 時計 (クロック) ドライバ
1746:
1747: (1) 操作対象となるデバイス
1748:
1749: EM1-D512 の SPI(SP0) およびこれに接続された RTC(RX-4581NB) を対象とする。
1750: SP0 には RTC の他、Audio CODEC(ML7037), 電源管理コントローラ (DA9052) も
1751: 接続されているため、SPI 操作用のインタフェースも併せて提供する。
1752:
1753: デバイス名は "CLOCK" とする。
1754:
1755: (2) ハードウェアの制限事項
1756:
1757: 不揮発レジスタ (フリーレジスタ) への対応は行わない。
1758: RTC 割り込みには対応しない。
1759:
1760: (a) DN_CKAUTOPWON: 自動電源オン時刻の設定 / 取得 (RW)
1761:
1762: 対応しない。エラー (E_NOSPT) とする。
1763:
1764: (b) DN_CKREGISTER: 不揮発レジスターの書き込み / 読み出し (RW)
1765:
1766: 対応しない。エラー (E_NOSPT) とする。
1767:
1768: DN_CKAUTOPWON に対応しないため、事象通知も行わない。
1769:
1770: (3) SPI(SP0) 操作用インタフェース
1771:
1772: SPI(SP0) に接続された RTC, Audio CODEC, 電源管理コントローラの操作は、以
1773: 下のインタフェースを使用して行う。
1774:
1775: <device/em1d512/em1d512_iic.h>
1776: ER em1d512_spixfer(W cs, UB *xmit, UB *recv, W len)
1777:
1778: SPI(SP0) に接続されたデバイスに対し、データの送受信を行う。
1779:
1780: cs: 通信対象デバイス
1781: 0 電源管理コントローラ (DA9052)
1782: 1 Audio CODEC (ML7037)
1783: 2 RTC (RX-4581NB)
1784:
1785: xmit: 送信データを格納する領域の先頭ポインタ
1786: recv: 受信データを格納する領域の先頭ポインタ
1787: len: 送信/受信データ数 (byte)
1788:
1789: 戻り値: E_OK もしくはエラー (E_IO, E_TMOUT, E_PAR)
1790:
1791: SP0 割り込みを使用して動作するため、割り込みハンドラ内、もしくは割り込み
1792: が禁止された状態から呼び出してはならない。SP0 割り込み待ちは、tk_slp_tsk
1793: () を使用する。
1794:
1795: 5.3 スクリーン (ディスプレイドライバ)
1796:
1797: (1) 操作対象となるデバイス
1798:
1799: EM1-D512 に内蔵される、LCD コントローラを使用する。MEMC-LCD DirectPath
1800: モードを使用し、IMC (イメージコンポーザ) 無しで動作させる。
1801: LCD コントローラに加え、LCD の点灯制御に GPIO P82 および DA9052 の White
1802: LED Driver を使用する。
1803: LCD を使用するために必要な I/O ピンの設定は、適切に行われていることを前
1804: 提とする。表示に使用するピクセルクロックは、スクリーンドライバが PLL2 を
1805: 操作して生成する。
1806:
1807: (2) 機種依存事項 (スクリーンドライバ)
1808:
1809: スクリーンドライバで使用可能な属性データには、制限がある。
1810:
1811: (a) DN_SCRNO: 使用する表示モードの取り出し / 設定 (RW)
1812:
1813: 表示モードの取り出し (R) のみ対応する。
1814:
1815: (b) DN_SCRUPDFN: スクリーンの更新関数の取り出し (R)
1816:
1817: 対応しない。
1818: 関数ポインタには NULL がセットされる。
1819:
1820: (c) DN_SCRVFREQ: モニタの垂直周波数の設定 / 取り出し (RW)
1821:
1822: 対応しない。
1823: 取り出し: vfreq には 0 がセットされる。
1824: 設定: vfreq の値を無視する。
1825:
1826: (d) DN_SCRBRIGHT: スクリーンの明るさの設定 / 取り出し (RW)
1827:
1828: (e) DN_SCRUPDRECT: スクリーン表示の更新 (W)
1829:
1830: (f) DN_SCRADJUST: モニタのタイミング調整の設定 / 取り出し (RW)
1831:
1832: (g) DN_SCRMEMCLK: Video-RAM のクロック設定 / 取り出し (RW)
1833:
1834: (h) DN_SCRWRITE: 直接スクリーン表示 (W)
1835:
1836: 非対応。エラー (E_NOSPT) を返す。
1837:
1838: (i) サポートしている表示モード
1839:
1840: 以下の表示モードにのみ対応する。
1841:
1842: 800×480, 16bpp 固定
1843:
1844: (j) 表示モードの設定
1845:
1846: 表示モードの設定はシステム起動時にのみ行っているため、属性データとして動
1847: 的に設定する機能はサポートしていない。
1848:
1849: (k) 垂直周波数(リフレッシュレート)の設定
1850:
1851: 垂直周波数の設定機能はサポートしない。
1852:
1853: (l) DEVCONF エントリ
1854:
1855: スクリーンドライバが参照する DEVCONF エントリは、以下の通り。
1856:
1857: VIDEOMODE mode
1858:
1859: このエントリは予約する(使用してはならない)。
1860:
1861: VIDEOATTR attr
1862:
1863: このエントリは予約する(使用してはならない)。
1864:
1865: 5.4 KB/PD ドライバ
1866:
1867: (1) 操作対象となるデバイス
1868:
1869: - キーパッド
1870: - タッチパネル
1871:
1872: キーパッドは、GPIO P4(SW4), P6(SW3), P7(SW2) を使用し、キーの ON/OFF は
1873: これらの GPIO 割り込みを使用して検知する。
1874: タッチパネルの A/D 変換値は、RTC ドライバが提供する SPI(SP0) 操作用イン
1875: タフェースを使用して、電源管理コントローラ (DA9052) から得る。DA9052 の
1876: 割り込みマスクレジスタには以下の値を設定し、PEN_DOWN 割り込みのみを発生
1877: させるようにする。DA9052 からの割り込みは、GPIO P0 割り込みとして通知さ
1878: れる。
1879:
1880: R10(IRQ_MASK_A) 0xff
1881: R11(IRQ_MASK_B) 0xbf
1882: R12(IRQ_MASK_C) 0xff
1883: R13(IRQ_MASK_D) 0xff
1884:
1885: (2) 機種依存事項 (KB/PDドライバ)
1886:
1887: (a) DEVCONFエントリ
1888:
1889: 実IOドライバ(lowkbpd)は、以下のDEVCONFエントリを参照する。
1890:
1891: TEngTabletPar X-bias X-span Y-bias Y-span PointerNoDisp ScanRate(off)
1892: ScanRate(on)
1893: X-bias, X-span, Y-bias, Y-spanは、タッチパッドから得られた座標デ
1894: ータを正規化する際に使用する補正用パラメータである。
1895: PointerNoDispに1を指定した場合、ポインタの表示を行わない (MetaBut.
1896: nodsp=1 を渡す)。
1897: ScanRate(off)は、ペンをリリース後、次のペンタッチ検出を行うまで
1898: の時間をミリ秒単位で指定する。
1899: ScanRate(on)は、ペンタッチ中のポーリング間隔をミリ秒単位で指定す
1900: る。
1901:
1902: デフォルトは、PointerNoDisp=0, ScanRate(off)=50, ScanRate(on)=50,
1903: X-bias/X-span/Y-bias/Y-spanはLCDパネルに対応した値とする。
1904:
1905: TEngUseTablet タッチパネルの使用可否
1906: 1を指定した場合はタッチパネルを使用する。
1907: 0を使用した場合はタッチパネルを使用しない。
1908:
1909: デフォルトは1とする。
1910:
1911: (b) 押しボタンスイッチに関する事項
1912:
1913: 押しボタンスイッチとスキャンコードの対応は、以下の通りとする。
1914:
1915: SW2 SW3 SW4
1916: ------------------------
1917: 0x6e 0x6d 0x6f
1918:
1919: 5.5 RS-232C ドライバ
1920:
1921: (1) 操作対象となるデバイス
1922:
1923: EM1-D512 に内蔵される、UART0〜2 を対象とする。
1924: これらの UART を使用するために必要な I/O ピンの設定およびクロックの設定
1925: は、適切に行われていることを前提とする。
1926:
1927: RS-232C のデバイス名・対応するポート・使用するリソースを、以下に示す。
1928:
1929: ポート名 アドレス 割り込み
1930: "rsa" (UART0) 0x50000000〜0x5000ffff IV_IRQ(9)
1931: "rsb" (UART1) 0x50010000〜0x5001ffff IV_IRQ(10)
1932: "rsc" (UART2) 0x50020000〜0x5002ffff IV_IRQ(11)
1933:
1934: チップから以下の信号線が出力されないため、これらの信号線に関連する機能は
1935: 使用できない (使用しないこと)。
1936:
1937: UART0 RI, DSR, DTR, RTS, CTS
1938: UART1 RI, DSR, DTR, RTS, CTS
1939: UART2 RI, DSR, DTR
1940:
1941: (2) 機種依存事項 (RSドライバ)
1942:
1943: (a) 各種属性データ
1944:
1945: RS ドライバで設定可能な属性データ、および属性データに設定可能な各種パラ
1946: メータの範囲を、以下に示す。
1947:
1948: (b) DN_RSMODE: 通信モード (RW)
1949:
1950: 以下のモードに対応する。
1951:
1952: parity: 0:無し, 1:奇数, 2:偶数
1953: datalen: 0:5bit, 1:6bit, 2:7bit, 3:8bit
1954: stopbits: 0:1bit, 1:1.5bit, 2:2bit
1955: baud: 300〜115200
1956:
1957: (c) DN_RSFLOW: フロー制御 (RW)
1958:
1959: UART0, UART1 については、csflow および rsflow に 0 を指定すること。
1960:
1961: (d) DN_RSSTAT: 回線状態 (R)
1962:
1963: 一部の信号線が利用できないため、以下の値は意味を持たない。
1964:
1965: UART0 CI(RI), CD(DCD), DR(DSR), CS(CTS)
1966: UART1 CI(RI), CD(DCD), DR(DSR), CS(CTS)
1967: UART2 CI(RI), CD(DCD), DR(DSR)
1968:
1969: (3) 機種依存事項 (シリアル I/O ドライバ)
1970:
1971: (a) ポート番号とデバイスとの対応
1972:
1973: シリアル I/O ドライバの serial_in(), serial_out(), serial_ctl()で指定す
1974: るport番号と、対応するデバイスは、以下の通りである。
1975:
1976: port デバイス
1977: 0 UART0
1978: 1 UART1
1979: 2 UART2
1980: 3 予約
1981:
1982: (b) serial_ctl()の制限事項
1983:
1984: ER serial_ctl(W port, W kind, UW *arg) の kind, arg の指定には、制限が
1985: ある。
1986:
1987: <kind> <arg>
1988: DN_RSFLOW RsFlow フロー制御
1989:
1990: ・RsFlow の設定は、RS ドライバの DN_RSFLOW の項を参照。
1991:
1992: - DN_RSSTAT RsStat 回線状態の取得
1993:
1994: ・取得した RsStat の内容は、RS ドライバの DN_RSSTAT の項を参照。
1995:
1996: RS_LINECTL UW 制御線の ON/OFF 設定
1997:
1998: ・以下の指定による信号線の操作は、意味を為さない。
1999:
2000: UART0 RSCTL_DTR, RSCTL_RTS
2001: UART1 RSCTL_DTR, RSCTL_RTS
2002: UART2 RSCTL_DTR
2003:
2004: 以上
2005: