川の流れのように‥(Eiji Ota's Weblog)
- All
- application
- kernel
- life
- opensolaris
UltraSPARC sfmmu - 生き残るSpitfireの精神 UltraSPARCとともに
UltraSPARCのMMU その名は、「ガミガミ女」のMMU...
前回NiagaraではMMU用のTrapが違うようだっていうお話をしましたので、その"流れ"で今回はUltraSPARCのMMUについて、ちょっとお話しましょう。前回は、確か、次の2つのトラップ(TL = 0の時)が従来のUltraSPARC用のMMUトラップ…っていうお話をしたんでしたよね? 今回はその続き…。
さぁ、始まり始まり…。^_^
ITLB_MISS(tt0); /* 064 instruction access MMU miss */ DTLB_MISS(tt0); /* 068 data access MMU miss */
と言いつつ、さて皆さん、出だしからいきなり脱線です ^-^ UltraSPARC用のMMU処理はsfmmuと呼ばれているんですけど、このsf...というのは、初代のUltraSPARC CPU, UltraSPARC-IのコードネームがSpitfireであったことからきたもの - すなわちSpitfire MMUの略記なんですねぇ。
スピットファイアというと、あの第2次世界大戦中のイギリスの名機を思い出す方もいるのでは? バトル・オブ・ブリテンで、ドイツのメッサーシュミットと互角の戦いを繰り広げた戦闘機ですねぇ。子供の頃、スピットファイアやメッサーシュミット、零式戦闘機なんて聞くと、何か凄いもののように思えて、胸がドキドキしたものです。^O^
もちろん、今回はその戦闘機うんぬんということでは全然ないんですが、…全然今まで知らなかったのですが…、このスピットファイア、「ガミガミ女」っていう意味(注1)があるらしいんですよねぇ。('-')
つまり、UltraSPARCのsfmmuって、ガミガミ女のMMUっていうことですよね。この新鮮な驚きっ! (← これが言いたかった (^-^;)>)
それでは、しょっぱな早速脱線したところで、このTLBミスって何?っていうところをまず説明しましょう!^.^
MMU(= Memory Management Unit)をサポートしているCPUは、ご存知のようにメモリにアクセスする時にVA(= Virtual Address:仮想アドレス)でアクセスすることができます。でも、メモリの実体は、PA(= Physical Address:物理アドレス)で番地付けられていますよね。プログラムがメモリの番地をVAで指定してきた時に、「誰か」がVAからPAに変換してCPUに本当の番地を教えてあげないといけないわけです。そしてそれをMMUがやっている…というわけですね。それで、プログラムは仮想アドレスを番地として使っても問題ないわけですね。
それでは、MMUはどのようにして仮想アドレスを物理アドレスに変換しているかというと、TLB(= Translation Lookaside Buffer)という変換テーブルを用意していて、そのテーブルに該当のアドレスがないかを検索します。見つかったら、その情報を元に変換してやるわけです。X86アーキテクチャでは、Page Translation Cacheと呼ばれてたりしますから、こちらの方が馴染みがある方もいるでしょうね。
まぁ、運良くTLBに探しているアドレスがあればいいんですけれど、世の中そう甘くな〜いっ。いつもあるとは限らないお金とアドレス、必要な時に見つからない。じゃぁ、どうすればいいのぉ? そう、そう、そういう時は、嘆きたくなりますよねぇ、なんとかしてぇぇって。 MMUが嘆きたくなるその時、CPUがtrapしてくる - そう、それがこのTLBミス・トラップなんです。(^-^;) .oO (ちょっと苦しかったかしら…)
実際には、TLBミスが発生した時にどうするのかっていうのは、CPU次第。X86アーキのように、カーネルがPage Directory Table等々のTableを用意してあげて、CPUがTable Walkingを行って捜し出すものもあれば、CPUがtrapをあげてカーネルに教えて頂戴って言ってくるのもあります。
UltraSPARCは後者を採用しているわけなんですね。X86アーキに慣れている人は、なんか面倒だなって感じるかも知れないけど、この手法は結構ポピュラーな方法です。Andrew S. Tanenbaum教授の(有名な)著書"Operationg Systems Design and Implementation"にもSoftware TLB Managementとして説明(注2)されていて、数々のRISC CPUに採用されている方法でもあるんですね。(*_*)
さぁ、相変わらず前置きが長い私です…さっさと本題に入りますと(^.^;)(汗汗)、このITLB_MISSとDTLB_MISSは、今まで説明したように、基本的にはMMUがTLBを使って検索したが見つからなかったアドレス変換を、Nucleusが肩代りしてあげるためのものです。
ほぼ双子の二人なITLB_MISS()とDTLB_MISSですから、どちらか一方、ではDTLB_MISS()の方をみてみましょうね?(インストラクションには実行権が必要なので、その辺りが違ったりしますが、まぁ気にしないことにしませう)
NucleusにはTSB(= Translation Storage Buffer)と呼ばれる領域があって、これでTLBエントリ(TTE)を管理しています。いわば、Nucleusが管理しているDirect Map Cacheのような"感じ"なんですが、MMU miss trapが発生しますと、CPUはこれかなって思う8Kページの情報(TSBのポインタやTag情報)を持ってシステムにtrapをかけてきますので、この情報を元に、TSBからアドレス変換情報を引っ張ってきて、TLBを更新してあげる…というのが、このUltraSPARCのMMU miss trapの基本処理です。(^-^)
それでは、説明はそれぐらいにして、実際のコードをみてみましょうね。
/* * Needs to be exactly 32 instructions * * UTLB NOTE: If we don't hit on the 8k pointer then we branch * to a special 4M tsb handler. It would be nice if that handler * could live in this file but currently it seems better to allow * it to fall thru to sfmmu_tsb_miss. */ #define DTLB_MISS(table_name) ;\ .global table_name/**/_dtlbmiss ;\ table_name/**/_dtlbmiss: ;\ HAT_PERCPU_DBSTAT(TSBMISS_DTLBMISS) /* 3 instr ifdef DEBUG */ ;\ mov MMU_TAG_ACCESS, %g6 /* select tag acc */ ;\ ldxa [%g0]ASI_DMMU_TSB_8K, %g1 /* g1 = tsbe ptr */ ;\ ldxa [%g6]ASI_DMMU, %g2 /* g2 = tag access */ ;\ sllx %g2, TAGACC_CTX_LSHIFT, %g3 ;\ srlx %g3, TAGACC_CTX_LSHIFT, %g3 /* g3 = ctx */ ;\ cmp %g3, INVALID_CONTEXT ;\ ble,pn %xcc, sfmmu_kdtlb_miss ;\ srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\ brlz,pn %g1, sfmmu_udtlb_slowpath ;\ nop ;\ ldda [%g1]ASI_NQUAD_LD, %g4 /* g4 = tag, %g5 data */ ;\ cmp %g4, %g7 ;\ bne,pn %xcc, sfmmu_tsb_miss_tt /* no 4M TSB, miss */ ;\ mov %g0, %g3 /* clear 4M tsbe ptr */ ;\ TT_TRACE(trace_tsbhit) /* 2 instr ifdef TRAPTRACE */ ;\ stxa %g5, [%g0]ASI_DTLB_IN /* trapstat expects TTE */ ;\ retry /* in %g5 */ ;\ unimp 0 ;\ unimp 0 ;\ unimp 0 ;\ unimp 0 ;\ unimp 0 ;\ unimp 0 ;\ unimp 0 ;\ unimp 0 ;\ unimp 0 ;\ unimp 0 ;\ unimp 0 ;\ .align 128
まず、上の青色で表示されたところをみてください。
これがTLB miss Trapの処理の中核部分です。どうですか? 凄くシンプルですよね? Tanenbaum教授が「過去はHWでMMUを処理していたが、現代のRISC CPUはそれをソフトで行う…。驚くべきことに、…ソフトで行う処理は非常に効率的…」と記述したところ(正確には注2を見てね)が、正にここ。これをみると、なるほどと頷けるものがありますよね。^-^
赤色で示されたところは、TSBにもない場合や、8Kページではなかった場合、コンテキストが不正である場合などの時に、飛んでいくルーチンです。実際には、色々なケースがあるので一筋縄ではいかないんですよね…^.^;。でも、基本は凄くシンプルってことが見て頂けたでしょうか? RISCらしさ- シンプルであること - が出ているところ…かも知れませんね。^-^ (8kページ以外や異常系はそれなりに大変だけど…)
そうそう、コメントなんですけれど…
/* * Needs to be exactly 32 instructions * * UTLB NOTE: If we don't hit on the 8k pointer then we branch * to a special 4M tsb handler. It would be nice if that handler * could live in this file but currently it seems better to allow * it to fall thru to sfmmu_tsb_miss. */この、「exactly 32 instructions」 ← ここに前回の疑問の回答がありました!のでご報告。(^-^)v
CPU実装依存のTrap 0x64 (instruction access MMU miss)とTrap 0x68 (data access MMU miss)は、UltraSPARCでは32命令まで使用できることになっているんですね。それに対し、SPARCv9で決められているMMU用のTrap 0x9と0x31は8命令。この違いから来ているみたい。
普通、Trapハンドラのエントリは8命令で記述するんですけれど、例外はWindow Registerを扱うspill/fill/clean_windowトラップ。こちらは、性能に関係することもあって、32命令まで使用できるようになっています。でも、このinstruction access MMU missとdata access MMU missもspill/fill君たちと同じく、32命令なんですね。これで前回の疑問がとけました。(嬉しいっ)
なぜUltraSPARCはMMU用のTrap 0x9と0x31を使用せず、代わりに0x64と0x68を使用することにしたか - それは、TLB miss trapの処理にはスピードが必要なのにもかかわらず、8命令では命令数が足りなくて処理が遅くなってしまうから - ということだったんですね。(うんうん。納得しましたっ)
そういえば、このトラップ番号0x64, 0x68は、それぞれfast_instruction_access_MMU_miss trap, fast_data_access_MMU_miss trapと、やたら長い(^.^)名前で呼ばれていました。(ってすぐ気づけって…。ははは…。(^-^;)> でも分かって良かった)
......
今日は「ガミガミ女」のMMU(← こだわりです'-') - sfmmuの基本的な部分をさっくり覗いてみました。如何だったですか? HWではなくSWで処理するMMUの、シンプルな基本デザインとそこからくる処理速度。Tanenbaum教授を驚かせた意外性がここにありました。UltraSPARC-I以降のUltraSPARC達ががそれぞれMMUの実装を変更しつつ(注3)も、この「ガミガミ女」のデザインはしっかり踏襲しています(^.^;)。
......
さて、お知らせです。
実は7/4の独立記念日の休暇を利用して、日本でビザを更新することにしました。生憎ビザ更新には時間がかかることもあり、しばらく日本に滞在することになりそうです(幸か不幸か…ですね(^-^).oO(お刺身食べたい…))。そんなこともあって、僕のBlogも不定期になりそうなんですけれど、どうかお許し下さいね! ちょっと予定が分からないので、予めご連絡しておきたいと思いました。それでは。(^v^)
◎ (注1) スピットファイアって「ガミガミ女」以外にも色々意味はありそうなのですが…(+_+)
◎ (注2) Tanenbaum教授は、「... In this design, TLB management and handling TLB faults are done entirely by the MMU hardware. Traps to the operating system occur only when a page is not in memory. In the past, this assumption was true. However, some modern RISC machines, including the MIPS, Alpha, and HP PA, do nearly all of this page management in software. .... Suprisingly enough, if the TLB is reasonably large (say, 64 entries) to reduce the miss rate, software management of the TLB turns out to be quite efficient. ...」と説明されています。
引用は、"Operationg Systems Desing and Implementation Second Edition" (ISBN 0-13-630129-9) P.329 から。
◎ (注3) 実はSPARC architectureはMMUの仕様については明確に定めていません。v7では存在せず、v8ではReference MMUがあり、v9ではMMU Requirementが定義されているだけです。V9のMMU Requirementについては、"The SPARC architecture Manual Version 9"のF SPARC-V9 MMU Requirement (P275)を見て貰うとよいと思いますが、他との整合性を満たすための必要な事項等が定められているだけで、そのRequirementを満たすのであれば、実際にはどのようなMMUの実装であってもかまいません。
MMUは性能に大きく関係するところであり、SPARC CPUの設計の見せどころになっています。また近い将来、技術の進歩により実装が変更される場合でも、システムの互換性を損なわず新しい技術を導入できるようになっています。極端な話として、MMUを実装しなくてもArchitecture上は全く問題ありません。ですが、MMUの違いはカーネルの実装で吸収しなくてはなりません。(T-T)
Technorati Tag:
SPARC
Technorati Tag:
OpenSolaris
Technorati Tag:
Solaris
Technorati Tag:
trap
Technorati Tag:
UltraSPARC
Technorati Tag:
sfmmu
Technorati Tag:
MMU
Posted at 04:38午前 7 02, 2005 by eota in kernel | Comments[0]
Niagara Nucleus - まだHWがナイあガラ ← 苦しい^.^;
Niagara Nucleus処理を覗きみる (滝に打たれに脇道へ)
いつもは激暑になることが多かった初夏ですけれど、今年はなぜか過ごし易い日々が続きます。朝晩は冷え込んで肌寒い事も…。いつもですと、昼間は滝のように水を浴びたくなるのに、今年はそうでもないんですねぇ。嬉しいのか、悲しいのか、ちょっと微妙。(*.*)さて、前回お話したSolarisのNucleus処理ですけれど、Trap Tableのお話をちょっとしました。先日リリースされたOpenSolarisのソースですが、SPARCv9用のtrap_table.sが2つありますよね? 気づきました?
先日のOpenSolarisのソースは、OpenSolarisと銘打っているものの、Sunで開発しているSolarisのソースとほとんど変わりません。6月上旬のソースをそのまま公開しましたので、かなり出来たてほやほやのやつを、生きのいいまま(?)出したって感じになってます。(^-^;)
2つのtrap_table.s - sun4u/ml/trap_table.sとsun4v/ml/trap_table.sなんですが - sun4uのものは従来のUltraSPARCのものなんですけれど、sun4vの方はNiagara用なんですねぇ。(おいおい…^-^;)
実機もまだ巷に出回っていないのに、どうするんじゃぁ?って思いますが、まぁ、そのまんまですから…。ははは。^^; 当然sun4vの方はバグがまだまだあるってわけですね(でも、ハードが未だ出ていないから関係ないですねっ。うんうん!)
では、Niagara向けはどの辺が違うのか、さっそく覗き見してしまいませう。こういうことが、どうどうとできてしまうのが、ある意味オープンソフトのいいところっ!
では、さっそくNiagaraの滝を浴びに…ではなく、Niagaraのtrap table(^.^)をさっくりみてみましょうね。
まず目につくところは、trap_table0のところの、次の2つのMMU missトラップ(0x009と0x031)でしょうか?
ITSB_MISS; /* 009 instruction access MMU miss */ DTSB_MISS; /* 031 data access MMU miss */
これらのトラップはSPARCV9ではMMU用のトラップとして定義(注)されていますが、従来のUltraSPARCアーキでは(なぜか)使用せず、代わりに次の実装依存のトラップをMMU用に使用していました。
ITLB_MISS(tt0); /* 064 instruction access MMU miss */ DTLB_MISS(tt0); /* 068 data access MMU miss */
今回、このトラップ番号0x009と0x031はSunのSPARC機(というか、SPARCv9 CPUかな?)として、初めて使用されることになりますね。
このトラップをもう少し調べると、発生時に次のマクロによりsfmmu_slow_{d,i}mmu_missにジャンプすることが分かります。
#define DTSB_MISS \ GOTO_TT(sfmmu_slow_dmmu_miss,trace_dmmu) #define ITSB_MISS \ GOTO_TT(sfmmu_slow_immu_miss,trace_immu)
これらの関数は、sfmmu/ml/sfmmu_asm.sで定義されており、コメントには次のようにありますから、やはりsun4vで新たにサポートされたトラップであることが分かりますよね。どうやら、{instruction, data} miss with multiple TSBsの時に発生するもののようですねっ。
#ifdef sun4v /* * User/kernel data miss w// multiple TSBs * The first probe covers 8K, 64K, and 512K page sizes, * because 64K and 512K mappings are replicated off 8K * pointer. Second probe covers 4M page size only. * * MMU fault area contains miss address and context. */
もう1つ目につくのは、次のトラップ番号0x60がサポートされていないことです。
NOT; /* 060 interrupt vector */
従来であれば、割り込みはこのトラップ番号0x60でシステムに通知されるのですが、その代わりに次の2つのmondoトラップが用意されています。
CPU_MONDO; /* 07C cpu_mondo */ DEV_MONDO; /* 07D dev_mondo */
これらの関数はsun4v/ml/mach_interrupt.sで定義されており、従来interrupt vectorとして通知されていた割り込みが、sun4v上ではcpu割り込み(0x07c)とdevice割り込み(0x07d)に別れたことが分かります。恐らく、これは従来cpu間の通信手段として使われていたx-call(クロスコール)と通常のデバイス割り込みが同じトラップ番号0x60を共有していたため、それを改めて明確に分離したものと思われます。
そもそもクロスコールとデバイス割り込みとは性格が違うものなので、分離するのはある意味では"筋"であったかも知れませんね。
また、面白いのは、エラー割り込み(CE=ECCを使ったコレクタブルエラーなど)として使われていた次のトラップが無くなり、
GOTO_TT(ce_err, trace_gen); /* 063 corrected ECC error */ LABELED_BAD(tt0_fecc); /* 070 fast ecache ECC error */ LABELED_BAD(tt0_dperr); /* 071 Cheetah+ dcache parity error */ LABELED_BAD(tt0_iperr); /* 072 Cheetah+ icache parity error */
代わりに、resumable, non-resumableという形でまとめられています。
GOTO_TT(resumable_error, trace_gen); /* 07E resumable error */ GOTO_TT(nonresumable_error, trace_gen); /* 07F non-reasumable error */
これらのトラップは実際にはsun4v/os/error.cで処理されていますが、ざっと見では、今のところは、あまり従来の枠を越えたものには見えませんね。残念っ(今後変わるかな?)。
ところで皆さん、sun4v用のtrap_table.sを読むと、hypervisorという言葉が使われている事に気づきました? ^-^
/* * Data miss handler (must be exactly 32 instructions) * * This handler is invoked only if the hypervisor has been instructed * not to do any TSB walk. * * Kernel and invalid context cases are handled by the sfmmu_kdtlb_miss * handler. * * User TLB miss handling depends upon whether a user process has one or * two TSBs. User TSB information (physical base and size code) is kept * in two dedicated scratchpad registers. Absence of a user TSB (primarily * second TSB) is indicated by a negative value (-1) in that register. */
hypervisorというのは、いわゆる仮想化技術のことで、有名なものにはVMwareがありますが、hypervisorはどちらかというとXenのようなIBMのVM(Virtual Machine)技術に似た仮想化技術です。
sun4vにはhypervisorが使われると予想できますけれど、実際sun4v/ml/hcall.sを覗いてみると、hypervisorの処理が幾つか実装されていますねぇ。(あるある!)
これらのhypervisorの関数をみていますと、次のように%o5レジスタにFunction Numberを入れて、ソフト・トラップをかけることが分かります。
mov SVC_RECV, %o5 ta FAST_TRAP
これらの値は、sun4v/sys/hypervisor_api.hに定義されていますので、興味がある方はそちらを見てみて下さいね。
FAST_TRAPは、0x80で定義されていますので、実際にはトラップ番号0x180でシステムに通知されるはずですが、sun4v用のtrap_table.sを見ますと、
/* * Code running at TL>0 does not use soft traps, so * we can truncate the table here. * However: * sun4v uses (hypervisor) ta instructions at TL > 0, so * provide a safety net for now. */ /* soft traps */ BAD4; BAD4; BAD4; BAD4; /* 100 - 10F unused */ BAD4; BAD4; BAD4; BAD4; /* 110 - 11F unused */ BAD4; BAD4; BAD4; BAD4; /* 120 - 12F unused */ BAD4; BAD4; BAD4; BAD4; /* 130 - 13F unused */ BAD4; BAD4; BAD4; BAD4; /* 140 - 14F unused */ BAD4; BAD4; BAD4; BAD4; /* 150 - 15F unused */ BAD4; BAD4; BAD4; BAD4; /* 160 - 16F unused */ BAD4; BAD4; BAD4; BAD4; /* 170 - 17F unused */ /* reserved */ NOT4; NOT4; NOT4; NOT4; /* 180 - 18F reserved */
とあり、残念なことにまだ実装されていない様子です。(^_^;)
今後、sun4v/Niagaraの実装がリリースされることを期待したいですね。
今日は、ちょっと脱線してNiagaraのNucleusの実装を覗きみました。
ソースが公開されていると、HWが出ていなくても、どんな感じのものなのか、 ちょっと想像できてしまいます。なんとなくNiagaraが今から楽しみになってきてしまいますね。
(注) トラップ番号0x09と0x31は、SPARCv9では次のように定義されています。でも、今で使われていなかったんですよ。う〜ん、不思議だ。Niagaraのためにとっておいた…とも思えんし。(?_?)
● instruction_access_MMU_miss [tt=0x09]
A miss in an MMU occurred on an instruction access from memory. For example, a PDC or TLB did not contain a translation for the virtual adddress.
● data_access_MMU_miss [tt=0x31]
A miss in an MMU occurred on a data access from/to memory. For example, a page descriptor cache or translation lookaside buffer did not contain a translation for the virtual address.
引用は、"The SPARC architecture Manual Version 9" P112, P113から。
Technorati Tag:
OpenSolaris
Technorati Tag:
Solaris
Posted at 12:05午前 6 22, 2005 by eota in kernel | Comments[0]
祝OpenSolaris:誕生おめでとう!
Solaris Nucleus処理の解説 (SPARC版)
今日はOpenSolarisの誕生日! v(^-^)/ 待ちに待った(?)日です。生まれたばかりのOpenSolarisは、まだまだヨチヨチの赤ん坊。皆さん、暖かいご支援を期待したいです!
さて、いよいよソースコード[1]もどうどうと皆さんの前にさらけ出しても、なんらお叱りを受けることもなくなりましたね。一つ一つ手かせ足かせが取れていくようで、嬉しい限りです。
今日は、これからOpenSolarisをやろうという人のため、今までとはうって変わって、真面目に実装の解説をすることにしました。(といっても、今までも、それなりに真面目のつもりだったんですが‥ (^^;)
そして今日の解説は、迷いもなく(^-^;)、Solarisの心臓部Nucleus[2]。(じゃじゃーーん)
どのOSもException/Interruptを処理して初めてOSと呼べると思うのですが、(←単に持論です、無視して頂いてかまいませんです。はい^-^) Solaris Operating Systemでは、Exception/Interruptを処理するtrapレベルのコードをnucleusと呼んだりします。このnucleusというのは、SPARC v9アーキテクチャ[3]で定義されている言葉なんですが、ちょっと説明しますね。
SPARC V9では、MMUのコンテキストとして、次の3つをサポートできることになっています。
- Primaryコンテキスト
- Secondaryコンテキスト
- Nucleusコンテキスト
このうち、最初のPrimaryコンテキストとSecondaryコンテキストは必須です。幸い(?)なことに、SunのUltraSPARCシリーズと富士通のSPARC64[4]では、Nucleusコンテキストをサポートしていますので、ここで解説するお話は、双方のSPARC V9アーキのCPUに当てはまりますね!。
Solaris Operating System(面倒なので、以下は、Solaris OSと略記しちゃいます)では、trapを処理する部分[5]はusr/src/uts/sun4u/ml/trap_table.sです。
でもちょっと待って下さいね。SPARC用のtrap_table.sを読む前に、SPARC V9特有のNested Trapについて知っておかないといけませんよぉ。
Nested Trapというのは、Exception/Interruptを処理している最中でも、trap、Exceptionなどの処理をできる仕組みをいいます。
つまり、trap処理であっても、trapがdisableされていない - enable状態になっているということなんですね。これを処理するために、CPUでは、trap stackを実装する必要がありますが、何段まで実装するかというのは、CPUの実装依存になっています。
では、UltraSPARCではどうなっているんでしょう?
1222 /* 1223 * ======================================================================= 1224 * SPARC V9 TRAP TABLE 1225 * 1226 * The trap table is divided into two halves: the first half is used when 1227 * taking traps when TL=0; the second half is used when taking traps from 1228 * TL>0. Note that handlers in the second half of the table might not be able 1229 * to make the same assumptions as handlers in the first half of the table. 1230 * 1231 * Worst case trap nesting so far: 1232 * 1233 * at TL=0 client issues software trap requesting service 1234 * at TL=1 nucleus wants a register window 1235 * at TL=2 register window clean/spill/fill takes a TLB miss 1236 * at TL=3 processing TLB miss 1237 * at TL=4 handle asynchronous error 1238 * 1239 * Note that a trap from TL=4 to TL=5 places Spitfire in "RED mode". 1240 * 1241 * ======================================================================= 1242 */上のコメントを読みますと、UltraSPARCは5段の深さを持っていることが分かりますね。何段であるかはCPUの実装依存なんですけれど、カーネルを移植するためには重要な意味を持っています。
ここで、TL=0というのが通常のカーネル/ユーザモードです。そして、例外や割り込みが発生すると、TLレベルが1つあがって、TL=1となります。そして、この時にコンテキストがNucleusコンテキストに切り替わります。Nested Trapの場合は、この状態でも更に例外などを受け付けることができ、上のコメントにありますように、window fill/spillトラップ、MMUトラップなどを受け付けることができます。
ですけれど、stackには限りがありますよね。永遠にtrapを受け付けることはできませんので、上限にぶつかってしまった場合は、REDモード[6]と呼ばれる特別なモードに入ります。REDモードは、異常処理を扱うモードで、通常はここに入ることはありませんけれど。(でも、バグっていると、すんなり(^-^;)入ります)
さて、SPARC V9用のtrap tableですが、実装では、TL = 0の時と、TL > 0の時の2つの表に分割されます。TL = 0用(通常のtrap処理用)は、trap_table0でスタートする表で、TL > 0用 (nested trap用)は、trap_table1でスタートする表です。ソースでは、次のようになっています。
TL = 0用(通常のtrap処理用)
1250 trap_table0: 1251 /* hardware traps */ 1252 NOT; /* 000 reserved */ 1253 RED; /* 001 power on reset */ 1254 RED; /* 002 watchdog reset */ 1255 RED; /* 003 externally initiated reset */ 1256 RED; /* 004 software initiated reset */ 1257 RED; /* 005 red mode exception */ 1258 NOT; NOT; /* 006 - 007 reserved */ 1259 IMMU_EXCEPTION; /* 008 instruction access exception */ 1260 NOT; /* 009 instruction access MMU miss */ 1261 ASYNC_TRAP(T_INSTR_ERROR, trace_gen); 1262 /* 00A instruction access error */ 1263 NOT; NOT4; /* 00B - 00F reserved */ 1264 ILLTRAP_INSTR; /* 010 illegal instruction */ 1265 TRAP(T_PRIV_INSTR); /* 011 privileged opcode */ 1266 NOT; /* 012 unimplemented LDD */
TL > 0用 (nested trap用)
1412 trap_table1: 1413 NOT4; NOT4; NOT; NOT; /* 000 - 009 unused */ 1414 ASYNC_TRAP(T_INSTR_ERROR + T_TL1, trace_gen); 1415 /* 00A instruction access error */ 1416 NOT; NOT4; /* 00B - 00F unused */ 1417 NOT4; NOT4; NOT4; NOT4; /* 010 - 01F unused */ 1418 NOT4; /* 020 - 023 unused */ 1419 CLEAN_WINDOW; /* 024 - 027 clean window */ 1420 NOT4; NOT4; /* 028 - 02F unused */ 1421 DMMU_EXCEPTION_TL1; /* 030 data access exception */ 1422 NOT; /* 031 unused */ 1423 ASYNC_TRAP(T_DATA_ERROR + T_TL1, trace_gen); 1424 /* 032 data access error */ 1425 NOT; /* 033 unused */ 1426 MISALIGN_ADDR_TL1; /* 034 mem address not aligned */ 1427 NOT; NOT; NOT; NOT4; NOT4 /* 035 - 03F unused */ 1428 NOT4; NOT4; NOT4; NOT4; /* 040 - 04F unused */ 1429 NOT4; NOT4; NOT4; NOT4; /* 050 - 05F unused */ 1430 NOT; /* 060 unused */
同じような表が2つあることが見て取れますね。右に書かれている数字がトラップ番号で、該当するトラップが発生した時に処理するルーチンがこの表で定義されているわけですね。例えば、TL = 0の表でトラップ番号008を見ますとinstruction access exceptionが発生した時に、IMMU_EXCEPTIONが実行される、というように分かりますよね。
Solaris OSのTrap処理を理解するには、まずこのtrap_table.sを理解するのが第一歩ですけれど、これからポツリポツリとSolarisの実装について(つまみ食い)解説していくつもり(今のところ‥^.^;)ですのでお楽しみに!
1. 一応、ライセンスがついているようです。(^-^;)
2. サンに来る前に働いていた富士通のプライムパワー用のSolarisで最初にいじったところです。その時はプライムパワー用のSolaris RAS処理を実装しました。
3. The SPARC Architecture manual (SPARC International, Inc) ISBN: 0-13-099227-5を参照して下さいね。
4. SPARC64-III, -IV, -V(Vはちょっとだけ)知っています。しっかりした、いいCPUだと個人的には思っています。サンも富士通も好きなので、サンと富士通が仲良くできてとても嬉しいです。APL、可愛がってね。
5. 個人的な好みでは、trap処理のようなlowレベルのコードが大好きです。
6. REDモードは、SPARCv9のスペック策定の時、富士通側の要望により入ったものだと、当時一緒に働いていた富士通のHWのエンジニアの方から教わりました。
Technorati Tag: OpenSolaris
Technorati Tag: Solaris
Posted at 01:23午後 6 14, 2005 by eota in kernel | Comments[0]