Skip to content

Commit

Permalink
Squashed changes
Browse files Browse the repository at this point in the history
All the changes for 64-bit and CHERI.

Change-Id: I2bff6c51a8675739feaca971b5d4c20430b4a13c
  • Loading branch information
Lawrence Esswood committed Jul 11, 2024
1 parent 283a241 commit d48c1d6
Show file tree
Hide file tree
Showing 14 changed files with 1,188 additions and 288 deletions.
15 changes: 15 additions & 0 deletions AppMakefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,22 @@ $(foreach platform, $(TOCK_TARGETS), $(eval $(call BUILD_RULES,$(call ARCH_FN,$(
$(BUILDDIR)/$(PACKAGE_NAME).tab: $(foreach platform, $(TOCK_TARGETS), $(BUILDDIR)/$(call ARCH_FN,$(platform))/$(call OUTPUT_NAME_FN,$(platform)).elf)
$(Q)$(ELF2TAB) $(ELF2TAB_ARGS) -o $@ $^

#
# These don't really belong here, but I wanted to provide an easy way to try
# running the examples on cheri QEMU.

THIS_FILE := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
TOCK_DIR ?= $(THIS_FILE)../tock

# Run a hybrid app
.PHONY: run_hybrid
run_hybrid : $(BUILDDIR)/$(PACKAGE_NAME).tab
APP_BIN=$(abspath $(BUILDDIR)/rv64imacxcheri/rv64imacxcheri.tbf) make -C $(TOCK_DIR)/boards/qemu_cheri_virt run_app

# Run a purecap app
.PHONY: run_pure
run_pure : $(BUILDDIR)/$(PACKAGE_NAME).tab
APP_BIN=$(abspath $(BUILDDIR)/rv64imacxcheripure/rv64imacxcheripure.tbf) make -C $(TOCK_DIR)/boards/qemu_cheri_virt run_app

# Rules for building apps
.PHONY: all
Expand Down
176 changes: 147 additions & 29 deletions Configuration.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,28 @@ MAKEFLAGS += -r
MAKEFLAGS += -R

# Toolchain programs
ifeq ($(CHERI),)
AR := -ar
AS := -as
CXX := -g++
OBJDUMP := -objdump
RANLIB := -ranlib
READELF := -readelf
SIZE := -size
else
# AppMakefile.mk tries to append these to the "TOOLCHAIN_x" parameter.
# Sadly, the compiler for the CHERI toolchain is not llvm-clang, it is just clang,
# so we need the names without a hyphen unlike above.
AR := ar
AS := as
CXX := clang++
OBJDUMP := objdump
RANLIB := ranlib
READELF := readelf
SIZE := size
STRIP := strip
OBJCOPY := objcopy
endif

# Set default region sizes
STACK_SIZE ?= 2048
Expand Down Expand Up @@ -65,6 +80,12 @@ OPENTITAN_TOCK_TARGETS := rv32imc|rv32imc.0x20030080.0x10005000|0x20030080|0x100
ARTY_E21_TOCK_TARGETS := rv32imac|rv32imac.0x40430060.0x80004000|0x40430060|0x80004000\
rv32imac|rv32imac.0x40440060.0x80007000|0x40440060|0x80007000

CHERI_TARGETS := rv64imacxcheri\
rv64imacxcheripure

ifneq ($(CHERI),)
TOCK_TARGETS ?= $(CHERI_TARGETS)
else
# Include the RISC-V targets.
# rv32imac|rv32imac.0x20040060.0x80002800 # RISC-V for HiFive1b
# rv32imac|rv32imac.0x403B0060.0x3FCC0000 # RISC-V for ESP32-C3
Expand All @@ -81,26 +102,28 @@ TOCK_TARGETS ?= cortex-m0\
$(OPENTITAN_TOCK_TARGETS) \
$(ARTY_E21_TOCK_TARGETS)
endif
endif

# Generate TOCK_ARCHS, the set of architectures listed in TOCK_TARGETS
TOCK_ARCHS := $(sort $(foreach target, $(TOCK_TARGETS), $(firstword $(subst |, ,$(target)))))

# Check if elf2tab exists, if not, install it using cargo.
ELF2TAB ?= elf2tab
ELF2TAB_REQUIRED_VERSION := 0.7.0
ELF2TAB_REQUIRED_VERSION := 0.10.2
ELF2TAB_EXISTS := $(shell $(SHELL) -c "command -v $(ELF2TAB)")
ELF2TAB_VERSION := $(shell $(SHELL) -c "$(ELF2TAB) --version | cut -d ' ' -f 2")

# Check elf2tab version
UPGRADE_ELF2TAB := $(shell $(SHELL) -c "printf '%s\n%s\n' '$(ELF2TAB_REQUIRED_VERSION)' '$(ELF2TAB_VERSION)' | sort --check=quiet --version-sort || echo yes")

ifeq ($(UPGRADE_ELF2TAB),yes)
$(info Trying to update elf2tab to >= $(ELF2TAB_REQUIRED_VERSION))
# Ensure that we install exactly the required version
ifneq ($(ELF2TAB_REQUIRED_VERSION),$(ELF2TAB_VERSION))
$(info Trying to update elf2tab to $(ELF2TAB_REQUIRED_VERSION))
ELF2TAB_EXISTS =
endif

ifndef ELF2TAB_EXISTS
$(shell cargo install elf2tab)
$(shell cargo install -f --version $(ELF2TAB_REQUIRED_VERSION) elf2tab)
# Check elf2tab version after install
ELF2TAB_VERSION := $(shell $(SHELL) -c "$(ELF2TAB) --version | cut -d ' ' -f 2")
UPGRADE_ELF2TAB := $(shell $(SHELL) -c "printf '%s\n%s\n' '$(ELF2TAB_REQUIRED_VERSION)' '$(ELF2TAB_VERSION)' | sort --check=quiet --version-sort || echo yes")
Expand All @@ -111,34 +134,50 @@ endif

ELF2TAB_ARGS += -n $(PACKAGE_NAME)
ELF2TAB_ARGS += --stack $(STACK_SIZE) --app-heap $(APP_HEAP_SIZE) --kernel-heap $(KERNEL_HEAP_SIZE) --kernel-major $(KERNEL_MAJOR_VERSION) --kernel-minor $(KERNEL_MINOR_VERSION)
# This helps keep the program nice and aligned. Otherwise the header ends up 76 bytes.
ELF2TAB_ARGS += --protected-region-size 96

# Setup the correct toolchain for each architecture.
TOOLCHAIN_cortex-m0 := arm-none-eabi
TOOLCHAIN_cortex-m3 := arm-none-eabi
TOOLCHAIN_cortex-m4 := arm-none-eabi
TOOLCHAIN_cortex-m7 := arm-none-eabi

THIS_FILE := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
CHERI_SDK ?= $(abspath ${THIS_FILE}/../cheri/output/sdk)

# RISC-V toolchains, irrespective of their name-tuple, can compile for
# essentially any target. Thus, try a few known names and choose the one for
# which a compiler is found.
ifneq (,$(shell which riscv64-none-elf-gcc 2>/dev/null))
TOOLCHAIN_rv32i := riscv64-none-elf

ifneq (,$(shell which $(CHERI_SDK)/bin/clang))
TOOLCHAIN_x := $(CHERI_SDK)/bin/
else ifneq (,$(shell which ~/cheri/output/sdk/bin/clang))
TOOLCHAIN_x := ~/cheri/output/sdk/bin/
else ifneq (,$(shell which riscv64-none-elf-gcc 2>/dev/null))
TOOLCHAIN_x := riscv64-none-elf
else ifneq (,$(shell which riscv32-none-elf-gcc 2>/dev/null))
TOOLCHAIN_rv32i := riscv32-none-elf
TOOLCHAIN_x := riscv32-none-elf
else ifneq (,$(shell which riscv64-elf-gcc 2>/dev/null))
TOOLCHAIN_rv32i := riscv64-elf
TOOLCHAIN_x := riscv64-elf
else ifneq (,$(shell which riscv64-unknown-elf-clang 2>/dev/null))
TOOLCHAIN_rv32i := riscv64-unknown-elf
TOOLCHAIN_x := riscv64-unknown-elf
else ifneq (,$(shell which riscv32-unknown-elf-clang 2>/dev/null))
TOOLCHAIN_rv32i := riscv32-unknown-elf
TOOLCHAIN_x := riscv32-unknown-elf
else
# Fallback option. We don't particularly want to throw an error (even if
# RISCV=1 is set) as this configuration makefile can be useful without a
# proper toolchain.
TOOLCHAIN_rv32i := riscv64-unknown-elf
TOOLCHAIN_x := riscv64-unknown-elf
endif
TOOLCHAIN_rv32imac := $(TOOLCHAIN_rv32i)
TOOLCHAIN_rv32imc := $(TOOLCHAIN_rv32i)

TOOLCHAIN_rv32i := $(TOOLCHAIN_x)
TOOLCHAIN_rv32imac := $(TOOLCHAIN_x)
TOOLCHAIN_rv32imc := $(TOOLCHAIN_x)
TOOLCHAIN_rv32imacxcheri := $(TOOLCHAIN_x)
TOOLCHAIN_rv64imac := $(TOOLCHAIN_x)
TOOLCHAIN_rv64imacxcheri := $(TOOLCHAIN_x)
TOOLCHAIN_rv64imacxcheripure := $(TOOLCHAIN_x)

# Setup the correct compiler. For cortex-m we only support GCC as it is the only
# toolchain with the PIC support we need for Tock userspace apps.
Expand All @@ -153,14 +192,24 @@ CC_cortex-m7 := $(CC_cortex-m)
# default to that.
ifeq ($(CLANG),)
# Default to GCC
CC_rv32 := -gcc
CC_X := -gcc
else
# If `CLANG=1` on command line, use -clang
CC_rv32 := -clang
# With the toolchain built for the CHERI, the names are different
ifeq ($(CHERI),)
CC_X := -clang
else
CC_X := clang
endif
endif
CC_rv32i := $(CC_rv32)
CC_rv32imc := $(CC_rv32)
CC_rv32imac := $(CC_rv32)
CC_rv32 := $(CC_X)
CC_rv32i := $(CC_X)
CC_rv32imc := $(CC_X)
CC_rv32imac := $(CC_X)
CC_rv32imacxcheri :=$(CC_X)
CC_rv64imac := $(CC_X)
CC_rv64imacxcheri := $(CC_X)
CC_rv64imacxcheripure := $(CC_X)

# Flags for building app Assembly, C, C++ files
# n.b. make convention is that CPPFLAGS are shared for C and C++ sources
Expand All @@ -173,13 +222,17 @@ override CPPFLAGS += \
-Os\
-fdata-sections -ffunction-sections\
-fstack-usage\
-fno-rtti\
-fno-exceptions\
-Wall\
-Wextra

override WLFLAGS += \
-Wl,--warn-common\
-Wl,--gc-sections\
-Wl,--build-id=none


# Various flags for a specific toolchain. Different compilers may have different
# supported features. For GCC we warn if the compiler estimates the stack usage
# will be greater than the allocated stack size.
Expand Down Expand Up @@ -208,6 +261,7 @@ endif
# fully relocatable. Therefore, just including these flags is not sufficient to
# build a full PIC app for Tock. So, we split these out, and only include them
# for architectures where we have full PIC support.

override CPPFLAGS_PIC += \
-Wl,--emit-relocs\
-fPIC
Expand All @@ -220,40 +274,95 @@ override CFLAGS_rv32imc += $(CFLAGS_rv32)
override CFLAGS_rv32imac += $(CFLAGS_rv32)

override CPPFLAGS_rv32 += \
$(CPPFLAGS_toolchain_rv32)
$(CPPFLAGS_toolchain_rv32)\
-fPIE\
--target=riscv32-none-elf\

# Add different flags for different architectures
override CPPFLAGS_rv32i += $(CPPFLAGS_rv32) \
-march=rv32i\
-mabi=ilp32\
-mcmodel=medlow

override WLFLAGS_rv32i += \
-Wl,--no-relax # Prevent use of global_pointer for riscv
WLFLAGS_x = -Wl,--no-relax # Prevent use of global_pointer for riscv

ifneq ($(CHERI),)
WLFLAGS_x += -Wl,-z,norelro,--no-rosegment,-pie,-zrel,-znow,-znotext,--no-dynamic-linker
endif

override WLFLAGS_rv32i += $(WLFLAGS_x)

override CPPFLAGS_rv32imc += $(CPPFLAGS_rv32) \
-march=rv32imc\
-mabi=ilp32\
-mcmodel=medlow

override WLFLAGS_rv32imc += \
-Wl,--no-relax # Prevent use of global_pointer for riscv
override WLFLAGS_rv32imc += $(WLFLAGS_x)

override CPPFLAGS_rv32imac += $(CPPFLAGS_rv32) \
-march=rv32imac\
-mabi=ilp32\
-mcmodel=medlow

override WLFLAGS_rv32imac += \
-Wl,--no-relax # Prevent use of global_pointer for riscv

override WLFLAGS_rv32imac += $(WLFLAGS_x)

override CPPFLAGS_rv32imacxcheri += $(CPPFLAGS_rv32) \
-march=rv32imacxcheri\
-mabi=ilp32\
-mcmodel=medlow

override WLFLAGS_rv32imacxcheri += $(WLFLAGS_x)

override CPPFLAGS_rv64imac += $(CPPFLAGS_rv32) \
--target=riscv64-none-elf\
-march=rv64imac\
-mabi=lp64\
-mcmodel=medany

override WLFLAGS_rv64imac += $(WLFLAGS_x)

override CPPFLAGS_rv64imacxcheri += $(CPPFLAGS_rv32) \
--target=riscv64-none-elf\
-march=rv64imacxcheri\
-mabi=lp64\
-mcmodel=medany

override WLFLAGS_rv64imacxcheri += $(WLFLAGS_x)

override CPPFLAGS_rv64imacxcheripure += $(CPPFLAGS_rv32) \
--target=riscv64-none-elf\
-march=rv64imacxcheri\
-mabi=l64pc128\
-mcmodel=medany

override WLFLAGS_rv64imacxcheripure += $(WLFLAGS_x)

ifneq ($(CHERI),)
# On CHERI, I want to provide my own libc
# By default, we should look within the CHERI_SDK
LIBC_ROOT ?= ${CHERI_SDK}/baremetal

override LINK_LIBS_cheri += -lc -lm -lgcc

override LINK_LIBS_rv32 += $(LINK_LIBS_cheri)

override CPPFLAGS_rv32imac += --sysroot=${LIBC_ROOT}/baremetal-newlib-riscv32/riscv32-unknown-elf

override CPPFLAGS_rv32imacxcheri += --sysroot=${LIBC_ROOT}/baremetal-newlib-riscv32-hybrid/riscv32-unknown-elf

override CPPFLAGS_rv64imac += --sysroot=${LIBC_ROOT}/baremetal-newlib-riscv64/riscv64-unknown-elf

override CPPFLAGS_rv64imacxcheri += --sysroot=${LIBC_ROOT}/baremetal-newlib-riscv64-hybrid/riscv64-unknown-elf

override CPPFLAGS_rv64imacxcheripure += --sysroot=${LIBC_ROOT}/baremetal-newlib-riscv64-purecap/riscv64-unknown-elf

else
# Otherwise use the provided one

override LINK_LIBS_rv32 += \
-lgcc -lstdc++ -lsupc++

override LINK_LIBS_rv32i += $(LINK_LIBS_rv32)
override LINK_LIBS_rv32imc += $(LINK_LIBS_rv32)
override LINK_LIBS_rv32imac += $(LINK_LIBS_rv32)

override LEGACY_LIBS_rv32i += \
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32i/libc.a\
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32i/libm.a
Expand All @@ -267,6 +376,15 @@ override LEGACY_LIBS_rv32imc += $(LEGACY_LIBS_rv32im)
override LEGACY_LIBS_rv32imac += \
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32imac/libc.a\
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32imac/libm.a
endif

override LINK_LIBS_rv32i += $(LINK_LIBS_rv32)
override LINK_LIBS_rv32imc += $(LINK_LIBS_rv32)
override LINK_LIBS_rv32imac += $(LINK_LIBS_rv32)
override LINK_LIBS_rv64imac += $(LINK_LIBS_rv32)
override LINK_LIBS_rv32imacxcheri += $(LINK_LIBS_rv32)
override LINK_LIBS_rv64imacxcheri += $(LINK_LIBS_rv32)
override LINK_LIBS_rv64imacxcheripure += $(LINK_LIBS_rv32)

override CFLAGS_cortex-m += \
$(CFLAGS_toolchain_cortex-m)
Expand Down
13 changes: 13 additions & 0 deletions examples/revoke_test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Makefile for user application

# Specify this directory relative to the current application.
TOCK_USERLAND_BASE_DIR = ../..

# Which files to compile.
C_SRCS := $(wildcard *.c)

STACK_SIZE = 8192

# Include userland makefile. Contains rules and flags for actually
# building the application.
include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk
Loading

0 comments on commit d48c1d6

Please sign in to comment.