-------------------------------------------------
AMD Microcode Container File format
-------------------------------------------------
Author:
  Aravind [dot] Gopalakrishnan [at] amd [dot] com
Initial version:
  July 2014
Updated:
  October 2014
-------------------------------------------------

Intro to AMD Container Files:
-----------------------------

* AMD provides microcode patch support for processors belonging to AMD
  processor families 10h, 11h, 12h, 14h, and 15h.
* There is one single file (container file) containing all microcode patches
  for AMD families 10h - 14h processors. [microcode_amd.bin]
* For AMD family 15h processors there is a separate container file. [microcode_amd_fam15h.bin]
* Microcode patches are not incremental, therefore you only need to make
  sure you have the latest container file for your AMD processor family.
* One can find the latest AMD microcode containers from [1], [2]

Mutual Exclusivity Rule of AMD containers:
* The patches for families 10h - 14h are guaranteed to be only on
  microcode_amd.bin
* Similarly, patches for family 15h will only be on microcode_amd_fam15h.bin
* This is because, the processes and scripts used to create container files
  ensure that there is no mix-up

Microcode patch header structure:
---------------------------------
struct __packed microcode_header_amd {
    uint32_t data_code;
    uint32_t patch_id;
    uint8_t  mc_patch_data_id[2];
    uint8_t  mc_patch_data_len;
    uint8_t  init_flag;
    uint32_t mc_patch_data_checksum;
    uint32_t nb_dev_id;
    uint32_t sb_dev_id;
    uint16_t processor_rev_id;
    uint8_t  nb_rev_id;
    uint8_t  sb_rev_id;
    uint8_t  bios_api_rev;
    uint8_t  reserved1[3];
    uint32_t match_reg[8];
}
More details about microcode patch header are typically not exposed to public.

Apply microcode updates using initrd:
-------------------------------------
Initrd images can be modified to contain AMD microcode containers in cpio
format at the start of the image.

Following example shows how to generate a combined initrd
Note: initrd-<val> could be different on your machine. Substitute accordingly
Example System base: Ubuntu 13.04 with 3.8.0-30-generic kernel

1.  mkdir initrd-for-xen-with_append
2.  cd initrd-for-xen-with_append
3.  mkdir -p kernel/x86/microcode
4.  cp /lib/firmware/amd-ucode/microcode_amd.bin .
5.  cp /lib/firmware/amd-ucode/microcode_amd_fam15h.bin .
6.  cat microcode_amd.bin microcode_amd_fam15h.bin > microcode_concatenated.bin
7.  mv microcode_concatenated.bin kernel/x86/microcode/AuthenticAMD.bin
8.  rm microcode_amd.bin microcode_amd_fam15h.bin
9.  find . | cpio -o -H newc > ucode.cpio
10.  cp /boot/initrd.img-3.8.0-30-generic .
11. cat ucode.cpio initrd.img-3.8.0-30-generic > initrd_for_xen_with_ucode
12. cp initrd_for_xen_with_ucode /boot/
13. On grub.cfg, provide the above initrd name as module.
14. Use 'ucode=scan' option as Xen boot parameter.

Misc Notes:
-----------
It is not recommended to concatenate two(or more) container files of
the same kind. (two microcode_amd_fam15h.bin for example)
This is because:
There is no check in Xen currently to verify this.
Now, given a situation where
1. An earlier container has a patch that 'fits' the processor you are
   currently on,
2. There is a subsequent container that *also* has a patch that 'fits',
3. The second patch happens to be an update over the patch found on the
   first container file.

In such a case, only the patch from the first container is applied.
This is because Xen assumes that the the containers (if concatenated
together) are different kinds AND the 'Mutual Exclusivity' rule is
always true.

In cases where users are not sure about provenance of containers 
they should obtain a "good" set  by downloading them from source links
[1], [2] since it's not guaranteed that the latest patch will be applied.

Reference(s):
-------------
[1] http://www.amd64.org/microcode.html 
[2] https://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/tree/amd-ucode 
[3] http://lxr.free-electrons.com/source/Documentation/x86/early-microcode.txt 
