With SMM holding page tables itself, we can consider SMM support stable and safe enough for general use. Also update the respective documentation. Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Change-Id: Ifcf0a1a5097a2d7c064bb709ec0b09ebee13a47d Reviewed-on: https://review.coreboot.org/c/coreboot/+/80338 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin L Roth <gaumless@gmail.com>
		
			
				
	
	
		
			97 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # x86 architecture documentation
 | |
| 
 | |
| This section contains documentation about coreboot on x86 architecture.
 | |
| 
 | |
| ```{toctree}
 | |
| :maxdepth: 1
 | |
| 
 | |
| x86 PAE support <pae.md>
 | |
| ```
 | |
| 
 | |
| ## State of x86_64 support
 | |
| Some SOCs now support 64bit mode. Search for HAVE_X86_64_SUPPORT in Kconfig.
 | |
| 
 | |
| In order to add support for x86_64 the following assumptions were made:
 | |
| * The CPU supports long mode
 | |
| * All memory returned by malloc must be below 4GiB in physical memory
 | |
| * All code that is to be run must be below 4GiB in physical memory
 | |
| * The high dword of pointers is always zero
 | |
| * The reference implementation is qemu
 | |
| * x86 payloads are loaded below 4GiB in physical memory and are jumped
 | |
|   to in *protected mode*
 | |
| 
 | |
| ## Assumptions for all stages using the reference implementation
 | |
| * 0-4GiB are identity mapped using 2MiB-pages as WB
 | |
| * Memory above 4GiB isn't accessible
 | |
| * page tables reside in memory mapped ROM
 | |
| * A stage can install new page tables in RAM
 | |
| 
 | |
| ## Page tables
 | |
| A `pagetables` cbfs file is generated based on an assembly file.
 | |
| 
 | |
| To generate the static page tables it must know the physical address where to
 | |
| place the file.
 | |
| 
 | |
| The page tables contains the following structure:
 | |
| * PML4E pointing to PDPE
 | |
| * PDPE with *$n* entries each pointing to PDE
 | |
| * *$n* PDEs with 512 entries each
 | |
| 
 | |
| At the moment *$n* is 4, which results in identity mapping the lower 4 GiB.
 | |
| 
 | |
| ## Basic x86_64 support
 | |
| Basic support for x86_64 has been implemented for QEMU mainboard target.
 | |
| 
 | |
| ## Reference implementation
 | |
| The reference implementation is
 | |
| ```{toctree}
 | |
| :maxdepth: 1
 | |
| 
 | |
| QEMU i440fx <../../mainboard/emulation/qemu-i440fx.md>
 | |
| QEMU Q35 <../../mainboard/emulation/qemu-q35.md>
 | |
| ```
 | |
| 
 | |
| ## TODO
 | |
| * Identity map memory above 4GiB in ramstage
 | |
| 
 | |
| ## Future work
 | |
| 
 | |
| 1. Fine grained page tables for SMM:
 | |
|    * Must not have execute and write permissions for the same page.
 | |
|    * Must allow only that TSEG pages can be marked executable
 | |
| 2. Support 64bit PCI BARs above 4GiB
 | |
| 3. Place and run code above 4GiB
 | |
| 
 | |
| ## Porting other boards
 | |
| * Fix compilation errors
 | |
| * Test how well CAR works with x86_64 and paging
 | |
| * Improve mode switches
 | |
| 
 | |
| ## Known problems on real hardware
 | |
| 
 | |
| Running VGA rom directly fails. Yabel works fine though.
 | |
| 
 | |
| ## Known bugs on KVM enabled qemu
 | |
| 
 | |
| The `x86_64` reference code runs fine in qemu soft-cpu, but has serious issues
 | |
| when using KVM mode on some machines. The workaround is to *not* place
 | |
| page-tables in ROM, as done in
 | |
| [CB:49228](https://review.coreboot.org/c/coreboot/+/49228).
 | |
| 
 | |
| Here's a list of known issues:
 | |
| 
 | |
| * After entering long mode, the FPU doesn't work anymore, including accessing
 | |
|   MMX registers. It works fine before entering long mode. It works fine when
 | |
|   switching back to protected mode. Other registers, like SSE registers, are
 | |
|   working fine.
 | |
| * Reading from virtual memory, when the page tables are stored in ROM, causes
 | |
|   the MMU to abort the "page table walking" mechanism when the lower address
 | |
|   bits of the virtual address to be translated have a specific pattern.
 | |
|   Instead of loading the correct physical page, the one containing the
 | |
|   page tables in ROM will be loaded and used, which breaks code and data as
 | |
|   the page table doesn't contain the expected data. This in turn leads to
 | |
|   undefined behaviour whenever the 'wrong' address is being read.
 | |
| * Disabling paging in compatibility mode crashes the CPU.
 | |
| * Returning from long mode to compatibility mode crashes the CPU.
 | |
| * Entering long mode crashes on AMD host platforms.
 |