summaryrefslogtreecommitdiff
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-03-12 13:04:11 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-03-12 13:04:11 -0700
commit299601cfc0aabbabf82fca50652b7290cce7eb00 (patch)
treeb9fceb84ddbb8888f3b980939cf1a8a39579c5ae /arch/mips/kernel/traps.c
parent0509ad5e1a7d9220f09edd5be114bf3bd51a7023 (diff)
parent69e634f1e27c8e5b954ea4be2d05dd744cabc0bc (diff)
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: [MIPS] Clocksource: Only install r4k counter as clocksource if present. [MIPS] Lasat: fix LASAT_CASCADE_IRQ [MIPS] Delete leftovers of old pcspeaker support. [MIPS] BCM1480: Init pci controller io_map_base [MIPS] Yosemite: Fix a few more section reference bugs. [MIPS] Fix yosemite build error [MIPS] Fix loads of section missmatches [MIPS] IP27: Tighten up CPU description to fix warnings. [MIPS] Fix plat_ioremap for JMR3927 [MIPS] Export __ucmpdi2 to modules. [MIPS] Fix typo in comment [MIPS] Use KBUILD_DEFCONFIG [MIPS] Allow 48Hz to be selected if CONFIG_SYS_SUPPORTS_ARBIT_HZ is set. [MIPS] Added missing cases for rdhwr emulation [MIPS] Alchemy: Fix ids in Alchemy db dma device table
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 fcae6675297..984c0d0a7b4 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)
/*
* Simulate trapping 'rdhwr' instructions to provide user accessible
- * registers not implemented in hardware. The only current use of this
- * is the thread area pointer.
+ * registers not implemented in hardware.
*/
static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
{
@@ -545,11 +544,31 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
int rd = (opcode & RD) >> 11;
int rt = (opcode & RT) >> 16;
switch (rd) {
- case 29:
- regs->regs[rt] = ti->tp_value;
- return 0;
+ 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:
- return -1;
+ regs->regs[rt] = 2;
+ }
+ return 0;
+ case 29:
+ regs->regs[rt] = ti->tp_value;
+ return 0;
+ default:
+ return -1;
}
}
@@ -1287,7 +1306,7 @@ int cp0_compare_irq;
int cp0_perfcount_irq;
EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
-void __init per_cpu_trap_init(void)
+void __cpuinit per_cpu_trap_init(void)
{
unsigned int cpu = smp_processor_id();
unsigned int status_set = ST0_CU0;
@@ -1404,11 +1423,12 @@ void __init set_handler(unsigned long offset, void *addr, unsigned long size)
flush_icache_range(ebase + offset, ebase + offset + size);
}
-static char panic_null_cerr[] __initdata =
+static char panic_null_cerr[] __cpuinitdata =
"Trying to set NULL cache error exception handler";
/* Install uncached CPU exception handler */
-void __init set_uncached_handler(unsigned long offset, void *addr, unsigned long size)
+void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
+ unsigned long size)
{
#ifdef CONFIG_32BIT
unsigned long uncached_ebase = KSEG1ADDR(ebase);