Skip to content

Commit

Permalink
rv: Add PicoRV32 initial firmware environment
Browse files Browse the repository at this point in the history
Signed-off-by: João Silva <jgc3silva@gmail.com>
  • Loading branch information
vankxr committed Jun 10, 2024
1 parent 6c1c568 commit c383ce3
Show file tree
Hide file tree
Showing 17 changed files with 2,153 additions and 0 deletions.
62 changes: 62 additions & 0 deletions .github/workflows/rv-fw-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: P*icoRV32 firmware build tests

on:
pull_request:
paths:
- "software/rv/**"
branches: [ "v2" ]
push:
paths:
- "software/rv/**"
branches: [ "v2" ]
workflow_dispatch:

env:
RV_TOOLS_ROOT: "/opt/riscv"
RV_TOOLS_BRANCH: "2024.04.12"

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Update install
run:
sudo apt-get update
timeout-minutes: 5

- name: Install toolchain
run: |
sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev libslirp-dev
git clone --branch $RV_TOOLS_BRANCH https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain
mkdir build
cd build
../configure --prefix=$RV_TOOLS_ROOT --enable-multilib
make -j$(nproc)
- name: Install build dependencies
run: |
# Install armmem
wget https://github.com/vankxr/armmem/releases/download/1.0-1/armmem_1.0-1_amd64.deb
sudo dpkg -i armmem_1.0-1_amd64.deb
timeout-minutes: 5

- uses: actions/checkout@v4
with:
fetch-depth: 1
clean: true

- name: Build PicoRV32 firmware
run: |
export PATH="$RV_TOOLS_ROOT/bin:$PATH"
cd ${{github.workspace}}/software/rv
make BUILD_TYPE=release
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: rv_firmware
path: ${{github.workspace}}/software/rv/bin/v*
retention-days: 30
6 changes: 6 additions & 0 deletions software/rv/.vscode/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*

!.gitignore
!c_cpp_properties.json
!tasks.json
!get_gcc_defines.sh
344 changes: 344 additions & 0 deletions software/rv/.vscode/c_cpp_properties.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions software/rv/.vscode/get_gcc_defines.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

riscv64-unknown-elf-gcc -mabi=ilp32 -march=rv32imc -E -dM - < /dev/null | sort | sed -e 's/"/\\"/g' | sed -r -e 's/#define ([^ ]+).([^\n]+)/"\1=\2",/g'
41 changes: 41 additions & 0 deletions software/rv/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"command": "make",
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Rebuild",
"type": "shell",
"command": "make clean; make"
},
{
"label": "Build (Increment Version)",
"type": "shell",
"command": "make INC_VERSION=y"
},
{
"label": "Increment Version",
"type": "shell",
"command": "make inc-version"
},
{
"label": "Decrement Version",
"type": "shell",
"command": "make dec-version"
},
{
"label": "Clean",
"type": "shell",
"command": "make clean"
}
]
}
191 changes: 191 additions & 0 deletions software/rv/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
# App Config
APP_ADDRESS = 0x00000000
APP_NAME = icyradio-rv

# Multiprocessing
MAX_PARALLEL =

# Directories
TARGETDIR = bin
SOURCEDIR = src
OBJECTDIR = bin/obj
INCLUDEDIR = include

STRUCT := $(shell find $(SOURCEDIR) -type d)

SOURCEDIRSTRUCT := $(filter-out %/include, $(STRUCT))
INCLUDEDIRSTRUCT := $(filter %/include, $(STRUCT))
OBJECTDIRSTRUCT := $(subst $(SOURCEDIR), $(OBJECTDIR), $(SOURCEDIRSTRUCT))

# Build type
BUILD_TYPE ?= debug

# Version
$(shell if ! test -f $(TARGETDIR)/.version; then echo 0 > $(TARGETDIR)/.version; fi)

INC_VERSION ?= n
BUILD_VERSION = $(shell cat $(TARGETDIR)/.version)

ifeq ($(INC_VERSION), y)
$(shell if test -f .vscode/launch.json; then sed -i 's/v$(BUILD_VERSION).$(APP_NAME)/v$(shell echo $$(($(BUILD_VERSION) + 1))).$(APP_NAME)/g' .vscode/launch.json; fi)
$(shell echo $$(($(BUILD_VERSION) + 1)) > $(TARGETDIR)/.version)
$(shell rm -rf $(OBJECTDIR)/*)
BUILD_VERSION = $(shell cat $(TARGETDIR)/.version)
endif

ifeq ($(BUILD_VERSION), 0)
$(shell echo $$(($(BUILD_VERSION) + 1)) > $(TARGETDIR)/.version)
$(shell rm -rf $(OBJECTDIR)/*)
BUILD_VERSION = $(shell cat $(TARGETDIR)/.version)
endif

# Compillers & Linker
CC = riscv64-unknown-elf-gcc
CXX = riscv64-unknown-elf-g++
LD = riscv64-unknown-elf-gcc
AS = riscv64-unknown-elf-as
STRIP = riscv64-unknown-elf-strip
OBJCOPY = riscv64-unknown-elf-objcopy
OBJDUMP = riscv64-unknown-elf-objdump
GDB = riscv64-unknown-elf-gdb

# Compillers & Linker flags
ASFLAGS = $(addprefix -I,$(INCLUDEDIRSTRUCT)) -mabi=ilp32 -march=rv32imc
CFLAGS = $(addprefix -I,$(INCLUDEDIRSTRUCT)) -mabi=ilp32 -march=rv32imc -nostdlib -nostartfiles -ffunction-sections -fdata-sections -ffreestanding -Os -std=gnu99 -Wpointer-arith -Werror -DBUILD_VERSION=$(BUILD_VERSION)
CXXFLAGS = $(addprefix -I,$(INCLUDEDIRSTRUCT)) -mabi=ilp32 -march=rv32imc -nostdlib -nostartfiles -ffunction-sections -fdata-sections -ffreestanding -fno-rtti -fno-exceptions -Os -std=c++17 -Wpointer-arith -Werror -DBUILD_VERSION=$(BUILD_VERSION)
LDFLAGS = -mabi=ilp32 -march=rv32imc --specs=nano.specs --specs=nosys.specs -nostdlib -nostartfiles -ffunction-sections -fdata-sections -ffreestanding -Wl,--gc-sections
LDLIBS = -lm -lc -lgcc -lnosys

ifeq ($(BUILD_TYPE), debug)
CFLAGS += -g
CXXFLAGS += -g
endif

## Linker scripts
LDSCRIPT = ld/picorv32_app.ld

# Target
TARGET = $(TARGETDIR)/v$(BUILD_VERSION).$(APP_NAME)

# Sources & objects
SRCFILES := $(addsuffix /*, $(SOURCEDIRSTRUCT))
SRCFILES := $(wildcard $(SRCFILES))

ASSOURCES := $(filter %.s, $(SRCFILES))
ASOBJECTS := $(subst $(SOURCEDIR), $(OBJECTDIR), $(ASSOURCES:%.s=%.o))

CASSOURCES := $(filter %.S, $(SRCFILES))
CASOBJECTS := $(subst $(SOURCEDIR), $(OBJECTDIR), $(CASSOURCES:%.S=%.o))

CSOURCES := $(filter %.c, $(SRCFILES))
COBJECTS := $(subst $(SOURCEDIR), $(OBJECTDIR), $(CSOURCES:%.c=%.o))

CXXSOURCES := $(filter %.cpp, $(SRCFILES))
CXXOBJECTS := $(subst $(SOURCEDIR), $(OBJECTDIR), $(CXXSOURCES:%.cpp=%.o))

SOURCES = $(ASSOURCES) $(CASSOURCES) $(CSOURCES) $(CXXSOURCES)
OBJECTS = $(ASOBJECTS) $(CASOBJECTS) $(COBJECTS) $(CXXOBJECTS)

all: clean-bin make-dir version compile mem-usage

compile:
@$(MAKE) INC_VERSION=n --no-print-directory -j${MAX_PARALLEL} $(TARGET).elf
@$(MAKE) INC_VERSION=n --no-print-directory -j${MAX_PARALLEL} $(TARGET).bin $(TARGET).hex $(TARGET).lss
@$(MAKE) INC_VERSION=n --no-print-directory -j${MAX_PARALLEL} $(TARGET).h

$(TARGET).lss: $(TARGET).elf
@echo Creating LSS file \'$@\'...
@$(OBJDUMP) -S --disassemble $< > $@

$(TARGET).bin: $(TARGET).elf
@echo Creating BIN file \'$@\'...
@$(OBJCOPY) -O binary --only-section=.irom0.text --only-section=.iram1.text --only-section=.dram1.data $< $(TARGET).flash.bin
@$(OBJCOPY) -O binary --only-section=.iram0.text --only-section=.dram0.data $< $(TARGET).bram.bin
@$(OBJCOPY) -O binary --only-section=.drom0.data $< $(TARGET).brom.bin

$(TARGET).hex: $(TARGET).elf
@echo Creating HEX file \'$@\'...
@$(OBJCOPY) -O ihex $< $@
@$(OBJCOPY) -O ihex --only-section=.irom0.text --only-section=.iram1.text --only-section=.dram1.data $< $(TARGET).flash.hex
@$(OBJCOPY) -O ihex --only-section=.iram0.text --only-section=.dram0.data $< $(TARGET).bram.hex
@$(OBJCOPY) -O ihex --only-section=.drom0.data $< $(TARGET).brom.hex

$(TARGET).h: $(TARGET).bin
@echo Generating C header file \'$@\'...
@xxd -u -i $(TARGET).flash.bin $(TARGET).flash.h
@sed -i 's/0X/0x/g' $(TARGET).flash.h
@sed -i 's/\s\s/ /g' $(TARGET).flash.h
@sed -i 's/unsigned char $(TARGETDIR)_v$(BUILD_VERSION)_/static const uint8_t /g' $(TARGET).flash.h
@sed -i 's/unsigned int $(TARGETDIR)_v$(BUILD_VERSION)_/static const uint32_t /g' $(TARGET).flash.h
@xxd -u -i $(TARGET).bram.bin $(TARGET).bram.h
@sed -i 's/0X/0x/g' $(TARGET).bram.h
@sed -i 's/\s\s/ /g' $(TARGET).bram.h
@sed -i 's/unsigned char $(TARGETDIR)_v$(BUILD_VERSION)_/static const uint8_t /g' $(TARGET).bram.h
@sed -i 's/unsigned int $(TARGETDIR)_v$(BUILD_VERSION)_/static const uint32_t /g' $(TARGET).bram.h
@xxd -u -i $(TARGET).brom.bin $(TARGET).brom.h
@sed -i 's/0X/0x/g' $(TARGET).brom.h
@sed -i 's/\s\s/ /g' $(TARGET).brom.h
@sed -i 's/unsigned char $(TARGETDIR)_v$(BUILD_VERSION)_/static const uint8_t /g' $(TARGET).brom.h
@sed -i 's/unsigned int $(TARGETDIR)_v$(BUILD_VERSION)_/static const uint32_t /g' $(TARGET).brom.h
@cat $(TARGET).flash.h $(TARGET).bram.h $(TARGET).brom.h > $(TARGET).h

$(TARGET).elf: $(OBJECTS)
@echo ---------------------------------------------------------------------------
@echo Creating ELF file \'$@\'...
@$(LD) $(LDFLAGS) -o $@ $^ -T $(LDSCRIPT) $(LDLIBSPATH) $(LDLIBS) -Wl,-Map=$(TARGET).map
ifeq ($(BUILD_TYPE), release)
@$(STRIP) -g $@
endif

$(OBJECTDIR)/%.o: $(SOURCEDIR)/%.s
@echo Compilling ASM file \'$<\' \> \'$@\'...
@$(AS) $(ASFLAGS) -MD -c -o $@ $<

$(OBJECTDIR)/%.o: $(SOURCEDIR)/%.S
@echo Compilling ASM file \'$<\' \> \'$@\'...
@$(CC) $(ASFLAGS) -MD -c -o $@ $<

$(OBJECTDIR)/%.o: $(SOURCEDIR)/%.c
@echo Compilling C file \'$<\' \> \'$@\'...
@$(CC) $(CFLAGS) -MD -c -o $@ $<

$(OBJECTDIR)/%.o: $(SOURCEDIR)/%.cpp
@echo Compilling C++ file \'$<\' \> \'$@\'...
@$(CXX) $(CXXFLAGS) -MD -c -o $@ $<

debug: $(TARGET).elf
$(GDB) $(TARGET).elf

inc-version:
@echo $$(($(BUILD_VERSION) + 1)) > $(TARGETDIR)/.version
@if test -f .vscode/launch.json; then sed -i 's/v$(BUILD_VERSION).$(APP_NAME)/v$(shell echo $$(($(BUILD_VERSION) + 1))).$(APP_NAME)/g' .vscode/launch.json; fi

dec-version:
@echo $$(($(BUILD_VERSION) - 1)) > $(TARGETDIR)/.version
@if test -f .vscode/launch.json; then sed -i 's/v$(BUILD_VERSION).$(APP_NAME)/v$(shell echo $$(($(BUILD_VERSION) - 1))).$(APP_NAME)/g' .vscode/launch.json; fi

version:
@echo Build version: v$(BUILD_VERSION)
@echo ---------------------------------------------------------------------------

mem-usage: $(TARGET).elf
@echo ---------------------------------------------------------------------------
@armmem -l $(LDSCRIPT) -d -h $<

make-dir:
@mkdir -p $(OBJECTDIRSTRUCT)

clean-bin:
@rm -f $(TARGETDIR)/*.h
@rm -f $(TARGETDIR)/*.lss
@rm -f $(TARGETDIR)/*.hex
@rm -f $(TARGETDIR)/*.bin
@rm -f $(TARGETDIR)/*.map
@rm -f $(TARGETDIR)/*.elf

clean: clean-bin
@rm -rf $(OBJECTDIR)/*

-include $(OBJECTS:.o=.d)

.PHONY: clean clean-bin make-dir mem-usage version dec-version inc-version debug compile all
3 changes: 3 additions & 0 deletions software/rv/bin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*
!.version
!.gitignore
1 change: 1 addition & 0 deletions software/rv/bin/.version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
Loading

0 comments on commit c383ce3

Please sign in to comment.