mb/emulation/qemu-q35,qemu-i440fx: Add x86_64 support

* Enable optional x86_64 romstage, postcar and ramstage
* Add Kconfig for x86_64 compilation
* Add documentation for x86 qemu mainboards
* Increase CAR stack as x86_64 uses more than 0x4000 bytes

Working:
* Boots to Linux
* Boots to SeaBIOS
* Drops to protected mode at end of ramstage
* Enumerates PCI devices
* Relocateable ramstage
* SMM

Change-Id: If2f02a95b2f91ab51043d4e81054354f4a6eb5d5
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/29667
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/Documentation/arch/x86/index.md b/Documentation/arch/x86/index.md
index 7b9e1fc..11d8a4f 100644
--- a/Documentation/arch/x86/index.md
+++ b/Documentation/arch/x86/index.md
@@ -5,10 +5,11 @@
 * [x86 PAE support](pae.md)
 
 ## State of x86_64 support
-At the moment there's no single board that supports x86_64 or to be exact
-`ARCH_RAMSTAGE_X86_64` and `ARCH_ROMSTAGE_X86_64`.
+At the moment there's only experimental x86_64 support.
+The `emulation/qemu-i440fx` and `emulation/qemu-q35` boards do support
+*ARCH_RAMSTAGE_X86_64* , *ARCH_POSTCAR_X86_64* and *ARCH_ROMSTAGE_X86_64*.
 
-In order to add support for x86_64 the following assumptions are made:
+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
@@ -39,18 +40,16 @@
 
 At the moment *$n* is 4, which results in identity mapping the lower 4 GiB.
 
-## Steps to add basic support for x86_64
-* Add x86_64 toolchain support - *DONE*
-* Fix compilation errors - *DONE*
-* Fix linker errors - *TODO*
-* Add x86_64 rmodule support - *DONE*
-* Add x86_64 exception handlers - *DONE*
-* Setup page tables for long mode - *DONE*
-* Add assembly code for long mode - *DONE*
-* Add assembly code for SMM - *DONE*
-* Add assembly code for postcar stage - *DONE*
-* Add assembly code to return to protected mode - *DONE*
-* Implement reference code for mainboard `emulation/qemu-q35` - *TODO*
+## Basic x86_64 support
+Basic support for x86_64 has been implemented for QEMU mainboard target.
+
+## Reference implementation
+The reference implementation is
+* [QEMU i440fx](../../mainboard/emulation/qemu-i440fx.md)
+* [QEMU Q35](../../mainboard/emulation/qemu-q35.md)
+
+## TODO
+* Identity map memory above 4GiB in ramstage
 
 ## Future work
 
diff --git a/Documentation/mainboard/emulation/qemu-i440fx.md b/Documentation/mainboard/emulation/qemu-i440fx.md
new file mode 100644
index 0000000..059ad12
--- /dev/null
+++ b/Documentation/mainboard/emulation/qemu-i440fx.md
@@ -0,0 +1,64 @@
+# qemu i440fx mainboard
+
+## Running coreboot in qemu
+Emulators like qemu don't need a firmware to do hardware init.
+The hardware starts in the configured state already.
+
+The coreboot port allows to test non mainboard specific code.
+As you can easily attach a debugger, it's a good target for
+experimental code.
+
+## coreboot x86_64 support
+coreboot historically runs in 32-bit protected mode, even though the
+processor supports x86_64 instructions (long mode).
+
+The qemu-i440fx mainboard has been ported to x86_64 and will serve as
+reference platform to enable additional platforms.
+
+To enable the support set the Kconfig option ``CONFIG_CPU_QEMU_X86_64=y``.
+
+## Installing qemu
+
+On debian you can install qemu by running:
+```bash
+$ sudo apt-get install qemu
+```
+
+On redhat you can install qemu by running:
+```bash
+$ sudo dnf install qemu
+```
+
+## Running coreboot
+
+### To run the i386 version of coreboot (default)
+Running on qemu-system-i386 will require a 32 bit operating system.
+
+```bash
+qemu-system-i386 -bios build/coreboot.rom -serial stdio -M pc
+```
+
+### To run the experimental x86_64 version of coreboot
+Running on qemu-system-x86_64 allows to run a 32 bit or 64 bit operating system,
+as well as firmware.
+
+```bash
+qemu-system-x86_64 -bios build/coreboot.rom -serial stdio -M pc
+```
+
+## Finding bugs
+To test coreboot's x86 code it's recommended to run on a x86 host and enable KVM.
+It will not only run faster, but is closer to real hardware. If you see the
+following message:
+
+    KVM internal error. Suberror: 1
+    emulation failure
+
+something went wrong. The same bug will likely cause a FAULT on real hardware,
+too.
+
+To enable KVM run:
+
+```bash
+qemu-system-x86_64 -bios build/coreboot.rom -serial stdio -M pc -accel kvm -cpu host
+```
diff --git a/Documentation/mainboard/emulation/qemu-q35.md b/Documentation/mainboard/emulation/qemu-q35.md
new file mode 100644
index 0000000..00163e8
--- /dev/null
+++ b/Documentation/mainboard/emulation/qemu-q35.md
@@ -0,0 +1,64 @@
+# qemu q35 mainboard
+
+## Running coreboot in qemu
+Emulators like qemu don't need a firmware to do hardware init.
+The hardware starts in the configured state already.
+
+The coreboot port allows to test non mainboard specific code.
+As you can easily attach a debugger, it's a good target for
+experimental code.
+
+## coreboot x86_64 support
+coreboot historically runs in 32-bit protected mode, even though the
+processor supports x86_64 instructions (long mode).
+
+The qemu-q35 mainboard has been ported to x86_64 and will serve as
+reference platform to enable additional platforms.
+
+To enable the support set the Kconfig option ``CONFIG_CPU_QEMU_X86_64=y``.
+
+## Installing qemu
+
+On debian you can install qemu by running:
+```bash
+$ sudo apt-get install qemu
+```
+
+On redhat you can install qemu by running:
+```bash
+$ sudo dnf install qemu
+```
+
+## Running coreboot
+### To run the i386 version of coreboot (default)
+Running on qemu-system-i386 will require a 32 bit operating system.
+
+```bash
+qemu-system-i386 -bios build/coreboot.rom -serial stdio -M q35
+```
+
+### To run the experimental x86_64 version of coreboot
+Running on `qemu-system-x86_64` allows to run a 32 bit or 64 bit operating system
+and firmware.
+
+```bash
+qemu-system-x86_64 -bios build/coreboot.rom -serial stdio -M q35
+```
+
+## Finding bugs
+To test coreboot's x86 code it's recommended to run on a x86 host and enable KVM.
+It will not only run faster, but is closer to real hardware. If you see the
+following message:
+
+    KVM internal error. Suberror: 1
+    emulation failure
+
+something went wrong. The same bug will likely cause a FAULT on real hardware,
+too.
+
+To enable KVM run:
+
+```bash
+qemu-system-x86_64 -bios build/coreboot.rom -serial stdio -M q35 -accel kvm -cpu host
+```
+
diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md
index 1749064..0eefee8 100644
--- a/Documentation/mainboard/index.md
+++ b/Documentation/mainboard/index.md
@@ -37,6 +37,8 @@
 - [Spike RISC-V emulator](emulation/spike-riscv.md)
 - [Qemu RISC-V emulator](emulation/qemu-riscv.md)
 - [Qemu AArch64 emulator](emulation/qemu-aarch64.md)
+- [Qemu x86 Q35](emulation/qemu-q35.md)
+- [Qemu x86 PC](emulation/qemu-i440fx.md)
 
 ## Facebook
 
diff --git a/src/cpu/qemu-x86/Kconfig b/src/cpu/qemu-x86/Kconfig
index 21ada02..af0c746 100644
--- a/src/cpu/qemu-x86/Kconfig
+++ b/src/cpu/qemu-x86/Kconfig
@@ -2,12 +2,29 @@
 
 config CPU_QEMU_X86
 	bool
-	select ARCH_BOOTBLOCK_X86_32
-	select ARCH_VERSTAGE_X86_32
-	select ARCH_ROMSTAGE_X86_32
-	select ARCH_RAMSTAGE_X86_32
 	select SMP
 	select UDELAY_TSC
 	select TSC_MONOTONIC_TIMER
 	select UNKNOWN_TSC_RATE
 	select SMM_ASEG
+
+if CPU_QEMU_X86
+
+config CPU_QEMU_X86_64
+	bool "Experimental 64bit support"
+	select ARCH_BOOTBLOCK_X86_64
+	select ARCH_VERSTAGE_X86_64
+	select ARCH_ROMSTAGE_X86_64
+	select ARCH_POSTCAR_X86_64
+	select ARCH_RAMSTAGE_X86_64
+
+config CPU_QEMU_X86_32
+	bool
+	default n if CPU_QEMU_X86_64
+	default y
+	select ARCH_BOOTBLOCK_X86_32
+	select ARCH_VERSTAGE_X86_32
+	select ARCH_ROMSTAGE_X86_32
+	select ARCH_POSTCAR_X86_32
+	select ARCH_RAMSTAGE_X86_32
+endif