川の流れのように‥(Eiji Ota's Weblog)

火曜日 6 14, 2005

祝OpenSolaris:誕生おめでとう!

祝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:
Technorati Tag:

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed

Calendar

Feeds

Search

Links

Navigation

Referrers