m/node: build microcode payloads
This adds a builder for loadable microcode payloads for the Linux
kernel and microcode for Intel and AMD CPUs. It also adds a rule
generating a microcode payload for Metropolis at
//metropolis/node:ucode but does not integrate it yet.
Change-Id: I00145e4c983d9ff3e81881e92cbecc3e09392665
Reviewed-on: https://review.monogon.dev/c/monogon/+/546
Reviewed-by: Sergiusz Bazanski <serge@monogon.tech>
diff --git a/metropolis/node/build/mkucode/def.bzl b/metropolis/node/build/mkucode/def.bzl
new file mode 100644
index 0000000..3faa775
--- /dev/null
+++ b/metropolis/node/build/mkucode/def.bzl
@@ -0,0 +1,45 @@
+def _cpio_ucode_impl(ctx):
+ ucode_spec = ctx.actions.declare_file(ctx.label.name + "_spec.prototxt")
+
+ vendors = []
+ inputs = []
+ for label, vendor in ctx.attr.ucode.items():
+ files = label[DefaultInfo].files.to_list()
+ inputs += files
+ vendors.append(struct(id = vendor, file = [f.path for f in files]))
+
+ ctx.actions.write(ucode_spec, proto.encode_text(struct(vendor = vendors)))
+
+ output_file = ctx.actions.declare_file(ctx.label.name + ".cpio")
+ ctx.actions.run(
+ outputs = [output_file],
+ inputs = [ucode_spec] + inputs,
+ tools = [ctx.executable._mkucode],
+ executable = ctx.executable._mkucode,
+ arguments = ["-out", output_file.path, "-spec", ucode_spec.path],
+ )
+ return [DefaultInfo(files = depset([output_file]))]
+
+cpio_ucode = rule(
+ implementation = _cpio_ucode_impl,
+ doc = """
+ Builds a cpio archive with microcode for the Linux early microcode loader.
+ """,
+ attrs = {
+ "ucode": attr.label_keyed_string_dict(
+ mandatory = True,
+ allow_files = True,
+ doc = """
+ Dictionary of Labels to String. Each label is a list of microcode files and the string label
+ is the vendor ID corresponding to that microcode.
+ """,
+ ),
+
+ # Tool
+ "_mkucode": attr.label(
+ default = Label("//metropolis/node/build/mkucode"),
+ executable = True,
+ cfg = "exec",
+ ),
+ },
+)