Add style guide.
Change-Id: Ic2517e3ae6187b88f991787f5a3ef72fef7c3f87
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9b6df60..579b8ad 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,6 +15,10 @@
(even if it was for a different project), you probably don't need to do it
again.
+## Style guide
+
+Submissions should follow the Hafnium [style guide](docs/StyleGuide.md).
+
## Code reviews
All submissions, including submissions by project members, require review. We
diff --git a/README.md b/README.md
index f0d266d..de88c0f 100644
--- a/README.md
+++ b/README.md
@@ -22,3 +22,4 @@
* [How to build a RAM disk containing VMs for Hafnium to run](docs/HafniumRamDisk.md)
* [Building Hafnium hermetically with Docker](docs/HermeticBuild.md)
* [The interface Hafnium provides to VMs](docs/VmInterface.md)
+* [Hafnium coding style](docs/StyleGuide.md)
diff --git a/docs/StyleGuide.md b/docs/StyleGuide.md
new file mode 100644
index 0000000..9422df8
--- /dev/null
+++ b/docs/StyleGuide.md
@@ -0,0 +1,81 @@
+# Style guide
+
+Hafnium's coding style has been based on the
+[Linux style](https://www.kernel.org/doc/html/v4.17/process/coding-style.html)
+with explicit modifications:
+
+* Always use braces for conditionals and loops. (No SSL `goto fail;`, thanks.)
+
+Following this, we generally fall back to the subset of the
+[Google C++ style guide](https://google.github.io/styleguide/cppguide.html) that
+is applicable to C.
+
+We try to automate this where possible with clang-format and clang-tidy but that
+doesn't capture everything we'd like today. Where the style enforced by this
+tooling conflicts with what is in this document we accept what the tooling
+requires, and try to improve it if possible.
+
+## Clarifications
+
+* Yes, it does mean all variables are declared, C90-style, at the top of
+ scope, even those loop induction variables.
+* Linux encourages no braces around single-statement branches. We follow
+ Google and require braces around all scope blocks.
+
+## Naming symbols
+
+* Arch-specific functions should start with `arch_`.
+* Platform-specific functions should start with `plat_`.
+* Non-static functions should generally start with the same of the file they
+ are declared in (after the `arch_` or `plat_` prefix if appropriate), though
+ there are quite a few exceptions to this rule.
+* Prefer `x_count` over `num_x`.
+
+## Prose
+
+These rules apply to comments and other natural language text.
+
+* Capitalize acronyms.
+ * CPU, vCPU, VM, EL2, SPCI, QEMU
+* Spell out Hafnium in full, not Hf.
+* Use single spaces.
+* Sentences end with full stops.
+* If the comment fits on one line use `/* */`, otherwise space it out:
+
+ ```
+ /*
+ * Informative long comment
+ * with extra information.
+ */
+ ```
+
+* Doc-ish comments start with `/**`.
+
+ * Use for:
+ * Function definitions (not declarations)
+ * Struct declarations
+ * Enum values
+ * Do not use for:
+ * Macros
+ * Definitions of globals
+
+* References to code symbols use backticks, e.g. `` `my_symbol` ``.
+
+## Coding practices
+
+* Function macros should be functions instead, that way you get types.
+* Lock ordering is described at the top of *api.c*.
+* Use opaque types to avoid implicit casts when it will help avoid mistakes.
+ e.g. *addr.h*
+* Avoid inline casting. C doesn't give much protection so be formal about the
+ transformations. e.g. *addr.h*
+* If a function acquires a resource, there must be a single exit path to free
+ the resource. Tracking down multiple exit points is hard and requires
+ duplicated code which is harder. This may require splitting functions into
+ subfunctions. Early exit is okay if there aren't any clean up tasks.
+* Don't use function pointers. It makes analysis hard and is often a target of
+ attacks.
+* Be liberal with CHECK. Use it to assert pre-/post- conditions.
+* No self-modifying code.
+* Build targets should include all the direct dependencies for their sources,
+ where possible, rather than relying on transitive dependencies.