NetBSD/armでcfi

ルーター系のモジュールのストレージはSPIかCFIのFlashが多いです。

NetBSDのcfiのサポートコードはsys/dev/norの下にあります。

実際つかっているターゲットを調べてみます。

```
% cd sys/arch
% grep -dskip ^cfi */conf/*
evbmips/conf/CPMBR1400:cfi0             at mainbus0
evbppc/conf/MPC8536DS:cfi0              at obio0 cs 0
evbppc/conf/P2020DS:cfi0                at obio0 cs 0
evbppc/conf/P2020RDB:cfi0               at obio0 cs 0
evbppc/conf/RB800:cfi0          at obio0 cs 0
evbppc/conf/TWRP1025:cfi0               at obio0 cs 0
```

evbmipsはRalinkのRT3883でそれ以外はPowerPCでarmでサポートしているターゲットはありません。

RT2880はcfiだけでRT3050からはcfiとspi両方使えてspiの方が多くなったきがしますし、Ralinkのほぼ最後のプロダクトのRT3883ではほとんどspiだったのではないでしょうか。

試しにRalinkのコードをベースにComcertoに追加してみて、とりあえず動きました。

https://dmesgd.nycbug.org/index.cgi?do=view&id=6847

mainbusにぶら下げていますが、memory tagは自前のをつかっています。mainbusのmemory tagを使うとうまくいかなくて、半日くらいはまりました。

カーネルのコンフィグレーションはこうしてます。

```
# NOR Flash
#options        NOR_VERBOSE
cfi0            at mainbus?
nor0            at cfi0
flash0          at nor0 offset 0x00000000 size 0x00040000 readonly 1 # U-boot
```

FreeBSDでいうところのgeom_mapのように、NetBSDではflashというデバイスでパティションを設定できるようです。

flash.c,cfi.cにちょっとパッチ当ててます。flash.cの方は文字化けでターミナルが固まるので外しました。cfi.cの方は落ちるのとコンパイルできないのでいじりました。

```diff
index 2d76d3d3b89..dd6c818816c 100644
--- a/sys/dev/flash/flash.c
+++ b/sys/dev/flash/flash.c
@@ -146,9 +146,11 @@ flash_attach(device_t parent, device_t self, void *aux)
 
        aprint_naive("\n");
 
+#if 0
        aprint_normal(": partition");
        if (sc->sc_partinfo.part_name != NULL)
                aprint_normal(" \"%s\"", sc->sc_partinfo.part_name);
+#endif
 
        aprint_normal(", size %s, offset %#jx",
                pbuf[0], (uintmax_t)sc->sc_partinfo.part_offset);
diff --git a/sys/dev/nor/cfi.c b/sys/dev/nor/cfi.c
index b3bc518f95b..f804f6dc2d4 100644
--- a/sys/dev/nor/cfi.c
+++ b/sys/dev/nor/cfi.c
@@ -423,7 +423,8 @@ cfi_probe(struct cfi * const cfi)
                        cfi->cfi_portwidth = pw;
                        cfi->cfi_chipwidth = cw;
                        found = cfi_chip_query(cfi);
-                       cfi_jedec_id(cfi);
+                       if (found)
+                               cfi_jedec_id(cfi);
                        if (! found)
                                found = cfi_emulate(cfi);
                        if (found)
@@ -632,9 +633,11 @@ cfi_read_qry(struct cfi * const cfi, bus_size_t off)
        case 2:
                data = bus_space_read_4(bst, bsh, off);
                break;
+#ifdef NOTYET
        case 3:
                data = bus_space_read_8(bst, bsh, off);
                break;
+#endif
        default:
                data = ~0;
                break;
```

cfi.cはなんだかやりすぎ感がありあまり好感をもてません。1,2,4,(8)バイトなflashのサポートが出来るように作られていますが、4とか8バイトのflashなんてみたことありません。

元々入っていたLinuxでは以下のようにflashを使っていたようです。

```
0x00000000-0x00040000 : "u-boot"
0x00040000-0x00060000 : "env"
0x00060000-0x00080000 : "data"
0x00080000-0x000a0000 : "wlan"
0x000a0000-0x001a0000 : "config"
0x001a0000-0x007a0000 : "recovery[upgrade]"
0x001a0100-0x007a0000 : "recovery[squashfs]"
0x007a0000-0x02000000 : "image[upgrade]"
0x007a0100-0x02000000 : "image[squashfs]"
```

ちょっといじってarm全般で使えるように修正しました。

qiitaの古い記事を見直して、FreeBSDのcfiドライバでリセットがかからないデバイスがあり、NetBSDのリセットを調べて同じようにしたのを思い出しました。NetBSDの方がいろいろ試されているような感じがします。ただNetBSDもFreeBSD本家もあまり有効な利用法はなくて、ZRouterが有効な利用方法を見つけたといった感じがします。