linux-mips
[Top] [All Lists]

[PATCH 3/3] MIPS: deal with larger physical offsets

To: linux-mips@linux-mips.org
Subject: [PATCH 3/3] MIPS: deal with larger physical offsets
From: Florian Fainelli <florian@openwrt.org>
Date: Thu, 28 Jan 2010 15:22:37 +0100
Cc: Ralf Baechle <ralf@linux-mips.org>, David Daney <ddaney@caviumnetworks.com>
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:from:date:subject :mime-version:x-uid:x-length:to:cc:organization:content-type :content-transfer-encoding:message-id; bh=D7lneYihwT8Lys5Fv+J3hSWJAlJNF9iwpvscT7msd6U=; b=iCpxcsbkTj1QSk4puQV8l664sQEufas9jdZoCi2mS4Ff2Q8K5A72VkOyAXScZ9bVrF QzC8bekCgV5IMnHeuxUcDQmGaJ8zG/Y/L1hIFQLCHzVJczRwk/6kJr82xTxgl+8JcWn7 YxR2WaemSU+ZEOlUv6VXJQb51ftPPUBXFBnvA=
Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:date:subject:mime-version:x-uid:x-length:to:cc :organization:content-type:content-transfer-encoding:message-id; b=mtcEtGEXwj/w+i1UDv93LIgbEI8VtpwSLQtuvFdBIgXU4GLjmCdLqhrMyPOHSJ7F0/ zN6zk8y6+9OYykUHH2d90pag7vQqhbPAHyHIjaU87kFmx4g+jFjeDAWVUPmTM/ajJhOx /DoF2alugElVrCGXLtcJi3cnuEKDBTntmpy78=
Organization: OpenWrt
Sender: linux-mips-bounce@linux-mips.org
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>
---
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 574608e..14d515f 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -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);
@@ -1271,11 +1272,6 @@ 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;
@@ -1283,9 +1279,18 @@ void __init *set_except_vector(int n, void *addr)
 
        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;
 }


<Prev in Thread] Current Thread [Next in Thread>