├── .gitignore
├── .gitmodules
├── LICENSE
├── Makefile
├── README.md
├── TODO.md
├── configs
├── .gitignore
└── Kconfig
├── docs
├── kdb.md
├── riscv.md
└── tests.md
├── include
├── config
│ └── config.h
├── cpu
│ ├── core.h
│ ├── cpu.h
│ ├── riscv
│ │ ├── aclint.h
│ │ ├── core.h
│ │ ├── cpu.h
│ │ ├── csr.h
│ │ ├── def.h
│ │ └── local-include
│ │ │ └── inst-list.h
│ └── word.h
├── debug.h
├── device
│ ├── bus.h
│ ├── memory.h
│ └── uart.h
├── isa
│ ├── isa.h
│ ├── riscv
│ │ └── isa.h
│ └── word.h
├── kdb
│ ├── cmd.h
│ ├── kdb.h
│ └── rsp.h
├── log.h
├── macro.h
└── utils
│ ├── decoder.h
│ ├── gdb-rsp.h
│ ├── task-timer.h
│ ├── tcp-server.h
│ └── utils.h
├── scripts
├── config.mk
├── decoder-gen
│ ├── gen.py
│ ├── instpat.py
│ └── main.py
├── filelist.mk
├── isa
│ └── riscv.mk
└── kdb
│ └── dummy.kdb
├── src
├── cpu
│ └── riscv
│ │ ├── aclint.cpp
│ │ ├── core.cpp
│ │ ├── cpu.cpp
│ │ ├── csr
│ │ ├── csr-rw.cpp
│ │ └── csr.cpp
│ │ ├── inst
│ │ ├── atomic.cpp
│ │ ├── base.cpp
│ │ ├── compressed.cpp
│ │ ├── inst-decoder.cpp
│ │ ├── local-decoder.h
│ │ ├── mul.cpp
│ │ ├── privileged.cpp
│ │ └── zicsr.cpp
│ │ ├── instpat
│ │ ├── base.instpat
│ │ └── compressed.instpat
│ │ ├── memory.cpp
│ │ └── privileged
│ │ ├── interrupt.cpp
│ │ └── trap.cpp
├── device
│ ├── bus.cpp
│ ├── memory.cpp
│ └── uart.cpp
├── isa
│ ├── riscv
│ │ ├── disassemble.cpp
│ │ └── riscv.cpp
│ └── riscv32
│ │ ├── disassemble.cpp
│ │ └── riscv32.cpp
├── kdb
│ ├── cmd.cpp
│ ├── cmd
│ │ ├── completion.cpp
│ │ ├── dbg.cpp
│ │ ├── info.cpp
│ │ ├── load.cpp
│ │ ├── log.cpp
│ │ ├── mem.cpp
│ │ ├── show.cpp
│ │ └── uart.cpp
│ ├── cpu-exec.cpp
│ ├── elf.cpp
│ ├── kdb.cpp
│ ├── memory.cpp
│ ├── rsp
│ │ └── rsp.cpp
│ └── uart.cpp
├── log.cpp
├── main.cpp
└── utils
│ ├── decoder
│ └── bitpat.cpp
│ ├── gdb-rsp
│ └── gdb-rsp.cpp
│ ├── task-timer
│ └── task-timer.cpp
│ ├── tcp-server
│ └── tcp-server.cpp
│ └── utils.cpp
├── tests
├── abstract-machine
│ ├── Makefile
│ ├── am
│ │ ├── Makefile
│ │ ├── include
│ │ │ ├── am-dev.h
│ │ │ ├── am.h
│ │ │ └── isa
│ │ │ │ └── riscv.h
│ │ └── src
│ │ │ ├── isa
│ │ │ └── riscv
│ │ │ │ ├── csr.c
│ │ │ │ ├── cte.c
│ │ │ │ ├── halt.S
│ │ │ │ ├── ioe
│ │ │ │ ├── timer.c
│ │ │ │ └── uart.c
│ │ │ │ ├── start.S
│ │ │ │ ├── trap.S
│ │ │ │ └── vme.c
│ │ │ └── trm.c
│ ├── klib
│ │ ├── Makefile
│ │ ├── include
│ │ │ ├── klib-macros.h
│ │ │ └── klib.h
│ │ └── src
│ │ │ ├── ctype.c
│ │ │ ├── int64.c
│ │ │ ├── stdio.c
│ │ │ ├── stdlib.c
│ │ │ └── string.c
│ └── scripts
│ │ ├── kdb
│ │ ├── debug.kdb
│ │ ├── init.kdb
│ │ └── run.kdb
│ │ ├── linker.ld
│ │ ├── riscv32.mk
│ │ └── riscv64.mk
├── benchmarks
│ └── microbench
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── include
│ │ └── benchmark.h
│ │ ├── init.kdb
│ │ └── src
│ │ ├── 15pz
│ │ ├── 15pz.cc
│ │ ├── heap.h
│ │ └── puzzle.h
│ │ ├── bench.c
│ │ ├── bf
│ │ └── bf.c
│ │ ├── dinic
│ │ └── dinic.cc
│ │ ├── fib
│ │ └── fib.c
│ │ ├── lzip
│ │ ├── lzip.c
│ │ ├── quicklz.c
│ │ └── quicklz.h
│ │ ├── md5
│ │ └── md5.c
│ │ ├── qsort
│ │ └── qsort.c
│ │ ├── queen
│ │ └── queen.c
│ │ ├── sieve
│ │ └── sieve.c
│ │ └── ssort
│ │ └── ssort.cc
├── cpu-tests
│ ├── Makefile
│ ├── include
│ │ └── test.h
│ └── tests
│ │ ├── add-longlong.c
│ │ ├── add.c
│ │ ├── bit.c
│ │ ├── bubble-sort.c
│ │ ├── crc32.c
│ │ ├── div.c
│ │ ├── dummy.c
│ │ ├── fact.c
│ │ ├── fib.c
│ │ ├── goldbach.c
│ │ ├── hello-str.c
│ │ ├── if-else.c
│ │ ├── leap-year.c
│ │ ├── load-store.c
│ │ ├── matrix-mul.c
│ │ ├── max.c
│ │ ├── mersenne.c
│ │ ├── min3.c
│ │ ├── mov-c.c
│ │ ├── movsx.c
│ │ ├── mul-longlong.c
│ │ ├── pascal.c
│ │ ├── prime.c
│ │ ├── quick-sort.c
│ │ ├── recursion.c
│ │ ├── select-sort.c
│ │ ├── shift.c
│ │ ├── shuixianhua.c
│ │ ├── string.c
│ │ ├── sub-longlong.c
│ │ ├── sum.c
│ │ ├── switch.c
│ │ ├── to-lower-case.c
│ │ ├── unalign.c
│ │ └── wanshu.c
├── ioe-tests
│ ├── makefile
│ ├── uart.c
│ └── uart.kdb
├── privileged-tests
│ ├── intr.c
│ ├── makefile
│ └── uart.kdb
└── riscv
│ ├── Makefile
│ ├── README.md
│ ├── deleg
│ └── src
│ │ └── deleg.S
│ ├── mtimer
│ └── src
│ │ └── timer.S
│ ├── smode
│ └── src
│ │ └── smode.S
│ ├── stimer
│ └── src
│ │ └── stimer.S
│ ├── uart.kdb
│ ├── vm32
│ ├── src
│ │ ├── inc.S
│ │ ├── main.c
│ │ └── trap.S
│ └── user-img
│ │ ├── Makefile
│ │ └── user.S
│ └── vm64
│ ├── src
│ ├── inc.S
│ ├── main.c
│ ├── trap.S
│ └── vm.c
│ └── user-img
│ ├── Makefile
│ └── user.S
├── tools
└── kconfig
│ ├── .config
│ ├── .gitignore
│ ├── Makefile
│ ├── conf.c
│ ├── confdata.c
│ ├── expr.c
│ ├── expr.h
│ ├── lexer.l
│ ├── list.h
│ ├── lkc.h
│ ├── lkc_proto.h
│ ├── lxdialog
│ ├── checklist.c
│ ├── dialog.h
│ ├── inputbox.c
│ ├── menubox.c
│ ├── textbox.c
│ ├── util.c
│ └── yesno.c
│ ├── mconf.c
│ ├── menu.c
│ ├── parser.y
│ ├── preprocess.c
│ ├── symbol.c
│ └── util.c
└── utils
└── uart
└── uart.py
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 |
3 | #vscode
4 | .vscode
5 |
6 | # clangd
7 | compile_commands.json
8 | .cache
9 |
10 | autogen
11 | autoconf.h
12 |
13 | __pycache__
14 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "utils/mini-gdbstub"]
2 | path = utils/mini-gdbstub
3 | url = https://github.com/RinHizakura/mini-gdbstub.git
4 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | include ./scripts/config.mk
2 |
3 | remove_quote = $(patsubst "%",%,$(1))
4 |
5 | CXX = clang++
6 | LD = clang++
7 | CXXFLAGS = -Wall -Wextra -Werror -pedantic -Ofast -Wno-unused-command-line-argument -Wno-unused-parameter -Wno-unused-private-field -flto -funroll-loops
8 | ISA := $(call remove_quote,$(CONFIG_ISA))
9 | BASE_ISA := $(call remove_quote,$(CONFIG_BASE_ISA))
10 |
11 | SRC_DIR = ./src
12 | BUILD_DIR = ./build
13 | OBJ_DIR = ./build/$(ISA)
14 |
15 | SRCS += $(shell find $(SRC_DIR) -path $(SRC_DIR)/isa -prune -o -path $(SRC_DIR)/cpu -prune -o \( -name "*.cpp" -o -name "*.c" \) -print)
16 | SRCS += $(shell find $(SRC_DIR)/isa/$(BASE_ISA) -name "*.cpp" -or -name "*.c" )
17 | # SRCS += $(shell find $(SRC_DIR)/isa/$(ISA) -name "*.cpp" -or -name "*.c" )
18 | SRCS += $(shell find $(SRC_DIR)/cpu/$(CONFIG_SRC_CPU_ISA) -name "*.cpp" -or -name "*.c" )
19 | OBJS += $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRCS))
20 | DEPS = $(OBJS:.o=.d)
21 |
22 | INCPATH += $(abspath ./include)
23 | INCPATH += $(abspath ./tests/isa/$(ISA))
24 | INCFLAGS = $(addprefix -I,$(INCPATH))
25 |
26 | LIBS += readline
27 | LIBFLAGS = $(addprefix -l,$(LIBS))
28 |
29 | CXXFLAGS += $(INCFLAGS)
30 | CXXFLAGS += $(LIBFLAGS)
31 |
32 | # for llvm
33 | CXXFLAGS += $(shell llvm-config --cxxflags) -fexceptions # for expection handling
34 | CXXFLAGS += $(shell llvm-config --libs)
35 |
36 | ifeq ($(shell which ccache > /dev/null 2>&1; echo $$?), 0)
37 | CXX := ccache $(CXX)
38 | endif
39 |
40 | TARGET = $(BUILD_DIR)/$(ISA)-kxemu
41 |
42 | $(TARGET): $(OBJS)
43 | $(info + CXX $@)
44 | @ mkdir -p $(BUILD_DIR)
45 | @ $(LD) $(OBJS) -o $(TARGET) $(LDFLAGS) $(CXXFLAGS)
46 |
47 | $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
48 | $(info + CXX $<)
49 | @ mkdir -p $(dir $@)
50 | @ $(CXX) $(CXXFLAGS) -MMD -MP -c $< -o $@
51 |
52 | -include $(DEPS)
53 |
54 | -include ./scripts/isa/$(BASE_ISA).mk
55 |
56 | kxemu: $(TARGET)
57 |
58 | run: $(TARGET)
59 | $(info + Running $(TARGET))
60 | @ $(TARGET) $(FLAGS)
61 |
62 | clean:
63 | rm -rf $(BUILD_DIR)
64 |
65 | count:
66 | $(info Counting lines in src and include directories...)
67 | @find $(SRC_DIR) ./include -name '*.c' -or -name "*.cpp" -or -name "*.h" | xargs cat | sed '/^\s*$$/d' | wc -l
68 |
69 | tidy:
70 | clang-tidy $(SRCS)
71 |
72 | .PHONY: kxemu run clean
73 | .DEFAULT_GOAL := kxemu
74 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | # KXemu TODO List
2 |
3 | 1. 移植nemu的cpu-tests部分
4 |
5 | 2. 为kdb编写命令行调试基础设施
6 |
7 | 3. 为riscv32指令集添加difftest
8 |
9 | 4. 实现riscv32-C指令集扩展
10 |
11 | 5. 龙芯指令集
12 |
--------------------------------------------------------------------------------
/configs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 | !Kconfig
--------------------------------------------------------------------------------
/configs/Kconfig:
--------------------------------------------------------------------------------
1 | mainmenu "KXemu Configurations"
2 |
3 | choice
4 | prompt "ISA"
5 | default ISA_riscv32
6 |
7 | config ISA_riscv32
8 | bool "riscv32"
9 |
10 | config ISA_riscv64
11 | bool "riscv64"
12 |
13 | endchoice
14 |
15 | config ISA
16 | string
17 | default riscv32 if ISA_riscv32
18 | default riscv64 if ISA_riscv64
19 |
20 | config BASE_ISA
21 | string
22 | default riscv if ISA_riscv32
23 | default riscv if ISA_riscv64
24 |
25 | config SRC_CPU_ISA
26 | string
27 | default riscv if ISA_riscv32
28 | default riscv if ISA_riscv64
29 |
30 | config LOG
31 | bool "LOG"
32 |
33 | config HINT
34 | bool "Show hints"
35 |
--------------------------------------------------------------------------------
/docs/kdb.md:
--------------------------------------------------------------------------------
1 | # KDB文档 Documentation
2 |
3 | ## KDB简介 Introduction
4 |
5 | KDB是对KXemu的包装,用于用户控制KXemu中的CPU,并且连接CPU和其他外设。
6 |
7 | ## KDB启动参数 Startup Parameters
8 |
9 | 编译运行KXemu,会自动启动kdb命令行。kdb接受的命令行参数:
10 |
11 | When KXemu is compiled and executed, the KDB command-line interface is automatically launched. KDB accepts the following command-line arguments:
12 |
13 | - `-s --source [filename]` 在启动的时候自动运行脚本,这可以用于大多数的时候运行镜像文件。可以指定多个源文件,kdb会依次运行它们。Automatically executes a script at startup, often used for running image files. Multiple source files can be specified, and KDB will execute them in order.
14 |
15 | - `-e --elf [filename]` 指定elf文件,在命令中使用`load elf`来将这个elf加载到内存的指定位置。Specifies an ELF file that can be loaded into memory using the load elf command.
16 |
17 | ## KDB命令
18 |
19 | ### 运行
20 |
21 | - `step [n]` 运行当前选中的核心`n`步,遇到核心出现错误或者break时终止。`n`默认为`1`。默认会打印运行的指令和反汇编代码。Executes the selected core for n steps, stopping on errors or breaks. Defaults to n=1. The executed instruction and its disassembly are printed by default.
22 |
23 | - `run` 运行当前核心,直到核心出现错误或者break时终止。Runs the current core(or halt in the riscv) until an error or break occurs.
24 |
25 | ### 日志
26 |
27 | - `log on [DEBUG|INFO|WARN|PANIC]` 打开一项日志等级的输出,默认所有等级的输出都是开启的。Enables a specific log level output. By default, all log levels are enabled.
28 |
29 | - `log off [DEBUG|INFO|WARN|PANIC]` 关闭一项日志等级的输出。Disables a specific log level output.
30 |
31 | ### 加载
32 |
33 | 加载指令用于加载在命令行参数中指定的文件,如ELF文件。
34 |
35 | Load commands are used to load files specified in the command-line arguments, such as ELF files.
36 |
37 | - `load elf` 加载命令行中由参数`--elf`或`-e`指定的`elf`路径,可以在批处理下设置好内存映射后延迟加载ELF文件。Loads the ELF file path specified by the --elf or -e argument, allowing deferred loading after memory mapping in batch processing.
38 |
39 | ### 内存
40 |
41 | - `mem create [name] [addr] [size]` 创建一个名为`name`的、映射到`addr`位置的,长度为`size`的内存映射区域。Creates a memory-mapped region named name at address addr with a size of size.
42 |
43 | - `mem img [addr] [filename]` 将本地文件加载到内存`addr`的位置,`addr`处映射的内存必须是一个用于存储的区域。Loads a local file into memory at address addr. The memory at addr must be a storage region.
44 |
45 | - `x > addr` 与gdb类似,打印内存中的数据。Similar to GDB, prints data from memory at the specified address.
46 |
47 | ### 串口
48 |
49 | - `uart add [port]` KXemu可以模拟一个UART16650设备,这条指令可以为CPU添加一个内存映射在`base`处的uart串口,如果指定端口,可以通过TCP套接字连接至串口,向端口`port`写入可以发送数据,同时可以从`port+1`端口接收KXemu的串口输出。如果不指定端口,则串口输出会自动输出至标准输出。在`./utils/uart`目录下有一个示例。KXemu can simulate a UART16650 device. This command maps a UART serial port to the CPU at the base address. If a port is specified, TCP sockets can be used to connect to the serial port, allowing data transmission to port and receiving KXemu's serial output from port+1. If no port is specified, output is directed to standard output. An example is available in the `./utils/uart` directory.
50 |
51 | - `uart puts [str]` 将`str`字符串的内容加入到串口的FIFO中。Adds the content of the str string to the UART's FIFO.
52 |
53 | ### Debug
54 |
55 | - `info ` 打印名字为`name`的寄存器。Prints the value of the register named name.
56 |
57 | - `info gpr` 打印当前核的所有通用寄存器。Prints all general-purpose registers of the current core(or halt).
58 |
59 | - `info pc` 打印当前核的PC。Prints the PC register of the current core(or halt).
60 |
61 | ### 其他
62 |
63 | - `source [filename]` 运行存储在本地的kdb命令文件。Executes a local KDB command file.
64 |
--------------------------------------------------------------------------------
/docs/riscv.md:
--------------------------------------------------------------------------------
1 | # RISCV
2 |
3 | ## 已实现
4 |
5 | 1. 基本整数指令集、M扩展指令集、C扩展指令集的整数部分。Basic integer instruction set, M-extension, and the integer part of the C-extension.
6 |
7 | 2. `ecall`指令、`mret`、`sret`指令的基本功能,包括特权级的切换。Basic functionality of the ecall, mret, and sret instructions, including privilege level switching.
8 |
9 | 3. `mtime`和`mtimecmp`的计时功能,默认频率是10MHz。Timing functionality for mtime and mtimecmp, with a default frequency of 10 MHz.
10 |
11 | 4. 物理内存保护和虚拟内存管理。 Physical Memory Protection and Vitrual Memory.
12 |
13 | 5. Sstc扩展。 Sstc Extension.
14 |
15 | ## 计划实现
16 |
17 | 1. 原子指令A扩展。
18 |
19 | 2. 浮点指令F扩展和D扩展。
20 |
--------------------------------------------------------------------------------
/docs/tests.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HD-CSKX/KXemu/0d7589c98924b1100e634359a3b84fff8809f54b/docs/tests.md
--------------------------------------------------------------------------------
/include/config/config.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_CONFIG_CONFIG_H__
2 | #define __KXEMU_CONFIG_CONFIG_H__
3 |
4 | #include "autoconf.h"
5 | #include "macro.h"
6 |
7 | #if defined (CONFIG_ISA_riscv32) && CONFIG_ISA_riscv32 == 1
8 | #define KXEMU_ISA riscv32
9 | #define KXEMU_ISA32
10 | #define KXEMU_ISA_32BIT true
11 | #define KXEMU_ISA_64BIT false
12 | #elif defined (CONFIG_ISA_riscv64) && CONFIG_ISA_riscv64 == 1
13 | #define KXEMU_ISA riscv64
14 | #define KXEMU_ISA64
15 | #define KXEMU__ISA_32BIT false
16 | #define KXEMU__ISA_64BIT true
17 | #else
18 | #error "Unsupport ISA"
19 | #endif
20 |
21 | #define KXEMU_ISA_STR MACRO_TO_STRING(KXEMU_ISA)
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/include/cpu/core.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_CPU_CORE_H__
2 | #define __KXEMU_CPU_CORE_H__
3 |
4 | #include
5 |
6 | namespace kxemu::cpu {
7 |
8 | template
9 | class Core {
10 | public:
11 | virtual bool is_error() = 0;
12 | virtual bool is_break() = 0;
13 | virtual bool is_running() = 0;
14 | virtual bool is_halt() = 0;
15 | virtual ~Core() = default;
16 |
17 | virtual void reset(word_t entry) = 0;
18 | virtual void step() = 0;
19 |
20 | virtual void run(word_t *breakpoints = nullptr, unsigned int n = 0) = 0;
21 |
22 | virtual word_t get_pc() = 0;
23 | virtual word_t get_gpr(int idx) = 0;
24 | virtual word_t get_register(const std::string &name, bool &success) = 0;
25 |
26 | virtual word_t get_halt_pc() = 0;
27 | virtual word_t get_halt_code() = 0;
28 |
29 | // The interface for virtual address translation for KDB
30 | virtual word_t vaddr_translate(word_t vaddr, bool &valid) {
31 | valid = true;
32 | return vaddr;
33 | }
34 | };
35 |
36 | } // namespace kxemu::cpu
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/include/cpu/cpu.h:
--------------------------------------------------------------------------------
1 | /***************************************************************
2 | * Project Name: KXemu
3 | * File Name: include/cpu/cpu.h
4 | * Description: Define interface of the cpu and the cpu core for
5 | different ISA.
6 | ***************************************************************/
7 |
8 | #ifndef __KXEMU_CPU_CPU_H__
9 | #define __KXEMU_CPU_CPU_H__
10 |
11 | #include "cpu/core.h"
12 | #include "device/bus.h"
13 |
14 | namespace kxemu::cpu {
15 |
16 | template
17 | class CPU {
18 | public:
19 | // flags for extension features
20 | virtual void init(device::Bus *memory, int flags, unsigned int coreCount) = 0;
21 | virtual void reset(word_t pc) = 0;
22 | virtual void step() = 0;
23 | virtual bool is_running() = 0;
24 |
25 | virtual unsigned int core_count() = 0;
26 | virtual Core *get_core(unsigned int coreID) = 0;
27 |
28 | virtual ~CPU() = default;
29 | };
30 |
31 | } // namespace kxemu::cpu
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/include/cpu/riscv/aclint.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_CPU_RISCV_CLINT_H__
2 | #define __KXEMU_CPU_RISCV_CLINT_H__
3 |
4 | #include "cpu/word.h"
5 |
6 | #include
7 | #include
8 |
9 | namespace kxemu::cpu {
10 |
11 | // This is an implementation of the Advanced Core Local Interruptor (ACLINT) for RISC-V.
12 | // See https://github.com/riscv/riscv-aclint/releases/download/v1.0-rc4/riscv-aclint-1.0-rc4.pdf
13 | // offset | Device | Description
14 | // 0x0000 - 0x3fff | MSWI | Machine-mode Software Interrupt Device
15 | // 0x4000 - 0x7ff0 | MTIMECMP |
16 | // 0xbff8 - 0xbfff | MTIME |
17 | // 0xc000 - 0xffff | SSWI | Supervisor-mode Software Interrupt Device
18 | class AClint {
19 | public:
20 | using callback_t = std::function;
21 | struct CoreInfo {
22 | void *core; // Pointer to the core object
23 |
24 | // The following fields are allocated in the core object
25 | uint64_t *mtimecmp; // Machine-mode Timecmp Register
26 | bool *msip; // Machine-mode Software Interrupt Device
27 | bool *ssip; // Supervisor-mode Software Interrupt Device
28 |
29 | callback_t set_mtimecmp; // Machine-mode Timecmp Register
30 | callback_t set_msip; // Machine-mode Software Interrupt Device
31 | callback_t set_ssip; // Supervisor-mode Software Interrupt Device
32 | };
33 |
34 | AClint();
35 | ~AClint();
36 |
37 | void init(unsigned int coreCount);
38 | void reset();
39 |
40 | word_t read(word_t addr, int size, bool &success);
41 | bool write(word_t addr, word_t value, int size);
42 |
43 | void register_core(unsigned int coreId, const CoreInfo &info);
44 | private:
45 | unsigned int coreCount;
46 |
47 | CoreInfo *cores;
48 | };
49 |
50 | } // namespace kxemu::cpu
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/include/cpu/riscv/cpu.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_CPU_RISCV_CPU_H__
2 | #define __KXEMU_CPU_RISCV_CPU_H__
3 |
4 | #include "cpu/cpu.h"
5 | #include "cpu/riscv/aclint.h"
6 | #include "cpu/riscv/core.h"
7 | #include "utils/task-timer.h"
8 |
9 | namespace kxemu::cpu {
10 |
11 | #ifdef KXEMU_ISA64
12 | using word_t = uint64_t;
13 | #else
14 | using word_t = uint32_t;
15 | #endif
16 |
17 | class RVCPU : public CPU {
18 | private:
19 | RVCore *cores;
20 | unsigned int coreCount;
21 |
22 | AClint aclint;
23 | utils::TaskTimer taskTimer;
24 |
25 | public:
26 | ~RVCPU() override;
27 |
28 | void init(device::Bus *bus, int flags, unsigned int coreCount) override;
29 | void reset(word_t pc) override;
30 | void step() override;
31 | bool is_running() override;
32 |
33 | unsigned int core_count() override;
34 | RVCore *get_core(unsigned int coreID) override;
35 | };
36 |
37 | } // namespace kxemu::cpu
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/include/cpu/riscv/csr.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_CPU_RISCV_CSR_H__
2 | #define __KXEMU_CPU_RISCV_CSR_H__
3 |
4 | #include "cpu/word.h"
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | namespace kxemu::cpu {
11 |
12 | class RVCSR {
13 | private:
14 | using csr_rw_func_t = word_t (RVCSR::*)(unsigned int addr, word_t value, bool &valid);
15 | struct CSR {
16 | csr_rw_func_t readFunc;
17 | csr_rw_func_t writeFunc;
18 | word_t value;
19 | word_t resetValue;
20 | };
21 | std::unordered_map csr;
22 | void add_csr(unsigned int addr, word_t resetValue = 0, csr_rw_func_t readFunc = nullptr, csr_rw_func_t writeFunc = nullptr);
23 |
24 | using callback_t = std::function;
25 | callback_t update_stimecmp;
26 |
27 | struct PMPCfg {
28 | word_t start;
29 | word_t end;
30 | bool r;
31 | bool w;
32 | bool x;
33 | } pmpCfgArray[64];
34 | unsigned int pmpCfgCount;
35 | void reload_pmpcfg();
36 | PMPCfg *pmp_check(word_t addr, int len);
37 |
38 | std::function get_uptime;
39 |
40 | // misa
41 | word_t read_misa(unsigned int addr, word_t value, bool &valid);
42 | word_t write_misa(unsigned int addr, word_t value, bool &valid);
43 |
44 | // mip
45 | word_t read_mip(unsigned int addr, word_t value, bool &valid);
46 | word_t write_mip(unsigned int addr, word_t value, bool &valid);
47 |
48 | // mie
49 | word_t read_mie(unsigned int addr, word_t value, bool &valid);
50 | word_t write_mie(unsigned int addr, word_t value, bool &valid);
51 |
52 | // pmp
53 | word_t write_pmpcfg (unsigned int addr, word_t value, bool &valid);
54 | word_t write_pmpaddr(unsigned int addr, word_t value, bool &valid);
55 |
56 | // sip
57 | word_t read_sip(unsigned int addr, word_t value, bool &valid);
58 | word_t write_sip(unsigned int addr, word_t value, bool &valid);
59 |
60 | // stimecmp
61 | word_t write_stimecmp(unsigned int addr, word_t value, bool &valid);
62 |
63 | // sie
64 | word_t read_sie(unsigned int addr, word_t value, bool &valid);
65 | word_t write_sie(unsigned int addr, word_t value, bool &valid);
66 |
67 | // sstatus
68 | word_t read_sstatus(unsigned int addr, word_t value, bool &valid);
69 | word_t write_sstatus(unsigned int addr, word_t value, bool &valid);
70 |
71 | // satp
72 | word_t read_satp(unsigned int addr, word_t value, bool &valid);
73 | word_t write_satp(unsigned int addr, word_t value, bool &valid);
74 |
75 | // time
76 | word_t read_time(unsigned int addr, word_t value, bool &valid);
77 |
78 | public:
79 | RVCSR();
80 |
81 | int privMode;
82 |
83 | void init(unsigned int hartId, std::function get_uptime);
84 | void init_callbacks(callback_t update_stimecmp);
85 | void reset();
86 |
87 | word_t read_csr(unsigned int addr, bool &valid);
88 | word_t read_csr(unsigned int addr);
89 | bool write_csr(unsigned int addr, word_t value);
90 |
91 | word_t *get_csr_ptr(unsigned int addr);
92 | const word_t *get_csr_ptr_readonly(unsigned int addr) const;
93 |
94 | bool pmp_check_r(word_t addr, int len);
95 | bool pmp_check_w(word_t addr, int len);
96 | bool pmp_check_x(word_t addr, int len);
97 | }; // class RVCSR
98 |
99 | } // namespace kxemu::cpu
100 |
101 | #endif
102 |
--------------------------------------------------------------------------------
/include/cpu/riscv/local-include/inst-list.h:
--------------------------------------------------------------------------------
1 | #include "config/config.h"
2 |
3 | #define _INST(name) void do_##name();
4 |
5 | _INST(add)
6 | _INST(sub)
7 | _INST(and)
8 | _INST(or)
9 | _INST(xor)
10 | _INST(sll)
11 | _INST(srl)
12 | _INST(sra)
13 | _INST(slt)
14 | _INST(sltu)
15 |
16 | _INST(addi)
17 | _INST(andi)
18 | _INST(ori)
19 | _INST(xori)
20 | _INST(slli)
21 | _INST(srli)
22 | _INST(srai)
23 | _INST(slti)
24 | _INST(sltiu)
25 |
26 | _INST(lb)
27 | _INST(lbu)
28 | _INST(lh)
29 | _INST(lhu)
30 | _INST(lw)
31 |
32 | _INST(sb)
33 | _INST(sh)
34 | _INST(sw)
35 |
36 | _INST(beq)
37 | _INST(bge)
38 | _INST(bgeu)
39 | _INST(blt)
40 | _INST(bltu)
41 | _INST(bne)
42 |
43 | _INST(jal)
44 | _INST(jalr)
45 |
46 | _INST(lui)
47 | _INST(auipc)
48 |
49 | // RV64 only
50 | #ifdef KXEMU_ISA64
51 | _INST(addw)
52 | _INST(subw)
53 | _INST(sllw)
54 | _INST(srlw)
55 | _INST(sraw)
56 |
57 | _INST(addiw)
58 | _INST(slliw)
59 | _INST(srliw)
60 | _INST(sraiw)
61 |
62 | _INST(lwu)
63 | _INST(ld)
64 |
65 | _INST(sd)
66 | #endif
67 |
68 | // Integer multiplication and division extension
69 | _INST(mul)
70 | _INST(mulh)
71 | _INST(mulhsu)
72 | _INST(mulhu)
73 | _INST(div)
74 | _INST(divu)
75 | _INST(rem)
76 | _INST(remu)
77 |
78 | // RV64 only
79 | #ifdef KXEMU_ISA64
80 | _INST(mulw)
81 | _INST(divw)
82 | _INST(divuw)
83 | _INST(remw)
84 | _INST(remuw)
85 | #endif
86 |
87 | // Atomic extension
88 | _INST(lr_w)
89 | _INST(sc_w)
90 | _INST(amoswap_w)
91 | _INST(amoadd_w)
92 | _INST(amoxor_w)
93 | _INST(amoand_w)
94 | _INST(amoor_w)
95 | _INST(amomin_w)
96 | _INST(amomax_w)
97 | _INST(amominu_w)
98 | _INST(amomaxu_w)
99 | #ifdef KXEMU_ISA64
100 | _INST(lr_d)
101 | _INST(sc_d)
102 | _INST(amoswap_d)
103 | _INST(amoadd_d)
104 | _INST(amoxor_d)
105 | _INST(amoand_d)
106 | _INST(amoor_d)
107 | _INST(amomin_d)
108 | _INST(amomax_d)
109 | _INST(amominu_d)
110 | _INST(amomaxu_d)
111 | #endif
112 |
113 | // Compressed extension
114 | _INST(c_lwsp)
115 | _INST(c_swsp)
116 |
117 | _INST(c_lw)
118 | _INST(c_sw)
119 |
120 | _INST(c_j)
121 | _INST(c_jal)
122 | _INST(c_jr)
123 | _INST(c_jalr)
124 |
125 | _INST(c_beqz)
126 | _INST(c_bnez)
127 |
128 | _INST(c_li)
129 | _INST(c_lui)
130 |
131 | _INST(c_addi)
132 | _INST(c_addi16sp)
133 | _INST(c_addi4spn)
134 |
135 | _INST(c_slli)
136 | _INST(c_srli)
137 | _INST(c_srai)
138 | _INST(c_andi)
139 |
140 | _INST(c_mv)
141 | _INST(c_add)
142 | _INST(c_sub)
143 | _INST(c_xor)
144 | _INST(c_or)
145 | _INST(c_and)
146 | _INST(c_nop)
147 |
148 | #ifdef KXEMU_ISA64
149 | _INST(c_ldsp)
150 | _INST(c_sdsp)
151 |
152 | _INST(c_ld)
153 | _INST(c_sd)
154 |
155 | _INST(c_addiw)
156 | _INST(c_addw)
157 | _INST(c_subw)
158 | #endif
159 |
160 | // Privileged mode
161 | _INST(ecall)
162 | _INST(mret)
163 | _INST(sret)
164 | _INST(ebreak)
165 | _INST(wfi)
166 |
167 | _INST(sfence_vma)
168 |
169 | // Zicsr exntension
170 | _INST(csrrw)
171 | _INST(csrrs)
172 | _INST(csrrc)
173 | _INST(csrrwi)
174 | _INST(csrrsi)
175 | _INST(csrrci)
176 |
177 | #undef _INST
178 |
--------------------------------------------------------------------------------
/include/cpu/word.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_CPU_WORD_H__
2 | #define __KXEMU_CPU_WORD_H__
3 |
4 | #include "config/config.h"
5 |
6 | #include
7 |
8 | namespace kxemu::cpu {
9 | #ifdef KXEMU_ISA64
10 | using word_t = uint64_t;
11 | using sword_t = int64_t;
12 | using dword_t = unsigned __int128;
13 | using sdword_t = __int128;
14 | #else
15 | using word_t = uint32_t;
16 | using sword_t = int32_t;
17 | using dword_t = uint64_t;
18 | using sdword_t = int64_t;
19 | #endif
20 | }
21 |
22 | #endif
23 |
--------------------------------------------------------------------------------
/include/debug.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_DEBUG_H__
2 | #define __KXEMU_DEBUG_H__
3 |
4 | #include "macro.h"
5 | #include
6 | #include
7 |
8 | #define SELF_PROTECT(cond, ...) \
9 | do { \
10 | if (unlikely(!(cond))) { \
11 | fprintf(stderr, FMT_FG_RED "[SELF-PROTECT][%s:%d %s]\nASSERT FAILED: %s\nThere must be wrong in your implemention. Please check.\n",\
12 | __FILE__, __LINE__, __func__, #cond); \
13 | fprintf(stderr, __VA_ARGS__); \
14 | fprintf(stderr, FMT_FG_RESET "\n"); \
15 | exit(1); \
16 | } \
17 | } while(0);
18 |
19 | #define NOT_IMPLEMENTED() \
20 | do { \
21 | printf(FMT_FG_RED "[NOT-IMPLEMENTED][%s:%d %s]\nNot implemented yet.\n" FMT_FG_RESET, __FILE__, __LINE__, __func__); \
22 | exit(1); \
23 | } while(0);
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/include/device/bus.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_DEVICE_BUS_H__
2 | #define __KXEMU_DEVICE_BUS_H__
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | namespace kxemu::device {
9 |
10 | using word_t = uint64_t;
11 |
12 | enum AMO {
13 | AMO_SWAP,
14 | AMO_ADD,
15 | AMO_AND,
16 | AMO_OR,
17 | AMO_XOR,
18 | AMO_MIN,
19 | AMO_MAX,
20 | AMO_MINU,
21 | AMO_MAXU
22 | };
23 |
24 | class MemoryMap {
25 | public:
26 | virtual ~MemoryMap() {};
27 |
28 | virtual word_t read(word_t offset, int size) = 0;
29 | virtual bool write(word_t offset, word_t data, int size) = 0;
30 |
31 | virtual word_t do_atomic(word_t addr, word_t data, int size, AMO amo, bool &valid) {
32 | valid = false;
33 | return 0;
34 | }
35 |
36 | virtual uint8_t *get_ptr(word_t offset) = 0;
37 |
38 | virtual const char *get_type_name() const = 0;
39 | };
40 |
41 | class Bus {
42 | public:
43 | ~Bus();
44 |
45 | struct MapBlock {
46 | std::string name;
47 | word_t start;
48 | word_t length;
49 | MemoryMap *map;
50 | };
51 | std::vector memoryMaps;
52 | MapBlock *match_map(word_t addr, word_t size = 0) const;
53 | bool add_memory_map(const std::string &name, word_t start, word_t length, MemoryMap *map);
54 | void free_all();
55 |
56 | word_t read(word_t addr, unsigned int size, bool &valid) const;
57 | bool write(word_t addr, word_t data, int size);
58 |
59 | word_t do_atomic(word_t addr, word_t data, int size, AMO amo, bool &valid);
60 |
61 | bool load_from_stream(std::istream &stream, word_t addr);
62 | bool load_from_stream(std::istream &stream, word_t addr, word_t length);
63 | bool load_from_memory(const uint8_t *src, word_t addr, word_t length);
64 |
65 | bool dump(std::ostream &stream, word_t addr, word_t length) const;
66 |
67 | bool memset(word_t addr, word_t length, uint8_t byte);
68 | uint8_t *get_ptr(word_t addr) const;
69 | word_t get_ptr_length(word_t addr) const;
70 | };
71 |
72 | } // namespace kxemu::device
73 |
74 | #endif
75 |
--------------------------------------------------------------------------------
/include/device/memory.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_DEVICE_MEMORY_H__
2 | #define __KXEMU_DEVICE_MEMORY_H__
3 |
4 | #include "device/bus.h"
5 |
6 | namespace kxemu::device {
7 |
8 | class Memory : public MemoryMap {
9 | private:
10 | uint64_t length;
11 | public:
12 | Memory(uint64_t length);
13 | ~Memory();
14 |
15 | word_t read(word_t addr, int size) override;
16 | bool write(word_t addr, word_t data, int size) override;
17 | uint8_t *get_ptr(word_t addr) override;
18 | const char *get_type_name() const override;
19 |
20 | uint8_t *data;
21 |
22 | word_t do_atomic(word_t addr, word_t data, int size, AMO amo, bool &valid) override;
23 | };
24 |
25 | } // namespace kxemu::device
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/include/device/uart.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_DEVICE_UART_H__
2 | #define __KXEMU_DEVICE_UART_H__
3 |
4 | #include "device/bus.h"
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #define UART_LENGTH 8
14 |
15 | namespace kxemu::device {
16 |
17 | class Uart16650: public MemoryMap {
18 | public:
19 | word_t read(word_t offset, int size) override;
20 | bool write(word_t offset, word_t data, int size) override;
21 | uint8_t *get_ptr(word_t offset) override;
22 | const char *get_type_name() const override;
23 |
24 | bool putch(uint8_t data);
25 | void set_output_stream(std::ostream &os); // send data to stream
26 | bool open_socket(const std::string &ip, int port); // open socket to send and receive data
27 |
28 | enum Mode {
29 | NONE,
30 | STREAM,
31 | SOCKET,
32 | };
33 |
34 | ~Uart16650();
35 |
36 | private:
37 | int mode = Mode::NONE;
38 | std::ostream *stream = nullptr;
39 |
40 | int sendSocket = -1;
41 | int recvSocket = -1;
42 |
43 | std::atomic uartSocketRunning;
44 | std::thread *recvThread;
45 | void recv_thread_loop();
46 |
47 | std::mutex mtx;
48 | std::queue queue; // FIFO buffer
49 |
50 | void send_byte(uint8_t c);
51 |
52 | // Divisor Latch Register
53 | // [0-7] RW - Divisor Latch
54 | uint8_t lsb = 0x00; // Divisor Latch Low
55 | uint8_t msb = 0x00; // Divisor Latch High
56 |
57 | // Interrupt Enable Register
58 | // [0] RW - Enable Received Data Available Interrupt
59 | // [1] RW - Enable Transmitter Holding Register Empty Interrupt
60 | // [2] RW - Enable Receiver Line Status Interrupt
61 | // [3] RW - Enable Modem Status Interrupt
62 | // [4-7] RW - Reserved
63 | uint8_t ier = 0b00000000; // reset value
64 |
65 | // Interrupt Identification Register
66 | // [0-3] R - Interrupt Identification
67 | // [4-5] R - 0
68 | // [6-7] R - 1
69 | uint8_t iir = 0b11000001; // reset value
70 |
71 | // FIFO Control Register
72 | // [0] W - Ignored
73 | // [1] W - Clear Receive FIFO
74 | // [2] W - Clear Transmit FIFO
75 | // [3-5] W - Ignored
76 | // [6-7] R - Receiver FIFO Trigger Level
77 | uint8_t fcr = 0b11000000; // reset value
78 |
79 | // Line Control Register
80 | // [0-1] RW - Word Length
81 | // [2] RW - Stop Bit
82 | // [3] RW - Parity Enable
83 | // [4] RW - Parity Type
84 | // [5] RW - Strick Parity
85 | // [6] RW - Break Control
86 | // [7] RW - Divisor Latch Access Bit
87 | uint8_t lcr = 0b00000011; // reset value
88 |
89 | // Line Status Register
90 | // [0] R - Data Ready
91 | // [1] R - Overrun Error
92 | // [2] R - Parity Error
93 | // [3] R - Framing Error
94 | // [4] R - Break Interrupt
95 | // [5] R - Transmitter Holding Register Empty
96 | // [6] R - Transmitter Empty
97 | // [7] R - FIFO Data Error
98 | uint8_t lsr;
99 |
100 | // NOTE: The following registers are not implemented
101 | // Modem Status Register
102 | // [0] R - Delta Clear to Send
103 | // [1] R - Delta Data Set Ready
104 | // [2] R - Trailing Edge Ring Indicator
105 | // [3] R - Delta Data Carrier Detect
106 | uint8_t msr;
107 | };
108 |
109 | } // namespace kxemu::device
110 |
111 | #endif
112 |
--------------------------------------------------------------------------------
/include/isa/isa.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_ISA_ISA_H__
2 | #define __KXEMU_ISA_ISA_H__
3 |
4 | #include "config/config.h"
5 | #include "cpu/cpu.h"
6 |
7 | #include
8 | #include
9 |
10 | namespace kxemu::isa {
11 | #if defined(KXEMU_ISA32)
12 | using word_t = uint32_t;
13 | #elif defined(KXEMU_ISA64)
14 | using word_t = uint64_t;
15 | #endif
16 |
17 | void init();
18 |
19 | // ISA information
20 | const char *get_isa_name();
21 | int get_elf_expected_machine();
22 |
23 | cpu::CPU *new_cpu();
24 |
25 | // Register
26 | unsigned int get_gpr_count();
27 | const char *get_gpr_name(int idx);
28 |
29 | // Disassemble
30 | unsigned int get_max_inst_len();
31 | std::string disassemble(const uint8_t *data, const uint64_t dataSize, const word_t pc, uint64_t &instLen);
32 | } // namespace kxemu::isa
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/include/isa/riscv/isa.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_ISA_RISCV32_ISA_H__
2 | #define __KXEMU_ISA_RISCV32_ISA_H__
3 |
4 | enum RVFlag {
5 | E = 1 << 0,
6 | C = 1 << 1,
7 | M = 1 << 2,
8 | A = 1 << 3,
9 | Zicsr = 1 << 4,
10 | Priv = 1 << 5,
11 | };
12 |
13 | #endif
14 |
--------------------------------------------------------------------------------
/include/isa/word.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_ISA_WORD_H__
2 | #define __KXEMU_ISA_WORD_H__
3 |
4 | // DO NOT include this file in the other header files
5 |
6 | #include "config/config.h"
7 | #include
8 | #include
9 |
10 | #define FMT_WORD32 "0x%08" PRIx32
11 | #define FMT_WORD64 "0x%016" PRIx64
12 | #define FMT_HEX32 "0x%" PRIx32
13 | #define FMT_HEX64 "0x%" PRIx64
14 | #define FMT_VARU32 "%" PRIu32
15 | #define FMT_VARU64 "%" PRIu64
16 |
17 | #ifdef KXEMU_ISA64
18 | #define FMT_WORD FMT_WORD64
19 | #define FMT_VARU FMT_VARU64
20 | #define WORD_BITS 64
21 | #define WORD_WIDTH 16
22 | #else
23 | #define FMT_WORD FMT_WORD32
24 | #define FMT_VARU FMT_VARU32
25 | #define WORD_BITS 32
26 | #define WORD_WIDTH 8
27 | #endif // KXEMU_ISA64
28 |
29 | #define FMT_STREAM_WORD(word) "0x" << std::hex << std::setfill('0') << word << std::dec
30 |
31 | #endif
--------------------------------------------------------------------------------
/include/kdb/cmd.h:
--------------------------------------------------------------------------------
1 | /***************************************************************
2 | * Project Name: KXemu
3 | * File Name: include/kdb/cmd.h
4 | * Description: Define functions for kdb command line interface.
5 | Command line is just an interface for user to interact with the system and the KDB.
6 | Only do such things in the cmd::* functions:
7 | 1. Parse the arguments from the user input.
8 | 2. Open file stream and pass the stream to the corresponding functions.
9 | 3. Call the corresponding functions to do the real work.
10 | 4. Return the result code to the caller.
11 | ***************************************************************/
12 |
13 | #ifndef __KXEMU_KDB_CMD_H__
14 | #define __KXEMU_KDB_CMD_H__
15 |
16 | #include "kdb/kdb.h"
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | namespace kxemu::kdb::cmd {
24 | using args_t = std::vector;
25 | using func_t = int (*)(const args_t &);
26 | using cmd_map_t = std::unordered_map;
27 | int find_and_run(const args_t &args, const cmd_map_t &cmdMap, std::size_t startArgs = 0);
28 |
29 | // do command function
30 | int log (const args_t &);
31 | int mem (const args_t &);
32 | int help (const args_t &);
33 | int quit (const args_t &);
34 | int source (const args_t &);
35 | int reset (const args_t &);
36 | int step (const args_t &);
37 | int run (const args_t &);
38 | int symbol (const args_t &); // print symbol table from ELF
39 | int load (const args_t &); // load image from filename given by args
40 | int info (const args_t &); // print info of cpu
41 | int uart (const args_t &); // uart command
42 | int breakpoint(const args_t &); // set breakpoint
43 | int show_mem(const args_t &);
44 |
45 | // do command return code
46 | enum Code {
47 | EmptyArgs = -2,
48 | CmdNotFound = -1,
49 | Success = 0,
50 | InvalidArgs = 1,
51 | MissingPrevOp = 2,
52 | CmdError = 3
53 | };
54 |
55 | // load source from args
56 | extern std::string elfFileName;
57 |
58 | extern cpu::Core *currentCore; // command line current cpu core
59 | extern int coreCount; // core count of cpu
60 |
61 | using completion_func_t = std::vector (*)(); // return possible list
62 | void init_completion();
63 | namespace completion {
64 | std::vector log_off();
65 | };
66 | } // cmd
67 |
68 | #endif // __KDB_CMD_H__
69 |
--------------------------------------------------------------------------------
/include/kdb/kdb.h:
--------------------------------------------------------------------------------
1 | #ifndef __KXEMU_KDB_KDB_H__
2 | #define __KXEMU_KDB_KDB_H__
3 |
4 | #include "device/uart.h"
5 | #include "cpu/cpu.h"
6 | #include "device/bus.h"
7 | #include "isa/isa.h"
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include