[MIPS] Added missing cases for rdhwr emulation

Some of these are architecturally required for R2 processors so lets try
to be bit closer to the real thing.  This also provides access to the
CPU cycle timer, even on multiprocessors.  In that aspect its currently
bug compatible to what would happen on a R2-based SMP.

Signed-off-by: Chris Dearman <chris@mips.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
Chris Dearman 2006-05-08 18:02:16 +01:00 committed by Ralf Baechle
parent 0ec734c2b8
commit 1f5826bd0e
1 changed files with 25 additions and 6 deletions

View File

@ -534,8 +534,7 @@ static int simulate_llsc(struct pt_regs *regs, unsigned int opcode)
/* /*
* Simulate trapping 'rdhwr' instructions to provide user accessible * Simulate trapping 'rdhwr' instructions to provide user accessible
* registers not implemented in hardware. The only current use of this * registers not implemented in hardware.
* is the thread area pointer.
*/ */
static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode) static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
{ {
@ -545,6 +544,26 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
int rd = (opcode & RD) >> 11; int rd = (opcode & RD) >> 11;
int rt = (opcode & RT) >> 16; int rt = (opcode & RT) >> 16;
switch (rd) { switch (rd) {
case 0: /* CPU number */
regs->regs[rt] = smp_processor_id();
return 0;
case 1: /* SYNCI length */
regs->regs[rt] = min(current_cpu_data.dcache.linesz,
current_cpu_data.icache.linesz);
return 0;
case 2: /* Read count register */
regs->regs[rt] = read_c0_count();
return 0;
case 3: /* Count register resolution */
switch (current_cpu_data.cputype) {
case CPU_20KC:
case CPU_25KF:
regs->regs[rt] = 1;
break;
default:
regs->regs[rt] = 2;
}
return 0;
case 29: case 29:
regs->regs[rt] = ti->tp_value; regs->regs[rt] = ti->tp_value;
return 0; return 0;