mips32-nemu: add basic cte
This commit is contained in:
parent
cd4541605d
commit
686f65299c
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue