diff --git a/am/arch/mips32-npc/include/npc.h b/am/arch/mips32-npc/include/npc.h index b98a23c6..6192aba8 100644 --- a/am/arch/mips32-npc/include/npc.h +++ b/am/arch/mips32-npc/include/npc.h @@ -90,10 +90,10 @@ typedef struct { #define EXC_TRAP 13 #define MFC0(dst, src, sel) \ -asm volatile("mfc0 %0, $"_STR(src)", %1\n\t":"=r"(dst):"i"(sel)) +asm volatile("nop; nop; nop; mfc0 %0, $"_STR(src)", %1; nop; nop; nop\n\t":"=r"(dst):"i"(sel)) #define MTC0(dst, src, sel) \ -asm volatile("mtc0 %0, $"_STR(dst)", %1\n\t"::"g"(src),"i"(sel)) +asm volatile("nop; nop; mtc0 %0, $"_STR(dst)", %1; nop; nop\n\t"::"g"(src),"i"(sel)) #define _STR(x) _VAL(x) #define _VAL(x) #x diff --git a/am/arch/mips32-npc/src/asye.c b/am/arch/mips32-npc/src/asye.c index dd3e2f35..d3d6a1df 100644 --- a/am/arch/mips32-npc/src/asye.c +++ b/am/arch/mips32-npc/src/asye.c @@ -8,13 +8,11 @@ static _RegSet* (*H) (_Event, _RegSet*) = NULL; void print_timer() { int compare = 0; MFC0(compare, CP0_COMPARE, 0); - int count = 0; - MFC0(count, CP0_COUNT, 0); - printk("\e[33m[AM]\e[0m:%d, %d\n", compare, count); - - static int counter = 0; - counter ++; - if(counter > 40) _halt(0); + int count0 = 0; + MFC0(count0, CP0_COUNT, 0); + int count1 = 0; + MFC0(count1, CP0_COUNT, 1); + printk("\e[33m[AM]\e[0m: compare:%d, count0:%d, count1:%d\n", compare, count0, count1); } void update_timer(uint32_t step) { @@ -53,7 +51,7 @@ _RegSet *_make(_Area kstack, void (*entry)(void *), void *args){ void _yield(){ init_timer(INTERVAL); - asm volatile("addiu $a0, $0, -1; syscall; nop"); + asm volatile("nop; li $a0, -1; syscall; nop"); } int _intr_read() { @@ -73,6 +71,9 @@ void irq_handle(struct _RegSet *regs){ cp0_cause_t *cause = (void*)&(regs->cause); uint32_t exccode = cause->ExcCode; uint32_t ipcode = cause->IP; + + // print_timer(); + // printk("[AM] cause:%x, status:%x, code:%x, ip:%x\n", regs->cause, regs->status, exccode, ipcode); _Event ev; ev.event = _EVENT_NULL; @@ -107,7 +108,8 @@ void irq_handle(struct _RegSet *regs){ case EXC_RI: case EXC_OV: default: - printk("unhandled exccode = %x, epc:%08x\n", exccode, regs->epc); + printk("unhandled exccode = %x, epc:%08x, badvaddr:%08x\n", exccode, regs->epc, regs->badvaddr); + printk("cp0: base:%08x, cause:%08x, status:%08x\n", regs->base, regs->cause, regs->status); _halt(-1); } @@ -117,7 +119,16 @@ void irq_handle(struct _RegSet *regs){ _RegSet *next = H(ev, regs); if(next != NULL) ret = next; } - // printf("rets: t0:%x, t1:%x, t2:%x, t3:%x\n", ret->t0, ret->t1, ret->t2, ret->t3); + /* + printk("======================\n"); + int count0 = 0; + MFC0(count0, CP0_COUNT, 0); + while(count0 > 0) { + _putc(count0 % 10 + '0'); + count0 /= 10; + } + _putc('\n'); + */ // restore common registers asm volatile( diff --git a/am/arch/mips32-npc/src/ioe.c b/am/arch/mips32-npc/src/ioe.c index b4d4f3c2..db2e574f 100644 --- a/am/arch/mips32-npc/src/ioe.c +++ b/am/arch/mips32-npc/src/ioe.c @@ -171,7 +171,7 @@ int e0_scan_code[256] = { [0x7D] = _KEY_PAGEUP, }; -size_t input_read(uintptr_t reg, void *buf, size_t size) { +static size_t keyboard_read(uintptr_t reg, void *buf, size_t size) { int code = in_scancode(); int *table = normal_scancode; @@ -192,7 +192,7 @@ size_t input_read(uintptr_t reg, void *buf, size_t size) { static _Device mips32_npc_dev[] = { {_DEV_SERIAL, "NOOP Serial Controller", uartlite_read, uartlite_write}, - {_DEV_INPUT, "NOOP Keyboard Controller", input_read, NULL}, + {_DEV_INPUT, "NOOP Keyboard Controller", keyboard_read, NULL}, {_DEV_TIMER, "NOOP Fake Timer", timer_read, NULL}, {_DEV_VIDEO, "NoneStandard VGA Controller", video_read, video_write}, }; diff --git a/am/arch/mips32-npc/src/trap.S b/am/arch/mips32-npc/src/trap.S index 6de76c08..c14e2529 100644 --- a/am/arch/mips32-npc/src/trap.S +++ b/am/arch/mips32-npc/src/trap.S @@ -45,15 +45,35 @@ _trap_entry: addu $sp, $k0, $0 + nop + nop mfc0 $k0, $14 + nop + nop sw $k0, 0x80($sp) + nop + nop mfc0 $k0, $13 + nop + nop sw $k0, 0x84($sp) + nop + nop mfc0 $k0, $12 + nop + nop sw $k0, 0x88($sp) + nop + nop mfc0 $k0, $8 + nop + nop sw $k0, 0x8c($sp) + nop + nop mfc0 $k0, $7 + nop + nop sw $k0, 0x90($sp) # give trapframe pointer to a0 addiu $a0, $sp, 0x4 diff --git a/tests/asyetest/main.c b/tests/asyetest/main.c index 7a3bb6ae..c49979b4 100644 --- a/tests/asyetest/main.c +++ b/tests/asyetest/main.c @@ -35,9 +35,8 @@ _RegSet* handler(_Event ev, _RegSet *regs) { #define _STR(x) _VAL(x) #define _VAL(x) #x -/* #define MFC0(dst, src, sel) \ -asm volatile("mfc0 %0, $"_STR(src)", %1\n\t":"=r"(dst):"i"(sel)) +asm volatile("nop; nop; mfc0 %0, $"_STR(src)", %1; nop; nop\n\t":"=r"(dst):"i"(sel)) void read_write_cp0() { int reg; @@ -45,29 +44,29 @@ void read_write_cp0() { reg = 0x12345678; \ MFC0(reg, src, sel); \ printf("CP0:{" #src ", " #sel "}=%x\n", reg); - CP0_OUT(8, 0) - CP0_OUT(9, 0) - CP0_OUT(9, 1) - CP0_OUT(11, 0) - CP0_OUT(12, 0) - CP0_OUT(13, 0) - CP0_OUT(14, 0) + CP0_OUT(8, 0) // badvaddr + CP0_OUT(9, 0) // count0 + CP0_OUT(9, 1) // count1 + CP0_OUT(11, 0) // compare + CP0_OUT(12, 0) // status + CP0_OUT(13, 0) // cause + CP0_OUT(14, 0) // epc } -*/ int main(){ _ioe_init(); _asye_init(handler); - // read_write_cp0(); + read_write_cp0(); assert(!_intr_read()); _intr_write(1); //_make(_heap, void*)main, 0); printf("intr:%x\n", _intr_read()); + _yield(); while (1) { for(int i = 0; i < 10; i++) printf("-"); printf(":yield, intr:%x\n", _intr_read()); - _yield(); + while(1); // no yield } return 0; } diff --git a/tests/cputest/tests/clz.c b/tests/cputest/tests/clz.c new file mode 100644 index 00000000..7b5e1c51 --- /dev/null +++ b/tests/cputest/tests/clz.c @@ -0,0 +1,35 @@ +#include "trap.h" + +int clz(uint32_t x) { + if(!x) return 32; + static const char debruijn32[32] = { + 0, 31, 9, 30, 3, 8, 13, 29, 2, 5, 7, 21, 12, 24, 28, 19, + 1, 10, 4, 14, 6, 22, 25, 20, 11, 15, 23, 26, 16, 27, 17, 18 + }; + x |= x>>1; + x |= x>>2; + x |= x>>4; + x |= x>>8; + x |= x>>16; + x++; + return debruijn32[x*0x076be629>>27]; +} + +int main() { +#ifdef __ISA_MIPS32__ + { + // special case, in == 0 + int in = 0, out = 0; + asm volatile("clz %0, %1": "=r"(out) : "r"(in)); + nemu_assert(out == clz(in)); + } + + for(int i = 0; i < 32; i++) { + int in = 1 << i; + int out = 0; + asm volatile("clz %0, %1": "=r"(out) : "r"(in)); + nemu_assert(out == clz(in)); + } +#endif + return 0; +} diff --git a/tests/segmenttest/Makefile b/tests/segmenttest/Makefile new file mode 100644 index 00000000..efcaa34f --- /dev/null +++ b/tests/segmenttest/Makefile @@ -0,0 +1,19 @@ +NAME = segmenttest +SRCS = main.c initrd.S +LIBS += klib compiler-rt +ARCH ?= mips32-npc + +TESTCASE = load-store +INITRD_S = initrd.S + +TESTBIN = $(AM_HOME)/tests/cputest/build/$(TESTCASE)-$(ARCH).bin + +$(TESTBIN): $(AM_HOME)/tests/cputest/tests/$(TESTCASE).c + make -s -C $(@D)/.. ARCH=$(ARCH) + +$(INITRD_S): $(TESTBIN) + @cp $< build/fsimg + @touch $@ + echo + $@ + +include $(AM_HOME)/Makefile.app diff --git a/tests/segmenttest/initrd.S b/tests/segmenttest/initrd.S new file mode 100644 index 00000000..28574af4 --- /dev/null +++ b/tests/segmenttest/initrd.S @@ -0,0 +1,5 @@ +.section .data +.global __fsimg_start, __fsimg_end +__fsimg_start: +.incbin "build/fsimg" +__fsimg_end: diff --git a/tests/segmenttest/main.c b/tests/segmenttest/main.c new file mode 100644 index 00000000..a5730e4a --- /dev/null +++ b/tests/segmenttest/main.c @@ -0,0 +1,49 @@ +#include +#include +#include + +_RegSet testcase_regs; + +int ntraps = 0; +_RegSet* handler(_Event ev, _RegSet *regs) { + switch (ev.event) { + case _EVENT_IRQ_TIMER: + printf("."); + break; + case _EVENT_IRQ_IODEV: + while (1) { + int key = read_key(); + if (key == _KEY_NONE) break; + if (key & 0x8000) { + printf("[D:%d]", key ^ 0x8000); + } else { + printf("[U:%d]/[TRAPS:%d]", key, ntraps); + ntraps = 0; + } + } + break; + case _EVENT_YIELD: + ntraps++; + break; + } + return &testcase_regs; +} + +void load_testcase() { + extern char __fsimg_start; + extern char __fsimg_end; +} + +int main(){ + _ioe_init(); + _asye_init(handler); + + assert(!_intr_read()); + _intr_write(1); + + load_testcase(); + + _yield(); + while(1) { } + return 0; +}