Open Design Computer Project

オリジナルCPUから作る本格的自作コンピューター

ユーザ用ツール

サイト用ツール


memo

開発メモ

ToDo / Issues

ISS

  • 要望
    • テスト自動化のために特定のアドレスの命令を実行したらシミュレーションを停止するようにできたらうれしい(br 0, #al等で停止させたい)。
      • ./mist32-simulator -b <address> で停止できるようになった。
    • テスト自動化のためにシミュレーション完了時に、あらかじめ指定したアドレスのデータを出力させたい(コマンドで出力させるメモリアドレスを複数指定できるなど)。
      • 要検討

ISA

これからは GitHub Issue へ https://github.com/mist32/mist32-isa/issues

  • ld8, st8 などの符号拡張付き命令を追加したい (AFE?) → 要件等、AFEでの対応をするか否か → Load StoreのAFEで対応/実装済み。なお、Loadのみで、Storeは対応させない。
    • アセンブラ未実装
  • TAS命令はこの実装にする tas src0, src1 | O2, I11 | tas gr[src0], mem[src1]
  • Memory barrierをもつ(AFE?) Load/Store命令またはmfence, lfence, sfence。どうしよう?
  • Compare and Branch 命令。3オペランドは不可能なので、0 の場合や !0 の場合などだけでも使えそう。

AFE

  • 符号拡張のAFE(8→32, 16→32)
  • displacement load/store は O2 の空きビット (10…16) を利用して行う
  • src オペランドに副作用がある命令 (post_inc, pre_dec, etc…) などは、難しいっぽい。

マイクロコード

  • Inorder / Out of Orderの両方、マイクロコードに対応させる。
    • InorderコアのTASをマイクロコードに変更 → Data BusをLockするし、マイクロコード実装でもオーバーヘッドはあまりない。

キャッシュ

  • 命令の自己書き換えにどう対応するか
    • 自己書き換えが起こらない前提が一番良い
    • パイプラインをフラッシュするにはどうすればよいか
    • キャッシュを消すにはどうすればよいか
    • 専用命令とかもありか?

MMU

  • MMUMOD と MMUPS を専用レジスタに移すか、専用命令が欲しい。
  • PTE にキャッシュ無効ビットだけでなくて、キャッシュライトスルービットも必要か?
    • I/O はそれ以下のレベルでキャッシュ無効にするとして、マルチコアの時とかどうなんだろう?

Software

  • mruby が -O3 でこける (undefined method のとき)
  • Compiler ToDo
    • 符号拡張 ld8, st8
    • SRSPWADD
    • Condition Code 周りの謎解明
  • Simulator ToDo
    • 命令権限
      • 現状はユーザーも何も関係ない状態
    • シミュレーターのデバッグ機能強化
      • gdb の next に相当する機能を付ける。
      • traceback の関数名表示
      • 特定番地のメモリ表示
      • メモリダンプ
    • キャッシュ
      • 4-way 4KB
      • Line: 64byte * 64 (4 * 16)
        • tttt tttt tttt tttt tttt ttee eeww wwxx
        • t: tag, e: entry address, w: word address
      • LRU
  • xv6 ToDo
    • MMC ide
    • CGA コンソール
    • KMC

コンパイラおかしい。cmp reg, imm が使えてない。

8010aaa0:       0e c0 00 20     lil     r1,0
  // split list
  a = list;
  b = list->next->next;

  while(b) {
    a = a->next;
8010aaa4:       10 40 00 63     ld32    r3,r3
    b = b->next;
8010aaa8:       10 40 00 82     ld32    r4,r2

    if(b->next) {
8010aaac:       10 40 00 44     ld32    r2,r4
8010aab0:       00 c0 00 41     cmp     r2,r1
8010aab4:       14 32 ff fc     br      8010aaa4 <omap_slab_sort+0x60>,#ne

割り込み

  • 割り込み権限の設定
    • ユーザー権限では割り込みを発行できない割り込みがあってもよさそう
    • IDT にそれを設定するフラグが必要になる
  • NMI について
    • x86 の NMI ってなんのためについてるんだろう?

コンテキストスイッチ

  • コンテキストスイッチ時にレジスタに dirty bit 的なものをつけて、書き換わったレジスタのみ退避
  • タスク実行中に、Load/Store ユニットの空きを利用して、バックグラウンドのレジスタセットに次のコンテキストのレジスタを予め読んでおく

GCI

SDC

  • 容量取得
  • カードがあるかないか
  • 処理が終わったことを割り込みで通知
  • マルチブロックリード・ライト

あとで書く

スタック

あとで仕様にまとめる

  • User stack と Kernel stack を用意するが、ハイパーバイザーが使いそうなモードはどうするか?
  • uspr, kspr とするか sp0, sp1… のようにするか
    • 特権レベル 1,2 のスタックも用意するなら後者のほうが良さそう
  • sruspr(w) を用意する
    • srkspr はいらない。kernel モードでしか触らないし、ユーザーから kspr 書かれたらいけない。
    • 特権レベル 1,2 のスタックも用意するならそれは必要?
    • 仮想化考えないほうがいいかも…
  • push, pop は、今参照しれている spr のみ
  • 権限レベルに同期して切り替わる。基本的に ib で切り替える。
    • ppcr にユーザープロセスのエントリアドレス
    • ppsr の権限フラグをユーザーにしておく
    • ib をすると、ユーザー権限になりスタックが切り替わって、ppcr のアドレスから実行される

開発メモ(伊藤)

ソフトウェア割り込みについて

ソフトウェアレベル
  1. 再入不可能割り込み
    1. SWI命令でソフトウェア割り込みを発生させる。レジスタ規約はr31にリターンアドレスを必要としない以外は関数呼び出しのそれと同様
    2. 必要な処理を行いibで割り込みからの復帰
  2. 再入可能割り込み
    1. SWI命令でソフトウェア割り込みを発生させる。レジスタ規約は関数呼び出しのそれと同様
    2. 多重割り込みを許可するに当たり旧状態のPPSR、PPCR、PSPR、PPDTR、PTIDRをスタックにPush
    3. srieiw命令で割り込み許可 
    4. 必要に尾おじて割り込みルーチン内の処理を行う
    5. srieiw命令で割り込み禁止 
    6. 多重割り込みを考慮するためにPushしていたPPSR, PPCR, PSPR, PPDTR, PTIDRをPop
    7. ibで割り込みからの復帰

以下プログラムでの記述例

- 再入不可能割り込み

S_IRQ_HUNDLER:
	...
	...何かしら必要な処理
	...
	ib		r31				;割り込みハンドラを抜ける

- 再入可能割り込み

S_IRQ_HUNDLER:
	srppcr		r?				;PPCRをR?にmove
	srppdpr		r?				;PPDTRをR?にmove
	srptidr		r?				;PTIDRをR?にmove
	push		r?				;PPCRをPush
	push		r?				;PPDTRをPush
	push		r?				;PTIDRをPush
	srieiw		1				;グローバル割り込み許可
	...
	...何かしら必要な処理(この中は多重割り込み可能)
	...
	srieiw		0				;グローバル割り込み不許可
	pop		r?				;PTIDRをPop
	pop		r?				;PPDTRをPop
	pop		r?				;PPCRをPop
	srptidw		r?				;R?をPTIDRにmove
	srppcw		r?				;R?をPPCRにmove
	srppdpw		r?				;R?をPPDTRにmove
	ib						;割り込みハンドラを抜ける
ハードウェアレベル
  1. 割り込みへの移行ステート
    1. swi命令が発行されるとコア内でexceptionを起こし割り込みを禁止する。exceptionを発生させた位置までコミットするのを待つ
    2. コミットしたら割り込みベクタをチェックしてプロセッサ内に持っている割り込みベクタのキャッシュをチェックしてもしDisableであればFaultを起こす。Enableの時にはPSRをPPSRに、PCRをPPCRに、SPRをSSPRに、PDTRをPPDTRに、TIDRをPTIDRに、TIDRをPTIDRにコピー
    3. PSRはIMを1(パブリック割り込みをマスク)して、CMODを2'b00(Kernel Mode)にする。PDTR、TIDRはそのまま、SPRはTIDRが示すストラクチャからKernel用のSPRを取得。
    4. PCRは割り込みベクタから取得したものをセット(割り込みハンドラにBranch)
  2. 割り込みからの復帰ステート
    1. ibが実行されるとコア内でexceptionを起こし割り込みを禁止する。exceptionを発生させた位置までコミットするのを待つ。
    2. コミットしたらPPSRをPSRに、PSPRをSPRに、PPDTRをPDTRに、PTIDRをTIDRにコピー
    3. PPCRをPCにセット(Branch)

ハードウェア割り込みについて(非TSW)

ソフトウェアレベル
  1. 再入不可能割り込み
    1. 割り込みストラクチャテーブルのPTIDRが示すエントリにGR0~31, PPCR, PSPR, PPDTR, PPSRを格納。
    2. 必要な処理を行いibで割り込みからの復帰
  2. 再入可能割り込み
    1. GR0~31, PPCR, PSPR, PPDTR, PPSRをPush。
    2. 割り込みを起こしたデバイスのステータスレジスタを読み割り込みをクリア
    3. srieiw命令で割り込み許可 
    4. 割り込みルーチン内の処理を行う
    5. srieiw命令で割り込み禁止 
    6. GR0~31, PPCR, PSPR, PPDTR, PPSRをPop。
    7. ibで割り込みからの復帰

以下プログラムでの記述例

  • 再入不可能割り込み
H_RD_IRQ_HUNDLER:
	push		r?				;必要に応じて割り込みハンドラで使用するレジスタをpush
	ld32		r?,		R?		;割り込み要因のデバイスからステータスを取り出すことで割り込みフラグをクリア
	...
	...何かしら必要な処理
	...
	push		r?				;pushされていたレジスタをpop	
	ib						;割り込みハンドラを抜ける
  • 再入可能割り込み
H_RE_IRQ_HUNDLER:
	push		r0				;汎用レジスタ0-31をpush
	...
	push		r31				
	srppcr		r?				;PPCRをR?にmove
	srppdpr		r?				;PPDTRをR?にmove
	srptidr		r?				;PTIDRをR?にmove
	push		r?				;PPCRをPush
	push		r?				;PPDTRをPush
	push		r?				;PTIDRをPush
	ld32		r?,		R?		;割り込み要因のデバイスからステータスを取り出すことで割り込みフラグをクリア
	srieiw		1				;グローバル割り込み許可
	...
	...何かしら必要な処理
	...
	srieiw		0				;グローバル割り込み禁止
	pop		r?				;PTIDRをPop
	pop		r?				;PPDTRをPop
	pop		r?				;PPCRをPop
	srptidw		r?				;R?をPTIDRにmove
	srppcw		r?				;R?をPPCRにmove
	srppdpw		r?				;R?をPPDTRにmove
	pop		r31				;以前実行していた汎用レジスタを、現在の汎用レジスタにコピー
	...
	pop		r0
	ib						;割り込みハンドラを抜ける
ハードウェアレベル(ソフトウェア割り込みのそれと同じ)
  1. 割り込みへの移行ステート
    1. 割り込みが発生するとコア内でexceptionを起こし割り込みを禁止する。exceptionを発生させた位置までコミットするのを待つ
    2. コミットしたら割り込みベクタをチェックしてプロセッサ内に持っている割り込みベクタのキャッシュをチェックしてもしDisableであればFaultを起こす。Enableの時にはPSRをPPSRに、PCRをPPCRに、SPRをSSPRに、PDTRをPPDTRに、TIDRをPTIDRに、TIDRをPTIDRにコピー
    3. PSRはIMを1(パブリック割り込みをマスク)して、CMODを2'b00(Kernel Mode)にする。PDTR、TIDRはそのまま、SPRはTIDRが示すストラクチャからKernel用のSPRを取得。
    4. PCRは割り込みベクタから取得したものをセット(割り込みハンドラにBranch)
  2. 割り込みからの復帰ステート
    1. ibが実行されるとコア内でexceptionを起こし割り込みを禁止する。exceptionを発生させた位置までコミットするのを待つ。
    2. コミットしたらPPSRをPSRに、PSPRをSPRに、PPDTRをPDTRに、PTIDRをTIDRにコピー
    3. PPCRをPCにセット(Branch)

タスクスイッチ(ソフトウェア)

ソフトウェアレベル
  1. 再入不可能割り込み
    1. 割り込みストラクチャテーブルのPTIDRが示すエントリにGR0~31, PPCR, PSPR, PPDTR, PPSRを格納。
    2. 必要な処理を行いibで割り込みからの復帰
  2. 再入可能割り込み
    1. GR0~31, PPCR, PSPR, PPDTR, PPSRをPush。
    2. 割り込みを起こしたデバイスのステータスレジスタを読み割り込みをクリア
    3. srieiw命令で割り込み許可 
    4. 割り込みルーチン内の処理を行う
    5. srieiw命令で割り込み禁止 
    6. GR0~31, PPCR, PSPR, PPDTR, PPSRをPop。
    7. ibで割り込みからの復帰

なお、コンパイラの最適化により使用しないレジスタを退避しない場合がある。

以下プログラムでの記述例

  • 再入不可能割り込み
H_RD_IRQ_HUNDLER:
	push		r?				;TSWを行う上でこの関数で使用するレジスタを一時的に退避
	ld32		r?,		R?		;割り込み要因のデバイスからステータスを取り出すことで割り込みフラグをクリア
	...
	...コンテキストを退避。上のpushしたレジスタも一旦popする。最低限r0~31, pcr(つまりppcr), spr(しかし、どうやって以前のsprを取得する??psprが必要?), pdtr(つまりppdtr), psr(つまりppsr), flagr(pflagrが必要?)の退避が必要。
	...
	push		r?				;pushされていたレジスタをpop	
	ib						;割り込みハンドラを抜ける
  • 再入可能割り込み
H_RE_IRQ_HUNDLER:
	push		r0				;汎用レジスタ0-31をpush
	...
	push		r31				
	srppcr		r?				;PPCRをR?にmove
	srppdpr		r?				;PPDTRをR?にmove
	srptidr		r?				;PTIDRをR?にmove
	push		r?				;PPCRをPush
	push		r?				;PPDTRをPush
	push		r?				;PTIDRをPush
	ld32		r?,		R?		;割り込み要因のデバイスからステータスを取り出すことで割り込みフラグをクリア
	srieiw		1				;グローバル割り込み許可
	...
	...何かしら必要な処理
	...
	srieiw		0				;グローバル割り込み禁止
	pop		r?				;PTIDRをPop
	pop		r?				;PPDTRをPop
	pop		r?				;PPCRをPop
	srptidw		r?				;R?をPTIDRにmove
	srppcw		r?				;R?をPPCRにmove
	srppdpw		r?				;R?をPPDTRにmove
	pop		r31				;以前実行していた汎用レジスタを、現在の汎用レジスタにコピー
	...
	pop		r0
	ib						;割り込みハンドラを抜ける
ハードウェアレベル(通常の割り込みと全くかわりなし)
  1. 割り込みへの移行ステート
    1. 割り込みが発生するとコア内でexceptionを起こし割り込みを禁止する。exceptionを発生させた位置までコミットするのを待つ
    2. コミットしたら割り込みベクタをチェックしてプロセッサ内に持っている割り込みベクタのキャッシュをチェックしてもしDisableであればFaultを起こす。Enableの時にはPSRをPPSRに、PCRをPPCRに、SPRをSSPRに、PDTRをPPDTRに、TIDRをPTIDRに、TIDRをPTIDRにコピー
    3. PSRはIMを1(パブリック割り込みをマスク)して、CMODを2'b00(Kernel Mode)にする。PDTR、TIDRはそのまま、SPRはTIDRが示すストラクチャからKernel用のSPRを取得。
    4. PCRは割り込みベクタから取得したものをセット(割り込みハンドラにBranch)
  2. 割り込みからの復帰ステート
    1. ibが実行されるとコア内でexceptionを起こし割り込みを禁止する。exceptionを発生させた位置までコミットするのを待つ。
    2. コミットしたらPPSRをPSRに、PSPRをSPRに、PPDTRをPDTRに、PTIDRをTIDRにコピー
    3. PPCRをPCにセット(Branch)

タスクスイッチ(ハードウェア)

ソフトウェアレベル

タスクストラクチャのQueueに有効なエントリが存在しない場合フォールトが発生する。そのフォールトが起きた場合にはQueueにタスクをセットする必要がある。

ハードウェアレベル
  1. 割り込みフラグが必ずEnableになっていることを確認。EnableでなければEnableになるまで待機。Enableの場合、その実行ポイントまでコミットを待つ。
  2. コミットすると、microcodeでタスクストラクチャテーブルのTIDRが示すエントリにコンテキストをStore
  3. 次に実行すべきタスクをmicrocodeでタスクストラクチャテーブルのQueueから探す。もしも見つからない場合フォールトを起こす(番号未定)、
  4. Queueにて見つかった場合そのコンテキストをQueueに示されたタスク番号のタスクストラクチャテーブルからLoadしレジスタにセット。
  5. マイクロコードでPCRにストラクチャテーブルのPCRデータをセット(B)することで次のタスクを実行開始

CPUについて

フラグの処理

Branch系命令(BR, BUR, B)において、その前の命令がフラグを発生させない命令の場合はそのBranch命令は実行を停止(つまりリザベーションステーションでコミットしない)。ただし今後ROBのコミット状態を判断してもしBranch命令以外コミットしている状態であることが確認できたら何かしらのFaultを起こしたり、常にブランチしたり等の対応を行う予定。とりあえず今は、CCで#AL以外の場合必ずその1つ前のにフラグを生成しない命令は置かないこと。

総メモリ容量の取得

SPDから総メモリ容量を取得。その情報はDPSに格納。 → DPSでの対応完了

総メモリ容量を超えたLoad / Storeを行うと常に0x0を返す。

ハードウェアタスクスイッチ

現状搭載しない。使用的に微妙。

memo.txt · 最終更新: 2014/05/23 15:29 by hktechno