Added clz testcase, add nop before and after cp0 instructions

This commit is contained in:
141242068-ouxianfei 2018-07-21 19:50:55 +08:00
parent 9e46fc035e
commit a3b104322a
9 changed files with 164 additions and 26 deletions

View File

@ -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

View File

@ -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(

View File

@ -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},
};

View File

@ -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

View File

@ -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;
}

35
tests/cputest/tests/clz.c Normal file
View File

@ -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;
}

View File

@ -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

View File

@ -0,0 +1,5 @@
.section .data
.global __fsimg_start, __fsimg_end
__fsimg_start:
.incbin "build/fsimg"
__fsimg_end:

49
tests/segmenttest/main.c Normal file
View File

@ -0,0 +1,49 @@
#include <am.h>
#include <amdev.h>
#include <klib.h>
_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;
}