- added exception vector table.

S/W can write exception handler entry to this table.
  Exception handler can now reside anywhere in memory.

Committed on the Free edition of March Hare Software CVSNT Server.
Upgrade to CVS Suite for more features and support:
http://march-hare.com/cvsnt/


git-svn-id: http://moon:8086/svn/vhdl/trunk@494 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2009-10-03 16:48:28 +00:00
parent f706de00bb
commit 21f33a1768
3 changed files with 50 additions and 13 deletions
+15 -11
View File
@@ -1,9 +1,13 @@
#include <regdef.h> #include <regdef.h>
#include <xcpt_asm.h> #include <xcpt_asm.h>
.section .ktext,"ax" .section .exc_vect
_xcpt_vector_tbl:
.fill 16, 4, 0
.text
LEAF(xcptlow_handler) LEAF(_xcpt_handler)
.set noreorder .set noreorder
.set noat .set noat
/* Note: exceptions do not save and restore registers k0 and k1. /* Note: exceptions do not save and restore registers k0 and k1.
@@ -91,21 +95,21 @@ LEAF(xcptlow_handler)
/* and call the C exception handler */ /* and call the C exception handler */
move a0, sp # arg1 = &xcp move a0, sp # arg1 = &xcp
subu sp, 16 # (arg save area) subu sp, 16 # (arg save area)
j _xcptcall j _xcpt_call
move ra, zero # fake return address move ra, zero # fake return address
/* This strange call to _xcptcall with zero return address is to /* This strange call to _xcpt_call with zero return address is to
* help exception-aware debuggers to trace back over the exception event. * help exception-aware debuggers to trace back over the exception event.
* We are basically interposing a bogus stackframe (with a zero return * We are basically interposing a bogus stackframe (with a zero return
* address) between the C exception handler and the actual machine * address) between the C exception handler and the actual machine
* exception. * exception.
*/ */
xcptrest: $xcptrest:
.set noat .set noat
add AT, sp, 16 add AT, sp, 16
/* at points to exception frame */ /* at points to exception frame */
xcptrestother: $xcptrestother:
/* restore all state */ /* restore all state */
/* restore most general registers */ /* restore most general registers */
lw t0, XCP_T0(AT) lw t0, XCP_T0(AT)
@@ -160,10 +164,10 @@ xcptrestother:
.set reorder .set reorder
.set at .set at
END(xcptlow_handler) END(_xcpt_handler)
LEAF(_xcptcall) LEAF(_xcpt_call)
/* on entry: a0 == &xcp */ /* on entry: a0 == &xcp */
subu sp, 24 subu sp, 24
sw ra, 16(sp) sw ra, 16(sp)
@@ -173,8 +177,8 @@ LEAF(_xcptcall)
nop nop
lw ra, 16(sp) lw ra, 16(sp)
addu sp, 24 addu sp, 24
beqz ra, xcptrest beqz ra, $xcptrest
nop nop
j ra j ra
nop nop
END(_xcptcall) END(_xcpt_call)
+4 -2
View File
@@ -31,9 +31,11 @@ SECTIONS
*(.start) *(.start)
} }
/* Kernel text with low-level exception handler */ /* Kernel text with low-level exception handler */
.ktext __executable_start + 0x180 : .exc_vector __executable_start + 0x080 :
{ {
*(.ktext) _exc_vect_start = .;
*(.exc_vect)
_exc_vect_end = .;
} }
.init : .init :
{ {
+31
View File
@@ -9,11 +9,19 @@ argv: .word argv0
.section .start, "ax" .section .start, "ax"
.extern _init .extern _init
.extern dbg_init .extern dbg_init
.extern _exc_vect_start
.extern _xcpt_handler
.align 2 .align 2
.globl _start .globl _start
_start: _start:
.set noreorder .set noreorder
j init
nop
.set reorder
.text
.set noreorder
init:
# Set stack pointer # Set stack pointer
la $sp, stack_ptr la $sp, stack_ptr
# Set global pointer # Set global pointer
@@ -27,6 +35,17 @@ $zeroise:
bne $8, $9, $zeroise bne $8, $9, $zeroise
addiu $8, 4 addiu $8, 4
# Install exception vector jump code
la $t1, _exc_vect_copy_start
la $t2, _exc_vect_copy_end
la $t0, _exc_vect_start
$install: lw $v0, 0($t1)
addiu $t1, 4
sw $v0, 0($t0)
bne $t1, $t2, $install
addiu $t0, 4
# Call _init # Call _init
la $k0, _init la $k0, _init
jalr $k0 jalr $k0
@@ -41,6 +60,12 @@ $zeroise:
li $a0, 1 li $a0, 1
la $a1, argv la $a1, argv
# Set user-mode
mfc0 $a0, $12
li $a1, 3
or $a0, $a1
mtc0 $a0, $12
# Call main # Call main
la $k0, main la $k0, main
jalr $k0 jalr $k0
@@ -52,5 +77,11 @@ _terminate:
la $t0, exit la $t0, exit
jalr $t0 jalr $t0
move $a0, $v0 move $a0, $v0
_exc_vect_copy_start:
la $k0, _xcpt_handler
jr $k0
nop
_exc_vect_copy_end:
.set reorder .set reorder