Skip to content

Commit

Permalink
MIPS: Deal with larger physical offsets
Browse files Browse the repository at this point in the history
AR7 has a larger physical offset than other MIPS based systems and therefore
needs to setup its handlers beyond the usual KSEG0 range. When running the
kernel in mapped mode this modification is also required. Remove function
comment which is now incorrect.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Signed-off-by: Eugene Konev <ejka@imfi.kspu.ru>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
To: linux-mips@linux-mips.org
To: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@linux-mips.org
Patchwork: http://patchwork.linux-mips.org/patch/889/
Patchwork: http://patchwork.linux-mips.org/patch/932/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Florian Fainelli authored and Ralf Baechle committed Feb 27, 2010
1 parent 2d1b6e9 commit 92bbe1b
Showing 1 changed file with 13 additions and 8 deletions.
21 changes: 13 additions & 8 deletions arch/mips/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <asm/types.h>
#include <asm/stacktrace.h>
#include <asm/irq.h>
#include <asm/uasm.h>

extern void check_wait(void);
extern asmlinkage void r4k_wait(void);
Expand Down Expand Up @@ -1271,21 +1272,25 @@ unsigned long ebase;
unsigned long exception_handlers[32];
unsigned long vi_handlers[64];

/*
* As a side effect of the way this is implemented we're limited
* to interrupt handlers in the address range from
* KSEG0 <= x < KSEG0 + 256mb on the Nevada. Oh well ...
*/
void __init *set_except_vector(int n, void *addr)
{
unsigned long handler = (unsigned long) addr;
unsigned long old_handler = exception_handlers[n];

exception_handlers[n] = handler;
if (n == 0 && cpu_has_divec) {
*(u32 *)(ebase + 0x200) = 0x08000000 |
(0x03ffffff & (handler >> 2));
local_flush_icache_range(ebase + 0x200, ebase + 0x204);
unsigned long jump_mask = ~((1 << 28) - 1);
u32 *buf = (u32 *)(ebase + 0x200);
unsigned int k0 = 26;
if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) {
uasm_i_j(&buf, handler & ~jump_mask);
uasm_i_nop(&buf);
} else {
UASM_i_LA(&buf, k0, handler);
uasm_i_jr(&buf, k0);
uasm_i_nop(&buf);
}
local_flush_icache_range(ebase + 0x200, (unsigned long)buf);
}
return (void *)old_handler;
}
Expand Down

0 comments on commit 92bbe1b

Please sign in to comment.