klib: printf support

This commit is contained in:
xinyangli 2024-07-09 17:26:11 +08:00
parent f38674ce79
commit 955f1f2d79
Signed by: xin
SSH key fingerprint: SHA256:qZ/tzd8lYRtUFSrfBDBMcUqV4GHKxqeqRA3huItgvbk
19 changed files with 438 additions and 245 deletions

View file

@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
include(CMakeDependentOption) include(CMakeDependentOption)
include(CMakePackageConfigHelpers) # Used to find libcheck include(CMakePackageConfigHelpers) # Used to find libcheck
include(CTest) include(CTest)
include(GNUInstallDirs) include(GNUInstallDirs)
@ -15,15 +15,11 @@ set(ISA CACHE STRING "Target ISA")
set_property(CACHE ISA PROPERTY STRINGS "riscv" "x86" "x86_64" "native") set_property(CACHE ISA PROPERTY STRINGS "riscv" "x86" "x86_64" "native")
string(TOUPPER ${ISA} ISA_UPPER) string(TOUPPER ${ISA} ISA_UPPER)
cmake_dependent_option( cmake_dependent_option(__PLATFORM_NEMU__ "Run on NEMU" ON
__PLATFORM_NEMU__ "Run on NEMU" "ISA MATCHES \"(riscv | x86)\"" OFF)
ON "ISA MATCHES \"(riscv | x86)\"" OFF) cmake_dependent_option(__PLATFORM_NPC__ "Run on NPC" ON "ISA MATCHES riscv" OFF)
cmake_dependent_option( cmake_dependent_option(__PLATFORM_NATIVE__ "Run on native" ON
__PLATFORM_NPC__ "Run on NPC" "ISA MATCHES native" OFF)
ON "ISA MATCHES riscv" OFF)
cmake_dependent_option(
__PLATFORM_NATIVE__ "Run on native"
ON "ISA MATCHES native" OFF)
# -- Set PLATFORM according to options # -- Set PLATFORM according to options
set(MATCH_PLATFORM_PATTERN "^__PLATFORM_([A-Z]*)__$") set(MATCH_PLATFORM_PATTERN "^__PLATFORM_([A-Z]*)__$")
@ -31,64 +27,96 @@ get_cmake_property(CACHE_VARS CACHE_VARIABLES)
message(STATUS "ISA: ${ISA}") message(STATUS "ISA: ${ISA}")
foreach(VAR IN LISTS CACHE_VARS) foreach(VAR IN LISTS CACHE_VARS)
if(VAR MATCHES ${MATCH_PLATFORM_PATTERN}) if(VAR MATCHES ${MATCH_PLATFORM_PATTERN})
# Retrieve the value of the cache variable # Retrieve the value of the cache variable
get_property(VAR_VALUE CACHE ${VAR} PROPERTY VALUE) get_property(
set(PLATFORM_UPPER ${CMAKE_MATCH_1}) VAR_VALUE
string(TOLOWER ${PLATFORM_UPPER} PLATFORM) CACHE ${VAR}
list(APPEND PLATFORMS ${PLATFORM}) PROPERTY VALUE)
message(STATUS "Variable: ${VAR}=${VAR_VALUE}, Platform: ${PLATFORM}") set(PLATFORM_UPPER ${CMAKE_MATCH_1})
endif() string(TOLOWER ${PLATFORM_UPPER} PLATFORM)
list(APPEND PLATFORMS ${PLATFORM})
message(STATUS "Variable: ${VAR}=${VAR_VALUE}, Platform: ${PLATFORM}")
endif()
endforeach() endforeach()
if((NOT PLATFORM) AND (NOT ISA MATCHES native)) if((NOT PLATFORM) AND (NOT ISA MATCHES native))
message(FATAL_ERROR "Platform not given!") message(FATAL_ERROR "Platform not given!")
endif() endif()
set(SUPPORTED_ARCH "riscv-nemu" "riscv-npc" "native") set(SUPPORTED_ARCH "riscv-nemu" "riscv-npc" "native")
foreach(PLATFORM IN LISTS PLATFORMS) foreach(PLATFORM IN LISTS PLATFORMS)
if(${ISA} MATCHES "native") if(${ISA} MATCHES "native")
set(ARCH "native") set(ARCH "native")
else() else()
set(ARCH ${ISA}-${PLATFORM}) set(ARCH ${ISA}-${PLATFORM})
endif() endif()
if(NOT ARCH IN_LIST SUPPORTED_ARCH) if(NOT ARCH IN_LIST SUPPORTED_ARCH)
message(FATAL_ERROR "Given ISA-PLATFORM (${ISA}-${PLATFORM}) does not match one of the following: ${SUPPORTED_ARCH}") message(
endif() FATAL_ERROR
"Given ISA-PLATFORM (${ISA}-${PLATFORM}) does not match one of the following: ${SUPPORTED_ARCH}"
)
endif()
endforeach() endforeach()
# -- Target specific options # -- Target specific options
cmake_dependent_option( cmake_dependent_option(NATIVE_USE_KLIB "Use Klib even if on native" ON
NATIVE_USE_KLIB "Use Klib even if on native" "NOT __ISA_NATIVE__" OFF)
ON "NOT __ISA_NATIVE__" OFF)
# -- Add compile definitions based on options # -- Add compile definitions based on options
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# NOTE: klib and am include header files in each other, # NOTE: klib and am include header files in each other, so we need to create
# so we need to create interface libraries for correct dependency # interface libraries for correct dependency
add_library(am_interface INTERFACE) add_library(am_interface INTERFACE)
target_include_directories(am_interface INTERFACE target_include_directories(
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/am/include> am_interface
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/am/src> INTERFACE $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/am/include>
$<INSTALL_INTERFACE:include/abstract-machine>) $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/am/src>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_compile_definitions(am_interface INTERFACE ARCH_H=<arch/${ISA}.h>) target_compile_definitions(am_interface INTERFACE ARCH_H=<arch/${ISA}.h>)
file(GLOB_RECURSE AM_HEADERS "${CMAKE_SOURCE_DIR}/am/include/*.h")
target_sources(
am_interface
PUBLIC FILE_SET
am_headers
TYPE
HEADERS
BASE_DIRS
${CMAKE_SOURCE_DIR}/am/include
FILES
${AM_HEADERS})
add_library(klib_interface INTERFACE) add_library(klib_interface INTERFACE)
target_include_directories(klib_interface target_include_directories(
INTERFACE klib_interface
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/klib/include> INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/klib/include>
$<INSTALL_INTERFACE:include/abstract-machine>) $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
file(GLOB_RECURSE KLIB_HEADERS "${CMAKE_SOURCE_DIR}/klib/include/*.h")
target_sources(
klib_interface
PUBLIC FILE_SET
klib_headers
TYPE
HEADERS
BASE_DIRS
${CMAKE_SOURCE_DIR}/klib/include
FILES
${KLIB_HEADERS})
install(TARGETS am_interface klib_interface install(
EXPORT interfaceTargets TARGETS am_interface klib_interface
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/abstract-machine) EXPORT interfaceTargets
FILE_SET klib_headers FILE_SET am_headers
INCLUDES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT interfaceTargets install(
FILE interfaceTargets.cmake EXPORT interfaceTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) FILE interfaceTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
add_subdirectory(klib) add_subdirectory(klib)
add_subdirectory(am) add_subdirectory(am)

View file

@ -7,7 +7,7 @@
"generator": "Unix Makefiles", "generator": "Unix Makefiles",
"binaryDir": "${sourceDir}/out/build/${presetName}", "binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": { "cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug", "CMAKE_BUILD_TYPE": "RelWithDebInfo",
"ISA": "native", "ISA": "native",
"__PLATFORM_NATIVE__": true, "__PLATFORM_NATIVE__": true,
"NATIVE_USE_KLIB": true "NATIVE_USE_KLIB": true
@ -19,7 +19,7 @@
"generator": "Unix Makefiles", "generator": "Unix Makefiles",
"binaryDir": "${sourceDir}/out/build/${presetName}", "binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": { "cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug", "CMAKE_BUILD_TYPE": "RelWithDebInfo",
"ISA": "riscv", "ISA": "riscv",
"__PLATFORM_NPC__": true, "__PLATFORM_NPC__": true,
"__PLATFORM_NEMU__": true "__PLATFORM_NEMU__": true

View file

@ -1,26 +1,26 @@
add_subdirectory(src) add_subdirectory(src)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/abstract-machine)
foreach(PLATFORM IN LISTS PLATFORMS) foreach(PLATFORM IN LISTS PLATFORMS)
if(ISA MATCHES "native") if(ISA MATCHES "native")
set(ARCH "native") set(ARCH "native")
else() else()
set(ARCH ${ISA}-${PLATFORM}) set(ARCH ${ISA}-${PLATFORM})
endif() endif()
install(TARGETS am-${ARCH} install(
EXPORT amTargets-${ARCH} TARGETS am-${ARCH}
LIBRARY DESTINATION lib) EXPORT amTargets-${ARCH}
LIBRARY DESTINATION lib)
install(EXPORT amTargets-${ARCH} install(
FILE amTargets.cmake EXPORT amTargets-${ARCH}
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH}) FILE amTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH})
configure_package_config_file( configure_package_config_file(
${CMAKE_SOURCE_DIR}/cmake/am-config.cmake.in ${CMAKE_SOURCE_DIR}/cmake/am-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/am-${ARCH}-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/am-${ARCH}-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH}) INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/am-${ARCH}-config.cmake install(FILES ${CMAKE_CURRENT_BINARY_DIR}/am-${ARCH}-config.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH}) DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH})
endforeach() endforeach()

View file

@ -10,14 +10,16 @@ set(SOURCES
ioe/disk.c ioe/disk.c
ioe/gpu.c ioe/gpu.c
ioe/input.c ioe/input.c
ioe/timer.c ioe/timer.c)
)
add_library(am-native ${SOURCES}) add_library(am-native ${SOURCES})
# FIXME: get free(): invalid address when user program compiled without pie # FIXME: get free(): invalid address when user program compiled without pie
set_target_properties(am-native PROPERTIES set_target_properties(
POSITION_INDEPENDENT_CODE TRUE am-native PROPERTIES POSITION_INDEPENDENT_CODE TRUE
INTERFACE_POSITION_INDEPENDENT_CODE TRUE) INTERFACE_POSITION_INDEPENDENT_CODE TRUE)
find_package(SDL2 REQUIRED) find_package(SDL2 REQUIRED)
target_link_libraries(am-native PUBLIC SDL2::SDL2 PRIVATE klib_interface am_interface) target_link_libraries(
am-native
PUBLIC SDL2::SDL2
PRIVATE klib_interface am_interface)

View file

@ -1,18 +1,17 @@
#include <am.h> #include <am.h>
#include <nemu.h> #include <nemu.h>
void __am_timer_init() { void __am_timer_init() {}
}
void __am_timer_uptime(AM_TIMER_UPTIME_T *uptime) { void __am_timer_uptime(AM_TIMER_UPTIME_T *uptime) {
uptime->us = 0; uptime->us = ((uint64_t)inl(RTC_ADDR + 4) << 32) + inl(RTC_ADDR);
} }
void __am_timer_rtc(AM_TIMER_RTC_T *rtc) { void __am_timer_rtc(AM_TIMER_RTC_T *rtc) {
rtc->second = 0; rtc->second = 0;
rtc->minute = 0; rtc->minute = 0;
rtc->hour = 0; rtc->hour = 0;
rtc->day = 0; rtc->day = 0;
rtc->month = 0; rtc->month = 0;
rtc->year = 1900; rtc->year = 1900;
} }

View file

@ -6,19 +6,18 @@ int main(const char *args);
Area heap = RANGE(&_heap_start, PMEM_END); Area heap = RANGE(&_heap_start, PMEM_END);
#ifndef MAINARGS #ifndef MAINARGS
#define MAINARGS "" #define MAINARGS "5"
#endif #endif
static const char mainargs[] = MAINARGS; static const char mainargs[] = MAINARGS;
void putch(char ch) { void putch(char ch) { outb(SERIAL_PORT, ch); }
outb(SERIAL_PORT, ch);
}
void halt(int code) { void halt(int code) {
nemu_trap(code); nemu_trap(code);
// should not reach here // should not reach here
while (1); while (1)
;
} }
void _trm_init() { void _trm_init() {

View file

@ -1,12 +1,9 @@
foreach(PLATFORM IN LISTS PLATFORMS) foreach(PLATFORM IN LISTS PLATFORMS)
string(TOUPPER ${ARCH} ARCH_UPPER) string(TOUPPER ${ARCH} ARCH_UPPER)
set(AM_COMMON_COMPILE_DEF set(AM_COMMON_COMPILE_DEF
# -- Arch related # -- Arch related
$<MAKE_C_IDENTIFIER:__ARCH_${ARCH_UPPER}__> $<MAKE_C_IDENTIFIER:__ARCH_${ARCH_UPPER}__> __ISA_${ISA_UPPER}__
__ISA_${ISA_UPPER}__ __PLATFORM_${PLATFORM_UPPER}__
__PLATFORM_${PLATFORM_UPPER}__ $<$<BOOL:${NATIVE_USE_KLIB}>:__NATIVE_USE_KLIB__>)
add_subdirectory(${PLATFORM})
$<$<BOOL:${NATIVE_USE_KLIB}>:__NATIVE_USE_KLIB__>
)
add_subdirectory(${PLATFORM})
endforeach() endforeach()

View file

@ -1,52 +1,41 @@
include(nemu-settings) include(nemu-settings)
include(riscv-settings) include(riscv-settings)
add_library(am-riscv-nemu add_library(am-riscv-nemu cte.c start.S trap.S vme.c ${NEMU_SOURCES})
cte.c
start.S
trap.S
vme.c
${NEMU_SOURCES}
)
target_compile_options(am-riscv-nemu PRIVATE target_compile_options(am-riscv-nemu PRIVATE ${NEMU_COMPILE_OPTIONS}
${NEMU_COMPILE_OPTIONS} ${RISCV_COMPILE_OPTIONS})
${RISCV_COMPILE_OPTIONS})
target_link_options(am-riscv-nemu PRIVATE target_link_options(am-riscv-nemu PRIVATE ${NEMU_LINK_OPITIONS}
${NEMU_LINK_OPITIONS} ${RISCV_LINK_OPTIONS})
${RISCV_LINK_OPTIONS})
target_include_directories(am-riscv-nemu PRIVATE target_include_directories(am-riscv-nemu PRIVATE ${NEMU_INCLUDE_DIRECTORIES})
${NEMU_INCLUDE_DIRECTORIES})
target_link_options(am-riscv-nemu INTERFACE target_link_options(
LINKER:--defsym=_pmem_start=0x80000000 am-riscv-nemu
LINKER:--defsym=_entry_offset=0x0 INTERFACE
LINKER:--gc-sections LINKER:--defsym=_pmem_start=0x80000000
LINKER:-e _start LINKER:--defsym=_entry_offset=0x0
-nostartfiles) LINKER:--gc-sections
LINKER:-e
_start
-nostartfiles)
target_link_options(am-riscv-nemu INTERFACE target_link_options(
$<BUILD_INTERFACE:-T${CMAKE_SOURCE_DIR}/scripts/linker.ld> am-riscv-nemu INTERFACE
$<INSTALL_INTERFACE:-T${CMAKE_INSTALL_FULL_DATADIR}/linker.ld>) $<BUILD_INTERFACE:-T${CMAKE_SOURCE_DIR}/scripts/linker.ld>
$<INSTALL_INTERFACE:-T${CMAKE_INSTALL_FULL_DATADIR}/linker.ld>)
target_include_directories(am-riscv-nemu target_link_libraries(
PUBLIC am-riscv-nemu
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/am/include> PUBLIC am_interface klib_interface
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/abstract-machine>) INTERFACE m)
target_link_libraries(am-riscv-nemu target_compile_definitions(am-riscv-nemu PRIVATE ISA_H=<riscv/riscv.h>)
PUBLIC am_interface klib_interface
INTERFACE m)
target_compile_definitions(am-riscv-nemu PRIVATE set_target_properties(
ISA_H=<riscv/riscv.h>) am-riscv-nemu PROPERTIES POSITION_INDEPENDENT_CODE OFF
INTERFACE_POSITION_INDEPENDENT_CODE OFF)
set_target_properties(am-riscv-nemu PROPERTIES
POSITION_INDEPENDENT_CODE OFF
INTERFACE_POSITION_INDEPENDENT_CODE OFF)
install(FILES ${CMAKE_SOURCE_DIR}/scripts/linker.ld install(FILES ${CMAKE_SOURCE_DIR}/scripts/linker.ld
DESTINATION ${CMAKE_INSTALL_DATADIR}) DESTINATION ${CMAKE_INSTALL_DATADIR})

View file

@ -2,38 +2,45 @@ include(riscv-settings)
add_subdirectory(libgcc) add_subdirectory(libgcc)
add_library(am-riscv-npc add_library(
cte.c am-riscv-npc
input.c cte.c
ioe.c input.c
mpe.c ioe.c
start.S mpe.c
timer.c start.S
trap.S timer.c
trm.c trap.S
vme.c trm.c
) vme.c)
target_link_libraries(am-riscv-npc PRIVATE npcgcc PUBLIC am_interface klib_interface) target_link_libraries(
am-riscv-npc
PRIVATE npcgcc
PUBLIC am_interface klib_interface)
target_link_options(am-riscv-npc INTERFACE target_link_options(
$<BUILD_INTERFACE:-T${CMAKE_SOURCE_DIR}/scripts/linker.ld> am-riscv-npc INTERFACE
$<INSTALL_INTERFACE:-T${CMAKE_INSTALL_FULL_DATADIR}/linker.ld>) $<BUILD_INTERFACE:-T${CMAKE_SOURCE_DIR}/scripts/linker.ld>
$<INSTALL_INTERFACE:-T${CMAKE_INSTALL_FULL_DATADIR}/linker.ld>)
target_link_options(am-riscv-npc INTERFACE target_link_options(
LINKER:--defsym=_pmem_start=0x80000000 am-riscv-npc
LINKER:--defsym=_entry_offset=0x0 INTERFACE
LINKER:--gc-sections LINKER:--defsym=_pmem_start=0x80000000
LINKER:-e _start LINKER:--defsym=_entry_offset=0x0
-nostartfiles) LINKER:--gc-sections
LINKER:-e
_start
-nostartfiles)
target_link_options(am-riscv-npc INTERFACE target_link_options(
$<BUILD_INTERFACE:-T${CMAKE_SOURCE_DIR}/scripts/linker.ld> am-riscv-npc INTERFACE
$<INSTALL_INTERFACE:-T${CMAKE_INSTALL_FULL_DATADIR}/linker.ld>) $<BUILD_INTERFACE:-T${CMAKE_SOURCE_DIR}/scripts/linker.ld>
$<INSTALL_INTERFACE:-T${CMAKE_INSTALL_FULL_DATADIR}/linker.ld>)
target_compile_definitions(am-riscv-npc target_compile_definitions(am-riscv-npc PUBLIC ${AM_COMMON_COMPILE_DEF}
PUBLIC ${AM_COMMON_COMPILE_DEF} ARCH_H=<arch/riscv.h> ARCH_H=<arch/riscv.h>)
)
install(FILES ${CMAKE_SOURCE_DIR}/scripts/linker.ld install(FILES ${CMAKE_SOURCE_DIR}/scripts/linker.ld
DESTINATION ${CMAKE_INSTALL_DATADIR}) DESTINATION ${CMAKE_INSTALL_DATADIR})

View file

@ -7,26 +7,32 @@ void __am_timer_rtc(AM_TIMER_RTC_T *);
void __am_timer_uptime(AM_TIMER_UPTIME_T *); void __am_timer_uptime(AM_TIMER_UPTIME_T *);
void __am_input_keybrd(AM_INPUT_KEYBRD_T *); void __am_input_keybrd(AM_INPUT_KEYBRD_T *);
static void __am_timer_config(AM_TIMER_CONFIG_T *cfg) { cfg->present = true; cfg->has_rtc = true; } static void __am_timer_config(AM_TIMER_CONFIG_T *cfg) {
static void __am_input_config(AM_INPUT_CONFIG_T *cfg) { cfg->present = true; } cfg->present = true;
cfg->has_rtc = true;
}
static void __am_input_config(AM_INPUT_CONFIG_T *cfg) { cfg->present = true; }
static void __am_uart_config(AM_UART_CONFIG_T *cfg) { cfg->present = false; }
typedef void (*handler_t)(void *buf); typedef void (*handler_t)(void *buf);
static void *lut[128] = { static void *lut[128] = {
[AM_TIMER_CONFIG] = __am_timer_config, [AM_UART_CONFIG] = __am_uart_config,
[AM_TIMER_RTC ] = __am_timer_rtc, [AM_TIMER_CONFIG] = __am_timer_config,
[AM_TIMER_UPTIME] = __am_timer_uptime, [AM_TIMER_RTC] = __am_timer_rtc,
[AM_INPUT_CONFIG] = __am_input_config, [AM_TIMER_UPTIME] = __am_timer_uptime,
[AM_INPUT_KEYBRD] = __am_input_keybrd, [AM_INPUT_CONFIG] = __am_input_config,
[AM_INPUT_KEYBRD] = __am_input_keybrd,
}; };
static void fail(void *buf) { panic("access nonexist register"); } static void fail(void *buf) { panic("access nonexist register"); }
bool ioe_init() { bool ioe_init() {
for (int i = 0; i < LENGTH(lut); i++) for (int i = 0; i < LENGTH(lut); i++)
if (!lut[i]) lut[i] = fail; if (!lut[i])
lut[i] = fail;
__am_timer_init(); __am_timer_init();
return true; return true;
} }
void ioe_read (int reg, void *buf) { ((handler_t)lut[reg])(buf); } void ioe_read(int reg, void *buf) { ((handler_t)lut[reg])(buf); }
void ioe_write(int reg, void *buf) { ((handler_t)lut[reg])(buf); } void ioe_write(int reg, void *buf) { ((handler_t)lut[reg])(buf); }

View file

@ -1,14 +1,9 @@
add_library(npcgcc add_library(npcgcc ashldi3.c div.S muldi3.S multi3.c unused.c)
ashldi3.c
div.S
muldi3.S
multi3.c
unused.c
)
target_link_libraries(npcgcc PRIVATE klib_interface am_interface) target_link_libraries(npcgcc PRIVATE klib_interface am_interface)
target_link_options(npcgcc INTERFACE -nolibc -nostdlib) target_link_options(npcgcc INTERFACE -nolibc -nostdlib)
install(TARGETS npcgcc install(
EXPORT amTargets-riscv-npc TARGETS npcgcc
LIBRARY DESTINATION lib) EXPORT amTargets-riscv-npc
LIBRARY DESTINATION lib)

View file

@ -1,17 +1,18 @@
#include "npc.h"
#include <am.h> #include <am.h>
#include <riscv/riscv.h>
void __am_timer_init() { void __am_timer_init() {}
}
void __am_timer_uptime(AM_TIMER_UPTIME_T *uptime) { void __am_timer_uptime(AM_TIMER_UPTIME_T *uptime) {
uptime->us = 0; uptime->us = ((uint64_t)inl(RTC_ADDR + 4) << 32) + inl(RTC_ADDR);
} }
void __am_timer_rtc(AM_TIMER_RTC_T *rtc) { void __am_timer_rtc(AM_TIMER_RTC_T *rtc) {
rtc->second = 0; rtc->second = 0;
rtc->minute = 0; rtc->minute = 0;
rtc->hour = 0; rtc->hour = 0;
rtc->day = 0; rtc->day = 0;
rtc->month = 0; rtc->month = 0;
rtc->year = 1900; rtc->year = 1900;
} }

View file

@ -1,5 +1,7 @@
#include "npc.h"
#include <am.h> #include <am.h>
#include <klib-macros.h> #include <klib-macros.h>
#include <riscv/riscv.h>
extern char _heap_start; extern char _heap_start;
int main(const char *args); int main(const char *args);
@ -10,11 +12,11 @@ extern char _pmem_start;
Area heap = RANGE(&_heap_start, PMEM_END); Area heap = RANGE(&_heap_start, PMEM_END);
#ifndef MAINARGS #ifndef MAINARGS
#define MAINARGS "" #define MAINARGS "3"
#endif #endif
static const char mainargs[] = MAINARGS; static const char mainargs[] = MAINARGS;
void putch(char ch) {} void putch(char ch) { outb(SERIAL_PORT, ch); }
void halt(int code) { void halt(int code) {
asm volatile("mv a0, %0; ebreak" : : "r"(code)); asm volatile("mv a0, %0; ebreak" : : "r"(code));

View file

@ -7,7 +7,7 @@
}: }:
stdenv.mkDerivation { stdenv.mkDerivation {
pname = "abstract-machine"; pname = "abstract-machine";
version = "2024.02.18"; version = "2024.06.01";
src = ./.; src = ./.;

View file

@ -1 +1,4 @@
install(DIRECTORY include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/abstract-machine)
add_subdirectory(src) add_subdirectory(src)

View file

@ -1,32 +1,30 @@
# find_package(FLEX) # find_package(FLEX) find_package(BISON)
# find_package(BISON)
# FLEX_TARGET(fmt_scanner fmt_scanner.l fmt_scanner.c) # FLEX_TARGET(fmt_scanner fmt_scanner.l fmt_scanner.c)
set(SOURCES set(SOURCES cpp.c int64.c stdio.c stdlib.c string.c
cpp.c # ${FLEX_fmt_scanner_OUTPUTS}
int64.c
stdio.c
stdlib.c
string.c
# ${FLEX_fmt_scanner_OUTPUTS}
) )
add_library(klib ${SOURCES}) add_library(klib ${SOURCES})
target_link_libraries(klib PRIVATE am_interface klib_interface) target_link_libraries(klib PUBLIC am_interface klib_interface)
target_compile_options(klib PUBLIC -fno-builtin)
target_link_options(klib PUBLIC -nostartfiles -nolibc)
install(TARGETS klib install(
EXPORT klibTargets TARGETS klib
LIBRARY DESTINATION lib) EXPORT klibTargets
LIBRARY DESTINATION lib)
install(EXPORT klibTargets install(
FILE klibTargets.cmake EXPORT klibTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib) FILE klibTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)
configure_package_config_file(${CMAKE_SOURCE_DIR}/cmake/klib-config.cmake.in configure_package_config_file(
${CMAKE_SOURCE_DIR}/cmake/klib-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/klib-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/klib-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib) INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/klib-config.cmake install(FILES ${CMAKE_CURRENT_BINARY_DIR}/klib-config.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib) DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)

View file

@ -1,16 +1,91 @@
#include <am.h> #include <am.h>
#include <klib.h>
#include <klib-macros.h> #include <klib-macros.h>
#include <klib.h>
#include <stdarg.h> #include <stdarg.h>
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__) #if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
int vprintf(const char *fmt, va_list ap) { void print_int(int num, int width, char pad) {
const char *p = fmt; int reverse = 0;
while(*p != '\0') { int count = 0;
putch(*p);
if (num == 0) {
reverse = 0;
count = 1;
} else {
if (num < 0) {
putch('-');
num = -num;
}
while (num != 0) {
reverse = reverse * 10 + (num % 10);
num /= 10;
count++;
}
}
while (width > count) {
putch(pad);
width--;
}
if (reverse == 0) {
putch('0');
} else {
while (reverse != 0) {
putch('0' + (reverse % 10));
reverse /= 10;
}
}
}
int vprintf(const char *format, va_list args) {
const char *p = format;
while (*p) {
if (*p == '%') {
p++; // Skip the '%'
char pad = ' ';
int width = 0;
if (*p == '0') {
pad = '0';
p++;
}
while (*p >= '0' && *p <= '9') {
width = width * 10 + (*p - '0');
p++;
}
switch (*p) {
case 'd': { // Integer
int ival = va_arg(args, int);
print_int(ival, width, pad);
break;
}
case 'c': { // Character
char c = (char)va_arg(args, int);
putch(c);
break;
}
case 's': { // String
char *s = va_arg(args, char *);
putstr(s);
break;
}
case '%': {
putch('%');
break;
}
default:
panic("Wrong formatter provided to printf");
}
} else {
putch(*p);
}
p++;
} }
return 0;
} }
int printf(const char *fmt, ...) { int printf(const char *fmt, ...) {
@ -21,12 +96,103 @@ int printf(const char *fmt, ...) {
return 0; return 0;
} }
int vsprintf(char *out, const char *fmt, va_list ap) { void append_to_buffer(char **buf, int *pos, char c) { (*buf)[(*pos)++] = c; }
panic("Not implemented");
void print_int_to_buf(char **buf, int *pos, int num, int width, char pad) {
int reverse = 0, count = 0, neg = 0;
if (num == 0) {
reverse = 0;
count = 1;
} else {
if (num < 0) {
append_to_buffer(buf, pos, '-');
num = -num;
neg = 1;
}
while (num != 0) {
reverse = reverse * 10 + (num % 10);
num /= 10;
count++;
}
}
width -= neg;
while (width > count) {
append_to_buffer(buf, pos, pad);
width--;
}
if (reverse == 0) {
append_to_buffer(buf, pos, '0');
} else {
while (reverse != 0) {
append_to_buffer(buf, pos, '0' + (reverse % 10));
reverse /= 10;
}
}
}
int vsprintf(char *buf, const char *format, va_list args) {
const char *p = format;
int pos = 0; // Position in buf
while (*p) {
if (*p == '%') {
p++; // Skip the '%'
char pad = ' ';
int width = 0;
if (*p == '0') {
pad = '0';
p++;
}
while (*p >= '0' && *p <= '9') {
width = width * 10 + (*p - '0');
p++;
}
switch (*p) {
case 'd': { // Integer
int ival = va_arg(args, int);
print_int_to_buf(&buf, &pos, ival, width, pad);
break;
}
case 'c': { // Character
char c = (char)va_arg(args, int);
append_to_buffer(&buf, &pos, c);
break;
}
case 's': { // String
char *s = va_arg(args, char *);
while (*s) {
append_to_buffer(&buf, &pos, *s++);
}
break;
}
case '%': {
append_to_buffer(&buf, &pos, '%');
break;
}
default:
panic("Unsupported format specifier");
}
} else {
append_to_buffer(&buf, &pos, *p);
}
p++;
}
buf[pos] = '\0'; // Null-terminate the string
return pos;
} }
int sprintf(char *out, const char *fmt, ...) { int sprintf(char *out, const char *fmt, ...) {
panic("Not implemented"); va_list args;
va_start(args, fmt);
vsprintf(out, fmt, args);
va_end(args);
return 0;
} }
int snprintf(char *out, size_t n, const char *fmt, ...) { int snprintf(char *out, size_t n, const char *fmt, ...) {

View file

@ -1,6 +1,6 @@
#include <am.h> #include <am.h>
#include <klib.h>
#include <klib-macros.h> #include <klib-macros.h>
#include <klib.h>
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__) #if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
static unsigned long int next = 1; static unsigned long int next = 1;
@ -8,23 +8,21 @@ static unsigned long int next = 1;
int rand(void) { int rand(void) {
// RAND_MAX assumed to be 32767 // RAND_MAX assumed to be 32767
next = next * 1103515245 + 12345; next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768; return (unsigned int)(next / 65536) % 32768;
} }
void srand(unsigned int seed) { void srand(unsigned int seed) { next = seed; }
next = seed;
}
int abs(int x) { int abs(int x) { return (x < 0 ? -x : x); }
return (x < 0 ? -x : x);
}
int atoi(const char* nptr) { int atoi(const char *nptr) {
int x = 0; int x = 0;
while (*nptr == ' ') { nptr ++; } while (*nptr == ' ') {
nptr++;
}
while (*nptr >= '0' && *nptr <= '9') { while (*nptr >= '0' && *nptr <= '9') {
x = x * 10 + *nptr - '0'; x = x * 10 + *nptr - '0';
nptr ++; nptr++;
} }
return x; return x;
} }
@ -33,13 +31,19 @@ void *malloc(size_t size) {
// On native, malloc() will be called during initializaion of C runtime. // On native, malloc() will be called during initializaion of C runtime.
// Therefore do not call panic() here, else it will yield a dead recursion: // Therefore do not call panic() here, else it will yield a dead recursion:
// panic() -> putchar() -> (glibc) -> malloc() -> panic() // panic() -> putchar() -> (glibc) -> malloc() -> panic()
#if !(defined(__ISA_NATIVE__) && defined(__NATIVE_USE_KLIB__)) static void *addr = NULL;
panic("Not implemented"); void *ret = NULL;
#endif if (addr == 0) {
return NULL; addr = heap.start;
ret = addr;
} else {
panic_on(addr + size > heap.end, "Memory space not enough");
ret = addr;
addr += size;
}
return ret;
} }
void free(void *ptr) { void free(void *ptr) {}
}
#endif #endif

View file

@ -1,14 +1,11 @@
set(TEST_SOURCES set(TEST_SOURCES stdio string)
stdio
string
)
foreach(TEST IN LISTS TEST_SOURCES) foreach(TEST IN LISTS TEST_SOURCES)
# TODO: Run tests in other configurations # TODO: Run tests in other configurations
if(__PLATFORM_NATIVE__) if(__PLATFORM_NATIVE__)
add_executable(${TEST} ${TEST}.c) add_executable(${TEST} ${TEST}.c)
target_link_libraries(${TEST} PRIVATE am_interface klib_interface klib m) target_link_libraries(${TEST} PRIVATE am_interface klib_interface klib m)
target_link_libraries(${TEST} PRIVATE am-native) target_link_libraries(${TEST} PRIVATE am-native)
add_test(NAME ${TEST} COMMAND ${TEST}) add_test(NAME ${TEST} COMMAND ${TEST})
endif() endif()
endforeach() endforeach()