/kernel/trunk/arch/sparc64/include/trap/interrupt.h |
---|
30,8 → 30,8 |
* This file contains interrupt vector trap handler. |
*/ |
#ifndef __sparc64_INTERRUPT_H__ |
#define __sparc64_INTERRUPT_H__ |
#ifndef __sparc64_TRAP_INTERRUPT_H__ |
#define __sparc64_TRAP_INTERRUPT_H__ |
#include <arch/trap/trap_table.h> |
#include <arch/stack.h> |
59,10 → 59,10 |
#ifdef __ASM__ |
.macro INTERRUPT_LEVEL_N_HANDLER n |
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp |
save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp |
mov \n - 1, %o0 |
mov %fp, %o1 |
SAVING_HANDLER exc_dispatch |
PREEMPTIBLE_HANDLER exc_dispatch |
.endm |
.macro INTERRUPT_VECTOR_TRAP_HANDLER |
/kernel/trunk/arch/sparc64/include/trap/trap_table.h |
---|
71,11 → 71,22 |
mov %l7, %g7 |
.endm |
.macro SAVING_HANDLER f |
#define PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE (STACK_WINDOW_SAVE_AREA_SIZE+(4*8)) |
#define SAVED_TSTATE -(1*8) |
#define SAVED_TPC -(2*8) |
#define SAVED_TNPC -(3*8) |
#define SAVED_PSTATE -(4*8) |
.macro PREEMPTIBLE_HANDLER f |
set \f, %l0 |
b saving_handler |
b preemptible_handler |
nop |
.endm |
.macro SIMPLE_HANDLER f |
call \f |
nop |
.endm |
#endif /* __ASM__ */ |
#endif |
/kernel/trunk/arch/sparc64/include/trap/exception.h |
---|
0,0 → 1,40 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef __sparc64_EXCEPTION_H__ |
#define __sparc64_EXCEPTION_H__ |
#define TT_INSTRUCTION_ACCESS_EXCEPTION 0x08 |
#define TT_MEM_ADDRESS_NOT_ALIGNED 0x34 |
#ifndef __ASM__ |
extern void do_instruction_access_exc(void); |
extern void do_mem_address_not_aligned(void); |
#endif /* !__ASM__ */ |
#endif |
/kernel/trunk/arch/sparc64/Makefile.inc |
---|
60,5 → 60,6 |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/trap/trap_table.S \ |
arch/$(ARCH)/src/trap/trap.c \ |
arch/$(ARCH)/src/trap/exception.c \ |
arch/$(ARCH)/src/trap/interrupt.c \ |
arch/$(ARCH)/src/drivers/tick.c |
/kernel/trunk/arch/sparc64/src/trap/exception.c |
---|
0,0 → 1,42 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <arch/trap/exception.h> |
#include <debug.h> |
/** Handle instruction_access_exception. */ |
void do_instruction_access_exc(void) |
{ |
panic("Instruction Access Exception\n"); |
} |
/** Handle mem_address_not_aligned. */ |
void do_mem_address_not_aligned(void) |
{ |
panic("Memory Address Not Aligned\n"); |
} |
/kernel/trunk/arch/sparc64/src/trap/trap.c |
---|
29,6 → 29,7 |
#include <arch/trap/trap.h> |
#include <arch/trap/trap_table.h> |
#include <arch/trap/regwin.h> |
#include <arch/trap/exception.h> |
#include <arch/trap/interrupt.h> |
#include <arch/asm.h> |
#include <memstr.h> |
53,10 → 54,14 |
/* |
* Install kernel-provided handlers. |
*/ |
trap_install_handler(TT_INSTRUCTION_ACCESS_EXCEPTION, TRAP_TABLE_ENTRY_SIZE, false); |
trap_install_handler(TT_CLEAN_WINDOW, CLEAN_WINDOW_HANDLER_SIZE, false); |
trap_install_handler(TT_MEM_ADDRESS_NOT_ALIGNED, TRAP_TABLE_ENTRY_SIZE, false); |
trap_install_handler(TT_SPILL_0_NORMAL, SPILL_HANDLER_SIZE, false); |
trap_install_handler(TT_FILL_0_NORMAL, FILL_HANDLER_SIZE, false); |
trap_install_handler(TT_INSTRUCTION_ACCESS_EXCEPTION, TRAP_TABLE_ENTRY_SIZE, true); |
trap_install_handler(TT_CLEAN_WINDOW, CLEAN_WINDOW_HANDLER_SIZE, true); |
trap_install_handler(TT_MEM_ADDRESS_NOT_ALIGNED, TRAP_TABLE_ENTRY_SIZE, true); |
trap_install_handler(TT_SPILL_0_NORMAL, SPILL_HANDLER_SIZE, true); |
trap_install_handler(TT_FILL_0_NORMAL, FILL_HANDLER_SIZE, true); |
trap_install_handler(TT_INTERRUPT_LEVEL_1, INTERRUPT_LEVEL_N_HANDLER_SIZE, false); |
/kernel/trunk/arch/sparc64/src/trap/trap_table.S |
---|
48,6 → 48,8 |
#include <arch/trap/trap_table.h> |
#include <arch/trap/regwin.h> |
#include <arch/trap/interrupt.h> |
#include <arch/trap/exception.h> |
#include <arch/stack.h> |
#define TABLE_SIZE TRAP_TABLE_SIZE |
#define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE |
59,6 → 61,12 |
.global trap_table |
trap_table: |
/* TT = 0x08, TL = 0, instruction_access_exception */ |
.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE |
.global instruction_access_exception |
instruction_access_exception: |
SIMPLE_HANDLER do_instruction_access_exc |
/* TT = 0x24, TL = 0, clean_window handler */ |
.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE |
.global clean_window_handler |
65,6 → 73,12 |
clean_window_handler: |
CLEAN_WINDOW_HANDLER |
/* TT = 0x34, TL = 0, mem_address_not_aligned */ |
.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE |
.global mem_address_not_aligned |
mem_address_not_aligned: |
SIMPLE_HANDLER do_mem_address_not_aligned |
/* TT = 0x41, TL = 0, interrupt_level_1 handler */ |
.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE |
.global interrupt_level_1_handler |
177,6 → 191,12 |
* Handlers for TL>0. |
*/ |
/* TT = 0x08, TL > 0, instruction_access_exception */ |
.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE |
.global instruction_access_exception_high |
instruction_access_exception_high: |
SIMPLE_HANDLER do_instruction_access_exc |
/* TT = 0x24, TL > 0, clean_window handler */ |
.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE |
.global clean_window_handler_high |
183,15 → 203,18 |
clean_window_handler_high: |
CLEAN_WINDOW_HANDLER |
/* TT = 0x34, TL > 0, mem_address_not_aligned */ |
.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE |
.global mem_address_not_aligned_high |
mem_address_not_aligned_high: |
SIMPLE_HANDLER do_mem_address_not_aligned |
/* TT = 0x80, TL > 0, spill_0_normal handler */ |
.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE |
.global spill_0_normal_high |
spill_0_normal_high: |
SPILL_NORMAL_HANDLER |
/* TT = 0xc0, TL > 0, fill_0_normal handler */ |
.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE |
.global fill_0_normal_high |
209,18 → 232,105 |
.space TABLE_SIZE, 0 |
/* Trap handler that explicitly saves global registers. |
/* Preemptible trap handler. |
* |
* This trap handler makes arrangements to |
* make calling scheduler() possible. |
* |
* The caller is responsible for doing save |
* and allocating PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE |
* bytes on stack. |
* |
* Input registers: |
* %l0 Address of function to call. |
* Output registers: |
* %l1 - %l7 Copy of %g1 - %g7 |
*/ |
.global saving_handler |
saving_handler: |
.global preemptible_handler |
preemptible_handler: |
/* |
* Save TSTATE, TPC, TNPC and PSTATE aside. |
*/ |
rdpr %tstate, %g1 |
rdpr %tpc, %g2 |
rdpr %tnpc, %g3 |
rdpr %pstate, %g4 |
stx %g1, [%fp + STACK_BIAS + SAVED_TSTATE] |
stx %g2, [%fp + STACK_BIAS + SAVED_TPC] |
stx %g3, [%fp + STACK_BIAS + SAVED_TNPC] |
stx %g4, [%fp + STACK_BIAS + SAVED_PSTATE] |
/* |
* Write 0 to TL. |
*/ |
wrpr %g0, 0, %tl |
/* |
* Alter PSTATE. |
* - switch to normal globals. |
*/ |
and %g4, ~1, %g4 ! mask alternate globals |
wrpr %g4, 0, %pstate |
/* |
* Save the normal globals. |
*/ |
SAVE_GLOBALS |
/* |
* Call the higher-level handler. |
*/ |
call %l0 |
nop |
/* |
* Restore the normal global register set. |
*/ |
RESTORE_GLOBALS |
restore /* matches the save instruction from the top-level handler */ |
/* |
* Restore PSTATE from saved copy. |
* Alternate globals become active. |
*/ |
ldx [%fp + STACK_BIAS + SAVED_PSTATE], %l4 |
wrpr %l4, 0, %pstate |
/* |
* Write 1 to TL. |
*/ |
wrpr %g0, 1, %tl |
/* |
* Read TSTATE, TPC and TNPC from saved copy. |
*/ |
ldx [%fp + STACK_BIAS + SAVED_TSTATE], %g1 |
ldx [%fp + STACK_BIAS + SAVED_TPC], %g2 |
ldx [%fp + STACK_BIAS + SAVED_TNPC], %g3 |
/* |
* Do restore to match the save instruction from the top-level handler. |
*/ |
restore |
/* |
* On execution of retry instruction, CWP will be restored from TSTATE register. |
* However, because of scheduling, it is possible that CWP in saved TSTATE |
* is different from current CWP. The following chunk of code fixes CWP |
* in the saved copy of TSTATE. |
*/ |
rdpr %cwp, %g4 ! read current CWP |
and %g1, ~0x1f, %g1 ! clear CWP field in saved TSTATE |
or %g1, %g4, %g1 ! write current CWP to TSTATE |
/* |
* Restore TSTATE, TPC and TNPC from saved copies. |
*/ |
wrpr %g1, 0, %tstate |
wrpr %g2, 0, %tpc |
wrpr %g3, 0, %tnpc |
/* |
* Return from interrupt. |
*/ |
retry |
/kernel/trunk/arch/sparc64/src/panic.S |
---|
32,11 → 32,9 |
.global panic_printf |
panic_printf: |
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp |
call printf |
nop |
call halt |
nop |
/* Not reached. */ |
restore |