[sw] Provide our own freestanding C headers.

Since these headers implement C11, this change bumps the -std flag
passed to GCC/Clang to c11.

This change also sets up Meson and Make to ignore all system/compiler
headers except for those we provide.

Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
diff --git a/meson.build b/meson.build
index eb7bde8..13a9d9d 100644
--- a/meson.build
+++ b/meson.build
@@ -6,9 +6,9 @@
   'opentitan', 'c', 'cpp',
   version: '0.1',
   meson_version: '>=0.51.0', # Matches version in python-requirements.txt
-  default_options : [
-    'c_std=c99',
-    'build.c_std=c99',
+  default_options: [
+    'c_std=c11',
+    'build.c_std=c11',
     'cpp_std=c++14',
     'build.cpp_std=c++14',
     'warning_level=1',
@@ -62,6 +62,7 @@
 add_project_arguments(
   '-I' + meson.source_root(),
   '-I' + meson.build_root(),
+  '-isystem' + meson.source_root() / 'sw/device/lib/base/freestanding',
   language: 'c', native: false)
 add_project_arguments(
   '-I' + meson.source_root(),
@@ -71,13 +72,13 @@
 # The following flags are applied only to cross builds
 add_project_arguments(
   # Do not use standard system startup files or libraries
-  '-nostartfiles', '-nostdlib',
+  '-nostartfiles', '-nostdlib', '-nostdinc',
   '-static', # Only link static files
   optimize_size_args,
   language: 'cpp', native: false)
 add_project_arguments(
   # Do not use standard system startup files or libraries
-  '-nostartfiles', '-nostdlib',
+  '-nostartfiles', '-nostdlib', '-nostdinc',
   '-static', # Only link static files
   optimize_size_args,
   language: 'c', native: false)
diff --git a/sw/device/exts/common/meson.build b/sw/device/exts/common/meson.build
index 38ce046..88a9478 100644
--- a/sw/device/exts/common/meson.build
+++ b/sw/device/exts/common/meson.build
@@ -23,7 +23,11 @@
   # This is included as a source, not as a static library, so that the .crt
   # section is picked up correctly.
   sources: ['_crt.c'],
-  dependencies: [sw_lib_irq, sw_lib_mem],
+  dependencies: [
+    freestanding_headers,
+    sw_lib_mem,
+    sw_lib_irq,
+  ],
   # This argument exists solely so that Meson realizes that riscv_linker_script
   # is part of the dependency graph. This seems to be the only way to convince
   # Meson to behave in this way, for the following reasons:
diff --git a/sw/device/lib/base/freestanding/README.md b/sw/device/lib/base/freestanding/README.md
new file mode 100644
index 0000000..d871686
--- /dev/null
+++ b/sw/device/lib/base/freestanding/README.md
@@ -0,0 +1,10 @@
+# OpenTitan Freestanding C Headers
+
+This subtree defines headers requred for a C freestanding implementation, as specified in S4p6 of the C11 standard.
+Said headers are implemented to the letter as described in respective sections of said standard.
+
+All of `sw/device` is compiled using only these headers, and this directory acts as the sole root against which `#include <...>` directives are resolved.
+Headers provided by the system or the compiler are totally inaccessible and should not be used.
+
+These headers are guaranteed to be compatible with processors and compilers implementing the RISC-V ILP32 psABI, though they may be compatible with other architectures and calling conventions on a best-effort basis.
+However, compilers *must* be compatible with Clang and GCC's intrinsics.
diff --git a/sw/device/lib/base/freestanding/float.h b/sw/device/lib/base/freestanding/float.h
new file mode 100644
index 0000000..0cf3b9c
--- /dev/null
+++ b/sw/device/lib/base/freestanding/float.h
@@ -0,0 +1,70 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_FLOAT_H_
+#define OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_FLOAT_H_
+
+/**
+ * This header implements the float.h standard header, as required by C11 S4p6.
+ * This header is specified in detail in S7.7 and S5.2.4.2.2 of the same.
+ *
+ * The compiler-defined names below are cribbed from
+ * https://clang.llvm.org/doxygen/float_8h_source.html
+ */
+
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#define FLT_ROUNDS (-1)
+#define FLT_RADIX __FLT_RADIX__
+
+#define FLT_MANT_DIG __FLT_MANT_DIG__
+#define DBL_MANT_DIG __DBL_MANT_DIG__
+#define LDBL_MANT_DIG __LDBL_MANT_DIG__
+
+#define DECIMAL_DIG __DECIMAL_DIG__
+
+#define FLT_DIG __FLT_DIG__
+#define DBL_DIG __DBL_DIG__
+#define LDBL_DIG __LDBL_DIG__
+
+#define FLT_MIN_EXP __FLT_MIN_EXP__
+#define DBL_MIN_EXP __DBL_MIN_EXP__
+#define LDBL_MIN_EXP __LDBL_MIN_EXP__
+
+#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
+#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
+#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
+
+#define FLT_MAX_EXP __FLT_MAX_EXP__
+#define DBL_MAX_EXP __DBL_MAX_EXP__
+#define LDBL_MAX_EXP __LDBL_MAX_EXP__
+
+#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
+#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
+#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
+
+#define FLT_MAX __FLT_MAX__
+#define DBL_MAX __DBL_MAX__
+#define LDBL_MAX __LDBL_MAX__
+
+#define FLT_EPSILON __FLT_EPSILON__
+#define DBL_EPSILON __DBL_EPSILON__
+#define LDBL_EPSILON __LDBL_EPSILON__
+
+#define FLT_MIN __FLT_MIN__
+#define DBL_MIN __DBL_MIN__
+#define LDBL_MIN __LDBL_MIN__
+
+#define FLT_TRUE_MIN __FLT_DENORM_MIN__
+#define DBL_TRUE_MIN __DBL_DENORM_MIN__
+#define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
+
+#define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__
+#define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__
+#define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__
+
+#define FLT_HAS_SUBNORM __FLT_HAS_DENORM__
+#define DBL_HAS_SUBNORM __DBL_HAS_DENORM__
+#define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_FLOAT_H_
diff --git a/sw/device/lib/base/freestanding/iso646.h b/sw/device/lib/base/freestanding/iso646.h
new file mode 100644
index 0000000..762f480
--- /dev/null
+++ b/sw/device/lib/base/freestanding/iso646.h
@@ -0,0 +1,38 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_ISO646_H_
+#define OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_ISO646_H_
+
+/**
+ * This header implements the iso646.h standard header, as required by C11 S4p6.
+ * See S7.9 of the same for a description.
+ *
+ * This file is provided only for standards compliance reason; including this
+ * file is a style violation.
+ */
+
+// The below macro definitions cause clang-format to freak out somewhat, so we
+// need to turn it off.
+// clang-format off
+
+#define and &&
+#define and_eq &=
+#define bitand &
+
+#define or ||
+#define or_eq |=
+#define bitor |
+
+#define xor ^
+#define xor_eq ^=
+
+#define not !
+#define not_eq !=
+
+#define compl ~
+
+// clang-format on
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_ISO646_H_
diff --git a/sw/device/lib/base/freestanding/limits.h b/sw/device/lib/base/freestanding/limits.h
new file mode 100644
index 0000000..4b16fba
--- /dev/null
+++ b/sw/device/lib/base/freestanding/limits.h
@@ -0,0 +1,44 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_LIMITS_H_
+#define OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_LIMITS_H_
+
+#include <stdint.h>
+
+/**
+ * This header implements the limits.h standard header, as required by C11 S4p6.
+ * This header is specified in detail in S7.10 and S5.2.4.2.1 of the same.
+ */
+
+#define SCHAR_MAX __SCHAR_MAX__
+#define SHRT_MAX __SHRT_MAX__
+#define INT_MAX __INT_MAX__
+#define LONG_MAX __LONG_MAX__
+#define LLONG_MAX __LONG_LONG_MAX__
+
+#define SCHAR_MIN (-__SCHAR_MAX__ - 1)
+#define SHRT_MIN (-__SHRT_MAX__ - 1)
+#define INT_MIN (-__INT_MAX__ - 1)
+#define LONG_MIN (-__LONG_MAX__ - 1L)
+#define LLONG_MIN (-__LONG_LONG_MAX__ - 1LL)
+
+#define UCHAR_MAX (__SCHAR_MAX__ * 2 + 1)
+#define USHRT_MAX (__SHRT_MAX__ * 2 + 1)
+#define UINT_MAX (__INT_MAX__ * 2U + 1U)
+#define ULONG_MAX (__LONG_MAX__ * 2UL + 1UL)
+#define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL)
+
+#define CHAR_BIT __CHAR_BIT__
+#define MB_LEN_MAX (1)
+
+#ifdef __CHAR_UNSIGNED__
+#define CHAR_MIN (0)
+#define CHAR_MAX UCHAR_MAX
+#else
+#define CHAR_MIN SCHAR_MIN
+#define CHAR_MAX SCHAR_MAX
+#endif
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_LIMITS_H_
diff --git a/sw/device/lib/base/freestanding/meson.build b/sw/device/lib/base/freestanding/meson.build
new file mode 100644
index 0000000..94477a5
--- /dev/null
+++ b/sw/device/lib/base/freestanding/meson.build
@@ -0,0 +1,19 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+# This target exists so that Meson can be made aware that other targets depend
+# on these headers.
+freestanding_headers = declare_dependency(
+  sources: [
+    'float.h',
+    'iso646.h',
+    'limits.h',
+    'stdalign.h',
+    'stdarg.h',
+    'stdbool.h',
+    'stddef.h',
+    'stdint.h',
+    'stdnoreturn.h',
+  ],
+)
diff --git a/sw/device/lib/base/freestanding/stdalign.h b/sw/device/lib/base/freestanding/stdalign.h
new file mode 100644
index 0000000..3feab85
--- /dev/null
+++ b/sw/device/lib/base/freestanding/stdalign.h
@@ -0,0 +1,19 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDALIGN_H_
+#define OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDALIGN_H_
+
+/**
+ * This header implements the stdalign.h standard header, as required by C11
+ * S4p6. This header is specified in detail in S7.15 of the same.
+ */
+
+#define alignas _Alignas
+#define __alignas_is_defined 1
+
+#define alignof _Alignof
+#define __alignof_is_defined 1
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDALIGN_H_
diff --git a/sw/device/lib/base/freestanding/stdarg.h b/sw/device/lib/base/freestanding/stdarg.h
new file mode 100644
index 0000000..dca2e72
--- /dev/null
+++ b/sw/device/lib/base/freestanding/stdarg.h
@@ -0,0 +1,22 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDARG_H_
+#define OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDARG_H_
+
+/**
+ * This header implements the stdarg.h standard header, as required by C11 S4p6.
+ * This header is specified in detail in S7.16.
+ *
+ * The compiler intrinsics below are cribbed from
+ * https://clang.llvm.org/doxygen/stdarg_8h_source.html
+ */
+
+typedef __builtin_va_list va_list;
+#define va_start(ap, param) __builtin_va_start(ap, param)
+#define va_end(ap) __builtin_va_end(ap)
+#define va_arg(ap, type) __builtin_va_arg(ap, type)
+#define va_copy(dest, src) __builtin_va_copy(dest, src)
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDARG_H_
diff --git a/sw/device/lib/base/freestanding/stdbool.h b/sw/device/lib/base/freestanding/stdbool.h
new file mode 100644
index 0000000..95b4077
--- /dev/null
+++ b/sw/device/lib/base/freestanding/stdbool.h
@@ -0,0 +1,19 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDBOOL_H_
+#define OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDBOOL_H_
+
+/**
+ * This header implements the stdbool.h standard header, as required by C11
+ * S4p6. This header is specified in detail in S7.18 of the same.
+ */
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+#define __bool_true_false_are_defined 1
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDBOOL_H_
diff --git a/sw/device/lib/base/freestanding/stddef.h b/sw/device/lib/base/freestanding/stddef.h
new file mode 100644
index 0000000..2667f66
--- /dev/null
+++ b/sw/device/lib/base/freestanding/stddef.h
@@ -0,0 +1,33 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDDEF_H_
+#define OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDDEF_H_
+
+#include <stdalign.h>
+#include <stdint.h>
+
+/**
+ * This header implements the stdint.h standard header, as required by C11 S4p6.
+ * This header is specified in detail in S7.19 of the same.
+ *
+ * See https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md
+ * for the RISC-V specifics this file conforms to.
+ */
+
+// GCC's built-in defines do not include a type with the maximum alignment, but
+// does include a define with the maximum alignment value. Since the only
+// requirement of |max_align_t| is that it be some type such that its alignment
+// is maximal, we simply use a one-byte struct whose alignment is forced to be
+// the maximum.
+typedef struct { alignas(__BIGGEST_ALIGNMENT__) uint8_t __nonce; } max_align_t;
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+typedef __WCHAR_TYPE__ wchar_t;
+
+#define NULL ((void *)0)
+#define offsetof(type, member) __builtin_offsetof(type, member)
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDDEF_H_
diff --git a/sw/device/lib/base/freestanding/stdint.h b/sw/device/lib/base/freestanding/stdint.h
new file mode 100644
index 0000000..2c618a8
--- /dev/null
+++ b/sw/device/lib/base/freestanding/stdint.h
@@ -0,0 +1,137 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDINT_H_
+#define OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDINT_H_
+
+/**
+ * This header implements the stdint.h standard header, as required by C11 S4p6.
+ * This header is specified in detail in S7.20 the same.
+ *
+ * Actual limit values below are defined as:
+ * - Unsigned MAXs are defined as the |0xff..ffU| all-ones representation.
+ * - Signed MINs are defined as |0x80..00| all-zeroes-but-the-last
+ *   representation.
+ * - Unsigned MAXs are defined as |0x7f..ff| all-ones-but-the-last
+ *   representation.
+ * These shorthands are correct for two's complement and the ones least likely
+ * to get a mistake in.
+ *
+ * It goes without saying that this file assumes the underlying representation
+ * is two's complement and little-endian.
+ *
+ * See https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md
+ * for the RISC-V specifics this file conforms to.
+ */
+
+typedef __UINT8_TYPE__ uint8_t;
+typedef __UINT16_TYPE__ uint16_t;
+typedef __UINT32_TYPE__ uint32_t;
+typedef __UINT64_TYPE__ uint64_t;
+typedef __INT8_TYPE__ int8_t;
+typedef __INT16_TYPE__ int16_t;
+typedef __INT32_TYPE__ int32_t;
+typedef __INT64_TYPE__ int64_t;
+
+typedef __UINT_LEAST8_TYPE__ uint_least8_t;
+typedef __UINT_LEAST16_TYPE__ uint_least16_t;
+typedef __UINT_LEAST32_TYPE__ uint_least32_t;
+typedef __UINT_LEAST64_TYPE__ uint_least64_t;
+typedef __INT_LEAST8_TYPE__ int_least8_t;
+typedef __INT_LEAST16_TYPE__ int_least16_t;
+typedef __INT_LEAST32_TYPE__ int_least32_t;
+typedef __INT_LEAST64_TYPE__ int_least64_t;
+
+typedef __UINT_FAST8_TYPE__ uint_fast8_t;
+typedef __UINT_FAST16_TYPE__ uint_fast16_t;
+typedef __UINT_FAST32_TYPE__ uint_fast32_t;
+typedef __UINT_FAST64_TYPE__ uint_fast64_t;
+typedef __INT_FAST8_TYPE__ int_fast8_t;
+typedef __INT_FAST16_TYPE__ int_fast16_t;
+typedef __INT_FAST32_TYPE__ int_fast32_t;
+typedef __INT_FAST64_TYPE__ int_fast64_t;
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+typedef __INTPTR_TYPE__ intptr_t;
+
+typedef __UINTMAX_TYPE__ uintmax_t;
+typedef __INTMAX_TYPE__ intmax_t;
+
+// NOTE: Below, we use GCC/Clang's built-in defines for limits. However, only
+// MAX limits are provided and, as such, we define a signed MIN, given a MAX, as
+// (-MIN - 1). (MAX + 1) will trigger signed overflow and, as such, Undefined
+// Behavior.
+
+#define INT8_MIN (-__INT8_MAX__ - 1)
+#define INT8_MAX __INT8_MAX__
+#define UINT8_MAX __UINT8_MAX__
+#define INT16_MIN (-__INT16_MAX__ - 1)
+#define INT16_MAX __INT16_MAX__
+#define UINT16_MAX __UINT16_MAX__
+#define INT32_MIN (-__INT32_MAX__ - 1)
+#define INT32_MAX __INT32_MAX__
+#define UINT32_MAX __UINT32_MAX__
+#define INT64_MIN (-__INT64_MAX__ - 1)
+#define INT64_MAX __INT64_MAX__
+#define UINT64_MAX __UINT64_MAX__
+
+#define INT_LEAST8_MIN (-__INT_LEAST8_MAX__ - 1)
+#define INT_LEAST8_MAX __INT_LEAST8_MAX__
+#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
+#define INT_LEAST16_MIN (-__INT_LEAST16_MAX__ - 1)
+#define INT_LEAST16_MAX __INT_LEAST16_MAX__
+#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
+#define INT_LEAST32_MIN (-__INT_LEAST32_MAX__ - 1)
+#define INT_LEAST32_MAX __INT_LEAST32_MAX__
+#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
+#define INT_LEAST64_MIN (-__INT_LEAST64_MAX__ - 1)
+#define INT_LEAST64_MAX __INT_LEAST64_MAX__
+#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
+
+#define INT_FAST8_MIN (-__INT_FAST8_MAX__ - 1)
+#define INT_FAST8_MAX __INT_FAST8_MAX__
+#define UINT_FAST8_MAX __UINT_FAST8_MAX__
+#define INT_FAST16_MIN (-__INT_FAST16_MAX__ - 1)
+#define INT_FAST16_MAX __INT_FAST16_MAX__
+#define UINT_FAST16_MAX __UINT_FAST16_MAX__
+#define INT_FAST32_MIN (-__INT_FAST32_MAX__ - 1)
+#define INT_FAST32_MAX __INT_FAST32_MAX__
+#define UINT_FAST32_MAX __UINT_FAST32_MAX__
+#define INT_FAST64_MIN (-__INT_FAST64_MAX__ - 1)
+#define INT_FAST64_MAX __INT_FAST64_MAX__
+#define UINT_FAST64_MAX __UINT_FAST64_MAX__
+
+#define INTPTR_MIN (-__INTPTR_MAX__ - 1)
+#define INTPTR_MAX __INTPTR_MAX__
+#define UINTPTR_MAX __UINTPTR_MAX__
+
+#define INTMAX_MIN (-__INTMAX_MAX__ - 1)
+#define INTMAX_MAX __INTMAX_MAX__
+#define UINTMAX_MAX __UINTMAX_MAX__
+
+#define PTRDIFF_MIN (-__PTRDIFF_MAX__ - 1)
+#define PTRDIFF_MAX __PTRDIFF_MAX__
+
+#define SIZE_MAX __SIZE_MAX__
+
+#define WCHAR_MIN (-__WCHAR_MAX__ - 1)
+#define WCHAR_MAX __WCHAR_MAX__
+
+// NOTE: While GCC and Clang both provide macros for implememting the _C macros,
+// they are inconsistent on which is correct, so we implement them ourselves
+// below.
+
+#define INT8_C(value) (value)
+#define INT16_C(value) (value)
+#define INT32_C(value) (value)
+#define INT64_C(value) (value##LL)
+#define INTMAX_C(value) (value##LL)
+
+#define UINT8_C(value) (value##U)
+#define UINT16_C(value) (value##U)
+#define UINT32_C(value) (value##U)
+#define UINT64_C(value) (value##ULL)
+#define UINTMAX_C(value) (value##ULL)
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDINT_H_
diff --git a/sw/device/lib/base/freestanding/stdnoreturn.h b/sw/device/lib/base/freestanding/stdnoreturn.h
new file mode 100644
index 0000000..925ac88
--- /dev/null
+++ b/sw/device/lib/base/freestanding/stdnoreturn.h
@@ -0,0 +1,15 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDNORETURN_H_
+#define OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDNORETURN_H_
+
+/**
+ * This header implements the stdnoreturn.h standard header, as required by C11
+ * S4p6. This header is specified in detail in S7.23 of the same.
+ */
+
+#define noreturn _Noreturn
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_BASE_FREESTANDING_STDNORETURN_H_
diff --git a/sw/device/lib/base/meson.build b/sw/device/lib/base/meson.build
index 0beab29..3c74044 100644
--- a/sw/device/lib/base/meson.build
+++ b/sw/device/lib/base/meson.build
@@ -2,6 +2,8 @@
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
 
+subdir('freestanding')
+
 # Memory Operations library (sw_lib_mem)
 sw_lib_mem = declare_dependency(
   link_with: static_library(
@@ -9,5 +11,4 @@
     sources: ['memory.c'],
     c_args: ['-fno-builtin'],
   )
-)
-
+)
\ No newline at end of file