NJU-ProjectN/abstract-machine ics2023 initialized
NJU-ProjectN/abstract-machine 3348db971fd860be5cb28e21c18f9d0e65d0c96a Merge pull request #8 from Jasonyanyusong/master
This commit is contained in:
parent
2824efad33
commit
8e4feb4010
129 changed files with 9017 additions and 0 deletions
24
abstract-machine/am/src/mips/mips32.h
Normal file
24
abstract-machine/am/src/mips/mips32.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef MIPS32_H__
|
||||
#define MIPS32_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint8_t inb(uintptr_t addr) { return *(volatile uint8_t *)addr; }
|
||||
static inline uint16_t inw(uintptr_t addr) { return *(volatile uint16_t *)addr; }
|
||||
static inline uint32_t inl(uintptr_t addr) { return *(volatile uint32_t *)addr; }
|
||||
|
||||
static inline void outb(uintptr_t addr, uint8_t data) { *(volatile uint8_t *)addr = data; }
|
||||
static inline void outw(uintptr_t addr, uint16_t data) { *(volatile uint16_t *)addr = data; }
|
||||
static inline void outl(uintptr_t addr, uint32_t data) { *(volatile uint32_t *)addr = data; }
|
||||
|
||||
#define PTE_V 0x2
|
||||
#define PTE_D 0x4
|
||||
|
||||
// Page directory and page table constants
|
||||
#define PTXSHFT 12 // Offset of PTX in a linear address
|
||||
#define PDXSHFT 22 // Offset of PDX in a linear address
|
||||
|
||||
#define PDX(va) (((uint32_t)(va) >> PDXSHFT) & 0x3ff)
|
||||
#define PTX(va) (((uint32_t)(va) >> PTXSHFT) & 0x3ff)
|
||||
|
||||
#endif
|
54
abstract-machine/am/src/mips/nemu/cte.c
Normal file
54
abstract-machine/am/src/mips/nemu/cte.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include <am.h>
|
||||
#include <mips/mips32.h>
|
||||
#include <klib.h>
|
||||
|
||||
static Context* (*user_handler)(Event, Context*) = NULL;
|
||||
|
||||
Context* __am_irq_handle(Context *c) {
|
||||
if (user_handler) {
|
||||
Event ev = {0};
|
||||
uint32_t ex_code = 0;
|
||||
switch (ex_code) {
|
||||
default: ev.event = EVENT_ERROR; break;
|
||||
}
|
||||
|
||||
c = user_handler(ev, c);
|
||||
assert(c != NULL);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
extern void __am_asm_trap(void);
|
||||
|
||||
#define EX_ENTRY 0x80000180
|
||||
|
||||
bool cte_init(Context*(*handler)(Event, Context*)) {
|
||||
// initialize exception entry
|
||||
const uint32_t j_opcode = 0x08000000;
|
||||
uint32_t instr = j_opcode | (((uint32_t)__am_asm_trap >> 2) & 0x3ffffff);
|
||||
*(uint32_t *)EX_ENTRY = instr;
|
||||
*(uint32_t *)(EX_ENTRY + 4) = 0; // delay slot
|
||||
*(uint32_t *)0x80000000 = instr; // TLB refill exception
|
||||
*(uint32_t *)(0x80000000 + 4) = 0; // delay slot
|
||||
|
||||
// register event handler
|
||||
user_handler = handler;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Context *kcontext(Area kstack, void (*entry)(void *), void *arg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void yield() {
|
||||
asm volatile("syscall 1");
|
||||
}
|
||||
|
||||
bool ienabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void iset(bool enable) {
|
||||
}
|
10
abstract-machine/am/src/mips/nemu/start.S
Normal file
10
abstract-machine/am/src/mips/nemu/start.S
Normal file
|
@ -0,0 +1,10 @@
|
|||
.section entry, "ax"
|
||||
.globl _start
|
||||
.type _start, @function
|
||||
|
||||
_start:
|
||||
move $fp, $zero
|
||||
la $sp, _stack_pointer
|
||||
jal _trm_init
|
||||
|
||||
.fill 0x200
|
71
abstract-machine/am/src/mips/nemu/trap.S
Normal file
71
abstract-machine/am/src/mips/nemu/trap.S
Normal file
|
@ -0,0 +1,71 @@
|
|||
|
||||
#define MAP(c, f) c(f)
|
||||
|
||||
#define REGS(f) \
|
||||
f( 1) f( 2) f( 3) f( 4) f( 5) f( 6) f( 7) f( 8) f( 9) \
|
||||
f(10) f(11) f(12) f(13) f(14) f(15) f(16) f(17) f(18) f(19) \
|
||||
f(20) f(21) f(22) f(23) f(24) f(25) f(28) \
|
||||
f(30) f(31)
|
||||
|
||||
#define PUSH(n) sw $n, (n * 4)($sp);
|
||||
#define POP(n) lw $n, (n * 4)($sp);
|
||||
|
||||
#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
|
||||
|
||||
|
||||
.set noat
|
||||
.globl __am_asm_trap
|
||||
__am_asm_trap:
|
||||
move $k1, $sp
|
||||
addiu $sp, $sp, -CONTEXT_SIZE
|
||||
|
||||
MAP(REGS, PUSH)
|
||||
|
||||
sw $k1, 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)
|
||||
|
||||
# allow nested exception
|
||||
li $a0, ~0x3
|
||||
and $t3, $t3, $a0 # clear status.exl and status.ie
|
||||
mtc0 $t3, $CP0_STATUS
|
||||
|
||||
move $a0, $sp
|
||||
jal __am_irq_handle
|
||||
|
||||
lw $t0, OFFSET_LO($sp)
|
||||
lw $t1, OFFSET_HI($sp)
|
||||
lw $t3, OFFSET_STATUS($sp)
|
||||
lw $t4, OFFSET_EPC($sp)
|
||||
|
||||
# set status.exl
|
||||
ori $t3, $t3, 0x2
|
||||
|
||||
mtlo $t0
|
||||
mthi $t1
|
||||
mtc0 $t3, $CP0_STATUS
|
||||
mtc0 $t4, $CP0_EPC
|
||||
|
||||
MAP(REGS, POP)
|
||||
|
||||
addiu $sp, $sp, CONTEXT_SIZE
|
||||
eret
|
42
abstract-machine/am/src/mips/nemu/vme.c
Normal file
42
abstract-machine/am/src/mips/nemu/vme.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include <am.h>
|
||||
#include <nemu.h>
|
||||
|
||||
#define USER_SPACE RANGE(0x40000000, 0x80000000)
|
||||
|
||||
static void* (*pgalloc_usr)(int) = NULL;
|
||||
static void (*pgfree_usr)(void*) = NULL;
|
||||
static int vme_enable = 0;
|
||||
static PTE *cur_pdir = NULL;
|
||||
|
||||
bool vme_init(void* (*pgalloc_f)(int), void (*pgfree_f)(void*)) {
|
||||
pgalloc_usr = pgalloc_f;
|
||||
pgfree_usr = pgfree_f;
|
||||
vme_enable = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void protect(AddrSpace *as) {
|
||||
as->ptr = (PTE*)(pgalloc_usr(PGSIZE));
|
||||
as->pgsize = PGSIZE;
|
||||
as->area = USER_SPACE;
|
||||
}
|
||||
|
||||
void unprotect(AddrSpace *as) {
|
||||
}
|
||||
|
||||
void __am_get_cur_as(Context *c) {
|
||||
c->pdir = (vme_enable ? cur_pdir : NULL);
|
||||
}
|
||||
|
||||
void __am_switch(Context *c) {
|
||||
if (vme_enable && c->pdir != NULL) {
|
||||
cur_pdir = c->pdir;
|
||||
}
|
||||
}
|
||||
|
||||
void map(AddrSpace *as, void *va, void *pa, int prot) {
|
||||
}
|
||||
|
||||
Context *ucontext(AddrSpace *as, Area kstack, void *entry) {
|
||||
return NULL;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue