aboutsummaryrefslogtreecommitdiff
path: root/rv64cpu/sw
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-03-15 16:07:39 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-03-15 16:07:39 +0800
commitf6441a2e6f901748b504ef93872649c9463a404e (patch)
tree54332548c2e2b74b44aba646a09cffb543856050 /rv64cpu/sw
downloadrcc-project-f6441a2e6f901748b504ef93872649c9463a404e.tar.gz
rcc-project-f6441a2e6f901748b504ef93872649c9463a404e.tar.xz
initial commit: project architecture
Diffstat (limited to 'rv64cpu/sw')
-rw-r--r--rv64cpu/sw/CMakeLists.txt71
-rw-r--r--rv64cpu/sw/baremetal/cache_test/.gitkeep0
-rw-r--r--rv64cpu/sw/baremetal/hello_uart/.gitkeep0
-rw-r--r--rv64cpu/sw/baremetal/timer_irq/.gitkeep0
-rw-r--r--rv64cpu/sw/common/.gitkeep0
-rw-r--r--rv64cpu/sw/common/link.ld76
6 files changed, 147 insertions, 0 deletions
diff --git a/rv64cpu/sw/CMakeLists.txt b/rv64cpu/sw/CMakeLists.txt
new file mode 100644
index 0000000..c43580f
--- /dev/null
+++ b/rv64cpu/sw/CMakeLists.txt
@@ -0,0 +1,71 @@
+# ─── Software Build (Bare-Metal) ─────────────────────────────────────────────────
+#
+# This CMakeLists.txt is only included when BUILD_SW=ON and requires
+# the RISC-V cross-compilation toolchain:
+#
+# cmake -B build_sw -DBUILD_SW=ON \
+# -DCMAKE_TOOLCHAIN_FILE=tools/toolchain-riscv64.cmake
+#
+# ─────────────────────────────────────────────────────────────────────────────────
+
+enable_language(ASM)
+
+set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/common/link.ld)
+set(STARTUP_SRC ${CMAKE_CURRENT_SOURCE_DIR}/common/start.S)
+
+# ─── Helper: create a bare-metal firmware target ─────────────────────────────────
+function(add_firmware)
+ cmake_parse_arguments(FW "" "NAME" "SOURCES" ${ARGN})
+
+ add_executable(${FW_NAME}.elf
+ ${STARTUP_SRC}
+ ${FW_SOURCES}
+ )
+
+ target_include_directories(${FW_NAME}.elf PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/common
+ )
+
+ target_link_options(${FW_NAME}.elf PRIVATE
+ -T${LINKER_SCRIPT}
+ -Wl,-Map=${FW_NAME}.map
+ )
+
+ # Generate .bin
+ add_custom_command(TARGET ${FW_NAME}.elf POST_BUILD
+ COMMAND ${CMAKE_OBJCOPY} -O binary
+ ${FW_NAME}.elf ${FW_NAME}.bin
+ COMMENT "Generating ${FW_NAME}.bin"
+ )
+
+ # Generate .hex (for $readmemh)
+ add_custom_command(TARGET ${FW_NAME}.elf POST_BUILD
+ COMMAND ${CMAKE_OBJCOPY} -O verilog
+ ${FW_NAME}.elf ${FW_NAME}.hex
+ COMMENT "Generating ${FW_NAME}.hex"
+ )
+
+ # Print size
+ add_custom_command(TARGET ${FW_NAME}.elf POST_BUILD
+ COMMAND ${CMAKE_SIZE} ${FW_NAME}.elf
+ )
+endfunction()
+
+# ═══════════════════════════════════════════════════════════════════════════════════
+# Firmware Targets — uncomment as you create the source files
+# ═══════════════════════════════════════════════════════════════════════════════════
+#
+# add_firmware(
+# NAME hello_uart
+# SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/baremetal/hello_uart/main.c
+# )
+#
+# add_firmware(
+# NAME timer_irq
+# SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/baremetal/timer_irq/main.c
+# )
+#
+# add_firmware(
+# NAME cache_test
+# SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/baremetal/cache_test/main.c
+# )
diff --git a/rv64cpu/sw/baremetal/cache_test/.gitkeep b/rv64cpu/sw/baremetal/cache_test/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/rv64cpu/sw/baremetal/cache_test/.gitkeep
diff --git a/rv64cpu/sw/baremetal/hello_uart/.gitkeep b/rv64cpu/sw/baremetal/hello_uart/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/rv64cpu/sw/baremetal/hello_uart/.gitkeep
diff --git a/rv64cpu/sw/baremetal/timer_irq/.gitkeep b/rv64cpu/sw/baremetal/timer_irq/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/rv64cpu/sw/baremetal/timer_irq/.gitkeep
diff --git a/rv64cpu/sw/common/.gitkeep b/rv64cpu/sw/common/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/rv64cpu/sw/common/.gitkeep
diff --git a/rv64cpu/sw/common/link.ld b/rv64cpu/sw/common/link.ld
new file mode 100644
index 0000000..705a25d
--- /dev/null
+++ b/rv64cpu/sw/common/link.ld
@@ -0,0 +1,76 @@
+/* ═══════════════════════════════════════════════════════════════════════════════
+ * richard-cpu Linker Script
+ *
+ * Memory map matches rtl/soc/mem_map.sv
+ * ═══════════════════════════════════════════════════════════════════════════════ */
+
+OUTPUT_ARCH("riscv")
+ENTRY(_start)
+
+MEMORY
+{
+ /* Boot ROM / SRAM — 256 MB total addressable, practical limit is FPGA BRAM */
+ ROM (rx) : ORIGIN = 0x00000000, LENGTH = 64K
+ RAM (rwx) : ORIGIN = 0x00010000, LENGTH = 256M - 64K
+}
+
+SECTIONS
+{
+ /* ── Code ──────────────────────────────────────────────────────────────── */
+ .text : ALIGN(4)
+ {
+ *(.text.init) /* _start / trap vector MUST be first */
+ *(.text .text.*)
+ } > ROM
+
+ /* ── Read-only data ───────────────────────────────────────────────────── */
+ .rodata : ALIGN(8)
+ {
+ *(.rodata .rodata.*)
+ *(.srodata .srodata.*)
+ } > ROM
+
+ /* ── Initialized data (load from ROM, copy to RAM) ────────────────────── */
+ .data : ALIGN(8)
+ {
+ _data_start = .;
+ *(.data .data.*)
+ *(.sdata .sdata.*)
+ _data_end = .;
+ } > RAM AT > ROM
+
+ _data_load = LOADADDR(.data);
+
+ /* ── BSS (zero-initialized) ──────────────────────────────────────────── */
+ .bss (NOLOAD) : ALIGN(8)
+ {
+ _bss_start = .;
+ *(.bss .bss.*)
+ *(.sbss .sbss.*)
+ *(COMMON)
+ _bss_end = .;
+ } > RAM
+
+ /* ── Stack (grows downward) ──────────────────────────────────────────── */
+ . = ALIGN(16);
+ _stack_bottom = .;
+ . = . + 8K;
+ _stack_top = .;
+
+ /* ── Heap ────────────────────────────────────────────────────────────── */
+ _heap_start = .;
+
+ /* ── tohost / fromhost (Compliance test interface) ────────────────────── */
+ .tohost (NOLOAD) : ALIGN(8)
+ {
+ PROVIDE(tohost = .); . += 8;
+ PROVIDE(fromhost = .); . += 8;
+ } > RAM
+
+ /DISCARD/ :
+ {
+ *(.comment)
+ *(.note.*)
+ *(.eh_frame*)
+ }
+}