Initially, I wanted to move only the Kconfig DISPLAY_MTRRS into the "Debug" menu. It turned out, though, that the code looks rather generic. No need to hide it in soc/intel/. To not bloat src/Kconfig up any further, start a new `Kconfig.debug` hierarchy just for debug options. If somebody wants to review the code if it's 100% generic, we could even get rid of HAVE_DISPLAY_MTRRS. Change-Id: Ibd0a64121bd6e4ab5d7fd835f3ac25d3f5011f24 Signed-off-by: Nico Huber <nico.h@gmx.de> Reviewed-on: https://review.coreboot.org/c/29684 Reviewed-by: Patrick Georgi <pgeorgi@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
		
			
				
	
	
		
			732 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			732 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html>
 | |
|   <head>
 | |
|     <title>SoC</title>
 | |
|   </head>
 | |
|   <body>
 | |
| 
 | |
| <h1>x86 System on a Chip (SoC) Development</h1>
 | |
| <p>
 | |
|   SoC development is best done in parallel with development for a specific
 | |
|   board.  The combined steps are listed
 | |
|   <a target="_blank" href="../development.html">here</a>.
 | |
|   The development steps for the SoC are listed below:
 | |
| </p>
 | |
| <ol>
 | |
|   <li><a target="_blank" href="../fsp1_1.html#RequiredFiles">FSP 1.1</a> required files</li>
 | |
|   <li>SoC <a href="#RequiredFiles">Required Files</a></li>
 | |
|   <li><a href="#Descriptor">Start Booting</a></li>
 | |
|   <li><a href="#EarlyDebug">Early Debug</a></li>
 | |
|   <li><a href="#Bootblock">Bootblock</a></li>
 | |
|   <li><a href="#TempRamInit">TempRamInit</a></li>
 | |
|   <li><a href="#Romstage">Romstage</a>
 | |
|     <ol type="A">
 | |
|       <li>Enable <a href="#SerialOutput">Serial Output"</a></li>
 | |
|       <li>Get the <a href="#PreviousSleepState">Previous Sleep State</a></li>
 | |
|       <li>Add the <a href="#MemoryInit">MemoryInit</a> Support</li>
 | |
|       <li>Disable the <a href="#DisableShadowRom">Shadow ROM</a></li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li><a href="#Ramstage">Ramstage</a>
 | |
|     <ol type="A">
 | |
|       <li><a href="#DeviceTree">Start Device Tree Processing</a></li>
 | |
|       <li>Set up the <a href="#MemoryMap">Memory Map"</a></li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li><a href="#AcpiTables">ACPI Tables</a></li>
 | |
|   <li><a href="#LegacyHardware">Legacy Hardware</a></li>
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| <hr>
 | |
| <h2><a name="RequiredFiles">Required Files</a></h2>
 | |
| <p>
 | |
|   Create the directory as src/soc/<Vendor>/<Chip Family>.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
|   The following files are required to build a new SoC:
 | |
| </p>
 | |
| <ul>
 | |
|   <li>Include files
 | |
|     <ul>
 | |
|       <li>include/soc/pei_data.h</li>
 | |
|       <li>include/soc/pm.h</li>
 | |
|     </ul>
 | |
|   </li>
 | |
|   <li>Kconfig - Defines the Kconfig value for the SoC and selects the tool
 | |
|     chains for the various stages:
 | |
|     <ul>
 | |
|       <li>select ARCH_BOOTBLOCK_<Tool Chain></li>
 | |
|       <li>select ARCH_RAMSTAGE_<Tool Chain></li>
 | |
|       <li>select ARCH_ROMSTAGE_<Tool Chain></li>
 | |
|       <li>select ARCH_VERSTAGE_<Tool Chain></li>
 | |
|     </ul>
 | |
|   </li>
 | |
|   <li>Makefile.inc - Specify the include paths</li>
 | |
|   <li>memmap.c - Top of usable RAM</li>
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <hr>
 | |
| <h2><a name="Descriptor">Start Booting</a></h2>
 | |
| <p>
 | |
|   Some SoC parts require additional firmware components in the flash.
 | |
|   This section describes how to add those pieces.
 | |
| </p>
 | |
| 
 | |
| <h3>Intel Firmware Descriptor</h3>
 | |
| <p>
 | |
|   The Intel Firmware Descriptor (IFD) is located at the base of the flash part.
 | |
|   The following command overwrites the base of the flash image with the Intel
 | |
|   Firmware Descriptor:
 | |
| </p>
 | |
| <pre><code>dd if=descriptor.bin of=build/coreboot.rom conv=notrunc >/dev/null 2>&1</code></pre>
 | |
| 
 | |
| 
 | |
| <h3><a name="MEB">Management Engine Binary</a></h3>
 | |
| <p>
 | |
|   Some SoC parts contain and require that the Management Engine (ME) be running
 | |
|   before it is possible to bring the x86 processor out of reset.  A binary file
 | |
|   containing the management engine code must be added to the firmware using the
 | |
|   ifdtool.  The following commands add this binary blob:
 | |
| </p>
 | |
| <pre><code>util/ifdtool/ifdtool -i ME:me.bin  build/coreboot.rom
 | |
| mv build/coreboot.rom.new build/coreboot.rom
 | |
| </code></pre>
 | |
| 
 | |
| 
 | |
| <h3><a name="EarlyDebug">Early Debug</a></h3>
 | |
| <p>
 | |
|   Early debugging between the reset vector and the time the serial port is enabled
 | |
|   is most easily done by writing values to port 0x80.
 | |
| </p>
 | |
| 
 | |
| 
 | |
| <h3>Success</h3>
 | |
| <p>
 | |
|   When the reset vector is successfully invoked, port 0x80 will output the following value:
 | |
| </p>
 | |
| <ul>
 | |
|   <li>0x01: <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/include/console/post_codes.h;hb=HEAD#l45">POST_RESET_VECTOR_CORRECT</a>
 | |
|     - Bootblock successfully executed the
 | |
|     <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/x86/16bit/reset16.inc;hb=HEAD#l4">reset vector</a>
 | |
|     and entered the 16-bit code at
 | |
|     <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/x86/16bit/entry16.inc;hb=HEAD#l35">_start</a>
 | |
|   </li>
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <hr>
 | |
| <h2><a name="Bootblock">Bootblock</a></h2>
 | |
| <p>
 | |
|   Implement the bootblock using the following steps:
 | |
| </p>
 | |
| <ol>
 | |
|   <li>Create the directory as src/soc/<Vendor>/<Chip Family>/bootblock</li>
 | |
|   <li>Add the timestamp.inc file which initializes the floating point registers and saves
 | |
|     the initial timestamp.
 | |
|   </li>
 | |
|   <li>Add the bootblock.c file which:
 | |
|     <ol type="A">
 | |
|       <li>Enables memory-mapped PCI config access</li>
 | |
|       <li>Updates the microcode by calling intel_update_microcode_from_cbfs</li>
 | |
|       <li>Enable ROM caching</li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Edit the src/soc/<Vendor>/<Chip Family>/Kconfig file
 | |
|     <ol type="A">
 | |
|       <li>Add the BOOTBLOCK_CPU_INIT value to point to the bootblock.c file</li>
 | |
|       <li>Add the CHIPSET_BOOTBLOCK_INCLUDE value to point to the timestamp.inc file</li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Edit the src/soc/<Vendor>/<Chip Family>/Makefile.inc file
 | |
|     <ol type="A">
 | |
|       <li>Add the bootblock subdirectory</li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Edit the src/soc/<Vendor>/<Chip Family>/memmap.c file
 | |
|     <ol type="A">
 | |
|       <li>Add the fsp/memmap.h include file</li>
 | |
|       <li>Add the mmap_region_granularity routine</li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Add the necessary .h files to define the necessary values and structures</li>
 | |
|   <li>When successful port 0x80 will output the following values:
 | |
|     <ol type="A">
 | |
|       <li>0x01: <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/include/console/post_codes.h;hb=HEAD#l45">POST_RESET_VECTOR_CORRECT</a>
 | |
|         - Bootblock successfully executed the
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/x86/16bit/reset16.inc;hb=HEAD#l4">reset vector</a>
 | |
|         and entered the 16-bit code at
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/x86/16bit/entry16.inc;hb=HEAD#l35">_start</a>
 | |
|       </li>
 | |
|       <li>0x10: <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/include/console/post_codes.h;hb=HEAD#l53">POST_ENTER_PROTECTED_MODE</a>
 | |
|         - Bootblock executing in
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/x86/32bit/entry32.inc;hb=HEAD#l55">32-bit mode</a>
 | |
|       </li>
 | |
|       <li>0x10 - Verstage/romstage reached 32-bit mode</li>
 | |
|     </ol>
 | |
|   </li>
 | |
| </ol>
 | |
| 
 | |
| <p>
 | |
|   <b>Build Note:</b> The following files are included into the default bootblock image:
 | |
| </p>
 | |
| <ul>
 | |
|   <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/bootblock_romcc.S;hb=HEAD">src/arch/x86/bootblock_romcc.S</a>
 | |
|     added by   <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/Makefile.inc;hb=HEAD#l133">src/arch/x86/Makefile.inc</a>
 | |
|     and includes the following files:
 | |
|     <ul>
 | |
|       <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/prologue.inc">src/arch/x86/prologue.inc</a></li>
 | |
|       <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/x86/16bit/reset16.inc">src/cpu/x86/16bit/reset16.inc</a></li>
 | |
|       <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/x86/16bit/entry16.inc">src/cpu/x86/16bit/entry16.inc</a></li>
 | |
|       <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/x86/32bit/entry32.inc">src/cpu/x86/32bit/entry32.inc</a></li>
 | |
|       <li>The code in
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/bootblock_romcc.S">src/arch/x86/bootblock_romcc.S</a>
 | |
|         includes src/soc/<Vendor>/<Chip Family>/bootblock/timestamp.inc using the
 | |
|         CONFIG_CHIPSET_BOOTBLOCK_INCLUDE value set above
 | |
|       </li>
 | |
|       <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/x86/sse_enable.inc">src/cpu/x86/sse_enable.inc</a></li>
 | |
|       <li>The code in
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/Makefile.inc;hb=HEAD#l156">src/arch/x86/Makefile.inc</a>
 | |
|         invokes the ROMCC tool to convert the following "C" code into assembler as bootblock.inc:
 | |
|         <ul>
 | |
|           <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/include/arch/bootblock_romcc.h">src/arch/x86/include/arch/bootblock_romcc.h</a></li>
 | |
|           <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/x86/lapic/boot_cpu.c">src/cpu/x86/lapic/boot_cpu.c</a></li>
 | |
|           <li>The CONFIG_BOOTBLOCK_CPU_INIT value set above typically points to the code in
 | |
|             src/soc/<Vendor>/<Chip Family>/bootblock/bootblock.c
 | |
|           </li>
 | |
|         </ul>
 | |
|       </li>
 | |
|     </ul>
 | |
|   </li>
 | |
|   <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/id.S">src/arch/x86/id.S</a>
 | |
|     added by <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/Makefile.inc;hb=HEAD#l110">src/arch/x86/Makefile.inc</a>
 | |
|   </li>
 | |
|   <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/intel/fit/fit.S">src/cpu/intel/fit/fit.S</a>
 | |
|     added by <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/cpu/intel/fit/Makefile.inc;hb=HEAD">src/cpu/intel/fit/Makefile.inc</a>
 | |
|   </li>
 | |
|   <li><a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/walkcbfs.S">src/arch/x86/walkcbfs.S</a>
 | |
|     added by <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/Makefile.inc;hb=HEAD#l137">src/arch/x86/Makefile.inc</a>
 | |
|   </li>
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <hr>
 | |
| <h2><a name="TempRamInit">TempRamInit</a></h2>
 | |
| <p>
 | |
|   Enable the call to TempRamInit in two stages:
 | |
| </p>
 | |
| <ol>
 | |
|   <li>Finding the FSP binary in the read-only CBFS region</li>
 | |
|   <li>Call TempRamInit</li>
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| <h3>Find FSP Binary</h3>
 | |
| <p>
 | |
| Use the following steps to locate the FSP binary:
 | |
| </p>
 | |
| <ol>
 | |
|   <li>Edit the src/soc/<Vendor>/<Chip Family>/Kconfig file
 | |
|     <ol type="A">
 | |
|       <li>Add "select USE_GENERIC_FSP_CAR_INC" to enable the use of
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/drivers/intel/fsp1_1/cache_as_ram.inc">src/drivers/intel/fsp1_1/cache_as_ram.inc</a>
 | |
|       </li>
 | |
|       <li>Add "select SOC_INTEL_COMMON" to enable the use of the files from src/soc/intel/common
 | |
|       </li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Debug the result until port 0x80 outputs
 | |
|     <ol type="A">
 | |
|       <li>0x90: <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/include/console/post_codes.h;hb=HEAD#l205">POST_FSP_TEMP_RAM_INIT</a>
 | |
|         - Just before calling
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/drivers/intel/fsp1_1/cache_as_ram.inc;hb=HEAD#l73">TempRamInit</a>
 | |
|       </li>
 | |
|       <li>Alternating 0xba and 0x01 - The FSP image was not found</li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Add the <a target="_blank" href="../fsp1_1.html#FspBinary">FSP binary file</a> to the flash image</li>
 | |
|   <li>Set the following Kconfig values:
 | |
|     <ul>
 | |
|       <li>CONFIG_FSP_LOC to the FSP base address specified in the previous step</li>
 | |
|       <li>CONFIG_FSP_IMAGE_ID_STRING</li>
 | |
|     </ul>
 | |
|   </li>
 | |
|   <li>Debug the result until port 0x80 outputs
 | |
|     <ol type="A">
 | |
|       <li>0x90: <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/include/console/post_codes.h;hb=HEAD#l205">POST_FSP_TEMP_RAM_INIT</a>
 | |
|         - Just before calling
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/drivers/intel/fsp1_1/cache_as_ram.inc;hb=HEAD#l73">TempRamInit</a>
 | |
|       </li>
 | |
|       <li>Alternating 0xbb and 0x02 - TempRamInit executed, no CPU microcode update found</li>
 | |
|     </ol>
 | |
|   </li>
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| <h3>Calling TempRamInit</h3>
 | |
| <p>
 | |
| Use the following steps to debug the call to TempRamInit:
 | |
| </p>
 | |
| <ol>
 | |
|   <li>Add the CPU microcode update file
 | |
|     <ol type="A">
 | |
|       <li>Add the microcode file with the following command
 | |
| <pre><code>util/cbfstool/cbfstool build/coreboot.rom add -t microcode -n cpu_microcode_blob.bin -b <base address> -f cpu_microcode_blob.bin</code></pre>
 | |
|       </li>
 | |
|       <li>Set the Kconfig values
 | |
|         <ul>
 | |
|           <li>CONFIG_CPU_MICROCODE_CBFS_LOC set to the value from the previous step</li>
 | |
|           <li>CONFIG_CPU_MICROCODE_CBFS_LEN</li>
 | |
|         </ul>
 | |
|       </li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Debug the result until port 0x80 outputs
 | |
|     <ol type="A">
 | |
|       <li>0x90: <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/include/console/post_codes.h;hb=HEAD#l205">POST_FSP_TEMP_RAM_INIT</a>
 | |
|         - Just before calling
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/drivers/intel/fsp1_1/cache_as_ram.inc;hb=HEAD#l73">TempRamInit</a>
 | |
|       </li>
 | |
|       <li>0x2A - Just before calling
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/drivers/intel/fsp1_1/cache_as_ram.inc;hb=HEAD#l151">cache_as_ram_main</a>
 | |
|         which is the start of the verstage code which may be part of romstage
 | |
|       </li>
 | |
|     </ol>
 | |
|   </li>
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| <hr>
 | |
| <h2><a name="Romstage">Romstage</a></h2>
 | |
| 
 | |
| <h3><a name="SerialOutput">Serial Output</a></h3>
 | |
| <p>
 | |
|   The following steps add the serial output support for romstage:
 | |
| </p>
 | |
| <ol>
 | |
|   <li>Create the romstage subdirectory</li>
 | |
|   <li>Add romstage/romstage.c
 | |
|     <ol type="A">
 | |
|       <li>Program the necessary base addresses</li>
 | |
|       <li>Disable the TCO</li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Add romstage/Makefile.inc
 | |
|     <ol type="A">
 | |
|       <li>Add romstage.c to romstage</li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Add gpio configuration support if necessary</li>
 | |
|   <li>Add the necessary .h files to support the build</li>
 | |
|   <li>Update Makefile.inc
 | |
|     <ol type="A">
 | |
|       <li>Add the romstage subdirectory</li>
 | |
|       <li>Add the gpio configuration support file to romstage</li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Set the necessary Kconfig values to enable serial output:
 | |
|     <ul>
 | |
|       <li>CONFIG_DRIVERS_UART_<driver>=y</li>
 | |
|       <li>CONFIG_CONSOLE_SERIAL=y</li>
 | |
|       <li>CONFIG_UART_FOR_CONSOLE=<port></li>
 | |
|       <li>CONFIG_CONSOLE_SERIAL_115200=y</li>
 | |
|     </ul>
 | |
|   </li>
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| <h3><a name="PreviousSleepState">Determine Previous Sleep State</a></h3>
 | |
| <p>
 | |
|   The following steps implement the code to get the previous sleep state:
 | |
| </p>
 | |
| <ol>
 | |
|   <li>Implement the fill_power_state routine which determines the previous sleep state</li>
 | |
|   <li>Debug the result until port 0x80 outputs
 | |
|     <ol type="A">
 | |
|       <li>0x32:
 | |
|         - Just after entering
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/drivers/intel/fsp1_1/romstage.c;hb=HEAD#l99">romstage_common</a>
 | |
|       </li>
 | |
|       <li>0x33 - Just after calling
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/drivers/intel/fsp1_1/romstage.c;hb=HEAD#l113">soc_pre_ram_init</a>
 | |
|       </li>
 | |
|       <li>0x34:
 | |
|         - Just after entering
 | |
|         <a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/drivers/intel/fsp1_1/raminit.c;hb=HEAD#l67">raminit</a>
 | |
|       </li>
 | |
|     </ol>
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| <h3><a name="MemoryInit">MemoryInit Support</a></h3>
 | |
| <p>
 | |
|   The following steps implement the code to support the FSP MemoryInit call:
 | |
| </p>
 | |
| <ol>
 | |
|   <li>Add the chip.h header file to define the UPD values which get passed
 | |
|     to MemoryInit.  Skip the values containing SPD addresses and DRAM
 | |
|     configuration data which is determined by the board.
 | |
|     <p>
 | |
|       <b>Build Note</b>: The src/mainboard/<Vendor>/<Board>/devicetree.cb
 | |
|       file specifies the default values for these parameters.  The build
 | |
|       process creates the static.c module which contains the config data
 | |
|       structure containing these values.
 | |
|     </p>
 | |
|   </li>
 | |
|   <li>Edit romstage/romstage.c
 | |
|     <ol type="A">
 | |
|       <li>Implement the romstage/romstage.c/soc_memory_init_params routine to
 | |
|         copy the values from the config structure into the UPD structure
 | |
|       </li>
 | |
|       <li>Implement the soc_display_memory_init_params routine to display
 | |
|         the updated UPD parameters by calling fsp_display_upd_value
 | |
|       </li>
 | |
|     </ol>
 | |
|   </li>
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| <h3><a name="DisableShadowRom">Disable Shadow ROM</a></h3>
 | |
| <p>
 | |
|   A shadow of the SPI flash part is mapped from 0x000e0000 to 0x000fffff.
 | |
|   This shadow needs to be disabled to allow RAM to properly respond to
 | |
|   this address range.
 | |
| </p>
 | |
| <ol>
 | |
|   <li>Edit romstage/romstage.c and add the soc_after_ram_init routine</li>
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| <hr>
 | |
| <h2><a name="Ramstage">Ramstage</a></h2>
 | |
| 
 | |
| <h3><a name="DeviceTree">Start Device Tree Processing</a></h3>
 | |
| <p>
 | |
|   The src/mainboard/<Vendor>/<Board>/devicetree.cb file drives the
 | |
|   execution during ramstage.  This file is processed by the util/sconfig utility
 | |
|   to generate build/mainboard/<Vendor>/<Board>/static.c.  The various
 | |
|   state routines in
 | |
|   src/lib/<a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/lib/hardwaremain.c;hb=HEAD#l128">hardwaremain.c</a>
 | |
|   call dev_* routines which use the tables in static.c to locate operation tables
 | |
|   associated with the various chips and devices.  After location the operation
 | |
|   tables, the state routines call one or more functions depending upon the
 | |
|   state of the state machine.
 | |
| </p>
 | |
| 
 | |
| <h4><a name="ChipOperations">Chip Operations</a></h4>
 | |
| <p>
 | |
|   Kick-starting the ramstage state machine requires creating the operation table
 | |
|   for the chip listed in devicetree.cb:
 | |
| </p>
 | |
| <ol>
 | |
|   <li>Edit src/soc/<SoC Vendor>/<SoC Family>/chip.c:
 | |
|     <ol type="A">
 | |
|       <li>
 | |
|         This chip's operation table has the name
 | |
|         soc_<SoC Vendor>_<SoC Family>_ops which is derived from the
 | |
|         chip path specified in the devicetree.cb file.
 | |
|       </li>
 | |
|       <li>Use the CHIP_NAME macro to specify the name for the chip</li>
 | |
|       <li>For FSP 1.1, specify a .init routine which calls intel_silicon_init</li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Edit src/soc/<SoC Vendor>/<SoC Family>/Makefile.inc and add chip.c to ramstage</li>
 | |
| </ol>
 | |
| 
 | |
| <h4>Domain Operations</h4>
 | |
| <p>
 | |
|   coreboot uses the domain operation table to initiate operations on all of the
 | |
|   devices in the domain.  By default coreboot enables all PCI devices which it
 | |
|   finds.  Listing a device in devicetree.cb gives the board vendor control over
 | |
|   the device state.  Non-PCI devices may also be listed under PCI device such as
 | |
|   the LPC bus or SMbus devices.
 | |
| </p>
 | |
| <ol>
 | |
|   <li>Edit src/soc/<SoC Vendor>/<SoC Family>/chip.c:
 | |
|     <ol type="A">
 | |
|       <li>
 | |
|         The domain operation table is typically placed in
 | |
|         src/soc/<SoC Vendor>/<SoC Family>/chip.c.
 | |
|         The table typically looks like the following:
 | |
| <pre><code>static struct device_operations pci_domain_ops = {
 | |
| 	.read_resources	= pci_domain_read_resources,
 | |
| 	.set_resources	= pci_domain_set_resources,
 | |
| 	.scan_bus	= pci_domain_scan_bus,
 | |
| };
 | |
| </code></pre>
 | |
|       </li>
 | |
|       <li>
 | |
|         Create a .enable_dev entry in the chip operations table which points to a
 | |
|         routine which sets the domain table for the device with the DEVICE_PATH_DOMAIN.
 | |
| <pre><code>	if (dev->path.type == DEVICE_PATH_DOMAIN) {
 | |
| 		dev->ops = &pci_domain_ops;
 | |
| 	}
 | |
| </code></pre>
 | |
|       </li>
 | |
|       <li>
 | |
|         During the BS_DEV_ENUMERATE state, ramstage now display the device IDs
 | |
|         for the PCI devices on the bus.
 | |
|       </li>
 | |
|     </ol>
 | |
|   </li>
 | |
|   <li>Set CONFIG_DEBUG_BOOT_STATE=y in the .config file</li>
 | |
|   <li>
 | |
|     Debug the result until the PCI vendor and device IDs are displayed
 | |
|     during the BS_DEV_ENUMERATE state.
 | |
|   </li>
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| <h3><a name="DeviceDrivers">PCI Device Drivers</a></h3>
 | |
| <p>
 | |
|   PCI device drivers consist of a ".c" file which contains a "pci_driver" data
 | |
|   structure at the end of the file with the attribute tag "__pci_driver".  This
 | |
|   attribute tag places an entry into a link time table listing the various
 | |
|   coreboot device drivers.
 | |
| </p>
 | |
| <p>
 | |
|   Specify the following fields in the table:
 | |
| </p>
 | |
| <ol>
 | |
|   <li>.vendor - PCI vendor ID value of the device</li>
 | |
|   <li>.device - PCI device ID value of the device or<br>
 | |
|   .devices - Address of a zero terminated array of PCI device IDs
 | |
|   </li>
 | |
|   <li>.ops - Operations table for the device.  This is the address
 | |
|     of a "static struct device_operations" data structure specifying
 | |
|     the routines to execute during the different states and sub-states
 | |
|     of ramstage's processing.
 | |
|   </li>
 | |
|   <li>Turn on the device in mainboard/<Vendor>/<Board>/devicetree.cb</li>
 | |
|   <li>
 | |
|     Debug until the device is on and properly configured in coreboot and
 | |
|     usable by the payload
 | |
|   </li>
 | |
| </ol>
 | |
| 
 | |
| <h4><a name="SubsystemIds">Subsystem IDs</a></h4>
 | |
| <p>
 | |
|   PCI subsystem IDs are assigned during the BS_DEV_ENABLE state.  The device
 | |
|   driver may use the common mechanism to assign subsystem IDs by adding
 | |
|   the ".ops_pci" to the pci_driver data structure.  This field points to
 | |
|   a "struct pci_operations" that specifies a routine to set the subsystem
 | |
|   IDs for the device.  The routine might look something like this:
 | |
| </p>
 | |
| <pre><code>static void pci_set_subsystem(struct device *dev, unsigned vendor, unsigned device)
 | |
| {
 | |
| 	if (!vendor || !device) {
 | |
| 		vendor = pci_read_config32(dev, PCI_VENDOR_ID);
 | |
| 		device = vendor >> 16;
 | |
| 	}
 | |
| 	printk(BIOS_SPEW,
 | |
| 		"PCI: %02x:%02x:%d subsystem vendor: 0x%04x, device: 0x%04x\n",
 | |
| 		0, PCI_SLOT(dev->path.pci.devfn), PCI_FUNC(dev->path.pci.devfn),
 | |
| 		vendor & 0xffff, device);
 | |
| 	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
 | |
| 			((device & 0xffff) << 16) | (vendor & 0xffff));
 | |
| }
 | |
| </code></pre>
 | |
| 
 | |
| 
 | |
| 
 | |
| <h3>Set up the <a name="MemoryMap">Memory Map</a></h3>
 | |
| <p>
 | |
|   The memory map is built by the various PCI device drivers during the
 | |
|   BS_DEV_RESOURCES state of ramstage.  The northcluster driver will typically
 | |
|   specify the DRAM resources while the other drivers will typically specify
 | |
|   the IO resources.  These resources are hung off the struct device *data structure by
 | |
|   src/device/device_util.c/<a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/device/device_util.c;hb=HEAD#l448">new_resource</a>.
 | |
| </p>
 | |
| <p>
 | |
|   During the BS_WRITE_TABLES state, coreboot collects these resources and
 | |
|   places them into a data structure identified by LB_MEM_TABLE.
 | |
| </p>
 | |
| <p>
 | |
|   Edit the device driver file:
 | |
| </p>
 | |
| <ol>
 | |
|   <li>
 | |
|     Implement a read_resources routine which calls macros defined in
 | |
|     src/include/device/<a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/include/device/device.h;hb=HEAD#l237">device.h</a>
 | |
|     like:
 | |
|     <ul>
 | |
|       <li>ram_resource</li>
 | |
|       <li>reserved_ram_resource</li>
 | |
|       <li>bad_ram_resource</li>
 | |
|       <li>uma_resource</li>
 | |
|       <li>mmio_resource</li>
 | |
|     </ul>
 | |
|   </li>
 | |
| </ol>
 | |
| 
 | |
| <p>
 | |
|   Testing: Verify that the resources are properly displayed by coreboot during the BS_WRITE_TABLES state.
 | |
| </p>
 | |
| 
 | |
| 
 | |
| 
 | |
| <hr>
 | |
| <h2><a name="AcpiTables">ACPI Tables</a></h2>
 | |
| <p>
 | |
|   One of the payloads that needs ACPI tables is the EDK2 <a target="_blank" href="quark.html#CorebootPayloadPkg">CorebootPayloadPkg</a>.
 | |
| </p>
 | |
| 
 | |
| <h3>FADT</h3>
 | |
| <p>
 | |
|   The EDK2 module
 | |
|   CorebootModulePkg/Library/CbParseLib/<a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootModulePkg/Library/CbParseLib/CbParseLib.c#l450">CbParseLib.c</a>
 | |
|   requires that the FADT contains the values in the table below.
 | |
|   These values are placed into a HOB identified by
 | |
|   <a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootModulePkg/CorebootModulePkg.dec#l36">gUefiAcpiBoardInfoGuid</a>
 | |
|   by routine
 | |
|   CorebootModulePkg/CbSupportPei/CbSupportPei/<a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootModulePkg/CbSupportPei/CbSupportPei.c#l364">CbPeiEntryPoint</a>.
 | |
| </p>
 | |
| <table border="1">
 | |
|   <tr bgcolor="#c0ffc0">
 | |
|     <td>coreboot Field</td>
 | |
|     <td>EDK2 Field</td>
 | |
|     <td>gUefiAcpiBoardInfoGuid</td>
 | |
|     <td>Use</li>
 | |
|     <td>
 | |
|       <a target="_blank" href="http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf">ACPI Spec.</a>
 | |
|       Section
 | |
|     </td>
 | |
|   </tr>
 | |
|   <tr>
 | |
|     <td>gpe0_blk<br>gpe0_blk_len</td>
 | |
|     <td>Gpe0Blk<br>Gpe0BlkLen</td>
 | |
|     <td>
 | |
|       <a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootModulePkg/Library/CbParseLib/CbParseLib.c#l477">PmGpeEnBase</a>
 | |
|     </td>
 | |
|     <td><a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c#l129">Shutdown</a></td>
 | |
|     <td>4.8.4.1</td>
 | |
|   </tr>
 | |
|   <tr>
 | |
|     <td>pm1a_cnt_blk</td>
 | |
|     <td>Pm1aCntBlk</td>
 | |
|     <td>PmCtrlRegBase</td>
 | |
|     <td>
 | |
|       <a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c#l139">Shutdown</a><br>
 | |
|       <a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c#l40">Suspend</a>
 | |
|     </td>
 | |
|     <td>4.8.3.2.1</td>
 | |
|   </tr>
 | |
|   <tr>
 | |
|     <td>pm1a_evt_blk</td>
 | |
|     <td>Pm1aEvtBlk</td>
 | |
|     <td>PmEvtBase</td>
 | |
|     <td><a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c#l134">Shutdown</a></td>
 | |
|     <td>4.8.3.1.1</td>
 | |
|   </tr>
 | |
|   <tr>
 | |
|     <td>pm_tmr_blk</td>
 | |
|     <td>PmTmrBlk</td>
 | |
|     <td>PmTimerRegBase</td>
 | |
|     <td>
 | |
|       <a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.c#l55">Timer</a>
 | |
|     </td>
 | |
|     <td>4.8.3.3</td>
 | |
|   </tr>
 | |
|   <tr>
 | |
|     <td>reset_reg.</td>
 | |
|     <td>ResetReg.Address</td>
 | |
|     <td>ResetRegAddress</td>
 | |
|     <td>
 | |
|       <a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c#l71">Cold</a>
 | |
|       and
 | |
|       <a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c#l98">Warm</a>
 | |
|       resets
 | |
|     </td>
 | |
|     <td>4.3.3.6</td>
 | |
|   </tr>
 | |
|   <tr>
 | |
|     <td>reset_value</td>
 | |
|     <td>ResetValue</td>
 | |
|     <td>ResetValue</td>
 | |
|     <td>
 | |
|       <a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c#l71">Cold</a>
 | |
|       and
 | |
|       <a target="_blank" href="https://github.com/tianocore/edk2/blob/master/CorebootPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c#l98">Warm</a>
 | |
|       resets
 | |
|     </td>
 | |
|     <td>4.8.3.6</td>
 | |
|   </tr>
 | |
| </table>
 | |
| <p>
 | |
|   The EDK2 data structure is defined in
 | |
|   MdeModulePkg/Include/IndustryStandard/<a target="_blank" href="https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/Acpi61.h#l111">Acpi61.h</a>
 | |
|   The coreboot data structure is defined in
 | |
|   src/arch/x86/include/arch/<a target="_blank" href="https://review.coreboot.org/gitweb?p=coreboot.git;a=blob;f=src/arch/x86/include/arch/acpi.h;hb=HEAD#l237">acpi.h</a>
 | |
| </p>
 | |
| 
 | |
| <ol>
 | |
|   <li>
 | |
|     Select <a target="_blank" href="../Board/board.html#AcpiTables">HAVE_ACPI_TABLES</a>
 | |
|     in the board's Kconfig file
 | |
|   </li>
 | |
|   <li>Create a acpi.c module:
 | |
|     <ol type="A">
 | |
|       <li>Add the acpi_fill_in_fadt routine and initialize the values above</li>
 | |
|     </ol>
 | |
|   </li>
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| 
 | |
| <hr>
 | |
| <h2><a name="LegacyHardware">Legacy Hardware</a></h2>
 | |
| <p>
 | |
|   One of the payloads that needs legacy hardare is the EDK2 <a target="_blank" href="quark.html#CorebootPayloadPkg">CorebootPayloadPkg</a>.
 | |
| </p>
 | |
| 
 | |
| <table border="1">
 | |
|   <tr bgcolor="c0ffc0">
 | |
|     <th>Peripheral</th>
 | |
|     <th>Use</th>
 | |
|     <th>8259 Interrupt Vector</th>
 | |
|     <th>IDT Base Offset</th>
 | |
|     <th>Interrupt Handler</th>
 | |
|   </tr>
 | |
|   <tr>
 | |
|     <td>
 | |
|       <a target="_blank" href="http://www.scs.stanford.edu/10wi-cs140/pintos/specs/8254.pdf">8254</a>
 | |
|       Programmable Interval Timer
 | |
|     </td>
 | |
|     <td>
 | |
|       EDK2: PcAtChipsetPkg/8254TimerDxe/<a target="_blank" href="https://github.com/tianocore/edk2/blob/master/PcAtChipsetPkg/8254TimerDxe/Timer.c">Timer.c</a>
 | |
|     </td>
 | |
|     <td>0</td>
 | |
|     <td>0x340</td>
 | |
|     <td>
 | |
|       <a target="_blank" href="https://github.com/tianocore/edk2/blob/master/PcAtChipsetPkg/8254TimerDxe/Timer.c#l71">TimerInterruptHandler</a>
 | |
|     </td>
 | |
|   </tr>
 | |
|   <tr>
 | |
|     <td>
 | |
|       <a target="_blank" href="https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwibxYKU3ZDLAhVOzWMKHfuqB40QFggcMAA&url=http%3A%2F%2Fbochs.sourceforge.net%2Ftechspec%2Fintel-8259a-pic.pdf.gz&usg=AFQjCNF1NT0OQ6ys1Pn6Iv9sv6cKRzZbGg&sig2=HfBszp9xTVO_fajjPWCsJw">8259</a>
 | |
|       Programmable Interrupt Controller
 | |
|     </td>
 | |
|     <td>
 | |
|       EDK2: PcAtChipsetPkg/8259InterruptControllerDxe/<a target="_blank" href="https://github.com/tianocore/edk2/blob/master/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c">8259.c</a>
 | |
|     </td>
 | |
|     <td>
 | |
|       Master interrupts: 0, 2 - 7<br>
 | |
|       Slave interrupts: 8 - 15<br>
 | |
|       Interrupt vector 1 is never generated, the cascaded input generates interrupts 8 - 15
 | |
|     </td>
 | |
|     <td>
 | |
|       Master: 0x340, 0x350 - 0x378<br>
 | |
|       Slave: 0x380 - 0x3b8<br>
 | |
|       Interrupt descriptors are 8 bytes each
 | |
|     </td>
 | |
|     <td> </td>
 | |
|   </tr>
 | |
| </table>
 | |
| 
 | |
| <hr>
 | |
| <p>Modified: 4 March 2016</p>
 | |
|   </body>
 | |
| </html>
 |