Add a kdb show command to print arbitrary SPRs on PowerPC
Summary: There is often a need at the debugger to print arbitrary special purpose registers (SPRs) on PowerPC. Using a rewritable asm stub, print any SPR provided on the command line. Note, as there is no checking in this, attempting to print a nonexistent SPR may cause a Program exception (illegal instruction, or boundedly undefined). Note also that this relies on the kernel text pages being writable. If in the future this is made not the case, this will need to be reworked. Test Plan: Printing the Processor Version Register (PVR, SPR 287): db> show spr 11f SPR 287(11f): 80240012 Differential Revision: https://reviews.freebsd.org/D7403
This commit is contained in:
parent
fc9bbf2794
commit
cbc3c68d9a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=304051
@ -6,3 +6,10 @@
|
||||
#include <powerpc/aim/locore32.S>
|
||||
#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
|
||||
|
@ -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 */
|
||||
/************************************************************************/
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user