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 NAME = am
SRCS = $(shell find -L ./arch/$(ARCH)/src/ -name "*.c" -o -name "*.cpp" -o -name "*.S") SRCS = $(shell find -L ./arch/$(ARCH)/src/ -name "*.c" -o -name "*.cpp" -o -name "*.S")
LIBS += klib
include $(AM_HOME)/Makefile.lib include $(AM_HOME)/Makefile.lib

View File

@ -14,6 +14,23 @@
#define HZ 50000000 #define HZ 50000000
#define MAX_MEMORY_SIZE 0x4000000 #define MAX_MEMORY_SIZE 0x4000000
#define INTERVAL 1000 #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 R(_Pixel p) { return p >> 16; }
static inline u8 G(_Pixel p) { return p >> 8; } static inline u8 G(_Pixel p) { return p >> 8; }

View File

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