The default exception vector was located at sdram. But some designs
locate the exception vector at onchip memory or sram, and the
default exception hook won't work without regenerate hardware.

This patch copy a sequence of instructions to the hardwired exception
location. So that exceptions are redirected to inthandler at sdram.

FIXME: It won't work if the exception slave is not writable. An error
should be generated then.

Signed-off-by: Thomas Chou <[EMAIL PROTECTED]>
---
 linux-2.6.x/arch/nios2nommu/kernel/asm-offsets.c   |    4 +++
 linux-2.6.x/arch/nios2nommu/kernel/head.S          |   22 +++++++++++++++++++-
 .../arch/nios2nommu/scripts/PTF/SystemPTF/CPU.pm   |   12 ++++++++++
 .../arch/nios2nommu/scripts/gen_nios2_system.h.pl  |   11 ++++++++++
 4 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/linux-2.6.x/arch/nios2nommu/kernel/asm-offsets.c 
b/linux-2.6.x/arch/nios2nommu/kernel/asm-offsets.c
index 4877eba..0e06837 100644
--- a/linux-2.6.x/arch/nios2nommu/kernel/asm-offsets.c
+++ b/linux-2.6.x/arch/nios2nommu/kernel/asm-offsets.c
@@ -156,6 +156,10 @@ int main(void)
        DEFINE(NIOS2_ICACHE_LINE_SIZE, nasys_icache_line_size);
        DEFINE(NIOS2_DCACHE_SIZE, nasys_dcache_size);
        DEFINE(NIOS2_DCACHE_LINE_SIZE, nasys_dcache_line_size);
+
+#if defined(CPU_EXCEPT_ADDRESS)
+       DEFINE(CPU_EXCEPT_ADDRESS_ASM, CPU_EXCEPT_ADDRESS);
+#endif
        
 #if defined(na_enet)
        DEFINE(NA_ENET_ASM, na_enet);
diff --git a/linux-2.6.x/arch/nios2nommu/kernel/head.S 
b/linux-2.6.x/arch/nios2nommu/kernel/head.S
index f1cba65..9b0eeec 100644
--- a/linux-2.6.x/arch/nios2nommu/kernel/head.S
+++ b/linux-2.6.x/arch/nios2nommu/kernel/head.S
@@ -87,7 +87,7 @@ text_flush:
        /* This is the default location for the exception 
         * handler. Code in jump to our handler
         */
-       
+exc_hook:      
        movia   r24,inthandler
        jmp     r24
 1:             
@@ -129,6 +129,26 @@ loop_move:                         // r1: src, r2: dest, 
r3: last dest
 
 finish_move:
 
+#if defined(CPU_EXCEPT_ADDRESS_ASM) && (CPU_EXCEPT_ADDRESS_ASM != 
(LINUX_SDRAM_START + 0x20))
+/*     Copy an instruction sequence to put at the exception address */ 
+        movia  r2,exc_hook
+        movia  r3,CPU_EXCEPT_ADDRESS_ASM
+        ldw     r1,0(r2)
+        stw     r1,0(r3)
+        ldw     r1,4(r2)
+        stw     r1,4(r3)
+        ldw     r1,8(r2)
+        stw     r1,8(r3)
+        flushd  0(r3)
+        flushd  4(r3)
+        flushd  8(r3)
+        flushi  r3
+        addi    r3,r3,4
+        flushi  r3
+        addi    r3,r3,4
+        flushi  r3
+#endif
+
        //------------------------------------
        // Disable interrupts on known devices
        //
diff --git a/linux-2.6.x/arch/nios2nommu/scripts/PTF/SystemPTF/CPU.pm 
b/linux-2.6.x/arch/nios2nommu/scripts/PTF/SystemPTF/CPU.pm
index ea10598..810886d 100644
--- a/linux-2.6.x/arch/nios2nommu/scripts/PTF/SystemPTF/CPU.pm
+++ b/linux-2.6.x/arch/nios2nommu/scripts/PTF/SystemPTF/CPU.pm
@@ -72,6 +72,18 @@ sub getResetLocationOffset {
        return ($location, $offset);
 }
 
+sub getExceptLocationOffset {
+       my ($self) = @_;
+       
+       $wsa = $self->{ptf}->getSection('WIZARD_SCRIPT_ARGUMENTS', '');
+       $wsa or return;
+       
+       my $location = $wsa->getAssignment ('exc_slave');
+       my $offset = $wsa->getAssignment ('exc_offset');
+       
+       return ($location, $offset);
+}
+
 sub isEnabled {
        my ($self) = @_;
        
diff --git a/linux-2.6.x/arch/nios2nommu/scripts/gen_nios2_system.h.pl 
b/linux-2.6.x/arch/nios2nommu/scripts/gen_nios2_system.h.pl
index b7bcff5..1855cbf 100644
--- a/linux-2.6.x/arch/nios2nommu/scripts/gen_nios2_system.h.pl
+++ b/linux-2.6.x/arch/nios2nommu/scripts/gen_nios2_system.h.pl
@@ -304,6 +304,17 @@ printf ("#define %-33s %30s\n",
                ("CPU_RESET_ADDRESS", $reset_address));
 }
 
+{      
+       my ($except_location, $except_offset) = $cpu->getExceptLocationOffset();
+       my ($except_module_name, $except_port_name) = ($except_location =~ 
/(.*)\/(.*)/);
+       my $except_module = $system->getModule ($except_module_name);
+       my $except_address = $except_module->getBaseAddress ($except_port_name);
+       
+       $except_address = hex ($except_address) + hex ($except_offset);
+       printf ("#define %-53s %#010x\n", 
+               ("CPU_EXCEPT_ADDRESS", $except_address));
+}
+
 print "\n";
 
 #
-- 
1.5.3.3

_______________________________________________
uClinux-dev mailing list
[email protected]
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by [email protected]
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev

Reply via email to