Files
system76-coreboot/Documentation/arch/x86/index.md
Nicholas Chin 35599f9a66 Docs: Replace Recommonmark with MyST Parser
Recommonmark has been deprecated since 2021 [1] and the last release was
over 3 years ago [2]. As per their announcement, Markedly Structured
Text (MyST) Parser [3] is the recommended replacement.

For the most part, the existing documentation is compatible with MyST,
as both parsers are built around the CommonMark flavor of Markdown. The
main difference that affects coreboot is how the Sphinx toctree is
generated. Recommonmark has a feature called auto_toc_tree, which
converts single level lists of references into a toctree:

* [Part 1: Starting from scratch](part1.md)
* [Part 2: Submitting a patch to coreboot.org](part2.md)
* [Part 3: Writing unit tests](part3.md)
* [Managing local additions](managing_local_additions.md)
* [Flashing firmware](flashing_firmware/index.md)

MyST Parser does not provide a replacement for this feature, meaning the
toctree must be defined manually. This is done using MyST's syntax for
Sphinx directives:

```{toctree}
:maxdepth: 1

Part 1: Starting from scratch <part1.md>
Part 2: Submitting a patch to coreboot.org <part2.md>
Part 3: Writing unit tests <part3.md>
Managing local additions <managing_local_additions.md>
Flashing firmware <flashing_firmware/index.md>
```

Internally, auto_toc_tree essentially converts lists of references into
the Sphinx toctree structure that the MyST syntax above more directly
represents.

The toctrees were converted to the MyST syntax using the following
command and Python script:

`find ./ -iname "*.md" | xargs -n 1 python conv_toctree.py`

```
import re
import sys

in_list = False
f = open(sys.argv[1])
lines = f.readlines()
f.close()

with open(sys.argv[1], "w") as f:
    for line in lines:
        match = re.match(r"^[-*+] \[(.*)\]\((.*)\)$", line)
        if match is not None:
            if not in_list:
                in_list = True
                f.write("```{toctree}\n")
                f.write(":maxdepth: 1\n\n")
            f.write(match.group(1) + " <" + match.group(2) + ">\n")
        else:
            if in_list:
                f.write("```\n")
            f.write(line)
            in_list = False

    if in_list:
        f.write("```\n")
```

While this does add a little more work for creating the toctree, this
does give more control over exactly what goes into the toctree. For
instance, lists of links to external resources currently end up in the
toctree, but we may want to limit it to pages within coreboot.

This change does break rendering and navigation of the documentation in
applications that can render Markdown, such as Okular, Gitiles, or the
GitHub mirror. Assuming the docs are mainly intended to be viewed after
being rendered to doc.coreboot.org, this is probably not an issue in
practice.

Another difference is that MyST natively supports Markdown tables,
whereas with Recommonmark, tables had to be written in embedded rST [4].
However, MyST also supports embedded rST, so the existing tables can be
easily converted as the syntax is nearly identical.

These were converted using
`find ./ -iname "*.md" | xargs -n 1 sed -i "s/eval_rst/{eval-rst}/"`

Makefile.sphinx and conf.py were regenerated from scratch by running
`sphinx-quickstart` using the updated version of Sphinx, which removes a
lot of old commented out boilerplate. Any relevant changes coreboot had
made on top of the previous autogenerated versions of these files were
ported over to the newly generated file.

From some initial testing the generated webpages appear and function
identically to the existing documentation built with Recommonmark.

TEST: `make -C util/docker docker-build-docs` builds the documentation
successfully and the generated output renders properly when viewed in
a web browser.

[1] https://github.com/readthedocs/recommonmark/issues/221
[2] https://pypi.org/project/recommonmark/
[3] https://myst-parser.readthedocs.io/en/latest/
[4] https://doc.coreboot.org/getting_started/writing_documentation.html

Change-Id: I0837c1722fa56d25c9441ea218e943d8f3d9b804
Signed-off-by: Nicholas Chin <nic.c3.14@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/73158
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2024-03-21 16:11:56 +00:00

3.6 KiB

x86 architecture documentation

This section contains documentation about coreboot on x86 architecture.

:maxdepth: 1

x86 PAE support <pae.md>

State of x86_64 support

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 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
  • The CPU supports 1GiB hugepages
  • 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

: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
    • Must reside in SMRAM
  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
  • Test libgfxinit / VGA Option ROMs / FSP

Known bugs on real hardware

According to Intel x86_64 mode hasn't been validated in CAR environments. Until now it could be verified on various Intel platforms and no issues have been found.

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.

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.