Base opentitantool application.

1. Establish the basic `opentitantool` framework.
2. Create a procedural macro for deriving `CommandDispatch` for interior
nodes in the command hierarchy.
3. Create some sample `hello` commands in `hello.rs`.

Signed-off-by: Chris Frantz <cfrantz@google.com>
diff --git a/sw/host/opentitanlib/Cargo.toml b/sw/host/opentitanlib/Cargo.toml
index 3309988..85b7870 100644
--- a/sw/host/opentitanlib/Cargo.toml
+++ b/sw/host/opentitanlib/Cargo.toml
@@ -15,3 +15,6 @@
 nix = "0.17.0"
 bitflags = "1.0"
 log = "0.4"
+
+erased-serde = "0.3.12"
+opentitantool_derive = {path = "opentitantool_derive"}
diff --git a/sw/host/opentitanlib/opentitantool_derive/Cargo.toml b/sw/host/opentitanlib/opentitantool_derive/Cargo.toml
new file mode 100644
index 0000000..39f5f9d
--- /dev/null
+++ b/sw/host/opentitanlib/opentitantool_derive/Cargo.toml
@@ -0,0 +1,18 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+[package]
+name = "opentitantool_derive"
+version = "0.1.0"
+authors = ["lowRISC contributors"]
+edition = "2018"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+proc-macro2 = "1.0"
+proc-macro-error = "1.0"
+quote = "1.0"
+syn = "1.0"
diff --git a/sw/host/opentitanlib/opentitantool_derive/src/lib.rs b/sw/host/opentitanlib/opentitantool_derive/src/lib.rs
new file mode 100644
index 0000000..3c000c6
--- /dev/null
+++ b/sw/host/opentitanlib/opentitantool_derive/src/lib.rs
@@ -0,0 +1,105 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+use proc_macro2::TokenStream;
+use proc_macro_error::{abort, proc_macro_error};
+use quote::quote;
+use syn::{parse_macro_input, Data, DataEnum, DeriveInput, Fields, Ident, Variant};
+
+/// Derives the `CommandDispatch` trait for a NewType enum.
+///
+/// Derive this on purely interior nodes in the opentitantool command hierarchy
+/// (that is: nodes whose only purpose is to dispatch down to the next layer
+/// in the command heirarchy).  The automatic derivation simply calls the
+/// `run` method on the next layer in the command hierarchy.
+///
+/// Imagine that you have structs `World` and `People` which implement
+/// "Hello World" and "Hello People" commands.  You would create Newtype
+/// variants inside of a `Hello` enum and derive `CommandDispatch` to
+/// generate the dispatch layer for this interior node in the command hierarchy:
+///
+/// ```
+/// #[derive(StructOpt, CommandDispatch)]
+/// pub enum Hello {
+///     World(World),
+///     People(People),
+/// }
+///
+/// // The derived code is as follows:
+/// impl opentitanlib::app::command::CommandDispatch for Hello {
+///     fn run(
+///         &self,
+///         backend: &mut dyn opentitanlib::transport::Transport
+///     ) -> anyhow::Result<Option<Box<dyn erased_serde::Serialize>>> {
+///         match self {
+///             Hello::World(ref __field) => __field.run(backend),
+///             Hello::People(ref __field) => __field.run(backend),
+///         }
+///     }
+/// }
+/// ```
+#[proc_macro_derive(CommandDispatch)]
+#[proc_macro_error]
+pub fn derive_command_dispatch(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+    let input = parse_macro_input!(input as DeriveInput);
+
+    match &input.data {
+        Data::Enum(e) => dispatch_enum(&input.ident, e).into(),
+        _ => abort!(
+            input.ident.span(),
+            "CommandDispatch is only implemented for enums"
+        ),
+    }
+}
+
+fn dispatch_enum(name: &Ident, e: &DataEnum) -> TokenStream {
+    let arms = e
+        .variants
+        .iter()
+        .map(|variant| dispatch_variant(name, variant))
+        .collect::<Vec<_>>();
+
+    // We wrap the derived code inside an anonymous const block to give the
+    // `extern crate` references a local namespace that wont pollute the
+    // global namespace.
+    quote! {
+        const _: () = {
+            extern crate opentitanlib;
+            extern crate anyhow;
+            extern crate erased_serde;
+
+            impl opentitanlib::app::command::CommandDispatch for #name {
+                fn run(
+                    &self,
+                    backend: &mut dyn opentitanlib::transport::Transport
+                ) -> anyhow::Result<Option<Box<dyn erased_serde::Serialize>>> {
+                    match self {
+                        #(#arms),*
+                    }
+                }
+            }
+        };
+    }
+}
+
+fn dispatch_variant(name: &Ident, variant: &Variant) -> TokenStream {
+    let ident = &variant.ident;
+    let unnamed_len = match &variant.fields {
+        Fields::Unnamed(u) => u.unnamed.len(),
+        _ => abort!(
+            variant.ident.span(),
+            "CommandDispatch is only implemented for Newtype variants"
+        ),
+    };
+    if unnamed_len != 1 {
+        abort!(
+            variant.ident.span(),
+            "CommandDispatch is only implemented for Newtype variants"
+        );
+    }
+    quote! {
+        #name::#ident(ref __field) =>
+            opentitanlib::app::command::CommandDispatch::run(__field, backend)
+    }
+}
diff --git a/sw/host/opentitanlib/src/app/command.rs b/sw/host/opentitanlib/src/app/command.rs
new file mode 100644
index 0000000..b275cce
--- /dev/null
+++ b/sw/host/opentitanlib/src/app/command.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
+
+use crate::transport::Transport;
+use anyhow::Result;
+use erased_serde::Serialize;
+pub use opentitantool_derive::*;
+
+/// The `CommandDispatch` trait should be implemented for all leaf structures
+/// in the application's command hierarchy.  It can be automatically derived
+/// on internal nodes in the heirarchy.  See the documentation for
+/// [`opentitantool_derive`].
+pub trait CommandDispatch {
+    fn run(&self, transport: &mut dyn Transport) -> Result<Option<Box<dyn Serialize>>>;
+}
diff --git a/sw/host/opentitanlib/src/app/mod.rs b/sw/host/opentitanlib/src/app/mod.rs
new file mode 100644
index 0000000..a371aaa
--- /dev/null
+++ b/sw/host/opentitanlib/src/app/mod.rs
@@ -0,0 +1,6 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+//! Useful modules for OpenTitanTool application development.
+pub mod command;
diff --git a/sw/host/opentitanlib/src/lib.rs b/sw/host/opentitanlib/src/lib.rs
index 3825007..ab50890 100644
--- a/sw/host/opentitanlib/src/lib.rs
+++ b/sw/host/opentitanlib/src/lib.rs
@@ -2,6 +2,7 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
+pub mod app;
 pub mod io;
 pub mod transport;
 pub mod util;
diff --git a/sw/host/opentitantool/Cargo.toml b/sw/host/opentitantool/Cargo.toml
new file mode 100644
index 0000000..7345c24
--- /dev/null
+++ b/sw/host/opentitantool/Cargo.toml
@@ -0,0 +1,24 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+[package]
+name = "opentitantool"
+version = "0.1.0"
+authors = ["lowRISC contributors"]
+edition = "2018"
+
+[dependencies]
+anyhow = "1.0"
+thiserror = "1.0"
+opentitanlib = {path="../opentitanlib"}
+structopt = "0.3"
+log = "0.4"
+env_logger = "0.8.3"
+raw_tty = "0.1.0"
+regex = "1"
+nix = "0.17.0"
+
+serde = {version="1", features=["serde_derive"]}
+serde_json = "1"
+erased-serde = "0.3.12"
diff --git a/sw/host/opentitantool/src/backend/mod.rs b/sw/host/opentitantool/src/backend/mod.rs
new file mode 100644
index 0000000..544be3c
--- /dev/null
+++ b/sw/host/opentitantool/src/backend/mod.rs
@@ -0,0 +1,29 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+use anyhow::Result;
+use structopt::StructOpt;
+use thiserror::Error;
+
+use opentitanlib::transport::{EmptyTransport, Transport};
+
+#[derive(Debug, StructOpt)]
+pub struct BackendOpts {
+    #[structopt(long, default_value)]
+    interface: String,
+}
+
+#[derive(Error, Debug)]
+pub enum Error {
+    #[error("unknown interface {0}")]
+    UnknownInterface(String),
+}
+
+/// Creates the requested backend interface according to [`BackendOpts`].
+pub fn create(args: &BackendOpts) -> Result<Box<dyn Transport>> {
+    match args.interface.as_str() {
+        "" => Ok(Box::new(EmptyTransport)),
+        _ => Err(Error::UnknownInterface(args.interface.clone()).into()),
+    }
+}
diff --git a/sw/host/opentitantool/src/command/hello.rs b/sw/host/opentitantool/src/command/hello.rs
new file mode 100644
index 0000000..4df9860
--- /dev/null
+++ b/sw/host/opentitantool/src/command/hello.rs
@@ -0,0 +1,92 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+//! Sample command heirarchy.
+//!
+//! This module implements a sample command heirarchy to demonstrate
+//! the command framework for opentitantool.
+
+use anyhow::Result;
+use erased_serde::Serialize;
+use structopt::StructOpt;
+
+use opentitanlib::app::command::CommandDispatch;
+use opentitanlib::transport::Transport;
+
+#[derive(Debug, StructOpt)]
+/// The `hello world` command accepts an command option of `--cruel`.
+pub struct HelloWorld {
+    #[structopt(short, long)]
+    cruel: bool,
+}
+
+#[derive(serde::Serialize)]
+/// The [`HelloMessage`] is the result of the `hello world` command.
+pub struct HelloMessage {
+    pub greeting: String,
+}
+
+impl CommandDispatch for HelloWorld {
+    fn run(&self, _transport: &mut dyn Transport) -> Result<Option<Box<dyn Serialize>>> {
+        // Is the world cruel or not?
+        let msg = if self.cruel {
+            "Hello cruel World!"
+        } else {
+            "Hello World!"
+        };
+        Ok(Some(Box::new(HelloMessage {
+            greeting: msg.to_owned(),
+        })))
+    }
+}
+
+#[derive(Debug, StructOpt)]
+/// The `hello people` command takes no additional switches or arguments.
+pub struct HelloPeople {
+    // Unit structs not allowed by StructOpt
+}
+
+impl CommandDispatch for HelloPeople {
+    fn run(&self, _transport: &mut dyn Transport) -> Result<Option<Box<dyn Serialize>>> {
+        // The `hello people` command produces no result.
+        Ok(None)
+    }
+}
+
+#[derive(Debug, StructOpt, CommandDispatch)]
+/// There are two types of `hello` subcommand; this enum binds them together
+/// so they can both be under the `hello` command.  This enum also derives
+/// `CommandDispatch` which automatically builds a `run` method for this
+/// type which dispatches to the subcommands.
+pub enum HelloTypes {
+    World(HelloWorld),
+    People(HelloPeople),
+}
+
+#[derive(Debug, StructOpt)]
+/// The `goodbye` command takes no options or arguments.
+pub struct GoodbyeCommand {}
+
+#[derive(serde::Serialize)]
+/// The [`GoodbyeMessage`] is the result of the `goodbye` command.
+pub struct GoodbyeMessage {
+    pub message: String,
+}
+
+impl CommandDispatch for GoodbyeCommand {
+    fn run(&self, _transport: &mut dyn Transport) -> Result<Option<Box<dyn Serialize>>> {
+        Ok(Some(Box::new(GoodbyeMessage {
+            message: "Goodbye!".to_owned(),
+        })))
+    }
+}
+
+#[derive(Debug, StructOpt, CommandDispatch)]
+/// The [`Greetings`] enum binds the `hello` and `goodbye` command hirarchies
+/// in this module together into a single type which can be included into
+/// the root of the command heirarchy in `main.rs`.
+pub enum Greetings {
+    Hello(HelloTypes),
+    Goodbye(GoodbyeCommand),
+}
diff --git a/sw/host/opentitantool/src/command/mod.rs b/sw/host/opentitantool/src/command/mod.rs
new file mode 100644
index 0000000..950ba35
--- /dev/null
+++ b/sw/host/opentitantool/src/command/mod.rs
@@ -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
+
+pub mod hello;
diff --git a/sw/host/opentitantool/src/main.rs b/sw/host/opentitantool/src/main.rs
new file mode 100644
index 0000000..3dbbb2b
--- /dev/null
+++ b/sw/host/opentitantool/src/main.rs
@@ -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
+
+use anyhow::Result;
+use log::LevelFilter;
+use structopt::StructOpt;
+
+mod backend;
+mod command;
+use opentitanlib::app::command::CommandDispatch;
+
+#[derive(Debug, StructOpt, CommandDispatch)]
+enum RootCommandHierarchy {
+    // Flattened because `Greetings` is a subcommand hierarchy.
+    #[structopt(flatten)]
+    Greetings(command::hello::Greetings),
+}
+
+#[derive(Debug, StructOpt)]
+struct Opts {
+    #[structopt(long, default_value = "off")]
+    logging: LevelFilter,
+
+    #[structopt(flatten)]
+    backend_opts: backend::BackendOpts,
+
+    #[structopt(subcommand)]
+    command: RootCommandHierarchy,
+}
+
+fn main() -> Result<()> {
+    let opts = Opts::from_args();
+    env_logger::Builder::from_default_env()
+        .filter(None, opts.logging)
+        .init();
+
+    let mut interface = backend::create(&opts.backend_opts)?;
+
+    if let Some(value) = opts.command.run(&mut *interface)? {
+        println!("{}", serde_json::to_string_pretty(&value)?);
+    }
+    Ok(())
+}