mips32-nemu: add basic cte

This commit is contained in:
Zihao Yu 2019-01-17 20:09:42 +08:00
parent cd4541605d
commit 686f65299c
4 changed files with 185 additions and 9 deletions

View File

@ -1,22 +1,28 @@
#ifndef __ARCH_H__
#define __ARCH_H__
#include <am.h>
#define PMEM_SIZE (128 * 1024 * 1024)
#define PGSIZE 4096
struct _Context {
uint32_t at,
v0,v1,
a0,a1,a2,a3,
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,
s0,s1,s2,s3,s4,s5,s6,s7,
k0,k1,
gp,sp,fp,ra;
struct _Protect *prot;
uint32_t gpr[31];
uint32_t lo, hi;
uint32_t cause, status, epc;
};
#define GPR1 gpr[4]
#define GPR2 gpr[5]
#define GPR3 gpr[6]
#define GPR4 gpr[7]
#define GPRx gpr[2]
#ifdef __cplusplus
extern "C" {
#endif
//static inline void _ioe_init() { }
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,64 @@
#include <am.h>
#include <mips32.h>
#include <klib.h>
static _Context* (*user_handler)(_Event, _Context*) = NULL;
void get_cur_as(_Context *c);
void _switch(_Context *c);
_Context* irq_handle(_Context *c) {
// get_cur_as(c);
_Context *next = c;
if (user_handler) {
_Event ev = {0};
uint32_t ex_code = (c->cause >> 2) & 0x1f;
uint32_t syscall_instr;
switch (ex_code) {
case 0: ev.event = _EVENT_IRQ_TIMER; break;
case 8:
syscall_instr = *(uint32_t *)(c->epc);
ev.event = ((syscall_instr >> 6) == 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;
}
}
// _switch(next);
return next;
}
extern void asm_trap(void);
#define EX_ENTRY 0x180
int _cte_init(_Context*(*handler)(_Event, _Context*)) {
// initialize exception entry
uint32_t *p = (uint32_t *)EX_ENTRY;
*p = 0x08000000 | (((uint32_t)asm_trap >> 2) & 0x3ffffff);
// register event handler
user_handler = handler;
return 0;
}
_Context *_kcontext(_Area stack, void (*entry)(void *), void *arg) {
return NULL;
}
void _yield() {
asm volatile("syscall 1");
}
int _istatus(int enable) {
return 0;
}

View File

@ -0,0 +1,61 @@
#define concat_temp(x, y) x ## y
#define concat(x, y) concat_temp(x, y)
#define regs(X) \
X( 1) X( 2) X( 3) X( 4) X( 5) X( 6) X( 7) X( 8) X( 9) \
X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17) X(18) X(19) \
X(20) X(21) X(22) X(23) X(24) X(25) X(26) X(27) X(28) \
X(30) X(31)
#define CONTEXT_SIZE ((31 + 6) * 4)
#define OFFSET_SP (29 * 4)
#define OFFSET_LO (32 * 4)
#define OFFSET_HI (33 * 4)
#define OFFSET_CAUSE (34 * 4)
#define OFFSET_STATUS (35 * 4)
#define OFFSET_EPC (36 * 4)
#define CP0_STATUS 12
#define CP0_CAUSE 13
#define CP0_EPC 14
#define push(n) sw $n, (n * 4)($sp);
#define pop(n) lw $n, (n * 4)($sp);
.set noat
.globl asm_trap
asm_trap:
move $k0, $sp
addiu $sp, $sp, -CONTEXT_SIZE
regs(push)
sw $k0, OFFSET_SP($sp)
mflo $t0
mfhi $t1
mfc0 $t2, $CP0_CAUSE
mfc0 $t3, $CP0_STATUS
mfc0 $t4, $CP0_EPC
sw $t0, OFFSET_LO($sp)
sw $t1, OFFSET_HI($sp)
sw $t2, OFFSET_CAUSE($sp)
sw $t3, OFFSET_STATUS($sp)
sw $t4, OFFSET_EPC($sp)
move $a0, $sp
jal irq_handle
lw $t0, OFFSET_LO($sp)
lw $t1, OFFSET_HI($sp)
lw $t2, OFFSET_CAUSE($sp)
lw $t3, OFFSET_STATUS($sp)
lw $t4, OFFSET_EPC($sp)
mtlo $t0
mthi $t1
mtc0 $t2, $CP0_CAUSE
mtc0 $t3, $CP0_STATUS
mtc0 $t4, $CP0_EPC
regs(pop)
eret

View File

@ -0,0 +1,45 @@
#include <mips32.h>
#include <klib.h>
#define PG_ALIGN __attribute((aligned(PGSIZE)))
static void* (*pgalloc_usr)(size_t);
static void (*pgfree_usr)(void*);
_Area segments[] = { // Kernel memory mappings
{.start = (void*)0, .end = (void*)PMEM_SIZE}
};
#define NR_KSEG_MAP (sizeof(segments) / sizeof(segments[0]))
int _vme_init(void* (*pgalloc_f)(size_t), void (*pgfree_f)(void*)) {
pgalloc_usr = pgalloc_f;
pgfree_usr = pgfree_f;
return 0;
}
int _protect(_Protect *p) {
return 0;
}
void _unprotect(_Protect *p) {
}
static _Protect *cur_as = NULL;
void get_cur_as(_Context *c) {
c->prot = cur_as;
}
void _switch(_Context *c) {
assert(0);
cur_as = c->prot;
}
int _map(_Protect *p, void *va, void *pa, int mode) {
return 0;
}
_Context *_ucontext(_Protect *p, _Area ustack, _Area kstack, void *entry, void *args) {
return NULL;
}