Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ jobs:
env:
CC: ${{ steps.install_cc.outputs.cc }}
run: |
. .ci/common.sh
export LATEST_RELEASE=$(download_with_headers "https://api.github.com/repos/sysprog21/rv32emu-prebuilt/releases" \
"Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
| grep '"tag_name"' \
| grep "sail" \
| head -n 1 \
| sed -E 's/.*"tag_name": "([^"]+)".*/\1/')
.ci/riscv-tests.sh
if: ${{ always() }}

Expand Down Expand Up @@ -341,7 +348,8 @@ jobs:
- uses: actions/checkout@v4
- name: install-dependencies
run: |
brew install make dtc expect sdl2 sdl2_mixer bc e2fsprogs p7zip llvm@18 dcfldd
brew install make dtc expect sdl2 bc e2fsprogs p7zip llvm@18 dcfldd
brew install sdl2_mixer || echo "Warning: sdl2_mixer installation failed, continuing without SDL_MIXER support"
.ci/riscv-toolchain-install.sh
echo "${{ github.workspace }}/toolchain/bin" >> $GITHUB_PATH
echo "$(brew --prefix llvm@18)/bin" >> $GITHUB_PATH
Expand Down Expand Up @@ -489,6 +497,13 @@ jobs:
env:
CC: ${{ steps.install_cc.outputs.cc }}
run: |
. .ci/common.sh
export LATEST_RELEASE=$(download_with_headers "https://api.github.com/repos/sysprog21/rv32emu-prebuilt/releases" \
"Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
| grep '"tag_name"' \
| grep "sail" \
| head -n 1 \
| sed -E 's/.*"tag_name": "([^"]+)".*/\1/')
python3 -m venv venv
. venv/bin/activate
.ci/riscv-tests.sh
Expand Down Expand Up @@ -525,8 +540,12 @@ jobs:
sudo apt-get install -q=2 clang-18 clang-tools-18
shell: bash
- name: run scan-build without JIT
env:
LATEST_RELEASE: dummy
run: make distclean && scan-build-18 -v -o ~/scan-build --status-bugs --use-cc=clang-18 --force-analyze-debug-code --show-description -analyzer-config stable-report-filename=true -enable-checker valist,nullability make ENABLE_EXT_F=0 ENABLE_SDL=0 ENABLE_JIT=0
- name: run scan-build with JIT
env:
LATEST_RELEASE: dummy
run: |
make ENABLE_JIT=1 distclean && scan-build-18 -v -o ~/scan-build --status-bugs --use-cc=clang-18 --force-analyze-debug-code --show-description -analyzer-config stable-report-filename=true -enable-checker valist,nullability make ENABLE_EXT_F=0 ENABLE_SDL=0 ENABLE_JIT=1

Expand Down
69 changes: 60 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
include mk/common.mk
include mk/toolchain.mk

# Verify GNU make version (3.80+ required for order-only prerequisites)
ifeq ($(filter 3.80 3.81 3.82 3.83 3.84 4.% 5.%,$(MAKE_VERSION)),)
$(error GNU make 3.80 or higher is required. Current version: $(MAKE_VERSION))
endif

OUT ?= build
BIN := $(OUT)/rv32emu

Expand Down Expand Up @@ -46,6 +51,7 @@ endif
# Device Tree(initrd, memory range)
# src/io.c(memory init)
# src/riscv.c(system emulation layout init)
# Note: These memory settings are for SYSTEM mode only (when ELF_LOADER=0)
ifeq ($(call has, SYSTEM), 1)
ifeq ($(call has, ELF_LOADER), 0)
MiB = 1024*1024
Expand All @@ -66,6 +72,7 @@ CFLAGS_dt += -DMEM_START=0x$(MEM_START) \
-DINITRD_END=0x$(shell echo "obase=16; ibase=16; \
$(REAL_MEM_SIZE) - $(call compute_size, $(DTB_SIZE)) - 1" | bc)

# Memory size for SYSTEM mode (may be overridden by FULL4G if ENABLE_ELF_LOADER=1)
CFLAGS += -DMEM_SIZE=0x$(REAL_MEM_SIZE) -DDTB_SIZE=0x$(REAL_DTB_SIZE) -DINITRD_SIZE=0x$(REAL_INITRD_SIZE)
endif
endif
Expand Down Expand Up @@ -173,27 +180,39 @@ ENABLE_FULL4G ?= 0

# Experimental SDL oriented system calls
ENABLE_SDL ?= 1
ENABLE_SDL_MIXER ?= 1
ifneq ("$(CC_IS_EMCC)", "1") # note that emcc generates port SDL headers/library, so it does not requires system SDL headers/library
ifeq ($(call has, SDL), 1)
ifeq (, $(shell which sdl2-config))
$(warning No sdl2-config in $$PATH. Check SDL2 installation in advance)
override ENABLE_SDL := 0
endif
ifeq (1, $(shell pkg-config --exists SDL2_mixer; echo $$?))
$(warning No SDL2_mixer lib installed. Check SDL2_mixer installation in advance)
override ENABLE_SDL := 0
$(warning No SDL2_mixer lib installed. SDL2_mixer support will be disabled)
override ENABLE_SDL_MIXER := 0
endif
endif
else
# Disable SDL_MIXER for emscripten builds to avoid SDL2_mixer port compilation issues
# The emscripten-ports/SDL2_mixer was archived in Jan 2024 with unfixable warnings
override ENABLE_SDL_MIXER := 0
endif
$(call set-feature, SDL)
$(call set-feature, SDL_MIXER)
ifeq ($(call has, SDL), 1)
OBJS_EXT += syscall_sdl.o
ifneq ("$(CC_IS_EMCC)", "1")
$(OUT)/syscall_sdl.o: CFLAGS += $(shell sdl2-config --cflags)
endif
# 4 GiB of memory is required to run video games.
ENABLE_FULL4G := 1
ifneq ("$(CC_IS_EMCC)", "1")
LDFLAGS += $(shell sdl2-config --libs) -pthread
ifeq ($(call has, SDL_MIXER), 1)
LDFLAGS += $(shell pkg-config --libs SDL2_mixer)
endif
endif
endif

# If SYSTEM is enabled and ELF_LOADER is not, then skip FULL4G bacause guestOS
# has dedicated memory mapping range.
Expand All @@ -206,7 +225,22 @@ endif
# Full access to a 4 GiB address space, necessitating more memory mapping
# during emulator initialization.
$(call set-feature, FULL4G)

# Configuration validation and conflict detection
ifeq ($(call has, SDL), 1)
ifeq ($(call has, SYSTEM), 1)
ifeq ($(call has, ELF_LOADER), 0)
ifeq ($(call has, FULL4G), 0)
$(warning SDL requires FULL4G=1 but SYSTEM forces FULL4G=0. Set ENABLE_ELF_LOADER=1 or disable SDL/SYSTEM)
endif
endif
endif
endif

ifeq ($(call has, FULL4G), 1)
# Note: If both SYSTEM and FULL4G are enabled with ELF_LOADER=1,
# this MEM_SIZE definition will override the SYSTEM mode definition.
# This is intentional for ELF loader use cases.
CFLAGS += -DMEM_SIZE=0xFFFFFFFFULL # 2^{32} - 1
endif

Expand Down Expand Up @@ -259,6 +293,8 @@ ifeq ($(call has, JIT), 1)
else
$(error No llvm-config-18 installed. Check llvm-config-18 installation in advance, or use "ENABLE_T2C=0" to disable tier-2 LLVM compiler)
endif
else
$(warning T2C (tier-2 compiler) is disabled. Using tier-1 JIT only.)
endif
ifneq ($(processor),$(filter $(processor),x86_64 aarch64 arm64))
$(error JIT mode only supports for x64 and arm64 target currently.)
Expand Down Expand Up @@ -292,7 +328,7 @@ include mk/artifact.mk
include mk/system.mk
include mk/wasm.mk

all: config $(BUILD_DTB) $(BUILD_DTB2C) $(BIN)
all: $(BUILD_DTB) $(BUILD_DTB2C) $(BIN)

OBJS := \
map.o \
Expand Down Expand Up @@ -327,19 +363,31 @@ ifeq ($(call has, GDBSTUB), 1)
$(OBJS): $(GDBSTUB_LIB)
endif

$(OUT)/%.o: src/%.c $(deps_emcc)
$(Q)mkdir -p $(shell dirname $@)
$(OUT)/%.o: src/%.c $(CONFIG_FILE) $(deps_emcc) | $(OUT)
$(Q)mkdir -p $(dir $@)
$(VECHO) " CC\t$@\n"
$(Q)$(CC) -o $@ $(CFLAGS) $(CFLAGS_emcc) -c -MMD -MF [email protected] $<

$(BIN): $(OBJS) $(DEV_OBJS)
$(OUT):
$(Q)mkdir -p $@

$(BIN): $(OBJS) $(DEV_OBJS) | $(OUT)
$(VECHO) " LD\t$@\n"
$(Q)$(CC) -o $@ $(CFLAGS_emcc) $^ $(LDFLAGS)

$(CONFIG_FILE): FORCE
$(Q)mkdir -p $(OUT)
$(Q)echo "$(CFLAGS)" | xargs -n1 | sort | sed -n 's/^RV32_FEATURE/ENABLE/p' > [email protected]
$(Q)if ! cmp -s $@ [email protected] 2>/dev/null; then \
mv [email protected] $@; \
$(PRINTF) "Configuration updated. Check $(OUT)/.config for configured items.\n"; \
else \
$(RM) [email protected]; \
fi

.PHONY: FORCE config
FORCE:
config: $(CONFIG_FILE)
$(CONFIG_FILE):
$(Q)echo "$(CFLAGS)" | xargs -n1 | sort | sed -n 's/^RV32_FEATURE/ENABLE/p' > $@
$(VECHO) "Check the file $(OUT)/.config for configured items.\n"

# Tools
include mk/tools.mk
Expand Down Expand Up @@ -434,4 +482,7 @@ distclean: clean
$(Q)-$(RM) -r $(SOFTFLOAT_DUMMY_PLAT) $(OUT)/softfloat
$(Q)$(call notice, [OK])

.PHONY: all config tool check check-hello misalign misalign-in-blk-emu mmu-test
.PHONY: gdbstub-test doom quake clean distclean artifact

-include $(deps)
8 changes: 4 additions & 4 deletions mk/external.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ COMPRESSED_IS_DIR :=
EXTRACTOR :=
VERIFIER :=

# temporarily files to store correct SHA value and computed SHA value
# Temporary files to store correct SHA value and computed SHA value
# respectively for verification of directory source
$(eval SHA_FILE1 := $(shell mktemp))
$(eval SHA_FILE2 := $(shell mktemp))
SHA_FILE1 := $(shell mktemp)
SHA_FILE2 := $(shell mktemp)

# $(1): compressed source
define prologue
Expand All @@ -17,7 +17,7 @@ endef

# $(1), $(2), $(3): files to be deleted
define epilogue
$(eval _ := $(shell $(RM) $(1) $(2) $(3)))
$(RM) $(1) $(2) $(3)
endef

# $(1): compressed source URL
Expand Down
8 changes: 5 additions & 3 deletions mk/riscv-arch-test.mk
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
riscof-check:
$(Q)if [ "$(shell pip show riscof 2>&1 | head -n 1 | cut -d' ' -f1)" = "WARNING:" ]; then \
$(PRINTF) "Run 'pip3 install -r requirements.txt to install dependencies.\n"; \
exit 1; \
fi;
$(PRINTF) "Run 'pip3 install -r requirements.txt' to install dependencies.\n"; \
exit 1; \
fi

ARCH_TEST_DIR ?= tests/riscv-arch-test
ARCH_TEST_SUITE ?= $(ARCH_TEST_DIR)/riscv-test-suite
Expand All @@ -27,3 +27,5 @@ endif
--config=$(RISCV_TARGET)/config.ini \
--suite=$(ARCH_TEST_SUITE) \
--env=$(ARCH_TEST_DIR)/riscv-test-suite/env

.PHONY: riscof-check arch-test
6 changes: 4 additions & 2 deletions mk/softfloat.mk
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,13 @@ $(SOFTFLOAT_DUMMY_PLAT):
$(Q)touch $@

$(SOFTFLOAT_FILES): $(SOFTFLOAT_SENTINEL)
$(OUT)/softfloat/%.o: $(SOFTFLOAT_DIR)/%.c $(SOFTFLOAT_SENTINEL) $(SOFTFLOAT_DUMMY_PLAT)
$(Q)mkdir -p $(shell dirname $@)
$(OUT)/softfloat/%.o: $(SOFTFLOAT_DIR)/%.c $(CONFIG_FILE) $(SOFTFLOAT_SENTINEL) $(SOFTFLOAT_DUMMY_PLAT) | $(OUT)/softfloat $(OUT)/softfloat/RISCV
$(VECHO) " CC\t$@\n"
$(Q)$(CC) -o $@ $(CFLAGS) $(CFLAGS_softfloat) -c -MMD -MF [email protected] $<

$(OUT)/softfloat $(OUT)/softfloat/RISCV:
$(Q)mkdir -p $@

SOFTFLOAT_LIB := $(OUT)/softfloat/softfloat.a
$(SOFTFLOAT_LIB): $(SOFTFLOAT_OBJS)
$(VECHO) " AR\t$@\n"
Expand Down
9 changes: 7 additions & 2 deletions mk/system.mk
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ $(BUILD_DTB2C): $(BIN_TO_C) $(BUILD_DTB)
$(VECHO) " BIN2C\t$@\n"
$(Q)$(BIN_TO_C) $(BUILD_DTB) > $@

$(DEV_OUT)/%.o: $(DEV_SRC)/%.c $(deps_emcc)
$(Q)mkdir -p $(DEV_OUT)
$(DEV_OUT)/%.o: $(DEV_SRC)/%.c $(CONFIG_FILE) $(deps_emcc) | $(DEV_OUT)
$(VECHO) " CC\t$@\n"
$(Q)$(CC) -o $@ $(CFLAGS) $(CFLAGS_emcc) -c -MMD -MF [email protected] $<

$(DEV_OUT):
$(Q)mkdir -p $@

DEV_OBJS := $(patsubst $(DEV_SRC)/%.c, $(DEV_OUT)/%.o, $(wildcard $(DEV_SRC)/*.c))
deps := $(DEV_OBJS:%.o=%.o.d)

Expand All @@ -46,4 +49,6 @@ system_deps += artifact $(BUILD_DTB) $(BUILD_DTB2C) $(BIN)
system: $(system_deps)
$(system_action)

.PHONY: system

endif
20 changes: 14 additions & 6 deletions mk/tests.mk
Original file line number Diff line number Diff line change
Expand Up @@ -85,31 +85,39 @@ $(CACHE_TEST_TARGET): $(CACHE_TEST_OBJS)
$(VECHO) " CC\t$@\n"
$(Q)$(CC) $^ -o $@ $(LDFLAGS)

$(CACHE_TEST_OUTDIR)/%.o: $(CACHE_TEST_SRCDIR)/%.c
$(CACHE_TEST_OUTDIR)/%.o: $(CACHE_TEST_SRCDIR)/%.c $(CONFIG_FILE) | $(CACHE_TEST_OUTDIR) $(CACHE_TEST_OUTDIR)/lfu
$(VECHO) " CC\t$@\n"
$(Q)mkdir -p $(dir $@)/lfu
$(Q)$(CC) -o $@ $(CFLAGS) -I./src -c -MMD -MF [email protected] $<

$(CACHE_TEST_OUTDIR) $(CACHE_TEST_OUTDIR)/lfu:
$(Q)mkdir -p $@

$(MAP_TEST_OUT): $(MAP_TEST_TARGET)
$(Q)touch $@

$(MAP_TEST_TARGET): $(MAP_TEST_OBJS)
$(VECHO) " CC\t$@\n"
$(Q)$(CC) $^ -o $@ $(LDFLAGS)

$(MAP_TEST_OUTDIR)/%.o: $(MAP_TEST_SRCDIR)/%.c
$(MAP_TEST_OUTDIR)/%.o: $(MAP_TEST_SRCDIR)/%.c $(CONFIG_FILE) | $(MAP_TEST_OUTDIR)
$(VECHO) " CC\t$@\n"
$(Q)mkdir -p $(dir $@)
$(Q)$(CC) -o $@ $(CFLAGS) -I./src -c -MMD -MF [email protected] $<

$(MAP_TEST_OUTDIR):
$(Q)mkdir -p $@

$(PATH_TEST_OUT): $(PATH_TEST_TARGET)
$(Q)touch $@

$(PATH_TEST_TARGET): $(PATH_TEST_OBJS)
$(VECHO) " CC\t$@\n"
$(Q)$(CC) $^ -o $@ $(LDFLAGS)

$(PATH_TEST_OUTDIR)/%.o: $(PATH_TEST_SRCDIR)/%.c
$(PATH_TEST_OUTDIR)/%.o: $(PATH_TEST_SRCDIR)/%.c $(CONFIG_FILE) | $(PATH_TEST_OUTDIR)
$(VECHO) " CC\t$@\n"
$(Q)mkdir -p $(dir $@)
$(Q)$(CC) -o $@ $(CFLAGS) -I./src -c -MMD -MF [email protected] $<

$(PATH_TEST_OUTDIR):
$(Q)mkdir -p $@

.PHONY: tests run-test-cache run-test-map run-test-path
4 changes: 3 additions & 1 deletion mk/tools.mk
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ HIST_OBJS := \
HIST_OBJS := $(addprefix $(OUT)/, $(HIST_OBJS))
deps += $(HIST_OBJS:%.o=%.o.d)

$(OUT)/%.o: tools/%.c
$(OUT)/%.o: tools/%.c | $(OUT)
$(VECHO) " CC\t$@\n"
$(Q)$(CC) -o $@ $(CFLAGS) -Wno-missing-field-initializers -Isrc -c -MMD -MF [email protected] $<

Expand All @@ -39,3 +39,5 @@ LINUX_IMAGE_SRC = $(BUILDROOT_DATA) $(LINUX_DATA)
build-linux-image: $(LINUX_IMAGE_SRC)
$(Q)./tools/build-linux-image.sh
$(Q)$(PRINTF) "Build done.\n"

.PHONY: build-linux-image
8 changes: 7 additions & 1 deletion mk/wasm.mk
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ CFLAGS += -mtail-call

# Build emscripten-port SDL
ifeq ($(call has, SDL), 1)
CFLAGS_emcc += -sUSE_SDL=2 -sSDL2_MIXER_FORMATS=wav,mid -sUSE_SDL_MIXER=2
# Disable STRICT mode to avoid -Werror in SDL2_mixer port compilation.
# The emscripten-ports/SDL2_mixer was archived in Jan 2024 and has warnings
# in music_modplug.c that become fatal errors under STRICT mode.
CFLAGS_emcc += -sSTRICT=0 -sUSE_SDL=2 -sSDL2_MIXER_FORMATS=wav,mid -sUSE_SDL_MIXER=2
OBJS_EXT += syscall_sdl.o
LDFLAGS += -pthread
endif
Expand Down Expand Up @@ -159,4 +162,7 @@ start-web: $(start_web_deps)
$(foreach T, $(STATIC_WEB_FILES), $(call cp-web-file, $(T)))
$(Q)mv $(DEMO_DIR)/*.html $(DEMO_DIR)/index.html
$(Q)python3 -m http.server --bind $(DEMO_IP) $(DEMO_PORT) --directory $(DEMO_DIR)

.PHONY: check-demo-dir-exist start-web

endif
Loading
Loading