From 42839a2200d8a242bfc9b9de693dd41b96f61274 Mon Sep 17 00:00:00 2001
From: Iru Cai <mytbk920423@gmail.com>
Date: Fri, 18 May 2018 00:14:29 +0800
Subject: New slides for the talk at LCPU

---
 coreboot-talk.tex | 471 ++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 401 insertions(+), 70 deletions(-)

(limited to 'coreboot-talk.tex')

diff --git a/coreboot-talk.tex b/coreboot-talk.tex
index 5d1f203..9aef87a 100644
--- a/coreboot-talk.tex
+++ b/coreboot-talk.tex
@@ -14,8 +14,8 @@
 
 \title{coreboot - the free firmware}
 \author[vimacs]{vimacs \texttt{<https://vimacs.lcpu.club>}}
-\institute[BLUG]{Beijing GNU/Linux User Group}
-\date{June 13th, 2017}
+\institute[LCPU]{Linux Club of Peking University}
+\date{May 19th, 2018}
 \begin{document}
 
 \begin{frame}
@@ -25,11 +25,18 @@
 \begin{frame}{License}
   This work is licensed under the Creative Commons Attribution 4.0
   International License. To view a copy of this license, visit
-  \url{http://creativecommons.org/licenses/by/4.0/}.
+  \url{http://creativecommons.org/licenses/by/4.0/}. \\~\\
+
+  You can find the source code of this presentation at:
+  \url{https://git.wehack.space/coreboot-talk/}
 \end{frame}
 
 \begin{frame}{Index}
-\tableofcontents[part=1]
+  \tableofcontents[part=1]
+\end{frame}
+
+\begin{frame}{Index}
+  \tableofcontents[part=2]
 \end{frame}
 
 \part{1}
@@ -44,14 +51,14 @@
   systems. As an Open Source project it provides auditability and
   maximum control over technology.
 
-  \emph{The word 'coreboot' should always be written in lowercase,
-    even at the start of a sentence.  }
+  \textbf{The word 'coreboot' should always be written in lowercase,
+    even at the start of a sentence.}
 \end{frame}
 
 \subsection{History}
 
 \begin{frame}{History: from LinuxBIOS to coreboot}
-  coreboot has a very long history, stretching back more than 15 years
+  coreboot has a very long history, stretching back more than 18 years
   to when it was known as LinuxBIOS. While the project has gone
   through lots of changes over the years, many of the earliest
   developers still contribute today.
@@ -153,7 +160,22 @@
   \end{itemize}
 \end{frame}
 
-\begin{frame}{About libreboot}
+\subsection{Why use coreboot}
+\begin{frame}[fragile]{Why use coreboot}
+
+  You can see the advantages of coreboot at:
+  \url{https://www.coreboot.org/users.html}
+
+  \begin{itemize}
+  \item coreboot is free software (see
+    \href{https://www.fsf.org/campaigns/priority-projects/priority-projects/highpriorityprojects#Coreboot}{FSF
+      Free BIOS Campaign})
+  \item fast boot times
+  \item it's flexible
+  \end{itemize}
+\end{frame}
+
+\begin{frame}{libreboot and firmware freedom}
   Some firmware components are non-free:
   \begin{itemize}
   \item Intel ME firmware/AMD PSP
@@ -168,24 +190,47 @@
   the EC firmware is also free(Chromium EC in Chromebooks).
 \end{frame}
 
-\subsection{Why use coreboot}
-\begin{frame}[fragile]{Why use coreboot}
+\begin{frame}[fragile]{me\_cleaner}
+  ME firmware can be neutralized:
+  \begin{itemize}
+  \item ME firmware partitions are individually signed, we can remove
+    all the partitions except FTPR.
+  \item In each partition, the manifests of the modules are signed,
+    but the modules are only checked before being executed, so the
+    modules that don't need to be executed can be removed.
+  \end{itemize}
 
-  You can see the advantages of coreboot at:
-  \url{https://www.coreboot.org/users.html}
+  For more information, read the me\_cleaner wiki at \url{https://github.com/corna/me_cleaner/wiki/How-does-it-work%3F}.
+\end{frame}
+
+\begin{frame}{LinuxBoot}
+  LinuxBoot (\url{https://www.linuxboot.org}) is a firmware for modern
+  servers that replaces specific firmware functionality like the UEFI
+  DXE phase with a Linux kernel and runtime.
+
+  \begin{figure}[htbp]
+    \centering
+    \includegraphics[scale=0.4]{images/pi.png}
+  \end{figure}
+\end{frame}
+
+\begin{frame}{UEFI v.s. NERF}
+  NERF is LinuxBoot with u-root as the initramfs. u-root contains boot
+  policy tools in Go (e.g. PXE booting, booting via GRUB config) among
+  standard busybox-like utilities rewritten in Go.
 
   \begin{itemize}
-  \item coreboot is free software (see
-    \href{https://www.fsf.org/campaigns/priority-projects/priority-projects/highpriorityprojects#Coreboot}{FSF
-      Free BIOS Campaign})
-  \item fast boot times
-  \item it's flexible
+  \item UEFI = Unified Extensible Firmware Interface
+  \item NERF = Non-Extensible Reduced Firmware
   \end{itemize}
 \end{frame}
 
-\begin{frame}{Fun stuff on BIOS}
+\begin{frame}[fragile]
   \begin{itemize}
-  \item \url{https://www.coreboot.org/Fun_Stuff}
+  \item Fun stuff: \url{https://www.coreboot.org/Fun_Stuff}
+  \item BIOS malware: \url{https://news.ycombinator.com/item?id=10039870}
+  \item \vcmd|rm -rf /sys/firmware/efi/efivars| can brick a system
+  \item SMM Vulnerabilities in firmware
   \end{itemize}
 \end{frame}
 
@@ -193,7 +238,7 @@
 
 \frame{\tableofcontents[currentsection]}
 
-\begin{frame}{How coreboot works}
+\begin{frame}[fragile]{How coreboot works}
 %On Intel x86 architecture, the first instruction is at 0xFFFFFFF0.
 %src/cpu/x86/16bit/reset16.inc
 %_start16bit(entry16.inc): enter protected mode
@@ -203,8 +248,11 @@
   We'll take lenovo/x230 as example to see how a machine boots with
   coreboot.
 
-  We can build coreboot with ``\texttt{make V=1 > build.log}`` to see which
+  We can build coreboot with \vcmd|make V=1 > build.log| to see which
   files are used to build coreboot for this mainboard.
+
+  All the source code is in the \vcmd|src/| directory, we'll omit it
+  in the following slides.
 \end{frame}
 
 \begin{frame}{coreboot stages}
@@ -219,42 +267,46 @@
   \end{itemize}
 \end{frame}
 
-\begin{frame}{bootblock}
+\begin{frame}[fragile]{bootblock}
   When the machine starts, PC poionts at reset vector (f000:fff0), the
   CPU runs the bootblock code.
 
-  The bootblock code is in src/arch/x86/bootblock\_romcc.S, which
-  includes:
+  The bootblock code is in \vcmd|arch/x86/bootblock_romcc.S|,
+  which includes:
   \begin{itemize}
-    \item src/cpu/x86/16bit/reset16.inc: the code at reset vector
-    \item src/cpu/x86/16bit/entry16.inc: the 16-bit code that sets CPU to protected mode
-    \item src/cpu/x86/32bit/entry32.inc: sets segment registers
-    \item generated/bootblock.inc: generated from src/arch/x86/bootblock\_simple.c with ROMCC
+    \item cpu/x86/16bit/reset16.inc: the code at reset vector
+    \item cpu/x86/16bit/entry16.inc: the 16-bit code that sets CPU to protected mode
+    \item cpu/x86/32bit/entry32.inc: sets segment registers
+    \item generated/bootblock.inc: generated by ROMCC from
+      \vcmd|arch/x86/bootblock_simple.c|, which then runs romstage
   \end{itemize}
-
-  bootblock\_simple.c then runs romstage.
 \end{frame}
 
-\begin{frame}{romstage}
-  romstage starts at src/arch/x86/assembly\_entry.S, which includes:
+\begin{frame}[fragile]{romstage}
+  romstage starts at \vcmd|arch/x86/assembly_entry.S|, which includes:
   \begin{itemize}
-    \item src/cpu/x86/32bit/entry32.inc: loads GDT and sets segment registers
+    \item cpu/x86/32bit/entry32.inc: loads GDT and sets segment registers
     \item generated/assembly.inc: generated from
-      src/cpu/intel/model\_206ax/cache\_as\_ram.inc, which sets up CAR
-      and runs the init code in romstage by calling ramstage\_main(),
-      then runs ramstage by calling romstage\_after\_car() which calls
-      run\_ramstage().
-  \end{itemize}
-
-  ramstage\_main() is in src/cpu/intel/car/romstage.c, it calls
-  mainboard\_romstage\_entry() in
-  src/northbridge/intel/sandybridge/romstage.c, which does the DRAM
+      cpu/intel/model\_206ax/cache\_as\_ram.inc, which:
+      \begin{itemize}
+      \item sets up CAR
+      \item calls \vcmd|romstage_main()|, which runs the init code in
+        romstage
+      \item disable CAR
+      \item calls \vcmd|romstage_after_car()|, which calls
+        \vcmd|run_ramstage()| to run ramstage
+      \end{itemize}
+  \end{itemize}
+
+  \vcmd|romstage_main()| is in cpu/intel/car/romstage.c, it calls
+  \vcmd|mainboard_romstage_entry()| in
+  northbridge/intel/sandybridge/romstage.c, which does the DRAM
   initialization.
 \end{frame}
 
-\begin{frame}{ramstage}
-  ramstage starts at src/arch/x86/c\_start.S, it calls the ``main``
-  function in src/lib/hardwaremain.c.
+\begin{frame}[fragile]{ramstage}
+  ramstage starts at \vcmd|src/arch/x86/c_start.S|, it calls the
+  \vcmd|main| function in src/lib/hardwaremain.c.
 
   There are 12 boot states defined in source code. Functions for each
   state are run in ramstage. At last payload is loaded and run.
@@ -279,6 +331,21 @@
   \end{itemize}
 \end{frame}
 
+\begin{frame}{Full disk encryption with LUKS}
+  When using coreboot, we can use GRUB or a Linux kernel based OS as
+  payload. Therefore, we can do a full disk encryption with LUKS.
+\end{frame}
+
+\begin{frame}[fragile]{Linux kernel as payload}
+  We can first run a Linux kernel, then using \vcmd|kexec| to run the
+  kernel on disk.
+  \begin{itemize}
+  \item Petitboot: a bootloader designed to run in a Linux environment
+    for OPAL on PowerPC/POWER machines and the Playstation 3
+  \item Heads: \url{https://github.com/osresearch/heads}
+  \end{itemize}
+\end{frame}
+
 \begin{frame}[fragile]{Supported OSes}
   coreboot supports many operating systems:
   \begin{itemize}
@@ -405,6 +472,15 @@ flashrom -p <prog> --layout layout.txt \
   it.
 \end{frame}
 
+\begin{frame}{ACPI debug}
+  \begin{itemize}
+  \item Linux ACPI debugging: Documentation/acpi/debug.txt in Linux
+    source code
+  \item Linux ACPI table updating:
+    \url{https://wiki.archlinux.org/index.php/DSDT\#Using_a_CPIO_archive}
+  \end{itemize}
+\end{frame}
+
 \section{Join the community}
 
 \frame{\tableofcontents[currentsection]}
@@ -431,7 +507,7 @@ flashrom -p <prog> --layout layout.txt \
   \item Mailing list: coreboot@coreboot.org
   \item IRC: \#coreboot at irc.freenode.net
   \item Mattermost (bridged to IRC): \url{https://chat.coreboot.org}
-  \item bug tracking system: \url{http://ticket.coreboot.org/}
+  \item bug tracking system: \url{https://ticket.coreboot.org/}
   \item twitter: @coreboot\_org
   \end{itemize}
 \end{frame}
@@ -489,10 +565,17 @@ flashrom -p <prog> --layout layout.txt \
 
 \end{frame}
 
-\section{How to port coreboot}
+\part{2}
+
+\section{Porting coreboot with autoport}
 
 \frame{\tableofcontents[currentsection]}
 
+\begin{frame}{Porting coreboot with autoport}
+  In this section, I'll show how I ported coreboot to Sandy/Ivy Bridge
+  laptops and mainboards with autoport.
+\end{frame}
+
 \begin{frame}{Chips on a mainboard}
   coreboot needs to initialize these chips.
 
@@ -536,29 +619,162 @@ flashrom -p <prog> --layout layout.txt \
   \end{itemize}
 \end{frame}
 
-\subsection{Example}
+\begin{frame}{Tools to work with the OEM firmware}
+  Sometimes, we need to know how the OEM firmware works, and implement
+  it in coreboot. These tools can help:
+
+  \begin{itemize}
+  \item UEFITool (\url{https://github.com/LongSoft/UEFITool}): a tool
+    to view, extract and replace the modules in a UEFI firmware
+  \item radare2 (\url{https://github.com/radare/radare2}): a reverse
+    engineering framework, hex editor, and binary analysis tool
+  \end{itemize}
+\end{frame}
+
+\subsection{ASRock B75 Pro3-M}
+
+\begin{frame}{ASRock B75 Pro3-M}
+  ASRock B75 Pro3-M is a desktop board. Porting coreboot to a desktop
+  board is easier than to a laptop:
+  \begin{itemize}
+  \item Most desktop boards don't have an EC.
+  \item Most desktop boards have a serial port at Super I/O, which is
+    easier to use than an EHCI debug port.
+  \item The flash chips on desktop boards are usually socketed.
+  \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{B75 Pro3-M: Super I/O}
+  Just run autoport in GNU/Linux running on this board, and get the
+  generated source code.
+
+  B75 Pro3-M uses Nuvoton NCT6776 as Super I/O, which is also used by
+  asrock/g41c-gs, so copy the Super I/O related things. If possible,
+  see the superiotool output for details.
+  \begin{itemize}
+  \item Kconfig
+  \item devicetree.cb
+  \item \vcmd|mainboard_config_superio| in romstage.c
+  \end{itemize}
+\end{frame}
+
+\begin{frame}{B75 Pro3-M: Hanging on boot, how to solve it?}
+  I got the debug output from the serial port, and saw the system
+  hanging when configuring PCIe devices.
 
-\begin{frame}{Example}
-  I made coreboot boot on HP Elitebook 2760p
-  (\url{https://review.coreboot.org/c/18241/}) half a year ago.
+  I disabled the ASMedia SATA controller in devicetree.cb, and the
+  system can boot. Patrick Rudolph saw from the boot log that the
+  system stopped after enabling ASPM of the ASMedia SATA controller,
+  thinking that the ASPM of that device should be disabled.
+  \begin{itemize}
+  \item Using ASPM override worked at the time I ported coreboot to
+    this board.
+  \item Now it uses the ASPM blacklist driver.
+  \end{itemize}
+\end{frame}
+
+\subsection{Sandy/Ivy Bridge HP Elitebooks}
+
+\begin{frame}{HP Elitebook 2760p}
+  I ported coreboot to HP Elitebooks and succeeded last year. In this
+  talk, I'll talk about how I ported coreboot to HP Elitebook 2760p
+  (\url{https://review.coreboot.org/c/18241/}):
   \begin{itemize}
   \item The flash chip is \textbf{socketed}, and is very easy to swap!
-  \item Sandy Bridge platform, so use autoport
+  \item Sandy Bridge platform, use autoport to generate the code
+  \end{itemize}
+\end{frame}
+
+\begin{frame}{I could not power on the machine}
+  At first, I built the ROM with the generated code and flashed
+  it. However, the power LED of the laptop just blinked and I could
+  not power on the laptop.
+
+  Let's look at what an embedded controller does:
+  \begin{itemize}
+  \item controlling the keyboard, touchpad, buttons and switches
+  \item turning the computer on and off
+  \item thermal management
+  \item battery management
+  \item \ldots
+  \end{itemize}
+
+  I guess the EC needs to read something from the flash chip to make
+  it work, maybe it's the EC firmware.
+\end{frame}
+
+\begin{frame}[fragile]{First attempt: Using UEFITool}
+  EC firmware is not UEFI modules, so I'll look into the place where
+  no UEFI modules are stored, for example, paddings.
+
+  \begin{figure}[htbp]
+    \centering
+    \includegraphics[scale=0.6]{images/uefitool-extract.jpg}
+  \end{figure}
+\end{frame}
+
+\begin{frame}[fragile]{EC firmware in the flash chip}
+  Using \vcmd|strings|, I can find some interesting things.
+
+  \begin{figure}[htbp]
+    \centering
+    \includegraphics[scale=0.5]{images/hp_ec.jpg}
+  \end{figure}
+
+  Now I can figure out the EC is based on 8051.
+\end{frame}
+
+\begin{frame}[fragile]{Editing binary file using radare2}
+  I use radare 2 to edit binary file. Running \vcmd|r2 -n -w bios.rom|
+  to open a binary file for editing. Remember to make a copy of the
+  file for backup.
+
+  \begin{itemize}
+  \item \vcmd|s addr|: seek to \textit{addr}
+  \item \vcmd|s $s-16|: seek to 16 bytes to the end of the file,
+    \vcmd|$s| means the file size
+  \item \vcmd|wx deadbeef|: write 4 bytes 0xde, 0xad, 0xbe, 0xef to
+    the seek offset
+  \item \vcmd|wx deadbeef @ addr|: write 4 bytes 0xde, 0xad, 0xbe,
+    0xef to \textit{addr}
+  \item \vcmd|w0 10|: write 10 zero bytes to the seek offset
+  \item \vcmd|wr 10 @ $s-0x100|: write 10 random bytes to 256 bytes to
+    the end of the file
   \end{itemize}
+\end{frame}
 
-  First, we need to make it boot, but not so easy:
+\begin{frame}{Testing where the EC reads in the flash chip}
+  Now I use radare2 to write random bytes or zero bytes to the flash
+  regions that I think may contain the things the EC needs to read. At
+  last, I found two essential regions.
   \begin{itemize}
-  \item It needs two blobs, otherwise the EC will not function!
-  \item see util/kbc1126/README.md
+  \item a ~64K region starting at 0x780000
+  \item a ~0xa00 region starting at 0x7ff700
   \end{itemize}
 \end{frame}
 
-\begin{frame}{Fixes (keyboard)}
-  After adding the blobs, the laptop boots!
+\begin{frame}[fragile]{More observations}
+  \begin{figure}[htbp]
+    \centering
+    \includegraphics[scale=0.6]{images/hp_ec_blobs.png}
+  \end{figure}
+
+  Looking at the blobs, it looks like that the first two bytes are the
+  sizes of the blobs.
 
-  Keyboard doesn't work.
+  After changing some bytes in the blobs, the laptop could not power
+  on. However, I could enlarge the blob size and append zero bytes.
+
+  At last, I found the next two bytes are checksum bytes, and the
+  checksum is SYSV checksum. Another finding is that, the 8 bytes at
+  \vcmd|$s-0x100| store the position of the two blobs.
+\end{frame}
+
+\begin{frame}{Keyboard}
+  After adding the blobs, the laptop boots! However, thek eyboard
+  doesn't work, which means the keyboard controller is not
+  initialized.
   \begin{itemize}
-  \item KBC not initialized
   \item It uses SMSC KBC1126 which provides EC, super I/O, and KBC
   \item I found an SMSC KBC1122 datasheet
   \item Also I found src/superio/smsc/kbc1100/, so the keyboard works
@@ -572,23 +788,138 @@ flashrom -p <prog> --layout layout.txt \
   \end{itemize}
 \end{frame}
 
-\begin{frame}{Fixes (fan control)}
-  The laptop fan always runs on full speed, that's because EC is not
+\begin{frame}{Fan control}
+  The laptop fan always runs on full speed, because EC is not
   initialized properly.
 
-  Reverse engineering it!
+  I didn't find anything about the fan control of this EC, so at last
+  I chose to reverse engineering it.
+
+  Using UEFITool, I found a module called EcThermalInit.
+
+  \begin{figure}[htbp]
+    \centering
+    \includegraphics[scale=0.9]{images/ecthermal.png}
+  \end{figure}
+\end{frame}
+
+\begin{frame}{Analyzing on this module}
+  I found there's a protection in the factory firmware, which makes
+  the laptop fail to boot if I remove or modify a UEFI module in the
+  DXE core. But it's easy to remove the protection.
+
+  After that, I try to \textbf{remove} and \textbf{modify} the driver,
+  to see what code is responsible for the fan control of the laptop.
+\end{frame}
+
+\begin{frame}{Reverse engineering with radare2}
+  \begin{figure}[htbp]
+    \centering
+    \includegraphics[scale=0.9]{images/ecthermal-re.jpg}
+  \end{figure}
+\end{frame}
+
+\begin{frame}{ACPI}
+  I need to implement the ACPI support to support:
+  \begin{itemize}
+  \item battery status
+  \item lid switch handling
+  \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{How an OS initializes the ACPI support}
+  In \vcmd|drivers/acpi/acpica/hwacpi.c| of the kernel source code, a
+  function called \vcmd|acpi_hw_set_mode| sets ACPI on or off by
+  writing a byte called \textit{acpi\_enable} or \textit{acpi\_disable}
+  to the SMI command port to trigger an SMI.
+
+  So we have to reverse the SMM modules in the firmware to see what it
+  does to enable or disable ACPI.
+\end{frame}
+
+\begin{frame}[fragile]{ACPI in HP Elitebooks}
+  Fortunately, I found a bit called \vcmd|ACPI| in EC RAM in the
+  vendor DSDT, and this bit is set during a system wake up from sleep.
+
+  Using ectool to set this bit, ACPI worked as expected.
+
+  At last, I wrote the ACPI code according to the vendor DSDT, then
+  the AC and battery status in HP Elitebooks running coreboot can be
+  shown in the OS.
+\end{frame}
+
+\subsection{Dell Latitude E6230}
+
+\begin{frame}{Dell Latitude E6230}
+  Dell Latitude is another series of business laptops, so I'm also
+  interested in porting coreboot to it. A friend of mine gave me a
+  E6230, then I used autoport to generate the coreboot code for it.
+
   \begin{itemize}
-  \item Use UEFITool to extract the UEFI driver
-  \item Check UEFI specification and related documents (e.g. EFI CPU
-    I/O Protocol Specification) to identify the UEFI protocols
+  \item EC and Super I/O: MEC5055+ECE5048, I can't find anything about them
+  \item Two flash chips: 8M+4M, the 4M one stores the high address part
+  \item The 8M flash chip cannot be accessed via ISP
   \end{itemize}
 \end{frame}
 
-\begin{frame}{A lot of things to be done...}
+\begin{frame}[fragile]{What to do when I can't do an ISP}
+  I desoldered the 8M flash chip with hot air, and I read its
+  content. Then I move all the BIOS region to the 8M chip:
   \begin{itemize}
-  \item ACPI support
-  \item GRUB payload doesn't work
-  \item ...
+  \item Use \vcmd|me_cleaner| to shrink the ME firmware, and modify
+    the IFD with \vcmd|ifdtool|, so that all the things are in the
+    lower 8M.
+  \item Solder wires to a socket, so I can easily access and replace
+    the chip.
+  \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Soldering the wires}
+  \begin{figure}[htbp]
+    \centering
+    \includegraphics[scale=0.2]{images/e6230-wires.jpg}
+  \end{figure}
+\end{frame}
+
+\begin{frame}[fragile]{How to shut down with several instructions?}
+  When I was modifying the firmware, I wanted to see if the code in
+  some place was run. I wrote some instructions at that place, so that
+  the system will shut down if those instructions are executed.
+
+  For Intel systems, there are some PM ports handled by Intel PCH. I
+  can shutdown the machine using 3 instructions:
+
+\begin{verbatim}
+  mov eax, 0x3c00
+  mov dx, PMBASE+4
+  out dx, eax
+\end{verbatim}
+
+PMBASE can be read from a running machine in PCI configuration space
+of 00:1f.0 offset 0x40. You can also disassemble the vendor
+firmware. It's usually configured in bootblock or PEI phase.
+\end{frame}
+
+\begin{frame}{Making coreboot work on Dell Latitude E6230}
+  Using the code generated by autoport, Dell Latitude E6230 can boot
+  to OS. However, the system will shutdown in one minute after power
+  on.
+
+  Using UEFITool, I found a PEI module called PeiEcIoDriver, removing
+  which will cause the laptop shutdown shortly after powering on the
+  laptop.
+\end{frame}
+
+\begin{frame}[fragile]
+  Reversing this module is easy, but after using the EC initialization
+  code in coreboot, the laptop will still shutdown.
+  \begin{itemize}
+  \item The code uses port 0x910 and 0x911, but they're not in the
+    decode range when running the generated coreboot code.
+  \item The OEM firmware sets the decode range in bootblock, and
+    overrides it later, so I can't find this in the running system.
+  \item Solution: set the decode range in \vcmd|pch_enable_lpc| in
+    romstage.c
   \end{itemize}
 \end{frame}
 
@@ -601,7 +932,7 @@ flashrom -p <prog> --layout layout.txt \
   \end{itemize}
 \end{frame}
 
-\part{2}
+\part{3}
 \section{[OT] Choosing hardware friendly to free software}
 \begin{frame}{Hardware choosing(Machines)}
   \begin{block}{Laptops}
-- 
cgit v1.2.3

