コグノスケ


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

link もっと前
2023年7月24日 >>> 2023年7月11日
link もっと後

2023年7月24日

OpenOCDで独自のCSRを追加してアクセスする

目次: OpenOCD

OpenOCDにRISC-Vの独自(もしくは標準に準拠しているものの新しすぎるなど)のCSR(Control and Status Register)を定義してアクセスする方法をメモしておきます。

前回はexpose_csrsを使って独自のレジスタを定義しました。この機能はOpenOCDの改造が不要で手軽な反面、2つの問題があります。1つ目の問題はSMPモードだと使えないことで、SMPモードと併用すると下記のように怒られCSRにアクセスできません。

SMPモードとexpose_csrsを併用したときの警告
Warn : Register csrNNN does not exist in riscv.cpu.0, which is part of an SMP group where this register does exist.

2つ目の問題点は名前がわかりづらいことです。csrNNNのようなほぼ番号同然の名前を暗記するのは正直言って辛いですよね。

独自のCSRを定義

CSR名を新たに追加するにはOpenOCDにパッチを当てて、再ビルドする必要があります。OpenOCDのビルド方法は以前書きました(2023年6月28日の日記参照)のでそちらに任せるとして、今回はパッチについて紹介しましょう。

前回同様、題材はRNMI CSRを使います。RISC-V Privileged Architectures V20211203(RISC-V Instruction Set Manual の2023-05-23のリリースページからダウンロードできます)を見ると、RNMIでは4つのCSRが定義されています。


Resumable NMI CSR

書き起こしておくと、

  • 0x740: mnscratch
  • 0x741: mnepc
  • 0x742: mncause
  • 0x744: mnstatus

となります。OpenOCDを変更すべき箇所はsrc/target/riscv/encoding.hというヘッダファイルだけです。

OpenOCDにRNMI CSRを追加するパッチ

diff --git a/src/target/riscv/encoding.h b/src/target/riscv/encoding.h
index c2da4e676..6c3f9cc12 100644
--- a/src/target/riscv/encoding.h
+++ b/src/target/riscv/encoding.h
@@ -2992,6 +2992,10 @@
 #define CSR_PMPADDR61 0x3ed
 #define CSR_PMPADDR62 0x3ee
 #define CSR_PMPADDR63 0x3ef
+#define CSR_MNSCRATCH 0x740
+#define CSR_MNEPC 0x741
+#define CSR_MNCAUSE 0x742
+#define CSR_MNSTATUS 0x744
 #define CSR_MSECCFG 0x747
 #define CSR_TSELECT 0x7a0
 #define CSR_TDATA1 0x7a1
@@ -4714,6 +4718,10 @@ DECLARE_CSR(pmpaddr60, CSR_PMPADDR60)
 DECLARE_CSR(pmpaddr61, CSR_PMPADDR61)
 DECLARE_CSR(pmpaddr62, CSR_PMPADDR62)
 DECLARE_CSR(pmpaddr63, CSR_PMPADDR63)
+DECLARE_CSR(mnscratch, CSR_MNSCRATCH)
+DECLARE_CSR(mnepc, CSR_MNEPC)
+DECLARE_CSR(mncause, CSR_MNCAUSE)
+DECLARE_CSR(mnstatus, CSR_MNSTATUS)
 DECLARE_CSR(mseccfg, CSR_MSECCFG)
 DECLARE_CSR(tselect, CSR_TSELECT)
 DECLARE_CSR(tdata1, CSR_TDATA1)

CSR番号とDECLARE_CSRを追加するだけで良いみたいです。さすがOpenOCD便利な作りですね。

NS31を使って動作確認

前回同様、RNMIを実装しているCPUの例としてNSITEXE NS31を用いてRNMI CSRを読み出してみましょう。

新たに追加したCSR名を指定してNS31のRNMI CSRを読み出す
(gdb) info reg mnscratch mnepc mncause mnstatus

mnscratch      0x0      0
mnepc          0x0      0
mncause        0x80000000       -2147483648
mnstatus       0x8      8

無事読み出すことができました。やはり名前が付いているとわかりやすいですね。

編集者:すずき(2023/09/24 09:19)

コメント一覧

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



2023年7月20日

RISC-Vも完璧じゃない

目次: RISC-V

RISC-Vは最後発の命令セットだけあって、従来の命令セットで評判の悪かった部分は改善されている場合が多いです。しかし人の作るものですからミスや見落としはあります。

例としてわかりやすいのがRV64I命令セットの32bit unsignedと64bit unsigned加算処理です。下記のようなコードを書いたとします。

32bit unsignedと64bit unsigned加算処理のサンプルコード

unsigned int __attribute__((noinline)) something(int n)
{
	return n * n;
}

int test(unsigned int num)
{
	unsigned long long sum = 0;

	for (int i = 0; i < num; i++) {
		sum += something(i);    //32bit unsigned + 64bit unsigned
	}

	return sum;
}

下記のようにコンパイルします。RV64GCはRV64IMAFDCの略(M: Multiplication and Division, A: Atomic, F: Single-Precision Floating-Point, D: Double-Precision Floating-Point, C: Compressed)です。RV64I以外のMAFDCの各命令も出てきますが、話題と関係ないので気にしないでください。RV64GCが基本的な命令セットくらいの認識でOKです。

RV64GCでコンパイル
$ riscv64-unknown-elf-gcc -g -O2 -march=rv64gc -mabi=lp64d -c -o rv64gc.o a.c

逆アセンブルを見ると変なシフト命令(アドレス24, 26)が2つ出力されます。

RV64GCを使用したときの逆アセンブル

000000000000001a <.L5>:
                sum += something(i);
  1a:   8522                    mv      a0,s0         # s0: i, s1: sum
  1c:   00000097                auipc   ra,0x0
  20:   000080e7                jalr    ra            # call something()
  24:   1502                    slli    a0,a0,0x20    # a0: something() の返り値
  26:   9101                    srli    a0,a0,0x20    # shift x 2で上位32ビットを0埋め
        for (int i = 0; i < num; i++) {
  28:   2405                    addiw   s0,s0,1
                sum += something(i);
  2a:   94aa                    add     s1,s1,a0      # shift x 2 + add
        for (int i = 0; i < num; i++) {
  2c:   ff2417e3                bne     s0,s2,1a <.L5>

RV64Iには32bit unsigned向けの加算命令がなく、32bit unsignedを64bit unsignedにゼロ拡張してから加算する必要があるためです。さらに悲しいことにゼロ拡張する命令もなく、32bit左シフト命令+32bit右論理シフト命令でゼロ拡張するヘボい処理になります。

SiFiveあなたもか

シフト命令2つくらい何だというのか?ケチケチするなよ?という感覚が普通かもしれませんが、余計な命令が出ると特にローエンドのCPUでは性能への影響が無視できません。どうやらCoreMarkのような典型的なベンチマークにも影響が出ていたようで、

SiFiveが公開しているCoreMarkの型定義(一部抜粋)

// GitHub: sifive/benchmark-coremark
// freedom-metal/core_portme.h

typedef signed short ee_s16;
typedef unsigned short ee_u16;
typedef signed int ee_s32;
typedef double ee_f32;
typedef unsigned char ee_u8;
typedef signed int ee_u32;     //★★★u32なのに "signed" intになっている★★★
typedef signed long ee_u64;    //★★★u64なのに "signed" longになっている★★★
#if __riscv_xlen == 32
typedef ee_u32 ee_ptr_int;
#else
typedef ee_u64 ee_ptr_int;
#endif
typedef signed int ee_size_t;

RISC-Vの盟主たるSiFiveすらも「unsigned型をsigned型にすりかえて性能を上げるぞい!」というCoreMarkハックを行っていた(該当箇所へのリンク)ほどです……。

RISC-Vパッチワーク

当然RV64Iのまずい点はRISC-Vの方々も気づいており、B拡張(Bit-manipulation extensions)を追加したときに上記の問題は修正されました(RISC-V Bitmanipulation extension規格書へのリンク)。

B拡張はZba, Zbb, Zbc, Zbsの4つがあります。

  • Zba: Address generation instructions
  • Zbb: Basic bit-manipulation
  • Zbc: Carry-less multiplication
  • Zbs: Single-bit instructions

この中のZba拡張にて32bit unsigned加算命令であるadd.uw命令が追加されました。他にも1, 2, 3bitシフト&加算命令なんかも追加されています。unsigned加算や1, 2, 3bitシフト&加算は配列の要素のアドレスを計算する際に頻出で、Address generation instructionsというグループ名にしたのでしょう。

Zba拡張を使うとどのように改善されるか確認します。

RV64GCとZba拡張でコンパイル
$ riscv64-unknown-elf-gcc -g -O2 -march=rv64gc_zba -mabi=lp64d -c -o rv64gcb.o a.c

逆アセンブルを見ると変なシフト命令は消滅し、新たにadd.uw命令が出力されていることが分かると思います。

RV64GCとZba拡張を使用したときの逆アセンブル結果

000000000000001a <.L5>:
                sum += something(i);
  1a:   8522                    mv      a0,s0       # s0: i, s1: sum
  1c:   00000097                auipc   ra,0x0
  20:   000080e7                jalr    ra          # call something()
        for (int i = 0; i < num; i++) {
  24:   2405                    addiw   s0,s0,1
                sum += something(i);
  26:   089504bb                add.uw  s1,a0,s1    # shift x 2は消滅、add.uwのみ
        for (int i = 0; i < num; i++) {
  2a:   ff2418e3                bne     s0,s2,1a <.L5>

めでたしめでたし。なんですけど、人によっては色々言いたいこともあると思います。Bit-manipulationとAddress generation全然関係ないぞ?とかね。

しかし冒頭にも書いたとおり、何事も最初から完璧なものはないです。命令セットが汚くなっていくのはRISC-Vが実用段階に入った証であり、むしろ良いことだと個人的には思います。

編集者:すずき(2023/07/23 17:11)

コメント一覧

  • hdkさん(2023/07/21 22:45)
    x86脳なので、mov %eax,%eax (32ビット→ゼロ拡張64ビット) とか、movzwl %ax,%eax (16ビット→ゼロ拡張32ビット) とか、そういうのに相当する何かがありそうに思ってしまいますが、わざわざシフト命令2個生成されるところをみると、ないんですね... intとintptr_tのサイズが同じならよかったんでしょうけど、違うと確かに厳しそう...
  • すずきさん(2023/07/23 17:10)
    x86はもちろん、先代であるMIPSにさえこの手のミスはないらしい(詳しくは知らない)んですが、RISC-Vは命令削減にこだわり過ぎたのか、見落としたのかなんだか知らんのですが、ミスってるんですよねー……。
open/close この記事にコメントする



2023年7月14日

AndesのCPUコアが搭載されたRISC-V SoCボードを購入

目次: RISC-V

先日6月14日に発売開始されたRenesas RZ/Five(R9A07G043F01GBG)搭載のボードAP-RZFV-0A製品紹介サイトへのリンク)を購入しました。

SoCはRenesas製で、CPUコアは台湾Andes TechnologyのAX45MP(製品紹介サイトへのリンク)です。

追加部品を購入

ボードだけ購入するとACアダプタが付属していません。全部入りが良ければLinux開発キットを併せて購入すると良いかと思います。

秋月にて5VセンタープラスのACアダプタATS012S-W050U(製品紹介サイトへのリンク)を購入しました。700円です。安い。何も考えず2A出力のアダプタにしましたが、出力が足りなかったらまた考えます。

ボード上のJTAG端子CN3を見ると、ハーフピッチと呼ばれる1.27mm間隔の10ピンヘッダでした。このヘッダに接続できるJTAGケーブルを持っていないので、Strawberry LinuxにてJTAG変換基盤ARM-JTAG-20-10(製品紹介サイトへのリンク)を購入しました。800円くらいです。これも安い。

電源に関してはACアダプタ以外にも、安定化電源やUSBから取る方法(ジャンパ端子J18を半田付けでショートさせる必要あり)があります。ボードのマニュアルをご参照ください。

JTAGを繋ぐ

JTAGコネクタCN3にJTAG変換基盤ARM-JTAG-20-10のハーフピッチコネクタを接続します。ケーブルの赤い線が1番ピン側(ボード上の白い三角マークがある、LANコネクタなどがある方)です。写真も載せておきます。


AP-RZFV-0A CN3にJTAGケーブルを接続

ボードのマニュアルを見るとわかりますが、SoCにDEBUGENという端子があり [1]DebugModeと [0]NormalMode(出荷時設定)があるそうです。ボード上のDIPスイッチ(SW2の3番)をOFFにするとDebugModeに切り替わりJTAGが繋がるようになります。

OpenOCDにて接続

お持ちのJTAGによって設定がやや違いますが、SEGGER J-Linkの場合はOpenOCDの設定ファイルはこんな感じです。

OpenOCD設定ファイルfor RZ/Five
adapter speed 1000
reset_config trst_and_srst
 
set _CHIPNAME riscv
set _DAP_TAPID 0x1000563d
 
jtag newtap $_CHIPNAME dap -irlen 5 -ircapture 0x01 -irmask 0x03 \
        -expected-id $_DAP_TAPID
 
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME.0 riscv -chain-position $_CHIPNAME.dap -coreid 0

設定をファイルに保存したら、J-Linkの設定ファイルとともに指定して起動しましょう。

OpenOCD起動ログ
$ sudo ./src/openocd -c 'bindto 0.0.0.0' -f tcl/interface/jlink.cfg -f ~/openocd_renesas_rzv.cfg

Open On-Chip Debugger 0.11.0+dev-00551-gaad871805 (2022-01-16-22:30)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
0
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : J-Link V11 compiled Jul  3 2020 10:47:34
Info : Hardware version: 11.00
Info : VTarget = 1.812 V
Info : clock speed 1000 kHz
Info : JTAG tap: riscv.dap tap/device found: 0x1000563d (mfg: 0x31e (Andes Technology Corporation), part: 0x0005, ver: 0x1)
Info : datacount=4 progbufsize=8
Info : Examined RISC-V core; found 1 harts
Info :  hart 0: XLEN=64, misa=0x800000000094312d
Info : starting gdb server for riscv.cpu.0 on 3333
Info : Listening on port 3333 for gdb connections

無事CPUが認識されました。よきかなよきかな。

編集者:すずき(2023/07/19 08:54)

コメント一覧

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



2023年7月13日

PHP 8への道のり

目次: 自宅サーバー

この日記システムをPHPの最新バージョンPHP 8に対応させました。

きっかけはさくらインターネットから「PHP 5を使うのは危険だよ」というメールが来たことです。PHP 5.6のEOLは2018年なので5年くらい放置していたんですね。さすがにサボりすぎました。

PHP 5とPHP 7は互換性が保たれていて(PHP 6は欠番らしい)おり1文字も変更することなくPHPのバージョンアップに対応できました。ところがPHP 8は古い機能を色々と廃止したようで全く動きませんでした。

PHP 8で動かなくなった機能達

PHP 8で動かなくなった機能達のエラーメッセージや直し方(正しいかどうか知らない)を順不同で紹介したいと思います。

get_magic_quotes_gpc() 関数は廃止
PHP Fatal error:  Uncaught Error: Call to undefined function get_magic_quotes_gpc()

この関数は説明を見ても常にfalseを返すと書いてあり、もはや存在しようがしなかろうが呼ぶ意味がありません。この関数を呼んでいるコードごと消しました。

クラスのコンストラクタが曲者でした。PHP 7までクラスと同名の関数がコンストラクタ扱いされましたが、PHP 8から __construct() がコンストラクタ扱いされます。この変更の影響であらゆるクラスの初期化が実行されなくなって、訳のわからないエラーを引き起こしました。デバッグが一番面倒くさかったです。

波括弧のオフセット指定は廃止
PHP Fatal error:  Array and string offset access syntax with curly braces is no longer supported

PHP 8では波括弧 {} によるオフセットの指定が廃止されたので、角括弧 [] に置き換える必要があります。難しくはないですが、地味に使っている箇所が多く修正が大変でした……。

each() 関数は廃止
PHP Fatal error:  Uncaught Error: Call to undefined function each()

PHP 8ではeach() 関数が廃止されました。これも複数ヶ所で使っていて修正が面倒でした。

修正例

// 修正前
reset($array);
list($a, $b) = each($array);

// 修正後
reset($array);
$a = key($array);
$b = current($array);

上記のように先頭のキーと値を取り出すためだけに使っていたので、単純にkey() とcurrent() 関数で書き換えました。

mb_strrpos() の引数
PHP Fatal error:  Uncaught TypeError: mb_strrpos(): Argument #3 ($offset) must be of type int, string given

PHP 7はmb_strrpos() 関数の3番目の引数(offsetの位置)にencodeを指定してもエラーにならなかったのですが、PHP 8ではoffset, encodeを指定しないとエラーになるようです。PHPは良くわかりませんなあ。

編集者:すずき(2024/01/13 14:29)

コメント一覧

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



2023年7月12日

自宅のサーバーとPHP

目次: 自宅サーバー

自宅のファイルサーバー兼WebサーバーでPHPが動かなくなっていました。

素のPHP 8すら動かないので、おそらくPHP 5の寿命が尽きたときにPHP周りの設定が全部吹っ飛んで動かなくなったと思われます。自宅のWebサーバーは自宅から見えないので、長らく気づいていませんでした……。あれまあ。

まずはPHP CGIや日記システムで使っているGDやmbstringをインストールします。

PHPのインストール
# apt-get install php-cgi php-gd libapache2-mod-php8.2 php8.2-mbstring

Apache 2の設定ファイルを変更してPHP 8.2を有効にします。

Apache 2でPHP 8.2を有効にする
# cd /etc/apache2/mods-enabled
# ln -s ../mods-available/php8.2.conf
# ln -s ../mods-available/php8.2.load

# systemctl restart apache2

Apache 2はユーザーディレクトリといって /home/username/public_html/ ディレクトリに置いたファイルが、URL /~username/ で見える仕組みがありまして、日記システムはユーザーディレクトリに配置しています。

初期状態のphp8.2.confだとユーザーディレクトリの配下にあるPHPスクリプトは動きません。わざと無効化してあります。

php 8.2のユーザーディレクトリの設定

# /etc/apache2/mods-enabled/php8.2.conf

#...略...

# Running PHP scripts in user directories is disabled by default
#
# To re-enable PHP in user directories comment the following lines
# (from <IfModule ...> to </IfModule>.) Do NOT set it to On as it
# prevents .htaccess files from disabling it.
<IfModule mod_userdir.c>
    <Directory /home/*/public_html>
        php_admin_flag engine Off
    </Directory>
</IfModule>

コメントにある通りIfModuleタグごと全てコメントにして、Apache 2を再起動しましょう。これできっとPHP 8が動くはずです。

編集者:すずき(2024/01/13 14:29)

コメント一覧

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



link もっと前
2023年7月24日 >>> 2023年7月11日
link もっと後

管理用メニュー

link 記事を新規作成

<2023>
<<<07>>>
------1
2345678
9101112131415
16171819202122
23242526272829
3031-----

最近のコメント5件

  • link 21年9月20日
    すずきさん (11/19 01:04)
    「It was my pleasure.」
  • link 21年9月20日
    whtさん (11/17 23:41)
    「This blog solves my ...」
  • 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サーバーに繋ぐ使い方をした...」

最近の記事20件

  • link 23年4月10日
    すずき (11/15 23:48)
    「[Linux - まとめリンク] 目次: Linux関係の深いまとめリンク。目次: RISC-V目次: ROCK64/ROCK...」
  • link 24年11月6日
    すずき (11/15 23:47)
    「[Ubuntu 24.04 LTS on ThinkPad X1 Carbon Gen 12] 目次: Linux会社ではTh...」
  • link 24年11月11日
    すずき (11/15 23:26)
    「[Pythonのテストフレームワーク] 目次: Python最近Pythonを触ることが増えたのでテストについて調べようと思い...」
  • link 24年11月2日
    すずき (11/15 23:25)
    「[Python - まとめリンク] 目次: Python一覧が欲しくなったので作りました。 スクリプト言語始めました(Pyth...」
  • link 20年5月10日
    すずき (11/15 23:24)
    「[Pythonの文字置換APIは変な名前] 目次: PythonPythonの文字列置換は "string".replace(...」
  • link 24年2月7日
    すずき (11/15 23:23)
    「[複数の音声ファイルのラウドネスを統一したい] 目次: PythonPCやデジタル音楽プレーヤーで音楽を聞いていると、曲によっ...」
  • link 13年7月2日
    すずき (11/15 23:22)
    「[スクリプト言語始めました(PythonとRubyでNクイーン問題)] 目次: ベンチマーク目次: Pythonスクリプト言語...」
  • link 23年9月18日
    すずき (11/15 23:22)
    「[一覧の一覧 - まとめリンク] 一覧の一覧、まとめのまとめが欲しくなったので作りました。OS、アーキテクチャ系。目次: An...」
  • link 13年10月1日
    すずき (11/15 23:21)
    「[JetBrains PyCharm 3.0リリース] 目次: PythonPyCharmがメジャーアップデートされ PyCh...」
  • link 22年7月8日
    すずき (11/08 23:28)
    「[マンガ紹介 - まとめリンク] 目次: マンガ紹介面白かった漫画の紹介です。知名度はあまり気にせず紹介します。5作品乙女ゲー...」
  • link 24年10月31日
    すずき (11/04 15:17)
    「[DENSOの最終勤務日] 最終勤務日でした、入門カードや会社のPCを返却してきました。在籍期間はNSITEXE(品川のオフィ...」
  • link 24年10月30日
    すずき (11/02 20:33)
    「[マンガ紹介] 目次: マンガ紹介お気に入りのマンガ紹介シリーズ。最近完結した短めの作品を紹介します。マイナススキル持ち四人が...」
  • link 19年3月28日
    すずき (11/02 13:27)
    「[マンガ紹介] 目次: マンガ紹介お気に入りのマンガ紹介シリーズ。こわもてかわもて(全2巻、2019年)(アマゾンへのリンク)...」
  • link 21年6月20日
    すずき (11/02 13:22)
    「[読書一生分が93万円?] 目次: マンガ紹介書籍通販のhontoがこんなキャンペーンをやっています。honto読書一生分プレ...」
  • link 17年10月27日
    すずき (11/02 13:11)
    「[異世界&最強系漫画の種類] 目次: マンガ紹介少し前にアニメ化されて盛り上がって(おそらく負の方向に…)いた「...」
  • link 24年10月28日
    すずき (10/30 23:49)
    「[Linuxからリモートデスクトップ] 目次: Linux開発用のLinuxマシンの画面を見るにはいろいろな手段がありますが、...」
  • link 24年10月24日
    すずき (10/25 02:35)
    「[ONKYOからM-AUDIOのUSB DACへ] 目次: PCかれこれ10年以上(2013年3月16日の日記参照)活躍してく...」
  • link 24年7月25日
    すずき (10/25 02:24)
    「[OpenSBIを調べる - デバイスツリーの扱い(別方法)] 目次: LinuxOpenSBIのブート部分を調べます。Ope...」
  • link 24年8月7日
    すずき (10/25 02:23)
    「[Debian独自の挙動をするQEMUとbinfmt_misc] 目次: Linux前回はbinfmt_miscの使い方や動作...」
  • link 24年9月9日
    すずき (10/25 02:22)
    「[GDBの便利コマンド] 目次: LinuxGDBは便利ですが、少し使わないでいるとあっという間にコマンドを忘れます。便利&使...」
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

最終更新: 11/19 01:04