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
49
nemu/include/common.h
Normal file
49
nemu/include/common.h
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.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __COMMON_H__
|
||||
#define __COMMON_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <generated/autoconf.h>
|
||||
#include <macro.h>
|
||||
|
||||
#ifdef CONFIG_TARGET_AM
|
||||
#include <klib.h>
|
||||
#else
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if CONFIG_MBASE + CONFIG_MSIZE > 0x100000000ul
|
||||
#define PMEM64 1
|
||||
#endif
|
||||
|
||||
typedef MUXDEF(CONFIG_ISA64, uint64_t, uint32_t) word_t;
|
||||
typedef MUXDEF(CONFIG_ISA64, int64_t, int32_t) sword_t;
|
||||
#define FMT_WORD MUXDEF(CONFIG_ISA64, "0x%016" PRIx64, "0x%08" PRIx32)
|
||||
|
||||
typedef word_t vaddr_t;
|
||||
typedef MUXDEF(PMEM64, uint64_t, uint32_t) paddr_t;
|
||||
#define FMT_PADDR MUXDEF(PMEM64, "0x%016" PRIx64, "0x%08" PRIx32)
|
||||
typedef uint16_t ioaddr_t;
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#endif
|
29
nemu/include/cpu/cpu.h
Normal file
29
nemu/include/cpu/cpu.h
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.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __CPU_CPU_H__
|
||||
#define __CPU_CPU_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
void cpu_exec(uint64_t n);
|
||||
|
||||
void set_nemu_state(int state, vaddr_t pc, int halt_ret);
|
||||
void invalid_inst(vaddr_t thispc);
|
||||
|
||||
#define NEMUTRAP(thispc, code) set_nemu_state(NEMU_END, thispc, code)
|
||||
#define INV(thispc) invalid_inst(thispc)
|
||||
|
||||
#endif
|
102
nemu/include/cpu/decode.h
Normal file
102
nemu/include/cpu/decode.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/***************************************************************************************
|
||||
* 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 __CPU_DECODE_H__
|
||||
#define __CPU_DECODE_H__
|
||||
|
||||
#include <isa.h>
|
||||
|
||||
typedef struct Decode {
|
||||
vaddr_t pc;
|
||||
vaddr_t snpc; // static next pc
|
||||
vaddr_t dnpc; // dynamic next pc
|
||||
ISADecodeInfo isa;
|
||||
IFDEF(CONFIG_ITRACE, char logbuf[128]);
|
||||
} Decode;
|
||||
|
||||
// --- pattern matching mechanism ---
|
||||
__attribute__((always_inline))
|
||||
static inline void pattern_decode(const char *str, int len,
|
||||
uint64_t *key, uint64_t *mask, uint64_t *shift) {
|
||||
uint64_t __key = 0, __mask = 0, __shift = 0;
|
||||
#define macro(i) \
|
||||
if ((i) >= len) goto finish; \
|
||||
else { \
|
||||
char c = str[i]; \
|
||||
if (c != ' ') { \
|
||||
Assert(c == '0' || c == '1' || c == '?', \
|
||||
"invalid character '%c' in pattern string", c); \
|
||||
__key = (__key << 1) | (c == '1' ? 1 : 0); \
|
||||
__mask = (__mask << 1) | (c == '?' ? 0 : 1); \
|
||||
__shift = (c == '?' ? __shift + 1 : 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define macro2(i) macro(i); macro((i) + 1)
|
||||
#define macro4(i) macro2(i); macro2((i) + 2)
|
||||
#define macro8(i) macro4(i); macro4((i) + 4)
|
||||
#define macro16(i) macro8(i); macro8((i) + 8)
|
||||
#define macro32(i) macro16(i); macro16((i) + 16)
|
||||
#define macro64(i) macro32(i); macro32((i) + 32)
|
||||
macro64(0);
|
||||
panic("pattern too long");
|
||||
#undef macro
|
||||
finish:
|
||||
*key = __key >> __shift;
|
||||
*mask = __mask >> __shift;
|
||||
*shift = __shift;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void pattern_decode_hex(const char *str, int len,
|
||||
uint64_t *key, uint64_t *mask, uint64_t *shift) {
|
||||
uint64_t __key = 0, __mask = 0, __shift = 0;
|
||||
#define macro(i) \
|
||||
if ((i) >= len) goto finish; \
|
||||
else { \
|
||||
char c = str[i]; \
|
||||
if (c != ' ') { \
|
||||
Assert((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || c == '?', \
|
||||
"invalid character '%c' in pattern string", c); \
|
||||
__key = (__key << 4) | (c == '?' ? 0 : (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10); \
|
||||
__mask = (__mask << 4) | (c == '?' ? 0 : 0xf); \
|
||||
__shift = (c == '?' ? __shift + 4 : 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
macro16(0);
|
||||
panic("pattern too long");
|
||||
#undef macro
|
||||
finish:
|
||||
*key = __key >> __shift;
|
||||
*mask = __mask >> __shift;
|
||||
*shift = __shift;
|
||||
}
|
||||
|
||||
|
||||
// --- pattern matching wrappers for decode ---
|
||||
#define INSTPAT(pattern, ...) do { \
|
||||
uint64_t key, mask, shift; \
|
||||
pattern_decode(pattern, STRLEN(pattern), &key, &mask, &shift); \
|
||||
if ((((uint64_t)INSTPAT_INST(s) >> shift) & mask) == key) { \
|
||||
INSTPAT_MATCH(s, ##__VA_ARGS__); \
|
||||
goto *(__instpat_end); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define INSTPAT_START(name) { const void ** __instpat_end = &&concat(__instpat_end_, name);
|
||||
#define INSTPAT_END(name) concat(__instpat_end_, name): ; }
|
||||
|
||||
#endif
|
53
nemu/include/cpu/difftest.h
Normal file
53
nemu/include/cpu/difftest.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/***************************************************************************************
|
||||
* 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 __CPU_DIFFTEST_H__
|
||||
#define __CPU_DIFFTEST_H__
|
||||
|
||||
#include <common.h>
|
||||
#include <difftest-def.h>
|
||||
|
||||
#ifdef CONFIG_DIFFTEST
|
||||
void difftest_skip_ref();
|
||||
void difftest_skip_dut(int nr_ref, int nr_dut);
|
||||
void difftest_set_patch(void (*fn)(void *arg), void *arg);
|
||||
void difftest_step(vaddr_t pc, vaddr_t npc);
|
||||
void difftest_detach();
|
||||
void difftest_attach();
|
||||
#else
|
||||
static inline void difftest_skip_ref() {}
|
||||
static inline void difftest_skip_dut(int nr_ref, int nr_dut) {}
|
||||
static inline void difftest_set_patch(void (*fn)(void *arg), void *arg) {}
|
||||
static inline void difftest_step(vaddr_t pc, vaddr_t npc) {}
|
||||
static inline void difftest_detach() {}
|
||||
static inline void difftest_attach() {}
|
||||
#endif
|
||||
|
||||
extern void (*ref_difftest_memcpy)(paddr_t addr, void *buf, size_t n, bool direction);
|
||||
extern void (*ref_difftest_regcpy)(void *dut, bool direction);
|
||||
extern void (*ref_difftest_exec)(uint64_t n);
|
||||
extern void (*ref_difftest_raise_intr)(uint64_t NO);
|
||||
|
||||
static inline bool difftest_check_reg(const char *name, vaddr_t pc, word_t ref, word_t dut) {
|
||||
if (ref != dut) {
|
||||
Log("%s is different after executing instruction at pc = " FMT_WORD
|
||||
", right = " FMT_WORD ", wrong = " FMT_WORD ", diff = " FMT_WORD,
|
||||
name, pc, ref, dut, ref ^ dut);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
26
nemu/include/cpu/ifetch.h
Normal file
26
nemu/include/cpu/ifetch.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/***************************************************************************************
|
||||
* 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 __CPU_IFETCH_H__
|
||||
|
||||
#include <memory/vaddr.h>
|
||||
|
||||
static inline uint32_t inst_fetch(vaddr_t *pc, int len) {
|
||||
uint32_t inst = vaddr_ifetch(*pc, len);
|
||||
(*pc) += len;
|
||||
return inst;
|
||||
}
|
||||
|
||||
#endif
|
43
nemu/include/debug.h
Normal file
43
nemu/include/debug.h
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.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __DEBUG_H__
|
||||
#define __DEBUG_H__
|
||||
|
||||
#include <common.h>
|
||||
#include <stdio.h>
|
||||
#include <utils.h>
|
||||
|
||||
#define Log(format, ...) \
|
||||
_Log(ANSI_FMT("[%s:%d %s] " format, ANSI_FG_BLUE) "\n", \
|
||||
__FILE__, __LINE__, __func__, ## __VA_ARGS__)
|
||||
|
||||
#define Assert(cond, format, ...) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
MUXDEF(CONFIG_TARGET_AM, printf(ANSI_FMT(format, ANSI_FG_RED) "\n", ## __VA_ARGS__), \
|
||||
(fflush(stdout), fprintf(stderr, ANSI_FMT(format, ANSI_FG_RED) "\n", ## __VA_ARGS__))); \
|
||||
IFNDEF(CONFIG_TARGET_AM, extern FILE* log_fp; fflush(log_fp)); \
|
||||
extern void assert_fail_msg(); \
|
||||
assert_fail_msg(); \
|
||||
assert(cond); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define panic(format, ...) Assert(0, format, ## __VA_ARGS__)
|
||||
|
||||
#define TODO() panic("please implement me")
|
||||
|
||||
#endif
|
24
nemu/include/device/alarm.h
Normal file
24
nemu/include/device/alarm.h
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.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __DEVICE_ALARM_H__
|
||||
#define __DEVICE_ALARM_H__
|
||||
|
||||
#define TIMER_HZ 60
|
||||
|
||||
typedef void (*alarm_handler_t) ();
|
||||
void add_alarm_handle(alarm_handler_t h);
|
||||
|
||||
#endif
|
56
nemu/include/device/map.h
Normal file
56
nemu/include/device/map.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/***************************************************************************************
|
||||
* 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 __DEVICE_MAP_H__
|
||||
#define __DEVICE_MAP_H__
|
||||
|
||||
#include <cpu/difftest.h>
|
||||
|
||||
typedef void(*io_callback_t)(uint32_t, int, bool);
|
||||
uint8_t* new_space(int size);
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
// we treat ioaddr_t as paddr_t here
|
||||
paddr_t low;
|
||||
paddr_t high;
|
||||
void *space;
|
||||
io_callback_t callback;
|
||||
} IOMap;
|
||||
|
||||
static inline bool map_inside(IOMap *map, paddr_t addr) {
|
||||
return (addr >= map->low && addr <= map->high);
|
||||
}
|
||||
|
||||
static inline int find_mapid_by_addr(IOMap *maps, int size, paddr_t addr) {
|
||||
int i;
|
||||
for (i = 0; i < size; i ++) {
|
||||
if (map_inside(maps + i, addr)) {
|
||||
difftest_skip_ref();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void add_pio_map(const char *name, ioaddr_t addr,
|
||||
void *space, uint32_t len, io_callback_t callback);
|
||||
void add_mmio_map(const char *name, paddr_t addr,
|
||||
void *space, uint32_t len, io_callback_t callback);
|
||||
|
||||
word_t map_read(paddr_t addr, int len, IOMap *map);
|
||||
void map_write(paddr_t addr, int len, word_t data, IOMap *map);
|
||||
|
||||
#endif
|
24
nemu/include/device/mmio.h
Normal file
24
nemu/include/device/mmio.h
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.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __DEVICE_MMIO_H__
|
||||
#define __DEVICE_MMIO_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
word_t mmio_read(paddr_t addr, int len);
|
||||
void mmio_write(paddr_t addr, int len, word_t data);
|
||||
|
||||
#endif
|
40
nemu/include/difftest-def.h
Normal file
40
nemu/include/difftest-def.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/***************************************************************************************
|
||||
* 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 __DIFFTEST_DEF_H__
|
||||
#define __DIFFTEST_DEF_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <macro.h>
|
||||
#include <generated/autoconf.h>
|
||||
|
||||
#define __EXPORT __attribute__((visibility("default")))
|
||||
enum { DIFFTEST_TO_DUT, DIFFTEST_TO_REF };
|
||||
|
||||
#if defined(CONFIG_ISA_x86)
|
||||
# define DIFFTEST_REG_SIZE (sizeof(uint32_t) * 9) // GPRs + pc
|
||||
#elif defined(CONFIG_ISA_mips32)
|
||||
# define DIFFTEST_REG_SIZE (sizeof(uint32_t) * 38) // GPRs + status + lo + hi + badvaddr + cause + pc
|
||||
#elif defined(CONFIG_ISA_riscv)
|
||||
#define RISCV_GPR_TYPE MUXDEF(CONFIG_RV64, uint64_t, uint32_t)
|
||||
#define RISCV_GPR_NUM MUXDEF(CONFIG_RVE , 16, 32)
|
||||
#define DIFFTEST_REG_SIZE (sizeof(RISCV_GPR_TYPE) * (RISCV_GPR_NUM + 1)) // GPRs + pc
|
||||
#elif defined(CONFIG_ISA_loongarch32r)
|
||||
# define DIFFTEST_REG_SIZE (sizeof(uint32_t) * 33) // GPRs + pc
|
||||
#else
|
||||
# error Unsupport ISA
|
||||
#endif
|
||||
|
||||
#endif
|
58
nemu/include/isa.h
Normal file
58
nemu/include/isa.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/***************************************************************************************
|
||||
* 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_H__
|
||||
#define __ISA_H__
|
||||
|
||||
// Located at src/isa/$(GUEST_ISA)/include/isa-def.h
|
||||
#include <isa-def.h>
|
||||
|
||||
// The macro `__GUEST_ISA__` is defined in $(CFLAGS).
|
||||
// It will be expanded as "x86" or "mips32" ...
|
||||
typedef concat(__GUEST_ISA__, _CPU_state) CPU_state;
|
||||
typedef concat(__GUEST_ISA__, _ISADecodeInfo) ISADecodeInfo;
|
||||
|
||||
// monitor
|
||||
extern unsigned char isa_logo[];
|
||||
void init_isa();
|
||||
|
||||
// reg
|
||||
extern CPU_state cpu;
|
||||
void isa_reg_display();
|
||||
word_t isa_reg_str2val(const char *name, bool *success);
|
||||
|
||||
// exec
|
||||
struct Decode;
|
||||
int isa_exec_once(struct Decode *s);
|
||||
|
||||
// memory
|
||||
enum { MMU_DIRECT, MMU_TRANSLATE, MMU_FAIL };
|
||||
enum { MEM_TYPE_IFETCH, MEM_TYPE_READ, MEM_TYPE_WRITE };
|
||||
enum { MEM_RET_OK, MEM_RET_FAIL, MEM_RET_CROSS_PAGE };
|
||||
#ifndef isa_mmu_check
|
||||
int isa_mmu_check(vaddr_t vaddr, int len, int type);
|
||||
#endif
|
||||
paddr_t isa_mmu_translate(vaddr_t vaddr, int len, int type);
|
||||
|
||||
// interrupt/exception
|
||||
vaddr_t isa_raise_intr(word_t NO, vaddr_t epc);
|
||||
#define INTR_EMPTY ((word_t)-1)
|
||||
word_t isa_query_intr();
|
||||
|
||||
// difftest
|
||||
bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc);
|
||||
void isa_difftest_attach();
|
||||
|
||||
#endif
|
110
nemu/include/macro.h
Normal file
110
nemu/include/macro.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/***************************************************************************************
|
||||
* 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 __MACRO_H__
|
||||
#define __MACRO_H__
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// macro stringizing
|
||||
#define str_temp(x) #x
|
||||
#define str(x) str_temp(x)
|
||||
|
||||
// strlen() for string constant
|
||||
#define STRLEN(CONST_STR) (sizeof(CONST_STR) - 1)
|
||||
|
||||
// calculate the length of an array
|
||||
#define ARRLEN(arr) (int)(sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
// macro concatenation
|
||||
#define concat_temp(x, y) x ## y
|
||||
#define concat(x, y) concat_temp(x, y)
|
||||
#define concat3(x, y, z) concat(concat(x, y), z)
|
||||
#define concat4(x, y, z, w) concat3(concat(x, y), z, w)
|
||||
#define concat5(x, y, z, v, w) concat4(concat(x, y), z, v, w)
|
||||
|
||||
// macro testing
|
||||
// See https://stackoverflow.com/questions/26099745/test-if-preprocessor-symbol-is-defined-inside-macro
|
||||
#define CHOOSE2nd(a, b, ...) b
|
||||
#define MUX_WITH_COMMA(contain_comma, a, b) CHOOSE2nd(contain_comma a, b)
|
||||
#define MUX_MACRO_PROPERTY(p, macro, a, b) MUX_WITH_COMMA(concat(p, macro), a, b)
|
||||
// define placeholders for some property
|
||||
#define __P_DEF_0 X,
|
||||
#define __P_DEF_1 X,
|
||||
#define __P_ONE_1 X,
|
||||
#define __P_ZERO_0 X,
|
||||
// define some selection functions based on the properties of BOOLEAN macro
|
||||
#define MUXDEF(macro, X, Y) MUX_MACRO_PROPERTY(__P_DEF_, macro, X, Y)
|
||||
#define MUXNDEF(macro, X, Y) MUX_MACRO_PROPERTY(__P_DEF_, macro, Y, X)
|
||||
#define MUXONE(macro, X, Y) MUX_MACRO_PROPERTY(__P_ONE_, macro, X, Y)
|
||||
#define MUXZERO(macro, X, Y) MUX_MACRO_PROPERTY(__P_ZERO_,macro, X, Y)
|
||||
|
||||
// test if a boolean macro is defined
|
||||
#define ISDEF(macro) MUXDEF(macro, 1, 0)
|
||||
// test if a boolean macro is undefined
|
||||
#define ISNDEF(macro) MUXNDEF(macro, 1, 0)
|
||||
// test if a boolean macro is defined to 1
|
||||
#define ISONE(macro) MUXONE(macro, 1, 0)
|
||||
// test if a boolean macro is defined to 0
|
||||
#define ISZERO(macro) MUXZERO(macro, 1, 0)
|
||||
// test if a macro of ANY type is defined
|
||||
// NOTE1: it ONLY works inside a function, since it calls `strcmp()`
|
||||
// NOTE2: macros defined to themselves (#define A A) will get wrong results
|
||||
#define isdef(macro) (strcmp("" #macro, "" str(macro)) != 0)
|
||||
|
||||
// simplification for conditional compilation
|
||||
#define __IGNORE(...)
|
||||
#define __KEEP(...) __VA_ARGS__
|
||||
// keep the code if a boolean macro is defined
|
||||
#define IFDEF(macro, ...) MUXDEF(macro, __KEEP, __IGNORE)(__VA_ARGS__)
|
||||
// keep the code if a boolean macro is undefined
|
||||
#define IFNDEF(macro, ...) MUXNDEF(macro, __KEEP, __IGNORE)(__VA_ARGS__)
|
||||
// keep the code if a boolean macro is defined to 1
|
||||
#define IFONE(macro, ...) MUXONE(macro, __KEEP, __IGNORE)(__VA_ARGS__)
|
||||
// keep the code if a boolean macro is defined to 0
|
||||
#define IFZERO(macro, ...) MUXZERO(macro, __KEEP, __IGNORE)(__VA_ARGS__)
|
||||
|
||||
// functional-programming-like macro (X-macro)
|
||||
// apply the function `f` to each element in the container `c`
|
||||
// NOTE1: `c` should be defined as a list like:
|
||||
// f(a0) f(a1) f(a2) ...
|
||||
// NOTE2: each element in the container can be a tuple
|
||||
#define MAP(c, f) c(f)
|
||||
|
||||
#define BITMASK(bits) ((1ull << (bits)) - 1)
|
||||
#define BITS(x, hi, lo) (((x) >> (lo)) & BITMASK((hi) - (lo) + 1)) // similar to x[hi:lo] in verilog
|
||||
#define SEXT(x, len) ({ struct { int64_t n : len; } __x = { .n = x }; (uint64_t)__x.n; })
|
||||
|
||||
#define ROUNDUP(a, sz) ((((uintptr_t)a) + (sz) - 1) & ~((sz) - 1))
|
||||
#define ROUNDDOWN(a, sz) ((((uintptr_t)a)) & ~((sz) - 1))
|
||||
|
||||
#define PG_ALIGN __attribute((aligned(4096)))
|
||||
|
||||
#if !defined(likely)
|
||||
#define likely(cond) __builtin_expect(cond, 1)
|
||||
#define unlikely(cond) __builtin_expect(cond, 0)
|
||||
#endif
|
||||
|
||||
// for AM IOE
|
||||
#define io_read(reg) \
|
||||
({ reg##_T __io_param; \
|
||||
ioe_read(reg, &__io_param); \
|
||||
__io_param; })
|
||||
|
||||
#define io_write(reg, ...) \
|
||||
({ reg##_T __io_param = (reg##_T) { __VA_ARGS__ }; \
|
||||
ioe_write(reg, &__io_param); })
|
||||
|
||||
#endif
|
41
nemu/include/memory/host.h
Normal file
41
nemu/include/memory/host.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/***************************************************************************************
|
||||
* 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 __MEMORY_HOST_H__
|
||||
#define __MEMORY_HOST_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
static inline word_t host_read(void *addr, int len) {
|
||||
switch (len) {
|
||||
case 1: return *(uint8_t *)addr;
|
||||
case 2: return *(uint16_t *)addr;
|
||||
case 4: return *(uint32_t *)addr;
|
||||
IFDEF(CONFIG_ISA64, case 8: return *(uint64_t *)addr);
|
||||
default: MUXDEF(CONFIG_RT_CHECK, assert(0), return 0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void host_write(void *addr, int len, word_t data) {
|
||||
switch (len) {
|
||||
case 1: *(uint8_t *)addr = data; return;
|
||||
case 2: *(uint16_t *)addr = data; return;
|
||||
case 4: *(uint32_t *)addr = data; return;
|
||||
IFDEF(CONFIG_ISA64, case 8: *(uint64_t *)addr = data; return);
|
||||
IFDEF(CONFIG_RT_CHECK, default: assert(0));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
37
nemu/include/memory/paddr.h
Normal file
37
nemu/include/memory/paddr.h
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.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __MEMORY_PADDR_H__
|
||||
#define __MEMORY_PADDR_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#define PMEM_LEFT ((paddr_t)CONFIG_MBASE)
|
||||
#define PMEM_RIGHT ((paddr_t)CONFIG_MBASE + CONFIG_MSIZE - 1)
|
||||
#define RESET_VECTOR (PMEM_LEFT + CONFIG_PC_RESET_OFFSET)
|
||||
|
||||
/* convert the guest physical address in the guest program to host virtual address in NEMU */
|
||||
uint8_t* guest_to_host(paddr_t paddr);
|
||||
/* convert the host virtual address in NEMU to guest physical address in the guest program */
|
||||
paddr_t host_to_guest(uint8_t *haddr);
|
||||
|
||||
static inline bool in_pmem(paddr_t addr) {
|
||||
return addr - CONFIG_MBASE < CONFIG_MSIZE;
|
||||
}
|
||||
|
||||
word_t paddr_read(paddr_t addr, int len);
|
||||
void paddr_write(paddr_t addr, int len, word_t data);
|
||||
|
||||
#endif
|
29
nemu/include/memory/vaddr.h
Normal file
29
nemu/include/memory/vaddr.h
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.
|
||||
***************************************************************************************/
|
||||
|
||||
#ifndef __MEMORY_VADDR_H__
|
||||
#define __MEMORY_VADDR_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
word_t vaddr_ifetch(vaddr_t addr, int len);
|
||||
word_t vaddr_read(vaddr_t addr, int len);
|
||||
void vaddr_write(vaddr_t addr, int len, word_t data);
|
||||
|
||||
#define PAGE_SHIFT 12
|
||||
#define PAGE_SIZE (1ul << PAGE_SHIFT)
|
||||
#define PAGE_MASK (PAGE_SIZE - 1)
|
||||
|
||||
#endif
|
77
nemu/include/utils.h
Normal file
77
nemu/include/utils.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/***************************************************************************************
|
||||
* 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 __UTILS_H__
|
||||
#define __UTILS_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
// ----------- state -----------
|
||||
|
||||
enum { NEMU_RUNNING, NEMU_STOP, NEMU_END, NEMU_ABORT, NEMU_QUIT };
|
||||
|
||||
typedef struct {
|
||||
int state;
|
||||
vaddr_t halt_pc;
|
||||
uint32_t halt_ret;
|
||||
} NEMUState;
|
||||
|
||||
extern NEMUState nemu_state;
|
||||
|
||||
// ----------- timer -----------
|
||||
|
||||
uint64_t get_time();
|
||||
|
||||
// ----------- log -----------
|
||||
|
||||
#define ANSI_FG_BLACK "\33[1;30m"
|
||||
#define ANSI_FG_RED "\33[1;31m"
|
||||
#define ANSI_FG_GREEN "\33[1;32m"
|
||||
#define ANSI_FG_YELLOW "\33[1;33m"
|
||||
#define ANSI_FG_BLUE "\33[1;34m"
|
||||
#define ANSI_FG_MAGENTA "\33[1;35m"
|
||||
#define ANSI_FG_CYAN "\33[1;36m"
|
||||
#define ANSI_FG_WHITE "\33[1;37m"
|
||||
#define ANSI_BG_BLACK "\33[1;40m"
|
||||
#define ANSI_BG_RED "\33[1;41m"
|
||||
#define ANSI_BG_GREEN "\33[1;42m"
|
||||
#define ANSI_BG_YELLOW "\33[1;43m"
|
||||
#define ANSI_BG_BLUE "\33[1;44m"
|
||||
#define ANSI_BG_MAGENTA "\33[1;35m"
|
||||
#define ANSI_BG_CYAN "\33[1;46m"
|
||||
#define ANSI_BG_WHITE "\33[1;47m"
|
||||
#define ANSI_NONE "\33[0m"
|
||||
|
||||
#define ANSI_FMT(str, fmt) fmt str ANSI_NONE
|
||||
|
||||
#define log_write(...) IFDEF(CONFIG_TARGET_NATIVE_ELF, \
|
||||
do { \
|
||||
extern FILE* log_fp; \
|
||||
extern bool log_enable(); \
|
||||
if (log_enable()) { \
|
||||
fprintf(log_fp, __VA_ARGS__); \
|
||||
fflush(log_fp); \
|
||||
} \
|
||||
} while (0) \
|
||||
)
|
||||
|
||||
#define _Log(...) \
|
||||
do { \
|
||||
printf(__VA_ARGS__); \
|
||||
log_write(__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue