[sw, style] Replace LLVM-style X macro guidance

The new guidance is consistent with the far more common practice
throughout the project; we also eliminate the sole LLVM-style X macro.

Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
diff --git a/doc/rm/c_cpp_coding_style.md b/doc/rm/c_cpp_coding_style.md
index 4f1af11..22c076e 100644
--- a/doc/rm/c_cpp_coding_style.md
+++ b/doc/rm/c_cpp_coding_style.md
@@ -198,16 +198,21 @@
 
 ### X Macros
 
-In order to avoid repetitive definitions or statements, we allow the use of [X Macros](https://en.wikipedia.org/wiki/X_Macro) in our C and C++ code.
+In order to avoid repetitive definitions or statements, we allow the use of [X macros](https://en.wikipedia.org/wiki/X_Macro) in our C and C++ code.
 
 Uses of X Macros should follow the following example, which uses this pattern in a switch definition:
 ```c
+#define MANY_FIELDS(X) \
+  X(1, 2, 3)           \
+  X(4, 5, 6)
+
 int get_field2(int identifier) {
+#define ITEM_(id_field, data_field1, data_field2) \
+  case id_field:                               \
+    return data_field2;
+
   switch (identifier) {
-#define ITEM(id_field, data_field1, data_field2) \
-    case id_field:                               \
-      return data_field2;
-#include "path/to/item.def"
+    MANY_FIELDS(ITEM_)
     default:
       return 0;
   }
@@ -215,49 +220,9 @@
 ```
 This example expands to a case statement for each item, which returns the `data_field2` value where the passed in identifier matches `id_field`.
 
-The contents of the X Macro file from this example ("path/to/item.def") should look like:
-```c
-
-/**
- * \def ITEM(id_field, data_field1, data_field2)
- *
- * <Documentation about meaning of ITEM fields>
- */
-#ifndef ITEM
-#error ITEM(id_field, data_field1, data_field2) must be defined
-#endif
-
-ITEM(fields...)
-ITEM(fields...)
-
-#undef ITEM
-```
-
-These X Macro files must:
-
-*   Have the extension `.def`.
-    The file's basename should match the X Macro name.
-    This is so we can easily identify that this is an X Macro, which will be used by the preprocessor, and is required at compile-time.
-*   Document the X Macro and the meaning of its fields.
-*   Error if the X Macro is not defined.
-*   Include a sequence of X Macro uses, one per line, omitting following semicolons.
-    Omitting semicolons allows X Macros to be used in either expression or statement position, which is useful.
-*   Undefine the X Macro name at the end of the file.
-
-X Macro field values should be valid C constant literals.
-The first field of an X Macro should be the primary identifier, as shown in the example.
-
-X Macros should be kept as simple as possible.
-X Macro files should endeavour to only define one kind of X Macro, and separate files should be used for other X Macros.
-If possible, X Macros should only be used in implementation files, and should be avoided in headers.
-
-The code using an X Macro must:
-
-*   Define the X Macro name, including any separators (such as semicolons or commas) within the definition.
-    It is usually clearer if you split the definition over multiple lines.
-*   Immediately after the definition, include the `.def` file for the X Macro.
-
-
+X macros that are not part of a header's API should be `#undef`ed after they are not needed.
+Similarly, the arguments to an X macro, if they are defined in a header, should be `#undef`ed too.
+This is not necessary in a `.c` or `.cc` file, where this cannot cause downstream namespace pollution.
 
 ## C++ Style Guide {#cxx-style-guide}
 
diff --git a/sw/device/lib/runtime/BUILD b/sw/device/lib/runtime/BUILD
index 635f41a..c0aad80 100644
--- a/sw/device/lib/runtime/BUILD
+++ b/sw/device/lib/runtime/BUILD
@@ -71,11 +71,11 @@
     srcs = ["pmp.c"],
     hdrs = ["pmp.h"],
     target_compatible_with = [OPENTITAN_CPU],
-    textual_hdrs = ["pmp_regions.def"],
     deps = [
         "//sw/device/lib/base:bitfield",
         "//sw/device/lib/base:csr",
         "//sw/device/lib/base:macros",
+        "//sw/device/lib/base/freestanding",
     ],
 )
 
diff --git a/sw/device/lib/runtime/pmp.c b/sw/device/lib/runtime/pmp.c
index 2749f7c..e83afa0 100644
--- a/sw/device/lib/runtime/pmp.c
+++ b/sw/device/lib/runtime/pmp.c
@@ -43,6 +43,39 @@
 };
 
 /**
+ * This is an X-Macro used for automatically deriving switch statements which
+ * link PMP region identifiers to associated information including their
+ * configuration register identifier.
+ *
+ * This macro should be invoked with a macro argument with the following
+ * signature:
+ *
+ * @param region_id PMP Region Identifier.
+ * @param config_reg_id Configuration Register ID for a given PMP Region (for
+ * Ibex).
+ */
+#define PMP_REGIONS(X) \
+  X(0, 0)              \
+  X(1, 0)              \
+  X(2, 0)              \
+  X(3, 0)              \
+                       \
+  X(4, 1)              \
+  X(5, 1)              \
+  X(6, 1)              \
+  X(7, 1)              \
+                       \
+  X(8, 2)              \
+  X(9, 2)              \
+  X(10, 2)             \
+  X(11, 2)             \
+                       \
+  X(12, 3)             \
+  X(13, 3)             \
+  X(14, 3)             \
+  X(15, 3)
+
+/**
  * Reads the pmpcfg for a given region.
  *
  * This reads the entire `pmpcfgN` value, not just the word associated with the
@@ -55,13 +88,14 @@
  */
 OT_WARN_UNUSED_RESULT
 static bool pmp_cfg_csr_read(pmp_region_index_t region, uint32_t *value) {
-  switch (region) {
-#define PMP_REGION(region_id, config_reg_id)        \
+#define PMP_READ_CONFIG_(region_id, config_reg_id)  \
   case region_id: {                                 \
     CSR_READ(CSR_REG_PMPCFG##config_reg_id, value); \
     return true;                                    \
   }
-#include "sw/device/lib/runtime/pmp_regions.def"
+
+  switch (region) {
+    PMP_REGIONS(PMP_READ_CONFIG_)
     default:
       return false;
   }
@@ -80,13 +114,14 @@
  */
 OT_WARN_UNUSED_RESULT
 static bool pmp_cfg_csr_write(pmp_region_index_t region, uint32_t value) {
-  switch (region) {
-#define PMP_REGION(region_id, config_reg_id)         \
+#define PMP_WRITE_CONFIG_(region_id, config_reg_id)  \
   case region_id: {                                  \
     CSR_WRITE(CSR_REG_PMPCFG##config_reg_id, value); \
     return true;                                     \
   }
-#include "sw/device/lib/runtime/pmp_regions.def"
+
+  switch (region) {
+    PMP_REGIONS(PMP_WRITE_CONFIG_)
     default:
       return false;
   }
@@ -102,13 +137,14 @@
  */
 OT_WARN_UNUSED_RESULT
 static bool pmp_addr_csr_read(pmp_region_index_t region, uint32_t *value) {
-  switch (region) {
-#define PMP_REGION(region_id, _)                 \
+#define PMP_READ_ADDR_(region_id, _)             \
   case region_id: {                              \
     CSR_READ(CSR_REG_PMPADDR##region_id, value); \
     return true;                                 \
   }
-#include "sw/device/lib/runtime/pmp_regions.def"
+
+  switch (region) {
+    PMP_REGIONS(PMP_READ_ADDR_)
     default:
       return false;
   }
@@ -123,13 +159,14 @@
  */
 OT_WARN_UNUSED_RESULT
 static bool pmp_addr_csr_write(pmp_region_index_t region, uint32_t value) {
-  switch (region) {
-#define PMP_REGION(region_id, _)                  \
+#define PMP_WRITE_ADDR_(region_id, _)             \
   case region_id: {                               \
     CSR_WRITE(CSR_REG_PMPADDR##region_id, value); \
     return true;                                  \
   }
-#include "sw/device/lib/runtime/pmp_regions.def"
+
+  switch (region) {
+    PMP_REGIONS(PMP_WRITE_ADDR_)
     default:
       return false;
   }
diff --git a/sw/device/lib/runtime/pmp_regions.def b/sw/device/lib/runtime/pmp_regions.def
deleted file mode 100644
index 5bf8680..0000000
--- a/sw/device/lib/runtime/pmp_regions.def
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-/**
- * \def PMP_REGION(region_id, config_reg_id)
- *
- * This is an X-Macro used for automatically deriving switch statements which
- * link PMP region identifiers to associated information including their
- * configuration register identifier.
- *
- * This also acts as the definitive list of every single PMP region that is
- * supported by `sw/device/lib/runtime/pmp.h`.
- *
- * This macro will be invoked without a following semicolon or comma.
- *
- * The macro will be undef'd at the end of this file, so this file may be
- * included multiple times in the same implementation file. Each inclusion site
- * should define `PMP_REGION` as required before including this file.
- *
- * @param region_id PMP Region Identifier.
- * @param config_reg_id Configuration Register ID for a given PMP Region (for
- * Ibex).
- */
-#ifndef PMP_REGION
-#error PMP_REGION(region_id, config_reg_id) must be defined
-#endif  // PMP_REGION
-
-PMP_REGION(0, 0)
-PMP_REGION(1, 0)
-PMP_REGION(2, 0)
-PMP_REGION(3, 0)
-
-PMP_REGION(4, 1)
-PMP_REGION(5, 1)
-PMP_REGION(6, 1)
-PMP_REGION(7, 1)
-
-PMP_REGION(8, 2)
-PMP_REGION(9, 2)
-PMP_REGION(10, 2)
-PMP_REGION(11, 2)
-
-PMP_REGION(12, 3)
-PMP_REGION(13, 3)
-PMP_REGION(14, 3)
-PMP_REGION(15, 3)
-
-#undef PMP_REGION