TFMicro integration into KelvinV2 ecosystem.

Successful integration necessitated modifications across the repository.

Revisions to the build system encompass:
 * Workspace has been reconfigured to facilitate the download of the tflite_micro repository and its associated dependencies.
 * rules/repos.bzl file now incorporates new repositories for download.
 * rules/utils.bzl file has been updated to include the generate_cc_arrays tool.

The tflite_micro patch incorporates:
 * Patches designed to disable -pthreads within ruy and gemmlowp.
 * Adjustments to the visibility of the generate_cc_array and hello_world models.

Regarding the toolchain, the following changes have been implemented:
* Removal of freestanding attributes.
* Addition of no-exceptions and no-rtti flags.
* Introduction of a new tcm.ld file to facilitate high-memory kelvin_binaries.

Validation was conducted using tests/cocotb/tutorial/tflite_micro_test.cc.
Toolchain Validation bazel test tests/cocotb/...

Change-Id: I3cc05b9ad6a23d4c20c1b9c074b1b8a6b18dae5d
diff --git a/.bazelrc b/.bazelrc
index a78752b..2f0134a 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -59,6 +59,14 @@
 run:synthesis --build_tag_filters="synthesis"
 run:synthesis --test_tag_filters="synthesis"
 
+# Set preprocessor defines for tflite-micro.
+build --copt=-DTF_LITE_USE_GLOBAL_CMATH_FUNCTIONS
+build --copt=-DTF_LITE_USE_GLOBAL_MIN
+build --copt=-DTF_LITE_USE_GLOBAL_MAX
+build --copt=-DTF_LITE_MCU_DEBUG_LOG
+build:opt --copt=-DTF_LITE_STRIP_ERROR_STRINGS
+
+
 # Selecting kelvin platform with custom toolchain.
 build:kelvin_v2 --platforms=//platforms:kelvin_v2
 
diff --git a/WORKSPACE b/WORKSPACE
index eb26098..8ff5140 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -14,7 +14,15 @@
 
 workspace(name = "kelvin_hw")
 
-load("//rules:repos.bzl", "kelvin_repos", "renode_repos", "cvfpu_repos", "rvvi_repos", "fpga_repos")
+load(
+    "//rules:repos.bzl",
+    "cvfpu_repos",
+    "fpga_repos",
+    "kelvin_repos",
+    "renode_repos",
+    "rvvi_repos",
+    "tflite_repos",
+)
 
 kelvin_repos()
 
@@ -95,26 +103,21 @@
 nonhermetic_repo(name = "nonhermetic")
 
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-
 load("@rules_python//python:pip.bzl", "pip_parse")
 
 pip_parse(
-   name = "ot_python_deps",
-   requirements_lock = "@lowrisc_opentitan_gh//:python-requirements.txt",
-   python_interpreter_target = "@python39_x86_64-unknown-linux-gnu//:python",
+    name = "ot_python_deps",
+    python_interpreter_target = "@python39_x86_64-unknown-linux-gnu//:python",
+    requirements_lock = "@lowrisc_opentitan_gh//:python-requirements.txt",
 )
 
 load("//third_party/python:requirements.bzl", "install_deps")
+
 install_deps()
 
 # OpenTitan's requirements need this, but for some reason do not provide it.
 http_archive(
     name = "ot_python_deps_importlib_metadata",
-    urls = [
-        "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl",
-    ],
-    sha256 = "e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd",
-    type = "zip",
     build_file_content = """
 package(default_visibility = ["//visibility:public"])
 py_library(
@@ -125,9 +128,15 @@
     tags = ["pypi_name=importlib_metadata","pypi_version=8.7.0"],
 )
 """,
+    sha256 = "e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd",
+    type = "zip",
+    urls = [
+        "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl",
+    ],
 )
 
 load("@ot_python_deps//:requirements.bzl", ot_install_deps = "install_deps")
+
 ot_install_deps()
 
 http_archive(
@@ -142,13 +151,29 @@
 )
 """,
     sha256 = "c9c85f8361e9d02d64474c51e3b3730ba09807cf4610d6d002c49a270458b49c",
+    strip_prefix = "toolchain_kelvin_v2",
     urls = [
         "https://storage.googleapis.com/shodan-public-artifacts/toolchain_kelvin_tar_files/toolchain_kelvin_v2-2025-09-11.tar.gz",
     ],
-    strip_prefix = "toolchain_kelvin_v2",
 )
 
 register_toolchains(
     "//toolchain:cc_kelvin_v2_toolchain",
     "//toolchain:cc_kelvin_v2_semihosting_toolchain",
 )
+
+tflite_repos()
+
+load("@tflite_micro//tensorflow:workspace.bzl", tf_micro_workspace = "workspace")
+
+tf_micro_workspace()
+
+pip_parse(
+    name = "tflm_pip_deps",
+    python_interpreter_target = "@python39_x86_64-unknown-linux-gnu//:python",
+    requirements_lock = "@tflite_micro//third_party:python_requirements.txt",
+)
+
+load("@tflm_pip_deps//:requirements.bzl", "install_deps")
+
+install_deps()
diff --git a/rules/kelvin_v2.bzl b/rules/kelvin_v2.bzl
index 22423da..a8dd49d 100644
--- a/rules/kelvin_v2.bzl
+++ b/rules/kelvin_v2.bzl
@@ -256,4 +256,4 @@
         srcs = [name],
         output_group = "bin_file",
         tags = tags,
-    )
\ No newline at end of file
+    )
diff --git a/rules/repos.bzl b/rules/repos.bzl
index 803b891..ef28c55 100644
--- a/rules/repos.bzl
+++ b/rules/repos.bzl
@@ -17,6 +17,7 @@
 
 load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
 
 def kelvin_repos():
     http_archive(
@@ -190,3 +191,39 @@
         ],
         patch_args = ["-p1"],
     )
+
+def tflite_repos():
+    http_archive(
+        name = "tflite_micro",
+        url = "https://github.com/tensorflow/tflite-micro/archive/b75c6ff4e2270047f2b48fa01f833c8101c31f43.zip",
+        sha256 = "ac3e675b71c55529a32d19a8cf0912413c1d1b9a551512e2665883a1666fb0ba",
+        strip_prefix = "tflite-micro-b75c6ff4e2270047f2b48fa01f833c8101c31f43",
+        patches = [
+            "@kelvin_hw//third_party/tflite-micro:Tflite-Micro-Kelvin-integration.patch",
+            "@kelvin_hw//third_party/tflite-micro:0001-Remove-xtensa-and-hifi-kernels.patch",
+        ],
+        patch_args = ["-p1"],
+    )
+
+    http_archive(
+        name = "hedron_compile_commands",
+        sha256 = "bacabfe758676fdc19e4bea7c4a3ac99c7e7378d259a9f1054d341c6a6b44ff6",
+        strip_prefix = "bazel-compile-commands-extractor-1266d6a25314d165ca78d0061d3399e909b7920e",
+        url = "https://github.com/hedronvision/bazel-compile-commands-extractor/archive/1266d6a25314d165ca78d0061d3399e909b7920e.tar.gz",
+    )
+
+    maybe(
+        http_archive,
+        name = "rules_python",
+        sha256 = "9d04041ac92a0985e344235f5d946f71ac543f1b1565f2cdbc9a2aaee8adf55b",
+        strip_prefix = "rules_python-0.26.0",
+        url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.26.0.tar.gz",
+    )
+
+    maybe(
+        http_archive,
+        name = "pybind11_bazel",
+        strip_prefix = "pybind11_bazel-faf56fb3df11287f26dbc66fdedf60a2fc2c6631",
+        urls = ["https://github.com/pybind/pybind11_bazel/archive/faf56fb3df11287f26dbc66fdedf60a2fc2c6631.zip"],
+        sha256 = "a185aa68c93b9f62c80fcb3aadc3c83c763854750dc3f38be1dadcb7be223837",
+    )
diff --git a/rules/utils.bzl b/rules/utils.bzl
index be8ec88..9a13b86 100644
--- a/rules/utils.bzl
+++ b/rules/utils.bzl
@@ -13,39 +13,39 @@
 # limitations under the License.
 
 def template_rule(rule, name_map, **kwargs):
-  """ Macro for creating multiple instances of a rule template.
+    """ Macro for creating multiple instances of a rule template.
 
-      Usage:
-        template_rule(
-            example_rule,
-            {
-                "foo": {
-                    "varying_param1": 42,
-                    "varying_param2": [ "//some/source:file" ],
-                },
-                "bar": {
-                    "varying_param1": 9001,
-                    "varying_param2": [ "//different/source:file" ],
-                },
-            },
-            common_param1: "same_for_both_rules"
-            common_param2: [ "//also:same", "//for/both:rules" ]
+        Usage:
+          template_rule(
+              example_rule,
+              {
+                  "foo": {
+                      "varying_param1": 42,
+                      "varying_param2": [ "//some/source:file" ],
+                  },
+                  "bar": {
+                      "varying_param1": 9001,
+                      "varying_param2": [ "//different/source:file" ],
+                  },
+              },
+              common_param1: "same_for_both_rules"
+              common_param2: [ "//also:same", "//for/both:rules" ]
+          )
+
+        Args:
+          rule: The base rule for the template
+          name_map: A map of rule name -> (map of parameter name -> argument)
+          **kwargs: Arguments that remain the same for each instance of the rule.
+    """
+    for rule_name, argmap in name_map.items():
+        rule_kwargs = argmap
+        for k, v in kwargs.items():
+            rule_kwargs.update([(k, v)])
+        rule(
+            name = rule_name,
+            **rule_kwargs
         )
 
-      Args:
-        rule: The base rule for the template
-        name_map: A map of rule name -> (map of parameter name -> argument)
-        **kwargs: Arguments that remain the same for each instance of the rule.
-  """
-  for rule_name, argmap in name_map.items():
-    rule_kwargs = argmap
-    for k, v in kwargs.items():
-      rule_kwargs.update([(k, v)])
-    rule(
-        name = rule_name,
-        **rule_kwargs
-    )
-
 def cc_embed_data(
         name,
         srcs,
@@ -75,3 +75,20 @@
         testonly = testonly,
         **kwargs
     )
+
+# From @tflite_micro//tensorflow/lite/micro/build_def.bzl, and paths.
+# Modified to point to the external repo as visibility of the package is restricted
+# TODO upstream changes to tflite-micro to fix this.
+def generate_cc_arrays(name, src, out, tags = []):
+    native.genrule(
+        name = name,
+        srcs = [
+            src,
+        ],
+        outs = [
+            out,
+        ],
+        tags = tags,
+        cmd = "$(location @tflite_micro//tensorflow/lite/micro/tools:generate_cc_arrays) $@ $<",
+        tools = ["@tflite_micro//tensorflow/lite/micro/tools:generate_cc_arrays"],
+    )
diff --git a/tests/cocotb/tutorial/BUILD b/tests/cocotb/tutorial/BUILD
index ed9660d..7e79acf 100644
--- a/tests/cocotb/tutorial/BUILD
+++ b/tests/cocotb/tutorial/BUILD
@@ -14,6 +14,7 @@
 
 load("//rules:coco_tb.bzl", "cocotb_test_suite")
 load("//rules:kelvin_v2.bzl", "kelvin_v2_binary")
+load("//rules:utils.bzl", "generate_cc_arrays")
 load(
     "//tests/cocotb:build_defs.bzl",
     "VCS_BUILD_ARGS",
@@ -52,12 +53,12 @@
         ],
         "data": glob(["**/*.elf"]),
     },
+    vcs_build_args = VCS_BUILD_ARGS,
     vcs_data = glob(["**/*.elf"]) + [
         "//tests/cocotb:coverage_exclude.cfg",
     ],
-    vcs_build_args = VCS_BUILD_ARGS,
-    vcs_test_args = VCS_TEST_ARGS,
     vcs_defines = VCS_DEFINES,
+    vcs_test_args = VCS_TEST_ARGS,
     vcs_verilog_sources = ["//hdl/chisel/src/kelvin:core_mini_axi_cc_library_verilog"],
     verilator_model = "//tests/cocotb:core_mini_axi_model",
 )
@@ -81,13 +82,13 @@
         ],
         "data": ["//examples:kelvin_v2_hello_world_add_floats.elf"],
     },
+    vcs_build_args = VCS_BUILD_ARGS,
     vcs_data = [
         "//examples:kelvin_v2_hello_world_add_floats.elf",
         "//tests/cocotb:coverage_exclude.cfg",
     ],
-    vcs_build_args = VCS_BUILD_ARGS,
-    vcs_test_args = VCS_TEST_ARGS,
     vcs_defines = VCS_DEFINES,
+    vcs_test_args = VCS_TEST_ARGS,
     vcs_verilog_sources = ["//hdl/chisel/src/kelvin:core_mini_axi_cc_library_verilog"],
     verilator_model = "//tests/cocotb:core_mini_axi_model",
 )
@@ -96,3 +97,32 @@
     name = "kelvin_v2_program",
     srcs = ["program.cc"],
 )
+
+kelvin_v2_binary(
+    name = "tflite_micro_test",
+    srcs = [
+        "hello_world_tflite_cc",
+        "tflite_micro_test.cc",
+    ],
+    hdrs = ["hello_world_tflite.h"],
+    linker_script = "@kelvin_hw//toolchain:kelvin_tcm_highmem.ld",
+    deps = [
+        "@tflite_micro//tensorflow/lite/micro:micro_framework",
+        "@tflite_micro//tensorflow/lite/micro:micro_log",
+        "@tflite_micro//tensorflow/lite/micro:micro_profiler",
+        "@tflite_micro//tensorflow/lite/micro:op_resolvers",
+        "@tflite_micro//tensorflow/lite/micro:system_setup",
+    ],
+)
+
+generate_cc_arrays(
+    name = "hello_world_tflite_cc",
+    src = "@tflite_micro//tensorflow/lite/micro/examples/hello_world/models:hello_world_int8.tflite",
+    out = "hello_world_tflite.cc",
+)
+
+generate_cc_arrays(
+    name = "hello_world_tflite_h",
+    src = "@tflite_micro//tensorflow/lite/micro/examples/hello_world/models:hello_world_int8.tflite",
+    out = "hello_world_tflite.h",
+)
diff --git a/tests/cocotb/tutorial/tflite_micro_test.cc b/tests/cocotb/tutorial/tflite_micro_test.cc
new file mode 100644
index 0000000..79c5886
--- /dev/null
+++ b/tests/cocotb/tutorial/tflite_micro_test.cc
@@ -0,0 +1,53 @@
+// Copyright 2025 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.
+
+#include <math.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "tensorflow/lite/core/c/common.h"
+#include "tensorflow/lite/micro/micro_interpreter.h"
+#include "tensorflow/lite/micro/micro_mutable_op_resolver.h"
+#include "tensorflow/lite/micro/system_setup.h"
+#include "tests/cocotb/tutorial/hello_world_tflite.h"
+
+namespace {
+using HelloWorldOpResolver = tflite::MicroMutableOpResolver<1>;
+
+TfLiteStatus RegisterOps(HelloWorldOpResolver& op_resolver) {
+  TF_LITE_ENSURE_STATUS(op_resolver.AddFullyConnected());
+  return kTfLiteOk;
+}
+}  // namespace
+
+int main(int argc, char** argv) {
+  const tflite::Model* model = tflite::GetModel(g_hello_world_int8_model_data);
+  HelloWorldOpResolver op_resolver;
+
+  constexpr size_t kTensorArenaSize = 3000;
+  uint8_t tensor_arena[kTensorArenaSize];
+
+  tflite::MicroInterpreter interpreter(model, op_resolver, tensor_arena,
+                                       kTensorArenaSize);
+
+  if (interpreter.AllocateTensors() != kTfLiteOk) {
+    return -1;
+  }
+  TfLiteTensor* input = interpreter.input(0);
+  memset(tflite::GetTensorData<uint8_t>(input), 0, input->bytes);
+  if (interpreter.Invoke() != kTfLiteOk) {
+    return -2;
+  }
+  return 0;
+}
diff --git a/third_party/tflite-micro/0001-Remove-xtensa-and-hifi-kernels.patch b/third_party/tflite-micro/0001-Remove-xtensa-and-hifi-kernels.patch
new file mode 100644
index 0000000..f4d6f58
--- /dev/null
+++ b/third_party/tflite-micro/0001-Remove-xtensa-and-hifi-kernels.patch
@@ -0,0 +1,141 @@
+From 9ceb5fda8112ab23d3410f6bfe3adbc364f26ff8 Mon Sep 17 00:00:00 2001
+From: Naveen Dodda <ndodda@google.com>
+Date: Wed, 24 Sep 2025 19:51:04 +0000
+Subject: [PATCH] Remove xtensa and hifi kernels
+
+---
+ tensorflow/lite/micro/kernels/BUILD | 88 +----------------------------
+ 1 file changed, 1 insertion(+), 87 deletions(-)
+
+diff --git a/tensorflow/lite/micro/kernels/BUILD b/tensorflow/lite/micro/kernels/BUILD
+index 1bb25088..9671c204 100644
+--- a/tensorflow/lite/micro/kernels/BUILD
++++ b/tensorflow/lite/micro/kernels/BUILD
+@@ -9,11 +9,6 @@ load(
+ load(
+     "//tensorflow:extra_rules.bzl",
+     "tflm_kernel_friends",
+-    "xtensa_fusion_f1_config",
+-    "xtensa_hifi_3_config",
+-    "xtensa_hifi_3z_config",
+-    "xtensa_hifi_5_config",
+-    "xtensa_vision_p6_config",
+ )
+ 
+ package(
+@@ -191,26 +186,6 @@ tflm_cc_library(
+     ],
+ )
+ 
+-HIFI3_COPTS = [
+-    "-DXTENSA=1",
+-    "-DHIFI3=1",
+-]
+-
+-HIFI4_COPTS = [
+-    "-DXTENSA=1",
+-    "-DHIFI4=1",
+-]
+-
+-HIFI5_COPTS = [
+-    "-DXTENSA=1",
+-    "-DHIFI5=1",
+-]
+-
+-VP6_COPTS = [
+-    "-DXTENSA=1",
+-    "-DVISION_P6=1",
+-]
+-
+ tflm_kernel_cc_library(
+     name = "micro_ops",
+     srcs = [
+@@ -354,26 +329,10 @@ tflm_kernel_cc_library(
+         "transpose_conv.h",
+         "unidirectional_sequence_lstm.h",
+     ] + select({
+-        xtensa_fusion_f1_config(): glob(["xtensa/**/*.h"]),
+-        xtensa_hifi_3_config(): glob(["xtensa/**/*.h"]),
+-        xtensa_hifi_3z_config(): glob(["xtensa/**/*.h"]),
+-        xtensa_hifi_5_config(): glob(["xtensa/**/*.h"]),
+-        xtensa_vision_p6_config(): glob(["xtensa/**/*.h"]),
+         "//conditions:default": [],
+     }),
+-    accelerated_srcs = {
+-        xtensa_fusion_f1_config(): glob(["xtensa/**/*.cc"]),
+-        xtensa_hifi_3_config(): glob(["xtensa/**/*.cc"]),
+-        xtensa_hifi_3z_config(): glob(["xtensa/**/*.cc"]),
+-        xtensa_hifi_5_config(): glob(["xtensa/**/*.cc"]),
+-        xtensa_vision_p6_config(): glob(["xtensa/**/*.cc"]),
+-    },
++    accelerated_srcs = {},
+     copts = tflm_copts() + select({
+-        xtensa_fusion_f1_config(): HIFI4_COPTS,
+-        xtensa_hifi_3_config(): HIFI3_COPTS,
+-        xtensa_hifi_3z_config(): HIFI4_COPTS,
+-        xtensa_hifi_5_config(): HIFI5_COPTS,
+-        xtensa_vision_p6_config(): VP6_COPTS,
+         "//conditions:default": [],
+     }),
+     visibility = [
+@@ -405,11 +364,6 @@ tflm_kernel_cc_library(
+         "//tensorflow/lite/schema:schema_fbs",
+         "@flatbuffers//:runtime_cc",
+     ] + select({
+-        xtensa_fusion_f1_config(): ["//third_party/xtensa/nnlib_hifi4:nnlib_hifi4_lib"],
+-        xtensa_hifi_3_config(): ["//third_party/xtensa/nnlib_hifi4:nnlib_hifi4_lib"],
+-        xtensa_hifi_3z_config(): ["//third_party/xtensa/nnlib_hifi4:nnlib_hifi4_lib"],
+-        xtensa_hifi_5_config(): ["//third_party/xtensa/nnlib_hifi5:nnlib_hifi5_lib"],
+-        xtensa_vision_p6_config(): ["//third_party/xtensa/xi_tflmlib_vision_p6:xi_tflmlib_vision_p6_lib"],
+         "//conditions:default": [],
+     }),
+ )
+@@ -1538,45 +1492,5 @@ string_flag(
+     build_setting_default = "",
+     values = [
+         "",
+-        "xtensa_fusion_f1",
+-        "xtensa_hifi_3",
+-        "xtensa_hifi_3z",
+-        "xtensa_hifi_5",
+-        "xtensa_vision_p6",
+     ],
+ )
+-
+-config_setting(
+-    name = "xtensa_fusion_f1_default",
+-    flag_values = {
+-        ":optimized_kernels": "xtensa_fusion_f1",
+-    },
+-)
+-
+-config_setting(
+-    name = "xtensa_hifi_3_default",
+-    flag_values = {
+-        ":optimized_kernels": "xtensa_hifi_3",
+-    },
+-)
+-
+-config_setting(
+-    name = "xtensa_hifi_3z_default",
+-    flag_values = {
+-        ":optimized_kernels": "xtensa_hifi_3z",
+-    },
+-)
+-
+-config_setting(
+-    name = "xtensa_hifi_5_default",
+-    flag_values = {
+-        ":optimized_kernels": "xtensa_hifi_5",
+-    },
+-)
+-
+-config_setting(
+-    name = "xtensa_vision_p6_default",
+-    flag_values = {
+-        ":optimized_kernels": "xtensa_vision_p6",
+-    },
+-)
+-- 
+2.51.0.536.g15c5d4f767-goog
+
diff --git a/third_party/tflite-micro/BUILD.bazel b/third_party/tflite-micro/BUILD.bazel
new file mode 100644
index 0000000..9ba09c9
--- /dev/null
+++ b/third_party/tflite-micro/BUILD.bazel
@@ -0,0 +1,24 @@
+# Copyright 2025 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
+#
+#     http://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.
+
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+    name = "all_srcs",
+    srcs = glob(["*.patch"]),
+)
+
+exports_files(
+    srcs = glob(["*.patch"]),
+)
diff --git a/third_party/tflite-micro/Tflite-Micro-Kelvin-integration.patch b/third_party/tflite-micro/Tflite-Micro-Kelvin-integration.patch
new file mode 100644
index 0000000..df82766
--- /dev/null
+++ b/third_party/tflite-micro/Tflite-Micro-Kelvin-integration.patch
@@ -0,0 +1,158 @@
+From 8bc9af42f6f20e6a2a3e83d512e918c6f85239c8 Mon Sep 17 00:00:00 2001
+From: Naveen Dodda <ndodda@google.com>
+Date: Fri, 12 Sep 2025 23:04:51 +0000
+Subject: [PATCH] TFmicro Kelvin integration
+
+---
+ .../micro/examples/hello_world/models/BUILD   |  5 +---
+ tensorflow/lite/micro/tools/BUILD             |  2 +-
+ tensorflow/workspace.bzl                      |  1 +
+ third_party/gemmlowp/BUILD                    |  6 +++++
+ .../gemmlowp/remove-pthreads-as-default.patch | 25 +++++++++++++++++++
+ third_party/ruy/BUILD                         |  2 ++
+ .../ruy/remove-pthreads-as-default.patch      | 23 +++++++++++++++++
+ third_party/ruy/workspace.bzl                 |  2 ++
+ 8 files changed, 61 insertions(+), 5 deletions(-)
+ create mode 100644 third_party/gemmlowp/BUILD
+ create mode 100644 third_party/gemmlowp/remove-pthreads-as-default.patch
+ create mode 100644 third_party/ruy/remove-pthreads-as-default.patch
+
+diff --git a/tensorflow/lite/micro/examples/hello_world/models/BUILD b/tensorflow/lite/micro/examples/hello_world/models/BUILD
+index 4c9441b8..457cf190 100644
+--- a/tensorflow/lite/micro/examples/hello_world/models/BUILD
++++ b/tensorflow/lite/micro/examples/hello_world/models/BUILD
+@@ -9,10 +9,7 @@ exports_files(
+         "hello_world_float.tflite",
+         "hello_world_int8.tflite",
+     ],
+-    visibility = [
+-        "//codegen/examples/hello_world:__subpackages__",
+-        "//tensorflow/lite/micro/examples/hello_world:__subpackages__",
+-    ],
++    visibility = ["//visibility:public"] ,
+ )
+ 
+ generate_cc_arrays(
+diff --git a/tensorflow/lite/micro/tools/BUILD b/tensorflow/lite/micro/tools/BUILD
+index c3b2f981..8e10f866 100644
+--- a/tensorflow/lite/micro/tools/BUILD
++++ b/tensorflow/lite/micro/tools/BUILD
+@@ -5,7 +5,7 @@ load("@pybind11_bazel//:build_defs.bzl", "pybind_extension")
+ load("//tensorflow:extra_rules.bzl", "tflm_application_friends")
+ 
+ package(
+-    default_visibility = ["//:__subpackages__"],
++    default_visibility = ["//visibility:public"],
+     licenses = ["notice"],
+ )
+ 
+diff --git a/tensorflow/workspace.bzl b/tensorflow/workspace.bzl
+index b799523b..4aed7b03 100644
+--- a/tensorflow/workspace.bzl
++++ b/tensorflow/workspace.bzl
+@@ -35,6 +35,7 @@ def tf_repositories(path_prefix = "", tf_repo_name = ""):
+             "https://storage.googleapis.com/mirror.tensorflow.org/github.com/google/gemmlowp/archive/fda83bdc38b118cc6b56753bd540caa49e570745.zip",
+             "https://github.com/google/gemmlowp/archive/fda83bdc38b118cc6b56753bd540caa49e570745.zip",
+         ],
++        patch_file = "@tflite_micro//third_party/gemmlowp:remove-pthreads-as-default.patch",
+     )
+ 
+     tf_http_archive(
+diff --git a/third_party/gemmlowp/BUILD b/third_party/gemmlowp/BUILD
+new file mode 100644
+index 00000000..b4ea97ae
+--- /dev/null
++++ b/third_party/gemmlowp/BUILD
+@@ -0,0 +1,6 @@
++ackage(
++    default_visibility = ["//visibility:public"],
++    licenses = ["notice"],
++)
++
++exports_files(glob(["*.patch"]))
+\ No newline at end of file
+diff --git a/third_party/gemmlowp/remove-pthreads-as-default.patch b/third_party/gemmlowp/remove-pthreads-as-default.patch
+new file mode 100644
+index 00000000..e32ac209
+--- /dev/null
++++ b/third_party/gemmlowp/remove-pthreads-as-default.patch
+@@ -0,0 +1,25 @@
++From 6f094c09fe6ae26306f1b376ceeed02f3af52d01 Mon Sep 17 00:00:00 2001
++From: Naveen Dodda <ndodda@google.com>
++Date: Mon, 8 Sep 2025 21:30:52 +0000
++Subject: [PATCH] Changes to turn off default threads option
++
++---
++ flags.bzl | 2 +-
++ 1 file changed, 1 insertion(+), 1 deletion(-)
++
++diff --git a/flags.bzl b/flags.bzl
++index e35fe9e..e26a448 100644
++--- a/flags.bzl
+++++ b/flags.bzl
++@@ -4,7 +4,7 @@ LIB_COPTS = []
++ LIB_LINKOPTS = select({
++     ":android": [],
++     ":windows": [],
++-    "//conditions:default": ["-lpthread"],
+++    "//conditions:default": [],
++ })
++ 
++ BIN_LINKOPTS = LIB_LINKOPTS
++-- 
++2.51.0.384.g4c02a37b29-goog
++
+diff --git a/third_party/ruy/BUILD b/third_party/ruy/BUILD
+index 518fea8f..f4ab327d 100644
+--- a/third_party/ruy/BUILD
++++ b/third_party/ruy/BUILD
+@@ -4,3 +4,5 @@ package(
+     default_visibility = ["//visibility:public"],
+     licenses = ["notice"],
+ )
++
++exports_files(glob(["*.patch"]) + ["LICENSE"])
+\ No newline at end of file
+diff --git a/third_party/ruy/remove-pthreads-as-default.patch b/third_party/ruy/remove-pthreads-as-default.patch
+new file mode 100644
+index 00000000..5c834007
+--- /dev/null
++++ b/third_party/ruy/remove-pthreads-as-default.patch
+@@ -0,0 +1,23 @@
++From 621a1914d61159f2b4461aaf87a5a0e35156180f Mon Sep 17 00:00:00 2001
++From: Naveen Dodda <ndodda@google.com>
++Date: Fri, 12 Sep 2025 22:13:17 +0000
++Subject: [PATCH] remove pthreads as default
++
++---
++ ruy/build_defs.oss.bzl | 2 +-
++ 1 file changed, 1 insertion(+), 1 deletion(-)
++
++diff --git a/ruy/build_defs.oss.bzl b/ruy/build_defs.oss.bzl
++index e405b41..83097b7 100644
++--- a/ruy/build_defs.oss.bzl
+++++ b/ruy/build_defs.oss.bzl
++@@ -11,5 +11,5 @@ def ruy_linkopts_thread_standard_library():
++     # https://github.com/abseil/abseil-cpp/blob/1112609635037a32435de7aa70a9188dcb591458/absl/base/BUILD.bazel#L155
++     return select({
++         "@bazel_tools//src/conditions:windows": [],
++-        "//conditions:default": ["-pthread"],
+++        "//conditions:default": [""],
++     })
++-- 
++2.51.0.384.g4c02a37b29-goog
++
+diff --git a/third_party/ruy/workspace.bzl b/third_party/ruy/workspace.bzl
+index 50769621..b5274df9 100644
+--- a/third_party/ruy/workspace.bzl
++++ b/third_party/ruy/workspace.bzl
+@@ -12,4 +12,6 @@ def repo():
+             "https://github.com/google/ruy/archive/54774a7a2cf85963777289193629d4bd42de4a59.zip",
+         ],
+         build_file = "//third_party/ruy:BUILD",
++        patch_file = "@tflite_micro//third_party/ruy:remove-pthreads-as-default.patch",
++
+     )
+-- 
+2.51.0.534.gc79095c0ca-goog
+
diff --git a/toolchain/BUILD.bazel b/toolchain/BUILD.bazel
index bc00348..c6d1cc6 100644
--- a/toolchain/BUILD.bazel
+++ b/toolchain/BUILD.bazel
@@ -21,6 +21,7 @@
     srcs = [
         "//toolchain/wrappers:all",
         "//toolchain:kelvin_tcm.ld",
+        "//toolchain:kelvin_tcm_highmem.ld",
         "@toolchain_kelvin_v2//:all_files",
     ],
 )
diff --git a/toolchain/build_scripts/README.md b/toolchain/build_scripts/README.md
index eae25c2..d12b09f 100644
--- a/toolchain/build_scripts/README.md
+++ b/toolchain/build_scripts/README.md
@@ -12,4 +12,4 @@
 $ docker run -v `pwd`:/toolchain/build_scripts -w /toolchain/build_scripts toolchain_test bash kelvin_v2_toolchain_build.sh
 ```
 
-The toolchain artifacts will be located at rv32_out
+Output toolchain artifacts will be exported to rv32_out
\ No newline at end of file
diff --git a/toolchain/cc_toolchain_config.bzl b/toolchain/cc_toolchain_config.bzl
index b55194b..5e3c7c7 100644
--- a/toolchain/cc_toolchain_config.bzl
+++ b/toolchain/cc_toolchain_config.bzl
@@ -28,19 +28,24 @@
     ACTION_NAMES.cpp_link_nodeps_dynamic_library,
 ]
 
-all_compile_actions = [
-    ACTION_NAMES.c_compile,
-    ACTION_NAMES.assemble,
-    ACTION_NAMES.preprocess_assemble,
-    ACTION_NAMES.linkstamp_compile,
+cpp_compile_actions = [
     ACTION_NAMES.cpp_compile,
     ACTION_NAMES.cpp_header_parsing,
     ACTION_NAMES.cpp_module_compile,
     ACTION_NAMES.cpp_module_codegen,
+]
+
+other_compile_actions = [
+    ACTION_NAMES.c_compile,
+    ACTION_NAMES.assemble,
+    ACTION_NAMES.preprocess_assemble,
+    ACTION_NAMES.linkstamp_compile,
     ACTION_NAMES.lto_backend,
     ACTION_NAMES.clif_match,
 ]
 
+all_compile_actions = cpp_compile_actions + other_compile_actions
+
 def _impl(ctx):
     tool_paths = [
         tool_path(
@@ -150,8 +155,8 @@
         ],
     )
 
-    optimization_compile_flag_set = flag_set(
-        actions = all_compile_actions,
+    optimization_cpp_compile_flag_set = flag_set(
+        actions = cpp_compile_actions,
         flag_groups = [
             flag_group(
                 flags = [
@@ -159,7 +164,22 @@
                     "-Os",
                     "-ffunction-sections",
                     "-fdata-sections",
-                    "-ffreestanding",
+                    "-fno-exceptions",
+                    "-fno-rtti",
+                ],
+            ),
+        ],
+    )
+
+    optimization_other_compile_flag_set = flag_set(
+        actions = other_compile_actions,
+        flag_groups = [
+            flag_group(
+                flags = [
+                    "-g3",
+                    "-Os",
+                    "-ffunction-sections",
+                    "-fdata-sections",
                 ],
             ),
         ],
@@ -256,7 +276,8 @@
         name = "fastbuild",
         enabled = False,
         flag_sets = [
-            optimization_compile_flag_set,
+            optimization_cpp_compile_flag_set,
+            optimization_other_compile_flag_set,
             optimization_link_flag_set,
         ],
         provides = ["compilation_mode"],
@@ -266,7 +287,8 @@
         name = "opt",
         enabled = False,
         flag_sets = [
-            optimization_compile_flag_set,
+            optimization_cpp_compile_flag_set,
+            optimization_other_compile_flag_set,
             optimization_link_flag_set,
         ],
         provides = ["compilation_mode"],
diff --git a/toolchain/kelvin_tcm_highmem.ld b/toolchain/kelvin_tcm_highmem.ld
new file mode 100644
index 0000000..117bb17
--- /dev/null
+++ b/toolchain/kelvin_tcm_highmem.ld
@@ -0,0 +1,120 @@
+/* Copyright 2025 Google LLC. */
+/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+MEMORY {
+    ITCM(rx): ORIGIN = 0x00000000, LENGTH = 1024K
+    DTCM(rw): ORIGIN = 0x00100000, LENGTH = 1024K
+}
+
+STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x80;
+__stack_size = STACK_SIZE;
+__stack_shift = 7;
+__boot_hart = 0;
+HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x80;
+
+ENTRY(_start)
+
+SECTIONS {
+    /* ITCM data here */
+    . = ORIGIN(ITCM);
+    .text : ALIGN(16) {
+        *(._init)
+        *(.text)
+        *(.text.*)
+        . = ALIGN(16);
+    } > ITCM
+
+    .init.array : ALIGN(16) {
+      __init_array_start = .;
+      __init_array_start__ = .;
+      *(.init_array)
+      *(.init_array.*)
+      . = ALIGN(16);
+      __init_array_end = .;
+      __init_array_end__ = .;
+    } > ITCM
+
+    .rodata : ALIGN(16) {
+      *(.srodata)
+      *(.srodata.*)
+      *(.rodata)
+      *(.rodata.*)
+      . = ALIGN(16);
+    } > ITCM
+
+    /* Static Thread Local Storage template */
+    .tdata : {
+        PROVIDE_HIDDEN (__tdata_start = .);
+        *(.tdata .tdata.*)
+        *(.gnu.linkonce.td.*)
+        PROVIDE_HIDDEN (__tdata_end = .);
+    } > DTCM
+    PROVIDE (__tdata_size = SIZEOF (.tdata));
+
+    .tbss (NOLOAD) : {
+        PROVIDE_HIDDEN (__tbss_start = .);
+        PROVIDE_HIDDEN (__tbss_offset = ABSOLUTE (__tbss_start - __tdata_start));
+        *(.tbss .tbss.*)
+        *(.gnu.linkonce.tb.*)
+        *(.tcommon)
+        PROVIDE_HIDDEN (__tbss_end = .);
+    } > DTCM
+    PROVIDE (__tbss_size = SIZEOF (.tbss));
+
+    .data : ALIGN(16) {
+      __data_start__ = .;
+      /**
+      * This will get loaded into `gp`, and the linker will use that register for
+      * accessing data within [-2048,2047] of `__global_pointer$`.
+      *
+      * This is much cheaper (for small data) than materializing the
+      * address and loading from that (which will take one extra instruction).
+      */
+      _global_pointer = . + 0x800;
+      __global_pointer$ = . + 0x800;
+      *(.sdata)
+      *(.sdata.*)
+      *(.data)
+      *(.data.*)
+      /**
+       * Memory location for the return value from main,
+       * which could be inspected by another core in the system.
+       **/
+      . = ALIGN(4);
+      _ret = .;
+      . += 4;
+      . = ALIGN(16);
+      __data_end__ = .;
+      _edata = .;
+    } > DTCM
+
+    /* DTCM data here */
+    . = ORIGIN(DTCM);
+    .bss : ALIGN(16) {
+      __bss_start__ = .;
+      __bss_start = .;
+      *(.sbss)
+      *(.sbss.*)
+      *(.bss)
+      *(.bss.*)
+      __bss_end__ = .;
+      __bss_end = .;
+      _end = .;
+    } > DTCM
+
+    .heap : ALIGN(16) {
+      __heap_start__ = .;
+      _heap_ptr = .;
+      . += HEAP_SIZE;
+      __heap_end__ = .;
+      __heap_end = .;
+    } > DTCM
+
+    .stack : ALIGN(16) {
+      __stack_start__ = .;
+      __stack_start = .;
+      . += STACK_SIZE;
+      __stack_end__ = .;
+    } > DTCM
+}
\ No newline at end of file