Browse Source

[pk] fixed timer interrupt bug, etc.

cs250
Andrew Waterman 15 years ago
parent
commit
ba0cf05466
  1. 1
      pk/entry.S
  2. 2
      pk/fp.c
  3. 38
      pk/handlers.c
  4. 3
      pk/pcr.h
  5. 8
      pk/pk.h
  6. 20
      pk/syscall.c

1
pk/entry.S

@ -132,7 +132,6 @@ trap_entry:
jal save_tf
move $sp,$x2
move $a0,$x2
ei
jal handle_trap
.end trap_entry

2
pk/fp.c

@ -195,8 +195,6 @@ int emulate_fp(trapframe_t* tf)
if(have_fp)
put_fp_state(fp_state.fpr,fp_state.fsr);
advance_pc(tf);
return 0;
}

38
pk/handlers.c

@ -6,20 +6,10 @@ int have_vector = 1;
static void handle_fp_disabled(trapframe_t* tf)
{
if(have_fp)
init_fp(tf);
else
{
#ifdef PK_ENABLE_FP_EMULATION
if(emulate_fp(tf) != 0)
{
dump_tf(tf);
panic("FPU emulation failed!");
}
#else
panic("FPU emulation disabled! pc %lx, insn %x",tf->epc,(uint32_t)tf->insn);
#endif
}
irq_enable();
kassert(have_fp);
init_fp(tf);
}
static void handle_vector_disabled(trapframe_t* tf)
@ -39,8 +29,13 @@ static void handle_privileged_instruction(trapframe_t* tf)
static void handle_illegal_instruction(trapframe_t* tf)
{
#ifdef PK_ENABLE_FP_EMULATION
irq_enable();
if(emulate_fp(tf) == 0)
{
advance_pc(tf);
return;
}
#endif
dump_tf(tf);
@ -113,6 +108,19 @@ static void handle_interrupt(trapframe_t* tf)
}
}
static void handle_syscall(trapframe_t* tf)
{
irq_enable();
long n = tf->gpr[2];
sysret_t ret = syscall(tf->gpr[4], tf->gpr[5], tf->gpr[6], tf->gpr[7], n);
tf->gpr[2] = ret.result;
tf->gpr[3] = ret.result == -1 ? ret.err : 0;
advance_pc(tf);
}
void handle_trap(trapframe_t* tf)
{
typedef void (*trap_handler)(trapframe_t*);
@ -134,7 +142,7 @@ void handle_trap(trapframe_t* tf)
};
int exccode = (tf->cause & CAUSE_EXCCODE) >> CAUSE_EXCCODE_SHIFT;
kassert(exccode < sizeof(trap_handlers)/sizeof(trap_handlers[0]));
kassert(exccode < ARRAY_SIZE(trap_handlers));
trap_handlers[exccode](tf);

3
pk/pcr.h

@ -71,6 +71,9 @@
asm volatile ("mfcr %0,$cr%1" : "=r"(__tmp) : "i"(reg)); \
__tmp; })
#define irq_disable() asm volatile("di")
#define irq_enable() asm volatile("ei")
#endif
#endif

8
pk/pk.h

@ -8,6 +8,7 @@
#ifndef __ASSEMBLER__
#include <stdint.h>
#include <machine/syscall.h>
typedef struct
{
@ -37,7 +38,6 @@ void pop_tf(trapframe_t*);
void dump_tf(trapframe_t*);
void unhandled_trap(trapframe_t*);
void handle_syscall(trapframe_t*);
void handle_misaligned_load(trapframe_t*);
void handle_misaligned_store(trapframe_t*);
void handle_fault_load(trapframe_t*);
@ -45,14 +45,18 @@ void handle_fault_store(trapframe_t*);
void boot();
void sys_exit(int code) __attribute__((noreturn));
sysret_t syscall(long a0, long a1, long a2, long a3, long n);
long load_elf(const char* fn, int* user64);
static inline void advance_pc(trapframe_t* tf)
{
tf->epc += 4;
int rvc = (tf->insn & 0x3) < 0x3;
tf->epc += rvc ? 2 : 4;
}
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
#ifdef __cplusplus
}
#endif

20
pk/syscall.c

@ -92,7 +92,7 @@ sysret_t sys_unlink(const char* name, size_t len)
return frontend_syscall(SYS_unlink,(long)name,len,0,0);
}
void handle_syscall(trapframe_t* tf)
sysret_t syscall(long a0, long a1, long a2, long a3, long n)
{
const static void* syscall_table[] = {
[SYS_exit] = sys_exit,
@ -108,22 +108,8 @@ void handle_syscall(trapframe_t* tf)
[SYS_unlink] = sys_unlink,
};
syscall_t p;
unsigned long n = tf->gpr[2];
if(n >= sizeof(syscall_table)/sizeof(void*) || !syscall_table[n])
{
dump_tf(tf);
if(n >= ARRAY_SIZE(syscall_table) || !syscall_table[n])
panic("bad syscall #%ld!",n);
}
else
p = (syscall_t)syscall_table[n];
sysret_t ret = p(tf->gpr[4],tf->gpr[5],tf->gpr[6],tf->gpr[7],n);
tf->gpr[2] = ret.result;
tf->gpr[3] = ret.result == -1 ? ret.err : 0;
//printk("syscall %d (%x,%x,%x,%x) from %x == %d\n",n,tf->gpr[4],tf->gpr[5],tf->gpr[6],tf->gpr[7],tf->gpr[31],tf->gpr[2]);
advance_pc(tf);
pop_tf(tf);
return ((syscall_t)syscall_table[n])(a0, a1, a2, a3, n);
}

Loading…
Cancel
Save