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命令を発行するようになっていた。
これもキャッシュコヒーレンシを保つ為の命令っぽい。
要所要所でこういうのを入れてく必要があるみたいだ。(それもアーキテクチャによるけど)