Subject: Re: CP0 count register
To: Matthew Luckie <mjl@luckie.org.nz>
From: Simon Burge <simonb@NetBSD.org>
List: port-mips
Date: 05/15/2007 11:55:18
Matthew Luckie wrote:

> I would like to be able to measure the number of clock cycles a routine
> takes in user-space when running on a MIPS in order to measure the
> performance of a routine as accurately as possible.
> 
> It seems that the count register on CP0 is what I want to use, but that
> it cannot be accessed from user-space unless the appropriate bit in
> the CP0 status register is set to one.  That is:
> 
> mips_cp0_status_write(mips_cp0_status_read() | MIPS_SR_COP_0_BIT);
> 
> Is it possible, at all, to access CP0 in userspace if the kernel is
> modified to allow access to CP0 by user-space?  documentation such as
> http://6004.csail.mit.edu/6.371/handouts/mips6371.pdf suggests it is,
> but that is all I have to work with, and I am not intimately familiar
> with NetBSD on the MIPS CPU.
> 
> If it is, I was thinking of modifying sys/arch/mips/mips/vm_machdep.c 
> cpu_lwp_fork() and cpu_setfunc() as follows:
> 
>   [ ... patch deleted ... ]
> 
> Is this likely to work, or am I trying to do something that the MIPS
> CPU working with NetBSD is not able to support?  The hardware I'm
> using is NetBSD/cobalt running 4.0_BETA2 200703090002Z

I'd never have thought to allow CP0 access to user programs.  Certainly
from a general standpoint you couldn't do this, since then any user
process can completely corrupt the machine state and security would be
pretty much non-existant.  That said, it seems like what you suggest
might work.  Just be _really_ careful which registers you touch :-)

I'm guessing the overhead of a gettimeofday(2) system call is either
too high, or not granular enough?  The way I'd probably go about this
if I really needed access to CP0 Count would be to add some sort of
fast path handling.  Perhaps add a new system call number and check for
it explicitly in MIPSX(SystemCall) before you set up the kernel stack
frame.  You could do that in a handful of instructions, and the impact
on normal system calls should be quite minimal.

Interestingly the Release 2 versions of the MIPS32 and MIPS64 specs
which have only been out a few years do allow for user programs
reading the CP0 Count register (through a new "read hardware register"
instruction), but I'm not sure if there are any Release 2 CPUs supported
by NetBSD.  But that doesn't help you right now :-(

Cheers,
Simon.