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" \) \