Initial bancha support. Bancha is derived from sencha by combining the SEC+SMC. The 1st-level bootstrap is a CHERIoT-specific version of the OpenTitan test_rom which requires toolchain suoport for -mabi=cheriot-baremetal. This CL includes revised support for building a toolchain with baremetal support comprised of compiler mods & baremetal-specific include files. The include files are not (yet) part of LLVM so we store them here, NB: this also filters out "cheri"-tagged bazel build targets for matcha_sw_all (which would otherwise fail because they use a cheri toolchain). Change-Id: Id2c20c93c2e37a841a15a3f81f3813d7b2523187
diff --git a/patches/cheriot-llvm/riscv32-unknown-elf/include/README b/patches/cheriot-llvm/riscv32-unknown-elf/include/README new file mode 100644 index 0000000..cde23f7 --- /dev/null +++ b/patches/cheriot-llvm/riscv32-unknown-elf/include/README
@@ -0,0 +1 @@ +These come from cheriot-rtos/sdk/include, possibly with changes.
diff --git a/patches/cheriot-llvm/riscv32-unknown-elf/include/assert.h b/patches/cheriot-llvm/riscv32-unknown-elf/include/assert.h new file mode 100644 index 0000000..39fccbf --- /dev/null +++ b/patches/cheriot-llvm/riscv32-unknown-elf/include/assert.h
@@ -0,0 +1,27 @@ +// Copyright Microsoft and CHERIoT Contributors. +// SPDX-License-Identifier: MIT + +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +#ifdef NDEBUG +# define assert(x) ((void)0) +#else +// XXX extract needed bits from <stdlib.h> +#include <cdefs.h> +static inline void __dead2 panic() +{ + // Invalid instruction is guaranteed to trap. + while (1) + { + __asm volatile("unimp"); + } +} +# define assert(x) ((x) ? (void)0 : panic()) +#endif + +#ifndef static_assert +#define static_assert _Static_assert +#endif + +#endif // _ASSERT_H_
diff --git a/patches/cheriot-llvm/riscv32-unknown-elf/include/cdefs.h b/patches/cheriot-llvm/riscv32-unknown-elf/include/cdefs.h new file mode 100644 index 0000000..1c6eca3 --- /dev/null +++ b/patches/cheriot-llvm/riscv32-unknown-elf/include/cdefs.h
@@ -0,0 +1,110 @@ +// Copyright Microsoft and CHERIoT Contributors. +// SPDX-License-Identifier: MIT + +#ifndef __CDEFS_H__ +#define __CDEFS_H__ + +/* + * Testing against Clang-specific extensions. + */ +#ifndef __has_attribute +# define __has_attribute(x) 0 +#endif +#ifndef __has_extension +# define __has_extension __has_feature +#endif +#ifndef __has_feature +# define __has_feature(x) 0 +#endif +#ifndef __has_include +# define __has_include(x) 0 +#endif +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/// Helper to use C++ in headers only in C++ mode. +#ifdef __cplusplus +# define __if_cxx(x) x +# define __if_c(x) +#else +# define __if_cxx(x) +# define __if_c(x) x +#endif + +/// Allow the C99 spelling of bool in C++ +#ifdef __cplusplus +using _Bool = bool; +#endif + +#if defined(__cplusplus) +# define __BEGIN_DECLS \ + extern "C" \ + { +# define __END_DECLS } +# define __DECL extern "C" +#else +# define __BEGIN_DECLS +# define __END_DECLS +# define __DECL +#endif + +#define __weak_symbol __attribute__((weak)) +#define __dead2 __attribute__((noreturn)) +#define __pure2 __attribute__((const)) +#define __noinline __attribute__((noinline)) +#define __always_inline __attribute__((always_inline)) +#define __unused __attribute__((unused)) +#define __used __attribute__((used)) +#define __packed __attribute__((packed)) +#define __aligned(x) __attribute__((aligned(x))) +#define __section(x) __attribute__((section(x))) +#define __alloc_size(x) __attribute__((alloc_size(x))) +#define __alloc_align(x) __attribute__((alloc_align(x))) +#define __cheri_callback __attribute__((cheri_ccallback)) +#if __has_attribute(cheriot_minimum_stack) +# define __cheriot_minimum_stack(x) __attribute__((cheriot_minimum_stack(x))) +#else +# warning \ + "cheriot_minimum_stack attribute not supported, please update your compiler" +# define __cheriot_minimum_stack(x) +#endif +// When running clang-tidy, we use the same compile flags for everything and so +// will get errors about things being defined in the wrong compartment, so +// define away the compartment name and pretend everything is local for now. +#ifdef CLANG_TIDY +# define __cheri_compartment(x) +#else +# define __cheri_compartment(x) __attribute__((cheri_compartment(x))) +#endif +#define __cheri_libcall __attribute__((cheri_libcall)) + +#define offsetof(a, b) __builtin_offsetof(a, b) + +#define __predict_true(exp) __builtin_expect((exp), 1) +#define __predict_false(exp) __builtin_expect((exp), 0) + +#define __XSTRING(a) __STRING(a) +#define __STRING(a) #a +/// Inner implementation for `__pragma` +#define __pragma_helper(x) _Pragma(#x) +/// Helper that allows pragma strings to be constructed with concatenation +#define __pragma(x) __pragma_helper(x) + +#ifdef __clang__ +/** + * Helper that pushes the diagnostic stack and adds the argument (specified as + * a string, of the form "-W{warning}") to the ignored list. + */ +# define __clang_ignored_warning_push(x) \ + _Pragma("clang diagnostics push") __pragma(clang diagnostic ignored x) +/** + * Undoes the most recent `__clang_ignored_warning_push`. + */ +# define __clang_ignored_warning_pop() _Pragma("clang diagnostics pop") +#else +# define __clang_ignored_warning_push(x) +# define __clang_ignored_warning_pop() +#endif + +#endif // _CDEFS_H_
diff --git a/patches/cheriot-llvm/riscv32-unknown-elf/include/stdarg.h b/patches/cheriot-llvm/riscv32-unknown-elf/include/stdarg.h new file mode 100644 index 0000000..54ff54f --- /dev/null +++ b/patches/cheriot-llvm/riscv32-unknown-elf/include/stdarg.h
@@ -0,0 +1,17 @@ +// Copyright Microsoft and CHERIoT Contributors. +// SPDX-License-Identifier: MIT + +#ifndef __STDARG_H__ +#define __STDARG_H__ + +/* + * Minimalist contents of a traditional stdarg.h required to use printf(). + */ + +typedef __builtin_va_list va_list; +#define va_start(v, l) __builtin_va_start((v), l) +#define va_end __builtin_va_end +#define va_arg __builtin_va_arg +#define va_copy __builtin_va_copy + +#endif /* _STDARG_H_ */
diff --git a/patches/cheriot-llvm/riscv32-unknown-elf/include/stdbool.h b/patches/cheriot-llvm/riscv32-unknown-elf/include/stdbool.h new file mode 100644 index 0000000..c4013ec --- /dev/null +++ b/patches/cheriot-llvm/riscv32-unknown-elf/include/stdbool.h
@@ -0,0 +1,13 @@ +// Copyright Microsoft and CHERIoT Contributors. +// SPDX-License-Identifier: MIT + +#ifndef _STDBOOL_H_ +#define _STDBOOL_H_ + +#ifndef __cplusplus +typedef _Bool bool; +# define true 1 +# define false 0 +#endif // __cplusplus + +#endif // _STDBOOL_H_
diff --git a/patches/cheriot-llvm/riscv32-unknown-elf/include/stddef.h b/patches/cheriot-llvm/riscv32-unknown-elf/include/stddef.h new file mode 100644 index 0000000..8b7cf7c --- /dev/null +++ b/patches/cheriot-llvm/riscv32-unknown-elf/include/stddef.h
@@ -0,0 +1,23 @@ +// Copyright Microsoft and CHERIoT Contributors. +// SPDX-License-Identifier: MIT + +#pragma once + +#ifndef NULL +# ifdef __cplusplus +# define NULL nullptr +# else +# define NULL ((void *)0) +# endif +#endif + +typedef __SIZE_TYPE__ size_t; +typedef signed int ssize_t; +typedef __PTRDIFF_TYPE__ ptrdiff_t; +typedef __UINTPTR_TYPE__ maxalign_t; + +/// CHERI C definition for an address-sized integer +typedef __PTRADDR_TYPE__ ptraddr_t; + +/// Compatibility definition +typedef ptraddr_t vaddr_t;
diff --git a/patches/cheriot-llvm/riscv32-unknown-elf/include/stdint.h b/patches/cheriot-llvm/riscv32-unknown-elf/include/stdint.h new file mode 100644 index 0000000..03c5af0 --- /dev/null +++ b/patches/cheriot-llvm/riscv32-unknown-elf/include/stdint.h
@@ -0,0 +1,77 @@ +// Copyright Microsoft and CHERIoT Contributors. +// SPDX-License-Identifier: MIT + +#pragma once + +#define CHAR_BIT 8 + +#define __constant_integer_suffix_impl(a, b) a##b +#define __constant_integer_suffix(a, b) __constant_integer_suffix_impl(a, b) + +typedef __UINT8_TYPE__ uint8_t; +typedef __UINT_LEAST8_TYPE__ uint_least8_t; +typedef __UINT_FAST8_TYPE__ uint_fast8_t; +#define UINT8_C(x) __constant_integer_suffix(x, __UINT8_C_SUFFIX__) +#define UINT8_MAX __UINT8_MAX__ + +typedef __INT8_TYPE__ int8_t; +typedef __INT_LEAST8_TYPE__ int_least8_t; +typedef __INT_FAST8_TYPE__ int_fast8_t; +#define INT8_C(x) __constant_integer_suffix(x, __INT8_C_SUFFIX__) +#define INT8_MAX __INT8_MAX__ +#define INT8_MIN ((-INT8_C(INT8_MAX)) - 1) + +typedef __UINT16_TYPE__ uint16_t; +typedef __UINT_LEAST16_TYPE__ uint_least16_t; +typedef __UINT_FAST16_TYPE__ uint_fast16_t; +#define UINT16_C(x) __constant_integer_suffix(x, __UINT16_C_SUFFIX__) +#define UINT16_MAX __UINT16_MAX__ + +typedef __INT16_TYPE__ int16_t; +typedef __INT_LEAST16_TYPE__ int_least16_t; +typedef __INT_FAST16_TYPE__ int_fast16_t; +#define INT16_C(x) __constant_integer_suffix(x, __INT16_C_SUFFIX__) +#define INT16_MAX __INT16_MAX__ +#define INT16_MIN ((-INT16_C(INT16_MAX)) - 1) + +typedef __UINT32_TYPE__ uint32_t; +typedef __UINT_LEAST32_TYPE__ uint_least32_t; +typedef __UINT_FAST32_TYPE__ uint_fast32_t; +#define UINT32_C(x) __constant_integer_suffix(x, __UINT32_C_SUFFIX__) +#define UINT32_MAX __UINT32_MAX__ + +typedef __INT32_TYPE__ int32_t; +typedef __INT_LEAST32_TYPE__ int_least32_t; +typedef __INT_FAST32_TYPE__ int_fast32_t; +#define INT32_C(x) __constant_integer_suffix(x, __INT32_C_SUFFIX__) +#define INT32_MAX __INT32_MAX__ +#define INT32_MIN ((-INT32_C(INT32_MAX)) - 1) + +typedef __UINT64_TYPE__ uint64_t; +typedef __UINT_LEAST64_TYPE__ uint_least64_t; +typedef __UINT_FAST64_TYPE__ uint_fast64_t; +#define UINT64_C(x) __constant_integer_suffix(x, __UINT64_C_SUFFIX__) +#define UINT64_MAX __UINT64_MAX__ + +typedef __INT64_TYPE__ int64_t; +typedef __INT_LEAST64_TYPE__ int_least64_t; +typedef __INT_FAST64_TYPE__ int_fast64_t; +#define INT64_C(x) __constant_integer_suffix(x, __INT64_C_SUFFIX__) +#define INT64_MAX __INT64_MAX__ +#define INT64_MIN ((-INT64_C(INT64_MAX)) - 1) + +typedef __UINTMAX_TYPE__ uintmax_t; +#define UINTMAX_C(x) __constant_integer_suffix(x, __UINTMAX_C_SUFFIX__) +#define UINTMAX_MAX __UINTMAX_MAX__ +typedef __INTMAX_TYPE__ intmax_t; +#define INTMAX_C(x) __constant_integer_suffix(x, __INTMAX_C_SUFFIX__) +#define INTMAX_MAX __INTMAX_MAX__ +#define INTMAX_MIN ((-INTMAX_C(INTMAX_MAX)) - 1) + +typedef __UINTPTR_TYPE__ uintptr_t; +#define UINTPTR_MAX __UINTPTR_MAX__ +typedef __INTPTR_TYPE__ intptr_t; +#define INTPTR_MAX __INTPTR_MAX__ +#define INTPTR_MIN ((-INTPTR_C(INTPTR_MAX)) - 1) + +#define SIZE_MAX __SIZE_MAX__
diff --git a/patches/cheriot-llvm/riscv32-unknown-elf/include/string.h b/patches/cheriot-llvm/riscv32-unknown-elf/include/string.h new file mode 100644 index 0000000..75d32d0 --- /dev/null +++ b/patches/cheriot-llvm/riscv32-unknown-elf/include/string.h
@@ -0,0 +1,47 @@ +// Copyright Microsoft and CHERIoT Contributors. +// SPDX-License-Identifier: MIT + +#pragma once +#include <cdefs.h> +#include <stddef.h> +#include <stdint.h> + +#ifdef _CHERIOT_BAREMETAL_ +// --mabi=cheriot-baremetal generates unmangled symbol names for intrinsics +#undef __cheri_libcall +#define __cheri_libcall +#endif + +int __cheri_libcall memcmp(const void *str1, const void *str2, size_t count); +void *__cheri_libcall memcpy(void *dest, const void *src, size_t n); +void *__cheri_libcall memset(void *, int, size_t); +void *__cheri_libcall memmove(void *dest, const void *src, size_t n); +// Should return const void* but must match riscv32 binutils +void *__cheri_libcall memchr(const void *, int, size_t); +size_t __cheri_libcall strlen(const char *str); +int __cheri_libcall strncmp(const char *s1, const char *s2, size_t n); +char *__cheri_libcall strncpy(char *dest, const char *src, size_t n); +int __cheri_libcall strcmp(const char *s1, const char *s2); +char *__cheri_libcall strnstr(const char *haystack, + const char *needle, + size_t haystackLength); +char *__cheri_libcall strchr(const char *s, int c); +size_t __cheri_libcall strlcpy(char *dest, const char *src, size_t n); + +/** + * Explicit bzero is a memset variant that the compiler is not permitted to + * remove. Our implementation simply wraps memset and is safe from removal + * because it is provided by a different shared library. + */ +void __cheri_libcall explicit_bzero(void *s, size_t n); + +__always_inline static inline char *strcpy(char *dst, const char *src) +{ + return dst + strlcpy(dst, src, SIZE_MAX); +} + +__always_inline static inline char *strstr(const char *haystack, + const char *needle) +{ + return strnstr(haystack, needle, SIZE_MAX); +}
diff --git a/platforms/bancha/cantrip_apps.mk b/platforms/bancha/cantrip_apps.mk new file mode 100644 index 0000000..ac655d9 --- /dev/null +++ b/platforms/bancha/cantrip_apps.mk
@@ -0,0 +1 @@ +# CantripOS Test Application configuration
diff --git a/platforms/bancha/cantrip_builtins.mk b/platforms/bancha/cantrip_builtins.mk new file mode 100644 index 0000000..f85e941 --- /dev/null +++ b/platforms/bancha/cantrip_builtins.mk
@@ -0,0 +1,23 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Placeholder until the top-level cantrip_builtins.mk is cleaned up. + +CANTRIP_APPS_RELEASE := +CANTRIP_MODEL_RELEASE := + +CANTRIP_APPS_DEBUG := +CANTRIP_MODEL_DEBUG := + +CANTRIP_SCRIPTS :=
diff --git a/platforms/bancha/platform.mk b/platforms/bancha/platform.mk new file mode 100644 index 0000000..8eac493 --- /dev/null +++ b/platforms/bancha/platform.mk
@@ -0,0 +1,130 @@ +# +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Firmware image to build & load at boot. +ifeq ($(CHERIOT_FIRMWARE),) +$(error "CHERIOT_FIRMWARE not set. Did build/platforms/${PLATFORM}/setup.sh get sourced?") +endif +CHERIOT_FIRMWARE_SRC_DIR := ${ROOTDIR}/hw/matcha/sw/device/cheriot/${CHERIOT_FIRMWARE} + +# Optional xmake config options, typically useful for enabling debugging +# otherwise compiled out. +#CHERIOT_DEBUG_CONFIG_OPTIONS=--debug-scheduler=true --debug-allocator=true +#CHERIOT_RELEASE_CONFIG_OPTIONS=--debug-scheduler=true --debug-allocator=true + +# Platform-specific requirements handled by "m prereqs" +PLATFORM_PYTHON_DEPS=\ + ${ROOTDIR}/hw/opentitan-upstream/python-requirements.txt +PLATFORM_APT_DEPS=\ + ${ROOTDIR}/hw/opentitan-upstream/apt-requirements.txt + +# Put host tool targets first. +include $(ROOTDIR)/build/platforms/nexus/renode.mk +include $(ROOTDIR)/build/platforms/sencha/cheriot.mk +include $(ROOTDIR)/build/platforms/sencha/riscv_toolchain.mk + +include $(ROOTDIR)/build/platforms/nexus/iree.mk +include $(ROOTDIR)/build/platforms/nexus/kelvin.mk +include $(ROOTDIR)/build/platforms/nexus/opentitan_sw.mk +include $(ROOTDIR)/build/platforms/nexus/opentitan_hw.mk +include $(ROOTDIR)/build/platforms/nexus/matcha_hw.mk +include $(ROOTDIR)/build/platforms/nexus/tock.mk + +# Put simulation targets at the end +include $(ROOTDIR)/build/platforms/bancha/sim.mk + +# Driver include files auto-generated from opentitan definitions. + +ifeq ($(OPENTITAN_SOURCE),) +$(error "OPENTITAN_SOURCE not set. Did build/platforms/bancha/setup.sh get sourced?") +endif + +ifeq ($(OPENTITAN_GEN_DIR),) +$(error "OPENTITAN_GEN_DIR not set. Did build/platforms/bancha/setup.sh get sourced?") +endif + +$(OPENTITAN_GEN_DIR): + mkdir -p $(OPENTITAN_GEN_DIR) + +# Matcha hw config #defines generated from RTL + +I2S_HEADER=$(OPENTITAN_GEN_DIR)/i2s_regs.h +ML_TOP_HEADER=$(OPENTITAN_GEN_DIR)/ml_top_regs.h +TLUL_MAILBOX_HEADER=$(OPENTITAN_GEN_DIR)/tlul_mailbox_regs.h +UART_HEADER=$(OPENTITAN_GEN_DIR)/uart_regs.h + +$(I2S_HEADER): $(REGTOOL) $(I2S_HJSON) | $(OPENTITAN_GEN_DIR) + $(REGTOOL) -D -o $@ $(I2S_HJSON) +$(ML_TOP_HEADER): $(REGTOOL) $(ML_TOP_HJSON) | $(OPENTITAN_GEN_DIR) + $(REGTOOL) -D -o $@ $(ML_TOP_HJSON) +$(TLUL_MAILBOX_HEADER): $(REGTOOL) $(MBOX_HJSON) | $(OPENTITAN_GEN_DIR) + $(REGTOOL) -D -o $@ $(MBOX_HJSON) +$(UART_HEADER): $(REGTOOL) $(UART_HJSON) | $(OPENTITAN_GEN_DIR) + $(REGTOOL) -D -o $@ $(UART_HJSON) + +TOP_MATCHA_DIR=${CHERIOT_OUT_DIR}/top_matcha +TOP_MATCHA_MEMORY_HEADER=$(TOP_MATCHA_DIR)/sw/autogen/top_matcha_memory.h +TOP_MATCHA_IRQ_HEADER=$(TOP_MATCHA_DIR)/sw/autogen/top_matcha_smc_irq.h +# NB: could depend on the templates instead +TOPGEN_MATCHA=${ROOTDIR}/hw/matcha/util/topgen_matcha.py + +${TOP_MATCHA_DIR}: + mkdir -p $(TOP_MATCHA_DIR) + +# NB: no way to generate just the files we need +$(TOP_MATCHA_IRQ_HEADER): $(TOPGEN_MATCHA) ${TOP_MATCHA_DIR} $(TOP_MATCHA_HJSON) + PYTHONPATH=${OPENTITAN_SOURCE}/util/ ${TOPGEN_MATCHA} -t ${TOP_MATCHA_HJSON} -o ${TOP_MATCHA_DIR}/ --top-only +$(TOP_MATCHA_MEMORY_HEADER): $(TOPGEN_MATCHA) ${TOP_MATCHA_DIR} $(TOP_MATCHA_HJSON) + PYTHONPATH=${OPENTITAN_SOURCE}/util/ ${TOPGEN_MATCHA} -t ${TOP_MATCHA_HJSON} -o ${TOP_MATCHA_DIR}/ --top-only + +# Targets to install the symlink to opentitan headers for each build + +cheriot-build-debug-prepare:: | $(CHERIOT_OUT_DEBUG) + ln -sf $(CHERIOT_OUT_DIR)/opentitan-gen $(CHERIOT_OUT_DEBUG)/ + +cheriot-build-release-prepare:: | $(CHERIOT_OUT_RELEASE) + ln -sf $(CHERIOT_OUT_DIR)/opentitan-gen $(CHERIOT_OUT_RELEASE)/ + +CHERIOT_GEN_HEADERS=\ + $(I2S_HEADER) \ + $(ML_TOP_HEADER) \ + $(TLUL_MAILBOX_HEADER) \ + $(UART_HEADER) \ + $(TOP_MATCHA_IRQ_HEADER) \ + $(TOP_MATCHA_MEMORY_HEADER) + +cheriot-gen-headers:: $(CHERIOT_GEN_HEADERS) + +cheriot-clean-headers:: + rm -f $(CHERIOT_GEN_HEADERS) + +# Point to the clang++ target to make sure the binary is installed. +$(CACHE)/cheriot-tools/bin/clang++: | $(CACHE) + ./scripts/install-toolchain.sh cheriot + +## Installs the LLVM compiler for CHERIoT +# +# Requires network access. This fetches the toolchain from the GCP archive and +# extracts it locally to the cache/. +install_cheriot: $(CACHE)/cheriot-tools/bin/clang++ + +# NB: install the prebuilt CHERIoT toolchain. Note this means it +# is necessary to do something like: +# $ set-platform bancha +# $ m tools +# to get a working build environment. +tools:: install_cheriot + +.PHONY:: install_cheriot
diff --git a/platforms/bancha/setup.sh b/platforms/bancha/setup.sh new file mode 100644 index 0000000..7845a2a --- /dev/null +++ b/platforms/bancha/setup.sh
@@ -0,0 +1,21 @@ +#!/bin/bash +# +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +source "${ROOTDIR}/build/platforms/sencha/setup.sh" + +# Firmware image to build & load at boot. +# NB: the pathname to the source directory is formulated in platform.mk +export CHERIOT_FIRMWARE="soundstream"
diff --git a/platforms/bancha/sim.mk b/platforms/bancha/sim.mk new file mode 100644 index 0000000..5da3432 --- /dev/null +++ b/platforms/bancha/sim.mk
@@ -0,0 +1,170 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +EXT_FLASH_DEBUG=$(CHERIOT_OUT_DEBUG)/ext_flash.tar +EXT_FLASH_RELEASE=$(CHERIOT_OUT_RELEASE)/ext_flash.tar + +CHERIOT_SIM_SRC_DIR := $(ROOTDIR)/sim/mpact-cheriot +CHERIOT_SIM_OUT_DIR := $(OUT)/cheriot/sim + +CHERIOT_BOOT_SRC_DIR := $(MATCHA_SRC_DIR)/sw/device/cheriot/boot + +TMP_DEBUG=$(CHERIOT_OUT_DEBUG)/tmp +TMP_RELEASE=$(CHERIOT_OUT_RELEASE)/tmp + +sim_configs: + $(RENODE_SIM_GENERATOR_SCRIPT) + +clean_sim_configs: + @rm -rf $(OUT)/renode_configs + +$(TMP_DEBUG): + mkdir $(TMP_DEBUG) +$(TMP_RELEASE): + mkdir $(TMP_RELEASE) + +## Build the CHERIoT boot ROM image +# +# This builds the HW boot rom executable for simulation. +# Source is in hw/matcha, while output is placed in +# out/cheriot/hw/ +cheriot_boot_rom: cheriot_boot_rom_otp +cheriot_boot_rom_clean: cheriot_boot_rom_otp_clean + +cheriot_boot_rom_otp: | $(CHERIOT_OUT_DIR) + cd $(MATCHA_SRC_DIR) && \ + bazel build --config=cheriot-baremetal --copt=-D_CHERIOT_BAREMETAL_ \ + //sw/device/lib/testing/test_rom:test_rom_no_otp_cheri_fpga_nexus.elf + cd $(MATCHA_SRC_DIR) && \ + find "bazel-out/" -wholename "*test_rom/test_rom_no_otp_cheri_fpga_nexus.elf" \ + -exec cp -f '{}' "$(CHERIOT_OUT_DIR)/$(BOOT_ROM_ELF)" \; + cd ${MATCHA_SRC_DIR}/bazel-matcha && \ + $(CACHE)/cheriot-tools/bin/llvm-objdump -glxsdrS --demangle \ + $(CHERIOT_OUT_DIR)/$(BOOT_ROM_ELF) > $(CHERIOT_OUT_DIR)/$(BOOT_ROM_ELF).dump + +cheriot_boot_rom_otp_clean: + cd $(MATCHA_SRC_DIR) && bazel clean --expunge + +# XXX symlink cheriot fw to "kernel" to satisfy elfloader +$(EXT_FLASH_DEBUG): $(MATCHA_BUNDLE_DEBUG) $(CHERIOT_FIRMWARE_DEBUG) | $(TMP_DEBUG) + cp -f $(MATCHA_BUNDLE_DEBUG) $(TMP_DEBUG)/matcha-tock-bundle + ${C_PREFIX}strip $(TMP_DEBUG)/matcha-tock-bundle + ${C_PREFIX}objcopy -O binary -g $(TMP_DEBUG)/matcha-tock-bundle $(TMP_DEBUG)/matcha-tock-bundle.bin + ln -sf $(CHERIOT_FIRMWARE_DEBUG) $(TMP_DEBUG)/kernel + tar -C $(TMP_DEBUG) -cvhf $@ matcha-tock-bundle.bin kernel +ext_flash_debug: $(EXT_FLASH_DEBUG) + +$(EXT_FLASH_RELEASE): $(CHERIOT_FIRMWARE_RELEASE) | $(TMP_RELEASE) + cp -f $(CHERIOT_FIRMWARE_RELEASE) $(TMP_RELEASE)/cheriot-firmware + ${C_PREFIX}strip $(TMP_RELEASE)/cheriot-firmware + ${C_PREFIX}objcopy -O binary -g $(TMP_RELEASE)/cheriot-firmware $(TMP_RELEASE)/cheriot-firmware.bin + tar -C $(TMP_RELEASE) -cvhf $@ cheriot-firmware.bin +ext_flash_release: $(EXT_FLASH_RELEASE) + +# Renode commands to issue before the initial start of a simulation. +# This pauses all cores and then sets cpu0 (SC). +RENODE_PRESTART_CMDS=pause; cpu0 IsHalted false; +PORT_PRESTART_CMDS:=$(shell $(ROOTDIR)/scripts/generate-renode-port-cmd.sh $(RENODE_PORT)) + +# XXX the same for now +BANCHA_RESC_DEBUG=sim/config/bancha.resc +BANCHA_RESC_RELEASE=sim/config/bancha.resc +CHERIOT_RESC_RELEASE=sim/config/cheriot.resc + +BANCHA_REPL=sim/config/platforms/bancha.repl + +## Launches an end-to-end build of the system and starts Renode +# +# This top-level target triggers the `cheriot_sim`, `kelvin_sim', `renode`, +# `cheriot_boot_rom`, and `ext_flash_release' targets to build the entire +# system and then finally starts the Renode simulator. +# +# This is the default target for the build system, and is generally what you +# need for day-to-day work on the software side of Shodan. +simulate: renode cheriot_sim kelvin_sim cheriot_boot_rom ext_flash_release + $(RENODE_CMD) -e "\ + \$$repl_file = @${BANCHA_REPL}; \ + \$$sc_bin =@$(TMP_RELEASE)/cheriot-firmware.bin; \ + \$$cheriot_elf = @$(TMP_RELEASE)/cheriot-firmware; \ + $(PORT_PRESTART_CMDS) i @${BANCHA_RESC_RELEASE}; \ + $(RENODE_PRESTART_CMDS) start" + +## Version of the `simulate` target that also enables the simulator command +## line interface on port 4567. To access the simulator use something like +## telnet localhost 4567. Note renode will block until the cli is connected. +simulate+cli: renode cheriot_sim kelvin_sim cheriot_boot_rom ext_flash_release + $(RENODE_CMD) -e "\ + \$$repl_file = @${BANCHA_REPL}; \ + \$$sc_bin =@$(TMP_RELEASE)/cheriot-firmware.bin; \ + \$$cheriot_elf = @$(TMP_RELEASE)/cheriot-firmware; \ + \$$cli_port = 4567; \ + \$$wait_for_cli = true; \ + $(PORT_PRESTART_CMDS) i @${BANCHA_RESC_RELEASE}; \ + $(RENODE_PRESTART_CMDS) start" + +## Debug version of the `simulate` target +# +# This top-level target does the same job as `simulate`, but instead of +# unhalting the CPUs and starting the system, this alternate target only unhalts +# cpu0, and uses the debug build of TockOS from the `matcha_tock_debug` target. +simulate-debug: renode cheriot_sim kelvin_sim cheriot_boot_rom ext_flash_debug + $(RENODE_CMD) -e "\ + \$$repl_file = @${BANCHA_REPL}; \ + \$$tar = @$(EXT_FLASH_DEBUG); \ + \$$sc_bin =@$(TMP_RELEASE)/cheriot-firmware.bin; \ + \$$cheriot_elf = @$(TMP_RELEASE)/cheriot-firmware; \ + $(PORT_PRESTART_CMDS) i @${BANCHA_RESC_DEBUG}; \ + $(RENODE_PRESTART_CMDS); start" + +## Debug version of the `simulate` target +# +# This top-level target does the same job as `simulate-debug`, but instead of +# unhalting the CPUs and starting the system, this alternate target starts +# renode with no CPUs unhalted, allowing for GDB to be used for early system +# start. +debug-simulation: renode cheriot_sim kelvin_sim cheriot_boot_rom ext_flash_debug + $(RENODE_CMD) -e "\ + \$$repl_file = @${BANCHA_REPL}; \ + \$$tar = @$(EXT_FLASH_DEBUG); \ + \$$sc_bin =@$(TMP_RELEASE)/cheriot-firmware.bin; \ + \$$cheriot_elf = @$(TMP_RELEASE)/cheriot-firmware; \ + $(PORT_PRESTART_CMDS) i @${BANCHA_RESC_DEBUG}; start" + +$(CHERIOT_SIM_OUT_DIR): + mkdir -p "$(CHERIOT_SIM_OUT_DIR)" + +## Build CHERIoT ISS +# +# Build mpact-sim-based CHERIoT ISS with bazel, and copy it to out/ +# Use /tmp as the bazel tmpfs to unblock CI +cheriot_sim: | $(CHERIOT_SIM_OUT_DIR) + cd "$(CHERIOT_SIM_SRC_DIR)" && \ + bazel build --sandbox_tmpfs_path=/tmp \ + //cheriot:mpact_cheriot \ + //cheriot:renode_mpact_cheriot + cd "$(CHERIOT_SIM_SRC_DIR)/bazel-bin" && \ + cp -f cheriot/mpact_cheriot "$(CHERIOT_SIM_OUT_DIR)" && \ + cp -f cheriot/librenode_mpact_cheriot.so "$(CHERIOT_SIM_OUT_DIR)" + +## Clean CHERIoT ISS +# +# Clean the CHERIoT ISS +cheriot_sim_clean: + cd "$(CHERIOT_SIM_SRC_DIR)" && \ + bazel clean --expunge + rm -rf $(CHERIOT_SIM_OUT_DIR) + +.PHONY:: sim_configs clean_sim_configs simulate simulate-debug debug-simulation +.PHONY:: cheriot_sim cheriot_sim_clean +.PHONY:: cheriot_boot_rom cheriot_boot_rom_clean
diff --git a/platforms/nexus/matcha_hw.mk b/platforms/nexus/matcha_hw.mk index c6d9a58..53ee435 100644 --- a/platforms/nexus/matcha_hw.mk +++ b/platforms/nexus/matcha_hw.mk
@@ -75,7 +75,7 @@ # matcha_sw_all: | $(MATCHA_OUT_DIR) cd $(MATCHA_SRC_DIR) && \ - bazel build --define DISABLE_VERILATOR_BUILD=true --build_tag_filters="-kelvin_fpga" \ + bazel build --define DISABLE_VERILATOR_BUILD=true --build_tag_filters="-kelvin_fpga,-cheri" \ //sw/device/... cd $(MATCHA_SRC_DIR) && \ find "bazel-out/" \( -type f -name "*.elf" -o -name "*.bin" -o -name "*.vmem" \) \
diff --git a/platforms/sencha/cheriot.mk b/platforms/sencha/cheriot.mk index 790f01a..369473a 100644 --- a/platforms/sencha/cheriot.mk +++ b/platforms/sencha/cheriot.mk
@@ -92,6 +92,9 @@ cheriot-clean: cheriot-tests-clean cheriot-examples-clean rm -rf $(CHERIOT_OUT_DIR) +$(CHERIOT_OUT_DIR): + mkdir -p $(CHERIOT_OUT_DIR) + $(CHERIOT_OUT_DEBUG): mkdir -p $(CHERIOT_OUT_DEBUG)
diff --git a/platforms/sencha/riscv_toolchain.mk b/platforms/sencha/riscv_toolchain.mk index 0df299a..52817d0 100644 --- a/platforms/sencha/riscv_toolchain.mk +++ b/platforms/sencha/riscv_toolchain.mk
@@ -21,7 +21,6 @@ TOOLCHAIN_BUILD_DATE := $(shell date +%Y-%m-%d) - toolchain_cheriot_src: if [[ -f "${TOOLCHAIN_CHERIOT_BIN}" ]]; then \ echo "Toolchain exists, run 'm toolchain_cheriot_clean' if you really want to rebuild"; \ @@ -39,13 +38,20 @@ -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld" \ -DLLVM_ENABLE_UNWIND_TABLES=NO \ -DLLVM_TARGETS_TO_BUILD=RISCV \ - -DLLVM_DISTRIBUTION_COMPONENTS="clang;clangd;lld;llvm-objdump" \ + -DLLVM_DISTRIBUTION_COMPONENTS="clang;clangd;lld;llvm-ar;llvm-objdump;llvm-objcopy" \ -G Ninja \ $(TOOLCHAIN_CHERIOT_SRC_DIR)/llvm cmake --build $(TOOLCHAIN_CHERIOT_BUILD_DIR) --target install-distribution + cmake --build $(TOOLCHAIN_CHERIOT_BUILD_DIR) --target install-clang-resource-headers cmake --build $(TOOLCHAIN_CHERIOT_BUILD_DIR) --target clean -$(OUT)/toolchain_cheriot_$(TOOLCHAIN_BUILD_DATE).tar.gz: $(TOOLCHAIN_CHERIOT_BIN) +# Copies our baremetal include files into the toolchain. These should be +# generated from / by llvm but for now we have hand-crafted files sufficient +# to build all the OpenTitan artifacts we need. +toolchain_cheriot_includes: + cp -p -r ${ROOTDIR}/build/patches/cheriot-llvm/riscv32-unknown-elf ${TOOLCHAIN_CHERIOT_OUT_DIR} + +$(OUT)/toolchain_cheriot_$(TOOLCHAIN_BUILD_DATE).tar.gz: $(TOOLCHAIN_CHERIOT_BIN) toolchain_cheriot_includes tar -C $(CACHE) -czf \ "$(OUT)/toolchain_cheriot_$(TOOLCHAIN_BUILD_DATE).tar.gz" cheriot-tools cd $(OUT) && sha256sum "toolchain_cheriot_$(TOOLCHAIN_BUILD_DATE).tar.gz" > \ @@ -71,4 +77,7 @@ toolchain_cheriot_clean: rm -rf "$(TOOLCHAIN_CHERIOT_OUT_DIR)" "$(TOOLCHAIN_CHERIOT_SRC_DIR)" "$(TOOLCHAIN_CHERIOT_BUILD_DIR)" -.PHONY:: toolchain_cheriot toolchain_cheriot_src toolchain_cheriot_clean +.PHONY:: toolchain_cheriot +.PHONY:: toolchain_cheriot_src +.PHONY:: toolchain_cheriot_includes +.PHONY:: toolchain_cheriot_clean
diff --git a/platforms/shodan/matcha_hw.mk b/platforms/shodan/matcha_hw.mk index ce3ec35..3568c4a 100644 --- a/platforms/shodan/matcha_hw.mk +++ b/platforms/shodan/matcha_hw.mk
@@ -74,7 +74,7 @@ # matcha_sw_all: | $(MATCHA_OUT_DIR) cd $(MATCHA_SRC_DIR) && \ - bazel build --define DISABLE_VERILATOR_BUILD=true --build_tag_filters="-kelvin_fpga" \ + bazel build --define DISABLE_VERILATOR_BUILD=true --build_tag_filters="-kelvin_fpga,-cheri" \ //sw/device/... cd $(MATCHA_SRC_DIR) && \ find "bazel-out/" \( -type f -name "*.elf" -o -name "*.bin" -o -name "*.vmem" \) \
diff --git a/platforms/sparrow/matcha_hw.mk b/platforms/sparrow/matcha_hw.mk index 976f75f..6dc6f91 100644 --- a/platforms/sparrow/matcha_hw.mk +++ b/platforms/sparrow/matcha_hw.mk
@@ -62,7 +62,7 @@ # matcha_sw_all: | $(MATCHA_OUT_DIR) cd $(MATCHA_SRC_DIR) && \ - bazel build --define DISABLE_VERILATOR_BUILD=true --build_tag_filters="-kelvin_asic" \ + bazel build --define DISABLE_VERILATOR_BUILD=true --build_tag_filters="-kelvin_asic,-cheri" \ //sw/device/... cd $(MATCHA_SRC_DIR) && \ find "bazel-out/" \( -type f -name "*.elf" -o -name "*.bin" -o -name "*.vmem" \) \