私のマルチプロセッサー初体験は1990年にモトローラの88Kでした。当時は何もできなかったのですが、最近はちょっと利口になったかもしれないのでc2kでマルチプロセッサーを試してみます。
comcerto 2000(Cortex-A9 armv7)は最初はシングルコアの製品もあったようですが、ほとんどコアが2つ入っています。armのマルチプロセッサーはarmv6mpで公式仕様になりました。armv6mpの製品はほとんどなくて、実質armv7以降になります。
c1kもマルチコアがあるのですが、armv6mpではないようで謎マルチコアです。
共通仕様にはなっていますが、決まっていない事もいろいろありSOC毎の処理も必要です。
NetBSDではinitarmの終わりのほうでセカンダリーのCPUを上げます。
Snoop Control Unit(SCU)を設定して、c2kの場合、物理アドレスの0番地から実行を始めるので、そこのメモリに処理をおいてCPUのリセットを解除します。
0番地からの処理はcpu_mpstartへのジャンプにします。
いつもの最初の一歩作戦です。
--- a/sys/arch/arm/arm/armv6_start.S
+++ b/sys/arch/arm/arm/armv6_start.S
@@ -834,6 +834,9 @@ ENTRY_NP(cpu_mpstart)
#if defined(__ARMEB__)
setend be // switch to BE now
#endif
+ ldr r2, .Luart
+ mov r1, #78
+ strb r1, [r2]
/* disable IRQs/FIQs. */
cpsid if
@@ -897,6 +900,8 @@ ENTRY_NP(cpu_mpstart)
movw lr, #:lower16:armv7_mpcontinuation
movt lr, #:upper16:armv7_mpcontinuation
b armv7_mmuinit
+.Luart:
+ .word 0x96400000
ASEND(cpu_mpstart)
/*
文字が出たので、CPUは起動したようです。
VERBOSE_INIT_ARMを設定してビルドするとログでます。
midr : 0x412fc091revidr: 0x412fc091
mpidr : 0x80000901
index : 0x00000001
sp : 0x034cf000
AB sctlr:0x00c50078/0x00c50078 CFG01H1JKIL
MMU
virtual
index: 0x00000001 ttb (TTBR0=0x034d405b) (TTBR1=0x034d405b) (TTBCR=0x00000011) ci = 0x833d4740 vfp hatched |=0x00000002
定義間違えて、てこずりましたが、できました。
割り込みの処理状況は以下のようにして確認できます。
c2k# intrctl list
interrupt id CPU0 CPU1 device name(s)
armgic irq 0 303* 259* IPI ast
armgic irq 1 51* 52* IPI xcall
armgic irq 2 3665* 7674* IPI nop
armgic irq 3 0* 0* IPI shootdown
armgic irq 4 0* 0* IPI ddb
armgic irq 5 281* 521* IPI generic
armgic irq 27 88945* 88945*
armgic irq 36 274013* 0
armgic irq 53 1* 0
armgic irq 54 16572* 0
armgic irq 59 2030* 0
irq 27はA9のタイマーです。
CPUが結構熱くなるのでヒートシンク貼って、温度測ってみたところ、気温30度の時に、通常時57度で、コンパイル流して負荷かけると63度になりました。結構熱持ちます。
後日追記:BCM5301XでもMULTIPROCESSORを試したのですが、セカンドのCPUは起動できたのですが、cpufuncが上手く動かなくて落ちてしまうようです。
ちょっといじったらcpu_init_secondary_processor()まで進んで、cpu_setup()で落ちるようになりました。
cpu_init_secondary_processor()がなんだか不安定で、デバッグライト入れると挙動が変わったりします。なんでかな。。。
c2kはBCM5301Xを雛形にしてポートしたのだがc2kはMULTIPROCESSORで動くのにBCM5301Xは動かない。。。
Linuxのコードを見ると、L2キャッシュを止めているのだが、同じようにinitarmの最初で止めると、initarmの最後のセカンダリを上げたところでハングする。
ブートローダーのL2キャッシュの初期化に依存してしまっているのかも。。。またいつか調べよう。