//SPARTAN/trunk/tools/mips/gencontext.c |
---|
6,14 → 6,16 |
#define __mips_TYPES_H_ |
#include "../../arch/mips/include/context.h" |
#include "../../arch/mips/include/exception.h" |
#define FILENAME "../../arch/mips/src/context_offset.h" |
#define FILENAME "../../arch/mips/include/context_offset.h" |
int main(void) |
{ |
FILE *f; |
struct context ctx; |
struct context *pctx = &ctx; |
struct context *pctx = NULL; |
struct exception_regdump *edmp = NULL; |
f = fopen(FILENAME,"w"); |
if (!f) { |
23,6 → 25,8 |
fprintf(f, "/* This file is automatically generated by %s. */\n", __FILE__); |
fprintf(f,"/* struct context */\n"); |
fprintf(f,"#define OFFSET_SP 0x%x\n",((int)&pctx->sp) - (int )pctx); |
fprintf(f,"#define OFFSET_PC 0x%x\n",((int)&pctx->pc) - (int )pctx); |
fprintf(f,"#define OFFSET_S0 0x%x\n",((int)&pctx->s0) - (int )pctx); |
36,7 → 40,43 |
fprintf(f,"#define OFFSET_S8 0x%x\n",((int)&pctx->s8) - (int )pctx); |
fprintf(f,"#define OFFSET_GP 0x%x\n",((int)&pctx->gp) - (int )pctx); |
fprintf(f,"\n\n/* struct register_dump */\n"); |
fprintf(f,"#define EOFFSET_AT 0x%x\n",((int)&edmp->at) - (int )edmp); |
fprintf(f,"#define EOFFSET_V0 0x%x\n",((int)&edmp->v0) - (int )edmp); |
fprintf(f,"#define EOFFSET_V1 0x%x\n",((int)&edmp->v1) - (int )edmp); |
fprintf(f,"#define EOFFSET_A0 0x%x\n",((int)&edmp->a0) - (int )edmp); |
fprintf(f,"#define EOFFSET_A1 0x%x\n",((int)&edmp->a1) - (int )edmp); |
fprintf(f,"#define EOFFSET_A2 0x%x\n",((int)&edmp->a2) - (int )edmp); |
fprintf(f,"#define EOFFSET_A3 0x%x\n",((int)&edmp->a3) - (int )edmp); |
fprintf(f,"#define EOFFSET_T0 0x%x\n",((int)&edmp->t0) - (int )edmp); |
fprintf(f,"#define EOFFSET_T1 0x%x\n",((int)&edmp->t1) - (int )edmp); |
fprintf(f,"#define EOFFSET_T2 0x%x\n",((int)&edmp->t2) - (int )edmp); |
fprintf(f,"#define EOFFSET_T3 0x%x\n",((int)&edmp->t3) - (int )edmp); |
fprintf(f,"#define EOFFSET_T4 0x%x\n",((int)&edmp->t4) - (int )edmp); |
fprintf(f,"#define EOFFSET_T5 0x%x\n",((int)&edmp->t5) - (int )edmp); |
fprintf(f,"#define EOFFSET_T6 0x%x\n",((int)&edmp->t6) - (int )edmp); |
fprintf(f,"#define EOFFSET_T7 0x%x\n",((int)&edmp->t7) - (int )edmp); |
fprintf(f,"#define EOFFSET_S0 0x%x\n",((int)&edmp->s0) - (int )edmp); |
fprintf(f,"#define EOFFSET_S1 0x%x\n",((int)&edmp->s1) - (int )edmp); |
fprintf(f,"#define EOFFSET_S2 0x%x\n",((int)&edmp->s2) - (int )edmp); |
fprintf(f,"#define EOFFSET_S3 0x%x\n",((int)&edmp->s3) - (int )edmp); |
fprintf(f,"#define EOFFSET_S4 0x%x\n",((int)&edmp->s4) - (int )edmp); |
fprintf(f,"#define EOFFSET_S5 0x%x\n",((int)&edmp->s5) - (int )edmp); |
fprintf(f,"#define EOFFSET_S6 0x%x\n",((int)&edmp->s6) - (int )edmp); |
fprintf(f,"#define EOFFSET_S7 0x%x\n",((int)&edmp->s7) - (int )edmp); |
fprintf(f,"#define EOFFSET_T8 0x%x\n",((int)&edmp->t8) - (int )edmp); |
fprintf(f,"#define EOFFSET_T9 0x%x\n",((int)&edmp->t9) - (int )edmp); |
fprintf(f,"#define EOFFSET_GP 0x%x\n",((int)&edmp->gp) - (int )edmp); |
fprintf(f,"#define EOFFSET_SP 0x%x\n",((int)&edmp->sp) - (int )edmp); |
fprintf(f,"#define EOFFSET_S8 0x%x\n",((int)&edmp->s8) - (int )edmp); |
fprintf(f,"#define EOFFSET_RA 0x%x\n",((int)&edmp->ra) - (int )edmp); |
fprintf(f,"#define EOFFSET_LO 0x%x\n",((int)&edmp->lo) - (int )edmp); |
fprintf(f,"#define EOFFSET_HI 0x%x\n",((int)&edmp->hi) - (int )edmp); |
fprintf(f,"#define EOFFSET_STATUS 0x%x\n",((int)&edmp->status) - (int )edmp); |
fprintf(f,"#define EOFFSET_EPC 0x%x\n",((int)&edmp->epc) - (int )edmp); |
fprintf(f,"#define REGISTER_SPACE %d\n",sizeof(*edmp)); |
fclose(f); |
return 0; |
//SPARTAN/trunk/src/clean.mips |
---|
3,4 → 3,4 |
make dist-clean ARCH=mips |
rm ../tools/mips/gencontext |
rm ../arch/mips/src/context_offset.h |
rm ../arch/mips/include/context_offset.h |
//SPARTAN/trunk/arch/mips/include/exception.h |
---|
29,6 → 29,10 |
#ifndef __EXCEPTION_H__ |
#define __EXCEPTION_H__ |
#ifndef __mips_TYPES_H_ |
# include <arch/types.h> |
#endif |
#define EXC_Int 0 |
#define EXC_Mod 1 |
#define EXC_TLBL 2 |
48,6 → 52,44 |
#define EXC_WATCH 23 |
#define EXC_VCED 31 |
extern void exception(void); |
struct exception_regdump { |
__u32 at; |
__u32 v0; |
__u32 v1; |
__u32 a0; |
__u32 a1; |
__u32 a2; |
__u32 a3; |
__u32 t0; |
__u32 t1; |
__u32 t2; |
__u32 t3; |
__u32 t4; |
__u32 t5; |
__u32 t6; |
__u32 t7; |
__u32 s0; |
__u32 s1; |
__u32 s2; |
__u32 s3; |
__u32 s4; |
__u32 s5; |
__u32 s6; |
__u32 s7; |
__u32 t8; |
__u32 t9; |
__u32 gp; |
__u32 sp; |
__u32 s8; |
__u32 ra; |
__u32 lo; |
__u32 hi; |
__u32 status; /* cp0_status */ |
__u32 epc; /* cp0_epc */ |
}; |
extern void exception(struct exception_regdump *pstate); |
#endif |
//SPARTAN/trunk/arch/mips/include/thread.h |
---|
29,6 → 29,6 |
#ifndef __mips_THREAD_H__ |
#define __mips_THREAD_H__ |
#define ARCH_THREAD_DATA __u32 saved_epc; |
#define ARCH_THREAD_DATA |
#endif |
//SPARTAN/trunk/arch/mips/include/mm/tlb.h |
---|
29,6 → 29,8 |
#ifndef __mips_TLB_H__ |
#define __mips_TLB_H__ |
#include <arch/exception.h> |
#define PAGE_UNCACHED 2 |
#define PAGE_CACHEABLE_EXC_WRITE 5 |
63,7 → 65,7 |
typedef struct entry_lo pte_t; |
extern void tlb_refill(void); |
extern void tlb_invalid(void); |
extern void tlb_invalid(struct exception_regdump *pstate); |
extern void tlb_refill(struct exception_regdump *pstate); |
#endif |
//SPARTAN/trunk/arch/mips/include/context.h |
---|
31,45 → 31,6 |
#define STACK_ITEM_SIZE 4 |
/* These are offsets into the register dump saved |
* on exception entry |
*/ |
#define EOFFSET_AT 0 |
#define EOFFSET_V0 4 |
#define EOFFSET_V1 8 |
#define EOFFSET_A0 12 |
#define EOFFSET_A1 16 |
#define EOFFSET_A2 20 |
#define EOFFSET_A3 24 |
#define EOFFSET_A4 28 |
#define EOFFSET_T1 32 |
#define EOFFSET_T2 36 |
#define EOFFSET_T3 40 |
#define EOFFSET_T4 44 |
#define EOFFSET_T5 48 |
#define EOFFSET_T6 52 |
#define EOFFSET_T7 56 |
#define EOFFSET_T8 60 |
#define EOFFSET_T9 64 |
#define EOFFSET_S0 68 |
#define EOFFSET_S1 72 |
#define EOFFSET_S2 76 |
#define EOFFSET_S3 80 |
#define EOFFSET_S4 84 |
#define EOFFSET_S5 88 |
#define EOFFSET_S6 92 |
#define EOFFSET_S7 96 |
#define EOFFSET_S8 100 |
#define EOFFSET_GP 104 |
#define EOFFSET_RA 108 |
#define EOFFSET_SP 112 |
#define EOFFSET_LO 116 |
#define EOFFSET_HI 120 |
#define EOFFSET_STATUS 124 |
#define REGISTER_SPACE 128 |
/* |
* Put one item onto the stack to support get_stack_base(). |
*/ |
//SPARTAN/trunk/arch/mips/src/exception.c |
---|
34,10 → 34,9 |
#include <arch.h> |
#include <debug.h> |
void exception(void) |
void exception(struct exception_regdump *pstate) |
{ |
int excno; |
__u32 epc; |
__u32 epc_shift = 0; |
ASSERT(CPU != NULL); |
45,18 → 44,14 |
/* |
* NOTE ON OPERATION ORDERING |
* |
* On entry, cpu_priority_high() must be called before exception bit is cleared. |
* On exit, exception bit must be set before cpu_priority_restore() is called. |
* On entry, cpu_priority_high() must be called before |
* exception bit is cleared. |
*/ |
cpu_priority_high(); |
epc = cp0_epc_read(); |
cp0_status_write(cp0_status_read() & ~ (cp0_status_exl_exception_bit | |
cp0_status_um_bit)); |
if (THREAD) { |
THREAD->saved_epc = epc; |
} |
/* decode exception number and process the exception */ |
switch (excno = (cp0_cause_read() >> 2) & 0x1f) { |
case EXC_Int: |
64,7 → 59,7 |
break; |
case EXC_TLBL: |
case EXC_TLBS: |
tlb_invalid(); |
tlb_invalid(pstate); |
break; |
case EXC_Mod: |
panic("unhandled TLB Modification Exception\n"); |
114,12 → 109,5 |
panic("unhandled exception %d\n", excno); |
} |
if (THREAD) |
epc = THREAD->saved_epc; |
/* Raise EXL bit before epc_write, so that we support |
* properly nested exceptions |
*/ |
cp0_status_write(cp0_status_read() | cp0_status_exl_exception_bit); |
cp0_epc_write(epc + epc_shift); |
pstate->epc += epc_shift; |
} |
//SPARTAN/trunk/arch/mips/src/context.S |
---|
28,7 → 28,7 |
#define __ASM__ |
#include <arch/asm/regname.h> |
#include "context_offset.h" |
#include <arch/context_offset.h> |
.text |
//SPARTAN/trunk/arch/mips/src/mm/tlb.c |
---|
35,22 → 35,22 |
#include <symtab.h> |
void tlb_refill(void) |
void tlb_refill(struct exception_regdump *pstate) |
{ |
panic("tlb_refill exception\n"); |
} |
void tlb_invalid(void) |
void tlb_invalid(struct exception_regdump *pstate) |
{ |
char *symbol = ""; |
if (THREAD) { |
char *s = get_symtab_entry(THREAD->saved_epc); |
char *s = get_symtab_entry(pstate->epc); |
if (s) |
symbol = s; |
} |
panic("%X: TLB exception at %X(%s)\n", cp0_badvaddr_read(), |
THREAD ? THREAD->saved_epc : 0, symbol); |
pstate->epc, symbol); |
} |
void tlb_invalidate(int asid) |
//SPARTAN/trunk/arch/mips/src/start.S |
---|
31,7 → 31,7 |
#include <arch/asm/regname.h> |
#include <arch/mm/page.h> |
#include <arch/asm/boot.h> |
#include <arch/context.h> |
#include <arch/context_offset.h> |
.text |
55,7 → 55,7 |
sw $a1,EOFFSET_A1(\r) |
sw $a2,EOFFSET_A2(\r) |
sw $a3,EOFFSET_A3(\r) |
sw $t0,EOFFSET_A4(\r) |
sw $t0,EOFFSET_T0(\r) |
sw $t1,EOFFSET_T1(\r) |
sw $t2,EOFFSET_T2(\r) |
sw $t3,EOFFSET_T3(\r) |
86,6 → 86,8 |
mfc0 $at, $status |
sw $at,EOFFSET_STATUS(\r) |
mfc0 $at, $epc |
sw $at,EOFFSET_EPC(\r) |
.endm |
.macro REGISTERS_LOAD r |
95,7 → 97,7 |
lw $a1,EOFFSET_A1(\r) |
lw $a2,EOFFSET_A2(\r) |
lw $a3,EOFFSET_A3(\r) |
lw $t0,EOFFSET_A4(\r) |
lw $t0,EOFFSET_T0(\r) |
lw $t1,EOFFSET_T1(\r) |
lw $t2,EOFFSET_T2(\r) |
lw $t3,EOFFSET_T3(\r) |
124,6 → 126,8 |
lw $at,EOFFSET_STATUS(\r) |
mtc0 $at, $status |
lw $at,EOFFSET_EPC(\r) |
mtc0 $at, $epc |
lw $at,EOFFSET_AT(\r) |
lw $sp,EOFFSET_SP(\r) |
191,7 → 195,8 |
REGISTERS_STORE $k0 |
add $sp, $k0, 0 |
jal exception |
add $a0, $sp, 0 |
jal exception /* exception(register_space) */ |
nop |
REGISTERS_LOAD $sp |
205,7 → 210,8 |
REGISTERS_STORE $k0 |
add $sp, $k0, 0 |
jal tlb_refill |
add $a0, $sp, 0 |
jal tlb_refill /* tlb_refill(register_space) */ |
nop |
REGISTERS_LOAD $sp |