NJU-ProjectN/nemu ics2023 initialized
NJU-ProjectN/nemu eb63cf3568dbf4e0c3c6ef462e6ec685550fabbc Merge pull request #76 from rijuyuezhu/master
This commit is contained in:
parent
1efe03efb9
commit
2824efad33
141 changed files with 19573 additions and 0 deletions
22
nemu/src/am-bin.S
Normal file
22
nemu/src/am-bin.S
Normal file
|
@ -0,0 +1,22 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
.section .rodata
|
||||
.globl bin_start, bin_end
|
||||
bin_start:
|
||||
#ifdef BIN_PATH
|
||||
.incbin BIN_PATH
|
||||
#endif
|
||||
bin_end:
|
128
nemu/src/cpu/cpu-exec.c
Normal file
128
nemu/src/cpu/cpu-exec.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <cpu/cpu.h>
|
||||
#include <cpu/decode.h>
|
||||
#include <cpu/difftest.h>
|
||||
#include <locale.h>
|
||||
|
||||
/* The assembly code of instructions executed is only output to the screen
|
||||
* when the number of instructions executed is less than this value.
|
||||
* This is useful when you use the `si' command.
|
||||
* You can modify this value as you want.
|
||||
*/
|
||||
#define MAX_INST_TO_PRINT 10
|
||||
|
||||
CPU_state cpu = {};
|
||||
uint64_t g_nr_guest_inst = 0;
|
||||
static uint64_t g_timer = 0; // unit: us
|
||||
static bool g_print_step = false;
|
||||
|
||||
void device_update();
|
||||
|
||||
static void trace_and_difftest(Decode *_this, vaddr_t dnpc) {
|
||||
#ifdef CONFIG_ITRACE_COND
|
||||
if (ITRACE_COND) { log_write("%s\n", _this->logbuf); }
|
||||
#endif
|
||||
if (g_print_step) { IFDEF(CONFIG_ITRACE, puts(_this->logbuf)); }
|
||||
IFDEF(CONFIG_DIFFTEST, difftest_step(_this->pc, dnpc));
|
||||
}
|
||||
|
||||
static void exec_once(Decode *s, vaddr_t pc) {
|
||||
s->pc = pc;
|
||||
s->snpc = pc;
|
||||
isa_exec_once(s);
|
||||
cpu.pc = s->dnpc;
|
||||
#ifdef CONFIG_ITRACE
|
||||
char *p = s->logbuf;
|
||||
p += snprintf(p, sizeof(s->logbuf), FMT_WORD ":", s->pc);
|
||||
int ilen = s->snpc - s->pc;
|
||||
int i;
|
||||
uint8_t *inst = (uint8_t *)&s->isa.inst.val;
|
||||
for (i = ilen - 1; i >= 0; i --) {
|
||||
p += snprintf(p, 4, " %02x", inst[i]);
|
||||
}
|
||||
int ilen_max = MUXDEF(CONFIG_ISA_x86, 8, 4);
|
||||
int space_len = ilen_max - ilen;
|
||||
if (space_len < 0) space_len = 0;
|
||||
space_len = space_len * 3 + 1;
|
||||
memset(p, ' ', space_len);
|
||||
p += space_len;
|
||||
|
||||
#ifndef CONFIG_ISA_loongarch32r
|
||||
void disassemble(char *str, int size, uint64_t pc, uint8_t *code, int nbyte);
|
||||
disassemble(p, s->logbuf + sizeof(s->logbuf) - p,
|
||||
MUXDEF(CONFIG_ISA_x86, s->snpc, s->pc), (uint8_t *)&s->isa.inst.val, ilen);
|
||||
#else
|
||||
p[0] = '\0'; // the upstream llvm does not support loongarch32r
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void execute(uint64_t n) {
|
||||
Decode s;
|
||||
for (;n > 0; n --) {
|
||||
exec_once(&s, cpu.pc);
|
||||
g_nr_guest_inst ++;
|
||||
trace_and_difftest(&s, cpu.pc);
|
||||
if (nemu_state.state != NEMU_RUNNING) break;
|
||||
IFDEF(CONFIG_DEVICE, device_update());
|
||||
}
|
||||
}
|
||||
|
||||
static void statistic() {
|
||||
IFNDEF(CONFIG_TARGET_AM, setlocale(LC_NUMERIC, ""));
|
||||
#define NUMBERIC_FMT MUXDEF(CONFIG_TARGET_AM, "%", "%'") PRIu64
|
||||
Log("host time spent = " NUMBERIC_FMT " us", g_timer);
|
||||
Log("total guest instructions = " NUMBERIC_FMT, g_nr_guest_inst);
|
||||
if (g_timer > 0) Log("simulation frequency = " NUMBERIC_FMT " inst/s", g_nr_guest_inst * 1000000 / g_timer);
|
||||
else Log("Finish running in less than 1 us and can not calculate the simulation frequency");
|
||||
}
|
||||
|
||||
void assert_fail_msg() {
|
||||
isa_reg_display();
|
||||
statistic();
|
||||
}
|
||||
|
||||
/* Simulate how the CPU works. */
|
||||
void cpu_exec(uint64_t n) {
|
||||
g_print_step = (n < MAX_INST_TO_PRINT);
|
||||
switch (nemu_state.state) {
|
||||
case NEMU_END: case NEMU_ABORT:
|
||||
printf("Program execution has ended. To restart the program, exit NEMU and run again.\n");
|
||||
return;
|
||||
default: nemu_state.state = NEMU_RUNNING;
|
||||
}
|
||||
|
||||
uint64_t timer_start = get_time();
|
||||
|
||||
execute(n);
|
||||
|
||||
uint64_t timer_end = get_time();
|
||||
g_timer += timer_end - timer_start;
|
||||
|
||||
switch (nemu_state.state) {
|
||||
case NEMU_RUNNING: nemu_state.state = NEMU_STOP; break;
|
||||
|
||||
case NEMU_END: case NEMU_ABORT:
|
||||
Log("nemu: %s at pc = " FMT_WORD,
|
||||
(nemu_state.state == NEMU_ABORT ? ANSI_FMT("ABORT", ANSI_FG_RED) :
|
||||
(nemu_state.halt_ret == 0 ? ANSI_FMT("HIT GOOD TRAP", ANSI_FG_GREEN) :
|
||||
ANSI_FMT("HIT BAD TRAP", ANSI_FG_RED))),
|
||||
nemu_state.halt_pc);
|
||||
// fall through
|
||||
case NEMU_QUIT: statistic();
|
||||
}
|
||||
}
|
132
nemu/src/cpu/difftest/dut.c
Normal file
132
nemu/src/cpu/difftest/dut.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <isa.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <memory/paddr.h>
|
||||
#include <utils.h>
|
||||
#include <difftest-def.h>
|
||||
|
||||
void (*ref_difftest_memcpy)(paddr_t addr, void *buf, size_t n, bool direction) = NULL;
|
||||
void (*ref_difftest_regcpy)(void *dut, bool direction) = NULL;
|
||||
void (*ref_difftest_exec)(uint64_t n) = NULL;
|
||||
void (*ref_difftest_raise_intr)(uint64_t NO) = NULL;
|
||||
|
||||
#ifdef CONFIG_DIFFTEST
|
||||
|
||||
static bool is_skip_ref = false;
|
||||
static int skip_dut_nr_inst = 0;
|
||||
|
||||
// this is used to let ref skip instructions which
|
||||
// can not produce consistent behavior with NEMU
|
||||
void difftest_skip_ref() {
|
||||
is_skip_ref = true;
|
||||
// If such an instruction is one of the instruction packing in QEMU
|
||||
// (see below), we end the process of catching up with QEMU's pc to
|
||||
// keep the consistent behavior in our best.
|
||||
// Note that this is still not perfect: if the packed instructions
|
||||
// already write some memory, and the incoming instruction in NEMU
|
||||
// will load that memory, we will encounter false negative. But such
|
||||
// situation is infrequent.
|
||||
skip_dut_nr_inst = 0;
|
||||
}
|
||||
|
||||
// this is used to deal with instruction packing in QEMU.
|
||||
// Sometimes letting QEMU step once will execute multiple instructions.
|
||||
// We should skip checking until NEMU's pc catches up with QEMU's pc.
|
||||
// The semantic is
|
||||
// Let REF run `nr_ref` instructions first.
|
||||
// We expect that DUT will catch up with REF within `nr_dut` instructions.
|
||||
void difftest_skip_dut(int nr_ref, int nr_dut) {
|
||||
skip_dut_nr_inst += nr_dut;
|
||||
|
||||
while (nr_ref -- > 0) {
|
||||
ref_difftest_exec(1);
|
||||
}
|
||||
}
|
||||
|
||||
void init_difftest(char *ref_so_file, long img_size, int port) {
|
||||
assert(ref_so_file != NULL);
|
||||
|
||||
void *handle;
|
||||
handle = dlopen(ref_so_file, RTLD_LAZY);
|
||||
assert(handle);
|
||||
|
||||
ref_difftest_memcpy = dlsym(handle, "difftest_memcpy");
|
||||
assert(ref_difftest_memcpy);
|
||||
|
||||
ref_difftest_regcpy = dlsym(handle, "difftest_regcpy");
|
||||
assert(ref_difftest_regcpy);
|
||||
|
||||
ref_difftest_exec = dlsym(handle, "difftest_exec");
|
||||
assert(ref_difftest_exec);
|
||||
|
||||
ref_difftest_raise_intr = dlsym(handle, "difftest_raise_intr");
|
||||
assert(ref_difftest_raise_intr);
|
||||
|
||||
void (*ref_difftest_init)(int) = dlsym(handle, "difftest_init");
|
||||
assert(ref_difftest_init);
|
||||
|
||||
Log("Differential testing: %s", ANSI_FMT("ON", ANSI_FG_GREEN));
|
||||
Log("The result of every instruction will be compared with %s. "
|
||||
"This will help you a lot for debugging, but also significantly reduce the performance. "
|
||||
"If it is not necessary, you can turn it off in menuconfig.", ref_so_file);
|
||||
|
||||
ref_difftest_init(port);
|
||||
ref_difftest_memcpy(RESET_VECTOR, guest_to_host(RESET_VECTOR), img_size, DIFFTEST_TO_REF);
|
||||
ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF);
|
||||
}
|
||||
|
||||
static void checkregs(CPU_state *ref, vaddr_t pc) {
|
||||
if (!isa_difftest_checkregs(ref, pc)) {
|
||||
nemu_state.state = NEMU_ABORT;
|
||||
nemu_state.halt_pc = pc;
|
||||
isa_reg_display();
|
||||
}
|
||||
}
|
||||
|
||||
void difftest_step(vaddr_t pc, vaddr_t npc) {
|
||||
CPU_state ref_r;
|
||||
|
||||
if (skip_dut_nr_inst > 0) {
|
||||
ref_difftest_regcpy(&ref_r, DIFFTEST_TO_DUT);
|
||||
if (ref_r.pc == npc) {
|
||||
skip_dut_nr_inst = 0;
|
||||
checkregs(&ref_r, npc);
|
||||
return;
|
||||
}
|
||||
skip_dut_nr_inst --;
|
||||
if (skip_dut_nr_inst == 0)
|
||||
panic("can not catch up with ref.pc = " FMT_WORD " at pc = " FMT_WORD, ref_r.pc, pc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_skip_ref) {
|
||||
// to skip the checking of an instruction, just copy the reg state to reference design
|
||||
ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF);
|
||||
is_skip_ref = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ref_difftest_exec(1);
|
||||
ref_difftest_regcpy(&ref_r, DIFFTEST_TO_DUT);
|
||||
|
||||
checkregs(&ref_r, pc);
|
||||
}
|
||||
#else
|
||||
void init_difftest(char *ref_so_file, long img_size, int port) { }
|
||||
#endif
|
42
nemu/src/cpu/difftest/ref.c
Normal file
42
nemu/src/cpu/difftest/ref.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <difftest-def.h>
|
||||
#include <memory/paddr.h>
|
||||
|
||||
__EXPORT void difftest_memcpy(paddr_t addr, void *buf, size_t n, bool direction) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
__EXPORT void difftest_regcpy(void *dut, bool direction) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
__EXPORT void difftest_exec(uint64_t n) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
__EXPORT void difftest_raise_intr(word_t NO) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
__EXPORT void difftest_init(int port) {
|
||||
void init_mem();
|
||||
init_mem();
|
||||
/* Perform ISA dependent initialization. */
|
||||
init_isa();
|
||||
}
|
154
nemu/src/device/Kconfig
Normal file
154
nemu/src/device/Kconfig
Normal file
|
@ -0,0 +1,154 @@
|
|||
menuconfig DEVICE
|
||||
depends on !TARGET_SHARE
|
||||
bool "Devices"
|
||||
default n
|
||||
help
|
||||
Provide device support for NEMU.
|
||||
|
||||
if DEVICE
|
||||
|
||||
config HAS_PORT_IO
|
||||
bool
|
||||
default y if ISA_x86
|
||||
default n
|
||||
|
||||
menuconfig HAS_SERIAL
|
||||
bool "Enable serial"
|
||||
default y
|
||||
|
||||
if HAS_SERIAL
|
||||
config SERIAL_PORT
|
||||
depends on HAS_PORT_IO
|
||||
hex "Port address of the serial controller"
|
||||
default 0x3f8
|
||||
|
||||
config SERIAL_MMIO
|
||||
hex "MMIO address of the serial controller"
|
||||
default 0xa00003f8
|
||||
|
||||
config SERIAL_INPUT_FIFO
|
||||
bool "Enable input FIFO with /tmp/nemu.serial"
|
||||
default n
|
||||
endif # HAS_SERIAL
|
||||
|
||||
menuconfig HAS_TIMER
|
||||
bool "Enable timer"
|
||||
default y
|
||||
|
||||
if HAS_TIMER
|
||||
config RTC_PORT
|
||||
depends on HAS_PORT_IO
|
||||
hex "Port address of the timer"
|
||||
default 0x48
|
||||
|
||||
config RTC_MMIO
|
||||
hex "MMIO address of the timer"
|
||||
default 0xa0000048
|
||||
endif # HAS_TIMER
|
||||
|
||||
menuconfig HAS_KEYBOARD
|
||||
bool "Enable keyboard"
|
||||
default y
|
||||
|
||||
if HAS_KEYBOARD
|
||||
config I8042_DATA_PORT
|
||||
depends on HAS_PORT_IO
|
||||
hex "Port address of the keyboard controller"
|
||||
default 0x60
|
||||
|
||||
config I8042_DATA_MMIO
|
||||
hex "MMIO address of the keyboard controller"
|
||||
default 0xa0000060
|
||||
endif # HAS_KEYBOARD
|
||||
|
||||
menuconfig HAS_VGA
|
||||
bool "Enable VGA"
|
||||
default y
|
||||
|
||||
if HAS_VGA
|
||||
config FB_ADDR
|
||||
hex "Physical address of the VGA frame buffer"
|
||||
default 0xa1000000
|
||||
|
||||
config VGA_CTL_PORT
|
||||
depends on HAS_PORT_IO
|
||||
hex "Port address of the VGA controller"
|
||||
default 0x100
|
||||
|
||||
config VGA_CTL_MMIO
|
||||
hex "MMIO address of the VGA controller"
|
||||
default 0xa0000100
|
||||
|
||||
config VGA_SHOW_SCREEN
|
||||
bool "Enable SDL SCREEN"
|
||||
default y
|
||||
|
||||
choice
|
||||
prompt "Screen Size"
|
||||
default VGA_SIZE_400x300
|
||||
config VGA_SIZE_400x300
|
||||
bool "400 x 300"
|
||||
config VGA_SIZE_800x600
|
||||
bool "800 x 600"
|
||||
endchoice
|
||||
endif # HAS_VGA
|
||||
|
||||
if !TARGET_AM
|
||||
menuconfig HAS_AUDIO
|
||||
bool "Enable audio"
|
||||
default y
|
||||
|
||||
if HAS_AUDIO
|
||||
config SB_ADDR
|
||||
hex "Physical address of the audio stream buffer"
|
||||
default 0xa1200000
|
||||
|
||||
config SB_SIZE
|
||||
hex "Size of the audio stream buffer"
|
||||
default 0x10000
|
||||
|
||||
config AUDIO_CTL_PORT
|
||||
depends on HAS_PORT_IO
|
||||
hex "Port address of the audio controller"
|
||||
default 0x200
|
||||
|
||||
config AUDIO_CTL_MMIO
|
||||
hex "MMIO address of the audio controller"
|
||||
default 0xa0000200
|
||||
endif # HAS_AUDIO
|
||||
|
||||
menuconfig HAS_DISK
|
||||
bool "Enable disk"
|
||||
default y
|
||||
|
||||
if HAS_DISK
|
||||
config DISK_CTL_PORT
|
||||
depends on HAS_PORT_IO
|
||||
hex "Port address of the disk controller"
|
||||
default 0x300
|
||||
|
||||
config DISK_CTL_MMIO
|
||||
hex "MMIO address of the disk controller"
|
||||
default 0xa0000300
|
||||
|
||||
config DISK_IMG_PATH
|
||||
string "The path of disk image"
|
||||
default ""
|
||||
endif # HAS_DISK
|
||||
|
||||
menuconfig HAS_SDCARD
|
||||
bool "Enable sdcard"
|
||||
default n
|
||||
|
||||
if HAS_SDCARD
|
||||
config SDCARD_CTL_MMIO
|
||||
hex "MMIO address of the sdcard controller"
|
||||
default 0xa3000000
|
||||
|
||||
config SDCARD_IMG_PATH
|
||||
string "The path of sdcard image"
|
||||
default ""
|
||||
endif # HAS_SDCARD
|
||||
endif
|
||||
|
||||
endif # DEVICE
|
51
nemu/src/device/alarm.c
Normal file
51
nemu/src/device/alarm.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <common.h>
|
||||
#include <device/alarm.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define MAX_HANDLER 8
|
||||
|
||||
static alarm_handler_t handler[MAX_HANDLER] = {};
|
||||
static int idx = 0;
|
||||
|
||||
void add_alarm_handle(alarm_handler_t 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]();
|
||||
}
|
||||
}
|
||||
|
||||
void init_alarm() {
|
||||
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");
|
||||
|
||||
struct itimerval it = {};
|
||||
it.it_value.tv_sec = 0;
|
||||
it.it_value.tv_usec = 1000000 / TIMER_HZ;
|
||||
it.it_interval = it.it_value;
|
||||
ret = setitimer(ITIMER_VIRTUAL, &it, NULL);
|
||||
Assert(ret == 0, "Can not set timer");
|
||||
}
|
47
nemu/src/device/audio.c
Normal file
47
nemu/src/device/audio.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <common.h>
|
||||
#include <device/map.h>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
enum {
|
||||
reg_freq,
|
||||
reg_channels,
|
||||
reg_samples,
|
||||
reg_sbuf_size,
|
||||
reg_init,
|
||||
reg_count,
|
||||
nr_reg
|
||||
};
|
||||
|
||||
static uint8_t *sbuf = NULL;
|
||||
static uint32_t *audio_base = NULL;
|
||||
|
||||
static void audio_io_handler(uint32_t offset, int len, bool is_write) {
|
||||
}
|
||||
|
||||
void init_audio() {
|
||||
uint32_t space_size = sizeof(uint32_t) * nr_reg;
|
||||
audio_base = (uint32_t *)new_space(space_size);
|
||||
#ifdef CONFIG_HAS_PORT_IO
|
||||
add_pio_map ("audio", CONFIG_AUDIO_CTL_PORT, audio_base, space_size, audio_io_handler);
|
||||
#else
|
||||
add_mmio_map("audio", CONFIG_AUDIO_CTL_MMIO, audio_base, space_size, audio_io_handler);
|
||||
#endif
|
||||
|
||||
sbuf = (uint8_t *)new_space(CONFIG_SB_SIZE);
|
||||
add_mmio_map("audio-sbuf", CONFIG_SB_ADDR, sbuf, CONFIG_SB_SIZE, NULL);
|
||||
}
|
89
nemu/src/device/device.c
Normal file
89
nemu/src/device/device.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <common.h>
|
||||
#include <utils.h>
|
||||
#include <device/alarm.h>
|
||||
#ifndef CONFIG_TARGET_AM
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
|
||||
void init_map();
|
||||
void init_serial();
|
||||
void init_timer();
|
||||
void init_vga();
|
||||
void init_i8042();
|
||||
void init_audio();
|
||||
void init_disk();
|
||||
void init_sdcard();
|
||||
void init_alarm();
|
||||
|
||||
void send_key(uint8_t, bool);
|
||||
void vga_update_screen();
|
||||
|
||||
void device_update() {
|
||||
static uint64_t last = 0;
|
||||
uint64_t now = get_time();
|
||||
if (now - last < 1000000 / TIMER_HZ) {
|
||||
return;
|
||||
}
|
||||
last = now;
|
||||
|
||||
IFDEF(CONFIG_HAS_VGA, vga_update_screen());
|
||||
|
||||
#ifndef CONFIG_TARGET_AM
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
nemu_state.state = NEMU_QUIT;
|
||||
break;
|
||||
#ifdef CONFIG_HAS_KEYBOARD
|
||||
// If a key was pressed
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP: {
|
||||
uint8_t k = event.key.keysym.scancode;
|
||||
bool is_keydown = (event.key.type == SDL_KEYDOWN);
|
||||
send_key(k, is_keydown);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void sdl_clear_event_queue() {
|
||||
#ifndef CONFIG_TARGET_AM
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event));
|
||||
#endif
|
||||
}
|
||||
|
||||
void init_device() {
|
||||
IFDEF(CONFIG_TARGET_AM, ioe_init());
|
||||
init_map();
|
||||
|
||||
IFDEF(CONFIG_HAS_SERIAL, init_serial());
|
||||
IFDEF(CONFIG_HAS_TIMER, init_timer());
|
||||
IFDEF(CONFIG_HAS_VGA, init_vga());
|
||||
IFDEF(CONFIG_HAS_KEYBOARD, init_i8042());
|
||||
IFDEF(CONFIG_HAS_AUDIO, init_audio());
|
||||
IFDEF(CONFIG_HAS_DISK, init_disk());
|
||||
IFDEF(CONFIG_HAS_SDCARD, init_sdcard());
|
||||
|
||||
IFNDEF(CONFIG_TARGET_AM, init_alarm());
|
||||
}
|
19
nemu/src/device/disk.c
Normal file
19
nemu/src/device/disk.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <device/map.h>
|
||||
|
||||
void init_disk() {
|
||||
}
|
32
nemu/src/device/filelist.mk
Normal file
32
nemu/src/device/filelist.mk
Normal file
|
@ -0,0 +1,32 @@
|
|||
#***************************************************************************************
|
||||
# Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
#
|
||||
# NEMU is licensed under Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
# See the Mulan PSL v2 for more details.
|
||||
#**************************************************************************************/
|
||||
|
||||
DIRS-y += src/device/io
|
||||
SRCS-$(CONFIG_DEVICE) += src/device/device.c src/device/alarm.c src/device/intr.c
|
||||
SRCS-$(CONFIG_HAS_SERIAL) += src/device/serial.c
|
||||
SRCS-$(CONFIG_HAS_TIMER) += src/device/timer.c
|
||||
SRCS-$(CONFIG_HAS_KEYBOARD) += src/device/keyboard.c
|
||||
SRCS-$(CONFIG_HAS_VGA) += src/device/vga.c
|
||||
SRCS-$(CONFIG_HAS_AUDIO) += src/device/audio.c
|
||||
SRCS-$(CONFIG_HAS_DISK) += src/device/disk.c
|
||||
SRCS-$(CONFIG_HAS_SDCARD) += src/device/sdcard.c
|
||||
|
||||
SRCS-BLACKLIST-$(CONFIG_TARGET_AM) += src/device/alarm.c
|
||||
|
||||
ifdef CONFIG_DEVICE
|
||||
ifndef CONFIG_TARGET_AM
|
||||
LIBS += -lSDL2
|
||||
endif
|
||||
endif
|
19
nemu/src/device/intr.c
Normal file
19
nemu/src/device/intr.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
|
||||
void dev_raise_intr() {
|
||||
}
|
70
nemu/src/device/io/map.c
Normal file
70
nemu/src/device/io/map.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <memory/host.h>
|
||||
#include <memory/vaddr.h>
|
||||
#include <device/map.h>
|
||||
|
||||
#define IO_SPACE_MAX (2 * 1024 * 1024)
|
||||
|
||||
static uint8_t *io_space = NULL;
|
||||
static uint8_t *p_space = NULL;
|
||||
|
||||
uint8_t* new_space(int size) {
|
||||
uint8_t *p = p_space;
|
||||
// page aligned;
|
||||
size = (size + (PAGE_SIZE - 1)) & ~PAGE_MASK;
|
||||
p_space += size;
|
||||
assert(p_space - io_space < IO_SPACE_MAX);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void check_bound(IOMap *map, paddr_t addr) {
|
||||
if (map == NULL) {
|
||||
Assert(map != NULL, "address (" FMT_PADDR ") is out of bound at pc = " FMT_WORD, addr, cpu.pc);
|
||||
} else {
|
||||
Assert(addr <= map->high && addr >= map->low,
|
||||
"address (" FMT_PADDR ") is out of bound {%s} [" FMT_PADDR ", " FMT_PADDR "] at pc = " FMT_WORD,
|
||||
addr, map->name, map->low, map->high, cpu.pc);
|
||||
}
|
||||
}
|
||||
|
||||
static void invoke_callback(io_callback_t c, paddr_t offset, int len, bool is_write) {
|
||||
if (c != NULL) { c(offset, len, is_write); }
|
||||
}
|
||||
|
||||
void init_map() {
|
||||
io_space = malloc(IO_SPACE_MAX);
|
||||
assert(io_space);
|
||||
p_space = io_space;
|
||||
}
|
||||
|
||||
word_t map_read(paddr_t addr, int len, IOMap *map) {
|
||||
assert(len >= 1 && len <= 8);
|
||||
check_bound(map, addr);
|
||||
paddr_t offset = addr - map->low;
|
||||
invoke_callback(map->callback, offset, len, false); // prepare data to read
|
||||
word_t ret = host_read(map->space + offset, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void map_write(paddr_t addr, int len, word_t data, IOMap *map) {
|
||||
assert(len >= 1 && len <= 8);
|
||||
check_bound(map, addr);
|
||||
paddr_t offset = addr - map->low;
|
||||
host_write(map->space + offset, len, data);
|
||||
invoke_callback(map->callback, offset, len, true);
|
||||
}
|
63
nemu/src/device/io/mmio.c
Normal file
63
nemu/src/device/io/mmio.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <device/map.h>
|
||||
#include <memory/paddr.h>
|
||||
|
||||
#define NR_MAP 16
|
||||
|
||||
static IOMap maps[NR_MAP] = {};
|
||||
static int nr_map = 0;
|
||||
|
||||
static IOMap* fetch_mmio_map(paddr_t addr) {
|
||||
int mapid = find_mapid_by_addr(maps, nr_map, addr);
|
||||
return (mapid == -1 ? NULL : &maps[mapid]);
|
||||
}
|
||||
|
||||
static void report_mmio_overlap(const char *name1, paddr_t l1, paddr_t r1,
|
||||
const char *name2, paddr_t l2, paddr_t r2) {
|
||||
panic("MMIO region %s@[" FMT_PADDR ", " FMT_PADDR "] is overlapped "
|
||||
"with %s@[" FMT_PADDR ", " FMT_PADDR "]", name1, l1, r1, name2, l2, r2);
|
||||
}
|
||||
|
||||
/* device interface */
|
||||
void add_mmio_map(const char *name, paddr_t addr, void *space, uint32_t len, io_callback_t callback) {
|
||||
assert(nr_map < NR_MAP);
|
||||
paddr_t left = addr, right = addr + len - 1;
|
||||
if (in_pmem(left) || in_pmem(right)) {
|
||||
report_mmio_overlap(name, left, right, "pmem", PMEM_LEFT, PMEM_RIGHT);
|
||||
}
|
||||
for (int i = 0; i < nr_map; i++) {
|
||||
if (left <= maps[i].high && right >= maps[i].low) {
|
||||
report_mmio_overlap(name, left, right, maps[i].name, maps[i].low, maps[i].high);
|
||||
}
|
||||
}
|
||||
|
||||
maps[nr_map] = (IOMap){ .name = name, .low = addr, .high = addr + len - 1,
|
||||
.space = space, .callback = callback };
|
||||
Log("Add mmio map '%s' at [" FMT_PADDR ", " FMT_PADDR "]",
|
||||
maps[nr_map].name, maps[nr_map].low, maps[nr_map].high);
|
||||
|
||||
nr_map ++;
|
||||
}
|
||||
|
||||
/* bus interface */
|
||||
word_t mmio_read(paddr_t addr, int len) {
|
||||
return map_read(addr, len, fetch_mmio_map(addr));
|
||||
}
|
||||
|
||||
void mmio_write(paddr_t addr, int len, word_t data) {
|
||||
map_write(addr, len, data, fetch_mmio_map(addr));
|
||||
}
|
49
nemu/src/device/io/port-io.c
Normal file
49
nemu/src/device/io/port-io.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <device/map.h>
|
||||
|
||||
#define PORT_IO_SPACE_MAX 65535
|
||||
|
||||
#define NR_MAP 16
|
||||
static IOMap maps[NR_MAP] = {};
|
||||
static int nr_map = 0;
|
||||
|
||||
/* device interface */
|
||||
void add_pio_map(const char *name, ioaddr_t addr, void *space, uint32_t len, io_callback_t callback) {
|
||||
assert(nr_map < NR_MAP);
|
||||
assert(addr + len <= PORT_IO_SPACE_MAX);
|
||||
maps[nr_map] = (IOMap){ .name = name, .low = addr, .high = addr + len - 1,
|
||||
.space = space, .callback = callback };
|
||||
Log("Add port-io map '%s' at [" FMT_PADDR ", " FMT_PADDR "]",
|
||||
maps[nr_map].name, maps[nr_map].low, maps[nr_map].high);
|
||||
|
||||
nr_map ++;
|
||||
}
|
||||
|
||||
/* CPU interface */
|
||||
uint32_t pio_read(ioaddr_t addr, int len) {
|
||||
assert(addr + len - 1 < PORT_IO_SPACE_MAX);
|
||||
int mapid = find_mapid_by_addr(maps, nr_map, addr);
|
||||
assert(mapid != -1);
|
||||
return map_read(addr, len, &maps[mapid]);
|
||||
}
|
||||
|
||||
void pio_write(ioaddr_t addr, int len, uint32_t data) {
|
||||
assert(addr + len - 1 < PORT_IO_SPACE_MAX);
|
||||
int mapid = find_mapid_by_addr(maps, nr_map, addr);
|
||||
assert(mapid != -1);
|
||||
map_write(addr, len, data, &maps[mapid]);
|
||||
}
|
100
nemu/src/device/keyboard.c
Normal file
100
nemu/src/device/keyboard.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <device/map.h>
|
||||
#include <utils.h>
|
||||
|
||||
#define KEYDOWN_MASK 0x8000
|
||||
|
||||
#ifndef CONFIG_TARGET_AM
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
// Note that this is not the standard
|
||||
#define NEMU_KEYS(f) \
|
||||
f(ESCAPE) f(F1) f(F2) f(F3) f(F4) f(F5) f(F6) f(F7) f(F8) f(F9) f(F10) f(F11) f(F12) \
|
||||
f(GRAVE) f(1) f(2) f(3) f(4) f(5) f(6) f(7) f(8) f(9) f(0) f(MINUS) f(EQUALS) f(BACKSPACE) \
|
||||
f(TAB) f(Q) f(W) f(E) f(R) f(T) f(Y) f(U) f(I) f(O) f(P) f(LEFTBRACKET) f(RIGHTBRACKET) f(BACKSLASH) \
|
||||
f(CAPSLOCK) f(A) f(S) f(D) f(F) f(G) f(H) f(J) f(K) f(L) f(SEMICOLON) f(APOSTROPHE) f(RETURN) \
|
||||
f(LSHIFT) f(Z) f(X) f(C) f(V) f(B) f(N) f(M) f(COMMA) f(PERIOD) f(SLASH) f(RSHIFT) \
|
||||
f(LCTRL) f(APPLICATION) f(LALT) f(SPACE) f(RALT) f(RCTRL) \
|
||||
f(UP) f(DOWN) f(LEFT) f(RIGHT) f(INSERT) f(DELETE) f(HOME) f(END) f(PAGEUP) f(PAGEDOWN)
|
||||
|
||||
#define NEMU_KEY_NAME(k) NEMU_KEY_ ## k,
|
||||
|
||||
enum {
|
||||
NEMU_KEY_NONE = 0,
|
||||
MAP(NEMU_KEYS, NEMU_KEY_NAME)
|
||||
};
|
||||
|
||||
#define SDL_KEYMAP(k) keymap[SDL_SCANCODE_ ## k] = NEMU_KEY_ ## k;
|
||||
static uint32_t keymap[256] = {};
|
||||
|
||||
static void init_keymap() {
|
||||
MAP(NEMU_KEYS, SDL_KEYMAP)
|
||||
}
|
||||
|
||||
#define KEY_QUEUE_LEN 1024
|
||||
static int key_queue[KEY_QUEUE_LEN] = {};
|
||||
static int key_f = 0, key_r = 0;
|
||||
|
||||
static void key_enqueue(uint32_t am_scancode) {
|
||||
key_queue[key_r] = am_scancode;
|
||||
key_r = (key_r + 1) % KEY_QUEUE_LEN;
|
||||
Assert(key_r != key_f, "key queue overflow!");
|
||||
}
|
||||
|
||||
static uint32_t key_dequeue() {
|
||||
uint32_t key = NEMU_KEY_NONE;
|
||||
if (key_f != key_r) {
|
||||
key = key_queue[key_f];
|
||||
key_f = (key_f + 1) % KEY_QUEUE_LEN;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
void send_key(uint8_t scancode, bool is_keydown) {
|
||||
if (nemu_state.state == NEMU_RUNNING && keymap[scancode] != NEMU_KEY_NONE) {
|
||||
uint32_t am_scancode = keymap[scancode] | (is_keydown ? KEYDOWN_MASK : 0);
|
||||
key_enqueue(am_scancode);
|
||||
}
|
||||
}
|
||||
#else // !CONFIG_TARGET_AM
|
||||
#define NEMU_KEY_NONE 0
|
||||
|
||||
static uint32_t key_dequeue() {
|
||||
AM_INPUT_KEYBRD_T ev = io_read(AM_INPUT_KEYBRD);
|
||||
uint32_t am_scancode = ev.keycode | (ev.keydown ? KEYDOWN_MASK : 0);
|
||||
return am_scancode;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t *i8042_data_port_base = NULL;
|
||||
|
||||
static void i8042_data_io_handler(uint32_t offset, int len, bool is_write) {
|
||||
assert(!is_write);
|
||||
assert(offset == 0);
|
||||
i8042_data_port_base[0] = key_dequeue();
|
||||
}
|
||||
|
||||
void init_i8042() {
|
||||
i8042_data_port_base = (uint32_t *)new_space(4);
|
||||
i8042_data_port_base[0] = NEMU_KEY_NONE;
|
||||
#ifdef CONFIG_HAS_PORT_IO
|
||||
add_pio_map ("keyboard", CONFIG_I8042_DATA_PORT, i8042_data_port_base, 4, i8042_data_io_handler);
|
||||
#else
|
||||
add_mmio_map("keyboard", CONFIG_I8042_DATA_MMIO, i8042_data_port_base, 4, i8042_data_io_handler);
|
||||
#endif
|
||||
IFNDEF(CONFIG_TARGET_AM, init_keymap());
|
||||
}
|
439
nemu/src/device/mmc.h
Normal file
439
nemu/src/device/mmc.h
Normal file
|
@ -0,0 +1,439 @@
|
|||
/*
|
||||
* Header for MultiMediaCard (MMC)
|
||||
*
|
||||
* Copyright 2002 Hewlett-Packard Company
|
||||
*
|
||||
* Use consistent with the GNU GPL is permitted,
|
||||
* provided that this copyright notice is
|
||||
* preserved in its entirety in all copies and derived works.
|
||||
*
|
||||
* HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
|
||||
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
|
||||
* FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*
|
||||
* Many thanks to Alessandro Rubini and Jonathan Corbet!
|
||||
*
|
||||
* Based strongly on code by:
|
||||
*
|
||||
* Author: Yong-iL Joh <tolkien@mizi.com>
|
||||
*
|
||||
* Author: Andrew Christian
|
||||
* 15 May 2002
|
||||
*/
|
||||
|
||||
#ifndef LINUX_MMC_MMC_H
|
||||
#define LINUX_MMC_MMC_H
|
||||
|
||||
/* Standard MMC commands (4.1) type argument response */
|
||||
/* class 1 */
|
||||
#define MMC_GO_IDLE_STATE 0 /* bc */
|
||||
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
|
||||
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
|
||||
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
|
||||
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
|
||||
#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */
|
||||
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
|
||||
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
|
||||
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
|
||||
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
|
||||
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
|
||||
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
|
||||
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
|
||||
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
|
||||
#define MMC_BUS_TEST_R 14 /* adtc R1 */
|
||||
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
|
||||
#define MMC_BUS_TEST_W 19 /* adtc R1 */
|
||||
#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */
|
||||
#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
|
||||
|
||||
/* class 2 */
|
||||
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
|
||||
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
|
||||
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
|
||||
|
||||
/* class 3 */
|
||||
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
|
||||
|
||||
/* class 4 */
|
||||
#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
|
||||
#define MMC_PROGRAM_CID 26 /* adtc R1 */
|
||||
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
|
||||
|
||||
/* class 6 */
|
||||
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
|
||||
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
|
||||
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
|
||||
|
||||
/* class 5 */
|
||||
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
|
||||
#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
|
||||
#define MMC_ERASE 38 /* ac R1b */
|
||||
|
||||
/* class 9 */
|
||||
#define MMC_FAST_IO 39 /* ac <Complex> R4 */
|
||||
#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
|
||||
|
||||
/* class 7 */
|
||||
#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
|
||||
|
||||
/* class 8 */
|
||||
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
|
||||
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
|
||||
|
||||
/* class 11 */
|
||||
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
|
||||
#define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr R1 */
|
||||
#define MMC_EXECUTE_READ_TASK 46 /* adtc [20:16] task id R1 */
|
||||
#define MMC_EXECUTE_WRITE_TASK 47 /* adtc [20:16] task id R1 */
|
||||
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
|
||||
|
||||
//static inline bool mmc_op_multi(u32 opcode)
|
||||
//{
|
||||
// return opcode == MMC_WRITE_MULTIPLE_BLOCK ||
|
||||
// opcode == MMC_READ_MULTIPLE_BLOCK;
|
||||
//}
|
||||
|
||||
/*
|
||||
* MMC_SWITCH argument format:
|
||||
*
|
||||
* [31:26] Always 0
|
||||
* [25:24] Access Mode
|
||||
* [23:16] Location of target Byte in EXT_CSD
|
||||
* [15:08] Value Byte
|
||||
* [07:03] Always 0
|
||||
* [02:00] Command Set
|
||||
*/
|
||||
|
||||
/*
|
||||
MMC status in R1, for native mode (SPI bits are different)
|
||||
Type
|
||||
e : error bit
|
||||
s : status bit
|
||||
r : detected and set for the actual command response
|
||||
x : detected and set during command execution. the host must poll
|
||||
the card by sending status command in order to read these bits.
|
||||
Clear condition
|
||||
a : according to the card state
|
||||
b : always related to the previous command. Reception of
|
||||
a valid command will clear it (with a delay of one command)
|
||||
c : clear by read
|
||||
*/
|
||||
|
||||
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
|
||||
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
|
||||
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
|
||||
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
|
||||
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
|
||||
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
|
||||
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
|
||||
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
|
||||
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
|
||||
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
|
||||
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
|
||||
#define R1_CC_ERROR (1 << 20) /* erx, c */
|
||||
#define R1_ERROR (1 << 19) /* erx, c */
|
||||
#define R1_UNDERRUN (1 << 18) /* ex, c */
|
||||
#define R1_OVERRUN (1 << 17) /* ex, c */
|
||||
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
|
||||
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
|
||||
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
|
||||
#define R1_ERASE_RESET (1 << 13) /* sr, c */
|
||||
#define R1_STATUS(x) (x & 0xFFFFE000)
|
||||
#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
|
||||
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
|
||||
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
|
||||
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
|
||||
#define R1_APP_CMD (1 << 5) /* sr, c */
|
||||
|
||||
#define R1_STATE_IDLE 0
|
||||
#define R1_STATE_READY 1
|
||||
#define R1_STATE_IDENT 2
|
||||
#define R1_STATE_STBY 3
|
||||
#define R1_STATE_TRAN 4
|
||||
#define R1_STATE_DATA 5
|
||||
#define R1_STATE_RCV 6
|
||||
#define R1_STATE_PRG 7
|
||||
#define R1_STATE_DIS 8
|
||||
|
||||
/*
|
||||
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
|
||||
* R1 is the low order byte; R2 is the next highest byte, when present.
|
||||
*/
|
||||
#define R1_SPI_IDLE (1 << 0)
|
||||
#define R1_SPI_ERASE_RESET (1 << 1)
|
||||
#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
|
||||
#define R1_SPI_COM_CRC (1 << 3)
|
||||
#define R1_SPI_ERASE_SEQ (1 << 4)
|
||||
#define R1_SPI_ADDRESS (1 << 5)
|
||||
#define R1_SPI_PARAMETER (1 << 6)
|
||||
/* R1 bit 7 is always zero */
|
||||
#define R2_SPI_CARD_LOCKED (1 << 8)
|
||||
#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */
|
||||
#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP
|
||||
#define R2_SPI_ERROR (1 << 10)
|
||||
#define R2_SPI_CC_ERROR (1 << 11)
|
||||
#define R2_SPI_CARD_ECC_ERROR (1 << 12)
|
||||
#define R2_SPI_WP_VIOLATION (1 << 13)
|
||||
#define R2_SPI_ERASE_PARAM (1 << 14)
|
||||
#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */
|
||||
#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
|
||||
|
||||
/*
|
||||
* OCR bits are mostly in host.h
|
||||
*/
|
||||
#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
|
||||
|
||||
/*
|
||||
* Card Command Classes (CCC)
|
||||
*/
|
||||
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
|
||||
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
|
||||
/* (and for SPI, CMD58,59) */
|
||||
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
|
||||
/* (CMD11) */
|
||||
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
|
||||
/* (CMD16,17,18) */
|
||||
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
|
||||
/* (CMD20) */
|
||||
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
|
||||
/* (CMD16,24,25,26,27) */
|
||||
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
|
||||
/* (CMD32,33,34,35,36,37,38,39) */
|
||||
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
|
||||
/* (CMD28,29,30) */
|
||||
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
|
||||
/* (CMD16,CMD42) */
|
||||
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
|
||||
/* (CMD55,56,57,ACMD*) */
|
||||
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
|
||||
/* (CMD5,39,40,52,53) */
|
||||
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
|
||||
/* (CMD6,34,35,36,37,50) */
|
||||
/* (11) Reserved */
|
||||
/* (CMD?) */
|
||||
|
||||
/*
|
||||
* CSD field definitions
|
||||
*/
|
||||
|
||||
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
|
||||
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
|
||||
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
|
||||
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
|
||||
|
||||
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
|
||||
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
|
||||
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
|
||||
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
|
||||
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
|
||||
|
||||
/*
|
||||
* EXT_CSD fields
|
||||
*/
|
||||
|
||||
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
|
||||
#define EXT_CSD_FLUSH_CACHE 32 /* W */
|
||||
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
|
||||
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
|
||||
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
|
||||
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
|
||||
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
|
||||
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
|
||||
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
|
||||
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
|
||||
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
|
||||
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
|
||||
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
|
||||
#define EXT_CSD_HPI_MGMT 161 /* R/W */
|
||||
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
|
||||
#define EXT_CSD_BKOPS_EN 163 /* R/W */
|
||||
#define EXT_CSD_BKOPS_START 164 /* W */
|
||||
#define EXT_CSD_SANITIZE_START 165 /* W */
|
||||
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
|
||||
#define EXT_CSD_RPMB_MULT 168 /* RO */
|
||||
#define EXT_CSD_FW_CONFIG 169 /* R/W */
|
||||
#define EXT_CSD_BOOT_WP 173 /* R/W */
|
||||
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
|
||||
#define EXT_CSD_PART_CONFIG 179 /* R/W */
|
||||
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
|
||||
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
|
||||
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
|
||||
#define EXT_CSD_HS_TIMING 185 /* R/W */
|
||||
#define EXT_CSD_POWER_CLASS 187 /* R/W */
|
||||
#define EXT_CSD_REV 192 /* RO */
|
||||
#define EXT_CSD_STRUCTURE 194 /* RO */
|
||||
#define EXT_CSD_CARD_TYPE 196 /* RO */
|
||||
#define EXT_CSD_DRIVER_STRENGTH 197 /* RO */
|
||||
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
|
||||
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
|
||||
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
|
||||
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
|
||||
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
|
||||
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
|
||||
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
|
||||
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
|
||||
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
|
||||
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
|
||||
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
|
||||
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
|
||||
#define EXT_CSD_BOOT_MULT 226 /* RO */
|
||||
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
|
||||
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
|
||||
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
|
||||
#define EXT_CSD_TRIM_MULT 232 /* RO */
|
||||
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
|
||||
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
|
||||
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
|
||||
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
|
||||
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
|
||||
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
|
||||
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
|
||||
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
|
||||
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
|
||||
#define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */
|
||||
#define EXT_CSD_PRE_EOL_INFO 267 /* RO */
|
||||
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */
|
||||
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */
|
||||
#define EXT_CSD_CMDQ_DEPTH 307 /* RO */
|
||||
#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */
|
||||
#define EXT_CSD_SUPPORTED_MODE 493 /* RO */
|
||||
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
|
||||
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
|
||||
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
|
||||
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
|
||||
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
|
||||
#define EXT_CSD_HPI_FEATURES 503 /* RO */
|
||||
|
||||
/*
|
||||
* EXT_CSD field definitions
|
||||
*/
|
||||
|
||||
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
|
||||
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
|
||||
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
|
||||
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
|
||||
|
||||
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
|
||||
|
||||
#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
|
||||
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
|
||||
|
||||
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
|
||||
#define EXT_CSD_CMD_SET_SECURE (1<<1)
|
||||
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
|
||||
|
||||
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
|
||||
EXT_CSD_CARD_TYPE_HS_52)
|
||||
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
|
||||
/* DDR mode @1.8V or 3V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
|
||||
/* DDR mode @1.2V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
|
||||
| EXT_CSD_CARD_TYPE_DDR_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
|
||||
/* SDR mode @1.2V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
|
||||
EXT_CSD_CARD_TYPE_HS200_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
|
||||
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
|
||||
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
|
||||
EXT_CSD_CARD_TYPE_HS400_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
|
||||
|
||||
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
|
||||
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
|
||||
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
|
||||
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
|
||||
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
|
||||
#define EXT_CSD_BUS_WIDTH_STROBE BIT(7) /* Enhanced strobe mode */
|
||||
|
||||
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
|
||||
#define EXT_CSD_TIMING_HS 1 /* High speed */
|
||||
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
|
||||
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
|
||||
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
|
||||
|
||||
#define EXT_CSD_SEC_ER_EN BIT(0)
|
||||
#define EXT_CSD_SEC_BD_BLK_EN BIT(2)
|
||||
#define EXT_CSD_SEC_GB_CL_EN BIT(4)
|
||||
#define EXT_CSD_SEC_SANITIZE BIT(6) /* v4.5 only */
|
||||
|
||||
#define EXT_CSD_RST_N_EN_MASK 0x3
|
||||
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
|
||||
|
||||
#define EXT_CSD_NO_POWER_NOTIFICATION 0
|
||||
#define EXT_CSD_POWER_ON 1
|
||||
#define EXT_CSD_POWER_OFF_SHORT 2
|
||||
#define EXT_CSD_POWER_OFF_LONG 3
|
||||
|
||||
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
|
||||
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
|
||||
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
|
||||
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
|
||||
|
||||
#define EXT_CSD_PACKED_EVENT_EN BIT(3)
|
||||
|
||||
/*
|
||||
* EXCEPTION_EVENT_STATUS field
|
||||
*/
|
||||
#define EXT_CSD_URGENT_BKOPS BIT(0)
|
||||
#define EXT_CSD_DYNCAP_NEEDED BIT(1)
|
||||
#define EXT_CSD_SYSPOOL_EXHAUSTED BIT(2)
|
||||
#define EXT_CSD_PACKED_FAILURE BIT(3)
|
||||
|
||||
#define EXT_CSD_PACKED_GENERIC_ERROR BIT(0)
|
||||
#define EXT_CSD_PACKED_INDEXED_ERROR BIT(1)
|
||||
|
||||
/*
|
||||
* BKOPS status level
|
||||
*/
|
||||
#define EXT_CSD_BKOPS_LEVEL_2 0x2
|
||||
|
||||
/*
|
||||
* BKOPS modes
|
||||
*/
|
||||
#define EXT_CSD_MANUAL_BKOPS_MASK 0x01
|
||||
#define EXT_CSD_AUTO_BKOPS_MASK 0x02
|
||||
|
||||
/*
|
||||
* Command Queue
|
||||
*/
|
||||
#define EXT_CSD_CMDQ_MODE_ENABLED BIT(0)
|
||||
#define EXT_CSD_CMDQ_DEPTH_MASK GENMASK(4, 0)
|
||||
#define EXT_CSD_CMDQ_SUPPORTED BIT(0)
|
||||
|
||||
/*
|
||||
* MMC_SWITCH access modes
|
||||
*/
|
||||
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
|
||||
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
|
||||
|
||||
/*
|
||||
* Erase/trim/discard
|
||||
*/
|
||||
#define MMC_ERASE_ARG 0x00000000
|
||||
#define MMC_SECURE_ERASE_ARG 0x80000000
|
||||
#define MMC_TRIM_ARG 0x00000001
|
||||
#define MMC_DISCARD_ARG 0x00000003
|
||||
#define MMC_SECURE_TRIM1_ARG 0x80000001
|
||||
#define MMC_SECURE_TRIM2_ARG 0x80008000
|
||||
#define MMC_SECURE_ARGS 0x80000000
|
||||
#define MMC_TRIM_ARGS 0x00008001
|
||||
|
||||
#define mmc_driver_type_mask(n) (1 << (n))
|
||||
|
||||
#endif /* LINUX_MMC_MMC_H */
|
134
nemu/src/device/sdcard.c
Normal file
134
nemu/src/device/sdcard.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <device/map.h>
|
||||
#include "mmc.h"
|
||||
|
||||
// http://www.files.e-shop.co.il/pdastore/Tech-mmc-samsung/SEC%20MMC%20SPEC%20ver09.pdf
|
||||
|
||||
// see page 26 of the manual above
|
||||
#define MEMORY_SIZE (16ull * 1024 * 1024 * 1024) // 16GB
|
||||
#define READ_BL_LEN 15
|
||||
#define BLOCK_LEN (1 << READ_BL_LEN)
|
||||
#define NR_BLOCK (MEMORY_SIZE / BLOCK_LEN)
|
||||
#define C_SIZE_MULT 7 // only 3 bits
|
||||
#define MULT (1 << (C_SIZE_MULT + 2))
|
||||
#define C_SIZE (NR_BLOCK / MULT - 1)
|
||||
|
||||
// This is a simple hardware implementation of linux/drivers/mmc/host/bcm2835.c
|
||||
// No DMA and IRQ is supported, so the driver must be modified to start PIO
|
||||
// right after sending the actual read/write commands.
|
||||
|
||||
enum {
|
||||
SDCMD, SDARG, SDTOUT, SDCDIV,
|
||||
SDRSP0, SDRSP1, SDRSP2, SDRSP3,
|
||||
SDHSTS, __PAD0, __PAD1, __PAD2,
|
||||
SDVDD, SDEDM, SDHCFG, SDHBCT,
|
||||
SDDATA, __PAD10, __PAD11, __PAD12,
|
||||
SDHBLC
|
||||
};
|
||||
|
||||
static FILE *fp = NULL;
|
||||
static uint32_t *base = NULL;
|
||||
static uint32_t blkcnt = 0;
|
||||
static long blk_addr = 0;
|
||||
static uint32_t addr = 0;
|
||||
static bool write_cmd = 0;
|
||||
static bool read_ext_csd = false;
|
||||
|
||||
static void prepare_rw(int is_write) {
|
||||
blk_addr = base[SDARG];
|
||||
addr = 0;
|
||||
if (fp) fseek(fp, blk_addr << 9, SEEK_SET);
|
||||
write_cmd = is_write;
|
||||
}
|
||||
|
||||
static void sdcard_handle_cmd(int cmd) {
|
||||
switch (cmd) {
|
||||
case MMC_GO_IDLE_STATE: break;
|
||||
case MMC_SEND_OP_COND: base[SDRSP0] = 0x80ff8000; break;
|
||||
case MMC_ALL_SEND_CID:
|
||||
base[SDRSP0] = 0x00000001;
|
||||
base[SDRSP1] = 0x00000000;
|
||||
base[SDRSP2] = 0x00000000;
|
||||
base[SDRSP3] = 0x15000000;
|
||||
break;
|
||||
case 52: // ???
|
||||
break;
|
||||
case MMC_SEND_CSD:
|
||||
base[SDRSP0] = 0x92404001;
|
||||
base[SDRSP1] = 0x124b97e3 | ((C_SIZE & 0x3) << 30);
|
||||
base[SDRSP2] = 0x0f508000 | (C_SIZE >> 2) | (READ_BL_LEN << 16);
|
||||
base[SDRSP3] = 0x9026012a;
|
||||
break;
|
||||
case MMC_SEND_EXT_CSD: read_ext_csd = true; addr = 0; break;
|
||||
case MMC_SLEEP_AWAKE: break;
|
||||
case MMC_APP_CMD: break;
|
||||
case MMC_SET_RELATIVE_ADDR: break;
|
||||
case MMC_SELECT_CARD: break;
|
||||
case MMC_SET_BLOCK_COUNT: blkcnt = base[SDARG] & 0xffff; break;
|
||||
case MMC_READ_MULTIPLE_BLOCK: prepare_rw(false); break;
|
||||
case MMC_WRITE_MULTIPLE_BLOCK: prepare_rw(true); break;
|
||||
case MMC_SEND_STATUS: base[SDRSP0] = 0x900; base[SDRSP1] = base[SDRSP2] = base[SDRSP3] = 0; break;
|
||||
case MMC_STOP_TRANSMISSION: break;
|
||||
default:
|
||||
panic("unhandled command = %d", cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static void sdcard_io_handler(uint32_t offset, int len, bool is_write) {
|
||||
int idx = offset / 4;
|
||||
switch (idx) {
|
||||
case SDCMD: sdcard_handle_cmd(base[SDCMD] & 0x3f); break;
|
||||
case SDARG:
|
||||
case SDRSP0:
|
||||
case SDRSP1:
|
||||
case SDRSP2:
|
||||
case SDRSP3:
|
||||
break;
|
||||
case SDDATA:
|
||||
if (read_ext_csd) {
|
||||
// See section 8.1 JEDEC Standard JED84-A441
|
||||
uint32_t data;
|
||||
switch (addr) {
|
||||
case 192: data = 2; break; // EXT_CSD_REV
|
||||
case 212: data = MEMORY_SIZE / 512; break;
|
||||
default: data = 0;
|
||||
}
|
||||
base[SDDATA] = data;
|
||||
if (addr == 512 - 4) read_ext_csd = false;
|
||||
} else if (fp) {
|
||||
__attribute__((unused)) int ret;
|
||||
if (!write_cmd) { ret = fread(&base[SDDATA], 4, 1, fp); }
|
||||
else { ret = fwrite(&base[SDDATA], 4, 1, fp); }
|
||||
}
|
||||
addr += 4;
|
||||
break;
|
||||
default:
|
||||
Log("offset = 0x%x(idx = %d), is_write = %d, data = 0x%x", offset, idx, is_write, base[idx]);
|
||||
panic("unhandle offset = %d", offset);
|
||||
}
|
||||
}
|
||||
|
||||
void init_sdcard() {
|
||||
base = (uint32_t *)new_space(0x80);
|
||||
add_mmio_map("sdhci", CONFIG_SDCARD_CTL_MMIO, base, 0x80, sdcard_io_handler);
|
||||
|
||||
Assert(C_SIZE < (1 << 12), "shoule be fit in 12 bits");
|
||||
|
||||
const char *img = CONFIG_SDCARD_IMG_PATH;
|
||||
fp = fopen(img, "r+");
|
||||
if (fp == NULL) Log("Can not find sdcard image: %s", img);
|
||||
}
|
51
nemu/src/device/serial.c
Normal file
51
nemu/src/device/serial.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <utils.h>
|
||||
#include <device/map.h>
|
||||
|
||||
/* http://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming */
|
||||
// NOTE: this is compatible to 16550
|
||||
|
||||
#define CH_OFFSET 0
|
||||
|
||||
static uint8_t *serial_base = NULL;
|
||||
|
||||
|
||||
static void serial_putc(char ch) {
|
||||
MUXDEF(CONFIG_TARGET_AM, putch(ch), putc(ch, stderr));
|
||||
}
|
||||
|
||||
static void serial_io_handler(uint32_t offset, int len, bool is_write) {
|
||||
assert(len == 1);
|
||||
switch (offset) {
|
||||
/* We bind the serial port with the host stderr in NEMU. */
|
||||
case CH_OFFSET:
|
||||
if (is_write) serial_putc(serial_base[0]);
|
||||
else panic("do not support read");
|
||||
break;
|
||||
default: panic("do not support offset = %d", offset);
|
||||
}
|
||||
}
|
||||
|
||||
void init_serial() {
|
||||
serial_base = new_space(8);
|
||||
#ifdef CONFIG_HAS_PORT_IO
|
||||
add_pio_map ("serial", CONFIG_SERIAL_PORT, serial_base, 8, serial_io_handler);
|
||||
#else
|
||||
add_mmio_map("serial", CONFIG_SERIAL_MMIO, serial_base, 8, serial_io_handler);
|
||||
#endif
|
||||
|
||||
}
|
48
nemu/src/device/timer.c
Normal file
48
nemu/src/device/timer.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <device/map.h>
|
||||
#include <device/alarm.h>
|
||||
#include <utils.h>
|
||||
|
||||
static uint32_t *rtc_port_base = NULL;
|
||||
|
||||
static void rtc_io_handler(uint32_t offset, int len, bool is_write) {
|
||||
assert(offset == 0 || offset == 4);
|
||||
if (!is_write && offset == 4) {
|
||||
uint64_t us = get_time();
|
||||
rtc_port_base[0] = (uint32_t)us;
|
||||
rtc_port_base[1] = us >> 32;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_TARGET_AM
|
||||
static void timer_intr() {
|
||||
if (nemu_state.state == NEMU_RUNNING) {
|
||||
extern void dev_raise_intr();
|
||||
dev_raise_intr();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void init_timer() {
|
||||
rtc_port_base = (uint32_t *)new_space(8);
|
||||
#ifdef CONFIG_HAS_PORT_IO
|
||||
add_pio_map ("rtc", CONFIG_RTC_PORT, rtc_port_base, 8, rtc_io_handler);
|
||||
#else
|
||||
add_mmio_map("rtc", CONFIG_RTC_MMIO, rtc_port_base, 8, rtc_io_handler);
|
||||
#endif
|
||||
IFNDEF(CONFIG_TARGET_AM, add_alarm_handle(timer_intr));
|
||||
}
|
92
nemu/src/device/vga.c
Normal file
92
nemu/src/device/vga.c
Normal file
|
@ -0,0 +1,92 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <common.h>
|
||||
#include <device/map.h>
|
||||
|
||||
#define SCREEN_W (MUXDEF(CONFIG_VGA_SIZE_800x600, 800, 400))
|
||||
#define SCREEN_H (MUXDEF(CONFIG_VGA_SIZE_800x600, 600, 300))
|
||||
|
||||
static uint32_t screen_width() {
|
||||
return MUXDEF(CONFIG_TARGET_AM, io_read(AM_GPU_CONFIG).width, SCREEN_W);
|
||||
}
|
||||
|
||||
static uint32_t screen_height() {
|
||||
return MUXDEF(CONFIG_TARGET_AM, io_read(AM_GPU_CONFIG).height, SCREEN_H);
|
||||
}
|
||||
|
||||
static uint32_t screen_size() {
|
||||
return screen_width() * screen_height() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static void *vmem = NULL;
|
||||
static uint32_t *vgactl_port_base = NULL;
|
||||
|
||||
#ifdef CONFIG_VGA_SHOW_SCREEN
|
||||
#ifndef CONFIG_TARGET_AM
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
|
||||
static void init_screen() {
|
||||
SDL_Window *window = NULL;
|
||||
char title[128];
|
||||
sprintf(title, "%s-NEMU", str(__GUEST_ISA__));
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
SDL_CreateWindowAndRenderer(
|
||||
SCREEN_W * (MUXDEF(CONFIG_VGA_SIZE_400x300, 2, 1)),
|
||||
SCREEN_H * (MUXDEF(CONFIG_VGA_SIZE_400x300, 2, 1)),
|
||||
0, &window, &renderer);
|
||||
SDL_SetWindowTitle(window, title);
|
||||
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STATIC, SCREEN_W, SCREEN_H);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
static inline void update_screen() {
|
||||
SDL_UpdateTexture(texture, NULL, vmem, SCREEN_W * sizeof(uint32_t));
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
#else
|
||||
static void init_screen() {}
|
||||
|
||||
static inline void update_screen() {
|
||||
io_write(AM_GPU_FBDRAW, 0, 0, vmem, screen_width(), screen_height(), true);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void vga_update_screen() {
|
||||
// TODO: call `update_screen()` when the sync register is non-zero,
|
||||
// then zero out the sync register
|
||||
}
|
||||
|
||||
void init_vga() {
|
||||
vgactl_port_base = (uint32_t *)new_space(8);
|
||||
vgactl_port_base[0] = (screen_width() << 16) | screen_height();
|
||||
#ifdef CONFIG_HAS_PORT_IO
|
||||
add_pio_map ("vgactl", CONFIG_VGA_CTL_PORT, vgactl_port_base, 8, NULL);
|
||||
#else
|
||||
add_mmio_map("vgactl", CONFIG_VGA_CTL_MMIO, vgactl_port_base, 8, NULL);
|
||||
#endif
|
||||
|
||||
vmem = new_space(screen_size());
|
||||
add_mmio_map("vmem", CONFIG_FB_ADDR, vmem, screen_size(), NULL);
|
||||
IFDEF(CONFIG_VGA_SHOW_SCREEN, init_screen());
|
||||
IFDEF(CONFIG_VGA_SHOW_SCREEN, memset(vmem, 0, screen_size()));
|
||||
}
|
17
nemu/src/engine/filelist.mk
Normal file
17
nemu/src/engine/filelist.mk
Normal file
|
@ -0,0 +1,17 @@
|
|||
#***************************************************************************************
|
||||
# Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
#
|
||||
# NEMU is licensed under Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
# See the Mulan PSL v2 for more details.
|
||||
#**************************************************************************************/
|
||||
|
||||
INC_PATH += $(NEMU_HOME)/src/engine/$(ENGINE)
|
||||
DIRS-y += src/engine/$(ENGINE)
|
51
nemu/src/engine/interpreter/hostcall.c
Normal file
51
nemu/src/engine/interpreter/hostcall.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <utils.h>
|
||||
#include <cpu/ifetch.h>
|
||||
#include <isa.h>
|
||||
#include <cpu/difftest.h>
|
||||
|
||||
void set_nemu_state(int state, vaddr_t pc, int halt_ret) {
|
||||
difftest_skip_ref();
|
||||
nemu_state.state = state;
|
||||
nemu_state.halt_pc = pc;
|
||||
nemu_state.halt_ret = halt_ret;
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
void invalid_inst(vaddr_t thispc) {
|
||||
uint32_t temp[2];
|
||||
vaddr_t pc = thispc;
|
||||
temp[0] = inst_fetch(&pc, 4);
|
||||
temp[1] = inst_fetch(&pc, 4);
|
||||
|
||||
uint8_t *p = (uint8_t *)temp;
|
||||
printf("invalid opcode(PC = " FMT_WORD "):\n"
|
||||
"\t%02x %02x %02x %02x %02x %02x %02x %02x ...\n"
|
||||
"\t%08x %08x...\n",
|
||||
thispc, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], temp[0], temp[1]);
|
||||
|
||||
printf("There are two cases which will trigger this unexpected exception:\n"
|
||||
"1. The instruction at PC = " FMT_WORD " is not implemented.\n"
|
||||
"2. Something is implemented incorrectly.\n", thispc);
|
||||
printf("Find this PC(" FMT_WORD ") in the disassembling result to distinguish which case it is.\n\n", thispc);
|
||||
printf(ANSI_FMT("If it is the first case, see\n%s\nfor more details.\n\n"
|
||||
"If it is the second case, remember:\n"
|
||||
"* The machine is always right!\n"
|
||||
"* Every line of untested code is always wrong!\n\n", ANSI_FG_RED), isa_logo);
|
||||
|
||||
set_nemu_state(NEMU_ABORT, thispc, -1);
|
||||
}
|
27
nemu/src/engine/interpreter/init.c
Normal file
27
nemu/src/engine/interpreter/init.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <cpu/cpu.h>
|
||||
|
||||
void sdb_mainloop();
|
||||
|
||||
void engine_start() {
|
||||
#ifdef CONFIG_TARGET_AM
|
||||
cpu_exec(-1);
|
||||
#else
|
||||
/* Receive commands from user. */
|
||||
sdb_mainloop();
|
||||
#endif
|
||||
}
|
28
nemu/src/filelist.mk
Normal file
28
nemu/src/filelist.mk
Normal file
|
@ -0,0 +1,28 @@
|
|||
#***************************************************************************************
|
||||
# Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
#
|
||||
# NEMU is licensed under Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
# See the Mulan PSL v2 for more details.
|
||||
#**************************************************************************************/
|
||||
|
||||
SRCS-y += src/nemu-main.c
|
||||
DIRS-y += src/cpu src/monitor src/utils
|
||||
DIRS-$(CONFIG_MODE_SYSTEM) += src/memory
|
||||
DIRS-BLACKLIST-$(CONFIG_TARGET_AM) += src/monitor/sdb
|
||||
|
||||
SHARE = $(if $(CONFIG_TARGET_SHARE),1,0)
|
||||
LIBS += $(if $(CONFIG_TARGET_NATIVE_ELF),-lreadline -ldl -pie,)
|
||||
|
||||
ifdef mainargs
|
||||
ASFLAGS += -DBIN_PATH=\"$(mainargs)\"
|
||||
endif
|
||||
SRCS-$(CONFIG_TARGET_AM) += src/am-bin.S
|
||||
.PHONY: src/am-bin.S
|
17
nemu/src/isa/filelist.mk
Normal file
17
nemu/src/isa/filelist.mk
Normal file
|
@ -0,0 +1,17 @@
|
|||
#***************************************************************************************
|
||||
# Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
#
|
||||
# NEMU is licensed under Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
# See the Mulan PSL v2 for more details.
|
||||
#**************************************************************************************/
|
||||
|
||||
INC_PATH += $(NEMU_HOME)/src/isa/$(GUEST_ISA)/include
|
||||
DIRS-y += src/isa/$(GUEST_ISA)
|
25
nemu/src/isa/loongarch32r/difftest/dut.c
Normal file
25
nemu/src/isa/loongarch32r/difftest/dut.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <cpu/difftest.h>
|
||||
#include "../local-include/reg.h"
|
||||
|
||||
bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void isa_difftest_attach() {
|
||||
}
|
35
nemu/src/isa/loongarch32r/include/isa-def.h
Normal file
35
nemu/src/isa/loongarch32r/include/isa-def.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __ISA_LOONGARCH32R_H__
|
||||
#define __ISA_LOONGARCH32R_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
typedef struct {
|
||||
word_t gpr[32];
|
||||
vaddr_t pc;
|
||||
} loongarch32r_CPU_state;
|
||||
|
||||
// decode
|
||||
typedef struct {
|
||||
union {
|
||||
uint32_t val;
|
||||
} inst;
|
||||
} loongarch32r_ISADecodeInfo;
|
||||
|
||||
#define isa_mmu_check(vaddr, len, type) (MMU_DIRECT)
|
||||
|
||||
#endif
|
43
nemu/src/isa/loongarch32r/init.c
Normal file
43
nemu/src/isa/loongarch32r/init.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <memory/paddr.h>
|
||||
|
||||
// this is not consistent with uint8_t
|
||||
// but it is ok since we do not access the array directly
|
||||
static const uint32_t img [] = {
|
||||
0x1c00000c, // pcaddu12i $t0,0
|
||||
0x29804180, // st.w $zero,$t0,16
|
||||
0x28804184, // ld.w $a0,$t0,16
|
||||
0x002a0000, // break 0 (used as nemu_trap)
|
||||
0xdeadbeef, // some data
|
||||
};
|
||||
|
||||
static void restart() {
|
||||
/* Set the initial program counter. */
|
||||
cpu.pc = RESET_VECTOR;
|
||||
|
||||
/* The zero register is always 0. */
|
||||
cpu.gpr[0] = 0;
|
||||
}
|
||||
|
||||
void init_isa() {
|
||||
/* Load built-in image. */
|
||||
memcpy(guest_to_host(RESET_VECTOR), img, sizeof(img));
|
||||
|
||||
/* Initialize this virtual computer system. */
|
||||
restart();
|
||||
}
|
72
nemu/src/isa/loongarch32r/inst.c
Normal file
72
nemu/src/isa/loongarch32r/inst.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include "local-include/reg.h"
|
||||
#include <cpu/cpu.h>
|
||||
#include <cpu/ifetch.h>
|
||||
#include <cpu/decode.h>
|
||||
|
||||
#define R(i) gpr(i)
|
||||
#define Mr vaddr_read
|
||||
#define Mw vaddr_write
|
||||
|
||||
enum {
|
||||
TYPE_2RI12, TYPE_1RI20,
|
||||
TYPE_N, // none
|
||||
};
|
||||
|
||||
#define src1R() do { *src1 = R(rj); } while (0)
|
||||
#define simm12() do { *imm = SEXT(BITS(i, 21, 10), 12); } while (0)
|
||||
#define simm20() do { *imm = SEXT(BITS(i, 24, 5), 20) << 12; } while (0)
|
||||
|
||||
static void decode_operand(Decode *s, int *rd_, word_t *src1, word_t *src2, word_t *imm, int type) {
|
||||
uint32_t i = s->isa.inst.val;
|
||||
int rj = BITS(i, 9, 5);
|
||||
*rd_ = BITS(i, 4, 0);
|
||||
switch (type) {
|
||||
case TYPE_1RI20: simm20(); src1R(); break;
|
||||
case TYPE_2RI12: simm12(); src1R(); break;
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_exec(Decode *s) {
|
||||
int rd = 0;
|
||||
word_t src1 = 0, src2 = 0, imm = 0;
|
||||
s->dnpc = s->snpc;
|
||||
|
||||
#define INSTPAT_INST(s) ((s)->isa.inst.val)
|
||||
#define INSTPAT_MATCH(s, name, type, ... /* execute body */ ) { \
|
||||
decode_operand(s, &rd, &src1, &src2, &imm, concat(TYPE_, type)); \
|
||||
__VA_ARGS__ ; \
|
||||
}
|
||||
|
||||
INSTPAT_START();
|
||||
INSTPAT("0001110 ????? ????? ????? ????? ?????" , pcaddu12i, 1RI20 , R(rd) = s->pc + imm);
|
||||
INSTPAT("0010100010 ???????????? ????? ?????" , ld.w , 2RI12 , R(rd) = Mr(src1 + imm, 4));
|
||||
INSTPAT("0010100110 ???????????? ????? ?????" , st.w , 2RI12 , Mw(src1 + imm, 4, R(rd)));
|
||||
|
||||
INSTPAT("0000 0000 0010 10100 ????? ????? ?????", break , N , NEMUTRAP(s->pc, R(4))); // R(4) is $a0
|
||||
INSTPAT("????????????????? ????? ????? ?????" , inv , N , INV(s->pc));
|
||||
INSTPAT_END();
|
||||
|
||||
R(0) = 0; // reset $zero to 0
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isa_exec_once(Decode *s) {
|
||||
s->isa.inst.val = inst_fetch(&s->snpc, 4);
|
||||
return decode_exec(s);
|
||||
}
|
33
nemu/src/isa/loongarch32r/local-include/reg.h
Normal file
33
nemu/src/isa/loongarch32r/local-include/reg.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __LOONGARCH32R_REG_H__
|
||||
#define __LOONGARCH32R_REG_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
static inline int check_reg_idx(int idx) {
|
||||
IFDEF(CONFIG_RT_CHECK, assert(idx >= 0 && idx < 32));
|
||||
return idx;
|
||||
}
|
||||
|
||||
#define gpr(idx) cpu.gpr[check_reg_idx(idx)]
|
||||
|
||||
static inline const char* reg_name(int idx) {
|
||||
extern const char* regs[];
|
||||
return regs[check_reg_idx(idx)];
|
||||
}
|
||||
|
||||
#endif
|
16
nemu/src/isa/loongarch32r/logo.c
Normal file
16
nemu/src/isa/loongarch32r/logo.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
unsigned char isa_logo[] = "loongarch32r manual";
|
31
nemu/src/isa/loongarch32r/reg.c
Normal file
31
nemu/src/isa/loongarch32r/reg.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include "local-include/reg.h"
|
||||
|
||||
const char *regs[] = {
|
||||
"$0", "ra", "tp", "sp", "a0", "a1", "a2", "a3",
|
||||
"a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
|
||||
"t4", "t5", "t6", "t7", "t8", "rs", "fp", "s0",
|
||||
"s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8"
|
||||
};
|
||||
|
||||
void isa_reg_display() {
|
||||
}
|
||||
|
||||
word_t isa_reg_str2val(const char *s, bool *success) {
|
||||
return 0;
|
||||
}
|
28
nemu/src/isa/loongarch32r/system/intr.c
Normal file
28
nemu/src/isa/loongarch32r/system/intr.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
|
||||
word_t isa_raise_intr(word_t NO, vaddr_t epc) {
|
||||
/* TODO: Trigger an interrupt/exception with ``NO''.
|
||||
* Then return the address of the interrupt/exception vector.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
word_t isa_query_intr() {
|
||||
return INTR_EMPTY;
|
||||
}
|
22
nemu/src/isa/loongarch32r/system/mmu.c
Normal file
22
nemu/src/isa/loongarch32r/system/mmu.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <memory/paddr.h>
|
||||
#include <memory/vaddr.h>
|
||||
|
||||
paddr_t isa_mmu_translate(vaddr_t vaddr, int len, int type) {
|
||||
return MEM_RET_FAIL;
|
||||
}
|
25
nemu/src/isa/mips32/difftest/dut.c
Normal file
25
nemu/src/isa/mips32/difftest/dut.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <cpu/difftest.h>
|
||||
#include "../local-include/reg.h"
|
||||
|
||||
bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void isa_difftest_attach() {
|
||||
}
|
36
nemu/src/isa/mips32/include/isa-def.h
Normal file
36
nemu/src/isa/mips32/include/isa-def.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __ISA_MIPS32_H__
|
||||
#define __ISA_MIPS32_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
typedef struct {
|
||||
word_t gpr[32];
|
||||
word_t pad[5];
|
||||
vaddr_t pc;
|
||||
} mips32_CPU_state;
|
||||
|
||||
// decode
|
||||
typedef struct {
|
||||
union {
|
||||
uint32_t val;
|
||||
} inst;
|
||||
} mips32_ISADecodeInfo;
|
||||
|
||||
#define isa_mmu_check(vaddr, len, type) (MMU_DIRECT)
|
||||
|
||||
#endif
|
42
nemu/src/isa/mips32/init.c
Normal file
42
nemu/src/isa/mips32/init.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <memory/paddr.h>
|
||||
|
||||
// this is not consistent with uint8_t
|
||||
// but it is ok since we do not access the array directly
|
||||
static const uint32_t img [] = {
|
||||
0x3c048000, // lui a0, 0x8000
|
||||
0xac800000, // sw zero, 0(a0)
|
||||
0x8c820000, // lw v0,0(a0)
|
||||
0x7000003f, // sdbbp (used as nemu_trap)
|
||||
};
|
||||
|
||||
static void restart() {
|
||||
/* Set the initial program counter. */
|
||||
cpu.pc = RESET_VECTOR;
|
||||
|
||||
/* The zero register is always 0. */
|
||||
cpu.gpr[0] = 0;
|
||||
}
|
||||
|
||||
void init_isa() {
|
||||
/* Load built-in image. */
|
||||
memcpy(guest_to_host(RESET_VECTOR), img, sizeof(img));
|
||||
|
||||
/* Initialize this virtual computer system. */
|
||||
restart();
|
||||
}
|
74
nemu/src/isa/mips32/inst.c
Normal file
74
nemu/src/isa/mips32/inst.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include "local-include/reg.h"
|
||||
#include <cpu/cpu.h>
|
||||
#include <cpu/ifetch.h>
|
||||
#include <cpu/decode.h>
|
||||
|
||||
#define R(i) gpr(i)
|
||||
#define Mr vaddr_read
|
||||
#define Mw vaddr_write
|
||||
|
||||
enum {
|
||||
TYPE_I, TYPE_U,
|
||||
TYPE_N, // none
|
||||
};
|
||||
|
||||
#define src1R() do { *src1 = R(rs); } while (0)
|
||||
#define src2R() do { *src2 = R(rt); } while (0)
|
||||
#define immI() do { *imm = SEXT(BITS(i, 15, 0), 16); } while(0)
|
||||
#define immU() do { *imm = BITS(i, 15, 0); } while(0)
|
||||
|
||||
static void decode_operand(Decode *s, int *rd, word_t *src1, word_t *src2, word_t *imm, int type) {
|
||||
uint32_t i = s->isa.inst.val;
|
||||
int rt = BITS(i, 20, 16);
|
||||
int rs = BITS(i, 25, 21);
|
||||
*rd = (type == TYPE_U || type == TYPE_I) ? rt : BITS(i, 15, 11);
|
||||
switch (type) {
|
||||
case TYPE_I: src1R(); immI(); break;
|
||||
case TYPE_U: src1R(); immU(); break;
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_exec(Decode *s) {
|
||||
int rd = 0;
|
||||
word_t src1 = 0, src2 = 0, imm = 0;
|
||||
s->dnpc = s->snpc;
|
||||
|
||||
#define INSTPAT_INST(s) ((s)->isa.inst.val)
|
||||
#define INSTPAT_MATCH(s, name, type, ... /* execute body */ ) { \
|
||||
decode_operand(s, &rd, &src1, &src2, &imm, concat(TYPE_, type)); \
|
||||
__VA_ARGS__ ; \
|
||||
}
|
||||
|
||||
INSTPAT_START();
|
||||
INSTPAT("001111 ????? ????? ????? ????? ??????", lui , U, R(rd) = imm << 16);
|
||||
INSTPAT("100011 ????? ????? ????? ????? ??????", lw , I, R(rd) = Mr(src1 + imm, 4));
|
||||
INSTPAT("101011 ????? ????? ????? ????? ??????", sw , I, Mw(src1 + imm, 4, R(rd)));
|
||||
|
||||
INSTPAT("011100 ????? ????? ????? ????? 111111", sdbbp , N, NEMUTRAP(s->pc, R(2))); // R(2) is $v0;
|
||||
INSTPAT("?????? ????? ????? ????? ????? ??????", inv , N, INV(s->pc));
|
||||
INSTPAT_END();
|
||||
|
||||
R(0) = 0; // reset $zero to 0
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isa_exec_once(Decode *s) {
|
||||
s->isa.inst.val = inst_fetch(&s->snpc, 4);
|
||||
return decode_exec(s);
|
||||
}
|
33
nemu/src/isa/mips32/local-include/reg.h
Normal file
33
nemu/src/isa/mips32/local-include/reg.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __MIPS32_REG_H__
|
||||
#define __MIPS32_REG_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
static inline int check_reg_idx(int idx) {
|
||||
IFDEF(CONFIG_RT_CHECK, assert(idx >= 0 && idx < 32));
|
||||
return idx;
|
||||
}
|
||||
|
||||
#define gpr(idx) cpu.gpr[check_reg_idx(idx)]
|
||||
|
||||
static inline const char* reg_name(int idx) {
|
||||
extern const char* regs[];
|
||||
return regs[check_reg_idx(idx)];
|
||||
}
|
||||
|
||||
#endif
|
78
nemu/src/isa/mips32/logo.c
Normal file
78
nemu/src/isa/mips32/logo.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
// refer to http://www.patorjk.com/software/taag/#p=display&f=Big&t=Type%20Something%20
|
||||
|
||||
/*
|
||||
_ ____ ___ __ __ _
|
||||
(_) |___ \__ \ | \/ | | |
|
||||
_ __ ___ _ _ __ ___ __) | ) | | \ / | __ _ _ __ _ _ __ _| |
|
||||
| '_ ` _ \| | '_ \/ __||__ < / / | |\/| |/ _` | '_ \| | | |/ _` | |
|
||||
| | | | | | | |_) \__ \___) / /_ | | | | (_| | | | | |_| | (_| | |
|
||||
|_| |_| |_|_| .__/|___/____/____| |_| |_|\__,_|_| |_|\__,_|\__,_|_|
|
||||
| |
|
||||
|_|
|
||||
|
||||
*/
|
||||
|
||||
unsigned char isa_logo[] = {
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x5f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x20,
|
||||
0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x20, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x5f, 0x29,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7c, 0x5f, 0x5f,
|
||||
0x5f, 0x20, 0x5c, 0x5f, 0x5f, 0x20, 0x5c, 0x20, 0x20, 0x7c, 0x20, 0x20,
|
||||
0x5c, 0x2f, 0x20, 0x20, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x20, 0x5f, 0x20,
|
||||
0x5f, 0x5f, 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x20, 0x5f, 0x20,
|
||||
0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x29,
|
||||
0x20, 0x7c, 0x20, 0x29, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x5c, 0x20, 0x20,
|
||||
0x2f, 0x20, 0x7c, 0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x20, 0x5f, 0x20, 0x5f,
|
||||
0x5f, 0x20, 0x20, 0x5f, 0x20, 0x20, 0x20, 0x5f, 0x20, 0x20, 0x5f, 0x5f,
|
||||
0x20, 0x5f, 0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x7c, 0x20, 0x27, 0x5f, 0x20,
|
||||
0x60, 0x20, 0x5f, 0x20, 0x5c, 0x7c, 0x20, 0x7c, 0x20, 0x27, 0x5f, 0x20,
|
||||
0x5c, 0x2f, 0x20, 0x5f, 0x5f, 0x7c, 0x7c, 0x5f, 0x5f, 0x20, 0x3c, 0x20,
|
||||
0x2f, 0x20, 0x2f, 0x20, 0x20, 0x7c, 0x20, 0x7c, 0x5c, 0x2f, 0x7c, 0x20,
|
||||
0x7c, 0x2f, 0x20, 0x5f, 0x60, 0x20, 0x7c, 0x20, 0x27, 0x5f, 0x20, 0x5c,
|
||||
0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x2f, 0x20, 0x5f, 0x60, 0x20,
|
||||
0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c,
|
||||
0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x5f, 0x29, 0x20, 0x5c,
|
||||
0x5f, 0x5f, 0x20, 0x5c, 0x5f, 0x5f, 0x5f, 0x29, 0x20, 0x2f, 0x20, 0x2f,
|
||||
0x5f, 0x20, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x20, 0x7c, 0x20, 0x7c, 0x20,
|
||||
0x28, 0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20,
|
||||
0x7c, 0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x28, 0x5f, 0x7c, 0x20, 0x7c, 0x20,
|
||||
0x7c, 0x0a, 0x20, 0x7c, 0x5f, 0x7c, 0x20, 0x7c, 0x5f, 0x7c, 0x20, 0x7c,
|
||||
0x5f, 0x7c, 0x5f, 0x7c, 0x20, 0x2e, 0x5f, 0x5f, 0x2f, 0x7c, 0x5f, 0x5f,
|
||||
0x5f, 0x2f, 0x5f, 0x5f, 0x5f, 0x5f, 0x2f, 0x5f, 0x5f, 0x5f, 0x5f, 0x7c,
|
||||
0x20, 0x7c, 0x5f, 0x7c, 0x20, 0x20, 0x7c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f,
|
||||
0x2c, 0x5f, 0x7c, 0x5f, 0x7c, 0x20, 0x7c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f,
|
||||
0x2c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5f, 0x7c, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x7c, 0x20, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7c,
|
||||
0x5f, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, '\0'
|
||||
};
|
31
nemu/src/isa/mips32/reg.c
Normal file
31
nemu/src/isa/mips32/reg.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include "local-include/reg.h"
|
||||
|
||||
const char *regs[] = {
|
||||
"$0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
|
||||
};
|
||||
|
||||
void isa_reg_display() {
|
||||
}
|
||||
|
||||
word_t isa_reg_str2val(const char *s, bool *success) {
|
||||
return 0;
|
||||
}
|
28
nemu/src/isa/mips32/system/intr.c
Normal file
28
nemu/src/isa/mips32/system/intr.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
|
||||
word_t isa_raise_intr(word_t NO, vaddr_t epc) {
|
||||
/* TODO: Trigger an interrupt/exception with ``NO''.
|
||||
* Then return the address of the interrupt/exception vector.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
word_t isa_query_intr() {
|
||||
return INTR_EMPTY;
|
||||
}
|
22
nemu/src/isa/mips32/system/mmu.c
Normal file
22
nemu/src/isa/mips32/system/mmu.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <memory/paddr.h>
|
||||
#include <memory/vaddr.h>
|
||||
|
||||
paddr_t isa_mmu_translate(vaddr_t vaddr, int len, int type) {
|
||||
return MEM_RET_FAIL;
|
||||
}
|
10
nemu/src/isa/riscv32/Kconfig
Normal file
10
nemu/src/isa/riscv32/Kconfig
Normal file
|
@ -0,0 +1,10 @@
|
|||
menu "ISA-dependent Options for riscv"
|
||||
|
||||
config RV64
|
||||
bool "64-bit RISC-V architecture"
|
||||
default n
|
||||
|
||||
config RVE
|
||||
bool "Use E extension"
|
||||
default n
|
||||
endmenu
|
25
nemu/src/isa/riscv32/difftest/dut.c
Normal file
25
nemu/src/isa/riscv32/difftest/dut.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <cpu/difftest.h>
|
||||
#include "../local-include/reg.h"
|
||||
|
||||
bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void isa_difftest_attach() {
|
||||
}
|
35
nemu/src/isa/riscv32/include/isa-def.h
Normal file
35
nemu/src/isa/riscv32/include/isa-def.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __ISA_RISCV_H__
|
||||
#define __ISA_RISCV_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
typedef struct {
|
||||
word_t gpr[MUXDEF(CONFIG_RVE, 16, 32)];
|
||||
vaddr_t pc;
|
||||
} MUXDEF(CONFIG_RV64, riscv64_CPU_state, riscv32_CPU_state);
|
||||
|
||||
// decode
|
||||
typedef struct {
|
||||
union {
|
||||
uint32_t val;
|
||||
} inst;
|
||||
} MUXDEF(CONFIG_RV64, riscv64_ISADecodeInfo, riscv32_ISADecodeInfo);
|
||||
|
||||
#define isa_mmu_check(vaddr, len, type) (MMU_DIRECT)
|
||||
|
||||
#endif
|
43
nemu/src/isa/riscv32/init.c
Normal file
43
nemu/src/isa/riscv32/init.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <memory/paddr.h>
|
||||
|
||||
// this is not consistent with uint8_t
|
||||
// but it is ok since we do not access the array directly
|
||||
static const uint32_t img [] = {
|
||||
0x00000297, // auipc t0,0
|
||||
0x00028823, // sb zero,16(t0)
|
||||
0x0102c503, // lbu a0,16(t0)
|
||||
0x00100073, // ebreak (used as nemu_trap)
|
||||
0xdeadbeef, // some data
|
||||
};
|
||||
|
||||
static void restart() {
|
||||
/* Set the initial program counter. */
|
||||
cpu.pc = RESET_VECTOR;
|
||||
|
||||
/* The zero register is always 0. */
|
||||
cpu.gpr[0] = 0;
|
||||
}
|
||||
|
||||
void init_isa() {
|
||||
/* Load built-in image. */
|
||||
memcpy(guest_to_host(RESET_VECTOR), img, sizeof(img));
|
||||
|
||||
/* Initialize this virtual computer system. */
|
||||
restart();
|
||||
}
|
76
nemu/src/isa/riscv32/inst.c
Normal file
76
nemu/src/isa/riscv32/inst.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include "local-include/reg.h"
|
||||
#include <cpu/cpu.h>
|
||||
#include <cpu/ifetch.h>
|
||||
#include <cpu/decode.h>
|
||||
|
||||
#define R(i) gpr(i)
|
||||
#define Mr vaddr_read
|
||||
#define Mw vaddr_write
|
||||
|
||||
enum {
|
||||
TYPE_I, TYPE_U, TYPE_S,
|
||||
TYPE_N, // none
|
||||
};
|
||||
|
||||
#define src1R() do { *src1 = R(rs1); } while (0)
|
||||
#define src2R() do { *src2 = R(rs2); } while (0)
|
||||
#define immI() do { *imm = SEXT(BITS(i, 31, 20), 12); } while(0)
|
||||
#define immU() do { *imm = SEXT(BITS(i, 31, 12), 20) << 12; } while(0)
|
||||
#define immS() do { *imm = (SEXT(BITS(i, 31, 25), 7) << 5) | BITS(i, 11, 7); } while(0)
|
||||
|
||||
static void decode_operand(Decode *s, int *rd, word_t *src1, word_t *src2, word_t *imm, int type) {
|
||||
uint32_t i = s->isa.inst.val;
|
||||
int rs1 = BITS(i, 19, 15);
|
||||
int rs2 = BITS(i, 24, 20);
|
||||
*rd = BITS(i, 11, 7);
|
||||
switch (type) {
|
||||
case TYPE_I: src1R(); immI(); break;
|
||||
case TYPE_U: immU(); break;
|
||||
case TYPE_S: src1R(); src2R(); immS(); break;
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_exec(Decode *s) {
|
||||
int rd = 0;
|
||||
word_t src1 = 0, src2 = 0, imm = 0;
|
||||
s->dnpc = s->snpc;
|
||||
|
||||
#define INSTPAT_INST(s) ((s)->isa.inst.val)
|
||||
#define INSTPAT_MATCH(s, name, type, ... /* execute body */ ) { \
|
||||
decode_operand(s, &rd, &src1, &src2, &imm, concat(TYPE_, type)); \
|
||||
__VA_ARGS__ ; \
|
||||
}
|
||||
|
||||
INSTPAT_START();
|
||||
INSTPAT("??????? ????? ????? ??? ????? 00101 11", auipc , U, R(rd) = s->pc + imm);
|
||||
INSTPAT("??????? ????? ????? 100 ????? 00000 11", lbu , I, R(rd) = Mr(src1 + imm, 1));
|
||||
INSTPAT("??????? ????? ????? 000 ????? 01000 11", sb , S, Mw(src1 + imm, 1, src2));
|
||||
|
||||
INSTPAT("0000000 00001 00000 000 00000 11100 11", ebreak , N, NEMUTRAP(s->pc, R(10))); // R(10) is $a0
|
||||
INSTPAT("??????? ????? ????? ??? ????? ????? ??", inv , N, INV(s->pc));
|
||||
INSTPAT_END();
|
||||
|
||||
R(0) = 0; // reset $zero to 0
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isa_exec_once(Decode *s) {
|
||||
s->isa.inst.val = inst_fetch(&s->snpc, 4);
|
||||
return decode_exec(s);
|
||||
}
|
33
nemu/src/isa/riscv32/local-include/reg.h
Normal file
33
nemu/src/isa/riscv32/local-include/reg.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __RISCV_REG_H__
|
||||
#define __RISCV_REG_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
static inline int check_reg_idx(int idx) {
|
||||
IFDEF(CONFIG_RT_CHECK, assert(idx >= 0 && idx < MUXDEF(CONFIG_RVE, 16, 32)));
|
||||
return idx;
|
||||
}
|
||||
|
||||
#define gpr(idx) (cpu.gpr[check_reg_idx(idx)])
|
||||
|
||||
static inline const char* reg_name(int idx) {
|
||||
extern const char* regs[];
|
||||
return regs[check_reg_idx(idx)];
|
||||
}
|
||||
|
||||
#endif
|
63
nemu/src/isa/riscv32/logo.c
Normal file
63
nemu/src/isa/riscv32/logo.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
// refer to http://www.patorjk.com/software/taag/#p=display&f=Big&t=Type%20Something%20
|
||||
|
||||
/*
|
||||
_ __ __ _
|
||||
(_) | \/ | | |
|
||||
_ __ _ ___ ___ ________ __ | \ / | __ _ _ __ _ _ __ _| |
|
||||
| '__| / __|/ __|______\ \ / / | |\/| |/ _` | '_ \| | | |/ _` | |
|
||||
| | | \__ \ (__ \ V / | | | | (_| | | | | |_| | (_| | |
|
||||
|_| |_|___/\___| \_/ |_| |_|\__,_|_| |_|\__,_|\__,_|_|
|
||||
|
||||
*/
|
||||
|
||||
unsigned char isa_logo[] = {
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x5f, 0x20,
|
||||
0x20, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x5f, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x28, 0x5f, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x7c, 0x20, 0x20, 0x5c, 0x2f, 0x20, 0x20, 0x7c, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7c, 0x20,
|
||||
0x7c, 0x0a, 0x20, 0x20, 0x5f, 0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x20, 0x5f,
|
||||
0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x5f, 0x5f, 0x20, 0x7c, 0x20,
|
||||
0x5c, 0x20, 0x20, 0x2f, 0x20, 0x7c, 0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x20,
|
||||
0x5f, 0x20, 0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x20, 0x20, 0x20, 0x5f, 0x20,
|
||||
0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x7c, 0x20,
|
||||
0x27, 0x5f, 0x5f, 0x7c, 0x20, 0x2f, 0x20, 0x5f, 0x5f, 0x7c, 0x2f, 0x20,
|
||||
0x5f, 0x5f, 0x7c, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5c, 0x20, 0x5c,
|
||||
0x20, 0x2f, 0x20, 0x2f, 0x20, 0x7c, 0x20, 0x7c, 0x5c, 0x2f, 0x7c, 0x20,
|
||||
0x7c, 0x2f, 0x20, 0x5f, 0x60, 0x20, 0x7c, 0x20, 0x27, 0x5f, 0x20, 0x5c,
|
||||
0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x2f, 0x20, 0x5f, 0x60, 0x20,
|
||||
0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x20, 0x7c, 0x20,
|
||||
0x5c, 0x5f, 0x5f, 0x20, 0x5c, 0x20, 0x28, 0x5f, 0x5f, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, 0x20, 0x56, 0x20, 0x2f, 0x20, 0x20,
|
||||
0x7c, 0x20, 0x7c, 0x20, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x28, 0x5f, 0x7c,
|
||||
0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x5f, 0x7c,
|
||||
0x20, 0x7c, 0x20, 0x28, 0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x0a, 0x20,
|
||||
0x7c, 0x5f, 0x7c, 0x20, 0x20, 0x7c, 0x5f, 0x7c, 0x5f, 0x5f, 0x5f, 0x2f,
|
||||
0x5c, 0x5f, 0x5f, 0x5f, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x5c, 0x5f, 0x2f, 0x20, 0x20, 0x20, 0x7c, 0x5f, 0x7c, 0x20, 0x20,
|
||||
0x7c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5f, 0x7c, 0x20,
|
||||
0x7c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f,
|
||||
0x2c, 0x5f, 0x7c, 0x5f, 0x7c, 0x0a, '\0' /* Termination Character is indispensable! */
|
||||
};
|
31
nemu/src/isa/riscv32/reg.c
Normal file
31
nemu/src/isa/riscv32/reg.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include "local-include/reg.h"
|
||||
|
||||
const char *regs[] = {
|
||||
"$0", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
|
||||
"s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
|
||||
"a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||
"s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"
|
||||
};
|
||||
|
||||
void isa_reg_display() {
|
||||
}
|
||||
|
||||
word_t isa_reg_str2val(const char *s, bool *success) {
|
||||
return 0;
|
||||
}
|
28
nemu/src/isa/riscv32/system/intr.c
Normal file
28
nemu/src/isa/riscv32/system/intr.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
|
||||
word_t isa_raise_intr(word_t NO, vaddr_t epc) {
|
||||
/* TODO: Trigger an interrupt/exception with ``NO''.
|
||||
* Then return the address of the interrupt/exception vector.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
word_t isa_query_intr() {
|
||||
return INTR_EMPTY;
|
||||
}
|
22
nemu/src/isa/riscv32/system/mmu.c
Normal file
22
nemu/src/isa/riscv32/system/mmu.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <memory/vaddr.h>
|
||||
#include <memory/paddr.h>
|
||||
|
||||
paddr_t isa_mmu_translate(vaddr_t vaddr, int len, int type) {
|
||||
return MEM_RET_FAIL;
|
||||
}
|
34
nemu/src/memory/Kconfig
Normal file
34
nemu/src/memory/Kconfig
Normal file
|
@ -0,0 +1,34 @@
|
|||
menu "Memory Configuration"
|
||||
|
||||
config MBASE
|
||||
hex "Memory base address"
|
||||
default 0x0 if ISA_x86
|
||||
default 0x80000000
|
||||
|
||||
config MSIZE
|
||||
hex "Memory size"
|
||||
default 0x8000000
|
||||
|
||||
config PC_RESET_OFFSET
|
||||
hex "Offset of reset vector from the base of memory"
|
||||
default 0x100000 if ISA_x86
|
||||
default 0
|
||||
|
||||
choice
|
||||
prompt "Physical memory definition"
|
||||
default PMEM_GARRAY
|
||||
config PMEM_MALLOC
|
||||
bool "Using malloc()"
|
||||
config PMEM_GARRAY
|
||||
depends on !TARGET_AM
|
||||
bool "Using global array"
|
||||
endchoice
|
||||
|
||||
config MEM_RANDOM
|
||||
depends on MODE_SYSTEM && !DIFFTEST && !TARGET_AM
|
||||
bool "Initialize the memory with random values"
|
||||
default y
|
||||
help
|
||||
This may help to find undefined behaviors.
|
||||
|
||||
endmenu #MEMORY
|
64
nemu/src/memory/paddr.c
Normal file
64
nemu/src/memory/paddr.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <memory/host.h>
|
||||
#include <memory/paddr.h>
|
||||
#include <device/mmio.h>
|
||||
#include <isa.h>
|
||||
|
||||
#if defined(CONFIG_PMEM_MALLOC)
|
||||
static uint8_t *pmem = NULL;
|
||||
#else // CONFIG_PMEM_GARRAY
|
||||
static uint8_t pmem[CONFIG_MSIZE] PG_ALIGN = {};
|
||||
#endif
|
||||
|
||||
uint8_t* guest_to_host(paddr_t paddr) { return pmem + paddr - CONFIG_MBASE; }
|
||||
paddr_t host_to_guest(uint8_t *haddr) { return haddr - pmem + CONFIG_MBASE; }
|
||||
|
||||
static word_t pmem_read(paddr_t addr, int len) {
|
||||
word_t ret = host_read(guest_to_host(addr), len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pmem_write(paddr_t addr, int len, word_t data) {
|
||||
host_write(guest_to_host(addr), len, data);
|
||||
}
|
||||
|
||||
static void out_of_bound(paddr_t addr) {
|
||||
panic("address = " FMT_PADDR " is out of bound of pmem [" FMT_PADDR ", " FMT_PADDR "] at pc = " FMT_WORD,
|
||||
addr, PMEM_LEFT, PMEM_RIGHT, cpu.pc);
|
||||
}
|
||||
|
||||
void init_mem() {
|
||||
#if defined(CONFIG_PMEM_MALLOC)
|
||||
pmem = malloc(CONFIG_MSIZE);
|
||||
assert(pmem);
|
||||
#endif
|
||||
IFDEF(CONFIG_MEM_RANDOM, memset(pmem, rand(), CONFIG_MSIZE));
|
||||
Log("physical memory area [" FMT_PADDR ", " FMT_PADDR "]", PMEM_LEFT, PMEM_RIGHT);
|
||||
}
|
||||
|
||||
word_t paddr_read(paddr_t addr, int len) {
|
||||
if (likely(in_pmem(addr))) return pmem_read(addr, len);
|
||||
IFDEF(CONFIG_DEVICE, return mmio_read(addr, len));
|
||||
out_of_bound(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void paddr_write(paddr_t addr, int len, word_t data) {
|
||||
if (likely(in_pmem(addr))) { pmem_write(addr, len, data); return; }
|
||||
IFDEF(CONFIG_DEVICE, mmio_write(addr, len, data); return);
|
||||
out_of_bound(addr);
|
||||
}
|
29
nemu/src/memory/vaddr.c
Normal file
29
nemu/src/memory/vaddr.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <memory/paddr.h>
|
||||
|
||||
word_t vaddr_ifetch(vaddr_t addr, int len) {
|
||||
return paddr_read(addr, len);
|
||||
}
|
||||
|
||||
word_t vaddr_read(vaddr_t addr, int len) {
|
||||
return paddr_read(addr, len);
|
||||
}
|
||||
|
||||
void vaddr_write(vaddr_t addr, int len, word_t data) {
|
||||
paddr_write(addr, len, data);
|
||||
}
|
162
nemu/src/monitor/monitor.c
Normal file
162
nemu/src/monitor/monitor.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <memory/paddr.h>
|
||||
|
||||
void init_rand();
|
||||
void init_log(const char *log_file);
|
||||
void init_mem();
|
||||
void init_difftest(char *ref_so_file, long img_size, int port);
|
||||
void init_device();
|
||||
void init_sdb();
|
||||
void init_disasm(const char *triple);
|
||||
|
||||
static void welcome() {
|
||||
Log("Trace: %s", MUXDEF(CONFIG_TRACE, ANSI_FMT("ON", ANSI_FG_GREEN), ANSI_FMT("OFF", ANSI_FG_RED)));
|
||||
IFDEF(CONFIG_TRACE, Log("If trace is enabled, a log file will be generated "
|
||||
"to record the trace. This may lead to a large log file. "
|
||||
"If it is not necessary, you can disable it in menuconfig"));
|
||||
Log("Build time: %s, %s", __TIME__, __DATE__);
|
||||
printf("Welcome to %s-NEMU!\n", ANSI_FMT(str(__GUEST_ISA__), ANSI_FG_YELLOW ANSI_BG_RED));
|
||||
printf("For help, type \"help\"\n");
|
||||
Log("Exercise: Please remove me in the source code and compile NEMU again.");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_TARGET_AM
|
||||
#include <getopt.h>
|
||||
|
||||
void sdb_set_batch_mode();
|
||||
|
||||
static char *log_file = NULL;
|
||||
static char *diff_so_file = NULL;
|
||||
static char *img_file = NULL;
|
||||
static int difftest_port = 1234;
|
||||
|
||||
static long load_img() {
|
||||
if (img_file == NULL) {
|
||||
Log("No image is given. Use the default build-in image.");
|
||||
return 4096; // built-in image size
|
||||
}
|
||||
|
||||
FILE *fp = fopen(img_file, "rb");
|
||||
Assert(fp, "Can not open '%s'", img_file);
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long size = ftell(fp);
|
||||
|
||||
Log("The image is %s, size = %ld", img_file, size);
|
||||
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
int ret = fread(guest_to_host(RESET_VECTOR), size, 1, fp);
|
||||
assert(ret == 1);
|
||||
|
||||
fclose(fp);
|
||||
return size;
|
||||
}
|
||||
|
||||
static int parse_args(int argc, char *argv[]) {
|
||||
const struct option table[] = {
|
||||
{"batch" , no_argument , NULL, 'b'},
|
||||
{"log" , required_argument, NULL, 'l'},
|
||||
{"diff" , required_argument, NULL, 'd'},
|
||||
{"port" , required_argument, NULL, 'p'},
|
||||
{"help" , no_argument , NULL, 'h'},
|
||||
{0 , 0 , NULL, 0 },
|
||||
};
|
||||
int o;
|
||||
while ( (o = getopt_long(argc, argv, "-bhl:d:p:", table, NULL)) != -1) {
|
||||
switch (o) {
|
||||
case 'b': sdb_set_batch_mode(); break;
|
||||
case 'p': sscanf(optarg, "%d", &difftest_port); break;
|
||||
case 'l': log_file = optarg; break;
|
||||
case 'd': diff_so_file = optarg; break;
|
||||
case 1: img_file = optarg; return 0;
|
||||
default:
|
||||
printf("Usage: %s [OPTION...] IMAGE [args]\n\n", argv[0]);
|
||||
printf("\t-b,--batch run with batch mode\n");
|
||||
printf("\t-l,--log=FILE output log to FILE\n");
|
||||
printf("\t-d,--diff=REF_SO run DiffTest with reference REF_SO\n");
|
||||
printf("\t-p,--port=PORT run DiffTest with port PORT\n");
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_monitor(int argc, char *argv[]) {
|
||||
/* Perform some global initialization. */
|
||||
|
||||
/* Parse arguments. */
|
||||
parse_args(argc, argv);
|
||||
|
||||
/* Set random seed. */
|
||||
init_rand();
|
||||
|
||||
/* Open the log file. */
|
||||
init_log(log_file);
|
||||
|
||||
/* Initialize memory. */
|
||||
init_mem();
|
||||
|
||||
/* Initialize devices. */
|
||||
IFDEF(CONFIG_DEVICE, init_device());
|
||||
|
||||
/* Perform ISA dependent initialization. */
|
||||
init_isa();
|
||||
|
||||
/* Load the image to memory. This will overwrite the built-in image. */
|
||||
long img_size = load_img();
|
||||
|
||||
/* Initialize differential testing. */
|
||||
init_difftest(diff_so_file, img_size, difftest_port);
|
||||
|
||||
/* Initialize the simple debugger. */
|
||||
init_sdb();
|
||||
|
||||
#ifndef CONFIG_ISA_loongarch32r
|
||||
IFDEF(CONFIG_ITRACE, init_disasm(
|
||||
MUXDEF(CONFIG_ISA_x86, "i686",
|
||||
MUXDEF(CONFIG_ISA_mips32, "mipsel",
|
||||
MUXDEF(CONFIG_ISA_riscv,
|
||||
MUXDEF(CONFIG_RV64, "riscv64",
|
||||
"riscv32"),
|
||||
"bad"))) "-pc-linux-gnu"
|
||||
));
|
||||
#endif
|
||||
|
||||
/* Display welcome message. */
|
||||
welcome();
|
||||
}
|
||||
#else // CONFIG_TARGET_AM
|
||||
static long load_img() {
|
||||
extern char bin_start, bin_end;
|
||||
size_t size = &bin_end - &bin_start;
|
||||
Log("img size = %ld", size);
|
||||
memcpy(guest_to_host(RESET_VECTOR), &bin_start, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void am_init_monitor() {
|
||||
init_rand();
|
||||
init_mem();
|
||||
init_isa();
|
||||
load_img();
|
||||
IFDEF(CONFIG_DEVICE, init_device());
|
||||
welcome();
|
||||
}
|
||||
#endif
|
125
nemu/src/monitor/sdb/expr.c
Normal file
125
nemu/src/monitor/sdb/expr.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
|
||||
/* We use the POSIX regex functions to process regular expressions.
|
||||
* Type 'man regex' for more information about POSIX regex functions.
|
||||
*/
|
||||
#include <regex.h>
|
||||
|
||||
enum {
|
||||
TK_NOTYPE = 256, TK_EQ,
|
||||
|
||||
/* TODO: Add more token types */
|
||||
|
||||
};
|
||||
|
||||
static struct rule {
|
||||
const char *regex;
|
||||
int token_type;
|
||||
} rules[] = {
|
||||
|
||||
/* TODO: Add more rules.
|
||||
* Pay attention to the precedence level of different rules.
|
||||
*/
|
||||
|
||||
{" +", TK_NOTYPE}, // spaces
|
||||
{"\\+", '+'}, // plus
|
||||
{"==", TK_EQ}, // equal
|
||||
};
|
||||
|
||||
#define NR_REGEX ARRLEN(rules)
|
||||
|
||||
static regex_t re[NR_REGEX] = {};
|
||||
|
||||
/* Rules are used for many times.
|
||||
* Therefore we compile them only once before any usage.
|
||||
*/
|
||||
void init_regex() {
|
||||
int i;
|
||||
char error_msg[128];
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < NR_REGEX; i ++) {
|
||||
ret = regcomp(&re[i], rules[i].regex, REG_EXTENDED);
|
||||
if (ret != 0) {
|
||||
regerror(ret, &re[i], error_msg, 128);
|
||||
panic("regex compilation failed: %s\n%s", error_msg, rules[i].regex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct token {
|
||||
int type;
|
||||
char str[32];
|
||||
} Token;
|
||||
|
||||
static Token tokens[32] __attribute__((used)) = {};
|
||||
static int nr_token __attribute__((used)) = 0;
|
||||
|
||||
static bool make_token(char *e) {
|
||||
int position = 0;
|
||||
int i;
|
||||
regmatch_t pmatch;
|
||||
|
||||
nr_token = 0;
|
||||
|
||||
while (e[position] != '\0') {
|
||||
/* Try all rules one by one. */
|
||||
for (i = 0; i < NR_REGEX; i ++) {
|
||||
if (regexec(&re[i], e + position, 1, &pmatch, 0) == 0 && pmatch.rm_so == 0) {
|
||||
char *substr_start = e + position;
|
||||
int substr_len = pmatch.rm_eo;
|
||||
|
||||
Log("match rules[%d] = \"%s\" at position %d with len %d: %.*s",
|
||||
i, rules[i].regex, position, substr_len, substr_len, substr_start);
|
||||
|
||||
position += substr_len;
|
||||
|
||||
/* TODO: Now a new token is recognized with rules[i]. Add codes
|
||||
* to record the token in the array `tokens'. For certain types
|
||||
* of tokens, some extra actions should be performed.
|
||||
*/
|
||||
|
||||
switch (rules[i].token_type) {
|
||||
default: TODO();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == NR_REGEX) {
|
||||
printf("no match at position %d\n%s\n%*.s^\n", position, e, position, "");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
word_t expr(char *e, bool *success) {
|
||||
if (!make_token(e)) {
|
||||
*success = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: Insert codes to evaluate the expression. */
|
||||
TODO();
|
||||
|
||||
return 0;
|
||||
}
|
143
nemu/src/monitor/sdb/sdb.c
Normal file
143
nemu/src/monitor/sdb/sdb.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include "sdb.h"
|
||||
|
||||
static int is_batch_mode = false;
|
||||
|
||||
void init_regex();
|
||||
void init_wp_pool();
|
||||
|
||||
/* We use the `readline' library to provide more flexibility to read from stdin. */
|
||||
static char* rl_gets() {
|
||||
static char *line_read = NULL;
|
||||
|
||||
if (line_read) {
|
||||
free(line_read);
|
||||
line_read = NULL;
|
||||
}
|
||||
|
||||
line_read = readline("(nemu) ");
|
||||
|
||||
if (line_read && *line_read) {
|
||||
add_history(line_read);
|
||||
}
|
||||
|
||||
return line_read;
|
||||
}
|
||||
|
||||
static int cmd_c(char *args) {
|
||||
cpu_exec(-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cmd_q(char *args) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_help(char *args);
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
const char *description;
|
||||
int (*handler) (char *);
|
||||
} cmd_table [] = {
|
||||
{ "help", "Display information about all supported commands", cmd_help },
|
||||
{ "c", "Continue the execution of the program", cmd_c },
|
||||
{ "q", "Exit NEMU", cmd_q },
|
||||
|
||||
/* TODO: Add more commands */
|
||||
|
||||
};
|
||||
|
||||
#define NR_CMD ARRLEN(cmd_table)
|
||||
|
||||
static int cmd_help(char *args) {
|
||||
/* extract the first argument */
|
||||
char *arg = strtok(NULL, " ");
|
||||
int i;
|
||||
|
||||
if (arg == NULL) {
|
||||
/* no argument given */
|
||||
for (i = 0; i < NR_CMD; i ++) {
|
||||
printf("%s - %s\n", cmd_table[i].name, cmd_table[i].description);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < NR_CMD; i ++) {
|
||||
if (strcmp(arg, cmd_table[i].name) == 0) {
|
||||
printf("%s - %s\n", cmd_table[i].name, cmd_table[i].description);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
printf("Unknown command '%s'\n", arg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sdb_set_batch_mode() {
|
||||
is_batch_mode = true;
|
||||
}
|
||||
|
||||
void sdb_mainloop() {
|
||||
if (is_batch_mode) {
|
||||
cmd_c(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
for (char *str; (str = rl_gets()) != NULL; ) {
|
||||
char *str_end = str + strlen(str);
|
||||
|
||||
/* extract the first token as the command */
|
||||
char *cmd = strtok(str, " ");
|
||||
if (cmd == NULL) { continue; }
|
||||
|
||||
/* treat the remaining string as the arguments,
|
||||
* which may need further parsing
|
||||
*/
|
||||
char *args = cmd + strlen(cmd) + 1;
|
||||
if (args >= str_end) {
|
||||
args = NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEVICE
|
||||
extern void sdl_clear_event_queue();
|
||||
sdl_clear_event_queue();
|
||||
#endif
|
||||
|
||||
int i;
|
||||
for (i = 0; i < NR_CMD; i ++) {
|
||||
if (strcmp(cmd, cmd_table[i].name) == 0) {
|
||||
if (cmd_table[i].handler(args) < 0) { return; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == NR_CMD) { printf("Unknown command '%s'\n", cmd); }
|
||||
}
|
||||
}
|
||||
|
||||
void init_sdb() {
|
||||
/* Compile the regular expressions. */
|
||||
init_regex();
|
||||
|
||||
/* Initialize the watchpoint pool. */
|
||||
init_wp_pool();
|
||||
}
|
23
nemu/src/monitor/sdb/sdb.h
Normal file
23
nemu/src/monitor/sdb/sdb.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __SDB_H__
|
||||
#define __SDB_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
word_t expr(char *e, bool *success);
|
||||
|
||||
#endif
|
43
nemu/src/monitor/sdb/watchpoint.c
Normal file
43
nemu/src/monitor/sdb/watchpoint.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include "sdb.h"
|
||||
|
||||
#define NR_WP 32
|
||||
|
||||
typedef struct watchpoint {
|
||||
int NO;
|
||||
struct watchpoint *next;
|
||||
|
||||
/* TODO: Add more members if necessary */
|
||||
|
||||
} WP;
|
||||
|
||||
static WP wp_pool[NR_WP] = {};
|
||||
static WP *head = NULL, *free_ = NULL;
|
||||
|
||||
void init_wp_pool() {
|
||||
int i;
|
||||
for (i = 0; i < NR_WP; i ++) {
|
||||
wp_pool[i].NO = i;
|
||||
wp_pool[i].next = (i == NR_WP - 1 ? NULL : &wp_pool[i + 1]);
|
||||
}
|
||||
|
||||
head = NULL;
|
||||
free_ = wp_pool;
|
||||
}
|
||||
|
||||
/* TODO: Implement the functionality of watchpoint */
|
||||
|
35
nemu/src/nemu-main.c
Normal file
35
nemu/src/nemu-main.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
void init_monitor(int, char *[]);
|
||||
void am_init_monitor();
|
||||
void engine_start();
|
||||
int is_exit_status_bad();
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
/* Initialize the monitor. */
|
||||
#ifdef CONFIG_TARGET_AM
|
||||
am_init_monitor();
|
||||
#else
|
||||
init_monitor(argc, argv);
|
||||
#endif
|
||||
|
||||
/* Start engine. */
|
||||
engine_start();
|
||||
|
||||
return is_exit_status_bad();
|
||||
}
|
109
nemu/src/utils/disasm.cc
Normal file
109
nemu/src/utils/disasm.cc
Normal file
|
@ -0,0 +1,109 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
#if LLVM_VERSION_MAJOR >= 14
|
||||
#include "llvm/MC/TargetRegistry.h"
|
||||
#if LLVM_VERSION_MAJOR >= 15
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#endif
|
||||
#else
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#endif
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#if LLVM_VERSION_MAJOR < 11
|
||||
#error Please use LLVM with major version >= 11
|
||||
#endif
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static llvm::MCDisassembler *gDisassembler = nullptr;
|
||||
static llvm::MCSubtargetInfo *gSTI = nullptr;
|
||||
static llvm::MCInstPrinter *gIP = nullptr;
|
||||
|
||||
extern "C" void init_disasm(const char *triple) {
|
||||
llvm::InitializeAllTargetInfos();
|
||||
llvm::InitializeAllTargetMCs();
|
||||
llvm::InitializeAllAsmParsers();
|
||||
llvm::InitializeAllDisassemblers();
|
||||
|
||||
std::string errstr;
|
||||
std::string gTriple(triple);
|
||||
|
||||
llvm::MCInstrInfo *gMII = nullptr;
|
||||
llvm::MCRegisterInfo *gMRI = nullptr;
|
||||
auto target = llvm::TargetRegistry::lookupTarget(gTriple, errstr);
|
||||
if (!target) {
|
||||
llvm::errs() << "Can't find target for " << gTriple << ": " << errstr << "\n";
|
||||
assert(0);
|
||||
}
|
||||
|
||||
MCTargetOptions MCOptions;
|
||||
gSTI = target->createMCSubtargetInfo(gTriple, "", "");
|
||||
std::string isa = target->getName();
|
||||
if (isa == "riscv32" || isa == "riscv64") {
|
||||
gSTI->ApplyFeatureFlag("+m");
|
||||
gSTI->ApplyFeatureFlag("+a");
|
||||
gSTI->ApplyFeatureFlag("+c");
|
||||
gSTI->ApplyFeatureFlag("+f");
|
||||
gSTI->ApplyFeatureFlag("+d");
|
||||
}
|
||||
gMII = target->createMCInstrInfo();
|
||||
gMRI = target->createMCRegInfo(gTriple);
|
||||
auto AsmInfo = target->createMCAsmInfo(*gMRI, gTriple, MCOptions);
|
||||
#if LLVM_VERSION_MAJOR >= 13
|
||||
auto llvmTripleTwine = Twine(triple);
|
||||
auto llvmtriple = llvm::Triple(llvmTripleTwine);
|
||||
auto Ctx = new llvm::MCContext(llvmtriple,AsmInfo, gMRI, nullptr);
|
||||
#else
|
||||
auto Ctx = new llvm::MCContext(AsmInfo, gMRI, nullptr);
|
||||
#endif
|
||||
gDisassembler = target->createMCDisassembler(*gSTI, *Ctx);
|
||||
gIP = target->createMCInstPrinter(llvm::Triple(gTriple),
|
||||
AsmInfo->getAssemblerDialect(), *AsmInfo, *gMII, *gMRI);
|
||||
gIP->setPrintImmHex(true);
|
||||
gIP->setPrintBranchImmAsAddress(true);
|
||||
if (isa == "riscv32" || isa == "riscv64")
|
||||
gIP->applyTargetSpecificCLOption("no-aliases");
|
||||
}
|
||||
|
||||
extern "C" void disassemble(char *str, int size, uint64_t pc, uint8_t *code, int nbyte) {
|
||||
MCInst inst;
|
||||
llvm::ArrayRef<uint8_t> arr(code, nbyte);
|
||||
uint64_t dummy_size = 0;
|
||||
gDisassembler->getInstruction(inst, dummy_size, arr, pc, llvm::nulls());
|
||||
|
||||
std::string s;
|
||||
raw_string_ostream os(s);
|
||||
gIP->printInst(&inst, pc, "", *gSTI, os);
|
||||
|
||||
int skip = s.find_first_not_of('\t');
|
||||
const char *p = s.c_str() + skip;
|
||||
assert((int)s.length() - skip < size);
|
||||
strcpy(str, p);
|
||||
}
|
20
nemu/src/utils/filelist.mk
Normal file
20
nemu/src/utils/filelist.mk
Normal file
|
@ -0,0 +1,20 @@
|
|||
#***************************************************************************************
|
||||
# Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
#
|
||||
# NEMU is licensed under Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
# See the Mulan PSL v2 for more details.
|
||||
#**************************************************************************************/
|
||||
|
||||
ifneq ($(CONFIG_ITRACE)$(CONFIG_IQUEUE),)
|
||||
CXXSRC = src/utils/disasm.cc
|
||||
CXXFLAGS += $(shell llvm-config --cxxflags) -fPIE
|
||||
LIBS += $(shell llvm-config --libs)
|
||||
endif
|
37
nemu/src/utils/log.c
Normal file
37
nemu/src/utils/log.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
extern uint64_t g_nr_guest_inst;
|
||||
|
||||
#ifndef CONFIG_TARGET_AM
|
||||
FILE *log_fp = NULL;
|
||||
|
||||
void init_log(const char *log_file) {
|
||||
log_fp = stdout;
|
||||
if (log_file != NULL) {
|
||||
FILE *fp = fopen(log_file, "w");
|
||||
Assert(fp, "Can not open '%s'", log_file);
|
||||
log_fp = fp;
|
||||
}
|
||||
Log("Log is written to %s", log_file ? log_file : "stdout");
|
||||
}
|
||||
|
||||
bool log_enable() {
|
||||
return MUXDEF(CONFIG_TRACE, (g_nr_guest_inst >= CONFIG_TRACE_START) &&
|
||||
(g_nr_guest_inst <= CONFIG_TRACE_END), false);
|
||||
}
|
||||
#endif
|
24
nemu/src/utils/state.c
Normal file
24
nemu/src/utils/state.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <utils.h>
|
||||
|
||||
NEMUState nemu_state = { .state = NEMU_STOP };
|
||||
|
||||
int is_exit_status_bad() {
|
||||
int good = (nemu_state.state == NEMU_END && nemu_state.halt_ret == 0) ||
|
||||
(nemu_state.state == NEMU_QUIT);
|
||||
return !good;
|
||||
}
|
49
nemu/src/utils/timer.c
Normal file
49
nemu/src/utils/timer.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <common.h>
|
||||
#include MUXDEF(CONFIG_TIMER_GETTIMEOFDAY, <sys/time.h>, <time.h>)
|
||||
|
||||
IFDEF(CONFIG_TIMER_CLOCK_GETTIME,
|
||||
static_assert(CLOCKS_PER_SEC == 1000000, "CLOCKS_PER_SEC != 1000000"));
|
||||
IFDEF(CONFIG_TIMER_CLOCK_GETTIME,
|
||||
static_assert(sizeof(clock_t) == 8, "sizeof(clock_t) != 8"));
|
||||
|
||||
static uint64_t boot_time = 0;
|
||||
|
||||
static uint64_t get_time_internal() {
|
||||
#if defined(CONFIG_TARGET_AM)
|
||||
uint64_t us = io_read(AM_TIMER_UPTIME).us;
|
||||
#elif defined(CONFIG_TIMER_GETTIMEOFDAY)
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
uint64_t us = now.tv_sec * 1000000 + now.tv_usec;
|
||||
#else
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
|
||||
uint64_t us = now.tv_sec * 1000000 + now.tv_nsec / 1000;
|
||||
#endif
|
||||
return us;
|
||||
}
|
||||
|
||||
uint64_t get_time() {
|
||||
if (boot_time == 0) boot_time = get_time_internal();
|
||||
uint64_t now = get_time_internal();
|
||||
return now - boot_time;
|
||||
}
|
||||
|
||||
void init_rand() {
|
||||
srand(get_time_internal());
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue