diff --git a/sys/powerpc/aim/locore.S b/sys/powerpc/aim/locore.S index 0cb51f26519..806884dfbef 100644 --- a/sys/powerpc/aim/locore.S +++ b/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 diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S index c706771353d..aaed3c3198b 100644 --- a/sys/powerpc/booke/locore.S +++ b/sys/powerpc/booke/locore.S @@ -848,6 +848,14 @@ ENTRY(dataloss_erratum_access) 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 */ /************************************************************************/ diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c index 37e05b55a68..c9ad2362c9c 100644 --- a/sys/powerpc/powerpc/machdep.c +++ b/sys/powerpc/powerpc/machdep.c @@ -516,3 +516,31 @@ spinlock_exit(void) } } +/* + * 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); +}