提交 7875fc1e 编写于 作者: Z Zihao Yu

Merge branch 'freertos' into 'rv64'

Freertos

See merge request projectn/nemu!12
#ifndef __ALARM_H__
#define __ALARM_H__
void add_alarm_handle(void *h);
#endif
#include "common.h"
#include <sys/time.h>
#include <signal.h>
#define TIMER_HZ 100
#define MAX_HANDLER 8
typedef void (*alarm_handler_t) (void);
static alarm_handler_t handler[MAX_HANDLER] = {};
static int idx = 0;
static struct itimerval it = {};
void add_alarm_handle(void *h) {
assert(idx < MAX_HANDLER);
handler[idx ++] = h;
}
static void alarm_sig_handler(int signum) {
int i;
for (i = 0; i < idx; i ++) {
handler[i]();
}
int ret = setitimer(ITIMER_VIRTUAL, &it, NULL);
Assert(ret == 0, "Can not set timer");
}
void init_alarm(void) {
struct sigaction s;
memset(&s, 0, sizeof(s));
s.sa_handler = alarm_sig_handler;
int ret = sigaction(SIGVTALRM, &s, NULL);
Assert(ret == 0, "Can not set signal handler");
it.it_value.tv_sec = 0;
it.it_value.tv_usec = 1000000 / TIMER_HZ;
ret = setitimer(ITIMER_VIRTUAL, &it, NULL);
Assert(ret == 0, "Can not set timer");
}
......@@ -2,31 +2,21 @@
#ifdef HAS_IOE
#include <sys/time.h>
#include <signal.h>
#include "device/alarm.h"
#include <SDL2/SDL.h>
#define TIMER_HZ 100
#define VGA_HZ 50
static struct itimerval it = {};
static int device_update_flag = false;
void init_alarm();
void init_serial();
void init_timer();
void init_vga();
void init_i8042();
void timer_intr();
void send_key(uint8_t, bool);
static void timer_sig_handler(int signum) {
timer_intr();
static int device_update_flag = false;
static void set_device_update_flag() {
device_update_flag = true;
int ret = setitimer(ITIMER_VIRTUAL, &it, NULL);
Assert(ret == 0, "Can not set timer");
}
void device_update() {
......@@ -68,16 +58,8 @@ void init_device() {
init_vga();
init_i8042();
struct sigaction s;
memset(&s, 0, sizeof(s));
s.sa_handler = timer_sig_handler;
int ret = sigaction(SIGVTALRM, &s, NULL);
Assert(ret == 0, "Can not set signal handler");
it.it_value.tv_sec = 0;
it.it_value.tv_usec = 1000000 / TIMER_HZ;
ret = setitimer(ITIMER_VIRTUAL, &it, NULL);
Assert(ret == 0, "Can not set timer");
add_alarm_handle(set_device_update_flag);
init_alarm();
}
#else
......
......@@ -16,10 +16,7 @@ static void serial_ch_io_handler(uint32_t offset, int len, bool is_write) {
char c = serial_ch_base[0];
/* We bind the serial port with the host stdout in NEMU. */
putc(c, stdout);
if (c == '\n') {
fflush(stdout);
}
putc(c, stderr);
}
void init_serial() {
......
#include "device/map.h"
#include "device/alarm.h"
#include "monitor/monitor.h"
#include <sys/time.h>
#define RTC_PORT 0x48 // Note that this is not the standard
#define RTC_MMIO 0xa1000048
void timer_intr() {
if (nemu_state.state == NEMU_RUNNING) {
extern void dev_raise_intr(void);
dev_raise_intr();
}
}
static uint32_t *rtc_port_base = NULL;
void rtc_io_handler(uint32_t offset, int len, bool is_write) {
static void rtc_io_handler(uint32_t offset, int len, bool is_write) {
assert(offset == 0 || offset == 8 || offset == 12);
if (!is_write) {
struct timeval now;
......@@ -27,8 +21,16 @@ void rtc_io_handler(uint32_t offset, int len, bool is_write) {
}
}
static void timer_intr() {
if (nemu_state.state == NEMU_RUNNING) {
extern void dev_raise_intr(void);
dev_raise_intr();
}
}
void init_timer() {
rtc_port_base = (void*)new_space(16);
add_pio_map("rtc", RTC_PORT, (void *)rtc_port_base, 16, rtc_io_handler);
add_mmio_map("rtc", RTC_MMIO, (void *)rtc_port_base, 16, rtc_io_handler);
add_alarm_handle(timer_intr);
}
......@@ -23,7 +23,7 @@ static SDL_Texture *texture = NULL;
static uint32_t (*vmem) [SCREEN_W] = NULL;
static uint32_t *screensize_port_base = NULL;
void update_screen() {
static inline void update_screen() {
SDL_UpdateTexture(texture, NULL, vmem, SCREEN_W * sizeof(vmem[0][0]));
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
......
#include "monitor/monitor.h"
#include "device/alarm.h"
#include "device/map.h"
#define CLINT_MMIO 0x2000000
#define CLINT_MTIMECMP (0x4000 / sizeof(clint_base[0]))
#define CLINT_MTIME (0xBFF8 / sizeof(clint_base[0]))
static uint64_t *clint_base = NULL;
void clint_intr(void) {
if (nemu_state.state == NEMU_RUNNING) {
clint_base[CLINT_MTIME] += 0x800;
}
}
bool clint_query_intr(void) {
return clint_base[CLINT_MTIME] >= clint_base[CLINT_MTIMECMP];
}
void init_clint(void) {
clint_base = (void *)new_space(0x10000);
add_mmio_map("clint", CLINT_MMIO, (void *)clint_base, 0x10000, NULL);
add_alarm_handle(clint_intr);
}
......@@ -5,7 +5,7 @@
#define CSRS(f) \
f(mstatus , 0x300) f(mtvec , 0x305) f(mepc , 0x341) f(mcause , 0x342) \
f(satp , 0x180)
f(mie , 0x304) f(satp , 0x180)
#define CSR_STRUCT_START(name) \
typedef union { \
......@@ -45,6 +45,21 @@ CSR_STRUCT_END(mcause)
CSR_STRUCT_START(mepc)
CSR_STRUCT_END(mepc)
CSR_STRUCT_START(mie)
uint64_t usie : 1;
uint64_t ssie : 1;
uint64_t hsie : 1;
uint64_t msie : 1;
uint64_t utie : 1;
uint64_t stie : 1;
uint64_t htie : 1;
uint64_t mtie : 1;
uint64_t ueie : 1;
uint64_t seie : 1;
uint64_t heie : 1;
uint64_t meie : 1;
CSR_STRUCT_END(mie)
#define CSRS_DECL(name, val) extern concat(name, _t)* const name;
MAP(CSRS, CSRS_DECL)
......
......@@ -92,6 +92,12 @@ make_DHelper(csr) {
decode_op_r(id_dest, decinfo.isa.instr.rd, false);
}
make_DHelper(csri) {
decode_op_i(id_src, decinfo.isa.instr.rs1, true);
decode_op_i(id_src2, decinfo.isa.instr.csr, true);
decode_op_r(id_dest, decinfo.isa.instr.rd, false);
}
// RVC
#define creg2reg(creg) (creg + 8)
......
......@@ -28,6 +28,7 @@ make_EHelper(nemu_trap);
make_EHelper(csrrw);
make_EHelper(csrrs);
make_EHelper(csrrc);
make_EHelper(priv);
make_EHelper(mul);
......
......@@ -59,7 +59,7 @@ static make_EHelper(op32) {
static make_EHelper(system) {
static OpcodeEntry table [8] = {
EX(priv), IDEX(csr, csrrw), IDEX(csr, csrrs), EMPTY, EMPTY, EMPTY, EMPTY, EMPTY
EX(priv), IDEX(csr, csrrw), IDEX(csr, csrrs), EMPTY, EMPTY, EMPTY, IDEX(csri, csrrs), IDEX(csri, csrrc)
};
idex(pc, &table[decinfo.isa.instr.funct3]);
}
......
......@@ -24,7 +24,17 @@ make_EHelper(csrrs) {
print_asm_template3("csrrs");
}
extern void raise_intr(uint32_t NO, vaddr_t epc);
make_EHelper(csrrc) {
rtlreg_t *csr = csr_decode_wrapper(id_src2->val);
rtl_sr(id_dest->reg, csr, 8);
rtl_not(&s0, &id_src->val);
rtl_and(csr, csr, &s0);
print_asm_template3("csrrc");
}
extern void raise_intr(word_t NO, vaddr_t epc);
make_EHelper(priv) {
uint32_t type = decinfo.isa.instr.csr;
......
......@@ -110,6 +110,7 @@ make_DHelper(B);
make_DHelper(ld);
make_DHelper(st);
make_DHelper(csr);
make_DHelper(csri);
make_DHelper(CR);
make_DHelper(CB);
......
......@@ -11,10 +11,14 @@ const uint32_t isa_default_img [] = {
};
const long isa_default_img_size = sizeof(isa_default_img);
void init_clint(void);
void init_isa(void) {
cpu.gpr[0]._64 = 0;
cpu.pc = PC_START;
mstatus->val = 0x000c0100;
register_pmem(0x80000000u);
init_clint();
}
#include "rtl/rtl.h"
#include "csr.h"
void raise_intr(uint32_t NO, vaddr_t epc) {
#define INTR_BIT (1ULL << 63)
void raise_intr(word_t NO, vaddr_t epc) {
/* TODO: Trigger an interrupt/exception with ``NO''.
* That is, use ``NO'' to index the IDT.
*/
......@@ -15,11 +17,18 @@ void raise_intr(uint32_t NO, vaddr_t epc) {
}
bool isa_query_intr(void) {
if (cpu.INTR && mstatus->mie) {
cpu.INTR = false;
// machine external interrupt
raise_intr(0x8000000b, cpu.pc);
extern bool clint_query_intr(void);
if (mstatus->mie) {
//if (cpu.INTR) {
// cpu.INTR = false;
// // machine external interrupt
// raise_intr(0xb | INTR_BIT, cpu.pc);
//}
if (clint_query_intr() && mie->mtie) {
// machine timer interrupt
raise_intr(0x7 | INTR_BIT, cpu.pc);
return true;
}
}
return false;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册