提交 77ecbf52 编写于 作者: Z Zihao Yu

remove stale riscv32-noop

上级 064fac47
include $(AM_HOME)/am/arch/isa/riscv32.mk
AM_SRCS := $(ISA)/noop/trm.c \
$(ISA)/noop/uartlite.c \
$(ISA)/noop/perf.c \
$(ISA)/noop/cte.c \
$(ISA)/nemu/trap.S \
$(ISA)/noop/instr.c \
$(ISA)/nemu/vme.c \
nemu-common/ioe.c \
$(ISA)/noop/input.c \
nemu-common/nemu-timer.c \
nemu-common/nemu-video.c \
dummy/mpe.c \
$(ISA)/nemu/boot/start.S
LDFLAGS += -L $(AM_HOME)/am/src/nemu-common
LDFLAGS += -T $(AM_HOME)/am/src/$(ISA)/nemu/boot/loader.ld
image:
@echo + LD "->" $(BINARY_REL).elf
@$(LD) $(LDFLAGS) --gc-sections -o $(BINARY).elf --start-group $(LINK_FILES) --end-group
@$(OBJDUMP) -d $(BINARY).elf > $(BINARY).txt
@echo + OBJCOPY "->" $(BINARY_REL).bin
@$(OBJCOPY) -S --set-section-flags .bss=alloc,contents -O binary $(BINARY).elf $(BINARY).bin
run:
$(MAKE) -C $(NOOP_HOME) emu IMAGE="$(BINARY).bin"
#ifndef __ARCH_H__
#define __ARCH_H__
#include <riscv32.h>
struct _Context {
union {
struct _AddressSpace *as;
uint32_t gpr[32];
};
uint32_t cause;
uint32_t status;
uint32_t epc;
};
#define GPR1 gpr[17] // a7
#define GPR2 gpr[10] // a0
#define GPR3 gpr[11] // a1
#define GPR4 gpr[12] // a2
#define GPRx gpr[10] // a0
#define MAP(c, f) c(f)
#define COUNTERS(f) \
f(cycle) f(time) f(instr)
#define CNT_IDX(cnt) PERFCNT_##cnt
#define CNT_ENUM_ITEM(cnt) CNT_IDX(cnt),
enum {
MAP(COUNTERS, CNT_ENUM_ITEM)
NR_PERFCNT,
};
typedef struct {
R64 cnts[NR_PERFCNT];
} PerfCntSet;
void __am_perfcnt_read(PerfCntSet *t);
void __am_perfcnt_sub(PerfCntSet *res, PerfCntSet *t1, PerfCntSet *t0);
void __am_perfcnt_add(PerfCntSet *res, PerfCntSet *t1, PerfCntSet *t0);
void __am_perfcnt_show(PerfCntSet *t);
void __am_perfcnt_excel(PerfCntSet *t);
#endif
#include <am.h>
#include <riscv32.h>
#include <klib.h>
static _Context* (*user_handler)(_Event, _Context*) = NULL;
void __am_get_cur_as(_Context *c);
void __am_switch(_Context *c);
int __am_illegal_instr(_Context *c);
_Context* __am_irq_handle(_Context *c) {
__am_get_cur_as(c);
_Context *next = c;
if (user_handler) {
_Event ev = {0};
switch (c->cause) {
//case 0: ev.event = _EVENT_IRQ_TIMER; break;
case 2:
if (__am_illegal_instr(c)) c->epc += 4;
break;
case 9:
ev.event = (c->GPR1 == -1) ? _EVENT_YIELD : _EVENT_SYSCALL;
c->epc += 4;
break;
default: ev.event = _EVENT_ERROR; break;
}
next = user_handler(ev, c);
if (next == NULL) {
next = c;
}
}
// __am__switch(next);
return next;
}
extern void __am_asm_trap(void);
int _cte_init(_Context*(*handler)(_Event, _Context*)) {
// initialize exception entry
asm volatile("csrw stvec, %0" : : "r"(__am_asm_trap));
// register event handler
user_handler = handler;
return 0;
}
_Context *_kcontext(_Area stack, void (*entry)(void *), void *arg) {
_Context *c = (_Context*)stack.end - 1;
c->epc = (uintptr_t)entry;
c->status = 0x000c0100;
return c;
}
void _yield() {
asm volatile("li a7, -1; ecall");
}
int _intr_read() {
return 0;
}
void _intr_write(int enable) {
}
#include <am.h>
#include <amdev.h>
#include <nemu.h>
#include <klib.h>
#define KEYDOWN_MASK 0x8000
int __am_uartlite_getchar();
static int am_keycode[128] = {
[' '] = _KEY_SPACE,
['a'] = _KEY_A, ['b'] = _KEY_B, ['c'] = _KEY_C, ['d'] = _KEY_D,
['e'] = _KEY_E, ['f'] = _KEY_F, ['g'] = _KEY_G, ['h'] = _KEY_H,
['i'] = _KEY_I, ['j'] = _KEY_J, ['k'] = _KEY_K, ['l'] = _KEY_L,
['m'] = _KEY_M, ['n'] = _KEY_N, ['o'] = _KEY_O, ['p'] = _KEY_P,
['q'] = _KEY_Q, ['r'] = _KEY_R, ['s'] = _KEY_S, ['t'] = _KEY_T,
['u'] = _KEY_U, ['v'] = _KEY_V, ['w'] = _KEY_W, ['x'] = _KEY_X,
['y'] = _KEY_Y, ['z'] = _KEY_Z
};
size_t __am_input_read(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
case _DEVREG_INPUT_KBD: {
_DEV_INPUT_KBD_t *kbd = (_DEV_INPUT_KBD_t *)buf;
static int last_key = _KEY_NONE;
static int last_release = 0;
static unsigned long timestamp = 0;
kbd->keydown = 0;
kbd->keycode = _KEY_NONE;
if (last_release) {
// and return the makecode of the last key
kbd->keydown = 1;
kbd->keycode = last_key;
last_release = 0;
timestamp = uptime();
} else {
int _k = __am_uartlite_getchar();
assert(_k < 128 && _k >= 0);
int key = am_keycode[_k];
if (key == _KEY_NONE) {
if (last_key != _KEY_NONE) {
unsigned long now = uptime();
if (now - timestamp > 500) {
kbd->keydown = 0;
kbd->keycode = last_key;
last_key = _KEY_NONE;
}
}
} else {
int another_key = (key != _KEY_NONE && last_key != _KEY_NONE && key != last_key);
// if we press a different key, now return the breakcode of the old key,
// and return the makecode of new key next time
kbd->keydown = another_key ? 0 : 1;
kbd->keycode = another_key ? last_key : key;
last_key = key;
last_release = another_key;
if (!another_key) timestamp = uptime();
}
}
return sizeof(_DEV_INPUT_KBD_t);
}
}
return 0;
}
#include <am.h>
#include <riscv32.h>
#include <klib.h>
#include <klib-macros.h>
static uint32_t mul(uint32_t a, uint32_t b, int sign, int hi) {
if (a == 0x80000000 && b == 0x80000000) {
// hard code the result for this special case
const R64 res = {.val = 0x4000000000000000LL};
return (hi ? res.hi : res.lo);
}
else if (b == 0x80000000) {
// swap the operands
uint32_t t = a;
a = b;
b = t;
}
int sign_a = 0, sign_b = 0;
if (sign) {
if ((int32_t)a < 0) { sign_a = 1; a = -a; }
if ((int32_t)b < 0) { sign_b = 1; b = -b; }
}
// booth algorithm
R64 P = {.hi = 0, .lo = b };
uint32_t choose = (P.lo & 1) << 1;
int i;
for (i = 32; i > 0; i --) {
switch (choose) {
case 1: P.hi += a; break;
case 2: P.hi -= a; break;
}
choose = P.lo & 0x3;
P.val >>= 1;
}
if (sign_a ^ sign_b) P.val = -P.val;
return (hi ? P.hi : P.lo);
}
static uint32_t div(uint32_t a, uint32_t b, int sign, int reminder) {
int sign_a = 0, sign_b = 0;
if (sign) {
if ((int32_t)a < 0) { sign_a = 1; a = -a; }
if ((int32_t)b < 0) { sign_b = 1; b = -b; }
}
// non-performing restoring division
R64 R = {.val = a};
R.val <<= 1;
int i;
for (i = 32; i > 1; i --) {
if (R.hi >= b) {
R.hi -= b;
R.val = (R.val << 1) + 1;
}
else {
R.val <<= 1;
}
}
R.lo <<= 1;
if (R.hi >= b) {
R.hi -= b;
R.lo ++;
}
if (sign_a ^ sign_b) R.lo = -R.lo;
if (sign_a) R.hi = -R.hi;
return (reminder ? R.hi : R.lo);
}
int __am_illegal_instr(_Context *c) {
union {
struct {
uint32_t opcode :7;
uint32_t rd :5;
uint32_t func :3;
uint32_t rs1 :5;
uint32_t rs2 :5;
uint32_t func2 :7;
};
uint32_t val;
} instr;
instr.val = *(uint32_t *)(c->epc);
if (instr.opcode == 0x33 && instr.func2 == 1) {
// M extension
uint32_t rs1 = c->gpr[instr.rs1];
uint32_t rs2 = c->gpr[instr.rs2];
switch (instr.func) {
/* mul */ case 0: c->gpr[instr.rd] = mul(rs1, rs2, true, false); return true;
/* mulh */ case 1: c->gpr[instr.rd] = mul(rs1, rs2, true, true); return true;
/* div */ case 4: c->gpr[instr.rd] = div(rs1, rs2, true, false); return true;
/* divu */ case 5: c->gpr[instr.rd] = div(rs1, rs2, false, false); return true;
/* rem */ case 6: c->gpr[instr.rd] = div(rs1, rs2, true, true); return true;
/* remu */ case 7: c->gpr[instr.rd] = div(rs1, rs2, false, true); return true;
}
}
printf("invalid instruction\n");
_halt(1);
return false;
}
uint32_t __mulsi3 (uint32_t a, uint32_t b) {
// mul a0, a0, a1
asm volatile(".word 0x02b50533");
return a;
// return mul(a, b, true, false);
}
uint32_t __divsi3 (uint32_t a, uint32_t b) { return div(a, b, true, false); }
uint32_t __modsi3 (uint32_t a, uint32_t b) { return div(a, b, true, true); }
uint32_t __umodsi3(uint32_t a, uint32_t b) { return div(a, b, false, true); }
uint32_t __udivsi3(uint32_t a, uint32_t b) { return div(a, b, false, false); }
#include <am.h>
#include <klib.h>
#define PERFCNT_BASE 0xb00
#define CNT_NAME(cnt) #cnt,
static const char *name [] = {
MAP(COUNTERS, CNT_NAME)
};
void __am_perfcnt_read(PerfCntSet *set) {
#define READ_LO(cnt) \
asm volatile("csrr %0, %1" : "=r"(set->cnts[CNT_IDX(cnt)].lo) : "i"(PERFCNT_BASE + CNT_IDX(cnt)));
#define READ_HI(cnt) \
asm volatile("csrr %0, %1" : "=r"(set->cnts[CNT_IDX(cnt)].hi) : "i"(PERFCNT_BASE + 0x80 + CNT_IDX(cnt)));
MAP(COUNTERS, READ_LO)
MAP(COUNTERS, READ_HI)
}
void __am_perfcnt_sub(PerfCntSet *res, PerfCntSet *t1, PerfCntSet *t0) {
int i;
for (i = 0; i < NR_PERFCNT; i ++) {
if (i != CNT_IDX(time)) {
res->cnts[i].val = t1->cnts[i].val - t0->cnts[i].val;
}
}
}
void __am_perfcnt_add(PerfCntSet *res, PerfCntSet *t1, PerfCntSet *t0) {
int i;
for (i = 0; i < NR_PERFCNT; i ++) {
if (i != CNT_IDX(time)) {
res->cnts[i].val = t1->cnts[i].val + t0->cnts[i].val;
}
}
}
void __am_perfcnt_show(PerfCntSet *t) {
int i;
for (i = 0; i < NR_PERFCNT; i ++) {
if (i != CNT_IDX(time)) {
printf("{%10u, %10u} <- %s\n", t->cnts[i].hi, t->cnts[i].lo, name[i]);
}
}
}
void __am_perfcnt_excel(PerfCntSet *t) {
int i;
for (i = 0; i < NR_PERFCNT; i ++) {
if (i != CNT_IDX(time)) {
if (i == CNT_IDX(cycle)) {
printf("%u,", t->cnts[i].hi);
}
printf("%u,", t->cnts[i].lo);
}
}
printf("\n");
}
#include <am.h>
#include <riscv32.h>
#include <klib.h>
extern char _heap_start;
extern char _heap_end;
int main(const char *args);
void __am_init_uartlite(void);
void __am_uartlite_putchar(char ch);
_Area _heap = RANGE(&_heap_start, &_heap_end);
void _putc(char ch) {
__am_uartlite_putchar(ch);
}
void _halt(int code) {
__asm__ volatile("mv a0, %0; .word 0x0005006b" : :"r"(code));
// should not reach here during simulation
printf("Exit with code = %d\n", code);
// should not reach here on FPGA
while (1);
}
void _trm_init() {
__am_init_uartlite();
extern const char _mainargs;
int ret = main(&_mainargs);
_halt(ret);
}
#include <riscv32.h>
#define UARTLITE_MMIO 0x40600000
#define UARTLITE_RX_FIFO 0x0
#define UARTLITE_TX_FIFO 0x4
#define UARTLITE_STAT_REG 0x8
#define UARTLITE_CTRL_REG 0xc
#define UARTLITE_RST_FIFO 0x03
#define UARTLITE_TX_FULL 0x08
#define UARTLITE_RX_VALID 0x01
void __am_init_uartlite(void) {
outb(UARTLITE_MMIO + UARTLITE_CTRL_REG, UARTLITE_RST_FIFO);
}
void __am_uartlite_putchar(char ch) {
if (ch == '\n') __am_uartlite_putchar('\r');
while (inb(UARTLITE_MMIO + UARTLITE_STAT_REG) & UARTLITE_TX_FULL);
outb(UARTLITE_MMIO + UARTLITE_TX_FIFO, ch);
}
int __am_uartlite_getchar() {
if (inb(UARTLITE_MMIO + UARTLITE_STAT_REG) & UARTLITE_RX_VALID)
return inb(UARTLITE_MMIO + UARTLITE_RX_FIFO);
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册