diff --git a/am/Makefile b/am/Makefile index 9dbb61c4..ac8efe4b 100644 --- a/am/Makefile +++ b/am/Makefile @@ -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 diff --git a/am/arch/mips32-npc/include/npc.h b/am/arch/mips32-npc/include/npc.h index 33257019..bec69f09 100644 --- a/am/arch/mips32-npc/include/npc.h +++ b/am/arch/mips32-npc/include/npc.h @@ -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; } diff --git a/am/arch/mips32-npc/src/asym.c b/am/arch/mips32-npc/src/asym.c index 9d63e570..4734af5f 100644 --- a/am/arch/mips32-npc/src/asym.c +++ b/am/arch/mips32-npc/src/asym.c @@ -1,20 +1,21 @@ #include #include #include +#include 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;