aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r--arch/mips/kernel/traps.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index fcae66752972..984c0d0a7b4d 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -534,8 +534,7 @@ static int simulate_llsc(struct pt_regs *regs, unsigned int opcode)
534 534
535/* 535/*
536 * Simulate trapping 'rdhwr' instructions to provide user accessible 536 * Simulate trapping 'rdhwr' instructions to provide user accessible
537 * registers not implemented in hardware. The only current use of this 537 * registers not implemented in hardware.
538 * is the thread area pointer.
539 */ 538 */
540static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode) 539static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
541{ 540{
@@ -545,11 +544,31 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
545 int rd = (opcode & RD) >> 11; 544 int rd = (opcode & RD) >> 11;
546 int rt = (opcode & RT) >> 16; 545 int rt = (opcode & RT) >> 16;
547 switch (rd) { 546 switch (rd) {
548 case 29: 547 case 0: /* CPU number */
549 regs->regs[rt] = ti->tp_value; 548 regs->regs[rt] = smp_processor_id();
550 return 0; 549 return 0;
550 case 1: /* SYNCI length */
551 regs->regs[rt] = min(current_cpu_data.dcache.linesz,
552 current_cpu_data.icache.linesz);
553 return 0;
554 case 2: /* Read count register */
555 regs->regs[rt] = read_c0_count();
556 return 0;
557 case 3: /* Count register resolution */
558 switch (current_cpu_data.cputype) {
559 case CPU_20KC:
560 case CPU_25KF:
561 regs->regs[rt] = 1;
562 break;
551 default: 563 default:
552 return -1; 564 regs->regs[rt] = 2;
565 }
566 return 0;
567 case 29:
568 regs->regs[rt] = ti->tp_value;
569 return 0;
570 default:
571 return -1;
553 } 572 }
554 } 573 }
555 574
@@ -1287,7 +1306,7 @@ int cp0_compare_irq;
1287int cp0_perfcount_irq; 1306int cp0_perfcount_irq;
1288EXPORT_SYMBOL_GPL(cp0_perfcount_irq); 1307EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
1289 1308
1290void __init per_cpu_trap_init(void) 1309void __cpuinit per_cpu_trap_init(void)
1291{ 1310{
1292 unsigned int cpu = smp_processor_id(); 1311 unsigned int cpu = smp_processor_id();
1293 unsigned int status_set = ST0_CU0; 1312 unsigned int status_set = ST0_CU0;
@@ -1404,11 +1423,12 @@ void __init set_handler(unsigned long offset, void *addr, unsigned long size)
1404 flush_icache_range(ebase + offset, ebase + offset + size); 1423 flush_icache_range(ebase + offset, ebase + offset + size);
1405} 1424}
1406 1425
1407static char panic_null_cerr[] __initdata = 1426static char panic_null_cerr[] __cpuinitdata =
1408 "Trying to set NULL cache error exception handler"; 1427 "Trying to set NULL cache error exception handler";
1409 1428
1410/* Install uncached CPU exception handler */ 1429/* Install uncached CPU exception handler */
1411void __init set_uncached_handler(unsigned long offset, void *addr, unsigned long size) 1430void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
1431 unsigned long size)
1412{ 1432{
1413#ifdef CONFIG_32BIT 1433#ifdef CONFIG_32BIT
1414 unsigned long uncached_ebase = KSEG1ADDR(ebase); 1434 unsigned long uncached_ebase = KSEG1ADDR(ebase);