Merge changes from topic "cheriot-toolchain"

* changes:
  Add cheriot-baremetal toolchain support
  Add CHERIoT-LLVM toolchain support.
diff --git a/.bazelrc b/.bazelrc
index a4341dc..daac0b0 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -27,6 +27,8 @@
 build:riscv32 --platforms=@crt//platforms/riscv32:opentitan
 build:kelvin --platforms=//platforms/riscv32:kelvin
 build:sparrow --platforms=@matcha//platforms/riscv32:sparrow
+build:cheriot --platforms=@matcha//platforms/cheri/riscv32:cheriot
+build:cheriot-baremetal --platforms=@matcha//platforms/cheri/riscv32:cheriot-baremetal
 
 # Support airgapped build environment
 build:airgapped_env --//rules:build_env='airgapped'
diff --git a/WORKSPACE b/WORKSPACE
index b85e10f..756c1f7 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -38,6 +38,12 @@
     path = "../../out/kelvin/sw/bazel_out",
 )
 
+new_local_repository(
+    name = "cheriot-llvm",
+    build_file = "third_party/cheriot-llvm/BUILD",
+    path = "../../cache/cheriot-tools",
+)
+
 # Used by airgapped environment
 new_local_repository(
     name = "kelvin_core",
@@ -89,6 +95,9 @@
 
 kelvin_register_toolchain()
 
+load("//platforms:registration.bzl", "cheriot_register_toolchain")
+cheriot_register_toolchain()
+
 # Tools for release automation
 load("@lowrisc_opentitan//third_party/github:repos.bzl", "github_tools_repos")
 
diff --git a/constraints/BUILD.bazel b/constraints/BUILD.bazel
new file mode 100644
index 0000000..f29bca3
--- /dev/null
+++ b/constraints/BUILD.bazel
@@ -0,0 +1,5 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+package(default_visibility = ["//visibility:public"])
diff --git a/constraints/extension/BUILD.bazel b/constraints/extension/BUILD.bazel
new file mode 100644
index 0000000..63ba63b
--- /dev/null
+++ b/constraints/extension/BUILD.bazel
@@ -0,0 +1,12 @@
+package(default_visibility = ["//visibility:public"])
+
+constraint_setting(name = "extension")
+
+constraint_value(
+    name = "cheri",
+    constraint_setting = ":extension",
+)
+constraint_value(
+    name = "cheri-baremetal",
+    constraint_setting = ":extension",
+)
diff --git a/platforms/cheri/BUILD.bazel b/platforms/cheri/BUILD.bazel
new file mode 100644
index 0000000..ffd0fb0
--- /dev/null
+++ b/platforms/cheri/BUILD.bazel
@@ -0,0 +1 @@
+package(default_visibility = ["//visibility:public"])
diff --git a/platforms/cheri/riscv32/BUILD.bazel b/platforms/cheri/riscv32/BUILD.bazel
new file mode 100644
index 0000000..14ca641
--- /dev/null
+++ b/platforms/cheri/riscv32/BUILD.bazel
@@ -0,0 +1,16 @@
+package(default_visibility = ["//visibility:public"])
+
+platform(
+    name = "cheriot",
+    constraint_values = [
+        "@platforms//cpu:riscv32",
+        "//constraints/extension:cheri",
+    ],
+)
+platform(
+    name = "cheriot-baremetal",
+    constraint_values = [
+        "@platforms//cpu:riscv32",
+        "//constraints/extension:cheri-baremetal",
+    ],
+)
diff --git a/platforms/cheri/riscv32/devices.bzl b/platforms/cheri/riscv32/devices.bzl
new file mode 100644
index 0000000..31a928f
--- /dev/null
+++ b/platforms/cheri/riscv32/devices.bzl
@@ -0,0 +1,51 @@
+load("@crt//config:device.bzl", "device_config")
+load("@crt//config:compiler.bzl", "listify_flags")
+
+DEVICES = [
+    device_config(
+        name = "cheriot",
+        architecture = "rv32imcxcheri",
+        feature_set = "//platforms/cheri/riscv32/features:rv32imcxcheri",
+        constraints = [
+            "@platforms//cpu:riscv32",
+            "//constraints/extension:cheri",
+        ],
+        substitutions = {
+            "ARCHITECTURE": "rv32imcxcheri",
+            "ABI": "cheriot",
+            "CMODEL": "medany",
+            "ENDIAN": "little",
+            "TARGET": "riscv32-unknown-elf",
+            "[STACK_PROTECTOR]": "",
+            "[SYSTEM_LIBRARY_PATHS]": listify_flags(
+                "-L{}",
+                [
+                    "external/cheriot-llvm/baremetal/baremetal-riscv32-purecap/riscv32-unknown-elf/lib/",
+                ],
+            ),
+        },
+    ),
+    device_config(
+        name = "cheriot-baremetal",
+        architecture = "rv32imcxcheri",
+        feature_set = "//platforms/cheri/riscv32/features:rv32imcxcheri",
+        constraints = [
+            "@platforms//cpu:riscv32",
+            "//constraints/extension:cheri-baremetal",
+        ],
+        substitutions = {
+            "ARCHITECTURE": "rv32imcxcheri",
+            "ABI": "cheriot-baremetal",
+            "CMODEL": "medany",
+            "ENDIAN": "little",
+            "TARGET": "riscv32-unknown-elf",
+            "[STACK_PROTECTOR]": "",
+            "[SYSTEM_LIBRARY_PATHS]": listify_flags(
+                "-L{}",
+                [
+                    "external/cheriot-llvm/baremetal/baremetal-riscv32-purecap/riscv32-unknown-elf/lib/",
+                ],
+            ),
+        },
+    ),
+]
diff --git a/platforms/cheri/riscv32/features/BUILD.bazel b/platforms/cheri/riscv32/features/BUILD.bazel
new file mode 100644
index 0000000..534d35a
--- /dev/null
+++ b/platforms/cheri/riscv32/features/BUILD.bazel
@@ -0,0 +1,88 @@
+load(
+    "@crt//config:features.bzl",
+    "CPP_ALL_COMPILE_ACTIONS",
+    "C_ALL_COMPILE_ACTIONS",
+    "LD_ALL_ACTIONS",
+    "feature",
+    "feature_set",
+    "flag_group",
+    "flag_set",
+)
+
+package(default_visibility = ["//visibility:public"])
+
+feature(
+    name = "architecture",
+    enabled = True,
+    flag_sets = [
+        flag_set(
+            actions = CPP_ALL_COMPILE_ACTIONS + C_ALL_COMPILE_ACTIONS + LD_ALL_ACTIONS,
+            flag_groups = [
+                flag_group(
+                    flags = [
+                        "-march=ARCHITECTURE",
+                        "-mcpu=cheriot",
+                        "-mabi=ABI",
+                        "-mcmodel=CMODEL",
+                        "-mENDIAN-endian",
+                        "--target=TARGET",
+                        "-mxcheri-rvc",
+                        "-mrelax",
+                    ],
+                ),
+            ],
+        ),
+    ],
+)
+
+feature(
+    name = "fastbuild",
+    enabled = False,
+    flag_sets = [
+        flag_set(
+            actions = CPP_ALL_COMPILE_ACTIONS + C_ALL_COMPILE_ACTIONS,
+            flag_groups = [
+                flag_group(
+                    flags = [
+                        "-Os",
+                        "-g",
+                    ],
+                ),
+            ],
+        ),
+    ],
+    provides = ["compilation_mode"],
+)
+
+feature(
+    name = "library_search_directories",
+    enabled = True,
+    flag_sets = [
+        flag_set(
+            actions = LD_ALL_ACTIONS,
+            flag_groups = [
+                flag_group(
+                    flags = ["[SYSTEM_LIBRARY_PATHS]"],
+                ),
+                flag_group(
+                    expand_if_available = "library_search_directories",
+                    flags = ["-L%{library_search_directories}"],
+                    iterate_over = "library_search_directories",
+                ),
+            ],
+        ),
+    ],
+)
+
+feature_set(
+    name = "rv32imcxcheri",
+    base = [
+        "@crt//features/common",
+        "@crt//features/embedded",
+    ],
+    feature = [
+        ":architecture",
+        ":fastbuild",
+        ":library_search_directories",
+    ],
+)
diff --git a/platforms/registration.bzl b/platforms/registration.bzl
index c2d55b4..1d3e878 100644
--- a/platforms/registration.bzl
+++ b/platforms/registration.bzl
@@ -1,3 +1,7 @@
 def kelvin_register_toolchain(name = "kelvin"):
     native.register_execution_platforms("//platforms/riscv32:kelvin")
     native.register_toolchains("//toolchains/kelvin:all")
+
+def cheriot_register_toolchain(name = "cheriot"):
+    native.register_execution_platforms("//platforms/cheri/riscv32:all")
+    native.register_toolchains("//toolchains/cheri_llvm:all")
diff --git a/third_party/cheriot-llvm/BUILD b/third_party/cheriot-llvm/BUILD
new file mode 100755
index 0000000..502216a
--- /dev/null
+++ b/third_party/cheriot-llvm/BUILD
@@ -0,0 +1,8 @@
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+    name = "all",
+    srcs = glob(["**"], exclude=["**/*.html","**/*.pdf"]),
+)
+
+exports_files(["bin/**"])
diff --git a/toolchains/cheri_llvm/BUILD.bazel b/toolchains/cheri_llvm/BUILD.bazel
new file mode 100644
index 0000000..45d5c69
--- /dev/null
+++ b/toolchains/cheri_llvm/BUILD.bazel
@@ -0,0 +1,41 @@
+load("@crt//config:compiler.bzl", "setup")
+load("//platforms/cheri/riscv32:devices.bzl", "DEVICES")
+
+package(default_visibility = ["//visibility:public"])
+
+SYSTEM_INCLUDE_PATHS = [
+    "external/cheriot-llvm/lib/clang/13.0.0/include",
+    "external/cheriot-llvm/riscv32-unknown-elf/include",
+]
+
+filegroup(
+    name = "compiler_components",
+    srcs = [
+        "//toolchains/cheri_llvm/wrappers:all",
+        "@cheriot-llvm//:all",
+    ],
+)
+
+[setup(
+    name = device.name,
+    architecture = device.architecture,
+    artifact_naming = device.artifact_naming,
+    compiler_components = ":compiler_components",
+    constraints = device.constraints,
+    feature_set = device.feature_set,
+    include_directories = SYSTEM_INCLUDE_PATHS,
+    params = {
+        "compiler": "clang",
+    },
+    substitutions = device.substitutions,
+    tools = {
+        "ar":      "wrappers/ar",
+        "cpp":     "wrappers/cpp",
+        "gcc":     "wrappers/clang",
+        "ld":      "wrappers/ld",
+        "nm":      "wrappers/nm",
+        "objcopy": "wrappers/objcopy",
+        "objdump": "wrappers/objdump",
+        "strip":   "wrappers/strip",
+    },
+) for device in DEVICES]
diff --git a/toolchains/cheri_llvm/wrappers/BUILD b/toolchains/cheri_llvm/wrappers/BUILD
new file mode 100644
index 0000000..b44d8ec
--- /dev/null
+++ b/toolchains/cheri_llvm/wrappers/BUILD
@@ -0,0 +1,17 @@
+package(default_visibility = ["//visibility:public"])
+
+exports_files(glob(["*"]))
+
+filegroup(
+    name = "all",
+    srcs = [
+        "ar",
+        "clang",
+        "cpp",
+        "ld",
+        "nm",
+        "objcopy",
+        "objdump",
+        "strip",
+    ],
+)
diff --git a/toolchains/cheri_llvm/wrappers/ar b/toolchains/cheri_llvm/wrappers/ar
new file mode 100755
index 0000000..0bf921d
--- /dev/null
+++ b/toolchains/cheri_llvm/wrappers/ar
@@ -0,0 +1,12 @@
+#!/bin/bash --norc
+
+TOOLCHAIN="cheriot-llvm"
+VERSION="13.0.0"
+
+ARGS=()
+POSTARGS=()
+
+exec "external/${TOOLCHAIN}/bin/llvm-ar" \
+    "${ARGS[@]}" \
+    "$@"\
+    "${POSTARGS[@]}"
diff --git a/toolchains/cheri_llvm/wrappers/clang b/toolchains/cheri_llvm/wrappers/clang
new file mode 120000
index 0000000..da2bdd9
--- /dev/null
+++ b/toolchains/cheri_llvm/wrappers/clang
@@ -0,0 +1 @@
+driver.sh
\ No newline at end of file
diff --git a/toolchains/cheri_llvm/wrappers/cpp b/toolchains/cheri_llvm/wrappers/cpp
new file mode 120000
index 0000000..da2bdd9
--- /dev/null
+++ b/toolchains/cheri_llvm/wrappers/cpp
@@ -0,0 +1 @@
+driver.sh
\ No newline at end of file
diff --git a/toolchains/cheri_llvm/wrappers/driver.sh b/toolchains/cheri_llvm/wrappers/driver.sh
new file mode 100755
index 0000000..077cdff
--- /dev/null
+++ b/toolchains/cheri_llvm/wrappers/driver.sh
@@ -0,0 +1,13 @@
+#!/bin/bash --norc
+
+PROG=${0##*/}
+TOOLCHAIN="cheriot-llvm"
+VERSION="13.0.0"
+
+ARGS=()
+POSTARGS=()
+
+exec "external/${TOOLCHAIN}/bin/${PROG}" \
+    "${ARGS[@]}" \
+    "$@"\
+    "${POSTARGS[@]}"
diff --git a/toolchains/cheri_llvm/wrappers/ld b/toolchains/cheri_llvm/wrappers/ld
new file mode 120000
index 0000000..da2bdd9
--- /dev/null
+++ b/toolchains/cheri_llvm/wrappers/ld
@@ -0,0 +1 @@
+driver.sh
\ No newline at end of file
diff --git a/toolchains/cheri_llvm/wrappers/nm b/toolchains/cheri_llvm/wrappers/nm
new file mode 120000
index 0000000..da2bdd9
--- /dev/null
+++ b/toolchains/cheri_llvm/wrappers/nm
@@ -0,0 +1 @@
+driver.sh
\ No newline at end of file
diff --git a/toolchains/cheri_llvm/wrappers/objcopy b/toolchains/cheri_llvm/wrappers/objcopy
new file mode 120000
index 0000000..da2bdd9
--- /dev/null
+++ b/toolchains/cheri_llvm/wrappers/objcopy
@@ -0,0 +1 @@
+driver.sh
\ No newline at end of file
diff --git a/toolchains/cheri_llvm/wrappers/objdump b/toolchains/cheri_llvm/wrappers/objdump
new file mode 120000
index 0000000..da2bdd9
--- /dev/null
+++ b/toolchains/cheri_llvm/wrappers/objdump
@@ -0,0 +1 @@
+driver.sh
\ No newline at end of file
diff --git a/toolchains/cheri_llvm/wrappers/strip b/toolchains/cheri_llvm/wrappers/strip
new file mode 120000
index 0000000..da2bdd9
--- /dev/null
+++ b/toolchains/cheri_llvm/wrappers/strip
@@ -0,0 +1 @@
+driver.sh
\ No newline at end of file