コグノスケ


link 未来から過去へ表示  link 過去から未来へ表示(*)

link もっと前
2024年8月14日 >>> 2024年9月13日
link もっと後

2024年8月25日

レガシィの7回目の車検完了

目次:

ディーラーまで車検の車を取りに行きました。外は非常に暑くて辛いです……。今後、新しく車を買うときは車検が冬になるようにしたいですね。夏の車検はもう嫌だ。

追加の修理費は特にありませんが、タイヤがもうダメそうだったのでFALKEN AZENIS FK520Lに交換しました。FALKENのプレミアムグレードですが、割と安かった気がします。ブリヂストンやヨコハマは結構高くて1.5〜2倍くらいしますね。

今回FALKENのタイヤを調べていて初めて知ったのですが、DUNLOP(アジア地域など)とFALKENはどちらも住友ゴム工業が製造しているんですね。しかもDUNLOPブランドは非常に複雑でグッドイヤー、住友ゴム工業、コンチネンタルなど複数社が地域ごとにDUNLOPブランドを分け合っているようです。何でそんなことに?ややこしいなあ?

前回の車検からの懸念事項だったパワステギアボックスだかのオイル滲みはまだ耐えてくれているようです。駆動系のブーツ類も硬くなっているそうですが、ブーツ類は消耗品だからしかたないですね。半年後の点検まで様子見します。

編集者:すずき(2024/09/01 14:59)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年8月27日

Milk-V Jupiterが届いた

目次: RISC-V

Milk-V Jupiterが届きました。お値段が非常に安かったのもあってM1/K1両方購入しました。注文したのは2か月くらい前で、何も音沙汰がなかったので忘れかけていましたが無事に届いて良かったです。

Jupiterの見た目はPCのMini-ITX規格マザーボードとほぼ一緒です。動かすためにはATX電源が必要なので別途用意してください。SoCはSpacemiT Key Stone M1/K1で、CPUはX60という独自コアが8コア搭載、RVA22のほかRVV 1.0にも対応しています。いいですね〜。


Milk-V Jupiter (Key Stone M1)


Milk-V Jupiter (Key Stone K1)

Key Stone M1とKey Stone K1の違いがよくわかりませんが、とりあえずM1はCPU 1.8GHz駆動でK1は CPU 1.6GHz駆動の違いがあるらしいです(Jupiter - Milk-V)。わかりやすい違いは見た目ですね。M1はヒートスプレッダが付いていて銀色のパッケージ、K1は樹脂のみで黒色のパッケージです。

SpacemiTのドキュメントは一応ある(Documentation - SpacemiT)のですが、ダウンロードできない形式になっていて不親切ですね……。イケてない。

Ubuntuのインストール

起動方法はSDカード、SSD、eMMCと複数ありますが簡単な方法はSDカードからの起動です。Milk-Vの公式サイトにある通りにインストールすれば良いです(Milk-V Jupiter Install OS Image - Milk-V)。OSイメージはUbuntuとFedoraとSpecemiT独自(?)のBianbu OSが用意されていますので、お好みで使うと良いと思います。私は使い慣れているUbuntuにしました。

SDカードに書き込むツールもRaspberry Piのときにお世話になったBalena Etcherを使います。なぜかUbuntuのバージョンは23.10(Mantic Minotaur)です。LTSではないUbuntuはサポート期限が短い(24.04リリースまでの9か月程度)ので、長期間の運用には向いていません。普通の人はしないと思いますけども。

CoreMarkを実行

新しいボード購入時の恒例、CoreMarkを実行します。まずはCPUの動作周波数を確認します。

CPU動作周波数の確認
katsuhiro@milkv-jupiter:~$ sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq

1800000

katsuhiro@milkv-jupiter:~$ sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq

614400

katsuhiro@milkv-jupiter:~$ sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq

1800000

CPUの動作周波数は0.614GHz〜1.8GHzのようですが、curは1.8GHz固定で変動している様子はありません。バグってる?固定?まあいいや、とりあえずこの値を信じましょう。

最初はシンプルにオプションOfastを試します。

CoreMark結果(GCC 13.2.0 -Ofast)
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 17322
Total time (secs): 17.322000
Iterations/Sec   : 6350.305969
Iterations       : 110000
Compiler version : GCC13.2.0
Compiler flags   : -Ofast -g
Memory location  : Please put data memory location here
                        (e.g. code in flash, data on heap etc)
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0x33ff
Correct operation validated. See README.md for run and reporting rules.
CoreMark 1.0 : 6350.305969 / GCC13.2.0 -Ofast -g / Heap

6350.305969 / 1800 = 3.52CM/MHzですね、正直言ってあまり速くないです。Cortex-A53より上、Cortex-A55より下といったところです。

RISC-Vは標準的な命令以外にも拡張命令が多数定義されています。なかでもbit manipulation命令はこの手のベンチマークには結構効き目がありますので、有効にして測ってみます。Zbc拡張は有効にしたら逆に遅くなったので外しています。

CoreMark結果(GCC 13.2.0 -Ofast、bit manipulation拡張ON)
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 16201
Total time (secs): 16.201000
Iterations/Sec   : 6789.704339
Iterations       : 110000
Compiler version : GCC13.2.0
Compiler flags   : -Ofast -g -march=rv64gc_zicsr_zifencei_zmmul_zba_zbb_zbs
Memory location  : Please put data memory location here
                        (e.g. code in flash, data on heap etc)
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0x33ff
Correct operation validated. See README.md for run and reporting rules.
CoreMark 1.0 : 6789.704339 / GCC13.2.0 -Ofast -g -march=rv64gc_zicsr_zifencei_zmmul_zba_zbb_zbs / Heap

6789.704339 / 1800 = 3.77CM/MHzです、だいぶ改善されてCortex-A55と同程度になりました。それでも速いとは言い難いですけど……。X60コア用にコンパイルするときはbit manipulation系の拡張命令は必須ですね。

編集者:すずき(2024/08/28 23:42)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年8月31日

Microsoftマウスが壊れた

3年前くらいに購入した(2021年3月6日の日記参照)Microsoft Basic Optical Mouseが壊れました。今までのマウスは左ボタンが壊れて勝手にダブルクリック病になっていましたが、今回はセンターホイールが壊れて下に回しているのに上にスクロールされたり、上に回しているのに下にスクロールされたりする症状が出ています。初めて出会う症状ですが、ダブルクリック病と同じくらいイライラします。


Microsoft Basic Optical Mouse分解

3年使ったものなので内部は埃だらけで若干お見苦しいですが、捨てる前に分解して内部の写真を撮りました。ボタンと逆側にあるねじ1本で留まっているだけで、分解はとても簡単です。内部の基板は極めてシンプルです。片面が茶色(レジストなし)、逆側が緑色(レジストあり)のちょっと変わった基板でした。両面レジストが普通だと思っていましたが、コストカットのためですかね?

さて次のマウスは何にしようかな〜と言いたいところですが、実は同じマウスがもう1つあるので引き続き2個目のMicrosoft Basic Optical Mouseを使います。

間違って2個買ったのではなく、あまりに安かったのですぐ壊れるかと思い2個買いました。でも蓋を開けてみれば3年も使えたし杞憂でしたね。1年あたりにすれば300円くらいで驚異のコストパフォーマンス、素晴らしい製品だと思います。Microsoftはこの価格で儲かっているのでしょうか……?

編集者:すずき(2024/09/01 15:01)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年9月13日

OpenSBIを調べる - OpenSBIとRISC-V ISA extensions

目次: Linux

今回はOpenSBIがRISC-Vの拡張機能をどのように認識し有効にするか調べます。

RISC-Vはたくさんの拡張命令と拡張機能が存在し、CPUやHWの実装によって対応する機能が異なります。そのためCPU/HWがRISC-Vのどの規格に対応しているのかを表す方法が必要です。RISC-Vの規格では命令セットと拡張機能をまとめて"rv64imafdc_aaa_bbb"のような文字列で表します。この文字列の名前がわからないのが困ったところですが、仕様書ではISA extensionsと書かれていることが多いようなので、以降はISA extensionsと表記します。

当初ISA extensionsは"rv64imafdc"のような「rv + ビット幅(32 or 64) + アルファベットの羅列(1文字=1つの拡張を表す)」だけの素朴なルールでしたが、際限なく増えるRISC-Vの拡張機能はこんなルールでは表せません。現在は"rv64imafdc_aaa_bbb_ccc"のようなアンダースコア + 拡張名を列車のように繋げるルール(RISC-V Unprivileged Architecture: Chapter 36. ISA Extension Naming Conventions)が採用されています。

例えばQEMUの仮想CPUのISA extensionsを見ると、

QEMUの仮想CPUのISA extensions
rv64imafdch_zic64b_zicbom_zicbop_zicboz_
ziccamoa_ziccif_zicclsm_ziccrse_
zicntr_zicsr_zifencei_zihintntl_
ihintpause_zihpm_za64rs_zawrs_
zfa_zca_zcd_zba_
zbb_zbc_zbs_ssccptr_
sscounterenw_sstc_sstvala_sstvecd_
svadu

本来はとても長い1行ですが、見づらいため4つごとに改行を入れています。もはやISA extensionsは魔法の呪文か暗号の様相を呈していて、どこか一文字だけ間違えていたとしても気付ける自信がありません。

OpenSBIが拡張機能を認識する方法

拡張機能の認識方法を調べます。答えを先に書くとデバイスツリーのcpuノードのriscv,isaプロパティの長い長い文字列を頭から解析しています。割と力技でした。

デバイスツリーのCPUノード、riscv,isaプロパティの例

/ {
	cpus {
		cpu0: cpu@0 {
			device_type = "cpu";
			reg = <0>;
			compatible = "riscv";
			riscv,isa-base = "rv64i";
			riscv,isa = "rv64imafdc_zicsr_zifencei_zba_zbb_zbs";  //★★これ★★

			status = "okay";
			//...

ISA extensionsの文字列解析をする関数はfdt_parse_isa_one_hart()という関数です。

fdt_parse_isa_one_hart()関数の呼び出し履歴
sbi_init @ lib/sbi/sbi_init.c
  init_coldboot @ lib/sbi/sbi_init.c
    sbi_hart_init @ lib/sbi/sbi_hart.c
      hart_detect_features @ lib/sbi/sbi_hart.c
        sbi_platform_extensions_init @ include/sbi/sbi_platform.h
          sbi_platform_ops(plat)->extensions_init(hfeatures);
          -> generic_extensions_init @ platform/generic/platform.c
            fdt_parse_isa_extensions @ lib/utils/fdt/fdt_helper.c
              fdt_parse_isa_all_harts @ lib/utils/fdt/fdt_helper.c
                fdt_parse_isa_one_hart @ lib/utils/fdt/fdt_helper.c

GenericプラットフォームをQEMU用のデバイスツリーで動作させた際の呼び出し経路はこんな感じです。3つ上位のfdt_parse_isa_all_harts()関数を見ると、

ISA extensionsを解析する処理と結果を格納する部分のコード

// opensbi/platform/generic/platform.c

static int generic_extensions_init(struct sbi_hart_features *hfeatures)
{
	int rc;

	//★★第3引数hfeatures->extensionsにISA extensionsの解析結果を書き込む★★
	//★★hfeaturesはscratch領域のhart_features_offsetバイト目、手元の環境だと192バイト目★★

	/* Parse the ISA string from FDT and enable the listed extensions */
	rc = fdt_parse_isa_extensions(fdt_get_address(), current_hartid(),
				      hfeatures->extensions);

	if (rc)
		return rc;

	if (generic_plat && generic_plat->extensions_init)
		return generic_plat->extensions_init(generic_plat_match,
						     hfeatures);

	return 0;
}


// opensbi/lib/utils/fdt/fdt_helper.c

int fdt_parse_isa_extensions(void *fdt, unsigned int hartid,
			unsigned long *extensions)
{
	int rc, i;
	unsigned long *hart_exts;
	struct sbi_scratch *scratch;

	if (!fdt_isa_bitmap_offset) {
		fdt_isa_bitmap_offset = sbi_scratch_alloc_offset(
					sizeof(*hart_exts) *
					BITS_TO_LONGS(SBI_HART_EXT_MAX));
		if (!fdt_isa_bitmap_offset)
			return SBI_ENOMEM;

		//★★この関数がISA extensionsの解析結果を置く場所は★★
		//★★scratch領域 + fdt_isa_bitmap_offsetの場所★★
		rc = fdt_parse_isa_all_harts(fdt);
		if (rc)
			return rc;
	}

	scratch = sbi_hartid_to_scratch(hartid);
	if (!scratch)
		return SBI_ENOENT;

	//★★scratch領域 + fdt_isa_bitmap_offsetの場所を取得する★★
	hart_exts = sbi_scratch_offset_ptr(scratch, fdt_isa_bitmap_offset);

	//★★ISA extensionsの解析結果は、hfeatures->extensionsに全てまとめられる★★
	for (i = 0; i < BITS_TO_LONGS(SBI_HART_EXT_MAX); i++)
		extensions[i] |= hart_exts[i];
	return 0;
}


// opensbi/lib/utils/fdt/fdt_helper.c

static int fdt_parse_isa_all_harts(void *fdt)
{
	u32 hartid;
	const fdt32_t *val;
	unsigned long *hart_exts;
	struct sbi_scratch *scratch;
	int err, cpu_offset, cpus_offset, len;

	if (!fdt || !fdt_isa_bitmap_offset)
		return SBI_EINVAL;

	cpus_offset = fdt_path_offset(fdt, "/cpus");
	if (cpus_offset < 0)
		return cpus_offset;

	fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
		err = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
		if (err)
			continue;

		if (!fdt_node_is_enabled(fdt, cpu_offset))
			continue;

		//★★device treeのriscv,isaプロパティを見る★★
		val = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
		if (!val || len <= 0)
			return SBI_ENOENT;

		scratch = sbi_hartid_to_scratch(hartid);
		if (!scratch)
			return SBI_ENOENT;

		//★★解析結果を置く場所はscratch領域 + fdt_isa_bitmap_offsetの場所★★
		hart_exts = sbi_scratch_offset_ptr(scratch,
						   fdt_isa_bitmap_offset);

		//★★riscv64imafdc_zicsr_zifencei_...のような文字列を解析する★★
		err = fdt_parse_isa_one_hart((const char *)val, hart_exts);
		if (err)
			return err;
	}

	return 0;
}

デバイスツリーのcpusノードを探して、子ノード(cpu@0など)のriscv,isaプロパティを読み出して、文字列解析するfdt_parse_isa_one_hart()関数に渡していることがわかります。

解析結果はscratch領域(OpenSBIのhartごとの情報を保持しておくメモリ領域、スタック領域の末尾に確保される)のfdt_isa_bitmap_offsetに置かれ、最終的には別のscratch領域にあるfeatures->extensionsにまとめられます。scratch領域の詳細が気になるところですが、また別の機会に調べることにします。

OpenSBIが拡張機能を有効にする方法

拡張機能はリセット直後は無効になっているものもあるので、有効にする必要があります。RISC-V Privileged Architectureではmenvcfgというレジスタがあり、適切なビットフィールドに値をセットして機能の有効/無効を切り替える場合があります。有効/無効が設定できない機能もあって、統一感がないです……。

例えばS-mode用のタイマーコンペアレジスタ(stimecmpレジスタ)を定義しているSSTC拡張では、menvcfgのビット63 STCE(STimecmp Enable)フィールドに1をセットすると機能が有効になります。機能を有効にせずstimecmpにアクセスするとillegal instruction例外が発生します。

OpenSBIのコードでmenvcfgレジスタに値を設定する関数は下記のmstatus_init()です。

拡張機能を有効にするためmenvcfgレジスタに値を設定するコード

// opensbi/lib/sbi/sbi_hart.c

/**
 * Check whether a particular hart extension is available
 *
 * @param scratch pointer to the HART scratch space
 * @param ext the extension number to check
 * @returns true (available) or false (not available)
 */
bool sbi_hart_has_extension(struct sbi_scratch *scratch,
			    enum sbi_hart_extensions ext)
{
	struct sbi_hart_features *hfeatures =
			sbi_scratch_offset_ptr(scratch, hart_features_offset);

	if (__test_bit(ext, hfeatures->extensions))
		return true;
	else
		return false;
}

static void mstatus_init(struct sbi_scratch *scratch)
{
	int cidx;
	unsigned long mstatus_val = 0;
	unsigned int mhpm_mask = sbi_hart_mhpm_mask(scratch);
	uint64_t mhpmevent_init_val = 0;
	uint64_t menvcfg_val, mstateen_val;

//...

	if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_12) {
		menvcfg_val = csr_read(CSR_MENVCFG);
#if __riscv_xlen == 32
		menvcfg_val |= ((uint64_t)csr_read(CSR_MENVCFGH)) << 32;
#endif

#define __set_menvcfg_ext(__ext, __bits)				\
		if (sbi_hart_has_extension(scratch, __ext))		\
			menvcfg_val |= __bits;

		/*
		 * Enable access to extensions if they are present in the
		 * hardware or in the device tree.
		 */

		//★★sbi_hart_has_extension()関数で拡張機能の一覧hfeatures->extensionsのビットをテストする★★
		//★★拡張機能が存在しているなら、menvcfgの相当するビットをセットする★★
		__set_menvcfg_ext(SBI_HART_EXT_ZICBOZ, ENVCFG_CBZE)
		__set_menvcfg_ext(SBI_HART_EXT_ZICBOM, ENVCFG_CBCFE)
		__set_menvcfg_ext(SBI_HART_EXT_ZICBOM,
				  ENVCFG_CBIE_INV << ENVCFG_CBIE_SHIFT)
#if __riscv_xlen > 32
		__set_menvcfg_ext(SBI_HART_EXT_SVPBMT, ENVCFG_PBMTE)
#endif
		__set_menvcfg_ext(SBI_HART_EXT_SSTC, ENVCFG_STCE)
		__set_menvcfg_ext(SBI_HART_EXT_SMCDELEG, ENVCFG_CDE);
		__set_menvcfg_ext(SBI_HART_EXT_SVADU, ENVCFG_ADUE);

#undef __set_menvcfg_ext

		/*
		 * When both Svade and Svadu are present in DT, the default scheme for managing
		 * the PTE A/D bits should use Svade. Check Svadu before Svade extension to ensure
		 * that the ADUE bit is cleared when the Svade support are specified.
		 */

		if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SVADE))
			menvcfg_val &= ~ENVCFG_ADUE;

		csr_write(CSR_MENVCFG, menvcfg_val);    //★★menvcfgを設定、拡張機能が有効になる★★
#if __riscv_xlen == 32
		csr_write(CSR_MENVCFGH, menvcfg_val >> 32);
#endif

		/* Enable S-mode access to seed CSR */
		if (sbi_hart_has_extension(scratch, SBI_HART_EXT_ZKR)) {
			csr_set(CSR_MSECCFG, MSECCFG_SSEED);
			csr_clear(CSR_MSECCFG, MSECCFG_USEED);
		}
	}

	/* Disable all interrupts */
	csr_write(CSR_MIE, 0);

	/* Disable S-mode paging */
	if (misa_extension('S'))
		csr_write(CSR_SATP, 0);
}

以上がOpenSBIによって拡張機能が認識&有効になる仕掛けです。ISA extensionsを間違えるとこの仕組みは動かないので、ISA extensionsの長くて難しくて間違いやすい記述はどうすれば良いの?と疑問が湧きます。しかしその答えはOpenSBIにはなさそうですね……。

ちなみにmenvcfgの詳細はPrivileged Architecture(GitHubにソースコードがあります、PDFはReleasesからダウンロード可能)に記載されています。なんちゃら拡張が使う予定のビットフィールドなのでそちらを参照せよと書いていることも多く、各々の拡張機能の仕様書を行脚することになるでしょう。

編集者:すずき(2024/09/17 19:26)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2024年8月14日 >>> 2024年9月13日
link もっと後

管理用メニュー

link 記事を新規作成

<2024>
<<<08>>>
----123
45678910
11121314151617
18192021222324
25262728293031

最近のコメント5件

  • link 24年10月1日
    すずきさん (10/06 03:41)
    「xrdpで十分動作しているので、Wayl...」
  • link 24年10月1日
    hdkさん (10/03 19:05)
    「GNOMEをお使いでしたら今はWayla...」
  • link 24年10月1日
    すずきさん (10/03 10:12)
    「私は逆にVNCサーバーに繋ぐ使い方をした...」
  • link 24年10月1日
    hdkさん (10/03 08:30)
    「おー、面白いですね。xrdpはすでに立ち...」
  • link 14年6月13日
    2048player...さん (09/26 01:04)
    「最後に、この式を出すのに紙4枚(A4)も...」

最近の記事3件

  • link 24年10月3日
    すずき (10/06 01:33)
    「[Ubuntu 20.04 LTSでxrdpのエラーを再現できるか挑戦] 目次: Linux先日(2024年10月1日の日記参...」
  • link 23年4月10日
    すずき (10/05 15:09)
    「[Linux - まとめリンク] 目次: Linux関係の深いまとめリンク。目次: RISC-V目次: ROCK64/ROCK...」
  • link 24年10月2日
    すずき (10/05 15:08)
    「[VirtualBoxでxrdpのエラーを再現できるか挑戦] 目次: Linux昨日(2024年10月1日の日記参照)のUbu...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 10/06 03:41