[sw, tock] Generate Rust bindings to DIF headers

Uses the bindgen crate to generate a .rs file to mirror all headers in
sw/device/lib/dif.

Signed-off-by: Jon Flatley <jflat@google.com>
diff --git a/sw/device/tock/boards/opentitan/Cargo.lock b/sw/device/tock/boards/opentitan/Cargo.lock
index 6aea3d4..45fb17c 100644
--- a/sw/device/tock/boards/opentitan/Cargo.lock
+++ b/sw/device/tock/boards/opentitan/Cargo.lock
@@ -1,6 +1,65 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
 [[package]]
+name = "aho-corasick"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "ansi_term"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "bindgen"
+version = "0.53.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bb26d6a69a335b8cb0e7c7e9775cd5666611dc50a37177c3f2cedcfc040e8c8"
+dependencies = [
+ "bitflags",
+ "cexpr",
+ "cfg-if",
+ "clang-sys",
+ "clap",
+ "env_logger",
+ "lazy_static",
+ "lazycell",
+ "log",
+ "peeking_take_while",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash",
+ "shlex",
+ "which",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+
+[[package]]
 name = "capsules"
 version = "0.1.0"
 source = "git+https://github.com/tock/tock?rev=d37ef3d2#d37ef3d2df9957d5e52591e20d6e7839410f174d"
@@ -10,6 +69,53 @@
 ]
 
 [[package]]
+name = "cc"
+version = "1.0.52"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d"
+
+[[package]]
+name = "cexpr"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
+[[package]]
+name = "clang-sys"
+version = "0.29.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a"
+dependencies = [
+ "glob",
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "clap"
+version = "2.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
+dependencies = [
+ "ansi_term",
+ "atty",
+ "bitflags",
+ "strsim",
+ "textwrap",
+ "unicode-width",
+ "vec_map",
+]
+
+[[package]]
 name = "components"
 version = "0.1.0"
 source = "git+https://github.com/tock/tock?rev=d37ef3d2#d37ef3d2df9957d5e52591e20d6e7839410f174d"
@@ -19,9 +125,17 @@
 ]
 
 [[package]]
+name = "dif"
+version = "0.1.0"
+dependencies = [
+ "bindgen",
+]
+
+[[package]]
 name = "earlgrey"
 version = "0.1.0"
 dependencies = [
+ "dif",
  "opentitan_common",
  "tock",
 ]
@@ -32,6 +146,43 @@
 source = "git+https://github.com/tock/tock?rev=d37ef3d2#d37ef3d2df9957d5e52591e20d6e7839410f174d"
 
 [[package]]
+name = "env_logger"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "humantime"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
+dependencies = [
+ "quick-error",
+]
+
+[[package]]
 name = "kernel"
 version = "0.1.0"
 source = "git+https://github.com/tock/tock?rev=d37ef3d2#d37ef3d2df9957d5e52591e20d6e7839410f174d"
@@ -41,6 +192,59 @@
 ]
 
 [[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "lazycell"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
+
+[[package]]
+name = "libc"
+version = "0.2.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
+
+[[package]]
+name = "libloading"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
+dependencies = [
+ "cc",
+ "winapi",
+]
+
+[[package]]
+name = "log"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
+
+[[package]]
+name = "nom"
+version = "5.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6"
+dependencies = [
+ "memchr",
+ "version_check",
+]
+
+[[package]]
 name = "opentitan"
 version = "0.1.0"
 dependencies = [
@@ -56,6 +260,54 @@
 ]
 
 [[package]]
+name = "peeking_take_while"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
+[[package]]
+name = "quote"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "regex"
+version = "1.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+ "thread_local",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
+
+[[package]]
 name = "riscv-csr"
 version = "0.1.0"
 source = "git+https://github.com/tock/tock?rev=d37ef3d2#d37ef3d2df9957d5e52591e20d6e7839410f174d"
@@ -64,6 +316,12 @@
 ]
 
 [[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
 name = "rv32i"
 version = "0.1.0"
 source = "git+https://github.com/tock/tock?rev=d37ef3d2#d37ef3d2df9957d5e52591e20d6e7839410f174d"
@@ -75,6 +333,45 @@
 ]
 
 [[package]]
+name = "shlex"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
+
+[[package]]
+name = "strsim"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
+
+[[package]]
+name = "termcolor"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+dependencies = [
+ "unicode-width",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
 name = "tock"
 version = "0.1.0"
 dependencies = [
@@ -99,3 +396,67 @@
 name = "tock_rt0"
 version = "0.1.0"
 source = "git+https://github.com/tock/tock?rev=d37ef3d2#d37ef3d2df9957d5e52591e20d6e7839410f174d"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
+
+[[package]]
+name = "vec_map"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
+
+[[package]]
+name = "version_check"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
+
+[[package]]
+name = "which"
+version = "3.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/sw/device/tock/chips/earlgrey/Cargo.toml b/sw/device/tock/chips/earlgrey/Cargo.toml
index bcd1671..d907bfc 100644
--- a/sw/device/tock/chips/earlgrey/Cargo.toml
+++ b/sw/device/tock/chips/earlgrey/Cargo.toml
@@ -16,3 +16,4 @@
 [dependencies]
 opentitan_common = { path = "../opentitan_common" }
 tock = { path = "../../tock" }
+dif = { path = "../../dif" }
diff --git a/sw/device/tock/dif/Cargo.toml b/sw/device/tock/dif/Cargo.toml
new file mode 100644
index 0000000..a8c723f
--- /dev/null
+++ b/sw/device/tock/dif/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "dif"
+version = "0.1.0"
+authors = ["lowRISC contributors <info@lowrisc.org>"]
+build = "build.rs"
+
+[profile.dev]
+panic = "abort"
+lto = false
+opt-level = "z"
+debug = true
+
+[profile.release]
+panic = "abort"
+lto = true
+opt-level = "z"
+debug = true
+
+[build-dependencies]
+bindgen = { version = "0.53.1" }
diff --git a/sw/device/tock/dif/build.rs b/sw/device/tock/dif/build.rs
new file mode 100644
index 0000000..1305e47
--- /dev/null
+++ b/sw/device/tock/dif/build.rs
@@ -0,0 +1,78 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// This build script relies on a number of meson build system environment
+// variables:
+//    - MESON_SOURCE_ROOT:
+//      The full path to the source code top directory.
+//    - MESON_BUILD_ROOT:
+//      The full path to the build top directory.
+//    - OUT_DIR:
+//      The full path to the directory where the output(s) must be written.
+//
+// This script finds all C header files in specified directories by combining
+// `MESON_SOURCE_ROOT` with a relative path. It then generates rust bindings
+// for the found C header files, the generated file is stored in `OUT_DIR`.
+
+extern crate bindgen;
+
+use std::env;
+use std::fs;
+use std::path::Path;
+
+static DIF_RELATIVE_PATH: &str = "sw/device/lib/dif";
+
+fn main() {
+    let source_root = env::var("MESON_SOURCE_ROOT").expect("no MESON_SOURCE_ROOT env variable");
+
+    let build_root = env::var("MESON_BUILD_ROOT").expect("no MESON_BUILD_ROOT env variable");
+
+    let out_dir = env::var("OUT_DIR").expect("no OUT_DIR env variable");
+
+    generate_bindings(&source_root, &build_root, &out_dir);
+}
+
+fn generate_bindings(source_root: &str, build_root: &str, out_dir: &str) {
+    let mut binding_builder = bindgen::builder()
+        .raw_line("use riscv32_c_types;")
+        .ctypes_prefix("riscv32_c_types")
+        .clang_arg("--target=riscv32")
+        .clang_args(&["-I", source_root])
+        .clang_args(&["-I", build_root]);
+
+    let dif_path = Path::new(&source_root).join(DIF_RELATIVE_PATH);
+    let dif_build_meson = dif_path.join("meson.build");
+    let dif_build_meson = dif_build_meson
+        .to_str()
+        .expect("failed to create DIF meson.build path string");
+
+    println!("cargo:rerun-if-changed={}", dif_build_meson);
+
+    let dif_files = fs::read_dir(dif_path).expect("failed to create DIF directory path object");
+
+    // Find all of the DIF headers, and add them to the bindgen builder "state".
+    for file in dif_files {
+        let full_file_path = file.expect("file is not open").path();
+
+        if let Some(extension) = full_file_path.extension() {
+            let full_file_name = full_file_path
+                .to_str()
+                .expect("failed to get the full file name string");
+
+            if extension == "h" {
+                binding_builder = binding_builder.header(full_file_name);
+
+                // Rerun the generator script if DIFs headers change.
+                println!("cargo:rerun-if-changed={}", full_file_name);
+            }
+        }
+    }
+
+    let out_file = Path::new(&out_dir).join("ot_dif_bindings.rs");
+    binding_builder
+        .generate()
+        .expect("failed to generate the bindings")
+        .write_to_file(out_file)
+        .expect("failed to create the output file");
+}
diff --git a/sw/device/tock/dif/src/lib.rs b/sw/device/tock/dif/src/lib.rs
new file mode 100644
index 0000000..1b016c2
--- /dev/null
+++ b/sw/device/tock/dif/src/lib.rs
@@ -0,0 +1,16 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+//! Bindings for OpenTitan DIF libaries
+
+#![no_std]
+#![crate_name = "dif"]
+#![crate_type = "rlib"]
+
+#[allow(nonstandard_style)]
+pub mod dif_bind {
+    include!(concat!(env!("OUT_DIR"), "/ot_dif_bindings.rs"));
+}
+
+pub mod riscv32_c_types;
diff --git a/sw/device/tock/dif/src/riscv32_c_types.rs b/sw/device/tock/dif/src/riscv32_c_types.rs
new file mode 100644
index 0000000..34bfaab
--- /dev/null
+++ b/sw/device/tock/dif/src/riscv32_c_types.rs
@@ -0,0 +1,10 @@
+#[allow(nonstandard_style)]
+pub type c_int = i32;
+#[allow(nonstandard_style)]
+pub type c_uint = u32;
+#[allow(nonstandard_style)]
+pub type c_longlong = i64;
+#[allow(nonstandard_style)]
+pub type c_ulonglong = u64;
+
+pub use core::ffi::c_void;
diff --git a/sw/device/tock/meson.build b/sw/device/tock/meson.build
index 4948dea..2303135 100644
--- a/sw/device/tock/meson.build
+++ b/sw/device/tock/meson.build
@@ -38,6 +38,8 @@
     manifest_path,
     '@OUTDIR@',
     toolchain_file,
+    meson.source_root(),
+    meson.build_root(),
     rust_flags,
   ],
   output: target,
diff --git a/util/build_tock.sh b/util/build_tock.sh
index eabfe25..71908de 100755
--- a/util/build_tock.sh
+++ b/util/build_tock.sh
@@ -14,7 +14,9 @@
 MANIFEST_PATH="${3}"
 TARGET_DIR="${4}"
 TOOLCHAIN_FILE="${5}"
-export RUSTFLAGS="${6}"
+export MESON_SOURCE_ROOT="${6}"
+export MESON_BUILD_ROOT="${7}"
+export RUSTFLAGS="${8}"
 
 if [[ "${MODE}" == "release" ]]; then
 	RELEASE_FLAG="--release"