Furquan Shaikh has uploaded this change for review.

View Change

Documentation: Add documentation for resource allocator

This change adds documentation for resource allocator in coreboot
which captures the expectations from device and platform drivers and
details about resource allocator v3 and v4.

Change-Id: I887284b44df2bf871f45c3a93fbef9cfc37e42a0
Signed-off-by: Furquan Shaikh <furquan@google.com>
---
A Documentation/device/index.md
A Documentation/device/resource_allocation.md
M Documentation/index.md
3 files changed, 95 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/03/43603/1
diff --git a/Documentation/device/index.md b/Documentation/device/index.md
new file mode 100644
index 0000000..9b703d6
--- /dev/null
+++ b/Documentation/device/index.md
@@ -0,0 +1,6 @@
+# Device management specific documentation
+
+This section contains documentation about device management in
+coreboot.
+
+- [Resource allocation](resource_allocation.md)
diff --git a/Documentation/device/resource_allocation.md b/Documentation/device/resource_allocation.md
new file mode 100644
index 0000000..e82b1c1
--- /dev/null
+++ b/Documentation/device/resource_allocation.md
@@ -0,0 +1,88 @@
+# Resource allocation in coreboot
+
+## Introduction
+
+Resource allocator in coreboot is responsible for assigning parts of the address space to devices. It handles two types of resource requests from devices viz. IO (IORESOURCE_IO) and MMIO (IORESOURCE_MEM). It is typically used for PCI devices, but it also keeps track of other assignments to ensure that there are no conflicts
+
+## Principles followed by the resource allocator
+
+Resource allocator follows these basic principles:
+
+* Allocate address space for every device resource as long as its requirement can be satisfied.
+* Don’t overlap with resources in fixed locations.
+* Don’t overlap with other resource allocations and follow the rules of bridges i.e. downstream devices of bridges should use parts of the address space allocated to the bridge.
+
+## Pre-allocation and post-allocation requirements
+
+The main function that is responsible for allocating resources is `allocate_resources()` and gets called in the `BS_DEV_RESOURCES` boot state. The resource allocator depends upon the device and platform drivers to perform pre-allocation and post-allocation operations. Pre-allocation step requires that the device and platform drivers provide a complete map of fixed resources (resources not changed by the allocator) owned by the device/platform and a list of resource requests that need to be satisfied by the allocator. This is done as part of the `read_resources()` device operation. This step is critical to ensure that the resource allocator can perform its operation correctly as per the principles outlined above. In the post-allocation step, the device and platform drivers are expected to assign the address space allocated by the allocator to the resources requested by the device. This is done as part of the `set_resources()` device operation. This allows the resource allocator to perform its operation independent of platform and device type.
+
+## Input and output rules for the resource allocator
+
+As mentioned above, the entrypoint into the resource allocator is `allocate_resources()`. One of the important goals of the allocator is to perform its operation independent of platform and device type. In order to accomplish this, it is important to clearly define what goes into the allocator and what comes out of it. This determines the expected behavior from the device and platform drivers.
+
+The allocator processes all devices in each domain sub-tree and performs allocation for resources of the following types:
+* IORESOURCE_IO
+* IORESOURCE_MEM
+
+On the other hand, it does not change resources marked with IORESOURCE_FIXED flag. These are referred to as “fixed resources”. Resources that have the IORESOURCE_BRIDGE flag set are referred to as “bridge resources”.
+
+
+### Input Rules
+
+1. IORESOURCE_IO and IORESOURCE_MEM are mutually exclusive. Both the flags must never be set for the same resource.
+1. Resources that should not be changed by the allocator must be marked with IORESOURCE_FIXED flag. These resources must be pre-assigned a valid `base` address. It is used by the allocator to ensure there are no conflicts during the allocation step.
+1. A fixed resource must not overlap with any other fixed resource within the same address space (IO / MEM), unless either of them is a bridge resource.
+1. A fixed bridge resource must not overlap with any other fixed resource within the same address space and on the same bus (i.e. same device or its siblings), unless exactly one of them has IORESOURCE_SUBTRACTIVE set.
+
+### Output Rules
+
+1. All device attributes (members of `struct device` structure) beside non-fixed resources are left unaltered.
+1. The structure of resource lists (`next` pointers) is left unaltered.
+1. The `index` and `gran` attributes of all resources are left unaltered.
+1. The `size`, `limit` and `align` attributes of all non-bridge resources are left unaltered.
+1. All non-fixed assigned resources downstream of a bridge are covered by an assigned bridge resource of that bridge.
+1. IORESOURCE_ASSIGNED flag is set for a non-fixed resource only if it is assigned address space by the allocator. If allocation for a non-fixed resource fails for any reason, all the attributes of that resource are left untouched including resource flags. It is the responsibility of the device and platform driver to check the IORESOURCE_ASSIGNED flag before using the values stored in the `base` field of the resource.
+
+## Resource allocator implementations
+
+Currently, there are two flavors of resource allocators implemented in coreboot - v3 and v4.
+
+### Resource Allocator v3
+
+This is the older resource allocator which is used only on the following platforms:
+
+* northbridge/amd/pi/00630F01
+* northbridge/amd/pi/00730F01
+* northbridge/amd/pi/00660F01
+* northbridge/amd/agesa/family14
+* northbridge/amd/agesa/family15tn
+* northbridge/amd/agesa/family16kb
+
+Resource allocator v3 is still retained and used for the above platforms because these platforms do not conform to the requirements of the allocator i.e. not all the fixed resources of the platform are provided during the `read_resources()` operation. This results in the resource allocator not getting a complete view of the address space. These platforms still work okay with the older resource allocator because of the way it performs allocation in a single window of the address space. No platform other than the ones listed above must use resource allocator v3 as it will be deprecated once the above platforms are fixed. It can be enabled by selecting the `RESOURCE_ALLOCATOR_V3` Kconfig option.
+
+#### Highlights
+
+* Contains two phases - resource computation phase and resource allocation phase.
+* Finds a single window for resource allocation towards the top of addressable memory under 4G boundary.
+
+#### Limitations
+
+* Finds a single window for resource allocation towards the top of addressable memory under 4G boundary.
+* Does not support allocation above 4G boundary. Thus, it might not be able to allocate resources for devices that request large allocations (e.g. USB4, discrete graphics, etc.).
+
+
+### Resource Allocator v4
+
+This is the latest resource allocator that uses multiple ranges for allocating resources. Unlike resource allocator v3, it does not use the topmost available window for allocation. Instead, it uses the first available window within the address space that is available and satisfies the resource request. This allows utilization of the entire available address space and also allows allocation above the 4G boundary.
+
+#### Highlights
+
+* Contains two phases - resource computation phase and resource allocation phase.
+* In phase 1, the allocator walks in a DFS fashion gathering the requirements from leaf devices and propagates them back up to their upstream bridges until the requirements for all the downstream devices of the domain are gathered.
+* Every domain is considered to have a fixed set of resources. These ranges cannot be relaxed based on the requirements of the downstream devices. They represent the available windows from which resources can be allocated to the different devices under the domain.
+* In the second phase, the allocator walks down the tree allocating resources to downstream devices as per the resource requirements gathered in the first phase.
+* In order to accomplish best fit for the resources, a list of ranges is maintained by each resource type (IO and MEM).
+* Domain does not distinguish between mem and prefmem resources. Thus, the resource allocation at domain level considers mem and prefmem together when finding the best fit based on the biggest resource requirement.
+* Allocation at bridge level works the same as at the domain level. One major difference at the bridge level is that it considers prefmem resources separately from mem resources.
+* Device and platform drivers can request the allocator to perform allocation for a particular resource above 4G boundary by using the flag `IORESOURCE_ABOVE_4G`.
+
diff --git a/Documentation/index.md b/Documentation/index.md
index a7c4869..ec26b4e 100644
--- a/Documentation/index.md
+++ b/Documentation/index.md
@@ -188,3 +188,4 @@
* [Utilities](util.md)
* [Release notes for past releases](releases/index.md)
* [Flashing firmware tutorial](flash_tutorial/index.md)
+* [Device Management](device/index.md)

To view, visit change 43603. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I887284b44df2bf871f45c3a93fbef9cfc37e42a0
Gerrit-Change-Number: 43603
Gerrit-PatchSet: 1
Gerrit-Owner: Furquan Shaikh <furquan@google.com>
Gerrit-MessageType: newchange