Compare commits
3 commits
18db852763
...
4478f49549
Author | SHA1 | Date | |
---|---|---|---|
4478f49549 | |||
8545a92c1f | |||
da0c42422d |
32 changed files with 575 additions and 74 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -10,4 +10,5 @@
|
||||||
!init.sh
|
!init.sh
|
||||||
/fceux-am
|
/fceux-am
|
||||||
/nvboard
|
/nvboard
|
||||||
/am-kernels
|
**/.cache
|
||||||
|
**/result
|
||||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "am-kernels"]
|
||||||
|
path = am-kernels
|
||||||
|
url = ./am-kernels/
|
25
abstract-machine/.gitignore
vendored
25
abstract-machine/.gitignore
vendored
|
@ -1,19 +1,6 @@
|
||||||
*
|
**/.direnv/
|
||||||
!*/
|
**/build/
|
||||||
!*.h
|
**/.envrc
|
||||||
!*.c
|
**/.cache
|
||||||
!*.cc
|
.vscode
|
||||||
!*.S
|
compile_commands.json
|
||||||
!*.ld
|
|
||||||
!*.sh
|
|
||||||
!*.py
|
|
||||||
!*.mk
|
|
||||||
!Makefile
|
|
||||||
!README
|
|
||||||
!LICENSE
|
|
||||||
.*
|
|
||||||
_*
|
|
||||||
*~
|
|
||||||
build/
|
|
||||||
!.gitignore
|
|
||||||
.vscode
|
|
||||||
|
|
87
abstract-machine/CMakeLists.txt
Normal file
87
abstract-machine/CMakeLists.txt
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
|
project(abstract-machine)
|
||||||
|
enable_language(CXX C ASM)
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
|
include(CMakeDependentOption)
|
||||||
|
include(CMakePackageConfigHelpers) # Used to find libcheck
|
||||||
|
include(CTest)
|
||||||
|
|
||||||
|
# -- General options
|
||||||
|
set(ISA CACHE STRING "Target ISA")
|
||||||
|
set_property(CACHE ISA PROPERTY STRINGS "riscv" "x86" "x86_64" "native")
|
||||||
|
string(TOUPPER ${ISA} ISA_UPPER)
|
||||||
|
|
||||||
|
cmake_dependent_option(
|
||||||
|
__PLATFORM_NEMU__ "Run on NEMU"
|
||||||
|
ON "ISA MATCHES \"(riscv | x86)\"" OFF)
|
||||||
|
cmake_dependent_option(
|
||||||
|
__PLATFORM_NATIVE__ "Run on native"
|
||||||
|
ON "ISA MATCHES native" OFF)
|
||||||
|
|
||||||
|
# -- Set PLATFORM according to options
|
||||||
|
set(MATCH_PLATFORM_PATTERN "^__PLATFORM_([A-Z]*)__")
|
||||||
|
get_cmake_property(CACHE_VARS CACHE_VARIABLES)
|
||||||
|
|
||||||
|
message(STATUS "ISA: ${ISA}")
|
||||||
|
foreach(VAR IN LISTS CACHE_VARS)
|
||||||
|
if(VAR MATCHES ${MATCH_PLATFORM_PATTERN})
|
||||||
|
# Retrieve the value of the cache variable
|
||||||
|
get_property(VAR_VALUE CACHE ${VAR} PROPERTY VALUE)
|
||||||
|
set(PLATFORM_UPPER ${CMAKE_MATCH_1})
|
||||||
|
string(TOLOWER ${PLATFORM_UPPER} PLATFORM)
|
||||||
|
message(STATUS "Variable: ${VAR}=${VAR_VALUE}, Platform: ${PLATFORM}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(${PLATFORM} MATCHES "native")
|
||||||
|
set(ARCH "native")
|
||||||
|
else()
|
||||||
|
set(ARCH ${ISA}-${PLATFORM})
|
||||||
|
endif()
|
||||||
|
string(TOUPPER ${ARCH} ARCH_UPPER)
|
||||||
|
|
||||||
|
# -- Target specific options
|
||||||
|
cmake_dependent_option(
|
||||||
|
NATIVE_USE_KLIB "Use Klib even if on native"
|
||||||
|
ON "NOT __ISA_NATIVE__" OFF)
|
||||||
|
|
||||||
|
# -- Add compile definitions based on options
|
||||||
|
add_compile_definitions(
|
||||||
|
$<MAKE_C_IDENTIFIER:__ARCH_${ARCH_UPPER}__>
|
||||||
|
__ISA_${ISA_UPPER}__
|
||||||
|
__PLATFORM_${PLATFORM_UPPER}__
|
||||||
|
)
|
||||||
|
|
||||||
|
add_compile_definitions(
|
||||||
|
$<$<BOOL:${NATIVE_USE_KLIB}>:__NATIVE_USE_KLIB__>
|
||||||
|
)
|
||||||
|
|
||||||
|
# -- Required compiler flags
|
||||||
|
add_compile_options(
|
||||||
|
# -Werror
|
||||||
|
-Wno-main
|
||||||
|
-fno-asynchronous-unwind-tables
|
||||||
|
-fno-builtin
|
||||||
|
-fno-stack-protector
|
||||||
|
-U_FORTIFY_SOURCE
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:-ffreestanding>
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>)
|
||||||
|
|
||||||
|
add_link_options(
|
||||||
|
-znoexecstack
|
||||||
|
)
|
||||||
|
|
||||||
|
# -- Include linker script here. Use this linker script at link time if INCLUDE_LINKER_SCRIPT is set to true
|
||||||
|
set(LINKER_SCRIPT linker.ld)
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
add_compile_options(-march=rv32if -mabi=ilp32)
|
||||||
|
add_link_options(-march=rv32if -mabi=ilp32)
|
||||||
|
|
||||||
|
add_subdirectory(klib)
|
||||||
|
add_subdirectory(am)
|
29
abstract-machine/CMakePresets.json
Normal file
29
abstract-machine/CMakePresets.json
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"version": 6,
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "native",
|
||||||
|
"displayName": "Native",
|
||||||
|
"generator": "Unix Makefiles",
|
||||||
|
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"ISA": "native",
|
||||||
|
"__PLATFORM_NATIVE__": true,
|
||||||
|
"NATIVE_USE_KLIB": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "riscv-nemu",
|
||||||
|
"displayName": "Riscv32 NEMU",
|
||||||
|
"generator": "Unix Makefiles",
|
||||||
|
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||||
|
"installDir": "/home/xin/repo/ysyx-workbench/abstract-machine/out/install",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"ISA": "riscv",
|
||||||
|
"__PLATFORM_NEMU__": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
10
abstract-machine/am/CMakeLists.txt
Normal file
10
abstract-machine/am/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
|
add_library(am_interface INTERFACE)
|
||||||
|
target_include_directories(am_interface INTERFACE
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
|
$<INSTALL_INTERFACE:include/abstract-machine>)
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
install(DIRECTORY include/ DESTINATION include/abstract-machine)
|
53
abstract-machine/am/src/CMakeLists.txt
Normal file
53
abstract-machine/am/src/CMakeLists.txt
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
if(ISA MATCHES "native")
|
||||||
|
set(SOURCEDIR "./${PLATFORM}")
|
||||||
|
else()
|
||||||
|
set(SOURCEDIR "./${ISA}/${PLATFORM}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(${SOURCEDIR})
|
||||||
|
|
||||||
|
target_include_directories(am-${ARCH}
|
||||||
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
||||||
|
$<INSTALL_INTERFACE:include/abstract-machine>)
|
||||||
|
target_link_libraries(am-${ARCH}
|
||||||
|
PUBLIC klib_interface
|
||||||
|
INTERFACE m)
|
||||||
|
|
||||||
|
# TODO: Check
|
||||||
|
target_link_options(am-${ARCH} INTERFACE
|
||||||
|
$<BUILD_INTERFACE:-T${CMAKE_SOURCE_DIR}/scripts/${LINKER_SCRIPT}>
|
||||||
|
$<INSTALL_INTERFACE:-T${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH}/${LINKER_SCRIPT}>)
|
||||||
|
|
||||||
|
# Interface compile flags
|
||||||
|
target_link_options(am-${ARCH} INTERFACE
|
||||||
|
-znoexecstack)
|
||||||
|
|
||||||
|
target_compile_options(am-${ARCH} INTERFACE
|
||||||
|
-fno-asynchronous-unwind-tables
|
||||||
|
-fno-builtin
|
||||||
|
-fno-stack-protector
|
||||||
|
-U_FORTIFY_SOURCE
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:-ffreestanding>
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>)
|
||||||
|
|
||||||
|
install(TARGETS am-${ARCH} klib_interface am_interface
|
||||||
|
EXPORT amTargets
|
||||||
|
LIBRARY DESTINATION lib)
|
||||||
|
|
||||||
|
install(EXPORT amTargets
|
||||||
|
FILE amTargets.cmake
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH})
|
||||||
|
|
||||||
|
configure_package_config_file(${CMAKE_SOURCE_DIR}/cmake/am-config.cmake.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/am-${ARCH}-config.cmake
|
||||||
|
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH})
|
||||||
|
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/am-${ARCH}-config.cmake
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH})
|
||||||
|
|
||||||
|
# TODO: check
|
||||||
|
install(FILES ${CMAKE_SOURCE_DIR}/scripts/${LINKER_SCRIPT}
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH})
|
26
abstract-machine/am/src/native/CMakeLists.txt
Normal file
26
abstract-machine/am/src/native/CMakeLists.txt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
include(CheckPIESupported)
|
||||||
|
check_pie_supported()
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
trap.S
|
||||||
|
cte.c
|
||||||
|
ioe.c
|
||||||
|
mpe.c
|
||||||
|
platform.c
|
||||||
|
trm.c
|
||||||
|
vme.c
|
||||||
|
ioe/audio.c
|
||||||
|
ioe/disk.c
|
||||||
|
ioe/gpu.c
|
||||||
|
ioe/input.c
|
||||||
|
ioe/timer.c
|
||||||
|
)
|
||||||
|
add_library(am-native ${SOURCES})
|
||||||
|
|
||||||
|
# FIXME: get free(): invalid address when user program compiled without pie
|
||||||
|
set_target_properties(am-native PROPERTIES
|
||||||
|
POSITION_INDEPENDENT_CODE TRUE
|
||||||
|
INTERFACE_POSITION_INDEPENDENT_CODE TRUE)
|
||||||
|
|
||||||
|
find_package(SDL2 REQUIRED)
|
||||||
|
target_link_libraries(am-${ARCH} PUBLIC SDL2::SDL2)
|
34
abstract-machine/am/src/riscv/nemu/CMakeLists.txt
Normal file
34
abstract-machine/am/src/riscv/nemu/CMakeLists.txt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
include(nemu-settings)
|
||||||
|
include(riscv-settings)
|
||||||
|
|
||||||
|
add_library(am-${ISA}-nemu
|
||||||
|
cte.c
|
||||||
|
start.S
|
||||||
|
trap.S
|
||||||
|
vme.c
|
||||||
|
${NEMU_SOURCES}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(am-${ISA}-nemu PRIVATE
|
||||||
|
${NEMU_COMPILE_OPTIONS}
|
||||||
|
${RISCV_COMPILE_OPTIONS})
|
||||||
|
target_link_options(am-${ISA}-nemu PRIVATE
|
||||||
|
${NEMU_LINK_OPITIONS}
|
||||||
|
${RISCV_LINK_OPTIONS})
|
||||||
|
target_include_directories(am-${ISA}-nemu PRIVATE
|
||||||
|
${NEMU_INCLUDE_DIRECTORIES})
|
||||||
|
target_link_options(am-${ISA}-nemu INTERFACE
|
||||||
|
LINKER:--defsym=_pmem_start=0x80000000
|
||||||
|
LINKER:--defsym=_entry_offset=0x0
|
||||||
|
LINKER:--gc-sections
|
||||||
|
LINKER:-e _start
|
||||||
|
-nostartfiles)
|
||||||
|
|
||||||
|
target_compile_definitions(am-${ISA}-nemu PUBLIC
|
||||||
|
ARCH_H="arch/riscv.h")
|
||||||
|
target_compile_definitions(am-${ISA}-nemu PRIVATE
|
||||||
|
ISA_H="riscv/riscv.h")
|
||||||
|
|
||||||
|
set_target_properties(am-${ISA}-nemu PROPERTIES
|
||||||
|
POSITION_INDEPENDENT_CODE OFF
|
||||||
|
INTERFACE_POSITION_INDEPENDENT_CODE OFF)
|
9
abstract-machine/cmake/am-config.cmake.in
Normal file
9
abstract-machine/cmake/am-config.cmake.in
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
if(${ARCH} MATCHES "native")
|
||||||
|
find_dependency(SDL2 REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Include the targets file
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/amTargets.cmake")
|
6
abstract-machine/cmake/klib-config.cmake.in
Normal file
6
abstract-machine/cmake/klib-config.cmake.in
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
|
||||||
|
# Include the targets file
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/klibTargets.cmake")
|
11
abstract-machine/cmake/nemu-settings.cmake
Normal file
11
abstract-machine/cmake/nemu-settings.cmake
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
set(NEMU_COMPILE_OPTIONS -fdata-sections -ffunction-sections)
|
||||||
|
set(NEMU_LINK_OPTIONS
|
||||||
|
--defsym=_pmem_start=0x80000000
|
||||||
|
--defsym=_entry_offset=0x0
|
||||||
|
--gc-sections
|
||||||
|
-e _start)
|
||||||
|
set(NEMU_INCLUDE_DIRECTORIES
|
||||||
|
${CMAKE_SOURCE_DIR}/am/src/platform/nemu/include)
|
||||||
|
file(GLOB_RECURSE NEMU_SOURCES
|
||||||
|
${CMAKE_SOURCE_DIR}/am/src/platform/nemu/*.[cS])
|
||||||
|
set(INCLUDE_LINKER_SCRIPT ON)
|
2
abstract-machine/cmake/riscv-settings.cmake
Normal file
2
abstract-machine/cmake/riscv-settings.cmake
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
set(RISCV_COMPILE_OPTIONS)
|
||||||
|
set(RISCV_LINK_OPTIONS)
|
26
abstract-machine/default.nix
Normal file
26
abstract-machine/default.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ stdenv,
|
||||||
|
lib,
|
||||||
|
cmake,
|
||||||
|
SDL2,
|
||||||
|
isa ? "native",
|
||||||
|
platform ? "NEMU"
|
||||||
|
}:
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "abstract-machine";
|
||||||
|
version = "2024.02.18";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
cmakeFlags = [
|
||||||
|
(lib.cmakeFeature "ISA" isa)
|
||||||
|
(lib.cmakeBool "__PLATFORM_${lib.strings.toUpper platform}__" true)
|
||||||
|
];
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
cmake
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
|
||||||
|
] ++ (if platform=="native" then [ SDL2 ] else [ ]);
|
||||||
|
}
|
12
abstract-machine/klib/CMakeLists.txt
Normal file
12
abstract-machine/klib/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
|
add_library(klib_interface INTERFACE)
|
||||||
|
target_include_directories(klib_interface
|
||||||
|
INTERFACE
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
|
$<INSTALL_INTERFACE:include/abstract-machine>)
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
||||||
|
# add_subdirectory(tests)
|
||||||
|
|
||||||
|
install(DIRECTORY include/ DESTINATION include/abstract-machine)
|
|
@ -35,6 +35,7 @@ int atoi (const char *nptr);
|
||||||
int printf (const char *format, ...);
|
int printf (const char *format, ...);
|
||||||
int sprintf (char *str, const char *format, ...);
|
int sprintf (char *str, const char *format, ...);
|
||||||
int snprintf (char *str, size_t size, const char *format, ...);
|
int snprintf (char *str, size_t size, const char *format, ...);
|
||||||
|
int vprintf (const char *format, va_list ap);
|
||||||
int vsprintf (char *str, const char *format, va_list ap);
|
int vsprintf (char *str, const char *format, va_list ap);
|
||||||
int vsnprintf (char *str, size_t size, const char *format, va_list ap);
|
int vsnprintf (char *str, size_t size, const char *format, va_list ap);
|
||||||
|
|
||||||
|
|
33
abstract-machine/klib/src/CMakeLists.txt
Normal file
33
abstract-machine/klib/src/CMakeLists.txt
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# find_package(FLEX)
|
||||||
|
# find_package(BISON)
|
||||||
|
|
||||||
|
# FLEX_TARGET(fmt_scanner fmt_scanner.l fmt_scanner.c)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
cpp.c
|
||||||
|
int64.c
|
||||||
|
stdio.c
|
||||||
|
stdlib.c
|
||||||
|
string.c
|
||||||
|
# ${FLEX_fmt_scanner_OUTPUTS}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(klib ${SOURCES})
|
||||||
|
target_include_directories(klib PUBLIC $<TARGET_PROPERTY:am_interface,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||||
|
target_compile_definitions(klib PUBLIC $<TARGET_PROPERTY:am-${ARCH},INTERFACE_COMPILE_DEFINITIONS>)
|
||||||
|
|
||||||
|
install(TARGETS klib
|
||||||
|
EXPORT klibTargets
|
||||||
|
LIBRARY DESTINATION lib)
|
||||||
|
|
||||||
|
install(EXPORT klibTargets
|
||||||
|
FILE klibTargets.cmake
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)
|
||||||
|
|
||||||
|
configure_package_config_file(${CMAKE_SOURCE_DIR}/cmake/klib-config.cmake.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/klib-config.cmake
|
||||||
|
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)
|
||||||
|
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/klib-config.cmake
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)
|
||||||
|
|
|
@ -5,8 +5,20 @@
|
||||||
|
|
||||||
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
||||||
|
|
||||||
|
int vprintf(const char *fmt, va_list ap) {
|
||||||
|
const char *p = fmt;
|
||||||
|
while(*p != '\0') {
|
||||||
|
putch(*p);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int printf(const char *fmt, ...) {
|
int printf(const char *fmt, ...) {
|
||||||
panic("Not implemented");
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vprintf(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vsprintf(char *out, const char *fmt, va_list ap) {
|
int vsprintf(char *out, const char *fmt, va_list ap) {
|
||||||
|
|
|
@ -5,43 +5,115 @@
|
||||||
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
||||||
|
|
||||||
size_t strlen(const char *s) {
|
size_t strlen(const char *s) {
|
||||||
panic("Not implemented");
|
const char *p = s;
|
||||||
|
size_t len = 0;
|
||||||
|
while(*(p++) != '\0') len++;
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strcpy(char *dst, const char *src) {
|
char *strcpy(char *dst, const char *src) {
|
||||||
panic("Not implemented");
|
char *p_dst = dst;
|
||||||
|
const char *p_src = src;
|
||||||
|
for(; *p_src != '\0'; p_src++, p_dst++) {
|
||||||
|
*p_dst = *p_src;
|
||||||
|
}
|
||||||
|
*p_dst = '\0';
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strncpy(char *dst, const char *src, size_t n) {
|
char *strncpy(char *dst, const char *src, size_t n) {
|
||||||
panic("Not implemented");
|
int i = 0;
|
||||||
|
for(; i < n && src[i] != '\0'; i++) {
|
||||||
|
dst[i] = src[i];
|
||||||
|
}
|
||||||
|
for(; i < n; i++) {
|
||||||
|
dst[i] = '\0';
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strcat(char *dst, const char *src) {
|
char *strcat(char *dst, const char *src) {
|
||||||
panic("Not implemented");
|
char *p_dst = dst;
|
||||||
|
const char *p_src = src;
|
||||||
|
while(*p_dst != '\0') p_dst++;
|
||||||
|
for(; *p_src != '\0'; p_src++, p_dst++) {
|
||||||
|
*p_dst = *p_src;
|
||||||
|
}
|
||||||
|
*p_dst = '\0';
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strcmp(const char *s1, const char *s2) {
|
int strcmp(const char *s1, const char *s2) {
|
||||||
panic("Not implemented");
|
const char *p_s1 = s1, *p_s2 = s2;
|
||||||
|
for(; *p_s1 == *p_s2; p_s1++, p_s2++) {
|
||||||
|
if(*p_s1 == '\0' || *p_s2 == '\0') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *p_s1 - *p_s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strncmp(const char *s1, const char *s2, size_t n) {
|
int strncmp(const char *s1, const char *s2, size_t n) {
|
||||||
panic("Not implemented");
|
const char *p_s1 = s1, *p_s2 = s2;
|
||||||
|
int i = 0;
|
||||||
|
for(i = 0; i < n - 1; i++) {
|
||||||
|
if(s1[i] == '\0' || s2[i] == '\0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return s1[i] - s2[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memset(void *s, int c, size_t n) {
|
void *memset(void *s, int c, size_t n) {
|
||||||
panic("Not implemented");
|
uint8_t *p = s;
|
||||||
|
for(int i = 0; i < n; i++) {
|
||||||
|
p[i] = c;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memmove(void *dst, const void *src, size_t n) {
|
void *memmove(void *dst, const void *src, size_t n) {
|
||||||
panic("Not implemented");
|
if (src + n > dst && src < dst) {
|
||||||
|
size_t len = dst - src;
|
||||||
|
void *p_dst = (void *)src + n;
|
||||||
|
const void *p_src = src + n - len;
|
||||||
|
while(p_dst >= dst) {
|
||||||
|
memcpy(p_dst, p_src, len);
|
||||||
|
p_src -= len;
|
||||||
|
p_dst -= len;
|
||||||
|
}
|
||||||
|
if(n % len) memcpy(dst, src, n % len);
|
||||||
|
} else if (dst < src && dst + n > src) {
|
||||||
|
size_t len = src - dst;
|
||||||
|
void *p_dst = dst;
|
||||||
|
const void *p_src = src;
|
||||||
|
while(p_src < src + n) {
|
||||||
|
memcpy(p_dst, p_src, len);
|
||||||
|
p_src += len;
|
||||||
|
p_dst += len;
|
||||||
|
}
|
||||||
|
if(n % len) memcpy(p_dst, p_src, n % len);
|
||||||
|
} else {
|
||||||
|
memcpy(dst, src, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memcpy(void *out, const void *in, size_t n) {
|
void *memcpy(void *out, const void *in, size_t n) {
|
||||||
panic("Not implemented");
|
for (size_t i = 0 ; i < n ; i++) {
|
||||||
|
*(uint8_t *)(out + i) = *(uint8_t *)(in + i);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||||
panic("Not implemented");
|
const uint8_t *p1 = s1, *p2 = s2;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if(*p1 != *p2)
|
||||||
|
return p1 - p2;
|
||||||
|
p1++; p2++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
17
abstract-machine/klib/tests/CMakeLists.txt
Normal file
17
abstract-machine/klib/tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
set(TEST_SOURCES
|
||||||
|
stdio
|
||||||
|
string
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach(TEST IN LISTS TEST_SOURCES)
|
||||||
|
add_executable(${TEST} ${TEST}.c)
|
||||||
|
target_link_libraries(${TEST} am-${ARCH} klib m)
|
||||||
|
target_include_directories(${TEST}
|
||||||
|
PRIVATE $<TARGET_PROPERTY:am_interface,INTERFACE_INCLUDE_DIRECTORIES>
|
||||||
|
PRIVATE $<TARGET_PROPERTY:klib_interface,INTERFACE_INCLUDE_DIRECTORIES>
|
||||||
|
)
|
||||||
|
# TODO: Run tests in other configurations
|
||||||
|
if(__PLATFORM_NATIVE__)
|
||||||
|
add_test(NAME ${TEST} COMMAND ${TEST})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
5
abstract-machine/klib/tests/stdio.c
Normal file
5
abstract-machine/klib/tests/stdio.c
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include <klib.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
75
abstract-machine/klib/tests/string.c
Normal file
75
abstract-machine/klib/tests/string.c
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
#include <klib.h>
|
||||||
|
#include <klib-macros.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void test_strcpy() {
|
||||||
|
char b[32];
|
||||||
|
char *s;
|
||||||
|
b[16]='a'; b[17]='b'; b[18]='c'; b[19]=0;
|
||||||
|
panic_on((s = strcpy(b, b+16)) != b, "strcpy wrong return value");
|
||||||
|
panic_on(strcmp(s, "abc") != 0, "strcpy gave incorrect string");
|
||||||
|
panic_on((s = strcpy(b+1, b+16)) != b+1, "strcpy wrong return value");
|
||||||
|
panic_on(strcmp(s, "abc") != 0, "strcpy gave incorrect string");
|
||||||
|
|
||||||
|
panic_on((s = strcpy(b+1, b+17)) != b+1, "strcpy wrong return value");
|
||||||
|
panic_on(strcmp(s, "bc") != 0, "strcpy gave incorrect string");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_strncpy() {
|
||||||
|
char b[32];
|
||||||
|
char *s;
|
||||||
|
int i;
|
||||||
|
b[3] = 'x'; b[4] = 0;
|
||||||
|
panic_on((s = strncpy(b, "abc", 3)) != b, "strncpy wrong return value");
|
||||||
|
panic_on(b[2] != 'c', "strncpy fails to copy last byte");
|
||||||
|
panic_on(b[3] != 'x', "strncpy overruns buffer to null-terminate");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_strncmp() {
|
||||||
|
panic_on(strncmp("abcd", "abce", 3) != 0, "strncmp compares past n");
|
||||||
|
panic_on(strncmp("abc", "abd", 3) == 0, "strncmp fails to compare n-1st byte");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_memset() {
|
||||||
|
uint8_t arr[128];
|
||||||
|
arr[120] = 0xd;
|
||||||
|
panic_on(memset(arr, 0xf, 120) != arr, "memset wrong return value");
|
||||||
|
panic_on(arr[7] != 0xf, "memset fails to set value in range");
|
||||||
|
panic_on(arr[120] != 0xd, "memset set value past n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_memcpy() {
|
||||||
|
const uint8_t src[] = { 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x0, 0x0 };
|
||||||
|
uint8_t dst[8] = {0};
|
||||||
|
memcpy(dst, src, 8);
|
||||||
|
panic_on(memcmp(dst, src, 8) != 0, "memcpy fails to copy memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_memmove() {
|
||||||
|
const uint8_t ref[] = { 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x0, 0x0 };
|
||||||
|
uint8_t dst[8] = {0};
|
||||||
|
const uint8_t ans1[] = { 0x1, 0x2, 0x3, 0x4, 0x3, 0x4, 0x0, 0x0 };
|
||||||
|
const uint8_t ans2[] = { 0x1, 0x2, 0x2, 0x3, 0x4, 0x3, 0x0, 0x0 };
|
||||||
|
const uint8_t ans3[] = { 0x1, 0x2, 0x2, 0x1, 0x2, 0x2, 0x3, 0x4 };
|
||||||
|
memmove(dst, ref, 8);
|
||||||
|
panic_on(memcmp(dst, ref, 8) != 0, "memmove fails to copy non-overlapping memory");
|
||||||
|
|
||||||
|
memmove(dst, dst + 2, 4);
|
||||||
|
panic_on(memcmp(dst, ans1, 8) != 0, "memmove fails to copy overlapping memory (dst < src)");
|
||||||
|
|
||||||
|
memmove(dst + 2, dst + 1, 4);
|
||||||
|
panic_on(memcmp(dst, ans2, 8) != 0, "memmove fails to copy overlapping memory (src < dst)");
|
||||||
|
|
||||||
|
memmove(dst + 3, dst, 5);
|
||||||
|
panic_on(memcmp(dst, ans3, 8) != 0, "memmove fails to copy overlapping memory (src < dst)");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
test_strcpy();
|
||||||
|
test_strncpy();
|
||||||
|
test_strncmp();
|
||||||
|
test_memset();
|
||||||
|
test_memcpy();
|
||||||
|
test_memmove();
|
||||||
|
return 0;
|
||||||
|
}
|
BIN
abstract-machine/out/install/lib/libklib.a
Normal file
BIN
abstract-machine/out/install/lib/libklib.a
Normal file
Binary file not shown.
1
am-kernels
Submodule
1
am-kernels
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 2f559823a63cf6909d5a9e32dee47d6891caf553
|
60
flake.nix
60
flake.nix
|
@ -12,54 +12,37 @@
|
||||||
localSystem = system;
|
localSystem = system;
|
||||||
crossSystem = {
|
crossSystem = {
|
||||||
config = "riscv32-none-elf";
|
config = "riscv32-none-elf";
|
||||||
abi = "ilp32";
|
gcc = {
|
||||||
|
abi = "ilp32";
|
||||||
|
arch = "rv32if";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
packages.nemu = pkgs.callPackage ./nemu { am-kernels = self.packages.${system}.am-kernels; };
|
packages.nemu = pkgs.callPackage ./nemu { am-kernels = self.packages.${system}.am-kernels-cmake; };
|
||||||
|
packages.abstract-machine = crossPkgs.callPackage ./abstract-machine { isa = "riscv"; platform = "nemu"; };
|
||||||
|
|
||||||
packages.am-kernels = crossPkgs.stdenv.mkDerivation rec {
|
packages.am-kernels-cmake = crossPkgs.stdenv.mkDerivation rec {
|
||||||
pname = "am-kernels";
|
pname = "am-kernels-cmake";
|
||||||
version = "2024.02.18";
|
version = "2024.02.18";
|
||||||
|
|
||||||
src = pkgs.fetchFromGitHub {
|
src = ./am-kernels;
|
||||||
owner = "NJU-ProjectN";
|
|
||||||
repo = "am-kernels";
|
|
||||||
rev = "bb725d6f8223dd7de831c3b692e8c4531e9d01af";
|
|
||||||
hash = "sha256-ZHdrw28TN8cMvhhzM469OV7cp0Yp+8yao855HP4+P4A=";
|
|
||||||
};
|
|
||||||
|
|
||||||
AM_HOME = pkgs.fetchFromGitHub {
|
nativeBuildInputs = [
|
||||||
owner = "xinyangli";
|
pkgs.cmake
|
||||||
repo = "abstract-machine";
|
];
|
||||||
rev = "788595aac61c6b2f3b78ca8aa7d08dc33911bca4";
|
|
||||||
hash = "sha256-YvWHIBP9tz3HL2TyibftvvQrpkWUDPnviCF4oyLmdjg=";
|
|
||||||
};
|
|
||||||
|
|
||||||
ARCH = "riscv32-nemu";
|
cmakeFlags = [
|
||||||
|
(pkgs.lib.cmakeFeature "ISA" "riscv")
|
||||||
|
(pkgs.lib.cmakeFeature "PLATFORM" "nemu")
|
||||||
|
(pkgs.lib.cmakeFeature "CMAKE_INSTALL_DATADIR" "share")
|
||||||
|
];
|
||||||
|
|
||||||
patchPhase = ''
|
buildInputs = [
|
||||||
sed -i 's/\/bin\/echo/echo/' tests/cpu-tests/Makefile
|
# SDL2
|
||||||
'';
|
self.packages.${system}.abstract-machine
|
||||||
|
];
|
||||||
buildPhase = ''
|
|
||||||
AS=$CC make -C tests/cpu-tests BUILD_DIR=$(pwd)/build ARCH=$ARCH
|
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/share/images $out/share/dump
|
|
||||||
cp build/riscv32-nemu/*.bin $out/share/images
|
|
||||||
cp build/riscv32-nemu/*.txt $out/share/dump
|
|
||||||
'';
|
|
||||||
|
|
||||||
dontFixup = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
devShells.default = pkgs.mkShell {
|
|
||||||
packages = with pkgs; [
|
|
||||||
gdb
|
|
||||||
] ++ builtins.attrValues self.packages.${system};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
devShells.nemu = pkgs.mkShell {
|
devShells.nemu = pkgs.mkShell {
|
||||||
|
@ -74,4 +57,3 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,4 +94,4 @@ integration-tests: $(IMAGES)
|
||||||
|
|
||||||
test: unit-tests integration-tests
|
test: unit-tests integration-tests
|
||||||
|
|
||||||
.PHONY: test unit-tests integration-tests
|
.PHONY: test unit-tests integration-tests
|
||||||
|
|
|
@ -38,7 +38,7 @@ stdenv.mkDerivation rec {
|
||||||
|
|
||||||
doCheck = true;
|
doCheck = true;
|
||||||
checkPhase = ''
|
checkPhase = ''
|
||||||
export IMAGES_PATH=${am-kernels}/share/images
|
export IMAGES_PATH=${am-kernels}/share/binary
|
||||||
make test
|
make test
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ stdenv.mkDerivation rec {
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
export NEMU_HOME=$(pwd)
|
export NEMU_HOME=$(pwd)
|
||||||
export IMAGES_PATH=${am-kernels}/share/images
|
export IMAGES_PATH=${am-kernels}/share/binary
|
||||||
'';
|
'';
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <utils.h>
|
#include <utils.h>
|
||||||
|
#include <macro.h>
|
||||||
|
|
||||||
IFDEF(CONFIG_ITRACE, void log_itrace_print());
|
IFDEF(CONFIG_ITRACE, void log_itrace_print());
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ static void do_branch(Decode *s, bool condition, word_t offset) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_FTRACE
|
||||||
static void ftrace_jalr(Decode *s, int rd, vaddr_t dst) {
|
static void ftrace_jalr(Decode *s, int rd, vaddr_t dst) {
|
||||||
uint32_t i = s->isa.inst.val;
|
uint32_t i = s->isa.inst.val;
|
||||||
int rs1 = BITS(i, 19, 15);
|
int rs1 = BITS(i, 19, 15);
|
||||||
|
@ -71,6 +72,7 @@ static void ftrace_jalr(Decode *s, int rd, vaddr_t dst) {
|
||||||
ftrace_call(s->pc, dst);
|
ftrace_call(s->pc, dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int decode_exec(Decode *s) {
|
static int decode_exec(Decode *s) {
|
||||||
int rd = 0;
|
int rd = 0;
|
||||||
|
|
|
@ -133,8 +133,12 @@ void init_monitor(int argc, char *argv[]) {
|
||||||
|
|
||||||
// printf("elf_file: %s\n", elf_file);
|
// printf("elf_file: %s\n", elf_file);
|
||||||
if(elf_file != NULL) {
|
if(elf_file != NULL) {
|
||||||
|
#ifdef CONFIG_FTRACE
|
||||||
void init_elf(const char *path);
|
void init_elf(const char *path);
|
||||||
init_elf(elf_file);
|
init_elf(elf_file);
|
||||||
|
#else
|
||||||
|
Warning("Elf file provided, but ftrace not turned on. Ignoring elf file.");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_ISA_loongarch32r
|
#ifndef CONFIG_ISA_loongarch32r
|
||||||
|
|
|
@ -10,7 +10,6 @@ static vaddr_t ftrace_stack[CONFIG_FTRACE_STACK_SIZE] = {0};
|
||||||
static vaddr_t ftrace_stack_len = 0;
|
static vaddr_t ftrace_stack_len = 0;
|
||||||
func_t *func_table = NULL;
|
func_t *func_table = NULL;
|
||||||
int func_table_len = 0, func_table_size = 8;
|
int func_table_len = 0, func_table_size = 8;
|
||||||
#endif
|
|
||||||
|
|
||||||
static int cmp_func_t(const void *a, const void *b) {
|
static int cmp_func_t(const void *a, const void *b) {
|
||||||
return ((func_t *)a)->start > ((func_t *)b)->start;
|
return ((func_t *)a)->start > ((func_t *)b)->start;
|
||||||
|
@ -122,3 +121,4 @@ void ftrace_return(vaddr_t pc, vaddr_t addr) {
|
||||||
Trace("%*s0x%x ret 0x%x <%s+0x%x>", ftrace_stack_len, "", pc, addr,
|
Trace("%*s0x%x ret 0x%x <%s+0x%x>", ftrace_stack_len, "", pc, addr,
|
||||||
f == NULL ? "???" : f->name, addr - f->start);
|
f == NULL ? "???" : f->name, addr - f->start);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue