NetBSD-5.0BETA/macppcのSMP実装ーCPU初期化以外の部分について
読んでみたらi386より簡単そうだったので、こちらをもう少し読み進める事にする。
SMP対応のコードってどんな所に散らばってるんだろうか?とMULTIPROCESSORでgrepしてみると、まぁ大体こんな感じである:
bash-3.2$ grep MULTIPROCESSOR -r arch/powerpc arch/macppc |grep -v .svn arch/powerpc/powerpc/fpu.c:#ifdef MULTIPROCESSOR arch/powerpc/powerpc/fpu.c:#ifdef MULTIPROCESSOR arch/powerpc/powerpc/fpu.c:#endif /* MULTIPROCESSOR */ arch/powerpc/powerpc/fpu.c:#ifndef MULTIPROCESSOR arch/powerpc/powerpc/fpu.c:#ifdef MULTIPROCESSOR arch/powerpc/powerpc/pmap_subr.c:#ifdef MULTIPROCESSOR arch/powerpc/powerpc/pmap_subr.c:#endif /* !MULTIPROCESSOR */ arch/powerpc/powerpc/locore_subr.S:#ifdef MULTIPROCESSOR arch/powerpc/powerpc/locore_subr.S:#if defined(MULTIPROCESSOR) && 0 arch/powerpc/powerpc/locore_subr.S:#if defined(MULTIPROCESSOR) && !defined(PPC_OEA64) && !defined (PPC_IBM4XX) arch/powerpc/powerpc/locore_subr.S:#endif /*MULTIPROCESSOR + OEA*/ arch/powerpc/powerpc/openfirm.c:#ifdef MULTIPROCESSOR arch/powerpc/powerpc/openfirm.c:#ifdef MULTIPROCESSOR arch/powerpc/powerpc/lock_stubs.S:#if defined(MULTIPROCESSOR) arch/powerpc/include/cpu.h:#ifdef MULTIPROCESSOR arch/powerpc/include/cpu.h:#endif /* MULTIPROCESSOR */ arch/powerpc/include/cpu.h:#ifdef MULTIPROCESSOR arch/powerpc/oea/ofwoea_machdep.c:#if defined(MULTIPROCESSOR) && defined(ofppc) arch/powerpc/oea/ofwoea_machdep.c:#if defined(MULTIPROCESSOR) && defined(ofppc) arch/powerpc/oea/cpu_subr.c:#ifdef MULTIPROCESSOR arch/powerpc/oea/cpu_subr.c:#endif /*MULTIPROCESSOR*/ arch/powerpc/oea/cpu_subr.c:#ifndef MULTIPROCESSOR arch/powerpc/oea/cpu_subr.c:#ifndef MULTIPROCESSOR arch/powerpc/oea/cpu_subr.c:#ifdef MULTIPROCESSOR arch/powerpc/oea/cpu_subr.c:#endif /*MULTIPROCESSOR*/ arch/powerpc/oea/altivec.c:#ifdef MULTIPROCESSOR arch/powerpc/oea/altivec.c:#ifdef MULTIPROCESSOR arch/powerpc/oea/altivec.c:#endif /*MULTIPROCESSOR*/ arch/powerpc/oea/altivec.c:#ifndef MULTIPROCESSOR arch/powerpc/oea/altivec.c:#ifdef MULTIPROCESSOR arch/powerpc/oea/pmap.c:#ifdef MULTIPROCESSOR arch/powerpc/oea/pmap.c:#ifdef MULTIPROCESSOR arch/powerpc/pic/ipi_openpic.c:#ifdef MULTIPROCESSOR arch/powerpc/pic/ipi_openpic.c:#endif /*MULTIPROCESSOR*/ arch/powerpc/pic/ipi.c:#ifdef MULTIPROCESSOR arch/powerpc/pic/ipi.c:#endif /*MULTIPROCESSOR*/ arch/powerpc/pic/intr.c:#ifdef MULTIPROCESSOR arch/powerpc/pic/intr.c:#ifdef MULTIPROCESSOR arch/macppc/include/intr.h:#ifdef MULTIPROCESSOR arch/macppc/include/intr.h:#endif /* MULTIPROCESSOR */ arch/macppc/macppc/interrupts.c:#ifdef MULTIPROCESSOR arch/macppc/macppc/interrupts.c:#endif /*MULTIPROCESSOR*/ arch/macppc/macppc/machdep.c:#ifdef MULTIPROCESSOR arch/macppc/macppc/machdep.c:#ifdef MULTIPROCESSOR arch/macppc/macppc/cpu.c:#ifdef MULTIPROCESSOR arch/macppc/macppc/cpu.c:#ifdef MULTIPROCESSOR arch/macppc/macppc/cpu.c:#ifdef MULTIPROCESSOR arch/macppc/macppc/cpu.c:#endif /* MULTIPROCESSOR */ arch/macppc/macppc/ipi_hammerhead.c:#ifdef MULTIPROCESSOR arch/macppc/macppc/ipi_hammerhead.c:#endif /*MULTIPROCESSOR*/ arch/macppc/conf/GENERIC.MP:options MULTIPROCESSOR
CPU周り以外だと、lock周りやpmap周り、intrrupt周りが主な所で、後はfpuとかaltivecとか。
で、初期化の為にopenfirmwareの辺りにも少し入っている、と。
てな訳で、まずはlock周りを眺めてみる。
#if defined(MULTIPROCESSOR) #define ISYNC isync #define SYNC sync #else #define ISYNC /* nothing */ #define SYNC /* nothing */ #endif .text #if __HAVE_MUTEX_STUBS /* * int _lock_cas(uintptr_t *ptr, uintptr_t old, uintptr_t new); */ ENTRY(_lock_cas) 1: lptrarx %r10,0,%r3 cmpw %r10,%r4 bne- 2f stptrcx. %r5,0,%r3 bne- 1b SYNC li %r3,1 blr 2: li %r3,0 blr
実に簡潔なコードになっていて、MULTIPROCESSORの時はデータ変更後にCPUキャッシュを同期するよ、という事らしい(sync,isync命令)。
まぁ、ここら辺はアーキテクチャによって違ってくるのかもしれない。
static inline void pmap_pte_clear(volatile struct pte *pt, vaddr_t va, int ptebit) { /* * As shown in Section 7.6.3.2.3 */ pt->pte_lo &= ~ptebit; TLBIE(va); SYNC(); EIEIO(); TLBSYNC(); SYNC(); #ifdef MULTIPROCESSOR DCBST(pt); #endif }
pmapでは、syncの後にdcbst命令を発行するようになっていた。
これもキャッシュコヒーレンシを保つ為の命令っぽい。
要所要所でこういうのを入れてく必要があるみたいだ。(それもアーキテクチャによるけど)