Index: sys/powerpc/aim/locore.S =================================================================== --- sys/powerpc/aim/locore.S +++ sys/powerpc/aim/locore.S @@ -6,3 +6,10 @@ #include #endif +/* + * XXX: This should be moved to a shared AIM/booke asm file, if one ever is + * created. + */ +ENTRY(get_spr) + mfspr %r3, 0 + blr Index: sys/powerpc/booke/locore.S =================================================================== --- sys/powerpc/booke/locore.S +++ sys/powerpc/booke/locore.S @@ -846,6 +846,14 @@ blr +/* + * XXX: This should be moved to a shared AIM/booke asm file, if one ever is + * created. + */ +ENTRY(get_spr) + mfspr %r3, 0 + blr + /************************************************************************/ /* Data section */ /************************************************************************/ Index: sys/powerpc/powerpc/machdep.c =================================================================== --- sys/powerpc/powerpc/machdep.c +++ sys/powerpc/powerpc/machdep.c @@ -516,3 +516,31 @@ } } +/* + * Simple ddb(4) command/hack to view any SPR on the running CPU. + * Uses a trivial asm function to perform the mfspr, and rewrites the mfspr + * instruction each time. + * XXX: Since it uses code modification, it won't work if the kernel code pages + * are marked RO. + */ +extern register_t get_spr(int); + +DB_SHOW_COMMAND(spr, db_show_spr) +{ + register_t spr; + volatile uint32_t *p; + int sprno, saved_sprno; + + if (!have_addr) + return; + + saved_sprno = sprno = (intptr_t) addr; + sprno = ((sprno & 0x3e0) >> 5) | ((sprno & 0x1f) << 5); + p = (uint32_t *)(void *)&get_spr; + *p = (*p & ~0x001ff800) | (sprno << 11); + __syncicache(get_spr, cacheline_size); + spr = get_spr(sprno); + + db_printf("SPR %d(%x): %lx\n", saved_sprno, saved_sprno, + (unsigned long)spr); +}