fix exception

This commit is contained in:
141220007 2017-06-02 02:05:15 +08:00
parent 4b83f155b9
commit b302f528b9
3 changed files with 54 additions and 28 deletions

View File

@ -1,3 +1,4 @@
NAME = am
SRCS = $(shell find -L ./arch/$(ARCH)/src/ -name "*.c" -o -name "*.cpp" -o -name "*.S")
LIBS += klib
include $(AM_HOME)/Makefile.lib

View File

@ -14,6 +14,23 @@
#define HZ 50000000
#define MAX_MEMORY_SIZE 0x4000000
#define INTERVAL 1000
#define cp0_badvaddr 8
#define cp0_count 9
#define cp0_compare 11
#define cp0_status 12
#define cp0_cause 13
#define cp0_epc 14
#define MFC0(dst, src, sel) \
asm volatile("mfc0 %0, $"_STR(src)", %1\n\t":"=r"(dst):"i"(sel))
#define MTC0(dst, src, sel) \
asm volatile("mtc0 %0, $"_STR(dst)", %1\n\t"::"g"(src),"i"(sel))
#define _STR(x) _VAL(x)
#define _VAL(x) #x
static inline u8 R(_Pixel p) { return p >> 16; }
static inline u8 G(_Pixel p) { return p >> 8; }

View File

@ -1,20 +1,21 @@
#include <am.h>
#include <npc.h>
#include <arch.h>
#include <klib.h>
u32 GetCount(int sel){
u32 tick = 0;
if(sel == 1)
asm volatile("mfc0 %0, $9, %1\n\t":"=r"(tick):"i"(1));
else if(sel == 0)
asm volatile("mfc0 %0, $9, %1\n\t":"=r"(tick):"i"(0));
if(sel == 0)
MFC0(tick, cp0_count, 0);
else if(sel == 1)
MFC0(tick, cp0_count, 1);
else
_halt(1);
return tick;
}
void SetCompare(u32 compare){
asm volatile("mtc0 %0, $11\n\t"::"r"(compare));
MTC0(cp0_compare, compare, 0);
}
void _time_event(){
@ -40,21 +41,21 @@ void _idle(){
void _idisable(){
int status = 0;
asm volatile("mfc0 %0,$12 \n\t":"=r"(status));
MFC0(status, cp0_status, 0);
status = status | 0x2;
asm volatile("mtc0 %0,$12 \n\t"::"r"(status));
MTC0(cp0_status, status, 0);
}
void _ienable(){
int status = 0;
asm volatile("mfc0 %0,$12 \n\t":"=r"(status));
MFC0(status, cp0_status, 0);
status = status & 0xfffffffd;
asm volatile("mtc0 %0,$12 \n\t"::"r"(status));
MTC0(cp0_status, status, 0);
}
int _istatus(){
int status = 0;
asm volatile("mfc0 %0,$12 \n\t":"=r"(status));
MFC0(status, cp0_status, 0);
if((status & 0x2) >> 1){
return 0;
}
@ -65,19 +66,22 @@ int _istatus(){
void irq_handle(struct TrapFrame *tf){
//TODO:handle interrupt
u32 arg = 0;
u32 intr = 0;
u8 IPCode = 0;
u8 ExcCode = 0;
u32 EPC = 0;
u32 BadVaddr = 0;
u32 arg = 0, IPExcCode = 0;
u8 IPCode = 0, ExcCode = 0;
u32 EPC = 0, BadVaddr = 0;
// cp0 info & general regfiles, values of k0 & k1 come from trap.S
asm volatile("add %0,$k1,$zero\n\t":"=r"(arg));
asm volatile("add %0,$k0,$zero\n\t":"=r"(intr));
asm volatile("mfc0 %0, $14\n\t":"=r"(EPC));
asm volatile("mfc0 %0, $8\n\t":"=r"(BadVaddr));
asm volatile("add %0,$k0,$zero\n\t":"=r"(IPExcCode));
MFC0(EPC, cp0_epc, 0);
MFC0(BadVaddr, cp0_badvaddr, 0);
tf = (void *)arg;
IPCode = (intr & 0xff00) >> 8;
ExcCode = (intr & 0xff) >> 2;
IPCode = (IPExcCode & 0xff00) >> 8;
ExcCode = (IPExcCode & 0xff) >> 2;
//TODO: exception handling
switch(ExcCode){
case 0:{ //interrupt
switch(IPCode){
@ -107,32 +111,36 @@ void irq_handle(struct TrapFrame *tf){
}
break;
case 8:{ // syscall
printk("syscall\n");
printk("Syscall\n");
printk("$epc = 0x%x\n", EPC);
// epc + 4 -> used to eret to next instruction, instead of syscall
EPC += 4;
asm volatile("mtc0 %0, $14\n\t"::"g"(EPC));
MTC0(cp0_epc, EPC, 0);
_halt(0);
}
break;
case 9:{ // breakpoint
printk("Break\n");
EPC += 4;
asm volatile("mtc0 %0, $14\n\t"::"g"(EPC));
printk("$epc = 0x%x\n", EPC);
_halt(0);
}
break;
case 10:{ // invalid instruction
printk("Invalid instruction\n");
printk("$epc = 0x%x\n", EPC);
_halt(0);
}
break;
case 12:{ // overflow
printk("Overflow\n");
EPC += 4;
asm volatile("mtc0 %0, $14\n\t"::"g"(EPC));
printk("$epc = 0x%x\n", EPC);
_halt(0);
}
break;
case 13:{ // trap
printk("Trap\n");
EPC += 4;
asm volatile("mtc0 %0, $14\n\t"::"g"(EPC));
MTC0(cp0_epc, EPC, 0);
_halt(0);
}
break;