diff options
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r-- | arch/mips/kernel/traps.c | 38 |
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 | */ |
540 | static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode) | 539 | static 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; | |||
1287 | int cp0_perfcount_irq; | 1306 | int cp0_perfcount_irq; |
1288 | EXPORT_SYMBOL_GPL(cp0_perfcount_irq); | 1307 | EXPORT_SYMBOL_GPL(cp0_perfcount_irq); |
1289 | 1308 | ||
1290 | void __init per_cpu_trap_init(void) | 1309 | void __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 | ||
1407 | static char panic_null_cerr[] __initdata = | 1426 | static 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 */ |
1411 | void __init set_uncached_handler(unsigned long offset, void *addr, unsigned long size) | 1430 | void __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); |